m68332Serial.c
上传用户:luoyougen
上传日期:2008-05-12
资源大小:23136k
文件大小:8k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* m68332Serial.c - Motorola MC68332 tty driver*/
  2. /* Copyright 1984-1993 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 01l,12feb93,caf  documented that 110 is minimum baud rate.
  8. 01k,12feb93,caf  fixed tyCoIoctl() parameter checking (SPR 1810).
  9.  updated copyright notice.
  10. 01j,01dec92,jdi  NOMANUAL for tyCoInt() - SPR 1808.
  11. 01i,28oct92,caf  tweaked tyCoDevCreate() documentation.
  12. 01h,13aug92,caf  fixed baud calculation.  ansified.
  13. 01g,28jul92,caf  fixed ansi warnings.
  14. 01f,18jul92,smb  Changed errno.h to errnoLib.h.
  15. 01e,26may92,rrr  the tree shuffle
  16. 01d,24jan92,jdi  documentation cleanup.
  17. 01c,04oct91,rrr  passed through the ansification filter
  18.   -changed VOID to void
  19.   -changed copyright notice
  20. 01b,27sep91,jdi  documentation cleanup.
  21. 01a,19sep91,jcf  written.
  22. */
  23. /*
  24. DESCRIPTION
  25. This is the driver for the Motorola MC68332 on-chip UART.
  26. USER-CALLABLE ROUTINES
  27. Most of the routines in this driver are accessible only through the I/O
  28. system.  Two routines, however, must be called directly:  tyCoDrv() to
  29. initialize the driver, and tyCoDevCreate() to create devices.
  30. Before the driver can be used, it must be initialized by calling the
  31. routine tyCoDrv().  This routine should be called exactly once, before any
  32. reads, writes, or calls to tyCoDevCreate().  Normally, it is called from
  33. usrRoot() in usrConfig.c.
  34. Before a terminal can be used, it must be created using tyCoDevCreate().
  35. Each port to be used should have exactly one device associated with it by
  36. calling this routine.  The MC68332 has only one channel associated with it.
  37. IOCTL FUNCTIONS
  38. This driver responds to the same ioctl() codes as a normal tty driver; for
  39. more information, see the manual entry for tyLib.  The available baud rates
  40. are 110 to 38400.
  41. SEE ALSO
  42. tyLib
  43. */
  44. /* includes */
  45. #include "vxWorks.h"
  46. #include "iv.h"
  47. #include "errnoLib.h"
  48. #include "ioLib.h"
  49. #include "intLib.h"
  50. #include "iosLib.h"
  51. #include "tyLib.h"
  52. #include "config.h"
  53. /* defines */
  54. #define DEFAULT_BAUD 9600
  55. /* globals */
  56. IMPORT TY_CO_DEV tyCoDv []; /* device descriptors */
  57. /* locals */
  58. LOCAL int tyCoDrvNum; /* driver number of this driver */
  59. /* forward declarations */
  60. LOCAL void tyCoStartup ();
  61. LOCAL int tyCoOpen ();
  62. LOCAL STATUS tyCoIoctl ();
  63. LOCAL void tyCoHrdInit ();
  64. /*******************************************************************************
  65. *
  66. * tyCoDrv - initialize the tty driver
  67. *
  68. * This routine initializes the serial driver, sets up interrupt vectors,
  69. * and performs hardware initialization of the serial port.
  70. *
  71. * This routine should be called exactly once, before any reads, writes, or
  72. * calls to tyCoDevCreate().  Normally, it is called from usrRoot() in
  73. * usrConfig.c.
  74. *
  75. * RETURNS: OK, or ERROR if the driver cannot be installed.
  76. *
  77. * SEE ALSO: tyCoDevCreate()
  78. */
  79. STATUS tyCoDrv (void)
  80.     {
  81.     /* check if driver already installed */
  82.     if (tyCoDrvNum > 0)
  83. return (OK);
  84.     tyCoHrdInit ();
  85.     tyCoDrvNum = iosDrvInstall (tyCoOpen, (FUNCPTR) NULL, tyCoOpen,
  86. (FUNCPTR) NULL, tyRead, tyWrite, tyCoIoctl);
  87.     return (tyCoDrvNum == ERROR ? ERROR : OK);
  88.     }
  89. /*******************************************************************************
  90. *
  91. * tyCoDevCreate - create a device for an on-board serial port
  92. *
  93. * This routine creates a device on a specified serial port.  Each port
  94. * to be used should have exactly one device associated with it by calling
  95. * this routine.
  96. *
  97. * For instance, to create the device "/tyCo/0", with buffer sizes of 512 bytes,
  98. * the proper call would be:
  99. * .CS
  100. *     tyCoDevCreate ("/tyCo/0", 0, 512, 512);
  101. * .CE
  102. *
  103. * RETURNS:
  104. * OK, or ERROR if the driver is not installed, the channel is invalid, or
  105. * the device already exists.
  106. *
  107. * SEE ALSO: tyCoDrv()
  108. */
  109. STATUS tyCoDevCreate
  110.     (
  111.     char *      name,           /* name to use for this device      */
  112.     FAST int    channel,        /* physical channel for this device */
  113.     int         rdBufSize,      /* read buffer size, in bytes       */
  114.     int         wrtBufSize      /* write buffer size, in bytes      */
  115.     )
  116.     {
  117.     FAST TY_CO_DEV *pTyCoDv;
  118.     if (tyCoDrvNum <= 0)
  119. {
  120. errnoSet (S_ioLib_NO_DRIVER);
  121. return (ERROR);
  122. }
  123.     /* if this doesn't represent a valid channel, don't do it */
  124.     if (channel != 0)
  125.         return (ERROR);
  126.     pTyCoDv = &tyCoDv [channel];
  127.     /* if there is a device already on this channel, don't do it */
  128.     if (pTyCoDv->created)
  129. return (ERROR);
  130.     /* initialize the ty descriptor */
  131.     if (tyDevInit (&pTyCoDv->tyDev, rdBufSize, wrtBufSize,
  132.    (FUNCPTR) tyCoStartup) != OK)
  133. return (ERROR);
  134.     /* mark the device as created, and add the device to the I/O system */
  135.     pTyCoDv->created = TRUE;
  136.     *M332_QSM_SCCR1 |= QSM_SCCR1_RIE; /* enable receiver interrupts */
  137.     return (iosDevAdd (&pTyCoDv->tyDev.devHdr, name, tyCoDrvNum));
  138.     }
  139. /*******************************************************************************
  140. *
  141. * tyCoHrdInit - initialize the USART
  142. */
  143. LOCAL void tyCoHrdInit (void)
  144.     {
  145.     FAST int oldlevel = intLock (); /* LOCK INTERRUPTS */
  146.     /* initialize QSM registers associated with SCI */
  147.     *M332_QSM_QILR &= ~QSM_QILR_SCI_MASK; /* disable sci ints */
  148.     /* set default baud rate */
  149.     *M332_QSM_SCCR0 = tyCoDv [0].baudFreq / (32 * DEFAULT_BAUD);
  150.     *M332_QSM_SCCR1 = QSM_SCCR1_RE | QSM_SCCR1_TE; /* enable rx/tx */
  151.     *M332_QSM_QILR |= INT_LVL_SCI; /* enable sci ints */
  152.     intUnlock (oldlevel); /* UNLOCK INTERRUPTS */
  153.     }
  154. /*******************************************************************************
  155. *
  156. * tyCoOpen - open file to USART
  157. */
  158. LOCAL int tyCoOpen
  159.     (
  160.     TY_CO_DEV *pTyCoDv,
  161.     char      *name,
  162.     int        mode
  163.     )
  164.     {
  165.     return ((int) pTyCoDv);
  166.     }
  167. /*******************************************************************************
  168. *
  169. * tyCoIoctl - special device control
  170. *
  171. * This routine handles FIOBAUDRATE requests and passes all others to tyIoctl.
  172. *
  173. * RETURNS: OK or ERROR if invalid baud rate, or whatever tyIoctl returns.
  174. *
  175. * INTERNAL
  176. * The range of SCI baud rates depends on the system clock frequency.
  177. * For 16 MHz systems, the practical range is 110 to 38400 baud.
  178. */
  179. LOCAL STATUS tyCoIoctl
  180.     (
  181.     TY_CO_DEV * pTyCoDv, /* device to control */
  182.     int request, /* request code      */
  183.     int arg /* some argument     */
  184.     )
  185.     {
  186.     FAST STATUS status = ERROR;
  187.     UINT16 baudScratch;
  188.     switch (request)
  189. {
  190. case FIOBAUDRATE:
  191.     baudScratch = tyCoDv [0].baudFreq / (32 * arg);
  192.     if ((baudScratch >= 1) && (baudScratch <= 8191) && (arg <= 38400))
  193. {
  194. *M332_QSM_SCCR0 = baudScratch;
  195. status = OK;
  196. break;
  197. }
  198.     break;
  199. default:
  200.     status = tyIoctl (&pTyCoDv->tyDev, request, arg);
  201.     break;
  202. }
  203.     return (status);
  204.     }
  205. /*******************************************************************************
  206. *
  207. * tyCoInt - interrupt level processing
  208. *
  209. * This routine handles interrupts from the SCI port.
  210. *
  211. * NOMANUAL
  212. */
  213. void tyCoInt (void)
  214.     {
  215.     char outChar;
  216.     if (*M332_QSM_SCSR & QSM_SCSR_TDRE)
  217. if (tyITx (&tyCoDv [0].tyDev, &outChar) == OK)
  218.     *M332_QSM_SCDR = outChar;
  219. else
  220.     *M332_QSM_SCCR1 &= ~QSM_SCCR1_TIE;
  221.     if (*M332_QSM_SCSR & QSM_SCSR_RDRF)
  222. tyIRd (&tyCoDv [0].tyDev, *M332_QSM_SCDR);
  223.     }
  224. /*******************************************************************************
  225. *
  226. * tyCoStartup - transmitter startup routine
  227. *
  228. * Call interrupt level character output routine.
  229. */
  230. LOCAL void tyCoStartup
  231.     (
  232.     TY_CO_DEV *pTyCoDv /* ty device to start up */
  233.     )
  234.     {
  235.     char outChar;
  236.     if ((*M332_QSM_SCSR & QSM_SCSR_TDRE) &&
  237.         (tyITx (&pTyCoDv->tyDev, &outChar) == OK))
  238. {
  239. *M332_QSM_SCDR   = outChar;
  240. *M332_QSM_SCCR1 |= QSM_SCCR1_TIE;
  241. }
  242.     }