Usart sends strings as garbage, while single characters work fine. (AS6.2, atmega 2560,avrdude,stk500v1)

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

Hi all,

 

As this is my first post to this forum, I would like to thank all of you for creating this awesome collection of knowledge.

I learned a lot from all of you. As I kept getting stuck on a problem I decided to join AVRfreaks, as I'll be working with AVR quite a lot with my robotics projects.

But well, getting to the topic:

 

EDIT: I forgot to mention I use Putty (v0.63) to communicate.

 

I'm a newbe in AVR, trying to print strings through USART from an atmega2560.

As I followed the tutorial http://efundies.com/avr/avr_usart_init.htm, I got stuck on weird string output.

As environment I use Atmel studio 6.2. As ISP I use an arduino setup, set-up as a stk500v1.

Whenever I'm trying to print strings, I receive garbage. Sending single characters do work though.

 

I'm aware that this behavior reoccured multiple times on the forum. I tried to learn from it the last three days,

but I keep getting stuck on this weird output for strings.

 

I came across multiple similar issues on this forum, where the problem was often:

  • frequency/baudrate not set correctly
  • .data not included in .hex (I don't know what I'm talking about in terms of makefiles.)
  • UDRE not checked before sending.

 

Since sending single characters do work correctly, I assume the frequency/baudrate is set correctly.

I do check UDRE.

I'm not sure about the .data..

 

For building the project I use standard build as set in atmel studio 6.2, which created an auto-generated makefile.

Since I'm quite noobish with respect to AVR, I would really appreciate if someone could help me out.  :)

 

EDIT2:

I changed the code to be more compact, and more to the point of the problem.

I also changed the attachment, including source and all files produced by the build.

 

At the moment the main weirdness is in the prints of strA. It doesn't print the string through void usart_pstr(char*);

It does print the single characters with given index.

It doesn't print the single characters in a for-loop.

 

I expect my code to print:

hello1
hello2
hello3
hello
hello

Though what is receive is:

▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
hello2
▒▒▒▒▒▒▒▒▒▒
hello
▒▒▒▒▒

 

F_CPU is set to 16000000 in Toolchain=>ACR/GNU C Compiler => Symbols => Defined symbols : F_CPU=16000000    (This way was suggested by some guy at some forum. Though I'm not sure whether this differs from just defining it in the .c file..)

 

#include <avr/io.h>
#include <avr/pgmspace.h>

#define BAUD 19200
#define MYUBRR F_CPU/16/BAUD-1


void usart_init(uint16_t ubrr){
	/*enable receiver and transmitter*/
	UCSR0B = (1<<RXEN0)|(1<<TXEN0);
	/*set baud rate*/
	UBRR0H = (uint8_t)(ubrr>>8);
	UBRR0L = (uint8_t)(ubrr);
}


void usart_putchar(char data){
	/*wait for empty transmit buffer*/
	while(!((UCSR0A)& (_BV(UDRE0))));
	UDR0 = data;
}

void usart_pstr(char *s){
	while(*s){
		usart_putchar(*s);
		s++;
	}
}

int main(void){
	uint8_t i;

	/*init com*/
	usart_init(MYUBRR);

	/*send strings*/
	
	char *strA=  "hello1\n\r\0"; 
	usart_pstr(strA);  /*prints garbage*/
	
	usart_putchar('\n');
	usart_putchar('\r');

	char strB[7]; 
	strB[0]='h';
	strB[1]='e';
	strB[2]='l';
	strB[3]='l';
	strB[4]='o';
	strB[5] = '2';
	strB[6] = '\0';

	usart_pstr(strB); /*prints "hello2"*/

	usart_putchar('\r');  
	usart_putchar('\n'); 

	usart_pstr("hello3\n\r");/*prints garbage*/

	usart_putchar('\r');  
	usart_putchar('\n');

	usart_putchar(strA[0]);  /*prints "hello"*/
	usart_putchar(strA[1]);
	usart_putchar(strA[2]);
	usart_putchar(strA[3]);
	usart_putchar(strA[4]); /**/

	usart_putchar('\r'); 
	usart_putchar('\n');

	for(i=0;i<=4;i++)     /*prints garbage*/
		usart_putchar(strA[i]);
		
	usart_putchar('\n');
	usart_putchar('\r');

	return 0;
}

 

Thanks in advance :)

 

Attachment(s): 

Last Edited: Fri. Apr 17, 2015 - 11:36 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

You appear to have:

	UCSR0C = (1<<UMSEL01)|(3<<UCSZ00);

UMSEL01 is Reserved on most AVRs.     Otherwise,   your code looks fine to me.

As a general rule,   regular Async UART comms does not need any changes to UCSR0C from the power-up default.

 

David.

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

Thank you for your quick reply and the lesson :)

 

I left out the changes to UMSEL01.

The programs behaviour is still the same.

 

My suspicions are that the usart part itself works fine,

but that something is wrong with the string storage.

 

If I ask to print "Hello\n\r" instead of "Hello, world!\n\r" the amount of garbage decreases from 17 to 9 characters.

"Hello, world!\n\r" counts 17 characters, iff I count "\n" and "\r" as 2 characters respectively.

"Hello\n\r" counts 17 characters, iff I count "\n" and "\r" as 2 characters respectively.

But of course '\n' and '\r' are single caracters..

 

So I assume that the pointers are valid, since the null-terminator is at the correct position.

This gives me suspicions that something is wrong with the format of the characters used in the string. Although this is contradicted by a hexdump of the .elf (see attachment), which does include the strings in correct format.

 

It is quite a mystery to me..

 

Marc

 

 

Attachment(s): 

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

Ah-ha.   Now it becomes interesting.

 

I tried it for myself on a real ATmega2560 @ 16MHz.

 

I needed to correct the missing characters from your main() declaration:

int main(void) {
	//init com

and then it compiled fine and ran fine.

 

I still have not looked at the mega2560 data sheet.    But if (2<<UMSEL00) is a Reserved setting,   it does not stop it working.

 

I was using a Chinese Arduino MEGA2560 clone.

 

David.

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

...and then it compiled fine and ran fine.

... but that something is wrong with the string storage.

Hmmm--you are using a "modern" GCC version.

 

I'm not familiar enough with GCC...is the anonymous string "Hello, World!2\n\r" stored in flash or SRAM?  The routine expects an SRAM string.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

The "modern" GCC is still incapable of handling anonymous strings.     They all go into SRAM unless you specifically do the PSTR() kludge.

 

I really would not lose any sleep over three strings in a mega2560's SRAM.

 

It would be nice to hear from the OP.    i.e. how did the copy-paste get corrupted?

 

I can't see any practical time diffference between a putstring() or a sequence of putchar()s.     Both will end up with gap-free transmission.

Obviously,    a putstring() call is easier for the programmer to maintain.

 

David.

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

They all go into SRAM unless you specifically do the PSTR() kludge.

No compiler option for that like CV has?

 

OP could clean up the test program a bit, post the complete program along with .LSS and such.

 

Also, for sanity I'd try a defined string with the value, and pass that to the routine.  .LSS for that, too...

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

Lee,

 

With the missing punctuation,   the OP's posted code won't compile.

 

With my suggested edits,   the program works just fine.

 

If there was a glitch in the Start bit,    you would not get identical graphic characters.

 

Note that the Xmega will have a problem with Start bits if the ASM is not swift enough.    But I have never seen this effect with a Mega with any Compiler.   

 

Of course,   if the Terminal software displays that graphic character for a Framing error,    you can solve it by just placing a _delay_ms(1) between the init() and the first putstring().

 

David.

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

Thank you for your reactions.

It seems I deleted the ){ at the main function declaration while removing irrelevant code. My appologies for that.

 

@David

Did the program run with correct output at your mega2560?

If so, I'm wondering whether it could be a hardware problem.. I hope not so..

I tried the delay as suggested. This did not influence the behavior.

 

I'm not familiar with the term "anonymous strings". I suppose this is the string that is given as argument of void pstr(char*) directly?

But well, the strings are put in SRAM, if I understand you correctly, which should be correct.

 

@David

You asked how the copy-paste got corrupted. To what copy-paste are you refering to?

I assume the output that I described earlier. That was the exact output as shown in Putty.

 

@theusch

I'll do what you asked, and I'll put in the next post.

 

I tried something else also:

This works correctly.

	char d[10];  //Does work
	d[0]='h';
	d[1]='o';
	d[2]='i';
	d[3]='h';
	d[4]='o';
	d[5]='i';
	d[6]='h';
	d[7]='o';
	d[8]='i';
	d[9] = '\0';
	
	usart_pstr(d);

I'll update more trimmed code to the original post in an edit.

 

Marc

 

 

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

I built your program in AS6.2.    Ran it on a MEGA2560 board.    Used the Codevision Terminal @ 19200 baud.

 

An anonymous string is  uart_pstr("David");

A named string is char string[] = "Prentice";

 

There is no way that I can see your

	char* c=  "Hello, world!1\n\r";  //Doesn't work.. 

getting placed in flash.     It is simply creating a string in SRAM and then creating a pointer variable with the string's address.

 

Note that using 'c' for a string is not a very intuitive name.

And there is little point in using a pointer.    I would just use an array:

	char string[] =  "Hello, world!1\n\r";  //flexible array 
        uart_pstr(string);                      //pass address of named array
        uart_pstr("Hello, world!2\n\r");        //anonymous string
    

Somehow,   I suspect that your mention of PUTTY implies you are using Linux.

This might imply that you are not using ready-made Makefiles.     If you don't link properly,    the strings don't get copied to SRAM from Flash at startup.

 

David.

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

EDIT: I forgot to mention, I use windows, with an autogenerated makefile.

 

I was learned that

char *str = "string"

is identical to

char str[] = "string"

Altough, with str[] the characters are not printed, and with *str they are. (see bottom of this post, the first "hello" becomes garbage using a str[])

 

But well, I changed the code, so it is more compact and reflects the problem better. The new code is at the top of this thread. Since I only changed the main(), I'll put the new main here:

 

int main(void){
	uint8_t i;

	/*init com*/
	usart_init(MYUBRR);

	/*send strings*/
	
	char *strA=  "hello1\n\r\0"; 
	usart_pstr(strA);  /*prints garbage*/
	
	usart_putchar('\n');
	usart_putchar('\r');

	char strB[7]; 
	strB[0]='h';
	strB[1]='e';
	strB[2]='l';
	strB[3]='l';
	strB[4]='o';
	strB[5] = '2';
	strB[6] = '\0';

	usart_pstr(strB); /*prints "hello2"*/

	usart_putchar('\r');  
	usart_putchar('\n'); 

	usart_pstr("hello3\n\r");/*prints garbage*/

	usart_putchar('\r');  
	usart_putchar('\n');

	usart_putchar(strA[0]);  /*prints "hello"*/
	usart_putchar(strA[1]);
	usart_putchar(strA[2]);
	usart_putchar(strA[3]);
	usart_putchar(strA[4]); /**/

	usart_putchar('\r'); 
	usart_putchar('\n');

	for(i=0;i<=4;i++)     /*prints garbage*/
		usart_putchar(strA[i]);
		
	usart_putchar('\n');
	usart_putchar('\r');

	return 0;
}

I expect it to output:

hello1
hello2
hello3
hello
hello

Though what I get is:

▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
hello2
▒▒▒▒▒▒▒▒▒▒
hello
▒▒▒▒▒

 

So the anonymous string results in problems

The last two prints should be identical.:

The first "hello" is printed with explicit indices, while the second "hello" returns garbage, using a dynamic index by using a for-loop

 

Marc

 

Last Edited: Sat. Apr 18, 2015 - 12:19 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

MarcGr wrote:

EDIT: I forgot to mention, I use windows, with an autogenerated makefile.

 

I was learned that

char *str = "string"

is identical to

char str[] = "string"

No,  they are completely different.    One is a named pointer to an anonymous string and the other is a named array that is initialised.

 

Your 'program' is wrong too.

1.  char *strA points to an anonymous string that you subsequently overwrite.

2.  if your Makefile was correct,   the anonymous string would have been copied to SRAM at startup.    (a 10-byte space)

3.  since you are not changing the pointer,   the strA[N] syntax just uses the same area of SRAM.

4.  the startup code copied to a 10-byte space.   Your strA[N] statements 'fit' inside this 10-byte space.   If you had written a 'longer' sequence it could exceed this space.

5.  your strB[N] statements are executed by the main() function.    They do not depend on the startup code initialising SRAM.

6.  so I would expect uart_pstr(strB) to work even with a bad Makefile.

 

My conclusion is that you are not using an AS6 generated Makefile.    Or you have specifically disabled some of the startup code.

 

David.

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

My makefile is correct. It is an autogenerated makefile by AS6.2.

I also tried to build it with the template makefile (http://www.sax.de/~joerg/mfile/)

Both resulted in the same behavior.

 

So your alternative sounds quite plausable. How could I check

whether my startup code is correct, or how could I restore the startup code?

 

I searched around for it, but I found it hard to find something usefull.

 

Thanks for the help :)

 

Marc

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

david.prentice wrote:
MarcGr wrote:

 

EDIT: I forgot to mention, I use windows, with an autogenerated makefile.

 

I was learned that

char *str = "string"

is identical to

char str[] = "string"

No,  they are completely different.    One is a named pointer to an anonymous string and the other is a named array that is initialised.

 

http://c-faq.com/aryptr/index.html

 

In particular: http://c-faq.com/aryptr/aryptreq...

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
Last Edited: Sat. Apr 18, 2015 - 08:37 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

MarcGr wrote:

My makefile is correct. It is an autogenerated makefile by AS6.2.

I also tried to build it with the template makefile (http://www.sax.de/~joerg/mfile/)

Both resulted in the same behavior.

 

So your alternative sounds quite plausable. How could I check

whether my startup code is correct, or how could I restore the startup code?

 

I searched around for it, but I found it hard to find something usefull.

 

Thanks for the help :)

 

Marc

I simply don't believe you.    I have attached the AS6.2 project.   

I suggest that you upload the pre-built HEX file and try it for yourself.

 

Then "Rebuild" it for yourself.    And upload "your" HEX file.

 

Please report the results of both HEX files.

 

As far as I can see,   your program startup is not initialising the data in SRAM.

 

If you still have a problem,   please ZIP up your original AS6.2 project directory and attach it here (like I did).

 

David.

Attachment(s): 

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

Thank you. I uploaded the pre-built .hex.

This resulted in the following output:

 

 

After this I built it myself, resulting in the same output:

 

http://puu.sh/hjjDW/1786850ac3.png

 

I added the project folder, as it was after rebuilt.

 

I program the m2560 as follows:

 

I have an arduino Uno programmed as ISP. I program the mega 2560as follows:

 


C:\Users\Marc\Documents\MarcGr\MarcGr\MarcGr\Debug>avrdude -p m2560 -P com4 -c s
tk500v1 -b 19200 -U flash:w:MarcGr.hex

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.07s

avrdude: Device signature = 0x1e9801
avrdude: NOTE: FLASH memory has been specified, an erase cycle will be performed

         To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file "MarcGr.hex"
avrdude: input file MarcGr.hex auto detected as Intel Hex
avrdude: writing flash (484 bytes):

Writing | ################################################## | 100% 0.49s

avrdude: 484 bytes of flash written
avrdude: verifying flash memory against MarcGr.hex:
avrdude: load data flash data from input file MarcGr.hex:
avrdude: input file MarcGr.hex auto detected as Intel Hex
avrdude: input file MarcGr.hex contains 484 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 0.35s

avrdude: verifying ...
avrdude: 484 bytes of flash verified

avrdude: safemode: Fuses OK

avrdude done.  Thank you.

 

Attachment(s): 

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

Well,   I am confused.

 

I downloaded Putty to my Vista Laptop.    It certainly is unpleasant to use!

 

Then I tried my original HEX file -- which worked perfectly.

And then your build of the HEX file -- which worked perfectly.

 

I did note that any Framing or Parity errors result in your 'streaky box' character.    e.g. if I ran the terminal at 9600 baud.

 

Since you say you are running at 16MHz,   you must have a crystal or ceramic resonator.     So I can't see how you could get Framing errors.

The USART is pretty forgiving about F_CPU accuracy.  e.g. +-2%.

 

It would be nice to know what your hardware is.

Even nicer if I could reproduce your problem.

 

David.

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

It certainly is unpleasant to use!

It's one of those things that grows on you. One of its nice features is how it easily handles id_rsa.pub when connecting with ssh. 

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

As soon as you "open the Serial Terminal",    you have no means of disconnecting or re-configuring it.    It is Close and start from scratch again.

 

Yes,   I am sure that it is excellent for encrypted transmissions.     Just a pain when all you want is simple TTY or VT100.

 

David.

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

As soon as you "open the Serial Terminal",    you have no means of disconnecting or re-configuring it.    It is Close and start from scratch again.

 

Yes,   I am sure that it is excellent for encrypted transmissions.     Just a pain when all you want is simple TTY or VT100.    Preferably with a HEX mode.

 

David.

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

The hardware setup, on which the atmega 2560 is located, is a multiwii pro.

It is a board designed for flying rc airplanes and quads. I'd like to write my own software,

to use it for projects in robotics. Basically it is an atmega 2560 with a bunch of sensors attached to communicate with through I2C.

multiwii pro

(Uninformative picture of the board)

 

 

 

A big problem with this board is the lack of proper documentation. I'll ask around for a proper description of the board layout on their forum http://www.multiwii.com. (once their servers are up again..)

Their descriptions are mainly high-level usage instructions with their software..

 

The 16 MHz was an assumption of mine. Although a uninterrupted sequence of putchar('c')'s worked fine, which makes it probable that it is not a source of trouble or even that the 16MHz assumption is correct.

 

It is programmed by using an Arduino Nano Uno, programmed as ISP by using the code of the arduino examples itself. Could a fabricated programmer make a difference?

 

David, you mentioned earlier possible faulty startup code. Is this included in the .hex file, or is it already present on the atmega?

 

I'm having trouble with finding relavant information about this. I read  a comment of you on https://www.avrfreaks.net/forum/sending-strings-uart-fails-atmega2560,

where you said:

It is pretty obvious that the "Hello World" has not been copied to SRAM by the crts0.o startup code.

Hence the UART just spits out whatever values happen to reside in SRAM at the location that should have been initialised.

(dec 4 2014 3:42 pm)

Is it possible to reload crts0 to the atmega 2560?

 

Thanks again for the help :)

 

Marc

Last Edited: Sun. Apr 19, 2015 - 05:00 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Just show your objcopy that creates the .hex - are you using -j's or -R's? And is .data being included as well as .text?

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

No,   the startup code is part of the HEX.    Your build and my build work fine on my Arduino MEGA2560.

My 'suspicion' was that you were a Linux afficionado that creates a home-grown Makefile.    Hence Cliff asking about -J and -r

 

The only way to get bad comms is 'wrong F_CPU'.

You can check whether your F_CPU is really 16MHz by counting 100 _delay_ms(1000) blinks of an LED against your wristwatch.

 

It is possible (but unlikely) that it is using a 14.7456MHz crystal.     This would give Framing errors if you had built for 16MHz.

OTOH,   I would expect the #3 string to have Framing errors too.

 

Change F_CPU to 14745600 in the "All Configs" Symbols.   Rebuild and try it.

 

If you have a magnifying glass and good eyesight,   you might see some writing on the crystal.    I would trust the blink test more.

 

David.

Last Edited: Sun. Apr 19, 2015 - 05:15 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
"C:\Program Files (x86)\Atmel\Atmel Toolchain\AVR8 GCC\Native\3.4.1061\avr8-gnu-toolchain\bin\avr-objcopy.exe" -O ihex -R .eeprom -R .fuse -R .lock -R .signature -R .user_signatures  "usartTrimmed.elf" "usartTrimmed.hex"

As generated by AS6.2. Since only -R (remove) is used, and no -j (include only). So .data and .text should both be included.

Both Peter and I both built .hex files. Both resulted in incorrect output for me, and correct output for Peter.

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

Good idea! Didn't thought of that.

I will try the blink test. :)

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

I did a blink test, and it timed a minute perfectly (1 blink each second). with F_CPU=16000000.

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

Digging around I saw something that implied that the GPS module communicates with this board at 115,200. That baud rate can't be achieved with a 16MHz crystal.

 

Although the lack of information on this board is shocking.

#1 This forum helps those that help themselves

#2 All grounds are not created equal

#3 How have you proved that your chip is running at xxMHz?

#4 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand." - Heater's ex-boss

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

I am convinced that your board is running at something other than 16MHz.

 

But I can't reproduce the error with Putty at 18700 baud or other magic value.

And your blink timing is easy to achieve good timing accuracy.

 

Have you tried using another Terminal like TeraTerm or Bray?

Then you could display the raw bytes as HEX.

 

David.

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

TeraTerm results in:

 

FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 0D 0A FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 0D 0A 48 65 6C 6C 6F 2C 20 77 6F 72 6C 64 21 33 0A 0D

 

Where 48 - 33 represents "Hello World!3".

 

This is the output from the code/.hex we earlier exchanged.

 

Marc

 

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

I uploaded the arduino bootloader. And programmed the atmega through it. I loaded the following simple sketch:

 

void setup(){
 Serial.begin(19200);
 char str[] = "Hello World!\n\r";
 Serial.write(str);
}

void loop(){
  
}

 

Here it wrote the string with no problems.

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

Digging around a bit, this board is described as being 'Arduino mega'  compatible meaning that it should have a 16MHz crystal on it.

 

One thing I can't see above....what are you using to connect this board to your PC?

#1 This forum helps those that help themselves

#2 All grounds are not created equal

#3 How have you proved that your chip is running at xxMHz?

#4 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand." - Heater's ex-boss

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

MarcGr wrote:

"C:\Program Files (x86)\Atmel\Atmel Toolchain\AVR8 GCC\Native\3.4.1061\avr8-gnu-toolchain\bin\avr-objcopy.exe" -O ihex -R .eeprom -R .fuse -R .lock -R .signature -R .user_signatures  "usartTrimmed.elf" "usartTrimmed.hex"

As generated by AS6.2. Since only -R (remove) is used, and no -j (include only). So .data and .text should both be included.

Both Peter and I both built .hex files. Both resulted in incorrect output for me, and correct output for Peter.

 

I am struggling.    I am guessing that your friend Peter has got an identical board.   Everything works for him.

 

You clearly have duff characters being sent to both Putty and TeraTerm.

I presume that the Arduino output was viewed by Putty or Teraterm.

 

In practice,    all 19200 baud comms will be sent without gaps.    So if the first Start bit is wrong,   the whole sequence is likely to be out of sync.

In practice,    with a Mega AVR,    the chip powers up with 'inactive' UART.    The first byte that is sent will 'sync' correctly.    And so will subsequent bytes.

 

What is really weird is the "/r/n" that appears to be correctly received.

 

Perhaps your crystal is unreliable.    You can simply put your three strings inside a loop,  and call repeatedly with a 1 sec pause.    See if string#3 syncs the subsequent string#1.

 

David.

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

I'm late to this thread but just to say that I went back to the first posted "problem" .zip file and extracted usartTrimmed.hex from it. This is what the binary contains:

$ hexdump -C usart.bin 
00000000  71 c0 00 00 86 c0 00 00  84 c0 00 00 82 c0 00 00  |q...............|
00000010  80 c0 00 00 7e c0 00 00  7c c0 00 00 7a c0 00 00  |....~...|...z...|
00000020  78 c0 00 00 76 c0 00 00  74 c0 00 00 72 c0 00 00  |x...v...t...r...|
00000030  70 c0 00 00 6e c0 00 00  6c c0 00 00 6a c0 00 00  |p...n...l...j...|
00000040  68 c0 00 00 66 c0 00 00  64 c0 00 00 62 c0 00 00  |h...f...d...b...|
00000050  60 c0 00 00 5e c0 00 00  5c c0 00 00 5a c0 00 00  |`...^...\...Z...|
00000060  58 c0 00 00 56 c0 00 00  54 c0 00 00 52 c0 00 00  |X...V...T...R...|
00000070  50 c0 00 00 4e c0 00 00  4c c0 00 00 4a c0 00 00  |P...N...L...J...|
00000080  48 c0 00 00 46 c0 00 00  44 c0 00 00 42 c0 00 00  |H...F...D...B...|
00000090  40 c0 00 00 3e c0 00 00  3c c0 00 00 3a c0 00 00  |@...>...<...:...|
000000a0  38 c0 00 00 36 c0 00 00  34 c0 00 00 32 c0 00 00  |8...6...4...2...|
000000b0  30 c0 00 00 2e c0 00 00  2c c0 00 00 2a c0 00 00  |0.......,...*...|
000000c0  28 c0 00 00 26 c0 00 00  24 c0 00 00 22 c0 00 00  |(...&...$..."...|
000000d0  20 c0 00 00 1e c0 00 00  1c c0 00 00 1a c0 00 00  | ...............|
000000e0  18 c0 00 00 11 24 1f be  cf ef d1 e2 de bf cd bf  |.....$..........|
000000f0  00 e0 0c bf 12 e0 a0 e0  b2 e0 ee ef f1 e0 00 e0  |................|
00000100  0b bf 02 c0 07 90 0d 92  a4 31 b1 07 d9 f7 1c d0  |.........1......|
00000110  74 c0 76 cf 28 e1 20 93  c1 00 90 93 c5 00 80 93  |t.v.(. .........|
00000120  c4 00 08 95 90 91 c0 00  95 ff fc cf 80 93 c6 00  |................|
00000130  08 95 cf 93 df 93 ec 01  89 91 88 23 11 f0 f2 df  |...........#....|
00000140  fb cf df 91 cf 91 08 95  0f 93 1f 93 cf 93 df 93  |................|
00000150  cd b7 de b7 27 97 0f b6  f8 94 de bf 0f be cd bf  |....'...........|
00000160  83 e3 90 e0 d7 df 80 e0  92 e0 e3 df 8a e0 da df  |................|
00000170  8d e0 d8 df 88 e6 89 83  85 e6 8a 83 8c e6 8b 83  |................|
00000180  8c 83 8f e6 8d 83 82 e3  8e 83 1f 82 ce 01 01 96  |................|
00000190  d0 df 8d e0 c7 df 8a e0  c5 df 8a e0 92 e0 c9 df  |................|
000001a0  8d e0 c0 df 8a e0 be df  88 e6 bc df 85 e6 ba df  |................|
000001b0  8c e6 b8 df 8c e6 b6 df  8f e6 b4 df 8d e0 b2 df  |................|
000001c0  8a e0 b0 df 00 e0 12 e0  f8 01 81 91 8f 01 aa df  |................|
000001d0  f2 e0 05 30 1f 07 c1 f7  8a e0 a4 df 8d e0 a2 df  |...0............|
000001e0  80 e0 90 e0 27 96 0f b6  f8 94 de bf 0f be cd bf  |....'...........|
000001f0  df 91 cf 91 1f 91 0f 91  08 95 f8 94 ff cf 68 65  |..............he|
00000200  6c 6c 6f 31 0a 0d 00 00  68 65 6c 6c 6f 33 0a 0d  |llo1....hello3..|
00000210  00 00                                             |..|
00000212

You can clearly see "hello1" and "hello3" in this so they are part of the image in flash.

 

The code that sets up .data (in the supplied LSS) is:

000000f4 <__do_copy_data>:
  f4:	12 e0       	ldi	r17, 0x02	; 2
  f6:	a0 e0       	ldi	r26, 0x00	; 0
  f8:	b2 e0       	ldi	r27, 0x02	; 2
  fa:	ee ef       	ldi	r30, 0xFE	; 254
  fc:	f1 e0       	ldi	r31, 0x01	; 1
  fe:	00 e0       	ldi	r16, 0x00	; 0
 100:	0b bf       	out	0x3b, r16	; 59
 102:	02 c0       	rjmp	.+4      	; 0x108 <__do_copy_data+0x14>
 104:	07 90       	elpm	r0, Z+
 106:	0d 92       	st	X+, r0
 108:	a4 31       	cpi	r26, 0x14	; 20
 10a:	b1 07       	cpc	r27, r17
 10c:	d9 f7       	brne	.-10     	; 0x104 <__do_copy_data+0x10>
 10e:	1c d0       	rcall	.+56     	; 0x148 <main>

That is loading 0x01FE into Z which is the address of the first 'h' in "hello1". This is being copied to 0x0200 (address in X) and the copying continues to 0x0214 so will copy from 0x1FE+0x14 which is 0x212. Again that looks right.

 

So .data will be setup correctly in RAM.

 

Later in the code is:

 166:	80 e0       	ldi	r24, 0x00	; 0
 168:	92 e0       	ldi	r25, 0x02	; 2
 16a:	e3 df       	rcall	.-58     	; 0x132 <usart_pstr>

so it's difficult to see how this will not succeed in printing the string at 0x200 (that is "hello1").

 

About the only thing I can think of is that the CPU being used either doesn't have RAM at 0x200 or it is faulty.

 

(a JTAG debugger would tell you what's going on here in about 3 seconds!).

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

I will try JTAG debugging :)

I found a page (https://github.com/synthetos/PiOCD/wiki/Using-a-Raspberry-Pi-as-a-JTAG-Dongle),

describing how I can set-up my raspberry to do jtag debugging. I will post results as soon as the setup is complete.

 

Thanks,

 

Marc

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

How does that article help? It's about the Rpi doing OpenOCD to debug ARM chips. I thought you said you used a mega2560 (well that's what is in the thread title)? To debug modern AVRs your only option is a debugger from Atmel. They do not make their current debug protocols "open".

 

The best/cheapest way to debug AVR (and 2560 over JTAG in particular) these days is an Atmel-ICE. Most folks choose the "Basic" for $50. Though there is a "bare PCB" version for about $35.

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

I use 115200 at 16mhz all the time, just use 2x mode. Arduino uses it also.

 

Imagecraft compiler user