-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathElevatorController.s
More file actions
980 lines (812 loc) · 40.1 KB
/
ElevatorController.s
File metadata and controls
980 lines (812 loc) · 40.1 KB
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
@ CSC230 -- Elevator simulation program
@ Template Author: Dr. Micaela Serra
@ Modified by: Stevie Howard
@===== STAGE 0
@ Sets initial outputs and screen
@ Enters IDLE state and updates simulated time every second
@ Polls for left black button to exit simulation
.equ SWI_EXIT, 0x11 @terminate program
@ swi codes for using the Embest board
.equ SWI_SETSEG8, 0x200 @display on 8 Segment
.equ SWI_SETLED, 0x201 @LEDs on/off
.equ SWI_CheckBlack, 0x202 @check press Black button
.equ SWI_CheckBlue, 0x203 @check press Blue button
.equ SWI_DRAW_STRING, 0x204 @display a string on LCD
.equ SWI_DRAW_INT, 0x205 @display an int on LCD
.equ SWI_CLEAR_DISPLAY, 0x206 @clear LCD
.equ SWI_DRAW_CHAR, 0x207 @display a char on LCD
.equ SWI_CLEAR_LINE, 0x208 @clear a line on LCD
.equ SEG_A, 0x80 @ patterns for 8 segment display
.equ SEG_B, 0x40
.equ SEG_C, 0x20
.equ SEG_D, 0x08
.equ SEG_E, 0x04
.equ SEG_F, 0x02
.equ SEG_G, 0x01
.equ SEG_P, 0x10
.equ LEFT_LED, 0x02 @patterns for LED lights
.equ RIGHT_LED, 0x01
.equ BOTH_LED, 0x03
.equ NO_LED, 0x00
@ bit patterns for black buttons
.equ LEFT_BLACK_BUTTON, 0x02
.equ RIGHT_BLACK_BUTTON, 0x01
@ bit patterns for blue keys
.equ C1, 1<<0 @ =1
.equ C2, 1<<1 @ =2
.equ C3, 1<<2 @ =4
.equ C4, 1<<3 @ =8
.equ F1UP, 1<<4 @ =16
.equ F2UP, 1<<5 @ =32
.equ F3UP, 1<<6 @ =64
.equ F2DW, 1<<9 @ = 512
.equ F3DW, 1<<10 @ = 1024
.equ F4DW, 1<<11 @ = 2056
@ timing related
.equ SWI_GetTicks, 0x6d @get current time
.equ EmbestTimerMask, 0x7fff @ 15 bit mask for Embest timer
@(2^15) -1 = 32,767
.equ OneSecond, 1000 @ Time intervals
.equ HalfSecond, 500
.equ WaitFloors, 4 @ seconds moving between floors
.equ WaitDoors, 4 @ seconds opening doors
@ Values used for initialization
.equ NumTextLines, 5
.equ EndSimulation, -2
.equ EmergencyStop, -1
.equ RequestsDone, 0
.equ TopFloor, 4
.equ BottomFloor, 1
.text
.global _start
@======================================================================================================@
@======================================================================================================@
@======================================================================================================@
@===== The entry point of the program =================================@
_start: @ go to initial idle state at floor 1
ldr r3,=FloorNum @ draw initial screen
bl Initdraw @ Initdraw(R3:&floor)
ldr r4,=SimulTime
mov r0,#0 @ no requests
MainControl: @ go to Idling until some event
ldr r7,[r3] @ R7 = current floor
bl Idling @ R0<--Idling(R3:&floor;R4:&simulation time)
@ when back here, some event happened: check which one
@ It cannot be emergency, that is taken care of directly
cmp r0,#EndSimulation @ was it end of program?
beq NormalExit
SwitchOnBlue: @ check which blue button
ldr r7,[r3] @ r7 = current floor
cmp r0,#C1 @ check if button pushed was C1
beq CF1UP
cmp r0,#C2 @ check if button pushed was C2
beq CF2UPDW
cmp r0,#C3 @ check if button pushed was C3
beq CF3UPDW
cmp r0,#C4 @ check if button pushed was C4
beq CF4DW
cmp r0,#F1UP @ check if button pushed was F1UP
beq CF1UP
cmp r0,#F2UP @ check if button pushed was F2UP
beq CF2UPDW
cmp r0,#F3UP @ check if button pushed was F3UP
beq CF3UPDW
cmp r0,#F2DW @ check if button pushed was F2DW
beq CF2UPDW
cmp r0,#F3DW @ check if button pushed was F3DW
beq CF3UPDW
cmp r0,#F4DW @ check if button pushed was F4DW
beq CF4DW
bal MainControl @ if any other button, ignore
CF1UP:
cmp r7,#1 @ is elevator already on floor 1?
beq EndSwitchOnBlue @ yes - then no action required
bgt MoveDown @ no - then car needs to move down: MoveDown
CF2UPDW:
cmp r7,#2 @ is elevator already on floor 2?
beq EndSwitchOnBlue @ yes - then no action required
bgt MoveDown @ current floor < calling floor, so car needs to move down
blt MoveUp @ current floor > calling floor, so car needs to move up
CF3UPDW:
cmp r7,#3 @ is elevator already on floor 3?
beq EndSwitchOnBlue @ yes - then no action required
bgt MoveDown @ current floor < calling floor, so car needs to move down
blt MoveUp @ current floor > calling floor, so car needs to move up
CF4DW:
cmp r7,#4 @ is elevator already on floor 4?
beq EndSwitchOnBlue @ yes - then no action required
blt MoveUp @ current floor > calling floor, so car needs to move up
EndSwitchOnBlue:
bal MainControl @ return to an idle
MoveUp: @ MoveUp(r7=current floor)
bl MovingUp @ MovingUp(R3= &floor; R4= &simulation time)
cmp r0,#EndSimulation @ was stop button pushed?
beq NormalExit @ yes - end simulation normally
bl CheckSignalsLower @ CheckSignalsLower(r3: &floor)
cmp r0,#1 @ check the result of CheckSignalsLower
beq MoveDown @ If the result is a 1 the car must go down, MoveDown(r7=current floor)
bal MainControl @ otherwise return to idling
MoveDown: @ MoveDown(r7=current floor)
bl MovingDown @ MovingDown(R3= &floor; R4= &simulation time)
cmp r0,#EndSimulation @ check for stop button pushed
beq NormalExit @ end simulation normally
bl CheckSignalsHigher @ CheckSignalsHigher(r3: &floor)
cmp r0,#1 @ check the result of CheckSignalsHigher
beq MoveUp @ If the result is a 1 the car must go up, MoveUp(r7=current floor)
bal MainControl @ otherwise return to idling
NormalExit:
bl ExitClear @ clear all, come back and exit
bal EndElevator
EndElevator:
swi SWI_EXIT @ program main exit
@======================================================================@
@======================================================================@
@ === Idling (R3:&floor;R4:&simulation time)-->R0 =====================@
@ Inputs: R3 = & floor; R4 = & simulation time
@ Output: R0 = #EndSimulation,
@ = #EmergencyStop
@ = number >0 for blue button pattern
@ Description:
@ Poll buttons continuosly
@ Every 1 second, update simulation time on screen
Idling:
stmfd sp!,{r1-r10,lr}
mov r5,#0 @ Display Idle State on all outputs
BL UpdateDirectionScreen @ UpdateDirectionScreen(R5:direction)
mov r5,#1 @ point (stopped)
BL UpdateFloor @ UpdateFloor(R3:&floor;R5:stopped)
mov r0, #NO_LED @ LEDs off
swi SWI_SETLED
ldr r7, =EmbestTimerMask @ mask for 15 bit timer
ldr r10,=OneSecond @ interval to update time
PollMainEv:
swi SWI_GetTicks @ get time T0
and r0,r0,r7 @ T0 in 15 bits
ldr r1, =Time0
str r0, [r1] @ save T1 in Time0
RepeatTillTimeEv:
swi SWI_CheckBlack
cmp r0, #LEFT_BLACK_BUTTON @ end of simulation
beq ShutEv
cmp r0, #RIGHT_BLACK_BUTTON @ emergency manual shutdown
beq EmButtonEv
swi SWI_CheckBlue @ car or floor button
cmp r0,#0
bne BlueButtonEv @ pressed blue buttons
@ else here no events detected, keep checking time passing
swi SWI_GetTicks @ get time T1
and r0,r0,r7 @ T1 in 15 bits
mov r2,r0 @ r2 is T1
ldr r3, =Time0
ldr r1, [r3] @ r1 is T0
cmp r2,r1 @ is T1>T0?
bge SimpleTimeEv
sub r9,r7,r1 @ elapsed TIME= 32,676 - T0
add r9,r9,r2 @ + T1
bal CheckIntervalEv
SimpleTimeEv:
sub r9,r2,r1 @ elapsed TIME = T1-T0
CheckIntervalEv:
cmp r9,r10 @ is TIME < update period?
blt RepeatTillTimeEv
@ enough time passed without events, need to update outputs
str r0, [r3] @ update Time0
BL UpdateTime @ UpdateTime(R4: & simul time)
bal PollMainEv @ then keep polling till event
BlueButtonEv: @ store event type in global array
BL SetButtonsArray @ SetButtonsArray(r0:blue button)
bal DoneIdling
EmButtonEv:
mov r0,#EmergencyStop @ get out
bal EmergencyState
ShutEv:
mov r0,#EndSimulation @ ending simulation
DoneIdling:
LDMFD sp!,{r1-r10,pc}
@======================================================================@
@======================================================================@
@ === Void SetButtonsArray(r0:blue button)=============================@
@ Inputs: r0=blue button request
@ Results: none
@ Description:
@ Set the appropriate entry in the global array of requests
@ if it is a valid button
@
SetButtonsArray:
STMFD sp!,{r0-r6,lr}
ldr r3,=ButtonsArray @ address of global array
mov r2,#1 @ flag
ldr r4,=0x0000FFFF @ mask to clear upper register
and r0,r0,r4 @ clear upper 16 bits
mov r5,#1 @ find position of blue button
mov r6,#1 @ to translate to index in array
LP1:
cmp r5,r0 @ is this position?
beq Index @ position found
mov r5,r5,lsl #1 @ else try next position
add r6,r6,#1
bal LP1
Index:
sub r0,r6,#1 @ index=button-1
cmp r0,#12 @ button 12,13,14,15 9 (i.e. >12) invalid
bge EndSetButtonsArray
cmp r0,#7 @ button 7,8 invalid
beq EndSetButtonsArray
cmp r0,#8
beq EndSetButtonsArray
str r2,[r3,r0,LSL #2] @ array[index*4]
EndSetButtonsArray:
swi SWI_CheckBlue @ clear for buttons bounce?
LDMFD sp!,{r0-r6,pc}
@======================================================================@
@======================================================================@
@ === Void ClearButtonsArray(r3: &floor)===============================@
@ Inputs: r3 = & floor
@ Results: none
@ Description:
@ Clear the entries in the global array for a given floor
@
ClearButtonsArray:
STMFD sp!,{r1-r4,lr}
ldr r1,=ButtonsArray @ address of global array
mov r2,#0 @ flag
ldr r3,[r3] @ floor
sub r3,r3,#1 @ index=floor-1
mov r4,#3 @ loop counter for 3 arrays
RB:
str r2,[r1,r3,LSL #2] @ array[index*4]
add r3,r3,#4 @ next array
subs r4,r4,#1 @ decrement loop counter, have we looped 3 times?
bne RB @ no - keep looping
LDMFD sp!,{r1-r4,pc}
@======================================================================@
@======================================================================@
@ === WaitAndPoll (R4: & simul time;R5:waiting time)===================@
@ Inputs: R4 = & simulation time
@ R5 = time in seconds to wait while polling
@ Results: R0 = #EndSimulation,
@ = #EmergencyStop
@ = 0 otherwise
@ Side effects: if events captured, global arrays updated
@ Description:
@ Poll buttons while waiting for a length of time
@ in seconds, and every 1 second update simulation
@ time on screen. If polling captures event, arrays
@ for signals are updated
@ Used when elevator is moving between floors
@ or when doors are opening
@
WaitAndPoll:
stmfd sp!,{r1-r10,lr}
ldr r7, =EmbestTimerMask @ mask for 15 bit timer
ldr r10,=OneSecond @ interval to update time
mov r6,#0 @ r6 is loop counter to count full seconds
WaitPollMainEv:
swi SWI_GetTicks @ get time T0
and r0,r0,r7 @ T0 in 15 bits
ldr r1, =Time0 @ R1 = T0
str r0, [r1] @ save T0 in Time0
WaitRepeatTillTimeEv:
swi SWI_CheckBlack
cmp r0, #LEFT_BLACK_BUTTON @ end of simulation
beq WaitShutEv
cmp r0, #RIGHT_BLACK_BUTTON @ emergency manual shutdown
beq WaitEmButtonEv
swi SWI_CheckBlue @ car or floor button
cmp r0,#0
bne WaitBlueButtonEv @ pressed blue buttons
@ else no events detected, keep checking time passing
swi SWI_GetTicks @ get time T1
and r8,r0,r7 @ T1 in 15 bits
mov r2,r8 @ r2 is T1
ldr r3, =Time0
ldr r1,[r3] @ r1 is T0
cmp r2,r1 @ is T1>T0?
bge WaitSimpletimeEv
sub r9,r7,r1 @ elapsed TIME= 32,676 - T0
add r9,r9,r2 @ + T1
bal WaitCheckIntervalEv
WaitSimpletimeEv:
sub r9,r2,r1 @ elapsed TIME = T1-T0
WaitCheckIntervalEv:
cmp r9,r10 @ is TIME < update period?
blt WaitRepeatTillTimeEv
@ enough time passed without events, need to update outputs
str r0, [r3] @ update Time0
BL UpdateTime @ UpdateTime(R4: & simul time)
add r6,r6,#1 @ increment loop counter
cmp r6,r5 @ is number of loops < 5?
blt WaitPollMainEv @ then keep polling till event
bal EndWaitAndPoll
WaitBlueButtonEv: @ store event type in global array
BL SetButtonsArray @ SetButtonsArray(r0:blue button)
bal WaitRepeatTillTimeEv
WaitEmButtonEv:
mov r0,#EmergencyStop @ get out
bal EmergencyState
WaitShutEv:
mov r0,#EndSimulation @ ending simulation
EndWaitAndPoll:
LDMFD sp!,{r1-r10,pc}
@======================================================================@
@======================================================================@
@ ===CheckSignalsHigher(r3: &floor)====================================@
@ Input: r3 = & floor
@ Results: R0 = 0 (no to higher signal); 1 (yes to higher signal)
@ Description:
@ Check global arrays for any signals at floor>given floor
CheckSignalsHigher:
STMFD sp!,{r1-r10,lr}
ldr r1,=ButtonsArray @ address of global array
ldr r0,=RequestsDone @ no flag found (by default)
mov r6,#0 @ outer loop counter for each floor being checked
ldr r7,=TopFloor @ R7 = number of floors
ldr r3,[r3] @ floor number, used as index to check floor above current floor.
sub r5,r7,r3 @ R5 = loop counter for # floors to check (1st one checked automatically)
HighWrap:
mov r4,#3 @ loop counter for 3 arrays
HighLoop:
ldr r2,[r1,r3,LSL #2] @ array[index*4]
cmp r2,#1 @ is the value at this position in array == 1?
beq HigherSignalExists @ yes - then it is a signal, and it is higher.
add r3,r3,#4 @ else check next array
subs r4,r4,#1 @ have we looped 3 times? once for each array?
bne HighLoop @ if not, loop again
sub r3,r3,#11 @ R3 = floor above the last floor checked
add r6,r6,#1 @ add one to outer loop counter
cmp r6,r5 @ has the outer loop run enough times to check all possible floors?
blt HighWrap @ no - loop again checking the next higher floor.
EndCheckSignalsHigher: @ return to calling function
LDMFD sp!,{r1-r10,pc}
HigherSignalExists:
mov r0,#1 @ move the flag into R0 to indicate that a higher signal exists
bal EndCheckSignalsHigher
@======================================================================@
@======================================================================@
@ ===CheckSignalsLower(r3: &floor)=====================================@
@ Inputs: r3 = & floor
@ Output: R0 = 0 (no to lower signal); 1 (yes to lower signal)
@ Description:
@ Check global arrays for any signals at floor<given floor
CheckSignalsLower:
STMFD sp!,{r1-r10,lr}
ldr r1,=ButtonsArray @ address of global array
ldr r0,=RequestsDone @ no flag found (by default)
mov r6,#0 @ outer loop counter for each floor to be checked
ldr r3,[r3] @ R3=current floor number
sub r5,r3,#1 @ R5 = loop counter for how many additional floors to check (will check first one automatically)
sub r3,r3,#2 @ index=floor-2 to access the floor below current, in array
LowWrap:
mov r4,#3 @ loop counter for 3 arrays
LowLoop:
ldr r2,[r1,r3,LSL #2] @ array[index*4]
cmp r2,#1 @ is the value at this position in array == 1?
beq LowerSignalExists @ yes - then there are lower floors signalled
add r3,r3,#4 @ else check next array
subs r4,r4,#1 @ have we looped 3 times - once for each array?
bne LowLoop @ no - loop again
sub r3,r3,#13 @ R3 = floor below the last floor checked
add r6,r6,#1 @ add one to outer loop counter
cmp r6,r5 @ has the outer loop run enough times to check all possible floors?
blt LowWrap @ no - loop again checking the next lower floor.
EndCheckSignalsLower: @ return to calling function
LDMFD sp!,{r1-r10,pc}
LowerSignalExists:
mov r0,#1 @ move the flag into R0 to indicate that a higher signal exists
bal EndCheckSignalsLower
@======================================================================@
@======================================================================@
@ ===CheckFloorSignal(r3: &floor)======================================@
@ Inputs: r3 = & floor
@ Output: none
@ Description:
@ Check global arrays for any signals at current floor
CheckFloorSignal:
STMFD sp!,{r1-r10,lr}
ldr r0,=RequestsDone @ no flag found yet (by default)
ldr r1,=ButtonsArray @ address of global array
ldr r3,[r3] @ R3 = floor number
sub r3,r3,#1 @ index=floor-1
mov r4,#3 @ loop counter for 3 arrays
FloorSignal:
ldr r2,[r1,r3,LSL #2] @ array[index*4]
cmp r2,#1 @ check if the content at that index is a 1
beq FloorSignalExists @ if there is a 1 at this index in any array, the signal is there
add r3,r3,#4 @ move on to next array
subs r4,r4,#1 @ decrement loop counter
bne FloorSignal @ loop 3 times
beq EndCheckFloorSignal
FloorSignalExists:
mov r0,#1 @ R0=1 to indicate a flag was found
EndCheckFloorSignal:
LDMFD sp!,{r1-r10,pc}
@======================================================================@
@======================================================================@
@ ===MovingUp (R3= &floor; R4= &simulation time)=======================@
@ Inputs: R3 = &floor; R4 = &simulation time
@ Output: R0 = #EndSimulation,
@ = #EmergencyStop
@ = 0 otherwise
@ Side effects: if events captured, global arrays updated
@ Description:
@ Move up each floor until all UP requests done
MovingUp:
STMFD sp!,{r1-r10,lr}
ldr r7,[r3] @ R7 = current floor
mov r5,#1 @ R5 = 1 to indicate up direction
BL UpdateDirectionScreen @ UpdateDirectionScreen(R5:direction)
mov r5,#0 @ no 8-segment dot (moving)
BL UpdateFloor @ UpdateFloor(R3:&floor;R5:moving)
mov r0, #LEFT_LED @ Left LED on
swi SWI_SETLED @ LEDs updated
TopMovingUp:
ldr r5,=WaitFloors @ set delay for floor travel time
bl WaitAndPoll @ check for any buttons pushed while traveling between floors
cmp r0,#EndSimulation @ check for stop button pushed
beq EndMovingUp @ return to Main for exit instructions
add r7,r7,#1 @ floor indicator incremented by one
str r7,[r3] @ floor variable incremented by one
mov r5,#0 @ no 8-segment dot
bl UpdateFloor @ UpdateFloor(R3:&floor;R5:moving)
bl CheckFloorSignal @ look for a call at current floor
cmp r0,#1 @ check for a "yes" returned by checkfloorsignal
bne CheckTop @ if no signal at current floor, go to CheckTop
bl OpenDoors @ OpenDoors (R3: &floor;R4: &simul time)
cmp r0,#EndSimulation @ check whether exit button was pressed
beq EndMovingUp @ if yes, finished moving up.
mov r0, #LEFT_LED @ Left LED on
swi SWI_SETLED
CheckTop:
cmp r7,#TopFloor @ check whether current floor is top floor
beq EndMovingUp @ yes - then we cannot go any higher
bl CheckSignalsHigher @ CheckSignalsHigher(r3: &floor)
cmp r0,#1 @ check whether there have been calls from higher floors
bne EndMovingUp
mov r5,#1 @ R5=1 to indicate up direction
bl UpdateDirectionScreen @ UpdateDirectionScreen(R5:direction)
bal TopMovingUp @ continue loop to continue moving up
EndMovingUp:
LDMFD sp!,{r1-r10,pc}
@======================================================================@
@======================================================================@
@ === MovingDown(R3: &floor;R4: &simul time)===========================@
@ Inputs: R3 = & floor; R4 = & simulation time
@ Output: R0 = #EndSimulation,
@ = #EmergencyStop
@ = 0 otherwise
@ Side effects: if events captured, global arrays updated
@ Description:
@ Move down each floor until all DOWN requests done
MovingDown:
STMFD sp!,{r1-r10,lr}
ldr r7,[r3] @ R7 = current floor
mov r5,#-1 @ R5=-1 to indicate down direction
BL UpdateDirectionScreen @ UpdateDirectionScreen(R5:direction)
mov r5,#0 @ 8-segment should have no dot (moving)
BL UpdateFloor @ UpdateFloor(R3:&floor;R5:moving)
mov r0, #RIGHT_LED @ Right LED on
swi SWI_SETLED
TopMovingDown:
ldr r5,=WaitFloors
bl WaitAndPoll
cmp r0,#EndSimulation @ check for stop button pushed
beq EndMovingDown @ return to Main for exit instructions
sub r7,r7,#1 @ decrement floor counter
str r7,[r3] @ floor variable decremented by one
mov r5,#0 @ no 8-segment dot
bl UpdateFloor @ UpdateFloor(R3:&floor;R5:moving)
bl CheckFloorSignal @ look for a call at current floor
cmp r0,#1 @ check for a "yes" returned by checkfloorsignal
bne CheckBottom @ if no signal at current floor, go to CheckTop
bl OpenDoors @ OpenDoors (R3: &floor;R4: &simul time)
cmp r0,#EndSimulation @ check whether exit button was pressed
beq EndMovingDown @ if yes, finished moving up.
mov r0, #RIGHT_LED @ Left LED on
swi SWI_SETLED
CheckBottom:
cmp r7,#BottomFloor @ check whether current floor is top floor
beq EndMovingDown @ yes - cannot go any lower.
bl CheckSignalsLower @ CheckSignalsLower(r3: &floor)
cmp r0,#1 @ check whether there has been a call from lower floors
bne EndMovingDown @ no - finished moving down.
mov r5,#-1 @ R5=1 to indicate up direction
bl UpdateDirectionScreen @ UpdateDirectionScreen(R5:direction)
bal TopMovingDown @ continue loop to continue moving down
EndMovingDown: @ return to calling function
LDMFD sp!,{r1-r10,pc}
@======================================================================@
@======================================================================@
@ === OpenDoors (R3: &floor;R4: &simul time)===========================@
@ Inputs: R3 = & floor; R4 = & simulation time
@ Output: R0 = #EndSimulation,
@ = #EmergencyStop
@ = 0 otherwise
@ Side effects: clears arrays at floor number
@ Description:
@ Set the outputs for doors open,
@ stay for X seconds while polling
OpenDoors:
STMFD sp!,{r1-r10,lr}
mov r5,#2 @ Display open doors
BL UpdateDirectionScreen @ UpdateDirectionScreen(R5:direction)
mov r5,#0 @ 8-segment should have no dot
BL UpdateFloor @ UpdateFloor(R3:&floor;R5:stopped)
mov r0, #BOTH_LED @ bothLEDs on
swi SWI_SETLED
ldr r5,=WaitDoors @ Set wait time for doors
bl WaitAndPoll @ WaitAndPoll(R4=&simulation time, R5=delay time)
bl ClearButtonsArray @ ClearButtonsArray(r3: &floor)
EndOpenDoors:
LDMFD sp!,{r1-r10,pc}
@======================================================================@
@======================================================================@
@===== UpdateTime(R4:& simulated time)=================================@
@ Inputs: R4 = & simulated time
@ Output: none
@ Description:
@ Displays the updated value of the current simulation time
@ on screen and updates its variable
UpdateTime:
stmfd sp!, {r0-r4,lr}
ldr r2,[r4] @update simulated time
add r2,r2,#1
str r2,[r4]
mov r1, #2 @ r1 = next line number to display
mov r0, #20 @ r0 = column number for displayed strings
swi SWI_DRAW_INT
EndUpdateTime:
ldmfd sp!, {r0-r4,pc}
@======================================================================@
@======================================================================@
@===== UpdateFloor(R3:&floor;R5:stopped)===============================@
@ Inputs: R3 = & floor number;R5 = 1(idle) or 0(moving)
@ Output: none
@ Description:
@ Displays the value of the current floor on the LCD screen
@ and in the 8-segment
UpdateFloor:
stmfd sp!, {r0-r2,lr}
ldr r0,[r3] @ r0=floor number
mov r1,r5 @ point?
BL Display8Segment @ Display8Segment (Number:R0; Point:R1)
mov r2,r0 @ r2=floor number
mov r0,#20 @ column on screen
mov r1,#4 @ row on screen
swi SWI_DRAW_INT
EndUpdateFloor:
ldmfd sp!, {r0-r2,pc}
@======================================================================@
@======================================================================@
@===== UpdateDirectionScreen(R5:direction)=============================@
@ Inputs: R5 = current direction of elevator movement
@ Output: none
@ Description:
@ Displays the pattern for the elevator direction on
@ the appropriate 5 lines on the LCD screen
@ Direction: -1 = down; 0 = stopped; 1 = up ; 2 open doors
UpdateDirectionScreen:
stmfd sp!, {r0-r5,lr}
mov r4,#0 @ line counter
cmp r5,#0 @ establish direction
blt DirDown
beq DirIdle
cmp r5,#1
beq DirUp
DirOp: ldr r2,=lineD1op
bal DrawDir
DirDown: ldr r2,=lineD1dw
bal DrawDir
DirIdle: ldr r2,=lineD1st
bal DrawDir
DirUp: ldr r2,=lineD1up
DrawDir:
mov r1, #6 @ r1 = row
mov r0, #0 @ r0 = column
Drl:
swi SWI_DRAW_STRING
add r1, r1, #1 @ next line number
add r2,r2,#8 @ next string
add r4,r4,#1 @ update line counter
cmp r4, #NumTextLines
blt Drl
EndUpdateDirectionScreen:
ldmfd sp!, {r0-r5,pc}
@======================================================================@
@======================================================================@
@ =====Initdraw(R3:& floor)============================================@
@ Inputs: R3 = & floor
@ Output: none
@ Description:
@ Draws the initial state of LCD screen, LEDs
@ and 8-segment
Initdraw:
stmfd sp!, {r0-r5,lr}
mov r1, #0 @ r1 = row
mov r0, #0 @ r0 = column
ldr r2, =lineID @ identification
swi SWI_DRAW_STRING
mov r1, #2 @ r1 = row
mov r0, #10 @ r0 = column
ldr r2, =lineTime @ time XXX
swi SWI_DRAW_STRING
mov r1, #4 @ r1 = row
mov r0, #10 @ r0 = column
ldr r2, =lineFloor @ floor number XX
swi SWI_DRAW_STRING
mov r1, #11 @ r1 = row
mov r0, #1 @ r0 = column
ldr r2, =keysline1 @ floor number XX
swi SWI_DRAW_STRING
mov r1, #12 @ r1 =row
mov r0, #1 @ r0 = column
ldr r2, =keysline2 @ floor number XX
swi SWI_DRAW_STRING
mov r1, #13 @ r1 = row
mov r0, #1 @ r0 = column
ldr r2, =keysline3 @ floor number XX
swi SWI_DRAW_STRING
mov r5,#0 @ Draw the Idle State strings
BL UpdateDirectionScreen @ UpdateDirectionScreen(R5:direction)
mov r5,#1 @ point (stopped)
BL UpdateFloor @ UpdateFloor(R3:&floor;R5:stopped)
mov r0, #NO_LED @ LEDs off
swi SWI_SETLED
mov r0,#1 @ floor 1
mov r1,#1 @ stopped
BL Display8Segment @ Display8Segment(R0:number;R1:point)
EndInitdraw:
ldmfd sp!, {r0-r5,pc}
@======================================================================@
@======================================================================@
@=====EmergencyState()=================================================@
@ Inputs: none
@ Output: none
@ Description:
@ The function sets the configuration for
@ the output devices in case of emergency.
@ NOTE: this function does not return to Main Control;
@ execution stays here in an infinite loop after
@ updating outputs, until program is ended manually
EmergencyState:
swi SWI_CLEAR_DISPLAY @ clear standard output from LCD
mov r0, #0 @ column 1 for message display
mov r1, #7 @ line 8 for message display
ldr r2, =EmergencyMessage
swi SWI_DRAW_STRING @ display emergency message on line 7
EmergencyFlashing:
mov r0, #8 @ 8-segment pattern ALL on (like an 8)
mov r1,#0 @ 8-segment dot off
BL Display8Segment @ Display8Segment(R0:number;R1:point)
mov r0, #BOTH_LED
swi SWI_SETLED @ both LEDs on
ldr r10,=HalfSecond @ set delay to half a second
bl Wait @ wait for half a second with all lights on
mov r0, #10 @ 8-segment pattern ALL off
BL Display8Segment @ Display8Segment(R0:number;R1:point)
mov r0, #NO_LED
swi SWI_SETLED @ both LEDs off
ldr r10,=HalfSecond
bl Wait @ wait for half a second with lights off, Wait(Delay:r10)
bal EmergencyFlashing @ loop for the rest of eternity
@======================================================================@
@======================================================================@
@===== ExitClear()=====================================================@
@ Inputs: none
@ Output: none
@ Description:
@ Clear the board and display the last message
ExitClear:
stmfd sp!, {r0-r2,lr}
mov r0, #10 @ 8-segment pattern off
mov r1,#0
BL Display8Segment @ Display8Segment(R0:number;R1:point)
mov r0, #NO_LED
swi SWI_SETLED @ clear LEDs
swi SWI_CLEAR_DISPLAY @ clear LCD
mov r0, #5
mov r1, #7
ldr r2, =Goodbye
swi SWI_DRAW_STRING @ display goodbye message on line 8
EndExitClear:
ldmfd sp!, {r0-r2,pc}
@======================================================================@
@======================================================================@
@ ==== void Wait(Delay:r10) ===========================================@
@ Inputs: R10 = delay in milliseconds
@ Output: none
@ Description:
@ Wait for r10 milliseconds using a 15-bit timer
Wait:
stmfd sp!, {r0-r2,r7-r10,lr}
ldr r7, =EmbestTimerMask
swi SWI_GetTicks @ get time T1
and r1,r0,r7 @ T1 in 15 bits
WaitLoop:
swi SWI_GetTicks @ get time T2
and r2,r0,r7 @ T2 in 15 bits
cmp r2,r1 @ is T2>T1?
bge simpletimeW
sub r9,r7,r1 @ elapsed TIME= 32,676 - T1
add r9,r9,r2 @ + T2
bal CheckIntervalW
simpletimeW:
sub r9,r2,r1 @ elapsed TIME = T2-T1
CheckIntervalW:
cmp r9,r10 @ is TIME < desired interval?
blt WaitLoop
EndWait:
ldmfd sp!, {r0-r2,r7-r10,pc}
@======================================================================@
@======================================================================@
@ *** Display8Segment (Number:R0; Point:R1) ***========================@
@ Inputs: R0=number to display; R1=point or no point
@ Output: none
@ Description:
@ Displays the number 0-9 in R0 on the 8-segment
@ If R1 = 1, the point is also shown
Display8Segment:
STMFD sp!,{r0-r2,lr}
ldr r2,=Digits
ldr r0,[r2,r0,lsl#2]
tst r1,#0x01 @if r1=1,
orrne r0,r0,#SEG_P @ then show P
swi SWI_SETSEG8
EndDisplay8Segment:
LDMFD sp!,{r0-r2,pc}
@======================================================================================================@
@======================================================================================================@
@======================================================================================================@
@======================================================================================================@
.data
.align
SimulTime: .word 0
Time0: .skip 4
FloorNum: .word 1
ButtonsArray:
ButtonsCar: .word 0,0,0,0 @ 4 words for 4 car buttons
FloorUp: .word 0,0,0,0 @ floor 1,2,3 up,4 unused
FloorDw: .word 0,0,0,0 @ floor 2,3,4 down, 1 unused
Digits: @ for 8-segment display:
.word SEG_A|SEG_B|SEG_C|SEG_D|SEG_E|SEG_G @ 0
.word SEG_B|SEG_C @ 1
.word SEG_A|SEG_B|SEG_F|SEG_E|SEG_D @ 2
.word SEG_A|SEG_B|SEG_F|SEG_C|SEG_D @ 3
.word SEG_G|SEG_F|SEG_B|SEG_C @ 4
.word SEG_A|SEG_G|SEG_F|SEG_C|SEG_D @ 5
.word SEG_A|SEG_G|SEG_F|SEG_E|SEG_D|SEG_C @ 6
.word SEG_A|SEG_B|SEG_C @ 7
.word SEG_A|SEG_B|SEG_C|SEG_D|SEG_E|SEG_F|SEG_G @ 8
.word SEG_A|SEG_B|SEG_F|SEG_G|SEG_C @ 9
.word 0 @ Blank
lineID: .asciz "Elevator -- Stevie Howard"
lineTime: .asciz "Time: seconds"
lineFloor: .asciz "Floor = "
keysline1: .asciz "Blue Keys: C1, C2, C3, C4"
keysline2: .asciz " FU1 FU2 FU3 XX"
keysline3: .asciz " XX FD2 FD3 FD4"
.align
lineD1up: .asciz " @ "
lineD2up: .asciz " @|@ "
lineD3up: .asciz " @ | @ "
lineD4up: .asciz " | "
lineD5up: .asciz " | "
lineD1st: .asciz "@@@@@@@"
lineD2st: .asciz "@@@@@@@"
lineD3st: .asciz "@@@@@@@"
lineD4st: .asciz "@@@@@@@"
lineD5st: .asciz "@@@@@@@"
lineD1dw: .asciz " | "
lineD2dw: .asciz " | "
lineD3dw: .asciz " @ | @ "
lineD4dw: .asciz " @|@ "
lineD5dw: .asciz " @ "
lineD1op: .asciz "@@@@@@@"
lineD2op: .asciz "@ @"
lineD3op: .asciz "@ @"
lineD4op: .asciz "@ @"
lineD5op: .asciz "@@@@@@@"
Goodbye:
.asciz "**** Elevator program ended. ****"
EmergencyMessage:
.asciz "***ELEVATOR EMERGENCY - TIME TO PANIC!**"
.end