Problem With Local Bytes

While working on my I2C routines, I did this test
pub main() | device, addr, slaveid, last, byte s, m, h

  setup()
  
  ' write 23:59:45 to rtc
  
  s := $45
  m := $59
  h := $23
  
  i2c.start()
  i2c.write($D0)
  i2c.write($00)
  i2c.wr_block(@s, 3)
  i2c.stop()
  
  last := -1
  
  repeat
    i2c.start()
    i2c.write($D0)
    i2c.write($00)
    i2c.start()
    i2c.write($D1)
    s := i2c.read(i2c.ACK)
    m := i2c.read(i2c.ACK)
    h := i2c.read(i2c.NAK)
    i2c.stop()
    
    if (s <> last)
      term.tx(term.HOME)
      term.fstr3(string("%2.2x:%2.2x:%2.2x"), h, m, s)
      last := s
      
    waitms(50)
Only the seconds and minutes are written to the clock -- hours gets 0.

If I change to this:
pub main() | device, addr, slaveid, last, time, byte s, m, h

  setup()
  
  ' write 23:59:45 to rtc
  
  time := $23_59_45
  
  i2c.start()
  i2c.write($D0)
  i2c.write($00)
  i2c.wr_block(@time, 3)
  i2c.stop()
  
  last := -1
  
  repeat
    i2c.start()
    i2c.write($D0)
    i2c.write($00)
    i2c.start()
    i2c.write($D1)
    s := i2c.read(i2c.ACK)
    m := i2c.read(i2c.ACK)
    h := i2c.read(i2c.NAK)
    i2c.stop()
    
    if (s <> last)
      term.tx(term.HOME)
      term.fstr3(string("%2.2x:%2.2x:%2.2x"), h, m, s)
      last := s
      
    waitms(50)
...the complete time is correctly written to the RTC. The only difference is using a local long vs local bytes.

@cgracey Is the a problem with PNut? I'm using v34n.

Comments

  • Dave HeinDave Hein Posts: 6,007
    edited 2020-03-18 - 17:51:30
    Are m and h bytes also? Maybe you have to explicitly declare them as bytes like you did for s.
  • Local variables declared after PUB are always longs on the stack. Their least significant bytes are 4 byte adresses apart. So @s gives the adress of s but @m is 4 higher and @h is 8 higher.
  • JonnyMacJonnyMac Posts: 6,595
    edited 2020-03-18 - 18:23:39
    Are m and h bytes also? Maybe you have to explicitly declare them as bytes like you did for s.
    They're supposed to be. I thought, based on the current documentation that everything declared after byte would be a byte. You're right, explicit declaration is required for words and bytes.
    pub main() | device, addr, slaveid, last, byte s, byte m, byte h
    

    Edit: I just did a little test to confirm that the size override must be done per variable. In my original version m and h were longs.

    Local variables declared after PUB are always longs on the stack. Their least significant bytes are 4 byte addresses apart. So @s gives the address of s but @m is 4 higher and @h is 8 higher.
    In Spin2 the default size for locals can be overridden.
  • cgraceycgracey Posts: 12,677
    edited 2020-03-19 - 00:42:23
    It's only worth declaring byte locals if you need a string buffer, or something. The mechanisms to address longs are more efficient.
  • I'll put a note in the documentation that size overrides apply to the next variable, only.
  • I didn't know you could declare local variables as bytes either...

    That is interesting...
Sign In or Register to comment.