@ -52,7 +52,7 @@ void uart_ring_process(uart_ring *q) {
if ( q - > w_ptr_tx ! = q - > r_ptr_tx ) {
if ( q - > w_ptr_tx ! = q - > r_ptr_tx ) {
if ( sr & USART_SR_TXE ) {
if ( sr & USART_SR_TXE ) {
q - > uart - > DR = q - > elems_tx [ q - > r_ptr_tx ] ;
q - > uart - > DR = q - > elems_tx [ q - > r_ptr_tx ] ;
q - > r_ptr_tx + = 1 ;
q - > r_ptr_tx = ( q - > r_ptr_tx + 1 ) % FIFO_SIZE ;
} else {
} else {
// push on interrupt later
// push on interrupt later
q - > uart - > CR1 | = USART_CR1_TXEIE ;
q - > uart - > CR1 | = USART_CR1_TXEIE ;
@ -64,13 +64,15 @@ void uart_ring_process(uart_ring *q) {
if ( sr & USART_SR_RXNE | | sr & USART_SR_ORE ) {
if ( sr & USART_SR_RXNE | | sr & USART_SR_ORE ) {
uint8_t c = q - > uart - > DR ; // TODO: can drop packets
uint8_t c = q - > uart - > DR ; // TODO: can drop packets
uint8_t next_w_ptr = q - > w_ptr_rx + 1 ;
if ( q ! = & esp_ring ) {
uint16_t next_w_ptr = ( q - > w_ptr_rx + 1 ) % FIFO_SIZE ;
if ( next_w_ptr ! = q - > r_ptr_rx ) {
if ( next_w_ptr ! = q - > r_ptr_rx ) {
q - > elems_rx [ q - > w_ptr_rx ] = c ;
q - > elems_rx [ q - > w_ptr_rx ] = c ;
q - > w_ptr_rx = next_w_ptr ;
q - > w_ptr_rx = next_w_ptr ;
if ( q - > callback ) q - > callback ( q ) ;
if ( q - > callback ) q - > callback ( q ) ;
}
}
}
}
}
if ( sr & USART_SR_ORE ) {
if ( sr & USART_SR_ORE ) {
// set dropped packet flag?
// set dropped packet flag?
@ -92,7 +94,7 @@ int getc(uart_ring *q, char *elem) {
enter_critical_section ( ) ;
enter_critical_section ( ) ;
if ( q - > w_ptr_rx ! = q - > r_ptr_rx ) {
if ( q - > w_ptr_rx ! = q - > r_ptr_rx ) {
* elem = q - > elems_rx [ q - > r_ptr_rx ] ;
* elem = q - > elems_rx [ q - > r_ptr_rx ] ;
q - > r_ptr_rx + = 1 ;
q - > r_ptr_rx = ( q - > r_ptr_rx + 1 ) % FIFO_SIZE ;
ret = 1 ;
ret = 1 ;
}
}
exit_critical_section ( ) ;
exit_critical_section ( ) ;
@ -102,10 +104,10 @@ int getc(uart_ring *q, char *elem) {
int injectc ( uart_ring * q , char elem ) {
int injectc ( uart_ring * q , char elem ) {
int ret = 0 ;
int ret = 0 ;
uint8 _t next_w_ptr ;
uint16 _t next_w_ptr ;
enter_critical_section ( ) ;
enter_critical_section ( ) ;
next_w_ptr = q - > w_ptr_rx + 1 ;
next_w_ptr = ( q - > w_ptr_rx + 1 ) % FIFO_SIZE ;
if ( next_w_ptr ! = q - > r_ptr_rx ) {
if ( next_w_ptr ! = q - > r_ptr_rx ) {
q - > elems_rx [ q - > w_ptr_rx ] = elem ;
q - > elems_rx [ q - > w_ptr_rx ] = elem ;
q - > w_ptr_rx = next_w_ptr ;
q - > w_ptr_rx = next_w_ptr ;
@ -118,10 +120,10 @@ int injectc(uart_ring *q, char elem) {
int putc ( uart_ring * q , char elem ) {
int putc ( uart_ring * q , char elem ) {
int ret = 0 ;
int ret = 0 ;
uint8 _t next_w_ptr ;
uint16 _t next_w_ptr ;
enter_critical_section ( ) ;
enter_critical_section ( ) ;
next_w_ptr = q - > w_ptr_tx + 1 ;
next_w_ptr = ( q - > w_ptr_tx + 1 ) % FIFO_SIZE ;
if ( next_w_ptr ! = q - > r_ptr_tx ) {
if ( next_w_ptr ! = q - > r_ptr_tx ) {
q - > elems_tx [ q - > w_ptr_tx ] = elem ;
q - > elems_tx [ q - > w_ptr_tx ] = elem ;
q - > w_ptr_tx = next_w_ptr ;
q - > w_ptr_tx = next_w_ptr ;
@ -159,6 +161,51 @@ void uart_set_baud(USART_TypeDef *u, int baud) {
}
}
}
}
# define USART1_DMA_LEN 0x20
char usart1_dma [ USART1_DMA_LEN ] ;
void uart_dma_drain ( ) {
uart_ring * q = & esp_ring ;
enter_critical_section ( ) ;
if ( DMA2 - > HISR & DMA_HISR_TCIF5 | | DMA2 - > HISR & DMA_HISR_HTIF5 | | DMA2_Stream5 - > NDTR ! = USART1_DMA_LEN ) {
// disable DMA
q - > uart - > CR3 & = ~ USART_CR3_DMAR ;
DMA2_Stream5 - > CR & = ~ DMA_SxCR_EN ;
while ( DMA2_Stream5 - > CR & DMA_SxCR_EN ) ;
int i ;
for ( i = 0 ; i < USART1_DMA_LEN - DMA2_Stream5 - > NDTR ; i + + ) {
char c = usart1_dma [ i ] ;
uint16_t next_w_ptr = ( q - > w_ptr_rx + 1 ) % FIFO_SIZE ;
if ( next_w_ptr ! = q - > r_ptr_rx ) {
q - > elems_rx [ q - > w_ptr_rx ] = c ;
q - > w_ptr_rx = next_w_ptr ;
}
}
// reset DMA len
DMA2_Stream5 - > NDTR = USART1_DMA_LEN ;
// clear interrupts
DMA2 - > HIFCR = DMA_HIFCR_CTCIF5 | DMA_HIFCR_CHTIF5 ;
//DMA2->HIFCR = DMA_HIFCR_CTEIF5 | DMA_HIFCR_CDMEIF5 | DMA_HIFCR_CFEIF5;
// enable DMA
DMA2_Stream5 - > CR | = DMA_SxCR_EN ;
q - > uart - > CR3 | = USART_CR3_DMAR ;
}
exit_critical_section ( ) ;
}
void DMA2_Stream5_IRQHandler ( void ) {
//set_led(LED_BLUE, 1);
uart_dma_drain ( ) ;
//set_led(LED_BLUE, 0);
}
void uart_init ( USART_TypeDef * u , int baud ) {
void uart_init ( USART_TypeDef * u , int baud ) {
// enable uart and tx+rx mode
// enable uart and tx+rx mode
u - > CR1 = USART_CR1_UE ;
u - > CR1 = USART_CR1_UE ;
@ -170,9 +217,23 @@ void uart_init(USART_TypeDef *u, int baud) {
// ** UART is ready to work **
// ** UART is ready to work **
// enable interrupts
// enable interrupts
if ( u ! = USART1 ) {
u - > CR1 | = USART_CR1_RXNEIE ;
u - > CR1 | = USART_CR1_RXNEIE ;
}
if ( u = = USART1 ) {
if ( u = = USART1 ) {
// DMA2, stream 2, channel 3
DMA2_Stream5 - > M0AR = ( uint32_t ) usart1_dma ;
DMA2_Stream5 - > NDTR = USART1_DMA_LEN ;
DMA2_Stream5 - > PAR = ( uint32_t ) & ( USART1 - > DR ) ;
// channel4, increment memory, periph -> memory, enable
DMA2_Stream5 - > CR = DMA_SxCR_CHSEL_2 | DMA_SxCR_MINC | DMA_SxCR_HTIE | DMA_SxCR_TCIE | DMA_SxCR_EN ;
// this one uses DMA receiver
u - > CR3 = USART_CR3_DMAR ;
NVIC_EnableIRQ ( DMA2_Stream5_IRQn ) ;
NVIC_EnableIRQ ( USART1_IRQn ) ;
NVIC_EnableIRQ ( USART1_IRQn ) ;
} else if ( u = = USART2 ) {
} else if ( u = = USART2 ) {
NVIC_EnableIRQ ( USART2_IRQn ) ;
NVIC_EnableIRQ ( USART2_IRQn ) ;