xplain - usart newb question

Go To Last Post
5 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi, for a couple of days now i was trying to figure out USART on xplain with LUFA bride with (almost) no success. My code for now looks like this

#include 
#include  
 
static int uart_putchar(char c, FILE *stream);
static void uart_init (void);
 
static FILE mystdout = FDEV_SETUP_STREAM (uart_putchar, NULL, _FDEV_SETUP_WRITE);
 
 
int main (void)
{
    uart_init();
    stdout = &mystdout;
 
    while (1)
        printf("Hello, world!\n");
}
 
 
static int uart_putchar (char c, FILE *stream)
{
    if (c == '\n')
        uart_putchar('\r', stream);
 
    // Wait for the transmit buffer to be empty
    while ( !( USARTC0.STATUS & USART_DREIF_bm) );
 
    // Put our character into the transmit buffer
    USARTC0.DATA = c; 
 
    return 0;
}
 
 
// Init USART.  Transmit only (we're not receiving anything)
// We use USARTC0, transmit pin on PC3.
// Want 9600 baud. Have a 2 MHz clock. BSCALE = 0
// BSEL = ( 2000000 / (2^0 * 16*9600)) -1 = 12
// Fbaud = 2000000 / (2^0 * 16 * (12+1))  = 9615 bits/sec
static void uart_init (void)
{
    // Set the TxD pin high - set PORTC DIR register bit 3 to 1
    PORTC.OUTSET = PIN3_bm;
 
    // Set the TxD pin as an output - set PORTC OUT register bit 3 to 1
    PORTC.DIRSET = PIN3_bm;
 
    // Set baud rate & frame format
    USARTC0.BAUDCTRLB = 0;			// BSCALE = 0 as well
    USARTC0.BAUDCTRLA = 12;
 
    // Set mode of operation
    USARTC0.CTRLA = 0;				// no interrupts please
    USARTC0.CTRLC = 0x03;			// async, no parity, 8 bit data, 1 stop bit
 
    // Enable transmitter only
    USARTC0.CTRLB = USART_TXEN_bm;
}

it's form frnakvh blog and its working ok, i can see Hello world in hyperterminal but i cant figure it out in opposite direction, form what i read i need to change usart_init() to something like this:


static void uart_init (void)
{
    // Set the TxD pin high - set PORTC DIR register bit 3 to 1
    PORTC.OUTSET = PIN3_bm;
 
    // Set the TxD pin as an output - set PORTC OUT register bit 3 to 1
    PORTC.DIRSET = PIN3_bm;
    PORTC.DIRCLR = PIN2_bm; //ADD pin for RxD
 
    // Set baud rate & frame format
    USARTC0.BAUDCTRLB = 0;			// BSCALE = 0 as well
    USARTC0.BAUDCTRLA = 12;
 
    // Set mode of operation
    USARTC0.CTRLA = 0;				// no interrupts please
    USARTC0.CTRLC = 0x03;			// async, no parity, 8 bit data, 1 stop bit
 
    // Enable transmitter only AND receiver
    USARTC0.CTRLB = USART_TXEN_bm | USART_RXEN_bm; 
}

can someone explain to me how main() should look like to, for example echo back received char to terminal ?
Why when i switch USARTC0 to USARTD0 i dont see Hello world in my terminal ? Is USARTC0 somehow connected to USB ? And one more question, in atmel examples to make usart work i had to connect pins 3/2 on portd, why ? When using USARTC0 with RX/TX enabled i should connect pins on PORTC to ? I'am very confused about this.

thanks for any replay, and sorry for my poor english :)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Have you read and looked at the code of AVR1307?

(in fact to learn about Xmega get the whole set of AVR13xx notes).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

yes i did, in fact i read all of xmega/xplain documents, but still cant figure it out...
even tried example from avr1307, but i cant connect portc pin2 to pin3 on xplain, when i change code to portd/usartd0 and connect pins nothing happens...
i'am lost

Last Edited: Wed. Jun 1, 2011 - 04:45 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well on a "traditional" AVR you'd use:

uint8_t UART_read(void) {
  while (!(UCSRCA & (1<<RXC)));
  return UDR;
}

It looks in X as if UDR is (in your case) USARTC0.DATA so that's going to be:

  return USARTC0.DATA;

So all that remains is to find out what the equivalent of RXC is. The status register is USARTC0.STATUS so all that remains is to find the name of the RXC bit. It looks like RXCIF. So maybe:

uint8_t UART_read(void) {
  while (!(USARTC0.STATUS & (1<<RXCIF)));
  return USARTC0.DATA;
}

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ok, got it, its working now, i can light leds from my pc

edit//

hmm can someone explain to me why my code sometimes work and sometimes not ? its win driver fault or xmega code ?
i need to plug/unplug my board couple of times to make it work, what can be cause of this wierd behaviour ?
I'am using great LUFA bridge and my xmega code looks like this:

#include "usart_driver.h"
#include 
#include "avr_compiler.h"
#include "ioport.h"
#include "port_driver.h"
#include "pmic_driver.h"
#include "TC_driver.h"

#define USART USARTC0

void Config32MHzClock(void)
{
  CCP = CCP_IOREG_gc; //Security Signature to modify clock 
  // initialize clock source to be 32MHz internal oscillator (no PLL)
  OSC.CTRL = OSC_RC32MEN_bm; // enable internal 32MHz oscillator
  while(!(OSC.STATUS & OSC_RC32MRDY_bm)); // wait for oscillator ready
  CCP = CCP_IOREG_gc; //Security Signature to modify clock 
  CLK.CTRL = 0x01; //select sysclock 32MHz osc
};

int main (void)
{
	Config32MHzClock();
	char receivedData;

	PORTC.DIRSET = PIN3_bm;
	PORTC.DIRCLR = PIN2_bm;

	USART_Format_Set(&USART, USART_CHSIZE_8BIT_gc, USART_PMODE_DISABLED_gc, false);

	USART_Baudrate_Set(&USART, 3317 , 12);

	USART_Rx_Enable(&USART);
	USART_Tx_Enable(&USART);


	while(1) {

		do{
		/* Wait until data received or a timeout.*/
		}while(!USART_IsRXComplete(&USART));
		receivedData = USART_GetChar(&USART);

		do{
		/* Wait until it is possible to put data into TX data register. */
		}while(!USART_IsTXDataRegisterEmpty(&USART));
		USART_PutChar(&USART, receivedData);
		
		if (receivedData == 'a') {      
			PORTE.DIR = 0x01;
		} else if (receivedData == 'b') {      
			PORTE.DIR = 0x02;         
		} else {
			PORTE.DIR = 0x04;
		}

	}
}