Need a sysRPL CRC16 routine. - Hewlett Packard

This is a discussion on Need a sysRPL CRC16 routine. - Hewlett Packard ; The rules are: 1. Load a 16-bit register with all 1's (FFFFh) 2. XOR the first 8-bit byte with the high order byte of the 16-bit register. Put the result in a in the 16-bit register. 3. Shift the 16-bit ...

+ Reply to Thread
Results 1 to 18 of 18

Thread: Need a sysRPL CRC16 routine.

  1. Need a sysRPL CRC16 routine.

    The rules are:

    1. Load a 16-bit register with all 1's (FFFFh)

    2. XOR the first 8-bit byte with the high order byte of the 16-bit
    register. Put the result in a in the 16-bit register.

    3. Shift the 16-bit register one bit to the right.

    4a. If the bit shifted out to the right is one, XOR the generating
    polynomial 1010 0000 0000 0001 (A001h) with the 16 bit
    register.

    4b. If the bit shifted out to the right is zero, return to step 3.

    5. Repeat steps 3 and 4 until 8 shifts have been performed.

    6. XOR the next 8-bit byte with the 16-bit register.

    7. Repeat steps 3 through 6 until all bytes of the message have
    been XOR'd with the 16-bit register and shifted 8 times.

    8. The contents of the 16-bit register are the 2-byte CRC error check
    and is added to the message most sifnificant bits first.

    For a message = 0207h the resulting CRC16 is 1241h. The completed
    message would then need to be formatted like this: 12 41 07 02.

    I would sure appreciate some help getting this into a sysRPL program.
    Just getting the hex strings into a form I can manipulate is very
    tricky, and my experience isn't up to the task (yet!). Would some
    kind soul please assist?

    Thank you!

    -Dot-

  2. Re: Need a sysRPL CRC16 routine.

    On Mon, 02 Apr 2007 22:26:14 -0500, dot wrote:

    [about getting a CRC-16, but for what object?]

    > For a message = 0207h the resulting CRC16 is 1241h.
    > The completed message would then need to be formatted
    > like this: 12 41 07 02


    What type of object do you mean by "message"?

    Isn't the built-in hardware CRC that very same CRC-16?

    However, it seems that you may want to include
    only the bytes of a string (or hex string?),
    without its prolog word?

    A small modification of OCRC (in ML) might be able
    to accomplish that (although I am not going to try

    Finally, hex string concatenation via "&HXS" ?
    (to append the 4-nibble CRC to the original object?)

    [r->] [OFF]

  3. Re: Need a sysRPL CRC16 routine.

    hello,

    did you try the CRC function in the hacker's library (256)

    cyrille

    "dot" wrote in message
    news:7q8313521cuq2464gtkcq0c4lrjeb1ei60@4ax.com...
    > The rules are:
    >
    > 1. Load a 16-bit register with all 1's (FFFFh)
    >
    > 2. XOR the first 8-bit byte with the high order byte of the 16-bit
    > register. Put the result in a in the 16-bit register.
    >
    > 3. Shift the 16-bit register one bit to the right.
    >
    > 4a. If the bit shifted out to the right is one, XOR the generating
    > polynomial 1010 0000 0000 0001 (A001h) with the 16 bit
    > register.
    >
    > 4b. If the bit shifted out to the right is zero, return to step 3.
    >
    > 5. Repeat steps 3 and 4 until 8 shifts have been performed.
    >
    > 6. XOR the next 8-bit byte with the 16-bit register.
    >
    > 7. Repeat steps 3 through 6 until all bytes of the message have
    > been XOR'd with the 16-bit register and shifted 8 times.
    >
    > 8. The contents of the 16-bit register are the 2-byte CRC error check
    > and is added to the message most sifnificant bits first.
    >
    > For a message = 0207h the resulting CRC16 is 1241h. The completed
    > message would then need to be formatted like this: 12 41 07 02.
    >
    > I would sure appreciate some help getting this into a sysRPL program.
    > Just getting the hex strings into a form I can manipulate is very
    > tricky, and my experience isn't up to the task (yet!). Would some
    > kind soul please assist?
    >
    > Thank you!
    >
    > -Dot-




  4. Re: Need a sysRPL CRC16 routine.

    On Tue, 03 Apr 2007 09:01:30 -0500, cyrille kindly replied:

    > did you try the CRC function in the hacker's library (256)


    I wondered what that was!

    Expecially since an *empty* string gives #5285 (as a system binary).

    So I just looked it up in the AUR:

    This command gives you the CRC of the data in
    a library object or string (the CRC computation
    starts on the *size* [field] of the object
    and finishes 4 nibbles *before* the end of the object).

    Is that what you wanted, Dot?

    One could compensate for the ending point by appending
    four nibbles in advance, but how can one compensate
    for the starting point?

    [r->] [OFF]

  5. Re: Need a sysRPL CRC16 routine.

    On Tue, 03 Apr 2007 02:12:52 -0500, "John H Meyers"
    wrote:

    >On Mon, 02 Apr 2007 22:26:14 -0500, dot wrote:
    >
    >[about getting a CRC-16, but for what object?]
    >
    >> For a message = 0207h the resulting CRC16 is 1241h.
    >> The completed message would then need to be formatted
    >> like this: 12 41 07 02

    >
    >What type of object do you mean by "message"?

    The CRC16 is needed to satisfy the modbus message protocol. There is
    a string of hex digits (depending on the modbus message) which will
    need to be processed, and the resulting CRC16 values added in big
    endian fashion (least significant byte then most significant byte).
    The modbus message string becomes one long hex string.
    >
    >Isn't the built-in hardware CRC that very same CRC-16?

    It does not seem to be. The test message "0207" yielded 5B04h
    and the reverse string, "0702" yields 0CA9h. I need to end up with
    1241h for the valid test message CRC16.
    >
    >However, it seems that you may want to include
    >only the bytes of a string (or hex string?),
    >without its prolog word?

    In general, this shouldn't be that difficult to implement. I am
    having trouble just getting started, though. Starting out with the
    string "0207" I need to break that message into the upper byte (02h)
    and the lower byte (07h). I think I could use the shift byte commands
    xSRB and xRLB to do that, but I havent't gotten that far yet.
    >
    >A small modification of OCRC (in ML) might be able
    >to accomplish that (although I am not going to try
    >
    >Finally, hex string concatenation via "&HXS" ?
    >(to append the 4-nibble CRC to the original object?)
    >
    >[r->] [OFF]





  6. Re: Need a sysRPL CRC16 routine.

    hello,

    to compensate for the start, just do:
    ->H H->S

    cyrille

    "John H Meyers" wrote in message
    newsp.tp7usy1ynn735j@w2kjhm.ia.mum.edu...
    > On Tue, 03 Apr 2007 09:01:30 -0500, cyrille kindly replied:
    >
    >> did you try the CRC function in the hacker's library (256)

    >
    > I wondered what that was!
    >
    > Expecially since an *empty* string gives #5285 (as a system binary).
    >
    > So I just looked it up in the AUR:
    >
    > This command gives you the CRC of the data in
    > a library object or string (the CRC computation
    > starts on the *size* [field] of the object
    > and finishes 4 nibbles *before* the end of the object).
    >
    > Is that what you wanted, Dot?
    >
    > One could compensate for the ending point by appending
    > four nibbles in advance, but how can one compensate
    > for the starting point?
    >
    > [r->] [OFF]




  7. Re: Need a sysRPL CRC16 routine.

    On Tue, 03 Apr 2007 16:45:27 -0500, cyrille kindly wrote:

    > to compensate for the start, just do:
    > ->H H->S


    "ABC" \->H H\->S

    now we have "xxxxxABC"
    (including its original prolog and length inside the string?)

    Does this offer us a way to get the CRC of just the bytes "ABC"
    ignoring all prolog and/or length nibbles?

    Sorry I'm not catching on yet.

    [r->] [OFF]

  8. Re: Need a sysRPL CRC16 routine.

    On Tue, 03 Apr 2007 13:46:00 -0500, dot wrote:

    >> What type of object do you mean by "message"?


    > The CRC16 is needed to satisfy the modbus message protocol. There is
    > a string of hex digits (depending on the modbus message) which will
    > need to be processed, and the resulting CRC16 values added in big
    > endian fashion (least significant byte then most significant byte).
    > The modbus message string becomes one long hex string.


    >> Isn't the built-in hardware CRC that very same CRC-16?


    > It does not seem to be. The test message "0207" yielded 5B04h
    > and the reverse string, "0702" yields 0CA9h.
    > I need to end up with 1241h for the valid test message CRC16.


    What object type was each "message," how did you create it,
    and what internal function did you use for CRC?
    ("yielded" means when you did what?)

    Even if you constructed a proper 2-byte hex string as input
    (which can't be done via UserRPL), neither the BYTES nor CRC
    nor OCRC etc. commands can be used as-is, because they
    start performing CRC on a *prefix* to those actual bytes
    (BYTES starts at the prolog and goes to the end of the object;
    CRC starts at the "length" field and stops 4 nibbles short
    of the end of the object, if the AUR is correct -- the latter
    seems to have been specially designed to compute a library CRC).

    I suppose that all might be done upon hex strings
    (very slowly), but it sure would be nice to have
    a straightforward *ML* function for the CRC
    of an arbitrary *string* (no prolog, no length,
    just the string itself) -- in general, this should
    also accommodate "odd-nibble" strings and general hex strings,
    whose internal structures are all identical
    [prolog, length in nibbles (including length field itself), data]

    Note that "user" binary objects are also hex strings,
    but are fixed-length (16d nibbles of data):

    #123456789ABCDEF0h \->H ==> E4A20 51000 0FEDCBA987654321
    #1234567h \->H ==> E4A20 51000 7654321000000000

    OTOH, "ABC" BYTES DROP \->H ==> E4A20 90000 7DC9 [four nibbles only]

    And of course "ABC" \->H ==> C2A20 B0000 142434

    So, umm, would "ABC" in my computer have the same or different CRC-16?

    [r->] [OFF]

  9. Re: Need a sysRPL CRC16 routine.

    On Tue, 03 Apr 2007 11:30:24 -0500, "John H Meyers"
    wrote:

    >On Tue, 03 Apr 2007 09:01:30 -0500, cyrille kindly replied:
    >
    >> did you try the CRC function in the hacker's library (256)

    >
    >I wondered what that was!
    >
    >Expecially since an *empty* string gives #5285 (as a system binary).
    >
    >So I just looked it up in the AUR:
    >
    > This command gives you the CRC of the data in
    > a library object or string (the CRC computation
    > starts on the *size* [field] of the object
    > and finishes 4 nibbles *before* the end of the object).
    >
    >Is that what you wanted, Dot?
    >
    >One could compensate for the ending point by appending
    >four nibbles in advance, but how can one compensate
    >for the starting point?
    >
    >[r->] [OFF]


    Well, folks ... you'll probably just laugh at my feeble sysrpl
    attempts, but I seem to have the program working. The program has the
    test message string "0207" built in, just for test purposes; and the
    crc-16 computed result is to be concatenated to the end of the test
    message in "big endian" fashion and the correct calculated
    crc-16 in this case is 1241h. So the final message would be the
    string "02074112"

    There is a lot of hex and string manipulation going on here. The true
    sysrpl experts will probably find much better ways of doing this. I
    thought I would share my solution and see if there are any of you that
    would care to show this novice the ropes!

    -Dot-

    RPL
    ( D:\hp49g+\Projects\ModBus\CRC.s, part of the ModBus.hpp project,
    created by <> on 4/2/2007 )

    INCLUDE ModBus.h

    *********************************************
    * CRC-16 Cyclical Redundancy Check *
    * INPUTS: msg *
    * OUTPUTS: msg + CRC-16 *
    *********************************************

    xNAME
    ::
    xHEX ( Set Hex Mode )
    xCLEAR ( Clear the display )
    #1 ClrUserFlag ( Clear the carry flag )

    * Initial test message for address 02 function 07 which is for a
    * status request. The crc16 should be 12 41

    * Dummy message string: normally from the stack on entry
    "0207" ( Initial test message )
    "#FFFF" DOSTR> ( Initial crc16 all 1's = FFFFh )
    #4 ( Initial message length )
    "#A001" DOSTR> ( CRC16 generating polynomial )
    "#001" DOSTR> ( Carry bit tester )

    {
    LAM msg ( Message string from stack )
    LAM crc16 ( Initially all 1's = FFFFh )
    LAM len ( Message length )
    LAM poly ( CRC16 generating polynomial )
    LAM oflag ( Carry bit tester )
    }
    BIND


    LAM msg LEN$ ( Get message length )
    ' LAM len STO ( Save message length )

    LAM len BINT1 ( Process each Byte in the message string )
    DO
    LAM crc16 ( Step 1: Load FFFFh into 16-bit
    register )
    "#" LAM msg INDEX@ INDEX@ #1+ SUB$ &$ DOSTR> ( Get msg
    Byte )

    bitXOR ( Step 2: XOR crc16 Register with
    current Byte )
    DUPDUP ' LAM crc16 STO ( Save the resulting
    crc. Leave on stack )

    BINT9 BINT1 ( Eight shifts required )
    DO
    * Step 3: Shift CRC one bit right check for carry
    LAM oflag bitAND ( Examine
    lsb for 1: signifies carry )
    LAM oflag EQUAL ( check
    for carry )
    SWAP
    bitSR
    SWAP

    * If TRUE use polynomial and save result to crc register
    IT :: LAM poly bitXOR ; ( Step
    4: if carry out use polynomial )
    DUPDUP
    ' LAM crc16 STO ( Step 5:
    process each byte through 8 shifts. )

    LOOP

    #2 +LOOP ( Step 6: Get next Byte )

    * Step 7: Shift CRC16 byte order and append to message
    LAM msg
    LAM crc16 BINT1 BINT2 SUBHXS hxs>$ BINT3 BINT4 SUB$ &$
    LAM crc16 BINT3 BINT4 SUBHXS hxs>$ BINT3 BINT4 SUB$ &$
    ' LAM msg STO

    * ----- Debug code ------
    xCLEAR
    "Msg = " LAM msg &$
    ;



  10. Re: Need a sysRPL CRC16 routine.

    On Fri, 06 Apr 2007 16:55:36 -0500, dot wrote:

    [Source code]

    > * Dummy message string: normally from the stack on entry
    > "0207" ( Initial test message )


    That looks like a *string* object
    containing characters used to *represent*hex*digits*
    which ultimately represents *another* object
    whose CRC is to be computed, is that not so?

    In that case, the built-in CRC could not possibly help,
    because it operates on actual bytes in memory,
    automatically computing the running CRC
    as those actual bytes are accessed from memory.

    I thought you meant an actual object like a hex string
    (the exact same type of object as a user binary integer,
    each byte itself being two hex digits' worth of bits,
    and which in general can be any length); the built-in CRC
    might very well be useful there, or at least
    more relevant to the general idea of taking
    the real CRC of the *body* portion
    of real calculator objects
    (without the prolog and/or count).

    Congratulations on your completed program.

    [r->] [OFF]

  11. Re: Need a sysRPL CRC16 routine.

    Yes, the message object is a string object representing hex digits.
    In the modbus protocol, there are functions that are given hex codes
    and usually a start and end address that represent a number of
    registers that are to be involved in some way. So each message string
    then, is the function code, and the register count as a string of hex
    digits.

    It's confusing until you get your mind wrapped around that. It makes
    programming it interesting. The crc-16 generator is crucial to the
    process, since the protocol requires it, successful communication with
    modbus devices won't work without it.

    Most of the documentation found on the 'net seems to have errors in
    the table of intermediate results. Close inspection reveals it
    though, and so I was able to work through the example until I
    *finally* got it right!

    -Dot-
    On Fri, 06 Apr 2007 17:32:19 -0500, "John H Meyers"
    wrote:

    >On Fri, 06 Apr 2007 16:55:36 -0500, dot wrote:
    >
    >[Source code]
    >
    >> * Dummy message string: normally from the stack on entry
    >> "0207" ( Initial test message )

    >
    >That looks like a *string* object
    >containing characters used to *represent*hex*digits*
    >which ultimately represents *another* object
    >whose CRC is to be computed, is that not so?
    >
    >In that case, the built-in CRC could not possibly help,
    >because it operates on actual bytes in memory,
    >automatically computing the running CRC
    >as those actual bytes are accessed from memory.
    >
    >I thought you meant an actual object like a hex string
    >(the exact same type of object as a user binary integer,
    >each byte itself being two hex digits' worth of bits,
    >and which in general can be any length); the built-in CRC
    >might very well be useful there, or at least
    >more relevant to the general idea of taking
    >the real CRC of the *body* portion
    >of real calculator objects
    >(without the prolog and/or count).
    >
    >Congratulations on your completed program.
    >
    >[r->] [OFF]



  12. Re: Need a sysRPL CRC16 routine.

    On Fri, 06 Apr 2007 17:59:40 -0500, dot wrote:

    > the "message object" is a string object representing hex digits


    Then here's a little program which converts such a string
    into a genuine internal "hex string" (do HOME 256 ATTACH
    before program entry or transfer):

    @ "123ABC" -> #123ABCh [C# 6 CBA321]
    \<< SREV DUP HEAD DROP @ Empty string is invalid
    H\->S #2A4Eh SB~B #5AB3h SYSEVAL \>>

    At this point, a slightly modified CRC (in ML)
    which should start after the prolog+length
    and continue to the end of the object
    might give the correct answer, and one could use &HXS
    to append the 16-bit checksum to the original hex string.

    To convert an internal hex string back to a string:

    @ #123ABCh -> "123ABC"
    \<< DUP B\->R DROP \->H 11 OVER SIZE SUB SREV \>>

    Note that these programs work on any-length strings
    (whereas "user binary integers" are 16 digits),
    and that longer hex strings are never fully displayed
    on the stack or when edited (HP48[S/G] shows "C#" notation
    when edited, although it can't re-compile that notation).

    The usual "back up memory first" advice
    is of course strongly recommended.

    Might anyone care to examine OCRC and xCRC,
    and supply the modified SysRPL/ML for obtaining the CRC
    of the entire body (without length field) of a hex string?

    [r->] [OFF]

  13. Re: Need a sysRPL CRC16 routine.

    Hi,

    "John H Meyers" schrieb im Newsbeitrag
    newsp.tqek1pivnn735j@w2kjhm.ia.mum.edu...
    > On Fri, 06 Apr 2007 17:59:40 -0500, dot wrote:
    >
    > [..]
    > Might anyone care to examine OCRC and xCRC,
    > and supply the modified SysRPL/ML for obtaining the CRC
    > of the entire body (without length field) of a hex string?
    >

    In the HP-48, the PCO =OCRC first calls a subroutine to get the ob's size.
    The 2nd subroutine call does the actual CRC calculation,
    with the following input:
    A[A]: #nibbles to do CRC on
    C[A]: @object_data to do CRC for
    Output:
    A[A]: CRC

    So if someone would like to exclude the ob's length field from CRC
    calculation,
    it should be sufficient to insert two lines between
    the first and the 2nd subroutine call, like this:

    =OCRC CON(5) (*)+5
    GOSUB GetSize

    ***
    A=A-CON A,5 * Decrement nib count
    C=C+CON A,5 * Increment start address
    ***

    GOSUB DoCRC
    ....




    HTH

    Happy Easter days:-)

    Raymond



  14. Re: Need a sysRPL CRC16 routine.

    Thanks for your thoughts on the string > hex and vice versa. It is an
    underlying goal in my effort, though, to keep the program in a sysrpl
    program.

    One of the more demanding issues associated with this is the string
    and hex handling. Sysrpl is not particularly intuitive on this point.
    It might be useful to create stand alone programs to manipulate
    strings and hex (back and forth). I haven't fully tested the program
    that I submitted yesterday, and one of the things I anticipate might
    happen will be the need to pad the result with leading zeros if the
    result happens to be less than four characters (hex digits) long.

    If the result of some message string would happen to produce the
    crc-16 value of "1" (for example), then there would be a need to
    prefix "000" to the crc-16 string before breaking it into the two
    bytes and interposing them for the big endian result. Likewise for
    other results that might require "00" or "0" to be the prefix pad
    needed.

    For the hex numbering system in the hp calc, it's almost like there is
    a 'hex' (voodoo curse!) put on it.

    I forgot to say thank you to William Graves for his dilligence and the
    effort he has put into the Debug4x programming environment. I have
    used Debug4x, and now with the latest version, all along. It's been a
    very useful tool. So, "thank you, William!"

    I have crashed it a few times, and find that recovery most of the time
    is as simple as reloading the emulator with a version of the .e49 file
    that I have set up for my needs (flags and all). Other times
    resetting the emulator works, and a few times I had to shut down
    Debug4x as it was hopelessly stalled (unresponsive program). Usually
    the Debug4x lock up was related to running out of stack room; and that
    was caused by an error in my programming code.

    -Dot-
    On Sat, 07 Apr 2007 02:42:51 -0500, "John H Meyers"
    wrote:

    >On Fri, 06 Apr 2007 17:59:40 -0500, dot wrote:
    >
    >> the "message object" is a string object representing hex digits

    >
    >Then here's a little program which converts such a string
    >into a genuine internal "hex string" (do HOME 256 ATTACH
    >before program entry or transfer):
    >
    >@ "123ABC" -> #123ABCh [C# 6 CBA321]
    >\<< SREV DUP HEAD DROP @ Empty string is invalid
    >H\->S #2A4Eh SB~B #5AB3h SYSEVAL \>>
    >
    >At this point, a slightly modified CRC (in ML)
    >which should start after the prolog+length
    >and continue to the end of the object
    >might give the correct answer, and one could use &HXS
    >to append the 16-bit checksum to the original hex string.
    >
    >To convert an internal hex string back to a string:
    >
    >@ #123ABCh -> "123ABC"
    >\<< DUP B\->R DROP \->H 11 OVER SIZE SUB SREV \>>
    >
    >Note that these programs work on any-length strings
    >(whereas "user binary integers" are 16 digits),
    >and that longer hex strings are never fully displayed
    >on the stack or when edited (HP48[S/G] shows "C#" notation
    >when edited, although it can't re-compile that notation).
    >
    >The usual "back up memory first" advice
    >is of course strongly recommended.
    >
    >Might anyone care to examine OCRC and xCRC,
    >and supply the modified SysRPL/ML for obtaining the CRC
    >of the entire body (without length field) of a hex string?
    >
    >[r->] [OFF]



  15. Re: Need a sysRPL CRC16 routine.

    On Fri, 06 Apr 2007 17:59:40 -0500, dot wrote:

    > the message object is a string object representing hex digits.


    This seems to indicate the ASCII version of "modbus" (see below).

    > In the modbus protocol, there are functions that are given hex codes
    > and usually a start and end address that represent a number of
    > registers that are to be involved in some way.So each message string then, is the function code,
    > and the register count as a string of hex digits.
    >
    > It's confusing until you get your mind wrapped around that.
    > It makes programming it interesting. The crc-16 generator
    > is crucial to the process, since the protocol requires it,
    > successful communication with modbus devices won't work without it.


    I finally looked up "modbus" and found this:

    http://en.wikipedia.org/wiki/Modbus
    "Two variants exist, with different representations
    of numerical data and slightly different protocol details.
    Modbus RTU is a compact, binary representation of the data.
    Modbus ASCII is human readable, and more verbose.
    Both of these variants use serial communication.
    The RTU format follows the commands/data
    with a cyclic redundancy check checksum,
    while the ASCII format uses a longitudinal redundancy check checksum."
    [NOTE that last sentence!]

    http://www.modicon.com/techpubs/toc7.html

    http://www.modicon.com/techpubs/intr7.html
    (says the same things about RTU vs. ASCII formats)
    "When controllers are setup to communicate on a Modbus network
    using ASCII mode, each eight-bit byte in a message
    is sent as two ASCII characters... [and the]
    Error Check Field [is] Longitudinal Redundancy Check (LRC)"

    http://www.modicon.com/techpubs/crc7.html
    "The Longitudinal Redundancy Check (LRC) field is one byte,
    containing an eight-bit binary value.
    The LRC is calculated by adding together successive eight-bit bytes,
    discarding any carries, then two's complementing the result.
    The eight-bit LRC (two ASCII characters) is transmitted
    high order character first, followed by the low order character"

    Bottom line:

    Are you communicating with *binary* data (needing a binary CRC),
    or *ascii* data (neededing an ascii -- and much simpler -- LRC)?

    The particular "A001" CRC polynomial used in "modbus RTU"
    is labeled "Reversed original CRC-16-IBM polynomial"
    in http://en.wikipedia.org/wiki/Cyclic_redundancy_check
    and may not be what's used in HP calcs anyway, in which case
    the HP hardware CRC of only the body of a [hex]string
    won't be useful, even for "modbus RTU"

    [r->] [OFF]

  16. Re: Need a sysRPL CRC16 routine.

    [Backup memory *before* using anything in this post!]

    On Sat, 07 Apr 2007 06:35:54 -0500, Raymond Del Tondo wrote:

    > In the HP-48, the PCO =OCRC
    > first calls a subroutine to get the ob's size.
    > The 2nd subroutine call does the actual CRC calculation,
    > with the following input:
    > A[A]: #nibbles to do CRC on
    > C[A]: @object_data to do CRC for
    > Output:
    > A[A]: CRC
    >
    > So to exclude the ob's length field from CRC calculation,
    > it should be sufficient to insert two lines between
    > the first and the 2nd subroutine call, like this:
    >
    > =OCRC CON(5) (*)+5
    > GOSUB GetSize
    >
    > ***
    > A=A-CON A,5 * Decrement nib count
    > C=C+CON A,5 * Increment start address
    > ***
    >
    > GOSUB DoCRC
    > ...


    Thanks to the above helpful analysis
    (but any errors in the following due to my mangling),
    here's what I've got for a CRC of [hex]string *body* only
    (doesn't Kermit also need to do this for packets?)

    "
    (Based on CRC - ROMPTR 100 1B and OCRC )
    ::
    CK1NoBlame
    DUPTYPECSTR?
    OVER
    TYPEHSTR?
    OR
    NOTcase
    SETTYPEERR
    CODE
    A=DAT1 A
    D1+5
    D=D+1 A
    GOSBVL SAVPTR
    GOSBVL DisableIntr
    D0=A
    D0+5
    A=DAT0 A
    D0+5
    A-5 A
    GOSBVL DoCRC
    R1=A A
    GOSBVL PUSH#
    GOVLNG 05965
    ENDCODE
    ;
    @" -92 SF ASM 'CRCC' STO @ CRC of [hex]string *body* only
    @ Backup memory before use!

    The same should of course work also in HP48[S/G]
    (except for above being specified in MASD style

    I was surprised that the HP CRC starts with an initial value #0000
    (rather than #FFFF), but this does seem to agree with Kermit,
    as specified in the original Kermit protocol manual
    (Sixth Edition, June 1986, by Frank da Cruz, see page 39)
    http://www.columbia.edu/kermit/ftp/e/kproto.for

    On the other hand, the Kermit manual says that they are using
    "16-bit CRC-CCITT," while others dispute what that means:
    http://www.joegeluso.com/software/articles/ccitt.htm
    (same polynomial, but initializing to #FFFF)

    Thus the above program produces #0h for an empty string,
    or for any string of all null characters [0 CHR],
    and also for #0h, no matter what actual length hex string.

    Although #0 entered in the command line always compiles
    to a 64-bit value (and R\->B also always produces a 64-bit value),
    operations which are restricted to the current binary word size
    (e.g. adding 0) actually result in the shortest hex string
    having at least as many bits as the word size;
    this was news to me, although it has always been so,
    possibly hidden by the fact that different-length hex strings
    starting with different number of leading zero bits
    all normally display the same on the calc stack,
    although the difference is displayed in SysRPL display mode
    (SSTK with Jazz, or setting flag -85 in HP50/49/48Gii)

    The actual length of calculator hex strings can also be discerned
    by converting them to strings of hex digits, using the following
    (HP50/49/48Gii only, needs HOME 256 ATTACH before entry or transfer)

    @ "123ABC" <-> #123ABCh [C# 6 CBA321]
    \<< DUP TYPE 10 \=/ @ Empty string is invalid
    { SREV DUP HEAD DROP H\->S #2A4Eh SB~B #5AB3h SYSEVAL }
    { \->H 11 OVER SIZE SUB SREV } IFTE \>> 'S~B' STO
    @ Backup memory before use!

    In HP48[S/G], \->H can be found as \->ASC in the "Hack" library
    (#4C301Bh LIBEVAL, which is *not* the same as \->ASC by Bill Wickes),
    so at least the binary -> string direction can be done with that tool;
    converting in the other direction may be performed
    by assembling (with Jazz) "HXS length reversed_digits"

    [r->] [OFF]

  17. Re: Need a sysRPL CRC16 routine.

    On Mon, 09 Apr 2007 03:22:19 -0500, "John H Meyers"
    wrote:

    >On Fri, 06 Apr 2007 17:59:40 -0500, dot wrote:
    >
    >> the message object is a string object representing hex digits.

    >
    >This seems to indicate the ASCII version of "modbus" (see below).


    No, I'm using the modbus RTU format. Requires CRC error check
    >


    >
    >Bottom line:
    >
    >Are you communicating with *binary* data (needing a binary CRC),


    I'm using modbus RTU. The data in modbus RTU is packed two hex
    characters per byte, whereas, in modbus ASCII the data is only one hex
    character per byte. Additionally, the packet format in modbus ASCII
    is different than modbus RTU. There is a prefixed ":" character in
    the ASCII version, which uses the LRC as you pointed out. There is no
    prefix character in modbus RTU and it uses the CRC with the A001h
    polynomial.

    I have the crc generator program working fine, although it surely can
    be made more efficient. The big boys generally use a software driven
    look up table, for the sake of speed. These days, with the increased
    processing horsepower, I'm not sure look up tables offer much
    advantage.

    >or *ascii* data (neededing an ascii -- and much simpler -- LRC)?
    >
    >The particular "A001" CRC polynomial used in "modbus RTU"
    >is labeled "Reversed original CRC-16-IBM polynomial"
    >in http://en.wikipedia.org/wiki/Cyclic_redundancy_check
    >and may not be what's used in HP calcs anyway, in which case
    >the HP hardware CRC of only the body of a [hex]string
    >won't be useful, even for "modbus RTU"
    >
    >[r->] [OFF]



  18. Re: Need a sysRPL CRC16 routine.

    Have you tried changing the wordsize?
    4; 8; ... 60; 64
    _____________________________________________
    "John H Meyers" wrote in message
    newsp.tp8d85a7nn735j@w2kjhm.ia.mum.edu...
    On Tue, 03 Apr 2007 13:46:00 -0500, dot wrote:

    Note that "user" binary objects are also hex strings,
    but are fixed-length (16d nibbles of data):

    #123456789ABCDEF0h \->H ==> E4A20 51000 0FEDCBA987654321
    #1234567h \->H ==> E4A20 51000 7654321000000000




+ Reply to Thread