[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Simulavr-devel] UART Interrupt and Timer problem
From: |
Jakob Schwendner |
Subject: |
Re: [Simulavr-devel] UART Interrupt and Timer problem |
Date: |
Sat, 14 May 2005 23:45:52 +1000 |
Hi Klaus,
oops, I am sorry I should have read the avr-libc section on interrupts
properly before posting the report. However, in the current state,
there still seems to be some problems with the UARTs (it could be me
again ofcourse). I have changed the INTERRUPT to a SIGNAL. The test is
meant to transmit 2 characters to the UART using interrupts.
The interrupt gets raised correctly when I enable the UDRIE in the
UCSRnB register.
What doesn't seem to work is the clearing of that same flag in the
interrupt code (using UCSR1B ^= _BV(UDRIE)). Even though the trace
states that the UDRIE is not set anymore, the interrupt keeps getting
raised again once the handler has finished.
Here is my code:
//----- Include Files ---------------------------------------------------------
#include <avr/io.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
#define F_CPU 16000000
#define UART1_BAUD 19200
typedef unsigned char u08;
//----- Begin Code ------------------------------------------------------------
void io_init(void);
void uart1_send(char *s, int size);
int main(void)
{
io_init();
while(1) {
char *s = "this is a test";
uart1_send( s, 2 );
// delay
int m = 20000;
while( m-- );
}
return 0;
}
void io_init() {
// set LED pins for output
DDRA = _BV(DDA2) | _BV(DDA4);
// set BAUD rate for UART1
UBRR1L = ((F_CPU+(UART1_BAUD * 8L))/(UART1_BAUD * 16L)-1);
UBRR1H = 0;
// init UART1
UCSR1B = _BV(TXEN);
// enable all interupts
sei();
}
char *tx_buf;
u08 tx_index;
u08 tx_size;
void uart1_send(char *s, int size) {
tx_buf = s;
tx_size = size;
tx_index = 0;
// enable UART data ready interrupt
UCSR1B |= _BV(UDRIE);
}
SIGNAL(SIG_UART1_DATA)
{
// send new data
UDR1 = tx_buf[tx_index++];
if( tx_index >= tx_size ) {
// disable data ready interrupt
UCSR1B ^= _BV(UDRIE);
}
}
On 5/12/05, Klaus Rudolph <address@hidden> wrote:
> Hi Jakob,
>
> great that we have found such a good tester!
>
> > Similar problem,
> I donĀ“t believe :-)
>
> > different interrupt. UART_DATA_READY is according to
> > the data-sheet meant to stay on until switched off.
> Yes! Thats seems to be your problem :-)
>
> > However in my
> > sample code (attached below) it seems that the interrupt code body
> > doesn't even get called when an interrupt is raised,
> the irq vector is called! Look at your timestamp: 16058
> you are running in code with symbol __vector_31 which is your INTERRUPT
> routine. That is correct.
>
>
> > as a few cycles
> > later another one is raised again. (and so on).
> That seems to be OK. The first thing you do is to enable the interrupt
> again -> SEI instruction, the UDR is still set and also UDRIE is set.
> This three points mean-> start a interrupt. And this is done.
>
> I think you should not write
>
> INTERRUPT(SIG_UART1_DATA)
> please use
> SIGNAL(SIG_UART1_DATA)
> instead. This will not activate the interrupts before ending your
> interrupt handler.
>
>
> > Also the program
> > generates a "Not allowed to write to Pin! Read-Only!" error. Don't
> > know where that comes from. Here is the trace:
> >
>
> Thats really simple :-) You are running a interrupt routine and the
> actual PC is saved on stack. After entering the ISR (Interrupt Service
> Routine) you enable the next interrupt but not leave the ISR. You
> pushing a lot of PCs to stack and the lower RAM address space is
> the io register bank. And one of the registers you are writing
> is one of the pin registers. This will throw the message.
> After that you are also crashing the registers and so on.
>
> Seems that there is only a bug in the test :-). If the behaviour is
> not like the real hardware please send again a mail. But I think
> your testcode is wrong.
>
> But writing to an reserved register has crashed my simulator!
> Thanks for this, I found a very stupied bug which to fix needs updating
> nearly all files. I will do this the next days and put it together
> with the last changes to CVS. Thanks for that hint!
>
> Thanks
> Klaus
>
>
> > 15996 ../avrtest/avrtest.elf 0x012a: __vector_31+0x2
> > IRQ DETECTED: VectorAddr: 62../avrtest/avrtest.elf IrqSystem:
> > IrqHandlerStarted Vec: 31
> > IRAM[0x10fc,,__bss_end,_end+0xfe8]=0x95 SP=0x10fb
> > IRAM[0x10fb,,__bss_end,_end+0xfe7]=0x00 SP=0x10fa
> > 16058 ../avrtest/avrtest.elf 0x007c: __SREG__,__SP_H__+0x1f
> > CPU-waitstate
> > 16120 ../avrtest/avrtest.elf 0x007c: __SREG__,__SP_H__+0x1f
> > CPU-waitstate
> > 16182 ../avrtest/avrtest.elf 0x007c: __SREG__,__SP_H__+0x1f
> > CPU-waitstate
> > 16244 ../avrtest/avrtest.elf 0x007c: __SREG__,__SP_H__+0x1f
> > JMP 128f0 __stack+0x8bf9
> > 16306 ../avrtest/avrtest.elf 0x0126: __vector_31
> > CPU-waitstate
> > 16368 ../avrtest/avrtest.elf 0x0126: __vector_31
> > CPU-waitstate
> > 16430 ../avrtest/avrtest.elf 0x0126: __vector_31
> > SEI SREG=[I-------]
> > 16492 ../avrtest/avrtest.elf 0x0128: __vector_31+0x1
> > PUSH R1 IRAM[0x10fa,,__bss_end,_end+0xfe6]=0x00 SP=0x10f9
> > 16554 ../avrtest/avrtest.elf 0x012a: __vector_31+0x2
> > CPU-waitstate
> > 16616 ../avrtest/avrtest.elf 0x012a: __vector_31+0x2
> > IRQ DETECTED: VectorAddr: 62../avrtest/avrtest.elf IrqSystem:
> > IrqHandlerStarted Vec: 31
> > IRAM[0x10f9,,__bss_end,_end+0xfe5]=0x95 SP=0x10f8
> > IRAM[0x10f8,,__bss_end,_end+0xfe4]=0x00 SP=0x10f7
> > [...]
> >
> > and the code that produced it:
> >
> > //----- Include Files
> > ---------------------------------------------------------
> > #include <avr/io.h>
> > #include <avr/signal.h>
> > #include <avr/interrupt.h>
> >
> > #define F_CPU 16000000
> > #define UART1_BAUD 19200
> >
> > typedef unsigned char u08;
> >
> > //----- Begin Code
> > ------------------------------------------------------------
> >
> > void io_init(void);
> > void uart1_send(char *s, int size);
> >
> > int main(void)
> > {
> > io_init();
> >
> > while(1) {
> >
> > char *s = "this is a test";
> > uart1_send( s, 3 );
> >
> > // delay
> > int m = 20000;
> > while( m-- );
> > }
> >
> > return 0;
> > }
> >
> > void io_init() {
> > // set LED pins for output
> > DDRA = _BV(DDA2) | _BV(DDA4);
> >
> > // set BAUD rate for UART1
> > UBRR1L = ((F_CPU+(UART1_BAUD * 8L))/(UART1_BAUD * 16L)-1);
> > UBRR1H = 0;
> >
> > // init UART1
> > UCSR1B = _BV(TXEN);
> >
> > // enable all interupts
> > sei();
> > }
> >
> > char *tx_buf;
> > u08 tx_index;
> > u08 tx_size;
> >
> > void uart1_send(char *s, int size) {
> > tx_size = size;
> > tx_buf=s;
> > tx_index=0;
> >
> > // enable UART data ready interrupt
> > UCSR1B |= _BV(UDRIE);
> > }
> >
> > INTERRUPT(SIG_UART1_DATA)
> > {
> > // disable data ready interrupt
> > UCSR1B ^= _BV(UDRIE);
> >
> > // check for more data
> > if( tx_index < tx_size ) {
> > // enable data ready interrupt
> > UDR1 = tx_buf[tx_index++];
> > UCSR1B |= _BV(UDRIE);
> > }
> > }
> >
>
> --
> +++ Lassen Sie Ihren Gedanken freien Lauf... z.B. per FreeSMS +++
> GMX bietet bis zu 100 FreeSMS/Monat: http://www.gmx.net/de/go/mail
>