-
Notifications
You must be signed in to change notification settings - Fork 0
/
DS1390-RTC.asm
2362 lines (2226 loc) · 102 KB
/
DS1390-RTC.asm
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
;********************************************************************************************
;* Aiolos Project *
;* MSP Serial Terminal *
;********************************************************************************************
;* Real Time Clock handling for Maxim-Dallas DS1390 and compatible ICs. *
;* Note that in SPI, when a master transmits a byte it receives one simultaneously *
;* This library provides functions for interrupts. There are cases that a bus is shared *
;* with other peripherals; the only different pin is the chip selector. There is a *
;* specific definition that tells the library preprocessor if the RTC is on a shared bus *
;* or not. The name of the definition is SHAREDBUS. If it is 0 or not defined then it is *
;* assumed the RTC is alone on the bus so the system binds the interrupt service routines *
;* to the necessary interrupt vectors. If the SHAREDBUS has a value of 1, it does not bind *
;* them. In that case it is assumed that the binding will happen at the main program, *
;* because the interrupt vectors belonging to USC, Timers or port pins are shared with *
;* other processes. Thus, the main program must have a kind of dispatcher that should test *
;* which of the peripherals need attention and dispatch the program to the appropriate ISR.*
;* The interrupts needed are three: *
;********************************************************************************************
.title "Aiolos Project: MSP Serial Terminal - Real Time Clock Library"
.tab 4
.cdecls C,LIST,"msp430.h" ; Include device header file
;============================================================================================
; DEFINITIONS - This section contains all necessary definition visible only to this file
;--------------------------------------------------------------------------------------------
.if $defined("RTCSPI") ;RTCSPI could be defined in command line
_RTCSPI .equ RTCSPI ;The UCSI that communicates to RTC
.else
_RTCSPI .equ "UCA0"
.endif
.if $defined("RTCCtlPort") ;RTCCtlPort could be defined in command line
_RTCCtlPort .equ RTCCtlPort ;The port the control pins of RTC are connected
.else
_RTCCtlPort .equ 1
.endif
.if $defined("RTCIntPort") ;RTCCtlPort could be defined in command line
_RTCIntPort .equ RTCIntPort
.else
;_RTCIntPort .equ 1 ;Uncomment if RTC interrupt is on a different port
.endif ; than RTCCtlPort. Could also be defined in CLI
.if $defined("RTC_IRQ") ;RTC_IRQ could be defined in command line
_RTC_IRQ .equ RTC_IRQ
.else
_RTC_IRQ .equ BIT4 ;Interrupt pin
.endif
.if $defined("RTC_CS") ;RTC_CS could be defined in command line
_RTC_CS .equ RTC_CS
.else
_RTC_CS .equ BIT3 ;Chip select pin
.endif
.if $defined("SHAREDBUS") ;SHAREDBUS could be defined in command line
_SHAREDBUS .equ SHAREDBUS ;Giving a value of 0 means that the bus is used
.else ; only by this peripheral. A value of 1 means
_SHAREDBUS .equ 1 ; that SPI bus is shared with other peripherals
.endif
.if $defined("CPUSMCLK")
_CPUSMCLK .equ CPUSMCLK
.else
_CPUSMCLK .equ 16000000 ;The CPU SMCLK clock frequency in Hz
.endif
.if $defined("RTCRXBUFLEN") ;RTCRXBUFLEN could be defined in command line
_RTCRXBUFLEN .equ RTCRXBUFLEN
.else
_RTCRXBUFLEN .equ 18 ;Size of incoming stream buffer
.endif
.if $defined("RTCTXBUFLEN") ;RTCTXBUFLEN could be defined in command line
_RTCTXBUFLEN .equ RTCTXBUFLEN
.else
_RTCTXBUFLEN .equ 18 ;Size of outgoing stream buffer
.endif
;============================================================================================
; LIBRARY DEFINITIONS - This section contains definitions, global to all program
;--------------------------------------------------------------------------------------------
RTC_cS .equ 000h ;Command for reading current centiseconds (BCD)
RTC_Secs .equ 001h ;Command for seconds (BCD)
RTC_Mins .equ 002h ;Command for minutes (BCD)
RTC_Hours .equ 003h ;Command for hours. For 24 mode is just BCD, for
; 12 hour mode, uses also the AM/PM bit
RTC_Day .equ 004h ;Command for reading day of week (1 to 7)
RTC_Date .equ 005h ;Command for reading day of month (1 to 31 BCD)
RTC_MonCent .equ 006h ;Command for reading month (BCD) and century bit
RTC_Year .equ 007h ;Command for reading year's two last digits (BCD)
RTC_cSAlm .equ 008h ;Read Alarm's centiseconds (BCD)
RTC_SecsAlm .equ 009h ;Read Alarm's seconds (BCD)/Alarm Mask 1
RTC_MinsAlm .equ 00Ah ;Read Alarm's minutes (BCD)/Alarm Mask 2
RTC_HoursAlm .equ 00Bh ;Read Alarm's Hour (BCD for 24 mode/BCD + AM/PM
; flag for 12 hour mode). Also read Alarm Mask 3
RTC_DayDateAlm .equ 00Ch ;Read Alarm's Day or Date value (BCD)/AM4
RTC_Control .equ 00Dh ;Read Control Register
RTC_Status .equ 00Eh ;Read Status Register
RTC_Charger .equ 00Fh ;Read Trickle Charger settings
RTC_CmdMask .equ 00Fh ;Mask the bits that represent a reading command
RTC_Write .equ 080h ;Set this bit to construct a Write command
RTC_12HoursMask .equ 01Fh ;Mask for reading Hours in 12 hour mode
RTC_MonthMask .equ 01Fh ;Mask for reading Month
RTC_CenturyMask .equ 080h ;Mask for reading century flag
RTC_AlmMask .equ 080h ;Mask for reading AMx bits
RTC_AlmSecMask .equ 07Fh ;Mask for reading alarm's seconds
RTC_AlmMinMask .equ 07Fh ;Mask for reading alarm's minutes
RTC_1224Mask .equ 040h ;Mask for reading hour format (12 or 24 mode)
RTC_12Flg .equ 040h ;Flag for setting 12 mode format
RTC_24Flg .equ 000h ;Flag for setting 24 mode format
RTC_AMPMMask .equ 020h ;Mask for reading AM/PM bit
RTC_AMFlg .equ 000h ;Flag for setting AM hour
RTC_PMFlg .equ 020h ;Flag for setting PM hour
RTC_DayDateMask .equ 040h ;Mask for Day/Date bit reading (for Day value = 0)
RTC_AlmDayMask .equ 00Fh ;Mask for reading day of alarm
RTC_AlmDateMask .equ 03Fh ;Mask for reading date of alarm
RTC_DateFlg .equ 000h ;Flag for setting date
RTC_DayFlg .equ 040h ;Flag for setting day
RTC_CtlEOSC .equ 080h ;Control register bit mask for EOSC
RTC_CtlBBSQI .equ 020h ;Control register bit mask for BBSQI
RTC_CtlINTCN .equ 004h ;Control register bit mask for INTCN
RTC_CtlAIE .equ 001h ;Control register bit mask for AIE
RTC_CtlRateMask .equ 018h ;Control register bit mask for Rate Selection
RTC_CtlRate1 .equ 000h ;Control register bit setting for 1Hz output rate
RTC_CtlRate4K .equ 008h ;Control register bit setting for 4092Hz rate
RTC_CtlRate8K .equ 010h ;Control register bit setting for 8192Hz rate
RTC_CtlRate32K .equ 018h ;Control register bit setting for 32768Hz rate
RTC_StatOSF .equ 080h ;Status register bit mask for OSF
RTC_StatAF .equ 001h ;Status register bit mask for AF
RTC_TCSPasswd .equ 0A0h ;Trickle charger register enabling password
RTC_TCSDiodeMsk .equ 00Ch ;Trickle charger mask for diode setting
RTC_TCSDiode .equ 008h ;Trickle charger bit setting for diode usage
RTC_TCSNoDiode .equ 004h ;Trickle charger bit setting for using no diode
RTC_TCSResMask .equ 003h ;Trickle charger mask for resistor setting
RTC_TCSRes250 .equ 001h ;Trickle charger bit setting for 250Ω resistor
RTC_TCSRes2K .equ 002h ;Trickle charger bit setting for 2KΩ resistor
RTC_TCSRes4K .equ 003h ;Trickle charger bit setting for 4KΩ resistor
RTC_TCSDisable .equ 000h ;Trickle charger bit setting for disabling charger
RTC_ALMRPTCS .equ 000h ;Alarm interrupt repetition every 100th of a
; second
RTC_ALMRPTDS .equ 002h ;Alarm interrupt repetition every 10th of a second
RTC_ALMRPTSEC .equ 004h ;Alarm interrupt repetition every second
RTC_ALMRPTMIN .equ 006h ;Alarm interrupt repetition every minute
RTC_ALMRPTHOUR .equ 008h ;Alarm interrupt repetition every hour
RTC_ALMRPTDAY .equ 00Ah ;Alarm interrupt repetition every day
RTC_ALMRPTWEEK .equ 00Ch ;Alarm interrupt repetition every week
RTC_ALMRPTMONTH .equ 00Eh ;Alarm interrupt repetition every month
.def RTC_cS ;Get/Set milliseconds
.def RTC_Secs ;Get/Set seconds
.def RTC_Mins ;Get/Set minutes
.def RTC_Hours ;Get/Set Hours
.def RTC_Day ;Get/Set Day of week (1 to 7)
.def RTC_Date ;Get/Set Date
.def RTC_MonCent ;Get/Set Century and Month
.def RTC_Year ;Get/Set Year (00-99)
.def RTC_cSAlm ;Get/Set Alarm milliseconds
.def RTC_SecsAlm ;Get/Set Alarm Seconds and Alarm Mask 1 (AM1)
.def RTC_MinsAlm ;Get/Set Alarm Minutes and Alarm Mask 2 (AM2)
.def RTC_HoursAlm ;Get/Set Alarm Hours and Alarm Mask 3 (AM3)
.def RTC_DayDateAlm ;Get/Set Alarm Day or Date and Alarm Mask 4 (AM4)
.def RTC_Control ;Get/Set RTC Control Register
.def RTC_Status ;Get/Set RTC Status Register
.def RTC_Charger ;Get/Set Trickle Charger Status
.def RTC_12HoursMask ;Mask for reading Hours in 12 hour mode
.def RTC_MonthMask ;Mask for reading Month
.def RTC_AlmSecMask ;Mask for reading alarm's seconds
.def RTC_AlmMinMask ;Mask for reading alarm's minutes
.def RTC_AlmDayMask ;Mask for reading day of alarm
.def RTC_AlmDateMask ;Mask for reading date of alarm
.def RTC_AlmMask ;Alarm Mask Filter
.def RTC_CenturyMask ;Century Mask Filter
.def RTC_1224Mask ;12/24 Hour Mode Filter
.def RTC_12Flg ;Value for 12 Hour Mode
.def RTC_24Flg ;Value for 24 Hour Mode
.def RTC_AMPMMask ;AM/PM Mask
.def RTC_AMFlg ;Value for AM Hour
.def RTC_PMFlg ;Value for PM Hour
.def RTC_DayDateMask ;Day/Date Mask setting for Alarm
.def RTC_DateFlg ;Value for Date Setting/Reading
.def RTC_DayFlg ;Value for Day Setting/Reading
.def RTC_CtlEOSC ;Enable Oscillator Mask bit for Control Register
.def RTC_CtlBBSQI ;Battery-Backed and Square-Wave Interrupt Enable
; Mask bit for Control Register
.def RTC_CtlINTCN ;Interrupt Control Mask bit for Control Register
.def RTC_CtlAIE ;Alarm Interrupt Enable Mask bit for Control Reg.
.def RTC_CtlRateMask ;Control register bit mask for Rate Selection
.def RTC_CtlRate1 ;Rate Selection value for 1Hz Square Wave
.def RTC_CtlRate4K ;Rate Selection value for 4096Hz Square Wave
.def RTC_CtlRate8K ;Rate Selection value for 8192Hz Square Wave
.def RTC_CtlRate32K ;Rate Selection Value for 32768Hz Square Wave
.def RTC_StatOSF ;Oscillator Stop Status Flag bit
.def RTC_StatAF ;Oscillator Alarm Status Flag bit
.def RTC_TCSPasswd ;Trickle Charger - Password value
.def RTC_TCSDiodeMsk ;Trickle charger mask for diode setting
.def RTC_TCSDiode ;Trickle Charger - Use Diode value
.def RTC_TCSNoDiode ;Trickle Charger - Do Not Use Diode value
.def RTC_TCSResMask ;Trickle charger mask for resistor setting
.def RTC_TCSRes250 ;Trickle Charger - Use 250 Ohm resistor
.def RTC_TCSRes2K ;Trickle Charger - Use 2 KOhm resistor
.def RTC_TCSRes4K ;Trickle Charger - Use 4 KOhm resistor
.def RTC_TCSDisable ;Trickle Charger - Disable charger
.def RTC_ALMRPTCS ;Alarm interrupt repetition every 100th of a
; second
.def RTC_ALMRPTDS ;Alarm interrupt repetition every 10th of a second
.def RTC_ALMRPTSEC ;Alarm interrupt repetition every second
.def RTC_ALMRPTMIN ;Alarm interrupt repetition every minute
.def RTC_ALMRPTHOUR ;Alarm interrupt repetition every hour
.def RTC_ALMRPTDAY ;Alarm interrupt repetition every day
.def RTC_ALMRPTWEEK ;Alarm interrupt repetition every week
.def RTC_ALMRPTMONTH ;Alarm interrupt repetition every month
;============================================================================================
; AUTO DEFINITIONS - This section contains definitions calculated by preprocessor, mainly
; according to the previously specified ones
;--------------------------------------------------------------------------------------------
RTCBAUD .equ (_CPUSMCLK / 4000000) ;The baud rate factor for BR0 and BR1 registers
.if _RTCSPI == "UCA0"
RTCDataPort .equ 3
RTC_SIMO .equ BIT4
RTC_SOMI .equ BIT5
RTC_CLK .equ BIT0
RTC_ALL .equ RTC_SIMO+RTC_SOMI+RTC_CLK
RTCIN .equ P3IN
RTCOUT .equ P3OUT
RTCDIR .equ P3DIR
RTCSEL .equ P3SEL
RTCREN .equ P3REN
RTCCLKIN .equ P3IN
RTCCLKOUT .equ P3OUT
RTCCLKDIR .equ P3DIR
RTCCLKSEL .equ P3SEL
RTCCLKREN .equ P3REN
RTCCTL0 .equ UCA0CTL0
RTCCTL1 .equ UCA0CTL1
RTCBR0 .equ UCA0BR0
RTCBR1 .equ UCA0BR1
RTCMCTL .equ UCA0MCTL
RTCSTAT .equ UCA0STAT
RTCRXBUF .equ UCA0RXBUF
RTCTXBUF .equ UCA0TXBUF
RTCTXIE .equ UCA0TXIE
RTCRXIE .equ UCA0RXIE
RTCIE .equ IE2
RTCIFG .equ IFG2
RTCTXVECTOR .equ "USCIAB0TX"
RTCRXVECTOR .equ "USCIAB0RX"
.elseif _RTCSPI == "UCA1"
RTCDataPort .equ 3
RTCClkPort .equ 5
RTC_SIMO .equ BIT6
RTC_SOMI .equ BIT7
RTC_CLK .equ BIT0
RTC_ALL .equ RTC_SIMO+RTC_SOMI
RTCIN .equ P3IN
RTCOUT .equ P3OUT
RTCDIR .equ P3DIR
RTCSEL .equ P3SEL
RTCREN .equ P3REN
RTCCLKIN .equ P5IN
RTCCLKOUT .equ P5OUT
RTCCLKDIR .equ P5DIR
RTCCLKSEL .equ P5SEL
RTCCLKREN .equ P5REN
RTCCTL0 .equ UCA1CTL0
RTCCTL1 .equ UCA1CTL1
RTCBR0 .equ UCA1BR0
RTCBR1 .equ UCA1BR1
RTCMCTL .equ UCA1MCTL
RTCSTAT .equ UCA1STAT
RTCRXBUF .equ UCA1RXBUF
RTCTXBUF .equ UCA1TXBUF
RTCTXIE .equ UCA1TXIE
RTCRXIE .equ UCA1RXIE
RTCIE .equ UC1IE
RTCIFG .equ UC1IFG
RTCTXVECTOR .equ "USCIAB1TX"
RTCRXVECTOR .equ "USCIAB1RX"
.elseif _RTCSPI == "UCB0"
RTCDataPort .equ 3
RTC_SIMO .equ BIT1
RTC_SOMI .equ BIT2
RTC_CLK .equ BIT3
RTC_ALL .equ RTC_SIMO+RTC_SOMI+RTC_CLK
RTCIN .equ P3IN
RTCOUT .equ P3OUT
RTCDIR .equ P3DIR
RTCSEL .equ P3SEL
RTCREN .equ P3REN
RTCCLKIN .equ P3IN
RTCCLKOUT .equ P3OUT
RTCCLKDIR .equ P3DIR
RTCCLKSEL .equ P3SEL
RTCCLKREN .equ P3REN
RTCCTL0 .equ UCB0CTL0
RTCCTL1 .equ UCB0CTL1
RTCBR0 .equ UCB0BR0
RTCBR1 .equ UCB0BR1
RTCMCTL .equ UCB0MCTL
RTCSTAT .equ UCB0STAT
RTCRXBUF .equ UCB0RXBUF
RTCTXBUF .equ UCB0TXBUF
RTCTXIE .equ UCB0TXIE
RTCRXIE .equ UCB0RXIE
RTCIE .equ IE2
RTCIFG .equ IFG2
RTCTXVECTOR .equ "USCIAB0TX"
RTCRXVECTOR .equ "USCIAB0RX"
.elseif _RTCSPI == "UCB1"
RTCDataPort .equ 5
RTC_SIMO .equ BIT1
RTC_SOMI .equ BIT2
RTC_CLK .equ BIT3
RTC_ALL .equ RTC_SIMO+RTC_SOMI+RTC_CLK
RTCIN .equ P5IN
RTCOUT .equ P5OUT
RTCDIR .equ P5DIR
RTCSEL .equ P5SEL
RTCREN .equ P5REN
RTCCLKIN .equ P5IN
RTCCLKOUT .equ P5OUT
RTCCLKDIR .equ P5DIR
RTCCLKSEL .equ P5SEL
RTCCLKREN .equ P5REN
RTCCTL0 .equ UCB1CTL0
RTCCTL1 .equ UCB1CTL1
RTCBR0 .equ UCB1BR0
RTCBR1 .equ UCB1BR1
RTCMCTL .equ UCB1MCTL
RTCSTAT .equ UCB1STAT
RTCRXBUF .equ UCB1RXBUF
RTCTXBUF .equ UCB1TXBUF
RTCTXIE .equ UCB1TXIE
RTCRXIE .equ UCB1RXIE
RTCIE .equ UC1IE
RTCIFG .equ UC1IFG
RTCTXVECTOR .equ "USCIAB1TX"
RTCRXVECTOR .equ "USCIAB1RX"
.else
emsg "===> _RTCSPI can be one of UCA0, UCA1, UCB0 or UCB1"
.endif
.if (_RTCCtlPort == 1)
RTCCTLIN .equ P1IN
RTCCTLOUT .equ P1OUT
RTCCTLDIR .equ P1DIR
RTCCTLSEL .equ P1SEL
RTCCTLREN .equ P1REN
.elseif (_RTCCtlPort == 2)
RTCCTLIN .equ P2IN
.eval P2OUT,RTCCTLOUT
RTCCTLDIR .equ P2DIR
RTCCTLSEL .equ P2SEL
RTCCTLREN .equ P2REN
.elseif (_RTCCtlPort == 3)
RTCCTLIN .equ P3IN
.eval P3OUT,RTCCTLOUT
RTCCTLDIR .equ P3DIR
RTCCTLSEL .equ P3SEL
RTCCTLREN .equ P3REN
.elseif (_RTCCtlPort == 4)
RTCCTLIN .equ P4IN
.eval P4OUT,RTCCTLOUT
RTCCTLDIR .equ P4DIR
RTCCTLSEL .equ P4SEL
RTCCTLREN .equ P4REN
.elseif (_RTCCtlPort == 5)
RTCCTLIN .equ P5IN
.eval P5OUT,RTCCTLOUT
RTCCTLDIR .equ P5DIR
RTCCTLSEL .equ P5SEL
RTCCTLREN .equ P5REN
.elseif (_RTCCtlPort == 6)
RTCCTLIN .equ P6IN
.eval P6OUT,RTCCTLOUT
RTCCTLDIR .equ P6DIR
RTCCTLSEL .equ P6SEL
RTCCTLREN .equ P6REN
.elseif (_RTCCtlPort == 7)
RTCCTLIN .equ P7IN
.eval P7OUT,RTCCTLOUT
RTCCTLDIR .equ P7DIR
RTCCTLSEL .equ P7SEL
RTCCTLREN .equ P7REN
.elseif (_RTCCtlPort == 8)
RTCCTLIN .equ P8IN
.eval P8OUT,RTCCTLOUT
RTCCTLDIR .equ P8DIR
RTCCTLSEL .equ P8SEL
RTCCTLREN .equ P8REN
.else
emsg "_RTCCtlPort was not defined correctly!"
.endif
.if $defined("_RTCIntPort")
UseInt .equ _RTCIntPort
.else
UseInt .equ _RTCCtlPort
.endif
.if UseInt == 1
RTCINTIN .equ P1IN
RTCINTOUT .equ P1OUT
RTCINTDIR .equ P1DIR
RTCINTSEL .equ P1SEL
RTCINTREN .equ P1REN
RTCINTIE .equ P1IE
RTCINTIES .equ P1IES
RTCINTIFG .equ P1IFG
RTCINTVECTOR .equ "PORT1"
.elseif UseInt == 2
RTCINTIN .equ P2IN
RTCINTOUT .equ P2OUT
RTCINTDIR .equ P2DIR
RTCINTSEL .equ P2SEL
RTCINTREN .equ P2REN
RTCINTIE .equ P2IE
RTCINTIES .equ P2IES
RTCINTIFG .equ P2IFG
RTCINTVECTOR .equ "PORT2"
.else
emsg "Wrong definition of UseInt. Somehow it does not belong to port 1 or 2"
.endif
.if $defined("_SHAREDBUS") = 0
SINGLEISR .equ 1
.else
.if _SHAREDBUS == 0
SINGLEISR .equ 1
.else
SINGLEISR .equ 0
.endif
.endif
;-------------------------< Specify which of them should be public >-------------------------
.def _RTCSPI ;Is a string describing the port used for SPI
.def _RTC_IRQ ;Is the pin specified for serving interrupts
.def _RTC_CS ;Chip select pin for bus checking
.def RTCCTLOUT
.def RTCTXVECTOR
.def RTCRXVECTOR
.def RTCINTVECTOR
;============================================================================================
; VARIABLES - This section contains local variables
;--------------------------------------------------------------------------------------------
.sect ".bss"
.align 1
RTCFlags: .space 2 ;Some flags for controlling the function of RTC
FLG_InCmd .equ BIT0 ;Bit 0 shows if there is any command scheduling in
; progress, so no one else must alter
FLG_CmdOK .equ BIT1 ;Bit 1 of RTCFlags presents if there is a
; complete command in transfer buffer
FLG_Abord .equ BIT2 ;Bit 2 of RTCFlags shows if there is the need to
; force command termination (due to error)
FLG_WakeUp .equ BIT3 ;Bit 3 of RTCFlags shows that after a complete
; command reading, system should be waken up
FLG_LateAlm .equ BIT4 ;Bit 4 of RTCFlags shows if there is the need to
; service an alarm just after sending the command
; in progress
FLG_CmdByte .equ BIT5 ;Shows that the byte send was a command to RTC
FLG_Vars .equ BIT6 ;The receiving ISR should use the variables area
; directly
FLG_Write .equ BIT7 ;Flags that we are using a Write command
; (receiving data must be discarded)
FLG_Serve .equ BIT8 ;Flags if Alarm woke up the system
RTCRxCBuf: .space _RTCRXBUFLEN ;The incomming stream circular buffer
RTCTxCBuf: .space _RTCTXBUFLEN ;The outgoing stream circular buffer
RxBufStrt: .space 1 ;The offset of the first character in the Rx
; buffer
RxBufLen: .space 1 ;The length of data waiting in the Rx buffer
TxBufStrt: .space 1 ;The offset of the first character in the Tx
; buffer
TxBufLen: .space 1 ;The length of data waiting in the Tx buffer
CentiSecs: .space 1 ;Current centiseconds
Seconds: .space 1 ;Current seconds
Minutes: .space 1 ;Current minutes
Hours: .space 1 ;Current hours/12-24 mode/AM-PM
WeekDay: .space 1 ;Current day of week
Date: .space 1 ;Current day of month
Month: .space 1 ;Current month/Century
Year: .space 1 ;Current year (in century)
AlmCentiSecs: .space 1 ;Alarm's centiseconds
AlmSeconds: .space 1 ;Alarm's seconds + AM1
AlmMinutes: .space 1 ;Alarm's minutes + AM2
AlmHours: .space 1 ;Alarm's hours/12-24 mode/AM-PM + AM3
AlmDayDate: .space 1 ;Alarm's Day or Date setting + AM4
ControlReg: .space 1 ;Control register
StatusReg: .space 1 ;Status register
Charger: .space 1 ;Trickle charger register
ServePtr: .space 1 ;When serving an alarm, data are stored directly
; in their original positions and not the receive
; buffer. This is the pointer to the next variable
; to be stored, relative to CentiSecs
MAXSERVEPTR .equ 010h ;Maximum number of data stored in case of alarm
; serving storage
;============================================================================================
; CONSTANTS - This section contains constant data written in Flash (.const section)
;--------------------------------------------------------------------------------------------
.sect ".const"
.align 1
;The following table is a lookup table for alarm repetition settings of 100ths of
; seconds (first byte in each entry) and the Alarm Mask bits (second byte of each
; entry). The second byte contains AM1 at LSbit to AM4 at bit 3 and Day/Date flag
; is on bit 4
AlmRptTbl: .byte 0FFh,00Fh ;Repetition every 100th of a second
.byte 0F0h,00Fh ;Repetition every 10th of a second (centisecond)
.byte 000h,00Fh ;Repetition every second
.byte 000h,00Eh ;Repetition every minute
.byte 000h,00Ch ;Repetition every hour
.byte 000h,008h ;Repetition every day
.byte 000h,010h ;Repetition every week
.byte 000h,000h ;Repetition every month
;============================================================================================
; PROGRAM FUNCTIONS
;--------------------------------------------------------------------------------------------
;--< Some of the labels must be available to other files >-----------------------------------
.def RTCTxISR ;Interrupt service routine for SPI Tx
.def RTCRxISR ;Interrupt service routine for SPI Rx
.def RTCAlarmISR ;Interrupt service routine for RTC Alarm function
.def InitRTCPorts ;Initialises the port pins used for RTC
.def InitRTCUSC ;Initialises the serial bus of the RTC
.def InitRTCSys ;Initialises the RTC subsystem's variables
.def RTCChkSPITxISR ;Checks if RTC needs attention
.def RTCEnableInts ;Enables all interrupts of RTC subsystem
.def RTCDisableInts ;Disables all interrupts of RTC subsystem
.def RTCEnableAlarmInt ;Enables only the alarm interrupt fo RTC
.def RTCDisableAlarmInt ;Disables only the alarm interrupt of RTC
.def RTCWaitData ;Blocks main thread until SPI finishes
.def RTCIsBusy ;Checks if the RTC bus is busy or not
.def RTCReceive ;Fetch one byte of those returned by RTC during a
; read command
.def RTCReadAll ;Reads all memory of Real Time Clock
.def RTCReadcSecs ;Reads current CentiSeconds
.def RTCReadLastcSecs ;Reads CentiSeconds previously read from RTC
.def RTCSetcSecs ;Sets value to CentiSeconds
.def RTCReadSecs ;Reads current Seconds
.def RTCReadLastSecs ;Reads Seconds previously read from RTC
.def RTCSetSecs ;Sets value to Seconds
.def RTCReadMins ;Reads current Minutes
.def RTCReadLastMins ;Reads Minutes previously read from RTC
.def RTCSetMins ;Sets value to Minutes
.def RTCReadHours ;Reads current Hours + AM/PM + 12/24 mode
.def RTCReadLastHours ;Reads Hours (AM + Mode) previously read from RTC
.def RTCSetHours ;Sets value to Hours, AM/PM flag and 12/24 Mode
.def RTCReadWeekDay ;Reads current Day of week
.def RTCReadLastWeekDay ;Reads Day of week previously read from RTC
.def RTCSetWeekDay ;Sets value to Day of week
.def RTCReadDate ;Reads current Day of month
.def RTCReadLastDate ;Reads Day of month previously read from RTC
.def RTCSetDate ;Sets value to Day of month
.def RTCReadMonCent ;Reads current Month and Century flag
.def RTCReadLastMonCent ;Reads Month/Century previously read from RTC
.def RTCSetMonCent ;Sets value to Month and Century flag
.def RTCReadYear ;Reads current Year
.def RTCReadLastYear ;Reads Yesr previously read from RTC
.def RTCSetYear ;Sets value to Year
.def RTCReadAlmcSecs ;Reads current Alarm CentiSeconds
.def RTCReadLastAlmcSecs ;Reads Alarm CentiSeconds previously read from RTC
.def RTCSetAlmcSecs ;Sets value to Alarm CentiSeconds
.def RTCReadAlmSecs ;Reads current Alarm Seconds
.def RTCReadLastAlmSecs ;Reads Alarm Seconds previously read from RTC
.def RTCSetAlmSecs ;Sets value to Alarm Seconds
.def RTCReadAlmMins ;Reads current Alarm Minutes
.def RTCReadLastAlmMins ;Reads Alarm Minutes previously read from RTC
.def RTCSetAlmMins ;Sets value to Alarm Minutes
.def RTCReadAlmHours ;Reads current Alarm Hours + AM/PM + 12/24 Mode
.def RTCReadLastAlmHours ;Reads Alarm Hours previously read from RTC
.def RTCSetAlmHours ;Sets value to Alarm Hours + AM/PM + 12/24 Mode
.def RTCReadAlmDayDate ;Reads current Alarm Day/Date
.def RTCReadLastAlmDayDate ;Reads Alarm Day/Date previously read from RTC
.def RTCSetAlmDayDate ;Sets value to Alarm Day/Date
.def RTCReadCtrl ;Reads current Control register
.def RTCReadLastCtrl ;Reads Control register previously read from RTC
.def RTCSetCtrl ;Sets value to Control Register
.def RTCReadStatus ;Issues a Read Status command and return its value
.def RTCReadLastStatus ;Returns the last read value of Status register
; without issuing any command)
.def RTCSetStatus ;Sets value to Status register (Actually resets
; bits)
.def RTCReadChrg ;Reads current Trickle Charger register
.def RTCReadLastChrg ;Reads Trickle Charger previously read from RTC
.def RTCSetChrg ;Sets value to Trickle Charger register
.def RTCWriteMulti ;Writes a mutlibyte command to RTC
.def ReadTimeStr ;Reads the time from RTC and converts it to string
; in specified buffer
.def ReadLastTimeStr ;Converts the time stored in variables to string
; in specified buffer, without issuing a command
; to RTC
.def RTCSetAlmRate ;Sets all the alarm repetition flags according to
; the input.
.def RTCCheckServe ;Checks and then resets the Serve flag, set when
; RTC was the one who woke up the system
.def RTCCpHour2Alm ;Reads current time from RTC and copies it to
; Alarm registers only in memory
.def RTCCpLastHour2Alm ;Copies last read time to Alarm registers, without
; issuing a read command.
;==< Interrupt Service Routines >============================================================
.text ;Place program in ROM (Flash)
.align 1
RTCTxISR:
; After a byte is sent to RTC, the SPI bus triggers this interrupt. The interrupt sends
; another character from the circular transmit buffer to RTC, if any. It also checks for
; incomplete commands in buffer that must be discarded, or even the late alarm interrupt
; triggering, in case there was already a command scheduling in progress while the original
; alarm interrupt was triggered
; Input: None
; Output: None
; Registers Used: R4
; Registers Altered: None
; Stack Usage: 2 bytes maximum
; Depend On Defs: FLG_Abord, FLG_CmdByte, FLG_CmdOK, FLG_LateAlm, RTC_CmdMask, _RTC_CS,
; _RTC_IRQ, RTCCTLOUT, RTCIE, RTCINTIFG, RTCTXBUF, _RTCTXBUFLEN, RTCTXIE,
; SINGLEISR
; Depend On Vars: RTCFlags, RTCTxCBuf, ServePtr, TxBufLen, TxBufStrt
; Depend On Funcs: None
BIT #FLG_Abord,&RTCFlags ;Do we have an incomplete command in buffer?
JNZ RTCTx_Discard ;Yes => Discard data
CMP.B #000h,&TxBufLen ;Is the buffer empty?
JEQ RTCTx_Exit ;Yes => Nothing to send... Just exit
RTCTx_New: PUSH R4 ;R4 must stay unaffected
MOV.B &TxBufStrt,R4 ;Get the starting offset
BIC #FLG_CmdByte,&RTCFlags ;Normally we send data bytes. The reason we clear
; FLG_CmdByte flag here and not in receiving ISR is that if a data byte is
; transmitted there will also be a data byte reception which will make the dummy
; byte received earlier be discarded
BIT.B #_RTC_CS,&RTCCTLOUT ;Is the CS of RTC enabled?
JZ RTCTx_CSOK ;Yes => Every thing is fine, keep sending data
.if SINGLEISR == 0 ;Only when ISR is shared
CALL #InitRTCUSC ;Initialise the bus as RTC needs it
BIS.B #RTCTXIE+RTCRXIE,&RTCIE ;Re-enable SPI interrupts (disabled by
; init when raised UCSWRST)
.endif
BIS #FLG_CmdByte+FLG_Write,&RTCFlags ;Flag that we are sending a command
; byte as a Write command
MOV.B RTCTxCBuf(R4),&ServePtr ;Store the offset of the variable to be used for
AND.B #RTC_CmdMask,&ServePtr ; reading
BIC.B #_RTC_CS,&RTCCTLOUT ;Enable communication to RTC
BIT.B #RTC_Write,RTCTxCBuf(R4);Is this a write command?
JNZ RTCTx_CSOK ;Yes => everything is fine, keep on
BIC #FLG_Write,&RTCFlags ;Flag that this is a read command
RTCTx_CSOK: MOV.B RTCTxCBuf(R4),&RTCTXBUF ;Transfer the byte to SPI
DEC.B &TxBufLen ;One byte less in the buffer
; MOV.B &TxBufStrt,R4 ;Get the starting offset again
INC.B R4 ;Try to advance the pointer to the following byte
CMP.B #_RTCTXBUFLEN,R4 ;Pass the end of buffer?
JL RTCTx_NoRvt ;No => Do not revert to first buffer cell
MOV.B #000h,R4 ;else, revert to the starting offset of buffer
RTCTx_NoRvt:
MOV.B R4,&TxBufStrt ;Store the new offset value
;*** WORKARROUND ***
BIC.B #RTCTXIE,&RTCIE ;Temporarilly disable this interrupt
;*******************
POP R4 ;Restore R4
RTCTx_Exit: RETI
RTCTx_Discard:
MOV.B #000h,&TxBufLen ;No data in transmition buffer
BIC #FLG_Abord,&RTCFlags ;Clear the "Incomplete Command" flag
JMP RTCRTx_End ;Exit from interrupt without sending any data
;-------------------------------------------
RTCRxISR:
; When an Rx interrupt is triggered, another byte is at the reveiving buffer of SPI module.
; This ISR writes the incomming byte to the Receiving circular buffer. In case the incoming
; stream is to serve Alarm interrupt then the incoming data are stored directly to their
; associated variables, to save time and wakes up the system to use the new data
; Input: None
; Output: None
; Registers Used: R4
; Registers Altered: None
; Stack Usage: 2 bytes maximum
; Depend On Defs: FLG_WakeUp, MAXSERVEPTR, RTCRXBUF, _RTCRXBUFLEN
; Depend On Vars: RTCFlags, RTCRxCBuf, RxBufLen, RxBufStrt, ServePtr, TxBufLen
; Depend On Funcs: None
BIT #FLG_CmdByte + FLG_Write,&RTCFlags ;Did we send a command byte or serving
; a Write command? (in that case the data received
; is dummy)
JZ RTCRx_Norm ;No => Keep on receiving the byte
RTCRx_Dummy:
PUSH R4 ;Store R4 to leave it unaffected
MOV.B &RTCRXBUF,R4 ;Dummy read of this byte
RTCRx_FinCh:
POP R4 ;Restore the old value of R4
;*** WORKARROUND ***
BIS.B #RTCTXIE,&RTCIE ;Re-enable this interrupt (was disabled during
; RTXTxISR)
;*******************
CMP.B #000h,&TxBufLen ;Was this the last byte?
JNZ RTCRx_Exit ;No => just exit
BIT #FLG_CmdOK,&RTCFlags ;Did we transfer a complete command?
JZ RTCRTx_SkipCS ;No => Skip raising CS of RTC
RTCRTx_End: BIC #FLG_CmdOK+FLG_Vars,&RTCFlags ;Restore flags to their original state
BIS.B #_RTC_CS,&RTCCTLOUT ;Disable communication to RTC
BIT #FLG_LateAlm,&RTCFlags ;Do we have to late execute the alarm interrupt?
JZ RTCRTx_SkipAlm ;No => Do not fire alarm interrupt
BIC #FLG_LateAlm,&RTCFlags ;Alarm late firing is scheduled
BIS.B #_RTC_IRQ,&RTCINTIFG ;Fire the alarm interrupt
RTCRTx_SkipAlm:
BIT #FLG_WakeUp,&RTCFlags ;Test if we need to wake the system up
JZ RTCRTx_SkipCS ;No => then do not wake up the system
BIC #FLG_WakeUp,&RTCFlags ;(OK, the alarm is serviced now!)
BIC #CPUOFF+SCG0+SCG1+OSCOFF,0(SP) ;Wake up the system
RTCRTx_SkipCS:
.if SINGLEISR == 1
BIC.B #RTCTXIE,&RTCIE ;Disable Tx Interrupt from RTC
.endif
; The reason the interrupt may not be disabled in here is that when the interrupt is
; shared, the main dispatcher must disable it when there is no active hardware
; waiting for communications and not the ISR function itself
RTCRx_Exit: RETI
RTCRx_Norm: BIT #FLG_Vars,&RTCFlags ;Do we have to use variables directly to store the
; received bytes in place?
JNZ RTCRx_Vars ;Yes => Store data to alternative buffer
CMP.B #_RTCRXBUFLEN,&RxBufLen ;Is there any space left in receiving buffer?
JHS RTCRx_Dummy ;No => just exit... The incoming data are gone!...
PUSH R4 ;R4 must stay unaffected out of ISR, so store it
MOV.B &RxBufLen,R4 ;Get the length of the buffer
ADD.B &RxBufStrt,R4 ;Add the offset of the first byte
CMP.B #_RTCRXBUFLEN,R4 ;Is the total passed the end of buffer?
JL RTCRx_NoRvt ;No => then do not revert to the beginning of it
SUB.B #_RTCRXBUFLEN,R4 ;else, revert to the beginning of buffer
RTCRx_NoRvt:
MOV.B &RTCRXBUF,RTCRxCBuf(R4) ;Store the new character
INC.B &RxBufLen ;Buffer contains one more byte
JMP RTCRx_FinCh
;For alarm servicing or when we need to directly store the receiving data to their
; appropriate variables, we use the variables space as an alterative buffer.
RTCRx_Vars: CMP.B #MAXSERVEPTR,&ServePtr ;Did we reach the maximum number of bytes allowed?
JHS RTCRx_Dummy ;Yes => Just ignore this byte
PUSH R4 ;R4 must stay unaffected, so stack it
MOV.B &ServePtr,R4 ;Relative pointer of variable to be used
INC.B &ServePtr ;Advance the pointer by one
MOV.B &RTCRXBUF,CentiSecs(R4) ;Store the byte read in its appropriate variable
JMP RTCRx_FinCh ;Check if finished
;-------------------------------------------
RTCAlarmISR:
; Real Time Clock gives the ability to schedule an alarm. When the time has come, an interrupt
; coming from the RTC chip triggers this ISR. Its job is to get the time from the RTC and wake
; up the system (when all data were read from RTC). The main loop of the main program, then,
; can act as desired
; Input: None
; Output: None
; Registers Used: R4, R5 (through RTCSchedule and RTCSend functions), R6
; Registers Altered: None
; Stack Usage: 12 bytes (6 for pushing registers and 6 when calling RTCSend)
; Depend On Defs: FLG_Abord, FLG_InCmd, FLG_LateAlm, FLG_WakeUp, RTC_cS
; Depend On Vars: RTCFlags, ServePtr
; Depend On Funcs: RTCSchedule, RTCSend
BIT #FLG_InCmd,&RTCFlags ;Is there a command in progress by another process
JNZ AlmISR_Later ;Yes => do not alter it, schedule yourself later
PUSH R4 ;Store used registers. They must stay unaffected
PUSH R5 ; by the interrupt service routine
PUSH R6
; MOV.B #000h,&ServePtr ;Going to start a new packet of data
MOV.B #RTC_cS,R4 ;Going to read the whole RTC memory map
CALL #RTCSchedule ;Send this Read command to RTC
JC AlmISR_End ;If there is another command in transmition, do
; not do anything, just exit
BIS #FLG_Abord,&RTCFlags ;If we fail sending a byte then we must flag that
; this is not a complete command
MOV.B #000h,R4 ;Next bytes just create the clock pulses
MOV.B #007h,R6 ;Going to read 8 bytes to read the complete RTC
; time/date, so 7 will be scheduled and the last
; will complete the command
AlmISR_Nxt: CALL #RTCSchedule ;Send one dummy byte
JC AlmISR_End ;In case of error just abord sending command
DEC.B R6 ;One byte less to read
JNZ AlmISR_Nxt ;Repeat until all dummy bytes have been sent
CALL #RTCSend ;Send the whole command
JC AlmISR_End ;In case of error exit. Abord flag is set
;Just after the exit of this interrupt, a burst of data will start flowing through
;SPI bus to RTC. When this is over, the receiving interrupt should transfer those
;data to their appropriate variables in RAM and wake up the system
BIC #FLG_Abord,&RTCFlags ;Well, now we have a complete comand in buffer
BIS #FLG_Serve+FLG_WakeUp+FLG_Vars,&RTCFlags ;And the data must be stored
; to their propper variables directly, the system
; should wake up after executing the command and
; the Alarm was the one who woke up the system
AlmISR_End: BIC.B #_RTC_IRQ,&RTCINTIFG ;Well this interrupt is serviced
POP R6 ;Restore registers to their original values
POP R5
POP R4
RETI
;In case there is a process that has already started to schedule a command to RTC
; addind data there would alter the whole command with unpredictable result. Here
; we do not really serve the alarm interrupt, but instead we schedule it for later
; usage (just after sending the command that is in progress)
AlmISR_Later:
BIS #FLG_LateAlm,&RTCFlags ;Flag the bit that this should be served later
RETI ;and return to interrupted process
;-------------------------------------------
;==< Main Program >==========================================================================
RTCChkSPITxISR:
; Checks if RTC needs to use the bus. If yes, it takes the ownership and sends the bytes
; stored in the buffer, acting as an interrupt process. If not, then it just returns to the
; calling dispatcher routine
; Input: Expects the bus to be free. That is why the dispatcher calls this
; function (using a simple CALL command) only when it discovers the bus
; is free.
; Output: None
; Registers Used: None
; Registers Altered: None
; Stack Usage: 2 bytes maximum (by RTCTxISR interrupt service routine)
; Depend On Defs: FLG_Abord, SINGLEISR
; Depend On Vars: RTCFlags, TxBufLen
; Depend On Funcs: RTCTxISR
.if SINGLEISR == 0 ;This part of code is needed only if RTC seats on
; a shared bus
TST.B &TxBufLen ;Is the buffer empty?
JZ RTCChkExit ;Yes => Just return to the dispatcher
INCD SP ;Remove the return to caller address to act as an
; interrupt service routine
BIT #FLG_Abord,&RTCFlags;Do we have an incomplete command in buffer?
JNZ RTCTx_Discard ;Yes => Discard data
JMP RTCTx_New ;Aquire the bus and send a byte from the buffer
.endif
RTCChkExit: RET ;else, Return to calling dispatcher
;-------------------------------------------
InitRTCPorts:
; Configures the ports that the Real Time Clock chip is connected to, according to the
; definitions at the top of the file
; Input: None
; Output: None
; Registers Used: None
; Registers Altered: None
; Stack Usage: None
; Depend On Defs: RTC_ALL, RTC_CLK, _RTC_CS, _RTC_IRQ, RTCClkPort, RTCCLKSEL, RTCCTLDIR,
; RTCCTLREN, RTCCTLOUT, RTCINTDIR, RTCINTIES, RTCINTIFG, RTCINTOUT,
; _RTCIntPort, RTCINTREN, RTCSEL
; Depend On Vars: None
; Depend On Funcs: None
BIS.B #RTC_ALL,&RTCSEL ;All bits of RTC data port belong to USCI module
.if $defined("RTCClkPort") ;If clock port is different from the data port
BIS.B #RTC_CLK,&RTCCLKSEL ;it should be set as special function, too
.endif
BIS.B #_RTC_CS,&RTCCTLDIR ;Chip select pin is Output
.if $defined("_RTCIntPort") ;If the interrupt port is different then
BIC.B #_RTC_IRQ,&RTCINTDIR ;explicitly define this pin as input
BIS.B #_RTC_IRQ,&RTCINTREN ;Enable the resistor of IRQ pin
BIS.B #_RTC_IRQ,&RTCINTOUT ;And make the resistor a pull-up one
.else ;else, we can use only one command to set these
BIC.B #_RTC_IRQ,&RTCCTLDIR ;pins as inputs
BIS.B #_RTC_IRQ,&RTCCTLREN ;and enable their internal resistors
BIS.B #_RTC_IRQ,&RTCCTLOUT ;Make the IRQ resistor a pull-up one
.endif
BIS.B #_RTC_IRQ,&RTCINTIES ;Trigger interrupt on falling edge of IRQ
BIC.B #_RTC_IRQ,&RTCINTIFG ;Clear any pending interrupt flag
BIS.B #_RTC_CS,&RTCCTLOUT ;Raise CS to deactivate RTC bus
RET
;-------------------------------------------
InitRTCUSC:
; RTC is communicating with the processor through a serial SPI bus. This function initialises
; the USC module the RTC is connected to, as SPI at 4 MHz clock
; Input: None
; Output: None
; Registers Used: None
; Registers Altered: None
; Stack Usage: None
; Depend On Defs: RTCBAUD, RTCBR0, RTCBR1, RTCCTL0, RTCCTL1, RTCMCTL
; Depend On Vars: None
; Depend On Funcs: None
BIS.B #UCSWRST,&RTCCTL1 ;Reset and hold UCSI of touchscreen controller
MOV.B #UCMSB+UCMST+UCSYNC,&RTCCTL0 ; UCCKPH = 0 for sampling at falling
; edge of CLK, UCCKPL = 0 for keeping low CLK when bus is inactive,
; UCMSB = 1 for sending MSB first, UC7BIT = 0 for using 8 bit transactions
; UCMST = 1 for MSP being a SPI Master, UCMODEx = 00 for 3-wire bus and
; UCSYNC = 1 because SPI is always synchronous bus
MOV.B #UCSSEL1+UCSWRST,&RTCCTL1 ;Still in reset mode, SMCLK clocks the module
MOV.B #(RTCBAUD >> 8),&RTCBR1 ;Set the Baud Rate to 2.5MHz
MOV.B #(RTCBAUD & 0FFh),&RTCBR0
MOV.B #00000h,&RTCMCTL ;In SPI no modulation control is allowed
BIC.B #UCSWRST,&RTCCTL1 ;Let UCSI run
RET
;-------------------------------------------
InitRTCSys:
; RTC subsystem uses some variables to achieve its goal. Some of them must be initialised
; Input: None
; Output: None
; Registers Used: None
; Registers Altered: None
; Stack Usage: None
; Depend On Defs: None
; Depend On Vars: RTCFlags, RxBufLen, RxBufStrt, TxBufLen, TxBufStrt, ServePtr
; Depend On Funcs: None
MOV.B #000h,&RxBufStrt ;Receive buffer start pointer to the beginning
MOV.B #000h,&RxBufLen ;No data written in receive buffer
MOV.B #000h,&TxBufStrt ;Transmit buffer start pointer to the beginning
MOV.B #000h,&TxBufLen ;No data written in transmit buffer
MOV.B #000h,&ServePtr ;Pointer fo data storage during alarm serving
MOV #00000h,&RTCFlags ;Reset all flags
RET
;-------------------------------------------
RTCEnableInts:
; Enables all the interrupts associated with RTC's functionality. These are: Interrupt for
; sending and receiving data and port interrupt for Alarm IRQ. The GIE bit is not controlled
; by this function
; Input: None
; Output: None
; Registers Used: None
; Registers Altered: None
; Stack Usage: None
; Depend On Defs: _RTC_IRQ, RTCINTIE, RTCINTIFG, RTCIE, RTCRXIE
; Depend On Vars: None
; Depend On Funcs: None
BIS.B #RTCRXIE,&RTCIE ;Enable SPI Rx interrupts
; BIC.B #_RTC_IRQ,&RTCINTIFG ;Reset any pending Alarm Interrupt
; BIS.B #_RTC_IRQ,&RTCINTIE ;Enable Alarm Interrupt
RET
;-------------------------------------------
RTCDisableInts:
; Disables all the interrupts associated with RTC's functionality
; Input: None
; Output: None
; Registers Used: None
; Registers Altered: None
; Stack Usage: None
; Depend On Defs: _RTC_IRQ, RTCINTIE, RTCINTIFG, RTCIE, RTCRXIE
; Depend On Vars: None
; Depend On Funcs: None
BIC.B #RTCRXIE,&RTCIE ;Disable SPI interrupts (only Rx. Tx will be
; disabled when it finishes sending data)
BIC.B #_RTC_IRQ,&RTCINTIE ;Disable Alarm interrupts
BIC.B #_RTC_IRQ,&RTCINTIFG ;and reset any pending Alarm Interrupt
RET
;-------------------------------------------
RTCEnableAlarmInt:
; Enables RTC Alarm interrupt
; Input: None
; Output: None
; Registers Used: None
; Registers Altered: None
; Stack Usage: None
; Depend On Defs: _RTC_IRQ, RTCINTIE, RTCINTIFG
; Depend On Vars: None
; Depend On Funcs: None
BIC.B #_RTC_IRQ,&RTCINTIFG ;Clear any pending interrupt by RTC Alarm
BIS.B #_RTC_IRQ,&RTCINTIE ;Enable Alarm Interrupt
RET
;-------------------------------------------
RTCDisableAlarmInt:
; Disables the RTC Alarm interrupt
; Input: None
; Output: None
; Registers Used: None
; Registers Altered: None
; Stack Usage: None
; Depend On Defs: _RTC_IRQ, RTCINTIE
; Depend On Vars: None
; Depend On Funcs: None
BIC.B #_RTC_IRQ,&RTCINTIE ;Disable Alarm interrupts
RET
;-------------------------------------------
RTCSchedule:
; Schedules a byte to be sent to the Real Time Clock by storing it in Transmit Buffer.
; Input: R4 contains the byte to be scheduled