📄 iic.c
字号:
;/*********************************************************************
;* Project Name : S3C2443X
;*
;* Copyright 2005 by Samsung Electronics, Inc.
;* All rights reserved.
;*
;* Project Description :
;* This software is only for verifying functions of the mDirac III
;* Anybody can use this code without our permission.
;**********************************************************************
;*
;* Description : Code for the basic function for IIC.
;* It can support write and read mode with 7-bit addresses
;* Can make the 10-bit address write and read mode
;* with assemble these functions.
;*
;* History
;* R0.0 (2005.9.30) : Y.C.Kwon draft
;*
;**********************************************************************/
#include "System.h"
#include "iic.h"
#include "iic1.h"
#define SlaveRX (0)
#define SlaveTX (1)
#define MasterRX (2)
#define MasterTX (3)
static volatile char *IIC_BUFFER;
//static volatile char IIC_BUFFER[3];
static volatile unsigned int IIC_PT;
static unsigned int IIC_DATALEN;
static volatile unsigned char IIC_STAT;
void * iic_func[][2]=
{
(void *) Test_IIC_Int, (char *)"IIC Test(Int) ",
(void *) Test_IIC_Pol, (char *)"IIC Test(Poll) ", // "123456789012345678901"
(void *) Test_IIC1_Int, (char *)"IIC1 Test(Int) ",
(void *) Test_IIC1_Pol, (char *)"IIC1 Test(Poll) ",
0,0
};
void Test_IIC(void)
{
int i=0;
while(1)
{
i=0;
printf("\n\n");
while(1)
{ //display menu
printf("%2d:%s",i,iic_func[i][1]);
i++;
if((int)(iic_func[i][0])==0)
{
printf("\n");
break;
}
printf("\n");
}
printf("\nPress Enter key to exit : ");
i = GetIntNum();
if(i==-1) break; // return.
if(i>=0 && (i<((sizeof(iic_func)-1)/8)) ) // select and execute...
( (void (*)(void)) (iic_func[i][0]) )();
}
}
void __irq IIC_Int( void)
{
IIC_STAT = rIICSTAT;
switch( (IIC_STAT>>6)&0x3) {
case SlaveRX : break;
case SlaveTX : break;
case MasterRX : if (IIC_PT>0)
IIC_BUFFER[IIC_PT-1] = rIICDS;
IIC_PT++;
if (IIC_PT==IIC_DATALEN)
rIICCON &= ~(1<<7);
else if (IIC_PT>IIC_DATALEN)
rIICSTAT = 0x90; // Stop Master Rx condition
rIICCON &= ~(1<<4); // Clear pending bit to resume
break;
case MasterTX : if (IIC_PT<IIC_DATALEN)
rIICDS = IIC_BUFFER[IIC_PT];
else
rIICSTAT= 0xd0; // Stop Master Tx condition, ACK flag clear
IIC_PT++;
rIICCON &= ~(1<<4); // Clear pending bit to resume
break;
}
IIC_STAT&=0xf;
ClearPending(BIT_IIC);
}
void IIC_open( unsigned int freq) // Hz order.
{
unsigned int clk_prescaler, clk_divider;
rGPECON = rGPECON & ~(0xf<<28) | (0xa<<28); // IIC setting
rGPEUDP = rGPEUDP & ~(0xf<<28) | (0x0<<28);
if (((PCLK>>4)/freq)>0xf) {
clk_prescaler = 1;
clk_divider = (PCLK>>9)/freq; // PCLK/512/freq
} else {
clk_prescaler = 0;
clk_divider = (PCLK>>4)/freq; // PCLK/16/freq
}
// Prescaler IICCLK=PCLK/16, Enable interrupt, Transmit clock value Tx clock=IICCLK/16
rIICCON = (clk_prescaler<<6) | (1<<5) | (clk_divider&0xf);
rIICADD = 0x10; // Slave address = [7:1]
rIICSTAT = 0x10; // IIC bus data output enable(Rx/Tx)
rIICLC = 0; // SDA Filter disable
}
void IIC_open_Cam( unsigned int freq) // Hz order.
{
unsigned int clk_prescaler, clk_divider;
rGPECON = rGPECON & ~(0xf<<28) | (0xa<<28); // IIC setting
rGPEUDP = rGPEUDP & ~(0xf<<28) | (0x0<<28);
pISR_IIC = (unsigned)IIC_Int;
rINTMSK &= ~(BIT_IIC);
if (((PCLK>>4)/freq)>0xf) {
clk_prescaler = 1;
clk_divider = (PCLK>>9)/freq; // PCLK/512/freq
} else {
clk_prescaler = 0;
clk_divider = (PCLK>>4)/freq; // PCLK/16/freq
}
// Prescaler IICCLK=PCLK/16, Enable interrupt, Transmit clock value Tx clock=IICCLK/16
rIICCON = (clk_prescaler<<6) | (1<<5) | (clk_divider&0xf);
rIICADD = 0x10; // Slave address = [7:1]
rIICSTAT = 0x10; // IIC bus data output enable(Rx/Tx)
rIICLC = 0; // SDA Filter disable
}
void IIC_close( void)
{
rINTMSK |= BIT_IIC;
rIICSTAT = 0x0; // IIC bus data output disable(Rx/Tx)
}
// Write Mode Format with 7-bit addresses
void IIC_Write( unsigned char SlaveAddr, char *Data, unsigned int n)
{
while(rIICSTAT&(1<<5)); // Wait until IIC bus is free.
// IIC_BUFFER[1] = *Data;
IIC_BUFFER = Data;
IIC_PT = 0;
IIC_DATALEN = n;
rIICCON |= (1<<7);
rIICDS = SlaveAddr;
rIICSTAT = 0xF0; // Master Tx Start.
}
void IIC_Write_Pol( unsigned char SlaveAddr, char *Data, unsigned int n)
{
while(rIICSTAT&(1<<5)); // Wait until IIC bus is free.
// IIC_BUFFER[1] = *Data;
IIC_BUFFER = Data;
IIC_PT = 0;
IIC_DATALEN = n;
rIICCON |= (1<<7); // acknowledge enable bit
rIICDS = SlaveAddr;
rIICSTAT = 0xF0; // Master Tx Start.
while(IIC_DATALEN >= IIC_PT)
{
while(!(rIICCON&(1<<4))); // check the interrupt pending bit
IIC_STAT = rIICSTAT;
switch( (IIC_STAT>>6)&0x3) {
case SlaveRX : break;
case SlaveTX : break;
case MasterRX : if (IIC_PT>0)
IIC_BUFFER[IIC_PT-1] = rIICDS;
IIC_PT++;
if (IIC_PT==IIC_DATALEN)
rIICCON &= ~(1<<7);
else if (IIC_PT>IIC_DATALEN)
rIICSTAT = 0x90; // Stop Master Rx condition
rIICCON &= ~(1<<4); // Clear pending bit to resume
break;
case MasterTX : if (IIC_PT<IIC_DATALEN)
rIICDS = IIC_BUFFER[IIC_PT];
else
rIICSTAT= 0xd0; // Stop Master Tx condition, ACK flag clear
IIC_PT++;
rIICCON &= ~(1<<4); // Clear pending bit to resume
break;
}
IIC_STAT&=0xf; // check status flag
}
}
// Read Mode Format with 7-bit addresses
void IIC_Read( unsigned char SlaveAddr, char *Data, unsigned int n)
{
while(rIICSTAT&(1<<5)); // Wait until IIC bus is free.
// IIC_BUFFER[1] = *Data;
IIC_BUFFER = Data;
IIC_PT = 0;
IIC_DATALEN = n;
rIICCON |= (1<<7);
rIICDS = SlaveAddr;
rIICSTAT = 0xB0; // Master Rx Start
}
void IIC_Read_Pol( unsigned char SlaveAddr, char *Data, unsigned int n)
{
while(rIICSTAT&(1<<5)); // Wait until IIC bus is free.
// IIC_BUFFER[1] = *Data;
IIC_BUFFER = Data;
IIC_PT = 0;
IIC_DATALEN = n;
rIICCON |= (1<<7);
rIICDS = SlaveAddr;
rIICSTAT = 0xB0; // Master Rx Start
while(IIC_DATALEN >= IIC_PT)
{
while(!(rIICCON&(1<<4)));
IIC_STAT = rIICSTAT;
switch( (IIC_STAT>>6)&0x3) {
case SlaveRX : break;
case SlaveTX : break;
case MasterRX : if (IIC_PT>0)
IIC_BUFFER[IIC_PT-1] = rIICDS;
IIC_PT++;
if (IIC_PT==IIC_DATALEN)
rIICCON &= ~(1<<7);
else if (IIC_PT>IIC_DATALEN)
rIICSTAT = 0x90; // Stop Master Rx condition
rIICCON &= ~(1<<4); // Clear pending bit to resume
break;
case MasterTX : if (IIC_PT<IIC_DATALEN)
rIICDS = IIC_BUFFER[IIC_PT];
else
rIICSTAT= 0xd0; // Stop Master Tx condition, ACK flag clear
IIC_PT++;
rIICCON &= ~(1<<4); // Clear pending bit to resume
break;
}
IIC_STAT&=0xf; // check status flag
}
}
void IIC_Wait( void) // Waiting for the command takes effect.
{ // But not for IIS bus free.
while(IIC_PT<=IIC_DATALEN);
}
unsigned char IIC_Status( void) // Return IIC Status Register value at last interrupt occur.
{
return IIC_STAT;
}
//****************************************************************//
//* Basic test code for Serial EEPROM with the basic functions.
//****************************************************************//
#define EEPROMSlaveAddr 0xa0
void WrSerialEEPROM( char Addr, char Data)
{
char D[2];
D[0]=Addr;
D[1]=Data;
IIC_Write( EEPROMSlaveAddr, D, 2);
do { // Polling for an ACK signal from SerialEEPROM.
IIC_Write( EEPROMSlaveAddr, NULL, 0);
IIC_Wait();
} while(IIC_Status()&0x1);
}
void WrSerialEEPROM_Pol( char Addr, char Data)
{
char D[2];
D[0]=Addr;
D[1]=Data;
IIC_Write_Pol( EEPROMSlaveAddr, D, 2);
do { // Polling for an ACK signal from SerialEEPROM.
IIC_Write_Pol( EEPROMSlaveAddr, NULL, 0);
IIC_Wait();
} while(IIC_Status()&0x1); // ACK was not received
}
void RdSerialEEPROM( char Addr, char *Data)
{
IIC_Write( EEPROMSlaveAddr, &Addr, 1);
IIC_Read( EEPROMSlaveAddr, Data, 1);
IIC_Wait(); // Waiting for read complete.
}
void RdSerialEEPROM_Pol( char Addr, char *Data)
{
IIC_Write_Pol( EEPROMSlaveAddr, &Addr, 1);
IIC_Read_Pol( EEPROMSlaveAddr, Data, 1);
IIC_Wait(); // Waiting for read complete.
}
void Test_IIC_Int( void)
{
unsigned int i;
char D;
printf("[ IIC Test using Serial EEPROM ]\n");
IIC_open(200000); // Serial EEPROM IIC clk = 200KHz
pISR_IIC = (unsigned)IIC_Int;
rINTMSK &= ~(BIT_IIC);
printf("\nWrite (0xff) and read back from EEPROM\n");
for(i=0;i<256;i++) {
D=0;
WrSerialEEPROM(i,0xff);
RdSerialEEPROM(i,&D);
printf("%02x ",D);
if ((i&0xf)==0xf) printf("\n");
}
printf("\nWrite (0~255) and read back from EEPROM\n");
for(i=0;i<256;i++) {
D=0;
WrSerialEEPROM(i,i);
RdSerialEEPROM(i,&D);
printf("%02x ",D);
if ((i&0xf)==0xf) printf("\n");
}
IIC_close();
}
void Test_IIC_Pol( void)
{
unsigned int i;
char D;
printf("[ IIC Test using Serial EEPROM [polling mode] ]\n");
IIC_open(200000); // Serial EEPROM IIC clk = 200KHz
printf("\nWrite (0xff) and read back from EEPROM\n");
for(i=0;i<256;i++) {
D=0;
WrSerialEEPROM_Pol(i,0xff);
RdSerialEEPROM_Pol(i,&D);
printf("%02x ",D);
if ((i&0xf)==0xf) printf("\n");
}
printf("\nWrite (0~255) and read back from EEPROM\n");
for(i=0;i<256;i++) {
D=0;
WrSerialEEPROM_Pol(i,i);
RdSerialEEPROM_Pol(i,&D);
printf("%02x ",D);
if ((i&0xf)==0xf) printf("\n");
}
IIC1_close();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -