Optimize USART driver's code size

Using tables reduces code size while also improving lisibility. That is a
win-win
This commit is contained in:
Steins7 2024-04-06 22:56:28 +02:00
parent c6da4e11d8
commit 4eec301d17

View File

@ -29,50 +29,52 @@ static void configure_baudrate(volatile struct USART* regs, uint32_t clock,
//--local variables------------------------------------------------------------- //--local variables-------------------------------------------------------------
static volatile struct USART* const usart1 = (struct USART*)USART1_BASE_ADDRESS; static volatile struct USART* const usarts[] = {
static volatile struct USART* const usart2 = (struct USART*)USART2_BASE_ADDRESS; (struct USART*)USART1_BASE_ADDRESS,
static volatile struct USART* const usart3 = (struct USART*)USART3_BASE_ADDRESS; (struct USART*)USART2_BASE_ADDRESS,
(struct USART*)USART3_BASE_ADDRESS,
static const struct DmaParam usart1_rx_param = {
(void*)&usart1->DR,
DMA_CONFIG,
DMA_PERIPH_1,
DMA_CHANNEL_5,
}; };
static const struct DmaParam usart2_rx_param = { static const struct DmaParam usarts_rx_param[] = {
(void*)&usart2->DR, {
DMA_CONFIG, (void*)&usarts[USART_PERIPH_1]->DR,
DMA_PERIPH_1, DMA_CONFIG,
DMA_CHANNEL_6, DMA_PERIPH_1,
DMA_CHANNEL_5,
},
{
(void*)&usarts[USART_PERIPH_2]->DR,
DMA_CONFIG,
DMA_PERIPH_1,
DMA_CHANNEL_6,
},
{
(void*)&usarts[USART_PERIPH_3]->DR,
DMA_CONFIG,
DMA_PERIPH_1,
DMA_CHANNEL_3,
},
}; };
static const struct DmaParam usart3_rx_param = { static const struct DmaParam usarts_tx_param[] = {
(void*)&usart3->DR, {
DMA_CONFIG, (void*)&usarts[USART_PERIPH_1]->DR,
DMA_PERIPH_1, DMA_CONFIG,
DMA_CHANNEL_3, DMA_PERIPH_1,
}; DMA_CHANNEL_4,
},
static const struct DmaParam usart1_tx_param = { {
(void*)&usart1->DR, (void*)&usarts[USART_PERIPH_2]->DR,
DMA_CONFIG, DMA_CONFIG,
DMA_PERIPH_1, DMA_PERIPH_1,
DMA_CHANNEL_4, DMA_CHANNEL_7,
}; },
{
static const struct DmaParam usart2_tx_param = { (void*)&usarts[USART_PERIPH_3]->DR,
(void*)&usart2->DR, DMA_CONFIG,
DMA_CONFIG, DMA_PERIPH_1,
DMA_PERIPH_1, DMA_CHANNEL_2,
DMA_CHANNEL_7, },
};
static const struct DmaParam usart3_tx_param = {
(void*)&usart3->DR,
DMA_CONFIG,
DMA_PERIPH_1,
DMA_CHANNEL_2,
}; };
@ -87,18 +89,21 @@ void usart_configure(enum UsartPeriph periph, enum UsartConfig config,
switch (periph) { switch (periph) {
case USART_PERIPH_1: case USART_PERIPH_1:
rcc_enable(RCC_AHB_NONE, RCC_APB1_NONE, RCC_APB2_USART); rcc_enable(RCC_AHB_NONE, RCC_APB1_NONE, RCC_APB2_USART);
configure_baudrate(usart1, clocks.apb2_freq, baudrate); configure_baudrate(usarts[USART_PERIPH_1], clocks.apb2_freq,
configure_usart(usart1, config); baudrate);
configure_usart(usarts[USART_PERIPH_1], config);
break; break;
case USART_PERIPH_2: case USART_PERIPH_2:
rcc_enable(RCC_AHB_NONE, RCC_APB1_USART2, RCC_APB2_NONE); rcc_enable(RCC_AHB_NONE, RCC_APB1_USART2, RCC_APB2_NONE);
configure_baudrate(usart2, clocks.apb1_freq, baudrate); configure_baudrate(usarts[USART_PERIPH_2], clocks.apb1_freq,
configure_usart(usart2, config); baudrate);
configure_usart(usarts[USART_PERIPH_2], config);
break; break;
case USART_PERIPH_3: case USART_PERIPH_3:
rcc_enable(RCC_AHB_NONE, RCC_APB1_USART3, RCC_APB2_NONE); rcc_enable(RCC_AHB_NONE, RCC_APB1_USART3, RCC_APB2_NONE);
configure_baudrate(usart3, clocks.apb1_freq, baudrate); configure_baudrate(usarts[USART_PERIPH_3], clocks.apb1_freq,
configure_usart(usart3, config); baudrate);
configure_usart(usarts[USART_PERIPH_3], config);
break; break;
default: default:
break; break;
@ -107,25 +112,12 @@ void usart_configure(enum UsartPeriph periph, enum UsartConfig config,
uint32_t usart_read_byte(enum UsartPeriph periph, uint8_t* byte) uint32_t usart_read_byte(enum UsartPeriph periph, uint8_t* byte)
{ {
volatile struct USART* regs; if (periph > USART_PERIPH_3) {
return 1;
switch (periph) {
case USART_PERIPH_1:
regs = usart1;
break;
case USART_PERIPH_2:
regs = usart2;
break;
case USART_PERIPH_3:
regs = usart3;
break;
default:
return 1;
break;
} }
if (regs->SR.RXNE) { if (usarts[periph]->SR.RXNE) {
*byte = regs->DR.DR; *byte = usarts[periph]->DR.DR;
return 0; return 0;
} else { } else {
return 1; return 1;
@ -134,26 +126,13 @@ uint32_t usart_read_byte(enum UsartPeriph periph, uint8_t* byte)
uint32_t usart_write_byte(enum UsartPeriph periph, uint8_t byte) uint32_t usart_write_byte(enum UsartPeriph periph, uint8_t byte)
{ {
volatile struct USART* regs; if (periph > USART_PERIPH_3) {
return 1;
switch (periph) {
case USART_PERIPH_1:
regs = usart1;
break;
case USART_PERIPH_2:
regs = usart2;
break;
case USART_PERIPH_3:
regs = usart3;
break;
default:
return 1;
break;
} }
//only write data if the tx register it empty, give up otherwise //only write data if the tx register it empty, give up otherwise
if (regs->SR.TXE) { if (usarts[periph]->SR.TXE) {
reg_write(regs->DR, USART_DR_DR, byte); reg_write(usarts[periph]->DR, USART_DR_DR, byte);
return 0; return 0;
} else { } else {
return 1; return 1;
@ -162,50 +141,22 @@ uint32_t usart_write_byte(enum UsartPeriph periph, uint8_t byte)
const struct DmaParam* usart_configure_rx_dma(enum UsartPeriph periph) const struct DmaParam* usart_configure_rx_dma(enum UsartPeriph periph)
{ {
const struct DmaParam* param; if (periph > USART_PERIPH_3) {
return nullptr;
switch (periph) {
case USART_PERIPH_1:
param = &usart1_rx_param;
reg_set(usart1->CR3, USART_CR3_DMAR);
break;
case USART_PERIPH_2:
param = &usart2_rx_param;
reg_set(usart2->CR3, USART_CR3_DMAR);
break;
case USART_PERIPH_3:
param = &usart3_rx_param;
reg_set(usart3->CR3, USART_CR3_DMAR);
break;
default:
return nullptr;
} }
return param; reg_set(usarts[periph]->CR3, USART_CR3_DMAR);
return &usarts_rx_param[periph];
} }
const struct DmaParam* usart_configure_tx_dma(enum UsartPeriph periph) const struct DmaParam* usart_configure_tx_dma(enum UsartPeriph periph)
{ {
const struct DmaParam* param; if (periph > USART_PERIPH_3) {
return nullptr;
switch (periph) {
case USART_PERIPH_1:
param = &usart1_tx_param;
reg_set(usart1->CR3, USART_CR3_DMAT);
break;
case USART_PERIPH_2:
param = &usart2_tx_param;
reg_set(usart2->CR3, USART_CR3_DMAT);
break;
case USART_PERIPH_3:
param = &usart3_tx_param;
reg_set(usart3->CR3, USART_CR3_DMAT);
break;
default:
return nullptr;
} }
return param; reg_set(usarts[periph]->CR3, USART_CR3_DMAT);
return &usarts_tx_param[periph];
} }