avr-gcc-list
[Top][All Lists]
Advanced

[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




reply via email to

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