自己动手写TCC7901的GPIO驱动

//=====================================================================
//TITLE:
//    自己动手写TCC7901的GPIO驱动
//AUTHOR:
//    norains
//DATE:
//    Monday 12-July-2010
//Environment:
//    Windows CE 5.0 + TCC7901
//=====================================================================

    如果你使用的是WinCE,然后又涉及到GPIO的操作,你会很尴尬地发现,WinCE根本就没有针对于GPIO的接口。如果你想采用标准流驱动的GPIO口,很大的可能必须你自己丰衣足食,运气好一点的,或许你所使用的BSP就附带有其相应驱动。而对于TCC7901而言,很遗憾,属于前者。

 

    不过幸运的是,TCC7901对于寄存器的操作还算方便,所以写起驱动来,也并不是一件困难的事情。

 

    既然不困难,那么我们就自己动手,将TCC7901的驱动来完善吧!

 

    这篇文章假设朋友们已经对WinCE的流驱动结构有一定的了解,所以在此不对驱动的结构来进行解说,而是直奔主题。

 

    因为对于TCC7901的GPIO驱动来说,主要功能无非是设置或获取工作方式以及相应的数据,故我们对于控制码的定义可以定义为如下五种:

enum GPIOCtrl { //设置工作的模式 IOCTL_GPIO_SET_DIRECTION = 0x00, //获取工作的模式 IOCTL_GPIO_GET_DIRECTION = 0x01, //将输入的PIN作为GPIO口功能 IOCTL_GPIO_SET_FUNCTION_GPIO = 0x02, //设置数据为高,该控制码只有工作模式为输出时才有笑 IOCTL_GPIO_SET_DATA = 0x03, //设置数据为低,该控制码只有工作模式为输出时才有笑 IOCTL_GPIO_CLEAR_DATA = 0x04, //获取GPIO的数据 IOCTL_GPIO_GET_DATA = 0x05, };  


 控制码有了,那么我们的控制函数就可以简单的如此:
extern "C" BOOL PIO_IOControl( DWORD Handle, DWORD dwIoControlCode, PBYTE pInBuf, DWORD nInBufSize, PBYTE pOutBuf, DWORD nOutBufSize, PDWORD pBytesReturned ) { switch(dwIoControlCode) { case IOCTL_GPIO_SET_DIRECTION: { if(sizeof(GPIOCtrlData) > nInBufSize) { return FALSE; } GPIOCtrlData *pCtrlData = reinterpret_cast<GPIOCtrlData *>(pInBuf); return GPIO_SetDirection(pCtrlData->pin,pCtrlData->drct); } case IOCTL_GPIO_GET_DIRECTION: { if(sizeof(GPIOPin) > nInBufSize || sizeof(GPIODirection) > nOutBufSize) { return FALSE; } *(reinterpret_cast<GPIODirection *>(pOutBuf)) = GPIO_GetDirection(*(reinterpret_cast<GPIOPin *>(pInBuf))); return TRUE; } case IOCTL_GPIO_SET_FUNCTION_GPIO: { if(sizeof(GPIOPin) > nInBufSize) { return FALSE; } return GPIO_SetFuncGPIO(*(reinterpret_cast<GPIOPin *>(pInBuf))); } case IOCTL_GPIO_SET_DATA: { if(sizeof(GPIOPin) > nInBufSize) { return FALSE; } return GPIO_SetData(*(reinterpret_cast<GPIOPin *>(pInBuf))); } case IOCTL_GPIO_CLEAR_DATA: { if(sizeof(GPIOPin) > nInBufSize) { return FALSE; } return GPIO_ClearData(*(reinterpret_cast<GPIOPin *>(pInBuf))); } case IOCTL_GPIO_GET_DATA: { if(sizeof(GPIOPin) > nInBufSize || sizeof(GPIOInputData) > nOutBufSize) { return FALSE; } GPIOInputData inputData = GPIO_GetData(*(reinterpret_cast<GPIOPin *>(pInBuf))); *(reinterpret_cast<GPIOInputData *>(pOutBuf)) = inputData; if(inputData == GPIO_INPUT_HIGH || inputData == GPIO_INPUT_LOW) { return TRUE; } else { return FALSE; } } default: return FALSE; } return FALSE; }

 

 

    该函数用到了一些常量,其实和控制码一样,也是枚举类型:

//GPIO的PIN enum GPIOPin { GPIO_A00, GPIO_A01, GPIO_A02, GPIO_A03, GPIO_A04, GPIO_A05, GPIO_A06, GPIO_A07, GPIO_A08, GPIO_A09, GPIO_A10, GPIO_A11, GPIO_A12, GPIO_B00, GPIO_B01, GPIO_B02, GPIO_B03, GPIO_B04, GPIO_B05, GPIO_B06, GPIO_B07, GPIO_B08, GPIO_B09, GPIO_B10, GPIO_B11, GPIO_B12, GPIO_B13, GPIO_B14, GPIO_B15, GPIO_C00, GPIO_C01, GPIO_C02, GPIO_C03, GPIO_C04, GPIO_C05, GPIO_C06, GPIO_C07, GPIO_C08, GPIO_C09, GPIO_C10, GPIO_C11, GPIO_C12, GPIO_C13, GPIO_C14, GPIO_C15, GPIO_C16, GPIO_C17, GPIO_C18, GPIO_C19, GPIO_C20, GPIO_C21, GPIO_C22, GPIO_C23, GPIO_C24, GPIO_C25, GPIO_C26, GPIO_C27, GPIO_C28, GPIO_C29, GPIO_C30, GPIO_C31, GPIO_D00, GPIO_D01, GPIO_D02, GPIO_D03, GPIO_D04, GPIO_D05, GPIO_D06, GPIO_D07, GPIO_D08, GPIO_D09, GPIO_D10, GPIO_D11, GPIO_D12, GPIO_E00, GPIO_E01, GPIO_E02, GPIO_E03, GPIO_E04, GPIO_E05, GPIO_E06, GPIO_E07, GPIO_E08, GPIO_E09, GPIO_E10, GPIO_E11, GPIO_E12, GPIO_E13, GPIO_E14, GPIO_E15, GPIO_E16, GPIO_E17, GPIO_E18, GPIO_E19, GPIO_E20, GPIO_E21, GPIO_E22, GPIO_E23, GPIO_E24, GPIO_E25, GPIO_E26, GPIO_E27, GPIO_E28, GPIO_E29, GPIO_E30, GPIO_E31, GPIO_F00, GPIO_F01, GPIO_F02, GPIO_F03, GPIO_F04, GPIO_F05, GPIO_F06, GPIO_F07, GPIO_F08, GPIO_F09, GPIO_F10, GPIO_F11, GPIO_F12, GPIO_F13, GPIO_F14, GPIO_F15, GPIO_F16, GPIO_F17, GPIO_F18, GPIO_F19, GPIO_F20, GPIO_F21, GPIO_F22, GPIO_F23, GPIO_F24, GPIO_F25, GPIO_F26, GPIO_F27, GPIO_F28, GPIO_F29, /* Only used as input mode */ GPIO_F30, /* Only used as input mode */ GPIO_F31 /* Only used as input mode */ }; //GPIO的模式 enum GPIODirection { GPIO_DIRCT_INPUT = 0, GPIO_DIRCT_OUTPUT = 1, GPIO_DIRCT_UNKNOW = 3 }; //GPIO的输入数据 enum GPIOInputData { GPIO_INPUT_LOW = 0, GPIO_INPUT_HIGH = 1, GPIO_INPUT_UNKNOW = 3, }; struct GPIOCtrlData { enum GPIOPin pin; enum GPIODirection drct; };

 

 

    我们先回头,看看IOControl的所调用的GPIO_SetFuncGPIO函数:
BOOL GPIO_SetFuncGPIO(GPIOPin gpioPin) { switch(gpioPin) { case GPIO_A00: case GPIO_A01: SET_FUNC_AS_GPIO_A00_TO_A01(); break; case GPIO_A02: SET_FUNC_AS_GPIO_A02(); break; case GPIO_A03: SET_FUNC_AS_GPIO_A03(); break; case GPIO_A04: SET_FUNC_AS_GPIO_A04(); break; case GPIO_A05: SET_FUNC_AS_GPIO_A05(); break; case GPIO_A06: SET_FUNC_AS_GPIO_A06(); break; case GPIO_A07: SET_FUNC_AS_GPIO_A07(); break; case GPIO_A08: SET_FUNC_AS_GPIO_A08(); break; case GPIO_A09: SET_FUNC_AS_GPIO_A09(); break; case GPIO_A10: SET_FUNC_AS_GPIO_A10(); break; case GPIO_A11: SET_FUNC_AS_GPIO_A11(); break; case GPIO_A12: SET_FUNC_AS_GPIO_A12(); break; case GPIO_B00: SET_FUNC_AS_GPIO_B00(); break; case GPIO_B01: SET_FUNC_AS_GPIO_B01(); break; case GPIO_B02: SET_FUNC_AS_GPIO_B02(); break; case GPIO_B03: SET_FUNC_AS_GPIO_B03(); break; case GPIO_B04: SET_FUNC_AS_GPIO_B04(); break; case GPIO_B05: SET_FUNC_AS_GPIO_B05(); break; case GPIO_B06: SET_FUNC_AS_GPIO_B06(); break; case GPIO_B07: SET_FUNC_AS_GPIO_B07(); break; case GPIO_B08: SET_FUNC_AS_GPIO_B08(); break; case GPIO_B09: SET_FUNC_AS_GPIO_B09(); break; case GPIO_B10: SET_FUNC_AS_GPIO_B10(); break; case GPIO_B11: SET_FUNC_AS_GPIO_B11(); break; case GPIO_B12: SET_FUNC_AS_GPIO_B12(); break; case GPIO_B13: SET_FUNC_AS_GPIO_B13(); break; case GPIO_B14: SET_FUNC_AS_GPIO_B14(); break; case GPIO_B15: SET_FUNC_AS_GPIO_B15(); break; case GPIO_C00: case GPIO_C01: case GPIO_C02: case GPIO_C03: case GPIO_C04: case GPIO_C05: case GPIO_C06: case GPIO_C07: SET_FUNC_AS_GPIO_C00_TO_C07(); break; case GPIO_C08: case GPIO_C09: case GPIO_C10: case GPIO_C11: case GPIO_C12: case GPIO_C13: case GPIO_C14: case GPIO_C15: SET_FUNC_AS_GPIO_C08_TO_C15(); break; case GPIO_C16: case GPIO_C17: SET_FUNC_AS_GPIO_C16_TO_C17(); break; case GPIO_C18: case GPIO_C19: SET_FUNC_AS_GPIO_C18_TO_C19(); break; case GPIO_C20: SET_FUNC_AS_GPIO_C20(); break; case GPIO_C21: SET_FUNC_AS_GPIO_C21(); break; case GPIO_C22: SET_FUNC_AS_GPIO_C22(); break; case GPIO_C23: SET_FUNC_AS_GPIO_C23(); break; case GPIO_C24: SET_FUNC_AS_GPIO_C24(); break; case GPIO_C25: SET_FUNC_AS_GPIO_C25(); break; case GPIO_C26: SET_FUNC_AS_GPIO_C26(); break; case GPIO_C27: SET_FUNC_AS_GPIO_C27(); break; case GPIO_C28: SET_FUNC_AS_GPIO_C28(); break; case GPIO_C29: SET_FUNC_AS_GPIO_C29(); break; case GPIO_C30: SET_FUNC_AS_GPIO_C30(); break; case GPIO_C31: SET_FUNC_AS_GPIO_C31(); break; case GPIO_D00: SET_FUNC_AS_GPIO_D00(); break; case GPIO_D01: SET_FUNC_AS_GPIO_D01(); break; case GPIO_D02: SET_FUNC_AS_GPIO_D02(); break; case GPIO_D03: SET_FUNC_AS_GPIO_D03(); break; case GPIO_D04: SET_FUNC_AS_GPIO_D04(); break; case GPIO_D05: SET_FUNC_AS_GPIO_D05(); break; case GPIO_D06: SET_FUNC_AS_GPIO_D06(); break; case GPIO_D07: SET_FUNC_AS_GPIO_D07(); break; case GPIO_D08: SET_FUNC_AS_GPIO_D08(); break; case GPIO_D09: SET_FUNC_AS_GPIO_D09(); break; case GPIO_D10: SET_FUNC_AS_GPIO_D10(); break; case GPIO_D11: SET_FUNC_AS_GPIO_D11(); break; case GPIO_D12: SET_FUNC_AS_GPIO_D12(); break; case GPIO_E00: SET_FUNC_AS_GPIO_E00(); break; case GPIO_E01: SET_FUNC_AS_GPIO_E01(); break; case GPIO_E02: SET_FUNC_AS_GPIO_E02(); break; case GPIO_E03: SET_FUNC_AS_GPIO_E03(); break; case GPIO_E04: SET_FUNC_AS_GPIO_E04(); break; case GPIO_E05: SET_FUNC_AS_GPIO_E05(); break; case GPIO_E06: SET_FUNC_AS_GPIO_E06(); break; case GPIO_E07: SET_FUNC_AS_GPIO_E07(); break; case GPIO_E08: SET_FUNC_AS_GPIO_E08(); break; case GPIO_E09: SET_FUNC_AS_GPIO_E09(); break; case GPIO_E10: SET_FUNC_AS_GPIO_E10(); break; case GPIO_E11: SET_FUNC_AS_GPIO_E11(); break; case GPIO_E12: SET_FUNC_AS_GPIO_E12(); break; case GPIO_E13: SET_FUNC_AS_GPIO_E13(); break; case GPIO_E14: SET_FUNC_AS_GPIO_E14(); break; case GPIO_E15: SET_FUNC_AS_GPIO_E15(); break; case GPIO_E16: SET_FUNC_AS_GPIO_E16(); break; case GPIO_E17: SET_FUNC_AS_GPIO_E17(); break; case GPIO_E18: SET_FUNC_AS_GPIO_E18(); break; case GPIO_E19: SET_FUNC_AS_GPIO_E19(); break; case GPIO_E20: SET_FUNC_AS_GPIO_E20(); break; case GPIO_E21: SET_FUNC_AS_GPIO_E21(); break; case GPIO_E22: SET_FUNC_AS_GPIO_E22(); break; case GPIO_E23: SET_FUNC_AS_GPIO_E23(); break; case GPIO_E24: SET_FUNC_AS_GPIO_E24(); break; case GPIO_E25: SET_FUNC_AS_GPIO_E25(); break; case GPIO_E26: SET_FUNC_AS_GPIO_E26(); break; case GPIO_E27: SET_FUNC_AS_GPIO_E27(); break; case GPIO_E28: SET_FUNC_AS_GPIO_E28(); break; case GPIO_E29: SET_FUNC_AS_GPIO_E29(); break; case GPIO_E30: SET_FUNC_AS_GPIO_E30(); break; case GPIO_E31: SET_FUNC_AS_GPIO_E31(); break; case GPIO_F00: SET_FUNC_AS_GPIO_F00(); break; case GPIO_F01: SET_FUNC_AS_GPIO_F01(); break; case GPIO_F02: SET_FUNC_AS_GPIO_F02(); break; case GPIO_F03: SET_FUNC_AS_GPIO_F03(); break; case GPIO_F04: SET_FUNC_AS_GPIO_F04(); break; case GPIO_F05: SET_FUNC_AS_GPIO_F05(); break; case GPIO_F06: SET_FUNC_AS_GPIO_F06(); break; case GPIO_F07: SET_FUNC_AS_GPIO_F07(); break; case GPIO_F08: case GPIO_F09: case GPIO_F10: case GPIO_F11: SET_FUNC_AS_GPIO_F08_TO_F11(); break; case GPIO_F12: case GPIO_F13: case GPIO_F14: case GPIO_F15: SET_FUNC_AS_GPIO_F12_TO_F15(); break; case GPIO_F16: case GPIO_F17: SET_FUNC_AS_GPIO_F16_TO_F17(); break; case GPIO_F18: case GPIO_F19: case GPIO_F21: case GPIO_F22: case GPIO_F23: SET_FUNC_AS_GPIO_F18_TO_F19_F21_TO_F23(); break; case GPIO_F20: SET_FUNC_AS_GPIO_F20(); break; case GPIO_F24: SET_FUNC_AS_GPIO_F24(); break; case GPIO_F25: SET_FUNC_AS_GPIO_F25(); break; case GPIO_F26: SET_FUNC_AS_GPIO_F26(); break; case GPIO_F27: SET_FUNC_AS_GPIO_F27(); break; case GPIO_F28: SET_FUNC_AS_GPIO_F28(); break; case GPIO_F29: case GPIO_F30: case GPIO_F31: SET_FUNC_AS_GPIO_F29_TO_F31(); break; } return TRUE; }

 

    不知道大家看了,是不是觉得有点恐怖,一大版的case。但其实这也没办法,因为这些GPIO口的功能设置,每个之间基本上不存在相似性,所以只能通过case这种土办法。

 

  虽然在这函数中,我们看到了函数的调用,但其实际上却是一堆宏定义而已:
  #define SET_FUNC_AS_GPIO_A00_TO_A01() (BITCSET(HwPORTCFG11,HwPORTCFG11_GPIOA0(0xFUL),HwPORTCFG11_GPIOA0(0))) #define SET_FUNC_AS_GPIO_A02() (BITCSET(HwPORTCFG4,HwPORTCFG4_GPIOA2(0xFUL),HwPORTCFG4_GPIOA2(0))) #define SET_FUNC_AS_GPIO_A03() (BITCSET(HwPORTCFG4,HwPORTCFG4_GPIOA3(0xFUL),HwPORTCFG4_GPIOA3(0))) #define SET_FUNC_AS_GPIO_A04() (BITCSET(HwPORTCFG4,HwPORTCFG4_GPIOA4(0xFUL),HwPORTCFG4_GPIOA4(0))) #define SET_FUNC_AS_GPIO_A05() (BITCSET(HwPORTCFG4,HwPORTCFG4_GPIOA5(0xFUL),HwPORTCFG4_GPIOA5(0))) #define SET_FUNC_AS_GPIO_A06() (BITCSET(HwPORTCFG7,HwPORTCFG7_GPIOA6(0xFUL),HwPORTCFG7_GPIOA6(0))) #define SET_FUNC_AS_GPIO_A07() (BITCSET(HwPORTCFG7,HwPORTCFG7_GPIOA7(0xFUL),HwPORTCFG7_GPIOA7(0))) #define SET_FUNC_AS_GPIO_A08() (BITCSET(HwPORTCFG7,HwPORTCFG7_GPIOA8(0xFUL),HwPORTCFG7_GPIOA8(0))) #define SET_FUNC_AS_GPIO_A09() (BITCSET(HwPORTCFG8,HwPORTCFG8_GPIOA9(0xFUL),HwPORTCFG8_GPIOA9(0))) #define SET_FUNC_AS_GPIO_A10() (BITCSET(HwPORTCFG8,HwPORTCFG8_GPIOA10(0xFUL),HwPORTCFG8_GPIOA10(0))) #define SET_FUNC_AS_GPIO_A11() (BITCSET(HwPORTCFG8,HwPORTCFG8_GPIOA11(0xFUL),HwPORTCFG8_GPIOA11(0))) #define SET_FUNC_AS_GPIO_A12() (BITCSET(HwPORTCFG8,HwPORTCFG8_GPIOA12(0xFUL),HwPORTCFG8_GPIOA12(0))) #define SET_FUNC_AS_GPIO_B00() (BITCSET(HwPORTCFG5,HwPORTCFG5_GPIOB0(0xFUL),HwPORTCFG5_GPIOB0(0))) #define SET_FUNC_AS_GPIO_B01() (BITCSET(HwPORTCFG5,HwPORTCFG5_GPIOB1(0xFUL),HwPORTCFG5_GPIOB1(0))) #define SET_FUNC_AS_GPIO_B02() (BITCSET(HwPORTCFG5,HwPORTCFG5_GPIOB2(0xFUL),HwPORTCFG5_GPIOB2(0))) #define SET_FUNC_AS_GPIO_B03() (BITCSET(HwPORTCFG5,HwPORTCFG5_GPIOB3(0xFUL),HwPORTCFG5_GPIOB3(0))) #define SET_FUNC_AS_GPIO_B04() (BITCSET(HwPORTCFG5,HwPORTCFG5_GPIOB4(0xFUL),HwPORTCFG5_GPIOB4(0))) #define SET_FUNC_AS_GPIO_B05() (BITCSET(HwPORTCFG5,HwPORTCFG5_GPIOB5(0xFUL),HwPORTCFG5_GPIOB5(0))) #define SET_FUNC_AS_GPIO_B06() (BITCSET(HwPORTCFG5,HwPORTCFG5_GPIOB6(0xFUL),HwPORTCFG5_GPIOB6(0))) #define SET_FUNC_AS_GPIO_B07() (BITCSET(HwPORTCFG6,HwPORTCFG6_GPIOB7(0xFUL),HwPORTCFG6_GPIOB7(0))) #define SET_FUNC_AS_GPIO_B08() (BITCSET(HwPORTCFG6,HwPORTCFG6_GPIOB8(0xFUL),HwPORTCFG6_GPIOB8(0))) #define SET_FUNC_AS_GPIO_B09() (BITCSET(HwPORTCFG6,HwPORTCFG6_GPIOB9(0xFUL),HwPORTCFG6_GPIOB9(0))) #define SET_FUNC_AS_GPIO_B10() (BITCSET(HwPORTCFG6,HwPORTCFG6_GPIOB10(0xFUL),HwPORTCFG6_GPIOB10(0))) #define SET_FUNC_AS_GPIO_B11() (BITCSET(HwPORTCFG6,HwPORTCFG6_GPIOB11(0xFUL),HwPORTCFG6_GPIOB11(0))) #define SET_FUNC_AS_GPIO_B12() (BITCSET(HwPORTCFG6,HwPORTCFG6_GPIOB12(0xFUL),HwPORTCFG6_GPIOB12(0))) #define SET_FUNC_AS_GPIO_B13() (BITCSET(HwPORTCFG6,HwPORTCFG6_GPIOB13(0xFUL),HwPORTCFG6_GPIOB13(0))) #define SET_FUNC_AS_GPIO_B14() (BITCSET(HwPORTCFG6,HwPORTCFG6_GPIOB14(0xFUL),HwPORTCFG6_GPIOB14(0))) #define SET_FUNC_AS_GPIO_B15() (BITCSET(HwPORTCFG7,HwPORTCFG7_GPIOB15(0xFUL),HwPORTCFG7_GPIOB15(0))) #define SET_FUNC_AS_GPIO_C00_TO_C07() (BITCSET(HwPORTCFG0,HwPORTCFG0_LCD8(0xFUL),HwPORTCFG0_LCD8(2))) #define SET_FUNC_AS_GPIO_C08_TO_C15() (BITCSET(HwPORTCFG0,HwPORTCFG0_LCD16(0xFUL),HwPORTCFG0_LCD16(2))) #define SET_FUNC_AS_GPIO_C16_TO_C17() (BITCSET(HwPORTCFG0,HwPORTCFG0_LCD18(0xFUL),HwPORTCFG0_LCD18(2))) #define SET_FUNC_AS_GPIO_C18_TO_C19() (BITCSET(HwPORTCFG0,HwPORTCFG0_LPD19(0xFUL),HwPORTCFG0_LPD19(2))) #define SET_FUNC_AS_GPIO_C20() (BITCSET(HwPORTCFG0,HwPORTCFG0_LPD20(0xFUL),HwPORTCFG0_LPD20(2))) #define SET_FUNC_AS_GPIO_C21() (BITCSET(HwPORTCFG0,HwPORTCFG0_LPD21(0xFUL),HwPORTCFG0_LPD21(2))) #define SET_FUNC_AS_GPIO_C22() (BITCSET(HwPORTCFG0,HwPORTCFG0_LPD22(0xFUL),HwPORTCFG0_LPD22(2))) #define SET_FUNC_AS_GPIO_C23() (BITCSET(HwPORTCFG0,HwPORTCFG0_LPD23(0xFUL),HwPORTCFG0_LPD23(2))) #define SET_FUNC_AS_GPIO_C24() (BITCSET(HwPORTCFG4,HwPORTCFG4_CSN_CS0(0xFUL),HwPORTCFG4_CSN_CS0(1))) #define SET_FUNC_AS_GPIO_C25() (BITCSET(HwPORTCFG1,HwPORTCFG1_LDE(0xFUL),HwPORTCFG1_LDE(2))) #define SET_FUNC_AS_GPIO_C26() (BITCSET(HwPORTCFG1,HwPORTCFG1_LCK(0xFUL),HwPORTCFG1_LCK(2))) #define SET_FUNC_AS_GPIO_C27() (BITCSET(HwPORTCFG1,HwPORTCFG1_LHS(0xFUL),HwPORTCFG1_LHS(2))) #define SET_FUNC_AS_GPIO_C28() (BITCSET(HwPORTCFG1,HwPORTCFG1_LVS(0xFUL),HwPORTCFG1_LVS(2))) #define SET_FUNC_AS_GPIO_C29() (BITCSET(HwPORTCFG1,HwPORTCFG1_LCS(0xFUL),HwPORTCFG1_LCS(2))) #define SET_FUNC_AS_GPIO_C30() (BITCSET(HwPORTCFG1,HwPORTCFG1_GPIOC30(0xFUL),HwPORTCFG1_GPIOC30(2))) #define SET_FUNC_AS_GPIO_C31() (BITCSET(HwPORTCFG1,HwPORTCFG1_GPIOC31(0xFUL),HwPORTCFG1_GPIOC31(2))) #define SET_FUNC_AS_GPIO_D00() (BITCSET(HwPORTCFG11,HwPORTCFG11_BCLK(0xFUL),HwPORTCFG11_BCLK(1))) #define SET_FUNC_AS_GPIO_D01() (BITCSET(HwPORTCFG11,HwPORTCFG11_LRCK(0xFUL),HwPORTCFG11_LRCK(1))) #define SET_FUNC_AS_GPIO_D02() (BITCSET(HwPORTCFG11,HwPORTCFG11_MCLK(0xFUL),HwPORTCFG11_MCLK(1))) #define SET_FUNC_AS_GPIO_D03() (BITCSET(HwPORTCFG11,HwPORTCFG11_DAO(0xFUL),HwPORTCFG11_DAO(1))) #define SET_FUNC_AS_GPIO_D04() (BITCSET(HwPORTCFG11,HwPORTCFG11_DAI(0xFUL),HwPORTCFG11_DAI(1))) #define SET_FUNC_AS_GPIO_D05() (BITCSET(HwPORTCFG3,HwPORTCFG3_SCMD0(0xFUL),HwPORTCFG3_SCMD0(1))) #define SET_FUNC_AS_GPIO_D06() (BITCSET(HwPORTCFG4,HwPORTCFG4_SCLK0(0xFUL),HwPORTCFG4_SCLK0(1))) #define SET_FUNC_AS_GPIO_D07() (BITCSET(HwPORTCFG4,HwPORTCFG4_SDI0(0xFUL),HwPORTCFG4_SDI0(1))) #define SET_FUNC_AS_GPIO_D08() (BITCSET(HwPORTCFG4,HwPORTCFG4_SDO0(0xFUL),HwPORTCFG4_SDO0(1))) #define SET_FUNC_AS_GPIO_D09() (BITCSET(HwPORTCFG7,HwPORTCFG7_SCMD1(0xFUL),HwPORTCFG7_SCMD1(1))) #define SET_FUNC_AS_GPIO_D10() (BITCSET(HwPORTCFG7,HwPORTCFG7_SCLK1(0xFUL),HwPORTCFG7_SCLK1(1))) #define SET_FUNC_AS_GPIO_D11() (BITCSET(HwPORTCFG7,HwPORTCFG7_SDI1(0xFUL),HwPORTCFG7_SDI1(1))) #define SET_FUNC_AS_GPIO_D12() (BITCSET(HwPORTCFG7,HwPORTCFG7_SDO1(0xFUL),HwPORTCFG7_SDO1(1))) #define SET_FUNC_AS_GPIO_E00() (BITCSET(HwPORTCFG9,HwPORTCFG9_UTXD0(0xFUL),HwPORTCFG9_UTXD0(1))) #define SET_FUNC_AS_GPIO_E01() (BITCSET(HwPORTCFG9,HwPORTCFG9_URXD0(0xFUL),HwPORTCFG9_URXD0(1))) #define SET_FUNC_AS_GPIO_E02() (BITCSET(HwPORTCFG9,HwPORTCFG9_UCTS0(0xFUL),HwPORTCFG9_UCTS0(1))) #define SET_FUNC_AS_GPIO_E03() (BITCSET(HwPORTCFG9,HwPORTCFG9_URTS0(0xFUL),HwPORTCFG9_URTS0(1))) #define SET_FUNC_AS_GPIO_E04() (BITCSET(HwPORTCFG10,HwPORTCFG10_UTXD1(0xFUL),HwPORTCFG10_UTXD1(1))) #define SET_FUNC_AS_GPIO_E05() (BITCSET(HwPORTCFG10,HwPORTCFG10_URXD1(0xFUL),HwPORTCFG10_URXD1(1))) #define SET_FUNC_AS_GPIO_E06() (BITCSET(HwPORTCFG10,HwPORTCFG10_UCTS1(0xFUL),HwPORTCFG10_UCTS1(1))) #define SET_FUNC_AS_GPIO_E07() (BITCSET(HwPORTCFG10,HwPORTCFG10_URTS1(0xFUL),HwPORTCFG10_URTS1(1))) #define SET_FUNC_AS_GPIO_E08() (BITCSET(HwPORTCFG10,HwPORTCFG10_UTXD2(0xFUL),HwPORTCFG10_UTXD2(1))) #define SET_FUNC_AS_GPIO_E09() (BITCSET(HwPORTCFG10,HwPORTCFG10_URXD2(0xFUL),HwPORTCFG10_URXD2(1))) #define SET_FUNC_AS_GPIO_E10() (BITCSET(HwPORTCFG10,HwPORTCFG10_UTXD3(0xFUL),HwPORTCFG10_UTXD3(1))) #define SET_FUNC_AS_GPIO_E11() (BITCSET(HwPORTCFG10,HwPORTCFG10_URXD3(0xFUL),HwPORTCFG10_URXD3(1))) #define SET_FUNC_AS_GPIO_E12() (BITCSET(HwPORTCFG12,HwPORTCFG12_CPD0(0xFUL),HwPORTCFG12_CPD0(1))) #define SET_FUNC_AS_GPIO_E13() (BITCSET(HwPORTCFG12,HwPORTCFG12_CPD1(0xFUL),HwPORTCFG12_CPD1(1))) #define SET_FUNC_AS_GPIO_E14() (BITCSET(HwPORTCFG12,HwPORTCFG12_CPD2(0xFUL),HwPORTCFG12_CPD2(1))) #define SET_FUNC_AS_GPIO_E15() (BITCSET(HwPORTCFG12,HwPORTCFG12_CPD3(0xFUL),HwPORTCFG12_CPD3(1))) #define SET_FUNC_AS_GPIO_E16() (BITCSET(HwPORTCFG12,HwPORTCFG12_CPD4(0xFUL),HwPORTCFG12_CPD4(1))) #define SET_FUNC_AS_GPIO_E17() (BITCSET(HwPORTCFG13,HwPORTCFG13_CPD5(0xFUL),HwPORTCFG13_CPD5(1))) #define SET_FUNC_AS_GPIO_E18() (BITCSET(HwPORTCFG13,HwPORTCFG13_CPD6(0xFUL),HwPORTCFG13_CPD6(1))) #define SET_FUNC_AS_GPIO_E19() (BITCSET(HwPORTCFG13,HwPORTCFG13_CPD7(0xFUL),HwPORTCFG13_CPD7(1))) #define SET_FUNC_AS_GPIO_E20() (BITCSET(HwPORTCFG11,HwPORTCFG11_CCKI(0xFUL),HwPORTCFG11_CCKI(1))) #define SET_FUNC_AS_GPIO_E21() (BITCSET(HwPORTCFG12,HwPORTCFG12_CVS(0xFUL),HwPORTCFG12_CVS(1))) #define SET_FUNC_AS_GPIO_E22() (BITCSET(HwPORTCFG12,HwPORTCFG12_CHS(0xFUL),HwPORTCFG12_CHS(1))) #define SET_FUNC_AS_GPIO_E23() (BITCSET(HwPORTCFG12,HwPORTCFG12_CCKO(0xFUL),HwPORTCFG12_CCKO(1))) #define SET_FUNC_AS_GPIO_E24() (BITCSET(HwPORTCFG8,HwPORTCFG8_AIN0(0xFUL),HwPORTCFG8_AIN0(1))) #define SET_FUNC_AS_GPIO_E25() (BITCSET(HwPORTCFG8,HwPORTCFG8_AIN1(0xFUL),HwPORTCFG8_AIN1(1))) #define SET_FUNC_AS_GPIO_E26() (BITCSET(HwPORTCFG8,HwPORTCFG8_AIN2(0xFUL),HwPORTCFG8_AIN2(1))) #define SET_FUNC_AS_GPIO_E27() (BITCSET(HwPORTCFG8,HwPORTCFG8_AIN3(0xFUL),HwPORTCFG8_AIN3(1))) #define SET_FUNC_AS_GPIO_E28() (BITCSET(HwPORTCFG9,HwPORTCFG9_AIN4(0xFUL),HwPORTCFG9_AIN4(1))) #define SET_FUNC_AS_GPIO_E29() (BITCSET(HwPORTCFG9,HwPORTCFG9_AIN5(0xFUL),HwPORTCFG9_AIN5(1))) #define SET_FUNC_AS_GPIO_E30() (BITCSET(HwPORTCFG9,HwPORTCFG9_AIN6(0xFUL),HwPORTCFG9_AIN6(1))) #define SET_FUNC_AS_GPIO_E31() (BITCSET(HwPORTCFG9,HwPORTCFG9_AIN7(0xFUL),HwPORTCFG9_AIN7(1))) #define SET_FUNC_AS_GPIO_F00() (BITCSET(HwPORTCFG3,HwPORTCFG3_HPXD0(0xFUL),HwPORTCFG3_HPXD0(1))) #define SET_FUNC_AS_GPIO_F01() (BITCSET(HwPORTCFG3,HwPORTCFG3_HPXD1(0xFUL),HwPORTCFG3_HPXD1(1))) #define SET_FUNC_AS_GPIO_F02() (BITCSET(HwPORTCFG3,HwPORTCFG3_HPXD2(0xFUL),HwPORTCFG3_HPXD2(1))) #define SET_FUNC_AS_GPIO_F03() (BITCSET(HwPORTCFG3,HwPORTCFG3_HPXD3(0xFUL),HwPORTCFG3_HPXD3(1))) #define SET_FUNC_AS_GPIO_F04() (BITCSET(HwPORTCFG3,HwPORTCFG3_HPXD4(0xFUL),HwPORTCFG3_HPXD4(1))) #define SET_FUNC_AS_GPIO_F05() (BITCSET(HwPORTCFG3,HwPORTCFG3_HPXD5(0xFUL),HwPORTCFG3_HPXD5(1))) #define SET_FUNC_AS_GPIO_F06() (BITCSET(HwPORTCFG3,HwPORTCFG3_HPXD6(0xFUL),HwPORTCFG3_HPXD6(1))) #define SET_FUNC_AS_GPIO_F07() (BITCSET(HwPORTCFG2,HwPORTCFG2_HPXD7(0xFUL),HwPORTCFG2_HPXD7(1))) #define SET_FUNC_AS_GPIO_F08_TO_F11() (BITCSET(HwPORTCFG2,HwPORTCFG2_HPXD11(0xFUL),HwPORTCFG2_HPXD11(1))) #define SET_FUNC_AS_GPIO_F12_TO_F15() (BITCSET(HwPORTCFG2,HwPORTCFG2_HPXD15(0xFUL),HwPORTCFG2_HPXD15(1))) #define SET_FUNC_AS_GPIO_F16_TO_F17() (BITCSET(HwPORTCFG2,HwPORTCFG2_HPXD17(0xFUL),HwPORTCFG2_HPXD17(1))) #define SET_FUNC_AS_GPIO_F18_TO_F19_F21_TO_F23() (BITCSET(HwPORTCFG2,HwPORTCFG2_HPCTRL(0xFUL),HwPORTCFG2_HPCTRL(1))) #define SET_FUNC_AS_GPIO_F20() (BITCSET(HwPORTCFG13,HwPORTCFG13_HPCSN(0xFUL),HwPORTCFG13_HPCSN(1))) #define SET_FUNC_AS_GPIO_F24() (BITCSET(HwPORTCFG2,HwPORTCFG2_HPCSN_L(0xFUL),HwPORTCFG2_HPCSN_L(1))) #define SET_FUNC_AS_GPIO_F25() (BITCSET(HwPORTCFG2,HwPORTCFG2_GPIOF25(0xFUL),HwPORTCFG2_GPIOF25(1))) #define SET_FUNC_AS_GPIO_F26() (BITCSET(HwPORTCFG2,HwPORTCFG2_GPIOF26(0xFUL),HwPORTCFG2_GPIOF26(1))) #define SET_FUNC_AS_GPIO_F27() (BITCSET(HwPORTCFG1,HwPORTCFG1_GPIOF27(0xFUL),HwPORTCFG1_GPIOF27(1))) #define SET_FUNC_AS_GPIO_F28() (BITCSET(HwPORTCFG5,HwPORTCFG5_CSN_NOR(0xFUL),HwPORTCFG5_CSN_NOR(1))) #define SET_FUNC_AS_GPIO_F29_TO_F31() (BITCSET(HwPORTCFG11,HwPORTCFG11_BM(0xFUL),HwPORTCFG11_BM(1)))   


  这些宏定义实际上都只是针对于TCC7901寄存器的操作,这里不再对寄存器操作的原理做叙述,有兴趣的朋友可以查看我的另一篇文章:《应用程序中读写TCC7901的寄存器》(http://blog.csdn.net/norains/archive/2010/07/12/5729377.aspx)
  
  对于别的所调用的函数,代码也并不复杂:
   BOOL GPIO_SetDirection(GPIOPin gpioPin,GPIODirection gpioDirct) { volatile DWORD *pdwReg = NULL; DWORD dwSetBit = 0; //Get the direction register and bit. GetDirctReg(gpioPin,&pdwReg,dwSetBit); if(pdwReg == NULL) { return FALSE; } if(gpioDirct == GPIO_DIRCT_INPUT) { BITCLR(*pdwReg,dwSetBit); } else { if(gpioDirct >= GPIO_F29 && gpioDirct <= GPIO_F31) { //It's only used for input mode return FALSE; } BITSET(*pdwReg,dwSetBit); } return TRUE; } GPIODirection GPIO_GetDirection(GPIOPin gpioPin) { volatile DWORD *pdwReg = NULL; DWORD dwGetBit = 0; //Get the direction register and bit. GetDirctReg(gpioPin,&pdwReg,dwGetBit); if(pdwReg == NULL) { return GPIO_DIRCT_UNKNOW; } if((*pdwReg & dwGetBit) == 0) { return GPIO_DIRCT_INPUT; } else { return GPIO_DIRCT_OUTPUT; } } void GetDirctReg(GPIOPin gpioPin,volatile DWORD **ppdwReg,DWORD &dwBit) { if(gpioPin >= GPIO_A00 && gpioPin <= GPIO_A12) { *ppdwReg = &HwGPAEN; dwBit = 0x1 << (gpioPin - GPIO_A00); } else if(gpioPin >= GPIO_B00 && gpioPin <= GPIO_B15) { *ppdwReg = &HwGPBEN; dwBit = 0x1 << (gpioPin - GPIO_B00); } else if(gpioPin >= GPIO_C00 && gpioPin <= GPIO_C31) { *ppdwReg = &HwGPCEN; dwBit = 0x1 << (gpioPin - GPIO_C00); } else if(gpioPin >= GPIO_D00 && gpioPin <= GPIO_D12) { *ppdwReg = &HwGPDEN; dwBit = 0x1 << (gpioPin - GPIO_D00); } else if(gpioPin >= GPIO_E00 && gpioPin <= GPIO_E31) { *ppdwReg = &HwGPEEN; dwBit = 0x1 << (gpioPin - GPIO_E00); } else if(gpioPin >= GPIO_F00 && gpioPin <= GPIO_F31) { *ppdwReg = &HwGPFEN; dwBit = 0x1 << (gpioPin - GPIO_F00); } } BOOL GPIO_SetData(GPIOPin gpioPin) { if(GPIO_GetDirection(gpioPin) != GPIO_DIRCT_OUTPUT) { return FALSE; } volatile DWORD *pdwReg = NULL; DWORD dwSetBit = 0; //Get the direction register and bit. GetDataReg(gpioPin,&pdwReg,dwSetBit); if(pdwReg == NULL) { return FALSE; } //RETAILMSG(1,(TEXT("/r/nThe data register is:%d"),pdwReg)); //RETAILMSG(1,(TEXT("/r/nBefore setting:%d"),*pdwReg)); BITSET(*pdwReg,dwSetBit); //RETAILMSG(1,(TEXT("/r/nAfter setting:%d"),*pdwReg)); return TRUE; } BOOL GPIO_ClearData(GPIOPin gpioPin) { if(GPIO_GetDirection(gpioPin) != GPIO_DIRCT_OUTPUT) { return FALSE; } volatile DWORD *pdwReg = NULL; DWORD dwSetBit = 0; //Get the direction register and bit. GetDataReg(gpioPin,&pdwReg,dwSetBit); if(pdwReg == NULL) { return FALSE; } //RETAILMSG(1,(TEXT("/r/nThe data register is:%d"),pdwReg)); //RETAILMSG(1,(TEXT("/r/nBefore Clearing:%d"),*pdwReg)); BITCLR(*pdwReg,dwSetBit); //RETAILMSG(1,(TEXT("/r/nAfter Clearing:%d"),*pdwReg)); return TRUE; } GPIOInputData GPIO_GetData(GPIOPin gpioPin) { if(GPIO_GetDirection(gpioPin) != GPIO_DIRCT_INPUT) { return GPIO_INPUT_UNKNOW; } volatile DWORD *pdwReg = NULL; DWORD dwSetBit = 0; //Get the direction register and bit. GetDataReg(gpioPin,&pdwReg,dwSetBit); if(pdwReg == NULL) { return GPIO_INPUT_UNKNOW; } return static_cast<GPIOInputData>((*pdwReg & dwSetBit) != 0); } void GetDataReg(GPIOPin gpioPin,volatile DWORD **ppdwReg,DWORD &dwBit) { if(gpioPin >= GPIO_A00 && gpioPin <= GPIO_A12) { *ppdwReg = &HwGPADAT; dwBit = 0x1 << (gpioPin - GPIO_A00); } else if(gpioPin >= GPIO_B00 && gpioPin <= GPIO_B15) { *ppdwReg = &HwGPBDAT; dwBit = 0x1 << (gpioPin - GPIO_B00); } else if(gpioPin >= GPIO_C00 && gpioPin <= GPIO_C31) { *ppdwReg = &HwGPCDAT; dwBit = 0x1 << (gpioPin - GPIO_C00); } else if(gpioPin >= GPIO_D00 && gpioPin <= GPIO_D12) { *ppdwReg = &HwGPDDAT; dwBit = 0x1 << (gpioPin - GPIO_D00); } else if(gpioPin >= GPIO_E00 && gpioPin <= GPIO_E31) { *ppdwReg = &HwGPEDAT; dwBit = 0x1 << (gpioPin - GPIO_E00); } else if(gpioPin >= GPIO_F00 && gpioPin <= GPIO_F31) { *ppdwReg = &HwGPFDAT; dwBit = 0x1 << (gpioPin - GPIO_F00); } }   


  既然是驱动,那肯定是少不了注册表了:
  [HKEY_LOCAL_MACHINE/Drivers/Builtin/Pio]
      "Prefix"="PIO"
      "Dll"="gpio.dll"
      "Order"=dword:0
      "Index"=dword:1
  
  
  当我们编译好系统,将GPIO的驱动正确加载之后,我们就可以非常简单地通过CreateFile来对GPIO进行相应的操作啦!

你可能感兴趣的:(c,工作,null,input,WinCE,output)