Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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 }
Generated on Wed Aug 17 2022 05:29:14 by
 1.7.2