Atmel website | ARM Community | AVR freaks | Technical Support
Banner
 FAQ •  Search •  Register •  Login 

All times are UTC + 1 hour [ DST ]




Post new topic Reply to topic  [ 5 posts ] 
Author Message
 Post subject: Can't get RX interrupt for DBGU port to fire
PostPosted: Sun Feb 28, 2010 3:02 am 
Offline

Joined: Mon Jan 11, 2010 4:37 pm
Posts: 36
I really wanted to solve this myself and feel like I'm getting the hang of my AT91SAM9261. But I'm clearly not.

I am writing some simple-as-possible code to do two things: trap an interrupt for (a) the PIT, and (b) when receive a character over the DBGU.

Below is the code.

Code:


__irq __arm void AT91F_SysHandler(void)
{
    volatile int StStatus;
    // Read the system timer status register
    if(AT91F_PITGetStatus(AT91C_BASE_PITC))
    {
        AT91F_PITGetPIVR(AT91C_BASE_PITC);
        tick++;
    }
   
    if (AT91C_BASE_DBGU->DBGU_CSR & AT91C_US_RXRDY)
    {     
      // handle DBGU rx
      tick++;     
    }

   
    AT91F_AIC_AcknowledgeIt(AT91C_BASE_AIC);
}

void main(void)
{         
   
    // Clear AIC stack
 
    AT91C_BASE_AIC->AIC_EOICR = AT91C_BASE_AIC->AIC_EOICR;  // clear the AIC stack (???)
   
    AT91C_BASE_AIC->AIC_DCR = 1;   // put the AIC in protect mode (so debug reads don't trigger action)
   
    // set up the PIT
   
    AT91C_BASE_PITC->PITC_PIMR = (SYS_TMR_PER/10)? ((SYS_TMR_PER/10) * (Fmclk/1000000) + 8) >> 4 : 0; // +8 to avoid %10 and /10
    AT91C_BASE_PITC->PITC_PIMR |= AT91C_PITC_PITEN;   
    AT91C_BASE_PITC->PITC_PIMR |= AT91C_PITC_PITIEN;    // enable the PIT interrupt
   
    tick = 0;

    // set up the AIC

    AT91C_BASE_AIC->AIC_IDCR = (0x1 << AT91C_ID_SYS) ;       // disable the system interrupt
    AT91C_BASE_AIC->AIC_SVR[AT91C_ID_SYS] = (unsigned int) AT91F_SysHandler ;      // point the vector to the function
    AT91C_BASE_AIC->AIC_SMR[AT91C_ID_SYS] = AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE | AT91C_AIC_PRIOR_HIGHEST  ;    // set mode, priority
    AT91C_BASE_AIC->AIC_ICCR = (0x1 << AT91C_ID_SYS) ;   // clear the system interrupt
       
    AT91C_BASE_AIC->AIC_IECR = 0x1 << (AT91C_ID_SYS) ;  // enable the system interrupt
   
    // set up the DBGU
   
    AT91C_BASE_DBGU->DBGU_CR = AT91C_US_RSTRX | AT91C_US_RSTTX | AT91C_US_RXDIS | AT91C_US_TXDIS ;      // Reset receiver and transmitter
    AT91C_BASE_DBGU->DBGU_BRGR = calculate_baudrate(Fmclk, AT91C_BAUDRATE_115200);   
    AT91C_BASE_DBGU->DBGU_MR = AT91C_US_ASYNC_MODE  ;      // define the USART mode
    AT91C_BASE_DBGU->DBGU_CR = AT91C_US_RXEN | AT91C_US_TXEN;  // enables the transmitter and receiver   
   
    AT91C_BASE_DBGU->DBGU_IER = AT91C_US_RXRDY; // RX Ready interrupt
    AT91C_BASE_AIC->AIC_IECR = 1 << AT91C_ID_SYS;
   
    __enable_interrupt();
     
    while(1){};

}




I put breakpoints in both branches of the AT91F_SysHandler function, and it seems that my PIT is working fine, but I can't trigger the AT91C_US_RXRDY branch by sending a character in to the DBGU port. Zilch.

I'm pretty sure that I have the hardware, connection, and port settings correct because I have some other code that sends a character out to my terminal, and I receive it fine at 115200. I've tried the send functions of a couple of different port tools, so I don't think the problem is there.

By the way when I do get a PIT interrupt, I look at my DBGU_CSR registers to see if anything looks funny, and I see:

RXRDY=0
TXRDY=1
ENDRX=1
ENDTX=1
OVRE=0
FRAME=0
PARE=0
TXEMPTY=1
TXBUFE=1
RXBUFF=1
RX=1
TX=1

Nothing jumps out at me as wrong, but maybe someone smarter sees something.

Anyway I have been spending WAY too much time on this and am an utter failure. You will make me a very, very happy man if you spot the problem in my code. You will be a hero of mythic proportions.


Top
 Profile  
 
 Post subject: Re: Can't get RX interrupt for DBGU port to fire
PostPosted: Sun Feb 28, 2010 1:53 pm 
Offline

Joined: Mon Jan 11, 2010 4:37 pm
Posts: 36
By the way sorry for the mess of code. What I did was cobbled together a sample that works (but did more than I needed) and I took pieces out until PIT stopped working, then I would add that piece back in. So I had a smallest possible set that got the PIT working. Then I read about DBGU and looked at sample code added additional commands to trap DBGU USART RX in the same system interrupt -- but can't for the life of me get it to work. The new stuff is the few lines of code under "set up the DBGU", everything else seems to be okay (i.e., PIT works).

Thanks for any advice, really at wit's end.


Top
 Profile  
 
 Post subject: Re: Can't get RX interrupt for DBGU port to fire
PostPosted: Sun Feb 28, 2010 4:29 pm 
Offline

Joined: Thu Feb 25, 2010 5:02 pm
Posts: 88
Are you configuring the PIO to use Peripherial A for the DBGU pins?

And you probably want to remove the line that enables the system interrupts before you configure the DBGU. You are enabling this after the DBGU is configured.

Code:
AT91C_BASE_AIC->AIC_ICCR = (0x1 << AT91C_ID_SYS) ;   // clear the system interrupt

AT91C_BASE_AIC->AIC_IECR = 0x1 << (AT91C_ID_SYS) ;  // enable the system interrupt    // set up the DBGU
    AT91C_BASE_DBGU->DBGU_CR = AT91C_US_RSTRX | AT91C_US_RSTTX | AT91C_US_RXDIS | AT91C_US_TXDIS ;      // Reset receiver and transmitter
    AT91C_BASE_DBGU->DBGU_BRGR = calculate_baudrate(Fmclk, AT91C_BAUDRATE_115200);   
    AT91C_BASE_DBGU->DBGU_MR = AT91C_US_ASYNC_MODE  ;      // define the USART mode
    AT91C_BASE_DBGU->DBGU_CR = AT91C_US_RXEN | AT91C_US_TXEN;  // enables the transmitter and receiver   
   
    AT91C_BASE_DBGU->DBGU_IER = AT91C_US_RXRDY; // RX Ready interrupt
AT91C_BASE_AIC->AIC_IECR = 1 << AT91C_ID_SYS;

_________________
Duane P. Fridley, IEEE CSDP
Viable Bytes, Inc.


Top
 Profile  
 
 Post subject: Re: Can't get RX interrupt for DBGU port to fire
PostPosted: Sun Feb 28, 2010 9:27 pm 
Offline

Joined: Thu Feb 25, 2010 5:02 pm
Posts: 88
You will also have to enable the PIOA peripherial clock.

_________________
Duane P. Fridley, IEEE CSDP
Viable Bytes, Inc.


Top
 Profile  
 
 Post subject: Re: Can't get RX interrupt for DBGU port to fire
PostPosted: Wed Mar 03, 2010 12:08 am 
Offline

Joined: Mon Jan 11, 2010 4:37 pm
Posts: 36
(thought I replied to this already, sorry)

Darn, my hopes were up since I overlooked both those things. Thanks, I'm sure it's closer -- but still no trapped interrupt on rx character.

Here is my amended main() code that enables PIOA for DBGU, and enables the PIOA clock on the PMC. Can anyone see the problem?

OR, does a kind soul using DBGUon their 9261 have 5 minutes to cut and paste this into the top of their main(), see if it works for them? (If not maybe I have an electrical problem -- our HW guys maybe fried the board -- but I doubt it.)

(Yes, I am reduced to such impositions. I wish I could offer something in return.)





Code:
void main()
{   
    AT91C_BASE_PMC->PMC_PCER = ((unsigned int) 1 << AT91C_ID_PIOA   )    ;    // enable PIOA perip clock   
    AT91C_BASE_AIC->AIC_EOICR = AT91C_BASE_AIC->AIC_EOICR;  // clear the AIC stack (???)
   
    AT91C_BASE_AIC->AIC_DCR = 1;   // put the AIC in protect mode (so debug reads don't trigger action)
   
    // initialize the PIT
   
    AT91C_BASE_PITC->PITC_PIMR = (SYS_TMR_PER/10)? ((SYS_TMR_PER/10) * (Fmclk/1000000) + 8) >> 4 : 0;
    AT91C_BASE_PITC->PITC_PIMR |= AT91C_PITC_PITEN;   
    AT91C_BASE_PITC->PITC_PIMR |= AT91C_PITC_PITIEN;    // enable the PIT interrupt
   
    tick = 0;

    AT91C_BASE_AIC->AIC_IDCR = (0x1 << AT91C_ID_SYS) ;       // disable the system interrupt
    AT91C_BASE_AIC->AIC_SVR[AT91C_ID_SYS] = (unsigned int) AT91F_SysHandler ; // point vector to function
    AT91C_BASE_AIC->AIC_SMR[AT91C_ID_SYS] = AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE | AT91C_AIC_PRIOR_HIGHEST  ;    // set mode, priority
    AT91C_BASE_AIC->AIC_ICCR = (0x1 << AT91C_ID_SYS) ;   // clear the system interrupt
     
    AT91C_BASE_PIOA->PIO_PDR = AT91C_PA9_DRXD | AT91C_PA10_DTXD;    // Enable peripheral pins
    AT91C_BASE_PIOA->PIO_ASR = AT91C_PA9_DRXD | AT91C_PA10_DTXD;    // Select the A function (Debug Unit)
    // Reset receiver and transmitter
    AT91C_BASE_DBGU->DBGU_CR = AT91C_US_RSTRX | AT91C_US_RSTTX | AT91C_US_RXDIS | AT91C_US_TXDIS ;     
    AT91C_BASE_DBGU->DBGU_BRGR = calculate_baudrate(Fmclk, AT91C_BAUDRATE_115200);   
    AT91C_BASE_DBGU->DBGU_MR = AT91C_US_ASYNC_MODE  ;      // define the USART mode
    AT91C_BASE_DBGU->DBGU_CR = AT91C_US_RXEN | AT91C_US_TXEN;  // enables the transmitter and receiver   
   
    AT91C_BASE_DBGU->DBGU_IER = AT91C_US_RXRDY; // RX Ready interrupt
    AT91C_BASE_AIC->AIC_IECR = 1 << AT91C_ID_SYS;   // enable the system interrupt
   
    __enable_interrupt();
   
    while(1){};


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 5 posts ] 

All times are UTC + 1 hour [ DST ]


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: