📄 iic.c
字号:
/**************************************************************************************
*
* Project Name : S3C6400 Validation
*
* Copyright 2006 by Samsung Electronics, Inc.
* All rights reserved.
*
* Project Description :
* This software is only for validating functions of the S3C6400.
* Anybody can use this software without our permission.
*
*--------------------------------------------------------------------------------------
*
* File Name : iic.c
*
* File Description : This file implements the API functons for IIC
*
* Author : Woojin.Kim
* Dept. : AP Development Team
* Created Date : 2007/01/11
* Version : 0.1
*
* History
* - Created(Woojin.Kim 2007/01/11)
*
**************************************************************************************/
#include "iic.h"
#include "option.h"
#include "library.h"
#include "sfr6400.h"
#include "system.h"
#include "gpio.h"
#include "intc.h"
#include "def.h"
#define IICBUFSIZE 0x20
static volatile u8 *g_PcIIC_BUFFER;
static volatile u32 g_uIIC_PT;
static u32 g_uIIC_DATALEN;
static volatile u8 g_cIIC_STAT;
static volatile u8 g_cIIC_SlaveRxDone;
static volatile u8 g_cIIC_SlaveTxDone;
//////////
// Function Name : Isr_IIC
// Function Description : This function is Interrupt Service Routine of IIC
// when interrupt occurs, check IICSTAT, find mode and operate it
// Input : NONE
// Output : NONE
// Version : v0.1
void __irq Isr_IIC( void)
{
u32 uTemp0 = 0;
u8 cCnt;
g_cIIC_STAT = Inp32(rIICSTAT);
switch( (g_cIIC_STAT>>6)&0x3)
{
case SlaveRX :
// printf("IICSTAT = %x ",g_cIIC_STAT);
if(g_uIIC_PT<100)
{
g_PcIIC_BUFFER[g_uIIC_PT++]=Inp8(rIICDS);
Delay(100);
uTemp0 = Inp32(rIICCON);
uTemp0 &= ~(1<<4); // Clear pending bit to resume
Outp32(rIICCON,uTemp0);
break;
}
Outp8(rIICSTAT,0x0); // Stop Int
uTemp0 = Inp32(rIICCON);
uTemp0 &= ~(1<<4); // Clear pending bit to resume
Outp32(rIICCON,uTemp0);
g_cIIC_SlaveRxDone = 1;
Delay(1); // wait until Stop Condition is in effect
break;
case SlaveTX :
// printf("IICSTAT = %x ",g_cIIC_STAT);
if(g_uIIC_PT>100)
{
Outp32(rIICSTAT,0xd0); // Stop Master Tx condition, ACK flag clear
uTemp0 = Inp32(rIICCON);
uTemp0 &= ~(1<<4); // Clear pending bit to resume
Outp32(rIICCON,uTemp0);
g_cIIC_SlaveTxDone = 1;
Delay(1); // wait until Stop Condition is in effect
break;
}
Outp8(rIICDS,g_PcIIC_BUFFER[g_uIIC_PT++]);
for(cCnt=0;cCnt<10;cCnt++); // for setup time (rising edge of IICSCL)
Delay(100);
uTemp0 = Inp32(rIICCON);
uTemp0 &= ~(1<<4); // Clear pending bit to resume
Outp32(rIICCON,uTemp0);
break;
case MasterRX: if (g_uIIC_PT>0)
g_PcIIC_BUFFER[g_uIIC_PT-1] = Inp32(rIICDS);
g_uIIC_PT++;
if (g_uIIC_PT==g_uIIC_DATALEN)
{
uTemp0 = Inp32(rIICCON);
uTemp0 &= ~(1<<7); // Disable Ack generation
Outp32(rIICCON,uTemp0); // EEPROM 俊辑绰 stop 傈俊 ACK 救焊晨
}
else if (g_uIIC_PT > g_uIIC_DATALEN)
Outp32(rIICSTAT,0x90); // Stop Master Rx condition
uTemp0 = Inp32(rIICCON);
uTemp0 &= ~(1<<4); // Clear pending bit to resume
Outp32(rIICCON,uTemp0);
break;
case MasterTX: if (g_uIIC_PT<g_uIIC_DATALEN)
Outp32(rIICDS,g_PcIIC_BUFFER[g_uIIC_PT]);
else
{
Outp32(rIICSTAT,0xd0); // Stop Master Tx condition, ACK flag clear
}
g_uIIC_PT++;
uTemp0 = Inp32(rIICCON);
uTemp0 &= ~(1<<4); // Clear pending bit to resume
Outp32(rIICCON,uTemp0);
break;
}
g_cIIC_STAT &=0xf;
INTC_ClearVectAddr();
}
//////////
// Function Name : IIC_Open
// Function Description : This function Set up VIC & IICCON with user's input frequency which determines uClkValue
// Input : ufreq ufreq(Hz) = PCLK/16/uClkValue
// Output : NONE
// Version : v0.1
void IIC_Open( u32 ufreq) // Hz order. freq(Hz) = PCLK/16/clk_divider
{
u32 uSelClkSrc;
u32 uClkValue;
INTC_SetVectAddr(NUM_IIC,Isr_IIC);
INTC_Enable(NUM_IIC);
GPIO_SetFunctionEach(eGPIO_B,eGPIO_5,2);
GPIO_SetFunctionEach(eGPIO_B,eGPIO_6,2);
GPIO_SetPullUpDownEach(eGPIO_B,eGPIO_5,2);
GPIO_SetPullUpDownEach(eGPIO_B,eGPIO_6,2);
if ((((g_PCLK>>4)/ufreq)-1)>0xf)
{
uSelClkSrc = 1;
uClkValue = ((g_PCLK>>9)/ufreq) -1; // PCLK/512/freq
}
else
{
uSelClkSrc = 0;
uClkValue = ((g_PCLK>>4)/ufreq) -1; // PCLK/16/freq
}
// Prescaler IICCLK=PCLK/16, Enable interrupt, Transmit clock value Tx clock=IICCLK/16
/*
printf("g_PCLK = %d",g_PCLK);
printf("uSelClkSrc = %d",uSelClkSrc);
printf("uClkValue = %d",uClkValue);
UART_Getc();
*/
Outp32(rIICCON,(uSelClkSrc<<6) | (1<<5) | (uClkValue&0xf));
Outp32(rIICADD,0xc0); // Slave address = [7:1]
Outp32(rIICSTAT,0x10); // IIC bus data output enable(Rx/Tx)
Outp32(rIICLC,0x0); // SDA Filter enable,delayed 15clks
}
//////////
// Function Name : IIC_OpenPolling
// Function Description : This function Set up IICCON with user's input frequency which determines uClkValue
// (without ISR set up,for polling mode)
// Input : ufreq ufreq(Hz) = PCLK/16/uClkValue
// Output : NONE
// Version : v0.1
void IIC_OpenPolling( u32 ufreq) // Hz order. freq(Hz) = PCLK/16/clk_divider
{
u32 uSelClkSrc;
u32 uClkValue;
GPIO_SetFunctionEach(eGPIO_B,eGPIO_5,2);
GPIO_SetFunctionEach(eGPIO_B,eGPIO_6,2);
GPIO_SetPullUpDownEach(eGPIO_B,eGPIO_5,2);
GPIO_SetPullUpDownEach(eGPIO_B,eGPIO_6,2);
if ((((g_PCLK>>4)/ufreq)-1)>0xf)
{
uSelClkSrc = 1;
uClkValue = ((g_PCLK>>9)/ufreq) -1; // PCLK/512/freq
}
else
{
uSelClkSrc = 0;
uClkValue = ((g_PCLK>>4)/ufreq) -1; // PCLK/16/freq
}
/*
if (((g_PCLK>>4)/ufreq)>0xf)
{
uSelClkSrc = 1;
uClkValue = ((g_PCLK>>9)/ufreq) -1; // PCLK/512/freq
}
else
{
uSelClkSrc = 0;
uClkValue = ((g_PCLK>>4)/ufreq) -1; // PCLK/16/freq
}
*/
// Prescaler IICCLK=PCLK/16, Enable interrupt, Transmit clock value Tx clock=IICCLK/16
Outp32(rIICCON,(uSelClkSrc<<6) | (1<<5) | (uClkValue&0xf));
Outp32(rIICADD,0xc0); // Slave address = [7:1]
Outp32(rIICSTAT,0x10); // IIC bus data output enable(Rx/Tx)
Outp32(rIICLC,0x7); // SDA Filter disable
}
//////////
// Function Name : IIC_Close
// Function Description : This function disable IIC
// Input : NONE
// Output : NONE
// Version : v0.1
void IIC_Close(void)
{
INTC_Disable(NUM_IIC);
Outp32(rIICSTAT,0x0); // IIC bus data output disable(Rx/Tx)
GPIO_SetFunctionEach(eGPIO_B,eGPIO_5,0);
GPIO_SetFunctionEach(eGPIO_B,eGPIO_6,0);
GPIO_SetPullUpDownEach(eGPIO_B,eGPIO_5,0);
GPIO_SetPullUpDownEach(eGPIO_B,eGPIO_6,0);
}
//////////
// Function Name : IIC_SetWrite
// Function Description : This function sets up write mode with 7-bit addresses
// Input : cSlaveAddr [8bit SlaveDeviceAddress],
// pData[Data which you want to write],
// uDataLen [Data Length]
// Output : NONE
// Version : v0.1
void IIC_SetWrite( u8 cSlaveAddr, u8 *pData, u32 uDataLen)
{
u32 uTmp0;
u32 uTmp1;
uTmp0 = Inp32(rIICSTAT);
while(uTmp0&(1<<5)) // Wait until IIC bus is free.
{
uTmp0 = Inp32(rIICSTAT);
}
g_PcIIC_BUFFER = pData;
g_uIIC_PT = 0;
g_uIIC_DATALEN = uDataLen;
uTmp1 = Inp32(rIICCON);
uTmp1 |= (1<<7);
Outp32(rIICCON,uTmp1); // Ack generation Enable
Outp32(rIICDS,cSlaveAddr);
Outp32(rIICSTAT,0xf0); // Master Tx Start.
}
//////////
// Function Name : IIC_SetRead
// Function Description : This function sets up Read mode with 7-bit addresses
// Input : cSlaveAddr [8bit SlaveDeviceAddress],
// pData[Data which you want to read],
// uDataLen [Data Length]
// Output : NONE
// Version : v0.1
void IIC_SetRead( u8 cSlaveAddr, u8 *pData, u32 uDataLen)
{
u32 uTmp2;
u32 uTmp3;
uTmp2= Inp32(rIICSTAT);
while(uTmp2&(1<<5)) // Wait until IIC bus is free.
{
uTmp2 = Inp32(rIICSTAT);
}
g_PcIIC_BUFFER = pData;
g_uIIC_PT = 0;
g_uIIC_DATALEN = uDataLen;
uTmp3 = Inp32(rIICCON);
uTmp3 |= (1<<7);
Outp32(rIICCON,uTmp3); // Ack generation Enable
Outp32(rIICDS,cSlaveAddr);
Outp32(rIICSTAT,0xB0); // Master Rx Start.
}
//////////
// Function Name : IIC_Wait
// Function Description : This function waits until the command takes effect
// But not for IIC bus free
// Input : NONE
// Output : NONE
// Version : v0.1
void IIC_Wait( void) // Waiting for the command takes effect.
{ // But not for IIS bus free.
while(g_uIIC_PT<=g_uIIC_DATALEN);
}
//////////
// Function Name : IIC_Status
// Function Description : This function returns IIC Status Register value at last interrupt occur
// Input : NONE
// Output : NONE
// Version : v0.1
u8 IIC_Status( void) // Return IIC Status Register value at last interrupt occur.
{
return g_cIIC_STAT;
}
//////////
// Function Name : IIC_Write
// Function Description : This function STARTs up write mode with 7-bit addresses
// Input : cSlaveAddr [8bit SlaveDeviceAddress],
// cAddr[8bit Address where you want to write],
// pData[Data which you want to write]
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -