[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [avr-gcc-list] Is this a Stack problem?
From: |
Eric Fu |
Subject: |
Re: [avr-gcc-list] Is this a Stack problem? |
Date: |
Wed, 21 Jan 2004 07:18:55 +1100 |
Hi All,
Thanks for the help.
My code is for a software half duplex UART (interrupt driven). Let's focus
on the Transmit first. It roughly runs as follows:
TMR0 Compare match INT is used to generate a time period equivalent to the
bit rate.
COM setup: 1 Start bit, 8 data bits, 1 Stop bit.
A ring buffer is used.
In the main loop, ' TransmitString1(START_MSG); ' is called, (byte
START_MSG[] = "\rHello Eric";)
In the ISR, it checks if this is Receive or Transmit. It should go for
Transmit. (simulation shows correctly)
At Transmit section, all 10 bits in a frame get transmitted, 1 bit per
entry.
I will focus on the ISR today to see what went wrong there. According to AVR
LIB manual, using INTERRUPT () will save all the registers used in the ISR.
But I did save SREG in some places just to be sure.
The ISR is as follows: (INT0 external interrupt for Receiving is not
included)
INTERRUPT(SIG_OUTPUT_COMPARE0) //timer0 compare match INT
{
byte temp=SREG;
++Tmr0Cntr;
if(Tmr0Cntr == 1) // this is to test if this ISR is enterred or not
{
Tmr0Cntr = 0;
if(TESTBIT(PORTD, LEDA) )
CLRBIT(PORTD, LEDA);
else
SETBIT(PORTD, LEDA);
}
// the real code starts here
if( !(TESTBIT(UART1FLAG,TD)) ) // if receiving mode, do here
{
if( !(TESTBIT(UART1FLAG,START_BIT)) )
{
SETBIT(UART1FLAG, START_BIT);
ONE_BIT_TMR0;
}
if( BIT_CNTR<8 )
{
if( TESTBIT(PIND,RXD1) )
UDR1 |= 1<<BIT_CNTR++;
}
else
{
if( (TESTBIT(PIND,RXD1)) ) //if not STOP BIT, something wrong, skip here
{
byte data;
byte TmpHead;
/* Read the received data */
data = UDR1;
/* Calculate buffer index */
TmpHead = ( uart1.RxHead + 1 ) & RX_BUFFER_MASK;
uart1.RxHead = TmpHead; /* Store new index */
if ( TmpHead == uart1.RxTail )
{
/* ERROR! Receive buffer overflow */
}
uart1.RxBuf[TmpHead] = data; /* Store received data in buffer */
SETBIT(UART1FLAG,RDR);
}
else
{// receive again
STOP_TMR0;
SETBIT(GIFR,INTF0); // clear INTF0 flag
SETBIT(GICR,INT0); // enable INT0, make it ready for the next receive
}
}
}
else
{// transmitting mode
byte TmpTail;
/* Check if all data is transmitted */
if ( uart1.TxHead != uart1.TxTail )
{
if( !TESTBIT(UART1FLAG,START_BIT) )
{
SETBIT(UART1FLAG, START_BIT);
CLRBIT(PORTD,TXD1); // Start bit
TmpTail = ( uart1.TxTail + 1 ) & TX_BUFFER_MASK;
UDR1 = uart1.TxBuf[TmpTail]; /* Start transmition */
SREG=temp;
}
else
{
if(BIT_CNTR<8)
{
if( (UDR1 & _BV(BIT_CNTR)) )
SETBIT(PORTD,TXD1); //
else
CLRBIT(PORTD,TXD1); //
++BIT_CNTR;
SREG=temp;
}
else if(BIT_CNTR++<9)
{
SETBIT(PORTD,TXD1); //Stop bit
SREG=temp;
}
else
{
STOP_TMR0;
SETBIT(UART1FLAG,TDC);
TmpTail = ( uart1.TxTail + 1 ) & TX_BUFFER_MASK;
uart1.TxTail = TmpTail; /* Store new index */
SREG=temp;
}
}
}
else
STOP_TMR0;
SREG=temp;
}
}
Thanks.
Eric Fu
----- Original Message -----
From: "Lorne Gutz" <address@hidden>
To: "Eric Fu" <address@hidden>; <address@hidden>
Sent: Wednesday, January 21, 2004 1:41 AM
Subject: Re: [avr-gcc-list] Is this a Stack problem?
If you check you will find that there are 2 interrupts involved
with the UART transmitt.
Basicly you must use one to enable the other when the
UART is ready to except another character.
>From what you have stated below I believe that your code
has rammed 11 characters into the UART before anything
ever gets sent. You could easly have a stack overflow if
your code is reenterand, and interrupt gets enabled inside
your ISR.
cheers
Lorne
On Monday 19 January 2004 16:41, Eric Fu wrote:
> Hi All,
>
> I'm writing a test code to implement a SW half duplex interrupt UART with
> ATmega16 / STK500. The code passes the compiler (modified from a
successful
> HW UART code). However, it doesn't work. It couldn't transmit anything,
> nothing happens at the transmit pin. The degugging I did shows the
> following: a.. The timer interrupt routine has been entered 22 times
before
> it stops. And it is repeatable. Note: the timer period is defined same as
> bit rate. It supposed to transmit 11 ASCII code, equivalent to 220 timer
> interrupt entries. b.. If I run the Simulator in AVR Studio 4.08 in step
> mode, it could transmit the all the 11 characters, at least this is what I
> saw in the Simulator, and the transmit pin behaves as expected (in the
> Simulator) c.. If I run in continuos mode with a breakpoint set
immediately
> after the 11 characters, it took 28 Secs to complete, however, it seems it
> does it connectedly. As I don't have a emulator at the moment, it is hard
> for me to find the fault.
>
> Could it be Stack problem? If it is, how to fix it?
> The compile message for code size is
>
> Size after:
> RF001.elf :
> section size addr
> .text 1622 0
> .data 12 8388704
> .bss 137 8388716
> .noinit 0 8388853
> .eeprom 0 8454144
> .stab 7212 0
> .stabstr 3158 0
> Total 12141
>
> I'm not sure what stab and stabstr are. Are they supposed to be like that?
>
> Thanks
>
> Eric Fu
>
> _______________________________________________
> avr-gcc-list mailing list
> address@hidden
> http://www.avr1.org/mailman/listinfo/avr-gcc-list