// // 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) { uint8_t error = 0; // transmit buffer (blocking) DBG_PRINTF("vAHI_SiMasterWriteSlaveAddr %x\r\n", txAddress); vAHI_SiMasterWriteSlaveAddr(txAddress, false); DBG_PRINTF("bAHI_SiMasterSetCmdReg\r\n"); bool ret = bAHI_SiMasterSetCmdReg(E_AHI_SI_START_BIT, E_AHI_SI_NO_STOP_BIT, E_AHI_SI_NO_SLAVE_READ, E_AHI_SI_SLAVE_WRITE, E_AHI_SI_SEND_ACK, E_AHI_SI_NO_IRQ_ACK); DBG_PRINTF("bAHI_SiPollTransferInProgress\r\n"); while(bAHI_SiPollTransferInProgress()); /* wait while busy */ /* check to see if we get an ACK back*/ DBG_PRINTF("bAHI_SiPollRxNack\r\n"); if(bAHI_SiPollRxNack()) error = 2; // error, got NACK on address transmit if (error == 0) { uint16_t sent = 0; while (sent < txBufferLength) { DBG_PRINTF("sent %d\n", txBuffer[sent]); vAHI_SiMasterWriteData8(txBuffer[sent++]); if(sent == (txBufferLength) ) { vAHI_SiSetCmdReg(E_AHI_SI_NO_START_BIT, E_AHI_SI_STOP_BIT, E_AHI_SI_NO_SLAVE_READ, E_AHI_SI_SLAVE_WRITE, E_AHI_SI_SEND_ACK, E_AHI_SI_NO_IRQ_ACK); } else { vAHI_SiSetCmdReg(E_AHI_SI_NO_START_BIT, E_AHI_SI_NO_STOP_BIT, E_AHI_SI_NO_SLAVE_READ, E_AHI_SI_SLAVE_WRITE, E_AHI_SI_SEND_ACK, E_AHI_SI_NO_IRQ_ACK); } while(bAHI_SiPollTransferInProgress()); /* wait while busy */ /* check to see if we get an ACK back*/ if(bAHI_SiPollRxNack()) { error = 3; // error, got NACK during data transmmit vAHI_SiSetCmdReg(E_AHI_SI_NO_START_BIT, E_AHI_SI_STOP_BIT, E_AHI_SI_NO_SLAVE_READ, E_AHI_SI_NO_SLAVE_WRITE, E_AHI_SI_SEND_ACK, E_AHI_SI_NO_IRQ_ACK); } DBG_PRINTF("sent done %d\n", sent); } } //if (error == 0) { // TWI_Stop(twi); // if (!TWI_WaitTransferComplete(twi, XMIT_TIMEOUT)) // error = 4; // error, finishing up //} txBufferLength = 0; // empty buffer status = MASTER_IDLE; return error; }
uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop) { if (quantity > BUFFER_LENGTH) quantity = BUFFER_LENGTH; DBG_PRINTF("vAHI_SiMasterWriteSlaveAddr %x\r\n", address); vAHI_SiMasterWriteSlaveAddr(address, true); vAHI_SiSetCmdReg(E_AHI_SI_START_BIT, E_AHI_SI_NO_STOP_BIT, E_AHI_SI_NO_SLAVE_READ, E_AHI_SI_SLAVE_WRITE, E_AHI_SI_SEND_ACK, E_AHI_SI_NO_IRQ_ACK); while(bAHI_SiPollTransferInProgress()); /* wait while busy */ // perform blocking read into buffer int readed = 0; do { if(readed == (quantity-1) ) { vAHI_SiSetCmdReg(E_AHI_SI_NO_START_BIT, E_AHI_SI_STOP_BIT, E_AHI_SI_SLAVE_READ, E_AHI_SI_NO_SLAVE_WRITE, E_AHI_SI_SEND_ACK, E_AHI_SI_NO_IRQ_ACK); } else { vAHI_SiSetCmdReg(E_AHI_SI_NO_START_BIT, E_AHI_SI_NO_STOP_BIT, E_AHI_SI_SLAVE_READ, E_AHI_SI_NO_SLAVE_WRITE, E_AHI_SI_SEND_ACK, E_AHI_SI_NO_IRQ_ACK); } while(bAHI_SiPollTransferInProgress()); /* wait while busy */ rxBuffer[readed++] = u8AHI_SiMasterReadData8(); DBG_PRINTF("u8AHI_SiMasterReadData8 %x\r\n", rxBuffer[readed-1]); } while (readed < quantity); // set rx buffer iterator vars rxBufferIndex = 0; rxBufferLength = readed; return readed; }
PROCESS_THREAD(i2c_process, ev, data) { static size_t i; #if (DEBUG==1) static u32_t i2c_ticks; #endif PROCESS_BEGIN(); vAHI_SiRegisterCallback(i2c_irq); vAHI_SiConfigure(true,true,I2C_400KHZ_FAST_MODE); while ((transaction=list_pop(transactions))) { #if (DEBUG==1) printf("i2c: to 0x%x start, %d written, %d read\n", transaction->addr, transaction->wrlen, transaction->rdlen); i2c_ticks = u32AHI_TickTimerRead(); #endif if (transaction->wrlen) { /* send slave address, start condition */ vAHI_SiWriteData8(transaction->addr); vAHI_SiSetCmdReg(E_AHI_SI_START_BIT, E_AHI_SI_NO_STOP_BIT, E_AHI_SI_NO_SLAVE_READ, E_AHI_SI_SLAVE_WRITE, E_AHI_SI_SEND_ACK, E_AHI_SI_NO_IRQ_ACK); PROCESS_YIELD_UNTIL(ev==PROCESS_EVENT_POLL); if (i2c_status==FAIL) { /* we only test for ACK on the first byte! */ if (transaction->cb) transaction->cb(false); #if (DEBUG==1) printf("i2c: to 0x%x failed, %d written, %d read in %d ticks\n", transaction->addr, transaction->wrlen, transaction->rdlen, u32AHI_TickTimerRead() - i2c_ticks); #endif continue; } } /* send wr data. If repeated_start and there is something to read, send no * stop condition, else send a stop condition on the last byte. */ for (i=0; i<transaction->wrlen; i++) { vAHI_SiWriteData8(transaction->buf[i]); vAHI_SiSetCmdReg(E_AHI_SI_NO_START_BIT, (transaction->wrlen!=0) ? E_AHI_SI_NO_STOP_BIT : transaction->rdlen, E_AHI_SI_NO_SLAVE_READ, E_AHI_SI_SLAVE_WRITE, E_AHI_SI_SEND_ACK, E_AHI_SI_NO_IRQ_ACK); PROCESS_YIELD_UNTIL(ev==PROCESS_EVENT_POLL); if (i2c_status==FAIL) { /* we only test for ACK on the first byte! */ if (transaction->cb) transaction->cb(false); #if (DEBUG==1) printf("i2c: to 0x%x failed, %d written, %d read in %d ticks\n", transaction->addr, transaction->wrlen, transaction->rdlen, (uint32_t) u32AHI_TickTimerRead() - i2c_ticks); #endif continue; } } if (transaction->rdlen) { /* send slave addr, start condition */ vAHI_SiWriteData8(transaction->addr|1); vAHI_SiSetCmdReg(E_AHI_SI_START_BIT, E_AHI_SI_NO_STOP_BIT, E_AHI_SI_NO_SLAVE_READ, E_AHI_SI_SLAVE_WRITE, E_AHI_SI_SEND_ACK, E_AHI_SI_NO_IRQ_ACK); PROCESS_YIELD_UNTIL(ev==PROCESS_EVENT_POLL); } /* read data, send stop condition on last byte, send nak on last byte when * end_of_transmission is set.*/ for (i=0; i<transaction->rdlen; i++) { vAHI_SiSetCmdReg(E_AHI_SI_NO_START_BIT, i==transaction->rdlen-1, E_AHI_SI_SLAVE_READ, E_AHI_SI_NO_SLAVE_WRITE, (i==transaction->rdlen-1) ? E_AHI_SI_SEND_NACK : E_AHI_SI_SEND_ACK, E_AHI_SI_NO_IRQ_ACK); PROCESS_YIELD_UNTIL(ev==PROCESS_EVENT_POLL); transaction->buf[transaction->wrlen+i] = u8AHI_SiReadData8(); } #if (DEBUG==1) printf("i2c: to 0x%x completed, %d written, %d read in %d ticks (rd:", transaction->addr, transaction->wrlen, transaction->rdlen, (u32_t) u32AHI_TickTimerRead() - i2c_ticks); for (i=0; i<transaction->rdlen+transaction->wrlen; i++) printf("0x%x,", transaction->buf[i]); printf(")\n"); #endif if (transaction->cb) transaction->cb(i2c_status==SUCCESS); } vAHI_SiConfigure(false,false,0); PROCESS_END(); }