You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

862 lines
24 KiB

#include <stm32f4xx.h>
#include <string.h>
#include "serial.h"
/* must be power of 2 */
#ifdef UART_TX_DMA_BUFSIZ
#define TX_DMA_BUFFER_SIZE UART_TX_DMA_BUFSIZ
#else
#define TX_DMA_BUFFER_SIZE 512
#endif
struct serial {
const char *name;
void (*setup)(struct serial *);
/* uart */
USART_TypeDef *uart;
uint32_t rcc_uart;
int8_t tx_irq;
int8_t tx_irq_priority;
int8_t eie_irq;
int8_t eie_irq_priority;
uint32_t dma_rcc;
uint32_t tx_dma_channel;
uint32_t rx_dma_channel;
DMA_Stream_TypeDef * rx_dma_stream;
DMA_Stream_TypeDef * tx_dma_stream;
uint32_t tx_dma_tcflag;
DMA_InitTypeDef tx_dma_conf;
volatile uint8_t *tx_buffer;
uint16_t tx_buffer_size;
volatile uint8_t *tx_dma_buffer;
volatile uint8_t *rx_buffer;
uint16_t rx_buffer_size;
volatile uint16_t tx_head;
volatile uint16_t tx_tail;
uint16_t rx_head;
};
void serial_reconfigure(struct serial *uart, int baudrate, int databits, int stopbits, int parity)
{
USART_InitTypeDef uart_conf;
USART_Cmd(uart->uart, DISABLE);
USART_DeInit(uart->uart);
/* Set up USART/UART using default parameters */
USART_StructInit(&uart_conf);
switch (databits) {
case 9:
uart_conf.USART_WordLength = USART_WordLength_9b;
break;
default:
uart_conf.USART_WordLength = USART_WordLength_8b;
break;
}
uart_conf.USART_BaudRate = baudrate;
uart_conf.USART_StopBits = stopbits;
uart_conf.USART_Parity = parity ;
uart_conf.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
uart_conf.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(uart->uart, &uart_conf);
USART_Cmd(uart->uart, ENABLE);
}
void serial_setup(struct serial *uart, int baudrate, int databits, int stopbits)
{
DMA_InitTypeDef dma_conf;
NVIC_InitTypeDef irq_conf;
/* setup pins */
uart->setup(uart);
RCC_AHB1PeriphClockCmd(uart->dma_rcc, ENABLE);
serial_reconfigure(uart, baudrate, databits, stopbits, SERIAL_PARITY_NO);
USART_Cmd(uart->uart, DISABLE);
/* Configure RX DMA ... */
DMA_DeInit(uart->rx_dma_stream);
DMA_StructInit(&dma_conf);
dma_conf.DMA_Channel = uart->rx_dma_channel;
dma_conf.DMA_PeripheralBaseAddr = (uint32_t)&uart->uart->DR;
dma_conf.DMA_Memory0BaseAddr = (uint32_t)uart->rx_buffer;
dma_conf.DMA_BufferSize = uart->rx_buffer_size;
dma_conf.DMA_DIR = DMA_DIR_PeripheralToMemory;
dma_conf.DMA_MemoryInc = DMA_MemoryInc_Enable;
dma_conf.DMA_Mode = DMA_Mode_Circular;
dma_conf.DMA_Priority = DMA_Priority_High;
dma_conf.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
dma_conf.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_Init(uart->rx_dma_stream, &dma_conf);
/* Configure TX DMA ... */
DMA_DeInit(uart->tx_dma_stream);
DMA_StructInit(&dma_conf);
dma_conf.DMA_Channel = uart->tx_dma_channel;
dma_conf.DMA_PeripheralBaseAddr = (uint32_t)&uart->uart->DR;
dma_conf.DMA_Memory0BaseAddr = (uint32_t)uart->tx_dma_buffer;
dma_conf.DMA_BufferSize = TX_DMA_BUFFER_SIZE;
dma_conf.DMA_DIR = DMA_DIR_MemoryToPeripheral;
dma_conf.DMA_MemoryInc = DMA_MemoryInc_Enable;
dma_conf.DMA_Priority = DMA_Priority_High;
DMA_Init(uart->tx_dma_stream, &dma_conf);
uart->tx_dma_conf = dma_conf;
DMA_Cmd(uart->rx_dma_stream, ENABLE);
DMA_Cmd(uart->tx_dma_stream, DISABLE);
DMA_ITConfig(uart->tx_dma_stream, DMA_IT_TC, ENABLE);
USART_DMACmd(uart->uart, USART_DMAReq_Tx | USART_DMAReq_Rx, ENABLE);
memset(&irq_conf, 0, sizeof irq_conf);
irq_conf.NVIC_IRQChannel = uart->tx_irq;
if (uart->tx_irq_priority > 0) {
irq_conf.NVIC_IRQChannelPreemptionPriority = uart->tx_irq_priority;
}
irq_conf.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&irq_conf);
if (uart->eie_irq >= 0) {
memset(&irq_conf, 0, sizeof irq_conf);
irq_conf.NVIC_IRQChannel = uart->eie_irq;
if (uart->eie_irq_priority > 0) {
irq_conf.NVIC_IRQChannelPreemptionPriority = uart->eie_irq_priority;
}
irq_conf.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&irq_conf);
USART_ITConfig(uart->uart, USART_IT_PE | USART_IT_ERR | USART_IT_NE | USART_IT_FE, ENABLE);
}
/* Enable the UART with the new settings */
USART_Cmd(uart->uart, ENABLE);
}
void serial_close(struct serial *uart)
{
NVIC_InitTypeDef irq_conf;
DMA_ITConfig(uart->tx_dma_stream, DMA_IT_TC, DISABLE);
USART_DMACmd(uart->uart, USART_DMAReq_Tx | USART_DMAReq_Rx, DISABLE);
DMA_Cmd(uart->rx_dma_stream, DISABLE);
DMA_Cmd(uart->tx_dma_stream, DISABLE);
irq_conf.NVIC_IRQChannel = uart->tx_irq;
irq_conf.NVIC_IRQChannelCmd = DISABLE;
NVIC_Init(&irq_conf);
USART_Cmd(uart->uart, DISABLE);
USART_DeInit(uart->uart);
DMA_DeInit(uart->rx_dma_stream);
DMA_DeInit(uart->tx_dma_stream);
}
static int tx_buffer_empty(struct serial *uart)
{
return uart->tx_head == uart->tx_tail;
}
static int tx_buffer_full(struct serial *uart)
{
return (uint16_t)(uart->tx_tail - uart->tx_head) == uart->tx_buffer_size;
}
static void tx_buffer_put(struct serial *uart, uint8_t data)
{
uart->tx_buffer[uart->tx_tail % uart->tx_buffer_size] = data;
uart->tx_tail++;
}
static uint8_t tx_buffer_get(struct serial *uart)
{
uint8_t data = uart->tx_buffer[uart->tx_head % uart->tx_buffer_size];
uart->tx_head++;
return data;
}
void serial_tx_buffer_clear(struct serial *uart)
{
uart->tx_head = 0;
uart->tx_tail = 0;
}
size_t serial_send_buffer_space(struct serial *uart)
{
return uart->tx_buffer_size - (uint16_t)(uart->tx_tail - uart->tx_head);
}
static int rx_buffer_empty(struct serial *uart)
{
if (uart->rx_dma_stream->CR & DMA_SxCR_EN) {
uint16_t rx_tail = (uart->rx_buffer_size - uart->rx_dma_stream->NDTR) % uart->rx_buffer_size;
return rx_tail == uart->rx_head;
} else {
return 1;
}
}
static uint8_t rx_buffer_get(struct serial *uart)
{
uint8_t data = uart->rx_buffer[uart->rx_head];
uart->rx_head = (uart->rx_head + 1) % uart->rx_buffer_size;
return data;
}
int serial_rx_size(struct serial *uart)
{
if (uart->rx_dma_stream->CR & DMA_SxCR_EN) {
uint16_t rx_tail = (uart->rx_buffer_size - uart->rx_dma_stream->NDTR);
return rx_tail - uart->rx_head;
}
return -1;
}
int serial_peekchar(struct serial *uart)
{
if (!rx_buffer_empty(uart)) {
return uart->rx_buffer[uart->rx_head];
}
return -1;
}
void serial_rx_buffer_clear(struct serial *uart)
{
uart->rx_head = 0;
DMA_Cmd(uart->rx_dma_stream, DISABLE);
DMA_Cmd(uart->rx_dma_stream, ENABLE);
}
int serial_getchar(struct serial *uart)
{
if (!rx_buffer_empty(uart)) {
return rx_buffer_get(uart);
}
return -1;
}
static void __eie_isr(struct serial *_uart)
{
uint32_t flags;
USART_TypeDef *uart = _uart->uart;
flags = uart->SR;
if (flags & (USART_FLAG_NE | USART_FLAG_FE | USART_FLAG_ORE | USART_FLAG_PE)) {
(void)uart->DR;
uart->SR &= ~(USART_FLAG_NE | USART_FLAG_FE | USART_FLAG_ORE | USART_FLAG_PE);
/* printf("clear error %s: %x\r\n", _uart->name, flags); */
}
}
size_t serial_recv_buffered(struct serial *uart, uint8_t* data, size_t max_bytes)
{
size_t bytes_read = 0;
__eie_isr(uart);
if (max_bytes == 1) {
if (!rx_buffer_empty(uart)) {
*data = rx_buffer_get(uart);
bytes_read = 1;
}
} else if (!rx_buffer_empty(uart)) {
uint16_t rx_tail = (uart->rx_buffer_size - uart->rx_dma_stream->NDTR) % uart->rx_buffer_size;
if (uart->rx_head > rx_tail) {
while (uart->rx_head < uart->rx_buffer_size && bytes_read < max_bytes) {
data[bytes_read++] = uart->rx_buffer[uart->rx_head++];
}
if (uart->rx_head == uart->rx_buffer_size) {
uart->rx_head = 0;
}
}
if ((bytes_read < max_bytes) && (uart->rx_head < rx_tail)) {
while (uart->rx_head < rx_tail && bytes_read < max_bytes) {
data[bytes_read++] = uart->rx_buffer[uart->rx_head++];
}
if (uart->rx_head == uart->rx_buffer_size) {
uart->rx_head = 0;
}
}
}
return bytes_read;
}
size_t serial_recv_blocking(struct serial *uart, uint8_t* data, size_t max_bytes)
{
size_t i = max_bytes;
__eie_isr(uart);
while (i > 0) {
while (USART_GetFlagStatus(uart->uart, USART_FLAG_RXNE) == RESET)
;
*data++ = USART_ReceiveData(uart->uart);
--i;
}
return (max_bytes);
}
static int dma_tx(struct serial *uart)
{
int i;
for (i = 0; i < TX_DMA_BUFFER_SIZE && !tx_buffer_empty(uart); ++i) {
uart->tx_dma_buffer[i] = tx_buffer_get(uart);
}
if (i > 0) {
uart->tx_dma_conf.DMA_BufferSize = i;
DMA_Init(uart->tx_dma_stream, &uart->tx_dma_conf);
DMA_Cmd(uart->tx_dma_stream, ENABLE);
}
return (i);
}
size_t serial_send_buffered(struct serial *uart, const uint8_t* data, size_t num_bytes)
{
size_t bytes_written = 0;
__eie_isr(uart);
while (!tx_buffer_full(uart) && (bytes_written < num_bytes)) {
tx_buffer_put(uart, data[bytes_written++]);
}
if (!tx_buffer_empty(uart) && !(uart->tx_dma_stream->CR & DMA_SxCR_EN)) {
dma_tx(uart);
}
return bytes_written;
}
size_t serial_send_blocking(struct serial *uart, const uint8_t *data, size_t num)
{
size_t i = num;
__eie_isr(uart);
while (USART_GetFlagStatus(uart->uart, USART_FLAG_TC) == RESET)
;
while (i > 0) {
USART_SendData(uart->uart, *data++);
while (USART_GetFlagStatus(uart->uart, USART_FLAG_TC) == RESET);
--i;
}
return (num);
}
static __attribute__((unused)) void __tx_dma_isr(struct serial *uart)
{
if (DMA_GetITStatus(uart->tx_dma_stream, uart->tx_dma_tcflag)) {
DMA_ClearITPendingBit(uart->tx_dma_stream, uart->tx_dma_tcflag);
if (!tx_buffer_empty(uart)) {
dma_tx(uart);
} else {
/* Disable the selected DMA Stream by clearing EN bit */
uart->tx_dma_stream->CR &= ~(uint32_t)DMA_SxCR_EN;
}
}
}
#if (TARGET_HAS_USART1)
void __attribute__((weak)) target_usart1_setup()
{
GPIO_InitTypeDef gpio_conf;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
GPIO_StructInit(&gpio_conf);
gpio_conf.GPIO_Pin = GPIO_Pin_9;
gpio_conf.GPIO_OType = GPIO_OType_PP;
gpio_conf.GPIO_Mode = GPIO_Mode_AF;
gpio_conf.GPIO_Speed = GPIO_Speed_50MHz;
gpio_conf.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOA, &gpio_conf);
gpio_conf.GPIO_Pin = GPIO_Pin_10;
gpio_conf.GPIO_OType = GPIO_OType_OD;
gpio_conf.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &gpio_conf);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);
}
static void usart1_setup(struct serial *uart)
{
RCC_APB2PeriphClockCmd(uart->rcc_uart, ENABLE);
target_usart1_setup();
}
static volatile uint8_t __usart1_rx_buffer[TARGET_USART1_RX_BUFFER_SIZE] __attribute__((section(".rxdma.usart1,\"aw\",%nobits@")));
static volatile uint8_t __usart1_tx_buffer[TARGET_USART1_TX_BUFFER_SIZE] __attribute__((section(".txbuf.usart1,\"aw\",%nobits@")));
static volatile uint8_t __usart1_tx_dma_buffer[TX_DMA_BUFFER_SIZE] __attribute__((section(".txdma.usart1,\"aw\",%nobits@")));
struct serial serial0 = {
.name = "USART1",
.setup = usart1_setup,
.uart = USART1,
.rcc_uart = RCC_APB2Periph_USART1,
.tx_irq = DMA2_Stream7_IRQn,
.eie_irq = -1,
.dma_rcc = RCC_AHB1Periph_DMA2,
.tx_dma_channel = DMA_Channel_4,
.rx_dma_channel = DMA_Channel_4,
.rx_dma_stream = DMA2_Stream2,
.tx_dma_stream = DMA2_Stream7,
.tx_dma_tcflag = DMA_IT_TCIF7,
.tx_dma_buffer = __usart1_tx_dma_buffer,
.tx_buffer_size = TARGET_USART1_TX_BUFFER_SIZE,
.tx_buffer = __usart1_tx_buffer,
.rx_buffer_size = TARGET_USART1_RX_BUFFER_SIZE,
.rx_buffer = __usart1_rx_buffer,
};
void DMA2_Stream7_IRQHandler(void)
{
__tx_dma_isr(&serial0);
}
#endif
#if (TARGET_HAS_USART2)
void __attribute__((weak)) target_usart2_setup()
{
GPIO_InitTypeDef gpio_conf;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
GPIO_StructInit(&gpio_conf);
gpio_conf.GPIO_Pin = GPIO_Pin_2;
gpio_conf.GPIO_OType = GPIO_OType_PP;
gpio_conf.GPIO_Mode = GPIO_Mode_AF;
gpio_conf.GPIO_Speed = GPIO_Speed_50MHz;
gpio_conf.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOA, &gpio_conf);
gpio_conf.GPIO_Pin = GPIO_Pin_3;
gpio_conf.GPIO_OType = GPIO_OType_OD;
gpio_conf.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &gpio_conf);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2);
}
static void usart2_setup(struct serial *uart)
{
RCC_APB1PeriphClockCmd(uart->rcc_uart, ENABLE);
target_usart2_setup();
}
static volatile uint8_t __usart2_rx_buffer[TARGET_USART2_RX_BUFFER_SIZE] __attribute__((section(".rxdma.usart2,\"aw\",%nobits@")));
static volatile uint8_t __usart2_tx_buffer[TARGET_USART2_TX_BUFFER_SIZE] __attribute__((section(".txbuf.usart2,\"aw\",%nobits@")));
static volatile uint8_t __usart2_tx_dma_buffer[TX_DMA_BUFFER_SIZE] __attribute__((section(".txdma.usart2,\"aw\",%nobits@")));
struct serial serial1 = {
.name = "USART2",
.setup = usart2_setup,
.uart = USART2,
.rcc_uart = RCC_APB1Periph_USART2,
.tx_irq = DMA1_Stream6_IRQn,
.eie_irq = -1,
.dma_rcc = RCC_AHB1Periph_DMA1,
.tx_dma_channel = DMA_Channel_4,
.rx_dma_channel = DMA_Channel_4,
.rx_dma_stream = DMA1_Stream5,
.tx_dma_stream = DMA1_Stream6,
.tx_dma_tcflag = DMA_IT_TCIF6,
.tx_dma_buffer = __usart2_tx_dma_buffer,
.tx_buffer_size = TARGET_USART2_TX_BUFFER_SIZE,
.tx_buffer = __usart1_tx_buffer,
.rx_buffer_size = TARGET_USART2_RX_BUFFER_SIZE,
.rx_buffer = __usart2_rx_buffer,
};
void DMA1_Stream6_IRQHandler(void)
{
__tx_dma_isr(&serial1);
}
#endif
#if (TARGET_HAS_USART3)
void __attribute__((weak)) target_usart3_setup()
{
GPIO_InitTypeDef gpio_conf;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
GPIO_StructInit(&gpio_conf);
gpio_conf.GPIO_Pin = GPIO_Pin_10;
gpio_conf.GPIO_OType = GPIO_OType_PP;
gpio_conf.GPIO_Mode = GPIO_Mode_AF;
gpio_conf.GPIO_Speed = GPIO_Speed_50MHz;
gpio_conf.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOB, &gpio_conf);
gpio_conf.GPIO_Pin = GPIO_Pin_11;
gpio_conf.GPIO_OType = GPIO_OType_OD;
gpio_conf.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &gpio_conf);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_USART3);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_USART3);
}
static void usart3_setup(struct serial *uart)
{
RCC_APB1PeriphClockCmd(uart->rcc_uart, ENABLE);
target_usart3_setup();
}
static volatile uint8_t __usart3_rx_buffer[TARGET_USART3_RX_BUFFER_SIZE] __attribute__((section(".rxdma.usart3,\"aw\",%nobits@")));
static volatile uint8_t __usart3_tx_buffer[TARGET_USART3_TX_BUFFER_SIZE] __attribute__((section(".txbuf.usart3,\"aw\",%nobits@")));
static volatile uint8_t __usart3_tx_dma_buffer[TX_DMA_BUFFER_SIZE] __attribute__((section(".txdma.usart3,\"aw\",%nobits@")));
struct serial serial2 = {
.name = "USART3",
.setup = usart3_setup,
.uart = USART3,
.rcc_uart = RCC_APB1Periph_USART3,
.tx_irq = DMA1_Stream3_IRQn,
.eie_irq = -1,
.dma_rcc = RCC_AHB1Periph_DMA1,
.rx_dma_channel = DMA_Channel_4,
.tx_dma_channel = DMA_Channel_4,
.rx_dma_stream = DMA1_Stream1,
.tx_dma_stream = DMA1_Stream3,
.tx_dma_tcflag = DMA_IT_TCIF3,
.tx_dma_buffer = __usart3_tx_dma_buffer,
.tx_buffer_size = TARGET_USART3_TX_BUFFER_SIZE,
.tx_buffer = __usart3_tx_buffer,
.rx_buffer_size = TARGET_USART3_RX_BUFFER_SIZE,
.rx_buffer = __usart3_rx_buffer,
};
void DMA1_Stream3_IRQHandler(void)
{
__tx_dma_isr(&serial2);
}
#endif
#if (TARGET_HAS_USART4)
void __attribute__((weak)) target_uart4_setup()
{
GPIO_InitTypeDef gpio_conf;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
GPIO_StructInit(&gpio_conf);
gpio_conf.GPIO_Pin = GPIO_Pin_0;
gpio_conf.GPIO_OType = GPIO_OType_PP;
gpio_conf.GPIO_Mode = GPIO_Mode_AF;
gpio_conf.GPIO_Speed = GPIO_Speed_50MHz;
gpio_conf.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOA, &gpio_conf);
gpio_conf.GPIO_Pin = GPIO_Pin_1;
gpio_conf.GPIO_OType = GPIO_OType_OD;
gpio_conf.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &gpio_conf);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource0, GPIO_AF_UART4);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_UART4);
}
static void usart4_setup(struct serial *uart)
{
RCC_APB1PeriphClockCmd(uart->rcc_uart, ENABLE);
target_uart4_setup();
}
static volatile uint8_t __usart4_rx_buffer[TARGET_USART4_RX_BUFFER_SIZE] __attribute__((section(".rxdma.usart4,\"aw\",%nobits@")));
static volatile uint8_t __usart4_tx_buffer[TARGET_USART4_TX_BUFFER_SIZE] __attribute__((section(".txbuf.usart4,\"aw\",%nobits@")));
static volatile uint8_t __usart4_tx_dma_buffer[TX_DMA_BUFFER_SIZE] __attribute__((section(".txdma.usart4,\"aw\",%nobits@")));
struct serial serial3 = {
.name = "UART4",
.setup = usart4_setup,
.uart = UART4,
.rcc_uart = RCC_APB1Periph_UART4,
.tx_irq = DMA1_Stream4_IRQn,
/* .eie_irq = UART4_IRQn, */
.eie_irq = -1,
.dma_rcc = RCC_AHB1Periph_DMA1,
.tx_dma_channel = DMA_Channel_4,
.rx_dma_channel = DMA_Channel_4,
.rx_dma_stream = DMA1_Stream2,
.tx_dma_stream = DMA1_Stream4,
.tx_dma_tcflag = DMA_IT_TCIF4,
.tx_dma_buffer = __usart4_tx_dma_buffer,
.tx_buffer_size = TARGET_USART4_TX_BUFFER_SIZE,
.tx_buffer = __usart4_tx_buffer,
.rx_buffer_size = TARGET_USART4_RX_BUFFER_SIZE,
.rx_buffer = __usart4_rx_buffer,
};
void DMA1_Stream4_IRQHandler(void)
{
__tx_dma_isr(&serial3);
}
void UART4_IRQHandler(void)
{
__eie_isr(&serial3);
}
#endif
#if (TARGET_HAS_USART5)
void __attribute__((weak)) target_uart5_setup()
{
GPIO_InitTypeDef gpio_conf;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
GPIO_StructInit(&gpio_conf);
gpio_conf.GPIO_Pin = GPIO_Pin_2;
gpio_conf.GPIO_OType = GPIO_OType_PP;
gpio_conf.GPIO_Mode = GPIO_Mode_AF;
gpio_conf.GPIO_Speed = GPIO_Speed_50MHz;
gpio_conf.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOD, &gpio_conf);
gpio_conf.GPIO_Pin = GPIO_Pin_12;
gpio_conf.GPIO_OType = GPIO_OType_PP;
gpio_conf.GPIO_Mode = GPIO_Mode_AF;
gpio_conf.GPIO_Speed = GPIO_Speed_50MHz;
gpio_conf.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOC, &gpio_conf);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource12, GPIO_AF_UART5);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource2, GPIO_AF_UART5);
}
static void usart5_setup(struct serial *uart)
{
RCC_APB1PeriphClockCmd(uart->rcc_uart, ENABLE);
target_uart5_setup();
}
static volatile uint8_t __usart5_rx_buffer[TARGET_USART5_RX_BUFFER_SIZE] __attribute__((section(".rxdma.usart5,\"aw\",%nobits@")));
static volatile uint8_t __usart5_tx_buffer[TARGET_USART5_TX_BUFFER_SIZE] __attribute__((section(".txbuf.usart5,\"aw\",%nobits@")));
static volatile uint8_t __usart5_tx_dma_buffer[TX_DMA_BUFFER_SIZE] __attribute__((section(".txdma.usart5,\"aw\",%nobits@")));
struct serial serial4 = {
.name = "USART5",
.setup = usart5_setup,
.uart = UART5,
.rcc_uart = RCC_APB1Periph_UART5,
.tx_irq = DMA1_Stream7_IRQn,
/* .eie_irq = USART6_IRQn, */
.eie_irq = -1,
.dma_rcc = RCC_AHB1Periph_DMA1,
.tx_dma_channel = DMA_Channel_4,
.rx_dma_channel = DMA_Channel_4,
.rx_dma_stream = DMA1_Stream0,
.tx_dma_stream = DMA1_Stream7,
.tx_dma_tcflag = DMA_IT_TCIF7,
.tx_dma_buffer = __usart5_tx_dma_buffer,
.tx_buffer_size = TARGET_USART5_TX_BUFFER_SIZE,
.tx_buffer = __usart5_tx_buffer,
.rx_buffer_size = TARGET_USART5_RX_BUFFER_SIZE,
.rx_buffer = __usart5_rx_buffer,
};
void DMA1_Stream7_IRQHandler(void)
{
__tx_dma_isr(&serial4);
}
#endif
#if (TARGET_HAS_USART6)
void __attribute__((weak)) target_usart6_setup()
{
GPIO_InitTypeDef gpio_conf;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE);
GPIO_StructInit(&gpio_conf);
gpio_conf.GPIO_Pin = GPIO_Pin_14;
gpio_conf.GPIO_OType = GPIO_OType_PP;
gpio_conf.GPIO_Mode = GPIO_Mode_AF;
gpio_conf.GPIO_Speed = GPIO_Speed_50MHz;
gpio_conf.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOG, &gpio_conf);
gpio_conf.GPIO_Pin = GPIO_Pin_7;
gpio_conf.GPIO_OType = GPIO_OType_OD;
gpio_conf.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOC, &gpio_conf);
GPIO_PinAFConfig(GPIOG, GPIO_PinSource14, GPIO_AF_USART6);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_USART6);
}
static void usart6_setup(struct serial *uart)
{
RCC_APB2PeriphClockCmd(uart->rcc_uart, ENABLE);
target_usart6_setup();
}
static volatile uint8_t __usart6_rx_buffer[TARGET_USART6_RX_BUFFER_SIZE] __attribute__((section(".rxdma.usart6,\"aw\",%nobits@")));
static volatile uint8_t __usart6_tx_buffer[TARGET_USART6_TX_BUFFER_SIZE] __attribute__((section(".txbuf.usart6,\"aw\",%nobits@")));
static volatile uint8_t __usart6_tx_dma_buffer[TX_DMA_BUFFER_SIZE] __attribute__((section(".txdma.usart6,\"aw\",%nobits@")));
struct serial serial5 = {
.name = "USART6",
.setup = usart6_setup,
.uart = USART6,
.rcc_uart = RCC_APB2Periph_USART6,
.tx_irq = DMA2_Stream6_IRQn,
/* .eie_irq = USART6_IRQn, */
.eie_irq = -1,
.dma_rcc = RCC_AHB1Periph_DMA2,
.tx_dma_channel = DMA_Channel_5,
.rx_dma_channel = DMA_Channel_5,
.rx_dma_stream = DMA2_Stream1,
.tx_dma_stream = DMA2_Stream6,
.tx_dma_tcflag = DMA_IT_TCIF6,
.tx_dma_buffer = __usart6_tx_dma_buffer,
.tx_buffer_size = TARGET_USART6_TX_BUFFER_SIZE,
.tx_buffer = __usart6_tx_buffer,
.rx_buffer_size = TARGET_USART6_RX_BUFFER_SIZE,
.rx_buffer = __usart6_rx_buffer,
};
void DMA2_Stream6_IRQHandler(void)
{
__tx_dma_isr(&serial5);
}
void USART6_IRQHandler(void)
{
__eie_isr(&serial5);
}
#endif
#if (TARGET_HAS_USART7)
void __attribute__((weak)) target_usart7_setup()
{
GPIO_InitTypeDef gpio_conf;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);
GPIO_StructInit(&gpio_conf);
gpio_conf.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
gpio_conf.GPIO_OType = GPIO_OType_PP;
gpio_conf.GPIO_Mode = GPIO_Mode_AF;
gpio_conf.GPIO_Speed = GPIO_Speed_50MHz;
gpio_conf.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOF, &gpio_conf);
GPIO_PinAFConfig(GPIOF, GPIO_PinSource6, GPIO_AF_UART7);
GPIO_PinAFConfig(GPIOF, GPIO_PinSource7, GPIO_AF_UART7);
}
static void usart7_setup(struct serial *uart)
{
RCC_APB1PeriphClockCmd(uart->rcc_uart, ENABLE);
target_usart7_setup();
}
static volatile uint8_t __usart7_rx_buffer[TARGET_USART7_RX_BUFFER_SIZE] __attribute__((section(".rxdma.usart7,\"aw\",%nobits@")));
static volatile uint8_t __usart7_tx_buffer[TARGET_USART7_TX_BUFFER_SIZE] __attribute__((section(".txbuf.usart7,\"aw\",%nobits@")));
static volatile uint8_t __usart7_tx_dma_buffer[TX_DMA_BUFFER_SIZE] __attribute__((section(".txdma.usart7,\"aw\",%nobits@")));
struct serial serial6 = {
.name = "USART7",
.setup = usart7_setup,
.uart = UART7,
.rcc_uart = RCC_APB1Periph_UART7,
.tx_irq = DMA1_Stream1_IRQn,
/* .eie_irq = UART7_IRQn, */
.eie_irq = -1,
.dma_rcc = RCC_AHB1Periph_DMA1,
.tx_dma_channel = DMA_Channel_5,
.rx_dma_channel = DMA_Channel_5,
.rx_dma_stream = DMA1_Stream3,
.tx_dma_stream = DMA1_Stream1,
.tx_dma_tcflag = DMA_IT_TCIF1,
.tx_dma_buffer = __usart7_tx_dma_buffer,
.tx_buffer_size = TARGET_USART7_TX_BUFFER_SIZE,
.tx_buffer = __usart7_tx_buffer,
.rx_buffer_size = TARGET_USART7_RX_BUFFER_SIZE,
.rx_buffer = __usart7_rx_buffer,
};
void DMA1_Stream1_IRQHandler(void)
{
__tx_dma_isr(&serial6);
}
void UART7_IRQHandler(void)
{
__eie_isr(&serial6);
}
#endif