simulavr-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Simulavr-devel] UART Interrupt and Timer problem


From: Klaus Rudolph
Subject: Re: [Simulavr-devel] UART Interrupt and Timer problem
Date: Mon, 16 May 2005 20:09:29 +0200
User-agent: Mozilla/5.0 (X11; U; Linux i686; de-AT; rv:1.6) Gecko/20040114

Hi Jakob,


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.
Yes, also a bug. Fixed in CVS.

Please update from cvs, I changed such a lot of things....
Please report all build problems if you got some. The commit in cvs was a bit
strange....

Thanks a lot for your work!

Bye
Klaus



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









reply via email to

[Prev in Thread] Current Thread [Next in Thread]