Вот, например: #include "uart.h"
#include "stm32f107xc.h"
#include "systime.h"
#include <string.h>
#define RX_BUFSIZE 64
#define TX_BUFSIZE 64
static USART_TypeDef* const usart = USART1;
static uint8_t volatile rxfifo[RX_BUFSIZE];
static uint8_t volatile txbuf[TX_BUFSIZE];
static unsigned int rxtail, txhead;
static DMA_Channel_TypeDef* const txstream = DMA1_Channel4;
static DMA_Channel_TypeDef* const rxstream = DMA1_Channel5;
void
uart_init(void)
{
rxstream->CMAR = (int)&rxfifo;
rxstream->CPAR = (int)&usart->DR;
rxstream->CNDTR = RX_BUFSIZE;
rxstream->CCR = DMA_CCR_MINC
| DMA_CCR_CIRC
| DMA_CCR_EN;
uart_mode_boot();
}
void
uart_mode_norm(void)
{
usart->BRR = SYSTIME_TPS / 4000000;
usart->CR1 = USART_CR1_UE
| USART_CR1_TE
| USART_CR1_RE;
usart->CR3 |= USART_CR3_HDSEL;
}
void
uart_mode_boot(void)
{
usart->BRR = SYSTIME_TPS / 57600;
usart->CR3 = USART_CR3_DMAR
| USART_CR3_DMAT;
usart->CR1 = USART_CR1_PCE
| USART_CR1_M
| USART_CR1_UE
| USART_CR1_TE
| USART_CR1_RE;
}
bool
uart_txe(void)
{
return txstream->CNDTR == 0;
}
void
uart_putbytes(const void* src, int n)
{
memcpy((void*)(txbuf + txhead), src, n);
txhead += n;
}
void
uart_putbyte(int b)
{
txbuf[txhead++] = b;
}
int
uart_send(void)
{
while (!uart_txe()) ;
txstream->CCR = 0;
while (txstream->CCR & DMA_CCR_EN) ;
DMA1->IFCR = DMA_IFCR_CGIF4
| DMA_IFCR_CTCIF4
| DMA_IFCR_CHTIF4
| DMA_IFCR_CTEIF4;
txstream->CMAR = (int)txbuf;
txstream->CPAR = (int)&usart->DR;
txstream->CNDTR = txhead;
txstream->CCR = DMA_CCR_DIR
| DMA_CCR_MINC
| DMA_CCR_EN;
int ret = txhead;
txhead = 0;
return ret;
}
void
uart_sendbytes(const void* src, int n)
{
while (!uart_txe()) ;
txstream->CCR = 0;
while (txstream->CCR & DMA_CCR_EN) ;
DMA1->IFCR = DMA_IFCR_CGIF4
| DMA_IFCR_CTCIF4
| DMA_IFCR_CHTIF4
| DMA_IFCR_CTEIF4;
txstream->CMAR = (int)src;
txstream->CPAR = (int)&usart->DR;
txstream->CNDTR = n;
txstream->CCR = DMA_CCR_DIR
| DMA_CCR_MINC
| DMA_CCR_EN;
txhead = 0;
}
void
uart_sendbyte(int b)
{
static uint8_t buf;
buf = b;
uart_sendbytes(&buf, 1);
}
int
uart_getbyte(void)
{
return rxfifo[rxtail++ & (RX_BUFSIZE - 1)];
}
void
uart_getbytes(void* dst, int n)
{
uint8_t* dst8 = dst;
while (n-- > 0)
{
*dst8++ = uart_getbyte();
}
}
int
uart_rxcount(void)
{
return (0 - rxstream->CNDTR - rxtail) & (RX_BUFSIZE - 1);
}
int
uart_peek(int i)
{
return rxfifo[(rxtail + i) & (RX_BUFSIZE - 1)];
}
void
uart_flush(int n)
{
rxtail += n;
}