uint8_t I2C::read(uint8_t address, uint8_t registerAddress, uint8_t numberBytes, uint8_t *dataBuffer) { bytesAvailable = 0; bufferIndex = 0; if(numberBytes == 0){numberBytes++;} nack = numberBytes - 1; returnStatus = 0; returnStatus = start(); if(returnStatus){return(returnStatus);} returnStatus = sendAddress(SLA_W(address)); if(returnStatus) { if(returnStatus == 1){return(2);} return(returnStatus); } returnStatus = sendByte(registerAddress); if(returnStatus) { if(returnStatus == 1){return(3);} return(returnStatus); } returnStatus = start(); if(returnStatus) { if(returnStatus == 1){return(4);} return(returnStatus); } returnStatus = sendAddress(SLA_R(address)); if(returnStatus) { if(returnStatus == 1){return(5);} return(returnStatus); } for(uint8_t i = 0; i < numberBytes; i++) { if( i == nack ) { returnStatus = receiveByte(0); if(returnStatus == 1){return(6);} if(returnStatus != MR_DATA_NACK){return(returnStatus);} } else { returnStatus = receiveByte(1); if(returnStatus == 1){return(6);} if(returnStatus != MR_DATA_ACK){return(returnStatus);} } dataBuffer[i] = TWDR; bytesAvailable = i+1; totalBytes = i+1; } returnStatus = stop(); if(returnStatus) { if(returnStatus == 1){return(7);} return(returnStatus); } return(returnStatus); }
uint8_t I2C::write(uint8_t address, uint8_t registerAddress, uint8_t *data, uint8_t numberBytes) { returnStatus = 0; returnStatus = start(); if(returnStatus){return(returnStatus);} returnStatus = sendAddress(SLA_W(address)); if(returnStatus) { if(returnStatus == 1){return(2);} return(returnStatus); } returnStatus = sendByte(registerAddress); if(returnStatus) { if(returnStatus == 1){return(3);} return(returnStatus); } for (uint8_t i = 0; i < numberBytes; i++) { returnStatus = sendByte(data[i]); if(returnStatus) { if(returnStatus == 1){return(3);} return(returnStatus); } } returnStatus = stop(); if(returnStatus) { if(returnStatus == 1){return(7);} return(returnStatus); } return(returnStatus); }
uint8_t I2C::write(uint8_t address, uint8_t registerAddress, uint8_t data) { returnStatus = 0; returnStatus = start(); if(returnStatus){return(returnStatus);} returnStatus = sendAddress(SLA_W(address)); if(returnStatus) { if(returnStatus == 1){return(2);} return(returnStatus); } returnStatus = sendByte(registerAddress); if(returnStatus) { if(returnStatus == 1){return(3);} return(returnStatus); } returnStatus = sendByte(data); if(returnStatus) { if(returnStatus == 1){return(3);} return(returnStatus); } returnStatus = stop(); if(returnStatus) { if(returnStatus == 1){return(7);} return(returnStatus); } return(returnStatus); }
int jumpToAddress(int fd, unsigned addr) { if (sendCommand(fd, 0x21)) return -1; if (sendAddress(fd, addr)) return -1; return 0; }
// // Originally, 'endTransmission' was an f(void) function. // It has been modified to take one parameter indicating // whether or not a STOP should be performed on the bus. // Calling endTransmission(false) allows a sketch to // perform a repeated start. // // WARNING: Nothing in the library keeps track of whether // the bus tenure has been properly ended with a STOP. It // is very possible to leave the bus in a hung state if // no call to endTransmission(true) is made. Some I2C // devices will behave oddly if they do not see a STOP. // uint8_t TwoWire::endTransmission(uint8_t sendStop) { /* Set direction to send for sending of address and data. */ uint8_t result = (uint8_t)getWriteError(); if(result != 0) { // reset tx buffer iterator vars txBufferIndex = 0; txBufferLength = 0; // indicate that we are done transmitting transmitting_master = false; return 1; } uint32_t t0 = millis(); while(I2C_HAL_GetStatusFlag(instance, kI2CBusBusy) && !I2C_HAL_IsMaster(instance)) { if(millis() - t0 >= 25) return 4; //timeout } uint16_t slaveAddress; slaveAddress = (txAddress << 1U) & 0x00FFU; bool sent = sendAddress(slaveAddress); //tx buffer also sent by interrupt // reset tx buffer iterator vars txBufferIndex = 0; txBufferLength = 0; // indicate that we are done transmitting transmitting_master = false; clearWriteError(); result = 4; if(sent) //sent without timeout { if(master_state == MASTER_STATE_COMPLETE) { result = 0; } else if(master_state == MASTER_STATE_TX_NAK) //failed { result = (txBufferIndex == 0) ? 2 : 3; //address or data fail sendStop = true; } if(sendStop) { I2C_HAL_SendStop(instance); } } I2C_HAL_SetDirMode(instance, kI2CReceive); return result; }
uint8_t I2C::beginTransmission(uint8_t address) { returnStatusWire = 0; returnStatus = 0; returnStatus = start(); returnStatusWire = returnStatus; if(returnStatus){return(returnStatus);} returnStatus = sendAddress(SLA_W(address)); returnStatusWire = returnStatus; return(returnStatus); }
int writeMemory(int fd, unsigned addr, void *ptr, int len) { unsigned char *data = ptr; while (len > 0) { int xfer = (len > 256) ? 256 : len; if (sendCommand(fd, 0x31)) return -1; if (sendAddress(fd, addr)) return -1; if (sendData(fd, data, xfer)) return -1; data += xfer; len -= xfer; addr += xfer; } return 0; }
int readMemory(int fd, unsigned addr, void *ptr, int len) { unsigned char *data = ptr; while (len > 0) { int xfer = (len > 256) ? 256 : len; fprintf(stderr,"read %04x at %08x -> %p\n", xfer, addr, data); if (sendCommand(fd, 0x11)) return -1; if (sendAddress(fd, addr)) return -1; if (sendLength(fd, xfer)) return -1; if (readData(fd, data, xfer)) return -1; data += xfer; len -= xfer; addr += xfer; } return 0; }
int I2C::ping(uint8_t addr) { returnStatus = 0; returnStatus = start(); if (!returnStatus) { returnStatus = sendAddress(SLA_W(addr)); } if (returnStatus) { if(returnStatus == 1) { return -1; } else { return 0; // no response } } stop(); return 1; }
void I2C::scan() { uint16_t tempTime = timeOutDelay; timeOut(80); uint8_t totalDevicesFound = 0; Serial.println("Scanning for devices...please wait"); Serial.println(); for(uint8_t s = 0; s <= 0x7F; s++) { returnStatus = 0; returnStatus = start(); if(!returnStatus) { returnStatus = sendAddress(SLA_W(s)); } if(returnStatus) { if(returnStatus == 1) { Serial.println("There is a problem with the bus, could not complete scan"); timeOutDelay = tempTime; return; } } else { Serial.print("Found device at address - "); Serial.print(" 0x"); Serial.println(s,HEX); totalDevicesFound++; } stop(); } if(!totalDevicesFound) { Serial.println("No devices found"); } timeOutDelay = tempTime; }
uint8_t I2C::write(uint8_t address, uint16_t registerAddress, uint8_t data, boolean mode) { returnStatus = 0; returnStatus = start(); if(returnStatus){return(returnStatus);} returnStatus = sendAddress(SLA_W(address)); if(returnStatus) { if(returnStatus == 1){return(2);} return(returnStatus); } if (!mode) returnStatus = sendByte(registerAddress); else { returnStatus = sendByte((registerAddress >> 8) & 0x00FF); returnStatus = sendByte(registerAddress & 0x00FF); } if(returnStatus) { if(returnStatus == 1){return(3);} return(returnStatus); } returnStatus = sendByte(data); if(returnStatus) { if(returnStatus == 1){return(3);} return(returnStatus); } returnStatus = stop(); if(returnStatus) { if(returnStatus == 1){return(7);} return(returnStatus); } return(returnStatus); }
uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop) { if(quantity == 0) return 0; uint32_t t0 = millis(); while(I2C_HAL_GetStatusFlag(instance, kI2CBusBusy) && !I2C_HAL_IsMaster(instance)) { if(millis() - t0 >= 25) return 4; //timeout } if(quantity > BUFFER_LENGTH){ quantity = BUFFER_LENGTH; } rxBufferQuantity = quantity; rxBufferIndex = 0; rxBufferLength = 0; uint16_t slaveAddr = (address << 1U) | 1; if(!sendAddress(slaveAddr) || master_state != MASTER_STATE_READ_READY) { I2C_HAL_SendStop(instance); I2C_HAL_SetDirMode(instance, kI2CReceive); return 0; } master_send_stop = sendStop; master_state = MASTER_STATE_IDLE; I2C_HAL_SetDirMode(instance, kI2CReceive); /* Send NAK if only one byte to read. */ if (rxBufferQuantity == 0x1U) { I2C_HAL_SendNak(instance); } else { I2C_HAL_SendAck(instance); } I2C_HAL_ReadByte(instance); t0 = millis(); while(master_state == MASTER_STATE_IDLE) { if(millis() - t0 >= 25) { rxBufferIndex = 0; rxBufferLength = 0; I2C_HAL_SendStop(instance); I2C_HAL_SetDirMode(instance, kI2CReceive); return 0; //timeout } } if(master_state == MASTER_STATE_COMPLETE) { rxBufferIndex = 0; return rxBufferLength; } else { rxBufferIndex = 0; rxBufferLength = 0; rxBufferQuantity = 0; I2C_HAL_SendStop(instance); I2C_HAL_SetDirMode(instance, kI2CReceive); return 0; //timeout } }
void i2cCheckPort(i2cPortData *pPort) { switch(pPort->i2cState) { case I2C_STATE_START: if(!pPort->pConBits->SEN) { // start done - send a read or write address sendAddress(pPort); } break; case I2C_STATE_ADDR: if(!pPort->pStatBits->TRSTAT) { // address send done - did the device ack? if(!pPort->pStatBits->ACKSTAT) { // device ack'd if(pPort->writeSize) { // start writing writeNextByte(pPort); } else { // start reading readNextByte(pPort); } } else { // no ack - do a stop and give up noAck(pPort); } } break; case I2C_STATE_WRITE: if(!pPort->pStatBits->TRSTAT) { // write done - did the device ack? if(!pPort->pStatBits->ACKSTAT) { if(pPort->i2cIndex < pPort->writeSize) { writeNextByte(pPort); } else { // done writing - might need to read if(pPort->readSize) { // repeat start pPort->pConBits->RSEN = 1; pPort->i2cState = I2C_STATE_R_START; } else { i2cStop(pPort); } } } else { noAck(pPort); } } break; case I2C_STATE_R_START: if(!pPort->pConBits->RSEN) { // Repeat start done - back to the address pPort->writeSize = 0; // force a read sendAddress(pPort); } break; case I2C_STATE_READ: if(!pPort->pConBits->RCEN) { // done reading, now do ack pPort->readBuffer[pPort->i2cIndex] = *pPort->pRxReg; pPort->i2cIndex++; pPort->pConBits->ACKDT = (pPort->i2cIndex == pPort->readSize); // NACK on last byte pPort->pConBits->ACKEN = 1; pPort->i2cState = I2C_STATE_READ_ACK; } break; case I2C_STATE_READ_ACK: if(!pPort->pConBits->ACKEN) { // done read ack if(pPort->i2cIndex >= pPort->readSize) { // done receiving i2cStop(pPort); } else { readNextByte(pPort); } } break; case I2C_STATE_STOP: if(!pPort->pConBits->PEN) { // stop condition done pPort->i2cState = I2C_STATE_IDLE; *pPort->pConReg = I2CCON_OFF; // Turn off the I2C } break; default: pPort->i2cState = I2C_STATE_IDLE; break; } }