//------------------------------------------------------------------- void I2C_WriteByte ( uint8_t SlaveAddr, uint8_t RegAddr, uint8_t Data ) { #if 0 sccb_write(SlaveAddr, RegAddr, Data); #else I2CSendAddr(SlaveAddr,WRITE); I2CSendByte(RegAddr); I2CSendByte(Data); I2CSendStop(); #endif }
/** * Send out a single byte of data over the I2C * * @param data The byte of data to send */ bool I2C_TransmitOneByte(unsigned char data) { // Wait for the transmitter to be ready while (!I2CTransmitterIsReady(I2C1)); // Transmit the byte if (I2CSendByte(I2C1, data) == I2C_MASTER_BUS_COLLISION) { //serialPrint("Error: I2C Master Bus Collision\r\n"); while (1); } // Wait for the transmission to finish while (!I2CTransmissionHasCompleted(I2C1)); unsigned int i; for (i = 0; i < I2C_Timeout; i++) { if (I2CByteWasAcknowledged(I2C1)) { break; } else if (i == I2C_Timeout - 1) { //serialPrint("Error: I2C Slave Did Not Acknowledge\r\n"); return FALSE; } } return TRUE; }
//------------------------------------------------------------------------------ // Function: SendAddr // Description: //------------------------------------------------------------------------------ static uint8_t I2CSendAddr(uint8_t addr, uint8_t read) { volatile uint8_t x = 0; //delay variable //generate START condition SET_SCL(); #if 0 if(GET_SCL) TX_DEBUG_PRINT(("GET_SCL is high rightly \n")); else TX_DEBUG_PRINT(("GET_SCL is low wrong\n")); #endif x++; //short delay to keep setup times in spec CLEAR_SDA(); #if 0 if(!GET_SDA) TX_DEBUG_PRINT(("GET_SDA is low rightly\n")); else TX_DEBUG_PRINT(("GET_SDA is high wrong\n")); #endif x++; x++; x++; CLEAR_SCL(); #if 0 if(!GET_SCL) TX_DEBUG_PRINT(("GET_SCL is low rightly\n")); else TX_DEBUG_PRINT(("GET_SCL is high wrong\n")); #endif x++; return (I2CSendByte(addr|read)); //send address uint8_t with read/write bit }
/*写SD2200状态寄存器命令*/ void I2CWriteStatus(void) { if(!I2CStart())return; I2CSendByte(0x60,1); //发送SD2200状态寄存器_1命令 if(!I2CWaitAck()){I2CStop();return;} // I2CSendByte(0x03,0); //IC进行复位初始化,24小时制 I2CSendByte(0x02,0); //IC不进行复位初始化,24小时制 I2CWaitAck(); I2CStop(); I2CStart(); I2CSendByte(0x62,1); //发送SD2200状态寄存器_2命令 I2CWaitAck(); I2CSendByte(0x00,0); //清TEST位,禁止中断输出 I2CWaitAck(); I2CStop(); }
/************************************************************************************************** Function: static BOOL I2CShared_TransmitOneByte(const I2C_MODULE i2c, const UINT8 data) Author(s): mkobit Summary: Transmits one byte of data to (i2c) Description: Waits until transmitter is ready and sends the byte of data Static function, used by internal library Preconditions: Transaction started I2C module configured Parameters: const I2C_MODULE i2c - I2C module to be used for this transaction const UINT8 data - to be transmitted Returns: TRUE - If successful FALSE - If unsuccessful Example: <code> I2CShared_TransmitOneByte(I2C1, 0x43) </code> Conditions at Exit: Transmission of byte complete I2C bus waiting for next action **************************************************************************************************/ static BOOL I2CShared_TransmitOneByte(const I2C_MODULE i2c, const UINT8 data) { int fault_count = 0; // Wait for the transmitter to be ready while(!I2CTransmitterIsReady(i2c)) { if (fault_count++ == TIMEOUT) { //printf("I2CShared_TransmitOneByte: Timeout waiting for I2CTransmitterIsReady\n"); return FALSE; } } // Transmit the byte if(I2CSendByte(i2c, data) == I2C_MASTER_BUS_COLLISION) { //printf("I2CShared_TransmitOneByte: Error, I2C Master Bus Collision , status = 0x%x\n", I2CGetStatus(i2c)); return FALSE; } fault_count = 0; // Wait for the transmission to finish while(!I2CTransmissionHasCompleted(i2c)) { if (fault_count++ == TIMEOUT) { //printf("I2CShared_TransmitOneByte: Timeout waiting for I2CTransmissionHasCompleted\n"); return FALSE; } } if(!I2CByteWasAcknowledged(i2c)) { //printf("I2CShared_TransmitOneByte: Error, sent byte was not acknowledged, status = 0x%x\n", I2CGetStatus(i2c)); //I2CShared_DebugStatus(i2c); return FALSE; } return TRUE; }
/******读SD2200实时数据寄存器******/ void I2CReadDate(void) { uchar m,tmp; if(!I2CStart())return; I2CSendByte(0x65,1);//从年开始读取数据 if(!I2CWaitAck()){I2CStop();return;} for(m=0;m<7;m++) { timeBuf[m]=I2CReceiveByte(); if (m!=6) //最后一个数据不应答 { I2CAck(); } } I2CNoAck(); I2CStop(); /* for(m=0;m<SEND_TIME_LEN;m++) { //BCD处理 tmp=timeBuf[m+4]/16; sendTimeBuf[m]=timeBuf[m+4]%16; sendTimeBuf[m]=sendTimeBuf[m]+tmp*10; showTimeBuf[2*m]=timeBuf[m+4]/16; showTimeBuf[2*m+1]=timeBuf[m+4]%16; }*/ //展开处理 因小时需单独处理 12点以上的需减去40 tmp=timeBuf[4]/16; sendTimeBuf[0]=timeBuf[4]%16; sendTimeBuf[0]=sendTimeBuf[0]+tmp*10; if(sendTimeBuf[0]>=40){ sendTimeBuf[0]-=40; } showTimeBuf[0]=sendTimeBuf[0]/10; showTimeBuf[1]=sendTimeBuf[0]%10; tmp=timeBuf[5]/16; sendTimeBuf[1]=timeBuf[5]%16; sendTimeBuf[1]=sendTimeBuf[1]+tmp*10; showTimeBuf[2]=sendTimeBuf[1]/10; showTimeBuf[3]=sendTimeBuf[1]%10; tmp=timeBuf[6]/16; sendTimeBuf[2]=timeBuf[6]%16; sendTimeBuf[2]=sendTimeBuf[2]+tmp*10; showTimeBuf[4]=sendTimeBuf[2]/10; showTimeBuf[5]=sendTimeBuf[2]%10; //年月日 tmp=timeBuf[0]/16; sendTimeBuf[3]=timeBuf[0]%16; sendTimeBuf[3]=sendTimeBuf[3]+tmp*10; tmp=timeBuf[1]/16; sendTimeBuf[4]=timeBuf[1]%16; sendTimeBuf[4]=sendTimeBuf[4]+tmp*10; tmp=timeBuf[2]/16; sendTimeBuf[5]=timeBuf[2]%16; sendTimeBuf[5]=sendTimeBuf[5]+tmp*10; }
//------------------------------------------------------------------------------ // Function Name: I2C_ReadSegmentBlockEDID // Function Description: Reads segment block of EDID from HDMI Downstream Device //------------------------------------------------------------------------------ uint8_t I2C_ReadSegmentBlockEDID (uint8_t SlaveAddr, uint8_t Segment, uint8_t Offset, uint8_t *Buffer, uint8_t Length) { uint8_t i, bState; TX_DEBUG_PRINT(("I2C_ReadSegmentBlockEDID%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n")); bState = I2CSendAddr(0x60, WRITE); if(bState){ I2CSendStop(); return IIC_NOACK; } bState = I2CSendByte(Segment); if(bState){ I2CSendStop(); return IIC_NOACK; } bState = I2CSendAddr(SlaveAddr,WRITE); if(bState){ I2CSendStop(); return IIC_NOACK; } bState = I2CSendByte(Offset); if(bState){ I2CSendStop(); return IIC_NOACK; } bState = I2CSendAddr (SlaveAddr,READ); if(bState){ I2CSendStop(); return IIC_NOACK; } for (i = 0; i < Length - 1; i++) if (I2CGetByte(NOT_LAST_BYTE, &Buffer[i])) return IIC_SCL_TIMEOUT; if (I2CGetByte(LAST_BYTE, &Buffer[i])) return IIC_SCL_TIMEOUT; I2CSendStop(); return IIC_OK; }
}void i2cSendByte(I2C_MODULE id, BYTE data){ while(!I2CTransmitterIsReady(id));//maybe comment this out I2CSendByte(id, data); //I2C_RESULT temp = I2CSendByte(id, data); //temp; while(!I2CTransmissionHasCompleted(id)); while(!I2CByteWasAcknowledged(id)); }
/* * I2CSendAddr(byte addr, byte rd) * * * Rueckgabe: Keine * * Autor: - */ void I2CSendAddr(byte addr, byte rd) { SCL = 1; _I2CBitDly(); SDA = 0; // generate start _I2CBitDly(); SCL = 0; _I2CBitDly(); I2CSendByte(addr+rd); // send address byte }
unsigned int portableMasterWriteI2C(I2cBusConnection* i2cBusConnection, unsigned char data) { I2cBus* i2cBus = i2cBusConnection->i2cBus; if (i2cBus == NULL) { return MasterWriteI2C1(data); } else { I2C_MODULE i2cModule = getI2C_MODULE(i2cBus->port); return I2CSendByte(i2cModule, data); } }
static int transmit_byte(I2C_MODULE port, UINT8 data) { while(!I2CTransmitterIsReady(port)); if(I2CSendByte(port, data) == I2C_MASTER_BUS_COLLISION) return -1; while(!I2CTransmissionHasCompleted(port)); return 0; }
bool i2c_transmit(char byte) { state = I2C_STATE_TRANSMIT; if (I2CSendByte(I2C1, byte) != I2C_SUCCESS) return FALSE; if (!semaphore_take(bus_lock, PORT_MAX_DELAY)) return FALSE; return TRUE; }
/*写SD2200时间寄存器命令*/ void I2CWriteTime(void) //7字节bcd year/month/day/week/hour/minite/second { uchar i,tmp; for(i=0;i<7;i++) { //BCD处理 tmp=initTimeBuf[i]/10; timeBuf[i]=initTimeBuf[i]%10; timeBuf[i]=timeBuf[i]+tmp*16; } I2CStart(); I2CSendByte(0x64,1); //发送SD2200写时间寄存器命令, I2CWaitAck(); for(i=0;i<7;i++) { I2CSendByte(timeBuf[i],0); I2CWaitAck(); } I2CStop(); }
//------------------------------------------------------------------------------ // Function Name: I2C_WriteBlock // Function Description: Writes block of data from I2C Device //------------------------------------------------------------------------------ uint8_t I2C_WriteBlock( uint8_t SlaveAddr, uint8_t RegAddr, uint8_t NBytes, uint8_t * Data ) { uint8_t i, bState; bState = I2CSendAddr (SlaveAddr,WRITE); if( bState ){ I2CSendStop(); return IIC_NOACK; } bState = I2CSendByte(RegAddr); if(bState){ I2CSendStop(); return IIC_NOACK; } for (i=0; i<NBytes; i++) I2CSendByte(Data[i]); I2CSendStop(); return IIC_OK; }
//------------------------------------------------------------------- uint8_t I2C_ReadByte ( uint8_t SlaveAddr, uint8_t RegAddr ) { #if 0 return sccb_read(SlaveAddr, RegAddr); #else uint8_t Data = 0; I2CSendAddr(SlaveAddr,WRITE); I2CSendByte(RegAddr); I2CSendAddr (SlaveAddr,READ); I2CGetByte(LAST_BYTE, &Data); I2CSendStop(); return Data; #endif }
bool TransmitOneByte( uint8_t data ) { // Wait for the transmitter to be ready while(!I2CTransmitterIsReady(OVM7690_I2C_BUS)); // Transmit the byte if(I2CSendByte(OVM7690_I2C_BUS, data) == I2C_MASTER_BUS_COLLISION) { return false; } // Wait for the transmission to finish while(!I2CTransmissionHasCompleted(OVM7690_I2C_BUS)); return true; }
static bool TransmitOneByte(I2C_MODULE i2c_id, uint8_t data) { // Wait for the transmitter to be ready while (!I2CTransmitterIsReady(i2c_id)); // Transmit the byte if (I2CSendByte(i2c_id, data) == I2C_MASTER_BUS_COLLISION) { //DBPRINTF("Error: I2C Master Bus Collision\n"); return FALSE; } // Wait for the transmission to finish while (!I2CTransmissionHasCompleted(i2c_id)); return TRUE; }
BOOL TransmitOneByte( UINT8 data ) { // Wait for the transmitter to be ready while(!I2CTransmitterIsReady(OVM7690_I2C_BUS)); // Transmit the byte if(I2CSendByte(OVM7690_I2C_BUS, data) == I2C_MASTER_BUS_COLLISION) { return FALSE; } // Wait for the transmission to finish while(!I2CTransmissionHasCompleted(OVM7690_I2C_BUS)); return TRUE; }
BOOL TransmitOneByte( UINT8 data ) { // Wait for the transmitter to be ready while(!I2CTransmitterIsReady(EEPROM_I2C_BUS)); // Transmit the byte if(I2CSendByte(EEPROM_I2C_BUS, data) == I2C_MASTER_BUS_COLLISION) { DBPRINTF("Error: I2C Master Bus Collision\n"); return FALSE; } // Wait for the transmission to finish while(!I2CTransmissionHasCompleted(EEPROM_I2C_BUS)); return TRUE; }
BOOL I2C_transmitOneByte(I2C_MODULE I2C_ID, uint8_t data) { // Wait for the transmitter to be ready while(!I2CTransmitterIsReady(I2C_ID)); // Transmit the byte and check for bus collision if(I2CSendByte(I2C_ID, data) == I2C_MASTER_BUS_COLLISION){ #ifdef DEBUG printf("Error: I2C Master Bus Collision\n"); #endif return FALSE; } // Wait for the transmission to finish while(!I2CTransmissionHasCompleted(I2C_ID)); return TRUE; }
BOOL MPU6050::TransmitOneByte( UINT8 data ) { UINT16 count = 0; // Wait for the transmitter to be ready while( !I2CTransmitterIsReady( this->i2cBusId ) && count < 64000 ) { count++; } if( count < 64000 ) { // Transmit the byte if(I2CSendByte( this->i2cBusId, data) == I2C_MASTER_BUS_COLLISION) { sprintf( filename, "Error in TransmitOneByte(). I2C Master Bus Collision.\n" ); putsUART1( filename ); //DBPRINTF("Error: I2C Master Bus Collision\n"); return FALSE; } count = 0; // Wait for the transmission to finish while( !I2CTransmissionHasCompleted( this->i2cBusId ) && count < 64000 ) { count++; } if( count >= 64000 ) { sprintf( filename, "Error: TransmitOneByte(). Loop timeout for I2CTransmissionHasCompleted().\n" ); putsUART1( filename ); return FALSE; } } else { sprintf( filename, "Error: TransmitOneByte(). Loop timeout for I2CTransmitterIsReady().\n" ); putsUART1( filename ); return FALSE; } return TRUE; }
//============================================================================== BOOL i2c_Tx( UINT8 data ) { // Wait for the transmitter to be ready while(!I2CTransmitterIsReady(EEPROM_I2C_BUS)); //while ( !I2C1STATbits.TBF ) ; // Transmit the byte if(I2CSendByte(EEPROM_I2C_BUS, data) == I2C_MASTER_BUS_COLLISION) { putsUART1("Error: I2C Master Bus Collision\n"); return FALSE; } //I2C1TRN = data; // Wait for the transmission to finish while(!I2CTransmissionHasCompleted(EEPROM_I2C_BUS)); //while ( I2C1STATbits.TRSTAT ); return TRUE; }
BOOL TransmitOneByte( UINT8 data ) { char Success = TRUE; // Wait for the transmitter to be ready while(!I2CTransmitterIsReady(PIC24_I2C_BUS)); // Transmit the byte if(I2CSendByte(PIC24_I2C_BUS, data) == I2C_MASTER_BUS_COLLISION) { DBPRINTF("Error: I2C Master Bus Collision\n"); printf("bus coll\n"); goto END2; Success = FALSE; } // Wait for the transmission to finish while(!I2CTransmissionHasCompleted(PIC24_I2C_BUS)); END2: if(Success == FALSE){return FALSE;} else return TRUE; }
//------------------------------------------------------------------------------ // Function Name: I2C_ReadBlock // Function Description: Reads block of data from I2C Device //------------------------------------------------------------------------------ uint8_t I2C_ReadBlock(uint8_t SlaveAddr, uint8_t RegAddr,uint8_t *Data, uint8_t NBytes) { uint8_t i, bState; bState = I2CSendAddr(SlaveAddr,WRITE); if(bState){ I2CSendStop(); return IIC_NOACK; } bState = I2CSendByte(RegAddr); if(bState){ I2CSendStop(); return IIC_NOACK; } bState = I2CSendAddr (SlaveAddr,READ); if(bState){ I2CSendStop(); return IIC_NOACK; } for (i = 0; i < NBytes - 1; i++) { if (I2CGetByte(NOT_LAST_BYTE, &Data[i])){ I2CSendStop(); return IIC_SCL_TIMEOUT; } } if (I2CGetByte(LAST_BYTE, &Data[i])){ I2CSendStop(); return IIC_SCL_TIMEOUT; } I2CSendStop(); return IIC_OK; }
/* Sends a byte on an i2c channel (with no strings attached) */ void sendByte(I2C_MODULE i2c, BYTE byte){ I2CSendByte(i2c, byte); // Send and wait for finish while( ! I2CTransmissionHasCompleted(i2c)); while( ! (I2CByteWasAcknowledged(i2c))); // wait for ack }
/* * workAS() * Schnittstelle nur fuer das Modul Betriebsmittelverwaltung. Die * Schnittstelle dient dem Auslesen von maximal vier Meldungen der Module aus * dem Ringpuffer und deren Versendung ueber den I2C-Bus. * Fuer diese Uebertragung werden werden maximal 29 Bytes + Start- und * Stoppbits versendet. * * Nach Aufruf dieser Schnittstelle wird ueberprueft, ob der Ringpuffer leer * ist. Wenn dem so ist, muessen keine Daten untersucht werden und der Vorgang * wird beendet. * Andernfalls wird ueberprueft, ob der Lesezeiger AS_read_next_msg auf einen * gueltigen Index zeigt. Ggf. wird dieser durch Nullsetzen korrigiert. * Dadurch soll sichergestellt werden, dass im Folgenden nicht wahllose Werte * aus dem Speicher gelesen werden. * Es wird eine Wartepause von 1,568 ms eingelegt. * Dann wird versucht die I2C-Bus-Verbindung zum AD herzustellen. Dazu wird die * Funktion I2CSendAddr(addr, rd) mit den Parametern (8, WRITE) benutzt. * Schlaegt die Verbindung fehl, wird der Vorgang beendet. * Danach wird versucht maximal vier Meldungen zu versenden. Dazu werden * jeweils die naechsten 7 Daten aus dem Ringpuffer an der Stelle des * Lesezeigers AS_read_next_msg gelesen und mit Hilfe der Funktion * I2CSendByte(bt) wird sucht, sie zu versenden. Schlaegt die Verbindung fehl, * wird erst versucht die Verbindung zu beenden und danach wird der Vorgang * beendet. * Ist der Vorgang des Daten aus dem Ringpuffers versenden abgeschlossen, wird * versucht die Verbindung zu beenden. Dazu wird die Funktion I2CSendStop() * benutzt. * * Rueckgabe: Keine * * Autor: Felix Blueml */ void workAS() { // Maximale Anzahl Mitteilungen, die versendet werden. // byte maxSendMsg_workAS; // ist globale Variable // Zaehler fuer die beiden for-Schleifen, fuer die Versendung von // Mitteilungen. // byte i_workAS, j_workAS; // sind globale Variablen // Keine Elemente im Puffer zum versenden? if(!AS_msg_counter) { // Abbruch! return; } // Enthaellt AS_read_next_msg einen falschen Wert? if(AS_read_next_msg >= MAX_MELDUNGEN) { // Sicherstellen, dass nicht wahllos irgendwelche Werte aus // dem Speicher gelesen werden AS_read_next_msg = 0; } warten(); // eine Wartepause einlegen // Versuche eine schreibende Verbindung zum Arduino mit der // Adresse 4 herzustellen _i2c_error = 255; // Status: Kein Fehler I2CSendAddr(8, WRITE); if(_i2c_error != 255) // Fehler erkannt? { // Abbruch! return; } // Lese maximal 4 Mitteilungen aus dem Ringpuffer und versende sie if(AS_msg_counter<4) { maxSendMsg_workAS = AS_msg_counter; } else { maxSendMsg_workAS = 4; } for(i_workAS=0; i_workAS<maxSendMsg_workAS; i_workAS++) { for(j_workAS=0; j_workAS<7; j_workAS++) { // Versuche ein Byte aus dem Ringpuffer an den Arduino // zu versenden _i2c_error = 255; // Status: Kein Fehler I2CSendByte(AS_msg_array[AS_read_next_msg][j_workAS]); if(_i2c_error != 255) // Fehler erkannt? { // Versuche die Verbindung zu beenden I2CSendStop(); // Abbruch! return; } } // Eine komplette Statusmeldung wurde versendet, // Lesezeiger auf die naechste zu sendende Meldung setzen AS_read_next_msg = (AS_read_next_msg+1) % MAX_MELDUNGEN; // Fuellstand um 1 verringern AS_msg_counter--; } // Versuche die Verbindung zu beenden I2CSendStop(); }
void i2c_isr(uint8_t p) { I2CModule_t * mod; // Get a reference to the module structure switch (p) { case I2C2: mod = &I2C_2; break; default: return; } switch (mod->state) { case IDLE: break; case START: I2CStart(mod->moduleName); mod->state = ADDRESS; I2C_2.dataDirection = WRITING; break; case ADDRESS: switch (mod->dataDirection) { case READING: I2CSendByte(mod->moduleName, mod->frame->address + 1); mod->state = CHECK_ACK; break; case WRITING: I2CSendByte(mod->moduleName, mod->frame->address); mod->state = CHECK_ACK; break; } break; case CHECK_ACK: if (I2CByteWasAcknowledged(mod->moduleName) == True) { switch (mod->dataDirection) { case READING: mod->state = READ; break; case WRITING: mod->state = WRITE; break; } } else { mod->frame->success = False; mod->state = STOP; } i2c_isr(mod->moduleName); break; case RESTART: I2CRepeatStart(mod->moduleName); mod->dataDirection = READING; mod->state = ADDRESS; break; case READ_START: I2CReceiverEnable(mod->moduleName, TRUE); mod->state = READ; break; case READ: mod->frame->rx_buf[mod->frame->rx_buf_index++] = I2CGetByte(mod->moduleName); // If we need to read more bytes send an ACK if (mod->frame->rx_buf_index <= mod->frame->bytesToRead) { I2CAcknowledgeByte(mod->moduleName, True); // Send an ACK mod->state = READ_START; // Prepare for the next byte } else { I2CAcknowledgeByte(mod->moduleName, False); // Send a NACK mod->frame->success = True; mod->state = STOP; // Prepare for a stop condition } break; case WRITE: // If there are still bytes to send if (mod->frame->tx_buf_index < mod->frame->tx_buf_size) { I2CSendByte(mod->moduleName, mod->frame->tx_buf[mod->frame->tx_buf_index++]); } else { // If we need to read some bytes if (mod->frame->bytesToRead > 0) { mod->state = RESTART; // Send a restart condition } else { mod->frame->success = True; mod->state = STOP; // Send a stop condition } i2c_isr(mod->moduleName); // Re-run this function to call stop/restart // TODO: Perhaps there is a better way to do this..! } break; case STOP: I2CStop(mod->moduleName); mod->frameToSend = False; mod->state = IDLE; // Tell the owner of the frame that it has complete or failed if (mod->frame->success == True) { mod->frame->callback(); } else { mod->frame->error(); } break; case BUSERROR: led12 = 1; // TODO: Something..! while(1); // Don't know what to do here yet..! break; } }