sysDuart.c
上传用户:dqzhongke1
上传日期:2022-06-26
资源大小:667k
文件大小:5k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* sysDuart.c -  Wind River SBC8548 Duart device initialization */
  2. /*
  3.  * Copyright (c) 2006 Wind River Systems, Inc.
  4.  *
  5.  * The right to copy, distribute, modify, or otherwise make use
  6.  * of this software may be licensed only pursuant to the terms
  7.  * of an applicable Wind River license agreement.
  8.  */
  9. /*
  10. modification history
  11. --------------------
  12. 01a,30jan06,kds  Modified from cds8548/sysDuart.c/01a
  13. */
  14. /*
  15. DESCRIPTION
  16. This file contains board-specific routines for Wind River SBC8548
  17. Duart device initialization. 
  18. INCLUDE FILES:
  19. */
  20. #include <vxWorks.h>
  21. #include <config.h>
  22. #include <intLib.h>
  23. #include <iv.h>
  24. #include <sysLib.h>
  25. #include <config.h>
  26. #include <sysEpic.h>
  27. #include <sysDuart.h>         /* MPC8241/8245 duart driver */
  28. #include <drv/sio/ns16552Sio.h> /* ns16552Sio driver */
  29. /* device description structs */
  30. typedef struct
  31.     {
  32.     USHORT vector; /* Interrupt vector */
  33.     ULONG  baseAdrs; /* Register base address */
  34.     USHORT regSpace; /* Address Interval */
  35.     USHORT intLevel; /* Interrupt level */
  36.     } NS16552_CHAN_PARAS;
  37. /* external variable */
  38. IMPORT int epicIntTrace;                /* trace epic internal interrupts */
  39. /* global variable */
  40. NS16550_CHAN  ns16550Chan[N_DUART_CHANNELS];
  41. char  *eumbbar_base;                    /* eumbbar base address */
  42. /* static variables */
  43. /* 
  44.  * Both DUART channels are supported on the SBC8548 board. 
  45.  * COM1 is selected by default. To select COM2, swap the COM1_ADR
  46.  * and COM2_ADR constants below.
  47.  */
  48. LOCAL NS16552_CHAN_PARAS devDuartParas[] = 
  49.     {
  50.     {EPIC_DUART_INT_VEC, COM1_ADR, DUART_REG_ADDR_INTERVAL, EPIC_DUART_INT_NUM},
  51.     {EPIC_DUART2_INT_VEC, COM2_ADR, DUART_REG_ADDR_INTERVAL, EPIC_DUART2_INT_NUM}
  52.     };  
  53. /*
  54.  * Array of pointers to all MPC854x serial channels configured.
  55.  * See sysDuartChanGet(). It is this array that maps channel pointers
  56.  * to standard device names.  The first entry will become "/tyCo/2",
  57.  * the second "/tyCo/3".
  58.  */
  59. SIO_CHAN * sysSerialSioChans [N_SIO_CHANNELS] =
  60.     {
  61.     (SIO_CHAN *)&ns16550Chan[0].pDrvFuncs,
  62.     (SIO_CHAN *)&ns16550Chan[1].pDrvFuncs
  63.     };
  64. /* definitions */
  65. #define DUART_REG(reg, chan) 
  66.         *(volatile UINT8 *)(devDuartParas[chan].baseAdrs + reg * devDuartParas[chan].regSpace)
  67. /******************************************************************************
  68. *
  69. * sysDuartHwInit - initialize duart MPC854x devices to a quiescent state
  70. *
  71. * This routine initializes the MPC854x Duart device descriptors and puts
  72. * the devices in a quiescent state.  It is called from sysHwInit() with
  73. * interrupts locked.   Polled mode serial operations are possible, but
  74. * not interrupt mode operations which are enabled by sysDuartHwInit2().
  75. *
  76. * RETURNS: N/A
  77. *
  78. * SEE ALSO: sysHwInit()
  79. */ 
  80. void sysDuartHwInit (void)
  81.     {
  82.     int i;
  83.     eumbbar_base = (char *)CCSBAR;
  84. for (i = 0; i < N_DUART_CHANNELS; i++)
  85. {
  86. ns16550Chan[i].regs        = (UINT8 *)devDuartParas[i].baseAdrs;
  87. ns16550Chan[i].level    = devDuartParas[i].intLevel;
  88. ns16550Chan[i].channelMode = SIO_MODE_INT;
  89. ns16550Chan[i].regDelta    = devDuartParas[i].regSpace;
  90. ns16550Chan[i].baudRate    = DUART_BAUD;
  91. ns16550Chan[i].xtal    = sysClkFreqGet();
  92. ns16550DevInit (&ns16550Chan[i]);
  93. }
  94. if (ns16550Chan[0].channelMode == SIO_MODE_INT)
  95. {
  96.         eumbbar_base[UDCR2] = 0x01;  /* set duart mode */
  97.         eumbbar_base[ULCR2] = 0x80;  /* open DLAB */
  98.         eumbbar_base[UAFR2] = 0x00;
  99.         eumbbar_base[UDMB2] = 0x0a;  /* MSB 9600bps @400Mhz */
  100. eumbbar_base[UDLB2] = 0xaa;  /* LSB */
  101. eumbbar_base[ULCR2] = 0x03;  /* clear DLAB, no-parity, 1stop bit, 8bit data */
  102. eumbbar_base[UMCR2] = 0x02;  /* disable loopback mode */
  103. eumbbar_base[UIER2] = 0x03;  /* Tx empty, Rx interrupt enable */
  104. }
  105.     } /* sysDuartHwInit () */
  106. /******************************************************************************
  107. *
  108. * sysDuartHwInit2 - connect MPC854x duart device interrupts
  109. *
  110. * This routine connects the MPC854x duart device interrupts. It is called
  111. * from sysHwInit2().  
  112. *
  113. * Serial device interrupts cannot be connected in sysDuartHwInit() because
  114. * the kernel memory allocator is not initialized at that point and
  115. * intConnect() calls malloc().
  116. *
  117. * RETURNS: N/A
  118. *
  119. * SEE ALSO: sysHwInit2()
  120. */ 
  121. void sysSerialHwInit2 (void)
  122.     {
  123.     int i;
  124.     /* connect serial interrupts */
  125.     for (i = 0; i < N_DUART_CHANNELS; i++)
  126.         {
  127.         (void) sysEpicIntConnect ((VOIDFUNCPTR *)((int)devDuartParas[i].vector),
  128.                            (VOIDFUNCPTR)ns16550Int, (int)&ns16550Chan[i] );
  129.         sysEpicIntEnable (devDuartParas[i].vector); 
  130.         }
  131.     } /* sysDuartHwInit2 () */
  132. /******************************************************************************
  133. *
  134. * sysDuartChanGet - get the SIO_CHAN device associated with MPC854x
  135. *
  136. * This routine returns a pointer to the SIO_CHAN device associated
  137. * with a specified serial channel on MPC854x.  It is called by usrRoot() to
  138. * obtain pointers when creating the system serial devices, `/tyCo/x'.  It
  139. * is also used by the WDB agent to locate its serial channel.
  140. *
  141. * RETURNS: A pointer to the SIO_CHAN structure for the channel, or ERROR
  142. * if the channel is invalid.
  143. */
  144. SIO_CHAN * sysSerialChanGet
  145.     (
  146.     int channel         /* serial channel */
  147.     )
  148.     {
  149.     if ( (channel < 0) ||
  150.          (channel >= (int)NELEMENTS(sysSerialSioChans)) )
  151. return (SIO_CHAN *) ERROR;
  152.     return sysSerialSioChans[channel];
  153.     }