-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.lst
1878 lines (1874 loc) · 68.8 KB
/
main.lst
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
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
CCS PCH C Compiler, Version 5.007, 61971 02-Haz-24 16:55
Filename: D:\BACKUP\GitHub Calismalar\PIC-CANBus-Communication\main.lst
ROM used: 2056 bytes (6%)
Largest free fragment is 30708
RAM used: 41 (3%) at main() level
93 (6%) worst case
Stack used: 1 locations (0 in main + 1 for interrupts)
Stack size: 31
*
0000: GOTO 0708
*
0008: MOVWF 04
000A: MOVFF FD8,05
000E: MOVFF FE0,06
0012: MOVLB 0
0014: MOVFF FE9,0C
0018: MOVFF FEA,07
001C: MOVFF FE1,08
0020: MOVFF FE2,09
0024: MOVFF FD9,0A
0028: MOVFF FDA,0B
002C: MOVFF FF3,12
0030: MOVFF FF4,13
0034: MOVFF FFA,14
0038: MOVFF 00,0E
003C: MOVFF 01,0F
0040: MOVFF 02,10
0044: MOVFF 03,11
0048: BTFSS F9D.0
004A: GOTO 0054
004E: BTFSC F9E.0
0050: GOTO 00A2
0054: BTFSS FA3.0
0056: GOTO 0060
005A: BTFSC FA4.0
005C: GOTO 0294
0060: MOVFF 0E,00
0064: MOVFF 0F,01
0068: MOVFF 10,02
006C: MOVFF 11,03
0070: MOVFF 0C,FE9
0074: MOVFF 07,FEA
0078: BSF 07.7
007A: MOVFF 08,FE1
007E: MOVFF 09,FE2
0082: MOVFF 0A,FD9
0086: MOVFF 0B,FDA
008A: MOVFF 12,FF3
008E: MOVFF 13,FF4
0092: MOVFF 14,FFA
0096: MOVF 04,W
0098: MOVFF 06,FE0
009C: MOVFF 05,FD8
00A0: RETFIE 0
.................... #include <18F458.h>
.................... //////// Standard Header file for the PIC18F458 device ////////////////
.................... #device PIC18F458
....................
.................... #list
....................
.................... #include <can-18xxx8.c>
.................... /////////////////////////////////////////////////////////////////////////
.................... //// can-18xxx8.c ////
.................... //// CAN Library routines for Microchip's PIC18Cxx8 and 18Fxx8 line ////
.................... //// ////
.................... //// This library provides the following functions: ////
.................... //// (for more information on these functions see the comment ////
.................... //// header above each function) ////
.................... //// ////
.................... //// can_init - Configures the PIC18xxx8 CAN peripheral ////
.................... //// ////
.................... //// can_set_baud - Sets the baud rate control registers ////
.................... //// ////
.................... //// can_set_mode - Sets the CAN module into a specific mode ////
.................... //// ////
.................... //// can_set_id - Sets the standard and extended ID ////
.................... //// ////
.................... //// can_get_id - Gets the standard and extended ID ////
.................... //// ////
.................... //// can_putd - Sends a message/request with specified ID ////
.................... //// ////
.................... //// can_getd - Returns specified message/request and ID ////
.................... //// ////
.................... //// can_kbhit - Returns true if there is data in one of the ////
.................... //// receive buffers ////
.................... //// ////
.................... //// can_tbe - Returns true if the transmit buffer is ready to ////
.................... //// send more data ////
.................... //// ////
.................... //// can_abort - Aborts all pending transmissions ////
.................... //// ////
.................... //// PIN_B3 is CANRX, and PIN_B2 is CANTX. You will need a CAN ////
.................... //// transceiver to connect these pins to CANH and CANL bus lines. ////
.................... //// ////
.................... //// CCS provides an example, ex_can.c, which shows how to use this ////
.................... //// library. ////
.................... //// ////
.................... /////////////////////////////////////////////////////////////////////////
.................... //// ////
.................... //// Version History ////
.................... //// ////
.................... //// Jul 27 04 - can_init() uses CAN_USE_EXTENDED_ID instead of ////
.................... //// setting all RX filters to extended. ////
.................... //// ////
.................... //// Feb 24 04 - can_get_id() fixed for EID<18:20>. ////
.................... //// ////
.................... //// Mar 30 09 - added CANTX2 code for PIC18F6585/8585/6680/8680 ////
.................... //// ////
.................... //// May 18 10 - changed variable types to unsigned incase compiled ////
.................... //// with #device ANSI, which makes variables signed ////
.................... //// ////
.................... //// Apr 20 11 - updated for new PIC18FxxK80 chips ////
.................... //// ////
.................... //// Jan 10 13 - updated can_init() function to setup correct tris ////
.................... //// register for PIC being used. ////
.................... //// ////
.................... /////////////////////////////////////////////////////////////////////////
.................... //// (C) Copyright 1996,2013 Custom Computer Services ////
.................... //// This source code may only be used by licensed users of the CCS ////
.................... //// C compiler. This source code may only be distributed to other ////
.................... //// licensed users of the CCS C compiler. No other use, ////
.................... //// reproduction or distribution is permitted without written ////
.................... //// permission. Derivative programs created using this software ////
.................... //// in object code form are not restricted in any way. ////
.................... /////////////////////////////////////////////////////////////////////////
....................
.................... #include <can-18xxx8.h>
.................... /////////////////////////////////////////////////////////////////////////
.................... //// can-18xxx8.h ////
.................... //// ////
.................... //// Prototypes, definitions, defines and macros used for and with ////
.................... //// the CCS CAN library for PIC18Fxx8 and PIC18Cxx8. ////
.................... //// ////
.................... //// (see can-18xxx8.c) ////
.................... //// ////
.................... /////////////////////////////////////////////////////////////////////////
.................... //// (C) Copyright 1996,2013 Custom Computer Services ////
.................... //// This source code may only be used by licensed users of the CCS ////
.................... //// C compiler. This source code may only be distributed to other ////
.................... //// licensed users of the CCS C compiler. No other use, ////
.................... //// reproduction or distribution is permitted without written ////
.................... //// permission. Derivative programs created using this software ////
.................... //// in object code form are not restricted in any way. ////
.................... /////////////////////////////////////////////////////////////////////////
....................
.................... #ifndef __CCS_CAN18xxx8_LIB_DEFINES__
.................... #define __CCS_CAN18xxx8_LIB_DEFINES__
....................
.................... #ifndef CAN_DO_DEBUG
.................... #define CAN_DO_DEBUG FALSE
.................... #endif
....................
.................... #IFNDEF CAN_USE_EXTENDED_ID
.................... #define CAN_USE_EXTENDED_ID TRUE
.................... #ENDIF
....................
.................... #IFNDEF CAN_BRG_SYNCH_JUMP_WIDTH
.................... #define CAN_BRG_SYNCH_JUMP_WIDTH 0 //synchronized jump width (def: 1 x Tq)
.................... #ENDIF
....................
.................... #IFNDEF CAN_BRG_PRESCALAR
.................... #define CAN_BRG_PRESCALAR 4 //baud rate generator prescalar (def: 4) ( Tq = (2 x (PRE + 1))/Fosc )
.................... #ENDIF
....................
.................... #ifndef CAN_BRG_SEG_2_PHASE_TS
.................... #define CAN_BRG_SEG_2_PHASE_TS TRUE //phase segment 2 time select bit (def: freely programmable)
.................... #endif
....................
.................... #ifndef CAN_BRG_SAM
.................... #define CAN_BRG_SAM 0 //sample of the can bus line (def: bus line is sampled 1 times prior to sample point)
.................... #endif
....................
.................... #ifndef CAN_BRG_PHASE_SEGMENT_1
.................... #define CAN_BRG_PHASE_SEGMENT_1 5 //phase segment 1 (def: 6 x Tq)
.................... #endif
....................
.................... #ifndef CAN_BRG_PROPAGATION_TIME
.................... #define CAN_BRG_PROPAGATION_TIME 2 //propagation time select (def: 3 x Tq)
.................... #endif
....................
.................... #ifndef CAN_BRG_WAKE_FILTER
.................... #define CAN_BRG_WAKE_FILTER FALSE //selects can bus line filter for wake up bit
.................... #endif
....................
.................... #ifndef CAN_BRG_PHASE_SEGMENT_2
.................... #define CAN_BRG_PHASE_SEGMENT_2 5 //phase segment 2 time select (def: 6 x Tq)
.................... #endif
....................
.................... #ifndef CAN_USE_RX_DOUBLE_BUFFER
.................... #define CAN_USE_RX_DOUBLE_BUFFER TRUE //if buffer 0 overflows, do NOT use buffer 1 to put buffer 0 data
.................... #endif
....................
.................... #ifndef CAN_ENABLE_DRIVE_HIGH
.................... #define CAN_ENABLE_DRIVE_HIGH 0
.................... #endif
....................
.................... #ifndef CAN_ENABLE_CAN_CAPTURE
.................... #define CAN_ENABLE_CAN_CAPTURE 0
.................... #endif
....................
.................... #ifndef CAN_ENABLE_CANTX2 // added 03/30/09 for PIC18F6585/8585/6680/8680
.................... #define CAN_ENABLE_CANTX2 0 // 0 CANTX2 disabled, 1 CANTX2 enabled
.................... #endif
....................
.................... #ifndef CAN_CANTX2_SOURCE // added 03/30/09 for PIC18F6585/8585/6680/8680
.................... #define CAN_CANTX2_SOURCE 0 // 0 source is invert of CANTX1, 1 source is CAN Clock
.................... #endif
....................
.................... enum CAN_OP_MODE {CAN_OP_CONFIG=4, CAN_OP_LISTEN=3, CAN_OP_LOOPBACK=2, CAN_OP_DISABLE=1, CAN_OP_NORMAL=0};
.................... enum CAN_WIN_ADDRESS {CAN_WIN_RX0=0, CAN_WIN_RX1=5, CAN_WIN_TX0=4, CAN_WIN_TX1=3, CAN_WIN_TX2=2};
....................
.................... //can control
.................... struct {
.................... int1 void0; //0
.................... CAN_WIN_ADDRESS win:3; //1:3 //window address bits
.................... int1 abat; //4 //abort all pending transmissions
.................... CAN_OP_MODE reqop:3; //5:7 //request can operation mode bits
.................... } CANCON;
.................... #byte CANCON = getenv("SFR:CANCON") //0xF6F
....................
....................
.................... enum CAN_INT_CODE {CAN_INT_WAKEUP=7, CAN_INT_RX0=6, CAN_INT_RX1=5, CAN_INT_TX0=4, CAN_INT_TX1=3, CAN_INT_TX2=2, CAN_INT_ERROR=1, CAN_INT_NO=0};
....................
.................... //can status register READ-ONLY
.................... struct {
.................... int1 void0; //0
.................... CAN_INT_CODE icode:3; //1:3 //interrupt code
.................... int1 void4; //4
.................... CAN_OP_MODE opmode:3; //5:7 //operation mode status
.................... } CANSTAT;
.................... #byte CANSTAT = getenv("SFR:CANSTAT") //0xF6E
....................
.................... //communication status register READ-ONLY
.................... struct {
.................... int1 ewarn; //0 //error warning
.................... int1 rxwarn; //1 //receiver warning
.................... int1 txwarn; //2 //transmitter warning
.................... int1 rxbp; //3 //receiver bus passive
.................... int1 txbp; //4 //transmitter bus passive bit
.................... int1 txbo; //5 //transmitter bus off
.................... int1 rx1ovfl; //6 //receive buffer 1 overflow
.................... int1 rx0ovfl; //7 //receive buffer 0 overflow
.................... } COMSTAT;
.................... #byte COMSTAT= getenv("SFR:COMSTAT") //0xF74
....................
.................... //baud rate control register 1
.................... struct {
.................... int brp:6; //0:5 //baud rate prescalar
.................... int sjw:2; //6:7 //synchronized jump width
.................... } BRGCON1;
.................... #byte BRGCON1 = getenv("SFR:BRGCON1") //0xF70
....................
.................... //baud rate control register 2
.................... struct {
.................... int prseg:3; //0:2 //propagation time select
.................... int seg1ph:3; //3:5 //phase segment 1
.................... int1 sam; //6 //sample of the can bus line
.................... int1 seg2phts; //7 //phase segment 2 time select
.................... } BRGCON2;
.................... #byte BRGCON2 = getenv("SFR:BRGCON2") //0xF71
....................
.................... //baud rate control register 3
.................... struct {
.................... int seg2ph:3; //0:2 //phase segment 2 time select
.................... int void543:3; //3:5
.................... int1 wakfil; //6 //selects can bus line filter for wake-up
.................... int1 void7; //7
.................... } BRGCON3;
.................... #byte BRGCON3 = getenv("SFR:BRGCON3") //0xF72
....................
.................... //can i/o control register
.................... struct {
.................... int void3210:4; //0:3
.................... int1 cancap; //4 //can message receive capture
.................... int1 endrhi; //5 //enable drive high
.................... int1 tx2en; //6 //CANTX2 Pin Enable bit //added 3/30/09 for PIC18F6585/8585/6680/8680
.................... int1 tx2src; //7 //CANTX2 Pin Data Source bit //added 3/30/09 for PIC18F6585/8585/6680/8680
.................... } CIOCON;
.................... #byte CIOCON = getenv("SFR:CIOCON") //0xF73
....................
.................... //transmit buffer n control register
.................... struct txbNcon_struct {
.................... int txpri:2; //0:1 //transmit priority bits
.................... int1 void2; //2
.................... int1 txreq; //3 //transmit request status (clear to request message abort)
.................... int1 txerr; //4 //transmission error detected
.................... int1 txlarb; //5 //transmission lost arbitration status
.................... int1 txabt; //6 //transmission aborted status
.................... int1 void7;
.................... };
.................... struct txbNcon_struct TXB0CON;
.................... struct txbNcon_struct TXB1CON;
.................... struct txbNcon_struct TXB2CON;
.................... struct txbNcon_struct TXBaCON;
.................... #byte TXB0CON = getenv("SFR:TXB0CON") //0xF40
.................... #byte TXB1CON = getenv("SFR:TXB1CON") //0xF30
.................... #byte TXB2CON = getenv("SFR:TXB2CON") //0xF20
.................... #byte TXBaCON = 0xF60 // txbXcon when in the access bank
....................
....................
.................... //transmit buffer n standard identifier
.................... #byte TXB0SIDH = getenv("SFR:TXB0SIDH") //
.................... #byte TXB0SIDL = getenv("SFR:TXB0SIDL") //
.................... #byte TXB1SIDH = getenv("SFR:TXB1SIDH") //
.................... #byte TXB1SIDL = getenv("SFR:TXB1SIDL") //
.................... #byte TXB2SIDH = getenv("SFR:TXB2SIDH") //
.................... #byte TXB2SIDL = getenv("SFR:TXB2SIDL") //
....................
.................... //transmit buffer n extended identifier
.................... #byte TXB0EIDH = getenv("SFR:TXB0EIDH") //0xF43
.................... #byte TXB0EIDL = getenv("SFR:TXB0EIDL") //0xF44
.................... #byte TXB1EIDH = getenv("SFR:TXB1EIDH") //0xF33
.................... #byte TXB1EIDL = getenv("SFR:TXB1EIDL") //0xF34
.................... #byte TXB2EIDH = getenv("SFR:TXB2EIDH") //0xF23
.................... #byte TXB2EIDL = getenv("SFR:TXB2EIDL") //0xF24
....................
.................... #define RX0MASK getenv("SFR:RXM0EIDL") //0xF1B //rxm0eidl
.................... #define RX1MASK getenv("SFR:RXM1EIDL") //0xF1F //rxm1eidl
.................... #define RX0FILTER0 getenv("SFR:RXF0EIDL") //0xF03 //rxf0eidl
.................... #define RX0FILTER1 getenv("SFR:RXF1EIDL") //0xF07 //rxf1eidl
.................... #define RX1FILTER2 getenv("SFR:RXF2EIDL") //0xF0B //rxf2eidl
.................... #define RX1FILTER3 getenv("SFR:RXF3EIDL") //0xF0F //rxf3eidl
.................... #define RX1FILTER4 getenv("SFR:RXF4EIDL") //0xF13 //rxf4eidl
.................... #define RX1FILTER5 getenv("SFR:RXF5EIDL") //0xF17 //rxf5eidl
.................... #define RXB0ID getenv("SFR:RXB0EIDL") //0xF64 //rxb0eidl
.................... #define RXB1ID getenv("SFR:RXB1EIDL") //0xF54 //rxb1eidl
.................... #define TXB0ID getenv("SFR:TXB0EIDL") //0xF44 //txb0eidl
.................... #define TXB1ID getenv("SFR:TXB1EIDL") //0xF34 //txb1eidl
.................... #define TXB2ID getenv("SFR:TXB2EIDL") //0xF24 //tsb2eidl
.................... #define TXRXBaID 0xF64
....................
.................... //transmit buffer n data byte m
.................... #byte TXB0D0 = getenv("SFR:TXB0D0") //0xF46
.................... #byte TXB0D7 = getenv("SFR:TXB0D7") //0xF4D
.................... #byte TXB1D0 = getenv("SFR:TXB1D0") //0xF36
.................... #byte TXB1D7 = getenv("SFR:TXB1D7") //0xF3D
.................... #byte TXB2D0 = getenv("SFR:TXB2D0") //0xF26
.................... #byte TXB2D7 = getenv("SFR:TXB2D7") //0xF2D
....................
.................... //transmit buffer n data length
.................... struct txbNdlc_struct {
.................... int dlc:4; //0:3
.................... int void54:2; //4:5
.................... int1 rtr; //6 //transmission frame remote transmission
.................... int1 void7; //7
.................... };
.................... struct txbNdlc_struct TXB0DLC;
.................... struct txbNdlc_struct TXB1DLC;
.................... struct txbNdlc_struct TXB2DLC;
.................... struct txbNdlc_struct TXBaDLC;
.................... #byte TXB0DLC = getenv("SFR:TXB0DLC") //0xF45
.................... #byte TXB1DLC = getenv("SFR:TXB1DLC") //0xF35
.................... #byte TXB2DLC = getenv("SFR:TXB2DLC") //0xF25
.................... #byte TXBaDLC = 0xF65 //txbXdlc when in the access bank
....................
....................
.................... //transmit error count register
.................... #byte TXERRCNT=getenv("SFR:TXERRCNT") //0xF76
....................
....................
.................... enum CAN_RX_MODE {CAN_RX_ALL=3, CAN_RX_EXT=2, CAN_RX_STD=1, CAN_RX_VALID=0};
....................
.................... //receive buffer 0 control register
.................... struct {
.................... int1 filthit0; //0 //filter hit
.................... int1 jtoff; //1 //jump table offset
.................... int1 rxb0dben; //2 //receive buffer 0 double buffer enable
.................... int1 rxrtrro; //3 //receive remote transfer request
.................... int1 void4; //4
.................... CAN_RX_MODE rxm:2; //5:6 //receiver buffer mode
.................... int1 rxful; //7 //receive full status
.................... } RXB0CON;
.................... #byte RXB0CON = getenv("SFR:RXB0CON") //0xF60
....................
.................... //receive buffer 1 control register
.................... struct {
.................... int filthit:3; //0:2
.................... int1 rxrtrro; //3 //receive remote transfer request
.................... int1 void4; //4
.................... CAN_RX_MODE rxm:2; //5:6 //receive buffer mode
.................... int1 rxful; //7 //receive full
.................... } RXB1CON;
.................... #byte RXB1CON = getenv("SFR:RXB1CON") //0xF50
....................
....................
.................... //receive buffer n standard identifier
.................... #byte RXB0SIDH = getenv("SFR:RXB0SIDH") //0xF61
.................... #byte RXB0SIDL = getenv("SFR:RXB0SIDL") //0xF62
.................... #byte RXB1SIDH = getenv("SFR:RXB1SIDH") //0xF51
.................... #byte RXB1SIDL = getenv("SFR:RXB1SIDL") //0xF52
....................
.................... //receive buffer n extended identifier
.................... #byte RXB0EIDH = getenv("SFR:RXB0EIDH") //0xF63
.................... #byte RXB0EIDL = getenv("SFR:RXB0EIDL") //0xF64
.................... #byte RXB1EIDH = getenv("SFR:RXB1EIDH") //0xF53
.................... #byte RXB1EIDL = getenv("SFR:RXB1EIDL") //0xF54
....................
.................... #byte TXRXBaEIDL=0xF64
....................
.................... struct {
.................... int void012:3; //0:3
.................... int1 ext; //extended id
.................... int1 srr; //substitute remove request bit
.................... int void567:3; //5:7
.................... } TXRXBaSIDL;
.................... #byte TXRXBaSIDL=0xF62
....................
.................... //receive buffer n data length code register
.................... struct rxbNdlc_struct {
.................... int dlc:4; //0:3 //data length code
.................... int1 rb0; //4 //reserved
.................... int1 rb1; //5 //reserved
.................... int1 rtr; //6 //receiver remote transmission request bit
.................... int1 void7; //7
.................... };
.................... struct rxbNdlc_struct RXB0DLC;
.................... struct rxbNdlc_struct RXB1DLC;
.................... struct rxbNdlc_struct RXBaDLC;
.................... #byte RXB0DLC = getenv("SFR:RXB0DLC") //0xF65
.................... #byte RXB1DLC = getenv("SFR:RXB1DLC") //0xF55
.................... #byte RXBaDLC = getenv("SFR:RXB0DLC") //0xF65
.................... //receive buffer n data field byte m register
.................... #byte RXB0D0 = getenv("SFR:RXB0D0") //0xF66
.................... #byte RXB0D7 = getenv("SFR:RXB0D7") //0xF6D
.................... #byte TXRXBaD0=0xF66
.................... #byte TXRXBaD7=0xF6D
....................
.................... //receive error count
.................... #byte RXERRCNT = getenv("SFR:RXERRCNT") //0xF75
....................
.................... //receive acceptance filter n standard identifier
.................... #byte RXF0SIDH = getenv("SFR:RXF0SIDH") //0xF00
.................... #byte RXF0SIDL = getenv("SFR:RXF0SIDL") //0xF01
.................... #byte RXF1SIDH = getenv("SFR:RXF1SIDH") //0xF04
.................... #byte RXF1SIDL = getenv("SFR:RXF1SIDL") //0xF05
.................... #byte RXF2SIDH = getenv("SFR:RXF2SIDH") //0xF08
.................... #byte RXF2SIDL = getenv("SFR:RXF2SIDL") //0xF09
.................... #byte RXF3SIDH = getenv("SFR:RXF3SIDH") //0xF0C
.................... #byte RXF3SIDL = getenv("SFR:RXF3SIDL") //0xF0D
.................... #byte RXF4SIDH = getenv("SFR:RXF4SIDH") //0xF10
.................... #byte RXF4SIDL = getenv("SFR:RXF4SIDL") //0xF11
.................... #byte RXF5SIDH = getenv("SFR:RXF5SIDH") //0xF14
.................... #byte RXF5SIDL = getenv("SFR:RXF5SIDL") //0xF15
....................
.................... //receive acceptance filter n extended identifier
.................... #byte RXF0EIDH = getenv("SFR:RXF0EIDH") //0xF02
.................... #byte RXF0EIDL = getenv("SFR:RXF0EIDL") //0xF03
.................... #byte RXF1EIDH = getenv("SFR:RXF1EIDH") //0xF06
.................... #byte RXF1EIDL = getenv("SFR:RXF1EIDL") //0xF07
.................... #byte RXF2EIDH = getenv("SFR:RXF2EIDH") //0xF0A
.................... #byte RXF2EIDL = getenv("SFR:RXF2EIDL") //0xF0B
.................... #byte RXF3EIDH = getenv("SFR:RXF3EIDH") //0xF0E
.................... #byte RXF3EIDL = getenv("SFR:RXF3EIDL") //0xF0F
.................... #byte RXF4EIDH = getenv("SFR:RXF4EIDH") //0xF12
.................... #byte RXF4EIDL = getenv("SFR:RXF4EIDL") //0xF13
.................... #byte RXF5EIDH = getenv("SFR:RXF5EIDH") //0xF16
.................... #byte RXF5EIDL = getenv("SFR:RXF5EIDL") //0xF17
....................
.................... //receive acceptance mask n standard identifier mask
.................... #byte RXM0SIDH = getenv("SFR:RXM0SIDH") //0xF18
.................... #byte RXM0SIDL = getenv("SFR:RXM0SIDL") //0xF19
.................... #byte RXM1SIDH = getenv("SFR:RXM1SIDH") //0xF1C
.................... #byte RXM1SIDL = getenv("SFR:RXM1SIDL") //0xF1D
....................
.................... //receive acceptance mask n extended identifier mask
.................... #byte RXM0EIDH = getenv("SFR:RXM0EIDH") //0xF1A
.................... #byte RXM0EIDL = getenv("SFR:RXM0EIDL") //0xF1B
.................... #byte RXM1EIDH = getenv("SFR:RXM1EIDH") //0xF1E
.................... #byte RXM1EIDL = getenv("SFR:RXM1EIDL") //0xF1F
....................
.................... //value to put in mask field to accept all incoming id's
.................... #define CAN_MASK_ACCEPT_ALL 0
....................
.................... //can interrupt flags
.................... #bit CAN_INT_IRXIF = getenv("BIT:IRXIF") //0xFA4.7
.................... #bit CAN_INT_WAKIF = getenv("BIT:WAKIF") //0xFA4.6
.................... #bit CAN_INT_ERRIF = getenv("BIT:ERRIF") //0xFA4.5
.................... #bit CAN_INT_TXB2IF = getenv("BIT:TXB2IF") // 0xFA4.4
.................... #bit CAN_INT_TXB1IF = getenv("BIT:TXB1IF") // 0xFA4.3
.................... #bit CAN_INT_TXB0IF = getenv("BIT:TXB0IF") // 0xFA4.2
.................... #bit CAN_INT_RXB1IF = getenv("BIT:RXB1IF") // 0xFA4.1
.................... #bit CAN_INT_RXB0IF = getenv("BIT:RXB0IF") // 0xFA4.0
....................
.................... //PROTOTYPES
....................
.................... struct rx_stat {
.................... int1 err_ovfl;
.................... int filthit:3;
.................... int1 buffer;
.................... int1 rtr;
.................... int1 ext;
.................... int1 inv;
.................... };
....................
.................... void can_init(void);
.................... void can_set_baud(void);
.................... void can_set_mode(CAN_OP_MODE mode);
.................... void can_set_id(unsigned int* addr, unsigned int32 id, int1 ext);
.................... unsigned int32 can_get_id(unsigned int * addr, int1 ext);
.................... int1 can_putd(unsigned int32 id, unsigned int * data, unsigned int len, unsigned int priority, int1 ext, int1 rtr);
.................... int1 can_getd(unsigned int32 & id, unsigned int * data, unsigned int & len, struct rx_stat & stat);
....................
.................... #endif
....................
....................
.................... #if CAN_DO_DEBUG
.................... #define can_debug printf
.................... #else
.................... #define can_debug
.................... #endif
....................
....................
.................... //macros
.................... #define can_kbhit() (RXB0CON.rxful || RXB1CON.rxful)
.................... #define can_tbe() (!TXB0CON.txreq || !TXB1CON.txreq || !TXB2CON.txreq)
.................... #define can_abort() (CANCON.abat=1)
....................
....................
.................... ////////////////////////////////////////////////////////////////////////
.................... //
.................... // can_init()
.................... //
.................... // Initializes PIC18xxx8 CAN peripheral. Sets the RX filter and masks so the
.................... // CAN peripheral will receive all incoming IDs. Configures both RX buffers
.................... // to only accept valid messages (as opposed to all messages, or all
.................... // extended message, or all standard messages). Also sets the tri-state
.................... // setting of B2 to output, and B3 to input (apparently the CAN peripheral
.................... // doesn't keep track of this)
.................... //
.................... // The constants (CAN_USE_RX_DOUBLE_BUFFER, CAN_ENABLE_DRIVE_HIGH,
.................... // CAN_ENABLE_CAN_CAPTURE) are given a default define in the can-18xxx8.h file.
.................... // These default values can be overwritten in the main code, but most
.................... // applications will be fine with these defaults.
.................... //
.................... //////////////////////////////////////////////////////////////////////////////
.................... void can_init(void) {
.................... can_set_mode(CAN_OP_CONFIG); //must be in config mode before params can be set
*
0544: MOVLW 04
0546: MOVWF 28
0548: RCALL 03C2
.................... can_set_baud();
054A: BRA 03E4
....................
.................... RXB0CON=0;
054C: CLRF F60
.................... RXB0CON.rxm=CAN_RX_VALID;
054E: MOVLW 9F
0550: ANDWF F60,W
0552: MOVWF F60
.................... RXB0CON.rxb0dben=CAN_USE_RX_DOUBLE_BUFFER;
0554: BSF F60.2
.................... RXB1CON=RXB0CON;
0556: MOVFF F60,F50
....................
.................... CIOCON.endrhi=CAN_ENABLE_DRIVE_HIGH;
055A: BCF F73.5
.................... CIOCON.cancap=CAN_ENABLE_CAN_CAPTURE;
055C: BCF F73.4
.................... CIOCON.tx2src=CAN_CANTX2_SOURCE; //added 3/30/09 for PIC18F6585/8585/6680/8680
055E: BCF F73.7
.................... CIOCON.tx2en=CAN_ENABLE_CANTX2; //added 3/30/09 for PIC18F6585/8585/6680/8680
0560: BCF F73.6
....................
.................... can_set_id(RX0MASK, CAN_MASK_ACCEPT_ALL, CAN_USE_EXTENDED_ID); //set mask 0
0562: MOVLW 0F
0564: MOVWF 37
0566: MOVLW 1B
0568: MOVWF 36
056A: CLRF 3B
056C: CLRF 3A
056E: CLRF 39
0570: CLRF 38
0572: MOVLW 01
0574: MOVWF 3C
0576: RCALL 0414
.................... can_set_id(RX0FILTER0, 0, CAN_USE_EXTENDED_ID); //set filter 0 of mask 0
0578: MOVLW 0F
057A: MOVWF 37
057C: MOVLW 03
057E: MOVWF 36
0580: CLRF 3B
0582: CLRF 3A
0584: CLRF 39
0586: CLRF 38
0588: MOVLW 01
058A: MOVWF 3C
058C: RCALL 0414
.................... can_set_id(RX0FILTER1, 0, CAN_USE_EXTENDED_ID); //set filter 1 of mask 0
058E: MOVLW 0F
0590: MOVWF 37
0592: MOVLW 07
0594: MOVWF 36
0596: CLRF 3B
0598: CLRF 3A
059A: CLRF 39
059C: CLRF 38
059E: MOVLW 01
05A0: MOVWF 3C
05A2: RCALL 0414
....................
.................... can_set_id(RX1MASK, CAN_MASK_ACCEPT_ALL, CAN_USE_EXTENDED_ID); //set mask 1
05A4: MOVLW 0F
05A6: MOVWF 37
05A8: MOVLW 1F
05AA: MOVWF 36
05AC: CLRF 3B
05AE: CLRF 3A
05B0: CLRF 39
05B2: CLRF 38
05B4: MOVLW 01
05B6: MOVWF 3C
05B8: RCALL 0414
.................... can_set_id(RX1FILTER2, 0, CAN_USE_EXTENDED_ID); //set filter 0 of mask 1
05BA: MOVLW 0F
05BC: MOVWF 37
05BE: MOVLW 0B
05C0: MOVWF 36
05C2: CLRF 3B
05C4: CLRF 3A
05C6: CLRF 39
05C8: CLRF 38
05CA: MOVLW 01
05CC: MOVWF 3C
05CE: RCALL 0414
.................... can_set_id(RX1FILTER3, 0, CAN_USE_EXTENDED_ID); //set filter 1 of mask 1
05D0: MOVLW 0F
05D2: MOVWF 37
05D4: MOVWF 36
05D6: CLRF 3B
05D8: CLRF 3A
05DA: CLRF 39
05DC: CLRF 38
05DE: MOVLW 01
05E0: MOVWF 3C
05E2: RCALL 0414
.................... can_set_id(RX1FILTER4, 0, CAN_USE_EXTENDED_ID); //set filter 2 of mask 1
05E4: MOVLW 0F
05E6: MOVWF 37
05E8: MOVLW 13
05EA: MOVWF 36
05EC: CLRF 3B
05EE: CLRF 3A
05F0: CLRF 39
05F2: CLRF 38
05F4: MOVLW 01
05F6: MOVWF 3C
05F8: RCALL 0414
.................... can_set_id(RX1FILTER5, 0, CAN_USE_EXTENDED_ID); //set filter 3 of mask 1
05FA: MOVLW 0F
05FC: MOVWF 37
05FE: MOVLW 17
0600: MOVWF 36
0602: CLRF 3B
0604: CLRF 3A
0606: CLRF 39
0608: CLRF 38
060A: MOVLW 01
060C: MOVWF 3C
060E: RCALL 0414
....................
.................... #if (getenv("DEVICE") == "PIC18F6585") || (getenv("DEVICE") == "PIC18LF6585") || \
.................... (getenv("DEVICE") == "PIC18F6680") || (getenv("DEVICE") == "PIC18LF6680") || \
.................... (getenv("DEVICE") == "PIC18F8585") || (getenv("DEVICE") == "PIC18LF8585") || \
.................... (getenv("DEVICE") == "PIC18F8680") || (getenv("DEVICE") == "PIC18LF8680") || \
.................... (getenv("DEVICE") == "PIC18C658") || (getenv("DEVICE") == "PIC18C858")
.................... set_tris_g((*getenv("SFR:TRISG") & 0xFE) | 0x04); //G2 in, G0 out
.................... if(CAN_ENABLE_CANTX2)
.................... bit_clear(*getenv("SFR:TRISG"), 1); //G1 out
.................... #elif getenv("FUSE_SET:CANE")
.................... set_tris_e((*getenv("SFR:TRISE") & 0xDF) | 0x10); //E4 in, E5 out
.................... #elif getenv("FUSE_SET:CANC")
.................... set_tris_c((*getenv("SFR:TRISC") & 0xBF) | 0x80); //C7 in, C6 out
.................... #else
.................... set_tris_b((*getenv("SFR:TRISB") & 0xFB) | 0x08); //B3 in, B2 out
0610: MOVF F93,W
0612: ANDLW FB
0614: IORLW 08
0616: MOVWF F93
.................... #endif
....................
.................... can_set_mode(CAN_OP_NORMAL);
0618: CLRF 28
061A: RCALL 03C2
061C: GOTO 072A (RETURN)
.................... }
....................
.................... ////////////////////////////////////////////////////////////////////////
.................... //
.................... // can_set_baud()
.................... //
.................... // Configures the baud rate control registers. All the defines here
.................... // are defaulted in the can-18xxx8.h file. These defaults can, and
.................... // probably should, be overwritten in the main code.
.................... //
.................... // Current defaults are set to work with Microchip's MCP250xxx CAN
.................... // Developers Kit if this PIC is running at 20Mhz.
.................... //
.................... ////////////////////////////////////////////////////////////////////////
.................... void can_set_baud(void) {
.................... BRGCON1.brp=CAN_BRG_PRESCALAR;
*
03E4: MOVLW C0
03E6: ANDWF F70,W
03E8: IORLW 04
03EA: MOVWF F70
.................... BRGCON1.sjw=CAN_BRG_SYNCH_JUMP_WIDTH;
03EC: MOVLW 3F
03EE: ANDWF F70,W
03F0: MOVWF F70
....................
.................... BRGCON2.prseg=CAN_BRG_PROPAGATION_TIME;
03F2: MOVLW F8
03F4: ANDWF F71,W
03F6: IORLW 02
03F8: MOVWF F71
.................... BRGCON2.seg1ph=CAN_BRG_PHASE_SEGMENT_1;
03FA: MOVLW C7
03FC: ANDWF F71,W
03FE: IORLW 28
0400: MOVWF F71
.................... BRGCON2.sam=CAN_BRG_SAM;
0402: BCF F71.6
.................... BRGCON2.seg2phts=CAN_BRG_SEG_2_PHASE_TS;
0404: BSF F71.7
....................
.................... BRGCON3.seg2ph=CAN_BRG_PHASE_SEGMENT_2;
0406: MOVLW F8
0408: ANDWF F72,W
040A: IORLW 05
040C: MOVWF F72
.................... BRGCON3.wakfil=CAN_BRG_WAKE_FILTER;
040E: BCF F72.6
0410: GOTO 054C (RETURN)
.................... }
....................
.................... void can_set_mode(CAN_OP_MODE mode) {
.................... CANCON.reqop=mode;
*
03C2: SWAPF 28,W
03C4: ANDLW 70
03C6: MOVWF 00
03C8: BCF FD8.0
03CA: RLCF 00,F
03CC: MOVLW 1F
03CE: ANDWF F6F,W
03D0: IORWF 00,W
03D2: MOVWF F6F
.................... while( (CANSTAT.opmode) != mode );
03D4: MOVFF F6E,00
03D8: SWAPF 00,F
03DA: RRCF 00,W
03DC: ANDLW 07
03DE: SUBWF 28,W
03E0: BNZ 03D4
03E2: RETURN 0
.................... }
....................
....................
.................... ////////////////////////////////////////////////////////////////////////
.................... //
.................... // can_set_id()
.................... //
.................... // Configures the xxxxEIDL, xxxxEIDH, xxxxSIDL and xxxxSIDH registers to
.................... // configure the defined buffer to use the specified ID
.................... //
.................... // Parameters:
.................... // addr - pointer to first byte of ID register, starting with xxxxEIDL.
.................... // For example, a pointer to RXM1EIDL
.................... // id - ID to set buffer to
.................... // ext - Set to TRUE if this buffer uses an extended ID, FALSE if not
.................... //
.................... ////////////////////////////////////////////////////////////////////////
.................... void can_set_id(unsigned int* addr, unsigned int32 id, int1 ext) {
.................... int *ptr;
....................
.................... ptr=addr;
*
0414: MOVFF 37,3E
0418: MOVFF 36,3D
....................
.................... if (ext) { //extended
041C: MOVF 3C,F
041E: BZ 04C4
.................... //eidl
.................... *ptr=make8(id,0); //0:7
0420: MOVFF 3D,FE9
0424: MOVFF 3E,FEA
0428: MOVFF 38,FEF
....................
.................... //eidh
.................... ptr--;
042C: MOVF 3D,W
042E: BTFSC FD8.2
0430: DECF 3E,F
0432: DECF 3D,F
.................... *ptr=make8(id,1); //8:15
0434: MOVFF 3D,FE9
0438: MOVFF 3E,FEA
043C: MOVFF 39,FEF
....................
.................... //sidl
.................... ptr--;
0440: MOVF 3D,W
0442: BTFSC FD8.2
0444: DECF 3E,F
0446: DECF 3D,F
.................... *ptr=make8(id,2) & 0x03; //16:17
0448: MOVFF 3D,FE9
044C: MOVFF 3E,FEA
0450: MOVF 3A,W
0452: ANDLW 03
0454: MOVWF FEF
.................... *ptr|=(make8(id,2) << 3) & 0xE0; //18:20
0456: MOVFF 3D,FE9
045A: MOVFF 3E,FEA
045E: MOVFF 3A,00
0462: RLCF 00,F
0464: RLCF 00,F
0466: RLCF 00,F
0468: MOVLW F8
046A: ANDWF 00,F
046C: MOVF 00,W
046E: ANDLW E0
0470: IORWF FEF,W
0472: MOVWF FEF
.................... *ptr|=0x08;
0474: MOVFF 3D,FE9
0478: MOVFF 3E,FEA
047C: MOVF FEF,W
047E: IORLW 08
0480: MOVWF FEF
....................
....................
.................... //sidh
.................... ptr--;
0482: MOVF 3D,W
0484: BTFSC FD8.2
0486: DECF 3E,F
0488: DECF 3D,F
.................... *ptr=((make8(id,2) >> 5) & 0x07 ); //21:23
048A: MOVFF 3D,FE9
048E: MOVFF 3E,FEA
0492: MOVFF 3A,00
0496: SWAPF 00,F
0498: RRCF 00,F
049A: MOVLW 07
049C: ANDWF 00,F
049E: MOVF 00,W
04A0: ANDLW 07
04A2: MOVWF FEF
.................... *ptr|=((make8(id,3) << 3) & 0xF8);//24:28
04A4: MOVFF 3D,FE9
04A8: MOVFF 3E,FEA
04AC: MOVFF 3B,00
04B0: RLCF 00,F
04B2: RLCF 00,F
04B4: RLCF 00,F
04B6: MOVLW F8
04B8: ANDWF 00,F
04BA: MOVF 00,W
04BC: ANDLW F8
04BE: IORWF FEF,W
04C0: MOVWF FEF
.................... }
04C2: BRA 0542
.................... else { //standard
.................... //eidl
.................... *ptr=0;
04C4: MOVFF 3D,FE9
04C8: MOVFF 3E,FEA
04CC: CLRF FEF
....................
.................... //eidh
.................... ptr--;
04CE: MOVF 3D,W
04D0: BTFSC FD8.2
04D2: DECF 3E,F
04D4: DECF 3D,F
.................... *ptr=0;
04D6: MOVFF 3D,FE9
04DA: MOVFF 3E,FEA
04DE: CLRF FEF
....................
.................... //sidl
.................... ptr--;
04E0: MOVF 3D,W
04E2: BTFSC FD8.2
04E4: DECF 3E,F
04E6: DECF 3D,F
.................... *ptr=(make8(id,0) << 5) & 0xE0;
04E8: MOVFF 3D,FE9
04EC: MOVFF 3E,FEA
04F0: MOVFF 38,00
04F4: SWAPF 00,F
04F6: RLCF 00,F
04F8: MOVLW E0
04FA: ANDWF 00,F
04FC: MOVF 00,W
04FE: ANDLW E0
0500: MOVWF FEF
....................
.................... //sidh
.................... ptr--;
0502: MOVF 3D,W
0504: BTFSC FD8.2
0506: DECF 3E,F
0508: DECF 3D,F
.................... *ptr=(make8(id,0) >> 3) & 0x1F;
050A: MOVFF 3D,FE9
050E: MOVFF 3E,FEA
0512: MOVFF 38,00
0516: RRCF 00,F
0518: RRCF 00,F
051A: RRCF 00,F
051C: MOVLW 1F
051E: ANDWF 00,F
0520: MOVF 00,W
0522: ANDLW 1F
0524: MOVWF FEF
.................... *ptr|=(make8(id,1) << 5) & 0xE0;
0526: MOVFF 3D,FE9
052A: MOVFF 3E,FEA
052E: MOVFF 39,00
0532: SWAPF 00,F
0534: RLCF 00,F
0536: MOVLW E0
0538: ANDWF 00,F
053A: MOVF 00,W
053C: ANDLW E0
053E: IORWF FEF,W
0540: MOVWF FEF
.................... }
0542: RETURN 0
.................... }
....................
.................... ////////////////////////////////////////////////////////////////////////
.................... //
.................... // can_get_id()
.................... //
.................... // Returns the ID of the specified buffer. (The opposite of can_set_id())
.................... // This is used after receiving a message, to see which ID sent the message.
.................... //
.................... // Parameters:
.................... // addr - pointer to first byte of ID register, starting with xxxxEIDL.
.................... // For example, a pointer to RXM1EIDL
.................... // ext - Set to TRUE if this buffer uses an extended ID, FALSE if not
.................... //
.................... // Returns:
.................... // The ID of the buffer
.................... //
.................... ////////////////////////////////////////////////////////////////////////
.................... unsigned int32 can_get_id(unsigned int * addr, int1 ext) {
.................... unsigned int32 ret;
.................... unsigned int * ptr;
....................
.................... ret=0;
*
00B2: CLRF 55
00B4: CLRF 54
00B6: CLRF 53
00B8: CLRF 52
.................... ptr=addr;
00BA: MOVFF 50,57
00BE: MOVFF 4F,56
....................
.................... if (ext) {
00C2: MOVF 51,F
00C4: BTFSC FD8.2
00C6: BRA 01DA
.................... ret=*ptr; //eidl
00C8: MOVFF 56,FE9
00CC: MOVFF 57,FEA
00D0: CLRF 55
00D2: CLRF 54
00D4: CLRF 53
00D6: MOVFF FEF,52
....................
.................... ptr--; //eidh
00DA: MOVF 56,W
00DC: BTFSC FD8.2
00DE: DECF 57,F
00E0: DECF 56,F
.................... ret|=((unsigned int32)*ptr << 8);
00E2: MOVFF 56,FE9
00E6: MOVFF 57,FEA
00EA: MOVF FEF,W
00EC: CLRF 5A
00EE: CLRF 59
00F0: MOVWF 58
00F2: CLRF 00
00F4: MOVF 00,W
00F6: IORWF 52,F
00F8: MOVF 58,W
00FA: IORWF 53,F
00FC: MOVF 59,W
00FE: IORWF 54,F