Renesas GR-Peach LCD Interface

Dependencies:   EthernetInterface HTTPD PubNub SDFileSystem mbed-rtos mbed picojson

Renesas GR-Peach LCD Interface

Revision:
0:0b32d3eaabfe
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lcd_main.cpp	Fri Oct 23 20:16:05 2015 +0000
@@ -0,0 +1,647 @@
+#include "gen_helper.h"
+#include "math.h"
+
+
+/* An SPI Master for interfacing and handling an LCD Slave with GR-Peach */
+
+
+/* Variables for holding previously drawn co-ordinate values */
+int x_left = 0; //holder for the last updated x co-ordinate value for the left side
+int y_left = 0; //holder for the last updated y co-ordinate value for the left side
+int x_right = 0; //holder for the last updated x co-ordinate value for the right side
+int y_right = 0; //holder for the last updated y co-ordinate value for the right side
+
+//The number of the levels for the tree.
+//This is declared here for ease of change in any function and reset it to
+//the original value after use.
+int number_levels = 0;
+
+gen_helper::gen_helper(PinName MOSI, PinName MISO, PinName SCK, PinName CS, PinName Reset, PinName RS, PinName _USBTX, PinName _USBRX, PwmOut _pwm) : 
+            lcd(MOSI, MISO, SCK), ssel(CS), reset(Reset), rs(RS), console(_USBTX, _USBRX), pwm(_pwm)
+{
+    _height = SCREEN_HEIGHT;
+    _width = SCREEN_WIDTH;
+}
+
+
+/* Init console by setting the baud rate */
+
+void gen_helper::init_console()
+{
+    //init serial over USB here
+    console.baud(115200);
+    console.printf("Console init done\n");
+}
+
+/**
+ * Draws a line by a factor of lambda value
+ *(x0,y0) are initial co-ordinates and (x1,y1) are the end co-ordinates
+
+ * x0 - starting x co-ordinate value
+ * y0 - starting y co-ordinate value
+ * x1 - end x co-ordinate value
+ * y1 - end y co-ordinate value
+ * lambda - the factor that decides the length of the resulting line segment
+ */
+void gen_helper::massaged_line(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, float lambda, uint16_t colour, uint16_t *X, uint16_t *Y)
+{
+    *X = (uint16_t)(x0 + (lambda * (x1 - x0)));
+    *Y = (uint16_t)(y0 + (lambda * (y1 - y0)));
+}
+
+
+/**
+ * rotate (x2,y2) around (x1,y1) by alpha degrees
+ * combines rotation and translation also.
+
+ * x1 - starting x co-ordinate
+ * y1 - starting y co-ordinate
+ * x2 - end x co-ordinate
+ * y2 - end y co-ordinate
+ * alpha - the degree of rotation required
+ */
+void gen_helper::rotate_line(float x1, float y1, float x2, float y2, uint16_t alpha, float *X, float *Y)
+{
+    float radian = (3.1415 * alpha / 180);
+    *X = (x2 - x1) * cosf(radian) - (y2 - y1) * sinf(radian) + x1;
+    *Y = (y2 - y1) * cosf(radian) + (x2 - x1) * sinf(radian) + y1;
+}
+
+
+/**
+ * Draw a line with the init and end co-ordinates
+ * (x0, y0) - start co-ordinates
+ * (x1, y1) - end co-ordinates
+ * color - color of the line
+ * Based on the ST7735 source
+*/
+void gen_helper::drawLine(int16_t x0, int16_t y0,int16_t x1, int16_t y1,uint16_t color)
+{
+    int16_t x, y;
+    float slope;
+    
+    //check for slope conditions
+    if( (x0 != x1) && (y0 != y1) ) 
+    {
+        slope = (y1 - y0) / (x1 - x0);
+        
+        if (abs(slope) < 1) 
+        {
+            for(x = x0; x < x1 + 1; x++) 
+            {
+                y = (x - x0) * slope + y0;
+                draw_pixel(x, (y + 0.5), color);
+            }
+        } 
+        else 
+        {
+            for(y = y0; y < y1 + 1; y++) 
+            {
+                x = (y - y0) / slope + x0;
+                draw_pixel((x + 0.5), y, color);
+            }
+        }
+    }
+}
+
+/**
+ * A helper function which is flexible enough to be
+ * given any pattern to be drawn on the LCD
+ * initial values are (20,0) and (20,20) and the number of levels in 7
+ */
+void gen_helper::draw_pattern_helper()
+{
+    int first_x0 = 20;
+    int first_y0 = 0;
+    int first_x1 = 20;
+    int first_y1 = 20;
+    //set the number of levels of the tree to 7
+    number_levels = 7;
+
+    //Draw the first tree
+    draw_custom_pattern(first_x0, first_y0, first_x1, first_y1);
+
+
+    //The second tree in the same plane
+    int next_tree_index = first_x0 + 30;
+    first_x0 = next_tree_index;
+    first_x1 = first_x0;
+
+    draw_custom_pattern(first_x0, first_y0, first_x1, first_y1);
+
+    //Third tree
+    next_tree_index += 30;
+    first_x0 = next_tree_index;
+    first_x1 = first_x0;
+    draw_custom_pattern(first_x0, first_y0, first_x1, first_y1);
+
+    //Fourth tree
+    next_tree_index += 30;
+    first_x0 = next_tree_index;
+    first_x1 = first_x0;
+    draw_custom_pattern(first_x0, first_y0, first_x1, first_y1);
+
+    //Fifth tree which starts at a much higher level than the previous trees
+    next_tree_index = 35;
+    first_x0 = next_tree_index;
+    first_x1 = first_x0;
+    first_y0+=20;
+    first_y1+=20;
+    draw_custom_pattern(first_x0, first_y0, first_x1, first_y1);
+
+    //Sixth tree that is at the same level as fifth
+    next_tree_index = 65;
+    first_x0 = next_tree_index;
+    first_x1 = first_x0;
+    draw_custom_pattern(first_x0, first_y0, first_x1, first_y1);
+
+    //Seventh tree that is at the same level as sixth
+    next_tree_index = 95;
+    first_x0 = next_tree_index;
+    first_x1 = first_x0;
+    draw_custom_pattern(first_x0, first_y0, first_x1, first_y1);
+
+
+    //Eighth tree at the same level as seventh
+    next_tree_index = 20;
+    first_x0 = next_tree_index;
+    first_x1 = first_x0;
+    first_y0 = 90;
+    first_y1 = first_y0 + 20;
+    number_levels = 3;
+    draw_custom_pattern(first_x0, first_y0, first_x1, first_y1);
+
+    //Ninth tree at the same level as eight but with only 3 levels
+    next_tree_index = 50;
+    first_x0 = next_tree_index;
+    first_x1 = first_x0;
+    first_y0 = 90;
+    first_y1 = first_y0 + 20;
+    number_levels = 3;
+    draw_custom_pattern(first_x0, first_y0, first_x1, first_y1);
+
+    //Tenth tree at the same level as ninth but with only 3 levels
+    next_tree_index = 80;
+    first_x0 = next_tree_index;
+    first_x1 = first_x0;
+    first_y0 = 90;
+    first_y1 = first_y0 + 20;
+    number_levels = 3;
+    draw_custom_pattern(first_x0, first_y0, first_x1, first_y1);
+
+    //Eleventh tree at the same level as tenth but with only 3 levels
+    next_tree_index = 110;
+    first_x0 = next_tree_index;
+    first_x1 = first_x0;
+    first_y0 = 90;
+    first_y1 = first_y0 + 20;
+    number_levels = 3;
+    draw_custom_pattern(first_x0, first_y0, first_x1, first_y1);
+
+}
+
+
+/**
+ * Draw the forest in any pattern that is desired with
+ * given two sets of start and end points
+ 
+ * x0 - starting x co-ordinate value
+ * y0 - starting y co-ordinate value
+ * x1 - end x co-ordinate value
+ * y1 - end y co-ordinate value
+ *
+ */
+void gen_helper::draw_custom_pattern(int x0, int y0, int x1, int y1)
+{
+    int first_x0 = x0;
+    int first_y0 = y0;
+    int first_x1 = x1;
+    int first_y1 = y1;
+    int temp_leftx = 0;
+    int temp_lefty = 0;
+    int temp_rightx = 0;
+    int temp_righty = 0;
+    int r_temp_leftx = 0;
+    int r_temp_lefty = 0;
+    int r_temp_rightx = 0;
+    int r_temp_righty = 0;
+
+    //draw the initial trunk of the tree and the next vertical branch that is
+    //a shrunken version of the trunk
+    drawLine(first_x0, first_y0, first_x1, first_y0+10, BLACK);
+    drawLine(first_x0+1, first_y0, first_x1+1, first_y0+10, BLACK);
+    draw_pattern(first_x0, first_y0+10, first_x1, first_y1+10);
+
+
+    //The pattern for drawing the tree and hence the forest.
+    //This can be any pattern required.
+    temp_leftx = x_left;
+    temp_lefty = y_left;
+    temp_rightx = x_right;
+    temp_righty = y_right;
+
+    r_temp_leftx = x_left;
+    r_temp_lefty = y_left;
+    r_temp_rightx = x_right;
+    r_temp_righty = y_right;
+
+
+    int i = 0;
+    for(i = 0; i < number_levels; i++)
+    {
+        draw_pattern(r_temp_leftx, r_temp_lefty, r_temp_leftx, r_temp_lefty+10);
+        draw_pattern(r_temp_rightx, r_temp_righty, r_temp_rightx, r_temp_righty+10);
+        r_temp_leftx = x_left;
+        r_temp_lefty = y_left;
+        r_temp_rightx = x_right;
+        r_temp_righty = y_right;
+    }
+
+    i = 0;
+    for(i = 0; i < number_levels; i++)
+    {
+        draw_pattern(temp_rightx, temp_righty, temp_rightx, temp_righty+10);
+        draw_pattern(temp_leftx, temp_lefty, temp_leftx, temp_lefty+10);
+        temp_leftx = x_left;
+        temp_lefty = y_left;
+        temp_rightx = x_right;
+        temp_righty = y_right;
+    }
+
+}
+
+
+/**
+ *
+ * x1 - starting x co-ordinate value
+ * y1 - starting y co-ordinate value
+ * x2 - end x co-ordinate value
+ * y2 - end y co-ordinate value
+ */
+void gen_helper::draw_pattern(int x1, int y1, int x2, int y2)
+{
+
+    int first_x0 = x1;
+    int first_y0 = y1;
+    int first_x1 = x2;
+    int first_y1 = y2;
+    int alpha = 30;
+    int neg_alpha = -30;
+
+
+    float x0=0, y0=0;
+
+    rotate_line(first_x0, first_y0, first_x1, first_y1, alpha, &x0, &y0);
+
+    drawLine(first_x0, first_y0, (int)x0, (int)y0, GREEN);
+
+    x_right = (int)x0;
+    y_right = (int)y0;
+
+    x0 = 0;
+    y0 = 0;
+
+    rotate_line(first_x0, first_y0, first_x1, first_y1, neg_alpha, &x0, &y0);
+    drawLine(first_x0, first_y0, (int)(x0+3), (int)y0, GREEN);
+
+    x_left = (int)x0+3;
+    y_left = (int)y0;
+
+
+}
+
+/********* SD card helper functions; wrappers over the SD card file system ********/
+uint8_t gen_helper::init_disk()
+{
+    return sd_fs->disk_initialize();
+}
+
+/**
+* Initialize the SD card
+*/
+uint8_t gen_helper::init_SD()
+{
+    sd_fs = new SDFileSystem(P8_5, P8_6, P8_3, P8_4, "sd");
+    
+    if(sd_fs)
+        return (uint8_t)0; //force a casting
+    else
+        return (uint8_t)-1;
+}
+
+/**
+* Open a file and return the file descriptor
+*/
+FILE* gen_helper::open_file(char *path, char *mode)
+{
+    return fopen(path, mode);
+}
+
+uint8_t gen_helper::close_file(FILE *fp)
+{
+    return fclose(fp);
+}
+
+uint8_t gen_helper::make_dir(char *path, uint32_t mode)
+{
+    return mkdir(path, mode);
+}
+
+uint8_t gen_helper::remove_file(char *path)
+{
+    return remove(path);
+}
+/****SD card function implementations end****/
+
+
+/* Initialize the LCD 
+* 
+*TODO : Check the row select and col select for Renesas GR-PEACH 
+*
+* Based on the specs from ST7735
+*/
+void gen_helper::lcd_init()
+{
+    console.printf("Writing to the lcd \n");
+ 
+    lcd.format(8, 3);
+    //lcd.frequency(15000000);
+    ssel = 0;
+    reset = 1;
+    wait_ms(500);
+    reset = 0;
+    wait_ms(500);
+    reset = 1;
+    wait_ms(500);
+    
+    write_spi_command(SW_RESET);                         // SW Reset                       
+    wait_ms(150);
+    write_spi_command(AWAKE_SLEEPMODE);                         // Out of sleepmode               
+    wait_ms(500);
+    
+    write_spi_command(FRAMERATE_NORMAL);                         // Frame rate in normal mode
+    write_spi_data(0x01);                              
+    write_spi_data(0x2C);
+    write_spi_data(0x2D);
+    
+    write_spi_command(FRAMERATE_IDLE);                         // Frame rate in idle mode
+    write_spi_data(0x01);                              
+    write_spi_data(0x2C);
+    write_spi_data(0x2D);
+
+    write_spi_command(FRAMERATE_PARTIAL);                         // Frame rate in partial mode
+    write_spi_data(0x01);                              
+    write_spi_data(0x2C);
+    write_spi_data(0x2D);
+    write_spi_data(0x01);   // inversion mode settings                              
+    write_spi_data(0x2C);
+    write_spi_data(0x2D);
+    
+    write_spi_command(INVERTED_MODE_OFF);   // Inverted mode off
+    write_spi_data(0x07);   
+
+    write_spi_command(POWER_CONTROL_1);
+    write_spi_data(0xA2); 
+    write_spi_data(0x02);  
+    write_spi_data(0x84);  
+    
+    write_spi_command(POWER_CONTROL_2);   // POWER CONTROL 2   
+    write_spi_data(0xC5);            
+    
+    write_spi_command(POWER_CONTROL_3);  // POWER CONTROL 3   
+    write_spi_data(0x0A);           
+    write_spi_data(0x00);           
+
+    write_spi_command(POWER_CONTROL_4);   // POWER CONTROL 4   
+    write_spi_data(0x8A);           
+    write_spi_data(0x2A);   
+  
+    write_spi_command(POWER_CONTROL_5);   // POWER CONTROL 5   
+    write_spi_data(0x8A);           
+    write_spi_data(0xEE);   
+    
+    write_spi_command(POWER_CONTROL_6);   // POWER CONTROL 6   
+    write_spi_data(0x0E);   
+
+    write_spi_command(INVOFF);   
+    
+    write_spi_command(ORIENTATION);   // ORIENTATION   
+    write_spi_data(0xC8);   
+    
+    write_spi_command(COLOR_MODE);
+    write_spi_data(0x05);   
+    
+    write_spi_command(COLUMN_ADDR_SET);
+    write_spi_data(0x00);   
+    write_spi_data(0x00);  
+    write_spi_data(0x00);   
+    write_spi_data(0x7F);   
+    
+    write_spi_command(ROW_ADDR_SET);   // ROW ADDR SET   
+    write_spi_data(0x00); 
+    write_spi_data(0x00);
+    write_spi_data(0x00); 
+    write_spi_data(0x9F);
+
+
+    write_spi_command(0xE0);
+    write_spi_data(0x02);
+    write_spi_data(0x1c);
+    write_spi_data(0x07);
+    write_spi_data(0x12);
+    write_spi_data(0x37);
+    write_spi_data(0x32);
+    write_spi_data(0x29);
+    write_spi_data(0x2d);
+    write_spi_data(0x29);
+    write_spi_data(0x25);
+    write_spi_data(0x2B);
+    write_spi_data(0x39);
+    write_spi_data(0x00);
+    write_spi_data(0x01);
+    write_spi_data(0x03);
+    write_spi_data(0x10);
+    write_spi_command(0xE1);
+    write_spi_data(0x03);
+    write_spi_data(0x1d);
+    write_spi_data(0x07);
+    write_spi_data(0x06);
+    write_spi_data(0x2E);
+    write_spi_data(0x2C);
+    write_spi_data(0x29);
+    write_spi_data(0x2D);
+    write_spi_data(0x2E);
+    write_spi_data(0x2E);
+    write_spi_data(0x37);
+    write_spi_data(0x3F);
+    write_spi_data(0x00);
+    write_spi_data(0x00);
+    write_spi_data(0x02);
+    write_spi_data(0x10);
+
+    write_spi_command(DISPLAY_ON); // display ON
+    wait_ms(100);
+
+    write_spi_command(NORMAL_DISP_ON);  // normal display on
+    wait_ms(10);
+
+    pwm.period_ms(2);
+
+    // just increasing the brightness of the screen gradually
+    for(float i = 0.0f; i < 1.0f; i += 0.1f) 
+    {
+        wait_ms(200);
+        pwm = i;
+    }
+
+    console.printf("PWM done\n"); // here for debugging
+
+}
+
+inline int gen_helper::spiwrite(uint8_t c) 
+{
+    return lcd.write(c);
+    
+}
+
+/* Write command */
+void gen_helper::write_spi_command(uint8_t c) 
+{
+
+    rs = 0;
+    ssel = 0;
+    lcd.write(c);
+    ssel = 1;
+}
+
+/* Write data */
+void gen_helper::write_spi_data(uint8_t c) 
+{
+
+    rs = 1;
+    ssel = 0;    
+    lcd.write(c);
+    ssel = 1;
+
+} 
+
+/**
+ * Based on ST7735 source ; sets the screen co-ordinates
+*/
+void gen_helper::set_screen_coor(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1) 
+{
+
+  write_spi_command(COLUMN_ADDR_SET); // Column addr set
+  write_spi_data(0x00);
+  write_spi_data(x0+colstart);     // XSTART 
+  write_spi_data(0x00);
+  write_spi_data(x1+colstart);     // XEND
+
+  write_spi_command(ROW_ADDR_SET); // Row addr set
+  write_spi_data(0x00);
+  write_spi_data(y0+rowstart);     // YSTART
+  write_spi_data(0x00);
+  write_spi_data(y1+rowstart);     // YEND
+
+  write_spi_command(WRITE_RAM); // write to RAM
+}
+
+
+/**
+* Draw a pixel on the screen
+*/
+void gen_helper::draw_pixel(int16_t x, int16_t y, uint16_t color) {
+
+    // exit if the co-ordinates are out of bounds of the screen
+    if((x < 0) ||(x >= _width) || (y < 0) || (y >= _height))
+        return;
+
+  set_screen_coor(x, y, x + 1, y + 1);
+  
+  rs = 1; 
+  ssel = 0;
+  lcd.format(16,3); //set the data rate to 16 bits
+  lcd.write(color);     
+  ssel = 1;
+  lcd.format(8,3); //set the data rate to 8 bits
+}
+
+/**
+* Draw a vertical line
+* Based on ST7735 source
+*/
+void gen_helper::draw_vertical_line(int16_t x, int16_t y, int16_t h, uint16_t color) 
+{
+
+    if((x >= _width) || (y >= _height))
+        return;
+
+    if((y + h - 1) >= _height)
+        h = _height - y;
+
+    set_screen_coor(x, y, x, y + h - 1);
+
+    uint8_t hi = color >> 8, lo = color;
+    while (h--) 
+    {
+        spiwrite(hi);
+        spiwrite(lo);
+    }
+}
+
+/**
+* Draw a horizontal line
+* Based on ST7735 source
+*/
+void gen_helper::draw_horizontal_line(int16_t x, int16_t y, int16_t w, uint16_t color) 
+{
+
+    //check for screen boundary
+    if((x >= _width) || (y >= _height))
+        return;
+
+    if((x + w - 1) >= _width)
+        w = _width - x;
+
+    set_screen_coor(x, y, x + w - 1, y);
+
+    uint8_t hi = color >> 8, lo = color;
+
+    while (w--) {
+        spiwrite(hi);
+        spiwrite(lo);
+    }
+}
+
+/**
+* Draw a rectangle and fill it with a color
+*/
+void gen_helper::fill_rect(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint32_t color)
+{
+    int16_t width, height;
+
+    width = x1 - x0 + 1;
+    height = y1 - y0 + 1;
+    set_screen_coor(x0, y0, x1, y1);
+    write_spi_command(WRITE_RAM);
+    write_rgb(color, width * height);
+}
+
+/**
+* Write RGB colors to the screen
+*/
+void gen_helper::write_rgb(uint32_t color, uint32_t repeat) {
+    
+    uint8_t red, green, blue;
+    int i;
+    red = (color >> 16);
+    green = (color >> 8) & 0xFF;
+    blue = color & 0xFF;
+    
+    for (i = 0; i< repeat; i++) 
+    {
+        write_spi_data(red);
+        write_spi_data(green);
+        write_spi_data(blue);
+    }
+}
\ No newline at end of file