diff --git a/bsp/gd32/driver/drv_adc.c b/bsp/gd32/driver/drv_adc.c new file mode 100644 index 0000000000000000000000000000000000000000..e80e7e7d43a267dd99ed0c72a7ac428c449d2af2 --- /dev/null +++ b/bsp/gd32/driver/drv_adc.c @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2023, mr-library Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2023-05-22 MacRsh first version + */ + +#include "drv_adc.h" + +#if (MR_CFG_ADC == MR_CFG_ENABLE) + +static struct ch32_adc_data ch32_adc_data[] = + { +#ifdef MR_BSP_ADC_1 + {"adc1", ADC1, RCU_ADC1}, +#endif +#ifdef MR_BSP_ADC_2 + {"adc2", ADC2, RCU_ADC2}, +#endif + }; + +static struct mr_adc adc_device[mr_array_num(ch32_adc_data)]; + +static mr_err_t ch32_adc_configure(mr_adc_t adc, mr_state_t state) +{ + struct ch32_adc_data *adc_data = (struct ch32_adc_data *)adc->device.data; + + if(state) + { + rcu_periph_clock_enable(adc_data->periph_clock);//使能ADC1通道时钟 + } + else + { + rcu_periph_clock_disable(adc_data->periph_clock);//禁止ADC1通道时钟 + } + rcu_adc_clock_config(RCU_CKADC_CKAPB2_DIV4);// ADC时钟8分频,最大14MHz + adc_deinit(adc_data->instance); + + adc_mode_config(ADC_MODE_FREE); + adc_special_function_config(adc_data->instance, ADC_CONTINUOUS_MODE, ENABLE);// 单通道用连续转换模式 + adc_data_alignment_config(adc_data->instance, ADC_DATAALIGN_RIGHT);// 结果转换右对齐 + adc_channel_length_config(adc_data->instance, ADC_REGULAR_CHANNEL, 1);// 转换通道1个 + adc_external_trigger_source_config(adc_data->instance, ADC_REGULAR_CHANNEL, ADC0_1_2_EXTTRIG_REGULAR_NONE);// 不用外部触发转换,软件开启即可 + adc_external_trigger_config(adc_data->instance, ADC_REGULAR_CHANNEL, ENABLE); + if(state) + { + adc_enable(adc_data->instance);// 使能ADC + } + else + { + adc_disable(adc_data->instance);// 禁止ADC + } + adc_calibration_enable(adc_data->instance);// 使能ADC校准 + + return MR_ERR_OK; +} + +static mr_err_t ch32_adc_channel_configure(mr_adc_t adc, mr_adc_config_t config) +{ + mr_size_t count = 0; + + rcu_periph_enum gpio_periph_clock; + uint32_t gpio_port; + uint16_t gpio_pin; + uint32_t gpio_mode; + + for (count = 0; count <= 17; count++) + { + if (count <= 7) + { + gpio_periph_clock = RCU_GPIOA; + if ((1 << count) & config->channel._mask) + { + rcu_periph_clock_enable(gpio_periph_clock); + gpio_mode = GPIO_MODE_AIN; + gpio_port = GPIOA; + gpio_pin = (1 << count); + gpio_init(gpio_port,gpio_mode,GPIO_OSPEED_50MHZ,gpio_pin); + } + } + else if (count <= 10) + { + gpio_periph_clock = RCU_GPIOB; + if ((1 << count) & config->channel._mask) + { + rcu_periph_clock_enable(gpio_periph_clock); + gpio_mode = GPIO_MODE_AIN; + gpio_port = GPIOB; + gpio_pin = (1 << count); + gpio_init(gpio_port,gpio_mode,GPIO_OSPEED_50MHZ,gpio_pin); + } + } + else if (count <= 15) + { + if ((1 << count) & config->channel._mask) + { + rcu_periph_clock_enable(gpio_periph_clock); + gpio_mode = GPIO_MODE_AIN; + gpio_port = GPIOC; + gpio_pin = (1 << count); + gpio_init(gpio_port,gpio_mode,GPIO_OSPEED_50MHZ,gpio_pin); + } + } + else if (count <= 17) + { + if ((1 << count) & config->channel._mask) + { + adc_tempsensor_vrefint_enable(); + } + else + { + adc_tempsensor_vrefint_disable(); + } + } + } + + return MR_ERR_OK; +} + +static mr_uint32_t ch32_adc_read(mr_adc_t adc, mr_off_t channel) +{ + + struct ch32_adc_data *adc_data = (struct ch32_adc_data *)adc->device.data; + mr_size_t i = 0; + mr_uint32_t adcccc = 0; + + if (channel > 17) + { + return 0; + } + + adc_regular_channel_config(adc_data->instance, 0, channel, ADC_SAMPLETIME_55POINT5); + adc_software_trigger_enable(adc_data->instance, ADC_REGULAR_CHANNEL); + while(!adc_flag_get(adc_data->instance, ADC_FLAG_EOC)) + { + i++; + if (i > MR_UINT16_MAX) + { + return 0; + } + } + adc_flag_clear(adc_data->instance, ADC_FLAG_EOC); + + adcccc = adc_regular_data_read(adc_data->instance); + return adcccc; +} + +mr_err_t drv_adc_init(void) +{ + static struct mr_adc_ops drv_ops = + { + ch32_adc_configure, + ch32_adc_channel_configure, + ch32_adc_read, + }; + mr_size_t count = mr_array_num(adc_device); + mr_err_t ret = MR_ERR_OK; + + while (count--) + { + ret = mr_adc_device_add(&adc_device[count], ch32_adc_data[count].name, &drv_ops, &ch32_adc_data[count]); + MR_ASSERT(ret == MR_ERR_OK); + } + + return ret; +} +MR_INIT_DRIVER_EXPORT(drv_adc_init); + +#endif diff --git a/bsp/gd32/driver/drv_adc.h b/bsp/gd32/driver/drv_adc.h new file mode 100644 index 0000000000000000000000000000000000000000..931b2060e439eb370498254e53b18728401c1f5a --- /dev/null +++ b/bsp/gd32/driver/drv_adc.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2023, mr-library Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2023-05-22 MacRsh first version + */ + +#ifndef _DRV_ADC_H_ +#define _DRV_ADC_H_ + +#include "adc.h" +#include "mrboard.h" + +#if (MR_CFG_ADC == MR_CFG_ENABLE) + +/** + * @struct ch32 ADC data + */ +struct ch32_adc_data +{ + const char *name; + + uint32_t instance; + rcu_periph_enum periph_clock; +}; + +#endif + +#endif /* _DRV_ADC_H_ */ diff --git a/bsp/gd32/driver/drv_gpio.c b/bsp/gd32/driver/drv_gpio.c new file mode 100644 index 0000000000000000000000000000000000000000..1484e9111c999aabaf7638b01b561360f0898dbb --- /dev/null +++ b/bsp/gd32/driver/drv_gpio.c @@ -0,0 +1,381 @@ +/* + * Copyright (c) 2023, mr-library Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2023-04-27 MacRsh first version + */ + +#include "drv_gpio.h" + +#if (MR_CFG_PIN == MR_CFG_ENABLE) + +#define PIN_STPORT(pin) ((GPIO_BASE + (0x400u * ((pin) / 16)))) +#define PIN_STPIN(pin) ((uint16_t)(1u << ((pin % 16)))) +#define PIN_RCC(pin) (RCU_GPIOA + ((pin) / 16)) + +static IRQn_Type irq[] = + { + EXTI0_IRQn, + EXTI1_IRQn, + EXTI2_IRQn, + EXTI3_IRQn, + EXTI4_IRQn, + EXTI5_9_IRQn, + EXTI5_9_IRQn, + EXTI5_9_IRQn, + EXTI5_9_IRQn, + EXTI5_9_IRQn, + EXTI10_15_IRQn, + EXTI10_15_IRQn, + EXTI10_15_IRQn, + EXTI10_15_IRQn, + EXTI10_15_IRQn, + EXTI10_15_IRQn, + }; + +static mr_off_t irq_mask[16] = {-1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1}; + +static struct mr_pin pin_device; + +static mr_err_t ch32_pin_configure(mr_pin_t pin, mr_pin_config_t config) +{ + rcu_periph_enum gpio_periph_clock; + uint32_t gpio_port; + uint16_t gpio_pin; + uint32_t gpio_mode; + + uint8_t gpio_port_source_gpiox; + uint8_t gpio_pin_source_pinx; + + exti_line_enum exti_linex; + exti_mode_enum exti_mode; + exti_trig_type_enum exti_trig_type; + + mr_uint32_t exti_line = config->number % 16; + + if (config->number < 0) + { + return -MR_ERR_INVALID; + } + + gpio_periph_clock = (rcu_periph_enum)PIN_RCC(config->number); + gpio_port = PIN_STPORT(config->number); + gpio_pin = PIN_STPIN(config->number); + gpio_port_source_gpiox = config->number / 16; + gpio_pin_source_pinx = config->number % 16; + + exti_linex = (exti_line_enum)(0x01 << exti_line); + + rcu_periph_clock_enable(gpio_periph_clock); + + switch (config->mode) + { + case MR_PIN_MODE_OUTPUT: + { + gpio_mode = GPIO_MODE_OUT_PP; + break; + } + + case MR_PIN_MODE_OUTPUT_OD: + { + gpio_mode = GPIO_MODE_OUT_OD; + break; + } + + case MR_PIN_MODE_INPUT: + { + gpio_mode = GPIO_MODE_IN_FLOATING; + break; + } + + case MR_PIN_MODE_INPUT_DOWN: + { + gpio_mode = GPIO_MODE_IPD; + break; + } + + case MR_PIN_MODE_INPUT_UP: + { + gpio_mode = GPIO_MODE_IPU; + break; + } + + case MR_PIN_MODE_IRQ_RISING: + { + gpio_mode = GPIO_MODE_IPD; + exti_trig_type = EXTI_TRIG_RISING; + exti_mode = EXTI_INTERRUPT; + break; + } + + case MR_PIN_MODE_IRQ_FALLING: + { + gpio_mode = GPIO_MODE_IPU; + exti_trig_type = EXTI_TRIG_FALLING; + exti_mode = EXTI_INTERRUPT; + break; + } + + case MR_PIN_MODE_IRQ_EDGE: + { + gpio_mode = GPIO_MODE_IN_FLOATING; + exti_trig_type = EXTI_TRIG_BOTH; + exti_mode = EXTI_INTERRUPT; + break; + } + + case MR_PIN_MODE_IRQ_LOW: + { + gpio_mode = GPIO_MODE_IN_FLOATING; + exti_trig_type = EXTI_TRIG_BOTH; + exti_mode = EXTI_EVENT; + break; + } + + case MR_PIN_MODE_IRQ_HIGH: + { + gpio_mode = GPIO_MODE_IN_FLOATING; + exti_trig_type = EXTI_TRIG_BOTH; + exti_mode = EXTI_EVENT; + break; + } + + default: + { + gpio_mode = GPIO_MODE_IN_FLOATING; + exti_mode = EXTI_INTERRUPT; + break; + } + } + + if (config->mode >= MR_PIN_MODE_IRQ_RISING) + { + if ((irq_mask[exti_line] != -1 && irq_mask[exti_line] != config->number)) + { + return -MR_ERR_BUSY; + } + + irq_mask[exti_line] = config->number; + + rcu_periph_clock_enable(RCU_AF); + gpio_exti_source_select(gpio_port_source_gpiox, gpio_pin_source_pinx); + exti_init(exti_linex, exti_mode, exti_trig_type); + exti_interrupt_enable(exti_linex); + + nvic_irq_enable(irq[exti_line], 1, 2); + } + else if (config->number == irq_mask[config->number % 16]) + { + if (exti_line >= 5 && exti_line <= 9) + { + if (irq_mask[5] == -1 && irq_mask[6] == -1 && irq_mask[7] == -1 && irq_mask[8] == -1 && irq_mask[9] == -1) + { + exti_interrupt_disable(exti_linex); + } + else + { + exti_interrupt_enable(exti_linex); + } + } + else + { + if (irq_mask[10] == -1 && irq_mask[11] == -1 && irq_mask[12] == -1 && irq_mask[13] == -1 && + irq_mask[14] == -1 + && irq_mask[15] == -1) + { + exti_interrupt_disable(exti_linex); + } + else + { + exti_interrupt_enable(exti_linex); + } + } + + irq_mask[exti_line] = -1; + + gpio_exti_source_select(gpio_port_source_gpiox, gpio_pin_source_pinx); + exti_init(exti_linex, exti_mode, exti_trig_type); + } + gpio_init(gpio_port,gpio_mode,GPIO_OSPEED_50MHZ,gpio_pin); + + return MR_ERR_OK; +} + +static mr_level_t ch32_pin_read(mr_pin_t pin, mr_off_t number) +{ + if (number > MR_BSP_PIN_NUMBER) + { + return 0; + } + + return (mr_level_t)gpio_input_bit_get(PIN_STPORT(number), PIN_STPIN(number)); +} + +static void ch32_pin_write(mr_pin_t pin, mr_off_t number, mr_level_t level) +{ + if (number > MR_BSP_PIN_NUMBER) + { + return; + } + + gpio_bit_write(PIN_STPORT(number), PIN_STPIN(number), (bit_status)level); +} + +void EXTI0_IRQHandler(void) ;//__attribute__((interrupt("WCH-Interrupt-fast"))); + +void EXTI0_IRQHandler(void) +{ + if (exti_interrupt_flag_get(EXTI_0) != RESET) + { + mr_pin_device_isr(&pin_device, irq_mask[0]); + exti_interrupt_flag_clear(EXTI_0); + } +} + +void EXTI1_IRQHandler(void) ;//__attribute__((interrupt("WCH-Interrupt-fast"))); + +void EXTI1_IRQHandler(void) +{ + if (exti_interrupt_flag_get(EXTI_1) != RESET) + { + mr_pin_device_isr(&pin_device, irq_mask[1]); + exti_interrupt_flag_clear(EXTI_1); + } +} + +void EXTI2_IRQHandler(void) ;//__attribute__((interrupt("WCH-Interrupt-fast"))); + +void EXTI2_IRQHandler(void) +{ + if (exti_interrupt_flag_get(EXTI_2) != RESET) + { + mr_pin_device_isr(&pin_device, irq_mask[2]); + exti_interrupt_flag_clear(EXTI_2); + } +} + +void EXTI3_IRQHandler(void) ;//__attribute__((interrupt("WCH-Interrupt-fast"))); + +void EXTI3_IRQHandler(void) +{ + if (exti_interrupt_flag_get(EXTI_3) != RESET) + { + mr_pin_device_isr(&pin_device, irq_mask[3]); + exti_interrupt_flag_clear(EXTI_3); + } +} + +void EXTI4_IRQHandler(void) ;//__attribute__((interrupt("WCH-Interrupt-fast"))); + +void EXTI4_IRQHandler(void) +{ + if (exti_interrupt_flag_get(EXTI_4) != RESET) + { + mr_pin_device_isr(&pin_device, irq_mask[4]); + exti_interrupt_flag_clear(EXTI_4); + } +} + +void EXTI5_9_IRQHandler(void) ;//__attribute__((interrupt("WCH-Interrupt-fast"))); + +void EXTI5_9_IRQHandler(void) +{ + if (exti_interrupt_flag_get(EXTI_5) != RESET) + { + mr_pin_device_isr(&pin_device, irq_mask[5]); + exti_interrupt_flag_clear(EXTI_5); + } + if (exti_interrupt_flag_get(EXTI_6) != RESET) + { + mr_pin_device_isr(&pin_device, irq_mask[6]); + exti_interrupt_flag_clear(EXTI_6); + } + if (exti_interrupt_flag_get(EXTI_7) != RESET) + { + mr_pin_device_isr(&pin_device, irq_mask[7]); + exti_interrupt_flag_clear(EXTI_7); + } + if (exti_interrupt_flag_get(EXTI_8) != RESET) + { + mr_pin_device_isr(&pin_device, irq_mask[8]); + exti_interrupt_flag_clear(EXTI_8); + } + if (exti_interrupt_flag_get(EXTI_9) != RESET) + { + mr_pin_device_isr(&pin_device, irq_mask[9]); + exti_interrupt_flag_clear(EXTI_9); + } +} + +void EXTI10_15_IRQHandler(void) ;//__attribute__((interrupt("WCH-Interrupt-fast"))); + +void EXTI10_15_IRQHandler(void) +{ + if (exti_interrupt_flag_get(EXTI_10) != RESET) + { + mr_pin_device_isr(&pin_device, irq_mask[10]); + exti_interrupt_flag_clear(EXTI_10); + } + if (exti_interrupt_flag_get(EXTI_11) != RESET) + { + mr_pin_device_isr(&pin_device, irq_mask[11]); + exti_interrupt_flag_clear(EXTI_11); + } + if (exti_interrupt_flag_get(EXTI_12) != RESET) + { + mr_pin_device_isr(&pin_device, irq_mask[12]); + exti_interrupt_flag_clear(EXTI_12); + } + if (exti_interrupt_flag_get(EXTI_13) != RESET) + { + mr_pin_device_isr(&pin_device, irq_mask[13]); + exti_interrupt_flag_clear(EXTI_13); + } + if (exti_interrupt_flag_get(EXTI_14) != RESET) + { + mr_pin_device_isr(&pin_device, irq_mask[14]); + exti_interrupt_flag_clear(EXTI_14); + } + if (exti_interrupt_flag_get(EXTI_15) != RESET) + { + mr_pin_device_isr(&pin_device, irq_mask[15]); + exti_interrupt_flag_clear(EXTI_15); + } +} + +mr_err_t drv_gpio_init(void) +{ + static struct mr_pin_ops drv_ops = + { + ch32_pin_configure, + ch32_pin_read, + ch32_pin_write, + }; + mr_err_t ret = MR_ERR_OK; + + ret = mr_pin_device_add(&pin_device, "pin", &drv_ops, MR_NULL); + MR_ASSERT(ret == MR_ERR_OK); + + return ret; +} +MR_INIT_DRIVER_EXPORT(drv_gpio_init); + +#endif diff --git a/bsp/gd32/driver/drv_gpio.h b/bsp/gd32/driver/drv_gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..0203ba528ba4b683bfee8d3c1befe48f176e0829 --- /dev/null +++ b/bsp/gd32/driver/drv_gpio.h @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2023, mr-library Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2023-04-27 MacRsh first version + */ + +#ifndef _DRV_GPIO_H_ +#define _DRV_GPIO_H_ + +#include "pin.h" +#include "mrboard.h" + +#endif /* _DRV_GPIO_H_ */ diff --git a/bsp/gd32/driver/drv_i2c.c b/bsp/gd32/driver/drv_i2c.c new file mode 100644 index 0000000000000000000000000000000000000000..3004af7f3b75700326e58a67c5a5ca31b1d41497 --- /dev/null +++ b/bsp/gd32/driver/drv_i2c.c @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2023, mr-library Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2023-07-19 MacRsh first version + */ + +#include "drv_i2c.h" + +#if (MR_CFG_I2C == MR_CFG_ENABLE) + +static struct ch32_soft_i2c_bus_data ch32_soft_i2c_bus_data[] = + { +#ifdef MR_BSP_I2C_1 + {"i2c1", RCU_GPIOC, GPIOC, GPIO_PIN_9, GPIO_PIN_8}, //Touch +#endif +#ifdef MR_BSP_I2C_2 + {"i2c2", RCU_GPIOE, GPIOE, GPIO_PIN_10, GPIO_PIN_11},//Led +#endif +#ifdef MR_BSP_I2C_3 + {"i2c3", RCU_GPIOD, GPIOD, GPIO_PIN_12, GPIO_PIN_11},//PCA9535 +#endif + }; + +static struct mr_soft_i2c_bus soft_i2c_bus_device[mr_array_num(ch32_soft_i2c_bus_data)]; + +static mr_err_t ch32_soft_i2c_bus_configure(mr_soft_i2c_bus_t i2c_bus, mr_state_t state) +{ + struct ch32_soft_i2c_bus_data *soft_i2c_bus_data = (struct ch32_soft_i2c_bus_data *)i2c_bus->i2c_bus.device.data; + + rcu_periph_clock_enable(soft_i2c_bus_data->gpio_periph_clock); + gpio_init(soft_i2c_bus_data->gpio_port,state == MR_ENABLE ? GPIO_MODE_OUT_OD : GPIO_MODE_IN_FLOATING,GPIO_OSPEED_50MHZ,soft_i2c_bus_data->scl_gpio_pin); + gpio_init(soft_i2c_bus_data->gpio_port,state == MR_ENABLE ? GPIO_MODE_OUT_OD : GPIO_MODE_IN_FLOATING,GPIO_OSPEED_50MHZ,soft_i2c_bus_data->sda_gpio_pin); + + return MR_ERR_OK; +} + +static void ch32_soft_i2c_bus_scl_write(mr_soft_i2c_bus_t i2c_bus, mr_level_t level) +{ + struct ch32_soft_i2c_bus_data *soft_i2c_bus_data = (struct ch32_soft_i2c_bus_data *)i2c_bus->i2c_bus.device.data; + + gpio_bit_write(soft_i2c_bus_data->gpio_port, soft_i2c_bus_data->scl_gpio_pin, (bit_status)level); +} + +static void ch32_soft_i2c_bus_sda_write(mr_soft_i2c_bus_t i2c_bus, mr_level_t level) +{ + struct ch32_soft_i2c_bus_data *soft_i2c_bus_data = (struct ch32_soft_i2c_bus_data *)i2c_bus->i2c_bus.device.data; + + gpio_bit_write(soft_i2c_bus_data->gpio_port, soft_i2c_bus_data->sda_gpio_pin, (bit_status)level); +} + +static mr_level_t ch32_soft_i2c_bus_sda_read(mr_soft_i2c_bus_t i2c_bus) +{ + struct ch32_soft_i2c_bus_data *soft_i2c_bus_data = (struct ch32_soft_i2c_bus_data *)i2c_bus->i2c_bus.device.data; + + return gpio_input_bit_get(soft_i2c_bus_data->gpio_port, soft_i2c_bus_data->sda_gpio_pin); +} + +mr_err_t drv_soft_i2c_bus_init(void) +{ + static struct mr_soft_i2c_ops drv_ops = + { + ch32_soft_i2c_bus_configure, + ch32_soft_i2c_bus_scl_write, + ch32_soft_i2c_bus_sda_write, + ch32_soft_i2c_bus_sda_read, + }; + mr_size_t count = mr_array_num(soft_i2c_bus_device); + mr_err_t ret = MR_ERR_OK; + + while (count--) + { + ret = mr_soft_i2c_bus_add(&soft_i2c_bus_device[count], + ch32_soft_i2c_bus_data[count].name, + &drv_ops, + &ch32_soft_i2c_bus_data[count]); + MR_ASSERT(ret == MR_ERR_OK); + } + + return ret; +} +MR_INIT_DRIVER_EXPORT(drv_soft_i2c_bus_init); + +#endif diff --git a/bsp/gd32/driver/drv_i2c.h b/bsp/gd32/driver/drv_i2c.h new file mode 100644 index 0000000000000000000000000000000000000000..580e49927397755d43c09d73bacfc5c8f506efe7 --- /dev/null +++ b/bsp/gd32/driver/drv_i2c.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2023, mr-library Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2023-07-19 MacRsh first version + */ + +#ifndef _DRV_I2C_H_ +#define _DRV_I2C_H_ + +#include "i2c.h" +#include "mrboard.h" + +#if (MR_CFG_I2C == MR_CFG_ENABLE) + +struct ch32_soft_i2c_bus_data +{ + const char *name; + + rcu_periph_enum gpio_periph_clock; + mr_uint32_t gpio_port; + mr_uint16_t scl_gpio_pin; + mr_uint16_t sda_gpio_pin; +}; + +#endif + +#endif /* _DRV_I2C_H_ */ diff --git a/bsp/gd32/driver/drv_uart.c b/bsp/gd32/driver/drv_uart.c new file mode 100644 index 0000000000000000000000000000000000000000..43d42af60432aa8418bd342e3bdcff622b6d87bf --- /dev/null +++ b/bsp/gd32/driver/drv_uart.c @@ -0,0 +1,343 @@ +/* + * Copyright (c) 2023, mr-library Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2023-04-23 MacRsh first version + */ + +#include "drv_uart.h" + +#if (MR_CFG_SERIAL == MR_CFG_ENABLE) + +enum +{ +#ifdef MR_BSP_UART_1 + CH32_UART_1_INDEX, +#endif +#ifdef MR_BSP_UART_2 + CH32_UART_2_INDEX, +#endif +#ifdef MR_BSP_UART_3 + CH32_UART_3_INDEX, +#endif +#ifdef MR_BSP_UART_4 + CH32_UART_4_INDEX, +#endif +#ifdef MR_BSP_UART_5 + CH32_UART_5_INDEX, +#endif +#ifdef MR_BSP_UART_6 + CH32_UART_6_INDEX, +#endif +#ifdef MR_BSP_UART_7 + CH32_UART_7_INDEX, +#endif +#ifdef MR_BSP_UART_8 + CH32_UART_8_INDEX, +#endif +}; + +static struct ch32_uart_data ch32_uart_data[] = + { +#ifdef MR_BSP_UART_1 + {"uart1", USART0, RCU_USART0, RCU_GPIOA, GPIOA, GPIO_PIN_9, GPIOA, GPIO_PIN_10,USART0_IRQn}, +#endif +#ifdef MR_BSP_UART_2 + {"uart2", USART1, RCU_USART1, RCU_GPIOA, GPIOA, GPIO_PIN_2, GPIOA, GPIO_PIN_3,USART1_IRQn}, +#endif +#ifdef MR_BSP_UART_3 + {"uart3", USART2, RCU_USART2, RCU_GPIOD, GPIOD, GPIO_PIN_8, GPIOD, GPIO_PIN_9,USART2_IRQn}, +#endif +#ifdef MR_BSP_UART_4 + {"uart4", UART3, RCU_UART3, RCU_GPIOC, GPIOC, GPIO_PIN_10, GPIOC, GPIO_PIN_11,UART3_IRQn}, +#endif +#ifdef MR_BSP_UART_5 + {"uart5", UART4, RCU_UART4, RCU_GPIOC, GPIOC, GPIO_PIN_12, GPIOC,GPIO_PIN_2, UART4_IRQn}, +#endif +#ifdef MR_BSP_UART_6 + {"uart6", UART5, RCC_APB1Periph_UART6, RCC_APB2Periph_GPIOC, GPIOC, GPIO_Pin_0, GPIOC, GPIO_Pin_1, UART6_IRQn}, +#endif +#ifdef MR_BSP_UART_7 + {"uart7", UART6, RCC_APB1Periph_UART7, RCC_APB2Periph_GPIOC, GPIOC, GPIO_Pin_2, GPIOC, GPIO_Pin_3, UART7_IRQn}, +#endif +#ifdef MR_BSP_UART_8 + {"uart8", UART7, RCC_APB1Periph_UART8, RCC_APB2Periph_GPIOC, GPIOC, GPIO_Pin_4, GPIOC, GPIO_Pin_5, UART8_IRQn}, +#endif + }; + +static struct mr_serial serial_device[mr_array_num(ch32_uart_data)]; + +static mr_err_t ch32_serial_configure(mr_serial_t serial, struct mr_serial_config *config) +{ + struct ch32_uart_data *uart_data = (struct ch32_uart_data *)serial->device.data; + + if (config->baud_rate == 0) + { + rcu_periph_clock_disable(uart_data->uart_periph_clock); + return MR_ERR_OK; + } + if(uart_data->instance == USART2) + { + gpio_pin_remap_config(GPIO_USART2_FULL_REMAP, ENABLE); + } + rcu_periph_clock_enable(RCU_AF); + rcu_periph_clock_enable(uart_data->uart_periph_clock); + rcu_periph_clock_enable(uart_data->gpio_periph_clock); + nvic_irq_enable(uart_data->irqno, 3, 0); + + switch (config->data_bits) + { + case MR_SERIAL_DATA_BITS_8: + { + usart_word_length_set(uart_data->instance,USART_WL_8BIT); + break; + } + + case MR_SERIAL_DATA_BITS_9: + { + usart_word_length_set(uart_data->instance,USART_WL_9BIT); + break; + } + + default: + return -MR_ERR_INVALID; + } + + switch (config->stop_bits) + { + case MR_SERIAL_STOP_BITS_1: + { + usart_stop_bit_set(uart_data->instance,USART_STB_1BIT); + break; + } + + case MR_SERIAL_STOP_BITS_2: + { + usart_stop_bit_set(uart_data->instance,USART_STB_2BIT); + break; + } + + default: + return -MR_ERR_INVALID; + } + switch (config->parity) + { + case MR_SERIAL_PARITY_NONE: + { + usart_parity_config(uart_data->instance,USART_PM_NONE); + break; + } + case MR_SERIAL_PARITY_ODD: + { + usart_parity_config(uart_data->instance,USART_PM_ODD); + break; + } + + case MR_SERIAL_PARITY_EVEN: + { + usart_parity_config(uart_data->instance,MR_SERIAL_PARITY_ODD); + break; + } + + default: + return -MR_ERR_INVALID; + } + + switch (config->bit_order) + { + case MR_SERIAL_BIT_ORDER_LSB: + { + break; + } + + default: + return -MR_ERR_INVALID; + } + + switch (config->invert) + { + case MR_SERIAL_NRZ_NORMAL: + { + break; + } + + default: + return -MR_ERR_INVALID; + } + + gpio_init(uart_data->tx_gpio_port,GPIO_MODE_AF_PP ,GPIO_OSPEED_50MHZ,uart_data->tx_gpio_pin); + gpio_init(uart_data->rx_gpio_port,GPIO_MODE_IPD ,GPIO_OSPEED_50MHZ,uart_data->rx_gpio_pin); + + usart_deinit(uart_data->instance); + usart_baudrate_set(uart_data->instance, config->baud_rate); + usart_receive_config(uart_data->instance, USART_RECEIVE_ENABLE); + usart_transmit_config(uart_data->instance, USART_TRANSMIT_ENABLE); + usart_interrupt_enable(uart_data->instance, USART_INT_RBNE); + //usart_interrupt_enable(uart_data->instance, USART_INT_TBE); + usart_enable(uart_data->instance); + + return MR_ERR_OK; +} + +static void ch32_serial_write(mr_serial_t serial, mr_uint8_t data) +{ + struct ch32_uart_data *uart_data = (struct ch32_uart_data *)serial->device.data; + mr_size_t i = 0; + + while (usart_flag_get(uart_data->instance, USART_FLAG_TC) == RESET) + { + i++; + if (i > MR_UINT16_MAX) + { + return; + } + } + USART_DATA(uart_data->instance) = ((uint16_t)USART_DATA_DATA & data); +} + +static mr_uint8_t ch32_serial_read(mr_serial_t serial) +{ + struct ch32_uart_data *uart_data = (struct ch32_uart_data *)serial->device.data; + mr_size_t i = 0; + + while (usart_interrupt_flag_get(uart_data->instance, USART_INT_FLAG_RBNE) == RESET) + { + i++; + if (i > MR_UINT16_MAX) + { + return 0; + } + } + usart_interrupt_flag_clear(uart_data->instance, USART_INT_FLAG_RBNE); + char dat = usart_data_receive(uart_data->instance) & 0xff; + + return dat; +} + +static void ch32_serial_start_tx(mr_serial_t serial) +{ + struct ch32_uart_data *uart_data = (struct ch32_uart_data *)serial->device.data; + + usart_transmit_config(uart_data->instance, USART_TRANSMIT_ENABLE); +} + +static void ch32_serial_stop_tx(mr_serial_t serial) +{ + struct ch32_uart_data *uart_data = (struct ch32_uart_data *)serial->device.data; + + usart_transmit_config(uart_data->instance, USART_TRANSMIT_DISABLE); +} + +static void ch32_serial_isr(mr_serial_t serial) +{ + struct ch32_uart_data *uart_data = (struct ch32_uart_data *)serial->device.data; + + if(RESET != usart_interrupt_flag_get(uart_data->instance, USART_INT_FLAG_RBNE)) + { + mr_serial_device_isr(serial, MR_SERIAL_EVENT_RX_INT); + + usart_interrupt_flag_clear(uart_data->instance, USART_INT_FLAG_RBNE); + } + if(RESET != usart_interrupt_flag_get(uart_data->instance, USART_INT_FLAG_TC)) + { + mr_serial_device_isr(serial, MR_SERIAL_EVENT_TX_INT); + + usart_interrupt_flag_clear(uart_data->instance, USART_INT_FLAG_TC); + } +} + +#ifdef MR_BSP_UART_1 +void USART0_IRQHandler(void) ;//__attribute__((interrupt("WCH-Interrupt-fast"))); +void USART0_IRQHandler(void) +{ + ch32_serial_isr(&serial_device[CH32_UART_1_INDEX]); +} +#endif + +#ifdef MR_BSP_UART_2 +void USART1_IRQHandler(void) ;//__attribute__((interrupt("WCH-Interrupt-fast"))); +void USART1_IRQHandler(void) +{ + ch32_serial_isr(&serial_device[CH32_UART_2_INDEX]); +} +#endif + +#ifdef MR_BSP_UART_3 +void USART2_IRQHandler(void) ;//__attribute__((interrupt("WCH-Interrupt-fast"))); +void USART2_IRQHandler(void) +{ + ch32_serial_isr(&serial_device[CH32_UART_3_INDEX]); +} +#endif + +#ifdef MR_BSP_UART_4 +void UART3_IRQHandler(void) ;//__attribute__((interrupt("WCH-Interrupt-fast"))); +void UART3_IRQHandler(void) +{ + ch32_serial_isr(&serial_device[CH32_UART_4_INDEX]); +} +#endif + +#ifdef MR_BSP_UART_5 +void UART4_IRQHandler(void) ;//__attribute__((interrupt("WCH-Interrupt-fast"))); +void UART4_IRQHandler(void) +{ + ch32_serial_isr(&serial_device[CH32_UART_5_INDEX]); +} +#endif + +#ifdef MR_BSP_UART_6 +void UART6_IRQHandler(void) ;//__attribute__((interrupt("WCH-Interrupt-fast"))); +void UART6_IRQHandler(void) +{ + ch32_serial_isr(&serial_device[CH32_UART_6_INDEX]); +} +#endif + +#ifdef MR_BSP_UART_7 +void UART7_IRQHandler(void) ;//__attribute__((interrupt("WCH-Interrupt-fast"))); +void UART7_IRQHandler(void) +{ + ch32_serial_isr(&serial_device[CH32_UART_7_INDEX]); +} +#endif + +#ifdef MR_BSP_UART_8 +void UART8_IRQHandler(void) ;//__attribute__((interrupt("WCH-Interrupt-fast"))); +void UART8_IRQHandler(void) +{ + ch32_serial_isr(&serial_device[CH32_UART_8_INDEX]); +} +#endif + +mr_err_t drv_uart_init(void) +{ + nvic_vector_table_set(NVIC_VECTTAB_FLASH,0x00005000);//设置偏移量 + __set_PRIMASK(0); + nvic_priority_group_set(NVIC_PRIGROUP_PRE4_SUB0); + + static struct mr_serial_ops drv_ops = + { + ch32_serial_configure, + ch32_serial_write, + ch32_serial_read, + ch32_serial_start_tx, + ch32_serial_stop_tx, + }; + mr_size_t count = mr_array_num(serial_device); + mr_err_t ret = MR_ERR_OK; + + while (count--) + { + ret = mr_serial_device_add(&serial_device[count], ch32_uart_data[count].name, &drv_ops, &ch32_uart_data[count]); + MR_ASSERT(ret == MR_ERR_OK); + } + + return ret; +} +MR_INIT_DRIVER_EXPORT(drv_uart_init); + +#endif diff --git a/bsp/gd32/driver/drv_uart.h b/bsp/gd32/driver/drv_uart.h new file mode 100644 index 0000000000000000000000000000000000000000..296f2c7c5a71b555831251c32a866e0f36be2400 --- /dev/null +++ b/bsp/gd32/driver/drv_uart.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2023, mr-library Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2023-04-23 MacRsh first version + */ + +#ifndef _DRV_UART_H_ +#define _DRV_UART_H_ + +#include "serial.h" +#include "mrboard.h" + +#if (MR_CFG_SERIAL == MR_CFG_ENABLE) + +/** + * @struct ch32 UART data + */ +struct ch32_uart_data +{ + const char *name; + + uint32_t instance; + rcu_periph_enum uart_periph_clock; + rcu_periph_enum gpio_periph_clock; + uint32_t tx_gpio_port; + mr_uint16_t tx_gpio_pin; + uint32_t rx_gpio_port; + mr_uint16_t rx_gpio_pin; + uint32_t irqno; +}; + +#endif + +#endif /* _DRV_UART_H_ */ diff --git a/bsp/gd32/driver/mrboard.c b/bsp/gd32/driver/mrboard.c new file mode 100644 index 0000000000000000000000000000000000000000..025a10693224ef78ec0eb58978f6bc66ddbc730a --- /dev/null +++ b/bsp/gd32/driver/mrboard.c @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2023, mr-library Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2023-09-11 MacRsh first version + */ + +#include "mrboard.h" + +void mr_delay_us(mr_size_t us) +{ + uint32_t i,j; + + for(i = 0;i < us;i ++) + for(j = 0;j < 5;j ++) + { + __NOP(); + __NOP(); + __NOP(); + __NOP(); + } +} + +void mr_delay_ms(mr_size_t ms) +{ + uint32_t i; + for(i = 0;i < ms;i ++) + { + mr_delay_us(ms); + } +} diff --git a/bsp/gd32/driver/mrboard.h b/bsp/gd32/driver/mrboard.h new file mode 100644 index 0000000000000000000000000000000000000000..37343d7b4064cbcbb2f9186cffe2fe220e377b4f --- /dev/null +++ b/bsp/gd32/driver/mrboard.h @@ -0,0 +1,99 @@ +#ifndef _MR_BOARD_H_ +#define _MR_BOARD_H_ + +#include "mrapi.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @include bsp head file + */ +#include "gd32f30x.h" +/** + * @def Bsp name + */ +#define MR_BSP_NAME "ch32-v2/v3" + +/** + * @def Bsp system clock + */ +#define MR_BSP_SYSCLK_FREQ SystemCoreClock + +/** + * @def Bsp pin number + */ +#define MR_BSP_PIN_NUMBER 144 + +/** + * @def Bsp uart + */ +//#define MR_BSP_UART_1 +#define MR_BSP_UART_2 +//#define MR_BSP_UART_3 +//#define MR_BSP_UART_4 +//#define MR_BSP_UART_5 +//#define MR_BSP_UART_6 +//#define MR_BSP_UART_7 +//#define MR_BSP_UART_8 + +/** + * @def Bsp adc + */ +#define MR_BSP_ADC_1 +#define MR_BSP_ADC_2 + +/** + * @def Bsp dac + */ +#define MR_BSP_DAC_1 +#define MR_BSP_DAC_2 + +/** + * @def Bsp i2c + */ +#define MR_BSP_I2C_1 +#define MR_BSP_I2C_2 +#define MR_BSP_I2C_3 + +/** + * @def Bsp spi + */ +#define MR_BSP_SPI_1 +#define MR_BSP_SPI_2 +#define MR_BSP_SPI_3 + +/** + * @def Bsp pwm + */ +#define MR_BSP_PWM_1 +//#define MR_BSP_PWM_2 +//#define MR_BSP_PWM_3 +//#define MR_BSP_PWM_4 +//#define MR_BSP_PWM_5 +//#define MR_BSP_PWM_6 +//#define MR_BSP_PWM_7 +//#define MR_BSP_PWM_8 +//#define MR_BSP_PWM_9 +//#define MR_BSP_PWM_10 + +/** + * @def Bsp timer + */ +#define MR_BSP_TIMER_1 +#define MR_BSP_TIMER_2 +#define MR_BSP_TIMER_3 +#define MR_BSP_TIMER_4 +#define MR_BSP_TIMER_5 +#define MR_BSP_TIMER_6 +#define MR_BSP_TIMER_7 +#define MR_BSP_TIMER_8 +#define MR_BSP_TIMER_9 +#define MR_BSP_TIMER_10 + +#ifdef __cplusplus +} +#endif + +#endif /* _MR_BOARD_H_ */ diff --git a/bsp/gd32/driver/mrdrv.h b/bsp/gd32/driver/mrdrv.h new file mode 100644 index 0000000000000000000000000000000000000000..a5a691737392f4bb13347b2af1cd5c4baaadb861 --- /dev/null +++ b/bsp/gd32/driver/mrdrv.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2023, mr-library Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2023-04-23 MacRsh first version + */ + +#ifndef _MR_DRV_H_ +#define _MR_DRV_H_ + +#include "mrconfig.h" + +#if (MR_CFG_ADC == MR_CFG_ENABLE) +#include "drv_adc.h" +#endif + +#if (MR_CFG_DAC == MR_CFG_ENABLE) +#include "drv_dac.h" +#endif + +#if (MR_CFG_I2C == MR_CFG_ENABLE) +#include "drv_i2c.h" +#endif + +#if (MR_CFG_PIN == MR_CFG_ENABLE) +#include "drv_gpio.h" +#endif + +#if (MR_CFG_PWM == MR_CFG_ENABLE) +#include "drv_pwm.h" +#endif + +#if (MR_CFG_SERIAL == MR_CFG_ENABLE) +#include "drv_uart.h" +#endif + +#if (MR_CFG_SPI == MR_CFG_ENABLE) +#include "drv_spi.h" +#endif + +#if (MR_CFG_TIMER == MR_CFG_ENABLE) +#include "drv_timer.h" +#endif + +#endif /* _MR_DRV_H_ */ \ No newline at end of file