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.
Dependents: Hexidraw_Demo Hexiwear-FinalProject_v2
hexidraw.cpp
00001 #include "oled_info.h" 00002 #include "hexidraw.h" 00003 00004 #include "mbed.h" 00005 00006 #include <math.h> 00007 00008 /* 00009 Command descriptions from: 00010 https://cdn-shop.adafruit.com/datasheets/SSD1351-Revision+1.3.pdf 00011 */ 00012 00013 OLED::OLED () : 00014 _spi(oled_sdi_pin, NC, oled_sck_pin), 00015 _cs(oled_cs_pin), 00016 _reset(oled_rst_pin), 00017 _dc(oled_dc_pin) 00018 { 00019 if(USE_BUFFER) { 00020 for(uint16_t i = 0; i < OLED_WIDTH * OLED_HEIGHT; ++ i) { 00021 displayBuffer[i] = BLACK; 00022 } 00023 } 00024 } 00025 00026 void OLED::begin() 00027 { 00028 00029 #if 0 00030 // set pin directions 00031 pinMode(_rs, OUTPUT); 00032 00033 if (_sclk) { 00034 pinMode(_sclk, OUTPUT); 00035 00036 pinMode(_sid, OUTPUT); 00037 } else { 00038 // using the hardware SPI 00039 SPI.begin(); 00040 SPI.setDataMode(SPI_MODE3); 00041 } 00042 00043 // Toggle RST low to reset; CS low so it'll listen to us 00044 pinMode(_cs, OUTPUT); 00045 digitalWrite(_cs, LOW); 00046 00047 if (_rst) { 00048 pinMode(_rst, OUTPUT); 00049 digitalWrite(_rst, HIGH); 00050 delay(500); 00051 digitalWrite(_rst, LOW); 00052 delay(500); 00053 digitalWrite(_rst, HIGH); 00054 delay(500); 00055 } 00056 #endif 00057 DigitalOut BOOSTEN(oled_power_enable); //Enable OLED 00058 00059 //Set SPI modes 00060 // _spi.format(8,3); 00061 _spi.frequency(8000000); 00062 00063 _dc =0; 00064 BOOSTEN = 0; 00065 wait(0.1f); 00066 _reset = 0 ; 00067 wait(0.1f); 00068 _reset = 1 ; 00069 wait(0.1f); 00070 BOOSTEN = 1; 00071 00072 writeCommand(OLED_CMD_SET_CMD_LOCK); 00073 writeData(0x12); 00074 00075 writeCommand(OLED_CMD_SET_CMD_LOCK); 00076 writeData(0xB1); 00077 00078 writeCommand(OLED_CMD_DISPLAYOFF); 00079 00080 00081 writeCommand(OLED_CMD_SET_OSC_FREQ_AND_CLOCKDIV); 00082 writeData(0xF1); 00083 00084 writeCommand(OLED_CMD_SET_MUX_RATIO); 00085 writeData(0x5F); 00086 00087 writeCommand(OLED_CMD_SET_REMAP); 00088 writeData(OLED_REMAP_SETTINGS); 00089 00090 writeCommand(OLED_CMD_SET_COLUMN); 00091 writeData(0x00); 00092 writeData(0x5F); 00093 00094 writeCommand(OLED_CMD_SET_ROW); 00095 writeData(0x00); 00096 writeData(0x5F); 00097 00098 writeCommand(OLED_CMD_STARTLINE); 00099 writeData(0x80); 00100 00101 writeCommand(OLED_CMD_DISPLAYOFFSET); 00102 writeData(0x60); 00103 00104 writeCommand(OLED_CMD_PRECHARGE); 00105 writeData(0x32); 00106 00107 writeCommand(OLED_CMD_VCOMH); 00108 writeData(0x05); 00109 00110 writeCommand(OLED_CMD_NORMALDISPLAY); 00111 00112 writeCommand(OLED_CMD_CONTRASTABC); 00113 writeData(0x8A); 00114 writeData(0x51); 00115 writeData(0x8A); 00116 00117 writeCommand(OLED_CMD_CONTRASTMASTER); 00118 writeData(0xCF); 00119 00120 writeCommand(OLED_CMD_SETVSL); 00121 writeData(0xA0); 00122 writeData(0xB5); 00123 writeData(0x55); 00124 00125 writeCommand(OLED_CMD_PRECHARGE2); 00126 writeData(0x01); 00127 00128 writeCommand(OLED_CMD_DISPLAYON); 00129 } 00130 00131 void OLED::writeCommand(uint8_t code) 00132 { 00133 _dc = 0; 00134 00135 _cs = 0; 00136 _spi.write(code); 00137 _cs = 1; 00138 } 00139 00140 void OLED::writeData(uint8_t value) 00141 { 00142 _dc = 1; 00143 00144 _cs = 0; 00145 _spi.write(value); 00146 _cs = 1; 00147 } 00148 //Turns on OLED sleep mode 00149 void OLED::sleep() 00150 { 00151 writeCommand(0xAE); 00152 } 00153 //Turns off OLED sleep mode 00154 void OLED::wake() 00155 { 00156 writeCommand(0xAF); 00157 } 00158 00159 void OLED::draw() 00160 { 00161 if(USE_BUFFER) { 00162 writeCommand(OLED_CMD_SET_COLUMN); 00163 writeData(16); 00164 writeData(111); 00165 writeCommand(OLED_CMD_SET_ROW); 00166 writeData(0); 00167 writeData(95); 00168 writeCommand(OLED_CMD_WRITERAM); 00169 00170 _dc = 1; 00171 _cs = 0; 00172 00173 for(uint32_t i = 0; i < OLED_WIDTH * OLED_HEIGHT; ++ i) { 00174 writeData(displayBuffer[i] >> 8); 00175 writeData(displayBuffer[i]); 00176 } 00177 00178 _cs = 1; 00179 } 00180 } 00181 00182 void OLED::cursor(int x, int y) //goTo 00183 { 00184 if ((x >= OLED_WIDTH) || (y >= OLED_HEIGHT)) return; 00185 x+=OLED_COL_OFFSET; 00186 // set x and y coordinate 00187 writeCommand(OLED_CMD_SET_COLUMN); 00188 writeData(x); 00189 writeData(OLED_WIDTH-1); 00190 00191 writeCommand(OLED_CMD_SET_ROW); 00192 writeData(y); 00193 writeData(OLED_HEIGHT-1); 00194 00195 writeCommand(OLED_CMD_WRITERAM); 00196 } 00197 00198 void OLED::pixel(int16_t x, int16_t y, uint16_t color) 00199 { 00200 // Bounds check. 00201 if ((x >= OLED_WIDTH) || (y >= OLED_HEIGHT)) return; 00202 if ((x < 0) || (y < 0)) return; 00203 if(!USE_BUFFER) { 00204 cursor(x, y); 00205 00206 writeCommand(OLED_CMD_WRITERAM); 00207 _dc = 1; 00208 _cs = 0; 00209 00210 writeData(color >> 8); 00211 writeData(color); 00212 00213 _cs = 1; 00214 } else { 00215 displayBuffer[x+OLED_WIDTH*y] = color; 00216 } 00217 } 00218 00219 void OLED::clear (uint16_t color) 00220 { 00221 rect(0, 0, OLED_WIDTH, OLED_HEIGHT, color); 00222 } 00223 void OLED::rect(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t fillcolor) 00224 { 00225 // Bounds check 00226 if ((x >= OLED_WIDTH) || (y >= OLED_HEIGHT)) 00227 return; 00228 00229 // Y bounds check 00230 if (y+h > OLED_HEIGHT) { 00231 h = OLED_HEIGHT - y - 1; 00232 } 00233 00234 // X bounds check 00235 if (x+w > OLED_WIDTH) { 00236 w = OLED_WIDTH - x - 1; 00237 } 00238 if(!USE_BUFFER) { 00239 x+= OLED_COL_OFFSET; 00240 00241 // set location 00242 writeCommand(OLED_CMD_SET_COLUMN); 00243 writeData(x); 00244 writeData(x+(w-1)); 00245 writeCommand(OLED_CMD_SET_ROW); 00246 writeData(y); 00247 writeData(y+(h-1)); 00248 // fill! 00249 writeCommand(OLED_CMD_WRITERAM); 00250 00251 for (uint16_t i=0; i < w*h; i++) { 00252 writeData(fillcolor >> 8); 00253 writeData(fillcolor); 00254 } 00255 } else { 00256 for(uint16_t _w = 0; _w < w; ++_w) { 00257 for(uint16_t _h = 0; _h < h; ++_h) { 00258 displayBuffer[((x+_w)+OLED_WIDTH*(y+_h))] = fillcolor; 00259 } 00260 } 00261 } 00262 } 00263 00264 void OLED::circle(uint16_t x, uint16_t y, uint16_t radius, uint16_t color, uint16_t width) 00265 { 00266 const float DEG2RAD = 3.14159f/180; 00267 for(uint16_t r = 0; r < width; ++r) { 00268 for(uint16_t i = 0; i < 360; ++i) { 00269 float degInRad = i*DEG2RAD; 00270 uint16_t x2 = x + cos(degInRad) * (radius+r); 00271 uint16_t y2 = y + sin(degInRad) * (radius+r); 00272 if(USE_BUFFER) { 00273 displayBuffer[((x2)+OLED_WIDTH*(y2))] = color; 00274 } else { 00275 pixel(x2, y2, color); 00276 } 00277 } 00278 } 00279 } 00280 00281 void buffer_swap( 00282 uint16_t* imgDst, 00283 const uint8_t* imgSrc, 00284 uint16_t imgSize 00285 ) 00286 { 00287 for ( int var = 0; var < imgSize; var++ ) { 00288 *imgDst = *imgSrc << 8; 00289 imgSrc++; 00290 *imgDst |= *imgSrc; 00291 imgDst++; 00292 imgSrc++; 00293 } 00294 } 00295 00296 00297 void OLED::image (uint16_t x, uint16_t y, const uint8_t* image) 00298 { 00299 x+= OLED_COL_OFFSET; 00300 //cursor(x, y); 00301 00302 uint16_t w = image[2]; 00303 uint16_t h = image[4]; 00304 00305 uint16_t image_data_size = w * h * OLED_BYTES_PER_PIXEL; 00306 00307 if(!USE_BUFFER) { 00308 writeCommand(OLED_CMD_SET_COLUMN); 00309 writeData(x); 00310 writeData(x+(w-1)); 00311 writeCommand(OLED_CMD_SET_ROW); 00312 writeData(y); 00313 writeData(y+(h-1)); 00314 00315 writeCommand(OLED_CMD_WRITERAM); 00316 _dc = 1; 00317 _cs = 0; 00318 00319 const uint8_t* buffer = OLED_SKIP_IMAGE_HEADER(image); 00320 00321 for ( uint32_t i = 0; i < image_data_size; i++) { 00322 _spi.write(*buffer); 00323 buffer += 1; 00324 } 00325 00326 } else { 00327 const uint8_t* buffer = OLED_SKIP_IMAGE_HEADER(image); 00328 buffer_swap(displayBuffer, buffer, image_data_size); 00329 } 00330 00331 } 00332 00333 00334 void OLED::dim() 00335 { 00336 for ( int i = 0; i < 16; i++ ) { 00337 writeCommand( OLED_CMD_CONTRASTMASTER); 00338 writeData( 0xC0 | (0xF-i)); 00339 wait( 20 ); 00340 } 00341 } 00342 00343 void OLED::hline(uint16_t x, uint16_t y, uint16_t width, uint16_t color, uint16_t thickness) 00344 { 00345 if(!USE_BUFFER) { 00346 //x+= OLED_COL_OFFSET; 00347 // set location 00348 writeCommand(OLED_CMD_SET_COLUMN); 00349 writeData(x); 00350 writeData(x+width-1); 00351 writeCommand(OLED_CMD_SET_ROW); 00352 writeData(y); 00353 writeData(y+thickness-1); 00354 // fill! 00355 writeCommand(OLED_CMD_WRITERAM); 00356 00357 for (uint16_t i=0; i < width*thickness; i++) { 00358 writeData(color >> 8); 00359 writeData(color); 00360 } 00361 } else { 00362 00363 for (uint16_t w=0; w < width; w++) { 00364 for (uint16_t h=0; h < thickness; h++) { 00365 displayBuffer[((x+w)+OLED_WIDTH*(y+h))] = color; 00366 } 00367 } 00368 } 00369 00370 } 00371 00372 void OLED::vline(uint16_t x, uint16_t y, uint16_t height, uint16_t color, uint16_t thickness) 00373 { 00374 if(!USE_BUFFER) { 00375 x+= OLED_COL_OFFSET; 00376 // set location 00377 writeCommand(OLED_CMD_SET_COLUMN); 00378 writeData(x); 00379 writeData(x+thickness-1); 00380 writeCommand(OLED_CMD_SET_ROW); 00381 writeData(y); 00382 writeData(y+height-1); 00383 // fill! 00384 writeCommand(OLED_CMD_WRITERAM); 00385 00386 for (uint16_t i=0; i < height*thickness; i++) { 00387 writeData(color >> 8); 00388 writeData(color); 00389 } 00390 } else { 00391 for (uint16_t w=0; w < thickness; w++) { 00392 for (uint16_t h=0; h < height; h++) { 00393 displayBuffer[((x+w)+OLED_WIDTH*(y+h))] = color; 00394 } 00395 } 00396 } 00397 } 00398 00399 void OLED::text(uint16_t x, uint16_t y, const uint8_t* text, const uint8_t* font, uint16_t color) 00400 { 00401 00402 x += OLED_COL_OFFSET; 00403 uint8_t pad = 2; 00404 00405 uint8_t firstChar = font[2]; 00406 uint8_t charHeight = font[6]; 00407 00408 uint16_t current_char = 0; 00409 while(text[current_char] != 0) { 00410 00411 ++current_char; 00412 } 00413 } 00414 00415 uint16_t Color565(uint8_t r, uint8_t g, uint8_t b) 00416 { 00417 uint16_t c; 00418 c = r >> 3; 00419 c <<= 6; 00420 c |= g >> 2; 00421 c <<= 5; 00422 c |= b >> 3; 00423 00424 return c; 00425 }
Generated on Mon Jul 18 2022 21:14:41 by
1.7.2