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, 2003 Red Hat, Inc.
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 version.
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 // You should have received a copy of the GNU General Public License along
23 // with eCos; if not, write to the Free Software Foundation, Inc.,
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
26 // As a special exception, if other files instantiate templates or use macros
27 // or inline functions from this file, or you compile this file and link it
28 // with other works to produce a work based on this file, this file does not
29 // by itself cause the resulting work to be covered by the GNU General Public
30 // License. However the source code for this file must still be made available
31 // in accordance with section (3) of the GNU General Public License.
33 // This exception does not invalidate any other reasons why a work based on
34 // this file might be covered by the GNU General Public License.
36 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37 // at http://sources.redhat.com/ecos/ecos-license/
38 // -------------------------------------------
39 //####ECOSGPLCOPYRIGHTEND####
40 //=============================================================================
41 //#####DESCRIPTIONBEGIN####
44 // Contributors:msalter
46 // Purpose: HAL diagnostic output
47 // Description: Implementations of HAL diagnostic output support.
49 //####DESCRIPTIONEND####
51 //===========================================================================*/
53 #include <pkgconf/hal.h>
54 #include CYGBLD_HAL_VARIANT_H // Variant specific configuration
55 #include CYGBLD_HAL_PLATFORM_H // Platform specific configuration
57 #include <cyg/infra/cyg_type.h> // base types
58 #include <cyg/infra/cyg_trac.h> // tracing macros
59 #include <cyg/infra/cyg_ass.h> // assertion macros
61 #include <cyg/hal/hal_arch.h> // basic machine info
62 #include <cyg/hal/hal_intr.h> // interrupt macros
63 #include <cyg/hal/hal_io.h> // IO macros
64 #include <cyg/hal/hal_diag.h>
65 #include <cyg/hal/drv_api.h>
66 #include <cyg/hal/hal_if.h> // interface API
67 #include <cyg/hal/hal_misc.h> // Helper functions
69 #if !defined(CYGSEM_HAL_IXP425_PLF_USES_UART1) && !defined(CYGSEM_HAL_IXP425_PLF_USES_UART2)
70 #define IXP425_NUM_UARTS 0
71 #elif defined(CYGSEM_HAL_IXP425_PLF_USES_UART1) && defined(CYGSEM_HAL_IXP425_PLF_USES_UART2)
72 #define IXP425_NUM_UARTS 2
74 #define IXP425_NUM_UARTS 1
77 #if IXP425_NUM_UARTS > 0
79 /*---------------------------------------------------------------------------*/
80 /* 16550 compatible UARTS */
82 // Define the serial registers.
83 #define CYG_DEV_RBR 0x00 // receiver buffer register, read, dlab = 0
84 #define CYG_DEV_THR 0x00 // transmitter holding register, write, dlab = 0
85 #define CYG_DEV_DLL 0x00 // divisor latch (LS), read/write, dlab = 1
86 #define CYG_DEV_IER 0x01 // interrupt enable register, read/write, dlab = 0
87 #define CYG_DEV_DLM 0x01 // divisor latch (MS), read/write, dlab = 1
88 #define CYG_DEV_IIR 0x02 // interrupt identification register, read, dlab = 0
89 #define CYG_DEV_FCR 0x02 // fifo control register, write, dlab = 0
90 #define CYG_DEV_LCR 0x03 // line control register, write
91 #define CYG_DEV_MCR 0x04 // modem control register, write
92 #define CYG_DEV_LSR 0x05 // line status register, read
93 #define CYG_DEV_MSR 0x06 // modem status register, read
94 #define CYG_DEV_SCR 0x07 // scratch pad register
96 // Interrupt Enable Register
97 #define SIO_IER_RCV 0x01
98 #define SIO_IER_XMT 0x02
99 #define SIO_IER_LS 0x04
100 #define SIO_IER_MS 0x08
101 #define SIO_IER_UUE 0x40 // UART Unit Enable
103 // The line status register bits.
104 #define SIO_LSR_DR 0x01 // data ready
105 #define SIO_LSR_OE 0x02 // overrun error
106 #define SIO_LSR_PE 0x04 // parity error
107 #define SIO_LSR_FE 0x08 // framing error
108 #define SIO_LSR_BI 0x10 // break interrupt
109 #define SIO_LSR_THRE 0x20 // transmitter holding register empty
110 #define SIO_LSR_TEMT 0x40 // transmitter register empty
111 #define SIO_LSR_ERR 0x80 // any error condition
113 // The modem status register bits.
114 #define SIO_MSR_DCTS 0x01 // delta clear to send
115 #define SIO_MSR_DDSR 0x02 // delta data set ready
116 #define SIO_MSR_TERI 0x04 // trailing edge ring indicator
117 #define SIO_MSR_DDCD 0x08 // delta data carrier detect
118 #define SIO_MSR_CTS 0x10 // clear to send
119 #define SIO_MSR_DSR 0x20 // data set ready
120 #define SIO_MSR_RI 0x40 // ring indicator
121 #define SIO_MSR_DCD 0x80 // data carrier detect
123 // The line control register bits.
124 #define SIO_LCR_WLS0 0x01 // word length select bit 0
125 #define SIO_LCR_WLS1 0x02 // word length select bit 1
126 #define SIO_LCR_STB 0x04 // number of stop bits
127 #define SIO_LCR_PEN 0x08 // parity enable
128 #define SIO_LCR_EPS 0x10 // even parity select
129 #define SIO_LCR_SP 0x20 // stick parity
130 #define SIO_LCR_SB 0x40 // set break
131 #define SIO_LCR_DLAB 0x80 // divisor latch access bit
133 // Modem Control Register
134 #define SIO_MCR_DTR 0x01
135 #define SIO_MCR_RTS 0x02
136 #define SIO_MCR_OUT1 0x04
137 #define SIO_MCR_OUT2 0x08
138 #define SIO_MCR_LOOP 0x10
139 #define SIO_MCR_AFE 0x20
141 #define UART1_BASE 0xC8000000
142 #define UART2_BASE 0xC8001000
144 //-----------------------------------------------------------------------------
147 cyg_int32 msec_timeout;
153 //-----------------------------------------------------------------------------
154 // Based on 14.7456 MHz xtal
156 set_baud( channel_data_t *chan )
158 cyg_uint32* base = chan->base;
159 cyg_uint16 div = 921600 / chan->baud_rate;
162 HAL_READ_UINT32(base+CYG_DEV_LCR, lcr);
163 HAL_WRITE_UINT32(base+CYG_DEV_LCR, lcr|SIO_LCR_DLAB);
164 HAL_WRITE_UINT32(base+CYG_DEV_DLL, div & 0xff);
165 HAL_WRITE_UINT32(base+CYG_DEV_DLM, (div >> 8) & 0xff);
166 HAL_WRITE_UINT32(base+CYG_DEV_LCR, lcr);
171 cyg_hal_plf_serial_init_channel(void* __ch_data)
173 cyg_uint32* base = ((channel_data_t*)__ch_data)->base;
174 channel_data_t* chan = (channel_data_t*)__ch_data;
176 HAL_WRITE_UINT32(chan->base+CYG_DEV_IER, SIO_IER_UUE);
179 HAL_WRITE_UINT32(base+CYG_DEV_LCR, SIO_LCR_WLS0 | SIO_LCR_WLS1);
180 chan->baud_rate = CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD;
182 HAL_WRITE_UINT32(base+CYG_DEV_FCR, 0x07); // Enable & clear FIFO
183 HAL_WRITE_UINT32(base+CYG_DEV_MCR, SIO_MCR_OUT2); // Enable interrupt to core
187 cyg_hal_plf_serial_putc(void *__ch_data, char c)
189 cyg_uint32* base = ((channel_data_t*)__ch_data)->base;
191 CYGARC_HAL_SAVE_GP();
194 HAL_READ_UINT32(base+CYG_DEV_LSR, lsr);
195 } while ((lsr & SIO_LSR_THRE) == 0);
198 HAL_WRITE_UINT32(base+CYG_DEV_THR, val);
200 CYGARC_HAL_RESTORE_GP();
204 cyg_hal_plf_serial_getc_nonblock(void* __ch_data, cyg_uint8* ch)
206 cyg_uint32* base = ((channel_data_t*)__ch_data)->base;
209 HAL_READ_UINT32(base+CYG_DEV_LSR, lsr);
210 if ((lsr & SIO_LSR_DR) == 0)
213 HAL_READ_UINT32(base+CYG_DEV_RBR, val);
220 cyg_hal_plf_serial_getc(void* __ch_data)
223 CYGARC_HAL_SAVE_GP();
225 while(!cyg_hal_plf_serial_getc_nonblock(__ch_data, &ch));
227 CYGARC_HAL_RESTORE_GP();
231 static channel_data_t plf_ser_channels[] = {
232 #if defined(CYGSEM_HAL_IXP425_PLF_USES_UART1) && !defined(HAL_PLATFORM_UART2_FIRST)
233 { (cyg_uint32*)UART1_BASE, 1000, CYGNUM_HAL_INTERRUPT_UART1 },
235 #if defined(CYGSEM_HAL_IXP425_PLF_USES_UART2)
236 { (cyg_uint32*)UART2_BASE, 1000, CYGNUM_HAL_INTERRUPT_UART2 }
238 #if defined(CYGSEM_HAL_IXP425_PLF_USES_UART1) && defined(HAL_PLATFORM_UART2_FIRST)
239 { (cyg_uint32*)UART1_BASE, 1000, CYGNUM_HAL_INTERRUPT_UART1 },
244 cyg_hal_plf_serial_write(void* __ch_data, const cyg_uint8* __buf,
247 CYGARC_HAL_SAVE_GP();
250 cyg_hal_plf_serial_putc(__ch_data, *__buf++);
252 CYGARC_HAL_RESTORE_GP();
256 cyg_hal_plf_serial_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len)
258 CYGARC_HAL_SAVE_GP();
261 *__buf++ = cyg_hal_plf_serial_getc(__ch_data);
263 CYGARC_HAL_RESTORE_GP();
267 cyg_hal_plf_serial_getc_timeout(void* __ch_data, cyg_uint8* ch)
270 channel_data_t* chan = (channel_data_t*)__ch_data;
272 CYGARC_HAL_SAVE_GP();
274 delay_count = chan->msec_timeout * 10; // delay in .1 ms steps
277 res = cyg_hal_plf_serial_getc_nonblock(__ch_data, ch);
278 if (res || 0 == delay_count--)
281 CYGACC_CALL_IF_DELAY_US(100);
284 CYGARC_HAL_RESTORE_GP();
289 cyg_hal_plf_serial_control(void *__ch_data, __comm_control_cmd_t __func, ...)
291 static int irq_state = 0;
292 channel_data_t* chan = (channel_data_t*)__ch_data;
294 CYGARC_HAL_SAVE_GP();
297 case __COMMCTL_IRQ_ENABLE:
300 HAL_WRITE_UINT32(chan->base+CYG_DEV_IER, SIO_IER_RCV | SIO_IER_UUE);
301 HAL_INTERRUPT_UNMASK(chan->isr_vector);
303 case __COMMCTL_IRQ_DISABLE:
307 HAL_WRITE_UINT32(chan->base+CYG_DEV_IER, SIO_IER_UUE);
308 HAL_INTERRUPT_MASK(chan->isr_vector);
310 case __COMMCTL_DBG_ISR_VECTOR:
311 ret = chan->isr_vector;
313 case __COMMCTL_SET_TIMEOUT:
317 va_start(ap, __func);
319 ret = chan->msec_timeout;
320 chan->msec_timeout = va_arg(ap, cyg_uint32);
324 case __COMMCTL_GETBAUD:
325 ret = chan->baud_rate;
327 case __COMMCTL_SETBAUD:
332 va_start(ap, __func);
333 b = va_arg(ap, cyg_int32);
336 if (b < 300 || b > 115200)
340 ret = set_baud(chan);
347 CYGARC_HAL_RESTORE_GP();
352 cyg_hal_plf_serial_isr(void *__ch_data, int* __ctrlc,
353 CYG_ADDRWORD __vector, CYG_ADDRWORD __data)
356 channel_data_t* chan = (channel_data_t*)__ch_data;
359 CYGARC_HAL_SAVE_GP();
361 cyg_drv_interrupt_acknowledge(chan->isr_vector);
364 HAL_READ_UINT32(chan->base+CYG_DEV_LSR, lsr);
365 if ( (lsr & SIO_LSR_DR) != 0 ) {
367 HAL_READ_UINT32(chan->base+CYG_DEV_RBR, c);
368 if( cyg_hal_is_break( &c , 1 ) )
371 res = CYG_ISR_HANDLED;
374 CYGARC_HAL_RESTORE_GP();
379 cyg_hal_ixp425_serial_init(void)
381 hal_virtual_comm_table_t* comm;
382 int i, cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
384 for (i = 0; i < IXP425_NUM_UARTS; i++) {
386 // Disable interrupts.
387 HAL_INTERRUPT_MASK(plf_ser_channels[i].isr_vector);
390 cyg_hal_plf_serial_init_channel(&plf_ser_channels[i]);
392 // Setup procs in the vector table
393 CYGACC_CALL_IF_SET_CONSOLE_COMM(i);
394 comm = CYGACC_CALL_IF_CONSOLE_PROCS();
395 CYGACC_COMM_IF_CH_DATA_SET(*comm, &plf_ser_channels[i]);
396 CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write);
397 CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read);
398 CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc);
399 CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc);
400 CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control);
401 CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr);
402 CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout);
404 // Restore original console
405 CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
408 // If the platform provides some channels of its own, then this function will be
409 // provided by that platform.
410 #if !defined(CYGNUM_HAL_IXP425_PLF_SERIAL_CHANNELS) || !CYGNUM_HAL_IXP425_PLF_SERIAL_CHANNELS
412 cyg_hal_plf_comms_init(void)
414 static int initialized = 0;
421 cyg_hal_ixp425_serial_init();
425 #endif // IXP425_NUM_UARTS > 0
427 /*---------------------------------------------------------------------------*/
434 /*---------------------------------------------------------------------------*/
435 /* End of hal_diag.c */