This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Urgent: Problem in Timer interrupt program using AT91SAM7SE512-EK]

Dear Friends,
I am using the Keil uvision3 ARM version,I have developed a new project Timer interrupt program.(downloaded from Atmel website).
In compilation of the code has no problem,after i downloaded into the Flash using ULink2 ARM debugger.

When i RUN the code,there is no output,means getting hang(only once go inside the interrupt loop,not return back ).

Hereby i have attached the source code for your reference.

Could you please advice on this problem.

The source code is
// ----------------------------------------------------------------------------
// File Name : interrupt_timer.c
// Object : Timer interrupt management
// : Use AT91B_LED1 & AT91B_LED2 for status interrupt
// Creation : JPP 11-May-2006
// ----------------------------------------------------------------------------

// Include Standard LIB files
#include "include_files.h"

//* Global variable int count_timer0_interrupt; int count_timer1_interrupt;

#define TIMER0_INTERRUPT_LEVEL 1
#define TIMER1_INTERRUPT_LEVEL 7

/*-----------------*/
/* Clock Selection */
/*-----------------*/
#define TC_CLKS 0x7
#define TC_CLKS_MCK2 0x0
#define TC_CLKS_MCK8 0x1
#define TC_CLKS_MCK32 0x2
#define TC_CLKS_MCK128 0x3
#define TC_CLKS_MCK1024 0x4

//*------------------------- Internal Function --------------------------------
//*----------------------------------------------------------------------------
//* Function Name : AT91F_TC_Open
//* Object : Initialize Timer Counter Channel and enable is clock
//* Input Parameters : <tc_pt> = TC Channel Descriptor Pointer
//* <mode> = Timer Counter Mode
//* : <TimerId> = Timer peripheral ID definitions
//* Output Parameters : None
//*----------------------------------------------------------------------------
void AT91F_TC_Open ( AT91PS_TC TC_pt, unsigned int Mode, unsigned int TimerId)
//* Begin
{ unsigned int dummy;

//* First, enable the clock of the TIMER AT91F_PMC_EnablePeriphClock ( AT91C_BASE_PMC, 1<< TimerId ) ;

//* Disable the clock and the interrupts TC_pt->TC_CCR = AT91C_TC_CLKDIS ; TC_pt->TC_IDR = 0xFFFFFFFF ;

//* Clear status bit dummy = TC_pt->TC_SR; //* Suppress warning variable "dummy" was set but never used dummy = dummy; //* Set the Mode of the Timer Counter TC_pt->TC_CMR = Mode| AT91C_TC_CPCTRG ;

TC_pt->TC_RC= 0xB71B;//0x12F4; =(Time * MCK)/1024 //0x5B8D;//500Ms //* Enable the clock TC_pt->TC_CCR = (AT91C_TC_CLKEN | AT91C_TC_SWTRG ) ;
//* End
} //*------------------------- Interrupt Function -------------------------------

//*----------------------------------------------------------------------------
//* Function Name : timer0_c_irq_handler
//* Object : C handler interrupt function call by the interrupts
//* assembling routine
//* Output Parameters : increment count_timer0_interrupt
//*---------------------------------------------------------------------------- void timer0_c_irq_handler(void)
{ AT91PS_TC TC_pt = AT91C_BASE_TC0; unsigned int dummy; //* AcknowAT91B_LEDge interrupt status dummy = TC_pt->TC_SR; //* Suppress warning variable "dummy" was set but never used dummy = dummy; //count_timer0_interrupt++; //* Read the output state if ( (AT91F_PIO_GetInput(AT91C_BASE_PIOA) & LED1 ) == LED1 ) { AT91F_PIO_ClearOutput( AT91C_BASE_PIOA, LED1); } else { AT91F_PIO_SetOutput( AT91C_BASE_PIOA, LED1); } /*if ( (AT91F_PIO_GetInput(AT91C_BASE_PIOC) & HEARTBT_OUTPUT ) == HEARTBT_OUTPUT ) { AT91F_PIO_ClearOutput(AT91C_BASE_PIOC, HEARTBT_OUTPUT); } else { AT91F_PIO_SetOutput( AT91C_BASE_PIOC, HEARTBT_OUTPUT); } */
} //*----------------------------------------------------------------------------
//* Function Name : timer1_c_irq_handler
//* Object : C handler interrupt function call by the interrupts
//* assembling routine
//* Output Parameters : increment count_timer1_interrupt
//*----------------------------------------------------------------------------
// void timer1_c_irq_handler(void)
//{
// AT91PS_TC TC_pt = AT91C_BASE_TC1;
// unsigned int dummy; //* AcknowAT91B_LEDge interrupt status
// dummy = TC_pt->TC_SR; //* Suppress warning variable "dummy" was set but never used
// dummy = dummy;
// count_timer1_interrupt++;

//* Read the output state // if ( (AT91F_PIO_GetInput(AT91D_BASE_PIO_LED) & AT91B_LED2 ) == AT91B_LED2 ) // { // AT91F_PIO_ClearOutput( AT91D_BASE_PIO_LED, AT91B_LED2 ); // } else { // AT91F_PIO_SetOutput( AT91D_BASE_PIO_LED, AT91B_LED2 ); // }
//}
//*-------------------------- External Function -------------------------------

//*----------------------------------------------------------------------------
//* Function Name : timer_init
//* Object : Init timer counter
//* Input Parameters : none
//* Output Parameters : TRUE
//*----------------------------------------------------------------------------
void timer_init ( void )
//* Begin
{ //init the timer interrupt counter count_timer0_interrupt=0; count_timer1_interrupt=0;

//* Open timer0 AT91F_TC_Open(AT91C_BASE_TC0,TC_CLKS_MCK1024,AT91C_ID_TC0);

//* Open Timer 0 interrupt AT91F_AIC_ConfigureIt ( AT91C_BASE_AIC, AT91C_ID_TC0, TIMER0_INTERRUPT_LEVEL, AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, timer0_c_irq_handler); AT91C_BASE_TC0->TC_IER = AT91C_TC_CPCS; // IRQ enable CPC AT91F_AIC_EnableIt (AT91C_BASE_AIC, AT91C_ID_TC0);

//* Open timer1 //AT91F_TC_Open(AT91C_BASE_TC1,TC_CLKS_MCK128,AT91C_ID_TC1);

//* Open Timer 1 interrupt /*AT91F_AIC_ConfigureIt ( AT91C_BASE_AIC, AT91C_ID_TC1, TIMER1_INTERRUPT_LEVEL, AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, timer1_c_irq_handler); AT91C_BASE_TC1->TC_IER = AT91C_TC_CPCS; // IRQ enable CPC AT91F_AIC_EnableIt (AT91C_BASE_AIC, AT91C_ID_TC1);*/

//* Start timer0 AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG ;

//* Start timer1 // AT91C_BASE_TC1->TC_CCR = AT91C_TC_SWTRG ;

//* End
}

With Regards & Thanks, Murthy.R

Parents
  • Hi friend,

    Thanks for your reply,
    Actually this same source code is working prperly in IAR workbench Tool.
    In keil tool only giving the problem.
    i have downloaded this example source code from www.atmel.com/.../product_card.asp
    website.

    The problem is when i give the input to board,the receiver interrupt receive the data and transmit to the USART0.
    After that the program is getting hang.
    Means the control goes to receiver interrupt function only once and should not return from it.

    Please help me to rectify this problem.

    With regards,
    Murthy.R

Reply
  • Hi friend,

    Thanks for your reply,
    Actually this same source code is working prperly in IAR workbench Tool.
    In keil tool only giving the problem.
    i have downloaded this example source code from www.atmel.com/.../product_card.asp
    website.

    The problem is when i give the input to board,the receiver interrupt receive the data and transmit to the USART0.
    After that the program is getting hang.
    Means the control goes to receiver interrupt function only once and should not return from it.

    Please help me to rectify this problem.

    With regards,
    Murthy.R

Children
  • Why looking for IAR examples instead of Keil examples?

    Also, the code did not match the contents of the AT91SAM7SE512_IAR.zip file - that ISR do look as expected for a UART ISR.

    In a UART ISR, you send characters by putting them in the transmit register of the UART - you don't call a PutChar function, unless the PutChar function specifically inserts a character into another UART's transmit queue, for that UART's ISR to later pick up and send.

  • Hi friend,
    Thanks for your Reply.
    I am new to this AT91SAM7SE512.So please help me on this UART RXD interrupt problem.
    This is my UART0 initialization code.
    Do i have to modify anything in this code.Because if i give this line "AT91C_BASE_AIC->AIC_IECR = 0x1 << AT91C_ID_US0;"the program(blink one LED) is not working.When i disable this line the LED blinking is working.And also the Transmission is working good.

    Please advise me on this.

    #define AT91C_US_ASYNC_MODE ( AT91C_US_USMODE_NORMAL + \ 
                            AT91C_US_NBSTOP_1_BIT + \ 
                            AT91C_US_PAR_NONE + \ 
                            AT91C_US_CHRL_8_BITS + \ 
                            AT91C_US_CLKS_CLOCK )
    #define BAUD_VALUE(baud_rate) (((( MCK  / (baud_rate * 16)) * 10) % 10) < 5 ? \ 
                                                                                                            (MCK / (baud_rate * 16)) : \ 
                                                                                                            (MCK / (baud_rate * 16)) + 1  )
    
    
    
    void uart0Init(void)
    {
         // enable the clock of UART0
         AT91C_BASE_PMC->PMC_PCER = (1<<AT91C_ID_US0);
         // enable uart pins on PIO
         *AT91C_PIOA_PDR = AT91C_PA5_RXD0 | AT91C_PA6_TXD0;
         // select peripheral connection
         *AT91C_PIOA_ASR = AT91C_PA5_RXD0 | AT91C_PA6_TXD0;
         // disable I/O pullup
          *AT91C_PIOA_PPUDR = AT91C_PA5_RXD0;
         // reset the UART
         AT91C_BASE_US0->US_CR = AT91C_US_RSTRX | AT91C_US_RSTTX | AT91C_US_RXDIS |AT91C_US_TXDIS;
         // set serial line mode
         AT91C_BASE_US0->US_MR = AT91C_US_ASYNC_MODE;
         // set the baud rate
         AT91C_BASE_US0->US_BRGR = BAUD_VALUE(9600);
         // enable the uart
        AT91C_BASE_US0->US_CR = AT91C_US_RXEN | AT91C_US_TXEN;
    
            // enable reaction on different interrupt sources
            AT91C_BASE_US0->US_IDR = 0xFFFFFFFF;
            AT91C_BASE_US0->US_IER = AT91C_US_RXRDY;
    
            // configure USART0 interrupt
            AT91C_BASE_AIC->AIC_IDCR = 0x1 << AT91C_ID_US0;
            AT91C_BASE_AIC->AIC_SVR[AT91C_ID_US0] = (unsigned long) Usart0Int;
            AT91C_BASE_AIC->AIC_SMR[AT91C_ID_US0] = AT91C_AIC_SRCTYPE_HIGH_LEVEL |2;
            AT91C_BASE_AIC->AIC_IECR = 0x1 << AT91C_ID_US0;
    
    
    }
    
    

    With Regards and Thanks

    Murthy.R

  • Because if i give this line "AT91C_BASE_AIC->AIC_IECR = 0x1 << AT91C_ID_US0;"the program(blink one LED) is not working.

    This line actually "enables" the USART0 interrupt. If your program does not work when you do that, then your USART0 interrupt service routine is the most likely culprit.

  • Please help me to rectify this problem

    With regards
    Murthy.R

  • You posted a link to the Atmel site, but haven't mentioned exactly what code you decided to try to use.

    Your posted code for the UART ISR does not look anything like the example code available - neither for IAR nor for Keil.

    Where did you get it?

    How have you modified it?

    I did look at the code in "AT91SAM7SE512_IAR.zip" and "AT91SAM7SE512_KEIL.zip", and both contains UART ISR code that looks like I would expect them to. Your posted code looks very much like a criss/cross between polled and interrupt-driven operation with their GetChar and PutChar references.

    I commented on it earlier, but didn't get a response about it.

  • hi,
    i have downloaded the "AT91SAM7SE512_KEIL.zip"code.
    i took a "AT91SAM7SE-Interrupt" as a example code and created a new project(using keil version 3.53).
    Then I tried that code,the transmission has no problem,
    but RXD is not working.

    Those putchar and getchar are used ISR in that example code.

    After that i have developed a new code without using the APIs(what i posted here).

    Please advise me on this.

    With regards,
    Murthy.R

  • Your code is not identical to the one you quotes.
    This is the code on the Atmel site:

    void Usart_c_irq_handler(void)
    {
            AT91PS_USART USART_pt = AT91C_BASE_US0;
            unsigned int status;
            //* get Usart status register
            status = USART_pt->US_CSR;
            if ( status & AT91C_US_RXRDY){
                    //* Get byte and send
                    AT91F_US_PutChar (USART_pt, AT91F_US_GetChar(USART_pt));
            }
    
            if ( status & AT91C_US_OVRE) {
                    //* clear US_RXRDY
                     AT91F_US_GetChar(USART_pt);
                     AT91F_US_PutChar (USART_pt, 'O');
            }
    
            //* Check error
            if ( status & AT91C_US_PARE) {
                     AT91F_US_PutChar (USART_pt, 'P');
            }
    
            if ( status & AT91C_US_FRAME) {
                     AT91F_US_PutChar (USART_pt, 'F');
            }
    
            if ( status & AT91C_US_TIMEOUT){
                    USART_pt->US_CR = AT91C_US_STTTO;
                     AT91F_US_PutChar (USART_pt, 'T');
            }
    
            //* Reset the satus bit
             USART_pt->US_CR = AT91C_US_RSTSTA;
    }
    


    It uses a USART_pt pointer, and doesn't have any acknowledge code for the interrupt. Also, maybe you should reset the status bit before acknowledning the interrupt?

    Another thing - there is different example code for the UART in the USART_USB sample project. That ISR code looks like:

    void Usart_c_irq_handler(void)
    {
            AT91PS_USART USART_pt = COM0;
            unsigned int status;
    
            //* get Usart status register and active interrupt
            status = USART_pt->US_CSR ;
            status &= USART_pt->US_IMR;
    
            if ( status & AT91C_US_RXBUFF){
            //* Toggel LED
            Trace_Toggel_LED( AT91B_LED1) ;
            //* transfert the char to DBGU
             if ( first == 0){
                 COM0->US_RPR = (unsigned int) buff_rx1;
                 COM0->US_RCR = 100;
                 pCDC.Write(&pCDC, buff_rx,100);
                 first =1;
               }else{
                 COM0->US_RPR = (unsigned int) buff_rx;
                 COM0->US_RCR = 100;
                 pCDC.Write(&pCDC, buff_rx1,100);
                 first=0;
               }
            }
    //* Check error
    
            if ( status & AT91C_US_TIMEOUT){
             Trace_Toggel_LED( AT91B_LED2) ;
             status = 100 - COM0->US_RCR;
             if  (status !=0){
               if ( first == 0){
                    COM0->US_RPR = (unsigned int) buff_rx1;
                    COM0->US_RCR = 100;
                    pCDC.Write(&pCDC, buff_rx,status);
                    first =1;
               }else{
                    COM0->US_RPR = (unsigned int) buff_rx;
                    COM0->US_RCR = 100;
                    pCDC.Write(&pCDC, buff_rx1,status);
                    first=0;
                }
                COM0->US_CR = AT91C_US_STTTO;
              }
            }
            //* Reset the satus bit for error
             USART_pt->US_CR = AT91C_US_RSTSTA;
    }
    

  • Hi friend,

    I have taken the first example(US0),
    the second one is Debug port.

    In the ISR i have included this lines(at the end).
    The result is same(No receving).

            AT91C_BASE_AIC->AIC_EOICR = AT91C_BASE_US0->US_CSR;               /*  Interrupt Ack*/
            AT91C_BASE_AIC->AIC_ICCR  = (1 << AT91C_ID_US0);                       /*  Interrupt Ack*/
            AT91C_BASE_AIC->AIC_EOICR = 0;
    
    
            AT91C_BASE_US0->US_CR = AT91C_US_RSTSTA;
    
    


    With regards,
    Murthy.R

  • Hi friends,

    Please give me any example code for USART receiver interrupt function(for KEIL uversion 3.53).

    Please help me.

    with regards,
    Murthy.R