Shop OBEX P1 Docs P2 Docs Learn Events
1-wire bus object in 100% Spin — Parallax Forums

1-wire bus object in 100% Spin

scanlimescanlime Posts: 106
edited 2008-08-26 03:05 in Propeller 1
I'm not sure if this has been done already, but if it has, I sure couldn't find it anywhere... Attached is a Dallas/Maxim 1-wire bus interface, written in 100% Spin. It should be drop-in compatible with Cam Thompson's exellent OneWire object.

Why spin? I found myself totally out of spare cogs, but needing to read some DS18B20 1-wire temperature sensors. If you can spare a cog, definitely use Cam's module instead. If you're short on space, though, this one might prove to be useful. What's the catch? Its timing relies on the speed at which the spin interpreter runs (yuck), and I only expect it to work at 80 MHz. The speed and timing accuracy is also a bit sub-optimal. But if you just want to read some temperature sensors or an iButton, it works great.

It implements all of the features of the original OneWire module, including search and CRC-8. It also adds a few extra features, while maintaining backward compatibility.

If this turns out to be useful for anyone, I can stick it in the object exchange.

--Micah

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2008-07-20 02:17
    Micah,
    Are you aware that you can write objects that are clock speed independent (as long as the clock is fast enough for the work to get done on time)? You just have to use the CLKFREQ variable which is set by the compiler based on the _CLKFREQ / _XINFREQ / _CLKMODE constant definitions. If you change the system clock frequency at runtime, you can also change the long value stored at RAM location zero which is what CLKFREQ uses. For example, if you want to wait 1ms, you can do WAITCNT(CLKFREQ / 1000 + CNT). If you want to wait 100us, you can use CLKFREQ / 100. Typically, if your program requires several time intervals, you compute the wait times during your object's initialization and store them in variables.
  • scanlimescanlime Posts: 106
    edited 2008-07-20 02:29
    Mike Green said...
    Micah,
    Are you aware that you can write objects that are clock speed independent (as long as the clock is fast enough for the work to get done on time)? You just have to use the CLKFREQ variable which is set by the compiler based on the _CLKFREQ / _XINFREQ / _CLKMODE constant definitions. If you change the system clock frequency at runtime, you can also change the long value stored at RAM location zero which is what CLKFREQ uses. For example, if you want to wait 1ms, you can do WAITCNT(CLKFREQ / 1000 + CNT). If you want to wait 100us, you can use CLKFREQ / 100. Typically, if your program requires several time intervals, you compute the wait times during your object's initialization and store them in variables.

    Thanks, but I understand how to use the Prop's system clock smile.gif

    There are a couple of delays (the reset pulse) which are long enough to time from Spin using waitcnt, but the primary reason I use a static clock frequency is because the shorter durations are timed out like this:

        if b & 1
          ' Write 1: Low for at least 1us, High for about 40us
          dira[noparse][[/noparse]pin]~~
          dira[noparse][[/noparse]pin]~
          dira[noparse][[/noparse]pin]~
          dira[noparse][[/noparse]pin]~
          dira[noparse][[/noparse]pin]~
          dira[noparse][[/noparse]pin]~
        else
          ' Write 0: Low for 40us
          dira[noparse][[/noparse]pin]~~
          dira[noparse][[/noparse]pin]~~
          dira[noparse][[/noparse]pin]~~
          dira[noparse][[/noparse]pin]~~
          dira[noparse][[/noparse]pin]~~
          dira[noparse][[/noparse]pin]~
    
    



    I can get a delay resolution of about 10us like this, which is shorter than the minimum delay you can get via waitcnt as far as I know.

    If it's possible to make a clock-speed-independent version of this module in Spin, I'd love to do that- but my goal was to give up a little flexibility if necessary so I could have a pure-Spin version of this module and save myself a cog.

    Thanks!
    --Micah
  • scanlimescanlime Posts: 106
    edited 2008-07-20 02:45
    I just tried an experiment:

      repeat
        t := 943
        c1 := cnt + clkfreq/1000
        c2 := c1 + t
        c3 := c2 + t
        c4 := c3 + t
    
        waitcnt(c1)
        dira[noparse][[/noparse]pin]~~
        waitcnt(c2)
        dira[noparse][[/noparse]pin]~
        waitcnt(c3)
        dira[noparse][[/noparse]pin]~~
        waitcnt(c4)
        dira[noparse][[/noparse]pin]~
    
    



    If I precalculate all waitcnt times, leaving just the code to set a pin (using a variable for the pin number), the fastest I can go is 943 cycles between waitcnts. That's 11.8us at 80 MHz. Not bad, and it might be good enough for 1-wire, but it really doesn't leave any headroom. If the clock was running any slower, you'd hang due to a missed waitcnt. For comparison, if I remove the waitcnt calls above, I get 7us between pin toggles.

    So.. I think I could convert SpinOneWire to use calculated waitcnt()s all around, but there's little enough 'wiggle room' in the timing that it would still be unlikely to work at any clock frequency other than 80 MHz. Doesn't seem like it would be worth the effort.

    --Micah
  • KenFordhamKenFordham Posts: 12
    edited 2008-07-20 04:52
    Thanks for posting that, Micah. It works very well.

    Ken
  • Timothy D. SwieterTimothy D. Swieter Posts: 1,613
    edited 2008-07-20 06:53
    Micah, I recommend posting the object in the Object Exchange.· You never know who will need it in the future and go looking for it.· The Object Exchange should be the clearing house for all usuable objects like this.· Don't worry if you still want to improve it, if it works in its current state that is great.· When/if you make an improved version you can update the object in the exchange.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Timothy D. Swieter, E.I.

    www.brilldea.com·- Prop Blade, LED Painter, RGB LEDs, uOLED-IOC
    www.sxmicro.com - a blog·exploring the SX micro
    www.tdswieter.com
  • scanlimescanlime Posts: 106
    edited 2008-07-20 20:18
    Posted it. Thanks!
  • hippyhippy Posts: 1,981
    edited 2008-07-21 13:22
    Slightly off-topic but related ...

    High-speed bit-banging with short timing is one of those things which could often be improved upon by using 'Inline PASM'. That isn't supported at present but will be possible once there's a RAM-based Spin Interpreter. The penalty to pay is the need to include the interpreter code within the image so not a perfect solution for everyone.

    It might be possible to convince Chip & Co to add support for inline PASM to the Prop Mk II Spin Interpreter but I'm not sure how that could be done without opening the door for people to casually dump the ROM Spin Interpreter code and bypass the encryption mechanisms.
  • ElectricAyeElectricAye Posts: 4,561
    edited 2008-08-26 03:05
    Micah,
    thanks for posting this on the Object Exchange. It's been a big, big help!

    Mark

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    It might be the Information Age but the Eon of Ignorance has yet to end.
Sign In or Register to comment.