Hallo Community,
versuche grad die UART0 eines LPC2138 mit Interrupts in Betrieb zu
nehmen, und obwohl mir das schon mal mit einem LPC2129 unter UART0
erfolgreich gelungen ist, krieg ich's nicht hin...
Umgebung: Yagarto (Eclipse, arm-elf-gcc, arm-elf-gdb, OpenOCD und
Amontec JTAGkey).
Kann mir jemand kurz sagen, was die typischen Fehler sind?
---
Ich nutze IRQ.
Im Startup Code daher:
1 | _vectors:
|
2 | ldr pc, ResetAddr // Reset
|
3 | ldr pc, UndefAddr // Undefined instruction
|
4 | ldr pc, SWIAddr // Software interrupt
|
5 | ldr pc, PAbortAddr // Prefetch abort
|
6 | ldr pc, DAbortAddr // Data abort
|
7 | ldr pc, ReservedAddr // Reserved
|
8 | ldr pc, [pc, #-0xFF0] // IRQ interrupt: jump to whatever VICVectAddr points to
|
9 | ldr pc, FIQAddr // FIQ interrupt
|
VICVectAddr sollte von VicVectAddr0 geladen werden.
Code aus UART-Konfig:
1 | // Clear any pending interrupts / Disable interrupts
|
2 | VICINTENCLR = MASK_VIC_UART0;
|
3 |
|
4 | // Make UART 0 Interrupt an IRQ Interrupt
|
5 | VICINTSELECT &= (~MASK_VIC_UART0);
|
6 |
|
7 | // Register UART ISR as vectored interrupt:
|
8 | // Write IRQ Handler address to VICVECTRADDRx,
|
9 | // write IRQ Channel to VICVECTCNTLx
|
10 | VICVECTADDR0 = (DWORD)IoUart0Isr;
|
11 | VICVECTCNTL0 = (DWORD)(VIC_CHANNEL_UART0 | VICVECTCTRL_IRQENA);
|
12 |
|
13 | // Enable UART 0 Interrupt Source
|
14 | VICINTENABLE |= MASK_VIC_UART0;
|
15 |
|
16 | // Enable specific interrupts:
|
17 | // Receive Data Available (RDA) und
|
18 | // Transmit Hold Register Empty (THRE) Interrupt
|
19 | U0IER |= (MASK_UXIER_RDA | MASK_UXIER_THRE);
|
Und ISR:
1 | void __attribute__ ((interrupt ("IRQ"))) IoUart0Isr (void) {
|
2 |
|
3 | ... // Code weggelassen
|
4 |
|
5 | // Clear UART Interrupt by reading U0IIR
|
6 | counter = U0IIR;
|
7 |
|
8 | // Acknowledge IRQ
|
9 | VICVECTADDR = 0;
|
10 | }
|
Das ganze läuft im RAM. Dazu habe ich das Memory Remapping per Debugger
eingestellt (Skript für GDB):
monitor mww 0xE01FC040 0x02
Allerdings liefert mit obiges immer eine Fehlermeldung, scheint aber
trotzdem zu funktionieren, denn wenn ich es weglasse, geht gar kein
Debuggen, mit o.g. Befehl geht debuggen, aber im Falle eines Interrupts
sprint das Ding sonst wohin...