sysSerial.c
上传用户:yuanda199
上传日期:2022-06-26
资源大小:412k
文件大小:8k
源码类别:

VxWorks

开发平台:

C/C++

  1. /*
  2.     EXTERNAL SOURCE RELEASE on 12/03/2001 3.0 - Subject to change without notice.
  3. */
  4. /*
  5.     Copyright 2001, Broadcom Corporation
  6.     All Rights Reserved.
  7.     
  8.     This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation;
  9.     the contents of this file may not be disclosed to third parties, copied or
  10.     duplicated in any form, in whole or in part, without the prior written
  11.     permission of Broadcom Corporation.
  12.     
  13. */
  14. /*
  15.  * Copyright(c) 2001 Broadcom Corp.
  16.  * All Rights Reserved.
  17.  * $Id: sysSerial.c,v 1.1 Broadcom SDK $
  18.  */
  19. /* sysSerial.c - bcm47xx BSP serial device initialization */
  20. /* Copyright 1984-1999 Wind River Systems, Inc. */
  21. #include "copyright_wrs.h"
  22. /*
  23. modification history
  24. --------------------
  25. 01b,12nov99,hsm   cleaned
  26. 01a,28jul99,hsm   created.
  27. */
  28. #include "vxWorks.h"
  29. #include "arch/mips/ivMips.h"
  30. #include "intLib.h"
  31. #include "config.h"
  32. #include "sysLib.h"
  33. #include "drv/sio/ns16552Sio.h"
  34. #include "vxbsp.h"
  35. #include "bcm4710.h"
  36. #include "bcmutils.h"
  37. #include "sbextif.h"
  38. #define PHY_NONE 31
  39. #define XTAL xtal_freq
  40. /* device initialization structure */
  41. typedef struct
  42.     {
  43.     USHORT vector;                      /* Interrupt vector */
  44.     ULONG  baseAdrs;                    /* Register base address */
  45.     USHORT regSpace;                    /* Address Interval */
  46.     USHORT intLevel;                    /* Interrupt level */
  47.     } NS16550_CHAN_PARAS;
  48. /* Local data structures */
  49. static NS16550_CHAN  ns16550Chan[N_UART_CHANNELS];
  50. /*
  51. *  The channel select address line (addr3) for the external DUART on the MBZ
  52. *  board is the opposite polarity from a normal address line, so COM1 is at
  53. *  a higher address than COM2.  
  54. */
  55. static NS16550_CHAN_PARAS devParas[] = 
  56.    {
  57.    {COM1_INT_VEC, COM1_BASE_ADR, COM1_ADR_INTERVAL, COM1_INT_LVL},
  58.    {COM2_INT_VEC, COM2_BASE_ADR, COM2_ADR_INTERVAL, COM2_INT_LVL}
  59.    };
  60. static NS16550_CHAN_PARAS iUARTdevParas = 
  61.    { MBZ_IUART_INT_VEC, MBZ_IUART_BASE_ADR,
  62.        MBZ_IUART_ADR_INTERVAL, MBZ_IUART_INT_LVL};
  63. static unsigned int xtal_freq = COM1_FREQ;
  64. #define UART_REG(reg,chan) 
  65.                 (devParas[chan].baseAdrs + reg * devParas[chan].regSpace)
  66. /******************************************************************************
  67. *
  68. * sysSerialIuartCheck - Check if Internal UART is used and update the devParas
  69. *
  70. * RETURNS: N/A
  71. */
  72. void
  73. sysSerialIuartCheck()
  74. {
  75.     xtal_freq = COM1_FREQ;
  76.     if (SYS_REVID_GET() == BOARD_ID_MBZ_5645_REF) {
  77.         devParas[0] = iUARTdevParas;
  78.         xtal_freq = BCM_47XX_IUART_FREQ;
  79.     }
  80. }
  81. /******************************************************************************
  82. *
  83. * sysSerialChannelPrimaryCheck - Check console UART channel used and update 
  84. *   devParas table if required.
  85. *
  86. * RETURNS: N/A
  87. */
  88. void
  89. sysSerialChannelPrimaryCheck()
  90. {
  91.     NS16550_CHAN_PARAS devParasTemp;
  92.     if (!sysIsLM()) return;
  93.     devParasTemp = devParas[0];
  94.     devParas[0] = devParas[1];
  95.     devParas[1] = devParasTemp;
  96. }
  97. /******************************************************************************
  98. *
  99. * sysSerialHwInit - initialize the BSP serial devices to a quiesent state
  100. *
  101. * This routine initializes the BSP serial device descriptors and puts the
  102. * devices in a quiesent state.  It is called from sysHwInit() with
  103. * interrupts locked.
  104. *
  105. * RETURNS: N/A
  106. */
  107. void sysSerialHwInit (void)
  108.     {
  109.     int i;
  110.     sysSerialIuartCheck();
  111.     sysSerialChannelPrimaryCheck();
  112.     for (i = 0; i < N_UART_CHANNELS; i++)
  113.         {        
  114.         ns16550Chan[i].regs             = (UINT8 *)devParas[i].baseAdrs;
  115.         ns16550Chan[i].level            = devParas[i].vector;
  116.         ns16550Chan[i].ier              = 0;
  117.         ns16550Chan[i].lcr              = 0;
  118.         ns16550Chan[i].pad1             = 0;
  119.         ns16550Chan[i].channelMode      = 0;
  120.         ns16550Chan[i].regDelta         = devParas[i].regSpace;
  121.         ns16550Chan[i].baudRate         = CONSOLE_BAUD_RATE;
  122.         ns16550Chan[i].xtal             = xtal_freq;
  123.         /* Turn on the internal uart */
  124.         if (ns16550Chan[i].regs == (uint8*)KSEG1ADDR(BCM4710_UART)) {
  125.             extifregs_t *eir = (extifregs_t*)KSEG1ADDR(BCM4710_REG_EXTIF);
  126.             eir->corecontrol = 1;
  127.         }
  128.         ns16550DevInit (&ns16550Chan[i]);
  129.         }
  130.     }
  131. /******************************************************************************
  132. *
  133. * sysSerialInt - BSP specific serial device ISR
  134. *
  135. */
  136. void sysSerialInt(int unit){
  137.     
  138.     ns16550Int (&ns16550Chan[unit]);    
  139. }
  140. /******************************************************************************
  141. *
  142. * sysSerialHwInit2 - connect BSP serial device interrupts
  143. *
  144. * This routine connects the BSP serial device interrupts.  It is called from
  145. * sysHwInit2().  Serial device interrupts could not be connected in
  146. * sysSerialHwInit() because the kernel memory allocator was not initialized
  147. * at that point, and intConnect() calls malloc().
  148. *
  149. * RETURNS: N/A
  150. */
  151. void sysSerialHwInit2 (void)
  152. {
  153.     int i;
  154.     for (i = 0; i < N_UART_CHANNELS; i++)
  155.        {
  156.          if(i==0) 
  157.             intConnect (INUM_TO_IVEC (IV_EXT_ALT1_VEC), sysSerialInt, 0);         
  158.          if(i==1)
  159.             intConnect (INUM_TO_IVEC (IV_EXT_ALT2_VEC), sysSerialInt, 1);
  160.        }      
  161. }
  162. /******************************************************************************
  163. *
  164. * sysSerialHwReset - reset the serial controllers
  165. *
  166. * Shutdown all controllers capable of generating interrupts, especially
  167. * controllers using DMA to transfer channel command blocks.  Most Bug
  168. * monitors presume that a hardware reset precedes entry to the monitor
  169. * code.
  170. *
  171. * RETURNS: N/A.
  172. */
  173. VOID sysSerialHwReset (void)
  174.     {
  175.     int i;
  176.     for (i = 0; i < N_UART_CHANNELS; i++)
  177.         ns16550DevInit (&ns16550Chan[i]);
  178.     }
  179. /******************************************************************************
  180. *
  181. * sysSerialChanGet - get the SIO_CHAN device associated with a serial channel
  182. *
  183. * This routine gets the SIO_CHAN device associated with a specified serial
  184. * channel.
  185. *
  186. * RETURNS: A pointer to the SIO_CHAN structure for the channel, or ERROR
  187. * if the channel is invalid.
  188. */
  189. SIO_CHAN * sysSerialChanGet
  190.     (
  191.     int channel         /* serial channel */
  192.     )
  193.     {
  194.     if (channel < 0 || channel >= NELEMENTS(ns16550Chan))
  195.         return (SIO_CHAN *)ERROR;
  196.     
  197.     return ((SIO_CHAN *) &ns16550Chan[channel]);
  198.     }
  199. /******************************************************************************
  200.  *
  201.  * Serial debugging print routines
  202.  *
  203.  * The following routines are for debugging, especially useful in early
  204.  * boot ROM and ISR code.
  205.  *
  206.  * sysSerialPutc
  207.  * sysSerialGetc
  208.  * sysSerialPrintString
  209.  * sysSerialPrintHex
  210.  *
  211.  * The sysSerialPrintString and sysSerialPrintHex routines should
  212.  * basically ALWAYS work.  They re-initialize the UART and turn off
  213.  * interrupts every time.
  214.  */
  215. #define SS_CHAN         0
  216. UCHAR sysSerialInByte
  217.     (
  218.     int addr
  219.     )
  220.     {
  221.     return *(volatile unsigned char *) (addr^3);
  222.     }
  223. void sysSerialOutByte
  224.     (
  225.     int addr,
  226.     UCHAR c
  227.     )
  228.     {
  229.     *(volatile unsigned char *) (addr^3) = c;
  230.     }
  231. void sysSerialDelay(void)
  232. {
  233.     volatile int i;
  234.     for (i = 0; i < 0x10000; i++)
  235.         ;
  236. }
  237. void sysSerialPutc(int c)
  238. {
  239.     int i = 10000;
  240.     while (!(sysSerialInByte(UART_REG(LSR, SS_CHAN)) & 0x40) && i--)
  241.         ;
  242.     sysSerialOutByte(UART_REG(THR, SS_CHAN), c);
  243. }
  244. int sysSerialGetc(void)
  245. {
  246.     while (!(sysSerialInByte(UART_REG(LSR, SS_CHAN)) & 0x01))
  247.         ;
  248.     return sysSerialInByte(UART_REG(RBR, SS_CHAN));
  249. }
  250. void sysSerialUARTPollInit
  251.    (
  252.    int channel
  253.    )
  254.    {
  255.    sysSerialOutByte (UART_REG (LCR, channel), LCR_DLAB);
  256.    sysSerialOutByte (UART_REG (DLL, channel), BAUD_LO (CONSOLE_BAUD_RATE));
  257.    sysSerialOutByte (UART_REG (DLM, channel), BAUD_HI (CONSOLE_BAUD_RATE));
  258.    sysSerialOutByte (UART_REG (LCR, channel), CHAR_LEN_8 | ONE_STOP |
  259.        PARITY_NONE);
  260.    /* Shouldn't need this, but do it anyway (turns on all modem control enables) */
  261.    sysSerialOutByte (UART_REG (MCR, channel), 0xb);
  262.    }
  263. void sysSerialPrintString(char *s)
  264. {
  265.     int c, il;
  266.     il = intLock();
  267.     sysSerialUARTPollInit (SS_CHAN);
  268.     while ((c = *s++) != 0) {
  269.         if (c == 'n')
  270.             sysSerialPutc('r');
  271.         sysSerialPutc(c);
  272.     }
  273.     sysSerialDelay();   /* Allow last char to flush */
  274.     intUnlock(il);
  275. }
  276. void sysSerialPrintHex(UINT32 value, int cr)
  277. {
  278.     const char hex[] = "0123456789abcdef";
  279.     int i, il;
  280.     il = intLock();
  281.     sysSerialUARTPollInit (SS_CHAN);
  282.     for (i = 0; i < 8; i++)
  283.         sysSerialPutc(hex[value >> (28 - i * 4) & 0xf]);
  284.     if (cr) {
  285.         sysSerialPutc('r');
  286.         sysSerialPutc('n');
  287.     }
  288.     sysSerialDelay();   /* Allow last char to flush */
  289.     intUnlock(il);
  290. }