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
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
|
|
|
|
|