Qubit 2020 / presensfirmwareupdate

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers lcd.cpp Source File

lcd.cpp

00001 #include "cisme.h"
00002 #include "lcd.h"
00003 #include "debug.h"
00004 #include "keys.h"
00005 
00006 #ifdef USE_LCD
00007 
00008 #define LCD_CMD_LEN 40
00009 #define LCD_MAX_ROW 7
00010 #define LCD_VALUE_MAX_RANK 5
00011 #define NUMBER_TO_ASCII(val) (val + 0x30)
00012 
00013 #define SOH    0x01
00014 #define ETX    0x03
00015 
00016 static Serial lcdComm(p13, p14);
00017 
00018 static void convertToHexStr(unsigned char value, char* dst)
00019 {
00020     static const char map[] = "0123456789abcdef";
00021     dst[0] = map[(value / 16)];
00022     dst[1] = map[(value % 16)];
00023 }
00024 
00025 static void lcdCallback(void)
00026 {
00027     keyEvent(lcdComm.getc());
00028 }
00029 
00030 static unsigned char lcdValueRank(unsigned long value)
00031 {
00032     unsigned char rank = 1;
00033     for (unsigned long rankIx = 10; (value / rankIx) != 0; rankIx *= 10, rank++);
00034     return rank;
00035 }
00036 
00037 static void lcdValueDiscardHighestRank(unsigned long* value)
00038 {
00039     unsigned char rank = lcdValueRank(*value);
00040     unsigned long divider = 1;
00041     
00042     for (; rank != 1; rank--) {
00043         divider *= 10;
00044     }
00045     
00046     *value %= divider;
00047 } 
00048 
00049 void lcdInit(void)
00050 {
00051     // Set the baud rate for the LCD
00052     lcdComm.baud(9600);
00053     // Set the serial parameters for the LCD
00054     lcdComm.format(8, Serial::None, 1);
00055     lcdComm.attach(lcdCallback, Serial::RxIrq);
00056 }
00057 
00058 void lcdClear(void)
00059 {
00060     lcdComm.attach(NULL);
00061     lcdComm.printf("%cCFF007F%c", SOH, ETX);
00062     lcdComm.attach(lcdCallback, Serial::RxIrq);
00063 }
00064 
00065 void lcdClearLine(unsigned char row)
00066 {
00067     static const unsigned char line[] = {1, 2, 4, 8, 16, 32, 64, 128};
00068     static char cmd[2]; //needed only for hex representation of line
00069     
00070     if (row > LCD_MAX_ROW) {
00071         ERROR("Too big row number. Received: %u, maximum is %u", row, LCD_MAX_ROW);
00072         return;
00073     }
00074     
00075     convertToHexStr(line[row], cmd);
00076     
00077     lcdComm.attach(NULL);
00078     lcdComm.printf("%cC%s007F%c", SOH, cmd, ETX);
00079     lcdComm.attach(lcdCallback, Serial::RxIrq);
00080 }
00081 
00082 #define LCD_CMD_COUNT_MGMT_BYTES 11
00083 
00084 void lcdWrite(unsigned char row, unsigned char col, Justification just, const char* format, ...)
00085 {
00086     static char cmd[LCD_CMD_LEN];
00087     static const unsigned char line[] = {1, 2, 4, 8, 16, 32, 64, 128};
00088     static char txt[LCD_CMD_LEN - LCD_CMD_COUNT_MGMT_BYTES] = {0};
00089     va_list params;
00090     int charactersWritten;
00091     
00092     if (row > LCD_MAX_ROW) {
00093         ERROR("Too big row number. Received: %u, maximum is %u", row, LCD_MAX_ROW);
00094         return;
00095     }
00096     
00097     va_start(params, format);
00098  
00099     charactersWritten = vsnprintf(txt, LCD_CMD_LEN - LCD_CMD_COUNT_MGMT_BYTES, format, params);
00100  
00101     va_end(params);
00102     
00103     /*
00104      * The return value is more than possible count of characters.
00105      * (excluding terminating NULL byte)
00106      * According to the man page, this means that output was truncated.
00107     */
00108     if (charactersWritten >= LCD_CMD_LEN - LCD_CMD_COUNT_MGMT_BYTES)
00109     {
00110         ERROR("Too big text length. textLength is %u max length is %u", charactersWritten, LCD_CMD_LEN - LCD_CMD_COUNT_MGMT_BYTES - 1);
00111         return;
00112     }
00113 
00114     unsigned char cmdIx = 0;
00115     cmd[cmdIx++] = 1;                           // SOH Byte
00116     cmd[cmdIx++] = 'P';                         // Print Command
00117     convertToHexStr(line[row], cmd + cmdIx);    // Row
00118     cmdIx += 2;
00119     convertToHexStr(col * 6, cmd + cmdIx);      // Column
00120     cmdIx += 2;
00121     cmd[cmdIx++] = '0';                         // Font - Single Line 5x7 Char
00122     cmd[cmdIx++] = '1';                         // Type - Black Chars on White Background
00123     cmd[cmdIx++] = NUMBER_TO_ASCII(just);       // Justification
00124 
00125     // Add message text to command string
00126     size_t txtLen = strlen(txt);
00127     memcpy(cmd + cmdIx, txt, txtLen);
00128     cmdIx += txtLen;    
00129         
00130     cmd[cmdIx++] = ' ';
00131     // Add ETX Character to End of Command String
00132     cmd[cmdIx++] = 3;
00133 
00134     lcdComm.attach(NULL);
00135     lcdComm.printf("%s\n", cmd);
00136     lcdComm.attach(lcdCallback, Serial::RxIrq);
00137 }
00138 
00139 unsigned long lcdGetParam(unsigned long min, unsigned long max, unsigned char row, unsigned char col)
00140 {
00141     Key key = KEY_NONE;
00142     unsigned long value = 0;
00143     unsigned char maxRank = lcdValueRank(max);
00144     char valueStr[LCD_VALUE_MAX_RANK + 1];
00145 
00146     while (key != KEY_HASH || value > max || value < min) {
00147         unsigned char strOffset = maxRank - lcdValueRank(value);
00148         memset(valueStr, '0', LCD_VALUE_MAX_RANK);        
00149         sprintf(valueStr + strOffset, "%u", value);
00150         lcdWrite(row, col, JUSTIFICATION_ABSOLUTE, valueStr);
00151 
00152         key = keyWait();
00153         if (key == KEY_ASTERISK) { // backspace
00154             value /= 10;
00155         }
00156         else if (key <= KEY_NINE) { // numeric values
00157             if (lcdValueRank(value) == maxRank) {
00158                 lcdValueDiscardHighestRank(&value);
00159             }
00160             value = value * 10 + key;
00161         }
00162     }
00163 
00164     return value;
00165 }
00166 
00167 #endif // USE_LCD