I have been working for about a week on interfacing I2C for the ATMega4809 as a master with a variety of slave devices. So far, I have been able to successfully implement Master Write functionality, however I keep getting stuck on Master Read. Specifically, I am unable to to successfully read from a slave device. I am familiar with the I2C protocol and have been able to successfully implement both Read and Write on Arduino. I have also isolated the problem with a logic analyzer to the point where the address and read op are acknowledged, but then after that, no valid data is sent. This leads me to believe that the issue is specific to the ATMega4809 itself and maybe I am missing something in regards to the implementation of the various registers and their intricacies. I have attached my Master Initialization and Master Read functions below. Any help would be greatly appreciated.
//TWI Master Initialization void TWI0_init(){ TWI0.MBAUD = (uint8_t)TWI0_BAUD(100000, 1); //Set the MBAUD rate TWI0.MCTRLB |= TWI_FLUSH_bm; // Clear TWI state TWI0.MCTRLA &= ~TWI_TIMEOUT_gm; // Disable Timeout for TWI operation TWI0.MCTRLA |= TWI_ENABLE_bm //enables as master | TWI_WIEN_bm //enables write interrupt | TWI_SMEN_bm //enables smart mode | TWI_RIEN_bm //enables read interrupt | TWI_QCEN_bm; //enables quick command TWI0.MSTATUS |= TWI_BUSSTATE_IDLE_gc; //initially sets the bus state to idle } //TWI Master Read Function void TWI0_read(uint8_t address, uint8_t* buffer, uint8_t length){ //write slave address and write op code as read TWI0.MADDR = (address << 1) | READ_OP; //wait for ACK or NACK from slave while(!(TWI0.MSTATUS & TWI_WIF_bm) && !(TWI0.MSTATUS & TWI_RIF_bm)){;} //makes sure a ACK was received if(!(TWI0.MSTATUS & TWI_RXACK_bm)){ //clears the interrupt bits TWI0.MSTATUS |= (TWI_RIF_bm | TWI_WIF_bm); //holds the location of the buffer uint8_t buffLoc = 0; //reads in data until buffer is full while(length){ if (length == 1){ TWI0.MCTRLB |= TWI_ACKACT_NACK_gc; // Next byte will be last to be received, setup NACK } else{ TWI0.MCTRLB &= ~(1 << TWI_ACKACT_bp); // More bytes to receive, setup ACK } if (--length) { buffer[buffLoc] = TWI0.MDATA; buffLoc++; TWI0.MCTRLB |= TWI_MCMD_RECVTRANS_gc; while(!(TWI0.MSTATUS & TWI_WIF_bm) && !(TWI0.MSTATUS & TWI_RIF_bm)){;} TWI0.MSTATUS |= (TWI_RIF_bm | TWI_WIF_bm); } else{ buffer[buffLoc] = TWI0.MDATA; buffLoc++; TWI0.MCTRLB |= TWI_ACKACT_NACK_gc; TWI0.MCTRLB |= TWI_MCMD_STOP_gc; } } } else{ TWI0.MSTATUS |= TWI_BUSSTATE_IDLE_gc; //resets the bus state TWI0_sendStop(); //sends stop bit } }