Shop OBEX P1 Docs P2 Docs Learn Events
Is there a better or simpler way to do this? — Parallax Forums

Is there a better or simpler way to do this?

Don MDon M Posts: 1,652
edited 2013-03-08 08:22 in Propeller 1
This code looks at some serial data being received. There are 3 bytes- 2 data and 1 checksum.

The data is received in and the checksum verified before the message is displayed.

This code works but looks rather long. Seems like a lot of redundency. Was wondering if there is a simpler way.
  repeat
    s := serial.rx_time(10)     
    case s
      $01: repeat until (s & $F_00) == $1_00 
             checksum += s
             s := serial.rx_time(2)
             if (s & $0_FF) == checksum
               ch_seq++
               term.str(string("Message 1", 13))
               quit        
        quit
      $02: repeat until (s & $F_00) == $1_00 
             checksum += s
             s := serial.rx_time(2)
             if (s & $0_FF) == checksum
               ch_seq++
               term.str(string("Message 2", 13))
               quit        
        quit
      $03: repeat until (s & $F_00) == $1_00 
             checksum += s
             s := serial.rx_time(2)
             if (s & $0_FF) == checksum
               ch_seq++
               term.str(string("Message 3", 13))
               quit        
        quit
      $04: repeat until (s & $F_00) == $1_00 
             checksum += s
             s := serial.rx_time(2)
             if (s & $0_FF) == checksum
               ch_seq++
               term.str(string("Message 4", 13))
               quit        
        quit
      $05: checksum += s
           s := serial.rx_time(2)
           case s
             $10: repeat until (s & $F_00) == $1_00  
                    checksum += s
                    s := serial.rx_time(2)
                    if (s & $0_FF) == checksum
                      ch_seq++
                      term.str(string("Message 5", 13))
                      quit
                quit
             $20: repeat until (s & $F_00) == $1_00  
                    checksum += s
                    s := serial.rx_time(2)
                    if (s & $0_FF) == checksum
                      ch_seq++
                      term.str(string("Message 6", 13))
                      quit         
               quit                 
        quit      
      $06: repeat until (s & $F_00) == $1_00 
             checksum += s
             s := serial.rx_time(2)
             if (s & $0_FF) == checksum
               ch_seq++
               term.str(string("Message 7", 13))
               quit        
        quit
      $11: checksum += s
           s := serial.rx_time(2)
           case s
             $00: repeat until (s & $F_00) == $1_00  
                    checksum += s
                    s := serial.rx_time(2)
                    if (s & $0_FF) == checksum
                      ch_seq++
                      term.str(string("Message 8", 13))
                      quit
                quit
             $10: repeat until (s & $F_00) == $1_00  
                    checksum += s
                    s := serial.rx_time(2)
                    if (s & $0_FF) == checksum
                      ch_seq++
                      term.str(string("Message 9", 13))
                      quit         
               quit
             $11: repeat until (s & $F_00) == $1_00  
                    checksum += s
                    s := serial.rx_time(2)
                    if (s & $0_FF) == checksum
                      ch_seq++
                      term.str(string("Message 10", 13))
                      quit
                quit
             $30: repeat until (s & $F_00) == $1_00  
                    checksum += s
                    s := serial.rx_time(2)
                    if (s & $0_FF) == checksum
                      ch_seq++
                      term.str(string("Message 11", 13))
                      quit
               quit
             $41: repeat until (s & $F_00) == $1_00  
                    checksum += s
                    s := serial.rx_time(2)
                    if (s & $0_FF) == checksum
                      ch_seq++
                      term.str(string("Message 12", 13))
                      quit
                quit
             $50: repeat until (s & $F_00) == $1_00  
                    checksum += s
                    s := serial.rx_time(2)
                    if (s & $0_FF) == checksum
                      ch_seq++
                      term.str(string("Message 13", 13))
                      quit         
               quit
             $51: repeat until (s & $F_00) == $1_00  
                    checksum += s
                    s := serial.rx_time(2)
                    if (s & $0_FF) == checksum
                      ch_seq++
                      term.str(string("Message 14", 13))
                      quit
                quit
             $52: repeat until (s & $F_00) == $1_00  
                    checksum += s
                    s := serial.rx_time(2)
                    if (s & $0_FF) == checksum
                      ch_seq++
                      term.str(string("Message 15", 13))
                      quit         
               quit
             $53: repeat until (s & $F_00) == $1_00  
                    checksum += s
                    s := serial.rx_time(2)
                    if (s & $0_FF) == checksum
                      ch_seq++
                      term.str(string("Message 16", 13))
                      quit
                quit
             $54: repeat until (s & $F_00) == $1_00  
                    checksum += s
                    s := serial.rx_time(2)
                    if (s & $0_FF) == checksum
                      ch_seq++
                      term.str(string("Message 17", 13))
                      quit         
               quit
                                        
        quit      
      $15: checksum += s
           s := serial.rx_time(2)
           case s
             $00: repeat until (s & $F_00) == $1_00  
                    checksum += s
                    s := serial.rx_time(2)
                    if (s & $0_FF) == checksum
                      ch_seq++
                      term.str(string("Message 18", 13))
                      quit
                quit
             $02: repeat until (s & $F_00) == $1_00  
                    checksum += s
                    s := serial.rx_time(2)
                    if (s & $0_FF) == checksum
                      ch_seq++
                      term.str(string("Message 19", 13))
                      quit         
               quit
             $03: repeat until (s & $F_00) == $1_00  
                    checksum += s
                    s := serial.rx_time(2)
                    if (s & $0_FF) == checksum
                      ch_seq++
                      term.str(string("Message 20", 13))
                      quit
                quit
             $04: repeat until (s & $F_00) == $1_00  
                    checksum += s
                    s := serial.rx_time(2)
                    if (s & $0_FF) == checksum
                      ch_seq++
                      term.str(string("Message 21", 13))
                      quit         
               quit                       
        quit      
          

Thanks.
Don

Comments

  • jmgjmg Posts: 15,173
    edited 2013-03-07 12:59
    Don M wrote: »
    This code works but looks rather long. Seems like a lot of redundency. Was wondering if there is a simpler way.

    If it fits, and the space is not wanted for anything else, then it is fine as it is... ;)
    (sometimes, expanded code is the fastest..)

    As for general clarity, some tools allow macros, or In-line expansion, so you get the same binary, but oft repeated Text can be written once.
    Not sure about Spin ? (a pre-processor could do this for you ? )

    Or, you can re-code what you have, to move as much common stuff outside the individual CASEs to a common area.
    Sometimes, that may need an 'undo' line added in infrequent not-needed cases.
    Overall size is smaller, but it may not be faster.
  • Dave HeinDave Hein Posts: 6,347
    edited 2013-03-07 13:29
    You could put the inner repeat loop in a separate method, and pass the value of "s" and the message number to it. You could also use lookup to generate the message number instead of using case statements. Or you could use expressions like $01..$04: to handle a range of cases.
  • MagIO2MagIO2 Posts: 2,243
    edited 2013-03-08 03:23
    For me it looks like the messages have a variable length, right?!
    I think the more important question is how will this code behave if you really have transmission problems! Will it recover? I don't think that it will recover by intention, more by chance! The mentioned code improvements won't change anything on recovery-behaviour.

    You should give us more details about the protocol, so that we can give better advice also in regards to recovery.

    In general optimizing code means to find similarities and make functions out of the similar parts using parameters in the parts that are embedded in similar code but are actually different. For example in the outer case statement cases from $01-$04 everything is exactly the same except the message number. So you can make it a function which accepts the message number as a parameter.
  • Bobb FwedBobb Fwed Posts: 1,119
    edited 2013-03-08 08:22
    Depending on how specific the Messages are, you could do something like this:
    repeat
        s := serial.rx_time(10)     
        case s
          $01..$04,$06:
            tmp := s 
            repeat until (s & $F_00) == $1_00 
              checksum += s
              s := serial.rx_time(2)
              if (s & $0_FF) == checksum
                ch_seq++
                term.str(string("Message "))
                term.dec(s)
                term.tx(13)
                quit        
            quit
          $05: checksum += s
               s := se'...
    

    Or you could break the REPEAT UNTIL... into a method/function.
Sign In or Register to comment.