Uart to Uart problem

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

Hello all! :D As first.. im more a lurker on this forum.
Search function works fine ;) to find many answers so mostly not needed to ask questions here. Great Forum!! Love it.
Though maybe i can contribute too since i now have an account.

But for my question:

I have an Xmega32A4.
Using 2 uarts.
I have an bluetooth module connected to it and an serial camera.

The reason why i have an Xmega between those guys is mosty for initializing. Oke it's overkill but it's great for Uarts...

The problem is that my Picture data of Raw images and sometimes commando's don't seem to transfer properly.
I have half baked images like this:

In the end there are alot white lines. So alot pixels are missing. Try selecting the picture with your mouse, you see there is 10% data missing at the end

So: Camera -> [avr] -> Bluetooth -> PC.
I know it's the AVR because without it works fine without it. But when i need to use it standalone i need to initialize with AT command both hardware.

I also used Parity Mode for communication between the bluetooth module and the AVR. Because i can't get the bluetooth to work without it. Does parity slow down something in the AVR?

Anyway my code:

int main (void)
{
	/****Initialisaties:****/
	OSCinit();			// Initialisatie oscilator 
	PORTA_DIR = 0xff;	// PORTA als output
	PORTA_OUT = 0xfe;	// Config PORTA, zet alle Leds uit + BTATCOM.
	PORTB_DIR = 0x00;	// PORTB als input
	_delay_ms(1000); 	// Delay voor opstarten bluetooth module
	pc_usart_init();	// Initialisatie usart computer
	cam_usart_init();	// Initialisatie usart camera
	bt_usart_init();	// Initialisatie usart bluetooth
	BluetoothNameInit();// Initialisatie van Bluetooth Naam	
    

    while (1)
	{

			// From Bluetooth to Camera
			if ((USARTE0.STATUS & USART_RXCIF_bm)&&(USARTC0.STATUS & USART_DREIF_bm)){
			USARTC0_DATA=USARTE0_DATA;
			}
			// From Camera to Bluetooth
			if ((USARTC0.STATUS & USART_RXCIF_bm)&&(USARTE0.STATUS & USART_DREIF_bm)){
			USARTE0_DATA=USARTC0_DATA;
			}

// OR I USE THIS CODE BUT SAME RESULT:

			// From bluetooth to camera
			if (USARTE0.STATUS & USART_RXCIF_bm){
			usart_putchar_CAM(USARTE0_DATA,NULL);
			}
			// From camera to bluetooth
			if (USARTC0.STATUS & USART_RXCIF_bm){
			usart_putchar_BT(USARTC0_DATA,NULL);
			}

// THIS CODE USES THE FOLLOWING FUNCTIONS:

static int usart_putchar_PC (char c, FILE *stream)
{
   	// Wait for the transmit buffer to be empty
    while ( !( USARTD0.STATUS & USART_DREIF_bm) );
 
    // Put our character into the transmit buffer
    USARTD0.DATA = c; 
    return 0;
}
 
static int usart_putchar_BT (char c, FILE *stream)  //
{ 
   	// Wait for the transmit buffer to be empty
    while ( !( USARTE0.STATUS & USART_DREIF_bm) );
 
    // Put our character into the transmit buffer
    USARTE0.DATA = c; 
    return 0;
}

static int usart_putchar_CAM (char c, FILE *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;
}


// Code for Initializing the baudrate etc in AVR:

	#define BAUD 115200
	#include 
	USARTE0.CTRLB = USART_RXEN_bm|USART_TXEN_bm|((USE_2X)?USART_CLK2X_bm:0);
	USARTE0.CTRLC = USART_CHSIZE0_bm|USART_CHSIZE1_bm|USART_PMODE1_bm; // With Parity
	USARTE0.BAUDCTRLA = UBRRL_VALUE;
	USARTE0.BAUDCTRLB = UBRRH_VALUE;
	#undef BAUD



Got a crystal running at "F_CPU 14745600UL"

But the most important is the while loop. Here the data will be send over trough the AVR. Afther the initializing functions have been taken care of in the main loop.

Somhow the AVR isn't catching the data fast enough? I thought this crystal was fast enough..

I hope someone will see the problem and can help me with it. Im kinda stuck on this one.

Kind regards,

Herman.

Last Edited: Thu. Jun 16, 2011 - 12:34 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am using the polling technique. Maybe working with interupts is more stable and can handle more troughput with data?

But i haven't worked alot with uarts together with interrupts. Only simple things. Im still a newbie.

Maybe people can give me hints? I don't need a full answer just suggestions and pointing me were i am wrong.

I just wonder why there are bytes lost... and were in my process.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
USARTE0.BAUDCTRLA = UBRRL_VALUE; 
USARTE0.BAUDCTRLB = UBRRH_VALUE; 

Sorry, but it's not clear to me where UBRR is calculated? You might have an baud mismatch error depending on what BAUDCTRLA and BAUDCTRLB are actually set to.

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

Perhaps a few thoughts to get you started.
(I don't read C).
Usually the problem would be in the RF link, and the first suggestion is to remove the RF link and connect the AVR directly to the PC and see if just the camera to uC to PC works. (AVR needs RS-232 or USB interface).

Next question, do either/both the camera and the BT module use handshake controls to indicate when they are avialable/busy?

Does the camera buffer the image? Can you slow the camera output down until you have the system working, then work on throughput?

Generally one would want to buffer the camera to micro data stream, and use interrupts to read this incoming data. Every new incoming byte triggers an interrupt. In the interrupt routine you read the byte and put it in a buffer. (Circular Buffer aka Ring Buffer).

In the Main program you can either use polled or interrupt driven routines to fetch data from the ring buffer and send it out the BT module.

Note that in practice the BT module will not have a 100% first time data transfer success rate. It may, on occassion, need to resend a packet two or even three times. This will slow down the micro to PC end of the link. Hence the buffer can still be absorbing data without losing it, while the BT to PC gets a packet or two behind now and then.

JC

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

rjbishop wrote:

USARTE0.BAUDCTRLA = UBRRL_VALUE; 
USARTE0.BAUDCTRLB = UBRRH_VALUE; 

Sorry, but it's not clear to me where UBRR is calculated? You might have an baud mismatch error depending on what BAUDCTRLA and BAUDCTRLB are actually set to.

This is calculated in ' #include '

You just define the Baudrate together with your Clock and then it pops out the values ;) easy right?

The util stuff makes you very lazy sometimes... haha

Last Edited: Fri. Jun 17, 2011 - 07:13 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

DocJC wrote:
Perhaps a few thoughts to get you started.
(I don't read C).
Usually the problem would be in the RF link, and the first suggestion is to remove the RF link and connect the AVR directly to the PC and see if just the camera to uC to PC works. (AVR needs RS-232 or USB interface).

Next question, do either/both the camera and the BT module use handshake controls to indicate when they are avialable/busy?

Does the camera buffer the image? Can you slow the camera output down until you have the system working, then work on throughput?

Generally one would want to buffer the camera to micro data stream, and use interrupts to read this incoming data. Every new incoming byte triggers an interrupt. In the interrupt routine you read the byte and put it in a buffer. (Circular Buffer aka Ring Buffer).

In the Main program you can either use polled or interrupt driven routines to fetch data from the ring buffer and send it out the BT module.

Note that in practice the BT module will not have a 100% first time data transfer success rate. It may, on occassion, need to resend a packet two or even three times. This will slow down the micro to PC end of the link. Hence the buffer can still be absorbing data without losing it, while the BT to PC gets a packet or two behind now and then.

JC

Hello first thanks you for your input,

I tested the bluetooth and the camera separately. My prototype board is designed this way that all uarts can connect to AVR or PC with the change of dipswitches.

Directly to the PC works fine. Got great images at very high baudrates like 460800.

Yesterday i also thought of the idea that the data could be missing because i use parity bit between the AVR and the Bluetooth module. Because between the Camera and the AVR there is no parity and no handshaking. The bluetooth module can use handshaking but is not really needed.

So now i can move on. I can try 3 things now:
-Try to get rid of the parity mode
-Try to get everything run with interupts
-Try to implement a ring buffer ( have no know how about this but ill just use google ;) )

Thanks alot!!!

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

Hi hermanw,

I highly recommend using interrupt based RX for your situation. Dean (abcminiuser) has a really nice UART ringbuffer that I attached. Let me give you a pretty simple example. I haven't testing this code exactly, but it's nearly the same approach I used in another project where it worked very well.

#include "LightweightRingBuff.h"

/* Set up ring buffer */
RingBuff_t RX_Buffer;
RingBuff_t TX_Buffer;

int main(void)
{
	/* Initialize Ring Buffers */
	RingBuffer_InitBuffer(&RX_Buffer);
	RingBuffer_InitBuffer(&TX_Buffer);
	
	for(;;)
	{
		if(RingBuffer_GetCount(&RX_Buffer) > 0)
			USART_SendByte(&USARTE0, RingBuffer_Remove(&RX_Buffer)
		
		if(RingBuffer_GetCount(&TX_Buffer) > 0)
			USART_SendByte(&USARTC0, RingBuffer_Remove(&TX_Buffer)
	
	}
}

/* ISR that grabs byte from camera and sticks it in ring buffer */
ISR(USARTC0_RXC_vect)
{
	uint8_t Received_Byte = USARTC0.DATA;
	RingBuffer_Insert(&RX_Buffer, Received_Byte);
}

/* ISR that grabs byte from bluetooth and sticks it in ring buffer */
ISR(USARTE0_RXC_vect)
{
	uint8_t Received_Byte = USARTE0.DATA;
	RingBuffer_Insert(&TX_Buffer, Received_Byte);
}

void USART_SendByte(USART_t *USART, uint8_t Data)
{
	while(!USART_DREG_EMPTY(USART));
		(*USART).DATA = Data;
}

Attachment(s): 

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

Thanks for that code Gordon,

As i stated, my crystal should be fast enough. I have like 1000 cycles for every byte!!

It was the parity bit. I have tried to remove it and i succeeded.

Between the AVR and the bluetooth module i used a Parity bit and between the AVR and the camera i used normal mode 8 Bits data 1 stopbit and no parity.

That's why alot of data was lost because of the parity. Now it's fine and working great :P

It was all because of the standard AT command of the bluetooth added the parity bit. Now i changed that.

Done! Thanks all!!!

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

Why don't use the dma to transfer incoming data to the output?
Just setup the dma to use UART-receive as event for triggering copying one byte from UART1.DATA to UART2.DATA ? Should work without any cpu power...

greetz jonas