OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [hal/] [arm/] [cma230/] [v2_0/] [src/] [hal_diag.c] - Blame information for rev 429

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 unneback
/*=============================================================================
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
// 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####
42
//
43
// Author(s):   nickg, gthomas
44
// Contributors:        nickg, gthomas
45
// Date:        1998-03-02
46
// Purpose:     HAL diagnostic output
47
// Description: Implementations of HAL diagnostic output support.
48
//
49
//####DESCRIPTIONEND####
50
//
51
//===========================================================================*/
52
 
53
#include <pkgconf/hal.h>
54
#include <pkgconf/hal_arm_cma230.h>        // board specifics
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>           // 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_diag.h>
64
#include <cyg/hal/hal_cma230.h>         // Hardware definitions
65
#include <cyg/hal/hal_if.h>             // Calling-if API
66
#include <cyg/hal/drv_api.h>            // driver API
67
#include <cyg/hal/hal_misc.h>           // Helper functions
68
 
69
static void cyg_hal_plf_serial_init(void);
70
 
71
// FIXME: Copy LCD driver from powerpc/cogent
72
//static void cyg_hal_plf_lcd_init(void);
73
 
74
void
75
cyg_hal_plf_comms_init(void)
76
{
77
    static int initialized = 0;
78
 
79
    if (initialized)
80
        return;
81
 
82
    initialized = 1;
83
 
84
    cyg_hal_plf_serial_init();
85
//    cyg_hal_plf_lcd_init();
86
}
87
 
88
//=============================================================================
89
// Serial driver
90
//=============================================================================
91
 
92
//-----------------------------------------------------------------------------
93
// There are two serial ports.
94
#define CYG_DEV_SERIAL_BASE_A    0xe900047 // port A
95
#define CYG_DEV_SERIAL_BASE_B    0xe900007 // port B
96
 
97
//-----------------------------------------------------------------------------
98
// Default baud rate is 38400
99
// Based on 3.6864 MHz xtal
100
#if CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD==9600
101
#define CYG_DEV_SERIAL_BAUD_MSB        0x00
102
#define CYG_DEV_SERIAL_BAUD_LSB        0x18
103
#endif
104
#if CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD==19200
105
#define CYG_DEV_SERIAL_BAUD_MSB        0x00
106
#define CYG_DEV_SERIAL_BAUD_LSB        0x0C
107
#endif
108
#if CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD==38400
109
#define CYG_DEV_SERIAL_BAUD_MSB        0x00
110
#define CYG_DEV_SERIAL_BAUD_LSB        0x06
111
#endif
112
#if CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD==115200
113
#define CYG_DEV_SERIAL_BAUD_MSB        0x00
114
#define CYG_DEV_SERIAL_BAUD_LSB        0x02
115
#endif
116
 
117
#ifndef CYG_DEV_SERIAL_BAUD_MSB
118
#error Missing/incorrect serial baud rate defined - CDL error?
119
#endif
120
 
121
//-----------------------------------------------------------------------------
122
// Define the serial registers. The Cogent board is equipped with a 16552
123
// serial chip.
124
#define CYG_DEV_SERIAL_RBR   0x00  // receiver buffer register, read, dlab = 0
125
#define CYG_DEV_SERIAL_THR   0x00 // transmitter holding register, write, dlab = 0
126
#define CYG_DEV_SERIAL_DLL   0x00 // divisor latch (LS), read/write, dlab = 1
127
#define CYG_DEV_SERIAL_IER   0x08 // interrupt enable register, read/write, dlab = 0
128
#define CYG_DEV_SERIAL_DLM   0x08 // divisor latch (MS), read/write, dlab = 1
129
#define CYG_DEV_SERIAL_IIR   0x10 // interrupt identification register, read, dlab = 0
130
#define CYG_DEV_SERIAL_FCR   0x10 // fifo control register, write, dlab = 0
131
#define CYG_DEV_SERIAL_AFR   0x10 // alternate function register, read/write, dlab = 1
132
#define CYG_DEV_SERIAL_LCR   0x18 // line control register, read/write
133
#define CYG_DEV_SERIAL_MCR   0x20
134
#define CYG_DEV_SERIAL_MCR_A 0x20
135
#define CYG_DEV_SERIAL_MCR_B 0x20
136
#define CYG_DEV_SERIAL_LSR   0x28 // line status register, read
137
#define CYG_DEV_SERIAL_MSR   0x30 // modem status register, read
138
#define CYG_DEV_SERIAL_SCR   0x38 // scratch pad register
139
 
140
// The interrupt enable register bits.
141
#define SIO_IER_ERDAI   0x01            // enable received data available irq
142
#define SIO_IER_ETHREI  0x02            // enable THR empty interrupt
143
#define SIO_IER_ELSI    0x04            // enable receiver line status irq
144
#define SIO_IER_EMSI    0x08            // enable modem status interrupt
145
 
146
// The interrupt identification register bits.
147
#define SIO_IIR_IP      0x01            // 0 if interrupt pending
148
#define SIO_IIR_ID_MASK 0x0e            // mask for interrupt ID bits
149
#define ISR_Tx  0x02
150
#define ISR_Rx  0x04
151
 
152
// The line status register bits.
153
#define SIO_LSR_DR      0x01            // data ready
154
#define SIO_LSR_OE      0x02            // overrun error
155
#define SIO_LSR_PE      0x04            // parity error
156
#define SIO_LSR_FE      0x08            // framing error
157
#define SIO_LSR_BI      0x10            // break interrupt
158
#define SIO_LSR_THRE    0x20            // transmitter holding register empty
159
#define SIO_LSR_TEMT    0x40            // transmitter register empty
160
#define SIO_LSR_ERR     0x80            // any error condition
161
 
162
// The modem status register bits.
163
#define SIO_MSR_DCTS  0x01              // delta clear to send
164
#define SIO_MSR_DDSR  0x02              // delta data set ready
165
#define SIO_MSR_TERI  0x04              // trailing edge ring indicator
166
#define SIO_MSR_DDCD  0x08              // delta data carrier detect
167
#define SIO_MSR_CTS   0x10              // clear to send
168
#define SIO_MSR_DSR   0x20              // data set ready
169
#define SIO_MSR_RI    0x40              // ring indicator
170
#define SIO_MSR_DCD   0x80              // data carrier detect
171
 
172
// The line control register bits.
173
#define SIO_LCR_WLS0   0x01             // word length select bit 0
174
#define SIO_LCR_WLS1   0x02             // word length select bit 1
175
#define SIO_LCR_STB    0x04             // number of stop bits
176
#define SIO_LCR_PEN    0x08             // parity enable
177
#define SIO_LCR_EPS    0x10             // even parity select
178
#define SIO_LCR_SP     0x20             // stick parity
179
#define SIO_LCR_SB     0x40             // set break
180
#define SIO_LCR_DLAB   0x80             // divisor latch access bit
181
 
182
// The FIFO control register
183
#define SIO_FCR_FCR0   0x01             // enable xmit and rcvr fifos
184
#define SIO_FCR_FCR1   0x02             // clear RCVR FIFO
185
#define SIO_FCR_FCR2   0x04             // clear XMIT FIFO
186
 
187
 
188
//-----------------------------------------------------------------------------
189
typedef struct {
190
    cyg_uint8* base;
191
    cyg_int32 msec_timeout;
192
    int isr_vector;
193
} channel_data_t;
194
 
195
//-----------------------------------------------------------------------------
196
static void
197
init_serial_channel(channel_data_t* __ch_data)
198
{
199
    cyg_uint8* base = __ch_data->base;
200
    cyg_uint8 lcr;
201
 
202
    // 8-1-no parity.
203
    HAL_WRITE_UINT8(base+CYG_DEV_SERIAL_LCR,
204
                     SIO_LCR_WLS0 | SIO_LCR_WLS1);
205
 
206
    HAL_READ_UINT8(base+CYG_DEV_SERIAL_LCR, lcr);
207
    lcr |= SIO_LCR_DLAB;
208
    HAL_WRITE_UINT8(base+CYG_DEV_SERIAL_LCR, lcr);
209
    HAL_WRITE_UINT8(base+CYG_DEV_SERIAL_DLL, CYG_DEV_SERIAL_BAUD_LSB);
210
    HAL_WRITE_UINT8(base+CYG_DEV_SERIAL_DLM, CYG_DEV_SERIAL_BAUD_MSB);
211
    lcr &= ~SIO_LCR_DLAB;
212
    HAL_WRITE_UINT8(base+CYG_DEV_SERIAL_LCR, lcr);
213
    HAL_WRITE_UINT8(base+CYG_DEV_SERIAL_FCR, 0x07);  // Enable & clear FIFO
214
}
215
 
216
static cyg_bool
217
cyg_hal_plf_serial_getc_nonblock(void* __ch_data, cyg_uint8* ch)
218
{
219
    cyg_uint8* base = ((channel_data_t*)__ch_data)->base;
220
    cyg_uint8 lsr;
221
 
222
    HAL_READ_UINT8(base+CYG_DEV_SERIAL_LSR, lsr);
223
    if ((lsr & SIO_LSR_DR) == 0)
224
        return false;
225
 
226
    HAL_READ_UINT8(base+CYG_DEV_SERIAL_RBR, *ch);
227
 
228
    return true;
229
}
230
 
231
 
232
cyg_uint8
233
cyg_hal_plf_serial_getc(void* __ch_data)
234
{
235
    cyg_uint8 ch;
236
    CYGARC_HAL_SAVE_GP();
237
 
238
    while(!cyg_hal_plf_serial_getc_nonblock(__ch_data, &ch));
239
 
240
    CYGARC_HAL_RESTORE_GP();
241
    return ch;
242
}
243
 
244
void
245
cyg_hal_plf_serial_putc(void* __ch_data, cyg_uint8 c)
246
{
247
    cyg_uint8* base = ((channel_data_t*)__ch_data)->base;
248
    cyg_uint8 lsr;
249
    CYGARC_HAL_SAVE_GP();
250
 
251
    do {
252
        HAL_READ_UINT8(base+CYG_DEV_SERIAL_LSR, lsr);
253
    } while ((lsr & SIO_LSR_THRE) == 0);
254
 
255
    HAL_WRITE_UINT8(base+CYG_DEV_SERIAL_THR, c);
256
 
257
    // Hang around until the character has been safely sent.
258
    do {
259
        HAL_READ_UINT8(base+CYG_DEV_SERIAL_LSR, lsr);
260
    } while ((lsr & SIO_LSR_THRE) == 0);
261
 
262
    CYGARC_HAL_RESTORE_GP();
263
}
264
 
265
static channel_data_t channels[2] = {
266
    { (cyg_uint8*)CMA101_DUARTA, 1000, CYGNUM_HAL_INTERRUPT_SERIAL_A},
267
    { (cyg_uint8*)CMA101_DUARTB, 1000, CYGNUM_HAL_INTERRUPT_SERIAL_B}
268
};
269
 
270
static void
271
cyg_hal_plf_serial_write(void* __ch_data, const cyg_uint8* __buf,
272
                         cyg_uint32 __len)
273
{
274
    CYGARC_HAL_SAVE_GP();
275
 
276
    while(__len-- > 0)
277
        cyg_hal_plf_serial_putc(__ch_data, *__buf++);
278
 
279
    CYGARC_HAL_RESTORE_GP();
280
}
281
 
282
static void
283
cyg_hal_plf_serial_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len)
284
{
285
    CYGARC_HAL_SAVE_GP();
286
 
287
    while(__len-- > 0)
288
        *__buf++ = cyg_hal_plf_serial_getc(__ch_data);
289
 
290
    CYGARC_HAL_RESTORE_GP();
291
}
292
 
293
cyg_bool
294
cyg_hal_plf_serial_getc_timeout(void* __ch_data, cyg_uint8* ch)
295
{
296
    int delay_count;
297
    channel_data_t* chan = (channel_data_t*)__ch_data;
298
    cyg_bool res;
299
    CYGARC_HAL_SAVE_GP();
300
 
301
    delay_count = chan->msec_timeout * 10; // delay in .1 ms steps
302
    for(;;) {
303
        res = cyg_hal_plf_serial_getc_nonblock(__ch_data, ch);
304
        if (res || 0 == delay_count--)
305
            break;
306
 
307
        CYGACC_CALL_IF_DELAY_US(100);
308
    }
309
 
310
    CYGARC_HAL_RESTORE_GP();
311
    return res;
312
}
313
 
314
static int
315
cyg_hal_plf_serial_control(void *__ch_data, __comm_control_cmd_t __func, ...)
316
{
317
    static int irq_state = 0;
318
    channel_data_t* chan = (channel_data_t*)__ch_data;
319
    cyg_uint8 ier;
320
    int ret = 0;
321
    CYGARC_HAL_SAVE_GP();
322
 
323
    switch (__func) {
324
    case __COMMCTL_IRQ_ENABLE:
325
        HAL_INTERRUPT_UNMASK(chan->isr_vector);
326
        HAL_INTERRUPT_SET_LEVEL(chan->isr_vector, 1);
327
        HAL_READ_UINT8(chan->base+CYG_DEV_SERIAL_IER, ier);
328
        ier |= SIO_IER_ERDAI;
329
        HAL_WRITE_UINT8(chan->base+CYG_DEV_SERIAL_IER, ier);
330
        irq_state = 1;
331
        break;
332
    case __COMMCTL_IRQ_DISABLE:
333
        ret = irq_state;
334
        irq_state = 0;
335
        HAL_INTERRUPT_MASK(chan->isr_vector);
336
        HAL_READ_UINT8(chan->base+CYG_DEV_SERIAL_IER, ier);
337
        ier &= ~SIO_IER_ERDAI;
338
        HAL_WRITE_UINT8(chan->base+CYG_DEV_SERIAL_IER, ier);
339
        break;
340
    case __COMMCTL_DBG_ISR_VECTOR:
341
        ret = chan->isr_vector;
342
        break;
343
    case __COMMCTL_SET_TIMEOUT:
344
    {
345
        va_list ap;
346
 
347
        va_start(ap, __func);
348
 
349
        ret = chan->msec_timeout;
350
        chan->msec_timeout = va_arg(ap, cyg_uint32);
351
 
352
        va_end(ap);
353
    }
354
    default:
355
        break;
356
    }
357
    CYGARC_HAL_RESTORE_GP();
358
    return ret;
359
}
360
 
361
static int
362
cyg_hal_plf_serial_isr(void *__ch_data, int* __ctrlc,
363
                       CYG_ADDRWORD __vector, CYG_ADDRWORD __data)
364
{
365
    channel_data_t* chan = (channel_data_t*)__ch_data;
366
    cyg_uint8 _iir;
367
    int res = 0;
368
    CYGARC_HAL_SAVE_GP();
369
 
370
    HAL_READ_UINT8(chan->base+CYG_DEV_SERIAL_IIR, _iir);
371
    _iir &= SIO_IIR_ID_MASK;
372
 
373
    *__ctrlc = 0;
374
    if ( ISR_Rx == _iir ) {
375
        cyg_uint8 c, lsr;
376
        HAL_READ_UINT8(chan->base+CYG_DEV_SERIAL_LSR, lsr);
377
        if (lsr & SIO_LSR_DR) {
378
 
379
            HAL_READ_UINT8(chan->base+CYG_DEV_SERIAL_RBR, c);
380
 
381
            if( cyg_hal_is_break( &c , 1 ) )
382
                *__ctrlc = 1;
383
        }
384
 
385
        // Acknowledge the interrupt
386
        HAL_INTERRUPT_ACKNOWLEDGE(chan->isr_vector);
387
        res = CYG_ISR_HANDLED;
388
    }
389
 
390
    CYGARC_HAL_RESTORE_GP();
391
    return res;
392
}
393
 
394
static void
395
cyg_hal_plf_serial_init(void)
396
{
397
    hal_virtual_comm_table_t* comm;
398
    int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
399
 
400
    // Disable interrupts.
401
    HAL_INTERRUPT_MASK(channels[0].isr_vector);
402
    HAL_INTERRUPT_MASK(channels[1].isr_vector);
403
 
404
    // Init channels
405
    init_serial_channel(&channels[0]);
406
    init_serial_channel(&channels[1]);
407
 
408
    // Setup procs in the vector table
409
 
410
    // Set channel 0
411
    CYGACC_CALL_IF_SET_CONSOLE_COMM(0);
412
    comm = CYGACC_CALL_IF_CONSOLE_PROCS();
413
    CYGACC_COMM_IF_CH_DATA_SET(*comm, &channels[0]);
414
    CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write);
415
    CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read);
416
    CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc);
417
    CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc);
418
    CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control);
419
    CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr);
420
    CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout);
421
 
422
    // Set channel 1
423
    CYGACC_CALL_IF_SET_CONSOLE_COMM(1);
424
    comm = CYGACC_CALL_IF_CONSOLE_PROCS();
425
    CYGACC_COMM_IF_CH_DATA_SET(*comm, &channels[1]);
426
    CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write);
427
    CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read);
428
    CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc);
429
    CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc);
430
    CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control);
431
    CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr);
432
    CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout);
433
 
434
    // Restore original console
435
    CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
436
}
437
 
438
//=============================================================================
439
// Compatibility with older stubs
440
//=============================================================================
441
 
442
#ifndef CYGSEM_HAL_VIRTUAL_VECTOR_DIAG
443
 
444
 
445
#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
446
#include <cyg/hal/drv_api.h>
447
#include <cyg/hal/hal_stub.h>           // cyg_hal_gdb_interrupt
448
#endif
449
 
450
// Assumption: all diagnostic output must be GDB packetized unless this is a ROM (i.e.
451
// totally stand-alone) system.
452
 
453
#if defined(CYG_HAL_STARTUP_ROM) || !defined(CYGDBG_HAL_DIAG_TO_DEBUG_CHAN)
454
#define HAL_DIAG_USES_HARDWARE
455
#endif
456
 
457
/*---------------------------------------------------------------------------*/
458
#if CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL==0
459
// This is the base address of the A-channel
460
#define CYG_DEV_SERIAL_BASE      CMA101_DUARTA
461
#define CYG_DEV_SERIAL_INT       CYGNUM_HAL_INTERRUPT_SERIAL_A
462
#else
463
// This is the base address of the B-channel
464
#define CYG_DEV_SERIAL_BASE      CMA101_DUARTB
465
#define CYG_DEV_SERIAL_INT       CYGNUM_HAL_INTERRUPT_SERIAL_B
466
#endif
467
 
468
static channel_data_t ser_channel = { (cyg_uint8*)CYG_DEV_SERIAL_BASE, 0, 0};
469
 
470
#ifdef HAL_DIAG_USES_HARDWARE
471
 
472
void hal_diag_init(void)
473
{
474
    static int init = 0;
475
    char *msg = "\n\rARM eCos\n\r";
476
    cyg_uint8 lcr;
477
 
478
    if (init++) return;
479
 
480
    init_serial_channel(&ser_channel);
481
 
482
    while (*msg) hal_diag_write_char(*msg++);
483
}
484
 
485
#ifdef DEBUG_DIAG
486
#if defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS)
487
#define DIAG_BUFSIZE 32
488
#else
489
#define DIAG_BUFSIZE 2048
490
#endif
491
static char diag_buffer[DIAG_BUFSIZE];
492
static int diag_bp = 0;
493
#endif
494
 
495
void hal_diag_write_char(char c)
496
{
497
    cyg_uint8 lsr;
498
 
499
    hal_diag_init();
500
 
501
    cyg_hal_plf_serial_putc(&ser_channel, c)
502
 
503
#ifdef DEBUG_DIAG
504
    diag_buffer[diag_bp++] = c;
505
    if (diag_bp == DIAG_BUFSIZE) {
506
        while (1) ;
507
        diag_bp = 0;
508
    }
509
#endif
510
}
511
 
512
void hal_diag_read_char(char *c)
513
{
514
    *c = cyg_hal_plf_serial_getc(&ser_channel);
515
}
516
 
517
#else // HAL_DIAG relies on GDB
518
 
519
// Initialize diag port - assume GDB channel is already set up
520
void hal_diag_init(void)
521
{
522
    if (0) init_serial_channel(&ser_channel); // avoid warning
523
}
524
 
525
// Actually send character down the wire
526
static void
527
hal_diag_write_char_serial(char c)
528
{
529
    cyg_hal_plf_serial_putc(&ser_channel, c);
530
}
531
 
532
static bool
533
hal_diag_read_serial(char *c)
534
{
535
    long timeout = 1000000000;  // A long time...
536
    while (!cyg_hal_plf_serial_getc_nonblock(&ser_channel, c))
537
        if (0 == --timeout) return false;
538
 
539
    return true;
540
}
541
 
542
void
543
hal_diag_read_char(char *c)
544
{
545
    while (!hal_diag_read_serial(c)) ;
546
}
547
 
548
void
549
hal_diag_write_char(char c)
550
{
551
    static char line[100];
552
    static int pos = 0;
553
 
554
    // No need to send CRs
555
    if( c == '\r' ) return;
556
 
557
    line[pos++] = c;
558
 
559
    if( c == '\n' || pos == sizeof(line) )
560
    {
561
        CYG_INTERRUPT_STATE old;
562
 
563
        // Disable interrupts. This prevents GDB trying to interrupt us
564
        // while we are in the middle of sending a packet. The serial
565
        // receive interrupt will be seen when we re-enable interrupts
566
        // later.
567
 
568
#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
569
        CYG_HAL_GDB_ENTER_CRITICAL_IO_REGION(old);
570
#else
571
        HAL_DISABLE_INTERRUPTS(old);
572
#endif
573
 
574
        while(1)
575
        {
576
            static char hex[] = "0123456789ABCDEF";
577
            cyg_uint8 csum = 0;
578
            int i;
579
            char c1;
580
 
581
            hal_diag_write_char_serial('$');
582
            hal_diag_write_char_serial('O');
583
            csum += 'O';
584
            for( i = 0; i < pos; i++ )
585
            {
586
                char ch = line[i];
587
                char h = hex[(ch>>4)&0xF];
588
                char l = hex[ch&0xF];
589
                hal_diag_write_char_serial(h);
590
                hal_diag_write_char_serial(l);
591
                csum += h;
592
                csum += l;
593
            }
594
            hal_diag_write_char_serial('#');
595
            hal_diag_write_char_serial(hex[(csum>>4)&0xF]);
596
            hal_diag_write_char_serial(hex[csum&0xF]);
597
 
598
            // Wait for the ACK character '+' from GDB here and handle
599
            // receiving a ^C instead.  This is the reason for this clause
600
            // being a loop.
601
            if (!hal_diag_read_serial(&c1))
602
                continue;   // No response - try sending packet again
603
 
604
            if( c1 == '+' )
605
                break;              // a good acknowledge
606
 
607
#ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
608
            cyg_drv_interrupt_acknowledge(CYG_DEV_SERIAL_INT);
609
            if( c1 == 3 ) {
610
                // Ctrl-C: breakpoint.
611
                cyg_hal_gdb_interrupt (__builtin_return_address(0));
612
                break;
613
            }
614
#endif
615
            // otherwise, loop round again
616
        }
617
 
618
        pos = 0;
619
 
620
        // And re-enable interrupts
621
#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
622
        CYG_HAL_GDB_LEAVE_CRITICAL_IO_REGION(old);
623
#else
624
        HAL_RESTORE_INTERRUPTS(old);
625
#endif
626
 
627
    }
628
}
629
#endif
630
 
631
#endif // CYGSEM_HAL_VIRTUAL_VECTOR_DIAG
632
 
633
/*---------------------------------------------------------------------------*/
634
/* End of hal_diag.c */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.