]> git.karo-electronics.de Git - karo-tx-redboot.git/blob - packages/hal/powerpc/mpc8260/v2_0/src/quicc2_diag.c
Initial revision
[karo-tx-redboot.git] / packages / hal / powerpc / mpc8260 / v2_0 / src / quicc2_diag.c
1 //=============================================================================
2 //
3 //      quicc2_diag.c
4 //
5 //      HAL diagnostic I/O support routines for MPC8260/QUICC2
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) 2002 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):   hmt
45 // Contributors:hmt, gthomas
46 // Date:        1999-06-08
47 // Purpose:     HAL diagnostics I/O support
48 // Description: 
49 //
50 //####DESCRIPTIONEND####
51 //
52 //=============================================================================
53
54 #include <pkgconf/hal.h>
55 #include <cyg/hal/hal_mem.h>            // HAL memory definitions
56 #include <cyg/infra/cyg_type.h>
57 #include <cyg/hal/hal_if.h>             // hal_if_init
58 #include <cyg/hal/hal_io.h>             // hal_if_init
59 #include <cyg/hal/hal_misc.h>           // cyg_hal_is_break
60
61 #include <cyg/hal/drv_api.h>            // CYG_ISR_HANDLED
62 // Added by WPD
63 #include <cyg/hal/hal_diag.h>
64 #include <cyg/hal/ppc_regs.h>
65 #include <cyg/hal/var_intr.h>
66 #include <cyg/hal/mpc8260.h>            // Needed for IMMR structure
67
68 // For Baud Rate Calculation, see MPC8260 PowerQUICC II User's Manual
69 // 16.3 UART Baud Rate Examples, page 16-5.
70 // BRGCx[DIV16]  = 0 ==> value of 1 (Prescale divider)
71 // BRGCx[EXTC]   = 16.667 MHz (Baud Rate generator input clock)
72 // GSMRx_L[xDCR] = 16 (Sampling Rate)
73 // UART_CLK_DIV + 1 = 
74 //       BRGCx[EXTC] / (BRGCx[DIV16] * UART_BAUD_RATE * GSMRx_L[xDCR])
75 // UART_CLK_DIV = ((66.667 MHz / 4) / (UART_BAUD_RATE * 16)) - 1
76 // UART_CLK_DIV = ((66.667 MHz ) / (UART_BAUD_RATE * 64)) - 1
77 // UART_CLK_DIV = ((CYGHWR_HAL_POWERPC_BOARD_SPEED*1000000 ) 
78 //                / (UART_BAUD_RATE * 64)) (Calculation will truncate, so 
79 //                                         lose the -1 )
80 #define UART_BIT_RATE(n) \
81     (((int)(CYGHWR_HAL_POWERPC_BOARD_SPEED*1000000))/(n * 64))
82 #define UART_BAUD_RATE CYGNUM_HAL_DIAG_BAUD
83
84
85 /***********************/
86 /* Global Declarations */
87 /***********************/
88 //#define USE_SMC1
89
90 volatile t_PQ2IMM  *IMM;   /* IMM base pointer */
91 volatile BDRINGS *RxTxBD;  /* buffer descriptors base pointer */
92 volatile LB *SCC1Buffers;  /* SCC1 base pointers */
93
94 #define SMC1_PRAM   0x04703800
95 #define BD_RX_ERROR 0xBF    /* Mask for set of Receive Buffer Errors,
96                                including: DE, LG, NO, AB, CR, OV, CD */
97
98 /*---------------------*/
99 /* Function Prototypes */
100 /*---------------------*/
101
102 static void  InitSCC1Uart(void);
103 static void  ConfigSCC1Clock(void);
104 static void  InitParallelPorts(void);
105 static cyg_uint8 SCC1Poll(void);
106 static void  InitBDs(void);
107
108 static cyg_uint8
109 cyg_hal_plf_serial_getc(void* __ch_data);
110
111 static cyg_bool
112 cyg_hal_plf_serial_getc_nonblock(void* __ch_data, cyg_uint8* ch);
113
114 static cyg_bool
115 cyg_hal_plf_serial_getc_timeout(void* __ch_data, cyg_uint8* ch);
116
117 static void
118 cyg_hal_plf_serial_putc(void* __ch_data, cyg_uint8 ch);
119
120 static void
121 cyg_hal_plf_serial_write(void* __ch_data, const cyg_uint8* __buf, 
122                          cyg_uint32 __len);
123 static void
124 cyg_hal_plf_serial_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len);
125
126 static void
127 cyg_hal_plf_serial_init_channel(void);
128
129 static int
130 cyg_hal_plf_serial_isr(void *__ch_data, int* __ctrlc, 
131                        CYG_ADDRWORD __vector, CYG_ADDRWORD __data);
132
133 static int
134 cyg_hal_plf_serial_control(void *__ch_data, __comm_control_cmd_t __func, ...);
135
136 static int
137 cyg_hal_plf_serial_isr(void *__ch_data, int* __ctrlc, 
138                        CYG_ADDRWORD __vector, CYG_ADDRWORD __data)
139 {
140     t_PQ2IMM  *immr = (t_PQ2IMM*) __ch_data;
141     struct cp_bufdesc *bd;
142     char ch;
143     int res = 0;
144     cyg_uint32 regval;
145
146     CYGARC_HAL_SAVE_GP();
147     //GREEN_LED_ON;
148 /*
149     dbg_values[3]++;
150     dbg_values[10+dbg_values[3]] = 
151         RxTxBD->RxBD.bd_cstatus
152         | (immr->scc_regs[SCC1].scce<<16);
153 */
154     *__ctrlc = 0;
155     if (immr->scc_regs[SCC1].scce & 0x0001) {
156
157         // Clear the event by writing a "1" to the prpoper bit.
158         immr->scc_regs[SCC1].scce = 0x0001;
159
160         if((RxTxBD->RxBD.bd_cstatus  &  0x8000) == 0){
161             ch = *(RxTxBD->RxBD.bd_addr);
162             /*----------------------*/
163             /* Set Buffer Empty bit */
164             /*----------------------*/
165             //dbg_values[10+dbg_values[3]] = __vector | 0xffff0000;
166             //dbg_values[10+dbg_values[3]] |= ch << 8;
167     
168             RxTxBD->RxBD.bd_cstatus |= 0x8000;   
169
170             if( cyg_hal_is_break( &ch , 1 ) ){
171                 //GREEN_LED_ON;
172               *__ctrlc = 1;
173               //dbg_values[7] = immr->ic_sivec;              
174             }
175         }
176         // Interrupt handled. Acknowledge it.
177         //eppc->cpmi_cisr = 0x10;
178         // Clear interrupt in SIPNR_L by writing a one to bit 8 (0x800000)
179         HAL_READ_UINT32(  ((char *) IMM) + 0x10000 + CYGARC_REG_IMM_SIPNR_L,
180                          regval);
181         regval |= 0x00800000;
182         HAL_WRITE_UINT32( ((char *) IMM) + 0x10000 + CYGARC_REG_IMM_SIPNR_L,
183                           regval);
184
185         res = CYG_ISR_HANDLED;
186     }
187
188     //GREEN_LED_OFF;
189     CYGARC_HAL_RESTORE_GP();
190     return res;
191 }
192
193 /* Early initialization of comm channels. Must not rely
194  * on interrupts, yet. Interrupt operation can be enabled
195  * in _bsp_board_init().
196  */
197 void
198 cyg_hal_plf_serial_init(void)
199 {
200 #ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
201     hal_virtual_comm_table_t* comm;
202     int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
203
204     static int init = 0;  // It's wrong to do this more than once
205     if (init) return;
206     init++;
207
208     // init_channel sets the global *IMM == 0x04700000, the base of the
209     // Internal Memory map for the MPC8260
210     cyg_hal_plf_serial_init_channel();
211
212     // Setup procs in the vector table
213
214     // Set channel 0
215     CYGACC_CALL_IF_SET_CONSOLE_COMM(0);// Should be configurable!
216     comm = CYGACC_CALL_IF_CONSOLE_PROCS();
217     CYGACC_COMM_IF_CH_DATA_SET(*comm, IMM);
218     CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write);
219     CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read);
220     CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc);
221     CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc);
222     CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control);
223     CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr);
224     CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout);
225
226     // Restore original console
227     CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
228
229 #else // No CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
230     static int init = 0;  // It's wrong to do this more than once
231     if (init) return;
232     init++;
233
234     cyg_hal_plf_serial_init_channel();
235 #endif
236 }
237
238 static void
239 cyg_hal_plf_serial_init_channel(void)
240 {
241     /* We will assume here that the IMMR has been programmed such that
242      * the internal Memory Map starts at 0x04700000.  Initialization
243      * should have done that setup.
244      */
245
246     IMM =  (t_PQ2IMM *)0x04700000;  /* MPC8260 internal register map  */
247
248     /*----------------------------------------------------------------------*/  
249     /* Get a pointer to the BD area on DP RAM. The buffer descriptors (BDs) */
250     /* and the Rx/Tx data buffers will be located right after SCC1's para-  */
251     /* meter RAM area because only 2 BDs and 2 data buffers are being used  */
252     /* for this port and SCC1 only uses 64 bytes of it's allotted 256 for   */
253     /* it's parameter ram. One BD and one data buffer each for transmit and */
254     /* receive will be used. This buffer descriptor area will take up 16    */
255     /* bytes.                                                               */
256     /*----------------------------------------------------------------------*/  
257       
258
259     RxTxBD = (BDRINGS *) 0x04708070;
260     //    (((CYG_WORD)&(IMM->pram.serials.scc_pram[SCC1])) + 72);  
261
262     //RxTxBD = (BDRINGS *)
263     //    (((CYG_WORD)&(IMM->pram.serials.scc_pram[SCC1])) + 72);  
264
265     /*-------------------------------------------------------------------*/
266     /* Establish the buffer pool in Dual Port RAM. We do this because the*/
267     /* pool size is only 2 bytes (1 for Rx and 1 for Tx) and to avoid    */
268     /* disabling data cache for the memory region where BufferPool would */
269     /* reside. The CPM does not recognize data in buffer pools once it   */
270     /* been cached. It's acesses are direct through DMA to external      */
271     /* memory.                                                           */
272     /*-------------------------------------------------------------------*/
273
274     //SCC1Buffers = (LB *)
275     //    (((CYG_WORD)&(IMM->pram.serials.scc_pram[SCC1])) + 96); 
276
277     SCC1Buffers = (LB *) 0x04708090;
278     //    (((CYG_WORD)&(IMM->pram.serials.scc_pram[SCC1]))
279     //     + 72 + 14); 
280
281    /*----------------------------------------*/
282    /* Initialize SCC1 and buffer descriptors */
283    /*----------------------------------------*/
284 /*    while(1); */
285
286     InitSCC1Uart();
287
288 }
289
290 /*---------------------------------------------------------------------------
291 *
292 * FUNCTION NAME:  InitBDs
293 *
294 *
295 * DESCRIPTION:
296 *
297 *  Initializes BD rings to point RX BDs to first half of buffer pool and TX 
298 *  BDs to second half of buffer pool. This function also initializes the 
299 *  buffer descriptors control and data length fields. It also ensures that 
300 *  transmit and recieve functions are disabled before buffer descriptors are
301 *  initialized.
302 *
303 * EXTERNAL EFFECTS: Disable Tx/Rx functions. Changes BDs in dual port ram.
304 *
305 * PARAMETERS: None
306 *
307 * RETURNS: None
308 *
309 *---------------------------------------------------------------------------*/
310
311 void InitBDs()
312
313 {
314    
315    /*--------------------------------------------------------------------*/
316    /* First let's ensure the SCC1 functions are off while we program the */
317    /* buffer descriptors and the parameter ram. Clear the ENT/ENR bits   */
318    /* in the GSMR -- disable Transmit/Receive                            */
319    /*--------------------------------------------------------------------*/
320    
321    IMM->scc_regs[SCC1].gsmr_l &= DISABLE_TX_RX;
322
323    /*--------------------------------------*/
324    /* Issue Init Stop TX Command for SCC1. */
325    /*--------------------------------------*/
326
327    while ((IMM->cpm_cpcr & CPCR_FLG) != READY_TO_RX_CMD); 
328
329    IMM->cpm_cpcr = SCC1_PAGE_SUBBLOCK |
330                    CPCR_STOP_TX |
331                    CPCR_FLG;             /* ISSUE COMMAND */
332
333    while ((IMM->cpm_cpcr & CPCR_FLG) != READY_TO_RX_CMD); 
334
335
336    /*-----------------------------------*/
337    /* Setup Receiver Buffer Descriptors */
338    /*-----------------------------------*/
339    
340 #if defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT) \
341     || defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT)
342    /* Set receive Buffer to generate an interrupt when buffer full */
343    RxTxBD->RxBD.bd_cstatus = 0xB000; /* 0xB000; */
344 #else
345    RxTxBD->RxBD.bd_cstatus = 0xA000;     /* Empty, Wrap Bit */
346 #endif
347    //dbg_values[3] = RxTxBD->RxBD.bd_cstatus;
348    RxTxBD->RxBD.bd_length = 1;
349    RxTxBD->RxBD.bd_addr = &(SCC1Buffers->RxBuffer);
350
351    /*--------------------------------------*/
352    /* Setup Transmitter Buffer Descriptors */
353    /*--------------------------------------*/
354
355    RxTxBD->TxBD.bd_cstatus = 0x2800;   /* Buffer not yet ready; Wrap Bit 
356                                           Clear-to-send_report           */
357
358    RxTxBD->TxBD.bd_length = 1;
359    RxTxBD->TxBD.bd_addr = &(SCC1Buffers->TxBuffer);
360
361 } /* end InitBDs */
362
363
364 /*---------------------------------------------------------------------------
365 *
366 * FUNCTION NAME:  InitSCC1Uart 
367 *                  
368 *
369 * DESCRIPTION:
370 *
371 *  SCC1 Uart Mode Initialization Routine.
372 *                 
373 * EXTERNAL EFFECT:
374 *
375 *  Initializes SCC1 to operate in Uart mode at 9600 Baud, No Parity, 8 data
376 *  bits, and 1 stop bit. 
377 *
378 * PARAMETERS: None
379 *
380 * RETURNS: None 
381 *
382 *--------------------------------------------------------------------------*/
383
384 void InitSCC1Uart()
385
386 {
387     cyg_uint32 regval;
388    /*----------------------------------------------------------------------*/
389    /* Configure the parallel ports so that TXD and RXD are connected to    */
390    /* the appropriate port pins and are configured according to their      */
391    /* functions.                                                           */
392    /*----------------------------------------------------------------------*/
393
394    InitParallelPorts();
395
396    /*------------------------------------------*/
397    /* Configure Clock Source and Clock Routing */
398    /*------------------------------------------*/
399
400    ConfigSCC1Clock();
401
402    /*-----------------------------------*/
403    /* Initialize the Buffer Descriptors */
404    /*-----------------------------------*/
405
406    InitBDs();
407
408    /*----------------------------------------------------------------------*/
409    /* Program Rx and Tx Function Codes (RFCRx/TFCRx).                      */
410    /*                                                                      */
411    /* - Bits 0-1 reserved. Set to zero.                                    */
412    /*                                                                      */
413    /* - GBL (Global) = 0 = Snooping Disabled.                              */
414    /*                                                                      */
415    /* - BO (Byte Ordering) = 11 = Big-endian or true little-endian.        */
416    /*                                                                      */
417    /* - TC[2] (Transfer Code) = 0 = Transfer code is 0                     */
418    /*                                                                      */
419    /* - DTB (Data Bus Indicator) = 1 =                                     */
420    /*                                                                      */
421    /*    Use the Local Bus for SDMA operation. In this example it doesn't  */
422    /*    matter because the buffer were located in parameter ram. Normally */
423    /*    this bit would be set because data buffers normally will reside   */
424    /*    in Local memory.                                                  */
425    /*----------------------------------------------------------------------*/
426
427    IMM->pram.serials.scc_pram[SCC1].rfcr = 0x18;
428
429    IMM->pram.serials.scc_pram[SCC1].tfcr = 0x18;
430
431    IMM->scc_regs[SCC1].psmr = 0xB000;
432
433    /*------------------------------------------------------------*/
434    /* Set RBASE, TBASE -- Rx,Tx Buffer Descriptor Base Addresses */
435    /*------------------------------------------------------------*/
436
437    IMM->pram.serials.scc_pram[SCC1].rbase = (CYG_WORD16)&RxTxBD->RxBD;
438
439    IMM->pram.serials.scc_pram[SCC1].tbase = (CYG_WORD16)&RxTxBD->TxBD;     
440
441    /*-----------------------------------------*/
442    /* Set MRBLR -- Max. Receive Buffer Length */
443    /*-----------------------------------------*/
444
445    IMM->pram.serials.scc_pram[SCC1].mrblr = 1;
446    
447    /*----------------------------------------------------------------------*/
448    /* Program the General SCC Mode Register High (GSMR_H)                  */
449    /*                                                                      */
450    /* - Bits 0-14 Reserved. Set to 0.                                      */
451    /*                                                                      */
452    /* - GDE (Glitch Detect Enable) = 0 = No Glitch Detect. BRG supplies    */
453    /*                                    the clock so there's no need to   */
454    /*                                    detect glitches.                  */
455    /*                                                                      */
456    /* - TCRC (Transparent CRC) = 00 = This field is ignored for Uart mode. */
457    /*                                                                      */
458    /* - REVD (Reverse Data) = 0 = This field is ignored for Uart mode.     */
459    /*                                                                      */
460    /* - TRX,TTX (Transparent Receiver/Transmitter) = 00 = Normal operation */
461    /*                                                                      */
462    /* - CDP,CTSP (CD/ & CTS/ sampling) = 00 = Normal Operation (envelope   */
463    /*                                         mode.                        */
464    /*                                                                      */
465    /* - CDS,CTSS (CD/ & CTSS Sampling) = 00 =                              */
466    /*                                                                      */
467    /*    CD/ or CTS/ is assumed to be asynchronous with data. It is        */
468    /*    internally synchronized by the SCC, then data is received (CD/)   */
469    /*    or sent (CTS/) after several clock delays.                        */
470    /*                                                                      */
471    /* - TFL (Transmit FIFO length) = 0 =                                   */
472    /*                                                                      */
473    /*    Normal Operation. The SCC transmit FIFO is 32 bytes.              */
474    /*                                                                      */
475    /* - RFW (Rx FIFO Width) = 1 =                                          */
476    /*                                                                      */
477    /*    Low-latency operation.The receive FIFO is 8 bits wide, reducing   */
478    /*    the Rx FIFO to a quarter of it's normal size. This allows data to */
479    /*    be written to the buffer as soon as a character is received,      */
480    /*    instead of waiting to receive 32 bits. This configuration must be */
481    /*    chosen for character-oriented protocols, such as UART. It can     */
482    /*    also be used for low-performance, low-latency, transparent        */
483    /*    operation.                                                        */
484    /*                                                                      */
485    /* - TXSY (Trasnmitter Synchronized) = 0 =                              */
486    /*                                                                      */
487    /*    No synchronization between receiver and transmitter.              */
488    /*                                                                      */
489    /* - SYNL (Sync Length) = 0 = An external sync (CD/) is used instead of */
490    /*                            the sync pattern in the DSR.              */
491    /*                                                                      */
492    /* - RTSM (RTS/ Mode) = 0 = Send idles between frames as defined by the */
493    /*                          protocol and the TEND bit. TRS/ is negated  */
494    /*                          between frames.                             */
495    /*                                                                      */
496    /* - RSYN (Receive Synchronization Timing) = 0 = This field is ignored  */
497    /*                                               for Uart mode.         */
498    /*                                                                      */
499    /*----------------------------------------------------------------------*/
500       
501    IMM->scc_regs[SCC1].gsmr_h = 0x00000060;
502
503
504    /*----------------------------------------------------------------------*/
505    /* Program the General SCC Mode Register High (GSMR_L)                  */
506    /*                                                                      */
507    /* - Bit 0 Reserved. Set to 0.                                          */
508    /*                                                                      */
509    /* - EDGE (Clock Edge) = 00 = Ignored in Uart Mode.                     */
510    /*                                                                      */
511    /* - TCI (Transmit Clock Invert) = 0 = Normal Operation                 */
512    /*                                                                      */
513    /* - TSNC (Transmit Sense) = 00 = Infinite. Carrier sense is always     */
514    /*                                active.                               */
515    /*                                                                      */
516    /* - RINV (DPLL Rx Input Invert) = 0 = Do not invert.                   */
517    /*                                                                      */
518    /* - TINV (DPLL Tx Input Invert) = 0 = Do not invert.                   */
519    /*                                                                      */
520    /* - TPL (Tx Preamble Length) = 000 = No Preamble.                      */
521    /*                                                                      */
522    /* - TPP (Tx Preamble Pattern) = 00 = All zeros. This field is ignored  */
523    /*                                    for Uart mode.                    */
524    /*                                                                      */
525    /* - TEND (Transmitter Frame Ending) = 0 =                              */
526    /*                                                                      */
527    /*    Default operation. TxD is encoded only when data is sent,         */
528    /*    including the preamble and opening and closing flags/syncs. When  */
529    /*    no data is available to send, the signal is driven high.          */
530    /*                                                                      */
531    /* - TDCR (Transmitter DPLL Clock Rate) = 10 =                          */
532    /*                                                                      */
533    /*    16x clock mode. This value is normally chosen for Uart mode.      */
534    /*                                                                      */
535    /* - RDCR (Receiver DPLL Clock Rate) = 10 =                             */
536    /*                                                                      */
537    /*    16x clock mode. This value is normally chosen for Uart mode.      */
538    /*                                                                      */
539    /* - RENC (Receiver Decoding Method) = 000 =                            */
540    /*                                                                      */
541    /*    NRZ. Required for Uart Mode (asynchronous or synchronous).        */
542    /*                                                                      */
543    /* - TENC (Transmitter Encoding Method) = 000 =                         */
544    /*                                                                      */
545    /*    NRZ. Required for Uart Mode (asynchronous or synchronous).        */
546    /*                                                                      */
547    /* - DIAG (Diagnostic Mode) = 01 = Loopback                             */
548    /*                                                                      */
549    /* - ENR (Enable Receiver) = 0 = Disabled for now. Will enabled later in*/
550    /*                               this function.                         */
551    /*                                                                      */
552    /* - ENT (Enable Transmitter) = 0 = Disabled for now. Will enable later */
553    /*                                  in this function.                   */
554    /*                                                                      */
555    /* - MODE (Channel Protocol Mode) = 0100 = Uart mode.                   */
556    /*                                                                      */
557    /*----------------------------------------------------------------------*/
558
559
560    IMM->scc_regs[SCC1].gsmr_l = 0x00028004;  
561
562    /*-----------------------------------------*/
563    /* Clear SCCE Register by writing all 1's. */
564    /*-----------------------------------------*/
565
566    IMM->scc_regs[SCC1].scce = ALL_ONES;
567
568    /*----------------------------------------------------------------------*/
569    /* Issue Init RX & TX Parameters Command for SCC1. This command to the  */
570    /* CP lets it know to reinitialize SCC1 with the new parameter RAM      */
571    /* values. When the ENT/ENR bits are set below Hunt Mode will begin     */
572    /* automatically.                                                       */
573    /*----------------------------------------------------------------------*/
574
575    while ((IMM->cpm_cpcr & CPCR_FLG) != READY_TO_RX_CMD); 
576
577    IMM->cpm_cpcr = SCC1_PAGE_SUBBLOCK |
578                    CPCR_INIT_TX_RX_PARAMS |
579                    CPCR_FLG;                 /* ISSUE COMMAND */
580
581    while ((IMM->cpm_cpcr & CPCR_FLG) != READY_TO_RX_CMD); 
582
583    /*-------------------------------------------------------------*/
584    /* Set the ENT/ENR bits in the GSMR -- Enable Transmit/Receive */
585    /*-------------------------------------------------------------*/
586
587     IMM->scc_regs[SCC1].gsmr_l |= GSMR_L1_ENT | GSMR_L1_ENR;
588 #if defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT) \
589     || defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT)
590 #define PFADDED   
591 #ifdef PFADDED   
592     // Fill out the control Character Table.  Make the first entry 
593     // an end of table line. 
594     // cc[0] = 0x4003 ==> reject if char = 0x3, write to RCCR
595     IMM->pram.serials.scc_pram[SCC1].SpecificProtocol.u.cc[0] = 0x4003;
596     {
597         int i;
598         for (i = 0; i < 8; i++){
599             IMM->pram.serials.scc_pram[SCC1].SpecificProtocol.u.cc[i] = 0x8000;
600         }
601     }
602     
603     IMM->pram.serials.scc_pram[SCC1].SpecificProtocol.u.rccm  = 0xc000;
604 #endif
605    /*-----------------------------------------*/
606     /* Write to the SCCM mask register to enable an CCR interrupt*/
607    /*-----------------------------------------*/
608    IMM->scc_regs[SCC1].sccm = 0x1;
609
610    /* Unmask the CPM SCC1 interrupt */
611    HAL_READ_UINT32( ((char *) IMM) + 0x10000 + CYGARC_REG_IMM_SIMR_L, regval);
612    regval |= 0x00800000;
613    HAL_WRITE_UINT32( ((char *) IMM) + 0x10000 + CYGARC_REG_IMM_SIMR_L, regval);
614
615 #endif
616 } /* end SCC1HInit() */
617
618
619 /*--------------------------------------------------------------------------
620 *
621 * FUNCTION NAME: ConfigSCC1Clock
622 *
623 * DESCRIPTION:
624 *
625 *  This function will configure SCC1 to utilize Baud Rate Generator #1. It 
626 *  will program the the baud rate generator and configure the SMXSCR 
627 *  register in the CPM Mux block to route the clock to SCC1. SCC2, SCC3, and
628 *  SCC4 are also programmed to assume Baud Rate Generator #1, #2, and #3 
629 *  respectively to be routed to them. There was no special reason for doing
630 *  this; The bit values needed to be programmed to something.
631 *
632 *
633 * EXTERNAL EFFECTS: BRGC1 and CMXSCR
634 *
635 * PARAMETERS:  
636 *
637 * RETURNS: Nothing
638 *
639 *--------------------------------------------------------------------------*/
640
641 void  ConfigSCC1Clock()
642
643 {
644     /* FIXME --- This picture is not accurate */
645    /*----------------------------------------------------------------------*/
646    /* Initialize Baud Rate Generator #1 to generate a 9600 clock. The      */
647    /* source of the clock starts with the input clock that is generated    */
648    /* external to the MPC8260 by a clock generator. This clock is then     */
649    /* fed to the CPM PLL where it is multiplied up and the output freq-    */
650    /* uency is determined by the MODCLK_HI bits in the Hard Reset Config-  */
651    /* uration Word and MODCK pins on the MPC8260. This output is fed to a  */
652    /* general purpose Baud Rate Generator Divider that services all 8 baud */
653    /* rate generators. From the output of this divider the the clock goes  */
654    /* to the baud rate generator circuitry where, in this case, BRGCLK is  */
655    /* selected to be BRGO1 (the output clock). This frequency is deter-    */
656    /* mined by a Divide by 1 or 16 divider and then a 12 bit Prescaler     */
657    /* divider. the clock then goes to the CPM Mux where BRG1 is selected   */
658    /* to be TCLK and RCLK to SCC1. This is accomplished by programming the */
659    /* CMXSCR register. TCLK and RCLK are then routed to the SCC1 DPLL      */
660    /* circuitry at 9600 baud where the DPLL will be programmed to multiply */
661    /* the frequency by X16 for UART over-sampling. Here a diagram and the  */
662    /* programming:                                                         */
663    /*                                                                      */
664    /* ----------    ---------         ---------------------                */
665    /* |External|    |MPC8260| 132 Mhz |General Purpose    | 16.5 Mhz       */
666    /* |Clk Gen |----|CPM PLL|---------|Baud Rate Generator|--------->|     */
667    /* |66 Mhz  |    |Block  |         |Divider [/8] (SCCR)|          |     */
668    /* ----------    ---------         ---------------------          |     */
669    /*                                                                |     */
670    /* |<-------------------------------------------------------------|     */
671    /* |                                                                    */
672    /* |   ------------------------              -------------------        */
673    /* |-->|Divide by 1 or 16 in  | 1.03125 Mhz  |12 Bit Prescaler  | BRG01 */
674    /*     |Baud Rate Generator   |------------->|in Baud Rate Gen. |--|    */
675    /*     |Block [/16 selected]  |              |Block [107(0x6B)  |  |    */
676    /*     |(BRGC1 Programmed)    |              |(BRGC1 Programmed)|  |    */
677    /*     ------------------------              --------------------  |    */
678    /*                                                                 |    */
679    /* |<--------------------------------------------------------------|    */
680    /* |                                                                    */
681    /* |            -------------- TCLK  ----------                         */                     
682    /* | 9.638 Khz  |   CPM Mux  |------>| SCC1   |----> TCLK*16 }*16 for   */
683    /* |----------->|  (CMXSCR)  | RCLK  | DPLL   |              }over-     */
684    /*              |(Programmed)|------>| *16    |----> RCLK*16 }sampling  */
685    /*              --------------       |(GSMR_L)|                         */
686    /*                                   ----------                         */
687    /*                                                                      */
688    /* SCCR was programmed in init8260.s. BRGC1,CMXSCR will be programmed   */
689    /* in this function. GSMR_L will be programmed in InitSCC1Uart().       */   
690    /*                                                                      */
691    /*----------------------------------------------------------------------*/
692
693    /*----------------------------------------------------------------------*/
694    /* Program Baud Rate Generator Configuration #1 Register (BRGC1).       */
695    /*                                                                      */
696    /* - Bits 0-13 are reserved. Set to 0.                                  */
697    /*                                                                      */
698    /* - RST (Reset BRG) = 0 = Enable the BRG                               */
699    /*                                                                      */
700    /* - EN (Enable BRG Count) = 1 = Enable clocks to the BRG               */
701    /*                                                                      */
702    /* - EXTC (External Clock Source) = 00 =                                */
703    /*                                                                      */
704    /*    The BRG input clock comes from the BRGCLK                         */
705    /*                                                                      */
706    /* - ATB (AutoBaud) = 0 = Normal operation of the BRG.                  */
707    /*                                                                      */
708    /* - CD (Clock Divider) = 0x6C = 108 decimal =                          */
709    /*                                                                      */
710    /*    The input frequency is 1.03125 Mhz Dividing it by 107 will give   */
711    /*    9.638 Khz. However 1 must be added to the count value because it  */
712    /*    counts down to 0. So the programmed value is 108.                 */
713    /*                                                                      */
714   /* PF edit - changed CD = 0x1A = 26 ==> baud rate of 4 * 9600 = 38400    */
715    /* - DIV16 (Divide-by-16) = 0 = divide by 1.                           */
716    /*----------------------------------------------------------------------*/
717
718   //     IMM->brgs_brgc1 = 0x000100D6;   
719   //IMM->brgs_brgc1 = 0x00010034; /* Attempt to get 38400 baud */   
720   // IMM->brgs_brgc1 = 0x00010022; /* Attempt to get 57600 baud */   
721   //IMM->brgs_brgc1 = 0x00010010; /* Attempt to get 115200 baud */   
722   IMM->brgs_brgc1 = 0x00010000 | (UART_BIT_RATE(UART_BAUD_RATE) << 1);
723
724    /*----------------------------------------------------------------------*/
725    /* Program the CMX SCC Route Register (CMXSCR).                         */
726    /*                                                                      */
727    /* - GR1 (Grant support of SCC1) = 0 =                                  */
728    /*                                                                      */
729    /*    SCC1 transmitter does not support the grant mechanism. The grant  */
730    /*    is always asserted internally.                                    */
731    /*                                                                      */
732    /* - SC1 (SCC1 connection) = 0                                          */
733    /*                                                                      */
734    /*    SCC1 is not connected to the TSA of the SIs but is connected      */
735    /*    directly to the NMSIx pins.                                       */
736    /*                                                                      */
737    /* - RS1CS (Receive SCC1 or clock source) = 000 =                       */
738    /*                                                                      */
739    /*    SCC1 receive clock is BRG1.                                       */
740    /*                                                                      */
741    /* - TS1CS (Transmit SCC1 clock source) = 000 =                         */
742    /*                                                                      */
743    /*    SCC1 transmit clock is BRG1.                                      */
744    /*                                                                      */
745    /* - GR2 (Grant support of SCC2) = 0 =                                  */
746    /*                                                                      */
747    /*    SCC1 transmitter does not support the grant mechanism. The grant  */
748    /*    is always asserted internally.                                    */
749    /*                                                                      */
750    /* - SC2 (SCC2 connection) = 0                                          */
751    /*                                                                      */
752    /*    SCC2 is not connected to the TSA of the SIs but is connected      */
753    /*    directly to the NMSIx pins.                                       */
754    /*                                                                      */
755    /* - RS2CS (Receive SCC2 or clock source) = 001 =                       */
756    /*                                                                      */
757    /*    SCC1 receive clock is BRG2.                                       */
758    /*                                                                      */
759    /* - TS2CS (Transmit SCC2 clock source) = 001 =                         */
760    /*                                                                      */
761    /*    SCC2 transmit clock is BRG2.                                      */
762    /*                                                                      */
763    /* - GR3 (Grant support of SCC3) = 0 =                                  */
764    /*                                                                      */
765    /*    SCC3 transmitter does not support the grant mechanism. The grant  */
766    /*    is always asserted internally.                                    */
767    /*                                                                      */
768    /* - SC3 (SCC3 connection) = 0                                          */
769    /*                                                                      */
770    /*    SCC3 is not connected to the TSA of the SIs but is connected      */
771    /*    directly to the NMSIx pins.                                       */
772    /*                                                                      */
773    /* - RS3CS (Receive SCC3 or clock source) = 010 =                       */
774    /*                                                                      */
775    /*    SCC3 receive clock is BRG3.                                       */
776    /*                                                                      */
777    /* - TS3CS (Transmit SCC3 clock source) = 010 =                         */
778    /*                                                                      */
779    /*    SCC3 transmit clock is BRG3.                                      */
780    /*                                                                      */
781    /* - GR4 (Grant support of SCC4) = 0 =                                  */
782    /*                                                                      */
783    /*    SCC4 transmitter does not support the grant mechanism. The grant  */
784    /*    is always asserted internally.                                    */
785    /*                                                                      */
786    /* - SC4 (SCC4 connection) = 0                                          */
787    /*                                                                      */
788    /*    SCC4 is not connected to the TSA of the SIs but is connected      */
789    /*    directly to the NMSIx pins.                                       */
790    /*                                                                      */
791    /* - RS4CS (Receive SCC4 or clock source) = 011 =                       */
792    /*                                                                      */
793    /*    SCC4 receive clock is BRG4.                                       */
794    /*                                                                      */
795    /* - TS4CS (Transmit SCC4 clock source) = 011 =                         */
796    /*                                                                      */
797    /*    SCC4 transmit clock is BRG4.                                      */
798    /*                                                                      */
799    /*----------------------------------------------------------------------*/
800
801    IMM->cpm_mux_cmxscr = 0x0009121B;  
802
803 } /* end of ConfigSCC1Clock() */
804
805
806
807 /*--------------------------------------------------------------------------
808 *
809 * FUNCTION NAME: InitParallelPorts
810 *
811 * DESCRIPTION:
812 *
813 *  This function programs the parallel port configuration registers to 
814 *  utilize the pins required for proper SCC1 operation. The pins programmed 
815 *  here are TxD and RxD for SCC1 and CD1 for SCC1.
816 *
817 * EXTERNAL EFFECTS: Parallel Port C and D Configuration Registers
818 *
819 * PARAMETERS:  
820 *
821 * RETURNS: Nothing
822 *
823 *--------------------------------------------------------------------------*/
824
825 void InitParallelPorts()
826
827 {
828    /*--------------------------------------------*/
829         /* Program the Port Special Options Registers */
830    /*--------------------------------------------*/
831
832         IMM->io_regs[PORT_C].psor &= 0xFFFDFFFF; /* CD/ pin 14 */
833         IMM->io_regs[PORT_D].psor &= 0xFFFFFFFC; /* clear first */
834         IMM->io_regs[PORT_D].psor |= 0x00000002; /* TXD pin 30| RXD pin 31 */
835
836    /*-------------------------------------------*/
837         /* Program the Port Pin Assignment Registers */
838    /*-------------------------------------------*/
839
840         IMM->io_regs[PORT_C].ppar |= 0x00020000;   /* CD/ pin 14 */
841         IMM->io_regs[PORT_D].ppar |= 0x00000003;   /* TXD pin 30| RXD pin 31 */
842
843    /*-------------------------------------------*/
844         /* Program the Port Data Direction Registers */
845    /*-------------------------------------------*/
846
847         IMM->io_regs[PORT_C].pdir &= 0xFFFDFFFF;   /* CD/ pin 14 */
848         IMM->io_regs[PORT_D].pdir &= 0xFFFFFFFC;   /* clear first */
849         IMM->io_regs[PORT_D].pdir |= 0x00000002;   /* TXD pin 30| RXD pin 31 */
850
851    /*---------------------------------------*/
852         /* Program the Port Open-Drain Registers */
853    /*---------------------------------------*/
854
855         IMM->io_regs[PORT_C].podr &= 0xFFFDFFFF; /* CD/ pin 14 */
856         IMM->io_regs[PORT_D].podr &= 0xFFFFFFFC; /* TXD pin 30| RXD pin 31 */
857
858 }
859
860 /*---------------------------------------------------------------------------
861 *
862 * FUNCTION NAME: BDRxError
863 *
864 * DESCRIPTION:
865 *
866 *     Return TRUE if Buffer Descriptor Status bd_cstatus indicates Receive 
867 *     Error; Return FALSE otherwise note Receive Errors are as follows:
868 *
869 *     0x80: DPLL Error (DE)
870 *     0x20: Length Violation (LG)
871 *     0x10: Non-Octet Aligned (NO)
872 *     0x8: Rx Abort Sequence (AB)
873 *     0x4: Rx CRC Error (CR)
874 *     0x2: Overrun (OV)
875 *     0x1: Carrier Detect Lost (CD)
876 *
877 * EXTERNAL EFFECTS: None
878 *
879 * PARAMETERS:  
880 *
881 *     bd_cstatus
882 *
883 * RETURNS: TRUE if there was an error and FALSE if there wasn't
884 *
885 *---------------------------------------------------------------------------*/
886
887 CYG_WORD16 BDRxError(CYG_WORD16 bd_cstatus)
888
889 {
890    
891    if (bd_cstatus & BD_RX_ERROR)
892       
893       return true;
894
895    else
896
897       return false;
898
899 } /* end BDRxError */
900
901 /*---------------------------------------------------------------------------
902 *
903 * FUNCTION NAME:  SCC1Poll
904 *
905 * DESCRIPTION: Poll SCC1 RxBD and check to see if a character was received
906 *
907 * EXTERNAL EFFECT: NONE
908 *                 
909 * PARAMETERS:  NONE
910 *
911 * RETURNS: A one if there is a character available in the receive buffer,
912 *          else zero.
913 *
914 *--------------------------------------------------------------------------*/
915
916 cyg_uint8 SCC1Poll(void)
917
918 {
919       
920    if(RxTxBD->RxBD.bd_cstatus & 0x8000) 
921    
922    {
923        return 0;  /*  character NOT available */
924    } 
925    
926    else
927    
928    {
929        return 1;  /*  character IS available */
930    }
931
932 } /* END SCC1Poll */
933
934 #ifndef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
935 void 
936 cyg_hal_plf_serial_putc(cyg_uint8 ch)
937 #else
938 static void
939 cyg_hal_plf_serial_putc(void* __ch_data, cyg_uint8 ch)
940 #endif
941 {
942    /*-----------------------------------*/
943    /* Loop until transmission completed */
944    /*-----------------------------------*/
945 #if 1
946   volatile CYG_WORD16 stat = 1;
947   while (stat){
948     stat = RxTxBD->TxBD.bd_cstatus  &  0x8000;
949   }
950 #else
951    while (RxTxBD->TxBD.bd_cstatus  &  0x8000);    
952 #endif
953    /*------------*/ 
954    /* Store data */
955    /*------------*/
956
957    *(RxTxBD->TxBD.bd_addr) = ch;                  
958    RxTxBD->TxBD.bd_length = 1;
959
960    /*---------------*/
961    /* Set Ready bit */
962    /*---------------*/
963
964    RxTxBD->TxBD.bd_cstatus |= 0x8000;              
965
966 }
967
968
969 static cyg_bool
970 cyg_hal_plf_serial_getc_nonblock(void* __ch_data, cyg_uint8* ch)
971 {
972   cyg_bool retval;
973
974   if ( (retval = SCC1Poll() ) ){   /* Check BD status for Rx characters */
975     *ch = cyg_hal_plf_serial_getc(__ch_data);
976   }
977
978   return retval;
979 }
980
981 #ifndef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
982 cyg_uint8
983 cyg_hal_plf_serial_getc(void)
984 #else
985 static cyg_uint8
986 cyg_hal_plf_serial_getc(void* __ch_data)
987 #endif
988 {
989     cyg_uint8 ch;
990     /*--------------------*/
991     /* Loop if RxBD empty */
992     /*--------------------*/
993 #if 1
994     volatile short stat = 1;
995     while (stat){
996         stat = RxTxBD->RxBD.bd_cstatus  &  0x8000;
997     }
998 #else
999     while (RxTxBD->RxBD.bd_cstatus  &  0x8000);      
1000 #endif
1001     /*--------------*/
1002     /* Receive data */
1003     /*--------------*/
1004     
1005     ch = *(RxTxBD->RxBD.bd_addr);   
1006    
1007     /*----------------------*/
1008     /* Set Buffer Empty bit */
1009     /*----------------------*/
1010     
1011     RxTxBD->RxBD.bd_cstatus |= 0x8000;   
1012
1013     return ch;
1014 }
1015
1016
1017
1018 static void
1019 cyg_hal_plf_serial_write(void* __ch_data, const cyg_uint8* __buf, 
1020                          cyg_uint32 __len)
1021 {
1022   //CYGARC_HAL_SAVE_GP();
1023
1024     while(__len-- > 0)
1025 #ifndef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
1026         cyg_hal_plf_serial_putc(*__buf++);
1027 #else
1028         cyg_hal_plf_serial_putc(__ch_data, *__buf++);
1029 #endif
1030
1031     //CYGARC_HAL_RESTORE_GP();
1032 }
1033
1034 static void
1035 cyg_hal_plf_serial_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len)
1036 {
1037     CYGARC_HAL_SAVE_GP();
1038
1039     while(__len-- > 0)
1040 #ifndef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
1041         *__buf++ = cyg_hal_plf_serial_getc();
1042 #else
1043         *__buf++ = cyg_hal_plf_serial_getc(__ch_data);
1044 #endif
1045     CYGARC_HAL_RESTORE_GP();
1046 }
1047
1048 cyg_int32 msec_timeout = 1000;
1049
1050 static cyg_bool
1051 cyg_hal_plf_serial_getc_timeout(void* __ch_data, cyg_uint8* ch)
1052 {
1053     int delay_count = msec_timeout * 10; // delay in .1 ms steps
1054     cyg_bool res;
1055     CYGARC_HAL_SAVE_GP();
1056
1057     for(;;) {
1058         res = cyg_hal_plf_serial_getc_nonblock(__ch_data, ch);
1059         if (res || 0 == delay_count--)
1060             break;
1061         
1062         CYGACC_CALL_IF_DELAY_US(100);
1063     }
1064
1065     CYGARC_HAL_RESTORE_GP();
1066     return res;
1067 }
1068
1069 static int
1070 cyg_hal_plf_serial_control(void *__ch_data, __comm_control_cmd_t __func, ...)
1071 {
1072     static int irq_state = 0;
1073     int ret = 0;
1074     cyg_uint32 regval;
1075     CYGARC_HAL_SAVE_GP();
1076
1077     switch (__func) {
1078     case __COMMCTL_IRQ_ENABLE:
1079         //HAL_INTERRUPT_UNMASK(CYGNUM_HAL_INTERRUPT_CPM_SMC1);
1080         // For now, don't bother calling a macro, just do it here
1081         // Bit 8 in the SIMR_L corresponds to SCC1
1082         HAL_READ_UINT32( ((char *) IMM) + 0x10000 + CYGARC_REG_IMM_SIMR_L, regval);
1083         regval |= 0x00800000;
1084
1085         HAL_WRITE_UINT32( ((char *) IMM) + 0x10000 + CYGARC_REG_IMM_SIMR_L, regval);
1086         asm volatile ("ori   %0, 0, 0x1234;"                     \
1087                       : /* No output */                   \
1088                       : "I" (22)); /* %0 ==> r2 */
1089
1090         //RxTxBD->RxBD.bd_cstatus = 0xB000;
1091         irq_state = 1;
1092         //RED_LED_ON;
1093         break;
1094     case __COMMCTL_IRQ_DISABLE:
1095         ret = irq_state;
1096         irq_state = 0;
1097         //HAL_INTERRUPT_MASK(CYGNUM_HAL_INTERRUPT_CPM_SMC1);
1098         HAL_READ_UINT32( ((char *) IMM) + 0x10000 + CYGARC_REG_IMM_SIMR_L, regval);
1099         regval &= 0xFF7FFFFF;
1100
1101         HAL_WRITE_UINT32( ((char *) IMM) + 0x10000 + CYGARC_REG_IMM_SIMR_L, regval);
1102         //RED_LED_OFF;
1103         //RxTxBD->RxBD.bd_cstatus = 0xA000;
1104         break;
1105     case __COMMCTL_DBG_ISR_VECTOR:
1106       //ret = CYGNUM_HAL_INTERRUPT_CPM_SMC1;
1107       ret = CYGNUM_HAL_INTERRUPT_SCC1;
1108
1109       //ret = 0x01;
1110         break;
1111     case __COMMCTL_SET_TIMEOUT:
1112     {
1113         va_list ap;
1114
1115         va_start(ap, __func);
1116
1117         ret = msec_timeout;
1118         msec_timeout = va_arg(ap, cyg_uint32);
1119
1120         va_end(ap);
1121     }        
1122     default:
1123         break;
1124     }
1125     CYGARC_HAL_RESTORE_GP();
1126     return ret;
1127 }
1128
1129 // EOF hal_aux.c