diff --git a/.travis.yml b/.travis.yml index 1db9f538b53c6d495cac9768ee2851624b182135..0ab8c7c08a33ddcd09c8bbc196c31ed28be514e6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -29,6 +29,7 @@ env: # - RTT_BSP='avr32uc3b0' RTT_TOOL_CHAIN='atmel-avr32' # - RTT_BSP='bf533' # no scons - RTT_BSP='efm32' RTT_TOOL_CHAIN='sourcery-arm' + - RTT_BSP='gd32e230k-start' RTT_TOOL_CHAIN='sourcery-arm' # - RTT_BSP='gd32450z-eval' RTT_TOOL_CHAIN='sourcery-arm' - RTT_BSP='gkipc' RTT_TOOL_CHAIN='sourcery-arm' - RTT_BSP='lm3s8962' RTT_TOOL_CHAIN='sourcery-arm' diff --git a/bsp/es32f0654/.config b/bsp/es32f0654/.config index f0af98f0acb50368d2b205459e5b3b2814f47661..2da21f0f50972f2c3affb2f67b94637923c572ae 100644 --- a/bsp/es32f0654/.config +++ b/bsp/es32f0654/.config @@ -354,6 +354,21 @@ CONFIG_BSP_USING_UART2=y # CONFIG_BSP_USING_HWTIMER2 is not set # CONFIG_BSP_USING_HWTIMER3 is not set +# +# RTC Drivers +# +# CONFIG_BSP_USING_RTC is not set + +# +# PM Drivers +# +# CONFIG_BSP_USING_PM is not set + +# +# ADC Drivers +# +# CONFIG_BSP_USING_ADC is not set + # # Onboard Peripheral Drivers # diff --git a/bsp/es32f0654/README.md b/bsp/es32f0654/README.md index 87eb82c118469b7b1993280e96ce3634bbf77117..8111adeda57a5ff9d6cbf520a81ec2bd1b35d2c0 100644 --- a/bsp/es32f0654/README.md +++ b/bsp/es32f0654/README.md @@ -42,6 +42,9 @@ ES-PDS-ES32F0654-V1.1 | I2C | 支持 | I2C0/1 | | PWM | 支持 | PWM0/1/2/3 | | TIMER | 支持 | TIMER0/1/2/3 | +| RTC | 支持 | RTC | +| PM | 支持 | Power Management | +| ADC | 支持 | ADC0 | ### 1.2 注意事项 diff --git a/bsp/es32f0654/drivers/Kconfig b/bsp/es32f0654/drivers/Kconfig index d5af1bbd9518f0fcf4b57814f2c1895067e69a46..f7a64ea678b920dc8f238bc5d1774b302bc3fdf6 100644 --- a/bsp/es32f0654/drivers/Kconfig +++ b/bsp/es32f0654/drivers/Kconfig @@ -102,6 +102,27 @@ menu "Hardware Drivers Config" default n endmenu + menu "RTC Drivers" + config BSP_USING_RTC + bool "Using RTC" + select RT_USING_RTC + default n + endmenu + + menu "PM Drivers" + config BSP_USING_PM + bool "Using PM" + select RT_USING_PM + 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" diff --git a/bsp/es32f0654/drivers/SConscript b/bsp/es32f0654/drivers/SConscript index 31f75af3b324cfbc9b660b5ad035923b021e39fc..a5ecf863ab5a3631ddbce451d1e52ca832d33429 100644 --- a/bsp/es32f0654/drivers/SConscript +++ b/bsp/es32f0654/drivers/SConscript @@ -35,6 +35,18 @@ if GetDepend('BSP_USING_PWM0') or GetDepend('BSP_USING_PWM1') or GetDepend('BSP_ if GetDepend('BSP_USING_HWTIMER0') or GetDepend('BSP_USING_HWTIMER1') or GetDepend('BSP_USING_HWTIMER2') or GetDepend('BSP_USING_HWTIMER3'): src += ['drv_hwtimer.c'] +# add rtc driver code +if GetDepend(['BSP_USING_RTC']): + src += ['drv_rtc.c'] + +# add pm driver code +if GetDepend(['BSP_USING_PM']): + src += ['drv_pm.c'] + +# add adc driver code +if GetDepend(['BSP_USING_ADC']): + src += ['drv_adc.c'] + CPPPATH = [cwd] group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH) diff --git a/bsp/es32f0654/drivers/drv_adc.c b/bsp/es32f0654/drivers/drv_adc.c new file mode 100644 index 0000000000000000000000000000000000000000..9a90e4d3944e48eb7d3737407848fab555709931 --- /dev/null +++ b/bsp/es32f0654/drivers/drv_adc.c @@ -0,0 +1,193 @@ +/* + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-04-03 wangyq the first version + */ + +#include +#include +#include +#include "board.h" +#include "drv_adc.h" +#include +#include + +#ifdef RT_USING_ADC + +/* 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) +{ + adc_handle_t *_hadc = (adc_handle_t *)device->parent.user_data; + + RT_ASSERT(device != RT_NULL); + + if (enabled) + { + ADC_ENABLE(_hadc); ; + } + else + { + ADC_DISABLE(_hadc); + } + + return RT_EOK; +} + +static adc_channel_t es32f0_adc_get_channel(rt_uint32_t channel) +{ + adc_channel_t es32f0_channel; + gpio_init_t gpio_initstruct; + + /* Initialize ADC pin */ + gpio_initstruct.mode = GPIO_MODE_INPUT; + gpio_initstruct.pupd = GPIO_FLOATING; + gpio_initstruct.odrv = GPIO_OUT_DRIVE_NORMAL; + gpio_initstruct.flt = GPIO_FILTER_DISABLE; + gpio_initstruct.type = GPIO_TYPE_CMOS; + gpio_initstruct.func = GPIO_FUNC_0; + + /* select gpio pin as adc function */ + switch (channel) + { + case 0: + es32f0_channel = ADC_CHANNEL_0; + gpio_init(GPIOC, GPIO_PIN_0, &gpio_initstruct); + break; + case 1: + es32f0_channel = ADC_CHANNEL_1; + gpio_init(GPIOC, GPIO_PIN_1, &gpio_initstruct); + break; + case 2: + es32f0_channel = ADC_CHANNEL_2; + gpio_init(GPIOC, GPIO_PIN_2, &gpio_initstruct); + break; + case 3: + es32f0_channel = ADC_CHANNEL_3; + gpio_init(GPIOC, GPIO_PIN_3, &gpio_initstruct); + break; + case 4: + es32f0_channel = ADC_CHANNEL_4; + gpio_init(GPIOA, GPIO_PIN_0, &gpio_initstruct); + break; + case 5: + es32f0_channel = ADC_CHANNEL_5; + gpio_init(GPIOA, GPIO_PIN_1, &gpio_initstruct); + break; + case 6: + es32f0_channel = ADC_CHANNEL_6; + gpio_init(GPIOA, GPIO_PIN_2, &gpio_initstruct); + break; + case 7: + es32f0_channel = ADC_CHANNEL_7; + gpio_init(GPIOA, GPIO_PIN_3, &gpio_initstruct); + break; + case 8: + es32f0_channel = ADC_CHANNEL_8; + gpio_init(GPIOA, GPIO_PIN_4, &gpio_initstruct); + break; + case 9: + es32f0_channel = ADC_CHANNEL_9; + gpio_init(GPIOA, GPIO_PIN_5, &gpio_initstruct); + break; + case 10: + es32f0_channel = ADC_CHANNEL_10; + gpio_init(GPIOA, GPIO_PIN_6, &gpio_initstruct); + break; + case 11: + es32f0_channel = ADC_CHANNEL_11; + gpio_init(GPIOA, GPIO_PIN_7, &gpio_initstruct); + break; + case 12: + es32f0_channel = ADC_CHANNEL_12; + gpio_init(GPIOC, GPIO_PIN_4, &gpio_initstruct); + break; + case 13: + es32f0_channel = ADC_CHANNEL_13; + gpio_init(GPIOC, GPIO_PIN_5, &gpio_initstruct); + break; + case 14: + es32f0_channel = ADC_CHANNEL_14; + gpio_init(GPIOB, GPIO_PIN_0, &gpio_initstruct); + break; + case 15: + es32f0_channel = ADC_CHANNEL_15; + gpio_init(GPIOB, GPIO_PIN_1, &gpio_initstruct); + break; + case 16: + es32f0_channel = ADC_CHANNEL_16; + break; + case 17: + es32f0_channel = ADC_CHANNEL_17; + break; + case 18: + es32f0_channel = ADC_CHANNEL_18; + break; + default: + break; + } + + return es32f0_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; + + 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); + + adc_normal_start(_hadc); + + if (adc_normal_poll_for_conversion(_hadc, 5000) == OK) + *value = adc_normal_get_value(_hadc); + + return RT_EOK; +} + +static const struct rt_adc_ops es32f0_adc_ops = +{ + es32f0_adc_enabled, + es32f0_get_adc_value, +}; + +int rt_hw_adc_init(void) +{ + int result = RT_EOK; + static adc_handle_t _h_adc0; + + /* 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.cont_mode = DISABLE; + _h_adc0.init.conv_nbr = ADC_NM_NBR_1; + _h_adc0.init.disc_mode = 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.neg_ref = ADC_NEG_REF_VSS; + _h_adc0.init.pos_ref = ADC_POS_REF_VDD; + adc_init(&_h_adc0); + + rt_hw_adc_register(&_device_adc0, "adc0", &es32f0_adc_ops, &_h_adc0); + + return result; +} +INIT_BOARD_EXPORT(rt_hw_adc_init); + +#endif diff --git a/bsp/es32f0654/drivers/drv_adc.h b/bsp/es32f0654/drivers/drv_adc.h new file mode 100644 index 0000000000000000000000000000000000000000..eaddd67407995815fa71ea964a7a160ae774bcdf --- /dev/null +++ b/bsp/es32f0654/drivers/drv_adc.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-04-03 wangyq the first version + */ + +#ifndef DRV_ADC_H__ +#define DRV_ADC_H__ + +int rt_hw_adc_init(void); + +#endif diff --git a/bsp/es32f0654/drivers/drv_pm.c b/bsp/es32f0654/drivers/drv_pm.c new file mode 100644 index 0000000000000000000000000000000000000000..256634b81d68645023719feec3ddd2d01cb13ab4 --- /dev/null +++ b/bsp/es32f0654/drivers/drv_pm.c @@ -0,0 +1,110 @@ +/* + * 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 + */ + +#include +#include +#include "board.h" +#include "drv_pm.h" +#include + +#ifdef RT_USING_PM + +static void _drv_pm_enter(struct rt_pm *pm) +{ + rt_uint32_t mode; + + mode = pm->current_mode; + + switch (mode) + { + case PM_RUN_MODE_NORMAL: + break; + + case PM_SLEEP_MODE_SLEEP: + __WFI(); + break; + + case PM_SLEEP_MODE_TIMER: + pmu_stop2_enter(); + break; + + case PM_SLEEP_MODE_SHUTDOWN: + pmu_standby_enter(PMU_STANDBY_PORT_NONE); + break; + + default: + RT_ASSERT(0); + break; + } +} + +static void _drv_pm_exit(struct rt_pm *pm) +{ + rt_uint32_t mode; + + RT_ASSERT(pm != RT_NULL); + + mode = pm->current_mode; + + switch (mode) + { + case PM_RUN_MODE_NORMAL: + break; + + case PM_SLEEP_MODE_SLEEP: + break; + + case PM_SLEEP_MODE_TIMER: + break; + + case PM_SLEEP_MODE_SHUTDOWN: + break; + + default: + RT_ASSERT(0); + break; + } +} + +#if PM_RUN_MODE_COUNT > 1 +static void _drv_pm_frequency_change(struct rt_pm *pm, rt_uint32_t frequency) +{ + return; +} +#endif + +static int drv_hw_pm_init(void) +{ + static const struct rt_pm_ops _ops = + { + _drv_pm_enter, + _drv_pm_exit, + +#if PM_RUN_MODE_COUNT > 1 + _drv_pm_frequency_change, +#endif + RT_NULL, + RT_NULL, + RT_NULL + }; + + rt_uint8_t timer_mask; + + /* initialize timer mask */ + timer_mask = 1UL << PM_SLEEP_MODE_TIMER; + + /* 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/drivers/drv_pm.h b/bsp/es32f0654/drivers/drv_pm.h new file mode 100644 index 0000000000000000000000000000000000000000..a4f6cc84eed89859f5beef2154384e9754f54782 --- /dev/null +++ b/bsp/es32f0654/drivers/drv_pm.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-04-01 wangyq the first version + */ + +#ifndef DRV_PM_H__ +#define DRV_PM_H__ + +int rt_hw_pm_init(void); + +#endif diff --git a/bsp/es32f0654/drivers/drv_rtc.c b/bsp/es32f0654/drivers/drv_rtc.c new file mode 100644 index 0000000000000000000000000000000000000000..0c9822e4e7ac5d8e30aa26c8dc8e54770024c3f9 --- /dev/null +++ b/bsp/es32f0654/drivers/drv_rtc.c @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-03-22 wangyq the first version + */ + +#include +#include +#include +#include +#include "board.h" +#include "drv_rtc.h" +#include +#include + +#ifdef RT_USING_RTC + +static void 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(); + RTC_UNLOCK(); + + MODIFY_REG(RTC->CON, RTC_CON_HFM_MSK, init->hour_format << RTC_CON_HFM_POS); + MODIFY_REG(RTC->CON, RTC_CON_EOS_MSK, init->output << RTC_CON_EOS_POSS); + MODIFY_REG(RTC->CON, RTC_CON_POL_MSK, init->output_polarity << RTC_CON_POL_POS); + MODIFY_REG(RTC->PSR, RTC_PSR_SPRS_MSK, init->synch_pre_div << RTC_PSR_SPRS_POSS); + MODIFY_REG(RTC->PSR, RTC_PSR_APRS_MSK, init->asynch_pre_div << RTC_PSR_APRS_POSS); + + RTC_LOCK(); + 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; + rtc_date_t date; + rtc_time_t time; + + switch (cmd) + { + case RT_DEVICE_CTRL_RTC_GET_TIME: + + 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; + 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; + rtc_set_time(&time, RTC_FORMAT_DEC); + rtc_set_date(&date, RTC_FORMAT_DEC); + /* start RTC */ + RTC_UNLOCK(); + SET_BIT(RTC->CON, RTC_CON_GO_MSK); + RTC_LOCK(); + break; + + case RT_DEVICE_CTRL_RTC_GET_ALARM: + break; + + case RT_DEVICE_CTRL_RTC_SET_ALARM: + break; + + default: + break; + } + + 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 + +int rt_hw_rtc_init(void) +{ + rt_err_t ret = RT_EOK; + static struct rt_device rtc_dev; + rtc_init_t rtc_initstruct; + + /* enable external 32.768kHz */ + CMU_LOSC_ENABLE(); + cmu_losc_safe_config(ENABLE); + /* set default time */ + RTC_UNLOCK(); + WRITE_REG(RTC->TIME, 0x134251); + WRITE_REG(RTC->DATE, 0x1190401); + RTC_LOCK(); + /* RTC function initialization */ + rtc_initstruct.hour_format = RTC_HOUR_FORMAT_24; + rtc_initstruct.asynch_pre_div = 0; + rtc_initstruct.synch_pre_div = 32767; + rtc_initstruct.output = RTC_OUTPUT_DISABLE; + rtc_init(&rtc_initstruct); + + 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/es32f0654/drivers/drv_rtc.h b/bsp/es32f0654/drivers/drv_rtc.h new file mode 100644 index 0000000000000000000000000000000000000000..fe0264fb5132952904c512ca814873d761485c9b --- /dev/null +++ b/bsp/es32f0654/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-03-22 wangyq the first version + */ + +#ifndef DRV_RTC_H__ +#define DRV_RTC_H__ + +int rt_hw_rtc_init(void); + +#endif diff --git a/bsp/es32f0654/libraries/SConscript b/bsp/es32f0654/libraries/SConscript index bbc9d5d2e1924e80883487183c6a77b80177d8c5..6da75a02629767c304c912112f550f5771f0bfd9 100644 --- a/bsp/es32f0654/libraries/SConscript +++ b/bsp/es32f0654/libraries/SConscript @@ -10,18 +10,17 @@ src = [] src += Glob('ES32F065x_ALD_StdPeriph_Driver/Source/*.c') - -#add for startup script +#add for startup script if rtconfig.CROSS_TOOL == 'gcc': src = src + ['CMSIS/Device/EastSoft/ES32F065x/Startup/gcc/startup_es32f065x.s'] elif rtconfig.CROSS_TOOL == 'keil': src = src + ['CMSIS/Device/EastSoft/ES32F065x/Startup/keil/startup_es32f065x.s'] elif rtconfig.CROSS_TOOL == 'iar': - src = src + ['CMSIS/Device/EastSoft/ES32F065x/Startup/iar/startup_es32f065x.s'] + src = src + ['CMSIS/Device/EastSoft/ES32F065x/Startup/iar/startup_es32f065x.s'] -path = [cwd + '/CMSIS/Device/EastSoft/ES32F065x/Include', - cwd + '/CMSIS/Include', - cwd + '/ES32F065x_ALD_StdPeriph_Driver/Include'] +path = [cwd + '/CMSIS/Device/EastSoft/ES32F065x/Include', + cwd + '/CMSIS/Include', + cwd + '/ES32F065x_ALD_StdPeriph_Driver/Include'] group = DefineGroup('Libraries', src, depend = [''], CPPPATH = path) diff --git a/bsp/es32f0654/rtconfig.h b/bsp/es32f0654/rtconfig.h index 52cb4930e09f4ebb206fe14bfa113e4ef12664e8..4ac4c17d0d2f3d637241f124c60b334174c3b8fa 100644 --- a/bsp/es32f0654/rtconfig.h +++ b/bsp/es32f0654/rtconfig.h @@ -175,6 +175,15 @@ /* HWtimer Drivers */ +/* RTC Drivers */ + + +/* PM Drivers */ + + +/* ADC Drivers */ + + /* Onboard Peripheral Drivers */ diff --git a/bsp/es32f0654/rtconfig.py b/bsp/es32f0654/rtconfig.py index 170bae8a7be6e9c997fcc5e5a10e7de3ff2e021c..eb371bf3a7199a3b5530611d6fb7f0dc26bf5600 100644 --- a/bsp/es32f0654/rtconfig.py +++ b/bsp/es32f0654/rtconfig.py @@ -46,7 +46,7 @@ if PLATFORM == 'gcc': 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 board/linker_scripts/link.lds' + LFLAGS = DEVICE + ' -Wl,--gc-sections,-Map=rtthread.map,-cref,-u,Reset_Handler -T drivers/linker_scripts/link.lds' CPATH = '' LPATH = '' diff --git a/bsp/gd32e230k-start/.config b/bsp/gd32e230k-start/.config new file mode 100644 index 0000000000000000000000000000000000000000..aa6698d6031041ff98a95aeadb2de3d7f6495b97 --- /dev/null +++ b/bsp/gd32e230k-start/.config @@ -0,0 +1,321 @@ +# +# 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_IDEL_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="uart0" +CONFIG_RT_VER_NUM=0x40001 +# 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 is not set + +# +# 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_SERIAL=y +CONFIG_RT_SERIAL_USING_DMA=y +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=y +# CONFIG_RT_USING_I2C_BITOPS 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_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=y +# CONFIG_RT_USING_QSPI is not set +# CONFIG_RT_USING_SPI_MSD is not set +CONFIG_RT_USING_SFUD=y +# CONFIG_RT_SFUD_USING_SFDP is not set +CONFIG_RT_SFUD_USING_FLASH_INFO_TABLE=y +# CONFIG_RT_SFUD_USING_QSPI is not set +# CONFIG_RT_DEBUG_SFUD is not set +# CONFIG_RT_USING_W25QXX is not set +# CONFIG_RT_USING_GD is not set +# CONFIG_RT_USING_ENC28J60 is not set +# CONFIG_RT_USING_SPI_WIFI is not set +# 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_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 + +# +# Network +# + +# +# Socket abstraction layer +# +# CONFIG_RT_USING_SAL is not set + +# +# light weight TCP/IP stack +# +# CONFIG_RT_USING_LWIP is not set + +# +# Modbus master and slave stack +# +# CONFIG_RT_USING_MODBUS 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_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 + +# +# 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_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_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_COAP is not set +# CONFIG_PKG_USING_NOPOLL is not set +# CONFIG_PKG_USING_NETUTILS is not set +# CONFIG_PKG_USING_AT_DEVICE 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 + +# +# 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 + +# +# 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 + +# +# 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 + +# +# peripheral libraries and drivers +# +# 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 + +# +# 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_CANFESTIVAL is not set +# CONFIG_PKG_USING_ZLIB is not set +# CONFIG_PKG_USING_DSTR is not set + +# +# sample package +# + +# +# 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 + +# +# example package: hello +# +# CONFIG_PKG_USING_HELLO is not set +CONFIG_RT_USING_USART0=y +CONFIG_RT_USING_USART1=y +# CONFIG_RT_USING_USART2 is not set +# CONFIG_RT_USING_UART3 is not set +# CONFIG_RT_USING_UART4 is not set +CONFIG_RT_USING_SPI0=y +CONFIG_RT_USING_SPI1=y +CONFIG_RT_USING_I2C0=y +# CONFIG_RT_USING_I2C1 is not set diff --git a/bsp/gd32e230k-start/Kconfig b/bsp/gd32e230k-start/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..36b2d0eeb1d4ed68e65609ea60430194ef12d875 --- /dev/null +++ b/bsp/gd32e230k-start/Kconfig @@ -0,0 +1,67 @@ +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 RT_USING_USART0 + bool "Using USART0" + select RT_USING_SERIAL + default y + +config RT_USING_USART1 + bool "Using USART1" + select RT_USING_SERIAL + default n + +config RT_USING_USART2 + bool "Using USART2" + select RT_USING_SERIAL + default n + +config RT_USING_UART3 + bool "Using UART3" + select RT_USING_SERIAL + default n + +config RT_USING_UART4 + bool "Using UART4" + select RT_USING_SERIAL + default n + +config RT_USING_SPI0 + bool "Using SPI0" + select RT_USING_SPI + default y + +config RT_USING_SPI1 + bool "Using SPI1" + select RT_USING_SPI + default n + +config RT_USING_I2C0 + bool "Using I2C0" + select RT_USING_I2C + default n + +config RT_USING_I2C1 + bool "Using I2C1" + select RT_USING_I2C + default n + + + diff --git a/bsp/gd32e230k-start/Libraries/CMSIS/GD/GD32E230/Include/gd32e230.h b/bsp/gd32e230k-start/Libraries/CMSIS/GD/GD32E230/Include/gd32e230.h new file mode 100644 index 0000000000000000000000000000000000000000..60838636f739ffc7dd4aaae396b32a148a496fa8 --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/CMSIS/GD/GD32E230/Include/gd32e230.h @@ -0,0 +1,212 @@ +/*! + \file gd32e230.h + \brief general definitions for GD32E230 + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor 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 copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 GD32E230_H +#define GD32E230_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* define GD32E230 */ +#if !defined (GD32E230) + #define GD32E230 +#endif /* define GD32E230 */ +#if !defined (GD32E230) + #error "Please select the target GD32E230 device used in your application (in gd32e230.h file)" +#endif /* undefine GD32E230 tip */ + +/* define value of high speed crystal oscillator (HXTAL) in Hz */ +#if !defined (HXTAL_VALUE) +#define HXTAL_VALUE ((uint32_t)8000000) +#endif /* high speed crystal oscillator value */ + +/* define startup timeout value of high speed crystal oscillator (HXTAL) */ +#if !defined (HXTAL_STARTUP_TIMEOUT) +#define HXTAL_STARTUP_TIMEOUT ((uint16_t)0x0800) +#endif /* high speed crystal oscillator startup timeout */ + +/* define value of internal 8MHz RC oscillator (IRC8M) in Hz */ +#if !defined (IRC8M_VALUE) +#define IRC8M_VALUE ((uint32_t)8000000) +#endif /* internal 8MHz RC oscillator value */ + +/* define startup timeout value of internal 8MHz RC oscillator (IRC8M) */ +#if !defined (IRC8M_STARTUP_TIMEOUT) +#define IRC8M_STARTUP_TIMEOUT ((uint16_t)0x0500) +#endif /* internal 8MHz RC oscillator startup timeout */ + +/* define value of internal RC oscillator for ADC in Hz */ +#if !defined (IRC28M_VALUE) +#define IRC28M_VALUE ((uint32_t)28000000) +#endif /* IRC28M_VALUE */ + +#if !defined (IRC48M_VALUE) +#define IRC48M_VALUE ((uint32_t)48000000) +#endif /* IRC48M_VALUE */ + +/* define value of internal 40KHz RC oscillator(IRC40K) in Hz */ +#if !defined (IRC40K_VALUE) +#define IRC40K_VALUE ((uint32_t)40000) +#endif /* internal 40KHz RC oscillator value */ + +/* define value of low speed crystal oscillator (LXTAL)in Hz */ +#if !defined (LXTAL_VALUE) +#define LXTAL_VALUE ((uint32_t)32768) +#endif /* low speed crystal oscillator value */ + +/* GD32E1x0 firmware library version number V1.0 */ +#define __GD32E230_STDPERIPH_VERSION_MAIN (0x01) /*!< [31:24] main version */ +#define __GD32E230_STDPERIPH_VERSION_SUB1 (0x00) /*!< [23:16] sub1 version */ +#define __GD32E230_STDPERIPH_VERSION_SUB2 (0x00) /*!< [15:8] sub2 version */ +#define __GD32E230_STDPERIPH_VERSION_RC (0x00) /*!< [7:0] release candidate */ +#define __GD32E230_STDPERIPH_VERSION ((__GD32E230_STDPERIPH_VERSION_MAIN << 24)\ + |(__GD32E230_STDPERIPH_VERSION_SUB1 << 16)\ + |(__GD32E230_STDPERIPH_VERSION_SUB2 << 8)\ + |(__GD32E230_STDPERIPH_VERSION_RC)) + +/* configuration of the Cortex-M23 processor and core peripherals */ +#define __CM23_REV 0x0100U /*!< Core revision r1p0 */ +#define __SAUREGION_PRESENT 0U /*!< SAU regions are not present */ +#define __MPU_PRESENT 0U /*!< MPU is present */ +#define __VTOR_PRESENT 1U /*!< VTOR is present */ +#define __NVIC_PRIO_BITS 2U /*!< Number of Bits used for Priority Levels */ +#define __Vendor_SysTickConfig 0U /*!< Set to 1 if different SysTick Config is used */ + +/* define interrupt number */ +typedef enum IRQn +{ + /* Cortex-M23 processor exceptions numbers */ + NonMaskableInt_IRQn = -14, /*!< non maskable interrupt */ + HardFault_IRQn = -13, /*!< hardfault interrupt */ + + SVCall_IRQn = -5, /*!< sv call interrupt */ + + PendSV_IRQn = -2, /*!< pend sv interrupt */ + SysTick_IRQn = -1, /*!< system tick interrupt */ + /* interruput numbers */ + WWDGT_IRQn = 0, /*!< window watchdog timer interrupt */ + LVD_IRQn = 1, /*!< LVD through EXTI line detect interrupt */ + RTC_IRQn = 2, /*!< RTC through EXTI line interrupt */ + FMC_IRQn = 3, /*!< FMC interrupt */ + RCU_IRQn = 4, /*!< RCU interrupt */ + EXTI0_1_IRQn = 5, /*!< EXTI line 0 and 1 interrupts */ + EXTI2_3_IRQn = 6, /*!< EXTI line 2 and 3 interrupts */ + EXTI4_15_IRQn = 7, /*!< EXTI line 4 to 15 interrupts */ + DMA_Channel0_IRQn = 9, /*!< DMA channel 0 interrupt */ + DMA_Channel1_2_IRQn = 10, /*!< DMA channel 1 and channel 2 interrupts */ + DMA_Channel3_4_IRQn = 11, /*!< DMA channel 3 and channel 4 interrupts */ + ADC_CMP_IRQn = 12, /*!< ADC, CMP interrupts */ + TIMER0_BRK_UP_TRG_COM_IRQn = 13, /*!< TIMER0 break, update, trigger and commutation interrupts */ + TIMER0_Channel_IRQn = 14, /*!< TIMER0 channel capture compare interrupts */ + TIMER2_IRQn = 16, /*!< TIMER2 interrupt */ + TIMER5_IRQn = 17, /*!< TIMER5 interrupt */ + TIMER13_IRQn = 19, /*!< TIMER13 interrupt */ + TIMER14_IRQn = 20, /*!< TIMER14 interrupt */ + TIMER15_IRQn = 21, /*!< TIMER15 interrupt */ + TIMER16_IRQn = 22, /*!< TIMER16 interrupt */ + I2C0_EV_IRQn = 23, /*!< I2C0 event interrupt */ + I2C1_EV_IRQn = 24, /*!< I2C1 event interrupt */ + SPI0_IRQn = 25, /*!< SPI0 interrupt */ + SPI1_IRQn = 26, /*!< SPI1 interrupt */ + USART0_IRQn = 27, /*!< USART0 interrupt */ + USART1_IRQn = 28, /*!< USART1 interrupt */ + I2C0_ER_IRQn = 32, /*!< I2C0 error interrupt */ + I2C1_ER_IRQn = 34, /*!< I2C1 error interrupt */ +} IRQn_Type; + +/* includes */ +#include "core_cm23.h" +#include "system_gd32e230.h" +#include + +/* enum definitions */ +typedef enum {DISABLE = 0, ENABLE = !DISABLE} EventStatus, ControlStatus; +typedef enum {RESET = 0, SET = !RESET} FlagStatus; +typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrStatus; + +/* bit operations */ +#define REG32(addr) (*(volatile uint32_t *)(uint32_t)(addr)) +#define REG16(addr) (*(volatile uint16_t *)(uint32_t)(addr)) +#define REG8(addr) (*(volatile uint8_t *)(uint32_t)(addr)) +#define BIT(x) ((uint32_t)((uint32_t)0x01U<<(x))) +#define BITS(start, end) ((0xFFFFFFFFUL << (start)) & (0xFFFFFFFFUL >> (31U - (uint32_t)(end)))) +#define GET_BITS(regval, start, end) (((regval) & BITS((start),(end))) >> (start)) + +/* main flash and SRAM memory map */ +#define FLASH_BASE ((uint32_t)0x08000000U) /*!< main FLASH base address */ +#define SRAM_BASE ((uint32_t)0x20000000U) /*!< SRAM base address */ +/* SRAM and peripheral base bit-band region */ +#define SRAM_BB_BASE ((uint32_t)0x22000000U) /*!< SRAM bit-band base address */ +#define PERIPH_BB_BASE ((uint32_t)0x42000000U) /*!< peripheral bit-band base address */ +/* peripheral memory map */ +#define APB1_BUS_BASE ((uint32_t)0x40000000U) /*!< apb1 base address */ +#define APB2_BUS_BASE ((uint32_t)0x40010000U) /*!< apb2 base address */ +#define AHB1_BUS_BASE ((uint32_t)0x40020000U) /*!< ahb1 base address */ +#define AHB2_BUS_BASE ((uint32_t)0x48000000U) /*!< ahb2 base address */ +/* advanced peripheral bus 1 memory map */ +#define TIMER_BASE (APB1_BUS_BASE + 0x00000000U) /*!< TIMER base address */ +#define RTC_BASE (APB1_BUS_BASE + 0x00002800U) /*!< RTC base address */ +#define WWDGT_BASE (APB1_BUS_BASE + 0x00002C00U) /*!< WWDGT base address */ +#define FWDGT_BASE (APB1_BUS_BASE + 0x00003000U) /*!< FWDGT base address */ +#define SPI_BASE (APB1_BUS_BASE + 0x00003800U) /*!< SPI base address */ +#define USART_BASE (APB1_BUS_BASE + 0x00004400U) /*!< USART base address */ +#define I2C_BASE (APB1_BUS_BASE + 0x00005400U) /*!< I2C base address */ +#define PMU_BASE (APB1_BUS_BASE + 0x00007000U) /*!< PMU base address */ +/* advanced peripheral bus 2 memory map */ +#define SYSCFG_BASE (APB2_BUS_BASE + 0x00000000U) /*!< SYSCFG base address */ +#define CMP_BASE (APB2_BUS_BASE + 0x0000001CU) /*!< CMP base address */ +#define EXTI_BASE (APB2_BUS_BASE + 0x00000400U) /*!< EXTI base address */ +#define ADC_BASE (APB2_BUS_BASE + 0x00002400U) /*!< ADC base address */ +/* advanced high performance bus 1 memory map */ +#define DMA_BASE (AHB1_BUS_BASE + 0x00000000U) /*!< DMA base address */ +#define DMA_CHANNEL_BASE (DMA_BASE + 0x00000008U) /*!< DMA channel base address */ +#define RCU_BASE (AHB1_BUS_BASE + 0x00001000U) /*!< RCU base address */ +#define FMC_BASE (AHB1_BUS_BASE + 0x00002000U) /*!< FMC base address */ +#define CRC_BASE (AHB1_BUS_BASE + 0x00003000U) /*!< CRC base address */ +/* advanced high performance bus 2 memory map */ +#define GPIO_BASE (AHB2_BUS_BASE + 0x00000000U) /*!< GPIO base address */ +/* option byte and debug memory map */ +#define OB_BASE ((uint32_t)0x1FFFF800U) /*!< OB base address */ +#define DBG_BASE ((uint32_t)0x40015800U) /*!< DBG base address */ + +#include "gd32e230_libopt.h" + +#ifdef __cplusplus +} +#endif + +#endif /* GD32E230_H */ diff --git a/bsp/gd32e230k-start/Libraries/CMSIS/GD/GD32E230/Include/system_gd32e230.h b/bsp/gd32e230k-start/Libraries/CMSIS/GD/GD32E230/Include/system_gd32e230.h new file mode 100644 index 0000000000000000000000000000000000000000..45441bd546092b47ed09fe17200f39876754b126 --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/CMSIS/GD/GD32E230/Include/system_gd32e230.h @@ -0,0 +1,58 @@ +/*! + \file system_gd32e230.h + \brief CMSIS Cortex-M23 Device Peripheral Access Layer Header File for + GD32E230 Device Series +*/ + +/* Copyright (c) 2012 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. + ---------------------------------------------------------------------------*/ + +/* This file refers the CMSIS standard, some adjustments are made according to GigaDevice chips */ + +#ifndef SYSTEM_GD32E230_H +#define SYSTEM_GD32E230_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* system clock frequency (core clock) */ +extern uint32_t SystemCoreClock; + +/* function declarations */ +/* initialize the system and update the SystemCoreClock variable */ +extern void SystemInit (void); +/* update the SystemCoreClock with current core clock retrieved from cpu registers */ +extern void SystemCoreClockUpdate (void); + +#ifdef __cplusplus +} +#endif + +#endif /* SYSTEM_GD32E230_H */ diff --git a/bsp/gd32e230k-start/Libraries/CMSIS/GD/GD32E230/Source/ARM/startup_gd32e230.s b/bsp/gd32e230k-start/Libraries/CMSIS/GD/GD32E230/Source/ARM/startup_gd32e230.s new file mode 100644 index 0000000000000000000000000000000000000000..8b001a390f230fd5fb457d85db153a7bf02d6d10 --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/CMSIS/GD/GD32E230/Source/ARM/startup_gd32e230.s @@ -0,0 +1,256 @@ +;/*! +; \file startup_gd32e230.s +; \brief start up file +; +; \version 2018-6-19, V1.0.0, firmware for GD32E230 +;*/ +; +;/* +; Copyright (c) 2018, GigaDevice Semiconductor 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 copyright holder nor the names of its contributors +; may be used to endorse or promote products derived from this software without +; specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +;AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +;WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +;IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +;INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +;NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +;PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +;WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +;ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +;OF SUCH DAMAGE. +;*/ + +; 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 0x00000400 + + AREA HEAP, NOINIT, READWRITE, ALIGN=3 +__heap_base +Heap_Mem SPACE Heap_Size +__heap_limit + + PRESERVE8 + THUMB + +; /* reset Vector Mapped to at Address 0 */ + AREA RESET, DATA, READONLY + EXPORT __Vectors + EXPORT __Vectors_End + EXPORT __Vectors_Size + +__Vectors DCD __initial_sp ; Top of Stack + DCD Reset_Handler ; Reset Handler + DCD NMI_Handler ; NMI Handler + DCD HardFault_Handler ; Hard Fault Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; SVCall Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD PendSV_Handler ; PendSV Handler + DCD SysTick_Handler ; SysTick Handler + +; /* external interrupts handler */ + DCD WWDGT_IRQHandler ; 16:Window Watchdog Timer + DCD LVD_IRQHandler ; 17:LVD through EXTI Line detect + DCD RTC_IRQHandler ; 18:RTC through EXTI Line + DCD FMC_IRQHandler ; 19:FMC + DCD RCU_IRQHandler ; 20:RCU + DCD EXTI0_1_IRQHandler ; 21:EXTI Line 0 and EXTI Line 1 + DCD EXTI2_3_IRQHandler ; 22:EXTI Line 2 and EXTI Line 3 + DCD EXTI4_15_IRQHandler ; 23:EXTI Line 4 to EXTI Line 15 + DCD 0 ; Reserved + DCD DMA_Channel0_IRQHandler ; 25:DMA Channel 0 + DCD DMA_Channel1_2_IRQHandler ; 26:DMA Channel 1 and DMA Channel 2 + DCD DMA_Channel3_4_IRQHandler ; 27:DMA Channel 3 and DMA Channel 4 + DCD ADC_CMP_IRQHandler ; 28:ADC and Comparator + DCD TIMER0_BRK_UP_TRG_COM_IRQHandler ; 29:TIMER0 Break,Update,Trigger and Commutation + DCD TIMER0_Channel_IRQHandler ; 30:TIMER0 Channel Capture Compare + DCD 0 ; Reserved + DCD TIMER2_IRQHandler ; 32:TIMER2 + DCD TIMER5_IRQHandler ; 33:TIMER5 + DCD 0 ; Reserved + DCD TIMER13_IRQHandler ; 35:TIMER13 + DCD TIMER14_IRQHandler ; 36:TIMER14 + DCD TIMER15_IRQHandler ; 37:TIMER15 + DCD TIMER16_IRQHandler ; 38:TIMER16 + DCD I2C0_EV_IRQHandler ; 39:I2C0 Event + DCD I2C1_EV_IRQHandler ; 40:I2C1 Event + DCD SPI0_IRQHandler ; 41:SPI0 + DCD SPI1_IRQHandler ; 42:SPI1 + DCD USART0_IRQHandler ; 43:USART0 + DCD USART1_IRQHandler ; 44:USART1 + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD I2C0_ER_IRQHandler ; 48:I2C0 Error + DCD 0 ; Reserved + DCD I2C1_ER_IRQHandler ; 50:I2C1 Error +__Vectors_End + +__Vectors_Size EQU __Vectors_End - __Vectors + + AREA |.text|, CODE, READONLY + +;/* reset Handler */ +Reset_Handler PROC + EXPORT Reset_Handler [WEAK] + IMPORT SystemInit + IMPORT __main + LDR R0, =SystemInit + BLX R0 + LDR R0, =__main + BX R0 + ENDP + +;/* dummy Exception Handlers */ +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 +; /* external interrupts handler */ + EXPORT WWDGT_IRQHandler [WEAK] + EXPORT LVD_IRQHandler [WEAK] + EXPORT RTC_IRQHandler [WEAK] + EXPORT FMC_IRQHandler [WEAK] + EXPORT RCU_IRQHandler [WEAK] + EXPORT EXTI0_1_IRQHandler [WEAK] + EXPORT EXTI2_3_IRQHandler [WEAK] + EXPORT EXTI4_15_IRQHandler [WEAK] + EXPORT DMA_Channel0_IRQHandler [WEAK] + EXPORT DMA_Channel1_2_IRQHandler [WEAK] + EXPORT DMA_Channel3_4_IRQHandler [WEAK] + EXPORT ADC_CMP_IRQHandler [WEAK] + EXPORT TIMER0_BRK_UP_TRG_COM_IRQHandler [WEAK] + EXPORT TIMER0_Channel_IRQHandler [WEAK] + EXPORT TIMER2_IRQHandler [WEAK] + EXPORT TIMER5_IRQHandler [WEAK] + EXPORT TIMER13_IRQHandler [WEAK] + EXPORT TIMER14_IRQHandler [WEAK] + EXPORT TIMER15_IRQHandler [WEAK] + EXPORT TIMER16_IRQHandler [WEAK] + EXPORT I2C0_EV_IRQHandler [WEAK] + EXPORT I2C1_EV_IRQHandler [WEAK] + EXPORT SPI0_IRQHandler [WEAK] + EXPORT SPI1_IRQHandler [WEAK] + EXPORT USART0_IRQHandler [WEAK] + EXPORT USART1_IRQHandler [WEAK] + EXPORT I2C0_ER_IRQHandler [WEAK] + EXPORT I2C1_ER_IRQHandler [WEAK] + +;/* external interrupts handler */ +WWDGT_IRQHandler +LVD_IRQHandler +RTC_IRQHandler +FMC_IRQHandler +RCU_IRQHandler +EXTI0_1_IRQHandler +EXTI2_3_IRQHandler +EXTI4_15_IRQHandler +DMA_Channel0_IRQHandler +DMA_Channel1_2_IRQHandler +DMA_Channel3_4_IRQHandler +ADC_CMP_IRQHandler +TIMER0_BRK_UP_TRG_COM_IRQHandler +TIMER0_Channel_IRQHandler +TIMER2_IRQHandler +TIMER5_IRQHandler +TIMER13_IRQHandler +TIMER14_IRQHandler +TIMER15_IRQHandler +TIMER16_IRQHandler +I2C0_EV_IRQHandler +I2C1_EV_IRQHandler +SPI0_IRQHandler +SPI1_IRQHandler +USART0_IRQHandler +USART1_IRQHandler +I2C0_ER_IRQHandler +I2C1_ER_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 PROC + LDR R0, = Heap_Mem + LDR R1, =(Stack_Mem + Stack_Size) + LDR R2, = (Heap_Mem + Heap_Size) + LDR R3, = Stack_Mem + BX LR + ENDP + + ALIGN + + ENDIF + + END diff --git a/bsp/gd32e230k-start/Libraries/CMSIS/GD/GD32E230/Source/IAR/startup_gd32e230.s b/bsp/gd32e230k-start/Libraries/CMSIS/GD/GD32E230/Source/IAR/startup_gd32e230.s new file mode 100644 index 0000000000000000000000000000000000000000..a491356ce0e0131d5b7941907a9c721515d0cb1f --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/CMSIS/GD/GD32E230/Source/IAR/startup_gd32e230.s @@ -0,0 +1,303 @@ +;/*! +; \file startup_gd32e230.s +; \brief start up file +; +; \version 2018-06-19, V1.0.0, firmware for GD32E230 +;*/ +; +;/* +; Copyright (c) 2018, GigaDevice Semiconductor 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 copyright holder nor the names of its contributors +; may be used to endorse or promote products derived from this software without +; specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +;AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +;WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +;IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +;INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +;NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +;PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +;WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +;ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +;OF SUCH DAMAGE. +;*/ + + MODULE ?cstartup + + ;; Forward declaration of sections. + SECTION CSTACK:DATA:NOROOT(3) + + SECTION .intvec:CODE:NOROOT(2) + + EXTERN __iar_program_start + EXTERN SystemInit + PUBLIC __vector_table + + DATA +__vector_table + DCD sfe(CSTACK) ; top of stack + DCD Reset_Handler ; Vector Number 1,Reset Handler + + DCD NMI_Handler ; Vector Number 2,NMI Handler + DCD HardFault_Handler ; Vector Number 3,Hard Fault Handler + DCD MemManage_Handler ; Vector Number 4,MPU Fault Handler + DCD BusFault_Handler ; Vector Number 5,Bus Fault Handler + DCD UsageFault_Handler ; Vector Number 6,Usage Fault Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler ; Vector Number 11,SVCall Handler + DCD DebugMon_Handler ; Vector Number 12,Debug Monitor Handler + DCD 0 ; Reserved + DCD PendSV_Handler ; Vector Number 14,PendSV Handler + DCD SysTick_Handler ; Vector Number 15,SysTick Handler + + ; External Interrupts + DCD WWDGT_IRQHandler ; 16:Window Watchdog Timer + DCD LVD_IRQHandler ; 17:LVD through EXTI Line detect + DCD RTC_IRQHandler ; 18:RTC through EXTI Line + DCD FMC_IRQHandler ; 19:FMC + DCD RCU_IRQHandler ; 20:RCU + DCD EXTI0_1_IRQHandler ; 21:EXTI Line 0 and EXTI Line 1 + DCD EXTI2_3_IRQHandler ; 22:EXTI Line 2 and EXTI Line 3 + DCD EXTI4_15_IRQHandler ; 23:EXTI Line 4 to EXTI Line 15 + DCD 0 ; Reserved + DCD DMA_Channel0_IRQHandler ; 25:DMA Channel 0 + DCD DMA_Channel1_2_IRQHandler ; 26:DMA Channel 1 and DMA Channel 2 + DCD DMA_Channel3_4_IRQHandler ; 27:DMA Channel 3 and DMA Channel 4 + DCD ADC_CMP_IRQHandler ; 28:ADC and Comparator + DCD TIMER0_BRK_UP_TRG_COM_IRQHandler ; 29:TIMER0 Break,Update,Trigger and Commutation + DCD TIMER0_Channel_IRQHandler ; 30:TIMER0 Channel Capture Compare + DCD 0 ; Reserved + DCD TIMER2_IRQHandler ; 32:TIMER2 + DCD TIMER5_IRQHandler ; 33:TIMER5 + DCD 0 ; Reserved + DCD TIMER13_IRQHandler ; 35:TIMER13 + DCD TIMER14_IRQHandler ; 36:TIMER14 + DCD TIMER15_IRQHandler ; 37:TIMER15 + DCD TIMER16_IRQHandler ; 38:TIMER16 + DCD I2C0_EV_IRQHandler ; 39:I2C0 Event + DCD I2C1_EV_IRQHandler ; 40:I2C1 Event + DCD SPI0_IRQHandler ; 41:SPI0 + DCD SPI1_IRQHandler ; 42:SPI1 + DCD USART0_IRQHandler ; 43:USART0 + DCD USART1_IRQHandler ; 44:USART1 + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD I2C0_ER_IRQHandler ; 48:I2C0 Error + DCD 0 ; Reserved + DCD I2C1_ER_IRQHandler ; 50:I2C1 Error + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Default interrupt handlers. +;; + THUMB + + PUBWEAK Reset_Handler + SECTION .text:CODE:NOROOT:REORDER(2) +Reset_Handler + LDR R0, =SystemInit + BLX R0 + 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 MemManage_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +MemManage_Handler + B MemManage_Handler + + PUBWEAK BusFault_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +BusFault_Handler + B BusFault_Handler + + PUBWEAK UsageFault_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +UsageFault_Handler + B UsageFault_Handler + + PUBWEAK SVC_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +SVC_Handler + B SVC_Handler + + PUBWEAK DebugMon_Handler + SECTION .text:CODE:NOROOT:REORDER(1) +DebugMon_Handler + B DebugMon_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 WWDGT_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +WWDGT_IRQHandler + B WWDGT_IRQHandler + + PUBWEAK LVD_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +LVD_IRQHandler + B LVD_IRQHandler + + PUBWEAK RTC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RTC_IRQHandler + B RTC_IRQHandler + + PUBWEAK FMC_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +FMC_IRQHandler + B FMC_IRQHandler + + PUBWEAK RCU_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +RCU_IRQHandler + B RCU_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 DMA_Channel0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA_Channel0_IRQHandler + B DMA_Channel0_IRQHandler + + PUBWEAK DMA_Channel1_2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA_Channel1_2_IRQHandler + B DMA_Channel1_2_IRQHandler + + PUBWEAK DMA_Channel3_4_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +DMA_Channel3_4_IRQHandler + B DMA_Channel3_4_IRQHandler + + PUBWEAK ADC_CMP_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +ADC_CMP_IRQHandler + B ADC_CMP_IRQHandler + + PUBWEAK TIMER0_BRK_UP_TRG_COM_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER0_BRK_UP_TRG_COM_IRQHandler + B TIMER0_BRK_UP_TRG_COM_IRQHandler + + PUBWEAK TIMER0_Channel_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER0_Channel_IRQHandler + B TIMER0_Channel_IRQHandler + + PUBWEAK TIMER2_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER2_IRQHandler + B TIMER2_IRQHandler + + PUBWEAK TIMER5_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER5_IRQHandler + B TIMER5_IRQHandler + + PUBWEAK TIMER13_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER13_IRQHandler + B TIMER13_IRQHandler + + PUBWEAK TIMER14_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER14_IRQHandler + B TIMER14_IRQHandler + + PUBWEAK TIMER15_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER15_IRQHandler + B TIMER15_IRQHandler + + PUBWEAK TIMER16_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +TIMER16_IRQHandler + B TIMER16_IRQHandler + + PUBWEAK I2C0_EV_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C0_EV_IRQHandler + B I2C0_EV_IRQHandler + + PUBWEAK I2C1_EV_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C1_EV_IRQHandler + B I2C1_EV_IRQHandler + + PUBWEAK SPI0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI0_IRQHandler + B SPI0_IRQHandler + + PUBWEAK SPI1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +SPI1_IRQHandler + B SPI1_IRQHandler + + PUBWEAK USART0_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USART0_IRQHandler + B USART0_IRQHandler + + PUBWEAK USART1_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +USART1_IRQHandler + B USART1_IRQHandler + + PUBWEAK I2C0_ER_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C0_ER_IRQHandler + B I2C0_ER_IRQHandler + + PUBWEAK I2C1_ER_IRQHandler + SECTION .text:CODE:NOROOT:REORDER(1) +I2C1_ER_IRQHandler + B I2C1_ER_IRQHandler + END \ No newline at end of file diff --git a/bsp/gd32e230k-start/Libraries/CMSIS/GD/GD32E230/Source/system_gd32e230.c b/bsp/gd32e230k-start/Libraries/CMSIS/GD/GD32E230/Source/system_gd32e230.c new file mode 100644 index 0000000000000000000000000000000000000000..a4768d181f8edb6241fc74f1be8287105de68fa4 --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/CMSIS/GD/GD32E230/Source/system_gd32e230.c @@ -0,0 +1,371 @@ +/*! + \file system_gd32e230.c + \brief CMSIS Cortex-M23 Device Peripheral Access Layer Source File for + GD32E1x0 Device Series +*/ + +/* Copyright (c) 2012 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. + ---------------------------------------------------------------------------*/ + +/* This file refers the CMSIS standard, some adjustments are made according to GigaDevice chips */ + +#include "gd32e230.h" + +/* system frequency define */ +#define __IRC8M (IRC8M_VALUE) /* internal 8 MHz RC oscillator frequency */ +#define __HXTAL (HXTAL_VALUE) /* high speed crystal oscillator frequency */ +#define __SYS_OSC_CLK (__IRC8M) /* main oscillator frequency */ + +#define VECT_TAB_OFFSET (uint32_t)0x00 /* vector table base offset */ + +/* select a system clock by uncommenting the following line */ +//#define __SYSTEM_CLOCK_8M_HXTAL (__HXTAL) +//#define __SYSTEM_CLOCK_8M_IRC8M (__IRC8M) +#define __SYSTEM_CLOCK_72M_PLL_HXTAL (uint32_t)(72000000) +//#define __SYSTEM_CLOCK_72M_PLL_IRC8M_DIV2 (uint32_t)(72000000) + +#define SEL_IRC8M 0x00 +#define SEL_HXTAL 0x01 +#define SEL_PLL 0x02 + +/* set the system clock frequency and declare the system clock configuration function */ +#ifdef __SYSTEM_CLOCK_8M_HXTAL +uint32_t SystemCoreClock = __SYSTEM_CLOCK_8M_HXTAL; +static void system_clock_8m_hxtal(void); + +#elif defined (__SYSTEM_CLOCK_72M_PLL_HXTAL) +uint32_t SystemCoreClock = __SYSTEM_CLOCK_72M_PLL_HXTAL; +static void system_clock_72m_hxtal(void); + +#elif defined (__SYSTEM_CLOCK_72M_PLL_IRC8M_DIV2) +uint32_t SystemCoreClock = __SYSTEM_CLOCK_72M_PLL_IRC8M_DIV2; +static void system_clock_72m_irc8m(void); + +#else +uint32_t SystemCoreClock = __SYSTEM_CLOCK_8M_IRC8M; +static void system_clock_8m_irc8m(void); +#endif /* __SYSTEM_CLOCK_8M_HXTAL */ + +/* configure the system clock */ +static void system_clock_config(void); + +/*! + \brief setup the microcontroller system, initialize the system + \param[in] none + \param[out] none + \retval none +*/ +void SystemInit (void) +{ + /* enable IRC8M */ + RCU_CTL0 |= RCU_CTL0_IRC8MEN; + while(0U == (RCU_CTL0 & RCU_CTL0_IRC8MSTB)){ + } + /* reset RCU */ + RCU_CFG0 &= ~(RCU_CFG0_SCS | RCU_CFG0_AHBPSC | RCU_CFG0_APB1PSC | RCU_CFG0_APB2PSC |\ + RCU_CFG0_ADCPSC | RCU_CFG0_CKOUTSEL | RCU_CFG0_CKOUTDIV | RCU_CFG0_PLLDV); + RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PLLMF | RCU_CFG0_PLLMF4 | RCU_CFG0_PLLDV); + RCU_CTL0 &= ~(RCU_CTL0_HXTALEN | RCU_CTL0_CKMEN | RCU_CTL0_PLLEN | RCU_CTL0_HXTALBPS); + RCU_CFG1 &= ~(RCU_CFG1_PREDV); + RCU_CFG2 &= ~(RCU_CFG2_USART0SEL | RCU_CFG2_ADCSEL); + RCU_CFG2 &= ~RCU_CFG2_IRC28MDIV; + RCU_CFG2 &= ~RCU_CFG2_ADCPSC2; + RCU_CTL1 &= ~RCU_CTL1_IRC28MEN; + RCU_INT = 0x00000000U; + + /* configure system clock */ + system_clock_config(); + +#ifdef VECT_TAB_SRAM + nvic_vector_table_set(NVIC_VECTTAB_RAM,VECT_TAB_OFFSET); +#else + nvic_vector_table_set(NVIC_VECTTAB_FLASH,VECT_TAB_OFFSET); +#endif +} + +/*! + \brief configure the system clock + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_config(void) +{ +#ifdef __SYSTEM_CLOCK_8M_HXTAL + system_clock_8m_hxtal(); +#elif defined (__SYSTEM_CLOCK_72M_PLL_HXTAL) + system_clock_72m_hxtal(); +#elif defined (__SYSTEM_CLOCK_72M_PLL_IRC8M_DIV2) + system_clock_72m_irc8m(); +#elif defined (__SYSTEM_CLOCK_72M_PLL_IRC48M_DIV2) + system_clock_72m_irc48m(); +#else + system_clock_8m_irc8m(); +#endif /* __SYSTEM_CLOCK_8M_HXTAL */ +} + +#ifdef __SYSTEM_CLOCK_8M_HXTAL +/*! + \brief configure the system clock to 8M by HXTAL + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_8m_hxtal(void) +{ + uint32_t timeout = 0U; + uint32_t stab_flag = 0U; + + /* enable HXTAL */ + RCU_CTL0 |= RCU_CTL0_HXTALEN; + + /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */ + do{ + timeout++; + stab_flag = (RCU_CTL0 & RCU_CTL0_HXTALSTB); + } + while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout)); + /* if fail */ + if(0U == (RCU_CTL0 & RCU_CTL0_HXTALSTB)){ + while(1){ + } + } + + /* HXTAL is stable */ + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; + /* APB1 = AHB */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV1; + + /* select HXTAL as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_HXTAL; + + /* wait until HXTAL is selected as system clock */ + while(0U == (RCU_CFG0 & RCU_SCSS_HXTAL)){ + } +} + +#elif defined (__SYSTEM_CLOCK_72M_PLL_HXTAL) +/*! + \brief configure the system clock to 72M by PLL which selects HXTAL as its clock source + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_72m_hxtal(void) +{ + uint32_t timeout = 0U; + uint32_t stab_flag = 0U; + + /* enable HXTAL */ + RCU_CTL0 |= RCU_CTL0_HXTALEN; + + /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */ + do{ + timeout++; + stab_flag = (RCU_CTL0 & RCU_CTL0_HXTALSTB); + } + while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout)); + /* if fail */ + if(0U == (RCU_CTL0 & RCU_CTL0_HXTALSTB)){ + while(1){ + } + } + + FMC_WS &= ~FMC_WS_WSCNT; + FMC_WS |= WS_WSCNT_2; + + /* HXTAL is stable */ + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; + /* APB1 = AHB */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV1; + + /* PLL = HXTAL * 9 = 72 MHz */ + RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PLLMF | RCU_CFG0_PLLDV); + RCU_CFG0 |= (RCU_PLLSRC_HXTAL | RCU_PLL_MUL9); + + /* enable PLL */ + RCU_CTL0 |= RCU_CTL0_PLLEN; + + /* wait until PLL is stable */ + while(0U == (RCU_CTL0 & RCU_CTL0_PLLSTB)){ + } + + /* select PLL as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_PLL; + + /* wait until PLL is selected as system clock */ + while(0U == (RCU_CFG0 & RCU_SCSS_PLL)){ + } +} + +#elif defined (__SYSTEM_CLOCK_72M_PLL_IRC8M_DIV2) +/*! + \brief configure the system clock to 72M by PLL which selects IRC8M/2 as its clock source + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_72m_irc8m(void) +{ + uint32_t timeout = 0U; + uint32_t stab_flag = 0U; + + /* enable IRC8M */ + RCU_CTL0 |= RCU_CTL0_IRC8MEN; + + /* wait until IRC8M is stable or the startup time is longer than IRC8M_STARTUP_TIMEOUT */ + do{ + timeout++; + stab_flag = (RCU_CTL0 & RCU_CTL0_IRC8MSTB); + } + while((0U == stab_flag) && (IRC8M_STARTUP_TIMEOUT != timeout)); + + /* if fail */ + if(0U == (RCU_CTL0 & RCU_CTL0_IRC8MSTB)){ + while(1){ + } + } + + FMC_WS &= ~FMC_WS_WSCNT; + FMC_WS |= WS_WSCNT_2; + + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; + /* APB1 = AHB */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV1; + /* PLL = (IRC8M/2) * 18 = 72 MHz */ + RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PLLMF); + RCU_CFG0 |= (RCU_PLLSRC_IRC8M_DIV2 | RCU_PLL_MUL18); + + /* enable PLL */ + RCU_CTL0 |= RCU_CTL0_PLLEN; + + /* wait until PLL is stable */ + while(0U == (RCU_CTL0 & RCU_CTL0_PLLSTB)){ + } + + /* select PLL as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_PLL; + + /* wait until PLL is selected as system clock */ + while(0U == (RCU_CFG0 & RCU_SCSS_PLL)){ + } +} + +#else +/*! + \brief configure the system clock to 8M by IRC8M + \param[in] none + \param[out] none + \retval none +*/ +static void system_clock_8m_irc8m(void) +{ + /* AHB = SYSCLK */ + RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; + /* APB2 = AHB */ + RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; + /* APB1 = AHB */ + RCU_CFG0 |= RCU_APB1_CKAHB_DIV1; + + /* select IRC8M as system clock */ + RCU_CFG0 &= ~RCU_CFG0_SCS; + RCU_CFG0 |= RCU_CKSYSSRC_IRC8M; + + /* wait until IRC8M is selected as system clock */ + while(0U != (RCU_CFG0 & RCU_SCSS_IRC8M)){ + } +} +#endif /* __SYSTEM_CLOCK_8M_HXTAL */ + +/*! + \brief update the SystemCoreClock with current core clock retrieved from cpu registers + \param[in] none + \param[out] none + \retval none +*/ +void SystemCoreClockUpdate (void) +{ + uint32_t sws = 0U; + uint32_t pllmf = 0U, pllmf4 = 0U, pllsel = 0U, prediv = 0U, idx = 0U, clk_exp = 0U; + /* exponent of AHB clock divider */ + const uint8_t ahb_exp[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; + + sws = GET_BITS(RCU_CFG0, 2, 3); + switch(sws){ + /* IRC8M is selected as CK_SYS */ + case SEL_IRC8M: + SystemCoreClock = IRC8M_VALUE; + break; + /* HXTAL is selected as CK_SYS */ + case SEL_HXTAL: + SystemCoreClock = HXTAL_VALUE; + break; + /* PLL is selected as CK_SYS */ + case SEL_PLL: + /* get the value of PLLMF[3:0] */ + pllmf = GET_BITS(RCU_CFG0, 18, 21); + pllmf4 = GET_BITS(RCU_CFG0, 27, 27); + /* high 16 bits */ + if(1U == pllmf4){ + pllmf += 17U; + }else if(15U == pllmf){ + pllmf = 16U; + }else{ + pllmf += 2U; + } + + /* PLL clock source selection, HXTAL or IRC8M/2 */ + pllsel = GET_BITS(RCU_CFG0, 16, 16); + if(0U != pllsel){ + prediv = (GET_BITS(RCU_CFG1, 0, 3) + 1U); + SystemCoreClock = (HXTAL_VALUE / prediv) * pllmf; + }else{ + SystemCoreClock = (IRC8M_VALUE >> 1) * pllmf; + } + break; + /* IRC8M is selected as CK_SYS */ + default: + SystemCoreClock = IRC8M_VALUE; + break; + } + /* calculate AHB clock frequency */ + idx = GET_BITS(RCU_CFG0, 4, 7); + clk_exp = ahb_exp[idx]; + SystemCoreClock >>= clk_exp; +} diff --git a/bsp/gd32e230k-start/Libraries/CMSIS/cmsis_compiler.h b/bsp/gd32e230k-start/Libraries/CMSIS/cmsis_compiler.h new file mode 100644 index 0000000000000000000000000000000000000000..fdb1a971c6a8c8defab24e25879172e86939c1ba --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/CMSIS/cmsis_compiler.h @@ -0,0 +1,271 @@ +/**************************************************************************//** + * @file cmsis_compiler.h + * @brief CMSIS compiler generic header file + * @version V5.1.0 + * @date 09. October 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.6 LTM (armclang) + */ +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) && (__ARMCC_VERSION < 6100100) + #include "cmsis_armclang_ltm.h" + + /* + * Arm Compiler above 6.10.1 (armclang) + */ +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6100100) + #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 + #define __RESTRICT __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/gd32e230k-start/Libraries/CMSIS/cmsis_gcc.h b/bsp/gd32e230k-start/Libraries/CMSIS/cmsis_gcc.h new file mode 100644 index 0000000000000000000000000000000000000000..d86b0a2d5a6d38996d772cb79b574567d287a8da --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/CMSIS/cmsis_gcc.h @@ -0,0 +1,2101 @@ +/**************************************************************************//** + * @file cmsis_gcc.h + * @brief CMSIS compiler GCC header file + * @version V5.1.0 + * @date 20. December 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_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) +{ + 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) +{ + 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) +{ + 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) +{ + 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) +{ + 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 + 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 + 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 + 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 + 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)) ) */ + + +/** + \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) +// Re-enable using built-in when GCC has been fixed +// || (__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) +// Re-enable using built-in when GCC has been fixed +// || (__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 +} + + +/*@} 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 + */ +__STATIC_FORCEINLINE uint8_t __CLZ(uint32_t value) +{ + /* Even though __builtin_clz produces a CLZ instruction on ARM, formally + __builtin_clz(0) is undefined behaviour, so handle this case specially. + This guarantees ARM-compatible results if happening to compile on a non-ARM + target, and ensures the compiler doesn't decide to activate any + optimisations using the logic "value was passed to __builtin_clz, so it + is non-zero". + ARM GCC 7.3 and possibly earlier will optimise this test away, leaving a + single CLZ instruction. + */ + if (value == 0U) + { + return 32U; + } + return __builtin_clz(value); +} + + +#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/gd32e230k-start/Libraries/CMSIS/cmsis_version.h b/bsp/gd32e230k-start/Libraries/CMSIS/cmsis_version.h new file mode 100644 index 0000000000000000000000000000000000000000..660f612aa31fe2a71cc786af5cac407e41fdd144 --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/CMSIS/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/gd32e230k-start/Libraries/CMSIS/core_cm23.h b/bsp/gd32e230k-start/Libraries/CMSIS/core_cm23.h new file mode 100644 index 0000000000000000000000000000000000000000..26fe163a0e82caad81aa359afbe6aa5e1e5bcf62 --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/CMSIS/core_cm23.h @@ -0,0 +1,1993 @@ +/**************************************************************************//** + * @file core_cm23.h + * @brief CMSIS Cortex-M23 Core Peripheral Access Layer Header File + * @version V5.0.8 + * @date 12. November 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_FP + #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_NMIPENDSET_Pos SCB_ICSR_PENDNMISET_Pos /*!< SCB ICSR: NMIPENDSET Position, backward compatibility */ +#define SCB_ICSR_NMIPENDSET_Msk SCB_ICSR_PENDNMISET_Msk /*!< SCB ICSR: NMIPENDSET Mask, backward compatibility */ + +#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 +{ + __IM 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 */ + __IOM uint32_t PSCR; /*!< Offset: 0x308 (R/W) Periodic Synchronization Control Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER Register */ + __IM uint32_t ITFTTD0; /*!< Offset: 0xEEC (R/ ) Integration Test FIFO Test Data 0 Register */ + __IOM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/W) Integration Test ATB Control Register 2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) Integration Test ATB Control Register 0 */ + __IM uint32_t ITFTTD1; /*!< Offset: 0xEFC (R/ ) Integration Test FIFO Test Data 1 Register */ + __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/ ) Device Configuration Register */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) Device Type Identifier Register */ +} 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_FOnMan_Pos 6U /*!< TPI FFCR: FOnMan Position */ +#define TPI_FFCR_FOnMan_Msk (0x1UL << TPI_FFCR_FOnMan_Pos) /*!< TPI FFCR: FOnMan 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 Test FIFO Test Data 0 Register Definitions */ +#define TPI_ITFTTD0_ATB_IF2_ATVALID_Pos 29U /*!< TPI ITFTTD0: ATB Interface 2 ATVALIDPosition */ +#define TPI_ITFTTD0_ATB_IF2_ATVALID_Msk (0x3UL << TPI_ITFTTD0_ATB_IF2_ATVALID_Pos) /*!< TPI ITFTTD0: ATB Interface 2 ATVALID Mask */ + +#define TPI_ITFTTD0_ATB_IF2_bytecount_Pos 27U /*!< TPI ITFTTD0: ATB Interface 2 byte count Position */ +#define TPI_ITFTTD0_ATB_IF2_bytecount_Msk (0x3UL << TPI_ITFTTD0_ATB_IF2_bytecount_Pos) /*!< TPI ITFTTD0: ATB Interface 2 byte count Mask */ + +#define TPI_ITFTTD0_ATB_IF1_ATVALID_Pos 26U /*!< TPI ITFTTD0: ATB Interface 1 ATVALID Position */ +#define TPI_ITFTTD0_ATB_IF1_ATVALID_Msk (0x3UL << TPI_ITFTTD0_ATB_IF1_ATVALID_Pos) /*!< TPI ITFTTD0: ATB Interface 1 ATVALID Mask */ + +#define TPI_ITFTTD0_ATB_IF1_bytecount_Pos 24U /*!< TPI ITFTTD0: ATB Interface 1 byte count Position */ +#define TPI_ITFTTD0_ATB_IF1_bytecount_Msk (0x3UL << TPI_ITFTTD0_ATB_IF1_bytecount_Pos) /*!< TPI ITFTTD0: ATB Interface 1 byte countt Mask */ + +#define TPI_ITFTTD0_ATB_IF1_data2_Pos 16U /*!< TPI ITFTTD0: ATB Interface 1 data2 Position */ +#define TPI_ITFTTD0_ATB_IF1_data2_Msk (0xFFUL << TPI_ITFTTD0_ATB_IF1_data1_Pos) /*!< TPI ITFTTD0: ATB Interface 1 data2 Mask */ + +#define TPI_ITFTTD0_ATB_IF1_data1_Pos 8U /*!< TPI ITFTTD0: ATB Interface 1 data1 Position */ +#define TPI_ITFTTD0_ATB_IF1_data1_Msk (0xFFUL << TPI_ITFTTD0_ATB_IF1_data1_Pos) /*!< TPI ITFTTD0: ATB Interface 1 data1 Mask */ + +#define TPI_ITFTTD0_ATB_IF1_data0_Pos 0U /*!< TPI ITFTTD0: ATB Interface 1 data0 Position */ +#define TPI_ITFTTD0_ATB_IF1_data0_Msk (0xFFUL /*<< TPI_ITFTTD0_ATB_IF1_data0_Pos*/) /*!< TPI ITFTTD0: ATB Interface 1 data0 Mask */ + +/* TPI Integration Test ATB Control Register 2 Register Definitions */ +#define TPI_ITATBCTR2_AFVALID2S_Pos 1U /*!< TPI ITATBCTR2: AFVALID2S Position */ +#define TPI_ITATBCTR2_AFVALID2S_Msk (0x1UL << TPI_ITATBCTR2_AFVALID2S_Pos) /*!< TPI ITATBCTR2: AFVALID2SS Mask */ + +#define TPI_ITATBCTR2_AFVALID1S_Pos 1U /*!< TPI ITATBCTR2: AFVALID1S Position */ +#define TPI_ITATBCTR2_AFVALID1S_Msk (0x1UL << TPI_ITATBCTR2_AFVALID1S_Pos) /*!< TPI ITATBCTR2: AFVALID1SS Mask */ + +#define TPI_ITATBCTR2_ATREADY2S_Pos 0U /*!< TPI ITATBCTR2: ATREADY2S Position */ +#define TPI_ITATBCTR2_ATREADY2S_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY2S_Pos*/) /*!< TPI ITATBCTR2: ATREADY2S Mask */ + +#define TPI_ITATBCTR2_ATREADY1S_Pos 0U /*!< TPI ITATBCTR2: ATREADY1S Position */ +#define TPI_ITATBCTR2_ATREADY1S_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY1S_Pos*/) /*!< TPI ITATBCTR2: ATREADY1S Mask */ + +/* TPI Integration Test FIFO Test Data 1 Register Definitions */ +#define TPI_ITFTTD1_ATB_IF2_ATVALID_Pos 29U /*!< TPI ITFTTD1: ATB Interface 2 ATVALID Position */ +#define TPI_ITFTTD1_ATB_IF2_ATVALID_Msk (0x3UL << TPI_ITFTTD1_ATB_IF2_ATVALID_Pos) /*!< TPI ITFTTD1: ATB Interface 2 ATVALID Mask */ + +#define TPI_ITFTTD1_ATB_IF2_bytecount_Pos 27U /*!< TPI ITFTTD1: ATB Interface 2 byte count Position */ +#define TPI_ITFTTD1_ATB_IF2_bytecount_Msk (0x3UL << TPI_ITFTTD1_ATB_IF2_bytecount_Pos) /*!< TPI ITFTTD1: ATB Interface 2 byte count Mask */ + +#define TPI_ITFTTD1_ATB_IF1_ATVALID_Pos 26U /*!< TPI ITFTTD1: ATB Interface 1 ATVALID Position */ +#define TPI_ITFTTD1_ATB_IF1_ATVALID_Msk (0x3UL << TPI_ITFTTD1_ATB_IF1_ATVALID_Pos) /*!< TPI ITFTTD1: ATB Interface 1 ATVALID Mask */ + +#define TPI_ITFTTD1_ATB_IF1_bytecount_Pos 24U /*!< TPI ITFTTD1: ATB Interface 1 byte count Position */ +#define TPI_ITFTTD1_ATB_IF1_bytecount_Msk (0x3UL << TPI_ITFTTD1_ATB_IF1_bytecount_Pos) /*!< TPI ITFTTD1: ATB Interface 1 byte countt Mask */ + +#define TPI_ITFTTD1_ATB_IF2_data2_Pos 16U /*!< TPI ITFTTD1: ATB Interface 2 data2 Position */ +#define TPI_ITFTTD1_ATB_IF2_data2_Msk (0xFFUL << TPI_ITFTTD1_ATB_IF2_data1_Pos) /*!< TPI ITFTTD1: ATB Interface 2 data2 Mask */ + +#define TPI_ITFTTD1_ATB_IF2_data1_Pos 8U /*!< TPI ITFTTD1: ATB Interface 2 data1 Position */ +#define TPI_ITFTTD1_ATB_IF2_data1_Msk (0xFFUL << TPI_ITFTTD1_ATB_IF2_data1_Pos) /*!< TPI ITFTTD1: ATB Interface 2 data1 Mask */ + +#define TPI_ITFTTD1_ATB_IF2_data0_Pos 0U /*!< TPI ITFTTD1: ATB Interface 2 data0 Position */ +#define TPI_ITFTTD1_ATB_IF2_data0_Msk (0xFFUL /*<< TPI_ITFTTD1_ATB_IF2_data0_Pos*/) /*!< TPI ITFTTD1: ATB Interface 2 data0 Mask */ + +/* TPI Integration Test ATB Control Register 0 Definitions */ +#define TPI_ITATBCTR0_AFVALID2S_Pos 1U /*!< TPI ITATBCTR0: AFVALID2S Position */ +#define TPI_ITATBCTR0_AFVALID2S_Msk (0x1UL << TPI_ITATBCTR0_AFVALID2S_Pos) /*!< TPI ITATBCTR0: AFVALID2SS Mask */ + +#define TPI_ITATBCTR0_AFVALID1S_Pos 1U /*!< TPI ITATBCTR0: AFVALID1S Position */ +#define TPI_ITATBCTR0_AFVALID1S_Msk (0x1UL << TPI_ITATBCTR0_AFVALID1S_Pos) /*!< TPI ITATBCTR0: AFVALID1SS Mask */ + +#define TPI_ITATBCTR0_ATREADY2S_Pos 0U /*!< TPI ITATBCTR0: ATREADY2S Position */ +#define TPI_ITATBCTR0_ATREADY2S_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY2S_Pos*/) /*!< TPI ITATBCTR0: ATREADY2S Mask */ + +#define TPI_ITATBCTR0_ATREADY1S_Pos 0U /*!< TPI ITATBCTR0: ATREADY1S Position */ +#define TPI_ITATBCTR0_ATREADY1S_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY1S_Pos*/) /*!< TPI ITATBCTR0: ATREADY1S Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x3UL /*<< 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_FIFOSZ_Pos 6U /*!< TPI DEVID: FIFOSZ Position */ +#define TPI_DEVID_FIFOSZ_Msk (0x7UL << TPI_DEVID_FIFOSZ_Pos) /*!< TPI DEVID: FIFOSZ Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x3FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 4U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 0U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType 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 + + +/* Special LR values for Secure/Non-Secure call handling and exception handling */ + +/* Function Return Payload (from ARMv8-M Architecture Reference Manual) LR value on entry from Secure BLXNS */ +#define FNC_RETURN (0xFEFFFFFFUL) /* bit [0] ignored when processing a branch */ + +/* The following EXC_RETURN mask values are used to evaluate the LR on exception entry */ +#define EXC_RETURN_PREFIX (0xFF000000UL) /* bits [31:24] set to indicate an EXC_RETURN value */ +#define EXC_RETURN_S (0x00000040UL) /* bit [6] stack used to push registers: 0=Non-secure 1=Secure */ +#define EXC_RETURN_DCRS (0x00000020UL) /* bit [5] stacking rules for called registers: 0=skipped 1=saved */ +#define EXC_RETURN_FTYPE (0x00000010UL) /* bit [4] allocate stack for floating-point context: 0=done 1=skipped */ +#define EXC_RETURN_MODE (0x00000008UL) /* bit [3] processor mode for return: 0=Handler mode 1=Thread mode */ +#define EXC_RETURN_SPSEL (0x00000004UL) /* bit [2] stack pointer used to restore context: 0=MSP 1=PSP */ +#define EXC_RETURN_ES (0x00000001UL) /* bit [0] security state exception was taken to: 0=Non-secure 1=Secure */ + +/* Integrity Signature (from ARMv8-M Architecture Reference Manual) for exception context stacking */ +#if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) /* Value for processors with floating-point extension: */ +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125AUL) /* bit [0] SFTC must match LR bit[4] EXC_RETURN_FTYPE */ +#else +#define EXC_INTEGRITY_SIGNATURE (0xFEFA125BUL) /* Value for processors without floating-point extension */ +#endif + + +/* 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) ) + +#define __NVIC_SetPriorityGrouping(X) (void)(X) +#define __NVIC_GetPriorityGrouping() (0U) + +/** + \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 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. + 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. + */ +__NO_RETURN __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/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_adc.h b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_adc.h new file mode 100644 index 0000000000000000000000000000000000000000..2ffbec390ec54f4f0fa1162b7a4398c57e4fa074 --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_adc.h @@ -0,0 +1,351 @@ +/*! + \file gd32e230_adc.h + \brief definitions for the ADC + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor 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 copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 GD32E230_ADC_H +#define GD32E230_ADC_H + +#include "gd32e230.h" + +/* ADC definitions */ +#define ADC ADC_BASE + +/* registers definitions */ +#define ADC_STAT REG32(ADC + 0x00U) /*!< ADC status register */ +#define ADC_CTL0 REG32(ADC + 0x04U) /*!< ADC control register 0 */ +#define ADC_CTL1 REG32(ADC + 0x08U) /*!< ADC control register 1 */ +#define ADC_SAMPT0 REG32(ADC + 0x0CU) /*!< ADC sampling time register 0 */ +#define ADC_SAMPT1 REG32(ADC + 0x10U) /*!< ADC sampling time register 1 */ +#define ADC_IOFF0 REG32(ADC + 0x14U) /*!< ADC inserted channel data offset register 0 */ +#define ADC_IOFF1 REG32(ADC + 0x18U) /*!< ADC inserted channel data offset register 1 */ +#define ADC_IOFF2 REG32(ADC + 0x1CU) /*!< ADC inserted channel data offset register 2 */ +#define ADC_IOFF3 REG32(ADC + 0x20U) /*!< ADC inserted channel data offset register 3 */ +#define ADC_WDHT REG32(ADC + 0x24U) /*!< ADC watchdog high threshold register */ +#define ADC_WDLT REG32(ADC + 0x28U) /*!< ADC watchdog low threshold register */ +#define ADC_RSQ0 REG32(ADC + 0x2CU) /*!< ADC regular sequence register 0 */ +#define ADC_RSQ1 REG32(ADC + 0x30U) /*!< ADC regular sequence register 1 */ +#define ADC_RSQ2 REG32(ADC + 0x34U) /*!< ADC regular sequence register 2 */ +#define ADC_ISQ REG32(ADC + 0x38U) /*!< ADC inserted sequence register */ +#define ADC_IDATA0 REG32(ADC + 0x3CU) /*!< ADC inserted data register 0 */ +#define ADC_IDATA1 REG32(ADC + 0x40U) /*!< ADC inserted data register 1 */ +#define ADC_IDATA2 REG32(ADC + 0x44U) /*!< ADC inserted data register 2 */ +#define ADC_IDATA3 REG32(ADC + 0x48U) /*!< ADC inserted data register 3 */ +#define ADC_RDATA REG32(ADC + 0x4CU) /*!< ADC regular data register */ +#define ADC_OVSAMPCTL REG32(ADC + 0x80U) /*!< ADC oversampling control register */ + +/* bits definitions */ +/* ADC_STAT */ +#define ADC_STAT_WDE BIT(0) /*!< analog watchdog event flag */ +#define ADC_STAT_EOC BIT(1) /*!< end of conversion flag */ +#define ADC_STAT_EOIC BIT(2) /*!< inserted channel end of conversion flag */ +#define ADC_STAT_STIC BIT(3) /*!< inserted channel start flag */ +#define ADC_STAT_STRC BIT(4) /*!< regular channel start flag */ + +/* ADC_CTL0 */ +#define ADC_CTL0_WDCHSEL BITS(0,4) /*!< analog watchdog channel select bits */ +#define ADC_CTL0_EOCIE BIT(5) /*!< interrupt enable for EOC */ +#define ADC_CTL0_WDEIE BIT(6) /*!< analog watchdog interrupt enable */ +#define ADC_CTL0_EOICIE BIT(7) /*!< interrupt enable for inserted channels */ +#define ADC_CTL0_SM BIT(8) /*!< scan mode */ +#define ADC_CTL0_WDSC BIT(9) /*!< when in scan mode, analog watchdog is effective on a single channel */ +#define ADC_CTL0_ICA BIT(10) /*!< automatic inserted group conversion */ +#define ADC_CTL0_DISRC BIT(11) /*!< discontinuous mode on regular channels */ +#define ADC_CTL0_DISIC BIT(12) /*!< discontinuous mode on inserted channels */ +#define ADC_CTL0_DISNUM BITS(13,15) /*!< discontinuous mode channel count */ +#define ADC_CTL0_IWDEN BIT(22) /*!< analog watchdog enable on inserted channels */ +#define ADC_CTL0_RWDEN BIT(23) /*!< analog watchdog enable on regular channels */ +#define ADC_CTL0_DRES BITS(24,25) /*!< ADC data resolution */ + +/* ADC_CTL1 */ +#define ADC_CTL1_ADCON BIT(0) /*!< ADC converter on */ +#define ADC_CTL1_CTN BIT(1) /*!< continuous conversion */ +#define ADC_CTL1_CLB BIT(2) /*!< ADC calibration */ +#define ADC_CTL1_RSTCLB BIT(3) /*!< reset calibration */ +#define ADC_CTL1_DMA BIT(8) /*!< direct memory access mode */ +#define ADC_CTL1_DAL BIT(11) /*!< data alignment */ +#define ADC_CTL1_ETSIC BITS(12,14) /*!< external trigger select for inserted channel */ +#define ADC_CTL1_ETEIC BIT(15) /*!< external trigger enable for inserted channel */ +#define ADC_CTL1_ETSRC BITS(17,19) /*!< external trigger select for regular channel */ +#define ADC_CTL1_ETERC BIT(20) /*!< external trigger enable for regular channel */ +#define ADC_CTL1_SWICST BIT(21) /*!< start on inserted channel */ +#define ADC_CTL1_SWRCST BIT(22) /*!< start on regular channel */ +#define ADC_CTL1_TSVREN BIT(23) /*!< enable channel 16 and 17 */ + +/* ADC_SAMPTx x=0,1 */ +#define ADC_SAMPTX_SPTN BITS(0,2) /*!< channel n(n=0..9,16 and 17) sample time selection */ + +/* ADC_IOFFx x=0..3 */ +#define ADC_IOFFX_IOFF BITS(0,11) /*!< data offset for inserted channel x */ + +/* ADC_WDHT */ +#define ADC_WDHT_WDHT BITS(0,11) /*!< analog watchdog high threshold */ + +/* ADC_WDLT */ +#define ADC_WDLT_WDLT BITS(0,11) /*!< analog watchdog low threshold */ + +/* ADC_RSQx x=0..2 */ +#define ADC_RSQX_RSQN BITS(0,4) /*!< n conversion in regular sequence */ +#define ADC_RSQ0_RL BITS(20,23) /*!< regular channel sequence length */ + +/* ADC_ISQ */ +#define ADC_ISQ_ISQN BITS(0,4) /*!< n conversion in regular sequence */ +#define ADC_ISQ_IL BITS(20,21) /*!< inserted sequence length */ + +/* ADC_IDATAx x=0..3*/ +#define ADC_IDATAX_IDATAN BITS(0,15) /*!< inserted channel x conversion data */ + +/* ADC_RDATA */ +#define ADC_RDATA_RDATA BITS(0,15) /*!< regular channel data */ + +/* ADC_OVSAMPCTL */ +#define ADC_OVSAMPCTL_OVSEN BIT(0) /*!< oversampling enable */ +#define ADC_OVSAMPCTL_OVSR BITS(2,4) /*!< oversampling ratio */ +#define ADC_OVSAMPCTL_OVSS BITS(5,8) /*!< oversampling shift */ +#define ADC_OVSAMPCTL_TOVS BIT(9) /*!< triggered oversampling */ + +/* constants definitions */ +/* ADC flag definitions */ +#define ADC_FLAG_WDE ADC_STAT_WDE /*!< analog watchdog event flag */ +#define ADC_FLAG_EOC ADC_STAT_EOC /*!< end of group conversion flag */ +#define ADC_FLAG_EOIC ADC_STAT_EOIC /*!< end of inserted channel group conversion flag */ +#define ADC_FLAG_STIC ADC_STAT_STIC /*!< start flag of inserted channel group */ +#define ADC_FLAG_STRC ADC_STAT_STRC /*!< start flag of regular channel group */ + +/* adc_ctl0 register value */ +#define CTL0_DISNUM(regval) (BITS(13,15) & ((uint32_t)(regval) << 13)) /*!< number of conversions in discontinuous mode */ + +/* ADC special function */ +#define ADC_SCAN_MODE ADC_CTL0_SM /*!< scan mode */ +#define ADC_INSERTED_CHANNEL_AUTO ADC_CTL0_ICA /*!< inserted channel group convert automatically */ +#define ADC_CONTINUOUS_MODE ADC_CTL1_CTN /*!< continuous mode */ + +/* ADC data alignment */ +#define ADC_DATAALIGN_RIGHT ((uint32_t)0x00000000U) /*!< right alignment */ +#define ADC_DATAALIGN_LEFT ADC_CTL1_DAL /*!< left alignment */ + +/* external trigger select for regular channel */ +#define CTL1_ETSRC(regval) (BITS(17,19) & ((uint32_t)(regval) << 17)) +#define ADC_EXTTRIG_REGULAR_T0_CH0 CTL1_ETSRC(0) /*!< TIMER0 CH0 event select */ +#define ADC_EXTTRIG_REGULAR_T0_CH1 CTL1_ETSRC(1) /*!< TIMER0 CH1 event select */ +#define ADC_EXTTRIG_REGULAR_T0_CH2 CTL1_ETSRC(2) /*!< TIMER0 CH2 event select */ +#define ADC_EXTTRIG_REGULAR_T2_TRGO CTL1_ETSRC(4) /*!< TIMER2 TRGO event select */ +#define ADC_EXTTRIG_REGULAR_T14_CH0 CTL1_ETSRC(5) /*!< TIMER14 CH0 event select */ +#define ADC_EXTTRIG_REGULAR_EXTI_11 CTL1_ETSRC(6) /*!< external interrupt line 11 */ +#define ADC_EXTTRIG_REGULAR_NONE CTL1_ETSRC(7) /*!< software trigger */ + +/* external trigger select for inserted channel */ +#define CTL1_ETSIC(regval) (BITS(12,14) & ((uint32_t)(regval) << 12)) +#define ADC_EXTTRIG_INSERTED_T0_TRGO CTL1_ETSIC(0) /*!< TIMER0 TRGO event select */ +#define ADC_EXTTRIG_INSERTED_T0_CH3 CTL1_ETSIC(1) /*!< TIMER0 CH3 event select */ +#define ADC_EXTTRIG_INSERTED_T2_CH3 CTL1_ETSIC(4) /*!< TIMER2 CH3 event select */ +#define ADC_EXTTRIG_INSERTED_T14_TRGO CTL1_ETSIC(5) /*!< TIMER14 TRGO event select */ +#define ADC_EXTTRIG_INSERTED_EXTI_15 CTL1_ETSIC(6) /*!< external interrupt line 15 */ +#define ADC_EXTTRIG_INSERTED_NONE CTL1_ETSIC(7) /*!< software trigger */ + +/* adc_samptx register value */ +#define SAMPTX_SPT(regval) (BITS(0,2) & ((uint32_t)(regval) << 0)) +#define ADC_SAMPLETIME_1POINT5 SAMPTX_SPT(0) /*!< 1.5 sampling cycles */ +#define ADC_SAMPLETIME_7POINT5 SAMPTX_SPT(1) /*!< 7.5 sampling cycles */ +#define ADC_SAMPLETIME_13POINT5 SAMPTX_SPT(2) /*!< 13.5 sampling cycles */ +#define ADC_SAMPLETIME_28POINT5 SAMPTX_SPT(3) /*!< 28.5 sampling cycles */ +#define ADC_SAMPLETIME_41POINT5 SAMPTX_SPT(4) /*!< 41.5 sampling cycles */ +#define ADC_SAMPLETIME_55POINT5 SAMPTX_SPT(5) /*!< 55.5 sampling cycles */ +#define ADC_SAMPLETIME_71POINT5 SAMPTX_SPT(6) /*!< 71.5 sampling cycles */ +#define ADC_SAMPLETIME_239POINT5 SAMPTX_SPT(7) /*!< 239.5 sampling cycles */ + +/* ADC data offset for inserted channel x*/ +#define IOFFX_IOFF(regval) (BITS(0,11) & ((uint32_t)(regval) << 0)) + +/* ADC analog watchdog high threshold */ +#define WDHT_WDHT(regval) (BITS(0,11) & ((uint32_t)(regval) << 0)) + +/* ADC analog watchdog low threshold */ +#define WDLT_WDLT(regval) (BITS(0,11) & ((uint32_t)(regval) << 0)) + +/* ADC regular channel group length */ +#define RSQ0_RL(regval) (BITS(20,23) & ((uint32_t)(regval) << 20)) + +/* ADC inserted channel group length */ +#define ISQ_IL(regval) (BITS(20,21) & ((uint32_t)(regval) << 20)) + +/* ADC resolution definitions */ +#define CTL0_DRES(regval) (BITS(24,25) & ((regval) << 24)) /*!< ADC resolution */ +#define ADC_RESOLUTION_12B CTL0_DRES(0) /*!< 12-bit ADC resolution */ +#define ADC_RESOLUTION_10B CTL0_DRES(1) /*!< 10-bit ADC resolution */ +#define ADC_RESOLUTION_8B CTL0_DRES(2) /*!< 8-bit ADC resolution */ +#define ADC_RESOLUTION_6B CTL0_DRES(3) /*!< 6-bit ADC resolution */ + +/* ADC oversampling shift */ +#define OVSAMPCTL_OVSS(regval) (BITS(5,8) & ((uint32_t)(regval) << 5)) +#define ADC_OVERSAMPLING_SHIFT_NONE OVSAMPCTL_OVSS(0) /*!< no oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_1B OVSAMPCTL_OVSS(1) /*!< 1-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_2B OVSAMPCTL_OVSS(2) /*!< 2-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_3B OVSAMPCTL_OVSS(3) /*!< 3-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_4B OVSAMPCTL_OVSS(4) /*!< 4-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_5B OVSAMPCTL_OVSS(5) /*!< 5-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_6B OVSAMPCTL_OVSS(6) /*!< 6-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_7B OVSAMPCTL_OVSS(7) /*!< 7-bit oversampling shift */ +#define ADC_OVERSAMPLING_SHIFT_8B OVSAMPCTL_OVSS(8) /*!< 8-bit oversampling shift */ + +/* ADC oversampling ratio */ +#define OVSAMPCTL_OVSR(regval) (BITS(2,4) & ((uint32_t)(regval) << 2)) +#define ADC_OVERSAMPLING_RATIO_MUL2 OVSAMPCTL_OVSR(0) /*!< oversampling ratio multiple 2 */ +#define ADC_OVERSAMPLING_RATIO_MUL4 OVSAMPCTL_OVSR(1) /*!< oversampling ratio multiple 4 */ +#define ADC_OVERSAMPLING_RATIO_MUL8 OVSAMPCTL_OVSR(2) /*!< oversampling ratio multiple 8 */ +#define ADC_OVERSAMPLING_RATIO_MUL16 OVSAMPCTL_OVSR(3) /*!< oversampling ratio multiple 16 */ +#define ADC_OVERSAMPLING_RATIO_MUL32 OVSAMPCTL_OVSR(4) /*!< oversampling ratio multiple 32 */ +#define ADC_OVERSAMPLING_RATIO_MUL64 OVSAMPCTL_OVSR(5) /*!< oversampling ratio multiple 64 */ +#define ADC_OVERSAMPLING_RATIO_MUL128 OVSAMPCTL_OVSR(6) /*!< oversampling ratio multiple 128 */ +#define ADC_OVERSAMPLING_RATIO_MUL256 OVSAMPCTL_OVSR(7) /*!< oversampling ratio multiple 256 */ + +/* ADC triggered oversampling */ +#define ADC_OVERSAMPLING_ALL_CONVERT 0U /*!< all oversampled conversions for a channel are done consecutively after a trigger */ +#define ADC_OVERSAMPLING_ONE_CONVERT 1U /*!< each oversampled conversion for a channel needs a trigger */ + +/* ADC channel group definitions */ +#define ADC_REGULAR_CHANNEL ((uint8_t)0x01U) /*!< ADC regular channel group */ +#define ADC_INSERTED_CHANNEL ((uint8_t)0x02U) /*!< ADC inserted channel group */ +#define ADC_REGULAR_INSERTED_CHANNEL ((uint8_t)0x03U) /*!< both regular and inserted channel group */ +#define ADC_CHANNEL_DISCON_DISABLE ((uint8_t)0x04U) /*!< disable discontinuous mode of regular & inserted channel */ + +/* ADC inserted channel definitions */ +#define ADC_INSERTED_CHANNEL_0 ((uint8_t)0x00U) /*!< ADC inserted channel 0 */ +#define ADC_INSERTED_CHANNEL_1 ((uint8_t)0x01U) /*!< ADC inserted channel 1 */ +#define ADC_INSERTED_CHANNEL_2 ((uint8_t)0x02U) /*!< ADC inserted channel 2 */ +#define ADC_INSERTED_CHANNEL_3 ((uint8_t)0x03U) /*!< ADC inserted channel 3 */ + +/* ADC channel definitions */ +#define ADC_CHANNEL_0 ((uint8_t)0x00U) /*!< ADC channel 0 */ +#define ADC_CHANNEL_1 ((uint8_t)0x01U) /*!< ADC channel 1 */ +#define ADC_CHANNEL_2 ((uint8_t)0x02U) /*!< ADC channel 2 */ +#define ADC_CHANNEL_3 ((uint8_t)0x03U) /*!< ADC channel 3 */ +#define ADC_CHANNEL_4 ((uint8_t)0x04U) /*!< ADC channel 4 */ +#define ADC_CHANNEL_5 ((uint8_t)0x05U) /*!< ADC channel 5 */ +#define ADC_CHANNEL_6 ((uint8_t)0x06U) /*!< ADC channel 6 */ +#define ADC_CHANNEL_7 ((uint8_t)0x07U) /*!< ADC channel 7 */ +#define ADC_CHANNEL_8 ((uint8_t)0x08U) /*!< ADC channel 8 */ +#define ADC_CHANNEL_9 ((uint8_t)0x09U) /*!< ADC channel 9 */ +#define ADC_CHANNEL_16 ((uint8_t)0x10U) /*!< ADC channel 16 */ +#define ADC_CHANNEL_17 ((uint8_t)0x11U) /*!< ADC channel 17 */ + +/* ADC interrupt definitions */ +#define ADC_INT_WDE ADC_STAT_WDE /*!< analog watchdog event interrupt */ +#define ADC_INT_EOC ADC_STAT_EOC /*!< end of group conversion interrupt */ +#define ADC_INT_EOIC ADC_STAT_EOIC /*!< end of inserted group conversion interrupt */ + +/* ADC interrupt flag */ +#define ADC_INT_FLAG_WDE ADC_STAT_WDE /*!< analog watchdog event interrupt flag */ +#define ADC_INT_FLAG_EOC ADC_STAT_EOC /*!< end of group conversion interrupt flag */ +#define ADC_INT_FLAG_EOIC ADC_STAT_EOIC /*!< end of inserted group conversion interrupt flag */ + +/* function declarations */ +/* reset ADC */ +void adc_deinit(void); +/* enable ADC interface */ +void adc_enable(void); +/* disable ADC interface */ +void adc_disable(void); + +/* ADC calibration and reset calibration */ +void adc_calibration_enable(void); +/* enable DMA request */ +void adc_dma_mode_enable(void); +/* disable DMA request */ +void adc_dma_mode_disable(void); + +/* enable the temperature sensor and Vrefint channel */ +void adc_tempsensor_vrefint_enable(void); +/* disable the temperature sensor and Vrefint channel */ +void adc_tempsensor_vrefint_disable(void); + +/* configure ADC discontinuous mode */ +void adc_discontinuous_mode_config(uint8_t channel_group, uint8_t length); +/* configure ADC special function */ +void adc_special_function_config(uint32_t function, ControlStatus newvalue); + +/* configure ADC data alignment */ +void adc_data_alignment_config(uint32_t data_alignment); +/* configure the length of regular channel group or inserted channel group */ +void adc_channel_length_config(uint8_t channel_group, uint32_t length); +/* configure ADC regular channel */ +void adc_regular_channel_config(uint8_t rank, uint8_t channel, uint32_t sample_time); +/* configure ADC inserted channel */ +void adc_inserted_channel_config(uint8_t rank, uint8_t channel, uint32_t sample_time); +/* configure ADC inserted channel offset */ +void adc_inserted_channel_offset_config(uint8_t inserted_channel, uint16_t offset); +/* enable ADC external trigger */ +void adc_external_trigger_config(uint8_t channel_group, ControlStatus newvalue); +/* configure ADC external trigger source */ +void adc_external_trigger_source_config(uint8_t channel_group, uint32_t external_trigger_source); +/* enable ADC software trigger */ +void adc_software_trigger_enable(uint8_t channel_group); + +/* read ADC regular group data register */ +uint16_t adc_regular_data_read(void); +/* read ADC inserted group data register */ +uint16_t adc_inserted_data_read(uint8_t inserted_channel); + +/* get the ADC flag bits */ +FlagStatus adc_flag_get(uint32_t flag); +/* clear the ADC flag bits */ +void adc_flag_clear(uint32_t flag); +/* get the ADC interrupt bits */ +FlagStatus adc_interrupt_flag_get(uint32_t flag); +/* clear the ADC flag */ +void adc_interrupt_flag_clear(uint32_t flag); +/* enable ADC interrupt */ +void adc_interrupt_enable(uint32_t interrupt); +/* disable ADC interrupt */ +void adc_interrupt_disable(uint32_t interrupt); + +/* configure ADC analog watchdog single channel */ +void adc_watchdog_single_channel_enable(uint8_t channel); +/* configure ADC analog watchdog group channel */ +void adc_watchdog_group_channel_enable(uint8_t channel_group); +/* disable ADC analog watchdog */ +void adc_watchdog_disable(void); +/* configure ADC analog watchdog threshold */ +void adc_watchdog_threshold_config(uint16_t low_threshold, uint16_t high_threshold); + +/* configure ADC resolution */ +void adc_resolution_config(uint32_t resolution); +/* configure ADC oversample mode */ +void adc_oversample_mode_config(uint8_t mode, uint16_t shift, uint8_t ratio); +/* enable ADC oversample mode */ +void adc_oversample_mode_enable(void); +/* disable ADC oversample mode */ +void adc_oversample_mode_disable(void); + +#endif /* GD32E230_ADC_H */ diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_cmp.h b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_cmp.h new file mode 100644 index 0000000000000000000000000000000000000000..aa9d8a9b2c82130c2ad7db9383eb85fcac9cc3ea --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_cmp.h @@ -0,0 +1,162 @@ +/*! + \file gd32e230_cmp.h + \brief definitions for the CMP + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor 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 copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 GD32E230_CMP_H +#define GD32E230_CMP_H + +#include "gd32e230.h" + +/* CMP definitions */ +#define CMP CMP_BASE /*!< CMP base address */ + +/* registers definitions */ +#define CMP_CS REG32((CMP) + 0x00U) /*!< CMP control and status register */ + +/* CMP_CS bits definitions */ +#define CMP_CS_CMPEN BIT(0) /*!< CMP enable */ +#define CMP_CS_CMPSW BIT(1) /*!< CMP switch */ +#define CMP_CS_CMPM BITS(2,3) /*!< CMP mode */ +#define CMP_CS_CMPMSEL BITS(4,6) /*!< COMP_M input selection */ +#define CMP_CS_CMPOSEL BITS(8,10) /*!< CMP output selection */ +#define CMP_CS_CMPPL BIT(11) /*!< polarity of CMP output */ +#define CMP_CS_CMPHST BITS(12,13) /*!< CMP hysteresis */ +#define CMP_CS_CMPO BIT(14) /*!< CMP output */ +#define CMP_CS_CMPLK BIT(15) /*!< CMP lock */ + +/* consts definitions */ +/* operating mode */ +typedef enum{ + CMP_HIGHSPEED = 0, /*!< high speed mode */ + CMP_MIDDLESPEED, /*!< medium speed mode */ + CMP_LOWSPEED, /*!< low speed mode */ + CMP_VERYLOWSPEED /*!< very-low speed mode */ +}operating_mode_enum; + +/* inverting input */ +typedef enum{ + CMP_1_4VREFINT = 0, /*!< VREFINT /4 input */ + CMP_1_2VREFINT, /*!< VREFINT /2 input */ + CMP_3_4VREFINT, /*!< VREFINT *3/4 input */ + CMP_VREFINT, /*!< VREFINT input */ + CMP_PA4, /*!< PA4 input */ + CMP_PA5, /*!< PA5 input */ + CMP_PA0, /*!< PA0 input */ + CMP_PA2 /*!< PA2 input */ +}inverting_input_enum; + +/* hysteresis */ +typedef enum{ + CMP_HYSTERESIS_NO = 0, /*!< output no hysteresis */ + CMP_HYSTERESIS_LOW, /*!< output low hysteresis */ + CMP_HYSTERESIS_MIDDLE, /*!< output middle hysteresis */ + CMP_HYSTERESIS_HIGH /*!< output high hysteresis */ +}cmp_hysteresis_enum; + +/* output */ +typedef enum{ + CMP_OUTPUT_NONE = 0x0U, /*!< output no selection */ + CMP_OUTPUT_TIMER0BKIN = 0x1U, /*!< TIMER 0 break input */ + CMP_OUTPUT_TIMER0IC0 = 0x2U, /*!< TIMER 0 channel0 input capture */ + CMP_OUTPUT_TIMER0OCPRECLR = 0x3U, /*!< TIMER 0 OCPRE_CLR input */ + CMP_OUTPUT_TIMER2IC0 = 0x06U, /*!< TIMER 2 channel0 input capture */ + CMP_OUTPUT_TIMER2OCPRECLR = 0x7U /*!< TIMER 2 OCPRE_CLR input */ +}cmp_output_enum; + +/* CMP mode */ +#define CS_CMPM(regval) (BITS(2,3) & ((uint32_t)(regval) << 2)) +#define CS_CMPM_HIGHSPEED CS_CMPM(0) /*!< CMP mode high speed */ +#define CS_CMPM_MIDDLESPEED CS_CMPM(1) /*!< CMP mode middle speed */ +#define CS_CMPM_LOWSPEED CS_CMPM(2) /*!< CMP mode low speed */ +#define CS_CMPM_VERYLOWSPEED CS_CMPM(3) /*!< CMP mode very low speed */ + +/* comparator inverting input */ +#define CS_CMPMSEL(regval) (BITS(4,6) & ((uint32_t)(regval) << 4)) +#define CS_CMPMSEL_1_4VREFINT CS_CMPMSEL(0) /*!< CMP inverting input 1/4 Vrefint */ +#define CS_CMPMSEL_1_2VREFINT CS_CMPMSEL(1) /*!< CMP inverting input 1/2 Vrefint */ +#define CS_CMPMSEL_3_4VREFINT CS_CMPMSEL(2) /*!< CMP inverting input 3/4 Vrefint */ +#define CS_CMPMSEL_VREFINT CS_CMPMSEL(3) /*!< CMP inverting input Vrefint */ +#define CS_CMPMSEL_PA4 CS_CMPMSEL(4) /*!< CMP inverting input PA4*/ +#define CS_CMPMSEL_PA5 CS_CMPMSEL(5) /*!< CMP inverting input PA5*/ +#define CS_CMPMSEL_PA0 CS_CMPMSEL(6) /*!< CMP inverting input PA0*/ +#define CS_CMPMSEL_PA2 CS_CMPMSEL(7) /*!< CMP inverting input PA2*/ + +/* CMP output */ +#define CS_CMPOSEL(regval) (BITS(8,10) & ((uint32_t)(regval) << 8)) +#define CS_CMPOSEL_OUTPUT_NONE CS_CMPOSEL(0) /*!< CMP output none */ +#define CS_CMPOSEL_OUTPUT_TIMER0BKIN CS_CMPOSEL(1) /*!< CMP output TIMER 0 break input */ +#define CS_CMPOSEL_OUTPUT_TIMER0IC0 CS_CMPOSEL(2) /*!< CMP output TIMER 0 channel 0 input capture */ +#define CS_CMPOSEL_OUTPUT_TIMER0OCPRECLR CS_CMPOSEL(3) /*!< CMP output TIMER 0 ocpreclear input */ +#define CS_CMPOSEL_OUTPUT_TIMER2IC0 CS_CMPOSEL(6) /*!< CMP output TIMER 2 channle 0 input capture */ +#define CS_CMPOSEL_OUTPUT_TIMER2OCPRECLR CS_CMPOSEL(7) /*!< CMP output TIMER 2 ocpreclear input */ + +/* CMP hysteresis */ +#define CS_CMPHST(regval) (BITS(12,13) & ((uint32_t)(regval) << 12)) +#define CS_CMPHST_HYSTERESIS_NO CS_CMPHST(0) /*!< CMP output no hysteresis */ +#define CS_CMPHST_HYSTERESIS_LOW CS_CMPHST(1) /*!< CMP output low hysteresis */ +#define CS_CMPHST_HYSTERESIS_MIDDLE CS_CMPHST(2) /*!< CMP output middle hysteresis */ +#define CS_CMPHST_HYSTERESIS_HIGH CS_CMPHST(3) /*!< CMP output high hysteresis */ + +/* CMP output level */ +#define CMP_OUTPUTLEVEL_HIGH ((uint32_t)0x00000001) /*!< comparator output high */ +#define CMP_OUTPUTLEVEL_LOW ((uint32_t)0x00000000) /*!< comparator output low */ + +/* output polarity of comparator */ +#define CMP_OUTPUT_POLARITY_INVERTED ((uint32_t)0x00000001) /*!< output is inverted */ +#define CMP_OUTPUT_POLARITY_NOINVERTED ((uint32_t)0x00000000) /*!< output is not inverted */ + +/* function declarations */ + +/* initialization functions */ +/* CMP deinit */ +void cmp_deinit(void); +/* CMP mode init */ +void cmp_mode_init(operating_mode_enum operating_mode, inverting_input_enum inverting_input, cmp_hysteresis_enum output_hysteresis); +/* CMP output init */ +void cmp_output_init(cmp_output_enum output_slection, uint32_t output_polarity); +/* enable CMP */ +void cmp_enable(void); +/* disable CMP */ +void cmp_disable(void); +/* enable CMP switch */ +void cmp_switch_enable(void); +/* disable CMP switch */ +void cmp_switch_disable(void); +/* get output level */ +uint32_t cmp_output_level_get(void); +/* lock the CMP */ +void cmp_lock_enable(void); + +#endif /* GD32E230_CMP_H */ diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_crc.h b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_crc.h new file mode 100644 index 0000000000000000000000000000000000000000..619ce479702e0d3ad8e2e45cfa31e1ff475c7e75 --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_crc.h @@ -0,0 +1,120 @@ +/*! + \file gd32e230_crc.h + \brief definitions for the CRC + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor 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 copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 GD32E230_CRC_H +#define GD32E230_CRC_H + +#include "gd32e230.h" + +/* CRC definitions */ +#define CRC CRC_BASE + +/* registers definitions */ +#define CRC_DATA REG32((CRC) + 0x00U) /*!< CRC data register */ +#define CRC_FDATA REG32((CRC) + 0x04U) /*!< CRC free data register */ +#define CRC_CTL REG32((CRC) + 0x08U) /*!< CRC control register */ +#define CRC_IDATA REG32((CRC) + 0x10U) /*!< CRC initialization data register */ +#define CRC_POLY REG32((CRC) + 0x14U) /*!< CRC polynomial register */ + +/* bits definitions */ +/* CRC_DATA */ +#define CRC_DATA_DATA BITS(0,31) /*!< CRC data bits */ + +/* CRC_FDATA */ +#define CRC_FDATA_FDATA BITS(0,7) /*!< CRC free data bits */ + +/* CRC_CTL */ +#define CRC_CTL_RST BIT(0) /*!< CRC reset bit */ +#define CRC_CTL_PS BITS(3,4) /*!< size of polynomial function bits */ +#define CRC_CTL_REV_I BITS(5,6) /*!< input data reverse function bits */ +#define CRC_CTL_REV_O BIT(7) /*!< output data reverse function bit */ + +/* CRC_INIT */ +#define CRC_IDATA_IDATA BITS(0,31) /*!< CRC initialization data bits */ + +/* CRC_POLY */ +#define CRC_POLY_POLY BITS(0,31) /*!< CRC polynomial value bits */ + +/* constants definitions */ +/* size of polynomial function */ +#define CTL_PS(regval) (BITS(3, 4) & ((regval) << 3)) +#define CRC_CTL_PS_32 CTL_PS(0) /*!< 32-bit polynomial for CRC calculation */ +#define CRC_CTL_PS_16 CTL_PS(1) /*!< 16-bit polynomial for CRC calculation */ +#define CRC_CTL_PS_8 CTL_PS(2) /*!< 8-bit polynomial for CRC calculation */ +#define CRC_CTL_PS_7 CTL_PS(3) /*!< 7-bit polynomial for CRC calculation */ + +/* input data reverse function */ +#define CTL_REV_I(regval) (BITS(5, 6) & ((regval) << 5)) +#define CRC_INPUT_DATA_NOT CTL_REV_I(0) /*!< input data not reverse */ +#define CRC_INPUT_DATA_BYTE CTL_REV_I(1) /*!< input data reversed by byte type */ +#define CRC_INPUT_DATA_HALFWORD CTL_REV_I(2) /*!< input data reversed by half-word type */ +#define CRC_INPUT_DATA_WORD CTL_REV_I(3) /*!< input data reversed by word type */ + +/* function declarations */ +/* deinit CRC calculation unit */ +void crc_deinit(void); + +/* enable the reverse operation of output data */ +void crc_reverse_output_data_enable(void); +/* disable the reverse operation of output data */ +void crc_reverse_output_data_disable(void); + +/* reset data register to the value of initializaiton data register */ +void crc_data_register_reset(void); +/* read the data register */ +uint32_t crc_data_register_read(void); + +/* read the free data register */ +uint8_t crc_free_data_register_read(void); +/* write the free data register */ +void crc_free_data_register_write(uint8_t free_data); + +/* write the initial value register */ +void crc_init_data_register_write(uint32_t init_data); +/* configure the CRC input data function */ +void crc_input_data_reverse_config(uint32_t data_reverse); + +/* configure the CRC size of polynomial function */ +void crc_polynomial_size_set(uint32_t poly_size); +/* configure the CRC polynomial value function */ +void crc_polynomial_set(uint32_t poly); + +/* CRC calculate a 32-bit data */ +uint32_t crc_single_data_calculate(uint32_t sdata); +/* CRC calculate a 32-bit data array */ +uint32_t crc_block_data_calculate(uint32_t array[], uint32_t size); + +#endif /* GD32E230_CRC_H */ diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_dbg.h b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_dbg.h new file mode 100644 index 0000000000000000000000000000000000000000..4a07da903e3fd607fb46f9a0bd167869689ae9f8 --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_dbg.h @@ -0,0 +1,123 @@ +/*! + \file gd32e230_dbg.h + \brief definitions for the DBG + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor 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 copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 GD32E230_DBG_H +#define GD32E230_DBG_H + +#include "gd32e230.h" + +/* DBG definitions */ +#define DBG DBG_BASE + +/* registers definitions */ +#define DBG_ID REG32(DBG + 0x00U) /*!< DBG_ID code register */ +#define DBG_CTL0 REG32(DBG + 0x04U) /*!< DBG control register 0 */ +#define DBG_CTL1 REG32(DBG + 0x08U) /*!< DBG control register 1 */ + +/* bits definitions */ +/* DBG_ID */ +#define DBG_ID_ID_CODE BITS(0,31) /*!< DBG ID code values */ + +/* DBG_CTL0 */ +#define DBG_CTL0_SLP_HOLD BIT(0) /*!< keep debugger connection during sleep mode */ +#define DBG_CTL0_DSLP_HOLD BIT(1) /*!< keep debugger connection during deepsleep mode */ +#define DBG_CTL0_STB_HOLD BIT(2) /*!< keep debugger connection during standby mode */ +#define DBG_CTL0_FWDGT_HOLD BIT(8) /*!< debug FWDGT kept when core is halted */ +#define DBG_CTL0_WWDGT_HOLD BIT(9) /*!< debug WWDGT kept when core is halted */ +#define DBG_CTL0_TIMER0_HOLD BIT(10) /*!< TIMER0 counter kept when core is halted */ +#define DBG_CTL0_TIMER2_HOLD BIT(12) /*!< TIMER2 counter kept when core is halted */ +#define DBG_CTL0_I2C0_HOLD BIT(15) /*!< hold I2C0 smbus when core is halted */ +#define DBG_CTL0_I2C1_HOLD BIT(16) /*!< hold I2C1 smbus when core is halted */ +#define DBG_CTL0_TIMER5_HOLD BIT(19) /*!< hold TIMER5 counter when core is halted */ +#define DBG_CTL0_TIMER13_HOLD BIT(27) /*!< hold TIMER13 counter when core is halted */ + +/* DBG_CTL1 */ +#define DBG_CTL1_RTC_HOLD BIT(10) /*!< hold RTC calendar and wakeup counter when core is halted */ +#define DBG_CTL1_TIMER14_HOLD BIT(16) /*!< hold TIMER14 counter when core is halted */ +#define DBG_CTL1_TIMER15_HOLD BIT(17) /*!< hold TIMER15 counter when core is halted */ +#define DBG_CTL1_TIMER16_HOLD BIT(18) /*!< hold TIMER16 counter when core is halted */ + +/* constants definitions */ +#define DBG_LOW_POWER_SLEEP DBG_CTL0_SLP_HOLD /*!< keep debugger connection during sleep mode */ +#define DBG_LOW_POWER_DEEPSLEEP DBG_CTL0_DSLP_HOLD /*!< keep debugger connection during deepsleep mode */ +#define DBG_LOW_POWER_STANDBY DBG_CTL0_STB_HOLD /*!< keep debugger connection during standby mode */ + +/* define the peripheral debug hold bit position and its register index offset */ +#define DBG_REGIDX_BIT(regidx, bitpos) (((regidx) << 6) | (bitpos)) +#define DBG_REG_VAL(periph) (REG32(DBG + ((uint32_t)(periph) >> 6))) +#define DBG_BIT_POS(val) ((uint32_t)(val) & 0x1FU) + +/* register index */ +enum dbg_reg_idx +{ + DBG_IDX_CTL0 = 0x04U, + DBG_IDX_CTL1 = 0x08U, +}; + +/* peripherals hold bit */ +typedef enum +{ + DBG_FWDGT_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL0, 8U), /*!< FWDGT hold bit */ + DBG_WWDGT_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL0, 9U), /*!< WWDGT hold bit */ + DBG_TIMER0_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL0, 10U), /*!< TIMER0 hold bit */ + DBG_TIMER2_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL0, 12U), /*!< TIMER2 hold bit */ + DBG_TIMER5_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL0, 19U), /*!< TIMER5 hold bit */ + DBG_TIMER13_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL0, 27U), /*!< TIMER13 hold bit */ + DBG_TIMER14_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL1, 16U), /*!< TIMER14 hold bit */ + DBG_TIMER15_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL1, 17U), /*!< TIMER15 hold bit */ + DBG_TIMER16_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL1, 18U), /*!< TIMER16 hold bit */ + DBG_I2C0_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL0, 15U), /*!< I2C0 hold bit */ + DBG_I2C1_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL0, 16U), /*!< I2C1 hold bit */ + DBG_RTC_HOLD = DBG_REGIDX_BIT(DBG_IDX_CTL1, 10U), /*!< RTC hold bit */ +}dbg_periph_enum; + +/* function declarations */ +/* deinitialize the DBG */ +void dbg_deinit(void); +/* read DBG_ID code register */ +uint32_t dbg_id_get(void); + +/* enable low power behavior when the MCU is in debug mode */ +void dbg_low_power_enable(uint32_t dbg_low_power); +/* disable low power behavior when the MCU is in debug mode */ +void dbg_low_power_disable(uint32_t dbg_low_power); + +/* enable peripheral behavior when the MCU is in debug mode */ +void dbg_periph_enable(dbg_periph_enum dbg_periph); +/* disable peripheral behavior when the MCU is in debug mode */ +void dbg_periph_disable(dbg_periph_enum dbg_periph); + +#endif /* GD32E230_DBG_H */ diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_dma.h b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_dma.h new file mode 100644 index 0000000000000000000000000000000000000000..2205e1bdce9369c0ffa55dc4eb85d365cca40fba --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_dma.h @@ -0,0 +1,264 @@ +/*! + \file gd32e230_dma.h + \brief definitions for the DMA + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor 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 copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 GD32E230_DMA_H +#define GD32E230_DMA_H + +#include "gd32e230.h" + +/* DMA definitions */ +#define DMA DMA_BASE /*!< DMA base address */ + +/* registers definitions */ +#define DMA_INTF REG32(DMA + 0x00U) /*!< DMA interrupt flag register */ +#define DMA_INTC REG32(DMA + 0x04U) /*!< DMA interrupt flag clear register */ +#define DMA_CH0CTL REG32(DMA + 0x08U) /*!< DMA channel 0 control register */ +#define DMA_CH0CNT REG32(DMA + 0x0CU) /*!< DMA channel 0 counter register */ +#define DMA_CH0PADDR REG32(DMA + 0x10U) /*!< DMA channel 0 peripheral base address register */ +#define DMA_CH0MADDR REG32(DMA + 0x14U) /*!< DMA channel 0 memory base address register */ +#define DMA_CH1CTL REG32(DMA + 0x1CU) /*!< DMA channel 1 control register */ +#define DMA_CH1CNT REG32(DMA + 0x20U) /*!< DMA channel 1 counter register */ +#define DMA_CH1PADDR REG32(DMA + 0x24U) /*!< DMA channel 1 peripheral base address register */ +#define DMA_CH1MADDR REG32(DMA + 0x28U) /*!< DMA channel 1 memory base address register */ +#define DMA_CH2CTL REG32(DMA + 0x30U) /*!< DMA channel 2 control register */ +#define DMA_CH2CNT REG32(DMA + 0x34U) /*!< DMA channel 2 counter register */ +#define DMA_CH2PADDR REG32(DMA + 0x38U) /*!< DMA channel 2 peripheral base address register */ +#define DMA_CH2MADDR REG32(DMA + 0x3CU) /*!< DMA channel 2 memory base address register */ +#define DMA_CH3CTL REG32(DMA + 0x44U) /*!< DMA channel 3 control register */ +#define DMA_CH3CNT REG32(DMA + 0x48U) /*!< DMA channel 3 counter register */ +#define DMA_CH3PADDR REG32(DMA + 0x4CU) /*!< DMA channel 3 peripheral base address register */ +#define DMA_CH3MADDR REG32(DMA + 0x50U) /*!< DMA channel 3 memory base address register */ +#define DMA_CH4CTL REG32(DMA + 0x58U) /*!< DMA channel 4 control register */ +#define DMA_CH4CNT REG32(DMA + 0x5CU) /*!< DMA channel 4 counter register */ +#define DMA_CH4PADDR REG32(DMA + 0x60U) /*!< DMA channel 4 peripheral base address register */ +#define DMA_CH4MADDR REG32(DMA + 0x64U) /*!< DMA channel 4 memory base address register */ + +/* bits definitions */ +/* DMA_INTF */ +#define DMA_INTF_GIF BIT(0) /*!< global interrupt flag of channel */ +#define DMA_INTF_FTFIF BIT(1) /*!< full transfer finish flag of channel */ +#define DMA_INTF_HTFIF BIT(2) /*!< half transfer finish flag of channel */ +#define DMA_INTF_ERRIF BIT(3) /*!< error flag of channel */ + +/* DMA_INTC */ +#define DMA_INTC_GIFC BIT(0) /*!< clear global interrupt flag of channel */ +#define DMA_INTC_FTFIFC BIT(1) /*!< clear transfer finish flag of channel */ +#define DMA_INTC_HTFIFC BIT(2) /*!< clear half transfer finish flag of channel */ +#define DMA_INTC_ERRIFC BIT(3) /*!< clear error flag of channel */ + +/* DMA_CHxCTL,x=0..4 */ +#define DMA_CHXCTL_CHEN BIT(0) /*!< channel x enable */ +#define DMA_CHXCTL_FTFIE BIT(1) /*!< enable bit for channel x transfer complete interrupt */ +#define DMA_CHXCTL_HTFIE BIT(2) /*!< enable bit for channel x transfer half complete interrupt */ +#define DMA_CHXCTL_ERRIE BIT(3) /*!< enable bit for channel x error interrupt */ +#define DMA_CHXCTL_DIR BIT(4) /*!< direction of the data transfer on the channel */ +#define DMA_CHXCTL_CMEN BIT(5) /*!< circulation mode */ +#define DMA_CHXCTL_PNAGA BIT(6) /*!< next address generation algorithm of peripheral */ +#define DMA_CHXCTL_MNAGA BIT(7) /*!< next address generation algorithm of memory */ +#define DMA_CHXCTL_PWIDTH BITS(8,9) /*!< transfer data size of peripheral */ +#define DMA_CHXCTL_MWIDTH BITS(10,11) /*!< transfer data size of memory */ +#define DMA_CHXCTL_PRIO BITS(12,13) /*!< priority level of channelx */ +#define DMA_CHXCTL_M2M BIT(14) /*!< memory to memory mode */ + +/* DMA_CHxCNT,x=0..4 */ +#define DMA_CHXCNT_CNT BITS(0,15) /*!< transfer counter */ + +/* DMA_CHxPADDR,x=0..4 */ +#define DMA_CHXPADDR_PADDR BITS(0,31) /*!< peripheral base address */ + +/* DMA_CHxMADDR,x=0..4 */ +#define DMA_CHXMADDR_MADDR BITS(0,31) /*!< memory base address */ + +/* constants definitions */ +/* DMA channel select */ +typedef enum +{ + DMA_CH0 = 0, /*!< DMA Channel0 */ + DMA_CH1, /*!< DMA Channel1 */ + DMA_CH2, /*!< DMA Channel2 */ + DMA_CH3, /*!< DMA Channel3 */ + DMA_CH4, /*!< DMA Channel4 */ +} dma_channel_enum; + +/* DMA initialize struct */ +typedef struct +{ + uint32_t periph_addr; /*!< peripheral base address */ + uint32_t periph_width; /*!< transfer data size of peripheral */ + uint32_t memory_addr; /*!< memory base address */ + uint32_t memory_width; /*!< transfer data size of memory */ + uint32_t number; /*!< channel transfer number */ + uint32_t priority; /*!< channel priority level */ + uint8_t periph_inc; /*!< peripheral increasing mode */ + uint8_t memory_inc; /*!< memory increasing mode */ + uint8_t direction; /*!< channel data transfer direction */ +} dma_parameter_struct; + +/* DMA reset value */ +#define DMA_CHCTL_RESET_VALUE ((uint32_t)0x00000000U) /*!< the reset value of DMA channel CHXCTL register */ +#define DMA_CHCNT_RESET_VALUE ((uint32_t)0x00000000U) /*!< the reset value of DMA channel CHXCNT register */ +#define DMA_CHPADDR_RESET_VALUE ((uint32_t)0x00000000U) /*!< the reset value of DMA channel CHXPADDR register */ +#define DMA_CHMADDR_RESET_VALUE ((uint32_t)0x00000000U) /*!< the reset value of DMA channel CHXMADDR register */ +#define DMA_CHINTF_RESET_VALUE (DMA_INTF_GIF | DMA_INTF_FTFIF | \ + DMA_INTF_HTFIF | DMA_INTF_ERRIF) + +#define DMA_FLAG_ADD(flag,shift) ((flag) << ((uint32_t)(shift) * 4U)) /*!< DMA channel flag shift */ + +/* DMA_CHCTL base address */ +#define DMA_CHXCTL_BASE (DMA + 0x08U) /*!< the base address of DMA channel CHXCTL register */ +#define DMA_CHXCNT_BASE (DMA + 0x0CU) /*!< the base address of DMA channel CHXCNT register */ +#define DMA_CHXPADDR_BASE (DMA + 0x10U) /*!< the base address of DMA channel CHXPADDR register */ +#define DMA_CHXMADDR_BASE (DMA + 0x14U) /*!< the base address of DMA channel CHXMADDR register */ + +/* DMA channel shift bit */ +#define DMA_CHCTL(channel) REG32(DMA_CHXCTL_BASE + 0x14U * (uint32_t)(channel)) /*!< the address of DMA channel CHXCTL register */ +#define DMA_CHCNT(channel) REG32(DMA_CHXCNT_BASE + 0x14U * (uint32_t)(channel)) /*!< the address of DMA channel CHXCNT register */ +#define DMA_CHPADDR(channel) REG32(DMA_CHXPADDR_BASE + 0x14U * (uint32_t)(channel)) /*!< the address of DMA channel CHXPADDR register */ +#define DMA_CHMADDR(channel) REG32(DMA_CHXMADDR_BASE + 0x14U * (uint32_t)(channel)) /*!< the address of DMA channel CHXMADDR register */ + +/* DMA_INTF register */ +/* interrupt flag bits */ +#define DMA_INT_FLAG_G DMA_INTF_GIF /*!< global interrupt flag of channel */ +#define DMA_INT_FLAG_FTF DMA_INTF_FTFIF /*!< full transfer finish interrupt flag of channel */ +#define DMA_INT_FLAG_HTF DMA_INTF_HTFIF /*!< half transfer finish interrupt flag of channel */ +#define DMA_INT_FLAG_ERR DMA_INTF_ERRIF /*!< error interrupt flag of channel */ + +/* flag bits */ +#define DMA_FLAG_G DMA_INTF_GIF /*!< global interrupt flag of channel */ +#define DMA_FLAG_FTF DMA_INTF_FTFIF /*!< full transfer finish flag of channel */ +#define DMA_FLAG_HTF DMA_INTF_HTFIF /*!< half transfer finish flag of channel */ +#define DMA_FLAG_ERR DMA_INTF_ERRIF /*!< error flag of channel */ + +/* DMA_CHxCTL register */ +/* interrupt enable bits */ +#define DMA_INT_FTF DMA_CHXCTL_FTFIE /*!< enable bit for channel full transfer finish interrupt */ +#define DMA_INT_HTF DMA_CHXCTL_HTFIE /*!< enable bit for channel half transfer finish interrupt */ +#define DMA_INT_ERR DMA_CHXCTL_ERRIE /*!< enable bit for channel error interrupt */ + +/* transfer direction */ +#define DMA_PERIPHERAL_TO_MEMORY ((uint32_t)0x00000000U) /*!< read from peripheral and write to memory */ +#define DMA_MEMORY_TO_PERIPHERAL ((uint32_t)0x00000001U) /*!< read from memory and write to peripheral */ + +/* peripheral increasing mode */ +#define DMA_PERIPH_INCREASE_DISABLE ((uint32_t)0x00000000U) /*!< next address of peripheral is fixed address mode */ +#define DMA_PERIPH_INCREASE_ENABLE ((uint32_t)0x00000001U) /*!< next address of peripheral is increasing address mode */ + +/* memory increasing mode */ +#define DMA_MEMORY_INCREASE_DISABLE ((uint32_t)0x00000000U) /*!< next address of memory is fixed address mode */ +#define DMA_MEMORY_INCREASE_ENABLE ((uint32_t)0x00000001U) /*!< next address of memory is increasing address mode */ + +/* transfer data size of peripheral */ +#define CHCTL_PWIDTH(regval) (BITS(8,9) & ((regval) << 8)) /*!< transfer data size of peripheral */ +#define DMA_PERIPHERAL_WIDTH_8BIT CHCTL_PWIDTH(0U) /*!< transfer data size of peripheral is 8-bit */ +#define DMA_PERIPHERAL_WIDTH_16BIT CHCTL_PWIDTH(1U) /*!< transfer data size of peripheral is 16-bit */ +#define DMA_PERIPHERAL_WIDTH_32BIT CHCTL_PWIDTH(2U) /*!< transfer data size of peripheral is 32-bit */ + +/* transfer data size of memory */ +#define CHCTL_MWIDTH(regval) (BITS(10,11) & ((regval) << 10)) /*!< transfer data size of memory */ +#define DMA_MEMORY_WIDTH_8BIT CHCTL_MWIDTH(0U) /*!< transfer data size of memory is 8-bit */ +#define DMA_MEMORY_WIDTH_16BIT CHCTL_MWIDTH(1U) /*!< transfer data size of memory is 16-bit */ +#define DMA_MEMORY_WIDTH_32BIT CHCTL_MWIDTH(2U) /*!< transfer data size of memory is 32-bit */ + +/* channel priority level */ +#define CHCTL_PRIO(regval) (BITS(12,13) & ((regval) << 12)) /*!< DMA channel priority level */ +#define DMA_PRIORITY_LOW CHCTL_PRIO(0U) /*!< low priority */ +#define DMA_PRIORITY_MEDIUM CHCTL_PRIO(1U) /*!< medium priority */ +#define DMA_PRIORITY_HIGH CHCTL_PRIO(2U) /*!< high priority */ +#define DMA_PRIORITY_ULTRA_HIGH CHCTL_PRIO(3U) /*!< ultra high priority */ + +/* DMA_CHxCNT register */ +/* transfer counter */ +#define DMA_CHANNEL_CNT_MASK DMA_CHXCNT_CNT + +/* function declarations */ +/* deinitialize DMA a channel registers */ +void dma_deinit(dma_channel_enum channelx); +/* initialize the parameters of DMA struct with the default values */ +void dma_struct_para_init(dma_parameter_struct* init_struct); +/* initialize DMA channel */ +void dma_init(dma_channel_enum channelx, dma_parameter_struct* init_struct); +/* enable DMA circulation mode */ +void dma_circulation_enable(dma_channel_enum channelx); +/* disable DMA circulation mode */ +void dma_circulation_disable(dma_channel_enum channelx); +/* enable memory to memory mode */ +void dma_memory_to_memory_enable(dma_channel_enum channelx); +/* disable memory to memory mode */ +void dma_memory_to_memory_disable(dma_channel_enum channelx); +/* enable DMA channel */ +void dma_channel_enable(dma_channel_enum channelx); +/* disable DMA channel */ +void dma_channel_disable(dma_channel_enum channelx); + +/* set DMA peripheral base address */ +void dma_periph_address_config(dma_channel_enum channelx, uint32_t address); +/* set DMA memory base address */ +void dma_memory_address_config(dma_channel_enum channelx, uint32_t address); +/* set the number of remaining data to be transferred by the DMA */ +void dma_transfer_number_config(dma_channel_enum channelx, uint32_t number); +/* get the number of remaining data to be transferred by the DMA */ +uint32_t dma_transfer_number_get(dma_channel_enum channelx); +/* configure priority level of DMA channel */ +void dma_priority_config(dma_channel_enum channelx, uint32_t priority); +/* configure transfer data size of memory */ +void dma_memory_width_config (dma_channel_enum channelx, uint32_t mwidth); +/* configure transfer data size of peripheral */ +void dma_periph_width_config (dma_channel_enum channelx, uint32_t pwidth); +/* enable next address increasement algorithm of memory */ +void dma_memory_increase_enable(dma_channel_enum channelx); +/* disable next address increasement algorithm of memory */ +void dma_memory_increase_disable(dma_channel_enum channelx); +/* enable next address increasement algorithm of peripheral */ +void dma_periph_increase_enable(dma_channel_enum channelx); +/* disable next address increasement algorithm of peripheral */ +void dma_periph_increase_disable(dma_channel_enum channelx); +/* configure the direction of data transfer on the channel */ +void dma_transfer_direction_config(dma_channel_enum channelx, uint32_t direction); + +/* check DMA flag is set or not */ +FlagStatus dma_flag_get(dma_channel_enum channelx, uint32_t flag); +/* clear DMA a channel flag */ +void dma_flag_clear(dma_channel_enum channelx, uint32_t flag); +/* check DMA flag and interrupt enable bit is set or not */ +FlagStatus dma_interrupt_flag_get(dma_channel_enum channelx, uint32_t flag); +/* clear DMA a channel flag */ +void dma_interrupt_flag_clear(dma_channel_enum channelx, uint32_t flag); +/* enable DMA interrupt */ +void dma_interrupt_enable(dma_channel_enum channelx, uint32_t source); +/* disable DMA interrupt */ +void dma_interrupt_disable(dma_channel_enum channelx, uint32_t source); + +#endif /* GD32E230_DMA_H */ diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_exti.h b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_exti.h new file mode 100644 index 0000000000000000000000000000000000000000..4d8b875c4a71767f2a9a4e8705992006c5f8db11 --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_exti.h @@ -0,0 +1,278 @@ +/*! + \file gd32e230_exti.h + \brief definitions for the EXTI + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor 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 copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 GD32E230_EXTI_H +#define GD32E230_EXTI_H + +#include "gd32e230.h" + +/* EXTI definitions */ +#define EXTI EXTI_BASE + +/* registers definitions */ +#define EXTI_INTEN REG32(EXTI + 0x00U) /*!< interrupt enable register */ +#define EXTI_EVEN REG32(EXTI + 0x04U) /*!< event enable register */ +#define EXTI_RTEN REG32(EXTI + 0x08U) /*!< rising edge trigger enable register */ +#define EXTI_FTEN REG32(EXTI + 0x0CU) /*!< falling trigger enable register */ +#define EXTI_SWIEV REG32(EXTI + 0x10U) /*!< software interrupt event register */ +#define EXTI_PD REG32(EXTI + 0x14U) /*!< pending register */ + +/* bits definitions */ +/* EXTI_INTEN */ +#define EXTI_INTEN_INTEN0 BIT(0) /*!< interrupt from line 0 */ +#define EXTI_INTEN_INTEN1 BIT(1) /*!< interrupt from line 1 */ +#define EXTI_INTEN_INTEN2 BIT(2) /*!< interrupt from line 2 */ +#define EXTI_INTEN_INTEN3 BIT(3) /*!< interrupt from line 3 */ +#define EXTI_INTEN_INTEN4 BIT(4) /*!< interrupt from line 4 */ +#define EXTI_INTEN_INTEN5 BIT(5) /*!< interrupt from line 5 */ +#define EXTI_INTEN_INTEN6 BIT(6) /*!< interrupt from line 6 */ +#define EXTI_INTEN_INTEN7 BIT(7) /*!< interrupt from line 7 */ +#define EXTI_INTEN_INTEN8 BIT(8) /*!< interrupt from line 8 */ +#define EXTI_INTEN_INTEN9 BIT(9) /*!< interrupt from line 9 */ +#define EXTI_INTEN_INTEN10 BIT(10) /*!< interrupt from line 10 */ +#define EXTI_INTEN_INTEN11 BIT(11) /*!< interrupt from line 11 */ +#define EXTI_INTEN_INTEN12 BIT(12) /*!< interrupt from line 12 */ +#define EXTI_INTEN_INTEN13 BIT(13) /*!< interrupt from line 13 */ +#define EXTI_INTEN_INTEN14 BIT(14) /*!< interrupt from line 14 */ +#define EXTI_INTEN_INTEN15 BIT(15) /*!< interrupt from line 15 */ +#define EXTI_INTEN_INTEN16 BIT(16) /*!< interrupt from line 16 */ +#define EXTI_INTEN_INTEN17 BIT(17) /*!< interrupt from line 17 */ +#define EXTI_INTEN_INTEN18 BIT(18) /*!< interrupt from line 18 */ +#define EXTI_INTEN_INTEN19 BIT(19) /*!< interrupt from line 19 */ +#define EXTI_INTEN_INTEN20 BIT(20) /*!< interrupt from line 20 */ +#define EXTI_INTEN_INTEN21 BIT(21) /*!< interrupt from line 21 */ +#define EXTI_INTEN_INTEN22 BIT(22) /*!< interrupt from line 22 */ +#define EXTI_INTEN_INTEN23 BIT(23) /*!< interrupt from line 23 */ +#define EXTI_INTEN_INTEN24 BIT(24) /*!< interrupt from line 24 */ +#define EXTI_INTEN_INTEN25 BIT(25) /*!< interrupt from line 25 */ +#define EXTI_INTEN_INTEN26 BIT(26) /*!< interrupt from line 26 */ +#define EXTI_INTEN_INTEN27 BIT(27) /*!< interrupt from line 27 */ + +/* EXTI_EVEN */ +#define EXTI_EVEN_EVEN0 BIT(0) /*!< event from line 0 */ +#define EXTI_EVEN_EVEN1 BIT(1) /*!< event from line 1 */ +#define EXTI_EVEN_EVEN2 BIT(2) /*!< event from line 2 */ +#define EXTI_EVEN_EVEN3 BIT(3) /*!< event from line 3 */ +#define EXTI_EVEN_EVEN4 BIT(4) /*!< event from line 4 */ +#define EXTI_EVEN_EVEN5 BIT(5) /*!< event from line 5 */ +#define EXTI_EVEN_EVEN6 BIT(6) /*!< event from line 6 */ +#define EXTI_EVEN_EVEN7 BIT(7) /*!< event from line 7 */ +#define EXTI_EVEN_EVEN8 BIT(8) /*!< event from line 8 */ +#define EXTI_EVEN_EVEN9 BIT(9) /*!< event from line 9 */ +#define EXTI_EVEN_EVEN10 BIT(10) /*!< event from line 10 */ +#define EXTI_EVEN_EVEN11 BIT(11) /*!< event from line 11 */ +#define EXTI_EVEN_EVEN12 BIT(12) /*!< event from line 12 */ +#define EXTI_EVEN_EVEN13 BIT(13) /*!< event from line 13 */ +#define EXTI_EVEN_EVEN14 BIT(14) /*!< event from line 14 */ +#define EXTI_EVEN_EVEN15 BIT(15) /*!< event from line 15 */ +#define EXTI_EVEN_EVEN16 BIT(16) /*!< event from line 16 */ +#define EXTI_EVEN_EVEN17 BIT(17) /*!< event from line 17 */ +#define EXTI_EVEN_EVEN18 BIT(18) /*!< event from line 18 */ +#define EXTI_EVEN_EVEN19 BIT(19) /*!< event from line 19 */ +#define EXTI_EVEN_EVEN20 BIT(20) /*!< event from line 20 */ +#define EXTI_EVEN_EVEN21 BIT(21) /*!< event from line 21 */ +#define EXTI_EVEN_EVEN22 BIT(22) /*!< event from line 22 */ +#define EXTI_EVEN_EVEN23 BIT(23) /*!< event from line 23 */ +#define EXTI_EVEN_EVEN24 BIT(24) /*!< event from line 24 */ +#define EXTI_EVEN_EVEN25 BIT(25) /*!< event from line 25 */ +#define EXTI_EVEN_EVEN26 BIT(26) /*!< event from line 26 */ +#define EXTI_EVEN_EVEN27 BIT(27) /*!< event from line 27 */ + +/* EXTI_RTEN */ +#define EXTI_RTEN_RTEN0 BIT(0) /*!< rising edge from line 0 */ +#define EXTI_RTEN_RTEN1 BIT(1) /*!< rising edge from line 1 */ +#define EXTI_RTEN_RTEN2 BIT(2) /*!< rising edge from line 2 */ +#define EXTI_RTEN_RTEN3 BIT(3) /*!< rising edge from line 3 */ +#define EXTI_RTEN_RTEN4 BIT(4) /*!< rising edge from line 4 */ +#define EXTI_RTEN_RTEN5 BIT(5) /*!< rising edge from line 5 */ +#define EXTI_RTEN_RTEN6 BIT(6) /*!< rising edge from line 6 */ +#define EXTI_RTEN_RTEN7 BIT(7) /*!< rising edge from line 7 */ +#define EXTI_RTEN_RTEN8 BIT(8) /*!< rising edge from line 8 */ +#define EXTI_RTEN_RTEN9 BIT(9) /*!< rising edge from line 9 */ +#define EXTI_RTEN_RTEN10 BIT(10) /*!< rising edge from line 10 */ +#define EXTI_RTEN_RTEN11 BIT(11) /*!< rising edge from line 11 */ +#define EXTI_RTEN_RTEN12 BIT(12) /*!< rising edge from line 12 */ +#define EXTI_RTEN_RTEN13 BIT(13) /*!< rising edge from line 13 */ +#define EXTI_RTEN_RTEN14 BIT(14) /*!< rising edge from line 14 */ +#define EXTI_RTEN_RTEN15 BIT(15) /*!< rising edge from line 15 */ +#define EXTI_RTEN_RTEN16 BIT(16) /*!< rising edge from line 16 */ +#define EXTI_RTEN_RTEN17 BIT(17) /*!< rising edge from line 17 */ +#define EXTI_RTEN_RTEN19 BIT(19) /*!< rising edge from line 19 */ +#define EXTI_RTEN_RTEN21 BIT(21) /*!< rising edge from line 21 */ + +/* EXTI_FTEN */ +#define EXTI_FTEN_FTEN0 BIT(0) /*!< falling edge from line 0 */ +#define EXTI_FTEN_FTEN1 BIT(1) /*!< falling edge from line 1 */ +#define EXTI_FTEN_FTEN2 BIT(2) /*!< falling edge from line 2 */ +#define EXTI_FTEN_FTEN3 BIT(3) /*!< falling edge from line 3 */ +#define EXTI_FTEN_FTEN4 BIT(4) /*!< falling edge from line 4 */ +#define EXTI_FTEN_FTEN5 BIT(5) /*!< falling edge from line 5 */ +#define EXTI_FTEN_FTEN6 BIT(6) /*!< falling edge from line 6 */ +#define EXTI_FTEN_FTEN7 BIT(7) /*!< falling edge from line 7 */ +#define EXTI_FTEN_FTEN8 BIT(8) /*!< falling edge from line 8 */ +#define EXTI_FTEN_FTEN9 BIT(9) /*!< falling edge from line 9 */ +#define EXTI_FTEN_FTEN10 BIT(10) /*!< falling edge from line 10 */ +#define EXTI_FTEN_FTEN11 BIT(11) /*!< falling edge from line 11 */ +#define EXTI_FTEN_FTEN12 BIT(12) /*!< falling edge from line 12 */ +#define EXTI_FTEN_FTEN13 BIT(13) /*!< falling edge from line 13 */ +#define EXTI_FTEN_FTEN14 BIT(14) /*!< falling edge from line 14 */ +#define EXTI_FTEN_FTEN15 BIT(15) /*!< falling edge from line 15 */ +#define EXTI_FTEN_FTEN16 BIT(16) /*!< falling edge from line 16 */ +#define EXTI_FTEN_FTEN17 BIT(17) /*!< falling edge from line 17 */ +#define EXTI_FTEN_FTEN19 BIT(19) /*!< falling edge from line 19 */ +#define EXTI_FTEN_FTEN21 BIT(21) /*!< falling edge from line 21 */ + +/* EXTI_SWIEV */ +#define EXTI_SWIEV_SWIEV0 BIT(0) /*!< software interrupt/event request from line 0 */ +#define EXTI_SWIEV_SWIEV1 BIT(1) /*!< software interrupt/event request from line 1 */ +#define EXTI_SWIEV_SWIEV2 BIT(2) /*!< software interrupt/event request from line 2 */ +#define EXTI_SWIEV_SWIEV3 BIT(3) /*!< software interrupt/event request from line 3 */ +#define EXTI_SWIEV_SWIEV4 BIT(4) /*!< software interrupt/event request from line 4 */ +#define EXTI_SWIEV_SWIEV5 BIT(5) /*!< software interrupt/event request from line 5 */ +#define EXTI_SWIEV_SWIEV6 BIT(6) /*!< software interrupt/event request from line 6 */ +#define EXTI_SWIEV_SWIEV7 BIT(7) /*!< software interrupt/event request from line 7 */ +#define EXTI_SWIEV_SWIEV8 BIT(8) /*!< software interrupt/event request from line 8 */ +#define EXTI_SWIEV_SWIEV9 BIT(9) /*!< software interrupt/event request from line 9 */ +#define EXTI_SWIEV_SWIEV10 BIT(10) /*!< software interrupt/event request from line 10 */ +#define EXTI_SWIEV_SWIEV11 BIT(11) /*!< software interrupt/event request from line 11 */ +#define EXTI_SWIEV_SWIEV12 BIT(12) /*!< software interrupt/event request from line 12 */ +#define EXTI_SWIEV_SWIEV13 BIT(13) /*!< software interrupt/event request from line 13 */ +#define EXTI_SWIEV_SWIEV14 BIT(14) /*!< software interrupt/event request from line 14 */ +#define EXTI_SWIEV_SWIEV15 BIT(15) /*!< software interrupt/event request from line 15 */ +#define EXTI_SWIEV_SWIEV16 BIT(16) /*!< software interrupt/event request from line 16 */ +#define EXTI_SWIEV_SWIEV17 BIT(17) /*!< software interrupt/event request from line 17 */ +#define EXTI_SWIEV_SWIEV19 BIT(19) /*!< software interrupt/event request from line 19 */ +#define EXTI_SWIEV_SWIEV21 BIT(21) /*!< software interrupt/event request from line 21 */ + +/* EXTI_PD */ +#define EXTI_PD_PD0 BIT(0) /*!< interrupt/event pending status from line 0 */ +#define EXTI_PD_PD1 BIT(1) /*!< interrupt/event pending status from line 1 */ +#define EXTI_PD_PD2 BIT(2) /*!< interrupt/event pending status from line 2 */ +#define EXTI_PD_PD3 BIT(3) /*!< interrupt/event pending status from line 3 */ +#define EXTI_PD_PD4 BIT(4) /*!< interrupt/event pending status from line 4 */ +#define EXTI_PD_PD5 BIT(5) /*!< interrupt/event pending status from line 5 */ +#define EXTI_PD_PD6 BIT(6) /*!< interrupt/event pending status from line 6 */ +#define EXTI_PD_PD7 BIT(7) /*!< interrupt/event pending status from line 7 */ +#define EXTI_PD_PD8 BIT(8) /*!< interrupt/event pending status from line 8 */ +#define EXTI_PD_PD9 BIT(9) /*!< interrupt/event pending status from line 9 */ +#define EXTI_PD_PD10 BIT(10) /*!< interrupt/event pending status from line 10 */ +#define EXTI_PD_PD11 BIT(11) /*!< interrupt/event pending status from line 11 */ +#define EXTI_PD_PD12 BIT(12) /*!< interrupt/event pending status from line 12 */ +#define EXTI_PD_PD13 BIT(13) /*!< interrupt/event pending status from line 13 */ +#define EXTI_PD_PD14 BIT(14) /*!< interrupt/event pending status from line 14 */ +#define EXTI_PD_PD15 BIT(15) /*!< interrupt/event pending status from line 15 */ +#define EXTI_PD_PD16 BIT(16) /*!< interrupt/event pending status from line 16 */ +#define EXTI_PD_PD17 BIT(17) /*!< interrupt/event pending status from line 17 */ +#define EXTI_PD_PD19 BIT(19) /*!< interrupt/event pending status from line 19 */ +#define EXTI_PD_PD21 BIT(21) /*!< interrupt/event pending status from line 21 */ + +/* constants definitions */ +/* EXTI line number */ +typedef enum +{ + EXTI_0 = BIT(0), /*!< EXTI line 0 */ + EXTI_1 = BIT(1), /*!< EXTI line 1 */ + EXTI_2 = BIT(2), /*!< EXTI line 2 */ + EXTI_3 = BIT(3), /*!< EXTI line 3 */ + EXTI_4 = BIT(4), /*!< EXTI line 4 */ + EXTI_5 = BIT(5), /*!< EXTI line 5 */ + EXTI_6 = BIT(6), /*!< EXTI line 6 */ + EXTI_7 = BIT(7), /*!< EXTI line 7 */ + EXTI_8 = BIT(8), /*!< EXTI line 8 */ + EXTI_9 = BIT(9), /*!< EXTI line 9 */ + EXTI_10 = BIT(10), /*!< EXTI line 10 */ + EXTI_11 = BIT(11), /*!< EXTI line 11 */ + EXTI_12 = BIT(12), /*!< EXTI line 12 */ + EXTI_13 = BIT(13), /*!< EXTI line 13 */ + EXTI_14 = BIT(14), /*!< EXTI line 14 */ + EXTI_15 = BIT(15), /*!< EXTI line 15 */ + EXTI_16 = BIT(16), /*!< EXTI line 16 */ + EXTI_17 = BIT(17), /*!< EXTI line 17 */ + EXTI_18 = BIT(18), /*!< EXTI line 18 */ + EXTI_19 = BIT(19), /*!< EXTI line 19 */ + EXTI_20 = BIT(20), /*!< EXTI line 20 */ + EXTI_21 = BIT(21), /*!< EXTI line 21 */ + EXTI_22 = BIT(22), /*!< EXTI line 22 */ + EXTI_23 = BIT(23), /*!< EXTI line 23 */ + EXTI_24 = BIT(24), /*!< EXTI line 24 */ + EXTI_25 = BIT(25), /*!< EXTI line 25 */ + EXTI_26 = BIT(26), /*!< EXTI line 26 */ + EXTI_27 = BIT(27), /*!< EXTI line 27 */ +}exti_line_enum; + +/* external interrupt and event */ +typedef enum +{ + EXTI_INTERRUPT = 0, /*!< EXTI interrupt mode */ + EXTI_EVENT /*!< EXTI event mode */ +}exti_mode_enum; + +/* interrupt trigger mode */ +typedef enum +{ + EXTI_TRIG_RISING = 0, /*!< EXTI rising edge trigger */ + EXTI_TRIG_FALLING, /*!< EXTI falling edge trigger */ + EXTI_TRIG_BOTH /*!< EXTI rising and falling edge trigger */ +}exti_trig_type_enum; + +/* function declarations */ +/* deinitialize the EXTI */ +void exti_deinit(void); +/* enable the configuration of EXTI initialize */ +void exti_init(exti_line_enum linex, exti_mode_enum mode, exti_trig_type_enum trig_type); +/* enable the interrupts from EXTI line x */ +void exti_interrupt_enable(exti_line_enum linex); +/* enable the events from EXTI line x */ +void exti_event_enable(exti_line_enum linex); +/* disable the interrupts from EXTI line x */ +void exti_interrupt_disable(exti_line_enum linex); +/* disable the events from EXTI line x */ +void exti_event_disable(exti_line_enum linex); + +/* get EXTI lines pending flag */ +FlagStatus exti_flag_get(exti_line_enum linex); +/* clear EXTI lines pending flag */ +void exti_flag_clear(exti_line_enum linex); +/* get EXTI lines flag when the interrupt flag is set */ +FlagStatus exti_interrupt_flag_get(exti_line_enum linex); +/* clear EXTI lines pending flag */ +void exti_interrupt_flag_clear(exti_line_enum linex); +/* EXTI software interrupt event enable */ +void exti_software_interrupt_enable(exti_line_enum linex); +/* EXTI software interrupt event disable */ +void exti_software_interrupt_disable(exti_line_enum linex); + +#endif /* GD32E230_EXTI_H */ diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_fmc.h b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_fmc.h new file mode 100644 index 0000000000000000000000000000000000000000..50f6d4b8bd4c50bac01c77caeb9f551d5bb215db --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_fmc.h @@ -0,0 +1,272 @@ +/*! + \file gd32e230_fmc.h + \brief definitions for the FMC + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor 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 copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 GD32E230_FMC_H +#define GD32E230_FMC_H + +#include "gd32e230.h" + +/* FMC and option byte definition */ +#define FMC FMC_BASE /*!< FMC register base address */ +#define OB OB_BASE /*!< option byte base address */ + +/* registers definitions */ +#define FMC_WS REG32((FMC) + 0x00U) /*!< FMC wait state register */ +#define FMC_KEY REG32((FMC) + 0x04U) /*!< FMC unlock key register */ +#define FMC_OBKEY REG32((FMC) + 0x08U) /*!< FMC option bytes unlock key register */ +#define FMC_STAT REG32((FMC) + 0x0CU) /*!< FMC status register */ +#define FMC_CTL REG32((FMC) + 0x10U) /*!< FMC control register */ +#define FMC_ADDR REG32((FMC) + 0x14U) /*!< FMC address register */ +#define FMC_OBSTAT REG32((FMC) + 0x1CU) /*!< FMC option bytes status register */ +#define FMC_WP REG32((FMC) + 0x20U) /*!< FMC write protection register */ +#define FMC_PID REG32((FMC) + 0x100U) /*!< FMC product ID register */ + +#define OB_SPC_USER REG32((OB) + 0x00U) /*!< option byte security protection value and user value */ +#define OB_DATA REG32((OB) + 0x04U) /*!< option byte data value*/ +#define OB_WP REG32((OB) + 0x08U) /*!< option byte write protection */ + +/* bits definitions */ +/* FMC_WS */ +#define FMC_WS_WSCNT BITS(0,2) /*!< wait state counter */ +#define FMC_WS_PFEN BIT(4) /*!< pre-fetch enable */ +#define FMC_WS_PGW BIT(15) /*!< program width to flash memory */ + +/* FMC_KEY */ +#define FMC_KEY_KEY BITS(0,31) /*!< FMC main flash unlock key bits */ + +/* FMC_OBKEY */ +#define FMC_OBKEY_OBKEY BITS(0,31) /*!< option bytes unlock key bits */ + +/* FMC_STAT */ +#define FMC_STAT_BUSY BIT(0) /*!< flash busy flag bit */ +#define FMC_STAT_PGERR BIT(2) /*!< flash program error flag bit */ +#define FMC_STAT_PGAERR BIT(3) /*!< program alignment error flag bit */ +#define FMC_STAT_WPERR BIT(4) /*!< flash write protection error flag bit */ +#define FMC_STAT_ENDF BIT(5) /*!< end of operation flag bit */ + +/* FMC_CTL */ +#define FMC_CTL_PG BIT(0) /*!< main flash program command bit */ +#define FMC_CTL_PER BIT(1) /*!< main flash page erase bit */ +#define FMC_CTL_MER BIT(2) /*!< main flash mass erase bit */ +#define FMC_CTL_OBPG BIT(4) /*!< option bytes program command bit */ +#define FMC_CTL_OBER BIT(5) /*!< option bytes erase command bit */ +#define FMC_CTL_START BIT(6) /*!< send erase command to FMC bit */ +#define FMC_CTL_LK BIT(7) /*!< flash lock bit */ +#define FMC_CTL_OBWEN BIT(9) /*!< option bytes erase/program enable bit */ +#define FMC_CTL_ERRIE BIT(10) /*!< error interrupt enable bit */ +#define FMC_CTL_ENDIE BIT(12) /*!< end of operation interrupt enable bit */ +#define FMC_CTL_OBRLD BIT(13) /*!< option bytes reload bit */ + +/* FMC_ADDR */ +#define FMC_ADDR_ADDR BITS(0,31) /*!< flash command address bits */ + +/* FMC_OBSTAT */ +#define FMC_OBSTAT_OBERR BIT(0) /*!< option bytes read error bit */ +#define FMC_OBSTAT_PLEVEL_BIT0 BIT(1) /*!< protection level bit 0 */ +#define FMC_OBSTAT_PLEVEL_BIT1 BIT(2) /*!< protection level bit 1 */ +#define FMC_OBSTAT_USER BITS(8,15) /*!< option bytes user bits */ +#define FMC_OBSTAT_DATA BITS(16,31) /*!< option byte data bits */ + +/* FMC_WP */ +#define FMC_WP_WP BITS(0,15) /*!< store WP[15:0] of option byte block after system reset */ + +/* FMC_PID */ +#define FMC_PID_PID BITS(0,31) /*!< product ID bits */ + +/* constants definitions */ +/* fmc state */ +typedef enum +{ + FMC_READY, /*!< the operation has been completed */ + FMC_BUSY, /*!< the operation is in progress */ + FMC_PGERR, /*!< program error */ + FMC_PGAERR, /*!< program alignment error */ + FMC_WPERR, /*!< erase/program protection error */ + FMC_TOERR, /*!< timeout error */ + FMC_OB_HSPC /*!< option byte security protection code high */ +}fmc_state_enum; + +/* unlock key */ +#define UNLOCK_KEY0 ((uint32_t)0x45670123U) /*!< unlock key 0 */ +#define UNLOCK_KEY1 ((uint32_t)0xCDEF89ABU) /*!< unlock key 1 */ + +/* wait state counter value */ +#define WS_WSCNT_0 ((uint8_t)0x00U) /*!< 0 wait state added */ +#define WS_WSCNT_1 ((uint8_t)0x01U) /*!< 1 wait state added */ +#define WS_WSCNT_2 ((uint8_t)0x02U) /*!< 2 wait state added */ + +/* read protect configure */ +#define FMC_NSPC ((uint16_t)0x5AA5U) /*!< no security protection */ +#define FMC_LSPC ((uint16_t)0x44BBU) /*!< low security protection, any value except 0xA5 or 0xCC */ +#define FMC_HSPC ((uint16_t)0x33CCU) /*!< high security protection */ + +#define LOW_16BITS_MASK ((uint32_t)0x0000FFFFU) /*!< low 16 bits mask */ +#define HIGH_16BITS_MASK ((uint32_t)0xFFFF0000U) /*!< high 16 bits mask */ + +/* option byte address */ +#define OB_SPC_USER_ADDRESS ((uint32_t)0x1FFFF800U) /*!< address of option byte security protection and user */ +#define OB_DATA_ADDRESS ((uint32_t)0x1FFFF804U) /*!< address of option byte data */ +#define OB_WP_ADDRESS ((uint32_t)0x1FFFF808U) /*!< address of option byte write protection */ + +/* option byte write protection */ +#define OB_LWP ((uint32_t)0x000000FFU) /*!< write protection low bits */ +#define OB_HWP ((uint32_t)0x0000FF00U) /*!< write protection high bits */ + +/* option byte software/hardware free watchdog timer */ +#define OB_FWDGT_HW ((uint8_t)(~BIT(0))) /*!< hardware free watchdog timer */ +#define OB_FWDGT_SW ((uint8_t)BIT(0)) /*!< software free watchdog timer */ + +/* option byte reset or not entering deep sleep mode */ +#define OB_DEEPSLEEP_RST ((uint8_t)(~BIT(1))) /*!< generate a reset instead of entering deepsleep mode */ +#define OB_DEEPSLEEP_NRST ((uint8_t)BIT(1)) /*!< no reset when entering deepsleep mode */ + +/* option byte reset or not entering standby mode */ +#define OB_STDBY_RST ((uint8_t)(~BIT(2))) /*!< generate a reset instead of entering standby mode */ +#define OB_STDBY_NRST ((uint8_t)BIT(2)) /*!< no reset when entering deepsleep mode */ + +/* option byte OB_BOOT1_n set */ +#define OB_BOOT1_SET_1 ((uint8_t)(~BIT(4))) /*!< BOOT1 bit is 1 */ +#define OB_BOOT1_SET_0 ((uint8_t)BIT(4)) /*!< BOOT1 bit is 0 */ + +/* option byte VDDA monitor enable/disable */ +#define OB_VDDA_DISABLE ((uint8_t)(~BIT(5))) /*!< disable VDDA monitor */ +#define OB_VDDA_ENABLE ((uint8_t)BIT(5)) /*!< enable VDDA monitor */ + +/* option byte SRAM parity enable/disable */ +#define OB_SRAM_PARITY_ENABLE ((uint8_t)(~BIT(6))) /*!< enable SRAM parity check */ +#define OB_SRAM_PARITY_DISABLE ((uint8_t)BIT(6)) /*!< disable SRAM parity check */ + +/* option byte security protection level in FMC_OBSTAT register */ +#define OB_OBSTAT_PLEVEL_NO ((uint8_t)0x00U) /*!< no security protection */ +#define OB_OBSTAT_PLEVEL_LOW ((uint8_t)0x01U) /*!< low security protection */ +#define OB_OBSTAT_PLEVEL_HIGH ((uint8_t)0x03U) /*!< high security protection */ + +/* option byte user mask */ +#define OB_USER_MASK ((uint8_t)0x88U) /*!< OB_USER reserved bit mask */ + +/* option byte data address */ +#define OB_DATA_ADDR0 ((uint32_t)0x1FFFF804U) /*!< option byte data address 0 */ +#define OB_DATA_ADDR1 ((uint32_t)0x1FFFF806U) /*!< option byte data address 1 */ + +/* FMC flags */ +#define FMC_FLAG_BUSY FMC_STAT_BUSY /*!< FMC busy flag */ +#define FMC_FLAG_PGERR FMC_STAT_PGERR /*!< FMC programming error flag */ +#define FMC_FLAG_PGAERR FMC_STAT_PGAERR /*!< FMC program alignment error flag */ +#define FMC_FLAG_WPERR FMC_STAT_WPERR /*!< FMC write protection error flag */ +#define FMC_FLAG_END FMC_STAT_ENDF /*!< FMC end of programming flag */ + +/* FMC interrupt flags */ +#define FMC_INT_FLAG_PGERR FMC_STAT_PGERR /*!< FMC programming error flag */ +#define FMC_INT_FLAG_PGAERR FMC_STAT_PGAERR /*!< FMC program alignment error flag */ +#define FMC_INT_FLAG_WPERR FMC_STAT_WPERR /*!< FMC write protection error flag */ +#define FMC_INT_FLAG_END FMC_STAT_ENDF /*!< FMC end of programming flag */ + +/* FMC interrupt enable */ +#define FMC_INTEN_END FMC_CTL_ENDIE /*!< enable FMC end of operation interrupt */ +#define FMC_INTEN_ERR FMC_CTL_ERRIE /*!< enable FMC error interrupt */ + +/* FMC time out */ +#define FMC_TIMEOUT_COUNT ((uint32_t)0x000F0000U) /*!< count to judge of FMC timeout */ + +/* function declarations */ +/* FMC main memory programming functions */ +/* unlock the main FMC operation */ +void fmc_unlock(void); +/* lock the main FMC operation */ +void fmc_lock(void); +/* set the wait state counter value */ +void fmc_wscnt_set(uint8_t wscnt); + +/* pre-fetch enable */ +void fmc_prefetch_enable(void); +/* pre-fetch disable */ +void fmc_prefetch_disable(void); +/* FMC erase page */ +fmc_state_enum fmc_page_erase(uint32_t page_address); +/* FMC erase whole chip */ +fmc_state_enum fmc_mass_erase(void); +/* FMC program a double word at the corresponding address */ +fmc_state_enum fmc_doubleword_program(uint32_t address, uint64_t data); +/* FMC program a word at the corresponding address */ +fmc_state_enum fmc_word_program(uint32_t address, uint32_t data); + +/* FMC option bytes programming functions */ +/* unlock the option byte operation */ +void ob_unlock(void); +/* lock the option byte operation */ +void ob_lock(void); +/* reload the option byte and generate a system reset */ +void ob_reset(void); +/* get option byte value */ +uint32_t option_byte_value_get(uint32_t addr); +/* erase option byte */ +fmc_state_enum ob_erase(void); +/* enable option byte write protection (OB_WP) */ +fmc_state_enum ob_write_protection_enable(uint16_t ob_wp); +/* configure read out protect */ +fmc_state_enum ob_security_protection_config(uint16_t ob_spc); +/* write the FMC option byte user */ +fmc_state_enum ob_user_write(uint8_t ob_user); +/* write the FMC option byte data */ +fmc_state_enum ob_data_program(uint16_t data); +/* get the FMC option byte OB_USER */ +uint8_t ob_user_get(void); +/* get the FMC option byte OB_DATA */ +uint16_t ob_data_get(void); +/* get the FMC option byte write protection */ +uint16_t ob_write_protection_get(void); +/* get the value of FMC option byte security protection level (PLEVEL) in FMC_OBSTAT register */ +uint32_t ob_obstat_plevel_get(void); + +/* FMC interrupts and flags management functions */ +/* enable FMC interrupt */ +void fmc_interrupt_enable(uint32_t interrupt); +/* disable FMC interrupt */ +void fmc_interrupt_disable(uint32_t interrupt); +/* get flag set or reset */ +FlagStatus fmc_flag_get(uint32_t flag); +/* clear the FMC pending flag */ +void fmc_flag_clear(uint32_t flag); +/* get intrrupt flag set or reset */ +FlagStatus fmc_interrupt_flag_get(uint32_t int_flag); +/* clear the FMC interrupt pending flag by writing 1 */ +void fmc_interrupt_flag_clear(uint32_t int_flag); +/* return the FMC state */ +fmc_state_enum fmc_state_get(void); +/* check FMC ready or not */ +fmc_state_enum fmc_ready_wait(uint32_t timeout); + +#endif /* GD32E230_FMC_H */ diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_fwdgt.h b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_fwdgt.h new file mode 100644 index 0000000000000000000000000000000000000000..101f87a34ad9c7c27b3248b451a7b340e74b76a0 --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_fwdgt.h @@ -0,0 +1,119 @@ +/*! + \file gd32e230_fwdgt.h + \brief definitions for the FWDGT + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor 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 copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 GD32E230_FWDGT_H +#define GD32E230_FWDGT_H + +#include "gd32e230.h" + +/* FWDGT definitions */ +#define FWDGT FWDGT_BASE + +/* registers definitions */ +#define FWDGT_CTL REG32((FWDGT) + 0x00000000U) /*!< FWDGT control register */ +#define FWDGT_PSC REG32((FWDGT) + 0x00000004U) /*!< FWDGT prescaler register */ +#define FWDGT_RLD REG32((FWDGT) + 0x00000008U) /*!< FWDGT reload register */ +#define FWDGT_STAT REG32((FWDGT) + 0x0000000CU) /*!< FWDGT status register */ +#define FWDGT_WND REG32((FWDGT) + 0x00000010U) /*!< FWDGT window register */ + +/* bits definitions */ +/* FWDGT_CTL */ +#define FWDGT_CTL_CMD BITS(0,15) /*!< FWDGT command value */ + +/* FWDGT_PSC */ +#define FWDGT_PSC_PSC BITS(0,2) /*!< FWDGT prescaler divider value */ + +/* FWDGT_RLD */ +#define FWDGT_RLD_RLD BITS(0,11) /*!< FWDGT counter reload value */ + +/* FWDGT_STAT */ +#define FWDGT_STAT_PUD BIT(0) /*!< FWDGT prescaler divider value update */ +#define FWDGT_STAT_RUD BIT(1) /*!< FWDGT counter reload value update */ +#define FWDGT_STAT_WUD BIT(2) /*!< FWDGT counter window value update */ + +/* FWDGT_WND */ +#define FWDGT_WND_WND BITS(0,11) /*!< FWDGT counter window value */ + +/* constants definitions */ +/* FWDGT_PSC register value */ +#define PSC_PSC(regval) (BITS(0,2) & ((uint32_t)(regval) << 0U)) +#define FWDGT_PSC_DIV4 ((uint8_t)PSC_PSC(0)) /*!< FWDGT prescaler set to 4 */ +#define FWDGT_PSC_DIV8 ((uint8_t)PSC_PSC(1)) /*!< FWDGT prescaler set to 8 */ +#define FWDGT_PSC_DIV16 ((uint8_t)PSC_PSC(2)) /*!< FWDGT prescaler set to 16 */ +#define FWDGT_PSC_DIV32 ((uint8_t)PSC_PSC(3)) /*!< FWDGT prescaler set to 32 */ +#define FWDGT_PSC_DIV64 ((uint8_t)PSC_PSC(4)) /*!< FWDGT prescaler set to 64 */ +#define FWDGT_PSC_DIV128 ((uint8_t)PSC_PSC(5)) /*!< FWDGT prescaler set to 128 */ +#define FWDGT_PSC_DIV256 ((uint8_t)PSC_PSC(6)) /*!< FWDGT prescaler set to 256 */ + +/* control value */ +#define FWDGT_WRITEACCESS_ENABLE ((uint16_t)0x00005555U) /*!< FWDGT_CTL bits write access enable value */ +#define FWDGT_WRITEACCESS_DISABLE ((uint16_t)0x00000000U) /*!< FWDGT_CTL bits write access disable value */ +#define FWDGT_KEY_RELOAD ((uint16_t)0x0000AAAAU) /*!< FWDGT_CTL bits fwdgt counter reload value */ +#define FWDGT_KEY_ENABLE ((uint16_t)0x0000CCCCU) /*!< FWDGT_CTL bits fwdgt counter enable value */ + +/* FWDGT timeout value */ +#define FWDGT_WND_TIMEOUT ((uint32_t)0x000FFFFFU) /*!< FWDGT_WND register write operation state flag timeout */ +#define FWDGT_PSC_TIMEOUT ((uint32_t)0x000FFFFFU) /*!< FWDGT_PSC register write operation state flag timeout */ +#define FWDGT_RLD_TIMEOUT ((uint32_t)0x000FFFFFU) /*!< FWDGT_RLD register write operation state flag timeout */ + +/* FWDGT flag definitions */ +#define FWDGT_FLAG_PUD FWDGT_STAT_PUD /*!< a write operation to FWDGT_PSC register is on going */ +#define FWDGT_FLAG_RUD FWDGT_STAT_RUD /*!< a write operation to FWDGT_RLD register is on going */ +#define FWDGT_FLAG_WUD FWDGT_STAT_WUD /*!< a write operation to FWDGT_WND register is on going */ + +/* function declarations */ +/* enable write access to FWDGT_PSC and FWDGT_RLD */ +void fwdgt_write_enable(void); +/* disable write access to FWDGT_PSC,FWDGT_RLD and FWDGT_WND */ +void fwdgt_write_disable(void); +/* start the free watchdog timer counter */ +void fwdgt_enable(void); + +/* configure the free watchdog timer counter prescaler value */ +ErrStatus fwdgt_prescaler_value_config(uint16_t prescaler_value); +/* configure the free watchdog timer counter reload value */ +ErrStatus fwdgt_reload_value_config(uint16_t reload_value); +/* configure the free watchdog timer counter window value */ +ErrStatus fwdgt_window_value_config(uint16_t window_value); +/* reload the counter of FWDGT */ +void fwdgt_counter_reload(void); +/* configure counter reload value, and prescaler divider value */ +ErrStatus fwdgt_config(uint16_t reload_value, uint8_t prescaler_div); + +/* get flag state of FWDGT */ +FlagStatus fwdgt_flag_get(uint16_t flag); + +#endif /* GD32E230_FWDGT_H */ diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_gpio.h b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..252383983d2a51cb65caef691a192d29d70bf82d --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_gpio.h @@ -0,0 +1,388 @@ +/*! + \file gd32e230_gpio.h + \brief definitions for the GPIO + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor 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 copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 GD32E230_GPIO_H +#define GD32E230_GPIO_H + +#include "gd32e230.h" + +/* GPIOx(x=A,B,C,F) definitions */ +#define GPIOA (GPIO_BASE + 0x00000000U) +#define GPIOB (GPIO_BASE + 0x00000400U) +#define GPIOC (GPIO_BASE + 0x00000800U) +#define GPIOF (GPIO_BASE + 0x00001400U) + +/* registers definitions */ +#define GPIO_CTL(gpiox) REG32((gpiox) + 0x00U) /*!< GPIO port control register */ +#define GPIO_OMODE(gpiox) REG32((gpiox) + 0x04U) /*!< GPIO port output mode register */ +#define GPIO_OSPD(gpiox) REG32((gpiox) + 0x08U) /*!< GPIO port output speed register */ +#define GPIO_PUD(gpiox) REG32((gpiox) + 0x0CU) /*!< GPIO port pull-up/pull-down register */ +#define GPIO_ISTAT(gpiox) REG32((gpiox) + 0x10U) /*!< GPIO port input status register */ +#define GPIO_OCTL(gpiox) REG32((gpiox) + 0x14U) /*!< GPIO port output control register */ +#define GPIO_BOP(gpiox) REG32((gpiox) + 0x18U) /*!< GPIO port bit operation register */ +#define GPIO_LOCK(gpiox) REG32((gpiox) + 0x1CU) /*!< GPIO port configuration lock register */ +#define GPIO_AFSEL0(gpiox) REG32((gpiox) + 0x20U) /*!< GPIO alternate function selected register 0 */ +#define GPIO_AFSEL1(gpiox) REG32((gpiox) + 0x24U) /*!< GPIO alternate function selected register 1 */ +#define GPIO_BC(gpiox) REG32((gpiox) + 0x28U) /*!< GPIO bit clear register */ +#define GPIO_TG(gpiox) REG32((gpiox) + 0x2CU) /*!< GPIO port bit toggle register */ + +/* bits definitions */ +/* GPIO_CTL */ +#define GPIO_CTL_CTL0 BITS(0,1) /*!< pin 0 configuration bits */ +#define GPIO_CTL_CTL1 BITS(2,3) /*!< pin 1 configuration bits */ +#define GPIO_CTL_CTL2 BITS(4,5) /*!< pin 2 configuration bits */ +#define GPIO_CTL_CTL3 BITS(6,7) /*!< pin 3 configuration bits */ +#define GPIO_CTL_CTL4 BITS(8,9) /*!< pin 4 configuration bits */ +#define GPIO_CTL_CTL5 BITS(10,11) /*!< pin 5 configuration bits */ +#define GPIO_CTL_CTL6 BITS(12,13) /*!< pin 6 configuration bits */ +#define GPIO_CTL_CTL7 BITS(14,15) /*!< pin 7 configuration bits */ +#define GPIO_CTL_CTL8 BITS(16,17) /*!< pin 8 configuration bits */ +#define GPIO_CTL_CTL9 BITS(18,19) /*!< pin 9 configuration bits */ +#define GPIO_CTL_CTL10 BITS(20,21) /*!< pin 10 configuration bits */ +#define GPIO_CTL_CTL11 BITS(22,23) /*!< pin 11 configuration bits */ +#define GPIO_CTL_CTL12 BITS(24,25) /*!< pin 12 configuration bits */ +#define GPIO_CTL_CTL13 BITS(26,27) /*!< pin 13 configuration bits */ +#define GPIO_CTL_CTL14 BITS(28,29) /*!< pin 14 configuration bits */ +#define GPIO_CTL_CTL15 BITS(30,31) /*!< pin 15 configuration bits */ + +/* GPIO_OMODE */ +#define GPIO_OMODE_OM0 BIT(0) /*!< pin 0 output mode bit */ +#define GPIO_OMODE_OM1 BIT(1) /*!< pin 1 output mode bit */ +#define GPIO_OMODE_OM2 BIT(2) /*!< pin 2 output mode bit */ +#define GPIO_OMODE_OM3 BIT(3) /*!< pin 3 output mode bit */ +#define GPIO_OMODE_OM4 BIT(4) /*!< pin 4 output mode bit */ +#define GPIO_OMODE_OM5 BIT(5) /*!< pin 5 output mode bit */ +#define GPIO_OMODE_OM6 BIT(6) /*!< pin 6 output mode bit */ +#define GPIO_OMODE_OM7 BIT(7) /*!< pin 7 output mode bit */ +#define GPIO_OMODE_OM8 BIT(8) /*!< pin 8 output mode bit */ +#define GPIO_OMODE_OM9 BIT(9) /*!< pin 9 output mode bit */ +#define GPIO_OMODE_OM10 BIT(10) /*!< pin 10 output mode bit */ +#define GPIO_OMODE_OM11 BIT(11) /*!< pin 11 output mode bit */ +#define GPIO_OMODE_OM12 BIT(12) /*!< pin 12 output mode bit */ +#define GPIO_OMODE_OM13 BIT(13) /*!< pin 13 output mode bit */ +#define GPIO_OMODE_OM14 BIT(14) /*!< pin 14 output mode bit */ +#define GPIO_OMODE_OM15 BIT(15) /*!< pin 15 output mode bit */ + +/* GPIO_OSPD */ +#define GPIO_OSPD_OSPD0 BITS(0,1) /*!< pin 0 output max speed bits */ +#define GPIO_OSPD_OSPD1 BITS(2,3) /*!< pin 1 output max speed bits */ +#define GPIO_OSPD_OSPD2 BITS(4,5) /*!< pin 2 output max speed bits */ +#define GPIO_OSPD_OSPD3 BITS(6,7) /*!< pin 3 output max speed bits */ +#define GPIO_OSPD_OSPD4 BITS(8,9) /*!< pin 4 output max speed bits */ +#define GPIO_OSPD_OSPD5 BITS(10,11) /*!< pin 5 output max speed bits */ +#define GPIO_OSPD_OSPD6 BITS(12,13) /*!< pin 6 output max speed bits */ +#define GPIO_OSPD_OSPD7 BITS(14,15) /*!< pin 7 output max speed bits */ +#define GPIO_OSPD_OSPD8 BITS(16,17) /*!< pin 8 output max speed bits */ +#define GPIO_OSPD_OSPD9 BITS(18,19) /*!< pin 9 output max speed bits */ +#define GPIO_OSPD_OSPD10 BITS(20,21) /*!< pin 10 output max speed bits */ +#define GPIO_OSPD_OSPD11 BITS(22,23) /*!< pin 11 output max speed bits */ +#define GPIO_OSPD_OSPD12 BITS(24,25) /*!< pin 12 output max speed bits */ +#define GPIO_OSPD_OSPD13 BITS(26,27) /*!< pin 13 output max speed bits */ +#define GPIO_OSPD_OSPD14 BITS(28,29) /*!< pin 14 output max speed bits */ +#define GPIO_OSPD_OSPD15 BITS(30,31) /*!< pin 15 output max speed bits */ + +/* GPIO_PUD */ +#define GPIO_PUD_PUD0 BITS(0,1) /*!< pin 0 pull-up or pull-down bits */ +#define GPIO_PUD_PUD1 BITS(2,3) /*!< pin 1 pull-up or pull-down bits */ +#define GPIO_PUD_PUD2 BITS(4,5) /*!< pin 2 pull-up or pull-down bits */ +#define GPIO_PUD_PUD3 BITS(6,7) /*!< pin 3 pull-up or pull-down bits */ +#define GPIO_PUD_PUD4 BITS(8,9) /*!< pin 4 pull-up or pull-down bits */ +#define GPIO_PUD_PUD5 BITS(10,11) /*!< pin 5 pull-up or pull-down bits */ +#define GPIO_PUD_PUD6 BITS(12,13) /*!< pin 6 pull-up or pull-down bits */ +#define GPIO_PUD_PUD7 BITS(14,15) /*!< pin 7 pull-up or pull-down bits */ +#define GPIO_PUD_PUD8 BITS(16,17) /*!< pin 8 pull-up or pull-down bits */ +#define GPIO_PUD_PUD9 BITS(18,19) /*!< pin 9 pull-up or pull-down bits */ +#define GPIO_PUD_PUD10 BITS(20,21) /*!< pin 10 pull-up or pull-down bits */ +#define GPIO_PUD_PUD11 BITS(22,23) /*!< pin 11 pull-up or pull-down bits */ +#define GPIO_PUD_PUD12 BITS(24,25) /*!< pin 12 pull-up or pull-down bits */ +#define GPIO_PUD_PUD13 BITS(26,27) /*!< pin 13 pull-up or pull-down bits */ +#define GPIO_PUD_PUD14 BITS(28,29) /*!< pin 14 pull-up or pull-down bits */ +#define GPIO_PUD_PUD15 BITS(30,31) /*!< pin 15 pull-up or pull-down bits */ + +/* GPIO_ISTAT */ +#define GPIO_ISTAT_ISTAT0 BIT(0) /*!< pin 0 input status */ +#define GPIO_ISTAT_ISTAT1 BIT(1) /*!< pin 1 input status */ +#define GPIO_ISTAT_ISTAT2 BIT(2) /*!< pin 2 input status */ +#define GPIO_ISTAT_ISTAT3 BIT(3) /*!< pin 3 input status */ +#define GPIO_ISTAT_ISTAT4 BIT(4) /*!< pin 4 input status */ +#define GPIO_ISTAT_ISTAT5 BIT(5) /*!< pin 5 input status */ +#define GPIO_ISTAT_ISTAT6 BIT(6) /*!< pin 6 input status */ +#define GPIO_ISTAT_ISTAT7 BIT(7) /*!< pin 7 input status */ +#define GPIO_ISTAT_ISTAT8 BIT(8) /*!< pin 8 input status */ +#define GPIO_ISTAT_ISTAT9 BIT(9) /*!< pin 9 input status */ +#define GPIO_ISTAT_ISTAT10 BIT(10) /*!< pin 10 input status */ +#define GPIO_ISTAT_ISTAT11 BIT(11) /*!< pin 11 input status */ +#define GPIO_ISTAT_ISTAT12 BIT(12) /*!< pin 12 input status */ +#define GPIO_ISTAT_ISTAT13 BIT(13) /*!< pin 13 input status */ +#define GPIO_ISTAT_ISTAT14 BIT(14) /*!< pin 14 input status */ +#define GPIO_ISTAT_ISTAT15 BIT(15) /*!< pin 15 input status */ + +/* GPIO_OCTL */ +#define GPIO_OCTL_OCTL0 BIT(0) /*!< pin 0 output bit */ +#define GPIO_OCTL_OCTL1 BIT(1) /*!< pin 1 output bit */ +#define GPIO_OCTL_OCTL2 BIT(2) /*!< pin 2 output bit */ +#define GPIO_OCTL_OCTL3 BIT(3) /*!< pin 3 output bit */ +#define GPIO_OCTL_OCTL4 BIT(4) /*!< pin 4 output bit */ +#define GPIO_OCTL_OCTL5 BIT(5) /*!< pin 5 output bit */ +#define GPIO_OCTL_OCTL6 BIT(6) /*!< pin 6 output bit */ +#define GPIO_OCTL_OCTL7 BIT(7) /*!< pin 7 output bit */ +#define GPIO_OCTL_OCTL8 BIT(8) /*!< pin 8 output bit */ +#define GPIO_OCTL_OCTL9 BIT(9) /*!< pin 9 output bit */ +#define GPIO_OCTL_OCTL10 BIT(10) /*!< pin 10 output bit */ +#define GPIO_OCTL_OCTL11 BIT(11) /*!< pin 11 output bit */ +#define GPIO_OCTL_OCTL12 BIT(12) /*!< pin 12 output bit */ +#define GPIO_OCTL_OCTL13 BIT(13) /*!< pin 13 output bit */ +#define GPIO_OCTL_OCTL14 BIT(14) /*!< pin 14 output bit */ +#define GPIO_OCTL_OCTL15 BIT(15) /*!< pin 15 output bit */ + +/* GPIO_BOP */ +#define GPIO_BOP_BOP0 BIT(0) /*!< pin 0 set bit */ +#define GPIO_BOP_BOP1 BIT(1) /*!< pin 1 set bit */ +#define GPIO_BOP_BOP2 BIT(2) /*!< pin 2 set bit */ +#define GPIO_BOP_BOP3 BIT(3) /*!< pin 3 set bit */ +#define GPIO_BOP_BOP4 BIT(4) /*!< pin 4 set bit */ +#define GPIO_BOP_BOP5 BIT(5) /*!< pin 5 set bit */ +#define GPIO_BOP_BOP6 BIT(6) /*!< pin 6 set bit */ +#define GPIO_BOP_BOP7 BIT(7) /*!< pin 7 set bit */ +#define GPIO_BOP_BOP8 BIT(8) /*!< pin 8 set bit */ +#define GPIO_BOP_BOP9 BIT(9) /*!< pin 9 set bit */ +#define GPIO_BOP_BOP10 BIT(10) /*!< pin 10 set bit */ +#define GPIO_BOP_BOP11 BIT(11) /*!< pin 11 set bit */ +#define GPIO_BOP_BOP12 BIT(12) /*!< pin 12 set bit */ +#define GPIO_BOP_BOP13 BIT(13) /*!< pin 13 set bit */ +#define GPIO_BOP_BOP14 BIT(14) /*!< pin 14 set bit */ +#define GPIO_BOP_BOP15 BIT(15) /*!< pin 15 set bit */ +#define GPIO_BOP_CR0 BIT(16) /*!< pin 0 clear bit */ +#define GPIO_BOP_CR1 BIT(17) /*!< pin 1 clear bit */ +#define GPIO_BOP_CR2 BIT(18) /*!< pin 2 clear bit */ +#define GPIO_BOP_CR3 BIT(19) /*!< pin 3 clear bit */ +#define GPIO_BOP_CR4 BIT(20) /*!< pin 4 clear bit */ +#define GPIO_BOP_CR5 BIT(21) /*!< pin 5 clear bit */ +#define GPIO_BOP_CR6 BIT(22) /*!< pin 6 clear bit */ +#define GPIO_BOP_CR7 BIT(23) /*!< pin 7 clear bit */ +#define GPIO_BOP_CR8 BIT(24) /*!< pin 8 clear bit */ +#define GPIO_BOP_CR9 BIT(25) /*!< pin 9 clear bit */ +#define GPIO_BOP_CR10 BIT(26) /*!< pin 10 clear bit */ +#define GPIO_BOP_CR11 BIT(27) /*!< pin 11 clear bit */ +#define GPIO_BOP_CR12 BIT(28) /*!< pin 12 clear bit */ +#define GPIO_BOP_CR13 BIT(29) /*!< pin 13 clear bit */ +#define GPIO_BOP_CR14 BIT(30) /*!< pin 14 clear bit */ +#define GPIO_BOP_CR15 BIT(31) /*!< pin 15 clear bit */ + +/* GPIO_LOCK */ +#define GPIO_LOCK_LK0 BIT(0) /*!< pin 0 lock bit */ +#define GPIO_LOCK_LK1 BIT(1) /*!< pin 1 lock bit */ +#define GPIO_LOCK_LK2 BIT(2) /*!< pin 2 lock bit */ +#define GPIO_LOCK_LK3 BIT(3) /*!< pin 3 lock bit */ +#define GPIO_LOCK_LK4 BIT(4) /*!< pin 4 lock bit */ +#define GPIO_LOCK_LK5 BIT(5) /*!< pin 5 lock bit */ +#define GPIO_LOCK_LK6 BIT(6) /*!< pin 6 lock bit */ +#define GPIO_LOCK_LK7 BIT(7) /*!< pin 7 lock bit */ +#define GPIO_LOCK_LK8 BIT(8) /*!< pin 8 lock bit */ +#define GPIO_LOCK_LK9 BIT(9) /*!< pin 9 lock bit */ +#define GPIO_LOCK_LK10 BIT(10) /*!< pin 10 lock bit */ +#define GPIO_LOCK_LK11 BIT(11) /*!< pin 11 lock bit */ +#define GPIO_LOCK_LK12 BIT(12) /*!< pin 12 lock bit */ +#define GPIO_LOCK_LK13 BIT(13) /*!< pin 13 lock bit */ +#define GPIO_LOCK_LK14 BIT(14) /*!< pin 14 lock bit */ +#define GPIO_LOCK_LK15 BIT(15) /*!< pin 15 lock bit */ +#define GPIO_LOCK_LKK BIT(16) /*!< pin sequence lock key */ + +/* GPIO_AFSEL0 */ +#define GPIO_AFSEL0_SEL0 BITS(0,3) /*!< pin 0 alternate function selected */ +#define GPIO_AFSEL0_SEL1 BITS(4,7) /*!< pin 1 alternate function selected */ +#define GPIO_AFSEL0_SEL2 BITS(8,11) /*!< pin 2 alternate function selected */ +#define GPIO_AFSEL0_SEL3 BITS(12,15) /*!< pin 3 alternate function selected */ +#define GPIO_AFSEL0_SEL4 BITS(16,19) /*!< pin 4 alternate function selected */ +#define GPIO_AFSEL0_SEL5 BITS(20,23) /*!< pin 5 alternate function selected */ +#define GPIO_AFSEL0_SEL6 BITS(24,27) /*!< pin 6 alternate function selected */ +#define GPIO_AFSEL0_SEL7 BITS(28,31) /*!< pin 7 alternate function selected */ + +/* GPIO_AFSEL1 */ +#define GPIO_AFSEL1_SEL8 BITS(0,3) /*!< pin 8 alternate function selected */ +#define GPIO_AFSEL1_SEL9 BITS(4,7) /*!< pin 9 alternate function selected */ +#define GPIO_AFSEL1_SEL10 BITS(8,11) /*!< pin 10 alternate function selected */ +#define GPIO_AFSEL1_SEL11 BITS(12,15) /*!< pin 11 alternate function selected */ +#define GPIO_AFSEL1_SEL12 BITS(16,19) /*!< pin 12 alternate function selected */ +#define GPIO_AFSEL1_SEL13 BITS(20,23) /*!< pin 13 alternate function selected */ +#define GPIO_AFSEL1_SEL14 BITS(24,27) /*!< pin 14 alternate function selected */ +#define GPIO_AFSEL1_SEL15 BITS(28,31) /*!< pin 15 alternate function selected */ + +/* GPIO_BC */ +#define GPIO_BC_CR0 BIT(0) /*!< pin 0 clear bit */ +#define GPIO_BC_CR1 BIT(1) /*!< pin 1 clear bit */ +#define GPIO_BC_CR2 BIT(2) /*!< pin 2 clear bit */ +#define GPIO_BC_CR3 BIT(3) /*!< pin 3 clear bit */ +#define GPIO_BC_CR4 BIT(4) /*!< pin 4 clear bit */ +#define GPIO_BC_CR5 BIT(5) /*!< pin 5 clear bit */ +#define GPIO_BC_CR6 BIT(6) /*!< pin 6 clear bit */ +#define GPIO_BC_CR7 BIT(7) /*!< pin 7 clear bit */ +#define GPIO_BC_CR8 BIT(8) /*!< pin 8 clear bit */ +#define GPIO_BC_CR9 BIT(9) /*!< pin 9 clear bit */ +#define GPIO_BC_CR10 BIT(10) /*!< pin 10 clear bit */ +#define GPIO_BC_CR11 BIT(11) /*!< pin 11 clear bit */ +#define GPIO_BC_CR12 BIT(12) /*!< pin 12 clear bit */ +#define GPIO_BC_CR13 BIT(13) /*!< pin 13 clear bit */ +#define GPIO_BC_CR14 BIT(14) /*!< pin 14 clear bit */ +#define GPIO_BC_CR15 BIT(15) /*!< pin 15 clear bit */ + +/* GPIO_TG */ +#define GPIO_TG_TG0 BIT(0) /*!< pin 0 toggle bit */ +#define GPIO_TG_TG1 BIT(1) /*!< pin 1 toggle bit */ +#define GPIO_TG_TG2 BIT(2) /*!< pin 2 toggle bit */ +#define GPIO_TG_TG3 BIT(3) /*!< pin 3 toggle bit */ +#define GPIO_TG_TG4 BIT(4) /*!< pin 4 toggle bit */ +#define GPIO_TG_TG5 BIT(5) /*!< pin 5 toggle bit */ +#define GPIO_TG_TG6 BIT(6) /*!< pin 6 toggle bit */ +#define GPIO_TG_TG7 BIT(7) /*!< pin 7 toggle bit */ +#define GPIO_TG_TG8 BIT(8) /*!< pin 8 toggle bit */ +#define GPIO_TG_TG9 BIT(9) /*!< pin 9 toggle bit */ +#define GPIO_TG_TG10 BIT(10) /*!< pin 10 toggle bit */ +#define GPIO_TG_TG11 BIT(11) /*!< pin 11 toggle bit */ +#define GPIO_TG_TG12 BIT(12) /*!< pin 12 toggle bit */ +#define GPIO_TG_TG13 BIT(13) /*!< pin 13 toggle bit */ +#define GPIO_TG_TG14 BIT(14) /*!< pin 14 toggle bit */ +#define GPIO_TG_TG15 BIT(15) /*!< pin 15 toggle bit */ + +/* constants definitions */ +typedef FlagStatus bit_status; + +/* output mode definitions */ +#define CTL_CLTR(regval) (BITS(0,1) & ((uint32_t)(regval) << 0)) +#define GPIO_MODE_INPUT CTL_CLTR(0) /*!< input mode */ +#define GPIO_MODE_OUTPUT CTL_CLTR(1) /*!< output mode */ +#define GPIO_MODE_AF CTL_CLTR(2) /*!< alternate function mode */ +#define GPIO_MODE_ANALOG CTL_CLTR(3) /*!< analog mode */ + +/* pull-up/pull-down definitions */ +#define PUD_PUPD(regval) (BITS(0,1) & ((uint32_t)(regval) << 0)) +#define GPIO_PUPD_NONE PUD_PUPD(0) /*!< floating mode, no pull-up and pull-down resistors */ +#define GPIO_PUPD_PULLUP PUD_PUPD(1) /*!< with pull-up resistor */ +#define GPIO_PUPD_PULLDOWN PUD_PUPD(2) /*!< with pull-down resistor */ + +/* GPIO pin definitions */ +#define GPIO_PIN_0 BIT(0) /*!< GPIO pin 0 */ +#define GPIO_PIN_1 BIT(1) /*!< GPIO pin 1 */ +#define GPIO_PIN_2 BIT(2) /*!< GPIO pin 2 */ +#define GPIO_PIN_3 BIT(3) /*!< GPIO pin 3 */ +#define GPIO_PIN_4 BIT(4) /*!< GPIO pin 4 */ +#define GPIO_PIN_5 BIT(5) /*!< GPIO pin 5 */ +#define GPIO_PIN_6 BIT(6) /*!< GPIO pin 6 */ +#define GPIO_PIN_7 BIT(7) /*!< GPIO pin 7 */ +#define GPIO_PIN_8 BIT(8) /*!< GPIO pin 8 */ +#define GPIO_PIN_9 BIT(9) /*!< GPIO pin 9 */ +#define GPIO_PIN_10 BIT(10) /*!< GPIO pin 10 */ +#define GPIO_PIN_11 BIT(11) /*!< GPIO pin 11 */ +#define GPIO_PIN_12 BIT(12) /*!< GPIO pin 12 */ +#define GPIO_PIN_13 BIT(13) /*!< GPIO pin 13 */ +#define GPIO_PIN_14 BIT(14) /*!< GPIO pin 14 */ +#define GPIO_PIN_15 BIT(15) /*!< GPIO pin 15 */ +#define GPIO_PIN_ALL BITS(0,15) /*!< GPIO pin all */ + +/* GPIO mode configuration values */ +#define GPIO_MODE_SET(n, mode) ((uint32_t)((uint32_t)(mode) << (2U * (n)))) +#define GPIO_MODE_MASK(n) (0x3U << (2U * (n))) + +/* GPIO pull-up/pull-down values */ +#define GPIO_PUPD_SET(n, pupd) ((uint32_t)((uint32_t)(pupd) << (2U * (n)))) +#define GPIO_PUPD_MASK(n) (0x3U << (2U * (n))) + +/* GPIO output speed values */ +#define GPIO_OSPEED_SET(n, speed) ((uint32_t)((uint32_t)(speed) << (2U * (n)))) +#define GPIO_OSPEED_MASK(n) (0x3U << (2U * (n))) + +/* GPIO output type */ +#define GPIO_OTYPE_PP ((uint8_t)(0x00U)) /*!< push pull mode */ +#define GPIO_OTYPE_OD ((uint8_t)(0x01U)) /*!< open drain mode */ + +/* GPIO output max speed value */ +#define OSPD_OSPD0(regval) (BITS(0,1) & ((uint32_t)(regval) << 0)) +#define GPIO_OSPEED_2MHZ OSPD_OSPD0(0) /*!< output max speed 2MHz */ +#define GPIO_OSPEED_10MHZ OSPD_OSPD0(1) /*!< output max speed 10MHz */ +#define GPIO_OSPEED_50MHZ OSPD_OSPD0(3) /*!< output max speed 50MHz */ + +/* GPIO alternate function values */ +#define GPIO_AFR_SET(n, af) ((uint32_t)((uint32_t)(af) << (4U * (n)))) +#define GPIO_AFR_MASK(n) (0xFU << (4U * (n))) + +/* GPIO alternate function */ +#define AF(regval) (BITS(0,3) & ((uint32_t)(regval) << 0)) +#define GPIO_AF_0 AF(0) /*!< alternate function 0 selected */ +#define GPIO_AF_1 AF(1) /*!< alternate function 1 selected */ +#define GPIO_AF_2 AF(2) /*!< alternate function 2 selected */ +#define GPIO_AF_3 AF(3) /*!< alternate function 3 selected */ +#define GPIO_AF_4 AF(4) /*!< alternate function 4 selected (port A,B only) */ +#define GPIO_AF_5 AF(5) /*!< alternate function 5 selected (port A,B only) */ +#define GPIO_AF_6 AF(6) /*!< alternate function 6 selected (port A,B only) */ +#define GPIO_AF_7 AF(7) /*!< alternate function 7 selected (port A,B only) */ + +/* function declarations */ +/* reset GPIO port */ +void gpio_deinit(uint32_t gpio_periph); +/* set GPIO mode */ +void gpio_mode_set(uint32_t gpio_periph, uint32_t mode, uint32_t pull_up_down, uint32_t pin); +/* set GPIO output type and speed */ +void gpio_output_options_set(uint32_t gpio_periph, uint8_t otype, uint32_t speed, uint32_t pin); + +/* set GPIO pin bit */ +void gpio_bit_set(uint32_t gpio_periph, uint32_t pin); +/* reset GPIO pin bit */ +void gpio_bit_reset(uint32_t gpio_periph, uint32_t pin); +/* write data to the specified GPIO pin */ +void gpio_bit_write(uint32_t gpio_periph, uint32_t pin, bit_status bit_value); +/* write data to the specified GPIO port */ +void gpio_port_write(uint32_t gpio_periph, uint16_t data); + +/* get GPIO pin input status */ +FlagStatus gpio_input_bit_get(uint32_t gpio_periph, uint32_t pin); +/* get GPIO port input status */ +uint16_t gpio_input_port_get(uint32_t gpio_periph); +/* get GPIO pin output status */ +FlagStatus gpio_output_bit_get(uint32_t gpio_periph, uint32_t pin); +/* get GPIO port output status */ +uint16_t gpio_output_port_get(uint32_t gpio_periph); + +/* set GPIO alternate function */ +void gpio_af_set(uint32_t gpio_periph,uint32_t alt_func_num, uint32_t pin); +/* lock GPIO pin bit */ +void gpio_pin_lock(uint32_t gpio_periph, uint32_t pin); + +/* toggle GPIO pin status */ +void gpio_bit_toggle(uint32_t gpio_periph, uint32_t pin); +/* toggle GPIO port status */ +void gpio_port_toggle(uint32_t gpio_periph); + +#endif /* GD32E230_GPIO_H */ diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_i2c.h b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_i2c.h new file mode 100644 index 0000000000000000000000000000000000000000..ab07d469870bb75aed0ff92eede8cdafedce159b --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_i2c.h @@ -0,0 +1,389 @@ +/*! + \file gd32e230_i2c.h + \brief definitions for the I2C + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor 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 copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 GD32E230_I2C_H +#define GD32E230_I2C_H + +#include "gd32e230.h" + +/* I2Cx(x=0,1) definitions */ +#define I2C0 I2C_BASE /*!< I2C0 base address */ +#define I2C1 (I2C_BASE+0x400U) /*!< I2C1 base address */ + +/* registers definitions */ +#define I2C_CTL0(i2cx) REG32((i2cx) + 0x00U) /*!< I2C control register 0 */ +#define I2C_CTL1(i2cx) REG32((i2cx) + 0x04U) /*!< I2C control register 1 */ +#define I2C_SADDR0(i2cx) REG32((i2cx) + 0x08U) /*!< I2C slave address register 0*/ +#define I2C_SADDR1(i2cx) REG32((i2cx) + 0x0CU) /*!< I2C slave address register */ +#define I2C_DATA(i2cx) REG32((i2cx) + 0x10U) /*!< I2C transfer buffer register */ +#define I2C_STAT0(i2cx) REG32((i2cx) + 0x14U) /*!< I2C transfer status register 0 */ +#define I2C_STAT1(i2cx) REG32((i2cx) + 0x18U) /*!< I2C transfer status register */ +#define I2C_CKCFG(i2cx) REG32((i2cx) + 0x1CU) /*!< I2C clock configure register */ +#define I2C_RT(i2cx) REG32((i2cx) + 0x20U) /*!< I2C rise time register */ +#define I2C_SAMCS(i2cx) REG32((i2cx) + 0x80U) /*!< I2C SAM control and status register */ +#define I2C_FMPCFG(i2cx) REG32((i2cx) + 0x90U) /*!< I2C fast-mode-plus configure register */ + +/* bits definitions */ +/* I2Cx_CTL0 */ +#define I2C_CTL0_I2CEN BIT(0) /*!< peripheral enable */ +#define I2C_CTL0_SMBEN BIT(1) /*!< SMBus mode */ +#define I2C_CTL0_SMBSEL BIT(3) /*!< SMBus type */ +#define I2C_CTL0_ARPEN BIT(4) /*!< ARP enable */ +#define I2C_CTL0_PECEN BIT(5) /*!< PEC enable */ +#define I2C_CTL0_GCEN BIT(6) /*!< general call enable */ +#define I2C_CTL0_SS BIT(7) /*!< clock stretching disable (slave mode) */ +#define I2C_CTL0_START BIT(8) /*!< start generation */ +#define I2C_CTL0_STOP BIT(9) /*!< stop generation */ +#define I2C_CTL0_ACKEN BIT(10) /*!< acknowledge enable */ +#define I2C_CTL0_POAP BIT(11) /*!< acknowledge/PEC position (for data reception) */ +#define I2C_CTL0_PECTRANS BIT(12) /*!< packet error checking */ +#define I2C_CTL0_SALT BIT(13) /*!< SMBus alert */ +#define I2C_CTL0_SRESET BIT(15) /*!< software reset */ + +/* I2Cx_CTL1 */ +#define I2C_CTL1_I2CCLK BITS(0,6) /*!< I2CCLK[6:0] bits (peripheral clock frequency) */ +#define I2C_CTL1_ERRIE BIT(8) /*!< error interrupt inable */ +#define I2C_CTL1_EVIE BIT(9) /*!< event interrupt enable */ +#define I2C_CTL1_BUFIE BIT(10) /*!< buffer interrupt enable */ +#define I2C_CTL1_DMAON BIT(11) /*!< DMA requests enable */ +#define I2C_CTL1_DMALST BIT(12) /*!< DMA last transfer */ + +/* I2Cx_SADDR0 */ +#define I2C_SADDR0_ADDRESS0 BIT(0) /*!< bit 0 of a 10-bit address */ +#define I2C_SADDR0_ADDRESS BITS(1,7) /*!< 7-bit address or bits 7:1 of a 10-bit address */ +#define I2C_SADDR0_ADDRESS_H BITS(8,9) /*!< highest two bits of a 10-bit address */ +#define I2C_SADDR0_ADDFORMAT BIT(15) /*!< address mode for the I2C slave */ + +/* I2Cx_SADDR1 */ +#define I2C_SADDR1_DUADEN BIT(0) /*!< aual-address mode switch */ +#define I2C_SADDR1_ADDRESS2 BITS(1,7) /*!< second I2C address for the slave in dual-address mode */ + +/* I2Cx_DATA */ +#define I2C_DATA_TRB BITS(0,7) /*!< 8-bit data register */ + +/* I2Cx_STAT0 */ +#define I2C_STAT0_SBSEND BIT(0) /*!< start bit (master mode) */ +#define I2C_STAT0_ADDSEND BIT(1) /*!< address sent (master mode)/matched (slave mode) */ +#define I2C_STAT0_BTC BIT(2) /*!< byte transfer finished */ +#define I2C_STAT0_ADD10SEND BIT(3) /*!< 10-bit header sent (master mode) */ +#define I2C_STAT0_STPDET BIT(4) /*!< stop detection (slave mode) */ +#define I2C_STAT0_RBNE BIT(6) /*!< data register not empty (receivers) */ +#define I2C_STAT0_TBE BIT(7) /*!< data register empty (transmitters) */ +#define I2C_STAT0_BERR BIT(8) /*!< bus error */ +#define I2C_STAT0_LOSTARB BIT(9) /*!< arbitration lost (master mode) */ +#define I2C_STAT0_AERR BIT(10) /*!< acknowledge failure */ +#define I2C_STAT0_OUERR BIT(11) /*!< overrun/underrun */ +#define I2C_STAT0_PECERR BIT(12) /*!< PEC error in reception */ +#define I2C_STAT0_SMBTO BIT(14) /*!< timeout signal in SMBus mode */ +#define I2C_STAT0_SMBALT BIT(15) /*!< SMBus alert status */ + +/* I2Cx_STAT1 */ +#define I2C_STAT1_MASTER BIT(0) /*!< master/slave */ +#define I2C_STAT1_I2CBSY BIT(1) /*!< bus busy */ +#define I2C_STAT1_TR BIT(2) /*!< transmitter/receiver */ +#define I2C_STAT1_RXGC BIT(4) /*!< general call address (slave mode) */ +#define I2C_STAT1_DEFSMB BIT(5) /*!< SMBus device default address (slave mode) */ +#define I2C_STAT1_HSTSMB BIT(6) /*!< SMBus host header (slave mode) */ +#define I2C_STAT1_DUMODF BIT(7) /*!< dual flag (slave mode) */ +#define I2C_STAT1_PECV BITS(8,15) /*!< packet error checking value */ + +/* I2Cx_CKCFG */ +#define I2C_CKCFG_CLKC BITS(0,11) /*!< clock control register in fast/standard mode or fast mode plus(master mode) */ +#define I2C_CKCFG_DTCY BIT(14) /*!< duty cycle of fast mode or fast mode plus */ +#define I2C_CKCFG_FAST BIT(15) /*!< I2C speed selection in master mode */ + +/* I2Cx_RT */ +#define I2C_RT_RISETIME BITS(0,6) /*!< maximum rise time in fast/standard mode or fast mode plus(master mode) */ + +/* I2Cx_SAMCS */ +#define I2C_SAMCS_SAMEN BIT(0) /*!< SAM_V interface enable */ +#define I2C_SAMCS_STOEN BIT(1) /*!< SAM_V interface timeout detect enable */ +#define I2C_SAMCS_TFFIE BIT(4) /*!< txframe fall interrupt enable */ +#define I2C_SAMCS_TFRIE BIT(5) /*!< txframe rise interrupt enable */ +#define I2C_SAMCS_RFFIE BIT(6) /*!< rxframe fall interrupt enable */ +#define I2C_SAMCS_RFRIE BIT(7) /*!< rxframe rise interrupt enable */ +#define I2C_SAMCS_TXF BIT(8) /*!< level of txframe signal */ +#define I2C_SAMCS_RXF BIT(9) /*!< level of rxframe signal */ +#define I2C_SAMCS_TFF BIT(12) /*!< txframe fall flag */ +#define I2C_SAMCS_TFR BIT(13) /*!< txframe rise flag */ +#define I2C_SAMCS_RFF BIT(14) /*!< rxframe fall flag */ +#define I2C_SAMCS_RFR BIT(15) /*!< rxframe rise flag */ + +/* I2Cx_FMPCFG */ +#define I2C_FMPCFG_FMPEN BIT(0) /*!< fast mode plus enable bit */ + +/* constants definitions */ +/* define the I2C bit position and its register index offset */ +#define I2C_REGIDX_BIT(regidx, bitpos) (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos)) +#define I2C_REG_VAL(i2cx, offset) (REG32((i2cx) + (((uint32_t)(offset) & 0xFFFFU) >> 6))) +#define I2C_BIT_POS(val) ((uint32_t)(val) & 0x1FU) +#define I2C_REGIDX_BIT2(regidx, bitpos, regidx2, bitpos2) (((uint32_t)(regidx2) << 22) | (uint32_t)((bitpos2) << 16)\ + | (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos))) +#define I2C_REG_VAL2(i2cx, offset) (REG32((i2cx) + ((uint32_t)(offset) >> 22))) +#define I2C_BIT_POS2(val) (((uint32_t)(val) & 0x1F0000U) >> 16) + +/* register offset */ +#define I2C_CTL1_REG_OFFSET 0x04U /*!< CTL1 register offset */ +#define I2C_STAT0_REG_OFFSET 0x14U /*!< STAT0 register offset */ +#define I2C_STAT1_REG_OFFSET 0x18U /*!< STAT1 register offset */ +#define I2C_SAMCS_REG_OFFSET 0x80U /*!< SAMCS register offset */ + +/* I2C flags */ +typedef enum +{ + /* flags in STAT0 register */ + I2C_FLAG_SBSEND = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 0U), /*!< start condition sent out in master mode */ + I2C_FLAG_ADDSEND = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 1U), /*!< address is sent in master mode or received and matches in slave mode */ + I2C_FLAG_BTC = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 2U), /*!< byte transmission finishes */ + I2C_FLAG_ADD10SEND = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 3U), /*!< header of 10-bit address is sent in master mode */ + I2C_FLAG_STPDET = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 4U), /*!< stop condition detected in slave mode */ + I2C_FLAG_RBNE = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 6U), /*!< I2C_DATA is not Empty during receiving */ + I2C_FLAG_TBE = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 7U), /*!< I2C_DATA is empty during transmitting */ + I2C_FLAG_BERR = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 8U), /*!< a bus error occurs indication a unexpected start or stop condition on I2C bus */ + I2C_FLAG_LOSTARB = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 9U), /*!< arbitration lost in master mode */ + I2C_FLAG_AERR = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 10U), /*!< acknowledge error */ + I2C_FLAG_OUERR = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 11U), /*!< over-run or under-run situation occurs in slave mode */ + I2C_FLAG_PECERR = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 12U), /*!< PEC error when receiving data */ + I2C_FLAG_SMBTO = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 14U), /*!< timeout signal in SMBus mode */ + I2C_FLAG_SMBALT = I2C_REGIDX_BIT(I2C_STAT0_REG_OFFSET, 15U), /*!< SMBus alert status */ + /* flags in STAT1 register */ + I2C_FLAG_MASTER = I2C_REGIDX_BIT(I2C_STAT1_REG_OFFSET, 0U), /*!< a flag indicating whether I2C block is in master or slave mode */ + I2C_FLAG_I2CBSY = I2C_REGIDX_BIT(I2C_STAT1_REG_OFFSET, 1U), /*!< busy flag */ + I2C_FLAG_TR = I2C_REGIDX_BIT(I2C_STAT1_REG_OFFSET, 2U), /*!< whether the I2C is a transmitter or a receiver */ + I2C_FLAG_RXGC = I2C_REGIDX_BIT(I2C_STAT1_REG_OFFSET, 4U), /*!< general call address (00h) received */ + I2C_FLAG_DEFSMB = I2C_REGIDX_BIT(I2C_STAT1_REG_OFFSET, 5U), /*!< default address of SMBus device */ + I2C_FLAG_HSTSMB = I2C_REGIDX_BIT(I2C_STAT1_REG_OFFSET, 6U), /*!< SMBus host header detected in slave mode */ + I2C_FLAG_DUMOD = I2C_REGIDX_BIT(I2C_STAT1_REG_OFFSET, 7U), /*!< dual flag in slave mode indicating which address is matched in dual-address mode */ + /* flags in SAMCS register */ + I2C_FLAG_TFF = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 12U), /*!< txframe fall flag */ + I2C_FLAG_TFR = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 13U), /*!< txframe rise flag */ + I2C_FLAG_RFF = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 14U), /*!< rxframe fall flag */ + I2C_FLAG_RFR = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 15U) /*!< rxframe rise flag */ +}i2c_flag_enum; + +/* I2C interrupt flags */ +typedef enum +{ + /* interrupt flags in CTL1 register */ + I2C_INT_FLAG_SBSEND = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 9U, I2C_STAT0_REG_OFFSET, 0U), /*!< start condition sent out in master mode interrupt flag */ + I2C_INT_FLAG_ADDSEND = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 9U, I2C_STAT0_REG_OFFSET, 1U), /*!< address is sent in master mode or received and matches in slave mode interrupt flag */ + I2C_INT_FLAG_BTC = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 9U, I2C_STAT0_REG_OFFSET, 2U), /*!< byte transmission finishes */ + I2C_INT_FLAG_ADD10SEND = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 9U, I2C_STAT0_REG_OFFSET, 3U), /*!< header of 10-bit address is sent in master mode interrupt flag */ + I2C_INT_FLAG_STPDET = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 9U, I2C_STAT0_REG_OFFSET, 4U), /*!< stop condition detected in slave mode interrupt flag */ + I2C_INT_FLAG_RBNE = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 9U, I2C_STAT0_REG_OFFSET, 6U), /*!< I2C_DATA is not Empty during receiving interrupt flag */ + I2C_INT_FLAG_TBE = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 9U, I2C_STAT0_REG_OFFSET, 7U), /*!< I2C_DATA is empty during transmitting interrupt flag */ + I2C_INT_FLAG_BERR = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 8U, I2C_STAT0_REG_OFFSET, 8U), /*!< a bus error occurs indication a unexpected start or stop condition on I2C bus interrupt flag */ + I2C_INT_FLAG_LOSTARB = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 8U, I2C_STAT0_REG_OFFSET, 9U), /*!< arbitration lost in master mode interrupt flag */ + I2C_INT_FLAG_AERR = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 8U, I2C_STAT0_REG_OFFSET, 10U), /*!< acknowledge error interrupt flag */ + I2C_INT_FLAG_OUERR = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 8U, I2C_STAT0_REG_OFFSET, 11U), /*!< over-run or under-run situation occurs in slave mode interrupt flag */ + I2C_INT_FLAG_PECERR = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 8U, I2C_STAT0_REG_OFFSET, 12U), /*!< PEC error when receiving data interrupt flag */ + I2C_INT_FLAG_SMBTO = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 8U, I2C_STAT0_REG_OFFSET, 14U), /*!< timeout signal in SMBus mode interrupt flag */ + I2C_INT_FLAG_SMBALT = I2C_REGIDX_BIT2(I2C_CTL1_REG_OFFSET, 8U, I2C_STAT0_REG_OFFSET, 15U), /*!< SMBus Alert status interrupt flag */ + /* interrupt flags in SAMCS register */ + I2C_INT_FLAG_TFF = I2C_REGIDX_BIT2(I2C_SAMCS_REG_OFFSET, 4U, I2C_SAMCS_REG_OFFSET, 12U), /*!< txframe fall interrupt flag */ + I2C_INT_FLAG_TFR = I2C_REGIDX_BIT2(I2C_SAMCS_REG_OFFSET, 5U, I2C_SAMCS_REG_OFFSET, 13U), /*!< txframe rise interrupt flag */ + I2C_INT_FLAG_RFF = I2C_REGIDX_BIT2(I2C_SAMCS_REG_OFFSET, 6U, I2C_SAMCS_REG_OFFSET, 14U), /*!< rxframe fall interrupt flag */ + I2C_INT_FLAG_RFR = I2C_REGIDX_BIT2(I2C_SAMCS_REG_OFFSET, 7U, I2C_SAMCS_REG_OFFSET, 15U) /*!< rxframe rise interrupt flag */ +}i2c_interrupt_flag_enum; + +/* I2C interrupt enable or disable */ +typedef enum +{ + /* interrupt in CTL1 register */ + I2C_INT_ERR = I2C_REGIDX_BIT(I2C_CTL1_REG_OFFSET, 8U), /*!< error interrupt enable */ + I2C_INT_EV = I2C_REGIDX_BIT(I2C_CTL1_REG_OFFSET, 9U), /*!< event interrupt enable */ + I2C_INT_BUF = I2C_REGIDX_BIT(I2C_CTL1_REG_OFFSET, 10U), /*!< buffer interrupt enable */ + /* interrupt in SAMCS register */ + I2C_INT_TFF = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 4U), /*!< txframe fall interrupt enable */ + I2C_INT_TFR = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 5U), /*!< txframe rise interrupt enable */ + I2C_INT_RFF = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 6U), /*!< rxframe fall interrupt enable */ + I2C_INT_RFR = I2C_REGIDX_BIT(I2C_SAMCS_REG_OFFSET, 7U) /*!< rxframe rise interrupt enable */ +}i2c_interrupt_enum; + +/* SMBus/I2C mode switch and SMBus type selection */ +#define I2C_I2CMODE_ENABLE ((uint32_t)0x00000000U) /*!< I2C mode */ +#define I2C_SMBUSMODE_ENABLE I2C_CTL0_SMBEN /*!< SMBus mode */ + +/* SMBus/I2C mode switch and SMBus type selection */ +#define I2C_SMBUS_DEVICE ((uint32_t)0x00000000U) /*!< SMBus mode device type */ +#define I2C_SMBUS_HOST I2C_CTL0_SMBSEL /*!< SMBus mode host type */ + +/* I2C transfer direction */ +#define I2C_RECEIVER ((uint32_t)0x00000001U) /*!< receiver */ +#define I2C_TRANSMITTER ((uint32_t)0xFFFFFFFEU) /*!< transmitter */ + +/* whether or not to send an ACK */ +#define I2C_ACK_DISABLE ((uint32_t)0x00000000U) /*!< ACK will be not sent */ +#define I2C_ACK_ENABLE ((uint32_t)0x00000001U) /*!< ACK will be sent */ + +/* I2C POAP position*/ +#define I2C_ACKPOS_NEXT ((uint32_t)0x00000000U) /*!< ACKEN bit decides whether or not to send ACK for the next byte */ +#define I2C_ACKPOS_CURRENT ((uint32_t)0x00000001U) /*!< ACKEN bit decides whether or not to send ACK or not for the current byte */ + +/* whether or not to stretch SCL low */ +#define I2C_SCLSTRETCH_ENABLE I2C_CTL0_SS /*!< SCL stretching is enabled */ +#define I2C_SCLSTRETCH_DISABLE ((uint32_t)0x00000000U) /*!< SCL stretching is disabled */ + +/* whether or not to response to a general call */ +#define I2C_GCEN_ENABLE I2C_CTL0_GCEN /*!< slave will response to a general call */ +#define I2C_GCEN_DISABLE ((uint32_t)0x00000000U) /*!< slave will not response to a general call */ + +/* software reset I2C */ +#define I2C_SRESET_SET I2C_CTL0_SRESET /*!< I2C is under reset */ +#define I2C_SRESET_RESET ((uint32_t)0x00000000U) /*!< I2C is not under reset */ + +/* I2C DMA mode configure */ +/* DMA mode switch */ +#define I2C_DMA_ON I2C_CTL1_DMAON /*!< DMA mode enabled */ +#define I2C_DMA_OFF ((uint32_t)0x00000000U) /*!< DMA mode disabled */ + +/* flag indicating DMA last transfer */ +#define I2C_DMALST_ON I2C_CTL1_DMALST /*!< next DMA EOT is the last transfer */ +#define I2C_DMALST_OFF ((uint32_t)0x00000000U) /*!< next DMA EOT is not the last transfer */ + +/* I2C PEC configure */ +/* PEC enable */ +#define I2C_PEC_ENABLE I2C_CTL0_PECEN /*!< PEC calculation on */ +#define I2C_PEC_DISABLE ((uint32_t)0x00000000U) /*!< PEC calculation off */ + +/* PEC transfer */ +#define I2C_PECTRANS_ENABLE I2C_CTL0_PECTRANS /*!< transfer PEC */ +#define I2C_PECTRANS_DISABLE ((uint32_t)0x00000000U) /*!< not transfer PEC value */ + +/* I2C SMBus configure */ +/* issue or not alert through SMBA pin */ +#define I2C_SALTSEND_ENABLE I2C_CTL0_SALT /*!< issue alert through SMBA pin */ +#define I2C_SALTSEND_DISABLE ((uint32_t)0x00000000U) /*!< not issue alert through SMBA */ + +/* ARP protocol in SMBus switch */ +#define I2C_ARP_ENABLE I2C_CTL0_ARPEN /*!< ARP enable */ +#define I2C_ARP_DISABLE ((uint32_t)0x00000000U) /*!< ARP disable */ + +/* fast mode plus enable */ +#define I2C_FAST_MODE_PLUS_ENABLE I2C_FMPCFG_FMPEN /*!< fast mode plus enable */ +#define I2C_FAST_MODE_PLUS_DISABLE ((uint32_t)0x00000000U) /*!< fast mode plus disable */ + +/* transmit I2C data */ +#define DATA_TRANS(regval) (BITS(0,7) & ((uint32_t)(regval) << 0)) + +/* receive I2C data */ +#define DATA_RECV(regval) GET_BITS((uint32_t)(regval), 0, 7) + +/* I2C duty cycle in fast mode or fast mode plus */ +#define I2C_DTCY_2 ((uint32_t)0x00000000U) /*!< in I2C fast mode or fast mode plus Tlow/Thigh = 2 */ +#define I2C_DTCY_16_9 I2C_CKCFG_DTCY /*!< in I2C fast mode or fast mode plus Tlow/Thigh = 16/9 */ + +/* address mode for the I2C slave */ +#define I2C_ADDFORMAT_7BITS ((uint32_t)0x00000000U) /*!< address:7 bits */ +#define I2C_ADDFORMAT_10BITS I2C_SADDR0_ADDFORMAT /*!< address:10 bits */ + +/* function declarations */ +/* reset I2C */ +void i2c_deinit(uint32_t i2c_periph); +/* configure I2C clock */ +void i2c_clock_config(uint32_t i2c_periph, uint32_t clkspeed, uint32_t dutycyc); +/* configure I2C address */ +void i2c_mode_addr_config(uint32_t i2c_periph, uint32_t mode, uint32_t addformat, uint32_t addr); +/* SMBus type selection */ +void i2c_smbus_type_config(uint32_t i2c_periph, uint32_t type); +/* whether or not to send an ACK */ +void i2c_ack_config(uint32_t i2c_periph, uint32_t ack); +/* configure I2C POAP position */ +void i2c_ackpos_config(uint32_t i2c_periph, uint32_t pos); +/* master sends slave address */ +void i2c_master_addressing(uint32_t i2c_periph, uint32_t addr, uint32_t trandirection); +/* enable dual-address mode */ +void i2c_dualaddr_enable(uint32_t i2c_periph, uint32_t addr); +/* disable dual-address mode */ +void i2c_dualaddr_disable(uint32_t i2c_periph); +/* enable I2C */ +void i2c_enable(uint32_t i2c_periph); +/* disable I2C */ +void i2c_disable(uint32_t i2c_periph); + +/* generate a START condition on I2C bus */ +void i2c_start_on_bus(uint32_t i2c_periph); +/* generate a STOP condition on I2C bus */ +void i2c_stop_on_bus(uint32_t i2c_periph); +/* I2C transmit data function */ +void i2c_data_transmit(uint32_t i2c_periph, uint8_t data); +/* I2C receive data function */ +uint8_t i2c_data_receive(uint32_t i2c_periph); +/* enable I2C DMA mode */ +void i2c_dma_enable(uint32_t i2c_periph, uint32_t dmastate); +/* configure whether next DMA EOT is DMA last transfer or not */ +void i2c_dma_last_transfer_config(uint32_t i2c_periph, uint32_t dmalast); +/* whether to stretch SCL low when data is not ready in slave mode */ +void i2c_stretch_scl_low_config(uint32_t i2c_periph, uint32_t stretchpara); +/* whether or not to response to a general call */ +void i2c_slave_response_to_gcall_config(uint32_t i2c_periph, uint32_t gcallpara); +/* software reset I2C */ +void i2c_software_reset_config(uint32_t i2c_periph, uint32_t sreset); + +/* I2C PEC calculation on or off */ +void i2c_pec_enable(uint32_t i2c_periph, uint32_t pecstate); +/* I2C whether to transfer PEC value */ +void i2c_pec_transfer_enable(uint32_t i2c_periph, uint32_t pecpara); +/* packet error checking value */ +uint8_t i2c_pec_value_get(uint32_t i2c_periph); +/* I2C issue alert through SMBA pin */ +void i2c_smbus_issue_alert(uint32_t i2c_periph, uint32_t smbuspara); +/* I2C ARP protocol in SMBus switch */ +void i2c_smbus_arp_enable(uint32_t i2c_periph, uint32_t arpstate); + +/* enable SAM_V interface */ +void i2c_sam_enable(uint32_t i2c_periph); +/* disable SAM_V interface */ +void i2c_sam_disable(uint32_t i2c_periph); +/* enable SAM_V interface timeout detect */ +void i2c_sam_timeout_enable(uint32_t i2c_periph); +/* disable SAM_V interface timeout detect */ +void i2c_sam_timeout_disable(uint32_t i2c_periph); + +/* check I2C flag is set or not */ +FlagStatus i2c_flag_get(uint32_t i2c_periph, i2c_flag_enum flag); +/* clear I2C flag */ +void i2c_flag_clear(uint32_t i2c_periph, i2c_flag_enum flag); +/* enable I2C interrupt */ +void i2c_interrupt_enable(uint32_t i2c_periph, i2c_interrupt_enum interrupt); +/* disable I2C interrupt */ +void i2c_interrupt_disable(uint32_t i2c_periph, i2c_interrupt_enum interrupt); +/* check I2C interrupt flag */ +FlagStatus i2c_interrupt_flag_get(uint32_t i2c_periph, i2c_interrupt_flag_enum int_flag); +/* clear I2C interrupt flag */ +void i2c_interrupt_flag_clear(uint32_t i2c_periph, i2c_interrupt_flag_enum int_flag); + +#endif /* GD32E230_I2C_H */ diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_misc.h b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_misc.h new file mode 100644 index 0000000000000000000000000000000000000000..4bc91a96000d1d407da50c0fb4daf2209303f277 --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_misc.h @@ -0,0 +1,86 @@ +/*! + \file gd32e230_misc.h + \brief definitions for the MISC + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor 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 copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 GD32E230_MISC_H +#define GD32E230_MISC_H + +#include "gd32e230.h" + +/* constants definitions */ +/* set the RAM and FLASH base address */ +#define NVIC_VECTTAB_RAM ((uint32_t)0x20000000) /*!< RAM base address */ +#define NVIC_VECTTAB_FLASH ((uint32_t)0x08000000) /*!< Flash base address */ + +/* set the NVIC vector table offset mask */ +#define NVIC_VECTTAB_OFFSET_MASK ((uint32_t)0x1FFFFF80) /*!< NVIC vector table offset mask */ + +/* the register key mask, if you want to do the write operation, you should write 0x5FA to VECTKEY bits */ +#define NVIC_AIRCR_VECTKEY_MASK ((uint32_t)0x05FA0000) /*!< NVIC VECTKEY mask */ + +/* choose the method to enter or exit the lowpower mode */ +#define SCB_SCR_SLEEPONEXIT ((uint8_t)0x02) /*!< choose the the system whether enter low power mode by exiting from ISR */ +#define SCB_SCR_SLEEPDEEP ((uint8_t)0x04) /*!< choose the the system enter the DEEPSLEEP mode or SLEEP mode */ +#define SCB_SCR_SEVONPEND ((uint8_t)0x10) /*!< choose the interrupt source that can wake up the lowpower mode */ + +#define SCB_LPM_SLEEP_EXIT_ISR SCB_SCR_SLEEPONEXIT /*!< low power mode by exiting from ISR */ +#define SCB_LPM_DEEPSLEEP SCB_SCR_SLEEPDEEP /*!< DEEPSLEEP mode or SLEEP mode */ +#define SCB_LPM_WAKE_BY_ALL_INT SCB_SCR_SEVONPEND /*!< wakeup by all interrupt */ + +/* choose the systick clock source */ +#define SYSTICK_CLKSOURCE_HCLK_DIV8 ((uint32_t)0xFFFFFFFBU) /*!< systick clock source is from HCLK/8 */ +#define SYSTICK_CLKSOURCE_HCLK ((uint32_t)0x00000004U) /*!< systick clock source is from HCLK */ + +/* function declarations */ + +/* enable NVIC request */ +void nvic_irq_enable(uint8_t nvic_irq, uint8_t nvic_irq_priority); +/* disable NVIC request */ +void nvic_irq_disable(uint8_t nvic_irq); +/* initiates a system reset request to reset the MCU */ +void nvic_system_reset(void); + +/* set the NVIC vector table base address */ +void nvic_vector_table_set(uint32_t nvic_vict_tab, uint32_t offset); + +/* set the state of the low power mode */ +void system_lowpower_set(uint8_t lowpower_mode); +/* reset the state of the low power mode */ +void system_lowpower_reset(uint8_t lowpower_mode); + +/* set the systick clock source */ +void systick_clksource_set(uint32_t systick_clksource); + +#endif /* GD32E230_MISC_H */ diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_pmu.h b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_pmu.h new file mode 100644 index 0000000000000000000000000000000000000000..1db5b1fb47cd6cc4bb2e6fab85e16b0f3a2124de --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_pmu.h @@ -0,0 +1,146 @@ +/*! + \file gd32e230_pmu.h + \brief definitions for the PMU + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor 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 copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 GD32E230_PMU_H +#define GD32E230_PMU_H + +#include "gd32e230.h" + +/* PMU definitions */ +#define PMU PMU_BASE /*!< PMU base address */ + +/* registers definitions */ +#define PMU_CTL REG32((PMU) + 0x00U) /*!< PMU control register */ +#define PMU_CS REG32((PMU) + 0x04U) /*!< PMU control and status register */ + +/* bits definitions */ +/* PMU_CTL */ +#define PMU_CTL_LDOLP BIT(0) /*!< LDO low power mode */ +#define PMU_CTL_STBMOD BIT(1) /*!< standby mode */ +#define PMU_CTL_WURST BIT(2) /*!< wakeup flag reset */ +#define PMU_CTL_STBRST BIT(3) /*!< standby flag reset */ +#define PMU_CTL_LVDEN BIT(4) /*!< low voltage detector enable */ +#define PMU_CTL_LVDT BITS(5,7) /*!< low voltage detector threshold */ +#define PMU_CTL_BKPWEN BIT(8) /*!< backup domain write enable */ +#define PMU_CTL_LDOVS_0 BIT(14) /*!< LDO output voltage select */ +#define PMU_CTL_LDOVS_1 BIT(15) /*!< LDO output voltage select */ +#define PMU_CTL_LDOVS BITS(14,15) /*!< LDO output voltage select */ + +/* PMU_CS */ +#define PMU_CS_WUF BIT(0) /*!< wakeup flag */ +#define PMU_CS_STBF BIT(1) /*!< standby flag */ +#define PMU_CS_LVDF BIT(2) /*!< low voltage detector status flag */ +#define PMU_CS_WUPEN0 BIT(8) /*!< wakeup pin enable */ +#define PMU_CS_WUPEN1 BIT(9) /*!< wakeup pin enable */ +#define PMU_CS_WUPEN5 BIT(13) /*!< wakeup pin enable */ +#define PMU_CS_WUPEN6 BIT(14) /*!< wakeup pin enable */ + +/* constants definitions */ +/* PMU low voltage detector threshold definitions */ +#define CTL_LVDT(regval) (BITS(5,7)&((uint32_t)(regval)<<5)) +#define PMU_LVDT_0 CTL_LVDT(0) /*!< voltage threshold is 2.1V */ +#define PMU_LVDT_1 CTL_LVDT(1) /*!< voltage threshold is 2.3V */ +#define PMU_LVDT_2 CTL_LVDT(2) /*!< voltage threshold is 2.4V */ +#define PMU_LVDT_3 CTL_LVDT(3) /*!< voltage threshold is 2.6V */ +#define PMU_LVDT_4 CTL_LVDT(4) /*!< voltage threshold is 2.7V */ +#define PMU_LVDT_5 CTL_LVDT(5) /*!< voltage threshold is 2.9V */ +#define PMU_LVDT_6 CTL_LVDT(6) /*!< voltage threshold is 3.0V */ +#define PMU_LVDT_7 CTL_LVDT(7) /*!< voltage threshold is 3.1V */ + +/* PMU LDO output voltage select definitions */ +#define CTL_LDOVS(regval) (BITS(14,15)&((uint32_t)(regval)<<14)) +#define PMU_LDOVS_HIGH CTL_LDOVS(1) /*!< LDO output voltage high mode */ +#define PMU_LDOVS_LOW CTL_LDOVS(2) /*!< LDO output voltage low mode */ + +/* PMU ldo definitions */ +#define PMU_LDO_NORMAL ((uint32_t)0x00000000U) /*!< LDO operates normally when PMU enter deepsleep mode */ +#define PMU_LDO_LOWPOWER PMU_CTL_LDOLP /*!< LDO work at low power status when PMU enter deepsleep mode */ + +/* PMU flag definitions */ +#define PMU_FLAG_WAKEUP PMU_CS_WUF /*!< wakeup flag status */ +#define PMU_FLAG_STANDBY PMU_CS_STBF /*!< standby flag status */ +#define PMU_FLAG_LVD PMU_CS_LVDF /*!< LVD flag status */ + +/* PMU WKUP pin definitions */ +#define PMU_WAKEUP_PIN0 PMU_CS_WUPEN0 /*!< WKUP Pin 0 (PA0) enable */ +#define PMU_WAKEUP_PIN1 PMU_CS_WUPEN1 /*!< WKUP Pin 1 (PC13) enable */ +#define PMU_WAKEUP_PIN5 PMU_CS_WUPEN5 /*!< WKUP Pin 5 (PB5) enable */ +#define PMU_WAKEUP_PIN6 PMU_CS_WUPEN6 /*!< WKUP Pin 6 (PB15) enable */ + +/* PMU flag reset definitions */ +#define PMU_FLAG_RESET_WAKEUP PMU_CTL_WURST /*!< wakeup flag reset */ +#define PMU_FLAG_RESET_STANDBY PMU_CTL_STBRST /*!< standby flag reset */ + +/* PMU command constants definitions */ +#define WFI_CMD ((uint8_t)0x00U) /*!< use WFI command */ +#define WFE_CMD ((uint8_t)0x01U) /*!< use WFE command */ + +/* function declarations */ +/* reset PMU registers */ +void pmu_deinit(void); + +/* select low voltage detector threshold */ +void pmu_lvd_select(uint32_t lvdt_n); +/* select LDO output voltage */ +void pmu_ldo_output_select(uint32_t ldo_output); +/* disable PMU lvd */ +void pmu_lvd_disable(void); + +/* set PMU mode */ +/* PMU work in sleep mode */ +void pmu_to_sleepmode(uint8_t sleepmodecmd); +/* PMU work in deepsleep mode */ +void pmu_to_deepsleepmode(uint32_t ldo, uint8_t deepsleepmodecmd); +/* PMU work in standby mode */ +void pmu_to_standbymode(uint8_t standbymodecmd); +/* enable PMU wakeup pin */ +void pmu_wakeup_pin_enable(uint32_t wakeup_pin); +/* disable PMU wakeup pin */ +void pmu_wakeup_pin_disable(uint32_t wakeup_pin); + +/* backup related functions */ +/* enable backup domain write */ +void pmu_backup_write_enable(void); +/* disable backup domain write */ +void pmu_backup_write_disable(void); + +/* flag functions */ +/* clear flag bit */ +void pmu_flag_clear(uint32_t flag_clear); +/* get flag state */ +FlagStatus pmu_flag_get(uint32_t flag); + +#endif /* GD32E230_PMU_H */ diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_rcu.h b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_rcu.h new file mode 100644 index 0000000000000000000000000000000000000000..53f2e34e345c56ea61927fd4076b0906e71f2d2e --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_rcu.h @@ -0,0 +1,672 @@ +/*! + \file gd32e230_rcu.h + \brief definitions for the RCU + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor 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 copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 GD32E230_RCU_H +#define GD32E230_RCU_H + +#include "gd32e230.h" + +/* RCU definitions */ +#define RCU RCU_BASE + +/* registers definitions */ +#define RCU_CTL0 REG32(RCU + 0x00U) /*!< control register 0 */ +#define RCU_CFG0 REG32(RCU + 0x04U) /*!< configuration register 0 */ +#define RCU_INT REG32(RCU + 0x08U) /*!< interrupt register */ +#define RCU_APB2RST REG32(RCU + 0x0CU) /*!< APB2 reset register */ +#define RCU_APB1RST REG32(RCU + 0x10U) /*!< APB1 reset register */ +#define RCU_AHBEN REG32(RCU + 0x14U) /*!< AHB enable register */ +#define RCU_APB2EN REG32(RCU + 0x18U) /*!< APB2 enable register */ +#define RCU_APB1EN REG32(RCU + 0x1CU) /*!< APB1 enable register */ +#define RCU_BDCTL REG32(RCU + 0x20U) /*!< backup domain control register */ +#define RCU_RSTSCK REG32(RCU + 0x24U) /*!< reset source /clock register */ +#define RCU_AHBRST REG32(RCU + 0x28U) /*!< AHB reset register */ +#define RCU_CFG1 REG32(RCU + 0x2CU) /*!< configuration register 1 */ +#define RCU_CFG2 REG32(RCU + 0x30U) /*!< configuration register 2 */ +#define RCU_CTL1 REG32(RCU + 0x34U) /*!< control register 1 */ +#define RCU_VKEY REG32(RCU + 0x100U) /*!< voltage key register */ +#define RCU_DSV REG32(RCU + 0x134U) /*!< deep-sleep mode voltage register */ + +/* bits definitions */ +/* RCU_CTL0 */ +#define RCU_CTL0_IRC8MEN BIT(0) /*!< internal high speed oscillator enable */ +#define RCU_CTL0_IRC8MSTB BIT(1) /*!< IRC8M high speed internal oscillator stabilization flag */ +#define RCU_CTL0_IRC8MADJ BITS(3,7) /*!< high speed internal oscillator clock trim adjust value */ +#define RCU_CTL0_IRC8MCALIB BITS(8,15) /*!< high speed internal oscillator calibration value register */ +#define RCU_CTL0_HXTALEN BIT(16) /*!< external high speed oscillator enable */ +#define RCU_CTL0_HXTALSTB BIT(17) /*!< external crystal oscillator clock stabilization flag */ +#define RCU_CTL0_HXTALBPS BIT(18) /*!< external crystal oscillator clock bypass mode enable */ +#define RCU_CTL0_CKMEN BIT(19) /*!< HXTAL clock monitor enable */ +#define RCU_CTL0_PLLEN BIT(24) /*!< PLL enable */ +#define RCU_CTL0_PLLSTB BIT(25) /*!< PLL clock stabilization flag */ + +/* RCU_CFG0 */ +#define RCU_CFG0_SCS BITS(0,1) /*!< system clock switch */ +#define RCU_CFG0_SCSS BITS(2,3) /*!< system clock switch status */ +#define RCU_CFG0_AHBPSC BITS(4,7) /*!< AHB prescaler selection */ +#define RCU_CFG0_APB1PSC BITS(8,10) /*!< APB1 prescaler selection */ +#define RCU_CFG0_APB2PSC BITS(11,13) /*!< APB2 prescaler selection */ +#define RCU_CFG0_ADCPSC BITS(14,15) /*!< ADC clock prescaler selection */ +#define RCU_CFG0_PLLSEL BIT(16) /*!< PLL clock source selection */ +#define RCU_CFG0_PLLPREDV BIT(17) /*!< divider for PLL source clock selection */ +#define RCU_CFG0_PLLMF (BIT(27) | BITS(18,21)) /*!< PLL multiply factor */ +#define RCU_CFG0_CKOUTSEL BITS(24,26) /*!< CK_OUT clock source selection */ +#define RCU_CFG0_PLLMF4 BIT(27) /*!< bit 4 of PLLMF */ +#define RCU_CFG0_CKOUTDIV BITS(28,30) /*!< CK_OUT divider which the CK_OUT frequency can be reduced */ +#define RCU_CFG0_PLLDV BIT(31) /*!< CK_PLL divide by 1 or 2 */ + +/* RCU_INT */ +#define RCU_INT_IRC40KSTBIF BIT(0) /*!< IRC40K stabilization interrupt flag */ +#define RCU_INT_LXTALSTBIF BIT(1) /*!< LXTAL stabilization interrupt flag */ +#define RCU_INT_IRC8MSTBIF BIT(2) /*!< IRC8M stabilization interrupt flag */ +#define RCU_INT_HXTALSTBIF BIT(3) /*!< HXTAL stabilization interrupt flag */ +#define RCU_INT_PLLSTBIF BIT(4) /*!< PLL stabilization interrupt flag */ +#define RCU_INT_IRC28MSTBIF BIT(5) /*!< IRC28M stabilization interrupt flag */ +#define RCU_INT_CKMIF BIT(7) /*!< HXTAL clock stuck interrupt flag */ +#define RCU_INT_IRC40KSTBIE BIT(8) /*!< IRC40K stabilization interrupt enable */ +#define RCU_INT_LXTALSTBIE BIT(9) /*!< LXTAL stabilization interrupt enable */ +#define RCU_INT_IRC8MSTBIE BIT(10) /*!< IRC8M stabilization interrupt enable */ +#define RCU_INT_HXTALSTBIE BIT(11) /*!< HXTAL stabilization interrupt enable */ +#define RCU_INT_PLLSTBIE BIT(12) /*!< PLL stabilization interrupt enable */ +#define RCU_INT_IRC28MSTBIE BIT(13) /*!< IRC28M stabilization interrupt enable */ +#define RCU_INT_IRC40KSTBIC BIT(16) /*!< IRC40K stabilization interrupt clear */ +#define RCU_INT_LXTALSTBIC BIT(17) /*!< LXTAL stabilization interrupt clear */ +#define RCU_INT_IRC8MSTBIC BIT(18) /*!< IRC8M stabilization interrupt clear */ +#define RCU_INT_HXTALSTBIC BIT(19) /*!< HXTAL stabilization interrupt clear */ +#define RCU_INT_PLLSTBIC BIT(20) /*!< PLL stabilization interrupt clear */ +#define RCU_INT_IRC28MSTBIC BIT(21) /*!< IRC28M stabilization interrupt clear */ +#define RCU_INT_CKMIC BIT(23) /*!< HXTAL clock stuck interrupt clear */ + +/* RCU_APB2RST */ +#define RCU_APB2RST_CFGRST BIT(0) /*!< system configuration reset */ +#define RCU_APB2RST_ADCRST BIT(9) /*!< ADC reset */ +#define RCU_APB2RST_TIMER0RST BIT(11) /*!< TIMER0 reset */ +#define RCU_APB2RST_SPI0RST BIT(12) /*!< SPI0 reset */ +#define RCU_APB2RST_USART0RST BIT(14) /*!< USART0 reset */ +#define RCU_APB2RST_TIMER14RST BIT(16) /*!< TIMER14 reset */ +#define RCU_APB2RST_TIMER15RST BIT(17) /*!< TIMER15 reset */ +#define RCU_APB2RST_TIMER16RST BIT(18) /*!< TIMER16 reset */ + +/* RCU_APB1RST */ +#define RCU_APB1RST_TIMER2RST BIT(1) /*!< TIMER2 timer reset */ +#define RCU_APB1RST_TIMER5RST BIT(4) /*!< TIMER5 timer reset */ +#define RCU_APB1RST_TIMER13RST BIT(8) /*!< TIMER13 timer reset */ +#define RCU_APB1RST_WWDGTRST BIT(11) /*!< window watchdog timer reset */ +#define RCU_APB1RST_SPI1RST BIT(14) /*!< SPI1 reset */ +#define RCU_APB1RST_USART1RST BIT(17) /*!< USART1 reset */ +#define RCU_APB1RST_I2C0RST BIT(21) /*!< I2C0 reset */ +#define RCU_APB1RST_I2C1RST BIT(22) /*!< I2C1 reset */ +#define RCU_APB1RST_PMURST BIT(28) /*!< power control reset */ + +/* RCU_AHBEN */ +#define RCU_AHBEN_DMAEN BIT(0) /*!< DMA clock enable */ +#define RCU_AHBEN_SRAMSPEN BIT(2) /*!< SRAM interface clock enable */ +#define RCU_AHBEN_FMCSPEN BIT(4) /*!< FMC clock enable */ +#define RCU_AHBEN_CRCEN BIT(6) /*!< CRC clock enable */ +#define RCU_AHBEN_PAEN BIT(17) /*!< GPIO port A clock enable */ +#define RCU_AHBEN_PBEN BIT(18) /*!< GPIO port B clock enable */ +#define RCU_AHBEN_PCEN BIT(19) /*!< GPIO port C clock enable */ +#define RCU_AHBEN_PFEN BIT(22) /*!< GPIO port F clock enable */ + +/* RCU_APB2EN */ +#define RCU_APB2EN_CFGCMPEN BIT(0) /*!< system configuration and comparator clock enable */ +#define RCU_APB2EN_ADCEN BIT(9) /*!< ADC interface clock enable */ +#define RCU_APB2EN_TIMER0EN BIT(11) /*!< TIMER0 timer clock enable */ +#define RCU_APB2EN_SPI0EN BIT(12) /*!< SPI0 clock enable */ +#define RCU_APB2EN_USART0EN BIT(14) /*!< USART0 clock enable */ +#define RCU_APB2EN_TIMER14EN BIT(16) /*!< TIMER14 timer clock enable */ +#define RCU_APB2EN_TIMER15EN BIT(17) /*!< TIMER15 timer clock enable */ +#define RCU_APB2EN_TIMER16EN BIT(18) /*!< TIMER16 timer clock enable */ +#define RCU_APB2EN_DBGMCUEN BIT(22) /*!< DBGMCU clock enable */ + +/* RCU_APB1EN */ +#define RCU_APB1EN_TIMER2EN BIT(1) /*!< TIMER2 timer clock enable */ +#define RCU_APB1EN_TIMER5EN BIT(4) /*!< TIMER5 timer clock enable */ +#define RCU_APB1EN_TIMER13EN BIT(8) /*!< TIMER13 timer clock enable */ +#define RCU_APB1EN_WWDGTEN BIT(11) /*!< window watchdog timer clock enable */ +#define RCU_APB1EN_SPI1EN BIT(14) /*!< SPI1 clock enable */ +#define RCU_APB1EN_USART1EN BIT(17) /*!< USART1 clock enable */ +#define RCU_APB1EN_I2C0EN BIT(21) /*!< I2C0 clock enable */ +#define RCU_APB1EN_I2C1EN BIT(22) /*!< I2C1 clock enable */ +#define RCU_APB1EN_PMUEN BIT(28) /*!< power interface clock enable */ + +/* RCU_BDCTL */ +#define RCU_BDCTL_LXTALEN BIT(0) /*!< LXTAL enable */ +#define RCU_BDCTL_LXTALSTB BIT(1) /*!< external low-speed oscillator stabilization */ +#define RCU_BDCTL_LXTALBPS BIT(2) /*!< LXTAL bypass mode enable */ +#define RCU_BDCTL_LXTALDRI BITS(3,4) /*!< LXTAL drive capability */ +#define RCU_BDCTL_RTCSRC BITS(8,9) /*!< RTC clock entry selection */ +#define RCU_BDCTL_RTCEN BIT(15) /*!< RTC clock enable */ +#define RCU_BDCTL_BKPRST BIT(16) /*!< backup domain reset */ + +/* RCU_RSTSCK */ +#define RCU_RSTSCK_IRC40KEN BIT(0) /*!< IRC40K enable */ +#define RCU_RSTSCK_IRC40KSTB BIT(1) /*!< IRC40K stabilization */ +#define RCU_RSTSCK_V12RSTF BIT(23) /*!< V12 domain power reset flag */ +#define RCU_RSTSCK_RSTFC BIT(24) /*!< reset flag clear */ +#define RCU_RSTSCK_OBLRSTF BIT(25) /*!< option byte loader reset flag */ +#define RCU_RSTSCK_EPRSTF BIT(26) /*!< external pin reset flag */ +#define RCU_RSTSCK_PORRSTF BIT(27) /*!< power reset flag */ +#define RCU_RSTSCK_SWRSTF BIT(28) /*!< software reset flag */ +#define RCU_RSTSCK_FWDGTRSTF BIT(29) /*!< free watchdog timer reset flag */ +#define RCU_RSTSCK_WWDGTRSTF BIT(30) /*!< window watchdog timer reset flag */ +#define RCU_RSTSCK_LPRSTF BIT(31) /*!< low-power reset flag */ + +/* RCU_AHBRST */ +#define RCU_AHBRST_PARST BIT(17) /*!< GPIO port A reset */ +#define RCU_AHBRST_PBRST BIT(18) /*!< GPIO port B reset */ +#define RCU_AHBRST_PCRST BIT(19) /*!< GPIO port C reset */ +#define RCU_AHBRST_PFRST BIT(22) /*!< GPIO port F reset */ + +/* RCU_CFG1 */ +#define RCU_CFG1_PREDV BITS(0,3) /*!< CK_HXTAL divider previous PLL */ + +/* RCU_CFG2 */ +#define RCU_CFG2_USART0SEL BITS(0,1) /*!< CK_USART0 clock source selection */ +#define RCU_CFG2_ADCSEL BIT(8) /*!< CK_ADC clock source selection */ +#define RCU_CFG2_IRC28MDIV BIT(16) /*!< CK_IRC28M divider 2 or not */ +#define RCU_CFG2_ADCPSC2 BIT(31) /*!< bit 2 of ADCPSC */ + +/* RCU_CTL1 */ +#define RCU_CTL1_IRC28MEN BIT(0) /*!< IRC28M internal 28M RC oscillator enable */ +#define RCU_CTL1_IRC28MSTB BIT(1) /*!< IRC28M internal 28M RC oscillator stabilization flag */ +#define RCU_CTL1_IRC28MADJ BITS(3,7) /*!< internal 28M RC oscillator clock trim adjust value */ +#define RCU_CTL1_IRC28MCALIB BITS(8,15) /*!< internal 28M RC oscillator calibration value register */ + +/* RCU_VKEY */ +#define RCU_VKEY_KEY BITS(0,31) /*!< key of RCU_DSV register */ + +/* RCU_DSV */ +#define RCU_DSV_DSLPVS BITS(0,1) /*!< deep-sleep mode voltage select */ + +/* constants definitions */ +/* define the peripheral clock enable bit position and its register index offset */ +#define RCU_REGIDX_BIT(regidx, bitpos) (((uint32_t)(regidx)<<6) | (uint32_t)(bitpos)) +#define RCU_REG_VAL(periph) (REG32(RCU + ((uint32_t)(periph)>>6))) +#define RCU_BIT_POS(val) ((uint32_t)(val) & 0x1FU) +/* define the voltage key unlock value */ +#define RCU_VKEY_UNLOCK ((uint32_t)0x1A2B3C4D) + +/* register index */ +typedef enum +{ + /* peripherals enable */ + IDX_AHBEN = 0x14U, + IDX_APB2EN = 0x18U, + IDX_APB1EN = 0x1CU, + /* peripherals reset */ + IDX_AHBRST = 0x28U, + IDX_APB2RST = 0x0CU, + IDX_APB1RST = 0x10U, + /* clock stabilization */ + IDX_CTL0 = 0x00U, + IDX_BDCTL = 0x20U, + IDX_CTL1 = 0x34U, + /* peripheral reset */ + IDX_RSTSCK = 0x24U, + /* clock stabilization and stuck interrupt */ + IDX_INT = 0x08U, + /* configuration register */ + IDX_CFG0 = 0x04U, + IDX_CFG2 = 0x30U +}reg_idx; + +/* peripheral clock enable */ +typedef enum +{ + /* AHB peripherals */ + RCU_DMA = RCU_REGIDX_BIT(IDX_AHBEN, 0U), /*!< DMA clock */ + RCU_CRC = RCU_REGIDX_BIT(IDX_AHBEN, 6U), /*!< CRC clock */ + RCU_GPIOA = RCU_REGIDX_BIT(IDX_AHBEN, 17U), /*!< GPIOA clock */ + RCU_GPIOB = RCU_REGIDX_BIT(IDX_AHBEN, 18U), /*!< GPIOB clock */ + RCU_GPIOC = RCU_REGIDX_BIT(IDX_AHBEN, 19U), /*!< GPIOC clock */ + RCU_GPIOF = RCU_REGIDX_BIT(IDX_AHBEN, 22U), /*!< GPIOF clock */ + + /* APB2 peripherals */ + RCU_CFGCMP = RCU_REGIDX_BIT(IDX_APB2EN, 0U), /*!< CFGCMP clock */ + RCU_ADC = RCU_REGIDX_BIT(IDX_APB2EN, 9U), /*!< ADC clock */ + RCU_TIMER0 = RCU_REGIDX_BIT(IDX_APB2EN, 11U), /*!< TIMER0 clock */ + RCU_SPI0 = RCU_REGIDX_BIT(IDX_APB2EN, 12U), /*!< SPI0 clock */ + RCU_USART0 = RCU_REGIDX_BIT(IDX_APB2EN, 14U), /*!< USART0 clock */ + RCU_TIMER14 = RCU_REGIDX_BIT(IDX_APB2EN, 16U), /*!< TIMER14 clock */ + RCU_TIMER15 = RCU_REGIDX_BIT(IDX_APB2EN, 17U), /*!< TIMER15 clock */ + RCU_TIMER16 = RCU_REGIDX_BIT(IDX_APB2EN, 18U), /*!< TIMER16 clock */ + RCU_DBGMCU = RCU_REGIDX_BIT(IDX_APB2EN, 22U), /*!< DBGMCU clock */ + + /* APB1 peripherals */ + RCU_TIMER2 = RCU_REGIDX_BIT(IDX_APB1EN, 1U), /*!< TIMER2 clock */ + RCU_TIMER5 = RCU_REGIDX_BIT(IDX_APB1EN, 4U), /*!< TIMER5 clock */ + RCU_TIMER13 = RCU_REGIDX_BIT(IDX_APB1EN, 8U), /*!< TIMER13 clock */ + RCU_WWDGT = RCU_REGIDX_BIT(IDX_APB1EN, 11U), /*!< WWDGT clock */ + RCU_SPI1 = RCU_REGIDX_BIT(IDX_APB1EN, 14U), /*!< SPI1 clock */ + RCU_USART1 = RCU_REGIDX_BIT(IDX_APB1EN, 17U), /*!< USART1 clock */ + RCU_I2C0 = RCU_REGIDX_BIT(IDX_APB1EN, 21U), /*!< I2C0 clock */ + RCU_I2C1 = RCU_REGIDX_BIT(IDX_APB1EN, 22U), /*!< I2C1 clock */ + RCU_PMU = RCU_REGIDX_BIT(IDX_APB1EN, 28U), /*!< PMU clock */ + + /* Backup domain control(BDCTL) */ + RCU_RTC = RCU_REGIDX_BIT(IDX_BDCTL, 15U) /*!< RTC clock */ +}rcu_periph_enum; + +/* peripheral clock enable when sleep mode*/ +typedef enum +{ + /* AHB peripherals */ + RCU_SRAM_SLP = RCU_REGIDX_BIT(IDX_AHBEN, 2U), /*!< SRAM clock */ + RCU_FMC_SLP = RCU_REGIDX_BIT(IDX_AHBEN, 4U), /*!< FMC clock */ +}rcu_periph_sleep_enum; + +/* peripherals reset */ +typedef enum +{ + /* AHB peripherals reset */ + RCU_GPIOARST = RCU_REGIDX_BIT(IDX_AHBRST, 17U), /*!< GPIOA reset */ + RCU_GPIOBRST = RCU_REGIDX_BIT(IDX_AHBRST, 18U), /*!< GPIOB reset */ + RCU_GPIOCRST = RCU_REGIDX_BIT(IDX_AHBRST, 19U), /*!< GPIOC reset */ + RCU_GPIOFRST = RCU_REGIDX_BIT(IDX_AHBRST, 22U), /*!< GPIOF reset */ + + /* APB2 peripherals reset */ + RCU_CFGCMPRST = RCU_REGIDX_BIT(IDX_APB2RST, 0U), /*!< CFGCMP reset */ + RCU_ADCRST = RCU_REGIDX_BIT(IDX_APB2RST, 9U), /*!< ADC reset */ + RCU_TIMER0RST = RCU_REGIDX_BIT(IDX_APB2RST, 11U), /*!< TIMER0 reset */ + RCU_SPI0RST = RCU_REGIDX_BIT(IDX_APB2RST, 12U), /*!< SPI0 reset */ + RCU_USART0RST = RCU_REGIDX_BIT(IDX_APB2RST, 14U), /*!< USART0 reset */ + RCU_TIMER14RST = RCU_REGIDX_BIT(IDX_APB2RST, 16U), /*!< TIMER14 reset */ + RCU_TIMER15RST = RCU_REGIDX_BIT(IDX_APB2RST, 17U), /*!< TIMER15 reset */ + RCU_TIMER16RST = RCU_REGIDX_BIT(IDX_APB2RST, 18U), /*!< TIMER16 reset */ + + /* APB1 peripherals reset */ + RCU_TIMER2RST = RCU_REGIDX_BIT(IDX_APB1RST, 1U), /*!< TIMER2 reset */ + RCU_TIMER5RST = RCU_REGIDX_BIT(IDX_APB1RST, 4U), /*!< TIMER5 reset */ + RCU_TIMER13RST = RCU_REGIDX_BIT(IDX_APB1RST, 8U), /*!< TIMER13 reset */ + RCU_WWDGTRST = RCU_REGIDX_BIT(IDX_APB1RST, 11U), /*!< WWDGT reset */ + RCU_SPI1RST = RCU_REGIDX_BIT(IDX_APB1RST, 14U), /*!< SPI1 reset */ + RCU_USART1RST = RCU_REGIDX_BIT(IDX_APB1RST, 17U), /*!< USART1 reset */ + RCU_I2C0RST = RCU_REGIDX_BIT(IDX_APB1RST, 21U), /*!< I2C0 reset */ + RCU_I2C1RST = RCU_REGIDX_BIT(IDX_APB1RST, 22U), /*!< I2C1 reset */ + RCU_PMURST = RCU_REGIDX_BIT(IDX_APB1RST, 28U), /*!< PMU reset */ +}rcu_periph_reset_enum; + +/* clock stabilization and peripheral reset flags */ +typedef enum +{ + RCU_FLAG_IRC40KSTB = RCU_REGIDX_BIT(IDX_RSTSCK, 1U), /*!< IRC40K stabilization flags */ + RCU_FLAG_LXTALSTB = RCU_REGIDX_BIT(IDX_BDCTL, 1U), /*!< LXTAL stabilization flags */ + RCU_FLAG_IRC8MSTB = RCU_REGIDX_BIT(IDX_CTL0, 1U), /*!< IRC8M stabilization flags */ + RCU_FLAG_HXTALSTB = RCU_REGIDX_BIT(IDX_CTL0, 17U), /*!< HXTAL stabilization flags */ + RCU_FLAG_PLLSTB = RCU_REGIDX_BIT(IDX_CTL0, 25U), /*!< PLL stabilization flags */ + RCU_FLAG_IRC28MSTB = RCU_REGIDX_BIT(IDX_CTL1, 1U), /*!< IRC28M stabilization flags */ + + RCU_FLAG_V12RST = RCU_REGIDX_BIT(IDX_RSTSCK, 23U), /*!< V12 reset flags */ + RCU_FLAG_OBLRST = RCU_REGIDX_BIT(IDX_RSTSCK, 25U), /*!< OBL reset flags */ + RCU_FLAG_EPRST = RCU_REGIDX_BIT(IDX_RSTSCK, 26U), /*!< EPR reset flags */ + RCU_FLAG_PORRST = RCU_REGIDX_BIT(IDX_RSTSCK, 27U), /*!< power reset flags */ + RCU_FLAG_SWRST = RCU_REGIDX_BIT(IDX_RSTSCK, 28U), /*!< SW reset flags */ + RCU_FLAG_FWDGTRST = RCU_REGIDX_BIT(IDX_RSTSCK, 29U), /*!< FWDGT reset flags */ + RCU_FLAG_WWDGTRST = RCU_REGIDX_BIT(IDX_RSTSCK, 30U), /*!< WWDGT reset flags */ + RCU_FLAG_LPRST = RCU_REGIDX_BIT(IDX_RSTSCK, 31U) /*!< LP reset flags */ +}rcu_flag_enum; + +/* clock stabilization and ckm interrupt flags */ +typedef enum +{ + RCU_INT_FLAG_IRC40KSTB = RCU_REGIDX_BIT(IDX_INT, 0U), /*!< IRC40K stabilization interrupt flag */ + RCU_INT_FLAG_LXTALSTB = RCU_REGIDX_BIT(IDX_INT, 1U), /*!< LXTAL stabilization interrupt flag */ + RCU_INT_FLAG_IRC8MSTB = RCU_REGIDX_BIT(IDX_INT, 2U), /*!< IRC8M stabilization interrupt flag */ + RCU_INT_FLAG_HXTALSTB = RCU_REGIDX_BIT(IDX_INT, 3U), /*!< HXTAL stabilization interrupt flag */ + RCU_INT_FLAG_PLLSTB = RCU_REGIDX_BIT(IDX_INT, 4U), /*!< PLL stabilization interrupt flag */ + RCU_INT_FLAG_IRC28MSTB = RCU_REGIDX_BIT(IDX_INT, 5U), /*!< IRC28M stabilization interrupt flag */ + RCU_INT_FLAG_CKM = RCU_REGIDX_BIT(IDX_INT, 7U), /*!< CKM interrupt flag */ +}rcu_int_flag_enum; + +/* clock stabilization and stuck interrupt flags clear */ +typedef enum +{ + RCU_INT_FLAG_IRC40KSTB_CLR = RCU_REGIDX_BIT(IDX_INT, 16U), /*!< IRC40K stabilization interrupt flags clear */ + RCU_INT_FLAG_LXTALSTB_CLR = RCU_REGIDX_BIT(IDX_INT, 17U), /*!< LXTAL stabilization interrupt flags clear */ + RCU_INT_FLAG_IRC8MSTB_CLR = RCU_REGIDX_BIT(IDX_INT, 18U), /*!< IRC8M stabilization interrupt flags clear */ + RCU_INT_FLAG_HXTALSTB_CLR = RCU_REGIDX_BIT(IDX_INT, 19U), /*!< HXTAL stabilization interrupt flags clear */ + RCU_INT_FLAG_PLLSTB_CLR = RCU_REGIDX_BIT(IDX_INT, 20U), /*!< PLL stabilization interrupt flags clear */ + RCU_INT_FLAG_IRC28MSTB_CLR = RCU_REGIDX_BIT(IDX_INT, 21U), /*!< IRC28M stabilization interrupt flags clear */ + RCU_INT_FLAG_CKM_CLR = RCU_REGIDX_BIT(IDX_INT, 23U), /*!< CKM interrupt flags clear */ +}rcu_int_flag_clear_enum; + +/* clock stabilization interrupt enable or disable */ +typedef enum +{ + RCU_INT_IRC40KSTB = RCU_REGIDX_BIT(IDX_INT, 8U), /*!< IRC40K stabilization interrupt */ + RCU_INT_LXTALSTB = RCU_REGIDX_BIT(IDX_INT, 9U), /*!< LXTAL stabilization interrupt */ + RCU_INT_IRC8MSTB = RCU_REGIDX_BIT(IDX_INT, 10U), /*!< IRC8M stabilization interrupt */ + RCU_INT_HXTALSTB = RCU_REGIDX_BIT(IDX_INT, 11U), /*!< HXTAL stabilization interrupt */ + RCU_INT_PLLSTB = RCU_REGIDX_BIT(IDX_INT, 12U), /*!< PLL stabilization interrupt */ + RCU_INT_IRC28MSTB = RCU_REGIDX_BIT(IDX_INT, 13U), /*!< IRC28M stabilization interrupt */ +}rcu_int_enum; + +/* ADC clock source */ +typedef enum +{ + RCU_ADCCK_IRC28M_DIV2 = 0U, /*!< ADC clock source select IRC28M/2 */ + RCU_ADCCK_IRC28M, /*!< ADC clock source select IRC28M */ + RCU_ADCCK_APB2_DIV2, /*!< ADC clock source select APB2/2 */ + RCU_ADCCK_AHB_DIV3, /*!< ADC clock source select AHB/3 */ + RCU_ADCCK_APB2_DIV4, /*!< ADC clock source select APB2/4 */ + RCU_ADCCK_AHB_DIV5, /*!< ADC clock source select AHB/5 */ + RCU_ADCCK_APB2_DIV6, /*!< ADC clock source select APB2/6 */ + RCU_ADCCK_AHB_DIV7, /*!< ADC clock source select AHB/7 */ + RCU_ADCCK_APB2_DIV8, /*!< ADC clock source select APB2/8 */ + RCU_ADCCK_AHB_DIV9 /*!< ADC clock source select AHB/9 */ +}rcu_adc_clock_enum; + +/* oscillator types */ +typedef enum +{ + RCU_HXTAL = RCU_REGIDX_BIT(IDX_CTL0, 16U), /*!< HXTAL */ + RCU_LXTAL = RCU_REGIDX_BIT(IDX_BDCTL, 0U), /*!< LXTAL */ + RCU_IRC8M = RCU_REGIDX_BIT(IDX_CTL0, 0U), /*!< IRC8M */ + RCU_IRC28M = RCU_REGIDX_BIT(IDX_CTL1, 0U), /*!< IRC28M */ + RCU_IRC40K = RCU_REGIDX_BIT(IDX_RSTSCK, 0U), /*!< IRC40K */ + RCU_PLL_CK = RCU_REGIDX_BIT(IDX_CTL0, 24U) /*!< PLL */ +}rcu_osci_type_enum; + +/* rcu clock frequency */ +typedef enum +{ + CK_SYS = 0U, /*!< system clock */ + CK_AHB, /*!< AHB clock */ + CK_APB1, /*!< APB1 clock */ + CK_APB2, /*!< APB2 clock */ + CK_ADC, /*!< ADC clock */ + CK_USART /*!< USART clock */ +}rcu_clock_freq_enum; + +/* system clock source select */ +#define CFG0_SCS(regval) (BITS(0,1) & ((uint32_t)(regval) << 0)) +#define RCU_CKSYSSRC_IRC8M CFG0_SCS(0) /*!< system clock source select IRC8M */ +#define RCU_CKSYSSRC_HXTAL CFG0_SCS(1) /*!< system clock source select HXTAL */ +#define RCU_CKSYSSRC_PLL CFG0_SCS(2) /*!< system clock source select PLL */ + +/* system clock source select status */ +#define CFG0_SCSS(regval) (BITS(2,3) & ((uint32_t)(regval) << 2)) +#define RCU_SCSS_IRC8M CFG0_SCSS(0) /*!< system clock source select IRC8M */ +#define RCU_SCSS_HXTAL CFG0_SCSS(1) /*!< system clock source select HXTAL */ +#define RCU_SCSS_PLL CFG0_SCSS(2) /*!< system clock source select PLL */ + +/* AHB prescaler selection */ +#define CFG0_AHBPSC(regval) (BITS(4,7) & ((uint32_t)(regval) << 4)) +#define RCU_AHB_CKSYS_DIV1 CFG0_AHBPSC(0) /*!< AHB prescaler select CK_SYS */ +#define RCU_AHB_CKSYS_DIV2 CFG0_AHBPSC(8) /*!< AHB prescaler select CK_SYS/2 */ +#define RCU_AHB_CKSYS_DIV4 CFG0_AHBPSC(9) /*!< AHB prescaler select CK_SYS/4 */ +#define RCU_AHB_CKSYS_DIV8 CFG0_AHBPSC(10) /*!< AHB prescaler select CK_SYS/8 */ +#define RCU_AHB_CKSYS_DIV16 CFG0_AHBPSC(11) /*!< AHB prescaler select CK_SYS/16 */ +#define RCU_AHB_CKSYS_DIV64 CFG0_AHBPSC(12) /*!< AHB prescaler select CK_SYS/64 */ +#define RCU_AHB_CKSYS_DIV128 CFG0_AHBPSC(13) /*!< AHB prescaler select CK_SYS/128 */ +#define RCU_AHB_CKSYS_DIV256 CFG0_AHBPSC(14) /*!< AHB prescaler select CK_SYS/256 */ +#define RCU_AHB_CKSYS_DIV512 CFG0_AHBPSC(15) /*!< AHB prescaler select CK_SYS/512 */ + +/* APB1 prescaler selection */ +#define CFG0_APB1PSC(regval) (BITS(8,10) & ((uint32_t)(regval) << 8)) +#define RCU_APB1_CKAHB_DIV1 CFG0_APB1PSC(0) /*!< APB1 prescaler select CK_AHB */ +#define RCU_APB1_CKAHB_DIV2 CFG0_APB1PSC(4) /*!< APB1 prescaler select CK_AHB/2 */ +#define RCU_APB1_CKAHB_DIV4 CFG0_APB1PSC(5) /*!< APB1 prescaler select CK_AHB/4 */ +#define RCU_APB1_CKAHB_DIV8 CFG0_APB1PSC(6) /*!< APB1 prescaler select CK_AHB/8 */ +#define RCU_APB1_CKAHB_DIV16 CFG0_APB1PSC(7) /*!< APB1 prescaler select CK_AHB/16 */ + +/* APB2 prescaler selection */ +#define CFG0_APB2PSC(regval) (BITS(11,13) & ((uint32_t)(regval) << 11)) +#define RCU_APB2_CKAHB_DIV1 CFG0_APB2PSC(0) /*!< APB2 prescaler select CK_AHB */ +#define RCU_APB2_CKAHB_DIV2 CFG0_APB2PSC(4) /*!< APB2 prescaler select CK_AHB/2 */ +#define RCU_APB2_CKAHB_DIV4 CFG0_APB2PSC(5) /*!< APB2 prescaler select CK_AHB/4 */ +#define RCU_APB2_CKAHB_DIV8 CFG0_APB2PSC(6) /*!< APB2 prescaler select CK_AHB/8 */ +#define RCU_APB2_CKAHB_DIV16 CFG0_APB2PSC(7) /*!< APB2 prescaler select CK_AHB/16 */ + +/* ADC clock prescaler selection */ +#define CFG0_ADCPSC(regval) (BITS(14,15) & ((uint32_t)(regval) << 14)) +#define RCU_ADC_CKAPB2_DIV2 CFG0_ADCPSC(0) /*!< ADC clock prescaler select CK_APB2/2 */ +#define RCU_ADC_CKAPB2_DIV4 CFG0_ADCPSC(1) /*!< ADC clock prescaler select CK_APB2/4 */ +#define RCU_ADC_CKAPB2_DIV6 CFG0_ADCPSC(2) /*!< ADC clock prescaler select CK_APB2/6 */ +#define RCU_ADC_CKAPB2_DIV8 CFG0_ADCPSC(3) /*!< ADC clock prescaler select CK_APB2/8 */ + +/* PLL clock source selection */ +#define RCU_PLLSRC_IRC8M_DIV2 (uint32_t)0x00000000U /*!< PLL clock source select IRC8M/2 */ +#define RCU_PLLSRC_HXTAL RCU_CFG0_PLLSEL /*!< PLL clock source select HXTAL */ + +/* HXTAL divider for PLL source clock selection */ +#define RCU_PLLPREDV (uint32_t)0x00000000U /*!< HXTAL clock selected */ +#define RCU_PLLPREDV_DIV2 RCU_CFG0_PLLPREDV /*!< HXTAL/2 clock selected */ + +/* PLL multiply factor */ +#define CFG0_PLLMF(regval) (BITS(18,21) & ((uint32_t)(regval) << 18)) +#define RCU_PLL_MUL2 CFG0_PLLMF(0) /*!< PLL source clock multiply by 2 */ +#define RCU_PLL_MUL3 CFG0_PLLMF(1) /*!< PLL source clock multiply by 3 */ +#define RCU_PLL_MUL4 CFG0_PLLMF(2) /*!< PLL source clock multiply by 4 */ +#define RCU_PLL_MUL5 CFG0_PLLMF(3) /*!< PLL source clock multiply by 5 */ +#define RCU_PLL_MUL6 CFG0_PLLMF(4) /*!< PLL source clock multiply by 6 */ +#define RCU_PLL_MUL7 CFG0_PLLMF(5) /*!< PLL source clock multiply by 7 */ +#define RCU_PLL_MUL8 CFG0_PLLMF(6) /*!< PLL source clock multiply by 8 */ +#define RCU_PLL_MUL9 CFG0_PLLMF(7) /*!< PLL source clock multiply by 9 */ +#define RCU_PLL_MUL10 CFG0_PLLMF(8) /*!< PLL source clock multiply by 10 */ +#define RCU_PLL_MUL11 CFG0_PLLMF(9) /*!< PLL source clock multiply by 11 */ +#define RCU_PLL_MUL12 CFG0_PLLMF(10) /*!< PLL source clock multiply by 12 */ +#define RCU_PLL_MUL13 CFG0_PLLMF(11) /*!< PLL source clock multiply by 13 */ +#define RCU_PLL_MUL14 CFG0_PLLMF(12) /*!< PLL source clock multiply by 14 */ +#define RCU_PLL_MUL15 CFG0_PLLMF(13) /*!< PLL source clock multiply by 15 */ +#define RCU_PLL_MUL16 CFG0_PLLMF(14) /*!< PLL source clock multiply by 16 */ +#define RCU_PLL_MUL17 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(0)) /*!< PLL source clock multiply by 17 */ +#define RCU_PLL_MUL18 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(1)) /*!< PLL source clock multiply by 18 */ +#define RCU_PLL_MUL19 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(2)) /*!< PLL source clock multiply by 19 */ +#define RCU_PLL_MUL20 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(3)) /*!< PLL source clock multiply by 20 */ +#define RCU_PLL_MUL21 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(4)) /*!< PLL source clock multiply by 21 */ +#define RCU_PLL_MUL22 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(5)) /*!< PLL source clock multiply by 22 */ +#define RCU_PLL_MUL23 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(6)) /*!< PLL source clock multiply by 23 */ +#define RCU_PLL_MUL24 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(7)) /*!< PLL source clock multiply by 24 */ +#define RCU_PLL_MUL25 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(8)) /*!< PLL source clock multiply by 25 */ +#define RCU_PLL_MUL26 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(9)) /*!< PLL source clock multiply by 26 */ +#define RCU_PLL_MUL27 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(10)) /*!< PLL source clock multiply by 27 */ +#define RCU_PLL_MUL28 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(11)) /*!< PLL source clock multiply by 28 */ +#define RCU_PLL_MUL29 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(12)) /*!< PLL source clock multiply by 29 */ +#define RCU_PLL_MUL30 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(13)) /*!< PLL source clock multiply by 30 */ +#define RCU_PLL_MUL31 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(14)) /*!< PLL source clock multiply by 31 */ +#define RCU_PLL_MUL32 (RCU_CFG0_PLLMF4 | CFG0_PLLMF(15)) /*!< PLL source clock multiply by 32 */ + +/* CK_OUT clock source selection */ +#define CFG0_CKOUTSEL(regval) (BITS(24,26) & ((uint32_t)(regval) << 24)) +#define RCU_CKOUTSRC_NONE CFG0_CKOUTSEL(0) /*!< no clock selected */ +#define RCU_CKOUTSRC_IRC28M CFG0_CKOUTSEL(1) /*!< CK_OUT clock source select IRC28M */ +#define RCU_CKOUTSRC_IRC40K CFG0_CKOUTSEL(2) /*!< CK_OUT clock source select IRC40K */ +#define RCU_CKOUTSRC_LXTAL CFG0_CKOUTSEL(3) /*!< CK_OUT clock source select LXTAL */ +#define RCU_CKOUTSRC_CKSYS CFG0_CKOUTSEL(4) /*!< CK_OUT clock source select CKSYS */ +#define RCU_CKOUTSRC_IRC8M CFG0_CKOUTSEL(5) /*!< CK_OUT clock source select IRC8M */ +#define RCU_CKOUTSRC_HXTAL CFG0_CKOUTSEL(6) /*!< CK_OUT clock source select HXTAL */ +#define RCU_CKOUTSRC_CKPLL_DIV1 (RCU_CFG0_PLLDV | CFG0_CKOUTSEL(7)) /*!< CK_OUT clock source select CK_PLL */ +#define RCU_CKOUTSRC_CKPLL_DIV2 CFG0_CKOUTSEL(7) /*!< CK_OUT clock source select CK_PLL/2 */ + +/* CK_OUT divider */ +#define CFG0_CKOUTDIV(regval) (BITS(28,30) & ((uint32_t)(regval) << 28)) +#define RCU_CKOUT_DIV1 CFG0_CKOUTDIV(0) /*!< CK_OUT is divided by 1 */ +#define RCU_CKOUT_DIV2 CFG0_CKOUTDIV(1) /*!< CK_OUT is divided by 2 */ +#define RCU_CKOUT_DIV4 CFG0_CKOUTDIV(2) /*!< CK_OUT is divided by 4 */ +#define RCU_CKOUT_DIV8 CFG0_CKOUTDIV(3) /*!< CK_OUT is divided by 8 */ +#define RCU_CKOUT_DIV16 CFG0_CKOUTDIV(4) /*!< CK_OUT is divided by 16 */ +#define RCU_CKOUT_DIV32 CFG0_CKOUTDIV(5) /*!< CK_OUT is divided by 32 */ +#define RCU_CKOUT_DIV64 CFG0_CKOUTDIV(6) /*!< CK_OUT is divided by 64 */ +#define RCU_CKOUT_DIV128 CFG0_CKOUTDIV(7) /*!< CK_OUT is divided by 128 */ + +/* CK_PLL divide by 1 or 2 for CK_OUT */ +#define RCU_PLLDV_CKPLL_DIV2 (uint32_t)0x00000000U /*!< CK_PLL divide by 2 for CK_OUT */ +#define RCU_PLLDV_CKPLL RCU_CFG0_PLLDV /*!< CK_PLL divide by 1 for CK_OUT */ + +/* LXTAL drive capability */ +#define BDCTL_LXTALDRI(regval) (BITS(3,4) & ((uint32_t)(regval) << 3)) +#define RCU_LXTAL_LOWDRI BDCTL_LXTALDRI(0) /*!< lower driving capability */ +#define RCU_LXTAL_MED_LOWDRI BDCTL_LXTALDRI(1) /*!< medium low driving capability */ +#define RCU_LXTAL_MED_HIGHDRI BDCTL_LXTALDRI(2) /*!< medium high driving capability */ +#define RCU_LXTAL_HIGHDRI BDCTL_LXTALDRI(3) /*!< higher driving capability */ + +/* RTC clock entry selection */ +#define BDCTL_RTCSRC(regval) (BITS(8,9) & ((uint32_t)(regval) << 8)) +#define RCU_RTCSRC_NONE BDCTL_RTCSRC(0) /*!< no clock selected */ +#define RCU_RTCSRC_LXTAL BDCTL_RTCSRC(1) /*!< LXTAL selected as RTC source clock */ +#define RCU_RTCSRC_IRC40K BDCTL_RTCSRC(2) /*!< IRC40K selected as RTC source clock */ +#define RCU_RTCSRC_HXTAL_DIV32 BDCTL_RTCSRC(3) /*!< HXTAL/32 selected as RTC source clock */ + +/* CK_HXTAL divider previous PLL */ +#define CFG1_PREDV(regval) (BITS(0,3) & ((uint32_t)(regval) << 0)) +#define RCU_PLL_PREDV1 CFG1_PREDV(0) /*!< PLL not divided */ +#define RCU_PLL_PREDV2 CFG1_PREDV(1) /*!< PLL divided by 2 */ +#define RCU_PLL_PREDV3 CFG1_PREDV(2) /*!< PLL divided by 3 */ +#define RCU_PLL_PREDV4 CFG1_PREDV(3) /*!< PLL divided by 4 */ +#define RCU_PLL_PREDV5 CFG1_PREDV(4) /*!< PLL divided by 5 */ +#define RCU_PLL_PREDV6 CFG1_PREDV(5) /*!< PLL divided by 6 */ +#define RCU_PLL_PREDV7 CFG1_PREDV(6) /*!< PLL divided by 7 */ +#define RCU_PLL_PREDV8 CFG1_PREDV(7) /*!< PLL divided by 8 */ +#define RCU_PLL_PREDV9 CFG1_PREDV(8) /*!< PLL divided by 9 */ +#define RCU_PLL_PREDV10 CFG1_PREDV(9) /*!< PLL divided by 10 */ +#define RCU_PLL_PREDV11 CFG1_PREDV(10) /*!< PLL divided by 11 */ +#define RCU_PLL_PREDV12 CFG1_PREDV(11) /*!< PLL divided by 12 */ +#define RCU_PLL_PREDV13 CFG1_PREDV(12) /*!< PLL divided by 13 */ +#define RCU_PLL_PREDV14 CFG1_PREDV(13) /*!< PLL divided by 14 */ +#define RCU_PLL_PREDV15 CFG1_PREDV(14) /*!< PLL divided by 15 */ +#define RCU_PLL_PREDV16 CFG1_PREDV(15) /*!< PLL divided by 16 */ + +/* USART0 clock source selection */ +#define CFG2_USART0SEL(regval) (BITS(0,1) & ((uint32_t)(regval) << 0)) +#define RCU_USART0SRC_CKAPB2 CFG2_USART0SEL(0) /*!< CK_USART0 select CK_APB2 */ +#define RCU_USART0SRC_CKSYS CFG2_USART0SEL(1) /*!< CK_USART0 select CK_SYS */ +#define RCU_USART0SRC_LXTAL CFG2_USART0SEL(2) /*!< CK_USART0 select LXTAL */ +#define RCU_USART0SRC_IRC8M CFG2_USART0SEL(3) /*!< CK_USART0 select IRC8M */ + +/* ADC clock source selection */ +#define RCU_ADCSRC_IRC28M (uint32_t)0x00000000U /*!< ADC clock source select */ +#define RCU_ADCSRC_AHB_APB2DIV RCU_CFG2_ADCSEL /*!< ADC clock source select */ + +/* IRC28M clock divider for ADC */ +#define RCU_ADC_IRC28M_DIV2 (uint32_t)0x00000000U /*!< IRC28M/2 select to ADC clock */ +#define RCU_ADC_IRC28M_DIV1 RCU_CFG2_IRC28MDIV /*!< IRC28M select to ADC clock */ + +/* Deep-sleep mode voltage */ +#define DSV_DSLPVS(regval) (BITS(0,1) & ((uint32_t)(regval) << 0)) +#define RCU_DEEPSLEEP_V_1_0 DSV_DSLPVS(0) /*!< core voltage is 1.0V in deep-sleep mode */ +#define RCU_DEEPSLEEP_V_0_9 DSV_DSLPVS(1) /*!< core voltage is 0.9V in deep-sleep mode */ +#define RCU_DEEPSLEEP_V_0_8 DSV_DSLPVS(2) /*!< core voltage is 0.8V in deep-sleep mode */ +#define RCU_DEEPSLEEP_V_1_2 DSV_DSLPVS(3) /*!< core voltage is 1.2V in deep-sleep mode */ + +/* function declarations */ +/* deinitialize the RCU */ +void rcu_deinit(void); +/* enable the peripherals clock */ +void rcu_periph_clock_enable(rcu_periph_enum periph); +/* disable the peripherals clock */ +void rcu_periph_clock_disable(rcu_periph_enum periph); +/* enable the peripherals clock when sleep mode */ +void rcu_periph_clock_sleep_enable(rcu_periph_sleep_enum periph); +/* disable the peripherals clock when sleep mode */ +void rcu_periph_clock_sleep_disable(rcu_periph_sleep_enum periph); +/* reset the peripherals */ +void rcu_periph_reset_enable(rcu_periph_reset_enum periph_reset); +/* disable reset the peripheral */ +void rcu_periph_reset_disable(rcu_periph_reset_enum periph_reset); +/* reset the BKP */ +void rcu_bkp_reset_enable(void); +/* disable the BKP reset */ +void rcu_bkp_reset_disable(void); + +/* configure the system clock source */ +void rcu_system_clock_source_config(uint32_t ck_sys); +/* get the system clock source */ +uint32_t rcu_system_clock_source_get(void); +/* configure the AHB prescaler selection */ +void rcu_ahb_clock_config(uint32_t ck_ahb); +/* configure the APB1 prescaler selection */ +void rcu_apb1_clock_config(uint32_t ck_apb1); +/* configure the APB2 prescaler selection */ +void rcu_apb2_clock_config(uint32_t ck_apb2); +/* configure the ADC clock source and prescaler selection */ +void rcu_adc_clock_config(rcu_adc_clock_enum ck_adc); +/* configure the CK_OUT clock source and divider */ +void rcu_ckout_config(uint32_t ckout_src, uint32_t ckout_div); + +/* configure the PLL clock source selection and PLL multiply factor */ +void rcu_pll_config(uint32_t pll_src, uint32_t pll_mul); +/* configure the USART clock source selection */ +void rcu_usart_clock_config(uint32_t ck_usart); +/* configure the RTC clock source selection */ +void rcu_rtc_clock_config(uint32_t rtc_clock_source); +/* configure the HXTAL divider used as input of PLL */ +void rcu_hxtal_prediv_config(uint32_t hxtal_prediv); +/* configure the LXTAL drive capability */ +void rcu_lxtal_drive_capability_config(uint32_t lxtal_dricap); + +/* get the clock stabilization and periphral reset flags */ +FlagStatus rcu_flag_get(rcu_flag_enum flag); +/* clear the reset flag */ +void rcu_all_reset_flag_clear(void); +/* get the clock stabilization interrupt and ckm flags */ +FlagStatus rcu_interrupt_flag_get(rcu_int_flag_enum int_flag); +/* clear the interrupt flags */ +void rcu_interrupt_flag_clear(rcu_int_flag_clear_enum int_flag_clear); +/* enable the stabilization interrupt */ +void rcu_interrupt_enable(rcu_int_enum stab_int); +/* disable the stabilization interrupt */ +void rcu_interrupt_disable(rcu_int_enum stab_int); + +/* wait until oscillator stabilization flags is SET */ +ErrStatus rcu_osci_stab_wait(rcu_osci_type_enum osci); +/* turn on the oscillator */ +void rcu_osci_on(rcu_osci_type_enum osci); +/* turn off the oscillator */ +void rcu_osci_off(rcu_osci_type_enum osci); +/* enable the oscillator bypass mode */ +void rcu_osci_bypass_mode_enable(rcu_osci_type_enum osci); +/* disable the oscillator bypass mode */ +void rcu_osci_bypass_mode_disable(rcu_osci_type_enum osci); +/* enable the HXTAL clock monitor */ +void rcu_hxtal_clock_monitor_enable(void); +/* disable the HXTAL clock monitor */ +void rcu_hxtal_clock_monitor_disable(void); + +/* set the IRC8M adjust value */ +void rcu_irc8m_adjust_value_set(uint8_t irc8m_adjval); +/* set the IRC28M adjust value */ +void rcu_irc28m_adjust_value_set(uint8_t irc28m_adjval); +/* unlock the voltage key */ +void rcu_voltage_key_unlock(void); +/* set the deep sleep mode voltage */ +void rcu_deepsleep_voltage_set(uint32_t dsvol); + +/* get the system clock, bus and peripheral clock frequency */ +uint32_t rcu_clock_freq_get(rcu_clock_freq_enum clock); + +#endif /* GD32E230_RCU_H */ diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_rtc.h b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_rtc.h new file mode 100644 index 0000000000000000000000000000000000000000..27756b160998c0e58116e1485c7647e9f451bb29 --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_rtc.h @@ -0,0 +1,561 @@ +/*! + \file gd32e230_rtc.h + \brief definitions for the RTC + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor 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 copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 GD32E230_RTC_H +#define GD32E230_RTC_H + +#include "gd32e230.h" + +/* RTC definitions */ +#define RTC RTC_BASE + +/* registers definitions */ +#define RTC_TIME REG32((RTC) + 0x00000000U) /*!< RTC time of day register */ +#define RTC_DATE REG32((RTC) + 0x00000004U) /*!< RTC date register */ +#define RTC_CTL REG32((RTC) + 0x00000008U) /*!< RTC control register */ +#define RTC_STAT REG32((RTC) + 0x0000000CU) /*!< RTC status register */ +#define RTC_PSC REG32((RTC) + 0x00000010U) /*!< RTC time prescaler register */ +#define RTC_ALRM0TD REG32((RTC) + 0x0000001CU) /*!< RTC alarm 0 time and date register */ +#define RTC_WPK REG32((RTC) + 0x00000024U) /*!< RTC write protection key register */ +#define RTC_SS REG32((RTC) + 0x00000028U) /*!< RTC sub second register */ +#define RTC_SHIFTCTL REG32((RTC) + 0x0000002CU) /*!< RTC shift function control register */ +#define RTC_TTS REG32((RTC) + 0x00000030U) /*!< RTC time of timestamp register */ +#define RTC_DTS REG32((RTC) + 0x00000034U) /*!< RTC date of timestamp register */ +#define RTC_SSTS REG32((RTC) + 0x00000038U) /*!< RTC sub second of timestamp register */ +#define RTC_HRFC REG32((RTC) + 0x0000003CU) /*!< RTC high resolution frequency compensation registor */ +#define RTC_TAMP REG32((RTC) + 0x00000040U) /*!< RTC tamper register */ +#define RTC_ALRM0SS REG32((RTC) + 0x00000044U) /*!< RTC alarm 0 sub second register */ +#define RTC_BKP0 REG32((RTC) + 0x00000050U) /*!< RTC backup 0 register */ +#define RTC_BKP1 REG32((RTC) + 0x00000054U) /*!< RTC backup 1 register */ +#define RTC_BKP2 REG32((RTC) + 0x00000058U) /*!< RTC backup 2 register */ +#define RTC_BKP3 REG32((RTC) + 0x0000005CU) /*!< RTC backup 3 register */ +#define RTC_BKP4 REG32((RTC) + 0x00000060U) /*!< RTC backup 4 register */ + +/* bits definitions */ +/* RTC_TIME */ +#define RTC_TIME_SCU BITS(0,3) /*!< second units in BCD code */ +#define RTC_TIME_SCT BITS(4,6) /*!< second tens in BCD code */ +#define RTC_TIME_MNU BITS(8,11) /*!< minute units in BCD code */ +#define RTC_TIME_MNT BITS(12,14) /*!< minute tens in BCD code */ +#define RTC_TIME_HRU BITS(16,19) /*!< hour units in BCD code */ +#define RTC_TIME_HRT BITS(20,21) /*!< hour tens in BCD code */ +#define RTC_TIME_PM BIT(22) /*!< AM/PM notation */ + +/* RTC_DATE */ +#define RTC_DATE_DAYU BITS(0,3) /*!< date units in BCD code */ +#define RTC_DATE_DAYT BITS(4,5) /*!< date tens in BCD code */ +#define RTC_DATE_MONU BITS(8,11) /*!< month units in BCD code */ +#define RTC_DATE_MONT BIT(12) /*!< month tens in BCD code */ +#define RTC_DATE_DOW BITS(13,15) /*!< day of week units */ +#define RTC_DATE_YRU BITS(16,19) /*!< year units in BCD code */ +#define RTC_DATE_YRT BITS(20,23) /*!< year tens in BCD code */ + +/* RTC_CTL */ +#define RTC_CTL_TSEG BIT(3) /*!< valid event edge of time-stamp */ +#define RTC_CTL_REFEN BIT(4) /*!< reference clock detection function enable */ +#define RTC_CTL_BPSHAD BIT(5) /*!< shadow registers bypass control */ +#define RTC_CTL_CS BIT(6) /*!< display format of clock system */ +#define RTC_CTL_ALRM0EN BIT(8) /*!< alarm function enable */ +#define RTC_CTL_TSEN BIT(11) /*!< time-stamp function enable */ +#define RTC_CTL_ALRM0IE BIT(12) /*!< RTC alarm interrupt enable */ +#define RTC_CTL_TSIE BIT(15) /*!< time-stamp interrupt enable */ +#define RTC_CTL_A1H BIT(16) /*!< add 1 hour(summer time change) */ +#define RTC_CTL_S1H BIT(17) /*!< subtract 1 hour(winter time change) */ +#define RTC_CTL_DSM BIT(18) /*!< daylight saving mark */ +#define RTC_CTL_COS BIT(19) /*!< calibration output selection */ +#define RTC_CTL_OPOL BIT(20) /*!< output polarity */ +#define RTC_CTL_OS BITS(21,22) /*!< output selection */ +#define RTC_CTL_COEN BIT(23) /*!< calibration output enable */ + +/* RTC_STAT */ +#define RTC_STAT_ALRM0WF BIT(0) /*!< alarm configuration can be write flag */ +#define RTC_STAT_SOPF BIT(3) /*!< shift function operation pending flag */ +#define RTC_STAT_YCM BIT(4) /*!< year configuration mark status flag */ +#define RTC_STAT_RSYNF BIT(5) /*!< register synchronization flag */ +#define RTC_STAT_INITF BIT(6) /*!< initialization state flag */ +#define RTC_STAT_INITM BIT(7) /*!< enter initialization mode */ +#define RTC_STAT_ALRM0F BIT(8) /*!< alarm occurs flag */ +#define RTC_STAT_TSF BIT(11) /*!< time-stamp flag */ +#define RTC_STAT_TSOVRF BIT(12) /*!< time-stamp overflow flag */ +#define RTC_STAT_TP0F BIT(13) /*!< RTC tamp 0 detected flag */ +#define RTC_STAT_TP1F BIT(14) /*!< RTC tamp 1 detected flag */ +#define RTC_STAT_SCPF BIT(16) /*!< recalibration pending flag */ + +/* RTC_PSC */ +#define RTC_PSC_FACTOR_S BITS(0,14) /*!< synchronous prescaler factor */ +#define RTC_PSC_FACTOR_A BITS(16,22) /*!< asynchronous prescaler factor */ + +/* RTC_ALRM0TD */ +#define RTC_ALRM0TD_SCU BITS(0,3) /*!< second units in BCD code */ +#define RTC_ALRM0TD_SCT BITS(4,6) /*!< second tens in BCD code */ +#define RTC_ALRM0TD_MSKS BIT(7) /*!< alarm second mask bit */ +#define RTC_ALRM0TD_MNU BITS(8,11) /*!< minutes units in BCD code */ +#define RTC_ALRM0TD_MNT BITS(12,14) /*!< minutes tens in BCD code */ +#define RTC_ALRM0TD_MSKM BIT(15) /*!< alarm minutes mask bit */ +#define RTC_ALRM0TD_HRU BITS(16,19) /*!< hour units in BCD code */ +#define RTC_ALRM0TD_HRT BITS(20,21) /*!< hour units in BCD code */ +#define RTC_ALRM0TD_PM BIT(22) /*!< AM/PM flag */ +#define RTC_ALRM0TD_MSKH BIT(23) /*!< alarm hour mask bit */ +#define RTC_ALRM0TD_DAYU BITS(24,27) /*!< date units or week day in BCD code */ +#define RTC_ALRM0TD_DAYT BITS(28,29) /*!< date tens in BCD code */ +#define RTC_ALRM0TD_DOWS BIT(30) /*!< day of week selection */ +#define RTC_ALRM0TD_MSKD BIT(31) /*!< alarm date mask bit */ + +/* RTC_WPK */ +#define RTC_WPK_WPK BITS(0,7) /*!< key for write protection */ + +/* RTC_SS */ +#define RTC_SS_SSC BITS(0,15) /*!< sub second value */ + +/* RTC_SHIFTCTL */ +#define RTC_SHIFTCTL_SFS BITS(0,14) /*!< subtract a fraction of a second */ +#define RTC_SHIFTCTL_A1S BIT(31) /*!< one second add */ + +/* RTC_TTS */ +#define RTC_TTS_SCU BITS(0,3) /*!< second units in BCD code */ +#define RTC_TTS_SCT BITS(4,6) /*!< second units in BCD code */ +#define RTC_TTS_MNU BITS(8,11) /*!< minute units in BCD code */ +#define RTC_TTS_MNT BITS(12,14) /*!< minute tens in BCD code */ +#define RTC_TTS_HRU BITS(16,19) /*!< hour units in BCD code */ +#define RTC_TTS_HRT BITS(20,21) /*!< hour tens in BCD code */ +#define RTC_TTS_PM BIT(22) /*!< AM/PM notation */ + +/* RTC_DTS */ +#define RTC_DTS_DAYU BITS(0,3) /*!< date units in BCD code */ +#define RTC_DTS_DAYT BITS(4,5) /*!< date tens in BCD code */ +#define RTC_DTS_MONU BITS(8,11) /*!< month units in BCD code */ +#define RTC_DTS_MONT BIT(12) /*!< month tens in BCD code */ +#define RTC_DTS_DOW BITS(13,15) /*!< day of week units */ + +/* RTC_SSTS */ +#define RTC_SSTS_SSC BITS(0,15) /*!< timestamp sub second units */ + +/* RTC_HRFC */ +#define RTC_HRFC_CMSK BITS(0,8) /*!< calibration mask number */ +#define RTC_HRFC_CWND16 BIT(13) /*!< calibration window select 16 seconds */ +#define RTC_HRFC_CWND8 BIT(14) /*!< calibration window select 16 seconds */ +#define RTC_HRFC_FREQI BIT(15) /*!< increase RTC frequency by 488.5ppm */ + +/* RTC_TAMP */ +#define RTC_TAMP_TP0EN BIT(0) /*!< tamper 0 detection enable */ +#define RTC_TAMP_TP0EG BIT(1) /*!< tamper 0 event trigger edge for RTC tamp 0 input */ +#define RTC_TAMP_TPIE BIT(2) /*!< tamper detection interrupt enable */ +#define RTC_TAMP_TP1EN BIT(3) /*!< tamper 1 detection enable */ +#define RTC_TAMP_TP1EG BIT(4) /*!< tamper 1 event trigger edge for RTC tamp 1 input */ +#define RTC_TAMP_TPTS BIT(7) /*!< make tamper function used for timestamp function */ +#define RTC_TAMP_FREQ BITS(8,10) /*!< sample frequency of tamper event detection */ +#define RTC_TAMP_FLT BITS(11,12) /*!< RTC tamp x filter count setting */ +#define RTC_TAMP_PRCH BITS(13,14) /*!< precharge duration time of RTC tamp x */ +#define RTC_TAMP_DISPU BIT(15) /*!< RTC tamp x pull up disable bit */ +#define RTC_TAMP_PC13VAL BIT(18) /*!< alarm output type control/PC13 output value */ +#define RTC_TAMP_PC13MDE BIT(19) /*!< PC13 mode */ +#define RTC_TAMP_PC14VAL BIT(20) /*!< PC14 output value */ +#define RTC_TAMP_PC14MDE BIT(21) /*!< PC14 mode */ +#define RTC_TAMP_PC15VAL BIT(22) /*!< PC15 output value */ +#define RTC_TAMP_PC15MDE BIT(23) /*!< PC15 mode */ + +/* RTC_ALRM0SS */ +#define RTC_ALRM0SS_SSC BITS(0,14) /*!< alarm sub second value */ +#define RTC_ALRM0SS_MASKSSC BITS(24,27) /*!< mask control bit of SS */ + +/* RTC_BKP0 */ +#define RTC_BKP0_DATA BITS(0,31) /*!< backup domain registers */ + +/* RTC_BKP1 */ +#define RTC_BKP1_DATA BITS(0,31) /*!< backup domain registers */ + +/* RTC_BKP2 */ +#define RTC_BKP2_DATA BITS(0,31) /*!< backup domain registers */ + +/* RTC_BKP3 */ +#define RTC_BKP3_DATA BITS(0,31) /*!< backup domain registers */ + +/* RTC_BKP4 */ +#define RTC_BKP4_DATA BITS(0,31) /*!< backup domain registers */ + +/* constants definitions */ +/* structure for initialization of the RTC */ +typedef struct +{ + uint8_t rtc_year; /*!< RTC year value: 0x0 - 0x99(BCD format) */ + uint8_t rtc_month; /*!< RTC month value */ + uint8_t rtc_date; /*!< RTC date value: 0x1 - 0x31(BCD format) */ + uint8_t rtc_day_of_week; /*!< RTC weekday value */ + uint8_t rtc_hour; /*!< RTC hour value */ + uint8_t rtc_minute; /*!< RTC minute value: 0x0 - 0x59(BCD format) */ + uint8_t rtc_second; /*!< RTC second value: 0x0 - 0x59(BCD format) */ + uint16_t rtc_factor_asyn; /*!< RTC asynchronous prescaler value: 0x0 - 0x7F */ + uint16_t rtc_factor_syn; /*!< RTC synchronous prescaler value: 0x0 - 0x7FFF */ + uint32_t rtc_am_pm; /*!< RTC AM/PM value */ + uint32_t rtc_display_format; /*!< RTC time notation */ +}rtc_parameter_struct; + +/* structure for RTC alarm configuration */ +typedef struct +{ + uint32_t rtc_alarm_mask; /*!< RTC alarm mask */ + uint32_t rtc_weekday_or_date; /*!< specify RTC alarm is on date or weekday */ + uint8_t rtc_alarm_day; /*!< RTC alarm date or weekday value*/ + uint8_t rtc_alarm_hour; /*!< RTC alarm hour value */ + uint8_t rtc_alarm_minute; /*!< RTC alarm minute value: 0x0 - 0x59(BCD format) */ + uint8_t rtc_alarm_second; /*!< RTC alarm second value: 0x0 - 0x59(BCD format) */ + uint32_t rtc_am_pm; /*!< RTC alarm AM/PM value */ +}rtc_alarm_struct; + +/* structure for RTC time-stamp configuration */ +typedef struct +{ + uint8_t rtc_timestamp_month; /*!< RTC time-stamp month value */ + uint8_t rtc_timestamp_date; /*!< RTC time-stamp date value: 0x1 - 0x31(BCD format) */ + uint8_t rtc_timestamp_day; /*!< RTC time-stamp weekday value */ + uint8_t rtc_timestamp_hour; /*!< RTC time-stamp hour value */ + uint8_t rtc_timestamp_minute; /*!< RTC time-stamp minute value: 0x0 - 0x59(BCD format) */ + uint8_t rtc_timestamp_second; /*!< RTC time-stamp second value: 0x0 - 0x59(BCD format) */ + uint32_t rtc_am_pm; /*!< RTC time-stamp AM/PM value */ +}rtc_timestamp_struct; + +/* structure for RTC tamper configuration */ +typedef struct +{ + uint32_t rtc_tamper_source; /*!< RTC tamper source */ + uint32_t rtc_tamper_trigger; /*!< RTC tamper trigger */ + uint32_t rtc_tamper_filter; /*!< RTC tamper consecutive samples needed during a voltage level detection */ + uint32_t rtc_tamper_sample_frequency; /*!< RTC tamper sampling frequency during a voltage level detection */ + ControlStatus rtc_tamper_precharge_enable; /*!< RTC tamper precharge feature during a voltage level detection */ + uint32_t rtc_tamper_precharge_time; /*!< RTC tamper precharge duration if precharge feature is enabled */ + ControlStatus rtc_tamper_with_timestamp; /*!< RTC tamper time-stamp feature */ +}rtc_tamper_struct; + +/* time register value */ +#define TIME_SC(regval) (BITS(0,6) & ((uint32_t)(regval) << 0U)) /*!< write value to RTC_TIME_SC bit field */ +#define GET_TIME_SC(regval) GET_BITS((regval),0,6) /*!< get value of RTC_TIME_SC bit field */ + +#define TIME_MN(regval) (BITS(8,14) & ((uint32_t)(regval) << 8U)) /*!< write value to RTC_TIME_MN bit field */ +#define GET_TIME_MN(regval) GET_BITS((regval),8,14) /*!< get value of RTC_TIME_MN bit field */ + +#define TIME_HR(regval) (BITS(16,21) & ((uint32_t)(regval) << 16U)) /*!< write value to RTC_TIME_HR bit field */ +#define GET_TIME_HR(regval) GET_BITS((regval),16,21) /*!< get value of RTC_TIME_HR bit field */ + +#define RTC_AM ((uint32_t)0x00000000U) /*!< AM format */ +#define RTC_PM RTC_TIME_PM /*!< PM format */ + +/* date register value */ +#define DATE_DAY(regval) (BITS(0,5) & ((uint32_t)(regval) << 0U)) /*!< write value to RTC_DATE_DAY bit field */ +#define GET_DATE_DAY(regval) GET_BITS((regval),0,5) /*!< get value of RTC_DATE_DAY bit field */ + +#define DATE_MON(regval) (BITS(8,12) & ((uint32_t)(regval) << 8U)) /*!< write value to RTC_DATE_MON bit field */ +#define GET_DATE_MON(regval) GET_BITS((regval),8,12) /*!< get value of RTC_DATE_MON bit field */ +#define RTC_JAN ((uint8_t)0x01U) /*!< Janurary */ +#define RTC_FEB ((uint8_t)0x02U) /*!< February */ +#define RTC_MAR ((uint8_t)0x03U) /*!< March */ +#define RTC_APR ((uint8_t)0x04U) /*!< April */ +#define RTC_MAY ((uint8_t)0x05U) /*!< May */ +#define RTC_JUN ((uint8_t)0x06U) /*!< June */ +#define RTC_JUL ((uint8_t)0x07U) /*!< July */ +#define RTC_AUG ((uint8_t)0x08U) /*!< August */ +#define RTC_SEP ((uint8_t)0x09U) /*!< September */ +#define RTC_OCT ((uint8_t)0x10U) /*!< October */ +#define RTC_NOV ((uint8_t)0x11U) /*!< November */ +#define RTC_DEC ((uint8_t)0x12U) /*!< December */ + +#define DATE_DOW(regval) (BITS(13,15) & ((uint32_t)(regval) << 13U)) /*!< write value to RTC_DATE_DOW bit field */ +#define GET_DATE_DOW(regval) GET_BITS((regval),13,15) /*!< get value of RTC_DATE_DOW bit field */ +#define RTC_MONDAY ((uint8_t)0x01U) /*!< Monday */ +#define RTC_TUESDAY ((uint8_t)0x02U) /*!< Tuesday */ +#define RTC_WEDSDAY ((uint8_t)0x03U) /*!< Wednesday */ +#define RTC_THURSDAY ((uint8_t)0x04U) /*!< Thursday */ +#define RTC_FRIDAY ((uint8_t)0x05U) /*!< Friday */ +#define RTC_SATURDAY ((uint8_t)0x06U) /*!< Saturday */ +#define RTC_SUNDAY ((uint8_t)0x07U) /*!< Sunday */ + +#define DATE_YR(regval) (BITS(16,23) & ((uint32_t)(regval) << 16U)) /*!< write value to RTC_DATE_YR bit field */ +#define GET_DATE_YR(regval) GET_BITS((regval),16,23) /*!< get value of RTC_DATE_YR bit field */ + +/* ctl register value */ +#define CTL_OS(regval) (BITS(21,22) & ((uint32_t)(regval) << 21U)) /*!< write value to RTC_CTL_OS bit field */ +#define RTC_OS_DISABLE CTL_OS(0) /*!< disable output RTC_ALARM */ +#define RTC_OS_ENABLE CTL_OS(1) /*!< enable alarm flag output */ + +#define RTC_CALIBRATION_512HZ RTC_CTL_COEN /*!< calibration output of 512Hz is enable */ +#define RTC_CALIBRATION_1HZ (RTC_CTL_COEN | RTC_CTL_COS) /*!< calibration output of 1Hz is enable */ +#define RTC_ALARM_HIGH RTC_CTL_OS /*!< enable alarm flag output with high level */ +#define RTC_ALARM_LOW (RTC_CTL_OS | RTC_CTL_OPOL) /*!< enable alarm flag output with low level*/ + +#define RTC_24HOUR ((uint32_t)0x00000000U) /*!< 24-hour format */ +#define RTC_12HOUR RTC_CTL_CS /*!< 12-hour format */ + +#define RTC_TIMESTAMP_RISING_EDGE ((uint32_t)0x00000000U) /*!< rising edge is valid event edge for time-stamp event */ +#define RTC_TIMESTAMP_FALLING_EDGE RTC_CTL_TSEG /*!< falling edge is valid event edge for time-stamp event */ + +/* psc register value */ +#define PSC_FACTOR_S(regval) (BITS(0,14) & ((uint32_t)(regval) << 0U)) /*!< write value to RTC_PSC_FACTOR_S bit field */ +#define GET_PSC_FACTOR_S(regval) GET_BITS((regval),0,14) /*!< get value of RTC_PSC_FACTOR_S bit field */ + +#define PSC_FACTOR_A(regval) (BITS(16,22) & ((uint32_t)(regval) << 16U)) /*!< write value to RTC_PSC_FACTOR_A bit field */ +#define GET_PSC_FACTOR_A(regval) GET_BITS((regval),16,22) /*!< get value of RTC_PSC_FACTOR_A bit field */ + +/* alrm0td register value */ +#define ALRM0TD_SC(regval) (BITS(0,6) & ((uint32_t)(regval)<< 0U)) /*!< write value to RTC_ALRM0TD_SC bit field */ +#define GET_ALRM0TD_SC(regval) GET_BITS((regval),0,6) /*!< get value of RTC_ALRM0TD_SC bit field */ + +#define ALRM0TD_MN(regval) (BITS(8,14) & ((uint32_t)(regval) << 8U)) /*!< write value to RTC_ALRM0TD_MN bit field */ +#define GET_ALRM0TD_MN(regval) GET_BITS((regval),8,14) /*!< get value of RTC_ALRM0TD_MN bit field */ + +#define ALRM0TD_HR(regval) (BITS(16,21) & ((uint32_t)(regval) << 16U)) /*!< write value to RTC_ALRM0TD_HR bit field */ +#define GET_ALRM0TD_HR(regval) GET_BITS((regval),16,21) /*!< get value of RTC_ALRM0TD_HR bit field */ + +#define ALRM0TD_DAY(regval) (BITS(24,29) & ((uint32_t)(regval) << 24U)) /*!< write value to RTC_ALRM0TD_DAY bit field */ +#define GET_ALRM0TD_DAY(regval) GET_BITS((regval),24,29) /*!< get value of RTC_ALRM0TD_DAY bit field */ + +#define RTC_ALARM_NONE_MASK ((uint32_t)0x00000000U) /*!< alarm none mask */ +#define RTC_ALARM_DATE_MASK RTC_ALRM0TD_MSKD /*!< alarm date mask */ +#define RTC_ALARM_HOUR_MASK RTC_ALRM0TD_MSKH /*!< alarm hour mask */ +#define RTC_ALARM_MINUTE_MASK RTC_ALRM0TD_MSKM /*!< alarm minute mask */ +#define RTC_ALARM_SECOND_MASK RTC_ALRM0TD_MSKS /*!< alarm second mask */ +#define RTC_ALARM_ALL_MASK (RTC_ALRM0TD_MSKD|RTC_ALRM0TD_MSKH|RTC_ALRM0TD_MSKM|RTC_ALRM0TD_MSKS) /*!< alarm all mask */ + +#define RTC_ALARM_DATE_SELECTED ((uint32_t)0x00000000U) /*!< alarm date format selected */ +#define RTC_ALARM_WEEKDAY_SELECTED RTC_ALRM0TD_DOWS /*!< alarm weekday format selected */ + +/* wpk register value */ +#define WPK_WPK(regval) (BITS(0,7) & ((uint32_t)(regval) << 0U)) /*!< write value to RTC_WPK_WPK bit field */ + +/* ss register value */ +#define SS_SSC(regval) (BITS(0,15) & ((uint32_t)(regval) << 0U)) /*!< write value to RTC_SS_SSC bit field */ + +/* shiftctl register value */ +#define SHIFTCTL_SFS(regval) (BITS(0,14) & ((uint32_t)(regval) << 0U)) /*!< write value to RTC_SHIFTCTL_SFS bit field */ + +#define RTC_SHIFT_ADD1S_RESET ((uint32_t)0x00000000U) /*!< not add 1 second */ +#define RTC_SHIFT_ADD1S_SET RTC_SHIFTCTL_A1S /*!< add one second to the clock */ + +/* tts register value */ +#define TTS_SC(regval) (BITS(0,6) & ((uint32_t)(regval) << 0U)) /*!< write value to RTC_TTS_SC bit field */ +#define GET_TTS_SC(regval) GET_BITS((regval),0,6) /*!< get value of RTC_TTS_SC bit field */ + +#define TTS_MN(regval) (BITS(8,14) & ((uint32_t)(regval) << 8U)) /*!< write value to RTC_TTS_MN bit field */ +#define GET_TTS_MN(regval) GET_BITS((regval),8,14) /*!< get value of RTC_TTS_MN bit field */ + +#define TTS_HR(regval) (BITS(16,21) & ((uint32_t)(regval) << 16U)) /*!< write value to RTC_TTS_HR bit field */ +#define GET_TTS_HR(regval) GET_BITS((regval),16,21) /*!< get value of RTC_TTS_HR bit field */ + +/* dts register value */ +#define DTS_DAY(regval) (BITS(0,5) & ((uint32_t)(regval) << 0U)) /*!< write value to RTC_DTS_DAY bit field */ +#define GET_DTS_DAY(regval) GET_BITS((regval),0,5) /*!< get value of RTC_DTS_DAY bit field */ + +#define DTS_MON(regval) (BITS(8,12) & ((uint32_t)(regval) << 8U)) /*!< write value to RTC_DTS_MON bit field */ +#define GET_DTS_MON(regval) GET_BITS((regval),8,12) /*!< get value of RTC_DTS_MON bit field */ + +#define DTS_DOW(regval) (BITS(13,15) & ((uint32_t)(regval) << 13U)) /*!< write value to RTC_DTS_DOW bit field */ +#define GET_DTS_DOW(regval) GET_BITS((regval),13,15) /*!< get value of RTC_DTS_DOW bit field */ + +/* ssts register value */ +#define SSTS_SSC(regval) (BITS(0,15) & ((uint32_t)(regval) << 0U)) /*!< write value to RTC_SSTS_SSC bit field */ + +/* hrfc register value */ +#define HRFC_CMSK(regval) (BITS(0,8) & ((uint32_t)(regval) << 0U)) /*!< write value to RTC_HRFC_CMSK bit field */ + +#define RTC_CALIBRATION_WINDOW_32S ((uint32_t)0x00000000U) /*!< 2exp20 RTCCLK cycles, 32s if RTCCLK = 32768 Hz */ +#define RTC_CALIBRATION_WINDOW_16S RTC_HRFC_CWND16 /*!< 2exp19 RTCCLK cycles, 16s if RTCCLK = 32768 Hz */ +#define RTC_CALIBRATION_WINDOW_8S RTC_HRFC_CWND8 /*!< 2exp18 RTCCLK cycles, 8s if RTCCLK = 32768 Hz */ + +#define RTC_CALIBRATION_PLUS_SET RTC_HRFC_FREQI /*!< increase RTC frequency by 488.5ppm */ +#define RTC_CALIBRATION_PLUS_RESET ((uint32_t)0x00000000U) /*!< no effect */ + +/* tamp register value */ +#define TAMP_FREQ(regval) (BITS(8,10) & ((uint32_t)(regval) << 8U)) /*!< write value to RTC_TAMP_FREQ bit field */ +#define RTC_FREQ_DIV32768 TAMP_FREQ(0) /*!< sample once every 32768 RTCCLK(1Hz if RTCCLK=32.768KHz) */ +#define RTC_FREQ_DIV16384 TAMP_FREQ(1) /*!< sample once every 16384 RTCCLK(2Hz if RTCCLK=32.768KHz) */ +#define RTC_FREQ_DIV8192 TAMP_FREQ(2) /*!< sample once every 8192 RTCCLK(4Hz if RTCCLK=32.768KHz) */ +#define RTC_FREQ_DIV4096 TAMP_FREQ(3) /*!< sample once every 4096 RTCCLK(8Hz if RTCCLK=32.768KHz) */ +#define RTC_FREQ_DIV2048 TAMP_FREQ(4) /*!< sample once every 2048 RTCCLK(16Hz if RTCCLK=32.768KHz) */ +#define RTC_FREQ_DIV1024 TAMP_FREQ(5) /*!< sample once every 1024 RTCCLK(32Hz if RTCCLK=32.768KHz) */ +#define RTC_FREQ_DIV512 TAMP_FREQ(6) /*!< sample once every 512 RTCCLK(64Hz if RTCCLK=32.768KHz) */ +#define RTC_FREQ_DIV256 TAMP_FREQ(7) /*!< sample once every 256 RTCCLK(128Hz if RTCCLK=32.768KHz) */ + +#define TAMP_FLT(regval) (BITS(11,12) & ((uint32_t)(regval) << 11U)) /*!< write value to RTC_TAMP_FLT bit field */ +#define RTC_FLT_EDGE TAMP_FLT(0) /*!< detecting tamper event using edge mode. precharge duration is disabled automatically */ +#define RTC_FLT_2S TAMP_FLT(1) /*!< detecting tamper event using level mode.2 consecutive valid level samples will make a effective tamper event */ +#define RTC_FLT_4S TAMP_FLT(2) /*!< detecting tamper event using level mode.4 consecutive valid level samples will make an effective tamper event */ +#define RTC_FLT_8S TAMP_FLT(3) /*!< detecting tamper event using level mode.8 consecutive valid level samples will make a effective tamper event */ + +#define TAMP_PRCH(regval) (BITS(13,14) & ((uint32_t)(regval) << 13U)) /*!< write value to RTC_TAMP_PRCH bit field */ +#define RTC_PRCH_1C TAMP_PRCH(0) /*!< 1 RTC clock prechagre time before each sampling */ +#define RTC_PRCH_2C TAMP_PRCH(1) /*!< 2 RTC clock prechagre time before each sampling */ +#define RTC_PRCH_4C TAMP_PRCH(2) /*!< 4 RTC clock prechagre time before each sampling */ +#define RTC_PRCH_8C TAMP_PRCH(3) /*!< 8 RTC clock prechagre time before each sampling */ + +#define RTC_TAMPER0 RTC_TAMP_TP0EN /*!< tamper 0 detection enable */ +#define RTC_TAMPER1 RTC_TAMP_TP1EN /*!< tamper 1 detection enable */ + +#define RTC_TAMPER_TRIGGER_EDGE_RISING ((uint32_t)0x00000000U) /*!< tamper detection is in rising edge mode */ +#define RTC_TAMPER_TRIGGER_EDGE_FALLING RTC_TAMP_TP0EG /*!< tamper detection is in falling edge mode */ +#define RTC_TAMPER_TRIGGER_LEVEL_LOW ((uint32_t)0x00000000U) /*!< tamper detection is in low level mode */ +#define RTC_TAMPER_TRIGGER_LEVEL_HIGH RTC_TAMP_TP0EG /*!< tamper detection is in high level mode */ + +#define RTC_TAMPER_TRIGGER_POS ((uint32_t)0x00000001U) /* shift position of trigger relative to source */ + +#define RTC_ALARM_OUTPUT_OD ((uint32_t)0x00000000U) /*!< RTC alarm output open-drain mode */ +#define RTC_ALARM_OUTPUT_PP RTC_TAMP_PC13VAL /*!< RTC alarm output push-pull mode */ + +/* alrm0ss register value */ +#define ALRM0SS_SSC(regval) (BITS(0,14) & ((uint32_t)(regval)<< 0U)) /*!< write value to RTC_ALRM0SS_SSC bit field */ + +#define ALRM0SS_MASKSSC(regval) (BITS(24,27) & ((uint32_t)(regval) << 24U)) /*!< write value to RTC_ALRM0SS_MASKSSC bit field */ +#define RTC_MASKSSC_0_14 ALRM0SS_MASKSSC(0) /*!< mask alarm subsecond configuration */ +#define RTC_MASKSSC_1_14 ALRM0SS_MASKSSC(1) /*!< mask RTC_ALRM0SS_SSC[14:1], and RTC_ALRM0SS_SSC[0] is to be compared */ +#define RTC_MASKSSC_2_14 ALRM0SS_MASKSSC(2) /*!< mask RTC_ALRM0SS_SSC[14:2], and RTC_ALRM0SS_SSC[1:0] is to be compared */ +#define RTC_MASKSSC_3_14 ALRM0SS_MASKSSC(3) /*!< mask RTC_ALRM0SS_SSC[14:3], and RTC_ALRM0SS_SSC[2:0] is to be compared */ +#define RTC_MASKSSC_4_14 ALRM0SS_MASKSSC(4) /*!< mask RTC_ALRM0SS_SSC[14:4], and RTC_ALRM0SS_SSC[3:0] is to be compared */ +#define RTC_MASKSSC_5_14 ALRM0SS_MASKSSC(5) /*!< mask RTC_ALRM0SS_SSC[14:5], and RTC_ALRM0SS_SSC[4:0] is to be compared */ +#define RTC_MASKSSC_6_14 ALRM0SS_MASKSSC(6) /*!< mask RTC_ALRM0SS_SSC[14:6], and RTC_ALRM0SS_SSC[5:0] is to be compared */ +#define RTC_MASKSSC_7_14 ALRM0SS_MASKSSC(7) /*!< mask RTC_ALRM0SS_SSC[14:7], and RTC_ALRM0SS_SSC[6:0] is to be compared */ +#define RTC_MASKSSC_8_14 ALRM0SS_MASKSSC(8) /*!< mask RTC_ALRM0SS_SSC[14:8], and RTC_ALRM0SS_SSC[7:0] is to be compared */ +#define RTC_MASKSSC_9_14 ALRM0SS_MASKSSC(9) /*!< mask RTC_ALRM0SS_SSC[14:9], and RTC_ALRM0SS_SSC[8:0] is to be compared */ +#define RTC_MASKSSC_10_14 ALRM0SS_MASKSSC(10) /*!< mask RTC_ALRM0SS_SSC[14:10], and RTC_ALRM0SS_SSC[9:0] is to be compared */ +#define RTC_MASKSSC_11_14 ALRM0SS_MASKSSC(11) /*!< mask RTC_ALRM0SS_SSC[14:11], and RTC_ALRM0SS_SSC[10:0] is to be compared */ +#define RTC_MASKSSC_12_14 ALRM0SS_MASKSSC(12) /*!< mask RTC_ALRM0SS_SSC[14:12], and RTC_ALRM0SS_SSC[11:0] is to be compared */ +#define RTC_MASKSSC_13_14 ALRM0SS_MASKSSC(13) /*!< mask RTC_ALRM0SS_SSC[14:13], and RTC_ALRM0SS_SSC[12:0] is to be compared */ +#define RTC_MASKSSC_14 ALRM0SS_MASKSSC(14) /*!< mask RTC_ALRM0SS_SSC[14], and RTC_ALRM0SS_SSC[13:0] is to be compared */ +#define RTC_MASKSSC_NONE ALRM0SS_MASKSSC(15) /*!< mask none, and RTC_ALRM0SS_SSC[14:0] is to be compared */ + +/* RTC interrupt source */ +#define RTC_INT_TIMESTAMP RTC_CTL_TSIE /*!< time-stamp interrupt enable */ +#define RTC_INT_ALARM RTC_CTL_ALRM0IE /*!< RTC alarm interrupt enable */ +#define RTC_INT_TAMP RTC_TAMP_TPIE /*!< tamper detection interrupt enable */ + +/* write protect key */ +#define RTC_UNLOCK_KEY1 ((uint8_t)0xCAU) /*!< RTC unlock key1 */ +#define RTC_UNLOCK_KEY2 ((uint8_t)0x53U) /*!< RTC unlock key2 */ +#define RTC_LOCK_KEY ((uint8_t)0xFFU) /*!< RTC lock key */ + +/* registers reset value */ +#define RTC_REGISTER_RESET ((uint32_t)0x00000000U) /*!< RTC common register reset value */ +#define RTC_DATE_RESET ((uint32_t)0x00002101U) /*!< RTC_DATE register reset value */ +#define RTC_STAT_RESET ((uint32_t)0x00000007U) /*!< RTC_STAT register reset value */ +#define RTC_PSC_RESET ((uint32_t)0x007F00FFU) /*!< RTC_PSC register reset value */ + +/* RTC timeout value */ +#define RTC_INITM_TIMEOUT ((uint32_t)0x00004000U) /*!< initialization state flag timeout */ +#define RTC_RSYNF_TIMEOUT ((uint32_t)0x00008000U) /*!< register synchronization flag timeout */ +#define RTC_HRFC_TIMEOUT ((uint32_t)0x00001000U) /*!< recalibration pending flag timeout */ +#define RTC_SHIFTCTL_TIMEOUT ((uint32_t)0x00001000U) /*!< shift function operation pending flag timeout */ +#define RTC_ALRM0WF_TIMEOUT ((uint32_t)0x00008000U) /*!< alarm configuration can be write flag timeout */ + +/* RTC flag */ +#define RTC_FLAG_RECALIBRATION RTC_STAT_SCPF /*!< recalibration pending flag */ +#define RTC_FLAG_TAMP1 RTC_STAT_TP1F /*!< tamper 1 event flag */ +#define RTC_FLAG_TAMP0 RTC_STAT_TP0F /*!< tamper 0 event flag */ +#define RTC_FLAG_TIMESTAMP_OVERFLOW RTC_STAT_TSOVRF /*!< time-stamp overflow event flag */ +#define RTC_FLAG_TIMESTAMP RTC_STAT_TSF /*!< time-stamp event flag */ +#define RTC_FLAG_ALARM0 RTC_STAT_ALRM0F /*!< alarm event flag */ +#define RTC_FLAG_INIT RTC_STAT_INITF /*!< init mode event flag */ +#define RTC_FLAG_RSYN RTC_STAT_RSYNF /*!< registers synchronized flag */ +#define RTC_FLAG_YCM RTC_STAT_YCM /*!< year parameter configured event flag */ +#define RTC_FLAG_SHIFT RTC_STAT_SOPF /*!< shift operation pending flag */ +#define RTC_FLAG_ALARM0_WRITTEN RTC_STAT_ALRM0WF /*!< alarm written available flag */ + +/* function declarations */ +/* reset most of the RTC registers */ +ErrStatus rtc_deinit(void); +/* initialize RTC registers */ +ErrStatus rtc_init(rtc_parameter_struct* rtc_initpara_struct); +/* enter RTC init mode */ +ErrStatus rtc_init_mode_enter(void); +/* exit RTC init mode */ +void rtc_init_mode_exit(void); +/* wait until RTC_TIME and RTC_DATE registers are synchronized with APB clock, and the shadow registers are updated */ +ErrStatus rtc_register_sync_wait(void); + +/* get current time and date */ +void rtc_current_time_get(rtc_parameter_struct* rtc_initpara_struct); +/* get current subsecond value */ +uint32_t rtc_subsecond_get(void); + +/* configure RTC alarm */ +void rtc_alarm_config(rtc_alarm_struct* rtc_alarm_time); +/* configure subsecond of RTC alarm */ +void rtc_alarm_subsecond_config(uint32_t mask_subsecond, uint32_t subsecond); +/* get RTC alarm */ +void rtc_alarm_get(rtc_alarm_struct* rtc_alarm_time); +/* get RTC alarm subsecond */ +uint32_t rtc_alarm_subsecond_get(void); +/* enable RTC alarm */ +void rtc_alarm_enable(void); +/* disable RTC alarm */ +ErrStatus rtc_alarm_disable(void); + +/* enable RTC time-stamp */ +void rtc_timestamp_enable(uint32_t edge); +/* disable RTC time-stamp */ +void rtc_timestamp_disable(void); +/* get RTC timestamp time and date */ +void rtc_timestamp_get(rtc_timestamp_struct* rtc_timestamp); +/* get RTC time-stamp subsecond */ +uint32_t rtc_timestamp_subsecond_get(void); + +/* enable RTC tamper */ +void rtc_tamper_enable(rtc_tamper_struct* rtc_tamper); +/* disable RTC tamper */ +void rtc_tamper_disable(uint32_t source); + +/* enable specified RTC interrupt */ +void rtc_interrupt_enable(uint32_t interrupt); +/* disble specified RTC interrupt */ +void rtc_interrupt_disable(uint32_t interrupt); +/* check specified flag */ +FlagStatus rtc_flag_get(uint32_t flag); +/* clear specified flag */ +void rtc_flag_clear(uint32_t flag); + +/* configure RTC alternate output source */ +void rtc_alter_output_config(uint32_t source, uint32_t mode); +/* configure RTC calibration register */ +ErrStatus rtc_calibration_config(uint32_t window, uint32_t plus, uint32_t minus); +/* ajust the daylight saving time by adding or substracting one hour from the current time */ +void rtc_hour_adjust(uint32_t operation); +/* ajust RTC second or subsecond value of current time */ +ErrStatus rtc_second_adjust(uint32_t add, uint32_t minus); +/* enable RTC bypass shadow registers function */ +void rtc_bypass_shadow_enable(void); +/* disable RTC bypass shadow registers function */ +void rtc_bypass_shadow_disable(void); +/* enable RTC reference clock detection function */ +ErrStatus rtc_refclock_detection_enable(void); +/* disable RTC reference clock detection function */ +ErrStatus rtc_refclock_detection_disable(void); + +#endif /* GD32E230_RTC_H */ diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_spi.h b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_spi.h new file mode 100644 index 0000000000000000000000000000000000000000..5be789ff111f9e1ed99905c646d3d5f1de34f9be --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_spi.h @@ -0,0 +1,424 @@ +/*! + \file gd32e230_spi.h + \brief definitions for the SPI + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor 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 copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 GD32E230_SPI_H +#define GD32E230_SPI_H + +#include "gd32e230.h" + +/* SPIx(x=0,1) definitions */ +#define SPI0 (SPI_BASE + 0x0000F800U) +#define SPI1 SPI_BASE + +/* SPI registers definitions */ +#define SPI_CTL0(spix) REG32((spix) + 0x00U) /*!< SPI control register 0 */ +#define SPI_CTL1(spix) REG32((spix) + 0x04U) /*!< SPI control register 1*/ +#define SPI_STAT(spix) REG32((spix) + 0x08U) /*!< SPI status register */ +#define SPI_DATA(spix) REG32((spix) + 0x0CU) /*!< SPI data register */ +#define SPI_CRCPOLY(spix) REG32((spix) + 0x10U) /*!< SPI CRC polynomial register */ +#define SPI_RCRC(spix) REG32((spix) + 0x14U) /*!< SPI receive CRC register */ +#define SPI_TCRC(spix) REG32((spix) + 0x18U) /*!< SPI transmit CRC register */ +#define SPI_I2SCTL(spix) REG32((spix) + 0x1CU) /*!< SPI I2S control register */ +#define SPI_I2SPSC(spix) REG32((spix) + 0x20U) /*!< SPI I2S clock prescaler register */ +#define SPI_QCTL(spix) REG32((spix) + 0x80U) /*!< SPI quad mode control register(only SPI1) */ + +/* bits definitions */ +/* SPI_CTL0 */ +#define SPI_CTL0_CKPH BIT(0) /*!< clock phase selection */ +#define SPI_CTL0_CKPL BIT(1) /*!< clock polarity selection */ +#define SPI_CTL0_MSTMOD BIT(2) /*!< master mode enable */ +#define SPI_CTL0_PSC BITS(3,5) /*!< master clock prescaler selection */ +#define SPI_CTL0_SPIEN BIT(6) /*!< SPI enable*/ +#define SPI_CTL0_LF BIT(7) /*!< LSB first mode */ +#define SPI_CTL0_SWNSS BIT(8) /*!< NSS pin selection in NSS software mode */ +#define SPI_CTL0_SWNSSEN BIT(9) /*!< NSS software mode selection */ +#define SPI_CTL0_RO BIT(10) /*!< receive only */ +/* only available in SPI0*/ +#define SPI_CTL0_FF16 BIT(11) /*!< data frame size */ +/* only available in SPI1*/ +#define SPI_CTL0_CRCL BIT(11) /*!< CRC length */ +#define SPI_CTL0_CRCNT BIT(12) /*!< CRC next transfer */ +#define SPI_CTL0_CRCEN BIT(13) /*!< CRC calculation enable */ +#define SPI_CTL0_BDOEN BIT(14) /*!< bidirectional transmit output enable*/ +#define SPI_CTL0_BDEN BIT(15) /*!< bidirectional enable */ + +/* SPI_CTL1 */ +#define SPI_CTL1_DMAREN BIT(0) /*!< receive buffer dma enable */ +#define SPI_CTL1_DMATEN BIT(1) /*!< transmit buffer dma enable */ +#define SPI_CTL1_NSSDRV BIT(2) /*!< drive NSS output */ +#define SPI_CTL1_NSSP BIT(3) /*!< SPI NSS pulse mode enable */ +#define SPI_CTL1_TMOD BIT(4) /*!< SPI TI mode enable */ +#define SPI_CTL1_ERRIE BIT(5) /*!< errors interrupt enable */ +#define SPI_CTL1_RBNEIE BIT(6) /*!< receive buffer not empty interrupt enable */ +#define SPI_CTL1_TBEIE BIT(7) /*!< transmit buffer empty interrupt enable */ +/* only available in SPI1 */ +#define SPI_CTL1_DZ BITS(8,11) /*!< data size */ +#define SPI_CTL1_BYTEN BIT(12) /*!< byte access to FIFO enable */ +#define SPI_CTL1_RXDMA_ODD BIT(13) /*!< odd bytes in RX DMA channel */ +#define SPI_CTL1_TXDMA_ODD BIT(14) /*!< odd bytes in TX DMA channel */ + +/* SPI_STAT */ +#define SPI_STAT_RBNE BIT(0) /*!< receive buffer not empty */ +#define SPI_STAT_TBE BIT(1) /*!< transmit buffer empty */ +#define SPI_STAT_I2SCH BIT(2) /*!< I2S channel side */ +#define SPI_STAT_TXURERR BIT(3) /*!< I2S transmission underrun error bit */ +#define SPI_STAT_CRCERR BIT(4) /*!< SPI CRC error bit */ +#define SPI_STAT_CONFERR BIT(5) /*!< SPI configuration error bit */ +#define SPI_STAT_RXORERR BIT(6) /*!< SPI reception overrun error bit */ +#define SPI_STAT_TRANS BIT(7) /*!< transmitting on-going bit */ +#define SPI_STAT_FERR BIT(8) /*!< format error bit */ +/* only available in SPI1 */ +#define SPI_STAT_RXLVL BITS(9,10) /*!< RXFIFO level */ +#define SPI_STAT_TXLVL BITS(11,12) /*!< TXFIFO level */ + +/* SPI_DATA */ +#define SPI_DATA_DATA BITS(0,15) /*!< data transfer register */ + +/* SPI_CRCPOLY */ +#define SPI_CRCPOLY_CRCPOLY BITS(0,15) /*!< CRC polynomial value */ + +/* SPI_RCRC */ +#define SPI_RCRC_RCRC BITS(0,15) /*!< RX CRC value */ + +/* SPI_TCRC */ +#define SPI_TCRC_TCRC BITS(0,15) /*!< TX CRC value */ + +/* SPI_I2SCTL */ +#define SPI_I2SCTL_CHLEN BIT(0) /*!< channel length */ +#define SPI_I2SCTL_DTLEN BITS(1,2) /*!< data length */ +#define SPI_I2SCTL_CKPL BIT(3) /*!< idle state clock polarity */ +#define SPI_I2SCTL_I2SSTD BITS(4,5) /*!< I2S standard selection */ +#define SPI_I2SCTL_PCMSMOD BIT(7) /*!< PCM frame synchronization mode */ +#define SPI_I2SCTL_I2SOPMOD BITS(8,9) /*!< I2S operation mode */ +#define SPI_I2SCTL_I2SEN BIT(10) /*!< I2S enable */ +#define SPI_I2SCTL_I2SSEL BIT(11) /*!< I2S mode selection */ + +/* SPI_I2SPSC */ +#define SPI_I2SPSC_DIV BITS(0,7) /*!< dividing factor for the prescaler */ +#define SPI_I2SPSC_OF BIT(8) /*!< odd factor for the prescaler */ +#define SPI_I2SPSC_MCKOEN BIT(9) /*!< I2S MCK output enable */ + +/* SPIx_QCTL(x=1) */ +#define SPI_QCTL_QMOD BIT(0) /*!< quad-SPI mode enable */ +#define SPI_QCTL_QRD BIT(1) /*!< quad-SPI mode read select */ +#define SPI_QCTL_IO23_DRV BIT(2) /*!< drive SPI_IO2 and SPI_IO3 enable */ + +/* constants definitions */ +/* SPIx and I2Sx parameter struct definitions */ +typedef struct +{ + uint32_t device_mode; /*!< SPI master or slave */ + uint32_t trans_mode; /*!< SPI transtype */ + uint32_t frame_size; /*!< SPI frame size */ + uint32_t nss; /*!< SPI NSS control by handware or software */ + uint32_t endian; /*!< SPI big endian or little endian */ + uint32_t clock_polarity_phase; /*!< SPI clock phase and polarity */ + uint32_t prescale; /*!< SPI prescale factor */ +}spi_parameter_struct; + +/* SPI mode definitions */ +#define SPI_MASTER (SPI_CTL0_MSTMOD | SPI_CTL0_SWNSS) /*!< SPI as master */ +#define SPI_SLAVE ((uint32_t)0x00000000U) /*!< SPI as slave */ + +/* SPI bidirectional transfer direction */ +#define SPI_BIDIRECTIONAL_TRANSMIT SPI_CTL0_BDOEN /*!< SPI work in transmit-only mode */ +#define SPI_BIDIRECTIONAL_RECEIVE (~SPI_CTL0_BDOEN) /*!< SPI work in receive-only mode */ + +/* SPI transmit type */ +#define SPI_TRANSMODE_FULLDUPLEX ((uint32_t)0x00000000U) /*!< SPI receive and send data at fullduplex communication */ +#define SPI_TRANSMODE_RECEIVEONLY SPI_CTL0_RO /*!< SPI only receive data */ +#define SPI_TRANSMODE_BDRECEIVE SPI_CTL0_BDEN /*!< bidirectional receive data */ +#define SPI_TRANSMODE_BDTRANSMIT (SPI_CTL0_BDEN | SPI_CTL0_BDOEN) /*!< bidirectional transmit data*/ + +/* SPI NSS control mode */ +#define SPI_NSS_SOFT SPI_CTL0_SWNSSEN /*!< SPI NSS control by sofrware */ +#define SPI_NSS_HARD ((uint32_t)0x00000000U) /*!< SPI NSS control by hardware */ + +/* SPI transmit way */ +#define SPI_ENDIAN_MSB ((uint32_t)0x00000000U) /*!< SPI transmit way is big endian: transmit MSB first */ +#define SPI_ENDIAN_LSB SPI_CTL0_LF /*!< SPI transmit way is little endian: transmit LSB first */ + +/* SPI clock phase and polarity */ +#define SPI_CK_PL_LOW_PH_1EDGE ((uint32_t)0x00000000U) /*!< SPI clock polarity is low level and phase is first edge */ +#define SPI_CK_PL_HIGH_PH_1EDGE SPI_CTL0_CKPL /*!< SPI clock polarity is high level and phase is first edge */ +#define SPI_CK_PL_LOW_PH_2EDGE SPI_CTL0_CKPH /*!< SPI clock polarity is low level and phase is second edge */ +#define SPI_CK_PL_HIGH_PH_2EDGE (SPI_CTL0_CKPL | SPI_CTL0_CKPH) /*!< SPI clock polarity is high level and phase is second edge */ + +/* SPI clock prescale factor */ +#define CTL0_PSC(regval) (BITS(3,5) & ((uint32_t)(regval) << 3)) +#define SPI_PSC_2 CTL0_PSC(0) /*!< SPI clock prescale factor is 2 */ +#define SPI_PSC_4 CTL0_PSC(1) /*!< SPI clock prescale factor is 4 */ +#define SPI_PSC_8 CTL0_PSC(2) /*!< SPI clock prescale factor is 8 */ +#define SPI_PSC_16 CTL0_PSC(3) /*!< SPI clock prescale factor is 16 */ +#define SPI_PSC_32 CTL0_PSC(4) /*!< SPI clock prescale factor is 32 */ +#define SPI_PSC_64 CTL0_PSC(5) /*!< SPI clock prescale factor is 64 */ +#define SPI_PSC_128 CTL0_PSC(6) /*!< SPI clock prescale factor is 128 */ +#define SPI_PSC_256 CTL0_PSC(7) /*!< SPI clock prescale factor is 256 */ + +/* SPIx frame size */ +#define CTL1_FRAMESIZE(regval) (BITS(8,11) & ((uint32_t)(regval) << 8)) +#define SPI_FRAMESIZE_4BIT CTL1_FRAMESIZE(3) /*!< SPI frame size is 4 bits */ +#define SPI_FRAMESIZE_5BIT CTL1_FRAMESIZE(4) /*!< SPI frame size is 5 bits */ +#define SPI_FRAMESIZE_6BIT CTL1_FRAMESIZE(5) /*!< SPI frame size is 6 bits */ +#define SPI_FRAMESIZE_7BIT CTL1_FRAMESIZE(6) /*!< SPI frame size is 7 bits */ +#define SPI_FRAMESIZE_8BIT CTL1_FRAMESIZE(7) /*!< SPI frame size is 8 bits */ +#define SPI_FRAMESIZE_9BIT CTL1_FRAMESIZE(8) /*!< SPI frame size is 9 bits */ +#define SPI_FRAMESIZE_10BIT CTL1_FRAMESIZE(9) /*!< SPI frame size is 10 bits */ +#define SPI_FRAMESIZE_11BIT CTL1_FRAMESIZE(10) /*!< SPI frame size is 11 bits */ +#define SPI_FRAMESIZE_12BIT CTL1_FRAMESIZE(11) /*!< SPI frame size is 12 bits */ +#define SPI_FRAMESIZE_13BIT CTL1_FRAMESIZE(12) /*!< SPI frame size is 13 bits */ +#define SPI_FRAMESIZE_14BIT CTL1_FRAMESIZE(13) /*!< SPI frame size is 14 bits */ +#define SPI_FRAMESIZE_15BIT CTL1_FRAMESIZE(14) /*!< SPI frame size is 15 bits */ +#define SPI_FRAMESIZE_16BIT CTL1_FRAMESIZE(15) /*!< SPI frame size is 16 bits */ + +/* SPIx CRC length(x=1) */ +#define SPI_CRC_8BIT ((uint32_t)0x00000000U) /*!< SPI CRC length is 8 bits */ +#define SPI_CRC_16BIT SPI_CTL0_CRCL /*!< SPI CRC length is 16 bits */ + +/* SPIx byte access enable(x=1) */ +#define SPI_HALFWORD_ACCESS ((uint32_t)0x00000000U) /*!< SPI half-word access to FIFO */ +#define SPI_BYTE_ACCESS SPI_CTL1_BYTEN /*!< SPI byte access to FIFO */ + +/* SPIx odd bytes in TX DMA channel(x=1) */ +#define SPI_TXDMA_EVEN ((uint32_t)0x00000000U) /*!< SPI number of byte in TX DMA channel is even */ +#define SPI_TXDMA_ODD SPI_CTL1_TXDMA_ODD /*!< SPI number of byte in TX DMA channel is odd */ + +/* SPIx odd bytes in RX DMA channel(x=1) */ +#define SPI_RXDMA_EVEN ((uint32_t)0x00000000U) /*!< SPI number of byte in RX DMA channel is even */ +#define SPI_RXDMA_ODD SPI_CTL1_RXDMA_ODD /*!< SPI number of byte in RX DMA channel is odd */ + +/* SPIx TXFIFO level(x=1) */ +#define CTL1_TXLVL(regval) (BITS(11,12) & ((uint32_t)(regval) << 11)) +#define SPI_TXLVL_EMPTY CTL1_RXLVL(0) /*!< SPI TXFIFO is empty */ +#define SPI_TXLVL_QUARTER_FULL CTL1_RXLVL(1) /*!< SPI TXFIFO is a quarter of full */ +#define SPI_TXLVL_HAlF_FULL CTL1_RXLVL(2) /*!< SPI TXFIFO is a half of full */ +#define SPI_TXLVL_FULL CTL1_RXLVL(3) /*!< SPI TXFIFO is full */ + +/* SPIx RXFIFO level(x=1) */ +#define CTL1_RXLVL(regval) (BITS(9,10) & ((uint32_t)(regval) << 9)) +#define SPI_RXLVL_EMPTY CTL1_RXLVL(0) /*!< SPI RXFIFO is empty */ +#define SPI_RXLVL_QUARTER_FULL CTL1_RXLVL(1) /*!< SPI RXFIFO is a quarter of full */ +#define SPI_RXLVL_HAlF_FULL CTL1_RXLVL(2) /*!< SPI RXFIFO is a half of full */ +#define SPI_RXLVL_FULL CTL1_RXLVL(3) /*!< SPI RXFIFO is full */ + +/* I2S audio sample rate */ +#define I2S_AUDIOSAMPLE_8K ((uint32_t)8000U) /*!< I2S audio sample rate is 8KHz */ +#define I2S_AUDIOSAMPLE_11K ((uint32_t)11025U) /*!< I2S audio sample rate is 11KHz */ +#define I2S_AUDIOSAMPLE_16K ((uint32_t)16000U) /*!< I2S audio sample rate is 16KHz */ +#define I2S_AUDIOSAMPLE_22K ((uint32_t)22050U) /*!< I2S audio sample rate is 22KHz */ +#define I2S_AUDIOSAMPLE_32K ((uint32_t)32000U) /*!< I2S audio sample rate is 32KHz */ +#define I2S_AUDIOSAMPLE_44K ((uint32_t)44100U) /*!< I2S audio sample rate is 44KHz */ +#define I2S_AUDIOSAMPLE_48K ((uint32_t)48000U) /*!< I2S audio sample rate is 48KHz */ +#define I2S_AUDIOSAMPLE_96K ((uint32_t)96000U) /*!< I2S audio sample rate is 96KHz */ +#define I2S_AUDIOSAMPLE_192K ((uint32_t)192000U) /*!< I2S audio sample rate is 192KHz */ + +/* I2S frame format */ +#define I2SCTL_DTLEN(regval) (BITS(1,2) & ((uint32_t)(regval) << 1)) +#define I2S_FRAMEFORMAT_DT16B_CH16B I2SCTL_DTLEN(0) /*!< I2S data length is 16 bit and channel length is 16 bit */ +#define I2S_FRAMEFORMAT_DT16B_CH32B (I2SCTL_DTLEN(0) | SPI_I2SCTL_CHLEN) /*!< I2S data length is 16 bit and channel length is 32 bit */ +#define I2S_FRAMEFORMAT_DT24B_CH32B (I2SCTL_DTLEN(1) | SPI_I2SCTL_CHLEN) /*!< I2S data length is 24 bit and channel length is 32 bit */ +#define I2S_FRAMEFORMAT_DT32B_CH32B (I2SCTL_DTLEN(2) | SPI_I2SCTL_CHLEN) /*!< I2S data length is 32 bit and channel length is 32 bit */ + +/* I2S master clock output */ +#define I2S_MCKOUT_DISABLE ((uint32_t)0x00000000U) /*!< I2S master clock output disable */ +#define I2S_MCKOUT_ENABLE SPI_I2SPSC_MCKOEN /*!< I2S master clock output enable */ + +/* I2S operation mode */ +#define I2SCTL_I2SOPMOD(regval) (BITS(8,9) & ((uint32_t)(regval) << 8)) +#define I2S_MODE_SLAVETX I2SCTL_I2SOPMOD(0) /*!< I2S slave transmit mode */ +#define I2S_MODE_SLAVERX I2SCTL_I2SOPMOD(1) /*!< I2S slave receive mode */ +#define I2S_MODE_MASTERTX I2SCTL_I2SOPMOD(2) /*!< I2S master transmit mode */ +#define I2S_MODE_MASTERRX I2SCTL_I2SOPMOD(3) /*!< I2S master receive mode */ + +/* I2S standard */ +#define I2SCTL_I2SSTD(regval) (BITS(4,5) & ((uint32_t)(regval) << 4)) +#define I2S_STD_PHILLIPS I2SCTL_I2SSTD(0) /*!< I2S phillips standard */ +#define I2S_STD_MSB I2SCTL_I2SSTD(1) /*!< I2S MSB standard */ +#define I2S_STD_LSB I2SCTL_I2SSTD(2) /*!< I2S LSB standard */ +#define I2S_STD_PCMSHORT I2SCTL_I2SSTD(3) /*!< I2S PCM short standard */ +#define I2S_STD_PCMLONG (I2SCTL_I2SSTD(3) | SPI_I2SCTL_PCMSMOD) /*!< I2S PCM long standard */ + +/* I2S clock polarity */ +#define I2S_CKPL_LOW ((uint32_t)0x00000000U) /*!< I2S clock polarity low level */ +#define I2S_CKPL_HIGH SPI_I2SCTL_CKPL /*!< I2S clock polarity high level */ + +/* SPI DMA constants definitions */ +#define SPI_DMA_TRANSMIT ((uint8_t)0x00U) /*!< SPI transmit data use DMA */ +#define SPI_DMA_RECEIVE ((uint8_t)0x01U) /*!< SPI receive data use DMA */ + +/* SPI CRC constants definitions */ +#define SPI_CRC_TX ((uint8_t)0x00U) /*!< SPI transmit CRC value */ +#define SPI_CRC_RX ((uint8_t)0x01U) /*!< SPI receive CRC value */ + +/* SPI/I2S interrupt enable/disable constants definitions */ +#define SPI_I2S_INT_TBE ((uint8_t)0x00U) /*!< transmit buffer empty interrupt */ +#define SPI_I2S_INT_RBNE ((uint8_t)0x01U) /*!< receive buffer not empty interrupt */ +#define SPI_I2S_INT_ERR ((uint8_t)0x02U) /*!< error interrupt */ + +/* SPI/I2S interrupt flag constants definitions */ +#define SPI_I2S_INT_FLAG_TBE ((uint8_t)0x00U) /*!< transmit buffer empty interrupt flag */ +#define SPI_I2S_INT_FLAG_RBNE ((uint8_t)0x01U) /*!< receive buffer not empty interrupt flag */ +#define SPI_I2S_INT_FLAG_RXORERR ((uint8_t)0x02U) /*!< overrun interrupt flag */ +#define SPI_INT_FLAG_CONFERR ((uint8_t)0x03U) /*!< config error interrupt flag */ +#define SPI_INT_FLAG_CRCERR ((uint8_t)0x04U) /*!< CRC error interrupt flag */ +#define I2S_INT_FLAG_TXURERR ((uint8_t)0x05U) /*!< underrun error interrupt flag */ +#define SPI_I2S_INT_FLAG_FERR ((uint8_t)0x06U) /*!< format error interrupt flag */ + +/* SPI/I2S flag definitions */ +#define SPI_FLAG_RBNE SPI_STAT_RBNE /*!< receive buffer not empty flag */ +#define SPI_FLAG_TBE SPI_STAT_TBE /*!< transmit buffer empty flag */ +#define SPI_FLAG_CRCERR SPI_STAT_CRCERR /*!< CRC error flag */ +#define SPI_FLAG_CONFERR SPI_STAT_CONFERR /*!< mode config error flag */ +#define SPI_FLAG_RXORERR SPI_STAT_RXORERR /*!< receive overrun error flag */ +#define SPI_FLAG_TRANS SPI_STAT_TRANS /*!< transmit on-going flag */ +#define SPI_FLAG_FERR SPI_STAT_FERR /*!< format error interrupt flag */ +#define I2S_FLAG_RBNE SPI_STAT_RBNE /*!< receive buffer not empty flag */ +#define I2S_FLAG_TBE SPI_STAT_TBE /*!< transmit buffer empty flag */ +#define I2S_FLAG_CH SPI_STAT_I2SCH /*!< channel side flag */ +#define I2S_FLAG_TXURERR SPI_STAT_TXURERR /*!< underrun error flag */ +#define I2S_FLAG_RXORERR SPI_STAT_RXORERR /*!< overrun error flag */ +#define I2S_FLAG_TRANS SPI_STAT_TRANS /*!< transmit on-going flag */ +#define I2S_FLAG_FERR SPI_STAT_FERR /*!< format error interrupt flag */ + +/* function declarations */ +/* SPI/I2S deinitialization and initialization functions */ +/* reset SPI and I2S */ +void spi_i2s_deinit(uint32_t spi_periph); +/* initialize the parameters of SPI struct with the default values */ +void spi_struct_para_init(spi_parameter_struct* spi_struct); +/* initialize SPI parameter */ +ErrStatus spi_init(uint32_t spi_periph, spi_parameter_struct* spi_struct); +/* enable SPI */ +void spi_enable(uint32_t spi_periph); +/* disable SPI */ +void spi_disable(uint32_t spi_periph); + +/* initialize I2S parameter */ +void i2s_init(uint32_t spi_periph, uint32_t mode, uint32_t standard, uint32_t ckpl); +/* configure I2S prescaler */ +void i2s_psc_config(uint32_t spi_periph, uint32_t audiosample, uint32_t frameformat, uint32_t mckout); +/* enable I2S */ +void i2s_enable(uint32_t spi_periph); +/* disable I2S */ +void i2s_disable(uint32_t spi_periph); + +/* NSS functions */ +/* enable SPI NSS output */ +void spi_nss_output_enable(uint32_t spi_periph); +/* disable SPI NSS output */ +void spi_nss_output_disable(uint32_t spi_periph); +/* SPI NSS pin high level in software mode */ +void spi_nss_internal_high(uint32_t spi_periph); +/* SPI NSS pin low level in software mode */ +void spi_nss_internal_low(uint32_t spi_periph); + +/* enable SPI DMA */ +void spi_dma_enable(uint32_t spi_periph, uint8_t dma); +/* disable SPI DMA */ +void spi_dma_disable(uint32_t spi_periph, uint8_t dma); + +/* configure SPI/I2S data frame format */ +ErrStatus spi_i2s_data_frame_format_config(uint32_t spi_periph, uint16_t frame_format); +/* SPI transmit data */ +void spi_i2s_data_transmit(uint32_t spi_periph, uint16_t data); +/* SPI receive data */ +uint16_t spi_i2s_data_receive(uint32_t spi_periph); +/* configure SPI bidirectional transfer direction */ +void spi_bidirectional_transfer_config(uint32_t spi_periph, uint32_t transfer_direction); + +/* SPI CRC functions */ +/* set SPI CRC polynomial */ +void spi_crc_polynomial_set(uint32_t spi_periph, uint16_t crc_poly); +/* get SPI CRC polynomial */ +uint16_t spi_crc_polynomial_get(uint32_t spi_periph); +/* turn on SPI CRC function */ +void spi_crc_on(uint32_t spi_periph); +/* turn off SPI CRC function */ +void spi_crc_off(uint32_t spi_periph); +/* SPI next data is CRC value */ +void spi_crc_next(uint32_t spi_periph); +/* get SPI CRC send value or receive value */ +uint16_t spi_crc_get(uint32_t spi_periph, uint8_t crc); + +/* SPI TI mode functions */ +/* enable SPI TI mode */ +void spi_ti_mode_enable(uint32_t spi_periph); +/* disable SPI TI mode */ +void spi_ti_mode_disable(uint32_t spi_periph); + +/* SPI NSS pulse mode functions */ +/* enable SPI NSS pulse mode */ +void spi_nssp_mode_enable(uint32_t spi_periph); +/* disable SPI NSS pulse mode */ +void spi_nssp_mode_disable(uint32_t spi_periph); + +/* quad wire SPI functions */ +/* enable quad wire SPI */ +void qspi_enable(uint32_t spi_periph); +/* disable quad wire SPI */ +void qspi_disable(uint32_t spi_periph); +/* enable quad wire SPI write */ +void qspi_write_enable(uint32_t spi_periph); +/* enable quad wire SPI read */ +void qspi_read_enable(uint32_t spi_periph); +/* enable quad wire SPI_IO2 and SPI_IO3 pin output */ +void qspi_io23_output_enable(uint32_t spi_periph); +/* disable quad wire SPI_IO2 and SPI_IO3 pin output */ +void qspi_io23_output_disable(uint32_t spi_periph); + +/* flag and interrupt functions */ +/* enable SPI and I2S interrupt */ +void spi_i2s_interrupt_enable(uint32_t spi_periph, uint8_t interrupt); +/* disable SPI and I2S interrupt */ +void spi_i2s_interrupt_disable(uint32_t spi_periph, uint8_t interrupt); +/* get SPI and I2S interrupt status */ +FlagStatus spi_i2s_interrupt_flag_get(uint32_t spi_periph, uint8_t interrupt); +/* get SPI and I2S flag status */ +FlagStatus spi_i2s_flag_get(uint32_t spi_periph, uint32_t flag); +/* clear SPI CRC error flag status */ +void spi_crc_error_clear(uint32_t spi_periph); + +/* only for SPI1 FIFO added */ +/* configure SPI access size to FIFO(8-bit or 16-bit) */ +void spi_fifo_access_size_config(uint32_t spi_periph, uint16_t fifo_access_size); +/* configure SPI total number of data transmitting by DMA is odd or not */ +void spi_transmit_odd_config(uint32_t spi_periph, uint16_t odd); +/* configure SPI total number of data receiving by DMA is odd or not */ +void spi_receive_odd_config(uint32_t spi_periph, uint16_t odd); +/* set CRC length */ +void spi_crc_length_set(uint32_t spi_periph, uint16_t crc_length); + +#endif /* GD32E230_SPI_H */ diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_syscfg.h b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_syscfg.h new file mode 100644 index 0000000000000000000000000000000000000000..9109a896022f6e014cdf32366595cac9890a2a60 --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_syscfg.h @@ -0,0 +1,187 @@ +/*! + \file GD32e230_syscfg.h + \brief definitions for the SYSCFG + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor 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 copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 GD32E230_SYSCFG_H +#define GD32E230_SYSCFG_H + +#include "gd32e230.h" + +/* SYSCFG definitions */ +#define SYSCFG SYSCFG_BASE + +/* registers definitions */ +#define SYSCFG_CFG0 REG32(SYSCFG + 0x00U) /*!< system configuration register 0 */ +#define SYSCFG_EXTISS0 REG32(SYSCFG + 0x08U) /*!< EXTI sources selection register 0 */ +#define SYSCFG_EXTISS1 REG32(SYSCFG + 0x0CU) /*!< EXTI sources selection register 1 */ +#define SYSCFG_EXTISS2 REG32(SYSCFG + 0x10U) /*!< EXTI sources selection register 2 */ +#define SYSCFG_EXTISS3 REG32(SYSCFG + 0x14U) /*!< EXTI sources selection register 3 */ +#define SYSCFG_CFG2 REG32(SYSCFG + 0x18U) /*!< system configuration register 2 */ +#define SYSCFG_CPU_IRQ_LAT REG32(SYSCFG + 0x100U) /*!< IRQ Latency register */ + +/* SYSCFG_CFG0 bits definitions */ +#define SYSCFG_CFG0_BOOT_MODE BITS(0,1) /*!< SYSCFG memory remap config */ +#define SYSCFG_CFG0_PA11_PA12_RMP BIT(4) /*!< PA11 and PA12 remapping bit for small packages (28 and 20 pins) */ +#define SYSCFG_CFG0_ADC_DMA_RMP BIT(8) /*!< ADC DMA remap config */ +#define SYSCFG_CFG0_USART0_TX_DMA_RMP BIT(9) /*!< USART0 Tx DMA remap config */ +#define SYSCFG_CFG0_USART0_RX_DMA_RMP BIT(10) /*!< USART0 Rx DMA remap config */ +#define SYSCFG_CFG0_TIMER15_DMA_RMP BIT(11) /*!< TIMER 15 DMA remap config */ +#define SYSCFG_CFG0_TIMER16_DMA_RMP BIT(12) /*!< TIMER 16 DMA remap config */ +#define SYSCFG_CFG0_PB9_HCCE BIT(19) /*!< PB9 pin high current capability enable */ + +/* SYSCFG_EXTISS0 bits definitions */ +#define SYSCFG_EXTISS0_EXTI0_SS BITS(0,3) /*!< EXTI 0 configuration */ +#define SYSCFG_EXTISS0_EXTI1_SS BITS(4,7) /*!< EXTI 1 configuration */ +#define SYSCFG_EXTISS0_EXTI2_SS BITS(8,11) /*!< EXTI 2 configuration */ +#define SYSCFG_EXTISS0_EXTI3_SS BITS(12,15) /*!< EXTI 3 configuration */ + +/* SYSCFG_EXTISS1 bits definitions */ +#define SYSCFG_EXTISS1_EXTI4_SS BITS(0,3) /*!< EXTI 4 configuration */ +#define SYSCFG_EXTISS1_EXTI5_SS BITS(4,7) /*!< EXTI 5 configuration */ +#define SYSCFG_EXTISS1_EXTI6_SS BITS(8,11) /*!< EXTI 6 configuration */ +#define SYSCFG_EXTISS1_EXTI7_SS BITS(12,15) /*!< EXTI 7 configuration */ + +/* SYSCFG_EXTISS2 bits definitions */ +#define SYSCFG_EXTISS2_EXTI8_SS BITS(0,3) /*!< EXTI 8 configuration */ +#define SYSCFG_EXTISS2_EXTI9_SS BITS(4,7) /*!< EXTI 9 configuration */ +#define SYSCFG_EXTISS2_EXTI10_SS BITS(8,11) /*!< EXTI 10 configuration */ +#define SYSCFG_EXTISS2_EXTI11_SS BITS(12,15) /*!< EXTI 11 configuration */ + +/* SYSCFG_EXTISS3 bits definitions */ +#define SYSCFG_EXTISS3_EXTI12_SS BITS(0,3) /*!< EXTI 12 configuration */ +#define SYSCFG_EXTISS3_EXTI13_SS BITS(4,7) /*!< EXTI 13 configuration */ +#define SYSCFG_EXTISS3_EXTI14_SS BITS(8,11) /*!< EXTI 14 configuration */ +#define SYSCFG_EXTISS3_EXTI15_SS BITS(12,15) /*!< EXTI 15 configuration */ + +/* SYSCFG_CFG2 bits definitions */ +#define SYSCFG_CFG2_LOCKUP_LOCK BIT(0) /*!< enable and lock the LOCKUP (Hardfault) output of Cortex-M23 with break input of TIMER0/14/15/16 */ +#define SYSCFG_CFG2_SRAM_PARITY_ERROR_LOCK BIT(1) /*!< enable and lock the SRAM_PARITY error signal with break input of TIMER0/14/15/16 */ +#define SYSCFG_CFG2_LVD_LOCK BIT(2) /*!< enable and lock the LVD connection with TIMER0 break input and also the LVD_EN and LVDSEL[2:0] bits of the power control interface */ +#define SYSCFG_CFG2_SRAM_PCEF BIT(8) /*!< SRAM parity check error flag */ + +/* SYSCFG_CPU_IRQ_LAT bits definitions */ +#define SYSCFG_CPU_IRQ_LAT_IRQ_LATENCY BITS(0,7) /*!< IRQ_LATENCY specifies the minimum number of cycles between an interrupt */ + +/* constants definitions */ +/* DMA remap definitions */ +#define SYSCFG_PA11_REMAP_PA12 SYSCFG_CFG0_PA11_PA12_RMP /*!< PA11 PA12 remap */ +#define SYSCFG_DMA_REMAP_ADC SYSCFG_CFG0_ADC_DMA_RMP /*!< ADC DMA remap */ +#define SYSCFG_DMA_REMAP_USART0TX SYSCFG_CFG0_USART0_TX_DMA_RMP /*!< USART0_TX DMA remap */ +#define SYSCFG_DMA_REMAP_USART0RX SYSCFG_CFG0_USART0_RX_DMA_RMP /*!< USART0_RX DMA remap */ +#define SYSCFG_DMA_REMAP_TIMER15 SYSCFG_CFG0_TIMER15_DMA_RMP /*!< TIMER15 DMA remap */ +#define SYSCFG_DMA_REMAP_TIMER16 SYSCFG_CFG0_TIMER16_DMA_RMP /*!< TIMER16 DMA remap */ + +/* high current definitions */ +#define SYSCFG_HIGH_CURRENT_ENABLE SYSCFG_CFG0_PB9_HCCE /*!< high current enable */ +#define SYSCFG_HIGH_CURRENT_DISABLE (~SYSCFG_CFG0_PB9_HCCE) /*!< high current disable */ + +/* EXTI source select definition */ +#define EXTISS0 ((uint8_t)0x00U) /*!< EXTI source select register 0 */ +#define EXTISS1 ((uint8_t)0x01U) /*!< EXTI source select register 1 */ +#define EXTISS2 ((uint8_t)0x02U) /*!< EXTI source select register 2 */ +#define EXTISS3 ((uint8_t)0x03U) /*!< EXTI source select register 3 */ + +/* EXTI source select mask bits definition */ +#define EXTI_SS_MASK BITS(0,3) /*!< EXTI source select mask */ + +/* EXTI source select jumping step definition */ +#define EXTI_SS_JSTEP ((uint8_t)(0x04U)) /*!< EXTI source select jumping step */ + +/* EXTI source select moving step definition */ +#define EXTI_SS_MSTEP(pin) (EXTI_SS_JSTEP * ((pin) % EXTI_SS_JSTEP)) /*!< EXTI source select moving step */ + +/* EXTI source port definitions */ +#define EXTI_SOURCE_GPIOA ((uint8_t)0x00U) /*!< EXTI GPIOA configuration */ +#define EXTI_SOURCE_GPIOB ((uint8_t)0x01U) /*!< EXTI GPIOB configuration */ +#define EXTI_SOURCE_GPIOC ((uint8_t)0x02U) /*!< EXTI GPIOC configuration */ +#define EXTI_SOURCE_GPIOF ((uint8_t)0x05U) /*!< EXTI GPIOF configuration */ + +/* EXTI source pin definitions */ +#define EXTI_SOURCE_PIN0 ((uint8_t)0x00U) /*!< EXTI GPIO pin0 configuration */ +#define EXTI_SOURCE_PIN1 ((uint8_t)0x01U) /*!< EXTI GPIO pin1 configuration */ +#define EXTI_SOURCE_PIN2 ((uint8_t)0x02U) /*!< EXTI GPIO pin2 configuration */ +#define EXTI_SOURCE_PIN3 ((uint8_t)0x03U) /*!< EXTI GPIO pin3 configuration */ +#define EXTI_SOURCE_PIN4 ((uint8_t)0x04U) /*!< EXTI GPIO pin4 configuration */ +#define EXTI_SOURCE_PIN5 ((uint8_t)0x05U) /*!< EXTI GPIO pin5 configuration */ +#define EXTI_SOURCE_PIN6 ((uint8_t)0x06U) /*!< EXTI GPIO pin6 configuration */ +#define EXTI_SOURCE_PIN7 ((uint8_t)0x07U) /*!< EXTI GPIO pin7 configuration */ +#define EXTI_SOURCE_PIN8 ((uint8_t)0x08U) /*!< EXTI GPIO pin8 configuration */ +#define EXTI_SOURCE_PIN9 ((uint8_t)0x09U) /*!< EXTI GPIO pin9 configuration */ +#define EXTI_SOURCE_PIN10 ((uint8_t)0x0AU) /*!< EXTI GPIO pin10 configuration */ +#define EXTI_SOURCE_PIN11 ((uint8_t)0x0BU) /*!< EXTI GPIO pin11 configuration */ +#define EXTI_SOURCE_PIN12 ((uint8_t)0x0CU) /*!< EXTI GPIO pin12 configuration */ +#define EXTI_SOURCE_PIN13 ((uint8_t)0x0DU) /*!< EXTI GPIO pin13 configuration */ +#define EXTI_SOURCE_PIN14 ((uint8_t)0x0EU) /*!< EXTI GPIO pin14 configuration */ +#define EXTI_SOURCE_PIN15 ((uint8_t)0x0FU) /*!< EXTI GPIO pin15 configuration */ + +/* lock definitions */ +#define SYSCFG_LOCK_LOCKUP SYSCFG_CFG2_LOCKUP_LOCK /*!< LOCKUP output lock */ +#define SYSCFG_LOCK_SRAM_PARITY_ERROR SYSCFG_CFG2_SRAM_PARITY_ERROR_LOCK /*!< SRAM parity error lock */ +#define SYSCFG_LOCK_LVD SYSCFG_CFG2_LVD_LOCK /*!< LVD lock */ + +/* SRAM parity check error flag definitions */ +#define SYSCFG_SRAM_PCEF SYSCFG_CFG2_SRAM_PCEF /*!< SRAM parity check error flag */ + +/* SYSCFG_CPU_IRQ_LAT register IRQ_LATENCY value */ +#define IRQ_LATENCY(regval) (BITS(0,7) & ((uint32_t)(regval) << 0U)) /*!< write value to IRQ_LATENCY bits field */ + +/* function declarations */ +/* deinit syscfg module */ +void syscfg_deinit(void); + +/* enable the DMA channels remapping */ +void syscfg_dma_remap_enable(uint32_t syscfg_dma_remap); +/* disable the DMA channels remapping */ +void syscfg_dma_remap_disable(uint32_t syscfg_dma_remap); + +/* enable PB9 high current capability */ +void syscfg_high_current_enable(void); +/* disable PB9 high current capability */ +void syscfg_high_current_disable(void); + +/* configure the GPIO pin as EXTI Line */ +void syscfg_exti_line_config(uint8_t exti_port, uint8_t exti_pin); +/* connect TIMER0/14/15/16 break input to the selected parameter */ +void syscfg_lock_config(uint32_t syscfg_lock); + +/* set the IRQ_LATENCY value */ +void irq_latency_set(uint8_t irq_latency); + +/* check if the specified flag in SYSCFG_CFG2 is set or not */ +FlagStatus syscfg_flag_get(uint32_t syscfg_flag); +/* clear the flag in SYSCFG_CFG2 by writing 1 */ +void syscfg_flag_clear(uint32_t syscfg_flag); + +#endif /* GD32E230_SYSCFG_H */ diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_timer.h b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_timer.h new file mode 100644 index 0000000000000000000000000000000000000000..c69aa8f895ef440c9a9a4d683a386cf9cb66f3ff --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_timer.h @@ -0,0 +1,760 @@ +/*! + \file gd32e230_timer.h + \brief definitions for the TIMER + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor 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 copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 GD32E230_TIMER_H +#define GD32E230_TIMER_H + +#include "gd32e230.h" + +/* TIMERx(x=0,1,2,5,13..16) definitions */ +#define TIMER0 (TIMER_BASE + 0x00012C00U) +#define TIMER2 (TIMER_BASE + 0x00000400U) +#define TIMER5 (TIMER_BASE + 0x00001000U) +#define TIMER13 (TIMER_BASE + 0x00002000U) +#define TIMER14 (TIMER_BASE + 0x00014000U) +#define TIMER15 (TIMER_BASE + 0x00014400U) +#define TIMER16 (TIMER_BASE + 0x00014800U) + +/* registers definitions */ +#define TIMER_CTL0(timerx) REG32((timerx) + 0x00U) /*!< TIMER control register 0 */ +#define TIMER_CTL1(timerx) REG32((timerx) + 0x04U) /*!< TIMER control register 1 */ +#define TIMER_SMCFG(timerx) REG32((timerx) + 0x08U) /*!< TIMER slave mode configuration register */ +#define TIMER_DMAINTEN(timerx) REG32((timerx) + 0x0CU) /*!< TIMER DMA and interrupt enable register */ +#define TIMER_INTF(timerx) REG32((timerx) + 0x10U) /*!< TIMER interrupt flag register */ +#define TIMER_SWEVG(timerx) REG32((timerx) + 0x14U) /*!< TIMER software event generation register */ +#define TIMER_CHCTL0(timerx) REG32((timerx) + 0x18U) /*!< TIMER channel control register 0 */ +#define TIMER_CHCTL1(timerx) REG32((timerx) + 0x1CU) /*!< TIMER channel control register 1 */ +#define TIMER_CHCTL2(timerx) REG32((timerx) + 0x20U) /*!< TIMER channel control register 2 */ +#define TIMER_CNT(timerx) REG32((timerx) + 0x24U) /*!< TIMER counter register */ +#define TIMER_PSC(timerx) REG32((timerx) + 0x28U) /*!< TIMER prescaler register */ +#define TIMER_CAR(timerx) REG32((timerx) + 0x2CU) /*!< TIMER counter auto reload register */ +#define TIMER_CREP(timerx) REG32((timerx) + 0x30U) /*!< TIMER counter repetition register */ +#define TIMER_CH0CV(timerx) REG32((timerx) + 0x34U) /*!< TIMER channel 0 capture/compare value register */ +#define TIMER_CH1CV(timerx) REG32((timerx) + 0x38U) /*!< TIMER channel 1 capture/compare value register */ +#define TIMER_CH2CV(timerx) REG32((timerx) + 0x3CU) /*!< TIMER channel 2 capture/compare value register */ +#define TIMER_CH3CV(timerx) REG32((timerx) + 0x40U) /*!< TIMER channel 3 capture/compare value register */ +#define TIMER_CCHP(timerx) REG32((timerx) + 0x44U) /*!< TIMER complementary channel protection register */ +#define TIMER_DMACFG(timerx) REG32((timerx) + 0x48U) /*!< TIMER DMA configuration register */ +#define TIMER_DMATB(timerx) REG32((timerx) + 0x4CU) /*!< TIMER DMA transfer buffer register */ +#define TIMER_IRMP(timerx) REG32((timerx) + 0x50U) /*!< TIMER channel input remap register */ +#define TIMER_CFG(timerx) REG32((timerx) + 0xFCU) /*!< TIMER configuration register */ + +/* bits definitions */ +/* TIMER_CTL0 */ +#define TIMER_CTL0_CEN BIT(0) /*!< TIMER counter enable */ +#define TIMER_CTL0_UPDIS BIT(1) /*!< update disable */ +#define TIMER_CTL0_UPS BIT(2) /*!< update source */ +#define TIMER_CTL0_SPM BIT(3) /*!< single pulse mode */ +#define TIMER_CTL0_DIR BIT(4) /*!< timer counter direction */ +#define TIMER_CTL0_CAM BITS(5,6) /*!< center-aligned mode selection */ +#define TIMER_CTL0_ARSE BIT(7) /*!< auto-reload shadow enable */ +#define TIMER_CTL0_CKDIV BITS(8,9) /*!< clock division */ + +/* TIMER_CTL1 */ +#define TIMER_CTL1_CCSE BIT(0) /*!< commutation control shadow enable */ +#define TIMER_CTL1_CCUC BIT(2) /*!< commutation control shadow register update control */ +#define TIMER_CTL1_DMAS BIT(3) /*!< DMA request source selection */ +#define TIMER_CTL1_MMC BITS(4,6) /*!< master mode control */ +#define TIMER_CTL1_TI0S BIT(7) /*!< channel 0 trigger input selection(hall mode selection) */ +#define TIMER_CTL1_ISO0 BIT(8) /*!< idle state of channel 0 output */ +#define TIMER_CTL1_ISO0N BIT(9) /*!< idle state of channel 0 complementary output */ +#define TIMER_CTL1_ISO1 BIT(10) /*!< idle state of channel 1 output */ +#define TIMER_CTL1_ISO1N BIT(11) /*!< idle state of channel 1 complementary output */ +#define TIMER_CTL1_ISO2 BIT(12) /*!< idle state of channel 2 output */ +#define TIMER_CTL1_ISO2N BIT(13) /*!< idle state of channel 2 complementary output */ +#define TIMER_CTL1_ISO3 BIT(14) /*!< idle state of channel 3 output */ + +/* TIMER_SMCFG */ +#define TIMER_SMCFG_SMC BITS(0,2) /*!< slave mode control */ +#define TIMER_SMCFG_OCRC BIT(3) /*!< OCPRE clear source selection */ +#define TIMER_SMCFG_TRGS BITS(4,6) /*!< trigger selection */ +#define TIMER_SMCFG_MSM BIT(7) /*!< master-slave mode */ +#define TIMER_SMCFG_ETFC BITS(8,11) /*!< external trigger filter control */ +#define TIMER_SMCFG_ETPSC BITS(12,13) /*!< external trigger prescaler */ +#define TIMER_SMCFG_SMC1 BIT(14) /*!< part of SMC for enable external clock mode 1 */ +#define TIMER_SMCFG_ETP BIT(15) /*!< external trigger polarity */ + +/* TIMER_DMAINTEN */ +#define TIMER_DMAINTEN_UPIE BIT(0) /*!< update interrupt enable */ +#define TIMER_DMAINTEN_CH0IE BIT(1) /*!< channel 0 capture/compare interrupt enable */ +#define TIMER_DMAINTEN_CH1IE BIT(2) /*!< channel 1 capture/compare interrupt enable */ +#define TIMER_DMAINTEN_CH2IE BIT(3) /*!< channel 2 capture/compare interrupt enable */ +#define TIMER_DMAINTEN_CH3IE BIT(4) /*!< channel 3 capture/compare interrupt enable */ +#define TIMER_DMAINTEN_CMTIE BIT(5) /*!< commutation interrupt request enable */ +#define TIMER_DMAINTEN_TRGIE BIT(6) /*!< trigger interrupt enable */ +#define TIMER_DMAINTEN_BRKIE BIT(7) /*!< break interrupt enable */ +#define TIMER_DMAINTEN_UPDEN BIT(8) /*!< update DMA request enable */ +#define TIMER_DMAINTEN_CH0DEN BIT(9) /*!< channel 0 DMA request enable */ +#define TIMER_DMAINTEN_CH1DEN BIT(10) /*!< channel 1 DMA request enable */ +#define TIMER_DMAINTEN_CH2DEN BIT(11) /*!< channel 2 DMA request enable */ +#define TIMER_DMAINTEN_CH3DEN BIT(12) /*!< channel 3 DMA request enable */ +#define TIMER_DMAINTEN_CMTDEN BIT(13) /*!< commutation DMA request enable */ +#define TIMER_DMAINTEN_TRGDEN BIT(14) /*!< trigger DMA request enable */ + +/* TIMER_INTF */ +#define TIMER_INTF_UPIF BIT(0) /*!< update interrupt flag */ +#define TIMER_INTF_CH0IF BIT(1) /*!< channel 0 capture/compare interrupt flag */ +#define TIMER_INTF_CH1IF BIT(2) /*!< channel 1 capture/compare interrupt flag */ +#define TIMER_INTF_CH2IF BIT(3) /*!< channel 2 capture/compare interrupt flag */ +#define TIMER_INTF_CH3IF BIT(4) /*!< channel 3 capture/compare interrupt flag */ +#define TIMER_INTF_CMTIF BIT(5) /*!< channel commutation interrupt flag */ +#define TIMER_INTF_TRGIF BIT(6) /*!< trigger interrupt flag */ +#define TIMER_INTF_BRKIF BIT(7) /*!< break interrupt flag */ +#define TIMER_INTF_CH0OF BIT(9) /*!< channel 0 overcapture flag */ +#define TIMER_INTF_CH1OF BIT(10) /*!< channel 1 overcapture flag */ +#define TIMER_INTF_CH2OF BIT(11) /*!< channel 2 overcapture flag */ +#define TIMER_INTF_CH3OF BIT(12) /*!< channel 3 overcapture flag */ + +/* TIMER_SWEVG */ +#define TIMER_SWEVG_UPG BIT(0) /*!< update event generate */ +#define TIMER_SWEVG_CH0G BIT(1) /*!< channel 0 capture or compare event generation */ +#define TIMER_SWEVG_CH1G BIT(2) /*!< channel 1 capture or compare event generation */ +#define TIMER_SWEVG_CH2G BIT(3) /*!< channel 2 capture or compare event generation */ +#define TIMER_SWEVG_CH3G BIT(4) /*!< channel 3 capture or compare event generation */ +#define TIMER_SWEVG_CMTG BIT(5) /*!< channel commutation event generation */ +#define TIMER_SWEVG_TRGG BIT(6) /*!< trigger event generation */ +#define TIMER_SWEVG_BRKG BIT(7) /*!< break event generation */ + +/* TIMER_CHCTL0 */ +/* output compare mode */ +#define TIMER_CHCTL0_CH0MS BITS(0,1) /*!< channel 0 mode selection */ +#define TIMER_CHCTL0_CH0COMFEN BIT(2) /*!< channel 0 output compare fast enable */ +#define TIMER_CHCTL0_CH0COMSEN BIT(3) /*!< channel 0 output compare shadow enable */ +#define TIMER_CHCTL0_CH0COMCTL BITS(4,6) /*!< channel 0 output compare mode */ +#define TIMER_CHCTL0_CH0COMCEN BIT(7) /*!< channel 0 output compare clear enable */ +#define TIMER_CHCTL0_CH1MS BITS(8,9) /*!< channel 1 mode selection */ +#define TIMER_CHCTL0_CH1COMFEN BIT(10) /*!< channel 1 output compare fast enable */ +#define TIMER_CHCTL0_CH1COMSEN BIT(11) /*!< channel 1 output compare shadow enable */ +#define TIMER_CHCTL0_CH1COMCTL BITS(12,14) /*!< channel 1 output compare mode */ +#define TIMER_CHCTL0_CH1COMCEN BIT(15) /*!< channel 1 output compare clear enable */ +/* input capture mode */ +#define TIMER_CHCTL0_CH0CAPPSC BITS(2,3) /*!< channel 0 input capture prescaler */ +#define TIMER_CHCTL0_CH0CAPFLT BITS(4,7) /*!< channel 0 input capture filter control */ +#define TIMER_CHCTL0_CH1CAPPSC BITS(10,11) /*!< channel 1 input capture prescaler */ +#define TIMER_CHCTL0_CH1CAPFLT BITS(12,15) /*!< channel 1 input capture filter control */ + +/* TIMER_CHCTL1 */ +/* output compare mode */ +#define TIMER_CHCTL1_CH2MS BITS(0,1) /*!< channel 2 mode selection */ +#define TIMER_CHCTL1_CH2COMFEN BIT(2) /*!< channel 2 output compare fast enable */ +#define TIMER_CHCTL1_CH2COMSEN BIT(3) /*!< channel 2 output compare shadow enable */ +#define TIMER_CHCTL1_CH2COMCTL BITS(4,6) /*!< channel 2 output compare mode */ +#define TIMER_CHCTL1_CH2COMCEN BIT(7) /*!< channel 2 output compare clear enable */ +#define TIMER_CHCTL1_CH3MS BITS(8,9) /*!< channel 3 mode selection */ +#define TIMER_CHCTL1_CH3COMFEN BIT(10) /*!< channel 3 output compare fast enable */ +#define TIMER_CHCTL1_CH3COMSEN BIT(11) /*!< channel 3 output compare shadow enable */ +#define TIMER_CHCTL1_CH3COMCTL BITS(12,14) /*!< channel 3 output compare mode */ +#define TIMER_CHCTL1_CH3COMCEN BIT(15) /*!< channel 3 output compare clear enable */ +/* input capture mode */ +#define TIMER_CHCTL1_CH2CAPPSC BITS(2,3) /*!< channel 2 input capture prescaler */ +#define TIMER_CHCTL1_CH2CAPFLT BITS(4,7) /*!< channel 2 input capture filter control */ +#define TIMER_CHCTL1_CH3CAPPSC BITS(10,11) /*!< channel 3 input capture prescaler */ +#define TIMER_CHCTL1_CH3CAPFLT BITS(12,15) /*!< channel 3 input capture filter control */ + +/* TIMER_CHCTL2 */ +#define TIMER_CHCTL2_CH0EN BIT(0) /*!< channel 0 capture/compare function enable */ +#define TIMER_CHCTL2_CH0P BIT(1) /*!< channel 0 capture/compare function polarity */ +#define TIMER_CHCTL2_CH0NEN BIT(2) /*!< channel 0 complementary output enable */ +#define TIMER_CHCTL2_CH0NP BIT(3) /*!< channel 0 complementary output polarity */ +#define TIMER_CHCTL2_CH1EN BIT(4) /*!< channel 1 capture/compare function enable */ +#define TIMER_CHCTL2_CH1P BIT(5) /*!< channel 1 capture/compare function polarity */ +#define TIMER_CHCTL2_CH1NEN BIT(6) /*!< channel 1 complementary output enable */ +#define TIMER_CHCTL2_CH1NP BIT(7) /*!< channel 1 complementary output polarity */ +#define TIMER_CHCTL2_CH2EN BIT(8) /*!< channel 2 capture/compare function enable */ +#define TIMER_CHCTL2_CH2P BIT(9) /*!< channel 2 capture/compare function polarity */ +#define TIMER_CHCTL2_CH2NEN BIT(10) /*!< channel 2 complementary output enable */ +#define TIMER_CHCTL2_CH2NP BIT(11) /*!< channel 2 complementary output polarity */ +#define TIMER_CHCTL2_CH3EN BIT(12) /*!< channel 3 capture/compare function enable */ +#define TIMER_CHCTL2_CH3P BIT(13) /*!< channel 3 capture/compare function polarity */ +#define TIMER_CHCTL2_CH3NP BIT(15) /*!< channel 3 complementary output polarity */ + +/* TIMER_CNT */ +#define TIMER_CNT_CNT16 BITS(0,15) /*!< 16 bit timer counter */ + +/* TIMER_PSC */ +#define TIMER_PSC_PSC BITS(0,15) /*!< prescaler value of the counter clock */ + +/* TIMER_CAR */ +#define TIMER_CAR_CARL16 BITS(0,15) /*!< 16 bit counter auto reload value */ + +/* TIMER_CREP */ +#define TIMER_CREP_CREP BITS(0,7) /*!< counter repetition value */ + +/* TIMER_CH0CV */ +#define TIMER_CH0CV_CH0VAL16 BITS(0,15) /*!< 16 bit capture/compare value of channel 0 */ + +/* TIMER_CH1CV */ +#define TIMER_CH1CV_CH1VAL16 BITS(0,15) /*!< 16 bit capture/compare value of channel 1 */ + +/* TIMER_CH2CV */ +#define TIMER_CH2CV_CH2VAL16 BITS(0,15) /*!< 16 bit capture/compare value of channel 2 */ + +/* TIMER_CH3CV */ +#define TIMER_CH3CV_CH3VAL16 BITS(0,15) /*!< 16 bit capture/compare value of channel 3 */ + +/* TIMER_CCHP */ +#define TIMER_CCHP_DTCFG BITS(0,7) /*!< dead time configure */ +#define TIMER_CCHP_PROT BITS(8,9) /*!< complementary register protect control */ +#define TIMER_CCHP_IOS BIT(10) /*!< idle mode off-state configure */ +#define TIMER_CCHP_ROS BIT(11) /*!< run mode off-state configure */ +#define TIMER_CCHP_BRKEN BIT(12) /*!< break enable */ +#define TIMER_CCHP_BRKP BIT(13) /*!< break polarity */ +#define TIMER_CCHP_OAEN BIT(14) /*!< output automatic enable */ +#define TIMER_CCHP_POEN BIT(15) /*!< primary output enable */ + +/* TIMER_DMACFG */ +#define TIMER_DMACFG_DMATA BITS(0,4) /*!< DMA transfer access start address */ +#define TIMER_DMACFG_DMATC BITS(8,12) /*!< DMA transfer count */ + +/* TIMER_DMATB */ +#define TIMER_DMATB_DMATB BITS(0,15) /*!< DMA transfer buffer address */ + +/* TIMER_IRMP */ +#define TIMER13_IRMP_CI0_RMP BITS(0,1) /*!< TIMER13 channel 0 input remap */ + +/* TIMER_CFG */ +#define TIMER_CFG_OUTSEL BIT(0) /*!< the output value selection */ +#define TIMER_CFG_CHVSEL BIT(1) /*!< write CHxVAL register selection */ + +/* constants definitions */ +/* TIMER init parameter struct definitions*/ +typedef struct +{ + uint16_t prescaler; /*!< prescaler value */ + uint16_t alignedmode; /*!< aligned mode */ + uint16_t counterdirection; /*!< counter direction */ + uint16_t clockdivision; /*!< clock division value */ + uint32_t period; /*!< period value */ + uint8_t repetitioncounter; /*!< the counter repetition value */ +}timer_parameter_struct; + +/* break parameter struct definitions*/ +typedef struct +{ + uint16_t runoffstate; /*!< run mode off-state */ + uint16_t ideloffstate; /*!< idle mode off-state */ + uint16_t deadtime; /*!< dead time */ + uint16_t breakpolarity; /*!< break polarity */ + uint16_t outputautostate; /*!< output automatic enable */ + uint16_t protectmode; /*!< complementary register protect control */ + uint16_t breakstate; /*!< break enable */ +}timer_break_parameter_struct; + +/* channel output parameter struct definitions */ +typedef struct +{ + uint16_t outputstate; /*!< channel output state */ + uint16_t outputnstate; /*!< channel complementary output state */ + uint16_t ocpolarity; /*!< channel output polarity */ + uint16_t ocnpolarity; /*!< channel complementary output polarity */ + uint16_t ocidlestate; /*!< idle state of channel output */ + uint16_t ocnidlestate; /*!< idle state of channel complementary output */ +}timer_oc_parameter_struct; + +/* channel input parameter struct definitions */ +typedef struct +{ + uint16_t icpolarity; /*!< channel input polarity */ + uint16_t icselection; /*!< channel input mode selection */ + uint16_t icprescaler; /*!< channel input capture prescaler */ + uint16_t icfilter; /*!< channel input capture filter control */ +}timer_ic_parameter_struct; + +/* TIMER interrupt enable or disable */ +#define TIMER_INT_UP TIMER_DMAINTEN_UPIE /*!< update interrupt */ +#define TIMER_INT_CH0 TIMER_DMAINTEN_CH0IE /*!< channel 0 interrupt */ +#define TIMER_INT_CH1 TIMER_DMAINTEN_CH1IE /*!< channel 1 interrupt */ +#define TIMER_INT_CH2 TIMER_DMAINTEN_CH2IE /*!< channel 2 interrupt */ +#define TIMER_INT_CH3 TIMER_DMAINTEN_CH3IE /*!< channel 3 interrupt */ +#define TIMER_INT_CMT TIMER_DMAINTEN_CMTIE /*!< channel commutation interrupt flag */ +#define TIMER_INT_TRG TIMER_DMAINTEN_TRGIE /*!< trigger interrupt */ +#define TIMER_INT_BRK TIMER_DMAINTEN_BRKIE /*!< break interrupt */ + +/* TIMER flag */ +#define TIMER_FLAG_UP TIMER_INTF_UPIF /*!< update flag */ +#define TIMER_FLAG_CH0 TIMER_INTF_CH0IF /*!< channel 0 flag */ +#define TIMER_FLAG_CH1 TIMER_INTF_CH1IF /*!< channel 1 flag */ +#define TIMER_FLAG_CH2 TIMER_INTF_CH2IF /*!< channel 2 flag */ +#define TIMER_FLAG_CH3 TIMER_INTF_CH3IF /*!< channel 3 flag */ +#define TIMER_FLAG_CMT TIMER_INTF_CMTIF /*!< channel commutation flag */ +#define TIMER_FLAG_TRG TIMER_INTF_TRGIF /*!< trigger flag */ +#define TIMER_FLAG_BRK TIMER_INTF_BRKIF /*!< break flag */ +#define TIMER_FLAG_CH0O TIMER_INTF_CH0OF /*!< channel 0 overcapture flag */ +#define TIMER_FLAG_CH1O TIMER_INTF_CH1OF /*!< channel 1 overcapture flag */ +#define TIMER_FLAG_CH2O TIMER_INTF_CH2OF /*!< channel 2 overcapture flag */ +#define TIMER_FLAG_CH3O TIMER_INTF_CH3OF /*!< channel 3 overcapture flag */ + +/* TIMER interrupt flag */ +#define TIMER_INT_FLAG_UP TIMER_INTF_UPIF /*!< update interrupt flag */ +#define TIMER_INT_FLAG_CH0 TIMER_INTF_CH0IF /*!< channel 0 interrupt flag */ +#define TIMER_INT_FLAG_CH1 TIMER_INTF_CH1IF /*!< channel 1 interrupt flag */ +#define TIMER_INT_FLAG_CH2 TIMER_INTF_CH2IF /*!< channel 2 interrupt flag */ +#define TIMER_INT_FLAG_CH3 TIMER_INTF_CH3IF /*!< channel 3 interrupt flag */ +#define TIMER_INT_FLAG_CMT TIMER_INTF_CMTIF /*!< channel commutation interrupt flag */ +#define TIMER_INT_FLAG_TRG TIMER_INTF_TRGIF /*!< trigger interrupt flag */ +#define TIMER_INT_FLAG_BRK TIMER_INTF_BRKIF + +/* TIMER DMA source enable */ +#define TIMER_DMA_UPD ((uint16_t)TIMER_DMAINTEN_UPDEN) /*!< update DMA enable */ +#define TIMER_DMA_CH0D ((uint16_t)TIMER_DMAINTEN_CH0DEN) /*!< channel 0 DMA enable */ +#define TIMER_DMA_CH1D ((uint16_t)TIMER_DMAINTEN_CH1DEN) /*!< channel 1 DMA enable */ +#define TIMER_DMA_CH2D ((uint16_t)TIMER_DMAINTEN_CH2DEN) /*!< channel 2 DMA enable */ +#define TIMER_DMA_CH3D ((uint16_t)TIMER_DMAINTEN_CH3DEN) /*!< channel 3 DMA enable */ +#define TIMER_DMA_CMTD ((uint16_t)TIMER_DMAINTEN_CMTDEN) /*!< commutation DMA request enable */ +#define TIMER_DMA_TRGD ((uint16_t)TIMER_DMAINTEN_TRGDEN) /*!< trigger DMA enable */ + +/* channel DMA request source selection */ +#define TIMER_DMAREQUEST_UPDATEEVENT TIMER_CTL1_DMAS /*!< DMA request of channel y is sent when update event occurs */ +#define TIMER_DMAREQUEST_CHANNELEVENT ((uint32_t)0x00000000U) /*!< DMA request of channel y is sent when channel y event occurs */ + +/* DMA access base address */ +#define DMACFG_DMATA(regval) (BITS(0, 4) & ((uint32_t)(regval) << 0U)) +#define TIMER_DMACFG_DMATA_CTL0 DMACFG_DMATA(0) /*!< DMA transfer address is TIMER_CTL0 */ +#define TIMER_DMACFG_DMATA_CTL1 DMACFG_DMATA(1) /*!< DMA transfer address is TIMER_CTL1 */ +#define TIMER_DMACFG_DMATA_SMCFG DMACFG_DMATA(2) /*!< DMA transfer address is TIMER_SMCFG */ +#define TIMER_DMACFG_DMATA_DMAINTEN DMACFG_DMATA(3) /*!< DMA transfer address is TIMER_DMAINTEN */ +#define TIMER_DMACFG_DMATA_INTF DMACFG_DMATA(4) /*!< DMA transfer address is TIMER_INTF */ +#define TIMER_DMACFG_DMATA_SWEVG DMACFG_DMATA(5) /*!< DMA transfer address is TIMER_SWEVG */ +#define TIMER_DMACFG_DMATA_CHCTL0 DMACFG_DMATA(6) /*!< DMA transfer address is TIMER_CHCTL0 */ +#define TIMER_DMACFG_DMATA_CHCTL1 DMACFG_DMATA(7) /*!< DMA transfer address is TIMER_CHCTL1 */ +#define TIMER_DMACFG_DMATA_CHCTL2 DMACFG_DMATA(8) /*!< DMA transfer address is TIMER_CHCTL2 */ +#define TIMER_DMACFG_DMATA_CNT DMACFG_DMATA(9) /*!< DMA transfer address is TIMER_CNT */ +#define TIMER_DMACFG_DMATA_PSC DMACFG_DMATA(10) /*!< DMA transfer address is TIMER_PSC */ +#define TIMER_DMACFG_DMATA_CAR DMACFG_DMATA(11) /*!< DMA transfer address is TIMER_CAR */ +#define TIMER_DMACFG_DMATA_CREP DMACFG_DMATA(12) /*!< DMA transfer address is TIMER_CREP */ +#define TIMER_DMACFG_DMATA_CH0CV DMACFG_DMATA(13) /*!< DMA transfer address is TIMER_CH0CV */ +#define TIMER_DMACFG_DMATA_CH1CV DMACFG_DMATA(14) /*!< DMA transfer address is TIMER_CH1CV */ +#define TIMER_DMACFG_DMATA_CH2CV DMACFG_DMATA(15) /*!< DMA transfer address is TIMER_CH2CV */ +#define TIMER_DMACFG_DMATA_CH3CV DMACFG_DMATA(16) /*!< DMA transfer address is TIMER_CH3CV */ +#define TIMER_DMACFG_DMATA_CCHP DMACFG_DMATA(17) /*!< DMA transfer address is TIMER_CCHP */ +#define TIMER_DMACFG_DMATA_DMACFG DMACFG_DMATA(18) /*!< DMA transfer address is TIMER_DMACFG */ + +/* DMA access burst length */ +#define DMACFG_DMATC(regval) (BITS(8, 12) & ((uint32_t)(regval) << 8U)) +#define TIMER_DMACFG_DMATC_1TRANSFER DMACFG_DMATC(0) /*!< DMA transfer 1 time */ +#define TIMER_DMACFG_DMATC_2TRANSFER DMACFG_DMATC(1) /*!< DMA transfer 2 times */ +#define TIMER_DMACFG_DMATC_3TRANSFER DMACFG_DMATC(2) /*!< DMA transfer 3 times */ +#define TIMER_DMACFG_DMATC_4TRANSFER DMACFG_DMATC(3) /*!< DMA transfer 4 times */ +#define TIMER_DMACFG_DMATC_5TRANSFER DMACFG_DMATC(4) /*!< DMA transfer 5 times */ +#define TIMER_DMACFG_DMATC_6TRANSFER DMACFG_DMATC(5) /*!< DMA transfer 6 times */ +#define TIMER_DMACFG_DMATC_7TRANSFER DMACFG_DMATC(6) /*!< DMA transfer 7 times */ +#define TIMER_DMACFG_DMATC_8TRANSFER DMACFG_DMATC(7) /*!< DMA transfer 8 times */ +#define TIMER_DMACFG_DMATC_9TRANSFER DMACFG_DMATC(8) /*!< DMA transfer 9 times */ +#define TIMER_DMACFG_DMATC_10TRANSFER DMACFG_DMATC(9) /*!< DMA transfer 10 times */ +#define TIMER_DMACFG_DMATC_11TRANSFER DMACFG_DMATC(10) /*!< DMA transfer 11 times */ +#define TIMER_DMACFG_DMATC_12TRANSFER DMACFG_DMATC(11) /*!< DMA transfer 12 times */ +#define TIMER_DMACFG_DMATC_13TRANSFER DMACFG_DMATC(12) /*!< DMA transfer 13 times */ +#define TIMER_DMACFG_DMATC_14TRANSFER DMACFG_DMATC(13) /*!< DMA transfer 14 times */ +#define TIMER_DMACFG_DMATC_15TRANSFER DMACFG_DMATC(14) /*!< DMA transfer 15 times */ +#define TIMER_DMACFG_DMATC_16TRANSFER DMACFG_DMATC(15) /*!< DMA transfer 16 times */ +#define TIMER_DMACFG_DMATC_17TRANSFER DMACFG_DMATC(16) /*!< DMA transfer 17 times */ +#define TIMER_DMACFG_DMATC_18TRANSFER DMACFG_DMATC(17) /*!< DMA transfer 18 times */ + +/* TIMER software event generation source */ +#define TIMER_EVENT_SRC_UPG ((uint16_t)0x0001U) /*!< update event generation */ +#define TIMER_EVENT_SRC_CH0G ((uint16_t)0x0002U) /*!< channel 0 capture or compare event generation */ +#define TIMER_EVENT_SRC_CH1G ((uint16_t)0x0004U) /*!< channel 1 capture or compare event generation */ +#define TIMER_EVENT_SRC_CH2G ((uint16_t)0x0008U) /*!< channel 2 capture or compare event generation */ +#define TIMER_EVENT_SRC_CH3G ((uint16_t)0x0010U) /*!< channel 3 capture or compare event generation */ +#define TIMER_EVENT_SRC_CMTG ((uint16_t)0x0020U) /*!< channel commutation event generation */ +#define TIMER_EVENT_SRC_TRGG ((uint16_t)0x0040U) /*!< trigger event generation */ +#define TIMER_EVENT_SRC_BRKG ((uint16_t)0x0080U) /*!< break event generation */ + +/* center-aligned mode selection */ +#define CTL0_CAM(regval) ((uint16_t)(BITS(5, 6) & ((uint32_t)(regval) << 5U))) +#define TIMER_COUNTER_EDGE CTL0_CAM(0) /*!< edge-aligned mode */ +#define TIMER_COUNTER_CENTER_DOWN CTL0_CAM(1) /*!< center-aligned and counting down assert mode */ +#define TIMER_COUNTER_CENTER_UP CTL0_CAM(2) /*!< center-aligned and counting up assert mode */ +#define TIMER_COUNTER_CENTER_BOTH CTL0_CAM(3) /*!< center-aligned and counting up/down assert mode */ + +/* TIMER prescaler reload mode */ +#define TIMER_PSC_RELOAD_NOW TIMER_SWEVG_UPG /*!< the prescaler is loaded right now */ +#define TIMER_PSC_RELOAD_UPDATE ((uint32_t)0x00000000U) /*!< the prescaler is loaded at the next update event */ + +/* count direction */ +#define TIMER_COUNTER_UP ((uint16_t)0x0000U) /*!< counter up direction */ +#define TIMER_COUNTER_DOWN ((uint16_t)TIMER_CTL0_DIR) /*!< counter down direction */ + +/* specify division ratio between TIMER clock and dead-time and sampling clock */ +#define CTL0_CKDIV(regval) ((uint16_t)(BITS(8, 9) & ((uint32_t)(regval) << 8U))) +#define TIMER_CKDIV_DIV1 CTL0_CKDIV(0) /*!< clock division value is 1, fDTS=fTIMER_CK */ +#define TIMER_CKDIV_DIV2 CTL0_CKDIV(1) /*!< clock division value is 2, fDTS= fTIMER_CK/2 */ +#define TIMER_CKDIV_DIV4 CTL0_CKDIV(2) /*!< clock division value is 4, fDTS= fTIMER_CK/4 */ + +/* single pulse mode */ +#define TIMER_SP_MODE_SINGLE TIMER_CTL0_SPM /*!< single pulse mode */ +#define TIMER_SP_MODE_REPETITIVE ((uint32_t)0x00000000U) /*!< repetitive pulse mode */ + +/* update source */ +#define TIMER_UPDATE_SRC_REGULAR TIMER_CTL0_UPS /*!< update generate only by counter overflow/underflow */ +#define TIMER_UPDATE_SRC_GLOBAL ((uint32_t)0x00000000U) /*!< update generate by setting of UPG bit or the counter overflow/underflow,or the slave mode controller trigger */ + +/* run mode off-state configure */ +#define TIMER_ROS_STATE_ENABLE ((uint16_t)TIMER_CCHP_ROS) /*!< when POEN bit is set, the channel output signals (CHx_O/CHx_ON) are enabled, with relationship to CHxEN/CHxNEN bits */ +#define TIMER_ROS_STATE_DISABLE ((uint16_t)0x0000U) /*!< when POEN bit is set, the channel output signals (CHx_O/CHx_ON) are disabled */ + +/* idle mode off-state configure */ +#define TIMER_IOS_STATE_ENABLE ((uint16_t)TIMER_CCHP_IOS) /*!< when POEN bit is reset, he channel output signals (CHx_O/CHx_ON) are enabled, with relationship to CHxEN/CHxNEN bits */ +#define TIMER_IOS_STATE_DISABLE ((uint16_t)0x0000U) /*!< when POEN bit is reset, the channel output signals (CHx_O/CHx_ON) are disabled */ + +/* break input polarity */ +#define TIMER_BREAK_POLARITY_LOW ((uint16_t)0x0000U) /*!< break input polarity is low */ +#define TIMER_BREAK_POLARITY_HIGH ((uint16_t)TIMER_CCHP_BRKP) /*!< break input polarity is high */ + +/* output automatic enable */ +#define TIMER_OUTAUTO_ENABLE ((uint16_t)TIMER_CCHP_OAEN) /*!< output automatic enable */ +#define TIMER_OUTAUTO_DISABLE ((uint16_t)0x0000U) /*!< output automatic disable */ + +/* complementary register protect control */ +#define CCHP_PROT(regval) ((uint16_t)(BITS(8, 9) & ((uint32_t)(regval) << 8U))) +#define TIMER_CCHP_PROT_OFF CCHP_PROT(0) /*!< protect disable */ +#define TIMER_CCHP_PROT_0 CCHP_PROT(1) /*!< PROT mode 0 */ +#define TIMER_CCHP_PROT_1 CCHP_PROT(2) /*!< PROT mode 1 */ +#define TIMER_CCHP_PROT_2 CCHP_PROT(3) /*!< PROT mode 2 */ + +/* break input enable */ +#define TIMER_BREAK_ENABLE ((uint16_t)TIMER_CCHP_BRKEN) /*!< break input enable */ +#define TIMER_BREAK_DISABLE ((uint16_t)0x0000U) /*!< break input disable */ + +/* TIMER channel n(n=0,1,2,3) */ +#define TIMER_CH_0 ((uint16_t)0x0000U) /*!< TIMER channel 0(TIMERx(x=0,2,13..16)) */ +#define TIMER_CH_1 ((uint16_t)0x0001U) /*!< TIMER channel 1(TIMERx(x=0,2,14)) */ +#define TIMER_CH_2 ((uint16_t)0x0002U) /*!< TIMER channel 2(TIMERx(x=0,2)) */ +#define TIMER_CH_3 ((uint16_t)0x0003U) /*!< TIMER channel 3(TIMERx(x=0,2)) */ +#define TIMER_CH_0_1 ((uint16_t)0x0004U) /*!< TIMER channel 0 and 1 for function parameter */ + +/* channel enable state*/ +#define TIMER_CCX_ENABLE ((uint32_t)0x00000001U) /*!< channel enable */ +#define TIMER_CCX_DISABLE ((uint32_t)0x00000000U) /*!< channel disable */ + +/* channel complementary output enable state*/ +#define TIMER_CCXN_ENABLE ((uint16_t)0x0004U) /*!< channel complementary enable */ +#define TIMER_CCXN_DISABLE ((uint16_t)0x0000U) /*!< channel complementary disable */ + +/* channel output polarity */ +#define TIMER_OC_POLARITY_HIGH ((uint16_t)0x0000U) /*!< channel output polarity is high */ +#define TIMER_OC_POLARITY_LOW ((uint16_t)0x0002U) /*!< channel output polarity is low */ + +/* channel complementary output polarity */ +#define TIMER_OCN_POLARITY_HIGH ((uint16_t)0x0000U) /*!< channel complementary output polarity is high */ +#define TIMER_OCN_POLARITY_LOW ((uint16_t)0x0008U) /*!< channel complementary output polarity is low */ + +/* idle state of channel output */ +#define TIMER_OC_IDLE_STATE_HIGH ((uint16_t)0x0100) /*!< idle state of channel output is high */ +#define TIMER_OC_IDLE_STATE_LOW ((uint16_t)0x0000) /*!< idle state of channel output is low */ + +/* idle state of channel complementary output */ +#define TIMER_OCN_IDLE_STATE_HIGH ((uint16_t)0x0200U) /*!< idle state of channel complementary output is high */ +#define TIMER_OCN_IDLE_STATE_LOW ((uint16_t)0x0000U) /*!< idle state of channel complementary output is low */ + +/* channel output compare mode */ +#define TIMER_OC_MODE_TIMING ((uint16_t)0x0000U) /*!< timing mode */ +#define TIMER_OC_MODE_ACTIVE ((uint16_t)0x0010U) /*!< active mode */ +#define TIMER_OC_MODE_INACTIVE ((uint16_t)0x0020U) /*!< inactive mode */ +#define TIMER_OC_MODE_TOGGLE ((uint16_t)0x0030U) /*!< toggle mode */ +#define TIMER_OC_MODE_LOW ((uint16_t)0x0040U) /*!< force low mode */ +#define TIMER_OC_MODE_HIGH ((uint16_t)0x0050U) /*!< force high mode */ +#define TIMER_OC_MODE_PWM0 ((uint16_t)0x0060U) /*!< PWM0 mode */ +#define TIMER_OC_MODE_PWM1 ((uint16_t)0x0070U) /*!< PWM1 mode*/ + +/* channel output compare shadow enable */ +#define TIMER_OC_SHADOW_ENABLE ((uint16_t)0x0008U) /*!< channel output shadow state enable */ +#define TIMER_OC_SHADOW_DISABLE ((uint16_t)0x0000U) /*!< channel output shadow state disable */ + +/* channel output compare fast enable */ +#define TIMER_OC_FAST_ENABLE ((uint16_t)0x0004) /*!< channel output fast function enable */ +#define TIMER_OC_FAST_DISABLE ((uint16_t)0x0000) /*!< channel output fast function disable */ + +/* channel output compare clear enable */ +#define TIMER_OC_CLEAR_ENABLE ((uint16_t)0x0080U) /*!< channel output clear function enable */ +#define TIMER_OC_CLEAR_DISABLE ((uint16_t)0x0000U) /*!< channel output clear function disable */ + +/* channel control shadow register update control */ +#define TIMER_UPDATECTL_CCU ((uint32_t)0x00000000U) /*!< the shadow registers are updated when CMTG bit is set */ +#define TIMER_UPDATECTL_CCUTRI TIMER_CTL1_CCUC /*!< the shadow registers are updated when CMTG bit is set or an rising edge of TRGI occurs */ + +/* channel input capture polarity */ +#define TIMER_IC_POLARITY_RISING ((uint16_t)0x0000U) /*!< input capture rising edge */ +#define TIMER_IC_POLARITY_FALLING ((uint16_t)0x0002U) /*!< input capture falling edge */ +#define TIMER_IC_POLARITY_BOTH_EDGE ((uint16_t)0x000AU) /*!< input capture both edge */ + +/* TIMER input capture selection */ +#define TIMER_IC_SELECTION_DIRECTTI ((uint16_t)0x0001U) /*!< channel y is configured as input and icy is mapped on CIy */ +#define TIMER_IC_SELECTION_INDIRECTTI ((uint16_t)0x0002U) /*!< channel y is configured as input and icy is mapped on opposite input */ +#define TIMER_IC_SELECTION_ITS ((uint16_t)0x0003U) /*!< channel y is configured as input and icy is mapped on ITS */ + +/* channel input capture prescaler */ +#define TIMER_IC_PSC_DIV1 ((uint16_t)0x0000U) /*!< no prescaler */ +#define TIMER_IC_PSC_DIV2 ((uint16_t)0x0004U) /*!< divided by 2 */ +#define TIMER_IC_PSC_DIV4 ((uint16_t)0x0008U) /*!< divided by 4*/ +#define TIMER_IC_PSC_DIV8 ((uint16_t)0x000CU) /*!< divided by 8 */ + +/* trigger selection */ +#define SMCFG_TRGSEL(regval) (BITS(4, 6) & ((uint32_t)(regval) << 4U)) +#define TIMER_SMCFG_TRGSEL_ITI0 SMCFG_TRGSEL(0) /*!< internal trigger 0 */ +#define TIMER_SMCFG_TRGSEL_ITI1 SMCFG_TRGSEL(1) /*!< internal trigger 1 */ +#define TIMER_SMCFG_TRGSEL_ITI2 SMCFG_TRGSEL(2) /*!< internal trigger 2 */ +#define TIMER_SMCFG_TRGSEL_ITI3 SMCFG_TRGSEL(3) /*!< internal trigger 3 */ +#define TIMER_SMCFG_TRGSEL_CI0F_ED SMCFG_TRGSEL(4) /*!< TI0 Edge Detector */ +#define TIMER_SMCFG_TRGSEL_CI0FE0 SMCFG_TRGSEL(5) /*!< filtered TIMER input 0 */ +#define TIMER_SMCFG_TRGSEL_CI1FE1 SMCFG_TRGSEL(6) /*!< filtered TIMER input 1 */ +#define TIMER_SMCFG_TRGSEL_ETIFP SMCFG_TRGSEL(7) /*!< external trigger */ + +/* master mode control */ +#define CTL1_MMC(regval) (BITS(4, 6) & ((uint32_t)(regval) << 4U)) +#define TIMER_TRI_OUT_SRC_RESET CTL1_MMC(0) /*!< the UPG bit as trigger output */ +#define TIMER_TRI_OUT_SRC_ENABLE CTL1_MMC(1) /*!< the counter enable signal TIMER_CTL0_CEN as trigger output */ +#define TIMER_TRI_OUT_SRC_UPDATE CTL1_MMC(2) /*!< update event as trigger output */ +#define TIMER_TRI_OUT_SRC_CH0 CTL1_MMC(3) /*!< a capture or a compare match occurred in channal0 as trigger output TRGO */ +#define TIMER_TRI_OUT_SRC_O0CPRE CTL1_MMC(4) /*!< O0CPRE as trigger output */ +#define TIMER_TRI_OUT_SRC_O1CPRE CTL1_MMC(5) /*!< O1CPRE as trigger output */ +#define TIMER_TRI_OUT_SRC_O2CPRE CTL1_MMC(6) /*!< O2CPRE as trigger output */ +#define TIMER_TRI_OUT_SRC_O3CPRE CTL1_MMC(7) /*!< O3CPRE as trigger output */ + +/* slave mode control */ +#define SMCFG_SMC(regval) (BITS(0, 2) & ((uint32_t)(regval) << 0U)) +#define TIMER_SLAVE_MODE_DISABLE SMCFG_SMC(0) /*!< slave mode disable */ +#define TIMER_ENCODER_MODE0 SMCFG_SMC(1) /*!< encoder mode 0 */ +#define TIMER_ENCODER_MODE1 SMCFG_SMC(2) /*!< encoder mode 1 */ +#define TIMER_ENCODER_MODE2 SMCFG_SMC(3) /*!< encoder mode 2 */ +#define TIMER_SLAVE_MODE_RESTART SMCFG_SMC(4) /*!< restart mode */ +#define TIMER_SLAVE_MODE_PAUSE SMCFG_SMC(5) /*!< pause mode */ +#define TIMER_SLAVE_MODE_EVENT SMCFG_SMC(6) /*!< event mode */ +#define TIMER_SLAVE_MODE_EXTERNAL0 SMCFG_SMC(7) /*!< external clock mode 0 */ + +/* OCPRE clear source selection */ +#define TIMER_OCPRE_CLEAR_SOURCE_CLR ((uint8_t)0x00U) /*!< OCPRE_CLR_INT is connected to the OCPRE_CLR input */ +#define TIMER_OCPRE_CLEAR_SOURCE_ETIF ((uint8_t)0x01U) /*!< OCPRE_CLR_INT is connected to ETIF */ +#define TIMER_OCPRE_CLEAR_SOURCE_DISABLE ((uint8_t)0x02U) /*!< OCRC=0, and disable ETI */ + +/* master slave mode selection */ +#define TIMER_MASTER_SLAVE_MODE_ENABLE TIMER_SMCFG_MSM /*!< master slave mode enable */ +#define TIMER_MASTER_SLAVE_MODE_DISABLE ((uint32_t)0x00000000U) /*!< master slave mode disable */ + +/* external trigger prescaler */ +#define SMCFG_ETPSC(regval) (BITS(12, 13) & ((uint32_t)(regval) << 12U)) +#define TIMER_EXT_TRI_PSC_OFF SMCFG_ETPSC(0) /*!< no divided */ +#define TIMER_EXT_TRI_PSC_DIV2 SMCFG_ETPSC(1) /*!< divided by 2 */ +#define TIMER_EXT_TRI_PSC_DIV4 SMCFG_ETPSC(2) /*!< divided by 4 */ +#define TIMER_EXT_TRI_PSC_DIV8 SMCFG_ETPSC(3) /*!< divided by 8 */ + +/* external trigger polarity */ +#define TIMER_ETP_FALLING TIMER_SMCFG_ETP /*!< active low or falling edge active */ +#define TIMER_ETP_RISING ((uint32_t)0x00000000U) /*!< active high or rising edge active */ + +/* channel 0 trigger input selection */ +#define TIMER_HALLINTERFACE_ENABLE TIMER_CTL1_TI0S /*!< TIMER hall sensor mode enable */ +#define TIMER_HALLINTERFACE_DISABLE ((uint32_t)0x00000000U) /*!< TIMER hall sensor mode disable */ + +/* TIMERx(x=0,2,13,14,15,16) write cc register selection */ +#define TIMER_CHVSEL_ENABLE ((uint16_t)TIMER_CFG_OUTSEL) /*!< write CHxVAL register selection enable */ +#define TIMER_CHVSEL_DISABLE ((uint16_t)0x0000U) /*!< write CC register selection enable */ + +/* the output value selection */ +#define TIMER_OUTSEL_ENABLE ((uint16_t)TIMER_CFG_OUTSEL) /*!< output value selection enable */ +#define TIMER_OUTSEL_DISABLE ((uint16_t)0x0000U) /*!< output value selection enable */ + +/* timer13 channel 0 input remap */ +#define TIMER13_IRMP(regval) (BITS(0, 1) & ((uint32_t)(regval) << 0U)) +#define TIMER13_CI0_RMP_GPIO TIMER13_IRMP(0) /*!< timer13 channel 0 input is connected to GPIO(TIMER13_CH0) */ +#define TIMER13_CI0_RMP_RTCCLK TIMER13_IRMP(1) /*!< timer13 channel 0 input is connected to the RTCCLK */ +#define TIMER13_CI0_RMP_HXTAL_DIV32 TIMER13_IRMP(2) /*!< timer13 channel 0 input is connected to HXTAL/32 clock */ +#define TIMER13_CI0_RMP_CKOUTSEL TIMER13_IRMP(3) /*!< timer13 channel 0 input is connected to CKOUTSEL */ + +/* function declarations */ +/* TIMER timebase*/ +/* deinit a TIMER */ +void timer_deinit(uint32_t timer_periph); +/* initialize TIMER init parameter struct */ +void timer_struct_para_init(timer_parameter_struct* initpara); +/* initialize TIMER counter */ +void timer_init(uint32_t timer_periph, timer_parameter_struct* initpara); +/* enable a TIMER */ +void timer_enable(uint32_t timer_periph); +/* disable a TIMER */ +void timer_disable(uint32_t timer_periph); +/* enable the auto reload shadow function */ +void timer_auto_reload_shadow_enable(uint32_t timer_periph); +/* disable the auto reload shadow function */ +void timer_auto_reload_shadow_disable(uint32_t timer_periph); +/* enable the update event */ +void timer_update_event_enable(uint32_t timer_periph); +/* disable the update event */ +void timer_update_event_disable(uint32_t timer_periph); +/* set TIMER counter alignment mode */ +void timer_counter_alignment(uint32_t timer_periph, uint16_t aligned); +/* set TIMER counter up direction */ +void timer_counter_up_direction(uint32_t timer_periph); +/* set TIMER counter down direction */ +void timer_counter_down_direction(uint32_t timer_periph); +/* configure TIMER prescaler */ +void timer_prescaler_config(uint32_t timer_periph, uint16_t prescaler, uint8_t pscreload); +/* configure TIMER repetition register value */ +void timer_repetition_value_config(uint32_t timer_periph, uint16_t repetition); +/* configure TIMER autoreload register value */ +void timer_autoreload_value_config(uint32_t timer_periph, uint16_t autoreload); +/* configure TIMER counter register value */ +void timer_counter_value_config(uint32_t timer_periph , uint16_t counter); +/* read TIMER counter value */ +uint32_t timer_counter_read(uint32_t timer_periph); +/* read TIMER prescaler value */ +uint16_t timer_prescaler_read(uint32_t timer_periph); +/* configure TIMER single pulse mode */ +void timer_single_pulse_mode_config(uint32_t timer_periph, uint32_t spmode); +/* configure TIMER update source */ +void timer_update_source_config(uint32_t timer_periph, uint32_t update); +/* OCPRE clear source selection */ +void timer_ocpre_clear_source_config(uint32_t timer_periph, uint8_t ocpreclear); + +/* TIMER interrupt and flag*/ +/* enable the TIMER interrupt */ +void timer_interrupt_enable(uint32_t timer_periph, uint32_t interrupt); +/* disable the TIMER interrupt */ +void timer_interrupt_disable(uint32_t timer_periph, uint32_t interrupt); +/* get timer interrupt flag */ +FlagStatus timer_interrupt_flag_get(uint32_t timer_periph, uint32_t interrupt); +/* clear TIMER interrupt flag */ +void timer_interrupt_flag_clear(uint32_t timer_periph, uint32_t interrupt); +/* get TIMER flags */ +FlagStatus timer_flag_get(uint32_t timer_periph, uint32_t flag); +/* clear TIMER flags */ +void timer_flag_clear(uint32_t timer_periph, uint32_t flag); + +/* timer DMA and event*/ +/* enable the TIMER DMA */ +void timer_dma_enable(uint32_t timer_periph, uint16_t dma); +/* disable the TIMER DMA */ +void timer_dma_disable(uint32_t timer_periph, uint16_t dma); +/* channel DMA request source selection */ +void timer_channel_dma_request_source_select(uint32_t timer_periph, uint8_t dma_request); +/* configure the TIMER DMA transfer */ +void timer_dma_transfer_config(uint32_t timer_periph,uint32_t dma_baseaddr, uint32_t dma_lenth); +/* software generate events */ +void timer_event_software_generate(uint32_t timer_periph, uint16_t event); + +/* TIMER channel complementary protection */ +/* initialize TIMER break parameter struct */ +void timer_break_struct_para_init(timer_break_parameter_struct* breakpara); +/* configure TIMER break function */ +void timer_break_config(uint32_t timer_periph, timer_break_parameter_struct* breakpara); +/* enable TIMER break function */ +void timer_break_enable(uint32_t timer_periph); +/* disable TIMER break function */ +void timer_break_disable(uint32_t timer_periph); +/* enable TIMER output automatic function */ +void timer_automatic_output_enable(uint32_t timer_periph); +/* disable TIMER output automatic function */ +void timer_automatic_output_disable(uint32_t timer_periph); +/* enable or disable TIMER primary output function */ +void timer_primary_output_config(uint32_t timer_periph, ControlStatus newvalue); +/* enable or disable channel capture/compare control shadow register */ +void timer_channel_control_shadow_config(uint32_t timer_periph, ControlStatus newvalue); +/* configure TIMER channel control shadow register update control */ +void timer_channel_control_shadow_update_config(uint32_t timer_periph, uint8_t ccuctl); + +/* TIMER channel output */ +/* initialize TIMER channel output parameter struct */ +void timer_channel_output_struct_para_init(timer_oc_parameter_struct* ocpara); +/* configure TIMER channel output function */ +void timer_channel_output_config(uint32_t timer_periph,uint16_t channel, timer_oc_parameter_struct* ocpara); +/* configure TIMER channel output compare mode */ +void timer_channel_output_mode_config(uint32_t timer_periph, uint16_t channel,uint16_t ocmode); +/* configure TIMER channel output pulse value */ +void timer_channel_output_pulse_value_config(uint32_t timer_periph, uint16_t channel, uint32_t pulse); +/* configure TIMER channel output shadow function */ +void timer_channel_output_shadow_config(uint32_t timer_periph, uint16_t channel, uint16_t ocshadow); +/* configure TIMER channel output fast function */ +void timer_channel_output_fast_config(uint32_t timer_periph, uint16_t channel, uint16_t ocfast); +/* configure TIMER channel output clear function */ +void timer_channel_output_clear_config(uint32_t timer_periph,uint16_t channel,uint16_t occlear); +/* configure TIMER channel output polarity */ +void timer_channel_output_polarity_config(uint32_t timer_periph, uint16_t channel, uint16_t ocpolarity); +/* configure TIMER channel complementary output polarity */ +void timer_channel_complementary_output_polarity_config(uint32_t timer_periph, uint16_t channel, uint16_t ocnpolarity); +/* configure TIMER channel enable state */ +void timer_channel_output_state_config(uint32_t timer_periph, uint16_t channel, uint32_t state); +/* configure TIMER channel complementary output enable state */ +void timer_channel_complementary_output_state_config(uint32_t timer_periph, uint16_t channel, uint16_t ocnstate); + +/* TIMER channel input */ +/* initialize TIMER channel input parameter struct */ +void timer_channel_input_struct_para_init(timer_ic_parameter_struct* icpara); +/* configure TIMER input capture parameter */ +void timer_input_capture_config(uint32_t timer_periph, uint16_t channel, timer_ic_parameter_struct* icpara); +/* configure TIMER channel input capture prescaler value */ +void timer_channel_input_capture_prescaler_config(uint32_t timer_periph, uint16_t channel, uint16_t prescaler); +/* read TIMER channel capture compare register value */ +uint32_t timer_channel_capture_value_register_read(uint32_t timer_periph, uint16_t channel); +/* configure TIMER input pwm capture function */ +void timer_input_pwm_capture_config(uint32_t timer_periph, uint16_t channel, timer_ic_parameter_struct* icpwm); +/* configure TIMER hall sensor mode */ +void timer_hall_mode_config(uint32_t timer_periph, uint32_t hallmode); + +/* TIMER master and slave */ +/* select TIMER input trigger source */ +void timer_input_trigger_source_select(uint32_t timer_periph, uint32_t intrigger); +/* select TIMER master mode output trigger source */ +void timer_master_output_trigger_source_select(uint32_t timer_periph, uint32_t outrigger); +/* select TIMER slave mode */ +void timer_slave_mode_select(uint32_t timer_periph,uint32_t slavemode); +/* configure TIMER master slave mode */ +void timer_master_slave_mode_config(uint32_t timer_periph, uint32_t masterslave); +/* configure TIMER external trigger input */ +void timer_external_trigger_config(uint32_t timer_periph, uint32_t extprescaler, uint32_t extpolarity, uint32_t extfilter); +/* configure TIMER quadrature decoder mode */ +void timer_quadrature_decoder_mode_config(uint32_t timer_periph, uint32_t decomode, uint16_t ic0polarity, uint16_t ic1polarity); +/* configure TIMER internal clock mode */ +void timer_internal_clock_config(uint32_t timer_periph); +/* configure TIMER the internal trigger as external clock input */ +void timer_internal_trigger_as_external_clock_config(uint32_t timer_periph, uint32_t intrigger); +/* configure TIMER the external trigger as external clock input */ +void timer_external_trigger_as_external_clock_config(uint32_t timer_periph, uint32_t extrigger, uint16_t extpolarity,uint32_t extfilter); +/* configure TIMER the external clock mode 0 */ +void timer_external_clock_mode0_config(uint32_t timer_periph, uint32_t extprescaler, uint32_t extpolarity, uint32_t extfilter); +/* configure TIMER the external clock mode 1 */ +void timer_external_clock_mode1_config(uint32_t timer_periph, uint32_t extprescaler, uint32_t extpolarity, uint32_t extfilter); +/* disable TIMER the external clock mode 1 */ +void timer_external_clock_mode1_disable(uint32_t timer_periph); +/* configure TIMER channel remap function */ +void timer_channel_remap_config(uint32_t timer_periph,uint32_t remap); + +/* TIMER configure */ +/* configure TIMER write CHxVAL register selection */ +void timer_write_chxval_register_config(uint32_t timer_periph, uint16_t ccsel); +/* configure TIMER output value selection */ +void timer_output_value_selection_config(uint32_t timer_periph, uint16_t outsel); + +#endif /* GD32E230_TIMER_H */ diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_usart.h b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_usart.h new file mode 100644 index 0000000000000000000000000000000000000000..6cb6f61056a783df1f52c6a4adc63081c73c660f --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_usart.h @@ -0,0 +1,614 @@ +/*! + \file gd32e230_usart.h + \brief definitions for the USART + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor 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 copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 GD32E230_USART_H +#define GD32E230_USART_H + +#include "gd32e230.h" + +/* USARTx(x=0,1) definitions */ +#define USART0 (USART_BASE + 0x0000F400U) +#define USART1 USART_BASE + +/* registers definitions */ +#define USART_CTL0(usartx) REG32((usartx) + 0x00000000U) /*!< USART control register 0 */ +#define USART_CTL1(usartx) REG32((usartx) + 0x00000004U) /*!< USART control register 1 */ +#define USART_CTL2(usartx) REG32((usartx) + 0x00000008U) /*!< USART control register 2 */ +#define USART_BAUD(usartx) REG32((usartx) + 0x0000000CU) /*!< USART baud rate register */ +#define USART_GP(usartx) REG32((usartx) + 0x00000010U) /*!< USART guard time and prescaler register */ +#define USART_RT(usartx) REG32((usartx) + 0x00000014U) /*!< USART receiver timeout register */ +#define USART_CMD(usartx) REG32((usartx) + 0x00000018U) /*!< USART command register */ +#define USART_STAT(usartx) REG32((usartx) + 0x0000001CU) /*!< USART status register */ +#define USART_INTC(usartx) REG32((usartx) + 0x00000020U) /*!< USART status clear register */ +#define USART_RDATA(usartx) REG32((usartx) + 0x00000024U) /*!< USART receive data register */ +#define USART_TDATA(usartx) REG32((usartx) + 0x00000028U) /*!< USART transmit data register */ +#define USART_CHC(usartx) REG32((usartx) + 0x000000C0U) /*!< USART coherence control register */ +#define USART_RFCS(usartx) REG32((usartx) + 0x000000D0U) /*!< USART receive FIFO control and status register */ + +/* bits definitions */ +/* USARTx_CTL0 */ +#define USART_CTL0_UEN BIT(0) /*!< USART enable */ +#define USART_CTL0_UESM BIT(1) /*!< USART enable in deep-sleep mode */ +#define USART_CTL0_REN BIT(2) /*!< receiver enable */ +#define USART_CTL0_TEN BIT(3) /*!< transmitter enable */ +#define USART_CTL0_IDLEIE BIT(4) /*!< idle line detected interrupt enable */ +#define USART_CTL0_RBNEIE BIT(5) /*!< read data buffer not empty interrupt and overrun error interrupt enable */ +#define USART_CTL0_TCIE BIT(6) /*!< transmission complete interrupt enable */ +#define USART_CTL0_TBEIE BIT(7) /*!< transmitter register empty interrupt enable */ +#define USART_CTL0_PERRIE BIT(8) /*!< parity error interrupt enable */ +#define USART_CTL0_PM BIT(9) /*!< parity mode */ +#define USART_CTL0_PCEN BIT(10) /*!< parity control enable */ +#define USART_CTL0_WM BIT(11) /*!< wakeup method in mute mode */ +#define USART_CTL0_WL BIT(12) /*!< word length */ +#define USART_CTL0_MEN BIT(13) /*!< mute mode enable */ +#define USART_CTL0_AMIE BIT(14) /*!< address match interrupt enable */ +#define USART_CTL0_OVSMOD BIT(15) /*!< oversample mode */ +#define USART_CTL0_DED BITS(16,20) /*!< driver enable deassertion time */ +#define USART_CTL0_DEA BITS(21,25) /*!< driver enable assertion time */ +#define USART_CTL0_RTIE BIT(26) /*!< receiver timeout interrupt enable */ +#define USART_CTL0_EBIE BIT(27) /*!< end of block interrupt enable */ + +/* USARTx_CTL1 */ +#define USART_CTL1_ADDM BIT(4) /*!< address detection mode */ +#define USART_CTL1_LBLEN BIT(5) /*!< LIN break frame length */ +#define USART_CTL1_LBDIE BIT(6) /*!< LIN break detection interrupt enable */ +#define USART_CTL1_CLEN BIT(8) /*!< last bit clock pulse */ +#define USART_CTL1_CPH BIT(9) /*!< clock phase */ +#define USART_CTL1_CPL BIT(10) /*!< clock polarity */ +#define USART_CTL1_CKEN BIT(11) /*!< ck pin enable */ +#define USART_CTL1_STB BITS(12,13) /*!< stop bits length */ +#define USART_CTL1_LMEN BIT(14) /*!< LIN mode enable */ +#define USART_CTL1_STRP BIT(15) /*!< swap TX/RX pins */ +#define USART_CTL1_RINV BIT(16) /*!< RX pin level inversion */ +#define USART_CTL1_TINV BIT(17) /*!< TX pin level inversion */ +#define USART_CTL1_DINV BIT(18) /*!< data bit level inversion */ +#define USART_CTL1_MSBF BIT(19) /*!< most significant bit first */ +#define USART_CTL1_ABDEN BIT(20) /*!< auto baud rate enable */ +#define USART_CTL1_ABDM BITS(21,22) /*!< auto baud rate mode */ +#define USART_CTL1_RTEN BIT(23) /*!< receiver timeout enable */ +#define USART_CTL1_ADDR BITS(24,31) /*!< address of the USART terminal */ + +/* USARTx_CTL2 */ +#define USART_CTL2_ERRIE BIT(0) /*!< error interrupt enable in multibuffer communication */ +#define USART_CTL2_IREN BIT(1) /*!< IrDA mode enable */ +#define USART_CTL2_IRLP BIT(2) /*!< IrDA low-power */ +#define USART_CTL2_HDEN BIT(3) /*!< half-duplex enable */ +#define USART_CTL2_NKEN BIT(4) /*!< NACK enable in smartcard mode */ +#define USART_CTL2_SCEN BIT(5) /*!< smartcard mode enable */ +#define USART_CTL2_DENR BIT(6) /*!< DMA enable for reception */ +#define USART_CTL2_DENT BIT(7) /*!< DMA enable for transmission */ +#define USART_CTL2_RTSEN BIT(8) /*!< RTS enable */ +#define USART_CTL2_CTSEN BIT(9) /*!< CTS enable */ +#define USART_CTL2_CTSIE BIT(10) /*!< CTS interrupt enable */ +#define USART_CTL2_OSB BIT(11) /*!< one sample bit mode */ +#define USART_CTL2_OVRD BIT(12) /*!< overrun disable */ +#define USART_CTL2_DDRE BIT(13) /*!< disable DMA on reception error */ +#define USART_CTL2_DEM BIT(14) /*!< driver enable mode */ +#define USART_CTL2_DEP BIT(15) /*!< driver enable polarity mode */ +#define USART_CTL2_SCRTNUM BITS(17,19) /*!< smartcard auto-retry number */ +#define USART_CTL2_WUM BITS(20,21) /*!< wakeup mode from deep-sleep mode */ +#define USART_CTL2_WUIE BIT(22) /*!< wakeup from deep-sleep mode interrupt enable */ + +/* USARTx_BAUD */ +#define USART_BAUD_FRADIV BITS(0,3) /*!< fraction of baud-rate divider */ +#define USART_BAUD_INTDIV BITS(4,15) /*!< integer of baud-rate divider */ + +/* USARTx_GP */ +#define USART_GP_PSC BITS(0,7) /*!< prescaler value for dividing the system clock */ +#define USART_GP_GUAT BITS(8,15) /*!< guard time value in smartcard mode */ + +/* USARTx_RT */ +#define USART_RT_RT BITS(0,23) /*!< receiver timeout threshold */ +#define USART_RT_BL BITS(24,31) /*!< block length */ + +/* USARTx_CMD */ +#define USART_CMD_ABDCMD BIT(0) /*!< auto baudrate detection command */ +#define USART_CMD_SBKCMD BIT(1) /*!< send break command */ +#define USART_CMD_MMCMD BIT(2) /*!< mute mode command */ +#define USART_CMD_RXFCMD BIT(3) /*!< receive data flush command */ +#define USART_CMD_TXFCMD BIT(4) /*!< transmit data flush request */ + +/* USARTx_STAT */ +#define USART_STAT_PERR BIT(0) /*!< parity error flag */ +#define USART_STAT_FERR BIT(1) /*!< frame error flag */ +#define USART_STAT_NERR BIT(2) /*!< noise error flag */ +#define USART_STAT_ORERR BIT(3) /*!< overrun error */ +#define USART_STAT_IDLEF BIT(4) /*!< idle line detected flag */ +#define USART_STAT_RBNE BIT(5) /*!< read data buffer not empty */ +#define USART_STAT_TC BIT(6) /*!< transmission completed */ +#define USART_STAT_TBE BIT(7) /*!< transmit data register empty */ +#define USART_STAT_LBDF BIT(8) /*!< LIN break detected flag */ +#define USART_STAT_CTSF BIT(9) /*!< CTS change flag */ +#define USART_STAT_CTS BIT(10) /*!< CTS level */ +#define USART_STAT_RTF BIT(11) /*!< receiver timeout flag */ +#define USART_STAT_EBF BIT(12) /*!< end of block flag */ +#define USART_STAT_ABDE BIT(14) /*!< auto baudrate detection error */ +#define USART_STAT_ABDF BIT(15) /*!< auto baudrate detection flag */ +#define USART_STAT_BSY BIT(16) /*!< busy flag */ +#define USART_STAT_AMF BIT(17) /*!< address match flag */ +#define USART_STAT_SBF BIT(18) /*!< send break flag */ +#define USART_STAT_RWU BIT(19) /*!< receiver wakeup from mute mode */ +#define USART_STAT_WUF BIT(20) /*!< wakeup from deep-sleep mode flag */ +#define USART_STAT_TEA BIT(21) /*!< transmit enable acknowledge flag */ +#define USART_STAT_REA BIT(22) /*!< receive enable acknowledge flag */ + +/* USARTx_INTC */ +#define USART_INTC_PEC BIT(0) /*!< parity error clear */ +#define USART_INTC_FEC BIT(1) /*!< frame error flag clear */ +#define USART_INTC_NEC BIT(2) /*!< noise detected clear */ +#define USART_INTC_OREC BIT(3) /*!< overrun error clear */ +#define USART_INTC_IDLEC BIT(4) /*!< idle line detected clear */ +#define USART_INTC_TCC BIT(6) /*!< transmission complete clear */ +#define USART_INTC_LBDC BIT(8) /*!< LIN break detected clear */ +#define USART_INTC_CTSC BIT(9) /*!< CTS change clear */ +#define USART_INTC_RTC BIT(11) /*!< receiver timeout clear */ +#define USART_INTC_EBC BIT(12) /*!< end of timeout clear */ +#define USART_INTC_AMC BIT(17) /*!< address match clear */ +#define USART_INTC_WUC BIT(20) /*!< wakeup from deep-sleep mode clear */ + +/* USARTx_RDATA */ +#define USART_RDATA_RDATA BITS(0,8) /*!< receive data value */ + +/* USARTx_TDATA */ +#define USART_TDATA_TDATA BITS(0,8) /*!< transmit data value */ + +/* USARTx_CHC */ +#define USART_CHC_HCM BIT(0) /*!< hardware flow control coherence mode */ +#define USART_CHC_EPERR BIT(8) /*!< early parity error flag */ + +/* USARTx_RFCS */ +#define USART_RFCS_ELNACK BIT(0) /*!< early NACK */ +#define USART_RFCS_RFEN BIT(8) /*!< receive FIFO enable */ +#define USART_RFCS_RFFIE BIT(9) /*!< receive FIFO full interrupt enable */ +#define USART_RFCS_RFE BIT(10) /*!< receive FIFO empty flag */ +#define USART_RFCS_RFF BIT(11) /*!< receive FIFO full flag */ +#define USART_RFCS_RFCNT BITS(12,14) /*!< receive FIFO counter number */ +#define USART_RFCS_RFFINT BIT(15) /*!< receive FIFO full interrupt flag */ + +/* constants definitions */ + +/* define the USART bit position and its register index offset */ +#define USART_REGIDX_BIT(regidx, bitpos) (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos)) +#define USART_REG_VAL(usartx, offset) (REG32((usartx) + (((uint32_t)(offset) & 0x0000FFFFU) >> 6))) +#define USART_BIT_POS(val) ((uint32_t)(val) & 0x0000001FU) +#define USART_REGIDX_BIT2(regidx, bitpos, regidx2, bitpos2) (((uint32_t)(regidx2) << 22) | (uint32_t)((bitpos2) << 16)\ + | (((uint32_t)(regidx) << 6) | (uint32_t)(bitpos))) +#define USART_REG_VAL2(usartx, offset) (REG32((usartx) + ((uint32_t)(offset) >> 22))) +#define USART_BIT_POS2(val) (((uint32_t)(val) & 0x001F0000U) >> 16) + +/* register offset */ +#define USART_CTL0_REG_OFFSET 0x00000000U /*!< CTL0 register offset */ +#define USART_CTL1_REG_OFFSET 0x00000004U /*!< CTL1 register offset */ +#define USART_CTL2_REG_OFFSET 0x00000008U /*!< CTL2 register offset */ +#define USART_STAT_REG_OFFSET 0x0000001CU /*!< STAT register offset */ +#define USART_CHC_REG_OFFSET 0x000000C0U /*!< CHC register offset */ +#define USART_RFCS_REG_OFFSET 0x000000D0U /*!< RFCS register offset */ + +/* USART flags */ +typedef enum{ + /* flags in STAT register */ + USART_FLAG_REA = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 22U), /*!< receive enable acknowledge flag */ + USART_FLAG_TEA = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 21U), /*!< transmit enable acknowledge flag */ + USART_FLAG_WU = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 20U), /*!< wakeup from Deep-sleep mode flag */ + USART_FLAG_RWU = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 19U), /*!< receiver wakeup from mute mode */ + USART_FLAG_SB = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 18U), /*!< send break flag */ + USART_FLAG_AM = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 17U), /*!< ADDR match flag */ + USART_FLAG_BSY = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 16U), /*!< busy flag */ + USART_FLAG_ABD = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 15U), /*!< auto baudrate detection flag */ + USART_FLAG_ABDE = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 14U), /*!< auto baudrate detection error */ + USART_FLAG_EB = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 12U), /*!< end of block flag */ + USART_FLAG_RT = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 11U), /*!< receiver timeout flag */ + USART_FLAG_CTS = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 10U), /*!< CTS level */ + USART_FLAG_CTSF = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 9U), /*!< CTS change flag */ + USART_FLAG_LBD = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 8U), /*!< LIN break detected flag */ + USART_FLAG_TBE = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 7U), /*!< transmit data buffer empty */ + USART_FLAG_TC = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 6U), /*!< transmission complete */ + USART_FLAG_RBNE = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 5U), /*!< read data buffer not empty */ + USART_FLAG_IDLE = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 4U), /*!< IDLE line detected flag */ + USART_FLAG_ORERR = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 3U), /*!< overrun error */ + USART_FLAG_NERR = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 2U), /*!< noise error flag */ + USART_FLAG_FERR = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 1U), /*!< frame error flag */ + USART_FLAG_PERR = USART_REGIDX_BIT(USART_STAT_REG_OFFSET, 0U), /*!< parity error flag */ + /* flags in CHC register */ + USART_FLAG_EPERR = USART_REGIDX_BIT(USART_CHC_REG_OFFSET, 8U), /*!< early parity error flag */ + /* flags in RFCS register */ + USART_FLAG_RFFINT = USART_REGIDX_BIT(USART_RFCS_REG_OFFSET, 15U), /*!< receive FIFO full interrupt flag */ + USART_FLAG_RFF = USART_REGIDX_BIT(USART_RFCS_REG_OFFSET, 11U), /*!< receive FIFO full flag */ + USART_FLAG_RFE = USART_REGIDX_BIT(USART_RFCS_REG_OFFSET, 10U), /*!< receive FIFO empty flag */ +}usart_flag_enum; + +/* USART interrupt flags */ +typedef enum +{ + /* interrupt flags in CTL0 register */ + USART_INT_FLAG_EB = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 27U, USART_STAT_REG_OFFSET, 12U), /*!< end of block interrupt and flag */ + USART_INT_FLAG_RT = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 26U, USART_STAT_REG_OFFSET, 11U), /*!< receiver timeout interrupt and flag */ + USART_INT_FLAG_AM = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 14U, USART_STAT_REG_OFFSET, 17U), /*!< address match interrupt and flag */ + USART_INT_FLAG_PERR = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 8U, USART_STAT_REG_OFFSET, 0U), /*!< parity error interrupt and flag */ + USART_INT_FLAG_TBE = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 7U, USART_STAT_REG_OFFSET, 7U), /*!< transmitter buffer empty interrupt and flag */ + USART_INT_FLAG_TC = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 6U, USART_STAT_REG_OFFSET, 6U), /*!< transmission complete interrupt and flag */ + USART_INT_FLAG_RBNE = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 5U, USART_STAT_REG_OFFSET, 5U), /*!< read data buffer not empty interrupt and flag */ + USART_INT_FLAG_RBNE_ORERR = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 5U, USART_STAT_REG_OFFSET, 3U), /*!< read data buffer not empty interrupt and overrun error flag */ + USART_INT_FLAG_IDLE = USART_REGIDX_BIT2(USART_CTL0_REG_OFFSET, 4U, USART_STAT_REG_OFFSET, 4U), /*!< IDLE line detected interrupt and flag */ + /* interrupt flags in CTL1 register */ + USART_INT_FLAG_LBD = USART_REGIDX_BIT2(USART_CTL1_REG_OFFSET, 6U, USART_STAT_REG_OFFSET, 8U), /*!< LIN break detected interrupt and flag */ + /* interrupt flags in CTL2 register */ + USART_INT_FLAG_WU = USART_REGIDX_BIT2(USART_CTL2_REG_OFFSET, 22U, USART_STAT_REG_OFFSET, 20U), /*!< wakeup from deep-sleep mode interrupt and flag */ + USART_INT_FLAG_CTS = USART_REGIDX_BIT2(USART_CTL2_REG_OFFSET, 10U, USART_STAT_REG_OFFSET, 9U), /*!< CTS interrupt and flag */ + USART_INT_FLAG_ERR_NERR = USART_REGIDX_BIT2(USART_CTL2_REG_OFFSET, 0U, USART_STAT_REG_OFFSET, 2U), /*!< error interrupt and noise error flag */ + USART_INT_FLAG_ERR_ORERR = USART_REGIDX_BIT2(USART_CTL2_REG_OFFSET, 0U, USART_STAT_REG_OFFSET, 3U), /*!< error interrupt and overrun error */ + USART_INT_FLAG_ERR_FERR = USART_REGIDX_BIT2(USART_CTL2_REG_OFFSET, 0U, USART_STAT_REG_OFFSET, 1U), /*!< error interrupt and frame error flag */ + /* interrupt flags in RFCS register */ + USART_INT_FLAG_RFF = USART_REGIDX_BIT2(USART_RFCS_REG_OFFSET, 9U, USART_RFCS_REG_OFFSET, 15U), /*!< receive FIFO full interrupt and flag */ +}usart_interrupt_flag_enum; + +/* USART interrupt enable or disable */ +typedef enum +{ + /* interrupt in CTL0 register */ + USART_INT_EB = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 27U), /*!< end of block interrupt */ + USART_INT_RT = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 26U), /*!< receiver timeout interrupt */ + USART_INT_AM = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 14U), /*!< address match interrupt */ + USART_INT_PERR = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 8U), /*!< parity error interrupt */ + USART_INT_TBE = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 7U), /*!< transmitter buffer empty interrupt */ + USART_INT_TC = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 6U), /*!< transmission complete interrupt */ + USART_INT_RBNE = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 5U), /*!< read data buffer not empty interrupt and overrun error interrupt */ + USART_INT_IDLE = USART_REGIDX_BIT(USART_CTL0_REG_OFFSET, 4U), /*!< IDLE line detected interrupt */ + /* interrupt in CTL1 register */ + USART_INT_LBD = USART_REGIDX_BIT(USART_CTL1_REG_OFFSET, 6U), /*!< LIN break detected interrupt */ + /* interrupt in CTL2 register */ + USART_INT_WU = USART_REGIDX_BIT(USART_CTL2_REG_OFFSET, 22U), /*!< wakeup from deep-sleep mode interrupt */ + USART_INT_CTS = USART_REGIDX_BIT(USART_CTL2_REG_OFFSET, 10U), /*!< CTS interrupt */ + USART_INT_ERR = USART_REGIDX_BIT(USART_CTL2_REG_OFFSET, 0U), /*!< error interrupt */ + /* interrupt in RFCS register */ + USART_INT_RFF = USART_REGIDX_BIT(USART_RFCS_REG_OFFSET, 9U), /*!< receive FIFO full interrupt */ +}usart_interrupt_enum; + +/* USART invert configure */ +typedef enum { + /* data bit level inversion */ + USART_DINV_ENABLE, /*!< data bit level inversion */ + USART_DINV_DISABLE, /*!< data bit level not inversion */ + /* TX pin level inversion */ + USART_TXPIN_ENABLE, /*!< TX pin level inversion */ + USART_TXPIN_DISABLE, /*!< TX pin level not inversion */ + /* RX pin level inversion */ + USART_RXPIN_ENABLE, /*!< RX pin level inversion */ + USART_RXPIN_DISABLE, /*!< RX pin level not inversion */ + /* swap TX/RX pins */ + USART_SWAP_ENABLE, /*!< swap TX/RX pins */ + USART_SWAP_DISABLE, /*!< not swap TX/RX pins */ +}usart_invert_enum; + +/* USART receiver configure */ +#define CTL0_REN(regval) (BIT(2) & ((uint32_t)(regval) << 2)) +#define USART_RECEIVE_ENABLE CTL0_REN(1) /*!< enable receiver */ +#define USART_RECEIVE_DISABLE CTL0_REN(0) /*!< disable receiver */ + +/* USART transmitter configure */ +#define CTL0_TEN(regval) (BIT(3) & ((uint32_t)(regval) << 3)) +#define USART_TRANSMIT_ENABLE CTL0_TEN(1) /*!< enable transmitter */ +#define USART_TRANSMIT_DISABLE CTL0_TEN(0) /*!< disable transmitter */ + +/* USART parity bits definitions */ +#define CTL0_PM(regval) (BITS(9,10) & ((uint32_t)(regval) << 9)) +#define USART_PM_NONE CTL0_PM(0) /*!< no parity */ +#define USART_PM_EVEN CTL0_PM(2) /*!< even parity */ +#define USART_PM_ODD CTL0_PM(3) /*!< odd parity */ + +/* USART wakeup method in mute mode */ +#define CTL0_WM(regval) (BIT(11) & ((uint32_t)(regval) << 11)) +#define USART_WM_IDLE CTL0_WM(0) /*!< idle line */ +#define USART_WM_ADDR CTL0_WM(1) /*!< address match */ + +/* USART word length definitions */ +#define CTL0_WL(regval) (BIT(12) & ((uint32_t)(regval) << 12)) +#define USART_WL_8BIT CTL0_WL(0) /*!< 8 bits */ +#define USART_WL_9BIT CTL0_WL(1) /*!< 9 bits */ + +/* USART oversample mode */ +#define CTL0_OVSMOD(regval) (BIT(15) & ((uint32_t)(regval) << 15)) +#define USART_OVSMOD_8 CTL0_OVSMOD(1) /*!< oversampling by 8 */ +#define USART_OVSMOD_16 CTL0_OVSMOD(0) /*!< oversampling by 16 */ + +/* USART address detection mode */ +#define CTL1_ADDM(regval) (BIT(4) & ((uint32_t)(regval) << 4)) +#define USART_ADDM_4BIT CTL1_ADDM(0) /*!< 4-bit address detection */ +#define USART_ADDM_FULLBIT CTL1_ADDM(1) /*!< full-bit address detection */ + +/* USART LIN break frame length */ +#define CTL1_LBLEN(regval) (BIT(5) & ((uint32_t)(regval) << 5)) +#define USART_LBLEN_10B CTL1_LBLEN(0) /*!< 10 bits break detection */ +#define USART_LBLEN_11B CTL1_LBLEN(1) /*!< 11 bits break detection */ + +/* USART last bit clock pulse */ +#define CTL1_CLEN(regval) (BIT(8) & ((uint32_t)(regval) << 8)) +#define USART_CLEN_NONE CTL1_CLEN(0) /*!< clock pulse of the last data bit (MSB) is not output to the CK pin */ +#define USART_CLEN_EN CTL1_CLEN(1) /*!< clock pulse of the last data bit (MSB) is output to the CK pin */ + +/* USART clock phase */ +#define CTL1_CPH(regval) (BIT(9) & ((uint32_t)(regval) << 9)) +#define USART_CPH_1CK CTL1_CPH(0) /*!< first clock transition is the first data capture edge */ +#define USART_CPH_2CK CTL1_CPH(1) /*!< second clock transition is the first data capture edge */ + +/* USART clock polarity */ +#define CTL1_CPL(regval) (BIT(10) & ((uint32_t)(regval) << 10)) +#define USART_CPL_LOW CTL1_CPL(0) /*!< steady low value on CK pin */ +#define USART_CPL_HIGH CTL1_CPL(1) /*!< steady high value on CK pin */ + +/* USART stop bits definitions */ +#define CTL1_STB(regval) (BITS(12,13) & ((uint32_t)(regval) << 12)) +#define USART_STB_1BIT CTL1_STB(0) /*!< 1 bit */ +#define USART_STB_0_5BIT CTL1_STB(1) /*!< 0.5 bit */ +#define USART_STB_2BIT CTL1_STB(2) /*!< 2 bits */ +#define USART_STB_1_5BIT CTL1_STB(3) /*!< 1.5 bits */ + +/* USART data is transmitted/received with the LSB/MSB first */ +#define CTL1_MSBF(regval) (BIT(19) & ((uint32_t)(regval) << 19)) +#define USART_MSBF_LSB CTL1_MSBF(0) /*!< LSB first */ +#define USART_MSBF_MSB CTL1_MSBF(1) /*!< MSB first */ + +/* USART auto baud rate detection mode bits definitions */ +#define CTL1_ABDM(regval) (BITS(21,22) & ((uint32_t)(regval) << 21)) +#define USART_ABDM_FTOR CTL1_ABDM(0) /*!< falling edge to rising edge measurement */ +#define USART_ABDM_FTOF CTL1_ABDM(1) /*!< falling edge to falling edge measurement */ + +/* USART IrDA low-power enable */ +#define CTL2_IRLP(regval) (BIT(2) & ((uint32_t)(regval) << 2)) +#define USART_IRLP_LOW CTL2_IRLP(1) /*!< low-power */ +#define USART_IRLP_NORMAL CTL2_IRLP(0) /*!< normal */ + +/* DMA enable for reception */ +#define CTL2_DENR(regval) (BIT(6) & ((uint32_t)(regval) << 6)) +#define USART_DENR_ENABLE CTL2_DENR(1) /*!< enable for reception */ +#define USART_DENR_DISABLE CTL2_DENR(0) /*!< disable for reception */ + +/* DMA enable for transmission */ +#define CTL2_DENT(regval) (BIT(7) & ((uint32_t)(regval) << 7)) +#define USART_DENT_ENABLE CTL2_DENT(1) /*!< enable for transmission */ +#define USART_DENT_DISABLE CTL2_DENT(0) /*!< disable for transmission */ + +/* USART RTS hardware flow control configure */ +#define CTL2_RTSEN(regval) (BIT(8) & ((uint32_t)(regval) << 8)) +#define USART_RTS_ENABLE CTL2_RTSEN(1) /*!< RTS hardware flow control enabled */ +#define USART_RTS_DISABLE CTL2_RTSEN(0) /*!< RTS hardware flow control disabled */ + +/* USART CTS hardware flow control configure */ +#define CTL2_CTSEN(regval) (BIT(9) & ((uint32_t)(regval) << 9)) +#define USART_CTS_ENABLE CTL2_CTSEN(1) /*!< CTS hardware flow control enabled */ +#define USART_CTS_DISABLE CTL2_CTSEN(0) /*!< CTS hardware flow control disabled */ + +/* USART one sample bit method configure */ +#define CTL2_OSB(regval) (BIT(11) & ((uint32_t)(regval) << 11)) +#define USART_OSB_1BIT CTL2_OSB(1) /*!< 1 sample bit */ +#define USART_OSB_3BIT CTL2_OSB(0) /*!< 3 sample bits */ + +/* USART driver enable polarity mode */ +#define CTL2_DEP(regval) (BIT(15) & ((uint32_t)(regval) << 15)) +#define USART_DEP_HIGH CTL2_DEP(0) /*!< DE signal is active high */ +#define USART_DEP_LOW CTL2_DEP(1) /*!< DE signal is active low */ + +/* USART wakeup mode from deep-sleep mode */ +#define CTL2_WUM(regval) (BITS(20,21) & ((uint32_t)(regval) << 20)) +#define USART_WUM_ADDR CTL2_WUM(0) /*!< WUF active on address match */ +#define USART_WUM_STARTB CTL2_WUM(2) /*!< WUF active on start bit */ +#define USART_WUM_RBNE CTL2_WUM(3) /*!< WUF active on RBNE */ + +/* USART hardware flow control coherence mode */ +#define CHC_HCM(regval) (BIT(0) & ((uint32_t)(regval) << 0)) +#define USART_HCM_NONE CHC_HCM(0) /*!< nRTS signal equals to the rxne status register */ +#define USART_HCM_EN CHC_HCM(1) /*!< nRTS signal is set when the last data bit has been sampled */ + +/* function declarations */ +/* initialization functions */ +/* reset USART */ +void usart_deinit(uint32_t usart_periph); +/* configure USART baud rate value */ +void usart_baudrate_set(uint32_t usart_periph, uint32_t baudval); +/* configure USART parity function */ +void usart_parity_config(uint32_t usart_periph, uint32_t paritycfg); +/* configure USART word length */ +void usart_word_length_set(uint32_t usart_periph, uint32_t wlen); +/* configure USART stop bit length */ +void usart_stop_bit_set(uint32_t usart_periph, uint32_t stblen); +/* enable USART */ +void usart_enable(uint32_t usart_periph); +/* disable USART */ +void usart_disable(uint32_t usart_periph); +/* configure USART transmitter */ +void usart_transmit_config(uint32_t usart_periph, uint32_t txconfig); +/* configure USART receiver */ +void usart_receive_config(uint32_t usart_periph, uint32_t rxconfig); + +/* USART normal mode communication */ +/* data is transmitted/received with the LSB/MSB first */ +void usart_data_first_config(uint32_t usart_periph, uint32_t msbf); +/* configure USART inverted */ +void usart_invert_config(uint32_t usart_periph, usart_invert_enum invertpara); +/* enable the USART overrun function */ +void usart_overrun_enable(uint32_t usart_periph); +/* disable the USART overrun function */ +void usart_overrun_disable(uint32_t usart_periph); +/* configure the USART oversample mode */ +void usart_oversample_config(uint32_t usart_periph, uint32_t oversamp); +/* configure sample bit method */ +void usart_sample_bit_config(uint32_t usart_periph, uint32_t osb); +/* enable receiver timeout */ +void usart_receiver_timeout_enable(uint32_t usart_periph); +/* disable receiver timeout */ +void usart_receiver_timeout_disable(uint32_t usart_periph); +/* configure receiver timeout threshold */ +void usart_receiver_timeout_threshold_config(uint32_t usart_periph, uint32_t rtimeout); +/* USART transmit data function */ +void usart_data_transmit(uint32_t usart_periph, uint32_t data); +/* USART receive data function */ +uint16_t usart_data_receive(uint32_t usart_periph); + +/* auto baud rate detection */ +/* enable auto baud rate detection */ +void usart_autobaud_detection_enable(uint32_t usart_periph); +/* disable auto baud rate detection */ +void usart_autobaud_detection_disable(uint32_t usart_periph); +/* configure auto baud rate detection mode */ +void usart_autobaud_detection_mode_config(uint32_t usart_periph, uint32_t abdmod); + +/* multi-processor communication */ +/* configure address of the USART */ +void usart_address_config(uint32_t usart_periph, uint8_t addr); +/* configure address detection mode */ +void usart_address_detection_mode_config(uint32_t usart_periph, uint32_t addmod); +/* enable mute mode */ +void usart_mute_mode_enable(uint32_t usart_periph); +/* disable mute mode */ +void usart_mute_mode_disable(uint32_t usart_periph); +/* configure wakeup method in mute mode */ +void usart_mute_mode_wakeup_config(uint32_t usart_periph, uint32_t wmethod); + +/* LIN mode communication */ +/* enable LIN mode */ +void usart_lin_mode_enable(uint32_t usart_periph); +/* disable LIN mode */ +void usart_lin_mode_disable(uint32_t usart_periph); +/* LIN break detection length */ +void usart_lin_break_detection_length_config(uint32_t usart_periph, uint32_t lblen); + +/* half-duplex communication */ +/* enable half-duplex mode */ +void usart_halfduplex_enable(uint32_t usart_periph); +/* disable half-duplex mode */ +void usart_halfduplex_disable(uint32_t usart_periph); + +/* synchronous communication */ +/* enable clock */ +void usart_clock_enable(uint32_t usart_periph); +/* disable clock */ +void usart_clock_disable(uint32_t usart_periph); +/* configure USART synchronous mode parameters */ +void usart_synchronous_clock_config(uint32_t usart_periph, uint32_t clen, uint32_t cph, uint32_t cpl); + +/* smartcard communication */ +/* configure guard time value in smartcard mode */ +void usart_guard_time_config(uint32_t usart_periph, uint32_t guat); +/* enable smartcard mode */ +void usart_smartcard_mode_enable(uint32_t usart_periph); +/* disable smartcard mode */ +void usart_smartcard_mode_disable(uint32_t usart_periph); +/* enable NACK in smartcard mode */ +void usart_smartcard_mode_nack_enable(uint32_t usart_periph); +/* disable NACK in smartcard mode */ +void usart_smartcard_mode_nack_disable(uint32_t usart_periph); +/* enable early NACK in smartcard mode */ +void usart_smartcard_mode_early_nack_enable(uint32_t usart_periph); +/* disable early NACK in smartcard mode */ +void usart_smartcard_mode_early_nack_disable(uint32_t usart_periph); +/* configure smartcard auto-retry number */ +void usart_smartcard_autoretry_config(uint32_t usart_periph, uint32_t scrtnum); +/* configure block length */ +void usart_block_length_config(uint32_t usart_periph, uint32_t bl); + +/* IrDA communication */ +/* enable IrDA mode */ +void usart_irda_mode_enable(uint32_t usart_periph); +/* disable IrDA mode */ +void usart_irda_mode_disable(uint32_t usart_periph); +/* configure the peripheral clock prescaler */ +void usart_prescaler_config(uint32_t usart_periph, uint32_t psc); +/* configure IrDA low-power */ +void usart_irda_lowpower_config(uint32_t usart_periph, uint32_t irlp); + +/* hardware flow communication */ +/* configure hardware flow control RTS */ +void usart_hardware_flow_rts_config(uint32_t usart_periph, uint32_t rtsconfig); +/* configure hardware flow control CTS */ +void usart_hardware_flow_cts_config(uint32_t usart_periph, uint32_t ctsconfig); + +/* coherence control */ +/* configure hardware flow control coherence mode */ +void usart_hardware_flow_coherence_config(uint32_t usart_periph, uint32_t hcm); + +/* enable RS485 driver */ +void usart_rs485_driver_enable(uint32_t usart_periph); +/* disable RS485 driver */ +void usart_rs485_driver_disable(uint32_t usart_periph); +/* configure driver enable assertion time */ +void usart_driver_assertime_config(uint32_t usart_periph, uint32_t deatime); +/* configure driver enable de-assertion time */ +void usart_driver_deassertime_config(uint32_t usart_periph, uint32_t dedtime); +/* configure driver enable polarity mode */ +void usart_depolarity_config(uint32_t usart_periph, uint32_t dep); + +/* USART DMA */ +/* configure USART DMA for reception */ +void usart_dma_receive_config(uint32_t usart_periph, uint32_t dmacmd); +/* configure USART DMA for transmission */ +void usart_dma_transmit_config(uint32_t usart_periph, uint32_t dmacmd); +/* disable DMA on reception error */ +void usart_reception_error_dma_disable(uint32_t usart_periph); +/* enable DMA on reception error */ +void usart_reception_error_dma_enable(uint32_t usart_periph); + +/* enable USART to wakeup the mcu from deep-sleep mode */ +void usart_wakeup_enable(uint32_t usart_periph); +/* disable USART to wakeup the mcu from deep-sleep mode */ +void usart_wakeup_disable(uint32_t usart_periph); +/* configure the USART wakeup mode from deep-sleep mode */ +void usart_wakeup_mode_config(uint32_t usart_periph, uint32_t wum); + +/* USART receive FIFO */ +/* enable receive FIFO */ +void usart_receive_fifo_enable(uint32_t usart_periph); +/* disable receive FIFO */ +void usart_receive_fifo_disable(uint32_t usart_periph); +/* read receive FIFO counter number */ +uint8_t usart_receive_fifo_counter_number(uint32_t usart_periph); + +/* flag & interrupt functions */ +/* get flag in STAT/RFCS register */ +FlagStatus usart_flag_get(uint32_t usart_periph, usart_flag_enum flag); +/* clear USART status */ +void usart_flag_clear(uint32_t usart_periph, usart_flag_enum flag); +/* enable USART interrupt */ +void usart_interrupt_enable(uint32_t usart_periph, usart_interrupt_enum inttype); +/* disable USART interrupt */ +void usart_interrupt_disable(uint32_t usart_periph, usart_interrupt_enum inttype); +/* enable USART command */ +void usart_command_enable(uint32_t usart_periph, uint32_t cmdtype); +/* get USART interrupt and flag status */ +FlagStatus usart_interrupt_flag_get(uint32_t usart_periph, usart_interrupt_flag_enum int_flag); +/* clear USART interrupt flag */ +void usart_interrupt_flag_clear(uint32_t usart_periph, usart_interrupt_flag_enum flag); + +#endif /* GD32E230_USART_H */ diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_wwdgt.h b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_wwdgt.h new file mode 100644 index 0000000000000000000000000000000000000000..38445b36de72758d14cddbe38042d17c41418a71 --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Include/gd32e230_wwdgt.h @@ -0,0 +1,88 @@ +/*! + \file gd32e230_wwdgt.h + \brief definitions for the WWDGT + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor 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 copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 GD32E230_WWDGT_H +#define GD32E230_WWDGT_H + +#include "gd32e230.h" + +/* WWDGT definitions */ +#define WWDGT WWDGT_BASE + +/* registers definitions */ +#define WWDGT_CTL REG32((WWDGT) + 0x00000000U) /*!< WWDGT control register */ +#define WWDGT_CFG REG32((WWDGT) + 0x00000004U) /*!< WWDGT configuration register */ +#define WWDGT_STAT REG32((WWDGT) + 0x00000008U) /*!< WWDGT status register */ + +/* bits definitions */ +/* WWDGT_CTL */ +#define WWDGT_CTL_CNT BITS(0,6) /*!< WWDGT counter value */ +#define WWDGT_CTL_WDGTEN BIT(7) /*!< WWDGT counter enable */ + +/* WWDGT_CFG */ +#define WWDGT_CFG_WIN BITS(0,6) /*!< WWDGT counter window value */ +#define WWDGT_CFG_PSC BITS(7,8) /*!< WWDGT prescaler divider value */ +#define WWDGT_CFG_EWIE BIT(9) /*!< WWDGT early wakeup interrupt enable */ + +/* WWDGT_STAT */ +#define WWDGT_STAT_EWIF BIT(0) /*!< WWDGT early wakeup interrupt flag */ + +/* constants definitions */ +#define CFG_PSC(regval) (BITS(7,8) & ((uint32_t)(regval) << 7U)) /*!< write value to WWDGT_CFG_PSC bit field */ +#define WWDGT_CFG_PSC_DIV1 ((uint32_t)CFG_PSC(0)) /*!< the time base of WWDGT = (PCLK1/4096)/1 */ +#define WWDGT_CFG_PSC_DIV2 ((uint32_t)CFG_PSC(1)) /*!< the time base of WWDGT = (PCLK1/4096)/2 */ +#define WWDGT_CFG_PSC_DIV4 ((uint32_t)CFG_PSC(2)) /*!< the time base of WWDGT = (PCLK1/4096)/4 */ +#define WWDGT_CFG_PSC_DIV8 ((uint32_t)CFG_PSC(3)) /*!< the time base of WWDGT = (PCLK1/4096)/8 */ + +/* function declarations */ +/* reset the window watchdog timer configuration */ +void wwdgt_deinit(void); +/* start the window watchdog timer counter */ +void wwdgt_enable(void); + +/* configure the window watchdog timer counter value */ +void wwdgt_counter_update(uint16_t counter_value); +/* configure counter value, window value, and prescaler divider value */ +void wwdgt_config(uint16_t counter, uint16_t window, uint32_t prescaler); + +/* enable early wakeup interrupt of WWDGT */ +void wwdgt_interrupt_enable(void); +/* check early wakeup interrupt state of WWDGT */ +FlagStatus wwdgt_flag_get(void); +/* clear early wakeup interrupt state of WWDGT */ +void wwdgt_flag_clear(void); + +#endif /* GD32E230_WWDGT_H */ diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_adc.c b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_adc.c new file mode 100644 index 0000000000000000000000000000000000000000..d0f706533627005ab4d6581f437846c2afdcce97 --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_adc.c @@ -0,0 +1,844 @@ +/*! + \file gd32e230_adc.c + \brief ADC driver + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor 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 copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 "gd32e230_adc.h" + +/*! + \brief reset ADC + \param[in] none + \param[out] none + \retval none +*/ +void adc_deinit(void) +{ + rcu_periph_reset_enable(RCU_ADCRST); + rcu_periph_reset_disable(RCU_ADCRST); +} + +/*! + \brief enable ADC interface + \param[in] none + \param[out] none + \retval none +*/ +void adc_enable(void) +{ + if(RESET == (ADC_CTL1 & ADC_CTL1_ADCON)){ + ADC_CTL1 |= (uint32_t)ADC_CTL1_ADCON; + } +} + +/*! + \brief disable ADC interface + \param[in] none + \param[out] none + \retval none +*/ +void adc_disable(void) +{ + ADC_CTL1 &= ~((uint32_t)ADC_CTL1_ADCON); +} + +/*! + \brief ADC calibration and reset calibration + \param[in] none + \param[out] none + \retval none +*/ +void adc_calibration_enable(void) +{ + /* reset the selected ADC calibration register */ + ADC_CTL1 |= (uint32_t) ADC_CTL1_RSTCLB; + /* check the RSTCLB bit state */ + while((ADC_CTL1 & ADC_CTL1_RSTCLB)){ + } + + /* enable ADC calibration process */ + ADC_CTL1 |= ADC_CTL1_CLB; + /* check the CLB bit state */ + while((ADC_CTL1 & ADC_CTL1_CLB)){ + } +} + +/*! + \brief enable DMA request + \param[in] none + \param[out] none + \retval none +*/ +void adc_dma_mode_enable(void) +{ + ADC_CTL1 |= (uint32_t)(ADC_CTL1_DMA); +} + +/*! + \brief disable DMA request + \param[in] none + \param[out] none + \retval none +*/ +void adc_dma_mode_disable(void) +{ + ADC_CTL1 &= ~((uint32_t)ADC_CTL1_DMA); +} + +/*! + \brief enable the temperature sensor and Vrefint channel + \param[in] none + \param[out] none + \retval none +*/ +void adc_tempsensor_vrefint_enable(void) +{ + /* enable the temperature sensor and Vrefint channel */ + ADC_CTL1 |= ADC_CTL1_TSVREN; +} + +/*! + \brief disable the temperature sensor and Vrefint channel + \param[in] none + \param[out] none + \retval none +*/ +void adc_tempsensor_vrefint_disable(void) +{ + /* disable the temperature sensor and Vrefint channel */ + ADC_CTL1 &= ~ADC_CTL1_TSVREN; +} + +/*! + \brief configure ADC discontinuous mode + \param[in] channel_group: select the channel group + only one parameter can be selected which is shown as below: + \arg ADC_REGULAR_CHANNEL: regular channel group + \arg ADC_INSERTED_CHANNEL: inserted channel group + \arg ADC_CHANNEL_DISCON_DISABLE: disable discontinuous mode of regular and inserted channel + \param[in] length: number of conversions in discontinuous mode, the number can be 1..8 + for regular channel, the number has no effect for inserted channel + \param[out] none + \retval none +*/ +void adc_discontinuous_mode_config(uint8_t channel_group, uint8_t length) +{ + ADC_CTL0 &= ~((uint32_t)(ADC_CTL0_DISRC | ADC_CTL0_DISIC)); + + switch(channel_group){ + case ADC_REGULAR_CHANNEL: + /* configure the number of conversions in discontinuous mode */ + ADC_CTL0 &= ~((uint32_t)ADC_CTL0_DISNUM); + ADC_CTL0 |= CTL0_DISNUM(((uint32_t)length - 1U)); + ADC_CTL0 |= (uint32_t)ADC_CTL0_DISRC; + break; + case ADC_INSERTED_CHANNEL: + ADC_CTL0 |= (uint32_t)ADC_CTL0_DISIC; + break; + case ADC_CHANNEL_DISCON_DISABLE: + default: + break; + } +} + +/*! + \brief configure ADC special function + \param[in] function: the function to configure + one or more parameters can be selected which is shown as below: + \arg ADC_SCAN_MODE: scan mode select + \arg ADC_INSERTED_CHANNEL_AUTO: inserted channel group convert automatically + \arg ADC_CONTINUOUS_MODE: continuous mode select + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void adc_special_function_config(uint32_t function, ControlStatus newvalue) +{ + if(newvalue){ + /* enable ADC scan mode */ + if(RESET != (function & ADC_SCAN_MODE)){ + ADC_CTL0 |= ADC_SCAN_MODE; + } + /* enable ADC inserted channel group convert automatically */ + if(RESET != (function & ADC_INSERTED_CHANNEL_AUTO)){ + ADC_CTL0 |= ADC_INSERTED_CHANNEL_AUTO; + } + /* enable ADC continuous mode */ + if(RESET != (function & ADC_CONTINUOUS_MODE)){ + ADC_CTL1 |= ADC_CONTINUOUS_MODE; + } + }else{ + /* disable ADC scan mode */ + if(RESET != (function & ADC_SCAN_MODE)){ + ADC_CTL0 &= ~ADC_SCAN_MODE; + } + /* disable ADC inserted channel group convert automatically */ + if(RESET != (function & ADC_INSERTED_CHANNEL_AUTO)){ + ADC_CTL0 &= ~ADC_INSERTED_CHANNEL_AUTO; + } + /* disable ADC continuous mode */ + if(RESET != (function & ADC_CONTINUOUS_MODE)){ + ADC_CTL1 &= ~ADC_CONTINUOUS_MODE; + } + } +} + +/*! + \brief configure ADC data alignment + \param[in] data_alignment: data alignment select + only one parameter can be selected which is shown as below: + \arg ADC_DATAALIGN_RIGHT: right alignment + \arg ADC_DATAALIGN_LEFT: left alignment + \param[out] none + \retval none +*/ +void adc_data_alignment_config(uint32_t data_alignment) +{ + if(ADC_DATAALIGN_RIGHT != data_alignment){ + ADC_CTL1 |= ADC_CTL1_DAL; + }else{ + ADC_CTL1 &= ~((uint32_t)ADC_CTL1_DAL); + } +} + +/*! + \brief configure the length of regular channel group or inserted channel group + \param[in] channel_group: select the channel group + only one parameter can be selected which is shown as below: + \arg ADC_REGULAR_CHANNEL: regular channel group + \arg ADC_INSERTED_CHANNEL: inserted channel group + \param[in] length: the length of the channel + regular channel 1-16 + inserted channel 1-4 + \param[out] none + \retval none +*/ +void adc_channel_length_config(uint8_t channel_group, uint32_t length) +{ + switch(channel_group){ + case ADC_REGULAR_CHANNEL: + /* configure the length of regular channel group */ + ADC_RSQ0 &= ~((uint32_t)ADC_RSQ0_RL); + ADC_RSQ0 |= RSQ0_RL((uint32_t)(length-1U)); + break; + case ADC_INSERTED_CHANNEL: + /* configure the length of inserted channel group */ + ADC_ISQ &= ~((uint32_t)ADC_ISQ_IL); + ADC_ISQ |= ISQ_IL((uint32_t)(length-1U)); + break; + default: + break; + } +} + +/*! + \brief configure ADC regular channel + \param[in] rank: the regular group sequence rank, this parameter must be between 0 to 15 + \param[in] channel: the selected ADC channel + only one parameter can be selected which is shown as below: + \arg ADC_CHANNEL_x(x=0..9,16,17): ADC Channelx + \param[in] sample_time: the sample time value + only one parameter can be selected which is shown as below: + \arg ADC_SAMPLETIME_1POINT5: 1.5 cycles + \arg ADC_SAMPLETIME_7POINT5: 7.5 cycles + \arg ADC_SAMPLETIME_13POINT5: 13.5 cycles + \arg ADC_SAMPLETIME_28POINT5: 28.5 cycles + \arg ADC_SAMPLETIME_41POINT5: 41.5 cycles + \arg ADC_SAMPLETIME_55POINT5: 55.5 cycles + \arg ADC_SAMPLETIME_71POINT5: 71.5 cycles + \arg ADC_SAMPLETIME_239POINT5: 239.5 cycles + \param[out] none + \retval none +*/ +void adc_regular_channel_config(uint8_t rank, uint8_t channel, uint32_t sample_time) +{ + uint32_t rsq,sampt; + + /* configure ADC regular sequence */ + if(rank < 6U){ + rsq = ADC_RSQ2; + rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (5U*rank))); + rsq |= ((uint32_t)channel << (5U*rank)); + ADC_RSQ2 = rsq; + }else if(rank < 12U){ + rsq = ADC_RSQ1; + rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (5U*(rank-6U)))); + rsq |= ((uint32_t)channel << (5U*(rank-6U))); + ADC_RSQ1 = rsq; + }else if(rank < 16U){ + rsq = ADC_RSQ0; + rsq &= ~((uint32_t)(ADC_RSQX_RSQN << (5U*(rank-12U)))); + rsq |= ((uint32_t)channel << (5U*(rank-12U))); + ADC_RSQ0 = rsq; + }else{ + } + + /* configure ADC sampling time */ + if(channel < 10U){ + sampt = ADC_SAMPT1; + sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (3U*channel))); + sampt |= (uint32_t)(sample_time << (3U*channel)); + ADC_SAMPT1 = sampt; + }else if(channel < 19U){ + sampt = ADC_SAMPT0; + sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (3U*(channel-10U)))); + sampt |= (uint32_t)(sample_time << (3U*(channel-10U))); + ADC_SAMPT0 = sampt; + }else{ + /* illegal parameters */ + } +} + +/*! + \brief configure ADC inserted channel + \param[in] rank: the inserted group sequencer rank,this parameter must be between 0 to 3 + \param[in] channel: the selected ADC channel + only one parameter can be selected which is shown as below: + \arg ADC_CHANNEL_x(x=0..9,16,17): ADC Channelx + \param[in] sample_time: The sample time value + only one parameter can be selected which is shown as below: + \arg ADC_SAMPLETIME_1POINT5: 1.5 cycles + \arg ADC_SAMPLETIME_7POINT5: 7.5 cycles + \arg ADC_SAMPLETIME_13POINT5: 13.5 cycles + \arg ADC_SAMPLETIME_28POINT5: 28.5 cycles + \arg ADC_SAMPLETIME_41POINT5: 41.5 cycles + \arg ADC_SAMPLETIME_55POINT5: 55.5 cycles + \arg ADC_SAMPLETIME_71POINT5: 71.5 cycles + \arg ADC_SAMPLETIME_239POINT5: 239.5 cycles + \param[out] none + \retval none +*/ +void adc_inserted_channel_config(uint8_t rank, uint8_t channel, uint32_t sample_time) +{ + uint8_t inserted_length; + uint32_t isq,sampt; + + inserted_length = (uint8_t)GET_BITS(ADC_ISQ , 20U , 21U); + + isq = ADC_ISQ; + isq &= ~((uint32_t)(ADC_ISQ_ISQN << (15U - (inserted_length - rank)*5U))); + isq |= ((uint32_t)channel << (15U - (inserted_length - rank)*5U)); + ADC_ISQ = isq; + + /* configure ADC sampling time */ + if(channel < 10U){ + sampt = ADC_SAMPT1; + sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (3U*channel))); + sampt |= (uint32_t) sample_time << (3U*channel); + ADC_SAMPT1 = sampt; + }else if(channel < 19U){ + sampt = ADC_SAMPT0; + sampt &= ~((uint32_t)(ADC_SAMPTX_SPTN << (3U*(channel - 10U)))); + sampt |= ((uint32_t)sample_time << (3U*(channel - 10U))); + ADC_SAMPT0 = sampt; + }else{ + /* illegal parameters */ + } +} + +/*! + \brief configure ADC inserted channel offset + \param[in] inserted_channel: insert channel select + only one parameter can be selected which is shown as below: + \arg ADC_INSERTED_CHANNEL_0: ADC inserted channel 0 + \arg ADC_INSERTED_CHANNEL_1: ADC inserted channel 1 + \arg ADC_INSERTED_CHANNEL_2: ADC inserted channel 2 + \arg ADC_INSERTED_CHANNEL_3: ADC inserted channel 3 + \param[in] offset: the offset data + \param[out] none + \retval none +*/ +void adc_inserted_channel_offset_config(uint8_t inserted_channel, uint16_t offset) +{ + uint8_t inserted_length; + uint32_t num = 0U; + + inserted_length = (uint8_t)GET_BITS(ADC_ISQ, 20U, 21U); + num = 3U - (inserted_length - inserted_channel); + + if(num <= 3U){ + /* calculate the offset of the register */ + num = num * 4U; + /* configure the offset of the selected channels */ + REG32((ADC) + 0x14U + num) = IOFFX_IOFF((uint32_t)offset); + } +} + +/*! + \brief enable or disable ADC external trigger + \param[in] channel_group: select the channel group + one or more parameters can be selected which is shown as below: + \arg ADC_REGULAR_CHANNEL: regular channel group + \arg ADC_INSERTED_CHANNEL: inserted channel group + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void adc_external_trigger_config(uint8_t channel_group, ControlStatus newvalue) +{ + if(newvalue){ + /* external trigger enable for regular channel */ + if(RESET != (channel_group & ADC_REGULAR_CHANNEL)){ + ADC_CTL1 |= ADC_CTL1_ETERC; + } + /* external trigger enable for inserted channel */ + if(RESET != (channel_group & ADC_INSERTED_CHANNEL)){ + ADC_CTL1 |= ADC_CTL1_ETEIC; + } + }else{ + /* external trigger disable for regular channel */ + if(RESET != (channel_group & ADC_REGULAR_CHANNEL)){ + ADC_CTL1 &= ~ADC_CTL1_ETERC; + } + /* external trigger disable for inserted channel */ + if(RESET != (channel_group & ADC_INSERTED_CHANNEL)){ + ADC_CTL1 &= ~ADC_CTL1_ETEIC; + } + } +} + +/*! + \brief configure ADC external trigger source + \param[in] channel_group: select the channel group + only one parameter can be selected which is shown as below: + \arg ADC_REGULAR_CHANNEL: regular channel group + \arg ADC_INSERTED_CHANNEL: inserted channel group + \param[in] external_trigger_source: regular or inserted group trigger source + only one parameter can be selected which is shown as below: + for regular channel: + \arg ADC_EXTTRIG_REGULAR_T0_CH0: TIMER0 CH0 event select + \arg ADC_EXTTRIG_REGULAR_T0_CH1: TIMER0 CH1 event select + \arg ADC_EXTTRIG_REGULAR_T0_CH2: TIMER0 CH2 event select + \arg ADC_EXTTRIG_REGULAR_T2_TRGO: TIMER2 TRGO event select + \arg ADC_EXTTRIG_REGULAR_T14_CH0: TIMER14 CH0 event select + \arg ADC_EXTTRIG_REGULAR_EXTI_11: external interrupt line 11 + \arg ADC_EXTTRIG_REGULAR_NONE: software trigger + for inserted channel: + \arg ADC_EXTTRIG_INSERTED_T0_TRGO: TIMER0 TRGO event select + \arg ADC_EXTTRIG_INSERTED_T0_CH3: TIMER0 CH3 event select + \arg ADC_EXTTRIG_INSERTED_T2_CH3: TIMER2 CH3 event select + \arg ADC_EXTTRIG_INSERTED_T14_TRGO: TIMER14 TRGO event select + \arg ADC_EXTTRIG_INSERTED_EXTI_15: external interrupt line 15 + \arg ADC_EXTTRIG_INSERTED_NONE: software trigger + \param[out] none + \retval none +*/ +void adc_external_trigger_source_config(uint8_t channel_group, uint32_t external_trigger_source) +{ + switch(channel_group){ + case ADC_REGULAR_CHANNEL: + /* external trigger select for regular channel */ + ADC_CTL1 &= ~((uint32_t)ADC_CTL1_ETSRC); + ADC_CTL1 |= (uint32_t)external_trigger_source; + break; + case ADC_INSERTED_CHANNEL: + /* external trigger select for inserted channel */ + ADC_CTL1 &= ~((uint32_t)ADC_CTL1_ETSIC); + ADC_CTL1 |= (uint32_t)external_trigger_source; + break; + default: + break; + } +} + +/*! + \brief enable ADC software trigger + \param[in] channel_group: select the channel group + one or more parameters can be selected which is shown as below: + \arg ADC_REGULAR_CHANNEL: regular channel group + \arg ADC_INSERTED_CHANNEL: inserted channel group + \param[out] none + \retval none +*/ +void adc_software_trigger_enable(uint8_t channel_group) +{ + /* enable regular group channel software trigger */ + if(RESET != (channel_group & ADC_REGULAR_CHANNEL)){ + ADC_CTL1 |= ADC_CTL1_SWRCST; + } + /* enable inserted channel group software trigger */ + if(RESET != (channel_group & ADC_INSERTED_CHANNEL)){ + ADC_CTL1 |= ADC_CTL1_SWICST; + } +} + +/*! + \brief read ADC regular group data register + \param[in] none + \param[out] none + \retval the conversion value +*/ +uint16_t adc_regular_data_read(void) +{ + return ((uint16_t)ADC_RDATA); +} + +/*! + \brief read ADC inserted group data register + \param[in] inserted_channel: inserted channel select + only one parameter can be selected which is shown as below: + \arg ADC_INSERTED_CHANNEL_0: ADC inserted channel 0 + \arg ADC_INSERTED_CHANNEL_1: ADC inserted channel 1 + \arg ADC_INSERTED_CHANNEL_2: ADC inserted channel 2 + \arg ADC_INSERTED_CHANNEL_3: ADC inserted channel 3 + \param[out] none + \retval the conversion value +*/ +uint16_t adc_inserted_data_read(uint8_t inserted_channel) +{ + uint32_t idata; + /* read the data of the selected channel */ + switch(inserted_channel){ + case ADC_INSERTED_CHANNEL_0: + idata = ADC_IDATA0; + break; + case ADC_INSERTED_CHANNEL_1: + idata = ADC_IDATA1; + break; + case ADC_INSERTED_CHANNEL_2: + idata = ADC_IDATA2; + break; + case ADC_INSERTED_CHANNEL_3: + idata = ADC_IDATA3; + break; + default: + idata = 0U; + break; + } + return (uint16_t)idata; +} + +/*! + \brief get the ADC flag bits + \param[in] flag: the adc flag bits + only one parameter can be selected which is shown as below: + \arg ADC_FLAG_WDE: analog watchdog event flag + \arg ADC_FLAG_EOC: end of group conversion flag + \arg ADC_FLAG_EOIC: end of inserted group conversion flag + \arg ADC_FLAG_STIC: start flag of inserted channel group + \arg ADC_FLAG_STRC: start flag of regular channel group + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus adc_flag_get(uint32_t flag) +{ + FlagStatus reval = RESET; + + if(ADC_STAT & flag){ + reval = SET; + } + return reval; +} + +/*! + \brief clear the ADC flag + \param[in] flag: the adc flag + one or more parameters can be selected which is shown as below: + \arg ADC_FLAG_WDE: analog watchdog event flag + \arg ADC_FLAG_EOC: end of group conversion flag + \arg ADC_FLAG_EOIC: end of inserted group conversion flag + \arg ADC_FLAG_STIC: start flag of inserted channel group + \arg ADC_FLAG_STRC: start flag of regular channel group + \param[out] none + \retval none +*/ +void adc_flag_clear(uint32_t flag) +{ + ADC_STAT &= ~((uint32_t)flag); +} + +/*! + \brief get the ADC interrupt flag + \param[in] flag: the adc interrupt flag + only one parameter can be selected which is shown as below: + \arg ADC_INT_FLAG_WDE: analog watchdog interrupt flag + \arg ADC_INT_FLAG_EOC: end of group conversion interrupt flag + \arg ADC_INT_FLAG_EOIC: end of inserted group conversion interrupt flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus adc_interrupt_flag_get(uint32_t flag) +{ + FlagStatus interrupt_flag = RESET; + uint32_t state; + + /* check the interrupt bits */ + switch(flag){ + case ADC_INT_FLAG_WDE: + state = ADC_STAT & ADC_STAT_WDE; + if((ADC_CTL0 & ADC_CTL0_WDEIE) && state){ + interrupt_flag = SET; + } + break; + case ADC_INT_FLAG_EOC: + state = ADC_STAT & ADC_STAT_EOC; + if((ADC_CTL0 & ADC_CTL0_EOCIE) && state){ + interrupt_flag = SET; + } + break; + case ADC_INT_FLAG_EOIC: + state = ADC_STAT & ADC_STAT_EOIC; + if((ADC_CTL0 & ADC_CTL0_EOICIE) && state){ + interrupt_flag = SET; + } + break; + default: + break; + } + return interrupt_flag; +} + +/*! + \brief clear ADC interrupt flag + \param[in] flag: the adc interrupt flag + only one parameter can be selected which is shown as below: + \arg ADC_INT_FLAG_WDE: analog watchdog interrupt flag + \arg ADC_INT_FLAG_EOC: end of group conversion interrupt flag + \arg ADC_INT_FLAG_EOIC: end of inserted group conversion interrupt flag + \param[out] none + \retval none +*/ +void adc_interrupt_flag_clear(uint32_t flag) +{ + ADC_STAT &= ~((uint32_t)flag); +} + +/*! + \brief enable ADC interrupt + \param[in] interrupt: the adc interrupt + one or more parameters can be selected which is shown as below: + \arg ADC_INT_WDE: analog watchdog interrupt + \arg ADC_INT_EOC: end of group conversion interrupt + \arg ADC_INT_EOIC: end of inserted group conversion interrupt + \param[out] none + \retval none +*/ +void adc_interrupt_enable(uint32_t interrupt) +{ + /* enable analog watchdog interrupt */ + if(RESET != (interrupt & ADC_INT_WDE)){ + ADC_CTL0 |= (uint32_t)ADC_CTL0_WDEIE; + } + + /* enable end of group conversion interrupt */ + if(RESET != (interrupt & ADC_INT_EOC)){ + ADC_CTL0 |= (uint32_t)ADC_CTL0_EOCIE; + } + + /* enable end of inserted group conversion interrupt */ + if(RESET != (interrupt & ADC_INT_EOIC)){ + ADC_CTL0 |= (uint32_t)ADC_CTL0_EOICIE; + } +} + +/*! + \brief disable ADC interrupt + \param[in] interrupt: the adc interrupt flag + one or more parameters can be selected which is shown as below: + \arg ADC_INT_WDE: analog watchdog interrupt + \arg ADC_INT_EOC: end of group conversion interrupt + \arg ADC_INT_EOIC: end of inserted group conversion interrupt + \param[out] none + \retval none +*/ +void adc_interrupt_disable(uint32_t interrupt) +{ + /* disable analog watchdog interrupt */ + if(RESET != (interrupt & ADC_INT_WDE)){ + ADC_CTL0 &= ~(uint32_t)ADC_CTL0_WDEIE; + } + + /* disable end of group conversion interrupt */ + if(RESET != (interrupt & ADC_INT_EOC)){ + ADC_CTL0 &= ~(uint32_t)ADC_CTL0_EOCIE; + } + + /* disable end of inserted group conversion interrupt */ + if(RESET != (interrupt & ADC_INT_EOIC)){ + ADC_CTL0 &= ~(uint32_t)ADC_CTL0_EOICIE; + } +} + +/*! + \brief configure ADC analog watchdog single channel + \param[in] channel: the selected ADC channel + only one parameter can be selected which is shown as below: + \arg ADC_CHANNEL_x(x=0..9,16,17): ADC Channelx + \param[out] none + \retval none +*/ +void adc_watchdog_single_channel_enable(uint8_t channel) +{ + ADC_CTL0 &= (uint32_t)~(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN | ADC_CTL0_WDSC | ADC_CTL0_WDCHSEL); + + ADC_CTL0 |= (uint32_t)channel; + ADC_CTL0 |= (uint32_t)(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN | ADC_CTL0_WDSC); +} + +/*! + \brief configure ADC analog watchdog group channel + \param[in] channel_group: the channel group use analog watchdog + only one parameter can be selected which is shown as below: + \arg ADC_REGULAR_CHANNEL: regular channel group + \arg ADC_INSERTED_CHANNEL: inserted channel group + \arg ADC_REGULAR_INSERTED_CHANNEL: both regular and inserted group + \param[out] none + \retval none +*/ +void adc_watchdog_group_channel_enable(uint8_t channel_group) +{ + ADC_CTL0 &= (uint32_t)~(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN | ADC_CTL0_WDSC); + + /* select the group */ + switch(channel_group){ + case ADC_REGULAR_CHANNEL: + ADC_CTL0 |= (uint32_t)ADC_CTL0_RWDEN; + break; + case ADC_INSERTED_CHANNEL: + ADC_CTL0 |= (uint32_t)ADC_CTL0_IWDEN; + break; + case ADC_REGULAR_INSERTED_CHANNEL: + ADC_CTL0 |= (uint32_t)(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN); + break; + default: + break; + } +} + +/*! + \brief disable ADC analog watchdog + \param[in] none + \param[out] none + \retval none +*/ +void adc_watchdog_disable(void) +{ + ADC_CTL0 &= (uint32_t)~(ADC_CTL0_RWDEN | ADC_CTL0_IWDEN | ADC_CTL0_WDSC | ADC_CTL0_WDCHSEL); +} + +/*! + \brief configure ADC analog watchdog threshold + \param[in] low_threshold: analog watchdog low threshold,0..4095 + \param[in] high_threshold: analog watchdog high threshold,0..4095 + \param[out] none + \retval none +*/ +void adc_watchdog_threshold_config(uint16_t low_threshold, uint16_t high_threshold) +{ + ADC_WDLT = (uint32_t)WDLT_WDLT(low_threshold); + ADC_WDHT = (uint32_t)WDHT_WDHT(high_threshold); +} + + +/*! + \brief configure ADC resolution + \param[in] resolution: ADC resolution + only one parameter can be selected which is shown as below: + \arg ADC_RESOLUTION_12B: 12-bit ADC resolution + \arg ADC_RESOLUTION_10B: 10-bit ADC resolution + \arg ADC_RESOLUTION_8B: 8-bit ADC resolution + \arg ADC_RESOLUTION_6B: 6-bit ADC resolution + \param[out] none + \retval none +*/ +void adc_resolution_config(uint32_t resolution) +{ + ADC_CTL0 &= ~((uint32_t)ADC_CTL0_DRES); + ADC_CTL0 |= (uint32_t)resolution; +} + +/*! + \brief configure ADC oversample mode + \param[in] mode: ADC oversampling mode + only one parameter can be selected which is shown as below: + \arg ADC_OVERSAMPLING_ALL_CONVERT: all oversampled conversions for a channel are done consecutively after a trigger + \arg ADC_OVERSAMPLING_ONE_CONVERT: each oversampled conversion for a channel needs a trigger + \param[in] shift: ADC oversampling shift + only one parameter can be selected which is shown as below: + \arg ADC_OVERSAMPLING_SHIFT_NONE: no oversampling shift + \arg ADC_OVERSAMPLING_SHIFT_1B: 1-bit oversampling shift + \arg ADC_OVERSAMPLING_SHIFT_2B: 2-bit oversampling shift + \arg ADC_OVERSAMPLING_SHIFT_3B: 3-bit oversampling shift + \arg ADC_OVERSAMPLING_SHIFT_4B: 3-bit oversampling shift + \arg ADC_OVERSAMPLING_SHIFT_5B: 5-bit oversampling shift + \arg ADC_OVERSAMPLING_SHIFT_6B: 6-bit oversampling shift + \arg ADC_OVERSAMPLING_SHIFT_7B: 7-bit oversampling shift + \arg ADC_OVERSAMPLING_SHIFT_8B: 8-bit oversampling shift + \param[in] ratio: ADC oversampling ratio + only one parameter can be selected which is shown as below: + \arg ADC_OVERSAMPLING_RATIO_MUL2: oversampling ratio multiple 2 + \arg ADC_OVERSAMPLING_RATIO_MUL4: oversampling ratio multiple 4 + \arg ADC_OVERSAMPLING_RATIO_MUL8: oversampling ratio multiple 8 + \arg ADC_OVERSAMPLING_RATIO_MUL16: oversampling ratio multiple 16 + \arg ADC_OVERSAMPLING_RATIO_MUL32: oversampling ratio multiple 32 + \arg ADC_OVERSAMPLING_RATIO_MUL64: oversampling ratio multiple 64 + \arg ADC_OVERSAMPLING_RATIO_MUL128: oversampling ratio multiple 128 + \arg ADC_OVERSAMPLING_RATIO_MUL256: oversampling ratio multiple 256 + \param[out] none + \retval none +*/ +void adc_oversample_mode_config(uint8_t mode, uint16_t shift, uint8_t ratio) +{ + /* configure ADC oversampling mode */ + if(ADC_OVERSAMPLING_ONE_CONVERT == mode){ + ADC_OVSAMPCTL |= (uint32_t)ADC_OVSAMPCTL_TOVS; + }else{ + ADC_OVSAMPCTL &= ~((uint32_t)ADC_OVSAMPCTL_TOVS); + } + + /* configure the shift and ratio */ + ADC_OVSAMPCTL &= ~((uint32_t)(ADC_OVSAMPCTL_OVSR | ADC_OVSAMPCTL_OVSS)); + ADC_OVSAMPCTL |= ((uint32_t)shift | (uint32_t)ratio); +} + +/*! + \brief enable ADC oversample mode + \param[in] none + \param[out] none + \retval none +*/ +void adc_oversample_mode_enable(void) +{ + ADC_OVSAMPCTL |= ADC_OVSAMPCTL_OVSEN; +} + +/*! + \brief disable ADC oversample mode + \param[in] none + \param[out] none + \retval none +*/ +void adc_oversample_mode_disable(void) +{ + ADC_OVSAMPCTL &= ~((uint32_t)ADC_OVSAMPCTL_OVSEN); +} diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_cmp.c b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_cmp.c new file mode 100644 index 0000000000000000000000000000000000000000..46ef66cbcf9394bd7cae9f6d35f632be0fd3c482 --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_cmp.c @@ -0,0 +1,180 @@ +/*! + \file gd32e230_cmp.c + \brief CMP driver + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor 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 copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 "gd32e230_cmp.h" + +/*! + \brief deinitialize comparator + \param[in] none + \param[out] none + \retval none +*/ +void cmp_deinit(void) +{ + CMP_CS = ((uint32_t)0x00000000U); +} + +/*! + \brief initialize comparator mode + \param[in] operating_mode + \arg CMP_HIGHSPEED: high speed mode + \arg CMP_MIDDLESPEED: medium speed mode + \arg CMP_LOWSPEED: low speed mode + \arg CMP_VERYLOWSPEED: very-low speed mode + \param[in] inverting_input + \arg CMP_1_4VREFINT: VREFINT *1/4 input + \arg CMP_1_2VREFINT: VREFINT *1/2 input + \arg CMP_3_4VREFINT: VREFINT *3/4 input + \arg CMP_VREFINT: VREFINT input + \arg CMP_PA4: PA4 input + \arg CMP_PA5: PA5 input + \arg CMP_PA0: PA0 input + \arg CMP_PA2: PA2 input + \param[in] hysteresis + \arg CMP_HYSTERESIS_NO: output no hysteresis + \arg CMP_HYSTERESIS_LOW: output low hysteresis + \arg CMP_HYSTERESIS_MIDDLE: output middle hysteresis + \arg CMP_HYSTERESIS_HIGH: output high hysteresis + \param[out] none + \retval none +*/ +void cmp_mode_init(operating_mode_enum operating_mode, inverting_input_enum inverting_input, cmp_hysteresis_enum output_hysteresis) +{ + /* initialize comparator mode */ + CMP_CS |= CS_CMPM(operating_mode) | CS_CMPMSEL(inverting_input) | CS_CMPHST(output_hysteresis); + +} + +/*! + \brief initialize comparator output + \param[in] output_slection + \arg CMP_OUTPUT_NONE: output no selection + \arg CMP_OUTPUT_TIMER0BKIN: TIMER 0 break input + \arg CMP_OUTPUT_TIMER0IC0: TIMER 0 channel0 input capture + \arg CMP_OUTPUT_TIMER0OCPRECLR: TIMER 0 OCPRE_CLR input + \arg CMP_OUTPUT_TIMER2IC0: TIMER 2 channel0 input capture + \arg CMP_OUTPUT_TIMER2OCPRECLR: TIMER 2 OCPRE_CLR input + \param[in] output_polarity + \arg CMP_OUTPUT_POLARITY_INVERTED: output is inverted + \arg CMP_OUTPUT_POLARITY_NOINVERTED: output is not inverted + \param[out] none + \retval none +*/ +void cmp_output_init(cmp_output_enum output_slection, uint32_t output_polarity) +{ + /* initialize comparator output */ + + CMP_CS |= CS_CMPOSEL(output_slection); + /* output polarity */ + if(CMP_OUTPUT_POLARITY_INVERTED == output_polarity){ + CMP_CS |= CMP_CS_CMPPL; + }else{ + CMP_CS &= ~CMP_CS_CMPPL; + } + +} + +/*! + \brief enable comparator + \param[in] none + \param[out] none + \retval none +*/ +void cmp_enable(void) +{ + CMP_CS |= CMP_CS_CMPEN; +} + +/*! + \brief disable comparator + \param[in] none + \param[out] none + \retval none +*/ +void cmp_disable(void) +{ + CMP_CS &= ~CMP_CS_CMPEN; +} + +/*! + \brief enable comparator switch + \param[in] none + \param[out] none + \retval none +*/ +void cmp_switch_enable(void) +{ + CMP_CS |= CMP_CS_CMPSW; +} + +/*! + \brief disable comparator switch + \param[in] none + \param[out] none + \retval none +*/ +void cmp_switch_disable(void) +{ + CMP_CS &= ~CMP_CS_CMPSW; +} + +/*! + \brief get output level + \param[in] none + \param[out] none + \retval the output level +*/ +uint32_t cmp_output_level_get(void) +{ + if(CMP_CS & CMP_CS_CMPO){ + return CMP_OUTPUTLEVEL_HIGH; + }else{ + return CMP_OUTPUTLEVEL_LOW; + } + +} + +/*! + \brief lock the comparator + \param[in] none + \param[out] none + \retval none +*/ +void cmp_lock_enable(void) +{ + CMP_CS |= CMP_CS_CMPLK; +} + diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_crc.c b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_crc.c new file mode 100644 index 0000000000000000000000000000000000000000..59391d7d386d628c01afdf67c4ef4024de1cb8cb --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_crc.c @@ -0,0 +1,206 @@ +/*! + \file gd32e230_crc.c + \brief CRC driver + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor 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 copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 "gd32e230_crc.h" + +/*! + \brief deinit CRC calculation unit + \param[in] none + \param[out] none + \retval none +*/ +void crc_deinit(void) +{ + CRC_IDATA = (uint32_t)0xFFFFFFFFU; + CRC_DATA = (uint32_t)0xFFFFFFFFU; + CRC_FDATA = (uint32_t)0x00000000U; + CRC_POLY = (uint32_t)0x04C11DB7U; + CRC_CTL = CRC_CTL_RST; +} + +/*! + \brief enable the reverse operation of output data + \param[in] none + \param[out] none + \retval none +*/ +void crc_reverse_output_data_enable(void) +{ + CRC_CTL &= (uint32_t)(~ CRC_CTL_REV_O); + CRC_CTL |= (uint32_t)CRC_CTL_REV_O; +} + +/*! + \brief disable the reverse operation of output data + \param[in] none + \param[out] none + \retval none +*/ +void crc_reverse_output_data_disable(void) +{ + CRC_CTL &= (uint32_t)(~ CRC_CTL_REV_O); +} + +/*! + \brief reset data register to the value of initializaiton data register + \param[in] none + \param[out] none + \retval none +*/ +void crc_data_register_reset(void) +{ + CRC_CTL |= (uint32_t)CRC_CTL_RST; +} + +/*! + \brief read the data register + \param[in] none + \param[out] none + \retval 32-bit value of the data register +*/ +uint32_t crc_data_register_read(void) +{ + uint32_t data; + data = CRC_DATA; + return (data); +} + +/*! + \brief read the free data register + \param[in] none + \param[out] none + \retval 8-bit value of the free data register +*/ +uint8_t crc_free_data_register_read(void) +{ + uint8_t fdata; + fdata = (uint8_t)CRC_FDATA; + return (fdata); +} + +/*! + \brief write the free data register + \param[in] free_data: specify 8-bit data + \param[out] none + \retval none +*/ +void crc_free_data_register_write(uint8_t free_data) +{ + CRC_FDATA = (uint32_t)free_data; +} + +/*! + \brief write the initializaiton data register + \param[in] init_data:specify 32-bit data + \param[out] none + \retval none +*/ +void crc_init_data_register_write(uint32_t init_data) +{ + CRC_IDATA = (uint32_t)init_data; +} + +/*! + \brief configure the CRC input data function + \param[in] data_reverse: specify input data reverse function + \arg CRC_INPUT_DATA_NOT: input data is not reversed + \arg CRC_INPUT_DATA_BYTE: input data is reversed on 8 bits + \arg CRC_INPUT_DATA_HALFWORD: input data is reversed on 16 bits + \arg CRC_INPUT_DATA_WORD: input data is reversed on 32 bits + \param[out] none + \retval none +*/ +void crc_input_data_reverse_config(uint32_t data_reverse) +{ + CRC_CTL &= (uint32_t)(~CRC_CTL_REV_I); + CRC_CTL |= (uint32_t)data_reverse; +} + +/*! + \brief configure the CRC size of polynomial function + \param[in] poly_size: size of polynomial + \arg CRC_CTL_PS_32: 32-bit polynomial for CRC calculation + \arg CRC_CTL_PS_16: 16-bit polynomial for CRC calculation + \arg CRC_CTL_PS_8: 8-bit polynomial for CRC calculation + \arg CRC_CTL_PS_7: 7-bit polynomial for CRC calculation + \param[out] none + \retval none +*/ +void crc_polynomial_size_set(uint32_t poly_size) +{ + CRC_CTL &= (uint32_t)(~(CRC_CTL_PS)); + CRC_CTL |= (uint32_t)poly_size; +} + +/*! + \brief configure the CRC polynomial value function + \param[in] poly: configurable polynomial value + \param[out] none + \retval none +*/ +void crc_polynomial_set(uint32_t poly) +{ + CRC_POLY &= (uint32_t)(~CRC_POLY_POLY); + CRC_POLY = poly; +} + +/*! + \brief CRC calculate a 32-bit data + \param[in] sdata: specify 32-bit data + \param[out] none + \retval 32-bit CRC calculate value +*/ +uint32_t crc_single_data_calculate(uint32_t sdata) +{ + CRC_DATA = sdata; + return(CRC_DATA); +} + +/*! + \brief CRC calculate a 32-bit data array + \param[in] array: pointer to an array of 32 bit data words + \param[in] size: size of the array + \param[out] none + \retval 32-bit CRC calculate value +*/ +uint32_t crc_block_data_calculate(uint32_t array[], uint32_t size) +{ + uint32_t index; + for(index = 0U; index < size; index++){ + CRC_DATA = array[index]; + } + return (CRC_DATA); +} diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_dbg.c b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_dbg.c new file mode 100644 index 0000000000000000000000000000000000000000..614bd6016e3fa418f0140f5feac5992154c119ad --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_dbg.c @@ -0,0 +1,140 @@ +/*! + \file gd32e230_dbg.c + \brief DBG driver + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor 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 copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 "gd32e230_dbg.h" + +#define DBG_RESET_VAL 0x00000000U + +/*! + \brief deinitialize the DBG + \param[in] none + \param[out] none + \retval none +*/ +void dbg_deinit(void) +{ + DBG_CTL0 = DBG_RESET_VAL; + DBG_CTL1 = DBG_RESET_VAL; +} + +/*! + \brief read DBG_ID code register + \param[in] none + \param[out] none + \retval DBG_ID code +*/ +uint32_t dbg_id_get(void) +{ + return DBG_ID; +} + +/*! + \brief enable low power behavior when the mcu is in debug mode + \param[in] dbg_low_power: + this parameter can be any combination of the following values: + \arg DBG_LOW_POWER_SLEEP: keep debugger connection during sleep mode + \arg DBG_LOW_POWER_DEEPSLEEP: keep debugger connection during deepsleep mode + \arg DBG_LOW_POWER_STANDBY: keep debugger connection during standby mode + \param[out] none + \retval none +*/ +void dbg_low_power_enable(uint32_t dbg_low_power) +{ + DBG_CTL0 |= dbg_low_power; +} + +/*! + \brief disable low power behavior when the mcu is in debug mode + \param[in] dbg_low_power: + this parameter can be any combination of the following values: + \arg DBG_LOW_POWER_SLEEP: donot keep debugger connection during sleep mode + \arg DBG_LOW_POWER_DEEPSLEEP: donot keep debugger connection during deepsleep mode + \arg DBG_LOW_POWER_STANDBY: donot keep debugger connection during standby mode + \param[out] none + \retval none +*/ +void dbg_low_power_disable(uint32_t dbg_low_power) +{ + DBG_CTL0 &= ~dbg_low_power; +} + +/*! + \brief enable peripheral behavior when the mcu is in debug mode + \param[in] dbg_periph: DBG peripheral + only one parameter can be selected which is shown as below: + \arg DBG_FWDGT_HOLD: debug FWDGT kept when core is halted + \arg DBG_WWDGT_HOLD: debug WWDGT kept when core is halted + \arg DBG_TIMER0_HOLD: TIMER0 counter kept when core is halted + \arg DBG_TIMER2_HOLD: TIMER2 counter kept when core is halted + \arg DBG_TIMER5_HOLD: hold TIMER5 counter when core is halted + \arg DBG_TIMER13_HOLD: hold TIMER13 counter when core is halted + \arg DBG_TIMER14_HOLD: hold TIMER14 counter when core is halted + \arg DBG_TIMER15_HOLD: hold TIMER15 counter when core is halted + \arg DBG_TIMER16_HOLD: hold TIMER16 counter when core is halted + \arg DBG_I2C0_HOLD: hold I2C0 SMBUS when core is halted + \arg DBG_I2C1_HOLD: hold I2C1 SMBUS when core is halted + \arg DBG_RTC_HOLD: hold RTC calendar and wakeup counter when core is halted + \param[out] none + \retval none +*/ +void dbg_periph_enable(dbg_periph_enum dbg_periph) +{ + DBG_REG_VAL(dbg_periph) |= BIT(DBG_BIT_POS(dbg_periph)); +} + +/*! + \brief disable peripheral behavior when the mcu is in debug mode + \param[in] dbg_periph: DBG peripheral + only one parameter can be selected which is shown as below: + \arg DBG_FWDGT_HOLD: debug FWDGT kept when core is halted + \arg DBG_WWDGT_HOLD: debug WWDGT kept when core is halted + \arg DBG_TIMER0_HOLD: TIMER0 counter kept when core is halted + \arg DBG_TIMER2_HOLD: TIMER2 counter kept when core is halted + \arg DBG_TIMER5_HOLD: hold TIMER5 counter when core is halted + \arg DBG_TIMER13_HOLD: hold TIMER13 counter when core is halted + \arg DBG_TIMER14_HOLD: hold TIMER14 counter when core is halted + \arg DBG_TIMER15_HOLD: hold TIMER15 counter when core is halted + \arg DBG_TIMER16_HOLD: hold TIMER16 counter when core is halted + \arg DBG_I2C0_HOLD: hold I2C0 SMBUS when core is halted + \arg DBG_I2C1_HOLD: hold I2C1 SMBUS when core is halted + \arg DBG_RTC_HOLD: hold RTC calendar and wakeup counter when core is halted + \param[out] none + \retval none +*/ +void dbg_periph_disable(dbg_periph_enum dbg_periph) +{ + DBG_REG_VAL(dbg_periph) &= ~BIT(DBG_BIT_POS(dbg_periph)); +} diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_dma.c b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_dma.c new file mode 100644 index 0000000000000000000000000000000000000000..5cdf462001170c1d3e0d1018d1162c4148357334 --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_dma.c @@ -0,0 +1,562 @@ +/*! + \file gd32e230_dma.c + \brief DMA driver + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor 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 copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 "gd32e230_dma.h" + +/*! + \brief deinitialize DMA a channel registers + \param[in] channelx: specify which DMA channel is deinitialized + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..4) + \param[out] none + \retval none +*/ +void dma_deinit(dma_channel_enum channelx) +{ + /* disable DMA a channel */ + DMA_CHCTL(channelx) &= ~DMA_CHXCTL_CHEN; + /* reset DMA channel registers */ + DMA_CHCTL(channelx) = DMA_CHCTL_RESET_VALUE; + DMA_CHCNT(channelx) = DMA_CHCNT_RESET_VALUE; + DMA_CHPADDR(channelx) = DMA_CHPADDR_RESET_VALUE; + DMA_CHMADDR(channelx) = DMA_CHMADDR_RESET_VALUE; + DMA_INTC |= DMA_FLAG_ADD(DMA_CHINTF_RESET_VALUE, channelx); +} + +/*! + \brief initialize the parameters of DMA struct with the default values + \param[in] init_struct: the initialization data needed to initialize DMA channel + \param[out] none + \retval none +*/ +void dma_struct_para_init(dma_parameter_struct* init_struct) +{ + /* set the DMA struct with the default values */ + init_struct->periph_addr = 0U; + init_struct->periph_width = 0U; + init_struct->periph_inc = (uint8_t)DMA_PERIPH_INCREASE_DISABLE; + init_struct->memory_addr = 0U; + init_struct->memory_width = 0U; + init_struct->memory_inc = (uint8_t)DMA_MEMORY_INCREASE_DISABLE; + init_struct->number = 0U; + init_struct->direction = (uint8_t)DMA_PERIPHERAL_TO_MEMORY; + init_struct->priority = (uint32_t)DMA_PRIORITY_LOW; +} + +/*! + \brief initialize DMA channel + \param[in] channelx: specify which DMA channel is initialized + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..4) + \param[in] init_struct: the data needed to initialize DMA channel + periph_addr: peripheral base address + periph_width: DMA_PERIPHERAL_WIDTH_8BIT,DMA_PERIPHERAL_WIDTH_16BIT,DMA_PERIPHERAL_WIDTH_32BIT + periph_inc: DMA_PERIPH_INCREASE_ENABLE,DMA_PERIPH_INCREASE_DISABLE + memory_addr: memory base address + memory_width: DMA_MEMORY_WIDTH_8BIT,DMA_MEMORY_WIDTH_16BIT,DMA_MEMORY_WIDTH_32BIT + memory_inc: DMA_MEMORY_INCREASE_ENABLE,DMA_MEMORY_INCREASE_DISABLE + direction: DMA_PERIPHERAL_TO_MEMORY,DMA_MEMORY_TO_PERIPHERAL + number: the number of remaining data to be transferred by the DMA + priority: DMA_PRIORITY_LOW,DMA_PRIORITY_MEDIUM,DMA_PRIORITY_HIGH,DMA_PRIORITY_ULTRA_HIGH + \param[out] none + \retval none +*/ +void dma_init(dma_channel_enum channelx, dma_parameter_struct* init_struct) +{ + uint32_t ctl; + + dma_channel_disable(channelx); + + /* configure peripheral base address */ + DMA_CHPADDR(channelx) = init_struct->periph_addr; + + /* configure memory base address */ + DMA_CHMADDR(channelx) = init_struct->memory_addr; + + /* configure the number of remaining data to be transferred */ + DMA_CHCNT(channelx) = (init_struct->number & DMA_CHANNEL_CNT_MASK); + + /* configure peripheral transfer width,memory transfer width,channel priotity */ + ctl = DMA_CHCTL(channelx); + ctl &= ~(DMA_CHXCTL_PWIDTH | DMA_CHXCTL_MWIDTH | DMA_CHXCTL_PRIO); + ctl |= (init_struct->periph_width | init_struct->memory_width | init_struct->priority); + DMA_CHCTL(channelx) = ctl; + + /* configure peripheral increasing mode */ + if(DMA_PERIPH_INCREASE_ENABLE == init_struct->periph_inc){ + DMA_CHCTL(channelx) |= DMA_CHXCTL_PNAGA; + }else{ + DMA_CHCTL(channelx) &= ~DMA_CHXCTL_PNAGA; + } + + /* configure memory increasing mode */ + if(DMA_MEMORY_INCREASE_ENABLE == init_struct->memory_inc){ + DMA_CHCTL(channelx) |= DMA_CHXCTL_MNAGA; + }else{ + DMA_CHCTL(channelx) &= ~DMA_CHXCTL_MNAGA; + } + + /* configure the direction of data transfer */ + if(DMA_PERIPHERAL_TO_MEMORY == init_struct->direction){ + DMA_CHCTL(channelx) &= ~DMA_CHXCTL_DIR; + }else{ + DMA_CHCTL(channelx) |= DMA_CHXCTL_DIR; + } +} + +/*! + \brief enable DMA circulation mode + \param[in] channelx: specify which DMA channel to set + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..4) + \param[out] none + \retval none +*/ +void dma_circulation_enable(dma_channel_enum channelx) +{ + DMA_CHCTL(channelx) |= DMA_CHXCTL_CMEN; +} + +/*! + \brief disable DMA circulation mode + \param[in] channelx: specify which DMA channel to set + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..4) + \param[out] none + \retval none +*/ +void dma_circulation_disable(dma_channel_enum channelx) +{ + DMA_CHCTL(channelx) &= ~DMA_CHXCTL_CMEN; +} + +/*! + \brief enable memory to memory mode + \param[in] channelx: specify which DMA channel to set + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..4) + \param[out] none + \retval none +*/ +void dma_memory_to_memory_enable(dma_channel_enum channelx) +{ + DMA_CHCTL(channelx) |= DMA_CHXCTL_M2M; +} + +/*! + \brief disable memory to memory mode + \param[in] channelx: specify which DMA channel to set + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..4) + \param[out] none + \retval none +*/ +void dma_memory_to_memory_disable(dma_channel_enum channelx) +{ + DMA_CHCTL(channelx) &= ~DMA_CHXCTL_M2M; +} + +/*! + \brief enable DMA channel + \param[in] channelx: specify which DMA channel to set + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..4) + \param[out] none + \retval none +*/ +void dma_channel_enable(dma_channel_enum channelx) +{ + DMA_CHCTL(channelx) |= DMA_CHXCTL_CHEN; +} + +/*! + \brief disable DMA channel + \param[in] channelx: specify which DMA channel to set + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..4) + \param[out] none + \retval none +*/ +void dma_channel_disable(dma_channel_enum channelx) +{ + DMA_CHCTL(channelx) &= ~DMA_CHXCTL_CHEN; +} + +/*! + \brief set DMA peripheral base address + \param[in] channelx: specify which DMA channel to set peripheral base address + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..4) + \param[in] address: peripheral base address + \param[out] none + \retval none +*/ +void dma_periph_address_config(dma_channel_enum channelx, uint32_t address) +{ + DMA_CHPADDR(channelx) = address; +} + +/*! + \brief set DMA memory base address + \param[in] channelx: specify which DMA channel to set memory base address + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..4) + \param[in] address: memory base address + \param[out] none + \retval none +*/ +void dma_memory_address_config(dma_channel_enum channelx, uint32_t address) +{ + DMA_CHMADDR(channelx) = address; +} + +/*! + \brief set the number of remaining data to be transferred by the DMA + \param[in] channelx: specify which DMA channel to set number + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..4) + \param[in] number: the number of remaining data to be transferred by the DMA + \param[out] none + \retval none +*/ +void dma_transfer_number_config(dma_channel_enum channelx, uint32_t number) +{ + DMA_CHCNT(channelx) = (number & DMA_CHANNEL_CNT_MASK); +} + +/*! + \brief get the number of remaining data to be transferred by the DMA + \param[in] channelx: specify which DMA channel to set number + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..4) + \param[out] none + \retval the number of remaining data to be transferred by the DMA +*/ +uint32_t dma_transfer_number_get(dma_channel_enum channelx) +{ + return (uint32_t)DMA_CHCNT(channelx); +} + +/*! + \brief configure priority level of DMA channel + \param[in] channelx: specify which DMA channel to set + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..4) + \param[in] priority: priority level of this channel + only one parameter can be selected which is shown as below: + \arg DMA_PRIORITY_LOW: low priority + \arg DMA_PRIORITY_MEDIUM: medium priority + \arg DMA_PRIORITY_HIGH: high priority + \arg DMA_PRIORITY_ULTRA_HIGH: ultra high priority + \param[out] none + \retval none +*/ +void dma_priority_config(dma_channel_enum channelx, uint32_t priority) +{ + uint32_t ctl; + + /* acquire DMA_CHxCTL register */ + ctl = DMA_CHCTL(channelx); + /* assign regiser */ + ctl &= ~DMA_CHXCTL_PRIO; + ctl |= priority; + DMA_CHCTL(channelx) = ctl; +} + +/*! + \brief configure transfer data width of memory + \param[in] channelx: specify which DMA channel to set + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..4) + \param[in] mwidth: transfer data width of memory + only one parameter can be selected which is shown as below: + \arg DMA_MEMORY_WIDTH_8BIT: transfer data width of memory is 8-bit + \arg DMA_MEMORY_WIDTH_16BIT: transfer data width of memory is 16-bit + \arg DMA_MEMORY_WIDTH_32BIT: transfer data width of memory is 32-bit + \param[out] none + \retval none +*/ +void dma_memory_width_config(dma_channel_enum channelx, uint32_t mwidth) +{ + uint32_t ctl; + + /* acquire DMA_CHxCTL register */ + ctl = DMA_CHCTL(channelx); + /* assign regiser */ + ctl &= ~DMA_CHXCTL_MWIDTH; + ctl |= mwidth; + DMA_CHCTL(channelx) = ctl; +} + +/*! + \brief configure transfer data width of peripheral + \param[in] channelx: specify which DMA channel to set + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..4) + \param[in] pwidth: transfer data width of peripheral + only one parameter can be selected which is shown as below: + \arg DMA_PERIPHERAL_WIDTH_8BIT: transfer data width of peripheral is 8-bit + \arg DMA_PERIPHERAL_WIDTH_16BIT: transfer data width of peripheral is 16-bit + \arg DMA_PERIPHERAL_WIDTH_32BIT: transfer data width of peripheral is 32-bit + \param[out] none + \retval none +*/ +void dma_periph_width_config(dma_channel_enum channelx, uint32_t pwidth) +{ + uint32_t ctl; + + /* acquire DMA_CHxCTL register */ + ctl = DMA_CHCTL(channelx); + /* assign regiser */ + ctl &= ~DMA_CHXCTL_PWIDTH; + ctl |= pwidth; + DMA_CHCTL(channelx) = ctl; +} + +/*! + \brief enable next address increasement algorithm of memory + \param[in] channelx: specify which DMA channel to set + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..4) + \param[out] none + \retval none +*/ +void dma_memory_increase_enable(dma_channel_enum channelx) +{ + DMA_CHCTL(channelx) |= DMA_CHXCTL_MNAGA; +} + +/*! + \brief disable next address increasement algorithm of memory + \param[in] channelx: specify which DMA channel to set + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..4) + \param[out] none + \retval none +*/ +void dma_memory_increase_disable(dma_channel_enum channelx) +{ + DMA_CHCTL(channelx) &= ~DMA_CHXCTL_MNAGA; +} + +/*! + \brief enable next address increasement algorithm of peripheral + \param[in] channelx: specify which DMA channel to set + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..4) + \param[out] none + \retval none +*/ +void dma_periph_increase_enable(dma_channel_enum channelx) +{ + DMA_CHCTL(channelx) |= DMA_CHXCTL_PNAGA; +} + +/*! + \brief disable next address increasement algorithm of peripheral + \param[in] channelx: specify which DMA channel to set + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..4) + \param[out] none + \retval none +*/ +void dma_periph_increase_disable(dma_channel_enum channelx) +{ + DMA_CHCTL(channelx) &= ~DMA_CHXCTL_PNAGA; +} + +/*! + \brief configure the direction of data transfer on the channel + \param[in] channelx: specify which DMA channel to set + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..4) + \param[in] direction: specify the direction of data transfer + only one parameter can be selected which is shown as below: + \arg DMA_PERIPHERAL_TO_MEMORY: read from peripheral and write to memory + \arg DMA_MEMORY_TO_PERIPHERAL: read from memory and write to peripheral + \param[out] none + \retval none +*/ +void dma_transfer_direction_config(dma_channel_enum channelx, uint32_t direction) +{ + if(DMA_PERIPHERAL_TO_MEMORY == direction){ + DMA_CHCTL(channelx) &= ~DMA_CHXCTL_DIR; + } else { + DMA_CHCTL(channelx) |= DMA_CHXCTL_DIR; + } +} + +/*! + \brief check DMA flag is set or not + \param[in] channelx: specify which DMA channel to get flag + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..4) + \param[in] flag: specify get which flag + only one parameter can be selected which is shown as below: + \arg DMA_FLAG_G: global interrupt flag of channel + \arg DMA_FLAG_FTF: full transfer finish flag of channel + \arg DMA_FLAG_HTF: half transfer finish flag of channel + \arg DMA_FLAG_ERR: error flag of channel + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus dma_flag_get(dma_channel_enum channelx, uint32_t flag) +{ + FlagStatus reval; + + if(RESET != (DMA_INTF & DMA_FLAG_ADD(flag, channelx))){ + reval = SET; + }else{ + reval = RESET; + } + + return reval; +} + +/*! + \brief clear DMA a channel flag + \param[in] channelx: specify which DMA channel to clear flag + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..4) + \param[in] flag: specify get which flag + only one parameter can be selected which is shown as below: + \arg DMA_FLAG_G: global interrupt flag of channel + \arg DMA_FLAG_FTF: full transfer finish flag of channel + \arg DMA_FLAG_HTF: half transfer finish flag of channel + \arg DMA_FLAG_ERR: error flag of channel + \param[out] none + \retval none +*/ +void dma_flag_clear(dma_channel_enum channelx, uint32_t flag) +{ + DMA_INTC |= DMA_FLAG_ADD(flag, channelx); +} + +/*! + \brief check DMA flag and interrupt enable bit is set or not + \param[in] channelx: specify which DMA channel to get flag + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..4) + \param[in] flag: specify get which flag + only one parameter can be selected which is shown as below: + \arg DMA_INT_FLAG_FTF: transfer finish flag of channel + \arg DMA_INT_FLAG_HTF: half transfer finish flag of channel + \arg DMA_INT_FLAG_ERR: error flag of channel + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus dma_interrupt_flag_get(dma_channel_enum channelx, uint32_t flag) +{ + uint32_t interrupt_enable = 0U, interrupt_flag = 0U; + + switch(flag){ + case DMA_INT_FLAG_FTF: + interrupt_flag = DMA_INTF & DMA_FLAG_ADD(flag, channelx); + interrupt_enable = DMA_CHCTL(channelx) & DMA_CHXCTL_FTFIE; + break; + case DMA_INT_FLAG_HTF: + interrupt_flag = DMA_INTF & DMA_FLAG_ADD(flag, channelx); + interrupt_enable = DMA_CHCTL(channelx) & DMA_CHXCTL_HTFIE; + break; + case DMA_INT_FLAG_ERR: + interrupt_flag = DMA_INTF & DMA_FLAG_ADD(flag, channelx); + interrupt_enable = DMA_CHCTL(channelx) & DMA_CHXCTL_ERRIE; + break; + default: + break; + } + + if(interrupt_flag && interrupt_enable){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear DMA a channel interrupt flag + \param[in] channelx: specify which DMA channel to clear flag + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..4) + \param[in] flag: specify get which flag + only one parameter can be selected which is shown as below: + \arg DMA_INT_FLAG_G: global interrupt flag of channel + \arg DMA_INT_FLAG_FTF: transfer finish flag of channel + \arg DMA_INT_FLAG_HTF: half transfer finish flag of channel + \arg DMA_INT_FLAG_ERR: error flag of channel + \param[out] none + \retval none +*/ +void dma_interrupt_flag_clear(dma_channel_enum channelx, uint32_t flag) +{ + DMA_INTC |= DMA_FLAG_ADD(flag,channelx); +} + +/*! + \brief enable DMA interrupt + \param[in] channelx: specify which DMA channel to set + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..4) + \param[in] source: specify which interrupt to enable + only one parameter can be selected which is shown as below: + \arg DMA_INT_ERR: channel error interrupt + \arg DMA_INT_HTF: channel half transfer finish interrupt + \arg DMA_INT_FTF: channel full transfer finish interrupt + \param[out] none + \retval none +*/ +void dma_interrupt_enable(dma_channel_enum channelx, uint32_t source) +{ + DMA_CHCTL(channelx) |= source; +} + +/*! + \brief disable DMA interrupt + \param[in] channelx: specify which DMA channel to set + only one parameter can be selected which is shown as below: + \arg DMA_CHx(x=0..4) + \param[in] source: specify which interrupt to disable + only one parameter can be selected which is shown as below: + \arg DMA_INT_ERR: channel error interrupt + \arg DMA_INT_HTF: channel half transfer finish interrupt + \arg DMA_INT_FTF: channel full transfer finish interrupt + \param[out] none + \retval none +*/ +void dma_interrupt_disable(dma_channel_enum channelx, uint32_t source) +{ + DMA_CHCTL(channelx) &= ~source; +} diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_exti.c b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_exti.c new file mode 100644 index 0000000000000000000000000000000000000000..894a38c62f1c86deeeedcbc185afed99e26e9267 --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_exti.c @@ -0,0 +1,254 @@ +/*! + \file gd32e230_exti.c + \brief EXTI driver + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor 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 copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 "gd32e230_exti.h" + +/*! + \brief deinitialize the EXTI + \param[in] none + \param[out] none + \retval none +*/ +void exti_deinit(void) +{ + /* reset the value of all the EXTI registers */ + EXTI_INTEN = (uint32_t)0x0F940000U; + EXTI_EVEN = (uint32_t)0x00000000U; + EXTI_RTEN = (uint32_t)0x00000000U; + EXTI_FTEN = (uint32_t)0x00000000U; + EXTI_SWIEV = (uint32_t)0x00000000U; +} + +/*! + \brief initialize the EXTI + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..17,19,21): EXTI line x + \param[in] mode: interrupt or event mode, refer to exti_mode_enum + only one parameter can be selected which is shown as below: + \arg EXTI_INTERRUPT: interrupt mode + \arg EXTI_EVENT: event mode + \param[in] trig_type: interrupt trigger type, refer to exti_trig_type_enum + only one parameter can be selected which is shown as below: + \arg EXTI_TRIG_RISING: rising edge trigger + \arg EXTI_TRIG_FALLING: falling trigger + \arg EXTI_TRIG_BOTH: rising and falling trigger + \param[out] none + \retval none +*/ +void exti_init(exti_line_enum linex, \ + exti_mode_enum mode, \ + exti_trig_type_enum trig_type) +{ + /* reset the EXTI line x */ + EXTI_INTEN &= ~(uint32_t)linex; + EXTI_EVEN &= ~(uint32_t)linex; + EXTI_RTEN &= ~(uint32_t)linex; + EXTI_FTEN &= ~(uint32_t)linex; + + /* set the EXTI mode and enable the interrupts or events from EXTI line x */ + switch(mode){ + case EXTI_INTERRUPT: + EXTI_INTEN |= (uint32_t)linex; + break; + case EXTI_EVENT: + EXTI_EVEN |= (uint32_t)linex; + break; + default: + break; + } + + /* set the EXTI trigger type */ + switch(trig_type){ + case EXTI_TRIG_RISING: + EXTI_RTEN |= (uint32_t)linex; + EXTI_FTEN &= ~(uint32_t)linex; + break; + case EXTI_TRIG_FALLING: + EXTI_RTEN &= ~(uint32_t)linex; + EXTI_FTEN |= (uint32_t)linex; + break; + case EXTI_TRIG_BOTH: + EXTI_RTEN |= (uint32_t)linex; + EXTI_FTEN |= (uint32_t)linex; + break; + default: + break; + } +} + +/*! + \brief enable the interrupts from EXTI line x + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..27): EXTI line x + \param[out] none + \retval none +*/ +void exti_interrupt_enable(exti_line_enum linex) +{ + EXTI_INTEN |= (uint32_t)linex; +} + +/*! + \brief enable the events from EXTI line x + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..27): EXTI line x + \param[out] none + \retval none +*/ +void exti_event_enable(exti_line_enum linex) +{ + EXTI_EVEN |= (uint32_t)linex; +} + +/*! + \brief disable the interrupt from EXTI line x + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..27): EXTI line x + \param[out] none + \retval none +*/ +void exti_interrupt_disable(exti_line_enum linex) +{ + EXTI_INTEN &= ~(uint32_t)linex; +} + +/*! + \brief disable the events from EXTI line x + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..27): EXTI line x + \param[out] none + \retval none +*/ +void exti_event_disable(exti_line_enum linex) +{ + EXTI_EVEN &= ~(uint32_t)linex; +} + +/*! + \brief get EXTI lines flag + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..17,19,21): EXTI line x + \param[out] none + \retval FlagStatus: status of flag (RESET or SET) +*/ +FlagStatus exti_flag_get(exti_line_enum linex) +{ + if(RESET != (EXTI_PD & (uint32_t)linex)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear EXTI lines pending flag + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..17,19,21): EXTI line x + \param[out] none + \retval none +*/ +void exti_flag_clear(exti_line_enum linex) +{ + EXTI_PD = (uint32_t)linex; +} + +/*! + \brief get EXTI lines flag when the interrupt flag is set + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..17,19,21): EXTI line x + \param[out] none + \retval FlagStatus: status of flag (RESET or SET) +*/ +FlagStatus exti_interrupt_flag_get(exti_line_enum linex) +{ + uint32_t flag_left, flag_right; + + flag_left = EXTI_PD & (uint32_t)linex; + flag_right = EXTI_INTEN & (uint32_t)linex; + + if((RESET != flag_left) && (RESET != flag_right)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear EXTI lines pending flag + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..17,19,21): EXTI line x + \param[out] none + \retval none +*/ +void exti_interrupt_flag_clear(exti_line_enum linex) +{ + EXTI_PD = (uint32_t)linex; +} + +/*! + \brief enable EXTI software interrupt event + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..17,19,21): EXTI line x + \param[out] none + \retval none +*/ +void exti_software_interrupt_enable(exti_line_enum linex) +{ + EXTI_SWIEV |= (uint32_t)linex; +} + +/*! + \brief disable EXTI software interrupt event + \param[in] linex: EXTI line number, refer to exti_line_enum + only one parameter can be selected which is shown as below: + \arg EXTI_x (x=0..17,19,21): EXTI line x + \param[out] none + \retval none +*/ +void exti_software_interrupt_disable(exti_line_enum linex) +{ + EXTI_SWIEV &= ~(uint32_t)linex; +} diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_fmc.c b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_fmc.c new file mode 100644 index 0000000000000000000000000000000000000000..148915780731f2dfba4072a54d8e1c65e3bf9a2e --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_fmc.c @@ -0,0 +1,814 @@ +/*! + \file gd32e230_fmc.c + \brief FMC driver + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor 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 copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 "gd32e230_fmc.h" + +/* FMC register bit offset */ +#define OB_HIGH_WP_OFFSET ((uint32_t)8U) +#define FMC_OBSTAT_USER_OFFSET ((uint32_t)8U) +#define FMC_OBSTAT_DATA_OFFSET ((uint32_t)16U) + +/*! + \brief unlock the main FMC operation + it is better to used in pairs with fmc_lock + \param[in] none + \param[out] none + \retval none +*/ +void fmc_unlock(void) +{ + if((RESET != (FMC_CTL & FMC_CTL_LK))){ + /* write the FMC key */ + FMC_KEY = UNLOCK_KEY0; + FMC_KEY = UNLOCK_KEY1; + } +} + +/*! + \brief lock the main FMC operation + it is better to used in pairs with fmc_unlock after an operation + \param[in] none + \param[out] none + \retval none +*/ +void fmc_lock(void) +{ + /* set the LK bit*/ + FMC_CTL |= FMC_CTL_LK; +} + +/*! + \brief set the wait state counter value + \param[in] wscnt: wait state counter value + \arg WS_WSCNT_0: 0 wait state added + \arg WS_WSCNT_1: 1 wait state added + \arg WS_WSCNT_2: 2 wait state added + \param[out] none + \retval none +*/ +void fmc_wscnt_set(uint8_t wscnt) +{ + uint32_t reg; + + reg = FMC_WS; + /* set the wait state counter value */ + reg &= ~FMC_WS_WSCNT; + FMC_WS = (reg | wscnt); +} + +/*! + \brief pre-fetch enable + \param[in] none + \param[out] none + \retval none +*/ +void fmc_prefetch_enable(void) +{ + FMC_WS |= FMC_WS_PFEN; +} + +/*! + \brief pre-fetch disable + \param[in] none + \param[out] none + \retval none +*/ +void fmc_prefetch_disable(void) +{ + FMC_WS &= ~FMC_WS_PFEN; +} + +/*! + \brief erase page + \param[in] page_address: target page start address + \param[out] none + \retval fmc_state: state of FMC + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_PGERR: program error + \arg FMC_PGAERR: program alignment error + \arg FMC_WPERR: erase/program protection error + \arg FMC_TOERR: timeout error + \arg FMC_OB_HSPC: option byte security protection code high +*/ +fmc_state_enum fmc_page_erase(uint32_t page_address) +{ + fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state){ + /* start page erase */ + FMC_CTL |= FMC_CTL_PER; + FMC_ADDR = page_address; + FMC_CTL |= FMC_CTL_START; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + /* reset the PER bit */ + FMC_CTL &= ~FMC_CTL_PER; + } + + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief erase whole chip + \param[in] none + \param[out] none + \retval fmc_state: state of FMC + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_PGERR: program error + \arg FMC_PGAERR: program alignment error + \arg FMC_WPERR: erase/program protection error + \arg FMC_TOERR: timeout error + \arg FMC_OB_HSPC: option byte security protection code high +*/ +fmc_state_enum fmc_mass_erase(void) +{ + fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state){ + /* start chip erase */ + FMC_CTL |= FMC_CTL_MER; + FMC_CTL |= FMC_CTL_START; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + /* reset the MER bit */ + FMC_CTL &= ~FMC_CTL_MER; + } + + /* return the fmc state */ + return fmc_state; +} + +/*! + \brief program a double word at the corresponding address in main flash, this + function also applies to OTP(address 0x1FFF_7000~0x1FFF_73FF) programming + \param[in] address: address to program + \param[in] data: double word to program + \param[out] none + \retval fmc_state: state of FMC + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_PGERR: program error + \arg FMC_PGAERR: program alignment error + \arg FMC_WPERR: erase/program protection error + \arg FMC_TOERR: timeout error + \arg FMC_OB_HSPC: option byte security protection code high +*/ +fmc_state_enum fmc_doubleword_program(uint32_t address, uint64_t data) +{ + uint32_t data0, data1; + + fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + data0 = (uint32_t)(data & 0xFFFFFFFFU); + data1 = (uint32_t)((data>>32U) & 0xFFFFFFFFU); + + /* configure program width */ + FMC_WS |= FMC_WS_PGW; + if(FMC_READY == fmc_state){ + /* set the PG bit to start program */ + FMC_CTL |= FMC_CTL_PG; + REG32(address) = data0; + REG32(address+4U) = data1; + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + /* reset the PG bit */ + FMC_CTL &= ~FMC_CTL_PG; + } + FMC_WS &= ~(FMC_WS_PGW); + + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief program a word at the corresponding address in main flash, this function + also applies to OTP(address 0x1FFF_7000~0x1FFF_73FF) programming + \param[in] address: address to program + \param[in] data: word to program + \param[out] none + \retval fmc_state: state of FMC + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_PGERR: program error + \arg FMC_PGAERR: program alignment error + \arg FMC_WPERR: erase/program protection error + \arg FMC_TOERR: timeout error + \arg FMC_OB_HSPC: option byte security protection code high +*/ +fmc_state_enum fmc_word_program(uint32_t address, uint32_t data) +{ + fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state){ + /* set the PG bit to start program */ + FMC_CTL |= FMC_CTL_PG; + + REG32(address) = data; + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + /* reset the PG bit */ + FMC_CTL &= ~FMC_CTL_PG; + } + + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief unlock the option byte operation + it is better to used in pairs with ob_lock + \param[in] none + \param[out] none + \retval none +*/ +void ob_unlock(void) +{ + if(RESET == (FMC_CTL & FMC_CTL_OBWEN)){ + /* write the FMC key */ + FMC_OBKEY = UNLOCK_KEY0; + FMC_OBKEY = UNLOCK_KEY1; + } + /* wait until OBWEN bit is set by hardware */ + while(RESET == (FMC_CTL & FMC_CTL_OBWEN)){ + } +} + +/*! + \brief lock the option byte operation + it is better to used in pairs with ob_unlock after an operation + \param[in] none + \param[out] none + \retval none +*/ +void ob_lock(void) +{ + /* reset the OBWE bit */ + FMC_CTL &= ~FMC_CTL_OBWEN; +} + +/*! + \brief reload the option byte and generate a system reset + \param[in] none + \param[out] none + \retval none +*/ +void ob_reset(void) +{ + /* set the OBRLD bit */ + FMC_CTL |= FMC_CTL_OBRLD; +} + +/*! + \brief get option byte value + \param[in] addr: address of option byte + \arg OB_SPC_USER_ADDRESS: address of option byte security protection and user + \arg OB_DATA_ADDRESS: address of option byte data + \arg OB_WP_ADDRESS: address of option byte write protection + \param[out] option byte value +*/ +uint32_t option_byte_value_get(uint32_t addr) +{ + return *(volatile uint32_t *)(addr); +} + +/*! + \brief erase the option byte + programmer must ensure FMC & option byte are both unlocked before calling this function + \param[in] none + \param[out] none + \retval fmc_state: state of FMC + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_PGERR: program error + \arg FMC_PGAERR: program alignment error + \arg FMC_WPERR: erase/program protection error + \arg FMC_TOERR: timeout error + \arg FMC_OB_HSPC: option byte security protection code high +*/ +fmc_state_enum ob_erase(void) +{ + uint16_t fmc_spc; + uint32_t val; + uint32_t fmc_plevel = ob_obstat_plevel_get(); + fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + /* get the original option byte security protection code */ + if(OB_OBSTAT_PLEVEL_NO == fmc_plevel){ + fmc_spc = FMC_NSPC; + }else if(OB_OBSTAT_PLEVEL_LOW == fmc_plevel){ + fmc_spc = FMC_LSPC; + }else{ + fmc_spc = FMC_HSPC; + fmc_state = FMC_OB_HSPC; + } + val = HIGH_16BITS_MASK | (uint32_t)fmc_spc; + + if(FMC_READY == fmc_state){ + /* start erase the option byte */ + FMC_CTL |= FMC_CTL_OBER; + FMC_CTL |= FMC_CTL_START; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state){ + /* reset the OBER bit */ + FMC_CTL &= ~FMC_CTL_OBER; + + /* set the OBPG bit */ + FMC_CTL |= FMC_CTL_OBPG; + + /* restore the last get option byte security protection code */ + OB_SPC_USER = val; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_TOERR != fmc_state){ + /* reset the OBPG bit */ + FMC_CTL &= ~FMC_CTL_OBPG; + } + }else{ + if(FMC_TOERR != fmc_state){ + /* reset the OBPG bit */ + FMC_CTL &= ~FMC_CTL_OBPG; + } + } + } + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief enable option byte write protection (OB_WP) + \param[in] ob_wp: write protection configuration data. Notice that set the + bit to 1 if you want to protect the corresponding pages. + \param[out] none + \retval fmc_state: state of FMC + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_PGERR: program error + \arg FMC_PGAERR: program alignment error + \arg FMC_WPERR: erase/program protection error + \arg FMC_TOERR: timeout error + \arg FMC_OB_HSPC: option byte security protection code high +*/ +fmc_state_enum ob_write_protection_enable(uint16_t ob_wp) +{ + uint32_t ob_wrp_val = 0U; + + fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + ob_wp = (uint16_t)(~ob_wp); + ob_wrp_val |= (uint32_t)ob_wp&0x00FFU; + ob_wrp_val |= (((uint32_t)ob_wp&0xFF00U)>>8U) << 16U; + + if(FMC_READY == fmc_state){ + /* set the OBPG bit*/ + FMC_CTL |= FMC_CTL_OBPG; + + if(0xFFFFFFFFU != ob_wrp_val){ + OB_WP = ob_wrp_val; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + } + if(FMC_TOERR != fmc_state){ + /* reset the OBPG bit */ + FMC_CTL &= ~FMC_CTL_OBPG; + } + } + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief configure security protection + \param[in] ob_spc: specify security protection code + \arg FMC_NSPC: no security protection + \arg FMC_LSPC: low security protection + \arg FMC_HSPC: high security protection + \param[out] none + \retval fmc_state: state of FMC + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_PGERR: program error + \arg FMC_PGAERR: program alignment error + \arg FMC_WPERR: erase/program protection error + \arg FMC_TOERR: timeout error + \arg FMC_OB_HSPC: option byte security protection code high +*/ +fmc_state_enum ob_security_protection_config(uint16_t ob_spc) +{ + uint32_t val; + fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + val = option_byte_value_get(OB_SPC_USER_ADDRESS); + /* the OB_SPC byte cannot be reprogrammed if protection level is high */ + if(OB_OBSTAT_PLEVEL_HIGH == ob_obstat_plevel_get()){ + fmc_state = FMC_OB_HSPC; + } + + val &= ~LOW_16BITS_MASK; + val |= (uint32_t)ob_spc; + + if(FMC_READY == fmc_state){ + /* start erase the option byte */ + FMC_CTL |= FMC_CTL_OBER; + FMC_CTL |= FMC_CTL_START; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state){ + + /* reset the OBER bit */ + FMC_CTL &= ~FMC_CTL_OBER; + + /* enable the option bytes programming */ + FMC_CTL |= FMC_CTL_OBPG; + + OB_SPC_USER = val; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_TOERR != fmc_state){ + /* reset the OBPG bit */ + FMC_CTL &= ~FMC_CTL_OBPG; + } + }else{ + if(FMC_TOERR != fmc_state){ + /* reset the OBER bit */ + FMC_CTL &= ~FMC_CTL_OBER; + } + } + } + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief program the FMC user option byte + this function can only clear the corresponding bits to be 0 rather than 1. + the function ob_erase is used to set all the bits to be 1. + \param[in] ob_user: user option byte + one or more parameters (bitwise AND) can be selected which are shown as below: + \arg OB_FWDGT_HW: hardware free watchdog timer + \arg OB_DEEPSLEEP_RST: no reset when entering deepsleep mode + \arg OB_STDBY_RST: no reset when entering standby mode + \arg OB_BOOT1_SET_1: BOOT1 bit is 1 + \arg OB_VDDA_DISABLE: disable VDDA monitor + \arg OB_SRAM_PARITY_ENABLE: enable sram parity check + \param[out] none + \retval fmc_state: state of FMC + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_PGERR: program error + \arg FMC_PGAERR: program alignment error + \arg FMC_WPERR: erase/program protection error + \arg FMC_TOERR: timeout error + \arg FMC_OB_HSPC: option byte security protection code high +*/ +fmc_state_enum ob_user_write(uint8_t ob_user) +{ + uint32_t val_spc_user; + /* check whether FMC is ready or not */ + fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + val_spc_user = option_byte_value_get(OB_SPC_USER_ADDRESS); + + val_spc_user &= ~HIGH_16BITS_MASK; + + val_spc_user |= ((uint32_t)ob_user<<16U); + + if(FMC_READY == fmc_state){ + /* start erase the option byte */ + FMC_CTL |= FMC_CTL_OBER; + FMC_CTL |= FMC_CTL_START; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_READY == fmc_state){ + + /* reset the OBER bit */ + FMC_CTL &= ~FMC_CTL_OBER; + + /* enable the option bytes programming */ + FMC_CTL |= FMC_CTL_OBPG; + + OB_SPC_USER = val_spc_user; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_TOERR != fmc_state){ + /* reset the OBPG bit */ + FMC_CTL &= ~FMC_CTL_OBPG; + } + }else{ + if(FMC_TOERR != fmc_state){ + /* reset the OBER bit */ + FMC_CTL &= ~FMC_CTL_OBER; + } + } + } + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief program the FMC data option byte + \param[in] data: the data to be programmed, OB_DATA[0:15] + \param[out] none + \retval fmc_state: state of FMC + \arg FMC_READY: the operation has been completed + \arg FMC_BUSY: the operation is in progress + \arg FMC_PGERR: program error + \arg FMC_PGAERR: program alignment error + \arg FMC_WPERR: erase/program protection error + \arg FMC_TOERR: timeout error + \arg FMC_OB_HSPC: option byte security protection code high +*/ +fmc_state_enum ob_data_program(uint16_t data) +{ + fmc_state_enum fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + uint32_t val = 0U; + + val |= (uint32_t)data&0x00FFU; + val |= (((uint32_t)data&0xFF00U)>>8U) << 16U; + + if(FMC_READY == fmc_state){ + /* set the OBPG bit */ + FMC_CTL |= FMC_CTL_OBPG; + OB_DATA = val; + + /* wait for the FMC ready */ + fmc_state = fmc_ready_wait(FMC_TIMEOUT_COUNT); + + if(FMC_TOERR != fmc_state){ + /* reset the OBPG bit */ + FMC_CTL &= ~FMC_CTL_OBPG; + } + } + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief get OB_USER in register FMC_OBSTAT + \param[in] none + \param[out] none + \retval ob_user +*/ +uint8_t ob_user_get(void) +{ + return (uint8_t)(FMC_OBSTAT >> FMC_OBSTAT_USER_OFFSET); +} + +/*! + \brief get OB_DATA in register FMC_OBSTAT + \param[in] none + \param[out] none + \retval ob_data +*/ +uint16_t ob_data_get(void) +{ + return (uint16_t)(FMC_OBSTAT >> FMC_OBSTAT_DATA_OFFSET); +} + +/*! + \brief get the FMC option byte write protection (OB_WP) in register FMC_WP + \param[in] none + \param[out] none + \retval OB_WP +*/ +uint16_t ob_write_protection_get(void) +{ + return (uint16_t)(FMC_WP); +} + +/*! + \brief get the value of FMC option byte security protection level (PLEVEL) in FMC_OBSTAT register + \param[in] none + \param[out] none + \retval the value of PLEVEL +*/ +uint32_t ob_obstat_plevel_get(void) +{ + return (FMC_OBSTAT & (FMC_OBSTAT_PLEVEL_BIT0 | FMC_OBSTAT_PLEVEL_BIT1)); +} + +/* FMC interrupts and flags management functions */ +/*! + \brief enable FMC interrupt + \param[in] interrupt: the FMC interrupt source + \arg FMC_INTEN_END: FMC end of operation interrupt + \arg FMC_INTEN_ERR: FMC error interrupt + \param[out] none + \retval none +*/ +void fmc_interrupt_enable(uint32_t interrupt) +{ + FMC_CTL |= interrupt; +} + +/*! + \brief disable FMC interrupt + \param[in] interrupt: the FMC interrupt source + \arg FMC_INTEN_END: FMC end of operation interrupt + \arg FMC_INTEN_ERR: FMC error interrupt + \param[out] none + \retval none +*/ +void fmc_interrupt_disable(uint32_t interrupt) +{ + FMC_CTL &= ~(uint32_t)interrupt; +} + +/*! + \brief get flag set or reset + \param[in] flag: check FMC flag + only one parameter can be selected which is shown as below: + \arg FMC_FLAG_BUSY: FMC busy flag + \arg FMC_FLAG_PGERR: FMC programming error flag + \arg FMC_FLAG_PGAERR: FMC program alignment error flag + \arg FMC_FLAG_WPERR: FMC write protection error flag + \arg FMC_FLAG_END: FMC end of programming flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus fmc_flag_get(uint32_t flag) +{ + FlagStatus status = RESET; + + if(FMC_STAT & flag){ + status = SET; + } + /* return the state of corresponding FMC flag */ + return status; +} + +/*! + \brief clear the FMC pending flag by writing 1 + \param[in] flag: clear FMC flag + one or more parameters can be selected which is shown as below: + \arg FMC_FLAG_PGERR: FMC programming error flag + \arg FMC_FLAG_PGAERR: FMC program alignment error flag + \arg FMC_FLAG_WPERR: FMC write protection error flag + \arg FMC_FLAG_END: FMC end of programming flag + \param[out] none + \retval none +*/ +void fmc_flag_clear(uint32_t flag) +{ + /* clear the flags */ + FMC_STAT = flag; +} + +/*! + \brief get intrrupt flag set or reset + \param[in] flag: check FMC flag + only one parameter can be selected which is shown as below: + \arg FMC_INT_FLAG_PGERR: FMC programming error flag + \arg FMC_INT_FLAG_PGAERR: FMC program alignment error flag + \arg FMC_INT_FLAG_WPERR: FMC write protection error flag + \arg FMC_INT_FLAG_END: FMC end of programming flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus fmc_interrupt_flag_get(uint32_t int_flag) +{ + uint32_t intenable = 0U, flagstatus = 0U; + + if(FMC_INT_FLAG_END == int_flag){ + /* get the interrupt enable bit status */ + intenable = FMC_CTL & FMC_INTEN_END; + /* get the corresponding flag bit status */ + flagstatus = FMC_STAT & int_flag; + if(intenable && flagstatus){ + return SET; + }else{ + return RESET; + } + }else{ + /* get the interrupt enable bit status */ + intenable = FMC_CTL & FMC_INTEN_ERR; + /* get the corresponding flag bit status */ + flagstatus = FMC_STAT & int_flag; + if(intenable && flagstatus){ + return SET; + }else{ + return RESET; + } + } +} + +/*! + \brief clear the FMC interrupt pending flag by writing 1 + \param[in] flag: clear FMC flag + one or more parameters can be selected which is shown as below: + \arg FMC_INT_FLAG_PGERR: FMC programming error flag + \arg FMC_INT_FLAG_PGAERR: FMC program alignment error flag + \arg FMC_INT_FLAG_WPERR: FMC write protection error flag + \arg FMC_INT_FLAG_END: FMC end of programming flag + \param[out] none + \retval none +*/ +void fmc_interrupt_flag_clear(uint32_t int_flag) +{ + /* clear the flags */ + FMC_STAT = int_flag; +} + +/*! + \brief get the FMC state + \param[in] none + \param[out] none + \retval fmc_state +*/ +fmc_state_enum fmc_state_get(void) +{ + fmc_state_enum fmc_state = FMC_READY; + + if((uint32_t)0x00U != (FMC_STAT & FMC_STAT_BUSY)){ + fmc_state = FMC_BUSY; + }else{ + if((uint32_t)0x00U != (FMC_STAT & FMC_STAT_WPERR)){ + fmc_state = FMC_WPERR; + }else{ + if((uint32_t)0x00U != (FMC_STAT & FMC_STAT_PGERR)){ + fmc_state = FMC_PGERR; + } + } + } + /* return the FMC state */ + return fmc_state; +} + +/*! + \brief check whether FMC is ready or not + \param[in] timeout: timeout count + \param[out] none + \retval fmc_state +*/ +fmc_state_enum fmc_ready_wait(uint32_t timeout) +{ + fmc_state_enum fmc_state = FMC_BUSY; + + /* wait for FMC ready */ + do{ + /* get FMC state */ + fmc_state = fmc_state_get(); + timeout--; + }while((FMC_BUSY == fmc_state) && (0U != timeout)); + + if(FMC_BUSY == fmc_state){ + fmc_state = FMC_TOERR; + } + /* return the FMC state */ + return fmc_state; +} diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_fwdgt.c b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_fwdgt.c new file mode 100644 index 0000000000000000000000000000000000000000..d3daa1fc32ef77696a536603a55ef85b120acf28 --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_fwdgt.c @@ -0,0 +1,252 @@ +/*! + \file gd32e230_fwdgt.c + \brief FWDGT driver + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor 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 copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 "gd32e230_fwdgt.h" + +/* write value to FWDGT_CTL_CMD bit field */ +#define CTL_CMD(regval) (BITS(0,15) & ((uint32_t)(regval) << 0U)) /*!< write value to FWDGT_CTL_CMD bit field */ +/* write value to FWDGT_RLD_RLD bit field */ +#define RLD_RLD(regval) (BITS(0,11) & ((uint32_t)(regval) << 0U)) /*!< write value to FWDGT_RLD_RLD bit field */ +/* write value to FWDGT_WND_WND bit field */ +#define WND_WND(regval) (BITS(0,11) & ((uint32_t)(regval) << 0U)) /*!< write value to FWDGT_WND_WND bit field */ + +/*! + \brief enable write access to FWDGT_PSC and FWDGT_RLD + \param[in] none + \param[out] none + \retval none +*/ +void fwdgt_write_enable(void) +{ + FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE; +} + +/*! + \brief disable write access to FWDGT_PSC,FWDGT_RLD and FWDGT_WND + \param[in] none + \param[out] none + \retval none +*/ +void fwdgt_write_disable(void) +{ + FWDGT_CTL = FWDGT_WRITEACCESS_DISABLE; +} + +/*! + \brief start the free watchdog timer counter + \param[in] none + \param[out] none + \retval none +*/ +void fwdgt_enable(void) +{ + FWDGT_CTL = FWDGT_KEY_ENABLE; +} + +/*! + \brief configure the free watchdog timer counter prescaler value + \param[in] prescaler_value: specify prescaler value + only one parameter can be selected which is shown as below: + \arg FWDGT_PSC_DIV4: FWDGT prescaler set to 4 + \arg FWDGT_PSC_DIV8: FWDGT prescaler set to 8 + \arg FWDGT_PSC_DIV16: FWDGT prescaler set to 16 + \arg FWDGT_PSC_DIV32: FWDGT prescaler set to 32 + \arg FWDGT_PSC_DIV64: FWDGT prescaler set to 64 + \arg FWDGT_PSC_DIV128: FWDGT prescaler set to 128 + \arg FWDGT_PSC_DIV256: FWDGT prescaler set to 256 + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus fwdgt_prescaler_value_config(uint16_t prescaler_value) +{ + uint32_t timeout = FWDGT_PSC_TIMEOUT; + uint32_t flag_status = RESET; + + /* enable write access to FWDGT_PSC */ + FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE; + + /* wait until the PUD flag to be reset */ + do{ + flag_status = FWDGT_STAT & FWDGT_STAT_PUD; + }while((--timeout > 0U) && ((uint32_t)RESET != flag_status)); + + if ((uint32_t)RESET != flag_status){ + return ERROR; + } + + /* configure FWDGT */ + FWDGT_PSC = (uint32_t)prescaler_value; + + return SUCCESS; +} + +/*! + \brief configure the free watchdog timer counter reload value + \param[in] reload_value: specify reload value(0x0000 - 0x0FFF) + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus fwdgt_reload_value_config(uint16_t reload_value) +{ + uint32_t timeout = FWDGT_RLD_TIMEOUT; + uint32_t flag_status = RESET; + + /* enable write access to FWDGT_RLD */ + FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE; + + /* wait until the RUD flag to be reset */ + do{ + flag_status = FWDGT_STAT & FWDGT_STAT_RUD; + }while((--timeout > 0U) && ((uint32_t)RESET != flag_status)); + + if ((uint32_t)RESET != flag_status){ + return ERROR; + } + + FWDGT_RLD = RLD_RLD(reload_value); + + return SUCCESS; +} + +/*! + \brief configure the free watchdog timer counter window value + \param[in] window_value: specify window value(0x0000 - 0x0FFF) + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus fwdgt_window_value_config(uint16_t window_value) +{ + uint32_t time_index = FWDGT_WND_TIMEOUT; + uint32_t flag_status = RESET; + + /* enable write access to FWDGT_WND */ + FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE; + + /* wait until the WUD flag to be reset */ + do{ + flag_status = FWDGT_STAT & FWDGT_STAT_WUD; + }while((--time_index > 0U) && ((uint32_t)RESET != flag_status)); + + if ((uint32_t)RESET != flag_status){ + return ERROR; + } + + FWDGT_WND = WND_WND(window_value); + + return SUCCESS; +} + +/*! + \brief reload the counter of FWDGT + \param[in] none + \param[out] none + \retval none +*/ +void fwdgt_counter_reload(void) +{ + FWDGT_CTL = FWDGT_KEY_RELOAD; +} + +/*! + \brief configure counter reload value, and prescaler divider value + \param[in] reload_value: specify reload value(0x0000 - 0x0FFF) + \param[in] prescaler_div: FWDGT prescaler value + only one parameter can be selected which is shown as below: + \arg FWDGT_PSC_DIV4: FWDGT prescaler set to 4 + \arg FWDGT_PSC_DIV8: FWDGT prescaler set to 8 + \arg FWDGT_PSC_DIV16: FWDGT prescaler set to 16 + \arg FWDGT_PSC_DIV32: FWDGT prescaler set to 32 + \arg FWDGT_PSC_DIV64: FWDGT prescaler set to 64 + \arg FWDGT_PSC_DIV128: FWDGT prescaler set to 128 + \arg FWDGT_PSC_DIV256: FWDGT prescaler set to 256 + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus fwdgt_config(uint16_t reload_value, uint8_t prescaler_div) +{ + uint32_t timeout = FWDGT_PSC_TIMEOUT; + uint32_t flag_status = RESET; + + /* enable write access to FWDGT_PSC,and FWDGT_RLD */ + FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE; + + /* wait until the PUD flag to be reset */ + do{ + flag_status = FWDGT_STAT & FWDGT_STAT_PUD; + }while((--timeout > 0U) && ((uint32_t)RESET != flag_status)); + + if ((uint32_t)RESET != flag_status){ + return ERROR; + } + + /* configure FWDGT */ + FWDGT_PSC = (uint32_t)prescaler_div; + + timeout = FWDGT_RLD_TIMEOUT; + /* wait until the RUD flag to be reset */ + do{ + flag_status = FWDGT_STAT & FWDGT_STAT_RUD; + }while((--timeout > 0U) && ((uint32_t)RESET != flag_status)); + + if ((uint32_t)RESET != flag_status){ + return ERROR; + } + + FWDGT_RLD = RLD_RLD(reload_value); + + /* reload the counter */ + FWDGT_CTL = FWDGT_KEY_RELOAD; + + return SUCCESS; +} + +/*! + \brief get flag state of FWDGT + \param[in] flag: flag to get + only one parameter can be selected which is shown as below: + \arg FWDGT_FLAG_PUD: a write operation to FWDGT_PSC register is on going + \arg FWDGT_FLAG_RUD: a write operation to FWDGT_RLD register is on going + \arg FWDGT_FLAG_WUD: a write operation to FWDGT_WND register is on going + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus fwdgt_flag_get(uint16_t flag) +{ + if(RESET != (FWDGT_STAT & flag)){ + return SET; + } + return RESET; +} diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_gpio.c b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_gpio.c new file mode 100644 index 0000000000000000000000000000000000000000..7223c98b8576c62ffe5f1a8dd4ccf91300c0ca53 --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_gpio.c @@ -0,0 +1,399 @@ +/*! + \file gd32e230_gpio.c + \brief GPIO driver + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor 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 copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 "gd32e230_gpio.h" + +/*! + \brief reset GPIO port + \param[in] gpio_periph: GPIOx(x = A,B,C,F) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,F) + \param[out] none + \retval none +*/ +void gpio_deinit(uint32_t gpio_periph) +{ + switch(gpio_periph){ + case GPIOA: + /* reset GPIOA */ + rcu_periph_reset_enable(RCU_GPIOARST); + rcu_periph_reset_disable(RCU_GPIOARST); + break; + case GPIOB: + /* reset GPIOB */ + rcu_periph_reset_enable(RCU_GPIOBRST); + rcu_periph_reset_disable(RCU_GPIOBRST); + break; + case GPIOC: + /* reset GPIOC */ + rcu_periph_reset_enable(RCU_GPIOCRST); + rcu_periph_reset_disable(RCU_GPIOCRST); + break; + case GPIOF: + /* reset GPIOF */ + rcu_periph_reset_enable(RCU_GPIOFRST); + rcu_periph_reset_disable(RCU_GPIOFRST); + break; + default: + break; + } +} + +/*! + \brief set GPIO mode + \param[in] gpio_periph: GPIOx(x = A,B,C,F) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,F) + \param[in] mode: gpio pin mode + \arg GPIO_MODE_INPUT: input mode + \arg GPIO_MODE_OUTPUT: output mode + \arg GPIO_MODE_AF: alternate function mode + \arg GPIO_MODE_ANALOG: analog mode + \param[in] pull_up_down: gpio pin with pull-up or pull-down resistor + \arg GPIO_PUPD_NONE: floating mode, no pull-up and pull-down resistors + \arg GPIO_PUPD_PULLUP: with pull-up resistor + \arg GPIO_PUPD_PULLDOWN:with pull-down resistor + \param[in] pin: GPIO pin + one or more parameters can be selected which are shown as below: + \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL + \param[out] none + \retval none +*/ +void gpio_mode_set(uint32_t gpio_periph, uint32_t mode, uint32_t pull_up_down, uint32_t pin) +{ + uint16_t i; + uint32_t ctl, pupd; + + ctl = GPIO_CTL(gpio_periph); + pupd = GPIO_PUD(gpio_periph); + + for(i = 0U;i < 16U;i++){ + if((1U << i) & pin){ + /* clear the specified pin mode bits */ + ctl &= ~GPIO_MODE_MASK(i); + /* set the specified pin mode bits */ + ctl |= GPIO_MODE_SET(i, mode); + + /* clear the specified pin pupd bits */ + pupd &= ~GPIO_PUPD_MASK(i); + /* set the specified pin pupd bits */ + pupd |= GPIO_PUPD_SET(i, pull_up_down); + } + } + + GPIO_CTL(gpio_periph) = ctl; + GPIO_PUD(gpio_periph) = pupd; +} + +/*! + \brief set GPIO output type and speed + \param[in] gpio_periph: GPIOx(x = A,B,C,F) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,F) + \param[in] otype: gpio pin output mode + \arg GPIO_OTYPE_PP: push pull mode + \arg GPIO_OTYPE_OD: open drain mode + \param[in] speed: gpio pin output max speed + \arg GPIO_OSPEED_2MHZ: output max speed 2MHz + \arg GPIO_OSPEED_10MHZ: output max speed 10MHz + \arg GPIO_OSPEED_50MHZ: output max speed 50MHz + \param[in] pin: GPIO pin + one or more parameters can be selected which are shown as below: + \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL + \param[out] none + \retval none +*/ +void gpio_output_options_set(uint32_t gpio_periph, uint8_t otype, uint32_t speed, uint32_t pin) +{ + uint16_t i; + uint32_t ospeed; + + if(GPIO_OTYPE_OD == otype){ + GPIO_OMODE(gpio_periph) |= (uint32_t)pin; + }else{ + GPIO_OMODE(gpio_periph) &= (uint32_t)(~pin); + } + + /* get the specified pin output speed bits value */ + ospeed = GPIO_OSPD(gpio_periph); + + for(i = 0U;i < 16U;i++){ + if((1U << i) & pin){ + /* clear the specified pin output speed bits */ + ospeed &= ~GPIO_OSPEED_MASK(i); + /* set the specified pin output speed bits */ + ospeed |= GPIO_OSPEED_SET(i,speed); + } + } + GPIO_OSPD(gpio_periph) = ospeed; +} + +/*! + \brief set GPIO pin bit + \param[in] gpio_periph: GPIOx(x = A,B,C,F) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,F) + \param[in] pin: GPIO pin + one or more parameters can be selected which are shown as below: + \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL + \param[out] none + \retval none +*/ +void gpio_bit_set(uint32_t gpio_periph, uint32_t pin) +{ + GPIO_BOP(gpio_periph) = (uint32_t)pin; +} + +/*! + \brief reset GPIO pin bit + \param[in] gpio_periph: GPIOx(x = A,B,C,F) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,F) + \param[in] pin: GPIO pin + one or more parameters can be selected which are shown as below: + \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL + \param[out] none + \retval none +*/ +void gpio_bit_reset(uint32_t gpio_periph, uint32_t pin) +{ + GPIO_BC(gpio_periph) = (uint32_t)pin; +} + +/*! + \brief write data to the specified GPIO pin + \param[in] gpio_periph: GPIOx(x = A,B,C,F) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,F) + \param[in] pin: GPIO pin + one or more parameters can be selected which are shown as below: + \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL + \param[in] bit_value: SET or RESET + \arg RESET: clear the port pin + \arg SET: set the port pin + \param[out] none + \retval none +*/ +void gpio_bit_write(uint32_t gpio_periph, uint32_t pin, bit_status bit_value) +{ + if(RESET != bit_value){ + GPIO_BOP(gpio_periph) = (uint32_t)pin; + }else{ + GPIO_BC(gpio_periph) = (uint32_t)pin; + } +} + +/*! + \brief write data to the specified GPIO port + \param[in] gpio_periph: GPIOx(x = A,B,C,F) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,F) + \param[in] data: specify the value to be written to the port output control register + \param[out] none + \retval none +*/ +void gpio_port_write(uint32_t gpio_periph, uint16_t data) +{ + GPIO_OCTL(gpio_periph) = (uint32_t)data; +} + +/*! + \brief get GPIO pin input status + \param[in] gpio_periph: GPIOx(x = A,B,C,F) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,F) + \param[in] pin: GPIO pin + one or more parameters can be selected which are shown as below: + \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL + \param[out] none + \retval SET or RESET +*/ +FlagStatus gpio_input_bit_get(uint32_t gpio_periph, uint32_t pin) +{ + if((uint32_t)RESET != (GPIO_ISTAT(gpio_periph)&(pin))){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief get GPIO all pins input status + \param[in] gpio_periph: GPIOx(x = A,B,C,F) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,F) + \param[out] none + \retval state of GPIO all pins +*/ +uint16_t gpio_input_port_get(uint32_t gpio_periph) +{ + return (uint16_t)GPIO_ISTAT(gpio_periph); +} + +/*! + \brief get GPIO pin output status + \param[in] gpio_periph: GPIOx(x = A,B,C,F) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,F) + \param[in] pin: GPIO pin + one or more parameters can be selected which are shown as below: + \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL + \param[out] none + \retval SET or RESET +*/ +FlagStatus gpio_output_bit_get(uint32_t gpio_periph, uint32_t pin) +{ + if((uint32_t)RESET != (GPIO_OCTL(gpio_periph)&(pin))){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief get GPIO all pins output status + \param[in] gpio_periph: GPIOx(x = A,B,C,F) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,F) + \param[out] none + \retval state of GPIO all pins +*/ +uint16_t gpio_output_port_get(uint32_t gpio_periph) +{ + return (uint16_t)GPIO_OCTL(gpio_periph); +} + +/*! + \brief set GPIO alternate function + \param[in] gpio_periph: GPIOx(x = A,B,C) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C) + \param[in] alt_func_num: GPIO pin af function, please refer to specific device datasheet + \arg GPIO_AF_0: TIMER13, TIMER14, TIMER16, SPI0, SPI1, I2S0, CK_OUT, USART0, + I2C0, I2C1, SWDIO, SWCLK + \arg GPIO_AF_1: USART0, USART1, TIMER2, TIMER14, I2C0, I2C1 + \arg GPIO_AF_2: TIMER0, TIMER1, TIMER15, TIMER16, I2S0 + \arg GPIO_AF_3: I2C0, TIMER14 + \arg GPIO_AF_4(port A,B only): USART1, I2C0, I2C1, TIMER13 + \arg GPIO_AF_5(port A,B only): TIMER15, TIMER16, I2S0 + \arg GPIO_AF_6(port A,B only): SPI1 + \arg GPIO_AF_7(port A,B only): CMP + \param[in] pin: GPIO pin + one or more parameters can be selected which are shown as below: + \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL + \param[out] none + \retval none +*/ +void gpio_af_set(uint32_t gpio_periph, uint32_t alt_func_num, uint32_t pin) +{ + uint16_t i; + uint32_t afrl, afrh; + + afrl = GPIO_AFSEL0(gpio_periph); + afrh = GPIO_AFSEL1(gpio_periph); + + for(i = 0U;i < 8U;i++){ + if((1U << i) & pin){ + /* clear the specified pin alternate function bits */ + afrl &= ~GPIO_AFR_MASK(i); + afrl |= GPIO_AFR_SET(i,alt_func_num); + } + } + + for(i = 8U;i < 16U;i++){ + if((1U << i) & pin){ + /* clear the specified pin alternate function bits */ + afrh &= ~GPIO_AFR_MASK(i - 8U); + afrh |= GPIO_AFR_SET(i - 8U,alt_func_num); + } + } + + GPIO_AFSEL0(gpio_periph) = afrl; + GPIO_AFSEL1(gpio_periph) = afrh; +} + +/*! + \brief lock GPIO pin bit + \param[in] gpio_periph: GPIOx(x = A,B) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B) + \param[in] pin: GPIO pin + one or more parameters can be selected which are shown as below: + \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL + \param[out] none + \retval none +*/ +void gpio_pin_lock(uint32_t gpio_periph, uint32_t pin) +{ + uint32_t lock = 0x00010000U; + lock |= pin; + + /* lock key writing sequence: write 1->write 0->write 1->read 0->read 1 */ + GPIO_LOCK(gpio_periph) = (uint32_t)lock; + GPIO_LOCK(gpio_periph) = (uint32_t)pin; + GPIO_LOCK(gpio_periph) = (uint32_t)lock; + lock = GPIO_LOCK(gpio_periph); + lock = GPIO_LOCK(gpio_periph); +} + +/*! + \brief toggle GPIO pin status + \param[in] gpio_periph: GPIOx(x = A,B,C,F) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,F) + \param[in] pin: GPIO pin + one or more parameters can be selected which are shown as below: + \arg GPIO_PIN_x(x=0..15), GPIO_PIN_ALL + \param[out] none + \retval none +*/ +void gpio_bit_toggle(uint32_t gpio_periph, uint32_t pin) +{ + GPIO_TG(gpio_periph) = (uint32_t)pin; +} + +/*! + \brief toggle GPIO port status + \param[in] gpio_periph: GPIOx(x = A,B,C,F) + only one parameter can be selected which is shown as below: + \arg GPIOx(x = A,B,C,F) + \param[out] none + \retval none +*/ +void gpio_port_toggle(uint32_t gpio_periph) +{ + GPIO_TG(gpio_periph) = 0x0000FFFFU; +} diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_i2c.c b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_i2c.c new file mode 100644 index 0000000000000000000000000000000000000000..89fb7f52e97dcc191c068631918879d7e10dd769 --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_i2c.c @@ -0,0 +1,797 @@ +/*! + \file gd32e230_i2c.c + \brief I2C driver + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor 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 copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 "gd32e230_i2c.h" + +/* I2C register bit mask */ +#define I2CCLK_MAX ((uint32_t)0x0000007FU) /*!< i2cclk maximum value */ +#define I2CCLK_MIN ((uint32_t)0x00000002U) /*!< i2cclk minimum value */ +#define I2C_FLAG_MASK ((uint32_t)0x0000FFFFU) /*!< i2c flag mask */ +#define I2C_ADDRESS_MASK ((uint32_t)0x000003FFU) /*!< i2c address mask */ +#define I2C_ADDRESS2_MASK ((uint32_t)0x000000FEU) /*!< the second i2c address mask */ + +/* I2C register bit offset */ +#define STAT1_PECV_OFFSET ((uint32_t)8U) /* bit offset of PECV in I2C_STAT1 */ + +/*! + \brief reset I2C + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_deinit(uint32_t i2c_periph) +{ + switch(i2c_periph){ + case I2C0: + /* reset I2C0 */ + rcu_periph_reset_enable(RCU_I2C0RST); + rcu_periph_reset_disable(RCU_I2C0RST); + break; + case I2C1: + /* reset I2C1 */ + rcu_periph_reset_enable(RCU_I2C1RST); + rcu_periph_reset_disable(RCU_I2C1RST); + break; + default: + break; + } +} + +/*! + \brief configure I2C clock + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] clkspeed: I2C clock speed, supports standard mode (up to 100 kHz), fast mode (up to 400 kHz) + and fast mode plus (up to 1MHz) + \param[in] dutycyc: duty cycle in fast mode or fast mode plus + only one parameter can be selected which is shown as below: + \arg I2C_DTCY_2: T_low/T_high=2 + \arg I2C_DTCY_16_9: T_low/T_high=16/9 + \param[out] none + \retval none +*/ +void i2c_clock_config(uint32_t i2c_periph, uint32_t clkspeed, uint32_t dutycyc) +{ + uint32_t pclk1, clkc, freq, risetime; + uint32_t temp; + + pclk1 = rcu_clock_freq_get(CK_APB1); + /* I2C peripheral clock frequency */ + freq = (uint32_t)(pclk1/1000000U); + if(freq >= I2CCLK_MAX){ + freq = I2CCLK_MAX; + } + temp = I2C_CTL1(i2c_periph); + temp &= ~I2C_CTL1_I2CCLK; + temp |= freq; + + I2C_CTL1(i2c_periph) = temp; + + if(100000U >= clkspeed){ + /* the maximum SCL rise time is 1000ns in standard mode */ + risetime = (uint32_t)((pclk1/1000000U)+1U); + if(risetime >= I2CCLK_MAX){ + I2C_RT(i2c_periph) = I2CCLK_MAX; + }else if(risetime <= I2CCLK_MIN){ + I2C_RT(i2c_periph) = I2CCLK_MIN; + }else{ + I2C_RT(i2c_periph) = risetime; + } + clkc = (uint32_t)(pclk1/(clkspeed*2U)); + if(clkc < 0x04U){ + /* the CLKC in standard mode minmum value is 4 */ + clkc = 0x04U; + } + I2C_CKCFG(i2c_periph) |= (I2C_CKCFG_CLKC & clkc); + + }else if(400000U >= clkspeed){ + /* the maximum SCL rise time is 300ns in fast mode */ + I2C_RT(i2c_periph) = (uint32_t)(((freq*(uint32_t)300U)/(uint32_t)1000U)+(uint32_t)1U); + if(I2C_DTCY_2 == dutycyc){ + /* I2C duty cycle is 2 */ + clkc = (uint32_t)(pclk1/(clkspeed*3U)); + I2C_CKCFG(i2c_periph) &= ~I2C_CKCFG_DTCY; + }else{ + /* I2C duty cycle is 16/9 */ + clkc = (uint32_t)(pclk1/(clkspeed*25U)); + I2C_CKCFG(i2c_periph) |= I2C_CKCFG_DTCY; + } + if(0U == (clkc & I2C_CKCFG_CLKC)){ + /* the CLKC in fast mode minmum value is 1 */ + clkc |= 0x0001U; + } + I2C_CKCFG(i2c_periph) |= I2C_CKCFG_FAST; + I2C_CKCFG(i2c_periph) |= clkc; + }else{ + /* fast mode plus, the maximum SCL rise time is 120ns */ + I2C_RT(i2c_periph) = (uint32_t)(((freq*(uint32_t)120U)/(uint32_t)1000U)+(uint32_t)1U); + if(I2C_DTCY_2 == dutycyc){ + /* I2C duty cycle is 2 */ + clkc = (uint32_t)(pclk1/(clkspeed*3U)); + I2C_CKCFG(i2c_periph) &= ~I2C_CKCFG_DTCY; + }else{ + /* I2C duty cycle is 16/9 */ + clkc = (uint32_t)(pclk1/(clkspeed*25U)); + I2C_CKCFG(i2c_periph) |= I2C_CKCFG_DTCY; + } + /* enable fast mode */ + I2C_CKCFG(i2c_periph) |= I2C_CKCFG_FAST; + I2C_CKCFG(i2c_periph) |= clkc; + /* enable I2C fast mode plus */ + I2C_FMPCFG(i2c_periph) = I2C_FMPCFG_FMPEN; + } +} + +/*! + \brief configure I2C address + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] mode: + only one parameter can be selected which is shown as below: + \arg I2C_I2CMODE_ENABLE: I2C mode + \arg I2C_SMBUSMODE_ENABLE: SMBus mode + \param[in] addformat: 7bits or 10bits + only one parameter can be selected which is shown as below: + \arg I2C_ADDFORMAT_7BITS: 7bits + \arg I2C_ADDFORMAT_10BITS: 10bits + \param[in] addr: I2C address + \param[out] none + \retval none +*/ +void i2c_mode_addr_config(uint32_t i2c_periph, uint32_t mode, uint32_t addformat, uint32_t addr) +{ + /* SMBus/I2C mode selected */ + uint32_t ctl = 0U; + + ctl = I2C_CTL0(i2c_periph); + ctl &= ~(I2C_CTL0_SMBEN); + ctl |= mode; + I2C_CTL0(i2c_periph) = ctl; + /* configure address */ + addr = addr & I2C_ADDRESS_MASK; + I2C_SADDR0(i2c_periph) = (addformat | addr); +} + +/*! + \brief SMBus type selection + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] type: + only one parameter can be selected which is shown as below: + \arg I2C_SMBUS_DEVICE: device + \arg I2C_SMBUS_HOST: host + \param[out] none + \retval none +*/ +void i2c_smbus_type_config(uint32_t i2c_periph, uint32_t type) +{ + if(I2C_SMBUS_HOST == type){ + I2C_CTL0(i2c_periph) |= I2C_CTL0_SMBSEL; + }else{ + I2C_CTL0(i2c_periph) &= ~(I2C_CTL0_SMBSEL); + } +} + +/*! + \brief whether or not to send an ACK + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] ack: + only one parameter can be selected which is shown as below: + \arg I2C_ACK_ENABLE: ACK will be sent + \arg I2C_ACK_DISABLE: ACK will not be sent + \param[out] none + \retval none +*/ +void i2c_ack_config(uint32_t i2c_periph, uint32_t ack) +{ + if(I2C_ACK_ENABLE == ack){ + I2C_CTL0(i2c_periph) |= I2C_CTL0_ACKEN; + }else{ + I2C_CTL0(i2c_periph) &= ~(I2C_CTL0_ACKEN); + } +} + +/*! + \brief configure I2C POAP position + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] pos: + only one parameter can be selected which is shown as below: + \arg I2C_ACKPOS_CURRENT: whether to send ACK or not for the current + \arg I2C_ACKPOS_NEXT: whether to send ACK or not for the next byte + \param[out] none + \retval none +*/ +void i2c_ackpos_config(uint32_t i2c_periph, uint32_t pos) +{ + /* configure I2C POAP position */ + if(I2C_ACKPOS_NEXT == pos){ + I2C_CTL0(i2c_periph) |= I2C_CTL0_POAP; + }else{ + I2C_CTL0(i2c_periph) &= ~(I2C_CTL0_POAP); + } +} + +/*! + \brief master sends slave address + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] addr: slave address + \param[in] trandirection: transmitter or receiver + only one parameter can be selected which is shown as below: + \arg I2C_TRANSMITTER: transmitter + \arg I2C_RECEIVER: receiver + \param[out] none + \retval none +*/ +void i2c_master_addressing(uint32_t i2c_periph, uint32_t addr, uint32_t trandirection) +{ + /* master is a transmitter or a receiver */ + if(I2C_TRANSMITTER == trandirection){ + addr = addr & I2C_TRANSMITTER; + }else{ + addr = addr | I2C_RECEIVER; + } + /* send slave address */ + I2C_DATA(i2c_periph) = addr; +} + +/*! + \brief enable dual-address mode + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] addr: the second address in dual-address mode + \param[out] none + \retval none +*/ +void i2c_dualaddr_enable(uint32_t i2c_periph, uint32_t addr) +{ + /* configure address */ + addr = addr & I2C_ADDRESS2_MASK; + I2C_SADDR1(i2c_periph) = (I2C_SADDR1_DUADEN | addr); +} + +/*! + \brief disable dual-address mode + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_dualaddr_disable(uint32_t i2c_periph) +{ + I2C_SADDR1(i2c_periph) &= ~(I2C_SADDR1_DUADEN); +} + +/*! + \brief enable I2C + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_enable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) |= I2C_CTL0_I2CEN; +} + +/*! + \brief disable I2C + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_disable(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) &= ~(I2C_CTL0_I2CEN); +} + +/*! + \brief generate a START condition on I2C bus + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_start_on_bus(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) |= I2C_CTL0_START; +} + +/*! + \brief generate a STOP condition on I2C bus + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_stop_on_bus(uint32_t i2c_periph) +{ + I2C_CTL0(i2c_periph) |= I2C_CTL0_STOP; +} + +/*! + \brief I2C transmit data function + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] data: data of transmission + \param[out] none + \retval none +*/ +void i2c_data_transmit(uint32_t i2c_periph, uint8_t data) +{ + I2C_DATA(i2c_periph) = DATA_TRANS(data); +} + +/*! + \brief I2C receive data function + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval data of received +*/ +uint8_t i2c_data_receive(uint32_t i2c_periph) +{ + return (uint8_t)DATA_RECV(I2C_DATA(i2c_periph)); +} + +/*! + \brief enable I2C DMA mode + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] dmastate: + only one parameter can be selected which is shown as below: + \arg I2C_DMA_ON: DMA mode enable + \arg I2C_DMA_OFF: DMA mode disable + \param[out] none + \retval none +*/ +void i2c_dma_enable(uint32_t i2c_periph, uint32_t dmastate) +{ + /* configure I2C DMA function */ + uint32_t ctl = 0U; + + ctl = I2C_CTL1(i2c_periph); + ctl &= ~(I2C_CTL1_DMAON); + ctl |= dmastate; + I2C_CTL1(i2c_periph) = ctl; +} + +/*! + \brief configure whether next DMA EOT is DMA last transfer or not + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] dmalast: + only one parameter can be selected which is shown as below: + \arg I2C_DMALST_ON: next DMA EOT is the last transfer + \arg I2C_DMALST_OFF: next DMA EOT is not the last transfer + \param[out] none + \retval none +*/ +void i2c_dma_last_transfer_config(uint32_t i2c_periph, uint32_t dmalast) +{ + /* configure DMA last transfer */ + uint32_t ctl = 0U; + + ctl = I2C_CTL1(i2c_periph); + ctl &= ~(I2C_CTL1_DMALST); + ctl |= dmalast; + I2C_CTL1(i2c_periph) = ctl; +} + +/*! + \brief whether to stretch SCL low when data is not ready in slave mode + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] stretchpara: + only one parameter can be selected which is shown as below: + \arg I2C_SCLSTRETCH_ENABLE: SCL stretching is enabled + \arg I2C_SCLSTRETCH_DISABLE: SCL stretching is disabled + \param[out] none + \retval none +*/ +void i2c_stretch_scl_low_config(uint32_t i2c_periph, uint32_t stretchpara) +{ + /* configure I2C SCL strerching enable or disable */ + uint32_t ctl = 0U; + + ctl = I2C_CTL0(i2c_periph); + ctl &= ~(I2C_CTL0_SS); + ctl |= stretchpara; + I2C_CTL0(i2c_periph) = ctl; +} + +/*! + \brief whether or not to response to a general call + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] gcallpara: + only one parameter can be selected which is shown as below: + \arg I2C_GCEN_ENABLE: slave will response to a general call + \arg I2C_GCEN_DISABLE: slave will not response to a general call + \param[out] none + \retval none +*/ +void i2c_slave_response_to_gcall_config(uint32_t i2c_periph, uint32_t gcallpara) +{ + /* configure slave response to a general call enable or disable */ + uint32_t ctl = 0U; + + ctl = I2C_CTL0(i2c_periph); + ctl &= ~(I2C_CTL0_GCEN); + ctl |= gcallpara; + I2C_CTL0(i2c_periph) = ctl; +} + +/*! + \brief software reset I2C + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] sreset: + only one parameter can be selected which is shown as below: + \arg I2C_SRESET_SET: I2C is under reset + \arg I2C_SRESET_RESET: I2C is not under reset + \param[out] none + \retval none +*/ +void i2c_software_reset_config(uint32_t i2c_periph, uint32_t sreset) +{ + /* modify CTL0 and configure software reset I2C state */ + uint32_t ctl = 0U; + + ctl = I2C_CTL0(i2c_periph); + ctl &= ~(I2C_CTL0_SRESET); + ctl |= sreset; + I2C_CTL0(i2c_periph) = ctl; +} + +/*! + \brief I2C PEC calculation on or off + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] pecpara: + only one parameter can be selected which is shown as below: + \arg I2C_PEC_ENABLE: PEC calculation on + \arg I2C_PEC_DISABLE: PEC calculation off + \param[out] none + \retval none +*/ +void i2c_pec_enable(uint32_t i2c_periph, uint32_t pecstate) +{ + /* on/off PEC calculation */ + uint32_t ctl = 0U; + + ctl = I2C_CTL0(i2c_periph); + ctl &= ~(I2C_CTL0_PECEN); + ctl |= pecstate; + I2C_CTL0(i2c_periph) = ctl; +} + +/*! + \brief I2C whether to transfer PEC value + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] pecpara: + only one parameter can be selected which is shown as below: + \arg I2C_PECTRANS_ENABLE: transfer PEC + \arg I2C_PECTRANS_DISABLE: not transfer PEC + \param[out] none + \retval none +*/ +void i2c_pec_transfer_enable(uint32_t i2c_periph, uint32_t pecpara) +{ + /* whether to transfer PEC */ + uint32_t ctl = 0U; + + ctl = I2C_CTL0(i2c_periph); + ctl &= ~(I2C_CTL0_PECTRANS); + ctl |= pecpara; + I2C_CTL0(i2c_periph) = ctl; +} + +/*! + \brief get packet error checking value + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval PEC value +*/ +uint8_t i2c_pec_value_get(uint32_t i2c_periph) +{ + return (uint8_t)((I2C_STAT1(i2c_periph) & I2C_STAT1_PECV)>>STAT1_PECV_OFFSET); +} + +/*! + \brief I2C issue alert through SMBA pin + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] smbuspara: + only one parameter can be selected which is shown as below: + \arg I2C_SALTSEND_ENABLE: issue alert through SMBA pin + \arg I2C_SALTSEND_DISABLE: not issue alert through SMBA pin + \param[out] none + \retval none +*/ +void i2c_smbus_issue_alert(uint32_t i2c_periph, uint32_t smbuspara) +{ + /* issue alert through SMBA pin configure*/ + uint32_t ctl = 0U; + + ctl = I2C_CTL0(i2c_periph); + ctl &= ~(I2C_CTL0_SALT); + ctl |= smbuspara; + I2C_CTL0(i2c_periph) = ctl; +} + +/*! + \brief enable or disable I2C ARP protocol in SMBus switch + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] smbuspara: + only one parameter can be selected which is shown as below: + \arg I2C_ARP_ENABLE: enable ARP + \arg I2C_ARP_DISABLE: disable ARP + \param[out] none + \retval none +*/ +void i2c_smbus_arp_enable(uint32_t i2c_periph, uint32_t arpstate) +{ + /* enable or disable I2C ARP protocol*/ + uint32_t ctl = 0U; + + ctl = I2C_CTL0(i2c_periph); + ctl &= ~(I2C_CTL0_ARPEN); + ctl |= arpstate; + I2C_CTL0(i2c_periph) = ctl; +} + +/*! + \brief enable SAM_V interface + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_sam_enable(uint32_t i2c_periph) +{ + I2C_SAMCS(i2c_periph) |= I2C_SAMCS_SAMEN; +} + +/*! + \brief disable SAM_V interface + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_sam_disable(uint32_t i2c_periph) +{ + I2C_SAMCS(i2c_periph) &= ~(I2C_SAMCS_SAMEN); +} + +/*! + \brief enable SAM_V interface timeout detect + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_sam_timeout_enable(uint32_t i2c_periph) +{ + I2C_SAMCS(i2c_periph) |= I2C_SAMCS_STOEN; +} + +/*! + \brief disable SAM_V interface timeout detect + \param[in] i2c_periph: I2Cx(x=0,1) + \param[out] none + \retval none +*/ +void i2c_sam_timeout_disable(uint32_t i2c_periph) +{ + I2C_SAMCS(i2c_periph) &= ~(I2C_SAMCS_STOEN); +} + +/*! + \brief check I2C flag is set or not + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] flag: I2C flags, refer to i2c_flag_enum + only one parameter can be selected which is shown as below: + \arg I2C_FLAG_SBSEND: start condition send out + \arg I2C_FLAG_ADDSEND: address is sent in master mode or received and matches in slave mode + \arg I2C_FLAG_BTC: byte transmission finishes + \arg I2C_FLAG_ADD10SEND: header of 10-bit address is sent in master mode + \arg I2C_FLAG_STPDET: stop condition detected in slave mode + \arg I2C_FLAG_RBNE: I2C_DATA is not Empty during receiving + \arg I2C_FLAG_TBE: I2C_DATA is empty during transmitting + \arg I2C_FLAG_BERR: a bus error occurs indication a unexpected start or stop condition on I2C bus + \arg I2C_FLAG_LOSTARB: arbitration lost in master mode + \arg I2C_FLAG_AERR: acknowledge error + \arg I2C_FLAG_OUERR: overrun or underrun situation occurs in slave mode + \arg I2C_FLAG_PECERR: PEC error when receiving data + \arg I2C_FLAG_SMBTO: timeout signal in SMBus mode + \arg I2C_FLAG_SMBALT: SMBus alert status + \arg I2C_FLAG_MASTER: a flag indicating whether I2C block is in master or slave mode + \arg I2C_FLAG_I2CBSY: busy flag + \arg I2C_FLAG_TR: whether the I2C is a transmitter or a receiver + \arg I2C_FLAG_RXGC: general call address (00h) received + \arg I2C_FLAG_DEFSMB: default address of SMBus device + \arg I2C_FLAG_HSTSMB: SMBus host header detected in slave mode + \arg I2C_FLAG_DUMOD: dual flag in slave mode indicating which address is matched in dual-address mode + \arg I2C_FLAG_TFF: txframe fall flag + \arg I2C_FLAG_TFR: txframe rise flag + \arg I2C_FLAG_RFF: rxframe fall flag + \arg I2C_FLAG_RFR: rxframe rise flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus i2c_flag_get(uint32_t i2c_periph, i2c_flag_enum flag) +{ + if(RESET != (I2C_REG_VAL(i2c_periph, flag) & BIT(I2C_BIT_POS(flag)))){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear I2C flag + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] flag: I2C flags, refer to i2c_flag_enum + only one parameter can be selected which is shown as below: + \arg I2C_FLAG_SMBALT: SMBus Alert status + \arg I2C_FLAG_SMBTO: timeout signal in SMBus mode + \arg I2C_FLAG_PECERR: PEC error when receiving data + \arg I2C_FLAG_OUERR: over-run or under-run situation occurs in slave mode + \arg I2C_FLAG_AERR: acknowledge error + \arg I2C_FLAG_LOSTARB: arbitration lost in master mode + \arg I2C_FLAG_BERR: a bus error + \arg I2C_FLAG_ADDSEND: cleared by reading I2C_STAT0 and reading I2C_STAT1 + \arg I2C_FLAG_TFF: txframe fall flag + \arg I2C_FLAG_TFR: txframe rise flag + \arg I2C_FLAG_RFF: rxframe fall flag + \arg I2C_FLAG_RFR: rxframe rise flag + \param[out] none + \retval none +*/ +void i2c_flag_clear(uint32_t i2c_periph, i2c_flag_enum flag) +{ + if(I2C_FLAG_ADDSEND == flag){ + /* read I2C_STAT0 and then read I2C_STAT1 to clear ADDSEND */ + I2C_STAT0(i2c_periph); + I2C_STAT1(i2c_periph); + }else{ + I2C_REG_VAL(i2c_periph, flag) &= ~BIT(I2C_BIT_POS(flag)); + } +} + +/*! + \brief enable I2C interrupt + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] interrupt: I2C interrupts, refer to i2c_interrupt_enum + only one parameter can be selected which is shown as below: + \arg I2C_INT_ERR: error interrupt enable + \arg I2C_INT_EV: event interrupt enable + \arg I2C_INT_BUF: buffer interrupt enable + \arg I2C_INT_TFF: txframe fall interrupt enable + \arg I2C_INT_TFR: txframe rise interrupt enable + \arg I2C_INT_RFF: rxframe fall interrupt enable + \arg I2C_INT_RFR: rxframe rise interrupt enable + \param[out] none + \retval none +*/ +void i2c_interrupt_enable(uint32_t i2c_periph, i2c_interrupt_enum interrupt) +{ + I2C_REG_VAL(i2c_periph, interrupt) |= BIT(I2C_BIT_POS(interrupt)); +} + +/*! + \brief disable I2C interrupt + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] interrupt: I2C interrupts, refer to i2c_flag_enum + only one parameter can be selected which is shown as below: + \arg I2C_INT_ERR: error interrupt enable + \arg I2C_INT_EV: event interrupt enable + \arg I2C_INT_BUF: buffer interrupt enable + \arg I2C_INT_TFF: txframe fall interrupt enable + \arg I2C_INT_TFR: txframe rise interrupt enable + \arg I2C_INT_RFF: rxframe fall interrupt enable + \arg I2C_INT_RFR: rxframe rise interrupt enable + \param[out] none + \retval none +*/ +void i2c_interrupt_disable(uint32_t i2c_periph, i2c_interrupt_enum interrupt) +{ + I2C_REG_VAL(i2c_periph, interrupt) &= ~BIT(I2C_BIT_POS(interrupt)); +} + +/*! + \brief check I2C interrupt flag + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] int_flag: I2C interrupt flags, refer to i2c_interrupt_flag_enum + only one parameter can be selected which is shown as below: + \arg I2C_INT_FLAG_SBSEND: start condition sent out in master mode interrupt flag + \arg I2C_INT_FLAG_ADDSEND: address is sent in master mode or received and matches in slave mode interrupt flag + \arg I2C_INT_FLAG_BTC: byte transmission finishes + \arg I2C_INT_FLAG_ADD10SEND: header of 10-bit address is sent in master mode interrupt flag + \arg I2C_INT_FLAG_STPDET: etop condition detected in slave mode interrupt flag + \arg I2C_INT_FLAG_RBNE: I2C_DATA is not Empty during receiving interrupt flag + \arg I2C_INT_FLAG_TBE: I2C_DATA is empty during transmitting interrupt flag + \arg I2C_INT_FLAG_BERR: a bus error occurs indication a unexpected start or stop condition on I2C bus interrupt flag + \arg I2C_INT_FLAG_LOSTARB: arbitration lost in master mode interrupt flag + \arg I2C_INT_FLAG_AERR: acknowledge error interrupt flag + \arg I2C_INT_FLAG_OUERR: over-run or under-run situation occurs in slave mode interrupt flag + \arg I2C_INT_FLAG_PECERR: PEC error when receiving data interrupt flag + \arg I2C_INT_FLAG_SMBTO: timeout signal in SMBus mode interrupt flag + \arg I2C_INT_FLAG_SMBALT: SMBus Alert status interrupt flag + \arg I2C_INT_FLAG_TFF: txframe fall interrupt flag + \arg I2C_INT_FLAG_TFR: txframe rise interrupt flag + \arg I2C_INT_FLAG_RFF: rxframe fall interrupt flag + \arg I2C_INT_FLAG_RFR: rxframe rise interrupt flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus i2c_interrupt_flag_get(uint32_t i2c_periph, i2c_interrupt_flag_enum int_flag) +{ + uint32_t intenable = 0U, flagstatus = 0U, bufie; + + /* check BUFIE */ + bufie = I2C_CTL1(i2c_periph)&I2C_CTL1_BUFIE; + + /* get the interrupt enable bit status */ + intenable = (I2C_REG_VAL(i2c_periph, int_flag) & BIT(I2C_BIT_POS(int_flag))); + /* get the corresponding flag bit status */ + flagstatus = (I2C_REG_VAL2(i2c_periph, int_flag) & BIT(I2C_BIT_POS2(int_flag))); + + if((I2C_INT_FLAG_RBNE == int_flag) || (I2C_INT_FLAG_TBE == int_flag)){ + if(intenable && bufie){ + intenable = 1U; + }else{ + intenable = 0U; + } + } + if((0U != flagstatus) && (0U != intenable)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear I2C interrupt flag + \param[in] i2c_periph: I2Cx(x=0,1) + \param[in] intflag: I2C interrupt flags, refer to i2c_interrupt_flag_enum + only one parameter can be selected which is shown as below: + \arg I2C_INT_FLAG_ADDSEND: address is sent in master mode or received and matches in slave mode interrupt flag + \arg I2C_INT_FLAG_BERR: a bus error occurs indication a unexpected start or stop condition on I2C bus interrupt flag + \arg I2C_INT_FLAG_LOSTARB: arbitration lost in master mode interrupt flag + \arg I2C_INT_FLAG_AERR: acknowledge error interrupt flag + \arg I2C_INT_FLAG_OUERR: over-run or under-run situation occurs in slave mode interrupt flag + \arg I2C_INT_FLAG_PECERR: PEC error when receiving data interrupt flag + \arg I2C_INT_FLAG_SMBTO: timeout signal in SMBus mode interrupt flag + \arg I2C_INT_FLAG_SMBALT: SMBus Alert status interrupt flag + \arg I2C_INT_FLAG_TFF: txframe fall interrupt flag + \arg I2C_INT_FLAG_TFR: txframe rise interrupt flag + \arg I2C_INT_FLAG_RFF: rxframe fall interrupt flag + \arg I2C_INT_FLAG_RFR: rxframe rise interrupt flag + \param[out] none + \retval none +*/ +void i2c_interrupt_flag_clear(uint32_t i2c_periph, i2c_interrupt_flag_enum int_flag) +{ + if(I2C_INT_FLAG_ADDSEND == int_flag){ + /* read I2C_STAT0 and then read I2C_STAT1 to clear ADDSEND */ + I2C_STAT0(i2c_periph); + I2C_STAT1(i2c_periph); + }else{ + I2C_REG_VAL2(i2c_periph, int_flag) &= ~BIT(I2C_BIT_POS2(int_flag)); + } +} diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_misc.c b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_misc.c new file mode 100644 index 0000000000000000000000000000000000000000..eac0dc0958b5604a559b729b1e886d2d696bd938 --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_misc.c @@ -0,0 +1,142 @@ +/*! + \file gd32e230_misc.c + \brief MISC driver + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor 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 copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 "gd32e230_misc.h" + +/*! + \brief enable NVIC request + \param[in] nvic_irq: the NVIC interrupt request, detailed in IRQn_Type + \param[in] nvic_irq_priority: the priority needed to set (0-3) + \param[out] none + \retval none +*/ +void nvic_irq_enable(uint8_t nvic_irq, + uint8_t nvic_irq_priority) +{ + /* set the priority and enable the selected IRQ */ + NVIC_SetPriority((IRQn_Type)nvic_irq, (uint32_t)nvic_irq_priority); + NVIC_EnableIRQ((IRQn_Type)nvic_irq); +} + +/*! + \brief disable NVIC request + \param[in] nvic_irq: the NVIC interrupt request, detailed in IRQn_Type + \param[out] none + \retval none +*/ +void nvic_irq_disable(uint8_t nvic_irq) +{ + /* disable the selected IRQ.*/ + NVIC_DisableIRQ((IRQn_Type)nvic_irq); +} + +/* */ +/*! + \brief initiates a system reset request to reset the MCU + \param[in] none + \param[out] none + \retval none +*/ +void nvic_system_reset(void) +{ + NVIC_SystemReset(); +} + +/*! + \brief set the NVIC vector table base address + \param[in] nvic_vict_tab: the RAM or FLASH base address + \arg NVIC_VECTTAB_RAM: RAM base address + \arg NVIC_VECTTAB_FLASH: Flash base address + \param[in] offset: Vector Table offset + \param[out] none + \retval none +*/ +void nvic_vector_table_set(uint32_t nvic_vict_tab, uint32_t offset) +{ + SCB->VTOR = nvic_vict_tab | (offset & NVIC_VECTTAB_OFFSET_MASK); +} + +/*! + \brief set the state of the low power mode + \param[in] lowpower_mode: the low power mode state + \arg SCB_LPM_SLEEP_EXIT_ISR: if chose this para, the system always enter low power + mode by exiting from ISR + \arg SCB_LPM_DEEPSLEEP: if chose this para, the system will enter the DEEPSLEEP mode + \arg SCB_LPM_WAKE_BY_ALL_INT: if chose this para, the lowpower mode can be woke up + by all the enable and disable interrupts + \param[out] none + \retval none +*/ +void system_lowpower_set(uint8_t lowpower_mode) +{ + SCB->SCR |= (uint32_t)lowpower_mode; +} + +/*! + \brief reset the state of the low power mode + \param[in] lowpower_mode: the low power mode state + \arg SCB_LPM_SLEEP_EXIT_ISR: if chose this para, the system will exit low power + mode by exiting from ISR + \arg SCB_LPM_DEEPSLEEP: if chose this para, the system will enter the SLEEP mode + \arg SCB_LPM_WAKE_BY_ALL_INT: if chose this para, the lowpower mode only can be + woke up by the enable interrupts + \param[out] none + \retval none +*/ +void system_lowpower_reset(uint8_t lowpower_mode) +{ + SCB->SCR &= (~(uint32_t)lowpower_mode); +} + +/*! + \brief set the systick clock source + \param[in] systick_clksource: the systick clock source needed to choose + \arg SYSTICK_CLKSOURCE_HCLK: systick clock source is from HCLK + \arg SYSTICK_CLKSOURCE_HCLK_DIV8: systick clock source is from HCLK/8 + \param[out] none + \retval none +*/ + +void systick_clksource_set(uint32_t systick_clksource) +{ + if(SYSTICK_CLKSOURCE_HCLK == systick_clksource ){ + /* set the systick clock source from HCLK */ + SysTick->CTRL |= SYSTICK_CLKSOURCE_HCLK; + }else{ + /* set the systick clock source from HCLK/8 */ + SysTick->CTRL &= SYSTICK_CLKSOURCE_HCLK_DIV8; + } +} diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_pmu.c b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_pmu.c new file mode 100644 index 0000000000000000000000000000000000000000..53e8a2e521ed0557213e03061231408e10b17184 --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_pmu.c @@ -0,0 +1,301 @@ +/*! + \file gd32e230_pmu.c + \brief PMU driver + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor 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 copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 "gd32e230_pmu.h" + +/*! + \brief reset PMU register + \param[in] none + \param[out] none + \retval none +*/ +void pmu_deinit(void) +{ + /* reset PMU */ + rcu_periph_reset_enable(RCU_PMURST); + rcu_periph_reset_disable(RCU_PMURST); +} + +/*! + \brief select low voltage detector threshold + \param[in] lvdt_n: + only one parameter can be selected which is shown as below: + \arg PMU_LVDT_0: voltage threshold is 2.1V + \arg PMU_LVDT_1: voltage threshold is 2.3V + \arg PMU_LVDT_2: voltage threshold is 2.4V + \arg PMU_LVDT_3: voltage threshold is 2.6V + \arg PMU_LVDT_4: voltage threshold is 2.7V + \arg PMU_LVDT_5: voltage threshold is 2.9V + \arg PMU_LVDT_6: voltage threshold is 3.0V + \arg PMU_LVDT_7: voltage threshold is 3.1V + \param[out] none + \retval none +*/ +void pmu_lvd_select(uint32_t lvdt_n) +{ + /* disable LVD */ + PMU_CTL &= ~PMU_CTL_LVDEN; + /* clear LVDT bits */ + PMU_CTL &= ~PMU_CTL_LVDT; + /* set LVDT bits according to lvdt_n */ + PMU_CTL |= lvdt_n; + /* enable LVD */ + PMU_CTL |= PMU_CTL_LVDEN; +} + +/*! + \brief select LDO output voltage + these bits set by software when the main PLL closed + \param[in] ldo_output: + only one parameter can be selected which is shown as below: + \arg PMU_LDOVS_LOW: LDO output voltage low mode + \arg PMU_LDOVS_HIGH: LDO output voltage high mode + \param[out] none + \retval none +*/ +void pmu_ldo_output_select(uint32_t ldo_output) +{ + PMU_CTL &= ~PMU_CTL_LDOVS; + PMU_CTL |= ldo_output; +} + +/*! + \brief disable PMU lvd + \param[in] none + \param[out] none + \retval none +*/ +void pmu_lvd_disable(void) +{ + /* disable LVD */ + PMU_CTL &= ~PMU_CTL_LVDEN; +} + +/*! + \brief PMU work at sleep mode + \param[in] sleepmodecmd: + only one parameter can be selected which is shown as below: + \arg WFI_CMD: use WFI command + \arg WFE_CMD: use WFE command + \param[out] none + \retval none +*/ +void pmu_to_sleepmode(uint8_t sleepmodecmd) +{ + /* clear sleepdeep bit of Cortex-M23 system control register */ + SCB->SCR &= ~((uint32_t)SCB_SCR_SLEEPDEEP_Msk); + + /* select WFI or WFE command to enter sleep mode */ + if(WFI_CMD == sleepmodecmd){ + __WFI(); + }else{ + __WFE(); + } +} + +/*! + \brief PMU work at deepsleep mode + \param[in] ldo: + only one parameter can be selected which is shown as below: + \arg PMU_LDO_NORMAL: LDO operates normally when pmu enter deepsleep mode + \arg PMU_LDO_LOWPOWER: LDO work at low power mode when pmu enter deepsleep mode + \param[in] deepsleepmodecmd: + only one parameter can be selected which is shown as below: + \arg WFI_CMD: use WFI command + \arg WFE_CMD: use WFE command + \param[out] none + \retval none +*/ +void pmu_to_deepsleepmode(uint32_t ldo,uint8_t deepsleepmodecmd) +{ + static uint32_t reg_snap[ 3 ]; + /* clear stbmod and ldolp bits */ + PMU_CTL &= ~((uint32_t)(PMU_CTL_STBMOD | PMU_CTL_LDOLP)); + + /* set ldolp bit according to pmu_ldo */ + PMU_CTL |= ldo; + + /* set sleepdeep bit of Cortex-M23 system control register */ + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + + reg_snap[ 0 ] = REG32( 0xE000E010U ); + reg_snap[ 1 ] = REG32( 0xE000E100U ); + reg_snap[ 2 ] = REG32( 0xE000E104U ); + + REG32( 0xE000E010U ) &= 0x00010004U; + REG32( 0xE000E180U ) = 0XF7FFEF19U; + REG32( 0xE000E184U ) = 0XFFFFFFFFU; + + /* select WFI or WFE command to enter deepsleep mode */ + if(WFI_CMD == deepsleepmodecmd){ + __WFI(); + }else{ + __SEV(); + __WFE(); + __WFE(); + } + + REG32( 0xE000E010U ) = reg_snap[ 0 ] ; + REG32( 0xE000E100U ) = reg_snap[ 1 ] ; + REG32( 0xE000E104U ) = reg_snap[ 2 ] ; + + /* reset sleepdeep bit of Cortex-M23 system control register */ + SCB->SCR &= ~((uint32_t)SCB_SCR_SLEEPDEEP_Msk); +} + +/*! + \brief pmu work at standby mode + \param[in] standbymodecmd: + only one parameter can be selected which is shown as below: + \arg WFI_CMD: use WFI command + \arg WFE_CMD: use WFE command + \param[out] none + \retval none +*/ +void pmu_to_standbymode(uint8_t standbymodecmd) +{ + /* set sleepdeep bit of Cortex-M23 system control register */ + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + + /* set stbmod bit */ + PMU_CTL |= PMU_CTL_STBMOD; + + /* reset wakeup flag */ + PMU_CTL |= PMU_CTL_WURST; + + /* select WFI or WFE command to enter standby mode */ + if(WFI_CMD == standbymodecmd){ + __WFI(); + }else{ + __WFE(); + } +} + +/*! + \brief enable wakeup pin + \param[in] wakeup_pin: + one or more parameters can be selected which are shown as below: + \arg PMU_WAKEUP_PIN0: WKUP Pin 0 (PA0) + \arg PMU_WAKEUP_PIN1: WKUP Pin 1 (PC13) + \arg PMU_WAKEUP_PIN5: WKUP Pin 5 (PB5) + \arg PMU_WAKEUP_PIN6: WKUP Pin 6 (PB15) + \param[out] none + \retval none +*/ +void pmu_wakeup_pin_enable(uint32_t wakeup_pin) +{ + PMU_CS |= wakeup_pin; +} + +/*! + \brief disable wakeup pin + \param[in] wakeup_pin: + one or more parameters can be selected which are shown as below: + \arg PMU_WAKEUP_PIN0: WKUP Pin 0 (PA0) + \arg PMU_WAKEUP_PIN1: WKUP Pin 1 (PC13) + \arg PMU_WAKEUP_PIN5: WKUP Pin 5 (PB5) + \arg PMU_WAKEUP_PIN6: WKUP Pin 6 (PB15) + \param[out] none + \retval none +*/ +void pmu_wakeup_pin_disable(uint32_t wakeup_pin) +{ + PMU_CS &= ~(wakeup_pin); +} + +/*! + \brief enable backup domain write + \param[in] none + \param[out] none + \retval none +*/ +void pmu_backup_write_enable(void) +{ + PMU_CTL |= PMU_CTL_BKPWEN; +} + +/*! + \brief disable backup domain write + \param[in] none + \param[out] none + \retval none +*/ +void pmu_backup_write_disable(void) +{ + PMU_CTL &= ~PMU_CTL_BKPWEN; +} + +/*! + \brief clear flag bit + \param[in] flag_clear: + one or more parameters can be selected which are shown as below: + \arg PMU_FLAG_RESET_WAKEUP: reset wakeup flag + \arg PMU_FLAG_RESET_STANDBY: reset standby flag + \param[out] none + \retval none +*/ +void pmu_flag_clear(uint32_t flag_clear) +{ + if(RESET != (flag_clear & PMU_FLAG_RESET_WAKEUP)){ + /* reset wakeup flag */ + PMU_CTL |= PMU_CTL_WURST; + } + if(RESET != (flag_clear & PMU_FLAG_RESET_STANDBY)){ + /* reset standby flag */ + PMU_CTL |= PMU_CTL_STBRST; + } +} + +/*! + \brief get flag state + \param[in] flag: + only one parameter can be selected which is shown as below: + \arg PMU_FLAG_WAKEUP: wakeup flag + \arg PMU_FLAG_STANDBY: standby flag + \arg PMU_FLAG_LVD: lvd flag + \param[out] none + \retval FlagStatus SET or RESET +*/ +FlagStatus pmu_flag_get(uint32_t flag) +{ + FlagStatus ret_status = RESET; + + if(PMU_CS & flag){ + ret_status = SET; + } + + return ret_status; +} diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_rcu.c b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_rcu.c new file mode 100644 index 0000000000000000000000000000000000000000..9483fa68f934a6030301d1a7c88fc5c82b4dc427 --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_rcu.c @@ -0,0 +1,1034 @@ +/*! + \file gd32e230_rcu.c + \brief RCU driver + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor 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 copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 "gd32e230_rcu.h" + +/* define clock source */ +#define SEL_IRC8M 0x00U +#define SEL_HXTAL 0x01U +#define SEL_PLL 0x02U + +/* define startup timeout count */ +#define OSC_STARTUP_TIMEOUT ((uint32_t)0x000FFFFFU) +#define LXTAL_STARTUP_TIMEOUT ((uint32_t)0x03FFFFFFU) + +/*! + \brief deinitialize the RCU + \param[in] none + \param[out] none + \retval none +*/ +void rcu_deinit(void) +{ + /* enable IRC8M */ + RCU_CTL0 |= RCU_CTL0_IRC8MEN; + while(0U == (RCU_CTL0 & RCU_CTL0_IRC8MSTB)){ + } + /* reset RCU */ + RCU_CFG0 &= ~(RCU_CFG0_SCS | RCU_CFG0_AHBPSC | RCU_CFG0_APB1PSC | RCU_CFG0_APB2PSC |\ + RCU_CFG0_ADCPSC | RCU_CFG0_CKOUTSEL | RCU_CFG0_CKOUTDIV | RCU_CFG0_PLLDV); + RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PLLMF | RCU_CFG0_PLLMF4 | RCU_CFG0_PLLDV); + RCU_CTL0 &= ~(RCU_CTL0_HXTALEN | RCU_CTL0_CKMEN | RCU_CTL0_PLLEN | RCU_CTL0_HXTALBPS); + RCU_CFG1 &= ~(RCU_CFG1_PREDV); + RCU_CFG2 &= ~(RCU_CFG2_USART0SEL | RCU_CFG2_ADCSEL); + RCU_CFG2 &= ~RCU_CFG2_IRC28MDIV; + RCU_CFG2 &= ~RCU_CFG2_ADCPSC2; + RCU_CTL1 &= ~RCU_CTL1_IRC28MEN; + RCU_INT = 0x00000000U; +} + +/*! + \brief enable the peripherals clock + \param[in] periph: RCU peripherals, refer to rcu_periph_enum + only one parameter can be selected which is shown as below: + \arg RCU_GPIOx (x=A,B,C,F): GPIO ports clock + \arg RCU_DMA: DMA clock + \arg RCU_CRC: CRC clock + \arg RCU_CFGCMP: CFGCMP clock + \arg RCU_ADC: ADC clock + \arg RCU_TIMERx (x=0,2,5,13,14,15,16): TIMER clock + \arg RCU_SPIx (x=0,1): SPI clock + \arg RCU_USARTx (x=0,1): USART clock + \arg RCU_WWDGT: WWDGT clock + \arg RCU_I2Cx (x=0,1): I2C clock + \arg RCU_PMU: PMU clock + \arg RCU_RTC: RTC clock + \arg RCU_DBGMCU: DBGMCU clock + \param[out] none + \retval none +*/ +void rcu_periph_clock_enable(rcu_periph_enum periph) +{ + RCU_REG_VAL(periph) |= BIT(RCU_BIT_POS(periph)); +} + +/*! + \brief disable the peripherals clock + \param[in] periph: RCU peripherals, refer to rcu_periph_enum + only one parameter can be selected which is shown as below: + \arg RCU_GPIOx (x=A,B,C,F): GPIO ports clock + \arg RCU_DMA: DMA clock + \arg RCU_CRC: CRC clock + \arg RCU_CFGCMP: CFGCMP clock + \arg RCU_ADC: ADC clock + \arg RCU_TIMERx (x=0,2,5,13,14,15,16): TIMER clock + \arg RCU_SPIx (x=0,1): SPI clock + \arg RCU_USARTx (x=0,1): USART clock + \arg RCU_WWDGT: WWDGT clock + \arg RCU_I2Cx (x=0,1): I2C clock + \arg RCU_PMU: PMU clock + \arg RCU_RTC: RTC clock + \arg RCU_DBGMCU: DBGMCU clock + \param[out] none + \retval none +*/ +void rcu_periph_clock_disable(rcu_periph_enum periph) +{ + RCU_REG_VAL(periph) &= ~BIT(RCU_BIT_POS(periph)); +} + +/*! + \brief enable the peripherals clock when sleep mode + \param[in] periph: RCU peripherals, refer to rcu_periph_sleep_enum + only one parameter can be selected which is shown as below: + \arg RCU_FMC_SLP: FMC clock + \arg RCU_SRAM_SLP: SRAM clock + \param[out] none + \retval none +*/ +void rcu_periph_clock_sleep_enable(rcu_periph_sleep_enum periph) +{ + RCU_REG_VAL(periph) |= BIT(RCU_BIT_POS(periph)); +} + +/*! + \brief disable the peripherals clock when sleep mode + \param[in] periph: RCU peripherals, refer to rcu_periph_sleep_enum + only one parameter can be selected which is shown as below: + \arg RCU_FMC_SLP: FMC clock + \arg RCU_SRAM_SLP: SRAM clock + \param[out] none + \retval none +*/ +void rcu_periph_clock_sleep_disable(rcu_periph_sleep_enum periph) +{ + RCU_REG_VAL(periph) &= ~BIT(RCU_BIT_POS(periph)); +} +/*! + \brief reset the peripherals + \param[in] periph_reset: RCU peripherals reset, refer to rcu_periph_reset_enum + only one parameter can be selected which is shown as below: + \arg RCU_GPIOxRST (x=A,B,C,F): reset GPIO ports + \arg RCU_CFGCMPRST: reset CFGCMP + \arg RCU_ADCRST: reset ADC + \arg RCU_TIMERxRST (x=0,2,5,13,14,15,16): reset TIMER + \arg RCU_SPIxRST (x=0,1): reset SPI + \arg RCU_USARTxRST (x=0,1): reset USART + \arg RCU_WWDGTRST: reset WWDGT + \arg RCU_I2CxRST (x=0,1): reset I2C + \arg RCU_PMURST: reset PMU + \param[out] none + \retval none +*/ +void rcu_periph_reset_enable(rcu_periph_reset_enum periph_reset) +{ + RCU_REG_VAL(periph_reset) |= BIT(RCU_BIT_POS(periph_reset)); +} + +/*! + \brief disable reset the peripheral + \param[in] periph_reset: RCU peripherals reset, refer to rcu_periph_reset_enum + only one parameter can be selected which is shown as below: + \arg RCU_GPIOxRST (x=A,B,C,F): reset GPIO ports + \arg RCU_CFGCMPRST: reset CFGCMP + \arg RCU_ADCRST: reset ADC + \arg RCU_TIMERxRST (x=0,2,5,13,14,15,16): reset TIMER + \arg RCU_SPIxRST (x=0,1): reset SPI + \arg RCU_USARTxRST (x=0,1): reset USART + \arg RCU_WWDGTRST: reset WWDGT + \arg RCU_I2CxRST (x=0,1): reset I2C + \arg RCU_PMURST: reset PMU + \param[out] none + \retval none +*/ +void rcu_periph_reset_disable(rcu_periph_reset_enum periph_reset) +{ + RCU_REG_VAL(periph_reset) &= ~BIT(RCU_BIT_POS(periph_reset)); +} + +/*! + \brief reset the BKP + \param[in] none + \param[out] none + \retval none +*/ +void rcu_bkp_reset_enable(void) +{ + RCU_BDCTL |= RCU_BDCTL_BKPRST; +} + +/*! + \brief disable the BKP reset + \param[in] none + \param[out] none + \retval none +*/ +void rcu_bkp_reset_disable(void) +{ + RCU_BDCTL &= ~RCU_BDCTL_BKPRST; +} + +/*! + \brief configure the system clock source + \param[in] ck_sys: system clock source select + only one parameter can be selected which is shown as below: + \arg RCU_CKSYSSRC_IRC8M: select CK_IRC8M as the CK_SYS source + \arg RCU_CKSYSSRC_HXTAL: select CK_HXTAL as the CK_SYS source + \arg RCU_CKSYSSRC_PLL: select CK_PLL as the CK_SYS source + \param[out] none + \retval none +*/ +void rcu_system_clock_source_config(uint32_t ck_sys) +{ + uint32_t cksys_source = 0U; + cksys_source = RCU_CFG0; + /* reset the SCS bits and set according to ck_sys */ + cksys_source &= ~RCU_CFG0_SCS; + RCU_CFG0 = (ck_sys | cksys_source); +} + +/*! + \brief get the system clock source + \param[in] none + \param[out] none + \retval which clock is selected as CK_SYS source + \arg RCU_SCSS_IRC8M: select CK_IRC8M as the CK_SYS source + \arg RCU_SCSS_HXTAL: select CK_HXTAL as the CK_SYS source + \arg RCU_SCSS_PLL: select CK_PLL as the CK_SYS source +*/ +uint32_t rcu_system_clock_source_get(void) +{ + return (RCU_CFG0 & RCU_CFG0_SCSS); +} + +/*! + \brief configure the AHB clock prescaler selection + \param[in] ck_ahb: AHB clock prescaler selection + only one parameter can be selected which is shown as below: + \arg RCU_AHB_CKSYS_DIVx, x=1, 2, 4, 8, 16, 64, 128, 256, 512 + \param[out] none + \retval none +*/ +void rcu_ahb_clock_config(uint32_t ck_ahb) +{ + uint32_t ahbpsc = 0U; + ahbpsc = RCU_CFG0; + /* reset the AHBPSC bits and set according to ck_ahb */ + ahbpsc &= ~RCU_CFG0_AHBPSC; + RCU_CFG0 = (ck_ahb | ahbpsc); +} + +/*! + \brief configure the APB1 clock prescaler selection + \param[in] ck_apb1: APB1 clock prescaler selection + only one parameter can be selected which is shown as below: + \arg RCU_APB1_CKAHB_DIV1: select CK_AHB as CK_APB1 + \arg RCU_APB1_CKAHB_DIV2: select CK_AHB/2 as CK_APB1 + \arg RCU_APB1_CKAHB_DIV4: select CK_AHB/4 as CK_APB1 + \arg RCU_APB1_CKAHB_DIV8: select CK_AHB/8 as CK_APB1 + \arg RCU_APB1_CKAHB_DIV16: select CK_AHB/16 as CK_APB1 + \param[out] none + \retval none +*/ +void rcu_apb1_clock_config(uint32_t ck_apb1) +{ + uint32_t apb1psc = 0U; + apb1psc = RCU_CFG0; + /* reset the APB1PSC and set according to ck_apb1 */ + apb1psc &= ~RCU_CFG0_APB1PSC; + RCU_CFG0 = (ck_apb1 | apb1psc); +} + +/*! + \brief configure the APB2 clock prescaler selection + \param[in] ck_apb2: APB2 clock prescaler selection + only one parameter can be selected which is shown as below: + \arg RCU_APB2_CKAHB_DIV1: select CK_AHB as CK_APB2 + \arg RCU_APB2_CKAHB_DIV2: select CK_AHB/2 as CK_APB2 + \arg RCU_APB2_CKAHB_DIV4: select CK_AHB/4 as CK_APB2 + \arg RCU_APB2_CKAHB_DIV8: select CK_AHB/8 as CK_APB2 + \arg RCU_APB2_CKAHB_DIV16: select CK_AHB/16 as CK_APB2 + \param[out] none + \retval none +*/ +void rcu_apb2_clock_config(uint32_t ck_apb2) +{ + uint32_t apb2psc = 0U; + apb2psc = RCU_CFG0; + /* reset the APB2PSC and set according to ck_apb2 */ + apb2psc &= ~RCU_CFG0_APB2PSC; + RCU_CFG0 = (ck_apb2 | apb2psc); +} + +/*! + \brief configure the ADC clock prescaler selection + \param[in] ck_adc: ADC clock prescaler selection, refer to rcu_adc_clock_enum + only one parameter can be selected which is shown as below: + \arg RCU_ADCCK_IRC28M_DIV2: select CK_IRC28M/2 as CK_ADC + \arg RCU_ADCCK_IRC28M: select CK_IRC28M as CK_ADC + \arg RCU_ADCCK_APB2_DIV2: select CK_APB2/2 as CK_ADC + \arg RCU_ADCCK_AHB_DIV3: select CK_AHB/3 as CK_ADC + \arg RCU_ADCCK_APB2_DIV4: select CK_APB2/4 as CK_ADC + \arg RCU_ADCCK_AHB_DIV5: select CK_AHB/5 as CK_ADC + \arg RCU_ADCCK_APB2_DIV6: select CK_APB2/6 as CK_ADC + \arg RCU_ADCCK_AHB_DIV7: select CK_AHB/7 as CK_ADC + \arg RCU_ADCCK_APB2_DIV8: select CK_APB2/8 as CK_ADC + \arg RCU_ADCCK_AHB_DIV9: select CK_AHB/9 as CK_ADC + \param[out] none + \retval none +*/ +void rcu_adc_clock_config(rcu_adc_clock_enum ck_adc) +{ + /* reset the ADCPSC, ADCSEL, IRC28MDIV bits */ + RCU_CFG0 &= ~RCU_CFG0_ADCPSC; + RCU_CFG2 &= ~(RCU_CFG2_ADCSEL | RCU_CFG2_IRC28MDIV | RCU_CFG2_ADCPSC2); + + /* set the ADC clock according to ck_adc */ + switch(ck_adc){ + case RCU_ADCCK_IRC28M_DIV2: + RCU_CFG2 &= ~RCU_CFG2_IRC28MDIV; + RCU_CFG2 &= ~RCU_CFG2_ADCSEL; + break; + case RCU_ADCCK_IRC28M: + RCU_CFG2 |= RCU_CFG2_IRC28MDIV; + RCU_CFG2 &= ~RCU_CFG2_ADCSEL; + break; + case RCU_ADCCK_APB2_DIV2: + RCU_CFG0 |= RCU_ADC_CKAPB2_DIV2; + RCU_CFG2 |= RCU_CFG2_ADCSEL; + break; + case RCU_ADCCK_AHB_DIV3: + RCU_CFG0 |= RCU_ADC_CKAPB2_DIV2; + RCU_CFG2 |= RCU_CFG2_ADCPSC2; + RCU_CFG2 |= RCU_CFG2_ADCSEL; + break; + case RCU_ADCCK_APB2_DIV4: + RCU_CFG0 |= RCU_ADC_CKAPB2_DIV4; + RCU_CFG2 |= RCU_CFG2_ADCSEL; + break; + case RCU_ADCCK_AHB_DIV5: + RCU_CFG0 |= RCU_ADC_CKAPB2_DIV4; + RCU_CFG2 |= RCU_CFG2_ADCPSC2; + RCU_CFG2 |= RCU_CFG2_ADCSEL; + break; + case RCU_ADCCK_APB2_DIV6: + RCU_CFG0 |= RCU_ADC_CKAPB2_DIV6; + RCU_CFG2 |= RCU_CFG2_ADCSEL; + break; + case RCU_ADCCK_AHB_DIV7: + RCU_CFG0 |= RCU_ADC_CKAPB2_DIV6; + RCU_CFG2 |= RCU_CFG2_ADCPSC2; + RCU_CFG2 |= RCU_CFG2_ADCSEL; + break; + case RCU_ADCCK_APB2_DIV8: + RCU_CFG0 |= RCU_ADC_CKAPB2_DIV8; + RCU_CFG2 |= RCU_CFG2_ADCSEL; + break; + case RCU_ADCCK_AHB_DIV9: + RCU_CFG0 |= RCU_ADC_CKAPB2_DIV8; + RCU_CFG2 |= RCU_CFG2_ADCPSC2; + RCU_CFG2 |= RCU_CFG2_ADCSEL; + break; + default: + break; + } +} + +/*! + \brief configure the CK_OUT clock source and divider + \param[in] ckout_src: CK_OUT clock source selection + only one parameter can be selected which is shown as below: + \arg RCU_CKOUTSRC_NONE: no clock selected + \arg RCU_CKOUTSRC_IRC28M: IRC28M selected + \arg RCU_CKOUTSRC_IRC40K: IRC40K selected + \arg RCU_CKOUTSRC_LXTAL: LXTAL selected + \arg RCU_CKOUTSRC_CKSYS: CKSYS selected + \arg RCU_CKOUTSRC_IRC8M: IRC8M selected + \arg RCU_CKOUTSRC_HXTAL: HXTAL selected + \arg RCU_CKOUTSRC_CKPLL_DIV1: CK_PLL selected + \arg RCU_CKOUTSRC_CKPLL_DIV2: CK_PLL/2 selected + \param[in] ckout_div: CK_OUT divider + \arg RCU_CKOUT_DIVx(x=1,2,4,8,16,32,64,128): CK_OUT is divided by x + \param[out] none + \retval none +*/ +void rcu_ckout_config(uint32_t ckout_src, uint32_t ckout_div) +{ + uint32_t ckout = 0U; + ckout = RCU_CFG0; + /* reset the CKOUTSEL, CKOUTDIV and PLLDV bits and set according to ckout_src and ckout_div */ + ckout &= ~(RCU_CFG0_CKOUTSEL | RCU_CFG0_CKOUTDIV | RCU_CFG0_PLLDV); + RCU_CFG0 = (ckout | ckout_src | ckout_div); +} + +/*! + \brief configure the PLL clock source selection and PLL multiply factor + \param[in] pll_src: PLL clock source selection + only one parameter can be selected which is shown as below: + \arg RCU_PLLSRC_IRC8M_DIV2: select CK_IRC8M/2 as PLL source clock + \arg RCU_PLLSRC_HXTAL: select HXTAL as PLL source clock + \param[in] pll_mul: PLL multiply factor + only one parameter can be selected which is shown as below: + \arg RCU_PLL_MULx(x=2..32): PLL source clock * x + \param[out] none + \retval none +*/ +void rcu_pll_config(uint32_t pll_src, uint32_t pll_mul) +{ + RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PLLMF); + RCU_CFG0 |= (pll_src | pll_mul); +} + +/*! + \brief configure the USART clock source selection + \param[in] ck_usart: USART clock source selection + only one parameter can be selected which is shown as below: + \arg RCU_USART0SRC_CKAPB2: CK_USART0 select CK_APB2 + \arg RCU_USART0SRC_CKSYS: CK_USART0 select CK_SYS + \arg RCU_USART0SRC_LXTAL: CK_USART0 select CK_LXTAL + \arg RCU_USART0SRC_IRC8M: CK_USART0 select CK_IRC8M + \param[out] none + \retval none +*/ +void rcu_usart_clock_config(uint32_t ck_usart) +{ + /* reset the USART0SEL bits and set according to ck_usart */ + RCU_CFG2 &= ~RCU_CFG2_USART0SEL; + RCU_CFG2 |= ck_usart; +} + +/*! + \brief configure the RTC clock source selection + \param[in] rtc_clock_source: RTC clock source selection + only one parameter can be selected which is shown as below: + \arg RCU_RTCSRC_NONE: no clock selected + \arg RCU_RTCSRC_LXTAL: CK_LXTAL selected as RTC source clock + \arg RCU_RTCSRC_IRC40K: CK_IRC40K selected as RTC source clock + \arg RCU_RTCSRC_HXTAL_DIV32: CK_HXTAL/32 selected as RTC source clock + \param[out] none + \retval none +*/ +void rcu_rtc_clock_config(uint32_t rtc_clock_source) +{ + /* reset the RTCSRC bits and set according to rtc_clock_source */ + RCU_BDCTL &= ~RCU_BDCTL_RTCSRC; + RCU_BDCTL |= rtc_clock_source; +} + +/*! + \brief configure the HXTAL divider used as input of PLL + \param[in] hxtal_prediv: HXTAL divider used as input of PLL + only one parameter can be selected which is shown as below: + \arg RCU_PLL_PREDVx(x=1..16): HXTAL divided x used as input of PLL + \param[out] none + \retval none +*/ +void rcu_hxtal_prediv_config(uint32_t hxtal_prediv) +{ + uint32_t prediv = 0U; + prediv = RCU_CFG1; + /* reset the PREDV bits and set according to hxtal_prediv */ + prediv &= ~RCU_CFG1_PREDV; + RCU_CFG1 = (prediv | hxtal_prediv); +} + +/*! + \brief configure the LXTAL drive capability + \param[in] lxtal_dricap: drive capability of LXTAL + only one parameter can be selected which is shown as below: + \arg RCU_LXTAL_LOWDRI: lower driving capability + \arg RCU_LXTAL_MED_LOWDRI: medium low driving capability + \arg RCU_LXTAL_MED_HIGHDRI: medium high driving capability + \arg RCU_LXTAL_HIGHDRI: higher driving capability + \param[out] none + \retval none +*/ +void rcu_lxtal_drive_capability_config(uint32_t lxtal_dricap) +{ + /* reset the LXTALDRI bits and set according to lxtal_dricap */ + RCU_BDCTL &= ~RCU_BDCTL_LXTALDRI; + RCU_BDCTL |= lxtal_dricap; +} + +/*! + \brief get the clock stabilization and periphral reset flags + \param[in] flag: the clock stabilization and periphral reset flags, refer to rcu_flag_enum + only one parameter can be selected which is shown as below: + \arg RCU_FLAG_IRC40KSTB: IRC40K stabilization flag + \arg RCU_FLAG_LXTALSTB: LXTAL stabilization flag + \arg RCU_FLAG_IRC8MSTB: IRC8M stabilization flag + \arg RCU_FLAG_HXTALSTB: HXTAL stabilization flag + \arg RCU_FLAG_PLLSTB: PLL stabilization flag + \arg RCU_FLAG_IRC28MSTB: IRC28M stabilization flag + \arg RCU_FLAG_V12RST: V12 domain power reset flag + \arg RCU_FLAG_OBLRST: option byte loader reset flag + \arg RCU_FLAG_EPRST: external pin reset flag + \arg RCU_FLAG_PORRST: power reset flag + \arg RCU_FLAG_SWRST: software reset flag + \arg RCU_FLAG_FWDGTRST: free watchdog timer reset flag + \arg RCU_FLAG_WWDGTRST: window watchdog timer reset flag + \arg RCU_FLAG_LPRST: low-power reset flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus rcu_flag_get(rcu_flag_enum flag) +{ + if(RESET != (RCU_REG_VAL(flag) & BIT(RCU_BIT_POS(flag)))){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear the reset flag + \param[in] none + \param[out] none + \retval none +*/ +void rcu_all_reset_flag_clear(void) +{ + RCU_RSTSCK |= RCU_RSTSCK_RSTFC; +} + +/*! + \brief get the clock stabilization interrupt and ckm flags + \param[in] int_flag: interrupt and ckm flags, refer to rcu_int_flag_enum + only one parameter can be selected which is shown as below: + \arg RCU_INT_FLAG_IRC40KSTB: IRC40K stabilization interrupt flag + \arg RCU_INT_FLAG_LXTALSTB: LXTAL stabilization interrupt flag + \arg RCU_INT_FLAG_IRC8MSTB: IRC8M stabilization interrupt flag + \arg RCU_INT_FLAG_HXTALSTB: HXTAL stabilization interrupt flag + \arg RCU_INT_FLAG_PLLSTB: PLL stabilization interrupt flag + \arg RCU_INT_FLAG_IRC28MSTB: IRC28M stabilization interrupt flag + \arg RCU_INT_FLAG_CKM: HXTAL clock stuck interrupt flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus rcu_interrupt_flag_get(rcu_int_flag_enum int_flag) +{ + if(RESET != (RCU_REG_VAL(int_flag) & BIT(RCU_BIT_POS(int_flag)))){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear the interrupt flags + \param[in] int_flag_clear: clock stabilization and stuck interrupt flags clear, refer to rcu_int_flag_clear_enum + only one parameter can be selected which is shown as below: + \arg RCU_INT_FLAG_IRC40KSTB_CLR: IRC40K stabilization interrupt flag clear + \arg RCU_INT_FLAG_LXTALSTB_CLR: LXTAL stabilization interrupt flag clear + \arg RCU_INT_FLAG_IRC8MSTB_CLR: IRC8M stabilization interrupt flag clear + \arg RCU_INT_FLAG_HXTALSTB_CLR: HXTAL stabilization interrupt flag clear + \arg RCU_INT_FLAG_PLLSTB_CLR: PLL stabilization interrupt flag clear + \arg RCU_INT_FLAG_IRC28MSTB_CLR: IRC28M stabilization interrupt flag clear + \arg RCU_INT_FLAG_CKM_CLR: clock stuck interrupt flag clear + \param[out] none + \retval none +*/ +void rcu_interrupt_flag_clear(rcu_int_flag_clear_enum int_flag_clear) +{ + RCU_REG_VAL(int_flag_clear) |= BIT(RCU_BIT_POS(int_flag_clear)); +} + +/*! + \brief enable the stabilization interrupt + \param[in] stab_int: clock stabilization interrupt, refer to rcu_int_enum + only one parameter can be selected which is shown as below: + \arg RCU_INT_IRC40KSTB: IRC40K stabilization interrupt enable + \arg RCU_INT_LXTALSTB: LXTAL stabilization interrupt enable + \arg RCU_INT_IRC8MSTB: IRC8M stabilization interrupt enable + \arg RCU_INT_HXTALSTB: HXTAL stabilization interrupt enable + \arg RCU_INT_PLLSTB: PLL stabilization interrupt enable + \arg RCU_INT_IRC28MSTB: IRC28M stabilization interrupt enable + \param[out] none + \retval none +*/ +void rcu_interrupt_enable(rcu_int_enum stab_int) +{ + RCU_REG_VAL(stab_int) |= BIT(RCU_BIT_POS(stab_int)); +} + + +/*! + \brief disable the stabilization interrupt + \param[in] stab_int: clock stabilization interrupt, refer to rcu_int_enum + only one parameter can be selected which is shown as below: + \arg RCU_INT_IRC40KSTB: IRC40K stabilization interrupt disable + \arg RCU_INT_LXTALSTB: LXTAL stabilization interrupt disable + \arg RCU_INT_IRC8MSTB: IRC8M stabilization interrupt disable + \arg RCU_INT_HXTALSTB: HXTAL stabilization interrupt disable + \arg RCU_INT_PLLSTB: PLL stabilization interrupt disable + \arg RCU_INT_IRC28MSTB: IRC28M stabilization interrupt disable + \param[out] none + \retval none +*/ +void rcu_interrupt_disable(rcu_int_enum stab_int) +{ + RCU_REG_VAL(stab_int) &= ~BIT(RCU_BIT_POS(stab_int)); +} + +/*! + \brief wait until oscillator stabilization flags is SET + \param[in] osci: oscillator types, refer to rcu_osci_type_enum + only one parameter can be selected which is shown as below: + \arg RCU_HXTAL: HXTAL + \arg RCU_LXTAL: LXTAL + \arg RCU_IRC8M: IRC8M + \arg RCU_IRC28M: IRC28M + \arg RCU_IRC40K: IRC40K + \arg RCU_PLL_CK: PLL + \param[out] none + \retval ErrStatus: SUCCESS or ERROR +*/ +ErrStatus rcu_osci_stab_wait(rcu_osci_type_enum osci) +{ + uint32_t stb_cnt = 0U; + ErrStatus reval = ERROR; + FlagStatus osci_stat = RESET; + switch(osci){ + case RCU_HXTAL: + /* wait until HXTAL is stabilization and osci_stat is not more than timeout */ + while((RESET == osci_stat) && (HXTAL_STARTUP_TIMEOUT != stb_cnt)){ + osci_stat = rcu_flag_get(RCU_FLAG_HXTALSTB); + stb_cnt++; + } + /* check whether flag is set or not */ + if(RESET != rcu_flag_get(RCU_FLAG_HXTALSTB)){ + reval = SUCCESS; + } + break; + + /* wait LXTAL stable */ + case RCU_LXTAL: + while((RESET == osci_stat) && (LXTAL_STARTUP_TIMEOUT != stb_cnt)){ + osci_stat = rcu_flag_get(RCU_FLAG_LXTALSTB); + stb_cnt++; + } + /* check whether flag is set or not */ + if(RESET != rcu_flag_get(RCU_FLAG_LXTALSTB)){ + reval = SUCCESS; + } + break; + + /* wait IRC8M stable */ + case RCU_IRC8M: + while((RESET == osci_stat) && (IRC8M_STARTUP_TIMEOUT != stb_cnt)){ + osci_stat = rcu_flag_get(RCU_FLAG_IRC8MSTB); + stb_cnt++; + } + /* check whether flag is set or not */ + if(RESET != rcu_flag_get(RCU_FLAG_IRC8MSTB)){ + reval = SUCCESS; + } + break; + + /* wait IRC28M stable */ + case RCU_IRC28M: + while((RESET == osci_stat) && (OSC_STARTUP_TIMEOUT != stb_cnt)){ + osci_stat = rcu_flag_get(RCU_FLAG_IRC28MSTB); + stb_cnt++; + } + /* check whether flag is set or not */ + if(RESET != rcu_flag_get(RCU_FLAG_IRC28MSTB)){ + reval = SUCCESS; + } + break; + + /* wait IRC40K stable */ + case RCU_IRC40K: + while((RESET == osci_stat) && (OSC_STARTUP_TIMEOUT != stb_cnt)){ + osci_stat = rcu_flag_get(RCU_FLAG_IRC40KSTB); + stb_cnt++; + } + /* check whether flag is set or not */ + if(RESET != rcu_flag_get(RCU_FLAG_IRC40KSTB)){ + reval = SUCCESS; + } + break; + + /* wait PLL stable */ + case RCU_PLL_CK: + while((RESET == osci_stat) && (OSC_STARTUP_TIMEOUT != stb_cnt)){ + osci_stat = rcu_flag_get(RCU_FLAG_PLLSTB); + stb_cnt++; + } + /* check whether flag is set or not */ + if(RESET != rcu_flag_get(RCU_FLAG_PLLSTB)){ + reval = SUCCESS; + } + break; + + default: + break; + } + /* return value */ + return reval; +} + +/*! + \brief turn on the oscillator + \param[in] osci: oscillator types, refer to rcu_osci_type_enum + only one parameter can be selected which is shown as below: + \arg RCU_HXTAL: HXTAL + \arg RCU_LXTAL: LXTAL + \arg RCU_IRC8M: IRC8M + \arg RCU_IRC28M: IRC28M + \arg RCU_IRC40K: IRC40K + \arg RCU_PLL_CK: PLL + \param[out] none + \retval none +*/ +void rcu_osci_on(rcu_osci_type_enum osci) +{ + RCU_REG_VAL(osci) |= BIT(RCU_BIT_POS(osci)); +} + +/*! + \brief turn off the oscillator + \param[in] osci: oscillator types, refer to rcu_osci_type_enum + only one parameter can be selected which is shown as below: + \arg RCU_HXTAL: HXTAL + \arg RCU_LXTAL: LXTAL + \arg RCU_IRC8M: IRC8M + \arg RCU_IRC28M: IRC28M + \arg RCU_IRC40K: IRC40K + \arg RCU_PLL_CK: PLL + \param[out] none + \retval none +*/ +void rcu_osci_off(rcu_osci_type_enum osci) +{ + RCU_REG_VAL(osci) &= ~BIT(RCU_BIT_POS(osci)); +} + +/*! + \brief enable the oscillator bypass mode, HXTALEN or LXTALEN must be reset before it + \param[in] osci: oscillator types, refer to rcu_osci_type_enum + only one parameter can be selected which is shown as below: + \arg RCU_HXTAL: HXTAL + \arg RCU_LXTAL: LXTAL + \param[out] none + \retval none +*/ +void rcu_osci_bypass_mode_enable(rcu_osci_type_enum osci) +{ + uint32_t reg; + switch(osci){ + case RCU_HXTAL: + /* HXTALEN must be reset before enable the oscillator bypass mode */ + reg = RCU_CTL0; + RCU_CTL0 &= ~RCU_CTL0_HXTALEN; + RCU_CTL0 = (reg | RCU_CTL0_HXTALBPS); + break; + case RCU_LXTAL: + /* LXTALEN must be reset before enable the oscillator bypass mode */ + reg = RCU_BDCTL; + RCU_BDCTL &= ~RCU_BDCTL_LXTALEN; + RCU_BDCTL = (reg | RCU_BDCTL_LXTALBPS); + break; + case RCU_IRC8M: + case RCU_IRC28M: + case RCU_IRC40K: + case RCU_PLL_CK: + break; + default: + break; + } +} + +/*! + \brief disable the oscillator bypass mode, HXTALEN or LXTALEN must be reset before it + \param[in] osci: oscillator types, refer to rcu_osci_type_enum + only one parameter can be selected which is shown as below: + \arg RCU_HXTAL: HXTAL + \arg RCU_LXTAL: LXTAL + \param[out] none + \retval none +*/ +void rcu_osci_bypass_mode_disable(rcu_osci_type_enum osci) +{ + uint32_t reg; + switch(osci){ + case RCU_HXTAL: + /* HXTALEN must be reset before disable the oscillator bypass mode */ + reg = RCU_CTL0; + RCU_CTL0 &= ~RCU_CTL0_HXTALEN; + RCU_CTL0 = (reg & (~RCU_CTL0_HXTALBPS)); + break; + case RCU_LXTAL: + /* LXTALEN must be reset before disable the oscillator bypass mode */ + reg = RCU_BDCTL; + RCU_BDCTL &= ~RCU_BDCTL_LXTALEN; + RCU_BDCTL = (reg & (~RCU_BDCTL_LXTALBPS)); + break; + case RCU_IRC8M: + case RCU_IRC28M: + case RCU_IRC40K: + case RCU_PLL_CK: + break; + default: + break; + } +} + +/*! + \brief enable the HXTAL clock monitor + \param[in] none + \param[out] none + \retval none +*/ +void rcu_hxtal_clock_monitor_enable(void) +{ + RCU_CTL0 |= RCU_CTL0_CKMEN; +} + +/*! + \brief disable the HXTAL clock monitor + \param[in] none + \param[out] none + \retval none +*/ +void rcu_hxtal_clock_monitor_disable(void) +{ + RCU_CTL0 &= ~RCU_CTL0_CKMEN; +} + +/*! + \brief set the IRC8M adjust value + \param[in] irc8m_adjval: IRC8M adjust value, must be between 0 and 0x1F + \param[out] none + \retval none +*/ +void rcu_irc8m_adjust_value_set(uint8_t irc8m_adjval) +{ + uint32_t adjust = 0U; + adjust = RCU_CTL0; + /* reset the IRC8MADJ bits and set according to irc8m_adjval */ + adjust &= ~RCU_CTL0_IRC8MADJ; + RCU_CTL0 = (adjust | (((uint32_t)irc8m_adjval)<<3)); +} + +/*! + \brief set the IRC28M adjust value + \param[in] irc28m_adjval: IRC28M adjust value, must be between 0 and 0x1F + \param[out] none + \retval none +*/ +void rcu_irc28m_adjust_value_set(uint8_t irc28m_adjval) +{ + uint32_t adjust = 0U; + adjust = RCU_CTL1; + /* reset the IRC28MADJ bits and set according to irc28m_adjval */ + adjust &= ~RCU_CTL1_IRC28MADJ; + RCU_CTL1 = (adjust | (((uint32_t)irc28m_adjval)<<3)); +} + +/*! + \brief unlock the voltage key + \param[in] none + \param[out] none + \retval none +*/ +void rcu_voltage_key_unlock(void) +{ + /* reset the KEY bits and set 0x1A2B3C4D */ + RCU_VKEY &= ~RCU_VKEY_KEY; + RCU_VKEY |= RCU_VKEY_UNLOCK; +} + +/*! + \brief set voltage in deep sleep mode + \param[in] dsvol: deep sleep mode voltage + only one parameter can be selected which is shown as below: + \arg RCU_DEEPSLEEP_V_1_0: the core voltage is 1.0V + \arg RCU_DEEPSLEEP_V_0_9: the core voltage is 0.9V + \arg RCU_DEEPSLEEP_V_0_8: the core voltage is 0.8V + \arg RCU_DEEPSLEEP_V_1_2: the core voltage is 1.2V + \param[out] none + \retval none +*/ +void rcu_deepsleep_voltage_set(uint32_t dsvol) +{ + /* reset the DSLPVS bits and set according to dsvol */ + RCU_DSV &= ~RCU_DSV_DSLPVS; + RCU_DSV |= dsvol; +} + +/*! + \brief get the system clock, bus and peripheral clock frequency + \param[in] clock: the clock frequency which to get + only one parameter can be selected which is shown as below: + \arg CK_SYS: system clock frequency + \arg CK_AHB: AHB clock frequency + \arg CK_APB1: APB1 clock frequency + \arg CK_APB2: APB2 clock frequency + \arg CK_ADC: ADC clock frequency + \arg CK_USART: USART0 clock frequency + \param[out] none + \retval clock frequency of system, AHB, APB1, APB2, ADC or USRAT0 +*/ +uint32_t rcu_clock_freq_get(rcu_clock_freq_enum clock) +{ + uint32_t sws = 0U, adcps = 0U, adcps2 = 0U, ck_freq = 0U; + uint32_t cksys_freq = 0U, ahb_freq = 0U, apb1_freq = 0U, apb2_freq = 0U; + uint32_t adc_freq = 0U, usart_freq = 0U; + uint32_t pllmf = 0U, pllmf4 = 0U, pllsel = 0U, prediv = 0U, idx = 0U, clk_exp = 0U; + /* exponent of AHB, APB1 and APB2 clock divider */ + const uint8_t ahb_exp[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; + const uint8_t apb1_exp[8] = {0, 0, 0, 0, 1, 2, 3, 4}; + const uint8_t apb2_exp[8] = {0, 0, 0, 0, 1, 2, 3, 4}; + + sws = GET_BITS(RCU_CFG0, 2, 3); + switch(sws){ + /* IRC8M is selected as CK_SYS */ + case SEL_IRC8M: + cksys_freq = IRC8M_VALUE; + break; + /* HXTAL is selected as CK_SYS */ + case SEL_HXTAL: + cksys_freq = HXTAL_VALUE; + break; + /* PLL is selected as CK_SYS */ + case SEL_PLL: + /* get the value of PLLMF[3:0] */ + pllmf = GET_BITS(RCU_CFG0, 18, 21); + pllmf4 = GET_BITS(RCU_CFG0, 27, 27); + /* high 16 bits */ + if(1U == pllmf4){ + pllmf += 17U; + }else if(15U == pllmf){ + pllmf = 16U; + }else{ + pllmf += 2U; + } + + /* PLL clock source selection, HXTAL or IRC8M/2 */ + pllsel = GET_BITS(RCU_CFG0, 16, 16); + if(0U != pllsel){ + prediv = (GET_BITS(RCU_CFG1, 0, 3) + 1U); + cksys_freq = (HXTAL_VALUE / prediv) * pllmf; + }else{ + cksys_freq = (IRC8M_VALUE >> 1) * pllmf; + } + break; + /* IRC8M is selected as CK_SYS */ + default: + cksys_freq = IRC8M_VALUE; + break; + } + /* calculate AHB clock frequency */ + idx = GET_BITS(RCU_CFG0, 4, 7); + clk_exp = ahb_exp[idx]; + ahb_freq = cksys_freq >> clk_exp; + + /* calculate APB1 clock frequency */ + idx = GET_BITS(RCU_CFG0, 8, 10); + clk_exp = apb1_exp[idx]; + apb1_freq = ahb_freq >> clk_exp; + + /* calculate APB2 clock frequency */ + idx = GET_BITS(RCU_CFG0, 11, 13); + clk_exp = apb2_exp[idx]; + apb2_freq = ahb_freq >> clk_exp; + + /* return the clocks frequency */ + switch(clock){ + case CK_SYS: + ck_freq = cksys_freq; + break; + case CK_AHB: + ck_freq = ahb_freq; + break; + case CK_APB1: + ck_freq = apb1_freq; + break; + case CK_APB2: + ck_freq = apb2_freq; + break; + case CK_ADC: + /* calculate ADC clock frequency */ + if(RCU_ADCSRC_AHB_APB2DIV != (RCU_CFG2 & RCU_CFG2_ADCSEL)){ + if(RCU_ADC_IRC28M_DIV1 != (RCU_CFG2 & RCU_CFG2_IRC28MDIV)){ + adc_freq = IRC28M_VALUE >> 1; + }else{ + adc_freq = IRC28M_VALUE; + } + }else{ + /* ADC clock select CK_APB2 divided by 2/4/6/8 or CK_AHB divided by 3/5/7/9 */ + adcps = GET_BITS(RCU_CFG0, 14, 15); + adcps2 = GET_BITS(RCU_CFG2, 31, 31); + if(0U != adcps2){ + /* ADC clock select CK_AHB divided by 3/5/7/9 */ + adc_freq = ahb_freq / (adcps + 1U); + }else{ + /* ADC clock select CK_APB2 divided by 2/4/6/8 */ + adc_freq = apb2_freq / adcps; + } + } + ck_freq = adc_freq; + break; + case CK_USART: + /* calculate USART0 clock frequency */ + if(RCU_USART0SRC_CKAPB2 == (RCU_CFG2 & RCU_CFG2_USART0SEL)){ + usart_freq = apb2_freq; + }else if(RCU_USART0SRC_CKSYS == (RCU_CFG2 & RCU_CFG2_USART0SEL)){ + usart_freq = cksys_freq; + }else if(RCU_USART0SRC_LXTAL == (RCU_CFG2 & RCU_CFG2_USART0SEL)){ + usart_freq = LXTAL_VALUE; + }else if(RCU_USART0SRC_IRC8M == (RCU_CFG2 & RCU_CFG2_USART0SEL)){ + usart_freq = IRC8M_VALUE; + }else{ + } + ck_freq = usart_freq; + break; + default: + break; + } + return ck_freq; +} diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_rtc.c b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_rtc.c new file mode 100644 index 0000000000000000000000000000000000000000..546afa781e1d6a92eccde3eee7d03ad9f63c7e87 --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_rtc.c @@ -0,0 +1,965 @@ +/*! + \file gd32e230_rtc.c + \brief RTC driver + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor 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 copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 "gd32e230_rtc.h" + +/*! + \brief reset most of the RTC registers + \param[in] none + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_deinit(void) +{ + ErrStatus error_status = ERROR; + + /* RTC_TAMP register is not under write protection */ + RTC_TAMP = RTC_REGISTER_RESET; + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* reset RTC_CTL register, this can be done without the init mode */ + RTC_CTL &= RTC_REGISTER_RESET; + + /* enter init mode */ + error_status = rtc_init_mode_enter(); + + if(ERROR != error_status){ + /* before reset RTC_TIME and RTC_DATE, BPSHAD bit in RTC_CTL should be reset as the condition. + in order to read calendar from shadow register, not the real registers being reset */ + RTC_TIME = RTC_REGISTER_RESET; + RTC_DATE = RTC_DATE_RESET; + + RTC_PSC = RTC_PSC_RESET; + + /* reset RTC_STAT register, also exit init mode. + at the same time, RTC_STAT_SOPF bit is reset, as the condition to reset RTC_SHIFTCTL register later */ + RTC_STAT = RTC_STAT_RESET; + + /* to write RTC_ALRM0SS register, ALRM0EN bit in RTC_CTL register should be reset as the condition */ + RTC_ALRM0TD = RTC_REGISTER_RESET; + RTC_ALRM0SS = RTC_REGISTER_RESET; + + /* reset RTC_SHIFTCTL and RTC_HRFC register, this can be done without the init mode */ + RTC_SHIFTCTL = RTC_REGISTER_RESET; + RTC_HRFC = RTC_REGISTER_RESET; + + error_status = rtc_register_sync_wait(); + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + + return error_status; +} + +/*! + \brief initialize RTC registers + \param[in] rtc_initpara_struct: pointer to a rtc_parameter_struct structure which contains + parameters for initialization of the rtc peripheral + members of the structure and the member values are shown as below: + rtc_year: 0x0 - 0x99(BCD format) + rtc_month: RTC_JAN, RTC_FEB, RTC_MAR, RTC_APR, RTC_MAY, RTC_JUN, + RTC_JUL, RTC_AUG, RTC_SEP, RTC_OCT, RTC_NOV, RTC_DEC + rtc_date: 0x1 - 0x31(BCD format) + rtc_day_of_week: RTC_MONDAY, RTC_TUESDAY, RTC_WEDSDAY, RTC_THURSDAY + RTC_FRIDAY, RTC_SATURDAY, RTC_SUNDAY + rtc_hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the rtc_display_format chose + rtc_minute: 0x0 - 0x59(BCD format) + rtc_second: 0x0 - 0x59(BCD format) + rtc_factor_asyn: 0x0 - 0x7F + rtc_factor_syn: 0x0 - 0x7FFF + rtc_am_pm: RTC_AM, RTC_PM + rtc_display_format: RTC_24HOUR, RTC_12HOUR + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_init(rtc_parameter_struct* rtc_initpara_struct) +{ + ErrStatus error_status = ERROR; + uint32_t reg_time = 0x00U, reg_date = 0x00U; + + reg_date = (DATE_YR(rtc_initpara_struct->rtc_year) | \ + DATE_DOW(rtc_initpara_struct->rtc_day_of_week) | \ + DATE_MON(rtc_initpara_struct->rtc_month) | \ + DATE_DAY(rtc_initpara_struct->rtc_date)); + + reg_time = (rtc_initpara_struct->rtc_am_pm| \ + TIME_HR(rtc_initpara_struct->rtc_hour) | \ + TIME_MN(rtc_initpara_struct->rtc_minute) | \ + TIME_SC(rtc_initpara_struct->rtc_second)); + + /* 1st: disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* 2nd: enter init mode */ + error_status = rtc_init_mode_enter(); + + if(ERROR != error_status){ + RTC_PSC = (uint32_t)(PSC_FACTOR_A(rtc_initpara_struct->rtc_factor_asyn)| \ + PSC_FACTOR_S(rtc_initpara_struct->rtc_factor_syn)); + + RTC_TIME = (uint32_t)reg_time; + RTC_DATE = (uint32_t)reg_date; + + RTC_CTL &= (uint32_t)(~RTC_CTL_CS); + RTC_CTL |= rtc_initpara_struct->rtc_display_format; + + /* 3rd: exit init mode */ + rtc_init_mode_exit(); + + /* 4th: wait the RSYNF flag to set */ + error_status = rtc_register_sync_wait(); + } + + /* 5th: enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + + return error_status; +} + +/*! + \brief enter RTC init mode + \param[in] none + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_init_mode_enter(void) +{ + uint32_t time_index = RTC_INITM_TIMEOUT; + uint32_t flag_status = RESET; + ErrStatus error_status = ERROR; + + /* check whether it has been in init mode */ + if((uint32_t)RESET == (RTC_STAT & RTC_STAT_INITF)){ + RTC_STAT |= RTC_STAT_INITM; + + /* wait until the INITF flag to be set */ + do{ + flag_status = RTC_STAT & RTC_STAT_INITF; + }while((--time_index > 0x00U) && ((uint32_t)RESET == flag_status)); + + if((uint32_t)RESET != flag_status){ + error_status = SUCCESS; + } + }else{ + error_status = SUCCESS; + } + return error_status; +} + +/*! + \brief exit RTC init mode + \param[in] none + \param[out] none + \retval none +*/ +void rtc_init_mode_exit(void) +{ + RTC_STAT &= (uint32_t)(~RTC_STAT_INITM); +} + +/*! + \brief wait until RTC_TIME and RTC_DATE registers are synchronized with APB clock, and the shadow + registers are updated + \param[in] none + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_register_sync_wait(void) +{ + volatile uint32_t time_index = RTC_RSYNF_TIMEOUT; + uint32_t flag_status = RESET; + ErrStatus error_status = ERROR; + + if((uint32_t)RESET == (RTC_CTL & RTC_CTL_BPSHAD)){ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* firstly clear RSYNF flag */ + RTC_STAT &= (uint32_t)(~RTC_STAT_RSYNF); + + /* wait until RSYNF flag to be set */ + do{ + flag_status = RTC_STAT & RTC_STAT_RSYNF; + }while((--time_index > 0x00U) && ((uint32_t)RESET == flag_status)); + + if((uint32_t)RESET != flag_status){ + error_status = SUCCESS; + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + }else{ + error_status = SUCCESS; + } + + return error_status; +} + +/*! + \brief get current time and date + \param[in] none + \param[out] rtc_initpara_struct: pointer to a rtc_parameter_struct structure which contains + parameters for initialization of the rtc peripheral + members of the structure and the member values are shown as below: + rtc_year: 0x0 - 0x99(BCD format) + rtc_month: RTC_JAN, RTC_FEB, RTC_MAR, RTC_APR, RTC_MAY, RTC_JUN, + RTC_JUL, RTC_AUG, RTC_SEP, RTC_OCT, RTC_NOV, RTC_DEC + rtc_date: 0x1 - 0x31(BCD format) + rtc_day_of_week: RTC_MONDAY, RTC_TUESDAY, RTC_WEDSDAY, RTC_THURSDAY + RTC_FRIDAY, RTC_SATURDAY, RTC_SUNDAY + rtc_hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the rtc_display_format chose + rtc_minute: 0x0 - 0x59(BCD format) + rtc_second: 0x0 - 0x59(BCD format) + rtc_factor_asyn: 0x0 - 0x7F + rtc_factor_syn: 0x0 - 0x7FFF + rtc_am_pm: RTC_AM, RTC_PM + rtc_display_format: RTC_24HOUR, RTC_12HOUR + \retval none +*/ +void rtc_current_time_get(rtc_parameter_struct* rtc_initpara_struct) +{ + uint32_t temp_tr = 0x00U, temp_dr = 0x00U, temp_pscr = 0x00U, temp_ctlr = 0x00U; + + temp_tr = (uint32_t)RTC_TIME; + temp_dr = (uint32_t)RTC_DATE; + temp_pscr = (uint32_t)RTC_PSC; + temp_ctlr = (uint32_t)RTC_CTL; + + /* get current time and construct rtc_parameter_struct structure */ + rtc_initpara_struct->rtc_year = (uint8_t)GET_DATE_YR(temp_dr); + rtc_initpara_struct->rtc_month = (uint8_t)GET_DATE_MON(temp_dr); + rtc_initpara_struct->rtc_date = (uint8_t)GET_DATE_DAY(temp_dr); + rtc_initpara_struct->rtc_day_of_week = (uint8_t)GET_DATE_DOW(temp_dr); + rtc_initpara_struct->rtc_hour = (uint8_t)GET_TIME_HR(temp_tr); + rtc_initpara_struct->rtc_minute = (uint8_t)GET_TIME_MN(temp_tr); + rtc_initpara_struct->rtc_second = (uint8_t)GET_TIME_SC(temp_tr); + rtc_initpara_struct->rtc_factor_asyn = (uint16_t)GET_PSC_FACTOR_A(temp_pscr); + rtc_initpara_struct->rtc_factor_syn = (uint16_t)GET_PSC_FACTOR_S(temp_pscr); + rtc_initpara_struct->rtc_am_pm = (uint32_t)(temp_pscr & RTC_TIME_PM); + rtc_initpara_struct->rtc_display_format = (uint32_t)(temp_ctlr & RTC_CTL_CS); +} + +/*! + \brief get current subsecond value + \param[in] none + \param[out] none + \retval current subsecond value +*/ +uint32_t rtc_subsecond_get(void) +{ + uint32_t reg = 0x00U; + /* if BPSHAD bit is reset, reading RTC_SS will lock RTC_TIME and RTC_DATE automatically */ + reg = (uint32_t)RTC_SS; + /* read RTC_DATE to unlock the 3 shadow registers */ + (void) (RTC_DATE); + + return reg; +} + +/*! + \brief configure RTC alarm + \param[in] rtc_alarm_time: pointer to a rtc_alarm_struct structure which contains + parameters for RTC alarm configuration + members of the structure and the member values are shown as below: + rtc_alarm_mask: RTC_ALARM_NONE_MASK, RTC_ALARM_DATE_MASK, RTC_ALARM_HOUR_MASK + RTC_ALARM_MINUTE_MASK, RTC_ALARM_SECOND_MASK, RTC_ALARM_ALL_MASK + rtc_weekday_or_date: RTC_ALARM_DATE_SELECTED, RTC_ALARM_WEEKDAY_SELECTED + rtc_alarm_day: 1) 0x1 - 0x31(BCD format) if RTC_ALARM_DATE_SELECTED is set + 2) RTC_MONDAY, RTC_TUESDAY, RTC_WEDSDAY, RTC_THURSDAY, RTC_FRIDAY, + RTC_SATURDAY, RTC_SUNDAY if RTC_ALARM_WEEKDAY_SELECTED is set + rtc_alarm_hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the rtc_display_format + rtc_alarm_minute: 0x0 - 0x59(BCD format) + rtc_alarm_second: 0x0 - 0x59(BCD format) + rtc_am_pm: RTC_AM, RTC_PM + \param[out] none + \retval none +*/ +void rtc_alarm_config(rtc_alarm_struct* rtc_alarm_time) +{ + uint32_t reg_alrm0td = 0x00U; + + reg_alrm0td = (rtc_alarm_time->rtc_alarm_mask | \ + rtc_alarm_time->rtc_weekday_or_date | \ + rtc_alarm_time->rtc_am_pm | \ + ALRM0TD_DAY(rtc_alarm_time->rtc_alarm_day) | \ + ALRM0TD_HR(rtc_alarm_time->rtc_alarm_hour) | \ + ALRM0TD_MN(rtc_alarm_time->rtc_alarm_minute) | \ + ALRM0TD_SC(rtc_alarm_time->rtc_alarm_second)); + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + RTC_ALRM0TD = (uint32_t)reg_alrm0td; + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief configure subsecond of RTC alarm + \param[in] mask_subsecond: alarm subsecond mask + only one parameter can be selected which is shown as below: + \arg RTC_MASKSSC_0_14: mask alarm subsecond configuration + \arg RTC_MASKSSC_1_14: mask RTC_ALRM0SS_SSC[14:1], and RTC_ALRM0SS_SSC[0] is to be compared + \arg RTC_MASKSSC_2_14: mask RTC_ALRM0SS_SSC[14:2], and RTC_ALRM0SS_SSC[1:0] is to be compared + \arg RTC_MASKSSC_3_14: mask RTC_ALRM0SS_SSC[14:3], and RTC_ALRM0SS_SSC[2:0] is to be compared + \arg RTC_MASKSSC_4_14: mask RTC_ALRM0SS_SSC[14:4], and RTC_ALRM0SS_SSC[3:0] is to be compared + \arg RTC_MASKSSC_5_14: mask RTC_ALRM0SS_SSC[14:5], and RTC_ALRM0SS_SSC[4:0] is to be compared + \arg RTC_MASKSSC_6_14: mask RTC_ALRM0SS_SSC[14:6], and RTC_ALRM0SS_SSC[5:0] is to be compared + \arg RTC_MASKSSC_7_14: mask RTC_ALRM0SS_SSC[14:7], and RTC_ALRM0SS_SSC[6:0] is to be compared + \arg RTC_MASKSSC_8_14: mask RTC_ALRM0SS_SSC[14:8], and RTC_ALRM0SS_SSC[7:0] is to be compared + \arg RTC_MASKSSC_9_14: mask RTC_ALRM0SS_SSC[14:9], and RTC_ALRM0SS_SSC[8:0] is to be compared + \arg RTC_MASKSSC_10_14: mask RTC_ALRM0SS_SSC[14:10], and RTC_ALRM0SS_SSC[9:0] is to be compared + \arg RTC_MASKSSC_11_14: mask RTC_ALRM0SS_SSC[14:11], and RTC_ALRM0SS_SSC[10:0] is to be compared + \arg RTC_MASKSSC_12_14: mask RTC_ALRM0SS_SSC[14:12], and RTC_ALRM0SS_SSC[11:0] is to be compared + \arg RTC_MASKSSC_13_14: mask RTC_ALRM0SS_SSC[14:13], and RTC_ALRM0SS_SSC[12:0] is to be compared + \arg RTC_MASKSSC_14: mask RTC_ALRM0SS_SSC[14], and RTC_ALRM0SS_SSC[13:0] is to be compared + \arg RTC_MASKSSC_NONE: mask none, and RTC_ALRM0SS_SSC[14:0] is to be compared + \param[in] subsecond: alarm subsecond value(0x000 - 0x7FFF) + \param[out] none + \retval none +*/ +void rtc_alarm_subsecond_config(uint32_t mask_subsecond, uint32_t subsecond) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + RTC_ALRM0SS = mask_subsecond | subsecond; + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief enable RTC alarm + \param[in] none + \param[out] none + \retval none +*/ +void rtc_alarm_enable(void) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + RTC_CTL |= RTC_CTL_ALRM0EN; + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief disable RTC alarm + \param[in] none + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_alarm_disable(void) +{ + volatile uint32_t time_index = RTC_ALRM0WF_TIMEOUT; + ErrStatus error_status = ERROR; + uint32_t flag_status = RESET; + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* clear the state of alarm */ + RTC_CTL &= (uint32_t)(~RTC_CTL_ALRM0EN); + + /* wait until ALRM0WF flag to be set after the alarm is disabled */ + do{ + flag_status = RTC_STAT & RTC_STAT_ALRM0WF; + }while((--time_index > 0x00U) && ((uint32_t)RESET == flag_status)); + + if((uint32_t)RESET != flag_status){ + error_status = SUCCESS; + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + + return error_status; +} + +/*! + \brief get RTC alarm + \param[in] none + \param[out] rtc_alarm_time: pointer to a rtc_alarm_struct structure which contains + parameters for RTC alarm configuration + members of the structure and the member values are shown as below: + rtc_alarm_mask: RTC_ALARM_NONE_MASK, RTC_ALARM_DATE_MASK, RTC_ALARM_HOUR_MASK + RTC_ALARM_MINUTE_MASK, RTC_ALARM_SECOND_MASK, RTC_ALARM_ALL_MASK + rtc_weekday_or_date: RTC_ALARM_DATE_SELECTED, RTC_ALARM_WEEKDAY_SELECTED + rtc_alarm_day: 1) 0x1 - 0x31(BCD format) if RTC_ALARM_DATE_SELECTED is set + 2) RTC_MONDAY, RTC_TUESDAY, RTC_WEDSDAY, RTC_THURSDAY, RTC_FRIDAY, + RTC_SATURDAY, RTC_SUNDAY if RTC_ALARM_WEEKDAY_SELECTED is set + rtc_alarm_hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the rtc_display_format + rtc_alarm_minute: 0x0 - 0x59(BCD format) + rtc_alarm_second: 0x0 - 0x59(BCD format) + rtc_am_pm: RTC_AM, RTC_PM + \retval none +*/ +void rtc_alarm_get(rtc_alarm_struct* rtc_alarm_time) +{ + uint32_t reg_alrm0td = 0x00U; + + /* get the value of RTC_ALRM0TD register */ + reg_alrm0td = RTC_ALRM0TD; + + /* get alarm parameters and construct the rtc_alarm_struct structure */ + rtc_alarm_time->rtc_alarm_mask = reg_alrm0td & RTC_ALARM_ALL_MASK; + rtc_alarm_time->rtc_am_pm = (uint32_t)(reg_alrm0td & RTC_ALRM0TD_PM); + rtc_alarm_time->rtc_weekday_or_date = (uint32_t)(reg_alrm0td & RTC_ALRM0TD_DOWS); + rtc_alarm_time->rtc_alarm_day = (uint8_t)GET_ALRM0TD_DAY(reg_alrm0td); + rtc_alarm_time->rtc_alarm_hour = (uint8_t)GET_ALRM0TD_HR(reg_alrm0td); + rtc_alarm_time->rtc_alarm_minute = (uint8_t)GET_ALRM0TD_MN(reg_alrm0td); + rtc_alarm_time->rtc_alarm_second = (uint8_t)GET_ALRM0TD_SC(reg_alrm0td); +} + +/*! + \brief get RTC alarm subsecond + \param[in] none + \param[out] none + \retval RTC alarm subsecond value +*/ +uint32_t rtc_alarm_subsecond_get(void) +{ + return ((uint32_t)(RTC_ALRM0SS & RTC_ALRM0SS_SSC)); +} + +/*! + \brief enable RTC time-stamp + \param[in] edge: specify which edge to detect of time-stamp + only one parameter can be selected which is shown as below: + \arg RTC_TIMESTAMP_RISING_EDGE: rising edge is valid event edge for timestamp event + \arg RTC_TIMESTAMP_FALLING_EDGE: falling edge is valid event edge for timestamp event + \param[out] none + \retval none +*/ +void rtc_timestamp_enable(uint32_t edge) +{ + uint32_t reg_ctl = 0x00U; + + /* clear the bits to be configured in RTC_CTL */ + reg_ctl = (uint32_t)(RTC_CTL & (uint32_t)(~(RTC_CTL_TSEG | RTC_CTL_TSEN))); + + /* new configuration */ + reg_ctl |= (uint32_t)(edge | RTC_CTL_TSEN); + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + RTC_CTL = (uint32_t)reg_ctl; + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief disable RTC time-stamp + \param[in] none + \param[out] none + \retval none +*/ +void rtc_timestamp_disable(void) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* clear the TSEN bit */ + RTC_CTL &= (uint32_t)(~ RTC_CTL_TSEN); + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief get RTC timestamp time and date + \param[in] none + \param[out] rtc_timestamp: pointer to a rtc_timestamp_struct structure which contains + parameters for RTC time-stamp configuration + members of the structure and the member values are shown as below: + rtc_timestamp_month: RTC_JAN, RTC_FEB, RTC_MAR, RTC_APR, RTC_MAY, RTC_JUN, + RTC_JUL, RTC_AUG, RTC_SEP, RTC_OCT, RTC_NOV, RTC_DEC + rtc_timestamp_date: 0x1 - 0x31(BCD format) + rtc_timestamp_day: RTC_MONDAY, RTC_TUESDAY, RTC_WEDSDAY, RTC_THURSDAY, RTC_FRIDAY, + RTC_SATURDAY, RTC_SUNDAY if RTC_ALARM_WEEKDAY_SELECTED is set + rtc_timestamp_hour: 0x0 - 0x12(BCD format) or 0x0 - 0x23(BCD format) depending on the rtc_display_format + rtc_timestamp_minute: 0x0 - 0x59(BCD format) + rtc_timestamp_second: 0x0 - 0x59(BCD format) + rtc_am_pm: RTC_AM, RTC_PM + \retval none +*/ +void rtc_timestamp_get(rtc_timestamp_struct* rtc_timestamp) +{ + uint32_t temp_tts = 0x00U, temp_dts = 0x00U; + + /* get the value of time_stamp registers */ + temp_tts = (uint32_t)RTC_TTS; + temp_dts = (uint32_t)RTC_DTS; + + /* get timestamp time and construct the rtc_timestamp_struct structure */ + rtc_timestamp->rtc_am_pm = (uint32_t)(temp_tts & RTC_TTS_PM); + rtc_timestamp->rtc_timestamp_month = (uint8_t)GET_DTS_MON(temp_dts); + rtc_timestamp->rtc_timestamp_date = (uint8_t)GET_DTS_DAY(temp_dts); + rtc_timestamp->rtc_timestamp_day = (uint8_t)GET_DTS_DOW(temp_dts); + rtc_timestamp->rtc_timestamp_hour = (uint8_t)GET_TTS_HR(temp_tts); + rtc_timestamp->rtc_timestamp_minute = (uint8_t)GET_TTS_MN(temp_tts); + rtc_timestamp->rtc_timestamp_second = (uint8_t)GET_TTS_SC(temp_tts); +} + +/*! + \brief get RTC time-stamp subsecond + \param[in] none + \param[out] none + \retval RTC time-stamp subsecond value +*/ +uint32_t rtc_timestamp_subsecond_get(void) +{ + return ((uint32_t)RTC_SSTS); +} + +/*! + \brief enable RTC tamper + \param[in] rtc_tamper: pointer to a rtc_tamper_struct structure which contains + parameters for RTC tamper configuration + members of the structure and the member values are shown as below: + rtc_tamper_source: RTC_TAMPER0, RTC_TAMPER1 + rtc_tamper_trigger: RTC_TAMPER_TRIGGER_EDGE_RISING, RTC_TAMPER_TRIGGER_EDGE_FALLING + RTC_TAMPER_TRIGGER_LEVEL_LOW, RTC_TAMPER_TRIGGER_LEVEL_HIGH + rtc_tamper_filter: RTC_FLT_EDGE, RTC_FLT_2S, RTC_FLT_4S, RTC_FLT_8S + rtc_tamper_sample_frequency: RTC_FREQ_DIV32768, RTC_FREQ_DIV16384, RTC_FREQ_DIV8192, + RTC_FREQ_DIV4096, RTC_FREQ_DIV2048, RTC_FREQ_DIV1024, + RTC_FREQ_DIV512, RTC_FREQ_DIV256 + rtc_tamper_precharge_enable: DISABLE, ENABLE + rtc_tamper_precharge_time: RTC_PRCH_1C, RTC_PRCH_2C, RTC_PRCH_4C, RTC_PRCH_8C + rtc_tamper_with_timestamp: DISABLE, ENABLE + \param[out] none + \retval none +*/ +void rtc_tamper_enable(rtc_tamper_struct* rtc_tamper) +{ + /* disable tamper */ + RTC_TAMP &= (uint32_t)~(rtc_tamper->rtc_tamper_source); + + /* tamper filter must be used when the tamper source is voltage level detection */ + RTC_TAMP &= (uint32_t)~RTC_TAMP_FLT; + + /* the tamper source is voltage level detection */ + if(rtc_tamper->rtc_tamper_filter != RTC_FLT_EDGE ){ + RTC_TAMP &= (uint32_t)~(RTC_TAMP_DISPU | RTC_TAMP_PRCH | RTC_TAMP_FREQ | RTC_TAMP_FLT); + + /* check if the tamper pin need precharge, if need, then configure the precharge time */ + if(DISABLE == rtc_tamper->rtc_tamper_precharge_enable){ + RTC_TAMP |= (uint32_t)RTC_TAMP_DISPU; + }else{ + RTC_TAMP |= (uint32_t)(rtc_tamper->rtc_tamper_precharge_time); + } + + RTC_TAMP |= (uint32_t)(rtc_tamper->rtc_tamper_sample_frequency); + RTC_TAMP |= (uint32_t)(rtc_tamper->rtc_tamper_filter); + } + + RTC_TAMP &= (uint32_t)~RTC_TAMP_TPTS; + + if(DISABLE != rtc_tamper->rtc_tamper_with_timestamp){ + /* the tamper event also cause a time-stamp event */ + RTC_TAMP |= (uint32_t)RTC_TAMP_TPTS; + } + + /* configure the tamper trigger */ + RTC_TAMP &= ((uint32_t)~((rtc_tamper->rtc_tamper_source) << RTC_TAMPER_TRIGGER_POS)); + if(RTC_TAMPER_TRIGGER_EDGE_RISING != rtc_tamper->rtc_tamper_trigger){ + RTC_TAMP |= (uint32_t)((rtc_tamper->rtc_tamper_source)<< RTC_TAMPER_TRIGGER_POS); + } + /* enable tamper */ + RTC_TAMP |= (uint32_t)(rtc_tamper->rtc_tamper_source); +} + +/*! + \brief disable RTC tamper + \param[in] source: specify which tamper source to be disabled + only one parameter can be selected which is shown as below: + \arg RTC_TAMPER0 + \arg RTC_TAMPER1 + \param[out] none + \retval none +*/ +void rtc_tamper_disable(uint32_t source) +{ + /* disable tamper */ + RTC_TAMP &= (uint32_t)~source; + +} + +/*! + \brief enable specified RTC interrupt + \param[in] interrupt: specify which interrupt source to be enabled + only one parameter can be selected which is shown as below: + \arg RTC_INT_TIMESTAMP: timestamp interrupt + \arg RTC_INT_ALARM: alarm interrupt + \arg RTC_INT_TAMP: tamp interrupt + \param[out] none + \retval none +*/ +void rtc_interrupt_enable(uint32_t interrupt) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* enable the interrupts in RTC_CTL register */ + RTC_CTL |= (uint32_t)(interrupt & (uint32_t)~RTC_TAMP_TPIE); + /* enable the interrupts in RTC_TAMP register */ + RTC_TAMP |= (uint32_t)(interrupt & RTC_TAMP_TPIE); + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief disble specified RTC interrupt + \param[in] interrupt: specify which interrupt source to be disabled + only one parameter can be selected which is shown as below: + \arg RTC_INT_TIMESTAMP: timestamp interrupt + \arg RTC_INT_ALARM: alarm interrupt + \arg RTC_INT_TAMP: tamp interrupt + \param[out] none + \retval none +*/ +void rtc_interrupt_disable(uint32_t interrupt) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* disable the interrupts in RTC_CTL register */ + RTC_CTL &= (uint32_t)~(interrupt & (uint32_t)~RTC_TAMP_TPIE); + /* disable the interrupts in RTC_TAMP register */ + RTC_TAMP &= (uint32_t)~(interrupt & RTC_TAMP_TPIE); + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief check specified flag + \param[in] flag: specify which flag to check + only one parameter can be selected which is shown as below: + \arg RTC_FLAG_RECALIBRATION: recalibration pending flag + \arg RTC_FLAG_TAMP1: tamper 1 event flag + \arg RTC_FLAG_TAMP0: tamper 0 event flag + \arg RTC_FLAG_TIMESTAMP_OVERFLOW: time-stamp overflow event flag + \arg RTC_FLAG_TIMESTAMP: time-stamp event flag + \arg RTC_FLAG_ALARM0: alarm event flag + \arg RTC_FLAG_INIT: init mode event flag + \arg RTC_FLAG_RSYN: time and date registers synchronized event flag + \arg RTC_FLAG_YCM: year parameter configured event flag + \arg RTC_FLAG_SHIFT: shift operation pending flag + \arg RTC_FLAG_ALARM0_WRITTEN: alarm writen available flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus rtc_flag_get(uint32_t flag) +{ + FlagStatus flag_state = RESET; + + if((uint32_t)RESET != (RTC_STAT & flag)){ + flag_state = SET; + } + return flag_state; +} + +/*! + \brief clear specified flag + \param[in] flag: specify which flag to clear + only one parameter can be selected which is shown as below: + \arg RTC_FLAG_TAMP1: tamper 1 event flag + \arg RTC_FLAG_TAMP0: tamper 0 event flag + \arg RTC_FLAG_TIMESTAMP_OVERFLOW: time-stamp overflow event flag + \arg RTC_FLAG_TIMESTAMP: time-stamp event flag + \arg RTC_FLAG_ALARM0: alarm event flag + \arg RTC_FLAG_RSYN: time and date registers synchronized event flag + \param[out] none + \retval none +*/ +void rtc_flag_clear(uint32_t flag) +{ + RTC_STAT &= (uint32_t)(~flag); +} + +/*! + \brief configure rtc alternate output source + \param[in] source: specify signal to output + only one parameter can be selected which is shown as below: + \arg RTC_CALIBRATION_512HZ: when the LSE freqency is 32768Hz and the RTC_PSC + is the default value, output 512Hz signal + \arg RTC_CALIBRATION_1HZ: when the LSE freqency is 32768Hz and the RTC_PSC + is the default value, output 512Hz signal + \arg RTC_ALARM_HIGH: when the alarm flag is set, the output pin is high + \arg RTC_ALARM_LOW: when the Alarm flag is set, the output pin is low + \param[in] mode: specify the output pin (PC13) mode when output alarm signal + only one parameter can be selected which is shown as below: + \arg RTC_ALARM_OUTPUT_OD: open drain mode + \arg RTC_ALARM_OUTPUT_PP: push pull mode + \param[out] none + \retval none +*/ +void rtc_alter_output_config(uint32_t source, uint32_t mode) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + RTC_CTL &= (uint32_t)~(RTC_CTL_COEN | RTC_CTL_OS | RTC_CTL_OPOL | RTC_CTL_COS); + + RTC_CTL |= (uint32_t)(source); + + /* alarm output */ + if((uint32_t)RESET != (source & RTC_OS_ENABLE)){ + RTC_TAMP &= (uint32_t)~(RTC_TAMP_PC13VAL); + RTC_TAMP |= (uint32_t)(mode); + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief configure RTC calibration register + \param[in] window: select calibration window + only one parameter can be selected which is shown as below: + \arg RTC_CALIBRATION_WINDOW_32S: 2exp20 RTCCLK cycles, 32s if RTCCLK = 32768 Hz + \arg RTC_CALIBRATION_WINDOW_16S: 2exp19 RTCCLK cycles, 16s if RTCCLK = 32768 Hz + \arg RTC_CALIBRATION_WINDOW_8S: 2exp18 RTCCLK cycles, 8s if RTCCLK = 32768 Hz + \param[in] plus: add RTC clock or not + only one parameter can be selected which is shown as below: + \arg RTC_CALIBRATION_PLUS_SET: add one RTC clock every 2048 rtc clock + \arg RTC_CALIBRATION_PLUS_RESET: no effect + \param[in] minus: the RTC clock to minus during the calibration window(0x0 - 0x1FF) + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_calibration_config(uint32_t window, uint32_t plus, uint32_t minus) +{ + uint32_t time_index = RTC_HRFC_TIMEOUT; + ErrStatus error_status = ERROR; + uint32_t flag_status = RESET; + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* check if a calibration operation is ongoing */ + do{ + flag_status = RTC_STAT & RTC_STAT_SCPF; + }while((--time_index > 0x00U) && ((uint32_t)RESET != flag_status)); + + if((uint32_t)RESET == flag_status){ + RTC_HRFC = (uint32_t)(window | plus | HRFC_CMSK(minus)); + error_status = SUCCESS; + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + + return error_status; +} + +/*! + \brief adjust the daylight saving time by adding or substracting one hour from the current time + \param[in] operation: hour ajustment operation + only one parameter can be selected which is shown as below: + \arg RTC_CTL_A1H: add one hour + \arg RTC_CTL_S1H: substract one hour + \param[out] none + \retval none +*/ +void rtc_hour_adjust(uint32_t operation) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + RTC_CTL |= (uint32_t)(operation); + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief adjust RTC second or subsecond value of current time + \param[in] add: add 1s to current time or not + only one parameter can be selected which is shown as below: + \arg RTC_SHIFT_ADD1S_RESET: no effect + \arg RTC_SHIFT_ADD1S_SET: add 1s to current time + \param[in] minus: number of subsecond to minus from current time(0x0 - 0x7FFF) + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_second_adjust(uint32_t add, uint32_t minus) +{ + uint32_t time_index = RTC_SHIFTCTL_TIMEOUT; + ErrStatus error_status = ERROR; + uint32_t flag_status = RESET; + uint32_t temp=0U; + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* check if a shift operation is ongoing */ + do{ + flag_status = RTC_STAT & RTC_STAT_SOPF; + }while((--time_index > 0x00U) && ((uint32_t)RESET != flag_status)); + + temp = RTC_CTL & RTC_CTL_REFEN; + /* check if the function of reference clock detection is disabled */ + if(((uint32_t)RESET == flag_status) && (RESET == temp)){ + RTC_SHIFTCTL = (uint32_t)(add | SHIFTCTL_SFS(minus)); + error_status = rtc_register_sync_wait(); + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + + return error_status; +} + +/*! + \brief enable RTC bypass shadow registers function + \param[in] none + \param[out] none + \retval none +*/ +void rtc_bypass_shadow_enable(void) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + RTC_CTL |= (uint8_t)RTC_CTL_BPSHAD; + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief disable RTC bypass shadow registers function + \param[in] none + \param[out] none + \retval none +*/ +void rtc_bypass_shadow_disable(void) +{ + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + RTC_CTL &= (uint8_t)~RTC_CTL_BPSHAD; + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; +} + +/*! + \brief enable RTC reference clock detection function + \param[in] none + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_refclock_detection_enable(void) +{ + ErrStatus error_status = ERROR; + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* enter init mode */ + error_status = rtc_init_mode_enter(); + + if(ERROR != error_status){ + RTC_CTL |= (uint32_t)RTC_CTL_REFEN; + /* exit init mode */ + rtc_init_mode_exit(); + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + + return error_status; +} + +/*! + \brief disable RTC reference clock detection function + \param[in] none + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus rtc_refclock_detection_disable(void) +{ + ErrStatus error_status = ERROR; + + /* disable the write protection */ + RTC_WPK = RTC_UNLOCK_KEY1; + RTC_WPK = RTC_UNLOCK_KEY2; + + /* enter init mode */ + error_status = rtc_init_mode_enter(); + + if(ERROR != error_status){ + RTC_CTL &= (uint32_t)~RTC_CTL_REFEN; + /* exit init mode */ + rtc_init_mode_exit(); + } + + /* enable the write protection */ + RTC_WPK = RTC_LOCK_KEY; + + return error_status; +} diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_spi.c b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_spi.c new file mode 100644 index 0000000000000000000000000000000000000000..a48f5c426acac0cdfc5223d7c255e2b3550f6001 --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_spi.c @@ -0,0 +1,1003 @@ +/*! + \file gd32e230_spi.c + \brief SPI driver + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor 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 copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 "gd32e230_spi.h" + +/* SPI/I2S parameter initialization mask */ +#define SPI_INIT_MASK ((uint32_t)0x00003040U) /*!< SPI0 parameter initialization mask */ +#define SPI_FIFO_INIT_MASK1 ((uint32_t)0x00003840U) /*!< SPI1 parameter initialization mask1 */ +#define SPI_FIFO_INIT_MASK2 ((uint32_t)0x0000F0FFU) /*!< SPI1 parameter initialization mask2*/ +#define I2S_INIT_MASK ((uint32_t)0x0000F047U) /*!< I2S parameter initialization mask */ + +#define SPI_FRAMESIZE_MASK ((uint32_t)0x00000800U) /*!< SPI0 frame size mask */ +#define SPI_BYTEN_MASK ((uint32_t)0x00001000U) /*!< SPI1 access to FIFO mask */ +#define SPI_TXLVL_EMPTY_MASK ((uint32_t)0x00001800U) /*!< SPI1 TXFIFO empty mask */ +#define SPI_RXLVL_EMPTY_MASK ((uint32_t)0x00000600U) /*!< SPI1 RXFIFO empty mask */ + +/* I2S clock source selection, multiplication and division mask */ +#define SPI_I2SPSC_RESET ((uint32_t)0x00000002U) /*!< I2S clock prescaler register reset value */ + +/*! + \brief reset SPI and I2S + \param[in] spi_periph: SPIx(x=0,1) + \param[out] none + \retval none +*/ +void spi_i2s_deinit(uint32_t spi_periph) +{ + switch(spi_periph){ + case SPI0: + /* reset SPI0 and I2S0 */ + rcu_periph_reset_enable(RCU_SPI0RST); + rcu_periph_reset_disable(RCU_SPI0RST); + break; + case SPI1: + /* reset SPI1 */ + rcu_periph_reset_enable(RCU_SPI1RST); + rcu_periph_reset_disable(RCU_SPI1RST); + break; + default : + break; + } +} + +/*! + \brief initialize the parameters of SPI struct with the default values + \param[in] spi_struct: SPI parameter stuct + \param[out] none + \retval none +*/ +void spi_struct_para_init(spi_parameter_struct* spi_struct) +{ + /* set the SPI struct with the default values */ + spi_struct->device_mode = SPI_SLAVE; + spi_struct->trans_mode = SPI_TRANSMODE_FULLDUPLEX; + spi_struct->frame_size = SPI_FRAMESIZE_8BIT; + spi_struct->nss = SPI_NSS_HARD; + spi_struct->clock_polarity_phase = SPI_CK_PL_LOW_PH_1EDGE; + spi_struct->prescale = SPI_PSC_2; +} + +/*! + \brief initialize SPI parameter + \param[in] spi_periph: SPIx(x=0,1) + \param[in] spi_struct: SPI parameter initialization stuct members of the structure + and the member values are shown as below: + device_mode: SPI_MASTER, SPI_SLAVE + trans_mode: SPI_TRANSMODE_FULLDUPLEX, SPI_TRANSMODE_RECEIVEONLY, + SPI_TRANSMODE_BDRECEIVE, SPI_TRANSMODE_BDTRANSMIT + frame_size: SPI_FRAMESIZE_4BIT, SPI_FRAMESIZE_5BIT + SPI_FRAMESIZE_6BIT, SPI_FRAMESIZE_7BIT + SPI_FRAMESIZE_8BIT, SPI_FRAMESIZE_9BIT + SPI_FRAMESIZE_10BIT, SPI_FRAMESIZE_11BIT + SPI_FRAMESIZE_12BIT, SPI_FRAMESIZE_13BIT + SPI_FRAMESIZE_14BIT, SPI_FRAMESIZE_15BIT + SPI_FRAMESIZE_16BIT + nss: SPI_NSS_SOFT, SPI_NSS_HARD + endian: SPI_ENDIAN_MSB, SPI_ENDIAN_LSB + clock_polarity_phase: SPI_CK_PL_LOW_PH_1EDGE, SPI_CK_PL_HIGH_PH_1EDGE + SPI_CK_PL_LOW_PH_2EDGE, SPI_CK_PL_HIGH_PH_2EDGE + prescale: SPI_PSC_n (n=2,4,8,16,32,64,128,256) + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus spi_init(uint32_t spi_periph, spi_parameter_struct* spi_struct) +{ + uint32_t reg1, reg2, reg3 = 0U; + + reg1 = SPI_CTL0(spi_periph); + reg1 &= SPI_INIT_MASK; + + reg2 = SPI_CTL0(spi_periph); + reg2 &= SPI_FIFO_INIT_MASK1; + + reg3 = SPI_CTL1(spi_periph); + reg3 &= SPI_FIFO_INIT_MASK2; + + if( SPI0 == spi_periph){ + /* select SPI as master or slave */ + reg1 |= spi_struct->device_mode; + /* select SPI transfer mode */ + reg1 |= spi_struct->trans_mode; + /* select SPI NSS use hardware or software */ + reg1 |= spi_struct->nss; + /* select SPI LSB or MSB */ + reg1 |= spi_struct->endian; + /* select SPI polarity and phase */ + reg1 |= spi_struct->clock_polarity_phase; + /* select SPI prescale to adjust transmit speed */ + reg1 |= spi_struct->prescale; + /* select SPI frame size */ + /* check SPI0 frame size is 8bits/16bits or not*/ + if((SPI_FRAMESIZE_8BIT != spi_struct->frame_size) && (SPI_FRAMESIZE_16BIT != spi_struct->frame_size)) + { + return ERROR; + }else{ + reg1 |= (spi_struct->frame_size & SPI_FRAMESIZE_MASK); + } + + /* write to SPI_CTL0 register */ + SPI_CTL0(spi_periph) = (uint32_t)reg1; + + }else{ + /* select SPI as master or slave */ + reg2 |= spi_struct->device_mode; + /* select SPI transfer mode */ + reg2 |= spi_struct->trans_mode; + /* select SPI NSS use hardware or software */ + reg2 |= spi_struct->nss; + /* select SPI LSB or MSB */ + reg2 |= spi_struct->endian; + /* select SPI polarity and phase */ + reg2 |= spi_struct->clock_polarity_phase; + /* select SPI prescale to adjust transmit speed */ + reg2 |= spi_struct->prescale; + /* write to SPI_CTL0 register */ + SPI_CTL0(spi_periph) = (uint32_t)reg2; + + /* select SPI data size */ + reg3 |= spi_struct->frame_size; + /* write to SPI_CTL0 register */ + SPI_CTL1(spi_periph) = (uint32_t)reg3; + } + + /* select SPI mode */ + SPI_I2SCTL(spi_periph) &= (uint32_t)(~SPI_I2SCTL_I2SSEL); + + return SUCCESS; +} + +/*! + \brief enable SPI + \param[in] spi_periph: SPIx(x=0,1) + \param[out] none + \retval none +*/ +void spi_enable(uint32_t spi_periph) +{ + SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_SPIEN; +} + +/*! + \brief disable SPI + \param[in] spi_periph: SPIx(x=0,1) + \param[out] none + \retval none +*/ +void spi_disable(uint32_t spi_periph) +{ + SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_SPIEN); +} + +/*! + \brief initialize I2S parameter + \param[in] spi_periph: SPIx(x=0) + \param[in] mode: I2S operation mode + only one parameter can be selected which is shown as below: + \arg I2S_MODE_SLAVETX: I2S slave transmit mode + \arg I2S_MODE_SLAVERX: I2S slave receive mode + \arg I2S_MODE_MASTERTX: I2S master transmit mode + \arg I2S_MODE_MASTERRX: I2S master receive mode + \param[in] standard: I2S standard + only one parameter can be selected which is shown as below: + \arg I2S_STD_PHILLIPS: I2S phillips standard + \arg I2S_STD_MSB: I2S MSB standard + \arg I2S_STD_LSB: I2S LSB standard + \arg I2S_STD_PCMSHORT: I2S PCM short standard + \arg I2S_STD_PCMLONG: I2S PCM long standard + \param[in] ckpl: I2S idle state clock polarity + only one parameter can be selected which is shown as below: + \arg I2S_CKPL_LOW: I2S clock polarity low level + \arg I2S_CKPL_HIGH: I2S clock polarity high level + \param[out] none + \retval none +*/ +void i2s_init(uint32_t spi_periph, uint32_t mode, uint32_t standard, uint32_t ckpl) +{ + uint32_t reg = 0U; + reg = SPI_I2SCTL(spi_periph); + reg &= I2S_INIT_MASK; + + /* enable I2S mode */ + reg |= (uint32_t)SPI_I2SCTL_I2SSEL; + /* select I2S mode */ + reg |= (uint32_t)mode; + /* select I2S standard */ + reg |= (uint32_t)standard; + /* select I2S polarity */ + reg |= (uint32_t)ckpl; + + /* write to SPI_I2SCTL register */ + SPI_I2SCTL(spi_periph) = (uint32_t)reg; +} + +/*! + \brief configure I2S prescaler + \param[in] spi_periph: SPIx(x=0) + \param[in] audiosample: I2S audio sample rate + only one parameter can be selected which is shown as below: + \arg I2S_AUDIOSAMPLE_8K: audio sample rate is 8KHz + \arg I2S_AUDIOSAMPLE_11K: audio sample rate is 11KHz + \arg I2S_AUDIOSAMPLE_16K: audio sample rate is 16KHz + \arg I2S_AUDIOSAMPLE_22K: audio sample rate is 22KHz + \arg I2S_AUDIOSAMPLE_32K: audio sample rate is 32KHz + \arg I2S_AUDIOSAMPLE_44K: audio sample rate is 44KHz + \arg I2S_AUDIOSAMPLE_48K: audio sample rate is 48KHz + \arg I2S_AUDIOSAMPLE_96K: audio sample rate is 96KHz + \arg I2S_AUDIOSAMPLE_192K: audio sample rate is 192KHz + \param[in] frameformat: I2S data length and channel length + only one parameter can be selected which is shown as below: + \arg I2S_FRAMEFORMAT_DT16B_CH16B: I2S data length is 16 bit and channel length is 16 bit + \arg I2S_FRAMEFORMAT_DT16B_CH32B: I2S data length is 16 bit and channel length is 32 bit + \arg I2S_FRAMEFORMAT_DT24B_CH32B: I2S data length is 24 bit and channel length is 32 bit + \arg I2S_FRAMEFORMAT_DT32B_CH32B: I2S data length is 32 bit and channel length is 32 bit + \param[in] mckout: I2S master clock output + only one parameter can be selected which is shown as below: + \arg I2S_MCKOUT_ENABLE: I2S master clock output enable + \arg I2S_MCKOUT_DISABLE: I2S master clock output disable + \param[out] none + \retval none +*/ +void i2s_psc_config(uint32_t spi_periph, uint32_t audiosample, uint32_t frameformat, uint32_t mckout) +{ + uint32_t i2sdiv = 2U, i2sof = 0U; + uint32_t clks = 0U; + uint32_t i2sclock = 0U; + + /* deinit SPI_I2SPSC register */ + SPI_I2SPSC(spi_periph) = SPI_I2SPSC_RESET; + + /* get system clock */ + i2sclock = rcu_clock_freq_get(CK_SYS); + + /* config the prescaler depending on the mclk output state, the frame format and audio sample rate */ + if(I2S_MCKOUT_ENABLE == mckout){ + clks = (uint32_t)(((i2sclock / 256U) * 10U) / audiosample); + }else{ + if(I2S_FRAMEFORMAT_DT16B_CH16B == frameformat){ + clks = (uint32_t)(((i2sclock / 32U) *10U ) / audiosample); + }else{ + clks = (uint32_t)(((i2sclock / 64U) *10U ) / audiosample); + } + } + + /* remove the floating point */ + clks = (clks + 5U) / 10U; + i2sof = (clks & 0x00000001U); + i2sdiv = ((clks - i2sof) / 2U); + i2sof = (i2sof << 8U); + + /* set the default values */ + if((i2sdiv < 2U) || (i2sdiv > 255U)){ + i2sdiv = 2U; + i2sof = 0U; + } + + /* configure SPI_I2SPSC */ + SPI_I2SPSC(spi_periph) = (uint32_t)(i2sdiv | i2sof | mckout); + + /* clear SPI_I2SCTL_DTLEN and SPI_I2SCTL_CHLEN bits */ + SPI_I2SCTL(spi_periph) &= (uint32_t)(~(SPI_I2SCTL_DTLEN | SPI_I2SCTL_CHLEN)); + /* configure data frame format */ + SPI_I2SCTL(spi_periph) |= (uint32_t)frameformat; +} + + +/*! + \brief enable I2S + \param[in] spi_periph: SPIx(x=0) + \param[out] none + \retval none +*/ +void i2s_enable(uint32_t spi_periph) +{ + SPI_I2SCTL(spi_periph) |= (uint32_t)SPI_I2SCTL_I2SEN; +} + +/*! + \brief disable I2S + \param[in] spi_periph: SPIx(x=0) + \param[out] none + \retval none +*/ +void i2s_disable(uint32_t spi_periph) +{ + SPI_I2SCTL(spi_periph) &= (uint32_t)(~SPI_I2SCTL_I2SEN); +} + +/*! + \brief enable SPI NSS output + \param[in] spi_periph: SPIx(x=0,1) + \param[out] none + \retval none +*/ +void spi_nss_output_enable(uint32_t spi_periph) +{ + SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_NSSDRV; +} + +/*! + \brief disable SPI NSS output + \param[in] spi_periph: SPIx(x=0,1) + \param[out] none + \retval none +*/ +void spi_nss_output_disable(uint32_t spi_periph) +{ + SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_NSSDRV); +} + +/*! + \brief SPI NSS pin high level in software mode + \param[in] spi_periph: SPIx(x=0,1) + \param[out] none + \retval none +*/ +void spi_nss_internal_high(uint32_t spi_periph) +{ + SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_SWNSS; +} + +/*! + \brief SPI NSS pin low level in software mode + \param[in] spi_periph: SPIx(x=0,1) + \param[out] none + \retval none +*/ +void spi_nss_internal_low(uint32_t spi_periph) +{ + SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_SWNSS); +} + +/*! + \brief enable SPI DMA send or receive + \param[in] spi_periph: SPIx(x=0,1) + \param[in] dma: SPI DMA mode + only one parameter can be selected which is shown as below: + \arg SPI_DMA_TRANSMIT: SPI transmit data using DMA + \arg SPI_DMA_RECEIVE: SPI receive data using DMA + \param[out] none + \retval none +*/ +void spi_dma_enable(uint32_t spi_periph, uint8_t dma) +{ + if(SPI_DMA_TRANSMIT == dma){ + SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_DMATEN; + }else{ + SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_DMAREN; + } +} + +/*! + \brief disable SPI DMA send or receive + \param[in] spi_periph: SPIx(x=0,1) + \param[in] dma: SPI DMA mode + only one parameter can be selected which is shown as below: + \arg SPI_DMA_TRANSMIT: SPI transmit data using DMA + \arg SPI_DMA_RECEIVE: SPI receive data using DMA + \param[out] none + \retval none +*/ +void spi_dma_disable(uint32_t spi_periph, uint8_t dma) +{ + if(SPI_DMA_TRANSMIT == dma){ + SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_DMATEN); + }else{ + SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_DMAREN); + } +} + +/*! + \brief configure SPI/I2S data frame format + \param[in] spi_periph: SPIx(x=0,1) + \param[in] frame_format: SPI frame size + only one parameter can be selected which is shown as below: + \arg SPI_FRAMESIZE_4BIT: SPI frame size is 4 bits + \arg SPI_FRAMESIZE_5BIT: SPI frame size is 5 bits + \arg SPI_FRAMESIZE_6BIT: SPI frame size is 6 bits + \arg SPI_FRAMESIZE_7BIT: SPI frame size is 7 bits + \arg SPI_FRAMESIZE_8BIT: SPI frame size is 8 bits + \arg SPI_FRAMESIZE_9BIT: SPI frame size is 9 bits + \arg SPI_FRAMESIZE_10BIT: SPI frame size is 10 bits + \arg SPI_FRAMESIZE_11BIT: SPI frame size is 11 bits + \arg SPI_FRAMESIZE_12BIT: SPI frame size is 12 bits + \arg SPI_FRAMESIZE_13BIT: SPI frame size is 13 bits + \arg SPI_FRAMESIZE_14BIT: SPI frame size is 14 bits + \arg SPI_FRAMESIZE_15BIT: SPI frame size is 15 bits + \arg SPI_FRAMESIZE_16BIT: SPI frame size is 16 bits + \param[out] none + \retval ErrStatus: ERROR or SUCCESS +*/ +ErrStatus spi_i2s_data_frame_format_config(uint32_t spi_periph, uint16_t frame_format) +{ + if(SPI0 == spi_periph) + { + /* check SPI0 frame size is 8bits/16bits or not*/ + if((SPI_FRAMESIZE_8BIT != frame_format) && (SPI_FRAMESIZE_16BIT != frame_format)) + { + return ERROR; + }else{ + /* clear SPI_CTL0_FF16 bit */ + SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_FF16); + /* configure SPI_CTL0_FF16 bit */ + SPI_CTL0(spi_periph) |= ((uint32_t)frame_format & SPI_FRAMESIZE_MASK); + } + } + else{ + /* clear SPI_CTL1_DZ bits */ + SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_DZ); + /* confige SPI_CTL1_DZ bits */ + SPI_CTL1(spi_periph) |= (uint32_t)frame_format; + } + return SUCCESS; +} + +/*! + \brief SPI transmit data + \param[in] spi_periph: SPIx(x=0,1) + \param[in] data: 16-bit data + \param[out] none + \retval none +*/ +void spi_i2s_data_transmit(uint32_t spi_periph, uint16_t data) +{ + uint32_t reg, byten; + if(SPI0 == spi_periph) + { + SPI_DATA(spi_periph) = (uint32_t)data; + } + else + { + /* get the access size to FIFO */ + byten = SPI_CTL1(spi_periph) & SPI_BYTEN_MASK; + if(RESET != byten) + { + reg = spi_periph + 0x0CU; + *( uint8_t *)(reg) = (uint8_t)data; + }else + { + SPI_DATA(spi_periph) = (uint16_t)data; + } + } +} + +/*! + \brief SPI receive data + \param[in] spi_periph: SPIx(x=0,1) + \param[out] none + \retval 16-bit data +*/ +uint16_t spi_i2s_data_receive(uint32_t spi_periph) +{ + uint32_t reg, byten; + if(SPI0 == spi_periph) + { + return ((uint16_t)SPI_DATA(spi_periph)); + } + else + { + /* get the access size to FIFO */ + byten = SPI_CTL1(spi_periph) & SPI_BYTEN_MASK; + if(RESET != byten) + { + reg = spi_periph + 0x0CU; + return (uint16_t)(*(uint8_t *)(reg)); + }else + { + return ((uint16_t)SPI_DATA(spi_periph)); + } + } +} + +/*! + \brief configure SPI bidirectional transfer direction + \param[in] spi_periph: SPIx(x=0,1) + \param[in] transfer_direction: SPI transfer direction + only one parameter can be selected which is shown as below: + \arg SPI_BIDIRECTIONAL_TRANSMIT: SPI work in transmit-only mode + \arg SPI_BIDIRECTIONAL_RECEIVE: SPI work in receive-only mode + \param[out] none + \retval none +*/ +void spi_bidirectional_transfer_config(uint32_t spi_periph, uint32_t transfer_direction) +{ + if(SPI_BIDIRECTIONAL_TRANSMIT == transfer_direction){ + /* set the transmit-only mode */ + SPI_CTL0(spi_periph) |= (uint32_t)SPI_BIDIRECTIONAL_TRANSMIT; + }else{ + /* set the receive-only mode */ + SPI_CTL0(spi_periph) &= SPI_BIDIRECTIONAL_RECEIVE; + } +} + +/*! + \brief set SPI CRC polynomial + \param[in] spi_periph: SPIx(x=0,1) + \param[in] crc_poly: CRC polynomial value + \param[out] none + \retval none +*/ +void spi_crc_polynomial_set(uint32_t spi_periph, uint16_t crc_poly) +{ + /* enable SPI CRC */ + SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_CRCEN; + /* set SPI CRC polynomial */ + SPI_CRCPOLY(spi_periph) = (uint32_t)crc_poly; +} + +/*! + \brief get SPI CRC polynomial + \param[in] spi_periph: SPIx(x=0,1) + \param[out] none + \retval 16-bit CRC polynomial +*/ +uint16_t spi_crc_polynomial_get(uint32_t spi_periph) +{ + return ((uint16_t)SPI_CRCPOLY(spi_periph)); +} + +/*! + \brief turn on CRC function + \param[in] spi_periph: SPIx(x=0,1) + \param[out] none + \retval none +*/ +void spi_crc_on(uint32_t spi_periph) +{ + SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_CRCEN; +} + +/*! + \brief turn off CRC function + \param[in] spi_periph: SPIx(x=0,1) + \param[out] none + \retval none +*/ +void spi_crc_off(uint32_t spi_periph) +{ + SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_CRCEN); +} + +/*! + \brief SPI next data is CRC value + \param[in] spi_periph: SPIx(x=0,1) + \param[out] none + \retval none +*/ +void spi_crc_next(uint32_t spi_periph) +{ + SPI_CTL0(spi_periph) |= (uint32_t)SPI_CTL0_CRCNT; +} + +/*! + \brief get SPI CRC send value or receive value + \param[in] spi_periph: SPIx(x=0,1) + \param[in] crc: SPI crc value + only one parameter can be selected which is shown as below: + \arg SPI_CRC_TX: get transmit crc value + \arg SPI_CRC_RX: get receive crc value + \param[out] none + \retval 16-bit CRC value +*/ +uint16_t spi_crc_get(uint32_t spi_periph, uint8_t crc) +{ + if(SPI_CRC_TX == crc){ + return ((uint16_t)(SPI_TCRC(spi_periph))); + }else{ + return ((uint16_t)(SPI_RCRC(spi_periph))); + } +} + +/*! + \brief enable SPI TI mode + \param[in] spi_periph: SPIx(x=0,1) + \param[out] none + \retval none +*/ +void spi_ti_mode_enable(uint32_t spi_periph) +{ + SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_TMOD; +} + +/*! + \brief disable SPI TI mode + \param[in] spi_periph: SPIx(x=0,1) + \param[out] none + \retval none +*/ +void spi_ti_mode_disable(uint32_t spi_periph) +{ + SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_TMOD); +} + +/*! + \brief enable SPI NSS pulse mode + \param[in] spi_periph: SPIx(x=0,1) + \param[out] none + \retval none +*/ +void spi_nssp_mode_enable(uint32_t spi_periph) +{ + SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_NSSP; +} + +/*! + \brief disable SPI NSS pulse mode + \param[in] spi_periph: SPIx(x=0,1) + \param[out] none + \retval none +*/ +void spi_nssp_mode_disable(uint32_t spi_periph) +{ + SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_NSSP); +} + +/*! + \brief enable quad wire SPI + \param[in] spi_periph: SPIx(x=1) + \param[out] none + \retval none +*/ +void qspi_enable(uint32_t spi_periph) +{ + SPI_QCTL(spi_periph) |= (uint32_t)SPI_QCTL_QMOD; +} + +/*! + \brief disable quad wire SPI + \param[in] spi_periph: SPIx(x=1) + \param[out] none + \retval none +*/ +void qspi_disable(uint32_t spi_periph) +{ + SPI_QCTL(spi_periph) &= (uint32_t)(~SPI_QCTL_QMOD); +} + +/*! + \brief enable quad wire SPI write + \param[in] spi_periph: SPIx(x=1) + \param[out] none + \retval none +*/ +void qspi_write_enable(uint32_t spi_periph) +{ + SPI_QCTL(spi_periph) &= (uint32_t)(~SPI_QCTL_QRD); +} + +/*! + \brief enable quad wire SPI read + \param[in] spi_periph: SPIx(x=1) + \param[out] none + \retval none +*/ +void qspi_read_enable(uint32_t spi_periph) +{ + SPI_QCTL(spi_periph) |= (uint32_t)SPI_QCTL_QRD; +} + +/*! + \brief enable SPI_IO2 and SPI_IO3 pin output + \param[in] spi_periph: SPIx(x=1) + \param[out] none + \retval none +*/ +void qspi_io23_output_enable(uint32_t spi_periph) +{ + SPI_QCTL(spi_periph) |= (uint32_t)SPI_QCTL_IO23_DRV; +} + + /*! + \brief disable SPI_IO2 and SPI_IO3 pin output + \param[in] spi_periph: SPIx(x=1) + \param[out] none + \retval none +*/ + void qspi_io23_output_disable(uint32_t spi_periph) +{ + SPI_QCTL(spi_periph) &= (uint32_t)(~SPI_QCTL_IO23_DRV); +} + +/*! + \brief enable SPI and I2S interrupt + \param[in] spi_periph: SPIx(x=0,1) + \param[in] interrupt: SPI/I2S interrupt + only one parameter can be selected which is shown as below: + \arg SPI_I2S_INT_TBE: transmit buffer empty interrupt + \arg SPI_I2S_INT_RBNE: receive buffer not empty interrupt + \arg SPI_I2S_INT_ERR: CRC error,configuration error,reception overrun error, + transmission underrun error and format error interrupt + \param[out] none + \retval none +*/ +void spi_i2s_interrupt_enable(uint32_t spi_periph, uint8_t interrupt) +{ + switch(interrupt){ + /* SPI/I2S transmit buffer empty interrupt */ + case SPI_I2S_INT_TBE: + SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_TBEIE; + break; + /* SPI/I2S receive buffer not empty interrupt */ + case SPI_I2S_INT_RBNE: + SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_RBNEIE; + break; + /* SPI/I2S error */ + case SPI_I2S_INT_ERR: + SPI_CTL1(spi_periph) |= (uint32_t)SPI_CTL1_ERRIE; + break; + default: + break; + } +} + +/*! + \brief disable SPI and I2S interrupt + \param[in] spi_periph: SPIx(x=0,1) + \param[in] interrupt: SPI/I2S interrupt + only one parameter can be selected which is shown as below: + \arg SPI_I2S_INT_TBE: transmit buffer empty interrupt + \arg SPI_I2S_INT_RBNE: receive buffer not empty interrupt + \arg SPI_I2S_INT_ERR: CRC error,configuration error,reception overrun error, + transmission underrun error and format error interrupt + \param[out] none + \retval none +*/ +void spi_i2s_interrupt_disable(uint32_t spi_periph, uint8_t interrupt) +{ + switch(interrupt){ + /* SPI/I2S transmit buffer empty interrupt */ + case SPI_I2S_INT_TBE: + SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_TBEIE); + break; + /* SPI/I2S receive buffer not empty interrupt */ + case SPI_I2S_INT_RBNE: + SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_RBNEIE); + break; + /* SPI/I2S error */ + case SPI_I2S_INT_ERR: + SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_ERRIE); + break; + default : + break; + } +} + +/*! + \brief get SPI and I2S interrupt flag status + \param[in] spi_periph: SPIx(x=0,1) + \param[in] interrupt: SPI/I2S interrupt flag status + only one parameter can be selected which is shown as below: + \arg SPI_I2S_INT_FLAG_TBE: transmit buffer empty interrupt flag + \arg SPI_I2S_INT_FLAG_RBNE: receive buffer not empty interrupt flag + \arg SPI_I2S_INT_FLAG_RXORERR: overrun interrupt flag + \arg SPI_INT_FLAG_CONFERR: config error interrupt flag + \arg SPI_INT_FLAG_CRCERR: CRC error interrupt flag + \arg I2S_INT_FLAG_TXURERR: underrun error interrupt flag + \arg SPI_I2S_INT_FLAG_FERR: format error interrupt flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus spi_i2s_interrupt_flag_get(uint32_t spi_periph, uint8_t interrupt) +{ + uint32_t reg1 = SPI_STAT(spi_periph); + uint32_t reg2 = SPI_CTL1(spi_periph); + + switch(interrupt){ + /* SPI/I2S transmit buffer empty interrupt */ + case SPI_I2S_INT_FLAG_TBE: + reg1 = reg1 & SPI_STAT_TBE; + reg2 = reg2 & SPI_CTL1_TBEIE; + break; + /* SPI/I2S receive buffer not empty interrupt */ + case SPI_I2S_INT_FLAG_RBNE: + reg1 = reg1 & SPI_STAT_RBNE; + reg2 = reg2 & SPI_CTL1_RBNEIE; + break; + /* SPI/I2S overrun interrupt */ + case SPI_I2S_INT_FLAG_RXORERR: + reg1 = reg1 & SPI_STAT_RXORERR; + reg2 = reg2 & SPI_CTL1_ERRIE; + break; + /* SPI config error interrupt */ + case SPI_INT_FLAG_CONFERR: + reg1 = reg1 & SPI_STAT_CONFERR; + reg2 = reg2 & SPI_CTL1_ERRIE; + break; + /* SPI CRC error interrupt */ + case SPI_INT_FLAG_CRCERR: + reg1 = reg1 & SPI_STAT_CRCERR; + reg2 = reg2 & SPI_CTL1_ERRIE; + break; + /* I2S underrun error interrupt */ + case I2S_INT_FLAG_TXURERR: + reg1 = reg1 & SPI_STAT_TXURERR; + reg2 = reg2 & SPI_CTL1_ERRIE; + break; + /* SPI/I2S format error interrupt */ + case SPI_I2S_INT_FLAG_FERR: + reg1 = reg1 & SPI_STAT_FERR; + reg2 = reg2 & SPI_CTL1_ERRIE; + break; + default : + break; + } + /*get SPI/I2S interrupt flag status */ + if((0U != reg1) && (0U != reg2)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief get SPI and I2S flag status + \param[in] spi_periph: SPIx(x=0,1) + \param[in] flag: SPI/I2S flag status + one or more parameters can be selected which are shown as below: + \arg SPI_FLAG_TBE: transmit buffer empty flag + \arg SPI_FLAG_RBNE: receive buffer not empty flag + \arg SPI_FLAG_TRANS: transmit on-going flag + \arg SPI_FLAG_RXORERR: receive overrun error flag + \arg SPI_FLAG_CONFERR: mode config error flag + \arg SPI_FLAG_CRCERR: CRC error flag + \arg SPI_FLAG_FERR: format error interrupt flag + \arg I2S_FLAG_TBE: transmit buffer empty flag + \arg I2S_FLAG_RBNE: receive buffer not empty flag + \arg I2S_FLAG_TRANS: transmit on-going flag + \arg I2S_FLAG_RXORERR: overrun error flag + \arg I2S_FLAG_TXURERR: underrun error flag + \arg I2S_FLAG_CH: channel side flag + only for SPI1: + \arg SPI_TXLVL_EMPTY: SPI TXFIFO is empty + \arg SPI_TXLVL_QUARTER_FULL: SPI TXFIFO is a quarter of full + \arg SPI_TXLVL_HAlF_FULL: SPI TXFIFO is a half of full + \arg SPI_TXLVL_FULL: SPI TXFIFO is full + \arg SPI_RXLVL_EMPTY: SPI RXFIFO is empty + \arg SPI_RXLVL_QUARTER_FULL: SPI RXFIFO is a quarter of full + \arg SPI_RXLVL_HAlF_FULL: SPI RXFIFO is a half of full + \arg SPI_RXLVL_FULL: SPI RXFIFO is full + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus spi_i2s_flag_get(uint32_t spi_periph, uint32_t flag) +{ + if(RESET != (SPI_STAT(spi_periph) & flag)){ + return SET; + }else{ + if(SPI1 == spi_periph){ + /* check TXFIFO is empty or not */ + if(SPI_TXLVL_EMPTY == flag){ + if(RESET != (SPI_STAT(spi_periph) & SPI_TXLVL_EMPTY_MASK)){ + return RESET; + }else{ + return SET; + } + } + /* check RXFIFO is empty or not */ + if(SPI_RXLVL_EMPTY == flag){ + if(RESET != (SPI_STAT(spi_periph) & SPI_RXLVL_EMPTY_MASK)){ + return RESET; + }else{ + return SET; + } + } + } + return RESET; + } +} + +/*! + \brief clear SPI CRC error flag status + \param[in] spi_periph: SPIx(x=0,1) + \param[out] none + \retval none +*/ +void spi_crc_error_clear(uint32_t spi_periph) +{ + SPI_STAT(spi_periph) &= (uint32_t)(~SPI_FLAG_CRCERR); +} + +/*! + \brief configure SPI1 access size to FIFO(8bit or 16bit) + \param[in] spi_periph: SPIx(x=1) + \param[in] fifo_access_size: byte access enable + only one parameter can be selected which is shown as below: + \arg SPI_HALFWORD_ACCESS: half-word access to FIFO + \arg SPI_BYTE_ACCESS: byte access to FIFO + \param[out] none + \retval none +*/ +void spi_fifo_access_size_config(uint32_t spi_periph, uint16_t fifo_access_size) +{ + /* clear SPI_CTL1_BYTEN bit */ + SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_BYTEN); + /* confige SPI_CTL1_BYTEN bit */ + SPI_CTL1(spi_periph) |= (uint32_t)fifo_access_size; +} + +/*! + \brief configure SPI1 total number of data to transmit by DMA is odd or not + \param[in] spi_periph: SPIx(x=1) + \param[in] odd: odd bytes in TX DMA channel + only one parameter can be selected which is shown as below: + \arg SPI_TXDMA_EVEN: number of byte in TX DMA channel is even + \arg SPI_TXDMA_ODD: number of byte in TX DMA channel is odd + \param[out] none + \retval none +*/ +void spi_transmit_odd_config(uint32_t spi_periph, uint16_t odd) +{ + /* clear SPI_CTL1_TXDMA_ODD bit */ + SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_TXDMA_ODD); + /* confige SPI_CTL1_TXDMA_ODD bit */ + SPI_CTL1(spi_periph) |= (uint32_t)odd; +} + +/*! + \brief configure SPI1 total number of data to receive by DMA is odd or not + \param[in] spi_periph: SPIx(x=1) + \param[in] odd: odd bytes in RX DMA channel + only one parameter can be selected which is shown as below: + \arg SPI_RXDMA_EVEN: number of bytes in RX DMA channel is even + \arg SPI_RXDMA_ODD: number of bytes in RX DMA channel is odd + \param[out] none + \retval none +*/ +void spi_receive_odd_config(uint32_t spi_periph, uint16_t odd) +{ + /* clear SPI_CTL1_RXDMA_ODD bit */ + SPI_CTL1(spi_periph) &= (uint32_t)(~SPI_CTL1_RXDMA_ODD); + /* confige SPI_CTL1_RXDMA_ODD bit */ + SPI_CTL1(spi_periph) |= (uint32_t)odd; +} + +/*! + \brief set CRC length + \param[in] spi_periph: SPIx(x=1) + \param[in] crc_length: CRC length + only one parameter can be selected which is shown as below: + \arg SPI_CRC_8BIT: CRC length is 8 bits + \arg SPI_CRC_16BIT: CRC length is 16 bits + \param[out] none + \retval none +*/ +void spi_crc_length_set(uint32_t spi_periph, uint16_t crc_length) +{ + /* clear SPI_CTL0_CRCL bit */ + SPI_CTL0(spi_periph) &= (uint32_t)(~SPI_CTL0_CRCL); + /* confige SPI_CTL0_CRCL bit */ + SPI_CTL0(spi_periph) |= (uint32_t)crc_length; +} diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_syscfg.c b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_syscfg.c new file mode 100644 index 0000000000000000000000000000000000000000..a0e79e417648a9305c21ea098360322914d0bcf6 --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_syscfg.c @@ -0,0 +1,207 @@ + /*! + \file gd32e230_syscfg.h + \brief SYSCFG driver + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor 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 copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 "gd32e230_syscfg.h" + +/*! + \brief reset the SYSCFG registers + \param[in] none + \param[out] none + \retval none +*/ +void syscfg_deinit(void) +{ + rcu_periph_reset_enable(RCU_CFGCMPRST); + rcu_periph_reset_disable(RCU_CFGCMPRST); +} + +/*! + \brief enable the DMA channels remapping + \param[in] syscfg_dma_remap: specify the DMA channels to remap + \arg SYSCFG_DMA_REMAP_TIMER16: remap TIMER16 channel0 and UP DMA requests to channel1(defaut channel0) + \arg SYSCFG_DMA_REMAP_TIMER15: remap TIMER15 channel2 and UP DMA requests to channel3(defaut channel2) + \arg SYSCFG_DMA_REMAP_USART0RX: remap USART0 Rx DMA request to channel4(default channel2) + \arg SYSCFG_DMA_REMAP_USART0TX: remap USART0 Tx DMA request to channel3(default channel1) + \arg SYSCFG_DMA_REMAP_ADC: remap ADC DMA requests from channel0 to channel1 + \arg SYSCFG_PA11_REMAP_PA12: remap PA11 PA12 + \param[out] none + \retval none +*/ +void syscfg_dma_remap_enable(uint32_t syscfg_dma_remap) +{ + SYSCFG_CFG0 |= syscfg_dma_remap; +} + +/*! + \brief disable the DMA channels remapping + \param[in] syscfg_dma_remap: specify the DMA channels to remap + \arg SYSCFG_DMA_REMAP_TIMER16: remap TIMER16 channel0 and UP DMA requests to channel1(defaut channel0) + \arg SYSCFG_DMA_REMAP_TIMER15: remap TIMER15 channel2 and UP DMA requests to channel3(defaut channel2) + \arg SYSCFG_DMA_REMAP_USART0RX: remap USART0 Rx DMA request to channel4(default channel2) + \arg SYSCFG_DMA_REMAP_USART0TX: remap USART0 Tx DMA request to channel3(default channel1) + \arg SYSCFG_DMA_REMAP_ADC: remap ADC DMA requests from channel0 to channel1 + \arg SYSCFG_PA11_REMAP_PA12: remap PA11 PA12 + \param[out] none + \retval none +*/ +void syscfg_dma_remap_disable(uint32_t syscfg_dma_remap) +{ + SYSCFG_CFG0 &= ~syscfg_dma_remap; +} + +/*! + \brief enable PB9 high current capability + \param[in] none + \param[out] none + \retval none +*/ +void syscfg_high_current_enable(void) +{ + SYSCFG_CFG0 |= SYSCFG_HIGH_CURRENT_ENABLE; +} + +/*! + \brief disable PB9 high current capability + \param[in] none + \param[out] none + \retval none +*/ +void syscfg_high_current_disable(void) +{ + SYSCFG_CFG0 &= SYSCFG_HIGH_CURRENT_DISABLE; +} + +/*! + \brief configure the GPIO pin as EXTI Line + \param[in] exti_port: specify the GPIO port used in EXTI + \arg EXTI_SOURCE_GPIOx(x = A,B,C,F): EXTI GPIO port + \param[in] exti_pin: specify the EXTI line + \arg EXTI_SOURCE_PINx(GPIOA x = 0..15,GPIOB x = 0..15,GPIOC x = 13..15,GPIOF x = 0.1.6.7): EXTI GPIO pin + \param[out] none + \retval none +*/ +void syscfg_exti_line_config(uint8_t exti_port, uint8_t exti_pin) +{ + uint32_t clear_exti_mask = ~((uint32_t)EXTI_SS_MASK << (EXTI_SS_MSTEP(exti_pin))); + uint32_t config_exti_mask = ((uint32_t)exti_port) << (EXTI_SS_MSTEP(exti_pin)); + + switch(exti_pin / EXTI_SS_JSTEP){ + case EXTISS0: + /* clear EXTI source line(0..3) */ + SYSCFG_EXTISS0 &= clear_exti_mask; + /* configure EXTI soure line(0..3) */ + SYSCFG_EXTISS0 |= config_exti_mask; + break; + case EXTISS1: + /* clear EXTI soure line(4..7) */ + SYSCFG_EXTISS1 &= clear_exti_mask; + /* configure EXTI soure line(4..7) */ + SYSCFG_EXTISS1 |= config_exti_mask; + break; + case EXTISS2: + /* clear EXTI soure line(8..11) */ + SYSCFG_EXTISS2 &= clear_exti_mask; + /* configure EXTI soure line(8..11) */ + SYSCFG_EXTISS2 |= config_exti_mask; + break; + case EXTISS3: + /* clear EXTI soure line(12..15) */ + SYSCFG_EXTISS3 &= clear_exti_mask; + /* configure EXTI soure line(12..15) */ + SYSCFG_EXTISS3 |= config_exti_mask; + break; + default: + break; + } +} + +/*! + \brief connect TIMER0/14/15/16 break input to the selected parameter + \param[in] syscfg_lock: Specify the parameter to be connected + \arg SYSCFG_LOCK_LOCKUP: Cortex-M23 lockup output connected to the break input + \arg SYSCFG_LOCK_SRAM_PARITY_ERROR: SRAM_PARITY check error connected to the break input + \arg SYSCFG_LOCK_LVD: LVD interrupt connected to the break input + \param[out] none + \retval none +*/ +void syscfg_lock_config(uint32_t syscfg_lock) +{ + SYSCFG_CFG2 |= syscfg_lock; +} + +/*! + \brief set the wait state counter value + \param[in] irq_latency: IRQ_LATENCY value (0x00 - 0xFF) + \param[out] none + \retval none +*/ +void irq_latency_set(uint8_t irq_latency) +{ + uint32_t reg; + + reg = SYSCFG_CPU_IRQ_LAT &(~(uint32_t)SYSCFG_CPU_IRQ_LAT_IRQ_LATENCY); + reg |= (uint32_t)(IRQ_LATENCY(irq_latency)); + + SYSCFG_CPU_IRQ_LAT = (uint32_t)reg; +} +/*! + \brief check if the specified flag in SYSCFG_CFG2 is set or not. + \param[in] syscfg_flag: specify the flag in SYSCFG_CFG2 to check. + \arg SYSCFG_SRAM_PCEF: SRAM parity check error flag. + \param[out] none + \retval the syscfg_flag state returned (SET or RESET). + */ +FlagStatus syscfg_flag_get(uint32_t syscfg_flag) +{ + if((SYSCFG_CFG2 & syscfg_flag) != (uint32_t)RESET){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear the flag in SYSCFG_CFG2 by writing 1. + \param[in] syscfg_flag: Specify the flag in SYSCFG_CFG2 to clear. + \arg SYSCFG_SRAM_PCEF: SRAM parity check error flag. + \param[out] none + \retval none +*/ +void syscfg_flag_clear(uint32_t syscfg_flag) +{ + SYSCFG_CFG2 |= (uint32_t) syscfg_flag; +} + diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_timer.c b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_timer.c new file mode 100644 index 0000000000000000000000000000000000000000..3fce2c47f8d474f2632e77c8ef9e625ac8001ff3 --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_timer.c @@ -0,0 +1,2059 @@ +/*! + \file gd32e230_timer.c + \brief TIMER driver + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor 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 copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 "gd32e230_timer.h" + +/* TIMER init parameter mask */ +#define ALIGNEDMODE_MASK ((uint32_t)0x00000060U) /*!< TIMER init parameter aligne dmode mask */ +#define COUNTERDIRECTION_MASK ((uint32_t)0x00000010U) /*!< TIMER init parameter counter direction mask */ +#define CLOCKDIVISION_MASK ((uint32_t)0x00000300U) /*!< TIMER init parameter clock division value mask */ + +/*! + \brief deinit a TIMER + \param[in] timer_periph: TIMERx(x=0,2,5,13..16) + \param[out] none + \retval none +*/ +void timer_deinit(uint32_t timer_periph) +{ + switch(timer_periph){ + case TIMER0: + /* reset TIMER0 */ + rcu_periph_reset_enable(RCU_TIMER0RST); + rcu_periph_reset_disable(RCU_TIMER0RST); + break; + case TIMER2: + /* reset TIMER2 */ + rcu_periph_reset_enable(RCU_TIMER2RST); + rcu_periph_reset_disable(RCU_TIMER2RST); + break; + case TIMER5: + /* reset TIMER5 */ + rcu_periph_reset_enable(RCU_TIMER5RST); + rcu_periph_reset_disable(RCU_TIMER5RST); + break; + case TIMER13: + /* reset TIMER13 */ + rcu_periph_reset_enable(RCU_TIMER13RST); + rcu_periph_reset_disable(RCU_TIMER13RST); + break; + case TIMER14: + /* reset TIMER14 */ + rcu_periph_reset_enable(RCU_TIMER14RST); + rcu_periph_reset_disable(RCU_TIMER14RST); + break; + case TIMER15: + /* reset TIMER15 */ + rcu_periph_reset_enable(RCU_TIMER15RST); + rcu_periph_reset_disable(RCU_TIMER15RST); + break; + case TIMER16: + /* reset TIMER16 */ + rcu_periph_reset_enable(RCU_TIMER16RST); + rcu_periph_reset_disable(RCU_TIMER16RST); + break; + default: + break; + } +} + +/*! + \brief initialize TIMER init parameter struct with a default value + \param[in] initpara: init parameter struct + \param[out] none + \retval none +*/ +void timer_struct_para_init(timer_parameter_struct* initpara) +{ + /* initialize the init parameter struct member with the default value */ + initpara->prescaler = 0U; + initpara->alignedmode = TIMER_COUNTER_EDGE; + initpara->counterdirection = TIMER_COUNTER_UP; + initpara->period = 65535U; + initpara->clockdivision = TIMER_CKDIV_DIV1; + initpara->repetitioncounter = 0U; +} + +/*! + \brief initialize TIMER counter + \param[in] timer_periph: TIMERx(x=0,2,5,13..16) + \param[in] initpara: init parameter struct + prescaler: prescaler value of the counter clock, 0~65535 + alignedmode: TIMER_COUNTER_EDGE, TIMER_COUNTER_CENTER_DOWN, TIMER_COUNTER_CENTER_UP, TIMER_COUNTER_CENTER_BOTH + counterdirection: TIMER_COUNTER_UP, TIMER_COUNTER_DOWN + period: counter auto reload value, 0~65535 + clockdivision: TIMER_CKDIV_DIV1, TIMER_CKDIV_DIV2, TIMER_CKDIV_DIV4 + repetitioncounter: counter repetition value, 0~255 + \param[out] none + \retval none +*/ +void timer_init(uint32_t timer_periph, timer_parameter_struct* initpara) +{ + /* configure the counter prescaler value */ + TIMER_PSC(timer_periph) = (uint16_t)initpara->prescaler; + + /* configure the counter direction and aligned mode */ + if((TIMER0 == timer_periph) || (TIMER2 == timer_periph)){ + TIMER_CTL0(timer_periph) &= ~(uint32_t)(TIMER_CTL0_DIR|TIMER_CTL0_CAM); + TIMER_CTL0(timer_periph) |= (uint32_t)initpara->alignedmode; + TIMER_CTL0(timer_periph) |= (uint32_t)initpara->counterdirection; + } + + /* configure the autoreload value */ + TIMER_CAR(timer_periph) = (uint32_t)initpara->period; + + if((TIMER0 == timer_periph) || (TIMER2 == timer_periph) || (TIMER13 == timer_periph) + || (TIMER14 == timer_periph) || (TIMER15 == timer_periph) || (TIMER16 == timer_periph)){ + /* reset the CKDIV bit */ + TIMER_CTL0(timer_periph) &= ~(uint32_t)TIMER_CTL0_CKDIV; + TIMER_CTL0(timer_periph) |= (uint32_t)initpara->clockdivision; + } + + if((TIMER0 == timer_periph) || (TIMER14 == timer_periph) || (TIMER15 == timer_periph) || (TIMER16 == timer_periph)){ + /* configure the repetition counter value */ + TIMER_CREP(timer_periph) = (uint32_t)initpara->repetitioncounter; + } + + /* generate an update event */ + TIMER_SWEVG(timer_periph) |= (uint32_t)TIMER_SWEVG_UPG; +} + +/*! + \brief enable a TIMER + \param[in] timer_periph: TIMERx(x=0,2,5,13..16) + \param[out] none + \retval none +*/ +void timer_enable(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) |= (uint32_t)TIMER_CTL0_CEN; +} + +/*! + \brief disable a TIMER + \param[in] timer_periph: TIMERx(x=0,2,5,13..16) + \param[out] none + \retval none +*/ +void timer_disable(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) &= ~(uint32_t)TIMER_CTL0_CEN; +} + +/*! + \brief enable the auto reload shadow function + \param[in] timer_periph: TIMERx(x=0,2,5,13..16) + \param[out] none + \retval none +*/ +void timer_auto_reload_shadow_enable(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) |= (uint32_t)TIMER_CTL0_ARSE; +} + +/*! + \brief disable the auto reload shadow function + \param[in] timer_periph: TIMERx(x=0,2,5,13..16) + \param[out] none + \retval none +*/ +void timer_auto_reload_shadow_disable(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) &= ~(uint32_t)TIMER_CTL0_ARSE; +} + +/*! + \brief enable the update event + \param[in] timer_periph: TIMERx(x=0,2,5,13..16) + \param[out] none + \retval none +*/ +void timer_update_event_enable(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) &= ~(uint32_t)TIMER_CTL0_UPDIS; +} + +/*! + \brief disable the update event + \param[in] timer_periph: TIMERx(x=0,2,5,13..16) + \param[out] none + \retval none +*/ +void timer_update_event_disable(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) |= (uint32_t) TIMER_CTL0_UPDIS; +} + +/*! + \brief set TIMER counter alignment mode + \param[in] timer_periph: TIMERx(x=0,2) + \param[in] aligned: + only one parameter can be selected which is shown as below: + \arg TIMER_COUNTER_EDGE: edge-aligned mode + \arg TIMER_COUNTER_CENTER_DOWN: center-aligned and counting down assert mode + \arg TIMER_COUNTER_CENTER_UP: center-aligned and counting up assert mode + \arg TIMER_COUNTER_CENTER_BOTH: center-aligned and counting up/down assert mode + \param[out] none + \retval none +*/ +void timer_counter_alignment(uint32_t timer_periph, uint16_t aligned) +{ + TIMER_CTL0(timer_periph) &= ~(uint32_t)TIMER_CTL0_CAM; + TIMER_CTL0(timer_periph) |= (uint32_t)aligned; +} + +/*! + \brief set TIMER counter up direction + \param[in] timer_periph: TIMERx(x=0,2) + \param[out] none + \retval none +*/ +void timer_counter_up_direction(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) &= ~(uint32_t)TIMER_CTL0_DIR; +} + +/*! + \brief set TIMER counter down direction + \param[in] timer_periph: TIMERx(x=0,2) + \param[out] none + \retval none +*/ +void timer_counter_down_direction(uint32_t timer_periph) +{ + TIMER_CTL0(timer_periph) |= (uint32_t)TIMER_CTL0_DIR; +} + +/*! + \brief configure TIMER prescaler + \param[in] timer_periph: TIMERx(x=0,2,5,13..16) + \param[in] prescaler: prescaler value,0~65535 + \param[in] pscreload: prescaler reload mode + only one parameter can be selected which is shown as below: + \arg TIMER_PSC_RELOAD_NOW: the prescaler is loaded right now + \arg TIMER_PSC_RELOAD_UPDATE: the prescaler is loaded at the next update event + \param[out] none + \retval none +*/ +void timer_prescaler_config(uint32_t timer_periph, uint16_t prescaler, uint8_t pscreload) +{ + TIMER_PSC(timer_periph) = (uint32_t)prescaler; + + if(TIMER_PSC_RELOAD_NOW == pscreload){ + TIMER_SWEVG(timer_periph) |= (uint32_t)TIMER_SWEVG_UPG; + } +} + +/*! + \brief configure TIMER repetition register value + \param[in] timer_periph: TIMERx(x=0,15,16) + \param[in] repetition: the counter repetition value,0~255 + \param[out] none + \retval none +*/ +void timer_repetition_value_config(uint32_t timer_periph, uint16_t repetition) +{ + TIMER_CREP(timer_periph) = (uint32_t)repetition; +} + +/*! + \brief configure TIMER autoreload register value + \param[in] timer_periph: TIMERx(x=0,2,5,13..16) + \param[in] autoreload: the counter auto-reload value,0~65535 + \param[out] none + \retval none +*/ +void timer_autoreload_value_config(uint32_t timer_periph, uint16_t autoreload) +{ + TIMER_CAR(timer_periph) = (uint32_t)autoreload; +} + +/*! + \brief configure TIMER counter register value + \param[in] timer_periph: TIMERx(x=0,2,5,13..16) + \param[in] counter: the counter value,0~65535 + \param[out] none + \retval none +*/ +void timer_counter_value_config(uint32_t timer_periph, uint16_t counter) +{ + TIMER_CNT(timer_periph) = (uint32_t)counter; +} + +/*! + \brief read TIMER counter value + \param[in] timer_periph: TIMERx(x=0,2,5,13..16) + \param[out] none + \retval counter value +*/ +uint32_t timer_counter_read(uint32_t timer_periph) +{ + uint32_t count_value = 0U; + count_value = TIMER_CNT(timer_periph); + return (count_value); +} + +/*! + \brief read TIMER prescaler value + \param[in] timer_periph: TIMERx(x=0,2,5,13..16) + \param[out] none + \retval prescaler register value +*/ +uint16_t timer_prescaler_read(uint32_t timer_periph) +{ + uint16_t prescaler_value = 0U; + prescaler_value = (uint16_t)(TIMER_PSC(timer_periph)); + return (prescaler_value); +} + +/*! + \brief configure TIMER single pulse mode + \param[in] timer_periph: TIMERx(x=0,2,5,14..16) + \param[in] spmode: + only one parameter can be selected which is shown as below: + \arg TIMER_SP_MODE_SINGLE: single pulse mode + \arg TIMER_SP_MODE_REPETITIVE: repetitive pulse mode + \param[out] none + \retval none +*/ +void timer_single_pulse_mode_config(uint32_t timer_periph, uint32_t spmode) +{ + if(TIMER_SP_MODE_SINGLE == spmode){ + TIMER_CTL0(timer_periph) |= (uint32_t)TIMER_CTL0_SPM; + }else if(TIMER_SP_MODE_REPETITIVE == spmode){ + TIMER_CTL0(timer_periph) &= ~((uint32_t)TIMER_CTL0_SPM); + }else{ + /* illegal parameters */ + } +} + +/*! + \brief configure TIMER update source + \param[in] timer_periph: TIMERx(x=0,2,5,13..16) + \param[in] update: + only one parameter can be selected which is shown as below: + \arg TIMER_UPDATE_SRC_GLOBAL: update generate by setting of UPG bit or the counter overflow/underflow,or the slave mode controller trigger + \arg TIMER_UPDATE_SRC_REGULAR: update generate only by counter overflow/underflow + \param[out] none + \retval none +*/ +void timer_update_source_config(uint32_t timer_periph, uint32_t update) +{ + if(TIMER_UPDATE_SRC_REGULAR == update){ + TIMER_CTL0(timer_periph) |= (uint32_t)TIMER_CTL0_UPS; + }else if(TIMER_UPDATE_SRC_GLOBAL == update){ + TIMER_CTL0(timer_periph) &= ~(uint32_t)TIMER_CTL0_UPS; + }else{ + /* illegal parameters */ + } +} + +/*! + \brief configure TIMER OCPRE clear source selection + \param[in] timer_periph: TIMERx(x=0,2) + \param[in] ocpreclear: + only one parameter can be selected which is shown as below: + \arg TIMER_OCPRE_CLEAR_SOURCE_CLR: OCPRE_CLR_INT is connected to the OCPRE_CLR input + \arg TIMER_OCPRE_CLEAR_SOURCE_ETIF: OCPRE_CLR_INT is connected to ETIF + \param[out] none + \retval none +*/ +void timer_ocpre_clear_source_config(uint32_t timer_periph, uint8_t ocpreclear) +{ + if(TIMER_OCPRE_CLEAR_SOURCE_ETIF == ocpreclear){ + TIMER_SMCFG(timer_periph) |= (uint32_t)TIMER_SMCFG_OCRC; + }else if(TIMER_OCPRE_CLEAR_SOURCE_CLR == ocpreclear){ + TIMER_SMCFG(timer_periph) &= ~(uint32_t)TIMER_SMCFG_OCRC; + }else{ + /* illegal parameters */ + } +} + +/*! + \brief enable the TIMER interrupt + \param[in] timer_periph: please refer to the following parameters + \param[in] interrupt: timer interrupt enable source + only one parameter can be selected which is shown as below: + \arg TIMER_INT_UP: update interrupt enable, TIMERx(x=0,2,5,13..16) + \arg TIMER_INT_CH0: channel 0 interrupt enable, TIMERx(x=0,2,13..16) + \arg TIMER_INT_CH1: channel 1 interrupt enable, TIMERx(x=0,2,14) + \arg TIMER_INT_CH2: channel 2 interrupt enable, TIMERx(x=0,2) + \arg TIMER_INT_CH3: channel 3 interrupt enable , TIMERx(x=0,2) + \arg TIMER_INT_CMT: commutation interrupt enable, TIMERx(x=0,14..16) + \arg TIMER_INT_TRG: trigger interrupt enable, TIMERx(x=0,2,14) + \arg TIMER_INT_BRK: break interrupt enable, TIMERx(x=0,14..16) + \param[out] none + \retval none +*/ +void timer_interrupt_enable(uint32_t timer_periph, uint32_t interrupt) +{ + TIMER_DMAINTEN(timer_periph) |= (uint32_t) interrupt; +} + +/*! + \brief disable the TIMER interrupt + \param[in] timer_periph: please refer to the following parameters + \param[in] interrupt: timer interrupt source disable + only one parameter can be selected which is shown as below: + \arg TIMER_INT_UP: update interrupt enable, TIMERx(x=0,2,5,13..16) + \arg TIMER_INT_CH0: channel 0 interrupt enable, TIMERx(x=0,2,13..16) + \arg TIMER_INT_CH1: channel 1 interrupt enable, TIMERx(x=0,2,14) + \arg TIMER_INT_CH2: channel 2 interrupt enable, TIMERx(x=0,2) + \arg TIMER_INT_CH3: channel 3 interrupt enable , TIMERx(x=0,2) + \arg TIMER_INT_CMT: commutation interrupt enable, TIMERx(x=0,14..16) + \arg TIMER_INT_TRG: trigger interrupt enable, TIMERx(x=0,2,14) + \arg TIMER_INT_BRK: break interrupt enable, TIMERx(x=0,14..16) + \param[out] none + \retval none +*/ +void timer_interrupt_disable(uint32_t timer_periph, uint32_t interrupt) +{ + TIMER_DMAINTEN(timer_periph) &= (~(uint32_t)interrupt); +} + +/*! + \brief get timer interrupt flag + \param[in] timer_periph: please refer to the following parameters + \param[in] interrupt: the timer interrupt bits + only one parameter can be selected which is shown as below: + \arg TIMER_INT_FLAG_UP: update interrupt flag,TIMERx(x=0,2,5,13..16) + \arg TIMER_INT_FLAG_CH0: channel 0 interrupt flag,TIMERx(x=0,2,13..16) + \arg TIMER_INT_FLAG_CH1: channel 1 interrupt flag,TIMERx(x=0,2,14) + \arg TIMER_INT_FLAG_CH2: channel 2 interrupt flag,TIMERx(x=0,2) + \arg TIMER_INT_FLAG_CH3: channel 3 interrupt flag,TIMERx(x=0,2) + \arg TIMER_INT_FLAG_CMT: channel commutation interrupt flag,TIMERx(x=0,14..16) + \arg TIMER_INT_FLAG_TRG: trigger interrupt flag,TIMERx(x=0,2,14) + \arg TIMER_INT_FLAG_BRK: break interrupt flag,TIMERx(x=0,14..16) + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus timer_interrupt_flag_get(uint32_t timer_periph, uint32_t interrupt) +{ + uint32_t val; + val = (TIMER_DMAINTEN(timer_periph) & interrupt); + if((RESET != (TIMER_INTF(timer_periph) & interrupt) ) && (RESET != val)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear TIMER interrupt flag + \param[in] timer_periph: please refer to the following parameters + \param[in] interrupt: the timer interrupt bits + only one parameter can be selected which is shown as below: + \arg TIMER_INT_FLAG_UP: update interrupt flag, TIMERx(x=0,2,5,13..16) + \arg TIMER_INT_FLAG_CH0: channel 0 interrupt flag, TIMERx(x=0,2,13..16) + \arg TIMER_INT_FLAG_CH1: channel 1 interrupt flag, TIMERx(x=0,2,14) + \arg TIMER_INT_FLAG_CH2: channel 2 interrupt flag, TIMERx(x=0,2) + \arg TIMER_INT_FLAG_CH3: channel 3 interrupt flag, TIMERx(x=0,2) + \arg TIMER_INT_FLAG_CMT: channel commutation interrupt flag, TIMERx(x=0,14..16) + \arg TIMER_INT_FLAG_TRG: trigger interrupt flag, TIMERx(x=0,2,14) + \arg TIMER_INT_FLAG_BRK: break interrupt flag, TIMERx(x=0,14..16) + \param[out] none + \retval none +*/ +void timer_interrupt_flag_clear(uint32_t timer_periph, uint32_t interrupt) +{ + TIMER_INTF(timer_periph) &= (~(uint32_t)interrupt); +} + +/*! + \brief get TIMER flags + \param[in] timer_periph: please refer to the following parameters + \param[in] flag: the timer interrupt flags + only one parameter can be selected which is shown as below: + \arg TIMER_FLAG_UP: update flag, TIMERx(x=0,2,5,13..16) + \arg TIMER_FLAG_CH0: channel 0 flag, TIMERx(x=0,2,13..16) + \arg TIMER_FLAG_CH1: channel 1 flag, TIMERx(x=0,2,14) + \arg TIMER_FLAG_CH2: channel 2 flag, TIMERx(x=0,2) + \arg TIMER_FLAG_CH3: channel 3 flag, TIMERx(x=0,2) + \arg TIMER_FLAG_CMT: channel control update flag, TIMERx(x=0,14..16) + \arg TIMER_FLAG_TRG: trigger flag, TIMERx(x=0,2,14) + \arg TIMER_FLAG_BRK: break flag,TIMERx(x=0,14..16) + \arg TIMER_FLAG_CH0O: channel 0 overcapture flag, TIMERx(x=0,2,13..16) + \arg TIMER_FLAG_CH1O: channel 1 overcapture flag, TIMERx(x=0,2,14) + \arg TIMER_FLAG_CH2O: channel 2 overcapture flag, TIMERx(x=0,2) + \arg TIMER_FLAG_CH3O: channel 3 overcapture flag, TIMERx(x=0,2) + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus timer_flag_get(uint32_t timer_periph, uint32_t flag) +{ + if(RESET != (TIMER_INTF(timer_periph) & flag)){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear TIMER flags + \param[in] timer_periph: please refer to the following parameters + \param[in] flag: the timer interrupt flags + only one parameter can be selected which is shown as below: + \arg TIMER_FLAG_UP: update flag, TIMERx(x=0,2,5,13..16) + \arg TIMER_FLAG_CH0: channel 0 flag, TIMERx(x=0,2,13..16) + \arg TIMER_FLAG_CH1: channel 1 flag, TIMERx(x=0,2,14) + \arg TIMER_FLAG_CH2: channel 2 flag, TIMERx(x=0,2) + \arg TIMER_FLAG_CH3: channel 3 flag, TIMERx(x=0,2) + \arg TIMER_FLAG_CMT: channel control update flag, TIMERx(x=0,14..16) + \arg TIMER_FLAG_TRG: trigger flag, TIMERx(x=0,2,14) + \arg TIMER_FLAG_BRK: break flag,TIMERx(x=0,14..16) + \arg TIMER_FLAG_CH0O: channel 0 overcapture flag, TIMERx(x=0,2,13..16) + \arg TIMER_FLAG_CH1O: channel 1 overcapture flag, TIMERx(x=0,2,14) + \arg TIMER_FLAG_CH2O: channel 2 overcapture flag, TIMERx(x=0,2) + \arg TIMER_FLAG_CH3O: channel 3 overcapture flag, TIMERx(x=0,2) + \param[out] none + \retval none +*/ +void timer_flag_clear(uint32_t timer_periph, uint32_t flag) +{ + TIMER_INTF(timer_periph) &= (~(uint32_t)flag); +} + +/*! + \brief enable the TIMER DMA + \param[in] timer_periph: please refer to the following parameters + \param[in] dma: specify which DMA to enable + one or more parameters can be selected which is shown as below: + \arg TIMER_DMA_UPD: update DMA, TIMERx(x=0,2,5,14..16) + \arg TIMER_DMA_CH0D: channel 0 DMA request, TIMERx(x=0,2,14..16) + \arg TIMER_DMA_CH1D: channel 1 DMA request, TIMERx(x=0,2,14) + \arg TIMER_DMA_CH2D: channel 2 DMA request, TIMERx(x=0,2) + \arg TIMER_DMA_CH3D: channel 3 DMA request, TIMERx(x=0,2) + \arg TIMER_DMA_CMTD: commutation DMA request, TIMERx(x=0,14) + \arg TIMER_DMA_TRGD: trigger DMA request, TIMERx(x=0,2,14) + \param[out] none + \retval none +*/ +void timer_dma_enable(uint32_t timer_periph, uint16_t dma) +{ + TIMER_DMAINTEN(timer_periph) |= (uint32_t) dma; +} + +/*! + \brief disable the TIMER DMA + \param[in] timer_periph: please refer to the following parameters + \param[in] dma: specify which DMA to disable + one or more parameters can be selected which are shown as below: + \arg TIMER_DMA_UPD: update DMA, TIMERx(x=0,2,5,14..16) + \arg TIMER_DMA_CH0D: channel 0 DMA request, TIMERx(x=0,2,14..16) + \arg TIMER_DMA_CH1D: channel 1 DMA request, TIMERx(x=0,2,14) + \arg TIMER_DMA_CH2D: channel 2 DMA request, TIMERx(x=0,2) + \arg TIMER_DMA_CH3D: channel 3 DMA request, TIMERx(x=0,2) + \arg TIMER_DMA_CMTD: commutation DMA request , TIMERx(x=0,14) + \arg TIMER_DMA_TRGD: trigger DMA request, TIMERx(x=0,2,14) + \param[out] none + \retval none +*/ +void timer_dma_disable(uint32_t timer_periph, uint16_t dma) +{ + TIMER_DMAINTEN(timer_periph) &= (~(uint32_t)(dma)); +} + +/*! + \brief channel DMA request source selection + \param[in] timer_periph: TIMERx(x=0,2,14..16) + \param[in] dma_request: channel DMA request source selection + only one parameter can be selected which is shown as below: + \arg TIMER_DMAREQUEST_CHANNELEVENT: DMA request of channel y is sent when channel y event occurs + \arg TIMER_DMAREQUEST_UPDATEEVENT: DMA request of channel y is sent when update event occurs + \param[out] none + \retval none +*/ +void timer_channel_dma_request_source_select(uint32_t timer_periph, uint8_t dma_request) +{ + if(TIMER_DMAREQUEST_UPDATEEVENT == dma_request){ + TIMER_CTL1(timer_periph) |= (uint32_t)TIMER_CTL1_DMAS; + }else if(TIMER_DMAREQUEST_CHANNELEVENT == dma_request){ + TIMER_CTL1(timer_periph) &= ~(uint32_t)TIMER_CTL1_DMAS; + }else{ + /* illegal parameters */ + } +} + +/*! + \brief configure the TIMER DMA transfer + \param[in] timer_periph: TIMERx(x=0,2,14..16) + \param[in] dma_baseaddr: + only one parameter can be selected which is shown as below: + \arg TIMER_DMACFG_DMATA_CTL0: DMA transfer address is TIMER_CTL0, TIMERx(x=0,2,14..16) + \arg TIMER_DMACFG_DMATA_CTL1: DMA transfer address is TIMER_CTL1, TIMERx(x=0,2,14..16) + \arg TIMER_DMACFG_DMATA_SMCFG: DMA transfer address is TIMER_SMCFG, TIMERx(x=0,2,14) + \arg TIMER_DMACFG_DMATA_DMAINTEN: DMA transfer address is TIMER_DMAINTEN, TIMERx(x=0,2,14..16) + \arg TIMER_DMACFG_DMATA_INTF: DMA transfer address is TIMER_INTF, TIMERx(x=0,2,14..16) + \arg TIMER_DMACFG_DMATA_SWEVG: DMA transfer address is TIMER_SWEVG, TIMERx(x=0,2,14..16) + \arg TIMER_DMACFG_DMATA_CHCTL0: DMA transfer address is TIMER_CHCTL0, TIMERx(x=0,2,14..16) + \arg TIMER_DMACFG_DMATA_CHCTL1: DMA transfer address is TIMER_CHCTL1, TIMERx(x=0,2) + \arg TIMER_DMACFG_DMATA_CHCTL2: DMA transfer address is TIMER_CHCTL2, TIMERx(x=0,2,14..16) + \arg TIMER_DMACFG_DMATA_CNT: DMA transfer address is TIMER_CNT, TIMERx(x=0,2,14..16) + \arg TIMER_DMACFG_DMATA_PSC: DMA transfer address is TIMER_PSC, TIMERx(x=0,2,14..16) + \arg TIMER_DMACFG_DMATA_CAR: DMA transfer address is TIMER_CAR, TIMERx(x=0,2,14..16) + \arg TIMER_DMACFG_DMATA_CREP: DMA transfer address is TIMER_CREP, TIMERx(x=0,14..16) + \arg TIMER_DMACFG_DMATA_CH0CV: DMA transfer address is TIMER_CH0CV, TIMERx(x=0,2,14..16) + \arg TIMER_DMACFG_DMATA_CH1CV: DMA transfer address is TIMER_CH1CV, TIMERx(x=0,2,14) + \arg TIMER_DMACFG_DMATA_CH2CV: DMA transfer address is TIMER_CH2CV, TIMERx(x=0,2) + \arg TIMER_DMACFG_DMATA_CH3CV: DMA transfer address is TIMER_CH3CV, TIMERx(x=0,2) + \arg TIMER_DMACFG_DMATA_CCHP: DMA transfer address is TIMER_CCHP, TIMERx(x=0,14..16) + \arg TIMER_DMACFG_DMATA_DMACFG: DMA transfer address is TIMER_DMACFG, TIMERx(x=0,2,14..16) + \param[in] dma_lenth: + only one parameter can be selected which is shown as below: + \arg TIMER_DMACFG_DMATC_xTRANSFER(x=1..18): DMA transfer x time + \param[out] none + \retval none +*/ +void timer_dma_transfer_config(uint32_t timer_periph, uint32_t dma_baseaddr, uint32_t dma_lenth) +{ + TIMER_DMACFG(timer_periph) &= (~(uint32_t)(TIMER_DMACFG_DMATA | TIMER_DMACFG_DMATC)); + TIMER_DMACFG(timer_periph) |= (uint32_t)(dma_baseaddr | dma_lenth); +} + +/*! + \brief software generate events + \param[in] timer_periph: please refer to the following parameters + \param[in] event: the timer software event generation sources + one or more parameters can be selected which are shown as below: + \arg TIMER_EVENT_SRC_UPG: update event,TIMERx(x=0,2,5,13..16) + \arg TIMER_EVENT_SRC_CH0G: channel 0 capture or compare event generation, TIMERx(x=0,2,13..16) + \arg TIMER_EVENT_SRC_CH1G: channel 1 capture or compare event generation, TIMERx(x=0,2,14) + \arg TIMER_EVENT_SRC_CH2G: channel 2 capture or compare event generation, TIMERx(x=0,2) + \arg TIMER_EVENT_SRC_CH3G: channel 3 capture or compare event generation, TIMERx(x=0,2) + \arg TIMER_EVENT_SRC_CMTG: channel commutation event generation, TIMERx(x=0,14..16) + \arg TIMER_EVENT_SRC_TRGG: trigger event generation, TIMERx(x=0,2,14) + \arg TIMER_EVENT_SRC_BRKG: break event generation, TIMERx(x=0,14..16) + \param[out] none + \retval none +*/ +void timer_event_software_generate(uint32_t timer_periph, uint16_t event) +{ + TIMER_SWEVG(timer_periph) |= (uint32_t)event; +} + +/*! + \brief initialize TIMER break parameter struct with a default value + \param[in] breakpara: TIMER break parameter struct + \param[out] none + \retval none +*/ +void timer_break_struct_para_init(timer_break_parameter_struct* breakpara) +{ + /* initialize the break parameter struct member with the default value */ + breakpara->runoffstate = TIMER_ROS_STATE_DISABLE; + breakpara->ideloffstate = TIMER_IOS_STATE_DISABLE; + breakpara->deadtime = 0U; + breakpara->breakpolarity = TIMER_BREAK_POLARITY_LOW; + breakpara->outputautostate = TIMER_OUTAUTO_DISABLE; + breakpara->protectmode = TIMER_CCHP_PROT_OFF; + breakpara->breakstate = TIMER_BREAK_DISABLE; +} + +/*! + \brief configure TIMER break function + \param[in] timer_periph: TIMERx(x=0,14..16) + \param[in] breakpara: TIMER break parameter struct + runoffstate: TIMER_ROS_STATE_ENABLE,TIMER_ROS_STATE_DISABLE + ideloffstate: TIMER_IOS_STATE_ENABLE,TIMER_IOS_STATE_DISABLE + deadtime: 0~255 + breakpolarity: TIMER_BREAK_POLARITY_LOW,TIMER_BREAK_POLARITY_HIGH + outputautostate: TIMER_OUTAUTO_ENABLE,TIMER_OUTAUTO_DISABLE + protectmode: TIMER_CCHP_PROT_OFF,TIMER_CCHP_PROT_0,TIMER_CCHP_PROT_1,TIMER_CCHP_PROT_2 + breakstate: TIMER_BREAK_ENABLE,TIMER_BREAK_DISABLE + \param[out] none + \retval none +*/ +void timer_break_config(uint32_t timer_periph, timer_break_parameter_struct* breakpara) +{ + TIMER_CCHP(timer_periph) = (uint32_t)(((uint32_t)(breakpara->runoffstate))| + ((uint32_t)(breakpara->ideloffstate))| + ((uint32_t)(breakpara->deadtime))| + ((uint32_t)(breakpara->breakpolarity))| + ((uint32_t)(breakpara->outputautostate)) | + ((uint32_t)(breakpara->protectmode))| + ((uint32_t)(breakpara->breakstate))) ; +} + +/*! + \brief enable TIMER break function + \param[in] timer_periph: TIMERx(x=0,14..16) + \param[out] none + \retval none +*/ +void timer_break_enable(uint32_t timer_periph) +{ + TIMER_CCHP(timer_periph) |= (uint32_t)TIMER_CCHP_BRKEN; +} + +/*! + \brief disable TIMER break function + \param[in] timer_periph: TIMERx(x=0,14..16) + \param[out] none + \retval none +*/ +void timer_break_disable(uint32_t timer_periph) +{ + TIMER_CCHP(timer_periph) &= ~(uint32_t)TIMER_CCHP_BRKEN; +} + +/*! + \brief enable TIMER output automatic function + \param[in] timer_periph: TIMERx(x=0,14..16) + \param[out] none + \retval none +*/ +void timer_automatic_output_enable(uint32_t timer_periph) +{ + TIMER_CCHP(timer_periph) |= (uint32_t)TIMER_CCHP_OAEN; +} + +/*! + \brief disable TIMER output automatic function + \param[in] timer_periph: TIMERx(x=0,14..16) + \param[out] none + \retval none +*/ +void timer_automatic_output_disable(uint32_t timer_periph) +{ + TIMER_CCHP(timer_periph) &= ~(uint32_t)TIMER_CCHP_OAEN; +} + +/*! + \brief configure TIMER primary output function + \param[in] timer_periph: TIMERx(x=0,14..16) + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void timer_primary_output_config(uint32_t timer_periph, ControlStatus newvalue) +{ + if(ENABLE == newvalue){ + TIMER_CCHP(timer_periph) |= (uint32_t)TIMER_CCHP_POEN; + }else{ + TIMER_CCHP(timer_periph) &= (~(uint32_t)TIMER_CCHP_POEN); + } +} + +/*! + \brief enable or disable channel capture/compare control shadow register + \param[in] timer_periph: TIMERx(x=0,14..16) + \param[in] newvalue: ENABLE or DISABLE + \param[out] none + \retval none +*/ +void timer_channel_control_shadow_config(uint32_t timer_periph, ControlStatus newvalue) +{ + if(ENABLE == newvalue){ + TIMER_CTL1(timer_periph) |= (uint32_t)TIMER_CTL1_CCSE; + }else{ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_CCSE); + } +} + +/*! + \brief configure TIMER channel control shadow register update control + \param[in] timer_periph: TIMERx(x=0,14..16) + \param[in] ccuctl: channel control shadow register update control + only one parameter can be selected which is shown as below: + \arg TIMER_UPDATECTL_CCU: the shadow registers update by when CMTG bit is set + \arg TIMER_UPDATECTL_CCUTRI: the shadow registers update by when CMTG bit is set or an rising edge of TRGI occurs + \param[out] none + \retval none +*/ +void timer_channel_control_shadow_update_config(uint32_t timer_periph, uint8_t ccuctl) +{ + if(TIMER_UPDATECTL_CCU == ccuctl){ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_CCUC); + }else if(TIMER_UPDATECTL_CCUTRI == ccuctl){ + TIMER_CTL1(timer_periph) |= (uint32_t)TIMER_CTL1_CCUC; + }else{ + /* illegal parameters */ + } +} + +/*! + \brief initialize TIMER channel output parameter struct with a default value + \param[in] ocpara: TIMER channel n output parameter struct + \param[out] none + \retval none +*/ +void timer_channel_output_struct_para_init(timer_oc_parameter_struct* ocpara) +{ + /* initialize the channel output parameter struct member with the default value */ + ocpara->outputstate = (uint16_t)TIMER_CCX_DISABLE; + ocpara->outputnstate = TIMER_CCXN_DISABLE; + ocpara->ocpolarity = TIMER_OC_POLARITY_HIGH; + ocpara->ocnpolarity = TIMER_OCN_POLARITY_HIGH; + ocpara->ocidlestate = TIMER_OC_IDLE_STATE_LOW; + ocpara->ocnidlestate = TIMER_OCN_IDLE_STATE_LOW; +} + +/*! + \brief configure TIMER channel output function + \param[in] timer_periph: please refer to the following parameters + \param[in] channel: + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel 0(TIMERx(x=0,2,13..16)) + \arg TIMER_CH_1: TIMER channel 1(TIMERx(x=0,2,14)) + \arg TIMER_CH_2: TIMER channel 2(TIMERx(x=0,2)) + \arg TIMER_CH_3: TIMER channel 3(TIMERx(x=0,2)) + \param[in] ocpara: TIMER channeln output parameter struct + outputstate: TIMER_CCX_ENABLE,TIMER_CCX_DISABLE + outputnstate: TIMER_CCXN_ENABLE,TIMER_CCXN_DISABLE + ocpolarity: TIMER_OC_POLARITY_HIGH,TIMER_OC_POLARITY_LOW + ocnpolarity: TIMER_OCN_POLARITY_HIGH,TIMER_OCN_POLARITY_LOW + ocidlestate: TIMER_OC_IDLE_STATE_LOW,TIMER_OC_IDLE_STATE_HIGH + ocnidlestate: TIMER_OCN_IDLE_STATE_LOW,TIMER_OCN_IDLE_STATE_HIGH + \param[out] none + \retval none +*/ +void timer_channel_output_config(uint32_t timer_periph, uint16_t channel, timer_oc_parameter_struct* ocpara) +{ + switch(channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + /* reset the CH0EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0EN); + TIMER_CHCTL0(timer_periph) &= ~(uint32_t)TIMER_CHCTL0_CH0MS; + /* set the CH0EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)ocpara->outputstate; + /* reset the CH0P bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0P); + /* set the CH0P bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)ocpara->ocpolarity; + + if((TIMER0 == timer_periph) || (TIMER14 == timer_periph) || (TIMER15 == timer_periph) || (TIMER16 == timer_periph)){ + /* reset the CH0NEN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0NEN); + /* set the CH0NEN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)ocpara->outputnstate; + /* reset the CH0NP bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0NP); + /* set the CH0NP bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)ocpara->ocnpolarity; + /* reset the ISO0 bit */ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO0); + /* set the ISO0 bit */ + TIMER_CTL1(timer_periph) |= (uint32_t)ocpara->ocidlestate; + /* reset the ISO0N bit */ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO0N); + /* set the ISO0N bit */ + TIMER_CTL1(timer_periph) |= (uint32_t)ocpara->ocnidlestate; + } + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + /* reset the CH1EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1EN); + TIMER_CHCTL0(timer_periph) &= ~(uint32_t)TIMER_CHCTL0_CH1MS; + /* set the CH1EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocpara->outputstate << 4U); + /* reset the CH1P bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1P); + /* set the CH1P bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocpolarity) << 4U); + + if(TIMER0 == timer_periph){ + /* reset the CH1NEN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1NEN); + /* set the CH1NEN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(ocpara->outputnstate) << 4U); + /* reset the CH1NP bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1NP); + /* set the CH1NP bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocnpolarity) << 4U); + /* reset the ISO1 bit */ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO1); + /* set the ISO1 bit */ + TIMER_CTL1(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocidlestate) << 2U); + /* reset the ISO1N bit */ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO1N); + /* set the ISO1N bit */ + TIMER_CTL1(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocnidlestate) << 2U); + } + + if(TIMER14 == timer_periph){ + /* reset the ISO1 bit */ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO1); + /* set the ISO1 bit */ + TIMER_CTL1(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocidlestate) << 2U); + } + + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + /* reset the CH2EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2EN); + TIMER_CHCTL1(timer_periph) &= ~(uint32_t)TIMER_CHCTL1_CH2MS; + /* set the CH2EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocpara->outputstate << 8U); + /* reset the CH2P bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2P); + /* set the CH2P bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocpolarity) << 8U); + + if(TIMER0 == timer_periph){ + /* reset the CH2NEN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2NEN); + /* set the CH2NEN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(ocpara->outputnstate) << 8U); + /* reset the CH2NP bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2NP); + /* set the CH2NP bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocnpolarity) << 8U); + /* reset the ISO2 bit */ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO2); + /* set the ISO2 bit */ + TIMER_CTL1(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocidlestate) << 4U); + /* reset the ISO2N bit */ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO2N); + /* set the ISO2N bit */ + TIMER_CTL1(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocnidlestate) << 4U); + } + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + /* reset the CH3EN bit */ + TIMER_CHCTL2(timer_periph) &=(~(uint32_t)TIMER_CHCTL2_CH3EN); + TIMER_CHCTL1(timer_periph) &= ~(uint32_t)TIMER_CHCTL1_CH3MS; + /* set the CH3EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocpara->outputstate << 12U); + /* reset the CH3P bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH3P); + /* set the CH3P bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocpolarity) << 12U); + + if(TIMER0 == timer_periph){ + /* reset the ISO3 bit */ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_ISO3); + /* set the ISO3 bit */ + TIMER_CTL1(timer_periph) |= (uint32_t)((uint32_t)(ocpara->ocidlestate) << 6U); + } + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel output compare mode + \param[in] timer_periph: please refer to the following parameters + \param[in] channel: + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0,2,13..16)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,2,14)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0,2)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0,2)) + \param[in] ocmode: channel output compare mode + only one parameter can be selected which is shown as below: + \arg TIMER_OC_MODE_TIMING: timing mode + \arg TIMER_OC_MODE_ACTIVE: active mode + \arg TIMER_OC_MODE_INACTIVE: inactive mode + \arg TIMER_OC_MODE_TOGGLE: toggle mode + \arg TIMER_OC_MODE_LOW: force low mode + \arg TIMER_OC_MODE_HIGH: force high mode + \arg TIMER_OC_MODE_PWM0: PWM0 mode + \arg TIMER_OC_MODE_PWM1: PWM1 mode + \param[out] none + \retval none +*/ +void timer_channel_output_mode_config(uint32_t timer_periph, uint16_t channel, uint16_t ocmode) +{ + switch(channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0COMCTL); + TIMER_CHCTL0(timer_periph) |= (uint32_t)ocmode; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1COMCTL); + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(ocmode) << 8U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2COMCTL); + TIMER_CHCTL1(timer_periph) |= (uint32_t)ocmode; + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3COMCTL); + TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)(ocmode) << 8U); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel output pulse value + \param[in] timer_periph: please refer to the following parameters + \param[in] channel: + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0,2,13..16)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,2,14)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0,2)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0,2)) + \param[in] pulse: channel output pulse value,0~65535 + \param[out] none + \retval none +*/ +void timer_channel_output_pulse_value_config(uint32_t timer_periph, uint16_t channel, uint32_t pulse) +{ + switch(channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CH0CV(timer_periph) = (uint32_t)pulse; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CH1CV(timer_periph) = (uint32_t)pulse; + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CH2CV(timer_periph) = (uint32_t)pulse; + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CH3CV(timer_periph) = (uint32_t)pulse; + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel output shadow function + \param[in] timer_periph: please refer to the following parameters + \param[in] channel: + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0,2,13..16)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,2,14)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0,2)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0,2)) + \param[in] ocshadow: channel output shadow state + only one parameter can be selected which is shown as below: + \arg TIMER_OC_SHADOW_ENABLE: channel output shadow state enable + \arg TIMER_OC_SHADOW_DISABLE: channel output shadow state disable + \param[out] none + \retval none +*/ +void timer_channel_output_shadow_config(uint32_t timer_periph, uint16_t channel, uint16_t ocshadow) +{ + switch(channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0COMSEN); + TIMER_CHCTL0(timer_periph) |= (uint32_t)ocshadow; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1COMSEN); + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(ocshadow) << 8U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2COMSEN); + TIMER_CHCTL1(timer_periph) |= (uint32_t)ocshadow; + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3COMSEN); + TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)(ocshadow) << 8U); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel output fast function + \param[in] timer_periph: please refer to the following parameters + \param[in] channel: + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0,2,13..16)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,2,14)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0,2)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0,2)) + \param[in] ocfast: channel output fast function + only one parameter can be selected which is shown as below: + \arg TIMER_OC_FAST_ENABLE: channel output fast function enable + \arg TIMER_OC_FAST_DISABLE: channel output fast function disable + \param[out] none + \retval none +*/ +void timer_channel_output_fast_config(uint32_t timer_periph, uint16_t channel, uint16_t ocfast) +{ + switch(channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0COMFEN); + TIMER_CHCTL0(timer_periph) |= (uint32_t)ocfast; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1COMFEN); + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)ocfast << 8U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2COMFEN); + TIMER_CHCTL1(timer_periph) |= (uint32_t)ocfast; + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3COMFEN); + TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)ocfast << 8U); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel output clear function + \param[in] timer_periph: please refer to the following parameters + \param[in] channel: + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0,2)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,2)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0,2)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0,2)) + \param[in] occlear: channel output clear function + only one parameter can be selected which is shown as below: + \arg TIMER_OC_CLEAR_ENABLE: channel output clear function enable + \arg TIMER_OC_CLEAR_DISABLE: channel output clear function disable + \param[out] none + \retval none +*/ +void timer_channel_output_clear_config(uint32_t timer_periph, uint16_t channel, uint16_t occlear) +{ + switch(channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0COMCEN); + TIMER_CHCTL0(timer_periph) |= (uint32_t)occlear; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1COMCEN); + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)occlear << 8U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2COMCEN); + TIMER_CHCTL1(timer_periph) |= (uint32_t)occlear; + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3COMCEN); + TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)occlear << 8U); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel output polarity + \param[in] timer_periph: please refer to the following parameters + \param[in] channel: + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0,2,13..16)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,2,14)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0,2)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0,2)) + \param[in] ocpolarity: channel output polarity + only one parameter can be selected which is shown as below: + \arg TIMER_OC_POLARITY_HIGH: channel output polarity is high + \arg TIMER_OC_POLARITY_LOW: channel output polarity is low + \param[out] none + \retval none +*/ +void timer_channel_output_polarity_config(uint32_t timer_periph, uint16_t channel, uint16_t ocpolarity) +{ + switch(channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0P); + TIMER_CHCTL2(timer_periph) |= (uint32_t)ocpolarity; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1P); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocpolarity << 4U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2P); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocpolarity << 8U); + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH3P); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocpolarity << 12U); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel complementary output polarity + \param[in] timer_periph: TIMERx(x=0,2,14) + \param[in] channel: + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0,2,13..16)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,2,14)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0,2)) + \arg TIMER_CH_3: TIMER channel2(TIMERx(x=0,2)) + \param[in] ocnpolarity: channel complementary output polarity + only one parameter can be selected which is shown as below: + \arg TIMER_OCN_POLARITY_HIGH: channel complementary output polarity is high + \arg TIMER_OCN_POLARITY_LOW: channel complementary output polarity is low + \param[out] none + \retval none +*/ +void timer_channel_complementary_output_polarity_config(uint32_t timer_periph, uint16_t channel, uint16_t ocnpolarity) +{ + switch(channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0NP); + TIMER_CHCTL2(timer_periph) |= (uint32_t)ocnpolarity; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1NP); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocnpolarity << 4U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2NP); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocnpolarity << 8U); + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH3NP); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocnpolarity << 12U); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel enable state + \param[in] timer_periph: please refer to the following parameters + \param[in] channel: + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0,2,13..16)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,2,14)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0,2)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0,2)) + \param[in] state: TIMER channel enable state + only one parameter can be selected which is shown as below: + \arg TIMER_CCX_ENABLE: channel enable + \arg TIMER_CCX_DISABLE: channel disable + \param[out] none + \retval none +*/ +void timer_channel_output_state_config(uint32_t timer_periph, uint16_t channel, uint32_t state) +{ + switch(channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0EN); + TIMER_CHCTL2(timer_periph) |= (uint32_t)state; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1EN); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)state << 4U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2EN); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)state << 8U); + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH3EN); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)state << 12U); + break; + default: + break; + } +} + +/*! + \brief configure TIMER channel complementary output enable state + \param[in] timer_periph: TIMERx(x=0,14..16) + \param[in] channel: + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0,14..16)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0)) + \param[in] ocnstate: TIMER channel complementary output enable state + only one parameter can be selected which is shown as below: + \arg TIMER_CCXN_ENABLE: channel complementary enable + \arg TIMER_CCXN_DISABLE: channel complementary disable + \param[out] none + \retval none +*/ +void timer_channel_complementary_output_state_config(uint32_t timer_periph, uint16_t channel, uint16_t ocnstate) +{ + switch(channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0NEN); + TIMER_CHCTL2(timer_periph) |= (uint32_t)ocnstate; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1NEN); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocnstate << 4U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2NEN); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)ocnstate << 8U); + break; + default: + break; + } +} + +/*! + \brief initialize TIMER channel input parameter struct with a default value + \param[in] icpara: TIMER channel intput parameter struct + \param[out] none + \retval none +*/ +void timer_channel_input_struct_para_init(timer_ic_parameter_struct* icpara) +{ + /* initialize the channel input parameter struct member with the default value */ + icpara->icpolarity = TIMER_IC_POLARITY_RISING; + icpara->icselection = TIMER_IC_SELECTION_DIRECTTI; + icpara->icprescaler = TIMER_IC_PSC_DIV1; + icpara->icfilter = 0U; +} + +/*! + \brief configure TIMER input capture parameter + \param[in] timer_periph: please refer to the following parameters + \param[in] channel: + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0,2,13..16)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,2,14)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0,2)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0,2)) + \param[in] icpara: TIMER channel intput parameter struct + icpolarity: TIMER_IC_POLARITY_RISING,TIMER_IC_POLARITY_FALLING,TIMER_IC_POLARITY_BOTH_EDGE + icselection: TIMER_IC_SELECTION_DIRECTTI,TIMER_IC_SELECTION_INDIRECTTI,TIMER_IC_SELECTION_ITS + icprescaler: TIMER_IC_PSC_DIV1,TIMER_IC_PSC_DIV2,TIMER_IC_PSC_DIV4,TIMER_IC_PSC_DIV8 + icfilter: 0~15 + \param[out] none + \retval none +*/ +void timer_input_capture_config(uint32_t timer_periph,uint16_t channel, timer_ic_parameter_struct* icpara) +{ + switch(channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + /* reset the CH0EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0EN); + + /* reset the CH0P and CH0NP bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH0P | TIMER_CHCTL2_CH0NP)); + TIMER_CHCTL2(timer_periph) |= (uint32_t)(icpara->icpolarity); + /* reset the CH0MS bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0MS); + TIMER_CHCTL0(timer_periph) |= (uint32_t)(icpara->icselection); + /* reset the CH0CAPFLT bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0CAPFLT); + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(icpara->icfilter) << 4U); + + /* set the CH0EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH0EN; + break; + + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + /* reset the CH1EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1EN); + + /* reset the CH1P and CH1NP bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH1P | TIMER_CHCTL2_CH1NP)); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(icpara->icpolarity) << 4U); + /* reset the CH1MS bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1MS); + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(icpara->icselection) << 8U); + /* reset the CH1CAPFLT bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1CAPFLT); + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(icpara->icfilter) << 12U); + + /* set the CH1EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH1EN; + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + /* reset the CH2EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH2EN); + + /* reset the CH2P and CH2NP bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH2P|TIMER_CHCTL2_CH2NP)); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(icpara->icpolarity) << 8U); + + /* reset the CH2MS bit */ + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2MS); + TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)(icpara->icselection)); + + /* reset the CH2CAPFLT bit */ + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2CAPFLT); + TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)(icpara->icfilter) << 4U); + + /* set the CH2EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH2EN; + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + /* reset the CH3EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH3EN); + + /* reset the CH3P and CH3NP bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH3P|TIMER_CHCTL2_CH3NP)); + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(icpara->icpolarity) << 12U); + + /* reset the CH3MS bit */ + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3MS); + TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)(icpara->icselection) << 8U); + + /* reset the CH3CAPFLT bit */ + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3CAPFLT); + TIMER_CHCTL1(timer_periph) |= (uint32_t)((uint32_t)(icpara->icfilter) << 12U); + + /* set the CH3EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH3EN; + break; + default: + break; + } + /* configure TIMER channel input capture prescaler value */ + timer_channel_input_capture_prescaler_config(timer_periph, channel, (uint16_t)(icpara->icprescaler)); +} + +/*! + \brief configure TIMER channel input capture prescaler value + \param[in] timer_periph: please refer to the following parameters + \param[in] channel: + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0,2,13..16)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,2,14)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0,2)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0,2)) + \param[in] prescaler: channel input capture prescaler value + only one parameter can be selected which is shown as below: + \arg TIMER_IC_PSC_DIV1: no prescaler + \arg TIMER_IC_PSC_DIV2: divided by 2 + \arg TIMER_IC_PSC_DIV4: divided by 4 + \arg TIMER_IC_PSC_DIV8: divided by 8 + \param[out] none + \retval none +*/ +void timer_channel_input_capture_prescaler_config(uint32_t timer_periph, uint16_t channel, uint16_t prescaler) +{ + switch(channel){ + /* configure TIMER_CH_0 */ + case TIMER_CH_0: + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0CAPPSC); + TIMER_CHCTL0(timer_periph) |= (uint32_t)prescaler; + break; + /* configure TIMER_CH_1 */ + case TIMER_CH_1: + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1CAPPSC); + TIMER_CHCTL0(timer_periph) |= ((uint32_t)prescaler << 8U); + break; + /* configure TIMER_CH_2 */ + case TIMER_CH_2: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH2CAPPSC); + TIMER_CHCTL1(timer_periph) |= (uint32_t)prescaler; + break; + /* configure TIMER_CH_3 */ + case TIMER_CH_3: + TIMER_CHCTL1(timer_periph) &= (~(uint32_t)TIMER_CHCTL1_CH3CAPPSC); + TIMER_CHCTL1(timer_periph) |= ((uint32_t)prescaler << 8U); + break; + default: + break; + } +} + +/*! + \brief read TIMER channel capture compare register value + \param[in] timer_periph: please refer to the following parameters + \param[in] channel: + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel0(TIMERx(x=0,2,13..16)) + \arg TIMER_CH_1: TIMER channel1(TIMERx(x=0,2,14)) + \arg TIMER_CH_2: TIMER channel2(TIMERx(x=0,2)) + \arg TIMER_CH_3: TIMER channel3(TIMERx(x=0,2)) + \param[out] none + \retval channel capture compare register value +*/ +uint32_t timer_channel_capture_value_register_read(uint32_t timer_periph, uint16_t channel) +{ + uint32_t count_value = 0U; + + switch(channel){ + /* read TIMER channel 0 capture compare register value */ + case TIMER_CH_0: + count_value = TIMER_CH0CV(timer_periph); + break; + /* read TIMER channel 1 capture compare register value */ + case TIMER_CH_1: + count_value = TIMER_CH1CV(timer_periph); + break; + /* read TIMER channel 2 capture compare register value */ + case TIMER_CH_2: + count_value = TIMER_CH2CV(timer_periph); + break; + /* read TIMER channel 3 capture compare register value */ + case TIMER_CH_3: + count_value = TIMER_CH3CV(timer_periph); + break; + default: + break; + } + return (count_value); +} + +/*! + \brief configure TIMER input pwm capture function + \param[in] timer_periph: TIMERx(x=0,2,14) + \param[in] channel: + only one parameter can be selected which is shown as below: + \arg TIMER_CH_0: TIMER channel0 + \arg TIMER_CH_1: TIMER channel1 + \param[in] icpwm:TIMER channel intput pwm parameter struct + icpolarity: TIMER_IC_POLARITY_RISING,TIMER_IC_POLARITY_FALLING + icselection: TIMER_IC_SELECTION_DIRECTTI,TIMER_IC_SELECTION_INDIRECTTI + icprescaler: TIMER_IC_PSC_DIV1,TIMER_IC_PSC_DIV2,TIMER_IC_PSC_DIV4,TIMER_IC_PSC_DIV8 + icfilter: 0~15 + \param[out] none + \retval none +*/ +void timer_input_pwm_capture_config(uint32_t timer_periph, uint16_t channel, timer_ic_parameter_struct* icpwm) +{ + uint16_t icpolarity = 0x0U; + uint16_t icselection = 0x0U; + + /* Set channel input polarity */ + if(TIMER_IC_POLARITY_RISING == icpwm->icpolarity){ + icpolarity = TIMER_IC_POLARITY_FALLING; + }else{ + icpolarity = TIMER_IC_POLARITY_RISING; + } + + /* Set channel input mode selection */ + if(TIMER_IC_SELECTION_DIRECTTI == icpwm->icselection){ + icselection = TIMER_IC_SELECTION_INDIRECTTI; + }else{ + icselection = TIMER_IC_SELECTION_DIRECTTI; + } + + if(TIMER_CH_0 == channel){ + /* reset the CH0EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0EN); + /* reset the CH0P and CH0NP bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH0P|TIMER_CHCTL2_CH0NP)); + /* set the CH0P and CH0NP bits */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)(icpwm->icpolarity); + /* reset the CH0MS bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0MS); + /* set the CH0MS bit */ + TIMER_CHCTL0(timer_periph) |= (uint32_t)(icpwm->icselection); + /* reset the CH0CAPFLT bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0CAPFLT); + /* set the CH0CAPFLT bit */ + TIMER_CHCTL0(timer_periph) |= ((uint32_t)(icpwm->icfilter) << 4U); + /* set the CH0EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH0EN; + /* configure TIMER channel input capture prescaler value */ + timer_channel_input_capture_prescaler_config(timer_periph,TIMER_CH_0,(uint16_t)(icpwm->icprescaler)); + + /* reset the CH1EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1EN); + /* reset the CH1P and CH1NP bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH1P|TIMER_CHCTL2_CH1NP)); + /* set the CH1P and CH1NP bits */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)icpolarity << 4U); + /* reset the CH1MS bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1MS); + /* set the CH1MS bit */ + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)icselection << 8U); + /* reset the CH1CAPFLT bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1CAPFLT); + /* set the CH1CAPFLT bit */ + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(icpwm->icfilter) << 12U); + /* set the CH1EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH1EN; + /* configure TIMER channel input capture prescaler value */ + timer_channel_input_capture_prescaler_config(timer_periph,TIMER_CH_1,(uint16_t)(icpwm->icprescaler)); + }else{ + /* reset the CH1EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1EN); + /* reset the CH1P and CH1NP bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH1P|TIMER_CHCTL2_CH1NP)); + /* set the CH1P and CH1NP bits */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)(icpwm->icpolarity) << 4U); + /* reset the CH1MS bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1MS); + /* set the CH1MS bit */ + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(icpwm->icselection) << 8U); + /* reset the CH1CAPFLT bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1CAPFLT); + /* set the CH1CAPFLT bit */ + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)(icpwm->icfilter) << 12U); + /* set the CH1EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH1EN; + /* configure TIMER channel input capture prescaler value */ + timer_channel_input_capture_prescaler_config(timer_periph, TIMER_CH_1, (uint16_t)(icpwm->icprescaler)); + + /* reset the CH0EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0EN); + /* reset the CH0P and CH0NP bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH0P|TIMER_CHCTL2_CH0NP)); + /* set the CH0P and CH0NP bits */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)icpolarity; + /* reset the CH0MS bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0MS); + /* set the CH0MS bit */ + TIMER_CHCTL0(timer_periph) |= (uint32_t)icselection; + /* reset the CH0CAPFLT bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0CAPFLT); + /* set the CH0CAPFLT bit */ + TIMER_CHCTL0(timer_periph) |= ((uint32_t)(icpwm->icfilter) << 4U); + /* set the CH0EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH0EN; + /* configure TIMER channel input capture prescaler value */ + timer_channel_input_capture_prescaler_config(timer_periph, TIMER_CH_0, (uint16_t)(icpwm->icprescaler)); + } +} + +/*! + \brief configure TIMER hall sensor mode + \param[in] timer_periph: TIMERx(x=0,2) + \param[in] hallmode: + only one parameter can be selected which is shown as below: + \arg TIMER_HALLINTERFACE_ENABLE: TIMER hall sensor mode enable + \arg TIMER_HALLINTERFACE_DISABLE: TIMER hall sensor mode disable + \param[out] none + \retval none +*/ +void timer_hall_mode_config(uint32_t timer_periph, uint32_t hallmode) +{ + if(TIMER_HALLINTERFACE_ENABLE == hallmode){ + TIMER_CTL1(timer_periph) |= (uint32_t)TIMER_CTL1_TI0S; + }else if(TIMER_HALLINTERFACE_DISABLE == hallmode){ + TIMER_CTL1(timer_periph) &= ~(uint32_t)TIMER_CTL1_TI0S; + }else{ + /* illegal parameters */ + } +} + +/*! + \brief select TIMER input trigger source + \param[in] timer_periph: TIMERx(x=0,2,14) + \param[in] intrigger: + only one parameter can be selected which is shown as below: + \arg TIMER_SMCFG_TRGSEL_ITI0: internal trigger 0(TIMERx(x=0,2,14)) + \arg TIMER_SMCFG_TRGSEL_ITI1: internal trigger 1(TIMERx(x=0,2,14)) + \arg TIMER_SMCFG_TRGSEL_ITI2: internal trigger 2(TIMERx(x=0,2)) + \arg TIMER_SMCFG_TRGSEL_CI0F_ED: TI0 edge detector(TIMERx(x=0,2,14)) + \arg TIMER_SMCFG_TRGSEL_CI0FE0: filtered TIMER input 0(TIMERx(x=0,2,14)) + \arg TIMER_SMCFG_TRGSEL_CI1FE1: filtered TIMER input 1(TIMERx(x=0,2,14)) + \arg TIMER_SMCFG_TRGSEL_ETIFP: external trigger(TIMERx(x=0,2)) + \param[out] none + \retval none +*/ +void timer_input_trigger_source_select(uint32_t timer_periph, uint32_t intrigger) +{ + TIMER_SMCFG(timer_periph) &= (~(uint32_t)TIMER_SMCFG_TRGS); + TIMER_SMCFG(timer_periph) |= (uint32_t)intrigger; +} + +/*! + \brief select TIMER master mode output trigger source + \param[in] timer_periph: TIMERx(x=0,2,5,14) + \param[in] outrigger: + only one parameter can be selected which is shown as below: + \arg TIMER_TRI_OUT_SRC_RESET: the UPG bit as trigger output(TIMERx(x=0,2,5,14)) + \arg TIMER_TRI_OUT_SRC_ENABLE: the counter enable signal TIMER_CTL0_CEN as trigger output(TIMERx(x=0,2,5,14)) + \arg TIMER_TRI_OUT_SRC_UPDATE: update event as trigger output(TIMERx(x=0,2,5,14)) + \arg TIMER_TRI_OUT_SRC_CH0: a capture or a compare match occurred in channal0 as trigger output TRGO + \arg TIMER_TRI_OUT_SRC_O0CPRE: O0CPRE as trigger output(TIMERx(x=0,2,14)) + \arg TIMER_TRI_OUT_SRC_O1CPRE: O1CPRE as trigger output(TIMERx(x=0,2,14)) + \arg TIMER_TRI_OUT_SRC_O2CPRE: O2CPRE as trigger output(TIMERx(x=0,2,14)) + \arg TIMER_TRI_OUT_SRC_O3CPRE: O3CPRE as trigger output(TIMERx(x=0,2,14)) + \param[out] none + \retval none +*/ +void timer_master_output_trigger_source_select(uint32_t timer_periph, uint32_t outrigger) +{ + TIMER_CTL1(timer_periph) &= (~(uint32_t)TIMER_CTL1_MMC); + TIMER_CTL1(timer_periph) |= (uint32_t)outrigger; +} + +/*! + \brief select TIMER slave mode + \param[in] timer_periph: TIMERx(x=0,2,14) + \param[in] slavemode: + only one parameter can be selected which is shown as below: + \arg TIMER_SLAVE_MODE_DISABLE: slave mode disable(TIMERx(x=0,2,14)) + \arg TIMER_ENCODER_MODE0: encoder mode 0(TIMERx(x=0,2)) + \arg TIMER_ENCODER_MODE1: encoder mode 1(TIMERx(x=0,2)) + \arg TIMER_ENCODER_MODE2: encoder mode 2(TIMERx(x=0,2)) + \arg TIMER_SLAVE_MODE_RESTART: restart mode(TIMERx(x=0,2,14)) + \arg TIMER_SLAVE_MODE_PAUSE: pause mode(TIMERx(x=0,2,14)) + \arg TIMER_SLAVE_MODE_EVENT: event mode(TIMERx(x=0,2,14)) + \arg TIMER_SLAVE_MODE_EXTERNAL0: external clock mode 0(TIMERx(x=0,2,14)) + \param[out] none + \retval none +*/ + +void timer_slave_mode_select(uint32_t timer_periph, uint32_t slavemode) +{ + TIMER_SMCFG(timer_periph) &= (~(uint32_t)TIMER_SMCFG_SMC); + + TIMER_SMCFG(timer_periph) |= (uint32_t)slavemode; +} + +/*! + \brief configure TIMER master slave mode + \param[in] timer_periph: TIMERx(x=0,2,14) + \param[in] masterslave: + only one parameter can be selected which is shown as below: + \arg TIMER_MASTER_SLAVE_MODE_ENABLE: master slave mode enable + \arg TIMER_MASTER_SLAVE_MODE_DISABLE: master slave mode disable + \param[out] none + \retval none +*/ +void timer_master_slave_mode_config(uint32_t timer_periph, uint32_t masterslave) +{ + if(TIMER_MASTER_SLAVE_MODE_ENABLE == masterslave){ + TIMER_SMCFG(timer_periph) |= (uint32_t)TIMER_SMCFG_MSM; + }else if(TIMER_MASTER_SLAVE_MODE_DISABLE == masterslave){ + TIMER_SMCFG(timer_periph) &= ~(uint32_t)TIMER_SMCFG_MSM; + }else{ + /* illegal parameters */ + } +} + +/*! + \brief configure TIMER external trigger input + \param[in] timer_periph: TIMERx(x=0,2) + \param[in] extprescaler: + only one parameter can be selected which is shown as below: + \arg TIMER_EXT_TRI_PSC_OFF: no divided + \arg TIMER_EXT_TRI_PSC_DIV2: divided by 2 + \arg TIMER_EXT_TRI_PSC_DIV4: divided by 4 + \arg TIMER_EXT_TRI_PSC_DIV8: divided by 8 + \param[in] extpolarity: + only one parameter can be selected which is shown as below: + \arg TIMER_ETP_FALLING: active low or falling edge active + \arg TIMER_ETP_RISING: active high or rising edge active + \param[in] extfilter: a value between 0 and 15 + \param[out] none + \retval none +*/ +void timer_external_trigger_config(uint32_t timer_periph, uint32_t extprescaler, + uint32_t extpolarity, uint32_t extfilter) +{ + TIMER_SMCFG(timer_periph) &= (~(uint32_t)(TIMER_SMCFG_ETP | TIMER_SMCFG_ETPSC | TIMER_SMCFG_ETFC)); + TIMER_SMCFG(timer_periph) |= (uint32_t)(extprescaler | extpolarity); + TIMER_SMCFG(timer_periph) |= (uint32_t)(extfilter << 8U); +} + +/*! + \brief configure TIMER quadrature decoder mode + \param[in] timer_periph: TIMERx(x=0,2) + \param[in] decomode: + only one parameter can be selected which is shown as below: + \arg TIMER_ENCODER_MODE0: counter counts on CI0FE0 edge depending on CI1FE1 level + \arg TIMER_ENCODER_MODE1: counter counts on CI1FE1 edge depending on CI0FE0 level + \arg TIMER_ENCODER_MODE2: counter counts on both CI0FE0 and CI1FE1 edges depending on the level of the other input + \param[in] ic0polarity: + only one parameter can be selected which is shown as below: + \arg TIMER_IC_POLARITY_RISING: capture rising edge + \arg TIMER_IC_POLARITY_FALLING: capture falling edge + \param[in] ic1polarity: + only one parameter can be selected which is shown as below: + \arg TIMER_IC_POLARITY_RISING: capture rising edge + \arg TIMER_IC_POLARITY_FALLING: capture falling edge + \param[out] none + \retval none +*/ +void timer_quadrature_decoder_mode_config(uint32_t timer_periph, uint32_t decomode, + uint16_t ic0polarity, uint16_t ic1polarity) +{ + TIMER_SMCFG(timer_periph) &= (~(uint32_t)TIMER_SMCFG_SMC); + TIMER_SMCFG(timer_periph) |= (uint32_t)decomode; + + TIMER_CHCTL0(timer_periph) &= (uint32_t)(((~(uint32_t)TIMER_CHCTL0_CH0MS))&((~(uint32_t)TIMER_CHCTL0_CH1MS))); + TIMER_CHCTL0(timer_periph) |= (uint32_t)(TIMER_IC_SELECTION_DIRECTTI|((uint32_t)TIMER_IC_SELECTION_DIRECTTI << 8U)); + + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH0P|TIMER_CHCTL2_CH0NP)); + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH1P|TIMER_CHCTL2_CH1NP)); + TIMER_CHCTL2(timer_periph) |= ((uint32_t)ic0polarity|((uint32_t)ic1polarity << 4U)); +} + +/*! + \brief configure TIMER internal clock mode + \param[in] timer_periph: TIMERx(x=0,2,14) + \param[out] none + \retval none +*/ +void timer_internal_clock_config(uint32_t timer_periph) +{ + TIMER_SMCFG(timer_periph) &= ~(uint32_t)TIMER_SMCFG_SMC; +} + +/*! + \brief configure TIMER the internal trigger as external clock input + \param[in] timer_periph: TIMERx(x=0,2,14) + \param[in] intrigger: + only one parameter can be selected which is shown as below: + \arg TIMER_SMCFG_TRGSEL_ITI0: internal trigger 0(TIMERx(x=0,2,14)) + \arg TIMER_SMCFG_TRGSEL_ITI1: internal trigger 1(TIMERx(x=0,2,14)) + \arg TIMER_SMCFG_TRGSEL_ITI2: internal trigger 2(TIMERx(x=0,2)) + \param[out] none + \retval none +*/ +void timer_internal_trigger_as_external_clock_config(uint32_t timer_periph, uint32_t intrigger) +{ + timer_input_trigger_source_select(timer_periph, intrigger); + TIMER_SMCFG(timer_periph) &= ~(uint32_t)TIMER_SMCFG_SMC; + TIMER_SMCFG(timer_periph) |= (uint32_t)TIMER_SLAVE_MODE_EXTERNAL0; +} + +/*! + \brief configure TIMER the external trigger as external clock input + \param[in] timer_periph: TIMERx(x=0,2,14) + \param[in] extrigger: + only one parameter can be selected which is shown as below: + \arg TIMER_SMCFG_TRGSEL_CI0F_ED: TI0 edge detector + \arg TIMER_SMCFG_TRGSEL_CI0FE0: filtered TIMER input 0 + \arg TIMER_SMCFG_TRGSEL_CI1FE1: filtered TIMER input 1 + \param[in] extpolarity: + only one parameter can be selected which is shown as below: + \arg TIMER_IC_POLARITY_RISING: active high or rising edge active + \arg TIMER_IC_POLARITY_FALLING: active low or falling edge active + \arg TIMER_IC_POLARITY_BOTH_EDGE: active both edge + \param[in] extfilter: a value between 0 and 15 + \param[out] none + \retval none +*/ +void timer_external_trigger_as_external_clock_config(uint32_t timer_periph, uint32_t extrigger, + uint16_t extpolarity, uint32_t extfilter) +{ + if(TIMER_SMCFG_TRGSEL_CI1FE1 == extrigger){ + /* reset the CH1EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH1EN); + /* reset the CH1NP bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH1P|TIMER_CHCTL2_CH1NP)); + /* set the CH1NP bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)((uint32_t)extpolarity << 4U); + /* reset the CH1MS bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1MS); + /* set the CH1MS bit */ + TIMER_CHCTL0(timer_periph) |= (uint32_t)((uint32_t)TIMER_IC_SELECTION_DIRECTTI << 8U); + /* reset the CH1CAPFLT bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH1CAPFLT); + /* set the CH1CAPFLT bit */ + TIMER_CHCTL0(timer_periph) |= (uint32_t)(extfilter << 8U); + /* set the CH1EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH1EN; + }else{ + /* reset the CH0EN bit */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)TIMER_CHCTL2_CH0EN); + /* reset the CH0P and CH0NP bits */ + TIMER_CHCTL2(timer_periph) &= (~(uint32_t)(TIMER_CHCTL2_CH0P|TIMER_CHCTL2_CH0NP)); + /* set the CH0P and CH0NP bits */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)extpolarity; + /* reset the CH0MS bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0MS); + /* set the CH0MS bit */ + TIMER_CHCTL0(timer_periph) |= (uint32_t)TIMER_IC_SELECTION_DIRECTTI; + /* reset the CH0CAPFLT bit */ + TIMER_CHCTL0(timer_periph) &= (~(uint32_t)TIMER_CHCTL0_CH0CAPFLT); + /* reset the CH0CAPFLT bit */ + TIMER_CHCTL0(timer_periph) |= (uint32_t)extfilter; + /* set the CH0EN bit */ + TIMER_CHCTL2(timer_periph) |= (uint32_t)TIMER_CHCTL2_CH0EN; + } + /* select TIMER input trigger source */ + timer_input_trigger_source_select(timer_periph,extrigger); + /* reset the SMC bit */ + TIMER_SMCFG(timer_periph) &= (~(uint32_t)TIMER_SMCFG_SMC); + /* set the SMC bit */ + TIMER_SMCFG(timer_periph) |= (uint32_t)TIMER_SLAVE_MODE_EXTERNAL0; +} + +/*! + \brief configure TIMER the external clock mode0 + \param[in] timer_periph: TIMERx(x=0,2) + \param[in] extprescaler: + only one parameter can be selected which is shown as below: + \arg TIMER_EXT_TRI_PSC_OFF: no divided + \arg TIMER_EXT_TRI_PSC_DIV2: divided by 2 + \arg TIMER_EXT_TRI_PSC_DIV4: divided by 4 + \arg TIMER_EXT_TRI_PSC_DIV8: divided by 8 + \param[in] extpolarity: + only one parameter can be selected which is shown as below: + \arg TIMER_ETP_FALLING: active low or falling edge active + \arg TIMER_ETP_RISING: active high or rising edge active + \param[in] extfilter: a value between 0 and 15 + \param[out] none + \retval none +*/ +void timer_external_clock_mode0_config(uint32_t timer_periph, uint32_t extprescaler, + uint32_t extpolarity, uint32_t extfilter) +{ + /* configure TIMER external trigger input */ + timer_external_trigger_config(timer_periph, extprescaler, extpolarity, extfilter); + + /* reset the SMC bit,TRGS bit */ + TIMER_SMCFG(timer_periph) &= (~(uint32_t)(TIMER_SMCFG_SMC | TIMER_SMCFG_TRGS)); + /* set the SMC bit,TRGS bit */ + TIMER_SMCFG(timer_periph) |= (uint32_t)(TIMER_SLAVE_MODE_EXTERNAL0 | TIMER_SMCFG_TRGSEL_ETIFP); +} + +/*! + \brief configure TIMER the external clock mode1 + \param[in] timer_periph: TIMERx(x=0,2) + \param[in] extprescaler: + only one parameter can be selected which is shown as below: + \arg TIMER_EXT_TRI_PSC_OFF: no divided + \arg TIMER_EXT_TRI_PSC_DIV2: divided by 2 + \arg TIMER_EXT_TRI_PSC_DIV4: divided by 4 + \arg TIMER_EXT_TRI_PSC_DIV8: divided by 8 + \param[in] extpolarity: + only one parameter can be selected which is shown as below: + \arg TIMER_ETP_FALLING: active low or falling edge active + \arg TIMER_ETP_RISING: active high or rising edge active + \param[in] extfilter: a value between 0 and 15 + \param[out] none + \retval none +*/ +void timer_external_clock_mode1_config(uint32_t timer_periph, uint32_t extprescaler, + uint32_t extpolarity, uint32_t extfilter) +{ + /* configure TIMER external trigger input */ + timer_external_trigger_config(timer_periph, extprescaler, extpolarity, extfilter); + + TIMER_SMCFG(timer_periph) |= (uint32_t)TIMER_SMCFG_SMC1; +} + +/*! + \brief disable TIMER the external clock mode1 + \param[in] timer_periph: TIMERx(x=0,2) + \param[out] none + \retval none +*/ +void timer_external_clock_mode1_disable(uint32_t timer_periph) +{ + TIMER_SMCFG(timer_periph) &= ~(uint32_t)TIMER_SMCFG_SMC1; +} + +/*! + \brief configure TIMER channel remap function + \param[in] timer_periph: TIMERx(x=13) + \param[in] remap: + only one parameter can be selected which is shown as below: + \arg TIMER13_CI0_RMP_GPIO: timer13 channel 0 input is connected to GPIO(TIMER13_CH0) + \arg TIMER13_CI0_RMP_RTCCLK: timer13 channel 0 input is connected to the RTCCLK + \arg TIMER13_CI0_RMP_HXTAL_DIV32: timer13 channel 0 input is connected to HXTAL/32 clock + \arg TIMER13_CI0_RMP_CKOUTSEL: timer13 channel 0 input is connected to CKOUTSEL + \param[out] none + \retval none +*/ +void timer_channel_remap_config(uint32_t timer_periph, uint32_t remap) +{ + TIMER_IRMP(timer_periph) = (uint32_t)remap; +} + +/*! + \brief configure TIMER write CHxVAL register selection + \param[in] timer_periph: TIMERx(x=0,2,13..16) + \param[in] ccsel: + only one parameter can be selected which is shown as below: + \arg TIMER_CHVSEL_DISABLE: no effect + \arg TIMER_CHVSEL_ENABLE: when write the CHxVAL register, if the write value is same as the CHxVAL value, the write access is ignored + \param[out] none + \retval none +*/ +void timer_write_chxval_register_config(uint32_t timer_periph, uint16_t ccsel) +{ + if(TIMER_CHVSEL_ENABLE == ccsel){ + TIMER_CFG(timer_periph) |= (uint32_t)TIMER_CFG_CHVSEL; + }else if(TIMER_CHVSEL_DISABLE == ccsel){ + TIMER_CFG(timer_periph) &= ~(uint32_t)TIMER_CFG_CHVSEL; + }else{ + /* illegal parameters */ + } +} + +/*! + \brief configure TIMER output value selection + \param[in] timer_periph: TIMERx(x=0,14..16) + \param[in] outsel: + only one parameter can be selected which is shown as below: + \arg TIMER_OUTSEL_DISABLE: no effect + \arg TIMER_OUTSEL_ENABLE: if POEN and IOS is 0, the output disabled + \param[out] none + \retval none +*/ +void timer_output_value_selection_config(uint32_t timer_periph, uint16_t outsel) +{ + if(TIMER_OUTSEL_ENABLE == outsel){ + TIMER_CFG(timer_periph) |= (uint32_t)TIMER_CFG_OUTSEL; + }else if(TIMER_OUTSEL_DISABLE == outsel){ + TIMER_CFG(timer_periph) &= ~(uint32_t)TIMER_CFG_OUTSEL; + }else{ + /* illegal parameters */ + } +} diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_usart.c b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_usart.c new file mode 100644 index 0000000000000000000000000000000000000000..f73723e4be154d105bf4bba3c83e95758cd984e0 --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_usart.c @@ -0,0 +1,1318 @@ +/*! + \file gd32e230_usart.c + \brief USART driver + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor 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 copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 "gd32e230_usart.h" + +/*! + \brief reset USART + \param[in] usart_periph: USARTx(x=0,1) + \param[out] none + \retval none +*/ +void usart_deinit(uint32_t usart_periph) +{ + switch(usart_periph){ + case USART0: + /* reset USART0 */ + rcu_periph_reset_enable(RCU_USART0RST); + rcu_periph_reset_disable(RCU_USART0RST); + break; + case USART1: + /* reset USART1 */ + rcu_periph_reset_enable(RCU_USART1RST); + rcu_periph_reset_disable(RCU_USART1RST); + break; + default: + break; + } +} + +/*! + \brief configure USART baud rate value + \param[in] usart_periph: USARTx(x=0,1) + \param[in] baudval: baud rate value + \param[out] none + \retval none +*/ +void usart_baudrate_set(uint32_t usart_periph, uint32_t baudval) +{ + uint32_t uclk = 0U, intdiv = 0U, fradiv = 0U, udiv = 0U; + switch(usart_periph){ + /* get clock frequency */ + case USART0: + /* get USART0 clock */ + uclk = rcu_clock_freq_get(CK_USART); + break; + case USART1: + /* get USART1 clock */ + uclk = rcu_clock_freq_get(CK_APB1); + break; + default: + break; + } + if(USART_CTL0(usart_periph) & USART_CTL0_OVSMOD){ + /* oversampling by 8, configure the value of USART_BAUD */ + udiv = ((2U*uclk)+baudval/2U)/baudval; + intdiv = udiv & 0x0000fff0U; + fradiv = (udiv>>1U) & 0x00000007U; + USART_BAUD(usart_periph) = ((USART_BAUD_FRADIV | USART_BAUD_INTDIV) & (intdiv | fradiv)); + }else{ + /* oversampling by 16, configure the value of USART_BAUD */ + udiv = (uclk+baudval/2U)/baudval; + intdiv = udiv & 0x0000fff0U; + fradiv = udiv & 0x0000000fU; + USART_BAUD(usart_periph) = ((USART_BAUD_FRADIV | USART_BAUD_INTDIV) & (intdiv | fradiv)); + } +} + +/*! + \brief configure USART parity + \param[in] usart_periph: USARTx(x=0,1) + \param[in] paritycfg: USART parity configure + only one parameter can be selected which is shown as below: + \arg USART_PM_NONE: no parity + \arg USART_PM_ODD: odd parity + \arg USART_PM_EVEN: even parity + \param[out] none + \retval none +*/ +void usart_parity_config(uint32_t usart_periph, uint32_t paritycfg) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + /* clear USART_CTL0 PM,PCEN bits */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_PM | USART_CTL0_PCEN); + /* configure USART parity mode */ + USART_CTL0(usart_periph) |= paritycfg; +} + +/*! + \brief configure USART word length + \param[in] usart_periph: USARTx(x=0,1) + \param[in] wlen: USART word length configure + only one parameter can be selected which is shown as below: + \arg USART_WL_8BIT: 8 bits + \arg USART_WL_9BIT: 9 bits + \param[out] none + \retval none +*/ +void usart_word_length_set(uint32_t usart_periph, uint32_t wlen) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + /* clear USART_CTL0 WL bit */ + USART_CTL0(usart_periph) &= ~USART_CTL0_WL; + /* configure USART word length */ + USART_CTL0(usart_periph) |= wlen; +} + +/*! + \brief configure USART stop bit length + \param[in] usart_periph: USARTx(x=0,1) + \param[in] stblen: USART stop bit configure + only one parameter can be selected which is shown as below: + \arg USART_STB_1BIT: 1 bit + \arg USART_STB_0_5BIT: 0.5bit + \arg USART_STB_2BIT: 2 bits + \arg USART_STB_1_5BIT: 1.5bit + \param[out] none + \retval none +*/ +void usart_stop_bit_set(uint32_t usart_periph, uint32_t stblen) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + /* clear USART_CTL1 STB bits */ + USART_CTL1(usart_periph) &= ~USART_CTL1_STB; + USART_CTL1(usart_periph) |= stblen; +} + +/*! + \brief enable USART + \param[in] usart_periph: USARTx(x=0,1) + \param[out] none + \retval none +*/ +void usart_enable(uint32_t usart_periph) +{ + USART_CTL0(usart_periph) |= USART_CTL0_UEN; +} + +/*! + \brief disable USART + \param[in] usart_periph: USARTx(x=0,1) + \param[out] none + \retval none +*/ +void usart_disable(uint32_t usart_periph) +{ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); +} + +/*! + \brief configure USART transmitter + \param[in] usart_periph: USARTx(x=0,1) + \param[in] txconfig: enable or disable USART transmitter + only one parameter can be selected which is shown as below: + \arg USART_TRANSMIT_ENABLE: enable USART transmission + \arg USART_TRANSMIT_DISABLE: enable USART transmission + \param[out] none + \retval none +*/ +void usart_transmit_config(uint32_t usart_periph, uint32_t txconfig) +{ + USART_CTL0(usart_periph) &= ~USART_CTL0_TEN; + /* configure transfer mode */ + USART_CTL0(usart_periph) |= txconfig; +} + +/*! + \brief configure USART receiver + \param[in] usart_periph: USARTx(x=0,1) + \param[in] rxconfig: enable or disable USART receiver + only one parameter can be selected which is shown as below: + \arg USART_RECEIVE_ENABLE: enable USART reception + \arg USART_RECEIVE_DISABLE: disable USART reception + \param[out] none + \retval none +*/ +void usart_receive_config(uint32_t usart_periph, uint32_t rxconfig) +{ + USART_CTL0(usart_periph) &= ~USART_CTL0_REN; + /* configure receiver mode */ + USART_CTL0(usart_periph) |= rxconfig; +} + +/*! + \brief data is transmitted/received with the LSB/MSB first + \param[in] usart_periph: USARTx(x=0,1) + \param[in] msbf: LSB/MSB + only one parameter can be selected which is shown as below: + \arg USART_MSBF_LSB: LSB first + \arg USART_MSBF_MSB: MSB first + \param[out] none + \retval none +*/ +void usart_data_first_config(uint32_t usart_periph, uint32_t msbf) +{ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + /* configure LSB or MSB first */ + USART_CTL1(usart_periph) &= ~(USART_CTL1_MSBF); + USART_CTL1(usart_periph) |= (USART_CTL1_MSBF & msbf); +} + +/*! + \brief USART inverted configure + \param[in] usart_periph: USARTx(x=0,1) + \param[in] invertpara: refer to usart_invert_enum + only one parameter can be selected which is shown as below: + \arg USART_DINV_ENABLE: data bit level inversion + \arg USART_DINV_DISABLE: data bit level not inversion + \arg USART_TXPIN_ENABLE: TX pin level inversion + \arg USART_TXPIN_DISABLE: TX pin level not inversion + \arg USART_RXPIN_ENABLE: RX pin level inversion + \arg USART_RXPIN_DISABLE: RX pin level not inversion + \arg USART_SWAP_ENABLE: swap TX/RX pins + \arg USART_SWAP_DISABLE: not swap TX/RX pins + \param[out] none + \retval none +*/ +void usart_invert_config(uint32_t usart_periph, usart_invert_enum invertpara) +{ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + /* inverted or not the specified signal */ + switch(invertpara){ + case USART_DINV_ENABLE: + USART_CTL1(usart_periph) |= USART_CTL1_DINV; + break; + case USART_DINV_DISABLE: + USART_CTL1(usart_periph) &= ~(USART_CTL1_DINV); + break; + case USART_TXPIN_ENABLE: + USART_CTL1(usart_periph) |= USART_CTL1_TINV; + break; + case USART_TXPIN_DISABLE: + USART_CTL1(usart_periph) &= ~(USART_CTL1_TINV); + break; + case USART_RXPIN_ENABLE: + USART_CTL1(usart_periph) |= USART_CTL1_RINV; + break; + case USART_RXPIN_DISABLE: + USART_CTL1(usart_periph) &= ~(USART_CTL1_RINV); + break; + case USART_SWAP_ENABLE: + USART_CTL1(usart_periph) |= USART_CTL1_STRP; + break; + case USART_SWAP_DISABLE: + USART_CTL1(usart_periph) &= ~(USART_CTL1_STRP); + break; + default: + break; + } +} + +/*! + \brief enable the USART overrun function + \param[in] usart_periph: USARTx(x=0,1) + \param[out] none + \retval none +*/ +void usart_overrun_enable(uint32_t usart_periph) +{ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + /* enable overrun function */ + USART_CTL2(usart_periph) &= ~(USART_CTL2_OVRD); +} + +/*! + \brief disable the USART overrun function + \param[in] usart_periph: USARTx(x=0,1) + \param[out] none + \retval none +*/ +void usart_overrun_disable(uint32_t usart_periph) +{ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + /* disable overrun function */ + USART_CTL2(usart_periph) |= USART_CTL2_OVRD; +} + +/*! + \brief configure the USART oversample mode + \param[in] usart_periph: USARTx(x=0,1) + \param[in] oversamp: oversample value + only one parameter can be selected which is shown as below: + \arg USART_OVSMOD_8: oversampling by 8 + \arg USART_OVSMOD_16: oversampling by 16 + \param[out] none + \retval none +*/ +void usart_oversample_config(uint32_t usart_periph, uint32_t oversamp) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + /* clear OVSMOD bit */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_OVSMOD); + USART_CTL0(usart_periph) |= oversamp; +} + +/*! + \brief configure the sample bit method + \param[in] usart_periph: USARTx(x=0,1) + \param[in] osb: sample bit + only one parameter can be selected which is shown as below: + \arg USART_OSB_1BIT: 1 bit + \arg USART_OSB_3BIT: 3 bits + \param[out] none + \retval none +*/ +void usart_sample_bit_config(uint32_t usart_periph, uint32_t osb) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) &= ~(USART_CTL2_OSB); + USART_CTL2(usart_periph) |= osb; +} + +/*! + \brief enable receiver timeout + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_receiver_timeout_enable(uint32_t usart_periph) +{ + USART_CTL1(usart_periph) |= USART_CTL1_RTEN; +} + +/*! + \brief disable receiver timeout + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_receiver_timeout_disable(uint32_t usart_periph) +{ + USART_CTL1(usart_periph) &= ~(USART_CTL1_RTEN); +} + +/*! + \brief configure receiver timeout threshold + \param[in] usart_periph: USARTx(x=0) + \param[in] rtimeout: 0x00000000-0x00FFFFFF, receiver timeout value in terms of number of baud clocks + \param[out] none + \retval none +*/ +void usart_receiver_timeout_threshold_config(uint32_t usart_periph, uint32_t rtimeout) +{ + USART_RT(usart_periph) &= ~(USART_RT_RT); + USART_RT(usart_periph) |= rtimeout; +} + +/*! + \brief USART transmit data function + \param[in] usart_periph: USARTx(x=0,1) + \param[in] data: data of transmission + \param[out] none + \retval none +*/ +void usart_data_transmit(uint32_t usart_periph, uint32_t data) +{ + USART_TDATA(usart_periph) = (USART_TDATA_TDATA & data); +} + +/*! + \brief USART receive data function + \param[in] usart_periph: USARTx(x=0,1) + \param[out] none + \retval data of received +*/ +uint16_t usart_data_receive(uint32_t usart_periph) +{ + return (uint16_t)(GET_BITS(USART_RDATA(usart_periph), 0U, 8U)); +} + +/*! + \brief enable auto baud rate detection + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_autobaud_detection_enable(uint32_t usart_periph) +{ + USART_CTL1(usart_periph) |= USART_CTL1_ABDEN; +} + +/*! + \brief disable auto baud rate detection + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_autobaud_detection_disable(uint32_t usart_periph) +{ + USART_CTL1(usart_periph) &= ~(USART_CTL1_ABDEN); +} + +/*! + \brief configure auto baud rate detection mode + \param[in] usart_periph: USARTx(x=0) + \param[in] abdmod: auto baud rate detection mode + only one parameter can be selected which is shown as below: + \arg USART_ABDM_FTOR: falling edge to rising edge measurement + \arg USART_ABDM_FTOF: falling edge to falling edge measurement + \param[out] none + \retval none +*/ +void usart_autobaud_detection_mode_config(uint32_t usart_periph, uint32_t abdmod) +{ + /* reset ABDM bits */ + USART_CTL1(usart_periph) &= ~(USART_CTL1_ABDM); + USART_CTL1(usart_periph) |= abdmod; +} + +/*! + \brief address of the USART terminal + \param[in] usart_periph: USARTx(x=0,1) + \param[in] addr: 0x00-0xFF, address of USART terminal + \param[out] none + \retval none +*/ +void usart_address_config(uint32_t usart_periph, uint8_t addr) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL1(usart_periph) &= ~(USART_CTL1_ADDR); + USART_CTL1(usart_periph) |= (USART_CTL1_ADDR & (((uint32_t)addr) << 24)); +} + +/*! + \brief configure address detection mode + \param[in] usart_periph: USARTx(x=0,1) + \param[in] addmod: address detection mode + only one parameter can be selected which is shown as below: + \arg USART_ADDM_4BIT: 4 bits + \arg USART_ADDM_FULLBIT: full bits + \param[out] none + \retval none +*/ +void usart_address_detection_mode_config(uint32_t usart_periph, uint32_t addmod) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL1(usart_periph) &= ~(USART_CTL1_ADDM); + USART_CTL1(usart_periph) |= USART_CTL1_ADDM & (addmod); +} + +/*! + \brief enable mute mode + \param[in] usart_periph: USARTx(x=0,1) + \param[out] none + \retval none +*/ +void usart_mute_mode_enable(uint32_t usart_periph) +{ + USART_CTL0(usart_periph) |= USART_CTL0_MEN; +} + +/*! + \brief disable mute mode + \param[in] usart_periph: USARTx(x=0,1) + \param[out] none + \retval none +*/ +void usart_mute_mode_disable(uint32_t usart_periph) +{ + USART_CTL0(usart_periph) &= ~(USART_CTL0_MEN); +} + +/*! + \brief configure wakeup method in mute mode + \param[in] usart_periph: USARTx(x=0,1) + \param[in] wmethod: two methods be used to enter or exit the mute mode + only one parameter can be selected which is shown as below: + \arg USART_WM_IDLE: idle line + \arg USART_WM_ADDR: address mark + \param[out] none + \retval none +*/ +void usart_mute_mode_wakeup_config(uint32_t usart_periph, uint32_t wmethod) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL0(usart_periph) &= ~(USART_CTL0_WM); + USART_CTL0(usart_periph) |= wmethod; +} + +/*! + \brief enable LIN mode + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_lin_mode_enable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL1(usart_periph) |= USART_CTL1_LMEN; +} + +/*! + \brief disable LIN mode + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_lin_mode_disable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL1(usart_periph) &= ~(USART_CTL1_LMEN); +} + +/*! + \brief LIN break detection length + \param[in] usart_periph: USARTx(x=0) + \param[in] lblen: LIN break detection length + only one parameter can be selected which is shown as below: + \arg USART_LBLEN_10B: 10 bits break detection + \arg USART_LBLEN_11B: 11 bits break detection + \param[out] none + \retval none +*/ +void usart_lin_break_detection_length_config(uint32_t usart_periph, uint32_t lblen) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + USART_CTL1(usart_periph) &= ~(USART_CTL1_LBLEN); + USART_CTL1(usart_periph) |= USART_CTL1_LBLEN & (lblen); +} + +/*! + \brief enable half-duplex mode + \param[in] usart_periph: USARTx(x=0,1) + \param[out] none + \retval none +*/ +void usart_halfduplex_enable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) |= USART_CTL2_HDEN; +} + +/*! + \brief disable half-duplex mode + \param[in] usart_periph: USARTx(x=0,1) + \param[out] none + \retval none +*/ +void usart_halfduplex_disable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) &= ~(USART_CTL2_HDEN); +} + +/*! + \brief enable clock + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_clock_enable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL1(usart_periph) |= USART_CTL1_CKEN; +} + +/*! + \brief disable clock + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_clock_disable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL1(usart_periph) &= ~(USART_CTL1_CKEN); +} + +/*! + \brief configure USART synchronous mode parameters + \param[in] usart_periph: USARTx(x=0,1) + \param[in] clen: last bit clock pulse + only one parameter can be selected which is shown as below: + \arg USART_CLEN_NONE: clock pulse of the last data bit (MSB) is not output to the CK pin + \arg USART_CLEN_EN: clock pulse of the last data bit (MSB) is output to the CK pin + \param[in] cph: clock phase + only one parameter can be selected which is shown as below: + \arg USART_CPH_1CK: first clock transition is the first data capture edge + \arg USART_CPH_2CK: second clock transition is the first data capture edge + \param[in] cpl: clock polarity + only one parameter can be selected which is shown as below: + \arg USART_CPL_LOW: steady low value on CK pin + \arg USART_CPL_HIGH: steady high value on CK pin + \param[out] none + \retval none +*/ +void usart_synchronous_clock_config(uint32_t usart_periph, uint32_t clen, uint32_t cph, uint32_t cpl) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + /* reset USART_CTL1 CLEN,CPH,CPL bits */ + USART_CTL1(usart_periph) &= ~(USART_CTL1_CLEN | USART_CTL1_CPH | USART_CTL1_CPL); + + USART_CTL1(usart_periph) |= (USART_CTL1_CLEN & clen); + USART_CTL1(usart_periph) |= (USART_CTL1_CPH & cph); + USART_CTL1(usart_periph) |= (USART_CTL1_CPL & cpl); +} + +/*! + \brief configure guard time value in smartcard mode + \param[in] usart_periph: USARTx(x=0) + \param[in] guat: 0x00-0xFF + \param[out] none + \retval none +*/ +void usart_guard_time_config(uint32_t usart_periph, uint32_t guat) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_GP(usart_periph) &= ~(USART_GP_GUAT); + USART_GP(usart_periph) |= (USART_GP_GUAT & ((guat) << 8)); +} + +/*! + \brief enable smartcard mode + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_smartcard_mode_enable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) |= USART_CTL2_SCEN; +} + +/*! + \brief disable smartcard mode + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_smartcard_mode_disable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) &= ~(USART_CTL2_SCEN); +} + +/*! + \brief enable NACK in smartcard mode + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_smartcard_mode_nack_enable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) |= USART_CTL2_NKEN; +} + +/*! + \brief disable NACK in smartcard mode + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_smartcard_mode_nack_disable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) &= ~(USART_CTL2_NKEN); +} + +/*! + \brief enable early NACK in smartcard mode + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_smartcard_mode_early_nack_enable(uint32_t usart_periph) +{ + USART_RFCS(usart_periph) |= USART_RFCS_ELNACK; +} + +/*! + \brief disable early NACK in smartcard mode + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_smartcard_mode_early_nack_disable(uint32_t usart_periph) +{ + USART_RFCS(usart_periph) &= ~USART_RFCS_ELNACK; +} + +/*! + \brief configure smartcard auto-retry number + \param[in] usart_periph: USARTx(x=0) + \param[in] scrtnum: 0x00000000-0x00000007, smartcard auto-retry number + \param[out] none + \retval none +*/ +void usart_smartcard_autoretry_config(uint32_t usart_periph, uint32_t scrtnum) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + USART_CTL2(usart_periph) &= ~(USART_CTL2_SCRTNUM); + USART_CTL2(usart_periph) |= (USART_CTL2_SCRTNUM & (scrtnum << 17)); +} + +/*! + \brief configure block length + \param[in] usart_periph: USARTx(x=0) + \param[in] bl: 0x00000000-0x000000FF + \param[out] none + \retval none +*/ +void usart_block_length_config(uint32_t usart_periph, uint32_t bl) +{ + USART_RT(usart_periph) &= ~(USART_RT_BL); + USART_RT(usart_periph) |= (USART_RT_BL & ((bl) << 24)); +} + +/*! + \brief enable IrDA mode + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_irda_mode_enable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) |= USART_CTL2_IREN; +} + +/*! + \brief disable IrDA mode + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_irda_mode_disable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) &= ~(USART_CTL2_IREN); +} + +/*! + \brief configure the peripheral clock prescaler in USART IrDA low-power or SmartCard mode + \param[in] usart_periph: USARTx(x=0) + \param[in] psc: 0x00000000-0x000000FF + \param[out] none + \retval none +*/ +void usart_prescaler_config(uint32_t usart_periph, uint32_t psc) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + USART_GP(usart_periph) &= ~(USART_GP_PSC); + USART_GP(usart_periph) |= psc; +} + +/*! + \brief configure IrDA low-power + \param[in] usart_periph: USARTx(x=0) + \param[in] irlp: IrDA low-power or normal + only one parameter can be selected which is shown as below: + \arg USART_IRLP_LOW: low-power + \arg USART_IRLP_NORMAL: normal + \param[out] none + \retval none +*/ +void usart_irda_lowpower_config(uint32_t usart_periph, uint32_t irlp) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + USART_CTL2(usart_periph) &= ~(USART_CTL2_IRLP); + USART_CTL2(usart_periph) |= (USART_CTL2_IRLP & irlp); +} + +/*! + \brief configure hardware flow control RTS + \param[in] usart_periph: USARTx(x=0,1) + \param[in] rtsconfig: enable or disable RTS + only one parameter can be selected which is shown as below: + \arg USART_RTS_ENABLE: enable RTS + \arg USART_RTS_DISABLE: disable RTS + \param[out] none + \retval none +*/ +void usart_hardware_flow_rts_config(uint32_t usart_periph, uint32_t rtsconfig) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) &= ~(USART_CTL2_RTSEN); + USART_CTL2(usart_periph) |= rtsconfig; +} + +/*! + \brief configure hardware flow control CTS + \param[in] usart_periph: USARTx(x=0,1) + \param[in] ctsconfig: enable or disable CTS + only one parameter can be selected which is shown as below: + \arg USART_CTS_ENABLE: enable CTS + \arg USART_CTS_DISABLE: disable CTS + \param[out] none + \retval none +*/ +void usart_hardware_flow_cts_config(uint32_t usart_periph, uint32_t ctsconfig) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) &= ~USART_CTL2_CTSEN; + USART_CTL2(usart_periph) |= ctsconfig; +} + + /*! + \brief configure hardware flow control coherence mode + \param[in] usart_periph: USARTx(x=0,1) + \param[in] hcm: + only one parameter can be selected which is shown as below: + \arg USART_HCM_NONE: nRTS signal equals to the rxne status register + \arg USART_HCM_EN: nRTS signal is set when the last data bit has been sampled + \param[out] none + \retval none +*/ +void usart_hardware_flow_coherence_config(uint32_t usart_periph, uint32_t hcm) +{ + USART_CHC(usart_periph) &= ~(USART_CHC_HCM); + USART_CHC(usart_periph) |= (USART_CHC_HCM & hcm); +} + +/*! + \brief enable RS485 driver + \param[in] usart_periph: USARTx(x=0,1) + \param[out] none + \retval none +*/ +void usart_rs485_driver_enable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) |= USART_CTL2_DEM; +} + +/*! + \brief disable RS485 driver + \param[in] usart_periph: USARTx(x=0,1) + \param[out] none + \retval none +*/ +void usart_rs485_driver_disable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) &= ~(USART_CTL2_DEM); +} + +/*! + \brief configure driver enable assertion time + \param[in] usart_periph: USARTx(x=0,1) + \param[in] deatime: 0x00000000-0x0000001F + \param[out] none + \retval none +*/ +void usart_driver_assertime_config(uint32_t usart_periph, uint32_t deatime) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL0(usart_periph) &= ~(USART_CTL0_DEA); + USART_CTL0(usart_periph) |= (USART_CTL0_DEA & ((deatime) << 21)); +} + +/*! + \brief configure driver enable de-assertion time + \param[in] usart_periph: USARTx(x=0,1) + \param[in] dedtime: 0x00000000-0x0000001F + \param[out] none + \retval none +*/ +void usart_driver_deassertime_config(uint32_t usart_periph, uint32_t dedtime) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL0(usart_periph) &= ~(USART_CTL0_DED); + USART_CTL0(usart_periph) |= (USART_CTL0_DED & ((dedtime) << 16)); +} + +/*! + \brief configure driver enable polarity mode + \param[in] usart_periph: USARTx(x=0,1) + \param[in] dep: DE signal + only one parameter can be selected which is shown as below: + \arg USART_DEP_HIGH: DE signal is active high + \arg USART_DEP_LOW: DE signal is active low + \param[out] none + \retval none +*/ +void usart_depolarity_config(uint32_t usart_periph, uint32_t dep) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + /* reset DEP bit */ + USART_CTL2(usart_periph) &= ~(USART_CTL2_DEP); + USART_CTL2(usart_periph) |= (USART_CTL2_DEP & dep); +} + +/*! + \brief configure USART DMA reception + \param[in] usart_periph: USARTx(x=0,1) + \param[in] dmacmd: enable or disable DMA for reception + only one parameter can be selected which is shown as below: + \arg USART_DENR_ENABLE: DMA enable for reception + \arg USART_DENR_DISABLE: DMA disable for reception + \param[out] none + \retval none +*/ +void usart_dma_receive_config(uint32_t usart_periph, uint32_t dmacmd) +{ + USART_CTL2(usart_periph) &= ~USART_CTL2_DENR; + /* configure DMA reception */ + USART_CTL2(usart_periph) |= dmacmd; +} + +/*! + \brief configure USART DMA transmission + \param[in] usart_periph: USARTx(x=0,1) + \param[in] dmacmd: enable or disable DMA for transmission + only one parameter can be selected which is shown as below: + \arg USART_DENT_ENABLE: DMA enable for transmission + \arg USART_DENT_DISABLE: DMA disable for transmission + \param[out] none + \retval none +*/ +void usart_dma_transmit_config(uint32_t usart_periph, uint32_t dmacmd) +{ + USART_CTL2(usart_periph) &= ~USART_CTL2_DENT; + /* configure DMA transmission */ + USART_CTL2(usart_periph) |= dmacmd; +} + +/*! + \brief disable DMA on reception error + \param[in] usart_periph: USARTx(x=0,1) + \param[out] none + \retval none +*/ +void usart_reception_error_dma_disable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) |= USART_CTL2_DDRE; +} + +/*! + \brief enable DMA on reception error + \param[in] usart_periph: USARTx(x=0,1) + \param[out] none + \retval none +*/ +void usart_reception_error_dma_enable(uint32_t usart_periph) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + + USART_CTL2(usart_periph) &= ~(USART_CTL2_DDRE); +} + +/*! + \brief enable USART to wakeup the mcu from deep-sleep mode + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_wakeup_enable(uint32_t usart_periph) +{ + USART_CTL0(usart_periph) |= USART_CTL0_UESM; +} + +/*! + \brief disable USART to wakeup the mcu from deep-sleep mode + \param[in] usart_periph: USARTx(x=0) + \param[out] none + \retval none +*/ +void usart_wakeup_disable(uint32_t usart_periph) +{ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UESM); +} + +/*! + \brief configure the USART wakeup mode from deep-sleep mode + \param[in] usart_periph: USARTx(x=0) + \param[in] wum: wakeup mode + only one parameter can be selected which is shown as below: + \arg USART_WUM_ADDR: WUF active on address match + \arg USART_WUM_STARTB: WUF active on start bit + \arg USART_WUM_RBNE: WUF active on RBNE + \param[out] none + \retval none +*/ +void usart_wakeup_mode_config(uint32_t usart_periph, uint32_t wum) +{ + /* disable USART */ + USART_CTL0(usart_periph) &= ~(USART_CTL0_UEN); + /* reset WUM bit */ + USART_CTL2(usart_periph) &= ~(USART_CTL2_WUM); + USART_CTL2(usart_periph) |= USART_CTL2_WUM & (wum); +} + +/*! + \brief enable receive FIFO + \param[in] usart_periph: USARTx(x=0,1) + \param[out] none + \retval none +*/ +void usart_receive_fifo_enable(uint32_t usart_periph) +{ + USART_RFCS(usart_periph) |= USART_RFCS_RFEN; +} + +/*! + \brief disable receive FIFO + \param[in] usart_periph: USARTx(x=0,1) + \param[out] none + \retval none +*/ +void usart_receive_fifo_disable(uint32_t usart_periph) +{ + USART_RFCS(usart_periph) &= ~(USART_RFCS_RFEN); +} + +/*! + \brief read receive FIFO counter number + \param[in] usart_periph: USARTx(x=0,1) + \param[out] none + \retval receive FIFO counter number +*/ +uint8_t usart_receive_fifo_counter_number(uint32_t usart_periph) +{ + return (uint8_t)(GET_BITS(USART_RFCS(usart_periph), 12U, 14U)); +} + +/*! + \brief get flag in STAT/CHC/RFCS register + \param[in] usart_periph: USARTx(x=0,1) + \param[in] flag: flag type + only one parameter can be selected which is shown as below: + \arg USART_FLAG_PERR: parity error flag + \arg USART_FLAG_FERR: frame error flag + \arg USART_FLAG_NERR: noise error flag + \arg USART_FLAG_ORERR: overrun error + \arg USART_FLAG_IDLE: idle line detected flag + \arg USART_FLAG_RBNE: read data buffer not empty + \arg USART_FLAG_TC: transmission completed + \arg USART_FLAG_TBE: transmit data register empty + \arg USART_FLAG_LBD: LIN break detected flag + \arg USART_FLAG_CTSF: CTS change flag + \arg USART_FLAG_CTS: CTS level + \arg USART_FLAG_RT: receiver timeout flag + \arg USART_FLAG_EB: end of block flag + \arg USART_FLAG_ABDE: auto baudrate detection error + \arg USART_FLAG_ABD: auto baudrate detection flag + \arg USART_FLAG_BSY: busy flag + \arg USART_FLAG_AM: address match flag + \arg USART_FLAG_SB: send break flag + \arg USART_FLAG_RWU: receiver wakeup from mute mode. + \arg USART_FLAG_WU: wakeup from deep-sleep mode flag + \arg USART_FLAG_TEA: transmit enable acknowledge flag + \arg USART_FLAG_REA: receive enable acknowledge flag + \arg USART_FLAG_EPERR: early parity error flag + \arg USART_FLAG_RFE: receive FIFO empty flag + \arg USART_FLAG_RFF: receive FIFO full flag + \arg USART_FLAG_RFFINT: receive FIFO full interrupt flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus usart_flag_get(uint32_t usart_periph, usart_flag_enum flag) +{ + if(RESET != (USART_REG_VAL(usart_periph, flag) & BIT(USART_BIT_POS(flag)))){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear USART status + \param[in] usart_periph: USARTx(x=0,1) + \param[in] flag: flag type + only one parameter can be selected which is shown as below: + \arg USART_FLAG_PERR: parity error flag + \arg USART_FLAG_FERR: frame error flag + \arg USART_FLAG_NERR: noise detected flag + \arg USART_FLAG_ORERR: overrun error flag + \arg USART_FLAG_IDLE: idle line detected flag + \arg USART_FLAG_TC: transmission complete flag + \arg USART_FLAG_LBD: LIN break detected flag + \arg USART_FLAG_CTSF: CTS change flag + \arg USART_FLAG_RT: receiver timeout flag + \arg USART_FLAG_EB: end of block flag + \arg USART_FLAG_AM: address match flag + \arg USART_FLAG_WU: wakeup from deep-sleep mode flag + \arg USART_FLAG_EPERR: early parity error flag + \param[out] none + \retval none +*/ +void usart_flag_clear(uint32_t usart_periph, usart_flag_enum flag) +{ + USART_INTC(usart_periph) |= BIT(USART_BIT_POS(flag)); +} + +/*! + \brief enable USART interrupt + \param[in] usart_periph: USARTx(x=0,1) + \param[in] inttype: interrupt type + only one parameter can be selected which is shown as below: + \arg USART_INT_IDLE: idle interrupt + \arg USART_INT_RBNE: read data buffer not empty interrupt and + overrun error interrupt enable interrupt + \arg USART_INT_TC: transmission complete interrupt + \arg USART_INT_TBE: transmit data register empty interrupt + \arg USART_INT_PERR: parity error interrupt + \arg USART_INT_AM: address match interrupt + \arg USART_INT_RT: receiver timeout interrupt + \arg USART_INT_EB: end of block interrupt + \arg USART_INT_LBD: LIN break detection interrupt + \arg USART_INT_ERR: error interrupt enable in multibuffer communication + \arg USART_INT_CTS: CTS interrupt + \arg USART_INT_WU: wakeup from deep-sleep mode interrupt + \arg USART_INT_RFF: receive FIFO full interrupt enable + \param[out] none + \retval none +*/ +void usart_interrupt_enable(uint32_t usart_periph, usart_interrupt_enum inttype) +{ + USART_REG_VAL(usart_periph, inttype) |= BIT(USART_BIT_POS(inttype)); +} + +/*! + \brief disable USART interrupt + \param[in] usart_periph: USARTx(x=0,1) + \param[in] inttype: interrupt type + only one parameter can be selected which is shown as below: + \arg USART_INT_IDLE: idle interrupt + \arg USART_INT_RBNE: read data buffer not empty interrupt and + overrun error interrupt + \arg USART_INT_TC: transmission complete interrupt + \arg USART_INT_TBE: transmit data register empty interrupt + \arg USART_INT_PERR: parity error interrupt + \arg USART_INT_AM: address match interrupt + \arg USART_INT_RT: receiver timeout interrupt + \arg USART_INT_EB: end of block interrupt + \arg USART_INT_LBD: LIN break detection interrupt + \arg USART_INT_ERR: error interrupt enable in multibuffer communication + \arg USART_INT_CTS: CTS interrupt + \arg USART_INT_WU: wakeup from deep-sleep mode interrupt + \arg USART_INT_RFF: receive FIFO full interrupt enable + \param[out] none + \retval none +*/ +void usart_interrupt_disable(uint32_t usart_periph, usart_interrupt_enum inttype) +{ + USART_REG_VAL(usart_periph, inttype) &= ~BIT(USART_BIT_POS(inttype)); +} + +/*! + \brief enable USART command + \param[in] usart_periph: USARTx(x=0,1) + \param[in] cmdtype: command type + only one parameter can be selected which is shown as below: + \arg USART_CMD_ABDCMD: auto baudrate detection command + \arg USART_CMD_SBKCMD: send break command + \arg USART_CMD_MMCMD: mute mode command + \arg USART_CMD_RXFCMD: receive data flush command + \arg USART_CMD_TXFCMD: transmit data flush request + \param[out] none + \retval none +*/ +void usart_command_enable(uint32_t usart_periph, uint32_t cmdtype) +{ + USART_CMD(usart_periph) |= (cmdtype); +} + +/*! + \brief get USART interrupt and flag status + \param[in] usart_periph: USARTx(x=0,1) + \param[in] int_flag: interrupt and flag type, refer to usart_interrupt_flag_enum + only one parameter can be selected which is shown as below: + \arg USART_INT_FLAG_EB: end of block interrupt and flag + \arg USART_INT_FLAG_RT: receiver timeout interrupt and flag + \arg USART_INT_FLAG_AM: address match interrupt and flag + \arg USART_INT_FLAG_PERR: parity error interrupt and flag + \arg USART_INT_FLAG_TBE: transmitter buffer empty interrupt and flag + \arg USART_INT_FLAG_TC: transmission complete interrupt and flag + \arg USART_INT_FLAG_RBNE: read data buffer not empty interrupt and flag + \arg USART_INT_FLAG_RBNE_ORERR: read data buffer not empty interrupt and overrun error flag + \arg USART_INT_FLAG_IDLE: IDLE line detected interrupt and flag + \arg USART_INT_FLAG_LBD: LIN break detected interrupt and flag + \arg USART_INT_FLAG_WU: wakeup from deep-sleep mode interrupt and flag + \arg USART_INT_FLAG_CTS: CTS interrupt and flag + \arg USART_INT_FLAG_ERR_NERR: error interrupt and noise error flag + \arg USART_INT_FLAG_ERR_ORERR: error interrupt and overrun error + \arg USART_INT_FLAG_ERR_FERR: error interrupt and frame error flag + \arg USART_INT_FLAG_RFF: receive FIFO full interrupt and flag + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus usart_interrupt_flag_get(uint32_t usart_periph, usart_interrupt_flag_enum int_flag) +{ + uint32_t intenable = 0U, flagstatus = 0U; + /* get the interrupt enable bit status */ + intenable = (USART_REG_VAL(usart_periph, int_flag) & BIT(USART_BIT_POS(int_flag))); + /* get the corresponding flag bit status */ + flagstatus = (USART_REG_VAL2(usart_periph, int_flag) & BIT(USART_BIT_POS2(int_flag))); + + if(flagstatus && intenable){ + return SET; + }else{ + return RESET; + } +} + +/*! + \brief clear USART interrupt flag + \param[in] usart_periph: USARTx(x=0,1) + \param[in] flag: USART interrupt flag + only one parameter can be selected which is shown as below: + \arg USART_INT_FLAG_PERR: parity error flag + \arg USART_INT_FLAG_ERR_FERR: frame error flag + \arg USART_INT_FLAG_ERR_NERR: noise detected flag + \arg USART_INT_FLAG_RBNE_ORERR: read data buffer not empty interrupt and overrun error flag + \arg USART_INT_FLAG_ERR_ORERR: error interrupt and overrun error + \arg USART_INT_FLAG_IDLE: idle line detected flag + \arg USART_INT_FLAG_TC: transmission complete flag + \arg USART_INT_FLAG_LBD: LIN break detected flag + \arg USART_INT_FLAG_CTS: CTS change flag + \arg USART_INT_FLAG_RT: receiver timeout flag + \arg USART_INT_FLAG_EB: end of block flag + \arg USART_INT_FLAG_AM: address match flag + \arg USART_INT_FLAG_WU: wakeup from deep-sleep mode flag + \arg USART_INT_FLAG_RFF: receive FIFO full interrupt and flag + \param[out] none + \retval none +*/ +void usart_interrupt_flag_clear(uint32_t usart_periph, usart_interrupt_flag_enum flag) +{ + if(USART_INT_FLAG_RFF == flag){ + USART_RFCS(usart_periph) &= (uint32_t)(~USART_RFCS_RFFINT); + }else{ + USART_INTC(usart_periph) |= BIT(USART_BIT_POS2(flag)); + } +} diff --git a/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_wwdgt.c b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_wwdgt.c new file mode 100644 index 0000000000000000000000000000000000000000..4d1ad0200c1124b4be59cf2136308e94c76b18aa --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/GD32E230_standard_peripheral/Source/gd32e230_wwdgt.c @@ -0,0 +1,148 @@ +/*! + \file gd32e230_wwdgt.c + \brief WWDGT driver + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor 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 copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 "gd32e230_wwdgt.h" +#include "gd32e230_rcu.h" + +/* WWDGT_CTL register value */ +#define CTL_CNT(regval) (BITS(0,6) & ((uint32_t)(regval) << 0U)) /*!< write value to WWDGT_CTL_CNT bit field */ +/* WWDGT_CFG register value */ +#define CFG_WIN(regval) (BITS(0,6) & ((uint32_t)(regval) << 0U)) /*!< write value to WWDGT_CFG_WIN bit field */ + +/*! + \brief reset the window watchdog timer configuration + \param[in] none + \param[out] none + \retval none +*/ +void wwdgt_deinit(void) +{ + rcu_periph_reset_enable(RCU_WWDGTRST); + rcu_periph_reset_disable(RCU_WWDGTRST); +} + +/*! + \brief start the window watchdog timer counter + \param[in] none + \param[out] none + \retval none +*/ +void wwdgt_enable(void) +{ + WWDGT_CTL |= WWDGT_CTL_WDGTEN; +} + +/*! + \brief configure the window watchdog timer counter value + \param[in] counter_value: 0x00000000 - 0x0000007F + \param[out] none + \retval none +*/ +void wwdgt_counter_update(uint16_t counter_value) +{ + uint32_t reg = 0x00000000U; + + reg = WWDGT_CTL &(~(uint32_t)WWDGT_CTL_CNT); + reg |= (uint32_t)(CTL_CNT(counter_value)); + + WWDGT_CTL = (uint32_t)reg; +} + +/*! + \brief configure counter value, window value, and prescaler divider value + \param[in] counter: 0x00000000 - 0x0000007F + \param[in] window: 0x00000000 - 0x0000007F + \param[in] prescaler: wwdgt prescaler value + only one parameter can be selected which is shown as below: + \arg WWDGT_CFG_PSC_DIV1: the time base of window watchdog counter = (PCLK1/4096)/1 + \arg WWDGT_CFG_PSC_DIV2: the time base of window watchdog counter = (PCLK1/4096)/2 + \arg WWDGT_CFG_PSC_DIV4: the time base of window watchdog counter = (PCLK1/4096)/4 + \arg WWDGT_CFG_PSC_DIV8: the time base of window watchdog counter = (PCLK1/4096)/8 + \param[out] none + \retval none +*/ +void wwdgt_config(uint16_t counter, uint16_t window, uint32_t prescaler) +{ + uint32_t reg_cfg = 0x00000000U, reg_ctl = 0x00000000U; + + /* clear WIN and PSC bits, clear CNT bit */ + reg_cfg = WWDGT_CFG &(~((uint32_t)WWDGT_CFG_WIN|(uint32_t)WWDGT_CFG_PSC)); + reg_ctl = WWDGT_CTL &(~(uint32_t)WWDGT_CTL_CNT); + + /* configure WIN and PSC bits, configure CNT bit */ + reg_cfg |= (uint32_t)(CFG_WIN(window)); + reg_cfg |= (uint32_t)(prescaler); + reg_ctl |= (uint32_t)(CTL_CNT(counter)); + + WWDGT_CFG = (uint32_t)reg_cfg; + WWDGT_CTL = (uint32_t)reg_ctl; +} + +/*! + \brief enable early wakeup interrupt of WWDGT + \param[in] none + \param[out] none + \retval none +*/ +void wwdgt_interrupt_enable(void) +{ + WWDGT_CFG |= WWDGT_CFG_EWIE; +} + +/*! + \brief check early wakeup interrupt state of WWDGT + \param[in] none + \param[out] none + \retval FlagStatus: SET or RESET +*/ +FlagStatus wwdgt_flag_get(void) +{ + if(RESET != (WWDGT_STAT & WWDGT_STAT_EWIF)){ + return SET; + } + return RESET; +} + +/*! + \brief clear early wakeup interrupt state of WWDGT + \param[in] none + \param[out] none + \retval none +*/ +void wwdgt_flag_clear(void) +{ + WWDGT_STAT &= (uint32_t)(~(uint32_t)WWDGT_STAT_EWIF); +} diff --git a/bsp/gd32e230k-start/Libraries/SConscript b/bsp/gd32e230k-start/Libraries/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..e79dc3421667b57e1e8e755fdfa57ae0c867a111 --- /dev/null +++ b/bsp/gd32e230k-start/Libraries/SConscript @@ -0,0 +1,27 @@ +import rtconfig +from building import * + +# get current directory +cwd = GetCurrentDir() + +# The set of source files associated with this SConscript file. + +src = Glob('GD32E230_standard_peripheral/Source/*.c') +src += [cwd + '/CMSIS/GD/GD32E230/Source/system_gd32e230.c'] + +#add for startup script +if rtconfig.CROSS_TOOL == 'keil': + src += [cwd + '/CMSIS/GD/GD32E230/Source/ARM/startup_gd32e230.s'] +elif rtconfig.CROSS_TOOL == 'iar': + src += [cwd + '/CMSIS/GD/GD32E230/Source/IAR/startup_gd32e230.s'] + +path = [ + cwd + '/CMSIS/GD/GD32E230/Include', + cwd + '/CMSIS', + cwd + '/GD32E230_standard_peripheral/Include',] + +CPPDEFINES = ['GD32E230'] + +group = DefineGroup('GD32_Lib', src, depend = [''], CPPPATH = path, CPPDEFINES = CPPDEFINES) + +Return('group') diff --git a/bsp/gd32e230k-start/README.md b/bsp/gd32e230k-start/README.md new file mode 100644 index 0000000000000000000000000000000000000000..1b676bc0b4ddb15e61490698108948b559b585ae --- /dev/null +++ b/bsp/gd32e230k-start/README.md @@ -0,0 +1,51 @@ +# GD32E230K-START # + +## 1. 简介 + +[GD32E230K-START](http://gd32mcu.21ic.com/site)是兆易科技提供的开发板,使用 Cortex-M23 内核的 GD32E230K8T6 作为主控制器。提供包括扩展引脚及板载 GD-Link 仿真器等外设资源。除 GD32E230K-START(32引脚)外,GD32E230 系列 START 开发板还有 GD32E230C-START(48引脚)、GD32E230G-START(28引脚)、GD32E230F-START(20引脚),四种开发板程序可以通用,可能需要改变部分引脚定义。 + +板载主要资源如下: + +| 硬件 | 描述 | +| -- | -- | +|CPU| Cortex-M23| +|主频| 72MHz | +|SRAM| 8KB | +|Flash| 64KB | + +## 2. 编译说明 + +GD32E230K-START板级包支持 MDK5,以下是具体版本信息: +注:Cortex-M23 内核只支持 ARM Compiler 6 (Armclang),并不支持 ARM Compiler 5 (armcc)。 + +| IDE/编译器 | 已测试版本 | +| -- | -- | +| MDK5(ARM Compiler 6) | MDK5.27 | + +## 3. 烧写及执行 + +下载程序:使用板载 GD-Link 工具。 + +### 3.1 配置和仿真 + +工程已经默认使能了RT-Thread UART驱动、GPIO驱动、SPI驱动、I2C驱动。若想进一步配置工程请 +使用ENV工具。 + +## 4. 驱动支持情况及计划 + +| 驱动 | 支持情况 | 备注 | +| ------ | ---- | :------: | +| UART | 支持 | USART0/1 | +| GPIO | 支持 | | +| SPI | 支持 | SPI0/1 | +| I2C | 支持 | I2C0/1 | + +## 5. 联系人信息 + +维护人: + +- [xuzhuoyi](https://github.com/xuzhuoyi) + +## 6. 参考 + +* [GD32E230K-START](http://gd32mcu.21ic.com/site) diff --git a/bsp/gd32e230k-start/SConscript b/bsp/gd32e230k-start/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..20f7689c53ca71a676748f79187f9764065466c5 --- /dev/null +++ b/bsp/gd32e230k-start/SConscript @@ -0,0 +1,15 @@ +# for module compiling +import os +Import('RTT_ROOT') +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/gd32e230k-start/SConstruct b/bsp/gd32e230k-start/SConstruct new file mode 100644 index 0000000000000000000000000000000000000000..57a8ac59fc3cc45c641e1ec26a51c4ade355160d --- /dev/null +++ b/bsp/gd32e230k-start/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-gd32f230.' + 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/gd32e230k-start/applications/SConscript b/bsp/gd32e230k-start/applications/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..b03718e857a664ccf66db568e00fbc995b5b8917 --- /dev/null +++ b/bsp/gd32e230k-start/applications/SConscript @@ -0,0 +1,9 @@ +from building import * + +cwd = GetCurrentDir() +src = Glob('*.c') +CPPPATH = [cwd] + +group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/gd32e230k-start/applications/main.c b/bsp/gd32e230k-start/applications/main.c new file mode 100644 index 0000000000000000000000000000000000000000..cabddf36d61e182a3873c9f11a479135a773d9f1 --- /dev/null +++ b/bsp/gd32e230k-start/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 + * 2015-07-29 Arda.Fu first implementation + */ +#include +#include + +int main(void) +{ + /* user app entry */ + + return 0; +} diff --git a/bsp/gd32e230k-start/drivers/SConscript b/bsp/gd32e230k-start/drivers/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..df3af3519ee376911a1a8329659db3d9fcb5b587 --- /dev/null +++ b/bsp/gd32e230k-start/drivers/SConscript @@ -0,0 +1,27 @@ +from building import * + +cwd = GetCurrentDir() + +# add the general drivers. +src = Split(""" +board.c +drv_usart.c +""") + +CPPPATH = [cwd] + +# add spi drivers. +if GetDepend('RT_USING_SPI'): + src += ['drv_spi.c'] + +# add i2c drivers. +if GetDepend('RT_USING_I2C'): + src += ['drv_i2c.c'] + +# add pin drivers. +if GetDepend('RT_USING_PIN'): + src += ['drv_gpio.c'] + +group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/gd32e230k-start/drivers/board.c b/bsp/gd32e230k-start/drivers/board.c new file mode 100644 index 0000000000000000000000000000000000000000..ea91fd7eb818cc8b5c462251514f88398ac6c0c3 --- /dev/null +++ b/bsp/gd32e230k-start/drivers/board.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2009-01-05 Bernard first implementation + */ +#include +#include +#include +#include + +/** + * @brief This function is executed in case of error occurrence. + * @param None + * @retval None + */ +void Error_Handler(void) +{ + /* USER CODE BEGIN Error_Handler */ + /* User can add his own implementation to report the HAL error return state */ + while (1) + { + } + /* USER CODE END Error_Handler */ +} + +/** System Clock Configuration +*/ +void SystemClock_Config(void) +{ + SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND); + NVIC_SetPriority(SysTick_IRQn, 0); +} + +/** + * 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 GD32 board. + */ +void rt_hw_board_init() +{ + /* NVIC Configuration */ +#define NVIC_VTOR_MASK 0x3FFFFF80 +#ifdef VECT_TAB_RAM + /* Set the Vector Table base location at 0x10000000 */ + SCB->VTOR = (0x10000000 & NVIC_VTOR_MASK); +#else /* VECT_TAB_FLASH */ + /* Set the Vector Table base location at 0x08000000 */ + SCB->VTOR = (0x08000000 & NVIC_VTOR_MASK); +#endif + + SystemClock_Config(); + +#ifdef RT_USING_COMPONENTS_INIT + rt_components_board_init(); +#endif + +#ifdef RT_USING_CONSOLE + rt_console_set_device(RT_CONSOLE_DEVICE_NAME); +#endif + +#ifdef RT_USING_HEAP + rt_system_heap_init((void*)HEAP_BEGIN, (void*)HEAP_END); +#endif +} + +/*@}*/ diff --git a/bsp/gd32e230k-start/drivers/board.h b/bsp/gd32e230k-start/drivers/board.h new file mode 100644 index 0000000000000000000000000000000000000000..5097fb169e1caed49a3a156e2d7f1e957a0c9dc6 --- /dev/null +++ b/bsp/gd32e230k-start/drivers/board.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2009-09-22 Bernard add board.h to this bsp + */ + +// <<< Use Configuration Wizard in Context Menu >>> +#ifndef __BOARD_H__ +#define __BOARD_H__ + +#include + +// Internal SRAM memory size[Kbytes] <8-64> +// Default: 64 +#ifdef __ICCARM__ +// Use *.icf ram symbal, to avoid hardcode. +extern char __ICFEDIT_region_RAM_end__; +#define GD32_SRAM_END &__ICFEDIT_region_RAM_end__ +#else +#define GD32_SRAM_SIZE 8 +#define GD32_SRAM_END (0x20000000 + GD32_SRAM_SIZE * 1024) +#endif + +#ifdef __ARMCC_VERSION +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 int __bss_end; +#define HEAP_BEGIN (&__bss_end) +#endif + +#define HEAP_END GD32_SRAM_END + +#endif + +//*** <<< end of configuration section >>> *** diff --git a/bsp/gd32e230k-start/drivers/drv_gpio.c b/bsp/gd32e230k-start/drivers/drv_gpio.c new file mode 100644 index 0000000000000000000000000000000000000000..521db3823baf990cd9bdefaf94d43ff1d2b59d9f --- /dev/null +++ b/bsp/gd32e230k-start/drivers/drv_gpio.c @@ -0,0 +1,471 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2017-10-20 ZYH the first version + * 2018-04-23 misonyo port to gd32f30x + * 2019-03-31 xuzhuoyi Porting for gd32e230 + */ + +#include "drv_gpio.h" +#include +#include +#include "gd32e230.h" +#include "gd32e230_exti.h" + +#ifdef RT_USING_PIN + +#define __GD32_PIN(index, port, pin) {index, RCU_GPIO##port, GPIO##port, \ + GPIO_PIN_##pin, EXTI_SOURCE_GPIO##port, EXTI_SOURCE_PIN##pin} +#define __GD32_PIN_DEFAULT {-1, (rcu_periph_enum)0, 0, 0, 0, 0} + +/* GD32 GPIO driver */ +struct pin_index +{ + rt_int16_t index; + rcu_periph_enum clk; + rt_uint32_t gpio_periph; + rt_uint32_t pin; + rt_uint32_t port_src; + rt_uint32_t pin_src; +}; + +static const struct pin_index pins[] = +{ + __GD32_PIN_DEFAULT, + __GD32_PIN(2, F, 0), + __GD32_PIN(3, F, 1), + __GD32_PIN_DEFAULT, + __GD32_PIN_DEFAULT, + __GD32_PIN(6, A, 0), + __GD32_PIN(7, A, 1), + __GD32_PIN(8, A, 2), + __GD32_PIN(9, A, 3), + __GD32_PIN(10, A, 4), + __GD32_PIN(11, A, 5), + __GD32_PIN(12, A, 6), + __GD32_PIN(13, A, 7), + __GD32_PIN(14, B, 0), + __GD32_PIN(15, B, 1), + __GD32_PIN(16, B, 2), + __GD32_PIN_DEFAULT, + __GD32_PIN(18, A, 8), + __GD32_PIN(19, A, 9), + __GD32_PIN(20, A, 10), + __GD32_PIN(21, A, 11), + __GD32_PIN(22, A, 12), + __GD32_PIN(23, A, 13), + __GD32_PIN(24, A, 14), + __GD32_PIN(25, A, 15), + __GD32_PIN(26, B, 3), + __GD32_PIN(27, B, 4), + __GD32_PIN(28, B, 5), + __GD32_PIN(29, B, 6), + __GD32_PIN(30, B, 7), + __GD32_PIN_DEFAULT, + __GD32_PIN(32, B, 8), +}; + +struct pin_irq_map +{ + rt_uint16_t pinbit; + IRQn_Type irqno; +}; +static const struct pin_irq_map pin_irq_map[] = +{ + {GPIO_PIN_0, EXTI0_1_IRQn}, + {GPIO_PIN_1, EXTI0_1_IRQn}, + {GPIO_PIN_2, EXTI2_3_IRQn}, + {GPIO_PIN_3, EXTI2_3_IRQn}, + {GPIO_PIN_4, EXTI4_15_IRQn}, + {GPIO_PIN_5, EXTI4_15_IRQn}, + {GPIO_PIN_6, EXTI4_15_IRQn}, + {GPIO_PIN_7, EXTI4_15_IRQn}, + {GPIO_PIN_8, EXTI4_15_IRQn}, + {GPIO_PIN_9, EXTI4_15_IRQn}, + {GPIO_PIN_10, EXTI4_15_IRQn}, + {GPIO_PIN_11, EXTI4_15_IRQn}, + {GPIO_PIN_12, EXTI4_15_IRQn}, + {GPIO_PIN_13, EXTI4_15_IRQn}, + {GPIO_PIN_14, EXTI4_15_IRQn}, + {GPIO_PIN_15, EXTI4_15_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(rt_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 gd32_pin_mode(rt_device_t dev, rt_base_t pin, rt_base_t mode) +{ + const struct pin_index *index; + rt_uint32_t pin_mode; + rt_uint32_t otype; + rt_uint32_t pull_up_down; + index = get_pin(pin); + if (index == RT_NULL) + { + return; + } + + /* GPIO Periph clock enable */ + rcu_periph_clock_enable(index->clk); + pin_mode = GPIO_MODE_OUTPUT; + otype = GPIO_OTYPE_PP; + pull_up_down = GPIO_PUPD_NONE; + + switch(mode) + { + case PIN_MODE_OUTPUT: + /* output setting */ + break; + case PIN_MODE_OUTPUT_OD: + /* output setting: od. */ + otype = GPIO_OTYPE_OD; + break; + case PIN_MODE_INPUT: + /* input setting: not pull. */ + pin_mode = GPIO_MODE_INPUT; + break; + case PIN_MODE_INPUT_PULLUP: + /* input setting: pull up. */ + pin_mode = GPIO_MODE_INPUT; + pull_up_down = GPIO_PUPD_PULLUP; + break; + case PIN_MODE_INPUT_PULLDOWN: + /* input setting: pull down. */ + pin_mode = GPIO_MODE_INPUT; + pull_up_down = GPIO_PUPD_PULLDOWN; + break; + default: + break; + } + + gpio_mode_set(index->gpio_periph, pin_mode, pull_up_down, index->pin); + gpio_output_options_set(index->gpio_periph, otype, GPIO_OSPEED_50MHZ, index->pin); + +} + +void gd32_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; + } + + gpio_bit_write(index->gpio_periph, index->pin, (bit_status)value); +} + +int gd32_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; + } + + value = gpio_input_bit_get(index->gpio_periph, index->pin); + + return value; +} + + +rt_inline rt_int32_t bit2bitno(rt_uint32_t bit) +{ + rt_uint8_t i; + for (i = 0; i < 32; i++) + { + if ((0x01 << i) == bit) + { + return i; + } + } + return -1; +} +rt_inline const struct pin_irq_map *get_pin_irq_map(rt_uint32_t pinbit) +{ + rt_int32_t mapindex = bit2bitno(pinbit); + if (mapindex < 0 || mapindex >= ITEM_NUM(pin_irq_map)) + { + return RT_NULL; + } + return &pin_irq_map[mapindex]; +}; +rt_err_t gd32_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 hdr_index = -1; + + index = get_pin(pin); + if (index == RT_NULL) + { + return RT_EINVAL; + } + hdr_index = bit2bitno(index->pin); + if (hdr_index < 0 || hdr_index >= ITEM_NUM(pin_irq_map)) + { + return RT_EINVAL; + } + + level = rt_hw_interrupt_disable(); + if (pin_irq_hdr_tab[hdr_index].pin == pin && + pin_irq_hdr_tab[hdr_index].hdr == hdr && + pin_irq_hdr_tab[hdr_index].mode == mode && + pin_irq_hdr_tab[hdr_index].args == args) + { + rt_hw_interrupt_enable(level); + return RT_EOK; + } + if (pin_irq_hdr_tab[hdr_index].pin != -1) + { + rt_hw_interrupt_enable(level); + return RT_EFULL; + } + pin_irq_hdr_tab[hdr_index].pin = pin; + pin_irq_hdr_tab[hdr_index].hdr = hdr; + pin_irq_hdr_tab[hdr_index].mode = mode; + pin_irq_hdr_tab[hdr_index].args = args; + rt_hw_interrupt_enable(level); + + return RT_EOK; +} +rt_err_t gd32_pin_detach_irq(struct rt_device *device, rt_int32_t pin) +{ + const struct pin_index *index; + rt_base_t level; + rt_int32_t hdr_index = -1; + + index = get_pin(pin); + if (index == RT_NULL) + { + return RT_EINVAL; + } + hdr_index = bit2bitno(index->pin); + if (hdr_index < 0 || hdr_index >= ITEM_NUM(pin_irq_map)) + { + return RT_EINVAL; + } + + level = rt_hw_interrupt_disable(); + if (pin_irq_hdr_tab[hdr_index].pin == -1) + { + rt_hw_interrupt_enable(level); + return RT_EOK; + } + pin_irq_hdr_tab[hdr_index].pin = -1; + pin_irq_hdr_tab[hdr_index].hdr = RT_NULL; + pin_irq_hdr_tab[hdr_index].mode = 0; + pin_irq_hdr_tab[hdr_index].args = RT_NULL; + rt_hw_interrupt_enable(level); + + return RT_EOK; +} +rt_err_t gd32_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; + rt_base_t level; + rt_int32_t hdr_index = -1; + exti_trig_type_enum trigger_mode; + + index = get_pin(pin); + if (index == RT_NULL) + { + return RT_EINVAL; + } + if (enabled == PIN_IRQ_ENABLE) + { + hdr_index = bit2bitno(index->pin); + if (hdr_index < 0 || hdr_index >= ITEM_NUM(pin_irq_map)) + { + return RT_EINVAL; + } + level = rt_hw_interrupt_disable(); + if (pin_irq_hdr_tab[hdr_index].pin == -1) + { + rt_hw_interrupt_enable(level); + return RT_EINVAL; + } + irqmap = &pin_irq_map[hdr_index]; + + switch (pin_irq_hdr_tab[hdr_index].mode) + { + case PIN_IRQ_MODE_RISING: + trigger_mode = EXTI_TRIG_RISING; + break; + case PIN_IRQ_MODE_FALLING: + trigger_mode = EXTI_TRIG_FALLING; + break; + case PIN_IRQ_MODE_RISING_FALLING: + trigger_mode = EXTI_TRIG_BOTH; + break; + default: + rt_hw_interrupt_enable(level); + return RT_EINVAL; + } + + //rcu_periph_clock_enable(RCU_AF); + + /* enable and set interrupt priority */ + nvic_irq_enable(irqmap->irqno, 5U); + + /* connect EXTI line to GPIO pin */ + syscfg_exti_line_config(index->port_src, index->pin_src); + + /* configure EXTI line */ + exti_init((exti_line_enum)(index->pin), EXTI_INTERRUPT, trigger_mode); + exti_interrupt_flag_clear((exti_line_enum)(index->pin)); + + rt_hw_interrupt_enable(level); + } + else if (enabled == PIN_IRQ_DISABLE) + { + irqmap = get_pin_irq_map(index->pin); + if (irqmap == RT_NULL) + { + return RT_EINVAL; + } + nvic_irq_disable(irqmap->irqno); + } + else + { + return RT_EINVAL; + } + + return RT_EOK; +} +const static struct rt_pin_ops _gd32_pin_ops = +{ + gd32_pin_mode, + gd32_pin_write, + gd32_pin_read, + gd32_pin_attach_irq, + gd32_pin_detach_irq, + gd32_pin_irq_enable, +}; + +int rt_hw_pin_init(void) +{ + int result; + + result = rt_device_pin_register("pin", &_gd32_pin_ops, RT_NULL); + + return result; +} +INIT_BOARD_EXPORT(rt_hw_pin_init); + +rt_inline void pin_irq_hdr(int irqno) +{ + if (pin_irq_hdr_tab[irqno].hdr) + { + pin_irq_hdr_tab[irqno].hdr(pin_irq_hdr_tab[irqno].args); + } +} + +void GD32_GPIO_EXTI_IRQHandler(rt_int8_t exti_line) +{ + if(RESET != exti_interrupt_flag_get((exti_line_enum)(1 << exti_line))) + { + pin_irq_hdr(exti_line); + exti_interrupt_flag_clear((exti_line_enum)(1 << exti_line)); + } +} +void EXTI0_IRQHandler(void) +{ + rt_interrupt_enter(); + GD32_GPIO_EXTI_IRQHandler(0); + rt_interrupt_leave(); +} +void EXTI1_IRQHandler(void) +{ + rt_interrupt_enter(); + GD32_GPIO_EXTI_IRQHandler(1); + rt_interrupt_leave(); +} +void EXTI2_IRQHandler(void) +{ + rt_interrupt_enter(); + GD32_GPIO_EXTI_IRQHandler(2); + rt_interrupt_leave(); +} +void EXTI3_IRQHandler(void) +{ + rt_interrupt_enter(); + GD32_GPIO_EXTI_IRQHandler(3); + rt_interrupt_leave(); +} +void EXTI4_IRQHandler(void) +{ + rt_interrupt_enter(); + GD32_GPIO_EXTI_IRQHandler(4); + rt_interrupt_leave(); +} +void EXTI5_9_IRQHandler(void) +{ + rt_interrupt_enter(); + GD32_GPIO_EXTI_IRQHandler(5); + GD32_GPIO_EXTI_IRQHandler(6); + GD32_GPIO_EXTI_IRQHandler(7); + GD32_GPIO_EXTI_IRQHandler(8); + GD32_GPIO_EXTI_IRQHandler(9); + rt_interrupt_leave(); +} +void EXTI10_15_IRQHandler(void) +{ + rt_interrupt_enter(); + GD32_GPIO_EXTI_IRQHandler(10); + GD32_GPIO_EXTI_IRQHandler(11); + GD32_GPIO_EXTI_IRQHandler(12); + GD32_GPIO_EXTI_IRQHandler(13); + GD32_GPIO_EXTI_IRQHandler(14); + GD32_GPIO_EXTI_IRQHandler(15); + rt_interrupt_leave(); +} + +#endif diff --git a/bsp/gd32e230k-start/drivers/drv_gpio.h b/bsp/gd32e230k-start/drivers/drv_gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..3c758b27132c085bcca723c946a4f2b7500dcf88 --- /dev/null +++ b/bsp/gd32e230k-start/drivers/drv_gpio.h @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2015-01-05 Bernard the first version + */ +#ifndef GPIO_H__ +#define GPIO_H__ + + +#endif diff --git a/bsp/gd32e230k-start/drivers/drv_i2c.c b/bsp/gd32e230k-start/drivers/drv_i2c.c new file mode 100644 index 0000000000000000000000000000000000000000..473a2b1bda2346b23c07c2027c1e6146d8b270ba --- /dev/null +++ b/bsp/gd32e230k-start/drivers/drv_i2c.c @@ -0,0 +1,381 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2017-06-05 tanek first implementation. + * 2018-04-19 misonyo Porting for gd32f30x + * 2019-03-31 xuzhuoyi Porting for gd32e230 + */ + +#include "drv_i2c.h" +#include +#include "gd32e230.h" + +#ifdef RT_USING_I2C + +#include + +#ifdef RT_USING_I2C_BITOPS + +/*user can change this*/ +#define I2C_BUS_NAME "i2c2" + +/*user should change this to adapt specific board*/ +#define I2C_SCL_PIN GPIO_PIN_4 +#define I2C_SCL_PORT GPIOE +#define I2C_SCL_CLK RCU_GPIOE +#define I2C_SDA_PIN GPIO_PIN_5 +#define I2C_SDA_PORT GPIOE +#define I2C_SDA_CLK RCU_GPIOE + +struct gd32_i2c_bit_data +{ + struct + { + rcu_periph_enum clk; + rt_uint32_t port; + rt_uint32_t pin; + }scl, sda; +}; + +static void gpio_set_sda(void *data, rt_int32_t state) +{ + struct gd32_i2c_bit_data* bd = data; + + if (state) + { + gpio_bit_set(bd->sda.port, bd->sda.pin); + } + else + { + gpio_bit_reset(bd->sda.port, bd->sda.pin); + } +} + +static void gpio_set_scl(void *data, rt_int32_t state) +{ + struct gd32_i2c_bit_data* bd = data; + if (state) + { + gpio_bit_set(bd->scl.port, bd->scl.pin); + } + else + { + gpio_bit_reset(bd->scl.port, bd->scl.pin); + } +} + +static rt_int32_t gpio_get_sda(void *data) +{ + struct gd32_i2c_bit_data* bd = data; + + return gpio_input_bit_get(bd->sda.port, bd->sda.pin); +} + +static rt_int32_t gpio_get_scl(void *data) +{ + struct gd32_i2c_bit_data* bd = data; + + return gpio_input_bit_get(bd->scl.port, bd->scl.pin); +} + +static void gpio_udelay(rt_uint32_t us) +{ + int i = ( rcu_clock_freq_get(CK_SYS) / 4000000 * us); + while(i) + { + i--; + } +} + +static void drv_i2c_gpio_init(const struct gd32_i2c_bit_data* bd) +{ + rcu_periph_clock_enable(bd->sda.clk); + rcu_periph_clock_enable(bd->scl.clk); + gpio_init(bd->sda.port, GPIO_MODE_OUT_OD, GPIO_OSPEED_10MHZ, bd->sda.pin); + gpio_init(bd->scl.port, GPIO_MODE_OUT_OD, GPIO_OSPEED_10MHZ, bd->scl.pin); + + gpio_bit_set(bd->sda.port, bd->sda.pin); + gpio_bit_set(bd->scl.port, bd->scl.pin); +} + +#else /* use hardware i2c */ + +struct gd32_i2c_bus +{ + struct rt_i2c_bus_device parent; + rt_uint32_t i2c_periph; +}; + +static int gd32_i2c_read(rt_uint32_t i2c_periph, rt_uint16_t slave_address, rt_uint8_t* p_buffer, rt_uint16_t data_byte) +{ + /* wait until I2C bus is idle */ + while(i2c_flag_get(i2c_periph, I2C_FLAG_I2CBSY)); + + /* send a start condition to I2C bus */ + i2c_start_on_bus(i2c_periph); + + /* wait until SBSEND bit is set */ + while(!i2c_flag_get(i2c_periph, I2C_FLAG_SBSEND)); + + /* send slave address to I2C bus */ + i2c_master_addressing(i2c_periph, slave_address<<1, I2C_RECEIVER); + + /* wait until ADDSEND bit is set */ + while(!i2c_flag_get(i2c_periph, I2C_FLAG_ADDSEND)); + + /* clear the ADDSEND bit */ + i2c_flag_clear(i2c_periph,I2C_FLAG_ADDSEND); + + if(1 == data_byte){ + /* disable acknowledge */ + i2c_ack_config(i2c_periph,I2C_ACK_DISABLE); + /* send a stop condition to I2C bus */ + i2c_stop_on_bus(i2c_periph); + } + + /* while there is data to be read */ + while(data_byte) + { + /* wait until the RBNE bit is set and clear it */ + if(i2c_flag_get(i2c_periph, I2C_FLAG_RBNE)) + { + /* read a byte from the EEPROM */ + *p_buffer = i2c_data_receive(i2c_periph); + + /* point to the next location where the byte read will be saved */ + p_buffer++; + + /* decrement the read bytes counter */ + data_byte--; + if(1 == data_byte) + { + /* disable acknowledge */ + i2c_ack_config(i2c_periph,I2C_ACK_DISABLE); + /* send a stop condition to I2C bus */ + i2c_stop_on_bus(i2c_periph); + } + } + } + + /* wait until the stop condition is finished */ + while(I2C_CTL0(i2c_periph)&0x0200); + + /* enable acknowledge */ + i2c_ack_config(i2c_periph,I2C_ACK_ENABLE); + + i2c_ackpos_config(i2c_periph,I2C_ACKPOS_CURRENT); + + return 0; +} + +static int gd32_i2c_write(rt_uint32_t i2c_periph, uint16_t slave_address, uint8_t* p_buffer, uint16_t data_byte) +{ + /* wait until I2C bus is idle */ + while(i2c_flag_get(i2c_periph, I2C_FLAG_I2CBSY)); + + /* send a start condition to I2C bus */ + i2c_start_on_bus(i2c_periph); + + /* wait until SBSEND bit is set */ + while(!i2c_flag_get(i2c_periph, I2C_FLAG_SBSEND)); + + /* send slave address to I2C bus */ + i2c_master_addressing(i2c_periph, slave_address<<1, I2C_TRANSMITTER); + + /* wait until ADDSEND bit is set */ + while(!i2c_flag_get(i2c_periph, I2C_FLAG_ADDSEND)); + + /* clear the ADDSEND bit */ + i2c_flag_clear(i2c_periph,I2C_FLAG_ADDSEND); + + /* wait until the transmit data buffer is empty */ + while(SET != i2c_flag_get( i2c_periph , I2C_FLAG_TBE)); + + /* while there is data to be read */ + while(data_byte) + { + i2c_data_transmit(i2c_periph, *p_buffer); + + /* point to the next byte to be written */ + p_buffer++; + + /* decrement the write bytes counter */ + data_byte --; + + /* wait until BTC bit is set */ + while(!i2c_flag_get(i2c_periph, I2C_FLAG_BTC)); + } + + /* send a stop condition to I2C bus */ + i2c_stop_on_bus(i2c_periph); + + /* wait until the stop condition is finished */ + while(I2C_CTL0(i2c_periph)&0x0200); + + return 0; +} + +static rt_size_t gd32_i2c_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; + + struct gd32_i2c_bus *gd32_i2c = (struct gd32_i2c_bus *)bus; + + for (i = 0; i < num; i++) + { + msg = &msgs[i]; + + if (msg->flags & RT_I2C_ADDR_10BIT) + { + i2c_mode_addr_config(gd32_i2c->i2c_periph,I2C_I2CMODE_ENABLE,I2C_ADDFORMAT_10BITS,0); + } + else + { + i2c_mode_addr_config(gd32_i2c->i2c_periph,I2C_I2CMODE_ENABLE,I2C_ADDFORMAT_7BITS,0); + } + if (msg->flags & RT_I2C_RD) + { + if (gd32_i2c_read(gd32_i2c->i2c_periph, msg->addr, msg->buf, msg->len) != 0) + { + i2c_dbg("i2c bus write failed,i2c bus stop!\n"); + goto out; + } + } + else + { + if (gd32_i2c_write(gd32_i2c->i2c_periph, msg->addr, msg->buf, msg->len) != 0) + { + i2c_dbg("i2c bus write failed,i2c bus stop!\n"); + goto out; + } + } + } + + ret = i; + +out: + i2c_dbg("send stop condition\n"); + + return ret; +} + +static const struct rt_i2c_bus_device_ops i2c_ops = +{ + gd32_i2c_xfer, + RT_NULL, + RT_NULL +}; + +#endif /* RT_USING_I2C_BITOPS */ + +int rt_hw_i2c_init(void) +{ +#ifdef RT_USING_I2C_BITOPS + { + static struct rt_i2c_bus_device i2c_device; + static const struct gd32_i2c_bit_data _i2c_bdata = + { + /* SCL */ + { I2C_SCL_CLK, I2C_SCL_PORT, I2C_SCL_PIN}, + /* SDA */ + { I2C_SDA_CLK, I2C_SDA_PORT, I2C_SDA_PIN}, + }; + + static const struct rt_i2c_bit_ops _i2c_bit_ops = + { + (void*)&_i2c_bdata, + gpio_set_sda, + gpio_set_scl, + gpio_get_sda, + gpio_get_scl, + gpio_udelay, + 1, + 100 + }; + + drv_i2c_gpio_init(&_i2c_bdata); + + i2c_device.priv = (void *)&_i2c_bit_ops; + rt_i2c_bit_add_bus(&i2c_device, I2C_BUS_NAME); + } + +#else /* register hardware I2C */ + +#ifdef RT_USING_I2C0 +#define I2C0_SPEED 100000 + + static struct gd32_i2c_bus gd32_i2c0; + /* enable GPIOB clock */ + rcu_periph_clock_enable(RCU_GPIOB); + + /* connect PB6 to I2C0_SCL */ + gpio_af_set(GPIOB, GPIO_AF_1, GPIO_PIN_6); + /* connect PB7 to I2C0_SDA */ + gpio_af_set(GPIOB, GPIO_AF_1, GPIO_PIN_7); + /* configure GPIO pins of I2C0 */ + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_6); + gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ,GPIO_PIN_6); + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_7); + gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ,GPIO_PIN_7); + + /* enable I2C clock */ + rcu_periph_clock_enable(RCU_I2C0); + /* configure I2C clock */ + i2c_clock_config(I2C0,I2C0_SPEED,I2C_DTCY_2); + + i2c_enable(I2C0); + /* enable acknowledge */ + i2c_ack_config(I2C0,I2C_ACK_ENABLE); + + rt_memset((void *)&gd32_i2c0, 0, sizeof(struct gd32_i2c_bus)); + gd32_i2c0.parent.ops = &i2c_ops; + gd32_i2c0.i2c_periph = I2C0; + rt_i2c_bus_device_register(&gd32_i2c0.parent, "i2c0"); +#endif + +#ifdef RT_USING_I2C1 +#define I2C1_SPEED 100000 + + static struct gd32_i2c_bus gd32_i2c1; + /* enable GPIOB clock */ + rcu_periph_clock_enable(RCU_GPIOB); + + /* connect PB10 to I2C1_SCL */ + gpio_af_set(GPIOB, GPIO_AF_1, GPIO_PIN_10); + /* connect PB11 to I2C1_SDA */ + gpio_af_set(GPIOB, GPIO_AF_1, GPIO_PIN_11); + /* configure GPIO pins of I2C1 */ + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_10); + gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ,GPIO_PIN_10); + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_11); + gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ,GPIO_PIN_11); + + /* enable I2C clock */ + rcu_periph_clock_enable(RCU_I2C1); + /* configure I2C clock */ + i2c_clock_config(I2C1,I2C1_SPEED,I2C_DTCY_2); + + i2c_enable(I2C1); + /* enable acknowledge */ + i2c_ack_config(I2C1,I2C_ACK_ENABLE); + + rt_memset((void *)&gd32_i2c1, 0, sizeof(struct gd32_i2c_bus)); + gd32_i2c1.parent.ops = &i2c_ops; + gd32_i2c1.i2c_periph = I2C1; + rt_i2c_bus_device_register(&gd32_i2c1.parent, "i2c1"); +#endif + +#endif /* RT_USING_I2C_BITOPS */ + + return 0; +} +INIT_DEVICE_EXPORT(rt_hw_i2c_init); + +#endif +/* end of i2c driver */ diff --git a/bsp/gd32e230k-start/drivers/drv_i2c.h b/bsp/gd32e230k-start/drivers/drv_i2c.h new file mode 100644 index 0000000000000000000000000000000000000000..6e7de45260befeb2460a4b908a3a87b1843e1d65 --- /dev/null +++ b/bsp/gd32e230k-start/drivers/drv_i2c.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2017-06-05 tanek first implementation. + */ + +#ifndef __DRV_I2C__ +#define __DRV_I2C__ + + +#endif diff --git a/bsp/gd32e230k-start/drivers/drv_spi.c b/bsp/gd32e230k-start/drivers/drv_spi.c new file mode 100644 index 0000000000000000000000000000000000000000..706756d3de93ba9617271b08a18b95bb7206e07a --- /dev/null +++ b/bsp/gd32e230k-start/drivers/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 + * 2017-06-05 tanek first implementation. + * 2018-04-19 misonyo Porting for gd32f30x + * 2019-03-31 xuzhuoyi Porting for gd32e230 + */ + +#include "drv_spi.h" +#include "gd32e230.h" +#include + +#if defined(RT_USING_SPI) && defined(RT_USING_PIN) +#include + +#if !defined(RT_USING_SPI0) && !defined(RT_USING_SPI1) +#error "Please define at least one SPIx" +#endif + +/* #define DEBUG */ +#ifdef DEBUG +#define DEBUG_PRINTF(...) rt_kprintf(__VA_ARGS__) +#else +#define DEBUG_PRINTF(...) +#endif + +/* private rt-thread spi ops function */ +static rt_err_t configure(struct rt_spi_device* device, struct rt_spi_configuration* configuration); +static rt_uint32_t xfer(struct rt_spi_device* device, struct rt_spi_message* message); + +static struct rt_spi_ops gd32_spi_ops = +{ + configure, + xfer +}; + +static rt_err_t configure(struct rt_spi_device* device, struct rt_spi_configuration* configuration) +{ + spi_parameter_struct spi_init_struct; + + rt_uint32_t spi_periph = (rt_uint32_t)device->bus->parent.user_data; + + RT_ASSERT(device != RT_NULL); + RT_ASSERT(configuration != RT_NULL); + + if(configuration->data_width <= 8) + { + spi_init_struct.frame_size = SPI_FRAMESIZE_8BIT; + } + else if(configuration->data_width <= 16) + { + spi_init_struct.frame_size = SPI_FRAMESIZE_16BIT; + } + else + { + return RT_EIO; + } + + { + rcu_clock_freq_enum spi_src; + rt_uint32_t spi_apb_clock; + rt_uint32_t max_hz; + + max_hz = configuration->max_hz; + + DEBUG_PRINTF("sys freq: %d\n", rcu_clock_freq_get(CK_SYS)); + DEBUG_PRINTF("CK_APB2 freq: %d\n", rcu_clock_freq_get(CK_APB2)); + DEBUG_PRINTF("max freq: %d\n", max_hz); + + if (spi_periph == SPI1) + { + spi_src = CK_APB1; + } + else + { + spi_src = CK_APB2; + } + spi_apb_clock = rcu_clock_freq_get(spi_src); + + if(max_hz >= spi_apb_clock/2) + { + spi_init_struct.prescale = SPI_PSC_2; + } + else if (max_hz >= spi_apb_clock/4) + { + spi_init_struct.prescale = SPI_PSC_4; + } + else if (max_hz >= spi_apb_clock/8) + { + spi_init_struct.prescale = SPI_PSC_8; + } + else if (max_hz >= spi_apb_clock/16) + { + spi_init_struct.prescale = SPI_PSC_16; + } + else if (max_hz >= spi_apb_clock/32) + { + spi_init_struct.prescale = SPI_PSC_32; + } + else if (max_hz >= spi_apb_clock/64) + { + spi_init_struct.prescale = SPI_PSC_64; + } + else if (max_hz >= spi_apb_clock/128) + { + spi_init_struct.prescale = SPI_PSC_128; + } + else + { + /* min prescaler 256 */ + spi_init_struct.prescale = SPI_PSC_256; + } + } /* baudrate */ + + switch(configuration->mode & RT_SPI_MODE_3) + { + case RT_SPI_MODE_0: + spi_init_struct.clock_polarity_phase = SPI_CK_PL_LOW_PH_1EDGE; + break; + case RT_SPI_MODE_1: + spi_init_struct.clock_polarity_phase = SPI_CK_PL_LOW_PH_2EDGE; + break; + case RT_SPI_MODE_2: + spi_init_struct.clock_polarity_phase = SPI_CK_PL_HIGH_PH_1EDGE; + break; + case RT_SPI_MODE_3: + spi_init_struct.clock_polarity_phase = SPI_CK_PL_HIGH_PH_2EDGE; + break; + } + + /* MSB or LSB */ + if(configuration->mode & RT_SPI_MSB) + { + spi_init_struct.endian = SPI_ENDIAN_MSB; + } + else + { + spi_init_struct.endian = SPI_ENDIAN_LSB; + } + + spi_init_struct.trans_mode = SPI_TRANSMODE_FULLDUPLEX; + spi_init_struct.device_mode = SPI_MASTER; + spi_init_struct.nss = SPI_NSS_SOFT; + + spi_init(spi_periph, &spi_init_struct); + + spi_crc_off(spi_periph); + + spi_enable(spi_periph); + + return RT_EOK; +}; + +static rt_uint32_t xfer(struct rt_spi_device* device, struct rt_spi_message* message) +{ + rt_base_t gd32_cs_pin = (rt_base_t)device->parent.user_data; + rt_uint32_t spi_periph = (rt_uint32_t)device->bus->parent.user_data; + struct rt_spi_configuration * config = &device->config; + + RT_ASSERT(device != NULL); + RT_ASSERT(message != NULL); + + /* take CS */ + if(message->cs_take) + { + rt_pin_write(gd32_cs_pin, PIN_LOW); + DEBUG_PRINTF("spi take cs\n"); + } + + { + if(config->data_width <= 8) + { + const rt_uint8_t * send_ptr = message->send_buf; + rt_uint8_t * recv_ptr = message->recv_buf; + rt_uint32_t size = message->length; + + DEBUG_PRINTF("spi poll transfer start: %d\n", size); + + while(size--) + { + rt_uint8_t data = 0xFF; + + if(send_ptr != RT_NULL) + { + data = *send_ptr++; + } + + // Todo: replace register read/write by gd32f3 lib + //Wait until the transmit buffer is empty + while(RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_TBE)); + // Send the byte + spi_i2s_data_transmit(spi_periph, data); + + //Wait until a data is received + while(RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_RBNE)); + // Get the received data + data = spi_i2s_data_receive(spi_periph); + + if(recv_ptr != RT_NULL) + { + *recv_ptr++ = data; + } + } + DEBUG_PRINTF("spi poll transfer finsh\n"); + } + else if(config->data_width <= 16) + { + const rt_uint16_t * send_ptr = message->send_buf; + rt_uint16_t * recv_ptr = message->recv_buf; + rt_uint32_t size = message->length; + + while(size--) + { + rt_uint16_t data = 0xFF; + + if(send_ptr != RT_NULL) + { + data = *send_ptr++; + } + + //Wait until the transmit buffer is empty + while(RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_TBE)); + // Send the byte + spi_i2s_data_transmit(spi_periph, data); + + //Wait until a data is received + while(RESET == spi_i2s_flag_get(spi_periph, SPI_FLAG_RBNE)); + // Get the received data + data = spi_i2s_data_receive(spi_periph); + + if(recv_ptr != RT_NULL) + { + *recv_ptr++ = data; + } + } + } + } + + /* release CS */ + if(message->cs_release) + { + rt_pin_write(gd32_cs_pin, PIN_HIGH); + DEBUG_PRINTF("spi release cs\n"); + } + + return message->length; +}; + +int gd32_hw_spi_init(void) +{ + int result = 0; +#ifdef RT_USING_SPI0 + static struct rt_spi_bus spi_bus0; + spi_bus0.parent.user_data = (void *)SPI0; + + result = rt_spi_bus_register(&spi_bus0, "spi0", &gd32_spi_ops); + + rcu_periph_clock_enable(RCU_GPIOA); + rcu_periph_clock_enable(RCU_SPI0); + + /* SPI0 GPIO config: SCK/PA5, MISO/PA6, MOSI/PA7 */ + gpio_af_set(GPIOA, GPIO_AF_0, GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7); + gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7); + gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7); +#endif +#ifdef RT_USING_SPI1 + static struct rt_spi_bus spi_bus1; + spi_bus1.parent.user_data = (void *)SPI1; + + result = rt_spi_bus_register(&spi_bus1, "spi1", &gd32_spi_ops); + + rcu_periph_clock_enable(RCU_SPI1); + rcu_periph_clock_enable(RCU_GPIOB); + + /* SPI1 GPIO config: SCK/PB13, MISO/PB14, MOSI/PB15 */ + gpio_af_set(GPIOB, GPIO_AF_0, GPIO_PIN_13 | GPIO_PIN_14 |GPIO_PIN_15); + gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_13 | GPIO_PIN_14 |GPIO_PIN_15); + gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_13 | GPIO_PIN_14 |GPIO_PIN_15); +#endif + return result; +} +INIT_BOARD_EXPORT(gd32_hw_spi_init); +#endif diff --git a/bsp/gd32e230k-start/drivers/drv_spi.h b/bsp/gd32e230k-start/drivers/drv_spi.h new file mode 100644 index 0000000000000000000000000000000000000000..01bafb9964de814870046517f1280ded38aeaa20 --- /dev/null +++ b/bsp/gd32e230k-start/drivers/drv_spi.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2012-01-01 aozima first implementation. + */ + +#ifndef gd32F30X_SPI_H_INCLUDED +#define gd32F30X_SPI_H_INCLUDED + + +#endif // gd32F30X_SPI_H_INCLUDED diff --git a/bsp/gd32e230k-start/drivers/drv_usart.c b/bsp/gd32e230k-start/drivers/drv_usart.c new file mode 100644 index 0000000000000000000000000000000000000000..c49684de4b59054fd128d28a0835aa866fbd0859 --- /dev/null +++ b/bsp/gd32e230k-start/drivers/drv_usart.c @@ -0,0 +1,298 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2009-01-05 Bernard the first version + * 2018-04-19 misonyo Porting for gd32f30x + * 2019-03-31 xuzhuoyi Porting for gd32e230 + */ + +#include +#include +#include +#include "gd32e230.h" + +#ifdef RT_USING_SERIAL + +#define UART_ENABLE_IRQ(n) NVIC_EnableIRQ((n)) +#define UART_DISABLE_IRQ(n) NVIC_DisableIRQ((n)) + +#if !defined(RT_USING_USART0) && !defined(RT_USING_USART1) +#error "Please define at least one UARTx" + +#endif + +#include + +/* GD32 uart driver */ +// Todo: compress uart info +struct gd32_uart +{ + uint32_t uart_periph; + IRQn_Type irqn; + rcu_periph_enum per_clk; + rcu_periph_enum tx_gpio_clk; + rcu_periph_enum rx_gpio_clk; + uint32_t tx_port; + uint32_t tx_af; + uint16_t tx_pin; + uint32_t rx_port; + uint32_t rx_af; + uint16_t rx_pin; + + struct rt_serial_device * serial; + char *device_name; +}; + +static void uart_isr(struct rt_serial_device *serial); + +#if defined(RT_USING_USART0) +struct rt_serial_device serial0; + +void USART0_IRQHandler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + + uart_isr(&serial0); + + /* leave interrupt */ + rt_interrupt_leave(); +} + +#endif /* RT_USING_USART0 */ + +#if defined(RT_USING_USART1) +struct rt_serial_device serial1; + +void USART1_IRQHandler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + + uart_isr(&serial1); + + /* leave interrupt */ + rt_interrupt_leave(); +} + +#endif /* RT_USING_UART1 */ + +static const struct gd32_uart uarts[] = { + #ifdef RT_USING_USART0 + { + USART0, // uart peripheral index + USART0_IRQn, // uart iqrn + RCU_USART0, RCU_GPIOA, RCU_GPIOA, // periph clock, tx gpio clock, rt gpio clock + GPIOA, GPIO_AF_1, GPIO_PIN_9, // tx port, tx pin + GPIOA, GPIO_AF_1, GPIO_PIN_10, // rx port, rx pin + &serial0, + "uart0", + }, + #endif + + #ifdef RT_USING_USART1 + { + USART1, // uart peripheral index + USART1_IRQn, // uart iqrn + RCU_USART1, RCU_GPIOA, RCU_GPIOA, // periph clock, tx gpio clock, rt gpio clock + GPIOA, GPIO_AF_1, GPIO_PIN_2, // tx port, tx pin + GPIOA, GPIO_AF_1, GPIO_PIN_3, // rx port, rx pin + &serial1, + "uart1", + }, + #endif +}; + + +/** +* @brief UART MSP Initialization +* This function configures the hardware resources used in this example: +* - Peripheral's clock enable +* - Peripheral's GPIO Configuration +* - NVIC configuration for UART interrupt request enable +* @param uart: UART handle pointer +* @retval None +*/ +void gd32_uart_gpio_init(struct gd32_uart *uart) +{ + /* enable USART clock */ + rcu_periph_clock_enable(uart->tx_gpio_clk); + rcu_periph_clock_enable(uart->rx_gpio_clk); + rcu_periph_clock_enable(uart->per_clk); + + /* connect port to USARTx_Tx */ + gpio_af_set(uart->tx_port, uart->tx_af, uart->tx_pin); + gpio_mode_set(uart->tx_port, GPIO_MODE_AF, GPIO_PUPD_NONE, uart->tx_pin); + gpio_output_options_set(uart->tx_port, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, uart->tx_pin); + + /* connect port to USARTx_Rx */ + gpio_af_set(uart->rx_port, uart->rx_af, uart->rx_pin); + gpio_mode_set(uart->rx_port, GPIO_MODE_INPUT, GPIO_PUPD_NONE, uart->rx_pin); + gpio_output_options_set(uart->rx_port, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, uart->rx_pin); + + NVIC_SetPriority(uart->irqn, 0); + NVIC_EnableIRQ(uart->irqn); +} + +static rt_err_t gd32_configure(struct rt_serial_device *serial, struct serial_configure *cfg) +{ + struct gd32_uart *uart; + + RT_ASSERT(serial != RT_NULL); + RT_ASSERT(cfg != RT_NULL); + + uart = (struct gd32_uart *)serial->parent.user_data; + + gd32_uart_gpio_init(uart); + + usart_baudrate_set(uart->uart_periph, cfg->baud_rate); + + switch (cfg->data_bits) + { + case DATA_BITS_9: + usart_word_length_set(uart->uart_periph, USART_WL_9BIT); + break; + + default: + usart_word_length_set(uart->uart_periph, USART_WL_8BIT); + break; + } + + switch (cfg->stop_bits) + { + case STOP_BITS_2: + usart_stop_bit_set(uart->uart_periph, USART_STB_2BIT); + break; + default: + usart_stop_bit_set(uart->uart_periph, USART_STB_1BIT); + break; + } + + switch (cfg->parity) + { + case PARITY_ODD: + usart_parity_config(uart->uart_periph, USART_PM_ODD); + break; + case PARITY_EVEN: + usart_parity_config(uart->uart_periph, USART_PM_EVEN); + break; + default: + usart_parity_config(uart->uart_periph, USART_PM_NONE); + break; + } + + usart_receive_config(uart->uart_periph, USART_RECEIVE_ENABLE); + usart_transmit_config(uart->uart_periph, USART_TRANSMIT_ENABLE); + usart_enable(uart->uart_periph); + + return RT_EOK; +} + +static rt_err_t gd32_control(struct rt_serial_device *serial, int cmd, void *arg) +{ + struct gd32_uart *uart; + + RT_ASSERT(serial != RT_NULL); + uart = (struct gd32_uart *)serial->parent.user_data; + + switch (cmd) + { + case RT_DEVICE_CTRL_CLR_INT: + /* disable rx irq */ + NVIC_DisableIRQ(uart->irqn); + /* disable interrupt */ + usart_interrupt_disable(uart->uart_periph, USART_INT_RBNE); + + break; + case RT_DEVICE_CTRL_SET_INT: + /* enable rx irq */ + NVIC_EnableIRQ(uart->irqn); + /* enable interrupt */ + usart_interrupt_enable(uart->uart_periph, USART_INT_RBNE); + break; + } + + return RT_EOK; +} + +static int gd32_putc(struct rt_serial_device *serial, char ch) +{ + struct gd32_uart *uart; + + RT_ASSERT(serial != RT_NULL); + uart = (struct gd32_uart *)serial->parent.user_data; + + usart_data_transmit(uart->uart_periph, ch); + while((usart_flag_get(uart->uart_periph, USART_FLAG_TC) == RESET)); + + return 1; +} + +static int gd32_getc(struct rt_serial_device *serial) +{ + int ch; + struct gd32_uart *uart; + + RT_ASSERT(serial != RT_NULL); + uart = (struct gd32_uart *)serial->parent.user_data; + + ch = -1; + if (usart_flag_get(uart->uart_periph, USART_FLAG_RBNE) != RESET) + ch = usart_data_receive(uart->uart_periph); + return ch; +} + +/** + * Uart common interrupt process. This need add to uart ISR. + * + * @param serial serial device + */ +static void uart_isr(struct rt_serial_device *serial) +{ + struct gd32_uart *uart = (struct gd32_uart *) serial->parent.user_data; + + RT_ASSERT(uart != RT_NULL); + + /* UART in mode Receiver */ + if ((usart_interrupt_flag_get(uart->uart_periph, USART_INT_FLAG_RBNE) != RESET) && + (usart_flag_get(uart->uart_periph, USART_FLAG_RBNE) != RESET)) + { + rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND); + /* Clear RXNE interrupt flag */ + usart_flag_clear(uart->uart_periph, USART_FLAG_RBNE); + } +} + +static const struct rt_uart_ops gd32_uart_ops = +{ + gd32_configure, + gd32_control, + gd32_putc, + gd32_getc +}; + +int gd32_hw_usart_init(void) +{ + struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; + int i; + + for (i = 0; i < sizeof(uarts) / sizeof(uarts[0]); i++) + { + uarts[i].serial->ops = &gd32_uart_ops; + uarts[i].serial->config = config; + + /* register UART device */ + rt_hw_serial_register(uarts[i].serial, + uarts[i].device_name, + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, + (void *)&uarts[i]); + } + + return 0; +} +INIT_BOARD_EXPORT(gd32_hw_usart_init); +#endif diff --git a/bsp/gd32e230k-start/drivers/drv_usart.h b/bsp/gd32e230k-start/drivers/drv_usart.h new file mode 100644 index 0000000000000000000000000000000000000000..0fb15bee6f8e363b4b7779598427bee817f19521 --- /dev/null +++ b/bsp/gd32e230k-start/drivers/drv_usart.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2009-01-05 Bernard the first version + */ + +#ifndef __USART_H__ +#define __USART_H__ + + +#endif diff --git a/bsp/gd32e230k-start/drivers/gd32e230_libopt.h b/bsp/gd32e230k-start/drivers/gd32e230_libopt.h new file mode 100644 index 0000000000000000000000000000000000000000..61010d794fd7ee533a3c81cb45f71123965f22c5 --- /dev/null +++ b/bsp/gd32e230k-start/drivers/gd32e230_libopt.h @@ -0,0 +1,60 @@ +/*! + \file gd32e230_libopt.h + \brief library optional for gd32e230 + + \version 2018-06-19, V1.0.0, firmware for GD32E230 +*/ + +/* + Copyright (c) 2018, GigaDevice Semiconductor 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 copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 GD32E230_LIBOPT_H +#define GD32E230_LIBOPT_H + +#include "gd32e230_adc.h" +#include "gd32e230_crc.h" +#include "gd32e230_dbg.h" +#include "gd32e230_dma.h" +#include "gd32e230_exti.h" +#include "gd32e230_fmc.h" +#include "gd32e230_gpio.h" +#include "gd32e230_syscfg.h" +#include "gd32e230_i2c.h" +#include "gd32e230_fwdgt.h" +#include "gd32e230_pmu.h" +#include "gd32e230_rcu.h" +#include "gd32e230_rtc.h" +#include "gd32e230_spi.h" +#include "gd32e230_timer.h" +#include "gd32e230_usart.h" +#include "gd32e230_wwdgt.h" +#include "gd32e230_misc.h" +#include "gd32e230_cmp.h" + +#endif /* GD32E230_LIBOPT_H */ diff --git a/bsp/gd32e230k-start/gd32_rom.icf b/bsp/gd32e230k-start/gd32_rom.icf new file mode 100644 index 0000000000000000000000000000000000000000..d6665c3649fc1b5fe92d25e3d24cc59d8b888942 --- /dev/null +++ b/bsp/gd32e230k-start/gd32_rom.icf @@ -0,0 +1,40 @@ +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x08000000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_ROM_start__ = 0x08000000; +define symbol __ICFEDIT_region_ROM_end__ = 0x0807ffff; +define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; +define symbol __ICFEDIT_region_RAM_end__ = 0x2000FFFF; +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 0x2000; +define symbol __ICFEDIT_size_heap__ = 0x2000; +/**** End of ICF editor section. ###ICF###*/ + +export symbol __ICFEDIT_region_RAM_end__; + +define symbol __region_RAM1_start__ = 0x10000000; +define symbol __region_RAM1_end__ = 0x1000FFFF; + +define memory mem with size = 4G; +define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; +define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; +define region RAM1_region = mem:[from __region_RAM1_start__ to __region_RAM1_end__]; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + +initialize by copy { readwrite }; +do not initialize { section .noinit }; + +keep { section FSymTab }; +keep { section VSymTab }; +keep { section .rti_fn* }; +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; + +place in ROM_region { readonly }; +place in RAM_region { readwrite, + block CSTACK, block HEAP }; +place in RAM1_region { section .sram }; \ No newline at end of file diff --git a/bsp/gd32e230k-start/gd32_rom.ld b/bsp/gd32e230k-start/gd32_rom.ld new file mode 100644 index 0000000000000000000000000000000000000000..a017d88f4dfb2964ce8ed0f5e4ded719224fa2db --- /dev/null +++ b/bsp/gd32e230k-start/gd32_rom.ld @@ -0,0 +1,142 @@ +/* + * linker script for GD32F30x with GNU ld + * bernard.xiong 2009-10-14 + */ + +/* Program Entry, set to mark it as "used" and avoid gc */ +MEMORY +{ + CODE (rx) : ORIGIN = 0x08000000, LENGTH = 512k /* 512KB flash */ + DATA (rw) : ORIGIN = 0x20000000, LENGTH = 64k /* 64KB sram */ +} +ENTRY(Reset_Handler) +_system_stack_size = 0x200; + +SECTIONS +{ + .text : + { + . = ALIGN(4); + _stext = .; + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + *(.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(4); + __fsymtab_start = .; + KEEP(*(FSymTab)) + __fsymtab_end = .; + . = ALIGN(4); + __vsymtab_start = .; + KEEP(*(VSymTab)) + __vsymtab_end = .; + . = ALIGN(4); + + /* section information for initial. */ + . = ALIGN(4); + __rt_init_start = .; + KEEP(*(SORT(.rti_fn*))) + __rt_init_end = .; + . = ALIGN(4); + + . = ALIGN(4); + _etext = .; + } > CODE = 0 + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + + /* This is used by the startup in order to initialize the .data secion */ + _sidata = .; + } > CODE + __exidx_end = .; + + /* .data section which is used for initialized data */ + + .data : AT (_sidata) + { + . = ALIGN(4); + /* This is used by the startup in order to initialize the .data secion */ + _sdata = . ; + + *(.data) + *(.data.*) + *(.gnu.linkonce.d*) + + . = ALIGN(4); + /* This is used by the startup in order to initialize the .data secion */ + _edata = . ; + } >DATA + + .stack : + { + . = . + _system_stack_size; + . = ALIGN(4); + _estack = .; + } >DATA + + __bss_start = .; + .bss : + { + . = ALIGN(4); + /* This is used by the startup in order to initialize the .bss secion */ + _sbss = .; + + *(.bss) + *(.bss.*) + *(COMMON) + + . = ALIGN(4); + /* This is used by the startup in order to initialize the .bss secion */ + _ebss = . ; + + *(.bss.init) + } > DATA + __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) } +} diff --git a/bsp/gd32e230k-start/gd32_rom.sct b/bsp/gd32e230k-start/gd32_rom.sct new file mode 100644 index 0000000000000000000000000000000000000000..abc5462a3fc942bdd29fa7e5a40729d1b71bd7bf --- /dev/null +++ b/bsp/gd32e230k-start/gd32_rom.sct @@ -0,0 +1,15 @@ +; ************************************************************* +; *** Scatter-Loading Description File generated by uVision *** +; ************************************************************* + +LR_IROM1 0x08000000 0x000080000 { ; load region size_region + ER_IROM1 0x08000000 0x000080000 { ; load address = execution address + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + } + RW_IRAM1 0x20000000 0x00010000 { ; RW data + .ANY (+RW +ZI) + } +} + diff --git a/bsp/gd32e230k-start/project.uvoptx b/bsp/gd32e230k-start/project.uvoptx new file mode 100644 index 0000000000000000000000000000000000000000..ef882479f1dc6ef840eb705a7377e5475923e5b4 --- /dev/null +++ b/bsp/gd32e230k-start/project.uvoptx @@ -0,0 +1,977 @@ + + + + 1.0 + +
### uVision Project, (C) Keil Software
+ + + *.c + *.s*; *.src; *.a* + *.obj; *.o + *.lib + *.txt; *.h; *.inc + *.plm + *.cpp + 0 + + + + 0 + 0 + + + + rt-thread_gd32e230 + 0x4 + ARM-ADS + + 12000000 + + 1 + 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 + + 255 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 20 + + + + + + + + + + + BIN\CMSIS_AGDI_V8M.DLL + + + + 0 + UL2V8M + UL2V8M(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0GD32E230 -FS08000000 -FL010000 -FP0($$Device:GD32E230K8$Flash\GD32E230.FLM)) + + + 0 + JL2CM3 + -U30000299 -O78 -S2 -ZTIFSpeedSel5000 -A0 -C0 -JU1 -JI127.0.0.1 -JP0 -RST0 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(4) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -TB1 -TFE0 -FO15 -FD20000000 -FC1000 -FN1 -FF0GD32F30x_HD -FS08000000 -FL080000 + + + + + 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 + 1 + 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\cpu.c + cpu.c + 0 + 0 + + + 1 + 4 + 1 + 0 + 0 + 0 + ..\..\src\device.c + device.c + 0 + 0 + + + 1 + 5 + 1 + 0 + 0 + 0 + ..\..\src\idle.c + idle.c + 0 + 0 + + + 1 + 6 + 1 + 0 + 0 + 0 + ..\..\src\ipc.c + ipc.c + 0 + 0 + + + 1 + 7 + 1 + 0 + 0 + 0 + ..\..\src\irq.c + irq.c + 0 + 0 + + + 1 + 8 + 1 + 0 + 0 + 0 + ..\..\src\kservice.c + kservice.c + 0 + 0 + + + 1 + 9 + 1 + 0 + 0 + 0 + ..\..\src\mem.c + mem.c + 0 + 0 + + + 1 + 10 + 1 + 0 + 0 + 0 + ..\..\src\mempool.c + mempool.c + 0 + 0 + + + 1 + 11 + 1 + 0 + 0 + 0 + ..\..\src\object.c + object.c + 0 + 0 + + + 1 + 12 + 1 + 0 + 0 + 0 + ..\..\src\scheduler.c + scheduler.c + 0 + 0 + + + 1 + 13 + 1 + 0 + 0 + 0 + ..\..\src\signal.c + signal.c + 0 + 0 + + + 1 + 14 + 1 + 0 + 0 + 0 + ..\..\src\thread.c + thread.c + 0 + 0 + + + 1 + 15 + 1 + 0 + 0 + 0 + ..\..\src\timer.c + timer.c + 0 + 0 + + + + + Applications + 1 + 0 + 0 + 0 + + 2 + 16 + 1 + 0 + 0 + 0 + applications\main.c + main.c + 0 + 0 + + + + + Drivers + 1 + 0 + 0 + 0 + + 3 + 17 + 1 + 0 + 0 + 0 + drivers\board.c + board.c + 0 + 0 + + + 3 + 18 + 1 + 0 + 0 + 0 + drivers\drv_usart.c + drv_usart.c + 0 + 0 + + + 3 + 19 + 1 + 0 + 0 + 0 + drivers\drv_spi.c + drv_spi.c + 0 + 0 + + + 3 + 20 + 1 + 0 + 0 + 0 + drivers\drv_i2c.c + drv_i2c.c + 0 + 0 + + + 3 + 21 + 1 + 0 + 0 + 0 + drivers\drv_gpio.c + drv_gpio.c + 0 + 0 + + + + + GD32_Lib + 0 + 0 + 0 + 0 + + 4 + 22 + 1 + 0 + 0 + 0 + Libraries\GD32E230_standard_peripheral\Source\gd32e230_adc.c + gd32e230_adc.c + 0 + 0 + + + 4 + 23 + 1 + 0 + 0 + 0 + Libraries\GD32E230_standard_peripheral\Source\gd32e230_cmp.c + gd32e230_cmp.c + 0 + 0 + + + 4 + 24 + 1 + 0 + 0 + 0 + Libraries\GD32E230_standard_peripheral\Source\gd32e230_crc.c + gd32e230_crc.c + 0 + 0 + + + 4 + 25 + 1 + 0 + 0 + 0 + Libraries\GD32E230_standard_peripheral\Source\gd32e230_dbg.c + gd32e230_dbg.c + 0 + 0 + + + 4 + 26 + 1 + 0 + 0 + 0 + Libraries\GD32E230_standard_peripheral\Source\gd32e230_dma.c + gd32e230_dma.c + 0 + 0 + + + 4 + 27 + 1 + 0 + 0 + 0 + Libraries\GD32E230_standard_peripheral\Source\gd32e230_exti.c + gd32e230_exti.c + 0 + 0 + + + 4 + 28 + 1 + 0 + 0 + 0 + Libraries\GD32E230_standard_peripheral\Source\gd32e230_fmc.c + gd32e230_fmc.c + 0 + 0 + + + 4 + 29 + 1 + 0 + 0 + 0 + Libraries\GD32E230_standard_peripheral\Source\gd32e230_fwdgt.c + gd32e230_fwdgt.c + 0 + 0 + + + 4 + 30 + 1 + 0 + 0 + 0 + Libraries\GD32E230_standard_peripheral\Source\gd32e230_gpio.c + gd32e230_gpio.c + 0 + 0 + + + 4 + 31 + 1 + 0 + 0 + 0 + Libraries\GD32E230_standard_peripheral\Source\gd32e230_i2c.c + gd32e230_i2c.c + 0 + 0 + + + 4 + 32 + 1 + 0 + 0 + 0 + Libraries\GD32E230_standard_peripheral\Source\gd32e230_misc.c + gd32e230_misc.c + 0 + 0 + + + 4 + 33 + 1 + 0 + 0 + 0 + Libraries\GD32E230_standard_peripheral\Source\gd32e230_pmu.c + gd32e230_pmu.c + 0 + 0 + + + 4 + 34 + 1 + 0 + 0 + 0 + Libraries\GD32E230_standard_peripheral\Source\gd32e230_rcu.c + gd32e230_rcu.c + 0 + 0 + + + 4 + 35 + 1 + 0 + 0 + 0 + Libraries\GD32E230_standard_peripheral\Source\gd32e230_rtc.c + gd32e230_rtc.c + 0 + 0 + + + 4 + 36 + 1 + 0 + 0 + 0 + Libraries\GD32E230_standard_peripheral\Source\gd32e230_spi.c + gd32e230_spi.c + 0 + 0 + + + 4 + 37 + 1 + 0 + 0 + 0 + Libraries\GD32E230_standard_peripheral\Source\gd32e230_syscfg.c + gd32e230_syscfg.c + 0 + 0 + + + 4 + 38 + 1 + 0 + 0 + 0 + Libraries\GD32E230_standard_peripheral\Source\gd32e230_timer.c + gd32e230_timer.c + 0 + 0 + + + 4 + 39 + 1 + 0 + 0 + 0 + Libraries\GD32E230_standard_peripheral\Source\gd32e230_usart.c + gd32e230_usart.c + 0 + 0 + + + 4 + 40 + 1 + 0 + 0 + 0 + Libraries\GD32E230_standard_peripheral\Source\gd32e230_wwdgt.c + gd32e230_wwdgt.c + 0 + 0 + + + 4 + 41 + 1 + 0 + 0 + 0 + Libraries\CMSIS\GD\GD32E230\Source\system_gd32e230.c + system_gd32e230.c + 0 + 0 + + + 4 + 42 + 2 + 0 + 0 + 0 + Libraries\CMSIS\GD\GD32E230\Source\ARM\startup_gd32e230.s + startup_gd32e230.s + 0 + 0 + + + + + cpu + 0 + 0 + 0 + 0 + + 5 + 43 + 1 + 0 + 0 + 0 + ..\..\libcpu\arm\common\backtrace.c + backtrace.c + 0 + 0 + + + 5 + 44 + 1 + 0 + 0 + 0 + ..\..\libcpu\arm\common\div0.c + div0.c + 0 + 0 + + + 5 + 45 + 1 + 0 + 0 + 0 + ..\..\libcpu\arm\common\showmem.c + showmem.c + 0 + 0 + + + 5 + 46 + 1 + 0 + 0 + 0 + ..\..\libcpu\arm\cortex-m23\cpuport.c + cpuport.c + 0 + 0 + + + 5 + 47 + 2 + 0 + 0 + 0 + ..\..\libcpu\arm\cortex-m23\context_rvds.S + context_rvds.S + 0 + 0 + + + + + DeviceDrivers + 0 + 0 + 0 + 0 + + 6 + 48 + 1 + 0 + 0 + 0 + ..\..\components\drivers\i2c\i2c_core.c + i2c_core.c + 0 + 0 + + + 6 + 49 + 1 + 0 + 0 + 0 + ..\..\components\drivers\i2c\i2c_dev.c + i2c_dev.c + 0 + 0 + + + 6 + 50 + 1 + 0 + 0 + 0 + ..\..\components\drivers\misc\pin.c + pin.c + 0 + 0 + + + 6 + 51 + 1 + 0 + 0 + 0 + ..\..\components\drivers\serial\serial.c + serial.c + 0 + 0 + + + 6 + 52 + 1 + 0 + 0 + 0 + ..\..\components\drivers\spi\spi_core.c + spi_core.c + 0 + 0 + + + 6 + 53 + 1 + 0 + 0 + 0 + ..\..\components\drivers\spi\spi_dev.c + spi_dev.c + 0 + 0 + + + 6 + 54 + 1 + 0 + 0 + 0 + ..\..\components\drivers\spi\spi_flash_sfud.c + spi_flash_sfud.c + 0 + 0 + + + 6 + 55 + 1 + 0 + 0 + 0 + ..\..\components\drivers\spi\sfud\src\sfud.c + sfud.c + 0 + 0 + + + 6 + 56 + 1 + 0 + 0 + 0 + ..\..\components\drivers\src\completion.c + completion.c + 0 + 0 + + + 6 + 57 + 1 + 0 + 0 + 0 + ..\..\components\drivers\src\dataqueue.c + dataqueue.c + 0 + 0 + + + 6 + 58 + 1 + 0 + 0 + 0 + ..\..\components\drivers\src\pipe.c + pipe.c + 0 + 0 + + + 6 + 59 + 1 + 0 + 0 + 0 + ..\..\components\drivers\src\ringblk_buf.c + ringblk_buf.c + 0 + 0 + + + 6 + 60 + 1 + 0 + 0 + 0 + ..\..\components\drivers\src\ringbuffer.c + ringbuffer.c + 0 + 0 + + + 6 + 61 + 1 + 0 + 0 + 0 + ..\..\components\drivers\src\waitqueue.c + waitqueue.c + 0 + 0 + + + 6 + 62 + 1 + 0 + 0 + 0 + ..\..\components\drivers\src\workqueue.c + workqueue.c + 0 + 0 + + + + + ::CMSIS + 0 + 0 + 0 + 1 + + +
diff --git a/bsp/gd32e230k-start/project.uvprojx b/bsp/gd32e230k-start/project.uvprojx new file mode 100644 index 0000000000000000000000000000000000000000..529a87f12ea1a2cfbf169c0cebd871f68fb3e28d --- /dev/null +++ b/bsp/gd32e230k-start/project.uvprojx @@ -0,0 +1,811 @@ + + + + 2.1 + +
### uVision Project, (C) Keil Software
+ + + + rt-thread_gd32e230 + 0x4 + ARM-ADS + 6120000::V6.12::.\ARMCLANG + 1 + + + GD32E230K8 + GigaDevice + GigaDevice.GD32E230_DFP.1.0.0 + http://gd32mcu.21ic.com/data/documents/yingyongruanjian + IRAM(0x20000000,0x0002000) IROM(0x08000000,0x0010000) CPUTYPE("Cortex-M23") CLOCK(12000000) ELITTLE + + + UL2V8M(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0GD32E230 -FS08000000 -FL010000 -FP0($$Device:GD32E230K8$Flash\GD32E230.FLM)) + 0 + $$Device:GD32E230K8$Device\Include\gd32e230.h + + + + + + + + + + $$Device:GD32E230K8$SVD\GD32E230.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\build\ + rtthread-gd32e230 + 1 + 0 + 0 + 1 + 1 + .\build\ + 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 + + + + + + + SARMV8M.DLL + -MPU + TCM.DLL + -pCM23 + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4096 + + 1 + BIN\UL2V8M.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-M23" + + 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 + 0x8000000 + 0x10000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x8000000 + 0x10000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x2000 + + + 0 + 0x0 + 0x0 + + + + + + 1 + 7 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + + + GD32E230 + + .;..\..\include;applications;drivers;Libraries\CMSIS\GD\GD32E230\Include;Libraries\CMSIS;Libraries\GD32E230_standard_peripheral\Include;..\..\libcpu\arm\common;..\..\libcpu\arm\cortex-m23;..\..\components\drivers\include;..\..\components\drivers\include;..\..\components\drivers\include;..\..\components\drivers\spi;..\..\components\drivers\include;..\..\components\drivers\spi\sfud\inc;..\..\components\drivers\include + + + + 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 + + + cpu.c + 1 + ..\..\src\cpu.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_usart.c + 1 + drivers\drv_usart.c + + + drv_spi.c + 1 + drivers\drv_spi.c + + + drv_i2c.c + 1 + drivers\drv_i2c.c + + + drv_gpio.c + 1 + drivers\drv_gpio.c + + + + + GD32_Lib + + + gd32e230_adc.c + 1 + Libraries\GD32E230_standard_peripheral\Source\gd32e230_adc.c + + + gd32e230_cmp.c + 1 + Libraries\GD32E230_standard_peripheral\Source\gd32e230_cmp.c + + + gd32e230_crc.c + 1 + Libraries\GD32E230_standard_peripheral\Source\gd32e230_crc.c + + + gd32e230_dbg.c + 1 + Libraries\GD32E230_standard_peripheral\Source\gd32e230_dbg.c + + + gd32e230_dma.c + 1 + Libraries\GD32E230_standard_peripheral\Source\gd32e230_dma.c + + + gd32e230_exti.c + 1 + Libraries\GD32E230_standard_peripheral\Source\gd32e230_exti.c + + + gd32e230_fmc.c + 1 + Libraries\GD32E230_standard_peripheral\Source\gd32e230_fmc.c + + + gd32e230_fwdgt.c + 1 + Libraries\GD32E230_standard_peripheral\Source\gd32e230_fwdgt.c + + + gd32e230_gpio.c + 1 + Libraries\GD32E230_standard_peripheral\Source\gd32e230_gpio.c + + + gd32e230_i2c.c + 1 + Libraries\GD32E230_standard_peripheral\Source\gd32e230_i2c.c + + + gd32e230_misc.c + 1 + Libraries\GD32E230_standard_peripheral\Source\gd32e230_misc.c + + + gd32e230_pmu.c + 1 + Libraries\GD32E230_standard_peripheral\Source\gd32e230_pmu.c + + + gd32e230_rcu.c + 1 + Libraries\GD32E230_standard_peripheral\Source\gd32e230_rcu.c + + + gd32e230_rtc.c + 1 + Libraries\GD32E230_standard_peripheral\Source\gd32e230_rtc.c + + + gd32e230_spi.c + 1 + Libraries\GD32E230_standard_peripheral\Source\gd32e230_spi.c + + + gd32e230_syscfg.c + 1 + Libraries\GD32E230_standard_peripheral\Source\gd32e230_syscfg.c + + + gd32e230_timer.c + 1 + Libraries\GD32E230_standard_peripheral\Source\gd32e230_timer.c + + + gd32e230_usart.c + 1 + Libraries\GD32E230_standard_peripheral\Source\gd32e230_usart.c + + + gd32e230_wwdgt.c + 1 + Libraries\GD32E230_standard_peripheral\Source\gd32e230_wwdgt.c + + + system_gd32e230.c + 1 + Libraries\CMSIS\GD\GD32E230\Source\system_gd32e230.c + + + startup_gd32e230.s + 2 + Libraries\CMSIS\GD\GD32E230\Source\ARM\startup_gd32e230.s + + + + + 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-m23\cpuport.c + + + context_rvds.S + 2 + ..\..\libcpu\arm\cortex-m23\context_rvds.S + + + + + 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 + + + + + + + + + + + + i2c_core.c + 1 + ..\..\components\drivers\i2c\i2c_core.c + + + i2c_dev.c + 1 + ..\..\components\drivers\i2c\i2c_dev.c + + + pin.c + 1 + ..\..\components\drivers\misc\pin.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 + + + spi_flash_sfud.c + 1 + ..\..\components\drivers\spi\spi_flash_sfud.c + + + sfud.c + 1 + ..\..\components\drivers\spi\sfud\src\sfud.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 + + + + + ::CMSIS + + + + + + + + + + + + + + + + + + +
diff --git a/bsp/gd32e230k-start/rtconfig.h b/bsp/gd32e230k-start/rtconfig.h new file mode 100644 index 0000000000000000000000000000000000000000..ae64fc01f68f292fe6331f65ce6cead86c985b37 --- /dev/null +++ b/bsp/gd32e230k-start/rtconfig.h @@ -0,0 +1,152 @@ +#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_IDEL_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 "uart0" +#define RT_VER_NUM 0x40001 + +/* 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 */ + + +/* 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_SERIAL_RB_BUFSZ 64 +#define RT_USING_I2C +#define RT_USING_PIN +#define RT_USING_SPI +#define RT_USING_SFUD +#define RT_SFUD_USING_FLASH_INFO_TABLE + +/* Using WiFi */ + + +/* Using USB */ + + +/* POSIX layer and C standard library */ + + +/* 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 */ + + +/* sample package */ + +/* samples: kernel and components samples */ + + +/* example package: hello */ + +#define RT_USING_USART0 +#define RT_USING_USART1 +#define RT_USING_SPI0 +#define RT_USING_SPI1 +#define RT_USING_I2C0 + +#endif diff --git a/bsp/gd32e230k-start/rtconfig.py b/bsp/gd32e230k-start/rtconfig.py new file mode 100644 index 0000000000000000000000000000000000000000..8356fe0c9c7595eaf9b3571e178a8a01371dddbf --- /dev/null +++ b/bsp/gd32e230k-start/rtconfig.py @@ -0,0 +1,124 @@ +import os + +# toolchains options +ARCH='arm' +CPU='cortex-m23' +CROSS_TOOL='keil' + +if os.getenv('RTT_CC'): + CROSS_TOOL = os.getenv('RTT_CC') + +# cross_tool provides the cross compiler +# EXEC_PATH is the compiler execute path, for example, CodeSourcery, Keil MDK, IAR +if CROSS_TOOL == 'gcc': + PLATFORM = 'gcc' + EXEC_PATH = r'D:/toolchain/gnu_tools_arm_embedded/5.4_2016q3/bin' +elif CROSS_TOOL == 'keil': + PLATFORM = 'armcc' + EXEC_PATH = r'C:/Keil_v5' +elif CROSS_TOOL == 'iar': + PLATFORM = 'iar' + EXEC_PATH = r'C:/Program Files (x86)/IAR Systems/Embedded Workbench 8.0' + +if os.getenv('RTT_EXEC_PATH'): + EXEC_PATH = os.getenv('RTT_EXEC_PATH') + +BUILD = 'debug' + +if PLATFORM == 'gcc': + # tool-chains + PREFIX = 'arm-none-eabi-' + CC = PREFIX + 'gcc' + AS = PREFIX + 'gcc' + AR = PREFIX + 'ar' + LINK = PREFIX + 'gcc' + TARGET_EXT = 'elf' + SIZE = PREFIX + 'size' + OBJDUMP = PREFIX + 'objdump' + OBJCPY = PREFIX + 'objcopy' + + DEVICE = ' -mcpu=cortex-m23 -mthumb -ffunction-sections -fdata-sections' + CFLAGS = DEVICE + ' -Dgcc' # -D' + PART_TYPE + AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp -Wa,-mimplicit-it=thumb ' + LFLAGS = DEVICE + ' -Wl,--gc-sections,-Map=rtthread-gd32.map,-cref,-u,Reset_Handler -T gd32_rom.ld' + + 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' + SIZE + ' $TARGET \n' + +elif PLATFORM == 'armcc': + # toolchains + CC = 'armcc' + AS = 'armasm' + AR = 'armar' + LINK = 'armlink' + TARGET_EXT = 'axf' + + DEVICE = ' --cpu Cortex-M23' + CFLAGS = DEVICE + ' --apcs=interwork' + AFLAGS = DEVICE + LFLAGS = DEVICE + ' --info sizes --info totals --info unused --info veneers --list rtthread-gd32.map --scatter gd32_rom.sct' + + LFLAGS += ' --keep *.o(.rti_fn.*) --keep *.o(FSymTab) --keep *.o(VSymTab)' + + EXEC_PATH += '/ARM/ARMCC/bin' + print(EXEC_PATH) + + 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 = ' -D USE_STDPERIPH_DRIVER' + ' -D GD32F30X_HD' + + 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 += ' --debug' + CFLAGS += ' --endian=little' + CFLAGS += ' --cpu=Cortex-M23' + CFLAGS += ' -e' + CFLAGS += ' --fpu=None' + CFLAGS += ' --dlib_config "' + EXEC_PATH + '/arm/INC/c/DLib_Config_Normal.h"' + CFLAGS += ' -Ol' + CFLAGS += ' --use_c++_inline' + + AFLAGS = '' + AFLAGS += ' -s+' + AFLAGS += ' -w+' + AFLAGS += ' -r' + AFLAGS += ' --cpu Cortex-M23' + AFLAGS += ' --fpu None' + + LFLAGS = ' --config gd32_rom.icf' + LFLAGS += ' --redirect _Printf=_PrintfTiny' + LFLAGS += ' --redirect _Scanf=_ScanfSmall' + LFLAGS += ' --entry __iar_program_start' + + EXEC_PATH += '/arm/bin/' + POST_ACTION = '' + diff --git a/bsp/gd32e230k-start/template.uvoptx b/bsp/gd32e230k-start/template.uvoptx new file mode 100644 index 0000000000000000000000000000000000000000..090bdb9227f025f3052c826ad6e581a9232d6e0b --- /dev/null +++ b/bsp/gd32e230k-start/template.uvoptx @@ -0,0 +1,185 @@ + + + + 1.0 + +
### uVision Project, (C) Keil Software
+ + + *.c + *.s*; *.src; *.a* + *.obj; *.o + *.lib + *.txt; *.h; *.inc + *.plm + *.cpp + 0 + + + + 0 + 0 + + + + rt-thread_gd32e230 + 0x4 + ARM-ADS + + 12000000 + + 1 + 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 + + 255 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 19 + + + + + + + + + + + BIN\UL2V8M.DLL + + + + 0 + UL2V8M + UL2V8M(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0GD32E230 -FS08000000 -FL010000 -FP0($$Device:GD32E230K8$Flash\GD32E230.FLM)) + + + 0 + JL2CM3 + -U30000299 -O78 -S2 -ZTIFSpeedSel5000 -A0 -C0 -JU1 -JI127.0.0.1 -JP0 -RST0 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(4) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -TB1 -TFE0 -FO15 -FD20000000 -FC1000 -FN1 -FF0GD32F30x_HD -FS08000000 -FL080000 + + + + + 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 + + + + + + + + + + + + + ::CMSIS + 0 + 0 + 0 + 1 + + +
diff --git a/bsp/gd32e230k-start/template.uvprojx b/bsp/gd32e230k-start/template.uvprojx new file mode 100644 index 0000000000000000000000000000000000000000..43c9f16629f1527e73a9fcbb9f84f222f55c80ea --- /dev/null +++ b/bsp/gd32e230k-start/template.uvprojx @@ -0,0 +1,402 @@ + + + + 2.1 + +
### uVision Project, (C) Keil Software
+ + + + rt-thread_gd32e230 + 0x4 + ARM-ADS + 5060750::V5.06 update 6 (build 750)::ARMCC + 1 + + + GD32E230K8 + GigaDevice + GigaDevice.GD32E230_DFP.1.0.0 + http://gd32mcu.21ic.com/data/documents/yingyongruanjian + IRAM(0x20000000,0x0002000) IROM(0x08000000,0x0010000) CPUTYPE("Cortex-M23") CLOCK(12000000) ELITTLE + + + UL2V8M(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0GD32E230 -FS08000000 -FL010000 -FP0($$Device:GD32E230K8$Flash\GD32E230.FLM)) + 0 + $$Device:GD32E230K8$Device\Include\gd32e230.h + + + + + + + + + + $$Device:GD32E230K8$SVD\GD32E230.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\build\ + rtthread-gd32e230 + 1 + 0 + 0 + 1 + 1 + .\build\ + 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 + + + + + + + SARMV8M.DLL + -MPU + TCM.DLL + -pCM23 + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4096 + + 1 + BIN\UL2V8M.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-M23" + + 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 + 0x8000000 + 0x10000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x8000000 + 0x10000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x2000 + + + 0 + 0x0 + 0x0 + + + + + + 1 + 7 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + + + + + applications;.;drivers;Libraries\CMSIS\GD\GD32F30x\Include;Libraries\CMSIS;Libraries\GD32F30x_standard_peripheral\Include;..\..\include;..\..\libcpu\arm\cortex-m4;..\..\libcpu\arm\common;..\..\components\dfs\include;..\..\components\dfs\filesystems\devfs;..\..\components\dfs\filesystems\elmfat;..\..\components\drivers\include;..\..\components\drivers\include;..\..\components\drivers\include;..\..\components\finsh + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + + + + 1 + 0 + 0 + 0 + 1 + 0 + 0x08000000 + 0x20000000 + + + + + --keep *.o(RTMSymTab) --keep *.o(.rti_fn.*) --keep *.o(FSymTab) --keep *.o(VSymTab) + + + + + + + + ::CMSIS + + + + + + + + + + + + + + + + + + +
diff --git a/bsp/stm32/libraries/HAL_Drivers/config/f4/dma_config.h b/bsp/stm32/libraries/HAL_Drivers/config/f4/dma_config.h index d382fc4e291fe8ea3b221c4ee584a40ae33f6794..8083c7782668a7df93766c5369872da9738db987 100644 --- a/bsp/stm32/libraries/HAL_Drivers/config/f4/dma_config.h +++ b/bsp/stm32/libraries/HAL_Drivers/config/f4/dma_config.h @@ -123,6 +123,12 @@ extern "C" { #define SPI4_TX_DMA_INSTANCE DMA2_Stream1 #define SPI4_TX_DMA_CHANNEL DMA_CHANNEL_4 #define SPI4_TX_DMA_IRQ DMA2_Stream1_IRQn +#elif defined(BSP_UART6_RX_USING_DMA) && !defined(UART6_RX_DMA_INSTANCE) +#define UART6_DMA_RX_IRQHandler DMA2_Stream1_IRQHandler +#define UART6_RX_DMA_RCC RCC_AHB1ENR_DMA2EN +#define UART6_RX_DMA_INSTANCE DMA2_Stream1 +#define UART6_RX_DMA_CHANNEL DMA_CHANNEL_5 +#define UART6_RX_DMA_IRQ DMA2_Stream1_IRQn #endif /* DMA2 stream2 */ diff --git a/bsp/stm32/libraries/HAL_Drivers/config/f4/uart_config.h b/bsp/stm32/libraries/HAL_Drivers/config/f4/uart_config.h index 256716d8c4bdb5dbc2cd75775d9cf75c3b906abe..50a7f50b84052d0a2b8a081f64dfb51b5972cd45 100644 --- a/bsp/stm32/libraries/HAL_Drivers/config/f4/uart_config.h +++ b/bsp/stm32/libraries/HAL_Drivers/config/f4/uart_config.h @@ -33,10 +33,10 @@ extern "C" { #ifndef UART1_DMA_CONFIG #define UART1_DMA_CONFIG \ { \ - .Instance = UART1_RX_DMA_INSTANCE, \ - .channel = UART1_RX_DMA_CHANNEL, \ - .dma_rcc = UART1_RX_DMA_RCC, \ - .dma_irq = UART1_RX_DMA_IRQ, \ + .Instance = UART1_RX_DMA_INSTANCE, \ + .channel = UART1_RX_DMA_CHANNEL, \ + .dma_rcc = UART1_RX_DMA_RCC, \ + .dma_irq = UART1_RX_DMA_IRQ, \ } #endif /* UART1_DMA_CONFIG */ #endif /* BSP_UART1_RX_USING_DMA */ @@ -56,10 +56,10 @@ extern "C" { #ifndef UART2_DMA_CONFIG #define UART2_DMA_CONFIG \ { \ - .Instance = UART2_RX_DMA_INSTANCE, \ - .channel = UART2_RX_DMA_CHANNEL, \ - .dma_rcc = UART2_RX_DMA_RCC, \ - .dma_irq = UART2_RX_DMA_IRQ, \ + .Instance = UART2_RX_DMA_INSTANCE, \ + .channel = UART2_RX_DMA_CHANNEL, \ + .dma_rcc = UART2_RX_DMA_RCC, \ + .dma_irq = UART2_RX_DMA_IRQ, \ } #endif /* UART2_DMA_CONFIG */ #endif /* BSP_UART2_RX_USING_DMA */ @@ -79,10 +79,10 @@ extern "C" { #ifndef UART3_DMA_CONFIG #define UART3_DMA_CONFIG \ { \ - .Instance = UART3_RX_DMA_INSTANCE, \ - .channel = UART3_RX_DMA_CHANNEL, \ - .dma_rcc = UART3_RX_DMA_RCC, \ - .dma_irq = UART3_RX_DMA_IRQ, \ + .Instance = UART3_RX_DMA_INSTANCE, \ + .channel = UART3_RX_DMA_CHANNEL, \ + .dma_rcc = UART3_RX_DMA_RCC, \ + .dma_irq = UART3_RX_DMA_IRQ, \ } #endif /* UART3_DMA_CONFIG */ #endif /* BSP_UART3_RX_USING_DMA */ @@ -102,10 +102,10 @@ extern "C" { #ifndef UART4_DMA_CONFIG #define UART4_DMA_CONFIG \ { \ - .Instance = UART4_RX_DMA_INSTANCE, \ - .channel = UART4_RX_DMA_CHANNEL, \ - .dma_rcc = UART4_RX_DMA_RCC, \ - .dma_irq = UART4_RX_DMA_IRQ, \ + .Instance = UART4_RX_DMA_INSTANCE, \ + .channel = UART4_RX_DMA_CHANNEL, \ + .dma_rcc = UART4_RX_DMA_RCC, \ + .dma_irq = UART4_RX_DMA_IRQ, \ } #endif /* UART4_DMA_CONFIG */ #endif /* BSP_UART4_RX_USING_DMA */ @@ -125,14 +125,37 @@ extern "C" { #ifndef UART5_DMA_CONFIG #define UART5_DMA_CONFIG \ { \ - .Instance = UART5_RX_DMA_INSTANCE, \ - .channel = UART5_RX_DMA_CHANNEL, \ - .dma_rcc = UART5_RX_DMA_RCC, \ - .dma_irq = UART5_RX_DMA_IRQ, \ + .Instance = UART5_RX_DMA_INSTANCE, \ + .channel = UART5_RX_DMA_CHANNEL, \ + .dma_rcc = UART5_RX_DMA_RCC, \ + .dma_irq = UART5_RX_DMA_IRQ, \ } #endif /* UART5_DMA_CONFIG */ #endif /* BSP_UART5_RX_USING_DMA */ +#if defined(BSP_USING_UART6) +#ifndef UART6_CONFIG +#define UART6_CONFIG \ + { \ + .name = "uart6", \ + .Instance = USART6, \ + .irq_type = USART6_IRQn, \ + } +#endif /* UART6_CONFIG */ +#endif /* BSP_USING_UART6 */ + +#if defined(BSP_UART6_RX_USING_DMA) +#ifndef UART6_DMA_CONFIG +#define UART6_DMA_CONFIG \ + { \ + .Instance = UART6_RX_DMA_INSTANCE, \ + .channel = UART6_RX_DMA_CHANNEL, \ + .dma_rcc = UART6_RX_DMA_RCC, \ + .dma_irq = UART6_RX_DMA_IRQ, \ + } +#endif /* UART6_DMA_CONFIG */ +#endif /* BSP_UART6_RX_USING_DMA */ + #ifdef __cplusplus } #endif diff --git a/bsp/stm32/libraries/HAL_Drivers/drv_usart.c b/bsp/stm32/libraries/HAL_Drivers/drv_usart.c index 87482fcb0034930fe2226b98c42c286a37fb1a5d..75852881f56b4c257a59e61b6ce8f05ff541bc65 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drv_usart.c +++ b/bsp/stm32/libraries/HAL_Drivers/drv_usart.c @@ -45,6 +45,9 @@ enum #ifdef BSP_USING_UART5 UART5_INDEX, #endif +#ifdef BSP_USING_UART6 + UART6_INDEX, +#endif #ifdef BSP_USING_LPUART1 LPUART1_INDEX, #endif @@ -67,6 +70,9 @@ static struct stm32_uart_config uart_config[] = #ifdef BSP_USING_UART5 UART5_CONFIG, #endif +#ifdef BSP_USING_UART6 + UART6_CONFIG, +#endif #ifdef BSP_USING_LPUART1 LPUART1_CONFIG, #endif @@ -431,6 +437,31 @@ void UART5_DMA_RX_IRQHandler(void) #endif /* defined(RT_SERIAL_USING_DMA) && defined(BSP_UART5_RX_USING_DMA) */ #endif /* BSP_USING_UART5*/ +#if defined(BSP_USING_UART6) +void USART6_IRQHandler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + + uart_isr(&(uart_obj[UART6_INDEX].serial)); + + /* leave interrupt */ + rt_interrupt_leave(); +} +#if defined(RT_SERIAL_USING_DMA) && defined(BSP_UART6_RX_USING_DMA) +void UART6_DMA_RX_IRQHandler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + + HAL_DMA_IRQHandler(&uart_obj[UART6_INDEX].dma.handle); + + /* leave interrupt */ + rt_interrupt_leave(); +} +#endif /* defined(RT_SERIAL_USING_DMA) && defined(BSP_UART6_RX_USING_DMA) */ +#endif /* BSP_USING_UART6*/ + #if defined(BSP_USING_LPUART1) void LPUART1_IRQHandler(void) { @@ -608,6 +639,11 @@ static void stm32_uart_get_dma_config(void) static struct dma_config uart5_dma_rx = UART5_DMA_CONFIG; uart_config[UART5_INDEX].dma_rx = &uart5_dma_rx; #endif +#ifdef BSP_UART6_RX_USING_DMA + uart_obj[UART6_INDEX].uart_dma_flag = 1; + static struct dma_config uart6_dma_rx = UART6_DMA_CONFIG; + uart_config[UART6_INDEX].dma_rx = &uart6_dma_rx; +#endif #ifdef BSP_LPUART1_RX_USING_DMA uart_obj[LPUART1_INDEX].uart_dma_flag = 1; static struct dma_config lpuart1_dma_rx = LPUART1_DMA_CONFIG; diff --git a/bsp/stm32/stm32f103-hw100k-ibox/README.md b/bsp/stm32/stm32f103-hw100k-ibox/README.md index dc7637caf62d4d308c88e8dad8fa93d0e35188af..fe178498d60a657eb5e95aff92e9942f7911f731 100644 --- a/bsp/stm32/stm32f103-hw100k-ibox/README.md +++ b/bsp/stm32/stm32f103-hw100k-ibox/README.md @@ -41,8 +41,8 @@ | **板载外设** | **支持情况** | **备注** | | :----------------- | :----------: | :------------------------------------- | | 以太网 | 支持 | W5500 使用 SPI2 | -| RS485 | 支持 | 使用 UART4 | -| LoRa | 暂不支持 | 使用 SPI1 LSD4RF | +| RS485 | 支持 | MAX485 使用 UART4 | +| LoRa | 支持 | 利尔达 LSD4RF-2F717N30 使用 SPI1 | | **片上外设** | **支持情况** | **备注** | | GPIO | 支持 | PA0, PA1... PG15 ---> PIN: 0, 1...144 | | UART | 支持 | UART1 | @@ -52,6 +52,7 @@ | ADC | 支持 | ADC1_CHANEL_10, ADC1_CHANNEL_11 | | PWM | 暂不支持 | | | IWG | 支持 | 命令:iwdg_sample wdt | +| FLASH | 支持 | 已适配 FAL | | **扩展模块** | **支持情况** | **备注** | | WIFI ESP8266 | 支持 | 硬十 ESP-02 使用 UART3 | @@ -114,6 +115,8 @@ msh > - 此开发板外部高速晶振是 12MHz ; - 使用 WIFI ESP8266 , 需将 CH_PD (PG1) 引脚拉高 ; - 使用 W5500,需插上网线 ; +- 测试 Lora 模块,可直接使用 sx12xx 软件包 ; +- 使用 MAX485, 可使用 软件包中 串口例程,增加收发使能引脚的控制 ; ## 联系人信息 diff --git a/bsp/stm32/stm32f103-hw100k-ibox/board/CubeMX_Config/CubeMX_Config.ioc b/bsp/stm32/stm32f103-hw100k-ibox/board/CubeMX_Config/CubeMX_Config.ioc index 4e92ef4a922bd3a45ac5ea9817e36a99bfc6f2c6..64b78b0f82d449ca47a3c7ec5094dd3d9266ea85 100644 --- a/bsp/stm32/stm32f103-hw100k-ibox/board/CubeMX_Config/CubeMX_Config.ioc +++ b/bsp/stm32/stm32f103-hw100k-ibox/board/CubeMX_Config/CubeMX_Config.ioc @@ -10,41 +10,45 @@ KeepUserPlacement=false Mcu.Family=STM32F1 Mcu.IP0=ADC1 Mcu.IP1=IWDG -Mcu.IP10=USART3 +Mcu.IP10=USART2 +Mcu.IP11=USART3 Mcu.IP2=NVIC Mcu.IP3=RCC Mcu.IP4=RTC -Mcu.IP5=SPI2 -Mcu.IP6=SYS -Mcu.IP7=UART4 -Mcu.IP8=USART1 -Mcu.IP9=USART2 -Mcu.IPNb=11 +Mcu.IP5=SPI1 +Mcu.IP6=SPI2 +Mcu.IP7=SYS +Mcu.IP8=UART4 +Mcu.IP9=USART1 +Mcu.IPNb=12 Mcu.Name=STM32F103Z(C-D-E)Tx Mcu.Package=LQFP144 Mcu.Pin0=PC14-OSC32_IN Mcu.Pin1=PC15-OSC32_OUT -Mcu.Pin10=PB13 -Mcu.Pin11=PB14 -Mcu.Pin12=PB15 -Mcu.Pin13=PA9 -Mcu.Pin14=PA10 -Mcu.Pin15=PA13 -Mcu.Pin16=PA14 -Mcu.Pin17=PC10 -Mcu.Pin18=PC11 -Mcu.Pin19=VP_IWDG_VS_IWDG +Mcu.Pin10=PA7 +Mcu.Pin11=PB10 +Mcu.Pin12=PB11 +Mcu.Pin13=PB13 +Mcu.Pin14=PB14 +Mcu.Pin15=PB15 +Mcu.Pin16=PA9 +Mcu.Pin17=PA10 +Mcu.Pin18=PA13 +Mcu.Pin19=PA14 Mcu.Pin2=OSC_IN -Mcu.Pin20=VP_RTC_VS_RTC_Activate -Mcu.Pin21=VP_SYS_VS_Systick +Mcu.Pin20=PC10 +Mcu.Pin21=PC11 +Mcu.Pin22=VP_IWDG_VS_IWDG +Mcu.Pin23=VP_RTC_VS_RTC_Activate +Mcu.Pin24=VP_SYS_VS_Systick Mcu.Pin3=OSC_OUT Mcu.Pin4=PC0 Mcu.Pin5=PC1 Mcu.Pin6=PA2 Mcu.Pin7=PA3 -Mcu.Pin8=PB10 -Mcu.Pin9=PB11 -Mcu.PinsNb=22 +Mcu.Pin8=PA5 +Mcu.Pin9=PA6 +Mcu.PinsNb=25 Mcu.ThirdPartyNb=0 Mcu.UserConstants= Mcu.UserName=STM32F103ZETx @@ -74,6 +78,12 @@ PA2.Mode=Asynchronous PA2.Signal=USART2_TX PA3.Mode=Asynchronous PA3.Signal=USART2_RX +PA5.Mode=Full_Duplex_Master +PA5.Signal=SPI1_SCK +PA6.Mode=Full_Duplex_Master +PA6.Signal=SPI1_MISO +PA7.Mode=Full_Duplex_Master +PA7.Signal=SPI1_MOSI PA9.Mode=Asynchronous PA9.Signal=USART1_TX PB10.Mode=Asynchronous @@ -132,7 +142,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_RTC_Init-RTC-false-HAL-true,5-MX_ADC1_Init-ADC1-false-HAL-true,6-MX_IWDG_Init-IWDG-false-HAL-true,7-MX_USART3_UART_Init-USART3-false-HAL-true,8-MX_SPI2_Init-SPI2-false-HAL-true,9-MX_UART4_Init-UART4-false-HAL-true,10-MX_USART2_UART_Init-USART2-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_RTC_Init-RTC-false-HAL-true,5-MX_ADC1_Init-ADC1-false-HAL-true,6-MX_IWDG_Init-IWDG-false-HAL-true,7-MX_USART3_UART_Init-USART3-false-HAL-true,8-MX_SPI2_Init-SPI2-false-HAL-true,9-MX_UART4_Init-UART4-false-HAL-true,10-MX_USART2_UART_Init-USART2-false-HAL-true,11-MX_SPI1_Init-SPI1-false-HAL-true RCC.ADCFreqValue=12000000 RCC.ADCPresc=RCC_ADCPCLK2_DIV6 RCC.AHBFreq_Value=72000000 @@ -167,6 +177,12 @@ SH.ADCx_IN10.0=ADC1_IN10,IN10 SH.ADCx_IN10.ConfNb=1 SH.ADCx_IN11.0=ADC1_IN11,IN11 SH.ADCx_IN11.ConfNb=1 +SPI1.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_8 +SPI1.CalculateBaudRate=9.0 MBits/s +SPI1.Direction=SPI_DIRECTION_2LINES +SPI1.IPParameters=VirtualType,Mode,Direction,BaudRatePrescaler,CalculateBaudRate +SPI1.Mode=SPI_MODE_MASTER +SPI1.VirtualType=VM_MASTER SPI2.CalculateBaudRate=18.0 MBits/s SPI2.Direction=SPI_DIRECTION_2LINES SPI2.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate diff --git a/bsp/stm32/stm32f103-hw100k-ibox/board/CubeMX_Config/Src/main.c b/bsp/stm32/stm32f103-hw100k-ibox/board/CubeMX_Config/Src/main.c index 004ef38ecbb4e8e6c4028474046821e5ef353166..b2e02475633d3d7ce346aef21b68f3341de08bab 100644 --- a/bsp/stm32/stm32f103-hw100k-ibox/board/CubeMX_Config/Src/main.c +++ b/bsp/stm32/stm32f103-hw100k-ibox/board/CubeMX_Config/Src/main.c @@ -68,6 +68,7 @@ IWDG_HandleTypeDef hiwdg; RTC_HandleTypeDef hrtc; +SPI_HandleTypeDef hspi1; SPI_HandleTypeDef hspi2; UART_HandleTypeDef huart4; @@ -90,6 +91,7 @@ static void MX_USART3_UART_Init(void); static void MX_SPI2_Init(void); static void MX_UART4_Init(void); static void MX_USART2_UART_Init(void); +static void MX_SPI1_Init(void); /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ @@ -135,6 +137,7 @@ int main(void) MX_SPI2_Init(); MX_UART4_Init(); MX_USART2_UART_Init(); + MX_SPI1_Init(); /* USER CODE BEGIN 2 */ /* USER CODE END 2 */ @@ -301,6 +304,44 @@ static void MX_RTC_Init(void) } +/** + * @brief SPI1 Initialization Function + * @param None + * @retval None + */ +static void MX_SPI1_Init(void) +{ + + /* USER CODE BEGIN SPI1_Init 0 */ + + /* USER CODE END SPI1_Init 0 */ + + /* USER CODE BEGIN SPI1_Init 1 */ + + /* USER CODE END SPI1_Init 1 */ + /* SPI1 parameter configuration*/ + hspi1.Instance = SPI1; + hspi1.Init.Mode = SPI_MODE_MASTER; + hspi1.Init.Direction = SPI_DIRECTION_2LINES; + hspi1.Init.DataSize = SPI_DATASIZE_8BIT; + hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; + hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; + hspi1.Init.NSS = SPI_NSS_SOFT; + hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8; + hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; + hspi1.Init.TIMode = SPI_TIMODE_DISABLE; + hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; + hspi1.Init.CRCPolynomial = 10; + if (HAL_SPI_Init(&hspi1) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN SPI1_Init 2 */ + + /* USER CODE END SPI1_Init 2 */ + +} + /** * @brief SPI2 Initialization Function * @param None diff --git a/bsp/stm32/stm32f103-hw100k-ibox/board/CubeMX_Config/Src/stm32f1xx_hal_msp.c b/bsp/stm32/stm32f103-hw100k-ibox/board/CubeMX_Config/Src/stm32f1xx_hal_msp.c index c21e9b8db698bd54d03374731881381589523371..a70b36e9dc7810c5e09b089bae05faea000524bc 100644 --- a/bsp/stm32/stm32f103-hw100k-ibox/board/CubeMX_Config/Src/stm32f1xx_hal_msp.c +++ b/bsp/stm32/stm32f103-hw100k-ibox/board/CubeMX_Config/Src/stm32f1xx_hal_msp.c @@ -226,7 +226,35 @@ void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi) { GPIO_InitTypeDef GPIO_InitStruct = {0}; - if(hspi->Instance==SPI2) + if(hspi->Instance==SPI1) + { + /* USER CODE BEGIN SPI1_MspInit 0 */ + + /* USER CODE END SPI1_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_SPI1_CLK_ENABLE(); + + __HAL_RCC_GPIOA_CLK_ENABLE(); + /**SPI1 GPIO Configuration + PA5 ------> SPI1_SCK + PA6 ------> SPI1_MISO + PA7 ------> SPI1_MOSI + */ + GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_7; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = GPIO_PIN_6; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* USER CODE BEGIN SPI1_MspInit 1 */ + + /* USER CODE END SPI1_MspInit 1 */ + } + else if(hspi->Instance==SPI2) { /* USER CODE BEGIN SPI2_MspInit 0 */ @@ -267,7 +295,26 @@ void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi) void HAL_SPI_MspDeInit(SPI_HandleTypeDef* hspi) { - if(hspi->Instance==SPI2) + if(hspi->Instance==SPI1) + { + /* USER CODE BEGIN SPI1_MspDeInit 0 */ + + /* USER CODE END SPI1_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_SPI1_CLK_DISABLE(); + + /**SPI1 GPIO Configuration + PA5 ------> SPI1_SCK + PA6 ------> SPI1_MISO + PA7 ------> SPI1_MOSI + */ + HAL_GPIO_DeInit(GPIOA, GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7); + + /* USER CODE BEGIN SPI1_MspDeInit 1 */ + + /* USER CODE END SPI1_MspDeInit 1 */ + } + else if(hspi->Instance==SPI2) { /* USER CODE BEGIN SPI2_MspDeInit 0 */ diff --git a/bsp/stm32/stm32f103-hw100k-ibox/board/Kconfig b/bsp/stm32/stm32f103-hw100k-ibox/board/Kconfig index 875b025bb6ca29521373da5fefb8f2a0ff0cb0f9..e21b212d87c00e8815e7a2a454c3d70e8dffa7c4 100644 --- a/bsp/stm32/stm32f103-hw100k-ibox/board/Kconfig +++ b/bsp/stm32/stm32f103-hw100k-ibox/board/Kconfig @@ -35,6 +35,49 @@ menu "Onboard Peripheral Drivers" hex default 0x00 + endif + config BSP_USING_LORA + bool "Enable LoRa Driver (spi1)" + default n + select PKG_USING_SX12XX + select SX12XX_DEVICE_EXTERN_CONFIG + select BSP_USING_SPI1 + if BSP_USING_LORA + if SX12XX_DEVICE_EXTERN_CONFIG + config SX12XX_SPI_DEVICE + string "SPI device name" + default "spi10" + + config SX12XX_RST_PIN + int "Reset PIN number" + default 7 + + config SX12XX_DO0_PIN + int "DO0 PIN number" + default 103 + + config SX12XX_DO1_PIN + int "DO1 PIN number" + default 104 + + config SX12XX_DO2_PIN + int "DO2 PIN number" + default 105 + + config SX12XX_DO3_PIN + int "DO3 PIN number" + default 106 + + config SX12XX_DO4_PIN + int "DO4 PIN number" + default 107 + + config SX12XX_DO5_PIN + int "DO5 PIN number" + default 108 + + endif + endif endmenu @@ -65,8 +108,8 @@ menu "On-chip Peripheral Drivers" config BSP_UART2_RX_USING_DMA bool "Enable UART2 RX DMA" depends on BSP_USING_UART2 && RT_SERIAL_USING_DMA - default n - + default n + config BSP_USING_UART3 bool "Enable UART3" default n @@ -75,15 +118,18 @@ menu "On-chip Peripheral Drivers" bool "Enable UART3 RX DMA" depends on BSP_USING_UART3 && RT_SERIAL_USING_DMA default n - + config BSP_USING_UART4 bool "Enable UART4" default n config BSP_UART4_RX_USING_DMA bool "Enable UART4 RX DMA" - depends on BSP_USING_UART4 && RT_SERIAL_USING_DMA + depends on BSP_USING_UART4 && RT_SERIAL_USING_DMA endif + config BSP_USING_ON_CHIP_FLASH + bool "Enable on-chip FLASH" + default n menuconfig BSP_USING_I2C1 bool "Enable I2C1 BUS (software simulation)" default n @@ -94,11 +140,11 @@ menu "On-chip Peripheral Drivers" config BSP_I2C1_SCL_PIN int "i2c1 scl pin number" range 0 144 - default 22 + default 22 config BSP_I2C1_SDA_PIN int "I2C1 sda pin number" range 0 144 - default 23 + default 23 endif menuconfig BSP_USING_SPI bool "Enable SPI BUS" @@ -113,7 +159,7 @@ menu "On-chip Peripheral Drivers" bool "Enable SPI1 TX DMA" depends on BSP_USING_SPI1 default n - + config BSP_SPI1_RX_USING_DMA bool "Enable SPI1 RX DMA" depends on BSP_USING_SPI1 @@ -122,18 +168,18 @@ menu "On-chip Peripheral Drivers" config BSP_USING_SPI2 bool "Enable SPI2 BUS" - default n - + default n + config BSP_SPI2_TX_USING_DMA bool "Enable SPI2 TX DMA" depends on BSP_USING_SPI2 default n - + config BSP_SPI2_RX_USING_DMA bool "Enable SPI2 RX DMA" depends on BSP_USING_SPI2 select BSP_SPI2_TX_USING_DMA - default n + default n endif @@ -145,8 +191,8 @@ menu "On-chip Peripheral Drivers" config BSP_USING_ADC1 bool "Enable ADC1" default n - endif - + endif + menuconfig BSP_USING_ONCHIP_RTC bool "Enable RTC" select RT_USING_RTC @@ -168,7 +214,7 @@ menu "On-chip Peripheral Drivers" config BSP_USING_WDT bool "Enable Watchdog Timer" select RT_USING_WDT - default n + default n endmenu menu "Board extended module Drivers" diff --git a/bsp/stm32/stm32f103-hw100k-ibox/board/SConscript b/bsp/stm32/stm32f103-hw100k-ibox/board/SConscript index 07307afa2a50a2e5447cf66a7995e725711fe56c..725bb2effb3bdb12cf12b2bcb77b8e1807b2d3c2 100644 --- a/bsp/stm32/stm32f103-hw100k-ibox/board/SConscript +++ b/bsp/stm32/stm32f103-hw100k-ibox/board/SConscript @@ -16,6 +16,9 @@ if GetDepend(['BSP_USING_ETH']): if GetDepend(['BSP_USING_WIFI_OR_GPRS']): src += Glob('ports/esp02_device.c') +if GetDepend(['BSP_USING_ON_CHIP_FLASH']): + src += Glob('ports/on_chip_flash_init.c') + path = [cwd] path += [cwd + '/CubeMX_Config/Inc'] path += [cwd + '/ports'] diff --git a/bsp/stm32/stm32f103-hw100k-ibox/board/ports/fal_cfg.h b/bsp/stm32/stm32f103-hw100k-ibox/board/ports/fal_cfg.h new file mode 100644 index 0000000000000000000000000000000000000000..5f83366ea09a964fdf1ebe78c07907a5dc70d4db --- /dev/null +++ b/bsp/stm32/stm32f103-hw100k-ibox/board/ports/fal_cfg.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018-12-5 SummerGift first version + */ + +#ifndef _FAL_CFG_H_ +#define _FAL_CFG_H_ + +#include +#include + +extern const struct fal_flash_dev stm32_onchip_flash; + +/* flash device table */ +#define FAL_FLASH_DEV_TABLE \ +{ \ + &stm32_onchip_flash, \ +} +/* ====================== Partition Configuration ========================== */ +#ifdef FAL_PART_HAS_TABLE_CFG + +/* partition table */ +#define FAL_PART_TABLE \ +{ \ + {FAL_PART_MAGIC_WROD, "app", "onchip_flash", 0, 496 * 1024, 0}, \ + {FAL_PART_MAGIC_WROD, "param", "onchip_flash", 496* 1024 , 16 * 1024, 0}, \ +} +#endif /* FAL_PART_HAS_TABLE_CFG */ +#endif /* _FAL_CFG_H_ */ diff --git a/bsp/stm32/stm32f103-hw100k-ibox/board/ports/on_chip_flash_init.c b/bsp/stm32/stm32f103-hw100k-ibox/board/ports/on_chip_flash_init.c new file mode 100644 index 0000000000000000000000000000000000000000..be8978c63dfe36373bf29ddd34053a490703e143 --- /dev/null +++ b/bsp/stm32/stm32f103-hw100k-ibox/board/ports/on_chip_flash_init.c @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018-11-27 SummerGift add spi flash port file + */ + +#include +#include "fal.h" + +#if defined(BSP_USING_ON_CHIP_FLASH) +static int rt_hw_on_chip_flash_init(void) +{ + fal_init(); + return RT_EOK; +} +INIT_COMPONENT_EXPORT(rt_hw_on_chip_flash_init); +#endif + diff --git a/bsp/stm32/stm32f411-st-nucleo/.config b/bsp/stm32/stm32f411-st-nucleo/.config index 6df7485ea9463097923ad7cc45bb3dfbeeafd6da..61c05d6feb3b2b14a7824a43f8785963348abdc6 100644 --- a/bsp/stm32/stm32f411-st-nucleo/.config +++ b/bsp/stm32/stm32f411-st-nucleo/.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 @@ -111,6 +112,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 @@ -185,12 +187,6 @@ CONFIG_RT_USING_PIN=y # CONFIG_RT_USING_RYM is not set # CONFIG_RT_USING_ULOG is not set # CONFIG_RT_USING_UTEST is not set - -# -# ARM CMSIS -# -# CONFIG_RT_USING_CMSIS_OS is not set -# CONFIG_RT_USING_RTT_CMSIS is not set # CONFIG_RT_USING_LWP is not set # @@ -207,6 +203,7 @@ CONFIG_RT_USING_PIN=y # 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_LJSON is not set # CONFIG_PKG_USING_EZXML is not set # CONFIG_PKG_USING_NANOPB is not set @@ -224,6 +221,7 @@ 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 @@ -238,6 +236,8 @@ CONFIG_RT_USING_PIN=y # 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_NIMBLE is not set +# CONFIG_PKG_USING_OTA_DOWNLOADER is not set # # security packages @@ -258,6 +258,7 @@ 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 # # tools packages @@ -269,6 +270,7 @@ CONFIG_RT_USING_PIN=y # 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 # # system packages @@ -286,10 +288,12 @@ CONFIG_RT_USING_PIN=y # 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 # # 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_AHT10 is not set @@ -300,7 +304,11 @@ CONFIG_RT_USING_PIN=y # 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_WM_LIBRARIES is not set # CONFIG_PKG_USING_KENDRYTE_SDK is not set +# CONFIG_PKG_USING_INFRARED is not set # # miscellaneous packages @@ -326,6 +334,8 @@ CONFIG_RT_USING_PIN=y # 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_SOC_FAMILY_STM32=y CONFIG_SOC_SERIES_STM32F4=y @@ -344,8 +354,11 @@ CONFIG_SOC_STM32F411RE=y CONFIG_BSP_USING_GPIO=y CONFIG_BSP_USING_UART=y CONFIG_BSP_USING_UART2=y +# CONFIG_BSP_USING_UART6 is not set # CONFIG_BSP_USING_I2C1 is not set +# CONFIG_BSP_USING_SPI is not set # CONFIG_BSP_USING_PWM is not set +# CONFIG_BSP_USING_ONCHIP_RTC is not set # CONFIG_BSP_USING_ON_CHIP_FLASH is not set # diff --git a/bsp/stm32/stm32f411-st-nucleo/board/CubeMX_Config/CubeMX_Config.ioc b/bsp/stm32/stm32f411-st-nucleo/board/CubeMX_Config/CubeMX_Config.ioc index 81e4b8cf645fd4c93896f232c6e81f3f472f9289..68d45640ce6e46472059002d156e55436f2844c0 100644 --- a/bsp/stm32/stm32f411-st-nucleo/board/CubeMX_Config/CubeMX_Config.ioc +++ b/bsp/stm32/stm32f411-st-nucleo/board/CubeMX_Config/CubeMX_Config.ioc @@ -2,24 +2,34 @@ File.Version=6 KeepUserPlacement=true Mcu.Family=STM32F4 -Mcu.IP0=NVIC -Mcu.IP1=RCC -Mcu.IP2=SYS -Mcu.IP3=TIM3 -Mcu.IP4=USART2 -Mcu.IPNb=5 +Mcu.IP0=IWDG +Mcu.IP1=NVIC +Mcu.IP2=RCC +Mcu.IP3=RTC +Mcu.IP4=SPI1 +Mcu.IP5=SYS +Mcu.IP6=TIM3 +Mcu.IP7=USART2 +Mcu.IP8=USART6 +Mcu.IPNb=9 Mcu.Name=STM32F411R(C-E)Tx Mcu.Package=LQFP64 Mcu.Pin0=PC13-ANTI_TAMP Mcu.Pin1=PC14-OSC32_IN Mcu.Pin10=PB0 Mcu.Pin11=PB1 -Mcu.Pin12=PA13 -Mcu.Pin13=PA14 -Mcu.Pin14=PB3 -Mcu.Pin15=VP_SYS_VS_Systick -Mcu.Pin16=VP_TIM3_VS_ClockSourceINT +Mcu.Pin12=PA11 +Mcu.Pin13=PA12 +Mcu.Pin14=PA13 +Mcu.Pin15=PA14 +Mcu.Pin16=PB3 +Mcu.Pin17=PB4 +Mcu.Pin18=PB5 +Mcu.Pin19=VP_IWDG_VS_IWDG Mcu.Pin2=PC15-OSC32_OUT +Mcu.Pin20=VP_RTC_VS_RTC_Activate +Mcu.Pin21=VP_SYS_VS_Systick +Mcu.Pin22=VP_TIM3_VS_ClockSourceINT Mcu.Pin3=PH0 - OSC_IN Mcu.Pin4=PH1 - OSC_OUT Mcu.Pin5=PA2 @@ -27,7 +37,7 @@ Mcu.Pin6=PA3 Mcu.Pin7=PA5 Mcu.Pin8=PA6 Mcu.Pin9=PA7 -Mcu.PinsNb=17 +Mcu.PinsNb=23 Mcu.ThirdPartyNb=0 Mcu.UserConstants= Mcu.UserName=STM32F411RETx @@ -43,6 +53,12 @@ NVIC.PriorityGroup=NVIC_PRIORITYGROUP_0 NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false NVIC.SysTick_IRQn=true\:0\:0\:true\:false\:true\:true NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:true +PA11.Locked=true +PA11.Mode=Asynchronous +PA11.Signal=USART6_TX +PA12.Locked=true +PA12.Mode=Asynchronous +PA12.Signal=USART6_RX PA13.GPIOParameters=GPIO_Label PA13.GPIO_Label=TMS PA13.Locked=true @@ -57,10 +73,8 @@ PA2.Mode=Asynchronous PA2.Signal=USART2_TX PA3.Mode=Asynchronous PA3.Signal=USART2_RX -PA5.GPIOParameters=GPIO_Label -PA5.GPIO_Label=LD2 [Green Led] -PA5.Locked=true -PA5.Signal=GPIO_Output +PA5.Mode=Full_Duplex_Master +PA5.Signal=SPI1_SCK PA6.Signal=S_TIM3_CH1 PA7.Signal=S_TIM3_CH2 PB0.Signal=S_TIM3_CH3 @@ -69,6 +83,10 @@ PB3.GPIOParameters=GPIO_Label PB3.GPIO_Label=SWO PB3.Locked=true PB3.Signal=SYS_JTDO-SWO +PB4.Mode=Full_Duplex_Master +PB4.Signal=SPI1_MISO +PB5.Mode=Full_Duplex_Master +PB5.Signal=SPI1_MOSI PC13-ANTI_TAMP.GPIOParameters=GPIO_Label,GPIO_ModeDefaultEXTI PC13-ANTI_TAMP.GPIO_Label=B1 [Blue PushButton] PC13-ANTI_TAMP.GPIO_ModeDefaultEXTI=GPIO_MODE_IT_FALLING @@ -121,7 +139,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_USART2_UART_Init-USART2-false-HAL-true,4-MX_TIM3_Init-TIM3-false-HAL-true +ProjectManager.functionlistsort=1-MX_GPIO_Init-GPIO-false-HAL-true,2-SystemClock_Config-RCC-false-HAL-false,3-MX_USART2_UART_Init-USART2-false-HAL-true,4-MX_TIM3_Init-TIM3-false-HAL-true,5-MX_USART6_UART_Init-USART6-false-HAL-true,6-MX_RTC_Init-RTC-false-HAL-true,7-MX_IWDG_Init-IWDG-false-HAL-true,8-MX_SPI1_Init-SPI1-false-HAL-true RCC.48MHZClocksFreq_Value=42000000 RCC.AHBFreq_Value=84000000 RCC.APB1CLKDivider=RCC_HCLK_DIV2 @@ -165,6 +183,11 @@ SH.S_TIM3_CH3.0=TIM3_CH3,PWM Generation3 CH3 SH.S_TIM3_CH3.ConfNb=1 SH.S_TIM3_CH4.0=TIM3_CH4,PWM Generation4 CH4 SH.S_TIM3_CH4.ConfNb=1 +SPI1.CalculateBaudRate=42.0 MBits/s +SPI1.Direction=SPI_DIRECTION_2LINES +SPI1.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate +SPI1.Mode=SPI_MODE_MASTER +SPI1.VirtualType=VM_MASTER TIM3.Channel-PWM\ Generation1\ CH1=TIM_CHANNEL_1 TIM3.Channel-PWM\ Generation2\ CH2=TIM_CHANNEL_2 TIM3.Channel-PWM\ Generation3\ CH3=TIM_CHANNEL_3 @@ -172,6 +195,12 @@ TIM3.Channel-PWM\ Generation4\ CH4=TIM_CHANNEL_4 TIM3.IPParameters=Channel-PWM Generation1 CH1,Channel-PWM Generation2 CH2,Channel-PWM Generation3 CH3,Channel-PWM Generation4 CH4 USART2.IPParameters=VirtualMode USART2.VirtualMode=VM_ASYNC +USART6.IPParameters=VirtualMode +USART6.VirtualMode=VM_ASYNC +VP_IWDG_VS_IWDG.Mode=IWDG_Activate +VP_IWDG_VS_IWDG.Signal=IWDG_VS_IWDG +VP_RTC_VS_RTC_Activate.Mode=RTC_Enabled +VP_RTC_VS_RTC_Activate.Signal=RTC_VS_RTC_Activate VP_SYS_VS_Systick.Mode=SysTick VP_SYS_VS_Systick.Signal=SYS_VS_Systick VP_TIM3_VS_ClockSourceINT.Mode=Internal diff --git a/bsp/stm32/stm32f411-st-nucleo/board/CubeMX_Config/Inc/main.h b/bsp/stm32/stm32f411-st-nucleo/board/CubeMX_Config/Inc/main.h index 3651f0788e74ded2316c9f225f16ab897537b34b..7dd412343c61a118e6d8b23d3ba71ac0eccd982f 100644 --- a/bsp/stm32/stm32f411-st-nucleo/board/CubeMX_Config/Inc/main.h +++ b/bsp/stm32/stm32f411-st-nucleo/board/CubeMX_Config/Inc/main.h @@ -82,8 +82,6 @@ void Error_Handler(void); /* Private defines -----------------------------------------------------------*/ #define B1_Pin GPIO_PIN_13 #define B1_GPIO_Port GPIOC -#define LD2_Pin GPIO_PIN_5 -#define LD2_GPIO_Port GPIOA #define TMS_Pin GPIO_PIN_13 #define TMS_GPIO_Port GPIOA #define TCK_Pin GPIO_PIN_14 diff --git a/bsp/stm32/stm32f411-st-nucleo/board/CubeMX_Config/Inc/stm32f4xx_hal_conf.h b/bsp/stm32/stm32f411-st-nucleo/board/CubeMX_Config/Inc/stm32f4xx_hal_conf.h index c2972886009278570a61ce1fd53cdf4b830c5eb0..a3ef6ecaa71c3f345aedd1ebcf78220eaa371ace 100644 --- a/bsp/stm32/stm32f411-st-nucleo/board/CubeMX_Config/Inc/stm32f4xx_hal_conf.h +++ b/bsp/stm32/stm32f411-st-nucleo/board/CubeMX_Config/Inc/stm32f4xx_hal_conf.h @@ -66,14 +66,14 @@ /* #define HAL_HASH_MODULE_ENABLED */ /* #define HAL_I2C_MODULE_ENABLED */ /* #define HAL_I2S_MODULE_ENABLED */ -/* #define HAL_IWDG_MODULE_ENABLED */ +#define HAL_IWDG_MODULE_ENABLED /* #define HAL_LTDC_MODULE_ENABLED */ /* #define HAL_RNG_MODULE_ENABLED */ -/* #define HAL_RTC_MODULE_ENABLED */ +#define HAL_RTC_MODULE_ENABLED /* #define HAL_SAI_MODULE_ENABLED */ /* #define HAL_SD_MODULE_ENABLED */ /* #define HAL_MMC_MODULE_ENABLED */ -/* #define HAL_SPI_MODULE_ENABLED */ +#define HAL_SPI_MODULE_ENABLED #define HAL_TIM_MODULE_ENABLED #define HAL_UART_MODULE_ENABLED /* #define HAL_USART_MODULE_ENABLED */ diff --git a/bsp/stm32/stm32f411-st-nucleo/board/CubeMX_Config/Src/main.c b/bsp/stm32/stm32f411-st-nucleo/board/CubeMX_Config/Src/main.c index cb90fe22eb77d4d30f1c5eff74db1b6756d4eb65..5fcc4359e78cce16b7e77abcf9f514334c0a11df 100644 --- a/bsp/stm32/stm32f411-st-nucleo/board/CubeMX_Config/Src/main.c +++ b/bsp/stm32/stm32f411-st-nucleo/board/CubeMX_Config/Src/main.c @@ -62,9 +62,16 @@ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ +IWDG_HandleTypeDef hiwdg; + +RTC_HandleTypeDef hrtc; + +SPI_HandleTypeDef hspi1; + TIM_HandleTypeDef htim3; UART_HandleTypeDef huart2; +UART_HandleTypeDef huart6; /* USER CODE BEGIN PV */ @@ -75,6 +82,10 @@ void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_USART2_UART_Init(void); static void MX_TIM3_Init(void); +static void MX_USART6_UART_Init(void); +static void MX_RTC_Init(void); +static void MX_IWDG_Init(void); +static void MX_SPI1_Init(void); /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ @@ -114,6 +125,10 @@ int main(void) MX_GPIO_Init(); MX_USART2_UART_Init(); MX_TIM3_Init(); + MX_USART6_UART_Init(); + MX_RTC_Init(); + MX_IWDG_Init(); + MX_SPI1_Init(); /* USER CODE BEGIN 2 */ /* USER CODE END 2 */ @@ -137,6 +152,7 @@ void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; /**Configure the main internal regulator output voltage */ @@ -144,8 +160,9 @@ void SystemClock_Config(void) __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); /**Initializes the CPU, AHB and APB busses clocks */ - RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI|RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS; + RCC_OscInitStruct.LSIState = RCC_LSI_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = 4; @@ -169,6 +186,112 @@ void SystemClock_Config(void) { Error_Handler(); } + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC; + PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSI; + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) + { + Error_Handler(); + } +} + +/** + * @brief IWDG Initialization Function + * @param None + * @retval None + */ +static void MX_IWDG_Init(void) +{ + + /* USER CODE BEGIN IWDG_Init 0 */ + + /* USER CODE END IWDG_Init 0 */ + + /* USER CODE BEGIN IWDG_Init 1 */ + + /* USER CODE END IWDG_Init 1 */ + hiwdg.Instance = IWDG; + hiwdg.Init.Prescaler = IWDG_PRESCALER_4; + hiwdg.Init.Reload = 4095; + if (HAL_IWDG_Init(&hiwdg) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN IWDG_Init 2 */ + + /* USER CODE END IWDG_Init 2 */ + +} + +/** + * @brief RTC Initialization Function + * @param None + * @retval None + */ +static void MX_RTC_Init(void) +{ + + /* USER CODE BEGIN RTC_Init 0 */ + + /* USER CODE END RTC_Init 0 */ + + /* USER CODE BEGIN RTC_Init 1 */ + + /* USER CODE END RTC_Init 1 */ + /**Initialize RTC Only + */ + hrtc.Instance = RTC; + hrtc.Init.HourFormat = RTC_HOURFORMAT_24; + hrtc.Init.AsynchPrediv = 127; + hrtc.Init.SynchPrediv = 255; + hrtc.Init.OutPut = RTC_OUTPUT_DISABLE; + hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH; + hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN; + if (HAL_RTC_Init(&hrtc) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN RTC_Init 2 */ + + /* USER CODE END RTC_Init 2 */ + +} + +/** + * @brief SPI1 Initialization Function + * @param None + * @retval None + */ +static void MX_SPI1_Init(void) +{ + + /* USER CODE BEGIN SPI1_Init 0 */ + + /* USER CODE END SPI1_Init 0 */ + + /* USER CODE BEGIN SPI1_Init 1 */ + + /* USER CODE END SPI1_Init 1 */ + /* SPI1 parameter configuration*/ + hspi1.Instance = SPI1; + hspi1.Init.Mode = SPI_MODE_MASTER; + hspi1.Init.Direction = SPI_DIRECTION_2LINES; + hspi1.Init.DataSize = SPI_DATASIZE_8BIT; + hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; + hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; + hspi1.Init.NSS = SPI_NSS_SOFT; + hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2; + hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; + hspi1.Init.TIMode = SPI_TIMODE_DISABLE; + hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; + hspi1.Init.CRCPolynomial = 10; + if (HAL_SPI_Init(&hspi1) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN SPI1_Init 2 */ + + /* USER CODE END SPI1_Init 2 */ + } /** @@ -274,6 +397,39 @@ static void MX_USART2_UART_Init(void) } +/** + * @brief USART6 Initialization Function + * @param None + * @retval None + */ +static void MX_USART6_UART_Init(void) +{ + + /* USER CODE BEGIN USART6_Init 0 */ + + /* USER CODE END USART6_Init 0 */ + + /* USER CODE BEGIN USART6_Init 1 */ + + /* USER CODE END USART6_Init 1 */ + huart6.Instance = USART6; + huart6.Init.BaudRate = 115200; + huart6.Init.WordLength = UART_WORDLENGTH_8B; + huart6.Init.StopBits = UART_STOPBITS_1; + huart6.Init.Parity = UART_PARITY_NONE; + huart6.Init.Mode = UART_MODE_TX_RX; + huart6.Init.HwFlowCtl = UART_HWCONTROL_NONE; + huart6.Init.OverSampling = UART_OVERSAMPLING_16; + if (HAL_UART_Init(&huart6) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN USART6_Init 2 */ + + /* USER CODE END USART6_Init 2 */ + +} + /** * @brief GPIO Initialization Function * @param None @@ -289,22 +445,12 @@ static void MX_GPIO_Init(void) __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); - /*Configure GPIO pin Output Level */ - HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_RESET); - /*Configure GPIO pin : B1_Pin */ GPIO_InitStruct.Pin = B1_Pin; GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(B1_GPIO_Port, &GPIO_InitStruct); - /*Configure GPIO pin : LD2_Pin */ - GPIO_InitStruct.Pin = LD2_Pin; - GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; - HAL_GPIO_Init(LD2_GPIO_Port, &GPIO_InitStruct); - } /* USER CODE BEGIN 4 */ diff --git a/bsp/stm32/stm32f411-st-nucleo/board/CubeMX_Config/Src/stm32f4xx_hal_msp.c b/bsp/stm32/stm32f411-st-nucleo/board/CubeMX_Config/Src/stm32f4xx_hal_msp.c index 0cc7029333cc2d782d590961df8d1efcbe7ee25f..b2c91f0c47030fa405e4ac885e517e447ba0a7dd 100644 --- a/bsp/stm32/stm32f411-st-nucleo/board/CubeMX_Config/Src/stm32f4xx_hal_msp.c +++ b/bsp/stm32/stm32f411-st-nucleo/board/CubeMX_Config/Src/stm32f4xx_hal_msp.c @@ -101,6 +101,133 @@ void HAL_MspInit(void) /* USER CODE END MspInit 1 */ } +/** +* @brief RTC MSP Initialization +* This function configures the hardware resources used in this example +* @param hrtc: RTC handle pointer +* @retval None +*/ +void HAL_RTC_MspInit(RTC_HandleTypeDef* hrtc) +{ + + if(hrtc->Instance==RTC) + { + /* USER CODE BEGIN RTC_MspInit 0 */ + + /* USER CODE END RTC_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_RTC_ENABLE(); + /* USER CODE BEGIN RTC_MspInit 1 */ + + /* USER CODE END RTC_MspInit 1 */ + } + +} + +/** +* @brief RTC MSP De-Initialization +* This function freeze the hardware resources used in this example +* @param hrtc: RTC handle pointer +* @retval None +*/ + +void HAL_RTC_MspDeInit(RTC_HandleTypeDef* hrtc) +{ + + if(hrtc->Instance==RTC) + { + /* USER CODE BEGIN RTC_MspDeInit 0 */ + + /* USER CODE END RTC_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_RTC_DISABLE(); + /* USER CODE BEGIN RTC_MspDeInit 1 */ + + /* USER CODE END RTC_MspDeInit 1 */ + } + +} + +/** +* @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==SPI1) + { + /* USER CODE BEGIN SPI1_MspInit 0 */ + + /* USER CODE END SPI1_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_SPI1_CLK_ENABLE(); + + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + /**SPI1 GPIO Configuration + PA5 ------> SPI1_SCK + PB4 ------> SPI1_MISO + PB5 ------> SPI1_MOSI + */ + GPIO_InitStruct.Pin = GPIO_PIN_5; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF5_SPI1; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_5; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF5_SPI1; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + /* USER CODE BEGIN SPI1_MspInit 1 */ + + /* USER CODE END SPI1_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==SPI1) + { + /* USER CODE BEGIN SPI1_MspDeInit 0 */ + + /* USER CODE END SPI1_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_SPI1_CLK_DISABLE(); + + /**SPI1 GPIO Configuration + PA5 ------> SPI1_SCK + PB4 ------> SPI1_MISO + PB5 ------> SPI1_MOSI + */ + HAL_GPIO_DeInit(GPIOA, GPIO_PIN_5); + + HAL_GPIO_DeInit(GPIOB, GPIO_PIN_4|GPIO_PIN_5); + + /* USER CODE BEGIN SPI1_MspDeInit 1 */ + + /* USER CODE END SPI1_MspDeInit 1 */ + } + +} + /** * @brief TIM_Base MSP Initialization * This function configures the hardware resources used in this example @@ -220,6 +347,30 @@ void HAL_UART_MspInit(UART_HandleTypeDef* huart) /* USER CODE END USART2_MspInit 1 */ } + else if(huart->Instance==USART6) + { + /* USER CODE BEGIN USART6_MspInit 0 */ + + /* USER CODE END USART6_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_USART6_CLK_ENABLE(); + + __HAL_RCC_GPIOA_CLK_ENABLE(); + /**USART6 GPIO Configuration + PA11 ------> USART6_TX + PA12 ------> USART6_RX + */ + GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF8_USART6; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* USER CODE BEGIN USART6_MspInit 1 */ + + /* USER CODE END USART6_MspInit 1 */ + } } @@ -251,6 +402,24 @@ void HAL_UART_MspDeInit(UART_HandleTypeDef* huart) /* USER CODE END USART2_MspDeInit 1 */ } + else if(huart->Instance==USART6) + { + /* USER CODE BEGIN USART6_MspDeInit 0 */ + + /* USER CODE END USART6_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_USART6_CLK_DISABLE(); + + /**USART6 GPIO Configuration + PA11 ------> USART6_TX + PA12 ------> USART6_RX + */ + HAL_GPIO_DeInit(GPIOA, GPIO_PIN_11|GPIO_PIN_12); + + /* USER CODE BEGIN USART6_MspDeInit 1 */ + + /* USER CODE END USART6_MspDeInit 1 */ + } } diff --git a/bsp/stm32/stm32f411-st-nucleo/board/Kconfig b/bsp/stm32/stm32f411-st-nucleo/board/Kconfig index 92402d950d92ce2f69149a28fb6e9129653c18a3..92982f2158c52aaa49fdcba17ffb1c864d4c5009 100644 --- a/bsp/stm32/stm32f411-st-nucleo/board/Kconfig +++ b/bsp/stm32/stm32f411-st-nucleo/board/Kconfig @@ -29,6 +29,15 @@ menu "On-chip Peripheral Drivers" bool "Enable UART2 RX DMA" depends on BSP_USING_UART2 && RT_SERIAL_USING_DMA default n + + config BSP_USING_UART6 + bool "Enable UART6" + default y + + config BSP_UART6_RX_USING_DMA + bool "Enable UART6 RX DMA" + depends on BSP_USING_UART6 && RT_SERIAL_USING_DMA + default n endif menuconfig BSP_USING_I2C1 @@ -38,14 +47,36 @@ menu "On-chip Peripheral Drivers" select RT_USING_I2C_BITOPS select RT_USING_PIN if BSP_USING_I2C1 + comment "Notice: PB8 --> 24; PB9 --> 25" config BSP_I2C1_SCL_PIN int "i2c1 scl pin number" range 0 80 - default 30 + default 24 config BSP_I2C1_SDA_PIN int "I2C1 sda pin number" range 0 80 - default 31 + default 25 + endif + + menuconfig BSP_USING_SPI + bool "Enable SPI BUS" + default n + select RT_USING_SPI + if BSP_USING_SPI + config BSP_USING_SPI1 + bool "Enable SPI1 BUS" + default n + + config BSP_SPI1_TX_USING_DMA + bool "Enable SPI1 TX DMA" + depends on BSP_USING_SPI1 + default n + + config BSP_SPI1_RX_USING_DMA + bool "Enable SPI1 RX DMA" + depends on BSP_USING_SPI1 + select BSP_SPI1_TX_USING_DMA + default n endif menuconfig BSP_USING_PWM @@ -75,6 +106,24 @@ menu "On-chip Peripheral Drivers" endif endif + menuconfig BSP_USING_ONCHIP_RTC + bool "Enable RTC" + select RT_USING_RTC + select RT_USING_LIBC + default n + if BSP_USING_ONCHIP_RTC + choice + prompt "Select clock source" + default BSP_RTC_USING_LSE + + config BSP_RTC_USING_LSE + bool "RTC USING LSE" + + config BSP_RTC_USING_LSI + bool "RTC USING LSI" + endchoice + endif + config BSP_USING_ON_CHIP_FLASH bool "Enable on-chip FLASH" default n diff --git a/bsp/stm32/stm32f411-st-nucleo/board/board.c b/bsp/stm32/stm32f411-st-nucleo/board/board.c index 20fb37099ce7499a473ea2dc1627a95f760e34a1..e9e6ffb5e716f9a646ef73b9fa9bd1122193d18a 100644 --- a/bsp/stm32/stm32f411-st-nucleo/board/board.c +++ b/bsp/stm32/stm32f411-st-nucleo/board/board.c @@ -14,6 +14,7 @@ void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; /**Configure the main internal regulator output voltage */ @@ -21,8 +22,9 @@ void SystemClock_Config(void) __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); /**Initializes the CPU, AHB and APB busses clocks */ - RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI|RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS; + RCC_OscInitStruct.LSIState = RCC_LSI_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = 4; @@ -46,4 +48,10 @@ void SystemClock_Config(void) { Error_Handler(); } + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC; + PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSI; + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) + { + Error_Handler(); + } } diff --git a/bsp/stm32/stm32f411-st-nucleo/rtconfig.h b/bsp/stm32/stm32f411-st-nucleo/rtconfig.h index 1d7b6ca3f093c40049897fa47d80766c4a81ffab..3f842a28cbe7ddef2345ef71648d1aac3909098a 100644 --- a/bsp/stm32/stm32f411-st-nucleo/rtconfig.h +++ b/bsp/stm32/stm32f411-st-nucleo/rtconfig.h @@ -110,9 +110,6 @@ /* Utilities */ -/* ARM CMSIS */ - - /* RT-Thread online packages */ /* IoT - internet of things */ diff --git a/components/cplusplus/Mail.h b/components/cplusplus/Mail.h index e6b11af9e8e28ee3df8fe93ef645bd216492a0fc..a4c98e4007ea5d925cc06ffe06ba01d4ad493106 100644 --- a/components/cplusplus/Mail.h +++ b/components/cplusplus/Mail.h @@ -28,7 +28,7 @@ template class Mail { public: /** Create and Initialise Mail queue. */ - Mail(const char* name = "") + Mail(const char *name = "") { rt_mb_init(&mID, name, mPool, queue_sz, RT_IPC_FLAG_FIFO); } diff --git a/components/cplusplus/Mutex.h b/components/cplusplus/Mutex.h index 4a54c41ebbbbb665d5564e2085d4b104450bea55..6fee3151555292e5f7fb9cb55845e4dd59e99e01 100644 --- a/components/cplusplus/Mutex.h +++ b/components/cplusplus/Mutex.h @@ -21,7 +21,7 @@ namespace rtthread { class Mutex { public: /** Create and Initialize a Mutex object */ - Mutex(const char* name = "mutex"); + Mutex(const char *name = "mutex"); ~Mutex(); /** Wait until a Mutex becomes available. diff --git a/components/cplusplus/Queue.h b/components/cplusplus/Queue.h index fba64bf51b38559daed3374e14e9c1087ea74448..351e3ec66b1c4585ad97fac97aaca1137ee4756a 100644 --- a/components/cplusplus/Queue.h +++ b/components/cplusplus/Queue.h @@ -68,7 +68,7 @@ public: private: struct rt_messagequeue mID; - char mPool[(sizeof(struct rt_messagequeue)+sizeof(T)) * queue_sz]; + char mPool[(sizeof(struct rt_messagequeue) + sizeof(T)) * queue_sz]; }; } diff --git a/components/cplusplus/Thread.h b/components/cplusplus/Thread.h index 9b6cf30884c971ee9f3644707d00e12508cd8f95..71ee50e1f987ee55473ed61a83e28c40d25d100a 100644 --- a/components/cplusplus/Thread.h +++ b/components/cplusplus/Thread.h @@ -20,7 +20,7 @@ namespace rtthread class Thread { public: - typedef void (*thread_func_t) (void *param); + typedef void (*thread_func_t)(void *param); /** Allocate a new thread without starting execution @param priority initial priority of the thread function. (default: osPriorityNormal). @@ -28,14 +28,14 @@ public: @param stack_pointer pointer to the stack area to be used by this thread (default: NULL). */ Thread(rt_uint32_t stack_size = 2048, - rt_uint8_t priority = (RT_THREAD_PRIORITY_MAX * 2)/3, + rt_uint8_t priority = (RT_THREAD_PRIORITY_MAX * 2) / 3, rt_uint32_t tick = 20, const char *name = "th"); Thread(void (*entry)(void *p), void *p = RT_NULL, rt_uint32_t stack_size = 2048, - rt_uint8_t priority = (RT_THREAD_PRIORITY_MAX * 2)/3, + rt_uint8_t priority = (RT_THREAD_PRIORITY_MAX * 2) / 3, rt_uint32_t tick = 20, const char *name = "th"); diff --git a/components/cplusplus/crt.cpp b/components/cplusplus/crt.cpp index cac1e5fa575e010db472431e0aaf5e2eef95fe9f..d4cb84f77c384223dcf021ec32c5e3ea04f7779e 100644 --- a/components/cplusplus/crt.cpp +++ b/components/cplusplus/crt.cpp @@ -26,7 +26,7 @@ void operator delete(void *ptr) rt_free(ptr); } -void operator delete[] (void *ptr) +void operator delete[](void *ptr) { return rt_free(ptr); } diff --git a/components/cplusplus/crt.h b/components/cplusplus/crt.h index 6228dab2a98a5f115a5820625708df219587dbdf..84e5a4b820abfdaa13dc6bb0e71b28589ddb8bf8 100644 --- a/components/cplusplus/crt.h +++ b/components/cplusplus/crt.h @@ -18,7 +18,7 @@ void *operator new(size_t size); void *operator new[](size_t size); void operator delete(void * ptr); -void operator delete[] (void *ptr); +void operator delete[](void *ptr); extern "C" void __cxa_pure_virtual(void); extern "C" int cplusplus_system_init(void); diff --git a/components/cplusplus/crt_init.c b/components/cplusplus/crt_init.c index 3294b51a40823f75d864d45a6fa4dacb23d6c9ca..fe1293245737a983d59351e2c82aa115b54d4601 100755 --- a/components/cplusplus/crt_init.c +++ b/components/cplusplus/crt_init.c @@ -50,11 +50,11 @@ RT_WEAK int cplusplus_system_init(void) for (; base != lim; base++) { - PROC *proc = (PROC*)((const char*)base + *base); + PROC *proc = (PROC *)((const char *)base + *base); (*proc)(); } #elif defined(__GNUC__) - typedef void(*pfunc) (); + typedef void(*pfunc)(); extern pfunc __ctors_start__[]; extern pfunc __ctors_end__[]; pfunc *p; diff --git a/components/dfs/filesystems/devfs/devfs.c b/components/dfs/filesystems/devfs/devfs.c index 308031287444906211fb18fd708a33572d7208f7..936b074ce1b7ce5fed1cafa97e4bcc919fde0211 100644 --- a/components/dfs/filesystems/devfs/devfs.c +++ b/components/dfs/filesystems/devfs/devfs.c @@ -97,7 +97,7 @@ int dfs_device_fs_close(struct dfs_fd *file) root_dirent = (struct device_dirent *)file->data; RT_ASSERT(root_dirent != RT_NULL); - + /* release dirent */ rt_free(root_dirent); return RT_EOK; @@ -133,7 +133,7 @@ int dfs_device_fs_open(struct dfs_fd *file) struct rt_object_information *information; struct device_dirent *root_dirent; rt_uint32_t count = 0; - + /* lock scheduler */ rt_enter_critical(); @@ -145,8 +145,8 @@ int dfs_device_fs_open(struct dfs_fd *file) count ++; } - root_dirent = (struct device_dirent *)rt_malloc(sizeof(struct device_dirent) + - count * sizeof(rt_device_t)); + root_dirent = (struct device_dirent *)rt_malloc(sizeof(struct device_dirent) + + count * sizeof(rt_device_t)); if (root_dirent != RT_NULL) { root_dirent->devices = (rt_device_t *)(root_dirent + 1); @@ -165,7 +165,7 @@ int dfs_device_fs_open(struct dfs_fd *file) /* set data */ file->data = root_dirent; - + return RT_EOK; } @@ -178,7 +178,7 @@ int dfs_device_fs_open(struct dfs_fd *file) { /* use device fops */ file->fops = device->fops; - file->data = (void*)device; + file->data = (void *)device; /* use fops */ if (file->fops->open) @@ -214,7 +214,7 @@ int dfs_device_fs_stat(struct dfs_filesystem *fs, const char *path, struct stat st->st_dev = 0; st->st_mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH | - S_IWUSR | S_IWGRP | S_IWOTH; + S_IWUSR | S_IWGRP | S_IWOTH; st->st_mode &= ~S_IFREG; st->st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH; @@ -233,7 +233,7 @@ int dfs_device_fs_stat(struct dfs_filesystem *fs, const char *path, struct stat st->st_dev = 0; st->st_mode = S_IRUSR | S_IRGRP | S_IROTH | - S_IWUSR | S_IWGRP | S_IWOTH; + S_IWUSR | S_IWGRP | S_IWOTH; if (dev_id->type == RT_Device_Class_Char) st->st_mode |= S_IFCHR; @@ -293,7 +293,7 @@ static int dfs_device_fs_poll(struct dfs_fd *fd, struct rt_pollreq *req) return mask; } -static const struct dfs_file_ops _device_fops = +static const struct dfs_file_ops _device_fops = { dfs_device_fs_open, dfs_device_fs_close, @@ -306,7 +306,7 @@ static const struct dfs_file_ops _device_fops = dfs_device_fs_poll, }; -static const struct dfs_filesystem_ops _device_fs = +static const struct dfs_filesystem_ops _device_fs = { "devfs", DFS_FS_FLAG_DEFAULT, diff --git a/components/dfs/filesystems/elmfat/dfs_elm.c b/components/dfs/filesystems/elmfat/dfs_elm.c index 582333a714963891150762e91ace48f50666be86..a45c15aa035634991bfad5cfe9083543f6bfe967 100644 --- a/components/dfs/filesystems/elmfat/dfs_elm.c +++ b/components/dfs/filesystems/elmfat/dfs_elm.c @@ -101,7 +101,7 @@ int dfs_elm_mount(struct dfs_filesystem *fs, unsigned long rwflag, const void *d FRESULT result; int index; struct rt_device_blk_geometry geometry; - char logic_nbr[2] = {'0',':'}; + char logic_nbr[2] = {'0', ':'}; /* get an empty position */ index = get_disk(RT_NULL); @@ -129,7 +129,7 @@ int dfs_elm_mount(struct dfs_filesystem *fs, unsigned long rwflag, const void *d } /* mount fatfs, always 0 logic driver */ - result = f_mount(fat, (const TCHAR*)logic_nbr, 1); + result = f_mount(fat, (const TCHAR *)logic_nbr, 1); if (result == FR_OK) { char drive[8]; @@ -139,7 +139,7 @@ int dfs_elm_mount(struct dfs_filesystem *fs, unsigned long rwflag, const void *d dir = (DIR *)rt_malloc(sizeof(DIR)); if (dir == RT_NULL) { - f_mount(RT_NULL, (const TCHAR*)logic_nbr, 1); + f_mount(RT_NULL, (const TCHAR *)logic_nbr, 1); disk[index] = RT_NULL; rt_free(fat); return -ENOMEM; @@ -157,7 +157,7 @@ int dfs_elm_mount(struct dfs_filesystem *fs, unsigned long rwflag, const void *d } __err: - f_mount(RT_NULL, (const TCHAR*)logic_nbr, 1); + f_mount(RT_NULL, (const TCHAR *)logic_nbr, 1); disk[index] = RT_NULL; rt_free(fat); return elm_result_to_dfs(result); @@ -168,7 +168,7 @@ int dfs_elm_unmount(struct dfs_filesystem *fs) FATFS *fat; FRESULT result; int index; - char logic_nbr[2] = {'0',':'}; + char logic_nbr[2] = {'0', ':'}; fat = (FATFS *)fs->data; @@ -180,7 +180,7 @@ int dfs_elm_unmount(struct dfs_filesystem *fs) return -ENOENT; logic_nbr[0] = '0' + index; - result = f_mount(RT_NULL, logic_nbr, (BYTE)1); + result = f_mount(RT_NULL, logic_nbr, (BYTE)1); if (result != FR_OK) return elm_result_to_dfs(result); @@ -200,10 +200,11 @@ int dfs_elm_mkfs(rt_device_t dev_id) int flag; FRESULT result; int index; - char logic_nbr[2] = {'0',':'}; - + char logic_nbr[2] = {'0', ':'}; + work = rt_malloc(_MAX_SS); - if(RT_NULL == work) { + if (RT_NULL == work) + { return -ENOMEM; } @@ -265,14 +266,15 @@ int dfs_elm_mkfs(rt_device_t dev_id) /* [IN] Size of the allocation unit */ /* [-] Working buffer */ /* [IN] Size of working buffer */ - result = f_mkfs(logic_nbr, FM_ANY|FM_SFD, 0, work, _MAX_SS); - rt_free(work); work = RT_NULL; + result = f_mkfs(logic_nbr, FM_ANY | FM_SFD, 0, work, _MAX_SS); + rt_free(work); + work = RT_NULL; /* check flag status, we need clear the temp driver stored in disk[] */ if (flag == FSM_STATUS_USE_TEMP_DRIVER) { rt_free(fat); - f_mount(RT_NULL, logic_nbr,(BYTE)index); + f_mount(RT_NULL, logic_nbr, (BYTE)index); disk[index] = RT_NULL; /* close device */ rt_device_close(dev_id); @@ -778,7 +780,7 @@ int dfs_elm_stat(struct dfs_filesystem *fs, const char *path, struct stat *st) return elm_result_to_dfs(result); } -static const struct dfs_file_ops dfs_elm_fops = +static const struct dfs_file_ops dfs_elm_fops = { dfs_elm_open, dfs_elm_close, @@ -834,7 +836,7 @@ DSTATUS disk_status(BYTE drv) } /* Read Sector(s) */ -DRESULT disk_read (BYTE drv, BYTE* buff, DWORD sector, UINT count) +DRESULT disk_read(BYTE drv, BYTE *buff, DWORD sector, UINT count) { rt_size_t result; rt_device_t device = disk[drv]; @@ -849,7 +851,7 @@ DRESULT disk_read (BYTE drv, BYTE* buff, DWORD sector, UINT count) } /* Write Sector(s) */ -DRESULT disk_write (BYTE drv, const BYTE* buff, DWORD sector, UINT count) +DRESULT disk_write(BYTE drv, const BYTE *buff, DWORD sector, UINT count) { rt_size_t result; rt_device_t device = disk[drv]; @@ -916,7 +918,7 @@ DWORD get_fattime(void) { DWORD fat_time = 0; -#ifdef RT_USING_LIBC +#ifdef RT_USING_LIBC time_t now; struct tm *p_tm; struct tm tm_now; @@ -933,12 +935,12 @@ DWORD get_fattime(void) /* unlock scheduler. */ rt_exit_critical(); - fat_time = (DWORD)(tm_now.tm_year - 80) << 25 | - (DWORD)(tm_now.tm_mon + 1) << 21 | - (DWORD)tm_now.tm_mday << 16 | - (DWORD)tm_now.tm_hour << 11 | - (DWORD)tm_now.tm_min << 5 | - (DWORD)tm_now.tm_sec / 2 ; + fat_time = (DWORD)(tm_now.tm_year - 80) << 25 | + (DWORD)(tm_now.tm_mon + 1) << 21 | + (DWORD)tm_now.tm_mday << 16 | + (DWORD)tm_now.tm_hour << 11 | + (DWORD)tm_now.tm_min << 5 | + (DWORD)tm_now.tm_sec / 2 ; #endif /* RT_USING_LIBC */ return fat_time; diff --git a/components/dfs/filesystems/nfs/dfs_nfs.c b/components/dfs/filesystems/nfs/dfs_nfs.c index ea055b73c1b1c987c30ec70dc6b2282358660515..f3653145640294b3d4f254b62e15c7dc663d9606 100644 --- a/components/dfs/filesystems/nfs/dfs_nfs.c +++ b/components/dfs/filesystems/nfs/dfs_nfs.c @@ -6,7 +6,7 @@ * Change Logs: * Date Author Notes */ - + #include #include #include @@ -65,9 +65,9 @@ typedef struct nfs_dir nfs_dir; nfs_dir *nfs_opendir(nfs_filesystem *nfs, const char *path); -static int nfs_parse_host_export(const char *host_export, +static int nfs_parse_host_export(const char *host_export, char *host, - size_t host_len, + size_t host_len, char *export, size_t export_len) { @@ -99,7 +99,7 @@ static int nfs_parse_host_export(const char *host_export, /* copy export path */ for (index = host_len; index < host_len + export_len; index ++) { - if (host_export[index] == 0) + if (host_export[index] == 0) { export[index - host_len] = '\0'; @@ -133,11 +133,11 @@ static nfs_fh3 *get_handle(nfs_filesystem *nfs, const char *name) char *path; char *init; - init = path = rt_malloc(strlen(name)+1); + init = path = rt_malloc(strlen(name) + 1); if (init == NULL) return NULL; - memcpy(init, name, strlen(name)+1); + memcpy(init, name, strlen(name) + 1); handle = rt_malloc(sizeof(nfs_fh3)); if (handle == NULL) @@ -202,10 +202,10 @@ static nfs_fh3 *get_dir_handle(nfs_filesystem *nfs, const char *name) char *path; char *init; - init = path = rt_malloc(strlen(name)+1); + init = path = rt_malloc(strlen(name) + 1); if (init == NULL) return NULL; - memcpy(init, name, strlen(name)+1); + memcpy(init, name, strlen(name) + 1); handle = rt_malloc(sizeof(nfs_fh3)); if (handle == NULL) @@ -274,7 +274,7 @@ static size_t nfs_get_filesize(nfs_filesystem *nfs, nfs_fh3 *handle) memset(&res, '\0', sizeof(res)); - if ((nfsproc3_getattr_3(args, &res, nfs->nfs_client)!=RPC_SUCCESS) || + if ((nfsproc3_getattr_3(args, &res, nfs->nfs_client) != RPC_SUCCESS) || res.status != NFS3_OK) { rt_kprintf("GetAttr failed: %d\n", res.status); @@ -285,7 +285,7 @@ static size_t nfs_get_filesize(nfs_filesystem *nfs, nfs_fh3 *handle) info = &res.GETATTR3res_u.resok.obj_attributes; size = info->size; xdr_free((xdrproc_t)xdr_GETATTR3res, (char *)&res); - + return size; } @@ -319,7 +319,7 @@ rt_bool_t nfs_is_directory(nfs_filesystem *nfs, const char *name) return RT_FALSE; } - info=&res.GETATTR3res_u.resok.obj_attributes; + info = &res.GETATTR3res_u.resok.obj_attributes; if (info->type == NFS3DIR) result = RT_TRUE; @@ -327,7 +327,7 @@ rt_bool_t nfs_is_directory(nfs_filesystem *nfs, const char *name) xdr_free((xdrproc_t)xdr_GETATTR3res, (char *)&res); xdr_free((xdrproc_t)xdr_nfs_fh3, (char *)handle); rt_free(handle); - + return result; } @@ -427,7 +427,7 @@ int nfs_mkdir(nfs_filesystem *nfs, const char *name, mode_t mode) xdr_free((xdrproc_t)xdr_MKDIR3res, (char *)&res); xdr_free((xdrproc_t)xdr_nfs_fh3, (char *)handle); rt_free(handle); - + return ret; } @@ -441,13 +441,13 @@ int nfs_mount(struct dfs_filesystem *fs, unsigned long rwflag, const void *data) memset(nfs, 0, sizeof(nfs_filesystem)); if (nfs_parse_host_export((const char *)data, nfs->host, HOST_LENGTH, - nfs->export, EXPORT_PATH_LENGTH) < 0) + nfs->export, EXPORT_PATH_LENGTH) < 0) { rt_kprintf("host or export path error\n"); goto __return; } - nfs->mount_client=clnt_create((char *)nfs->host, MOUNT_PROGRAM, MOUNT_V3, "udp"); + nfs->mount_client = clnt_create((char *)nfs->host, MOUNT_PROGRAM, MOUNT_V3, "udp"); if (nfs->mount_client == NULL) { rt_kprintf("create mount client failed\n"); @@ -465,7 +465,7 @@ int nfs_mount(struct dfs_filesystem *fs, unsigned long rwflag, const void *data) rt_kprintf("nfs mount failed\n"); goto __return; } - nfs->nfs_client=clnt_create((char *)nfs->host, NFS_PROGRAM, NFS_V3, "udp"); + nfs->nfs_client = clnt_create((char *)nfs->host, NFS_PROGRAM, NFS_V3, "udp"); if (nfs->nfs_client == NULL) { rt_kprintf("creat nfs client failed\n"); @@ -555,7 +555,7 @@ int nfs_read(struct dfs_fd *file, void *buf, size_t count) { READ3args args; READ3res res; - ssize_t bytes, total=0; + ssize_t bytes, total = 0; nfs_file *fd; nfs_filesystem *nfs; @@ -564,8 +564,8 @@ int nfs_read(struct dfs_fd *file, void *buf, size_t count) RT_ASSERT(file->data != NULL); - struct dfs_filesystem *dfs_nfs = ((struct dfs_filesystem*)(file->data)); - nfs = (struct nfs_filesystem *)(dfs_nfs->data); + struct dfs_filesystem *dfs_nfs = ((struct dfs_filesystem *)(file->data)); + nfs = (struct nfs_filesystem *)(dfs_nfs->data); fd = (nfs_file *)(nfs->data); RT_ASSERT(fd != NULL); @@ -577,7 +577,8 @@ int nfs_read(struct dfs_fd *file, void *buf, size_t count) return 0; args.file = fd->handle; - do { + do + { args.offset = fd->offset; args.count = count > DFS_NFS_MAX_MTU ? DFS_NFS_MAX_MTU : count; count -= args.count; @@ -612,7 +613,8 @@ int nfs_read(struct dfs_fd *file, void *buf, size_t count) } } xdr_free((xdrproc_t)xdr_READ3res, (char *)&res); - } while(count > 0); + } + while (count > 0); xdr_free((xdrproc_t)xdr_READ3res, (char *)&res); @@ -623,7 +625,7 @@ int nfs_write(struct dfs_fd *file, const void *buf, size_t count) { WRITE3args args; WRITE3res res; - ssize_t bytes, total=0; + ssize_t bytes, total = 0; nfs_file *fd; nfs_filesystem *nfs; @@ -631,8 +633,8 @@ int nfs_write(struct dfs_fd *file, const void *buf, size_t count) return -EISDIR; RT_ASSERT(file->data != NULL); - struct dfs_filesystem *dfs_nfs = ((struct dfs_filesystem*)(file->data)); - nfs = (struct nfs_filesystem *)(dfs_nfs->data); + struct dfs_filesystem *dfs_nfs = ((struct dfs_filesystem *)(file->data)); + nfs = (struct nfs_filesystem *)(dfs_nfs->data); fd = (nfs_file *)(nfs->data); RT_ASSERT(fd != NULL); @@ -642,11 +644,12 @@ int nfs_write(struct dfs_fd *file, const void *buf, size_t count) args.file = fd->handle; args.stable = FILE_SYNC; - do { + do + { args.offset = fd->offset; memset(&res, 0, sizeof(res)); - args.data.data_val=(void *)buf; + args.data.data_val = (void *)buf; args.count = count > DFS_NFS_MAX_MTU ? DFS_NFS_MAX_MTU : count; args.data.data_len = args.count; count -= args.count; @@ -676,7 +679,8 @@ int nfs_write(struct dfs_fd *file, const void *buf, size_t count) file->size = fd->size; } xdr_free((xdrproc_t)xdr_WRITE3res, (char *)&res); - } while (count > 0); + } + while (count > 0); xdr_free((xdrproc_t)xdr_WRITE3res, (char *)&res); @@ -692,8 +696,8 @@ int nfs_lseek(struct dfs_fd *file, off_t offset) return -EISDIR; RT_ASSERT(file->data != NULL); - struct dfs_filesystem *dfs_nfs = ((struct dfs_filesystem*)(file->data)); - nfs = (struct nfs_filesystem *)(dfs_nfs->data); + struct dfs_filesystem *dfs_nfs = ((struct dfs_filesystem *)(file->data)); + nfs = (struct nfs_filesystem *)(dfs_nfs->data); fd = (nfs_file *)(nfs->data); RT_ASSERT(fd != NULL); @@ -711,8 +715,8 @@ int nfs_close(struct dfs_fd *file) { nfs_filesystem *nfs; RT_ASSERT(file->data != NULL); - struct dfs_filesystem *dfs_nfs = ((struct dfs_filesystem*)(file->data)); - nfs = (struct nfs_filesystem *)(dfs_nfs->data); + struct dfs_filesystem *dfs_nfs = ((struct dfs_filesystem *)(file->data)); + nfs = (struct nfs_filesystem *)(dfs_nfs->data); if (file->type == FT_DIRECTORY) { @@ -741,14 +745,14 @@ int nfs_open(struct dfs_fd *file) { nfs_filesystem *nfs; RT_ASSERT(file->data != NULL); - struct dfs_filesystem *dfs_nfs = ((struct dfs_filesystem*)(file->data)); - nfs = (struct nfs_filesystem *)(dfs_nfs->data); + struct dfs_filesystem *dfs_nfs = ((struct dfs_filesystem *)(file->data)); + nfs = (struct nfs_filesystem *)(dfs_nfs->data); if (file->flags & O_DIRECTORY) { nfs_dir *dir; - + if (file->flags & O_CREAT) { if (nfs_mkdir(nfs, file->path, 0755) < 0) @@ -930,7 +934,7 @@ char *nfs_readdir(nfs_filesystem *nfs, nfs_dir *dir) return NULL; dir->cookie = dir->entry->cookie; - strncpy(name, dir->entry->name, NAME_MAX-1); + strncpy(name, dir->entry->name, NAME_MAX - 1); dir->entry = dir->entry->nextentry; name[NAME_MAX - 1] = '\0'; @@ -1013,7 +1017,7 @@ int nfs_unlink(struct dfs_filesystem *fs, const char *path) xdr_free((xdrproc_t)xdr_RMDIR3res, (char *)&res); xdr_free((xdrproc_t)xdr_nfs_fh3, (char *)handle); - rt_free(handle); + rt_free(handle); } return ret; @@ -1083,8 +1087,8 @@ int nfs_getdents(struct dfs_fd *file, struct dirent *dirp, uint32_t count) RT_ASSERT(file->data != NULL); - struct dfs_filesystem *dfs_nfs = ((struct dfs_filesystem*)(file->data)); - nfs = (struct nfs_filesystem *)(dfs_nfs->data); + struct dfs_filesystem *dfs_nfs = ((struct dfs_filesystem *)(file->data)); + nfs = (struct nfs_filesystem *)(dfs_nfs->data); dir = (nfs_dir *)(nfs->data); RT_ASSERT(dir != NULL); @@ -1118,18 +1122,18 @@ int nfs_getdents(struct dfs_fd *file, struct dirent *dirp, uint32_t count) static const struct dfs_file_ops nfs_fops = { - nfs_open, - nfs_close, - nfs_ioctl, - nfs_read, - nfs_write, - NULL, /* flush */ - nfs_lseek, - nfs_getdents, - NULL, /* poll */ + nfs_open, + nfs_close, + nfs_ioctl, + nfs_read, + nfs_write, + NULL, /* flush */ + nfs_lseek, + nfs_getdents, + NULL, /* poll */ }; -static const struct dfs_filesystem_ops _nfs = +static const struct dfs_filesystem_ops _nfs = { "nfs", DFS_FS_FLAG_DEFAULT, @@ -1138,7 +1142,7 @@ static const struct dfs_filesystem_ops _nfs = nfs_unmount, NULL, /* mkfs */ NULL, /* statfs */ - nfs_unlink, + nfs_unlink, nfs_stat, nfs_rename, }; diff --git a/components/dfs/filesystems/ramfs/dfs_ramfs.c b/components/dfs/filesystems/ramfs/dfs_ramfs.c index e851c7ef78abae0c35b1bc804d6b1fa0a7556bc3..aa85081e1e9754b39490ca27b4b59b59fe658481 100644 --- a/components/dfs/filesystems/ramfs/dfs_ramfs.c +++ b/components/dfs/filesystems/ramfs/dfs_ramfs.c @@ -21,14 +21,14 @@ int dfs_ramfs_mount(struct dfs_filesystem *fs, unsigned long rwflag, const void *data) { - struct dfs_ramfs* ramfs; + struct dfs_ramfs *ramfs; if (data == NULL) return -EIO; ramfs = (struct dfs_ramfs *)data; fs->data = ramfs; - + return RT_EOK; } @@ -48,8 +48,8 @@ int dfs_ramfs_statfs(struct dfs_filesystem *fs, struct statfs *buf) RT_ASSERT(buf != NULL); buf->f_bsize = 512; - buf->f_blocks = ramfs->memheap.pool_size/512; - buf->f_bfree = ramfs->memheap.available_size/512; + buf->f_blocks = ramfs->memheap.pool_size / 512; + buf->f_bfree = ramfs->memheap.available_size / 512; return RT_EOK; } @@ -119,7 +119,7 @@ int dfs_ramfs_write(struct dfs_fd *fd, const void *buf, size_t count) struct ramfs_dirent *dirent; struct dfs_ramfs *ramfs; - dirent = (struct ramfs_dirent*)fd->data; + dirent = (struct ramfs_dirent *)fd->data; RT_ASSERT(dirent != NULL); ramfs = dirent->fs; @@ -260,7 +260,7 @@ int dfs_ramfs_open(struct dfs_fd *file) file->size = dirent->size; if (file->flags & O_APPEND) file->pos = file->size; - else + else file->pos = 0; return 0; @@ -381,7 +381,7 @@ int dfs_ramfs_rename(struct dfs_filesystem *fs, return RT_EOK; } -static const struct dfs_file_ops _ram_fops = +static const struct dfs_file_ops _ram_fops = { dfs_ramfs_open, dfs_ramfs_close, @@ -418,7 +418,7 @@ int dfs_ramfs_init(void) } INIT_COMPONENT_EXPORT(dfs_ramfs_init); -struct dfs_ramfs* dfs_ramfs_create(rt_uint8_t *pool, rt_size_t size) +struct dfs_ramfs *dfs_ramfs_create(rt_uint8_t *pool, rt_size_t size) { struct dfs_ramfs *ramfs; rt_uint8_t *data_ptr; @@ -435,7 +435,7 @@ struct dfs_ramfs* dfs_ramfs_create(rt_uint8_t *pool, rt_size_t size) if (result != RT_EOK) return NULL; /* detach this memheap object from the system */ - rt_object_detach((rt_object_t)&(ramfs->memheap)); + rt_object_detach((rt_object_t) & (ramfs->memheap)); /* initialize ramfs object */ ramfs->magic = RAMFS_MAGIC; diff --git a/components/dfs/filesystems/ramfs/dfs_ramfs.h b/components/dfs/filesystems/ramfs/dfs_ramfs.h index 9419784db9f7f69acee738f05450639f594f5994..4975ecb332d085267fcd6e9f767cec64427ba0dd 100644 --- a/components/dfs/filesystems/ramfs/dfs_ramfs.h +++ b/components/dfs/filesystems/ramfs/dfs_ramfs.h @@ -24,7 +24,7 @@ struct ramfs_dirent struct dfs_ramfs *fs; /* file system ref */ char name[RAMFS_NAME_MAX]; /* dirent name */ - rt_uint8_t* data; + rt_uint8_t *data; rt_size_t size; /* file size */ }; @@ -41,7 +41,7 @@ struct dfs_ramfs }; int dfs_ramfs_init(void); -struct dfs_ramfs* dfs_ramfs_create(rt_uint8_t* pool, rt_size_t size); +struct dfs_ramfs *dfs_ramfs_create(rt_uint8_t *pool, rt_size_t size); #endif diff --git a/components/dfs/filesystems/romfs/dfs_romfs.c b/components/dfs/filesystems/romfs/dfs_romfs.c index a953ac72d5624543aed98645c5cc763a5c52528b..dcc34e58307e54906ec4c8614dda664ac735413a 100644 --- a/components/dfs/filesystems/romfs/dfs_romfs.c +++ b/components/dfs/filesystems/romfs/dfs_romfs.c @@ -105,7 +105,7 @@ struct romfs_dirent *dfs_romfs_lookup(struct romfs_dirent *root_dirent, const ch if (dirent[index].type == ROMFS_DIRENT_DIR) { /* enter directory */ - dirent = (struct romfs_dirent*)dirent[index].data; + dirent = (struct romfs_dirent *)dirent[index].data; found = 1; break; } @@ -226,7 +226,7 @@ int dfs_romfs_stat(struct dfs_filesystem *fs, const char *path, struct stat *st) st->st_dev = 0; st->st_mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH | - S_IWUSR | S_IWGRP | S_IWOTH; + S_IWUSR | S_IWGRP | S_IWOTH; if (dirent->type == ROMFS_DIRENT_DIR) { diff --git a/components/dfs/filesystems/romfs/dfs_romfs.h b/components/dfs/filesystems/romfs/dfs_romfs.h index efb6d44cafd4addaf8e9458cbe5c5b37b019a047..ba6a3d7dfa7b26a7716ccf9b6fad7d68df0c12aa 100644 --- a/components/dfs/filesystems/romfs/dfs_romfs.h +++ b/components/dfs/filesystems/romfs/dfs_romfs.h @@ -13,8 +13,8 @@ #include -#define ROMFS_DIRENT_FILE 0x00 -#define ROMFS_DIRENT_DIR 0x01 +#define ROMFS_DIRENT_FILE 0x00 +#define ROMFS_DIRENT_DIR 0x01 struct romfs_dirent { diff --git a/components/dfs/filesystems/romfs/romfs.c b/components/dfs/filesystems/romfs/romfs.c index 1ea9f21d8ef984291857d7b5fbaaeff50a07278c..cfce09a095500badf2a8c00f9a06a92184b58711 100644 --- a/components/dfs/filesystems/romfs/romfs.c +++ b/components/dfs/filesystems/romfs/romfs.c @@ -12,7 +12,7 @@ const static unsigned char _dummy_dummy_txt[] = { - 0x74,0x68,0x69,0x73,0x20,0x69,0x73,0x20,0x61,0x20,0x66,0x69,0x6c,0x65,0x21,0x0d,0x0a, + 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x21, 0x0d, 0x0a, }; const static struct romfs_dirent _dummy[] = @@ -22,17 +22,17 @@ const static struct romfs_dirent _dummy[] = const static unsigned char _dummy_txt[] = { - 0x74,0x68,0x69,0x73,0x20,0x69,0x73,0x20,0x61,0x20,0x66,0x69,0x6c,0x65,0x21,0x0d,0x0a, + 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x21, 0x0d, 0x0a, }; RT_WEAK const struct romfs_dirent _root_dirent[] = { - {ROMFS_DIRENT_DIR, "dummy", (rt_uint8_t *)_dummy, sizeof(_dummy)/sizeof(_dummy[0])}, + {ROMFS_DIRENT_DIR, "dummy", (rt_uint8_t *)_dummy, sizeof(_dummy) / sizeof(_dummy[0])}, {ROMFS_DIRENT_FILE, "dummy.txt", _dummy_txt, sizeof(_dummy_txt)}, }; RT_WEAK const struct romfs_dirent romfs_root = { - ROMFS_DIRENT_DIR, "/", (rt_uint8_t *)_root_dirent, sizeof(_root_dirent)/sizeof(_root_dirent[0]) + ROMFS_DIRENT_DIR, "/", (rt_uint8_t *)_root_dirent, sizeof(_root_dirent) / sizeof(_root_dirent[0]) }; diff --git a/components/dfs/filesystems/skeleton/skeleton.c b/components/dfs/filesystems/skeleton/skeleton.c index 30f0d4f629704e7db903e610851ca190f00d0b0d..0c20513e82d94a5143ae96655024e8736971dddc 100644 --- a/components/dfs/filesystems/skeleton/skeleton.c +++ b/components/dfs/filesystems/skeleton/skeleton.c @@ -14,52 +14,52 @@ #include "dfs_skt_fs.h" -int dfs_skt_mount(struct dfs_filesystem* fs, unsigned long rwflag, const void* data) +int dfs_skt_mount(struct dfs_filesystem *fs, unsigned long rwflag, const void *data) { return RT_EOK; } -int dfs_skt_unmount(struct dfs_filesystem* fs) +int dfs_skt_unmount(struct dfs_filesystem *fs) { return RT_EOK; } -int dfs_skt_ioctl(struct dfs_fd* file, int cmd, void* args) +int dfs_skt_ioctl(struct dfs_fd *file, int cmd, void *args) { return -RT_EIO; } -int dfs_skt_read(struct dfs_fd* file, void *buf, rt_size_t count) +int dfs_skt_read(struct dfs_fd *file, void *buf, rt_size_t count) { return count; } -int dfs_skt_lseek(struct dfs_fd* file, rt_off_t offset) +int dfs_skt_lseek(struct dfs_fd *file, rt_off_t offset) { return -RT_EIO; } -int dfs_skt_close(struct dfs_fd* file) +int dfs_skt_close(struct dfs_fd *file) { return RT_EOK; } -int dfs_skt_open(struct dfs_fd* file) +int dfs_skt_open(struct dfs_fd *file) { return RT_EOK; } -int dfs_skt_stat(struct dfs_filesystem* fs, const char *path, struct stat *st) +int dfs_skt_stat(struct dfs_filesystem *fs, const char *path, struct stat *st) { return RT_EOK; } -int dfs_skt_getdents(struct dfs_fd* file, struct dirent* dirp, rt_uint32_t count) +int dfs_skt_getdents(struct dfs_fd *file, struct dirent *dirp, rt_uint32_t count) { return count * sizeof(struct dirent); } -static const struct dfs_file_ops _skt_fops = +static const struct dfs_file_ops _skt_fops = { dfs_skt_open, dfs_skt_close, diff --git a/components/dfs/filesystems/uffs/dfs_uffs.c b/components/dfs/filesystems/uffs/dfs_uffs.c index b875d1eb00616a1c31c8ef82a21601b337cdae53..c89102f3e3e6106fcde673b2739c0967002438cb 100644 --- a/components/dfs/filesystems/uffs/dfs_uffs.c +++ b/components/dfs/filesystems/uffs/dfs_uffs.c @@ -33,12 +33,12 @@ struct _nand_dev { - struct rt_mtd_nand_device * dev; + struct rt_mtd_nand_device *dev; struct uffs_StorageAttrSt storage; uffs_Device uffs_dev; uffs_MountTable mount_table; char mount_path[UFFS_MOUNT_PATH_MAX]; - void * data; /* when uffs use static buf, it will save ptr here */ + void *data; /* when uffs use static buf, it will save ptr here */ }; /* make sure the following struct var had been initilased to 0! */ static struct _nand_dev nand_part[UFFS_DEVICE_MAX] = {0}; @@ -109,11 +109,11 @@ static URET _device_release(uffs_Device *dev) } static int init_uffs_fs( - struct _nand_dev * nand_part) + struct _nand_dev *nand_part) { - uffs_MountTable * mtb; - struct rt_mtd_nand_device * nand; - struct uffs_StorageAttrSt * flash_storage; + uffs_MountTable *mtb; + struct rt_mtd_nand_device *nand; + struct uffs_StorageAttrSt *flash_storage; mtb = &nand_part->mount_table; nand = nand_part->dev; @@ -123,7 +123,7 @@ static int init_uffs_fs( uffs_setup_storage(flash_storage, nand); /* register mount table */ - if(mtb->dev) + if (mtb->dev) { /* set memory allocator for uffs */ #if CONFIG_USE_SYSTEM_MEMORY_ALLOCATOR > 0 @@ -141,15 +141,15 @@ static int init_uffs_fs( } static int dfs_uffs_mount( - struct dfs_filesystem* fs, + struct dfs_filesystem *fs, unsigned long rwflag, - const void* data) + const void *data) { rt_base_t index; - uffs_MountTable * mount_part; - struct rt_mtd_nand_device * dev; - - RT_ASSERT(rt_strlen(fs->path) < (UFFS_MOUNT_PATH_MAX-1)); + uffs_MountTable *mount_part; + struct rt_mtd_nand_device *dev; + + RT_ASSERT(rt_strlen(fs->path) < (UFFS_MOUNT_PATH_MAX - 1)); dev = RT_MTD_NAND_DEVICE(fs->dev_id); /*1. find a empty entry in partition table */ @@ -184,7 +184,7 @@ static int dfs_uffs_mount( return 0; } -static int dfs_uffs_unmount(struct dfs_filesystem* fs) +static int dfs_uffs_unmount(struct dfs_filesystem *fs) { rt_base_t index; int result; @@ -210,7 +210,7 @@ static int dfs_uffs_mkfs(rt_device_t dev_id) { rt_base_t index; rt_uint32_t block; - struct rt_mtd_nand_device * mtd; + struct rt_mtd_nand_device *mtd; /*1. find the device index */ for (index = 0; index < UFFS_DEVICE_MAX; index++) @@ -249,11 +249,11 @@ static int dfs_uffs_mkfs(rt_device_t dev_id) return RT_EOK; } -static int dfs_uffs_statfs(struct dfs_filesystem* fs, - struct statfs *buf) +static int dfs_uffs_statfs(struct dfs_filesystem *fs, + struct statfs *buf) { rt_base_t index; - struct rt_mtd_nand_device * mtd = RT_MTD_NAND_DEVICE(fs->dev_id); + struct rt_mtd_nand_device *mtd = RT_MTD_NAND_DEVICE(fs->dev_id); RT_ASSERT(mtd != RT_NULL); @@ -265,24 +265,24 @@ static int dfs_uffs_statfs(struct dfs_filesystem* fs, } if (index == UFFS_DEVICE_MAX) return -ENOENT; - - buf->f_bsize = mtd->page_size*mtd->pages_per_block; + + buf->f_bsize = mtd->page_size * mtd->pages_per_block; buf->f_blocks = (mtd->block_end - mtd->block_start + 1); - buf->f_bfree = uffs_GetDeviceFree(&nand_part[index].uffs_dev)/buf->f_bsize ; - + buf->f_bfree = uffs_GetDeviceFree(&nand_part[index].uffs_dev) / buf->f_bsize ; + return 0; } -static int dfs_uffs_open(struct dfs_fd* file) +static int dfs_uffs_open(struct dfs_fd *file) { int fd; int oflag, mode; - char * file_path; + char *file_path; oflag = file->flags; if (oflag & O_DIRECTORY) /* operations about dir */ { - uffs_DIR * dir; + uffs_DIR *dir; if (oflag & O_CREAT) /* create a dir*/ { @@ -291,8 +291,8 @@ static int dfs_uffs_open(struct dfs_fd* file) } /* open dir */ file_path = rt_malloc(FILE_PATH_MAX); - if(file_path == RT_NULL) - return -ENOMEM; + if (file_path == RT_NULL) + return -ENOMEM; if (file->path[0] == '/' && !(file->path[1] == 0)) rt_snprintf(file_path, FILE_PATH_MAX, "%s/", file->path); @@ -306,7 +306,7 @@ static int dfs_uffs_open(struct dfs_fd* file) if (dir == RT_NULL) { - rt_free(file_path); + rt_free(file_path); return uffs_result_to_dfs(uffs_get_error()); } /* save this pointer,will used by dfs_uffs_getdents*/ @@ -349,7 +349,7 @@ static int dfs_uffs_open(struct dfs_fd* file) return 0; } -static int dfs_uffs_close(struct dfs_fd* file) +static int dfs_uffs_close(struct dfs_fd *file) { int oflag; int fd; @@ -372,12 +372,12 @@ static int dfs_uffs_close(struct dfs_fd* file) return uffs_result_to_dfs(uffs_get_error()); } -static int dfs_uffs_ioctl(struct dfs_fd * file, int cmd, void* args) +static int dfs_uffs_ioctl(struct dfs_fd *file, int cmd, void *args) { return -ENOSYS; } -static int dfs_uffs_read(struct dfs_fd * file, void* buf, size_t len) +static int dfs_uffs_read(struct dfs_fd *file, void *buf, size_t len) { int fd; int char_read; @@ -392,9 +392,9 @@ static int dfs_uffs_read(struct dfs_fd * file, void* buf, size_t len) return char_read; } -static int dfs_uffs_write(struct dfs_fd* file, - const void* buf, - size_t len) +static int dfs_uffs_write(struct dfs_fd *file, + const void *buf, + size_t len) { int fd; int char_write; @@ -410,7 +410,7 @@ static int dfs_uffs_write(struct dfs_fd* file, return char_write; } -static int dfs_uffs_flush(struct dfs_fd* file) +static int dfs_uffs_flush(struct dfs_fd *file) { int fd; int result; @@ -418,7 +418,7 @@ static int dfs_uffs_flush(struct dfs_fd* file) fd = (int)(file->data); result = uffs_flush(fd); - if (result < 0 ) + if (result < 0) return uffs_result_to_dfs(uffs_get_error()); return 0; } @@ -427,18 +427,18 @@ int uffs_seekdir(uffs_DIR *dir, long offset) { int i = 0; - while(i < offset) - { + while (i < offset) + { if (uffs_readdir(dir) == RT_NULL) return -1; i++; - } + } return 0; } -static int dfs_uffs_seek(struct dfs_fd* file, - rt_off_t offset) +static int dfs_uffs_seek(struct dfs_fd *file, + rt_off_t offset) { int result; @@ -446,17 +446,17 @@ static int dfs_uffs_seek(struct dfs_fd* file, if (file->type == FT_DIRECTORY) { uffs_rewinddir((uffs_DIR *)(file->data)); - result = uffs_seekdir((uffs_DIR *)(file->data), offset/sizeof(struct dirent)); + result = uffs_seekdir((uffs_DIR *)(file->data), offset / sizeof(struct dirent)); if (result >= 0) { - file->pos = offset; + file->pos = offset; return offset; } } else if (file->type == FT_REGULAR) { result = uffs_seek((int)(file->data), offset, USEEK_SET); - if (result >= 0) + if (result >= 0) return offset; } @@ -465,19 +465,19 @@ static int dfs_uffs_seek(struct dfs_fd* file, /* return the size of struct dirent*/ static int dfs_uffs_getdents( - struct dfs_fd* file, - struct dirent* dirp, + struct dfs_fd *file, + struct dirent *dirp, uint32_t count) { rt_uint32_t index; - char * file_path; - struct dirent* d; - uffs_DIR* dir; - struct uffs_dirent * uffs_d; - - dir = (uffs_DIR*)(file->data); + char *file_path; + struct dirent *d; + uffs_DIR *dir; + struct uffs_dirent *uffs_d; + + dir = (uffs_DIR *)(file->data); RT_ASSERT(dir != RT_NULL); - + /* round count, count is always 1 */ count = (count / sizeof(struct dirent)) * sizeof(struct dirent); if (count == 0) return -EINVAL; @@ -486,13 +486,13 @@ static int dfs_uffs_getdents( file_path = rt_malloc(FILE_PATH_MAX); if (file_path == RT_NULL) return -ENOMEM; - + index = 0; /* usually, the while loop should only be looped only once! */ while (1) { struct uffs_stat s; - + d = dirp + index; uffs_d = uffs_readdir(dir); @@ -507,8 +507,8 @@ static int dfs_uffs_getdents( else rt_strncpy(file_path, uffs_d->d_name, FILE_PATH_MAX); - uffs_stat(file_path, &s); - switch(s.st_mode & US_IFMT) /* file type mark */ + uffs_stat(file_path, &s); + switch (s.st_mode & US_IFMT) /* file type mark */ { case US_IFREG: /* directory */ d->d_type = DT_REG; @@ -533,10 +533,10 @@ static int dfs_uffs_getdents( if (index * sizeof(struct dirent) >= count) break; } - + /* free file name buf */ rt_free(file_path); - + if (index == 0) return uffs_result_to_dfs(uffs_get_error()); @@ -545,7 +545,7 @@ static int dfs_uffs_getdents( return index * sizeof(struct dirent); } -static int dfs_uffs_unlink(struct dfs_filesystem* fs, const char* path) +static int dfs_uffs_unlink(struct dfs_filesystem *fs, const char *path) { int result; struct uffs_stat s; @@ -556,7 +556,7 @@ static int dfs_uffs_unlink(struct dfs_filesystem* fs, const char* path) return uffs_result_to_dfs(uffs_get_error()); } - switch(s.st_mode & US_IFMT) + switch (s.st_mode & US_IFMT) { case US_IFREG: result = uffs_remove(path); @@ -575,12 +575,12 @@ static int dfs_uffs_unlink(struct dfs_filesystem* fs, const char* path) } static int dfs_uffs_rename( - struct dfs_filesystem* fs, - const char* oldpath, - const char* newpath) + struct dfs_filesystem *fs, + const char *oldpath, + const char *newpath) { int result; - + result = uffs_rename(oldpath, newpath); if (result < 0) return uffs_result_to_dfs(uffs_get_error()); @@ -588,7 +588,7 @@ static int dfs_uffs_rename( return 0; } -static int dfs_uffs_stat(struct dfs_filesystem* fs, const char *path, struct stat *st) +static int dfs_uffs_stat(struct dfs_filesystem *fs, const char *path, struct stat *st) { int result; struct uffs_stat s; @@ -607,7 +607,7 @@ static int dfs_uffs_stat(struct dfs_filesystem* fs, const char *path, struct sta return 0; } -static const struct dfs_file_ops dfs_uffs_fops = +static const struct dfs_file_ops dfs_uffs_fops = { dfs_uffs_open, dfs_uffs_close, diff --git a/components/dfs/filesystems/uffs/dfs_uffs.h b/components/dfs/filesystems/uffs/dfs_uffs.h index 615d29036d88acf9b5973972f53d63a80116705d..72f0ee92408fd0b004a9aca6a3e240d36a8f9211 100644 --- a/components/dfs/filesystems/uffs/dfs_uffs.h +++ b/components/dfs/filesystems/uffs/dfs_uffs.h @@ -83,7 +83,7 @@ extern const uffs_FlashOps nand_ops; extern void uffs_setup_storage( struct uffs_StorageAttrSt *attr, - struct rt_mtd_nand_device * nand); + struct rt_mtd_nand_device *nand); extern int dfs_uffs_init(void); #endif /* DFS_UFFS_H_ */ diff --git a/components/dfs/include/dfs.h b/components/dfs/include/dfs.h index 7fdcb1cfda3493e064401b317d501117ecbf0d2f..eb32a4b41146c41f0eb5feea25f7b1495ccf6775 100644 --- a/components/dfs/include/dfs.h +++ b/components/dfs/include/dfs.h @@ -102,7 +102,7 @@ struct dfs_fd *fd_get(int fd); void fd_put(struct dfs_fd *fd); int fd_is_open(const char *pathname); -struct dfs_fdtable* dfs_fdtable_get(void); +struct dfs_fdtable *dfs_fdtable_get(void); #ifdef __cplusplus } diff --git a/components/dfs/include/dfs_fs.h b/components/dfs/include/dfs_fs.h index 711771a1378766d1cc9a3835b376a5c8a1820fad..d3a00fc5428479ab5531f63f3953cb0d886bc005 100644 --- a/components/dfs/include/dfs_fs.h +++ b/components/dfs/include/dfs_fs.h @@ -7,7 +7,7 @@ * Date Author Notes * 2005-02-22 Bernard The first version. */ - + #ifndef __DFS_FS_H__ #define __DFS_FS_H__ @@ -60,7 +60,7 @@ struct dfs_partition uint8_t type; /* file system type */ off_t offset; /* partition start offset */ size_t size; /* partition size */ - rt_sem_t lock; + rt_sem_t lock; }; /* mount table */ @@ -75,11 +75,11 @@ struct dfs_mount_tbl int dfs_register(const struct dfs_filesystem_ops *ops); struct dfs_filesystem *dfs_filesystem_lookup(const char *path); -const char* dfs_filesystem_get_mounted_path(struct rt_device* device); +const char *dfs_filesystem_get_mounted_path(struct rt_device *device); int dfs_filesystem_get_partition(struct dfs_partition *part, - uint8_t *buf, - uint32_t pindex); + uint8_t *buf, + uint32_t pindex); int dfs_mount(const char *device_name, const char *path, diff --git a/components/dfs/include/dfs_posix.h b/components/dfs/include/dfs_posix.h index bc8ff1c698ce9aaf106bfd65723b66a4cf1b8eca..9fd76debe2aa9644954fa6512bca151658c4a3ee 100644 --- a/components/dfs/include/dfs_posix.h +++ b/components/dfs/include/dfs_posix.h @@ -36,7 +36,7 @@ struct dirent *readdir(DIR *d); long telldir(DIR *d); void seekdir(DIR *d, off_t offset); void rewinddir(DIR *d); -int closedir(DIR* d); +int closedir(DIR *d); /* file api*/ int open(const char *file, int flags, ...); diff --git a/components/dfs/include/dfs_private.h b/components/dfs/include/dfs_private.h index bfc71b3b351999eac169f72e29129793433bae7a..77dbe8562ddb335a4007d78b26897408d45c6881 100644 --- a/components/dfs/include/dfs_private.h +++ b/components/dfs/include/dfs_private.h @@ -12,8 +12,8 @@ #include -#define DBG_SECTION_NAME "DFS" -#define DBG_LEVEL DBG_INFO +#define DBG_SECTION_NAME "DFS" +#define DBG_LEVEL DBG_INFO #include #define NO_WORKING_DIR "system does not support working directory\n" diff --git a/components/dfs/src/dfs.c b/components/dfs/src/dfs.c index 6d52129b0622cafc5ad7a0ac605020b86947d70f..5bddb96930805c2b0777c23f80edf3fc69c7d17a 100644 --- a/components/dfs/src/dfs.c +++ b/components/dfs/src/dfs.c @@ -139,7 +139,7 @@ static int fd_alloc(struct dfs_fdtable *fdt, int startfd) /* increase the number of FD with 4 step length */ cnt = fdt->maxfd + 4; - cnt = cnt > DFS_FD_MAX? DFS_FD_MAX : cnt; + cnt = cnt > DFS_FD_MAX ? DFS_FD_MAX : cnt; fds = rt_realloc(fdt->fds, cnt * sizeof(struct dfs_fd *)); if (fds == NULL) goto __exit; /* return fdt->maxfd */ @@ -189,7 +189,7 @@ int fd_new(void) if (idx == fdt->maxfd) { idx = -(1 + DFS_FD_OFFSET); - LOG_E( "DFS fd new is failed! Could not found an empty fd entry."); + LOG_E("DFS fd new is failed! Could not found an empty fd entry."); goto __result; } @@ -400,7 +400,7 @@ char *dfs_normalize_path(const char *directory, const char *filename) /* join path and file name */ rt_snprintf(fullpath, strlen(directory) + strlen(filename) + 2, - "%s/%s", directory, filename); + "%s/%s", directory, filename); } else { @@ -499,7 +499,7 @@ RTM_EXPORT(dfs_normalize_path); /** * This function will get the file descriptor table of current process. */ -struct dfs_fdtable* dfs_fdtable_get(void) +struct dfs_fdtable *dfs_fdtable_get(void) { struct dfs_fdtable *fdt; #ifdef RT_USING_LWP @@ -523,12 +523,12 @@ int list_fd(void) { int index; struct dfs_fdtable *fd_table; - + fd_table = dfs_fdtable_get(); if (!fd_table) return -1; rt_enter_critical(); - + rt_kprintf("fd type ref magic path\n"); rt_kprintf("-- ------ --- ----- ------\n"); for (index = 0; index < (int)fd_table->maxfd; index ++) diff --git a/components/dfs/src/dfs_file.c b/components/dfs/src/dfs_file.c index b4f115ffc26262ba40a0964360768225dba74d36..81cab2ed79c11b52fd7f8d37f0a6b0958256cbbc 100644 --- a/components/dfs/src/dfs_file.c +++ b/components/dfs/src/dfs_file.c @@ -2,7 +2,7 @@ * Copyright (c) 2006-2018, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 - * + * * Change Logs: * Date Author Notes * 2005-02-22 Bernard The first version. @@ -543,7 +543,8 @@ void ls(const char *pathname) rt_kprintf("BAD file: %s\n", dirent.d_name); rt_free(fullpath); } - }while(length > 0); + } + while (length > 0); dfs_file_close(&fd); } @@ -565,7 +566,7 @@ void rm(const char *filename) } FINSH_FUNCTION_EXPORT(rm, remove files or directories); -void cat(const char* filename) +void cat(const char *filename) { uint32_t length; char buffer[81]; @@ -580,12 +581,13 @@ void cat(const char* filename) do { memset(buffer, 0, sizeof(buffer)); - length = dfs_file_read(&fd, buffer, sizeof(buffer)-1 ); + length = dfs_file_read(&fd, buffer, sizeof(buffer) - 1); if (length > 0) { rt_kprintf("%s", buffer); } - }while (length > 0); + } + while (length > 0); dfs_file_close(&fd); } @@ -638,7 +640,8 @@ static void copyfile(const char *src, const char *dst) break; } } - } while (read_bytes > 0); + } + while (read_bytes > 0); dfs_file_close(&src_fd); dfs_file_close(&fd); @@ -646,7 +649,7 @@ static void copyfile(const char *src, const char *dst) } extern int mkdir(const char *path, mode_t mode); -static void copydir(const char * src, const char * dst) +static void copydir(const char *src, const char *dst) { struct dirent dirent; struct stat stat; @@ -665,8 +668,8 @@ static void copydir(const char * src, const char * dst) length = dfs_file_getdents(&cpfd, &dirent, sizeof(struct dirent)); if (length > 0) { - char * src_entry_full = NULL; - char * dst_entry_full = NULL; + char *src_entry_full = NULL; + char *dst_entry_full = NULL; if (strcmp(dirent.d_name, "..") == 0 || strcmp(dirent.d_name, ".") == 0) continue; @@ -703,14 +706,15 @@ static void copydir(const char * src, const char * dst) rt_free(src_entry_full); rt_free(dst_entry_full); } - }while(length > 0); + } + while (length > 0); dfs_file_close(&cpfd); } static const char *_get_path_lastname(const char *path) { - char * ptr; + char *ptr; if ((ptr = strrchr(path, '/')) == NULL) return path; @@ -767,7 +771,7 @@ void copy(const char *src, const char *dst) { if (flag & FLAG_DST_IS_DIR) { - char * fdst; + char *fdst; fdst = dfs_normalize_path(dst, _get_path_lastname(src)); if (fdst == NULL) { @@ -786,7 +790,7 @@ void copy(const char *src, const char *dst) { if (flag & FLAG_DST_IS_DIR) { - char * fdst; + char *fdst; fdst = dfs_normalize_path(dst, _get_path_lastname(src)); if (fdst == NULL) { diff --git a/components/dfs/src/dfs_fs.c b/components/dfs/src/dfs_fs.c index a183e7f124942c020b3c304311328ba48642e42c..774d008ce65cc62b053f401a95df2d276a6e26cb 100644 --- a/components/dfs/src/dfs_fs.c +++ b/components/dfs/src/dfs_fs.c @@ -38,7 +38,7 @@ int dfs_register(const struct dfs_filesystem_ops *ops) dfs_lock(); /* check if this filesystem was already registered */ for (iter = &filesystem_operation_table[0]; - iter < &filesystem_operation_table[DFS_FILESYSTEM_TYPES_MAX]; iter ++) + iter < &filesystem_operation_table[DFS_FILESYSTEM_TYPES_MAX]; iter ++) { /* find out an empty filesystem type entry */ if (*iter == NULL) @@ -120,9 +120,9 @@ struct dfs_filesystem *dfs_filesystem_lookup(const char *path) * * @return the mounted path or NULL if none device mounted. */ -const char* dfs_filesystem_get_mounted_path(struct rt_device* device) +const char *dfs_filesystem_get_mounted_path(struct rt_device *device) { - const char* path = NULL; + const char *path = NULL; struct dfs_filesystem *iter; dfs_lock(); @@ -154,8 +154,8 @@ const char* dfs_filesystem_get_mounted_path(struct rt_device* device) * @return RT_EOK on successful or -RT_ERROR on failed. */ int dfs_filesystem_get_partition(struct dfs_partition *part, - uint8_t *buf, - uint32_t pindex) + uint8_t *buf, + uint32_t pindex) { #define DPT_ADDRESS 0x1be /* device partition offset in Boot Sector */ #define DPT_ITEM_SIZE 16 /* partition item size */ @@ -173,28 +173,28 @@ int dfs_filesystem_get_partition(struct dfs_partition *part, return -EIO; /* get partition type */ - type = *(dpt+4); + type = *(dpt + 4); if (type == 0) return -EIO; /* set partition information * size is the number of 512-Byte */ part->type = type; - part->offset = *(dpt+8) | *(dpt+9)<<8 | *(dpt+10)<<16 | *(dpt+11)<<24; - part->size = *(dpt+12) | *(dpt+13)<<8 | *(dpt+14)<<16 | *(dpt+15)<<24; + part->offset = *(dpt + 8) | *(dpt + 9) << 8 | *(dpt + 10) << 16 | *(dpt + 11) << 24; + part->size = *(dpt + 12) | *(dpt + 13) << 8 | *(dpt + 14) << 16 | *(dpt + 15) << 24; rt_kprintf("found part[%d], begin: %d, size: ", - pindex, part->offset*512); - if ((part->size>>11) == 0) - rt_kprintf("%d%s",part->size>>1,"KB\n"); /* KB */ + pindex, part->offset * 512); + if ((part->size >> 11) == 0) + rt_kprintf("%d%s", part->size >> 1, "KB\n"); /* KB */ else { unsigned int part_size; part_size = part->size >> 11; /* MB */ - if ((part_size>>10) == 0) - rt_kprintf("%d.%d%s",part_size,(part->size>>1)&0x3FF,"MB\n"); + if ((part_size >> 10) == 0) + rt_kprintf("%d.%d%s", part_size, (part->size >> 1) & 0x3FF, "MB\n"); else - rt_kprintf("%d.%d%s",part_size>>10,part_size&0x3FF,"GB\n"); + rt_kprintf("%d.%d%s", part_size >> 10, part_size & 0x3FF, "GB\n"); } return RT_EOK; @@ -240,7 +240,7 @@ int dfs_mount(const char *device_name, dfs_lock(); for (ops = &filesystem_operation_table[0]; - ops < &filesystem_operation_table[DFS_FILESYSTEM_TYPES_MAX]; ops++) + ops < &filesystem_operation_table[DFS_FILESYSTEM_TYPES_MAX]; ops++) if ((*ops != NULL) && (strcmp((*ops)->name, filesystemtype) == 0)) break; @@ -503,13 +503,13 @@ int dfs_mount_table(void) if (mount_table[index].path == NULL) break; if (dfs_mount(mount_table[index].device_name, - mount_table[index].path, - mount_table[index].filesystemtype, - mount_table[index].rwflag, - mount_table[index].data) != 0) + mount_table[index].path, + mount_table[index].filesystemtype, + mount_table[index].rwflag, + mount_table[index].data) != 0) { rt_kprintf("mount fs[%s] on %s failed.\n", mount_table[index].filesystemtype, - mount_table[index].path); + mount_table[index].path); return -RT_ERROR; } @@ -555,7 +555,7 @@ int df(const char *path) } rt_kprintf("disk free: %d.%d %s [ %d block, %d bytes per block ]\n", - (unsigned long)cap, minor, unit_str[unit_index], buffer.f_bfree, buffer.f_bsize); + (unsigned long)cap, minor, unit_str[unit_index], buffer.f_bfree, buffer.f_bsize); return 0; } FINSH_FUNCTION_EXPORT(df, get disk free); diff --git a/components/dfs/src/dfs_posix.c b/components/dfs/src/dfs_posix.c index f47a60ee5dc34da490b16155143b43f326205b90..6d643e2d4a182c500f408a842e9e8720d78ec49e 100644 --- a/components/dfs/src/dfs_posix.c +++ b/components/dfs/src/dfs_posix.c @@ -423,11 +423,11 @@ int fcntl(int fildes, int cmd, ...) d = fd_get(fildes); if (d) { - void* arg; + void *arg; va_list ap; va_start(ap, cmd); - arg = va_arg(ap, void*); + arg = va_arg(ap, void *); va_end(ap); ret = dfs_file_ioctl(d, cmd, arg); @@ -459,11 +459,11 @@ RTM_EXPORT(fcntl); */ int ioctl(int fildes, int cmd, ...) { - void* arg; + void *arg; va_list ap; va_start(ap, cmd); - arg = va_arg(ap, void*); + arg = va_arg(ap, void *); va_end(ap); /* we use fcntl for this API. */ @@ -645,8 +645,8 @@ struct dirent *readdir(DIR *d) if (d->num) { - struct dirent* dirent_ptr; - dirent_ptr = (struct dirent*)&d->buf[d->cur]; + struct dirent *dirent_ptr; + dirent_ptr = (struct dirent *)&d->buf[d->cur]; d->cur += dirent_ptr->d_reclen; } @@ -654,7 +654,7 @@ struct dirent *readdir(DIR *d) { /* get a new entry */ result = dfs_file_getdents(fd, - (struct dirent*)d->buf, + (struct dirent *)d->buf, sizeof(d->buf) - 1); if (result <= 0) { @@ -670,7 +670,7 @@ struct dirent *readdir(DIR *d) fd_put(fd); - return (struct dirent *)(d->buf+d->cur); + return (struct dirent *)(d->buf + d->cur); } RTM_EXPORT(readdir); diff --git a/components/dfs/src/poll.c b/components/dfs/src/poll.c index 6f83762082f23c6a80886a9041167526bab965e2..aee157eed50bdc22b4541aa5f099cf95e4ecf9c3 100644 --- a/components/dfs/src/poll.c +++ b/components/dfs/src/poll.c @@ -132,7 +132,7 @@ static int do_pollfd(struct pollfd *pollfd, rt_pollreq_t *req) mask = POLLMASK_DEFAULT; if (f->fops->poll) { - req->_key = pollfd->events | POLLERR| POLLHUP; + req->_key = pollfd->events | POLLERR | POLLHUP; mask = f->fops->poll(f, req); } diff --git a/components/dfs/src/select.c b/components/dfs/src/select.c index b9a444fe440824827c004eb0d51365182345fe44..b20f7cf656d8e0fbbf3e7795de40aaf428875016 100644 --- a/components/dfs/src/select.c +++ b/components/dfs/src/select.c @@ -18,12 +18,12 @@ static void fdszero(fd_set *set, int nfds) { fd_mask *m; int n; - + /* The 'sizeof(fd_set)' of the system space may differ from user space, so the actual size of the 'fd_set' is determined here with the parameter 'nfds' */ - m = (fd_mask*)set; + m = (fd_mask *)set; for (n = 0; n < nfds; n += (sizeof(fd_mask) * 8)) { rt_memset(m, 0, sizeof(fd_mask)); diff --git a/components/drivers/Kconfig b/components/drivers/Kconfig index c883e6458b4db15d9b8529e3962a49e0215ed591..792dc1b028c88bdc3651a9bff983bf50a9ca1698 100755 --- a/components/drivers/Kconfig +++ b/components/drivers/Kconfig @@ -10,17 +10,17 @@ if RT_USING_DEVICE_IPC default 512 config RT_USING_SYSTEM_WORKQUEUE - bool "Using system default workqueue - default n + bool "Using system default workqueue" + default n if RT_USING_SYSTEM_WORKQUEUE - config RT_SYSTEM_WORKQUEUE_STACKSIZE - int "The stack size for system workqueue thread" - default 512 + config RT_SYSTEM_WORKQUEUE_STACKSIZE + int "The stack size for system workqueue thread" + default 2048 - config RT_SYSTEM_WORKQUEUE_PRIORITY - int "The priority level of system workqueue thread" - default "23 + config RT_SYSTEM_WORKQUEUE_PRIORITY + int "The priority level of system workqueue thread" + default 23 endif endif diff --git a/components/drivers/src/workqueue.c b/components/drivers/src/workqueue.c index f2b1ae81e40fc2d2e3b620ee3cfe540a274caef2..d2e7dce3296d1aacf9e120dd41c9af5044fefe28 100644 --- a/components/drivers/src/workqueue.c +++ b/components/drivers/src/workqueue.c @@ -394,7 +394,7 @@ rt_err_t rt_work_cancel(struct rt_work *work) static int rt_work_sys_workqueue_init(void) { - sys_workq = rt_workqueue_create("sys_work", RT_SYSTEM_WORKQUEUE_STACKSIZE * 4, + sys_workq = rt_workqueue_create("sys_work", RT_SYSTEM_WORKQUEUE_STACKSIZE, RT_SYSTEM_WORKQUEUE_PRIORITY); return RT_EOK; diff --git a/components/finsh/shell.c b/components/finsh/shell.c index 0b3cc416994a5e01df598a890ae41ba4fc302895..53dcd11c669e1fe80b15794136b4f29862b3fb81 100644 --- a/components/finsh/shell.c +++ b/components/finsh/shell.c @@ -297,7 +297,6 @@ static void finsh_wait_auth(void) ch = finsh_getchar(); if (ch < 0) { - rt_kprintf("finsh getchar error\n"); continue; } @@ -510,7 +509,6 @@ void finsh_thread_entry(void *parameter) ch = finsh_getchar(); if (ch < 0) { - rt_kprintf("finsh getchar error\n"); continue; } diff --git a/libcpu/arm/cortex-m23/SConscript b/libcpu/arm/cortex-m23/SConscript new file mode 100644 index 0000000000000000000000000000000000000000..9ff30a796b5ca7b75c976f1e694598d125655840 --- /dev/null +++ b/libcpu/arm/cortex-m23/SConscript @@ -0,0 +1,23 @@ +# RT-Thread building script for component + +from building import * + +Import('rtconfig') + +cwd = GetCurrentDir() +src = Glob('*.c') + Glob('*.cpp') +CPPPATH = [cwd] + +if rtconfig.PLATFORM == 'armcc': + src += Glob('*_rvds.S') + +if rtconfig.PLATFORM == 'gcc': + src += Glob('*_init.S') + src += Glob('*_gcc.S') + +if rtconfig.PLATFORM == 'iar': + src += Glob('*_iar.S') + +group = DefineGroup('cpu', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/libcpu/arm/cortex-m23/context_gcc.S b/libcpu/arm/cortex-m23/context_gcc.S new file mode 100644 index 0000000000000000000000000000000000000000..4fc5a3adbd040bad28d9134216f5455e4e96e2c3 --- /dev/null +++ b/libcpu/arm/cortex-m23/context_gcc.S @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2010-01-25 Bernard first version + * 2012-06-01 aozima set pendsv priority to 0xFF. + * 2012-08-17 aozima fixed bug: store r8 - r11. + * 2013-02-20 aozima port to gcc. + * 2013-06-18 aozima add restore MSP feature. + * 2013-11-04 bright fixed hardfault bug for gcc. + * 2019-03-31 xuzhuoyi port to Cortex-M23. + */ + + .cpu cortex-m23 + .fpu softvfp + .syntax unified + .thumb + .text + + .equ SCB_VTOR, 0xE000ED08 /* Vector Table Offset Register */ + .equ NVIC_INT_CTRL, 0xE000ED04 /* interrupt control state register */ + .equ NVIC_SHPR3, 0xE000ED20 /* system priority register (3) */ + .equ NVIC_PENDSV_PRI, 0x00FF0000 /* PendSV priority value (lowest) */ + .equ NVIC_PENDSVSET, 0x10000000 /* value to trigger PendSV exception */ + +/* + * rt_base_t rt_hw_interrupt_disable(); + */ + .global rt_hw_interrupt_disable + .type rt_hw_interrupt_disable, %function +rt_hw_interrupt_disable: + MRS R0, PRIMASK + CPSID I + BX LR + +/* + * void rt_hw_interrupt_enable(rt_base_t level); + */ + .global rt_hw_interrupt_enable + .type rt_hw_interrupt_enable, %function +rt_hw_interrupt_enable: + MSR PRIMASK, R0 + BX LR + +/* + * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to); + * R0 --> from + * R1 --> to + */ + .global rt_hw_context_switch_interrupt + .type rt_hw_context_switch_interrupt, %function + .global rt_hw_context_switch + .type rt_hw_context_switch, %function +rt_hw_context_switch_interrupt: +rt_hw_context_switch: + /* set rt_thread_switch_interrupt_flag to 1 */ + LDR R2, =rt_thread_switch_interrupt_flag + LDR R3, [R2] + CMP R3, #1 + BEQ _reswitch + MOVS R3, #1 + STR R3, [R2] + + LDR R2, =rt_interrupt_from_thread /* set rt_interrupt_from_thread */ + STR R0, [R2] + +_reswitch: + LDR R2, =rt_interrupt_to_thread /* set rt_interrupt_to_thread */ + STR R1, [R2] + + LDR R0, =NVIC_INT_CTRL /* trigger the PendSV exception (causes context switch) */ + LDR R1, =NVIC_PENDSVSET + STR R1, [R0] + BX LR + +/* R0 --> switch from thread stack + * R1 --> switch to thread stack + * psr, pc, LR, R12, R3, R2, R1, R0 are pushed into [from] stack + */ + .global PendSV_Handler + .type PendSV_Handler, %function +PendSV_Handler: + /* disable interrupt to protect context switch */ + MRS R2, PRIMASK + CPSID I + + /* get rt_thread_switch_interrupt_flag */ + LDR R0, =rt_thread_switch_interrupt_flag + LDR R1, [R0] + CMP R1, #0x00 + BEQ pendsv_exit /* pendsv aLReady handled */ + + /* clear rt_thread_switch_interrupt_flag to 0 */ + MOVS R1, #0 + STR R1, [R0] + + LDR R0, =rt_interrupt_from_thread + LDR R1, [R0] + CMP R1, #0x00 + BEQ switch_to_thread /* skip register save at the first time */ + + MRS R1, PSP /* get from thread stack pointer */ + + SUBS R1, R1, #0x20 /* space for {R4 - R7} and {R8 - R11} */ + LDR R0, [R0] + STR R1, [R0] /* update from thread stack pointer */ + + STMIA R1!, {R4 - R7} /* push thread {R4 - R7} register to thread stack */ + + MOV R4, R8 /* mov thread {R8 - R11} to {R4 - R7} */ + MOV R5, R9 + MOV R6, R10 + MOV R7, R11 + STMIA R1!, {R4 - R7} /* push thread {R8 - R11} high register to thread stack */ +switch_to_thread: + LDR R1, =rt_interrupt_to_thread + LDR R1, [R1] + LDR R1, [R1] /* load thread stack pointer */ + + LDMIA R1!, {R4 - R7} /* pop thread {R4 - R7} register from thread stack */ + PUSH {R4 - R7} /* push {R4 - R7} to MSP for copy {R8 - R11} */ + + LDMIA R1!, {R4 - R7} /* pop thread {R8 - R11} high register from thread stack to {R4 - R7} */ + MOV R8, R4 /* mov {R4 - R7} to {R8 - R11} */ + MOV R9, R5 + MOV R10, R6 + MOV R11, R7 + + POP {R4 - R7} /* pop {R4 - R7} from MSP */ + + MSR PSP, R1 /* update stack pointer */ + +pendsv_exit: + /* restore interrupt */ + MSR PRIMASK, R2 + + MOVS R0, #0x04 + RSBS R0, R0, #0x00 + BX R0 +/* + * void rt_hw_context_switch_to(rt_uint32 to); + * R0 --> to + */ + .global rt_hw_context_switch_to + .type rt_hw_context_switch_to, %function +rt_hw_context_switch_to: + LDR R1, =rt_interrupt_to_thread + STR R0, [R1] + + /* set from thread to 0 */ + LDR R1, =rt_interrupt_from_thread + MOVS R0, #0 + STR R0, [R1] + + /* set interrupt flag to 1 */ + LDR R1, =rt_thread_switch_interrupt_flag + MOVS R0, #1 + STR R0, [R1] + + /* set the PendSV exception priority */ + LDR R0, =NVIC_SHPR3 + LDR R1, =NVIC_PENDSV_PRI + LDR R2, [R0,#0x00] /* read */ + ORRS R1, R1, R2 /* modify */ + STR R1, [R0] /* write-back */ + + LDR R0, =NVIC_INT_CTRL /* trigger the PendSV exception (causes context switch) */ + LDR R1, =NVIC_PENDSVSET + STR R1, [R0] + NOP + /* restore MSP */ + LDR R0, =SCB_VTOR + LDR R0, [R0] + LDR R0, [R0] + NOP + MSR MSP, R0 + + /* enable interrupts at processor level */ + CPSIE I + + /* never reach here! */ + +/* compatible with old version */ + .global rt_hw_interrupt_thread_switch + .type rt_hw_interrupt_thread_switch, %function +rt_hw_interrupt_thread_switch: + BX LR + NOP + + .global HardFault_Handler + .type HardFault_Handler, %function +HardFault_Handler: + /* get current context */ + MRS R0, PSP /* get fault thread stack pointer */ + PUSH {LR} + BL rt_hw_hard_fault_exception + POP {PC} + + +/* + * rt_uint32_t rt_hw_interrupt_check(void); + * R0 --> state + */ + .global rt_hw_interrupt_check + .type rt_hw_interrupt_check, %function +rt_hw_interrupt_check: + MRS R0, IPSR + BX LR diff --git a/libcpu/arm/cortex-m23/context_iar.S b/libcpu/arm/cortex-m23/context_iar.S new file mode 100644 index 0000000000000000000000000000000000000000..4f30c0bc0c74bf3de7362ed415014bb167050b00 --- /dev/null +++ b/libcpu/arm/cortex-m23/context_iar.S @@ -0,0 +1,207 @@ +;/* +; * Copyright (c) 2006-2019, RT-Thread Development Team +; * +; * SPDX-License-Identifier: Apache-2.0 +; * +; * Change Logs: +; * Date Author Notes +; * 2010-01-25 Bernard first version +; * 2012-06-01 aozima set pendsv priority to 0xFF. +; * 2012-08-17 aozima fixed bug: store r8 - r11. +; * 2013-06-18 aozima add restore MSP feature. +; * 2019-03-31 xuzhuoyi port to Cortex-M23. +; */ + +;/** +; * @addtogroup CORTEX-M23 +; */ +;/*@{*/ + +SCB_VTOR EQU 0xE000ED08 ; Vector Table Offset Register +NVIC_INT_CTRL EQU 0xE000ED04 ; interrupt control state register +NVIC_SHPR3 EQU 0xE000ED20 ; system priority register (2) +NVIC_PENDSV_PRI EQU 0x00FF0000 ; PendSV priority value (lowest) +NVIC_PENDSVSET EQU 0x10000000 ; value to trigger PendSV exception + + SECTION .text:CODE(2) + THUMB + REQUIRE8 + PRESERVE8 + + IMPORT rt_thread_switch_interrupt_flag + IMPORT rt_interrupt_from_thread + IMPORT rt_interrupt_to_thread + +;/* +; * rt_base_t rt_hw_interrupt_disable(); +; */ + EXPORT rt_hw_interrupt_disable +rt_hw_interrupt_disable: + MRS r0, PRIMASK + CPSID I + BX LR + +;/* +; * void rt_hw_interrupt_enable(rt_base_t level); +; */ + EXPORT rt_hw_interrupt_enable +rt_hw_interrupt_enable: + MSR PRIMASK, r0 + BX LR + +;/* +; * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to); +; * r0 --> from +; * r1 --> to +; */ + EXPORT rt_hw_context_switch_interrupt + EXPORT rt_hw_context_switch +rt_hw_context_switch_interrupt: +rt_hw_context_switch: + ; set rt_thread_switch_interrupt_flag to 1 + LDR r2, =rt_thread_switch_interrupt_flag + LDR r3, [r2] + CMP r3, #1 + BEQ _reswitch + MOVS r3, #0x1 + STR r3, [r2] + + LDR r2, =rt_interrupt_from_thread ; set rt_interrupt_from_thread + STR r0, [r2] + +_reswitch + LDR r2, =rt_interrupt_to_thread ; set rt_interrupt_to_thread + STR r1, [r2] + + LDR r0, =NVIC_INT_CTRL ; trigger the PendSV exception (causes context switch) + LDR r1, =NVIC_PENDSVSET + STR r1, [r0] + BX LR + +; r0 --> switch from thread stack +; r1 --> switch to thread stack +; psr, pc, lr, r12, r3, r2, r1, r0 are pushed into [from] stack + EXPORT PendSV_Handler +PendSV_Handler: + + ; disable interrupt to protect context switch + MRS r2, PRIMASK + CPSID I + + ; get rt_thread_switch_interrupt_flag + LDR r0, =rt_thread_switch_interrupt_flag + LDR r1, [r0] + CMP r1, #0x00 + BEQ pendsv_exit ; pendsv already handled + + ; clear rt_thread_switch_interrupt_flag to 0 + MOVS r1, #0x00 + STR r1, [r0] + + LDR r0, =rt_interrupt_from_thread + LDR r1, [r0] + CMP r1, #0x00 + BEQ switch_to_thread ; skip register save at the first time + + MRS r1, psp ; get from thread stack pointer + + SUBS r1, r1, #0x20 ; space for {r4 - r7} and {r8 - r11} + LDR r0, [r0] + STR r1, [r0] ; update from thread stack pointer + + STMIA r1!, {r4 - r7} ; push thread {r4 - r7} register to thread stack + + MOV r4, r8 ; mov thread {r8 - r11} to {r4 - r7} + MOV r5, r9 + MOV r6, r10 + MOV r7, r11 + STMIA r1!, {r4 - r7} ; push thread {r8 - r11} high register to thread stack + +switch_to_thread + LDR r1, =rt_interrupt_to_thread + LDR r1, [r1] + LDR r1, [r1] ; load thread stack pointer + + LDMIA r1!, {r4 - r7} ; pop thread {r4 - r7} register from thread stack + PUSH {r4 - r7} ; push {r4 - r7} to MSP for copy {r8 - r11} + + LDMIA r1!, {r4 - r7} ; pop thread {r8 - r11} high register from thread stack to {r4 - r7} + MOV r8, r4 ; mov {r4 - r7} to {r8 - r11} + MOV r9, r5 + MOV r10, r6 + MOV r11, r7 + + POP {r4 - r7} ; pop {r4 - r7} from MSP + + MSR psp, r1 ; update stack pointer + +pendsv_exit + ; restore interrupt + MSR PRIMASK, r2 + + MOVS r0, #0x04 + RSBS r0, r0, #0x00 + BX r0 + +;/* +; * void rt_hw_context_switch_to(rt_uint32 to); +; * r0 --> to +; * this fucntion is used to perform the first thread switch +; */ + EXPORT rt_hw_context_switch_to +rt_hw_context_switch_to: + ; set to thread + LDR r1, =rt_interrupt_to_thread + STR r0, [r1] + + ; set from thread to 0 + LDR r1, =rt_interrupt_from_thread + MOVS r0, #0x0 + STR r0, [r1] + + ; set interrupt flag to 1 + LDR r1, =rt_thread_switch_interrupt_flag + MOVS r0, #1 + STR r0, [r1] + + ; set the PendSV exception priority + LDR r0, =NVIC_SHPR3 + LDR r1, =NVIC_PENDSV_PRI + LDR r2, [r0,#0x00] ; read + ORRS r1,r1,r2 ; modify + STR r1, [r0] ; write-back + + ; trigger the PendSV exception (causes context switch) + LDR r0, =NVIC_INT_CTRL + LDR r1, =NVIC_PENDSVSET + STR r1, [r0] + NOP + + ; restore MSP + LDR r0, =SCB_VTOR + LDR r0, [r0] + LDR r0, [r0] + NOP + MSR msp, r0 + + ; enable interrupts at processor level + CPSIE I + + ; never reach here! + +; compatible with old version + EXPORT rt_hw_interrupt_thread_switch +rt_hw_interrupt_thread_switch: + BX lr + + IMPORT rt_hw_hard_fault_exception + EXPORT HardFault_Handler +HardFault_Handler: + + ; get current context + MRS r0, psp ; get fault thread stack pointer + PUSH {lr} + BL rt_hw_hard_fault_exception + POP {pc} + + END diff --git a/libcpu/arm/cortex-m23/context_rvds.S b/libcpu/arm/cortex-m23/context_rvds.S new file mode 100644 index 0000000000000000000000000000000000000000..f243097cc60f110c68c658c22d150c5afcce6bf2 --- /dev/null +++ b/libcpu/arm/cortex-m23/context_rvds.S @@ -0,0 +1,216 @@ +;/* +; * Copyright (c) 2006-2019, RT-Thread Development Team +; * +; * SPDX-License-Identifier: Apache-2.0 +; * +; * Change Logs: +; * Date Author Notes +; * 2010-01-25 Bernard first version +; * 2012-06-01 aozima set pendsv priority to 0xFF. +; * 2012-08-17 aozima fixed bug: store r8 - r11. +; * 2013-06-18 aozima add restore MSP feature. +; * 2019-03-31 xuzhuoyi port to Cortex-M23. +; */ + +;/** +; * @addtogroup CORTEX-M23 +; */ +;/*@{*/ + +SCB_VTOR EQU 0xE000ED08 ; Vector Table Offset Register +NVIC_INT_CTRL EQU 0xE000ED04 ; interrupt control state register +NVIC_SHPR3 EQU 0xE000ED20 ; system priority register (2) +NVIC_PENDSV_PRI EQU 0x00FF0000 ; PendSV priority value (lowest) +NVIC_PENDSVSET EQU 0x10000000 ; value to trigger PendSV exception + + AREA |.text|, CODE, READONLY, ALIGN=2 + THUMB + REQUIRE8 + PRESERVE8 + + IMPORT rt_thread_switch_interrupt_flag + IMPORT rt_interrupt_from_thread + IMPORT rt_interrupt_to_thread + +;/* +; * rt_base_t rt_hw_interrupt_disable(); +; */ +rt_hw_interrupt_disable PROC + EXPORT rt_hw_interrupt_disable + MRS r0, PRIMASK + CPSID I + BX LR + ENDP + +;/* +; * void rt_hw_interrupt_enable(rt_base_t level); +; */ +rt_hw_interrupt_enable PROC + EXPORT rt_hw_interrupt_enable + MSR PRIMASK, r0 + BX LR + ENDP + +;/* +; * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to); +; * r0 --> from +; * r1 --> to +; */ +rt_hw_context_switch_interrupt + EXPORT rt_hw_context_switch_interrupt +rt_hw_context_switch PROC + EXPORT rt_hw_context_switch + + ; set rt_thread_switch_interrupt_flag to 1 + LDR r2, =rt_thread_switch_interrupt_flag + LDR r3, [r2] + CMP r3, #1 + BEQ _reswitch + MOVS r3, #0x01 + STR r3, [r2] + + LDR r2, =rt_interrupt_from_thread ; set rt_interrupt_from_thread + STR r0, [r2] + +_reswitch + LDR r2, =rt_interrupt_to_thread ; set rt_interrupt_to_thread + STR r1, [r2] + + LDR r0, =NVIC_INT_CTRL ; trigger the PendSV exception (causes context switch) + LDR r1, =NVIC_PENDSVSET + STR r1, [r0] + BX LR + ENDP + +; r0 --> switch from thread stack +; r1 --> switch to thread stack +; psr, pc, lr, r12, r3, r2, r1, r0 are pushed into [from] stack +PendSV_Handler PROC + EXPORT PendSV_Handler + + ; disable interrupt to protect context switch + MRS r2, PRIMASK + CPSID I + + ; get rt_thread_switch_interrupt_flag + LDR r0, =rt_thread_switch_interrupt_flag + LDR r1, [r0] + CMP r1, #0x00 + BEQ pendsv_exit ; pendsv already handled + + ; clear rt_thread_switch_interrupt_flag to 0 + MOVS r1, #0x00 + STR r1, [r0] + + LDR r0, =rt_interrupt_from_thread + LDR r1, [r0] + CMP r1, #0x00 + BEQ switch_to_thread ; skip register save at the first time + + MRS r1, psp ; get from thread stack pointer + + SUBS r1, r1, #0x20 ; space for {r4 - r7} and {r8 - r11} + LDR r0, [r0] + STR r1, [r0] ; update from thread stack pointer + + STMIA r1!, {r4 - r7} ; push thread {r4 - r7} register to thread stack + + MOV r4, r8 ; mov thread {r8 - r11} to {r4 - r7} + MOV r5, r9 + MOV r6, r10 + MOV r7, r11 + STMIA r1!, {r4 - r7} ; push thread {r8 - r11} high register to thread stack + +switch_to_thread + LDR r1, =rt_interrupt_to_thread + LDR r1, [r1] + LDR r1, [r1] ; load thread stack pointer + + LDMIA r1!, {r4 - r7} ; pop thread {r4 - r7} register from thread stack + PUSH {r4 - r7} ; push {r4 - r7} to MSP for copy {r8 - r11} + + LDMIA r1!, {r4 - r7} ; pop thread {r8 - r11} high register from thread stack to {r4 - r7} + MOV r8, r4 ; mov {r4 - r7} to {r8 - r11} + MOV r9, r5 + MOV r10, r6 + MOV r11, r7 + + POP {r4 - r7} ; pop {r4 - r7} from MSP + + MSR psp, r1 ; update stack pointer + +pendsv_exit + ; restore interrupt + MSR PRIMASK, r2 + + MOVS r0, #0x04 + RSBS r0, r0, #0x00 + BX r0 + ENDP + +;/* +; * void rt_hw_context_switch_to(rt_uint32 to); +; * r0 --> to +; * this fucntion is used to perform the first thread switch +; */ +rt_hw_context_switch_to PROC + EXPORT rt_hw_context_switch_to + ; set to thread + LDR r1, =rt_interrupt_to_thread + STR r0, [r1] + + ; set from thread to 0 + LDR r1, =rt_interrupt_from_thread + MOVS r0, #0x0 + STR r0, [r1] + + ; set interrupt flag to 1 + LDR r1, =rt_thread_switch_interrupt_flag + MOVS r0, #1 + STR r0, [r1] + + ; set the PendSV exception priority + LDR r0, =NVIC_SHPR3 + LDR r1, =NVIC_PENDSV_PRI + LDR r2, [r0,#0x00] ; read + ORRS r1,r1,r2 ; modify + STR r1, [r0] ; write-back + + ; trigger the PendSV exception (causes context switch) + LDR r0, =NVIC_INT_CTRL + LDR r1, =NVIC_PENDSVSET + STR r1, [r0] + + ; restore MSP + LDR r0, =SCB_VTOR + LDR r0, [r0] + LDR r0, [r0] + MSR msp, r0 + + ; enable interrupts at processor level + CPSIE I + + ; never reach here! + ENDP + +; compatible with old version +rt_hw_interrupt_thread_switch PROC + EXPORT rt_hw_interrupt_thread_switch + BX lr + ENDP + + IMPORT rt_hw_hard_fault_exception + +HardFault_Handler PROC + EXPORT HardFault_Handler + + ; get current context + MRS r0, psp ; get fault thread stack pointer + PUSH {lr} + BL rt_hw_hard_fault_exception + POP {pc} + ENDP + + ALIGN 4 + + END diff --git a/libcpu/arm/cortex-m23/cpuport.c b/libcpu/arm/cortex-m23/cpuport.c new file mode 100644 index 0000000000000000000000000000000000000000..842802c866ea0cb6ea99094ca5d01a65906bca7f --- /dev/null +++ b/libcpu/arm/cortex-m23/cpuport.c @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2006-2019, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2010-01-25 Bernard first version + * 2012-05-31 aozima Merge all of the C source code into cpuport.c + * 2012-08-17 aozima fixed bug: store r8 - r11. + * 2012-12-23 aozima stack addr align to 8byte. + * 2019-03-31 xuzhuoyi port to Cortex-M23. + */ + +#include + +struct exception_stack_frame +{ + rt_uint32_t r0; + rt_uint32_t r1; + rt_uint32_t r2; + rt_uint32_t r3; + rt_uint32_t r12; + rt_uint32_t lr; + rt_uint32_t pc; + rt_uint32_t psr; +}; + +struct stack_frame +{ + /* r4 ~ r7 low register */ + rt_uint32_t r4; + rt_uint32_t r5; + rt_uint32_t r6; + rt_uint32_t r7; + + /* r8 ~ r11 high register */ + rt_uint32_t r8; + rt_uint32_t r9; + rt_uint32_t r10; + rt_uint32_t r11; + + struct exception_stack_frame exception_stack_frame; +}; + +/* flag in interrupt handling */ +rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread; +rt_uint32_t rt_thread_switch_interrupt_flag; + +/** + * 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) +{ + struct stack_frame *stack_frame; + rt_uint8_t *stk; + unsigned long i; + + stk = stack_addr + sizeof(rt_uint32_t); + stk = (rt_uint8_t *)RT_ALIGN_DOWN((rt_uint32_t)stk, 8); + stk -= sizeof(struct stack_frame); + + stack_frame = (struct stack_frame *)stk; + + /* init all register */ + for (i = 0; i < sizeof(struct stack_frame) / sizeof(rt_uint32_t); i ++) + { + ((rt_uint32_t *)stack_frame)[i] = 0xdeadbeef; + } + + stack_frame->exception_stack_frame.r0 = (unsigned long)parameter; /* r0 : argument */ + stack_frame->exception_stack_frame.r1 = 0; /* r1 */ + stack_frame->exception_stack_frame.r2 = 0; /* r2 */ + stack_frame->exception_stack_frame.r3 = 0; /* r3 */ + stack_frame->exception_stack_frame.r12 = 0; /* r12 */ + stack_frame->exception_stack_frame.lr = (unsigned long)texit; /* lr */ + stack_frame->exception_stack_frame.pc = (unsigned long)tentry; /* entry point, pc */ + stack_frame->exception_stack_frame.psr = 0x01000000L; /* PSR */ + + /* return task's current stack address */ + return stk; +} + +extern long list_thread(void); +extern rt_thread_t rt_current_thread; +/** + * fault exception handling + */ +void rt_hw_hard_fault_exception(struct exception_stack_frame *contex) +{ + rt_kprintf("psr: 0x%08x\n", contex->psr); + rt_kprintf(" pc: 0x%08x\n", contex->pc); + rt_kprintf(" lr: 0x%08x\n", contex->lr); + rt_kprintf("r12: 0x%08x\n", contex->r12); + rt_kprintf("r03: 0x%08x\n", contex->r3); + rt_kprintf("r02: 0x%08x\n", contex->r2); + rt_kprintf("r01: 0x%08x\n", contex->r1); + rt_kprintf("r00: 0x%08x\n", contex->r0); + + rt_kprintf("hard fault on thread: %s\n", rt_current_thread->name); + +#ifdef RT_USING_FINSH + list_thread(); +#endif + + while (1); +} + +#define SCB_CFSR (*(volatile const unsigned *)0xE000ED28) /* Configurable Fault Status Register */ +#define SCB_HFSR (*(volatile const unsigned *)0xE000ED2C) /* HardFault Status Register */ +#define SCB_MMAR (*(volatile const unsigned *)0xE000ED34) /* MemManage Fault Address register */ +#define SCB_BFAR (*(volatile const unsigned *)0xE000ED38) /* Bus Fault Address Register */ +#define SCB_AIRCR (*(volatile unsigned long *)0xE000ED00) /* Reset control Address Register */ +#define SCB_RESET_VALUE 0x05FA0004 /* Reset value, write to SCB_AIRCR can reset cpu */ + +#define SCB_CFSR_MFSR (*(volatile const unsigned char*)0xE000ED28) /* Memory-management Fault Status Register */ +#define SCB_CFSR_BFSR (*(volatile const unsigned char*)0xE000ED29) /* Bus Fault Status Register */ +#define SCB_CFSR_UFSR (*(volatile const unsigned short*)0xE000ED2A) /* Usage Fault Status Register */ + +/** + * reset CPU + */ +RT_WEAK void rt_hw_cpu_reset(void) +{ + SCB_AIRCR = SCB_RESET_VALUE;//((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |SCB_AIRCR_SYSRESETREQ_Msk); +} diff --git a/src/Kconfig b/src/Kconfig index e0a8050ff1be9801ec6ad793c65ca2d8a2df667f..21b1d638064373541739b9cab6793386cfb56871 100644 --- a/src/Kconfig +++ b/src/Kconfig @@ -124,7 +124,7 @@ if RT_DEBUG config RT_DEBUG_COLOR bool "Enable color debugging log" - default y + default n config RT_DEBUG_INIT_CONFIG bool "Enable debugging of components initialization" diff --git a/src/object.c b/src/object.c index 70b9a5c04ed4b3c4850ea8d620270e3b6ed67d08..e85737ce8fdf1a9679b5714bd10f330c4ddfa6ad 100644 --- a/src/object.c +++ b/src/object.c @@ -240,6 +240,7 @@ void rt_object_init(struct rt_object *object, const char *name) { register rt_base_t temp; + struct rt_list_node *node = RT_NULL; struct rt_object_information *information; #ifdef RT_USING_MODULE struct rt_dlmodule *module = dlmodule_self(); @@ -249,11 +250,26 @@ void rt_object_init(struct rt_object *object, information = rt_object_get_information(type); RT_ASSERT(information != RT_NULL); - /* initialize object's parameters */ + /* check object type to avoid re-initialization */ + + /* enter critical */ + rt_enter_critical(); + /* try to find object */ + for (node = information->object_list.next; + node != &(information->object_list); + node = node->next) + { + struct rt_object *obj; + + obj = rt_list_entry(node, struct rt_object, list); + RT_ASSERT(obj != object); + } + /* leave critical */ + rt_exit_critical(); + /* initialize object's parameters */ /* set object type to static */ object->type = type | RT_Object_Class_Static; - /* copy name */ rt_strncpy(object->name, name, RT_NAME_MAX); diff --git a/src/scheduler.c b/src/scheduler.c index 37b262d83bf1370e280e57b95c10ebd4d7f05802..be29d9a7e054b4fef95d77f4c7749c238e37f396 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -792,6 +792,12 @@ void rt_enter_critical(void) level = rt_hw_local_irq_disable(); current_thread = rt_cpu_self()->current_thread; + if (!current_thread) + { + rt_hw_local_irq_enable(level); + return ; + } + /* * the maximal number of nest is RT_UINT16_MAX, which is big * enough and does not check here @@ -842,6 +848,11 @@ void rt_exit_critical(void) level = rt_hw_local_irq_disable(); current_thread = rt_cpu_self()->current_thread; + if (!current_thread) + { + rt_hw_local_irq_enable(level); + return ; + } current_thread->scheduler_lock_nest --; @@ -873,14 +884,17 @@ void rt_exit_critical(void) level = rt_hw_interrupt_disable(); rt_scheduler_lock_nest --; - if (rt_scheduler_lock_nest <= 0) { rt_scheduler_lock_nest = 0; /* enable interrupt */ rt_hw_interrupt_enable(level); - rt_schedule(); + if (rt_current_thread) + { + /* if scheduler is started, do a schedule */ + rt_schedule(); + } } else {