/** * @brief Draws a pixel on the display. * * @param[in] x X location of the pixel * @param[in] y Y location of the pixel * @param[in] color The color of the pixel * * @notapi */ void lld_gdisp_draw_pixel(coord_t x, coord_t y, color_t color) { #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP if (x < GDISP.clipx0 || y < GDISP.clipy0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return; #endif acquire_bus(); set_cursor(x, y); write_reg(0x0022, color); release_bus(); }
LLDSPEC void gdisp_lld_fill_area(GDisplay *g) { uint16_t c; c = gdispColor2Native(g->p.color); acquire_bus(g); set_viewport(g); set_cursor(g); dma_with_noinc(g, &c, g->p.cx*g->p.cy); release_bus(g); }
/** * @brief Scroll vertically a section of the screen. * @note Optional. * @note If x,y + cx,cy is off the screen, the result is undefined. * @note If lines is >= cy, it is equivelent to a area fill with bgcolor. * * @param[in] x, y The start of the area to be scrolled * @param[in] cx, cy The size of the area to be scrolled * @param[in] lines The number of lines to scroll (Can be positive or negative) * @param[in] bgcolor The color to fill the newly exposed area. * * @notapi */ void GDISP_LLD(verticalscroll)(coord_t x, coord_t y, coord_t cx, coord_t cy, int lines, color_t bgcolor) { /* This is marked as "TODO: Test this" in the original GLCD driver. * For now we just leave the GDISP_HARDWARE_SCROLL off. */ static color_t buf[((GDISP_SCREEN_HEIGHT > GDISP_SCREEN_WIDTH ) ? GDISP_SCREEN_HEIGHT : GDISP_SCREEN_WIDTH)]; coord_t row0, row1; unsigned i, gap, abslines; #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; x = GDISP.clipx0; } if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; y = GDISP.clipy0; } if (!lines || cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return; if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x; if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y; #endif abslines = lines < 0 ? -lines : lines; acquire_bus(); if (abslines >= cy) { abslines = cy; gap = 0; } else { gap = cy - abslines; for(i = 0; i < gap; i++) { if(lines > 0) { row0 = y + i + lines; row1 = y + i; } else { row0 = (y - i - 1) + lines; row1 = (y - i - 1); } /* read row0 into the buffer and then write at row1*/ set_viewport(x, row0, cx, 1); lld_lcdReadStreamStart(); lld_lcdReadStream(buf, cx); lld_lcdReadStreamStop(); set_viewport(x, row1, cx, 1); stream_start(); write_data(buf, cx); stream_stop(); } } /* fill the remaining gap */ set_viewport(x, lines > 0 ? (y+gap) : y, cx, abslines); stream_start(); gap = cx*abslines; for(i = 0; i < gap; i++) write_data(bgcolor); stream_stop(); reset_viewport(); release_bus(); }
/** * @brief Scroll vertically a section of the screen. * @note Optional. * @note If x,y + cx,cy is off the screen, the result is undefined. * @note If lines is >= cy, it is equivelent to a area fill with bgcolor. * * @param[in] x, y The start of the area to be scrolled * @param[in] cx, cy The size of the area to be scrolled * @param[in] lines The number of lines to scroll (Can be positive or negative) * @param[in] bgcolor The color to fill the newly exposed area. * * @notapi */ void lld_gdisp_vertical_scroll(coord_t x, coord_t y, coord_t cx, coord_t cy, int lines, color_t bgcolor) { static color_t buf[((GDISP_SCREEN_HEIGHT > GDISP_SCREEN_WIDTH ) ? GDISP_SCREEN_HEIGHT : GDISP_SCREEN_WIDTH)]; coord_t row0, row1; unsigned i, gap, abslines, j; #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; x = GDISP.clipx0; } if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; y = GDISP.clipy0; } if (!lines || cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return; if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x; if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y; #endif abslines = lines < 0 ? -lines : lines; acquire_bus(); if (abslines >= cy) { abslines = cy; gap = 0; } else { gap = cy - abslines; for(i = 0; i < gap; i++) { if(lines > 0) { row0 = y + i + lines; row1 = y + i; } else { row0 = (y - i - 1) + lines; row1 = (y - i - 1); } /* read row0 into the buffer and then write at row1*/ set_viewport(x, row0, cx, 1); stream_start(); j = read_data(); // dummy read for (j = 0; j < cx; j++) buf[j] = read_data(); stream_stop(); set_viewport(x, row1, cx, 1); stream_start(); for (j = 0; j < cx; j++) write_data(buf[j]); stream_stop(); } } /* fill the remaining gap */ set_viewport(x, lines > 0 ? (y+gap) : y, cx, abslines); stream_start(); gap = cx*abslines; for(i = 0; i < gap; i++) write_data(bgcolor); stream_stop(); release_bus(); }
/** * @brief Clear the display. * @note Optional - The high level driver can emulate using software. * * @param[in] color The color of the pixel * * @notapi */ void lld_gdisp_clear(color_t color) { unsigned i; acquire_bus(); reset_viewport(); set_cursor(0, 0); stream_start(); for(i = 0; i < GDISP_SCREEN_WIDTH * GDISP_SCREEN_HEIGHT; i++) write_data(color); stream_stop(); release_bus(); }
/** * @brief Clear the display. * @note Optional - The high level driver can emulate using software. * * @param[in] color The color of the pixel * * @notapi */ void GDISP_LLD(clear)(color_t color) { unsigned i; acquire_bus(); set_cursor(0, 0); stream_start(); for(i = 0; i < GDISP_SCREEN_WIDTH * GDISP_SCREEN_HEIGHT; i++) write_data(color); stream_stop(); release_bus(); }
LLDSPEC void gdisp_lld_fill_area(GDisplay* g) { #if GDISP_NO_DMA_FROM_STACK static LLDCOLOR_TYPE c; #else LLDCOLOR_TYPE c; #endif c = gdispColor2Native(g->p.color); acquire_bus(g); set_viewport(g); set_cursor(g); dma_with_noinc(g, &c, g->p.cx * g->p.cy); release_bus(g); }
LLDSPEC void gdisp_lld_blit_area(GDisplay *g) { pixel_t *buffer; coord_t ycnt; buffer = (pixel_t *)g->p.ptr + g->p.x1 + g->p.y1 * g->p.x2; acquire_bus(g); set_viewport(g); set_cursor(g); if (g->p.x2 == g->p.cx) { dma_with_inc(g, buffer, g->p.cx*g->p.cy); } else { for (ycnt = g->p.cy; ycnt; ycnt--, buffer += g->p.x2) dma_with_inc(g, buffer, g->p.cy); } release_bus(g); }
/** * @brief Get the color of a particular pixel. * @note Optional. * @note If x,y is off the screen, the result is undefined. * * @param[in] x, y The pixel to be read * * @notapi */ color_t lld_gdisp_get_pixel_color(coord_t x, coord_t y) { color_t color; #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP if (x < 0 || x >= GDISP.Width || y < 0 || y >= GDISP.Height) return 0; #endif acquire_bus(); set_cursor(x, y); stream_start(); color = read_data(); // dummy read color = read_data(); stream_stop(); release_bus(); return color; }
/** * @brief Read the mouse/touch position. * * @param[in] pt A pointer to the structure to fill * * @note For drivers that don't support returning a position * when the touch is up (most touch devices), it should * return the previous position with the new Z value. * The z value is the pressure for those touch devices * that support it (-100 to 100 where > 0 is touched) * or, 0 or 100 for those drivers that don't. * * @notapi */ void ginput_lld_mouse_get_reading(MouseReading *pt) { uint16_t i; // If touch-off return the previous results if (!getpin_pressed()) { pt->x = lastx; pt->y = lasty; pt->z = 0; pt->buttons = 0; return; } // Read the port to get the touch settings aquire_bus(); /* Get the X value * Discard the first conversion - very noisy and keep the ADC on hereafter * till we are done with the sampling. Note that PENIRQ is disabled while reading. * Finally switch on PENIRQ once again - perform a dummy read. * Once we have the readings, find the medium using our filter function */ read_value(0xD1); for(i = 0; i < 7; i++) sampleBuf[i] = read_value(0xD1); read_value(0xD0); filter(); lastx = (coord_t)sampleBuf[3]; /* Get the Y value using the same process as above */ read_value(0x91); for(i = 0; i < 7; i++) sampleBuf[i] = read_value(0x91); read_value(0x90); filter(); lasty = (coord_t)sampleBuf[3]; // Release the bus release_bus(); // Return the results pt->x = lastx; pt->y = lasty; pt->z = 100; pt->buttons = GINPUT_TOUCH_PRESSED; }
LLDSPEC void gdisp_lld_clear(GDisplay *g) { acquire_bus(g); write_cmd(g, SSD1327_SET_COLUMN_ADDRESS); write_data(g, 0); write_data(g, GDISP_SCREEN_WIDTH - 1); write_cmd(g, SSD1327_SET_ROW_ADDRESS); write_data(g, 0); write_data(g, GDISP_SCREEN_HEIGHT - 1); write_cmd(g, SSD1327_WRITE_RAM); LLDCOLOR_TYPE c; c = gdispColor2Native(g->p.color); uint16_t i = 0; for (i = 0; i < GDISP_SCREEN_WIDTH*GDISP_SCREEN_HEIGHT; i++) { write_data(g, c >> 8); write_data(g, c & 0xFF); } release_bus(g); }
LLDSPEC bool_t gdisp_lld_init(GDisplay *g) { // No private area for this controller g->priv = 0; // Initialise the board interface init_board(g); // Hardware reset setpin_reset(g, TRUE); delayms(100); setpin_reset(g, FALSE); delayms(100); acquire_bus(g); const uint16_t *list = &lcd_init_list[0]; uint8_t size = sizeof(lcd_init_list) / sizeof(lcd_init_list[0]); while(size--) { write_index(g, *list++); } // Finish Init post_init_board(g); release_bus(g); // Turn on the back-light set_backlight(g, GDISP_INITIAL_BACKLIGHT); // Initialise the GDISP structure to match g->g.Width = GDISP_SCREEN_WIDTH; g->g.Height = GDISP_SCREEN_HEIGHT; g->g.Orientation = GDISP_ROTATE_0; g->g.Powermode = powerOn; g->g.Backlight = GDISP_INITIAL_BACKLIGHT; g->g.Contrast = GDISP_INITIAL_CONTRAST; return TRUE; }
/** * @brief Fill an area with a color. * @note Optional - The high level driver can emulate using software. * * @param[in] x, y The start filled area * @param[in] cx, cy The width and height to be filled * @param[in] color The color of the fill * * @notapi */ void GDISP_LLD(fillarea)(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) { unsigned i, area; #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; x = GDISP.clipx0; } if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; y = GDISP.clipy0; } if (cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return; if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x; if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y; #endif area = cx*cy; acquire_bus(); set_viewport(x, y, cx, cy); stream_start(); for(i = 0; i < area; i++) write_data(color); stream_stop(); reset_viewport(); release_bus(); }
/** * Notes: * * This chip has some problems which required careful coding to overcome. * * The interrupt pin seems to be unreliable, at least on some boards, so we at most * use the pin for filtering results to reduce cpu load. * The symptoms are that readings will just stop due to the irq not being asserted * even though there are items in the fifo. Another interrupt source such as a * touch transition will restart the irq. * * There is no fifo entry created when a touch up event occurs. We must therefore * generate a pseudo result on touch up. Fortunately the touch detection appears * reliable and so we turn off the driver GMOUSE_VFLG_POORUPDOWN setting. In practice * if touch is up we always return a pseudo event as this saves having to remember the * previous touch state. * * Z readings range from around 90 (fully touched) to around 150 (on the verge of non-touched). * Note the above is on the STM32F429i-Discovery board. Other boards may be different. * To be conservative we use 255 as touch off, anything else is a touch on. * * GMOUSE_STMPE811_TEST_MODE is designed to be used with the "touch_raw_readings" tool which shows * a steady stream of raw readings. * * Settings that may need tweaking on other hardware: * The settling times. We have set these conservatively at 1ms. * The reading window. We set this to 16 just to reduce noise. High-res panels may need a lower value. */ static bool_t MouseInit(GMouse* m, unsigned driverinstance) { if (!init_board(m, driverinstance)) return FALSE; aquire_bus(m); write_reg(m, STMPE811_REG_SYS_CTRL1, 0x02); // Software chip reset gfxSleepMilliseconds(10); write_reg(m, STMPE811_REG_SYS_CTRL2, 0x0C); // Temperature sensor clock off, GPIO clock off, touch clock on, ADC clock on #if GMOUSE_STMPE811_GPIO_IRQPIN write_reg(m, STMPE811_REG_INT_EN, 0x03); // Interrupt on INT pin when there is a sample or a touch transition. #else write_reg(m, STMPE811_REG_INT_EN, 0x00); // Don't Interrupt on INT pin #endif write_reg(m, STMPE811_REG_ADC_CTRL1, 0x48); // ADC conversion time = 80 clock ticks, 12-bit ADC, internal voltage refernce gfxSleepMilliseconds(2); write_reg(m, STMPE811_REG_ADC_CTRL2, 0x01); // ADC speed 3.25MHz write_reg(m, STMPE811_REG_GPIO_AF, 0x00); // GPIO alternate function - OFF write_reg(m, STMPE811_REG_TSC_CFG, 0xA3); // Averaging 4, touch detect delay 1ms, panel driver settling time 1ms write_reg(m, STMPE811_REG_FIFO_TH, 0x01); // FIFO threshold = 1 write_reg(m, STMPE811_REG_FIFO_STA, 0x01); // FIFO reset enable write_reg(m, STMPE811_REG_FIFO_STA, 0x00); // FIFO reset disable write_reg(m, STMPE811_REG_TSC_FRACT_XYZ, 0x07); // Z axis data format write_reg(m, STMPE811_REG_TSC_I_DRIVE, 0x01); // max 50mA touchscreen line current #if GMOUSE_STMPE811_READ_PRESSURE write_reg(m, STMPE811_REG_TSC_CTRL, 0x30); // X&Y&Z, 16 reading window write_reg(m, STMPE811_REG_TSC_CTRL, 0x31); // X&Y&Z, 16 reading window, TSC enable #else write_reg(m, STMPE811_REG_TSC_CTRL, 0x32); // X&Y, 16 reading window write_reg(m, STMPE811_REG_TSC_CTRL, 0x33); // X&Y, 16 reading window, TSC enable #endif write_reg(m, STMPE811_REG_INT_STA, 0xFF); // Clear all interrupts write_reg(m, STMPE811_REG_INT_CTRL, 0x01); // Level interrupt, enable interrupts release_bus(m); return TRUE; }
/** * @brief Get the color of a particular pixel. * @note Optional. * @note If x,y is off the screen, the result is undefined. * * @param[in] x, y The start of the text * * @notapi */ color_t GDISP_LLD(getpixelcolor)(coord_t x, coord_t y) { /* This routine is marked "DO NOT USE" in the original * GLCD driver. We just keep our GDISP_HARDWARE_READPIXEL * turned off for now. */ color_t color; #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP if (x < 0 || x >= GDISP.Width || y < 0 || y >= GDISP.Height) return 0; #endif aquire_bus(); set_cursor(x, y); stream_start(); color = lld_lcdReadData(); color = lld_lcdReadData(); stream_stop(); release_bus(); return color; }
LLDSPEC void gdisp_lld_fill_area(GDisplay *g) { coord_t x = g->p.x; coord_t y = g->p.y; coord_t w = g->p.cx; coord_t h = g->p.cy; LLDCOLOR_TYPE c = g->p.color; acquire_bus(g); write_cmd(g, SSD1327_SET_COLUMN_ADDRESS); write_data(g, x); write_data(g, x + w -1); write_cmd(g, SSD1327_SET_ROW_ADDRESS); write_data(g, y); write_data(g, y + h - 1); write_cmd(g, SSD1327_WRITE_RAM); uint16_t i = 0; for (i = 0; i < w*h; i++) { write_data(g, c >> 8); write_data(g, c & 0xFF); } release_bus(g); }
/** * @brief Fill an area with a bitmap. * @note Optional - The high level driver can emulate using software. * * @param[in] x, y The start filled area * @param[in] cx, cy The width and height to be filled * @param[in] srcx, srcy The bitmap position to start the fill from * @param[in] srccx The width of a line in the bitmap. * @param[in] buffer The pixels to use to fill the area. * * @notapi */ void GDISP_LLD(blitareaex)(coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx, coord_t srcy, coord_t srccx, const pixel_t *buffer) { coord_t endx, endy; unsigned lg; #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; srcx += GDISP.clipx0 - x; x = GDISP.clipx0; } if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; srcy += GDISP.clipy0 - y; y = GDISP.clipy0; } if (srcx+cx > srccx) cx = srccx - srcx; if (cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return; if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x; if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y; #endif acquire_bus(); set_viewport(x, y, cx, cy); stream_start(); endx = srcx + cx; endy = y + cy; lg = srccx - cx; buffer += srcx + srcy * srccx; for(; y < endy; y++, buffer += lg) for(x=srcx; x < endx; x++) write_data(*buffer++); stream_stop(); reset_viewport(); release_bus(); }
LLDSPEC void gdisp_lld_write_stop(GDisplay *g) { release_bus(g); }
void process_received_command() { if (receivedBytes[0] == 0) return; // parse command and arg here const char cmd = receivedBytes[0]; char* data = receivedBytes+2; if(debugMode == 1){ //Serial.print("DEBUG Handling this command: "); //Serial.println(receivedBytes); } // d - toggle debugging output // h - take a hold on the bus so the cpu doesn't get confused // l - release bus and reset the cpu // m - set rom size // o - set rom offset // p - ping // r - read address // w - write data to address // z - zero out memory switch(cmd) { case 'p': Serial.println("OK"); break; case 'z': zero_rom(); Serial.println("OK"); break; case 'o': set_rom_offset(cmd, data); Serial.println("OK"); break; case 'm': set_rom_size(cmd, data); Serial.println("OK"); break; case 'r': dump_memory_contents(cmd, data); Serial.println("OK"); break; case 'd': toggle_debug(); Serial.println("OK"); break; case 'w': parse_hex_and_write_to_mem(cmd, data); Serial.println("OK"); break; case 'h': hold_and_commandeer_bus(); Serial.println("OK"); break; case 'l': release_bus(); reset_cpu(); release_hold(); Serial.println("OK"); break; default: Serial.println("NOT OK"); break; }; clearReceivedCommand(); }
LLDSPEC void gdisp_lld_control(GDisplay *g) { switch(g->p.x) { case GDISP_CONTROL_POWER: if (g->g.Powermode == (powermode_t)g->p.ptr) return; switch((powermode_t)g->p.ptr) { case powerOff: acquire_bus(g); write_reg(g, 0x07, 0x0000); write_reg(g, 0x10, 0x0000); write_reg(g, 0x11, 0x0000); write_reg(g, 0x12, 0x0000); write_reg(g, 0x13, 0x0000); release_bus(g); set_backlight(g, 0); break; case powerOn: //*************Power On sequence ******************// acquire_bus(g); write_reg(g, 0x10, 0x0000); /* SAP, BT[3:0], AP, DSTB, SLP, STB */ write_reg(g, 0x11, 0x0000); /* DC1[2:0], DC0[2:0], VC[2:0] */ write_reg(g, 0x12, 0x0000); /* VREG1OUT voltage */ write_reg(g, 0x13, 0x0000); /* VDV[4:0] for VCOM amplitude */ gfxSleepMicroseconds(2000); /* Dis-charge capacitor power voltage */ write_reg(g, 0x10, 0x17B0); /* SAP, BT[3:0], AP, DSTB, SLP, STB */ write_reg(g, 0x11, 0x0147); /* DC1[2:0], DC0[2:0], VC[2:0] */ gfxSleepMicroseconds(500); write_reg(g, 0x12, 0x013C); /* VREG1OUT voltage */ gfxSleepMicroseconds(500); write_reg(g, 0x13, 0x0E00); /* VDV[4:0] for VCOM amplitude */ write_reg(g, 0x29, 0x0009); /* VCM[4:0] for VCOMH */ gfxSleepMicroseconds(500); write_reg(g, 0x07, 0x0173); /* 262K color and display ON */ release_bus(g); set_backlight(g, g->g.Backlight); break; case powerSleep: acquire_bus(g); write_reg(g, 0x07, 0x0000); /* display OFF */ write_reg(g, 0x10, 0x0000); /* SAP, BT[3:0], APE, AP, DSTB, SLP */ write_reg(g, 0x11, 0x0000); /* DC1[2:0], DC0[2:0], VC[2:0] */ write_reg(g, 0x12, 0x0000); /* VREG1OUT voltage */ write_reg(g, 0x13, 0x0000); /* VDV[4:0] for VCOM amplitude */ gfxSleepMicroseconds(2000); /* Dis-charge capacitor power voltage */ write_reg(g, 0x10, 0x0002); /* SAP, BT[3:0], APE, AP, DSTB, SLP */ release_bus(g); set_backlight(g, 0); break; case powerDeepSleep: acquire_bus(g); write_reg(g, 0x07, 0x0000); /* display OFF */ write_reg(g, 0x10, 0x0000); /* SAP, BT[3:0], APE, AP, DSTB, SLP */ write_reg(g, 0x11, 0x0000); /* DC1[2:0], DC0[2:0], VC[2:0] */ write_reg(g, 0x12, 0x0000); /* VREG1OUT voltage */ write_reg(g, 0x13, 0x0000); /* VDV[4:0] for VCOM amplitude */ gfxSleepMicroseconds(2000); /* Dis-charge capacitor power voltage */ write_reg(g, 0x10, 0x0004); /* SAP, BT[3:0], APE, AP, DSTB, SLP */ release_bus(g); set_backlight(g, 0); break; default: return; } g->g.Powermode = (powermode_t)g->p.ptr; return; case GDISP_CONTROL_ORIENTATION: if (g->g.Orientation == (orientation_t)g->p.ptr) return; switch((orientation_t)g->p.ptr) { case GDISP_ROTATE_0: acquire_bus(g); write_reg(g, 0x01, 0x0100); write_reg(g, 0x03, 0x1038); write_reg(g, 0x60, 0x2700); release_bus(g); g->g.Height = GDISP_SCREEN_HEIGHT; g->g.Width = GDISP_SCREEN_WIDTH; break; case GDISP_ROTATE_90: acquire_bus(g); write_reg(g, 0x01, 0x0000); write_reg(g, 0x03, 0x1030); write_reg(g, 0x60, 0x2700); release_bus(g); g->g.Height = GDISP_SCREEN_WIDTH; g->g.Width = GDISP_SCREEN_HEIGHT; break; case GDISP_ROTATE_180: acquire_bus(g); write_reg(g, 0x01, 0x0000); write_reg(g, 0x03, 0x1030); write_reg(g, 0x60, 0x2700); release_bus(g); g->g.Height = GDISP_SCREEN_HEIGHT; g->g.Width = GDISP_SCREEN_WIDTH; break; case GDISP_ROTATE_270: acquire_bus(g); write_reg(g, 0x01, 0x0100); write_reg(g, 0x03, 0x1038); write_reg(g, 0x60, 0xA700); release_bus(g); g->g.Height = GDISP_SCREEN_WIDTH; g->g.Width = GDISP_SCREEN_HEIGHT; break; default: return; } g->g.Orientation = (orientation_t)g->p.ptr; return; case GDISP_CONTROL_BACKLIGHT: if ((unsigned)g->p.ptr > 100) g->p.ptr = (void *)100; set_backlight(g, (unsigned)g->p.ptr); g->g.Backlight = (unsigned)g->p.ptr; return; default: return; } }
/** * @brief Driver Control * @details Unsupported control codes are ignored. * @note The value parameter should always be typecast to (void *). * @note There are some predefined and some specific to the low level driver. * @note GDISP_CONTROL_POWER - Takes a gdisp_powermode_t * GDISP_CONTROL_ORIENTATION - Takes a gdisp_orientation_t * GDISP_CONTROL_BACKLIGHT - Takes an int from 0 to 100. For a driver * that only supports off/on anything other * than zero is on. * GDISP_CONTROL_CONTRAST - Takes an int from 0 to 100. * GDISP_CONTROL_LLD - Low level driver control constants start at * this value. * * @param[in] what What to do. * @param[in] value The value to use (always cast to a void *). * * @notapi */ void lld_gdisp_control(unsigned what, void *value) { switch(what) { case GDISP_CONTROL_POWER: if (GDISP.Powermode == (gdisp_powermode_t)value) return; switch((gdisp_powermode_t)value) { case powerOff: acquire_bus(); write_reg(0x0010, 0x0000); // leave sleep mode write_reg(0x0007, 0x0000); // halt operation write_reg(0x0000, 0x0000); // turn off oszillator write_reg(0x0010, 0x0001); // enter sleepmode release_bus(); break; case powerOn: acquire_bus(); write_reg(0x0010, 0x0000); // leave sleep mode release_bus(); if (GDISP.Powermode != powerSleep) lld_gdisp_init(); break; case powerSleep: acquire_bus(); write_reg(0x0010, 0x0001); // enter sleep mode release_bus(); break; default: return; } GDISP.Powermode = (gdisp_powermode_t)value; return; case GDISP_CONTROL_ORIENTATION: if (GDISP.Orientation == (gdisp_orientation_t)value) return; switch((gdisp_orientation_t)value) { case GDISP_ROTATE_0: acquire_bus(); write_reg(0x0001, 0x2B3F); /* ID = 11 AM = 0 */ write_reg(0x0011, 0x6070); release_bus(); GDISP.Height = GDISP_SCREEN_HEIGHT; GDISP.Width = GDISP_SCREEN_WIDTH; break; case GDISP_ROTATE_90: acquire_bus(); write_reg(0x0001, 0x293F); /* ID = 11 AM = 1 */ write_reg(0x0011, 0x6078); release_bus(); GDISP.Height = GDISP_SCREEN_WIDTH; GDISP.Width = GDISP_SCREEN_HEIGHT; break; case GDISP_ROTATE_180: acquire_bus(); write_reg(0x0001, 0x2B3F); /* ID = 01 AM = 0 */ write_reg(0x0011, 0x6040); release_bus(); GDISP.Height = GDISP_SCREEN_HEIGHT; GDISP.Width = GDISP_SCREEN_WIDTH; break; case GDISP_ROTATE_270: acquire_bus(); write_reg(0x0001, 0x293F); /* ID = 01 AM = 1 */ write_reg(0x0011, 0x6048); release_bus(); GDISP.Height = GDISP_SCREEN_WIDTH; GDISP.Width = GDISP_SCREEN_HEIGHT; break; default: return; } #if GDISP_NEED_CLIP || GDISP_NEED_VALIDATION GDISP.clipx0 = 0; GDISP.clipy0 = 0; GDISP.clipx1 = GDISP.Width; GDISP.clipy1 = GDISP.Height; #endif GDISP.Orientation = (gdisp_orientation_t)value; return; /* case GDISP_CONTROL_BACKLIGHT: case GDISP_CONTROL_CONTRAST: */ } }
LLDSPEC void gdisp_lld_control(GDisplay *g) { switch(g->p.x) { #if 0 case GDISP_CONTROL_POWER: if (g->g.Powermode == (powermode_t)g->p.ptr) return; switch((powermode_t)g->p.ptr) { case powerOff: acquire_bus(g); // TODO release_bus(g); break; case powerOn: acquire_bus(g); // TODO release_bus(g); break; case powerSleep: acquire_bus(g); // TODO release_bus(g); break; default: return; } g->g.Powermode = (powermode_t)g->p.ptr; return; #endif #if 0 case GDISP_CONTROL_ORIENTATION: if (g->g.Orientation == (orientation_t)g->p.ptr) return; switch((orientation_t)g->p.ptr) { case GDISP_ROTATE_0: acquire_bus(g); // TODO release_bus(g); g->g.Height = GDISP_SCREEN_HEIGHT; g->g.Width = GDISP_SCREEN_WIDTH; break; case GDISP_ROTATE_90: acquire_bus(g); // TODO release_bus(g); g->g.Height = GDISP_SCREEN_WIDTH; g->g.Width = GDISP_SCREEN_HEIGHT; break; case GDISP_ROTATE_180: acquire_bus(g); // TODO release_bus(g); g->g.Height = GDISP_SCREEN_HEIGHT; g->g.Width = GDISP_SCREEN_WIDTH; break; case GDISP_ROTATE_270: acquire_bus(g); // TODO release_bus(g); g->g.Height = GDISP_SCREEN_WIDTH; g->g.Width = GDISP_SCREEN_HEIGHT; break; default: return; } g->g.Orientation = (orientation_t)g->p.ptr; return; #endif case GDISP_CONTROL_BACKLIGHT: if ((unsigned)g->p.ptr > 100) g->p.ptr = (void *)100; acquire_bus(g); set_backlight(g, (unsigned)g->p.ptr); release_bus(g); g->g.Backlight = (unsigned)g->p.ptr; return; //case GDISP_CONTROL_CONTRAST: default: return; } }
// #error "SSD1327 - Hardware control is not supported yet" LLDSPEC void gdisp_lld_control(GDisplay *g) { switch(g->p.x) { case GDISP_CONTROL_POWER: if (g->g.Powermode == (powermode_t)g->p.ptr) return; switch((powermode_t)g->p.ptr) { case powerOff: acquire_bus(g); write_cmd(g, SSD1327_SET_DISPLAY_MODE_ALL_OFF); release_bus(); break; case powerSleep: case powerDeepSleep: acquire_bus(g); write_cmd(g, SSD1327_SET_SLEEP_ON); release_bus(g); break; case powerOn: acquire_bus(g); write_cmd(g, SSD1327_SET_SLEEP_OFF); write_cmd(g, SSD1327_SET_DISPLAY_MODE_ALL_ON); release_bus(g); break; default: return; } g->g.Powermode = (powermode_t)g->p.ptr; return; case GDISP_CONTROL_ORIENTATION: if (g->g.Orientation == (orientation_t)g->p.ptr) return; switch((orientation_t)g->p.ptr) { case GDISP_ROTATE_0: // correct acquire_bus(g); write_reg(g, SSD1327_SET_REMAP, (0b01<<6) | (1<<5) | (1<<4) | (1<<2) | 0b00); // bits: // [0] : address increment (0: horizontal, 1: vertical, reset 0) // [1] : column remap (0: 0..127, 1: 127..0, reset 0) // [2] : color remap (0: A->B->C, 1: C->B->A, reset 0) // [3] : reserved // [4] : column scan direction (0: top->down, 1: bottom->up, reset 0) // [5] : odd/even split COM (0: disable, 1: enable, reset 1) // [6..7] : color depth (00,01: 65k, 10: 262k, 11: 262k format 2) write_cmd(g, SSD1327_WRITE_RAM); g->g.Height = GDISP_SCREEN_HEIGHT; g->g.Width = GDISP_SCREEN_WIDTH; release_bus(g); break; case GDISP_ROTATE_90: acquire_bus(g); write_reg(g, SSD1327_SET_REMAP, (0b01<<6) | (1<<5) | (1<<4) | (1<<2) | 0b10); write_cmd(g, SSD1327_WRITE_RAM); g->g.Height = GDISP_SCREEN_WIDTH; g->g.Width = GDISP_SCREEN_HEIGHT; release_bus(g); break; case GDISP_ROTATE_180: acquire_bus(g); write_reg(g, SSD1327_SET_REMAP, (0b01<<6) | (1<<5) | (0<<4) | (1<<2) | 0b00); write_reg(g, SSD1327_SET_REMAP, 0b01100110); write_cmd(g, SSD1327_WRITE_RAM); g->g.Height = GDISP_SCREEN_HEIGHT; g->g.Width = GDISP_SCREEN_WIDTH; release_bus(g); break; case GDISP_ROTATE_270: acquire_bus(g); write_reg(g, SSD1327_SET_REMAP, (0b01<<6) | (1<<5) | (0<<4) | (1<<2) | 0b01); write_cmd(g, SSD1327_WRITE_RAM); g->g.Height = GDISP_SCREEN_WIDTH; g->g.Width = GDISP_SCREEN_HEIGHT; release_bus(g); break; default: return; } g->g.Orientation = (orientation_t)g->p.ptr; return; case GDISP_CONTROL_BACKLIGHT: if ((unsigned)g->p.ptr > 100) g->p.ptr = (void *)100; set_backlight(g, (unsigned)g->p.ptr); g->g.Backlight = (unsigned)g->p.ptr; return; //case GDISP_CONTROL_CONTRAST: default: return; } }
static bool_t read_xyz(GMouse* m, GMouseReading* pdr) { #if GMOUSE_STMPE811_TEST_MODE static GMouseReading n; #endif uint8_t status; // Button information will be regenerated pdr->buttons = 0; #if GMOUSE_STMPE811_TEST_MODE aquire_bus(m); // Set the buttons to match various touch signals if ((read_byte(m, STMPE811_REG_TSC_CTRL) & 0x80)) pdr->buttons |= 0x02; status = read_byte(m, STMPE811_REG_FIFO_STA); if (!(status & 0x20)) pdr->buttons |= 0x04; #if GMOUSE_STMPE811_GPIO_IRQPIN if (getpin_irq(m)) pdr->buttons |= 0x08; #endif if ((status & 0x20)) { // Nothing in the fifo - just return the last position and pressure pdr->x = n.x; pdr->y = n.y; pdr->z = n.z; #if GMOUSE_STMPE811_GPIO_IRQPIN write_reg(m, STMPE811_REG_INT_STA, 0xFF); #endif release_bus(m); return TRUE; } #else // Is there a new sample or a touch transition #if GMOUSE_STMPE811_GPIO_IRQPIN if(!getpin_irq(m)) return FALSE; #endif // Is there something in the fifo status = read_byte(m, STMPE811_REG_FIFO_STA); if ((status & 0x20)) { // Nothing in the fifo. // If not touched return the pseudo result if (!(read_byte(m, STMPE811_REG_TSC_CTRL) & 0x80)) { pdr->z = gmvmt(m)->z_min; #if GMOUSE_STMPE811_GPIO_IRQPIN write_reg(m, STMPE811_REG_INT_STA, 0xFF); #endif release_bus(m); return TRUE; } // No new result #if GMOUSE_STMPE811_GPIO_IRQPIN write_reg(m, STMPE811_REG_INT_STA, 0xFF); #endif release_bus(m); return FALSE; } #endif // Time to get some readings pdr->x = (coord_t)read_word(m, STMPE811_REG_TSC_DATA_X); pdr->y = (coord_t)read_word(m, STMPE811_REG_TSC_DATA_Y); #if GMOUSE_STMPE811_READ_PRESSURE pdr->z = (coord_t)read_byte(m, STMPE811_REG_TSC_DATA_Z); #else pdr->z = gmvmt(m)->z_max; #endif #if !GMOUSE_STMPE811_SLOW_CPU if (!(status & 0xC0)) { // Is there more data to come if (!(read_byte(m, STMPE811_REG_FIFO_STA) & 0x20)) _gmouseWakeup(m); } else #endif // Clear the rest of the fifo { write_reg(m, STMPE811_REG_FIFO_STA, 0x01); // FIFO reset enable write_reg(m, STMPE811_REG_FIFO_STA, 0x00); // FIFO reset disable } // All done #if GMOUSE_STMPE811_GPIO_IRQPIN write_reg(m, STMPE811_REG_INT_STA, 0xFF); #endif release_bus(m); #if GMOUSE_STMPE811_TEST_MODE // Save the result for later n.x = pdr->x; n.y = pdr->y; n.z = pdr->z; #endif // Rescale X,Y if we are using self-calibration #if GMOUSE_STMPE811_SELF_CALIBRATE #if GDISP_NEED_CONTROL switch(gdispGGetOrientation(m->display)) { default: case GDISP_ROTATE_0: case GDISP_ROTATE_180: pdr->x = gdispGGetWidth(m->display) - pdr->x / (4096/gdispGGetWidth(m->display)); pdr->y = pdr->y / (4096/gdispGGetHeight(m->display)); break; case GDISP_ROTATE_90: case GDISP_ROTATE_270: pdr->x = gdispGGetHeight(m->display) - pdr->x / (4096/gdispGGetHeight(m->display)); pdr->y = pdr->y / (4096/gdispGGetWidth(m->display)); break; } #else pdr->x = gdispGGetWidth(m->display) - pdr->x / (4096/gdispGGetWidth(m->display)); pdr->y = pdr->y / (4096/gdispGGetHeight(m->display)); #endif #endif return TRUE; }
/** * @brief Low level GDISP driver initialization. * * @notapi */ bool_t lld_gdisp_init(void) { /* Initialise your display */ init_board(); // Hardware reset setpin_reset(TRUE); delayms(20); setpin_reset(FALSE); delayms(20); // Get the bus for the following initialisation commands acquire_bus(); write_reg(0x0000,0x0001); delay(5); write_reg(0x0003,0xA8A4); delay(5); write_reg(0x000C,0x0000); delay(5); write_reg(0x000D,0x080C); delay(5); write_reg(0x000E,0x2B00); delay(5); write_reg(0x001E,0x00B0); delay(5); write_reg(0x0001,0x2B3F); delay(5); write_reg(0x0002,0x0600); delay(5); write_reg(0x0010,0x0000); delay(5); write_reg(0x0011,0x6070); delay(5); write_reg(0x0005,0x0000); delay(5); write_reg(0x0006,0x0000); delay(5); write_reg(0x0016,0xEF1C); delay(5); write_reg(0x0017,0x0003); delay(5); write_reg(0x0007,0x0133); delay(5); write_reg(0x000B,0x0000); delay(5); write_reg(0x000F,0x0000); delay(5); write_reg(0x0041,0x0000); delay(5); write_reg(0x0042,0x0000); delay(5); write_reg(0x0048,0x0000); delay(5); write_reg(0x0049,0x013F); delay(5); write_reg(0x004A,0x0000); delay(5); write_reg(0x004B,0x0000); delay(5); write_reg(0x0044,0xEF00); delay(5); write_reg(0x0045,0x0000); delay(5); write_reg(0x0046,0x013F); delay(5); write_reg(0x0030,0x0707); delay(5); write_reg(0x0031,0x0204); delay(5); write_reg(0x0032,0x0204); delay(5); write_reg(0x0033,0x0502); delay(5); write_reg(0x0034,0x0507); delay(5); write_reg(0x0035,0x0204); delay(5); write_reg(0x0036,0x0204); delay(5); write_reg(0x0037,0x0502); delay(5); write_reg(0x003A,0x0302); delay(5); write_reg(0x003B,0x0302); delay(5); write_reg(0x0023,0x0000); delay(5); write_reg(0x0024,0x0000); delay(5); write_reg(0x0025,0x8000); delay(5); write_reg(0x004f,0x0000); delay(5); write_reg(0x004e,0x0000); delay(5); // Release the bus release_bus(); /* Turn on the back-light */ set_backlight(GDISP_INITIAL_BACKLIGHT); /* Initialise the GDISP structure */ GDISP.Width = GDISP_SCREEN_WIDTH; GDISP.Height = GDISP_SCREEN_HEIGHT; GDISP.Orientation = GDISP_ROTATE_0; GDISP.Powermode = powerOn; GDISP.Backlight = GDISP_INITIAL_BACKLIGHT; GDISP.Contrast = GDISP_INITIAL_CONTRAST; #if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP GDISP.clipx0 = 0; GDISP.clipy0 = 0; GDISP.clipx1 = GDISP.Width; GDISP.clipy1 = GDISP.Height; #endif return TRUE; }
LLDSPEC void gdisp_lld_control(GDisplay *g) { /* The hardware is capable of supporting... * GDISP_CONTROL_POWER - supported * GDISP_CONTROL_ORIENTATION - supported * GDISP_CONTROL_BACKLIGHT - unsupported * GDISP_CONTROL_CONTRAST - unsupported */ switch(g->p.x) { case GDISP_CONTROL_POWER: if (g->g.Powermode == (powermode_t)g->p.ptr) return; switch((powermode_t)g->p.ptr) { case powerOff: acquire_bus(g); write_index(g, SPFD54124B_CMD_SLPIN); release_bus(g); break; case powerOn: acquire_bus(g); write_index(g, SPFD54124B_CMD_SLPOUT); delayms(20); write_index(g, SPFD54124B_CMD_NORON); release_bus(g); break; case powerSleep: acquire_bus(g); write_index(g, SPFD54124B_CMD_SLPOUT); delayms(20); release_bus(g); break; default: return; } g->g.Powermode = (powermode_t)g->p.ptr; return; case GDISP_CONTROL_ORIENTATION: if (g->g.Orientation == (orientation_t)g->p.ptr) return; switch((orientation_t)g->p.ptr) { case GDISP_ROTATE_0: acquire_bus(g); write_index(g, SPFD54124B_CMD_MADCTR); write_index(g, 0x0100); release_bus(g); g->g.Height = GDISP_SCREEN_HEIGHT; g->g.Width = GDISP_SCREEN_WIDTH; break; case GDISP_ROTATE_90: acquire_bus(g); write_index(g, SPFD54124B_CMD_MADCTR); write_index(g, 0x01A0); release_bus(g); g->g.Height = GDISP_SCREEN_WIDTH; g->g.Width = GDISP_SCREEN_HEIGHT; break; case GDISP_ROTATE_180: acquire_bus(g); write_index(g, SPFD54124B_CMD_MADCTR); write_index(g, 0x01C0); release_bus(g); g->g.Height = GDISP_SCREEN_HEIGHT; g->g.Width = GDISP_SCREEN_WIDTH; break; case GDISP_ROTATE_270: acquire_bus(g); write_index(g, SPFD54124B_CMD_MADCTR); write_index(g, 0x0160); release_bus(g); g->g.Height = GDISP_SCREEN_WIDTH; g->g.Width = GDISP_SCREEN_HEIGHT; break; default: // GDISP_ROTATE_PORTRAIT and GDISP_ROTATE_LANDSCAPE are handled by the higher level code return; } g->g.Orientation = (orientation_t)g->p.ptr; return; } }
LLDSPEC void gdisp_lld_read_stop(GDisplay *g) { setwritemode(g); release_bus(g); }
LLDSPEC bool_t gdisp_lld_init(GDisplay *g) { uint16_t cver; // No private area for this controller g->priv = 0; // Initialise the board interface init_board(g); /* Hardware reset */ setpin_reset(g, TRUE); gfxSleepMicroseconds(1000); setpin_reset(g, FALSE); gfxSleepMicroseconds(1000); acquire_bus(g); write_index(g, 0); // Get controller version setreadmode(g); dummy_read(g); cver = read_data(g); setwritemode(g); /* initializing funciton */ write_reg(g, 0xe5,0x8000); /* Set the internal vcore voltage */ write_reg(g, 0x00,0x0001); /* start OSC */ write_reg(g, 0x2b,0x0010); /* Set the frame rate as 80 when the internal resistor is used for oscillator circuit */ write_reg(g, 0x01,0x0100); /* s720 to s1 ; G1 to G320 */ write_reg(g, 0x02,0x0700); /* set the line inversion */ write_reg(g, 0x03,0x1018); /* 65536 colors */ write_reg(g, 0x04,0x0000); write_reg(g, 0x08,0x0202); /* specify the line number of front and back porch periods respectively */ write_reg(g, 0x09,0x0000); write_reg(g, 0x0a,0x0000); write_reg(g, 0x0c,0x0000); /* select internal system clock */ write_reg(g, 0x0d,0x0000); write_reg(g, 0x0f,0x0000); write_reg(g, 0x50,0x0000); /* set windows adress */ write_reg(g, 0x51,0x00ef); write_reg(g, 0x52,0x0000); write_reg(g, 0x53,0x013f); write_reg(g, 0x60,0x2700); write_reg(g, 0x61,0x0001); write_reg(g, 0x6a,0x0000); write_reg(g, 0x80,0x0000); write_reg(g, 0x81,0x0000); write_reg(g, 0x82,0x0000); write_reg(g, 0x83,0x0000); write_reg(g, 0x84,0x0000); write_reg(g, 0x85,0x0000); write_reg(g, 0x90,0x0010); write_reg(g, 0x92,0x0000); write_reg(g, 0x93,0x0003); write_reg(g, 0x95,0x0110); write_reg(g, 0x97,0x0000); write_reg(g, 0x98,0x0000); /* power setting function */ write_reg(g, 0x10,0x0000); write_reg(g, 0x11,0x0000); write_reg(g, 0x12,0x0000); write_reg(g, 0x13,0x0000); gfxSleepMicroseconds(100); write_reg(g, 0x10,0x17b0); write_reg(g, 0x11,0x0004); gfxSleepMicroseconds(50); write_reg(g, 0x12,0x013e); gfxSleepMicroseconds(50); write_reg(g, 0x13,0x1f00); write_reg(g, 0x29,0x000f); gfxSleepMicroseconds(50); write_reg(g, 0x20,0x0000); write_reg(g, 0x21,0x0000); /* initializing function */ write_reg(g, 0x30,0x0204); write_reg(g, 0x31,0x0001); write_reg(g, 0x32,0x0000); write_reg(g, 0x35,0x0206); write_reg(g, 0x36,0x0600); write_reg(g, 0x37,0x0500); write_reg(g, 0x38,0x0505); write_reg(g, 0x39,0x0407); write_reg(g, 0x3c,0x0500); write_reg(g, 0x3d,0x0503); /* display on */ write_reg(g, 0x07,0x0173); gfxSleepMicroseconds(50); // Finish Init post_init_board(g); // Release the bus release_bus(g); // Turn on the backlight set_backlight(g, GDISP_INITIAL_BACKLIGHT); /* Initialise the GDISP structure */ g->g.Width = GDISP_SCREEN_WIDTH; g->g.Height = GDISP_SCREEN_HEIGHT; g->g.Orientation = GDISP_ROTATE_0; g->g.Powermode = powerOn; g->g.Backlight = GDISP_INITIAL_BACKLIGHT; g->g.Contrast = GDISP_INITIAL_CONTRAST; return TRUE; }
LLDSPEC bool_t gdisp_lld_init(GDisplay *g) { // No private area for this controller g->priv = 0; // Initialise the board interface init_board(g); // Hardware reset setpin_reset(g, TRUE); gfxSleepMilliseconds(20); setpin_reset(g, FALSE); gfxSleepMilliseconds(20); // Get the bus for the following initialisation commands acquire_bus(g); write_cmd(g, SSD1327_MAST_CODE); //Master code write_data(g, 0x00); write_cmd(g, SSD1327_SET_SLEEP_ON); // set display off write_cmd(g, SSD1327_SET_REMAP); write_data(g, 0x52); write_cmd(g, SSD1327_SET_DISPLAY_START); write_data(g, 0x00); write_cmd(g, SSD1327_SET_DISPLAY_OFFSET); write_data(g, 0x20); write_cmd(g, SSD1327_SET_DISPLAY_MODE_RESET); write_cmd(g, SSD1327_SET_MUX_RATIO); write_data(g, 0x5F); write_cmd(g, SSD1327_SET_FUNCTION_SELECT); write_data(g, 0x01); write_cmd(g, SSD1327_SET_CONTRAST); write_data(g, 0x5F); write_cmd(g, SSD1327_USE_LINEAR_GREY); write_cmd(g, SSD1327_SET_PHASE_LENGTH); write_data(g, 0x31); write_cmd(g, SSD1327_CLOCKDIV_OSCFREQ); write_data(g, 0x41); write_cmd(g, SSD1327_DISPLAY_ENHANCEMENT); write_data(g, 0xB5); write_cmd(g, SSD1327_SET_SECOND_PRECHARGE); write_data(g, 0x04); write_cmd(g, SSD1327_SET_PRECHARGE_VOLTAGE); write_data(g, 0x05); write_cmd(g, SSD1327_SET_VCOMH); write_data(g, 0x07); write_cmd(g, SSD1327_SET_FUNCTION_SELECT_B); write_data(g, 0x02); //i2c restart write_cmd(g, SSD1327_MAST_CODE); //Master code write_data(g, 0x00); write_cmd(g, SSD1327_SET_COLUMN_ADDRESS); //Master code write_data(g, 0x00); //COLUMN START write_data(g, 0x3F); //COLUMN END write_cmd(g, SSD1327_SET_ROW_ADDRESS); //Master code write_data(g, 0x00); //ROW START write_data(g, 0x7F); //ROW END write_cmd(g, SSD1327_MAST_CODE); //Master code write_data(g, 0x40); uint16_t i = 0; for (i = 0; i < 128*128; i++) { write_data(g, 0); } release_bus(g); // Finish Init post_init_board(g); // Release the bus // release_bus(g); /* Turn on the back-light */ set_backlight(g, GDISP_INITIAL_BACKLIGHT); /* Initialise the GDISP structure */ g->g.Width = GDISP_SCREEN_WIDTH; g->g.Height = GDISP_SCREEN_HEIGHT; g->g.Orientation = GDISP_ROTATE_0; g->g.Powermode = powerOn; g->g.Backlight = GDISP_INITIAL_BACKLIGHT; g->g.Contrast = GDISP_INITIAL_CONTRAST; return TRUE; }
LLDSPEC bool_t gdisp_lld_init(GDisplay *g) { // No private area for this controller g->priv = 0; // Initialise the board interface init_board(g); // Hardware reset setpin_reset(g, TRUE); gfxSleepMilliseconds(20); setpin_reset(g, FALSE); gfxSleepMilliseconds(20); // Get the bus for the following initialisation commands acquire_bus(g); // Soft reset write_reg8x2(g, 0x01, 0x01, 0x00); gfxSleepMilliseconds(1); // PLL config write_reg8(g, 0x88, 0x08); gfxSleepMilliseconds(1); write_reg8(g, 0x89, 0x02); gfxSleepMilliseconds(1); write_reg8(g, 0x10, 0x0F); //SYSR bit[4:3]=00 256 color bit[2:1]= 00 8bit MPU interface // 0x0F = 16bit MCU interface and 65k color display write_reg8(g, 0x04, 0x82); gfxSleepMilliseconds(1); //set PCLK inverse // Horizontal set write_reg8(g, 0x14, GDISP_SCREEN_WIDTH/8-1); //HDWR: Horizontal Display Width Setting Bit[6:0] - pixels = (HDWR + 1)*8 write_reg8(g, 0x15, 0x00); //Horizontal Non-Display Period Fine Tuning Option Register (HNDFTR) - HNDFT = [3:0] write_reg8(g, 0x16, 0x01); //HNDR: Horizontal Non-Display Period Bit[4:0] - pixels = (HNDR + 1)*8 write_reg8(g, 0x17, 0x00); //HSTR: HSYNC Start Position[4:0] - Position(PCLK) = (HSTR + 1)*8 write_reg8(g, 0x18, 0x05); //HPWR: HSYNC Polarity, The period width of HSYNC. Width [4:0] width(PCLK) = (HPWR + 1)*8 // Vertical set write_reg16(g, 0x19, GDISP_SCREEN_HEIGHT-1); //VDHR0,1: Vertical Display Height = VDHR + 1 write_reg16(g, 0x1b, 0x0002); //VNDR0,1: Vertical Non-Display Period Bit = (VSTR + 1) write_reg16(g, 0x1d, 0x0007); //VSTR0,1: VSYNC Start Position = (VSTR + 1) write_reg8(g, 0x1f, 0x09); //VPWR: VSYNC Polarity, VSYNC Pulse Width[6:0] - Width(PCLK) = (VPWR + 1) // Active window set write_reg16(g, 0x30, 0); //HSAW0 & HSAW1 write_reg16(g, 0x34, GDISP_SCREEN_WIDTH-1); //HEAW0 & HEAW1 write_reg16(g, 0x32, 0); //VSAW0 & VSAW1 write_reg16(g, 0x36, GDISP_SCREEN_HEIGHT-1); //VEAW0 & VEAW1 // Display ON write_reg8(g, 0x01, 0x80); //PWRR // GPO0 DISP high write_reg8(g, 0x13, 0x01); //GPO // Set initial back-light set_backlight(g, GDISP_INITIAL_BACKLIGHT); // Change timings for faster access post_init_board(g); // Release the bus release_bus(g); /* Initialise the GDISP structure */ g->g.Width = GDISP_SCREEN_WIDTH; g->g.Height = GDISP_SCREEN_HEIGHT; g->g.Orientation = GDISP_ROTATE_0; g->g.Powermode = powerOn; g->g.Backlight = GDISP_INITIAL_BACKLIGHT; g->g.Contrast = GDISP_INITIAL_CONTRAST; return TRUE; }