i2c_prom.c
来自「ESS3890+SL原代码(1*16内存)」· C语言 代码 · 共 774 行 · 第 1/2 页
C
774 行
#ifndef CHEAT // wait_timer((cptr->tF)+(cptr->tLOW)); /* SCL fall time + SCL low time */#endif }}/**************************************************** i2c_stop: I2C stop condition. arguments: *cptr ptr to the current device parameters. return: *****************************************************/static void i2c_stop(IIC_CONFIG *cptr){ need_to_stop = 0; /* reset "need_to_stop" */ cptr->SDA_set(0); /*1 SDA low */#ifndef CHEAT // wait_timer(cptr->tLOW); /* SCL low time */#endif i2c_raise_scl(cptr); /*2 SCL high */ // wait_timer((cptr->tR)+(cptr->tSU_STO)); /* SCL rise time + stop condition setup time */ cptr->SDA_set(1); /*3 SDA 1 */#ifndef CHEAT // wait_timer(cptr->tR); /* SDA rise time */#endif}/**************************************************** i2c_writebyte: Write a byte to I2C bus. arguments: *cptr ptr to the current device parameters. c a byte to be written return: *****************************************************/static void i2c_writebyte(IIC_CONFIG *cptr, unsigned char c){ int i; if (!need_to_stop) { for (i = 0; i < 8; i++) { // wait_timer(cptr->tLOW); /* SCL low time */ if (c & 0x80) { /* most significant bit */ cptr->SDA_set(1); /* SDA hi */ }else { cptr->SDA_set(0); /* SDA low */ }#ifndef CHEAT // wait_timer(cptr->tSU_DAT); /* data in setup time */#endif i2c_raise_scl(cptr); /* SCL high */ // wait_timer((cptr->tR)+(cptr->tHIGH)); /* SCL rise time + SCL high time */ cptr->SCL_set(0); /* SCL low */#ifndef CHEAT // wait_timer((cptr->tF)+(cptr->tHD_DAT)); /* SDA and SCL fall time + data in hold time */#endif c <<= 1; } i2c_ack(cptr, 1); /* get acknowledge */ if (timeout) need_to_stop = 1; else need_to_stop = 0; }}/**************************************************** i2c_ack: I2C acknowledge of byte transfer. arguments: *cptr ptr to the current device parameters. mode 0 (no ack needed) 1 (get ack) 2 (give ack) return: 0 okay (got ack) -1 error (no ack)*****************************************************/static int i2c_ack(IIC_CONFIG *cptr, int mode){ int tmp; int ack_starttime; int k = -1; if (!need_to_stop) { if (mode == 1) { /* get acknowledge */ cptr->SDA_set(1); /* 1 SDA TRISTATE_EAUX4 */ #ifndef CHEAT // wait_timer((cptr->tR)+(cptr->tSU_DAT)); /* SDA rise time and setup time */#endif // wait_timer(cptr->tLOW); /* SCL low time */ i2c_raise_scl(cptr); /* 2 SCL high */ // wait_timer(cptr->tHIGH); /* SCL rise time and high time */ ack_starttime = mvd[riface_timer2]; /* ack start time */ while (1) { if (!(cptr->SDA_sense())) { // 3 wait SDA low k = 0; yes_ack++; break; /* got acknowledge */ }else { k = -1; tmp = mvd[riface_timer2] - ack_starttime; if (tmp < 0) tmp += -timer2_period; if (tmp >= cptr->ack_wtime) { //16C timeout++; no_ack++; break; /* acknowledge timeout */ } }// AUD_service(); // cf } } else if (mode == 2) { /* acknowledge is needed */ // wait_timer(cptr->tLOW); /* SCL low time */ cptr->SDA_set(0); /* SDA low */ // wait_timer((cptr->tF)+(cptr->tSU_DAT)); /* SDA fall time and setup time */ // wait_timer(cptr->tLOW); /* SCL low time */ /* clock cycle for acknowledge */ i2c_raise_scl(cptr); /* SCL high */ // wait_timer((cptr->tR)+(cptr->tHIGH)); /* SDA and SCL rise time + SCL high time */ }else { /* no acknowledge is needed */ i2c_raise_scl(cptr); /* SCL high */ // wait_timer((cptr->tR)+(cptr->tHIGH)); /* SDA and SCL rise time + SCL high time */ } cptr->SCL_set(0); /* SCL low */ // wait_timer((cptr->tF)+(cptr->tLOW)); /* SCL fall time + SCL low time */ /* For mode 2, need to tristate SDA again. MY20010314 */ if( mode == 2 ) { cptr->SDA_set(1); /* SDA hi */ // wait_timer((cptr->tR)); /* SCL rise time */ } } return(k);}/**************************************************** i2c_readbyte: Read a byte from the I2C bus. arguments: *cptr ptr to the current device parameters. return: b byte read*****************************************************/static uchar i2c_readbyte(IIC_CONFIG *cptr){ int i; unsigned char b;#if defined(BD_ABELA3) SET_VFD_STROBE;#endif b = 0; if (!need_to_stop) { for (i = 0; i < 8; i++) { b <<= 1; // wait_timer(cptr->tAA); /* data output delay time */ i2c_raise_scl(cptr); /* SCL high */ // wait_timer(cptr->tR); /* SCL rise time */ if (cptr->SDA_sense()) /* SDA out */ b |= 1; else b |= 0; // wait_timer(cptr->tHIGH); /* SCL high time */ cptr->SCL_set(0); /* SCL low */ // wait_timer((cptr->tF)+(cptr->tDH)+(cptr->tLOW)); /* SCL fall time + data out hold time + clock low time */ } } return(b);}/****************************************************************** This is a driver to control the E2PROM.*******************************************************************//* for debug */#define EEPROM_TEST 0 /****************************************************************** Various Defines.*******************************************************************/#define EEPROM_ADDR 0xa0/****************************************************************** Variables.*******************************************************************/static int eeprom_timing[] = { 7000, /* tAA */ 6700, /* tBUF */ 4500, /* tHD_STA */ 6700, /* tSU_STA */ 6700, /* tLOW */ 4500, /* tHIGH */ 0, /* tHD_DAT */ 500, /* tSU_DAT */ 1000, /* tR */ 300, /* tF */ 6700, /* tSU_STO */ 300, /* tDH */ 10000000 /* tWR: 10ms seems to be about right */}; static int eeprom_id = -1; /* device id for eeprom */static int prev_wcmd = 0; /* = 1 (write cmd); = 0 (read cmd) */#if EEPROM_TEST/* for debug */static int i2c_ret = 0;static int w_addr = 0;static int w_data = 0;static int r_addr = 0;static int r_data = 0;static int s_data[128];#endif /* EEPROM_TEST */ /****************************************************************** Function Definitions.*******************************************************************//*********************************************************************** * I2C SDA and SCL pins ***********************************************************************/void set_sda(int high){ if (high) { INPUT_I2C_DAT; } else { CLEAR_I2C_DAT; } // if (high) { TRISTATE_AUX5; } else { CLEAR_AUX5; } }void set_scl(int high){ if (high) { INPUT_I2C_CLK; } else { CLEAR_I2C_CLK; }// if (high) { TRISTATE_AUX7; } else { CLEAR_AUX7; }}int sense_sda(){ return((I2C_DAT_HIGH) ? 1:0); // return((AUX5_HIGH) ? 1:0);}int sense_scl(){ return((I2C_CLK_HIGH) ? 1:0);// return((AUX7_HIGH) ? 1:0);}/**************************************************** I2C_PROM_init: Configure I2C parameters for the eeprom.*****************************************************/int I2C_PROM_init(){ eeprom_id = I2C_config(EEPROM_ADDR, set_scl, set_sda, sense_scl, sense_sda, eeprom_timing); if (eeprom_id==-1){ EepromErr = 1; return(0); // error eeprom }else{ EepromErr = 0; return (1); }}/******************************************** Write a byte to E2PROM. parameter: addr - word-address (0 to 127) data - 8-bit input data return: 0 - write okay -1 - error, no acknowledge from E2PROM*********************************************/int i2c_e2prom_bywrite(uchar addr, uchar data){ int a, b; if (prev_wcmd) { /* ack polling */ a = I2C_ackpolling(eeprom_id); } else { a = 1; } prev_wcmd = 1; /* write command */ if (a) { /* get ack or no polling is needed */ b = I2C_bytewrite(eeprom_id, addr, data); return(b); } else { /* no ack: device still busy */ return(-1); }} /******************************************** Read a byte from E2PROM. parameter: addr - word-address (0 to 127) return: >=0 - output data -1 - error, no acknowledge from E2PROM*********************************************/int i2c_e2prom_byread(uchar addr){ int a, b; if (prev_wcmd) { /* ack polling */ a = I2C_ackpolling(eeprom_id); } else { a = 1; } prev_wcmd = 0; /* read command */ if (a) { /* get ack or no polling is needed */ b = I2C_byteread(eeprom_id, addr); return(b); } else { /* no ack: device still busy */ return(-1); }}/****************************************************/#if EEPROM_TEST/* for debug */void I2C_driver_test(int mode){ int i; switch(mode) { case 1: /* config */ eeprom_id = I2C_config(EEPROM_ADDR, set_scl, set_sda, sense_scl, sense_sda, eeprom_timing); break; case 2: /* single byte write */ i2c_ret = I2C_bytewrite(eeprom_id, w_addr, w_data); break; case 3: /* single byte read */ r_data = I2C_byteread(eeprom_id, r_addr); break; case 4: /* 128 bytes write */ for (i = 0; i < 128; i++) { i2c_ret = I2C_bytewrite(eeprom_id, i, (127-i)); } break; case 5: /* 128 bytes read */ for (i = 0; i < 128; i++) { s_data[i] = I2C_byteread(eeprom_id, i); } break; default: break; }}#endif /* EEPROM_TEST */#endif /* I2C_E2PROM */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?