?? 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 + -