Ich wollte mal die interrupt levels des AVR128 ausprobieren. Da bin ich auf etwas gestossen was mich etwas stutzig macht. Ich habe da eine Subroutine die kommuniziert mit einer interrupt routine über einen Ring-Buffer. Diese sub-routine disabled natürlich immer die interrupts wenn sie etwas in den Ring-Buffer schreibt und die Pointer nachführen muss. Bis jetzt habe ich diese Subroutine mit "reti" abgeschlossen. Das funktioniert auf dem AVR128 nicht mehr. Erst als ich das reti durch ein sei und ret ersetzt habe funktioniert es. Und bevor ich da mit dem INTLVL1 beginne, wie ist das mit den beiden interrupt levels und dem I-Flag im SREG? Wie spielt das mit den LVL1EX und LVL0EX Flags im CPUINT_STATUS Register zusammen? Sehe ich das richtig, dass der Trick mit RETI das I-Flag nicht mehr setzt sondern nur diese LVL0/1EX Flags zurücksetzt und man das I-Flag nur noch mit SEI und CLI manipulieren sollte?
1 | serout_0: |
2 | push zl |
3 | push zh |
4 | serout_0wait: |
5 | cli |
6 | lds zl, tx0cnt ;;; Get number of characters in buffer |
7 | inc zl ;;; We want to add a character |
8 | brne serout_0nowait ;;; Not full, so we will not wait |
9 | ldi zl, low(serout0) ;;; |
10 | ldi zh, high(serout0) ;;; |
11 | call block ;;; |
12 | rjmp serout_0wait ; Then wait until there is room |
13 | |
14 | serout_0nowait: |
15 | sts tx0cnt, zl ;;; There is space in ring buffer |
16 | lds zl, tx0inptr ;;; Get input pointer |
17 | inc zl ;;; |
18 | sts tx0inptr, zl ;;; Update input pointer |
19 | clr zh ;;; |
20 | subi zl, low(-tx0ring) ;;; |
21 | sbci zh, high(-tx0ring) ;;; |
22 | st Z, char ;;; |
23 | lds zl, USART3_CTRLA ;;; Activate the data register empty |
24 | sbr zl, USART_DREIE_bm ;;; interrupt so the ISR picks up the |
25 | sts USART3_CTRLA, zl ;;; queued character(s) |
26 | pop zh ;;; |
27 | pop zl ;;; |
28 | ; reti ;;;<<<< geht nicht |
29 | sei |
30 | ret |