📄 ddk_gpio.c
字号:
//
// Copyright (C) 2006-2007, Freescale Semiconductor, Inc. All Rights Reserved.
// THIS SOURCE CODE, AND ITS USE AND DISTRIBUTION, IS SUBJECT TO THE TERMS
// AND CONDITIONS OF THE APPLICABLE LICENSE AGREEMENT
//
//------------------------------------------------------------------------------
//
// File: ddk_gpio.c
//
// This file contains the SoC-specific DDK interface for the GPIO module.
//
//-----------------------------------------------------------------------------
#include <windows.h>
#include <ceddk.h>
#include "csp.h"
//-----------------------------------------------------------------------------
// External Functions
//-----------------------------------------------------------------------------
// External Variables
//-----------------------------------------------------------------------------
// Defines
#define GPIO_MUTEX_NAME _T("GPIO_MUTEX")
#define DDK_GPIO_LOCK() WaitForSingleObject(g_Mutex, INFINITE)
#define DDK_GPIO_UNLOCK() ReleaseMutex(g_Mutex)
//-----------------------------------------------------------------------------
// Types
//-----------------------------------------------------------------------------
// Global Variables
//-----------------------------------------------------------------------------
// Local Variables
static PCSP_GPIO_REGS g_pGPIO = NULL;
static HANDLE g_Mutex = NULL;
//-----------------------------------------------------------------------------
// Local Functions
BOOL GpioAlloc(void);
BOOL GpioDealloc(void);
//-----------------------------------------------------------------------------
//
// Function: GpioAlloc
//
// This function allocates the data structures required for interaction
// with the GPIO hardware.
//
// Parameters:
// None.
//
// Returns:
// Returns TRUE if successful, otherwise returns FALSE.
//
//-----------------------------------------------------------------------------
BOOL GpioAlloc(void)
{
BOOL rc = FALSE;
PHYSICAL_ADDRESS phyAddr;
if (g_pGPIO == NULL) {
phyAddr.QuadPart = CSP_BASE_REG_PA_GPIO;
// Map peripheral physical address to virtual address
g_pGPIO = (PCSP_GPIO_REGS) MmMapIoSpace(phyAddr, sizeof(CSP_GPIO_REGS),
FALSE);
// Check if virtual mapping failed
if (g_pGPIO == NULL) {
DBGCHK((_T("CSPDDK")), FALSE);
ERRORMSG(1, (_T("GpioAlloc: MmMapIoSpace failed!\r\n")));
goto cleanUp;
}
}
g_Mutex = CreateMutex(NULL, FALSE, GPIO_MUTEX_NAME);
if (g_Mutex == NULL) {
DBGCHK((_T("CSPDDK")), FALSE);
ERRORMSG(1, (_T("GpioAlloc: CreateMutex failed!\r\n")));
goto cleanUp;
}
rc = TRUE;
cleanUp:
if (!rc) GpioDealloc();
return rc;
}
//-----------------------------------------------------------------------------
//
// Function: GpioDealloc
//
// This function deallocates the data structures required for interaction
// with the GPIO hardware.
//
// Parameters:
// None.
//
// Returns:
// Returns TRUE.
//
//-----------------------------------------------------------------------------
BOOL GpioDealloc(void)
{
// Unmap peripheral address space
if (g_pGPIO != NULL) {
MmUnmapIoSpace(g_pGPIO, sizeof(CSP_GPIO_REGS));
g_pGPIO = NULL;
}
CloseHandle(g_Mutex);
return TRUE;
}
//-----------------------------------------------------------------------------
//
// Function: GpioConfigPriFunc
//
// This function Configures a pin set to it's PRI function.
// Disabling will cause pins to be set as input with pullup enabled.
//
// Parameters:
// pGpioCfg
// [in] Pointer to configuration.
// bEnable
// [in] Enable or disable configuration.
//
// Returns:
// TRUE if request was successful, otherwise returns false.
//
//-----------------------------------------------------------------------------
static BOOL GpioConfigPriFunc(DDK_GPIO_CFG *pGpioCfg, BOOL bEnable)
{
UINT32 mask;
GPIO_PORT port;
UINT32 puen;
if (!pGpioCfg)
return FALSE;
mask = pGpioCfg->PriConfig.PinMap;
if (mask == 0) {
DBGCHK((_T("CSPDDK")), FALSE);
ERRORMSG(1, (_T("GpioConfigPriFunc: no pins specified!\r\n")));
return FALSE;
}
port = pGpioCfg->PriConfig.Port;
puen = g_pGPIO->PORT[port].PUEN;
DDK_GPIO_LOCK();
if (bEnable) {
// Configure Primary pins
g_pGPIO->PORT[port].GIUS &= ~mask;
g_pGPIO->PORT[port].GPR &= ~mask;
// Ensure only selected pins PUEN are changed
puen &= ~mask;
puen |= (pGpioCfg->PriConfig.PuenMap & mask);
g_pGPIO->PORT[port].PUEN = puen;
} else {
// Configure as input pins, pullup enabled
g_pGPIO->PORT[port].DDIR &= ~mask;
g_pGPIO->PORT[port].PUEN |= mask;
g_pGPIO->PORT[port].GIUS |= mask;
}
DDK_GPIO_UNLOCK();
return TRUE;
}
//-----------------------------------------------------------------------------
//
// Function: GpioConfigAltFunc
//
// This function Configures a pin set to it's ALT function.
// Disabling will cause pins to be set as input with pullup enabled.
//
// Parameters:
// pGpioCfg
// [in] Pointer to configuration.
// bEnable
// [in] Enable or disable configuration.
//
// Returns:
// TRUE if request was successful, otherwise returns false.
//
//-----------------------------------------------------------------------------
static BOOL GpioConfigAltFunc(DDK_GPIO_CFG *pGpioCfg, BOOL bEnable)
{
UINT32 mask;
GPIO_PORT port;
UINT32 puen;
if (!pGpioCfg)
return FALSE;
mask = pGpioCfg->AltConfig.PinMap;
if (mask == 0) {
DBGCHK((_T("CSPDDK")), FALSE);
ERRORMSG(1, (_T("GpioConfigAltFunc: no pins specified!\r\n")));
return FALSE;
}
port = pGpioCfg->AltConfig.Port;
puen = g_pGPIO->PORT[port].PUEN;
DDK_GPIO_LOCK();
if (bEnable) {
// Configure as Alt pins
g_pGPIO->PORT[port].GIUS &= ~mask;
g_pGPIO->PORT[port].GPR |= mask;
// Ensure only selected pins PUEN are changed
puen &= ~mask;
puen |= (pGpioCfg->AltConfig.PuenMap & mask);
g_pGPIO->PORT[port].PUEN = puen;
} else {
// Configure as input pins, pullup enabled
g_pGPIO->PORT[port].GIUS |= mask;
g_pGPIO->PORT[port].DDIR &= ~mask;
g_pGPIO->PORT[port].PUEN |= mask;
}
DDK_GPIO_UNLOCK();
return TRUE;
}
//-----------------------------------------------------------------------------
//
// Function: GpioConfigModuleIOFunc
//
// This function Configures a pin set to it's Module IO function.
// Disabling will cause pins to be set as input with pullup enabled.
//
// Parameters:
// pGpioCfg
// [in] Pointer to configuration.
// bEnable
// [in] Enable or disable configuration.
//
// Returns:
// TRUE if request was successful, otherwise returns false.
//
//-----------------------------------------------------------------------------
static BOOL GpioConfigModuleIOFunc(DDK_GPIO_CFG *pGpioCfg, BOOL bEnable)
{
GPIO_PORT port;
GPIO_INPUT_DEST_TYPE InputDest;
GPIO_OUTPUT_SOURCE_TYPE OutputSource;
UINT32 inputMask;
UINT32 outputMask;
UINT32 mask;
UINT32 pin;
UINT32 puen;
UINT32 ocr;
UINT32 iconf;
if (!pGpioCfg)
return FALSE;
inputMask = pGpioCfg->ModuleIOConfig.InputPinMap;
outputMask = pGpioCfg->ModuleIOConfig.OutputPinMap;
if ((inputMask == 0 && outputMask == 0) || (inputMask & outputMask) != 0) {
DBGCHK((_T("CSPDDK")), FALSE);
ERRORMSG(1, (_T("GpioConfigModuleIOFunc: invalid pins! input %x output %x\r\n"),
inputMask, outputMask));
return FALSE;
}
OutputSource = pGpioCfg->ModuleIOConfig.OutputSource;
if (outputMask != 0 && OutputSource >= GPIO_OUTPUT_SOURCE_MAX) {
DBGCHK((_T("CSPDDK")), FALSE);
ERRORMSG(1, (_T("GpioConfigModuleIOFunc: invalid output! mask %x source %d\r\n"),
outputMask, OutputSource));
return FALSE;
}
InputDest = pGpioCfg->ModuleIOConfig.InputDest;
if(inputMask != 0 && InputDest != GPIO_INPUT_DEST_AOUT
&& InputDest != GPIO_INPUT_DEST_BOUT ) {
DBGCHK((_T("CSPDDK")), FALSE);
ERRORMSG(1, (_T("GpioConfigModuleIOFunc: invalid input! inputMask %x InputDest %d\r\n"),
inputMask, InputDest));
return FALSE;
}
port = pGpioCfg->ModuleIOConfig.Port;
puen = g_pGPIO->PORT[port].PUEN;
mask = inputMask | outputMask;
DDK_GPIO_LOCK();
g_pGPIO->PORT[port].GIUS |= (inputMask | outputMask);
if (bEnable) {
// Configure module IO pins
g_pGPIO->PORT[port].DDIR &= ~inputMask;
g_pGPIO->PORT[port].DDIR |= outputMask;
puen &= ~mask;
puen |= (pGpioCfg->ModuleIOConfig.PuenMap & mask);
g_pGPIO->PORT[port].PUEN = puen;
} else {
// Configure all as input pins, pullup enabled
g_pGPIO->PORT[port].DDIR &= ~mask;
g_pGPIO->PORT[port].PUEN |= mask;
}
if (((inputMask | outputMask) & 0x0000FFFF) != 0) {
if(InputDest == GPIO_INPUT_DEST_AOUT)
iconf = g_pGPIO->PORT[port].ICONFA1;
else if(InputDest == GPIO_INPUT_DEST_BOUT)
iconf = g_pGPIO->PORT[port].ICONFB1;
ocr = g_pGPIO->PORT[port].OCR1;
for (mask = 1, pin = 0; pin < 16; pin++, mask <<= 1) {
if ((mask & inputMask) != 0) {
if (bEnable == TRUE)
iconf &= ~(3 << (pin * 2));
else
iconf |= (3 << (pin * 2));
} else if ((mask & outputMask) != 0) {
ocr &= ~(3 << (pin * 2));
if (bEnable == TRUE)
ocr |= (OutputSource << (pin * 2));
}
}
if (InputDest == GPIO_INPUT_DEST_AOUT)
g_pGPIO->PORT[port].ICONFA1 = iconf;
else if(InputDest == GPIO_INPUT_DEST_BOUT)
g_pGPIO->PORT[port].ICONFB1 = iconf;
g_pGPIO->PORT[port].OCR1 = ocr;
}
if (((inputMask | outputMask) & 0xFFFF0000) != 0) {
if(InputDest == GPIO_INPUT_DEST_AOUT)
iconf = g_pGPIO->PORT[port].ICONFA2;
else if(InputDest == GPIO_INPUT_DEST_BOUT)
iconf = g_pGPIO->PORT[port].ICONFB2;
ocr = g_pGPIO->PORT[port].OCR2;
for (mask = (1 << 16), pin = 0; pin < 16; pin++, mask <<= 1) {
if ((mask & inputMask) != 0) {
if(bEnable == TRUE)
iconf &= ~(3 << (pin * 2));
else
iconf |= (3 << (pin * 2));
} else if ((mask & outputMask) != 0) {
ocr &= ~(3 << (pin * 2));
if(bEnable == TRUE)
ocr |= (OutputSource << (pin * 2));
}
}
if(InputDest == GPIO_INPUT_DEST_AOUT)
g_pGPIO->PORT[port].ICONFA2 = iconf;
else if(InputDest == GPIO_INPUT_DEST_BOUT)
g_pGPIO->PORT[port].ICONFB2 = iconf;
g_pGPIO->PORT[port].OCR2 = ocr;
}
DDK_GPIO_UNLOCK();
return TRUE;
}
//-----------------------------------------------------------------------------
//
// Function: GpioConfigIOFunc
//
// This function Configures a pin set to it's simple IO function.
// Disabling will cause pins to be set as input with pullup enabled.
//
// Parameters:
// pGpioCfg
// [in] Pointer to configuration.
// bEnable
// [in] Enable or disable configuration.
//
// Returns:
// TRUE if request was successful, otherwise returns false.
//
//-----------------------------------------------------------------------------
static BOOL GpioConfigIOFunc(DDK_GPIO_CFG *pGpioCfg, BOOL bEnable)
{
GPIO_PORT port;
UINT32 inputMask;
UINT32 outputMask;
UINT32 pin;
UINT32 mask;
UINT32 puen;
UINT32 ocr;
if (!pGpioCfg)
return FALSE;
inputMask = pGpioCfg->IOConfig.InputPinMap;
outputMask = pGpioCfg->IOConfig.OutputPinMap;
if (inputMask == 0 && outputMask == 0 || (inputMask & outputMask) != 0) {
DBGCHK((_T("CSPDDK")), FALSE);
ERRORMSG(1, (_T("GpioConfigIOFunc: invalid pins! input %x output %x\r\n"),
inputMask, outputMask));
return FALSE;
}
port = pGpioCfg->IOConfig.Port;
puen = g_pGPIO->PORT[port].PUEN;
mask = inputMask | outputMask;
DDK_GPIO_LOCK();
g_pGPIO->PORT[port].GIUS |= mask;
if (bEnable) {
// Configure IO pins via pGPIO function.
g_pGPIO->PORT[port].DDIR &= ~inputMask;
g_pGPIO->PORT[port].DDIR |= outputMask;
puen &= ~mask;
puen |= (pGpioCfg->IOConfig.PuenMap & mask);
g_pGPIO->PORT[port].PUEN = puen;
} else {
// Configure all as input pins, pullup enabled.
g_pGPIO->PORT[port].DDIR &= ~mask;
g_pGPIO->PORT[port].PUEN |= mask;
}
if ((outputMask & 0x0000FFFF) != 0) {
ocr = g_pGPIO->PORT[port].OCR1;
for (mask = 1, pin = 0; pin < 16; pin++, mask <<= 1) {
if ((mask & outputMask) != 0) {
ocr &= ~(3 << (pin * 2));
if (bEnable == TRUE)
ocr |= (GPIO_OUTPUT_SOURCE_DATA << (pin * 2));
}
}
g_pGPIO->PORT[port].OCR1 = ocr;
}
if ((outputMask & 0xFFFF0000) != 0) {
ocr = g_pGPIO->PORT[port].OCR2;
for (mask = (1 << 16), pin = 0; pin < 16; pin++, mask <<= 1) {
if ((mask & outputMask) != 0) {
ocr &= ~(3 << (pin * 2));
if (bEnable == TRUE)
ocr |= (GPIO_OUTPUT_SOURCE_DATA << (pin * 2));
}
}
g_pGPIO->PORT[port].OCR2 = ocr;
}
DDK_GPIO_UNLOCK();
return TRUE;
}
//-----------------------------------------------------------------------------
//
// Function: GpioConfigIntrFunc
//
// This function Configures a pin set to it's interrupt function.
// Disabling will cause pins to be set as input with pullup enabled.
//
// Parameters:
// pGpioCfg
// [in] Pointer to configuration.
// bEnable
// [in] Enable or disable configuration.
//
// Returns:
// TRUE if request was successful, otherwise returns false.
//
//-----------------------------------------------------------------------------
static BOOL GpioConfigIntrFunc(DDK_GPIO_CFG *pGpioCfg, BOOL bEnable)
{
GPIO_PORT port;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -