📄 iic.c
字号:
;/*********************************************************************
;* Project Name : mDirac III
;*
;* 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 *IIC_BUFFER;
static volatile unsigned int IIC_PT;
static unsigned int IIC_DATALEN;
static volatile unsigned char IIC_STAT;
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 & ~((U32)(0xf<<28)) | ((U32)(0xa<<28)); // IIC setting
rGPEUDP = rGPEUDP & ~((U32)(0xf<<28)) | ((U32)(0xa<<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
}
pISR_IIC = (unsigned)IIC_Int;
rINTMSK &= ~(BIT_IIC);
// 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 = Data;
IIC_PT = 0;
IIC_DATALEN = n;
rIICCON |= (1<<7);
rIICDS = SlaveAddr;
rIICSTAT = 0xF0; // Master Tx Start.
}
// 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 = Data;
IIC_PT = 0;
IIC_DATALEN = n;
rIICCON |= (1<<7);
rIICDS = SlaveAddr;
rIICSTAT = 0xB0; // Master Rx Start
}
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 RdSerialEEPROM( char Addr, char *Data)
{
IIC_Write( EEPROMSlaveAddr, &Addr, 1);
IIC_Read( EEPROMSlaveAddr, Data, 1);
IIC_Wait(); // Waiting for read complete.
}
void Test_IIC( void)
{
unsigned int i;
char D;
printf("[ IIC Test using Serial EEPROM ]\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(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();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -