2016-07-28 19:02:54 +00:00
|
|
|
//! \file stm32f4_gpio.c
|
|
|
|
//! \author tkl
|
|
|
|
//! \date Mai 8, 2012
|
|
|
|
//! \brief Source file of the stm32f4 architecture dependent gpio driver.
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <stddef.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
|
|
#include "stm32f4xx.h"
|
|
|
|
|
|
|
|
#include "gpio.h"
|
|
|
|
#include "stm32f4_gpio.h"
|
|
|
|
|
|
|
|
//! \brief Contains data for a callback for an external interrupt.
|
|
|
|
typedef struct {
|
|
|
|
gpio_ext_it_cb_t callback; //!< The call back to be executed.
|
|
|
|
void *param; //!< Parameter for the callback
|
|
|
|
}exti_cb_list_t;
|
|
|
|
|
2016-08-15 19:41:22 +00:00
|
|
|
#if 0
|
2016-07-28 19:02:54 +00:00
|
|
|
//! \brief Contains call back data for all 16 exti lines.
|
|
|
|
static struct {
|
|
|
|
exti_cb_list_t callback_list[16]; //!< Call back data list for the exti lines.
|
|
|
|
}gpio_obj;
|
|
|
|
|
|
|
|
static uint8_t gpio_bin2dec(uint16_t bin)
|
|
|
|
{
|
|
|
|
uint8_t ret = 0;
|
|
|
|
switch(bin) {
|
|
|
|
case 0x0001: ret = 0; break;
|
|
|
|
case 0x0002: ret = 1; break;
|
|
|
|
case 0x0004: ret = 2; break;
|
|
|
|
case 0x0008: ret = 3; break;
|
|
|
|
case 0x0010: ret = 4; break;
|
|
|
|
case 0x0020: ret = 5; break;
|
|
|
|
case 0x0040: ret = 6; break;
|
|
|
|
case 0x0080: ret = 7; break;
|
|
|
|
case 0x0100: ret = 8; break;
|
|
|
|
case 0x0200: ret = 9; break;
|
|
|
|
case 0x0400: ret = 10; break;
|
|
|
|
case 0x0800: ret = 11; break;
|
|
|
|
case 0x1000: ret = 12; break;
|
|
|
|
case 0x2000: ret = 13; break;
|
|
|
|
case 0x4000: ret = 14; break;
|
|
|
|
case 0x8000: ret = 15; break;
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
2016-08-15 19:41:22 +00:00
|
|
|
#endif
|
2016-07-28 19:02:54 +00:00
|
|
|
int stm32f4_gpio_open(const void *gpio)
|
|
|
|
{
|
|
|
|
struct stm32f4_gpio *this;
|
|
|
|
|
|
|
|
if(gpio == NULL)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
this = (struct stm32f4_gpio *)gpio;
|
2016-08-15 19:41:22 +00:00
|
|
|
if(this->port == GPIOA)
|
|
|
|
__HAL_RCC_GPIOA_CLK_ENABLE();
|
|
|
|
else if(this->port == GPIOB)
|
|
|
|
__HAL_RCC_GPIOB_CLK_ENABLE();
|
|
|
|
else if(this->port == GPIOC)
|
|
|
|
__HAL_RCC_GPIOC_CLK_ENABLE();
|
|
|
|
else if(this->port == GPIOD)
|
|
|
|
__HAL_RCC_GPIOD_CLK_ENABLE();
|
|
|
|
else if(this->port == GPIOE)
|
|
|
|
__HAL_RCC_GPIOE_CLK_ENABLE();
|
|
|
|
else if(this->port == GPIOF)
|
|
|
|
__HAL_RCC_GPIOF_CLK_ENABLE();
|
|
|
|
else if(this->port == GPIOG)
|
|
|
|
__HAL_RCC_GPIOG_CLK_ENABLE();
|
|
|
|
else if(this->port == GPIOH)
|
|
|
|
__HAL_RCC_GPIOH_CLK_ENABLE();
|
|
|
|
else if(this->port == GPIOI)
|
|
|
|
__HAL_RCC_GPIOI_CLK_ENABLE();
|
|
|
|
HAL_GPIO_Init(this->port, (GPIO_InitTypeDef*)this->pin);
|
2016-07-28 19:02:54 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int stm32f4_gpio_close(const void *gpio)
|
|
|
|
{
|
|
|
|
if(gpio == NULL)
|
|
|
|
return -1;
|
2016-08-15 19:41:22 +00:00
|
|
|
struct stm32f4_gpio *this = (struct stm32f4_gpio *)gpio;
|
|
|
|
HAL_GPIO_DeInit(this->port, this->pin->Pin);
|
2016-07-28 19:02:54 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
char stm32f4_gpio_read(const void *gpio)
|
|
|
|
{
|
|
|
|
struct stm32f4_gpio *this;
|
|
|
|
if(gpio == NULL)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
this = (struct stm32f4_gpio *)gpio;
|
2016-08-15 19:41:22 +00:00
|
|
|
return HAL_GPIO_ReadPin(this->port, this->pin->Pin);
|
2016-07-28 19:02:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void stm32f4_gpio_write(const void *gpio, char byte) {
|
|
|
|
struct stm32f4_gpio *this;
|
|
|
|
if(gpio == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
this = (struct stm32f4_gpio *)gpio;
|
2016-08-15 19:41:22 +00:00
|
|
|
HAL_GPIO_WritePin(this->port, this->pin->Pin, (GPIO_PinState)(byte & 0x01));
|
2016-07-28 19:02:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void stm32f4_gpio_toggle(const void *gpio)
|
|
|
|
{
|
|
|
|
struct stm32f4_gpio *this;
|
|
|
|
if(gpio == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
this = (struct stm32f4_gpio *)gpio;
|
2016-08-15 19:41:22 +00:00
|
|
|
HAL_GPIO_TogglePin(this->port, this->pin->Pin);
|
2016-07-28 19:02:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int stm32f4_gpio_set_exti_callback(const void *gpio,
|
|
|
|
const void *callback, const void *param)
|
|
|
|
{
|
2016-08-15 19:41:22 +00:00
|
|
|
#if 0
|
2016-07-28 19:02:54 +00:00
|
|
|
struct stm32f4_gpio *this;
|
|
|
|
uint8_t pin;
|
|
|
|
if((gpio == NULL) || (callback == NULL))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
this = (struct stm32f4_gpio *)gpio;
|
|
|
|
pin = gpio_bin2dec(this->exti->EXTI_Line);
|
|
|
|
|
|
|
|
gpio_obj.callback_list[pin].callback = (gpio_ext_it_cb_t)callback;
|
|
|
|
gpio_obj.callback_list[pin].param = (void*)param;
|
2016-08-15 19:41:22 +00:00
|
|
|
#endif
|
2016-07-28 19:02:54 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-08-15 19:41:22 +00:00
|
|
|
#if 0
|
2016-07-28 19:02:54 +00:00
|
|
|
//! \brief The ISR for the EXTI0_IRQn interrupt.
|
|
|
|
void EXTI0_IRQHandler(void)
|
|
|
|
{
|
|
|
|
if(gpio_obj.callback_list[0].callback != NULL) {
|
|
|
|
gpio_ext_it_cb_t cb = gpio_obj.callback_list[0].callback;
|
|
|
|
void *param = gpio_obj.callback_list[0].param;
|
|
|
|
cb(param);
|
|
|
|
}
|
|
|
|
EXTI_ClearITPendingBit(EXTI_Line0);
|
|
|
|
}
|
|
|
|
|
|
|
|
//! \brief The ISR for the EXTI1_IRQn interrupt.
|
|
|
|
void EXTI1_IRQHandler(void)
|
|
|
|
{
|
|
|
|
if(gpio_obj.callback_list[1].callback != NULL) {
|
|
|
|
gpio_ext_it_cb_t cb = gpio_obj.callback_list[1].callback;
|
|
|
|
void *param = gpio_obj.callback_list[1].param;
|
|
|
|
cb(param);
|
|
|
|
}
|
|
|
|
EXTI_ClearITPendingBit(EXTI_Line1);
|
|
|
|
}
|
|
|
|
|
|
|
|
//! \brief The ISR for the EXTI2_IRQn interrupt.
|
|
|
|
void EXTI2_IRQHandler(void)
|
|
|
|
{
|
|
|
|
if(gpio_obj.callback_list[2].callback != NULL) {
|
|
|
|
gpio_ext_it_cb_t cb = gpio_obj.callback_list[2].callback;
|
|
|
|
void *param = gpio_obj.callback_list[2].param;
|
|
|
|
cb(param);
|
|
|
|
}
|
|
|
|
EXTI_ClearITPendingBit(EXTI_Line2);
|
|
|
|
}
|
|
|
|
|
|
|
|
//! \brief The ISR for the EXTI3_IRQn interrupt.
|
|
|
|
void EXTI3_IRQHandler(void)
|
|
|
|
{
|
|
|
|
if(gpio_obj.callback_list[3].callback != NULL) {
|
|
|
|
gpio_ext_it_cb_t cb = gpio_obj.callback_list[3].callback;
|
|
|
|
void *param = gpio_obj.callback_list[3].param;
|
|
|
|
cb(param);
|
|
|
|
}
|
|
|
|
EXTI_ClearITPendingBit(EXTI_Line3);
|
|
|
|
}
|
|
|
|
|
|
|
|
//! \brief The ISR for the EXTI4_IRQn interrupt.
|
|
|
|
void EXTI4_IRQHandler(void)
|
|
|
|
{
|
|
|
|
if(gpio_obj.callback_list[4].callback != NULL) {
|
|
|
|
gpio_ext_it_cb_t cb = gpio_obj.callback_list[4].callback;
|
|
|
|
void *param = gpio_obj.callback_list[4].param;
|
|
|
|
cb(param);
|
|
|
|
}
|
|
|
|
EXTI_ClearITPendingBit(EXTI_Line4);
|
|
|
|
}
|
|
|
|
|
|
|
|
//! \brief The ISR for the EXTI9_5_IRQn interrupt.
|
|
|
|
void EXTI9_5_IRQHandler(void) {
|
|
|
|
uint32_t exti = 0;
|
|
|
|
uint8_t pin;
|
|
|
|
if(EXTI_GetITStatus(EXTI_Line6))
|
|
|
|
exti = EXTI_Line6;
|
|
|
|
|
|
|
|
pin = gpio_bin2dec(exti);
|
|
|
|
if(gpio_obj.callback_list[pin].callback != NULL) {
|
|
|
|
gpio_ext_it_cb_t cb = gpio_obj.callback_list[pin].callback;
|
|
|
|
void *param = gpio_obj.callback_list[pin].param;
|
|
|
|
cb(param);
|
|
|
|
}
|
|
|
|
EXTI_ClearITPendingBit(exti);
|
|
|
|
}
|
|
|
|
|
|
|
|
//! \brief The ISR for the EXTI15_10_IRQn interrupt.
|
|
|
|
void EXTI15_10_IRQHandler(void) {
|
|
|
|
// TODO: detect & clear pending bit
|
|
|
|
}
|
2016-08-15 19:41:22 +00:00
|
|
|
#endif
|