This program probes each of the 127 possible devices on TWI.
Initially, onboard LED (Pin 13 on Arduino) is on to indicate probe is working. If the loop has completed successfully, then LED will turn off. If it stays on, the most probable case is TWINT is not being set.
There is another LED (Pin 12) that indicates a device has been found. If that LED stays off, then no device.
NOTE: The example on page 216 of Datasheet depicts TWSTO needing to be combined with TWINT & TWEN. This causes this routine to crash and LED on Pin 12 never lights.
I've tested this with 1602LCD display and all I can say is that removing SCL, LED 12 does not lite, so I'm going to assume routine is passing a valid device back to caller.
.equ TW_START = 0x08
.equ TW_STARTR = 0x10
.equ TW_SLAW_ACK = 0x18
.equ TW_SLAW_NACK = 0x20
.equ TW_DATAW_ACK = 0x28
.equ TW_DATAW_NACK = 0x30
.equ TW_SLAW_NOARB = 0x38
.def Dev_Addr = R20
; =============================================================================================
; Poll control register until TWINT
TWI_Wait: lds TEMP, TWCR ; Read control register @ 0xBC
sbrs TEMP, TWINT ; Test TWINT
rjmp TWI_Wait ; Continue till bit is on
; Read status register and strip prescaler from it.
lds TEMP, TWSR
andi TEMP, 0xF8
ret
; Onboard LED staying on indicates we're stuck somewhere in ProbeJ0 loop
TWI_Probe: sbi PORTB, PINB5 ; Turn onboard LED on
clr Dev_Addr
; Subtracting or adding Dev_Addr by 2 satisfies the requirement bit 0 be off for
; writing operations and bits 7 - 1 have the addresses 7F - 01.
ProbeJ0: subi Dev_Addr, 2
breq ProbeEx
; Being by sending start.
ldi TEMP, (1 << TWINT) | (1 << TWSTA) | (1 << TWEN)
sts TWCR, TEMP
rcall TWI_Wait
cpi TEMP, TW_START
brne ProbeEx
; Dev_Addr is already initialized for data register.
sts TWDR, Dev_Addr
ldi TEMP, (1 << TWINT) | (1 << TWEN)
sts TWCR, TEMP
rcall TWI_Wait
; Even if we've found a device, interface must be clear.
ldi R17, (1 << TWSTO)
sts TWCR, R17
cpi TEMP, TW_SLAW_ACK
brne ProbeJ0
; NOTE: On the 328P, sending TWEN with TWSTO would make this fail.
sbi PORTB, PINB4 ; Turn on LED attached to pin 12
; Turn onboard LED off and shift Dev_Addr so it has some value between 1 - 127
ProbeEx: cbi PORTB, PINB5 ; Turn off onboard LED
ror Dev_Addr
ret
Next will be implementing my interrupt driven reading/writing and then getting something to display on LCD.
Please PM if you want the complete ASM source or HEX file.