BeRTOS
|
00001 00041 #include "drv/led_7seg.h" 00042 #include "hw/hw_led_7seg.h" 00043 #include "cfg/cfg_arch.h" 00044 #include <drv/timer.h> 00045 #include <string.h> 00046 00047 /* 00048 * Define the timer for the refreshing 00049 */ 00050 static Timer sseg_trefresh; 00051 00052 /* 00053 * FUNCTION: sseg_refresh 00054 * 00055 * This is the procedure that prints the seven_seg structure'string to the display. 00056 * It prints a single digit at time and does all the checks to a proper display. 00057 * It is called by the wrapper function fired by the timer set in the init procedure. 00058 * 00059 * param SS The void pointer that holds the pointer to the data structure 00060 * 00061 */ 00062 static void sseg_refresh(SevenSeg *SS) 00063 { 00064 /* First Check if the structure is being edited we do a silent exit*/ 00065 if (SS->busyedit == true) 00066 return; 00067 00068 /* If we have displayed all the digits */ 00069 if (SS->curdigit == CONFIG_LED_7SEG_DIGIT) 00070 { 00071 sseg_off(); 00072 /* And if we have to display again all the digit */ 00073 if (SS->curspeed > 0) 00074 { 00075 SS->curspeed--; 00076 SS->curdigit = 0; 00077 SS->curpos -= CONFIG_LED_7SEG_DIGIT; 00078 } 00079 /* Else is time to scroll the text */ 00080 else 00081 { 00082 /* If we aren't at the end of the string */ 00083 if (SS->curpos < SS->string_len) 00084 { 00085 SS->curpos -= CONFIG_LED_7SEG_DIGIT; 00086 SS->curpos++; 00087 SS->curdigit = 0; 00088 SS->curspeed = SS->speed; 00089 } 00090 /* Else we are at the end of the string */ 00091 else 00092 { 00093 /* Set that the string was displayed at least one time and we can accept a new text*/ 00094 SS->firstrun = false; 00095 /* If the string has to be displayed only one time we set an empty string 00096 * to display till next print request*/ 00097 if (SS->runonce == true) 00098 sevenseg_clear(SS); 00099 /* Else we reset the text to it's first character ad do again the display */ 00100 else 00101 { 00102 SS->curdigit = 0; 00103 SS->curpos = 0; 00104 SS->curspeed = SS->speed; 00105 } 00106 } 00107 } 00108 } 00109 /* Else We have to do a print*/ 00110 else 00111 { 00112 /* If the text doesn't have to blink we write the character to the proper disply's digit */ 00113 if (SS->blink == false) 00114 sseg_on(SS->string[SS->curpos], SS->curdigit); 00115 /* Else we do the blinking */ 00116 else 00117 { 00118 /* If bdigit == 0 we have to blink all the digits */ 00119 if (SS->bdigit == 0) 00120 { 00121 if (SS->curspeed >= (SS->speed/2)) 00122 sseg_on(SS->string[SS->curpos], SS->curdigit); 00123 else 00124 sseg_off(); 00125 } 00126 /* else we have to blink only one digit (bdigit -1) */ 00127 else 00128 /* is this the digit to blink? */ 00129 if (SS->curdigit == ((unsigned int)SS->bdigit-1)) 00130 { 00131 if (SS->curspeed >= (SS->speed/2)) 00132 sseg_on(SS->string[SS->curpos], SS->curdigit); 00133 else 00134 sseg_off(); 00135 } 00136 /* no, so let do a normal print */ 00137 else 00138 sseg_on(SS->string[SS->curpos], SS->curdigit); 00139 } 00140 /* Ok, next time next char.... ;) */ 00141 SS->curdigit++; 00142 SS->curpos++; 00143 } 00144 } 00145 00146 /* 00147 * FUNCTION: sseg_refresh_wrapper 00148 * 00149 * This is a "wrapper" procedure that is called by the timer_setSoftint() 00150 * with the unique purpose to call the real sseg_refresh procedure without 00151 * the cast of the structure from void to SevenSeg. 00152 * 00153 * param VSS The void pointer that holds the pointer to the data structure 00154 * 00155 */ 00156 static void sseg_refresh_wrapper(void *VSS) 00157 { 00158 /* Here we cast the Structure from void to proper type */ 00159 SevenSeg *SS; 00160 SS = (SevenSeg *)VSS; 00161 /* now we call the right refresh routine */ 00162 sseg_refresh(SS); 00163 /* ReStart the timer */ 00164 timer_add(&sseg_trefresh); 00165 } 00166 00167 /* 00168 * FUNCTION: sseg_tabcheck 00169 * 00170 * This function return the position of the ascii character in the hex 00171 * segstable. 00172 * 00173 * param source The ascii char to be positioned 00174 */ 00175 INLINE uint8_t sseg_tabcheck(char source) 00176 { 00177 uint8_t hexchar=38; 00178 00179 /* Numbers */ 00180 if ((((int)source) > 47) && (((int)source) < 58)) 00181 hexchar = source-48; 00182 else 00183 /* Capital Letters */ 00184 if ((((int)source) > 64) && (((int)source) < 91)) 00185 hexchar = source-53; 00186 else 00187 /* Letters */ 00188 if ((((int)source) > 96) && (((int)source) < 123)) 00189 hexchar = source-85; 00190 else 00191 /* Minus */ 00192 if (((int)source) == 45) 00193 hexchar = 11; 00194 else 00195 /* Space */ 00196 if (((int)source) == 32) 00197 hexchar = 38; 00198 else 00199 /* Dot */ 00200 if (((int)source) == 46) 00201 hexchar = 10; 00202 return hexchar; 00203 } 00204 00217 int sevenseg_print(SevenSeg *SS, const char *sstring) 00218 { 00219 size_t string_lenght; 00220 unsigned int x,y,dotnumber; 00221 bool dotjump = false; 00222 uint8_t hexchar; 00223 00224 /* Check if the display is unlocked */ 00225 if (SS->busyedit == false) 00226 return -1; 00227 00228 /* Check if the string is too big */ 00229 if (sizeof(&sstring) > (CONFIG_LED_7SEG_STRLEN-(2*CONFIG_LED_7SEG_DIGIT))) 00230 return -2; 00231 00232 /* get the string length and set the number of dots in the string to 0 */ 00233 string_lenght = strlen(sstring); 00234 dotnumber = 0; 00235 00236 /* check if there are some dots in the string and report the number in dotnumber */ 00237 for (x=0;x<(unsigned int)string_lenght;x++) 00238 { 00239 if (((int)sstring[x]) == 46) 00240 dotnumber++; 00241 } 00242 00243 /* If the *REAL* lenght of the string is less or equal than the number of digits */ 00244 if (((int)string_lenght-dotnumber) <= CONFIG_LED_7SEG_DIGIT) 00245 { 00246 /* If the *REAL* lenght of the string is less than number of digits */ 00247 if (((int)string_lenght-dotnumber) < CONFIG_LED_7SEG_DIGIT) 00248 { 00249 /* Fill the left side of the string with blanks */ 00250 for (x=0; x<(CONFIG_LED_7SEG_DIGIT-((int)string_lenght-dotnumber)); x++) 00251 SS->string[x] = segstable[38]; 00252 y = x; 00253 } 00254 else 00255 { 00256 /* Else we have the exact string length of the display */ 00257 y = 0; 00258 } 00259 } 00260 else 00261 { 00262 /* Else we have the string length bigger than the display and we need to fill 00263 * the entire left side of the string with blanks to begin the scroll from the 00264 * rigthest side of the display */ 00265 for (x=0; x<CONFIG_LED_7SEG_DIGIT; x++) 00266 SS->string[x] = segstable[38]; 00267 y = CONFIG_LED_7SEG_DIGIT; 00268 } 00269 /* Here we start to fill the string with the Hex 7seg characters values */ 00270 hexchar = 0; 00271 for (x=0; x<(unsigned int)string_lenght; x++) 00272 { 00273 hexchar = sseg_tabcheck(sstring[x]); 00274 /* do we have a dot? */ 00275 if (hexchar == 10) 00276 { 00277 /* If we are at the first character of the string it has to be forced 00278 * as "lonly" dot ;) */ 00279 if (x > 0) 00280 { 00281 #if CONFIG_LED_7SEG_CCAT 00282 SS->string[y-1] = SS->string[y-1] | segstable[(int)hexchar]; 00283 #else 00284 SS->string[y-1] = SS->string[y-1] & segstable[(int)hexchar]; 00285 #endif 00286 dotjump = true; 00287 } 00288 } 00289 /* If the last character was a dot and we aren't at the first character of the string 00290 * we have just inserted it */ 00291 if (dotjump) 00292 dotjump = false; 00293 /* Let's put the character in the structure's string */ 00294 else 00295 { 00296 SS->string[y] = segstable[(int)hexchar]; 00297 y++; 00298 } 00299 } 00300 /* If we have the string length bigger than the display we need to fill 00301 * the entire right side of the string with blanks to end the scroll 00302 * to the rigthest side of the display */ 00303 if (((int)string_lenght-dotnumber) > CONFIG_LED_7SEG_DIGIT) 00304 { 00305 for (x=0; x<CONFIG_LED_7SEG_DIGIT; x++) 00306 { 00307 SS->string[y] = segstable[38]; 00308 y++; 00309 } 00310 } 00311 /* Let's put the total string length to the structure */ 00312 SS->string_len = y; 00313 00314 return 0; 00315 } 00316 00325 void sevenseg_init(SevenSeg *SS) 00326 { 00327 /* 00328 * Init the 7segments string structure 00329 */ 00330 SS->busyedit = true; 00331 sevenseg_clear(SS); 00332 SS->busyedit = false; 00333 00334 /* 00335 * Init the I/O ports and set the display OFF 00336 */ 00337 sseg_init(); 00338 00339 /* 00340 * Define the timer for the refresh of the display 00341 * The timer calls the sevenseg_refresh function 00342 * every "CONFIG_LED_7SEG_RTIME" milliseconds for 00343 * an acceptable persistance of a single 7 segments 00344 * display. 00345 */ 00346 // set the callback 00347 timer_setSoftint(&sseg_trefresh, sseg_refresh_wrapper, (void *)SS); 00348 // expire time: 1s 00349 timer_setDelay(&sseg_trefresh, ms_to_ticks(CONFIG_LED_7SEG_RTIME)); 00350 // start the timer 00351 timer_add(&sseg_trefresh); 00352 } 00353 00364 bool sevenseg_isReady(SevenSeg *SS) 00365 { 00366 return !SS->firstrun; 00367 } 00368 00379 bool sevenseg_unlock(SevenSeg *SS) 00380 { 00381 if (SS->firstrun == false) 00382 { 00383 SS->busyedit = true; 00384 SS->firstrun = true; 00385 SS->curdigit = 0; 00386 SS->curpos = 0; 00387 } 00388 else 00389 return false; 00390 return true; 00391 } 00392 00403 bool sevenseg_lock(SevenSeg *SS) 00404 { 00405 if (SS->busyedit == true) 00406 { 00407 /* If the string is longer than the number of the digit of the display we 00408 * reset the single digit blink to zero to be sure that the display of 00409 * the text is clean from previous single digit blinking settings */ 00410 if (SS->string_len > CONFIG_LED_7SEG_DIGIT) 00411 SS->bdigit = 0; 00412 SS->busyedit = false; 00413 } 00414 else 00415 return false; 00416 return true; 00417 } 00418 00432 bool sevenseg_setBlink(SevenSeg *SS, bool blink, uint8_t digit) 00433 { 00434 if (SS->busyedit == true) 00435 { 00436 if (blink == true) 00437 { 00438 if (digit == 0) 00439 SS->bdigit = digit; 00440 else 00441 if ((digit-1) <= CONFIG_LED_7SEG_DIGIT) 00442 SS->bdigit = digit; 00443 else 00444 return false; 00445 } 00446 SS->blink = blink; 00447 } 00448 else 00449 return false; 00450 return true; 00451 } 00452 00464 bool sevenseg_setRunonce(SevenSeg *SS, bool runonce) 00465 { 00466 if (SS->busyedit == true) 00467 SS->runonce = runonce; 00468 else 00469 return false; 00470 return true; 00471 } 00472 00486 bool sevenseg_setRunspeed(SevenSeg *SS, unsigned int r_speed) 00487 { 00488 if (SS->busyedit == true) 00489 { 00490 SS->speed = r_speed; 00491 SS->curspeed = r_speed; 00492 } 00493 else 00494 return false; 00495 return true; 00496 } 00497 00508 bool sevenseg_clear(SevenSeg *SS) 00509 { 00510 if (SS->busyedit == true) 00511 { 00512 memset(((void *)&SS->string),segstable[38],sizeof(SS->string)); 00513 SS->string_len = CONFIG_LED_7SEG_DIGIT; 00514 SS->blink = false; 00515 SS->bdigit = 0; 00516 SS->runonce = false; 00517 SS->curdigit = 0; 00518 SS->curpos = 0; 00519 SS->speed = CONFIG_LED_7SEG_SSPEED; 00520 SS->curspeed = CONFIG_LED_7SEG_SSPEED; 00521 SS->firstrun = false; 00522 } 00523 else 00524 return false; 00525 return true; 00526 } //defgroup drivers