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

VxWorks

开发平台:

C/C++

  1. /* mb86940Sio.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. 01b,09nov95,jdi  doc: style cleanup.
  8. 01a,31jul95,myz  written(based on mb86940Serial.c) 
  9. */
  10. /*
  11. DESCRIPTION
  12. This is the driver for the SPARClite MB86930 on-board serial ports.
  13. USAGE
  14. A MB86940_CHAN structure is used to describe the chip. 
  15. The BSP's sysHwInit() routine typically calls sysSerialHwInit(),
  16. which initializes all the values in the MB86940_CHAN structure (except
  17. the SIO_DRV_FUNCS) before calling mb86940DevInit().
  18. The BSP's sysHwInit2() routine typically calls sysSerialHwInit2(), which
  19. connects the chips interrupts via intConnect(). 
  20. IOCTL FUNCTIONS
  21. The UARTs use timer 3 output to generate the following baud rates:
  22. 110, 150, 300, 600, 1200, 2400, 4800, 9600, and 19200.
  23. Note that the UARTs will operate at the same baud rate.
  24. INCLUDE FILES: drv/sio/mb86940Sio.h 
  25. */
  26. #include "vxWorks.h"
  27. #include "sioLib.h"
  28. #include "intLib.h"
  29. #include "errno.h"
  30. #include "drv/sio/mb86940Sio.h"
  31. /* forward declarations */
  32. static int    mb86940Startup (MB86940_CHAN *);
  33. static int    mb86940Ioctl (MB86940_CHAN *,int,int);
  34. static int    mb86940CallbackInstall(SIO_CHAN *,int,STATUS (*)(),void *);
  35. static int    mb86940PTxChar (MB86940_CHAN *,char);
  36. static int    mb86940PRxChar (MB86940_CHAN *,char *);
  37. /* local driver function table */
  38. static SIO_DRV_FUNCS mb86940SioDrvFuncs = 
  39.     {
  40.     (int (*)())mb86940Ioctl,
  41.     (int (*)())mb86940Startup,
  42.     mb86940CallbackInstall,
  43.     (int (*)())mb86940PRxChar,
  44.     (int (*)(SIO_CHAN *,char))mb86940PTxChar
  45.     };
  46. /******************************************************************************
  47. *
  48. * mb86940CallbackInstall - install ISR callbacks to get put chars.
  49. */
  50. static int mb86940CallbackInstall
  51.     (
  52.     SIO_CHAN *  pSioChan,
  53.     int         callbackType,
  54.     STATUS      (*callback)(),
  55.     void *      callbackArg
  56.     )
  57.     {
  58.     MB86940_CHAN * pChan = (MB86940_CHAN *)pSioChan;
  59.     switch (callbackType)
  60.         {
  61.         case SIO_CALLBACK_GET_TX_CHAR:
  62.             pChan->getTxChar    = callback;
  63.             pChan->getTxArg     = callbackArg;
  64.             return (OK);
  65.         case SIO_CALLBACK_PUT_RCV_CHAR:
  66.             pChan->putRcvChar   = callback;
  67.             pChan->putRcvArg    = callbackArg;
  68.             return (OK);
  69.         default:
  70.             return (ENOSYS);
  71.         }
  72.     }
  73. /******************************************************************************
  74. *
  75. * mb86940DevInit - install the driver function table
  76. *
  77. * This routine installs the driver function table.  It also
  78. * prevents the serial channel from functioning by disabling the interrupt.
  79. *
  80. * RETURNS: N/A
  81. *
  82. */
  83. void mb86940DevInit
  84.     (
  85.     MB86940_CHAN *pChan
  86.     )
  87.     {
  88.     int delay;
  89.     volatile int bump;  /* for something to do */
  90.     /* disables the serial channel interrupts */ 
  91.                  
  92.     (*pChan->intDisable)(pChan->rxIntLevel);
  93.     (*pChan->intDisable) (pChan->txIntLevel);
  94.     /* install device driver function table */
  95.     pChan->pDrvFuncs = &mb86940SioDrvFuncs;
  96.     /* Initialization sequence to put the SDTR in a known reset state */
  97.     /* From Fujitsu code */
  98.     (*pChan->asiSeth) ((void *) (pChan->cp), NULL);
  99.     (*pChan->asiSeth) ((void *) (pChan->cp), NULL);
  100.     (*pChan->asiSeth) ((void *) (pChan->cp), NULL);
  101.     (*pChan->asiSeth) ((void *) (pChan->cp), FCC_SDTR_RESET);
  102.     for (delay=0; delay < 10000; delay++)
  103.         bump++;
  104.     /* after reset only the first access is the MODE register */
  105.     (*pChan->asiSeth) ((void *) (pChan->cp),   FCC_SDTR_1_BIT    |
  106.                                                FCC_SDTR_ODD      |
  107.                                                FCC_SDTR_NOPARITY |
  108.                                                FCC_SDTR_8BITS    |
  109.                                                FCC_SDTR_1_16XCLK);
  110.     (*pChan->baudSet)(pChan->baudRate);  /* set default baud rate */
  111.     (*pChan->asiSeth) ((void *) (pChan->cp), FCC_TX_START);
  112.     }
  113. /******************************************************************************
  114. *
  115. * mb86940Ioctl - special device control
  116. *
  117. * RETURNS: OK on success, EIO on device error, ENOSYS on unsupported
  118. *          request.
  119. *
  120. * NOTE:  Both serial ports use the output of timer 3 for the baud clock.
  121. * Therefore, both ports will be set for the same baud rate.
  122. */
  123. static STATUS mb86940Ioctl
  124.     (
  125.     MB86940_CHAN *pChan,     /* device to control */
  126.     int request,      /* request code */
  127.     int arg      /* some argument */
  128.     )
  129.     {
  130.     int oldlevel;
  131.     STATUS status = EIO;
  132.     switch (request)
  133. {
  134. case SIO_BAUD_SET:
  135.             oldlevel = intLock();
  136.     if ( (*pChan->baudSet) (arg) == OK )
  137. {
  138. status = OK;
  139. pChan->baudRate = arg;
  140. }
  141.             intUnlock(oldlevel);
  142.     break;
  143.         case SIO_BAUD_GET:
  144.             *(int *)arg = pChan->baudRate;
  145.             status = OK;
  146.             break;
  147.         case SIO_MODE_SET:
  148.             if (!(arg == SIO_MODE_POLL || arg == SIO_MODE_INT))
  149.                 break;
  150.             oldlevel = intLock();
  151.             /* set to either POLL mode or INT mode */
  152.             if (arg == SIO_MODE_POLL)
  153. {
  154.                 (*pChan->intDisable) (pChan->rxIntLevel);
  155. (*pChan->intDisable) (pChan->txIntLevel);
  156. }
  157.             else
  158. {
  159.                 (*pChan->intEnable) (pChan->rxIntLevel);
  160. (*pChan->intEnable) (pChan->txIntLevel);
  161. }
  162.             pChan->channelMode = arg;
  163.             intUnlock(oldlevel);
  164.             status = OK;
  165.             break;
  166.         case SIO_MODE_GET:
  167.             *(int *)arg = pChan->channelMode;
  168.             status = OK;
  169.             break;
  170.         case SIO_AVAIL_MODES_GET:
  171.             *(int *)arg = SIO_MODE_INT | SIO_MODE_POLL;
  172.             status = OK;
  173.             break; 
  174.         default:
  175.             status = ENOSYS;
  176.             break;
  177.         }
  178.     return (status);
  179.  
  180.     }
  181. /******************************************************************************
  182. *
  183. * mb86940IntRx - handle a receiver interrupt
  184. *
  185. * RETURNS: N/A
  186. *
  187. * NOMANUAL
  188. */
  189. void mb86940IntRx
  190.     (
  191.     MB86940_CHAN *pChan 
  192.     )
  193.     {
  194.     char ch;
  195.     ch = (char) (*pChan->asiGeth)((void *)(pChan->dp));
  196.     (*pChan->putRcvChar)(pChan->putRcvArg,ch);
  197.     }
  198. /******************************************************************************
  199. *
  200. * mb86940IntTx - handle a transmitter interrupt
  201. *
  202. * If there is another character to be transmitted, it sends it.  If
  203. * not, we just simply exit.        
  204. *
  205. * RETURNS: N/A
  206. *
  207. * NOMANUAL
  208. */
  209. void mb86940IntTx
  210.     (
  211.     MB86940_CHAN *pChan 
  212.     )
  213.     {
  214.     char outChar;
  215.     if ( ((*pChan->getTxChar) (pChan->getTxArg, &outChar) == OK) )
  216. (*pChan->asiSeth)((void *)(pChan->dp),outChar);
  217.     }
  218. /******************************************************************************
  219. *
  220. * mb86940Startup - transmitter startup routine
  221. *
  222. * Call interrupt level character output routine for SPARClite UART.
  223. */
  224. static int mb86940Startup
  225.     (
  226.     MB86940_CHAN *pChan /* ty device to start up */
  227.     )
  228.     {
  229.     char outChar;
  230.     /*
  231.      * if a character is available send it, the IRQ
  232.      * routine will send the rest.
  233.      */
  234.     if ((pChan->channelMode == SIO_MODE_INT) &&
  235. ( (*pChan->getTxChar) (pChan->getTxArg, &outChar) == OK) )
  236. (*pChan->asiSeth) ((void *)(pChan->dp), outChar);
  237.     return (OK);
  238.     }
  239. /******************************************************************************
  240. *
  241. * mb86940PTxChar - output a character in polled mode.
  242. *
  243. * RETURNS: OK if a character arrived, ERROR on device error, EAGAIN
  244. *          if the output buffer if full.
  245. */
  246. static int mb86940PTxChar 
  247.     (
  248.     MB86940_CHAN * pChan,
  249.     char ch
  250.     )
  251.     {
  252.     /* wait for Tx empty */
  253.     if ( ((*pChan->asiGeth) ((void *)pChan->cp) & FCC_SDTR_STAT_TRDY) == 0 )
  254.         return (EAGAIN);
  255.        
  256.     (*pChan->asiSeth) ((void *)pChan->dp,ch);
  257.     return (OK); 
  258.     }
  259. /******************************************************************************
  260. *
  261. * mb86940PRxChar - poll the device for input.
  262. *
  263. * RETURNS: OK if a character arrived, ERROR on device error, EAGAIN
  264. *          if the input buffer if empty.
  265. */
  266. static int mb86940PRxChar 
  267.     (
  268.     MB86940_CHAN * pChan,
  269.     char *ch
  270.     )
  271.     {
  272.     /* check for Rx char */
  273.     if ( !( (*pChan->asiGeth)((void *)pChan->cp) & FCC_SDTR_STAT_RRDY) )
  274.         return(EAGAIN);
  275.     *ch = (*pChan->asiGeth)((void *)pChan->dp);
  276.     return(OK);
  277.     }