/* most of this is taken from the file */
/* hal/powerpc/cogent/current/src/hal_diag.c in the */
/* Cygnus eCos source. Here is the copyright notice: */
/* */
/*============================================================================= */
/* */
/*      hal_diag.c */
/* */
/*      HAL diagnostic output code */
/* */
/*============================================================================= */
/*####COPYRIGHTBEGIN#### */
/* */
/* ------------------------------------------- */
/* The contents of this file are subject to the Cygnus eCos Public License */
/* Version 1.0 (the "License"); you may not use this file except in */
/* compliance with the License.  You may obtain a copy of the License at */
/* http://sourceware.cygnus.com/ecos */
/* */
/* Software distributed under the License is distributed on an "AS IS" */
/* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the */
/* License for the specific language governing rights and limitations under */
/* the License. */
/* */
/* The Original Code is eCos - Embedded Cygnus Operating System, released */
/* September 30, 1998. */
/* */
/* The Initial Developer of the Original Code is Cygnus.  Portions created */
/* by Cygnus are Copyright (C) 1998,1999 Cygnus Solutions.  All Rights Reserved. */
/* ------------------------------------------- */
/* */
/*####COPYRIGHTEND#### */
/*============================================================================= */
/*#####DESCRIPTIONBEGIN#### */
/* */
/* Author(s):    nickg, jskov */
/* Contributors: nickg, jskov */
/* Date:         1999-03-23 */
/* Purpose:      HAL diagnostic output */
/* Description:  Implementations of HAL diagnostic output support. */
/* */
/*####DESCRIPTIONEND#### */
/* */
/*============================================================================= */

/*----------------------------------------------------------------------------- */
/* Cogent board specific LCD code */

#include <common.h>
#include <stdarg.h>
#include <board/cogent/lcd.h>

static char lines[2][LCD_LINE_LENGTH+1];
static int curline;
static int linepos;
static int heartbeat_active;
/* make the next two strings exactly LCD_LINE_LENGTH (16) chars long */
/* pad to the right with spaces if necessary */
static char init_line0[LCD_LINE_LENGTH+1] = "U-Boot Cogent  ";
static char init_line1[LCD_LINE_LENGTH+1] = "mjj, 11 Aug 2000";

static inline unsigned char
lcd_read_status(cma_mb_lcd *clp)
{
    /* read the Busy Status Register */
    return (cma_mb_reg_read(&clp->lcd_bsr));
}

static inline void
lcd_wait_not_busy(cma_mb_lcd *clp)
{
    /*
     * wait for not busy
     * Note: It seems that the LCD isn't quite ready to process commands
     * when it clears the BUSY flag. Reading the status address an extra
     * time seems to give it enough breathing room.
     */

    while (lcd_read_status(clp) & LCD_STAT_BUSY)
	;

    (void)lcd_read_status(clp);
}

static inline void
lcd_write_command(cma_mb_lcd *clp, unsigned char cmd)
{
    lcd_wait_not_busy(clp);

    /* write the Command Register */
    cma_mb_reg_write(&clp->lcd_cmd, cmd);
}

static inline void
lcd_write_data(cma_mb_lcd *clp, unsigned char data)
{
    lcd_wait_not_busy(clp);

    /* write the Current Character Register */
    cma_mb_reg_write(&clp->lcd_ccr, data);
}

static inline void
lcd_dis(int addr, char *string)
{
    cma_mb_lcd *clp = (cma_mb_lcd *)CMA_MB_LCD_BASE;
    int pos, linelen;

    linelen = LCD_LINE_LENGTH;
    if (heartbeat_active && addr == LCD_LINE0)
	linelen--;

    lcd_write_command(clp, LCD_CMD_ADD + addr);
    for (pos = 0; *string != '\0' && pos < linelen; pos++)
        lcd_write_data(clp, *string++);
}

void
lcd_init(void)
{
    cma_mb_lcd *clp = (cma_mb_lcd *)CMA_MB_LCD_BASE;
    int i;

    /* configure the lcd for 8 bits/char, 2 lines and 5x7 dot matrix */
    lcd_write_command(clp, LCD_CMD_MODE);

    /* turn the LCD display on */
    lcd_write_command(clp, LCD_CMD_DON);

    curline = 0;
    linepos = 0;

    for (i = 0; i < LCD_LINE_LENGTH; i++) {
        lines[0][i] = init_line0[i];
	lines[1][i] = init_line1[i];
    }

    lines[0][LCD_LINE_LENGTH] = lines[1][LCD_LINE_LENGTH] = 0;

    lcd_dis(LCD_LINE0, lines[0]);
    lcd_dis(LCD_LINE1, lines[1]);

    printf("HD44780 2 line x %d char display\n", LCD_LINE_LENGTH);
}

void
lcd_write_char(const char c)
{
    int i, linelen;

    /* ignore CR */
    if (c == '\r')
	return;

    linelen = LCD_LINE_LENGTH;
    if (heartbeat_active && curline == 0)
	linelen--;

    if (c == '\n') {
        lcd_dis(LCD_LINE0, &lines[curline^1][0]);
        lcd_dis(LCD_LINE1, &lines[curline][0]);

        /* Do a line feed */
        curline ^= 1;
	linelen = LCD_LINE_LENGTH;
	if (heartbeat_active && curline == 0)
	    linelen--;
        linepos = 0;

        for (i = 0; i < linelen; i++)
            lines[curline][i] = ' ';

        return;
    }

    /* Only allow to be output if there is room on the LCD line */
    if (linepos < linelen)
        lines[curline][linepos++] = c;
}

void
lcd_flush(void)
{
    lcd_dis(LCD_LINE1, &lines[curline][0]);
}

void
lcd_write_string(const char *s)
{
    char *p;

    for (p = (char *)s; *p != '\0'; p++)
	lcd_write_char(*p);
}

void
lcd_printf(const char *fmt, ...)
{
    va_list args;
    char buf[CFG_PBSIZE];

    va_start(args, fmt);
    (void)vsprintf(buf, fmt, args);
    va_end(args);

    lcd_write_string(buf);
}

void
lcd_heartbeat(void)
{
    cma_mb_lcd *clp = (cma_mb_lcd *)CMA_MB_LCD_BASE;
#if 0
    static char rotchars[] = { '|', '/', '-', '\\' };
#else
    /* HD44780 Rom Code A00 has no backslash */
    static char rotchars[] = { '|', '/', '-', '\315' };
#endif
    static int rotator_index = 0;

    heartbeat_active = 1;

    /* write the address */
    lcd_write_command(clp, LCD_CMD_ADD + LCD_LINE0 + (LCD_LINE_LENGTH - 1));

    /* write the next char in the sequence */
    lcd_write_data(clp, rotchars[rotator_index]);

    if (++rotator_index >= (sizeof rotchars / sizeof rotchars[0]))
	rotator_index = 0;
}
