Document USART's private functions
This commit is contained in:
parent
fdc5f381f8
commit
b9285f2ab9
@ -21,20 +21,20 @@
|
||||
//--local definitions-----------------------------------------------------------
|
||||
|
||||
struct CircularBuffer {
|
||||
volatile uint8_t* buffer;
|
||||
uint16_t size;
|
||||
uint16_t begin;
|
||||
bool dmaLooped;
|
||||
volatile uint8_t* buffer; //the buffer to use as a circular buffer
|
||||
uint16_t size; //the size of the buffer
|
||||
uint16_t begin; //pointer to the current begin of the buffer
|
||||
bool dmaLooped; //whether the DMA looped or not (buffer overflow)
|
||||
};
|
||||
|
||||
struct FragmentedBuffer {
|
||||
uint8_t** buffers;
|
||||
uint16_t buffer_size;
|
||||
uint16_t byte_index;
|
||||
uint8_t buffer_nb;
|
||||
uint8_t free_buffer_nb;
|
||||
uint8_t buffer_index;
|
||||
uint8_t dma_buffer_index;
|
||||
uint8_t** buffers; //list of buffers to write to
|
||||
uint16_t buffer_size; //size of a single buffer
|
||||
uint16_t byte_index; //index of the current byte in the current buffer
|
||||
uint8_t buffer_nb; //total number of buffers
|
||||
uint8_t free_buffer_nb; //number of buffers not currently used
|
||||
uint8_t buffer_index; //index of the current buffer
|
||||
uint8_t dma_buffer_index; //index of the DMA's current buffer
|
||||
};
|
||||
|
||||
static void configure_usart(volatile struct USART* regs,
|
||||
@ -202,6 +202,10 @@ void usart_set_rx_buffer(enum UsartPeriph periph, uint8_t* buffer,
|
||||
|
||||
//--local functions-------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Apply the given configuration to the given registers. Generic version of
|
||||
* usart_configure()
|
||||
*/
|
||||
static void configure_usart(volatile struct USART* regs,
|
||||
enum UsartConfig config)
|
||||
{
|
||||
@ -279,6 +283,11 @@ static void configure_usart(volatile struct USART* regs,
|
||||
reg_set(regs->CR1, USART_CR1_UE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the given registers with the given baudrate. Baudrate is dependant
|
||||
* on the peripheric's clock and may not be exact due to precision errors (see
|
||||
* table 192 in documentation)
|
||||
*/
|
||||
static void configure_baudrate(volatile struct USART* regs, uint32_t clock,
|
||||
uint32_t baudrate)
|
||||
{
|
||||
@ -292,10 +301,17 @@ static void configure_baudrate(volatile struct USART* regs, uint32_t clock,
|
||||
reg_write(regs->BRR, USART_BRR_DIV_Fraction, divider & 0xF);
|
||||
}
|
||||
|
||||
/**
|
||||
* Non-blocking write to the given USART. Will return 0 if the write was
|
||||
* successfull, 1 otherwise. If the write is successfull, the tranfer complete
|
||||
* IRQ is enabled and the DMA disabled
|
||||
*/
|
||||
static uint32_t write_byte(volatile struct USART* regs, uint8_t byte)
|
||||
{
|
||||
//write if TX register empty
|
||||
if (regs->SR.TXE) {
|
||||
reg_write(regs->DR, USART_DR_DR, byte);
|
||||
//enable IRQ, disable DMA
|
||||
reg_reset(regs->CR3, USART_CR3_DMAT);
|
||||
reg_set(regs->CR1, USART_CR1_TXEIE);
|
||||
nvic_enable(NVIC_IRQ_USART1);
|
||||
@ -305,6 +321,10 @@ static uint32_t write_byte(volatile struct USART* regs, uint8_t byte)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the given byte to the given UART, using a FragmentedBuffer and a DMA
|
||||
* to bufferize the write if the peripheral is already busy.
|
||||
*/
|
||||
static uint32_t write_to_buffer(volatile struct USART *regs,
|
||||
volatile struct FragmentedBuffer *buffer, enum DmaChannel channel,
|
||||
uint8_t byte)
|
||||
@ -335,6 +355,7 @@ static uint32_t write_to_buffer(volatile struct USART *regs,
|
||||
dma_enter_critical(DMA_PERIPH_1, channel);
|
||||
}
|
||||
|
||||
//write the byte
|
||||
buffer->buffers[buffer->buffer_index][buffer->byte_index] = byte;
|
||||
++buffer->byte_index;
|
||||
|
||||
@ -342,11 +363,17 @@ static uint32_t write_to_buffer(volatile struct USART *regs,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the oldest byte from the given CircularBuffer if any. Returns 0 if the
|
||||
* read was successfull, 1 otherwise
|
||||
*/
|
||||
static uint32_t read_from_buffer(volatile struct CircularBuffer* buffer,
|
||||
enum DmaChannel channel, uint8_t* byte)
|
||||
{
|
||||
//retreive the current end of the buffer based on the DMA's progress
|
||||
uint16_t end = buffer->size - dma_get_remaining(DMA_PERIPH_1, channel);
|
||||
|
||||
//check for bytes to read and overflow
|
||||
if ((end > buffer->begin) && buffer->dmaLooped) {
|
||||
//TODO overflow
|
||||
buffer->begin = end;
|
||||
@ -355,6 +382,7 @@ static uint32_t read_from_buffer(volatile struct CircularBuffer* buffer,
|
||||
return 1;
|
||||
}
|
||||
|
||||
//read the oldest byte and advance the buffer
|
||||
*byte = buffer->buffer[buffer->begin];
|
||||
++buffer->begin;
|
||||
if (buffer->begin >= buffer->size) {
|
||||
@ -367,11 +395,16 @@ static uint32_t read_from_buffer(volatile struct CircularBuffer* buffer,
|
||||
|
||||
//--callbacks-------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Callback called on DMA TX tranfert's completion. Checks for any remaining
|
||||
* data to send. If any, starts a new transfer, else stop the DMA
|
||||
*/
|
||||
static void usart1_tx_callback(enum DmaIRQSource src)
|
||||
{
|
||||
(void)src; //only transfer complete expected
|
||||
volatile struct FragmentedBuffer* buffer = &usart1_tx_buffer;
|
||||
|
||||
//increment DMA's buffer since the last once has already been sent
|
||||
++buffer->dma_buffer_index;
|
||||
if (buffer->dma_buffer_index >= buffer->buffer_nb) {
|
||||
buffer->dma_buffer_index = 0;
|
||||
@ -384,6 +417,7 @@ static void usart1_tx_callback(enum DmaIRQSource src)
|
||||
return;
|
||||
}
|
||||
|
||||
//else start a new transfer
|
||||
dma_configure(DMA_PERIPH_1, DMA_CHANNEL_4,
|
||||
DMA_CONFIG_IRQ_COMPLETE | DMA_CONFIG_FROM_MEM
|
||||
| DMA_CONFIG_INC_MEM | DMA_CONFIG_PSIZE_8BITS
|
||||
@ -393,6 +427,8 @@ static void usart1_tx_callback(enum DmaIRQSource src)
|
||||
buffer->byte_index,
|
||||
usart1_tx_callback);
|
||||
|
||||
//if the newly transfering buffer was being written to, switch the current
|
||||
//buffer. Since we just ended a transfer, the next buffer should be empty
|
||||
if (buffer->dma_buffer_index == buffer->buffer_index)
|
||||
{
|
||||
++buffer->buffer_index;
|
||||
@ -403,6 +439,10 @@ static void usart1_tx_callback(enum DmaIRQSource src)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback called on DMA RX tranfert's completion. Sets a flag needed to
|
||||
* properly handle the circular buffer
|
||||
*/
|
||||
static void usart1_rx_callback(enum DmaIRQSource src)
|
||||
{
|
||||
(void)src; //only transfer complete expected
|
||||
|
||||
Loading…
Reference in New Issue
Block a user