Newhaven 320x240 LCD

Dependencies:   mbed

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;
 }