//-------------------------------------------------------------------
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
}
Beispiel #2
0
/**
 * 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;
}
Beispiel #8
0
}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
}
Beispiel #10
0
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;
}
Beispiel #12
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;
}
Beispiel #13
0
/*写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
}
Beispiel #16
0
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;
}
Beispiel #18
0
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;
}
Beispiel #19
0
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;
}
Beispiel #20
0
Datei: I2C.c Projekt: sdajani/sdp
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;
}
Beispiel #21
0
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;
}
Beispiel #22
0
//==============================================================================
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;
}
Beispiel #23
0
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;
}
Beispiel #25
0
/*
 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();
}
Beispiel #27
0
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;
    }
}