From 2f251e0ad712d51d822a49308aa736e98711b4c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?King=20K=C3=A9vin?= Date: Thu, 20 Aug 2020 13:52:16 +0200 Subject: [PATCH] led_tm1637: fix updating (both command and data need to be sent every time --- lib/led_tm1637.c | 83 +++++++++++++++++++++++------------------------- 1 file changed, 40 insertions(+), 43 deletions(-) diff --git a/lib/led_tm1637.c b/lib/led_tm1637.c index 44e7b08..a096066 100644 --- a/lib/led_tm1637.c +++ b/lib/led_tm1637.c @@ -46,6 +46,8 @@ static enum led_tm1637_brightness_t display_brightness = LED_TM1637_14DIV16; /** if display is on */ static bool display_on = false; +/** display buffer */ +static uint8_t led_tm1637_digits[4] = {0}; /** ASCII characters encoded for the 7 segments digit block * @note starts with space @@ -164,7 +166,7 @@ void led_tm1637_setup(void) rcc_periph_reset_pulse(RST_TIM(LED_TM1637_TIMER)); // reset timer state timer_set_mode(TIM(LED_TM1637_TIMER), TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP); // set timer mode, use undivided timer clock, edge alignment (simple count), and count up timer_set_prescaler(TIM(LED_TM1637_TIMER), 0); // don't prescale to get most precise timing ( 1/(72E6/1/(2**16))=0.91 ms > 0.5 us ) - timer_set_period(TIM(LED_TM1637_TIMER), 500); // set the clock frequency (emprical value until the signal starts to look bad) + timer_set_period(TIM(LED_TM1637_TIMER), 500); // set the clock frequency (empirical value until the signal starts to look bad) timer_clear_flag(TIM(LED_TM1637_TIMER), TIM_SR_UIF); // clear flag timer_update_on_overflow(TIM(LED_TM1637_TIMER)); // only use counter overflow as UEV source (use overflow as start time or timeout) } @@ -238,79 +240,73 @@ static bool led_tm1637_write(const uint8_t* data, size_t length) return to_return; } +/** write all data to SRAM (automatic address adding, normal) and control display + * @return if write succeeded + */ +static bool led_tm1637_update(void) +{ + const uint8_t write[] = { 0x40 }; // command: write data, automatic address adding, normal + const uint8_t data[] = { 0xc0, led_tm1637_digits[0], led_tm1637_digits[1], led_tm1637_digits[2], led_tm1637_digits[3] }; // set digits (start at address 0) + const uint8_t control[] = { (display_on ? 0x88 : 0x80) + (display_brightness & 0x7) }; // command to turn display on/off and set brightness + return led_tm1637_write(write, LENGTH(write)) && led_tm1637_write(data, LENGTH(data)) && led_tm1637_write(control, LENGTH(control)); // send commands +} + bool led_tm1637_on(void) { - uint8_t data[] = { 0x88 + display_brightness }; // command to turn display on (use set brightness) - bool to_return = false; // result to return - if (led_tm1637_write(data, LENGTH(data))) { // send command - display_on = true; // remember display is on - to_return = true; // command succeeded - } - return to_return; // return result + display_on = true; // remember display is on + return led_tm1637_update(); } bool led_tm1637_off(void) { - uint8_t data[] = { 0x80 + display_brightness }; // command to turn display off (use set brightness) - if (led_tm1637_write(data, LENGTH(data))) { // send command - display_on = false; // remember display is off - return true; // command succeeded - } - return false; // return result + display_on = false; // remember display is off + return led_tm1637_update(); } bool led_tm1637_brightness(enum led_tm1637_brightness_t brightness) { display_brightness = brightness; // save brightness - if (display_on) { // adjust brightness if display is on - return led_tm1637_on(); // adjust brightness - } else { - return true; // command succeeded - } - return false; + return led_tm1637_update(); } bool led_tm1637_number(uint16_t number, bool zero) { - const uint8_t write_data[] = { 0x40 }; // command: write data, automatic address adding, normal const uint8_t digits[] = { // digits to display (number / 1000) % 10, (number / 100) % 10, (number / 10) % 10, (number / 1) % 10, }; - uint8_t data[] = { 0xc0, 0, 0, 0, 0}; // number to be displayed // convert digits to text to be displayed if (0 == digits[0] && !zero) { - data[1] = ascii_7segments[' ' - ' ']; + led_tm1637_digits[0] = ascii_7segments[' ' - ' ']; } else { - data[1] = ascii_7segments[digits[0] + '0' - ' ']; + led_tm1637_digits[0] = ascii_7segments[digits[0] + '0' - ' ']; } if (0 == digits[0] && 0 == digits[1] && !zero) { - data[2] = ascii_7segments[' ' - ' ']; + led_tm1637_digits[1] = ascii_7segments[' ' - ' ']; } else { - data[2] = ascii_7segments[digits[1] + '0' - ' ']; + led_tm1637_digits[1] = ascii_7segments[digits[1] + '0' - ' ']; } if (0 == digits[0] && 0 == digits[1] && 0 == digits[2] && !zero) { - data[3] = ascii_7segments[' ' - ' ']; + led_tm1637_digits[2] = ascii_7segments[' ' - ' ']; } else { - data[3] = ascii_7segments[digits[2] + '0' - ' ']; + led_tm1637_digits[2] = ascii_7segments[digits[2] + '0' - ' ']; } - data[4] = ascii_7segments[digits[3] + '0' - ' ']; + led_tm1637_digits[3] = ascii_7segments[digits[3] + '0' - ' ']; - // display number - return led_tm1637_write(write_data, LENGTH(write_data)) && led_tm1637_write(data, LENGTH(data)); // send commands + return led_tm1637_update(); // display number } bool led_tm1637_time(uint8_t hours, uint8_t minutes) { - uint8_t write_data[] = { 0x40 }; // command: write data, automatic address adding, normal - uint8_t data[] = { 0xc0, ascii_7segments[((hours / 10) % 10) + '0' - ' '], ascii_7segments[((hours / 1) % 10) + '0' - ' '] | 0x80, ascii_7segments[((minutes / 10) % 10) + '0' - ' '], ascii_7segments[((minutes / 1) % 10) + '0' - ' '] }; // set address C0H and add data + // set digits + led_tm1637_digits[0] = ascii_7segments[((hours / 10) % 10) + '0' - ' ']; + led_tm1637_digits[1] = ascii_7segments[((hours / 1) % 10) + '0' - ' '] | 0x80; + led_tm1637_digits[2] = ascii_7segments[((minutes / 10) % 10) + '0' - ' ']; + led_tm1637_digits[3] = ascii_7segments[((minutes / 1) % 10) + '0' - ' ']; - if (led_tm1637_write(write_data, LENGTH(write_data)) && led_tm1637_write(data, LENGTH(data))) { // send commands - return true; - } - return false; + return led_tm1637_update(); // display time } bool led_tm1637_text(char* text) @@ -323,11 +319,12 @@ bool led_tm1637_text(char* text) return false; } } - uint8_t write_data[] = { 0x40 }; // command: write data, automatic address adding, normal - uint8_t data[] = { 0xc0, ascii_7segments[(text[0] & 0x7f) - ' '] | (text[0] & 0x80), ascii_7segments[(text[1] & 0x7f) - ' ']|(text[1] & 0x80), ascii_7segments[(text[2] & 0x7f) - ' ']|(text[2] & 0x80), ascii_7segments[(text[3] & 0x7f) - ' ']|(text[3] & 0x80) }; // set address C0H and add data - if (led_tm1637_write(write_data, LENGTH(write_data)) && led_tm1637_write(data, LENGTH(data))) { // send commands - return true; - } - return false; + // set digits + led_tm1637_digits[0] = ascii_7segments[(text[0] & 0x7f) - ' '] | (text[0] & 0x80); + led_tm1637_digits[1] = ascii_7segments[(text[1] & 0x7f) - ' '] | (text[1] & 0x80); + led_tm1637_digits[2] = ascii_7segments[(text[2] & 0x7f) - ' '] | (text[2] & 0x80); + led_tm1637_digits[3] = ascii_7segments[(text[3] & 0x7f) - ' '] | (text[3] & 0x80); + + return led_tm1637_update(); // display test }