diff --git a/drivers/usart.c b/drivers/usart.c index 017df30..0b8406c 100644 --- a/drivers/usart.c +++ b/drivers/usart.c @@ -12,6 +12,9 @@ #include "reg.h" #include "rcc.h" +#include "dma.h" + +#include "stddef.h" //--local definitions----------------------------------------------------------- @@ -20,14 +23,23 @@ static volatile struct USART* const usart1 = (struct USART*)USART1_BASE_ADDRESS; static volatile struct USART* const usart2 = (struct USART*)USART2_BASE_ADDRESS; static volatile struct USART* const usart3 = (struct USART*)USART3_BASE_ADDRESS; -void configure_usart(volatile struct USART* regs, enum UsartConfig config); -void configure_baudrate(volatile struct USART* regs, uint32_t clock, +static void configure_usart(volatile struct USART* regs, + enum UsartConfig config); +static void configure_baudrate(volatile struct USART* regs, uint32_t clock, uint32_t baudrate); -uint32_t periph_regs(enum UsartPeriph periph, volatile struct USART** regs); +static uint32_t periph_regs(enum UsartPeriph periph, + volatile struct USART** regs); +static uint32_t read_from_buffer(volatile uint8_t* buffer, + enum DmaChannel channel, uint8_t* byte); + +static void usart1_rx_callback(enum DmaIRQSource src); //--local variables------------------------------------------------------------- +static volatile uint8_t* usart1_rx_buffer; + + //--public functions------------------------------------------------------------ void usart_configure(enum UsartPeriph periph, enum UsartConfig config, @@ -75,21 +87,58 @@ uint32_t usart_write_byte(enum UsartPeriph periph, uint8_t byte) uint32_t usart_read_byte(enum UsartPeriph periph, uint8_t* byte) { volatile struct USART* regs; - if (periph_regs(periph, ®s)) { - return 1; + volatile uint8_t* buffer; + enum DmaChannel dma_channel; + + switch (periph) { + case USART_PERIPH_1: + regs = usart1; + buffer = usart1_rx_buffer; + dma_channel = DMA_CHANNEL_5; + break; + case USART_PERIPH_2: + case USART_PERIPH_3: + default: + return 1; + break; } - if (regs->SR.RXNE) { - *byte = regs->DR.DR; - return 0; + if (buffer) { + return read_from_buffer(buffer, dma_channel, byte); } else { - return 1; + if (regs->SR.RXNE) { + *byte = regs->DR.DR; + return 0; + } else { + return 1; + } + } +} + +void usart_set_rx_buffer(enum UsartPeriph periph, uint8_t* buffer, + uint16_t size) +{ + switch (periph) { + case USART_PERIPH_1: + dma_configure(DMA_PERIPH_1, DMA_CHANNEL_5, + DMA_CONFIG_IRQ_COMPLETE | DMA_CONFIG_FROM_PERIPH + | DMA_CONFIG_CIRCULAR | DMA_CONFIG_INC_MEM + | DMA_CONFIG_PSIZE_8BITS | DMA_CONFIG_MSIZE_8BITS + | DMA_CONFIG_PRIO_LOW, (void*)&usart1->DR, buffer, + size, usart1_rx_callback); + usart1_rx_buffer = buffer; + reg_set(usart1->CR3, USART_CR3_DMAR); + break; + case USART_PERIPH_2: + break; + case USART_PERIPH_3: + break; } } //--local functions------------------------------------------------------------- -void configure_usart(volatile struct USART* regs, enum UsartConfig config) +static void configure_usart(volatile struct USART* regs, enum UsartConfig config) { //configure parity switch (config) @@ -165,7 +214,7 @@ void configure_usart(volatile struct USART* regs, enum UsartConfig config) reg_set(regs->CR1, USART_CR1_UE); } -void configure_baudrate(volatile struct USART* regs, uint32_t clock, +static void configure_baudrate(volatile struct USART* regs, uint32_t clock, uint32_t baudrate) { uint32_t mantissa = clock / (baudrate * 16); @@ -178,7 +227,7 @@ void configure_baudrate(volatile struct USART* regs, uint32_t clock, reg_write(regs->BRR, USART_BRR_DIV_Fraction, divider & 0xF); } -uint32_t periph_regs(enum UsartPeriph periph, volatile struct USART** regs) +static uint32_t periph_regs(enum UsartPeriph periph, volatile struct USART** regs) { switch (periph) { case USART_PERIPH_1: @@ -198,3 +247,16 @@ uint32_t periph_regs(enum UsartPeriph periph, volatile struct USART** regs) return 0; } +static uint32_t read_from_buffer(volatile uint8_t* buffer, + enum DmaChannel channel, uint8_t* byte) +{ + +} + +//--callbacks------------------------------------------------------------------- + +static void usart1_rx_callback(enum DmaIRQSource src) +{ + +} + diff --git a/drivers/usart.h b/drivers/usart.h index c5845c1..ed68b3f 100644 --- a/drivers/usart.h +++ b/drivers/usart.h @@ -46,6 +46,12 @@ uint32_t usart_write_byte(enum UsartPeriph periph, uint8_t byte); uint32_t usart_read_byte(enum UsartPeriph periph, uint8_t* byte); +void usart_set_tx_buffer(enum UsartPeriph periph, uint8_t* buffer, + uint16_t size); + +void usart_set_rx_buffer(enum UsartPeriph periph, uint8_t* buffer, + uint16_t size); + #endif //_USART_H_