|
/*
* Copyright (c) 2021-2022, Meta Coding
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-02-10 Jone.Chen first version
*/
#ifndef __DRV_GPIO_H__
#define __DRV_GPIO_H__
#include <board.h>
#include <rtthread.h>
#include "HAL_gpio.h"
//PORT宏定义
#define __TKM32_PORT(port) GPIO##port##_BASE
#define PPORT(PORTx) ( ((rt_base_t)__TKM32_PORT(PORTx) - (rt_base_t)GPIOA_BASE)/(0x0400UL) )
//__TKM32_PORT(A) ---展开宏---> GPIOA_BASE
//PPORT(A) ---展开宏---> ( ((rt_base_t)GPIOA_BASE - (rt_base_t)GPIOA_BASE)/(0x0400UL) ) ------> 0
//PIN 索引 宏定义
#define GET_PIN(PORTx,PIN) (PPORT(PORTx)<3?(16*PPORT(PORTx)+PIN):PPORT(PORTx)==3?40+PIN:55+PIN)
//GET_PIN(A,0) ---展开宏---> (0<3?(16*0+0):0==3?40+0:55+0) ------> 0
//因TKM32 gpio不是每个都是16个IO,不能全用(16*PPORT(PORTx)+PIN)方式获取索引
//pins[]数组索引的宏定义
#define __TKM32_PIN(index, gpio, gpio_index) \
{ \
index, GPIO##gpio, GPIO_Pin_##gpio_index \
}
//__TKM32_PIN(0 , A, 0 ) ---展开宏---> 0,GPIOA,GPIO_Pin_0
/* TKM32 GPIO driver */
//pins[] 结构体
struct pin_index
{
int index;
GPIO_TypeDef *gpio;
uint32_t pin;
};
int rt_hw_pin_init(void);
#endif /* __DRV_GPIO_H__ */
/*
* Copyright (c) 2021-2022, Meta Coding
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-02-10 Jone.Chen first version
*/
#include <board.h>
#include "drv_gpio.h"
#include <drivers/pin.h>
#include <rthw.h>
#ifdef RT_USING_PIN
//存储所有Pin的数组
static const struct pin_index pins[] =
{
#if defined(GPIOA)
__TKM32_PIN(0 , A, 0 ), //PA0 索引0
__TKM32_PIN(1 , A, 1 ), //PA1 索引1
#endif /* defined(GPIOA) */
//..............
#if defined(GPIOE)
__TKM32_PIN(78, E, 23), //PE23 索引78
#endif /* defined(GPIOE) */
};
//计算Pin总数
#define ITEM_NUM(items) sizeof(items) / sizeof(items[0])
//用索引值 pin 获取一个GPIO_Pin的索引结构体
static const struct pin_index *get_pin(uint8_t pin)
{
const struct pin_index *index;
if (pin < ITEM_NUM(pins))
{
index = &pins[pin];
if (index->index == -1)
index = RT_NULL;
}
else
{
index = RT_NULL;
}
return index;
};
static void tkm32_pin_write(rt_device_t dev, rt_base_t pin, rt_base_t value)
{
const struct pin_index *index;
index = get_pin(pin);
if (index == RT_NULL)
{
return;
}
//控制gpio硬件动作
GPIO_WriteBit(index->gpio, index->pin, (BitAction)value);
}
static int tkm32_pin_read(rt_device_t dev, rt_base_t pin)
{
int value;
const struct pin_index *index;
value = PIN_LOW;
index = get_pin(pin);
if (index == RT_NULL)
{
return value;
}
//读取gpio硬件值
value = GPIO_ReadInputDataBit(index->gpio, index->pin);
return value;
}
static void tkm32_pin_mode(rt_device_t dev, rt_base_t pin, rt_base_t mode)
{
const struct pin_index *index;
GPIO_InitTypeDef GPIO_InitStruct;
index = get_pin(pin);
if (index == RT_NULL)
{
return;
}
/* Configure GPIO_InitStructure */
GPIO_InitStruct.GPIO_Pin = index->pin;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
if (mode == PIN_MODE_OUTPUT)
{
/* output setting */
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
}
else if (mode == PIN_MODE_INPUT)
{
/* input setting: not pull. */
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
}
else if (mode == PIN_MODE_INPUT_PULLUP)
{
/* input setting: pull up. */
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;//上拉输入
}
else if (mode == PIN_MODE_INPUT_PULLDOWN)
{
/* input setting: pull down. */
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPD;//下拉输入
}
else if (mode == PIN_MODE_OUTPUT_OD)
{
/* output setting: od. */
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_OD;//开漏输入
}
GPIO_Init(index->gpio, &GPIO_InitStruct);
}
rt_inline rt_int32_t bit2bitno(rt_uint32_t bit)
{
int i;
for (i = 0; i < 32; i++)
{
if ((0x01 << i) == bit)
{
return i;
}
}
return -1;
}
const static struct rt_pin_ops _tkm32_pin_ops = //填充ops结构体
{
tkm32_pin_mode,
tkm32_pin_write,
tkm32_pin_read,
};
int rt_hw_pin_init(void)
{
#if defined(GPIOA)
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);//使能时钟
#endif
//..............
return rt_device_pin_register("pin", &_tkm32_pin_ops, RT_NULL);//注册驱动
}
INIT_BOARD_EXPORT(rt_hw_pin_init);
#endif /* RT_USING_PIN */