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

📄 pmic_connectivity.cpp

📁 Microsoft WinCE 6.0 BSP FINAL release source code for use with the i.MX27ADS TO2 WCE600_FINAL_MX27_S
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/*---------------------------------------------------------------------------
* Copyright (C) 2006, 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:pmic_connectivity.cpp
//
// This file contains the SDK interface that is used by applications and other drivers 
// to access connectivity feature of the MC13783.
//
//-----------------------------------------------------------------------------

#include <windows.h>
#include <Devload.h>
#include <ceddk.h>
#include "socarm_macros.h"
#include "regs.h"
#include "regs_connectivity.h"
#include "pmic_lla.h"
#include "pmic_ioctl.h"
#include "pmic_connectivity.h"
#include "pmic_convity_priv.h"


#ifdef DEBUG

// Debug zone bit positions
#define ZONEID_ERROR		0
#define ZONEID_WARN			1
#define ZONEID_INIT			2
#define ZONEID_FUNC			3
#define ZONEID_INFO			4

// Debug zone masks
#define ZONEMASK_ERROR		 (1 << ZONEID_ERROR)
#define ZONEMASK_WARN		(1 << ZONEID_WARN)
#define ZONEMASK_INIT		(1 << ZONEID_INIT)
#define ZONEMASK_FUNC		(1 << ZONEID_FUNC)
#define ZONEMASK_INFO		(1 << ZONEID_INFO)

// Debug zone args to DEBUGMSG
#define ZONE_ERROR			 DEBUGZONE(ZONEID_ERROR)
#define ZONE_WARN			DEBUGZONE(ZONEID_WARN)
#define ZONE_INIT			DEBUGZONE(ZONEID_INIT)
#define ZONE_FUNC			DEBUGZONE(ZONEID_FUNC)
#define ZONE_INFO			DEBUGZONE(ZONEID_INFO)

extern DBGPARAM dpCurSettings;

#endif// DEBUG


//-----------------------------------------------------------------------------
// External Functions

//-----------------------------------------------------------------------------
// External Variables
extern HANDLE hPMI;

//-----------------------------------------------------------------------------
// Defines
#define CONVITY_INTR_USBI						0
#define CONVITY_INTR_IDI						1
#define CONVITY_INTR_SE1I						2
#define CONVITY_INTR_CKDETI						3

#define NUM_CONVITY_INTR						4

#define MC13783_INT_SEN0_CONVITYBITS_LSH			16
#define MC13783_INT_SEN0_CONVITYBITS_WID			7

#define MC13783_INT_SEN0_CONVITYBITS_USB4V4S		(1 << 0)
#define MC13783_INT_SEN0_CONVITYBITS_USB2V0S		(1 << 1)
#define MC13783_INT_SEN0_CONVITYBITS_USB0V8S		(1 << 2)
#define MC13783_INT_SEN0_CONVITYBITS_IDFLOATS		(1 << 3)
#define MC13783_INT_SEN0_CONVITYBITS_IDGNDS		(1 << 4)
#define MC13783_INT_SEN0_CONVITYBITS_SE1S			(1 << 5)
#define MC13783_INT_SEN0_CONVITYBITS_CKDETS		(1 << 6)

#define ENTRY_MSG		DEBUGMSG(ZONE_FUNC, (TEXT("+%s()\r\n"), __WFUNCTION__))
#define EXIT_MSG		DEBUGMSG(ZONE_FUNC, (TEXT("-%s()\r\n"), __WFUNCTION__))

//-----------------------------------------------------------------------------
// Types

// This enumeration is used to track the current state of each device handle.
typedef enum
{
    HANDLE_FREE,  /* Handle is available for use. */
    HANDLE_IN_USE /* Handle is currently in use.  */
} HANDLE_STATE;

/*
 * This structure maintains the current state of the connectivity driver. This
 * includes both the PMIC hardware state as well as the device handle and
 * callback states.
 */
typedef struct
{
    PMIC_CONVITY_HANDLE                       handle;           /* Device handle.      */
    HANDLE_STATE                              handleState;      /* Device handle
                                                                   state.              */
    PMIC_CONVITY_MODE                         mode;             /* Device mode.        */
    PMIC_CONVITY_CALLBACK                     callback;         /* Event callback
                                                                   function pointer.   */
    PMIC_CONVITY_EVENTS                       eventMask;        /* Event mask.         */
    PMIC_CONVITY_USB_SPEED                    usbSpeed;         /* USB connection
                                                                   speed.              */
    PMIC_CONVITY_USB_MODE                     usbMode;          /* USB connection
                                                                   mode.               */
    PMIC_CONVITY_USB_POWER_IN                 usbPowerIn;       /* USB transceiver
                                                                   power source.       */
    PMIC_CONVITY_USB_POWER_OUT                usbPowerOut;      /* USB transceiver
                                                                   power output
                                                                   level.              */
    PMIC_CONVITY_USB_TRANSCEIVER_MODE         usbXcvrMode;      /* USB transceiver
                                                                   mode.               */
    unsigned int                              usbDlpDuration;   /* USB Data Line
                                                                   Pulsing duration.   */
    PMIC_CONVITY_USB_OTG_CONFIG               usbOtgCfg;        /* USB OTG
                                                                   configuration
                                                                   options.            */
    PMIC_CONVITY_RS232_INTERNAL               rs232CfgInternal; /* RS-232 internal
                                                                   connections.        */
    PMIC_CONVITY_RS232_EXTERNAL               rs232CfgExternal; /* RS-232 external
                                                                   connections.        */
	BOOL                                      rs232TxTristated; /* RS-232 TX state     */

	PMIC_CONVITY_CEA936_DETECTION_CONFIG      cea936DetectCfg;  /* CEA-936 device 
																   detection circuitry */
} PMIC_CONVITY_STATE_STRUCT;


//-----------------------------------------------------------------------------
// Global Variables

// This structure defines the reset/power on state for the Connectivity driver.
static const PMIC_CONVITY_STATE_STRUCT reset =
{
	0,
	HANDLE_FREE,
	USB,
	NULL,
	(PMIC_CONVITY_EVENTS)0,
	USB_FULL_SPEED,
	USB_PERIPHERAL,
	USB_POWER_INTERNAL,
	USB_POWER_3V3,
	USB_TRANSCEIVER_OFF,
	0,
	(PMIC_CONVITY_USB_OTG_CONFIG)(USB_VBUS_CURRENT_LIMIT_HIGH),
	RS232_TX_USE0VM_RX_UDATVP,
	RS232_TX_UDM_RX_UDP,
	FALSE,
	ACCESSORY_ID_DP150KPU
};

// This structure maintains the current state of the Connectivity driver.
static PMIC_CONVITY_STATE_STRUCT convity;

/*
 * We use a mutex to ensure that no race condition arises in register states (inside ioctl handlers)
 * as well as convity data structure between the API calls and interrupt service thread.
 */
static CRITICAL_SECTION mutex;

static PMIC_PARAM_CONVITY_OP param;

static HANDLE hThread = NULL;
static bool threadContinue = 0;

// data structures that help handle all the connectivity interrupts in a loop.
static HANDLE hEventTab[] = {NULL, NULL, NULL, NULL};
static WCHAR* evtNames[] = 
{
	TEXT("EVENT_CONVITY_USBI"), 
	TEXT("EVENT_CONVITY_IDI"), 
	TEXT("EVENT_CONVITY_SE1I"),
	TEXT("EVENT_CONVITY_CKDETI")
};
static PMIC_INT_ID interruptTab[] = 
{
	PMIC_MC13783_INT_USBI, 
	PMIC_MC13783_INT_IDI, 
	PMIC_MC13783_INT_SE1I,
	PMIC_MC13783_INT_CKDETI
};


//-----------------------------------------------------------------------------
// Local Variables

//-----------------------------------------------------------------------------
// Local Functions


PMIC_STATUS PmicConvityInit(void)
{
	ENTRY_MSG;

	// Initialize the driver state to default state.
	convity = reset;

	// Initialize mutex.
	InitializeCriticalSection(&mutex);

	EXIT_MSG;
	return PMIC_SUCCESS;
}

void PmicConvityDeinit(void)
{
	ENTRY_MSG;
	// Free mutex.
	DeleteCriticalSection(&mutex);
	EXIT_MSG;
}


// Read the sense bits relevant to Connectivity from MC13783 interrupt sense
// 0 register.
static UINT32 GetSenseBits()
{
	UINT32 addr, temp;
	addr = MC13783_INT_SEN0_ADDR;

	if(!DeviceIoControl(hPMI, PMIC_IOCTL_LLA_READ_REG, &addr, sizeof(addr),
			&temp, sizeof(temp), NULL, NULL))
		return 0;

	return CSP_BITFEXT(temp, MC13783_INT_SEN0_CONVITYBITS);
}

// Look at the interrupt, new and previous sense bits and find out the occurred events
static PMIC_CONVITY_EVENTS GetSignalledEvents(int intrIndex, UINT32 oldSenseBits,
		UINT32 newSenseBits)
{
	UINT32 signals = 0;

	switch (intrIndex)
	{
	case CONVITY_INTR_USBI:
		// Check if 4.4V sense bit has changed.
		if ((oldSenseBits & MC13783_INT_SEN0_CONVITYBITS_USB4V4S) ^
			(newSenseBits & MC13783_INT_SEN0_CONVITYBITS_USB4V4S))
		{
			signals |= (newSenseBits & MC13783_INT_SEN0_CONVITYBITS_USB4V4S) ?
				USB_DETECT_4V4_RISE : USB_DETECT_4V4_FALL;
		}
		// Check if 2.0V sense bit has changed.
		if ((oldSenseBits & MC13783_INT_SEN0_CONVITYBITS_USB2V0S) ^
			(newSenseBits & MC13783_INT_SEN0_CONVITYBITS_USB2V0S))
		{
			signals |= (newSenseBits & MC13783_INT_SEN0_CONVITYBITS_USB2V0S) ?
				USB_DETECT_2V0_RISE : USB_DETECT_2V0_FALL;
		}
		// Check if 0.8V sense bit has changed.
		if ((oldSenseBits & MC13783_INT_SEN0_CONVITYBITS_USB0V8S) ^
			(newSenseBits & MC13783_INT_SEN0_CONVITYBITS_USB0V8S))
		{
			signals |= (newSenseBits & MC13783_INT_SEN0_CONVITYBITS_USB0V8S) ?
				USB_DETECT_0V8_RISE : USB_DETECT_0V8_FALL;
		}
		break;

	case CONVITY_INTR_IDI:
		//  Look at the current value of IDFLOATS and IDGNDS bits and determine the event.
		//			IDFLOATS		IDGNDS				Meaning
		//			============================================
		//				0				0				Non-USB accessory is attached.
		//				0				1				A type plug (USB host) is attached.
		//				1				0				B type plug (USB peripheral, OTG device 
		//												or no device) is attached.
		//				1				1				Factory mode.
		if (newSenseBits & MC13783_INT_SEN0_CONVITYBITS_IDFLOATS)
		{
			signals |= (newSenseBits & MC13783_INT_SEN0_CONVITYBITS_IDGNDS) ?
				USB_DETECT_FACTORY_MODE : USB_DETECT_MINI_B;
		}
		else
		{
			signals |= (newSenseBits & MC13783_INT_SEN0_CONVITYBITS_IDGNDS) ?
				USB_DETECT_MINI_A : USB_DETECT_NON_USB_ACCESORY;
		}
		break;

	case CONVITY_INTR_SE1I:
		// Look at SE1S to find out if it is rise or fall event.
		signals |= (newSenseBits & MC13783_INT_SEN0_CONVITYBITS_SE1S) ?
				USB_DETECT_SE1_RISE : USB_DETECT_SE1_FALL;
		break;

	case CONVITY_INTR_CKDETI:
		// CKDETI occurs only when CKDETS changed from 0 to 1. (CKDETS is L2H only).
		signals |= USB_DETECT_CKDETECT;
		break;

	default:
		break;
	}
	
	return (PMIC_CONVITY_EVENTS)signals;
}

//  Thread that waits for interrupt events to be signalled. Upon occurrence of an interrupt,
//  it finds out the event bits to inform the callback function.
static BOOL PmicConvityIsrThreadProc(LPVOID lpParam)
{
	// This variable keeps the previous known value of the sense bits. Upon occurrence
	// of an interrupt, the current values of sense bits and this (previous) value is used
	// to find out which event has occurred. Needed for USBI related sense bits only.
	static UINT32 senseBits = 0;
	int iRetVal;
	int iCount = 0;
	UINT32 newSenseBits;
	UINT32 events;


	SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);

	senseBits = GetSenseBits();
	while(threadContinue != 0)
	{
		iRetVal = WaitForMultipleObjects(NUM_CONVITY_INTR, hEventTab, FALSE, INFINITE);
		if ((iRetVal >= WAIT_OBJECT_0) && (iRetVal <= WAIT_OBJECT_0 + NUM_CONVITY_INTR - 1))
		{
			iRetVal -= WAIT_OBJECT_0;
			newSenseBits = GetSenseBits();
			events = GetSignalledEvents(iRetVal, senseBits, newSenseBits);
			events &= convity.eventMask;

			if ((convity.callback != NULL) && events)
				(*convity.callback)(events);

			// save the new sense bits in the global variable senseBits.
			senseBits = newSenseBits;

			// inform the system that interrupt handling is complete.
			PmicInterruptHandlingComplete(interruptTab[iRetVal]);
		}
	}

	ExitThread(TRUE);

	return TRUE;
}

// cleans up callback related data structures.
static PMIC_STATUS cleanup()
{
	int i;

	threadContinue = 0;
	for (i = 0; i < NUM_CONVITY_INTR; i++)
	{
		if (hEventTab[i])
		{
			PmicInterruptDeregister(interruptTab[i]);
			hEventTab[i] = NULL;
		}
	}
	hThread = NULL;
	convity.callback = (PMIC_CONVITY_CALLBACK)NULL;
	convity.eventMask = (PMIC_CONVITY_EVENTS)0;

	return PMIC_SUCCESS;
}


/*!
 * Attempt to open and gain exclusive access to the PMIC connectivity
 * hardware. An initial operating mode must also be specified.
 *
 * If the open request is successful, then a numeric handle is returned
 * and this handle must be used in all subsequent function calls. The
 * same handle must also be used in the pmic_convity_close() call when use
 * of the PMIC connectivity hardware is no longer required.
 *
 * @param       handle          device handle from open() call
 * @param       mode            initial connectivity operating mode
 *
 * @return      PMIC_SUCCESS    if the open request was successful
 */
PMIC_STATUS PmicConvityOpen(
    PMIC_CONVITY_HANDLE *const handle,
    const PMIC_CONVITY_MODE    mode)
{
    PMIC_STATUS rc = PMIC_ERROR;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -