From f1ba61e4136280435f8ff957e430e32e8ce8769f Mon Sep 17 00:00:00 2001 From: wangyq2018 Date: Tue, 19 Mar 2019 11:38:08 +0800 Subject: [PATCH] [bsp/es32f0334] add spi/i2c/pwm drivers --- bsp/es32f0334/.config | 21 ++ bsp/es32f0334/README.md | 10 +- bsp/es32f0334/drivers/Kconfig | 54 +++++ bsp/es32f0334/drivers/SConscript | 16 ++ bsp/es32f0334/drivers/board.c | 31 ++- bsp/es32f0334/drivers/drv_gpio.c | 8 +- bsp/es32f0334/drivers/drv_i2c.c | 141 +++++++++++++ bsp/es32f0334/drivers/drv_i2c.h | 16 ++ bsp/es32f0334/drivers/drv_pwm.c | 211 +++++++++++++++++++ bsp/es32f0334/drivers/drv_pwm.h | 16 ++ bsp/es32f0334/drivers/drv_spi.c | 297 +++++++++++++++++++++++++++ bsp/es32f0334/drivers/drv_spi.h | 27 +++ bsp/es32f0334/drivers/drv_spiflash.c | 31 +++ bsp/es32f0334/drivers/drv_spiflash.h | 16 ++ bsp/es32f0334/drivers/drv_uart.c | 13 +- bsp/es32f0334/project.uvoptx | 9 +- bsp/es32f0334/project.uvprojx | 2 +- bsp/es32f0334/rtconfig.h | 10 + bsp/es32f0334/template.uvoptx | 9 +- 19 files changed, 906 insertions(+), 32 deletions(-) create mode 100644 bsp/es32f0334/drivers/drv_i2c.c create mode 100644 bsp/es32f0334/drivers/drv_i2c.h create mode 100644 bsp/es32f0334/drivers/drv_pwm.c create mode 100644 bsp/es32f0334/drivers/drv_pwm.h create mode 100644 bsp/es32f0334/drivers/drv_spi.c create mode 100644 bsp/es32f0334/drivers/drv_spi.h create mode 100644 bsp/es32f0334/drivers/drv_spiflash.c create mode 100644 bsp/es32f0334/drivers/drv_spiflash.h diff --git a/bsp/es32f0334/.config b/bsp/es32f0334/.config index aeccdd7e22..b49063d9fc 100644 --- a/bsp/es32f0334/.config +++ b/bsp/es32f0334/.config @@ -324,9 +324,30 @@ CONFIG_BSP_USING_GPIO=y # CONFIG_BSP_USING_UART0 is not set CONFIG_BSP_USING_UART1=y +# +# SPI Drivers +# +# CONFIG_BSP_USING_SPI0 is not set +# CONFIG_BSP_USING_SPI1 is not set + +# +# I2C Drivers +# +# CONFIG_BSP_USING_I2C0 is not set +# CONFIG_BSP_USING_I2C1 is not set + +# +# PWM Drivers +# +# CONFIG_BSP_USING_PWM0 is not set +# CONFIG_BSP_USING_PWM1 is not set +# CONFIG_BSP_USING_PWM2 is not set +# CONFIG_BSP_USING_PWM3 is not set + # # Onboard Peripheral Drivers # +# CONFIG_BSP_USING_SPI_FLASH is not set # # Offboard Peripheral Drivers diff --git a/bsp/es32f0334/README.md b/bsp/es32f0334/README.md index 91564e62e2..ba41b0ef96 100644 --- a/bsp/es32f0334/README.md +++ b/bsp/es32f0334/README.md @@ -20,7 +20,7 @@ ES-PDS-ES32F0334-V1.1 该开发板常用 **板载资源** 如下: - MCU:ES32F0334LT,主频 48MHz,32KB SRAM,256KB FLASH,54 GPIOs -- 外部 FLASH:MX25L64(SPI,16MB)、EEPROM(24c04) +- 外部模块:SPI FLASH (MX25L64,8MB)、I2C EEPROM (M24C04,512B) - 常用外设 - LED:2个,(PA12/PC12) - 液晶屏:1个 @@ -35,13 +35,13 @@ ES-PDS-ES32F0334-V1.1 | **板载外设** | **支持情况** | **备注** | | :---------------- | :----------: | :------------------------------------| - +| SPI FLASH | 支持 | SPI0 | | **片上外设** | **支持情况** | **备注** | -| :---------------- | :----------: | :------------------------------------| | GPIO | 支持 | 54 GPIOs | | UART | 支持 | UART0/1 | - -| **扩展模块** | **支持情况** | **备注** | +| SPI | 支持 | SPI0/1 | +| I2C | 支持 | I2C0/1 | +| PWM | 支持 | PWM0/1/2/3 | 更多详细信息请咨询[上海东软载波微电子技术支持](http://www.essemi.com/) diff --git a/bsp/es32f0334/drivers/Kconfig b/bsp/es32f0334/drivers/Kconfig index 57a1530ef5..68ac89c998 100644 --- a/bsp/es32f0334/drivers/Kconfig +++ b/bsp/es32f0334/drivers/Kconfig @@ -19,10 +19,64 @@ menu "Hardware Drivers Config" endmenu + menu "SPI Drivers" + config BSP_USING_SPI0 + bool "Enable SPI0 BUS PB03/PB04/PB05(CLK/MISO/MOSI)" + select RT_USING_SPI + select RT_USING_PIN + default n + + config BSP_USING_SPI1 + bool "Enable SPI1 BUS PB13/PB14/PB15(CLK/MISO/MOSI)" + select RT_USING_SPI + select RT_USING_PIN + default n + endmenu + + menu "I2C Drivers" + config BSP_USING_I2C0 + bool "Enable I2C0 BUS PB08/PB09(SCL/SDA)" + select RT_USING_I2C + default n + config BSP_USING_I2C1 + bool "Enable I2C1 BUS PB10/PB11(SCL/SDA)" + select RT_USING_I2C + default n + endmenu + + menu "PWM Drivers" + config BSP_USING_PWM0 + bool "Using PWM0 PA08/PA09/PA10/PA11" + select RT_USING_PWM + default n + + config BSP_USING_PWM1 + bool "Using PWM1 PB06/PB07/PB08" + select RT_USING_PWM + default n + + config BSP_USING_PWM2 + bool "Using PWM2 PA00/PA01" + select RT_USING_PWM + default n + + config BSP_USING_PWM3 + bool "Using PWM3 PC06/PC07" + select RT_USING_PWM + default n + endmenu endmenu menu "Onboard Peripheral Drivers" + config BSP_USING_SPI_FLASH + bool "Enable SPI FLASH (W25Q64 spi0)" + select BSP_USING_SPI + select BSP_USING_SPI0 + select RT_USING_SFUD + select RT_SFUD_USING_SFDP + default n + endmenu menu "Offboard Peripheral Drivers" diff --git a/bsp/es32f0334/drivers/SConscript b/bsp/es32f0334/drivers/SConscript index 8581708e57..a52e6f193d 100644 --- a/bsp/es32f0334/drivers/SConscript +++ b/bsp/es32f0334/drivers/SConscript @@ -15,6 +15,22 @@ if GetDepend('RT_USING_PIN'): if GetDepend('BSP_USING_UART0') or GetDepend('BSP_USING_UART1'): src += ['drv_uart.c'] +# add spi driver code +if GetDepend('BSP_USING_SPI0') or GetDepend('BSP_USING_SPI1'): + src += ['drv_spi.c'] + +# add i2c driver code +if GetDepend('BSP_USING_I2C0') or GetDepend('BSP_USING_I2C1'): + src += ['drv_i2c.c'] + +# add spi flash driver code +if GetDepend('BSP_USING_SPI_FLASH'): + src += ['drv_spiflash.c'] + +# add pwm driver code +if GetDepend('BSP_USING_PWM0') or GetDepend('BSP_USING_PWM1') or GetDepend('BSP_USING_PWM2') or GetDepend('BSP_USING_PWM3'): + src += ['drv_pwm.c'] + CPPPATH = [cwd] group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH) diff --git a/bsp/es32f0334/drivers/board.c b/bsp/es32f0334/drivers/board.c index 0366c570c3..21fd401315 100644 --- a/bsp/es32f0334/drivers/board.c +++ b/bsp/es32f0334/drivers/board.c @@ -45,7 +45,7 @@ void SystemClock_Config(void) /* hosc 12MHz, from hosc/3 pll to 48MHz */ cmu_pll1_config(CMU_PLL1_INPUT_HOSC_3, CMU_PLL1_OUTPUT_48M); - /* MCLK 48MHz*/ + /* MCLK 48MHz */ cmu_clock_config(CMU_CLOCK_PLL1, 48000000); } @@ -58,14 +58,8 @@ void SystemClock_Config(void) *******************************************************************************/ void SysTick_Configuration(void) { - rt_uint32_t _mclk; - rt_uint32_t _sys_div = READ_BITS(CMU->CFGR, CMU_CFGR_SYSDIV_MSK, CMU_CFGR_SYSDIV_POSS); - - /* get hrc clock*/ - _mclk = cmu_get_clock(); - - /* SYSCLK = MCLK/SYSDIV */ - SysTick_Config(_mclk / (RT_TICK_PER_SECOND << _sys_div)); + /* ticks = sysclk / RT_TICK_PER_SECOND */ + SysTick_Config(cmu_get_sys_clock() / RT_TICK_PER_SECOND); } /** @@ -108,3 +102,22 @@ void rt_hw_board_init(void) rt_console_set_device(RT_CONSOLE_DEVICE_NAME); #endif } + +/** + * This function will delay for some us. + * + * @param us the delay time of us + */ +void rt_hw_us_delay(rt_uint32_t us) +{ + unsigned int start, now, delta, reload, us_tick; + start = SysTick->VAL; + reload = SysTick->LOAD; + us_tick = cmu_get_sys_clock() / 1000000UL; + do + { + now = SysTick->VAL; + delta = start > now ? start - now : reload + start - now; + } + while (delta < us_tick * us); +} diff --git a/bsp/es32f0334/drivers/drv_gpio.c b/bsp/es32f0334/drivers/drv_gpio.c index bfff6c7de9..9e3a9fa274 100644 --- a/bsp/es32f0334/drivers/drv_gpio.c +++ b/bsp/es32f0334/drivers/drv_gpio.c @@ -257,7 +257,7 @@ rt_err_t es32f0_pin_attach_irq(struct rt_device *device, rt_int32_t pin, { return RT_ENOSYS; } - /**pin no. convert to dec no.**/ + /* pin no. convert to dec no. */ for (irqindex = 0; irqindex < 16; irqindex++) { if ((0x01 << irqindex) == index->pin) @@ -327,7 +327,7 @@ rt_err_t es32f0_pin_irq_enable(struct rt_device *device, rt_base_t pin, const struct pin_irq_map *irqmap; rt_base_t level; rt_int32_t irqindex = -1; - /*Configure GPIO_InitStructure & EXTI_InitStructure*/ + /* Configure GPIO_InitStructure & EXTI_InitStructure */ gpio_init_t gpio_initstruct; exti_init_t exti_initstruct; exti_initstruct.filter = DISABLE; @@ -341,7 +341,7 @@ rt_err_t es32f0_pin_irq_enable(struct rt_device *device, rt_base_t pin, } if (enabled == PIN_IRQ_ENABLE) { - /**pin no. convert to dec no.**/ + /* pin no. convert to dec no. */ for (irqindex = 0; irqindex < 16; irqindex++) { if ((0x01 << irqindex) == index->pin) @@ -421,7 +421,7 @@ INIT_BOARD_EXPORT(rt_hw_pin_init); rt_inline void pin_irq_hdr(uint16_t GPIO_Pin) { uint16_t irqno; - /**pin no. convert to dec no.**/ + /* pin no. convert to dec no. */ for (irqno = 0; irqno < 16; irqno++) { if ((0x01 << irqno) == GPIO_Pin) diff --git a/bsp/es32f0334/drivers/drv_i2c.c b/bsp/es32f0334/drivers/drv_i2c.c new file mode 100644 index 0000000000..9d3a3c0a3f --- /dev/null +++ b/bsp/es32f0334/drivers/drv_i2c.c @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-03-19 wangyq the first version + */ + +#include +#include +#include +#include "board.h" +#include "drv_i2c.h" +#include +#include + +#ifdef RT_USING_I2C + +#define TIMEOUT 0x0FFF +/* I2C struct definition */ +static i2c_handle_t _h_i2c0, _h_i2c1; + +static void _i2c_init(void) +{ + gpio_init_t gpio_instruct; + + /* Initialize I2C Pin */ + gpio_instruct.mode = GPIO_MODE_OUTPUT; + gpio_instruct.odos = GPIO_PUSH_PULL; + gpio_instruct.pupd = GPIO_PUSH_UP; + gpio_instruct.odrv = GPIO_OUT_DRIVE_NORMAL; + gpio_instruct.flt = GPIO_FILTER_DISABLE; + gpio_instruct.type = GPIO_TYPE_CMOS; + gpio_instruct.func = GPIO_FUNC_5; + +#ifdef BSP_USING_I2C0 + /* Initialize I2C Function */ + _h_i2c0.perh = I2C0; + _h_i2c0.init.clk_speed = 100000; + _h_i2c0.init.duty = I2C_DUTYCYCLE_2; + _h_i2c0.init.own_addr1 = 0x0A; + _h_i2c0.init.addr_mode = I2C_ADDR_7BIT; + _h_i2c0.init.general_call = I2C_GENERALCALL_DISABLE; + _h_i2c0.init.no_stretch = I2C_NOSTRETCH_ENABLE; + + i2c_reset(&_h_i2c0); + i2c_init(&_h_i2c0); + /* I2C0_SCL->PB8, I2C0_SDA->PB9 */ + gpio_init(GPIOB, GPIO_PIN_8 | GPIO_PIN_9, &gpio_instruct); +#endif + +#ifdef BSP_USING_I2C1 + /* Initialize i2c function */ + _h_i2c1.perh = I2C1; + _h_i2c1.init.clk_speed = 100000; + _h_i2c1.init.duty = I2C_DUTYCYCLE_2; + _h_i2c1.init.own_addr1 = 0xA0; + _h_i2c1.init.addr_mode = I2C_ADDR_7BIT; + _h_i2c1.init.general_call = I2C_GENERALCALL_DISABLE; + _h_i2c1.init.no_stretch = I2C_NOSTRETCH_ENABLE; + + i2c_reset(&_h_i2c1); + i2c_init(&_h_i2c1); + /* I2C1_SCL->PB10, I2C1_SDA->PB11 */ + gpio_init(GPIOB, GPIO_PIN_10 | GPIO_PIN_11, &gpio_instruct); +#endif +} + +static rt_size_t es32f0_master_xfer(struct rt_i2c_bus_device *bus, + struct rt_i2c_msg msgs[], + rt_uint32_t num) +{ + struct rt_i2c_msg *msg; + rt_uint32_t i; + rt_err_t ret = RT_ERROR; + + for (i = 0; i < num; i++) + { + msg = &msgs[i]; + if (msg->flags & RT_I2C_RD) + { + if (i2c_master_recv(bus->priv, msg->addr << 1, msg->buf, msg->len, TIMEOUT) != 0) + { + i2c_dbg("i2c bus write failed,i2c bus stop!\n"); + goto out; + } + } + else + { + if (i2c_master_send(bus->priv, msg->addr << 1, msg->buf, msg->len, TIMEOUT) != 0) + { + i2c_dbg("i2c bus write failed,i2c bus stop!\n"); + goto out; + } + } + } + + ret = i; + +out: + i2c_dbg("send stop condition\n"); + + return ret; +} + +const struct rt_i2c_bus_device_ops es32f0_i2c_ops = +{ + es32f0_master_xfer, + RT_NULL, + RT_NULL, +}; + +int rt_hw_i2c_init(void) +{ + _i2c_init(); + +#ifdef BSP_USING_I2C0 + /* define i2c Instance */ + static struct rt_i2c_bus_device _i2c_device0; + rt_memset((void *)&_i2c_device0, 0, sizeof(struct rt_i2c_bus_device)); + _i2c_device0.ops = &es32f0_i2c_ops; + _i2c_device0.priv = &_h_i2c0; + rt_i2c_bus_device_register(&_i2c_device0, "i2c0"); +#endif + +#ifdef BSP_USING_I2C1 + /* define i2c Instance */ + static struct rt_i2c_bus_device _i2c_device1; + rt_memset((void *)&_i2c_device1, 0, sizeof(struct rt_i2c_bus_device)); + _i2c_device1.ops = &es32f0_i2c_ops; + _i2c_device1.priv = &_h_i2c1; + rt_i2c_bus_device_register(&_i2c_device1, "i2c1"); +#endif + + return RT_EOK; +} +INIT_DEVICE_EXPORT(rt_hw_i2c_init); + +#endif diff --git a/bsp/es32f0334/drivers/drv_i2c.h b/bsp/es32f0334/drivers/drv_i2c.h new file mode 100644 index 0000000000..2ba40feb69 --- /dev/null +++ b/bsp/es32f0334/drivers/drv_i2c.h @@ -0,0 +1,16 @@ +/* + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-03-19 wangyq the first version + */ + +#ifndef DRV_I2C_H__ +#define DRV_I2C_H__ + +int rt_hw_i2c_init(void); + +#endif diff --git a/bsp/es32f0334/drivers/drv_pwm.c b/bsp/es32f0334/drivers/drv_pwm.c new file mode 100644 index 0000000000..4275fb83f6 --- /dev/null +++ b/bsp/es32f0334/drivers/drv_pwm.c @@ -0,0 +1,211 @@ +/* + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-03-19 wangyq the first version + */ + +#include +#include +#include +#include +#include +#include +#include + +static void pwm_set_freq(timer_handle_t *timer_initstruct, uint32_t ns) +{ + uint64_t _arr = (uint64_t)cmu_get_pclk1_clock() * ns / 1000000000 / + (timer_initstruct->init.prescaler + 1); + + WRITE_REG(timer_initstruct->perh->AR, (uint32_t)_arr); + timer_initstruct->init.period = (uint32_t)_arr; +} + +static void pwm_set_duty(timer_handle_t *timer_initstruct, timer_channel_t ch, uint32_t ns) +{ + uint64_t tmp = (uint64_t)cmu_get_pclk1_clock() * ns / 1000000000 / + (timer_initstruct->init.prescaler + 1); + + if (ch == TIMER_CHANNEL_1) + WRITE_REG(timer_initstruct->perh->CCVAL1, (uint32_t)tmp); + else if (ch == TIMER_CHANNEL_2) + WRITE_REG(timer_initstruct->perh->CCVAL2, (uint32_t)tmp); + else if (ch == TIMER_CHANNEL_3) + WRITE_REG(timer_initstruct->perh->CCVAL3, (uint32_t)tmp); + else if (ch == TIMER_CHANNEL_4) + WRITE_REG(timer_initstruct->perh->CCVAL4, (uint32_t)tmp); +} + +static rt_err_t es32f0_pwm_control(struct rt_device_pwm *device, int cmd, void *arg) +{ + rt_err_t ret = RT_EOK; + uint32_t _ccep; + timer_channel_t pwm_channel; + timer_oc_init_t tim_ocinit; + timer_handle_t *timer_initstruct = (timer_handle_t *)device->parent.user_data; + struct rt_pwm_configuration *cfg = (struct rt_pwm_configuration *)arg; + + RT_ASSERT(timer_initstruct != RT_NULL); + + tim_ocinit.oc_mode = TIMER_OC_MODE_PWM1; + tim_ocinit.oc_polarity = TIMER_OC_POLARITY_HIGH; + tim_ocinit.oc_fast_en = DISABLE; + tim_ocinit.ocn_polarity = TIMER_OCN_POLARITY_HIGH; + tim_ocinit.ocn_idle = TIMER_OCN_IDLE_RESET; + tim_ocinit.oc_idle = TIMER_OC_IDLE_RESET; + + /* select pwm output channel */ + if (1 == cfg->channel) + { + pwm_channel = TIMER_CHANNEL_1; + } + else if (2 == cfg->channel) + { + pwm_channel = TIMER_CHANNEL_2; + } + else if (3 == cfg->channel) + { + if (timer_initstruct->perh == GP16C2T0 || timer_initstruct->perh == GP16C2T1) + return RT_EINVAL; + pwm_channel = TIMER_CHANNEL_3; + } + else if (4 == cfg->channel) + { + if (timer_initstruct->perh == GP16C2T0 || timer_initstruct->perh == GP16C2T1 || + timer_initstruct->perh == GP16C4T0) + return RT_EINVAL; + pwm_channel = TIMER_CHANNEL_4; + } + else + { + return RT_EINVAL; + } + + switch (cmd) + { + case PWM_CMD_ENABLE: + timer_pwm_start(timer_initstruct, pwm_channel); + break; + + case PWM_CMD_DISABLE: + timer_pwm_stop(timer_initstruct, pwm_channel); + break; + + case PWM_CMD_SET: + _ccep = timer_initstruct->perh->CCEP; + /* count registers max 0xFFFF, auto adjust prescaler */ + do + { + pwm_set_freq(timer_initstruct, cfg->period); + timer_initstruct->init.prescaler ++; + } + while (timer_initstruct->init.period > 0xFFFF); + /* update prescaler */ + WRITE_REG(timer_initstruct->perh->PRES, --timer_initstruct->init.prescaler); + timer_oc_config_channel(timer_initstruct, &tim_ocinit, pwm_channel); + pwm_set_duty(timer_initstruct, pwm_channel, cfg->pulse); + timer_initstruct->perh->CCEP = _ccep; + break; + + case PWM_CMD_GET: + cfg->pulse = timer_read_capture_value(timer_initstruct, pwm_channel) * 100 / + READ_REG(timer_initstruct->perh->AR); + break; + + default: + break; + } + return ret; +} + +const static struct rt_pwm_ops es32f0_pwm_ops = +{ + es32f0_pwm_control +}; + +int rt_hw_pwm_init(void) +{ + rt_err_t ret = RT_EOK; + gpio_init_t gpio_initstructure; + + gpio_initstructure.mode = GPIO_MODE_OUTPUT; + gpio_initstructure.odos = GPIO_PUSH_PULL; + gpio_initstructure.pupd = GPIO_PUSH_UP; + gpio_initstructure.odrv = GPIO_OUT_DRIVE_NORMAL; + gpio_initstructure.flt = GPIO_FILTER_DISABLE; + gpio_initstructure.type = GPIO_TYPE_TTL; + +#ifdef BSP_USING_PWM0 /* 4 channels */ + static struct rt_device_pwm pwm_dev0; + static timer_handle_t timer_initstruct0; + + timer_initstruct0.perh = AD16C4T0; + timer_pwm_init(&timer_initstruct0); + + /* gpio initialization */ + gpio_initstructure.func = GPIO_FUNC_2; + gpio_init(GPIOA, GPIO_PIN_8, &gpio_initstructure); + gpio_init(GPIOA, GPIO_PIN_9, &gpio_initstructure); + gpio_init(GPIOA, GPIO_PIN_10, &gpio_initstructure); + gpio_init(GPIOA, GPIO_PIN_11, &gpio_initstructure); + + ret = rt_device_pwm_register(&pwm_dev0, "pwm0", &es32f0_pwm_ops, + &timer_initstruct0); +#endif + +#ifdef BSP_USING_PWM1 /* 3 channels */ + static struct rt_device_pwm pwm_dev1; + static timer_handle_t timer_initstruct1; + + timer_initstruct1.perh = GP16C4T0; + timer_pwm_init(&timer_initstruct1); + + /* gpio initialization */ + gpio_initstructure.func = GPIO_FUNC_2; + gpio_init(GPIOB, GPIO_PIN_6, &gpio_initstructure); + gpio_init(GPIOB, GPIO_PIN_7, &gpio_initstructure); + gpio_init(GPIOB, GPIO_PIN_8, &gpio_initstructure); + + ret = rt_device_pwm_register(&pwm_dev1, "pwm1", &es32f0_pwm_ops, + &timer_initstruct1); +#endif + +#ifdef BSP_USING_PWM2 /* 2 channels */ + static struct rt_device_pwm pwm_dev2; + static timer_handle_t timer_initstruct2; + + timer_initstruct2.perh = GP16C2T0; + timer_pwm_init(&timer_initstruct2); + + /* gpio initialization */ + gpio_initstructure.func = GPIO_FUNC_2; + gpio_init(GPIOA, GPIO_PIN_0, &gpio_initstructure); + gpio_init(GPIOA, GPIO_PIN_1, &gpio_initstructure); + + ret = rt_device_pwm_register(&pwm_dev2, "pwm2", &es32f0_pwm_ops, + &timer_initstruct2); +#endif + +#ifdef BSP_USING_PWM3 /* 2 channels */ + static struct rt_device_pwm pwm_dev3; + static timer_handle_t timer_initstruct3; + + timer_initstruct3.perh = GP16C2T1; + timer_pwm_init(&timer_initstruct3); + + /* gpio initialization */ + gpio_initstructure.func = GPIO_FUNC_3; + gpio_init(GPIOC, GPIO_PIN_6, &gpio_initstructure); + gpio_init(GPIOC, GPIO_PIN_7, &gpio_initstructure); + + ret = rt_device_pwm_register(&pwm_dev3, "pwm3", &es32f0_pwm_ops, + &timer_initstruct3); +#endif + + return ret; +} +INIT_DEVICE_EXPORT(rt_hw_pwm_init); diff --git a/bsp/es32f0334/drivers/drv_pwm.h b/bsp/es32f0334/drivers/drv_pwm.h new file mode 100644 index 0000000000..82505bb28c --- /dev/null +++ b/bsp/es32f0334/drivers/drv_pwm.h @@ -0,0 +1,16 @@ +/* + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-03-19 wangyq the first version + */ + +#ifndef DRV_PWM_H__ +#define DRV_PWM_H__ + +int rt_hw_pwm_init(void); + +#endif diff --git a/bsp/es32f0334/drivers/drv_spi.c b/bsp/es32f0334/drivers/drv_spi.c new file mode 100644 index 0000000000..2f69b278f5 --- /dev/null +++ b/bsp/es32f0334/drivers/drv_spi.c @@ -0,0 +1,297 @@ +/* + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-03-19 wangyq the first version + */ + +#include +#include +#include +#include +#include "board.h" +#include "drv_spi.h" +#include +#include +#include + +#ifdef RT_USING_SPI + +#define SPITIMEOUT 0x0FFF + +rt_err_t spi_configure(struct rt_spi_device *device, + struct rt_spi_configuration *cfg) +{ + spi_handle_t *hspi; + hspi = (spi_handle_t *)device->bus->parent.user_data; + + /* config spi mode */ + if (cfg->mode & RT_SPI_SLAVE) + { + hspi->init.mode = SPI_MODE_SLAVER; + } + else + { + hspi->init.mode = SPI_MODE_MASTER; + } + if (cfg->mode & RT_SPI_3WIRE) + { + hspi->init.dir = SPI_DIRECTION_1LINE; + } + else + { + hspi->init.dir = SPI_DIRECTION_2LINES; + } + if (cfg->data_width == 8) + { + hspi->init.data_size = SPI_DATA_SIZE_8; + } + else if (cfg->data_width == 16) + { + hspi->init.data_size = SPI_DATA_SIZE_16; + } + + if (cfg->mode & RT_SPI_CPHA) + { + hspi->init.phase = SPI_CPHA_SECOND; + } + else + { + hspi->init.phase = SPI_CPHA_FIRST; + } + if (cfg->mode & RT_SPI_CPOL) + { + hspi->init.polarity = SPI_CPOL_HIGH; + } + else + { + hspi->init.polarity = SPI_CPOL_LOW; + } + if (cfg->mode & RT_SPI_NO_CS) + { + hspi->init.ss_en = DISABLE; + } + else + { + hspi->init.ss_en = ENABLE; + } + + /* config spi clock */ + if (cfg->max_hz >= cmu_get_pclk1_clock() / 2) + { + /* pclk1 max speed 48MHz, spi master max speed 10MHz */ + if (cmu_get_pclk1_clock() / 2 <= 10000000) + { + hspi->init.baud = SPI_BAUD_2; + } + else if (cmu_get_pclk1_clock() / 4 <= 10000000) + { + hspi->init.baud = SPI_BAUD_4; + } + else + { + hspi->init.baud = SPI_BAUD_8; + } + } + else if (cfg->max_hz >= cmu_get_pclk1_clock() / 4) + { + /* pclk1 max speed 48MHz, spi master max speed 10MHz */ + if (cmu_get_pclk1_clock() / 4 <= 10000000) + { + hspi->init.baud = SPI_BAUD_4; + } + else + { + hspi->init.baud = SPI_BAUD_8; + } + } + else if (cfg->max_hz >= cmu_get_pclk1_clock() / 8) + { + hspi->init.baud = SPI_BAUD_8; + } + else if (cfg->max_hz >= cmu_get_pclk1_clock() / 16) + { + hspi->init.baud = SPI_BAUD_16; + } + else if (cfg->max_hz >= cmu_get_pclk1_clock() / 32) + { + hspi->init.baud = SPI_BAUD_32; + } + else if (cfg->max_hz >= cmu_get_pclk1_clock() / 64) + { + hspi->init.baud = SPI_BAUD_64; + } + else if (cfg->max_hz >= cmu_get_pclk1_clock() / 128) + { + hspi->init.baud = SPI_BAUD_128; + } + else + { + hspi->init.baud = SPI_BAUD_256; + } + spi_init(hspi); + return RT_EOK; +} + +static rt_uint32_t spixfer(struct rt_spi_device *device, struct rt_spi_message *message) +{ + rt_err_t res; + spi_handle_t *hspi; + struct es32f0_hw_spi_cs *cs; + + RT_ASSERT(device != RT_NULL); + RT_ASSERT(device->bus != RT_NULL); + RT_ASSERT(device->bus->parent.user_data != RT_NULL); + RT_ASSERT(message->send_buf != RT_NULL || message->recv_buf != RT_NULL); + + hspi = (spi_handle_t *)device->bus->parent.user_data; + cs = device->parent.user_data; + + /* only send data */ + if (message->recv_buf == RT_NULL) + { + if (message->cs_take) + { + rt_pin_write(cs->pin, 0); + } + res = spi_send(hspi, (rt_uint8_t *)message->send_buf, (rt_int32_t)message->length, SPITIMEOUT); + if (message->cs_release) + { + rt_pin_write(cs->pin, 1); + } + if (res != RT_EOK) + return RT_ERROR; + } + + /* only receive data */ + if (message->send_buf == RT_NULL) + { + if (message->cs_take) + { + rt_pin_write(cs->pin, 0); + } + res = spi_recv(hspi, (rt_uint8_t *)message->recv_buf, (rt_int32_t)message->length, SPITIMEOUT); + if (message->cs_release) + { + rt_pin_write(cs->pin, 1); + } + if (res != RT_EOK) + return RT_ERROR; + } + + /* send & receive */ + else + { + if (message->cs_take) + { + rt_pin_write(cs->pin, 0); + } + res = spi_send_recv(hspi, (rt_uint8_t *)message->send_buf, (rt_uint8_t *)message->recv_buf, + (rt_int32_t)message->length, SPITIMEOUT); + if (message->cs_release) + { + rt_pin_write(cs->pin, 1); + } + if (res != RT_EOK) + return RT_ERROR; + } + + return message->length; +} + +const struct rt_spi_ops es32f0_spi_ops = +{ + spi_configure, + spixfer, +}; + +static struct rt_spi_bus _spi_bus0, _spi_bus1; +static spi_handle_t _spi0, _spi1; +int es32f0_spi_register_bus(SPI_TypeDef *SPIx, const char *name) +{ + struct rt_spi_bus *spi_bus; + spi_handle_t *spi; + gpio_init_t gpio_instruct; + + if (SPIx == SPI0) + { + _spi0.perh = SPI0; + spi_bus = &_spi_bus0; + spi = &_spi0; + + /* SPI0 gpio init */ + gpio_instruct.mode = GPIO_MODE_OUTPUT; + gpio_instruct.odos = GPIO_PUSH_PULL; + gpio_instruct.func = GPIO_FUNC_4; + gpio_instruct.type = GPIO_TYPE_CMOS; + gpio_instruct.flt = GPIO_FILTER_DISABLE; + + /* PB3->SPI0_SCK, PB5->SPI0_MOSI */ + gpio_init(GPIOB, GPIO_PIN_3 | GPIO_PIN_5, &gpio_instruct); + + /* PB4->SPI0_MISO */ + gpio_instruct.mode = GPIO_MODE_INPUT; + gpio_init(GPIOB, GPIO_PIN_4, &gpio_instruct); + } + else if (SPIx == SPI1) + { + _spi1.perh = SPI1; + spi_bus = &_spi_bus1; + spi = &_spi1; + + /* SPI1 gpio init */ + gpio_instruct.mode = GPIO_MODE_OUTPUT; + gpio_instruct.odos = GPIO_PUSH_PULL; + gpio_instruct.func = GPIO_FUNC_4; + gpio_instruct.type = GPIO_TYPE_CMOS; + gpio_instruct.flt = GPIO_FILTER_DISABLE; + + /* PB13->SPI1_SCK, PB15->SPI1_MOSI */ + gpio_init(GPIOB, GPIO_PIN_13 | GPIO_PIN_15, &gpio_instruct); + + /* PB14->SPI1_MISO */ + gpio_instruct.mode = GPIO_MODE_INPUT; + gpio_init(GPIOB, GPIO_PIN_14, &gpio_instruct); + } + else + { + return -1; + } + spi_bus->parent.user_data = spi; + + return rt_spi_bus_register(spi_bus, name, &es32f0_spi_ops); +} + +rt_err_t es32f0_spi_device_attach(rt_uint32_t pin, const char *bus_name, const char *device_name) +{ + /* define spi Instance */ + struct rt_spi_device *spi_device = (struct rt_spi_device *)rt_malloc(sizeof(struct rt_spi_device)); + RT_ASSERT(spi_device != RT_NULL); + struct es32f0_hw_spi_cs *cs_pin = (struct es32f0_hw_spi_cs *)rt_malloc(sizeof(struct es32f0_hw_spi_cs)); + RT_ASSERT(cs_pin != RT_NULL); + cs_pin->pin = pin; + rt_pin_mode(pin, PIN_MODE_OUTPUT); + rt_pin_write(pin, 1); + return rt_spi_bus_attach_device(spi_device, device_name, bus_name, (void *)cs_pin); +} + +int rt_hw_spi_init(void) +{ + int result = 0; + +#ifdef BSP_USING_SPI0 + result = es32f0_spi_register_bus(SPI0, "spi0"); +#endif + +#ifdef BSP_USING_SPI1 + result = es32f0_spi_register_bus(SPI1, "spi1"); +#endif + + return result; +} +INIT_BOARD_EXPORT(rt_hw_spi_init); + +#endif diff --git a/bsp/es32f0334/drivers/drv_spi.h b/bsp/es32f0334/drivers/drv_spi.h new file mode 100644 index 0000000000..08e36431aa --- /dev/null +++ b/bsp/es32f0334/drivers/drv_spi.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-03-19 wangyq the first version + */ + +#ifndef DRV_SPI_H__ +#define DRV_SPI_H__ + +#include +#include +#include + +struct es32f0_hw_spi_cs +{ + rt_uint32_t pin; +}; + +/* cannot be used before completion init */ +rt_err_t es32f0_spi_device_attach(rt_uint32_t pin, const char *bus_name, const char *device_name); +int rt_hw_spi_init(void); + +#endif diff --git a/bsp/es32f0334/drivers/drv_spiflash.c b/bsp/es32f0334/drivers/drv_spiflash.c new file mode 100644 index 0000000000..227d4a722f --- /dev/null +++ b/bsp/es32f0334/drivers/drv_spiflash.c @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-03-19 wangyq the first version + */ + +#include +#include "spi_flash.h" +#include "drv_spiflash.h" +#include "spi_flash_sfud.h" +#include "drv_spi.h" + +#if defined(BSP_USING_SPI_FLASH) +static int rt_hw_spi_flash_init(void) +{ + es32f0_spi_device_attach(50, "spi0", "spi00"); + + if (RT_NULL == rt_sfud_flash_probe("W25Q64", "spi00")) + { + return -RT_ERROR; + }; + + return RT_EOK; +} +INIT_COMPONENT_EXPORT(rt_hw_spi_flash_init); + +#endif diff --git a/bsp/es32f0334/drivers/drv_spiflash.h b/bsp/es32f0334/drivers/drv_spiflash.h new file mode 100644 index 0000000000..f578d2e48f --- /dev/null +++ b/bsp/es32f0334/drivers/drv_spiflash.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-19 wangyq the first version + */ + +#ifndef DRV_NOR_FLASH_H__ +#define DRV_NOR_FLASH_H__ + +int rt_hw_spi_flash_init(void); + +#endif diff --git a/bsp/es32f0334/drivers/drv_uart.c b/bsp/es32f0334/drivers/drv_uart.c index d7a638f8c9..26d6359999 100644 --- a/bsp/es32f0334/drivers/drv_uart.c +++ b/bsp/es32f0334/drivers/drv_uart.c @@ -45,13 +45,10 @@ static rt_err_t es32f0x_configure(struct rt_serial_device *serial, struct serial gpio_init_initstructure.func = GPIO_FUNC_3; gpio_init(GPIOB, GPIO_PIN_10, &gpio_init_initstructure); - /* Initialize rx pin ,the same as txpin except mode*/ + /* Initialize rx pin ,the same as txpin except mode */ gpio_init_initstructure.mode = GPIO_MODE_INPUT; gpio_init(GPIOB, GPIO_PIN_11, &gpio_init_initstructure); - - NVIC_EnableIRQ(UART0_IRQn); - -#endif /* uart0 gpio init */ +#endif #ifdef BSP_USING_UART1 /* Initialize tx pin */ @@ -61,9 +58,7 @@ static rt_err_t es32f0x_configure(struct rt_serial_device *serial, struct serial /* Initialize rx pin ,the same as txpin except mode*/ gpio_init_initstructure.mode = GPIO_MODE_INPUT; gpio_init(GPIOC, GPIO_PIN_11, &gpio_init_initstructure); - - NVIC_EnableIRQ(UART1_IRQn); -#endif /* uart1 gpio init */ +#endif uart->huart.init.mode = UART_MODE_UART; uart->huart.init.baud = cfg->baud_rate; @@ -90,7 +85,7 @@ static rt_err_t es32f0x_configure(struct rt_serial_device *serial, struct serial UART_DATA_INV_DISABLE(&uart->huart); } - /*enable rx int*/ + /* enable rx int */ uart_interrupt_config(&uart->huart, UART_IT_RXRD, ENABLE); return RT_EOK; diff --git a/bsp/es32f0334/project.uvoptx b/bsp/es32f0334/project.uvoptx index 74dc4b1440..d064f068ab 100644 --- a/bsp/es32f0334/project.uvoptx +++ b/bsp/es32f0334/project.uvoptx @@ -101,7 +101,7 @@ 0 0 1 - 3 + 2 @@ -112,9 +112,14 @@ - Segger\JL2CM3.dll + BIN\CMSIS_AGDI.dll + + 0 + CMSIS_AGDI + -X"Any" -UAny -O206 -S0 -C0 -P00 -N00("ARM CoreSight SW-DP") -D00(0BB11477) -L00(0) -TO18 -TC10000000 -TP20 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO15 -FD20000000 -FC1000 -FN1 -FF0ES32F033x.FLM -FS00 -FL040000 -FP0($$Device:ES32F0334LT$Flash\ES32F033x.FLM) + 0 JL2CM3 diff --git a/bsp/es32f0334/project.uvprojx b/bsp/es32f0334/project.uvprojx index d2b02f57d6..de68de284a 100644 --- a/bsp/es32f0334/project.uvprojx +++ b/bsp/es32f0334/project.uvprojx @@ -365,7 +365,7 @@ - --keep *.o(.rti_fn.*) --keep *.o(FSymTab) + diff --git a/bsp/es32f0334/rtconfig.h b/bsp/es32f0334/rtconfig.h index 8435637828..36c6a2e256 100644 --- a/bsp/es32f0334/rtconfig.h +++ b/bsp/es32f0334/rtconfig.h @@ -163,8 +163,18 @@ #define BSP_USING_UART1 +/* SPI Drivers */ + + +/* I2C Drivers */ + + +/* PWM Drivers */ + + /* Onboard Peripheral Drivers */ + /* Offboard Peripheral Drivers */ diff --git a/bsp/es32f0334/template.uvoptx b/bsp/es32f0334/template.uvoptx index 74dc4b1440..d064f068ab 100644 --- a/bsp/es32f0334/template.uvoptx +++ b/bsp/es32f0334/template.uvoptx @@ -101,7 +101,7 @@ 0 0 1 - 3 + 2 @@ -112,9 +112,14 @@ - Segger\JL2CM3.dll + BIN\CMSIS_AGDI.dll + + 0 + CMSIS_AGDI + -X"Any" -UAny -O206 -S0 -C0 -P00 -N00("ARM CoreSight SW-DP") -D00(0BB11477) -L00(0) -TO18 -TC10000000 -TP20 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO15 -FD20000000 -FC1000 -FN1 -FF0ES32F033x.FLM -FS00 -FL040000 -FP0($$Device:ES32F0334LT$Flash\ES32F033x.FLM) + 0 JL2CM3