[CODE][ASM] TWI Probe for single unknown device

1 post / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I've concocted this little snippet together as there are so many bricks available now, but they come with little or no information, especially what their address is. This routine will cycle through all 127 possibilities and if one is found, LED attached to PIN 12 (Arduino) will turn on, otherwise it will remain off.  While in the procedure, PIN 13 (Arduino onboard LED) will illuminate and if it stays on, there something has gone wrong.

 

Arduino          Indicator         Onboard

                         OFF                OFF                No device found

                          ON                OFF                Device found

                         OFF                 ON                Probably stuck polling TWINT

 

I realize there are libraries and other sources out there, but for me, this level of intimacy enhances my understanding of the hardware, and that is the ultimate goal.  On that note, I did experience something that is contrary to Datasheet and the examples show TWSTO being combined with TWEN. Now the examples do note single shot, which leads me to think, maybe after everything is said and done, stop should be enabled.  Don't know.

 

TEMP is defined elsewhere, but it is R16

 

  TWI_Probe: sbi PORTB, PINB5  ; Onboard LED = ON
                clr Dev_Addr  ; Initialize address to NULL 

        ; 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  ; Shift so range is 7F - 01
                ret
                
; *-------* Poll control register until TWINT
        
        ; If onboard LED stays on, we are probably stuck between here and RJMP.

  TWI_Wait: lds TEMP, TWCR  ; Read control register @ 0xBC
                sbrs TEMP, TWINT  ; Test TWINT
                rjmp TWI_Wait  ; Continue till bit is on

                lds TEMP, TWSR  ; Grab status
                andi TEMP, 0xF8  ; and strip prescaler bits.
                ret

 

Last Edited: Wed. Aug 17, 2016 - 08:42 PM