OpenCores
URL https://opencores.org/ocsvn/light52/light52/trunk

Subversion Repositories light52

[/] [light52/] [trunk/] [test/] [irq_test/] [src/] [irq_test.a51] - Blame information for rev 18

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 18 ja_rd
; irq_test.a51 -- Basic interrupt service test.
2 3 ja_rd
;
3 18 ja_rd
; This program is only meant to work in the simulation test bench, because it
4 16 ja_rd
; requires the external interrupt inputs to be wired to the P1 output port.
5
; They are in the simulation test bench entity but not in the synthesizable
6
; demo top entity.
7
;
8 3 ja_rd
; Its purpose is to demonstrate the working of the interrupt service logic. No
9
; actual tests are performed (other than the co-simulation tests), only checks.
10
;
11 18 ja_rd
; This program makes the following assumptions about the MCU configuration:
12
;
13
; 1.- Port line P1.0 is wired to external input EXTINT0.0
14
; 2.- The timer prescaler is set to 20us@50MHz.
15
;
16
; NOTE: I am aware that this code is perfectly hideous and nearly useless as a
17
; test bench; it will have to do for the time being. I can seldom find quality
18
; time for this project...
19 3 ja_rd
;-------------------------------------------------------------------------------
20
 
21
        ; Include the definitions for the light52 derivative
22
        $nomod51
23
        $include (light52.mcu)
24
 
25
ext_irq_ctr     set     060h        ; Incremented by external irq routine
26 18 ja_rd
timer_irq_ctr   set     062h        ; Incremented by timer irq routine
27
uart_irq_ctr    set     063h        ; Incremented by uart irq routine
28
irq_test_code   set     064h        ; Selects the behavior of the irq routines
29 3 ja_rd
 
30
 
31
        ;-- Macros -------------------------------------------------------------
32
 
33
        ; putc: send character in A to console (UART)
34
putc    macro   character
35
        local   putc_loop
36
        mov     SBUF,character
37
putc_loop:
38 18 ja_rd
        ; This program will only ever run in the simulated environment, where
39
        ; UART transmission is instantaneous. No need to loop here.
40 3 ja_rd
        ;mov     a,SCON
41
        ;anl     a,#10h
42
        ;jz      putc_loop
43
        endm
44
 
45
        ; put_crlf: send CR+LF to console
46
put_crlf macro
47
        putc    #13
48
        putc    #10
49
        endm
50
 
51
 
52
        ;-- Reset & interrupt vectors ------------------------------------------
53
 
54
        org     00h
55
        ljmp    start               ;
56
        org     03h
57
        ljmp    irq_ext
58
        org     0bh
59
        ljmp    irq_timer
60
        org     13h
61
        ljmp    irq_wrong
62
        org     1bh
63
        ljmp    irq_wrong
64
        org     23h
65
        ljmp    irq_wrong
66
 
67
 
68
        ;-- Main test program --------------------------------------------------
69
        org     30h
70 18 ja_rd
 
71
        ; Place a few utility routines here at the start so they are reachable
72
        ; by CJNE.
73
 
74
        ; Did not get expected IRQ: print failure message and block.
75
fail_expected:
76
        mov     DPTR,#text3
77
        call    puts
78
        mov     IE,#00h
79
        ajmp    $
80
 
81
        ; Got unexpected IRQ: print failure message and block.
82
fail_unexpected:
83
        mov     DPTR,#text1
84
        call    puts
85
        mov     IE,#00h
86
        ajmp    $
87
 
88
 
89 3 ja_rd
start:
90
 
91 18 ja_rd
        mov     IE,#00              ; Disable all interrupts...
92
        mov     IP,#01              ; ...and set EXTINT as high-priority.
93
        mov     irq_test_code,#00h  ; Tell irq routines to only inc the counters
94 3 ja_rd
 
95
 
96
        ;---- External interrupt test --------------------------------------
97
 
98 18 ja_rd
        ; Basic interrupt test.
99
 
100 16 ja_rd
        ; We'll be asserting the external interrupt request line 0, making
101
        ; sure the interrupt enable flags work properly. No other interrupt
102
        ; will be asserted simultaneously or while in the interrupt service
103
        ; routine.
104
 
105 3 ja_rd
        ; Trigger external IRQ with IRQs disabled, it should be ignored.
106 16 ja_rd
        mov     P1,#01h             ; Assert external interrupt line 0...
107
        nop                         ; ...give the CPU some time to acknowledge
108
        nop                         ; the interrupt...
109 3 ja_rd
        nop
110 16 ja_rd
        mov     a,ext_irq_ctr       ; ...and then make sure it hasn't.
111 3 ja_rd
        cjne    a,#00,fail_unexpected
112
        setb    EXTINT0.0           ; Clear external IRQ flag
113
 
114
        ; Trigger timer IRQ with external IRQ enabled but global IE disabled
115 16 ja_rd
        mov     IE,#01h             ; Enable external interrupt...
116
        mov     P1,#01h             ; ...and assert interrupt line.
117
        nop                         ; Wait a little...
118 3 ja_rd
        nop
119
        nop
120 16 ja_rd
        mov     a,ext_irq_ctr       ; ...and make sure the interrupt was NOT
121
        cjne    a,#00,fail_unexpected   ; serviced.
122 18 ja_rd
        setb    EXTINT0.0           ; Clear external IRQ flag
123 3 ja_rd
 
124
        ; Trigger external IRQ with external and global IRQ enabled
125 16 ja_rd
        mov     P1,#00h             ; Clear the external interrupt line...
126
        mov     IE,#81h             ; ...before enabling interrupts globally.
127
        mov     ext_irq_ctr,#00     ; Reset the interrupt counter...
128
        mov     P1,#01h             ; ...and assert the external interrupt.
129
        nop                         ; Give it some time to be acknowledged...
130 3 ja_rd
        nop
131
        nop
132 16 ja_rd
        mov     a,ext_irq_ctr       ; ...and make sure it has been serviced.
133 3 ja_rd
        cjne    a,#01,fail_expected
134 18 ja_rd
        setb    EXTINT0.0           ; Clear external IRQ flag
135
 
136
        ; Somewhat less basic interrupt test: priorities.
137
 
138
        ; Here we are going to use the test code byte (irq_test_code) to tell
139
        ; the interrupt routines what we want them to do. Since we only use two
140
        ; interrupt routines to test everything, each routine has to perform
141
        ; a few different roles.
142
        ; Basically we want to make sure that the irq priority rules hold:
143
        ;
144
        ; A.-Nothing can interrupt a high priority irq routine.
145
        ; B.- Only a high-priority irq can interrupt a low-priority irq.
146
        ; C.- Simultaneous irqs get ordered by their vector number.
147
        ;
148
        ; Rule C will NOT be tested in this program; and rules B and A get only
149
        ; the most basic of basic tests.
150
 
151
        ; Run test 1: Trigger another external interrupt while serving an
152
        ; external interrupt. Since both are high-priority, the timer interrupt
153
        ; should be ignored.
154
        mov     irq_test_code,#01h
155
        mov     P1,#00h             ; Clear the external interrupt line...
156
        mov     IE,#83h             ; ...before enabling interrupts globally.
157
        mov     ext_irq_ctr,#00     ; Reset the interrupt counter...
158
        mov     P1,#01h             ; ...and assert the external interrupt.
159
        nop                         ; Give it some time to be acknowledged...
160
        nop
161
        mov     a,ext_irq_ctr       ; ...and make sure it has been serviced.
162
        cjne    a,#01,fail_expected
163
        setb    EXTINT0.0           ; Clear external IRQ flag
164 3 ja_rd
 
165 18 ja_rd
        ; Run test 2: Trigger Timer interrupt while serving an external
166
        ; interrupt. Since the Timer irq is low-priority, it should be ignored.
167
        mov     irq_test_code,#02h
168
        mov     P1,#00h             ; Clear the external interrupt line...
169
        mov     IE,#83h             ; ...before enabling interrupts globally.
170
        mov     ext_irq_ctr,#00     ; Reset the interrupt counter...
171
        mov     P1,#01h             ; ...and assert the external interrupt.
172
        nop                         ; Give it some time to be acknowledged...
173
        nop
174
        mov     a,ext_irq_ctr       ; ...and make sure it has been serviced.
175
        cjne    a,#01,fail_expected
176
        setb    EXTINT0.0           ; Clear external IRQ flag
177
 
178
        ; Run test 3: Trigger interrupts within the timer interrupt service
179
        ; routine.
180
        mov     irq_test_code,#03h
181
        mov     timer_irq_ctr,#00h
182
        mov     P1,#00h             ; Clear the external interrupt line...
183
        mov     IE,#83h             ; ...before enabling interrupts globally.
184
        mov     ext_irq_ctr,#00     ; Reset the interrupt counter...
185
        mov     TSTAT,#01           ; Stop timer and clear timer interrupt...
186
        mov     TH,#00h             ; ...set counter = 000h...
187
        mov     TL,#00h             ;
188
        mov     TCH,#00h            ; ...and set Compare register = 0001h...
189
        mov     TCL,#01h            ;
190
        mov     TSTAT,#030h         ; ...then start counting.
191
 
192
        mov     r1,#95              ; Wait for the timer IRQ to trigger...
193
loop_001:
194
        nop
195
        nop
196
        nop
197
        nop
198
        nop
199
        nop
200
        nop
201
        nop
202
        djnz    r1,loop_001         ; ...then make sure the timer irq has
203
        mov     a,timer_irq_ctr     ; been triggered.
204
        cjne    a,#01h,fail_expected_irq_bridge
205
 
206 3 ja_rd
        ; End of irq test, print message and continue
207
        mov     DPTR,#text2
208
        call    puts
209
 
210
        ;---- Timer test ---------------------------------------------------
211 16 ja_rd
        ; Assume the prescaler is set for a 20us count period.
212 3 ja_rd
 
213 16 ja_rd
        ; All we will do here is make sure the counter changes at the right
214
        ; time, i.e. 20us after being started. We will NOT test the full
215
        ; functionality of the timer (not in this version of the test).
216 3 ja_rd
 
217 18 ja_rd
        ; Note that the irq tests above already assume the timer works... this
218
        ; test is somewhat redundant.
219
 
220 16 ja_rd
        mov     IE,#000h            ; Disable all interrupts...
221
                                    ; ...and put timer in
222
        mov     TSTAT,#00           ; Stop timer...
223
        mov     TH,#00              ; ...set counter = 0...
224
        mov     TL,#00              ;
225
        mov     TCH,#0c3h           ; ...and set Compare register = 50000.
226
        mov     TCL,#050h           ; (50000 counts = 1 second)
227
        mov     TSTAT,#030h         ; Start counting.
228 3 ja_rd
 
229
        ; Ok, now wait for a little less than 20us and make sure TH:TL has not
230
        ; changed yet.
231
        mov     r0,#95              ; We need to wait for 950 clock cycles...
232
loop0:                              ; ...and this is a 10-clock loop
233
        nop
234
        djnz    r0,loop0
235
        mov     a,TH
236
        cjne    a,#000h,fail_timer_error
237
        mov     a,TL
238
        cjne    a,#000h,fail_timer_error
239
 
240
        ; Now wait for another 100 clock cycles and make sure TH:TL has already
241
        ; changed.
242
        mov     r0,#10              ; We need to wait for 100 clock cycles...
243
loop1:                              ; ...and this is a 10-clock loop
244
        nop
245
        djnz    r0,loop1
246
        mov     a,TH
247
        cjne    a,#000h,fail_timer_error
248
        mov     a,TL
249
        cjne    a,#001h,fail_timer_error
250
 
251
        ; End of timer test, print message and continue
252
        mov     DPTR,#text5
253
        call    puts
254
 
255
        ;-- End of test program, enter single-instruction endless loop
256
quit:   ajmp    $
257
 
258 18 ja_rd
fail_expected_irq_bridge:
259
        jmp     fail_expected_irq
260 3 ja_rd
 
261
fail_timer_error:
262
        mov     DPTR,#text4
263
        call    puts
264
        mov     IE,#00h
265
        ajmp    $
266
 
267 16 ja_rd
        ; End of the test code. Now let's define a few utility routines.
268
 
269 3 ja_rd
;-- puts: output to UART a zero-terminated string at DPTR ----------------------
270
puts:
271
        mov     r0,#00h
272
puts_loop:
273
        mov     a,r0
274
        inc     r0
275
        movc    a,@a+DPTR
276
        jz      puts_done
277
 
278
        putc    a
279
        sjmp    puts_loop
280
puts_done:
281
        ret
282
 
283 18 ja_rd
;-- irq_ext: interrupt routine for external irq lines --------------------------
284 16 ja_rd
; Note we don't bother to preserve any registers.
285 3 ja_rd
irq_ext:
286
        mov     P1,#00h             ; Remove the external interrupt request
287
        mov     EXTINT0,#0ffh       ; Clear all external IRQ flags
288
        inc     ext_irq_ctr         ; Increment irq counter
289 18 ja_rd
        ; Ok, now check the test code byte to see what we have to do here.
290
        mov     a,irq_test_code
291
        cjne    a,#00h,irq_ext_0
292
 
293
        ; Test 0: Just increment irq counter (already done).
294 3 ja_rd
        mov     DPTR,#text0         ; Print IRQ message...
295
        call    puts
296
        reti                        ; ...and quit
297
 
298 18 ja_rd
irq_ext_0:
299
        cjne    a,#02h,irq_ext_1
300
        ; Test 2: Trigger timer interrupt while in the service routine.
301
        ; Verify that low-priority interrupts get ignored while in the service
302
        ; routine of a high-priority interrupt.
303
        mov     timer_irq_ctr,#00h
304
        mov     TSTAT,#01           ; Stop timer and clear timer interrupt...
305
        mov     TH,#00h             ; ...set counter = 000h...
306
        mov     TL,#00h             ;
307
        mov     TCH,#00h            ; ...and set Compare register = 0001h.
308
        mov     TCL,#01h            ;
309
        mov     IE,#82h             ; Enable timer interrupt...
310
        mov     TSTAT,#030h         ; ...and start counting.
311
 
312
        mov     r0,#95               ; Wait for the timer interrupt to trigger...
313
irq_ext_test0_loop0:
314
        nop
315
        nop
316
        nop
317
        nop
318
        nop
319
        nop
320
        nop
321
        nop
322
        djnz    r0,irq_ext_test0_loop0  ; ...the make sure the timer irq has
323
        mov     a,timer_irq_ctr         ; NOT triggered.
324
        cjne    a,#00h,fail_unexpected_irq
325
        reti
326
 
327
irq_ext_1:
328
        cjne    a,#01h,irq_ext_2
329
 
330
        ; Test 1: Trigger external interrupt while in the service routine.
331
        ; Verify that high-priority interrupts get ignored while in the service
332
        ; routine of another high-priority interrupt.
333
        mov     ext_irq_ctr,#00h
334
        mov     irq_test_code,#00h
335
        mov     IE,#81h                 ; ...enable the UART irq...
336
        mov     P1,#01h                 ; ...and trigger it
337
 
338
        mov     r0,#10                  ; Give time for the irq to trigger...
339
irq_ext_test2_loop0:
340
        nop
341
        djnz    r0,irq_ext_test2_loop0  ; ...the make sure the Timer irq has
342
        mov     a,ext_irq_ctr           ; NOT triggered.
343
        cjne    a,#00h,fail_unexpected_irq
344
        reti
345
 
346
irq_ext_2:
347
        ; Code byte irq_test_code not used; ignored.
348
        reti
349
 
350
 
351
;-- irq_timer: interrupt routine for timer -------------------------------------
352
; Note we don't bother to preserve any registers.
353 3 ja_rd
irq_timer:
354 18 ja_rd
        ; Check the test code to see what we have to do here.
355
        mov     a,irq_test_code
356
        cjne    a,#03,irq_timer_0
357
 
358
        ; Test code 3: interrupts within timer irq service routine.
359
 
360
        ; Trigger external interrupt within this irq service routine and make
361
        ; sure it gets serviced.
362
        mov     ext_irq_ctr,#00h
363
        mov     irq_test_code,#00h
364
        mov     IE,#81h                 ; ...enable the UART irq...
365
        mov     P1,#01h                 ; ...and trigger it
366
 
367
        mov     r0,#10                  ; Give time for the irq to trigger...
368
irq_timer_test3_loop0:
369
        nop
370
        djnz    r0,irq_timer_test3_loop0  ; ...the make sure the Timer irq has
371
        mov     a,ext_irq_ctr           ; NOT triggered.
372
        cjne    a,#01h,fail_expected_irq
373
 
374
        ; Ok, now re-trigger the timer interrupt within the timer service
375
        ; interrupt and make sure the new interrupt is not serviced.
376
        mov     irq_test_code,#00h
377
        mov     timer_irq_ctr,#00h
378
        mov     TSTAT,#01           ; Stop timer and clear timer interrupt...
379
        mov     TH,#00h             ; ...set counter = 000h...
380
        mov     TL,#00h             ;
381
        mov     TCH,#00h            ; ...and set Compare register = 0001h...
382
        mov     TCL,#01h            ;
383
        mov     TSTAT,#030h         ; ...then start counting.
384
 
385
        mov     r1,#95              ; Wait for the timer IRQ to trigger...
386
irq_timer_test3_loop1:
387
        nop
388
        nop
389
        nop
390
        nop
391
        nop
392
        nop
393
        nop
394
        nop
395
        djnz    r1,irq_timer_test3_loop1 ; ...then make sure the timer irq has
396
        mov     a,timer_irq_ctr     ; been ignored.
397
        cjne    a,#00h,fail_unexpected_irq
398
 
399
        inc     timer_irq_ctr       ; Increment timer interrupt counter...
400
        mov     TSTAT,#01           ; Stop timer and clear timer interrupt.
401
 
402
        reti
403
 
404
 
405
irq_timer_0:
406
        ; Test code 0: increment irq counter.
407
        ; Just increment the timer irq counter and quit.
408
        inc     timer_irq_ctr       ; Increment timer interrupt counter...
409
        mov     TSTAT,#01           ; Stop timer and clear timer interrupt.
410
        reti                        ; ...and quit.
411
 
412 3 ja_rd
irq_wrong:
413
        ajmp    irq_wrong
414
 
415 18 ja_rd
        ; Utility functions -- error messages to console, etc.
416
 
417
        ; Got unexpected IRQ: print failure message and block.
418
fail_unexpected_irq:
419
        mov     DPTR,#text1
420
        call    puts
421
        mov     IE,#00h
422
        ajmp    $
423
 
424
        ; Did not get expected IRQ: print failure message and block.
425
fail_expected_irq:
426
        mov     DPTR,#text3
427
        call    puts
428
        mov     IE,#00h
429
        ajmp    $
430
 
431 16 ja_rd
        ; End of the utility routines. Define constant data and we're done.
432 3 ja_rd
 
433
text0:  db      '',13,10,00h,00h
434
text1:  db      'Unexpected IRQ',13,10,00h,00h
435
text2:  db      'IRQ test finished, no errors',13,10,0
436
text3:  db      'Missing IRQ',13,10,0
437
text4:  db      'Timer error',13,10,0
438
text5:  db      'Timer test finished, no errors',13,10,0
439
 
440
        end

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.