OSDN Git Service

f028465766123b9ab96285ba8d3cd36b5947f7bf
[fast-forth/master.git] / MSP430-FORTH / IR_RC5.f
1 \ ---------------
2 \ IR_RC5_P1.2.f
3 \ ---------------
4 RST_STATE   \ to rub out this test with <reset> or RST_STATE or COLD
5
6 \ Copyright (C) <2014>  <J.M. THOORENS>
7 \
8 \ This program is free software: you can redistribute it and/or modify
9 \ it under the terms of the GNU General Public License as published by
10 \ the Free Software Foundation, either version 3 of the License, or
11 \ (at your option) any later version.
12 \
13 \ This program is distributed in the hope that it will be useful,
14 \ but WITHOUT ANY WARRANTY\ without even the implied warranty of
15 \ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 \ GNU General Public License for more details.
17 \
18 \ You should have received a copy of the GNU General Public License
19 \ along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
21
22 \ FORTH driver for IR remote compatible with the PHILIPS RC5 protocol, with select new/repeated command
23 \ target : see IR_RC5.pat
24
25 \ Send to terminal the RC5 new command.
26 \ Press S1 to send also RC5 repeated command.
27
28
29 \ HERE                            \ general minidump, part 1
30
31 \ --------------------------------------------------------------------------------------------
32 \ MSP-EXP430FR5969 driver for IR_RC5 receiver TSOP32236 wired on Px.y input \ 65 words, 24.5ms
33 \ --------------------------------------------------------------------------------------------
34
35 \ layout : see config.pat file for defining I/O
36
37 \ ******************************\
38 ASM RC5_INT                     \   wake up on Px.RC5 change interrupt
39 \ ******************************\
40 \ IR_RC5 driver                 \ IP,S,T,W,X,Y registers are free for use
41 \ ******************************\
42 \                               \ in :  SR(9)=old Toggle bit memory (ADD on)
43 \                               \       SMclock = 8|16|24 MHz
44 \                               \ use : TOS,IP,W,X,Y, TA0 timer, TA0R register
45 \                               \ out : TOS = 0 C6 C5 C4 C3 C2 C1 C0
46 \                               \       SR(9)=new Toggle bit memory (ADD on)
47 \ ******************************\
48 \ RC5_FirstStartBitHalfCycle:   \
49 \ ******************************\                division in TA0CTL (SMCLK/1,SMCLK/1,SMCLK/2,SMCLK/4,SMCLK/8)
50 \ MOV #0,&TA0EX0                \ predivide by 1 in TA0EX0 register ( 125kHz,   1MHz,   2MHZ,   4MHZ,   8MHZ), reset value
51 \ MOV #1,&TA0EX0                \ predivide by 2 in TA0EX0 register ( 250kHZ,   2MHz,   4MHZ,   8MHZ,  16MHZ)
52 \ MOV #2,&TA0EX0                \ predivide by 3 in TA0EX0 register ( 375kHz,   3MHz,   6MHZ,  12MHZ,  24MHZ)
53 \ MOV #3,&TA0EX0                \ predivide by 4 in TA0EX0 register ( 500kHZ,   4MHz,   8MHZ,  16MHZ)
54 \ MOV #4,&TA0EX0                \ predivide by 6 in TA0EX0 register ( 625kHz,   5MHz,  10MHZ,  20MHZ)
55 \ MOV #5,&TA0EX0                \ predivide by 6 in TA0EX0 register ( 750kHz,   6MHz,  12MHZ,  24MHZ)
56 \ MOV #6,&TA0EX0                \ predivide by 7 in TA0EX0 register ( 875kHz,   7MHz,  14MHZ,  28MHZ)
57 \ MOV #7,&TA0EX0                \ predivide by 8 in TA0EX0 register (   1MHz,   8MHz,  16MHZ,  32MHZ)
58 MOV #1778,X                     \ RC5_Period * 1us
59 \ MOV #222,X                    \ RC5_Period * 8us (SMCLK/1 and first column above)
60 MOV     #14,W                   \ count of loop
61 BEGIN                           \
62 \ ******************************\
63 \ RC5_HalfCycle                 \ <--- loop back ---+ with readjusted RC5_Period
64 \ ******************************\                   |
65 \   MOV #%1000100100,&TA0CTL    \ (re)start timer_A | SMCLK/1 time interval,free running,clear TA0_IFG and TA0R
66 \   MOV #%1002100100,&TA0CTL    \ (re)start timer_A | SMCLK/2 time interval,free running,clear TA0_IFG and TA0R
67 \   MOV #%1010100100,&TA0CTL    \ (re)start timer_A | SMCLK/4 time interval,free running,clear TA0_IFG and TA0R
68     MOV #%1011100100,&TA0CTL    \ (re)start timer_A | SMCLK/8 time interval,free running,clear TA0_IFG and TA0R
69 \ RC5_Compute_3/4_Period:       \                   |
70     RRUM    #1,X                \ X=1/2 cycle       |
71     MOV     X,Y                 \                   ^
72     RRUM    #1,Y                \ Y=1/4
73     ADD     X,Y                 \ Y=3/4 cycle
74     BEGIN   CMP Y,&TA0R         \3 wait 1/2 + 3/4 cycle = n+1/4 cycles 
75     U>= UNTIL                   \2
76 \ ******************************\
77 \ RC5_SampleOnFirstQuarter      \ at n+1/4 cycles, we sample RC5_input, ST2/C6 bit first
78 \ ******************************\
79     BIT.B   #RC5,&IR_IN         \ C_flag = IR bit
80     ADDC    IP,IP               \ C_flag <-- IP(15):IP(0) <-- C_flag
81     MOV.B   &IR_IN,&IR_IES      \ preset Px_IES.y state for next IFG
82     BIC.B   #RC5,&IR_IFG        \ clear Px_IFG.y after 4/4 cycle pin change
83     SUB     #1,W                \ decrement count loop
84 \                               \  count = 13 ==> IP = x  x  x  x  x  x  x  x |x  x  x  x  x  x  x /C6
85 \                               \  count = 0  ==> IP = x  x /C6 Tg A4 A3 A2 A1|A0 C5 C4 C3 C2 C1 C0  1 
86 0<> WHILE                       \ ----> out of loop ----+
87     ADD X,Y                     \                       |   Y = n+3/4 cycles = time out because n+1/2 cycles edge is always present
88     BEGIN                       \                       |
89         MOV &TA0R,X             \3                      |   X grows from n+1/4 up to n+3/4 cycles
90         CMP Y,X                 \1                      |   cycle time out of bound ?
91         U>= ?GOTO FW1           \2                  ^   |   yes: quit on truncated RC5 message
92         BIT.B #RC5,&IR_IFG      \3                  |   |   n+1/2 cycles edge is always present
93     0<> UNTIL                   \2                  |   |
94 REPEAT                          \ ----> loop back --+   |   with X = new RC5_period value
95 \ ******************************\                       |
96 \ RC5_SampleEndOf:              \ <---------------------+
97 \ ******************************\
98 \ RC5_ComputeNewRC5word         \
99 \ ******************************\
100 SUB     #2,PSP                  \
101 MOV     TOS,0(PSP)              \ save TOS before use
102 RLAM    #1,IP                   \ IP =  x /C6 Tg A4 A3 A2 A1 A0|C5 C4 C3 C2 C1 C0  1  0
103 MOV.B   IP,TOS                  \ TOS = C5 C4 C3 C2 C1 C0  1  0
104 RRUM    #2,TOS                  \ TOS =  0  0 C5 C4 C3 C2 C1 C0
105 \ ******************************\
106 \ RC5_ComputeC6bit              \
107 \ ******************************\
108 BIT     #BIT14,IP               \ test /C6 bit in IP
109 0= IF   BIS #BIT6,TOS           \ set C6 bit in TOS
110 THEN                            \ TOS =  0  C6 C5 C4 C3 C2 C1 C0
111 \ ******************************\
112 \ RC5_CommandByteIsDone         \ -- BASE RC5_code
113 \ ******************************\
114 \ Only New_RC5_Command ADD_ON   \ use SR(9) bit as toggle bit
115 \ ******************************\
116 RRUM    #4,IP                   \5 new toggle bit = IP(13) ==> IP(9)
117 XOR     SR,IP                   \ (new XOR old) Toggle bits
118 BIT     #UF1,IP                 \ repeated RC5_command ?
119 0= ?GOTO FW2                    \ yes, RETI without UF1 change
120 \ ******************************\
121 XOR #UF1,0(RSP)                 \ 5 toggle bit memory
122 FW2                             \   endof repeated RC5_command : RETI without UF1 change
123 FW1                             \   endof truncated RC5 message
124 BIC #$30,&TA0CTL                \   stop timer_A0
125 BIC #$F8,0(RSP)                 \ 4  SCG1,SCG0,OSCOFF,CPUOFF and GIE are OFF in retiSR to force LPM0_LOOP despite pending interrupt
126 RETI                            \ 5 for system OFF / 1 sec. ==> 1mA * 5us = 5nC + 6,5uA
127 ENDASM
128     \ 
129
130
131 \ ------------------------------\
132 CODE START                      \
133 \ ------------------------------\
134 \ init PORTX (P2:P1) (complement) default I/O are input with pullup resistors
135     BIC.B   #RC5,&PIRIFG        \ P1IFG.2 clear int flag for TSOP32236     (after IES select)
136     BIS.B   #RC5,&PIRIE         \ P1IE.2 enable interrupt for TSOP32236
137 \ ------------------------------\
138 \ define LPM mode for ACCEPT    \
139 \ ------------------------------\
140 \ MOV #LPM4,&LPM_MODE             \ with MSP430FR59xx
141 \ MOV #LPM2,&LPM_MODE             \ with MSP430FR57xx, terminal input don't work for LPMx > 2
142 \                                 \ with MSP430FR2xxx, terminal input don't work for LPMx > 0 ; LPM0 is the default value
143 \ ------------------------------\
144 \ init interrupt vectors        \
145 \ ------------------------------\
146     MOV     #INT_RC5,&IR_Vec    \ init Px vector interrupt
147 \ ------------------------------\
148     LO2HI
149 \ ------------------------------\
150 \ START is included in WARM     \
151 \ ------------------------------\
152     LIT RECURSE IS WARM         \ insert this starting routine between COLD and WARM...
153     ['] WARM >BODY EXECUTE      \ ...and continue with WARM (that unlocks I/O).
154  ;                              \
155
156 \ ------------------------------\
157 : STOP                          \ stops multitasking, must to be used before downloading app
158 \ ------------------------------\
159     ['] WARM >BODY IS WARM      \ remove START app from FORTH init process
160     ECHO COLD                   \ reset CPU, interrupt vectors, and start FORTH
161 ;
162
163 \ HERE OVER - DUMP              \ general minidump, part 2
164
165 PWR_HERE    \
166
167
168
169 \ --------------------------------------------------\
170 \ PHILIPS IR REMOTE RC5/RC6 protocol                \
171 \ --------------------------------------------------\
172 \ first half bit = no light, same as idle state
173 \ second half bit : 32 IR-light pulses of 6,944us,light ON/off ratio = 1/3
174
175 \        |<------32 IR light pulses = second half of first start bit ------->|
176 \        |_     _     _     _     _     _     _     _     _     _     _     _|
177 \ ...____| |___| |___| |___| |___| |___| |...| |___| |___| |___| |___| |___| |____________________________________...
178 \        |                                                                   |
179
180
181
182 \ at the output of IR receiver TSOPxxx during the first start bit :
183
184 \ ...idle state ->|<----- first half bit ------>|<- second half bit (IR light) ->|
185 \ ..._____________|_____________________________|                                |_________...
186 \                 |                             |                                |
187 \                 |                             |                                |
188 \                 |                             |________________________________|
189
190 \ 32 cycles of 27,777us (36kHz) = 888,888 us
191 \ one bit = 888,888 x 2 = 1778 us.
192
193
194
195 \   14 bits of active message   = 24.889 ms
196 \ + 50  bits of silent (idle)   = 88.888 ms
197 \ = RC5 message                 = 113.792 ms
198
199 \
200 \ RC5_message on IR LIGHT \ idle state = light off
201
202 \ 89ms>|<--------------------------------------------------24.889 ms-------------------------------------------------->|<88,
203 \      |                                                                                                               |
204 \      |       |       |       |       |       |       |       |       |       |       |       |       |       |       | 
205 \      |  ST1  | ST2/C6|  Tog  |  A4   |  A3   |  A2   |  A1   |  A0   |  C5   |  C4   |  C3   |  C2   |  C1   |  C0   |
206 \      |       |       |       |       |       |       |       |       |       |       |       |       |       |       | 
207 \          1       1       1       1       0       0       1       1       1       1       1       1       1       1 
208 \           ___     ___     ___     _______     ___         ___     ___     ___     ___     ___     ___     ___     ___ 
209 \          ^   |   ^   |   ^   |   ^       |   |   |       ^   |   ^   |   ^   |   ^   |   ^   |   ^   |   ^   |   ^   |
210 \  idle____|   |___|   |___|   |___|       v___|   v_______|   |___|   |___|   |___|   |___|   |___|   |___|   |___|   |____
211 \          
212 \
213 \ notice that each cycle contains its bit value preceded by its complement
214
215
216
217
218 \ the same RC5_message inverted at the output of IR receiver : idle state = 1
219 \
220 \       |       |       |       |       |       |       |       |       |       |       |       |       |       |       |
221 \       |  ST1  | ST2/C6|  Tog  |  A4   |  A3   |  A2   |   A1  |  A0   |  C5   |  C4   |  C3   |  C2   |  C1   |  C0   |
222 \       |       |       |       |       |       |       |       |       |       |       |       |       |       |       |
223 \           1       1       1       1       0       0       1       1       1       1       1       1       1       1  
224 \  idle_____     ___     ___     ___         ___     _______     ___     ___     ___     ___     ___     ___     ___     __idle
225 \           |   |   |   |   |   |   |       ^   |   ^       |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
226 \           v___|   v___|   v___|   v_______|   |___|       v___|   v___|   v___|   v___|   v___|   v___|   v___|   v___|
227 \           I       R       R       R       R       R       R       R       R       R       R       R       R       R
228 \
229 \ notice that each cycle contains its bit value followed by its complement
230
231
232
233
234 \ principe of the driver : 13 samples at 1/4 period and Resynchronise (R) on 1/2 period (two examples)
235
236 \       0,888 ms
237 \       |<->|<--------------------------------routine time = 12 3/4 cycles = 22.644 ms--------------------------->|
238 \       |       |       |       |       |       |       |       |       |       |       |       |       |       | |     |
239 \       |  ST1  | ST2/C6| Toggle|  A4   |  A3   |  A2   |   A1  |  A0   |  C5   |  C4   |  C3   |  C2   |  C1   | |C0   |
240 \       |       |       |       |       |       |       |       |       |       |       |       |       |       | |     |
241 \           1       1       1       1       0       0       1       1       1       1       1       1       1     | 1  
242 \  idle_____     _s_     _s_     _s_         ___     _____s_     _s_     _s_     _s_     _s_     _s_     _s_     _s_     __idle
243 \           |   |   |   |   |   |   |       ^   |   ^       |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
244 \           v___|   v___|   v___|   v_____s_|   |_s_|       v___|   v___|   v___|   v___|   v___|   v___|   v___|   v___|
245 \           I       R       R       R       R       R       R       R       R       R       R       R       R       ^   ^
246 \                 |       |       |       |       |       |       |       |       |       |       |       |       | |   |
247 \ samples :       1       2       3       4       5       6       4       8       9       10      11      12      13|   |
248 \                                                                                                                   |   | 
249 \ good ! but we have too many RC5_Int...---------------->                                                           I   I
250
251 \       0,888 ms
252 \       |<->|<--------------------------------routine time = 12 3/4 cycles = 22.644 ms--------------------------->|
253 \       |       |       |       |       |       |       |       |       |       |       |       |       |       | |     |
254 \       |  ST1  | ST2/C6| Toggle|  A4   |  A3   |  A2   |   A1  |  A0   |  C5   |  C4   |  C3   |  C2   |  C1   | |C0   |
255 \       |       |       |       |       |       |       |       |       |       |       |       |       |       | |     |
256 \           1       1       1       1       0       0       1       1       1       1       1       1       1     | 1
257 \  idle_____     _s_     _s_     ___         _o_     _o___s_     _s_     _s_     _s_     _s_     _s_     _s_         ______idle
258 \           |   |   |   |   |   |   |       ^   |   ^       |   |   |   |   |   |   |   |   |   |   |   |   |       ^   
259 \           v___|   v_o_|   v_o_|   v_o___s_|   |_s_|       v_o_|   v_o_|   v_o_|   v_o_|   v_o_|   v_o_|   v_o___s_|
260 \           I       R       R       R       R       R       R       R       R       R       R       R       R       ^
261 \                 |       |       |       |       |       |       |       |       |       |       |       |       | |
262 \ samples :       1       2       3       4       5       6       7       8       9       10       11     12      13|
263 \                                                                                                                   |
264 \ good ! but we have too many RC5_Int...------------------>                                                         I
265 \
266
267
268  
269
270 \ So, to avoid these RC5_Int after end : 13+1=14 samples, then the result is shifted one to wipe the 14th (two examples)
271
272 \       0,888 ms
273 \       |<->|<--------------------------------routine time = 13 3/4 cycles = 24.447 ms----------------------------------->|
274 \       |       |       |       |       |       |       |       |       |       |       |       |       |       |       | |
275 \       |  ST1  | ST2/C6| Toggle|  A4   |  A3   |  A2   |   A1  |  A0   |  C5   |  C4   |  C3   |  C2   |  C1   |  C0   | |
276 \       |   1   |   1   |   1   |   1   |   0   |   0   |   1   |   1   |   1   |   1   |   1   |   1   |   1   |   1   | | 
277 \       |       |       |       |       |       |       |       |       |       |       |       |       |       |       | |
278 \  idle_____     _s_     _s_     _s_         _o_     _o___s_     _s_     _s_     _s_     _s_     _s_     _s_     _s_     _s_idle
279 \           |   |   |   |   |   |   |       ^   |   ^       |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |
280 \           v___|   v_o_|   v_o_|   v_o___s_|   |_s_|       v_o_|   v_o_|   v_o_|   v_o_|   v_o_|   v_o_|   v_o_|   v_o_|
281 \           I   i   R   i   R   i   R       R   i   R       R   i   R   i   R   i   R   i   R   i   R   i   R   i   R   i
282 \                 |       |       |       |       |       |       |       |       |       |       |       |       |       |
283 \ samples :       1       2       3       4       5       6       7       8       9       10      11      12      13      14
284 \
285
286 \       0,888 ms
287 \       |<->|<--------------------------------routine time = 13 3/4 cycles = 24.447 ms----------------------------------->|
288 \       |       |       |       |       |       |       |       |       |       |       |       |       |       |       | |
289 \       |  ST1  | ST2/C6| Toggle|  A4   |  A3   |  A2   |   A1  |  A0   |  C5   |  C4   |  C3   |  C2   |  C1   |  C0   | |
290 \       |   1   |   1   |   1   |   1   |   0   |   0   |   1   |   1   |   1   |   1   |   1   |   1   |   1   |   0   | | 
291 \       |       |       |       |       |       |       |       |       |       |       |       |       |       |       | |
292 \  idle_____     _s_     _s_     _s_         _o_     _o___s_     _s_     _s_     _s_     _s_     _s_     _s_         _o___s_idle
293 \           |   |   |   |   |   |   |       ^   |   ^       |   |   |   |   |   |   |   |   |   |   |   |   |       ^   
294 \           v___|   v_o_|   v_o_|   v_o___s_|   |_s_|       v_o_|   v_o_|   v_o_|   v_o_|   v_o_|   v_o_|   v_o___s_|
295 \           I   i   R   i   R   i   R       R   i   R       R   i   R   i   R   i   R   i   R   i   R   i   R       R
296 \                 |       |       |       |       |       |       |       |       |       |       |       |       |       |
297 \ samples :       1       2       3       4       5       6       7       8       9       10      11      12      13      14
298
299
300 \ I = first interruption at the first 1/2 cycle : clear and start timer
301 \ i = useless RC5_Int (because aperiodic) at 4/4 cycle
302 \ s = sample RC5_intput at (1/2+3/4) = 5/4 cycle = n+1/4 cycles and clear useless RC5_Int
303 \ R = usefull (periodic) RC5_Int at 6/4 cycle = n+1/2 cycles : load new timer value, then clear it and restart it
304 \ o = RC5_Int time out at 7/4 cycle = n+3/4 cycles, used to detect truncated RC5_message (samples<14)
305
306 \ see also : http://www.sbprojects.com/knowledge/ir/rc5.php
307 \            http://laurent.deschamps.free.fr/ir/rc5/rc5.htm
308 \ Code RC5 : http://en.wikipedia.org/wiki/RC-5
309