## LCD

Support for classic HD-44780 based LCD display, in 4 bit unidirectional mode. This kind of interface needs 6 lines (`data4/data5/data6/data7` , `RS` and `E`). Since version `0.5.3` the LCD library is configurable to allow any connection to the target device. It provides for this purpose the following macros:

- `CONFIGURE_LCD_RS(PORTx , pin) ;`
- `CONFIGURE_LCD_E(PORTx , pin) ;`
- `CONFIGURE_LCD_DATA4(PORTx , pin) ;`
- `CONFIGURE_LCD_DATA5(PORTx , pin) ;`
- `CONFIGURE_LCD_DATA6(PORTx , pin) ;`
- `CONFIGURE_LCD_DATA7(PORTx , pin) ;`

Despite the fact this library is written in assembly language, the configuration can be done from the C code: just put the macro invocations somewhere in the `main()` function. For example:

       // command/data selection pin
       CONFIGURE_LCD_RS(PORTB, 5) ;
       // enable pin
       CONFIGURE_LCD_E(PORTB, 4) ;
       // data pins used in 4 bit mode
       CONFIGURE_LCD_DATA4(PORTA, 0) ;
       CONFIGURE_LCD_DATA5(PORTA, 1) ;
       CONFIGURE_LCD_DATA6(PORTA, 2) ;
       CONFIGURE_LCD_DATA7(PORTA, 3) ;

The following are low level functions, but LCD display can also be used from hi-level functions (such as `outdec()` or `printf()`), if the proper output redirection is programmed.

1. `void lcd_init(int delay) ;`

   Initialize the LCD display. The `delay` parameter is used by internal temporisation loops. Delay depends on LCD display capabilities and device clock. The following values work for me.

   CPU frequency | delay
   4Mhz | 8
   8Mhz | 15
   16Mhz | 30
   32Mhz | 60
   40Mhz | 75

2. `void lcd_init_Mhz(int Mhz) ;`

   This is a macro, provided for convenience as an alternative to `void lcd_init(int delay)`. The Mhz parameter is simply the clock frequency (in Mhz) of the target processor.

3. `void lcd_putchar(char c);`

   Displays character `c` at current cursor position. This function can be used as the parameter of `set_output()` to redirect outputs to the LCD display.

4. `void lcd_move(int pos) ;`

   Moves cursor to `pos` position. Coordinate system depends on LCD type. The following function allows to compute the cursor position for most classic flavors of LCD displays. Note that this function is not part of the library.

       // number of columns (16, 20 or 24)
       #define LCD_COLS 20

       uint8_t lcd_cursor_addr( uint8_t line,  uint8_t col)
       {
       #if LCD_COLS == 16
          static uint8_t laddrtab[4] = { 0x0, 0x40 , 0x10, 0x50 } ;
       #elif LCD_COLS == 20
          static uint8_t laddrtab[4] = { 0x0, 0x40 , 0x14, 0x54 } ;
       #elif LCD_COLS == 24
          static  uint8_t laddrtab[4] = { 0x0, 0x20 , 0x40, 0x60 } ;
       #else
          #error "LCD_COLS should be either 16 20 or 24"
       #endif
          return   laddrtab[line]+ col ;
       }

5. `void lcd_clear() ;`

   Erases display.

6. `void lcd_hex4(unsigned int c) ;`

   Displays low nibble of `c`, as an hexadecimal digit.

7. void `lcd_define_char(char c,char bitmap[8]) ;`

   Defines a new character with code `c`.

   Definable character codes range from 0 to 7, and the character matrix is 5x8 pixels large. `bitmap` array is an image of the character, each array's element corresponding to one line of the matrix.

8. `void lcd_hex8(unsigned int c) ;`

   Displays `c` as two hex digits.

9. `void lcd_hex16(unsigned long n) ;`

   Displays `n` as four hex digits.

10. `void lcd_puts(char *s) ;`

    Displays a nul-terminated character string.

11. `void lcd_Rputs(ROMptr s) ;`

    Displays a nul-terminated character string pointed to by rom pointer p. Please see section 10.8 for details about data in ROM.

12. `void lcd_RIputs(ROM literal) ;`

    Displays a nul-terminated character string defined by an immediate rom literal. Please see section 10.8 for details about data in ROM.

13. `void lcd_putcmd(char cmd) ;`

    Enters command mode, then send command `cmd` to LCD display. This function can be used to access more advanced functionnalities of the LCD display.