📄 iic.c
字号:
/*************************************************************************/
/* */
/* FILE NAME VERSION */
/* */
/* iic.c KS32C50100 : version 1.0 */
/* */
/* COMPONENT */
/* */
/* */
/* DESCRIPTION */
/* */
/* I2C control function library for SNDS100 evaluation board. */
/* */
/* AUTHOR */
/* */
/* */
/* DATA STRUCTURES */
/* */
/* */
/* FUNCTIONS */
/* */
/* */
/* DEPENDENCIES */
/* */
/* */
/* HISTORY */
/* */
/*************************************************************************/
#include <math.h>
#include "std.h"
#include "apdialog.h"
#include "snds.h"
#include "uart.h"
#include "isr.h"
#include "memory.h"
#include "pollio.h"
#include "iic.h"
#include "sysconf.h"
IIC_DATA_TX_FORMAT iic_txmit;
IIC_DATA_RX_FORMAT iic_recv;
/******************************************************************
* *
* IIC SETUP ROUTINE *
* *
******************************************************************/
void IicSetup(void)
{
// Reset IIC Controller
IICCON = IICRESET;
// Set Prescale Value: fSCL is IIC serial clock frequency
// fSCL defined at sysconf.h
IICPS = SetPreScaler((int)fSCL); //support upto 100KHz
}
/******************************************************************
* *
* SETUP IIC PRESCALER VALUE FROM SERIAL CLOCK FREQUENCY *
* *
******************************************************************/
int SetPreScaler(int sclk)
{
return((int)(((fMCLK/sclk)-3.0)/16.0)-0.5); //add 0.5 for
}
/******************************************************************
* *
* IIC INTERRUPT SERVICE ROUTINES *
* *
******************************************************************/
void IICWriteIsr(void)
{
if(!(iic_txmit.FLAG & (U32)iic_byte_addr_msb)) {
/* Send byte address: MSB */
IICBUF = iic_txmit.BYTE_ADDR_MSB;
iic_txmit.FLAG |= (U32)iic_byte_addr_msb;
}
else if(!(iic_txmit.FLAG & (U32)iic_byte_addr_lsb)) {
/* Send byte address: LSB */
IICBUF = iic_txmit.BYTE_ADDR_LSB;
iic_txmit.FLAG |= (U32)iic_byte_addr_lsb;
}
else if(iic_txmit.BuffByteCnt < iic_txmit.WriteDataSize) {
IICBUF = iic_txmit.PAGE_BUFFER[iic_txmit.BuffByteCnt++];
}
else {
/* STOP IIC Controller */
IICCON = STOP;
/* byte data or page data transmit done */
iic_txmit.FLAG |= (U32)iic_page_tx_done;
}
}
void IICReadIsr(void)
{
if(!(iic_recv.FLAG & (U32)iic_byte_addr_msb)) {
//else if(!(iic_recv.FLAG & (U32)iic_byte_addr_msb)) {
/* Send byte address: MSB */
IICBUF = iic_recv.BYTE_ADDR_MSB;
iic_recv.FLAG |= (U32)iic_byte_addr_msb; /* send msb byte addr */
}
else if(!(iic_recv.FLAG & (U32)iic_byte_addr_lsb)) {
/* Send byte address: LSB */
IICBUF = iic_recv.BYTE_ADDR_LSB;
iic_recv.FLAG |= (U32)iic_byte_addr_lsb; /* send lsb byte addr */
}
else if(!(iic_recv.FLAG & (U32)iic_repeat_start)) {
/* Repeat Start */
IICCON = RESTART;
IICCON = START|ACK|IEN;
IICBUF = iic_recv.SLAVE_ADDR|S_READ;
iic_recv.FLAG |= (U32)iic_repeat_start;
}
else if(!(iic_recv.FLAG & (U32)iic_multi_recv)) {
/* Receive multiple data */
IICCON = ACK|IEN;
iic_recv.FLAG |= (U32)iic_multi_recv;
}
else if(iic_recv.ByteReadCnt < iic_recv.ReadDataSize) {
*(iic_recv.RCV_BUFFER)++ = IICBUF;
iic_recv.ByteReadCnt++;
}
else if(!(iic_recv.FLAG & (U32)iic_no_more_recv)) {
/* Now,no more received data is required from slave */
IICCON = NOACK|IEN;
iic_recv.FLAG |= (U32)iic_no_more_recv;
}
else { /* Receive last data and STOP */
*(iic_recv.RCV_BUFFER)++ = IICBUF;
/* STOP IIC Controller */
IICCON = STOP;
/* byte data receive done */
iic_recv.FLAG |= (U32)iic_byte_rx_done;
}
}
/******************************************************************
* *
* LIBRARY FUNCTIONS FOR IIC READ & WRITE *
* KS24C32/64 : IIC Serial EEPROM *
* *
******************************************************************/
void IICWriteInt(U8 SlaveAddr,U32 WriteAddr,U8 *data,U32 SizeOfData)
{
int page,j;
int no_of_page; /* Number of page */
int remain_byte;
U32 PageAccessAddr;
//SysSetInterrupt(nIIC_INT,IICWriteIsr) ; /*Setup IIC Tx interrupt */
//Enable_Int(nIIC_INT) ;
PageAccessAddr = WriteAddr;
iic_txmit.SLAVE_ADDR = SlaveAddr;
no_of_page = (int)(ceil(SizeOfData/(U32)SizeOfPage));
remain_byte = (int)(SizeOfData%(U32)SizeOfPage);
for(page=0; page <= no_of_page;page++)
{
if(SizeOfData < SizeOfPage) {
for(j=0; j < SizeOfData; j++)
iic_txmit.PAGE_BUFFER[j] = *data++;
iic_txmit.WriteDataSize = SizeOfData;
}
else {
if(page == no_of_page) {
for(j=0; j < remain_byte; j++)
iic_txmit.PAGE_BUFFER[j] = *data++;
iic_txmit.WriteDataSize = remain_byte;
}
else {
for(j=0; j < SizeOfPage; j++)
iic_txmit.PAGE_BUFFER[j] = *data++;
iic_txmit.WriteDataSize = SizeOfPage;
}
}
IicSetup();
iic_txmit.FLAG = 0x0;
iic_txmit.BuffByteCnt = 0x0;
iic_txmit.BYTE_ADDR_MSB = (U8)((PageAccessAddr>>8) & 0xff);
iic_txmit.BYTE_ADDR_LSB = (U8)(PageAccessAddr & 0xff);
/* Step 1: Setup IICON register for transmit start */
while(IICCON & BUSY); /* Wait! the iic bus is busy */
IICCON = START|ACK|IEN; /* Now, Start to transmit */
/* Send Slave Address and Write command */
IICBUF = iic_txmit.SLAVE_ADDR|S_WRITE;
while(!(iic_txmit.FLAG & iic_page_tx_done));
PageAccessAddr += SizeOfPage;
for(j=0; j< (int)Write_Cycle_ms(5); j++); /* for 5ms write cycle */
}
}
void *IICReadInt(U8 SlaveAddr,U32 ReadAddr,U32 SizeOfData)
{
U8 *ReadPtr; /* data read pointer */
IicSetup();
SysSetInterrupt(nIIC_INT,IICReadIsr) ; /*Setup IIC Tx interrupt */
Enable_Int(nIIC_INT) ;
/*Memory alloc for receive data */
if((ReadPtr = (U8 *)malloc((unsigned)SizeOfData)) == (U8 *)(NULL))
Print("\rMemory allocation error occurred!!!\r");
iic_recv.RCV_BUFFER = ReadPtr;
iic_recv.FLAG = 0x0;
iic_recv.ByteReadCnt = 0x0;
iic_recv.ReadDataSize = SizeOfData;
iic_recv.SLAVE_ADDR = SlaveAddr;
iic_recv.BYTE_ADDR_MSB = (U8)((ReadAddr>>8) & 0xff);
iic_recv.BYTE_ADDR_LSB = (U8)(ReadAddr & 0xff);
/* Step 1: Setup IICON register for receive start */
while(IICCON & BUSY); /* Wait! the iic bus is busy */
IICCON = START|ACK|IEN;
/* Send Slave Address and Write command */
IICBUF = iic_recv.SLAVE_ADDR|S_WRITE;
while(!(iic_recv.FLAG & iic_byte_rx_done));
return(ReadPtr); /* return receive data pointer */
}
void IICWrite(U32 WriteAddr,U8 data,U32 SizeOfData)
{
//while(IICCON & BUSY); /* Wait! the iic bus is busy */
IICCON = START&ACK;
IICBUF = WriteAddr|S_WRITE;
while(!(IICCON &01));
IICBUF=data;
while(!(IICCON &01));
IICCON = STOP;
}
char IICRead(U32 ReadAddr,U32 SizeOfData)
{
char i;
while(IICCON & BUSY); /* Wait! the iic bus is busy */
IICCON = START|ACK; /* Now, Start to transmit */
IICBUF=0x0|S_WRITE;
while(!(IICCON &01));
IICCON = RESTART;
IICCON = START|ACK;
IICBUF = S_READ;
while(!(IICCON &01)); /* Wait! the iic bus is busy */
i=IICBUF;
IICCON = STOP;
return i;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -