当前位置:网站首页>【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
- New features of C 10
- Cross border e-commerce: advantages of foreign trade enterprises in overseas social media marketing
- C语言字符串练习
- Kotlin learning quick start (7) -- wonderful use of expansion
- One brush 148 force deduction hot question-5 longest palindrome substring (m)
- 數據分析必備的能力
- Prepare for the golden three silver four, 100+ software test interview questions (function / interface / Automation) interview questions. win victory the moment one raises one 's standard
- 网络安全web渗透技术
- 線程池:業務代碼最常用也最容易犯錯的組件
猜你喜欢

13mnnimo5-4 German standard steel plate 13MnNiMo54 boiler steel 13MnNiMo54 chemical properties

Bcvp developer community 2022 exclusive peripheral first bullet

New features of C 10

图之深度优先搜索

Static program analysis (I) -- Outline mind map and content introduction

Prepare for the golden three silver four, 100+ software test interview questions (function / interface / Automation) interview questions. win victory the moment one raises one 's standard

新库上线 | CnOpenData中国保险机构网点全集数据

What is your income level in the country?
![[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](/img/9d/6118b699c0d90810638f9b08d4f80a.jpg)
[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

The most complete postman interface test tutorial in the whole network, API interface test
随机推荐
2022.02.14_ Daily question leetcode five hundred and forty
CC2530 common registers for timer 1
Mysql database DDL and DML
RF Analyze Demo搭建 Step by Step
网络安全web渗透技术
网络硬盘NFS的安装与配置
[combinatorics] recursive equation (definition of general solution | structure theorem of general solution of recursive equation without multiple roots)
深入理解 SQL 中的 Grouping Sets 语句
Execute script unrecognized \r
Installation and configuration of network hard disk NFS
Squid 服务启动脚本
简单配置PostFix服务器
function overloading
Fast Ethernet and Gigabit Ethernet: what's the difference?
How SVN views modified file records
CC2530 common registers for crystal oscillator settings
An example of HP array card troubleshooting
C语言按行修改文件
执行脚本不认\r
How to promote cross department project collaboration | community essay solicitation