📄 iic_s5x532.c
字号:
/*====================================================================
IIC Tx/Rx between S3C24A0(Master) and S5X532(Slave) Test
- S5X532 Slave ID => 0x5a
- S5X532 I2C Format
WRITE: Start <5A> <Reg Addr> <Data> Stop
READ: Start <5A> <Reg Addr> Stop + Restart <5B> [Data] Stop
- Should consider Page Setting before Reg Read/Write
Ex) If you try to WRITE data '2Fh' at address '30h' in ISP (page 01)
<5Ah><ECh><01h> ;Page Setting
<5Ah><30h><2Fh> ;Reg Write
If you try ro READ data XXh at address '1Bh' in CIS (page 02)
<5Ah><ECh><02h> ;Page Setting
<5Ah><1Bh><restart><5B>[XXh] ;Reg Read
Revision History
0.0: 2003. 08. 05 (by Y. H. Lee)
- First Ported for OV7620 Register Read/Write using 2440 IIC Interface
0.1: 2003. 10. 08 (by Y. H. Lee)
- Ported for S5X532 Register Read/Write using 2440 IIC Interface
1.0: 2004.01.16 (ows)
- porting 2440 source to 24A0 for S5X5332 camera(samsung) test
*Notes
1. S3c24A0X version has the BUG in camera control register(CTRL_C's bit9[PCLKPOL]).
Bit9[PCLKPOL] did not affect the polarity of PCLK. As a result, , the fetched data when PCLK is rising
is invalidated. So, we tried to change the polarity of PCLK using the INVERTER IC for valid data fetching
_____ ______
/PCLK |_____| |______
____________
Data _____/ \______
\___________/
^---> Data fetching point delayed 50% after data valid
^---> point of output data by camera module
====================================================================*/
#include "iic_s5x532.h"
//===================================================================
// SMDK24A0 IIC configuration
// IIC port : dedicated X2cSDA, X2cSCL
//===================================================================
void * func_S5X532_test[][2]=
{
//IIC
(void *)S5X532_WriteByte, "Write 1 byte data into S5X532 register",
(void *)S5X532_ReadByte, "Read 1 byte data from S5X532 register",
(void *)S5X532_WriteBlock, "Write a block of byte data into S5X532 register",
(void *)S5X532_ReadBlock, "Read a block of byte data from S5X532 register",
0,0
};
void S5X532_Iic_Test(void)
{
int i, camclk;
Uart_Printf("\n***** IIC Master Tx/Rx Test Program with S5X532 *****\n");
rCLKCON |= ((1<<23)|(1<<21)); // enable camclk
CamReset(1); // s5x532 must do this.. CAMRST : ---|_____|---
Delay(1000); // ready time of s5x433, s5x532 IIC interface. needed...
// Selecting cam clock
Uart_Printf("Input Camera Clock\n");
Uart_Printf("0:48Mhz, 1:24Mhz, 2:16Mhz, 3:12Mhz, 4:9.6Mhz\n");
i = Uart_GetIntNum();
SetCAMClockDivider(i); //Set Camera Clock
pISR_IIC = (unsigned)S5X532_IicInt;
rINTMSK &= ~(BIT_IIC);
while(1)
{
i=0;
Uart_Printf("\n\n");
while(1)
{ //display menu
Uart_Printf("%2d:%s\n", i, func_S5X532_test[i][1]);
i++;
if((int)(func_S5X532_test[i][0])==0)
{
Uart_Printf("\n");
break;
}
if((i%4)==0)
Uart_Printf("\n");
}
Uart_Printf("\nPress Enter key to exit : ");
i = Uart_GetIntNum();
if(i==-1) break; // return.
if(i>=0 && (i<((sizeof(func_S5X532_test)-1)/8)) ) // select and execute...
( (void (*)(void)) (func_S5X532_test[i][0]) )();
}
rCLKCON &= ~((1<<23)|(1<<21)); // enable camclk
Uart_Printf("\n");
}
void S5X532_WriteByte(void)
{
unsigned int i, j, save_E, save_PE, RegAddr, RegData, pageNo;
//Enable ACK, Prescaler IICCLK=PCLK/512, Enable interrupt, Transmit clock value Tx clock=IICCLK/16
rIICCON = (1<<7) | (1<<6) | (1<<5) | (0xf);
rIICADD = 0x10; //24a0 slave address = [7:1]
rIICSTAT = 0x10; //IIC bus data output enable(Rx/Tx)
rIICSDADLY = 1; // SDAOUT has 5clock cycle delay
Uart_Printf("Input Write Page No of S5X532\n=>");
pageNo = (U8)Uart_GetIntNum();
Uart_Printf("Input Write Register Address of S5X532\n=>");
RegAddr = (U8)Uart_GetIntNum();
Uart_Printf("Input Write Transfer Data into S5X532\n=>");
RegData = (U8)Uart_GetIntNum();
Wr_S5X532(SlaveID, (U8)0xec, pageNo); // set Page no
Wr_S5X532(SlaveID, (U8)RegAddr, RegData); // set register after setting page number
}
void S5X532_ReadByte(void)
{
unsigned int i, j, save_E, save_PE, RegAddr, RegData, pageNo;
static U8 rdata[8];
//Enable ACK, Prescaler IICCLK=PCLK/512, Enable interrupt, Transmit clock value Tx clock=IICCLK/16
rIICCON = (1<<7) | (1<<6) | (1<<5) | (0xf);
rIICADD = 0x10; //2440 slave address = [7:1]
rIICSTAT = 0x10; //IIC bus data output enable(Rx/Tx)
rIICSDADLY = 1; // SDAOUT has 5clock cycle delay
Uart_Printf("Input Write Page No of S5X532\n=>");
pageNo = (U8)Uart_GetIntNum();
Wr_S5X532(SlaveID, (U8)0xec, pageNo); // set Page no
Uart_Printf("Input Read Register Address of S5X532\n=>");
RegAddr = (U8)Uart_GetIntNum();
Rd_S5X532(SlaveID, RegAddr, &rdata[0]);
Uart_Printf("Register Addr: 0x%2x, data: 0x%2x\n", RegAddr,rdata[0]);
}
void S5X532_WriteBlock(void)
{
unsigned int i, j, save_E, save_PE, RegAddr, RegData;
static U8 rdata[256];
// for camera init, added by junon
pISR_IIC = (unsigned)S5X532_IicInt;
rINTMSK &= ~(BIT_IIC);
//Enable ACK, Prescaler IICCLK=PCLK/512, Enable interrupt, Transmit clock value Tx clock=IICCLK/16
rIICCON = (1<<7) | (1<<6) | (1<<5) | (0xf);
rIICADD = 0x10; //2440 slave address = [7:1]
rIICSTAT = 0x10; //IIC bus data output enable(Rx/Tx)
rIICSDADLY = 1; // SDAOUT has 5clock cycle delay
for(i=0; i<(sizeof(S5X532_TV)/2); i++)
{
Wr_S5X532(SlaveID, S5X532_TV[i][0], S5X532_TV[i][1]);
}
Uart_Printf("\nBlock TX Ended...\n");
}
void S5X532_ReadBlock(void)
{
unsigned int i, j, save_E, save_PE, RegAddr, RegData;
static U8 rdata[256];
//Enable ACK, Prescaler IICCLK=PCLK/512, Enable interrupt, Transmit clock value Tx clock=IICCLK/16
rIICCON = (1<<7) | (1<<6) | (1<<5) | (0xf);
rIICADD = 0x10; //2440 slave address = [7:1]
rIICSTAT = 0x10; //IIC bus data output enable(Rx/Tx)
rIICSDADLY = 1; // SDAOUT has 5clock cycle delay
for(i=0; i<(sizeof(S5X532_TV)/2);i++)
{
if(S5X532_TV[i][0] == 0xec)
Wr_S5X532(SlaveID, S5X532_TV[i][0], S5X532_TV[i][1]);
else
Rd_S5X532(SlaveID, S5X532_TV[i][0], &rdata[i]);
}
for(i=0; i<(sizeof(S5X532_TV)/2);i++)
{
if(S5X532_TV[i][0] == 0xec)
Uart_Printf("Page: 0x%2x\n", S5X532_TV[i][1]);
else
Uart_Printf("Addr: 0x%2x, W: 0x%2x, R: 0x%2x\n", S5X532_TV[i][0], S5X532_TV[i][1], rdata[i]);
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
void Wr_S5X532(U32 slvAddr, U32 addr, U8 data)
{
_iicMode = WRDATA;
_iicPt = 0;
_iicData[0] = (U8)addr;
_iicData[1] = data;
_iicDataCount = 2;
rIICDS = slvAddr; //0x5a: S5X532 Slave ID
rIICSTAT = 0xf0; //Start Master TX Condition
rIICCON = 0xef; //Clearing the pending bit isn't needed because the pending bit has been cleared.
while(_iicDataCount!=-1);
// Run_Polling();
}
void Rd_S5X532(U32 slvAddr,U32 addr,U8 *data)
{
/*IIC Slave Addr Write + IIC Reg Addr Write */
_iicMode = SETRDADDR;
_iicPt = 0;
_iicData[0] = (U8)addr;
_iicDataCount = 1;
rIICDS = slvAddr;
rIICSTAT = 0xf0; //Master Tx, Start
rIICCON = 0xef; //Resumes IIC operation.
//Clearing the pending bit isn't needed because the pending bit has been cleared.
while(_iicDataCount!=-1);
// Run_Polling();
_iicMode = RDDATA;
_iicPt = 0;
_iicDataCount = 1;
rIICDS = slvAddr;
rIICSTAT = 0xb0; //Master Rx,Start
rIICCON = 0xef; //Resumes IIC operation.
while(_iicDataCount!=-1);
// Run_Polling();
*data = _iicData[1];
}
/*
////////////////////// Run_Polling ///////////////////////
void Run_Polling(void)
{
if(rIICCON & 0x10) //Tx/Rx Interrupt Enable
Polling();
}
*/
////////////////////// IicPoll ////////////////////////
void __irq S5X532_IicInt(void)
{
U32 iicSt,i;
ClearPending(BIT_IIC);
iicSt = rIICSTAT;
rINTMSK |= BIT_IIC;
if(iicSt & 0x8){} //When bus arbitration is failed.
if(iicSt & 0x4){} //When a slave address is matched with IICADD
if(iicSt & 0x2){} //When a slave address is 0000000b
if(iicSt & 0x1){} //When ACK isn't received
switch(_iicMode)
{
case RDDATA:
if((_iicDataCount--)==0)
{
_iicData[_iicPt++] = rIICDS;
rIICSTAT = 0x90; //Stop MasRx condition
rIICCON = 0xef; //Resumes IIC operation.
Delay(2); //Wait until stop condtion is in effect., Too long time... # need the time 2440:Delay(1), 24A0: Delay(2)
//The pending bit will not be set after issuing stop condition.
break;
}
_iicData[_iicPt++] = rIICDS; //The last data has to be read with no ack.
if((_iicDataCount)==0)
rIICCON = 0x6f; //Resumes IIC operation with NOACK in case of S5X532 Cameara
else
rIICCON = 0xef; //Resumes IIC operation with ACK
break;
case WRDATA:
if((_iicDataCount--)==0)
{
rIICSTAT = 0xd0; //stop MasTx condition
rIICCON = 0xef; //resumes IIC operation.
Delay(2); //wait until stop condtion is in effect. # need the time 2440:Delay(1), 24A0: Delay(2)
//The pending bit will not be set after issuing stop condition.
break;
}
rIICDS = _iicData[_iicPt++]; //_iicData[0] has dummy.
for(i=0;i<50;i++); //for setup time until rising edge of IICSCL
rIICCON = 0xef; //resumes IIC operation.
break;
case SETRDADDR:
// Uart_Printf("[S%d]",_iicDataCount);
if((_iicDataCount--)==0)
{
rIICSTAT = 0xd0; //stop MasTx condition
rIICCON = 0xef; //resumes IIC operation.
Delay(2); //wait until stop condtion is in effect.
break; //IIC operation is stopped because of IICCON[4]
}
rIICDS = _iicData[_iicPt++];
for(i=0;i<50;i++); //for setup time until rising edge of IICSCL
rIICCON = 0xef; //resumes IIC operation.
break;
default:
break;
}
rINTMSK &= ~BIT_IIC;
}
void Test_s5x532_with_sccb(void) // test not completed
{
int i;
unsigned char indata;
//ChangeUPllValue(0x38,2,1); // 96MHz
//rCLKDIVN|=(1<<3); // UCLK 48MHz setting
//SetCAMClockDivider(3); //Set Camera Clock 12MHz
rCLKCON |= ((1<<23)|(1<<21)); // enable camclk
// Selecting cam clock
Uart_Printf("Input Camera Clock\n");
Uart_Printf("0:48Mhz, 1:24Mhz, 2:16Mhz, 3:12Mhz, 4:9.6Mhz\n");
i = Uart_GetIntNum();
SetCAMClockDivider(i); //Set Camera Clock
//camclk = 96000000/(((rCAMDIVN&0xf) +1)*2);
//Uart_Printf("CAMCLK = %d Hz\n", camclk);
//Init_Sccb_Port();
/*
for(i=0; i<(sizeof(S5X532_YCbCr8bit_TV)/2);i++){
setCIS(S5X532_YCbCr8bit_TV[i][0], S5X532_YCbCr8bit_TV[i][1]);
Uart_Printf("Addr : 0x%x, Data : 0x%x\n", S5X532_YCbCr8bit_TV[i][0], S5X532_YCbCr8bit_TV[i][1]);
Uart_Getch();
}
*/ for(i=0; i<(sizeof(S5X532_TV)/2);i++){
// indata = getCIS(S5X532_YCbCr8bit_TV[i][0]);
Uart_Printf("Addr: 0x%3x, W: 0x%3x, R: 0x%3x\n", S5X532_TV[i][0], S5X532_TV[i][1], indata);
//Uart_Getch();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -