X-Git-Url: https://codewiz.org/gitweb?a=blobdiff_plain;f=bertos%2Fdrv%2Fled_7seg.c;h=96ff16dc10b9d981da4a5537459396192a1e25a4;hb=e655a1568f4499a683026a6ba7b95ddb05e60741;hp=d89ef3776ed2c9dc532d4944a503ba851804b1ac;hpb=41718ab2098bd5640da265c34f1ecb79a4123d39;p=bertos.git diff --git a/bertos/drv/led_7seg.c b/bertos/drv/led_7seg.c index d89ef377..96ff16dc 100644 --- a/bertos/drv/led_7seg.c +++ b/bertos/drv/led_7seg.c @@ -55,7 +55,7 @@ static Timer sseg_trefresh; * This is the procedure that prints the seven_seg structure'string to the display. * It prints a single digit at time and does all the checks to a proper display. * It is called by the wrapper function fired by the timer set in the init procedure. - * + * * param SS The void pointer that holds the pointer to the data structure * */ @@ -174,50 +174,125 @@ static void sseg_refresh_wrapper(void *VSS) */ INLINE uint8_t sseg_tabcheck(char source) { + /* If no legal character is recognized return a "space" */ uint8_t hexchar=38; /* Numbers */ - if ((((int)source) > 47) && (((int)source) < 58)) + if ((source > 47) && (source < 58)) hexchar = source-48; else /* Capital Letters */ - if ((((int)source) > 64) && (((int)source) < 91)) + if ((source > 64) && (source < 91)) hexchar = source-53; else /* Letters */ - if ((((int)source) > 96) && (((int)source) < 123)) + if ((source > 96) && (source < 123)) hexchar = source-85; else /* Minus */ - if (((int)source) == 45) + if (source == 45) hexchar = 11; else /* Space */ - if (((int)source) == 32) + if (source == 32) hexchar = 38; else /* Dot */ - if (((int)source) == 46) + if (source == 46) hexchar = 10; return hexchar; } +/* + * FUNCTION: sseg_digitbuild + * + * This function return the hex value of the graphic digit + * from a list of segments (ex. ACDP). + * + * param source The string of segments + */ +INLINE uint8_t sseg_digitbuild(const char *gstring, size_t start, size_t stop) +{ + /* the default "space" char returned if no "legal" segments recognized */ + uint8_t graphdigit = SEGMENT_EMPTY; + size_t x; + + /* Main cicle */ + for (x=start;x<=stop;x++) + { + switch (gstring[x]) + { + case 'A': + case 'a': + SET_SEGMENT(graphdigit, SEGMENT_A); + break; + case 'B': + case 'b': + SET_SEGMENT(graphdigit, SEGMENT_B); + break; + case 'C': + case 'c': + SET_SEGMENT(graphdigit, SEGMENT_C); + break; + case 'D': + case 'd': + SET_SEGMENT(graphdigit, SEGMENT_D); + break; + case 'E': + case 'e': + SET_SEGMENT(graphdigit, SEGMENT_E); + break; + case 'F': + case 'f': + SET_SEGMENT(graphdigit, SEGMENT_F); + break; + case 'G': + case 'g': + SET_SEGMENT(graphdigit, SEGMENT_G); + break; + case 'P': + case 'p': + SET_SEGMENT(graphdigit, SEGMENT_P); + break; + } + } + return graphdigit; +} + /** * \brief Print a string on the display * * This is the procedure that fills the seven_seg structure with the translated - * string to display. It swaps also the structures to display the new text when - * all the data is ready to display. + * string to display. + * + * To print a string simply call the procedure with a text string as the second parameter. + * Unrecognized characters are printed as a space + * + * To print "graphic" digits you have to enter them as a sequence of segments between "<>" + * for example: + * \code + * sevenseg_print(display,"Test Graphic"); + * \endcode + * This example will print "Test Graphic" + * + * This is the segments table: + * \code + * ___ + * F| A |B + * |___| + * | G | + * E|___|C oP + * D + * \endcode * * \param SS Pointer to the SevenSeg structure * \param sstring String to be displayed * - * \return 0 if all went well, -1 if the display is locked, -2 if the string too long. + * \return 0 if all went well, -1 if the display is locked, -2 if the string too long -3 if the string is malformed. */ int sevenseg_print(SevenSeg *SS, const char *sstring) { - size_t string_lenght; - unsigned int x,y,dotnumber; + size_t x,y,string_lenght,dotnumber,graph_digit_num,bracket_num,startgraph,stopgraph; bool dotjump = false; uint8_t hexchar; @@ -229,25 +304,58 @@ int sevenseg_print(SevenSeg *SS, const char *sstring) if (sizeof(&sstring) > (CONFIG_LED_7SEG_STRLEN-(2*CONFIG_LED_7SEG_DIGIT))) return -2; - /* get the string length and set the number of dots in the string to 0 */ + /* get the string length and set the number of dots and graphic in the string to 0 */ string_lenght = strlen(sstring); dotnumber = 0; + graph_digit_num = 0; + bracket_num = 0; - /* check if there are some dots in the string and report the number in dotnumber */ - for (x=0;x<(unsigned int)string_lenght;x++) + /* check if there are some dots an graphics in the string and report the number in dotnumber and graphnumber */ + for (x=0;x 0)) + { + /* If the previuos charachter is not a dot or a space we have a dot that + * has to be considered as a part of a previous character so we have to + * to count it */ + if ((sstring[x-1] != '.') & (sstring[x-1] != ' ')) + dotnumber++; + } + /* If we have a "<" or a ">" we have a graphic char */ + if (sstring[x] == '<') + { + bracket_num++; + x++; + while ((sstring[x] != '>') & (x 0 and is not pair we have a malformed string so exit with error */ + if (bracket_num > 0) + { + if (bracket_num & 1) + return -3; + else + /* Set the number of characters that compose the graphic + * to remove from the string, we subtract the "real" number + * of graphic character to display */ + graph_digit_num-=(bracket_num/2); + } /* If the *REAL* lenght of the string is less or equal than the number of digits */ - if (((int)string_lenght-dotnumber) <= CONFIG_LED_7SEG_DIGIT) + if ((string_lenght-dotnumber-graph_digit_num) <= CONFIG_LED_7SEG_DIGIT) { /* If the *REAL* lenght of the string is less than number of digits */ - if (((int)string_lenght-dotnumber) < CONFIG_LED_7SEG_DIGIT) + if ((string_lenght-dotnumber-graph_digit_num) < CONFIG_LED_7SEG_DIGIT) { /* Fill the left side of the string with blanks */ - for (x=0; x<(CONFIG_LED_7SEG_DIGIT-((int)string_lenght-dotnumber)); x++) + for (x=0; x<(CONFIG_LED_7SEG_DIGIT-(string_lenght-dotnumber-graph_digit_num)); x++) SS->string[x] = segstable[38]; y = x; } @@ -268,39 +376,63 @@ int sevenseg_print(SevenSeg *SS, const char *sstring) } /* Here we start to fill the string with the Hex 7seg characters values */ hexchar = 0; - for (x=0; x<(unsigned int)string_lenght; x++) + for (x=0; x 0) + x++; + /* set the first character of the graphic "string" to be passed to sseg_digitbuild */ + startgraph = x; + /* if we have an empty graphic char we return an error */ + if (sstring[x] == '>') + return -3; + while (sstring[x] != '>') + x++; + /* set the last character of the graphic "string" to be passed to sseg_digitbuild */ + stopgraph = x-1; + /* if we have a graphic char bigger than 8 (all the segments of the digit) we return an error */ + if (stopgraph-startgraph > 7) + return -3; + /* fill the destination string with the graphic digit returned by sseg_digitbuild */ + SS->string[y] = sseg_digitbuild(sstring,startgraph,stopgraph); + /* set next digit */ + y++; + } + else + { + hexchar = sseg_tabcheck(sstring[x]); + /* do we have a dot? */ + if (hexchar == 10) { + /* If we are at the first character of the string it has to be forced + * as "lonly" dot ;) */ + if ((x > 0) & ((sstring[x-1] != '.') & (sstring[x-1] != ' '))) + { #if CONFIG_LED_7SEG_CCAT - SS->string[y-1] = SS->string[y-1] | segstable[(int)hexchar]; + SS->string[y-1] = SS->string[y-1] | segstable[hexchar]; #else - SS->string[y-1] = SS->string[y-1] & segstable[(int)hexchar]; + SS->string[y-1] = SS->string[y-1] & segstable[hexchar]; #endif - dotjump = true; + dotjump = true; + } + } + /* If the last character was a dot and we aren't at the first character of the string + * we have just inserted it */ + if (dotjump) + dotjump = false; + /* Let's put the character in the structure's string */ + else + { + SS->string[y] = segstable[hexchar]; + y++; } - } - /* If the last character was a dot and we aren't at the first character of the string - * we have just inserted it */ - if (dotjump) - dotjump = false; - /* Let's put the character in the structure's string */ - else - { - SS->string[y] = segstable[(int)hexchar]; - y++; } } /* If we have the string length bigger than the display we need to fill * the entire right side of the string with blanks to end the scroll * to the rigthest side of the display */ - if (((int)string_lenght-dotnumber) > CONFIG_LED_7SEG_DIGIT) + if ((string_lenght-dotnumber-graph_digit_num) > CONFIG_LED_7SEG_DIGIT) { for (x=0; x