-/*!
+/**
* \file
* <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
* Copyright 2005 Develer S.r.l. (http://www.develer.com/)
- * This file is part of DevLib - See README.devlib for information.
+ *
* -->
*
* \brief LM044L type LCD hardware module (impl.)
/*#*
*#* $Log$
+ *#* Revision 1.5 2007/10/01 18:59:27 batt
+ *#* Set to const col_address; add static assert check on array dimension.
+ *#*
+ *#* Revision 1.4 2007/10/01 10:46:09 batt
+ *#* Add light LCD position computation.
+ *#*
+ *#* Revision 1.3 2006/09/20 19:55:01 marco
+ *#* Added CONFIG_LCD_4BIT.
+ *#*
+ *#* Revision 1.2 2006/07/19 12:56:25 bernie
+ *#* Convert to new Doxygen style.
+ *#*
*#* Revision 1.1 2005/11/04 18:00:42 bernie
*#* Import into DevLib.
*#*
*#*/
#include "lcd_hd44.h"
-#include "lcd_bus_pz.h"
-#include <arch_config.h>
+#include "hw_lcd.h"
+#include <cfg/arch_config.h>
#include <drv/timer.h>
#if defined(LCD_READ_H) && defined(LCD_READ_L) && defined(LCD_WRITE_H) && defined(LCD_WRITE_L)
#error Incomplete or missing LCD_READ/LCD_WRITE macros
#endif
-/*! Flag di stato del display */
+/** Flag di stato del display */
#define LCDF_BUSY BV(7)
-/*!
+#if CONFIG_LCD_ADDRESS_FAST == 1
+#define lcd_address(x) lcd_address[x]
+/**
* Addresses of LCD display character positions, expanded
* for faster access (DB7 = 1).
*/
};
STATIC_ASSERT(countof(lcd_address) == LCD_ROWS * LCD_COLS);
+#else /* CONFIG_LCD_ADDRESS_FAST == 0 */
-/*!
+static const uint8_t col_address[] =
+{
+ 0x80,
+ 0xC0,
+#if LCD_ROWS > 2
+ 0x94,
+ 0xD4
+#endif
+};
+STATIC_ASSERT(countof(col_address) == LCD_ROWS);
+/**
+ * Addresses of LCD display character positions, calculated runtime to save RAM
+ */
+static uint8_t lcd_address(uint8_t addr)
+{
+ return col_address[addr / LCD_COLS] + addr % LCD_COLS;
+}
+#endif /* CONFIG_LCD_ADDRESS_FAST */
+
+/**
* Current display position. We remember this to optimize
* LCD output by avoiding to set the address every time.
*/
/* Read data */
LCD_SET_E;
LCD_DELAY_READ;
- data |= LCD_READ;
+ data = LCD_READ;
LCD_CLR_E;
LCD_DELAY_READ;
#endif /* ARCH_EMUL */
-/*!
+/**
* Wait until the LCD busy flag clears.
*/
void lcd_waitBusy(void)
}
-/*!
+/**
* Move the cursor to \a addr, only if not already there.
*/
void lcd_moveTo(uint8_t addr)
if (addr != lcd_current_addr)
{
lcd_waitBusy();
- lcd_regWrite(lcd_address[addr]);
+ lcd_regWrite(lcd_address(addr));
lcd_current_addr = addr;
}
}
-/*!
+/**
* Write a value in LCD data register, waiting for the busy flag.
*/
void lcd_setReg(uint8_t val)
}
#include <cfg/debug.h>
-/*!
+/**
* Write the character \a c on display address \a addr.
*
* NOTE: argh, the HD44 lcd type is a bad beast: our
void lcd_putc(uint8_t addr, uint8_t c)
{
if (addr != lcd_current_addr)
- lcd_setReg(lcd_address[addr]);
+ lcd_setReg(lcd_address(addr));
lcd_waitBusy();
lcd_dataWrite(c);
/* If we are at the end of a row put the cursor at the beginning of the next */
if (!(lcd_current_addr % LCD_COLS))
- lcd_setReg(lcd_address[lcd_current_addr]);
+ lcd_setReg(lcd_address(lcd_current_addr));
}
-/*!
+/**
* Remap the glyph of a character.
*
* glyph - bitmap of 8x8 bits.
}
/* Move back to original address */
- lcd_setReg(lcd_address[lcd_current_addr]);
+ lcd_setReg(lcd_address(lcd_current_addr));
}
lcd_regWrite(LCD_CMD_CLEAR);
timer_delay(2);
- //lcd_regWrite(LCD_CMD_RESET_DDRAM); 4 bit mode doesn't allow char reprogramming
-
+#if !CONFIG_LCD_4BIT
+ lcd_regWrite(LCD_CMD_RESET_DDRAM); // 4 bit mode doesn't allow char reprogramming
+#endif
lcd_regWrite(LCD_CMD_DISPLAYMODE);
timer_delay(2);
}