前言
接着上篇《国民技术N32G457移植RT-Thread》的RT-Thread工程移植pin设备。
一、添加文件到工程中
1、添加drv_gpio.c
二、修改源文件
1、替换当前文件的__GD32为__N32
2、修改头文件
3、添加时钟和外部中断相关枚举
typedef enum
{
/* AHB peripherals */
RCU_DMA1 = RCC_AHB_PERIPH_DMA1,
RCU_DMA2 = RCC_AHB_PERIPH_DMA2,
RCU_SRAM = RCC_AHB_PERIPH_SRAM,
RCU_FLITF = RCC_AHB_PERIPH_FLITF,
RCU_CRC = RCC_AHB_PERIPH_CRC,
RCU_XFMC = RCC_AHB_PERIPH_XFMC,
RCU_RNGC = RCC_AHB_PERIPH_RNGC,
RCU_SDIO = RCC_AHB_PERIPH_SDIO,
RCU_SAC = RCC_AHB_PERIPH_SAC,
RCU_ADC1 = RCC_AHB_PERIPH_ADC1,
RCU_ADC2 = RCC_AHB_PERIPH_ADC2,
RCU_ADC3 = RCC_AHB_PERIPH_ADC3,
RCU_ADC4 = RCC_AHB_PERIPH_ADC4,
RCU_ETHMAC = RCC_AHB_PERIPH_ETHMAC,
RCU_QSPI = RCC_AHB_PERIPH_QSPI,
/* APB1 peripherals */
RCU_TIM2 = RCC_APB1_PERIPH_TIM2,
RCU_TIM3 = RCC_APB1_PERIPH_TIM3,
RCU_TIM4 = RCC_APB1_PERIPH_TIM4,
RCU_TIM5 = RCC_APB1_PERIPH_TIM5,
RCU_TIM6 = RCC_APB1_PERIPH_TIM6,
RCU_TIM7 = RCC_APB1_PERIPH_TIM7,
RCU_COMP = RCC_APB1_PERIPH_COMP,
RCU_COMP_FILT = RCC_APB1_PERIPH_COMP_FILT,
RCU_TSC = RCC_APB1_PERIPH_TSC,
RCU_WWDG = RCC_APB1_PERIPH_WWDG,
RCU_SPI2 = RCC_APB1_PERIPH_SPI2,
RCU_SPI3 = RCC_APB1_PERIPH_SPI3,
RCU_USART2 = RCC_APB1_PERIPH_USART2,
RCU_USART3 = RCC_APB1_PERIPH_USART3,
RCU_UART4 = RCC_APB1_PERIPH_UART4,
RCU_UART5 = RCC_APB1_PERIPH_UART5,
RCU_I2C1 = RCC_APB1_PERIPH_I2C1,
RCU_I2C2 = RCC_APB1_PERIPH_I2C2,
RCU_USB = RCC_APB1_PERIPH_USB,
RCU_CAN1 = RCC_APB1_PERIPH_CAN1,
RCU_CAN2 = RCC_APB1_PERIPH_CAN2,
RCU_BKP = RCC_APB1_PERIPH_BKP,
RCU_PWR = RCC_APB1_PERIPH_PWR,
RCU_DAC = RCC_APB1_PERIPH_DAC,
RCU_OPAMP = RCC_APB1_PERIPH_OPAMP,
/* APB2 peripherals */
RCU_AFIO = RCC_APB2_PERIPH_AFIO,
RCU_GPIOA = RCC_APB2_PERIPH_GPIOA,
RCU_GPIOB = RCC_APB2_PERIPH_GPIOB,
RCU_GPIOC = RCC_APB2_PERIPH_GPIOC,
RCU_GPIOD = RCC_APB2_PERIPH_GPIOD,
RCU_GPIOE = RCC_APB2_PERIPH_GPIOE,
RCU_GPIOF = RCC_APB2_PERIPH_GPIOF,
RCU_GPIOG = RCC_APB2_PERIPH_GPIOG,
RCU__TIM1 = RCC_APB2_PERIPH_TIM1,
RCU_SPI1 = RCC_APB2_PERIPH_SPI1,
RCU_TIM8 = RCC_APB2_PERIPH_TIM8,
RCU_USART1 = RCC_APB2_PERIPH_USART1,
RCU_DVP = RCC_APB2_PERIPH_DVP,
RCU_UART6 = RCC_APB2_PERIPH_UART6,
RCU_UART7 = RCC_APB2_PERIPH_UART7,
RCU_I2C3 = RCC_APB2_PERIPH_I2C3,
RCU_I2C4 = RCC_APB2_PERIPH_I2C4,
}rcu_periph_enum;
/* EXTI line number */
typedef enum
{
EXTI_0 = EXTI_LINE0, /*!< EXTI line 0 */
EXTI_1 = EXTI_LINE1, /*!< EXTI line 1 */
EXTI_2 = EXTI_LINE2, /*!< EXTI line 2 */
EXTI_3 = EXTI_LINE3, /*!< EXTI line 3 */
EXTI_4 = EXTI_LINE4, /*!< EXTI line 4 */
EXTI_5 = EXTI_LINE5, /*!< EXTI line 5 */
EXTI_6 = EXTI_LINE6, /*!< EXTI line 6 */
EXTI_7 = EXTI_LINE7, /*!< EXTI line 7 */
EXTI_8 = EXTI_LINE8, /*!< EXTI line 8 */
EXTI_9 = EXTI_LINE9, /*!< EXTI line 9 */
EXTI_10 = EXTI_LINE10, /*!< EXTI line 10 */
EXTI_11 = EXTI_LINE11, /*!< EXTI line 11 */
EXTI_12 = EXTI_LINE12, /*!< EXTI line 12 */
EXTI_13 = EXTI_LINE13, /*!< EXTI line 13 */
EXTI_14 = EXTI_LINE14, /*!< EXTI line 14 */
EXTI_15 = EXTI_LINE15, /*!< EXTI line 15 */
EXTI_16 = EXTI_LINE16, /*!< EXTI line 16 */
EXTI_17 = EXTI_LINE17, /*!< EXTI line 17 */
EXTI_18 = EXTI_LINE18, /*!< EXTI line 18 */
EXTI_19 = EXTI_LINE19, /*!< EXTI line 19 */
EXTI_20 = EXTI_LINE20, /*!< EXTI line 20 */
EXTI_21 = EXTI_LINE21, /*!< EXTI line 21 */
}exti_line_enum;
4、修改引脚索引宏
#define __N32_PIN(index, port, pin) {index, RCU_GPIO##port, GPIO##port,GPIO_PIN_##pin, \
GPIO##port##_PORT_SOURCE, GPIO_PIN_SOURCE##pin}
5、修改pin索引的结构体
6、修改外部中断引脚和中断映射
static const struct pin_irq_map pin_irq_map[] =
{
{GPIO_PIN_0, EXTI0_IRQn},
{GPIO_PIN_1, EXTI1_IRQn},
{GPIO_PIN_2, EXTI2_IRQn},
{GPIO_PIN_3, EXTI3_IRQn},
{GPIO_PIN_4, EXTI4_IRQn},
{GPIO_PIN_5, EXTI9_5_IRQn},
{GPIO_PIN_6, EXTI9_5_IRQn},
{GPIO_PIN_7, EXTI9_5_IRQn},
{GPIO_PIN_8, EXTI9_5_IRQn},
{GPIO_PIN_9, EXTI9_5_IRQn},
{GPIO_PIN_10, EXTI15_10_IRQn},
{GPIO_PIN_11, EXTI15_10_IRQn},
{GPIO_PIN_12, EXTI15_10_IRQn},
{GPIO_PIN_13, EXTI15_10_IRQn},
{GPIO_PIN_14, EXTI15_10_IRQn},
{GPIO_PIN_15, EXTI15_10_IRQn},
};
7、修改pin映射表
static const struct pin_index pins[] =
{
__N32_PIN_DEFAULT,
__N32_PIN(1, E, 2),
__N32_PIN(2, E, 3),
__N32_PIN(3, E, 4),
__N32_PIN(4, E, 5),
__N32_PIN(5, E, 6),
__N32_PIN_DEFAULT,
__N32_PIN(7, C, 13),
__N32_PIN(8, C, 14),
__N32_PIN(9, C, 15),
__N32_PIN_DEFAULT,
__N32_PIN_DEFAULT,
__N32_PIN_DEFAULT,
__N32_PIN_DEFAULT,
__N32_PIN_DEFAULT,
__N32_PIN_DEFAULT,
__N32_PIN_DEFAULT,
__N32_PIN_DEFAULT,
__N32_PIN_DEFAULT,
__N32_PIN_DEFAULT,
__N32_PIN_DEFAULT,
__N32_PIN_DEFAULT,
__N32_PIN_DEFAULT,
__N32_PIN_DEFAULT,
__N32_PIN_DEFAULT,
__N32_PIN_DEFAULT,
__N32_PIN(26, C, 0),
__N32_PIN(27, C, 1),
__N32_PIN(28, C, 2),
__N32_PIN(29, C, 3),
__N32_PIN_DEFAULT,
__N32_PIN_DEFAULT,
__N32_PIN_DEFAULT,
__N32_PIN_DEFAULT,
__N32_PIN(34, A, 0),
__N32_PIN(35, A, 1),
__N32_PIN(36, A, 2),
__N32_PIN(37, A, 3),
__N32_PIN_DEFAULT,
__N32_PIN_DEFAULT,
__N32_PIN(40, A, 4),
__N32_PIN(41, A, 5),
__N32_PIN(42, A, 6),
__N32_PIN(43, A, 7),
__N32_PIN(44, C, 4),
__N32_PIN(45, C, 5),
__N32_PIN(46, B, 0),
__N32_PIN(47, B, 1),
__N32_PIN(48, B, 2),
__N32_PIN(49, B, 3),
__N32_PIN(50, B, 4),
__N32_PIN(51, B, 5),
__N32_PIN_DEFAULT,
__N32_PIN_DEFAULT,
__N32_PIN_DEFAULT,
__N32_PIN_DEFAULT,
__N32_PIN_DEFAULT,
__N32_PIN_DEFAULT,
__N32_PIN(58, E, 7),
__N32_PIN(59, E, 8),
__N32_PIN(60, E, 9),
__N32_PIN_DEFAULT,
__N32_PIN_DEFAULT,
__N32_PIN(63, E, 10),
__N32_PIN(64, E, 11),
__N32_PIN(65, E, 12),
__N32_PIN(66, E, 13),
__N32_PIN(67, E, 14),
__N32_PIN(68, E, 15),
__N32_PIN(69, B, 10),
__N32_PIN(70, B, 11),
__N32_PIN_DEFAULT,
__N32_PIN_DEFAULT,
__N32_PIN(73, B, 12),
__N32_PIN(74, B, 13),
__N32_PIN(75, B, 14),
__N32_PIN(76, B, 15),
__N32_PIN(77, D, 8),
__N32_PIN(78, D, 9),
__N32_PIN(79, D, 10),
__N32_PIN(80, D, 11),
__N32_PIN(81, D, 12),
__N32_PIN(82, D, 13),
__N32_PIN_DEFAULT,
__N32_PIN_DEFAULT,
__N32_PIN(85, D, 14),
__N32_PIN(86, D, 15),
__N32_PIN_DEFAULT,
__N32_PIN_DEFAULT,
__N32_PIN_DEFAULT,
__N32_PIN_DEFAULT,
__N32_PIN_DEFAULT,
__N32_PIN_DEFAULT,
__N32_PIN_DEFAULT,
__N32_PIN_DEFAULT,
__N32_PIN_DEFAULT,
__N32_PIN(96, C, 6),
__N32_PIN(97, C, 7),
__N32_PIN(98, C, 8),
__N32_PIN(99, C, 9),
__N32_PIN(100, A, 8),
__N32_PIN(101, A, 9),
__N32_PIN(102, A, 10),
__N32_PIN(103, A, 11),
__N32_PIN(104, A, 12),
__N32_PIN(105, A, 13),
__N32_PIN_DEFAULT,
__N32_PIN_DEFAULT,
__N32_PIN_DEFAULT,
__N32_PIN(109, A, 14),
__N32_PIN(110, A, 15),
__N32_PIN(111, C, 10),
__N32_PIN(112, C, 11),
__N32_PIN(113, C, 12),
__N32_PIN(114, D, 0),
__N32_PIN(115, D, 1),
__N32_PIN(116, D, 2),
__N32_PIN(117, D, 3),
__N32_PIN(118, D, 4),
__N32_PIN(119, D, 5),
__N32_PIN_DEFAULT,
__N32_PIN_DEFAULT,
__N32_PIN(122, D, 6),
__N32_PIN(123, D, 7),
__N32_PIN_DEFAULT,
__N32_PIN_DEFAULT,
__N32_PIN_DEFAULT,
__N32_PIN_DEFAULT,
__N32_PIN_DEFAULT,
__N32_PIN_DEFAULT,
__N32_PIN_DEFAULT,
__N32_PIN_DEFAULT,
__N32_PIN_DEFAULT,
__N32_PIN(133, B, 3),
__N32_PIN(134, B, 4),
__N32_PIN(135, B, 5),
__N32_PIN(136, B, 6),
__N32_PIN(137, B, 7),
__N32_PIN_DEFAULT,
__N32_PIN(139, B, 8),
__N32_PIN(140, B, 9),
__N32_PIN(141, E, 0),
__N32_PIN(142, E, 1),
__N32_PIN_DEFAULT,
__N32_PIN_DEFAULT,
};
7、修改IO初始化函数gd32_pin_mode
void n32_pin_mode(rt_device_t dev, rt_base_t pin, rt_base_t mode)
{
const struct pin_index *index;
GPIO_InitType GPIO_InitStructure;
index = get_pin(pin);
if (index == RT_NULL)
{
return;
}
RCC_EnableAPB2PeriphClk(index->clk, ENABLE);
GPIO_InitStructure.Pin = index->pin;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
switch(mode)
{
case PIN_MODE_OUTPUT:
/* output setting */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
break;
case PIN_MODE_OUTPUT_OD:
/* output setting: od. */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
break;
case PIN_MODE_INPUT:
/* input setting: not pull. */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
break;
case PIN_MODE_INPUT_PULLUP:
/* input setting: pull up. */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
break;
case PIN_MODE_INPUT_PULLDOWN:
/* input setting: pull down. */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
break;
default:
break;
}
GPIO_InitPeripheral(index->gpio_periph, &GPIO_InitStructure);
}
8、修改IO读写函数
void n32_pin_write(rt_device_t dev, rt_base_t pin, rt_base_t value)
{
const struct pin_index *index;
index = get_pin(pin);
if (index == RT_NULL)
{
return;
}
GPIO_WriteBit(index->gpio_periph, index->pin, (Bit_OperateType)value);
}
int n32_pin_read(rt_device_t dev, rt_base_t pin)
{
int value;
const struct pin_index *index;
value = PIN_LOW;
index = get_pin(pin);
if (index == RT_NULL)
{
return value;
}
value = GPIO_ReadInputDataBit(index->gpio_periph, index->pin);
return value;
}
9、修改外部中断中断使能函数
rt_err_t n32_pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint32_t enabled)
{
const struct pin_index *index;
const struct pin_irq_map *irqmap;
rt_base_t level;
rt_int32_t hdr_index = -1;
EXTI_InitType EXTI_InitStructure;
GPIO_InitType GPIO_InitStructure;
index = get_pin(pin);
if (index == RT_NULL)
{
return RT_EINVAL;
}
if (enabled == PIN_IRQ_ENABLE)
{
hdr_index = bit2bitno(index->pin);
if (hdr_index < 0 || hdr_index >= ITEM_NUM(pin_irq_map))
{
return RT_EINVAL;
}
level = rt_hw_interrupt_disable();
if (pin_irq_hdr_tab[hdr_index].pin == -1)
{
rt_hw_interrupt_enable(level);
return RT_EINVAL;
}
irqmap = &pin_irq_map[hdr_index];
RCC_EnableAPB2PeriphClk(index->clk, ENABLE);
RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_AFIO, ENABLE);
GPIO_InitStructure.Pin = index->pin;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
switch (pin_irq_hdr_tab[hdr_index].mode)
{
case PIN_IRQ_MODE_RISING:
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
break;
case PIN_IRQ_MODE_FALLING:
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
break;
case PIN_IRQ_MODE_RISING_FALLING:
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
break;
default:
rt_hw_interrupt_enable(level);
return RT_EINVAL;
}
GPIO_InitPeripheral(index->gpio_periph, &GPIO_InitStructure);
GPIO_ConfigEXTILine(index->port_src, index->pin);
EXTI_InitStructure.EXTI_Line = index->pin;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_InitPeripheral(&EXTI_InitStructure);
EXTI_ClrITPendBit(index->pin);
NVIC_SetPriority(irqmap->irqno, 2);
NVIC_EnableIRQ(irqmap->irqno);
rt_hw_interrupt_enable(level);
}
else if (enabled == PIN_IRQ_DISABLE)
{
irqmap = get_pin_irq_map(index->pin);
if (irqmap == RT_NULL)
{
return RT_EINVAL;
}
NVIC_DisableIRQ(irqmap->irqno);
}
else
{
return RT_EINVAL;
}
return RT_EOK;
}
10、修改gd32_pin_attach_irq函数、gd32_pin_detach_irq函数名称为n32开头。
11、修改pin结构体,此结构体给将初始化、读和写等等函数映射到上层使用。
const static struct rt_pin_ops _n32_pin_ops =
{
n32_pin_mode,
n32_pin_write,
n32_pin_read,
n32_pin_attach_irq,
n32_pin_detach_irq,
n32_pin_irq_enable,
RT_NULL,
};
12、修改pin初始化函数
13、修改外部中断的中断服务函数
void GD32_GPIO_EXTI_IRQHandler(rt_int8_t exti_line)
{
if(RESET != EXTI_GetITStatus((exti_line_enum)(1 << exti_line)))
{
pin_irq_hdr(exti_line);
EXTI_ClrITPendBit((exti_line_enum)(1 << exti_line));
}
}
14、修改中断函数名称EXTI5_9_IRQHandler、EXTI10_15_IRQHandler为EXTI9_5_IRQHandler、EXTI15_10_IRQHandler。
三、源码下载
总结
下篇移植usart设备驱动