PAT9125_I2C: accept either NACK or ACK in receive

Both would be technically correct.
This commit is contained in:
Yuri D'Elia 2020-08-25 11:58:48 +02:00
parent d8a8837938
commit e37cdab38f

View file

@ -57,34 +57,52 @@ void twi_disable(void)
digitalWrite(SCL, 0); digitalWrite(SCL, 0);
} }
uint8_t twi_waitfor(uint8_t status) static void twi_wait()
{ {
while(!(TWCR & _BV(TWINT))); while(!(TWCR & _BV(TWINT)));
return (TW_STATUS != status);
} }
uint8_t twi_rw8(uint8_t address, uint8_t mode, uint8_t* data) uint8_t twi_rw8(uint8_t address, uint8_t mode, uint8_t* data)
{ {
// send start condition // send start condition
TWCR = _BV(TWEN) | _BV(TWINT) | _BV(TWSTA); TWCR = _BV(TWEN) | _BV(TWINT) | _BV(TWSTA);
if(twi_waitfor(TW_START)) twi_wait();
if(TW_STATUS != TW_START)
return 1; return 1;
// send address // send address
TWDR = mode; TWDR = mode;
TWDR |= (address << 1); TWDR |= (address << 1);
TWCR = _BV(TWEN) | _BV(TWINT); TWCR = _BV(TWEN) | _BV(TWINT);
if(twi_waitfor(mode == TW_READ? TW_MR_SLA_ACK: TW_MT_SLA_ACK)) twi_wait();
return 2;
// send or receive data
if(mode == TW_WRITE) if(mode == TW_WRITE)
{
if(TW_STATUS != TW_MT_SLA_ACK)
return 2;
// send data
TWDR = *data; TWDR = *data;
TWCR = _BV(TWEN) | _BV(TWINT); TWCR = _BV(TWEN) | _BV(TWINT);
if(twi_waitfor(mode == TW_READ? TW_MR_DATA_NACK: TW_MT_DATA_ACK)) twi_wait();
return 3; if(TW_STATUS != TW_MT_DATA_ACK)
if(mode == TW_READ) return 3;
}
else
{
if(TW_STATUS != TW_MR_SLA_ACK)
return 2;
// receive data
TWCR = _BV(TWEN) | _BV(TWINT);
twi_wait();
// accept ACK or NACK (since only 1 byte is read)
if(!(TW_STATUS & TW_MR_DATA_ACK))
return 3;
*data = TWDR; *data = TWDR;
}
// send stop // send stop
TWCR = _BV(TWEN) | _BV(TWINT) | _BV(TWSTO); TWCR = _BV(TWEN) | _BV(TWINT) | _BV(TWSTO);