USART on AT91SAM7SE512

All, after getting OpenOCD to support the flash in the AT91SAM7SE I’ve been piddling around with some code. I’m able to toggle LEDs and use the GPIO with ease. However, I am having some serious problems with the USART in the chip. I’m using the AT91SAM7SE-EK board. I’m attempting to use the follow code. I’m expecting that I will get a continuous stream of data coming out of the TXD0 pin. I get no data in HyperTerminal. When I have an oscilloscope hooked up to the pin signal is held high. I’m using the following code:

#include "AT91SAM7SE512.h"

int main()
{		
	// Setup the waitstates of the flash at 48MHz
	AT91C_BASE_MC->MC0_FMR = AT91C_MC_FWS_2FWS;
	AT91C_BASE_MC->MC1_FMR = AT91C_MC_FWS_2FWS;
	
	// Enable the main oscillator (18.432 MHz)
	AT91C_BASE_PMC->PMC_MOR = (AT91C_CKGR_OSCOUNT & (0x40 << 8)) | AT91C_CKGR_MOSCEN;
	
	// Wait for the startup time of the oscilator to ellapse
	while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MOSCS))
		;
		
	AT91C_BASE_PMC->PMC_PLLR = AT91C_CKGR_USBDIV_1           |
                               AT91C_CKGR_OUT_0              |
                               (16 << 8)                     |
                               (AT91C_CKGR_MUL & (72 << 16)) |
                               (AT91C_CKGR_DIV & 14);
	
	// Wait for the PLL startup time to ellapse
	while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCK))
		;
	while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY))
		;
		
	// Set the clock divider to 2
	AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_PRES_CLK_2;
	
	// Wait for the prescaler to take effect
	while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY))
		;
	
	// Select the PLL as the clock source
	AT91C_BASE_PMC->PMC_MCKR |= AT91C_PMC_CSS_PLL_CLK;
	
	// Wait for the clock to switch
	while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY))
		;
	
	/* Enable the USART now... */
	
	// Enable the clock for US0
	AT91C_BASE_PMC->PMC_PCER = (1<<AT91C_ID_US0);
	
	// Disable the PIO on pins 5 and 6 of PIOA
	AT91C_BASE_PIOA->PIO_PDR = AT91C_PIO_PA5 | AT91C_PIO_PA6;
	
	// Select pins 5 and 6 for use by the periph
	AT91C_BASE_PIOA->PIO_ASR = AT91C_PA5_RXD0 | 
							   AT91C_PA6_TXD0;
	
	// Disable and reset the transmitter and reciever
	AT91C_BASE_US0->US_CR = AT91C_US_RSTTX | 
							AT91C_US_RSTRX | 
							AT91C_US_TXDIS | 
							AT91C_US_RXDIS;
	
	// Set us up for normal mode 8, N, 1 using MCK
	AT91C_BASE_US0->US_MR = AT91C_US_USMODE_NORMAL | 
							AT91C_US_CLKS_CLOCK | 
							AT91C_US_CHRL_8_BITS | 
							AT91C_US_PAR_NONE |
							AT91C_US_NBSTOP_1_BIT;
							
	// Set the divider to 313 this is approximately 9600
	// with a ~48 MHz clock
	AT91C_BASE_US0->US_BRGR = 313;
	
	// Enable the transmitter nad reciever 
	AT91C_BASE_US0->US_CR = AT91C_US_TXEN | 
							AT91C_US_RXEN;
							
	/* Send some data on the USART now */
	while(1)
	{
		// Wait until TXRDY is set
		while (!(AT91C_BASE_US0->US_CSR & AT91C_US_TXRDY))
		{
		}
		// Set teh byte in THR
		AT91C_BASE_US0->US_THR = 'A';		
	}
	
	return 0;
}

Does anything look absolutely incorrect with that code?

Thanks for the assistance.

-Jerry.

Hi,

Without having checked the datasheet, it looks OK.

The standard checks:

Does the program get the AT91C_US_TXRDY flag ?

and actually go around the loop continously ?

Flip another pin when writing the character to US_THR and check with the scope.

On many processors the pin must be set as output even when controlled

by a special peripherial.

Regards,

Magnus

magnus - the PIO does not need to be set as an output.

Jerry - Your code looks close to identical to my code (though I’m running an AT91SAM7X256). This is the setup code that I’m using, that works perfectly:

  AT91F_PMC_EnablePeriphClock ( AT91C_BASE_PMC, 1 << AT91C_ID_US0 ); //enable usart0
  AT91C_BASE_PIOA->PIO_PDR = AT91C_PA0_RXD0|AT91C_PA1_TXD0;
  AT91C_BASE_PIOA->PIO_ASR = AT91C_PA0_RXD0|AT91C_PA1_TXD0;
  AT91C_BASE_US0->US_BRGR = (55000000 + 8*9600)/(16*9600);
  AT91C_BASE_US0->US_MR = AT91C_US_ASYNC_MODE;
  AT91C_BASE_US0->US_CR = AT91C_US_TXEN|AT91C_US_RXEN;

Your transmit function looks OK too. Are you sure you’re looking at PA6? The only real difference between my code and yours is that you disable and reset the rx and tx, while I do not. You could try commenting that line and see if anything changes - but I don’t see why that would cause problems.

Oh - and be aware that my code is for running at 55MHz and 9600 baud.

Magnus, I set the bit in PIO_OER to enable output and that had no affect. Also, I have set it up to toggle PA2 after it sets ‘A’ into the THR. The result is that PA2 toggles at ~480Hz now. I still get no activity on PA6.

NleachiM, I’ve taken your code and adapted it to the SAM7SE512 and I get no results. I’ve also disabled the disable and reset of the transmitter and receiver to no avail.

Are there any other suggestions?

Thanks.

-Jerry.

tallganglyguy:
Magnus, I set the bit in PIO_OER to enable output and that had no affect. Also, I have set it up to toggle PA2 after it sets ‘A’ into the THR. The result is that PA2 toggles at ~480Hz now. I still get no activity on PA6.

NleachiM, I’ve taken your code and adapted it to the SAM7SE512 and I get no results. I’ve also disabled the disable and reset of the transmitter and receiver to no avail.

Are there any other suggestions?

Thanks.

-Jerry.

Are you sure PA6 isn't connected to anything? The fact that PA2 is toggling is a good sign - it suggests that the uart is functioning properly.