Lib for the LCD display on mbed lab Board

Dependents:   SprintUSBModemWebsocketTest-LCD-RO iOSAppChat Christmas-LCD led_dimm ... more

Basic information

The LCD on the mbed lab board has 128 x 32 pixels and is connected via spi. It use a ST7565R controller. The spi connection is fast, but it has one drawback - you can't read the display buffer. This is a problem, because each bit reflect a pixel. If you want to set only one bit / pixel, you have to know the status of the other seven bits / pixel. Because of this we have to use a framebuffer (128 * 32 / 8 = 512 Byte). All drawing functions are working on this framebuffer. If you use the LPC1768 based mbed, the dma channel 0 is used to speed up the transfer to the lcd. This information is only relevant if you also want to use the dma controller. You have to switch to a other channel.

There are two update mode. After startup the automode is turned on. This means that the display is automaticly updated after the drawing. For example - if you call the function

lcd.line(x0, y0, x1, y1, 1);

a line from x0,y0 to x1,y1 is drawn inside the framebuffer and after that the framebuffer is copied to the lcd. If you draw more lines, it will be faster to draw all graphics inside the framebuffer and update the lcd only once. To do so, you can use the function :

lcd.set_auto_up(0);

This switch off the autoupdate. If you want to see it, you have to refresh the lcd by calling the function :

lcd.copy_to_lcd();

lcd.set_auto_up(1);

will switch back to auto update mode.

Basic functions

To use the lcd we have to create a lcd object :

C12832_LCD lcd;

There are two drawing modes : NORMAL and XOR. At startup the mode is NORMAL. If you use

lcd.setmode(XOR);

you switch to XOR mode. In this mode a pixel in the frambuffer is inverted if you set it to 1.

lcd.setmode(NORMAL);

switch back to normal mode.

The function :

lcd.invert(1);

will invert the lcd. This is done by the lcd controller. The framebuffer is not changed.

lcd.invert(0);

will switch back.

The function :

lcd.cls();

clear the screen.

The function :

lcd.set_contrast(25);

will set the contrast. The lib start with 23. A value between 10 and 35 will be visible.

Text

To print text you simply have to use the printf function. The output of the stdout is redirected to the lcd.

lcd.printf("temperature : %3.2f F",heat);

The position can be set up with the function :

lcd.locate(x,y);

At startup a 7 pixel font is used. If you want to use a different font you can include the lib http://mbed.org/users/dreschpe/code/LCD_fonts. This lib include four additional fonts. From 6 pixel to 23 pixel. To switch the font use :

lcd.set_font((unsigned char*) Arial_9);

The names of the fonts are : Small_6, Small_7, Arial_9, Arial12x12 and Arial24x23.

The function :

lcd._putc(c);

print the char c on the actual cursor position.

The function :

lcd.character(x, y, c);

print the char c at position x,y.

Graphic

The function :

lcd.line(x0, y0, x1, y1, color);

draw a single pixel line from x0,y0 to x1,y1. If color is 1 : black, 0 : white.

The function :

lcd.rect(x0, y0, x1, y1, color);

draw a single pixel rectangle from x0, y0 to x1, y1. If color is 1 : black, 0 : white.

The function :

lcd.fillrect(x0, y0, x1, y1, color);

draw a filled rectangle from x0, y0 to x1, y1. If color is 1 : black, 0 : white.

The function :

lcd.circle(x, y, r, color);

draw a circle with x,y center and radius r. If color is 1 : black, 0 : white.

The function :

lcd.fillcircle(x, y, r, color);

draw a filled circle with x,y center and radius r. If color is 1 : black, 0 : white.

The function :

lcd.pixel(x, y, color);

set a single pixel at x,y. If color is 1 : black, 0 : white. This function is not updating the lcd ! Even if the autoupdate is on. You have to call lcd.copy_to_lcd() after using this function - or to use a other function with autoupdate afterwards.

mbed rtos

To use the mbed rtos with the lib we have to make the lib thread save. What is the problem ? If different threads are writing to the lcd it can end in troubble. Thread1 is using the pintf("hello mbed") function to print this string to the actual position. After the chars "hel" are printed ,the scheduler is switching to thread2. This thread is writing at a different position on the screen. After that the scheduler is switch back to thread1 and the print function continue. Thread1 did not know that the internal cursor position has changed ....

To protect the access to the lcd we use a Mutex. If a thread has the mutex and a other thread also want it, the second thread has to wait.

Mutex lcd_mutex;  // define the mutex
    //...
lcd_mutex.lock(); // get the mutex or wait

//acccess to the lcd
 
lcd_mutex.unlock(); // free the mutex 

We use this framing to access the lcd.

Test program to show : http://mbed.org/users/dreschpe/code/lab1/

Committer:
dreschpe
Date:
Thu Oct 18 20:54:09 2012 +0000
Revision:
2:bdc53502af17
Parent:
1:66dd8afbfd06
Child:
3:468cdccff7af
add LPC11U24 support; fix bug in set_contrast

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dreschpe 0:4bbc531be6e2 1 /* mbed library for the mbed Lab Board 128*32 pixel LCD
dreschpe 0:4bbc531be6e2 2 * use C12832 controller
dreschpe 0:4bbc531be6e2 3 * Copyright (c) 2012 Peter Drescher - DC2PD
dreschpe 0:4bbc531be6e2 4 * Released under the MIT License: http://mbed.org/license/mit
dreschpe 0:4bbc531be6e2 5 *
dreschpe 0:4bbc531be6e2 6 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
dreschpe 0:4bbc531be6e2 7 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
dreschpe 0:4bbc531be6e2 8 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
dreschpe 0:4bbc531be6e2 9 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
dreschpe 0:4bbc531be6e2 10 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
dreschpe 0:4bbc531be6e2 11 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
dreschpe 0:4bbc531be6e2 12 * THE SOFTWARE.
dreschpe 0:4bbc531be6e2 13 */
dreschpe 0:4bbc531be6e2 14
dreschpe 0:4bbc531be6e2 15 // 13.10.12 initial design
dreschpe 0:4bbc531be6e2 16 // optional defines :
dreschpe 0:4bbc531be6e2 17 #define debug_lcd 1
dreschpe 0:4bbc531be6e2 18
dreschpe 0:4bbc531be6e2 19 #include "C12832_lcd.h"
dreschpe 0:4bbc531be6e2 20 #include "mbed.h"
dreschpe 0:4bbc531be6e2 21 #include "stdio.h"
dreschpe 0:4bbc531be6e2 22
dreschpe 0:4bbc531be6e2 23 #define BPP 1 // Bits per pixel
dreschpe 0:4bbc531be6e2 24
dreschpe 0:4bbc531be6e2 25 C12832_LCD::C12832_LCD(const char* name)
dreschpe 0:4bbc531be6e2 26 : _spi(p5,NC,p7),_reset(p6),_A0(p8),_CS(p11),GraphicsDisplay(name)
dreschpe 0:4bbc531be6e2 27 {
dreschpe 0:4bbc531be6e2 28 orientation = 1;
dreschpe 0:4bbc531be6e2 29 draw_mode = NORMAL;
dreschpe 0:4bbc531be6e2 30 char_x = 0;
dreschpe 0:4bbc531be6e2 31 lcd_reset();
dreschpe 0:4bbc531be6e2 32 }
dreschpe 0:4bbc531be6e2 33
dreschpe 0:4bbc531be6e2 34 int C12832_LCD::width()
dreschpe 0:4bbc531be6e2 35 {
dreschpe 0:4bbc531be6e2 36 if (orientation == 0 || orientation == 2) return 32;
dreschpe 0:4bbc531be6e2 37 else return 128;
dreschpe 0:4bbc531be6e2 38 }
dreschpe 0:4bbc531be6e2 39
dreschpe 0:4bbc531be6e2 40 int C12832_LCD::height()
dreschpe 0:4bbc531be6e2 41 {
dreschpe 0:4bbc531be6e2 42 if (orientation == 0 || orientation == 2) return 128;
dreschpe 0:4bbc531be6e2 43 else return 32;
dreschpe 0:4bbc531be6e2 44 }
dreschpe 0:4bbc531be6e2 45
dreschpe 0:4bbc531be6e2 46
dreschpe 1:66dd8afbfd06 47 /*void C12832_LCD::set_orientation(unsigned int o)
dreschpe 0:4bbc531be6e2 48 {
dreschpe 0:4bbc531be6e2 49 orientation = o;
dreschpe 0:4bbc531be6e2 50 switch (o) {
dreschpe 0:4bbc531be6e2 51 case (0):
dreschpe 0:4bbc531be6e2 52 wr_cmd(0xA0);
dreschpe 0:4bbc531be6e2 53 wr_cmd(0xC0);
dreschpe 0:4bbc531be6e2 54 break;
dreschpe 0:4bbc531be6e2 55 case (1):
dreschpe 0:4bbc531be6e2 56 wr_cmd(0xA0);
dreschpe 0:4bbc531be6e2 57 wr_cmd(0xC8);
dreschpe 0:4bbc531be6e2 58 break;
dreschpe 0:4bbc531be6e2 59 case (2):
dreschpe 0:4bbc531be6e2 60 wr_cmd(0xA1);
dreschpe 0:4bbc531be6e2 61 wr_cmd(0xC8);
dreschpe 0:4bbc531be6e2 62 break;
dreschpe 0:4bbc531be6e2 63 case (3):
dreschpe 0:4bbc531be6e2 64 wr_cmd(0xA1);
dreschpe 0:4bbc531be6e2 65 wr_cmd(0xC0);
dreschpe 0:4bbc531be6e2 66 break;
dreschpe 0:4bbc531be6e2 67 }
dreschpe 0:4bbc531be6e2 68 }
dreschpe 0:4bbc531be6e2 69
dreschpe 1:66dd8afbfd06 70 */
dreschpe 1:66dd8afbfd06 71
dreschpe 0:4bbc531be6e2 72 void C12832_LCD::invert(unsigned int o)
dreschpe 0:4bbc531be6e2 73 {
dreschpe 0:4bbc531be6e2 74 if(o == 0) wr_cmd(0xA6);
dreschpe 0:4bbc531be6e2 75 else wr_cmd(0xA7);
dreschpe 0:4bbc531be6e2 76 }
dreschpe 0:4bbc531be6e2 77
dreschpe 0:4bbc531be6e2 78
dreschpe 0:4bbc531be6e2 79 void C12832_LCD::set_contrast(unsigned int o)
dreschpe 0:4bbc531be6e2 80 {
dreschpe 1:66dd8afbfd06 81 contrast = o;
dreschpe 0:4bbc531be6e2 82 wr_cmd(0x81); // set volume
dreschpe 2:bdc53502af17 83 wr_cmd(o & 0x3F);
dreschpe 0:4bbc531be6e2 84 }
dreschpe 0:4bbc531be6e2 85
dreschpe 1:66dd8afbfd06 86 unsigned int C12832_LCD::get_contrast(void)
dreschpe 1:66dd8afbfd06 87 {
dreschpe 1:66dd8afbfd06 88 return(contrast);
dreschpe 1:66dd8afbfd06 89 }
dreschpe 1:66dd8afbfd06 90
dreschpe 0:4bbc531be6e2 91
dreschpe 0:4bbc531be6e2 92 // write command to lcd controller
dreschpe 0:4bbc531be6e2 93
dreschpe 0:4bbc531be6e2 94 void C12832_LCD::wr_cmd(unsigned char cmd)
dreschpe 0:4bbc531be6e2 95 {
dreschpe 0:4bbc531be6e2 96 _A0 = 0;
dreschpe 0:4bbc531be6e2 97 _CS = 0;
dreschpe 2:bdc53502af17 98 #if defined TARGET_LPC1768 // fast without mbed lib
dreschpe 0:4bbc531be6e2 99 LPC_SSP1->DR = cmd;
dreschpe 0:4bbc531be6e2 100 do {
dreschpe 0:4bbc531be6e2 101 } while ((LPC_SSP1->SR & 0x10) == 0x10); // wait for SPI1 idle
dreschpe 2:bdc53502af17 102 #else
dreschpe 2:bdc53502af17 103 _spi.write(cmd);
dreschpe 2:bdc53502af17 104 #endif
dreschpe 2:bdc53502af17 105 _CS = 1;
dreschpe 0:4bbc531be6e2 106 }
dreschpe 0:4bbc531be6e2 107
dreschpe 0:4bbc531be6e2 108 // write data to lcd controller
dreschpe 0:4bbc531be6e2 109
dreschpe 0:4bbc531be6e2 110 void C12832_LCD::wr_dat(unsigned char dat)
dreschpe 0:4bbc531be6e2 111 {
dreschpe 0:4bbc531be6e2 112 _A0 = 1;
dreschpe 0:4bbc531be6e2 113 _CS = 0;
dreschpe 2:bdc53502af17 114 #if defined TARGET_LPC1768 // fast without mbed lib
dreschpe 0:4bbc531be6e2 115 LPC_SSP1->DR = dat;
dreschpe 0:4bbc531be6e2 116 do {
dreschpe 0:4bbc531be6e2 117 } while ((LPC_SSP1->SR & 0x10) == 0x10); // wait for SPI1 idle
dreschpe 2:bdc53502af17 118 #else
dreschpe 2:bdc53502af17 119 _spi.write(dat);
dreschpe 2:bdc53502af17 120 #endif
dreschpe 0:4bbc531be6e2 121 _CS = 1;
dreschpe 0:4bbc531be6e2 122 }
dreschpe 0:4bbc531be6e2 123
dreschpe 0:4bbc531be6e2 124 // reset and init the lcd controller
dreschpe 0:4bbc531be6e2 125
dreschpe 0:4bbc531be6e2 126 void C12832_LCD::lcd_reset()
dreschpe 0:4bbc531be6e2 127 {
dreschpe 0:4bbc531be6e2 128
dreschpe 0:4bbc531be6e2 129 _spi.format(8,3); // 8 bit spi mode 3
dreschpe 0:4bbc531be6e2 130 _spi.frequency(20000000); // 19,2 Mhz SPI clock
dreschpe 0:4bbc531be6e2 131 DigitalOut _reset(p6);
dreschpe 0:4bbc531be6e2 132 _A0 = 0;
dreschpe 0:4bbc531be6e2 133 _CS = 1;
dreschpe 0:4bbc531be6e2 134 _reset = 0; // display reset
dreschpe 0:4bbc531be6e2 135 wait_us(50);
dreschpe 0:4bbc531be6e2 136 _reset = 1; // end reset
dreschpe 0:4bbc531be6e2 137 wait_ms(5);
dreschpe 0:4bbc531be6e2 138
dreschpe 0:4bbc531be6e2 139 /* Start Initial Sequence ----------------------------------------------------*/
dreschpe 0:4bbc531be6e2 140
dreschpe 0:4bbc531be6e2 141 wr_cmd(0xAE); // display off
dreschpe 0:4bbc531be6e2 142 wr_cmd(0xA2); // bias voltage
dreschpe 0:4bbc531be6e2 143
dreschpe 0:4bbc531be6e2 144 wr_cmd(0xA0);
dreschpe 0:4bbc531be6e2 145 wr_cmd(0xC8); // colum normal
dreschpe 0:4bbc531be6e2 146
dreschpe 0:4bbc531be6e2 147 wr_cmd(0x22); // voltage resistor ratio
dreschpe 0:4bbc531be6e2 148 wr_cmd(0x2F); // power on
dreschpe 1:66dd8afbfd06 149 //wr_cmd(0xA4); // LCD display ram
dreschpe 0:4bbc531be6e2 150 wr_cmd(0x40); // start line = 0
dreschpe 0:4bbc531be6e2 151 wr_cmd(0xAF); // display ON
dreschpe 0:4bbc531be6e2 152
dreschpe 0:4bbc531be6e2 153 wr_cmd(0x81); // set contrast
dreschpe 0:4bbc531be6e2 154 wr_cmd(0x17); // set contrast
dreschpe 0:4bbc531be6e2 155
dreschpe 0:4bbc531be6e2 156 wr_cmd(0xA6); // display normal
dreschpe 0:4bbc531be6e2 157
dreschpe 2:bdc53502af17 158
dreschpe 2:bdc53502af17 159 #if defined TARGET_LPC1768 //setup DMA channel 0
dreschpe 0:4bbc531be6e2 160 LPC_SC->PCONP |= (1UL << 29); // Power up the GPDMA
dreschpe 2:bdc53502af17 161 LPC_GPDMA->DMACConfig = 1; // enable DMA controller
dreschpe 0:4bbc531be6e2 162 LPC_GPDMA->DMACIntTCClear = 0x1;
dreschpe 0:4bbc531be6e2 163 LPC_GPDMA->DMACIntErrClr = 0x1;
dreschpe 0:4bbc531be6e2 164 LPC_GPDMACH0->DMACCLLI = 0;
dreschpe 2:bdc53502af17 165 #endif
dreschpe 0:4bbc531be6e2 166 // clear and update LCD
dreschpe 0:4bbc531be6e2 167 memset(buffer,0x00,512); // clear display buffer
dreschpe 0:4bbc531be6e2 168 copy_to_lcd();
dreschpe 0:4bbc531be6e2 169 }
dreschpe 0:4bbc531be6e2 170
dreschpe 0:4bbc531be6e2 171 // set one pixel in buffer
dreschpe 0:4bbc531be6e2 172
dreschpe 0:4bbc531be6e2 173 void C12832_LCD::pixel(int x, int y, int color)
dreschpe 0:4bbc531be6e2 174 {
dreschpe 0:4bbc531be6e2 175 // first check parameter
dreschpe 0:4bbc531be6e2 176 if(x > 128 || y > 32 || x < 0 || y < 0) return;
dreschpe 0:4bbc531be6e2 177
dreschpe 0:4bbc531be6e2 178 if(draw_mode == NORMAL) {
dreschpe 0:4bbc531be6e2 179 if(color == 0)
dreschpe 0:4bbc531be6e2 180 buffer[x + ((y/8) * 128)] &= ~(1 << (y%8)); // erase pixel
dreschpe 0:4bbc531be6e2 181 else
dreschpe 0:4bbc531be6e2 182 buffer[x + ((y/8) * 128)] |= (1 << (y%8)); // set pixel
dreschpe 0:4bbc531be6e2 183 } else { // XOR mode
dreschpe 0:4bbc531be6e2 184 if(color == 1)
dreschpe 0:4bbc531be6e2 185 buffer[x + ((y/8) * 128)] ^= (1 << (y%8)); // xor pixel
dreschpe 0:4bbc531be6e2 186 }
dreschpe 0:4bbc531be6e2 187 }
dreschpe 0:4bbc531be6e2 188
dreschpe 0:4bbc531be6e2 189 // update lcd
dreschpe 0:4bbc531be6e2 190
dreschpe 0:4bbc531be6e2 191 void C12832_LCD::copy_to_lcd(void)
dreschpe 0:4bbc531be6e2 192 {
dreschpe 2:bdc53502af17 193 #ifndef TARGET_LPC1768
dreschpe 2:bdc53502af17 194 int i;
dreschpe 2:bdc53502af17 195 #endif
dreschpe 0:4bbc531be6e2 196 //page 0
dreschpe 0:4bbc531be6e2 197 wr_cmd(0x00); // set column low nibble 0
dreschpe 0:4bbc531be6e2 198 wr_cmd(0x10); // set column hi nibble 0
dreschpe 0:4bbc531be6e2 199 wr_cmd(0xB0); // set page address 0
dreschpe 2:bdc53502af17 200 _A0 = 1;
dreschpe 2:bdc53502af17 201 #if defined TARGET_LPC1768
dreschpe 0:4bbc531be6e2 202 _CS = 0;
dreschpe 0:4bbc531be6e2 203 // start 128 byte DMA transfer to SPI1
dreschpe 0:4bbc531be6e2 204 LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP1->DR; // we send to SSP1
dreschpe 0:4bbc531be6e2 205 LPC_SSP1->DMACR = 0x2; // Enable SSP1 for DMA.
dreschpe 0:4bbc531be6e2 206 LPC_GPDMA->DMACIntTCClear = 0x1;
dreschpe 0:4bbc531be6e2 207 LPC_GPDMA->DMACIntErrClr = 0x1;
dreschpe 0:4bbc531be6e2 208 LPC_GPDMACH0->DMACCSrcAddr = (uint32_t) (buffer);
dreschpe 0:4bbc531be6e2 209 LPC_GPDMACH0->DMACCControl = 128 | (1UL << 31) | DMA_CHANNEL_SRC_INC ; // 8 bit transfer , address increment, interrupt
dreschpe 0:4bbc531be6e2 210 LPC_GPDMACH0->DMACCConfig = DMA_CHANNEL_ENABLE | DMA_TRANSFER_TYPE_M2P | DMA_DEST_SSP1_TX;
dreschpe 0:4bbc531be6e2 211 LPC_GPDMA->DMACSoftSReq = 0x1;
dreschpe 0:4bbc531be6e2 212 do {
dreschpe 0:4bbc531be6e2 213 } while ((LPC_GPDMA->DMACRawIntTCStat & 0x01) == 0); // DMA is running
dreschpe 0:4bbc531be6e2 214 do {
dreschpe 0:4bbc531be6e2 215 } while ((LPC_SSP1->SR & 0x10) == 0x10); // SPI1 not idle
dreschpe 0:4bbc531be6e2 216 _CS = 1;
dreschpe 2:bdc53502af17 217 #else // no DMA
dreschpe 2:bdc53502af17 218 for(i=0;i<128;i++){
dreschpe 2:bdc53502af17 219 wr_dat(buffer[i]);
dreschpe 2:bdc53502af17 220 }
dreschpe 2:bdc53502af17 221 #endif
dreschpe 0:4bbc531be6e2 222
dreschpe 0:4bbc531be6e2 223 // page 1
dreschpe 0:4bbc531be6e2 224 wr_cmd(0x00); // set column low nibble 0
dreschpe 0:4bbc531be6e2 225 wr_cmd(0x10); // set column hi nibble 0
dreschpe 0:4bbc531be6e2 226 wr_cmd(0xB1); // set page address 1
dreschpe 2:bdc53502af17 227 _A0 = 1;
dreschpe 2:bdc53502af17 228 #if defined TARGET_LPC1768
dreschpe 0:4bbc531be6e2 229 _CS = 0;
dreschpe 0:4bbc531be6e2 230 // start 128 byte DMA transfer to SPI1
dreschpe 0:4bbc531be6e2 231 LPC_GPDMA->DMACIntTCClear = 0x1;
dreschpe 0:4bbc531be6e2 232 LPC_GPDMA->DMACIntErrClr = 0x1;
dreschpe 0:4bbc531be6e2 233 LPC_GPDMACH0->DMACCSrcAddr = (uint32_t) (buffer + 128);
dreschpe 0:4bbc531be6e2 234 LPC_GPDMACH0->DMACCControl = 128 | (1UL << 31) | DMA_CHANNEL_SRC_INC ; // 8 bit transfer , address increment, interrupt
dreschpe 0:4bbc531be6e2 235 LPC_GPDMACH0->DMACCConfig = DMA_CHANNEL_ENABLE | DMA_TRANSFER_TYPE_M2P | DMA_DEST_SSP1_TX;
dreschpe 0:4bbc531be6e2 236 LPC_GPDMA->DMACSoftSReq = 0x1;
dreschpe 0:4bbc531be6e2 237 do {
dreschpe 0:4bbc531be6e2 238 } while ((LPC_GPDMA->DMACRawIntTCStat & 0x01) == 0); // DMA is running
dreschpe 0:4bbc531be6e2 239 do {
dreschpe 0:4bbc531be6e2 240 } while ((LPC_SSP1->SR & 0x10) == 0x10); // SPI1 not idle
dreschpe 0:4bbc531be6e2 241 _CS = 1;
dreschpe 2:bdc53502af17 242 #else // no DMA
dreschpe 2:bdc53502af17 243 for(i=128;i<256;i++){
dreschpe 2:bdc53502af17 244 wr_dat(buffer[i]);
dreschpe 2:bdc53502af17 245 }
dreschpe 2:bdc53502af17 246 #endif
dreschpe 0:4bbc531be6e2 247
dreschpe 0:4bbc531be6e2 248 //page 2
dreschpe 0:4bbc531be6e2 249 wr_cmd(0x00); // set column low nibble 0
dreschpe 0:4bbc531be6e2 250 wr_cmd(0x10); // set column hi nibble 0
dreschpe 0:4bbc531be6e2 251 wr_cmd(0xB2); // set page address 2
dreschpe 2:bdc53502af17 252 _A0 = 1;
dreschpe 2:bdc53502af17 253 #if defined TARGET_LPC1768
dreschpe 0:4bbc531be6e2 254 _CS = 0;
dreschpe 0:4bbc531be6e2 255 // start 128 byte DMA transfer to SPI1
dreschpe 0:4bbc531be6e2 256 LPC_GPDMA->DMACIntTCClear = 0x1;
dreschpe 0:4bbc531be6e2 257 LPC_GPDMA->DMACIntErrClr = 0x1;
dreschpe 0:4bbc531be6e2 258 LPC_GPDMACH0->DMACCSrcAddr = (uint32_t) (buffer + 256);
dreschpe 0:4bbc531be6e2 259 LPC_GPDMACH0->DMACCControl = 128 | (1UL << 31) | DMA_CHANNEL_SRC_INC ; // 8 bit transfer , address increment, interrupt
dreschpe 0:4bbc531be6e2 260 LPC_GPDMACH0->DMACCConfig = DMA_CHANNEL_ENABLE | DMA_TRANSFER_TYPE_M2P | DMA_DEST_SSP1_TX ;
dreschpe 0:4bbc531be6e2 261 LPC_GPDMA->DMACSoftSReq = 0x1;
dreschpe 0:4bbc531be6e2 262 do {
dreschpe 0:4bbc531be6e2 263 } while ((LPC_GPDMA->DMACRawIntTCStat & 0x01) == 0); // DMA is running
dreschpe 0:4bbc531be6e2 264 do {
dreschpe 0:4bbc531be6e2 265 } while ((LPC_SSP1->SR & 0x10) == 0x10); // SPI1 not idle
dreschpe 0:4bbc531be6e2 266 _CS = 1;
dreschpe 2:bdc53502af17 267 #else // no DMA
dreschpe 2:bdc53502af17 268 for(i=256;i<384;i++){
dreschpe 2:bdc53502af17 269 wr_dat(buffer[i]);
dreschpe 2:bdc53502af17 270 }
dreschpe 2:bdc53502af17 271 #endif
dreschpe 2:bdc53502af17 272
dreschpe 0:4bbc531be6e2 273 //page 3
dreschpe 0:4bbc531be6e2 274 wr_cmd(0x00); // set column low nibble 0
dreschpe 0:4bbc531be6e2 275 wr_cmd(0x10); // set column hi nibble 0
dreschpe 0:4bbc531be6e2 276 wr_cmd(0xB3); // set page address 3
dreschpe 0:4bbc531be6e2 277 _A0 = 1;
dreschpe 2:bdc53502af17 278
dreschpe 2:bdc53502af17 279 _CS = 0;
dreschpe 2:bdc53502af17 280 #if defined TARGET_LPC1768
dreschpe 0:4bbc531be6e2 281 // start 128 byte DMA transfer to SPI1
dreschpe 0:4bbc531be6e2 282 LPC_GPDMA->DMACIntTCClear = 0x1;
dreschpe 0:4bbc531be6e2 283 LPC_GPDMA->DMACIntErrClr = 0x1;
dreschpe 0:4bbc531be6e2 284 LPC_GPDMACH0->DMACCSrcAddr = (uint32_t) (buffer + 384);
dreschpe 0:4bbc531be6e2 285 LPC_GPDMACH0->DMACCControl = 128 | (1UL << 31) | DMA_CHANNEL_SRC_INC ; // 8 bit transfer , address increment, interrupt
dreschpe 0:4bbc531be6e2 286 LPC_GPDMACH0->DMACCConfig = DMA_CHANNEL_ENABLE | DMA_TRANSFER_TYPE_M2P | DMA_DEST_SSP1_TX;
dreschpe 0:4bbc531be6e2 287 LPC_GPDMA->DMACSoftSReq = 0x1;
dreschpe 0:4bbc531be6e2 288 do {
dreschpe 0:4bbc531be6e2 289 } while ((LPC_GPDMA->DMACRawIntTCStat & 0x01) == 0); // DMA is running
dreschpe 0:4bbc531be6e2 290 do {
dreschpe 0:4bbc531be6e2 291 } while ((LPC_SSP1->SR & 0x10) == 0x10); // SPI1 not idle
dreschpe 0:4bbc531be6e2 292 _CS = 1;
dreschpe 2:bdc53502af17 293 #else // no DMA
dreschpe 2:bdc53502af17 294 for(i=384;i<512;i++){
dreschpe 2:bdc53502af17 295 wr_dat(buffer[i]);
dreschpe 2:bdc53502af17 296 }
dreschpe 2:bdc53502af17 297 #endif
dreschpe 0:4bbc531be6e2 298 }
dreschpe 0:4bbc531be6e2 299
dreschpe 0:4bbc531be6e2 300 void C12832_LCD::cls(void)
dreschpe 0:4bbc531be6e2 301 {
dreschpe 0:4bbc531be6e2 302 memset(buffer,0x00,512); // clear display buffer
dreschpe 0:4bbc531be6e2 303 copy_to_lcd();
dreschpe 0:4bbc531be6e2 304 }
dreschpe 0:4bbc531be6e2 305
dreschpe 0:4bbc531be6e2 306
dreschpe 0:4bbc531be6e2 307 void C12832_LCD::line(int x0, int y0, int x1, int y1, int color)
dreschpe 0:4bbc531be6e2 308 {
dreschpe 0:4bbc531be6e2 309 int dx = 0, dy = 0;
dreschpe 0:4bbc531be6e2 310 int dx_sym = 0, dy_sym = 0;
dreschpe 0:4bbc531be6e2 311 int dx_x2 = 0, dy_x2 = 0;
dreschpe 0:4bbc531be6e2 312 int di = 0;
dreschpe 0:4bbc531be6e2 313
dreschpe 0:4bbc531be6e2 314 dx = x1-x0;
dreschpe 0:4bbc531be6e2 315 dy = y1-y0;
dreschpe 0:4bbc531be6e2 316
dreschpe 0:4bbc531be6e2 317 // if (dx == 0) { /* vertical line */
dreschpe 0:4bbc531be6e2 318 // if (y1 > y0) vline(x0,y0,y1,color);
dreschpe 0:4bbc531be6e2 319 // else vline(x0,y1,y0,color);
dreschpe 0:4bbc531be6e2 320 // return;
dreschpe 0:4bbc531be6e2 321 // }
dreschpe 0:4bbc531be6e2 322
dreschpe 0:4bbc531be6e2 323 if (dx > 0) {
dreschpe 0:4bbc531be6e2 324 dx_sym = 1;
dreschpe 0:4bbc531be6e2 325 } else {
dreschpe 0:4bbc531be6e2 326 dx_sym = -1;
dreschpe 0:4bbc531be6e2 327 }
dreschpe 0:4bbc531be6e2 328 // if (dy == 0) { /* horizontal line */
dreschpe 0:4bbc531be6e2 329 // if (x1 > x0) hline(x0,x1,y0,color);
dreschpe 0:4bbc531be6e2 330 // else hline(x1,x0,y0,color);
dreschpe 0:4bbc531be6e2 331 // return;
dreschpe 0:4bbc531be6e2 332 // }
dreschpe 0:4bbc531be6e2 333
dreschpe 0:4bbc531be6e2 334 if (dy > 0) {
dreschpe 0:4bbc531be6e2 335 dy_sym = 1;
dreschpe 0:4bbc531be6e2 336 } else {
dreschpe 0:4bbc531be6e2 337 dy_sym = -1;
dreschpe 0:4bbc531be6e2 338 }
dreschpe 0:4bbc531be6e2 339
dreschpe 0:4bbc531be6e2 340 dx = dx_sym*dx;
dreschpe 0:4bbc531be6e2 341 dy = dy_sym*dy;
dreschpe 0:4bbc531be6e2 342
dreschpe 0:4bbc531be6e2 343 dx_x2 = dx*2;
dreschpe 0:4bbc531be6e2 344 dy_x2 = dy*2;
dreschpe 0:4bbc531be6e2 345
dreschpe 0:4bbc531be6e2 346 if (dx >= dy) {
dreschpe 0:4bbc531be6e2 347 di = dy_x2 - dx;
dreschpe 0:4bbc531be6e2 348 while (x0 != x1) {
dreschpe 0:4bbc531be6e2 349
dreschpe 0:4bbc531be6e2 350 pixel(x0, y0, color);
dreschpe 0:4bbc531be6e2 351 x0 += dx_sym;
dreschpe 0:4bbc531be6e2 352 if (di<0) {
dreschpe 0:4bbc531be6e2 353 di += dy_x2;
dreschpe 0:4bbc531be6e2 354 } else {
dreschpe 0:4bbc531be6e2 355 di += dy_x2 - dx_x2;
dreschpe 0:4bbc531be6e2 356 y0 += dy_sym;
dreschpe 0:4bbc531be6e2 357 }
dreschpe 0:4bbc531be6e2 358 }
dreschpe 0:4bbc531be6e2 359 pixel(x0, y0, color);
dreschpe 0:4bbc531be6e2 360 } else {
dreschpe 0:4bbc531be6e2 361 di = dx_x2 - dy;
dreschpe 0:4bbc531be6e2 362 while (y0 != y1) {
dreschpe 0:4bbc531be6e2 363 pixel(x0, y0, color);
dreschpe 0:4bbc531be6e2 364 y0 += dy_sym;
dreschpe 0:4bbc531be6e2 365 if (di < 0) {
dreschpe 0:4bbc531be6e2 366 di += dx_x2;
dreschpe 0:4bbc531be6e2 367 } else {
dreschpe 0:4bbc531be6e2 368 di += dx_x2 - dy_x2;
dreschpe 0:4bbc531be6e2 369 x0 += dx_sym;
dreschpe 0:4bbc531be6e2 370 }
dreschpe 0:4bbc531be6e2 371 }
dreschpe 0:4bbc531be6e2 372 pixel(x0, y0, color);
dreschpe 0:4bbc531be6e2 373 }
dreschpe 0:4bbc531be6e2 374 return;
dreschpe 0:4bbc531be6e2 375 }
dreschpe 0:4bbc531be6e2 376
dreschpe 0:4bbc531be6e2 377 void C12832_LCD::rect(int x0, int y0, int x1, int y1, int color)
dreschpe 0:4bbc531be6e2 378 {
dreschpe 0:4bbc531be6e2 379
dreschpe 0:4bbc531be6e2 380 if (x1 > x0) line(x0,y0,x1,y0,color);
dreschpe 0:4bbc531be6e2 381 else line(x1,y0,x0,y0,color);
dreschpe 0:4bbc531be6e2 382
dreschpe 0:4bbc531be6e2 383 if (y1 > y0) line(x0,y0,x0,y1,color);
dreschpe 0:4bbc531be6e2 384 else line(x0,y1,x0,y0,color);
dreschpe 0:4bbc531be6e2 385
dreschpe 0:4bbc531be6e2 386 if (x1 > x0) line(x0,y1,x1,y1,color);
dreschpe 0:4bbc531be6e2 387 else line(x1,y1,x0,y1,color);
dreschpe 0:4bbc531be6e2 388
dreschpe 0:4bbc531be6e2 389 if (y1 > y0) line(x1,y0,x1,y1,color);
dreschpe 0:4bbc531be6e2 390 else line(x1,y1,x1,y0,color);
dreschpe 0:4bbc531be6e2 391
dreschpe 0:4bbc531be6e2 392 return;
dreschpe 0:4bbc531be6e2 393 }
dreschpe 0:4bbc531be6e2 394
dreschpe 0:4bbc531be6e2 395 void C12832_LCD::fillrect(int x0, int y0, int x1, int y1, int color)
dreschpe 0:4bbc531be6e2 396 {
dreschpe 0:4bbc531be6e2 397 int l,c,i;
dreschpe 0:4bbc531be6e2 398 if(x0 > x1) {
dreschpe 0:4bbc531be6e2 399 i = x0;
dreschpe 0:4bbc531be6e2 400 x0 = x1;
dreschpe 0:4bbc531be6e2 401 x1 = i;
dreschpe 0:4bbc531be6e2 402 }
dreschpe 0:4bbc531be6e2 403
dreschpe 0:4bbc531be6e2 404 if(y0 > y1) {
dreschpe 0:4bbc531be6e2 405 i = y0;
dreschpe 0:4bbc531be6e2 406 y0 = y1;
dreschpe 0:4bbc531be6e2 407 y1 = i;
dreschpe 0:4bbc531be6e2 408 }
dreschpe 0:4bbc531be6e2 409
dreschpe 0:4bbc531be6e2 410 for(l = x0; l<= x1; l ++) {
dreschpe 0:4bbc531be6e2 411 for(c = y0; c<= y1; c++) {
dreschpe 0:4bbc531be6e2 412 pixel(l,c,color);
dreschpe 0:4bbc531be6e2 413 }
dreschpe 0:4bbc531be6e2 414 }
dreschpe 0:4bbc531be6e2 415 }
dreschpe 0:4bbc531be6e2 416
dreschpe 0:4bbc531be6e2 417
dreschpe 0:4bbc531be6e2 418
dreschpe 0:4bbc531be6e2 419 void C12832_LCD::circle(int x0, int y0, int r, int color)
dreschpe 0:4bbc531be6e2 420 {
dreschpe 0:4bbc531be6e2 421
dreschpe 0:4bbc531be6e2 422 int draw_x0, draw_y0;
dreschpe 0:4bbc531be6e2 423 int draw_x1, draw_y1;
dreschpe 0:4bbc531be6e2 424 int draw_x2, draw_y2;
dreschpe 0:4bbc531be6e2 425 int draw_x3, draw_y3;
dreschpe 0:4bbc531be6e2 426 int draw_x4, draw_y4;
dreschpe 0:4bbc531be6e2 427 int draw_x5, draw_y5;
dreschpe 0:4bbc531be6e2 428 int draw_x6, draw_y6;
dreschpe 0:4bbc531be6e2 429 int draw_x7, draw_y7;
dreschpe 0:4bbc531be6e2 430 int xx, yy;
dreschpe 0:4bbc531be6e2 431 int di;
dreschpe 0:4bbc531be6e2 432 //WindowMax();
dreschpe 0:4bbc531be6e2 433 if (r == 0) { /* no radius */
dreschpe 0:4bbc531be6e2 434 return;
dreschpe 0:4bbc531be6e2 435 }
dreschpe 0:4bbc531be6e2 436
dreschpe 0:4bbc531be6e2 437 draw_x0 = draw_x1 = x0;
dreschpe 0:4bbc531be6e2 438 draw_y0 = draw_y1 = y0 + r;
dreschpe 0:4bbc531be6e2 439 if (draw_y0 < height()) {
dreschpe 0:4bbc531be6e2 440 pixel(draw_x0, draw_y0, color); /* 90 degree */
dreschpe 0:4bbc531be6e2 441 }
dreschpe 0:4bbc531be6e2 442
dreschpe 0:4bbc531be6e2 443 draw_x2 = draw_x3 = x0;
dreschpe 0:4bbc531be6e2 444 draw_y2 = draw_y3 = y0 - r;
dreschpe 0:4bbc531be6e2 445 if (draw_y2 >= 0) {
dreschpe 0:4bbc531be6e2 446 pixel(draw_x2, draw_y2, color); /* 270 degree */
dreschpe 0:4bbc531be6e2 447 }
dreschpe 0:4bbc531be6e2 448
dreschpe 0:4bbc531be6e2 449 draw_x4 = draw_x6 = x0 + r;
dreschpe 0:4bbc531be6e2 450 draw_y4 = draw_y6 = y0;
dreschpe 0:4bbc531be6e2 451 if (draw_x4 < width()) {
dreschpe 0:4bbc531be6e2 452 pixel(draw_x4, draw_y4, color); /* 0 degree */
dreschpe 0:4bbc531be6e2 453 }
dreschpe 0:4bbc531be6e2 454
dreschpe 0:4bbc531be6e2 455 draw_x5 = draw_x7 = x0 - r;
dreschpe 0:4bbc531be6e2 456 draw_y5 = draw_y7 = y0;
dreschpe 0:4bbc531be6e2 457 if (draw_x5>=0) {
dreschpe 0:4bbc531be6e2 458 pixel(draw_x5, draw_y5, color); /* 180 degree */
dreschpe 0:4bbc531be6e2 459 }
dreschpe 0:4bbc531be6e2 460
dreschpe 0:4bbc531be6e2 461 if (r == 1) {
dreschpe 0:4bbc531be6e2 462 return;
dreschpe 0:4bbc531be6e2 463 }
dreschpe 0:4bbc531be6e2 464
dreschpe 0:4bbc531be6e2 465 di = 3 - 2*r;
dreschpe 0:4bbc531be6e2 466 xx = 0;
dreschpe 0:4bbc531be6e2 467 yy = r;
dreschpe 0:4bbc531be6e2 468 while (xx < yy) {
dreschpe 0:4bbc531be6e2 469
dreschpe 0:4bbc531be6e2 470 if (di < 0) {
dreschpe 0:4bbc531be6e2 471 di += 4*xx + 6;
dreschpe 0:4bbc531be6e2 472 } else {
dreschpe 0:4bbc531be6e2 473 di += 4*(xx - yy) + 10;
dreschpe 0:4bbc531be6e2 474 yy--;
dreschpe 0:4bbc531be6e2 475 draw_y0--;
dreschpe 0:4bbc531be6e2 476 draw_y1--;
dreschpe 0:4bbc531be6e2 477 draw_y2++;
dreschpe 0:4bbc531be6e2 478 draw_y3++;
dreschpe 0:4bbc531be6e2 479 draw_x4--;
dreschpe 0:4bbc531be6e2 480 draw_x5++;
dreschpe 0:4bbc531be6e2 481 draw_x6--;
dreschpe 0:4bbc531be6e2 482 draw_x7++;
dreschpe 0:4bbc531be6e2 483 }
dreschpe 0:4bbc531be6e2 484 xx++;
dreschpe 0:4bbc531be6e2 485 draw_x0++;
dreschpe 0:4bbc531be6e2 486 draw_x1--;
dreschpe 0:4bbc531be6e2 487 draw_x2++;
dreschpe 0:4bbc531be6e2 488 draw_x3--;
dreschpe 0:4bbc531be6e2 489 draw_y4++;
dreschpe 0:4bbc531be6e2 490 draw_y5++;
dreschpe 0:4bbc531be6e2 491 draw_y6--;
dreschpe 0:4bbc531be6e2 492 draw_y7--;
dreschpe 0:4bbc531be6e2 493
dreschpe 0:4bbc531be6e2 494 if ( (draw_x0 <= width()) && (draw_y0>=0) ) {
dreschpe 0:4bbc531be6e2 495 pixel(draw_x0, draw_y0, color);
dreschpe 0:4bbc531be6e2 496 }
dreschpe 0:4bbc531be6e2 497
dreschpe 0:4bbc531be6e2 498 if ( (draw_x1 >= 0) && (draw_y1 >= 0) ) {
dreschpe 0:4bbc531be6e2 499 pixel(draw_x1, draw_y1, color);
dreschpe 0:4bbc531be6e2 500 }
dreschpe 0:4bbc531be6e2 501
dreschpe 0:4bbc531be6e2 502 if ( (draw_x2 <= width()) && (draw_y2 <= height()) ) {
dreschpe 0:4bbc531be6e2 503 pixel(draw_x2, draw_y2, color);
dreschpe 0:4bbc531be6e2 504 }
dreschpe 0:4bbc531be6e2 505
dreschpe 0:4bbc531be6e2 506 if ( (draw_x3 >=0 ) && (draw_y3 <= height()) ) {
dreschpe 0:4bbc531be6e2 507 pixel(draw_x3, draw_y3, color);
dreschpe 0:4bbc531be6e2 508 }
dreschpe 0:4bbc531be6e2 509
dreschpe 0:4bbc531be6e2 510 if ( (draw_x4 <= width()) && (draw_y4 >= 0) ) {
dreschpe 0:4bbc531be6e2 511 pixel(draw_x4, draw_y4, color);
dreschpe 0:4bbc531be6e2 512 }
dreschpe 0:4bbc531be6e2 513
dreschpe 0:4bbc531be6e2 514 if ( (draw_x5 >= 0) && (draw_y5 >= 0) ) {
dreschpe 0:4bbc531be6e2 515 pixel(draw_x5, draw_y5, color);
dreschpe 0:4bbc531be6e2 516 }
dreschpe 0:4bbc531be6e2 517 if ( (draw_x6 <=width()) && (draw_y6 <= height()) ) {
dreschpe 0:4bbc531be6e2 518 pixel(draw_x6, draw_y6, color);
dreschpe 0:4bbc531be6e2 519 }
dreschpe 0:4bbc531be6e2 520 if ( (draw_x7 >= 0) && (draw_y7 <= height()) ) {
dreschpe 0:4bbc531be6e2 521 pixel(draw_x7, draw_y7, color);
dreschpe 0:4bbc531be6e2 522 }
dreschpe 0:4bbc531be6e2 523 }
dreschpe 0:4bbc531be6e2 524 return;
dreschpe 0:4bbc531be6e2 525 }
dreschpe 0:4bbc531be6e2 526
dreschpe 0:4bbc531be6e2 527 void C12832_LCD::fillcircle(int x, int y, int r, int color)
dreschpe 0:4bbc531be6e2 528 {
dreschpe 0:4bbc531be6e2 529 int i;
dreschpe 0:4bbc531be6e2 530 for (i = 0; i <= r; i++)
dreschpe 0:4bbc531be6e2 531 circle(x,y,i,color);
dreschpe 0:4bbc531be6e2 532 }
dreschpe 0:4bbc531be6e2 533
dreschpe 0:4bbc531be6e2 534 void C12832_LCD::setmode(int mode)
dreschpe 0:4bbc531be6e2 535 {
dreschpe 0:4bbc531be6e2 536 draw_mode = mode;
dreschpe 0:4bbc531be6e2 537 }
dreschpe 0:4bbc531be6e2 538
dreschpe 0:4bbc531be6e2 539 void C12832_LCD::locate(int x, int y)
dreschpe 0:4bbc531be6e2 540 {
dreschpe 0:4bbc531be6e2 541 char_x = x;
dreschpe 0:4bbc531be6e2 542 char_y = y;
dreschpe 0:4bbc531be6e2 543 }
dreschpe 0:4bbc531be6e2 544
dreschpe 0:4bbc531be6e2 545
dreschpe 0:4bbc531be6e2 546
dreschpe 0:4bbc531be6e2 547 int C12832_LCD::columns()
dreschpe 0:4bbc531be6e2 548 {
dreschpe 0:4bbc531be6e2 549 return width() / font[1];
dreschpe 0:4bbc531be6e2 550 }
dreschpe 0:4bbc531be6e2 551
dreschpe 0:4bbc531be6e2 552
dreschpe 0:4bbc531be6e2 553
dreschpe 0:4bbc531be6e2 554 int C12832_LCD::rows()
dreschpe 0:4bbc531be6e2 555 {
dreschpe 0:4bbc531be6e2 556 return height() / font[2];
dreschpe 0:4bbc531be6e2 557 }
dreschpe 0:4bbc531be6e2 558
dreschpe 0:4bbc531be6e2 559
dreschpe 0:4bbc531be6e2 560
dreschpe 0:4bbc531be6e2 561 int C12832_LCD::_putc(int value)
dreschpe 0:4bbc531be6e2 562 {
dreschpe 0:4bbc531be6e2 563 if (value == '\n') { // new line
dreschpe 0:4bbc531be6e2 564 char_x = 0;
dreschpe 0:4bbc531be6e2 565 char_y = char_y + font[2];
dreschpe 0:4bbc531be6e2 566 if (char_y >= height() - font[2]) {
dreschpe 0:4bbc531be6e2 567 char_y = 0;
dreschpe 0:4bbc531be6e2 568 }
dreschpe 0:4bbc531be6e2 569 } else {
dreschpe 0:4bbc531be6e2 570 character(char_x, char_y, value);
dreschpe 0:4bbc531be6e2 571 }
dreschpe 0:4bbc531be6e2 572 return value;
dreschpe 0:4bbc531be6e2 573 }
dreschpe 0:4bbc531be6e2 574
dreschpe 0:4bbc531be6e2 575 void C12832_LCD::character(int x, int y, int c)
dreschpe 0:4bbc531be6e2 576 {
dreschpe 0:4bbc531be6e2 577 unsigned int hor,vert,offset,bpl,j,i,b;
dreschpe 0:4bbc531be6e2 578 unsigned char* zeichen;
dreschpe 0:4bbc531be6e2 579 unsigned char z,w;
dreschpe 0:4bbc531be6e2 580
dreschpe 0:4bbc531be6e2 581 if ((c < 31) || (c > 127)) return; // test char range
dreschpe 0:4bbc531be6e2 582
dreschpe 0:4bbc531be6e2 583 // read font parameter from start of array
dreschpe 0:4bbc531be6e2 584 offset = font[0]; // bytes / char
dreschpe 0:4bbc531be6e2 585 hor = font[1]; // get hor size of font
dreschpe 0:4bbc531be6e2 586 vert = font[2]; // get vert size of font
dreschpe 0:4bbc531be6e2 587 bpl = font[3]; // bytes per line
dreschpe 0:4bbc531be6e2 588
dreschpe 0:4bbc531be6e2 589 if (char_x + hor > width()) {
dreschpe 0:4bbc531be6e2 590 char_x = 0;
dreschpe 0:4bbc531be6e2 591 char_y = char_y + vert;
dreschpe 0:4bbc531be6e2 592 if (char_y >= height() - font[2]) {
dreschpe 0:4bbc531be6e2 593 char_y = 0;
dreschpe 0:4bbc531be6e2 594 }
dreschpe 0:4bbc531be6e2 595 }
dreschpe 0:4bbc531be6e2 596
dreschpe 0:4bbc531be6e2 597 zeichen = &font[((c -32) * offset) + 4]; // start of char bitmap
dreschpe 0:4bbc531be6e2 598 w = zeichen[0]; // width of actual char
dreschpe 0:4bbc531be6e2 599 // construct the char into the buffer
dreschpe 0:4bbc531be6e2 600 for (j=0; j<vert; j++) { // vert line
dreschpe 0:4bbc531be6e2 601 for (i=0; i<hor; i++) { // horz line
dreschpe 0:4bbc531be6e2 602 z = zeichen[bpl * i + ((j & 0xF8) >> 3)+1];
dreschpe 0:4bbc531be6e2 603 b = 1 << (j & 0x07);
dreschpe 0:4bbc531be6e2 604 if (( z & b ) == 0x00) {
dreschpe 0:4bbc531be6e2 605 pixel(x+i,y+j,0);
dreschpe 0:4bbc531be6e2 606 } else {
dreschpe 0:4bbc531be6e2 607 pixel(x+i,y+j,1);
dreschpe 0:4bbc531be6e2 608 }
dreschpe 0:4bbc531be6e2 609
dreschpe 0:4bbc531be6e2 610 }
dreschpe 0:4bbc531be6e2 611 }
dreschpe 0:4bbc531be6e2 612
dreschpe 0:4bbc531be6e2 613 char_x += w;
dreschpe 0:4bbc531be6e2 614 }
dreschpe 0:4bbc531be6e2 615
dreschpe 0:4bbc531be6e2 616
dreschpe 0:4bbc531be6e2 617 void C12832_LCD::set_font(unsigned char* f)
dreschpe 0:4bbc531be6e2 618 {
dreschpe 0:4bbc531be6e2 619 font = f;
dreschpe 0:4bbc531be6e2 620 }
dreschpe 0:4bbc531be6e2 621
dreschpe 0:4bbc531be6e2 622
dreschpe 0:4bbc531be6e2 623