Shop OBEX P1 Docs P2 Docs Learn Events
CRC16 routine problem — Parallax Forums

CRC16 routine problem

Damien AllenDamien Allen Posts: 103
edited 2007-03-19 19:36 in Propeller 1
Hi, i'm new to the prop and programming in general and i've been trying to write a modbus slave object in spin and i'm having trouble generating a correct crc.
I've attached my routine with the test i've been using, it must be something simple. Please can someone point me in the right direction or if i'm re-inventing the wheel as regards the to CRC or modbus object please point me in the direction of that also.

Many thanks

Damo

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2007-03-17 16:11
    For a start, please reread the description of the REPEAT statement in the manual. For example, you wrote "repeat i from i==start to i<bytecnt". That should be "repeat i from 0 to bytecnt-1". Your other statement was "repeat j from j==1 to j=<8" and should be "repeat j from 1 to 8". Beyond that, your crc routine could be a lot simpler, but try it with these changes.
  • Damien AllenDamien Allen Posts: 103
    edited 2007-03-17 16:12
    cheers mike i'll try that

    Edit: that worked!

    Post Edited (Damien Allen) : 3/17/2007 4:18:10 PM GMT
  • Damien AllenDamien Allen Posts: 103
    edited 2007-03-17 16:19
    Mike, when you said that it could be a lot simpler, what did you mean? we you referring to the table lookup method?
    I want the routine to be fast but I am even less proficient in ASM as I am in spin so that is a no-go for me.

    This routine is for modbus messages so i hope it is fast enough.
  • Jeff MartinJeff Martin Posts: 755
    edited 2007-03-17 20:02
    Damien,

    I'm curious, there are a few different forms of CRC16... is this really CRC16-CCITT?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    --Jeff Martin

    · Sr. Software Engineer
    · Parallax, Inc.
  • Mike GreenMike Green Posts: 23,101
    edited 2007-03-17 21:29
    Damien,
    What I meant is that some of your statements could be combined and some of the temporary variables eliminated. Table lookup is also an option and can be done completely in Spin. The "programming guru's advice" is to make it work first, then make it work correctly, then worry about speed.
  • Damien AllenDamien Allen Posts: 103
    edited 2007-03-18 00:26
    Thanks again Mike, i'll work on that later then. For now i'll get the rest of the modbus code working.

    Jeff, I believe it is just CRC-16, the routine roughly stays the same its just the polynomial that changes

    CRC-16 uses $A001 as the poly, whereas CRC16-CCITT uses $8404.

    Does that satisfy your curiousity? smile.gif
  • Mike GreenMike Green Posts: 23,101
    edited 2007-03-18 02:16
    Here's an example of a shorter, simpler routine. It makes use the fact that true is -1 and false is 0.
    PUB crc16(value)
       result := value
       repeat 8
          result := result >> 1 ^ ($A001 & (result & 1 <> 0))
    
    
  • Damien AllenDamien Allen Posts: 103
    edited 2007-03-18 13:00
    I can't get that to work Mike, also my routine has to be able to handle a message as an array
  • Mike GreenMike Green Posts: 23,101
    edited 2007-03-18 14:24
    Sorry, forgot the initial xor:
    PUB crc16(value)
       result := value ^ $FFFF
       repeat 8
          result := result >> 1 ^ ($A001 & (result & 1 <> 0))
    
  • Mike GreenMike Green Posts: 23,101
    edited 2007-03-18 14:31
    For multibyte:
    PUB crc16(buffer,count)
       result := $FFFF
       repeat count
          result ^= byte[noparse][[/noparse]buffer++]
          repeat 8
             result := result >> 1 ^ ($A001 & (result & 1 <> 0))
    
    


    You'd call this with "c := crc16(@data,8)". If you wanted to start at the 6th byte, you'd call "c := crc16(@data+5,8)".
  • Damien AllenDamien Allen Posts: 103
    edited 2007-03-18 14:39
    Cheers Mike thats fantastic!

    is there an easier way to reverse the byte order? the code i am using is below, again probably inelegant and slow but it works

    temp2 := (result >> 8)
    result := (result <<8) | temp2
  • Mike GreenMike Green Posts: 23,101
    edited 2007-03-18 14:52
    How about "result :=( (result >> 8) | (result << 8)) & $FFFF"
  • Damien AllenDamien Allen Posts: 103
    edited 2007-03-18 15:02
    That is perfect, now can i pester you once more for some advice? Please say so if i'm taking up too much of your time i won't be offended [noparse]:)[/noparse]

    My project requires me to have variables available across cogs as my modbus slave driver will reside in one cog and my main program which reads temperatures and stores them in the aforementioned variables in another.

    My modbus slave must be able recieve a request and send the value of one of those variables back.

    How or where do i declare these variables?? In the DAT section of my top level spin file?

    Many thanks

    Damo
  • Mike GreenMike Green Posts: 23,101
    edited 2007-03-18 16:01
    Damo,
    There's really not a great answer for this. The variables probably belong in the top level spin file, but there's no clean way to pass knowledge of these variables lower down in the hierarchy. There's not even a clean way to define these variables in a object by themselves and pass that knowledge upwards since multiple uses of the same object create multiple instances of their variables.

    Probably the best/easiest way to do this is to define all the variables in a "globalValues" object in a DAT section there. You would need a "set" and "get" method for each separate variable. The "set" and "get" method could take one or more subscripts as parameters if you are implementing an array. This object could be referenced in any object that needs access to the variables and, at least, only one copy of the code would be present (and only one copy of the DAT section). There are other ways, like allocating the variables yourself in upper memory and having constant declarations for each variable's address, then using byte[noparse]/noparse, word[noparse]/noparse, and long[noparse]/noparse to access the values. Download a copy of the Propeller OS for an example of this (in the OS_loader.spin object).
  • Damien AllenDamien Allen Posts: 103
    edited 2007-03-18 16:13
    Thank you again Mike
  • Jeff MartinJeff Martin Posts: 755
    edited 2007-03-19 16:39
    Damien Allen said...
    Thanks again Mike, i'll work on that later then. For now i'll get the rest of the modbus code working.

    Jeff, I believe it is just CRC-16, the routine roughly stays the same its just the polynomial that changes

    CRC-16 uses $A001 as the poly, whereas CRC16-CCITT uses $8404.

    Does that satisfy your curiousity? smile.gif
    Yes, thanks Damien.· I have an old CRC16-CCITT routine I wrote that could be re-written in Spin, but that doesn't help you if it is a different form.

    Thanks.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    --Jeff Martin

    · Sr. Software Engineer
    · Parallax, Inc.
  • Jeff MartinJeff Martin Posts: 755
    edited 2007-03-19 16:45
    Damien Allen said...
    My project requires me to have variables available across cogs as my modbus slave driver will reside in one cog and my main program which reads temperatures and stores them in the aforementioned variables in another.

    My modbus slave must be able recieve a request and send the value of one of those variables back.

    How or where do i declare these variables?? In the DAT section of my top level spin file?


    Damo
    In addition to Mike's suggestions, if cogs that need to share variables are all running Spin code, you can write the top-level object with all the cog's code in it (IE: your main methods as well as a number of methods that will be run by other cogs) and define all your global variables in your normal VAR block (or a separate VAR block if you want to make it clear what is meant to be used by multiple cogs)... because launching an object's Spin code into another cog has the natural effect of making ALL that object's variables directly available from the new cog as well.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    --Jeff Martin

    · Sr. Software Engineer
    · Parallax, Inc.
  • Damien AllenDamien Allen Posts: 103
    edited 2007-03-19 19:36
    Thats Jeff thats very useful
Sign In or Register to comment.