📄 i2c.c
字号:
#ifdef AT24C16
deviceAddr &= (~0x0f);
deviceAddr |= (wordAddrH<<1);
txPtr[0] = deviceAddr;
txPtr[1] = wordAddrL;
pChan->i2cTxBuf->statusMode = 0x3c00;
pChan->i2cTxBuf->dataLength = 0x02;
pChan->i2cTxBuf->statusMode |= 0x8000;
#else
txPtr[0] = (deviceAddr & 0xfe);
txPtr[1] = wordAddrH;
txPtr[2] = wordAddrL;
pChan->i2cTxBuf->statusMode = 0x3c00;
pChan->i2cTxBuf->dataLength = 0x03;
pChan->i2cTxBuf->statusMode |= 0x8000;
#endif
I2cStart (regBase);
while((pChan->i2cTxBuf->statusMode) & 0x8000);
if (pChan->i2cTxBuf->statusMode & 0x0007)
{
*I2CER(regBase) = 0x17;
return (ERROR);
}
intStat = *I2CER(regBase);
if (intStat & 0x10)
{
printf ("Tx error\n");
*I2CER(regBase) = 0x17;
return(ERROR);
}
*I2CER(regBase) = 0x17;
delay (EEPROM_DELAY_TIME);
#ifdef AT24C16
txPtr[0] = deviceAddr | 0x01;
#else
txPtr[0] = deviceAddr;
#endif
pChan->i2cTxBuf->statusMode = 0x3c00;
pChan->i2cTxBuf->dataLength = 2;
pChan->i2cTxBuf->statusMode |= 0x8000;
I2cStart(regBase);
while((pChan->i2cTxBuf->statusMode) & 0x8000);
if (pChan->i2cTxBuf->statusMode & 0x0007)
{
*I2CER(regBase) = 0x17;
return (ERROR);
}
intStat = *I2CER(regBase);
if (intStat & 0x10)
{
printf ("Tx error\n");
*I2CER(regBase) = 0x17;
return(ERROR);
}
*I2CER(regBase) = 0x12;
while((pChan->i2cRxBuf->statusMode) & 0x8000);
if (pChan->i2cRxBuf->statusMode & 0x02)
{
*I2CER(regBase) = 0x17;
return (ERROR);
}
intStat = *I2CER(regBase);
if ((intStat & 0x01) != 0x01) {
printf ("Rx error\n");
*I2CER(regBase) = 0x17;
return(ERROR);
}
rxPtr = pChan->i2cRxBuf->dataPointer;
*data = *rxPtr;
pChan->i2cRxBuf->statusMode = 0xb000;
pChan->i2cRxBuf->dataLength = 0x0;
delay (EEPROM_DELAY_TIME);
return(OK);
}
/**********************************************************************
* eepromSequenceRead - read some data from the eeprom
*
* RETURN: OK or ERROR
**********************************************************************/
STATUS eepromSequenceRead(UCHAR deviceAddr, UCHAR wordAddrH, UCHAR wordAddrL, char *buf, int number)
{
UCHAR intStat;
UCHAR count = 0;
u_char *txPtr;
u_char *rxPtr;
UINT32 regBase = vxImmrIsbGet();
UINT16 offset;
if (readAddrVerify(deviceAddr) == ERROR)
{
return (ERROR);
}
if ((buf == NULL) || (number <= 0) || (number > 64))
{
printf ("Illegal parameters\n");
return (ERROR);
}
offset = wordAddrH * 256 + wordAddrL;
if (offset >= EEPROM_MEM_SIZE)
{
printf ("Invalid address\n");
return (ERROR);
}
txPtr = pChan->i2cTxBuf->dataPointer;
#ifdef AT24C16
deviceAddr &= (~0x0f);
deviceAddr |= (wordAddrH<<1);
txPtr[0] = deviceAddr;
txPtr[1] = wordAddrL;
pChan->i2cTxBuf->statusMode = 0x3c00;
pChan->i2cTxBuf->dataLength = 0x02;
pChan->i2cTxBuf->statusMode |= 0x8000;
#else
txPtr[0] = (deviceAddr & 0xfe);
txPtr[1] = wordAddrH;
txPtr[2] = wordAddrL;
pChan->i2cTxBuf->statusMode = 0x3c00;
pChan->i2cTxBuf->dataLength = 0x03;
pChan->i2cTxBuf->statusMode |= 0x8000;
#endif
I2cStart (regBase);
while((pChan->i2cTxBuf->statusMode) & 0x8000);
if (pChan->i2cTxBuf->statusMode & 0x0007)
{
*I2CER(regBase) = 0x17;
return (ERROR);
}
intStat = *I2CER(regBase);
if (intStat & 0x10)
{
printf ("Tx error\n");
*I2CER(regBase) = 0x17;
return(ERROR);
}
*I2CER(regBase) = 0x17;
delay (EEPROM_DELAY_TIME);
#ifdef AT24C16
txPtr[0] = deviceAddr | 0x01;
#else
txPtr[0] = deviceAddr;
#endif
pChan->i2cTxBuf->statusMode = 0x3c00;
pChan->i2cTxBuf->dataLength = (number + 1);
pChan->i2cTxBuf->statusMode |= 0x8000;
I2cStart(regBase);
while((pChan->i2cTxBuf->statusMode) & 0x8000);
if (pChan->i2cTxBuf->statusMode & 0x0007)
{
*I2CER(regBase) = 0x17;
return (ERROR);
}
intStat = *I2CER(regBase);
if (intStat & 0x10)
{
printf ("Tx error\n");
*I2CER(regBase) = 0x17;
return(ERROR);
}
*I2CER(regBase) = 0x12;
delay (EEPROM_DELAY_TIME);
while((pChan->i2cRxBuf->statusMode) & 0x8000);
if (pChan->i2cRxBuf->statusMode & 0x02)
{
*I2CER(regBase) = 0x17;
return (ERROR);
}
intStat = *I2CER(regBase);
if ((intStat & 0x01) != 0x01) {
printf ("Rx error: intStat = %x\n", intStat);
*I2CER(regBase) = 0x17;
return(ERROR);
}
rxPtr = pChan->i2cRxBuf->dataPointer;
memcpy (buf, rxPtr, number);
pChan->i2cRxBuf->statusMode = 0xb000;
pChan->i2cRxBuf->dataLength = 0x0;
delay (EEPROM_DELAY_TIME);
return(OK);
}
/**********************************************************************
* rtcWrite - write data to DS1307
*
* Parameters:
* deviceAddr: rtc device write address. For DS1307, it is 0xd0.
* wordAddr: writting start address
* buf: user's buffer that will be written to DS1307
* number: write data number
*
* RETURN: OK or ERROR
**********************************************************************/
STATUS rtcWrite(UCHAR deviceAddr, UCHAR wordAddr, char *buf, int number)
{
u_char *txPtr;
UINT32 regBase;
UCHAR intStat;
if (writeAddrVerify(deviceAddr) == ERROR)
{
return (ERROR);
}
if ((buf == NULL) ||(number <= 0))
{
printf ("Invalid parameters\n");
return (ERROR);
}
regBase = vxImmrIsbGet();
txPtr = pChan->i2cTxBuf->dataPointer;
txPtr[0] = deviceAddr;
txPtr[1] = wordAddr;
memcpy((txPtr+2), buf, number);
pChan->i2cTxBuf->statusMode = 0x3c00;
pChan->i2cTxBuf->dataLength = (number + 2);
pChan->i2cTxBuf->statusMode |= 0x8000;
I2cStart(regBase);
while((pChan->i2cTxBuf->statusMode) & 0x8000);
if (pChan->i2cTxBuf->statusMode & 0x0007)
{
*I2CER(regBase) = 0x17;
return (ERROR);
}
intStat = *I2CER(regBase);
if(intStat & 0x10)
{
printf ("Tx error\n");
*I2CER(regBase) = 0x17;
return(ERROR);
}
*I2CER(regBase) = 0x17;
delay (RTC_DELAY_TIME);
return(OK);
}
/**********************************************************************
* rtcRead - read data from DS1307
*
* Parameters:
* deviceAddr: rtc device read address. For DS1307, it is 0xd1.
* wordAddr: the start address that be read from DS1307
* buf: user buffer that use to save data that be read from DS1307
* number: data number that will read from DS1307
*
* RETURN: OK or ERROR
**********************************************************************/
STATUS rtcRead(UCHAR deviceAddr, UCHAR wordAddr, char *buf, int number)
{
UCHAR deviceAddrWr;
u_char *txPtr;
UCHAR *rxPtr;
UINT32 regBase;
UCHAR len;
UCHAR intStat;
if(readAddrVerify(deviceAddr) == ERROR)
{
return(ERROR);
}
if((buf == NULL) || (number <= 0))
{
printf ("Invalid parameters\n");
return(ERROR);
}
regBase = vxImmrIsbGet();
txPtr = pChan->i2cTxBuf->dataPointer;
txPtr[0] = (deviceAddr & 0xfe);
txPtr[1] = wordAddr;
pChan->i2cTxBuf->statusMode = 0x3c00;
pChan->i2cTxBuf->dataLength = 2;
pChan->i2cTxBuf->statusMode |= 0x8000;
I2cStart(regBase);
while((pChan->i2cTxBuf->statusMode) & 0x8000);
if (pChan->i2cTxBuf->statusMode & 0x0007)
{
*I2CER(regBase) = 0x17;
return (ERROR);
}
intStat = *I2CER(regBase);
if(intStat & 0x10)
{
printf ("Tx error\n");
*I2CER(regBase) = 0x17;
return(ERROR);
}
*I2CER(regBase) = 0x17;
delay (RTC_DELAY_TIME);
txPtr[0] = deviceAddr;
pChan->i2cTxBuf->statusMode = 0x3c00;
pChan->i2cTxBuf->dataLength = (number + 1);
pChan->i2cTxBuf->statusMode |= 0x8000;
I2cStart(regBase);
while((pChan->i2cTxBuf->statusMode) & 0x8000);
intStat = *I2CER(regBase);
if(intStat & 0x10){
*I2CER(regBase) = 0x12;
return(ERROR);
}
delay (RTC_DELAY_TIME);
while((pChan->i2cRxBuf->statusMode) & 0x8000);
intStat = *I2CER(regBase);
if ((intStat & 0x01) != 0x01) {
*I2CER(regBase) = 0x17;
return(ERROR);
}
rxPtr = pChan->i2cRxBuf->dataPointer;
len = pChan->i2cRxBuf->dataLength;
memcpy(buf, rxPtr, len);
pChan->i2cRxBuf->statusMode = 0xb000;
pChan->i2cRxBuf->dataLength = 0x0;
delay (RTC_DELAY_TIME);
return(OK);
}
/**********************************************************************
* rtcInit - initialize the DS1307
*
* Initialize the DS1307 to 24 hours mode and enable oscillator.
*
* RETURN: OK or ERROR
**********************************************************************/
STATUS rtcInit(void)
{
UCHAR seconds;
UCHAR hours;
/* enable the oscillator */
if(rtcRead(0xd1, 0x00, &seconds, 1) == ERROR)
{
printf("cannot get the seconds!\n");
return(ERROR);
}
if(seconds & 0x80)
{
seconds = seconds & 0x7f;
if(rtcWrite(0xd0, 0x00, &seconds, 1) == ERROR)
{
printf("cannot enable the oscillator!\n");
return(ERROR);
}
}
/* enable 24 hours mode */
if(rtcRead(0xd1, 0x02, &hours, 1) == ERROR)
{
printf("cannot get the hours mode!\n");
return(ERROR);
}
if(hours & 0x40)
{
hours = hours & 0xbf;
if(rtcWrite(0xd0, 0x02, &hours, 1) == ERROR)
{
printf("cannot set the 24 hours mode!\n");
return(ERROR);
}
}
return(OK);
}
/**********************************************************************
* rtcTimeGet - get the real time from DS1307
*
* User can use this function to get the real time from DS1307.
*
* RETURN: OK or ERROR
**********************************************************************/
STATUS rtcTimeGet(RTC_TIME *rtcTime)
{
RTC_REGS rtcRegs;
if(rtcRead(0xd1, 0x00, (char *) &rtcRegs, sizeof(RTC_REGS)) == ERROR)
{
printf("cannot get the rtc time!\n");
return(ERROR);
}
rtcTime->seconds = ((rtcRegs.secondReg & 0x0f) + ((rtcRegs.secondReg & 0x70) >> 0x04) * 10);
rtcTime->minutes = ((rtcRegs.minuteReg & 0x0f) + ((rtcRegs.minuteReg & 0x70) >> 0x04) * 10);
rtcTime->hours = ((rtcRegs.hourReg & 0x0f) + ((rtcRegs.hourReg & 0x30) >> 0x04) * 10);
rtcTime->day = rtcRegs.dayReg ;
rtcTime->date = ((rtcRegs.dateReg & 0x0f) + ((rtcRegs.dateReg & 0x30) >> 0x04) * 10);
rtcTime->month = ((rtcRegs.monthReg & 0x0f) + ((rtcRegs.monthReg & 0x10) >> 0x04) * 10);
rtcTime->year = ((rtcRegs.yearReg & 0x0f) + ((rtcRegs.yearReg & 0xf0) >> 0x04) * 10);
return(OK);
}
/**********************************************************************
* rtcTimeSet - set the DS1307's time
*
* After getting the correct system time from GPS or network, user can
* use this function to set DS1307 to correct time.
*
* RETURN: OK or ERROR
**********************************************************************/
STATUS rtcTimeSet(RTC_TIME *rtcTime)
{
RTC_REGS rtcRegs;
UCHAR seconds;
UCHAR minutes;
UCHAR hours;
UCHAR day;
UCHAR date;
UCHAR month;
UCHAR year;
seconds = rtcTime->seconds;
minutes = rtcTime->minutes;
hours = rtcTime -> hours;
day = rtcTime->day;
date = rtcTime->date;
month = rtcTime->month;
year = rtcTime->year;
if ((seconds < 0) ||(seconds > 59))
{
printf("seconds is out of range, it should be a value between 0 and 59!\n");
return(ERROR);
}
if ((minutes < 0) || (minutes > 59))
{
printf("minutes is out of range, it should be a value between 0 and 59!\n");
return(ERROR);
}
if ((hours < 0) || (hours > 23))
{
printf("hours is out of range, it should be a value between 0 and 23!\n");
return(ERROR);
}
if ((day < 1) || (day > 7))
{
printf("day is out of range, it should be a value between 1 and 7!\n");
return(ERROR);
}
if ((date < 1) || (date > 31))
{
printf("date is out of range, it should be a value between 1 and 31!\n");
return(ERROR);
}
if ((month < 1) || (month > 12))
{
printf("month is out of range, it should be a value between 1 and 12!\n");
return(ERROR);
}
if ((year < 0) || (year > 99))
{
printf("year is out of range, it should be a value between 0 and 99!\n");
return(ERROR);
}
rtcRegs.secondReg = ((seconds /10) << 4) + seconds % 10;
rtcRegs.minuteReg = ((minutes /10) << 4) + minutes % 10;
rtcRegs.hourReg = ((hours /10) << 4) + hours % 10;
rtcRegs.dayReg = day;
rtcRegs.dateReg = ((date /10) << 4) + date % 10;
rtcRegs.monthReg = ((month /10) << 4) + month % 10;
rtcRegs.yearReg = ((year /10) << 4) + year % 10;
if(rtcWrite(0xd0, 0x00, (char *) &rtcRegs, sizeof(RTC_REGS)) == ERROR)
{
printf("cannot set the rtc time!\n");
return(ERROR);
}
return(OK);
}
void delay(int n)
{
int i;
for (i=0; i<n; i++)
{
asm("nop");
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -