Merge pull request #1595 from brucechousz/master

[Bsp][STM32F10x-HAL]优化GPIO驱动减小Flash占用
This commit is contained in:
ZYH 2018-07-02 20:40:35 +08:00 committed by GitHub
commit 06789333f4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 187 additions and 150 deletions

View File

@ -18,76 +18,142 @@
#include <board.h>
#include <rtthread.h>
#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_DEFAULT {-1, 0, 0, 0}
#define __STM32_PIN(index, gpio, gpio_index) (gpio | gpio_index)
#define __STM32_PIN_DEFAULT 0
static void GPIOA_CLK_ENABLE(void)
{
#ifdef __HAL_RCC_GPIOA_CLK_ENABLE
__HAL_RCC_GPIOA_CLK_ENABLE();
#endif
}
static void GPIOB_CLK_ENABLE(void)
{
#ifdef __HAL_RCC_GPIOB_CLK_ENABLE
__HAL_RCC_GPIOB_CLK_ENABLE();
#endif
}
#if (STM32F10X_PIN_NUMBERS >36)
static void GPIOC_CLK_ENABLE(void)
{
#ifdef __HAL_RCC_GPIOC_CLK_ENABLE
__HAL_RCC_GPIOC_CLK_ENABLE();
#endif
}
#if (STM32F10X_PIN_NUMBERS >48)
#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 void GPIOD_CLK_ENABLE(void)
static GPIO_TypeDef * get_st_gpio(rt_uint16_t gpio_pin)
{
#ifdef __HAL_RCC_GPIOD_CLK_ENABLE
__HAL_RCC_GPIOD_CLK_ENABLE();
#endif
switch(gpio_pin & 0xFF00)
{
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;
}
}
#if (STM32F10X_PIN_NUMBERS >64)
static void GPIOE_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_GPIOE_CLK_ENABLE
__HAL_RCC_GPIOE_CLK_ENABLE();
#endif
switch(gpio_pin & 0xFF00)
{
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;
}
}
#if (STM32F10X_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
}
static void GPIOH_CLK_ENABLE(void)
{
#ifdef __HAL_RCC_GPIOH_CLK_ENABLE
__HAL_RCC_GPIOH_CLK_ENABLE();
#endif
}
#endif
#endif
#endif
#endif
/* STM32 GPIO driver */
struct pin_index
{
int index;
void (*rcc)(void);
GPIO_TypeDef *gpio;
uint32_t pin;
};
static const struct pin_index pins[] =
static const rt_uint16_t pins[] =
{
#if (STM32F10X_PIN_NUMBERS == 36)
__STM32_PIN_DEFAULT,
@ -361,7 +427,6 @@ static const struct pin_index pins[] =
__STM32_PIN(7, C, 13),
__STM32_PIN(8, C, 14),
__STM32_PIN(9, C, 15),
__STM32_PIN(10, F, 0),
__STM32_PIN(11, F, 1),
__STM32_PIN(12, F, 2),
@ -545,74 +610,58 @@ struct rt_pin_irq_hdr pin_irq_hdr_tab[] =
};
#define ITEM_NUM(items) sizeof(items) / sizeof(items[0])
const struct pin_index *get_pin(uint8_t pin)
static 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))
{
index = &pins[pin];
if (index->index == -1)
index = RT_NULL;
gpio_pin = pins[pin];
}
else
{
index = RT_NULL;
}
return index;
return gpio_pin;
};
void stm32_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)
rt_uint16_t gpio_pin;
gpio_pin = get_pin(pin);
if (get_st_gpio(gpio_pin) == RT_NULL)
{
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 value;
const struct pin_index *index;
value = PIN_LOW;
index = get_pin(pin);
if (index == RT_NULL)
rt_uint16_t gpio_pin;
gpio_pin = get_pin(pin);
if (get_st_gpio(gpio_pin) == RT_NULL)
{
return value;
return PIN_LOW;
}
value = HAL_GPIO_ReadPin(index->gpio, index->pin);
return value;
return HAL_GPIO_ReadPin(get_st_gpio(gpio_pin), get_st_pin(gpio_pin));
}
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;
index = get_pin(pin);
if (index == RT_NULL)
gpio_pin = get_pin(pin);
if (get_st_gpio(gpio_pin) == RT_NULL)
{
return;
}
/* GPIO Periph clock enable */
index->rcc();
drv_clock_enable(gpio_pin);
/* 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.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
if (mode == PIN_MODE_OUTPUT)
{
/* output setting */
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
}
else if (mode == PIN_MODE_INPUT)
if (mode == PIN_MODE_INPUT)
{
/* input setting: not pull. */
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
}
else if (mode == PIN_MODE_INPUT_PULLUP)
{
@ -630,54 +679,41 @@ void stm32_pin_mode(rt_device_t dev, rt_base_t pin, rt_base_t mode)
{
/* output setting: 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;
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);
rt_int32_t mapindex = gpio_pin & 0x00FF;
if (mapindex < 0 || mapindex >= ITEM_NUM(pin_irq_map))
{
return RT_NULL;
}
return &pin_irq_map[mapindex];
};
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)
{
const struct pin_index *index;
rt_uint16_t gpio_pin;
rt_base_t level;
rt_int32_t irqindex = -1;
index = get_pin(pin);
if (index == RT_NULL)
gpio_pin = get_pin(pin);
if (get_st_gpio(gpio_pin) == RT_NULL)
{
return RT_ENOSYS;
}
irqindex = bit2bitno(index->pin);
irqindex = gpio_pin & 0x00FF;
if (irqindex < 0 || irqindex >= ITEM_NUM(pin_irq_map))
{
return RT_ENOSYS;
}
level = rt_hw_interrupt_disable();
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)
pin_irq_hdr_tab[irqindex].hdr == hdr &&
pin_irq_hdr_tab[irqindex].mode == mode &&
pin_irq_hdr_tab[irqindex].args == args)
{
rt_hw_interrupt_enable(level);
return RT_EOK;
@ -697,15 +733,15 @@ rt_err_t stm32_pin_attach_irq(struct rt_device *device, rt_int32_t pin,
rt_err_t stm32_pin_detach_irq(struct rt_device *device, rt_int32_t pin)
{
const struct pin_index *index;
rt_uint16_t gpio_pin;
rt_base_t level;
rt_int32_t irqindex = -1;
index = get_pin(pin);
if (index == RT_NULL)
gpio_pin = get_pin(pin);
if (get_st_gpio(gpio_pin) == RT_NULL)
{
return RT_ENOSYS;
}
irqindex = bit2bitno(index->pin);
irqindex = gpio_pin & 0x00FF;
if (irqindex < 0 || irqindex >= ITEM_NUM(pin_irq_map))
{
return RT_ENOSYS;
@ -727,19 +763,19 @@ rt_err_t stm32_pin_detach_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_uint32_t enabled)
{
const struct pin_index *index;
rt_uint16_t gpio_pin;
const struct pin_irq_map *irqmap;
rt_base_t level;
rt_int32_t irqindex = -1;
GPIO_InitTypeDef GPIO_InitStruct;
index = get_pin(pin);
if (index == RT_NULL)
gpio_pin = get_pin(pin);
if (get_st_gpio(gpio_pin) == RT_NULL)
{
return RT_ENOSYS;
}
if (enabled == PIN_IRQ_ENABLE)
{
irqindex = bit2bitno(index->pin);
irqindex = gpio_pin & 0x00FF;
if (irqindex < 0 || irqindex >= ITEM_NUM(pin_irq_map))
{
return RT_ENOSYS;
@ -752,33 +788,31 @@ rt_err_t stm32_pin_irq_enable(struct rt_device *device, rt_base_t pin,
}
irqmap = &pin_irq_map[irqindex];
/* GPIO Periph clock enable */
index->rcc();
drv_clock_enable(gpio_pin);
/* Configure GPIO_InitStructure */
GPIO_InitStruct.Pin = index->pin;
GPIO_InitStruct.Pin = get_st_pin(gpio_pin);
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
switch (pin_irq_hdr_tab[irqindex].mode)
{
case PIN_IRQ_MODE_RISING:
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
break;
case PIN_IRQ_MODE_FALLING:
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
GPIO_InitStruct.Pull = GPIO_PULLUP;
break;
case PIN_IRQ_MODE_RISING_FALLING:
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
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_EnableIRQ(irqmap->irqno);
rt_hw_interrupt_enable(level);
}
else if (enabled == PIN_IRQ_DISABLE)
{
irqmap = get_pin_irq_map(index->pin);
irqmap = get_pin_irq_map(gpio_pin);
if (irqmap == RT_NULL)
{
return RT_ENOSYS;
@ -810,8 +844,18 @@ int rt_hw_pin_init(void)
}
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)
{
uint16_t irqno;
for (irqno = 0; irqno < 16; irqno++)
{
if ((0x01 << irqno) == GPIO_Pin)
{
break;
}
}
if (irqno == 16)
return;
if (pin_irq_hdr_tab[irqno].hdr)
{
pin_irq_hdr_tab[irqno].hdr(pin_irq_hdr_tab[irqno].args);
@ -820,7 +864,7 @@ rt_inline void pin_irq_hdr(int irqno)
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
pin_irq_hdr(bit2bitno(GPIO_Pin));
pin_irq_hdr(GPIO_Pin);
}
void EXTI0_IRQHandler(void)

View File

@ -12,14 +12,7 @@
* 2015-01-05 Bernard the first version
* 2017-11-35 ZYH update to 3.0.0
*/
#ifndef GPIO_H__
#define GPIO_H__
struct stm32_hw_pin_userdata
{
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);
#ifndef __DRV_GPIO_H__
#define __DRV_GPIO_H__
extern int rt_hw_pin_init(void);
#endif