(* Micro Launchpad demo program for 16 MHz Xtal
    S?      = P1.3
    Led     = P1.0
    Power   = P2.4
    RC5-in  = P2.0
*)

hex
\ Period length is 1000 clock cycles ( #CYCLUS )
dm 1000 constant #CYCLUS
value POWER
: LOWER             power if  dm -20 +to power  then ;
: HIGHER            power #cyclus u< if  dm 20 +to power  then ;

: STOP-TIMER1       0 180 ! ;   \ TA1CTL
: PWM-OFF           stop-timer1  010 02E *bic ; \ P2SEL

: >PWM              ( 0 to #CYCLUS -- )
    #cyclus umin  196 ! ;       \ TA1CCR2   Set pulselength

: SWITCH             ( -- )     \ Set LED to current power value or off
    196 @ if  0 >pwm  else  power >pwm  then ;

\ PWM AT 2.4 or P2.5
: SETUP-PWM         ( -- )
    038 022 *bic 038 021 *bis   \ P1DIR,  P1IN  P1.3 to P1.5 are inputs
    038 027 *bis                \ P1REN   with pullup
    010 02E *bis 010 02A *bis   \ P2SEL, P2DIR  Set PWM to output pin P2.4
    stop-timer1  #cyclus 192 !  \ TA1CCR0  Set period time
    040 186 !                   \ TA1CCTL2 Set output mode positive pulse
    234  180 !                  \ TA1CTL   Activate timer
    0 >pwm ;


\ RC5 decoder
: RED       01 21 ;                    \ P1OUT  Red led at P1.0
: LAMP      10 29 ;                    \ P2OUT  Power out at P2.4 (4 Amp. max.)

\ Bit 6 t/m 10 are the system-bits they contain the device address
\ TV = 00 -> 0000, CD = 20 -> 0500 en VCR = 05 -> 0140
dm 00  6 lshift  constant RCTYPE        \ RC5 transmitter type
value RCDATA                            \ Command databyte (14 bits)
value RC#                               \ Number of received bits

\ Give true when there is a valid RC5 command is for this device.
value RCKEY?        ( -- flag )

code INTERRUPT-ON       #8 sr bis  next  end-code
code INTERRUPT-OFF      #8 sr bic  next  end-code

routine RCBIT-IN    ( -- )              \ Read, decode and collect RC-bits
    dm 1760 # 172 & mov                 \ TA0R   Next half period in 880 us
    #1  adr rc# & add                   \ Increase half-bit counter
    #1  adr rc# & bit  cc? if,          \ Test even bits
        day push                        \ Save help register
        adr rcdata &  day mov           \ Copy of low bit in day
        #1  28 & .b bit                 \ P2IN  Read input P2.0 to carry
        #0  day addc                    \ Add carry to previous half-bit
        #1  day bit  cs? if,            \ Bit pattern valid (uneven) 1/0 or 0/1?
            1C #  adr rc# & cmp  =? if, \ All 14 (28 half)bits collected?
                adr rcdata &  day mov   \ Copy data
                07C0 #  day and>        \ Only valid address bits needed
                rctype # day cmp  =? if, \ My address?
                    #-1  adr rckey? & mov \ Yes, command valid!
                    #1  2B & .b bic     \ P2IFG  Reset HW interrupt flag
                    #1  2D & .b bis     \ P2IE   HW interrupt on
                    #0  160 & mov       \ TA0CTL Stop timer
                then,
            then,
        else,                           \ Invalid pattern, restart!
            #1  2B & .b bic             \ P2IFG  Reset HW interrupt flag
            #1  2D & .b bis             \ P2IE   HW interrupt on
            #0  160 & mov               \ TA0CTL Stop timer
        then,
        rp )+ day mov                   \ Restore original day
    else,
        #1  28 & .b bit                 \ P2IN   Read input P2.0
        adr rcdata & adr rcdata & addc  \ Save first half-bit
    then,
    reti
end-code

routine RCSTART     ( -- )          \ Edge noticed, start decoder!
    #0  adr rckey? & cmp  =? if,
        #1 2D & .b bic              \ P2IE    Stop hardware interrupt
        dm 860 #  172 & mov         \ TA0CCR0 Set time to first sample, 430 us (~0,43 ms)
        02D4 #  160 & mov           \ TA0CTL  Start timer
        #1  adr rc# & mov           \ Fake half received bit,
        #1  adr rcdata & mov        \ Fake bit is high!
    then,
    #1  2B & .b bic                 \ Reset HW interrupt flag
    reti
end-code

: RC-ON             ( -- )          \ Install decoder hardware
    0000 160 !  0010 162 !          \ TA0CTL, TA0CCTL0 Timer A0 off and compare 0 interrupt on
\ Set hardware interrupt at P2.0 ready, all other bits of P2 are outputs
    00 02E c!                       \ P2SEL  Port-2 use all bits as normal I/O
    01 2F *bis                      \ P2REN  Bit-0 resistor on
    FE 2A c!                        \ P2DIR  Bit-0 is input, 1 t/m 7 are output
    01 29 *bis                      \ P2OUT  Bit-0 pullup resistance
    01 2C *bis                      \ P2IES  Bit-0 falling edge
    01 2B *bic                      \ P2IFG  Bit-0 reset HW interrupt flag
    01 2D *bis                      \ P2IE   Bit-0 interrupt on
    0 to rckey?                     \ Allow new key input
    interrupt-on ;                  \ Activate decoder

: RC-OFF            ( -- )
    interrupt-off                   \ Deactivate decoder
    0000 160 !  0000 162 !          \ TA0CTL, TA0CCTL0 Stop timer-A0
    01 2D *bic ;                    \ P2IE   HW interrupts off

\ Receive a RC5 databyte, x is a code from the definined RC5-code
\ command set. More info search for RC5 device documentation
\ here: https://en.wikipedia.org/wiki/RC-5
: RCKEY             ( -- x )        \ Wait for an RC5 command
    begin  rckey? until             \ Wait for valid key
    rcdata 3F and                   \ Low 6-bits are key-code
    0 to rckey? ;                   \ Allow next key

: RCTEST    ( -- )                  \ Print pressed rc key
    rc-on  red *bis  100 ms
    begin
        red *bic  rckey .
        red *bis  50 ms
    key? until
    red *bic  rc-off ;

: SLOWDOWN  ( -- )
    F0 ms  rckey? if  rckey drop  then ;

: FLASH     ( -- )                  \ Flash red led
    8 0 do  red *bix  100 ms  loop ;

: RC-LAMP   ( -- )                  \ Control LED lamp
    rckey
    dup 0C = if  switch  slowdown   then
    dup 10 = if  higher power >pwm  then
        11 = if  lower power >pwm   then ;

: RCDEMO    ( -- )
    rc-on  setup-pwm  dm 200 to power
    lamp *bic  flash
    begin
        rckey? if  rc-lamp  then
    key? until
    0 >pwm  lamp *bic  rc-off ;


rcbit-in    FFF2 vec!         \ Set Timer A0 interrupt vector
rcstart     FFE6 vec!         \ Set P2 interrupt vector
shield rc5r\

' rcdemo  to app  freeze

\ End
