📄 i2c_drv.c
字号:
/**
* modified by liwei@actions,2006,09,30
*/
typedef unsigned long ulong;
/*********************************************************************
GL3963 I2C Driver
File:I2C_Driver.c
Written by WangQian
Version:0.1
Update Data:2006-05-14
**********************************************************************/
#include "Actions_reg_213x.h"
static char na_flag;
/***************************** Function ***********************************/
//public I2C_Init(void);
//public I2C_Exit(void);
//public I2C_Start(ulong addr,char byt);
//public I2C_Stop(void);
//public I2C_WriteOneByte(char wbyte);
//public I2C_ReadOneByte(char stat);
//public trans_ov(void);
//public recv_ov(void);
//public DELAY_15us(void)
/***************************************************************************/
/********************************************************************************
Write Register:
Input Parameter:
*reg:Register point
var:Value
Output Parameter: No
********************************************************************************/
static void inline
Write_reg(volatile ulong * reg, ulong var)
{
*reg = var;
return;
}
/********************************************************************************
Read Register:
Input Parameter:
*reg:Register point
Output Parameter:
var:Return Value
********************************************************************************/
static ulong inline
Read_reg(volatile ulong * reg)
{
ulong var;
var = *reg;
return (var);
}
/********************************************************************************
I2C Initialization:
Input Parameter: No
Output Parameter: No
********************************************************************************/
void inline
I2C_Init(void)
{
Write_reg((ulong *) (I2C1_CTL), 0x00000000); //reset I2C
Write_reg((ulong *) (I2C1_CTL), 0x00000080); //enable I2C
//Write_reg((ulong *)(I2C1_CLKDIV), 0x0000001e); //SCL=PCLK/(CLKDIV*16) PCLK:48 SCL:400kbps
Write_reg((ulong *) (I2C1_CLKDIV), 0x00000002); //here must set the PCLK to set the speed 100K or 400K
Write_reg((ulong *) (I2C2_CTL), 0x00000080);
//Write_reg((ulong *)(I2C2_CLKDIV), 0x0000001e); //SCL=PCLK/(CLKDIV*16) PCLK:48 SCL:400kbps
Write_reg((ulong *) (I2C2_CLKDIV), 0x00000002);
return;
}
/********************************************************************************
I2C Exit:
Input Parameter: No
Output Parameter: No
********************************************************************************/
void inline
I2C_Exit(void)
{
Write_reg((ulong *) (I2C1_CTL), 0x00000000);
Write_reg((ulong *) (I2C2_CTL), 0x00000000);
return;
}
/********************************************************************************
I2C Transfer complete:
Input Parameter: No
Output Parameter:
1:ACK;
0:NACK
********************************************************************************/
char
trans_ov(void)
{
char flag;
ulong temp = 0;
unsigned int repeat_times = 0xfffff;
if (na_flag == 0) { //wait tranfer over
repeat_times = 0xfffff;
do {
temp = Read_reg((ulong *) (I2C1_STAT));
temp = temp & (0x80);
} while ( (temp == 0) && (--repeat_times>0));
if ( !repeat_times){
// printf("trans_ov time out\n ");
return 0;//failure
}
Write_reg((ulong *) (I2C1_STAT), 0x00000080);
temp = Read_reg((ulong *) (I2C1_CTL));
} else if (na_flag == 1) {
repeat_times = 0xfffff;
do {
temp = Read_reg((ulong *) (I2C2_STAT));
temp = temp & (0x80);
} while ( (temp == 0) && (--repeat_times>0));
if ( !repeat_times){
// printf(" trans_ov time out\n ");
return 0;//failure
}
Write_reg((ulong *) (I2C2_STAT), 0x00000080);
temp = Read_reg((ulong *) (I2C2_CTL));
}
temp = temp & (0x01); //ack or nack
if (temp == 1)
flag = 1;
else
flag = 0;
return (flag);
}
/********************************************************************************
I2C Receive complete:
Input Parameter: No
Output Parameter: No
********************************************************************************/
char
recv_ov(void)
{
ulong temp;
char flag = 0;
unsigned int repeat_times= 0xfffff;
if (na_flag == 0) { //wait receive over
do {
temp = Read_reg((ulong *) (I2C1_STAT));
temp = temp & (0x80);
} while ( (temp == 0) && (--repeat_times>0));
if ( !repeat_times){
// printf("recv_ov time out\n ");
}
Write_reg((ulong *) (I2C1_STAT), 0x00000080);
} else if (na_flag == 1) {
repeat_times = 0xfffff;
do {
temp = Read_reg((ulong *) (I2C2_STAT));
temp = temp & (0x80);
} while ( (temp == 0) && (--repeat_times>0));
if ( !repeat_times){
// printf("recv_ov time out\n ");
}
Write_reg((ulong *) (I2C2_STAT), 0x00000080);
}
return flag;
}
/********************************************************************************
I2C Start:
Input Parameter:
addr----Slave Address;
byt----one of the I2C
Output Parameter:
1-success;
0-fail.
********************************************************************************/
char
I2C_Start(ulong addr, char byt)
{
char flag;
na_flag = byt;
if (na_flag == 0) { //I2C1
Write_reg((ulong *) (I2C1_ADDR), addr); //slave address
Write_reg((ulong *) (I2C1_CTL), 0x00000086); //start condition
flag = trans_ov(); //1:ack 0:nack
return flag;
} else if (na_flag == 1) { //I2C2
Write_reg((ulong *) (I2C2_ADDR), addr);
Write_reg((ulong *) (I2C2_CTL), 0x00000086);
flag = trans_ov();
return flag;
}
return 0;
}
/********************************************************************************
I2C Stop:
Input Parameter: No
Output Parameter: No
********************************************************************************/
void
I2C_Stop(void)
{
ulong temp;
if (na_flag == 0) { //I2C1
Write_reg((ulong *) (I2C1_CTL), 0x0000008b); //stop condition
do {
temp = Read_reg((ulong *) (I2C1_STAT)); //wait stop
temp = (temp & 0x40);
} while (temp == 0);
Write_reg((ulong *) (I2C1_STAT), 0x00000040); //clear stop status
} else if (na_flag == 1) {
Write_reg((ulong *) (I2C2_CTL), 0x0000008b);
do {
temp = Read_reg((ulong *) (I2C2_STAT));
temp = (temp & 0x40);
} while (temp == 0);
Write_reg((ulong *) (I2C2_STAT), 0x00000040);
}
return;
}
/********************************************************************************
I2C Write One Byte:
Input Parameter:
wbyte---One Byte
Output Parameter:
0:fail;
1:success.
********************************************************************************/
char
I2C_WriteOneByte(ulong wbyte)
{
char flag;
if (na_flag == 0) {
Write_reg((ulong *) (I2C1_DAT), wbyte); //transfer data
Write_reg((ulong *) (I2C1_CTL), 0x00000082); //realse bus
} else if (na_flag == 1) {
Write_reg((ulong *) (I2C2_DAT), wbyte);
Write_reg((ulong *) (I2C2_CTL), 0x00000082);
}
flag = trans_ov(); //ack or nack
return (flag);
}
/********************************************************************************
I2C Read One Byte:
Input Parameter:
stat:1-Send NACK;
0-Send ACK.
Output Parameter:
Byte-Value
********************************************************************************/
ulong
I2C_ReadOneByte(char stat)
{
ulong readbyte = 0;
if (stat == 1) { //no ack
if (na_flag == 0) {
Write_reg((ulong *) (I2C1_CTL), 0x00000083); //realse bus and nack
recv_ov();
readbyte = Read_reg((ulong *) (I2C1_DAT)); //read data
//Write_reg((ulong *)(I2C1_CTL), 0x00000082); //realse bus and nack
//recv_ov();
} else {
Write_reg((ulong *) (I2C2_CTL), 0x00000083);
recv_ov();
readbyte = Read_reg((ulong *) (I2C2_DAT));
//Write_reg((ulong *)(I2C2_CTL), 0x00000082);
//recv_ov();
}
} else if (stat == 0) { //ack
if (na_flag == 0) {
Write_reg((ulong *) (I2C1_CTL), 0x00000082); //realse bus and ack
recv_ov();
readbyte = Read_reg((ulong *) (I2C1_DAT));
//Write_reg((ulong *)(I2C1_CTL), 0x00000082); //realse bus and ack
//recv_ov();
} else {
Write_reg((ulong *) (I2C2_CTL), 0x00000082);
recv_ov();
readbyte = Read_reg((ulong *) (I2C2_DAT));
//Write_reg((ulong *)(I2C2_CTL), 0x00000082);
//recv_ov();
}
}
return (readbyte);
}
/********************************************************************************
delay time:
Input Parameter: No
Output Parameter: No
********************************************************************************/
void
DELAY_15us(void)
{
return;
#if 0
volatile int i, c;
for (i = 0; i < 40; i++) {
c = 0;
}
return;
#endif
}
/********************************************************************************************
Function is to set PA and enable ADC DAC for FM.
Input parameter:
type(select FM or LINE)
Output parameter: no
********************************************************************************************/
void
INIT_ADDA(char type)
{
if (type == 0) { //LINE
Write_reg((ulong *) (ADC_CTL), 0x8b57a50a);
Write_reg((ulong *) (DAC_ANALOG), 0x2155a2fc);
} else if (type == 1) { //FM
Write_reg((ulong *) (ADC_CTL), 0x8b34bd0a); //AVCC_Voltage:2.9V ADC Iput Gain:0dB
int temp;
temp = Read_reg((ulong *)(DAC_ANALOG)); /* init,volume is 0*/
temp = temp | 0x2155a005;
// temp = temp & ~(0x1f<<3);
Write_reg((ulong *) (DAC_ANALOG), temp);
}
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -