| /* 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; | 
 | } | 
 |  | 
 | #ifdef CONFIG_SHOW_ACTIVITY | 
 | void board_show_activity (ulong timestamp) | 
 | { | 
 | #ifdef CONFIG_STATUS_LED | 
 | 	if ((timestamp % (CFG_HZ / 2) == 0) | 
 | 		lcd_heartbeat (); | 
 | #endif | 
 | } | 
 |  | 
 | void show_activity(int arg) | 
 | { | 
 | } | 
 | #endif |