优化GPIO驱动减小Flash占用1128->292

This commit is contained in:
zyh 2018-06-22 14:50:16 +08:00
parent ff9162a994
commit 0488daa11f
2 changed files with 180 additions and 163 deletions

View File

@ -15,97 +15,142 @@
#include <rtdevice.h> #include <rtdevice.h>
#include <board.h> #include <board.h>
#ifdef RT_USING_PIN #ifdef RT_USING_PIN
#define __STM32_PIN(index, gpio, gpio_index) {index, GPIO##gpio##_CLK_ENABLE, GPIO##gpio, GPIO_PIN_##gpio_index} #define __STM32_PIN(index, gpio, gpio_index) (gpio | gpio_index)
#define __STM32_PIN_DEFAULT {-1, 0, 0, 0} #define __STM32_PIN_DEFAULT 0
static void GPIOA_CLK_ENABLE(void) #define A (1U << 8)
#define B (2U << 8)
#define C (3U << 8)
#define D (4U << 8)
#define E (5U << 8)
#define F (6U << 8)
#define G (7U << 8)
#define H (8U << 8)
#define I (9U << 8)
#define J (10U << 8)
#define K (11U << 8)
static GPIO_TypeDef * get_st_gpio(rt_uint16_t gpio_pin)
{ {
#ifdef __HAL_RCC_GPIOA_CLK_ENABLE switch(gpio_pin >> 8)
__HAL_RCC_GPIOA_CLK_ENABLE(); {
#endif case A:
#ifdef GPIOA
return GPIOA;
#endif
case B:
#ifdef GPIOB
return GPIOB;
#endif
case C:
#ifdef GPIOC
return GPIOC;
#endif
case D:
#ifdef GPIOD
return GPIOD;
#endif
case E:
#ifdef GPIOE
return GPIOE;
#endif
case F:
#ifdef GPIOF
return GPIOF;
#endif
case G:
#ifdef GPIOG
return GPIOG;
#endif
case H:
#ifdef GPIOH
return GPIOH;
#endif
case I:
#ifdef GPIOI
return GPIOI;
#endif
case J:
#ifdef GPIOJ
return GPIOJ;
#endif
case K:
#ifdef GPIOK
return GPIOK;
#endif
default:
return RT_NULL;
}
} }
static void GPIOB_CLK_ENABLE(void) #define get_st_pin(gpio_pin) (0x01 << (gpio_pin&0xFF))
static void drv_clock_enable(rt_uint16_t gpio_pin)
{ {
#ifdef __HAL_RCC_GPIOB_CLK_ENABLE switch(gpio_pin >> 8)
__HAL_RCC_GPIOB_CLK_ENABLE(); {
#endif case A:
#ifdef __HAL_RCC_GPIOA_CLK_ENABLE
__HAL_RCC_GPIOA_CLK_ENABLE();
#endif
break;
case B:
#ifdef __HAL_RCC_GPIOB_CLK_ENABLE
__HAL_RCC_GPIOB_CLK_ENABLE();
#endif
break;
case C:
#ifdef __HAL_RCC_GPIOC_CLK_ENABLE
__HAL_RCC_GPIOC_CLK_ENABLE();
#endif
break;
case D:
#ifdef __HAL_RCC_GPIOD_CLK_ENABLE
__HAL_RCC_GPIOD_CLK_ENABLE();
#endif
break;
case E:
#ifdef __HAL_RCC_GPIOE_CLK_ENABLE
__HAL_RCC_GPIOE_CLK_ENABLE();
#endif
break;
case F:
#ifdef __HAL_RCC_GPIOF_CLK_ENABLE
__HAL_RCC_GPIOF_CLK_ENABLE();
#endif
break;
case G:
#ifdef __HAL_RCC_GPIOG_CLK_ENABLE
__HAL_RCC_GPIOG_CLK_ENABLE();
#endif
break;
case H:
#ifdef __HAL_RCC_GPIOH_CLK_ENABLE
__HAL_RCC_GPIOH_CLK_ENABLE();
#endif
break;
case I:
#ifdef __HAL_RCC_GPIOI_CLK_ENABLE
__HAL_RCC_GPIOI_CLK_ENABLE();
#endif
break;
case J:
#ifdef __HAL_RCC_GPIOJ_CLK_ENABLE
__HAL_RCC_GPIOJ_CLK_ENABLE();
#endif
break;
case K:
#ifdef __HAL_RCC_GPIOK_CLK_ENABLE
__HAL_RCC_GPIOK_CLK_ENABLE();
#endif
break;
default:
break;
}
} }
static void GPIOC_CLK_ENABLE(void)
{
#ifdef __HAL_RCC_GPIOC_CLK_ENABLE
__HAL_RCC_GPIOC_CLK_ENABLE();
#endif
}
#if (STM32F4xx_PIN_NUMBERS > 48)
static void GPIOD_CLK_ENABLE(void)
{
#ifdef __HAL_RCC_GPIOD_CLK_ENABLE
__HAL_RCC_GPIOD_CLK_ENABLE();
#endif
}
#if (STM32F4xx_PIN_NUMBERS > 64)
static void GPIOE_CLK_ENABLE(void)
{
#ifdef __HAL_RCC_GPIOE_CLK_ENABLE
__HAL_RCC_GPIOE_CLK_ENABLE();
#endif
}
#if (STM32F4xx_PIN_NUMBERS > 100)
static void GPIOF_CLK_ENABLE(void)
{
#ifdef __HAL_RCC_GPIOF_CLK_ENABLE
__HAL_RCC_GPIOF_CLK_ENABLE();
#endif
}
static void GPIOG_CLK_ENABLE(void)
{
#ifdef __HAL_RCC_GPIOG_CLK_ENABLE
__HAL_RCC_GPIOG_CLK_ENABLE();
#endif
}
#if (STM32F4xx_PIN_NUMBERS > 144)
static void GPIOH_CLK_ENABLE(void)
{
#ifdef __HAL_RCC_GPIOH_CLK_ENABLE
__HAL_RCC_GPIOH_CLK_ENABLE();
#endif
}
static void GPIOI_CLK_ENABLE(void)
{
#ifdef __HAL_RCC_GPIOI_CLK_ENABLE
__HAL_RCC_GPIOI_CLK_ENABLE();
#endif
}
#if (STM32F4xx_PIN_NUMBERS > 176)
static void GPIOJ_CLK_ENABLE(void)
{
#ifdef __HAL_RCC_GPIOJ_CLK_ENABLE
__HAL_RCC_GPIOJ_CLK_ENABLE();
#endif
}
static void GPIOK_CLK_ENABLE(void)
{
#ifdef __HAL_RCC_GPIOK_CLK_ENABLE
__HAL_RCC_GPIOK_CLK_ENABLE();
#endif
}
#endif
#endif
#endif
#endif
#endif
/* STM32 GPIO driver */ /* STM32 GPIO driver */
struct pin_index static const rt_uint16_t pins[] =
{
int index;
void (*rcc)(void);
GPIO_TypeDef *gpio;
uint32_t pin;
};
static const struct pin_index pins[] =
{ {
#if (STM32F4xx_PIN_NUMBERS == 36) #if (STM32F4xx_PIN_NUMBERS == 36)
__STM32_PIN_DEFAULT, __STM32_PIN_DEFAULT,
@ -1535,74 +1580,58 @@ struct rt_pin_irq_hdr pin_irq_hdr_tab[] =
}; };
#define ITEM_NUM(items) sizeof(items) / sizeof(items[0]) #define ITEM_NUM(items) sizeof(items) / sizeof(items[0])
const struct pin_index *get_pin(uint8_t pin) const rt_uint16_t get_pin(uint8_t pin)
{ {
const struct pin_index *index; rt_uint16_t gpio_pin = __STM32_PIN_DEFAULT;
if (pin < ITEM_NUM(pins)) if (pin < ITEM_NUM(pins))
{ {
index = &pins[pin]; gpio_pin = pins[pin];
if (index->index == -1)
index = RT_NULL;
} }
else return gpio_pin;
{
index = RT_NULL;
}
return index;
}; };
void stm32_pin_write(rt_device_t dev, rt_base_t pin, rt_base_t value) void stm32_pin_write(rt_device_t dev, rt_base_t pin, rt_base_t value)
{ {
const struct pin_index *index; rt_uint16_t gpio_pin;
index = get_pin(pin); gpio_pin = get_pin(pin);
if (index == RT_NULL) if (get_st_gpio(gpio_pin) == RT_NULL)
{ {
return; return;
} }
HAL_GPIO_WritePin(index->gpio, index->pin, (GPIO_PinState)value); HAL_GPIO_WritePin(get_st_gpio(gpio_pin), get_st_pin(gpio_pin), (GPIO_PinState)value);
} }
int stm32_pin_read(rt_device_t dev, rt_base_t pin) int stm32_pin_read(rt_device_t dev, rt_base_t pin)
{ {
int value; rt_uint16_t gpio_pin;
const struct pin_index *index; gpio_pin = get_pin(pin);
value = PIN_LOW; if (get_st_gpio(gpio_pin) == RT_NULL)
index = get_pin(pin);
if (index == RT_NULL)
{ {
return value; return PIN_LOW;
} }
value = HAL_GPIO_ReadPin(index->gpio, index->pin); return HAL_GPIO_ReadPin(get_st_gpio(gpio_pin), get_st_pin(gpio_pin));
return value;
} }
void stm32_pin_mode(rt_device_t dev, rt_base_t pin, rt_base_t mode) void stm32_pin_mode(rt_device_t dev, rt_base_t pin, rt_base_t mode)
{ {
const struct pin_index *index; rt_uint16_t gpio_pin;
GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitTypeDef GPIO_InitStruct;
index = get_pin(pin); gpio_pin = get_pin(pin);
if (index == RT_NULL) if (get_st_gpio(gpio_pin) == RT_NULL)
{ {
return; return;
} }
/* GPIO Periph clock enable */ /* GPIO Periph clock enable */
index->rcc(); drv_clock_enable(gpio_pin);
/* Configure GPIO_InitStructure */ /* Configure GPIO_InitStructure */
GPIO_InitStruct.Pin = index->pin; GPIO_InitStruct.Pin = get_st_pin(gpio_pin);
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
if (mode == PIN_MODE_OUTPUT) if (mode == PIN_MODE_INPUT)
{
/* output setting */
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
}
else if (mode == PIN_MODE_INPUT)
{ {
/* input setting: not pull. */ /* input setting: not pull. */
GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
} }
else if (mode == PIN_MODE_INPUT_PULLUP) else if (mode == PIN_MODE_INPUT_PULLUP)
{ {
@ -1620,27 +1649,13 @@ void stm32_pin_mode(rt_device_t dev, rt_base_t pin, rt_base_t mode)
{ {
/* output setting: od. */ /* output setting: od. */
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
GPIO_InitStruct.Pull = GPIO_NOPULL;
} }
HAL_GPIO_Init(index->gpio, &GPIO_InitStruct); HAL_GPIO_Init(get_st_gpio(gpio_pin), &GPIO_InitStruct);
} }
rt_inline rt_int32_t bit2bitno(rt_uint32_t bit) rt_inline const struct pin_irq_map *get_pin_irq_map(rt_uint16_t gpio_pin)
{ {
int i; rt_int32_t mapindex = gpio_pin & 0xFF;
for (i = 0; i < 32; i++)
{
if ((0x01 << i) == bit)
{
return i;
}
}
return -1;
}
rt_inline const struct pin_irq_map *get_pin_irq_map(uint32_t pinbit)
{
rt_int32_t mapindex = bit2bitno(pinbit);
if (mapindex < 0 || mapindex >= ITEM_NUM(pin_irq_map)) if (mapindex < 0 || mapindex >= ITEM_NUM(pin_irq_map))
{ {
return RT_NULL; return RT_NULL;
@ -1651,15 +1666,15 @@ rt_inline const struct pin_irq_map *get_pin_irq_map(uint32_t pinbit)
rt_err_t stm32_pin_attach_irq(struct rt_device *device, rt_int32_t pin, rt_err_t stm32_pin_attach_irq(struct rt_device *device, rt_int32_t pin,
rt_uint32_t mode, void (*hdr)(void *args), void *args) rt_uint32_t mode, void (*hdr)(void *args), void *args)
{ {
const struct pin_index *index; rt_uint16_t gpio_pin;
rt_base_t level; rt_base_t level;
rt_int32_t irqindex = -1; rt_int32_t irqindex = -1;
index = get_pin(pin); gpio_pin = get_pin(pin);
if (index == RT_NULL) if (get_st_gpio(gpio_pin) == RT_NULL)
{ {
return RT_ENOSYS; return RT_ENOSYS;
} }
irqindex = bit2bitno(index->pin); irqindex = gpio_pin&0xFF;
if (irqindex < 0 || irqindex >= ITEM_NUM(pin_irq_map)) if (irqindex < 0 || irqindex >= ITEM_NUM(pin_irq_map))
{ {
return RT_ENOSYS; return RT_ENOSYS;
@ -1688,15 +1703,15 @@ rt_err_t stm32_pin_attach_irq(struct rt_device *device, rt_int32_t pin,
rt_err_t stm32_pin_dettach_irq(struct rt_device *device, rt_int32_t pin) rt_err_t stm32_pin_dettach_irq(struct rt_device *device, rt_int32_t pin)
{ {
const struct pin_index *index; rt_uint16_t gpio_pin;
rt_base_t level; rt_base_t level;
rt_int32_t irqindex = -1; rt_int32_t irqindex = -1;
index = get_pin(pin); gpio_pin = get_pin(pin);
if (index == RT_NULL) if (get_st_gpio(gpio_pin) == RT_NULL)
{ {
return RT_ENOSYS; return RT_ENOSYS;
} }
irqindex = bit2bitno(index->pin); irqindex = gpio_pin&0xFF;
if (irqindex < 0 || irqindex >= ITEM_NUM(pin_irq_map)) if (irqindex < 0 || irqindex >= ITEM_NUM(pin_irq_map))
{ {
return RT_ENOSYS; return RT_ENOSYS;
@ -1718,19 +1733,19 @@ rt_err_t stm32_pin_dettach_irq(struct rt_device *device, rt_int32_t pin)
rt_err_t stm32_pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_err_t stm32_pin_irq_enable(struct rt_device *device, rt_base_t pin,
rt_uint32_t enabled) rt_uint32_t enabled)
{ {
const struct pin_index *index; rt_uint16_t gpio_pin;
const struct pin_irq_map *irqmap; const struct pin_irq_map *irqmap;
rt_base_t level; rt_base_t level;
rt_int32_t irqindex = -1; rt_int32_t irqindex = -1;
GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitTypeDef GPIO_InitStruct;
index = get_pin(pin); gpio_pin = get_pin(pin);
if (index == RT_NULL) if (get_st_gpio(gpio_pin) == RT_NULL)
{ {
return RT_ENOSYS; return RT_ENOSYS;
} }
if (enabled == PIN_IRQ_ENABLE) if (enabled == PIN_IRQ_ENABLE)
{ {
irqindex = bit2bitno(index->pin); irqindex = gpio_pin&0xFF;
if (irqindex < 0 || irqindex >= ITEM_NUM(pin_irq_map)) if (irqindex < 0 || irqindex >= ITEM_NUM(pin_irq_map))
{ {
return RT_ENOSYS; return RT_ENOSYS;
@ -1743,9 +1758,9 @@ rt_err_t stm32_pin_irq_enable(struct rt_device *device, rt_base_t pin,
} }
irqmap = &pin_irq_map[irqindex]; irqmap = &pin_irq_map[irqindex];
/* GPIO Periph clock enable */ /* GPIO Periph clock enable */
index->rcc(); drv_clock_enable(gpio_pin);
/* Configure GPIO_InitStructure */ /* Configure GPIO_InitStructure */
GPIO_InitStruct.Pin = index->pin; GPIO_InitStruct.Pin = get_st_pin(gpio_pin);
GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
switch (pin_irq_hdr_tab[irqindex].mode) switch (pin_irq_hdr_tab[irqindex].mode)
@ -1760,14 +1775,14 @@ rt_err_t stm32_pin_irq_enable(struct rt_device *device, rt_base_t pin,
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING; GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;
break; break;
} }
HAL_GPIO_Init(index->gpio, &GPIO_InitStruct); HAL_GPIO_Init(get_st_gpio(gpio_pin), &GPIO_InitStruct);
HAL_NVIC_SetPriority(irqmap->irqno, 5, 0); HAL_NVIC_SetPriority(irqmap->irqno, 5, 0);
HAL_NVIC_EnableIRQ(irqmap->irqno); HAL_NVIC_EnableIRQ(irqmap->irqno);
rt_hw_interrupt_enable(level); rt_hw_interrupt_enable(level);
} }
else if (enabled == PIN_IRQ_DISABLE) else if (enabled == PIN_IRQ_DISABLE)
{ {
irqmap = get_pin_irq_map(index->pin); irqmap = get_pin_irq_map(gpio_pin);
if (irqmap == RT_NULL) if (irqmap == RT_NULL)
{ {
return RT_ENOSYS; return RT_ENOSYS;
@ -1799,8 +1814,17 @@ int rt_hw_pin_init(void)
} }
INIT_BOARD_EXPORT(rt_hw_pin_init); INIT_BOARD_EXPORT(rt_hw_pin_init);
rt_inline void pin_irq_hdr(int irqno) rt_inline void pin_irq_hdr(uint16_t GPIO_Pin)
{ {
int irqno = 0;
for(irqno = 0; irqno < 16; irqno ++)
{
if((0x01 << irqno) == GPIO_Pin)
{
break;
}
}
if(irqno == 16)return;
if (pin_irq_hdr_tab[irqno].hdr) if (pin_irq_hdr_tab[irqno].hdr)
{ {
pin_irq_hdr_tab[irqno].hdr(pin_irq_hdr_tab[irqno].args); pin_irq_hdr_tab[irqno].hdr(pin_irq_hdr_tab[irqno].args);
@ -1809,7 +1833,7 @@ rt_inline void pin_irq_hdr(int irqno)
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{ {
pin_irq_hdr(bit2bitno(GPIO_Pin)); pin_irq_hdr(GPIO_Pin);
} }
void EXTI0_IRQHandler(void) void EXTI0_IRQHandler(void)

View File

@ -11,14 +11,7 @@
* Date Author Notes * Date Author Notes
* 2015-01-05 Bernard the first version * 2015-01-05 Bernard the first version
*/ */
#ifndef GPIO_H__ #ifndef __DRV_GPIO_H__
#define GPIO_H__ #define __DRV_GPIO_H__
struct stm32_hw_pin_userdata extern int rt_hw_pin_init(void);
{
int pin;
uint32_t mode;
};
#define PIN_USERDATA_END {-1,0}
extern struct stm32_hw_pin_userdata stm32_pins[];
int rt_hw_pin_init(void);
#endif #endif