void i2c_stop(i2c_connection conn) { struct i2c_state *c = (struct i2c_state *) conn; dprintf(("stop mcs %lx\n", HWREG(c->base + I2C_O_MCS))); if (I2CMasterBusBusy(c->base)) { i2c_command(c, I2C_MASTER_CMD_BURST_SEND_FINISH); } }
//Initialize as a master void TwoWire::begin(void) { if(i2cModule == NOT_ACTIVE) { i2cModule = BOOST_PACK_WIRE; } SysCtlPeripheralEnable(g_uli2cPeriph[i2cModule]); //Configure GPIO pins for I2C operation GPIOPinConfigure(g_uli2cConfig[i2cModule][0]); GPIOPinConfigure(g_uli2cConfig[i2cModule][1]); GPIOPinTypeI2C(g_uli2cBase[i2cModule], g_uli2cSDAPins[i2cModule]); GPIOPinTypeI2CSCL(g_uli2cBase[i2cModule], g_uli2cSCLPins[i2cModule]); I2CMasterInitExpClk(MASTER_BASE, F_CPU, false);//max bus speed=400kHz for gyroscope //force a stop condition if(!GPIOPinRead(g_uli2cBase[i2cModule], g_uli2cSCLPins[i2cModule])) forceStop(); //Handle any startup issues by pulsing SCL if(I2CMasterBusBusy(MASTER_BASE) || I2CMasterErr(MASTER_BASE) || !GPIOPinRead(g_uli2cBase[i2cModule], g_uli2cSCLPins[i2cModule])){ uint8_t doI = 0; GPIOPinTypeGPIOOutput(g_uli2cBase[i2cModule], g_uli2cSCLPins[i2cModule]); unsigned long mask = 0; do{ for(unsigned long i = 0; i < 10 ; i++) { SysCtlDelay(F_CPU/100000/3);//100Hz=desired frequency, delay iteration=3 cycles mask = (i%2) ? g_uli2cSCLPins[i2cModule] : 0; GPIOPinWrite(g_uli2cBase[i2cModule], g_uli2cSCLPins[i2cModule], mask); } doI++; }while(I2CMasterBusBusy(MASTER_BASE) && doI < 100); GPIOPinTypeI2CSCL(g_uli2cBase[i2cModule], g_uli2cSCLPins[i2cModule]); if(!GPIOPinRead(g_uli2cBase[i2cModule], g_uli2cSCLPins[i2cModule])) forceStop(); } }
/** * \brief This function reads data from EEPROM. * * \param data Address where data is to be read. * \param length Length of data to be read * \param offset Address of the byte from which data to be read. * * \return None. * * \note This muxing depends on the profile in which the EVM is configured. * EEPROMI2CSetUp Shall be called Before this API is used */ void EEPROMI2CRead(unsigned char *data, unsigned int length, unsigned short offset) { unsigned int idx = 0; /* First send the register offset - TX operation */ I2CSetDataCount(I2C_BASE_ADDR, 2); StatusClear(); I2CMasterControl(I2C_BASE_ADDR, I2C_CFG_MST_TX); I2CMasterStart(I2C_BASE_ADDR); /* Wait for the START to actually occir on the bus */ while (0 == I2CMasterBusBusy(I2C_BASE_ADDR)); I2CMasterDataPut(I2C_BASE_ADDR, (unsigned char)((offset >> 8) & 0xFF)); /* Wait for the Tx register to be empty */ while (0 == I2CMasterIntRawStatusEx(I2C_BASE_ADDR, I2C_INT_TRANSMIT_READY)); /* Push offset out and tell CPLD from where we intend to read the data */ I2CMasterDataPut(I2C_BASE_ADDR, (unsigned char)(offset & 0xFF)); I2CMasterIntClearEx(I2C_BASE_ADDR, I2C_INT_TRANSMIT_READY); while(0 == (I2CMasterIntRawStatus(I2C_BASE_ADDR) & I2C_INT_ADRR_READY_ACESS)); StatusClear(); I2CSetDataCount(I2C_BASE_ADDR, length); /* Now that we have sent the register offset, start a RX operation*/ I2CMasterControl(I2C_BASE_ADDR, I2C_CFG_MST_RX); /* Repeated start condition */ I2CMasterStart(I2C_BASE_ADDR); while (length--) { while (0 == I2CMasterIntRawStatusEx(I2C_BASE_ADDR, I2C_INT_RECV_READY)); data[idx++] = (unsigned char)I2CMasterDataGet(I2C_BASE_ADDR); I2CMasterIntClearEx(I2C_BASE_ADDR, I2C_INT_RECV_READY); } I2CMasterStop(I2C_BASE_ADDR); while(0 == (I2CMasterIntRawStatus(I2C_BASE_ADDR) & I2C_INT_STOP_CONDITION)); I2CMasterIntClearEx(I2C_BASE_ADDR, I2C_INT_STOP_CONDITION); }
uint8_t TwoWire::getRxData(unsigned long cmd) { if (currentState == IDLE) while(I2CMasterBusBusy(MASTER_BASE)); HWREG(MASTER_BASE + I2C_O_MCS) = cmd; while(I2CMasterBusy(MASTER_BASE)); uint8_t error = I2CMasterErr(MASTER_BASE); if (error != I2C_MASTER_ERR_NONE) { I2CMasterControl(MASTER_BASE, I2C_MASTER_CMD_BURST_RECEIVE_ERROR_STOP); } else { while(I2CMasterBusy(MASTER_BASE)); rxBuffer[rxWriteIndex] = I2CMasterDataGet(MASTER_BASE); rxWriteIndex = (rxWriteIndex + 1) % BUFFER_LENGTH; } return error; }
uint8_t TwoWire::endTransmission(uint8_t sendStop) { uint8_t error = I2C_MASTER_ERR_NONE; if(TX_BUFFER_EMPTY) return 0; //Wait for any previous transaction to complete while(I2CMasterBusBusy(MASTER_BASE)); while(I2CMasterBusy(MASTER_BASE)); //Select which slave we are requesting data from //false indicates we are writing to the slave I2CMasterSlaveAddrSet(MASTER_BASE, txAddress, false); while(I2CMasterBusy(MASTER_BASE)); unsigned long cmd = RUN_BIT | START_BIT; error = sendTxData(cmd,txBuffer[txReadIndex]); txReadIndex = (txReadIndex + 1) % BUFFER_LENGTH; if(error) return error; while(!TX_BUFFER_EMPTY) { error = sendTxData(RUN_BIT,txBuffer[txReadIndex]); txReadIndex = (txReadIndex + 1) % BUFFER_LENGTH; if(error) return getError(error); } if(sendStop) { while(I2CMasterBusy(MASTER_BASE)); HWREG(MASTER_BASE + I2C_O_MCS) = STOP_BIT; while(I2CMasterBusy(MASTER_BASE)); currentState = IDLE; } else { currentState = MASTER_TX; } // indicate that we are done transmitting transmitting = 0; return error; }
bool I2CGenIsNotIdle() { return !I2CMasterBusBusy(I2C0_BASE); }