当前位置:网站首页>[RT thread] NXP rt10xx device driver framework -- pin construction and use
[RT thread] NXP rt10xx device driver framework -- pin construction and use
2022-07-03 17:11:00 【L_ seventeen】
Preparation before development
- Hardware platform :nxp rt10xx Single chip microcomputer
- IDE: Keil
1.Kconfig Modifications and menuconfig To configure
Kconfig Found in PIN The default configuration is selected ( After all, the most commonly used IO Driving equipment )
RT-Thread Comonents -> Device Drivers
RT-Thread Components-> On-chip Peripheral Drivers

2. Engineering additions PIN Drive framework and BSP Driver interface
Device drive frame :pin.c BSP Interface :drv_gpio.c fsl_gpio.c fsl_iomuxc.c

3. Add or modify drv_gpio.c
The author consulted the document , The drive is perfect , Hardly need to change anything , Next, let's understand the basic framework
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);
The bsp Basically perfect , Nothing to change , Show it briefly
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. Build application layer demo
Basic function LED0 Blink in thread ,LED1 adopt KEY0 Press once to flip once 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 */
/* Interrupt callback function */
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);
// establish Audio Threads
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*****************************************************/
test result

边栏推荐
- New library online | cnopendata complete data of Chinese insurance institution outlets
- Why is WPA3 security of enterprise business so important?
- LeetCode 1656. Design ordered flow
- [2. Basics of Delphi grammar] 1 Identifiers and reserved words
- Squid 服务启动脚本
- 静态程序分析(一)—— 大纲思维导图与内容介绍
- 深入理解 SQL 中的 Grouping Sets 语句
- 數據分析必備的能力
- 关于学习Qt编程的好书精品推荐
- IL Runtime
猜你喜欢

Leetcode: lucky number in matrix

ANOVA example

Cross border e-commerce: advantages of foreign trade enterprises in overseas social media marketing

Kotlin learning quick start (7) -- wonderful use of expansion

CC2530 common registers for ADC single channel conversion

Web crawler knowledge day03
![[try to hack] active detection and concealment technology](/img/43/d48f851268fec566ce0cc83bd9557e.png)
[try to hack] active detection and concealment technology

Unity notes unityxr simple to use

跨境电商:外贸企业做海外社媒营销的优势

New features of C 10
随机推荐
Life is still confused? Maybe these subscription numbers have the answers you need!
On Lagrange interpolation and its application
[combinatorics] recursive equation (example of solving recursive equation without multiple roots | complete process of solving recursive equation without multiple roots)
How to judge the region of an IP through C?
新库上线 | CnOpenData中国观鸟记录数据
人生还在迷茫?也许这些订阅号里有你需要的答案!
执行脚本不认\r
vs code 插件 koroFileHeader
[combinatorics] recursive equation (definition of general solution | structure theorem of general solution of recursive equation without multiple roots)
跨境电商:外贸企业做海外社媒营销的优势
Necessary ability of data analysis
Cross border e-commerce: advantages of foreign trade enterprises in overseas social media marketing
Simple use of unity pen XR grab
网络硬盘NFS的安装与配置
Vs code plug-in korofileheader
SVN完全备份svnadmin hotcopy
[combinatorial mathematics] counting model, common combinatorial numbers and combinatorial identities**
Hands on in-depth learning notes (XIV) 3.7 Simple implementation of softmax regression
建立自己的网站(23)
Rsync远程同步