//------------------------------------------------------------------------------
// Function: SendByte
// Description:
//------------------------------------------------------------------------------
static uint8_t I2CSendByte(uint8_t abyte)
{
    uint8_t error = 0;
    uint8_t i;

    for (i = 0; i < 8; i++)
    {
        if (abyte & 0x80)
            SET_SDA();      //send each bit, MSB first
        else
            CLEAR_SDA();

        if (SetSCLHigh())       //do clock cycle
            return IIC_SCL_TIMEOUT;
		
        CLEAR_SCL();

        abyte <<= 1;        //shift over to get next bit
    }

    SET_SDA();              //listen for ACK
    #if 1
    if (SetSCLHigh())
	return IIC_SCL_TIMEOUT;

    if (GET_SDA())          //error if no ACK
    	{
    	printk("IIC_NOACK\n");
        error = IIC_NOACK;
    	}
		#endif
    CLEAR_SCL();

    return (error);     //return 0 for no ACK, 1 for ACK received
}
static uint8_t I2CGetByte(uint8_t lastbyte, uint8_t * Data)
{
    uint8_t abyte = 0;
    uint8_t i;

    for (i = 0; i < 8; i++)  //get each bit, MSB first
    {
        if (SetSCLHigh())
	     return IIC_SCL_TIMEOUT;
		
        abyte <<= 1;    //shift result over to make room for next bit

        if (GET_SDA())
            abyte++;    //same as 'abyte |= 1', only faster

        CLEAR_SCL();
    }

    if (lastbyte)
        SET_SDA();      //do not ACK last uint8_t read
    else
        CLEAR_SDA();

    if (SetSCLHigh())
	 return IIC_SCL_TIMEOUT;
	
    CLEAR_SCL();
    SET_SDA();
	
    *Data = abyte;
		
    return IIC_OK;
}
//------------------------------------------------------------------------------
// Function: SendStop
// Description:
//------------------------------------------------------------------------------
static uint8_t I2CSendStop(void)
{
    CLEAR_SDA();
    if (SetSCLHigh())
	return IIC_SCL_TIMEOUT;
	
    SET_SDA();
    return IIC_OK;
}
Beispiel #4
0
    void PeriodicProcessing( uint8_t inputValue, uint8_t& outputValue )
    {
        #define SET_SDA_ACCORDING_TO_BIT_NUMBER(bitMask) \
                if( (currentByte&bitMask) != 0)          \
                {                                        \
                    SetSDAHigh(outputValue);                         \
                }                                        \
                else                                     \
                {                                        \
                    SetSDALow(outputValue);                        \
                }

        //if(state != 30) DebugPrintf("%d\n",state);
        switch(state)
        {
            case 30:            // Enter command mode.
                bool    dataAvailable;


                if(numberOfBytes > 0)
                {
                    SetSCLLow(outputValue);

                    currentByte = inFIFO.NonBlockingGet(dataAvailable);
                    if( dataAvailable == true )
                    {
                        state           = 2;    // goto data transfer mode.
                    }
                    numberOfBytes--;
                }
                else
                {
                    currentCmd = cmdFIFO.NonBlockingGet(dataAvailable);
                    if( dataAvailable == true )
                    {
                        if(currentCmd == 0xfe)
                        {
                            state           = 40;    // Start condtion.
                        }
                        else if(currentCmd == 0xff)
                        {
                            state           = 28;    // Stop condition.
                        }
                        else if(currentCmd == 0xfd)
                        {
                            state           = 30;    // NOP TODO: We shouldn't need this to be pumped thru.
                        }
                        else
                        {
                            numberOfBytes   = currentCmd;   // number of bytes to transfer.
                        }
                    }
                }
                break;
            
            case 40: 
                SetSCLHigh(outputValue);    // SCL is not already high from previous.
                SetSDAHigh(outputValue);    // SDA is not already high from previous.
                state   = 41;
                break;

            case 41: 
                SetSDALow(outputValue);    // SCL is already high from previous. Generate START condition (-ve edge on SDA while SCL high)
                state   = 42;
                break;

            case 42: 
                SetSCLLow(outputValue);
                state   = 30;
                break;

            case 2:             // bit 7
                SET_SDA_ACCORDING_TO_BIT_NUMBER( 0x80 );
                state   = 3;
                break;

            case 3: 
                SetSCLHigh(outputValue);
                state   = 4;
                break;

            case 4: 
                SetSCLLow(outputValue);
                state   = 5;
                break;

            case 5:             // bit 6
                SET_SDA_ACCORDING_TO_BIT_NUMBER( 0x40 );
                state   = 6;
                break;

            case 6: 
                SetSCLHigh(outputValue);
                state   = 7;
                break;

            case 7: 
                SetSCLLow(outputValue);
                state   = 8;
                break;

            case 8:             // bit 5
                SET_SDA_ACCORDING_TO_BIT_NUMBER( 0x20 );
                state   = 9;
                break;

            case 9: 
                SetSCLHigh(outputValue);
                state   = 10;
                break;

            case 10: 
                SetSCLLow(outputValue);
                state   = 11;
                break;

            case 11:             // bit 4
                SET_SDA_ACCORDING_TO_BIT_NUMBER( 0x10 );
                state   = 12;
                break;

            case 12: 
                SetSCLHigh(outputValue);
                state   = 13;
                break;

            case 13: 
                SetSCLLow(outputValue);
                state   = 14;
                break;

            case 14:             // bit 3
                SET_SDA_ACCORDING_TO_BIT_NUMBER( 0x08 );
                state   = 15;
                break;

            case 15: 
                SetSCLHigh(outputValue);
                state   = 16;
                break;

            case 16: 
                SetSCLLow(outputValue);
                state   = 17;
                break;

            case 17:             // bit 2
                SET_SDA_ACCORDING_TO_BIT_NUMBER( 0x04 );
                state   = 18;
                break;

            case 18: 
                SetSCLHigh(outputValue);
                state   = 19;
                break;

            case 19: 
                SetSCLLow(outputValue);
                state   = 20;
                break;

            case 20:             // bit 1
                SET_SDA_ACCORDING_TO_BIT_NUMBER( 0x02 );
                state   = 21;
                break;

            case 21: 
                SetSCLHigh(outputValue);
                state   = 22;
                break;

            case 22: 
                SetSCLLow(outputValue);
                state   = 23;
                break;

            case 23:             // bit 0
                SET_SDA_ACCORDING_TO_BIT_NUMBER( 0x01 );
                state   = 24;
                break;

            case 24: 
                SetSCLHigh(outputValue);
                state   = 25;
                break;

            case 25: 
                SetSCLLow(outputValue);
                state   = 26;
                break;

            case 26:             // ACK bit
                // stop driving SDA so we can detect ACK state in next state.
                SetSCLHigh(outputValue);
                SetSDALow(outputValue);
                //SetSDAHigh(outputValue);
                state   = 27;
                break;

            case 27:             
                SetSCLLow(outputValue);
                //SetSDAHigh(outputValue);
                ack     = currentLevel;
                // drive SDA again now we have detected ACK.
                state   = 30;
                break;

            case 28:            // STOP condition.   SDA +ve edge while SCL high.
                SetSCLHigh(outputValue);
                state   = 29;
                break;

            case 29:            // STOP condition.   SDA +ve edge while SCL high.
                SetSDAHigh(outputValue);
                state   = 30;
                break;

            case 31:
                break;
        }
    }