void ResetI2C(void){ int i=0; int j=0; I2CEnable(I2C1, FALSE); TRISBSET = 0x0200; if(PORTDbits.RD9==0){ sprintf(NU32_RS232OutBuffer,"Bus is low...\r\n"); WriteString(UART2,NU32_RS232OutBuffer); } TRISDCLR = 0x0400; while(PORTDbits.RD9==0){ LATDbits.LATD10=!LATDbits.LATD10; sprintf(NU32_RS232OutBuffer,"Pulsing SCK...\r\n"); WriteString(UART2,NU32_RS232OutBuffer); ShortDelay(400000); } sprintf(NU32_RS232OutBuffer,"SDA high...\r\n"); WriteString(UART2,NU32_RS232OutBuffer); TRISDSET = 0x0400; ShortDelay(10000); I2CEnable(I2C1, TRUE); ShortDelay(50000); I2Cstopevent(); }
/** * \brief manages reference count on given bus and releases resource if no more refences exist * * \param[in] hal_data - opaque pointer to hal data structure - known only to the HAL implementation * * \return ATCA_STATUS */ ATCA_STATUS hal_i2c_release(void *hal_data) { ATCAI2CMaster_t *hal = (ATCAI2CMaster_t*)hal_data; i2c_bus_ref_ct--; // track total i2c bus interface instances for consistency checking and debugging // if the use count for this bus has gone to 0 references, disable it. protect against an unbracketed release if (hal && --(hal->ref_ct) <= 0 && i2c_hal_data[hal->bus_index] != NULL) { I2CEnable(hal->id, FALSE); free(i2c_hal_data[hal->bus_index]); i2c_hal_data[hal->bus_index] = NULL; } return ATCA_SUCCESS; }
//***************************************************************************** // //! \brief xi2c 001 test execute main body. //! //! \return None. // //***************************************************************************** static void xI2C001Execute(void) { I2CMasterInit(ulMaster, 400000); I2CEnable(ulMaster); I2CMasterWriteS1(ulMaster, 0x12, 'a', xfalse); I2CMasterWriteS2(ulMaster, 'b', xfalse); I2CMasterWriteS2(ulMaster, 'c', xfalse); I2CMasterWriteS2(ulMaster, 'd', xfalse); I2CMasterReadBufS1(ulMaster, 0x12, ucTemp, 5, xtrue); TestAssert(ucTemp[0] == 'a', "xi2c, \"I2C send or receive\" error!"); TestAssert(ucTemp[1] == 'b', "xi2c, \"I2C send or receive\" error!"); TestAssert(ucTemp[2] == 'c', "xi2c, \"I2C send or receive\" error!"); TestAssert(ucTemp[3] == 'd', "xi2c, \"I2C send or receive\" error!"); }
void I2C1update(void) { if (I2C1STAT & 0x0400) { // bus collision i2c1Mode = I2C1_MODE_ERROR; i2c1BusState = I2C1_BUS_ERROR; I2CEnable(I2C1, FALSE); } if (i2c1Delay) { i2c1Delay--; return; } if (i2c1Mode == I2C1_MODE_IDLE) { if (i2c1QueueRd != i2c1QueueWr) { // show that I2C1 is busy i2c1Mode = I2C1_MODE_WRITE; // clear the write and read indices i2c1Queue[i2c1QueueRd].wi = 0; i2c1Queue[i2c1QueueRd].ri = 0; // start I2C1 transfer i2c1BusState = I2C1_BUS_WR_DATA; I2C1CONSET = _I2CCON_SEN_MASK; } } // I2C1_IDLE else if (i2c1Mode == I2C1_MODE_WRITE_COMPLETE) { I2C1process(); i2c1QueueRd++; if (i2c1QueueRd >= I2C1_QUEUE_SIZE) { i2c1QueueRd = 0; } i2c1Mode = I2C1_MODE_IDLE; } // I2C1_WRITE_COMPLETE else if (i2c1Mode == I2C1_MODE_READ_COMPLETE) { I2C1process(); i2c1QueueRd++; if (i2c1QueueRd >= I2C1_QUEUE_SIZE) { i2c1QueueRd = 0; } i2c1Mode = I2C1_MODE_IDLE; } // I2C1_READ_COMPLETE else if (i2c1Mode == I2C1_MODE_ERROR) { // usually caused is SDA is low before start if (!(PORTA & PA_SCL1)) { // is clock is low, raise it PORTSetPinsDigitalOut(IOPORT_A, PA_SCL1); PORTSetBits(IOPORT_A, PA_SCL1); } else { if (!(PORTA & PA_SDA1)) { // if SDA is still low, try another clock pulse PORTSetPinsDigitalOut(IOPORT_A, PA_SCL1); PORTClearBits(IOPORT_A, PA_SCL1); } else { // SDA is now high, try clearing the error PORTSetPinsDigitalOut(IOPORT_A, PA_SDA1); PORTClearBits(IOPORT_A, PA_SDA1); i2c1Mode = I2C1_MODE_ERR_START; } } } else if (i2c1Mode == I2C1_MODE_ERR_START) { PORTSetBits(IOPORT_A, PA_SDA1); i2c1Mode = I2C1_MODE_ERR_STOP; } else if (i2c1Mode == I2C1_MODE_ERR_STOP) { I2C1STAT &= ~0x400; IFS0 &= ~0x20000000; PORTSetPinsDigitalIn(IOPORT_A, PA_SCL1 | PA_SDA1); I2CEnable(I2C1, TRUE); i2c1Mode = I2C1_MODE_IDLE; } } // I2C1update()
int main(void) { UINT8 i2cData[10]; I2C_7_BIT_ADDRESS SlaveAddress; int Index; int DataSz; UINT32 actualClock; BOOL Acknowledged; BOOL Success = TRUE; UINT8 i2cbyte; // Initialize debug messages (when supported) DBINIT(); // Set the I2C baudrate actualClock = I2CSetFrequency(EEPROM_I2C_BUS, GetPeripheralClock(), I2C_CLOCK_FREQ); if ( abs(actualClock-I2C_CLOCK_FREQ) > I2C_CLOCK_FREQ/10 ) { DBPRINTF("Error: I2C1 clock frequency (%u) error exceeds 10%%.\n", (unsigned)actualClock); } // Enable the I2C bus I2CEnable(EEPROM_I2C_BUS, TRUE); // // Send the data to EEPROM to program one location // // Initialize the data buffer I2C_FORMAT_7_BIT_ADDRESS(SlaveAddress, EEPROM_ADDRESS, I2C_WRITE); i2cData[0] = SlaveAddress.byte; i2cData[1] = 0x05; // EEPROM location to program (high address byte) i2cData[2] = 0x40; // EEPROM location to program (low address byte) i2cData[3] = 0xAA; // Data to write DataSz = 4; // Start the transfer to write data to the EEPROM if( !StartTransfer(FALSE) ) { while(1); } // Transmit all data Index = 0; while( Success && (Index < DataSz) ) { // Transmit a byte if (TransmitOneByte(i2cData[Index])) { // Advance to the next byte Index++; // Verify that the byte was acknowledged if(!I2CByteWasAcknowledged(EEPROM_I2C_BUS)) { DBPRINTF("Error: Sent byte was not acknowledged\n"); Success = FALSE; } } else { Success = FALSE; } } // End the transfer (hang here if an error occured) StopTransfer(); if(!Success) { while(1); } // Wait for EEPROM to complete write process, by polling the ack status. Acknowledged = FALSE; do { // Start the transfer to address the EEPROM if( !StartTransfer(FALSE) ) { while(1); } // Transmit just the EEPROM's address if (TransmitOneByte(SlaveAddress.byte)) { // Check to see if the byte was acknowledged Acknowledged = I2CByteWasAcknowledged(EEPROM_I2C_BUS); } else { Success = FALSE; } // End the transfer (stop here if an error occured) StopTransfer(); if(!Success) { while(1); } } while (Acknowledged != TRUE); // // Read the data back from the EEPROM. // // Initialize the data buffer I2C_FORMAT_7_BIT_ADDRESS(SlaveAddress, EEPROM_ADDRESS, I2C_WRITE); i2cData[0] = SlaveAddress.byte; i2cData[1] = 0x05; // EEPROM location to read (high address byte) i2cData[2] = 0x40; // EEPROM location to read (low address byte) DataSz = 3; // Start the transfer to read the EEPROM. if( !StartTransfer(FALSE) ) { while(1); } // Address the EEPROM. Index = 0; while( Success & (Index < DataSz) ) { // Transmit a byte if (TransmitOneByte(i2cData[Index])) { // Advance to the next byte Index++; } else { Success = FALSE; } // Verify that the byte was acknowledged if(!I2CByteWasAcknowledged(EEPROM_I2C_BUS)) { DBPRINTF("Error: Sent byte was not acknowledged\n"); Success = FALSE; } } // Restart and send the EEPROM's internal address to switch to a read transfer if(Success) { // Send a Repeated Started condition if( !StartTransfer(TRUE) ) { while(1); } // Transmit the address with the READ bit set I2C_FORMAT_7_BIT_ADDRESS(SlaveAddress, EEPROM_ADDRESS, I2C_READ); if (TransmitOneByte(SlaveAddress.byte)) { // Verify that the byte was acknowledged if(!I2CByteWasAcknowledged(EEPROM_I2C_BUS)) { DBPRINTF("Error: Sent byte was not acknowledged\n"); Success = FALSE; } } else { Success = FALSE; } } // Read the data from the desired address if(Success) { if(I2CReceiverEnable(EEPROM_I2C_BUS, TRUE) == I2C_RECEIVE_OVERFLOW) { DBPRINTF("Error: I2C Receive Overflow\n"); Success = FALSE; } else { while(!I2CReceivedDataIsAvailable(EEPROM_I2C_BUS)); i2cbyte = I2CGetByte(EEPROM_I2C_BUS); } } // End the transfer (stop here if an error occured) StopTransfer(); if(!Success) { while(1); } // Validate the data read if( i2cbyte != 0xAA ) { DBPRINTF("Error: Verify failed\n"); } else { DBPRINTF("Success\n"); } // Example complete while(1); }
//the next few functions are general for i2c //all these functions were stolen from Kralick_Lab4 void initI2CBus(I2C_MODULE id, int pBusFrq, int i2cFrq){ I2CConfigure(id, 0); I2CSetFrequency(id, pBusFrq, i2cFrq); I2CEnable(id, TRUE); }
//Turn on I2C Module and calibrate for standard operation. void I2Cinitialize(void){ I2CSetFrequency(I2C1, SYS_FREQ, I2C_CLOCK_FREQ); I2CEnable(I2C1, TRUE); }