fead support Ubiquitous/XiZi/board/xidatong bsp

This commit is contained in:
Liu_Weichao
2022-03-15 11:18:55 +08:00
parent 31697c14f2
commit 57c22182c2
121 changed files with 100392 additions and 1 deletions
@@ -0,0 +1,12 @@
config PIN_BUS_NAME
string "pin bus name"
default "pin"
config PIN_DRIVER_NAME
string "pin driver name"
default "pin_drv"
config PIN_DEVICE_NAME
string "pin device name"
default "pin_dev"
@@ -0,0 +1,3 @@
SRC_FILES := connect_gpio.c fsl_gpio.c
include $(KERNEL_ROOT)/compiler.mk
@@ -0,0 +1,544 @@
/*
* Copyright (c) 2020 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-11-06 balanceTWK first version
* 2019-04-23 WillianChan Fix GPIO serial number disorder
*/
/**
* @file connect_gpio.c
* @brief support gpio function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-25
*/
/*************************************************
File name: connect_gpio.c
Description: support gpio configure and register to bus framework
Others: take RT-Thread v4.0.2/bsp/stm32/libraries/HAL_Drivers/drv_gpio.c for references
https://github.com/RT-Thread/rt-thread/tree/v4.0.2
History:
1. Date: 2021-04-25
Author: AIIT XUOS Lab
Modification: add bus driver framework support for gpio
*************************************************/
#include <device.h>
#include <board.h>
#define STM32_PIN_NUMBERS 100 // [48, 64, 100, 144]
#define ITEM_NUM(items) sizeof(items)/sizeof(items[0])
struct PinIndex
{
int index;
GPIO_Type *gpio;
uint32_t pin;
};
struct PinIrq
{
uint8 port_source;
uint8 pin_source;
enum IRQn irq_exti_channel;
uint32 exti_line;
};
static const struct PinIndex pins[] = {
{0, GPIO1, 0},
{1, GPIO1, 1},
{2, GPIO1, 2},
{3, GPIO1, 3},
{4, GPIO1, 4},
{5, GPIO1, 5},
{6, GPIO1, 6},
{7, GPIO1, 7},
{8, GPIO1, 8},
{9, GPIO1, 9},
{10, GPIO1, 10},
{11, GPIO1, 11},
{12, GPIO1, 12},
{13, GPIO1, 13},
{14, GPIO1, 14},
{15, GPIO1, 15},
{16, GPIO2, 0},
{17, GPIO2, 1},
{18, GPIO2, 2},
{19, GPIO2, 3},
{20, GPIO2, 4},
{21, GPIO2, 5},
{22, GPIO2, 6},
{23, GPIO2, 7},
{24, GPIO2, 8},
{25, GPIO2, 9},
{26, GPIO2, 10},
{27, GPIO2, 11},
{28, GPIO2, 12},
{29, GPIO2, 13},
{30, GPIO2, 14},
{31, GPIO2, 15},
{32, GPIO3, 0},
{33, GPIO3, 1},
{34, GPIO3, 2},
{35, GPIO3, 3},
{36, GPIO3, 4},
{37, GPIO3, 5},
{38, GPIO3, 6},
{39, GPIO3, 7},
{40, GPIO3, 8},
{41, GPIO3, 9},
{42, GPIO3, 10},
{43, GPIO3, 11},
{44, GPIO3, 12},
{45, GPIO3, 13},
{46, GPIO3, 14},
{47, GPIO3, 15},
{-1, 0u, -1}
};
struct PinIrqHdr pin_irq_hdr_tab[] = {};
const struct PinIndex *GetPin(uint8_t pin)
{
const struct PinIndex *index;
if (pin < ITEM_NUM(pins)){
index = &pins[pin];
if (index->index == -1)
index = NONE;
}
else{
index = NONE;
}
return index;
}
static int32 GpioConfigMode(int mode, const struct PinIndex* index)
{
gpio_pin_config_t gpio_config;
NULL_PARAM_CHECK(index);
switch (mode)
{
case GPIO_CFG_OUTPUT:
gpio_config.direction = kGPIO_DigitalOutput;
gpio_config.interruptMode = kGPIO_NoIntmode;
break;
case GPIO_CFG_INPUT:
gpio_config.direction = kGPIO_DigitalInput;
gpio_config.interruptMode = kGPIO_NoIntmode;
break;
case GPIO_CFG_INPUT_PULLUP:
gpio_config.direction = kGPIO_DigitalInput;
gpio_config.interruptMode = kGPIO_IntRisingEdge;
break;
case GPIO_CFG_INPUT_PULLDOWN:
gpio_config.direction = kGPIO_DigitalInput;
gpio_config.interruptMode = kGPIO_IntFallingEdge;
break;
case GPIO_CFG_OUTPUT_OD:
gpio_config.direction = kGPIO_DigitalOutput;
break;
default:
break;
}
GPIO_PinInit(index->gpio, index->pin, &gpio_config);
return EOK;
}
static __inline int32 Bit2Bitnum(uint32 bit)
{
for (int i = 0; i < 32; i++){
if ((1UL << i) == bit){
return i;
}
}
return -1;
}
static __inline int32 Bitno2Bit(uint32 bitno)
{
if (bitno <= 32) {
return 1UL << bitno;
}
else {
return 0;
}
}
static const struct PinIrq *GetPinIrq(uint16_t pin)
{
static struct PinIrq irq;
const struct PinIndex* index = GetPin(pin);
if (index == NONE) {
return NONE;
}
irq.exti_line = index->pin;
irq.pin_source = Bit2Bitnum(index->pin);
irq.port_source = ((uint32_t)index->gpio - GPIO1_BASE) / (GPIO2_BASE - GPIO1_BASE);
switch (irq.pin_source)
{
case 0 :
irq.irq_exti_channel = GPIO1_INT0_IRQn;
break;
case 1 :
irq.irq_exti_channel = GPIO1_INT1_IRQn;
break;
case 2 :
irq.irq_exti_channel = GPIO1_INT2_IRQn;
break;
case 3 :
irq.irq_exti_channel = GPIO1_INT3_IRQn;
break;
case 4 :
irq.irq_exti_channel = GPIO1_INT4_IRQn;
break;
case 5 :
irq.irq_exti_channel = GPIO1_INT5_IRQn;
break;
case 6 :
irq.irq_exti_channel = GPIO1_INT6_IRQn;
break;
case 7 :
irq.irq_exti_channel = GPIO1_INT7_IRQn;
break;
default :
return NONE;
}
return &irq;
};
static int32 GpioIrqRegister(int32 pin, int32 mode, void (*hdr)(void *args), void *args)
{
const struct PinIndex* index = GetPin(pin);
int32 irqindex = -1;
irqindex = Bit2Bitnum(index->pin);
if (irqindex < 0 || irqindex >= ITEM_NUM(pin_irq_hdr_tab)) {
return -ENONESYS;
}
x_base level = CriticalAreaLock();
if (pin_irq_hdr_tab[irqindex].pin == pin &&
pin_irq_hdr_tab[irqindex].hdr == hdr &&
pin_irq_hdr_tab[irqindex].mode == mode &&
pin_irq_hdr_tab[irqindex].args == args
)
{
CriticalAreaUnLock(level);
return EOK;
}
if (pin_irq_hdr_tab[irqindex].pin != -1) {
CriticalAreaUnLock(level);
return -EDEV_BUSY;
}
pin_irq_hdr_tab[irqindex].pin = pin;
pin_irq_hdr_tab[irqindex].hdr = hdr;
pin_irq_hdr_tab[irqindex].mode = mode;
pin_irq_hdr_tab[irqindex].args = args;
CriticalAreaUnLock(level);
return EOK;
}
static uint32 GpioIrqFree(int32 pin)
{
const struct PinIndex* index = GetPin(pin);
int32 irqindex = -1;
irqindex = Bit2Bitnum(index->pin);
if (irqindex < 0 || irqindex >= ITEM_NUM(pin_irq_hdr_tab)) {
return -ENONESYS;
}
x_base level = CriticalAreaLock();
if (pin_irq_hdr_tab[irqindex].pin == -1){
CriticalAreaUnLock(level);
return EOK;
}
pin_irq_hdr_tab[irqindex].pin = -1;
pin_irq_hdr_tab[irqindex].hdr = NONE;
pin_irq_hdr_tab[irqindex].mode = 0;
pin_irq_hdr_tab[irqindex].args = NONE;
CriticalAreaUnLock(level);
return EOK;
}
static int32 GpioIrqEnable(x_base pin)
{
const struct PinIndex* index = GetPin(pin);
int32 irqindex = -1;
const struct PinIrq *irq;
gpio_pin_config_t gpio_config;
irqindex = Bit2Bitnum(index->pin);
if (irqindex < 0 || irqindex >= ITEM_NUM(pin_irq_hdr_tab)){
return -ENONESYS;
}
x_base level = CriticalAreaLock();
if (pin_irq_hdr_tab[irqindex].pin == -1) {
CriticalAreaUnLock(level);
return -ENONESYS;
}
irq = GetPinIrq(pin);
if (irq == NONE){
CriticalAreaUnLock(level);
return -ENONESYS;
}
switch (pin_irq_hdr_tab[irqindex].mode)
{
case GPIO_IRQ_EDGE_RISING:
gpio_config.direction = kGPIO_DigitalInput;
gpio_config.interruptMode = kGPIO_IntRisingEdge;
break;
case GPIO_IRQ_EDGE_FALLING:
gpio_config.direction = kGPIO_DigitalInput;
gpio_config.interruptMode = kGPIO_IntFallingEdge;
break;
case GPIO_IRQ_EDGE_BOTH:
gpio_config.direction = kGPIO_DigitalInput;
gpio_config.interruptMode = kGPIO_IntRisingOrFallingEdge;
break;
}
GPIO_PinInit(index->gpio, index->pin, &gpio_config);
GPIO_PortEnableInterrupts(index->gpio, index->pin);
CriticalAreaUnLock(level);
return EOK;
}
static int32 GpioIrqDisable(x_base pin)
{
const struct PinIndex* index = GetPin(pin);
const struct PinIrq *irq;
irq = GetPinIrq(index->pin);
NULL_PARAM_CHECK(irq);
GPIO_PortDisableInterrupts(index->gpio, index->pin);
return EOK;
}
static uint32 Stm32PinConfigure(struct PinParam *param)
{
NULL_PARAM_CHECK(param);
int ret = EOK;
const struct PinIndex *index = GetPin(param->pin);
switch(param->cmd)
{
case GPIO_CONFIG_MODE:
GpioConfigMode(param->mode, index);
break;
case GPIO_IRQ_REGISTER:
ret = GpioIrqRegister(param->pin,param->irq_set.irq_mode,param->irq_set.hdr,param->irq_set.args);
break;
case GPIO_IRQ_FREE:
ret = GpioIrqFree(param->pin);
break;
case GPIO_IRQ_ENABLE:
ret = GpioIrqEnable(param->pin);
break;
case GPIO_IRQ_DISABLE:
ret = GpioIrqDisable(param->pin);
break;
default:
ret = -EINVALED;
break;
}
return ret;
}
static uint32 Stm32PinInit(void)
{
static x_bool pin_init_flag = RET_FALSE;
if (!pin_init_flag) {
pin_init_flag = RET_TRUE;
}
return EOK;
}
static uint32 Stm32GpioDrvConfigure(void *drv, struct BusConfigureInfo *configure_info)
{
NULL_PARAM_CHECK(drv);
NULL_PARAM_CHECK(configure_info);
x_err_t ret = EOK;
struct PinParam *param;
switch (configure_info->configure_cmd)
{
case OPE_INT:
ret = Stm32PinInit();
break;
case OPE_CFG:
param = (struct PinParam *)configure_info->private_data;
ret = Stm32PinConfigure(param);
break;
default:
break;
}
return ret;
}
uint32 Stm32PinWrite(void *dev, struct BusBlockWriteParam *write_param)
{
NULL_PARAM_CHECK(dev);
NULL_PARAM_CHECK(write_param);
struct PinStat *pinstat = (struct PinStat *)write_param->buffer;
const struct PinIndex* index = GetPin(pinstat->pin);
NULL_PARAM_CHECK(index);
if (GPIO_LOW == pinstat->val) {
GPIO_PinWrite(index->gpio, index->pin, 0);
} else {
GPIO_PinWrite(index->gpio, index->pin, 1);
}
return EOK;
}
uint32 Stm32PinRead(void *dev, struct BusBlockReadParam *read_param)
{
NULL_PARAM_CHECK(dev);
NULL_PARAM_CHECK(read_param);
struct PinStat *pinstat = (struct PinStat *)read_param->buffer;
const struct PinIndex* index = GetPin(pinstat->pin);
NULL_PARAM_CHECK(index);
if(GPIO_PinRead(index->gpio, index->pin) == GPIO_LOW) {
pinstat->val = GPIO_LOW;
} else {
pinstat->val = GPIO_HIGH;
}
return pinstat->val;
}
static const struct PinDevDone dev_done =
{
.open = NONE,
.close = NONE,
.write = Stm32PinWrite,
.read = Stm32PinRead,
};
int Stm32HwGpioInit(void)
{
x_err_t ret = EOK;
static struct PinBus pin;
ret = PinBusInit(&pin, PIN_BUS_NAME);
if (ret != EOK) {
KPrintf("gpio bus init error %d\n", ret);
return ERROR;
}
static struct PinDriver drv;
drv.configure = &Stm32GpioDrvConfigure;
ret = PinDriverInit(&drv, PIN_DRIVER_NAME, NONE);
if (ret != EOK) {
KPrintf("pin driver init error %d\n", ret);
return ERROR;
}
ret = PinDriverAttachToBus(PIN_DRIVER_NAME, PIN_BUS_NAME);
if (ret != EOK) {
KPrintf("pin driver attach error %d\n", ret);
return ERROR;
}
static struct PinHardwareDevice dev;
dev.dev_done = &dev_done;
ret = PinDeviceRegister(&dev, NONE, PIN_DEVICE_NAME);
if (ret != EOK) {
KPrintf("pin device register error %d\n", ret);
return ERROR;
}
ret = PinDeviceAttachToBus(PIN_DEVICE_NAME, PIN_BUS_NAME);
if (ret != EOK) {
KPrintf("pin device register error %d\n", ret);
return ERROR;
}
return ret;
}
static __inline void PinIrqHdr(int irqno)
{
const struct PinIndex* index = GetPin(irqno);
const struct PinIrq *irq;
irq = GetPinIrq(index->pin);
NULL_PARAM_CHECK(irq);
GPIO_ClearPinsInterruptFlags(index->gpio, index->pin);
if (pin_irq_hdr_tab[irqno].hdr){
pin_irq_hdr_tab[irqno].hdr(pin_irq_hdr_tab[irqno].args);
}
}
void EXTI0_IRQHandler(int irq_num, void *arg)
{
PinIrqHdr(0);
}
DECLARE_HW_IRQ(GPIO1_INT0_IRQn, EXTI0_IRQHandler, NONE);
void EXTI1_IRQHandler(int irq_num, void *arg)
{
PinIrqHdr(1);
}
DECLARE_HW_IRQ(GPIO1_INT1_IRQn, EXTI1_IRQHandler, NONE);
void EXTI2_IRQHandler(int irq_num, void *arg)
{
PinIrqHdr(2);
}
DECLARE_HW_IRQ(GPIO1_INT2_IRQn, EXTI2_IRQHandler, NONE);
void EXTI3_IRQHandler(int irq_num, void *arg)
{
PinIrqHdr(3);
}
DECLARE_HW_IRQ(GPIO1_INT3_IRQn, EXTI3_IRQHandler, NONE);
void EXTI4_IRQHandler(int irq_num, void *arg)
{
PinIrqHdr(4);
}
DECLARE_HW_IRQ(GPIO1_INT4_IRQn, EXTI4_IRQHandler, NONE);
void EXTI5_IRQHandler(int irq_num, void *arg)
{
PinIrqHdr(5);
}
DECLARE_HW_IRQ(GPIO1_INT5_IRQn, EXTI5_IRQHandler, NONE);
void EXTI6_IRQHandler(int irq_num, void *arg)
{
PinIrqHdr(6);
}
DECLARE_HW_IRQ(GPIO1_INT6_IRQn, EXTI6_IRQHandler, NONE);
void EXTI7_IRQHandler(int irq_num, void *arg)
{
PinIrqHdr(7);
}
DECLARE_HW_IRQ(GPIO1_INT7_IRQn, EXTI7_IRQHandler, NONE);
@@ -0,0 +1,171 @@
/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_gpio.h"
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.igpio"
#endif
/*******************************************************************************
* Variables
******************************************************************************/
/* Array of GPIO peripheral base address. */
static GPIO_Type *const s_gpioBases[] = GPIO_BASE_PTRS;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Array of GPIO clock name. */
static const clock_ip_name_t s_gpioClock[] = GPIO_CLOCKS;
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/*******************************************************************************
* Prototypes
******************************************************************************/
/*!
* @brief Gets the GPIO instance according to the GPIO base
*
* @param base GPIO peripheral base pointer(PTA, PTB, PTC, etc.)
* @retval GPIO instance
*/
static uint32_t GPIO_GetInstance(GPIO_Type *base);
/*******************************************************************************
* Code
******************************************************************************/
static uint32_t GPIO_GetInstance(GPIO_Type *base)
{
uint32_t instance;
/* Find the instance index from base address mappings. */
for (instance = 0; instance < ARRAY_SIZE(s_gpioBases); instance++)
{
if (s_gpioBases[instance] == base)
{
break;
}
}
assert(instance < ARRAY_SIZE(s_gpioBases));
return instance;
}
/*!
* brief Initializes the GPIO peripheral according to the specified
* parameters in the initConfig.
*
* param base GPIO base pointer.
* param pin Specifies the pin number
* param initConfig pointer to a ref gpio_pin_config_t structure that
* contains the configuration information.
*/
void GPIO_PinInit(GPIO_Type *base, uint32_t pin, const gpio_pin_config_t *Config)
{
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Enable GPIO clock. */
uint32_t instance = GPIO_GetInstance(base);
/* If The clock IP is valid, enable the clock gate. */
if ((instance < ARRAY_SIZE(s_gpioClock)) && (kCLOCK_IpInvalid != s_gpioClock[instance]))
{
CLOCK_EnableClock(s_gpioClock[instance]);
}
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/* Register reset to default value */
base->IMR &= ~(1U << pin);
/* Configure GPIO pin direction */
if (Config->direction == kGPIO_DigitalInput)
{
base->GDIR &= ~(1U << pin);
}
else
{
GPIO_PinWrite(base, pin, Config->outputLogic);
base->GDIR |= (1U << pin);
}
/* Configure GPIO pin interrupt mode */
GPIO_SetPinInterruptConfig(base, pin, Config->interruptMode);
}
/*!
* brief Sets the output level of the individual GPIO pin to logic 1 or 0.
*
* param base GPIO base pointer.
* param pin GPIO port pin number.
* param output GPIOpin output logic level.
* - 0: corresponding pin output low-logic level.
* - 1: corresponding pin output high-logic level.
*/
void GPIO_PinWrite(GPIO_Type *base, uint32_t pin, uint8_t output)
{
assert(pin < 32);
if (output == 0U)
{
base->DR &= ~(1U << pin); /* Set pin output to low level.*/
}
else
{
base->DR |= (1U << pin); /* Set pin output to high level.*/
}
}
/*!
* brief Sets the current pin interrupt mode.
*
* param base GPIO base pointer.
* param pin GPIO port pin number.
* param pininterruptMode pointer to a ref gpio_interrupt_mode_t structure
* that contains the interrupt mode information.
*/
void GPIO_PinSetInterruptConfig(GPIO_Type *base, uint32_t pin, gpio_interrupt_mode_t pinInterruptMode)
{
volatile uint32_t *icr;
uint32_t icrShift;
icrShift = pin;
/* Register reset to default value */
base->EDGE_SEL &= ~(1U << pin);
if (pin < 16)
{
icr = &(base->ICR1);
}
else
{
icr = &(base->ICR2);
icrShift -= 16;
}
switch (pinInterruptMode)
{
case (kGPIO_IntLowLevel):
*icr &= ~(3U << (2 * icrShift));
break;
case (kGPIO_IntHighLevel):
*icr = (*icr & (~(3U << (2 * icrShift)))) | (1U << (2 * icrShift));
break;
case (kGPIO_IntRisingEdge):
*icr = (*icr & (~(3U << (2 * icrShift)))) | (2U << (2 * icrShift));
break;
case (kGPIO_IntFallingEdge):
*icr |= (3U << (2 * icrShift));
break;
case (kGPIO_IntRisingOrFallingEdge):
base->EDGE_SEL |= (1U << pin);
break;
default:
break;
}
}