92 //#include "mbed_debug.h" |
92 //#include "mbed_debug.h" |
93 |
93 |
94 #define SWAP(a, b) { a ^= b; b ^= a; a ^= b; } |
94 #define SWAP(a, b) { a ^= b; b ^= a; a ^= b; } |
95 |
95 |
96 |
96 |
97 SSD1322::SSD1322(proto_t displayproto, |
97 SSD1322::SSD1322(int Hz, PinName mosi, PinName miso, PinName sclk, PinName CS, PinName reset, PinName DC, |
98 int Hz, PinName mosi, PinName miso, PinName sclk, PinName CS, PinName reset, PinName DC, |
98 const char *name) |
99 const char *name, |
|
100 const unsigned int lcdsize_x, const unsigned int lcdsize_y) |
|
101 : GraphicsDisplay(name), |
99 : GraphicsDisplay(name), |
102 screensize_X(lcdsize_x), screensize_Y(lcdsize_y), |
100 screensize_X(DISPLAY_WIDTH), screensize_Y(DISPLAY_HEIGHT), |
103 _BPP(BPP), _PAGES(lcdsize_y/8*BPP), |
101 _BPP(BPP), _PAGES(DISPLAY_HEIGHT/8*BPP), |
104 _IC_X_SEGS(IC_X_SEGS), _IC_Y_COMS(IC_Y_COMS), _IC_PAGES(IC_Y_COMS/8*BPP) |
102 _IC_X_SEGS(IC_X_SEGS), _IC_Y_COMS(IC_Y_COMS), _IC_PAGES(IC_Y_COMS/8*BPP), |
105 { |
103 _spi(mosi, miso, sclk), |
106 proto = new SPI8(Hz, mosi, miso, sclk, CS, reset, DC); |
104 _DC(DC), _CS(CS), _RST(reset) |
107 buffer = (unsigned char*) malloc (screensize_X*_PAGES); |
105 { |
|
106 _RST = 1; |
|
107 _DC = 1; |
|
108 _CS = 1; |
|
109 _spi.format(8, 0); // 8 bit spi mode 0 |
|
110 _spi.frequency(Hz); |
108 set_auto_up(false); |
111 set_auto_up(false); |
109 foreground(0xFFFF); |
112 foreground(0xFFFF); |
110 background(0x0000); |
113 background(0x0000); |
111 hw_reset(); |
114 hw_reset(); |
112 bus_enable(true); |
|
113 init(); |
115 init(); |
114 set_orientation(1); |
116 set_orientation(1); |
115 cls(); |
117 cls(); |
116 locate(0,0); |
118 locate(0,0); |
117 } |
119 //_internalEventCallback.attach(this, &SSD1322::_cbHandler); |
118 |
|
119 SSD1322::~SSD1322() |
|
120 { |
|
121 free(buffer); |
|
122 } |
120 } |
123 |
121 |
124 void SSD1322::wr_cmd8(unsigned char cmd) |
122 void SSD1322::wr_cmd8(unsigned char cmd) |
125 { |
123 { |
126 proto->wr_cmd8(cmd); |
124 _CS = 0; |
|
125 _DC.write(0); // 0=cmd |
|
126 _spi.write(cmd); // write 8bit |
|
127 _DC.write(1); // 1=data next |
|
128 _CS = 1; |
127 } |
129 } |
128 |
130 |
129 void SSD1322::wr_data8(unsigned char data) |
131 void SSD1322::wr_data8(unsigned char data) |
130 { |
132 { |
131 proto->wr_data8(data); |
133 _CS = 0; |
132 } |
134 _spi.write(data); // write 8bit |
133 |
135 _CS = 1; |
134 void SSD1322::wr_cmd16(unsigned short cmd) |
136 |
135 { |
|
136 proto->wr_cmd16(cmd); |
|
137 } |
|
138 |
|
139 void SSD1322::wr_gram(unsigned short data, unsigned int count) |
|
140 { |
|
141 proto->wr_gram(data, count); |
|
142 } |
|
143 |
|
144 void SSD1322::wr_grambuf(unsigned short* data, unsigned int lenght) |
|
145 { |
|
146 proto->wr_grambuf(data, lenght); |
|
147 } |
137 } |
148 |
138 |
149 void SSD1322::hw_reset() |
139 void SSD1322::hw_reset() |
150 { |
140 { |
151 proto->hw_reset(); |
141 wait_ms(15); |
|
142 _DC = 1; |
|
143 _CS = 1; |
|
144 _RST = 0; // display reset |
|
145 wait_ms(2); |
|
146 _RST = 1; // end reset |
|
147 wait_ms(100); |
152 } |
148 } |
153 |
149 |
154 void SSD1322::bus_enable(bool enable) |
150 void SSD1322::bus_enable(bool enable) |
155 { |
151 { |
156 proto->BusEnable(enable); |
152 _CS = enable ? 0:1; |
157 } |
153 } |
158 |
|
159 |
154 |
160 |
155 |
161 // monochrome SSD1322 driver ICs does not have ram rotate in hw (swap raw<->columns) like TFT displays |
156 // monochrome SSD1322 driver ICs does not have ram rotate in hw (swap raw<->columns) like TFT displays |
162 // for portrait views, XY swap will be done in sw in pixel() function |
157 // for portrait views, XY swap will be done in sw in pixel() function |
163 void SSD1322::set_orientation(int o) |
158 void SSD1322::set_orientation(int o) |
241 win_x2 = x + w - 1; |
236 win_x2 = x + w - 1; |
242 win_y1 = y; |
237 win_y1 = y; |
243 win_y2 = y + h - 1; |
238 win_y2 = y + h - 1; |
244 } |
239 } |
245 void SSD1322::window_pushpixel(unsigned short color) { |
240 void SSD1322::window_pushpixel(unsigned short color) { |
246 pixel(cur_x, cur_y, color); |
241 pixel(cur_x, cur_y, color); |
247 cur_x++; |
242 cur_x++; |
248 if(cur_x > win_x2) { |
243 if(cur_x > win_x2) { |
249 cur_x = win_x1; |
244 cur_x = win_x1; |
250 cur_y++; |
245 cur_y++; |
251 if(cur_y > win_y2) { |
246 if(cur_y > win_y2) { |
252 cur_y = win_y1; |
247 cur_y = win_y1; |
253 } |
248 } |
254 } |
249 } |
255 } |
250 } |
256 void SSD1322::window_pushpixel(unsigned short color, unsigned int count) { |
251 void SSD1322::window_pushpixel(unsigned short color, unsigned int count) { |
257 while(count) |
252 while(count) |
258 { |
253 { |
259 pixel(cur_x, cur_y, color); |
254 pixel(cur_x, cur_y, color); |
260 cur_x++; |
255 cur_x++; |
261 if(cur_x > win_x2) |
256 if(cur_x > win_x2) |
262 { |
257 { |
263 cur_x = win_x1; |
258 cur_x = win_x1; |
264 cur_y++; |
259 cur_y++; |
265 if(cur_y > win_y2) |
260 if(cur_y > win_y2) |
266 { |
261 { |
267 cur_y = win_y1; |
262 cur_y = win_y1; |
268 } |
263 } |
269 } |
264 } |
270 count--; |
265 count--; |
271 } |
266 } |
272 } |
267 } |
273 void SSD1322::window_pushpixelbuf(unsigned short* color, unsigned int lenght) { |
268 void SSD1322::window_pushpixelbuf(unsigned short* color, unsigned int lenght) { |
274 while(lenght) |
269 while(lenght) |
275 { |
270 { |
276 pixel(cur_x, cur_y, *color++); |
271 pixel(cur_x, cur_y, *color++); |
277 cur_x++; |
272 cur_x++; |
278 if(cur_x > win_x2) |
273 if(cur_x > win_x2) |
279 { |
274 { |
280 cur_x = win_x1; |
275 cur_x = win_x1; |
281 cur_y++; |
276 cur_y++; |
282 if(cur_y > win_y2) |
277 if(cur_y > win_y2) |
283 { |
278 { |
284 cur_y = win_y1; |
279 cur_y = win_y1; |
285 } |
280 } |
286 } |
281 } |
287 lenght--; |
282 lenght--; |
288 } |
283 } |
289 } |
284 } |
290 |
285 |
291 unsigned short SSD1322::pixelpos(int x, int y) |
286 unsigned short SSD1322::pixelpos(int x, int y) |
292 { |
287 { |
310 unsigned char mask = (( 1 << _BPP) - 1); |
305 unsigned char mask = (( 1 << _BPP) - 1); |
311 |
306 |
312 buffer[(x + page*screensize_X)] = (buffer[(x + page*screensize_X)] & ~(mask<<(pos*_BPP))) | ((color&mask)<<(pos*_BPP)); |
307 buffer[(x + page*screensize_X)] = (buffer[(x + page*screensize_X)] & ~(mask<<(pos*_BPP))) | ((color&mask)<<(pos*_BPP)); |
313 */ |
308 */ |
314 |
309 |
315 unsigned char cval = buffer[(y*128) + x/2]; |
310 unsigned char cval = _pixelBuffer[(y*128) + x/2]; |
316 if (x&1) { |
311 if (x&1) { |
317 cval = (cval & 0xF0) | (color & 0x0F); |
312 cval = (cval & 0xF0) | (color & 0x0F); |
318 } else { |
313 } else { |
319 cval = (cval & 0x0F) | (color & 0x0F)<<4; |
314 cval = (cval & 0x0F) | (color & 0x0F)<<4; |
320 } |
315 } |
321 buffer[(y*128) + x/2] = cval; |
316 _pixelBuffer[(y*128) + x/2] = cval; |
322 } |
317 } |
323 |
318 |
324 unsigned short SSD1322::pixelread(int x, int y) |
319 unsigned short SSD1322::pixelread(int x, int y) |
325 { |
320 { |
326 if(!(orientation&1)) SWAP(x,y); |
321 if(!(orientation&1)) SWAP(x,y); |
357 wr_data8(end_col); |
352 wr_data8(end_col); |
358 } |
353 } |
359 |
354 |
360 void SSD1322::copy_to_lcd(void) |
355 void SSD1322::copy_to_lcd(void) |
361 { |
356 { |
|
357 unsigned int x, y; |
362 unsigned int i; |
358 unsigned int i; |
363 unsigned char x, y; |
|
364 |
|
365 set_row_address(0); |
359 set_row_address(0); |
366 set_column_address(0); |
360 set_column_address(0); |
367 |
361 |
|
362 memcpy((void*)_trBuffer, |
|
363 (const void*)_pixelBuffer, |
|
364 DISPLAY_BUFFER_ELEMENTS * sizeof(DISPLAY_BUFFER_TYPE)); |
|
365 wr_cmd8(SSD1322_CMD_WRITE_RAM); |
|
366 |
368 i = 0; |
367 i = 0; |
369 wr_cmd8(SSD1322_CMD_WRITE_RAM); |
|
370 for(y=0; y<64; y++) |
368 for(y=0; y<64; y++) |
371 for(x=0; x<128; x++) |
369 for(x=0; x<128; x++) |
372 wr_data8(buffer[i++]); |
370 wr_data8(_trBuffer[i++]); |
373 } |
371 } |
374 |
372 |
375 void SSD1322::copy_to_lcd(unsigned char from_col, unsigned char to_col, |
373 void SSD1322::copy_to_lcd(unsigned char from_col, unsigned char to_col, |
376 unsigned char from_row, unsigned char to_row) |
374 unsigned char from_row, unsigned char to_row) |
377 { |
375 { |
378 unsigned char x, y; |
376 unsigned int x, y; |
379 |
|
380 if (to_col>0x3F) |
377 if (to_col>0x3F) |
381 to_col = 0x3F; |
378 to_col = 0x3F; |
382 if (to_row>0x3F) |
379 if (to_row>0x3F) |
383 to_row = 0x3F; |
380 to_row = 0x3F; |
|
381 |
|
382 memcpy((void*)_trBuffer, |
|
383 (const void*)_pixelBuffer, |
|
384 DISPLAY_BUFFER_ELEMENTS * sizeof(DISPLAY_BUFFER_TYPE)); |
|
385 |
384 set_row_address(from_row, to_row); |
386 set_row_address(from_row, to_row); |
385 set_column_address(from_col, to_col); |
387 set_column_address(from_col, to_col); |
386 |
388 |
387 wr_cmd8(SSD1322_CMD_WRITE_RAM); |
389 wr_cmd8(SSD1322_CMD_WRITE_RAM); |
388 for(y=from_row; y<=to_row; y++) { |
390 for(y=from_row; y<=to_row; y++) { |
389 for(x=from_col; x<=to_col; x++) { |
391 for(x=from_col; x<=to_col; x++) { |
390 wr_data8(buffer[y*128 + 2*x]); |
392 wr_data8(_trBuffer[y*128 + 2*x]); |
391 wr_data8(buffer[y*128 + 2*x + 1]); |
393 wr_data8(_trBuffer[y*128 + 2*x + 1]); |
392 } |
394 } |
393 } |
395 } |
394 } |
396 } |
395 |
397 |
396 unsigned long SSD1322::buffaddr(unsigned int i) |
398 unsigned long SSD1322::buffaddr(unsigned int i) |
397 { |
399 { |
398 return (unsigned long) &(buffer[i]); |
400 return (unsigned long) &(_pixelBuffer[i]); |
399 } |
401 } |
400 |
402 |
401 void SSD1322::clrbuff(const unsigned char value) |
403 void SSD1322::clrbuff(const unsigned char value) |
402 { |
404 { |
403 memset(buffer, value, screensize_X*_PAGES); |
405 memset((void*)_pixelBuffer, value, screensize_X*_PAGES); |
404 } |
406 } |
405 |
407 |
406 void SSD1322::fills(const unsigned char value) |
408 void SSD1322::fills(const unsigned char value) |
407 { |
409 { |
408 clrbuff(value); |
410 clrbuff(value); |
409 copy_to_lcd(); |
411 copy_to_lcd(); |
410 } |
412 } |
411 |
413 |
412 void SSD1322::cls(void) |
414 void SSD1322::cls(void) |
413 { |
415 { |
414 clrbuff(); |
416 clrbuff(); |
415 copy_to_lcd(); |
417 copy_to_lcd(); |
416 } |
418 } |
417 |
419 |
418 //void ll_fill(const unsigned char value=0xFF, const unsigned char w=0x78, const unsigned char=0x80); |
|
419 void SSD1322::ll_fill(const unsigned char value, const unsigned char w, const unsigned char h) |
|
420 { |
|
421 unsigned short x,y; |
|
422 //w = 0x78; // 120 x 2px by byte => 240px |
|
423 //h = 0x80; // 0x80 for 64 rows because 2 COMs mode |
|
424 |
|
425 wr_cmd8(0x15); // COL ADDR |
|
426 wr_data8(0x00); |
|
427 wr_data8(w-1); |
|
428 |
|
429 wr_cmd8(0x75); // ROW ADDR |
|
430 wr_data8(0x00); |
|
431 wr_data8(h-1); |
|
432 |
|
433 wr_cmd8(0x5C); // WRITE RAM |
|
434 for(y=0; y<h/2; y++) |
|
435 { |
|
436 for(x=0; x<2*w; x++) |
|
437 { |
|
438 if ((y==0) | (y==(h/2-1))) |
|
439 wr_data8(0xFF); |
|
440 else if (x == 56) // ???? |
|
441 wr_data8(0xF2); |
|
442 else if (x == 183) |
|
443 //else if (x == (2*w-1)) |
|
444 wr_data8(0x2F); |
|
445 else if ((x%10) == 0) |
|
446 wr_data8(0x55); |
|
447 else if ((x%5) == 0) |
|
448 wr_data8(0x33); |
|
449 else |
|
450 wr_data8(0x22); |
|
451 } |
|
452 } |
|
453 } |
|
454 |
|
455 int SSD1322::sizeX() |
|
456 { |
|
457 return screensize_X; |
|
458 } |
|
459 int SSD1322::sizeY() |
|
460 { |
|
461 return screensize_Y; |
|
462 } |
|
463 |
420 |
464 // reset and init the lcd controller |
421 // reset and init the lcd controller |
465 void SSD1322::init() |
422 void SSD1322::init() |
466 { |
423 { |
467 /* Start Initial Sequence ----------------------------------------------------*/ |
424 /* Start Initial Sequence ----------------------------------------------------*/ |