-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.asm
More file actions
393 lines (326 loc) · 9.29 KB
/
Copy pathmain.asm
File metadata and controls
393 lines (326 loc) · 9.29 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
;==============================================================================
; AVR USART Serial Interface - Portfolio Refined Version
;
; Target: ATxmega128A1U
; Peripheral: USARTE0
; RX / TX: PE2 / PE3
; Baud: 115200
; Frame: 8 data bits, no parity, 1 stop bit
; System clk: 32 MHz internal oscillator
;
; Description:
; Implements bidirectional serial communication between the ATxmega128A1U
; and a PC terminal. The program prompts the user for text input, stores it
; in SRAM buffers, echoes it through USART, and displays the captured data.
;
; Portfolio refinements:
; - Reorganized comments and constants for readability
; - Added bounded string input to prevent SRAM buffer overflow
; - Improved backspace handling at the start of an empty buffer
; - Preserved the original program behavior and register-level USART control
;==============================================================================
.include "ATxmega128A1Udef.inc"
;------------------------------------------------------------------------------
; Constants
;------------------------------------------------------------------------------
.equ ENTER = 0x0D
.equ BACKSPACE = 0x08
.equ SPACE = 0x20
.equ YN_MAX = 3 ; 4-byte buffer: up to 3 chars + null terminator
.equ UNI_MAX = 39 ; 40-byte buffer: up to 39 chars + null terminator
.equ CITY_MAX = 39 ; 40-byte buffer: up to 39 chars + null terminator
;------------------------------------------------------------------------------
; SRAM buffers
;------------------------------------------------------------------------------
.dseg
.org 0x2000
ynBuf: .byte 4
uniBuf: .byte 40
cityBuf: .byte 40
;------------------------------------------------------------------------------
; Program memory / reset vector
;------------------------------------------------------------------------------
.cseg
.org 0x0000
rjmp START
.org 0x00F6
;==============================================================================
; START
;==============================================================================
START:
; Initialize stack pointer
ldi r16, low(RAMEND)
out CPU_SPL, r16
ldi r16, high(RAMEND)
out CPU_SPH, r16
; Configure the CPU for the 32 MHz internal oscillator
rcall setCPUClkto32Mwith32MIntOsc
; Configure USARTE0 for 115200 baud, 8-N-1
rcall initUSARTE0
;==============================================================================
; MAIN APPLICATION
;==============================================================================
MAIN:
; Ask whether the user wants to continue
ldi ZL, low(msg1 << 1)
ldi ZH, high(msg1 << 1)
ldi r16, 1
rcall putsUSARTE0
rcall newline
READ_YN:
; Read the response into ynBuf
ldi XL, low(ynBuf)
ldi XH, high(ynBuf)
ldi r18, YN_MAX
rcall getsUSARTE0
rcall newline
; Evaluate the first character
lds r22, ynBuf
; Empty input: ask again
cpi r22, 0
breq READ_YN
; n / N: stop
cpi r22, 'n'
breq NO_MORE
cpi r22, 'N'
breq NO_MORE
; y / Y: continue
cpi r22, 'y'
breq CONTINUE
cpi r22, 'Y'
breq CONTINUE
; Any other response: ask again
rjmp READ_YN
CONTINUE:
; Ask for university name
ldi ZL, low(msg2 << 1)
ldi ZH, high(msg2 << 1)
ldi r16, 1
rcall putsUSARTE0
ldi XL, low(uniBuf)
ldi XH, high(uniBuf)
ldi r18, UNI_MAX
rcall getsUSARTE0
rcall newline
; Display university name
ldi ZL, low(msg3 << 1)
ldi ZH, high(msg3 << 1)
ldi r16, 1
rcall putsUSARTE0
clr r16
ldi ZL, low(uniBuf)
ldi ZH, high(uniBuf)
rcall putsUSARTE0
rcall newline
; Ask for city
ldi ZL, low(msg4 << 1)
ldi ZH, high(msg4 << 1)
ldi r16, 1
rcall putsUSARTE0
ldi XL, low(cityBuf)
ldi XH, high(cityBuf)
ldi r18, CITY_MAX
rcall getsUSARTE0
rcall newline
; Display city
ldi ZL, low(msg5 << 1)
ldi ZH, high(msg5 << 1)
ldi r16, 1
rcall putsUSARTE0
clr r16
ldi ZL, low(cityBuf)
ldi ZH, high(cityBuf)
rcall putsUSARTE0
rcall newline
rjmp MAIN
NO_MORE:
ldi ZL, low(msgNoMore << 1)
ldi ZH, high(msgNoMore << 1)
ldi r16, 1
rcall putsUSARTE0
rcall newline
STOP:
rjmp STOP
;==============================================================================
; initUSARTE0
;
; Configures USARTE0 for:
; - PE2 = RX
; - PE3 = TX
; - 115200 baud
; - 8 data bits, no parity, 1 stop bit
;==============================================================================
initUSARTE0:
; PE3 output (TX); remaining PORTE pins, including PE2 RX, remain inputs
ldi r20, 0x08
sts PORTE_DIR, r20
; Baud-rate settings used by the original EE 235 implementation
ldi r20, 16
sts USARTE0_BAUDCTRLA, r20
clr r20
sts USARTE0_BAUDCTRLB, r20
sts USARTE0_CTRLA, r20
; Enable receiver and transmitter
ldi r20, 0x18
sts USARTE0_CTRLB, r20
; Asynchronous 8-bit, no parity, 1 stop bit
ldi r20, 0x03
sts USARTE0_CTRLC, r20
ret
;==============================================================================
; putchUSARTE0
;
; Input:
; r16 = character to transmit
;==============================================================================
putchUSARTE0:
WAIT_TX:
lds r20, USARTE0_STATUS
sbrs r20, USART_DREIF_bp
rjmp WAIT_TX
sts USARTE0_DATA, r16
ret
;==============================================================================
; putsUSARTE0
;
; Inputs:
; r16 = 1 -> string in program memory
; r16 = 0 -> string in data memory
; Z -> null-terminated string
;==============================================================================
putsUSARTE0:
cpi r16, 1
breq PSTRX
DSTRX:
ld r16, Z+
cpi r16, 0
breq DONEX
rcall putchUSARTE0
rjmp DSTRX
PSTRX:
lpm r16, Z+
cpi r16, 0
breq DONEX
rcall putchUSARTE0
rjmp PSTRX
DONEX:
ret
;==============================================================================
; newline
;
; Sends carriage return + line feed.
;==============================================================================
newline:
ldi r16, 0x0D
rcall putchUSARTE0
ldi r16, 0x0A
rcall putchUSARTE0
ret
;==============================================================================
; getchUSARTE0
;
; Output:
; r22 = received character
;==============================================================================
getchUSARTE0:
WAIT_RX:
lds r20, USARTE0_STATUS
sbrs r20, USART_RXCIF_bp
rjmp WAIT_RX
lds r22, USARTE0_DATA
ret
;==============================================================================
; getsUSARTE0
;
; Inputs:
; X -> destination buffer
; r18 -> maximum number of characters, excluding null terminator
;
; Behavior:
; - Reads until ENTER
; - Echoes accepted characters
; - Supports terminal backspace
; - Prevents writes beyond the destination buffer
; - Always null-terminates the resulting string
;==============================================================================
getsUSARTE0:
clr r19 ; character count = 0
READ_CHAR:
rcall getchUSARTE0
; ENTER terminates the string
cpi r22, ENTER
breq INPUT_DONE
; Handle backspace separately
cpi r22, BACKSPACE
breq HANDLE_BACKSPACE
; Ignore new characters after the buffer is full
cp r19, r18
brsh READ_CHAR
; Store and echo the received character
st X+, r22
inc r19
mov r16, r22
rcall putchUSARTE0
rjmp READ_CHAR
HANDLE_BACKSPACE:
; Nothing to erase if the buffer is already empty
tst r19
breq READ_CHAR
; Move the buffer pointer back and reduce the character count
sbiw XL, 1
dec r19
; Standard terminal erase sequence: BS, space, BS
ldi r16, BACKSPACE
rcall putchUSARTE0
ldi r16, SPACE
rcall putchUSARTE0
ldi r16, BACKSPACE
rcall putchUSARTE0
rjmp READ_CHAR
INPUT_DONE:
; Null-terminate the string
clr r20
st X, r20
ret
;==============================================================================
; setCPUClkto32Mwith32MIntOsc
;
; Enables the ATxmega128A1U 32 MHz internal oscillator and selects it as the
; system clock with no prescaling.
;==============================================================================
setCPUClkto32Mwith32MIntOsc:
; Enable the 32 MHz internal oscillator
lds r16, OSC_CTRL
ori r16, OSC_RC32MEN_bm
sts OSC_CTRL, r16
WAIT_32M:
; Wait until the oscillator is stable
lds r16, OSC_STATUS
sbrs r16, OSC_RC32MRDY_bp
rjmp WAIT_32M
; Protected write: select 32 MHz RC oscillator
ldi r16, CCP_IOREG_gc
sts CPU_CCP, r16
ldi r16, CLK_SCLKSEL_RC32M_gc
sts CLK_CTRL, r16
; Protected write: disable clock prescaling
ldi r16, CCP_IOREG_gc
sts CPU_CCP, r16
clr r16
sts CLK_PSCTRL, r16
ret
;==============================================================================
; Messages stored in program memory
;==============================================================================
msg1:
.db "Do you want to continue? y/n", 0
msg2:
.db "What is your university? ", 0
msg3:
.db "My university is ", 0
msg4:
.db "What is the city at which your university is located? ", 0
msg5:
.db "My university is located at ", 0
msgNoMore:
.db "No more", 0