Shop OBEX P1 Docs P2 Docs Learn Events
Help a PASM noob... — Parallax Forums

Help a PASM noob...

JeeHellJeeHell Posts: 3
edited 2013-12-07 06:41 in Propeller 1
Hello everyone,

Here is my first real attempt at PASM. Of course, it did not turn out to be working...
The aim is to listen an RF module which outputs data at 9600 bauds. The protocol is serial, but homemade to filter the RF noise.
The same approach worked in SPIN, but I just needed extra ticks to process the data in a more efficient way between two frames.

The emitter will first emit some random bits to set the gain of the RF receiver so noise is less a problem.
Then it sends three bytes in that order:
- first an header (to confirm this is the data we want to receive)
- the data byte
- and again the same data byte (I'll change that to a proper checksum when I get it working...)

Here is the code:
DAT                                                   
                        org     0
entry                   mov     RCVpin,#0             'RCVpin is 0, hardcoded for now          
                        mov     dRCVpin,#1              'decode RCVpin to...
                        shl     dRCVpin,RCVpin          '...binary format
                        rdlong  x,#0                    'get CLKFREQ
                        mov     y,baud                  'sets y to divide clockfreq by baud                        
                        call    #divide                 'clockfreq/baud
                        shl     x,#16                   'we need to get only x[0..15] for... 
                        shr     x,#16                   '...the result                        
                        mov     BitTime,x               'bittime=clokfreq/baud
                        mov     rxbyte,#0               'reset rxbyte
                        mov     halfBitTime,BitTime     'computing...
                        shr     halfBitTime,#1          '         ...halfBitTime
                        mov     rxbuf,#0         wz     'reset rxbuf, and set Z flag to 1 at the same time for the muxnz
                        muxnz   dira,dRCVpin            'we must set only the drcvpin to input=>low                                               

Sync                    mov     rxbuf,#0                'reset rxbuf                              
                                           
:loop                   waitpeq dRCVpin,dRCVpin         'wait for RCVpin to be High
                        mov     t,cnt                   'init time reference
                        mov     x,#0                    'waitPEQ pattern all to LOW                           
                        waitpeq x,dRCVpin               'wait for RCVpin to be Low
                        sub     t,cnt                   't=t-cnt 
                        cmp     t,halfBitTime   wc      'if t<bittime/2 then it's noise,and  C flag is set to 1
              if_c      jmp     #:loop
                        mov     t,cnt
                        add     t,halfBitTime
                        add     t,BitTime                            
                                                                         


getbyte                 waitcnt t,BitTime               'wait for middle of bit
                        shl     rxbuf,#1                'shift rxbuf left by one bit
                        test    ina,dRCVpin     wz      
                        muxnz   rxbuf,#1               'if INA & dRCVpin<>0 we put a 1 in the LSB of rxbuf

                        mov     y,rxbuf
                        and     y,sel_HDR              
                        cmp     y,HDR           wz      'if byteN°3 is the hdr byte we set Z flag to 1

              if_nz     jmp     #getbyte                'if no HDR byte we jump back to read a new bit from RXpin
                        
                        mov     byt,rxbuf               'put rxbuff in byt
                        shr     byt,#8                  'we remove the trailer byte
                        and     byt,#$FF                'and also the header byte, so byt is a potential RxByte

                        mov     y,rxbuf
                        and     y,Trail_byte
                        cmp     y,Trail_byte    wz    'if byt equals trail byte, we set Z flag to 1
              if_nz     jmp     #getbyte                'if not, we go grab a new bit

                        mov     rxbyte,byt               'so we got a correct RxByte!
                        jmp     #Sync                   'and we're happy to try again!           


'divide routine by parallax:
'divide x[31.00] by y[15..0] (y[16] must be 0)
'on exit, quotient is i x[15..0] and remainder is in x[31.16]
divide                  shl     y,#15                   
                        mov     t,#16
:loop                   cmpsub  x,y             wc
                        rcl     x,#1
                        djnz    t,#:loop
divide_ret              ret



sel_HDR                 long    %11111111_00000000_00000000
HDR                     long    %01010101_00000000_00000000
Trail_byte              long    %00000000_00000000_11111111
Data_byte               long    %00000000_11111111_00000000
baud                    long    9600
RCVpin                  long    0
dRCVpin                 res     1       
BitTime                 res     1
halfBitTime             res     1
x                       res     1
y                       res     1
rxbyte                  res     1
byt                     res     1
rxbuf                   res     1
t                       res     1
trail                   res     1


                        fit     496

Somehow, I never get more than one high bit in RxBuf, even though I keep outputing data on the RF, and the scope confirms the data is received...

If you have any inputs, ideas, fixes, you're all very welcome. I won't be offended if you say it's badly coded, it truly is my first PASM code (well the 2nd, the first one being a "flashing LED hello world"...)

Best regards,
Jean Luc

Comments

  • kuronekokuroneko Posts: 3,623
    edited 2013-12-07 04:54
    Two things jump out, test ina,dRCVpin wz doesn't work like this, use test dRCVpin,ina wz instead (have a look for shadow register(s)). Also, when you calculate the time difference - since cnt increases - the final sub t,cnt will give you a negative result. Better would be neg t,cnt followed by add t,cnt.
  • JeeHellJeeHell Posts: 3
    edited 2013-12-07 05:20
    thnaks for you hints Kuroneko! This did not solve the outcome (I fear I made a lot of small mistakes...), but it helps
    One question regarding the test instruction, why would the order of operands matter in this particular case?
  • kuronekokuroneko Posts: 3,623
    edited 2013-12-07 05:25
    JeeHell wrote: »
    One question regarding the test instruction, why would the order of operands matter in this particular case?
    ina (among others) is a read-only register. When used in the source operand slot (right) it reads the I/O pins, in the destination operand slot (left) you'll access its shadow register which is 0 by default but has no connection to the pins otherwise. This is just something one has to memorize. HTH
  • JeeHellJeeHell Posts: 3
    edited 2013-12-07 06:41
    Ok got it solved right now, I was making a mistake in the debugging routine as well (not included in the code...).
    Thanks a lot!
Sign In or Register to comment.