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

📄 ad6620.c

📁 这是单板上DPRAM的驱动程序
💻 C
字号:
#include <psos.h>
#include "board.h"
#include "sdev.h"
#include "AD6620.h"

/* AD6620 Base Address */
const char *AD6620_BASE=(char*)0x40000000;
int INI_STATUS;
void AD6620WriteReg( unsigned short Address, ULONG Data );
ULONG AD6620ReadReg( unsigned short Address);
void AD6620HardReset(void);

/* rd */
int AD6620Read ( void *pDataBuf, void *pBuf, int MaxLen )
{
    char d[5] = {0};
    AD6620MemValue* pMemBuf = (AD6620MemValue*)pBuf;

    if(MaxLen!=sizeof(AD6620MemValue))
        return SDE_INVALID_ARG;
   
    *(unsigned char *)(AD6620_BASE+AD6620_LAR) = (unsigned char)(pMemBuf->MemAdd);
    *(unsigned char *)(AD6620_BASE+AD6620_AMR) = ((unsigned char)(pMemBuf->MemAdd>>8))&0x03;
    
    d[0] = (*(char *)(AD6620_BASE+AD6620_DATA0))&0x0FF;
    if(pMemBuf->MemAdd>=0x300)
    {
        if(pMemBuf->MemAdd==0x302||pMemBuf->MemAdd==0x303)    
        {        
            d[1] = (*(char *)(0x40000000+AD6620_DATA1))&0x0FF;
            d[2] = (*(char *)(0x40000000+AD6620_DATA2))&0x0FF;
            d[3] = (*(char *)(0x40000000+AD6620_DATA3))&0x0FF;
            pMemBuf->MemDat[0] = (ULONG)(d[0]|(d[1]<<8)|(d[2]<<16)|(d[3]<<24))&0xFFFFFFFF;       /* 32 Data */
        }
        else 
        if(pMemBuf->MemAdd==0x304)
        {
            d[1] = (*(char *)(0x40000000+AD6620_DATA1))&0x0FF;
            pMemBuf->MemDat[0] = (ULONG)(d[0]|(d[1]<<8))&0xFFFF;       /* 16 Data */
        }
        else
            pMemBuf->MemDat[0] = (ULONG)(d[0])&0xFF;       /* 8 Data */
        pMemBuf->MemDat[1] = 0;
    }
    else
    {
        d[1] = (*(char *)(AD6620_BASE+AD6620_DATA1))&0x0FF;
        d[2] = (*(char *)(AD6620_BASE+AD6620_DATA2))&0x0FF;
        d[3] = (*(char *)(AD6620_BASE+AD6620_DATA3))&0x0FF;
    
        if((pMemBuf->MemAdd>=AD6620_IQ_RAM)&&(pMemBuf->MemAdd<=(AD6620_IQ_RAM+255)))
        {
            d[4] = (*(char *)(AD6620_BASE+AD6620_DATA4))&0x0FF;
            pMemBuf->MemDat[0] = (ULONG)(d[0]|(d[1]<<8)|(d[2]<<16))&0x3FFFF;       /* I Data */
            pMemBuf->MemDat[1] = (ULONG)((d[2]>>2)|(d[3]<<6)|(d[4]<<14))&0x3FFFF;  /* Q Data */
        }
        else
        {
            pMemBuf->MemDat[0] = (ULONG)(d[0]|(d[1]<<8)|(d[2]<<16)|(d[3]<<24));    /* Mem & Reg Data */
            pMemBuf->MemDat[1] = 0;
        }
    }        
    return SDE_OK;
}

/* Internal Function */
void AD6620WriteReg( unsigned short Address, ULONG Data )
{
    unsigned char d[5] = {0};

    *(unsigned char *)(AD6620_BASE+AD6620_LAR) = (unsigned char)Address;
    *(unsigned char *)(AD6620_BASE+AD6620_AMR) = ((unsigned char)(Address>>8))&0x03;
    
    if(Address==0x302||Address==0x303)    
    {
        d[3] = (unsigned char)((Data&0xFF000000)>>24);
        *(unsigned char *)(AD6620_BASE+AD6620_DATA3) = d[3];
        d[2] = (unsigned char)((Data&0x00FF0000)>>16);
        *(unsigned char *)(AD6620_BASE+AD6620_DATA2) = d[2];
        d[1] = (unsigned char)((Data&0x0000FF00)>>8);   
        *(unsigned char *)(AD6620_BASE+AD6620_DATA1) = d[1];
    }
    else 
    if(Address==0x304)
    {
        d[1] = (unsigned char)((Data&0x0000FF00)>>8);   
        *(unsigned char *)(AD6620_BASE+AD6620_DATA1) = d[1];
    }
    d[0] = (unsigned char)(Data&0x000000FF);
    *(unsigned char *)(AD6620_BASE+AD6620_DATA0) = d[0];
}

/* Internal Function */
ULONG AD6620ReadReg( unsigned short Address)
{
    unsigned char d[5] = {0};

    *(unsigned char *)(AD6620_BASE+AD6620_LAR) = (unsigned char)Address;
    *(unsigned char *)(AD6620_BASE+AD6620_AMR) = ((unsigned char)(Address>>8))&0x03;
    
    d[0] = *(unsigned char *)(AD6620_BASE+AD6620_DATA0);
    if(Address==0x302||Address==0x303)    
    {
        d[1] = *(unsigned char *)(AD6620_BASE+AD6620_DATA1);
        d[2] = *(unsigned char *)(AD6620_BASE+AD6620_DATA2);
        d[3] = *(unsigned char *)(AD6620_BASE+AD6620_DATA3);
    }
    else 
    if(Address==0x304)
    {
        d[1] = *(unsigned char *)(AD6620_BASE+AD6620_DATA1);
    }
    return (ULONG)(d[0]|(d[1]<<8)|(d[2]<<16)|(d[3]<<24));
}

void AD6620HardReset()
{
    int i;
    volatile float temp;
    SET_PC_BIT(4,0);/* Hard Reset */
    for(i=0;i<2;i++)
        temp = temp*1.19;
    SET_PC_BIT(4,1);/* Hard Reset Over */
}

void AD6620Init(void *pDataBuf, AD6620CfgStruct *cfg )
{
    unsigned char d[5] = {0};
    ULONG temp_value;
    ULONG i;
    
    AD6620CfgStruct* pCfg = (AD6620CfgStruct *)(pDataBuf);
/*-------------------------<< Initial data >>-------------------------------*/
    memmove(pCfg,cfg,sizeof(AD6620CfgStruct));
    
    AD6620HardReset();      
    AD6620WriteReg(AD6620_MODE_REG,(ULONG)0x01);  /* Soft_Reset */
    
    /* Init Coefficient RAM ,Address Increment Auto */
    *(unsigned char *)(AD6620_BASE+AD6620_LAR) = (unsigned char)(AD6620_CO_RAM);
    *(unsigned char *)(AD6620_BASE+AD6620_AMR) = ((unsigned char)(AD6620_CO_RAM>>8)&0x03)|0x80;  
    for(i=0;i<256;i++)
    {
        d[3] = (unsigned char)((pCfg->Coefficient[i]&0xFF000000)>>24);
        *(unsigned char *)(AD6620_BASE+AD6620_DATA3) = d[3];
        d[2] = (unsigned char)((pCfg->Coefficient[i]&0x00FF0000)>>16);
        *(unsigned char *)(AD6620_BASE+AD6620_DATA2) = d[2];
        d[1] = (unsigned char)((pCfg->Coefficient[i]&0x0000FF00)>>8);
        *(unsigned char *)(AD6620_BASE+AD6620_DATA1) = d[1];
        d[0] = (unsigned char)((pCfg->Coefficient[i]&0x000000FF));
        *(unsigned char *)(AD6620_BASE+AD6620_DATA0) = d[0];
    } 
    /* Init I Q data Parameter RAM ,Address Increment Auto */

    *(unsigned char *)(AD6620_BASE+AD6620_LAR) = (unsigned char)(AD6620_IQ_RAM);
    *(unsigned char *)(AD6620_BASE+AD6620_AMR) = ((unsigned char)(AD6620_IQ_RAM>>8)&0x03)|0x80;  
    for(i=0;i<256;i++)
    {
        *(unsigned char *)(AD6620_BASE+AD6620_DATA4) = 0;
        *(unsigned char *)(AD6620_BASE+AD6620_DATA3) = 0;
        *(unsigned char *)(AD6620_BASE+AD6620_DATA2) = 0;
        *(unsigned char *)(AD6620_BASE+AD6620_DATA1) = 0;
        *(unsigned char *)(AD6620_BASE+AD6620_DATA0) = 0;
    }         
    /* Mode Register */
    temp_value = (pCfg->RegValue.Chip_Mode<<1)|0x09; 
    AD6620WriteReg(AD6620_MODE_REG,(ULONG)(temp_value&0x0F));
    
    /* NCO Control Register */
    temp_value = (pCfg->RegValue.Nco_Bypass)|(pCfg->RegValue.Pha_Dither<<1)|(pCfg->RegValue.Amp_Dither<<2);
    AD6620WriteReg(AD6620_NCO_CON_REG,(ULONG)(temp_value&0x07));    
    
    /* NCO SYNC Control Register */
    temp_value = 0x0FFFFFFFF;
    AD6620WriteReg(AD6620_NCO_SYN_REG,(ULONG)temp_value);
    
    /* NCO Freq */
    AD6620WriteReg(AD6620_NCO_FREQ,(ULONG)(pCfg->RegValue.Nco_Freq&0x0FFFFFFFF));
    
    /* NCO Phase Offset */
    AD6620WriteReg(AD6620_NCO_PH_OFF,(ULONG)(pCfg->RegValue.Nco_Phoff&0x0FFFF));
    
    /* CIC2 Input Scale Factor */
    temp_value = pCfg->RegValue.Scic2_Sca|0x0D0;
    AD6620WriteReg(AD6620_SCIC2,(ULONG)(temp_value&0x0FF));    
    
    /* CIC2 Decimation Value */
    AD6620WriteReg(AD6620_MCIC2,(ULONG)(pCfg->RegValue.Mcic2_Dec&0x0FF));    
    
    /* CIC5 Scale Factor */
    AD6620WriteReg(AD6620_SCIC5,(ULONG)(pCfg->RegValue.Scic5_Sca&0x1F));    
    
    /* CIC5 Decimation Value */
    AD6620WriteReg(AD6620_MCIC5,(ULONG)(pCfg->RegValue.Mcic5_Dec&0x0FF));
    
    /* RCF Control Register:Output Scale Factor */
    AD6620WriteReg(AD6620_RCF_CON_REG,(ULONG)(pCfg->RegValue.Out_Sca&0x07));    
    
    /* RCF Decimation Value */
    AD6620WriteReg(AD6620_MRCF,(ULONG)(pCfg->RegValue.Rcf_Dec&0x0FF));    
    
    /* RCF Address Offset Register */
    AD6620WriteReg(AD6620_RCF_ADD_REG,(ULONG)(pCfg->RegValue.Rcf_AddOff&0x0FF));    
    
    /* Clear the Last Register to Zero */
    AD6620WriteReg(AD6620_INRESERVED,(ULONG)0x0);
    
    /* Number of Taps Minus One */
    AD6620WriteReg(AD6620_NTAPS,(ULONG)(pCfg->RegValue.Taps&0x0FF));    

    
    /*check the AD6620 configuration parametre */
   
   INI_STATUS = TRUE;
   /* check Coefficient RAM ,Address Increment Auto */
    *(unsigned char *)(AD6620_BASE+AD6620_LAR) = (unsigned char)(AD6620_CO_RAM);
    *(unsigned char *)(AD6620_BASE+AD6620_AMR) = ((unsigned char)(AD6620_CO_RAM>>8)&0x03)|0x40;  
    for(i=0;i<256;i++)
    {
        d[0] = *(unsigned char *)(AD6620_BASE+AD6620_DATA0);
        d[1] = *(unsigned char *)(AD6620_BASE+AD6620_DATA1);
        d[2] = *(unsigned char *)(AD6620_BASE+AD6620_DATA2);
        d[3] = *(unsigned char *)(AD6620_BASE+AD6620_DATA3);
        if((ULONG)(pCfg->Coefficient[i])!= (ULONG)(d[0]|(d[1]<<8)|(d[2]<<16)|(d[3]<<24))) i=257;
    } 
    if(i!=256) INI_STATUS = FALSE; 
    	
     /* check I Q data Parameter RAM ,Address Increment Auto */

    *(unsigned char *)(AD6620_BASE+AD6620_LAR) = (unsigned char)(AD6620_IQ_RAM);
    *(unsigned char *)(AD6620_BASE+AD6620_AMR) = ((unsigned char)(AD6620_IQ_RAM>>8)&0x03)|0x40;  
    for(i=0;i<256;i++)
    {
        d[0] = *(unsigned char *)(AD6620_BASE+AD6620_DATA0);
        d[1] = *(unsigned char *)(AD6620_BASE+AD6620_DATA1);
        d[2] = *(unsigned char *)(AD6620_BASE+AD6620_DATA2);
        d[3] = *(unsigned char *)(AD6620_BASE+AD6620_DATA3);
        if((ULONG)(d[0]|(d[1]<<8)|(d[2]<<16)|(d[3]<<24)) != 0) i=257;
    }         
    
    if(i!=256) INI_STATUS = FALSE;    	
	

    
    /* NCO Control Register */
    temp_value = (pCfg->RegValue.Nco_Bypass)|(pCfg->RegValue.Pha_Dither<<1)|(pCfg->RegValue.Amp_Dither<<2);
    if(AD6620ReadReg(AD6620_NCO_CON_REG) != (ULONG)(temp_value&0x07)) INI_STATUS = AD6620ReadReg(AD6620_NCO_CON_REG);    
    
    /* NCO SYNC Control Register */
    temp_value = 0x0FFFFFFFF;
    if(AD6620ReadReg(AD6620_NCO_SYN_REG) != (ULONG)temp_value) INI_STATUS = FALSE;
    

    /* NCO Freq */
    temp_value = pCfg->RegValue.Nco_Freq;
    if(AD6620ReadReg(AD6620_NCO_FREQ) != (ULONG)(temp_value&0x0FFFFFFFF)) INI_STATUS = FALSE;
    
    /* NCO Phase Offset */
    temp_value = pCfg->RegValue.Nco_Phoff;
    if(AD6620ReadReg(AD6620_NCO_PH_OFF) != (ULONG)(temp_value&0x0FFFF)) INI_STATUS = FALSE;
    
    /* CIC2 Input Scale Factor */
    temp_value = pCfg->RegValue.Scic2_Sca|0x0D0;
    if(AD6620ReadReg(AD6620_SCIC2) != (ULONG)(temp_value&0x0FF)) INI_STATUS = FALSE;    
    
    /* CIC2 Decimation Value */
    temp_value = pCfg->RegValue.Mcic2_Dec;
    if(AD6620ReadReg(AD6620_MCIC2)!= (ULONG)(temp_value&0x0FF)) INI_STATUS = FALSE;    
    
    /* CIC5 Scale Factor */
    temp_value = pCfg->RegValue.Scic5_Sca;
    if(AD6620ReadReg(AD6620_SCIC5) != (ULONG)(temp_value&0x1F)) INI_STATUS = FALSE;    
    
    /* CIC5 Decimation Value */
    temp_value = pCfg->RegValue.Mcic5_Dec;
    if(AD6620ReadReg(AD6620_MCIC5) != (ULONG)(temp_value&0x0FF)) INI_STATUS = FALSE;
    
    /* RCF Control Register:Output Scale Factor */
    temp_value = pCfg->RegValue.Out_Sca;
    if(AD6620ReadReg(AD6620_RCF_CON_REG) != (ULONG)(temp_value&0x07)) INI_STATUS = FALSE;    
    
    /* RCF Decimation Value */
    temp_value = pCfg->RegValue.Rcf_Dec;    
    if(AD6620ReadReg(AD6620_MRCF) != (ULONG)(temp_value&0x0FF)) INI_STATUS = FALSE;    
    
    /* RCF Address Offset Register */
    temp_value = pCfg->RegValue.Rcf_AddOff;        
    if(AD6620ReadReg(AD6620_RCF_ADD_REG) != (ULONG)(temp_value&0x0FF)) INI_STATUS = FALSE;    
    
    /* Clear the Last Register to Zero */    
    if(AD6620ReadReg(AD6620_INRESERVED) != (ULONG)0x0) INI_STATUS = FALSE;        
        
    /* Number of Taps Minus One */
    temp_value = pCfg->RegValue.Taps;
    if(AD6620ReadReg(AD6620_NTAPS) != (ULONG)(temp_value&0x0FF)) INI_STATUS = FALSE;    
 
     /* Remove System from Soft_Reset to Normal */
    AD6620WriteReg(AD6620_MODE_REG,(ULONG)(pCfg->RegValue.Chip_Mode<<1|0x08));    
}

int AD6620Cntrl(void *pDataBuf, int cmd, void *pParam, int maxlen)
{
    ULONG temp_value;
    AD6620CfgStruct *pCfg = (AD6620CfgStruct *)(pDataBuf);
    switch(cmd)
    {
    	case SDC_INIT_STATUS:
    		if(INI_STATUS == TRUE) return SDE_OK;
    			else return SDE_GENERAL_FAIL;
    		break;
    		
        case SDC_REINIT:
            if(maxlen!=0)  return SDE_INVALID_ARG;            
            AD6620Init(pDataBuf,pCfg);
            break;
            
        case SDC_GET_REG:
            if(maxlen!=sizeof(AD6620RegValue))  return SDE_INVALID_ARG;
            *(AD6620RegValue*)(pParam) = (pCfg->RegValue);
            break;
            
        case SDC_SET_NCO_FREQ:
            if(maxlen!=sizeof(ULONG))  return SDE_INVALID_ARG;     
            AD6620WriteReg(AD6620_NCO_FREQ,*(ULONG*)pParam);
            pCfg->RegValue.Nco_Freq = *(ULONG*)pParam;
            break;
            
        case SDC_SET_NCO_PHOFF:
            if(maxlen!=sizeof(ULONG))  return SDE_INVALID_ARG;     
            AD6620WriteReg(AD6620_NCO_PH_OFF,(*(ULONG*)pParam)&0x0FFFF);
            pCfg->RegValue.Nco_Phoff = *(unsigned short*)pParam;
            break;
            
        case SDC_SET_CIC2_SCA:
            if(maxlen!=sizeof(ULONG))  return SDE_INVALID_ARG;     
            AD6620WriteReg(AD6620_SCIC2,(*(ULONG*)pParam)|0x0B0);            
            pCfg->RegValue.Scic2_Sca = *(unsigned char*)pParam;
            break;
            
        case SDC_SET_CIC5_SCA:
            if(maxlen!=sizeof(ULONG))  return SDE_INVALID_ARG;     
            AD6620WriteReg(AD6620_SCIC5,(*(ULONG*)pParam)&0x1F);
            pCfg->RegValue.Scic5_Sca = *(unsigned char*)pParam;            
            break;
            
        case SDC_SET_OUT_SCA:
            if(maxlen!=sizeof(ULONG))  return SDE_INVALID_ARG;     
            AD6620WriteReg(AD6620_RCF_CON_REG,(*(ULONG*)pParam)&0x07);
            pCfg->RegValue.Out_Sca = *(unsigned char*)pParam;
            break;
            
        case SDC_SET_RCF_ADDOFF:
            if(maxlen!=sizeof(ULONG))  return SDE_INVALID_ARG;     
            AD6620WriteReg(AD6620_RCF_ADD_REG,(*(ULONG*)pParam)&0x0FF);
            pCfg->RegValue.Rcf_AddOff =*(unsigned char*)pParam;            
            break;
            
        default: 
            return SDE_UNKNOW_CMD;

    }/* end of switch(cmd) */
    return SDE_OK;
}

char *AD6620BspInit(int DEV, char *FreeMemPtr, AD6620CfgStruct *cfg)
{
    InstallSD(DEV,AD6620Read,NULL,AD6620Cntrl,FreeMemPtr);
    AD6620Init(FreeMemPtr, cfg); 
    FreeMemPtr += sizeof(AD6620CfgStruct);
    memcpy(FreeMemPtr,"*AD6620*",8);
    FreeMemPtr += 8;
    return FreeMemPtr;
}

⌨️ 快捷键说明

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