From b20c272c8ebc261ee1c3ba498ef5d4dad43549ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?King=20K=C3=A9vin?= Date: Sun, 27 Sep 2020 11:56:31 +0200 Subject: [PATCH] led_tm1637: allow the display to be upside down --- lib/led_tm1637.c | 28 ++++++++++++++++++++++++++-- lib/led_tm1637.h | 4 ++-- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/lib/led_tm1637.c b/lib/led_tm1637.c index a096066..76f4b48 100644 --- a/lib/led_tm1637.c +++ b/lib/led_tm1637.c @@ -48,6 +48,8 @@ static enum led_tm1637_brightness_t display_brightness = LED_TM1637_14DIV16; static bool display_on = false; /** display buffer */ static uint8_t led_tm1637_digits[4] = {0}; +/** if the display is upside down */ +bool led_tm1637_updown = false; /** ASCII characters encoded for the 7 segments digit block * @note starts with space @@ -150,8 +152,24 @@ static const uint8_t ascii_7segments[] = { 0x40, // 0b01000000 ~ }; -void led_tm1637_setup(void) + +/** convert the data for upside down displays + * @param[in] data the data to be converted + * @return the upside down data + */ +static uint8_t led_tm1637_rotate(uint8_t data) { + uint8_t converted = 0; + converted |= (data & 0xc0); // keep g and dot + converted |= (data << 3) & 0x38; // rotate abc + converted |= (data >> 3) & 0x07; // rotate def + return converted; +} + +void led_tm1637_setup(bool updown) +{ + led_tm1637_updown = updown; // remember if the display is upside down + // configure GPIO for CLK and DIO signals rcc_periph_clock_enable(GPIO_RCC(LED_TM1637_CLK_PIN)); // enable clock for GPIO peripheral gpio_set(GPIO_PORT(LED_TM1637_CLK_PIN), GPIO_PIN(LED_TM1637_CLK_PIN)); // idle high @@ -246,7 +264,13 @@ static bool led_tm1637_write(const uint8_t* data, size_t length) 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) + 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) + if (led_tm1637_updown) { // rotate data + data[1] = led_tm1637_rotate(led_tm1637_digits[3]); + data[2] = led_tm1637_rotate(led_tm1637_digits[2]) | (led_tm1637_digits[1] & 0x80); // keep the : for the time + data[3] = led_tm1637_rotate(led_tm1637_digits[1]) & 0x7f; // remove the : for the time + data[4] = led_tm1637_rotate(led_tm1637_digits[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 } diff --git a/lib/led_tm1637.h b/lib/led_tm1637.h index 57d0246..e26657d 100644 --- a/lib/led_tm1637.h +++ b/lib/led_tm1637.h @@ -22,8 +22,9 @@ enum led_tm1637_brightness_t { }; /** setup communication with TM1637 IC + * @param[in] updown if the display is upside down */ -void led_tm1637_setup(void); +void led_tm1637_setup(bool updown); /** switch display on * @return if transmission succeeded */ @@ -56,4 +57,3 @@ bool led_tm1637_time(uint8_t hours, uint8_t minutes); * @return if transmission succeeded */ bool led_tm1637_text(char* text); -