📄 adc.c
字号:
/*
********************************************************************************
*
* LCD控制程序
*
* 这是SCALAR当中与ADC相关的部分
*
* 文件名 : ADC.C
* 设计者 : Terry
********************************************************************************
* 功 能 描 述
*
* 1. ADC是SCALAR的一部分,我们将这一部分独立开来以便于管理和区分
* 2. 与ADC接口的函数,包括初始化部分都放在这里
* 3. 所有可调参数的输入都限定在00-FF的范围内
* 4. 同时这个部分也包含了sRGB的处理
********************************************************************************
*/
#include "global.h"
#include "scalar.h"
static int16 sine(uint8 alpha);
static int16 cosine(uint8 alpha);
static void product(int16 *first, int16 * second, int16 *result);
/*
********************************************************************************
* 函 数 名: AdcInit
* 功能描述: 初始化
* 输 入: 无
* 返 回: 无
********************************************************************************
*/
void AdcInit(void)
{
AdcUpdatePara(&AdcPar);
AdjBri(HIDE, 0);
}
/*
********************************************************************************
* 函 数 名: AdcSetPhase
* 功能描述: 输出ADC的采样相位
* 输 入: pahse :相位值
* 返 回: 无
********************************************************************************
*/
void AdcSetPhase(uint8 phase)
{
WrScalarReg(rP0D9, phase); // 低6位才是phase的制, 高两位是选择调整时钟
// 延时的通道
}
/*
********************************************************************************
* 函 数 名: AdcSetPll
* 功能描述: 输出ADC的采样时钟
* 输 入: htotal : 当前的采样时钟
* 返 回: 无
********************************************************************************
*/
uint8 code DpllSeqTab[4] = {100,48,20,0};
void AdcSetPll(uint16 htotal)
{
//uint32 xdata Hcount;
uint32 PixelRate;
uint8 k, i;
float temp;
// 根据Application Note的说明,在设置HPLL或者DPLL以及从Free Run模式返回正常
// 显示模式,都需要将寄存器0xB04的bit0先置位1,然后再清成0
WrScalarRegBit(rPB04, B0000_0001, B0000_0001);
WrScalarRegBit(rPB04, B0000_0000, B0000_0001);
WrScalarReg(rP0D0, 0x41);
// 根据信号是否位绿色同步来分别设置钳位的宽度(寄存器0x022)
// 计算像素时钟(单位是MHz),公式: 水平同步频率 * 水平所有的像素
k = ((uint32)htotal * 96)/SyncAttr.Hcount;
for (i = 0; i < 4; i++) {
if (k > DpllSeqTab[i]) break;
}
WrScalarReg(rP0D1, 0x10 + i);
WrScalarReg(rP0DB, 0x08);
/*
================================================================================
= 对背光是开的状态进行处理
================================================================================
*/
if (!Flg_BackLighPower) {
ulHfreqCounter = 0;
SysTmr = 100/SYSTMR_PRIO; // 250ms
while(SysTmr != 0) {
PixelRate = RdScalarWord(rP0DE);
PixelRate <<= 8;
PixelRate += RdScalarReg(rP0DD);
if (abs(PixelRate - ulHfreqCounter) > 2) {
ulHfreqCounter = PixelRate;
SysTmr = 100/SYSTMR_PRIO;
}
}
}
else {
PixelRate = RdScalarWord(rP0DE);
PixelRate <<= 8;
PixelRate += RdScalarReg(rP0DD);
}
temp = ((float)htotal * 536870912L) / PixelRate;
PixelRate = temp;
for(i; i>0; i--) {
PixelRate <<= 1;
}
WrScalarReg(rP0D2, (uint8)PixelRate);
WrScalarReg(rP0D3, (uint8)(PixelRate>>8));
WrScalarReg(rP0D4, (uint8)(PixelRate>>16));
WrScalarWord(rP0D7, htotal);
if (RdScalarReg(rP000) & BIT_4) {
//if (RdScalarReg(rP19A) & BIT_0) WrScalarReg(rP0D5, 0x09);
//else WrScalarReg(rP0D5, 0x01);
WrScalarReg(rP0D5, 0x01);
}
else {
if (RdScalarReg(rP19A) & BIT_0) WrScalarReg(rP0D5, 0x01);
else WrScalarReg(rP0D5, 0x09);
}
}
#if 0
uint8 code DpllSeqTab[4] = {100,50,20,0};
uint32 xdata Hcount;
void AdcSetPll(uint16 htotal)
{
uint32 PixelRate;
uint8 k, i;
float temp;
// 计算像素时钟(单位是MHz),公式: 水平同步频率 * 水平所有的像素
k = ((uint32)htotal * 96)/SyncAttr.Hcount;
//WrScalarReg(rP0D0, 0x43); // 在垂直消隐时更新数据
WrScalarReg(rP0D0, 0x53); // 0x53的数据是在2007年01月10日修改的
for (i = 0; i < 4; i++) {
if (k > DpllSeqTab[i]) break;
}
WrScalarReg(rP0D1, 0x10 + i);
WrScalarReg(rP0DB, 0x0C); // 2006-07-10修改
//if (Hfre < 2400) WrScalarReg(rP0DB, 0x0C);
//else if (Hfre < 4800) WrScalarReg(rP0DB, 0x0D);
//else WrScalarReg(rP0DB, 0x0E);
/*
================================================================================
= 对背光是开的状态进行处理
================================================================================
*/
//k = RdScalarReg(rP19A) & 0x01;
//if (k) k = 0x08;
//else k = 0x00;
if (!Flg_BackLighPower) {
//WrScalarReg(rP0D5, 0x01 + k);
WrScalarReg(rP0D5, 0x01);
Hcount = 0;
SysTmr = 100/SYSTMR_PRIO; // 250ms
while(SysTmr != 0) {
PixelRate = (((uint32)(RdScalarReg(rP0DF) & 0x3F))<<16) +
((uint16)RdScalarReg(rP0DE)<<8) + RdScalarReg(rP0DD);
if (abs(PixelRate - Hcount) > 2) {
Hcount = PixelRate;
SysTmr = 100/SYSTMR_PRIO;
}
}
}
else {
PixelRate = (((uint32)(RdScalarReg(rP0DF) & 0x3F))<<16) +
((uint16)RdScalarReg(rP0DE)<<8) + RdScalarReg(rP0DD);
}
temp = ((float)htotal * 536870912L) / PixelRate;
PixelRate = temp;
for(i; i>0; i--) {
PixelRate <<= 1;
}
WrScalarReg(rP0D2, (uint8)PixelRate);
WrScalarReg(rP0D3, (uint8)(PixelRate>>8));
WrScalarReg(rP0D4, (uint8)(PixelRate>>16));
WrScalarWord(rP0D7, htotal);
//WrScalarReg(rP0D5, 0x03 + k);
if (Flg_Interlace) WrScalarReg(rP0D5, 0x0B);
else WrScalarReg(rP0D5, 0x03);
}
#endif
/*
********************************************************************************
* 函 数 名: AdcSetClamp
* 功能描述: 输出ADC的钳位值
* 输 入: Chanel : 选择颜色通道
* val : 输出到ADC的钳位值
* 返 回: 无
********************************************************************************
*/
void AdcSetClamp(uint8 Chanel, uint8 val)
{
WrScalarReg((uint16)rP003 + Chanel + (Chanel<<1), val);
}
/*
********************************************************************************
* 函 数 名: AdcSetGain
* 功能描述: 输出ADC的增益值
* 输 入: Chanel : 选择颜色通道, 值的范围是: 0, 1, 2
* val : 输出到ADC的增益值, 设置的是高7位的值, 最低一位在00EHs
* 返 回: 无
********************************************************************************
*/
void AdcSetGain(uint8 Chanel, uint8 val)
{
WrScalarReg((uint16)rP001 + Chanel + (Chanel<<1), val);
}
/*
********************************************************************************
* 函 数 名: AdcUpdatePara
* 功能描述: 输出ADC所有的增益和钳位电压值
* 输 入: ADC参数结构指针,Adc
* 返 回: 无
********************************************************************************
*/
void AdcUpdatePara(ADCPAR * Adc)
{
AdcSetGain(COLOR_R, Adc->gainR);
AdcSetGain(COLOR_G, Adc->gainG);
AdcSetGain(COLOR_B, Adc->gainB);
AdcSetClamp(COLOR_R, Adc->clampR);
AdcSetClamp(COLOR_G, Adc->clampG);
AdcSetClamp(COLOR_B, Adc->clampB);
}
/*
********************************************************************************
* 函 数 名: AdcSetDigGain
* 功能描述: 输出数字式的增益值
* 输 入: color : 选择颜色通道
* val : 数字式的增益值
* 返 回: 无
********************************************************************************
*/
void AdcSetDigGain(uint8 color, uint8 val)
{
WrScalarRegBit(rP061, color + 1, 0x03);
WrScalarReg(rP063, val);
}
/*
********************************************************************************
* 函 数 名: AdcDigitalContrast
* 功能描述: 设置数字式增益
* 输 入: Con : 增益的值
* 返 回: 无
********************************************************************************
*/
void AdcDigitalContrast(uint8 Con)
{
AdcSetDigGain(COLOR_R, Con);
AdcSetDigGain(COLOR_G, Con);
AdcSetDigGain(COLOR_B, Con);
}
/*
********************************************************************************
* 下面是关于sRGB的处理
* 1. 以下的数据表是如何来的,还不是很清楚
********************************************************************************
*/
#if 0
int16 code rgb2yuv[3][3]={
{ 0x041B, 0x0810, 0x0191 },
{ -0x025F, -0x04A7, 0x0707 },
{ 0x0707, -0x05E2, -0x0124 }
};
int16 code yuv2rgb[3][3]={
{ 0x12A1, 0x0000, 0x1989 },
{ 0x12A1, -0x0644, -0x0D01 },
{ 0x12A1, 0x2046, 0x0000 }
};
int16 code sincos_tbl[65]={
0x0000,0x0064,0x00C9,0x012D,0x0191,0x01F5,0x0259,0x02BC,0x031F,0x0381,
0x03E3,0x0444,0x04A5,0x0505,0x0564,0x05C2,0x061F,0x067B,0x06D7,0x0731,
0x078A,0x07E3,0x083A,0x088F,0x08E3,0x0937,0x0988,0x09D8,0x0A26,0x0A73,
0x0ABF,0x0B08,0x0B50,0x0B97,0x0BDB,0x0C1E,0x0C5E,0x0C9D,0x0CDA,0x0D15,
0x0D4D,0x0D85,0x0DB9,0x0DEC,0x0E1C,0x0E4B,0x0E77,0x0EA1,0x0EC8,0x0EEE,
0x0F10,0x0F31,0x0F4F,0x0F6C,0x0F85,0x0F9C,0x0FB1,0x0FC4,0x0FD4,0x0FE1,
0x0FEC,0x0FF5,0x0FFB,0x0FFE,0x1000
};
/*
********************************************************************************
* 函 数 名: sine
* 功能描述: 通过查表的方式完成sine的计算,这样可以加快处理的速度
* 输 入: alpha : sine的输入值,范围是0-64
* 返 回: 计算的结果
********************************************************************************
*/
static int16 sine(uint8 alpha)
{
uint8 value = alpha & 0x3F;
switch(alpha & 0xC0){
case 0x00:
return(sincos_tbl[value]);
break;
case 0x40:
return(sincos_tbl[(64 - value)]);
break;
case 0x80:
return(-sincos_tbl[value]);
break;
case 0xC0:
return(-sincos_tbl[(64 - value)]);
break;
}
}
/*
********************************************************************************
* 函 数 名: cosine
* 功能描述: 通过查表的方式完成cosine的计算,这样可以加快处理的速度
* 输 入: alpha : cosine的输入值,范围是0-64
* 返 回: 计算的结果
********************************************************************************
*/
static int16 cosine(uint8 alpha)
{
return (sine(alpha + 64));
}
/*
********************************************************************************
* 函 数 名: product
* 功能描述:
* 输 入: first :
* second :
* result :
* 返 回: 无
********************************************************************************
*/
static void product(int16 *first, int16 * second, int16 *result)
{
uint8 i,j,k;
int32 res;
for(i = 0; i < 3; i++) {
for(j = 0; j < 3; j++) {
res = 0;
for(k = 0; k < 3; k++) {
res += (int32)*(first + i * 3 + k) * (int32)*(second + k * 3 + j);
}
//*(result + i * 3 + j) = ((res + 2048)>>12); // 2006年06月06日,将其屏蔽
*(result + i * 3 + j) = ((res)>>12);
}
}
}
#endif
uint16 code defautlTab[3][3]={
{ 0x1000, 0x0000, 0x0000 },
{ 0x0000, 0x1000, 0x0000 },
{ 0x0000, 0x0000, 0x1000 },
};
#define Saturation 50
#define Tint 50
/*
********************************************************************************
* 函 数 名: sRGB
* 功能描述:
* 输 入: Contrast :
* RedGain :
* GreenGain :
* BlueGain :
* 返 回: 无
*
********************************************************************************
*/
#if 0 // 以前使用的方法
void sRGB(uint8 Contrast, uint8 RedGain, uint8 GreenGain, uint8 BlueGain)
{
uint8 i,j;
uint16 xdata temp,gain[3];
uint16 xdata result[3][3];
gain[0] = ((uint16)RedGain * 255)/100;
gain[1] = ((uint16)GreenGain * 255)/100;
gain[2] = ((uint16)BlueGain * 255)/100;
//gain[0] = RedGain;
//gain[1] = GreenGain;
//gain[2] = BlueGain;
//Contrast = ((uint16)Contrast * 127)/100;
Contrast = Contrast + 40;
for(i=0; i<3; i++) {
for(j=0; j<3; j++) {
result[i][j] = defautlTab[i][j];
}
}
result[0][0] = (int)((float)result[0][0] * Contrast / 128 + 0.5);
result[1][1] = (int)((float)result[1][1] * Contrast / 128 + 0.5);
result[2][2] = (int)((float)result[2][2] * Contrast / 128 + 0.5);
for(i=0; i<3; i++){
WrScalarReg(rP1D0, ((i << 1) + 0x21));
for(j=0; j<3; j++){
temp = (((((long)(result[i][j]+8)>>4)*((long)gain[i]<<4))+2048)>>12);
if(temp < 0){
temp = temp ^ 0xFFFF;
temp +=1 ;
temp |= 0xF400;
}
WrScalarWord((rP1D1 + (j<<1)),temp);
}
}
WrScalarReg(rP1D0, 0x3D);
}
#endif
// 2006年09月27日,根据原厂的参考程序重新建立
//#if 0
void sRGB(uint8 Contrast, uint8 RedGain, uint8 GreenGain, uint8 BlueGain)
{
uint8 i,j;
uint16 xdata ss,hh;
int16 xdata temp,gain[3];
int16 xdata UserPrefContrast;
uint8 code arry[3][3]={
{1,0,0},
{0,1,0},
{0,0,1}
};
//gain[0] = (uint16)(RedGain + 0x80);//((Word)RedGain << 1) + 56;
//gain[1] = (uint16)(GreenGain + 0x80);//((Word)GreenGain<< 1) + 56;
//gain[2] = (uint16)(BlueGain + 0x80);//((Word)BlueGain<< 1) + 56;
gain[0] = RedGain;
gain[1] = GreenGain;
gain[2] = BlueGain;
ss = ((uint16)Saturation * 256 + 50) / 100;
hh = (((uint16)Tint * 256 + 50) / 100) - 128;
if (Contrast > 50)
UserPrefContrast = (uint16)(Contrast-50) * 45 /50 + 210;
else
UserPrefContrast = (uint16)Contrast * 160 /50 + 50;
//UserPrefContrast = (uint16)Contrast * 180 /100 + 29; // + 25
for(i = 0; i < 3; i++){
WrScalarReg(rP1D0, ((i << 1) + 0x21));
for(j = 0; j < 3; j++){
temp = ((((long)(UserPrefContrast)*((long)gain[i]<<5))+2048)>>12)*(long)arry[i][j];
if(temp < 0){
temp = temp ^ 0xFFFF;
temp +=1 ;
temp |= 0xF400;
}
WrScalarWord((rP1D1 + (j<<1)),temp);
}
}
WrScalarReg(rP1D0,0x3D);//0x2d);
}
//#endif
/*
********************************************************************************
* 文 件 结 束 *
********************************************************************************
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -