forked from gary/BCU
2
0
Fork 0
BCU/library/drv_stm32f4xx/drv_gpio.c

199 lines
5.0 KiB
C

/******************************************************************************
* @file drv_gpio.c
* @brief 初始化gpio接口配置
* @version V1
* @copyright
******************************************************************************/
#include "drv_gpio.h"
#include "drv_clk.h"
#include "kit_data.h"
#include "kit_debug.h"
typedef struct
{
uint16_t pin_cnt;
const GpioArray *array;
}GpioItem;
static GpioItem gpio_item;
static kit_ret_e gpio_set_pin_mode(uint32_t io, GpioMode mode);
GPIO_TypeDef * stm32_gpio[kGpioPort_End] = {GPIOA, GPIOB, GPIOC, GPIOD, GPIOE, GPIOF, GPIOG};
GpioStatus drv_gpio_get_pin_status(uint16_t idx)
{
uint32_t tmp, pin_bit, port;
GpioStatus res = kGpioStatus_Err;
KIT_ASSERT_PARAM(idx < gpio_item.pin_cnt);
if(idx < gpio_item.pin_cnt)
{
tmp = gpio_item.array[idx].io;
port = GPIO_GET_PORT(tmp);
pin_bit = GPIO_GET_PIN_BIT(tmp);
res = (GpioStatus)((stm32_gpio[port]->IDR & pin_bit) != 0);
}
return res;
}
kit_ret_e drv_gpio_set_pin_mode(uint8_t io_idx, GpioMode mode)
{
return gpio_set_pin_mode(gpio_item.array[io_idx].io, mode);
}
kit_ret_e drv_gpio_set_pin_status(uint16_t idx, GpioStatus status)
{
uint32_t tmp, pin_bit, port;
kit_ret_e res;
//KIT_ASSERT_PARAM((idx < gpio_item.pin_cnt) && (gpio_item.array[idx].mode == kGpioMode_Output_PP));
if(idx < gpio_item.pin_cnt)
{
tmp = gpio_item.array[idx].io;
port = GPIO_GET_PORT(tmp);
pin_bit = GPIO_GET_PIN_BIT(tmp);
if (status == kGpioStatus_High)
{
stm32_gpio[port]->BSRRL |= pin_bit;
}
else
{
stm32_gpio[port]->BSRRH |= pin_bit;
}
res = kKit_Ret_Ok;
}
else
{
res = kKit_Ret_ParamErr;
}
return res;
}
uint32_t drv_gpio_get_actual_io(uint16_t idx)
{
uint32_t io;
KIT_ASSERT_PARAM(idx < gpio_item.pin_cnt);
if(idx < gpio_item.pin_cnt)
{
io = gpio_item.array[idx].io;
}
else
{
io = 0xFFFFFFFF;
}
return io;
}
typedef enum
{
GPIO_Mode_IN = 0x00, /*!< GPIO Input Mode */
GPIO_Mode_OUT = 0x01, /*!< GPIO Output Mode */
GPIO_Mode_AF = 0x02, /*!< GPIO Alternate function Mode */
GPIO_Mode_AN = 0x03 /*!< GPIO Analog Mode */
}GPIOMode_TypeDef;
const uint8_t gpio_mode_value[kGpioMode_End] = {GPIO_Mode_IN, GPIO_Mode_OUT, GPIO_Mode_AF, GPIO_Mode_AN};
static kit_ret_e gpio_set_pin_mode(uint32_t io, GpioMode mode)
{
uint8_t pin, port;
kit_ret_e res;
pin = GPIO_GET_PIN(io);
port = GPIO_GET_PORT(io);
KIT_ASSERT_PARAM((port < kGpioPort_End) && (mode < kGpioMode_End));
if((port < kGpioPort_End) && (mode < kGpioMode_End))
{
//端口模式 0输入 1通用输出 2复用功能 3模拟模式
stm32_gpio[port]->MODER &= ~(0x03 << (pin << 1));
stm32_gpio[port]->MODER |= (uint32_t)gpio_mode_value[mode] << (pin << 1);
//输出模式 0输出推挽(复位默认值) 1输出开漏
//速度 50MHz
stm32_gpio[port]->OSPEEDR |= (uint32_t)0x02 << (pin << 1);
//上下拉 无
stm32_gpio[port]->PUPDR &= ~((uint32_t)0x03 << (pin << 1));
// stm32_gpio[port]->PUPDR |= ((uint32_t)0x02 << (pin << 1));
// if(mode == kGpioMode_Comm_Rx)
// {
// stm32_gpio[port]->PUPDR |= ((uint32_t)0x01 << (pin << 1));
// }
res = kKit_Ret_Ok;
}
else
{
res = kKit_Ret_ParamErr;
}
return res;
}
kit_ret_e drv_gpio_init(const GpioArray *array, uint16_t cnt)
{
uint16_t pin_bit;
uint32_t i, port, tmp;
kit_ret_e res;
KIT_ASSERT_PARAM((array != NULL) && (cnt > 0));
if((array != NULL) && (cnt > 0))
{
//打开IO口时钟
RCC->AHB1ENR |= (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOE | RCC_AHB1Periph_GPIOF | RCC_AHB1Periph_GPIOG);
for(i = 0; i < cnt; i++)
{
tmp = array[i].io;
port = GPIO_GET_PORT(tmp);
KIT_ASSERT_PARAM(port < kGpioPort_End);
pin_bit = GPIO_GET_PIN_BIT(tmp);
KIT_ASSERT_PARAM(array[i].mode < kGpioMode_End);
gpio_set_pin_mode(tmp, array[i].mode);
if(array[i].mode == kGpioMode_Output_PP)
{
if (array[i].init_st == kGpioStatus_High)
{
stm32_gpio[port]->BSRRL |= pin_bit;
}
else
{
stm32_gpio[port]->BSRRH |= pin_bit;
}
}
}
gpio_item.array = array;
gpio_item.pin_cnt = cnt;
res = kKit_Ret_Ok;
}
else
{
res = kKit_Ret_ParamErr;
}
KIT_ASSERT_RES(0, res);
return res;
}
void drv_gpio_set_af(uint8_t port, uint8_t pin, uint8_t af)
{
stm32_gpio[port]->AFR[pin >> 3] |= (uint32_t)af << ((pin % 8) << 2);
// stm32_gpio[port]->AFR[pin>>3]&=~(0X0F<<((pin&0X07)*4));
// stm32_gpio[port]->AFR[pin>>3]|=(u32)af<<((pin&0X07)*4);
}