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.
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####
43 // Author(s): David A Rusling
44 // Contributors: Philippe Robin
45 // Date: November 7, 2000
46 // Purpose: HAL diagnostic output
47 // Description: Implementations of HAL diagnostic output support.
49 //####DESCRIPTIONEND####
51 //===========================================================================*/
53 #include <pkgconf/hal.h>
54 #include <pkgconf/hal_arm_integrator.h> // board specifics
56 #include <cyg/infra/cyg_type.h> // base types
57 #include <cyg/infra/cyg_trac.h> // tracing macros
58 #include <cyg/infra/cyg_ass.h> // assertion macros
60 #include <cyg/hal/hal_arch.h> // basic machine info
61 #include <cyg/hal/hal_intr.h> // interrupt macros
62 #include <cyg/hal/hal_io.h> // IO macros
63 #include <cyg/hal/hal_if.h> // interface API
64 #include <cyg/hal/hal_misc.h> // Helper functions
65 #include <cyg/hal/hal_diag.h>
66 #include <cyg/hal/drv_api.h>
67 #include <cyg/hal/hal_integrator.h> // Hardware definitions
70 /*---------------------------------------------------------------------------*/
73 /* Codes for ASCI characters 32-127 */
74 unsigned int char_codes[] = {
75 0x0000, 0x2400, 0x0044, 0x7E12, 0x25DA, 0x4848, 0x2580, 0x0400,
76 0x0072, 0x001E, 0x7F80, 0x2580, 0x4000, 0x0180, 0x0000, 0x4800,
77 0x007E, 0x080C, 0x01B6, 0x011E, 0x01CC, 0x01DA, 0x01FA, 0x2802,
78 0x01FE, 0x01CE, 0x2400, 0x4400, 0x1800, 0x0190, 0x4200, 0x01A6,
79 0x217E, 0x01EE, 0x251E, 0x0072, 0x241E, 0x00F2, 0x00E2, 0x017A,
80 0x01EC, 0x2412, 0x001C, 0x18E0, 0x0070, 0x0A6C, 0x126C, 0x007E,
81 0x01E6, 0x107E, 0x11E6, 0x01DA, 0x2402, 0x007C, 0x4860, 0x506C,
82 0x5A00, 0x2A00, 0x4812, 0x0072, 0x1200, 0x001E, 0x0046, 0x0010,
83 0x0200, 0x01BE, 0x01F8, 0x01B0, 0x01BC, 0x01F6, 0x2980, 0x01DE,
84 0x01E8, 0x2000, 0x001C, 0x3500, 0x2400, 0x21A8, 0x01A8, 0x01B8,
85 0x01E6, 0x01CE, 0x01A0, 0x01DA, 0x00F0, 0x0038, 0x4020, 0x5028,
86 0x5A00, 0x030C, 0x4190, 0x2480, 0x2400, 0x2500, 0x0640, 0x0000
89 /* Codes for hexadecimal characters */
90 unsigned int hex_codes[] = {
91 0x007E, 0x080C, 0x01B6, 0x011E, 0x01CC, 0x01DA, 0x01FA, 0x2802,
92 0x01FE, 0x01CE, 0x01EE, 0x01F8, 0x0072, 0x01BC, 0x00F2, 0x00E2
95 void hal_diag_alpha_led_char(char c1, char c2);
98 // AMBA uart access macros
99 #define GET_STATUS(p) (IO_READ((p) + AMBA_UARTFR))
100 #define GET_CHAR(p) (IO_READ((p) + AMBA_UARTDR))
101 #define PUT_CHAR(p, c) (IO_WRITE(((p) + AMBA_UARTDR), (c)))
102 #define IO_READ(p) ((*(volatile unsigned int *)(p)) & 0xFF)
103 #define IO_WRITE(p, c) (*(unsigned int *)(p) = (c))
104 #define RX_DATA(s) (((s) & AMBA_UARTFR_RXFE) == 0)
105 #define TX_READY(s) (((s) & AMBA_UARTFR_TXFF) == 0)
106 #define TX_EMPTY(p) ((GET_STATUS(p) & AMBA_UARTFR_TMSK) == 0)
107 #define RX_EMPTY(p) ((GET_STATUS(p) & AMBA_UARTFR_RXFE) == 0)
108 // Define the serial registers.
110 //-----------------------------------------------------------------------------
113 cyg_int32 msec_timeout;
117 //-----------------------------------------------------------------------------
119 #if (CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD == 9600)
120 #define ARM_INTEGRATOR_BAUD_DIVISOR ARM_BAUD_9600
121 #elif (CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD == 19200)
122 #define ARM_INTEGRATOR_BAUD_DIVISOR ARM_BAUD_9600
123 #elif (CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD == 38400)
124 #define ARM_INTEGRATOR_BAUD_DIVISOR ARM_BAUD_38400
125 #elif (CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD == 57600)
126 #define ARM_INTEGRATOR_BAUD_DIVISOR ARM_BAUD_57600
127 #elif (CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD == 115200)
128 #define ARM_INTEGRATOR_BAUD_DIVISOR ARM_BAUD_115200
132 cyg_hal_plf_serial_init_channel(void* __ch_data)
134 cyg_uint8* base = ((channel_data_t*)__ch_data)->base;
136 // first, disable everything
137 IO_WRITE(base + AMBA_UARTCR, 0x0);
139 // Set baud rate CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD
140 IO_WRITE(base + AMBA_UARTLCR_M, ((ARM_INTEGRATOR_BAUD_DIVISOR & 0xf00) >> 8));
141 IO_WRITE(base + AMBA_UARTLCR_L, (ARM_INTEGRATOR_BAUD_DIVISOR & 0xff));
143 // ----------v----------v----------v----------v----------
144 // NOTE: MUST BE WRITTEN LAST (AFTER UARTLCR_M & UARTLCR_L)
145 // ----------^----------^----------^----------^----------
146 // set the UART to be 8 bits, 1 stop bit, no parity, fifo enabled
147 IO_WRITE(base + AMBA_UARTLCR_H, (AMBA_UARTLCR_H_WLEN_8 | AMBA_UARTLCR_H_FEN));
149 // finally, enable the uart
150 IO_WRITE(base + AMBA_UARTCR, AMBA_UARTCR_UARTEN);
155 cyg_hal_plf_serial_putc(void *__ch_data, char c)
157 channel_data_t* chan = (channel_data_t*)__ch_data;
158 cyg_uint8* base = chan->base;
160 CYGARC_HAL_SAVE_GP();
163 status = GET_STATUS(base);
164 } while (!TX_READY(status)); // wait until ready
170 status = GET_STATUS(base);
171 } while (!TX_READY(status)); // wait until ready
173 PUT_CHAR(base, '\r');
176 CYGARC_HAL_RESTORE_GP();
180 cyg_hal_plf_serial_getc_nonblock(void* __ch_data, cyg_uint8* ch)
182 cyg_uint8* base = ((channel_data_t*)__ch_data)->base;
184 long timeout = 100; // A long time...
187 status = GET_STATUS(base);
188 if (--timeout == 0) return false ;
189 } while (!RX_DATA(status)); // wait until ready
191 *ch = GET_CHAR(base);
197 cyg_hal_plf_serial_getc(void* __ch_data)
200 CYGARC_HAL_SAVE_GP();
202 while(!cyg_hal_plf_serial_getc_nonblock(__ch_data, &ch));
204 CYGARC_HAL_RESTORE_GP();
208 #if defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG) \
209 || defined(CYGPRI_HAL_IMPLEMENTS_IF_SERVICES)
211 static channel_data_t integrator_ser_channels[2] = {
212 { (cyg_uint8*)0x16000000, 1000, CYGNUM_HAL_INTERRUPT_UARTINT0 },
213 { (cyg_uint8*)0x17000000, 1000, CYGNUM_HAL_INTERRUPT_UARTINT1 }
217 cyg_hal_plf_serial_write(void* __ch_data, const cyg_uint8* __buf,
220 CYGARC_HAL_SAVE_GP();
223 cyg_hal_plf_serial_putc(__ch_data, *__buf++);
225 CYGARC_HAL_RESTORE_GP();
229 cyg_hal_plf_serial_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len)
231 CYGARC_HAL_SAVE_GP();
234 *__buf++ = cyg_hal_plf_serial_getc(__ch_data);
236 CYGARC_HAL_RESTORE_GP();
240 cyg_hal_plf_serial_getc_timeout(void* __ch_data, cyg_uint8* ch)
243 channel_data_t* chan = (channel_data_t*)__ch_data;
245 CYGARC_HAL_SAVE_GP();
247 delay_count = chan->msec_timeout * 10; // delay in .1 ms steps
250 res = cyg_hal_plf_serial_getc_nonblock(__ch_data, ch);
251 if (res || 0 == delay_count--)
254 CYGACC_CALL_IF_DELAY_US(100);
257 CYGARC_HAL_RESTORE_GP();
262 cyg_hal_plf_serial_control(void *__ch_data, __comm_control_cmd_t __func, ...)
264 static int irq_state = 0;
265 channel_data_t* chan = (channel_data_t*)__ch_data;
268 CYGARC_HAL_SAVE_GP();
271 case __COMMCTL_IRQ_ENABLE:
273 // Ensure that only Receive ints are generated.
274 status = IO_READ(chan->base + AMBA_UARTCR);
276 status |= (AMBA_UARTCR_RTIE | AMBA_UARTCR_RIE);
277 HAL_WRITE_UINT32(chan->base + AMBA_UARTCR, status);
279 HAL_INTERRUPT_UNMASK(chan->isr_vector);
281 case __COMMCTL_IRQ_DISABLE:
285 status = IO_READ(chan->base + AMBA_UARTCR);
286 status &= ~(AMBA_UARTCR_RTIE | AMBA_UARTCR_TIE | AMBA_UARTCR_RIE | AMBA_UARTCR_MSIE);
287 HAL_WRITE_UINT32(chan->base + AMBA_UARTCR, status);
289 HAL_INTERRUPT_MASK(chan->isr_vector);
291 case __COMMCTL_DBG_ISR_VECTOR:
292 ret = chan->isr_vector;
294 case __COMMCTL_SET_TIMEOUT:
298 va_start(ap, __func);
300 ret = chan->msec_timeout;
301 chan->msec_timeout = va_arg(ap, cyg_uint32);
308 CYGARC_HAL_RESTORE_GP();
313 cyg_hal_plf_serial_isr(void *__ch_data, int* __ctrlc,
314 CYG_ADDRWORD __vector, CYG_ADDRWORD __data)
317 channel_data_t* chan = (channel_data_t*)__ch_data;
320 CYGARC_HAL_SAVE_GP();
322 cyg_drv_interrupt_acknowledge(chan->isr_vector);
325 status = GET_STATUS(chan->base);
327 if ( RX_DATA(status) ) {
328 c = GET_CHAR(chan->base);
330 if( cyg_hal_is_break( &c , 1 ) )
333 res = CYG_ISR_HANDLED;
336 CYGARC_HAL_RESTORE_GP();
341 cyg_hal_plf_serial_init(void)
343 hal_virtual_comm_table_t* comm;
344 int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
346 // Disable interrupts.
347 HAL_INTERRUPT_MASK(integrator_ser_channels[0].isr_vector);
348 HAL_INTERRUPT_MASK(integrator_ser_channels[1].isr_vector);
351 cyg_hal_plf_serial_init_channel(&integrator_ser_channels[0]);
352 cyg_hal_plf_serial_init_channel(&integrator_ser_channels[1]);
354 // Setup procs in the vector table
357 CYGACC_CALL_IF_SET_CONSOLE_COMM(0);
358 comm = CYGACC_CALL_IF_CONSOLE_PROCS();
359 CYGACC_COMM_IF_CH_DATA_SET(*comm, &integrator_ser_channels[0]);
360 CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write);
361 CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read);
362 CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc);
363 CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc);
364 CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control);
365 CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr);
366 CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout);
369 CYGACC_CALL_IF_SET_CONSOLE_COMM(1);
370 comm = CYGACC_CALL_IF_CONSOLE_PROCS();
371 CYGACC_COMM_IF_CH_DATA_SET(*comm, &integrator_ser_channels[1]);
372 CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write);
373 CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read);
374 CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc);
375 CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc);
376 CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control);
377 CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr);
378 CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout);
380 // Restore original console
381 CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
387 cyg_hal_plf_comms_init(void)
389 static int initialized = 0;
396 cyg_hal_plf_serial_init();
398 #ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT2
399 cyg_hal_gdb_isr_attach(); // FIXME, hack to get CTRLC working
403 #endif // CYGSEM_HAL_VIRTUAL_VECTOR_DIAG || CYGPRI_HAL_IMPLEMENTS_IF_SERVICES
405 /*---------------------------------------------------------------------------*/
407 #ifdef CYGHWR_HAL_ARM_INTEGRATOR_DIAG_LEDS
412 volatile unsigned int *leds = (unsigned int *)INTEGRATOR_DBG_LEDS ;
417 hal_diag_alpha_led(unsigned int val)
419 volatile unsigned int *led = (unsigned int *)INTEGRATOR_DBG_BASE;
421 while (*led & 0x01) ;
427 hal_diag_alpha_led_char(char c1, char c2)
429 volatile unsigned int *led = (unsigned int *)INTEGRATOR_DBG_BASE;
430 unsigned int current;
434 if (c1 < 32 || c1 > 127) c1=32;
435 if (c1 >= 'a' && c1 < 'z') c1 -= 32;
437 current &= ~(0x00007FFE << 14);
438 current |= (char_codes[c1-32] << 14);
442 if (c2 < 32 || c2 > 127) c2 = 32;
443 if (c2 >= 'a' && c2 <= 'z') c2 -= 32;
445 current &= ~(0x00007FFE);
446 current |= char_codes[c2-32];
449 hal_diag_alpha_led(current);
453 #endif // CYGHWR_HAL_ARM_INTEGRATOR_DIAG_LEDS
455 /*---------------------------------------------------------------------------*/
456 /* End of hal_diag.c */