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

VxWorks

开发平台:

C/C++

  1. /* mb86940Serial.c - MB 86940 UART tty driver */
  2. /* Copyright 1992-1993 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 01h,21jun93,ccc  modified for mb931.
  8. 01g,28oct92,caf  tweaked tyCoDevCreate() documentation and parm checking.
  9. 01f,18aug92,ccc  made board-independent (from ver 01e of mb930/tyCoDrv.c).
  10. 01e,18jul92,smb  Changed errno.h to errnoLib.h.
  11. 01d,16jun92,jwt  cleaned up ANSI compiler warnings.
  12. 01c,26may92,rrr  the tree shuffle
  13. 01b,26apr92,jwt  passed through the ansification filter
  14.   -changed VOID to void
  15.   -changed copyright notice
  16. 01a,07jan92,ccc  written.
  17. */
  18. /*
  19. DESCRIPTION
  20. This is the driver for the SPARClite MB86930 on-board serial ports.
  21. USER-CALLABLE ROUTINES
  22. Most of the routines in this driver are accessible only through the I/O
  23. system.  Two routines, however, must be called directly: tyCoDrv() to
  24. initialize the driver, and tyCoDevCreate() to create devices.
  25. Before the driver can be used, it must be initialized by calling tyCoDrv().
  26. This routine should be called exactly once, before any reads, writes, or
  27. calls to tyCoDevCreate().  Normally, it is called by usrRoot() in usrConfig.c.
  28. Before a terminal can be used, it must be created using tyCoDevCreate().
  29. Each port to be used should have exactly one device associated with it
  30. by calling this routine.
  31. IOCTL FUNCTIONS
  32. This driver responds to the same ioctl() codes as a normal tty driver;
  33. for more information, see the manual entry for tyLib.  The UARTs use timer 
  34. 3 output to generate the following baud rates:  110, 150, 300, 600, 1200,
  35. 2400, 4800, 9600, and 19200.  Note that the UARTs will operate at the same
  36. baud rate.
  37. */
  38. #include "vxWorks.h"
  39. #include "ioLib.h"
  40. #include "tyLib.h"
  41. #include "intLib.h"
  42. #include "errnoLib.h"
  43. #include "arch/sparc/mb86940.h"
  44. LOCAL int tyCoDrvNum; /* driver number assigned to this driver */
  45. IMPORT TY_CO_DEV tyCoDv []; /* device descriptors */
  46. /* forward declarations */
  47. LOCAL void   tyCoStartup ();
  48. LOCAL int    tyCoOpen ();
  49. LOCAL int    tyCoRead ();
  50. LOCAL int    tyCoWrite ();
  51. LOCAL STATUS tyCoIoctl ();
  52. LOCAL void   tyCoHrdInit ();
  53. /******************************************************************************
  54. *
  55. * tyCoDrv - initialize the tty driver
  56. *
  57. * This routine initializes the serial driver, sets up interrupt vectors,
  58. * and performs hardware initialization of the serial ports.
  59. *
  60. * This routine must be called in supervisor state, since it does
  61. * physical I/O directly.  
  62. *
  63. * This routine should be called exactly once, before any reads, writes, or 
  64. * calls to tyCoDevCreate().  Normally, it is called by usrRoot() in 
  65. * usrConfig.c.
  66. *
  67. * RETURNS
  68. * OK, or ERROR if the driver cannot be installed.
  69. *
  70. * SEE ALSO: tyCoDevCreate()
  71. */
  72. STATUS tyCoDrv (void)
  73.     {
  74.     /* check if driver already installed */
  75.     if (tyCoDrvNum > 0)
  76. return (OK);
  77.     tyCoHrdInit ();
  78.     tyCoDrvNum = iosDrvInstall (tyCoOpen, (FUNCPTR) NULL, tyCoOpen,
  79. (FUNCPTR) NULL, tyCoRead, tyCoWrite, tyCoIoctl);
  80.     return (tyCoDrvNum == ERROR ? ERROR : OK);
  81.     }
  82. /******************************************************************************
  83. *
  84. * tyCoDevCreate - create a device for an on-board serial ports
  85. *
  86. * This routine creates a device on a specified serial port.  Each port
  87. * to be used should have exactly one device associated with it by calling
  88. * this routine.
  89. *
  90. * For instance, to create the device "/tyCo/0", with buffer sizes of 512
  91. * bytes, the proper call would be:
  92. * .CS
  93. *     tyCoDevCreate ("/tyCo/0", 0, 512, 512);
  94. * .CE
  95. *
  96. * RETURNS
  97. * OK, or ERROR if the driver is not installed, the channel is invalid, or the
  98. * device already exists.
  99. *
  100. * SEE ALSO: tyCoDrv()
  101. */
  102. STATUS tyCoDevCreate
  103.     (
  104.     char *      name,           /* name to use for this device      */
  105.     FAST int    channel,        /* physical channel for this device */
  106.     int         rdBufSize,      /* read buffer size, in bytes       */
  107.     int         wrtBufSize      /* write buffer size, in bytes      */
  108.     )
  109.     {
  110.     if (tyCoDrvNum <= 0)
  111. {
  112. errnoSet (S_ioLib_NO_DRIVER);
  113. return (ERROR);
  114. }
  115.     /* if this doesn't represent a valid channel, don't do it */
  116.     if (channel < 0 || channel >= tyCoDv [0].numChannels)
  117.         return (ERROR);
  118.     /* if this device already exists, don't create it */
  119.     if (tyCoDv [channel].created)
  120. return (ERROR);
  121.     /* initialize the ty descriptor, and turn on the bit for this
  122.      * receiver and transmitter in the interrupt mask */
  123.     if (tyDevInit ((TY_DEV_ID) &tyCoDv [channel],
  124.     rdBufSize, wrtBufSize, (FUNCPTR) tyCoStartup) != OK)
  125. {
  126. return (ERROR);
  127. }
  128.     /* Mark the device as having been created, and add the device to
  129.      * the I/O system */
  130.     tyCoDv [channel].created = TRUE;
  131.     return (iosDevAdd ((DEV_HDR *) &tyCoDv [channel], name, tyCoDrvNum));
  132.     }
  133. /******************************************************************************
  134. *
  135. * tyCoHrdInit - initialize the UARTs.
  136. *
  137. * This routine initializes the on-board UARTs for the VxWorks environment.
  138. *
  139. * This routine must be called in supervisor mode, since it accesses I/O
  140. * space. (This depends on how the page lookup table is setup!)
  141. *
  142. */
  143. LOCAL void tyCoHrdInit (void)
  144.     {
  145.     int ix;
  146.     int delay; /* delay for reset */
  147.     volatile int bump; /* for something to do */
  148.     int oldlevel; /* current interrupt level mask */
  149.     oldlevel = intLock (); /* disable interrupts during init */
  150.     /* set up baud rate at 9600 */
  151.     sysBaudSet (9600);
  152.     /* Initialization sequence to put the SDTR in a known reset state */
  153.     /* From Fujitsu code */
  154.     sys940AsiSeth ((void *) (tyCoDv [0].cp), NULL);
  155.     sys940AsiSeth ((void *) (tyCoDv [1].cp), NULL);
  156.     sys940AsiSeth ((void *) (tyCoDv [0].cp), NULL);
  157.     sys940AsiSeth ((void *) (tyCoDv [1].cp), NULL);
  158.     sys940AsiSeth ((void *) (tyCoDv [0].cp), NULL);
  159.     sys940AsiSeth ((void *) (tyCoDv [1].cp), NULL);
  160.     for (ix = 0; ix < tyCoDv [0].numChannels; ix++) /* should go to N_UARTS */
  161. {
  162. sys940AsiSeth ((void *) (tyCoDv [ix].cp), FCC_SDTR_RESET);
  163. for(delay=0; delay < 10000; delay++)
  164.     bump++;
  165. /* after reset only the first access is the MODE register */
  166. sys940AsiSeth ((void *) (tyCoDv [ix].cp), FCC_SDTR_1_BIT    |
  167.        FCC_SDTR_ODD      |
  168.        FCC_SDTR_NOPARITY |
  169.        FCC_SDTR_8BITS    |
  170.        FCC_SDTR_1_16XCLK);
  171. sys940AsiSeth ((void *) (tyCoDv [ix].cp), FCC_TX_START);
  172. }
  173.     intUnlock (oldlevel);
  174.     }
  175. /******************************************************************************
  176. *
  177. * tyCoOpen - open file to SPARClite UART
  178. */
  179. LOCAL int tyCoOpen
  180.     (
  181.     TY_CO_DEV *pTyCoDv,
  182.     char *name,
  183.     int flags,
  184.     int mode
  185.     )
  186.     {
  187.     return ((int) pTyCoDv);
  188.     }
  189. /******************************************************************************
  190. *
  191. * tyCoRead - task level read routine for SPARClite UART
  192. *
  193. * This routine fields all read calls to the SPARClite UART.
  194. */
  195. LOCAL int tyCoRead
  196.     (
  197.     TY_CO_DEV *pTyCoDv,
  198.     char *buffer,
  199.     int maxbytes
  200.     )
  201.     {
  202.     return (tyRead ((TY_DEV_ID) pTyCoDv, buffer, maxbytes));
  203.     }
  204. /******************************************************************************
  205. *
  206. * tyCoWrite - task level write routine for SPARClite UART
  207. *
  208. * This routine fields all write calls to the SPARClite UART.
  209. */
  210. LOCAL int tyCoWrite
  211.     (
  212.     TY_CO_DEV *pTyCoDv,
  213.     char *buffer,
  214.     int nbytes
  215.     )
  216.     {
  217.     return (tyWrite ((TY_DEV_ID) pTyCoDv, buffer, nbytes));
  218.     }
  219. /******************************************************************************
  220. *
  221. * tyCoIoctl - special device control
  222. *
  223. * This routine handles baud rate requests, and passes all other requests
  224. * to tyIoctl().
  225. *
  226. * NOTE:  Both serial ports use the output of timer 3 for the baud clock.
  227. * Therefore, both ports will be set for the same baud rate.
  228. */
  229. LOCAL STATUS tyCoIoctl
  230.     (
  231.     TY_CO_DEV *pTyCoDv, /* device to control */
  232.     int request, /* request code */
  233.     int arg /* some argument */
  234.     )
  235.     {
  236.     STATUS status;
  237.     switch (request)
  238. {
  239. case FIOBAUDRATE:
  240.     status = sysBaudSet (arg);
  241.     break;
  242. default:
  243.     status = tyIoctl ((TY_DEV_ID) pTyCoDv, request, arg);
  244.     break;
  245. }
  246.     return (status);
  247.     }
  248. /******************************************************************************
  249. *
  250. * tyCoIntRx - handle a receiver interrupt
  251. *
  252. * RETURNS: N/A
  253. *
  254. * NOMANUAL
  255. */
  256. void tyCoIntRx
  257.     (
  258.     FAST int channel
  259.     )
  260.     {
  261.     (void) tyIRd ((TY_DEV_ID) &tyCoDv [channel],
  262.   sys940AsiGeth ((void *) tyCoDv [channel].dp));
  263.     }
  264. /******************************************************************************
  265. *
  266. * tyCoIntTx - handle a transmitter interrupt
  267. *
  268. * If there is another character to be transmitted, it sends it.  If
  269. * not, or if a device has never been created for this channel, we just
  270. * disable the interrupt.
  271. *
  272. * RETURNS: N/A
  273. *
  274. * NOMANUAL
  275. */
  276. void tyCoIntTx
  277.     (
  278.     FAST int channel
  279.     )
  280.     {
  281.     char outChar;
  282.     if ((tyCoDv [channel].created) &&
  283. (tyITx ((TY_DEV_ID) &tyCoDv [channel], &outChar) == OK))
  284. {
  285. sys940AsiSeth ((void *) (tyCoDv [channel].dp), outChar);
  286. }
  287.     }
  288. /******************************************************************************
  289. *
  290. * tyCoStartup - transmitter startup routine
  291. *
  292. * Call interrupt level character output routine for SPARClite UART.
  293. */
  294. LOCAL void tyCoStartup
  295.     (
  296.     TY_CO_DEV *pTyCoDv /* ty device to start up */
  297.     )
  298.     {
  299.     char outChar;
  300.     /*
  301.      * if created, and a character is available send it, the the IRQ
  302.      * routine will send the rest.
  303.      */
  304.     if ((pTyCoDv->created) && (tyITx (&pTyCoDv->tyDev, &outChar) == OK))
  305. sys940AsiSeth ((void *) (pTyCoDv->dp), outChar);
  306.     }