rework #4

Merged
Steins7 merged 88 commits from rework into dev 2024-04-20 18:20:23 +00:00
7 changed files with 56 additions and 45 deletions
Showing only changes of commit fd33003e26 - Show all commits

View File

@ -19,9 +19,9 @@
//--local definitions----------------------------------------------------------- //--local definitions-----------------------------------------------------------
static void configure_dma(volatile struct DMA* dma, enum DmaChannel channel, static void configure_dma(volatile struct DMA* dma, enum DmaChannel channel,
enum DmaConfig config_mask, volatile void* periph, volatile void* mem, enum DmaConfig config_mask, volatile void* periph);
uint16_t size); static void start_dma(volatile struct DMA* dma, enum DmaChannel channel,
volatile void* mem, uint16_t size);
//--local variables------------------------------------------------------------- //--local variables-------------------------------------------------------------
@ -36,8 +36,8 @@ static volatile void* dma2_cb_params[5];
//--public functions------------------------------------------------------------ //--public functions------------------------------------------------------------
void dma_configure(enum DmaPeriph dma, enum DmaChannel channel, void dma_configure(enum DmaPeriph dma, enum DmaChannel channel,
enum DmaConfig config_mask, volatile void* periph, volatile void* mem, enum DmaConfig config_mask, volatile void* periph,
uint16_t size, DmaCallback callback, volatile void* cb_param) DmaCallback callback, volatile void* cb_param)
{ {
//reset peripheral first, to ensure proper configuration //reset peripheral first, to ensure proper configuration
dma_reset(dma, channel); dma_reset(dma, channel);
@ -45,7 +45,7 @@ void dma_configure(enum DmaPeriph dma, enum DmaChannel channel,
switch (dma) { switch (dma) {
case DMA_PERIPH_1: case DMA_PERIPH_1:
rcc_enable(RCC_AHB_DMA1, RCC_APB1_NONE, RCC_APB2_NONE); rcc_enable(RCC_AHB_DMA1, RCC_APB1_NONE, RCC_APB2_NONE);
configure_dma(dma1, channel, config_mask, periph, mem, size); configure_dma(dma1, channel, config_mask, periph);
if (callback) { if (callback) {
dma1_callbacks[channel] = callback; dma1_callbacks[channel] = callback;
dma1_cb_params[channel] = cb_param; dma1_cb_params[channel] = cb_param;
@ -54,7 +54,7 @@ void dma_configure(enum DmaPeriph dma, enum DmaChannel channel,
break; break;
case DMA_PERIPH_2: case DMA_PERIPH_2:
rcc_enable(RCC_AHB_DMA2, RCC_APB1_NONE, RCC_APB2_NONE); rcc_enable(RCC_AHB_DMA2, RCC_APB1_NONE, RCC_APB2_NONE);
configure_dma(dma2, channel, config_mask, periph, mem, size); configure_dma(dma2, channel, config_mask, periph);
if (callback) { if (callback) {
dma2_callbacks[channel] = callback; dma2_callbacks[channel] = callback;
dma2_cb_params[channel] = cb_param; dma2_cb_params[channel] = cb_param;
@ -110,20 +110,21 @@ void dma_exit_critical(enum DmaPeriph dma, enum DmaChannel channel)
} }
} }
void dma_enable(enum DmaPeriph dma, enum DmaChannel channel) void dma_start(enum DmaPeriph dma, enum DmaChannel channel,
volatile void* mem, uint16_t size)
{ {
switch (dma) { switch (dma) {
case DMA_PERIPH_1: case DMA_PERIPH_1:
reg_set(dma1->CHANNELS[channel].CCR, DMA_CCR_EN);
if (dma1_callbacks[channel]) { if (dma1_callbacks[channel]) {
nvic_enable(NVIC_IRQ_DMA1_CHANNEL1 + channel); nvic_enable(NVIC_IRQ_DMA1_CHANNEL1 + channel);
} }
start_dma(dma1, channel, mem, size);
break; break;
case DMA_PERIPH_2: case DMA_PERIPH_2:
reg_set(dma2->CHANNELS[channel].CCR, DMA_CCR_EN);
if (dma2_callbacks[channel]) { if (dma2_callbacks[channel]) {
nvic_enable(NVIC_IRQ_DMA2_CHANNEL1 + channel); nvic_enable(NVIC_IRQ_DMA2_CHANNEL1 + channel);
} }
start_dma(dma2, channel, mem, size);
break; break;
default: default:
return; return;
@ -146,7 +147,7 @@ void dma_enter_critical(enum DmaPeriph dma, enum DmaChannel channel)
} }
} }
void dma_disable(enum DmaPeriph dma, enum DmaChannel channel) void dma_stop(enum DmaPeriph dma, enum DmaChannel channel)
{ {
switch (dma) { switch (dma) {
case DMA_PERIPH_1: case DMA_PERIPH_1:
@ -185,21 +186,27 @@ uint16_t dma_get_remaining(enum DmaPeriph dma, enum DmaChannel channel)
//--local functions------------------------------------------------------------- //--local functions-------------------------------------------------------------
static void configure_dma(volatile struct DMA* dma, enum DmaChannel channel, static void configure_dma(volatile struct DMA* dma, enum DmaChannel channel,
enum DmaConfig config_mask, volatile void* periph, volatile void* mem, enum DmaConfig config_mask, volatile void* periph)
uint16_t size)
{ {
volatile struct DMA_CHANNEL* regs = &dma->CHANNELS[channel]; volatile struct DMA_CHANNEL* regs = &dma->CHANNELS[channel];
//registers should already be at reset value, apply new config //registers should already be at reset value, apply new config
regs->CCR.word = config_mask; regs->CCR.word = config_mask;
reg_write(regs->CNDTR, DMA_CNDTR_NDT, size);
regs->CPAR = (uint32_t)periph; regs->CPAR = (uint32_t)periph;
regs->CMAR = (uint32_t)mem;
//only enable channel when everything is configured
reg_set(regs->CCR, DMA_CCR_EN);
} }
static void start_dma(volatile struct DMA* dma, enum DmaChannel channel,
volatile void* mem, uint16_t size)
{
volatile struct DMA_CHANNEL* regs = &dma->CHANNELS[channel];
//registers should already be configured, apply transfer config
reg_write(regs->CNDTR, DMA_CNDTR_NDT, size);
regs->CMAR = (uint32_t)mem;
//only start transfer when everything is configured
reg_set(regs->CCR, DMA_CCR_EN);
}
//--ISRs------------------------------------------------------------------------ //--ISRs------------------------------------------------------------------------

View File

@ -88,8 +88,8 @@ struct DmaParam {
//--functions------------------------------------------------------------------- //--functions-------------------------------------------------------------------
void dma_configure(enum DmaPeriph dma, enum DmaChannel channel, void dma_configure(enum DmaPeriph dma, enum DmaChannel channel,
enum DmaConfig config_mask, volatile void* periph, volatile void* mem, enum DmaConfig config_mask, volatile void* periph,
uint16_t size, DmaCallback callback, volatile void* cb_param); DmaCallback callback, volatile void* cb_param);
void dma_configure_mem2mem(enum DmaPeriph dma, enum DmaChannel channel, void dma_configure_mem2mem(enum DmaPeriph dma, enum DmaChannel channel,
enum DmaConfigM2M config_mask, const void* src, void* dest, enum DmaConfigM2M config_mask, const void* src, void* dest,
@ -99,11 +99,12 @@ void dma_reset(enum DmaPeriph dma, enum DmaChannel channel);
void dma_exit_critical(enum DmaPeriph dma, enum DmaChannel channel); void dma_exit_critical(enum DmaPeriph dma, enum DmaChannel channel);
void dma_enable(enum DmaPeriph dma, enum DmaChannel channel); void dma_start(enum DmaPeriph dma, enum DmaChannel channel,
volatile void* mem, uint16_t size);
void dma_enter_critical(enum DmaPeriph dma, enum DmaChannel channel); void dma_enter_critical(enum DmaPeriph dma, enum DmaChannel channel);
void dma_disable(enum DmaPeriph dma, enum DmaChannel channel); void dma_stop(enum DmaPeriph dma, enum DmaChannel channel);
uint16_t dma_get_remaining(enum DmaPeriph dma, enum DmaChannel channe); uint16_t dma_get_remaining(enum DmaPeriph dma, enum DmaChannel channe);

View File

@ -192,12 +192,15 @@ const struct DmaParam* usart_configure_tx_dma(enum UsartPeriph periph)
switch (periph) { switch (periph) {
case USART_PERIPH_1: case USART_PERIPH_1:
param = &usart1_tx_param; param = &usart1_tx_param;
reg_set(usart1->CR3, USART_CR3_DMAT);
break; break;
case USART_PERIPH_2: case USART_PERIPH_2:
param = &usart2_tx_param; param = &usart2_tx_param;
reg_set(usart2->CR3, USART_CR3_DMAT);
break; break;
case USART_PERIPH_3: case USART_PERIPH_3:
param = &usart3_tx_param; param = &usart3_tx_param;
reg_set(usart3->CR3, USART_CR3_DMAT);
break; break;
default: default:
return nullptr; return nullptr;

View File

@ -31,17 +31,18 @@ void dma_cbuf_configure(volatile struct DmaCircBuffer* buffer,
buffer->buffer = raw_buffer; buffer->buffer = raw_buffer;
buffer->param = param;
buffer->priority = priority;
buffer->size = buffer_size; buffer->size = buffer_size;
buffer->begin = 0; buffer->begin = 0;
buffer->dma = param->dma;
buffer->channel = param->channel;
buffer->dma_looped = false; buffer->dma_looped = false;
dma_configure(buffer->param->dma, buffer->param->channel, dma_configure(buffer->dma, buffer->channel,
buffer->param->config, buffer->param->periph, DMA_CONFIG | param->config | priority,
buffer->buffer, buffer->size, cbuf_callback, buffer); param->periph, cbuf_callback, buffer);
dma_start(buffer->dma, buffer->channel, buffer->buffer, buffer->size);
} }
uint32_t dma_cbuf_read_byte(volatile struct DmaCircBuffer* buffer, uint32_t dma_cbuf_read_byte(volatile struct DmaCircBuffer* buffer,
@ -49,7 +50,7 @@ uint32_t dma_cbuf_read_byte(volatile struct DmaCircBuffer* buffer,
{ {
//retreive the current end of the buffer based on the DMA's progress //retreive the current end of the buffer based on the DMA's progress
uint16_t end = buffer->size uint16_t end = buffer->size
- dma_get_remaining(buffer->param->dma, buffer->param->channel); - dma_get_remaining(buffer->dma, buffer->channel);
//check for bytes to read and overflow //check for bytes to read and overflow
if ((end > buffer->begin) && buffer->dma_looped) { if ((end > buffer->begin) && buffer->dma_looped) {
@ -85,4 +86,3 @@ static void cbuf_callback(enum DmaIRQSource src, volatile void* param)
buffer->dma_looped = true; buffer->dma_looped = true;
} }

View File

@ -23,12 +23,12 @@
struct DmaCircBuffer { struct DmaCircBuffer {
volatile void* buffer; //the buffer to use as a circular buffer volatile void* buffer; //the buffer to use as a circular buffer
const struct DmaParam* param;
enum DmaConfig priority; //DMA config, must correspond to peripheral
uint16_t size; //the size of the buffer uint16_t size; //the size of the buffer
uint16_t begin; //pointer to the current begin of the buffer uint16_t begin; //pointer to the current begin of the buffer
enum DmaPeriph dma;
enum DmaChannel channel;
bool dma_looped; //whether the DMA looped or not (buffer overflow) bool dma_looped; //whether the DMA looped or not (buffer overflow)
}; };

View File

@ -31,15 +31,18 @@ void dma_mbuf_configure(volatile struct DmaMultiBuffer* buffer,
buffer->raw_buffer = raw_buffer; buffer->raw_buffer = raw_buffer;
buffer->param = param;
buffer->priority = priority;
buffer->buffer_size = buffer_size / 2; buffer->buffer_size = buffer_size / 2;
buffer->byte_index = 0; buffer->byte_index = 0;
buffer->buffer_index = 0; buffer->buffer_index = 0;
buffer->dma = param->dma;
buffer->channel = param->channel;
buffer->dma_running = false; buffer->dma_running = false;
dma_configure(buffer->dma, buffer->channel,
DMA_CONFIG | param->config | priority,
param->periph, mbuf_callback, buffer);
} }
uint32_t dma_mbuf_write_byte(volatile struct DmaMultiBuffer* buffer, uint32_t dma_mbuf_write_byte(volatile struct DmaMultiBuffer* buffer,
@ -66,12 +69,10 @@ void dma_mbuf_switch(volatile struct DmaMultiBuffer* buffer)
} }
//start a new transfer //start a new transfer
dma_configure(buffer->param->dma, buffer->param->channel,
DMA_CONFIG | buffer->param->config | buffer->priority,
buffer->param->periph,
&buffer->raw_buffer[buffer->buffer_index * buffer->buffer_size],
buffer->byte_index, mbuf_callback, buffer);
buffer->dma_running = true; buffer->dma_running = true;
dma_start(buffer->dma, buffer->channel,
&buffer->raw_buffer[buffer->buffer_index * buffer->buffer_size],
buffer->byte_index);
buffer->byte_index = 0; buffer->byte_index = 0;
++buffer->buffer_index; ++buffer->buffer_index;
@ -93,7 +94,7 @@ static void mbuf_callback(enum DmaIRQSource src, volatile void* param)
{ {
(void)src; //only transfer complete expected (void)src; //only transfer complete expected
volatile struct DmaMultiBuffer* buffer = param; volatile struct DmaMultiBuffer* buffer = param;
dma_stop(buffer->dma, buffer->channel);
buffer->dma_running = false; buffer->dma_running = false;
} }

View File

@ -23,13 +23,12 @@
struct DmaMultiBuffer { struct DmaMultiBuffer {
uint8_t* raw_buffer; uint8_t* raw_buffer;
const struct DmaParam* param;
enum DmaConfig priority;
uint16_t buffer_size; uint16_t buffer_size;
uint8_t byte_index; uint8_t byte_index;
uint8_t buffer_index; uint8_t buffer_index;
enum DmaPeriph dma;
enum DmaChannel channel;
bool dma_running; bool dma_running;
}; };