1 /*****************************************************************************
\r
2 ** FILE IDENTIFICATION
\r
4 ** Name: serial_lcd.h
\r
5 ** Purpose: Common header file for serial_lcd.c and serial_lcd.cpp
\r
6 ** Programmer: Kevin Rosenberg <kevin@rosenberg.net> (AVR Freaks member kmr)
\r
7 ** Date Started: Dec 2007
\r
9 ** Copyright (c) 2007-2008 by Kevin Rosenberg
\r
10 *******************************************************************************/
\r
12 #ifndef __SERIAL_LCD_H__
\r
13 #define __SERIAL_LCD_H__ 1
\r
16 #define F_CPU 14745600UL
\r
19 #define CONSERVATIVE_ENABLE_DURATION 0
\r
22 // Set STANDALONE_SOURCE as 1 to compile without KMR's standard header files, using
\r
23 // the below excerpts from these files
\r
24 #define STANDALONE_SOURCE 1
\r
25 #if STANDALONE_SOURCE
\r
27 #if defined(__GNUC__)
\r
29 #include <avr/pgmspace.h>
\r
30 #include <avr/sleep.h>
\r
31 #include <avr/interrupt.h>
\r
32 #include <avr/wdt.h>
\r
33 #include <util/delay.h>
\r
47 #define FLASH_DECLARE(x) const x __attribute__((progmem))
\r
48 #define NO_INIT_DECLARE(x) x __attribute__((section (".noinit")))
\r
49 #define INLINE_FUNC_DECLARE(x) inline x __attribute__((always_inline))
\r
50 #define PGM_READ_BYTE(x) pgm_read_byte(x)
\r
51 #define NOP() asm volatile("nop");
\r
52 #define REGISTER_BIT(rg,bt) ((volatile _io_reg*)_SFR_MEM_ADDR(rg))->bit##bt
\r
53 #define REGISTER_VAR(V,GNU,IAR) register volatile V asm(GNU)
\r
54 #define NO_RETURN_FUNC(fn) fn __attribute__((noreturn)); \
\r
56 #define MAIN_FUNC() int main(void) __attribute__((OS_main)); \
\r
58 #define MAIN_FUNC_LAST() return 0
\r
60 #elif defined(__ICCAVR__)
\r
62 #include <intrinsics.h>
\r
64 // Ensure that register/vector definitions match datasheet/GCC
\r
65 #if defined(__ATtiny2313__)
\r
66 #if !defined(WDTCSR)
\r
67 #define WDTCSR WDTCR
\r
69 #if defined(USART0_RX_vect) && !defined(USART_RX_vect)
\r
70 #define USART_RX_vect USART0_RX_vect
\r
74 #define FLASH_DECLARE(x) __flash x
\r
75 #define PRAGMA(x) _Pragma(#x)
\r
76 #define NO_INIT_DECLARE(x) __no_init x
\r
77 #define INLINE_FUNC_DECLARE(x) PRAGMA(inline=forced) \
\r
79 #define PGM_READ_BYTE(x) (*(x))
\r
80 #define NOP() __no_operation();
\r
81 #define REGISTER_BIT(rg,bt) rg##_Bit##bt
\r
82 #define REGISTER_VAR(V,GNU,IAR) __regvar __no_init V @ ## IAR
\r
83 #define ISR(x) PRAGMA(vector=x) \
\r
84 __interrupt void x##_handler(void); \
\r
85 __interrupt void x##_handler(void)
\r
86 #define NO_RETURN_FUNC(fn) __C_task fn
\r
87 #define MAIN_FUNC() __task void main(void)
\r
88 #define MAIN_FUNC_LAST()
\r
89 #define cli() __disable_interrupt()
\r
90 #define sei() __enable_interrupt()
\r
91 #define wdt_reset() __watchdog_reset()
\r
92 #define _delay_us(us) __delay_cycles((unsigned long)(((us * F_CPU)/1e6) + 0.5))
\r
93 #define _delay_ms(ms) __delay_cycles((unsigned long)(((ms * F_CPU)/1e3) + 0.5))
\r
94 #define sleep_cpu() __sleep()
\r
95 #if defined(__ATtiny2313__)
\r
96 #define sleep_enable() MCUCR |= (1<<SE)
\r
97 #define sleep_disable() MCUCR &= ~(1<<SE)
\r
99 typedef __flash unsigned char prog_uint8_t;
\r
100 typedef __flash unsigned int prog_uint16_t;
\r
101 typedef __flash unsigned int prog_uint32_t;
\r
103 #elif defined(__IMAGECRAFT__)
\r
105 // Below #include requires ICC v7.16+
\r
106 #include <iccioavr.h>
\r
118 #define NOP() asm("nop");
\r
119 // ImageCraft does not support inline functions
\r
121 #define INLINE_FUNC_DECLARE(x) x
\r
122 #define REGISTER_BIT(rg,bt) ((volatile _io_reg*)&rg)->bit##bt
\r
123 #define NO_RETURN_FUNC(fn) fn
\r
124 #define MAIN_FUNC() void main(void)
\r
125 #define MAIN_FUNC_LAST()
\r
126 // __flash keyword was introduced in Imagecraft v7.15
\r
127 #define FLASH_DECLARE(x) __flash x
\r
128 #define PGM_READ_BYTE(x) (*(x))
\r
129 #define cli() asm("cli")
\r
130 #define sei() asm("sei")
\r
131 #define wdt_reset() asm("wdr")
\r
132 #define sleep_cpu() asm("sleep")
\r
133 // Below two definition specific for ATTiny2313 compatible sleep enable
\r
134 #define sleep_enable() MCUCR |= (1<<SE)
\r
135 #define sleep_disable() MCUCR &= ~(1<<SE)
\r
137 // CodeVision Compiler
\r
138 #elif defined(__CODEVISIONAVR__)
\r
152 #define FLASH_DECLARE(x) flash x
\r
153 #define ASM(a) asm(a)
\r
154 #define NOP() asm("nop");
\r
156 #define INLINE_FUNC_DECLARE(x) x
\r
157 #define REGISTER_BIT(rg,bt) ((volatile _io_reg*)&rg)->bit##bt
\r
158 #define NEAR_VAR(x) x
\r
159 #define NO_RETURN_FUNC(fn) fn
\r
160 #define MAIN_FUNC(fn) fn
\r
161 #define MAIN_FUNC() void main(void)
\r
162 #define MAIN_FUNC_LAST()
\r
164 // 2007/11/29 - ImageCraft states they will support _Pragma() like IAR
\r
165 // in a "few months". At that point, REGISTER_VAR and NO_INIT_DECLARE can
\r
166 // be supported. REGISTER_VAR will need to be expanded with 4th variable to
\r
167 // hold register number for ImageCraft.
\r
168 // noinit for ImageCraft requires #pragma data:noinit
\r
169 //#define NO_INIT_DECLARE(x) _Pragma(data:noinit); x; _Pragma(data:data);
\r
170 #define NO_INIT_DECLARE(x) x
\r
171 //#define REGISTER_VAR(V,GNUR,IAR,ICC) _Pragma(global_register V ## : ## ICC)
\r
172 #define REGISTER_VAR(V,GNUR,IAR) V
\r
174 #define cli() asm("cli")
\r
175 #define sei() asm("sei")
\r
176 #define wdt_reset() asm("wdr")
\r
179 #error Unsupported compiler
\r
183 // Use local cross-compiler compability files
\r
184 #include "kavr_compat.h"
\r
185 #include "ksleep.h"
\r
186 #include "kdelay.h"
\r
190 /*************************************************************/
\r
191 /*************************************************************/
\r
193 /* //// From the LCD perspective \\\\
\r
195 LED <-- PORTD:1 // High = ON, Low = OFF
\r
196 J_1 --> PORTD:2 // BAUD rate select
\r
197 J_2 --> PORTD:3 // BAUD rate select
\r
198 LCD:R/W <-- PORTD:4
\r
203 LCD:R/W <-- PORTD:4
\r
206 LCD:Vee <-- CONTRAST
\r
207 LCD:DB0 <-- PORTB:0
\r
208 LCD:DB1 <-- PORTB:1
\r
209 LCD:DB2 <-- PORTB:2
\r
210 LCD:DB3 <-- PORTB:3
\r
211 LCD:DB4 <-- 4.7K Ohm <-- PORTx:4
\r
212 LCD:DB5 <-- 4.7K Ohm <-- PORTx:5
\r
213 LCD:DB6 <-- 4.7K Ohm <-- PORTx:6
\r
214 LCD:DB7 <-- 4.7K Ohm <-- PORTx:7
\r
216 //// From the I/O PORTx perspective \\\\
\r
218 PORTD:1 --> LED // High = ON, Low = OFF
\r
219 PORTD:2 <-- J_1 // BAUD rate select
\r
220 PORTD:3 <-- J_2 // BAUD rate select
\r
221 PORTD:4 --> LCD:R/W
\r
226 PORTB:0 --> LCD:DB0
\r
227 PORTB:1 --> LCD:DB1
\r
228 PORTB:2 --> LCD:DB2
\r
229 PORTB:3 --> LCD:DB3
\r
230 PORTB:4 --> 4.7K Ohm --> LCD:DB4
\r
231 PORTB:5 --> 4.7K Ohm --> LCD:DB5
\r
232 PORTB:6 --> 4.7K Ohm --> LCD:DB6
\r
233 PORTB:7 --> 4.7K Ohm --> LCD:DB7
\r
236 /*************************************************************/
\r
237 /*************************************************************/
\r
238 // If you want to use a different I/O port for LCD control & data,
\r
240 #define LCD_DATA_PORT PORTB
\r
241 #define LCD_DATA_PIN_REG PINB
\r
242 #define LCD_DATA_DIR DDRB
\r
244 #define LCD_CONTROL_PORT PORTD
\r
245 #define LCD_CONTROL_PIN_REG PIND
\r
246 #define LCD_CONTROL_DIR DDRD
\r
248 // LED backlight control pin
\r
249 #define LED_DIR DDRD
\r
250 #define LED_PORT PORTD
\r
251 #define LED_PIN PD1
\r
253 // LCD Read/Write Pin
\r
255 // LCD Register Select Pin
\r
259 /*************************************************************/
\r
260 /*************************************************************/
\r
262 // LCD busy status pin
\r
263 #define LCD_BUSY PB7
\r
265 // BAID rate setting pins
\r
266 #define BAUD_PORT PORTD
\r
267 #define BAUD_DIR DDRB
\r
268 #define BAUD_PIN_REG PIND
\r
269 #define BAUD_J1 PD2
\r
270 #define BAUD_J2 PD3
\r
273 // Direction register for clear to send signal
\r
274 #define CTS_DIR DDRA
\r
275 // Output port for clear to send signal
\r
276 #define CTS_PORT PORTA
\r
277 // Pin for clear to send signal (RESET pin on Tiny2313)
\r
278 // Ensure fuse is set to disable RESET function on RESET pin
\r
279 #define CTS_PIN PA2
\r
283 // PWeh must be 230nS minimum, nop = 67nS @ 14.7456MHz
\r
284 // At 4 cycles, E = 271nS
\r
285 // Some slow systems require 450ns, or 7 cycles at 14.7456MHz
\r
286 #if defined(__ICCAVR__)
\r
287 #if CONSERVATIVE_ENABLE_DURATION
\r
288 #define ENABLE_WAIT() __delay_cycles(7);
\r
290 #define ENABLE_WAIT() __delay_cycles(4);
\r
292 #elif defined(__GNUC__)
\r
293 static __inline__ void _NOP1 (void) { __asm__ volatile ( "nop " "\n\t" ); }
\r
294 static __inline__ void _NOP2 (void) { __asm__ volatile ( "rjmp 1f" "\n\t" "1:" "\n\t" ); }
\r
295 #if CONSERVATIVE_ENABLE_DURATION
\r
296 #define ENABLE_WAIT() _NOP2(); _NOP2(); _NOP2(); _NOP1();
\r
298 #define ENABLE_WAIT() _NOP2(); _NOP2();
\r
301 #if CONSERVATIVE_ENABLE_DURATION
\r
302 #define ENABLE_WAIT() NOP(); NOP(); NOP(); NOP(); NOP(); NOP(); NOP();
\r
304 #define ENABLE_WAIT() NOP(); NOP(); NOP(); NOP();
\r