]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/hal/arm/mac7100/var/v2_0/src/hal_diag.c
Initial revision
[karo-tx-redboot.git] / packages / hal / arm / mac7100 / var / v2_0 / src / hal_diag.c
1 /*=============================================================================
2 //
3 //      hal_diag.c
4 //
5 //      HAL diagnostic output code
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 Red Hat, 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 version.
16 //
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
20 // for more details.
21 //
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.
25 //
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.
32 //
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.
35 // -------------------------------------------
36 //####ECOSGPLCOPYRIGHTEND####
37 //=============================================================================
38 //#####DESCRIPTIONBEGIN####
39 //
40 // Author(s):   Ilija Koco <ilijak@siva.com.mk>
41 // Contributors:
42 // Date:        2006-04-15
43 // Purpose:     HAL diagnostic output
44 // Description: Implementations of HAL diagnostic output support.
45 //
46 //####DESCRIPTIONEND####
47 //
48 //===========================================================================
49  */
50
51 #include <pkgconf/hal.h>
52 #include CYGBLD_HAL_PLATFORM_H
53
54 #include <cyg/infra/cyg_type.h>         // base types
55
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>
63
64 #include <cyg/hal/var_io.h>             //
65 #include <cyg/devs/ser_esci.h>           // ESCI registers
66
67 //-----------------------------------------------------------------------------
68 typedef struct {
69     void *base;
70     cyg_int32 msec_timeout;
71     int isr_vector;
72     int isr_level;
73     int baud_rate;
74 } channel_data_t;
75
76
77
78 //-----------------------------------------------------------------------------
79
80 void
81 cyg_hal_plf_serial_putc(void *__ch_data, char c);
82
83
84 static void
85 cyg_hal_plf_serial_init_channel(void* __ch_data)
86 {
87         
88     channel_data_t* chan = (channel_data_t*)__ch_data;
89     cyg_uint8 *esci_base = chan->base;
90     
91
92     // Reset device
93     // 8-1-no parity.
94
95     HAL_WRITE_UINT8(FREESCALE_ESCI_CR3(esci_base), 0);
96     HAL_WRITE_UINT16(FREESCALE_ESCI_LINCTRL(esci_base), 0);
97     HAL_WRITE_UINT16(FREESCALE_ESCI_BD(esci_base), 
98                      FREESCALE_ESCI_BAUD(chan->baud_rate));
99
100     // Enable RX and TX
101     HAL_WRITE_UINT16(FREESCALE_ESCI_CR12(esci_base), (FREESCALE_ESCI_CR12_TE | 
102                                                       FREESCALE_ESCI_CR12_RE));
103 }
104
105 void
106 cyg_hal_plf_serial_putc(void* __ch_data, char ch_out)
107 {
108     channel_data_t* chan = (channel_data_t*)__ch_data;
109     CYG_ADDRESS esci_base = (CYG_ADDRESS) chan->base;
110     cyg_uint16 esci_sr;
111     
112     CYGARC_HAL_SAVE_GP();
113
114     do {
115         HAL_READ_UINT16(FREESCALE_ESCI_SR(esci_base), esci_sr);
116     } while (!(esci_sr & FREESCALE_ESCI_SR_TDRE));
117     
118     HAL_WRITE_UINT16(FREESCALE_ESCI_SR(esci_base), FREESCALE_ESCI_SR_TDRE);    
119     HAL_WRITE_UINT8(FREESCALE_ESCI_DRL(esci_base), ch_out);
120
121     CYGARC_HAL_RESTORE_GP();
122 }
123
124 static cyg_bool
125 cyg_hal_plf_serial_getc_nonblock(void* __ch_data, cyg_uint8* p_ch_in)
126 {
127     channel_data_t* chan = (channel_data_t*)__ch_data;    
128     CYG_ADDRESS esci_base = (CYG_ADDRESS) chan->base;
129     cyg_uint16 esci_sr;
130     cyg_uint8 ch_in;
131
132     HAL_READ_UINT16(FREESCALE_ESCI_SR(esci_base), esci_sr);
133     if (!(esci_sr & FREESCALE_ESCI_SR_RDRF))
134         return false;
135
136     HAL_READ_UINT8(FREESCALE_ESCI_DRL(esci_base), ch_in);
137     HAL_WRITE_UINT16(FREESCALE_ESCI_SR(esci_base), FREESCALE_ESCI_SR_RDRF);
138     *p_ch_in = ch_in;
139
140     return true;
141 }
142
143 cyg_uint8
144 cyg_hal_plf_serial_getc(void* __ch_data)
145 {
146     cyg_uint8 ch;
147     CYGARC_HAL_SAVE_GP();
148
149     while(!cyg_hal_plf_serial_getc_nonblock(__ch_data, &ch));
150
151     CYGARC_HAL_RESTORE_GP();
152     return ch;
153 }
154
155 static void
156 cyg_hal_plf_serial_write(void* __ch_data, const cyg_uint8* __buf, 
157                          cyg_uint32 __len)
158 {
159     CYGARC_HAL_SAVE_GP();
160
161     while(__len-- > 0)
162         cyg_hal_plf_serial_putc(__ch_data, *__buf++);
163
164     CYGARC_HAL_RESTORE_GP();
165 }
166
167 static void
168 cyg_hal_plf_serial_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len)
169 {
170     CYGARC_HAL_SAVE_GP();
171
172     while(__len-- > 0)
173         *__buf++ = cyg_hal_plf_serial_getc(__ch_data);
174
175     CYGARC_HAL_RESTORE_GP();
176 }
177
178 cyg_bool
179 cyg_hal_plf_serial_getc_timeout(void* __ch_data, cyg_uint8* p_ch_in)
180 {
181     int delay_count;
182     cyg_bool res;
183     CYGARC_HAL_SAVE_GP();
184
185     // delay in .1 ms steps
186     delay_count = ((channel_data_t*)__ch_data)->msec_timeout * 10; 
187
188     for(;;) {
189         res = cyg_hal_plf_serial_getc_nonblock(__ch_data, p_ch_in);
190         if (res || 0 == delay_count--)
191             break;
192         
193         CYGACC_CALL_IF_DELAY_US(100);
194     }
195
196     CYGARC_HAL_RESTORE_GP();
197     return res;
198 }
199
200 static int
201 cyg_hal_plf_serial_control(void *__ch_data, __comm_control_cmd_t __func, ...)
202 {
203     static int irq_state = 0;
204     channel_data_t* chan = (channel_data_t*)__ch_data;
205     cyg_uint8* base = ((channel_data_t*)__ch_data)->base;
206     cyg_uint16 ser_port_reg;
207     int ret = 0;
208     va_list ap;
209
210     CYGARC_HAL_SAVE_GP();
211     va_start(ap, __func);
212
213     switch (__func) {
214     case __COMMCTL_GETBAUD:
215         ret = chan->baud_rate;
216         break;
217     case __COMMCTL_SETBAUD:
218         chan->baud_rate = va_arg(ap, cyg_int32);
219         // Should we verify this value here?
220         cyg_hal_plf_serial_init_channel(chan);
221         ret = 0;
222         break;
223     case __COMMCTL_IRQ_ENABLE:
224         irq_state = 1;
225         HAL_INTERRUPT_ACKNOWLEDGE(chan->isr_vector);
226         HAL_INTERRUPT_UNMASK(chan->isr_vector);
227         
228         HAL_READ_UINT16(FREESCALE_ESCI_CR12(base), ser_port_reg);
229         ser_port_reg |= FREESCALE_ESCI_CR12_RIE;
230         HAL_WRITE_UINT16(FREESCALE_ESCI_CR12(base), ser_port_reg);
231         
232         break;
233     case __COMMCTL_IRQ_DISABLE:
234         ret = irq_state;
235         irq_state = 0;
236         HAL_INTERRUPT_MASK(chan->isr_vector);
237         
238         HAL_READ_UINT16(FREESCALE_ESCI_CR12(base), ser_port_reg);
239         ser_port_reg &= ~(cyg_uint16)FREESCALE_ESCI_CR12_RIE;
240         HAL_WRITE_UINT16(FREESCALE_ESCI_CR12(base), ser_port_reg);
241         break;
242     case __COMMCTL_DBG_ISR_VECTOR:
243         ret = chan->isr_vector;
244         break;
245     case __COMMCTL_SET_TIMEOUT:
246         ret = chan->msec_timeout;
247         chan->msec_timeout = va_arg(ap, cyg_uint32);
248     default:
249         break;
250     }
251
252     va_end(ap);
253     CYGARC_HAL_RESTORE_GP();
254     return ret;
255 }
256
257 static int
258 cyg_hal_plf_serial_isr(void *__ch_data, int* __ctrlc, 
259                        CYG_ADDRWORD __vector, CYG_ADDRWORD __data)
260 {
261     
262     channel_data_t* chan = (channel_data_t*)__ch_data;
263     CYG_ADDRESS esci_base = (CYG_ADDRESS) chan->base;
264     cyg_uint16 esci_sr;
265     int res = 0;
266     cyg_uint8 ch_in;
267     CYGARC_HAL_SAVE_GP();
268
269     *__ctrlc = 0;
270     
271     HAL_READ_UINT16(FREESCALE_ESCI_SR(esci_base), esci_sr);
272     if (esci_sr & FREESCALE_ESCI_SR_RDRF){
273         HAL_READ_UINT8(FREESCALE_ESCI_DRL(esci_base), ch_in);
274         if( cyg_hal_is_break( &ch_in , 1 ) )
275             *__ctrlc = 1;
276
277         res = CYG_ISR_HANDLED;
278         HAL_WRITE_UINT16(FREESCALE_ESCI_SR(esci_base), FREESCALE_ESCI_SR_RDRF);
279     }
280
281     HAL_INTERRUPT_ACKNOWLEDGE(chan->isr_vector);
282
283     CYGARC_HAL_RESTORE_GP();
284     return res;
285 }
286
287 static channel_data_t mac7100_ser_channels[4] = {
288     { (cyg_uint16*)FREESCALE_ESCI_A_BASE, 1000, MAC7100_ESCI_A_IV, 
289       MAC7100_ESCI_A_LEVEL, CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD},
290     { (cyg_uint16*)FREESCALE_ESCI_B_BASE, 1000, MAC7100_ESCI_B_IV, 
291       MAC7100_ESCI_B_LEVEL, CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD},
292     { (cyg_uint16*)FREESCALE_ESCI_C_BASE, 1000, MAC7100_ESCI_C_IV, 
293       MAC7100_ESCI_C_LEVEL, CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD},
294     { (cyg_uint16*)FREESCALE_ESCI_D_BASE, 1000, MAC7100_ESCI_D_IV, 
295       MAC7100_ESCI_D_LEVEL, CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD},
296 };
297
298 static void
299 cyg_hal_plf_serial_init(void)
300 {
301     hal_virtual_comm_table_t* comm;
302     int cur;
303
304     cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
305
306     // Init channels
307     cyg_hal_plf_serial_init_channel(&mac7100_ser_channels[0]);
308 #if CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS > 1
309     cyg_hal_plf_serial_init_channel(&mac7100_ser_channels[1]);
310 #endif
311 #if CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS > 2
312     cyg_hal_plf_serial_init_channel(&mac7100_ser_channels[2]);
313 #endif
314 #if CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS > 3
315     cyg_hal_plf_serial_init_channel(&mac7100_ser_channels[3]);
316 #endif
317     // Setup procs in the vector table
318
319     // Set channel 0
320     CYGACC_CALL_IF_SET_CONSOLE_COMM(0);
321     comm = CYGACC_CALL_IF_CONSOLE_PROCS();
322     CYGACC_COMM_IF_CH_DATA_SET(*comm, &mac7100_ser_channels[0]);
323     CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write);
324     CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read);
325     CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc);
326     CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc);
327     CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control);
328     CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr);
329     CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout);
330
331 #if CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS > 1
332     // Set channel 1
333     CYGACC_CALL_IF_SET_CONSOLE_COMM(1);
334     comm = CYGACC_CALL_IF_CONSOLE_PROCS();
335     CYGACC_COMM_IF_CH_DATA_SET(*comm, &mac7100_ser_channels[1]);
336     CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write);
337     CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read);
338     CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc);
339     CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc);
340     CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control);
341     CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr);
342     CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout);
343 #endif
344 #if CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS > 2    
345     CYGACC_CALL_IF_SET_CONSOLE_COMM(2);
346     comm = CYGACC_CALL_IF_CONSOLE_PROCS();
347     CYGACC_COMM_IF_CH_DATA_SET(*comm, &mac7100_ser_channels[2]);
348     CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write);
349     CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read);
350     CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc);
351     CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc);
352     CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control);
353     CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr);
354     CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout);
355 #endif
356 #if CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS > 3    
357     CYGACC_CALL_IF_SET_CONSOLE_COMM(3);
358     comm = CYGACC_CALL_IF_CONSOLE_PROCS();
359     CYGACC_COMM_IF_CH_DATA_SET(*comm, &mac7100_ser_channels[3]);
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);
367 #endif
368
369     // Restore original console
370     CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
371 }
372
373 void
374 cyg_hal_plf_comms_init(void)
375 {
376     static int initialized = 0;
377
378     if (initialized)
379         return;
380     initialized = 1;
381     cyg_hal_plf_serial_init();
382 }
383
384 //-----------------------------------------------------------------------------
385 // End of hal_diag.c