dc550_i2cdriver.c
来自「一款经典的数字电话设计资料」· C语言 代码 · 共 947 行 · 第 1/2 页
C
947 行
rtcData.rtcMsg[5][0] = RTC_YEARDATE_ADDR;
rtcData.rtcMsg[5][1] = (unsigned char)(date & 0x3F) |
(unsigned char)((year << 6) & 0xC0);
rtcData.rtcMsg[6][0] = RTC_DOWMONTH_ADDR;
rtcData.rtcMsg[6][1] = (unsigned char)(month & 0x1F) |
(unsigned char)((dayOfWeek << 5) & 0xE0);
rtcData.rtcMsg[7][0] = RTC_ALARMCTRL_ADDR;
rtcData.rtcMsg[7][1] = RTC_ALARMCTRL_OFF;
rtcData.rtcMsg[8][0] = RTC_CONTROL_ADDR;
rtcData.rtcMsg[8][1] = RTC_CONTROL_RUN;
rtcData.Index = 0;
rtcData.LastIndex = 8;
rtcData.UpdateClock = TRUE;
return 1;
}
int rtc_GetTimeOfDay( int *year,
int *month,
int *date,
int *hour,
int *minutes,
int *seconds,
int *dayOfWeek)
{
if (seconds)
*seconds = (int)(rtcData.TOD[0]);
if (minutes)
*minutes = (int)(rtcData.TOD[1]);
if (hour)
*hour = (int)(rtcData.TOD[2]);
if (year)
*year = (int)((rtcData.TOD[3] >> 6) & 0x3);
if (date)
*date = (int)(rtcData.TOD[3] & 0x3F);
if (dayOfWeek)
*dayOfWeek = (int)((rtcData.TOD[4] >> 5) & 0x7);
if (month)
*month = (int)(rtcData.TOD[4] & 0x1F);
return 1;
}
/******************************************************************************
DTMF CHIP INTERFACE ROUTINES
*****************************************************************************/
/*
030321 Modification:
static int dtmf_WriteByte(unsigned char val)
{
i2c_StartBit(DTMF);
if (!i2c_AddressSlave(DTMF, FALSE)) {
i2c_StopBit(DTMF);
return 0;
}
i2c_WriteByte(DTMF, val);
i2c_StopBit(DTMF);
return 1;
}
void dtmf_PlayTone(unsigned char val)
{
dtmfData.Tone = val;
dtmfData.Request = TRUE;
}
*/
/******************************************************************************
EEPROM INTERFACE ROUTINES
*****************************************************************************/
/*
* Note: All of the eeprom_Write* and eeprom_Read* functions happen
* immediately, whereas the eeprom_Get* and eeprom_Set* functions are
* simply memory manipulations. The magic number for waiting between
* write instructions seems to be 4 milliseconds (3.6 milliseconds works)
*/
int eeprom_SetNumber(int address, unsigned char* number, int length)
{
// Declare function variables
int i;
int j;
// dc550_printf("\r\nSaving: %s", number);
// If there is space, schedule writing value into EEPROM
if((eepromData.numberOfMessages + length) < EEPROM_ARRAY_SIZE) {
i = (eepromData.beginIndex + eepromData.numberOfMessages) &
EEPROM_ARRAY_MASK;
for(j = 0; j < length; j++) {
eepromData.address[i] = address + j;
eepromData.value[i] = number[j];
eepromData.numberOfMessages++;
i = ((i + 1) & EEPROM_ARRAY_MASK);
}
return 1;
}
// Otherwise, return 0
else
return 0;
}
int eeprom_SetSetting(int address, unsigned char value)
{
// Declare function variables
int i;
// If there is space, schedule writing value into EEPROM
if((eepromData.numberOfMessages + 1) < EEPROM_ARRAY_SIZE) {
i = (eepromData.beginIndex + eepromData.numberOfMessages) &
EEPROM_ARRAY_MASK;
eepromData.address[i] = address;
eepromData.value[i] = value;
eepromData.numberOfMessages++;
return 1;
}
// Otherwise, return 0
else
return 0;
}
int eeprom_SetVersion(unsigned char version)
{
// Declare function variables
int i;
// If there is space, schedule writing version and version inverse into
// EEPROM, and reset the eepromData.eepromVersion variable
if((eepromData.numberOfMessages + 1) < EEPROM_ARRAY_SIZE) {
i = (eepromData.beginIndex + eepromData.numberOfMessages) &
EEPROM_ARRAY_MASK;
eepromData.address[i] = EEPROM_ADDRESS_VERSION;
eepromData.value[i] = version;
eepromData.numberOfMessages++;
i = (eepromData.beginIndex + eepromData.numberOfMessages) &
EEPROM_ARRAY_MASK;
eepromData.address[i] = EEPROM_ADDRESS_VERSIONINVERSE;
eepromData.value[i] = ~version;
eepromData.numberOfMessages++;
eepromData.eepromVersion = version;
return 1;
}
// Otherwise, return 0
else
return 0;
}
unsigned char eeprom_GetVersion(void)
{
return eepromData.eepromVersion;
}
int eeprom_WriteArray(int address, unsigned char* array, int arraysize)
{
// Declare function variables
int i;
int j;
for(j = 0; j < arraysize; j++) {
for(i = 0; i < 4000; i++); // Wait 4ms (a write takes over 3ms)
if( eeprom_WriteByte(address + j, array[j]) == 0)
return 0;
}
return 1;
}
int eeprom_ReadArray(int address, unsigned char* array, int arraysize)
{
// Declare function variables
int i;
int j;
for(j = 0; j < arraysize; j++) {
for(i = 0; i < 4000; i++); // Wait 4ms (a write takes over 3ms)
if( eeprom_ReadByte(address + j, &array[j]) == 0)
return 0;
}
return 1;
}
int eeprom_WriteByte(int addr, unsigned char val)
{
i2c_StartBit(EEPROM);
if (!i2c_AddressSlave(EEPROM, FALSE)) {
i2c_StopBit(EEPROM);
return 0;
}
i2c_WriteByte(EEPROM, (addr >> 8) & 0xFF );
i2c_WriteByte(EEPROM, (addr & 0xFF));
i2c_WriteByte(EEPROM, val);
i2c_StopBit(EEPROM);
return 1;
}
int eeprom_ReadByte(int addr, unsigned char *val)
{
i2c_StartBit(EEPROM);
if (!i2c_AddressSlave(EEPROM, FALSE)) {
i2c_StopBit(EEPROM);
return 0;
}
i2c_WriteByte(EEPROM, (addr >> 8) & 0xFF );
i2c_WriteByte(EEPROM, (addr & 0xFF));
i2c_StartBit(EEPROM);
if (!i2c_AddressSlave(EEPROM, TRUE)) {
i2c_StopBit(EEPROM);
return 0;
}
i2c_ReadByte(EEPROM, val, TRUE);
i2c_StopBit(EEPROM);
return 1;
}
/******************************************************************************
DIGPOT INTERFACE ROUTINES
*****************************************************************************/
#define DIGPOT_WRITEDATA_CMD 0x10
void digpot_Volume(unsigned char val)
{
if (val > 15) val = 15;
digpotData.VolumeSetting = digpotData.VolumeLevels[val];
digpotData.VolumeRequest = TRUE;
}
void digpot_Contrast(unsigned char val)
{
if (val > 15) val = 15;
digpotData.ContrastSetting = digpotData.ContrastLevels[val];
digpotData.ContrastRequest = TRUE;
}
int digpot_WriteByte(DIGPOT_ID potId, int value)
{
i2c_StartBit(DIGPOT);
i2c_WriteByte(DIGPOT, ((DIGPOT_WRITEDATA_CMD+potId) & 0xff) );
i2c_WriteByte(DIGPOT, value);
i2c_StopBit(DIGPOT);
return 1;
}
/******************************************************************************
* FUNCTION: void i2cdriver_init(void)
******************************************************************************
* DESCRIPTION:
* This function is called during the initialization phase to initialize all
* of the i2c driver variables.
*****************************************************************************/
void i2cdriver_init(void)
{
int i;
unsigned char inverse;
// Set up clock and data lines to be outputs and to be high
I2C_POUT |= (I2C_CLOCK_MSK | I2C_DATA_MSK);
I2C_PDIR |= (I2C_CLOCK_MSK | I2C_DATA_MSK);
i2cData.i2cMaster = IDLE;
rtcData.UpdateClock = FALSE;
// 030321: dtmfData.Request = FALSE;
digpotData.VolumeRequest = FALSE;
digpotData.ContrastRequest = FALSE;
// 030321: dtmf_PlayTone(DTMF_OFF);
// Initialize volume/contrast values for the digital pot
digpotData.ContrastLevels[0] = 218;
digpotData.ContrastLevels[1] = 214;
digpotData.ContrastLevels[2] = 210;
digpotData.ContrastLevels[3] = 206;
digpotData.ContrastLevels[4] = 202;
digpotData.ContrastLevels[5] = 198;
digpotData.ContrastLevels[6] = 194;
digpotData.ContrastLevels[7] = 190;
digpotData.ContrastLevels[8] = 186;
digpotData.ContrastLevels[9] = 182;
digpotData.ContrastLevels[10] = 178;
digpotData.ContrastLevels[11] = 174;
digpotData.ContrastLevels[12] = 170;
digpotData.ContrastLevels[13] = 166;
digpotData.ContrastLevels[14] = 162;
digpotData.ContrastLevels[15] = 158;
digpotData.VolumeLevels[0] = 136;
digpotData.VolumeLevels[1] = 143;
digpotData.VolumeLevels[2] = 150;
digpotData.VolumeLevels[3] = 157;
digpotData.VolumeLevels[4] = 164;
digpotData.VolumeLevels[5] = 171;
digpotData.VolumeLevels[6] = 178;
digpotData.VolumeLevels[7] = 186;
digpotData.VolumeLevels[8] = 193;
digpotData.VolumeLevels[9] = 200;
digpotData.VolumeLevels[10] = 207;
digpotData.VolumeLevels[11] = 214;
digpotData.VolumeLevels[12] = 221;
digpotData.VolumeLevels[13] = 228;
digpotData.VolumeLevels[14] = 235;
digpotData.VolumeLevels[15] = 242;
// Initialize digital pot
digpot_WriteByte(VOLUME_POT, digpotData.VolumeLevels[0]);
digpot_WriteByte(CONTRAST_POT, digpotData.ContrastLevels[0]);
// Just powering-up: set time/date to *something*
memset(rtcData.TOD, 0, sizeof(rtcData.TOD));
rtc_SetTimeOfDay(0, 1, 1, 0, 0, 0, 0);
// Initialize EEPROM Variables
eepromData.beginIndex = 0;
eepromData.numberOfMessages = 0;
// Get EEPROM Version Number
eeprom_ReadByte(EEPROM_ADDRESS_VERSION, &eepromData.eepromVersion);
for(i = 0; i < 4000; i++); // Wait 4ms (a write takes over 3ms)
eeprom_ReadByte(EEPROM_ADDRESS_VERSIONINVERSE, &inverse);
if((eepromData.eepromVersion ^ inverse) != 0xFF)
eepromData.eepromVersion = 0;
}
/******************************************************************************
* FUNCTION: void i2cdriver_exec(void)
******************************************************************************
* DESCRIPTION:
* This function is called to execute the i2c driver task.
*****************************************************************************/
void i2cdriver_exec(void)
{
/*
030321 Modification:
// If we're ringing, handle any state machine change *first*
if (audio_ringerStateMachine())
return;
// Now, handle lower priority tasks
// Any DTMF tones to generate?
if ( dtmfData.Request && (i2cData.i2cMaster == IDLE) ) {
dtmf_WriteByte(dtmfData.Tone);
dtmfData.Request = FALSE;
return;
}
*/
// Updating the time of day (RTC)?
if ( rtcData.UpdateClock &&
((i2cData.i2cMaster == RTC) || (i2cData.i2cMaster == IDLE)) ) {
i2cData.i2cMaster = RTC;
if (rtcData.Index > rtcData.LastIndex) {
rtcData.UpdateClock = FALSE;
i2cData.i2cMaster = IDLE;
}
else {
// Write out the next byte to the RTC chip
rtc_WriteByte(rtcData.rtcMsg[rtcData.Index][0],
rtcData.rtcMsg[rtcData.Index][1]);
rtcData.Index++;
return;
}
}
// Volume adjustment requested?
if ( digpotData.VolumeRequest && (i2cData.i2cMaster == IDLE) ) {
digpot_WriteByte(VOLUME_POT, digpotData.VolumeSetting);
digpotData.VolumeRequest = FALSE;
return;
}
// Contrast adjustment requested?
if ( digpotData.ContrastRequest && (i2cData.i2cMaster == IDLE) ) {
digpot_WriteByte(CONTRAST_POT, digpotData.ContrastSetting);
digpotData.ContrastRequest = FALSE;
// dc550_printf("\r\nSet contrast to %d", digpotData.ContrastSetting);
return;
}
// EEPROM write requested?
if ( eepromData.numberOfMessages &&
((i2cData.i2cMaster == EEPROM) || (i2cData.i2cMaster == IDLE)) ) {
// Write the byte in the array
eeprom_WriteByte( eepromData.address[eepromData.beginIndex],
eepromData.value[eepromData.beginIndex] );
// Increment the begin index, decrement the number of messages
eepromData.beginIndex = ( (eepromData.beginIndex + 1) &
EEPROM_ARRAY_MASK );
eepromData.numberOfMessages--;
// If there are still more messages to write, reserve the I2C bus
if(eepromData.numberOfMessages)
i2cData.i2cMaster = EEPROM;
else
i2cData.i2cMaster = IDLE;
}
// Now, handle the *really* low priority tasks
if (i2cData.i2cMaster == IDLE) {
switch (idleTask) {
case RTC_UPDATE:
/* Update our Notion of Time of Day */
i2c_StartBit(RTC);
if (!i2c_AddressSlave(RTC, FALSE)) {
i2c_StopBit(RTC);
idleTask++;
return;
}
i2c_WriteByte(RTC, RTC_SECONDS_ADDR);
i2c_StartBit(RTC);
if (!i2c_AddressSlave(RTC, TRUE)) {
i2c_StopBit(RTC);
idleTask++;
return;
}
i2c_ReadByte(RTC, rtcData.TOD, FALSE);
i2c_ReadByte(RTC, rtcData.TOD+1, FALSE);
i2c_ReadByte(RTC, rtcData.TOD+2, FALSE);
i2c_ReadByte(RTC, rtcData.TOD+3, FALSE);
i2c_ReadByte(RTC, rtcData.TOD+4, TRUE);
i2c_StopBit(RTC);
idleTask++;
return;
case RTC_DISPLAY:
{
static int last_mins=-1;
int year,month,date,hour,mins,secs,dow;
/*
char *days[8] =
{"SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT", "---" };
*/
rtc_GetTimeOfDay(&year, &month, &date, &hour, &mins, &secs, &dow);
if (dow > 6) dow = 7;
if (mins != last_mins) {
/*
dc550_printf("\r\n%s %c%c-%c%c-0%c %c%c:%c%c:%c%c",
days[dow], '0'+(month>>4), '0'+(month&0xf),
'0'+(date>>4), '0'+(date&0xf),'0'+year,
'0'+(hour>>4), '0'+(hour&0xf),
'0'+(mins>>4), '0'+(mins&0xf),
'0'+(secs>>4), '0'+(secs&0xf));
*/
last_mins = mins;
}
idleTask++;
return;
}
case I2C_IDLE_TASK_LAST:
idleTask = I2C_IDLE_TASK_FIRST;
break;
}
}
return;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?