From 915b1740435f214125b1ad8b27679ccbda61a96a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?King=20K=C3=A9vin?= Date: Tue, 7 Feb 2017 19:59:18 +0100 Subject: [PATCH] implement display functions --- lib/led_tm1637.c | 166 +++++++++++++++++++++++++++++++++++++++++------ lib/led_tm1637.h | 4 +- 2 files changed, 147 insertions(+), 23 deletions(-) diff --git a/lib/led_tm1637.c b/lib/led_tm1637.c index aecffcc..cc96e13 100644 --- a/lib/led_tm1637.c +++ b/lib/led_tm1637.c @@ -19,11 +19,19 @@ * @note peripherals used: GPIO @ref led_tm1637_gpio, timer @ref led_tm1637_timer * @note the protocol is very similar to I2C but incompatible for the following reasons: the capacitance is too large for open-drain type output with weak pull-up resistors (push-pull needs to be used, preventing to get ACKs since no indication of the ACK timing is provided); the devices doesn't use addresses; the STM32 I2C will switch to receiver mode when the first sent byte (the I2C address) has last bit set to 1 (such as for address commands with B7=1 where B7 is transmitted last), preventing to send further bytes (the data byte after the address) * @warning all calls are blocking + * + * bit vs segment: 0bpgfedcba + * /a\ + * f b p + * +g+ + * e c p + * \b/ */ /* standard libraries */ #include // standard integer types #include // general utilities +#include // string utilities /* STM32 (including CM3) libraries */ #include // Cortex M3 utilities @@ -50,10 +58,111 @@ /** @} */ /** display brightness */ -static enum led_tm1637_brightness_t display_brightness = LED_TM1637_11DIV16; +static enum led_tm1637_brightness_t display_brightness = LED_TM1637_14DIV16; /** if display is on */ static bool display_on = false; +/** ASCII characters encoded for the 7 segments digit block + * @note starts with space + */ +static const uint8_t ascii_7segments[] = { + 0x00, // 0b00000000 space + 0x30, // 0b00110000 ! (I) + 0x22, // 0b00100010 " + 0x5c, // 0b01011100 # (o) + 0x6d, // 0b01101101 $ (s) + 0x52, // 0b01010010 % (/) + 0x7d, // 0b01111101 & (6) + 0x20, // 0b00100000 ' + 0x39, // 0b00111001 ( ([) + 0x0f, // 0b00001111 ) + 0x70, // 0b01110000 * + 0x46, // 0b01000110 + + 0x10, // 0b00010000 , + 0x40, // 0b01000000 - + 0x10, // 0b00010000 . (,) + 0x52, // 0b01010010 / + 0x3f, // 0b00111111 0 + 0x06, // 0b00000110 1 + 0x5b, // 0b01011011 2 + 0x4f, // 0b01001111 3 + 0x66, // 0b01100110 4 + 0x6d, // 0b01101101 5 + 0x7d, // 0b01111101 6 + 0x07, // 0b00000111 7 + 0x7f, // 0b01111111 8 + 0x6f, // 0b01101111 9 + 0x48, // 0b01001000 : (=) + 0x48, // 0b01001000 ; (=) + 0x58, // 0b01011000 < + 0x48, // 0b01001000 = + 0x4c, // 0b01001100 > + 0x53, // 0b01010011 ? + 0x7b, // 0b01111011 @ + 0x77, // 0b01110111 A + 0x7f, // 0b01111111 B + 0x39, // 0b00111001 C + 0x5e, // 0b01011110 D + 0x79, // 0b01111001 E + 0x71, // 0b01110001 F + 0x3d, // 0b00111101 G + 0x76, // 0b01110110 H + 0x30, // 0b00110000 I + 0x1e, // 0b00011110 J + 0x76, // 0b01110110 K + 0x38, // 0b00111000 L + 0x37, // 0b00110111 M + 0x37, // 0b00110111 N + 0x3f, // 0b00111111 O + 0x73, // 0b01110011 P + 0x6b, // 0b01101011 Q + 0x33, // 0b00110011 R + 0x6d, // 0b01101101 S + 0x78, // 0b01111000 T + 0x3e, // 0b00111110 U + 0x3e, // 0b00111110 V (U) + 0x3e, // 0b00111110 W (U) + 0x76, // 0b01110110 X (H) + 0x6e, // 0b01101110 Y + 0x5b, // 0b01011011 Z + 0x39, // 0b00111001 [ + 0x64, // 0b01100100 '\' + 0x0f, // 0b00001111 / + 0x23, // 0b00100011 ^ + 0x08, // 0b00001000 _ + 0x02, // 0b00000010 ` + 0x5f, // 0b01011111 a + 0x7c, // 0b01111100 b + 0x58, // 0b01011000 c + 0x5e, // 0b01011110 d + 0x7b, // 0b01111011 e + 0x71, // 0b01110001 f + 0x6f, // 0b01101111 g + 0x74, // 0b01110100 h + 0x10, // 0b00010000 i + 0x0c, // 0b00001100 j + 0x76, // 0b01110110 k + 0x30, // 0b00110000 l + 0x54, // 0b01010100 m + 0x54, // 0b01010100 n + 0x5c, // 0b01011100 o + 0x73, // 0b01110011 p + 0x67, // 0b01100111 q + 0x50, // 0b01010000 r + 0x6d, // 0b01101101 s + 0x78, // 0b01111000 t + 0x1c, // 0b00011100 u + 0x1c, // 0b00011100 v (u) + 0x1c, // 0b00011100 w (u) + 0x76, // 0b01110110 x + 0x6e, // 0b01101110 y + 0x5b, // 0b01011011 z + 0x39, // 0b00111001 { ([) + 0x30, // 0b00110000 | + 0x0f, // 0b00001111 } ([) + 0x40, // 0b01000000 ~ +}; + void led_tm1637_setup(void) { // configure GPIO for CLK and DIO signals @@ -78,7 +187,7 @@ void led_tm1637_setup(void) /** wait until clock tick (timer overflow) occurred */ -static void led_tm1637_tick(void) +static inline void led_tm1637_tick(void) { while (!timer_get_flag(TIM(LED_TM1637_TIMER), TIM_SR_UIF)); // wait until counter overflow update event happens timer_clear_flag(TIM(LED_TM1637_TIMER), TIM_SR_UIF); // clear event flag @@ -90,7 +199,7 @@ static void led_tm1637_tick(void) * @return if write succeeded * @note includes start and stop conditions */ -static bool led_tm1637_write(uint8_t* data, size_t length) +static bool led_tm1637_write(const uint8_t* data, size_t length) { bool to_return = true; // return if write succeeded if (data==NULL || length==0) { // verify there it data to be read @@ -109,13 +218,14 @@ static bool led_tm1637_write(uint8_t* data, size_t length) // send data bytes (MSb first) for (size_t i=0; i>= 1; // shift data + byte >>= 1; // shift data led_tm1637_tick(); // wait for next tick gpio_set(GPIO(LED_TM1637_CLK_PORT), GPIO(LED_TM1637_CLK_PIN)); // put CLK high led_tm1637_tick(); // wait for next tick (no DIO transition when CLK is high) @@ -158,47 +268,61 @@ bool led_tm1637_on(void) bool led_tm1637_off(void) { uint8_t data[] = { 0x80+display_brightness }; // command to turn display off (use set brightness) - bool to_return = false; // result to return if (led_tm1637_write(data,LENGTH(data))) { // send command display_on = false; // remember display is off - to_return = true; // command succeeded + return true; // command succeeded } - return to_return; // return result + return false; // return result } bool led_tm1637_brightness(enum led_tm1637_brightness_t brightness) { - bool to_return = false; // result to return display_brightness = brightness; // save brightness if (display_on) { // adjust brightness if display is on - to_return = led_tm1637_on(); // adjust brightness + return led_tm1637_on(); // adjust brightness } else { - to_return = true; // command succeeded + return true; // command succeeded } - return to_return; + return false; } bool led_tm1637_number(uint16_t number) { - (void) number; - bool to_return = false; // result to return uint8_t write_data[] = { 0x40 }; // command: write data, automatic address adding, normal - uint8_t data[] = { 0xc0, 0xff, 0x00, 0x00, 0xff }; // set address C0H and add data + uint8_t data[] = { 0xc0, ascii_7segments[((number/1000)%10)+'0'-' '], ascii_7segments[((number/100)%10)+'0'-' '], ascii_7segments[((number/10)%10)+'0'-' '], ascii_7segments[((number/1)%10)+'0'-' '] }; // set address C0H and add data if (led_tm1637_write(write_data,LENGTH(write_data)) && led_tm1637_write(data,LENGTH(data))) { // send commands - to_return = true; + return true; } - return to_return; + return false; } -/* bool led_tm1637_time(uint8_t hours, uint8_t minutes) { - return true; + 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 + + if (led_tm1637_write(write_data,LENGTH(write_data)) && led_tm1637_write(data,LENGTH(data))) { // send commands + return true; + } + return false; } bool led_tm1637_text(char* text) { - return true; + if (strlen(text)!=4) { // input text should have exactly 4 characters + return false; + } + for (uint8_t i=0; i<4; i++) { // input text should only contain printable character (8th bit is used for dots) + if ((text[i]&0x7f)<' ' || (text[i]&0x7f)>=' '+LENGTH(ascii_7segments)) { + 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; } -*/ diff --git a/lib/led_tm1637.h b/lib/led_tm1637.h index 772dbcc..7bd0109 100644 --- a/lib/led_tm1637.h +++ b/lib/led_tm1637.h @@ -63,8 +63,8 @@ bool led_tm1637_number(uint16_t number); */ bool led_tm1637_time(uint8_t hours, uint8_t minutes); /** display text - * @param[in] text text to display (4 characters) - * @note use first bit of each character to enable dot + * @param[in] text text to display (4 characters) + * @note use first bit of each character to enable dot * @return if transmission succeeded */ bool led_tm1637_text(char* text);