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

📄 adc.cpp

📁 wince5.0环境 S3C2440平台 ADC驱动程序
💻 CPP
字号:
#include <windows.h>
#include <types.h>
#include <excpt.h>
#include <tchar.h>
#include <cardserv.h>
#include <cardapi.h>
#include <tuple.h>
#include <devload.h>
#include <diskio.h>
#include <nkintr.h>
#include <windev.h>
#include <Pkfuncs.h>
#include <bsp.h>
#include <s3c2440a.h>
#include <string.h>

#define PRIVATE			static
#define PUBLIC

HANDLE g_hevInterrupt;//中断事件句柄
HANDLE g_htIST;
DWORD dwThreadID;

struct ADC_DEV{

	CRITICAL_SECTION	ADC_CS;			//临界区
	char				channel;		//通道选择
	char				prescale;		//预分频
	DWORD				OpenCnt;		// @field Protects use of this port 
	
}adcdev;
struct ADC_DEV *pADC_Dev;

/* I2C 的物理中断号及逻辑中断号 */
UINT32 g_ADCIrq = IRQ_ADC;
UINT32 g_ADCSysIntr = 31;             //this value set in the file: "intr.c"  function: "OEMInterruptHandler"

/* ADC 寄存器对应的虚拟地址 */
PRIVATE volatile S3C2440A_ADC_REG * v_pADCPregs;

/* INT 寄存器对应的虚拟地址 */
PRIVATE volatile S3C2440A_INTR_REG * v_pINTPregs;


//////////////////////////////////////////////////////////////////////////////
PUBLIC BOOL WINAPI
DllEntry(HANDLE hInstDll, DWORD dwReason, LPVOID lpvReserved)
{	
	switch (dwReason)
	{
		case DLL_PROCESS_ATTACH:
			//RETAILMSG(1,(TEXT("ADC:DLL_PROCESS_ATTACH\t\n")));
			return TRUE;
	
		case DLL_PROCESS_DETACH:
			//RETAILMSG(1,(TEXT("ADC:DLL_PROCESS_DETACH\t\n")));
			break;
	}

    return TRUE;
}

DWORD WINAPI AdcEventHandler(LPVOID a)//
{
	
		//RETAILMSG(1,(TEXT("AdcEventHandler: Waiting For Interruption Event!\r\n")));
		WaitForSingleObject(g_hevInterrupt,INFINITE);
		//RETAILMSG(1,(TEXT("AdcEventHandler: Interruption has happend! Exit ADC Handler\r\n")));
		InterruptDone(g_ADCSysIntr);
		
		return 0;

}


PRIVATE BOOL ADC_InitializeAddresses(void)
{
	BOOL	RetValue = TRUE;

	RETAILMSG(1, (TEXT(">>> ADC_initalization address..set..\r\n")));
		
	//	ADC Register Allocation
	v_pADCPregs = (volatile S3C2440A_ADC_REG *)VirtualAlloc(0, sizeof(S3C2440A_ADC_REG), MEM_RESERVE, PAGE_NOACCESS);
	if (v_pADCPregs == NULL) 
	{
		ERRORMSG(1,(TEXT("For ADCPregs : VirtualAlloc failed!\r\n")));
		RetValue = FALSE;
	}
	else 
	{
		if (!VirtualCopy((PVOID)v_pADCPregs, (PVOID)(S3C2440A_BASE_REG_PA_ADC >> 8), sizeof(S3C2440A_ADC_REG), PAGE_PHYSICAL | PAGE_READWRITE | PAGE_NOCACHE)) 
		{
			ERRORMSG(1,(TEXT("For ADCPregs: VirtualCopy failed!\r\n")));
			RetValue = FALSE;
		}
	}
	
	if (!RetValue) 
	{
		RETAILMSG (1, (TEXT("::: ADC_InitializeAddresses - Fail!!\r\n") ));

		if (v_pADCPregs) 
			VirtualFree((PVOID) v_pADCPregs, 0, MEM_RELEASE);

		v_pADCPregs = NULL;
	}
	
	
	//	INT Register Allocation
	v_pINTPregs = (volatile S3C2440A_INTR_REG *)VirtualAlloc(0, sizeof(S3C2440A_INTR_REG), MEM_RESERVE, PAGE_NOACCESS);
    
	if (v_pINTPregs == NULL) 
	{
		ERRORMSG(1,(TEXT("For INTPregs : VirtualAlloc failed!\r\n")));
		RetValue = FALSE;
	}
	else 
	{                                                     
		if (!VirtualCopy((PVOID)v_pINTPregs, (PVOID)(S3C2440A_BASE_REG_PA_INTR >> 8), sizeof(S3C2440A_INTR_REG), PAGE_PHYSICAL | PAGE_READWRITE | PAGE_NOCACHE)) 
		{
			ERRORMSG(1,(TEXT("For INTPregs: VirtualCopy failed!\r\n")));
			RetValue = FALSE;
		}
	}
	if (!RetValue) 
	{
		RETAILMSG (1, (TEXT("::: ADC_InitializeAddresses - Fail!!\r\n") ));

		if (v_pINTPregs) 
			VirtualFree((PVOID) v_pINTPregs, 0, MEM_RELEASE);

		v_pINTPregs = NULL;
	}
	
	

	return(RetValue);
}

void ADC_Init (void)
{

	pADC_Dev=&adcdev;

	InitializeCriticalSection(&(pADC_Dev->ADC_CS));     //初始化一个临界资源对象

	ADC_InitializeAddresses();

	// 从 OAL 请求一个 SYSINTR 值
/*    if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &g_ADCIrq, sizeof(UINT32), &g_ADCSysIntr, sizeof(UINT32), NULL))
    {
        RETAILMSG(1, (TEXT("ERROR: ADC: Failed to request sysintr value for ADC interrupt.\r\n")));
        return;
    }

    RETAILMSG(1,(TEXT("INFO: ADC: Mapped Irq 0x%d to SysIntr 0x%d.\r\n"), g_ADCIrq, g_ADCSysIntr));
*/
	////////////////Initialize Event/////////////////
	g_hevInterrupt = CreateEvent(NULL,FALSE,FALSE,NULL);	//create event

	if(g_hevInterrupt==NULL)
	{
		RETAILMSG(1,(TEXT("ERROR: ADC_Init: Event creation failed!\r\n")));
		return;
	}

	//注册中断
	if(!InterruptInitialize(g_ADCSysIntr,g_hevInterrupt,NULL,0))
	{
		RETAILMSG(1,(TEXT("ERROR: InterruptInitialize failed!\r\n")));
		return;
	}
			
}

/////////////////////////////////////////////////////////////////////////////////////////////////


/////////////////////////////////////////////////////////////////////////////////////////////////
DWORD ADC_Open(HANDLE hDeviceContext,
			   DWORD AccessCode,
			   DWORD ShareMode)
{
	return(1);
}

BOOL ADC_Close(DWORD hOpenContext)
{
	return TRUE;
}


DWORD ADC_Deinit(DWORD dwDeviceContext)
{
	RETAILMSG(1, (TEXT(":::ADC: ADC Driver deinit.\r\n")));

	// 通知中断服务线程退出
	PulseEvent(g_hevInterrupt);		
	Sleep(200);												/* 等待.... */

	// 释放中断资源
	InterruptDone(g_ADCSysIntr);
	InterruptDisable(g_ADCSysIntr);
	KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR, &g_ADCSysIntr, sizeof(UINT32), NULL, 0, NULL);

	/* 释放申请的虚拟内存 */
	if (v_pADCPregs)
		VirtualFree((PVOID)v_pADCPregs, 0, MEM_RELEASE);

	if (v_pINTPregs)
		VirtualFree((PVOID)v_pINTPregs, 0, MEM_RELEASE);
	
        return TRUE;
}


BOOL ADC_IOControl(DWORD hOpenContext,
					DWORD dwCode,
					PBYTE pBufIn,
					DWORD dwLenIn,
					PBYTE pBufOut,
					DWORD dwLenOut,
					PDWORD pdwActualOut)
{
	return(TRUE);
}


DWORD ADC_Read(DWORD hOpenContext,
			   LPVOID pBuffer,
			   DWORD Count)
{
	//int m_nISTPriority;
	DWORD ReturnValue;

	////////////////Initialize Thread/////////////////
	g_htIST= CreateThread(	NULL,
							0,
							 AdcEventHandler,
							NULL,
							CREATE_SUSPENDED,
							&dwThreadID
						 );
	
	//设置优先级
	if(!CeSetThreadPriority(g_htIST,151))
	{
		RETAILMSG(1,(TEXT("ADC_READ: Failed setting Thread Priority.\r\n")));
		return 0;
	}
	//恢复IST
	if(ResumeThread(g_htIST) == 0xFFFFFFFF)
	{
		RETAILMSG(1,(TEXT("ADC_READ: Resume Thread failure!.\r\n")));
		return 0;
	}

	///////////////Initialize Thread Over///////////////
	
	///////////////////Enable ADC//////////////////
	EnterCriticalSection(&(pADC_Dev->ADC_CS));

	///////////////////Enable INT//////////////////
	v_pINTPregs->INTMSK &= ~(1<<31);
	v_pINTPregs->INTSUBMSK &= ~(1<<10);

    ///////////////////A/D conversion starts////////////
	v_pADCPregs->ADCCON |= 1;

	LeaveCriticalSection(&(pADC_Dev->ADC_CS));

//	RETAILMSG(1,(TEXT("ADC_READ: ADCCON '%x'\r\n"),v_pADCPregs->ADCCON));
//	RETAILMSG(1,(TEXT("ADC_Write: INTMSK = '%x'\r\n"),v_pINTPregs->INTMSK));
//	RETAILMSG(1,(TEXT("ADC_Write: INTSUBMSK = '%x'\r\n"),v_pINTPregs->INTSUBMSK));

	///////////////////Wait for the ThreadObject////////////////

	ReturnValue=WaitForSingleObject(g_htIST ,200);	
	//////////////////Wait for the Thread Object Over////////////

	if(ReturnValue==WAIT_OBJECT_0)
	{
		///////////////////Write Buffer/////////////////////////
		
		EnterCriticalSection(&(pADC_Dev->ADC_CS));

		*((DWORD *)pBuffer)=v_pADCPregs->ADCDAT0;
		(*((DWORD *)pBuffer))&=0x03ff;

//		RETAILMSG(1,(TEXT("ADC_READ: Read Success! ADCDAT0 '%x'\r\n"),*((DWORD *)pBuffer)));
		LeaveCriticalSection(&(pADC_Dev->ADC_CS));

		//////////////////Write Buffer Over/////////////////////

		return 4;
	}
	else if(ReturnValue==WAIT_TIMEOUT)
	{
	
		RETAILMSG(1,(TEXT("ADC_READ: Read Timeout! \r\n")));
		
		TerminateThread(g_htIST,0);   //结束线程
		return 1;
	}
	else
	{
		RETAILMSG(1,(TEXT("ADC_READ: Do Not Know What Was Wrong!\r\n")));
		return 0;
	}
}


DWORD ADC_Write(DWORD hOpenContext,
				LPCVOID pSourceBytes,
				DWORD NumberOfBytes)
{
	DWORD *ADCControl;

	EnterCriticalSection(&(pADC_Dev->ADC_CS));    //申请进入临界对象
	
	ADCControl=(DWORD *)pSourceBytes;

	v_pADCPregs->ADCCON &= 0x8000;
	v_pADCPregs->ADCCON |= 0x4000;                      //A/D转换器预分频器使能
	v_pADCPregs->ADCCON |=((*ADCControl)&0xff)<<6;      //A/D 转换器预分频器数值
    v_pADCPregs->ADCCON |=((*(++ADCControl))&7)<<3;     //模拟输入通道选择
	
	LeaveCriticalSection(&(pADC_Dev->ADC_CS));          //释放临界对象

	return 4;
}


DWORD ADC_Seek(DWORD hOpenContext,
			   long Amount,
			   DWORD Type)
{
	return FALSE;
}

⌨️ 快捷键说明

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