led_tm1637: allow the display to be upside down

This commit is contained in:
King Kévin 2020-09-27 11:56:31 +02:00
parent 7dcfa18d8d
commit b20c272c8e
2 changed files with 28 additions and 4 deletions

View File

@ -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
}

View File

@ -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);