?? ixp425gpio.c
字號:
/* ixp425Gpio.c - Intel IXP425 GPIO source file *//* Copyright 2002 Wind River Systems, Inc. *//*modification history--------------------01a,05jun02,jb initial version...*//*DESCRIPTIONThis is the driver for the Intel IXP425 GPIO controller. This device has a total of16 pins; each of which can be programmed as either an input or output.When programmed as an input a pin can be used as an interrupt source. Each pin can detect interrupts as active high, active low, rising edge, falling edge, or transitional. In addition, two of the pins can be programmed to provide a user programmable frequency source. Available clock frequencies are a fraction of the 66MHz peripheral bus clock,and range from 33MHz to 4.4Mhz.Each pin is also capable of driving external LEDs.USAGETo check and clear an interrupt signalled through the GPIO: if (ixp425GpioIntStatusGet(line, &status) == OK) { if (status == TRUE) Interrupt pending { Call your ISR here } ixp425GPIOIntStatusClear(line); Clear interrupt }To configure the GPIO as a clock source: if (ixp425GPIOLineConfig(IXP425_GPIO_CLK0_PIN, IXP425_GPIO_OUT) == OK) { if (ixp425GpioClockSet(IXP425_GPIO_CLK_0, IXP425_GPIO_33_MHZ) == OK) { ixp425GPIOClockEnable(IXP425_GPIO_CLK_0, TRUE); } }INCLUDE FILES: ixp425Gpio.hSEE ALSO:.I "Ixp425 Data Sheet,"*//* includes */#include "vxWorks.h"#include "intLib.h"#include "errnoLib.h"#include "errno.h"#include "stdio.h"#include "ixp425Gpio.h"/* defines */#define IXP425_GPIO_INTSTYLE_MASK 0x7C /* Bits [6:2] define interrupt style */#define IXP425_GPIO_REG_WRITE(regPtr,val) \ (*((volatile UINT32 *)(regPtr)) = (val))#define IXP425_GPIO_REG_READ(regPtr,res) \ ((res) = *(volatile UINT32 *)(regPtr))/* Interrupt styles, these refer to actual values used in reg */#define IXP425_GPIO_STYLE_ACTIVE_HIGH (0x0)#define IXP425_GPIO_STYLE_ACTIVE_LOW (0x1)#define IXP425_GPIO_STYLE_RISING_EDGE (0x2)#define IXP425_GPIO_STYLE_FALLING_EDGE (0x3)#define IXP425_GPIO_STYLE_TRANSITIONAL (0x4)/* Mask used to clear interrupt styles */#define IXP425_GPIO_STYLE_CLEAR (0x7)#define IXP425_GPIO_STYLE_SIZE (3)#define IXP425_GPIO_CLK0_ENABLE (0x100)#define IXP425_GPIO_CLK1_ENABLE (0x1000000)/* Left shift values to set clock terminal count (TC) and duty cycle (DC)*/#define IXP425_GPIO_CLK0TC_LSH (4)#define IXP425_GPIO_CLK1TC_LSH (20)#define IXP425_GPIO_CLK0DC_LSH (0)#define IXP425_GPIO_CLK1DC_LSH (16)/******************************************************************************** ixp425GPIOLineConfig - configure a GPIO pin** This routine configures a GPIO pin/line for use as either an input or output.** RETURNS: OK when line is successfully configured; ERROR if the line number* passed is out of range, or an unknown style is requested for an* interrupt. */STATUS ixp425GPIOLineConfig (UINT8 lineNo, UINT32 style) { volatile UINT32 enableReg; volatile UINT32 styleReg; volatile UINT32 intReg; UINT32 intStyle; IXP425_GPIO_KEYDECLARE; if (lineNo > IXP425_GPIO_PIN_MAX) return (ERROR); IXP425_GPIO_REG_READ(IXP425_GPIO_GPOER, enableReg); if (style & IXP425_GPIO_OUT) { enableReg &= ~(0x1 << lineNo); } else if (style & IXP425_GPIO_IN) { switch (style & IXP425_GPIO_INTSTYLE_MASK) { case (IXP425_GPIO_ACTIVE_HIGH): intStyle = IXP425_GPIO_STYLE_ACTIVE_HIGH; break; case (IXP425_GPIO_ACTIVE_LOW): intStyle = IXP425_GPIO_STYLE_ACTIVE_LOW; break; case (IXP425_GPIO_RISING_EDGE): intStyle = IXP425_GPIO_STYLE_RISING_EDGE; break; case (IXP425_GPIO_FALLING_EDGE): intStyle = IXP425_GPIO_STYLE_FALLING_EDGE; break; case (IXP425_GPIO_TRANSITIONAL): intStyle = IXP425_GPIO_STYLE_TRANSITIONAL; break; default: intStyle = IXP425_GPIO_STYLE_ACTIVE_HIGH; break; } enableReg |= (0x1 << lineNo); IXP425_GPIO_INTLOCK (intKey); if(lineNo >= 8) /* pins 8-15 */ { lineNo -= 8; intReg = IXP425_GPIO_GPIT2R; } else /* pins 0-7 */ { intReg = IXP425_GPIO_GPIT1R; } /* Clear the style for the appropriate pin */ IXP425_GPIO_REG_READ(intReg, styleReg); styleReg &= ~(IXP425_GPIO_STYLE_CLEAR << (lineNo*IXP425_GPIO_STYLE_SIZE)); IXP425_GPIO_REG_WRITE(intReg, styleReg); /* Set the new style */ IXP425_GPIO_REG_READ(intReg, styleReg); styleReg |= (intStyle << (lineNo*IXP425_GPIO_STYLE_SIZE)); IXP425_GPIO_REG_WRITE(intReg, styleReg); IXP425_GPIO_INTUNLOCK (intKey); } else /* Unknown style options */ { return (ERROR); } IXP425_GPIO_REG_WRITE(IXP425_GPIO_GPOER, enableReg); return (OK); }/******************************************************************************** ixp425GPIOLineGet - get the value of a GPIO pin** RETURNS: OK when pin value is successfully retrieved; ERROR if the pin number* passed is out of range.*/STATUS ixp425GPIOLineGet (UINT8 lineNo, IXP425_GPIO_SIG *value) { if (lineNo > IXP425_GPIO_PIN_MAX) return (ERROR); if (value == NULL) return (ERROR); *value = IXP425_GPIO_LINE_GET(lineNo); return (OK); }/******************************************************************************** ixp425GPIOLineSet - set the value of a GPIO pin configured for output** RETURNS: OK when pin is successfully set; ERROR if the pin number* passed is out of range.*/STATUS ixp425GPIOLineSet (UINT8 lineNo, IXP425_GPIO_SIG value) { if (lineNo > IXP425_GPIO_PIN_MAX) return (ERROR); if (value == IXP425_GPIO_HIGH) { IXP425_GPIO_LINE_SET(lineNo); } else if (value == IXP425_GPIO_LOW) { IXP425_GPIO_LINE_CLEAR(lineNo); } return (OK); }/******************************************************************************** ixp425GPIOIntStatusGet - get the status of a GPIO pin interpreted as an * interrupt.** RETURNS: OK when status is successfully retrieved; ERROR if the pin number* passed is out of range.*/STATUS ixp425GPIOIntStatusGet (UINT8 lineNo, BOOL *status) { volatile UINT32 intStatusReg; if (lineNo > IXP425_GPIO_PIN_MAX) return (ERROR); if (status == NULL) return (ERROR); IXP425_GPIO_REG_READ(IXP425_GPIO_GPISR, intStatusReg); *status = ((intStatusReg & (0x1 << lineNo)) != 0); return (OK); }/******************************************************************************** ixp425GPIOIntStatusClear - clear the status of a GPIO pin interpreted as an * interrupt.** RETURNS: OK if status cleared; ERROR if the pin number passed is out of range.*/STATUS ixp425GPIOIntStatusClear (UINT8 lineNo) { UINT32 intStatusClr; if (lineNo > IXP425_GPIO_PIN_MAX) return (ERROR); intStatusClr = (0x1 << lineNo); /* Write 1 to clear */ IXP425_GPIO_REG_WRITE(IXP425_GPIO_GPISR, intStatusClr); return (OK); }/******************************************************************************** ixp425GPIOClockSet - Set the frequency for one of the GPIO clocks** RETURNS: OK if clock frequency successfully set; ERROR if frequency is out* of range, or invalid clock selected.*/STATUS ixp425GPIOClockSet (IXP425_GPIO_CLK_NO clock, IXP425_GPIO_CLK_FREQ freq) { volatile UINT32 clkReg; UINT32 dutyCycle; if (freq < IXP425_GPIO_33_MHZ || freq > IXP425_GPIO_4_4_MHZ) return ERROR; IXP425_GPIO_REG_READ(IXP425_GPIO_GPCLKR, clkReg); switch (clock) { case (IXP425_GPIO_CLK_0): { clkReg |= (freq << IXP425_GPIO_CLK0TC_LSH); dutyCycle = (unsigned int)(freq/2); clkReg |= (dutyCycle << IXP425_GPIO_CLK0DC_LSH); break; } case (IXP425_GPIO_CLK_1): { clkReg |= (freq << IXP425_GPIO_CLK1TC_LSH); dutyCycle = (unsigned int)(freq/2); clkReg |= (dutyCycle << IXP425_GPIO_CLK1DC_LSH); break; } default: /* Unknown clock selected */ return (ERROR); } IXP425_GPIO_REG_WRITE(IXP425_GPIO_GPCLKR, clkReg); return (OK); }/******************************************************************************** ixp425GPIOClockEnable - Enable/disable a GPIO clock** RETURNS: OK if clock successfully enabled; ERROR if unknown clock type.*/STATUS ixp425GPIOClockEnable(IXP425_GPIO_CLK_NO clock, BOOL state) { volatile UINT32 clkReg; IXP425_GPIO_REG_READ(IXP425_GPIO_GPCLKR, clkReg); switch (clock) { case (IXP425_GPIO_CLK_0): { if(state) clkReg |= IXP425_GPIO_CLK0_ENABLE; else clkReg &= ~IXP425_GPIO_CLK0_ENABLE; break; } case (IXP425_GPIO_CLK_1): { if(state) clkReg |= IXP425_GPIO_CLK1_ENABLE; else clkReg &= ~IXP425_GPIO_CLK1_ENABLE; break; } default: /* Unknown clock */ return (ERROR); } IXP425_GPIO_REG_WRITE(IXP425_GPIO_GPCLKR, clkReg); return (OK); }/******************************************************************************** ixp425GPIOReset - reset the GPIO controller** This routine resets the pins of the GPIO controller to known default settings.* The settings (defined in ixp425Gpio.h) modify how the pins are programmed* and what value they are set at. It is intended that this function be called* on a warm reset of the IXP425 device. ** RETURNS: N/A*/void ixp425GPIOReset() { IXP425_GPIO_KEYDECLARE; IXP425_GPIO_INTLOCK (intKey); IXP425_GPIO_REG_WRITE(IXP425_GPIO_GPOER, IXP425_GPIO_GPOER_DEF); IXP425_GPIO_REG_WRITE(IXP425_GPIO_GPOUTR, IXP425_GPIO_GPOUTR_DEF); IXP425_GPIO_REG_WRITE(IXP425_GPIO_GPIT1R, IXP425_GPIO_GPIT1R_DEF); IXP425_GPIO_REG_WRITE(IXP425_GPIO_GPIT2R, IXP425_GPIO_GPIT2R_DEF); IXP425_GPIO_REG_WRITE(IXP425_GPIO_GPCLKR, IXP425_GPIO_GPCLKR_DEF); IXP425_GPIO_INTUNLOCK (intKey); }/******************************************************************************** ixp425GPIOShow - display current GPIO configuration** RETURNS: N/A*/void ixp425GPIOShow() { UINT32 pinNo; volatile UINT32 confReg; volatile UINT32 clkReg; IXP425_GPIO_REG_READ(IXP425_GPIO_GPOER, confReg); IXP425_GPIO_REG_READ(IXP425_GPIO_GPCLKR, clkReg); printf("\nPin no\tType\tValue"); for (pinNo=0; pinNo<=IXP425_GPIO_PIN_MAX; pinNo++) { printf("\n%2u\t",pinNo); if((confReg & (0x1<<pinNo)) != 0) printf("input"); else if( ((pinNo == 14) && (clkReg & IXP425_GPIO_CLK0_ENABLE)) || ((pinNo == 15) && (clkReg & IXP425_GPIO_CLK1_ENABLE)) ) printf("clock"); else printf("output"); printf("\t%d",IXP425_GPIO_LINE_GET(pinNo)); } printf("\n"); }#ifdef IXP425_GPIO_NPEDEBUG/******************************************************************************** ixp425GPIONPEDebugEnable - enable debugging of NPEs using the GPIO** Debug signals are received from any of the three NPEs and sent through* the GPIO for monitoring on a logic analyzer.** RETURNS: OK if NPE debugging successfully enabled; ERROR otherwise*/STATUS ixp425GPIONPEDebugEnable (UINT32 npe, BOOL state) { volatile UINT32 npeReg; IXP425_GPIO_REG_READ(IXP425_GPIO_GPDBSELR, npeReg); npeReg &= (~0x3); switch (npe) { case IXP425_GPIO_DEBUG_NPEA: npeReg |= IXP425_GPIO_DEBUG_NPEA; break; case IXP425_GPIO_DEBUG_NPEB: npeReg |= IXP425_GPIO_DEBUG_NPEB; break; case IXP425_GPIO_DEBUG_NPEC: npeReg |= IXP425_GPIO_DEBUG_NPEC; break; default: return (ERROR); } if (state == TRUE) /* Enable */ { npeReg |= (0x1 << 2); } else if (state == FALSE) /* Disable */ { npeReg &= (~(0x1 << 2)); } IXP425_GPIO_REG_WRITE(IXP425_GPIO_GPDBSELR, npeReg); return (OK); }#endif /* IXP425_GPIO_NPEDEBUG */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -