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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [hal/] [powerpc/] [fads/] [v2_0/] [src/] [quicc_smc2.c] - Blame information for rev 587

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

Line No. Rev Author Line
1 27 unneback
//=============================================================================
2
//####UNSUPPORTEDBEGIN####
3
//
4
// -------------------------------------------
5
// This source file has been contributed to eCos/Red Hat. It may have been
6
// changed slightly to provide an interface consistent with those of other 
7
// files.
8
//
9
// The functionality and contents of this file is supplied "AS IS"
10
// without any form of support and will not necessarily be kept up
11
// to date by Red Hat.
12
//
13
// The style of programming used in this file may not comply with the
14
// eCos programming guidelines. Please do not use as a base for other
15
// files.
16
//
17
// All inquiries about this file, or the functionality provided by it,
18
// should be directed to the 'ecos-discuss' mailing list (see
19
// http://sourceware.cygnus.com/ecos/intouch.html for details).
20
//
21
// Contributed by: Kevin Hester <khester@opticworks.com>
22
// Maintained by:  <Unmaintained>
23
// See also:
24
//   Motorola's "Example Software Initializing the SMC as a UART" package 
25
//   (smc2.zip) at:
26
//    http://www.mot.com/SPS/RISC/netcomm/tools/index.html#MPC860_table
27
// -------------------------------------------
28
//
29
//####UNSUPPORTEDEND####
30
//=============================================================================
31
/*-------------------------------------------------------------------------
32
* FILENAME:  smc2.c
33
*
34
* DESCRIPTION:
35
*
36
*   The code in this module provides echo capability on SMC2. It's
37
*   intent is to provide the beginnings of a debug port that is
38
*   mostly compiler independent. If an ASCII terminal is connected
39
*   at 9600,N,8,1 on Port 2 (PB3) on the ADS board with no hardware
40
*   control, characters typed on the keyboard will be received by
41
*   SMC2 and echoed back out the RS232 port to the ASCII terminal.
42
*   This function was designed and tested on an ADS860
43
*   development board. Note that if a different baud rate is
44
*   required, there is a header file on the netcomm website under
45
*   the General Software category that is labelled "Asynchronous
46
*   Baud Rate Tables".
47
*
48
* REFERENCES:
49
*
50
*   1) MPC860 Users Manual
51
*   2) PowerPC Microprocessor Family: The Programming Environments for
52
*      32-Bit Microprocessors
53
*
54
* HISTORY:
55
*
56
* 27 APR 98  jay    initial release
57
*
58
*-------------------------------------------------------------------------*/
59
 
60
#include <cyg/hal/quicc_smc2.h>
61
#include "ppc_860.h"
62
 
63
/***********************/
64
/* Global Declarations */
65
/***********************/
66
 
67
static EPPC  *IMMR;      /* IMMR base pointer */
68
static BDRINGS *RxTxBD;  /* buffer descriptors base pointer */
69
static LB *SMC2Buffers;  /* SMC2 base pointers */
70
 
71
/*---------------------*/
72
/* Function Prototypes */
73
/*---------------------*/
74
 
75
//static char  SMC2Poll(void);
76
static void  InitBDs(void);
77
//static void  EchoChar(void);
78
static unsigned long GetIMMR(void);
79
 
80
 
81
/*-----------------------------------------------------------------------------
82
*
83
* FUNCTION NAME:  cyg_smc2_init
84
*
85
* DESCRIPTION:
86
*
87
* EXTERNAL EFFECT:
88
*
89
* PARAMETERS:  None
90
*
91
* RETURNS: None
92
*
93
*---------------------------------------------------------------------------*/
94
 
95
void cyg_smc2_init(unsigned long baudRate)
96
 
97
{
98
   unsigned long *bcsr1;
99
   unsigned long clockRate = 20 * 1000 * 1000;  // 20Mhz
100
   unsigned long divider = clockRate / (baudRate * 16) - 1;
101
 
102
   /*------------------------*/
103
   /* Establish IMMR pointer */
104
   /*------------------------*/
105
 
106
   IMMR = (EPPC *)(GetIMMR() & 0xFFFF0000);  /* MPC8xx internal register
107
                                                map  */
108
 
109
   /*-----------------------------------------------*/
110
   /* Enable RS232 interface on ADS board via BCSR1 */
111
   /* Get the base address of BCSR                  */
112
   /*-----------------------------------------------*/
113
 
114
   bcsr1 = (unsigned long *) ((IMMR->memc_br1 & 0xffff0000) + 4);
115
   *bcsr1 &= ~(1 << 18);  // turn on RS232 port 2
116
 
117
 
118
   /*-----------------------*/
119
   /* Allow SMC2 TX, RX out */
120
   /*-----------------------*/
121
 
122
   IMMR->pip_pbpar |= (0x0C00);
123
   IMMR->pip_pbdir &= 0xF3FF;
124
 
125
   /*------------------------------------------------*/
126
   /* Set Baud Rate to 9600 for 40MHz System Clock.  */
127
   /* Enable BRG Count.                              */
128
   /*------------------------------------------------*/
129
 
130
   IMMR->brgc2 = ((divider << 1) | 0x10000);
131
 
132
   IMMR->si_simode &= ~(0xF0000000);    /* SCM2:  NMSI mode */
133
   IMMR->si_simode |= 0x10000000;       /* SCM2:  Tx/Rx Clocks are BRG2 */
134
 
135
 
136
   /*--------------------*/
137
   /* Initialize the BDs */
138
   /*--------------------*/
139
 
140
   InitBDs(); /* before setting up info depending on RxTxBD below */
141
 
142
   IMMR->smc_regs[SMC2_REG].smc_smce = 0xFF;  /* Clear any pending events */
143
 
144
   /*----------------------------------------*/
145
   /* Set RXBD table start at Dual Port +800 */
146
   /*----------------------------------------*/
147
 
148
   IMMR->PRAM[PAGE4].pg.other.smc_dsp2.psmc2.u2.rbase = (unsigned short) (unsigned) &RxTxBD->RxBD;
149
 
150
   /*----------------------------------------*/
151
   /* Set TXBD table start at Dual Port +808 */
152
   /*----------------------------------------*/
153
 
154
   IMMR->PRAM[PAGE4].pg.other.smc_dsp2.psmc2.u2.tbase = (unsigned short) (unsigned) &RxTxBD->TxBD;
155
 
156
 
157
   /*--------------------------------------*/
158
   /* Set RFCR,TFCR -- Rx,Tx Function Code */
159
   /* Normal Operation and Motorola byte   */
160
   /* ordering                             */
161
   /*--------------------------------------*/
162
 
163
   IMMR->PRAM[PAGE4].pg.other.smc_dsp2.psmc2.u2.rfcr = 0x18;
164
   IMMR->PRAM[PAGE4].pg.other.smc_dsp2.psmc2.u2.tfcr = 0x18;
165
 
166
   /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
167
   /* Protocol Specific Parameters */
168
   /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
169
 
170
   /*---------------------------*/
171
   /* MRBLR = MAX buffer length */
172
   /*---------------------------*/
173
 
174
   IMMR->PRAM[PAGE4].pg.other.smc_dsp2.psmc2.u2.mrblr = 1;
175
 
176
   /*------------------------------------*/
177
   /* MAX_IDL = Disable MAX Idle Feature */
178
   /*------------------------------------*/
179
 
180
   IMMR->PRAM[PAGE4].pg.other.smc_dsp2.psmc2.u2.max_idl = 0;
181
 
182
   /*-------------------------------------*/
183
   /* BRKEC = No break condition occurred */
184
   /*-------------------------------------*/
185
 
186
   IMMR->PRAM[PAGE4].pg.other.smc_dsp2.psmc2.u2.brkec = 0;
187
 
188
   /*---------------------------------------*/
189
   /* BRKCR = 1 break char sent on top XMIT */
190
   /*---------------------------------------*/
191
 
192
   IMMR->PRAM[PAGE4].pg.other.smc_dsp2.psmc2.u2.brkcr = 1;
193
 
194
 
195
   /* InitBDs() used to be here - no harm in doing this again */
196
   IMMR->smc_regs[SMC2_REG].smc_smce = 0xFF;  /* Clear any pending events */
197
 
198
   /*--------------------------------------------------*/
199
   /* SMC_SMCM = Mask all interrupts, use polling mode */
200
   /*--------------------------------------------------*/
201
 
202
   IMMR->smc_regs[SMC2_REG].smc_smcm = 0;
203
 
204
   IMMR->cpmi_cicr = 0;           /* Disable all CPM interrups */
205
   IMMR->cpmi_cipr = 0xFFFFFFFF;  /* Clear all pending interrupt events */
206
   IMMR->cpmi_cimr = 0;           /* Mask all event interrupts */
207
 
208
   /*------------------------------------*/
209
   /* 8-bit mode,  no parity, 1 stop-bit */
210
   /* UART SMC Mode                      */
211
   /* Normal operation (no loopback),    */
212
   /* SMC Transmitter/Receiver Enabled   */
213
   /*------------------------------------*/
214
 
215
   IMMR->smc_regs[SMC2_REG].smc_smcmr = 0x4823;
216
 
217
   /*---------------------------------------*/
218
   /* Initialize Rx and Tx Params for SMC2: */
219
   /* Spin until cpcr flag is cleared       */
220
   /*---------------------------------------*/
221
 
222
   for(IMMR->cp_cr = 0x00d1; IMMR->cp_cr & 0x0001;) ;
223
 
224
}
225
 
226
 
227
 
228
/*-----------------------------------------------------------------------------
229
*
230
* FUNCTION NAME:  InitBDs
231
*
232
* DESCRIPTION: This function initializes the Tx and Rx Buffer Descriptors.
233
*
234
* EXTERNAL EFFECT: RxTxBD
235
*
236
* PARAMETERS:  None
237
*
238
* RETURNS: None
239
*
240
*---------------------------------------------------------------------------*/
241
 
242
static void InitBDs(void)
243
 
244
{
245
   /*--------------------------------------------------------------------*/
246
   /* We add 64 bytes to the start of the buffer descriptors because     */
247
   /* this code was also tested on the monitor version of SDS debugger.  */
248
   /* The monitor program on our target uses most of the first 64 bytes  */
249
   /* for buffer descriptors. If you are not using the SDS monitor  with */
250
   /* Motorola's ADS development board, you can delete 64 below and      */
251
   /* start at the beginning of this particular block of Dual Port RAM.  */
252
   /*--------------------------------------------------------------------*/
253
 
254
   /*----------------------------------*/
255
   /* Get pointer to BD area on DP RAM */
256
   /*----------------------------------*/
257
 
258
   RxTxBD = (BDRINGS *)(IMMR->qcp_or_ud.ud.udata_bd + 64);
259
 
260
   /*-------------------------------------------------------------------*/
261
   /* Establish the buffer pool in Dual Port RAM. We do this because the*/
262
   /* pool size is only 2 bytes (1 for Rx and 1 for Tx) and to avoid    */
263
   /* disabling data cache for the memory region where BufferPool would */
264
   /* reside. The CPM does not recognize data in buffer pools once it   */
265
   /* been cached. It's acesses are direct through DMA to external      */
266
   /* memory.                                                           */
267
   /*-------------------------------------------------------------------*/
268
 
269
   SMC2Buffers = (LB *)(IMMR->qcp_or_ud.ud.udata_bd + 80);
270
 
271
   /*-----------------------------------*/
272
   /* Setup Receiver Buffer Descriptors */
273
   /*-----------------------------------*/
274
 
275
   RxTxBD->RxBD.bd_cstatus = 0xA000;            /* Enable, Last BD */
276
   RxTxBD->RxBD.bd_length = 1;
277
   RxTxBD->RxBD.bd_addr = &(SMC2Buffers->RxBuffer);
278
 
279
 
280
   /*--------------------------------------*/
281
   /* Setup Transmitter Buffer Descriptors */
282
   /*--------------------------------------*/
283
 
284
   RxTxBD->TxBD.bd_cstatus = 0x2000;      /* Buffer not yet ready; Last BD */
285
   RxTxBD->TxBD.bd_length = 1;
286
   RxTxBD->TxBD.bd_addr = &(SMC2Buffers->TxBuffer);
287
 
288
} /* END InitBDs */
289
 
290
 
291
#if 0 // static unused function. -jskov 19990122
292
/*-----------------------------------------------------------------------------
293
*
294
* FUNCTION NAME:  EchoChar
295
*
296
* DESCRIPTION: This function facilitates the echoing of a received character.
297
*
298
* EXTERNAL EFFECT: RxTxBD
299
*
300
* PARAMETERS:  None
301
*
302
* RETURNS: None
303
*
304
*---------------------------------------------------------------------------*/
305
 
306
static void  EchoChar(void)
307
 
308
{
309
   char mych;
310
 
311
   mych = cyg_smc2_getchar();
312
   cyg_smc2_putchar(mych);
313
 
314
} /* end EchoChar */
315
#endif
316
 
317
/*-----------------------------------------------------------------------------
318
*
319
* FUNCTION NAME:  cyg_smc2_putchar
320
*
321
* DESCRIPTION: Output a character to SMC2
322
*
323
* EXTERNAL EFFECT: RxTxBD
324
*
325
* PARAMETERS:  ch - input character
326
*
327
* RETURNS: None
328
*
329
*---------------------------------------------------------------------------*/
330
 
331
void cyg_smc2_putchar(char ch)
332
 
333
{
334
  /*-----------------------------------*/
335
  /* Loop until transmission completed */
336
  /*-----------------------------------*/
337
 
338
   while (RxTxBD->TxBD.bd_cstatus  &  0x8000);
339
 
340
   /*------------*/
341
   /* Store data */
342
   /*------------*/
343
 
344
   *(RxTxBD->TxBD.bd_addr) = ch;
345
   RxTxBD->TxBD.bd_length = 1;
346
 
347
   /*---------------*/
348
   /* Set Ready bit */
349
   /*---------------*/
350
 
351
   RxTxBD->TxBD.bd_cstatus |= 0x8000;
352
 
353
}
354
 
355
 
356
 
357
/*-----------------------------------------------------------------------------
358
*
359
* FUNCTION NAME:  cyg_smc2_getchar
360
*
361
* DESCRIPTION: Get a character from SMC2
362
*
363
* EXTERNAL EFFECT: RxTxBD
364
*
365
* PARAMETERS:  NONE
366
*
367
* RETURNS: A character from SMC2
368
*
369
*---------------------------------------------------------------------------*/
370
 
371
char cyg_smc2_getchar(void)
372
 
373
{
374
 
375
    char ch;   /* output character from SMC2 */
376
 
377
    /*--------------------*/
378
    /* Loop if RxBD empty */
379
    /*--------------------*/
380
 
381
    while (RxTxBD->RxBD.bd_cstatus  &  0x8000);
382
 
383
    /*--------------*/
384
    /* Receive data */
385
    /*--------------*/
386
 
387
    ch = *(RxTxBD->RxBD.bd_addr);
388
 
389
    /*----------------------*/
390
    /* Set Buffer Empty bit */
391
    /*----------------------*/
392
 
393
    RxTxBD->RxBD.bd_cstatus |= 0x8000;
394
 
395
    return ch;
396
 
397
}
398
 
399
 
400
#if 0 // static unused function. -jskov 19990122
401
/*-----------------------------------------------------------------------------
402
*
403
* FUNCTION NAME:  SMC2Poll
404
*
405
* DESCRIPTION: Poll SMC2 RxBD and check to see if a character was received
406
*
407
* EXTERNAL EFFECT: NONE
408
*
409
* PARAMETERS:  NONE
410
*
411
* RETURNS: A one if there is a character available in the receive buffer,
412
*          else zero.
413
*
414
*---------------------------------------------------------------------------*/
415
 
416
static char SMC2Poll(void)
417
 
418
{
419
  return (RxTxBD->RxBD.bd_cstatus & 0x8000) ? 0 : 1;
420
 
421
} /* END SMC2Poll */
422
#endif
423
 
424
 
425
/*-----------------------------------------------------------------------------
426
*
427
* FUNCTION NAME:  GetIMMR
428
*
429
* DESCRIPTION: Returns current value in the IMMR register.
430
*
431
* EXTERNAL EFFECT: NONE
432
*
433
* PARAMETERS:  NONE
434
*
435
* RETURNS: The IMMR value in r3. The compiler uses r3 as the register
436
*          containing the return value.
437
*
438
*---------------------------------------------------------------------------*/
439
 
440
static unsigned long GetIMMR(void)
441
 
442
{
443
    unsigned long ret;
444
    asm volatile (" mfspr  %0,638 " : "=r" (ret));  /* IMMR is spr #638 */
445
 
446
    return ret;
447
}
448
 
449
 
450
/* EOF hal/powerpc/fads/quicc_smc2.c */

powered by: WebSVN 2.1.0

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