initial commit
This commit is contained in:
5
source/firmware/arch/stm32f4xx/driver/driver.mk
Executable file
5
source/firmware/arch/stm32f4xx/driver/driver.mk
Executable file
@@ -0,0 +1,5 @@
|
||||
CHECK_FOLDER += firmware/arch/stm32f4xx/driver
|
||||
SUB_FOLDER += firmware/arch/stm32f4xx/driver
|
||||
INCLUDES += firmware/arch/stm32f4xx/driver/include
|
||||
DOC_SRC += firmware/arch/stm32f4xx/driver
|
||||
DOC_SRC += firmware/arch/stm32f4xx/driver/include
|
49
source/firmware/arch/stm32f4xx/driver/include/stm32_sys_tick.h
Executable file
49
source/firmware/arch/stm32f4xx/driver/include/stm32_sys_tick.h
Executable file
@@ -0,0 +1,49 @@
|
||||
//! \file stm32_sys_tick.h
|
||||
//! \author tkl
|
||||
//! \date Feb 15, 2012
|
||||
//! \brief Header file of the stm32f10x architecture dependent sys tick timer implementation.
|
||||
#ifndef STM32_SYS_TICK_H_
|
||||
#define STM32_SYS_TICK_H_
|
||||
|
||||
#include "timer.h"
|
||||
|
||||
typedef void* (*stm32_sys_tick_cb_t)(void*); //!< callback for the external interrupt
|
||||
|
||||
//! \brief Type of sys tick base time.
|
||||
enum stm32_sys_tick_time_base {
|
||||
STM32_SYS_TICK_TIME_BASE_NONE = 0, //!< Not init
|
||||
STM32_SYS_TICK_TIME_BASE_US, //!< Tick time = 1 us.
|
||||
STM32_SYS_TICK_TIME_BASE_MS //!< Tick time = 1 ms.
|
||||
};
|
||||
|
||||
//! \brief The sys tick device.
|
||||
struct stm32_sys_tick {
|
||||
const enum stm32_sys_tick_time_base *tick_time_base; //!< time base for the system tick
|
||||
stm32_sys_tick_cb_t sys_tick_cb; //!< callback for the sys tick interrupt
|
||||
void *sys_tick_cb_param; //!< parameter for the callback
|
||||
};
|
||||
|
||||
//! \brief Open a sys tick timer.
|
||||
//! \param sys_tick The sys tick to open. Must be of type const stm32_sys_tick_t*.
|
||||
//! \return -1 in error case.
|
||||
int stm32_sys_tick_open(const void *sys_tick);
|
||||
|
||||
//! \brief Close a sys tick timer.
|
||||
//! \param sys_tick The sys tick to close. Must be of type const stm32_sys_tick_t*.
|
||||
//! \return -1 in error case.
|
||||
int stm32_sys_tick_close(const void *sys_tick);
|
||||
|
||||
//! \brief Set the call back for a sys tick timer.
|
||||
//! \param sys_tick The sys tick to open. Mus be of type const stm32_sys_tick_t*.
|
||||
//! \param callback The function pointer of the call back function.
|
||||
//! \param param The parameter for the call back function.
|
||||
//! \return -1 in error case.
|
||||
int stm32_sys_tick_set_cb(const void *sys_tick, const void *callback, const void *param);
|
||||
|
||||
static const struct timer_fp timer_fp = {
|
||||
stm32_sys_tick_open,
|
||||
stm32_sys_tick_close,
|
||||
stm32_sys_tick_set_cb
|
||||
};
|
||||
|
||||
#endif /* STM32_SYS_TICK_H_ */
|
62
source/firmware/arch/stm32f4xx/driver/include/stm32f4_gpio.h
Executable file
62
source/firmware/arch/stm32f4xx/driver/include/stm32f4_gpio.h
Executable file
@@ -0,0 +1,62 @@
|
||||
//! \file stm32f4_gpio.h
|
||||
//! \author tkl
|
||||
//! \date Mai 8, 2012
|
||||
//! \brief Header file of the stm32f4xx architecture dependent gpio driver.
|
||||
#ifndef STM32F4_GPIO_H_
|
||||
#define STM32F4_GPIO_H_
|
||||
|
||||
//! callback for the external interrupt
|
||||
typedef void* (*gpio_ext_it_cb_t)(void*);
|
||||
|
||||
//! \brief stm32f4 gpio device
|
||||
struct stm32f4_gpio {
|
||||
GPIO_TypeDef *port; //!< Gpio port
|
||||
const GPIO_InitTypeDef *pin; //!< Gpio pin
|
||||
const EXTI_InitTypeDef *exti; //!< Gpio exit it (could be NULL)
|
||||
const NVIC_InitTypeDef *nvic; //!< Gpio nvic (could be NULL)
|
||||
gpio_ext_it_cb_t ext_it_cb; //!< Gpio ext it callback (could be NULL)
|
||||
void *param; //!< Parameter for the callback
|
||||
};
|
||||
|
||||
//! \brief Open a gpio.
|
||||
//! \param gpio The gpio to open. Must be of type stm32f4_gpio_t.
|
||||
//! \retval -1 in error case.
|
||||
int stm32f4_gpio_open(const void *gpio);
|
||||
|
||||
//! \brief Close a gpio.
|
||||
//! \param gpio The gpio to close. Must be of type stm32f4_gpio_t.
|
||||
//! \retval -1 in error case.
|
||||
int stm32f4_gpio_close(const void *gpio);
|
||||
|
||||
//! \brief Read a gpio.
|
||||
//! \param gpio The gpio to read. Must be of type stm32f4_gpio_t.
|
||||
//! \return read out value.
|
||||
char stm32f4_gpio_read(const void *gpio);
|
||||
|
||||
//! \brief Write to a gpio.
|
||||
//! \param gpio The gpio to write. Must be of type stm32f4_gpio_t.
|
||||
//! \param byte The data to write.
|
||||
void stm32f4_gpio_write(const void *gpio, char byte);
|
||||
|
||||
//! \brief Toggle a gpio.
|
||||
//! \param gpio The gpio to read. Must be of type stm32f4_gpio_t.
|
||||
void stm32f4_gpio_toggle(const void *gpio);
|
||||
|
||||
//! \brief Set the callback for a gpio pin external interrupt.
|
||||
//! \param gpio The gpio to set call back for. Must be of type stm32f4_gpio_t.
|
||||
//! \param callback The function pointer to call back.
|
||||
//! \param param The parameter for the call back.
|
||||
//! \retval -1 in error case.
|
||||
int stm32f4_gpio_set_exti_callback(const void *gpio, const void *callback,
|
||||
const void *param);
|
||||
|
||||
static const struct gpio_fp gpio_fp = {
|
||||
stm32f4_gpio_open,
|
||||
stm32f4_gpio_close,
|
||||
stm32f4_gpio_read,
|
||||
stm32f4_gpio_write,
|
||||
stm32f4_gpio_toggle,
|
||||
stm32f4_gpio_set_exti_callback
|
||||
};
|
||||
|
||||
#endif /* STM32F4_GPIO_H_ */
|
65
source/firmware/arch/stm32f4xx/driver/include/stm32f4_uart.h
Normal file
65
source/firmware/arch/stm32f4xx/driver/include/stm32f4_uart.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* stm32_uart.h
|
||||
*
|
||||
* Created on: Jul 24, 2016
|
||||
* Author: tkl
|
||||
*/
|
||||
|
||||
#ifndef SOURCE_FIRMWARE_ARCH_STM32F4XX_DRIVER_UART_STM32_UART_H_
|
||||
#define SOURCE_FIRMWARE_ARCH_STM32F4XX_DRIVER_UART_STM32_UART_H_
|
||||
|
||||
#include "driver.h"
|
||||
#include "uart.h"
|
||||
|
||||
//! \brief Stm32f4 uart device.
|
||||
struct stm32f4_uart {
|
||||
const GPIO_InitTypeDef *gpio_init;
|
||||
GPIO_TypeDef *gpio_port;
|
||||
uint8_t pin_src_rx;
|
||||
uint8_t pin_src_tx;
|
||||
const USART_InitTypeDef *usart_init;
|
||||
USART_TypeDef *usart_port;
|
||||
uint16_t usart_it_select;
|
||||
const NVIC_InitTypeDef *nvic_init;
|
||||
};
|
||||
|
||||
//! \brief Open an uart device.
|
||||
//! \param this The uart to open.
|
||||
//! \retval -1 in error case.
|
||||
int stm32f4_uart_open(const void *this);
|
||||
|
||||
//! \brief Close an uart device.
|
||||
//! \param this The uart to close.
|
||||
//! \retval -1 in error case.
|
||||
int stm32f4_uart_close(const void *this);
|
||||
|
||||
//! \brief Read from an uart device.
|
||||
//! \param this The uart to read from.
|
||||
//! \param buffer The buffer to read to.
|
||||
//! \param len The length of the buffer.
|
||||
//! \retval -1 in error case, otherwise number of read characters.
|
||||
int stm32f4_uart_read(const void *this, char *buffer, int len);
|
||||
|
||||
//! \brief Write to an uart device.
|
||||
//! \param this The uart to write to.
|
||||
//! \param buffer The buffer to write.
|
||||
//! \param len The number of characters to write.
|
||||
//! \retval -1 in error case, otherwise number of written characters.
|
||||
int stm32f4_uart_write(const void *this, const char *buffer, int len);
|
||||
|
||||
//! \brief Set a callback for interrupt handling of the uart.
|
||||
//! \param this The uart.
|
||||
//! \param callback The callback to execute in interrupt case.
|
||||
//! \param param The argument for the callback.
|
||||
//! \retval -1 in error case.
|
||||
int stm32f4_uart_set_cb(const void *this, const void *callback, const void *param);
|
||||
|
||||
static const struct uart_fp stm32f4_uart_fp = {
|
||||
stm32f4_uart_open,
|
||||
stm32f4_uart_close,
|
||||
stm32f4_uart_read,
|
||||
stm32f4_uart_write,
|
||||
stm32f4_uart_set_cb
|
||||
};
|
||||
|
||||
#endif /* SOURCE_FIRMWARE_ARCH_STM32F4XX_DRIVER_UART_STM32_UART_H_ */
|
77
source/firmware/arch/stm32f4xx/driver/stm32_sys_tick.c
Executable file
77
source/firmware/arch/stm32f4xx/driver/stm32_sys_tick.c
Executable file
@@ -0,0 +1,77 @@
|
||||
//! \file stm32_sys_tick.c
|
||||
//! \author tkl
|
||||
//! \date Feb 15, 2012
|
||||
//! \brief Source file of the stm32f10x architecture dependent sys tick timer implementation.
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "stm32f4xx.h"
|
||||
|
||||
#include "stm32_sys_tick.h"
|
||||
#include "stm32f4xx_isr.h"
|
||||
|
||||
struct stm32_sys_tick_obj {
|
||||
stm32_sys_tick_cb_t sys_tick_cb;
|
||||
void *sys_tick_cb_param;
|
||||
};
|
||||
|
||||
static struct stm32_sys_tick_obj stm32_sys_tick_obj;
|
||||
|
||||
int stm32_sys_tick_open(const void *sys_tick) {
|
||||
if(sys_tick == NULL)
|
||||
return -1;
|
||||
|
||||
struct stm32_sys_tick *this = (struct stm32_sys_tick *)sys_tick;
|
||||
uint32_t div = 1000;
|
||||
switch(*this->tick_time_base) {
|
||||
case STM32_SYS_TICK_TIME_BASE_US:
|
||||
div = 1000000;
|
||||
break;
|
||||
|
||||
case STM32_SYS_TICK_TIME_BASE_MS:
|
||||
div = 1000;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
if(SysTick_Config(SystemCoreClock / div))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int stm32_sys_tick_close(const void *sys_tick)
|
||||
{
|
||||
if(sys_tick == NULL)
|
||||
return -1;
|
||||
|
||||
SysTick->CTRL = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int stm32_sys_tick_set_cb(const void *sys_tick, const void *callback, const void *param)
|
||||
{
|
||||
if((sys_tick == NULL) || (callback == NULL))
|
||||
return -1;
|
||||
|
||||
stm32_sys_tick_obj.sys_tick_cb = (stm32_sys_tick_cb_t)callback;
|
||||
stm32_sys_tick_obj.sys_tick_cb_param = (void*)param;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SysTick_Handler(void)
|
||||
{
|
||||
enter_isr();
|
||||
|
||||
if(stm32_sys_tick_obj.sys_tick_cb != NULL) {
|
||||
stm32_sys_tick_cb_t cb = stm32_sys_tick_obj.sys_tick_cb;
|
||||
void *param = stm32_sys_tick_obj.sys_tick_cb_param;
|
||||
cb(param);
|
||||
}
|
||||
|
||||
exit_isr();
|
||||
}
|
260
source/firmware/arch/stm32f4xx/driver/stm32f4_gpio.c
Executable file
260
source/firmware/arch/stm32f4xx/driver/stm32f4_gpio.c
Executable file
@@ -0,0 +1,260 @@
|
||||
//! \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;
|
||||
|
||||
//! \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;
|
||||
}
|
||||
|
||||
static void gpio_init(const struct stm32f4_gpio *gpio)
|
||||
{
|
||||
uint8_t m_port = 0;
|
||||
uint8_t m_pin = 0;
|
||||
uint32_t clock = 0;
|
||||
if(gpio == NULL)
|
||||
return;
|
||||
|
||||
if(gpio->port == GPIOA) {
|
||||
clock = RCC_AHB1Periph_GPIOA;
|
||||
m_port = EXTI_PortSourceGPIOA;
|
||||
}
|
||||
else if(gpio->port == GPIOB) {
|
||||
clock = RCC_AHB1Periph_GPIOB;
|
||||
m_port = EXTI_PortSourceGPIOB;
|
||||
}
|
||||
else if(gpio->port == GPIOC) {
|
||||
clock = RCC_AHB1Periph_GPIOC;
|
||||
m_port = EXTI_PortSourceGPIOC;
|
||||
}
|
||||
else if(gpio->port == GPIOD) {
|
||||
clock = RCC_AHB1Periph_GPIOD;
|
||||
m_port = EXTI_PortSourceGPIOD;
|
||||
}
|
||||
else if(gpio->port == GPIOE) {
|
||||
clock = RCC_AHB1Periph_GPIOE;
|
||||
m_port = EXTI_PortSourceGPIOE;
|
||||
}
|
||||
else if(gpio->port == GPIOF) {
|
||||
clock = RCC_AHB1Periph_GPIOF;
|
||||
m_port = EXTI_PortSourceGPIOF;
|
||||
}
|
||||
else if(gpio->port == GPIOG) {
|
||||
clock = RCC_AHB1Periph_GPIOG;
|
||||
m_port = EXTI_PortSourceGPIOG;
|
||||
}
|
||||
else if(gpio->port == GPIOH) {
|
||||
clock = RCC_AHB1Periph_GPIOH;
|
||||
m_port = EXTI_PortSourceGPIOH;
|
||||
}
|
||||
else if(gpio->port == GPIOI) {
|
||||
clock = RCC_AHB1Periph_GPIOI;
|
||||
m_port = EXTI_PortSourceGPIOI;
|
||||
}
|
||||
|
||||
RCC_AHB1PeriphClockCmd(clock, ENABLE);
|
||||
m_pin = gpio_bin2dec(gpio->pin->GPIO_Pin);
|
||||
|
||||
SYSCFG_EXTILineConfig(m_port, m_pin);
|
||||
}
|
||||
|
||||
int stm32f4_gpio_open(const void *gpio)
|
||||
{
|
||||
struct stm32f4_gpio *this;
|
||||
uint8_t m_pin = 0;
|
||||
|
||||
if(gpio == NULL)
|
||||
return -1;
|
||||
|
||||
this = (struct stm32f4_gpio *)gpio;
|
||||
gpio_init(this);
|
||||
m_pin = gpio_bin2dec(this->pin->GPIO_Pin);
|
||||
|
||||
GPIO_Init(this->port, (GPIO_InitTypeDef*)this->pin);
|
||||
|
||||
if(this->ext_it_cb != NULL) {
|
||||
gpio_obj.callback_list[m_pin].callback = this->ext_it_cb;
|
||||
gpio_obj.callback_list[m_pin].param = this->param;
|
||||
}
|
||||
|
||||
if((this->exti != NULL) && (this->nvic != NULL)) {
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
|
||||
EXTI_Init((EXTI_InitTypeDef*)this->exti);
|
||||
NVIC_Init((NVIC_InitTypeDef*)this->nvic);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int stm32f4_gpio_close(const void *gpio)
|
||||
{
|
||||
if(gpio == NULL)
|
||||
return -1;
|
||||
// TODO: deinit exti, nvic & gpio
|
||||
return 0;
|
||||
}
|
||||
|
||||
char stm32f4_gpio_read(const void *gpio)
|
||||
{
|
||||
struct stm32f4_gpio *this;
|
||||
if(gpio == NULL)
|
||||
return 0;
|
||||
|
||||
this = (struct stm32f4_gpio *)gpio;
|
||||
return GPIO_ReadOutputDataBit(this->port, this->pin->GPIO_Pin);
|
||||
}
|
||||
|
||||
void stm32f4_gpio_write(const void *gpio, char byte) {
|
||||
struct stm32f4_gpio *this;
|
||||
if(gpio == NULL)
|
||||
return;
|
||||
|
||||
this = (struct stm32f4_gpio *)gpio;
|
||||
GPIO_WriteBit(this->port, this->pin->GPIO_Pin, (BitAction)byte);
|
||||
}
|
||||
|
||||
void stm32f4_gpio_toggle(const void *gpio)
|
||||
{
|
||||
struct stm32f4_gpio *this;
|
||||
if(gpio == NULL)
|
||||
return;
|
||||
|
||||
this = (struct stm32f4_gpio *)gpio;
|
||||
BitAction act = Bit_SET;
|
||||
if(GPIO_ReadOutputDataBit(this->port, this->pin->GPIO_Pin))
|
||||
act = Bit_RESET;
|
||||
|
||||
GPIO_WriteBit(this->port, this->pin->GPIO_Pin, act);
|
||||
}
|
||||
|
||||
int stm32f4_gpio_set_exti_callback(const void *gpio,
|
||||
const void *callback, const void *param)
|
||||
{
|
||||
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;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//! \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
|
||||
}
|
102
source/firmware/arch/stm32f4xx/driver/stm32f4_uart.c
Normal file
102
source/firmware/arch/stm32f4xx/driver/stm32f4_uart.c
Normal file
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* stm32f4_uart.c
|
||||
*
|
||||
* Created on: Jul 24, 2016
|
||||
* Author: tkl
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "stm32f4xx.h"
|
||||
#include "stm32f4xx_isr.h"
|
||||
#include "stm32f4_uart.h"
|
||||
|
||||
struct stm32f4_uart_obj {
|
||||
const void *callback; //!< Interrupt callback.
|
||||
const void *parameter; //!< argument for the callback.
|
||||
};
|
||||
|
||||
static volatile struct stm32f4_uart_obj uart1_obj;
|
||||
|
||||
int stm32f4_uart_open(const void *this)
|
||||
{
|
||||
struct stm32f4_uart *uart = (struct stm32f4_uart *)this;
|
||||
uint8_t gpio_af = 0;
|
||||
uint32_t rcc_apb_uart = 0, rcc_apb_gpio = 0;
|
||||
|
||||
if(uart->usart_port == USART1) {
|
||||
gpio_af = GPIO_AF_USART1;
|
||||
rcc_apb_uart = RCC_APB2Periph_USART1;
|
||||
}
|
||||
if(uart->gpio_port == GPIOA) {
|
||||
rcc_apb_gpio = RCC_AHB1Periph_GPIOA;
|
||||
}
|
||||
else if(uart->gpio_port == GPIOB) {
|
||||
rcc_apb_gpio = RCC_AHB1Periph_GPIOB;
|
||||
}
|
||||
|
||||
RCC_APB2PeriphClockCmd(rcc_apb_uart, ENABLE);
|
||||
RCC_AHB1PeriphClockCmd(rcc_apb_gpio, ENABLE);
|
||||
|
||||
GPIO_Init(uart->gpio_port, (GPIO_InitTypeDef *)uart->gpio_init);
|
||||
|
||||
GPIO_PinAFConfig(uart->gpio_port, uart->pin_src_rx, gpio_af);
|
||||
GPIO_PinAFConfig(uart->gpio_port, uart->pin_src_tx, gpio_af);
|
||||
|
||||
USART_Init(uart->usart_port, (USART_InitTypeDef *)uart->usart_init);
|
||||
USART_ITConfig(uart->usart_port, uart->usart_it_select, ENABLE);
|
||||
NVIC_Init((NVIC_InitTypeDef *)uart->nvic_init);
|
||||
USART_Cmd(uart->usart_port, ENABLE);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int stm32f4_uart_close(const void *this)
|
||||
{
|
||||
struct stm32f4_uart *uart = (struct stm32f4_uart *)this;
|
||||
USART_Cmd(uart->usart_port, DISABLE);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int stm32f4_uart_read(const void *this, char *buffer, int len)
|
||||
{
|
||||
struct stm32f4_uart *uart = (struct stm32f4_uart *)this;
|
||||
*buffer = uart->usart_port->DR;
|
||||
return (1);
|
||||
}
|
||||
|
||||
int stm32f4_uart_write(const void *this, const char *buffer, int len)
|
||||
{
|
||||
struct stm32f4_uart *uart = (struct stm32f4_uart *)this;
|
||||
int i;
|
||||
for(i = 0; i < len; i++) {
|
||||
// wait until data register is empty
|
||||
while(!(uart->usart_port->SR & 0x00000040));
|
||||
USART_SendData(uart->usart_port, buffer[i]);
|
||||
}
|
||||
return (i);
|
||||
}
|
||||
|
||||
int stm32f4_uart_set_cb(const void *this, const void *callback, const void *param)
|
||||
{
|
||||
struct stm32f4_uart *uart = (struct stm32f4_uart *)this;
|
||||
if(uart->usart_port == USART1) {
|
||||
uart1_obj.callback = callback;
|
||||
uart1_obj.parameter = param;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
// this is the interrupt request handler (IRQ) for ALL USART1 interrupts
|
||||
void USART1_IRQHandler(void)
|
||||
{
|
||||
enter_isr();
|
||||
// check if the USART1 receive interrupt flag was set
|
||||
if(USART_GetITStatus(USART1, USART_IT_RXNE)) {
|
||||
if(uart1_obj.callback) {
|
||||
void (*cb)(const void *) = uart1_obj.callback;
|
||||
cb(uart1_obj.parameter);
|
||||
}
|
||||
}
|
||||
exit_isr();
|
||||
}
|
Reference in New Issue
Block a user