当前位置:网站首页>[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
边栏推荐
- ucore概述
- Kotlin learning quick start (7) -- wonderful use of expansion
- 29:第三章:开发通行证服务:12:开发【获得用户账户信息,接口】;(使用VO类包装查到的数据,以符合接口对返回数据的要求)(在多处都会用到的逻辑,在Controller中可以把其抽成一个共用方法)
- kubernetes资源对象介绍及常用命令(四)
- Open vsftpd port under iptables firewall
- [combinatorics] recursive equation (outline of recursive equation content | definition of recursive equation | example description of recursive equation | Fibonacci Series)
- 新库上线 | CnOpenData中国保险机构网点全集数据
- Simple configuration of postfix server
- Mysql database DDL and DML
- 基于主机的入侵系统IDS
猜你喜欢
[error reporting] omp: error 15: initializing libiomp5md dll, but found libiomp5md. dll already initialized.
建立自己的网站(23)
跨境电商:外贸企业做海外社媒营销的优势
Kotlin learning quick start (7) -- wonderful use of expansion
The largest matrix (H) in a brush 143 monotone stack 84 histogram
Redis:关于列表List类型数据的操作命令
CC2530 common registers for ADC single channel conversion
Web crawler knowledge day03
Life is still confused? Maybe these subscription numbers have the answers you need!
How do large consumer enterprises make digital transformation?
随机推荐
The most complete postman interface test tutorial in the whole network, API interface test
One brush 145 force deduction hot question-2 sum of two numbers (m)
vs code 插件 koroFileHeader
[2. Basics of Delphi grammar] 1 Identifiers and reserved words
數據分析必備的能力
CC2530 common registers for crystal oscillator settings
The largest matrix (H) in a brush 143 monotone stack 84 histogram
Life is still confused? Maybe these subscription numbers have the answers you need!
[error reporting] omp: error 15: initializing libiomp5md dll, but found libiomp5md. dll already initialized.
Visual studio "usually, each socket address (Protocol / network address / port) can only be used once“
聊聊接口优化的几个方法
Financial management (Higher Vocational College) financial management online Assignment 1 in autumn 20
MySQL Basics
On Lagrange interpolation and its application
27. Input 3 integers and output them in descending order. Pointer method is required.
[combinatorics] recursive equation (the relationship theorem between the solution of the recursive equation and the characteristic root | the linear property theorem of the solution of the recursive e
浅谈拉格朗日插值及其应用
Redis:关于列表List类型数据的操作命令
C language string inversion
C语言字符串反转