📄 iic1.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"
#define SlaveRX (0)
#define SlaveTX (1)
#define MasterRX (2)
#define MasterTX (3)
static volatile char *IIC1_BUFFER;
static volatile unsigned int IIC1_PT;
static unsigned int IIC1_DATALEN;
static volatile unsigned char IIC1_STAT;
void __irq IIC1_Int( void)
{
IIC1_STAT = rIICSTAT1;
switch( (IIC1_STAT>>6)&0x3) {
case SlaveRX : break;
case SlaveTX : break;
case MasterRX : if (IIC1_PT>0)
IIC1_BUFFER[IIC1_PT-1] = rIICDS1;
// printf("\nPT:%d, Buffer: %x, rIICDS1:%x",IIC1_PT-1, IIC1_BUFFER[IIC1_PT-1] , rIICDS1);
IIC1_PT++;
if (IIC1_PT==IIC1_DATALEN)
rIICCON1 &= ~(1<<7);
else if (IIC1_PT>IIC1_DATALEN)
rIICSTAT1 = 0x90; // Stop Master Rx condition
rIICCON1 &= ~(1<<4); // Clear pending bit to resume
break;
case MasterTX : if (IIC1_PT<IIC1_DATALEN)
{ rIICDS1 = IIC1_BUFFER[IIC1_PT];
// if(IIC1_PT==1) printf("\nISR%x, %x", IIC1_BUFFER[IIC1_PT] , rIICDS1);
}
else
rIICSTAT1= 0xd0; // Stop Master Tx condition, ACK flag clear
IIC1_PT++;
rIICCON1 &= ~(1<<4); // Clear pending bit to resume
break;
}
IIC1_STAT&=0xf; // check status flag
ClearPending2(BIT_IIC1);
}
void IIC1_open( unsigned int freq) // Hz order.
{
unsigned int clk_prescaler, clk_divider;
rGPBSEL|=(0x3<<1); // GPB7=I2CSDA, GPB8=I2CSCL
rGPBUDP=rGPBUDP&~(0xf<<14)|(0x0<<14); // pull up/down disable
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
}
// pISR_IIC1 = (unsigned)IIC1_Int;
// rINTMSK2 &= ~(BIT_IIC1);
// Prescaler IICCLK=PCLK/16, Enable interrupt, Transmit clock value Tx clock=IICCLK/16
rIICCON1 = (clk_prescaler<<6) | (1<<5) | (clk_divider&0xf);
rIICADD1 = 0x10; // Slave address = [7:1]
rIICSTAT1 = 0x10; // IIC bus data output enable(Rx/Tx)
rIICLC1 = 0; // SDA Filter disable
}
void IIC1_close( void)
{
rINTMSK2 |= BIT_IIC1;
rIICSTAT1 = 0x0; // IIC bus data output disable(Rx/Tx)
}
// Write Mode Format with 7-bit addresses
void IIC1_Write( unsigned char SlaveAddr, char *Data, unsigned int n)
{
while(rIICSTAT1&(1<<5)); // Wait until IIC bus is free.
IIC1_BUFFER = Data;
IIC1_PT = 0;
IIC1_DATALEN = n;
rIICCON1 |= (1<<7); // acknowledge enable bit
rIICDS1 = SlaveAddr;
rIICSTAT1 = 0xF0; // Master Tx Start.
}
void IIC1_Write_Pol( unsigned char SlaveAddr, char *Data, unsigned int n)
{
while(rIICSTAT1&(1<<5)); // Wait until IIC bus is free.
IIC1_BUFFER = Data;
IIC1_PT = 0;
IIC1_DATALEN = n;
rIICCON1 |= (1<<7); // acknowledge enable bit
rIICDS1 = SlaveAddr;
rIICSTAT1 = 0xF0; // Master Tx Start.
while(IIC1_DATALEN >= IIC1_PT)
{
while(!(rIICCON1&(1<<4))); // check the interrupt pending bit
IIC1_STAT = rIICSTAT1;
switch( (IIC1_STAT>>6)&0x3) {
case SlaveRX : break;
case SlaveTX : break;
case MasterRX : if (IIC1_PT>0)
IIC1_BUFFER[IIC1_PT-1] = rIICDS1;
IIC1_PT++;
if (IIC1_PT==IIC1_DATALEN)
rIICCON1 &= ~(1<<7);
else if (IIC1_PT>IIC1_DATALEN)
rIICSTAT1 = 0x90; // Stop Master Rx condition
rIICCON1 &= ~(1<<4); // Clear pending bit to resume
break;
case MasterTX : if (IIC1_PT<IIC1_DATALEN)
rIICDS1 = IIC1_BUFFER[IIC1_PT];
else
rIICSTAT1= 0xd0; // Stop Master Tx condition, ACK flag clear
IIC1_PT++;
rIICCON1 &= ~(1<<4); // Clear pending bit to resume
break;
}
IIC1_STAT&=0xf; // check status flag
}
}
// Read Mode Format with 7-bit addresses
void IIC1_Read( unsigned char SlaveAddr, char *Data, unsigned int n)
{
while(rIICSTAT1&(1<<5)); // Wait until IIC bus is free.
IIC1_BUFFER = Data;
IIC1_PT = 0;
IIC1_DATALEN = n;
rIICCON1 |= (1<<7);
rIICDS1 = SlaveAddr;
rIICSTAT1 = 0xB0; // Master Rx Start
}
void IIC1_Read_Pol( unsigned char SlaveAddr, char *Data, unsigned int n)
{
while(rIICSTAT1&(1<<5)); // Wait until IIC bus is free.
IIC1_BUFFER = Data;
IIC1_PT = 0;
IIC1_DATALEN = n;
rIICCON1 |= (1<<7);
rIICDS1 = SlaveAddr;
rIICSTAT1 = 0xB0; // Master Rx Start
while(IIC1_DATALEN >= IIC1_PT)
{
while(!(rIICCON1&(1<<4)));
IIC1_STAT = rIICSTAT1;
switch( (IIC1_STAT>>6)&0x3) {
case SlaveRX : break;
case SlaveTX : break;
case MasterRX : if (IIC1_PT>0)
IIC1_BUFFER[IIC1_PT-1] = rIICDS1;
IIC1_PT++;
if (IIC1_PT==IIC1_DATALEN)
rIICCON1 &= ~(1<<7);
else if (IIC1_PT>IIC1_DATALEN)
rIICSTAT1 = 0x90; // Stop Master Rx condition
rIICCON1 &= ~(1<<4); // Clear pending bit to resume
break;
case MasterTX : if (IIC1_PT<IIC1_DATALEN)
rIICDS1 = IIC1_BUFFER[IIC1_PT];
else
rIICSTAT1= 0xd0; // Stop Master Tx condition, ACK flag clear
IIC1_PT++;
rIICCON1 &= ~(1<<4); // Clear pending bit to resume
break;
}
IIC1_STAT&=0xf; // check status flag
}
}
void IIC1_Wait( void) // Waiting for the command takes effect.
{ // But not for IIS bus free.
while(IIC1_PT<=IIC1_DATALEN);
}
unsigned char IIC1_Status( void) // Return IIC Status Register value at last interrupt occur.
{
return IIC1_STAT;
}
//****************************************************************//
//* Basic test code for Serial EEPROM with the basic functions.
//****************************************************************//
#define EEPROMSlaveAddr 0xa0
void WrSerialEEPROM1( char Addr, char Data)
{
char D[2];
D[0]=Addr;
D[1]=Data;
IIC1_Write( EEPROMSlaveAddr, D, 2);
do { // Polling for an ACK signal from SerialEEPROM.
IIC1_Write( EEPROMSlaveAddr, NULL, 0);
IIC1_Wait();
} while(IIC1_Status()&0x1);
}
void WrSerialEEPROM1_Pol( char Addr, char Data)
{
char D[2];
D[0]=Addr;
D[1]=Data;
IIC1_Write_Pol( EEPROMSlaveAddr, D, 2);
do { // Polling for an ACK signal from SerialEEPROM.
IIC1_Write_Pol( EEPROMSlaveAddr, NULL, 0);
IIC1_Wait();
} while(IIC1_Status()&0x1); // ACK was not received
}
void RdSerialEEPROM1( char Addr, char *Data)
{
IIC1_Write( EEPROMSlaveAddr, &Addr, 1);
IIC1_Read( EEPROMSlaveAddr, Data, 1);
IIC1_Wait(); // Waiting for read complete.
}
void RdSerialEEPROM1_Pol( char Addr, char *Data)
{
IIC1_Write_Pol( EEPROMSlaveAddr, &Addr, 1);
IIC1_Read_Pol( EEPROMSlaveAddr, Data, 1);
IIC1_Wait(); // Waiting for read complete.
}
void Test_IIC1_Int( void)
{
unsigned int i, j;
char D;
printf("[ IIC1 Test using Serial EEPROM [Interrupt mode] ]\n");
IIC1_open(200000); // Serial EEPROM IIC clk = 200KHz
pISR_IIC1 = (unsigned)IIC1_Int;
rINTMSK2 &= ~(BIT_IIC1);
printf("\nWrite (0xff) and read back from EEPROM\n");
for(i=0;i<256;i++) {
D=0;
j=0xff;
// WrSerialEEPROM1_Pol(i,0xff);
WrSerialEEPROM1(i,j);
RdSerialEEPROM1(i,&D);
// RdSerialEEPROM1_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;
WrSerialEEPROM1(i,i);
RdSerialEEPROM1(i,&D);
printf("%02x ",D);
if ((i&0xf)==0xf) printf("\n");
}
IIC1_close();
}
void Test_IIC1_Pol( void)
{
unsigned int i;
char D;
printf("[ IIC1 Test using Serial EEPROM [polling mode] ]\n");
IIC1_open(200000); // Serial EEPROM IIC clk = 200KHz
printf("\nWrite (0xff) and read back from EEPROM\n");
for(i=0;i<256;i++) {
D=0;
WrSerialEEPROM1_Pol(i,0xff);
RdSerialEEPROM1_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;
WrSerialEEPROM1_Pol(i,i);
RdSerialEEPROM1_Pol(i,&D);
printf("%02x ",D);
if ((i&0xf)==0xf) printf("\n");
}
IIC1_close();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -