📄 codec.c
字号:
/*======================================================================
Project Name : S3C2450
Copyright 2006 by Samsung Electronics, Inc.
All rights reserved.
Project Description :
This software is only for verifying functions of the S3C2443.
Anybody can use this code without our permission.
File Name : iis_codec.c
Description : S3C2450 IIS codec code
Author : Dongjin Kim
Dept : AP
Created Date : 2007.10.19
Version : 0.0
History
R0.0 (2007.10.19): draft
- S3C2450 IIS codec code is derived from SA 2450 IIS test code
=======================================================================*/
#include "System.h"
#include "iis.h"
//defines
//global variable
unsigned int save_AC97_rGPECON, save_AC97_rGPEDAT, save_AC97_rGPEUDP;
unsigned int save_GPG_CON, save_GPG_DAT;
//externs
extern void IIC_close( void);
extern void IIC_Write( unsigned char SlaveAddr, char *Data, unsigned int n);
extern void IIC_Read( unsigned char SlaveAddr, char *Data, unsigned int n);
///////////////////////////////////////////////////////////////////////////
// GPIO port open/close/return status
//////////////////////////////////////////////////////////////////////////
void AC97_Port_Init(void)
{
//Push AC97 GPIO port configuration
save_AC97_rGPEDAT=rGPEDAT;
save_AC97_rGPECON=rGPECON;
save_AC97_rGPEUDP=rGPEUDP;
//---------------------------------------------------------------------
//PORT E GROUP
//Ports : GPE4 GPE3 GPE2 GPE1 GPE0
//Signal : AC97 SDO AC97 SDI AC97 BITCLK AC97 SYNC AC97 RESETn
//Binary : 11, 11, 11, 11, 11
//---------------------------------------------------------------------
rGPESEL = 0;//GPE
rGPECON |= 0x3ff; // GPE[4:0]=> AC97 function muxed IIS
rGPEUDP |= 0x1f; // The pull up function is disabled GPE[4:0]
}
void L3_Port_Init(void)
{
save_GPG_CON = rGPGCON; // L3
//----------------------------------------------------------
//PORT G GROUP
//Ports : GPG0 GPG1 GPG2
//Signal : L3MODE L3DATA L3CLK
//Setting: OUTPUT OUTPUT OUTPUT
// [1:0] [3:2] [5:4]
//Binary : 01 01 01
//----------------------------------------------------------
rGPGCON = rGPGCON & ~(0x3f) | (1<<4)|(1<<2)|(1); // output setting
}
void IIC0_Port_Init(void)
{
//IIC0
//-------------------------------------------------------------------------------
//PORT E GROUP
//Ports : GPE15 GPE14
//Signal : IICSDA IICSCL
//Binary : 10, 10
//-------------------------------------------------------------------------------
rGPECON = rGPECON & ~((U32)(0xf<<28)) | ((U32)(0xa<<28)); // IIC setting
rGPEUDP = rGPEUDP & ~((U32)(0xf<<28)) | ((U32)(0xa<<28));//pull down.
}
void AC97_Port_Return(void)
{
//Pop AC97 GPIO port configuration
rGPECON = rGPECON & ~(0x3ff) | (save_AC97_rGPECON & ~(0x3ff) );
rGPEDAT=save_AC97_rGPEDAT;
rGPEUDP=save_AC97_rGPEUDP;
}
void L3_Port_Return(void)
{
rGPGCON=save_GPG_CON;
rGPGDAT=save_GPG_DAT;
}
void IIC0_Port_Return(void)
{
//to be filled
}
//return gpe0~4 status
//3 : ac97
unsigned char AC97_PORT_status()
{
if(rGPESEL == 0)
{
if( (rGPECON & 0x3ff) == 0x3ff ) return 3;//ac97
else if( (rGPECON & 0x3ff) == 0x2aa ) return 2;//i2s0
else if( (rGPECON & 0x3ff) == 0x155 ) return 1;//out
else if( (rGPECON & 0x3ff) == 0x000 ) return 0;//in
else return 5;//n/a
}
else
return 4;//pcm0
}
//return gpg0~2 status
unsigned char L3_PORT_status()
{
//tbd-according to 2443, in 2450 l3 interface is not adopted.
}
//return gpe14~15 status
unsigned char IIC0_PORT_status()
{
if( (rGPECON & (0xf<<28) ) == (0xa<<28) ) return 2;//i2c0
else if( (rGPECON & (0xf<<28) ) == (0x5<<28) ) return 1;//out
else if( (rGPECON & (0xf<<28) ) == (0x0<<28) ) return 0;//in
else return 5;//n/a
}
//////////////////////////////////////////////////////////////////////////
// Interface
///////////////////////////////////////////////////////////////////////////
//void _WrL3Addr(unsigned char data)
//void _WrL3Data(unsigned char data,int halt)
//void Init1341(int mode)
// L3 interface library
void _WrL3Addr(unsigned char data)
{
int i,j;
rGPGDAT = rGPGDAT & ~(L3D | L3M | L3C) | L3C; //L3D=L, L3M=L(in address mode), L3C=H
for(j=0;j<4;j++); //tsu(L3) > 190ns
for(i=0;i<8;i++) //LSB first
{
if(data & 0x1) //If data's LSB is 'H'
{
rGPGDAT &= ~L3C; //L3C=L
rGPGDAT |= L3D; //L3D=H
for(j=0;j<4;j++); //tcy(L3) > 500ns
rGPGDAT |= L3C; //L3C=H
rGPGDAT |= L3D; //L3D=H
for(j=0;j<4;j++); //tcy(L3) > 500ns
}
else //If data's LSB is 'L'
{
rGPGDAT &= ~L3C; //L3C=L
rGPGDAT &= ~L3D; //L3D=L
for(j=0;j<4;j++); //tcy(L3) > 500ns
rGPGDAT |= L3C; //L3C=H
rGPGDAT &= ~L3D; //L3D=L
for(j=0;j<4;j++); //tcy(L3) > 500ns
}
data >>= 1;
}
rGPGDAT = rGPGDAT & ~(L3D | L3M | L3C) | (L3C | L3M); //L3M=H,L3C=H
}
void _WrL3Data(unsigned char data,int halt)
{
int i,j;
if(halt)
{
rGPGDAT = rGPGDAT & ~(L3D | L3M | L3C) | L3C; //L3C=H(while tstp, L3 interface halt condition)
for(j=0;j<4;j++); //tstp(L3) > 190ns
}
rGPGDAT = rGPGDAT & ~(L3D | L3M | L3C) | (L3C | L3M); //L3M=H(in data transfer mode)
for(j=0;j<4;j++); //tsu(L3)D > 190ns
for(i=0;i<8;i++)
{
if(data & 0x1) //if data's LSB is 'H'
{
rGPGDAT &= ~L3C; //L3C=L
rGPGDAT |= L3D; //L3D=H
for(j=0;j<4;j++); //tcy(L3) > 500ns
rGPGDAT |= (L3C | L3D); //L3C=H,L3D=H
for(j=0;j<4;j++); //tcy(L3) > 500ns
}
else //If data's LSB is 'L'
{
rGPGDAT &= ~L3C; //L3C=L
rGPGDAT &= ~L3D; //L3D=L
for(j=0;j<4;j++); //tcy(L3) > 500ns
rGPGDAT |= L3C; //L3C=H
rGPGDAT &= ~L3D; //L3D=L
for(j=0;j<4;j++); //tcy(L3) > 500ns
}
data >>= 1; //For check next bit
}
rGPGDAT = rGPGDAT & ~(L3D | L3M | L3C) | (L3C | L3M); //L3M=H,L3C=H
}
// I2C Interface
// slave addr+
void I2SCODEC_WrSerial( unsigned char slave_addr,
char reg_addr,
char data)
{
char D[2];
D[0]=reg_addr;
D[1]=data;
IIC_Write( slave_addr, D, 2);
IIC_Wait();
}
//2wire continous mode
//1. write device id(0x34(write), codec hw CSB pic is low),
// register address : readback(52)
// data : READMUX bit according to register address to read,
// read back configuration
// *
//
//2. write device id(0x35(read), data(according to READMUX bit)
//3. repeat 2. and get the data(first read data would be wrong)
void I2SCODEC_RdSerial( unsigned char slave_addr,
char reg_addr,
char *pdata)
{
// IIC_Write( slave_addr, ®_addr, 1);
//prior to read, read back register must be set.
IIC_Read( slave_addr, pdata, 1);
IIC_Wait();
// IIC_Read( slave_addr, pdata, 1);
// IIC_Wait();
}
//codec command read/write
//if port is not set as ac97, then set.
unsigned short AC97_Codec_Cmd(unsigned char CMD_Read, unsigned char CMD_Offset, unsigned short CMD_Data)
{
unsigned short Codec_Stat;
if( AC97_PORT_status() != INTERFACE_PORTNUM_AC97 )
{
printf("ac97 port is not selected. setting...\n");
AC97_Port_Init();
//delay to be activated.
}
//write
if(CMD_Read == 0)
{
rAC_CODEC_CMD = (0<<23)|(CMD_Offset<<16)|(CMD_Data<<0);
//delay_func(2); //32 us delay
Delay(1);
return 1;
}
else if (CMD_Read ==1) //read
{
rAC_CODEC_CMD = (1<<23)|(CMD_Offset<<16)|(CMD_Data<<0);
Delay(1000);
Codec_Stat = (unsigned short)(rAC_CODEC_STAT & 0xFFFF);
Delay(1000);
return Codec_Stat;
}
else
return 0;
}
//////////////////////////////////////////////////////////
// Audio Codec
//////////////////////////////////////////////////////////
//Initialization of UDA1341 Audio Codec using L3 Interface
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -