[BSP][k210]Add GPIO driver
This commit is contained in:
parent
56c8f8bcc2
commit
b2b78a8718
@ -11,6 +11,9 @@ drv_io_config.c
|
||||
''')
|
||||
CPPPATH = [cwd]
|
||||
|
||||
if GetDepend('RT_USING_PIN'):
|
||||
src += ['drv_gpio.c']
|
||||
|
||||
if GetDepend('BSP_USING_LCD'):
|
||||
src += ['drv_lcd.c']
|
||||
|
||||
|
267
bsp/k210/driver/drv_gpio.c
Normal file
267
bsp/k210/driver/drv_gpio.c
Normal file
@ -0,0 +1,267 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2019-03-19 ZYH first version
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
#include <rtdevice.h>
|
||||
#include <fpioa.h>
|
||||
#include <gpiohs.h>
|
||||
#include "drv_gpio.h"
|
||||
#include "drv_io_config.h"
|
||||
#include <plic.h>
|
||||
#include <rthw.h>
|
||||
#include <utils.h>
|
||||
#include <string.h>
|
||||
|
||||
#define DBG_ENABLE
|
||||
#define DBG_SECTION_NAME "PIN"
|
||||
#define DBG_LEVEL DBG_WARNING
|
||||
#define DBG_COLOR
|
||||
#include <rtdbg.h>
|
||||
|
||||
#define FUNC_GPIOHS(n) (FUNC_GPIOHS0 + n)
|
||||
|
||||
static int pin_alloc_table[FPIOA_NUM_IO];
|
||||
static uint32_t free_pin = 0;
|
||||
|
||||
static int alloc_pin_channel(rt_base_t pin_index)
|
||||
{
|
||||
if(free_pin == 31)
|
||||
{
|
||||
LOG_E("no free gpiohs channel to alloc");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(pin_alloc_table[pin_index] != -1)
|
||||
{
|
||||
LOG_W("already alloc gpiohs channel for pin %d", pin_index);
|
||||
return pin_alloc_table[pin_index];
|
||||
}
|
||||
|
||||
pin_alloc_table[pin_index] = free_pin;
|
||||
free_pin++;
|
||||
|
||||
fpioa_set_function(pin_index, FUNC_GPIOHS(pin_alloc_table[pin_index]));
|
||||
return pin_alloc_table[pin_index];
|
||||
}
|
||||
|
||||
static int get_pin_channel(rt_base_t pin_index)
|
||||
{
|
||||
return pin_alloc_table[pin_index];
|
||||
}
|
||||
|
||||
static void free_pin_channel(rt_base_t pin_index)
|
||||
{
|
||||
if(pin_alloc_table[pin_index] == -1)
|
||||
{
|
||||
LOG_W("free error:not alloc gpiohs channel for pin %d", pin_index);
|
||||
return;
|
||||
}
|
||||
pin_alloc_table[pin_index] = -1;
|
||||
free_pin--;
|
||||
}
|
||||
|
||||
|
||||
static void drv_pin_mode(struct rt_device *device, rt_base_t pin, rt_base_t mode)
|
||||
{
|
||||
int pin_channel = get_pin_channel(pin);
|
||||
if(pin_channel == -1)
|
||||
{
|
||||
pin_channel = alloc_pin_channel(pin);
|
||||
if(pin_channel == -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case PIN_MODE_OUTPUT:
|
||||
gpiohs_set_drive_mode(pin_channel, GPIO_DM_OUTPUT);
|
||||
break;
|
||||
case PIN_MODE_INPUT:
|
||||
gpiohs_set_drive_mode(pin_channel, GPIO_DM_INPUT);
|
||||
break;
|
||||
case PIN_MODE_INPUT_PULLUP:
|
||||
gpiohs_set_drive_mode(pin_channel, GPIO_DM_INPUT_PULL_UP);
|
||||
break;
|
||||
case PIN_MODE_INPUT_PULLDOWN:
|
||||
gpiohs_set_drive_mode(pin_channel, GPIO_DM_INPUT_PULL_DOWN);
|
||||
break;
|
||||
default:
|
||||
LOG_E("Not support mode %d", mode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void drv_pin_write(struct rt_device *device, rt_base_t pin, rt_base_t value)
|
||||
{
|
||||
int pin_channel = get_pin_channel(pin);
|
||||
if(pin_channel == -1)
|
||||
{
|
||||
LOG_E("pin %d not set mode", pin);
|
||||
return;
|
||||
}
|
||||
gpiohs_set_pin(pin_channel, value == PIN_HIGH ? GPIO_PV_HIGH : GPIO_PV_LOW);
|
||||
}
|
||||
|
||||
static int drv_pin_read(struct rt_device *device, rt_base_t pin)
|
||||
{
|
||||
int pin_channel = get_pin_channel(pin);
|
||||
if(pin_channel == -1)
|
||||
{
|
||||
LOG_E("pin %d not set mode", pin);
|
||||
return -1;
|
||||
}
|
||||
return gpiohs_get_pin(pin_channel) == GPIO_PV_HIGH ? PIN_HIGH : PIN_LOW;
|
||||
}
|
||||
|
||||
static struct
|
||||
{
|
||||
void (*hdr)(void *args);
|
||||
void *args;
|
||||
gpio_pin_edge_t edge;
|
||||
} irq_table[32];
|
||||
|
||||
static void pin_irq(int vector, void *param)
|
||||
{
|
||||
int pin_channel = vector - IRQN_GPIOHS0_INTERRUPT;
|
||||
if(irq_table[pin_channel].edge & GPIO_PE_FALLING)
|
||||
{
|
||||
set_gpio_bit(gpiohs->fall_ie.u32, pin_channel, 0);
|
||||
set_gpio_bit(gpiohs->fall_ip.u32, pin_channel, 1);
|
||||
set_gpio_bit(gpiohs->fall_ie.u32, pin_channel, 1);
|
||||
}
|
||||
|
||||
if(irq_table[pin_channel 2019-03-18 ZYH first version].edge & GPIO_PE_RISING)
|
||||
{
|
||||
set_gpio_bit(gpiohs->rise_ie.u32, pin_channel, 0);
|
||||
set_gpio_bit(gpiohs->rise_ip.u32, pin_channel, 1);
|
||||
set_gpio_bit(gpiohs->rise_ie.u32, pin_channel, 1);
|
||||
}
|
||||
|
||||
if(irq_table[pin_channel].edge & GPIO_PE_LOW)
|
||||
{
|
||||
set_gpio_bit(gpiohs->low_ie.u32, pin_channel, 0);
|
||||
set_gpio_bit(gpiohs->low_ip.u32, pin_channel, 1);
|
||||
set_gpio_bit(gpiohs->low_ie.u32, pin_channel, 1);
|
||||
}
|
||||
|
||||
if(irq_table[pin_channel].edge & GPIO_PE_HIGH)
|
||||
{
|
||||
set_gpio_bit(gpiohs->high_ie.u32, pin_channel, 0);
|
||||
set_gpio_bit(gpiohs->high_ip.u32, pin_channel, 1);
|
||||
set_gpio_bit(gpiohs->high_ie.u32, pin_channel, 1);
|
||||
}
|
||||
if(irq_table[pin_channel].hdr)
|
||||
{
|
||||
irq_table[pin_channel].hdr(irq_table[pin_channel].args);
|
||||
}
|
||||
}
|
||||
|
||||
static rt_err_t drv_pin_attach_irq(struct rt_device *device, rt_int32_t pin,
|
||||
rt_uint32_t mode, void (*hdr)(void *args), void *args)
|
||||
{
|
||||
int pin_channel = get_pin_channel(pin);
|
||||
char irq_name[10];
|
||||
if(pin_channel == -1)
|
||||
{
|
||||
LOG_E("pin %d not set mode", pin);
|
||||
return -RT_ERROR;
|
||||
}
|
||||
irq_table[pin_channel].hdr = hdr;
|
||||
irq_table[pin_channel].args = args;
|
||||
switch (mode)
|
||||
{
|
||||
case PIN_IRQ_MODE_RISING:
|
||||
irq_table[pin_channel].edge = GPIO_PE_FALLING;
|
||||
break;
|
||||
case PIN_IRQ_MODE_FALLING:
|
||||
irq_table[pin_channel].edge = GPIO_PE_RISING;
|
||||
break;
|
||||
case PIN_IRQ_MODE_RISING_FALLING:
|
||||
irq_table[pin_channel].edge = GPIO_PE_BOTH;
|
||||
break;
|
||||
case PIN_IRQ_MODE_HIGH_LEVEL:
|
||||
irq_table[pin_channel].edge = GPIO_PE_LOW;
|
||||
break;
|
||||
case PIN_IRQ_MODE_LOW_LEVEL:
|
||||
irq_table[pin_channel].edge = GPIO_PE_HIGH;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
gpiohs_set_pin_edge(pin_channel, irq_table[pin_channel].edge);
|
||||
rt_snprintf(irq_name, sizeof irq_name, "pin%d", pin);
|
||||
rt_hw_interrupt_install(IRQN_GPIOHS0_INTERRUPT + pin_channel, pin_irq, RT_NULL, irq_name);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_err_t drv_pin_detach_irq(struct rt_device *device, rt_int32_t pin)
|
||||
{
|
||||
rt_err_t ret = RT_EOK;
|
||||
|
||||
int pin_channel = get_pin_channel(pin);
|
||||
if(pin_channel == -1)
|
||||
{
|
||||
LOG_E("pin %d not set mode", pin);
|
||||
return -RT_ERROR;
|
||||
}
|
||||
|
||||
irq_table[pin_channel].hdr = RT_NULL;
|
||||
irq_table[pin_channel].args = RT_NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static rt_err_t drv_pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint32_t enabled)
|
||||
{
|
||||
int pin_channel = get_pin_channel(pin);
|
||||
|
||||
if(pin_channel == -1)
|
||||
{
|
||||
LOG_E("pin %d not set mode", pin);
|
||||
return -RT_ERROR;
|
||||
}
|
||||
|
||||
if(enabled)
|
||||
{
|
||||
rt_hw_interrupt_umask(IRQN_GPIOHS0_INTERRUPT + pin_channel);
|
||||
}
|
||||
else
|
||||
{
|
||||
rt_hw_interrupt_mask(IRQN_GPIOHS0_INTERRUPT + pin_channel);
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
const static struct rt_pin_ops drv_pin_ops =
|
||||
{
|
||||
drv_pin_mode,
|
||||
drv_pin_write,
|
||||
drv_pin_read,
|
||||
|
||||
drv_pin_attach_irq,
|
||||
drv_pin_detach_irq,
|
||||
drv_pin_irq_enable
|
||||
};
|
||||
|
||||
int rt_hw_pin_init(void)
|
||||
{
|
||||
rt_err_t ret = RT_EOK;
|
||||
memset(pin_alloc_table, 0, sizeof pin_alloc_table);
|
||||
free_pin = GPIO_ALLOC_START;
|
||||
ret = rt_device_pin_register("pin", &drv_pin_ops, RT_NULL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
INIT_BOARD_EXPORT(rt_hw_pin_init);
|
||||
|
16
bsp/k210/driver/drv_gpio.h
Normal file
16
bsp/k210/driver/drv_gpio.h
Normal file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2019-03-19 ZYH first version
|
||||
*/
|
||||
|
||||
#ifndef DRV_GPIO_H__
|
||||
#define DRV_GPIO_H__
|
||||
|
||||
int rt_hw_pin_init(void);
|
||||
|
||||
#endif
|
@ -18,6 +18,7 @@ enum HS_GPIO_CONFIG
|
||||
#ifdef BSP_SPI1_USING_SS3
|
||||
SPI1_CS3_PIN,
|
||||
#endif
|
||||
GPIO_ALLOC_START /* index of gpio driver start */
|
||||
};
|
||||
|
||||
extern int io_config_init(void);
|
||||
|
Loading…
x
Reference in New Issue
Block a user