Shop OBEX P1 Docs P2 Docs Learn Events
PropBasic jm_ir_hdserial header — Parallax Forums

PropBasic jm_ir_hdserial header

I am considering a driver for using the IR, found on the Hackable Badge and QuickStart HIB board. Since their are a few PropBasic programmers here, which way would be the best way to accomplish this?

I found a Spin program that JonnyMac has developed, which has an PASM component and a Spin component. Using that as a reference, which approach is the best. From the jm_ir_hdserial.spin code, it looks like maybe taking the PASM section and trying to fit it in the PropBasic format would be a consideration, not sure about that though. Any ideas as to how to approach this? Of course this would be a lib file so it could be added/used in other PropBasic programs.

Ray
  { ----------------------------- }
  {  I R   U A R T   D R I V E R  }
  { ----------------------------- } 
  

dat { ir uart }

                        org     0

irhds                   mov     t1, par                          ' start of structure
                        mov     rxheadpntr, t1                   ' save hub address of rxhead
                                                                  
                        add     t1, #4                            
                        mov     rxtailpntr, t1                   ' save hub address of rxtail

                        add     t1, #4                            
                        rdlong  rxbufpntr, t1                    ' read address of rxbuf[0]
                                                          
                        add     t1, #4                            
                        mov     txheadpntr, t1                   ' save hub address of txhead
                                                                  
                        add     t1, #4                            
                        mov     txtailpntr, t1                   ' save hub address of txtail
                                                                  
                        add     t1, #4                            
                        rdlong  txbufpntr, t1                    ' read address of txbuf[0]
                          
                        add     t1, #4                            
                        rdlong  t2, t1                           ' get rxpin
                        mov     rxmask, #1                       ' make pin mask
                        shl     rxmask, t2                        
                        andn    dira, rxmask                     ' force to input
                                                                  
                        add     t1, #4                            
                        rdlong  t2, t1                           ' get txpin
                        mov     txmask, #1                       ' make pin mask
                        shl     txmask, t2
                        andn    dira, txmask                     ' disable modulation

                        add     t1, #4                            
                        rdlong  bit1x0tix, t1                    ' read 1.0 bit timing
                        mov     bit1x5tix, bit1x0tix             ' create 1.5 bit timing
                        shr     bit1x5tix, #1                     
                        add     bit1x5tix, bit1x0tix   

                        add     t1, #4                           ' get mod frequency
                        rdlong  frqa, t1                         ' setup ctra modulation
                        or      t2, NCO_SE                       ' on tx pin
                        mov     ctra, t2                         ' activate counter



' =========                                                       
'  RECEIVE                                                        
' =========                                                       
                                                                  
rxserial                mov     rxtimer, cnt                     ' start timer 
                        test    rxmask, ina             wc       ' look for start bit
        if_c            jmp     #txserial                        ' if no start, check tx
                                                                  
receive                 add     rxtimer, bit1x5tix               ' skip start bit
                        mov     rxwork, #0                       ' clear work var
                        mov     rxcount, #8                      ' rx 8 bits     
                                                                  
rxbyte                  waitcnt rxtimer, bit1x0tix               ' wait for middle of bit
                        test    rxmask, ina             wc       ' rx --> c
                        shr     rxwork, #1                       ' prep for next bit
                        muxc    rxwork, #%1000_0000              ' add bit tor rxwork
                        djnz    rxcount, #rxbyte

                        waitcnt rxtimer, #0                      ' let last bit finish
                        test    rxmask, ina             wc       ' verify stop bit
        if_nc           jmp     #txserial                        ' skip if bad IR input
                                                                  
putrxbuf                rdlong  t1, rxheadpntr                   ' t1 := rxhead
                        add     t1, rxbufpntr                    ' t1 := rxbuf[rxhead]
                        wrbyte  rxwork, t1                       ' rxbuf[rxhead] := rxwork
                        sub     t1, rxbufpntr                    ' t1 := rxhead 
                        add     t1, #1                           ' inc t1
                        and     t1, #BUF_MASK                    ' rollover if needed
                        wrlong  t1, rxheadpntr                   ' rxhead := t1
                                          
                                                                  
                                                                  
' ==========
'  TRANSMIT
' ==========

txserial                rdlong  t1, txheadpntr                   ' t1 = txhead  
                        rdlong  t2, txtailpntr                   ' t2 = txtail
                        cmp     t1, t2                  wz       ' byte(s) to tx?
        if_z            jmp     #rxserial                        ' check rx
                                                                  
gettxbuf                mov     t1, txbufpntr                    ' t1 := @txbuf[0]
                        add     t1, t2                           ' t1 := @txbuf[txtail]
                        rdbyte  txwork, t1                       ' txwork := txbuf[txtail] 
                                                                  
updatetxtail            add     t2, #1                           ' inc txtail
                        and     t2, #BUF_MASK                    ' wrap to 0 if necessary
                        wrlong  t2, txtailpntr                   ' save
                                                                  
transmit                or      txwork, STOP_BITS                ' set stop bit(s)
                        shl     txwork, #1                       ' add start bit
                        mov     txcount, #11                     ' start + 8 data + 2 stop
                        mov     txtimer, bit1x0tix               ' load bit timing
                        add     txtimer, cnt                     ' sync with system counter
                                                                  
txbit                   shr     txwork, #1              wc       ' move bit0 to C
                        muxnc   dira, txmask                     ' enable modulation if C == 0
                        waitcnt txtimer, bit1x0tix               ' let timer expire, reload   
                        djnz    txcount, #txbit                  ' update bit count

                        jmp     #txserial                         
                                                                  
                                                                  
' -------------------------------------------------------------------------------------------------

NCO_SE                  long    %00100 << 26                     ' S/E NCO mode  
STOP_BITS               long    $FFFF_FF00                        

rxheadpntr              res     1                                ' head pointer
rxtailpntr              res     1                                ' tail pointer
rxbufpntr               res     1                                ' hub address of rxbuf[0]
txheadpntr              res     1                                ' head pointer
txtailpntr              res     1                                ' tail pointer
txbufpntr               res     1                                ' hub address of txbuf[0]
                                                                
rxmask                  res     1                                ' rx pin mask
txmask                  res     1                                ' tx pin mask
bit1x0tix               res     1                                ' 1.0 bit timing
bit1x5tix               res     1                                ' 1.5 bit timing  

rxwork                  res     1                                ' rx byte in
rxcount                 res     1                                ' bits to receive
rxtimer                 res     1                                ' timer for bit sampling

txwork                  res     1                                ' tx byte out
txcount                 res     1                                ' bits to transmit
txtimer                 res     1                                ' timer for bit output
                                                                  
t1                      res     1                                ' work vars
t2                      res     1                                 
t3                      res     1                                 
                                 
                        fit     496
                        

Comments

  • JonnyMacJonnyMac Posts: 8,923
    edited 2016-08-27 21:31
    Since serial over IR is very slow, and PropBASIC compiles to PASM anyway, I'd suggest you rewrite what I did in PASM as a task that can run in its own cog. Shouldn't take more than an hour or two to knock it all together. See the Simple_Serial object that comes with Propeller Tool for serial routines in Spin.

    Receiving is the same everywhere. To transmit IR, you need to assign one of the counters to the TX pin and set it to run as an oscillator for your modulation frequency. When you want to output a start or "0" bit, enable the output driver for the TX pin.

    Easy peasy.
Sign In or Register to comment.