Roqyun KO / Mbed 2 deprecated MeringueCitron

Dependencies:   mbed DHT

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers LCDGraphics.cpp Source File

LCDGraphics.cpp

00001 #include "ADA326.h"
00002 #include "mbed.h"
00003 #include "arial_font_48_64.h"
00004 
00005 #define BLACK 0
00006 #define WHITE 1
00007 #define INVERSE 2
00008 
00009 #define SSD1306_LCDHEIGHT 64
00010 #define SSD1306_LCDWIDTH 128
00011 
00012 
00013 extern Serial pc;
00014 
00015 LCDGraphics::LCDGraphics(uint16_t width, uint16_t height, uint8_t page)
00016 {
00017     // Initialize.
00018     this->chBuffer = NULL;
00019     this->sizeFont = 1.0f;
00020     this->spacing = 0;
00021     this->width = width;
00022     this->height = height;
00023     this->page = page;
00024     this->com_per_page = height / page;
00025     this->fontWidth = FONT_WIDTH;
00026     this->fontHeight = FONT_HEIGHT;
00027     //Allocate screen bitmap buffer that will eventually be displayed on the screen.
00028     this->screen = (uint8_t **)malloc(sizeof(uint8_t*) * width + 1);
00029     for(int x = 0; x < width; x++)
00030         this->screen[x] = (uint8_t *)malloc(sizeof(uint8_t) * page + 1);
00031 }
00032 // Horizontal spacing between characters
00033 void LCDGraphics::setFontSpacing(int8_t spacing)
00034 {
00035     if(spacing > FONT_WIDTH || spacing < -FONT_WIDTH) {
00036         pc.printf("Too much spacing.\r\n");
00037         return;
00038     }
00039     this->spacing = spacing;
00040 }
00041 // Set font size. Parameter taken is 0~100% in float. 
00042 // Maximum size is 48 x 48 (100% = 1.0f) and minimum is 4 x 4 (10% = 0.1f)
00043 void LCDGraphics::setFontSize(float size)
00044 {
00045  //   int length;
00046     if(size > 1.0f || size < 0.1f) {
00047         pc.printf("Font size cannot exceed 100%% or go below 10%%.\r\n");
00048         return;
00049     }
00050     fontWidth = (uint8_t)(FONT_WIDTH * size);
00051     fontHeight = (uint8_t)(FONT_HEIGHT * size);
00052     sizeFont = size;
00053 }
00054 // Set a pixel at coordinate (x,y) on the screen.
00055 void LCDGraphics::setPixel(uint16_t x,uint16_t y, uint8_t color)
00056 {
00057     uint8_t com_pos = y % com_per_page; 
00058     uint8_t page_pos = y / page;
00059     if (x > SSD1306_LCDWIDTH || y > SSD1306_LCDHEIGHT)
00060         return;
00061     switch(color) {
00062         case WHITE: 
00063             this->screen[x][page_pos] |= WHITE << com_pos;
00064             break;
00065         case BLACK: 
00066             this->screen[x][page_pos] &= ~(WHITE << com_pos);
00067             break;
00068         case INVERSE: 
00069             this->screen[x][page_pos] ^= WHITE << com_pos;
00070             break;
00071     }
00072 }
00073 #define CH_PIXEL_INDEX(x,y) ((y / 8) * 8 + x)
00074 // Write a character at the coordinate (x0, y0)
00075 void LCDGraphics::write(char c, uint8_t x0, uint8_t y0)
00076 {
00077     uint32_t finalWidth = 0, finalHeight = 0;
00078     uint32_t x_ratio, y_ratio;
00079     uint16_t x2, y2;
00080     const uint8_t *character = index_of_char(c);
00081     // Resize according to the defined font size.
00082     finalWidth = floor(FONT_WIDTH * sizeFont); 
00083     finalHeight = floor(FONT_HEIGHT * sizeFont);
00084     x_ratio = ((FONT_WIDTH << 16) / finalWidth ) + 1;
00085     y_ratio = ((FONT_HEIGHT << 16) / finalHeight ) + 1;
00086     if(!character) {
00087         pc.printf("Sorry. Unsupported character.\r\n");
00088         return;
00089     }
00090     
00091     for(int y = 0; y < finalHeight; y++){    
00092         for(int x = 0; x < finalWidth; x++){
00093             x2 = (x * x_ratio) >> 16;
00094             y2 = (y * y_ratio) >> 16;
00095             //pc.printf("(%d,%d)=>(%d, %d) : %d  %d\r\n", x,y,x2,y2, ((int)(y2 / 8))*8,y2 % 8);
00096             setPixel(x0 + x, y0 + y, (character[((int)(y2 / 8))*FONT_WIDTH + x2] >> (y2 % 8))&0x1);
00097             
00098         }
00099     }
00100 }
00101 int iCol = 0, iLine = 0;
00102 void LCDGraphics::print(const char *str, const uint8_t *pchEx, int numEx)
00103 {
00104     char ch;
00105     int i = 0, iEx = 0;
00106     iCol = 0;
00107     iLine = 0;
00108     while(str[i] != '\0')
00109     {
00110         ch = str[i];
00111         switch(ch) {
00112         case '\n' : // New line
00113             iLine++;
00114             break;
00115         case '\r' : // Return cursor to the first colomn.
00116             iCol = 0;
00117             break;
00118         
00119         case '\*': // Display special character.
00120             if(iEx < numEx)  {
00121                 ch = pchEx[iEx++];      
00122             }
00123         default : 
00124             // If the mamximum number of characters per line is reached, create a new line.
00125             if(iCol * (spacing + fontWidth) > SSD1306_LCDWIDTH - fontWidth) {
00126                 iLine++;
00127                 iCol = 0;
00128             }
00129             // If the mamximum number of lines is reached, write no more.
00130             if(iLine * fontHeight > SSD1306_LCDHEIGHT - 1) {
00131                 return;
00132             }
00133             // write character and set cursor to the next position.
00134             write(ch, iCol * (spacing + fontWidth), iLine * fontHeight);
00135             iCol++;
00136             break;
00137         }
00138         i++;
00139     }
00140 }
00141 // Read the predefined font bitmaps 
00142 const uint8_t* LCDGraphics::index_of_char(uint8_t c)
00143 {
00144     if('!' <= c && c <= '~')
00145     {
00146         return ascii[c - '!'];
00147     }
00148     else if (c == ' ')
00149     {   
00150         return ch_space;
00151     }
00152     else // special characters
00153     {        
00154         switch(c) {
00155             case A_CIRCONFLEX_MAJ : return ascii_extended[CHAR_A_CHAPEAU_MAJ];
00156             case A_CIRCONFLEX_MIN : return ascii_extended[CHAR_A_CHAPEAU_MIN];
00157             case A_GRAVE_MAJ : return ascii_extended[CHAR_A_GRAVE_MAJ];
00158             case A_GRAVE_MIN : return ascii_extended[CHAR_A_GRAVE_MIN];
00159             case AE_MAJ : return ascii_extended[CHAR_AE_MAJ];
00160             case AE_MIN : return ascii_extended[CHAR_AE_MIN];
00161             case CEDILE_MAJ :return ascii_extended[CHAR_C_EDILE_MAJ];
00162             case CEDILE_MIN :return ascii_extended[CHAR_C_EDILE_MIN];
00163             case E_GRAVE_MAJ : return ascii_extended[CHAR_E_GRAVE_MAJ];
00164             case E_GRAVE_MIN : return ascii_extended[CHAR_E_GRAVE_MIN];
00165             case E_AIGU_MAJ : return ascii_extended[CHAR_E_AIGU_MAJ];
00166             case E_AIGU_MIN : return ascii_extended[CHAR_E_AIGU_MIN];
00167             case E_CIRCONFLEX_MAJ : return ascii_extended[CHAR_E_CHAPEAU_MAJ];
00168             case E_CIRCONFLEX_MIN : return ascii_extended[CHAR_E_CHAPEAU_MIN];
00169             case E_TREMA_MAJ : return ascii_extended[CHAR_E_TREMA_MAJ];
00170             case E_TREMA_MIN : return ascii_extended[CHAR_E_TREMA_MIN];
00171             case I_CIRCONFLEX_MAJ : return ascii_extended[CHAR_I_CHAPEAU_MAJ];
00172             case I_CIRCONFLEX_MIN : return ascii_extended[CHAR_I_CHAPEAU_MIN];
00173             case I_TREMA_MAJ : return ascii_extended[CHAR_I_TREMA_MAJ];
00174             case I_TREMA_MIN : return ascii_extended[CHAR_I_TREMA_MIN];
00175             case O_CIRCONFLEX_MAJ : return ascii_extended[CHAR_O_CHAPEAU_MAJ];
00176             case O_CIRCONFLEX_MIN : return ascii_extended[CHAR_O_CHAPEAU_MIN];
00177             case O_TREMA_MAJ : return ascii_extended[CHAR_U_TREMA_MAJ];
00178             case O_TREMA_MIN : return ascii_extended[CHAR_O_TREMA_MIN];
00179             case U_CIRCONFLEX_MAJ : return ascii_extended[CHAR_U_CHAPEAU_MAJ];
00180             case U_CIRCONFLEX_MIN :return ascii_extended[CHAR_U_CHAPEAU_MIN];
00181             case U_GRAVE_MAJ : return ascii_extended[CHAR_U_GRAVE_MAJ];
00182             case U_GRAVE_MIN : return ascii_extended[CHAR_U_GRAVE_MIN];
00183             case U_TREMA_MIN : return ascii_extended[CHAR_U_TREMA_MIN];
00184             case U_TREMA_MAJ : return ascii_extended[CHAR_U_TREMA_MAJ];
00185             case DEGREE : return ascii_extended[CHAR_DEGREE];
00186             case EURO : return ascii_extended[CHAR_EURO];
00187         }
00188     }
00189     return NULL;
00190 }