예제 #1
0
/*
 * lcd_an_write_register
 * @lcd: LCD driver on which a byte is needed to be written.
 * @rs: Flag to specify if we are writing a data register or command register.
 *  TRUE: If we need to write a data register.
 *  FALSE: If we need to write a command register.
 * @byte: Byte needed to be written.
 * @return: Success will be returned if bytes was successfully written
 *  LCD_AN_TIME_OUT will be returned if timed out waiting for LCD.
 * This function write a register to the LCD.
 */
static int32_t lcd_an_write_register(LCD_AN *lcd, uint8_t rs, uint8_t byte)
{
#ifndef LCD_AN_NO_BUSY_WAIT
    uint8_t cmd_byte;
    uint32_t sys_time = current_system_tick();
#endif /* LCD_AN_NO_BUSY_WAIT */
    int32_t status = SUCCESS;

#ifndef LCD_AN_NO_BUSY_WAIT
    /* Wait for LCD. */
    do
    {
        /* Read command register. */
        lcd_an_read_register(lcd, FALSE, &cmd_byte);

        /* If we are still busy. */
        if (cmd_byte & (1 << 7))
        {
            /* Yield the task. */
            task_yield();
        }

    } while ((current_system_tick() - sys_time) < (MS_TO_TICK(LCD_AN_BUSY_TIMEOUT)) && (cmd_byte & (1 << 7)));

    /* If we did not timeout waiting for the LCD. */
    if (((cmd_byte & (1 << 7)) == 0) || (rs & LCD_IGNORE_WAIT))
#endif /* LCD_AN_NO_BUSY_WAIT */
    {
        /* Select required register. */
        if (rs & LCD_DATA_REG)
        {
            /* Select data register. */
            lcd->set_rs(lcd);
        }
        else
        {
            /* Select command register. */
            lcd->clr_rs(lcd);
        }

        /* We are writing data. */
        lcd->clr_rw(lcd);

        /* Disable the LCD data line. */
        lcd->clr_en(lcd);

        /* Put byte on the LCD. */
        lcd_an_send_nibble(lcd, ((byte >> 4) & 0x0F));
        lcd_an_send_nibble(lcd, (byte & 0x0F));

#ifdef LCD_AN_NO_BUSY_WAIT
        /* Yield the task to put delay in transaction.. */
        task_yield();
#else
    }
    else
    {
예제 #2
0
/*
 * lcd_an_write_register
 * @lcd: LCD driver on which a byte is needed to be written.
 * @rs: Flag to specify if we are writing a data register or command register.
 *  TRUE: If we need to write a data register.
 *  FALSE: If we need to write a command register.
 * @byte: Byte needed to be written.
 * @return: Success will be returned if bytes was successfully written
 *  LCD_AN_TIME_OUT will be returned if timed out waiting for LCD.
 * This function write a register to the LCD.
 */
int32_t lcd_an_write_register(LCD_AN *lcd, uint8_t rs, uint8_t byte)
{
    uint8_t cmd_byte = 0xFF;
    uint64_t sys_time = current_system_tick();
    int32_t status = SUCCESS;

    /* Wait for LCD. */
    while ((current_system_tick() - sys_time) < (MS_TO_TICK(LCD_AN_BUSY_TIMEOUT)) &&
           (cmd_byte & (1 << 7)))
    {
        /* Read command register. */
        lcd_an_read_register(lcd, FALSE, &cmd_byte);

        /* If we are still busy. */
        if (cmd_byte & (1 << 7))
        {
            /* Yield the task. */
            task_yield();
        }
    }

    /* If we did not timeout waiting for the LCD. */
    if ((cmd_byte & (1 << 7)) == 0)
    {
        /* Select required register. */
        if (rs == TRUE)
        {
            /* Select data register. */
            LCD_AN_TGT_SET_RS(lcd);
        }
        else
        {
            /* Select command register. */
            LCD_AN_TGT_CLR_RS(lcd);
        }

        /* We are writing data. */
        LCD_AN_TGT_CLR_RW(lcd);

        /* Disable the LCD data line. */
        LCD_AN_TGT_CLR_EN(lcd);

        /* Put byte on the LCD. */
        lcd_an_send_nibble(lcd, ((byte >> 4) & 0x0F));
        lcd_an_send_nibble(lcd, (byte & 0x0F));

    }
    else
    {
예제 #3
0
/*
 * lcd_an_register
 * @lcd: LCD data.
 * This function will register a LCD driver.
 */
void lcd_an_register(LCD_AN *lcd)
{
    int32_t status = SUCCESS;

    /* Initialize LCD. */
    LCD_AN_TGT_CLR_RS(lcd);
    LCD_AN_TGT_SET_RW(lcd);
    LCD_AN_TGT_CLR_EN(lcd);

#if (LCD_AN_INIT_DELAY > 0)
    /* Need to wait at least 15ms on power up. */
    sleep_ms(LCD_AN_INIT_DELAY);
#endif

    /* Send first 0x3. */
    lcd_an_send_nibble(lcd, 0x3);

    /* Controller still think that we are using 8bit mode so we can still read
     * the status bit. */
    status = lcd_an_wait_8bit(lcd);

    if (status == SUCCESS)
    {
        /* Send second 0x3. */
        LCD_AN_TGT_CLR_RW(lcd);
        lcd_an_send_nibble(lcd, 0x3);

        /* Wait for LCD to process the command in 8 bit mode. */
        status = lcd_an_wait_8bit(lcd);
    }

    if (status == SUCCESS)
    {
        /* Send third 0x3. */
        LCD_AN_TGT_CLR_RW(lcd);
        lcd_an_send_nibble(lcd, 0x3);

        /* Wait for LCD to process the command in 8 bit mode. */
        status = lcd_an_wait_8bit(lcd);
    }

    if (status == SUCCESS)
    {
        /* Switch to 4-bit mode. */
        LCD_AN_TGT_CLR_RW(lcd);
        lcd_an_send_nibble(lcd, 0x2);

        /* Wait for LCD to process the command in 8 bit mode. */
        status = lcd_an_wait_8bit(lcd);
    }

    /* LCD configuration. */
    if (status == SUCCESS)
    {
        status = lcd_an_write_register(lcd, FALSE, 0x28);
    }

    if (status == SUCCESS)
    {
        status = lcd_an_write_register(lcd, FALSE, 0x28);
    }

    if (status == SUCCESS)
    {
        status = lcd_an_write_register(lcd, FALSE, 0x08);
    }

    if (status == SUCCESS)
    {
        status = lcd_an_write_register(lcd, FALSE, 0x01);

#if (LCD_AN_CLEAR_DELAY > 0)
        /* Wait for sometime before writing any more data. */
        sleep_ms(LCD_AN_CLEAR_DELAY);
#endif
    }

    if (status == SUCCESS)
    {
        status = lcd_an_write_register(lcd, FALSE, 0x06);
    }

    if (status == SUCCESS)
    {
        status = lcd_an_write_register(lcd, FALSE, 0x0C);
    }

    if (status == SUCCESS)
    {
        /* Reset the cursor location. */
        lcd->cur_column = lcd->cur_row = 0;

        /* Register this LCD driver with console. */
        lcd->console.fs.write = &lcd_an_write;
        lcd->console.fs.ioctl = &lcd_an_ioctl;
        console_register(&lcd->console);

        /* There is always some space available for data to be sent. */
        lcd->console.fs.flags |= FS_SPACE_AVAILABLE;

#ifdef LCD_AN_DEBUG
        lcd_an_fd = fs_open("\\console\\lcd1", 0);

        /* Connect LCD with debug console. */
        fs_connect(lcd_an_fd, debug_fd);
#endif
    }

} /* lcd_an_register */