Ejemplo n.º 1
0
void lcd_begin_frame()
{
    uint8_t flags = vram.flags;
    uint8_t mode = vram.mode;

    lcd_window_x = 0;
    lcd_window_y = vram.first_line;

    /*
     * Wake up the LCD controller, if necessary.
     */
    if (!lcd_is_awake) {
        lcd_is_awake = 1;
        
        // First, we take the LCD controller out of reset.
        // Then we fully initialize it. We turn on the backlight
        // after both initialization is complete and the first
        // frame has finished rendering.

        CTRL_PORT = CTRL_IDLE & ~CTRL_LCD_DCX;
        CTRL_PORT = (CTRL_IDLE & ~CTRL_LCD_DCX) | CTRL_FLASH_LAT2;  // Enter reset

        lcd_reset_delay();

        CTRL_PORT = CTRL_IDLE;
        CTRL_PORT = CTRL_IDLE | CTRL_FLASH_LAT2;  // Exit reset
        
        // Controller initialization
        lcd_cmd_table(lcd_setup_table);
        #ifdef LCD_MODEL_TIANMA_HX8353
        lcd_lut_init();
        #endif
    }

    LCD_WRITE_BEGIN();

    // Set addressing mode
    LCD_CMD_MODE();
    LCD_BYTE(LCD_CMD_MADCTR);
    LCD_DATA_MODE();
    LCD_BYTE(LCD_MADCTR_NORMAL ^ (flags & LCD_MADCTR_VRAM));

    // Set row/column addressing, and start RAMWR.
    lcd_address_and_write();

    LCD_WRITE_END();

    // Vertical sync
    #ifdef HAVE_LCD_TE
    if (flags & _SYS_VF_SYNC)
        while (!CTRL_LCD_TE);
    #endif
}    
Ejemplo n.º 2
0
void lcd_lut_init()
{
    /*
     * The HX8353 seems to boot up with a totally bogus color LUT.
     * So, we need to set it ourselves.
     */
     
    LCD_WRITE_BEGIN();
    LCD_CMD_MODE();
    LCD_BYTE(LCD_CMD_COLOR_LUT);
    LCD_DATA_MODE();
    
    lcd_lut_32();   // Red
    lcd_lut_64();   // Green
    lcd_lut_32();   // Blue

    // It's okay to return in write mode.
}
Ejemplo n.º 3
0
/* 
**
** low level routine to send a byte value 
** to the LCD controller control register. 
** entry argument is the data to output 
** and the controller to use
** 1: IC 1, 2: IC 2, 3: both ICs
**
*/
void lcd_out_ctl(const unsigned char cmd, const unsigned char ncontr)
 { LCD_CMD_MODE();
   LCDDATAPORT = cmd;
   lcd_strobe_e(ncontr);
 }
Ejemplo n.º 4
0
void lcd_address_and_write(void)
{
    /*
     * Change the row/column address, and start a RAMWR command.
     *
     * Assumes we're already set up for writing to the LCD.
     * Leaves with the bus in data mode.
     *
     * In the case that HAVE_GRAM_PANEL_MISMATCH is defined,
     * we must calculate the appropriate values for CASET and RASET
     * based on the current VRAM flags configuration as follows:
     *
     * x_offset = (flags & LCD_MADCTR_MX) ? LCD_X_RIGHT_MARGIN : LCD_X_LEFT_MARGIN
     * y_offset = (flags & LCD_MADCTR_MY) ? LCD_Y_BOTTOM_MARGIN : LCD_Y_TOP_MARGIN
     * if (flags & LCD_MADCTR_MV) {
     *   col_offset = y_offset
     *   row_offset = x_offset
     * } else {
     *   col_offset = x_offset
     *   row_offset = y_offset
     * }
     *
     * Some graphics modes constrain the registers we can use
     * to implement this - we can only touch b, r0 and r1,
     * because of the requirements in vm_stamp_pixel(),
     * by way of vm_fb32_pixel(). Otherwise, we'd be happy
     * to implement this in C.
     */

#ifdef HAVE_GRAM_PANEL_MISMATCH
    __asm
        push    acc
        push    dpl
        push    dph

    ; vram.flags in a
        mov     dptr, #_SYS_VA_FLAGS
        movx    a, @dptr

    ; select y_margin based on LCD_MADCTR_MY and save in b
        jnb     acc.7, 1$   ; flags & LCD_MADCTR_MY
        mov     b, #LCD_Y_BOTTOM_MARGIN
        sjmp    2$
1$:
        mov     b, #LCD_Y_TOP_MARGIN

2$:
    ; col_offset in r1 and row_offset in r0, based on LCD_MADCTR_MV.
    ; XXX: because the X margins are both the same for the Santek,
    ;       we shortcut the test of LCD_MADCTR_MX, since currently
    ;       more code space is required to enable this test.
        jnb     acc.5, 3$   ; flags & LCD_MADCTR_MV
        mov     r1, b
        mov     r0, #LCD_X_RIGHT_MARGIN
        sjmp    4$
3$:
        mov     r1, #LCD_X_LEFT_MARGIN
        mov     r0, b

4$:
        ASM_LCD_CMD_MODE();
        ASM_LCD_BYTE(#LCD_CMD_CASET);
        ASM_LCD_DATA_MODE();
        ASM_LCD_BYTE(#0x0);
        mov     a, _lcd_window_x
        add     a, r1
        ASM_LCD_BYTE(a);
        ASM_LCD_BYTE(#0x0);
        mov     a, #(LCD_WIDTH - 1)
        add     a, r1
        ASM_LCD_BYTE(a);

        ASM_LCD_CMD_MODE();
        ASM_LCD_BYTE(#LCD_CMD_RASET);
        ASM_LCD_DATA_MODE();
        ASM_LCD_BYTE(#0x0);
        mov     a, _lcd_window_y
        add     a, r0
        ASM_LCD_BYTE(a);
        ASM_LCD_BYTE(#0x0);
        mov     a, #(LCD_HEIGHT - 1)
        add     a, r0
        ASM_LCD_BYTE(a);

        ; assumption: dptr and a are not touched below
        pop     dph
        pop     dpl
        pop     acc

    __endasm;
#else
    LCD_CMD_MODE();
    LCD_BYTE(LCD_CMD_CASET);
    LCD_DATA_MODE();
    LCD_BYTE(0);
    LCD_BYTE((lcd_window_x));
    LCD_BYTE(0);
    LCD_BYTE((LCD_WIDTH - 1));

    LCD_CMD_MODE();
    LCD_BYTE(LCD_CMD_RASET);
    LCD_DATA_MODE();
    LCD_BYTE(0);
    LCD_BYTE((lcd_window_y));
    LCD_BYTE(0);
    LCD_BYTE((LCD_HEIGHT - 1));
#endif

    /*
     * Start writing (RAMWR command).
     *
     * We have to do this particular command -> data transition
     * somewhat gingerly, since the Truly LCD is really picky. If we
     * transition from command to data while the write strobe is low,
     * it will falsely detect that as an additional byte-write that we
     * didn't intend.
     *
     * This paranoia is unnecessary but harmless on the Giantplus LCD.
     */

    LCD_CMD_MODE();
    LCD_BYTE(LCD_CMD_NOP);
    ADDR_PORT = 1;
    LCD_BYTE(LCD_CMD_RAMWR);
    LCD_DATA_MODE();
}