optimize source code for size. reduce compiled binary size 292 bytes (#8428)

* optimize source code for size. reduce compiled binary size 292 bytes

* more size optimization
master
bottilabo 2020-05-14 05:22:27 +09:00 committed by GitHub
parent 7abbc95cd6
commit a41f973f75
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 79 additions and 65 deletions

View File

@ -15,6 +15,14 @@
extern const unsigned char font[] PROGMEM; extern const unsigned char font[] PROGMEM;
#ifndef OLED_BLANK_CHAR
#define OLED_BLANK_CHAR ' '
#endif
#ifndef OLED_BITS_FILTER
#define OLED_BITS_FILTER
#endif
// Set this to 1 to help diagnose early startup problems // Set this to 1 to help diagnose early startup problems
// when testing power-on with ble. Turn it off otherwise, // when testing power-on with ble. Turn it off otherwise,
// as the latency of printing most of the debug info messes // as the latency of printing most of the debug info messes
@ -27,7 +35,10 @@ extern const unsigned char font[] PROGMEM;
// 'last_flush' is declared as uint16_t, // 'last_flush' is declared as uint16_t,
// so this must be less than 65535 // so this must be less than 65535
#ifndef ScreenOffInterval
#define ScreenOffInterval 60000 /* milliseconds */ #define ScreenOffInterval 60000 /* milliseconds */
#endif
#if DEBUG_TO_SCREEN #if DEBUG_TO_SCREEN
static uint8_t displaying; static uint8_t displaying;
#endif #endif
@ -61,38 +72,32 @@ done:
return res; return res;
} }
// Write 2-byte command sequence.
// Returns true on success
static inline bool _send_cmd2(uint8_t cmd, uint8_t opr) {
if (!_send_cmd1(cmd)) {
return false;
}
return _send_cmd1(opr);
}
// Write 3-byte command sequence.
// Returns true on success
static inline bool _send_cmd3(uint8_t cmd, uint8_t opr1, uint8_t opr2) {
if (!_send_cmd1(cmd)) {
return false;
}
if (!_send_cmd1(opr1)) {
return false;
}
return _send_cmd1(opr2);
}
#define send_cmd1(c) if (!_send_cmd1(c)) {goto done;} #define send_cmd1(c) if (!_send_cmd1(c)) {goto done;}
#define send_cmd2(c,o) if (!_send_cmd2(c,o)) {goto done;} #define send_cmds(c) if (!_send_cmds(c,sizeof(c))) {goto done;}
#define send_cmd3(c,o1,o2) if (!_send_cmd3(c,o1,o2)) {goto done;} #define cmd1(X) X
#define cmd2(X,Y) X,Y
#define cmd3(X,Y,Z) X,Y,Z
static bool _send_cmds(const uint8_t* p,uint8_t sz) {
for(uint8_t i=sz;i;i--) {
send_cmd1( pgm_read_byte(p++) );
}
return true;
done:
return false;
}
#define SEND_CMDS(...) {static const uint8_t _cmds[] PROGMEM = { __VA_ARGS__,0 };send_cmds(_cmds);}
static void clear_display(void) { static void clear_display(void) {
matrix_clear(&display); matrix_clear(&display);
// Clear all of the display bits (there can be random noise // Clear all of the display bits (there can be random noise
// in the RAM on startup) // in the RAM on startup)
send_cmd3(PageAddr, 0, (DisplayHeight / 8) - 1); SEND_CMDS(
send_cmd3(ColumnAddr, 0, DisplayWidth - 1); cmd3(PageAddr, 0, (DisplayHeight / 8) - 1),
cmd3(ColumnAddr, 0, DisplayWidth - 1)
);
if (i2c_start_write(SSD1306_ADDRESS)) { if (i2c_start_write(SSD1306_ADDRESS)) {
goto done; goto done;
@ -101,8 +106,8 @@ static void clear_display(void) {
// Data mode // Data mode
goto done; goto done;
} }
for (uint8_t row = 0; row < MatrixRows; ++row) { for (uint8_t row = MatrixRows;row; row--) {
for (uint8_t col = 0; col < DisplayWidth; ++col) { for (uint8_t col = DisplayWidth; col; col--) {
i2c_master_write(0); i2c_master_write(0);
} }
} }
@ -130,37 +135,46 @@ bool iota_gfx_init(bool rotate) {
bool success = false; bool success = false;
i2c_master_init(); i2c_master_init();
send_cmd1(DisplayOff); SEND_CMDS(
send_cmd2(SetDisplayClockDiv, 0x80); cmd1(DisplayOff),
send_cmd2(SetMultiPlex, DisplayHeight - 1); cmd2(SetDisplayClockDiv, 0x80),
cmd2(SetMultiPlex, DisplayHeight - 1),
send_cmd2(SetDisplayOffset, 0); cmd2(SetDisplayOffset, 0),
cmd1(SetStartLine | 0x0),
cmd2(SetChargePump, 0x14 /* Enable */),
send_cmd1(SetStartLine | 0x0); cmd2(SetMemoryMode, 0 /* horizontal addressing */)
send_cmd2(SetChargePump, 0x14 /* Enable */); );
send_cmd2(SetMemoryMode, 0 /* horizontal addressing */);
if(rotate){ if(rotate){
// the following Flip the display orientation 180 degrees // the following Flip the display orientation 180 degrees
send_cmd1(SegRemap); SEND_CMDS(
send_cmd1(ComScanInc); cmd1(SegRemap),
cmd1(ComScanInc)
);
}else{ }else{
// Flips the display orientation 0 degrees // Flips the display orientation 0 degrees
send_cmd1(SegRemap | 0x1); SEND_CMDS(
send_cmd1(ComScanDec); cmd1(SegRemap | 0x1),
cmd1(ComScanDec)
);
} }
send_cmd2(SetComPins, 0x2); SEND_CMDS(
send_cmd2(SetContrast, 0x8f); #ifdef SSD1306_128X64
send_cmd2(SetPreCharge, 0xf1); cmd2(SetComPins, 0x12),
send_cmd2(SetVComDetect, 0x40); #else
send_cmd1(DisplayAllOnResume); cmd2(SetComPins, 0x2),
send_cmd1(NormalDisplay); #endif
send_cmd1(DeActivateScroll); cmd2(SetContrast, 0x8f),
send_cmd1(DisplayOn); cmd2(SetPreCharge, 0xf1),
cmd2(SetVComDetect, 0x40),
cmd1(DisplayAllOnResume),
cmd1(NormalDisplay),
cmd1(DeActivateScroll),
cmd1(DisplayOn),
send_cmd2(SetContrast, 0); // Dim cmd2(SetContrast, 0) // Dim
);
clear_display(); clear_display();
@ -205,7 +219,7 @@ void matrix_write_char_inner(struct CharacterMatrix *matrix, uint8_t c) {
memmove(&matrix->display[0], &matrix->display[1], memmove(&matrix->display[0], &matrix->display[1],
MatrixCols * (MatrixRows - 1)); MatrixCols * (MatrixRows - 1));
matrix->cursor = &matrix->display[MatrixRows - 1][0]; matrix->cursor = &matrix->display[MatrixRows - 1][0];
memset(matrix->cursor, ' ', MatrixCols); memset(matrix->cursor, OLED_BLANK_CHAR, MatrixCols);
} }
} }
@ -218,7 +232,7 @@ void matrix_write_char(struct CharacterMatrix *matrix, uint8_t c) {
uint8_t cursor_col = (matrix->cursor - &matrix->display[0][0]) % MatrixCols; uint8_t cursor_col = (matrix->cursor - &matrix->display[0][0]) % MatrixCols;
while (cursor_col++ < MatrixCols) { while (cursor_col++ < MatrixCols) {
matrix_write_char_inner(matrix, ' '); matrix_write_char_inner(matrix, OLED_BLANK_CHAR);
} }
return; return;
} }
@ -231,17 +245,15 @@ void iota_gfx_write_char(uint8_t c) {
} }
void matrix_write(struct CharacterMatrix *matrix, const char *data) { void matrix_write(struct CharacterMatrix *matrix, const char *data) {
const char *end = data + strlen(data); while (*data) {
while (data < end) {
matrix_write_char(matrix, *data); matrix_write_char(matrix, *data);
++data; ++data;
} }
} }
void matrix_write_ln(struct CharacterMatrix *matrix, const char *data) { void matrix_write_ln(struct CharacterMatrix *matrix, const char *data) {
char data_ln[strlen(data)+2]; matrix_write(matrix, data);
snprintf(data_ln, sizeof(data_ln), "%s\n", data); matrix_write(matrix, "\n");
matrix_write(matrix, data_ln);
} }
void iota_gfx_write(const char *data) { void iota_gfx_write(const char *data) {
@ -264,7 +276,7 @@ void iota_gfx_write_P(const char *data) {
} }
void matrix_clear(struct CharacterMatrix *matrix) { void matrix_clear(struct CharacterMatrix *matrix) {
memset(matrix->display, ' ', sizeof(matrix->display)); memset(matrix->display, OLED_BLANK_CHAR, sizeof(matrix->display));
matrix->cursor = &matrix->display[0][0]; matrix->cursor = &matrix->display[0][0];
matrix->dirty = true; matrix->dirty = true;
} }
@ -281,8 +293,10 @@ void matrix_render(struct CharacterMatrix *matrix) {
#endif #endif
// Move to the home position // Move to the home position
send_cmd3(PageAddr, 0, MatrixRows - 1); SEND_CMDS(
send_cmd3(ColumnAddr, 0, (MatrixCols * FontWidth) - 1); cmd3(PageAddr, 0, MatrixRows - 1),
cmd3(ColumnAddr, 0, (MatrixCols * FontWidth) - 1)
);
if (i2c_start_write(SSD1306_ADDRESS)) { if (i2c_start_write(SSD1306_ADDRESS)) {
goto done; goto done;
@ -298,7 +312,7 @@ void matrix_render(struct CharacterMatrix *matrix) {
for (uint8_t glyphCol = 0; glyphCol < FontWidth; ++glyphCol) { for (uint8_t glyphCol = 0; glyphCol < FontWidth; ++glyphCol) {
uint8_t colBits = pgm_read_byte(glyph + glyphCol); uint8_t colBits = pgm_read_byte(glyph + glyphCol);
i2c_master_write(colBits); i2c_master_write(colBits OLED_BITS_FILTER);
} }
// 1 column of space between chars (it's not included in the glyph) // 1 column of space between chars (it's not included in the glyph)
@ -331,7 +345,7 @@ void iota_gfx_task(void) {
force_dirty = false; force_dirty = false;
} }
if (timer_elapsed(last_flush) > ScreenOffInterval) { if (ScreenOffInterval !=0 && timer_elapsed(last_flush) > ScreenOffInterval) {
iota_gfx_off(); iota_gfx_off();
} }
} }