1 |
786 |
skrzyp |
//==========================================================================
|
2 |
|
|
//
|
3 |
|
|
// olpce2294_misc.c
|
4 |
|
|
//
|
5 |
|
|
// HAL misc board support code for Olimex LPC-E2294 development board
|
6 |
|
|
//
|
7 |
|
|
//==========================================================================
|
8 |
|
|
// ####ECOSGPLCOPYRIGHTBEGIN####
|
9 |
|
|
// -------------------------------------------
|
10 |
|
|
// This file is part of eCos, the Embedded Configurable Operating System.
|
11 |
|
|
// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2008 Free Software Foundation, Inc.
|
12 |
|
|
//
|
13 |
|
|
// eCos is free software; you can redistribute it and/or modify it under
|
14 |
|
|
// the terms of the GNU General Public License as published by the Free
|
15 |
|
|
// Software Foundation; either version 2 or (at your option) any later
|
16 |
|
|
// version.
|
17 |
|
|
//
|
18 |
|
|
// eCos is distributed in the hope that it will be useful, but WITHOUT
|
19 |
|
|
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
20 |
|
|
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
21 |
|
|
// for more details.
|
22 |
|
|
//
|
23 |
|
|
// You should have received a copy of the GNU General Public License
|
24 |
|
|
// along with eCos; if not, write to the Free Software Foundation, Inc.,
|
25 |
|
|
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
26 |
|
|
//
|
27 |
|
|
// As a special exception, if other files instantiate templates or use
|
28 |
|
|
// macros or inline functions from this file, or you compile this file
|
29 |
|
|
// and link it with other works to produce a work based on this file,
|
30 |
|
|
// this file does not by itself cause the resulting work to be covered by
|
31 |
|
|
// the GNU General Public License. However the source code for this file
|
32 |
|
|
// must still be made available in accordance with section (3) of the GNU
|
33 |
|
|
// General Public License v2.
|
34 |
|
|
//
|
35 |
|
|
// This exception does not invalidate any other reasons why a work based
|
36 |
|
|
// on this file might be covered by the GNU General Public License.
|
37 |
|
|
// -------------------------------------------
|
38 |
|
|
// ####ECOSGPLCOPYRIGHTEND####
|
39 |
|
|
//==========================================================================
|
40 |
|
|
//#####DESCRIPTIONBEGIN####
|
41 |
|
|
//
|
42 |
|
|
// Author(s): Sergei Gavrikov
|
43 |
|
|
// Contributors: Sergei Gavrikov
|
44 |
|
|
// Date: 2008-08-31
|
45 |
|
|
// Purpose: HAL board support
|
46 |
|
|
// Description: Implementations of HAL board interfaces
|
47 |
|
|
//
|
48 |
|
|
//####DESCRIPTIONEND####
|
49 |
|
|
//
|
50 |
|
|
//========================================================================*/
|
51 |
|
|
|
52 |
|
|
#include <pkgconf/hal.h>
|
53 |
|
|
#include <cyg/hal/hal_io.h> // IO macros
|
54 |
|
|
#include <cyg/infra/cyg_type.h> // base types
|
55 |
|
|
|
56 |
|
|
#include <cyg/hal/var_io.h>
|
57 |
|
|
#include <cyg/hal/plf_io.h>
|
58 |
|
|
|
59 |
|
|
#include <cyg/hal/hal_intr.h> // Interrupt macros
|
60 |
|
|
#include <cyg/hal/hal_arch.h> // SAVE/RESTORE GP
|
61 |
|
|
#include <cyg/hal/hal_if.h>
|
62 |
|
|
#include <cyg/hal/hal_diag.h> // HAL_DELAY_US
|
63 |
|
|
|
64 |
|
|
extern void cyg_hal_plf_serial_init (void);
|
65 |
|
|
|
66 |
|
|
static void cyg_hal_plf_lcd_init (void);
|
67 |
|
|
|
68 |
|
|
// There are no diagnostic leds on the board, but there is a LCD there with a
|
69 |
|
|
// BACKLIGHT feature. So, we can drive by BACKLIGHT put on a cathode a static
|
70 |
|
|
// signal.
|
71 |
|
|
|
72 |
|
|
inline static void
|
73 |
|
|
_fake_led (bool state)
|
74 |
|
|
{
|
75 |
|
|
HAL_WRITE_UINT32 (CYGARC_HAL_LPC2XXX_REG_IO_BASE +
|
76 |
|
|
CYGARC_HAL_LPC2XXX_REG_IO0CLR, (1 << 10));
|
77 |
|
|
if (state) {
|
78 |
|
|
HAL_WRITE_UINT32 (CYGARC_HAL_LPC2XXX_REG_IO_BASE +
|
79 |
|
|
CYGARC_HAL_LPC2XXX_REG_IO0SET, (1 << 10));
|
80 |
|
|
}
|
81 |
|
|
}
|
82 |
|
|
|
83 |
|
|
//--------------------------------------------------------------------------
|
84 |
|
|
// hal_lpc2xxx_set_leds --
|
85 |
|
|
//
|
86 |
|
|
void
|
87 |
|
|
hal_lpc2xxx_set_leds (int mask)
|
88 |
|
|
{
|
89 |
|
|
_fake_led (mask & 1);
|
90 |
|
|
}
|
91 |
|
|
|
92 |
|
|
//--------------------------------------------------------------------------
|
93 |
|
|
// cyg_hal_plf_comms_init --
|
94 |
|
|
//
|
95 |
|
|
void
|
96 |
|
|
cyg_hal_plf_comms_init (void)
|
97 |
|
|
{
|
98 |
|
|
static int initialized = 0;
|
99 |
|
|
|
100 |
|
|
if (initialized)
|
101 |
|
|
return;
|
102 |
|
|
initialized = 1;
|
103 |
|
|
|
104 |
|
|
cyg_hal_plf_serial_init ();
|
105 |
|
|
cyg_hal_plf_lcd_init ();
|
106 |
|
|
}
|
107 |
|
|
|
108 |
|
|
//--------------------------------------------------------------------------
|
109 |
|
|
// LCD driver (It is based on powerpc/cogent code)
|
110 |
|
|
//
|
111 |
|
|
// Olimex LPC-E2294 development board has a LCD 16x2 display (GDM1602K) with
|
112 |
|
|
// a built-in controller (KS0066U). The controller is the Hitachi HD44780
|
113 |
|
|
// compliant chip. Note: the LCD is driven in a 4-bit mode.
|
114 |
|
|
//--------------------------------------------------------------------------
|
115 |
|
|
|
116 |
|
|
#define LCD_BASE (void *)NULL
|
117 |
|
|
|
118 |
|
|
#define LCD_DATA 0x00 // read/write lcd data
|
119 |
|
|
#define LCD_STAT 0x08 // read lcd busy status
|
120 |
|
|
#define LCD_CMD 0x08 // write lcd command
|
121 |
|
|
|
122 |
|
|
// status register bit definitions
|
123 |
|
|
#define LCD_STAT_BUSY 0x80 // 1 = display busy
|
124 |
|
|
#define LCD_STAT_ADD 0x7F // bits 0-6 return current display address
|
125 |
|
|
|
126 |
|
|
// command register definitions
|
127 |
|
|
#define LCD_CMD_RST 0x01 // clear entire display and reset display address
|
128 |
|
|
#define LCD_CMD_HOME 0x02 // reset display address and reset any shifting
|
129 |
|
|
#define LCD_CMD_ECL 0x04 // move cursor left one position on next write
|
130 |
|
|
#define LCD_CMD_ESL 0x05 // shift display left one position on next write
|
131 |
|
|
#define LCD_CMD_ECR 0x06 // move cursor right one position on next write
|
132 |
|
|
#define LCD_CMD_ESR 0x07 // shift display right one position on next write
|
133 |
|
|
#define LCD_CMD_DOFF 0x08 // display off, cursor off, blinking off
|
134 |
|
|
#define LCD_CMD_BL 0x09 // blink character at current cursor position
|
135 |
|
|
#define LCD_CMD_CUR 0x0A // enable cursor on
|
136 |
|
|
#define LCD_CMD_DON 0x0C // turn display on
|
137 |
|
|
#define LCD_CMD_CL 0x10 // move cursor left one position
|
138 |
|
|
#define LCD_CMD_SL 0x14 // shift display left one position
|
139 |
|
|
#define LCD_CMD_CR 0x18 // move cursor right one position
|
140 |
|
|
#define LCD_CMD_SR 0x1C // shift display right one position
|
141 |
|
|
#define LCD_CMD_MODE 0x28 // sets 4 bits, 2 lines, 5x8 characters
|
142 |
|
|
#define LCD_CMD_ACG 0x40 // bits 0-5 sets the character generator address
|
143 |
|
|
#define LCD_CMD_ADD 0x80 // bits 0-6 sets the display data addr to line 1 +
|
144 |
|
|
|
145 |
|
|
// LCD status values
|
146 |
|
|
#define LCD_OK 0x00
|
147 |
|
|
#define LCD_ERR 0x01
|
148 |
|
|
|
149 |
|
|
#define LCD_LINE0 0x00 // DRAM address from 0x00 to 0x0f
|
150 |
|
|
#define LCD_LINE1 0x40 // DRAM address from 0x40 to 0x4f
|
151 |
|
|
#define LCD_LINE_LENGTH 16
|
152 |
|
|
|
153 |
|
|
static char lcd_line0[LCD_LINE_LENGTH + 1];
|
154 |
|
|
static char lcd_line1[LCD_LINE_LENGTH + 1];
|
155 |
|
|
static char *lcd_line[2] = { lcd_line0, lcd_line1 };
|
156 |
|
|
|
157 |
|
|
static int lcd_curline = 0;
|
158 |
|
|
static int lcd_linepos = 0;
|
159 |
|
|
|
160 |
|
|
// the LCD controller <--> MPU interface
|
161 |
|
|
#define MPU_DB 0x000000f0 // DB7...DB4 wired to P0.7...P0.4
|
162 |
|
|
#define MPU_RS 0x10000000 // RS wired to P0.28
|
163 |
|
|
#define MPU_EN 0x20000000 // EN wired to P0.29
|
164 |
|
|
#define MPU_RW 0x40000000 // RW wired to P0.30
|
165 |
|
|
#define MPU_XX 0x700000f0 // all MPU lines
|
166 |
|
|
|
167 |
|
|
// LCD DARKLIGHT cathode
|
168 |
|
|
#define DARKLIGHT 0x00000020 // P0.10
|
169 |
|
|
|
170 |
|
|
// Bus timing characteristics for Hitachi HD44780 compliant chips (when Vcc =
|
171 |
|
|
// 4.5 to 5.5 V):
|
172 |
|
|
// tcycE - enable cycle time, min 500 ns
|
173 |
|
|
// tPWEH - enable pulse width (high level), min 230 ns
|
174 |
|
|
// tAS - address setup time (RS, R/W to E), min 40 ns
|
175 |
|
|
// tAH - address hold time, min 10 ns
|
176 |
|
|
// tDDR - data delay time (read operations), max 160 ns
|
177 |
|
|
// tDSW - data setup time (write operations), min 80 ns
|
178 |
|
|
|
179 |
|
|
#define LCD_DELAY_US(_us_) HAL_DELAY_US (_us_)
|
180 |
|
|
|
181 |
|
|
// It should overrite the data delay time, i.e. be grater than 160 ns.
|
182 |
|
|
// WARNING: be careful with the delay value, more shorter delay would
|
183 |
|
|
// occur a dead loop when the BF (busy flag) is checked.
|
184 |
|
|
#define LCD_NANO_DELAY() \
|
185 |
|
|
CYG_MACRO_START \
|
186 |
|
|
int i; \
|
187 |
|
|
for (i = 0; i < 1; i++); \
|
188 |
|
|
CYG_MACRO_END
|
189 |
|
|
|
190 |
|
|
// It should overwrite the tPWEH (enable pulse width)
|
191 |
|
|
#define LCD_MICRO_DELAY() \
|
192 |
|
|
CYG_MACRO_START \
|
193 |
|
|
int i; \
|
194 |
|
|
for (i = 0; i < 3; i++); \
|
195 |
|
|
CYG_MACRO_END
|
196 |
|
|
|
197 |
|
|
// Set RS, R/W to read data
|
198 |
|
|
#define LCD_RS_READ_DATA() \
|
199 |
|
|
CYG_MACRO_START \
|
200 |
|
|
cyg_uint32 _t_; \
|
201 |
|
|
HAL_READ_UINT32(CYGARC_HAL_LPC2XXX_REG_IO_BASE + \
|
202 |
|
|
CYGARC_HAL_LPC2XXX_REG_IO0SET, _t_); \
|
203 |
|
|
_t_ |= MPU_RW | MPU_RS; \
|
204 |
|
|
HAL_WRITE_UINT32(CYGARC_HAL_LPC2XXX_REG_IO_BASE + \
|
205 |
|
|
CYGARC_HAL_LPC2XXX_REG_IO0SET, _t_); \
|
206 |
|
|
CYG_MACRO_END
|
207 |
|
|
|
208 |
|
|
// Set RS, R/W to read a busy flag and address counter
|
209 |
|
|
#define LCD_RS_READ_STAT() \
|
210 |
|
|
CYG_MACRO_START \
|
211 |
|
|
cyg_uint32 _t_; \
|
212 |
|
|
HAL_READ_UINT32(CYGARC_HAL_LPC2XXX_REG_IO_BASE + \
|
213 |
|
|
CYGARC_HAL_LPC2XXX_REG_IO0SET, _t_); \
|
214 |
|
|
_t_ |= MPU_RW; \
|
215 |
|
|
HAL_WRITE_UINT32(CYGARC_HAL_LPC2XXX_REG_IO_BASE + \
|
216 |
|
|
CYGARC_HAL_LPC2XXX_REG_IO0SET, _t_); \
|
217 |
|
|
HAL_READ_UINT32(CYGARC_HAL_LPC2XXX_REG_IO_BASE + \
|
218 |
|
|
CYGARC_HAL_LPC2XXX_REG_IO0CLR, _t_); \
|
219 |
|
|
_t_ |= MPU_RS; \
|
220 |
|
|
HAL_WRITE_UINT32(CYGARC_HAL_LPC2XXX_REG_IO_BASE + \
|
221 |
|
|
CYGARC_HAL_LPC2XXX_REG_IO0CLR, _t_); \
|
222 |
|
|
CYG_MACRO_END
|
223 |
|
|
|
224 |
|
|
// Set RS, R/W to write data
|
225 |
|
|
#define LCD_RS_WRITE_DATA() \
|
226 |
|
|
CYG_MACRO_START \
|
227 |
|
|
cyg_uint32 _t_; \
|
228 |
|
|
HAL_READ_UINT32(CYGARC_HAL_LPC2XXX_REG_IO_BASE + \
|
229 |
|
|
CYGARC_HAL_LPC2XXX_REG_IO0CLR, _t_); \
|
230 |
|
|
_t_ |= MPU_RW; \
|
231 |
|
|
HAL_WRITE_UINT32(CYGARC_HAL_LPC2XXX_REG_IO_BASE + \
|
232 |
|
|
CYGARC_HAL_LPC2XXX_REG_IO0CLR, _t_); \
|
233 |
|
|
HAL_READ_UINT32(CYGARC_HAL_LPC2XXX_REG_IO_BASE + \
|
234 |
|
|
CYGARC_HAL_LPC2XXX_REG_IO0SET, _t_); \
|
235 |
|
|
_t_ |= MPU_RS; \
|
236 |
|
|
HAL_WRITE_UINT32(CYGARC_HAL_LPC2XXX_REG_IO_BASE + \
|
237 |
|
|
CYGARC_HAL_LPC2XXX_REG_IO0SET, _t_); \
|
238 |
|
|
CYG_MACRO_END
|
239 |
|
|
|
240 |
|
|
// Set RS, R/W to write an instruction
|
241 |
|
|
#define LCD_RS_WRITE_CMD() \
|
242 |
|
|
CYG_MACRO_START \
|
243 |
|
|
cyg_uint32 _t_; \
|
244 |
|
|
HAL_READ_UINT32(CYGARC_HAL_LPC2XXX_REG_IO_BASE + \
|
245 |
|
|
CYGARC_HAL_LPC2XXX_REG_IO0CLR, _t_); \
|
246 |
|
|
_t_ |= MPU_RW | MPU_RS; \
|
247 |
|
|
HAL_WRITE_UINT32(CYGARC_HAL_LPC2XXX_REG_IO_BASE + \
|
248 |
|
|
CYGARC_HAL_LPC2XXX_REG_IO0CLR, _t_); \
|
249 |
|
|
CYG_MACRO_END
|
250 |
|
|
|
251 |
|
|
#define LCD_ENABLE_HIGH() \
|
252 |
|
|
CYG_MACRO_START \
|
253 |
|
|
cyg_uint32 _t_; \
|
254 |
|
|
HAL_READ_UINT32(CYGARC_HAL_LPC2XXX_REG_IO_BASE + \
|
255 |
|
|
CYGARC_HAL_LPC2XXX_REG_IO0SET, _t_); \
|
256 |
|
|
_t_ |= MPU_EN; \
|
257 |
|
|
HAL_WRITE_UINT32(CYGARC_HAL_LPC2XXX_REG_IO_BASE + \
|
258 |
|
|
CYGARC_HAL_LPC2XXX_REG_IO0SET, _t_); \
|
259 |
|
|
CYG_MACRO_END
|
260 |
|
|
|
261 |
|
|
#define LCD_ENABLE_LOW() \
|
262 |
|
|
CYG_MACRO_START \
|
263 |
|
|
cyg_uint32 _t_; \
|
264 |
|
|
HAL_READ_UINT32(CYGARC_HAL_LPC2XXX_REG_IO_BASE + \
|
265 |
|
|
CYGARC_HAL_LPC2XXX_REG_IO0CLR, _t_); \
|
266 |
|
|
_t_ |= MPU_EN; \
|
267 |
|
|
HAL_WRITE_UINT32(CYGARC_HAL_LPC2XXX_REG_IO_BASE + \
|
268 |
|
|
CYGARC_HAL_LPC2XXX_REG_IO0CLR, _t_); \
|
269 |
|
|
CYG_MACRO_END
|
270 |
|
|
|
271 |
|
|
// High-level enable pulse
|
272 |
|
|
#define LCD_ENABLE_PULSE() \
|
273 |
|
|
CYG_MACRO_START \
|
274 |
|
|
LCD_ENABLE_HIGH (); \
|
275 |
|
|
LCD_MICRO_DELAY (); \
|
276 |
|
|
LCD_ENABLE_LOW (); \
|
277 |
|
|
LCD_MICRO_DELAY (); \
|
278 |
|
|
CYG_MACRO_END
|
279 |
|
|
|
280 |
|
|
// Read a nibble of data from LCD controller
|
281 |
|
|
#define LCD_READ_NIBBLE( _n_) \
|
282 |
|
|
CYG_MACRO_START \
|
283 |
|
|
cyg_uint32 _t_; \
|
284 |
|
|
HAL_READ_UINT32(CYGARC_HAL_LPC2XXX_REG_IO_BASE + \
|
285 |
|
|
CYGARC_HAL_LPC2XXX_REG_IO0DIR, _t_); \
|
286 |
|
|
_t_ &= ~MPU_DB; \
|
287 |
|
|
HAL_WRITE_UINT32(CYGARC_HAL_LPC2XXX_REG_IO_BASE + \
|
288 |
|
|
CYGARC_HAL_LPC2XXX_REG_IO0DIR, _t_); \
|
289 |
|
|
HAL_READ_UINT32(CYGARC_HAL_LPC2XXX_REG_IO_BASE + \
|
290 |
|
|
CYGARC_HAL_LPC2XXX_REG_IO0PIN, _t_); \
|
291 |
|
|
_n_ = (_t_ & MPU_DB) >> 4; _n_ &= 0x0f; \
|
292 |
|
|
CYG_MACRO_END
|
293 |
|
|
|
294 |
|
|
// Write a nibble of data to LCD controller
|
295 |
|
|
#define LCD_WRITE_NIBBLE( _n_) \
|
296 |
|
|
CYG_MACRO_START \
|
297 |
|
|
cyg_uint32 _t_; \
|
298 |
|
|
HAL_READ_UINT32(CYGARC_HAL_LPC2XXX_REG_IO_BASE + \
|
299 |
|
|
CYGARC_HAL_LPC2XXX_REG_IO0DIR, _t_); \
|
300 |
|
|
_t_ |= MPU_DB; \
|
301 |
|
|
HAL_WRITE_UINT32(CYGARC_HAL_LPC2XXX_REG_IO_BASE + \
|
302 |
|
|
CYGARC_HAL_LPC2XXX_REG_IO0DIR, _t_); \
|
303 |
|
|
HAL_READ_UINT32(CYGARC_HAL_LPC2XXX_REG_IO_BASE + \
|
304 |
|
|
CYGARC_HAL_LPC2XXX_REG_IO0CLR, _t_); \
|
305 |
|
|
_t_ |= MPU_DB; \
|
306 |
|
|
HAL_WRITE_UINT32(CYGARC_HAL_LPC2XXX_REG_IO_BASE + \
|
307 |
|
|
CYGARC_HAL_LPC2XXX_REG_IO0CLR, _t_); \
|
308 |
|
|
HAL_READ_UINT32(CYGARC_HAL_LPC2XXX_REG_IO_BASE + \
|
309 |
|
|
CYGARC_HAL_LPC2XXX_REG_IO0SET, _t_); \
|
310 |
|
|
_t_ |= ((_n_) & 0x0f) << 4; \
|
311 |
|
|
HAL_WRITE_UINT32(CYGARC_HAL_LPC2XXX_REG_IO_BASE + \
|
312 |
|
|
CYGARC_HAL_LPC2XXX_REG_IO0SET, _t_); \
|
313 |
|
|
CYG_MACRO_END
|
314 |
|
|
|
315 |
|
|
// Drop LCD on POTS
|
316 |
|
|
#define LCD_DROP_ON_POTS( _n_) \
|
317 |
|
|
CYG_MACRO_START \
|
318 |
|
|
cyg_uint32 _t_; \
|
319 |
|
|
HAL_READ_UINT32(CYGARC_HAL_LPC2XXX_REG_IO_BASE + \
|
320 |
|
|
CYGARC_HAL_LPC2XXX_REG_IO0DIR, _t_); \
|
321 |
|
|
_t_ |= MPU_XX; \
|
322 |
|
|
HAL_WRITE_UINT32(CYGARC_HAL_LPC2XXX_REG_IO_BASE + \
|
323 |
|
|
CYGARC_HAL_LPC2XXX_REG_IO0DIR, _t_); \
|
324 |
|
|
HAL_READ_UINT32(CYGARC_HAL_LPC2XXX_REG_IO_BASE + \
|
325 |
|
|
CYGARC_HAL_LPC2XXX_REG_IO0CLR, _t_); \
|
326 |
|
|
_t_ |= MPU_XX; \
|
327 |
|
|
HAL_WRITE_UINT32(CYGARC_HAL_LPC2XXX_REG_IO_BASE + \
|
328 |
|
|
CYGARC_HAL_LPC2XXX_REG_IO0CLR, _t_); \
|
329 |
|
|
CYG_MACRO_END
|
330 |
|
|
|
331 |
|
|
//--------------------------------------------------------------------------
|
332 |
|
|
// _lcd_read --
|
333 |
|
|
//
|
334 |
|
|
static void
|
335 |
|
|
_lcd_read (int sel, cyg_uint8 * dat)
|
336 |
|
|
{
|
337 |
|
|
cyg_uint8 n;
|
338 |
|
|
|
339 |
|
|
if (sel == LCD_DATA)
|
340 |
|
|
LCD_RS_READ_DATA ();
|
341 |
|
|
else
|
342 |
|
|
LCD_RS_READ_STAT ();
|
343 |
|
|
|
344 |
|
|
// read D7-D4 nibble
|
345 |
|
|
LCD_ENABLE_HIGH ();
|
346 |
|
|
LCD_NANO_DELAY ();
|
347 |
|
|
LCD_READ_NIBBLE (n);
|
348 |
|
|
*dat = n << 4;
|
349 |
|
|
LCD_MICRO_DELAY ();
|
350 |
|
|
LCD_ENABLE_LOW ();
|
351 |
|
|
LCD_MICRO_DELAY ();
|
352 |
|
|
|
353 |
|
|
// read D3-D0 nibble
|
354 |
|
|
LCD_ENABLE_HIGH ();
|
355 |
|
|
LCD_NANO_DELAY ();
|
356 |
|
|
LCD_READ_NIBBLE (n);
|
357 |
|
|
*dat |= n;
|
358 |
|
|
LCD_MICRO_DELAY ();
|
359 |
|
|
LCD_ENABLE_LOW ();
|
360 |
|
|
LCD_MICRO_DELAY ();
|
361 |
|
|
}
|
362 |
|
|
|
363 |
|
|
//--------------------------------------------------------------------------
|
364 |
|
|
// _lcd_write --
|
365 |
|
|
//
|
366 |
|
|
static void
|
367 |
|
|
_lcd_write (int sel, cyg_uint8 dat)
|
368 |
|
|
{
|
369 |
|
|
if (sel == LCD_DATA)
|
370 |
|
|
LCD_RS_WRITE_DATA ();
|
371 |
|
|
else
|
372 |
|
|
LCD_RS_WRITE_CMD ();
|
373 |
|
|
|
374 |
|
|
// write D7-D4 nibble
|
375 |
|
|
LCD_WRITE_NIBBLE ((dat >> 4) & 15);
|
376 |
|
|
LCD_ENABLE_HIGH ();
|
377 |
|
|
LCD_MICRO_DELAY ();
|
378 |
|
|
LCD_ENABLE_LOW ();
|
379 |
|
|
LCD_MICRO_DELAY ();
|
380 |
|
|
|
381 |
|
|
// write D3-D0 nibble
|
382 |
|
|
LCD_WRITE_NIBBLE (dat & 15);
|
383 |
|
|
LCD_ENABLE_HIGH ();
|
384 |
|
|
LCD_MICRO_DELAY ();
|
385 |
|
|
LCD_ENABLE_LOW ();
|
386 |
|
|
LCD_MICRO_DELAY ();
|
387 |
|
|
}
|
388 |
|
|
|
389 |
|
|
#define LCD_READ( _register_, _data_) \
|
390 |
|
|
_lcd_read(_register_, &(_data_))
|
391 |
|
|
|
392 |
|
|
#define LCD_WRITE( _register_, _data_) \
|
393 |
|
|
_lcd_write(_register_, _data_)
|
394 |
|
|
|
395 |
|
|
#ifdef CYG_HAL_STARTUP_ROM
|
396 |
|
|
//--------------------------------------------------------------------------
|
397 |
|
|
// _lcd_pots_init --
|
398 |
|
|
//
|
399 |
|
|
// This routine is an early LCD intitializing on power-on event (from KS0066U
|
400 |
|
|
// flow diagram).
|
401 |
|
|
//
|
402 |
|
|
static void
|
403 |
|
|
_lcd_pots_init (void)
|
404 |
|
|
{
|
405 |
|
|
|
406 |
|
|
// around power on
|
407 |
|
|
LCD_DROP_ON_POTS ();
|
408 |
|
|
|
409 |
|
|
// wait for more than 30 ms after Vdd rises to 4.5 V
|
410 |
|
|
LCD_DELAY_US (32000);
|
411 |
|
|
|
412 |
|
|
// at first, point on a using of 4-bit mode
|
413 |
|
|
LCD_WRITE_NIBBLE (2);
|
414 |
|
|
LCD_ENABLE_PULSE ();
|
415 |
|
|
|
416 |
|
|
LCD_WRITE_NIBBLE (2);
|
417 |
|
|
LCD_ENABLE_PULSE ();
|
418 |
|
|
LCD_WRITE_NIBBLE (8);
|
419 |
|
|
LCD_ENABLE_PULSE ();
|
420 |
|
|
|
421 |
|
|
// wait for more than 39 us
|
422 |
|
|
LCD_DELAY_US (40);
|
423 |
|
|
|
424 |
|
|
// BF (busy flag) can be checked
|
425 |
|
|
}
|
426 |
|
|
#endif
|
427 |
|
|
|
428 |
|
|
// The portion of a code below is a bit adopted the LCD driver code for a
|
429 |
|
|
// PowerPC Cogent board.
|
430 |
|
|
|
431 |
|
|
static void lcd_dis (int add, char *s, cyg_uint8 * base);
|
432 |
|
|
|
433 |
|
|
//--------------------------------------------------------------------------
|
434 |
|
|
// init_lcd_channel --
|
435 |
|
|
//
|
436 |
|
|
static void
|
437 |
|
|
init_lcd_channel (cyg_uint8 * base)
|
438 |
|
|
{
|
439 |
|
|
cyg_uint8 stat;
|
440 |
|
|
int i;
|
441 |
|
|
|
442 |
|
|
#ifdef CYG_HAL_STARTUP_ROM
|
443 |
|
|
_lcd_pots_init ();
|
444 |
|
|
#endif
|
445 |
|
|
|
446 |
|
|
// Wait for not busy
|
447 |
|
|
do {
|
448 |
|
|
LCD_READ (LCD_STAT, stat);
|
449 |
|
|
} while (stat & LCD_STAT_BUSY);
|
450 |
|
|
|
451 |
|
|
// Configure the LCD for 4 bits/char, 2 lines and 5x8 dot matrix
|
452 |
|
|
LCD_WRITE (LCD_CMD, LCD_CMD_MODE);
|
453 |
|
|
|
454 |
|
|
// Wait for not busy
|
455 |
|
|
do {
|
456 |
|
|
LCD_READ (LCD_STAT, stat);
|
457 |
|
|
} while (stat & LCD_STAT_BUSY);
|
458 |
|
|
|
459 |
|
|
// Turn the LCD display on
|
460 |
|
|
LCD_WRITE (LCD_CMD, LCD_CMD_DON);
|
461 |
|
|
|
462 |
|
|
lcd_curline = 0;
|
463 |
|
|
lcd_linepos = 0;
|
464 |
|
|
|
465 |
|
|
for (i = 0; i < LCD_LINE_LENGTH; i++)
|
466 |
|
|
lcd_line[0][i] = lcd_line[1][i] = ' ';
|
467 |
|
|
|
468 |
|
|
lcd_line[0][LCD_LINE_LENGTH] = lcd_line[1][LCD_LINE_LENGTH] = 0;
|
469 |
|
|
|
470 |
|
|
lcd_dis (LCD_LINE0, lcd_line[0], base);
|
471 |
|
|
lcd_dis (LCD_LINE1, lcd_line[1], base);
|
472 |
|
|
}
|
473 |
|
|
|
474 |
|
|
//--------------------------------------------------------------------------
|
475 |
|
|
// lcd_dis --
|
476 |
|
|
//
|
477 |
|
|
// This routine writes the string to the LCD display after setting the address
|
478 |
|
|
// to add.
|
479 |
|
|
//
|
480 |
|
|
static void
|
481 |
|
|
lcd_dis (int add, char *s, cyg_uint8 * base)
|
482 |
|
|
{
|
483 |
|
|
cyg_uint8 stat;
|
484 |
|
|
int i;
|
485 |
|
|
|
486 |
|
|
// Wait for not busy
|
487 |
|
|
do {
|
488 |
|
|
LCD_READ (LCD_STAT, stat);
|
489 |
|
|
} while (stat & LCD_STAT_BUSY);
|
490 |
|
|
|
491 |
|
|
// Write the address
|
492 |
|
|
LCD_WRITE (LCD_CMD, (LCD_CMD_ADD + add));
|
493 |
|
|
|
494 |
|
|
// Write the string out to the display stopping when we reach 0
|
495 |
|
|
for (i = 0; *s != '\0'; i++) {
|
496 |
|
|
// Wait for not busy
|
497 |
|
|
do {
|
498 |
|
|
LCD_READ (LCD_STAT, stat);
|
499 |
|
|
} while (stat & LCD_STAT_BUSY);
|
500 |
|
|
|
501 |
|
|
// Write the data
|
502 |
|
|
LCD_WRITE (LCD_DATA, *s++);
|
503 |
|
|
}
|
504 |
|
|
}
|
505 |
|
|
|
506 |
|
|
//--------------------------------------------------------------------------
|
507 |
|
|
// cyg_hal_plf_lcd_putc --
|
508 |
|
|
//
|
509 |
|
|
void
|
510 |
|
|
cyg_hal_plf_lcd_putc (void *__ch_data, cyg_uint8 c)
|
511 |
|
|
{
|
512 |
|
|
cyg_uint8 *base = (cyg_uint8 *) __ch_data;
|
513 |
|
|
unsigned long __state;
|
514 |
|
|
int i;
|
515 |
|
|
|
516 |
|
|
// Ignore CR
|
517 |
|
|
if (c == '\r')
|
518 |
|
|
return;
|
519 |
|
|
|
520 |
|
|
CYGARC_HAL_SAVE_GP ();
|
521 |
|
|
HAL_DISABLE_INTERRUPTS (__state);
|
522 |
|
|
|
523 |
|
|
if (c == '\n') {
|
524 |
|
|
lcd_dis (LCD_LINE0, &lcd_line[lcd_curline ^ 1][0], base);
|
525 |
|
|
lcd_dis (LCD_LINE1, &lcd_line[lcd_curline][0], base);
|
526 |
|
|
|
527 |
|
|
// Do a line feed
|
528 |
|
|
lcd_curline ^= 1;
|
529 |
|
|
lcd_linepos = 0;
|
530 |
|
|
|
531 |
|
|
for (i = 0; i < LCD_LINE_LENGTH; i++)
|
532 |
|
|
lcd_line[lcd_curline][i] = ' ';
|
533 |
|
|
|
534 |
|
|
goto _exit_putc;
|
535 |
|
|
}
|
536 |
|
|
|
537 |
|
|
// Only allow to be output if there is room on the LCD line
|
538 |
|
|
if (lcd_linepos < LCD_LINE_LENGTH)
|
539 |
|
|
lcd_line[lcd_curline][lcd_linepos++] = c;
|
540 |
|
|
|
541 |
|
|
_exit_putc:
|
542 |
|
|
HAL_RESTORE_INTERRUPTS (__state);
|
543 |
|
|
CYGARC_HAL_RESTORE_GP ();
|
544 |
|
|
}
|
545 |
|
|
|
546 |
|
|
//--------------------------------------------------------------------------
|
547 |
|
|
// cyg_hal_plf_lcd_getc --
|
548 |
|
|
//
|
549 |
|
|
cyg_uint8
|
550 |
|
|
cyg_hal_plf_lcd_getc (void *__ch_data)
|
551 |
|
|
{
|
552 |
|
|
return 0;
|
553 |
|
|
}
|
554 |
|
|
|
555 |
|
|
//--------------------------------------------------------------------------
|
556 |
|
|
// cyg_hal_plf_lcd_write --
|
557 |
|
|
//
|
558 |
|
|
static void
|
559 |
|
|
cyg_hal_plf_lcd_write (void *__ch_data, const cyg_uint8 * __buf,
|
560 |
|
|
cyg_uint32 __len)
|
561 |
|
|
{
|
562 |
|
|
CYGARC_HAL_SAVE_GP ();
|
563 |
|
|
|
564 |
|
|
while (__len-- > 0)
|
565 |
|
|
cyg_hal_plf_lcd_putc (__ch_data, *__buf++);
|
566 |
|
|
|
567 |
|
|
CYGARC_HAL_RESTORE_GP ();
|
568 |
|
|
}
|
569 |
|
|
|
570 |
|
|
//--------------------------------------------------------------------------
|
571 |
|
|
// cyg_hal_plf_lcd_read --
|
572 |
|
|
//
|
573 |
|
|
static void
|
574 |
|
|
cyg_hal_plf_lcd_read (void *__ch_data, cyg_uint8 * __buf, cyg_uint32 __len)
|
575 |
|
|
{
|
576 |
|
|
CYGARC_HAL_SAVE_GP ();
|
577 |
|
|
|
578 |
|
|
while (__len-- > 0)
|
579 |
|
|
*__buf++ = cyg_hal_plf_lcd_getc (__ch_data);
|
580 |
|
|
|
581 |
|
|
CYGARC_HAL_RESTORE_GP ();
|
582 |
|
|
}
|
583 |
|
|
|
584 |
|
|
//--------------------------------------------------------------------------
|
585 |
|
|
// cyg_hal_plf_lcd_control --
|
586 |
|
|
//
|
587 |
|
|
static int
|
588 |
|
|
cyg_hal_plf_lcd_control (void *__ch_data, __comm_control_cmd_t __func, ...)
|
589 |
|
|
{
|
590 |
|
|
return 0;
|
591 |
|
|
}
|
592 |
|
|
|
593 |
|
|
//--------------------------------------------------------------------------
|
594 |
|
|
// cyg_hal_plf_lcd_init --
|
595 |
|
|
//
|
596 |
|
|
static void
|
597 |
|
|
cyg_hal_plf_lcd_init (void)
|
598 |
|
|
{
|
599 |
|
|
hal_virtual_comm_table_t *comm;
|
600 |
|
|
int cur =
|
601 |
|
|
CYGACC_CALL_IF_SET_CONSOLE_COMM
|
602 |
|
|
(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
|
603 |
|
|
|
604 |
|
|
// Init channel
|
605 |
|
|
init_lcd_channel ((cyg_uint8 *) NULL);
|
606 |
|
|
|
607 |
|
|
// Setup procs in the vector table
|
608 |
|
|
|
609 |
|
|
// Set channel 2
|
610 |
|
|
CYGACC_CALL_IF_SET_CONSOLE_COMM (2);
|
611 |
|
|
comm = CYGACC_CALL_IF_CONSOLE_PROCS ();
|
612 |
|
|
CYGACC_COMM_IF_CH_DATA_SET (*comm, LCD_BASE);
|
613 |
|
|
CYGACC_COMM_IF_WRITE_SET (*comm, cyg_hal_plf_lcd_write);
|
614 |
|
|
CYGACC_COMM_IF_READ_SET (*comm, cyg_hal_plf_lcd_read);
|
615 |
|
|
CYGACC_COMM_IF_PUTC_SET (*comm, cyg_hal_plf_lcd_putc);
|
616 |
|
|
CYGACC_COMM_IF_GETC_SET (*comm, cyg_hal_plf_lcd_getc);
|
617 |
|
|
CYGACC_COMM_IF_CONTROL_SET (*comm, cyg_hal_plf_lcd_control);
|
618 |
|
|
|
619 |
|
|
// Restore original console
|
620 |
|
|
CYGACC_CALL_IF_SET_CONSOLE_COMM (cur);
|
621 |
|
|
}
|
622 |
|
|
|
623 |
|
|
#ifdef HAL_PLF_HARDWARE_INIT
|
624 |
|
|
//--------------------------------------------------------------------------
|
625 |
|
|
// hal_plf_hardware_init --
|
626 |
|
|
//
|
627 |
|
|
void
|
628 |
|
|
hal_plf_hardware_init (void)
|
629 |
|
|
{
|
630 |
|
|
// Cyrrently, it does nothing
|
631 |
|
|
}
|
632 |
|
|
#endif // HAL_PLF_HARDWARE_INIT
|
633 |
|
|
|
634 |
|
|
// indent: --indent-level4 -br -nut; vim: expandtab tabstop=4 shiftwidth=4
|
635 |
|
|
//--------------------------------------------------------------------------
|
636 |
|
|
// EOF olpce2294_misc.c
|