1 /*=============================================================================
5 // HAL diagnostic output code
7 //=============================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
12 // Copyright (C) 2004 eCosCentric Limited
14 // eCos is free software; you can redistribute it and/or modify it under
15 // the terms of the GNU General Public License as published by the Free
16 // Software Foundation; either version 2 or (at your option) any later version.
18 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
19 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23 // You should have received a copy of the GNU General Public License along
24 // with eCos; if not, write to the Free Software Foundation, Inc.,
25 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
27 // As a special exception, if other files instantiate templates or use macros
28 // or inline functions from this file, or you compile this file and link it
29 // with other works to produce a work based on this file, this file does not
30 // by itself cause the resulting work to be covered by the GNU General Public
31 // License. However the source code for this file must still be made available
32 // in accordance with section (3) of the GNU General Public License.
34 // This exception does not invalidate any other reasons why a work based on
35 // this file might be covered by the GNU General Public License.
36 // -------------------------------------------
37 //####ECOSGPLCOPYRIGHTEND####
38 //=============================================================================
39 //#####DESCRIPTIONBEGIN####
42 // Contributors:jskov, gthomas
44 // Purpose: HAL diagnostic output
45 // Description: Implementations of HAL diagnostic output support.
47 //####DESCRIPTIONEND####
49 //===========================================================================*/
51 #include <pkgconf/hal.h>
52 #include CYGBLD_HAL_PLATFORM_H
54 #include <cyg/infra/cyg_type.h> // base types
56 #include <cyg/hal/hal_arch.h> // SAVE/RESTORE GP macros
57 #include <cyg/hal/hal_io.h> // IO macros
58 #include <cyg/hal/hal_if.h> // interface API
59 #include <cyg/hal/hal_intr.h> // HAL_ENABLE/MASK/UNMASK_INTERRUPTS
60 #include <cyg/hal/hal_misc.h> // Helper functions
61 #include <cyg/hal/drv_api.h> // CYG_ISR_HANDLED
62 #include <cyg/hal/hal_diag.h>
64 #include <cyg/hal/var_io.h> // USART registers
66 //-----------------------------------------------------------------------------
69 cyg_int32 msec_timeout;
74 //-----------------------------------------------------------------------------
76 cyg_hal_plf_serial_init_channel(void* __ch_data)
78 channel_data_t* chan = (channel_data_t*)__ch_data;
79 cyg_uint8* base = chan->base;
80 cyg_uint16 divider = CYG_HAL_ARM_LPC2XXX_BAUD_GENERATOR(chan->baud_rate);
82 HAL_WRITE_UINT32(base+CYGARC_HAL_LPC2XXX_REG_UxLCR,
83 CYGARC_HAL_LPC2XXX_REG_UxLCR_DLAB);
84 HAL_WRITE_UINT32(base+CYGARC_HAL_LPC2XXX_REG_UxDLM, divider >> 8);
85 HAL_WRITE_UINT32(base+CYGARC_HAL_LPC2XXX_REG_UxDLL, divider & 0xFF);
88 HAL_WRITE_UINT32(base+CYGARC_HAL_LPC2XXX_REG_UxLCR,
89 CYGARC_HAL_LPC2XXX_REG_UxLCR_WORD_LENGTH_8 |
90 CYGARC_HAL_LPC2XXX_REG_UxLCR_STOP_1);
92 // Reset and enable FIFO
93 HAL_WRITE_UINT32(base+CYGARC_HAL_LPC2XXX_REG_UxFCR,
94 CYGARC_HAL_LPC2XXX_REG_UxFCR_FIFO_ENA |
95 CYGARC_HAL_LPC2XXX_REG_UxFCR_RX_FIFO_RESET |
96 CYGARC_HAL_LPC2XXX_REG_UxFCR_TX_FIFO_RESET);
100 cyg_hal_plf_serial_putc(void *__ch_data, char c)
102 cyg_uint8* base = ((channel_data_t*)__ch_data)->base;
104 CYGARC_HAL_SAVE_GP();
107 HAL_READ_UINT32(base+CYGARC_HAL_LPC2XXX_REG_UxLSR, stat);
108 } while ((stat & CYGARC_HAL_LPC2XXX_REG_UxLSR_THRE) == 0);
110 HAL_WRITE_UINT32(base+CYGARC_HAL_LPC2XXX_REG_UxTHR, c);
112 CYGARC_HAL_RESTORE_GP();
116 cyg_hal_plf_serial_getc_nonblock(void* __ch_data, cyg_uint8* ch)
118 channel_data_t* chan = (channel_data_t*)__ch_data;
119 cyg_uint8* base = chan->base;
122 HAL_READ_UINT32(base+CYGARC_HAL_LPC2XXX_REG_UxLSR, stat);
123 if ((stat & CYGARC_HAL_LPC2XXX_REG_UxLSR_RDR) == 0)
126 HAL_READ_UINT32(base+CYGARC_HAL_LPC2XXX_REG_UxRBR, *ch);
132 cyg_hal_plf_serial_getc(void* __ch_data)
135 CYGARC_HAL_SAVE_GP();
137 while(!cyg_hal_plf_serial_getc_nonblock(__ch_data, &ch));
139 CYGARC_HAL_RESTORE_GP();
144 cyg_hal_plf_serial_write(void* __ch_data, const cyg_uint8* __buf,
147 CYGARC_HAL_SAVE_GP();
150 cyg_hal_plf_serial_putc(__ch_data, *__buf++);
152 CYGARC_HAL_RESTORE_GP();
156 cyg_hal_plf_serial_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len)
158 CYGARC_HAL_SAVE_GP();
161 *__buf++ = cyg_hal_plf_serial_getc(__ch_data);
163 CYGARC_HAL_RESTORE_GP();
167 cyg_hal_plf_serial_getc_timeout(void* __ch_data, cyg_uint8* ch)
170 channel_data_t* chan = (channel_data_t*)__ch_data;
172 CYGARC_HAL_SAVE_GP();
174 delay_count = chan->msec_timeout * 10; // delay in .1 ms steps
177 res = cyg_hal_plf_serial_getc_nonblock(__ch_data, ch);
178 if (res || 0 == delay_count--)
181 CYGACC_CALL_IF_DELAY_US(100);
184 CYGARC_HAL_RESTORE_GP();
189 cyg_hal_plf_serial_control(void *__ch_data, __comm_control_cmd_t __func, ...)
191 static int irq_state = 0;
192 channel_data_t* chan = (channel_data_t*)__ch_data;
193 cyg_uint8* base = ((channel_data_t*)__ch_data)->base;
197 CYGARC_HAL_SAVE_GP();
198 va_start(ap, __func);
201 case __COMMCTL_GETBAUD:
202 ret = chan->baud_rate;
204 case __COMMCTL_SETBAUD:
205 chan->baud_rate = va_arg(ap, cyg_int32);
206 // Should we verify this value here?
207 cyg_hal_plf_serial_init_channel(chan);
210 case __COMMCTL_IRQ_ENABLE:
212 HAL_INTERRUPT_ACKNOWLEDGE(chan->isr_vector);
213 HAL_INTERRUPT_UNMASK(chan->isr_vector);
214 HAL_WRITE_UINT32(base+CYGARC_HAL_LPC2XXX_REG_UxIER,
215 CYGARC_HAL_LPC2XXX_REG_UxIER_RXDATA_INT);
217 case __COMMCTL_IRQ_DISABLE:
220 HAL_INTERRUPT_MASK(chan->isr_vector);
221 HAL_WRITE_UINT32(base+CYGARC_HAL_LPC2XXX_REG_UxIER, 0);
223 case __COMMCTL_DBG_ISR_VECTOR:
224 ret = chan->isr_vector;
226 case __COMMCTL_SET_TIMEOUT:
227 ret = chan->msec_timeout;
228 chan->msec_timeout = va_arg(ap, cyg_uint32);
234 CYGARC_HAL_RESTORE_GP();
239 cyg_hal_plf_serial_isr(void *__ch_data, int* __ctrlc,
240 CYG_ADDRWORD __vector, CYG_ADDRWORD __data)
243 channel_data_t* chan = (channel_data_t*)__ch_data;
247 CYGARC_HAL_SAVE_GP();
251 HAL_READ_UINT32(chan->base + CYGARC_HAL_LPC2XXX_REG_UxIIR, iir);
253 if((iir & (CYGARC_HAL_LPC2XXX_REG_UxIIR_IIR0 | CYGARC_HAL_LPC2XXX_REG_UxIIR_IIR1 |
254 CYGARC_HAL_LPC2XXX_REG_UxIIR_IIR2)) == CYGARC_HAL_LPC2XXX_REG_UxIIR_IIR2)
256 // Rx data available or character timeout
257 // Read data in order to clear interrupt
258 HAL_READ_UINT32(chan->base+CYGARC_HAL_LPC2XXX_REG_UxRBR, c);
259 if( cyg_hal_is_break( &c , 1 ) ) *__ctrlc = 1;
261 res = CYG_ISR_HANDLED;
264 HAL_INTERRUPT_ACKNOWLEDGE(chan->isr_vector);
266 CYGARC_HAL_RESTORE_GP();
270 static channel_data_t lpc2xxx_ser_channels[2] = {
271 { (cyg_uint8*)CYGARC_HAL_LPC2XXX_REG_UART0_BASE, 1000,
272 CYGNUM_HAL_INTERRUPT_UART0,
273 CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD},
274 { (cyg_uint8*)CYGARC_HAL_LPC2XXX_REG_UART1_BASE, 1000,
275 CYGNUM_HAL_INTERRUPT_UART1,
276 CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD}
280 cyg_hal_plf_serial_init(void)
282 hal_virtual_comm_table_t* comm;
285 cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
288 cyg_hal_plf_serial_init_channel(&lpc2xxx_ser_channels[0]);
289 #if CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS > 1
290 cyg_hal_plf_serial_init_channel(&lpc2xxx_ser_channels[1]);
293 // Setup procs in the vector table
296 CYGACC_CALL_IF_SET_CONSOLE_COMM(0);
297 comm = CYGACC_CALL_IF_CONSOLE_PROCS();
298 CYGACC_COMM_IF_CH_DATA_SET(*comm, &lpc2xxx_ser_channels[0]);
299 CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write);
300 CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read);
301 CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc);
302 CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc);
303 CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control);
304 CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr);
305 CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout);
307 #if CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS > 1
309 CYGACC_CALL_IF_SET_CONSOLE_COMM(1);
310 comm = CYGACC_CALL_IF_CONSOLE_PROCS();
311 CYGACC_COMM_IF_CH_DATA_SET(*comm, &lpc2xxx_ser_channels[1]);
312 CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write);
313 CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read);
314 CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc);
315 CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc);
316 CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control);
317 CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr);
318 CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout);
321 // Restore original console
322 CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
326 hal_diag_led(int mask)
328 hal_lpc2xxx_set_leds(mask);
331 //-----------------------------------------------------------------------------