summaryrefslogtreecommitdiff
path: root/2004/n/mic799/mic799.asm
blob: d8ecce538bf62e5546c5b6a78e36f47d8c9b578a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
; NIQ800 : free clone of MIC800
; clock : 4,096MHz		 ( T_inst=1us )
; serial line : 9600bps  ( T= 104 cycles )
;--------------------
;Trame de commande :
; 1er octet de controle: Res-EE-cs2-cs1-cs0-s2-s1-s0
; 2eme octet de position: la position du servo de 0 � 255

; Maximum 1,25ms entre les deux octets, sinon, le premier est oubli�


;--------------------------------
	errorlevel 0, -224, -205, -302
;--------------------------------

;----- PORTABILITE --------------

	include "p16f876.inc"
	include "m_84.asm"
	__CONFIG  _DEBUG_OFF & _WRT_ENABLE_ON & _CPD_OFF & _LVP_OFF & _BODEN_ON & _PWRTE_ON & _WDT_OFF & _XT_OSC 

servo0	equ	0


Same    equ     1
MSB     equ     7

;*****************  Communication Parameters   **************************
;
X_MODE  equ     1       ; If ( X_MODE==1) Then transmit LSB first
;                         if ( X_MODE==0) Then transmit MSB first ( CODEC like )
R_MODE  equ     1       ; If ( R_MODE==1) Then receive LSB first
;                         if ( X_MODE==0) Then receive MSB first ( CODEC like )
X_Nbit  equ     1       ; if (X_Nbit==1) # of data bits ( Transmission ) is 8 else 7
R_Nbit  equ     1       ; if (R_Nbit==1) # of data bits ( Reception ) is 8 else 7
;
Sbit2   equ     0       ; if Sbit2 = 0 then 1 Stop Bit else 2 Stop Bits
;
;*************************************************************************
;X_flag  equ     PA0     ; Bit 5 of F3 ( PA0 )
;R_flag  equ     PA1     ; Bit 6 of F3 ( PA1 )
;
BAUD_1  equ     .68     ; 3+3X = CLKOUT/Baud
BAUD_2  equ     .67     ; 6+3X = CLKOUT/Baud
BAUD_3  equ     .34     ; 3+3X = 0.5*CLKOUT/Baud
BAUD_4  equ     .86     ; 3+3X = 1.25*CLKOUT/Baud
BAUD_X  equ     .66     ; 11+3X = CLKOUT/Baud
BAUD_Y  equ     .66     ; 9 +3X = CLKOUT/Baud


; -- Scratchpad du pic utilis� ( 1er adresse m�moire utilisable )
sp	equ	h'20'	;(PIC 16f876)

debug	equ	0	; debugging

;--------------------------------
; Variable definition
CBLOCK	sp
buffer_in
value:1
command:1
chipID:1
flags:1
countwdt:1
curentvalue:1
wsave:1
statussave
tabval:8
RcvReg  :1      ; Data received
XmtReg  :1      ; Data to be transmitted
Count   :1      ; Counter for #of Bits Transmitted
DlyCnt  :1
ENDC

rtcc	equ	tmr0

; bits de porta
chID0	equ	0
chID1	equ	1
chID2	equ	2
;servo0	equ	0

; dans flags
ms2	equ	0	; continuer la deuxi�me ms
portvide equ	1
f_sec_octet equ	2
; -- bits de flags
bus_wr	equ	3

; bits de l'octet commande :
reset_b	equ	7
eeprom_b equ	6

;-----------------------------
;-----------------------------
BUSROBOT.ASM
;-----------------------------
;-----------------------------

; -- option
optionval equ	b'01000010'
edg_msk equ	b'01000000'


; ***** Mise � jour de l'EEPROM
; ***********************************************

	org	h'2100'
	de	1,.40,.75,.110,.145,.180,.215,.255


; ***** D�but du code
; ***********************************************
	ORG	0	;vecteur de reset
	goto 	reset
	ORG	4
serviceint:
	btfsc	intcon,intf
	goto	busint

; ***** Interuption de timer *****
	btfss	flags,ms2	; test du flag seconde moiti�
	goto	suite2ms

clr:	;on efface toutes les lignes 
	clrf	portb
	bcf	porta,servo0
	bsf	flags,portvide	; �a y est le port est bien vide
	bcf	intcon,t0if	;flag timer
	retfie

suite2ms: ; on lance la seconde moiti�
	bsf	flags,ms2	; flag qui dit qu'on est entr� dans la seconde moiti�

	movwf	wsave

	clrf	rtcc
	movf	curentvalue,w	; on remplit la rtcc
	subwf	rtcc,f

	bcf	intcon,t0if	;flag timer
	movf	wsave,w
	retfie


; ***** Interuption de bus *****
busint:		
	movwf	wsave
	movf	status,w
	movwf	statussave

;***************************************************************
;       Receiver
;
Rcvr
	IF      R_Nbit
	movlw   8               ; 8 Data bits
	ELSE
	movlw   7               ; 7 data bits
	ENDIF
;
	movwf   Count
R_next  bcf     STATUS,C
	IF      R_MODE
	rrf     RcvReg,Same     ; to set if MSB first or LSB first
	ELSE
	rlf     RcvReg,Same
	ENDIF
	btfsc   PORTA,DR
;
	IF      R_MODE
	  IF      R_Nbit
	  bsf     RcvReg,MSB       ; Conditional Assembly
	  ELSE
	  bsf     RcvReg,MSB-1
	  ENDIF
	ELSE
	bsf     RcvReg,LSB
	ENDIF
;
	call    DelayY
	decfsz  Count,Same
	goto    R_next
;****************************************************
;R_over  movf    RcvReg,0        ; Send back What is Just Received
;	movwf   XmtReg

	call	work

;****************************************************
;       Transmitter
;
Xmtr
	IF      X_Nbit
	movlw   8
	ELSE
	movlw   7
	ENDIF
	movwf   Count
;
	IF      X_MODE
	ELSE
	  IF    X_Nbit
	  ELSE
	  rlf   XmtReg,Same
	  ENDIF
	ENDIF
;
	bcf     PORTA,DX       ; Send Start Bit
	call    Delay1
X_next  bcf     STATUS,C
;
	IF      X_MODE
	rrf     XmtReg,Same     ; Conditional Assembly
	ELSE                    ; to set if MSB first or LSB first
	rlf     XmtReg,Same
	ENDIF
;
	btfsc   STATUS,C
	bsf     PORTA,DX
	btfss   STATUS,C
	bcf     PORTA,DX
	call    DelayX
	decfsz  Count,Same
	goto    X_next
	bsf     PORTA,DX       ; Send Stop Bit
	call    Delay1
;
	IF      Sbit2
	bsf     PORTA,DX
	call    Delay1
	ENDIF
;
	goto    finbusint
;
;   End of Transmission
;

DelayY  movlw   BAUD_Y
	goto    save
DelayX  movlw   BAUD_X
	goto    save
Delay4  movlw   BAUD_4
	goto    save
Delay1  movlw   BAUD_1            ; 104 uS for 9600 baud
	goto    save
Delay2  movlw   BAUD_2
save    movwf   DlyCnt
redo_1  decfsz  DlyCnt,Same
	goto    redo_1
	retlw   0
;


;----------------------------
;-- old bus_int
;----------------------------
	movf	portc,w

	btfsc	flags,f_sec_octet
	goto	sec_octet
	movwf	command
	bsf	flags,f_sec_octet
	goto	finbusint

sec_octet
	movwf	value
	call	work
	bcf	flags,f_sec_octet

;----- dans tous les cas --------
finbusint:
	movf	statussave,w
	movwf	status
	movf	wsave,w
	bcf	intcon,intf
	retfie


; ***** La sous-routine de reset *****
reset:
; pour les tris, seuls les lignes � 0 peuvent �tre bascul�es en entr�e. Les broches � 1 doivent rester en entr�e ( sauf la broche RW dans le cas d'une liaison non-duplex )
	movlw	b'11111111'
	tris	porta
	movlw	b'11111101'	; B7-B2 = input /  B1 = TX / B0 = RX
	tris	portb
	movlw	b'00000000'	; C7-C2 = output / C1 = servo1 / C0 servo0
	tris	portc
	clrf	portc

	movlw	optionval
	option

	clrf	buffer_in

	bsf	flags,portvide
	bcf	flags,f_sec_octet

	movlw	b'10110000'	; (G|EE|T|I|Rb|T|I|Rb)
	movwf	intcon
	
	call	restore_defaults
	goto	main

;----------------
restore_defaults:
	clrf	eeadr
	movlw	tabval
	movwf	fsr
I=0
WHILE I<=7
;	EEread	; lit l'eeprom � l'adresse eeadr et place le r�sultat dans eedata
;	movf	eedata,w
	movlw	.128
	movwf	indf
	
	incf	fsr,f
	incf	eeadr,f
I++
ENDW
	return
	


;------------------------------
; interpr�tation de la commande
; 1er octet de controle: D5-D0 ! type ! voie
; type=1 => IO
; 	voie=1 => in
;	voie=0 => out
; type=0 => servo
; 	voie=1 => servo1
;	voie=0 => servo0

work:
	movf	RcvReg,w
	movwf	XmtReg,f	; on pr�pare l'�cho de la commande

; type de trame
	btfss	RcvReg,1
	goto	setServo

;-- Gestion des IO
setIO
	btfss	RcvReg,1
	goto	IOout
;-
IOin
	movf	portb,w
	movwf	XmtReg,f

;mise en forme de la trame :
	bsf	XmtReg,0	; IO
	bsf	XmtReg,1	; in

	return

;-
IOout
	movf	RcvReg,w
	andlw	'11111100'
	movwf	command
	
	movf	portc,w
	; il faut bouger toutes les pattes du portb sans toucher aux servos
	andlw	'00000011'	; on efface les IO
	iorwf	command		; on les met � jour avec la nouvelle valeur

	movwf	portc
	return


;-- Gestion des servos
setServo
; n� de servo
	movf	command,w
	andlw	b'11111100'
	movwf	value,f

	andlw	b'00000001'
	movwf	eeadr	; on pr�pare l'�criture en eeprom
	addlw	tabval
	movwf	fsr	; on met � jour le pointeur de tableau

	movf	value,w	; on copie la valeur dans le tableau
	movwf	indf


; �criture en eeprom ?
;	btfsc	command,eeprom_b
;	goto	seteeprom
;
;	return

;seteeprom:
;	movwf	eedata	; on met la valeur dans eedata
;	EEwrite

	return


;---- on passe par une macro pour sp�cifier le label en local
waitnext MACRO
	LOCAL	again

again:	btfss	flags,portvide	; si le portb est vide, alors il faut lancer le signal du servo suivant
	goto	again		; sinon, on continue le poling

	ENDM

;---------------
main:
I=0
WHILE I<=7
	waitnext	;ex�cute la macro 

	bcf	flags,ms2
	movlw	I
	addlw	tabval
	movwf	fsr

; ---- MODE PROTEGE ON ----
	bcf	intcon,gie

IF I==7 ;on allume la bonne ligne de sortie
	bsf	porta,servo0
ELSE
	bsf	portb,I+1
ENDIF
	bcf	flags,portvide	; le port n'est plus vide

; on charge la rtcc pour attendre la premi�re ms
	load	.198,rtcc	

; on met la valeur de la "seconde ms" dans curentvalue
; par cette technique, la position est �chelon�e de 0 � 255 ( avant : 1 correspondait au 1ms, donc on incr�mente la valeur, comme �a 0 correspond au 1 qui correspond � 1ms )
	incf	indf,w	
	movwf	curentvalue 

	bsf	intcon,gie
; ---- MODE PROTEGE OFF ----

I++
ENDW
	goto	main

END