Hallo Leute,
ich arbeite gerade mit dem Eval-Kit SAM3U-EK von Atmel. Der darauf
verbaute ARM ATSAM3U4E ärgert mich zur Zeit ein wenig.
Konkret geht es mir um die USART Schnittstelle. Ich bin bereits soweit
das ich problemlos senden kann, nur das Empfangen(per Interrupt)
funktioniert nicht richtig.
Aber hier erstmal der Init Code der USART1:
1 | void USARTInit(void)
|
2 | {
|
3 |
|
4 | /*1. init PIOA&USART1*/
|
5 | //enable necessary peripheral clocks
|
6 | PMC->PMC_PCER = (0x1 << ID_PIOA )| //enable PIOA clock
|
7 | (0x1 << ID_USART1); //enable USART1 clock
|
8 |
|
9 | /*2. configure PIOA*/
|
10 | //disable pin charge interrupt for usart pins
|
11 | PIOA->PIO_IDR = (PIO_PA21A_RXD1 | PIO_PA20A_TXD1);
|
12 |
|
13 | //disable pullups for usart pins
|
14 | PIOA->PIO_PUDR = (PIO_PA21A_RXD1 | PIO_PA20A_TXD1);
|
15 |
|
16 | //disable pio controller for usart pins(enables peripheral control of the pin)
|
17 | PIOA->PIO_PDR = (PIO_PA21A_RXD1 | PIO_PA20A_TXD1);
|
18 |
|
19 | //select corresponding peripheral for usart1
|
20 | PIOA->PIO_ABSR &= ~(PIO_PA21A_RXD1 | PIO_PA20A_TXD1);
|
21 |
|
22 | /*3. configure USART1*/
|
23 | //reset receiver and transmitter
|
24 | USART1->US_CR = US_CR_RSTRX | US_CR_RSTTX;
|
25 |
|
26 | //disable all interrupts
|
27 | USART1->US_IDR = 0xFFFFFFFF;
|
28 |
|
29 | //set needed interrupts
|
30 | USART1->US_IER = (1<<3);
|
31 |
|
32 | //set baut rate factor
|
33 | USART1->US_BRGR = BAUD(9600);
|
34 |
|
35 | //set usart mode
|
36 | USART1->US_MR = (0x0 << 0)| //normal mode
|
37 | (0x0 << 4)| //use main clock
|
38 | (0x3 << 6)| //character length: 8 bits
|
39 | (0x4 << 9)| //no parity
|
40 | (0x0 << 12)| //1 stop bit
|
41 | (0x0 << 14); //normal mode: the USART channel operates as an RX/TX USART
|
42 |
|
43 | //disbale peripheral DMA controller for transmitter/receiver
|
44 | USART1->US_PTCR = US_PTCR_RXTDIS | US_PTCR_TXTDIS;
|
45 |
|
46 | //enable receiver and transmitter
|
47 | USART1->US_CR = US_CR_RXEN | US_CR_TXEN;
|
48 |
|
49 | /*4. activate interrupts*/
|
50 | //set interrupt values
|
51 | NVIC_DisableIRQ(USART1_IRQn);
|
52 | NVIC_ClearPendingIRQ(USART1_IRQn);
|
53 | NVIC_SetPriority(USART1_IRQn,5);
|
54 | NVIC_EnableIRQ(USART1_IRQn);
|
55 |
|
56 | };
|
hier der Interrupt Handler Code:
1 | void USART1_IRQHandler(void)
|
2 | {
|
3 | //init/vars
|
4 | unsigned int InterruptStatus;
|
5 |
|
6 | //read out interrupt stat
|
7 | InterruptStatus = USART1->US_CSR;
|
8 |
|
9 | //send back(test command)
|
10 | //SER_putChar(USART1->US_RHR);
|
11 |
|
12 | //reset status bits
|
13 | USART1->US_CR = US_CR_RSTSTA;
|
14 |
|
15 | //dummy action, to prevent compiler optimation
|
16 | InterruptStatus++;
|
17 | };
|
und noch der Vollständigkeit halber:
1 | void SER_putChar(char c)
|
2 | {
|
3 | while (!(USART1->US_CSR & US_CSR_TXRDY)){};
|
4 |
|
5 | USART1->US_THR = c;
|
6 | };
|
Problem ist, dass der sofort in den Interrupt springt wenn ich die USART
aktiviere, und da nie wieder raus kommt.
(getestet mit dem 'SER_putChar' Kommando, er schickt mir in einer
Endlosschleife das Zeichen zurück was zuletzt empfangen wurde)
Andere ISRs (zb Timer/RTC/...) funktionieren einwandfrei und werden
"beendet" sobald ich das jeweilig zugehörige Status Register lese.
Wie komme ich aus der USART1 ISR wieder raus?
Gruß,
Mark