How AM33X WEC7 BSP doing pinmux in OAL layer

TI Sitara Cortex-A8 MPU and it's companion boards
Post Reply
esky-sh
Posts: 1449
Joined: Sat Dec 20, 2008 4:21 am

How AM33X WEC7 BSP doing pinmux in OAL layer

Post by esky-sh » Wed May 02, 2012 9:43 pm

Most peripheral drivers on TI OMAP/Sitara series SOCs need pinmux facility to route their functional pins to specific chip pads. Typically WEC7 doing pinmux on it's OAL layer. Here is an example for how AM33x UART driver implement pinmux during driver initialize.

1. \AM33X_BSP\SRC\DRIVERS\UART\uart.reg
AM33X UART driver(am33x_uart.dll) retrieves pinmux information from corresponding registry entries

Code: Select all

;-- UART Driver -----------------------------------------------------------------

IF BSP_AM33X_UART1
[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\UART1]
	"Prefix"="COM"
	"Dll"="am33x_uart.dll"
//////////////////////////////////////////////////////////////////////////////
	"DeviceArrayIndex"=dword:1
/////////////////////////////////////////////////////////////////////////////
	"Index"=dword:1
	"Order"=dword:9
    "MemBase"=multi_sz:"44E05000"
    "MemLen"=multi_sz:"00001000"
	"PowerFlags"=dword:00000103         ; send pre/post device state changes
	"RxBuffer" = dword:2000
	"TxDmaRequest"=dword:ffffffff                 ; TxDma has issues after RX of break, disabled with ffffffff
	"TxDmaBufferSize"=dword:2000                  ; Size of DMA transmit buffer
	"RxDmaRequest"=dword:ffffffff                 ; S_DMA_49 RX DMA Request Line, use ffffffff to disable RX DMA
	"RxDmaBufferSize"=dword:2000                  ; Size of DMA receive buffer
	"RtsCtsEnable"=dword:0                        ; 1=enable RTS/CTS handshake support, 0=disable
	"HWMode"=dword:0                              ; Use hardware auto RTS/CTS
	"Frequency"=dword:2DC6C00                     ; UART operation freq, 48000000
	; PMCLASS_PMEXT_GUID, CE_DRIVER_POWER_MANAGEABLE_GENERIC_GUID
	"IClass"=multi_sz:"{0AE2066F-89A2-4D70-8FC2-29AEFA68413C}",
					  "{A32942B7-920C-486b-B0E6-92A702A99B35}"
	        
ENDIF BSP_AM33X_UART1

'DeviceArrayIndex' entry will be used for indexing of pad pinmux.

2. \PLATFORM\COMMON\SRC\SOC\COMMON_TI_V1\COMMON_TI_AMXX\SERIAL\pdd_common.c

Code: Select all

//------------------------------------------------------------------------------
//
//  Function:  HWInit
//
//  This function initializes a serial device and it returns information about
//  it.
//
static
PVOID
HWInit(
       ULONG context,
       PVOID pMdd,
       PHWOBJ pHWObj
       )
{
    BOOL rc = FALSE;
    UARTPDD *pPdd = NULL;
    PHYSICAL_ADDRESS pa;
    SOC_UART_REGS *pUartRegs;

    DEBUGMSG(ZONE_OPEN||ZONE_FUNCTION, (
        L"+HWInit(%s, 0x%08x, 0x%08x\r\n", context, pMdd, pHWObj
        ));

    // Allocate SER_INFO structure
    pPdd = LocalAlloc(LPTR, sizeof(UARTPDD));
    if (pPdd == NULL) goto cleanUp;

    memset(pPdd, 0x00, sizeof(UARTPDD));

    // Read device parameters
    if (GetDeviceRegistryParams(
        (LPCWSTR)context, pPdd, dimof(s_deviceRegParams), s_deviceRegParams
        ) != ERROR_SUCCESS)

    {
        DEBUGMSG(ZONE_ERROR, (L"ERROR: HWInit: "
            L"Failed read driver registry parameters\r\n"
            ));
        goto cleanUp;
    }


    rc = CreateParentBus(pPdd, context);
    if (rc == FALSE)
        goto cleanUp;

    rc = FALSE;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// Retrieve device index
	pPdd->DeviceID = SOCGetUartDeviceByIndex(pPdd->UARTIndex);
//////////////////////////////////////////////////////////////////////////////////////////////////////////////

	if (pPdd->DeviceID == OMAP_DEVICE_NONE)
	{
        DEBUGMSG(ZONE_ERROR, (L"ERROR: HWInit: "
            L"Failed to retrieve valid device ID for this UART\r\n"
            ));
        goto cleanUp;
	}
////////////////////////////////////////////////////////////////////////////////////////////////
	// Perform pads configuration
	if (!RequestDevicePads(pPdd->DeviceID))
	{
        DEBUGMSG(ZONE_ERROR, (L"ERROR: HWInit: "
            L"Failed to request pads\r\n"
            ));
        goto cleanUp;
	}
/////////////////////////////////////////////////////////////////////////////////////////////////
3. \PLATFORM\COMMON\SRC\SOC\COMMON_TI_V1\AM33X\SOCCFG\soccfg.c

Code: Select all

//  File:  soccfg.c
//
//  Configuration file for the device list
//
#include "am33x.h"
#include "soc_cfg.h"
#include "omap_devices_map.h"
#include "am33x_clocks.h"
#include "omap_cpgmac_regs.h"

DWORD SOCGetGPIODeviceByBank(DWORD index)
{
    switch (index)
    {
        case 1: return AM_DEVICE_GPIO0;
        case 2: return AM_DEVICE_GPIO1;
        case 3: return AM_DEVICE_GPIO2;
        case 4: return AM_DEVICE_GPIO3;
        default: return OMAP_DEVICE_NONE;   
    }
}

DWORD SOCGetSDHCDeviceBySlot(DWORD index)
{
    switch (index)
    {
    	case 1: return AM_DEVICE_MMCHS0;
    	case 2: return AM_DEVICE_MMCHS1;
    	case 3: return AM_DEVICE_MMCHS2;
    	default: return OMAP_DEVICE_NONE;   
    }
}

DWORD SOCGetMCSPIDeviceByBus(DWORD index)
{
	switch(index)
	{
		case 1:	return AM_DEVICE_MCSPI0;
		case 2:	return AM_DEVICE_MCSPI1;
	}
	return OMAP_DEVICE_NONE;
}

DWORD SOCGetI2CDeviceByBus(DWORD index)
{
	switch(index)
	{
		case 1:	return AM_DEVICE_I2C0;
		case 2:	return AM_DEVICE_I2C1;
		case 3:	return AM_DEVICE_I2C2;
	}
	return OMAP_DEVICE_NONE;
}
/////////////////////////////////////////////////////////////////////////////////
DWORD SOCGetUartDeviceByIndex(DWORD index)
{
	switch(index)
	{
		case 1:	return AM_DEVICE_UART0;
		case 2:	return AM_DEVICE_UART1;
		case 3:	return AM_DEVICE_UART2;
		case 4:	return AM_DEVICE_UART3;
		case 5:	return AM_DEVICE_UART4;
		case 6:	return AM_DEVICE_UART5;
	}
	return OMAP_DEVICE_NONE;
}
//////////////////////////////////////////////////////////////////////////////////
DWORD SOCGetGPMCAddress(DWORD index)
{
    UNREFERENCED_PARAMETER(index);
    return AM33X_GPMC_REGS_PA;
}

void SOCGetDSSInfo(DSS_INFO* pInfo)
{
    pInfo->DSSDevice = AM_DEVICE_LCDC;
    pInfo->TVEncoderDevice = (DWORD)NULL;
    pInfo->DSS1_REGS_PA     = (DWORD)NULL;
    pInfo->DISC1_REGS_PA    = (DWORD)NULL; 
    pInfo->VENC1_REGS_PA    = (DWORD)NULL;
    pInfo->DSI_REGS_PA      = (DWORD)NULL;
    pInfo->DSI_PLL_REGS_PA  = (DWORD)NULL;
}

UINT32 SOCGetSysFreqKHz(void)
{
	return 24000;
}
4. So OAL function RequestDevicePads() will do exact pinmuxing accroding specific device index number.
\PLATFORM\COMMON\SRC\SOC\COMMON_TI_V1\COMMON_TI\OAL\OMAP_OALPADCFG\oalpadcfg.c

Code: Select all

BOOL RequestDevicePads(OMAP_DEVICE device)
{
    BOOL rc = FALSE;
    const PAD_INFO* p = BSPGetDevicePadInfo(device);

    if (p)
    {
        rc = RequestAndConfigurePadArray(p);
    }

    return rc;
}

// NOTE : this function is not optimized at all. It's intended to be used very seldom
BOOL RequestAndConfigurePadArray(const PAD_INFO* padArray)
{
    BOOL rc = TRUE;
    int i = 0;
    
    PadCfgLock();
    // Check that all pads are valid and released
    i=0;
    while (rc && (padArray[i].padID != (UINT16) -1))
    {
        int padIndex;
        padIndex = FindPad(padArray[i].padID);
        if (padIndex == -1) 
        {
            goto error;
        }
        if (padIndex >= g_NbPads)
        {
            ASSERT(0);
            goto error;
        }
        if (g_bspPadInfo[padIndex].inUse)
        {                
            goto error;
        }
        i++;
    }

    // Request and Configure all pads
    i = 0;
    while (rc && (padArray[i].padID != (UINT16) -1))
    {
        int padIndex;
        padIndex = FindPad(padArray[i].padID);
        g_bspPadInfo[padIndex].inUse = 1;
        SOCSetPadConfig(padArray[i].padID,(UINT16)padArray[i].Cfg);     
        i++;
    }

    PadCfgUnlock();
    return TRUE;

error:
    PadCfgUnlock();
    return FALSE;
}
5. OMAP_DEVICE is indexing inside AM33X BSP
\PLATFORM\COMMON\SRC\SOC\COMMON_TI_V1\AM33X\INC\am33x_clocks.h

Code: Select all

typedef enum {    
    AM_DEVICE_ADC_TSC = 0, /* WKUP */ /* 0 */
    AM_DEVICE_CONTROL,
    AM_DEVICE_DEBUGSS,
    AM_DEVICE_GPIO0,
    AM_DEVICE_I2C0,
    AM_DEVICE_L4WKUP,
    AM_DEVICE_SMARTREFLEX0,
    AM_DEVICE_SMARTREFLEX1,
    AM_DEVICE_TIMER0,
    AM_DEVICE_TIMER1,
    AM_DEVICE_UART0,               /* 10 */
    AM_DEVICE_WDT0,
    AM_DEVICE_WDT1,
    AM_DEVICE_WKUP_M3,
    AM_DEVICE_AES0,         /* PER */
    AM_DEVICE_AES1,
    AM_DEVICE_CLKDIV32K,
    AM_DEVICE_CPGMAC0,
    AM_DEVICE_DCAN0,
    
    AM_DEVICE_TIMER7,
    AM_DEVICE_TPCC,
    AM_DEVICE_TPTC0,
    AM_DEVICE_TPTC1,
    AM_DEVICE_TPTC2,
//////////////////////////////////////////////////////////////////////////////
    AM_DEVICE_UART1,
    AM_DEVICE_UART2,               /* 70 */
    AM_DEVICE_UART3,
    AM_DEVICE_UART4,
    AM_DEVICE_UART5,
//////////////////////////////////////////////////////////////////////////////
    AM_DEVICE_USB0,
    AM_DEVICE_BITBLT,           /* GFX */
    AM_DEVICE_GFX,
    AM_DEVICE_MMU,
    AM_DEVICE_MMUCFG,
    AM_DEVICE_MPU,              /* MPU */
    AM_DEVICE_RTC,                /* 80 */
    AM_DEVICE_CEFUSE,
    AM_DEVICE_EFUSE,   
    AM_DEVICE_COUNT,
	/* following devices are needed for pinmux */    
    /* when adding new device here, dont forget to fill the s_rgDeviceRemapTable in prcm_device.h */
	AM_DEVICE_NAND,            /* same as GPMC */
	AM_DEVICE_NOR,             /* same as GPMC */    
	AM_DEVICE_BKL,             /* GPIO */
	AM_DEVICE_END         /* this should be the last one */
} AM33X_DEVICE_ID;
6. Re-sort device list per current board settings. This will prevent pinmuxing to un-exist SOC peripherals.
\PLATFORM\AM33X_BSP\SRC\BSP_COMMON\BSP_PADCFG\bsp_padcfg.c

Code: Select all

/*
 * Update the structure with the modules present in the general purpose
 * board and the profiles in which the modules are present.
 * If the module is physically present but if it is not available
 * in any of the profile, then do not update it.
 * For eg, nand is avialable only in the profiles 0 and 1, whereas
 * UART0  is available in all the profiles.
 */

const EVM_PIN_MUX GP_BOARD_PIN_MUX[] = {
    { ADCTSCPads,           AM_DEVICE_ADC_TSC,      PROFILE_0 | PROFILE_1 | PROFILE_2 | PROFILE_7,  DEV_ON_DGHTR_BRD},
    { BKLPads,              AM_DEVICE_BKL,          PROFILE_0 | PROFILE_1 | PROFILE_2 | PROFILE_7,  DEV_ON_DGHTR_BRD},
    { I2C0Pads,             AM_DEVICE_I2C0,         PROFILE_ALL,                                    DEV_ON_BASEBOARD},
    { I2C1Pads,             AM_DEVICE_I2C1,         PROFILE_ALL & ~PROFILE_2 & ~PROFILE_4,          DEV_ON_BASEBOARD},
    { LCDCPads,             AM_DEVICE_LCDC,         PROFILE_0 | PROFILE_1 | PROFILE_2 | PROFILE_7,  DEV_ON_DGHTR_BRD}, //although its separate LCD board, use BaseBoard as location; will use profile info to know if LCD is valid or not    
    { MCASP1Pads,           AM_DEVICE_MCASP1,       PROFILE_0 | PROFILE_3,                          DEV_ON_DGHTR_BRD},
    { MMC0Pads,             AM_DEVICE_MMCHS0,       PROFILE_ALL & ~PROFILE_5,                       DEV_ON_BASEBOARD},
    { MMC0_NoCD_Pads,       AM_DEVICE_MMCHS0,       PROFILE_5,                                      DEV_ON_BASEBOARD},
    { MMC1Pads,             AM_DEVICE_MMCHS1,       PROFILE_2,                                      DEV_ON_DGHTR_BRD},
    { MMC2Pads,             AM_DEVICE_MMCHS2,       PROFILE_4,                                      DEV_ON_DGHTR_BRD},
    { NANDPads,             AM_DEVICE_NAND,         PROFILE_ALL & ~PROFILE_2 & ~PROFILE_3,          DEV_ON_DGHTR_BRD},
    { NORPads,              AM_DEVICE_NOR,          PROFILE_3,                                      DEV_ON_DGHTR_BRD},    
    { RGMIIMultiplePhyPads, AM_DEVICE_CPGMAC0,      PROFILE_1 | PROFILE_2 | PROFILE_4 | PROFILE_6,  DEV_ON_DGHTR_BRD},
    { RGMIISinglePhyPads,   AM_DEVICE_CPGMAC0,      PROFILE_0 | PROFILE_3 | PROFILE_5 | PROFILE_7,  DEV_ON_BASEBOARD},
    { SPI0Pads,             AM_DEVICE_MCSPI0,       PROFILE_2,                                      DEV_ON_DGHTR_BRD},
    { UART0Pads,            AM_DEVICE_UART0,        PROFILE_ALL,                                    DEV_ON_BASEBOARD},    
    { USB0Pads,             AM_DEVICE_USB0,         PROFILE_ALL,                                    DEV_ON_BASEBOARD},    
    {0},
};

const EVM_PIN_MUX * AM335x_EVM_PIN_MUX[] = {
	GP_BOARD_PIN_MUX,
	NULL,
	NULL,
	NULL,
};


PAD_INFO* BSPGetAllPadsInfo()
{    
    return g_allowedPadCfg;
}

const PAD_INFO* BSPGetDevicePadInfo(OMAP_DEVICE device)
{
    DWORD i=0;
    EVM_PIN_MUX * board_pin_mux = AM335x_EVM_PIN_MUX[g_dwBoardId];
    if (board_pin_mux == NULL) {
        //OALMSG(1,(L"BSPGetDevicePadInfo: Invalid board ID %d\r\n",g_dwBoardId));   
        return NULL;
    }

    for (i = 0; board_pin_mux[i].padInfo != 0; i++)  {
        //look for the device
        if (board_pin_mux[i].device != device)
            continue;     
        //found the device; now check the profile
		if ((g_dwBoardProfile == PROFILE_NONE) || (board_pin_mux[i].profile & g_dwBoardProfile)) {
            //profile match found; now check if device on daugter card and if daugter card present
			if (((board_pin_mux[i].device_on == DEV_ON_DGHTR_BRD) && (g_dwBoardHasDcard == TRUE)) ||
                  (board_pin_mux[i].device_on == DEV_ON_BASEBOARD))
				return board_pin_mux[i].padInfo;			
		}        
	}
    
    //OALMSG(1,(L"BSPGetDevicePadInfo: No Device Pad Info found for device %d\r\n",device));       
    return NULL;
}
The flexibility of UART pinmux above is sufficient enough to allow hardware re-routing for same SOC peripheral without software change. But sometimes software get short-cut and registry will not be involved with pinmux settings. Here is another example for GPIO keypad driver in AM33X BSP.
\PLATFORM\AM33X_BSP\SRC\DRIVERS\KEYPAD\gpio_keypad.c

Code: Select all

//------------------------------------------------------------------------------
//  Local Definitions
#define VK_KEYS                     256
#define DWORD_BITS                  32

#define NB_KEYS 8
UCHAR vKeys[NB_KEYS] = {VK_DOWN, VK_UP, VK_LEFT, VK_RIGHT, L'1', L'2', L'3', VK_RETURN};

static const PAD_INFO KeypadPads[]    = {KEYPAD_PADS END_OF_PAD_ARRAY};

//------------------------------------------------------------------------------
//  Device registry parameters

static const DEVICE_REGISTRY_PARAM g_deviceRegParams[] = {
    {
        L"Priority256", PARAM_DWORD, FALSE, offset(KPD_DEVICE, priority256),
        fieldsize(KPD_DEVICE, priority256), (VOID*)100
    }, 
    {
        L"SamplePeriod", PARAM_DWORD, FALSE, offset(KPD_DEVICE, samplePeriod),
        fieldsize(KPD_DEVICE, samplePeriod), (VOID*)40
    }, {
        L"DebounceTime", PARAM_DWORD, FALSE, offset(KPD_DEVICE, debounceTime),
        fieldsize(KPD_DEVICE, debounceTime), (VOID*)0x50
    }, {
        L"FirstRepeat", PARAM_DWORD, FALSE, offset(KPD_DEVICE, firstRepeat),
        fieldsize(KPD_DEVICE, firstRepeat), (VOID*)500
    }, {
        L"NextRepeat", PARAM_DWORD, FALSE, offset(KPD_DEVICE, nextRepeat),
        fieldsize(KPD_DEVICE, nextRepeat), (VOID*)125
    }
};

//------------------------------------------------------------------------------
//  Local functions

BOOL KPD_Deinit(DWORD context);
static DWORD KPD_Thread(VOID *pParam);

//------------------------------------------------------------------------------
DWORD KPD_Init(LPCTSTR szContext, LPCVOID pBusContext)
//  Called by device manager to initialize device.
{
//    int i;
    DWORD rc = (DWORD)NULL;
    KPD_DEVICE *pDevice = NULL;

	UNREFERENCED_PARAMETER(pBusContext);

    DEBUGMSG(ZONE_FUNCTION, (L"+KPD_Init(%s, 0x%08x)\r\n", szContext, pBusContext));

	
	if (RequestAndConfigurePadArray(KeypadPads)==FALSE){
        DEBUGMSG(ZONE_ERROR, (L"ERROR: KPD_Init: Cannot configure keypad pads\r\n"));
        goto cleanUp;
	}

    pDevice = (KPD_DEVICE *)LocalAlloc(LPTR, sizeof(KPD_DEVICE));
    if (pDevice == NULL) {
        DEBUGMSG(ZONE_ERROR, (L"ERROR: KPD_Init: Failed allocate KDP driver structure\r\n"));
        goto cleanUp;
    }

	memset(pDevice, 0, sizeof(KPD_DEVICE));

    pDevice->hGpio = GPIOOpen();
    if (pDevice->hGpio == NULL){
        DEBUGMSG(ZONE_ERROR, (L"ERROR: KPD_Init: Failed to open GPIO driver\r\n"));
        goto cleanUp;
    }

	GPIOSetMode(pDevice->hGpio, GPIO_53, GPIO_DIR_OUTPUT);
	GPIOSetMode(pDevice->hGpio, GPIO_54, GPIO_DIR_OUTPUT);
	GPIOSetMode(pDevice->hGpio, GPIO_57, GPIO_DIR_INPUT);
	GPIOSetMode(pDevice->hGpio, GPIO_58, GPIO_DIR_INPUT);
	GPIOSetMode(pDevice->hGpio, GPIO_59, GPIO_DIR_INPUT);
	GPIOSetMode(pDevice->hGpio, GPIO_2,  GPIO_DIR_INPUT);
	GPIOSetMode(pDevice->hGpio, GPIO_3,  GPIO_DIR_INPUT);

	GPIOSetBit(pDevice->hGpio, GPIO_53);
	GPIOClrBit(pDevice->hGpio, GPIO_54);

    InitializeCriticalSection(&pDevice->cs);

    // Read device parameters
    if (GetDeviceRegistryParams(szContext, pDevice, dimof(g_deviceRegParams), g_deviceRegParams) 
		!= ERROR_SUCCESS) {
        DEBUGMSG(ZONE_ERROR, (L"ERROR: KPD_Init: Failed read KPD driver registry parameters\r\n"));
       
        pDevice->priority256=100;
        pDevice->samplePeriod=40;
        pDevice->debounceTime=0x50;
        pDevice->firstRepeat=500;
        pDevice->nextRepeat=125;
    }

	// Pinmux config 
	// GPIOSetMode for all required GPIOs

    if ((pDevice->hThread = CreateThread(NULL, 0, KPD_Thread, pDevice, 0,NULL)) == NULL) {
        DEBUGMSG (ZONE_ERROR, (L"ERROR: KPD_Init: Failed create interrupt thread\r\n"));
        goto cleanUp;
    }

	CeSetThreadPriority(pDevice->hThread, pDevice->priority256);

    rc = (DWORD)pDevice;

cleanUp:
    if (rc == 0) KPD_Deinit((DWORD)pDevice);
    DEBUGMSG(ZONE_FUNCTION, (L"-KPD_Init(rc = %d\r\n", rc));

    return rc;
}

//------------------------------------------------------------------------------
DWORD KPD_Thread(VOID *pContext)
{
//    int index;
    KPD_DEVICE *pDevice = (KPD_DEVICE*)pContext;
    DWORD timeout, time, ix;
    DWORD change, mask;
    UINT16 i;
    USHORT data;
	USHORT old_data;
    UINT16 ic=0;
    DWORD vkState[VK_KEYS/DWORD_BITS], vkNewState[VK_KEYS/DWORD_BITS];
    KEYPAD_REMAP_STATE *pRemapState = NULL;
    KEYPAD_REPEAT_STATE *pRepeatState = NULL;
    BOOL keyDown;
    UCHAR vk=0;

    DEBUGMSG(ZONE_IST, (L"KPD - Start IntrThread\r\n"));


#if 1

    // Init data
    memset(vkState, 0, sizeof(vkState));

	// Initialize remap informations
    if (g_keypadRemap.count > 0) {
        // Allocate state structure for remap
        if ((pRemapState = LocalAlloc(LPTR, g_keypadRemap.count * sizeof(KEYPAD_REMAP_STATE)))  == NULL) {
            DEBUGMSG(ZONE_ERROR, (L" KPD_Thread: Failed allocate memory for virtual key remap\r\n"));
            goto cleanUp;
        }
    }

    // Initialize repeat informations
    if (g_keypadRepeat.count > 0) {
        // Allocate state structure for remap
        if ((pRepeatState = LocalAlloc(LPTR, g_keypadRepeat.count * sizeof(KEYPAD_REPEAT_STATE))) == NULL){
            DEBUGMSG(ZONE_ERROR, (L" KPD_Thread: Failed allocate memory for virtual key auto repeat\r\n"));
            goto cleanUp;
        }
    }
#endif

    timeout = pDevice->samplePeriod;
	old_data = 0;
    // Loop until we are not stopped...
    while (!pDevice->bThreadExit) {
		Sleep(timeout/2);
		data = 0;
		data |= (GPIOGetBit(pDevice->hGpio,GPIO_57)) ? 0x01 : 0;			  
		data |= (GPIOGetBit(pDevice->hGpio,GPIO_58)) ? 0x02 : 0;			  
		data |= (GPIOGetBit(pDevice->hGpio,GPIO_59)) ? 0x04 : 0;			  
		GPIOSetBit(pDevice->hGpio, GPIO_54);
		GPIOClrBit(pDevice->hGpio, GPIO_53);
		Sleep(timeout/2);
		data |= (GPIOGetBit(pDevice->hGpio,GPIO_57)) ? 0x08 : 0;			  
		data |= (GPIOGetBit(pDevice->hGpio,GPIO_58)) ? 0x10 : 0;			  
		data |= (GPIOGetBit(pDevice->hGpio,GPIO_59)) ? 0x20 : 0;			  
		GPIOSetBit(pDevice->hGpio, GPIO_53);
		GPIOClrBit(pDevice->hGpio, GPIO_54);
		data |= (GPIOGetBit(pDevice->hGpio,GPIO_2))  ? 0 : 0x40;			  
		data |= (GPIOGetBit(pDevice->hGpio,GPIO_3))  ? 0 : 0x80;			  

#if 0
		mod_data = data ^ old_data;
		for (i = 0, mask_data = 1; i<NB_KEYS; i++, mask_data <<= 1){
			if (mod_data & mask_data){
				if (data & mask_data){
RETAILMSG(1, (L" KPD_Thread: Key Down: 0x%x\r\n", vKeys[i] ));
                        keybd_event(vKeys[i], 0, 0, 0);
				} else {
RETAILMSG(1, (L" KPD_Thread: Key Up: 0x%x\r\n", vKeys[i] ));
                        keybd_event(vKeys[i], 0, KEYEVENTF_KEYUP, 0);
				}

			}
In some cases, driver developer may forget to do pinmux stuff. So others should help him to add this somewhere to their code. :lol:
\PLATFORM\AM33X_BSP\SRC\DRIVERS\BACKLIGHT\gpio_backlight.cpp

Code: Select all

BOOL
GPIO_Backlight::Initialize(
    LPCTSTR szContext
    )
{
    DEBUGMSG(ZONE_FUNCTION, (
        L"+GPIO_Backlight::Initialize(%s)\r\n", szContext
        ));

    BOOL rc = FALSE;

    if (ParentClass::Initialize(szContext) == FALSE)
        {
        DEBUGMSG(ZONE_ERROR, (L"ERROR: TLED_Backlight::Initialize: "
            L"Parent class failed to initialize\r\n"
            ));
        goto cleanUp;
        }

    // Read device parameters
    if (GetDeviceRegistryParams(
            szContext, this, dimof(s_deviceRegParams), s_deviceRegParams
            ) != ERROR_SUCCESS)
        {
        DEBUGMSG(ZONE_ERROR, (L"ERROR: GPIO_Backlight::Initialize: "
            L"Failed read gpio driver registry parameters\r\n"
            ));
        goto cleanUp;
        }
        
    // GPIO pin not configured, tled only
    if (m_gpioId == GPIO_NOT_USED)
    {
        DEBUGMSG(ZONE_FUNCTION, (
            L"GPIO_Backlight::Initialize: No GPIO pin allocated, continuing...\r\n"
            ));
        rc = TRUE;
        goto cleanUp;
    }

    m_hGpio = GPIOOpen();
    if (m_hGpio == NULL)
        {
        DEBUGMSG(ZONE_ERROR, (L"ERROR: GPIO_Backlight::Initialize: "
            L"Failed allocate GPIO handle\r\n"
            ));
        goto cleanUp;
        }

    // setup for output mode
    GPIOSetMode(m_hGpio, m_gpioId, GPIO_DIR_OUTPUT);

    rc = TRUE;
cleanUp:

    DEBUGMSG(ZONE_FUNCTION, (
        L"-GPIO_Backlight::Initialize(%s) == %d\r\n", szContext, rc
        ));

    return rc;
}

Post Reply

Who is online

Users browsing this forum: No registered users and 4 guests