当前位置:网站首页>【RT-Thread】nxp rt10xx 设备驱动框架之--Pin搭建和使用
【RT-Thread】nxp rt10xx 设备驱动框架之--Pin搭建和使用
2022-07-03 17:07:00 【L_17】
开发前准备
- 硬件平台:nxp rt10xx单片机
- IDE: Keil
1.Kconfig 修改和menuconfig配置
Kconfig中发现PIN 配置默认是选中状态(毕竟最常用的IO驱动设备)
RT-Thread Comonents -> Device Drivers
RT-Thread Components-> On-chip Peripheral Drivers
2.工程添加PIN驱动框架和BSP驱动接口
设备驱动框架:pin.c BSP接口:drv_gpio.c fsl_gpio.c fsl_iomuxc.c
3.添加或修改drv_gpio.c
笔者查阅了文件,该驱动很完善,几乎不用改什么,接下来先了解下基本框架吧
struct rt_pin_ops
{
void (*pin_mode)(struct rt_device *device, rt_base_t pin, rt_base_t mode);
void (*pin_write)(struct rt_device *device, rt_base_t pin, rt_base_t value);
int (*pin_read)(struct rt_device *device, rt_base_t pin);
rt_err_t (*pin_attach_irq)(struct rt_device *device, rt_int32_t pin,
rt_uint32_t mode, void (*hdr)(void *args), void *args);
rt_err_t (*pin_detach_irq)(struct rt_device *device, rt_int32_t pin);
rt_err_t (*pin_irq_enable)(struct rt_device *device, rt_base_t pin, rt_uint32_t enabled);
rt_base_t (*pin_get)(const char *name);
};
const static struct rt_pin_ops imxrt_pin_ops =
{
imxrt_pin_mode,
imxrt_pin_write,
imxrt_pin_read,
imxrt_pin_attach_irq,
imxrt_pin_detach_irq,
imxrt_pin_irq_enable,
RT_NULL,
};
int rt_hw_pin_init(void)
{
int ret = RT_EOK;
ret = rt_device_pin_register("pin", &imxrt_pin_ops, RT_NULL);
return ret;
}
INIT_BOARD_EXPORT(rt_hw_pin_init);
该bsp基本很完善了,没什么要改的,简单展示一下吧
static void imxrt_isr(rt_int16_t index_offset, rt_int8_t pin_start, GPIO_Type *base)
{
rt_int32_t isr_status, index;
rt_int8_t i, pin_end;
pin_end = pin_start + 15;
isr_status = GPIO_PortGetInterruptFlags(base) & base->IMR;
for (i = pin_start; i <= pin_end ; i++)
{
if (isr_status & (1 << i))
{
GPIO_PortClearInterruptFlags(base, (1 << i));
index = index_offset + i;
if (hdr_tab[index].hdr != RT_NULL)
{
hdr_tab[index].hdr(hdr_tab[index].args);
}
}
}
}
static void imxrt_pin_mode(rt_device_t dev, rt_base_t pin, rt_base_t mode)
{
gpio_pin_config_t gpio;
rt_uint32_t config_value = 0;
rt_int8_t port, pin_num;
port = pin >> 5;
pin_num = pin & 31;
if (PIN_INVALID_CHECK(port, pin_num))
{
LOG_D("invalid pin,rtt pin: %d,port: %d,pin: %d \n", pin,port + 1,pin_num);
return;
}
gpio.outputLogic = 0;
gpio.interruptMode = kGPIO_NoIntmode;
switch (mode)
{
case PIN_MODE_OUTPUT:
{
gpio.direction = kGPIO_DigitalOutput;
config_value = 0x0030U; /* Drive Strength R0/6 */
}
break;
case PIN_MODE_INPUT:
{
gpio.direction = kGPIO_DigitalInput;
config_value = 0x0830U; /* Open Drain Enable */
}
break;
case PIN_MODE_INPUT_PULLDOWN:
{
gpio.direction = kGPIO_DigitalInput;
config_value = 0x3030U; /* 100K Ohm Pull Down */
}
break;
case PIN_MODE_INPUT_PULLUP:
{
gpio.direction = kGPIO_DigitalInput;
config_value = 0xB030U; /* 100K Ohm Pull Up */
}
break;
case PIN_MODE_OUTPUT_OD:
{
gpio.direction = kGPIO_DigitalOutput;
config_value = 0x0830U; /* Open Drain Enable */
}
break;
}
if (mask_tab[port].gpio != GPIO5)
{
CLOCK_EnableClock(kCLOCK_Iomuxc);
IOMUXC_SetPinMux(MUX_BASE + reg_offset[pin] * 4, 0x5U, 0, 0, CONFIG_BASE + reg_offset[pin] * 4, 1);
IOMUXC_SetPinConfig(MUX_BASE + reg_offset[pin] * 4, 0x5U, 0, 0, CONFIG_BASE + reg_offset[pin] * 4, config_value);
}
else
{
CLOCK_EnableClock(kCLOCK_IomuxcSnvs);
IOMUXC_SetPinMux(GPIO5_MUX_BASE + pin_num * 4, 0x5U, 0, 0, GPIO5_CONFIG_BASE + pin_num * 4, 1);
IOMUXC_SetPinConfig(GPIO5_MUX_BASE + pin_num * 4, 0x5U, 0, 0, GPIO5_CONFIG_BASE + pin_num * 4, config_value);
}
GPIO_PinInit(mask_tab[port].gpio, pin_num, &gpio);
}
static int imxrt_pin_read(rt_device_t dev, rt_base_t pin)
{
int value;
rt_int8_t port, pin_num;
value = PIN_LOW;
port = pin >> 5;
pin_num = pin & 31;
if (PIN_INVALID_CHECK(port, pin_num))
{
LOG_D("invalid pin,rtt pin: %d,port: %d,pin: %d \n", pin,port + 1,pin_num);
return value;
}
return GPIO_PinReadPadStatus(mask_tab[port].gpio, pin_num);
}
static void imxrt_pin_write(rt_device_t dev, rt_base_t pin, rt_base_t value)
{
rt_int8_t port, pin_num;
port = pin >> 5;
pin_num = pin & 31;
if (PIN_INVALID_CHECK(port, pin_num))
{
LOG_D("invalid pin,rtt pin: %d,port: %d,pin: %d \n", pin,port + 1,pin_num);
return;
}
GPIO_PinWrite(mask_tab[port].gpio, pin_num, value);
}
static rt_err_t imxrt_pin_attach_irq(struct rt_device *device, rt_int32_t pin,
rt_uint32_t mode, void (*hdr)(void *args), void *args)
{
rt_base_t level;
rt_int8_t port, pin_num;
port = pin >> 5;
pin_num = pin & 31;
if (PIN_INVALID_CHECK(port, pin_num))
{
LOG_D("invalid pin,rtt pin: %d,port: %d,pin: %d \n", pin,port + 1,pin_num);
return RT_ENOSYS;
}
level = rt_hw_interrupt_disable();
if (hdr_tab[pin].pin == pin &&
hdr_tab[pin].hdr == hdr &&
hdr_tab[pin].mode == mode &&
hdr_tab[pin].args == args)
{
rt_hw_interrupt_enable(level);
return RT_EOK;
}
hdr_tab[pin].pin = pin;
hdr_tab[pin].hdr = hdr;
hdr_tab[pin].mode = mode;
hdr_tab[pin].args = args;
rt_hw_interrupt_enable(level);
return RT_EOK;
}
static rt_err_t imxrt_pin_detach_irq(struct rt_device *device, rt_int32_t pin)
{
rt_base_t level;
rt_int8_t port, pin_num;
port = pin >> 5;
pin_num = pin & 31;
if (PIN_INVALID_CHECK(port, pin_num))
{
LOG_D("invalid pin,rtt pin: %d,port: %d,pin: %d \n", pin,port + 1,pin_num);
return RT_ENOSYS;
}
level = rt_hw_interrupt_disable();
if (hdr_tab[pin].pin == -1)
{
rt_hw_interrupt_enable(level);
return RT_EOK;
}
hdr_tab[pin].pin = -1;
hdr_tab[pin].hdr = RT_NULL;
hdr_tab[pin].mode = 0;
hdr_tab[pin].args = RT_NULL;
rt_hw_interrupt_enable(level);
return RT_EOK;
}
static rt_err_t imxrt_pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint32_t enabled)
{
gpio_interrupt_mode_t int_mode;
rt_int8_t port, pin_num, irq_index;
port = pin >> 5;
pin_num = pin & 31;
if (PIN_INVALID_CHECK(port, pin_num))
{
LOG_D("invalid pin,rtt pin: %d,port: %d,pin: %d \n", pin,port + 1,pin_num);
return RT_ENOSYS;
}
if (hdr_tab[pin].pin == -1)
{
LOG_D("rtt pin: %d callback function not initialized!\n", pin);
return RT_ENOSYS;
}
if (enabled == PIN_IRQ_ENABLE)
{
switch (hdr_tab[pin].mode)
{
case PIN_IRQ_MODE_RISING:
int_mode = kGPIO_IntRisingEdge;
break;
case PIN_IRQ_MODE_FALLING:
int_mode = kGPIO_IntFallingEdge;
break;
case PIN_IRQ_MODE_RISING_FALLING:
int_mode = kGPIO_IntRisingOrFallingEdge;
break;
case PIN_IRQ_MODE_HIGH_LEVEL:
int_mode = kGPIO_IntHighLevel;
break;
case PIN_IRQ_MODE_LOW_LEVEL:
int_mode = kGPIO_IntLowLevel;
break;
default:
int_mode = kGPIO_IntRisingEdge;
break;
}
irq_index = (port << 1) + (pin_num >> 4);
GPIO_PinSetInterruptConfig(mask_tab[port].gpio, pin_num, int_mode);
GPIO_PortEnableInterrupts(mask_tab[port].gpio, 1U << pin_num);
NVIC_SetPriority(irq_tab[irq_index], NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0));
EnableIRQ(irq_tab[irq_index]);
}
else if (enabled == PIN_IRQ_DISABLE)
{
GPIO_PortDisableInterrupts(mask_tab[port].gpio, 1U << pin_num);
}
else
{
return RT_EINVAL;
}
return RT_EOK;
}
4.搭建应用层demo
基本功能LED0线程中闪烁,LED1通过KEY0按一次翻转一次IO
/**************************************************START OF FILE*****************************************************/
/*------------------------------------------------------------------------------------------------------------------ Includes */
#include <rtthread.h>
#include <rtdevice.h>
#include "drv_gpio.h"
/*------------------------------------------------------------------------------------------------------------------ Macros */
#define THREAD_GPIO_PRIORITY 24
#define THREAD_GPIO_STACK_SIZE 512
#define THREAD_GPIO_TIMESLICE 2
#define LED0_PIN GET_PIN(1, 9)
#define LED1_PIN GET_PIN(1, 24)
#define KEY0_PIN GET_PIN(5, 0) //IOMUXC_SNVS_WAKEUP_GPIO5_IO00
/*------------------------------------------------------------------------------------------------------------------ Variables */
static rt_thread_t h_thread_gpio = RT_NULL;
static uint8_t ledBlink;
/*------------------------------------------------------------------------------------------------------------------ Functions */
/* 中断回调函数 */
void key_irq(void *args)
{
rt_kprintf("key push!\n");
rt_pin_write(LED1_PIN, !rt_pin_read(LED1_PIN));
}
static void thread_gpio(void *parameter)
{
rt_kprintf("thread gpio start\n");
while(1)
{
rt_pin_write(LED0_PIN, PIN_HIGH);
// rt_pin_write(LED1_PIN, PIN_HIGH);
rt_thread_mdelay(500);
rt_pin_write(LED0_PIN, PIN_LOW);
// rt_pin_write(LED1_PIN, PIN_LOW);
rt_thread_mdelay(500);
}
}
void xAPP_GpioInit(void)
{
rt_pin_mode(LED0_PIN, PIN_MODE_OUTPUT);
rt_pin_mode(LED1_PIN, PIN_MODE_OUTPUT);
rt_pin_write(LED1_PIN, PIN_HIGH);
rt_pin_mode(KEY0_PIN, PIN_MODE_INPUT_PULLUP);
rt_pin_attach_irq(KEY0_PIN, PIN_IRQ_MODE_FALLING, key_irq, RT_NULL);
rt_pin_irq_enable(KEY0_PIN, PIN_IRQ_ENABLE);
//创建Audio线程
h_thread_gpio = rt_thread_create("t_gpio",thread_gpio,RT_NULL,THREAD_GPIO_STACK_SIZE,THREAD_GPIO_PRIORITY,THREAD_GPIO_TIMESLICE);
if (h_thread_gpio != RT_NULL)
{
rt_thread_startup(h_thread_gpio);
}
}
/****************************************************END OF FILE*****************************************************/
测试结果
边栏推荐
- What material is sa537cl1? Sa537cl1 corresponds to the national standard material
- 大消费企业怎样做数字化转型?
- Kotlin learning quick start (7) -- wonderful use of expansion
- HP 阵列卡排障一例
- vs code 插件 koroFileHeader
- Assembly instance analysis -- screen display in real mode
- 27. Input 3 integers and output them in descending order. Pointer method is required.
- Deep understanding of grouping sets statements in SQL
- [combinatorics] polynomial theorem (polynomial theorem | polynomial theorem proof | polynomial theorem inference 1 item number is the number of non negative integer solutions | polynomial theorem infe
- Open vsftpd port under iptables firewall
猜你喜欢
What is the material of 13mnnimor? 13mnnimor steel plate for medium and low temperature pressure vessels
Take you to API development by hand
C语言按行修改文件
Redis: operation commands for list type data
New library online | cnopendata complete data of Chinese insurance institution outlets
Cross border e-commerce: advantages of foreign trade enterprises in overseas social media marketing
建立自己的网站(23)
[JDBC] API parsing
美团一面:为什么线程崩溃崩溃不会导致 JVM 崩溃
Great changes! National housing prices fell below the 10000 yuan mark
随机推荐
Depth first search of graph
网络硬盘NFS的安装与配置
[combinatorics] recursive equation (example 1 of recursive equation | list recursive equation)
The most complete postman interface test tutorial in the whole network, API interface test
比亚迪、长城混动市场再“聚首”
匯編實例解析--實模式下屏幕顯示
C language string inversion
[mathematical logic] equivalent calculus and reasoning calculus of propositional logic (propositional logic | equivalent calculus | principal conjunctive (disjunctive) paradigm | reasoning calculus)**
[try to hack] active detection and concealment technology
Mysql database DDL and DML
Interpretation of several important concepts of satellite antenna
C language string practice
Overview of satellite navigation system
What is the material of 13mnnimor? 13mnnimor steel plate for medium and low temperature pressure vessels
29: Chapter 3: develop Passport Service: 12: develop [obtain user account information, interface]; (use VO class to package the found data to meet the requirements of the interface for the returned da
智慧之道(知行合一)
Host based intrusion system IDS
vs code 插件 koroFileHeader
[2. Basics of Delphi grammar] 1 Identifiers and reserved words
Installation and configuration of network hard disk NFS