| 359 | kaklik | 1 |   | 
        
           |  |  | 2 | /****************************************************************************
 | 
        
           |  |  | 3 |  Title  :   C  file for the HD44780U LCD library (lcd_io.c)
 | 
        
           |  |  | 4 |  Author:    Chris efstathiou hendrix@otenet.gr
 | 
        
           |  |  | 5 |  Date:      1/Jul/2002
 | 
        
           |  |  | 6 |  Software:  AVR-GCC with AVR-AS
 | 
        
           |  |  | 7 |  Target:    any AVR device
 | 
        
           |  |  | 8 |  Comments:  This software is FREE.
 | 
        
           |  |  | 9 |   | 
        
           |  |  | 10 | *****************************************************************************/
 | 
        
           |  |  | 11 | #ifndef _IO_REG_MACRO_MODE_
 | 
        
           |  |  | 12 | #define _IO_REG_MACRO_MODE_  1     /* In case you have the new assignment mode io headers */
 | 
        
           |  |  | 13 | #endif
 | 
        
           |  |  | 14 |   | 
        
           |  |  | 15 | #ifndef  _SFR_ASM_COMPAT
 | 
        
           |  |  | 16 | #define  _SFR_ASM_COMPAT     1     /* This is for GCC 3.2 */
 | 
        
           |  |  | 17 | #endif
 | 
        
           |  |  | 18 |   | 
        
           |  |  | 19 | #include <io.h>
 | 
        
           |  |  | 20 | #include <progmem.h>
 | 
        
           |  |  | 21 | #include <eeprom.h>
 | 
        
           |  |  | 22 | #include "lcd_io.h"
 | 
        
           |  |  | 23 |   | 
        
           |  |  | 24 | /* constants/macros */
 | 
        
           |  |  | 25 | #ifndef CONCAT1
 | 
        
           |  |  | 26 | #define CONCAT1(a, b) CONCAT2(a, b)
 | 
        
           |  |  | 27 | #endif
 | 
        
           |  |  | 28 |   | 
        
           |  |  | 29 | #ifndef CONCAT2
 | 
        
           |  |  | 30 | #define CONCAT2(a, b) a ## b
 | 
        
           |  |  | 31 | #endif
 | 
        
           |  |  | 32 |   | 
        
           |  |  | 33 | #define LCD_POWER_ON_DELAY ( (20000*(F_CPU/60000))/100 )    /* 20 milliseconds */
 | 
        
           |  |  | 34 | #define LCD_INIT_DELAY     ( (5000*(F_CPU/60000))/100 )     /* 5 milliseconds */
 | 
        
           |  |  | 35 |   | 
        
           |  |  | 36 | #define INIT_MODE   2
 | 
        
           |  |  | 37 | #define DATA_MODE   1
 | 
        
           |  |  | 38 | #define CMD_MODE    0
 | 
        
           |  |  | 39 |   | 
        
           |  |  | 40 |   | 
        
           |  |  | 41 | /* CONVERSION OF LCD_DELAY_TIME TO TRUE MICROSECONDS */
 | 
        
           |  |  | 42 | #if LCD_READ_REQUIRED == 0 || LCD_IO_MODE == 2 || LCD_IO_MODE == 7
 | 
        
           |  |  | 43 | #define LCD_DELAY_SHORT ( (LCD_DELAY_TIME*(F_CPU/60000))/100 )
 | 
        
           |  |  | 44 | #define LCD_DELAY_LONG  ( LCD_DELAY_SHORT*40 )
 | 
        
           |  |  | 45 | #endif
 | 
        
           |  |  | 46 |   | 
        
           |  |  | 47 |   | 
        
           |  |  | 48 |   | 
        
           |  |  | 49 | /*######################################################################################################*/
 | 
        
           |  |  | 50 | #if LCD_IO_MODE == 2
 | 
        
           |  |  | 51 | /*######################################################################################################*/
 | 
        
           |  |  | 52 |   | 
        
           |  |  | 53 | #define LCD_DATA_PORT_IS_IO   1
 | 
        
           |  |  | 54 | #define LCD_CLOCK_PORT_IS_IO  1
 | 
        
           |  |  | 55 |   | 
        
           |  |  | 56 | #define LCD_DATA_PORT         CONCAT1(PORT,LCD_DATA_SIGNAL_PORT)
 | 
        
           |  |  | 57 | #define LCD_DATA_DDR_REG      CONCAT1(DDR,LCD_DATA_SIGNAL_PORT)
 | 
        
           |  |  | 58 |   | 
        
           |  |  | 59 | #define LCD_CLOCK_PORT        CONCAT1(PORT,LCD_CLOCK_SIGNAL_PORT) 
 | 
        
           |  |  | 60 | #define LCD_CLOCK_DDR_REG     CONCAT1(DDR,LCD_CLOCK_SIGNAL_PORT) 
 | 
        
           |  |  | 61 |   | 
        
           |  |  | 62 | #define LCD_READ_REQUIRED 0
 | 
        
           |  |  | 63 |   | 
        
           |  |  | 64 |   | 
        
           |  |  | 65 |   | 
        
           |  |  | 66 | #if defined(__AVR_ATmega103__)
 | 
        
           |  |  | 67 |   | 
        
           |  |  | 68 | #if LCD_DATA_PORT == PORTC 
 | 
        
           |  |  | 69 | #undef  LCD_DATA_PORT_IS_IO
 | 
        
           |  |  | 70 | #undef  LCD_DATA_DDR_REG
 | 
        
           |  |  | 71 | #define LCD_DATA_PORT_IS_IO   0
 | 
        
           |  |  | 72 | #endif
 | 
        
           |  |  | 73 |   | 
        
           |  |  | 74 | #if LCD_CLOCK_PORT == PORTC 
 | 
        
           |  |  | 75 | #undef  LCD_CLOCK_PORT_IS_IO
 | 
        
           |  |  | 76 | #undef  LCD_CLOCK_DDR_REG
 | 
        
           |  |  | 77 | #define LCD_CLOCK_PORT_IS_IO  0
 | 
        
           |  |  | 78 | #endif
 | 
        
           |  |  | 79 | #endif /* #if defined(__AVR_ATmega103__) */
 | 
        
           |  |  | 80 |   | 
        
           |  |  | 81 | /*######################################################################################################*/
 | 
        
           |  |  | 82 | #elif LCD_IO_MODE == 6
 | 
        
           |  |  | 83 | /*######################################################################################################*/
 | 
        
           |  |  | 84 | #define lcd_toggle_e()   ({ cbi(LCD_E_PORT, LCD_E_PIN); delay(F_CPU/6000000); \
 | 
        
           |  |  | 85 |                             sbi(LCD_E_PORT, LCD_E_PIN);  })
 | 
        
           |  |  | 86 |   | 
        
           |  |  | 87 | #if LCD_READ_REQUIRED == 1  
 | 
        
           |  |  | 88 | #undef  LCD_MULTIPLEX_REQUIRED
 | 
        
           |  |  | 89 | #define LCD_MULTIPLEX_REQUIRED   0
 | 
        
           |  |  | 90 | #define BUSY_FLAG   0
 | 
        
           |  |  | 91 | #define DATA        1
 | 
        
           |  |  | 92 | #endif
 | 
        
           |  |  | 93 |   | 
        
           |  |  | 94 | #if LCD_LINES == 1 || LCD_LINES == 2 || LCD_LINES == 4
 | 
        
           |  |  | 95 | #else
 | 
        
           |  |  | 96 | #error THE LCD LINES MUST BE 1 OR 2 OR 4 !
 | 
        
           |  |  | 97 | #endif
 | 
        
           |  |  | 98 |   | 
        
           |  |  | 99 | #define LCD_D4_PORT_IS_IO     1   
 | 
        
           |  |  | 100 | #define LCD_D5_PORT_IS_IO     1   
 | 
        
           |  |  | 101 | #define LCD_D6_PORT_IS_IO     1 
 | 
        
           |  |  | 102 | #define LCD_D7_PORT_IS_IO     1
 | 
        
           |  |  | 103 | #define LCD_RS_PORT_IS_IO     1
 | 
        
           |  |  | 104 | #define LCD_RW_PORT_IS_IO     1
 | 
        
           |  |  | 105 | #define LCD_E_PORT_IS_IO      1
 | 
        
           |  |  | 106 |   | 
        
           |  |  | 107 | #define LCD_D4_PORT           CONCAT1(PORT, LCD_DATA4_PORT)
 | 
        
           |  |  | 108 | #define LCD_D5_PORT           CONCAT1(PORT, LCD_DATA5_PORT)
 | 
        
           |  |  | 109 | #define LCD_D6_PORT           CONCAT1(PORT, LCD_DATA6_PORT)
 | 
        
           |  |  | 110 | #define LCD_D7_PORT           CONCAT1(PORT, LCD_DATA7_PORT)
 | 
        
           |  |  | 111 | #define LCD_RS_PORT           CONCAT1(PORT, LCD_RS_SIGNAL_PORT)
 | 
        
           |  |  | 112 | #define LCD_RW_PORT           CONCAT1(PORT, LCD_RW_SIGNAL_PORT)
 | 
        
           |  |  | 113 | #define LCD_E_PORT            CONCAT1(PORT, LCD_E_SIGNAL_PORT)
 | 
        
           |  |  | 114 |   | 
        
           |  |  | 115 | #define LCD_D4_DDR_REG        CONCAT1(DDR, LCD_DATA4_PORT)
 | 
        
           |  |  | 116 | #define LCD_D5_DDR_REG        CONCAT1(DDR, LCD_DATA5_PORT)
 | 
        
           |  |  | 117 | #define LCD_D6_DDR_REG        CONCAT1(DDR, LCD_DATA6_PORT)
 | 
        
           |  |  | 118 | #define LCD_D7_DDR_REG        CONCAT1(DDR, LCD_DATA7_PORT)
 | 
        
           |  |  | 119 | #define LCD_RS_DDR_REG        CONCAT1(DDR, LCD_RS_SIGNAL_PORT)
 | 
        
           |  |  | 120 | #define LCD_RW_DDR_REG        CONCAT1(DDR, LCD_RW_SIGNAL_PORT)
 | 
        
           |  |  | 121 | #define LCD_E_DDR_REG         CONCAT1(DDR, LCD_E_SIGNAL_PORT)
 | 
        
           |  |  | 122 |   | 
        
           |  |  | 123 |   | 
        
           |  |  | 124 |   | 
        
           |  |  | 125 | #if   LCD_READ_REQUIRED == 1
 | 
        
           |  |  | 126 |   | 
        
           |  |  | 127 | #define LCD_D4_PIN_REG        CONCAT1(PIN, LCD_DATA4_PORT)
 | 
        
           |  |  | 128 | #define LCD_D5_PIN_REG        CONCAT1(PIN, LCD_DATA5_PORT)
 | 
        
           |  |  | 129 | #define LCD_D6_PIN_REG        CONCAT1(PIN, LCD_DATA6_PORT)
 | 
        
           |  |  | 130 | #define LCD_D7_PIN_REG        CONCAT1(PIN, LCD_DATA7_PORT)
 | 
        
           |  |  | 131 |   | 
        
           |  |  | 132 | #elif LCD_READ_REQUIRED == 0
 | 
        
           |  |  | 133 |   | 
        
           |  |  | 134 | #undef LCD_RW_PORT
 | 
        
           |  |  | 135 | #undef LCD_RW_DDR_REG
 | 
        
           |  |  | 136 | #undef LCD_RW_PORT_IS_IO
 | 
        
           |  |  | 137 |   | 
        
           |  |  | 138 | #endif
 | 
        
           |  |  | 139 |   | 
        
           |  |  | 140 |   | 
        
           |  |  | 141 |   | 
        
           |  |  | 142 | #if defined(__AVR_ATmega103__)
 | 
        
           |  |  | 143 |   | 
        
           |  |  | 144 | #if LCD_D4_PORT == PORTC 
 | 
        
           |  |  | 145 | #if LCD_READ_REQUIRED == 1
 | 
        
           |  |  | 146 | #error THE PORT FOR LCD_D4 IS OUTPUT ONLY!
 | 
        
           |  |  | 147 | #endif
 | 
        
           |  |  | 148 | #undef  LCD_D4_PORT_IS_IO
 | 
        
           |  |  | 149 | #undef  LCD_D4_DDR_REG 
 | 
        
           |  |  | 150 | #define LCD_D4_PORT_IS_IO   0
 | 
        
           |  |  | 151 | #endif
 | 
        
           |  |  | 152 |   | 
        
           |  |  | 153 | #if LCD_D5_PORT == PORTC 
 | 
        
           |  |  | 154 | #if LCD_READ_REQUIRED == 1
 | 
        
           |  |  | 155 | #error THE PORT FOR LCD_D5 IS OUTPUT ONLY!
 | 
        
           |  |  | 156 | #endif
 | 
        
           |  |  | 157 | #undef  LCD_D5_PORT_IS_IO
 | 
        
           |  |  | 158 | #undef  LCD_D5_DDR_REG 
 | 
        
           |  |  | 159 | #define LCD_D5_PORT_IS_IO   0
 | 
        
           |  |  | 160 | #endif
 | 
        
           |  |  | 161 |   | 
        
           |  |  | 162 | #if LCD_D6_PORT == PORTC 
 | 
        
           |  |  | 163 | #if LCD_READ_REQUIRED == 1
 | 
        
           |  |  | 164 | #error THE PORT FOR LCD_D6 IS OUTPUT ONLY!
 | 
        
           |  |  | 165 | #endif
 | 
        
           |  |  | 166 | #undef  LCD_D6_PORT_IS_IO
 | 
        
           |  |  | 167 | #undef  LCD_D6_DDR_REG 
 | 
        
           |  |  | 168 | #define LCD_D6_PORT_IS_IO   0
 | 
        
           |  |  | 169 | #endif
 | 
        
           |  |  | 170 |   | 
        
           |  |  | 171 | #if LCD_D7_PORT == PORTC 
 | 
        
           |  |  | 172 | #if LCD_READ_REQUIRED == 1
 | 
        
           |  |  | 173 | #error THE PORT FOR LCD_D7 IS OUTPUT ONLY!
 | 
        
           |  |  | 174 | #endif
 | 
        
           |  |  | 175 | #undef  LCD_D7_PORT_IS_IO
 | 
        
           |  |  | 176 | #undef  LCD_D7_DDR_REG 
 | 
        
           |  |  | 177 | #define LCD_D7_PORT_IS_IO   0
 | 
        
           |  |  | 178 | #endif
 | 
        
           |  |  | 179 |   | 
        
           |  |  | 180 | #if LCD_RS_PORT == PORTC 
 | 
        
           |  |  | 181 | #undef  LCD_RS_PORT_IS_IO
 | 
        
           |  |  | 182 | #undef  LCD_RS_DDR_REG 
 | 
        
           |  |  | 183 | #define LCD_RS_PORT_IS_IO   0
 | 
        
           |  |  | 184 | #endif
 | 
        
           |  |  | 185 |   | 
        
           |  |  | 186 | #if LCD_READ_REQUIRED == 1 
 | 
        
           |  |  | 187 | #if LCD_RW_PORT == PORTC 
 | 
        
           |  |  | 188 | #undef  LCD_RW_PORT_IS_IO
 | 
        
           |  |  | 189 | #undef  LCD_RW_DDR_REG 
 | 
        
           |  |  | 190 | #define LCD_RW_PORT_IS_IO   0
 | 
        
           |  |  | 191 | #endif 
 | 
        
           |  |  | 192 | #endif
 | 
        
           |  |  | 193 |   | 
        
           |  |  | 194 | #if LCD_E_PORT == PORTC 
 | 
        
           |  |  | 195 | #undef  LCD_E_PORT_IS_IO
 | 
        
           |  |  | 196 | #undef  LCD_E_DDR_REG 
 | 
        
           |  |  | 197 | #define LCD_E_PORT_IS_IO    0
 | 
        
           |  |  | 198 | #endif
 | 
        
           |  |  | 199 |   | 
        
           |  |  | 200 | #endif /* #if defined(__AVR_ATmega103__) */
 | 
        
           |  |  | 201 |   | 
        
           |  |  | 202 | /*######################################################################################################*/
 | 
        
           |  |  | 203 | #elif LCD_IO_MODE == 7
 | 
        
           |  |  | 204 | /*######################################################################################################*/
 | 
        
           |  |  | 205 |   | 
        
           |  |  | 206 | #define lcd_toggle_e()   ({ cbivar(lcd_E_port, lcd_E_pin); delay(F_CPU/6000000); \
 | 
        
           |  |  | 207 |                             sbivar(lcd_E_port, lcd_E_pin);  })
 | 
        
           |  |  | 208 | #if SREG > 0X3F
 | 
        
           |  |  | 209 | #define IO_TO_MEM_OFFSET  0
 | 
        
           |  |  | 210 | #else
 | 
        
           |  |  | 211 | #define IO_TO_MEM_OFFSET  0X20
 | 
        
           |  |  | 212 | #endif
 | 
        
           |  |  | 213 |   | 
        
           |  |  | 214 | #define LCD_READ_REQUIRED 0  
 | 
        
           |  |  | 215 |   | 
        
           |  |  | 216 | #if LCD_0_LINES == 1 || LCD_0_LINES == 2 || LCD_0_LINES == 4
 | 
        
           |  |  | 217 | #else
 | 
        
           |  |  | 218 | #error THE LCD LINES MUST BE 1 OR 2 OR 4 !
 | 
        
           |  |  | 219 | #endif
 | 
        
           |  |  | 220 |   | 
        
           |  |  | 221 | #if LCD_1_LINES == 1 || LCD_1_LINES == 2 || LCD_1_LINES == 4
 | 
        
           |  |  | 222 | #else
 | 
        
           |  |  | 223 | #error THE LCD LINES MUST BE 1 OR 2 OR 4 !
 | 
        
           |  |  | 224 | #endif
 | 
        
           |  |  | 225 |   | 
        
           |  |  | 226 | #if NUMBER_OF_LCD_UNITS >= 3
 | 
        
           |  |  | 227 | #if LCD_2_LINES == 1 || LCD_2_LINES == 2 || LCD_2_LINES == 4
 | 
        
           |  |  | 228 | #else
 | 
        
           |  |  | 229 | #error THE LCD LINES MUST BE 1 OR 2 OR 4 !
 | 
        
           |  |  | 230 | #endif
 | 
        
           |  |  | 231 | #endif
 | 
        
           |  |  | 232 |   | 
        
           |  |  | 233 | #define LCD_D4_PORT_IS_IO     1   
 | 
        
           |  |  | 234 | #define LCD_D5_PORT_IS_IO     1   
 | 
        
           |  |  | 235 | #define LCD_D6_PORT_IS_IO     1 
 | 
        
           |  |  | 236 | #define LCD_D7_PORT_IS_IO     1
 | 
        
           |  |  | 237 | #define LCD_RS_PORT_IS_IO     1
 | 
        
           |  |  | 238 | #define LCD_0_E_PORT_IS_IO    1
 | 
        
           |  |  | 239 | #define LCD_1_E_PORT_IS_IO    1
 | 
        
           |  |  | 240 |   | 
        
           |  |  | 241 | #if NUMBER_OF_LCD_UNITS >=3
 | 
        
           |  |  | 242 | #define LCD_2_E_PORT_IS_IO    1
 | 
        
           |  |  | 243 | #endif
 | 
        
           |  |  | 244 |   | 
        
           |  |  | 245 | #define LCD_D4_PORT           CONCAT1(PORT, LCD_DATA4_PORT)
 | 
        
           |  |  | 246 | #define LCD_D5_PORT           CONCAT1(PORT, LCD_DATA5_PORT)
 | 
        
           |  |  | 247 | #define LCD_D6_PORT           CONCAT1(PORT, LCD_DATA6_PORT)
 | 
        
           |  |  | 248 | #define LCD_D7_PORT           CONCAT1(PORT, LCD_DATA7_PORT)
 | 
        
           |  |  | 249 | #define LCD_RS_PORT           CONCAT1(PORT, LCD_RS_SIGNAL_PORT)
 | 
        
           |  |  | 250 | #define LCD_0_E_PORT          CONCAT1(PORT, LCD_0_E_SIGNAL_PORT)
 | 
        
           |  |  | 251 | #define LCD_1_E_PORT          CONCAT1(PORT, LCD_1_E_SIGNAL_PORT)
 | 
        
           |  |  | 252 |   | 
        
           |  |  | 253 | #if NUMBER_OF_LCD_UNITS >=3
 | 
        
           |  |  | 254 | #define LCD_2_E_PORT          CONCAT1(PORT, LCD_2_E_SIGNAL_PORT)
 | 
        
           |  |  | 255 | #endif
 | 
        
           |  |  | 256 |   | 
        
           |  |  | 257 | #define LCD_D4_DDR_REG        CONCAT1(DDR, LCD_DATA4_PORT)
 | 
        
           |  |  | 258 | #define LCD_D5_DDR_REG        CONCAT1(DDR, LCD_DATA5_PORT)
 | 
        
           |  |  | 259 | #define LCD_D6_DDR_REG        CONCAT1(DDR, LCD_DATA6_PORT)
 | 
        
           |  |  | 260 | #define LCD_D7_DDR_REG        CONCAT1(DDR, LCD_DATA7_PORT)
 | 
        
           |  |  | 261 | #define LCD_RS_DDR_REG        CONCAT1(DDR, LCD_RS_SIGNAL_PORT)
 | 
        
           |  |  | 262 | #define LCD_0_E_DDR_REG       CONCAT1(DDR, LCD_0_E_SIGNAL_PORT)
 | 
        
           |  |  | 263 | #define LCD_1_E_DDR_REG       CONCAT1(DDR, LCD_1_E_SIGNAL_PORT)
 | 
        
           |  |  | 264 |   | 
        
           |  |  | 265 | #if NUMBER_OF_LCD_UNITS >=3
 | 
        
           |  |  | 266 | #define LCD_2_E_DDR_REG       CONCAT1(DDR, LCD_2_E_SIGNAL_PORT)
 | 
        
           |  |  | 267 | #endif
 | 
        
           |  |  | 268 |   | 
        
           |  |  | 269 |   | 
        
           |  |  | 270 | #if defined(__AVR_ATmega103__)
 | 
        
           |  |  | 271 |   | 
        
           |  |  | 272 | #if LCD_D4_PORT == PORTC 
 | 
        
           |  |  | 273 | #undef  LCD_D4_PORT_IS_IO
 | 
        
           |  |  | 274 | #undef  LCD_D4_DDR_REG 
 | 
        
           |  |  | 275 | #define LCD_D4_PORT_IS_IO   0
 | 
        
           |  |  | 276 | #endif
 | 
        
           |  |  | 277 |   | 
        
           |  |  | 278 | #if LCD_D5_PORT == PORTC 
 | 
        
           |  |  | 279 | #undef  LCD_D5_PORT_IS_IO
 | 
        
           |  |  | 280 | #undef  LCD_D5_DDR_REG 
 | 
        
           |  |  | 281 | #define LCD_D5_PORT_IS_IO   0
 | 
        
           |  |  | 282 | #endif
 | 
        
           |  |  | 283 |   | 
        
           |  |  | 284 | #if LCD_D6_PORT == PORTC 
 | 
        
           |  |  | 285 | #undef  LCD_D6_PORT_IS_IO
 | 
        
           |  |  | 286 | #undef  LCD_D6_DDR_REG 
 | 
        
           |  |  | 287 | #define LCD_D6_PORT_IS_IO   0
 | 
        
           |  |  | 288 | #endif
 | 
        
           |  |  | 289 |   | 
        
           |  |  | 290 | #if LCD_D7_PORT == PORTC 
 | 
        
           |  |  | 291 | #undef  LCD_D7_PORT_IS_IO
 | 
        
           |  |  | 292 | #undef  LCD_D7_DDR_REG 
 | 
        
           |  |  | 293 | #define LCD_D7_PORT_IS_IO   0
 | 
        
           |  |  | 294 | #endif
 | 
        
           |  |  | 295 |   | 
        
           |  |  | 296 | #if LCD_RS_PORT == PORTC 
 | 
        
           |  |  | 297 | #undef  LCD_RS_PORT_IS_IO
 | 
        
           |  |  | 298 | #undef  LCD_RS_DDR_REG 
 | 
        
           |  |  | 299 | #define LCD_RS_PORT_IS_IO   0
 | 
        
           |  |  | 300 | #endif
 | 
        
           |  |  | 301 |   | 
        
           |  |  | 302 | #if LCD_0_E_PORT == PORTC 
 | 
        
           |  |  | 303 | #undef  LCD_0_E_PORT_IS_IO
 | 
        
           |  |  | 304 | #undef  LCD_0_E_DDR_REG 
 | 
        
           |  |  | 305 | #define LCD_0_E_PORT_IS_IO  0
 | 
        
           |  |  | 306 | #endif
 | 
        
           |  |  | 307 |   | 
        
           |  |  | 308 | #if LCD_1_E_PORT == PORTC 
 | 
        
           |  |  | 309 | #undef  LCD_1_E_PORT_IS_IO
 | 
        
           |  |  | 310 | #undef  LCD_1_E_DDR_REG 
 | 
        
           |  |  | 311 | #define LCD_1_E_PORT_IS_IO  0
 | 
        
           |  |  | 312 | #endif
 | 
        
           |  |  | 313 |   | 
        
           |  |  | 314 | #if NUMBER_OF_LCD_UNITS >=3
 | 
        
           |  |  | 315 | #if LCD_2_E_PORT == PORTC 
 | 
        
           |  |  | 316 | #undef  LCD_2_E_PORT_IS_IO
 | 
        
           |  |  | 317 | #undef  LCD_2_E_DDR_REG 
 | 
        
           |  |  | 318 | #define LCD_2_E_PORT_IS_IO  0
 | 
        
           |  |  | 319 | #endif
 | 
        
           |  |  | 320 | #endif  /*  #if NUMBER_OF_LCD_UNITS >=3  */
 | 
        
           |  |  | 321 |   | 
        
           |  |  | 322 | #endif  /*  #if defined(__AVR_ATmega103__)  */
 | 
        
           |  |  | 323 |   | 
        
           |  |  | 324 | #endif  /*  #elif LCD_IO_MODE == 7 */   
 | 
        
           |  |  | 325 | /*######################################################################################################*/
 | 
        
           |  |  | 326 |   | 
        
           |  |  | 327 | /* type definitions */
 | 
        
           |  |  | 328 |   | 
        
           |  |  | 329 | typedef unsigned char  u08;
 | 
        
           |  |  | 330 | typedef unsigned short u16;
 | 
        
           |  |  | 331 |   | 
        
           |  |  | 332 | /*######################################################################################################*/
 | 
        
           |  |  | 333 | /* FUNCTION PROTOTYPES                                                                                  */
 | 
        
           |  |  | 334 | /*######################################################################################################*/
 | 
        
           |  |  | 335 |   | 
        
           |  |  | 336 | #if LCD_IO_MODE == 7
 | 
        
           |  |  | 337 | static void sbivar(unsigned char port, unsigned char bit);
 | 
        
           |  |  | 338 | static void cbivar(unsigned char port, unsigned char bit);
 | 
        
           |  |  | 339 | #endif
 | 
        
           |  |  | 340 |   | 
        
           |  |  | 341 | #if  LCD_READ_REQUIRED == 1
 | 
        
           |  |  | 342 | static unsigned char lcd_read(unsigned char rs);
 | 
        
           |  |  | 343 | static inline unsigned char lcd_waitbusy(void);
 | 
        
           |  |  | 344 | #endif
 | 
        
           |  |  | 345 |   | 
        
           |  |  | 346 | static void delay(unsigned long int us);
 | 
        
           |  |  | 347 |   | 
        
           |  |  | 348 | /*######################################################################################################*/
 | 
        
           |  |  | 349 | /* GLOBAL variables                                                                                     */
 | 
        
           |  |  | 350 | /*######################################################################################################*/
 | 
        
           |  |  | 351 |   | 
        
           |  |  | 352 | static unsigned char x,y, putc_lock=0;
 | 
        
           |  |  | 353 | #if LCD_IO_MODE == 7
 | 
        
           |  |  | 354 | static unsigned char lcd_E_port=0, lcd_E_pin=0, lcd_chars_per_line=0, lcd_lines=0, current_lcd_unit=0;
 | 
        
           |  |  | 355 | static struct xy {
 | 
        
           |  |  | 356 |                    unsigned char x;
 | 
        
           |  |  | 357 |                    unsigned char y;
 | 
        
           |  |  | 358 |                  } xy_coordinates[NUMBER_OF_LCD_UNITS];
 | 
        
           |  |  | 359 |   | 
        
           |  |  | 360 | #endif
 | 
        
           |  |  | 361 |   | 
        
           |  |  | 362 | /*######################################################################################################*/
 | 
        
           |  |  | 363 | /* local functions */
 | 
        
           |  |  | 364 | /*######################################################################################################*/
 | 
        
           |  |  | 365 |   | 
        
           |  |  | 366 | static void delay(unsigned long int us)
 | 
        
           |  |  | 367 | /* delay for a minimum of <us> microseconds (with a 6 Mhz crystal, the resolution is 1 us) */
 | 
        
           |  |  | 368 | {
 | 
        
           |  |  | 369 |    while ( us ) { us--; }  /* 6 cpu cycles per loop */
 | 
        
           |  |  | 370 | } 
 | 
        
           |  |  | 371 |   | 
        
           |  |  | 372 | /*######################################################################################################*/
 | 
        
           |  |  | 373 | #if LCD_IO_MODE == 7   /* lcd_write() function for 6 bit i/o one lcd unit */
 | 
        
           |  |  | 374 | /*######################################################################################################*/
 | 
        
           |  |  | 375 |   | 
        
           |  |  | 376 |   | 
        
           |  |  | 377 | static void sbivar(unsigned char port, unsigned char bit)
 | 
        
           |  |  | 378 | {
 | 
        
           |  |  | 379 | register unsigned char temp=0;
 | 
        
           |  |  | 380 |   | 
        
           |  |  | 381 |     temp=*((unsigned char*)(port+IO_TO_MEM_OFFSET));
 | 
        
           |  |  | 382 |     temp|= (1<<bit);
 | 
        
           |  |  | 383 |     *((unsigned char*)(port+IO_TO_MEM_OFFSET))=temp;
 | 
        
           |  |  | 384 |   | 
        
           |  |  | 385 | return;
 | 
        
           |  |  | 386 | }
 | 
        
           |  |  | 387 | /*######################################################################################################*/
 | 
        
           |  |  | 388 |   | 
        
           |  |  | 389 | static void cbivar(unsigned char port, unsigned char bit)
 | 
        
           |  |  | 390 | {
 | 
        
           |  |  | 391 | register unsigned char temp=0;
 | 
        
           |  |  | 392 |   | 
        
           |  |  | 393 |     temp=*((unsigned char*)(port+IO_TO_MEM_OFFSET));
 | 
        
           |  |  | 394 |     temp &= ~(1<<bit);
 | 
        
           |  |  | 395 |     *((unsigned char*)(port+IO_TO_MEM_OFFSET))=temp;
 | 
        
           |  |  | 396 |   | 
        
           |  |  | 397 | return;
 | 
        
           |  |  | 398 | }
 | 
        
           |  |  | 399 | /*######################################################################################################*/
 | 
        
           |  |  | 400 |   | 
        
           |  |  | 401 | static void lcd_write(unsigned char data, unsigned char mode) 
 | 
        
           |  |  | 402 | {
 | 
        
           |  |  | 403 | register unsigned char rs=0; 
 | 
        
           |  |  | 404 |   | 
        
           |  |  | 405 |   | 
        
           |  |  | 406 |        if(mode==DATA_MODE) rs=1; else rs=0;          /* set the rs value */
 | 
        
           |  |  | 407 |        /* output high nibble first */ 
 | 
        
           |  |  | 408 |        if(data&0x10) sbi(LCD_D4_PORT, LCD_D4_PIN);   else cbi(LCD_D4_PORT, LCD_D4_PIN);
 | 
        
           |  |  | 409 |        if(data&0x20) sbi(LCD_D5_PORT, LCD_D5_PIN);   else cbi(LCD_D5_PORT, LCD_D5_PIN);
 | 
        
           |  |  | 410 |        if(data&0x40) sbi(LCD_D6_PORT, LCD_D6_PIN);   else cbi(LCD_D6_PORT, LCD_D6_PIN);
 | 
        
           |  |  | 411 |        if(data&0x80) sbi(LCD_D7_PORT, LCD_D7_PIN);   else cbi(LCD_D7_PORT, LCD_D7_PIN);
 | 
        
           |  |  | 412 |        if(rs) sbi(LCD_RS_PORT, LCD_RS_PIN);          else cbi(LCD_RS_PORT, LCD_RS_PIN);
 | 
        
           |  |  | 413 |        lcd_toggle_e();
 | 
        
           |  |  | 414 |        /* output low nibble */
 | 
        
           |  |  | 415 |        /* if INIT_MODE skip this section else execute it */
 | 
        
           |  |  | 416 |        if(mode!=INIT_MODE)
 | 
        
           |  |  | 417 |         {
 | 
        
           |  |  | 418 |           if(data&0x01) sbi(LCD_D4_PORT, LCD_D4_PIN);   else cbi(LCD_D4_PORT, LCD_D4_PIN);
 | 
        
           |  |  | 419 |           if(data&0x02) sbi(LCD_D5_PORT, LCD_D5_PIN);   else cbi(LCD_D5_PORT, LCD_D5_PIN);
 | 
        
           |  |  | 420 |           if(data&0x04) sbi(LCD_D6_PORT, LCD_D6_PIN);   else cbi(LCD_D6_PORT, LCD_D6_PIN);
 | 
        
           |  |  | 421 |           if(data&0x08) sbi(LCD_D7_PORT, LCD_D7_PIN);   else cbi(LCD_D7_PORT, LCD_D7_PIN);
 | 
        
           |  |  | 422 |           if(rs) sbi(LCD_RS_PORT, LCD_RS_PIN);          else cbi(LCD_RS_PORT, LCD_RS_PIN);
 | 
        
           |  |  | 423 |           lcd_toggle_e();
 | 
        
           |  |  | 424 |         }
 | 
        
           |  |  | 425 |   | 
        
           |  |  | 426 |  delay(LCD_DELAY_SHORT);
 | 
        
           |  |  | 427 |   | 
        
           |  |  | 428 | }
 | 
        
           |  |  | 429 | /*------------------------------------------------------------------------------------------------------*/
 | 
        
           |  |  | 430 | void  select_lcd(unsigned char lcd_unit)
 | 
        
           |  |  | 431 | {
 | 
        
           |  |  | 432 | /* Save the current lcd unit x,y coordinates */
 | 
        
           |  |  | 433 |    xy_coordinates[current_lcd_unit].x=x;
 | 
        
           |  |  | 434 |    xy_coordinates[current_lcd_unit].y=y;
 | 
        
           |  |  | 435 |   | 
        
           |  |  | 436 |    if(lcd_unit==0)
 | 
        
           |  |  | 437 |     {
 | 
        
           |  |  | 438 |        lcd_E_port= LCD_0_E_PORT;
 | 
        
           |  |  | 439 |        lcd_E_pin = LCD_0_E_PIN;
 | 
        
           |  |  | 440 |        lcd_chars_per_line = LCD_0_CHARS_PER_LINE;
 | 
        
           |  |  | 441 |        lcd_lines = LCD_0_LINES;
 | 
        
           |  |  | 442 |        current_lcd_unit=lcd_unit;     /* Make the requested lcd unit current (active) */
 | 
        
           |  |  | 443 |        x=xy_coordinates[lcd_unit].x;  /* Load the saved x,y coordinates of the specified lcd unit */
 | 
        
           |  |  | 444 |        y=xy_coordinates[lcd_unit].y;
 | 
        
           |  |  | 445 |     }
 | 
        
           |  |  | 446 |    else if(lcd_unit==1)
 | 
        
           |  |  | 447 |          {
 | 
        
           |  |  | 448 |             lcd_E_port= LCD_1_E_PORT;
 | 
        
           |  |  | 449 |             lcd_E_pin = LCD_1_E_PIN;
 | 
        
           |  |  | 450 |             lcd_chars_per_line = LCD_1_CHARS_PER_LINE;
 | 
        
           |  |  | 451 |             lcd_lines = LCD_1_LINES;
 | 
        
           |  |  | 452 |             current_lcd_unit=lcd_unit;
 | 
        
           |  |  | 453 |             x=xy_coordinates[lcd_unit].x;
 | 
        
           |  |  | 454 |             y=xy_coordinates[lcd_unit].y;
 | 
        
           |  |  | 455 |          }
 | 
        
           |  |  | 456 | #if NUMBER_OF_LCD_UNITS >=3
 | 
        
           |  |  | 457 |    else if(lcd_unit==2)
 | 
        
           |  |  | 458 |          {
 | 
        
           |  |  | 459 |             lcd_E_port= LCD_2_E_PORT;
 | 
        
           |  |  | 460 |             lcd_E_pin = LCD_2_E_PIN;
 | 
        
           |  |  | 461 |             lcd_chars_per_line = LCD_2_CHARS_PER_LINE;
 | 
        
           |  |  | 462 |             lcd_lines = LCD_2_LINES;
 | 
        
           |  |  | 463 |             current_lcd_unit=lcd_unit;
 | 
        
           |  |  | 464 |             x=xy_coordinates[lcd_unit].x;
 | 
        
           |  |  | 465 |             y=xy_coordinates[lcd_unit].y;
 | 
        
           |  |  | 466 |          }
 | 
        
           |  |  | 467 | #endif
 | 
        
           |  |  | 468 | return;
 | 
        
           |  |  | 469 | }
 | 
        
           |  |  | 470 | /*######################################################################################################*/
 | 
        
           |  |  | 471 | #elif LCD_IO_MODE == 6   /* lcd_write() function for 6 bit i/o  with multi lcd units */
 | 
        
           |  |  | 472 | /*######################################################################################################*/
 | 
        
           |  |  | 473 |   | 
        
           |  |  | 474 | #if LCD_READ_REQUIRED == 1 
 | 
        
           |  |  | 475 |   | 
        
           |  |  | 476 | #define LCD_READ_DELAY  ( (10*(F_CPU/60000))/100 )
 | 
        
           |  |  | 477 |   | 
        
           |  |  | 478 | static unsigned char lcd_read(unsigned char rs) 
 | 
        
           |  |  | 479 | {
 | 
        
           |  |  | 480 | register unsigned char data=0;
 | 
        
           |  |  | 481 | /* RS=1: read data, RS=0: read busy flag, RW=1  read mode */  
 | 
        
           |  |  | 482 |     if (rs) sbi(LCD_RS_PORT, LCD_RS_PIN); else cbi(LCD_RS_PORT, LCD_RS_PIN);    
 | 
        
           |  |  | 483 |   | 
        
           |  |  | 484 |     /* configure data pins as input */
 | 
        
           |  |  | 485 |     cbi(LCD_D4_DDR_REG, LCD_D4_PIN );
 | 
        
           |  |  | 486 |     cbi(LCD_D5_DDR_REG, LCD_D5_PIN );
 | 
        
           |  |  | 487 |     cbi(LCD_D6_DDR_REG, LCD_D6_PIN );
 | 
        
           |  |  | 488 |     cbi(LCD_D7_DDR_REG, LCD_D7_PIN );
 | 
        
           |  |  | 489 |   | 
        
           |  |  | 490 |     /* set R/W pin for reading from LCD */
 | 
        
           |  |  | 491 |     sbi(LCD_RW_PORT, LCD_RW_PIN); 
 | 
        
           |  |  | 492 |     delay(LCD_READ_DELAY);
 | 
        
           |  |  | 493 |   | 
        
           |  |  | 494 |     if(bit_is_set(LCD_D7_PIN_REG, LCD_D7_PIN)) { data+=1; }
 | 
        
           |  |  | 495 |     data=(data<<1);
 | 
        
           |  |  | 496 |     if(bit_is_set(LCD_D6_PIN_REG, LCD_D6_PIN)) { data+=1; }
 | 
        
           |  |  | 497 |     data=(data<<1);
 | 
        
           |  |  | 498 |     if(bit_is_set(LCD_D5_PIN_REG, LCD_D5_PIN)) { data+=1; }
 | 
        
           |  |  | 499 |     data=(data<<1);
 | 
        
           |  |  | 500 |     if(bit_is_set(LCD_D4_PIN_REG, LCD_D4_PIN)) { data+=1; }
 | 
        
           |  |  | 501 |     data=(data<<1);
 | 
        
           |  |  | 502 |   | 
        
           |  |  | 503 |     lcd_toggle_e();
 | 
        
           |  |  | 504 |     delay(LCD_READ_DELAY);
 | 
        
           |  |  | 505 |   | 
        
           |  |  | 506 |     if(bit_is_set(LCD_D7_PIN_REG, LCD_D7_PIN)) { data+=1; }
 | 
        
           |  |  | 507 |     data=(data<<1);
 | 
        
           |  |  | 508 |     if(bit_is_set(LCD_D6_PIN_REG, LCD_D6_PIN)) { data+=1; }
 | 
        
           |  |  | 509 |     data=(data<<1);
 | 
        
           |  |  | 510 |     if(bit_is_set(LCD_D5_PIN_REG, LCD_D5_PIN)) { data+=1; }
 | 
        
           |  |  | 511 |     data=(data<<1);
 | 
        
           |  |  | 512 |     if(bit_is_set(LCD_D4_PIN_REG, LCD_D4_PIN)) { data+=1; }
 | 
        
           |  |  | 513 |   | 
        
           |  |  | 514 |     lcd_toggle_e();
 | 
        
           |  |  | 515 |   | 
        
           |  |  | 516 |     /* clear R/W pin for writting to LCD */
 | 
        
           |  |  | 517 |     cbi(LCD_RW_PORT, LCD_RW_PIN);      
 | 
        
           |  |  | 518 |   | 
        
           |  |  | 519 |     /* configure data pins as outputs */
 | 
        
           |  |  | 520 |     sbi(LCD_D4_DDR_REG, LCD_D4_PIN );
 | 
        
           |  |  | 521 |     sbi(LCD_D5_DDR_REG, LCD_D5_PIN );
 | 
        
           |  |  | 522 |     sbi(LCD_D6_DDR_REG, LCD_D6_PIN );
 | 
        
           |  |  | 523 |     sbi(LCD_D7_DDR_REG, LCD_D7_PIN );
 | 
        
           |  |  | 524 |   | 
        
           |  |  | 525 |   | 
        
           |  |  | 526 | return (data);
 | 
        
           |  |  | 527 | }
 | 
        
           |  |  | 528 | /*######################################################################################################*/
 | 
        
           |  |  | 529 | static inline unsigned char lcd_waitbusy(void)
 | 
        
           |  |  | 530 | /* loops while lcd is busy, reads address counter */
 | 
        
           |  |  | 531 | {
 | 
        
           |  |  | 532 | register unsigned char c;
 | 
        
           |  |  | 533 |   | 
        
           |  |  | 534 |     while ( (c=lcd_read(BUSY_FLAG) & (1<<LCD_BUSY)) ); 
 | 
        
           |  |  | 535 |   | 
        
           |  |  | 536 |     return (c);  // return address counter
 | 
        
           |  |  | 537 | }
 | 
        
           |  |  | 538 |   | 
        
           |  |  | 539 | #endif  /* #if LCD_READ_REQUIRED == 1  */
 | 
        
           |  |  | 540 | /*######################################################################################################*/
 | 
        
           |  |  | 541 |   | 
        
           |  |  | 542 | static void lcd_write(unsigned char data, unsigned char mode) 
 | 
        
           |  |  | 543 | {
 | 
        
           |  |  | 544 | register unsigned char rs=0; 
 | 
        
           |  |  | 545 |   | 
        
           |  |  | 546 |  /* save and set DDR(X) register(s) in case another program altered those values */
 | 
        
           |  |  | 547 | #if LCD_MULTIPLEX_ENABLE == 1
 | 
        
           |  |  | 548 |   | 
        
           |  |  | 549 | #if LCD_D4_PORT_IS_IO==1
 | 
        
           |  |  | 550 | unsigned char d4_is_output=0;
 | 
        
           |  |  | 551 | if(inp(LCD_D4_DDR_REG)&(1<<LCD_D4_PIN)) { d4_is_output=1; }
 | 
        
           |  |  | 552 | sbi(LCD_D4_DDR_REG, LCD_D4_PIN );
 | 
        
           |  |  | 553 | #endif
 | 
        
           |  |  | 554 | #if LCD_D5_PORT_IS_IO==1
 | 
        
           |  |  | 555 | unsigned char d5_is_output=0;
 | 
        
           |  |  | 556 | if(inp(LCD_D5_DDR_REG)&(1<<LCD_D5_PIN)) { d5_is_output=1; }
 | 
        
           |  |  | 557 | sbi(LCD_D5_DDR_REG, LCD_D5_PIN );
 | 
        
           |  |  | 558 | #endif
 | 
        
           |  |  | 559 | #if LCD_D6_PORT_IS_IO==1
 | 
        
           |  |  | 560 | unsigned char d6_is_output=0;
 | 
        
           |  |  | 561 | if(inp(LCD_D6_DDR_REG)&(1<<LCD_D6_PIN)) { d6_is_output=1; }
 | 
        
           |  |  | 562 | sbi(LCD_D6_DDR_REG, LCD_D6_PIN );
 | 
        
           |  |  | 563 | #endif
 | 
        
           |  |  | 564 | #if LCD_D7_PORT_IS_IO==1
 | 
        
           |  |  | 565 | unsigned char d7_is_output=0;
 | 
        
           |  |  | 566 | if(inp(LCD_D7_DDR_REG)&(1<<LCD_D7_PIN)) { d7_is_output=1; }
 | 
        
           |  |  | 567 | sbi(LCD_D7_DDR_REG, LCD_D7_PIN );
 | 
        
           |  |  | 568 | #endif
 | 
        
           |  |  | 569 | #if LCD_RS_PORT_IS_IO==1
 | 
        
           |  |  | 570 | unsigned char rs_is_output=0;
 | 
        
           |  |  | 571 | if(inp(LCD_RS_DDR_REG)&(1<<LCD_RS_PIN)) { rs_is_output=1; }
 | 
        
           |  |  | 572 | sbi(LCD_RS_DDR_REG, LCD_RS_PIN );
 | 
        
           |  |  | 573 | #endif
 | 
        
           |  |  | 574 |   | 
        
           |  |  | 575 | #endif  /* LCD_MULTIPLEX_ENABLE == 1 */
 | 
        
           |  |  | 576 |   | 
        
           |  |  | 577 |        if(mode==DATA_MODE) rs=1; else rs=0;          /* set the rs value */
 | 
        
           |  |  | 578 |        /* output high nibble first */ 
 | 
        
           |  |  | 579 |        if(data&0x10) sbi(LCD_D4_PORT, LCD_D4_PIN);   else cbi(LCD_D4_PORT, LCD_D4_PIN);
 | 
        
           |  |  | 580 |        if(data&0x20) sbi(LCD_D5_PORT, LCD_D5_PIN);   else cbi(LCD_D5_PORT, LCD_D5_PIN);
 | 
        
           |  |  | 581 |        if(data&0x40) sbi(LCD_D6_PORT, LCD_D6_PIN);   else cbi(LCD_D6_PORT, LCD_D6_PIN);
 | 
        
           |  |  | 582 |        if(data&0x80) sbi(LCD_D7_PORT, LCD_D7_PIN);   else cbi(LCD_D7_PORT, LCD_D7_PIN);
 | 
        
           |  |  | 583 |        if(rs) sbi(LCD_RS_PORT, LCD_RS_PIN);          else cbi(LCD_RS_PORT, LCD_RS_PIN);
 | 
        
           |  |  | 584 |        lcd_toggle_e();
 | 
        
           |  |  | 585 |        /* output low nibble */
 | 
        
           |  |  | 586 |        /* if INIT_MODE skip this section else execute it */
 | 
        
           |  |  | 587 |        if(mode!=INIT_MODE)
 | 
        
           |  |  | 588 |         {
 | 
        
           |  |  | 589 |           if(data&0x01) sbi(LCD_D4_PORT, LCD_D4_PIN);   else cbi(LCD_D4_PORT, LCD_D4_PIN);
 | 
        
           |  |  | 590 |           if(data&0x02) sbi(LCD_D5_PORT, LCD_D5_PIN);   else cbi(LCD_D5_PORT, LCD_D5_PIN);
 | 
        
           |  |  | 591 |           if(data&0x04) sbi(LCD_D6_PORT, LCD_D6_PIN);   else cbi(LCD_D6_PORT, LCD_D6_PIN);
 | 
        
           |  |  | 592 |           if(data&0x08) sbi(LCD_D7_PORT, LCD_D7_PIN);   else cbi(LCD_D7_PORT, LCD_D7_PIN);
 | 
        
           |  |  | 593 |           if(rs) sbi(LCD_RS_PORT, LCD_RS_PIN);          else cbi(LCD_RS_PORT, LCD_RS_PIN);
 | 
        
           |  |  | 594 |           lcd_toggle_e();
 | 
        
           |  |  | 595 |         }
 | 
        
           |  |  | 596 | #if   LCD_READ_REQUIRED == 0
 | 
        
           |  |  | 597 |  delay(LCD_DELAY_SHORT);
 | 
        
           |  |  | 598 | #elif LCD_READ_REQUIRED == 1
 | 
        
           |  |  | 599 |  lcd_waitbusy();
 | 
        
           |  |  | 600 | #endif
 | 
        
           |  |  | 601 |   | 
        
           |  |  | 602 | /* Restore the DDR registers, if multiplexing wanted */     
 | 
        
           |  |  | 603 | #if LCD_MULTIPLEX_ENABLE == 1 
 | 
        
           |  |  | 604 |   | 
        
           |  |  | 605 | #if LCD_D4_PORT_IS_IO==1
 | 
        
           |  |  | 606 | if(!d4_is_output) { cbi(LCD_D4_DDR_REG, LCD_D4_PIN ); } 
 | 
        
           |  |  | 607 | #endif
 | 
        
           |  |  | 608 | #if LCD_D5_PORT_IS_IO==1
 | 
        
           |  |  | 609 | if(!d5_is_output) { cbi(LCD_D5_DDR_REG, LCD_D5_PIN ); }
 | 
        
           |  |  | 610 | #endif
 | 
        
           |  |  | 611 | #if LCD_D6_PORT_IS_IO==1
 | 
        
           |  |  | 612 | if(!d6_is_output) { cbi(LCD_D6_DDR_REG, LCD_D6_PIN ); }
 | 
        
           |  |  | 613 | #endif
 | 
        
           |  |  | 614 | #if LCD_D7_PORT_IS_IO==1
 | 
        
           |  |  | 615 | if(!d7_is_output) { cbi(LCD_D7_DDR_REG, LCD_D7_PIN ); }
 | 
        
           |  |  | 616 | #endif
 | 
        
           |  |  | 617 | #if LCD_RS_PORT_IS_IO==1
 | 
        
           |  |  | 618 | if(!rs_is_output) { cbi(LCD_RS_DDR_REG, LCD_RS_PIN ); }
 | 
        
           |  |  | 619 | #endif
 | 
        
           |  |  | 620 |   | 
        
           |  |  | 621 | #endif  /* LCD_MULTIPLEX_ENABLE == 1 */
 | 
        
           |  |  | 622 | }
 | 
        
           |  |  | 623 | /*######################################################################################################*/
 | 
        
           |  |  | 624 | #elif LCD_IO_MODE == 2  /* lcd_write() function for 2 bit i/o */
 | 
        
           |  |  | 625 | /*######################################################################################################*/
 | 
        
           |  |  | 626 |   | 
        
           |  |  | 627 | static void lcd_write(unsigned char lcd_data,unsigned char mode) 
 | 
        
           |  |  | 628 | {
 | 
        
           |  |  | 629 | #define toggle_clock() ({ sbi(LCD_CLOCK_PORT, LCD_CLOCK_PIN); cbi(LCD_CLOCK_PORT, LCD_CLOCK_PIN); }) 
 | 
        
           |  |  | 630 | #define data(x) ({ if(x) sbi(LCD_DATA_PORT, LCD_DATA_PIN); else cbi(LCD_DATA_PORT, LCD_DATA_PIN); })        
 | 
        
           |  |  | 631 | #define toggle_data()       ({ data(1); delay(F_CPU/6000000); data(0); })
 | 
        
           |  |  | 632 |   | 
        
           |  |  | 633 | register unsigned char x=0, rs=0;
 | 
        
           |  |  | 634 |   | 
        
           |  |  | 635 |        /* INITIALIZATION */
 | 
        
           |  |  | 636 |        /* Set clock and data pins as outputs, at low state and set rs value */ 
 | 
        
           |  |  | 637 | #if LCD_CLOCK_PORT_IS_IO
 | 
        
           |  |  | 638 |   sbi(LCD_CLOCK_DDR_REG, LCD_CLOCK_PIN); 
 | 
        
           |  |  | 639 | #endif
 | 
        
           |  |  | 640 | #if LCD_DATA_PORT_IS_IO
 | 
        
           |  |  | 641 |   sbi(LCD_DATA_DDR_REG, LCD_DATA_PIN);
 | 
        
           |  |  | 642 | #endif
 | 
        
           |  |  | 643 |        cbi(LCD_CLOCK_PORT, LCD_CLOCK_PIN); cbi(LCD_DATA_PORT, LCD_DATA_PIN); 
 | 
        
           |  |  | 644 |        if(mode==DATA_MODE) rs=1; else rs=0;
 | 
        
           |  |  | 645 |   | 
        
           |  |  | 646 |        /* send high nibble first */
 | 
        
           |  |  | 647 |        x=6; while(x--)   {  toggle_clock();  }           /* clear shift register */           
 | 
        
           |  |  | 648 |        data(1);             toggle_clock();              /* send E "AND" signal */
 | 
        
           |  |  | 649 |        data(rs);            toggle_clock();              /* send RS signal */
 | 
        
           |  |  | 650 |        x=0x80; while(x>=0x10) { data(lcd_data&x); toggle_clock(); x=(x>>1); }
 | 
        
           |  |  | 651 |        /* Strobe E pin making sure that the pulse is 450 ns min */
 | 
        
           |  |  | 652 |        toggle_data();   
 | 
        
           |  |  | 653 |   | 
        
           |  |  | 654 |        /* send low nibble  Clock and Data are already low */
 | 
        
           |  |  | 655 |        x=6; while(x--)   {  toggle_clock();  }           /* clear shift register */       
 | 
        
           |  |  | 656 |        data(1);             toggle_clock();              /* send E "AND" signal */
 | 
        
           |  |  | 657 |        data(rs);            toggle_clock();              /* send RS signal */
 | 
        
           |  |  | 658 |        x=0x08; while(x>=0x01) { data(lcd_data&x); toggle_clock(); x=(x>>1); }
 | 
        
           |  |  | 659 |        /* if INIT_MODE do NOT strobe the E pin else strobe it */
 | 
        
           |  |  | 660 |        if(mode!=INIT_MODE) { toggle_data(); }       
 | 
        
           |  |  | 661 |   | 
        
           |  |  | 662 |        delay(LCD_DELAY_SHORT);     /* wait for command to execute  */     
 | 
        
           |  |  | 663 |   | 
        
           |  |  | 664 | }
 | 
        
           |  |  | 665 | /*######################################################################################################*/
 | 
        
           |  |  | 666 | #endif /* #elif LCD_IO_MODE == 2 */
 | 
        
           |  |  | 667 | /*######################################################################################################*/
 | 
        
           |  |  | 668 |   | 
        
           |  |  | 669 | /*######################################################################################################*/
 | 
        
           |  |  | 670 | /* PUBLIC FUNCTIONS */
 | 
        
           |  |  | 671 | /*######################################################################################################*/
 | 
        
           |  |  | 672 | void lcd_command(unsigned char cmd)
 | 
        
           |  |  | 673 | /* send command <cmd> to LCD */
 | 
        
           |  |  | 674 | {
 | 
        
           |  |  | 675 |     lcd_write(cmd,CMD_MODE);
 | 
        
           |  |  | 676 |   | 
        
           |  |  | 677 | }
 | 
        
           |  |  | 678 | /*######################################################################################################*/
 | 
        
           |  |  | 679 |   | 
        
           |  |  | 680 | void lcd_gotoxy(unsigned char lcd_x, unsigned char lcd_y)
 | 
        
           |  |  | 681 | /* goto position (x,y) */
 | 
        
           |  |  | 682 | {
 | 
        
           |  |  | 683 | #if LCD_IO_MODE == 7 
 | 
        
           |  |  | 684 |   | 
        
           |  |  | 685 | if(lcd_x >= lcd_chars_per_line || lcd_y >= lcd_lines) { putc_lock=1; return; }
 | 
        
           |  |  | 686 | else putc_lock=0;
 | 
        
           |  |  | 687 |   | 
        
           |  |  | 688 |     if (lcd_y==0 )    { lcd_command((1<<LCD_DDRAM)+LCD_START_LINE1+lcd_x); }
 | 
        
           |  |  | 689 |     else if(lcd_y==1) { lcd_command((1<<LCD_DDRAM)+LCD_START_LINE2+lcd_x); }
 | 
        
           |  |  | 690 |     else if(lcd_y==2) { lcd_command((1<<LCD_DDRAM)+LCD_START_LINE3+lcd_x); }
 | 
        
           |  |  | 691 |     else              { lcd_command((1<<LCD_DDRAM)+LCD_START_LINE4+lcd_x); }
 | 
        
           |  |  | 692 | /*------------------------------------------------------------------------------------------------------*/
 | 
        
           |  |  | 693 | #elif LCD_IO_MODE == 6 || LCD_IO_MODE == 2
 | 
        
           |  |  | 694 | /*------------------------------------------------------------------------------------------------------*/
 | 
        
           |  |  | 695 |   | 
        
           |  |  | 696 | if(lcd_x >= LCD_CHARS_PER_LINE || lcd_y >= LCD_LINES) { putc_lock=1; return; }
 | 
        
           |  |  | 697 | else putc_lock=0;
 | 
        
           |  |  | 698 |   | 
        
           |  |  | 699 | #if LCD_LINES==1
 | 
        
           |  |  | 700 |     if (lcd_y==0 ) { lcd_command((1<<LCD_DDRAM)+LCD_START_LINE1+lcd_x); }
 | 
        
           |  |  | 701 | #endif
 | 
        
           |  |  | 702 | #if LCD_LINES==2
 | 
        
           |  |  | 703 |     if (lcd_y==0 ) { lcd_command((1<<LCD_DDRAM)+LCD_START_LINE1+lcd_x);  }
 | 
        
           |  |  | 704 |     else           { lcd_command((1<<LCD_DDRAM)+LCD_START_LINE2+lcd_x);  }
 | 
        
           |  |  | 705 | #endif
 | 
        
           |  |  | 706 |   | 
        
           |  |  | 707 | #if LCD_LINES==4
 | 
        
           |  |  | 708 |     if (lcd_y==0 )    { lcd_command((1<<LCD_DDRAM)+LCD_START_LINE1+lcd_x); }
 | 
        
           |  |  | 709 |     else if(lcd_y==1) { lcd_command((1<<LCD_DDRAM)+LCD_START_LINE2+lcd_x); }
 | 
        
           |  |  | 710 |     else if(lcd_y==2) { lcd_command((1<<LCD_DDRAM)+LCD_START_LINE3+lcd_x); }
 | 
        
           |  |  | 711 |     else              { lcd_command((1<<LCD_DDRAM)+LCD_START_LINE4+lcd_x); }
 | 
        
           |  |  | 712 | #endif
 | 
        
           |  |  | 713 | #endif
 | 
        
           |  |  | 714 |     x=lcd_x;
 | 
        
           |  |  | 715 |     y=lcd_y;
 | 
        
           |  |  | 716 |   | 
        
           |  |  | 717 | }/* lcd_gotoxy */
 | 
        
           |  |  | 718 | /*######################################################################################################*/
 | 
        
           |  |  | 719 |   | 
        
           |  |  | 720 | unsigned int lcd_getxy(void)
 | 
        
           |  |  | 721 | {
 | 
        
           |  |  | 722 |   return((y*100)+x); 
 | 
        
           |  |  | 723 | }
 | 
        
           |  |  | 724 | /*######################################################################################################*/
 | 
        
           |  |  | 725 |   | 
        
           |  |  | 726 | void lcd_clrscr(void)
 | 
        
           |  |  | 727 | /* clear lcd and set cursor to home position */
 | 
        
           |  |  | 728 | {
 | 
        
           |  |  | 729 |    lcd_command(1<<LCD_CLR);
 | 
        
           |  |  | 730 | #if LCD_READ_REQUIRED == 0 || LCD_IO_MODE == 2 || LCD_IO_MODE == 7
 | 
        
           |  |  | 731 |    delay(LCD_DELAY_LONG);       /* this command needs more waiting time to execute */
 | 
        
           |  |  | 732 | #elif LCD_READ_REQUIRED == 1 && LCD_IO_MODE == 6  
 | 
        
           |  |  | 733 |    lcd_waitbusy();
 | 
        
           |  |  | 734 | #endif
 | 
        
           |  |  | 735 |   | 
        
           |  |  | 736 |    x=0; y=0;
 | 
        
           |  |  | 737 | }
 | 
        
           |  |  | 738 | /*######################################################################################################*/
 | 
        
           |  |  | 739 |   | 
        
           |  |  | 740 | void lcd_clrline(unsigned char line)
 | 
        
           |  |  | 741 | /* clear a specific lcd line and set cursor at the start of the line */
 | 
        
           |  |  | 742 | {
 | 
        
           |  |  | 743 | #if LCD_IO_MODE == 7
 | 
        
           |  |  | 744 |    if(lcd_lines==1)
 | 
        
           |  |  | 745 |     {
 | 
        
           |  |  | 746 |        lcd_gotoxy(0, 0);
 | 
        
           |  |  | 747 |        while(x<lcd_chars_per_line) { lcd_putc(' '); }
 | 
        
           |  |  | 748 |        lcd_gotoxy(0, 0);
 | 
        
           |  |  | 749 |     }    
 | 
        
           |  |  | 750 |   | 
        
           |  |  | 751 |    if(line<lcd_lines)
 | 
        
           |  |  | 752 |     {
 | 
        
           |  |  | 753 |        lcd_gotoxy(0, line);
 | 
        
           |  |  | 754 |        while(x<lcd_chars_per_line) { lcd_putc(' '); }
 | 
        
           |  |  | 755 |        lcd_gotoxy(0, line);
 | 
        
           |  |  | 756 |     }   
 | 
        
           |  |  | 757 |   | 
        
           |  |  | 758 | #elif LCD_IO_MODE == 6 || LCD_IO_MODE == 2
 | 
        
           |  |  | 759 |   | 
        
           |  |  | 760 | #if LCD_LINES == 1
 | 
        
           |  |  | 761 |   lcd_gotoxy(0, 0);
 | 
        
           |  |  | 762 |   while(x<LCD_CHARS_PER_LINE) { lcd_putc(' '); }
 | 
        
           |  |  | 763 |   lcd_gotoxy(0, 0);
 | 
        
           |  |  | 764 | #else  /* #if LCD_LINES == 1 */
 | 
        
           |  |  | 765 |   if(line<LCD_LINES)
 | 
        
           |  |  | 766 |    {
 | 
        
           |  |  | 767 |       lcd_gotoxy(0, line);
 | 
        
           |  |  | 768 |       while(x<LCD_CHARS_PER_LINE) { lcd_putc(' '); }
 | 
        
           |  |  | 769 |       lcd_gotoxy(0, line);
 | 
        
           |  |  | 770 |    }   
 | 
        
           |  |  | 771 | #endif  /*  #if LCD_LINES == 1  */
 | 
        
           |  |  | 772 | #endif  /*  #if LCD_IO_MODE == 7 */
 | 
        
           |  |  | 773 | }
 | 
        
           |  |  | 774 | /*######################################################################################################*/
 | 
        
           |  |  | 775 |   | 
        
           |  |  | 776 | void lcd_home(void)
 | 
        
           |  |  | 777 | /* set cursor to home position */
 | 
        
           |  |  | 778 | {
 | 
        
           |  |  | 779 |     lcd_command(1<<LCD_HOME);
 | 
        
           |  |  | 780 | #if LCD_READ_REQUIRED == 0 || LCD_IO_MODE == 2 || LCD_IO_MODE == 7
 | 
        
           |  |  | 781 |     delay(LCD_DELAY_LONG);       /* this command needs more waiting time to execute */
 | 
        
           |  |  | 782 | #elif LCD_READ_REQUIRED == 1 && LCD_IO_MODE == 6 
 | 
        
           |  |  | 783 |     lcd_waitbusy();
 | 
        
           |  |  | 784 | #endif    
 | 
        
           |  |  | 785 |     x=0; y=0;
 | 
        
           |  |  | 786 | }
 | 
        
           |  |  | 787 | /*######################################################################################################*/
 | 
        
           |  |  | 788 |   | 
        
           |  |  | 789 | void lcd_putc(unsigned char c)
 | 
        
           |  |  | 790 | /* print character at current cursor position */
 | 
        
           |  |  | 791 | {
 | 
        
           |  |  | 792 |  if(!putc_lock)
 | 
        
           |  |  | 793 |   {
 | 
        
           |  |  | 794 | #if LCD_IO_MODE == 7
 | 
        
           |  |  | 795 |    if(lcd_lines !=1)
 | 
        
           |  |  | 796 |     {  if(c=='\n') { if(y<lcd_lines-1) lcd_gotoxy(0,(y+1)); }
 | 
        
           |  |  | 797 |        else if(x<lcd_chars_per_line) { lcd_write(c, DATA_MODE); x++; }
 | 
        
           |  |  | 798 | #if LCD_AUTO_LINE_FEED == 1
 | 
        
           |  |  | 799 |        else if(y<lcd_lines-1) { lcd_gotoxy(0,(y+1)); lcd_write(c, DATA_MODE); x++; }
 | 
        
           |  |  | 800 |        else { lcd_gotoxy(0,0); lcd_write(c, DATA_MODE); x++; }
 | 
        
           |  |  | 801 | #endif
 | 
        
           |  |  | 802 |     }
 | 
        
           |  |  | 803 |    else{
 | 
        
           |  |  | 804 |          if(c=='\n') { return; }
 | 
        
           |  |  | 805 |          if(x<lcd_chars_per_line) { lcd_write(c, DATA_MODE); x++; }
 | 
        
           |  |  | 806 |        }
 | 
        
           |  |  | 807 | #elif LCD_IO_MODE == 6 || LCD_IO_MODE == 2
 | 
        
           |  |  | 808 |   | 
        
           |  |  | 809 | #if LCD_LINES!=1
 | 
        
           |  |  | 810 |        if(c=='\n') { if(y<LCD_LINES-1) lcd_gotoxy(0,(y+1)); }
 | 
        
           |  |  | 811 |        else if(x<LCD_CHARS_PER_LINE) { lcd_write(c, DATA_MODE); x++; }
 | 
        
           |  |  | 812 | #if LCD_AUTO_LINE_FEED == 1
 | 
        
           |  |  | 813 |        else if(y<LCD_LINES-1) { lcd_gotoxy(0,(y+1)); lcd_write(c, DATA_MODE); x++; }
 | 
        
           |  |  | 814 |        else { lcd_gotoxy(0,0); lcd_write(c, DATA_MODE); x++; }
 | 
        
           |  |  | 815 | #endif
 | 
        
           |  |  | 816 |   | 
        
           |  |  | 817 | #else
 | 
        
           |  |  | 818 |        if(c=='\n') { return; }
 | 
        
           |  |  | 819 |        if(x<LCD_CHARS_PER_LINE) { lcd_write(c, DATA_MODE); x++; }
 | 
        
           |  |  | 820 | #endif
 | 
        
           |  |  | 821 |   | 
        
           |  |  | 822 | #endif  /*   #if LCD_IO_MODE == 7  */       
 | 
        
           |  |  | 823 |   }  
 | 
        
           |  |  | 824 | }
 | 
        
           |  |  | 825 | /*######################################################################################################*/
 | 
        
           |  |  | 826 |   | 
        
           |  |  | 827 | void lcd_puts(const unsigned char *s)
 | 
        
           |  |  | 828 | /* print string on lcd (no auto linefeed) */
 | 
        
           |  |  | 829 | {
 | 
        
           |  |  | 830 |     register unsigned char c;
 | 
        
           |  |  | 831 |   | 
        
           |  |  | 832 |     while ( (c = *s++) ) { lcd_putc(c);  }
 | 
        
           |  |  | 833 |   | 
        
           |  |  | 834 | }
 | 
        
           |  |  | 835 | /*######################################################################################################*/
 | 
        
           |  |  | 836 |   | 
        
           |  |  | 837 | void lcd_puts_p(const unsigned char *progmem_s)
 | 
        
           |  |  | 838 | /* print string from program memory on lcd (no auto linefeed) */
 | 
        
           |  |  | 839 | {
 | 
        
           |  |  | 840 |     register unsigned char c;
 | 
        
           |  |  | 841 |   | 
        
           |  |  | 842 |     while ( (c = PRG_RDB(progmem_s++)) ) { lcd_putc(c);  }
 | 
        
           |  |  | 843 |   | 
        
           |  |  | 844 | }
 | 
        
           |  |  | 845 | /*######################################################################################################*/
 | 
        
           |  |  | 846 |   | 
        
           |  |  | 847 | void lcd_puts_e(unsigned char *eeprom_s)
 | 
        
           |  |  | 848 | /* print string from eeprom on lcd (no auto linefeed) */
 | 
        
           |  |  | 849 | {
 | 
        
           |  |  | 850 |  register unsigned char c;
 | 
        
           |  |  | 851 |   | 
        
           |  |  | 852 |     while( (c=eeprom_rb((unsigned int)eeprom_s++))&& c!=0xFF ) { lcd_putc(c);  }
 | 
        
           |  |  | 853 |     /*{ if(c==0xFF) break; lcd_putc(c);  }*/               
 | 
        
           |  |  | 854 | }
 | 
        
           |  |  | 855 | /*######################################################################################################*/
 | 
        
           |  |  | 856 |   | 
        
           |  |  | 857 | void lcd_puti(int value, unsigned char dot_position)
 | 
        
           |  |  | 858 | /* print signed integer on lcd with or without comma (no auto linefeed) */
 | 
        
           |  |  | 859 | {
 | 
        
           |  |  | 860 | unsigned char lcd_data[6]={'0','0','0','0','0','0' }, position=sizeof(lcd_data), radix=10; 
 | 
        
           |  |  | 861 |   | 
        
           |  |  | 862 |         /* convert int to ascii  */ 
 | 
        
           |  |  | 863 |         if(value<0) { lcd_putc('-'); value=-value; }    
 | 
        
           |  |  | 864 |         do { position--; *(lcd_data+position)=(value%radix)+'0'; value/=radix;  } while(value); 
 | 
        
           |  |  | 865 |   | 
        
           |  |  | 866 |         /* some fractional digit corrections  */
 | 
        
           |  |  | 867 |         if( dot_position>=sizeof(lcd_data) ) return;
 | 
        
           |  |  | 868 |         while( (sizeof(lcd_data)-dot_position)<=position )  position--; 
 | 
        
           |  |  | 869 |   | 
        
           |  |  | 870 |         /* start displaying the number */
 | 
        
           |  |  | 871 |         for(;position<=(sizeof(lcd_data)-1);position++)
 | 
        
           |  |  | 872 |           {
 | 
        
           |  |  | 873 |             if( position==sizeof(lcd_data)-dot_position ) lcd_putc(',');  
 | 
        
           |  |  | 874 |             lcd_putc(lcd_data[position]);
 | 
        
           |  |  | 875 |           }
 | 
        
           |  |  | 876 |   | 
        
           |  |  | 877 | return;
 | 
        
           |  |  | 878 | }
 | 
        
           |  |  | 879 | /*######################################################################################################*/
 | 
        
           |  |  | 880 | #if LCD_IO_MODE == 6 || LCD_IO_MODE == 2
 | 
        
           |  |  | 881 | /*######################################################################################################*/
 | 
        
           |  |  | 882 |   | 
        
           |  |  | 883 | void lcd_init(void)
 | 
        
           |  |  | 884 | {
 | 
        
           |  |  | 885 | /* initialize display and select type of cursor */
 | 
        
           |  |  | 886 | /* dispAttr: LCD_DISP_OFF, LCD_DISP_ON, LCD_DISP_ON_CURSOR, LCD_DISP_CURSOR_BLINK */
 | 
        
           |  |  | 887 |   | 
        
           |  |  | 888 | #if LCD_LINES==1
 | 
        
           |  |  | 889 | #define LCD_FUNCTION_DEFAULT    LCD_FUNCTION_4BIT_1LINE 
 | 
        
           |  |  | 890 | #else
 | 
        
           |  |  | 891 | #define LCD_FUNCTION_DEFAULT    LCD_FUNCTION_4BIT_2LINES 
 | 
        
           |  |  | 892 | #endif 
 | 
        
           |  |  | 893 |   | 
        
           |  |  | 894 | #if LCD_IO_MODE == 6  
 | 
        
           |  |  | 895 |   | 
        
           |  |  | 896 | #if LCD_E_PORT_IS_IO==1
 | 
        
           |  |  | 897 | sbi(LCD_E_DDR_REG, LCD_E_PIN  );
 | 
        
           |  |  | 898 | #endif        
 | 
        
           |  |  | 899 | sbi(LCD_E_PORT, LCD_E_PIN  ); 
 | 
        
           |  |  | 900 |   | 
        
           |  |  | 901 | #if LCD_MULTIPLEX_ENABLE == 0 
 | 
        
           |  |  | 902 |   | 
        
           |  |  | 903 | #if LCD_D4_PORT_IS_IO==1
 | 
        
           |  |  | 904 | sbi(LCD_D4_DDR_REG, LCD_D4_PIN );
 | 
        
           |  |  | 905 | #endif
 | 
        
           |  |  | 906 | #if LCD_D5_PORT_IS_IO==1
 | 
        
           |  |  | 907 | sbi(LCD_D5_DDR_REG, LCD_D5_PIN );
 | 
        
           |  |  | 908 | #endif
 | 
        
           |  |  | 909 | #if LCD_D6_PORT_IS_IO==1
 | 
        
           |  |  | 910 | sbi(LCD_D6_DDR_REG, LCD_D6_PIN );
 | 
        
           |  |  | 911 | #endif
 | 
        
           |  |  | 912 | #if LCD_D7_PORT_IS_IO==1
 | 
        
           |  |  | 913 | sbi(LCD_D7_DDR_REG, LCD_D7_PIN );
 | 
        
           |  |  | 914 | #endif
 | 
        
           |  |  | 915 | #if LCD_RS_PORT_IS_IO==1
 | 
        
           |  |  | 916 | sbi(LCD_RS_DDR_REG, LCD_RS_PIN );
 | 
        
           |  |  | 917 | #endif
 | 
        
           |  |  | 918 |   | 
        
           |  |  | 919 | #if LCD_READ_REQUIRED == 1 
 | 
        
           |  |  | 920 | #if  LCD_RW_PORT_IS_IO == 1
 | 
        
           |  |  | 921 | sbi(LCD_RW_DDR_REG, LCD_RW_PIN  );
 | 
        
           |  |  | 922 | #endif
 | 
        
           |  |  | 923 | cbi(LCD_RW_PORT, LCD_RW_PIN  ); 
 | 
        
           |  |  | 924 | #endif
 | 
        
           |  |  | 925 |   | 
        
           |  |  | 926 | #endif  /* #if LCD_MULTIPLEX_ENABLE == 0 */
 | 
        
           |  |  | 927 |   | 
        
           |  |  | 928 | #endif  /* #if LCD_IO_MODE == 6 */
 | 
        
           |  |  | 929 |   | 
        
           |  |  | 930 | /*------ Initialize lcd to 4 bit i/o mode -------*/
 | 
        
           |  |  | 931 | /* initial write to lcd is 8bit using delay since busy flag can't be checked here anyway */
 | 
        
           |  |  | 932 |   | 
        
           |  |  | 933 |     delay(LCD_POWER_ON_DELAY);                          /* Wait 20 milliseconds  */
 | 
        
           |  |  | 934 |   | 
        
           |  |  | 935 |     lcd_write(LCD_FUNCTION_8BIT_1LINE, INIT_MODE);
 | 
        
           |  |  | 936 |     delay(LCD_INIT_DELAY);                              /* Wait 5 milliseconds */
 | 
        
           |  |  | 937 |   | 
        
           |  |  | 938 |     lcd_write(LCD_FUNCTION_8BIT_1LINE, INIT_MODE);
 | 
        
           |  |  | 939 |   | 
        
           |  |  | 940 |     lcd_write(LCD_FUNCTION_8BIT_1LINE, INIT_MODE);
 | 
        
           |  |  | 941 |   | 
        
           |  |  | 942 |     lcd_write(LCD_FUNCTION_4BIT_1LINE, INIT_MODE);      /* set IO mode to 4bit */
 | 
        
           |  |  | 943 |   | 
        
           |  |  | 944 |   | 
        
           |  |  | 945 |     /* from now on the lcd accepts only 4 bit I/O, so we can use lcd_command() */    
 | 
        
           |  |  | 946 |   | 
        
           |  |  | 947 |     lcd_command(LCD_FUNCTION_DEFAULT);      /* function set: display lines  */
 | 
        
           |  |  | 948 |     lcd_command(LCD_DISP_OFF);              /* display off                  */
 | 
        
           |  |  | 949 |     lcd_clrscr();                           /* display clear                */ 
 | 
        
           |  |  | 950 |     lcd_command(LCD_MODE_DEFAULT);          /* set entry mode               */
 | 
        
           |  |  | 951 |     lcd_command(LCD_DISP_ON);               /* LCD DISPLAY ON (DEFAULT)     */
 | 
        
           |  |  | 952 |   | 
        
           |  |  | 953 | }/* lcd_init */
 | 
        
           |  |  | 954 | /*######################################################################################################*/
 | 
        
           |  |  | 955 | #elif LCD_IO_MODE == 7 
 | 
        
           |  |  | 956 | /*######################################################################################################*/
 | 
        
           |  |  | 957 |   | 
        
           |  |  | 958 | void lcd_init(void)
 | 
        
           |  |  | 959 | {
 | 
        
           |  |  | 960 | unsigned char lcd_unit=0;
 | 
        
           |  |  | 961 | /* initialize display and select type of cursor */
 | 
        
           |  |  | 962 | /* dispAttr: LCD_DISP_OFF, LCD_DISP_ON, LCD_DISP_ON_CURSOR, LCD_DISP_CURSOR_BLINK */
 | 
        
           |  |  | 963 |   | 
        
           |  |  | 964 | #if LCD_D4_PORT_IS_IO == 1
 | 
        
           |  |  | 965 | sbi(LCD_D4_DDR_REG, LCD_D4_PIN );
 | 
        
           |  |  | 966 | #endif
 | 
        
           |  |  | 967 | #if LCD_D5_PORT_IS_IO == 1
 | 
        
           |  |  | 968 | sbi(LCD_D5_DDR_REG, LCD_D5_PIN );
 | 
        
           |  |  | 969 | #endif
 | 
        
           |  |  | 970 | #if LCD_D6_PORT_IS_IO == 1
 | 
        
           |  |  | 971 | sbi(LCD_D6_DDR_REG, LCD_D6_PIN );
 | 
        
           |  |  | 972 | #endif
 | 
        
           |  |  | 973 | #if LCD_D7_PORT_IS_IO == 1
 | 
        
           |  |  | 974 | sbi(LCD_D7_DDR_REG, LCD_D7_PIN );
 | 
        
           |  |  | 975 | #endif
 | 
        
           |  |  | 976 | #if LCD_RS_PORT_IS_IO == 1
 | 
        
           |  |  | 977 | sbi(LCD_RS_DDR_REG, LCD_RS_PIN );
 | 
        
           |  |  | 978 | #endif
 | 
        
           |  |  | 979 |   | 
        
           |  |  | 980 | #if LCD_0_E_PORT_IS_IO == 1
 | 
        
           |  |  | 981 | sbi(LCD_0_E_DDR_REG, LCD_0_E_PIN  );                 
 | 
        
           |  |  | 982 | #endif        
 | 
        
           |  |  | 983 | sbi(LCD_0_E_PORT, LCD_0_E_PIN  ); 
 | 
        
           |  |  | 984 |   | 
        
           |  |  | 985 | #if LCD_1_E_PORT_IS_IO == 1
 | 
        
           |  |  | 986 | sbi(LCD_1_E_DDR_REG, LCD_1_E_PIN  );                 
 | 
        
           |  |  | 987 | #endif        
 | 
        
           |  |  | 988 | sbi(LCD_1_E_PORT, LCD_1_E_PIN  ); 
 | 
        
           |  |  | 989 |   | 
        
           |  |  | 990 | #if NUMBER_OF_LCD_UNITS >= 3
 | 
        
           |  |  | 991 | #if LCD_2_E_PORT_IS_IO == 1
 | 
        
           |  |  | 992 | sbi(LCD_2_E_DDR_REG, LCD_2_E_PIN  );                 
 | 
        
           |  |  | 993 | #endif        
 | 
        
           |  |  | 994 | sbi(LCD_2_E_PORT, LCD_2_E_PIN  );
 | 
        
           |  |  | 995 | #endif 
 | 
        
           |  |  | 996 |   | 
        
           |  |  | 997 | /*------ Initialize lcd to 4 bit i/o mode -------*/
 | 
        
           |  |  | 998 | /* initial write to lcd is 8bit using delay since busy flag can't be checked here anyway */
 | 
        
           |  |  | 999 |     xy_coordinates[LCD_0].x=0;
 | 
        
           |  |  | 1000 |     xy_coordinates[LCD_0].y=0;
 | 
        
           |  |  | 1001 |     xy_coordinates[LCD_1].x=0;
 | 
        
           |  |  | 1002 |     xy_coordinates[LCD_1].y=0;
 | 
        
           |  |  | 1003 | #if NUMBER_OF_LCD_UNITS >=3
 | 
        
           |  |  | 1004 |     xy_coordinates[LCD_2].x=0;
 | 
        
           |  |  | 1005 |     xy_coordinates[LCD_2].y=0;
 | 
        
           |  |  | 1006 | #endif
 | 
        
           |  |  | 1007 |   | 
        
           |  |  | 1008 |   | 
        
           |  |  | 1009 | for(lcd_unit=0; lcd_unit<NUMBER_OF_LCD_UNITS; lcd_unit++)
 | 
        
           |  |  | 1010 |   {
 | 
        
           |  |  | 1011 |       select_lcd(lcd_unit);
 | 
        
           |  |  | 1012 |   | 
        
           |  |  | 1013 |       delay(LCD_POWER_ON_DELAY);                          /* Wait 20 milliseconds  */
 | 
        
           |  |  | 1014 |       lcd_write(LCD_FUNCTION_8BIT_1LINE, INIT_MODE);
 | 
        
           |  |  | 1015 |       delay(LCD_INIT_DELAY);                              /* Wait 5 milliseconds */
 | 
        
           |  |  | 1016 |       lcd_write(LCD_FUNCTION_8BIT_1LINE, INIT_MODE);
 | 
        
           |  |  | 1017 |       lcd_write(LCD_FUNCTION_8BIT_1LINE, INIT_MODE);
 | 
        
           |  |  | 1018 |       lcd_write(LCD_FUNCTION_4BIT_1LINE, INIT_MODE);      /* set IO mode to 4bit */
 | 
        
           |  |  | 1019 |   | 
        
           |  |  | 1020 |       /* from now on the lcd accepts only 4 bit I/O, so we can use lcd_command() */    
 | 
        
           |  |  | 1021 |       /* function set: set how many lines the lcd unit has.  */
 | 
        
           |  |  | 1022 |       if(lcd_lines==1) { lcd_command(LCD_FUNCTION_4BIT_1LINE);  }  
 | 
        
           |  |  | 1023 |       else { lcd_command(LCD_FUNCTION_4BIT_2LINES); }
 | 
        
           |  |  | 1024 |   | 
        
           |  |  | 1025 |       lcd_command(LCD_DISP_OFF);                               /* display off                  */
 | 
        
           |  |  | 1026 |       lcd_clrscr();                                            /* display clear                */ 
 | 
        
           |  |  | 1027 |       lcd_command(LCD_MODE_DEFAULT);                           /* set entry mode               */
 | 
        
           |  |  | 1028 |       lcd_command(LCD_DISP_ON);                                /* Display on                   */
 | 
        
           |  |  | 1029 |   | 
        
           |  |  | 1030 |   } 
 | 
        
           |  |  | 1031 | select_lcd(0);
 | 
        
           |  |  | 1032 |   | 
        
           |  |  | 1033 | return;  
 | 
        
           |  |  | 1034 | }/* lcd_init */
 | 
        
           |  |  | 1035 |   | 
        
           |  |  | 1036 | #endif
 | 
        
           |  |  | 1037 | /*######################################################################################################*/
 | 
        
           |  |  | 1038 | /*                                         T H E   E N D                                                */
 | 
        
           |  |  | 1039 | /*######################################################################################################*/
 | 
        
           |  |  | 1040 |   |