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

VxWorks

开发平台:

C/C++

  1. /* ixp425Gpio.c - Intel IXP425 GPIO source file */
  2. /* Copyright 2002 Wind River Systems, Inc. */
  3. /*
  4. modification history
  5. --------------------
  6. 01a,05jun02,jb  initial version...
  7. */
  8. /*
  9. DESCRIPTION
  10. This is the driver for the Intel IXP425 GPIO controller. This device has a total of
  11. 16 pins; each of which can be programmed as either an input or output.
  12. When programmed as an input a pin can be used as an interrupt source. Each pin can 
  13. detect interrupts as active high, active low, rising edge, falling edge, or 
  14. transitional. 
  15. In addition, two of the pins can be programmed to provide a user programmable frequency 
  16. source. Available clock frequencies are a fraction of the 66MHz peripheral bus clock,
  17. and range from 33MHz to 4.4Mhz.
  18. Each pin is also capable of driving external LEDs.
  19. USAGE
  20. To check and clear an interrupt signalled through the GPIO:
  21. if (ixp425GpioIntStatusGet(line, &status) == OK) 
  22. {
  23. if (status == TRUE) Interrupt pending
  24.         {
  25. Call your ISR here 
  26.         }
  27. ixp425GPIOIntStatusClear(line);  Clear interrupt
  28. }
  29. To configure the GPIO as a clock source:
  30. if (ixp425GPIOLineConfig(IXP425_GPIO_CLK0_PIN, IXP425_GPIO_OUT) == OK)
  31. {
  32. if (ixp425GpioClockSet(IXP425_GPIO_CLK_0, IXP425_GPIO_33_MHZ) == OK) 
  33. {
  34. ixp425GPIOClockEnable(IXP425_GPIO_CLK_0, TRUE);
  35. }
  36. }
  37. INCLUDE FILES: ixp425Gpio.h
  38. SEE ALSO:
  39. .I "Ixp425 Data Sheet,"
  40. */
  41. /* includes */
  42. #include "vxWorks.h"
  43. #include "intLib.h"
  44. #include "errnoLib.h"
  45. #include "errno.h"
  46. #include "stdio.h"
  47. #include "ixp425Gpio.h"
  48. /* defines */
  49. #define IXP425_GPIO_INTSTYLE_MASK 0x7C  /* Bits [6:2] define interrupt style */
  50. #define IXP425_GPIO_REG_WRITE(regPtr,val) 
  51. (*((volatile UINT32 *)(regPtr)) = (val))
  52. #define IXP425_GPIO_REG_READ(regPtr,res) 
  53. ((res) = *(volatile UINT32 *)(regPtr))
  54. /* Interrupt styles, these refer to actual values used in reg */
  55. #define IXP425_GPIO_STYLE_ACTIVE_HIGH (0x0)
  56. #define IXP425_GPIO_STYLE_ACTIVE_LOW (0x1)
  57. #define IXP425_GPIO_STYLE_RISING_EDGE (0x2)
  58. #define IXP425_GPIO_STYLE_FALLING_EDGE (0x3)
  59. #define IXP425_GPIO_STYLE_TRANSITIONAL (0x4)
  60. /* Mask used to clear interrupt styles */
  61. #define IXP425_GPIO_STYLE_CLEAR (0x7)
  62. #define IXP425_GPIO_STYLE_SIZE (3)
  63. #define IXP425_GPIO_CLK0_ENABLE (0x100)
  64. #define IXP425_GPIO_CLK1_ENABLE (0x1000000)
  65. /* Left shift values to set clock terminal count (TC) and duty cycle (DC)*/
  66. #define IXP425_GPIO_CLK0TC_LSH (4)
  67. #define IXP425_GPIO_CLK1TC_LSH (20)
  68. #define IXP425_GPIO_CLK0DC_LSH (0)
  69. #define IXP425_GPIO_CLK1DC_LSH (16)
  70. /******************************************************************************
  71. *
  72. * ixp425GPIOLineConfig - configure a GPIO pin
  73. *
  74. * This routine configures a GPIO pin/line for use as either an input or output.
  75. *
  76. * RETURNS: OK when line is successfully configured; ERROR if the line number
  77. *    passed is out of range, or an unknown style is requested for an
  78. *    interrupt. 
  79. */
  80. STATUS ixp425GPIOLineConfig (UINT8 lineNo, UINT32 style)
  81.     {
  82.     volatile UINT32 enableReg;
  83.     volatile UINT32 styleReg;
  84.     volatile UINT32 intReg;
  85.     UINT32 intStyle;
  86.     IXP425_GPIO_KEYDECLARE;
  87.     if (lineNo > IXP425_GPIO_PIN_MAX)
  88.         return (ERROR);
  89.     IXP425_GPIO_REG_READ(IXP425_GPIO_GPOER, enableReg);
  90.     if (style & IXP425_GPIO_OUT)
  91.         {
  92. enableReg &= ~(0x1 << lineNo);
  93. }
  94.     else if (style & IXP425_GPIO_IN)
  95. {     
  96. switch (style & IXP425_GPIO_INTSTYLE_MASK)
  97.     {
  98.     case (IXP425_GPIO_ACTIVE_HIGH):
  99.         intStyle = IXP425_GPIO_STYLE_ACTIVE_HIGH; break;
  100.        
  101.     case (IXP425_GPIO_ACTIVE_LOW):
  102. intStyle = IXP425_GPIO_STYLE_ACTIVE_LOW; break;
  103.     case (IXP425_GPIO_RISING_EDGE):
  104. intStyle = IXP425_GPIO_STYLE_RISING_EDGE; break;
  105.     case (IXP425_GPIO_FALLING_EDGE):
  106. intStyle = IXP425_GPIO_STYLE_FALLING_EDGE; break;
  107.     case (IXP425_GPIO_TRANSITIONAL):
  108. intStyle = IXP425_GPIO_STYLE_TRANSITIONAL; break; 
  109.     default:
  110. intStyle = IXP425_GPIO_STYLE_ACTIVE_HIGH; break;
  111.     }
  112. enableReg |= (0x1 << lineNo);
  113.         IXP425_GPIO_INTLOCK (intKey);
  114. if(lineNo >= 8) /* pins 8-15 */
  115.     {
  116.     lineNo -= 8;
  117.     intReg = IXP425_GPIO_GPIT2R;
  118.     }
  119. else /* pins 0-7 */
  120.     {
  121.     intReg = IXP425_GPIO_GPIT1R;
  122.     }
  123.         /* Clear the style for the appropriate pin */
  124. IXP425_GPIO_REG_READ(intReg, styleReg);
  125. styleReg &= ~(IXP425_GPIO_STYLE_CLEAR << (lineNo*IXP425_GPIO_STYLE_SIZE));
  126. IXP425_GPIO_REG_WRITE(intReg, styleReg);
  127. /* Set the new style */
  128. IXP425_GPIO_REG_READ(intReg, styleReg);
  129. styleReg |= (intStyle << (lineNo*IXP425_GPIO_STYLE_SIZE));
  130. IXP425_GPIO_REG_WRITE(intReg, styleReg);
  131. IXP425_GPIO_INTUNLOCK (intKey);
  132. }
  133.     else /* Unknown style options */
  134. {
  135. return (ERROR);
  136. }
  137.     IXP425_GPIO_REG_WRITE(IXP425_GPIO_GPOER, enableReg);
  138.     return (OK);
  139.     }
  140. /******************************************************************************
  141. *
  142. * ixp425GPIOLineGet - get the value of a GPIO pin
  143. *
  144. * RETURNS: OK when pin value is successfully retrieved; ERROR if the pin number
  145. *    passed is out of range.
  146. */
  147. STATUS ixp425GPIOLineGet (UINT8 lineNo, IXP425_GPIO_SIG *value)
  148.     {
  149.     if (lineNo > IXP425_GPIO_PIN_MAX)
  150.         return (ERROR);
  151.     if (value == NULL)
  152. return (ERROR);
  153.     *value = IXP425_GPIO_LINE_GET(lineNo);
  154.     return (OK);
  155.     }
  156. /******************************************************************************
  157. *
  158. * ixp425GPIOLineSet - set the value of a GPIO pin configured for output
  159. *
  160. * RETURNS: OK when pin is successfully set; ERROR if the pin number
  161. *    passed is out of range.
  162. */
  163. STATUS ixp425GPIOLineSet (UINT8 lineNo, IXP425_GPIO_SIG value)
  164.     {
  165.     if (lineNo > IXP425_GPIO_PIN_MAX)
  166. return (ERROR);
  167.     if (value == IXP425_GPIO_HIGH)
  168.        {
  169.        IXP425_GPIO_LINE_SET(lineNo);
  170.        }
  171.     else if (value == IXP425_GPIO_LOW)
  172.        {
  173.        IXP425_GPIO_LINE_CLEAR(lineNo);
  174.        }
  175.     return (OK);
  176.     }
  177. /******************************************************************************
  178. *
  179. * ixp425GPIOIntStatusGet - get the status of a GPIO pin interpreted as an 
  180. *    interrupt.
  181. *
  182. * RETURNS: OK when status is successfully retrieved; ERROR if the pin number
  183. *    passed is out of range.
  184. */
  185. STATUS ixp425GPIOIntStatusGet (UINT8 lineNo, BOOL *status)
  186.     {
  187.     volatile UINT32 intStatusReg;
  188.     if (lineNo > IXP425_GPIO_PIN_MAX)
  189. return (ERROR);
  190.     if (status == NULL)
  191. return (ERROR);
  192.     IXP425_GPIO_REG_READ(IXP425_GPIO_GPISR, intStatusReg);
  193.     *status = ((intStatusReg & (0x1 << lineNo)) != 0);
  194.     return (OK);
  195.     }
  196. /******************************************************************************
  197. *
  198. * ixp425GPIOIntStatusClear - clear the status of a GPIO pin interpreted as an 
  199. *      interrupt.
  200. *
  201. * RETURNS: OK if status cleared; ERROR if the pin number passed is out of range.
  202. */
  203. STATUS ixp425GPIOIntStatusClear (UINT8 lineNo)
  204.     {
  205.     UINT32 intStatusClr;
  206.     if (lineNo > IXP425_GPIO_PIN_MAX)
  207. return (ERROR);
  208.     intStatusClr = (0x1 << lineNo);
  209.     /* Write 1 to clear */
  210.     IXP425_GPIO_REG_WRITE(IXP425_GPIO_GPISR, intStatusClr);
  211.     return (OK);
  212.     }
  213. /******************************************************************************
  214. *
  215. * ixp425GPIOClockSet - Set the frequency for one of the GPIO clocks
  216. *
  217. * RETURNS: OK if clock frequency successfully set; ERROR if frequency is out
  218. *          of range, or invalid clock selected.
  219. */
  220. STATUS ixp425GPIOClockSet (IXP425_GPIO_CLK_NO clock, IXP425_GPIO_CLK_FREQ freq)
  221.     {
  222.     volatile UINT32 clkReg;
  223.     UINT32 dutyCycle;
  224.     if (freq < IXP425_GPIO_33_MHZ || freq > IXP425_GPIO_4_4_MHZ)
  225. return ERROR;
  226.     IXP425_GPIO_REG_READ(IXP425_GPIO_GPCLKR, clkReg);
  227.     
  228.     switch (clock)
  229.         {
  230. case (IXP425_GPIO_CLK_0):
  231.              {
  232.      clkReg |= (freq << IXP425_GPIO_CLK0TC_LSH);
  233.      dutyCycle = (unsigned int)(freq/2);
  234.      clkReg |= (dutyCycle << IXP425_GPIO_CLK0DC_LSH);
  235.      break;
  236.      }
  237. case (IXP425_GPIO_CLK_1):
  238.              {
  239.      clkReg |= (freq << IXP425_GPIO_CLK1TC_LSH);
  240.      dutyCycle = (unsigned int)(freq/2);
  241.      clkReg |= (dutyCycle << IXP425_GPIO_CLK1DC_LSH);
  242.      break;
  243.      }
  244.  default: /* Unknown clock selected */
  245.     return (ERROR);
  246.  }
  247.     IXP425_GPIO_REG_WRITE(IXP425_GPIO_GPCLKR, clkReg);
  248.     return (OK);
  249.     }
  250. /******************************************************************************
  251. *
  252. * ixp425GPIOClockEnable - Enable/disable a GPIO clock
  253. *
  254. * RETURNS: OK if clock successfully enabled; ERROR if unknown clock type.
  255. */
  256. STATUS ixp425GPIOClockEnable(IXP425_GPIO_CLK_NO clock, BOOL state)
  257.     {
  258.     volatile UINT32 clkReg;
  259.     IXP425_GPIO_REG_READ(IXP425_GPIO_GPCLKR, clkReg);
  260.     switch (clock)
  261.         {
  262. case (IXP425_GPIO_CLK_0):
  263.     {
  264.     if(state)
  265.         clkReg |= IXP425_GPIO_CLK0_ENABLE;
  266.     else
  267.         clkReg &= ~IXP425_GPIO_CLK0_ENABLE;
  268.     break;
  269.     }
  270. case (IXP425_GPIO_CLK_1):
  271.     {
  272.     if(state)
  273.         clkReg |= IXP425_GPIO_CLK1_ENABLE;
  274.     else
  275.         clkReg &= ~IXP425_GPIO_CLK1_ENABLE;
  276.     
  277.     break;
  278.     }
  279. default: /* Unknown clock */
  280.     return (ERROR);
  281. }
  282.     IXP425_GPIO_REG_WRITE(IXP425_GPIO_GPCLKR, clkReg);
  283.     return (OK);
  284.     }
  285. /******************************************************************************
  286. *
  287. * ixp425GPIOReset - reset the GPIO controller
  288. *
  289. * This routine resets the pins of the GPIO controller to known default settings.
  290. * The settings (defined in ixp425Gpio.h) modify how the pins are programmed
  291. * and what value they are set at. It is intended that this function be called
  292. * on a warm reset of the IXP425 device. 
  293. *
  294. * RETURNS: N/A
  295. */
  296. void ixp425GPIOReset()
  297.     {
  298.     IXP425_GPIO_KEYDECLARE;
  299.     IXP425_GPIO_INTLOCK (intKey);
  300.     IXP425_GPIO_REG_WRITE(IXP425_GPIO_GPOER, IXP425_GPIO_GPOER_DEF);
  301.     IXP425_GPIO_REG_WRITE(IXP425_GPIO_GPOUTR, IXP425_GPIO_GPOUTR_DEF);
  302.     IXP425_GPIO_REG_WRITE(IXP425_GPIO_GPIT1R, IXP425_GPIO_GPIT1R_DEF);
  303.     IXP425_GPIO_REG_WRITE(IXP425_GPIO_GPIT2R, IXP425_GPIO_GPIT2R_DEF);
  304.     IXP425_GPIO_REG_WRITE(IXP425_GPIO_GPCLKR, IXP425_GPIO_GPCLKR_DEF);
  305.     IXP425_GPIO_INTUNLOCK (intKey);
  306.     }
  307. /******************************************************************************
  308. *
  309. * ixp425GPIOShow - display current GPIO configuration
  310. *
  311. * RETURNS: N/A
  312. */
  313. void ixp425GPIOShow()
  314.     {
  315.     UINT32 pinNo;
  316.     volatile UINT32 confReg;
  317.     volatile UINT32 clkReg;
  318.     IXP425_GPIO_REG_READ(IXP425_GPIO_GPOER, confReg);
  319.     IXP425_GPIO_REG_READ(IXP425_GPIO_GPCLKR, clkReg);
  320.     printf("nPin notTypetValue");
  321.     for (pinNo=0; pinNo<=IXP425_GPIO_PIN_MAX; pinNo++)
  322. {
  323. printf("n%2ut",pinNo);
  324. if((confReg & (0x1<<pinNo)) != 0)
  325.     printf("input");
  326. else if( ((pinNo == 14) && (clkReg & IXP425_GPIO_CLK0_ENABLE)) ||
  327.          ((pinNo == 15) && (clkReg & IXP425_GPIO_CLK1_ENABLE)) )
  328.     printf("clock");
  329. else
  330.     printf("output");
  331. printf("t%d",IXP425_GPIO_LINE_GET(pinNo));
  332. }
  333.     printf("n");
  334.     }
  335. #ifdef IXP425_GPIO_NPEDEBUG
  336. /******************************************************************************
  337. *
  338. * ixp425GPIONPEDebugEnable - enable debugging of NPEs using the GPIO
  339. *
  340. * Debug signals are received from any of the three NPEs and sent through
  341. * the GPIO for monitoring on a logic analyzer.
  342. *
  343. * RETURNS: OK if NPE debugging successfully enabled; ERROR otherwise
  344. */
  345. STATUS ixp425GPIONPEDebugEnable (UINT32 npe, BOOL state)
  346.     {
  347.     volatile UINT32 npeReg;
  348.     IXP425_GPIO_REG_READ(IXP425_GPIO_GPDBSELR, npeReg);
  349.     npeReg &= (~0x3);
  350.     
  351.     switch (npe)
  352. {
  353. case IXP425_GPIO_DEBUG_NPEA:
  354.     npeReg |= IXP425_GPIO_DEBUG_NPEA; 
  355.     break;
  356. case IXP425_GPIO_DEBUG_NPEB:
  357.     npeReg |= IXP425_GPIO_DEBUG_NPEB;
  358.     break;
  359. case IXP425_GPIO_DEBUG_NPEC:
  360.     npeReg |= IXP425_GPIO_DEBUG_NPEC;
  361.     break;
  362. default:
  363.     return (ERROR);
  364. }
  365.     if (state == TRUE) /* Enable */
  366. {
  367. npeReg |= (0x1 << 2);
  368. }
  369.     else if (state == FALSE) /* Disable */
  370. {
  371. npeReg &= (~(0x1 << 2));
  372. }
  373.     IXP425_GPIO_REG_WRITE(IXP425_GPIO_GPDBSELR, npeReg);
  374.     return (OK);
  375.     }
  376. #endif /* IXP425_GPIO_NPEDEBUG */