Renesas GR-Peach LCD Interface
Dependencies: EthernetInterface HTTPD PubNub SDFileSystem mbed-rtos mbed picojson
Renesas GR-Peach LCD Interface
lcd_main.cpp
- Committer:
- nikhilchaturtvedi
- Date:
- 2015-10-23
- Revision:
- 0:0b32d3eaabfe
File content as of revision 0:0b32d3eaabfe:
#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); } }