ASM: Probe TWI for a single device

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.