SAM7S64 DBGU port as a UART

Hi all, I have a AT91SAM7S64 chip from Atmel and I am running FreeRTOS without a problem.  I can access the 1st UART for serial communication without a problem.  The problem happens when I try to access the 2nd UART which is called the Debug Unit UART (DBGU).  According to the Docs DBGU is connected to the JTAG interface and can be used to debug using a console.  When I try to use DBGU with interrupts (TXCOMP, RX …), FreeRTOS gets very un-happy and gets in to a knot.  I think it is because of DBGU port having higher priority interrupts than the Interrupts used by FreeRTOS. Has anyone tried to use this port with FreeRTOS for normal serial comms ? How can I use it for normal serial comms ? Replys greatly appriciated. Cheers   Janaka

SAM7S64 DBGU port as a UART

The DBGU shares IRQ with the timer used for timer tick interrupts of freeRTOS (SYSIRQ). Therefore you will have to add a call to your ISR in the RTOS timer tick ISR(, or you can use the PDC and poll data once in a while (skip the IRQ)) Jokke.

SAM7S64 DBGU port as a UART

Not a direct answer as I don’t know about the DBGU – The timer interrupt priority for the tick is set to AT91C_AIC_PRIOR_HIGHEST.  Can you set the priority for the DBGU? Are you using the startup code from the SAM7 demo project?  Don’t use the Atmel supplied code as it is not compatable with FreeRTOS. Do you have other interrupt running in your system, or is the DBGU interrupt the first you have tried?

SAM7S64 DBGU port as a UART

You can of course also use the USART1, with it’s own IRQ. I guess you are also using (like me) AT91SAM7S-EK, where only DGU and UART0 are connected to DSUB, but it should be a rather simple HW patch to switch it to UART1 :-). Jokke again

SAM7S64 DBGU port as a UART

Thanks Jokke,  My suspicions were partially correct.  I have coded DBGU to not use the IRQs, and am polling the DBGU in another task.  It works well. Cheers   Janaka

SAM7S64 DBGU port as a UART

Thanks guys.  I have the UART1 and the USB working with IRQs. Yep it is the IAR & AT91SAM7S-EK kit.  I took the freeRTOS example as an template. Cheers   Janaka

SAM7S64 DBGU port as a UART

Trying to get DBGU working on the IAR port, has anyone got code that checks the source of the interrupt from within the ISR, and then services whichever is found to be the cause? Relevant thread… https://sourceforge.net/forum/message.php?msg_id=3828288

SAM7S64 DBGU port as a UART

Jon, actually your linked thread descibes it like you want it to work. The source of the interrupt has to be checked within the Tick Interrupt located in portISR.c example: if ((AT91C_BASE_PITC->PITC_PISR & AT91C_PITC_PITS) > 0) // did the PIT (timer) fire the interrupt? { vTaskIncrementTick(); } else if ((((AT91PS_USART)AT91C_BASE_DBGU)->US_CSR & AT91C_US_RXRDY) > 0) // did the DBGU Receiver fire the interrupt { … // Either signal the interrupt to a handling Task with a semaphore or branch to a short inline function }

SAM7S64 DBGU port as a UART

Thanks, In the IAR port, I’m a bit put off by the following comment: /* Currently the IAR port requires the preemptive tick function to be defined in an asm file. */ which is where its all at.. Not really sure why. My ARM assembly skills only go as far as creating wrappers for the ‘C’ ISRs. Thats none ;) I’m going to have a look at porting vPortPreemptiveTick to a ‘C’ ISR (quick) Failing that, time for some simple ASM… Jon.

SAM7S64 DBGU port as a UART

This should help me… http://blog.21ic.com/user1/3017/archives/2006/21108.html

SAM7S64 DBGU port as a UART

vPortPreemptiveTick is a C function in my port which is the STR712 with the IAR compiler.  Here’s the code: __arm void vPortPreemptiveTick( void ) {     /* Increment the tick counter. */     vTaskIncrementTick();     /* The new tick value might unblock a task.  Ensure the highest task that     is ready to execute is the task that will execute when the tick ISR     exits. */     #if configUSE_PREEMPTION == 1         vTaskSwitchContext();     #endif     TB_ClearITPendingBit( TB_IT_Update ); } The function is called directly from the assembler interrupt handler (the function address is stored in the interrupt vector table).

SAM7S64 DBGU port as a UART

Only the interrupt entry point need be in assembler.  This is done for you so you need not add any assembly code yourself.  The rest can be done in C. This is the case because the IAR compiler has no equivalent to the GCC ‘naked’ attribute and a rather limited inline assembler. Regards.

SAM7S64 DBGU port as a UART

Got it working by using vPreemptiveTick() declared in the GCC portISR.c, with an ASM wrapper. Checked the OS still runs, which it does.. Then I modified vPreemptiveTick() as described the linked thread. Then hooked in UartDbguIsr(). Hey presto it works. Now its time to test… There is another thread in the AT91 forum under the title "debug serial port interrupts" which talks about using a while loop to service interrupts until they are all cleared. May be worth a look. So… I give you step by step instructions on how I did it… <b>In port.c, replace the following text:</b> /* Currently the IAR port requires the preemptive tick function to be defined in an asm file. */ <b>With:</b> __arm void vPreemptiveTick( void ); __arm void vPreemptiveTick( void ) {    unsigned portLONG ulDummy;    if (AT91C_BASE_PITC->PITC_PISR & AT91C_PITC_PITS)    {       /* Increment the tick count – this may wake a task. */       vTaskIncrementTick();       /* Find the highest priority task that is ready to run. */       vTaskSwitchContext();       /* Clear the AT91C_PITC_PITS flag */       ulDummy = AT91C_BASE_PITC->PITC_PIVR;    }    else    {       /* Possible interrupt caused by the DBGU. AT91C_US_RXRDY and       AT91C_US_TXRDY checked & cleared within UartDbguIsr */       extern __arm void UartDbguIsr(void);       UartDbguIsr();    }    /* End the interrupt in the AIC. */    AT91C_BASE_AIC->AIC_EOICR = ulDummy; } <b>In portasm.s79, add the following to the list of externals:</b>    EXTERN vPreemptiveTick <b>In portasm.s79, rewrite vPreemptiveTick as a simple wrapper:</b> vPortPreemptiveTick:     portSAVE_CONTEXT            ; Save the context of the current task.     bl    vPreemptiveTick   ; Call the ISR routine.     portRESTORE_CONTEXT            ; Restore the context of the selected task. …..Hope this helps…..Jon….

SAM7S64 DBGU port as a UART

Hi.. I am trying to track a problem that is causing system instability on my SAM7S IAR port ~ once every 2 week period.
Ages ago I rewrote the PIT ISR in C, to allow the debug UART to be used.. (as it shares the same interrupt as the PIT. tut tut.)
See postings above..
Previously it was.. vPortPreemptiveTick:
   portSAVE_CONTEXT ; Save the context of the current task.
   LDR R0, =vTaskIncrementTick ; Increment the tick count – this may wake a task.
   mov lr, pc
   BX R0
   LDR R0, =vTaskSwitchContext ; Select the next task to execute.
   mov lr, pc
   BX R0
   LDR   R14, =AT91C_BASE_PITC ; Clear the PIT interrupt
   LDR   R0,
   LDR R14, =AT91C_BASE_AIC ; Mark the End of Interrupt on the AIC
   STR R14,
   portRESTORE_CONTEXT ; Restore the context of the selected task.
   END Now it is….(with the usual ASM wrappers) __arm void vPreemptiveTick( void );
__arm void vPreemptiveTick( void )
{
   unsigned portLONG ulDummy;
   if (AT91C_BASE_PITC->PITC_PISR & AT91C_PITC_PITS)
   {
      /* Increment the tick count – this may wake a task. */
      vTaskIncrementTick();
      /* Find the highest priority task that is ready to run. */
      vTaskSwitchContext();
      /* Clear the AT91C_PITC_PITS flag */
      ulDummy = AT91C_BASE_PITC->PITC_PIVR;
   }
   else
   {
      /* Possible interrupt caused by the DBGU. AT91C_US_RXRDY and
      AT91C_US_TXRDY checked & cleared within UartDbguIsr */
      extern __arm void UartDbguIsr(void);
      UartDbguIsr();
   }
   /* End the interrupt in the AIC. */
   AT91C_BASE_AIC->AIC_EOICR = ulDummy;
} I’d appreciate a glance over it to see if anyone can spot any cracks in the code. Its was a change I consider high risk. Also, I notice some people end the ISR differently.. Which is the correct way??
   portEND_SWITCHING_ISR (xTaskWokenByPost);
   AT91C_BASE_AIC->AIC_EOICR = 0;
}      
..or..
   AT91C_BASE_AIC->AIC_EOICR = 0;
   portEND_SWITCHING_ISR (xTaskWokenByPost);
}       Also, I looked at the ARM9 IAR port for ideas / differences – vPortTickISR() – its very different.. there seems to be no ASM wrapper..
But, the last comment says   /* The AIC is cleared in the asm wrapper, outside of this function. */
Which I found confusing..
Why is a standard C function vPortTickISR not declared as an __interrupt and written to the interrupt vector. See
  AIC_ConfigureIT( AT91C_ID_SYS, AT91C_AIC_PRIOR_LOWEST, vPortTickISR );
Where is the following equivalent instruction in the ARM9 port at the end of the ISR
  AT91C_BASE_AIC->AIC_EOICR = ulDummy;
It seems to break many of the rules on using interrupts under FreeRTOS with IAR If anyone can enlighten me and others, I would be grateful.
Thanks.