Paul Evans
/
Newhaven_LCD
Newhaven 320x240 LCD
Diff: newhaven.cpp
- Revision:
- 4:aa6dc362b462
- Parent:
- 3:1cf3ec6c70d7
--- a/newhaven.cpp Sun Feb 27 23:30:14 2011 +0000 +++ b/newhaven.cpp Mon Feb 28 17:48:12 2011 +0000 @@ -21,6 +21,12 @@ while(i--); } +void swap(int* a, int* b){ + int temp = *a; + *a = *b; + *b = temp; +} + // send commands to the LCD void NHLCD::comm_out(unsigned char j){ LCD_PORT->output(); // sets the buffer to output data @@ -29,7 +35,7 @@ CS = 0; // active LOW chip select RW = 0; // set to 0 for write operation E = 1; // operation enable - delay(1); // wait for operation to complete + //delay(1); // wait for operation to complete E = 0; // reset values RW = 1; CS = 1; @@ -43,7 +49,7 @@ CS = 0; // active LOW chip select RW = 0; // set to 0 for write operation E = 1; // operation enable - delay(1); // wait for operation to complete + //delay(1); // wait for operation to complete E = 0; // reset values RW = 1; CS = 1; @@ -84,31 +90,59 @@ /* set an individual pixel on the screen. * pixels are grouped in bytes, so you must isolate a particular pixel. */ -void NHLCD::setPixel(int row, int col){ - int loc = (0x04<<8)|(0xB0); //sets location to the top left corner of drawing screen - int c = loc+row*40+(col/8); // gets address of the correct byte - comm_out(0x46); // command to set cursor location - data_out((unsigned char)(c&0xFF)); // lower 8 bits of address - data_out((unsigned char)((c&0xFF00)>>8)); // upper 8 bits of address - comm_out(0x43); // command to read the byte - LCD_PORT->input(); // sets the buffer to input data - unsigned char buffer = LCD_PORT->read(); // stores byte in buffer - buffer = buffer|(1<<(7-((row*320+col)%8))); // sets the particular pixel on the byte - LCD_PORT->output(); // sets the buffer to output data - - comm_out(0x46); //command to set cursor location - data_out((unsigned char)(c&0xFF)); // lower 8 bits of address - data_out((unsigned char)((c&0xFF00)>>8)); // upper 8 bits of address - comm_out(0x42); // command to write to the screen - data_out(buffer); // write buffer to the screen +void NHLCD::setPixel(int row, int col, int color){ + int c = row*40+(col/8); // get location in buffer + char x = 1<<(7-(col%8)); // sets the bit to alter + if (color) // to mark the bit + screenBuffer[c] |= x; // marks the bit + else // to clear the bit + screenBuffer[c] &= ~x; // clears the bit + LCD_PORT->output(); // sets the buffer to output data + int loc = c+0x4B0; // get location on drawing screen + comm_out(0x46); // command to set cursor location + data_out((unsigned char)(loc&0xFF)); // lower 8 bits of address + data_out((unsigned char)((loc&0xFF00)>>8)); // upper 8 bits of address + comm_out(0x42); // command to write data + data_out(screenBuffer[c]); // write byte to the screen +} + +// draw a line -- Bresenham's line algorithm +void NHLCD::drawLine(int r1, int c1, int r2, int c2, int color){ + int w = r2 - r1; // calculate width of line + int h = c2 - c1; // calculate height of line + double ratio; + int x, y; + int upright = 0; // assumes the line is "wide" + if (abs(h) > abs(w)) { // checks if height is greater than width + upright = 1; // if it is, the line is "tall" + swap(&c1, &r1); // mirrors coordinates over the line y=x to make it "wide" + swap(&c2, &r2); + swap(&w, &h); + } + if (r1 > r2) { // if the first row is on the right, swaps start and end coordinates + swap(&c1, &c2); // now the line is always drawn from "bottom-left" to "top-right" + swap(&r1, &r2); + } + ratio = ((double) h) / w; // calculates ratio of height to width + for (x = r1; x < r2; x++) { // iterates through the rows + y = c1 + (x - r1) * ratio; // calculates the height at this particular row + if (upright) setPixel(y, x, color); // depending on if the line is "wide" or "tall", you have to + else setPixel(x, y, color); // call setPixel differently + } +} + +// draw and fill a rectangle +void NHLCD::fillRect(int row, int col, int height, int width, int color){ + for (int r = 0; r < height; r++) // iterate through each row + for (int c = 0; c < width; c++) // iterate through each column + setPixel(row+r,col+c,color); // set each pixel in the rectangle } // initialize the LCD void NHLCD::Init(void){ - /* reset the device */ - RST = 0; + RST = 0; // resets the device delay(5); - RST = 1; + RST = 1; // restarts it delay(10); comm_out(0x40); // system set command @@ -117,7 +151,7 @@ data_out(0x87); // horizontal character size (0x80 = 1) MUST BE MULTIPLE OF 320 data_out(0x07); // vertical character size (0x00 = 1) MUST BE MULTIPLE OF 240 data_out(40); // addresses per line - data_out(80); // bytes per line + data_out(80); // words per line data_out(0xEF); // 240 displace lines data_out(0x28); // virtual address 1 data_out(0x00); // virtual address 2 @@ -151,5 +185,7 @@ comm_out(0x59); // disp on/off data_out(0x16); // on - wait_ms(5); + + for(int i = 0; i < 40*240; i++) + screenBuffer[i] = 0; }