From bda476fc34d709b321aeea25a6bcf86754d343da Mon Sep 17 00:00:00 2001 From: Uri Shaked Date: Thu, 15 Apr 2021 19:44:42 +0300 Subject: [PATCH] fix(twi): broken repeated start #91 fix #91 --- src/peripherals/twi.spec.ts | 25 +++++++++++++++++++++++++ src/peripherals/twi.ts | 2 +- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/peripherals/twi.spec.ts b/src/peripherals/twi.spec.ts index 2628b57..342d611 100644 --- a/src/peripherals/twi.spec.ts +++ b/src/peripherals/twi.spec.ts @@ -68,6 +68,31 @@ describe('TWI', () => { expect(twi.eventHandler.start).toHaveBeenCalledWith(false); }); + it('should connect successfully in case of repeated start (issue #91)', () => { + const cpu = new CPU(new Uint16Array(1024)); + const twi = new AVRTWI(cpu, twiConfig, FREQ_16MHZ); + + // Start condition + cpu.writeData(TWCR, TWINT | TWSTA | TWEN); + cpu.cycles++; + cpu.tick(); + + // Repeated start + jest.spyOn(twi.eventHandler, 'start'); + cpu.writeData(TWCR, TWINT | TWSTA | TWEN); + cpu.cycles++; + cpu.tick(); + expect(twi.eventHandler.start).toHaveBeenCalledWith(true); + + // Now try to connect... + jest.spyOn(twi.eventHandler, 'connectToSlave'); + cpu.writeData(TWDR, 0x80); // Address 0x40, write mode + cpu.writeData(TWCR, TWINT | TWEN); + cpu.cycles++; + cpu.tick(); + expect(twi.eventHandler.connectToSlave).toHaveBeenCalledWith(0x40, true); + }); + it('should successfully transmit a byte to a slave', () => { // based on the example in page 225 of the datasheet: // https://ww1.microchip.com/downloads/en/DeviceDoc/ATmega48A-PA-88A-PA-168A-PA-328-P-DS-DS40002061A.pdf diff --git a/src/peripherals/twi.ts b/src/peripherals/twi.ts index f74001c..0dd8377 100644 --- a/src/peripherals/twi.ts +++ b/src/peripherals/twi.ts @@ -119,7 +119,7 @@ export class AVRTWI { this.eventHandler.start(status !== STATUS_TWI_IDLE); } else if (value & TWCR_TWSTO) { this.eventHandler.stop(); - } else if (status === STATUS_START) { + } else if (status === STATUS_START || status === STATUS_REPEATED_START) { this.eventHandler.connectToSlave(twdrValue >> 1, twdrValue & 0x1 ? false : true); } else if (status === STATUS_SLAW_ACK || status === STATUS_DATA_SENT_ACK) { this.eventHandler.writeByte(twdrValue);