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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [hal/] [coldfire/] [mcf5272/] [current/] [src/] [hal_diag.c] - Blame information for rev 786

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
//==========================================================================
2
//
3
//      hal_diag.c
4
//
5
//      HAL diagnostic I/O support routines for the MCF5272
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, 2006 Free Software Foundation, 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      
16
// version.                                                                 
17
//
18
// eCos is distributed in the hope that it will be useful, but WITHOUT      
19
// ANY 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        
24
// along with eCos; if not, write to the Free Software Foundation, Inc.,    
25
// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.            
26
//
27
// As a special exception, if other files instantiate templates or use      
28
// macros or inline functions from this file, or you compile this file      
29
// and link it with other works to produce a work based on this file,       
30
// this file does not by itself cause the resulting work to be covered by   
31
// the GNU General Public License. However the source code for this file    
32
// must still be made available in accordance with section (3) of the GNU   
33
// General Public License v2.                                               
34
//
35
// This exception does not invalidate any other reasons why a work based    
36
// on this file might be covered by the GNU General Public License.         
37
// -------------------------------------------                              
38
// ####ECOSGPLCOPYRIGHTEND####                                              
39
//==========================================================================
40
//#####DESCRIPTIONBEGIN####
41
//
42
// Author(s):    Enrico Piria
43
// Contributors:
44
// Date:         2005-25-06
45
// Purpose:      Code to manage the serial ports for diagnostic output.
46
// Description:
47
//
48
//####DESCRIPTIONEND####
49
//==========================================================================
50
 
51
 
52
#include <pkgconf/hal.h>
53
#include <cyg/infra/cyg_type.h>
54
#include <cyg/hal/hal_intr.h>           // CYGNUM_HAL_INTERRUPT_UART1
55
#include <cyg/hal/hal_if.h>             // __comm_control_cmd_t
56
#include <cyg/hal/hal_io.h>             // HAL I/O macros
57
#include <cyg/hal/hal_misc.h>           // cyg_hal_is_break
58
#include <cyg/hal/drv_api.h>            // CYG_ISR_HANDLED
59
 
60
#include <cyg/hal/plf_serial.h>
61
 
62
 
63
typedef struct {
64
    CYG_ADDRWORD                base;           // [Pointer] to Port base address
65
    unsigned int                vector;         // UART interrupt vector
66
    CYG_WORD                    msec_timeout;   // Timeout in msec
67
} channel_data_t;
68
 
69
static channel_data_t ports[] = {
70
    {
71
        (CYG_ADDRWORD) (&((mcf5272_devs_t *) 0)->uart[0]),
72
        CYGNUM_HAL_INTERRUPT_UART1,
73
        1000
74
    },
75
 
76
    {
77
        (CYG_ADDRWORD) (&((mcf5272_devs_t *) 0)->uart[1]),
78
        CYGNUM_HAL_INTERRUPT_UART2,
79
        1000
80
    }
81
};
82
 
83
 
84
static cyg_uint8
85
cyg_hal_plf_serial_getc(void* __ch_data);
86
 
87
static void
88
cyg_hal_plf_serial_putc(void* __ch_data, cyg_uint8 ch);
89
 
90
static void
91
cyg_hal_plf_serial_init_channel(channel_data_t *port);
92
 
93
static cyg_bool
94
cyg_hal_plf_serial_getc_nonblock(void* __ch_data, cyg_uint8* ch);
95
 
96
static cyg_bool
97
cyg_hal_plf_serial_getc_timeout(void* __ch_data, cyg_uint8* ch);
98
 
99
static void
100
cyg_hal_plf_serial_write(void* __ch_data, const cyg_uint8* __buf,
101
                         cyg_uint32 __len);
102
static void
103
cyg_hal_plf_serial_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len);
104
 
105
static int
106
cyg_hal_plf_serial_isr(void *__ch_data, int* __ctrlc,
107
                       CYG_ADDRWORD __vector, CYG_ADDRWORD __data);
108
static int
109
cyg_hal_plf_serial_control(void *__ch_data, __comm_control_cmd_t __func, ...);
110
 
111
 
112
// ----------------------------------------------------------------------------
113
// Early initialization of comm. channels.
114
void
115
cyg_hal_plf_comms_init(void)
116
{
117
    hal_virtual_comm_table_t* comm;
118
    int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
119
    cyg_uint32 portcnt;
120
    static int initialized = 0;
121
 
122
    if (initialized)
123
        return;
124
    initialized = 1;
125
 
126
#if (defined(CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL) && \
127
        CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL == 0) || \
128
    (defined(CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL) && \
129
        CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL == 0)
130
 
131
    // UART0 pins are multplexed with GPIO port B. Enable them in
132
    // port B control register.
133
    HAL_READ_UINT32(&MCF5272_DEVS->gpio.pbcnt, portcnt);
134
    HAL_WRITE_UINT32(&MCF5272_DEVS->gpio.pbcnt, ((portcnt &
135
        ~(MCF5272_GPIO_PBCNT_URT0_MSK)) |
136
        (MCF5272_GPIO_PBCNT_URT0_EN)));
137
 
138
    // Init channel 0
139
    cyg_hal_plf_serial_init_channel(&ports[0]);
140
 
141
    // Setup procs in the vector table for channel 0
142
    CYGACC_CALL_IF_SET_CONSOLE_COMM(0);
143
    comm = CYGACC_CALL_IF_CONSOLE_PROCS();
144
    CYGACC_COMM_IF_CH_DATA_SET(*comm, &ports[0]);
145
    CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write);
146
    CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read);
147
    CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc);
148
    CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc);
149
    CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control);
150
    CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr);
151
    CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout);
152
#endif
153
 
154
#if (defined(CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL) && \
155
        CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL == 1) || \
156
    (defined(CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL) && \
157
        CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL == 1)
158
 
159
    // UART1 pins need to be enabled in port D control register.
160
    HAL_READ_UINT32(&MCF5272_DEVS->gpio.pdcnt, portcnt);
161
    HAL_WRITE_UINT32(&MCF5272_DEVS->gpio.pdcnt, ((portcnt &
162
        ~(MCF5272_GPIO_PDCNT_URT1_MSK)) |
163
        (MCF5272_GPIO_PDCNT_URT1_EN)));
164
 
165
    // Init channel 1
166
    cyg_hal_plf_serial_init_channel(&ports[1]);
167
 
168
    // Setup procs in the vector table for channel 0
169
    CYGACC_CALL_IF_SET_CONSOLE_COMM(1);
170
    comm = CYGACC_CALL_IF_CONSOLE_PROCS();
171
    CYGACC_COMM_IF_CH_DATA_SET(*comm, &ports[1]);
172
    CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write);
173
    CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read);
174
    CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc);
175
    CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc);
176
    CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control);
177
    CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_serial_isr);
178
    CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout);
179
#endif
180
 
181
    // Restore original console
182
    CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
183
}
184
 
185
 
186
void cyg_hal_plf_serial_init_channel(channel_data_t *port)
187
{
188
    CYG_WORD16 clk_div;
189
    volatile mcf5272_uart_t *base =
190
        (volatile mcf5272_uart_t *)((char *)MCF5272_DEVS + port->base);
191
    // Initialize variable to prevent compiler warnings
192
    unsigned int baud_rate = 1200;
193
 
194
 
195
#ifdef CYGPRI_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL_CONFIGURABLE    
196
    if( (port-&ports[0]) == CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL )
197
        baud_rate = CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL_BAUD;
198
#endif    
199
#ifdef CYGPRI_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_CONFIGURABLE
200
    if( (port-&ports[0]) == CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL )
201
        baud_rate = CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD;
202
#endif
203
 
204
    // Before we do anything else, make sure we have enabled RTS in case
205
    // the device we are using relies on hardware flow control.
206
    // Note that this step is our only attempt at hardware flow control.
207
    HAL_WRITE_UINT8(&base->uop1, MCF5272_UART_UOP1_RTS);
208
 
209
    // Initialize UART
210
 
211
    // Reset Transmitter
212
    HAL_WRITE_UINT8(&base->ucr, MCF5272_UART_UCR_RTX);
213
 
214
    // Reset Receiver
215
    HAL_WRITE_UINT8(&base->ucr, MCF5272_UART_UCR_RRX);
216
 
217
    // Reset Mode Register
218
    HAL_WRITE_UINT8(&base->ucr, MCF5272_UART_UCR_RMR);
219
 
220
    HAL_WRITE_UINT8(&base->ucr, MCF5272_UART_UCR_RES);
221
    HAL_WRITE_UINT8(&base->ucr, MCF5272_UART_UCR_RBC);
222
 
223
    // Mode register 1 sets the UART to  8 data bits with no parity, and
224
    // mode register 2 forces 1 stop  bit. Also, interrupt generation
225
    // on RxRDY signal is enabled by default.
226
    // Reading or write to the mode register switches it from umr1 to umr2.
227
    // To set it to umr1, we must write a reset mode register command to the
228
    // command register.
229
    HAL_WRITE_UINT8(&base->umr, MCF5272_UART_UMR_8BNP);
230
    HAL_WRITE_UINT8(&base->umr, MCF5272_UART_UMR_1S);
231
 
232
    // Select a prescaled (by 1/16) CLKIN for the clock source
233
    HAL_WRITE_UINT8(&base->usr_ucsr, MCF5272_UART_UCSR_CLKIN);
234
 
235
    // Calculate baud settings
236
    clk_div = (CYG_WORD16)
237
              ((CYGHWR_HAL_SYSTEM_CLOCK_MHZ*1000000)/
238
               (baud_rate * 32));
239
    HAL_WRITE_UINT8(&base->udu, clk_div >> 8);
240
    HAL_WRITE_UINT8(&base->udl, clk_div & 0x00ff);
241
 
242
    // Enable the transmitter and receiver
243
    HAL_WRITE_UINT8(&base->ucr, MCF5272_UART_UCR_TXRXEN);
244
 
245
    // Set interrupt priority to highest maskable level
246
    HAL_INTERRUPT_SET_LEVEL(port->vector, 6);
247
}
248
 
249
 
250
cyg_uint8 cyg_hal_plf_serial_getc(void* __ch_data)
251
{
252
    cyg_uint8 ch;
253
 
254
 
255
    while(!cyg_hal_plf_serial_getc_nonblock(__ch_data, &ch));
256
 
257
    return ch;
258
}
259
 
260
 
261
void cyg_hal_plf_serial_putc(void *__ch_data, cyg_uint8 ch)
262
{
263
    channel_data_t *port = (channel_data_t *) __ch_data;
264
    volatile mcf5272_uart_t *base =
265
        (volatile mcf5272_uart_t *)((char *)MCF5272_DEVS + port->base);
266
    cyg_uint8 usr_ucsr, utf;
267
 
268
 
269
    // Loop until the transmit data holding register is empty
270
    do
271
    {
272
        HAL_READ_UINT8(&base->usr_ucsr, usr_ucsr);
273
    } while (!(usr_ucsr & MCF5272_UART_USR_TXRDY));
274
 
275
    // Write the character to the transmit buffer
276
    HAL_WRITE_UINT8(&base->urb_utb, ch);
277
 
278
    // Loop until the transmit data FIFO and the shift register are empty
279
    do
280
    {
281
        HAL_READ_UINT8(&base->utf, utf);
282
        HAL_READ_UINT8(&base->usr_ucsr, usr_ucsr);
283
    } while ((utf & MCF5272_UART_UTF_TXB) ||
284
        (!(usr_ucsr & MCF5272_UART_USR_TXEMP)));
285
}
286
 
287
static void cyg_hal_plf_serial_write(void* __ch_data, const cyg_uint8* __buf,
288
                                     cyg_uint32 __len)
289
{
290
    while(__len-- > 0)
291
        cyg_hal_plf_serial_putc(__ch_data, *__buf++);
292
}
293
 
294
 
295
static void cyg_hal_plf_serial_read(void* __ch_data, cyg_uint8* __buf,
296
                                    cyg_uint32 __len)
297
{
298
    while(__len-- > 0)
299
        *__buf++ = cyg_hal_plf_serial_getc(__ch_data);
300
}
301
 
302
 
303
static cyg_bool cyg_hal_plf_serial_getc_nonblock(void* __ch_data, cyg_uint8* ch)
304
{
305
    channel_data_t *port = (channel_data_t *) __ch_data;
306
    volatile mcf5272_uart_t *base =
307
        (volatile mcf5272_uart_t *)((char *)MCF5272_DEVS + port->base);
308
    cyg_uint8 usr_ucsr;
309
 
310
 
311
    // Read status
312
    HAL_READ_UINT8(&base->usr_ucsr, usr_ucsr);
313
 
314
    // Check if a character is present
315
    if (usr_ucsr & MCF5272_UART_USR_RRDY)
316
    {
317
        // Read character
318
        HAL_READ_UINT8(&base->urb_utb, *ch);
319
        return true;
320
    }
321
 
322
    return false;
323
}
324
 
325
 
326
static cyg_bool cyg_hal_plf_serial_getc_timeout(void* __ch_data, cyg_uint8* ch)
327
{
328
    int delay_count;
329
    cyg_bool res;
330
 
331
 
332
    delay_count = ((channel_data_t *)__ch_data)->msec_timeout;
333
 
334
    for(;;) {
335
        res = cyg_hal_plf_serial_getc_nonblock(__ch_data, ch);
336
        if (res || 0 == delay_count--)
337
            break;
338
 
339
        CYGACC_CALL_IF_DELAY_US(100);
340
    }
341
 
342
    return res;
343
}
344
 
345
 
346
static int cyg_hal_plf_serial_control(void *__ch_data,
347
                                      __comm_control_cmd_t __func, ...)
348
{
349
    static int irq_state = 0;
350
    channel_data_t *port = (channel_data_t *) __ch_data;
351
    volatile mcf5272_uart_t *base =
352
        (volatile mcf5272_uart_t *)((char *)MCF5272_DEVS + port->base);
353
    int ret = 0;
354
 
355
 
356
    switch (__func) {
357
    case __COMMCTL_IRQ_ENABLE:
358
        irq_state = 1;
359
 
360
        HAL_WRITE_UINT8(&base->uisr_uimr, MCF5272_UART_UIMR_FFULL);
361
        HAL_INTERRUPT_UNMASK(port->vector);
362
        break;
363
    case __COMMCTL_IRQ_DISABLE:
364
        ret = irq_state;
365
        irq_state = 0;
366
 
367
        HAL_INTERRUPT_MASK(port->vector);
368
        HAL_WRITE_UINT8(&base->uisr_uimr, 0);
369
        break;
370
    case __COMMCTL_DBG_ISR_VECTOR:
371
        ret = port->vector;
372
        break;
373
    case __COMMCTL_SET_TIMEOUT:
374
    {
375
        va_list ap;
376
 
377
        va_start(ap, __func);
378
 
379
        ret = port->msec_timeout;
380
        port->msec_timeout = va_arg(ap, cyg_uint32);
381
 
382
        va_end(ap);
383
    }
384
    default:
385
        break;
386
    }
387
 
388
    return ret;
389
}
390
 
391
 
392
static int cyg_hal_plf_serial_isr(void *__ch_data, int* __ctrlc,
393
                                  CYG_ADDRWORD __vector, CYG_ADDRWORD __data)
394
{
395
    channel_data_t *port = (channel_data_t *) __ch_data;
396
    volatile mcf5272_uart_t *base =
397
        (volatile mcf5272_uart_t *)((char *)MCF5272_DEVS + port->base);
398
    char c;
399
 
400
 
401
    // Disable the interrupt temporarily
402
    HAL_WRITE_UINT8(&base->uisr_uimr, 0);
403
 
404
    *__ctrlc = 0;
405
 
406
    // Read character
407
    HAL_READ_UINT8(&base->urb_utb, c);
408
    if( cyg_hal_is_break( &c , 1 ) )
409
    {
410
        *__ctrlc = 1;
411
    }
412
 
413
    // Re-enable RxRDY interrupt
414
    HAL_WRITE_UINT8(&base->uisr_uimr, MCF5272_UART_UIMR_FFULL);
415
 
416
    return CYG_ISR_HANDLED;
417
}

powered by: WebSVN 2.1.0

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