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

📄 adc.c

📁 SMDK2410_ZY_V11.rar
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************Copyright (c)**************************************************
**                               Guangzhou ZHIYUAN electronics Co.,LTD.
**                                     
**                                 http://www.zyinside.com
**
**--------------File Info-------------------------------------------------------------------------------
** File Name: 				adc.c
** Last modified Date: 		2006.10.09
** Last Version:			V1.0		
** Description: 			adc.c, S3C2410A 自带 A/D 转换器驱动程序 
**                          adc.c, the A/D driver of the S3C2410A A/D converter  
**------------------------------------------------------------------------------------------------------
** Created By: 				MingYuan Zheng 郑明远
** Created date: 			2006.10.09
** Version: 				V1.0
** Descriptions:			The original version 初始版本
**
**------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
** Version:
** Description:
**
********************************************************************************************************/


#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 <s3c2410x.h>
#include "ADC.h"

#define PRIVATE			static
#define PUBLIC


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

PRIVATE DWORD  m_s3c2410_pclk;		/* S3C2410 PCLK 时钟 */

PRIVATE DWORD  m_ADC_MaxFreq;		/* ADC 转换最大频率 */
PRIVATE DWORD  m_ADC_MinFreq;		/* ADC 转换最小频率 */

PRIVATE DWORD  m_ADC_OpenCout = 0;	/* 本驱动打开计数器 */


// ADC 寄存器暂存变量, 这是由于触摸屏也使用了 ADC
PRIVATE DWORD  m_tmp_ADCCON;
PRIVATE DWORD  m_tmp_ADCTSC;
PRIVATE DWORD  m_tmp_ADCDLY;


// S3C2410X 默认外设时钟
#define  DEFAULT_S3C2410X_PCLK     (203000000 / 4)

// ADC 转换通道个数
#define  ADC_CHANNEL_NUM		   7

// ADC 转换最大频率
#define  ADC_MAX_FREQ			   2500000	

// ADC 转换最大分频值			
#define  ADC_MAX_DIV			   256

// ADC 默认转换频率	2.5MHz
#define  ADC_DEFAULT_FREQ	       (2500000)


/*******************************************************************************************
函数名称: ADC_InitializeRegister
描    述: 初始化 ADC 硬件寄存器:  ADCCON 和 ADCTSC
输入参数: DWORD cpu_pclk:  CPU 的外设时钟	
输出参数: 无
返    回: 无
********************************************************************************************/
PRIVATE void ADC_InitializeRegister(DWORD cpu_pclk)
{
	// 保存 ADC 寄存器原来的设置值
	m_tmp_ADCCON = v_pADCregs->ADCCON;
	m_tmp_ADCTSC = v_pADCregs->ADCTSC; 
	m_tmp_ADCDLY = v_pADCregs->ADCDLY;

	v_pADCregs-> ADCCON = ADCCON_PRSCEN_EN |							// 使能 ADC 转换分频 
		                  ((cpu_pclk / ADC_DEFAULT_FREQ - 1) << 6) |  	// 设置 ADC 默认转换时钟
		                  ADCCON_CHANNEL_0 | 							// 默认 ADC 转换通道
						  ADCCON_NORMAL_MODE  |							// ADC 标准模式
						  ADCCON_EN_READSTART | 						// 使能读操作开始转换
						  ADCCON_DIS_START;								// 禁止 ADC 进行转换
	
	v_pADCregs->ADCTSC = v_pADCregs->ADCTSC & ~ADCTSC_NORMAL_MODE;	    // 普通ADC模式(非触摸屏)

	v_pADCregs->ADCDLY = 1;                                             // 延时时间最小
}


/*******************************************************************************************
函数名称: ADC_InitializeAddresses
描    述: 取得相关寄存器的虚拟地址
输入参数: 无
输出参数: 无
返    回: > 0 分配到的虚拟地址;  FALSE: 失败
********************************************************************************************/
PRIVATE BOOL ADC_InitializeAddresses(void)
{
	BOOL	RetValue = TRUE;
		
	/* ADC Register Allocation */
	v_pADCregs = (volatile S3C2410X_ADC_REG *)VirtualAlloc(0, sizeof(S3C2410X_ADC_REG), MEM_RESERVE, PAGE_NOACCESS);
	if (v_pADCregs == NULL) 
	{
		ERRORMSG(1,(TEXT("For ADCregs : VirtualAlloc failed!\r\n")));
		RetValue = FALSE;
	}
	else 
	{
		if (!VirtualCopy((PVOID)v_pADCregs, (PVOID)(S3C2410X_BASE_REG_PA_ADC >> 8), sizeof(S3C2410X_ADC_REG), PAGE_PHYSICAL | PAGE_READWRITE | PAGE_NOCACHE)) 
		{
			ERRORMSG(1,(TEXT("For ADCregs: VirtualCopy failed!\r\n")));
			RetValue = FALSE;
		}
	}
	
	if (!RetValue) 
	{
		RETAILMSG (1, (TEXT("::: ADC_InitializeAddresses - Fail!!\r\n") ));

		if (v_pADCregs) 
		{
			VirtualFree((PVOID) v_pADCregs, 0, MEM_RELEASE);
		}

		v_pADCregs = NULL;
	}

	return(RetValue);
}


/*******************************************************************************************
函数名称: ADC_GetLimitFreqency
描    述: 取得 ADC 转换器极限频率: 最高及最低转换频率
输入参数: DWORD cpu_pclk:  CPU 的外设时钟
输出参数: DWORD *max    :  ADC 转换频率最高值
		  DWORD *min    :  ADC 转换频率最低值
返    回: TRUE: 成功;  FALSE: 失败
********************************************************************************************/
PRIVATE BOOL ADC_GetLimitFreqency(DWORD cpu_pclk, DWORD *max, DWORD *min)
{
	DWORD maxval, minval;

    if ((cpu_pclk / 5) > ADC_MAX_FREQ)
    	maxval = ADC_MAX_FREQ;				/* 取得 ADC 转换最高频率 */
    else
    	maxval = cpu_pclk / 5;				/* 频率必须少于pclk的5倍 */
    	
   	minval = (cpu_pclk / ADC_MAX_DIV);  	/* 取得ADC转换最低频率 */
   	
   	if (minval >= maxval)
   		return FALSE;						/* 存在不合理 */
	
	*max = maxval;
	*min = minval;	

	return TRUE;
}


/*******************************************************************************************
函数名称: ADC_GetCurFreqency
描    述: 取得 ADC 当前转换器频率
输入参数: DWORD cpu_pclk:  CPU 的外设时钟
输出参数: 无
返    回: ADC 当前转换器频率
********************************************************************************************/
PRIVATE DWORD ADC_GetCurFreqency(DWORD cpu_pclk)
{
	DWORD adcfrequency;

    /* calculate the clock of IIC transmit speed */
    adcfrequency = cpu_pclk / (((v_pADCregs-> ADCCON  & ADCCON_PRSCVL_MSK) >> 6) + 1);

    return adcfrequency;
}


/*******************************************************************************************
函数名称: ADC_SetFreqency
描    述: 设置 ADC 转换器频率
输入参数: DWORD cpu_pclk:  CPU 的外设时钟
		  DWORD adc_freq:  ADC 转换频率
输出参数: 无
返    回: 实际的 ADC 转换频率, 如果超出范围,则返回最低转换频率
********************************************************************************************/
PRIVATE DWORD ADC_SetFreqency(DWORD cpu_pclk, DWORD adc_freq)
{
	DWORD adcfrequency;
	
	if ((adc_freq > m_ADC_MaxFreq) || (adc_freq < m_ADC_MinFreq))
		return m_ADC_MinFreq;

    /* 写入 ADC 转换频率分频值, 使设置生效 */
    v_pADCregs-> ADCCON &= ~ADCCON_PRSCVL_MSK;
	v_pADCregs-> ADCCON |= (cpu_pclk / adc_freq - 1) << 6;
    
    adcfrequency = ADC_GetCurFreqency(cpu_pclk);
    
    return adcfrequency;
}



/*******************************************************************************************
函数名称: ADC_Init
描    述: 驱动程序初始化函数
输入参数: DWORD dwContext: 设备管理器传递给本驱动的参数, 通常为流接口驱动在注册表内的位置 	
输出参数: 无
返    回: 驱动程序句柄
*******************************************************************************************/
PUBLIC DWORD ADC_Init(DWORD dwContext)
{
	PROCESSOR_INFO procInfo;
	DWORD dwBytesReturned;

    /* get the information of the device */
    if (!KernelIoControl(IOCTL_PROCESSOR_INFORMATION, NULL, 0, &procInfo, sizeof(PROCESSOR_INFO), &dwBytesReturned))
    {
        m_s3c2410_pclk = DEFAULT_S3C2410X_PCLK;
        RETAILMSG(TRUE, (TEXT("WARNING: ADC_Init failed to obtain processor frequency - using default value (%d).\r\n"), m_s3c2410_pclk)); 
    }
    else
    {
        m_s3c2410_pclk = procInfo.dwClockSpeed;
        RETAILMSG(TRUE, (TEXT("INFO: ADC_Init using processor frequency reported by the OAL (%d).\r\n"), m_s3c2410_pclk)); 
    }
	
	/* 获取 ADC 物理寄存器对应的虚拟空间 */
	ADC_InitializeAddresses();	

    RETAILMSG(1, (TEXT("::: ADC_Init Out\r\n")));

	return (DWORD)1;
}


/*******************************************************************************************
函数名称: DllEntry
描    述: 驱动程序动态库入口
输入参数: 	

⌨️ 快捷键说明

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