📄 2410iic.c
字号:
#include <string.h>
#include "2410addr.h"
#include "2410lib.h"
#include "def.h"
#include "2410IIC.h"
#define ZLG7290_SLA_ADD 0x70 //the slave address of ZLG7290:ic which drivers leds.
#define LED_SLA_ADD 0x70 //another name of the slave address
#define LED_MAJOR 100 //the major device number of led
#define TIME_TURN 0 //turn to display time
#define DATE_TURN 1 //turn to display date
#define IICCON_PEND_INT_CLEAR (1 << 4)
#define IICCON_PEND_INT_STATU (1 << 4)
static U8 _iicData[IICBUFSIZE];
static volatile int _iicDataCount;
static volatile int _iicStatus;
static volatile int _iicMode;
static int _iicPt;
//buffers for 8 leds:
//..[0]: the zlg790's slave address
//..[1]: the commad buffer's address of zlg7290
//..[2]: the first command
//..[3]: the second command
//..[4]: the end symbol
signed char sec_buf_l[5]={LED_SLA_ADD,0x07,0x63,-1,-1};
signed char sec_buf_h[5]={LED_SLA_ADD,0x07,0x62,-1,-1};
signed char blank_buf_l[5]={LED_SLA_ADD,0X07,0X61,0x1f,-1};
signed char min_buf_l[5]={LED_SLA_ADD,0x07,0x60,-1,-1};
signed char min_buf_h[5]={LED_SLA_ADD,0x07,0x67,-1,-1};
signed char blank_buf_h[5]={LED_SLA_ADD,0X07,0X66,0x1f,-1};
signed char hour_buf_l[5]={LED_SLA_ADD,0x07,0x65,-1,-1};
signed char hour_buf_h[5]={LED_SLA_ADD,0x07,0x64,-1,-1};
//buffers for 8 leds:
signed char date_buf_l[5]={LED_SLA_ADD,0x07,0x63,-1,-1};
signed char date_buf_h[5]={LED_SLA_ADD,0x07,0x62,-1,-1};
signed char mon_buf_l[5]={LED_SLA_ADD,0x07,0x61,-1,-1};
signed char mon_buf_h[5]={LED_SLA_ADD,0x07,0x60,-1,-1};
signed char year_buf_0[5]={LED_SLA_ADD,0x07,0x64,2,-1};
signed char year_buf_1[5]={LED_SLA_ADD,0x07,0x65,0,-1};
signed char year_buf_2[5]={LED_SLA_ADD,0x07,0x66,-1,-1};
signed char year_buf_3[5]={LED_SLA_ADD,0x07,0x67,-1,-1};
int date_time_turn = TIME_TURN; //turn to display time first
signed int date_s = 0; //the seconds how long date has been displayed
signed int time_s = 0; //the seconds how long time has been displayed
//time structure
static struct my_time{
char second;
char minute;
char hour;
char date;
char month;
char year;
}led_time;
/*
* write the cpu's rtc!
* you can change the time and date
*/
static void led_set_time(void)
{
rRTCCON = 0X01; //get the right to write rtc
rBCDYEAR = 0x04; //2004.9.26 11:49:30
rBCDMON = 0x09;
rBCDDATE = 0x26;
rBCDHOUR = 0x11;
rBCDMIN = 0x49;
rBCDSEC = 0x30;
rRTCCON = 0X00; //free the right to write rtc
}
/*
* get the date and time from rtc
*/
static void led_get_time(struct my_time *tempt)
{
tempt->second = rBCDSEC;
tempt->minute = rBCDMIN;
tempt->hour = rBCDHOUR;
tempt->date = rBCDDATE;
tempt->month = rBCDMON;
tempt->year = rBCDYEAR;
}
/*
* get the correct format of the time and date
* see the cpu 2410's doc for more details of the RTC registers
*/
static void led_time_format(struct my_time *tempt)
{
sec_buf_l[3] = (tempt->second & 0x0f);
sec_buf_h[3] = (tempt->second & 0x70) >> 4;
min_buf_l[3] = (tempt->minute & 0x0f) | 0x80;
min_buf_h[3] = (tempt->minute & 0x70) >> 4;
hour_buf_l[3] = (tempt->hour & 0x0f) |0x80;
hour_buf_h[3] = (tempt->hour & 0x30) >> 4;
date_buf_l[3] = (tempt->date & 0x0f);
date_buf_h[3] = (tempt->date & 0x30) >> 4;
mon_buf_l[3] = (tempt->month & 0x0f) | 0x80;
mon_buf_h[3] = (tempt->month & 0x10) >> 4;
year_buf_2[3] = (tempt->year) / 10;
year_buf_3[3]= (tempt->year) % 10 | 0x80;
}
/*
* send command to zlg7290
*/
static int led_send_cmd(signed char *data)
{
signed char *temp = data;
if (*temp == -1) //nothing to send!
return 0;
rIICDS = *temp; //store the slave device address!
rIICSTAT = 0xF0; //START SEND
temp++;
while (*temp != -1)
{
while (!(rIICCON & IICCON_PEND_INT_STATU)); //WAIT UNTIL TRANSFERS ENDED!
rIICDS = *temp; //put new command into it to be sended!
rIICCON &= ~IICCON_PEND_INT_CLEAR; //A NEW TRANSFERS
temp++;
}
while (!(rIICCON & IICCON_PEND_INT_STATU));
rIICSTAT = 0xD0;//STOP IIC
rIICCON &= ~IICCON_PEND_INT_CLEAR;//CLEAR PENDING INT
Delay(5); //delay needed before another transfers
return 1;
}
//===================================================================
// SMDK2410 IIC configuration
// GPE15=IICSDA, GPE14=IICSCL
// "Interrupt mode" for IIC block
//===================================================================
//******************[ Test_Iic ]**************************************
void Test_Iic(void)
{
unsigned int i,j,save_E,save_PE;
static U8 data[256];
Uart_Printf("[ IIC Test(Interrupt) using KS24C080 ]\n");
save_E = rGPECON;
save_PE = rGPEUP;
rGPEUP |= 0xc000; //Pull-up disable
rGPECON |= 0xa00000; //GPE15:IICSDA , GPE14:IICSCL
pISR_IIC = (unsigned)IicInt;
rINTMSK &= ~(BIT_IIC);
//Enable ACK, Prescaler IICCLK=PCLK/16, Enable interrupt, Transmit clock value Tx clock=IICCLK/16
// If PCLK 50.7MHz, IICCLK = 3.17MHz, Tx Clock = 0.198MHz
rIICCON = (1<<7) | (0<<6) | (1<<5) | (0xf);
rIICADD = 0x10; //2410 slave address = [7:1]
rIICSTAT = 0x10; //IIC bus data output enable(Rx/Tx)
Uart_Printf("Write test data into KS24C080\n");
for(i=0;i<256;i++)
Wr24C080(0xa0,(U8)i,i);
for(i=0;i<256;i++)
data[i] = 0;
Uart_Printf("Read test data from KS24C080\n");
for(i=0;i<256;i++)
Rd24C080(0xa0,(U8)i,&(data[i]));
//Line changed 0 ~ f
for(i=0;i<16;i++)
{
for(j=0;j<16;j++)
Uart_Printf("%2x ",data[i*16+j]);
Uart_Printf("\n");
}
rINTMSK |= BIT_IIC;
rGPEUP = save_PE;
rGPECON = save_E;
}
//*************************[ Wr24C080 ]****************************
void Wr24C080(U32 slvAddr,U32 addr,U8 data)
{
_iicMode = WRDATA;
_iicPt = 0;
_iicData[0] = (U8)addr;
_iicData[1] = data;
_iicDataCount = 2;
rIICDS = slvAddr; //0xa0
rIICSTAT = 0xf0; //MasTx,Start
//Clearing the pending bit isn't needed because the pending bit has been cleared.
while(_iicDataCount!=-1);
_iicMode = POLLACK;
while(1)
{
rIICDS = slvAddr;
_iicStatus = 0x100;
rIICSTAT = 0xf0; //MasTx,Start
rIICCON = 0xaf; //Resumes IIC operation.
while(_iicStatus==0x100);
if(!(_iicStatus&0x1))
break; //When ACK is received
}
rIICSTAT = 0xd0; //Stop MasTx condition
rIICCON = 0xaf; //Resumes IIC operation.
Delay(1); //Wait until stop condtion is in effect.
//Write is completed.
}
//**********************[ Rd24C080 ] ***********************************
void Rd24C080(U32 slvAddr,U32 addr,U8 *data)
{
_iicMode = SETRDADDR;
_iicPt = 0;
_iicData[0] = (U8)addr;
_iicDataCount = 1;
rIICDS = slvAddr;
rIICSTAT = 0xf0; //MasTx,Start
//Clearing the pending bit isn't needed because the pending bit has been cleared.
while(_iicDataCount!=-1);
_iicMode = RDDATA;
_iicPt = 0;
_iicDataCount = 1;
rIICDS = slvAddr;
rIICSTAT = 0xb0; //MasRx,Start
rIICCON = 0xaf; //Resumes IIC operation.
while(_iicDataCount!=-1);
*data = _iicData[1];
}
//-------------------------------------------------------------------------
void __irq IicInt(void)
{
U32 iicSt,i;
rSRCPND = BIT_IIC; //Clear pending bit
rINTPND = BIT_IIC;
iicSt = rIICSTAT;
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 POLLACK:
_iicStatus = iicSt;
break;
case RDDATA:
if((_iicDataCount--)==0)
{
_iicData[_iicPt++] = rIICDS;
rIICSTAT = 0x90; //Stop MasRx condition
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -