forked from seanamtalay/ECE375
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathece375-L8_TX.asm
371 lines (304 loc) · 9.88 KB
/
ece375-L8_TX.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
;***********************************************************
;*
;* Lab 8 TX - REMOTE
;*
;*
;***********************************************************
;*
;* Author: Samuel Jia Khai Lee & Namtalay Laorattanavech
;* Date: 3/13/2017
;*
;***********************************************************
.include "m128def.inc" ; Include definition file
;***********************************************************
;* Internal Register Definitions and Constants
;***********************************************************
.def mpr = r16 ; Multi-Purpose Register
.def mpr2 = r17
.def waitcnt = r18 ; Wait Loop Counter
.def ilcnt = r19 ; Inner Loop Counter
.def olcnt = r20 ; Outer Loop Counter
.equ WTime = 100 ; Time to wait in wait loop
.equ EngEnR = 4 ; Right Engine Enable Bit
.equ EngEnL = 7 ; Left Engine Enable Bit
.equ EngDirR = 5 ; Right Engine Direction Bit
.equ EngDirL = 6 ; Left Engine Direction Bit
; Use these action codes between the remote and robot
; MSB = 1 thus:
.equ BotAddress = 0b11111111
; control signals are shifted right by one and ORed with 0b10000000 = $80
.equ MovFwd = ($80|1<<(EngDirR-1)|1<<(EngDirL-1)) ;0b10110000 Move Forward Action Code
.equ MovBck = ($80|$00) ;0b10000000 Move Backward Action Code
.equ TurnR = ($80|1<<(EngDirL-1)) ;0b10100000 Turn Right Action Code
.equ TurnL = ($80|1<<(EngDirR-1)) ;0b10010000 Turn Left Action Code
.equ SpeedUp = ($80|1<<(EngDirL)) ;0b11000000 Speed Up Action Code
.equ SpeedDown = (1<<(EngDirR-1)|1<<(EngDirL-1)) ;0b00110000 Speed Down Action Code
.equ SpeedMax = ($80|1<<(EngDirL-1)) ;0b10100000 Speed Max Action Code
.equ SpeedMin = (1<<(EngDirR-1)|1<<(EngDirL)) ;0b01010000 Speed Min Action Code
;***********************************************************
;* Start of Code Segment
;***********************************************************
.cseg ; Beginning of code segment
;***********************************************************
;* Interrupt Vectors
;***********************************************************
.org $0000 ; Beginning of IVs
rjmp INIT ; Reset interrupt
.org $0046 ; End of Interrupt Vectors
;***********************************************************
;* Program Initialization
;***********************************************************
INIT:
;Stack Pointer (VERY IMPORTANT!!!!)
ldi mpr, high(RAMEND)
out SPH, mpr
ldi mpr, low(RAMEND)
out SPL, mpr
;I/O Ports
ldi mpr, $FF ;Set Port B Data Direction Regisiter
out DDRB, mpr
ldi mpr, $00 ;Initialize Port B Data Register
out PORTB, mpr
ldi mpr, $00 ;Set Port D Data Direction Register
out DDRD, mpr
ldi mpr, $FF ;Initialize Port D Data Register
out PORTD, mpr
;USART1
ldi mpr, (1<<U2X1) ;Set double data rate
sts UCSR1A, mpr
;Set baudrate at 2400bps
ldi mpr, high(416) ; Load high byte of 0x0340
sts UBRR1H, mpr ; UBRR1H in extended I/O space
ldi mpr, low(416) ; Load low byte of 0x0340
sts UBRR1L, mpr
;Enable receiver and enable receive interrupts
ldi mpr, (1<<TXEN1 | 1<<RXEN1)
sts UCSR1B, mpr
;Set frame format: 8 data bits, 2 stop bits
ldi mpr, (1<<UCSZ10)|(1<<UCSZ11)|(1<<USBS1)|(1<<UPM01)
sts UCSR1C, mpr ; UCSR0C in extended I/O space
;External Interrupts
;Set the External Interrupt Mask
ldi mpr, (1<<INT0) | (1<<INT1)
out EIMSK, mpr
clr mpr
out PORTB, mpr
;***********************************************************
;* Main Program
;***********************************************************
MAIN:
in mpr, PIND
sbrs mpr, 7 ;Check if each button/bit is cleared
rjmp TRANSMIT_R ;Then go to respective functions to transmit Bot Address and Action Code
sbrs mpr, 6
rjmp TRANSMIT_L
sbrs mpr, 5
rjmp TRANSMIT_FWD
sbrs mpr, 4
rjmp TRANSMIT_BCK
sbrs mpr, 3
rjmp TRANSMIT_SPD_MAX
sbrs mpr, 2
rjmp TRANSMIT_SPD_MIN
sbrs mpr, 1
rjmp TRANSMIT_SPD_UP
sbrs mpr, 0
rjmp TRANSMIT_SPD_DOWN
ldi mpr, (1<<INT0 | 1<<INT1) ;Clean Queue
out EIFR, mpr
rjmp MAIN
;***********************************************************
;* Functions and Subroutines
;***********************************************************
TRANSMIT_R: ;Transmit Bot Address using UDR1 to be checked for Transmit Right Function
ldi mpr2, (1<<7) ;if transmitter and receiver have the same address
out PORTB, mpr2
ldi mpr, BotAddress
sts UDR1, mpr
ldi waitcnt, 55
rcall Wait
TRANSMIT_R_LOOP1: ;Transmit Bot address and check if USART Data Register Empty is cleared
lds mpr, UCSR1A
sbrs mpr, UDRE1
rcall TRANSMIT_R_LOOP1
ldi mpr, TurnR
sts UDR1, mpr
ldi waitcnt, 250
rcall Wait
TRANSMIT_R_LOOP2:
lds mpr, UCSR1A
sbrs mpr, UDRE1
rjmp TRANSMIT_R_LOOP2
rjmp MAIN
;************************************************************
TRANSMIT_L: ;Transmit Bot Address using UDR1 to be checked for Transmit Left Function
ldi mpr2, (1<<6) ;if transmitter and receiver have the same address
out PORTB, mpr2
ldi mpr, BotAddress
sts UDR1, mpr
ldi waitcnt, 55
rcall Wait
TRANSMIT_L_LOOP1:
lds mpr, UCSR1A
sbrs mpr, UDRE1
rjmp TRANSMIT_L_LOOP1
ldi mpr, TurnL
sts UDR1, mpr
ldi waitcnt, 250
rcall Wait
TRANSMIT_L_LOOP2:
lds mpr, UCSR1A
sbrs mpr, UDRE1
rjmp TRANSMIT_L_LOOP2
rjmp MAIN
;************************************************************
TRANSMIT_FWD: ;Transmit Bot Address using UDR1 to be checked for Transmit Forward Function
ldi mpr2, (1<<5) ;if transmitter and receiver have the same address
out PORTB, mpr2
ldi mpr, BotAddress
sts UDR1, mpr
ldi waitcnt, 55
rcall Wait
TRANSMIT_FWD_LOOP1:
lds mpr, UCSR1A
sbrs mpr, UDRE1
rjmp TRANSMIT_FWD_LOOP1
ldi mpr, MovFwd
sts UDR1, mpr
ldi waitcnt, 250
rcall Wait
TRANSMIT_FWD_LOOP2:
lds mpr, UCSR1A
sbrs mpr, UDRE1
rjmp TRANSMIT_FWD_LOOP2
rjmp MAIN
;************************************************************
TRANSMIT_BCK: ;Transmit Bot Address using UDR1 to be checked for Transmit Backward Function
ldi mpr2, (1<<4) ;if transmitter and receiver have the same address
out PORTB, mpr2
ldi mpr, BotAddress
sts UDR1, mpr
ldi waitcnt, 55
rcall Wait
TRANSMIT_BCK_LOOP1:
lds mpr, UCSR1A
sbrs mpr, UDRE1
rjmp TRANSMIT_BCK_LOOP1
ldi mpr, MovBck
sts UDR1, mpr
ldi waitcnt, 250
rcall Wait
TRANSMIT_BCK_LOOP2:
lds mpr, UCSR1A
sbrs mpr, UDRE1
rjmp TRANSMIT_BCK_LOOP2
rjmp MAIN
;************************************************************
TRANSMIT_SPD_UP: ;Transmit Bot Address using UDR1 to be checked for Transmit Speed Up Function
ldi mpr2, (1<<1) ;if transmitter and receiver have the same address
out PORTB, mpr2
ldi mpr, BotAddress
sts UDR1, mpr
ldi waitcnt, 55
rcall Wait
TRANSMIT_SPD_UP_LOOP1:
lds mpr, UCSR1A
sbrs mpr, UDRE1
rcall TRANSMIT_SPD_UP_LOOP1
ldi mpr, SpeedUp
sts UDR1, mpr
ldi waitcnt, 250
rcall Wait
TRANSMIT_SPD_UP_LOOP2:
lds mpr, UCSR1A
sbrs mpr, UDRE1
rjmp TRANSMIT_SPD_UP_LOOP2
rjmp MAIN
;************************************************************
TRANSMIT_SPD_DOWN: ;Transmit Bot Address using UDR1 to be checked for Transmit Speed Down Function
ldi mpr2, (1<<0) ;if transmitter and receiver have the same address
out PORTB, mpr2
ldi mpr, BotAddress
sts UDR1, mpr
ldi waitcnt, 55
rcall Wait
TRANSMIT_SPD_DOWN_LOOP1:
lds mpr, UCSR1A
sbrs mpr, UDRE1
rcall TRANSMIT_SPD_DOWN_LOOP1
ldi mpr, SpeedDown
sts UDR1, mpr
ldi waitcnt, 250
rcall Wait
TRANSMIT_SPD_DOWN_LOOP2:
lds mpr, UCSR1A
sbrs mpr, UDRE1
rjmp TRANSMIT_SPD_DOWN_LOOP2
rjmp MAIN
;************************************************************
TRANSMIT_SPD_MAX: ;Transmit Bot Address using UDR1 to be checked for Transmit Speed Max Function
ldi mpr, BotAddress ;if transmitter and receiver have the same address
sts UDR1, mpr
ldi waitcnt, 55
rcall Wait
TRANSMIT_SPD_MAX_LOOP1:
lds mpr, UCSR1A
sbrs mpr, UDRE1
rcall TRANSMIT_SPD_MAX_LOOP1
ldi mpr, SpeedMax
sts UDR1, mpr
ldi mpr2, (1<<3)
out PORTB, mpr2
ldi waitcnt, 250
rcall Wait
TRANSMIT_SPD_MAX_LOOP2:
lds mpr, UCSR1A
sbrs mpr, UDRE1
rjmp TRANSMIT_SPD_MAX_LOOP2
rjmp MAIN
;************************************************************
TRANSMIT_SPD_MIN: ;Transmit Bot Address using UDR1 to be checked for Transmit Speed Min Function
ldi mpr2, (1<<2) ;if transmitter and receiver have the same address
out PORTB, mpr2
ldi mpr, BotAddress
sts UDR1, mpr
ldi waitcnt, 55
rcall Wait
TRANSMIT_SPD_MIN_LOOP1:
lds mpr, UCSR1A
sbrs mpr, UDRE1
rcall TRANSMIT_SPD_MIN_LOOP1
ldi mpr, SpeedMin
sts UDR1, mpr
ldi waitcnt, 250
rcall Wait
TRANSMIT_SPD_MIN_LOOP2:
lds mpr, UCSR1A
sbrs mpr, UDRE1
rjmp TRANSMIT_SPD_MIN_LOOP2
rjmp MAIN
;************************************************************
;----------------------------------------------------------------
; Sub: Wait
; Desc: A wait loop that is 16 + 159975*waitcnt cycles or roughly
; waitcnt*10ms. Just initialize wait for the specific amount
; of time in 10ms intervals. Here is the general eqaution
; for the number of clock cycles in the wait loop:
; ((3 * ilcnt + 3) * olcnt + 3) * waitcnt + 13 + call
;----------------------------------------------------------------
Wait:
push waitcnt ; Save wait register
push ilcnt ; Save ilcnt register
push olcnt ; Save olcnt register
Loop: ldi olcnt, 224 ; load olcnt register
OLoop: ldi ilcnt, 237 ; load ilcnt register
ILoop: dec ilcnt ; decrement ilcnt
brne ILoop ; Continue Inner Loop
dec olcnt ; decrement olcnt
brne OLoop ; Continue Outer Loop
dec waitcnt ; Decrement wait
brne Loop ; Continue Wait loop
pop olcnt ; Restore olcnt register
pop ilcnt ; Restore ilcnt register
pop waitcnt ; Restore wait register
ret ; Return from subroutine