I'm trying to write a library for my hobbyish purpose and it's almost ready for a smoke test. The only thing that annoys me is a called-once fuction :
(Note: all uppercase phrases are macro constants)
{
/////////// Interface clock enable
LCD_CTRL_PORT_CLK_EN;
LCD_DATA_PORT_CLK_EN;
//////////// Config control pins
//// pull up
LCD_CTRL_PORT->PUPDR &= ~LCD_CTRL_PORT_32BIT_MASK;
LCD_CTRL_PORT->PUPDR |= ( (0b01 << (LCD_CS_POS*2U))
| (0b01 << (LCD_RS_POS*2U))
| (0b01 << (LCD_WR_POS*2U))
| (0b01 << (LCD_RD_POS*2U))
| (0b01 << (LCD_RST_POS*2U)) );
//// set output direction
LCD_CTRL_PORT->MODER &= ~LCD_CTRL_PORT_32BIT_MASK;
LCD_CTRL_PORT->MODER |= ( (0b01 << (LCD_CS_POS*2U))
| (0b01 << (LCD_RS_POS*2U))
| (0b01 << (LCD_WR_POS*2U))
| (0b01 << (LCD_RD_POS*2U))
| (0b01 << (LCD_RST_POS*2U)) );
//// Max output speed
LCD_CTRL_PORT->OSPEEDR &= ~LCD_CTRL_PORT_32BIT_MASK;
LCD_CTRL_PORT->OSPEEDR |= ( (0b11 << (LCD_CS_POS*2U))
| (0b11 << (LCD_RS_POS*2U))
| (0b11 << (LCD_WR_POS*2U))
| (0b11 << (LCD_RD_POS*2U))
| (0b11 << (LCD_RST_POS*2U)) );
//// all control pin set HIGH (idle)
LCD_CTRL_PORT->BSRR |= (LCD_CS | LCD_RS | LCD_WR | LCD_RD | LCD_RST);
////////
//////////// Config data pins
LCD_DATA_PORT->PUPDR &= ~LCD_CTRL_PORT_32BIT_MASK;
LCD_DATA_PORT->OSPEEDR &= ~LCD_DATA_PORT_32BIT_MASK;
LCD_DATA_PORT->MODER &= ~LCD_CTRL_PORT_32BIT_MASK;
#if LCD_USE8BIT_MODE == 1
LCD_DATA_PORT->PUPDR |= ( 0x5555 << (LCD_DATAPORT_OUTPUT_OFFSET*2U) );
LCD_DATA_PORT->OSPEEDR |= ( 0xFFFF << (LCD_DATAPORT_OUTPUT_OFFSET*2U) );
LCD_DATA_PORT->MODER |= ( 0x5555 << (LCD_DATAPORT_OUTPUT_OFFSET*2U) );
LCD_DATA_PORT->BSRR = ( 0xFF << (LCD_DATAPORT_OUTPUT_OFFSET*2U) );
#else
LCD_DATA_PORT->PUPDR |= 0x55555555;
LCD_DATA_PORT->OSPEEDR |= 0xFFFFFFFF;
LCD_DATA_PORT->MODER |= 0x55555555;
LCD_DATA_PORT->BSRR = 0xFFFF;
#endif
I'm using True Studio and the platform is STM32F3. The function just plainly modifies some registers with constants derived from some macro constants.
But why it does cost almost 1 kB of flash (in .text section, I'm using Truestudio's build analyzer) although it isn't quite long ? Even HAL-GPIO function is 3x smaller.
Example macro:
#define LCD_XXXX_PORT GPIOX
#define LCD_XXX GPIO_PIN_X
#define LCD_XXX_POS POSITION_VAL(LCD_XXX)
register int *LCD_CTRL_PORT;
(But then replaceint
with the real type of the LCD control port typedef) \$\endgroup\$