avrtoolbox: Speed bug, usart0_init bug

Go To Last Post
24 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
#include "c:\avrtoolbox\libavr\source\elementary\serial\serial.h" //"libserial\serial.h"

int main(void)
{

	usart_baud_t usart_baud;
	usart_mode_t usart_mode;
	usart_databits_t usart_databits;
	usart_stopbits_t usart_stopbits;
	usart_parity_t usart_parity;
	usart_flow_control_t usart_flow_control;
	
	// test code 1
	// THIS LINE WAN'T COMPILE
	//usart0_init(usart_baud.baud_9600,F_CPU,usart_mode.usart_mode_asynchronous,usart_databits.8-bit,usart_stopbits.1-stopbit,usart_parity.parity_none,usart_flow_control.flow_none);

	// THIS CAN COMPILE, BUT DON'T WORK 
	usart0_init(9600,8000000,0,8,1,0,0); 
	usart0_put_string("Test");
	
	// BELOW CODE WORK, BUT SPEED IS HALF OF DECLARED !!!!
	// Test code 2
	//serial_begin(9600);
	//serial_out("Hello there this is 4800 speed ");
	 //  ACTUAL SPEED IS 4800 !!!!!!!

	while(1)
	{
	}
}

Generated code I tryed with ISIS Proteus.

Attachment(s): 

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

Is there a bug report hiding in there somewhere?

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

Your error comments aren't enough for us to debug when you don't show the code. :?

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

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

What is ISIS Proteus?

What is you actual crystal frequency?

Smiley

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

Quote:

What is ISIS Proteus?

It's an AVR simulator that can also simulate some external peripherals like LCD and so on. It actually costs £299 but we see an awful lot of people here using non licensed copies.

Those who use it seem convinced that it's a perfect simulation of both AVR and peripherals. It isn't and many of the "problems" we see here involving Proteus are faults in the simulation.

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

Thanks Cliff.

mbruck - any chance of testing this on real hardware?

Smiley

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

I have using ISIS Proteus for several years. It is not perfect for some one, but I NEVER had problem using it.
Less than a month ago I wrote MODBUS application using two serial ports and BascomAVR. I test it on mega162, mega324, and mega2560. BOTH in proteus and real hardware. Not to mention several application using serial port. ALWAYS first tryed on Proteus. So I can trust it.

Quote:
What is you actual crystal frequency?

That's the most often mistake I made. It should be 8000000. I double checked. I'll check again.
Quote:
any chance of testing this on real hardware?

Sorry, I don't have 328p available.
But I will connect this "simulation" to real HyperTerminal using virtual serial ports, and send you reports.

EDIT !

YES, it was Proteus made problem,for first time. Bingo.
As soon as I increase clock to 16000000, I got 9600 working.

Last Edited: Wed. Sep 14, 2011 - 06:15 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I must be going blind - you STILL haven't actually described what the problem is - what you expect and what actually happens?

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

Cliff,

In his code he says that he intended it to run at 9600 but it was running at 4800, thus the change in crystal value fixed it.

Smiley

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

Quote:
I must be going blind

Then you over 45 as I'm. :) (joke)
As you may see, proteus made problem with speed. But as seam only at 8000000 clock.
Beside this, yet another... ok posible problem I found.
It is in this line of code:

   usart_baud_t usart_baud; 
   usart_mode_t usart_mode; 
   usart_databits_t usart_databits; 
   usart_stopbits_t usart_stopbits; 
   usart_parity_t usart_parity; 
   usart_flow_control_t usart_flow_control; 
    
usart0_init(usart_baud.baud_9600,F_CPU,usart_mode.usart_mode_asynchronous,usart_databits.8-bit,usart_stopbits.1-stopbit,usart_parity.parity_none,usart_flow_control.flow_none);

This line return compile error:

Quote:
../serial_a_tester.c:15: error: request for member 'baud_9600' in something not a structure or union
../serial_a_tester.c:15: error: request for member 'usart_mode_asynchronous' in something not a structure or union
../serial_a_tester.c:15: error: expected ')' before numeric constant
../serial_a_tester.c:15: error: too few arguments to function 'usart0_init'

When we see that typedef's are declared in usart.h as:

typedef enum
{
    usart_mode_asynchronous = 0,
    usart_mode_synchronous = 1
} usart_mode_t;


typedef enum
{
    parity_none = 0,
	parity_even = 1,
    parity_odd = 2
} usart_parity_t;

typedef enum
{
	baud_1200 = 1200,
	baud_2400 = 2400,
	baud_4800 = 4800,
	baud_9600 = 9600,
	baud_19200 = 19200,
	baud_38400 = 38400,
	baud_57600 = 57600 // 3/17/11 JWP
} usart_baud_t;

// JWP 3/21/11
typedef enum
{
    bit5 = 5,
    bit6 = 6,
    bit7 = 7,
    bit8 = 8,
    bit9 = 9
} usart_databits_t;

typedef enum
{
	stopbit1 = 1,
	stopbit2 = 2
} usart_stopbits_t;	

typedef enum
{
    flow_none = 0,
    flow_sw = 1,
    flow_hw = 2
} usart_flow_control_t;

typedef struct
{
    usart_flow_control_t flow_control;
    uint8_t flow_out;
    uint8_t flow_in;
} usart_flow_t;

I can't figure out where is the problem with e.g. usart_baud.baud_9600 parametar?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
usart_baud.baud_9600

It's an enum not a member of a struct?!? Try:

usart0_init(baud_9600, F_CPU, usart_mode_asynchronous, 8-bit, 1-stopbit, parity_none, flow_none); 

Except that C does not allow symbols to start with a digit so as shown in the typedef's it should really be:

usart0_init(baud_9600, F_CPU, usart_mode_asynchronous, bit8, stopbit1, parity_none, flow_none); 

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

GEEE... You fast as space rocket... I'll try
...
Results:

../serial_a_tester.c:18: error: 'bit' undeclared (first use in this function)
../serial_a_tester.c:18: error: (Each undeclared identifier is reported only once
../serial_a_tester.c:18: error: for each function it appears in.)
../serial_a_tester.c:18: error: 'stopbit' undeclared (first use in this function)

.... edit after one minute
It seam mr. Smiley is also over 45 :)
In usart.h description he made small mistake:

Quote:
\param databits uint8_t Number of data bits
\code
typedef enum
{
5-bit = 5,
6-bit = 6,
7-bit = 7,
8-bit = 8,
9-bit = 9
} usart_databits_t;
\endcode

Quote:
\param stopbits uint8_t Number of stop bits
\code
typedef enum
{
1-stopbit = 1,
2-stopbit = 6,
} usart_stopbits_t;
\endcode

And I read that when calling usart0_init(...
This is something easy to correct.

Last Edited: Wed. Sep 14, 2011 - 07:00 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Did you use the 1st or 2nd suggestion I made? Only the second would work. In the first C would read "8-bit" as subtract a variable called 'bit' from the digit 8. There is no enum called 'bit' hence the error you now see.

I was simply saying that it looked like you had guessed the names usart_databits.8-bit, usart_stopbits.1-stopbit which I initially reduced to 8-bit, 1-stopbit because they were never valid.

So try the 2nd line I gave above.

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

Clawson, it is not easy to follow your suggestion so fast. Maybe you can take a coffe break?

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

It work now after usart0_init parameters correction. Tnx...
Oke, my rewrited code now is:

#include "c:\avrtoolbox\libavr\source\elementary\serial\serial.h" //"libserial\serial.h"

int main(void)
{
	// First way to send somethings to serial port
	// IT WORKS
	//serial_begin(9600);
	//serial_out("Hello there, I am alive!");

	// Second way to send somethings to serial port
	// NOT WORK. Nothing get out of micro.  Why ?
	usart0_init(baud_9600, F_CPU, usart_mode_asynchronous, bit8, stopbit1, parity_none, flow_none);
	usart0_put_pgm_string("Test");
	usart0_put_string("Test");
	
	while(1)
	{
	}
}

I believe it's self-explanatory question.

Last Edited: Wed. Sep 14, 2011 - 07:15 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

usart0_put_pgm_string("Test");

The _pgm_ in that name suggests the parameter should be in PROGMEM. Have you tried:

   usart0_put_pgm_string(PSTR("Test")); 

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

Quote:
usart0_put_pgm_string(PSTR("Test"));

Yes.. Still nothing. I believe serial tx and rx interrupts should be enabled. (?)

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

I have a usart tester program that shows how to use this code, but it isn't in the trunk despite the fact that my local TortoiseSVN says it it updated properly, so I'll see if I can figure out what is going on with that and in the meantime I'll attach the tester directory here.

Smiley

Attachment(s): 

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

Sorry but this is getting confusing.

I just saw that my doxygen doc isn't up to date so I'll fix that ASAP, but in the meantime the comment that is most relevant:

Quote:

Example:
\code
// Define string outside any function
const char pgm_str1[] PROGMEM = "This is a program memory string defined outside any function.\r";
...
// Put the program memory string into the transmit buffer
usart0_put_pgm_string(pgm_str1);
// Transmit it
usart0_send();

// Use with a string intialized in the function
usart0_put_pgm_string(PSTR("This is a program memory string using PSTR within a function.\r"));
usart0_send();

\endcode

The usart_putxxx only puts to the ring buffer, but doesn't send anything.

EDIT:
I'm doing something wrong with my TortiseSVN and the repository is not in synch with my local directories even though it says they are. I started another thread on this but in the meantime please be patient.

EDIT EDIT:
I left off the doxygen doc for the usart0_put_pgm_string function, but now it is in the repository and I'll put a link to this on the avrtoolbox mainpage so that it can be opened there.

Smiley

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

It seam you have lots of problems wit SVN and doxygen...

Quote:
in the meantime please be patient

Avrtoolbox is great job. I know you give so much energy to us. At least we can be patient a bit.
But it's not easy always to be patient. :) I have using BascomAVR several years, and several time I have tried to switch to C. But every time some new project jumps in and it's easy to solve it in language I know. Now, even I have project to finish I decided to learn C. Whatever cost.
First step is serial library. So I can spare at least one hour every day to test avrtoolbox serial library until we found it's stable and reliable.

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

Since you are coming from BascomAVR you might find that going directly to the Arduino and getting familiar with that first will provide a good transition to C which you can tackle after you've gotten good with Arduino. This isn't just you, this is what I recommend to all folks first approaching C for microcontrollers.

Smiley

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

Quote:
going directly to the Arduino and getting familiar with that first will provide a good transition to C which you can tackle after you've gotten good with Arduino.
Really? Let me read that again...
I'm not reading this right am I? You suggest learning an OOPS paradigm with a very high level interface, before doing everything by hand and back porting classes to singleton implementations?
Strip away the Arduino libraries and your students will be up the creak without your paddle.
Surely, if your going to teach C++, then teach C++?

--greg
Still learning, don't shout at me, educate me.
Starting the fire is easy; the hardest part is learning how to keep the flame!

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

I have changed usart.h buffer's len definion to:

#ifndef USART0_RECEIVE_BUFFER_LEN
    #define USART0_RECEIVE_BUFFER_LEN   127
#endif

and,

#ifndef USART0_TRANSMIT_BUFFER_LEN
    #define USART0_TRANSMIT_BUFFER_LEN  127
#endif

Now buffer's len can be different from project to project.
Also, in some communications protocols, packet can be bigger than 256 bytes... so

uint8_t usart0_transmit_buffer[USART0_TRANSMIT_BUFFER_LEN];

wan't be enough...
What if I try?

uint16_t usart0_transmit_buffer[USART0_TRANSMIT_BUFFER_LEN];

Would transmit and receive logic follow increased size?

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

gregsmithcts wrote:
Quote:
going directly to the Arduino and getting familiar with that first will provide a good transition to C which you can tackle after you've gotten good with Arduino.
Really? Let me read that again...
I'm not reading this right am I? You suggest learning an OOPS paradigm with a very high level interface, before doing everything by hand and back porting classes to singleton implementations?
Strip away the Arduino libraries and your students will be up the creak without your paddle.
Surely, if your going to teach C++, then teach C++?
I don't mean get familiar with anything below the actual Arduino library. The C++ dot notation for the Serial library may cause a moments confusion, but I expect most folks will skim on past it when they decide to move on to regular C programming. I'd never recommend any novice going into the guts of Arduino for various reasons I'll forebear to mention in public.

mbruck wrote:
Would transmit and receive logic follow increased size?
It should. But since these buffers are allocated on SRAM, then two 256 buffers uses 512 bytes of SRAM which would be all the SRAM on an ATmega48 and half that on the ATmega88 and 168 - so you would need to be aware of you devices SRAM size and how much the rest of your code might need.

Smiley