⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ddk_gpio.c

📁 Microsoft WinCE 6.0 BSP FINAL release source code for use with the i.MX27ADS TO2 WCE600_FINAL_MX27_S
💻 C
📖 第 1 页 / 共 2 页
字号:
//
// 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 + -