0 Replies - 1830 Views - Last Post: 31 October 2012 - 02:06 PM Rate Topic: -----

#1 ramsmack  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 5
  • Joined: 31-January 11

question about Macro problem arduino, uno board

Posted 31 October 2012 - 02:06 PM

We originally got a truncation error like below, we can get the same error when we comment out the branch in our macro. We made the macro because we assumed it was too long of code. However now we get the error listed below, which goes away if we comment out the branch instruction in our macro. Help with the branch error would be nice, mostly worried about the truncation error.

the error we originally got is like this

compute.s.o: In function `numbDet':
(.text+0x2c6): relocation truncated to fit: R_AVR_7_PCREL against `no symbol'
compute.s.o: In function `numbDet':
(.text+0x2ca): relocation truncated to fit: R_AVR_7_PCREL against `no symbol'
compute.s.o: In function `numbDet':
(.text+0x2ce): relocation truncated to fit: R_AVR_7_PCREL against `no symbol'
compute.s.o: In function `numbDet':
(.text+0x2d2): relocation truncated to fit: R_AVR_7_PCREL against `no symbol'
compute.s.o: In function `numbDet':
(.text+0x2d6): relocation truncated to fit: R_AVR_7_PCREL against `no symbol'
compute.s.o: In function `numbDet':
(.text+0x2da): relocation truncated to fit: R_AVR_7_PCREL against `no symbol'
compute.s.o: In function `numbDet':
(.text+0x2de): relocation truncated to fit: R_AVR_7_PCREL against `no symbol'

we added in the macro and now get this


compute.s: Assembler messages:
compute.s:353: Error: odd address operand: -651
compute.s:353: Error: operand out of range: -327
compute.s:360: Error: odd address operand: -675
compute.s:360: Error: operand out of range: -339
compute.s:367: Error: odd address operand: -699
compute.s:367: Error: operand out of range: -351



#
# I2C interface is wired to Arduino PORTC bits
# 4 and 5, with 4 being data and 5 being clock,
# so these symbols give us the values needed
#
      .set PORTC,0x08
      .set DDIRC,0x07
      .set PINC, 0x06
      .set SDA,4
      .set SCL,5

#
# I2C addresses of the components:
#  7-segment LED: 0x70
#  Digital Thermometer: 0x92
#  EEPROM: 0xA0

#
# Global data (none)
#
    .data
    .comm    tempV1, 1
    .global  tempV1
    .comm    tempV2, 1
    .global  tempV2
     


# external symbol (delayMicroseconds function)
    .extern delayMicroseconds

#
# Program code
#
     .text
     .global setupTherm
     .global readTherm
     .global displayTemp
     .global readI2CByte
     .global readI2CByte
     
     
     
setupTherm: 
      ; set pins to output mode
      sbi   DDIRC,SDA
      sbi   DDIRC,SCL
      call  delay1          ; wait to make sure PORTC ready
      call  startBit        ; send start bit
      call  sendAddress     ; send thermometer address
      call  sendWrite       ; send write command
      call  sendInst        ; send instruction
      call  stopBit         ; send stop bit
      call  delay1          ; wait to allow settling
      call  startBit        ; send start bit
      call  sendAddress     ; send thermometer address
      call  sendRead        ; send read command
      call  stopBit         ; send stop bit      
      ret                   ; all done, return to main program!

readTherm: 
      ; set pins to output mode
      sbi   DDIRC,SDA
      sbi   DDIRC,SCL
      call  delay1          ; wait to make sure PORTC ready
      call  startBit        ; send start bit
      call  sendAddress2    ; send thermometer address plus read bit
      call  readI2CByte
      mov   r23, r24        ;Copy the return value to another register
      call  readI2CByte     
      call  stopBit         ; send stop bit
      call  delay1          ; wait to allow settling
      sts   tempV1, r23      
      sts   tempV2, r24
      
      ret                   ; all done, return to main program!
      
      
displayTemp: 
      ; set pins to output mode
      sbi   DDIRC,SDA
      sbi   DDIRC,SCL
      lds   r23, tempV1
      lds   r24, tempV2
      call  delay1                ; wait to make sure PORTC ready
      call  startBit              ; send start bit
      call  sendDisplayAddress    ; send 7SEG address
      call  sendDisplayInst       ; send instruction
      call  sendControl           ; send control params
      call  shownone                 ;\
      call  tens                  ; send 4 data bytes 
      call  ones                  ;   for the 4 display digits
      call  tenths                ;/
      call  stopBit               ; send stop bit
      call  delay1                ; wait to allow settling
      ret                         ; all done, return to main program!
# 

# Delay for creating our clock period (50usec delay) 
     
#
delay1:
  push  r18  
  push  r19       
  push  r20       
  push  r22   
  push  r24  
  ldi   r24, 50       
  ldi   r25, 0       
  call  delayMicroseconds       
  pop   r24
  pop   r22       
  pop   r20       
  pop   r19       
  pop   r18       
  ret 

#
# I2C startbit: a high-to-low transition on SDA while clock is high
# 
startBit:
      cbi   PORTC,SCL    ; set clock low
      call  delay1
      sbi   PORTC,SDA    ; set data bit high
      call  delay1
      sbi   PORTC,SCL    ; set clock high
      call  delay1       ; leave clock high long enough
      cbi   PORTC,SDA    ; set data bit high (this causes the transition)
      call  delay1       ; keep clock high for a while
      cbi   PORTC,SCL    ; finally bring clock low
      call  delay1       ; leave clock low for long enough
      ret

#
# I2C stopbit: a low-to-high transition on SDA while clock is high
#
stopBit:
      sbi   PORTC,SCL    ; set clock high
      call  delay1       ; leave clock high long enough
      sbi   PORTC,SDA    ; set data bit high (this causes the transition)
      call  delay1       ; keep clock high for a while
      cbi   PORTC,SCL    ; finally bring clock low
      call  delay1
      cbi   PORTC,SDA    ; bring data line low
      call  delay1       ; leave clock low for long enough
      ret

#
# I2C 1 bit transmission: SDA high while clock is high
# 
oneBit:
      sbi   PORTC,SDA    ; set data bit high
      call  delay1
      sbi   PORTC,SCL    ; set clock high
      call  delay1       ; leave clock high long enough
      cbi   PORTC,SCL    ; finally bring clock low
      call  delay1
      cbi   PORTC,SDA    ; bring data line low
      call  delay1       ; leave clock low for long enough
      ret

#
# I2C 0 bit transmission: SDA low while clock is high
# 
zeroBit:
      cbi   PORTC,SDA    ; set data bit low
      sbi   PORTC,SCL    ; set clock high
      call  delay1       ; leave clock high long enough
      cbi   PORTC,SCL    ; finally bring clock low
      call  delay1       ; leave clock low for long enough
      ret

#
# I2C thermometer with write 0 bit address transmission: must transmit the byte value 0x92
#
sendAddress:
      call  oneBit
      call  zeroBit
      call  zeroBit
      call  oneBit
      call  zeroBit
      call  zeroBit
      call  oneBit
      call  zeroBit
      call  zeroBit     ; for ack clock period
      ret

#
# I2C thermometer with read bit address transmission: must transmit the byte value 0x93
#
sendAddress2:
      call  oneBit
      call  zeroBit
      call  zeroBit
      call  oneBit
      call  zeroBit
      call  zeroBit
      call  oneBit
      call  oneBit
      call  zeroBit     ; for ack clock period
      ret


#
# I2C LED address transmission: must transmit the byte value 0x70
#
sendDisplayAddress:
      call  zeroBit
      call  oneBit
      call  oneBit
      call  oneBit
      call  zeroBit
      call  zeroBit
      call  zeroBit
      call  zeroBit
      call  zeroBit     ; for ack clock period
      ret

#
# Instruction transmit: for us the instruction should be 0x00 
#  - all zeros means data is in order of: ctl d1 d2 d3 d4
#
sendDisplayInst:
      call  zeroBit
      call  zeroBit
      call  zeroBit
      call  zeroBit
      call  zeroBit
      call  zeroBit
      call  zeroBit
      call  zeroBit
      call  zeroBit     ; for ack clock period
      ret

#
# Subcommand (control byte): Must transmit the byte value 0x47
#  - in binary, 01000111
#
sendControl:
      call  zeroBit
      call  oneBit
      call  zeroBit
      call  zeroBit
      call  zeroBit
      call  oneBit
      call  oneBit
      call  oneBit
      call  zeroBit     ; for ack clock period
      ret

#
# Send that we are writing
#
sendWrite:
      call  zeroBit
      call  zeroBit
      call  zeroBit
      call  zeroBit
      call  zeroBit
      call  zeroBit
      call  zeroBit
      call  oneBit
      call  zeroBit     ; for ack clock period
      ret

#
# Send that we are reading
#
sendRead:
      call  zeroBit
      call  zeroBit
      call  zeroBit
      call  zeroBit
      call  zeroBit
      call  zeroBit
      call  zeroBit
      call  zeroBit
      call  zeroBit     ; for ack clock period
      ret

#
# Instruction transmit: for us the instruction should be 0x60 
#  
#
sendInst:
      call  zeroBit
      call  oneBit
      call  oneBit
      call  zeroBit
      call  zeroBit
      call  zeroBit
      call  zeroBit
      call  zeroBit
      call  zeroBit     ; for ack clock period
      ret




# 
# Read a byte from the I2C bus (assumes all initialization has been done, 
# and that the start bit and address have been sent; this only reads one 
# byte (and does the ACK), caller must complete the communication, reading   
# more bytes, sending a stop bit, etc.) 
# - leaves data byte in register r24; does not corrupt any other registers 
#       

  

readI2CByte:       
  push  r20               ; save r20 in case program is using it       
  cbi   PORTC, SDA        ; ensure output is low to switch to input       
  cbi   DDIRC, SDA        ; change SDA pin to input rather than output         
  ldi   r20, 8            ; we're going to read 8 bits       
  clr   r24               ; r24 will hold data byte, so start it at 0 
readLoop:       
  lsl   r24               ; shift the bits we have so far one place to left         
  sbi   PORTC, SCL        ; set clock high       
  call  delay1            ; keep high for a bit, gives time for therm to send bit       
  sbic  PINC, SDA         ; skip next instruction if input bit is 0       
  ori   r24, 0x01         ; input bit is a 1, so put a 1 into data byte          
  cbi   PORTC, SCL        ; set clock low       
  call  delay1            ; keep low for a bit       
  dec   r20               ; decrement our loop counter       
  brne  readLoop          ; if it is still not 0, go back to top of loop 
readDone:       
  sbi   DDIRC, SDA        ; change SDA pin back to output       
  cbi   PORTC, SDA        ; set data line low for ACK       
  sbi   PORTC, SCL        ; start ACK clock period       
  call  delay1            ; hold high       
  cbi   PORTC, SCL        ; set clock low       
  call  delay1            ; hold low       
  pop   r20               ; restore original r20       
  ret                     ; data byte is left in r24 
  
      
.MACRO division p0 p1 p2        ;numerator(returns remainder), denominator, blank(returns quotient)
    clr \p2
    inc \p2
    sub \p0, \p1
    brcc -3
    dec \p2
    add \p0, \p1
.ENDM


tens:
    mov r21, r24
    ldi r20, 10
    division r21,r20,r22
    call zeroBit      ;no decimal
    jmp numbDet
    
ones:
    mov r22, r24
    ldi r20, 10
    division r22, r20, r21
    call oneBit       ;decimal
    jmp numbDet
    
tenths:
    mov r21, r23
    ldi r20, 2
    division r21,r20,r22
    call zeroBit      ;no decimal
    
numbDet:
    dec r22
    BREQ show1
    dec r22
    BREQ show2
    dec r22
    BREQ show3
    dec r22
    BREQ show4
    dec r22
    BREQ show5
    dec r22
    BREQ show6
    dec r22
    BREQ show7
    dec r22
    BREQ show8
    dec r22
    BREQ show9
    rjmp show0
    
      
#
# Transmit a byte that will display a "0"
#
show0:
      call  zeroBit
      call  oneBit
      call  oneBit
      call  oneBit
      call  oneBit
      call  oneBit
      call  oneBit
      call  zeroBit     ; for ack clock period
      ret

#
# Transmit a byte that will display a "1"
#
show1:
      call  zeroBit
      call  zeroBit
      call  zeroBit
      call  zeroBit
      call  oneBit
      call  oneBit
      call  zeroBit
      call  zeroBit     ; for ack clock period
      ret

#
# Transmit a byte that will display a "2"
#
show2:
      call  oneBit
      call  zeroBit
      call  oneBit
      call  oneBit
      call  zeroBit
      call  oneBit
      call  oneBit
      call  zeroBit     ; for ack clock period
     ret
#
# Transmit a byte that will display a "3"
#
show3:
      call  zeroBit
      call  oneBit
      call  zeroBit
      call  oneBit
      call  oneBit
      call  oneBit
      call  oneBit
      call  zeroBit     ; for ack clock period
      ret

#
# Transmit a byte that will display a "4"
#
show4:
      call  oneBit
      call  oneBit
      call  zeroBit
      call  zeroBit
      call  oneBit
      call  oneBit
      call  zeroBit
      call  zeroBit     ; for ack clock period
      ret

#
# Transmit a byte that will display a "5"
#
show5:
      call  oneBit
      call  oneBit
      call  zeroBit
      call  oneBit
      call  oneBit
      call  zeroBit
      call  oneBit
      call  zeroBit     ; for ack clock period
      ret

#
# Transmit a byte that will display a "6"
#
show6:
      call  oneBit
      call  oneBit
      call  oneBit
      call  oneBit
      call  oneBit
      call  zeroBit
      call  oneBit
      call  zeroBit     ; for ack clock period
      ret

#
# Transmit a byte that will display a "7"
#
show7:
      call  zeroBit
      call  zeroBit
      call  zeroBit
      call  zeroBit
      call  oneBit
      call  oneBit
      call  oneBit
      call  zeroBit     ; for ack clock period
      ret

#
# Transmit a byte that will display a "8"
#
show8:
      call  oneBit
      call  oneBit
      call  oneBit
      call  oneBit
      call  oneBit
      call  oneBit
      call  oneBit
      call  zeroBit     ; for ack clock period
      ret
#
# Transmit a byte that will display a "9"
#
show9:
      call  oneBit
      call  oneBit
      call  zeroBit
      call  oneBit
      call  oneBit
      call  oneBit
      call  oneBit
      call  zeroBit     ; for ack clock period
      ret
#
# Transmit a byte that will display a "none"
#
shownone:
      call  zeroBit
      call  zeroBit
      call  zeroBit
      call  zeroBit
      call  zeroBit
      call  zeroBit
      call  zeroBit
      call  zeroBit     ; for ack clock period
      ret






Is This A Good Question/Topic? 0
  • +

Page 1 of 1