diff --git a/bsp/n32g452xx/Libraries/rt_drivers/SConscript b/bsp/n32g452xx/Libraries/rt_drivers/SConscript index 4e06b431d5..1298ec7063 100755 --- a/bsp/n32g452xx/Libraries/rt_drivers/SConscript +++ b/bsp/n32g452xx/Libraries/rt_drivers/SConscript @@ -20,41 +20,41 @@ if GetDepend(['RT_USING_WDT']): if GetDepend(['RT_USING_SERIAL']): src += ['drv_usart.c'] -if GetDepend(['RT_USING_PWM']): +if GetDepend(['BSP_USING_PWM']): src += ['drv_pwm.c'] -if GetDepend(['RT_USING_HWTIMER']): +if GetDepend(['BSP_USING_HWTIMER']): src += ['drv_hwtimer.c'] -if GetDepend(['RT_USING_SPI']): +if GetDepend(['BSP_USING_SPI']): src += ['drv_spi.c'] -if GetDepend(['RT_USING_ETH', 'RT_USING_LWIP']): +if GetDepend(['BSP_USING_ETH', 'BSP_USING_LWIP']): src += ['drv_eth.c'] if GetDepend(['RT_USING_I2C', 'RT_USING_I2C_BITOPS']): - if GetDepend('RT_USING_I2C1') or GetDepend('RT_USING_I2C2') or GetDepend('RT_USING_I2C3') or GetDepend('RT_USING_I2C4'): + if GetDepend('BSP_USING_I2C1') or GetDepend('BSP_USING_I2C2') or GetDepend('BSP_USING_I2C3') or GetDepend('BSP_USING_I2C4'): src += ['drv_soft_i2c.c'] -if GetDepend(['RT_USING_ADC']): +if GetDepend(['BSP_USING_ADC']): src += Glob('drv_adc.c') -if GetDepend('RT_USING_SRAM'): +if GetDepend('BSP_USING_SRAM'): src += ['drv_sram.c'] -if GetDepend('RT_USING_RTC'): +if GetDepend('BSP_USING_RTC'): src += ['drv_rtc.c'] -if GetDepend('RT_USING_ON_CHIP_FLASH'): +if GetDepend('BSP_USING_ON_CHIP_FLASH'): src += ['drv_flash.c'] -if GetDepend(['RT_USING_WDT']): +if GetDepend(['BSP_USING_WDT']): src += ['drv_wdt.c'] -if GetDepend(['RT_USING_CAN']): +if GetDepend(['BSP_USING_CAN']): src += ['drv_can.c'] -if GetDepend(['RT_USING_SDIO']): +if GetDepend(['BSP_USING_SDIO']): src += ['drv_sdio.c'] CPPPATH = [cwd] diff --git a/bsp/n32g452xx/Libraries/rt_drivers/drv_adc.c b/bsp/n32g452xx/Libraries/rt_drivers/drv_adc.c new file mode 100755 index 0000000000..44f7c24167 --- /dev/null +++ b/bsp/n32g452xx/Libraries/rt_drivers/drv_adc.c @@ -0,0 +1,208 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-01-15 Leo first version + */ + +#include +#include "drv_adc.h" + +#if defined(BSP_USING_ADC1) || defined(BSP_USING_ADC2) || defined(BSP_USING_ADC3) +#define DRV_DEBUG +#define LOG_TAG "drv.adc" +#include + +struct n32_adc +{ + struct rt_adc_device n32_adc_device; + ADC_Module *ADC_Handler; + char *name; +}; + +static struct n32_adc n32_adc_obj[] = +{ +#ifdef BSP_USING_ADC1 + ADC1_CONFIG, +#endif + +#ifdef BSP_USING_ADC2 + ADC2_CONFIG, +#endif + +#ifdef BSP_USING_ADC3 + ADC3_CONFIG, +#endif +}; + +static rt_uint32_t n32_adc_get_channel(rt_uint32_t channel) +{ + rt_uint32_t n32_channel = 0; + + switch (channel) + { + case 0: + n32_channel = ADC_CH_0; + break; + case 1: + n32_channel = ADC_CH_1; + break; + case 2: + n32_channel = ADC_CH_2; + break; + case 3: + n32_channel = ADC_CH_3; + break; + case 4: + n32_channel = ADC_CH_4; + break; + case 5: + n32_channel = ADC_CH_5; + break; + case 6: + n32_channel = ADC_CH_6; + break; + case 7: + n32_channel = ADC_CH_7; + break; + case 8: + n32_channel = ADC_CH_8; + break; + case 9: + n32_channel = ADC_CH_9; + break; + case 10: + n32_channel = ADC_CH_10; + break; + case 11: + n32_channel = ADC_CH_11; + break; + case 12: + n32_channel = ADC_CH_12; + break; + case 13: + n32_channel = ADC_CH_13; + break; + case 14: + n32_channel = ADC_CH_14; + break; + case 15: + n32_channel = ADC_CH_15; + break; + case 16: + n32_channel = ADC_CH_16; + break; + case 17: + n32_channel = ADC_CH_17; + break; + } + + return n32_channel; +} + +static rt_err_t n32_adc_enabled(struct rt_adc_device *device, rt_uint32_t channel, rt_bool_t enabled) +{ + ADC_Module *n32_adc_handler; + ADC_InitType ADC_InitStructure; + RT_ASSERT(device != RT_NULL); + n32_adc_handler = device->parent.user_data; + + n32_msp_adc_init(n32_adc_handler); + + /* ADCx configuration ------------------------------------------------------*/ + ADC_InitStruct(&ADC_InitStructure); + ADC_InitStructure.WorkMode = ADC_WORKMODE_INDEPENDENT; + ADC_InitStructure.MultiChEn = DISABLE; + ADC_InitStructure.ContinueConvEn = DISABLE; + ADC_InitStructure.ExtTrigSelect = ADC_EXT_TRIGCONV_NONE; + ADC_InitStructure.DatAlign = ADC_DAT_ALIGN_R; + ADC_InitStructure.ChsNumber = 1; + ADC_Init(n32_adc_handler, &ADC_InitStructure); + + /* ADCx regular channels configuration */ + ADC_ConfigRegularChannel(n32_adc_handler, n32_adc_get_channel(channel), 1, ADC_SAMP_TIME_28CYCLES5); + + /* Enable ADCx */ + ADC_Enable(n32_adc_handler, ENABLE); + + // /* Enable ADCx reset calibration register */ + // ADC_RstCalibration(n32_adc_handler); + // /* Check the end of ADCx reset calibration register */ + // while(ADC_GetResetCalibrationStatus(n32_adc_handler)); + + /* Start ADCx calibration */ + ADC_StartCalibration(n32_adc_handler); + /* Check the end of ADCx calibration */ + while(ADC_GetCalibrationStatus(n32_adc_handler)); + + if (enabled) + { + /* Enable ADC1 */ + ADC_Enable(n32_adc_handler, ENABLE); + } + else + { + /* Enable ADCx */ + ADC_Enable(n32_adc_handler, DISABLE); + } + + return RT_EOK; +} + +static rt_err_t n32_get_adc_value(struct rt_adc_device *device, rt_uint32_t channel, rt_uint32_t *value) +{ + ADC_Module *n32_adc_handler; + + RT_ASSERT(device != RT_NULL); + RT_ASSERT(value != RT_NULL); + + n32_adc_handler = device->parent.user_data; + + /* Start ADCx Software Conversion */ + ADC_EnableSoftwareStartConv(n32_adc_handler, ENABLE); + + /* Wait for the ADC to convert */ + while(ADC_GetFlagStatus(n32_adc_handler, ADC_FLAG_ENDC) == RESET); + + /* get ADC value */ + *value = ADC_GetDat(n32_adc_handler); + + return RT_EOK; +} + +static const struct rt_adc_ops at_adc_ops = +{ + .enabled = n32_adc_enabled, + .convert = n32_get_adc_value, +}; + +static int rt_hw_adc_init(void) +{ + int result = RT_EOK; + int i = 0; + + for (i = 0; i < sizeof(n32_adc_obj) / sizeof(n32_adc_obj[0]); i++) + { + /* register ADC device */ + if (rt_hw_adc_register(&n32_adc_obj[i].n32_adc_device, + n32_adc_obj[i].name, &at_adc_ops, + n32_adc_obj[i].ADC_Handler) == RT_EOK) + { + LOG_D("%s register success", n32_adc_obj[i].name); + } + else + { + LOG_E("%s register failed", n32_adc_obj[i].name); + result = -RT_ERROR; + } + } + + return result; +} +INIT_BOARD_EXPORT(rt_hw_adc_init); + +#endif /* BSP_USING_ADC */ + diff --git a/bsp/n32g452xx/Libraries/rt_drivers/drv_adc.h b/bsp/n32g452xx/Libraries/rt_drivers/drv_adc.h new file mode 100755 index 0000000000..38f06c3144 --- /dev/null +++ b/bsp/n32g452xx/Libraries/rt_drivers/drv_adc.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018-12-07 Leo first version + */ + +#ifndef __ADC_CONFIG_H__ +#define __ADC_CONFIG_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(BSP_USING_ADC1) || defined(BSP_USING_ADC2) || defined(BSP_USING_ADC3) + +#ifndef ADC1_CONFIG +#define ADC1_CONFIG \ + { \ + .ADC_Handler = ADC1, \ + .name = "adc1", \ + } +#endif /* ADC1_CONFIG */ + +#ifndef ADC2_CONFIG +#define ADC2_CONFIG \ + { \ + .ADC_Handler = ADC2, \ + .name = "adc2", \ + } +#endif /* ADC2_CONFIG */ + +#ifndef ADC3_CONFIG +#define ADC3_CONFIG \ + { \ + .ADC_Handler = ADC3, \ + .name = "adc3", \ + } +#endif /* ADC3_CONFIG */ + +#endif + + +#ifdef __cplusplus +} +#endif + +#endif /* __ADC_CONFIG_H__ */ diff --git a/bsp/n32g452xx/Libraries/rt_drivers/drv_common.c b/bsp/n32g452xx/Libraries/rt_drivers/drv_common.c index 8970b7ce89..bc653ca6a2 100755 --- a/bsp/n32g452xx/Libraries/rt_drivers/drv_common.c +++ b/bsp/n32g452xx/Libraries/rt_drivers/drv_common.c @@ -62,3 +62,4 @@ void rt_hw_us_delay(rt_uint32_t us) } } } + diff --git a/bsp/n32g452xx/Libraries/rt_drivers/drv_flash.c b/bsp/n32g452xx/Libraries/rt_drivers/drv_flash.c new file mode 100755 index 0000000000..45b9b6956c --- /dev/null +++ b/bsp/n32g452xx/Libraries/rt_drivers/drv_flash.c @@ -0,0 +1,210 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-02-09 shelton the first version + */ + +#include +#include + +#ifdef BSP_USING_ON_CHIP_FLASH +#include "drv_flash.h" + +#if defined(PKG_USING_FAL) +#include "fal.h" +#endif + +//#define DRV_DEBUG +#define LOG_TAG "drv.flash" +#include + +/** + * @brief Gets the page of a given address + * @param addr: address of the flash memory + * @retval The page of a given address + */ +static rt_uint32_t get_page(uint32_t addr) +{ + rt_uint32_t page = 0; + + page = RT_ALIGN_DOWN(addr, FLASH_PAGE_SIZE); + + return page; +} + +/** + * Read data from flash. + * @note This operation's units is word. + * + * @param addr flash address + * @param buf buffer to store read data + * @param size read bytes size + * + * @return result + */ +int n32_flash_read(rt_uint32_t addr, rt_uint8_t *buf, size_t size) +{ + size_t i; + + if ((addr + size) > N32_FLASH_END_ADDRESS) + { + LOG_E("read outrange flash size! addr is (0x%p)", (void *)(addr + size)); + return -RT_EINVAL; + } + + for (i = 0; i < size; i++, buf++, addr++) + { + *buf = *(rt_uint8_t *) addr; + } + + return size; +} + +/** + * Write data to flash. + * @note This operation's units is word. + * @note This operation must after erase. @see flash_erase. + * + * @param addr flash address + * @param buf the write data buffer + * @param size write bytes size + * + * @return result + */ +int n32_flash_write(rt_uint32_t addr, const rt_uint8_t *buf, size_t size) +{ + rt_err_t result = RT_EOK; + rt_uint32_t end_addr = addr + size; + + if (addr % 4 != 0) + { + LOG_E("write addr must be 4-byte alignment"); + return -RT_EINVAL; + } + + if ((end_addr) > N32_FLASH_END_ADDRESS) + { + LOG_E("write outrange flash size! addr is (0x%p)", (void *)(addr + size)); + return -RT_EINVAL; + } + + FLASH_Unlock(); + + while (addr < end_addr) + { + if (FLASH_ProgramWord(addr, *((rt_uint32_t *)buf)) == FLASH_COMPL) + { + if (*(rt_uint32_t *)addr != *(rt_uint32_t *)buf) + { + result = -RT_ERROR; + break; + } + addr += 4; + buf += 4; + } + else + { + result = -RT_ERROR; + break; + } + } + + FLASH_Lock(); + + if (result != RT_EOK) + { + return result; + } + + return size; +} + +/** + * Erase data on flash . + * @note This operation is irreversible. + * @note This operation's units is different which on many chips. + * + * @param addr flash address + * @param size erase bytes size + * + * @return result + */ +int n32_flash_erase(rt_uint32_t addr, size_t size) +{ + rt_err_t result = RT_EOK; + rt_uint32_t end_addr = addr + size; + rt_uint32_t page_addr = 0; + + FLASH_Unlock(); + + if ((end_addr) > N32_FLASH_END_ADDRESS) + { + LOG_E("erase outrange flash size! addr is (0x%p)", (void *)(addr + size)); + return -RT_EINVAL; + } + + while(addr < end_addr) + { + page_addr = get_page(addr); + + if(FLASH_EraseOnePage(page_addr) != FLASH_COMPL) + { + result = -RT_ERROR; + goto __exit; + } + + addr += FLASH_PAGE_SIZE; + } + + FLASH_Lock(); + +__exit: + if(result != RT_EOK) + { + return result; + } + + return size; +} + +#if defined(PKG_USING_FAL) + +static int fal_flash_read(long offset, rt_uint8_t *buf, size_t size); +static int fal_flash_write(long offset, const rt_uint8_t *buf, size_t size); +static int fal_flash_erase(long offset, size_t size); + +const struct fal_flash_dev n32_onchip_flash = +{ + "onchip_flash", + N32_FLASH_START_ADRESS, + N32_FLASH_SIZE, + FLASH_PAGE_SIZE, + { + NULL, + fal_flash_read, + fal_flash_write, + fal_flash_erase + } +}; + +static int fal_flash_read(long offset, rt_uint8_t *buf, size_t size) +{ + return n32_flash_read(n32_onchip_flash.addr + offset, buf, size); +} + +static int fal_flash_write(long offset, const rt_uint8_t *buf, size_t size) +{ + return n32_flash_write(n32_onchip_flash.addr + offset, buf, size); +} + +static int fal_flash_erase(long offset, size_t size) +{ + return n32_flash_erase(n32_onchip_flash.addr + offset, size); +} + +#endif +#endif /* BSP_USING_ON_CHIP_FLASH */ diff --git a/bsp/n32g452xx/Libraries/rt_drivers/drv_flash.h b/bsp/n32g452xx/Libraries/rt_drivers/drv_flash.h new file mode 100755 index 0000000000..ef4b1c716b --- /dev/null +++ b/bsp/n32g452xx/Libraries/rt_drivers/drv_flash.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-02-09 shelton the first version + */ + +#ifndef __DRV_FLASH_H__ +#define __DRV_FLASH_H__ + +#include +#include "rtdevice.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int n32_flash_read(rt_uint32_t addr, rt_uint8_t *buf, size_t size); +int n32_flash_write(rt_uint32_t addr, const rt_uint8_t *buf, size_t size); +int n32_flash_erase(rt_uint32_t addr, size_t size); + +#ifdef __cplusplus +} +#endif + +#endif /* __DRV_FLASH_H__ */ diff --git a/bsp/n32g452xx/Libraries/rt_drivers/drv_hwtimer.c b/bsp/n32g452xx/Libraries/rt_drivers/drv_hwtimer.c new file mode 100755 index 0000000000..dede483e54 --- /dev/null +++ b/bsp/n32g452xx/Libraries/rt_drivers/drv_hwtimer.c @@ -0,0 +1,412 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-03-16 Leo first version + */ + +#include +#include "drv_hwtimer.h" + +#define DRV_DEBUG +#define LOG_TAG "drv.hwtimer" +#include + +#ifdef BSP_USING_HWTIMER +enum +{ +#ifdef BSP_USING_HWTMR1 + TMR1_INDEX, +#endif + +#ifdef BSP_USING_HWTMR2 + TMR2_INDEX, +#endif + +#ifdef BSP_USING_HWTMR3 + TMR3_INDEX, +#endif + +#ifdef BSP_USING_HWTMR4 + TMR4_INDEX, +#endif + +#ifdef BSP_USING_HWTMR5 + TMR5_INDEX, +#endif + +#ifdef BSP_USING_HWTMR6 + TMR6_INDEX, +#endif + +#ifdef BSP_USING_HWTMR7 + TMR7_INDEX, +#endif + +#ifdef BSP_USING_HW_TMR8 + TMR8_INDEX, +#endif + +#ifdef BSP_USING_HWTMR9 + TMR9_INDEX, +#endif + +#ifdef BSP_USING_HWTMR10 + TMR10_INDEX, +#endif + +#ifdef BSP_USING_HWTMR11 + TMR11_INDEX, +#endif + +#ifdef BSP_USING_HWTMR12 + TMR12_INDEX, +#endif + +#ifdef BSP_USING_HWTMR13 + TMR13_INDEX, +#endif + +#ifdef BSP_USING_HWTMR14 + TMR14_INDEX, +#endif + +#ifdef BSP_USING_HWTMR15 + TMR15_INDEX, +#endif +}; + +struct at32_hwtimer +{ + rt_hwtimer_t time_device; + TMR_Type* tim_handle; + IRQn_Type tim_irqn; + char *name; +}; + +static struct at32_hwtimer at32_hwtimer_obj[] = +{ +#ifdef BSP_USING_HWTMR1 + TMR1_CONFIG, +#endif + +#ifdef BSP_USING_HWTMR2 + TMR2_CONFIG, +#endif + +#ifdef BSP_USING_HWTMR3 + TMR3_CONFIG, +#endif + +#ifdef BSP_USING_HWTMR4 + TMR4_CONFIG, +#endif + +#ifdef BSP_USING_HWTMR5 + TMR5_CONFIG, +#endif + +#ifdef BSP_USING_HWTMR6 + TMR6_CONFIG, +#endif + +#ifdef BSP_USING_HWTMR7 + TMR7_CONFIG, +#endif + +#ifdef BSP_USING_HWTMR8 + TMR8_CONFIG, +#endif + +#ifdef BSP_USING_HWTMR9 + TMR9_CONFIG, +#endif + +#ifdef BSP_USING_HWTMR10 + TMR10_CONFIG, +#endif + +#ifdef BSP_USING_HWTMR11 + TMR11_CONFIG, +#endif + +#ifdef BSP_USING_HWTMR12 + TMR12_CONFIG, +#endif + +#ifdef BSP_USING_HWTMR13 + TMR13_CONFIG, +#endif + +#ifdef BSP_USING_HWTMR14 + TMR14_CONFIG, +#endif + +#ifdef BSP_USING_HWTMR15 + TMR15_CONFIG, +#endif +}; + +static void at32_timer_init(struct rt_hwtimer_device *timer, rt_uint32_t state) +{ + RCC_ClockType RCC_ClockStruct; + TMR_TimerBaseInitType TMR_TMReBaseStructure; + NVIC_InitType NVIC_InitStructure; + uint32_t prescaler_value = 0; + TMR_Type *tim = RT_NULL; + struct at32_hwtimer *tim_device = RT_NULL; + + RT_ASSERT(timer != RT_NULL); + if (state) + { + tim = (TMR_Type *)timer->parent.user_data; + tim_device = (struct at32_hwtimer *)timer; + + /* timer clock enable */ + at32_msp_hwtmr_init(tim); + + /* timer init */ + RCC_GetClocksFreq(&RCC_ClockStruct); + /* Set timer clock is 1Mhz */ + prescaler_value = (uint32_t)(RCC_ClockStruct.SYSCLK_Freq / 10000) - 1; + + TMR_TMReBaseStructure.TMR_Period = 10000 - 1; + TMR_TMReBaseStructure.TMR_DIV = prescaler_value; + TMR_TMReBaseStructure.TMR_ClockDivision = TMR_CKD_DIV1; + TMR_TMReBaseStructure.TMR_RepetitionCounter = 0; + + if (timer->info->cntmode == HWTIMER_CNTMODE_UP) + { + TMR_TMReBaseStructure.TMR_CounterMode = TMR_CounterDIR_Up; + } + else + { + TMR_TMReBaseStructure.TMR_CounterMode = TMR_CounterDIR_Down; + } + + TMR_TimeBaseInit(tim, &TMR_TMReBaseStructure); + + /* Enable the TMRx global Interrupt */ + NVIC_InitStructure.NVIC_IRQChannel = tim_device->tim_irqn; + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&NVIC_InitStructure); + + TMR_INTConfig(tim, TMR_INT_Overflow ,ENABLE); + TMR_ClearITPendingBit(tim, TMR_INT_Overflow); + + LOG_D("%s init success", tim_device->name); + } +} + +static rt_err_t at32_timer_start(rt_hwtimer_t *timer, rt_uint32_t t, rt_hwtimer_mode_t opmode) +{ + rt_err_t result = RT_EOK; + TMR_Type *tim = RT_NULL; + + RT_ASSERT(timer != RT_NULL); + + tim = (TMR_Type *)timer->parent.user_data; + + /* set tim cnt */ + TMR_SetCounter(tim, 0); + /* set tim arr */ + TMR_SetAutoreload(tim, t - 1); + if (opmode == HWTIMER_MODE_ONESHOT) + { + /* set timer to single mode */ + TMR_SelectOnePulseMode(tim, TMR_OPMode_Once); + } + else + { + TMR_SelectOnePulseMode(tim, TMR_OPMode_Repetitive); + } + + /* start timer */ + TMR_Cmd(tim, ENABLE); + + return result; +} + +static void at32_timer_stop(rt_hwtimer_t *timer) +{ + TMR_Type *tim = RT_NULL; + + RT_ASSERT(timer != RT_NULL); + + tim = (TMR_Type *)timer->parent.user_data; + + /* stop timer */ + TMR_Cmd(tim, ENABLE); + /* set tim cnt */ + TMR_SetCounter(tim, 0); +} + +static rt_uint32_t at32_timer_counter_get(rt_hwtimer_t *timer) +{ + TMR_Type *tim = RT_NULL; + + RT_ASSERT(timer != RT_NULL); + + tim = (TMR_Type *)timer->parent.user_data; + + return tim->CNT; +} + +static rt_err_t at32_timer_ctrl(rt_hwtimer_t *timer, rt_uint32_t cmd, void *arg) +{ + RCC_ClockType RCC_ClockStruct; + TMR_Type *tim = RT_NULL; + rt_err_t result = RT_EOK; + + RT_ASSERT(timer != RT_NULL); + RT_ASSERT(arg != RT_NULL); + + tim = (TMR_Type *)timer->parent.user_data; + + switch(cmd) + { + case HWTIMER_CTRL_FREQ_SET: + { + rt_uint32_t freq; + rt_uint16_t val; + + /* set timer frequence */ + freq = *((rt_uint32_t *)arg); + + /* time init */ + RCC_GetClocksFreq(&RCC_ClockStruct); + + val = RCC_ClockStruct.SYSCLK_Freq / freq; + + TMR_DIVConfig(tim, val - 1, TMR_DIVReloadMode_Immediate); + } + break; + default: + { + result = -RT_ENOSYS; + } + break; + } + + return result; +} + +static const struct rt_hwtimer_info _info = TMR_DEV_INFO_CONFIG; +static const struct rt_hwtimer_ops _ops = +{ + .init = at32_timer_init, + .start = at32_timer_start, + .stop = at32_timer_stop, + .count_get = at32_timer_counter_get, + .control = at32_timer_ctrl, +}; + +#ifdef BSP_USING_HWTMR2 +void TMR2_GLOBAL_IRQHandler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + + if(TMR_GetINTStatus(TMR2, TMR_INT_Overflow) == SET) + { + + rt_device_hwtimer_isr(&at32_hwtimer_obj[TMR2_INDEX].time_device); + TMR_ClearITPendingBit(TMR2, TMR_INT_Overflow); + + } + /* leave interrupt */ + rt_interrupt_leave(); +} +#endif + +#ifdef BSP_USING_HWTMR3 +void TMR3_GLOBAL_IRQHandler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + + if(TMR_GetINTStatus(TMR3, TMR_INT_Overflow) == SET) + { + + rt_device_hwtimer_isr(&at32_hwtimer_obj[TMR3_INDEX].time_device); + TMR_ClearITPendingBit(TMR3, TMR_INT_Overflow); + + } + /* leave interrupt */ + rt_interrupt_leave(); +} +#endif + +#ifdef BSP_USING_HWTMR4 +void TMR4_GLOBAL_IRQHandler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + + if(TMR_GetINTStatus(TMR4, TMR_INT_Overflow) == SET) + { + + rt_device_hwtimer_isr(&at32_hwtimer_obj[TMR4_INDEX].time_device); + TMR_ClearITPendingBit(TMR4, TMR_INT_Overflow); + + } + /* leave interrupt */ + rt_interrupt_leave(); +} +#endif + +#ifdef BSP_USING_HWTMR5 +void TMR5_GLOBAL_IRQHandler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + + if(TMR_GetINTStatus(TMR5, TMR_INT_Overflow) == SET) + { + + rt_device_hwtimer_isr(&at32_hwtimer_obj[TMR5_INDEX].time_device); + TMR_ClearITPendingBit(TMR5, TMR_INT_Overflow); + + } + /* leave interrupt */ + rt_interrupt_leave(); +} +#endif + +static int rt_hw_hwtimer_init(void) +{ + int i = 0; + int result = RT_EOK; + + for (i = 0; i < sizeof(at32_hwtimer_obj) / sizeof(at32_hwtimer_obj[0]); i++) + { + at32_hwtimer_obj[i].time_device.info = &_info; + at32_hwtimer_obj[i].time_device.ops = &_ops; + if (rt_device_hwtimer_register(&at32_hwtimer_obj[i].time_device, at32_hwtimer_obj[i].name, at32_hwtimer_obj[i].tim_handle) == RT_EOK) + { + LOG_D("%s register success", at32_hwtimer_obj[i].name); + } + else + { + LOG_E("%s register failed", at32_hwtimer_obj[i].name); + result = -RT_ERROR; + } + } + + return result; +} +INIT_BOARD_EXPORT(rt_hw_hwtimer_init); + +#endif /* BSP_USING_HWTIMER */ + + + + + + + diff --git a/bsp/n32g452xx/Libraries/rt_drivers/drv_hwtimer.h b/bsp/n32g452xx/Libraries/rt_drivers/drv_hwtimer.h new file mode 100755 index 0000000000..9acfb8d468 --- /dev/null +++ b/bsp/n32g452xx/Libraries/rt_drivers/drv_hwtimer.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-03-16 Leo first version + */ + +#ifndef __TMR_CONFIG_H__ +#define __TMR_CONFIG_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef TMR_DEV_INFO_CONFIG +#define TMR_DEV_INFO_CONFIG \ + { \ + .maxfreq = 1000000, \ + .minfreq = 4000, \ + .maxcnt = 0xFFFF, \ + .cntmode = HWTIMER_CNTMODE_UP, \ + } +#endif /* TIM_DEV_INFO_CONFIG */ + +#ifdef BSP_USING_HWTMR2 +#ifndef TMR2_CONFIG +#define TMR2_CONFIG \ + { \ + .tim_handle = TMR2, \ + .tim_irqn = TMR2_GLOBAL_IRQn, \ + .name = "timer2", \ + } +#endif /* TMR2_CONFIG */ +#endif /* BSP_USING_HWTMR2 */ + +#ifdef BSP_USING_HWTMR3 +#ifndef TMR3_CONFIG +#define TMR3_CONFIG \ + { \ + .tim_handle = TMR3, \ + .tim_irqn = TMR3_GLOBAL_IRQn, \ + .name = "timer3", \ + } +#endif /* TMR3_CONFIG */ +#endif /* BSP_USING_HWTMR3 */ + +#ifdef BSP_USING_HWTMR4 +#ifndef TMR4_CONFIG +#define TMR4_CONFIG \ + { \ + .tim_handle = TMR4, \ + .tim_irqn = TMR4_GLOBAL_IRQn, \ + .name = "timer4", \ + } +#endif /* TMR4_CONFIG */ +#endif /* BSP_USING_HWTMR4 */ + +#ifdef BSP_USING_HWTMR5 +#ifndef TMR5_CONFIG +#define TMR5_CONFIG \ + { \ + .tim_handle = TMR5, \ + .tim_irqn = TMR5_GLOBAL_IRQn, \ + .name = "timer5", \ + } +#endif /* TMR5_CONFIG */ +#endif /* BSP_USING_HWTMR5 */ + +#ifdef __cplusplus +} +#endif + +#endif /* __TMR_CONFIG_H__ */ + diff --git a/bsp/n32g452xx/Libraries/rt_drivers/drv_log.h b/bsp/n32g452xx/Libraries/rt_drivers/drv_log.h new file mode 100755 index 0000000000..d91f70d37c --- /dev/null +++ b/bsp/n32g452xx/Libraries/rt_drivers/drv_log.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-01-09 shelton first version + */ + +/* + * NOTE: DO NOT include this file on the header file. + */ + +#ifndef LOG_TAG +#define DBG_TAG "drv" +#else +#define DBG_TAG LOG_TAG +#endif /* LOG_TAG */ + +#ifdef DRV_DEBUG +#define DBG_LVL DBG_LOG +#else +#define DBG_LVL DBG_INFO +#endif /* DRV_DEBUG */ + +#include diff --git a/bsp/n32g452xx/Libraries/rt_drivers/drv_pwm.c b/bsp/n32g452xx/Libraries/rt_drivers/drv_pwm.c new file mode 100755 index 0000000000..dd09d3365c --- /dev/null +++ b/bsp/n32g452xx/Libraries/rt_drivers/drv_pwm.c @@ -0,0 +1,291 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-1-13 Leo first version + */ + +#include +#include "drv_pwm.h" + +#ifdef RT_USING_PWM +#if !defined(BSP_USING_TIM1_CH1) && !defined(BSP_USING_TIM1_CH2) && \ + !defined(BSP_USING_TIM1_CH3) && !defined(BSP_USING_TIM1_CH4) && \ + !defined(BSP_USING_TIM2_CH1) && !defined(BSP_USING_TIM2_CH2) && \ + !defined(BSP_USING_TIM2_CH3) && !defined(BSP_USING_TIM2_CH4) && \ + !defined(BSP_USING_TIM3_CH1) && !defined(BSP_USING_TIM3_CH2) && \ + !defined(BSP_USING_TIM3_CH3) && !defined(BSP_USING_TIM3_CH4) +#error "Please define at least one BSP_USING_TIMx_CHx" +#endif +#endif /* RT_USING_PWM */ + +#define DRV_DEBUG +#define LOG_TAG "drv.pwm" +#include + +#define MAX_PERIOD 65535 +struct rt_device_pwm pwm_device; + +struct at32_pwm +{ + struct rt_device_pwm pwm_device; + TMR_Type* tim_handle; + rt_uint8_t channel; + char *name; +}; + +static struct at32_pwm at32_pwm_obj[] = +{ + #ifdef BSP_USING_TIM1_CH1 + PWM1_CONFIG, + #endif + + #ifdef BSP_USING_TIM1_CH2 + PWM2_CONFIG, + #endif + + #ifdef BSP_USING_TIM1_CH3 + PWM3_CONFIG, + #endif + + #ifdef BSP_USING_TIM1_CH4 + PWM4_CONFIG, + #endif + + #ifdef BSP_USING_TIM2_CH1 + PWM5_CONFIG, + #endif + + #ifdef BSP_USING_TIM2_CH2 + PWM6_CONFIG, + #endif + + #ifdef BSP_USING_TIM2_CH3 + PWM7_CONFIG, + #endif + + #ifdef BSP_USING_TIM2_CH4 + PWM8_CONFIG, + #endif + + #ifdef BSP_USING_TIM3_CH1 + PWM9_CONFIG, + #endif + + #ifdef BSP_USING_TIM3_CH2 + PWM10_CONFIG, + #endif + + #ifdef BSP_USING_TIM3_CH3 + PWM11_CONFIG, + #endif + + #ifdef BSP_USING_TIM3_CH4 + PWM12_CONFIG, + #endif +}; + +static rt_err_t drv_pwm_control(struct rt_device_pwm *device, int cmd, void *arg); +static struct rt_pwm_ops drv_ops = +{ + drv_pwm_control +}; + +static rt_err_t drv_pwm_enable(TMR_Type* TIMx, struct rt_pwm_configuration *configuration, rt_bool_t enable) +{ + /* Get the value of channel */ + rt_uint32_t channel = configuration->channel; + + if (!enable) + { + if(channel == 1) + { + TIM_CCxCmd(TIMx, TIM_Channel_1, TIM_CCx_Disable); + } + else if(channel == 2) + { + TIM_CCxCmd(TIMx, TIM_Channel_2, TIM_CCx_Disable); + } + else if(channel == 3) + { + TIM_CCxCmd(TIMx, TIM_Channel_3, TIM_CCx_Disable); + } + else if(channel == 4) + { + TIM_CCxCmd(TIMx, TIM_Channel_4, TIM_CCx_Disable); + } + } + else + { + if(channel == 1) + { + TIM_CCxCmd(TIMx, TIM_Channel_1, TIM_CCx_Enable); + } + else if(channel == 2) + { + TIM_CCxCmd(TIMx, TIM_Channel_1, TIM_CCx_Enable); + } + else if(channel == 3) + { + TIM_CCxCmd(TIMx, TIM_Channel_1, TIM_CCx_Enable); + } + else if(channel == 4) + { + TIM_CCxCmd(TIMx, TIM_Channel_1, TIM_CCx_Enable); + } + } + + /* TIMx enable counter */ + TIM_Cmd(TIMx, ENABLE); + + return RT_EOK; +} + +static rt_err_t drv_pwm_get(TMR_Type* TIMx, struct rt_pwm_configuration *configuration) +{ + RCC_ClockType RCC_Clockstruct; + rt_uint32_t ar, div, cc1, cc2, cc3, cc4; + rt_uint32_t channel = configuration->channel; + rt_uint64_t tim_clock; + + ar = TIMx->AR; + div = TIMx->DIV; + cc1 = TIMx->CC1; + cc2 = TIMx->CC2; + cc3 = TIMx->CC3; + cc4 = TIMx->CC4; + + RCC_GetClocksFreq(&RCC_Clockstruct); + + tim_clock = RCC_Clockstruct.APB2CLK_Freq; + + /* Convert nanosecond to frequency and duty cycle. */ + tim_clock /= 1000000UL; + configuration->period = (ar + 1) * (div + 1) * 1000UL / tim_clock; + if(channel == 1) + configuration->pulse = (cc1 + 1) * (div + 1) * 1000UL / tim_clock; + if(channel == 2) + configuration->pulse = (cc2 + 1) * (div+ 1) * 1000UL / tim_clock; + if(channel == 3) + configuration->pulse = (cc3 + 1) * (div + 1) * 1000UL / tim_clock; + if(channel == 4) + configuration->pulse = (cc4 + 1) * (div + 1) * 1000UL / tim_clock; + + return RT_EOK; +} + +static rt_err_t drv_pwm_set(TMR_Type* TIMx, struct rt_pwm_configuration *configuration) +{ + TIM_TimerBaseInitType TIM_TIMeBaseStructure; + TIM_OCInitType TIM_OCInitStructure; + rt_uint32_t period, pulse; + rt_uint64_t psc; + /* Get the channel number */ + rt_uint32_t channel = configuration->channel; + + /* Init timer pin and enable clock */ + at32_msp_tmr_init(TIMx); + + /* Convert nanosecond to frequency and duty cycle. */ + period = (unsigned long long)configuration->period ; + psc = period / MAX_PERIOD + 1; + period = period / psc; + + /* TIMe base configuration */ + TIM_TimeBaseStructInit(&TIM_TIMeBaseStructure); + TIM_TIMeBaseStructure.TIM_Period = period; + TIM_TIMeBaseStructure.TIM_DIV = psc - 1; + TIM_TIMeBaseStructure.TIM_ClockDivision = 0; + TIM_TIMeBaseStructure.TIM_CounterMode = TIM_CounterDIR_Up; + + TIM_TimeBaseInit(TIMx, &TIM_TIMeBaseStructure); + + pulse = (unsigned long long)configuration->pulse; + + /* PWM1 Mode configuration: Channel1 */ + TIM_OCStructInit(&TIM_OCInitStructure); + TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; + TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; + TIM_OCInitStructure.TIM_Pulse = pulse; + TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; + + if(channel == 1) + { + TIM_OC1Init(TIMx, &TIM_OCInitStructure); + TIM_OC1PreloadConfig(TIMx, TIM_OCPreload_Enable); + } + else if(channel == 2) + { + TIM_OC2Init(TIMx, &TIM_OCInitStructure); + TIM_OC2PreloadConfig(TIMx, TIM_OCPreload_Enable); + } + else if(channel == 3) + { + TIM_OC3Init(TIMx, &TIM_OCInitStructure); + TIM_OC3PreloadConfig(TIMx, TIM_OCPreload_Enable); + } + else if(channel == 4) + { + TIM_OC4Init(TIMx, &TIM_OCInitStructure); + TIM_OC4PreloadConfig(TIMx, TIM_OCPreload_Enable); + } + + TIM_ARPreloadConfig(TIMx, ENABLE); + +#if defined (SOC_SERIES_AT32F415) + if(TIMx == TIM1) +#else + if(TIMx == TIM1 || TIMx == TIM8) +#endif + { + TIM_CtrlPWMOutputs(TIMx,ENABLE); + } + + return RT_EOK; +} + +static rt_err_t drv_pwm_control(struct rt_device_pwm *device, int cmd, void *arg) +{ + struct rt_pwm_configuration *configuration = (struct rt_pwm_configuration *)arg; + TIM_Type *TIMx = (TIM_Type *)device->parent.user_data; + + switch (cmd) + { + case PWM_CMD_ENABLE: + return drv_pwm_enable(TIMx, configuration, RT_TRUE); + case PWM_CMD_DISABLE: + return drv_pwm_enable(TIMx, configuration, RT_FALSE); + case PWM_CMD_SET: + return drv_pwm_set(TIMx, configuration); + case PWM_CMD_GET: + return drv_pwm_get(TIMx, configuration); + default: + return RT_EINVAL; + } +} + +static int rt_hw_pwm_init(void) +{ + int i = 0; + int result = RT_EOK; + + for(i = 0; i < sizeof(at32_pwm_obj) / sizeof(at32_pwm_obj[0]); i++) + { + if(rt_device_pwm_register(&at32_pwm_obj[i].pwm_device, at32_pwm_obj[i].name, &drv_ops, at32_pwm_obj[i].tim_handle) == RT_EOK) + { + LOG_D("%s register success", at32_pwm_obj[i].name); + } + else + { + LOG_D("%s register failed", at32_pwm_obj[i].name); + result = -RT_ERROR; + } + } + + return result; +} + +INIT_BOARD_EXPORT(rt_hw_pwm_init); diff --git a/bsp/n32g452xx/Libraries/rt_drivers/drv_pwm.h b/bsp/n32g452xx/Libraries/rt_drivers/drv_pwm.h new file mode 100755 index 0000000000..720a810f79 --- /dev/null +++ b/bsp/n32g452xx/Libraries/rt_drivers/drv_pwm.h @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-1-13 Leo first version + */ + +#ifndef __PWM_CONFIG_H__ +#define __PWM_CONFIG_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef BSP_USING_TMR1_CH1 +#ifndef PWM1_CONFIG +#define PWM1_CONFIG \ + { \ + .tim_handle = TMR1, \ + .name = "tmr1pwm1", \ + .channel = 1 \ + } +#endif /* PWM1_CONFIG */ +#endif /* BSP_USING_TMR1_CH1 */ + +#ifdef BSP_USING_TMR1_CH2 +#ifndef PWM2_CONFIG +#define PWM2_CONFIG \ + { \ + .tim_handle = TMR1, \ + .name = "tmr1pwm2", \ + .channel = 2 \ + } +#endif /* PWM2_CONFIG */ +#endif /* BSP_USING_TMR1_CH2 */ + +#ifdef BSP_USING_TMR1_CH3 +#ifndef PWM3_CONFIG +#define PWM3_CONFIG \ + { \ + .tim_handle = TMR1, \ + .name = "tmr1pwm3", \ + .channel = 3 \ + } +#endif /* PWM3_CONFIG */ +#endif /* BSP_USING_TMR1_CH3 */ + +#ifdef BSP_USING_TMR1_CH4 +#ifndef PWM4_CONFIG +#define PWM4_CONFIG \ + { \ + .tim_handle = TMR1, \ + .name = "tmr1pwm4", \ + .channel = 4 \ + } +#endif /* PWM4_CONFIG */ +#endif /* BSP_USING_TMR1_CH4 */ + +#ifdef BSP_USING_TMR2_CH1 +#ifndef PWM5_CONFIG +#define PWM5_CONFIG \ + { \ + .tim_handle = TMR2, \ + .name = "tmr2pwm1", \ + .channel = 1 \ + } +#endif /* PWM5_CONFIG */ +#endif /* BSP_USING_TMR2_CH1 */ + +#ifdef BSP_USING_TMR2_CH2 +#ifndef PWM6_CONFIG +#define PWM6_CONFIG \ + { \ + .tim_handle = TMR2, \ + .name = "tmr2pwm2", \ + .channel = 2 \ + } +#endif /* PWM6_CONFIG */ +#endif /* BSP_USING_TMR2_CH2 */ + +#ifdef BSP_USING_TMR2_CH3 +#ifndef PWM7_CONFIG +#define PWM7_CONFIG \ + { \ + .tim_handle = TMR2, \ + .name = "tmr2pwm3", \ + .channel = 3 \ + } +#endif /* PWM7_CONFIG */ +#endif /* BSP_USING_TMR2_CH3 */ + +#ifdef BSP_USING_TMR2_CH4 +#ifndef PWM8_CONFIG +#define PWM8_CONFIG \ + { \ + .tim_handle = TMR2, \ + .name = "tmr2pwm4", \ + .channel = 4 \ + } +#endif /* PWM8_CONFIG */ +#endif /* BSP_USING_TMR2_CH4 */ + +#ifdef BSP_USING_TMR3_CH1 +#ifndef PWM9_CONFIG +#define PWM9_CONFIG \ + { \ + .tim_handle = TMR3, \ + .name = "tmr3pwm1", \ + .channel = 1 \ + } +#endif /* PWM9_CONFIG */ +#endif /* BSP_USING_TMR3_CH1 */ + +#ifdef BSP_USING_TMR3_CH2 +#ifndef PWM10_CONFIG +#define PWM10_CONFIG \ + { \ + .tim_handle = TMR3, \ + .name = "tmr3pwm2", \ + .channel = 2 \ + } +#endif /* PWM10_CONFIG */ +#endif /* BSP_USING_TMR3_CH2 */ + +#ifdef BSP_USING_TMR3_CH3 +#ifndef PWM11_CONFIG +#define PWM11_CONFIG \ + { \ + .tim_handle = TMR3, \ + .name = "tmr3pwm3", \ + .channel = 3 \ + } +#endif /* PWM11_CONFIG */ +#endif /* BSP_USING_TMR3_CH3 */ + +#ifdef BSP_USING_TMR3_CH4 +#ifndef PWM12_CONFIG +#define PWM12_CONFIG \ + { \ + .tim_handle = TMR3, \ + .name = "tmr3pwm4", \ + .channel = 4 \ + } +#endif /* PWM12_CONFIG */ +#endif /* BSP_USING_TMR3_CH4 */ + +#ifdef __cplusplus +} +#endif + +#endif /* __PWM_CONFIG_H__ */ diff --git a/bsp/n32g452xx/Libraries/rt_drivers/drv_soft_i2c.c b/bsp/n32g452xx/Libraries/rt_drivers/drv_soft_i2c.c new file mode 100755 index 0000000000..740875bf00 --- /dev/null +++ b/bsp/n32g452xx/Libraries/rt_drivers/drv_soft_i2c.c @@ -0,0 +1,220 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-01-09 shelton first version + */ + +#include +#include "drv_soft_i2c.h" + +#ifdef RT_USING_I2C + +#define LOG_TAG "drv.i2c" +#include + +#if !defined(BSP_USING_I2C1) && !defined(BSP_USING_I2C2) && !defined(BSP_USING_I2C3) && !defined(BSP_USING_I2C4) +#error "Please define at least one BSP_USING_I2Cx" +/* this driver can be disabled at menuconfig → RT-Thread Components → Device Drivers */ +#endif + +static const struct n32_soft_i2c_config soft_i2c_config[] = +{ +#ifdef BSP_USING_I2C1 + I2C1_BUS_CONFIG, +#endif +#ifdef BSP_USING_I2C2 + I2C2_BUS_CONFIG, +#endif +#ifdef BSP_USING_I2C3 + I2C3_BUS_CONFIG, +#endif +#ifdef BSP_USING_I2C4 + I2C4_BUS_CONFIG, +#endif +}; + +static struct n32_i2c i2c_obj[sizeof(soft_i2c_config) / sizeof(soft_i2c_config[0])]; + +/** + * This function initializes the i2c pin. + * + * @param Stm32 i2c dirver class. + */ +static void n32_i2c_gpio_init(struct n32_i2c *i2c) +{ + struct n32_soft_i2c_config* cfg = (struct n32_soft_i2c_config*)i2c->ops.data; + + rt_pin_mode(cfg->scl, PIN_MODE_OUTPUT_OD); + rt_pin_mode(cfg->sda, PIN_MODE_OUTPUT_OD); + + rt_pin_write(cfg->scl, PIN_HIGH); + rt_pin_write(cfg->sda, PIN_HIGH); +} + +/** + * This function sets the sda pin. + * + * @param Stm32 config class. + * @param The sda pin state. + */ +static void n32_set_sda(void *data, rt_int32_t state) +{ + struct n32_soft_i2c_config* cfg = (struct n32_soft_i2c_config*)data; + if (state) + { + rt_pin_write(cfg->sda, PIN_HIGH); + } + else + { + rt_pin_write(cfg->sda, PIN_LOW); + } +} + +/** + * This function sets the scl pin. + * + * @param Stm32 config class. + * @param The scl pin state. + */ +static void n32_set_scl(void *data, rt_int32_t state) +{ + struct n32_soft_i2c_config* cfg = (struct n32_soft_i2c_config*)data; + if (state) + { + rt_pin_write(cfg->scl, PIN_HIGH); + } + else + { + rt_pin_write(cfg->scl, PIN_LOW); + } +} + +/** + * This function gets the sda pin state. + * + * @param The sda pin state. + */ +static rt_int32_t n32_get_sda(void *data) +{ + struct n32_soft_i2c_config* cfg = (struct n32_soft_i2c_config*)data; + return rt_pin_read(cfg->sda); +} + +/** + * This function gets the scl pin state. + * + * @param The scl pin state. + */ +static rt_int32_t n32_get_scl(void *data) +{ + struct n32_soft_i2c_config* cfg = (struct n32_soft_i2c_config*)data; + return rt_pin_read(cfg->scl); +} +/** + * The time delay function. + * + * @param microseconds. + */ +static void n32_udelay(rt_uint32_t us) +{ + rt_uint32_t ticks; + rt_uint32_t told, tnow, tcnt = 0; + rt_uint32_t reload = SysTick->LOAD; + + ticks = us * reload / (1000000 / RT_TICK_PER_SECOND); + told = SysTick->VAL; + while (1) + { + tnow = SysTick->VAL; + if (tnow != told) + { + if (tnow < told) + { + tcnt += told - tnow; + } + else + { + tcnt += reload - tnow + told; + } + told = tnow; + if (tcnt >= ticks) + { + break; + } + } + } +} + +static const struct rt_i2c_bit_ops n32_bit_ops_default = +{ + .data = RT_NULL, + .set_sda = n32_set_sda, + .set_scl = n32_set_scl, + .get_sda = n32_get_sda, + .get_scl = n32_get_scl, + .udelay = n32_udelay, + .delay_us = 1, + .timeout = 100 +}; + +/** + * if i2c is locked, this function will unlock it + * + * @param at32 config class + * + * @return RT_EOK indicates successful unlock. + */ +static rt_err_t n32_i2c_bus_unlock(const struct n32_soft_i2c_config *cfg) +{ + rt_int32_t i = 0; + + if (PIN_LOW == rt_pin_read(cfg->sda)) + { + while (i++ < 9) + { + rt_pin_write(cfg->scl, PIN_HIGH); + n32_udelay(100); + rt_pin_write(cfg->scl, PIN_LOW); + n32_udelay(100); + } + } + if (PIN_LOW == rt_pin_read(cfg->sda)) + { + return -RT_ERROR; + } + + return RT_EOK; +} + +/* I2C initialization function */ +int rt_hw_i2c_init(void) +{ + rt_size_t obj_num = sizeof(i2c_obj) / sizeof(struct n32_i2c); + rt_err_t result; + + for (int i = 0; i < obj_num; i++) + { + i2c_obj[i].ops = n32_bit_ops_default; + i2c_obj[i].ops.data = (void*)&soft_i2c_config[i]; + i2c_obj[i].i2c_bus.priv = &i2c_obj[i].ops; + n32_i2c_gpio_init(&i2c_obj[i]); + result = rt_i2c_bit_add_bus(&i2c_obj[i].i2c_bus, soft_i2c_config[i].bus_name); + RT_ASSERT(result == RT_EOK); + n32_i2c_bus_unlock(&soft_i2c_config[i]); + + LOG_D("software simulation %s init done, pin scl: %d, pin sda %d", + soft_i2c_config[i].bus_name, + soft_i2c_config[i].scl, + soft_i2c_config[i].sda); + } + + return RT_EOK; +} + +INIT_BOARD_EXPORT(rt_hw_i2c_init); + +#endif /* RT_USING_I2C */ diff --git a/bsp/n32g452xx/Libraries/rt_drivers/drv_soft_i2c.h b/bsp/n32g452xx/Libraries/rt_drivers/drv_soft_i2c.h new file mode 100755 index 0000000000..683b0fe503 --- /dev/null +++ b/bsp/n32g452xx/Libraries/rt_drivers/drv_soft_i2c.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-01-09 shelton first version + */ + +#ifndef __DRV_I2C__ +#define __DRV_I2C__ + +#include +#include +#include + +/* at32 config class */ +struct n32_soft_i2c_config +{ + rt_uint8_t scl; + rt_uint8_t sda; + const char *bus_name; +}; +/* at32 i2c dirver class */ +struct n32_i2c +{ + struct rt_i2c_bit_ops ops; + struct rt_i2c_bus_device i2c_bus; +}; + +#ifdef BSP_USING_I2C1 +#define I2C1_BUS_CONFIG \ + { \ + .scl = BSP_I2C1_SCL_PIN, \ + .sda = BSP_I2C1_SDA_PIN, \ + .bus_name = "i2c1", \ + } +#endif + +#ifdef BSP_USING_I2C2 +#define I2C2_BUS_CONFIG \ + { \ + .scl = BSP_I2C2_SCL_PIN, \ + .sda = BSP_I2C2_SDA_PIN, \ + .bus_name = "i2c2", \ + } +#endif + +#ifdef BSP_USING_I2C3 +#define I2C3_BUS_CONFIG \ + { \ + .scl = BSP_I2C3_SCL_PIN, \ + .sda = BSP_I2C3_SDA_PIN, \ + .bus_name = "i2c3", \ + } +#endif + +#ifdef BSP_USING_I2C4 +#define I2C4_BUS_CONFIG \ + { \ + .scl = BSP_I2C4_SCL_PIN, \ + .sda = BSP_I2C4_SDA_PIN, \ + .bus_name = "i2c4", \ + } +#endif +int rt_hw_i2c_init(void); + +#endif diff --git a/bsp/n32g452xx/Libraries/rt_drivers/drv_spi.c b/bsp/n32g452xx/Libraries/rt_drivers/drv_spi.c new file mode 100755 index 0000000000..bfa53afebf --- /dev/null +++ b/bsp/n32g452xx/Libraries/rt_drivers/drv_spi.c @@ -0,0 +1,350 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-01-09 shelton first version + */ + +#include +#include "drv_spi.h" + +#ifdef RT_USING_SPI +#if !defined(BSP_USING_SPI1) && !defined(BSP_USING_SPI2) && \ + !defined(BSP_USING_SPI3) && !defined(BSP_USING_SPI4) +#error "Please define at least one SPIx" +#endif + +//#define DEBUG + +#define ARR_LEN(__N) (sizeof(__N) / sizeof(__N[0])) + +#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 n32_spi_ops = +{ + configure, + xfer +}; + +/** + * Attach the spi device to SPI bus, this function must be used after initialization. + */ +rt_err_t rt_hw_spi_device_attach(const char *bus_name, const char *device_name, GPIO_Module *cs_gpiox, uint16_t cs_gpio_pin) +{ + RT_ASSERT(bus_name != RT_NULL); + RT_ASSERT(device_name != RT_NULL); + + rt_err_t result; + struct rt_spi_device *spi_device; + struct n32_spi_cs *cs_pin; + + /* initialize the cs pin && select the slave*/ + GPIO_InitType GPIO_InitStruct; + GPIO_InitStruct.Pin = cs_gpio_pin; + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; + GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitPeripheral(cs_gpiox, &GPIO_InitStruct); + GPIO_SetBits(cs_gpiox, cs_gpio_pin); + + /* attach the device to spi bus*/ + spi_device = (struct rt_spi_device *)rt_malloc(sizeof(struct rt_spi_device)); + RT_ASSERT(spi_device != RT_NULL); + cs_pin = (struct n32_spi_cs *)rt_malloc(sizeof(struct n32_spi_cs)); + RT_ASSERT(cs_pin != RT_NULL); + cs_pin->GPIOx = cs_gpiox; + cs_pin->GPIO_Pin = cs_gpio_pin; + result = rt_spi_bus_attach_device(spi_device, device_name, bus_name, (void *)cs_pin); + + if (result != RT_EOK) + { + DEBUG_PRINTF("%s attach to %s faild, %d\n", device_name, bus_name, result); + } + + RT_ASSERT(result == RT_EOK); + + DEBUG_PRINTF("%s attach to %s done", device_name, bus_name); + + return result; +} + +static rt_err_t configure(struct rt_spi_device* device, + struct rt_spi_configuration* configuration) +{ + struct rt_spi_bus * spi_bus = (struct rt_spi_bus *)device->bus; + struct n32_spi *spi_instance = (struct n32_spi *)spi_bus->parent.user_data; + + SPI_InitType SPI_InitStruct; + + RT_ASSERT(device != RT_NULL); + RT_ASSERT(configuration != RT_NULL); + + n32_msp_spi_init(spi_instance->config->spix); + + /* data_width */ + if(configuration->data_width <= 8) + { + SPI_InitStruct.DataLen = SPI_DATA_SIZE_8BITS; + } + else if(configuration->data_width <= 16) + { + SPI_InitStruct.DataLen = SPI_DATA_SIZE_16BITS; + } + else + { + return RT_EIO; + } + + /* baudrate */ + { + uint32_t spi_apb_clock; + uint32_t max_hz; + RCC_ClocksType RCC_Clocks; + + max_hz = configuration->max_hz; + + RCC_GetClocksFreqValue(&RCC_Clocks); + DEBUG_PRINTF("sys freq: %d\n", RCC_Clocks.SysclkFreq); + DEBUG_PRINTF("max freq: %d\n", max_hz); + + if (spi_instance->config->spix == SPI1) + { + spi_apb_clock = RCC_Clocks.Pclk2Freq; + DEBUG_PRINTF("pclk2 freq: %d\n", RCC_Clocks.Pclk2Freq); + } + else + { + spi_apb_clock = RCC_Clocks.Pclk1Freq; + DEBUG_PRINTF("pclk1 freq: %d\n", RCC_Clocks.Pclk1Freq); + } + + if(max_hz >= spi_apb_clock/2) + { + SPI_InitStruct.BaudRatePres = SPI_BR_PRESCALER_2; + } + else if (max_hz >= spi_apb_clock/4) + { + SPI_InitStruct.BaudRatePres = SPI_BR_PRESCALER_4; + } + else if (max_hz >= spi_apb_clock/8) + { + SPI_InitStruct.BaudRatePres = SPI_BR_PRESCALER_8; + } + else if (max_hz >= spi_apb_clock/16) + { + SPI_InitStruct.BaudRatePres = SPI_BR_PRESCALER_16; + } + else if (max_hz >= spi_apb_clock/32) + { + SPI_InitStruct.BaudRatePres = SPI_BR_PRESCALER_32; + } + else if (max_hz >= spi_apb_clock/64) + { + SPI_InitStruct.BaudRatePres = SPI_BR_PRESCALER_64; + } + else if (max_hz >= spi_apb_clock/128) + { + SPI_InitStruct.BaudRatePres = SPI_BR_PRESCALER_128; + } + else + { + /* min prescaler 256 */ + SPI_InitStruct.BaudRatePres = SPI_BR_PRESCALER_256; + } + } /* baudrate */ + + switch(configuration->mode & RT_SPI_MODE_3) + { + case RT_SPI_MODE_0: + SPI_InitStruct.CLKPHA = SPI_CLKPHA_FIRST_EDGE; + SPI_InitStruct.CLKPOL = SPI_CLKPOL_LOW; + break; + case RT_SPI_MODE_1: + SPI_InitStruct.CLKPHA = SPI_CLKPHA_SECOND_EDGE; + SPI_InitStruct.CLKPOL = SPI_CLKPOL_LOW; + break; + case RT_SPI_MODE_2: + SPI_InitStruct.CLKPHA = SPI_CLKPHA_FIRST_EDGE; + SPI_InitStruct.CLKPOL = SPI_CLKPOL_HIGH; + break; + case RT_SPI_MODE_3: + SPI_InitStruct.CLKPHA = SPI_CLKPHA_SECOND_EDGE; + SPI_InitStruct.CLKPOL = SPI_CLKPOL_HIGH; + break; + } + + /* MSB or LSB */ + if(configuration->mode & RT_SPI_MSB) + { + SPI_InitStruct.FirstBit = SPI_FB_MSB; + } + else + { + SPI_InitStruct.FirstBit = SPI_FB_LSB; + } + + SPI_InitStruct.DataDirection = SPI_DIR_DOUBLELINE_FULLDUPLEX; + SPI_InitStruct.SpiMode = SPI_MODE_MASTER; + SPI_InitStruct.NSS = SPI_NSS_SOFT; + + /* init SPI */ + SPI_Init(spi_instance->config->spix, &SPI_InitStruct); + /* Enable SPI_MASTER */ + SPI_Enable(spi_instance->config->spix, ENABLE); + SPI_EnableCalculateCrc(spi_instance->config->spix, DISABLE); + + return RT_EOK; +}; + +static rt_uint32_t xfer(struct rt_spi_device* device, struct rt_spi_message* message) +{ + struct rt_spi_bus * at32_spi_bus = (struct rt_spi_bus *)device->bus; + struct n32_spi *spi_instance = (struct n32_spi *)at32_spi_bus->parent.user_data; + struct rt_spi_configuration * config = &device->config; + struct n32_spi_cs * at32_spi_cs = device->parent.user_data; + + RT_ASSERT(device != NULL); + RT_ASSERT(message != NULL); + + /* take CS */ + if(message->cs_take) + { + GPIO_ResetBits(at32_spi_cs->GPIOx, at32_spi_cs->GPIO_Pin); + 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 at32 lib + //Wait until the transmit buffer is empty + while(RESET == SPI_I2S_GetStatus(spi_instance->config->spix, SPI_I2S_TE_FLAG)); + // Send the byte + SPI_I2S_TransmitData(spi_instance->config->spix, data); + + //Wait until a data is received + while(RESET == SPI_I2S_GetStatus(spi_instance->config->spix, SPI_I2S_RNE_FLAG)); + // Get the received data + data = SPI_I2S_ReceiveData(spi_instance->config->spix); + + 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_GetStatus(spi_instance->config->spix, SPI_I2S_TE_FLAG)); + // Send the byte + SPI_I2S_TransmitData(spi_instance->config->spix, data); + + //Wait until a data is received + while(RESET == SPI_I2S_GetStatus(spi_instance->config->spix, SPI_I2S_RNE_FLAG)); + // Get the received data + data = SPI_I2S_ReceiveData(spi_instance->config->spix); + + if(recv_ptr != RT_NULL) + { + *recv_ptr++ = data; + } + } + } + } + + /* release CS */ + if(message->cs_release) + { + GPIO_SetBits(at32_spi_cs->GPIOx, at32_spi_cs->GPIO_Pin); + DEBUG_PRINTF("spi release cs\n"); + } + + return message->length; +}; + +static struct n32_spi_config configs[] = { +#ifdef BSP_USING_SPI1 + {SPI1, "spi1"}, +#endif + +#ifdef BSP_USING_SPI2 + {SPI2, "spi2"}, +#endif + +#ifdef BSP_USING_SPI3 + {SPI3, "spi3"}, +#endif + +#ifdef BSP_USING_SPI4 + {SPI4, "spi4"}, +#endif +}; + +static struct n32_spi spis[sizeof(configs) / sizeof(configs[0])] = {0}; + +/** \brief init and register at32 spi bus. + * + * \param SPI: at32 SPI, e.g: SPI1,SPI2,SPI3. + * \param spi_bus_name: spi bus name, e.g: "spi1" + * \return + * + */ +int rt_hw_spi_init(void) +{ + int i; + rt_err_t result; + rt_size_t obj_num = sizeof(spis) / sizeof(struct n32_spi); + + for (i = 0; i < obj_num; i++) + { + spis[i].config = &configs[i]; + spis[i].spi_bus.parent.user_data = (void *)&spis[i]; + result = rt_spi_bus_register(&(spis[i].spi_bus), spis[i].config->spi_name, &n32_spi_ops); + } + + return result; +} + +INIT_BOARD_EXPORT(rt_hw_spi_init); + +#endif diff --git a/bsp/n32g452xx/Libraries/rt_drivers/drv_spi.h b/bsp/n32g452xx/Libraries/rt_drivers/drv_spi.h new file mode 100755 index 0000000000..06ad293ecc --- /dev/null +++ b/bsp/n32g452xx/Libraries/rt_drivers/drv_spi.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-01-09 shelton first version + */ + +#ifndef __DRV_SPI__ +#define __DRV_SPI__ + +#include +#include +#include "n32g45x.h" + +struct n32_spi_config +{ + SPI_Module *spix; + const char *spi_name; +}; + +struct n32_spi +{ + struct n32_spi_config *config; + struct rt_spi_bus spi_bus; +}; + +struct n32_spi_cs +{ + GPIO_Module *GPIOx; + uint32_t GPIO_Pin; +}; + +/* public function */ +int rt_hw_spi_init(void); +rt_err_t rt_hw_spi_device_attach(const char *bus_name, const char *device_name, GPIO_Module *cs_gpiox, uint16_t cs_gpio_pin); + +#endif // __DRV_SPI__ + diff --git a/bsp/n32g452xx/Libraries/rt_drivers/drv_wdt.c b/bsp/n32g452xx/Libraries/rt_drivers/drv_wdt.c new file mode 100755 index 0000000000..0b304ad1ff --- /dev/null +++ b/bsp/n32g452xx/Libraries/rt_drivers/drv_wdt.c @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-01-22 shelton first version + */ + +#include +#include + +#ifdef RT_USING_WDT + +#define LSI_VALUE 40000 + +//#define DRV_DEBUG +#define LOG_TAG "drv.wdt" +#include + +struct at32_wdt_obj +{ + IWDG_Type *instance; + rt_uint32_t Prescaler; + rt_uint32_t Reload; + rt_uint16_t is_start; +}; +static struct at32_wdt_obj at32_wdt; +static struct rt_watchdog_ops ops; +static rt_watchdog_t watchdog; + +static rt_err_t wdt_init(rt_watchdog_t *wdt) +{ + return RT_EOK; +} + +static rt_err_t wdt_control(rt_watchdog_t *wdt, int cmd, void *arg) +{ + switch (cmd) + { + /* feed the watchdog */ + case RT_DEVICE_CTRL_WDT_KEEPALIVE: + IWDG_ReloadCounter(); + break; + /* set watchdog timeout */ + case RT_DEVICE_CTRL_WDT_SET_TIMEOUT: +#if defined(LSI_VALUE) + if(LSI_VALUE) + { + at32_wdt.Reload = (*((rt_uint32_t*)arg)) * LSI_VALUE / 256 ; + } + else + { + LOG_E("Please define the value of LSI_VALUE!"); + } + if(at32_wdt.Reload > 0xFFF) + { + LOG_E("wdg set timeout parameter too large, please less than %ds",0xFFF * 256 / LSI_VALUE); + return -RT_EINVAL; + } +#else + #error "Please define the value of LSI_VALUE!" +#endif + if(at32_wdt.is_start) + { + IWDG_KeyRegWrite(IWDG_KeyRegWrite_Enable); + IWDG_SetPrescaler(at32_wdt.Prescaler); + IWDG_SetReload(at32_wdt.Reload); + IWDG_KeyRegWrite(IWDG_KeyRegWrite_Disable); + IWDG_Enable(); + } + break; + case RT_DEVICE_CTRL_WDT_GET_TIMEOUT: +#if defined(LSI_VALUE) + if(LSI_VALUE) + { + (*((rt_uint32_t*)arg)) = at32_wdt.Reload * 256 / LSI_VALUE; + } + else + { + LOG_E("Please define the value of LSI_VALUE!"); + } +#else + #error "Please define the value of LSI_VALUE!" +#endif + break; + case RT_DEVICE_CTRL_WDT_START: + IWDG_KeyRegWrite(IWDG_KeyRegWrite_Enable); + IWDG_SetPrescaler(at32_wdt.Prescaler); + IWDG_SetReload(at32_wdt.Reload); + IWDG_KeyRegWrite(IWDG_KeyRegWrite_Disable); + IWDG_Enable(); + at32_wdt.is_start = 1; + break; + default: + LOG_W("This command is not supported."); + return -RT_ERROR; + } + return RT_EOK; +} + +int rt_hw_wdt_init(void) +{ + at32_wdt.instance = IWDG; + at32_wdt.Prescaler = IWDG_Psc_256; + at32_wdt.Reload = 0x00000FFF; + at32_wdt.is_start = 0; + + ops.init = &wdt_init; + ops.control = &wdt_control; + watchdog.ops = &ops; + /* register watchdog device */ + if (rt_hw_watchdog_register(&watchdog, "wdt", RT_DEVICE_FLAG_DEACTIVATE, RT_NULL) != RT_EOK) + { + LOG_E("wdt device register failed."); + return -RT_ERROR; + } + LOG_D("wdt device register success."); + return RT_EOK; +} +INIT_BOARD_EXPORT(rt_hw_wdt_init); + +#endif /* RT_USING_WDT */ diff --git a/bsp/n32g452xx/README.md b/bsp/n32g452xx/README.md new file mode 100755 index 0000000000..710ca97dd6 --- /dev/null +++ b/bsp/n32g452xx/README.md @@ -0,0 +1,3 @@ +# n32g452xx + +:) \ No newline at end of file diff --git a/bsp/n32g452xx/n32g452xx-mini-system/board/Kconfig b/bsp/n32g452xx/n32g452xx-mini-system/board/Kconfig index b5a93ccad2..495a4d537e 100755 --- a/bsp/n32g452xx/n32g452xx-mini-system/board/Kconfig +++ b/bsp/n32g452xx/n32g452xx-mini-system/board/Kconfig @@ -23,7 +23,7 @@ menu "On-chip Peripheral Drivers" select RT_USING_PIN default y - config RT_USING_ON_CHIP_FLASH + config BSP_USING_ON_CHIP_FLASH bool "Enable on-chip FLASH" default n @@ -44,6 +44,120 @@ menu "On-chip Peripheral Drivers" bool "Enable UART3" default n endif + + menuconfig BSP_USING_PWM + bool "Enable PWM" + default n + select RT_USING_PWM + if BSP_USING_PWM + menuconfig BSP_USING_TIM1 + bool "Enable timer1 output PWM" + default n + if BSP_USING_TIM1 + config BSP_USING_TIM1_CH1 + bool "Enable TIM1 channel1 PWM" + default n + + config BSP_USING_TIM1_CH4 + bool "Enable TIM1 channel4 PWM" + default n + endif + menuconfig BSP_USING_TIM2 + bool "Enable timer2 output PWM" + default n + if BSP_USING_TIM2 + config BSP_USING_TIM2_CH1 + bool "Enable TIM2 channel1 PWM" + default n + + config BSP_USING_TIM2_CH2 + bool "Enable TIM2 channel2 PWM" + default n + endif + endif + + menuconfig BSP_USING_HWTIMER + bool "Enable HWTIMER" + default n + select RT_USING_HWTIMER + if BSP_USING_HWTIMER + config BSP_USING_HWTIM3 + bool "Enable hardware timer3" + default n + config BSP_USING_HWTIM4 + bool "Enable hardware timer4" + default n + config BSP_USING_HWTIM5 + bool "Enable hardware timer5" + default n + 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_USING_SPI2 + bool "Enable SPI2 BUS" + default n + endif + + menuconfig BSP_USING_I2C1 + bool "Enable I2C1 BUS (software simulation)" + default n + select RT_USING_I2C + select RT_USING_I2C_BITOPS + select RT_USING_PIN + if BSP_USING_I2C1 + config BSP_I2C1_SCL_PIN + int "i2c1 scl pin number" + range 0 63 + default 22 + config BSP_I2C1_SDA_PIN + int "I2C1 sda pin number" + range 0 63 + default 23 + endif + + menuconfig BSP_USING_ADC + bool "Enable ADC" + default n + select RT_USING_ADC + if BSP_USING_ADC + config BSP_USING_ADC1 + bool "Enable ADC1" + default n + config BSP_USING_ADC2 + bool "Enable ADC2" + default n + endif + + menuconfig BSP_USING_CAN + bool "Enable CAN" + default n + select RT_USING_CAN + if BSP_USING_CAN + config BSP_USING_CAN1 + bool "using CAN1" + default n + config BSP_USING_CAN2 + bool "using CAN2" + default n + endif + + menuconfig BSP_USING_SDIO + bool "Enable SDIO" + default n + select RT_USING_SDIO + if BSP_USING_SDIO + config BSP_USING_SDIO1 + bool "Enable SDIO1" + default n + endif endmenu endmenu diff --git a/bsp/n32g452xx/n32g452xx-mini-system/board/SConscript b/bsp/n32g452xx/n32g452xx-mini-system/board/SConscript index 1f250e42ba..5c446528c0 100755 --- a/bsp/n32g452xx/n32g452xx-mini-system/board/SConscript +++ b/bsp/n32g452xx/n32g452xx-mini-system/board/SConscript @@ -9,9 +9,11 @@ cwd = GetCurrentDir() # add general drivers src = Split(''' board.c +msp/n32_msp.c ''') path = [cwd] +path += [cwd + '/msp'] startup_path_prefix = SDK_LIB diff --git a/bsp/n32g452xx/n32g452xx-mini-system/board/board.c b/bsp/n32g452xx/n32g452xx-mini-system/board/board.c index 7b293d2ba7..472768a1af 100755 --- a/bsp/n32g452xx/n32g452xx-mini-system/board/board.c +++ b/bsp/n32g452xx/n32g452xx-mini-system/board/board.c @@ -5,13 +5,18 @@ * * Change Logs: * Date Author Notes - * 2009-01-05 Bernard first implementation + * 2018-11-06 balanceTWK first version */ + #include #include #include + #include +#ifdef BSP_USING_SRAM +#include "drv_sram.h" +#endif /** * @brief This function is executed in case of error occurrence. * @param None @@ -51,9 +56,9 @@ void SysTick_Handler(void) } /** - * This function will initial N32 board. + * This function will initial AT32 board. */ -void rt_hw_board_init(void) +void rt_hw_board_init() { /* NVIC Configuration */ #define NVIC_VTOR_MASK 0x3FFFFF80 @@ -75,9 +80,9 @@ void rt_hw_board_init(void) rt_console_set_device(RT_CONSOLE_DEVICE_NAME); #endif -#ifdef RT_USING_HEAP - rt_system_heap_init((void*)HEAP_BEGIN, (void*)HEAP_END); +#ifdef BSP_USING_SRAM + rt_system_heap_init((void *)EXT_SRAM_BEGIN, (void *)EXT_SRAM_END); +#else + rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END); #endif } - -/*@}*/ diff --git a/bsp/n32g452xx/n32g452xx-mini-system/board/board.h b/bsp/n32g452xx/n32g452xx-mini-system/board/board.h index 4094156aba..c27d7cb87d 100755 --- a/bsp/n32g452xx/n32g452xx-mini-system/board/board.h +++ b/bsp/n32g452xx/n32g452xx-mini-system/board/board.h @@ -5,41 +5,45 @@ * * Change Logs: * Date Author Notes - * 2009-09-22 Bernard add board.h to this bsp + * 2020-01-15 shelton first version + * 2021-02-09 shelton add flash macros */ -// <<< Use Configuration Wizard in Context Menu >>> #ifndef __BOARD_H__ #define __BOARD_H__ #include +#include "n32_msp.h" -// Internal SRAM memory size[Kbytes] -// Default: 80 -#ifdef __ICCARM__ -// Use *.icf ram symbal, to avoid hardcode. -extern char __ICFEDIT_region_RAM_end__; -#define N32_SRAM_END &__ICFEDIT_region_RAM_end__ -#else -#define N32_SRAM_SIZE 80 -#define N32_SRAM_END (0x20000000 + N32_SRAM_SIZE * 1024) +#ifdef __cplusplus +extern "C" { #endif -#ifdef __CC_ARM +/* Just only support for AT32F40xxG */ +#define N32_FLASH_START_ADRESS ((uint32_t)0x08000000) +#define FLASH_PAGE_SIZE (2 * 1024) +#define N32_FLASH_SIZE (256 * 1024) +#define N32_FLASH_END_ADDRESS ((uint32_t)(N32_FLASH_START_ADRESS + N32_FLASH_SIZE)) + +/* Internal SRAM memory size[Kbytes] <80>, Default: 80*/ +#define N32_SRAM_SIZE (80) +#define N32_SRAM_END (0x20000000 + N32_SRAM_SIZE * 1024) + +#if defined(__CC_ARM) || defined(__CLANG_ARM) extern int Image$$RW_IRAM1$$ZI$$Limit; -#define HEAP_BEGIN (&Image$$RW_IRAM1$$ZI$$Limit) +#define HEAP_BEGIN ((void *)&Image$$RW_IRAM1$$ZI$$Limit) #elif __ICCARM__ -#pragma section="HEAP" -#define HEAP_BEGIN (__segment_end("HEAP")) +#pragma section="CSTACK" +#define HEAP_BEGIN (__segment_end("CSTACK")) #else extern int __bss_end; -#define HEAP_BEGIN (&__bss_end) +#define HEAP_BEGIN ((void *)&__bss_end) #endif -#define HEAP_END N32_SRAM_END - -void rt_hw_board_init(void); +#define HEAP_END N32_SRAM_END +#ifdef __cplusplus +} #endif -//*** <<< end of configuration section >>> *** +#endif /* __BOARD_H__ */ diff --git a/bsp/n32g452xx/n32g452xx-mini-system/board/msp/n32_msp.c b/bsp/n32g452xx/n32g452xx-mini-system/board/msp/n32_msp.c new file mode 100755 index 0000000000..d7c2cae387 --- /dev/null +++ b/bsp/n32g452xx/n32g452xx-mini-system/board/msp/n32_msp.c @@ -0,0 +1,295 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-04-13 shelton first version + */ + + +#include +#include "n32g45x.h" +#include "n32_msp.h" + +#ifdef BSP_USING_UART +void n32_msp_usart_init(void *Instance) +{ + GPIO_InitType GPIO_InitCtlStruct; + USART_Module *USARTx = (USART_Module *)Instance; + + GPIO_InitStruct(&GPIO_InitCtlStruct); + GPIO_InitCtlStruct.GPIO_Speed = GPIO_Speed_50MHz; +#ifdef BSP_USING_UART1 + if(USART1 == USARTx) + { + RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_USART1, ENABLE); + RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA, ENABLE); + GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_AF_PP; + GPIO_InitCtlStruct.Pin = GPIO_PIN_9; + GPIO_InitPeripheral(GPIOA, &GPIO_InitCtlStruct); + + GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; + GPIO_InitCtlStruct.Pin = GPIO_PIN_10; + GPIO_InitPeripheral(GPIOA, &GPIO_InitCtlStruct); + } +#endif +#ifdef BSP_USING_UART2 + if(USART2 == USARTx) + { + RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_USART2, ENABLE); + RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA, ENABLE); + GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_AF_PP; + GPIO_InitCtlStruct.Pin = GPIO_PIN_2; + GPIO_InitPeripheral(GPIOA, &GPIO_InitCtlStruct); + + GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; + GPIO_InitCtlStruct.Pin = GPIO_PIN_3; + GPIO_InitPeripheral(GPIOA, &GPIO_InitCtlStruct); + } +#endif +#ifdef BSP_USING_UART3 + if(USART3 == USARTx) + { + RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_USART3, ENABLE); + RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOB, ENABLE); + GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_AF_PP; + GPIO_InitCtlStruct.Pin = GPIO_PIN_10; + GPIO_InitPeripheral(GPIOB, &GPIO_InitCtlStruct); + + GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; + GPIO_InitCtlStruct.Pin = GPIO_PIN_11; + GPIO_InitPeripheral(GPIOB, &GPIO_InitCtlStruct); + } +#endif + /* Add others */ +} +#endif /* BSP_USING_SERIAL */ + +#ifdef BSP_USING_SPI +void n32_msp_spi_init(void *Instance) +{ + GPIO_InitType GPIO_InitCtlStruct; + SPI_Module *SPIx = (SPI_Module *)Instance; + + GPIO_InitStruct(&GPIO_InitCtlStruct); + GPIO_InitCtlStruct.GPIO_Speed = GPIO_Speed_50MHz; +#ifdef BSP_USING_SPI1 + if(SPI1 == SPIx) + { + RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_SPI1, ENABLE); + RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA, ENABLE); + + GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_Out_PP; + GPIO_InitCtlStruct.Pin = GPIO_PIN_4; + GPIO_InitPeripheral(GPIOA, &GPIO_InitCtlStruct); + GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_AF_PP; + GPIO_InitCtlStruct.Pin = GPIO_PIN_5 | GPIO_PIN_7; + GPIO_InitPeripheral(GPIOA, &GPIO_InitCtlStruct); + GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; + GPIO_InitCtlStruct.Pin = GPIO_PIN_6; + GPIO_InitPeripheral(GPIOA, &GPIO_InitCtlStruct); + } +#endif +#ifdef BSP_USING_SPI2 + if(SPI2 == SPIx) + { + RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_SPI2, ENABLE); + RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOB, ENABLE); + + GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_Out_PP; + GPIO_InitCtlStruct.Pin = GPIO_PIN_12; + GPIO_InitPeripheral(GPIOB, &GPIO_InitCtlStruct); + GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_AF_PP; + GPIO_InitCtlStruct.Pin = GPIO_PIN_13 | GPIO_PIN_15; + GPIO_InitPeripheral(GPIOB, &GPIO_InitCtlStruct); + GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; + GPIO_InitCtlStruct.Pin = GPIO_PIN_14; + GPIO_InitPeripheral(GPIOB, &GPIO_InitCtlStruct); + } +#endif + /* Add others */ +} +#endif /* BSP_USING_SPI */ + +#ifdef BSP_USING_SDIO +void n32_msp_sdio_init(void *Instance) +{ + GPIO_InitType GPIO_InitCtlStructure; + SDIO_Module *SDIOx = (SDIO_Module *)Instance; + + GPIO_InitStruct(&GPIO_InitCtlStructure); + GPIO_InitCtlStructure.GPIO_Speed = GPIO_Speed_50MHz; + + if(SDIO == SDIOx) + { + /* if used dma ... */ + RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_DMA2, ENABLE); + + RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_SDIO, ENABLE); + RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOC | RCC_APB2_PERIPH_GPIOD, ENABLE); + GPIO_InitCtlStructure.Pin = GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12; + GPIO_InitCtlStructure.GPIO_Mode = GPIO_Mode_AF_PP; + GPIO_InitPeripheral(GPIOC, &GPIO_InitCtlStructure); + + GPIO_InitCtlStructure.Pin = GPIO_PIN_2; + GPIO_InitCtlStructure.GPIO_Mode = GPIO_Mode_AF_PP; + GPIO_InitPeripheral(GPIOD, &GPIO_InitCtlStructure); + } +} +#endif /* BSP_USING_SDIO */ + +#ifdef BSP_USING_PWM +void n32_msp_tmr_init(void *Instance) +{ + GPIO_InitType GPIO_InitCtlStructure; + GPIO_InitStruct(&GPIO_InitCtlStructure); + TIM_Module *TIMx = (TIM_Module *)Instance; + + if(TIMx == TIM1) + { + /* TIM1 clock enable */ + RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_TIM1, ENABLE); + /* GPIOA clock enable */ + RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA, ENABLE); + + /* GPIOA Configuration:TIM1 Channel1 and Channel4 as alternate function push-pull */ + GPIO_InitCtlStructure.Pin = GPIO_PIN_8 | GPIO_PIN_11; + GPIO_InitCtlStructure.GPIO_Mode = GPIO_Mode_AF_PP; + GPIO_InitCtlStructure.GPIO_Speed = GPIO_Speed_50MHz; + + GPIO_InitPeripheral(GPIOA, &GPIO_InitCtlStructure); + } + + if(TIMx == TIM2) + { + /* TIM2 clock enable */ + RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_TIM2, ENABLE); + /* GPIOA clock enable */ + RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA, ENABLE); + + /* GPIOA Configuration:TIM2 Channel1 and Channel2 as alternate function push-pull */ + GPIO_InitCtlStructure.Pin = GPIO_PIN_0 | GPIO_PIN_1; + GPIO_InitCtlStructure.GPIO_Mode = GPIO_Mode_AF_PP; + GPIO_InitCtlStructure.GPIO_Speed = GPIO_Speed_50MHz; + + GPIO_InitPeripheral(GPIOA, &GPIO_InitCtlStructure); + } + /* Add others */ +} +#endif /* BSP_USING_PWM */ + +#ifdef BSP_USING_ADC +void n32_msp_adc_init(void *Instance) +{ + GPIO_InitType GPIO_InitCtlStruct; + GPIO_InitStruct(&GPIO_InitCtlStruct); + ADC_Module *ADCx = (ADC_Module *)Instance; + +#ifdef BSP_USING_ADC1 + if(ADCx == ADC1) + { + /* ADC1 & GPIO clock enable */ + RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_ADC1, ENABLE); + ADC_ConfigClk(ADC_CTRL3_CKMOD_AHB,RCC_ADCHCLK_DIV8); + RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOC, ENABLE); + + /* Configure ADC Channel as analog input */ + GPIO_InitCtlStruct.Pin = GPIO_PIN_0; + GPIO_InitCtlStruct.GPIO_Speed = GPIO_Speed_2MHz; + GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_AIN; + GPIO_InitPeripheral(GPIOC, &GPIO_InitCtlStruct); + } +#endif + +#ifdef BSP_USING_ADC2 + if(ADCx == ADC2) + { + /* ADC2 & GPIO clock enable */ + RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_ADC2, ENABLE); + ADC_ConfigClk(ADC_CTRL3_CKMOD_AHB,RCC_ADCHCLK_DIV8); + RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOC, ENABLE); + + /* Configure ADC Channel as analog input */ + GPIO_InitCtlStruct.Pin = GPIO_PIN_1; + GPIO_InitCtlStruct.GPIO_Speed = GPIO_Speed_2MHz; + GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_AIN; + GPIO_InitPeripheral(GPIOC, &GPIO_InitCtlStruct); + } +#endif +} +#endif /* BSP_USING_ADC */ + +#ifdef BSP_USING_HWTIMER +void n32_msp_hwtmr_init(void *Instance) +{ + TIM_Module *TIMx = (TIM_Module *)Instance; + +#ifdef BSP_USING_HWTIM3 + if(TIMx == TIM3) + { + /* TIM3 clock enable */ + RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_TIM3, ENABLE); + } +#endif + +#ifdef BSP_USING_HWTIM4 + if(TIMx == TIM4) + { + /* TIM4 clock enable */ + RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_TIM4, ENABLE); + } +#endif + +#ifdef BSP_USING_HWTIM5 + if(TIMx == TIM5) + { + /* TIM5 clock enable */ + RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_TIM5, ENABLE); + } +#endif +} +#endif + +#ifdef BSP_USING_CAN +void n32_msp_can_init(void *Instance) +{ + GPIO_InitType GPIO_InitCtlStruct; + CAN_Module *CANx = (CAN_Module *)Instance; + + GPIO_InitStruct(&GPIO_InitCtlStruct); + GPIO_InitCtlStruct.GPIO_Speed = GPIO_Speed_50MHz; +#ifdef BSP_USING_CAN1 + if(CAN1 == CANx) + { + RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_CAN1, ENABLE); + RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA, ENABLE); + GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_AF_PP; + GPIO_InitCtlStruct.Pin = GPIO_PIN_12; + GPIO_InitPeripheral(GPIOA, &GPIO_InitCtlStruct); + + GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; + GPIO_InitCtlStruct.Pin = GPIO_PIN_11; + GPIO_InitPeripheral(GPIOA, &GPIO_InitCtlStruct); + } +#endif +#ifdef BSP_USING_CAN2 + if(CAN2 == CANx) + { + RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_CAN2, ENABLE); + RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_AFIO, ENABLE); + RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOB, ENABLE); +// GPIO_PinsRemapConfig(AFIO_MAP6_CAN2_0001, ENABLE); + GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_AF_PP; + GPIO_InitCtlStruct.Pin = GPIO_PIN_6; + GPIO_InitPeripheral(GPIOB, &GPIO_InitCtlStruct); + + GPIO_InitCtlStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; + GPIO_InitCtlStruct.Pin = GPIO_PIN_5; + GPIO_InitPeripheral(GPIOB, &GPIO_InitCtlStruct); + } +#endif +} +#endif /* BSP_USING_CAN */ + diff --git a/bsp/n32g452xx/n32g452xx-mini-system/board/msp/n32_msp.h b/bsp/n32g452xx/n32g452xx-mini-system/board/msp/n32_msp.h new file mode 100755 index 0000000000..93e923c5a6 --- /dev/null +++ b/bsp/n32g452xx/n32g452xx-mini-system/board/msp/n32_msp.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-04-13 shelton first version + */ + +#ifndef __N32_MSP_H__ +#define __N32_MSP_H__ + +void n32_msp_usart_init(void *Instance); +void n32_msp_spi_init(void *Instance); +void n32_msp_tmr_init(void *Instance); +void n32_msp_sdio_init(void *Instance); +void n32_msp_adc_init(void *Instance); +void n32_msp_hwtmr_init(void *Instance); +void n32_msp_can_init(void *Instance); + +#endif /* __N32_MSP_H__ */ + diff --git a/bsp/n32g452xx/n32g452xx-mini-system/rtconfig.h b/bsp/n32g452xx/n32g452xx-mini-system/rtconfig.h index 79ee4ee83a..4337202359 100755 --- a/bsp/n32g452xx/n32g452xx-mini-system/rtconfig.h +++ b/bsp/n32g452xx/n32g452xx-mini-system/rtconfig.h @@ -88,7 +88,11 @@ #define RT_USING_SERIAL_V1 #define RT_SERIAL_USING_DMA #define RT_SERIAL_RB_BUFSZ 64 +#define RT_USING_I2C +#define RT_USING_I2C_BITOPS #define RT_USING_PIN +#define RT_USING_ADC +#define RT_USING_SPI /* Using USB */ @@ -97,7 +101,7 @@ #define RT_USING_LIBC #define RT_USING_POSIX -#define RT_LIBC_FIXED_TIMEZONE 8 +#define RT_LIBC_DEFAULT_TIMEZONE 8 /* Network */ @@ -182,7 +186,19 @@ /* On-chip Peripheral Drivers */ #define RT_USING_GPIO +#define BSP_USING_ON_CHIP_FLASH #define RT_USING_UART #define RT_USING_UART1 +#define RT_USING_UART2 +#define RT_USING_UART3 +#define BSP_USING_SPI +#define BSP_USING_SPI1 +#define BSP_USING_SPI2 +#define BSP_USING_I2C1 +#define BSP_I2C1_SCL_PIN 22 +#define BSP_I2C1_SDA_PIN 23 +#define BSP_USING_ADC +#define BSP_USING_ADC1 +#define BSP_USING_ADC2 #endif