]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/hal/arm/gps4020/v2_0/src/hal_diag.c
Initial revision
[karo-tx-redboot.git] / packages / hal / arm / gps4020 / 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 // Copyright (C) 2003 Gary Thomas
13 //
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.
17 //
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
21 // for more details.
22 //
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.
26 //
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.
33 //
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 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
38 // at http://sources.redhat.com/ecos/ecos-license/
39 // -------------------------------------------
40 //####ECOSGPLCOPYRIGHTEND####
41 //=============================================================================
42 //#####DESCRIPTIONBEGIN####
43 //
44 // Author(s):   nickg, gthomas
45 // Contributors:nickg, gthomas
46 // Date:        1998-03-02
47 // Purpose:     HAL diagnostic output
48 // Description: Implementations of HAL diagnostic output support.
49 //
50 //####DESCRIPTIONEND####
51 //
52 //===========================================================================*/
53
54 #include <pkgconf/hal.h>
55
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
59
60 #include <cyg/hal/hal_arch.h>           // SAVE/RESTORE GP macros
61 #include <cyg/hal/hal_io.h>             // IO macros
62 #include <cyg/hal/hal_if.h>             // interface API
63 #include <cyg/hal/hal_intr.h>           // HAL_ENABLE/MASK/UNMASK_INTERRUPTS
64 #include <cyg/hal/hal_misc.h>           // Helper functions
65 #include <cyg/hal/drv_api.h>            // CYG_ISR_HANDLED
66
67 #include <cyg/hal/gps4020.h>
68
69 //-----------------------------------------------------------------------------
70 typedef struct {
71     volatile struct _gps4020_uart *base;
72     cyg_int32             msec_timeout;
73     int                   isr_vector;
74     int                   int_state;
75 } channel_data_t;
76
77 static channel_data_t serial_channels[] = {
78     { (volatile struct _gps4020_uart *)GPS4020_UART1, 1000, CYGNUM_HAL_INTERRUPT_UART1_RX, 0 },
79 };
80
81 //-----------------------------------------------------------------------------
82
83 static void
84 cyg_hal_plf_serial_init_channel(void* __ch_data)
85 {
86     volatile struct _gps4020_uart *uart = ((channel_data_t*)__ch_data)->base;
87     uart->mode = SMR_STOP_1 | SMR_PARITY_OFF | SMR_LENGTH_8;
88     uart->baud = 0x15;  // FIXME - Magic for 57600
89     uart->modem_control = SMR_DTR | SMR_RTS;
90     uart->control = SCR_TEN | SCR_REN;
91 }
92
93 void
94 cyg_hal_plf_serial_putc(void *__ch_data, char c)
95 {
96     volatile struct _gps4020_uart *uart = ((channel_data_t*)__ch_data)->base;
97     // Wait for space for character
98     do {
99     } while ((uart->status & SSR_TxEmpty) == 0);
100     uart->TxRx = c;
101 }
102
103 static cyg_bool
104 cyg_hal_plf_serial_getc_nonblock(void *__ch_data, cyg_uint8 *ch)
105 {
106     volatile struct _gps4020_uart *uart = ((channel_data_t*)__ch_data)->base;
107     if ((uart->status & SSR_RxFull) == 0) {
108         return false;
109     }
110     *ch = uart->TxRx;
111     return true;
112 }
113
114 cyg_uint8
115 cyg_hal_plf_serial_getc(void* __ch_data)
116 {
117     cyg_uint8 ch;
118
119     while(!cyg_hal_plf_serial_getc_nonblock(__ch_data, &ch));
120
121     return ch;
122 }
123
124 static void
125 cyg_hal_plf_serial_write(void* __ch_data, const cyg_uint8* __buf, 
126                          cyg_uint32 __len)
127 {
128     while(__len-- > 0)
129         cyg_hal_plf_serial_putc(__ch_data, *__buf++);
130 }
131
132 static void
133 cyg_hal_plf_serial_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len)
134 {
135     while(__len-- > 0)
136         *__buf++ = cyg_hal_plf_serial_getc(__ch_data);
137 }
138
139 cyg_bool
140 cyg_hal_plf_serial_getc_timeout(void* __ch_data, cyg_uint8* ch)
141 {
142     int delay_count;
143     channel_data_t* chan = (channel_data_t*)__ch_data;
144     cyg_bool res;
145
146     delay_count = chan->msec_timeout * 10; // delay in .1 ms steps
147
148     for(;;) {
149         res = cyg_hal_plf_serial_getc_nonblock(__ch_data, ch);
150         if (res || 0 == delay_count--)
151             break;
152         CYGACC_CALL_IF_DELAY_US(100);
153     }
154
155     return res;
156 }
157
158 static int
159 cyg_hal_plf_serial_control(void *__ch_data, __comm_control_cmd_t __func, ...)
160 {
161     channel_data_t* chan = (channel_data_t*)__ch_data;
162     volatile struct _gps4020_uart *uart = ((channel_data_t*)__ch_data)->base;
163     int ret = 0;
164
165     switch (__func) {
166     case __COMMCTL_IRQ_ENABLE:
167         chan->int_state = 1;
168         uart->control |= SCR_RIE;
169         HAL_INTERRUPT_UNMASK(chan->isr_vector);
170         break;
171     case __COMMCTL_IRQ_DISABLE:
172         ret = chan->int_state;
173         chan->int_state = 0;
174         uart->control &= ~SCR_RIE;
175         HAL_INTERRUPT_MASK(chan->isr_vector);
176         break;
177     case __COMMCTL_DBG_ISR_VECTOR:
178         ret = chan->isr_vector;
179         break;
180     case __COMMCTL_SET_TIMEOUT:
181     {
182         va_list ap;
183
184         va_start(ap, __func);
185
186         ret = chan->msec_timeout;
187         chan->msec_timeout = va_arg(ap, cyg_uint32);
188
189         va_end(ap);
190     }        
191     default:
192         break;
193     }
194     return ret;
195 }
196
197 static int
198 cyg_hal_plf_serial_isr(void *__ch_data, int* __ctrlc, 
199                        CYG_ADDRWORD __vector, CYG_ADDRWORD __data)
200 {
201     int res = 0;
202     channel_data_t* chan = (channel_data_t*)__ch_data;
203     volatile struct _gps4020_uart *uart = ((channel_data_t*)__ch_data)->base;
204     char c;
205
206     cyg_drv_interrupt_acknowledge(chan->isr_vector);
207     *__ctrlc = 0;
208     if ((uart->status & SSR_RxFull) != 0) {
209         c = uart->TxRx;
210         if (cyg_hal_is_break(&c, 1))
211             *__ctrlc = 1;
212         res = CYG_ISR_HANDLED;
213     }
214     return res;
215 }
216
217 static void
218 cyg_hal_plf_serial_init(void)
219 {
220     hal_virtual_comm_table_t* comm;
221     int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
222
223     // Init channel
224     cyg_hal_plf_serial_init_channel(&serial_channels[0]);
225
226     // Setup procs in the vector table
227
228     // Set channel 0
229     CYGACC_CALL_IF_SET_CONSOLE_COMM(0);
230     comm = CYGACC_CALL_IF_CONSOLE_PROCS();
231     CYGACC_COMM_IF_CH_DATA_SET(*comm, &serial_channels[0]);
232     CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write);
233     CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read);
234     CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc);
235     CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc);
236     CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control);
237     CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr);
238     CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout);
239
240     // Restore original console
241     CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
242 }
243
244 void
245 cyg_hal_plf_comms_init(void)
246 {
247     static int initialized = 0;
248
249     if (initialized)
250         return;
251
252     initialized = 1;
253
254     cyg_hal_plf_serial_init();
255 }