diff --git a/drivers/usart.c b/drivers/usart.c index e317567..f6ae0a3 100644 --- a/drivers/usart.c +++ b/drivers/usart.c @@ -167,14 +167,13 @@ void usart_set_tx_buffer(enum UsartPeriph periph, uint8_t** buffers, #warning "check for null ptr" -// for (uint8_t i = 0; i < sizeof(struct FragmentedBuffer); ++i) -// { -// ((uint8_t*)(&buffer))[i] = 0; -// } buffer->buffers = buffers; buffer->buffer_size = buffer_size; + buffer->byte_index = 0; buffer->buffer_nb = buffer_nb; - buffer->free_buffer_nb = buffer_nb; + buffer->free_buffer_nb = buffer_nb - 1; + buffer->buffer_index = 0; + buffer->dma_buffer_index = 0; } void usart_set_rx_buffer(enum UsartPeriph periph, uint8_t* buffer, @@ -312,14 +311,16 @@ static uint32_t write_to_buffer(volatile struct USART *regs, { //if the tx register is empty, there is no need to go through the dma if (!write_byte(regs, byte)) { - //TODO enable IRQ return 0; } + dma_enter_critical(DMA_PERIPH_1, channel); + //if the current buffer is full, we need to switch it with an empty one if (buffer->byte_index >= buffer->buffer_size) { //if all buffer full, simply wait for the DMA to empty one + dma_exit_critical(DMA_PERIPH_1, channel); while (buffer->free_buffer_nb == 0) {} dma_enter_critical(DMA_PERIPH_1, channel); @@ -388,9 +389,18 @@ static void usart1_tx_callback(enum DmaIRQSource src) | DMA_CONFIG_INC_MEM | DMA_CONFIG_PSIZE_8BITS | DMA_CONFIG_MSIZE_8BITS | DMA_CONFIG_PRIO_LOW, (void*)&usart1->DR, - (void*)&buffer->buffers[buffer->dma_buffer_index], + (void*)buffer->buffers[buffer->dma_buffer_index], buffer->byte_index, usart1_tx_callback); + + if (buffer->dma_buffer_index == buffer->buffer_index) + { + ++buffer->buffer_index; + if (buffer->buffer_index >= buffer->buffer_nb) { + buffer->buffer_index = 0; + } + buffer->byte_index = 0; + } } static void usart1_rx_callback(enum DmaIRQSource src) @@ -405,6 +415,9 @@ static void usart1_rx_callback(enum DmaIRQSource src) void hdr_usart1(void) { nvic_clear_pending(NVIC_IRQ_USART1); + nvic_disable(NVIC_IRQ_USART1); + reg_reset(usart1->CR1, USART_CR1_TXEIE); + reg_set(usart1->CR3, USART_CR3_DMAT); volatile struct FragmentedBuffer* buffer = &usart1_tx_buffer; @@ -414,17 +427,22 @@ void hdr_usart1(void) return; } - reg_set(usart1->CR3, USART_CR3_DMAT); - reg_reset(usart1->CR1, USART_CR1_TXEIE); - nvic_disable(NVIC_IRQ_USART1); - dma_configure(DMA_PERIPH_1, DMA_CHANNEL_4, DMA_CONFIG_IRQ_COMPLETE | DMA_CONFIG_FROM_MEM | DMA_CONFIG_INC_MEM | DMA_CONFIG_PSIZE_8BITS | DMA_CONFIG_MSIZE_8BITS | DMA_CONFIG_PRIO_LOW, (void*)&usart1->DR, - (void*)&buffer->buffers[buffer->dma_buffer_index], + (void*)buffer->buffers[buffer->dma_buffer_index], buffer->byte_index, usart1_tx_callback); + + if (buffer->dma_buffer_index == buffer->buffer_index) + { + ++buffer->buffer_index; + if (buffer->buffer_index >= buffer->buffer_nb) { + buffer->buffer_index = 0; + } + buffer->byte_index = 0; + } }