if statement not picking up on variable change

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

THis is for an XMEGA32E5 using Codevision.

 

I am trying to sense when a character has appeared in teh buffer - just a simple test - and echo it back. After snooping around I came across this thread:

 

https://www.avrfreaks.net/forum/...

 

Which is based on teh mega32 but its pretty much teh same code for the XMEGA.

 

I tried Davids suggestion of a #define like this:

#define DATARECEIVED() (rx_counter_usartc0 != 0)

and in the main loop:

void main(void)
{
  puts("Bite Me!");    //This PRINTS to SERIAL PORT

while (1)
      {
      if (DATARECEIVED()) putchar(getchar());  //This does nothing.  No output

      }; 
}

 

 

But there is no echo back.

 

I even tried this to see if it at least fires:

void main(void)
{
  puts("Bite Me!");    //This PRINTS to SERIAL PORT

while (1)
      {
      if(DATARECEIVED())
      {
	putchar('Y');  //Still does not print
     
      }

      } 
}

And still no output from teh serial port.

 

Very troubling

 

Jim

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

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

Make a simple c0omplete program, and paste that.  The generated code for, at least, main().

 

So far, while your program is not signalling to your satisfaction, how do we know that

jgmdesign wrote:

rx_counter_usartc0

is NOT equal to 0?

 

For the signalling, do a simple put without the trigger -- do you see stuff on the TX?

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

Hey Lee!

 

theusch wrote:

So far, while your program is not signalling to your satisfaction, how do we know that

jgmdesign wrote:

 

rx_counter_usartc0

 

is NOT equal to 0?

 

From teh debug window:

 

It's not equal to zero.

 

theusch wrote:
For the signalling, do a simple put without the trigger -- do you see stuff on the TX?

Yes, I do.

 

Jim

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

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

Is rx_counter_usartc0 modified in an ISR?

Is it declared as voloatile?

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

Chuck99 wrote:

Is rx_counter_usartc0 modified in an ISR?

Is it declared as voloatile?

 

YEs.  From the .h file:

#ifndef _USARTS_INIT_INCLUDED_
#define _USARTS_INIT_INCLUDED_

// Disable an USART
void usart_disable(USART_t *pu);
// USARTC0 is used as the default input device by the 'getchar' function
// #define _ALTERNATE_GETCHAR_ is inserted for this purpose
// in the main program source file before #include <stdio.h>
char getchar(void);
// USARTC0 is used as the default output device by the 'putchar' function
// #define _ALTERNATE_PUTCHAR_ is inserted for this purpose
// in the main program source file before #include <stdio.h>
void putchar(char c);
// USARTC0 initialization
void usartc0_init(void);
// USARTC0 Receiver buffer
#define RX_BUFFER_SIZE_USARTC0 24

extern char rx_buffer_usartc0[RX_BUFFER_SIZE_USARTC0];
extern volatile unsigned char usartc0_eol;

#if RX_BUFFER_SIZE_USARTC0 <= 256
extern volatile unsigned char rx_wr_index_usartc0,rx_rd_index_usartc0;
#else
extern volatile unsigned int rx_wr_index_usartc0,rx_rd_index_usartc0;
#endif

#if RX_BUFFER_SIZE_USARTC0 < 256
extern volatile unsigned char rx_counter_usartc0;
#else
extern volatile unsigned int rx_counter_usartc0;
#endif

// This flag is set on USARTC0 Receiver buffer overflow
extern bit rx_buffer_overflow_usartc0;
// USARTC0 Transmitter buffer
#define TX_BUFFER_SIZE_USARTC0 128
extern char tx_buffer_usartc0[TX_BUFFER_SIZE_USARTC0];

#if TX_BUFFER_SIZE_USARTC0 <= 256
extern volatile unsigned char tx_wr_index_usartc0,tx_rd_index_usartc0;
#else
extern volatile unsigned int tx_wr_index_usartc0,tx_rd_index_usartc0;
#endif

#if TX_BUFFER_SIZE_USARTC0 < 256
extern volatile unsigned char tx_counter_usartc0;
#else
extern volatile unsigned int tx_counter_usartc0;
#endif

#endif

Jim

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

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

Here is the main file contents:

/*******************************************************
This program was created by the CodeWizardAVR V3.38
Automatic Program Generator
© Copyright 1998-2019 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com

Project :
Version :
Date    : 3/10/2020
Author  :
Company :
Comments: 

Chip type               : ATxmega32E5
Program type            : Application
AVR Core Clock frequency: 11.059200 MHz
Memory model            : Small
Data Stack size         : 1024
*******************************************************/

// I/O Registers definitions
#include <xmega32e5.h>
#include <delay.h>
// USARTC0 is used as the default input
// device by the 'getchar' function.
#define _ALTERNATE_GETCHAR_
// USARTC0 is used as the default output
// device by the 'putchar' function.
#define _ALTERNATE_PUTCHAR_
// Standard Input/Output functions
#define DATARECEIVED()  (rx_counter_usartc0 != 0)
//indicates data ready to read
#include <stdio.h>

// Clock System initialization function
#include "clock_init.h"

// Event System initialization function
#include "event_system_init.h"

// I/O Ports initialization function
#include "ports_init.h"

// Timers/Counters initialization functions
#include "timers_init.h"

// RTC initialization function
#include "rtc_init.h"

// Watchdog Timer initialization function
#include "watchdog_init.h"

// USARTs initialization functions
#include "usarts_init.h"

// ADC initialization functions
#include "adc_init.h"

// Analog Comparator(s) initialization function(s)
#include "analog_comp_init.h"

// SPI initialization functions
#include "spi_init.h"

// TWI initialization functions
#include "twi_init.h"

// Declare your global variables here

void main(void)
{
// Declare your local variables here
unsigned char n;

// Interrupt system initialization
// Optimize for speed
#pragma optsize-
// Make sure the interrupts are disabled
#asm("cli")
// Low level interrupt: On
// Round-robin scheduling for low level interrupt: On
// Medium level interrupt: Off
// High level interrupt: Off
// The interrupt vectors will be placed at the start of the Application FLASH section
n=(PMIC.CTRL & (~(PMIC_RREN_bm | PMIC_IVSEL_bm | PMIC_HILVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_LOLVLEN_bm))) |
	PMIC_LOLVLEN_bm | PMIC_RREN_bm;
CCP=CCP_IOREG_gc;
PMIC.CTRL=n;
// Set the default priority for round-robin scheduling
PMIC.INTPRI=0x00;
// Restore optimization for size if needed
#pragma optsize_default

// Watchdog timer initialization
watchdog_init();

// System clocks initialization
system_clocks_init();

// Event system initialization
event_system_init();

// Ports initialization
ports_init();

// Timer/Counter TCC4 initialization
tcc4_init();

// Timer/Counter TCC5 is disabled
tc5_disable(&TCC5);

// Timer/Counter TCD5 is disabled
tc5_disable(&TCD5);

// RTC initialization
rtcxm_init();

// USARTC0 initialization
usartc0_init();

// USARTD0 is disabled
usart_disable(&USARTD0);

// SPIC initialization
spic_init();

// TWIC initialization
twic_init();

// ADCA initialization
adca_init();

// DACA is disabled
DACA.CTRLA=0;

// Analog Comparator(s) for PORTA initialization
aca_init();

// Globally enable interrupts
#asm("sei")

puts("Bite Me!");

while (1)
      { 

	if (DATARECEIVED()) putchar(getchar());  //This does nothing.  No output
      }

}

Jim

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

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

theusch wrote:
The generated code for, at least, main().

Lee are you looking for the source, or teh compiled assembly code?

 

JIm

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

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

Well, it's late and I am getting tired.  Not sure why the code is ignoring the USART variables which are declared volatile, and I can see in the watch window.

 

Attachment removed - jgm

 

Jim

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

Last Edited: Wed. Mar 11, 2020 - 10:42 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

jgmdesign wrote:
why the code is ignoring
Does the Asm really show no access to the variable locations in question? (AFAICS that's the only way it could be "ignored"). Or are you saying that after access it is not performing the right data comparison? Again this should all be visible in the Asm.

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

clawson wrote:

Does the Asm really show no access to the variable locations in question? (AFAICS that's the only way it could be "ignored"). Or are you saying that after access it is not performing the right data comparison? Again this should all be visible in the Asm.

Its not performing the right data comparison.

 

jgmdesign wrote:

if (DATARECEIVED()) putchar(getchar()); 

Never fires.  I have also tried:

if(rx_counter_usartc0 != 0) putchar(getchar());

I'll pull the ASM and see what it reads.

 

Thanks

Jim

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

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

Here is the ASM code:

                 _0x4:
                 ; 0000 0094       {
                 ; 0000 0095        if (DATARECEIVED()) putchar(getchar());  //This does nothing.  No output
0000bf 91e0 2423 	LDS  R30,_rx_counter_usartc0
0000c1 30e0      	CPI  R30,0
0000c2 f019      	BREQ _0x7
0000c3 d1bf      	RCALL _getchar
0000c4 2fae      	MOV  R26,R30
0000c5 d203      	RCALL _putchar
                 ; 0000 0096 
                 ; 0000 0097 
                 ; 0000 0098       }
                 _0x7:
0000c6 cff8      	RJMP _0x4
                 ; 0000 0099 }
                 _0x8:
0000c7 cfff      	RJMP _0x8
                 ; .FEND

it looks like it's right.

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

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

So the implication then is that rx_counter_usartc0 does contain 0x00 when this line is encountered (or getchar is not returning something that is printable?)

 

If you actually put a breakpoint on 00BF and single step what happens, what is in R30 at the time ?

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

clawson wrote:

So the implication then is that rx_counter_usartc0 does contain 0x00 when this line is encountered (or getchar is not returning something that is printable?)

 

No, take a look at Post #3.  I will send a few characters from my terminal to increment rx_counter_usartc0, which should trigger the IF statement.  I showed the Watch window that shows that rx_counter_usartc0 is NOT zero which should satisfy the IF statement.

 

Getchar() is not printing what is in the buffer - which I can see has the characters I typed in teh terminal.

 

JIm

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

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

Is rx_counter_usartc0 declared and initialized within a .c file?

David

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

frog_jr wrote:

Is rx_counter_usartc0 declared and initialized within a .c file?

Yes,


#if RX_BUFFER_SIZE_USARTC0 < 256
volatile unsigned char rx_counter_usartc0=0;
#else
volatile unsigned int rx_counter_usartc0=0;
#endif

 

in the usarts_init.c file

 

and in the usarts.init.h we have:


#if RX_BUFFER_SIZE_USARTC0 < 256
extern volatile unsigned char rx_counter_usartc0;
#else
extern volatile unsigned int rx_counter_usartc0;
#endif

 

 

THis is what has me scratching my head.  CV wizard looks to have set everything up properly.

 

Jim

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

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

clawson wrote:
If you actually put a breakpoint on 00BF and single step what happens, what is in R30 at the time ?

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

Cliff,

Not to sound ignorant, but I have never done what you are asking, but I opened the .asm file and put the breakpoint on:

 

LDS  R30,_rx_counter_usartc0

and ran the code (its an Atmel ICE connected to my STK600 with an actual x32E5 on board so its real hardware).  I typed a few characters on my keyboard and the breakpoint does not fire, nor can I single step.  The 'rx_counter_usartc0' does indeed increment as it shows in teh watch window though.  R30 still shows 0x00 so its like the variable is not being looked at.

 

This is very frustrating.

 

JIm

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

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

Time to post a small complete program for the Freaks can take a detailed look Jim!

 

Jim

 

FF = PI > S.E.T

 

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

ki0bk wrote:

Time to post a small complete program for the Freaks can take a detailed look Jim!

 

Jim

Here is the main file:

/*******************************************************
This program was created by the CodeWizardAVR V3.38 
Automatic Program Generator
© Copyright 1998-2019 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com

Project : 
Version : 
Date    : 3/10/2020
Author  : 
Company : 
Comments: 


Chip type               : ATxmega32E5
Program type            : Application
AVR Core Clock frequency: 11.059200 MHz
Memory model            : Small
Data Stack size         : 1024
*******************************************************/

// I/O Registers definitions
#include <xmega32e5.h>

// USARTC0 is used as the default input
// device by the 'getchar' function.
#define _ALTERNATE_GETCHAR_
// USARTC0 is used as the default output
// device by the 'putchar' function.
#define _ALTERNATE_PUTCHAR_
//macro for picking up data received
#define DATARECEIVED() (rx_counter_usartc0 != 0)
// Standard Input/Output functions
#include <delay.h>
#include <stdio.h>

// Clock System initialization function
#include "clock_init.h"

// Event System initialization function
#include "event_system_init.h"

// I/O Ports initialization function
#include "ports_init.h"

// Timers/Counters initialization functions
#include "timers_init.h"

// RTC initialization function
#include "rtc_init.h"

// Watchdog Timer initialization function
#include "watchdog_init.h"

// USARTs initialization functions
#include "usarts_init.h"

// ADC initialization functions
#include "adc_init.h"

// Analog Comparator(s) initialization function(s)
#include "analog_comp_init.h"

// SPI initialization functions
#include "spi_init.h"

// TWI initialization functions
#include "twi_init.h"

// Declare your global variables here

void main(void)
{
// Declare your local variables here
unsigned char n;
int j = 1;
// Interrupt system initialization
// Optimize for speed
#pragma optsize- 
// Make sure the interrupts are disabled
#asm("cli")
// Low level interrupt: On
// Round-robin scheduling for low level interrupt: On
// Medium level interrupt: Off
// High level interrupt: Off
// The interrupt vectors will be placed at the start of the Application FLASH section
n=(PMIC.CTRL & (~(PMIC_RREN_bm | PMIC_IVSEL_bm | PMIC_HILVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_LOLVLEN_bm))) |
	PMIC_LOLVLEN_bm | PMIC_RREN_bm;
CCP=CCP_IOREG_gc;
PMIC.CTRL=n;
// Set the default priority for round-robin scheduling
PMIC.INTPRI=0x00;
// Restore optimization for size if needed
#pragma optsize_default

// Watchdog timer initialization
watchdog_init();

// System clocks initialization
system_clocks_init();

// Event system initialization
event_system_init();

// Ports initialization
ports_init();

// Timer/Counter TCC4 initialization
tcc4_init();

// Timer/Counter TCC5 is disabled
tc5_disable(&TCC5);

// Timer/Counter TCD5 initialization
tcd5_init();

// RTC initialization
rtcxm_init();

// USARTC0 initialization
usartc0_init();

// USARTD0 is disabled
usart_disable(&USARTD0);

// SPIC initialization
spic_init();

// TWIC initialization
twic_init();

// ADCA initialization
adca_init();

// DACA is disabled
DACA.CTRLA=0;

// Analog Comparator(s) for PORTA initialization
aca_init();

// Globally enable interrupts
#asm("sei")

puts("BITE ME!");   //This PRINTS to SERIAL PORT



while (1)
      {
         if (DATARECEIVED()) putchar(getchar());  //This does nothing.  No output
	   
		

      }
}

Here is the USARSts_init.h file:

/*******************************************************
USARTs initialization created by the
CodeWizardAVR V3.38 Automatic Program Generator
© Copyright 1998-2019 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com

Project : 
*******************************************************/

#ifndef _USARTS_INIT_INCLUDED_
#define _USARTS_INIT_INCLUDED_

// Disable an USART
void usart_disable(USART_t *pu);
// USARTC0 is used as the default input device by the 'getchar' function
// #define _ALTERNATE_GETCHAR_ is inserted for this purpose
// in the main program source file before #include <stdio.h>
char getchar(void);
// USARTC0 is used as the default output device by the 'putchar' function
// #define _ALTERNATE_PUTCHAR_ is inserted for this purpose
// in the main program source file before #include <stdio.h>
void putchar(char c);
// USARTC0 initialization
void usartc0_init(void);
// USARTC0 Receiver buffer
#define RX_BUFFER_SIZE_USARTC0 24
extern char rx_buffer_usartc0[RX_BUFFER_SIZE_USARTC0];


#if RX_BUFFER_SIZE_USARTC0 <= 256
extern volatile unsigned char rx_wr_index_usartc0,rx_rd_index_usartc0;
#else
extern volatile unsigned int rx_wr_index_usartc0,rx_rd_index_usartc0;
#endif

#if RX_BUFFER_SIZE_USARTC0 < 256
extern volatile unsigned char rx_counter_usartc0;
#else
extern volatile unsigned int rx_counter_usartc0;
#endif

// This flag is set on USARTC0 Receiver buffer overflow
extern bit rx_buffer_overflow_usartc0;
// USARTC0 Transmitter buffer
#define TX_BUFFER_SIZE_USARTC0 32
extern char tx_buffer_usartc0[TX_BUFFER_SIZE_USARTC0];

#if TX_BUFFER_SIZE_USARTC0 <= 256
extern volatile unsigned char tx_wr_index_usartc0,tx_rd_index_usartc0;
#else
extern volatile unsigned int tx_wr_index_usartc0,tx_rd_index_usartc0;
#endif

#if TX_BUFFER_SIZE_USARTC0 < 256
extern volatile unsigned char tx_counter_usartc0;
#else
extern volatile unsigned int tx_counter_usartc0;
#endif

#endif

And teh USARTS_INIT.c file:

/*******************************************************
USARTs initialization created by the
CodeWizardAVR V3.38 Automatic Program Generator
© Copyright 1998-2019 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com

Project : 
*******************************************************/

// I/O Registers definitions
#include <xmega32e5.h>

// USARTs initialization functions
#include "usarts_init.h"

// Disable an USART
void usart_disable(USART_t *pu)
{
// Rx and Tx are off
pu->CTRLB=0;
// Ensure that all interrupts generated by the USART are off
pu->CTRLA=0;
}

// USARTC0 initialization
void usartc0_init(void)
{
// Note: The correct PORTC direction for the RxD, TxD and XCK signals
// is configured in the ports_init function.

// Transmitter is enabled
// Set TxD=1
PORTC.OUTSET=0x08;

// Communication mode: Asynchronous USART
// Data bits: 8
// Stop bits: 1
// Parity: Disabled
USARTC0.CTRLC=USART_CMODE_ASYNCHRONOUS_gc | USART_PMODE_DISABLED_gc | USART_CHSIZE_8BIT_gc;

// Receive complete interrupt: Low Level
// Transmit complete interrupt: Low Level
// Data register empty interrupt: Disabled
USARTC0.CTRLA=(USARTC0.CTRLA & (~(USART_RXCINTLVL_gm | USART_TXCINTLVL_gm | USART_DREINTLVL_gm))) |
	USART_RXCINTLVL_LO_gc | USART_TXCINTLVL_LO_gc | USART_DREINTLVL_OFF_gc;

// Required Baud rate: 115200
// Real Baud Rate: 115200.0 (x1 Mode), Error: 0.0 %
USARTC0.BAUDCTRLA=0x80;
USARTC0.BAUDCTRLB=((0x09 << USART_BSCALE_gp) & USART_BSCALE_gm) | 0x02;

// Receiver: On
// Transmitter: On
// Double transmission speed mode: Off
// Multi-processor communication mode: Off
USARTC0.CTRLB=(USARTC0.CTRLB & (~(USART_RXEN_bm | USART_TXEN_bm | USART_CLK2X_bm | USART_MPCM_bm | USART_TXB8_bm))) |
	USART_RXEN_bm | USART_TXEN_bm;
}

// Note: RX_BUFFER_SIZE_USARTC0 is #define-d in 'usarts_init.h' with the value 24
char rx_buffer_usartc0[RX_BUFFER_SIZE_USARTC0];

#if RX_BUFFER_SIZE_USARTC0 <= 256
volatile unsigned char rx_wr_index_usartc0=0,rx_rd_index_usartc0=0;
#else
volatile unsigned int rx_wr_index_usartc0=0,rx_rd_index_usartc0=0;
#endif

#if RX_BUFFER_SIZE_USARTC0 < 256
volatile unsigned char rx_counter_usartc0=0;
#else
volatile unsigned int rx_counter_usartc0=0;
#endif

// This flag is set on USARTC0 Receiver buffer overflow
bit rx_buffer_overflow_usartc0=0;

// USARTC0 Receiver interrupt service routine
interrupt [USARTC0_RXC_vect] void usartc0_rx_isr(void)
{
unsigned char status;
char data;

status=USARTC0.STATUS;
data=USARTC0.DATA;
if ((status & (USART_FERR_bm | USART_PERR_bm | USART_BUFOVF_bm)) == 0)
   {
   rx_buffer_usartc0[rx_wr_index_usartc0++]=data;
   
#if RX_BUFFER_SIZE_USARTC0 == 256
   // special case for receiver buffer size=256
   if (++rx_counter_usartc0 == 0) rx_buffer_overflow_usartc0=1;
#else
   if (rx_wr_index_usartc0 == RX_BUFFER_SIZE_USARTC0) rx_wr_index_usartc0=0;
   if (++rx_counter_usartc0 == RX_BUFFER_SIZE_USARTC0)
      {
      rx_counter_usartc0=0;
      rx_buffer_overflow_usartc0=1;
      }
#endif
   }
}

// Receive a character from USARTC0
// USARTC0 is used as the default input device by the 'getchar' function
// #define _ALTERNATE_GETCHAR_ is inserted for this purpose
// in the main program source file before #include <stdio.h>
#pragma used+
char getchar(void)
{
char data;

while (rx_counter_usartc0==0);
data=rx_buffer_usartc0[rx_rd_index_usartc0++];
#if RX_BUFFER_SIZE_USARTC0 != 256
if (rx_rd_index_usartc0 == RX_BUFFER_SIZE_USARTC0) rx_rd_index_usartc0=0;
#endif
#asm("cli")
--rx_counter_usartc0;
#asm("sei")
return data;
}
#pragma used-

// Note: TX_BUFFER_SIZE_USARTC0 is #define-d in 'usarts_init.h' with the value 32
char tx_buffer_usartc0[TX_BUFFER_SIZE_USARTC0];

#if TX_BUFFER_SIZE_USARTC0 <= 256
volatile unsigned char tx_wr_index_usartc0=0,tx_rd_index_usartc0=0;
#else
volatile unsigned int tx_wr_index_usartc0=0,tx_rd_index_usartc0=0;
#endif

#if TX_BUFFER_SIZE_USARTC0 < 256
volatile unsigned char tx_counter_usartc0=0;
#else
volatile unsigned int tx_counter_usartc0=0;
#endif

// USARTC0 Transmitter interrupt service routine
interrupt [USARTC0_TXC_vect] void usartc0_tx_isr(void)
{
if (tx_counter_usartc0)
   {
   --tx_counter_usartc0;
   USARTC0.DATA=tx_buffer_usartc0[tx_rd_index_usartc0++];
#if TX_BUFFER_SIZE_USARTC0 != 256
   if (tx_rd_index_usartc0 == TX_BUFFER_SIZE_USARTC0) tx_rd_index_usartc0=0;
#endif
   }
}

// Write a character to the USARTC0 Transmitter buffer
// USARTC0 is used as the default output device by the 'putchar' function
// #define _ALTERNATE_PUTCHAR_ is inserted for this purpose
// in the main program source file before #include <stdio.h>
#pragma used+
void putchar(char c)
{
while (tx_counter_usartc0 == TX_BUFFER_SIZE_USARTC0);
#asm("cli")
if (tx_counter_usartc0 || ((USARTC0.STATUS & USART_DREIF_bm)==0))
   {
   tx_buffer_usartc0[tx_wr_index_usartc0++]=c;
#if TX_BUFFER_SIZE_USARTC0 != 256
   if (tx_wr_index_usartc0 == TX_BUFFER_SIZE_USARTC0) tx_wr_index_usartc0=0;
#endif
   ++tx_counter_usartc0;
   }
else
   USARTC0.DATA=c;
#asm("sei")
}
#pragma used-

JIm

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

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

If it doesn't hit the break on that then it's simply never getting as far as the if() in the first place. So something before this is either blocking or skipping it.

 

I take it the puts("Bit me") is seen to execute ?

 

I wonder if it's swamped in ISRs ?? I know ISR return allows one opcode from main() to execute each time so eventually it should execute everything in the while(1) but perhaps it is taking a very long time ?

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

clawson wrote:

If it doesn't hit the break on that then it's simply never getting as far as the if() in the first place. So something before this is either blocking or skipping it.

 

I take it the puts("Bit me") is seen to execute ?

 

I wonder if it's swamped in ISRs ?? I know ISR return allows one opcode from main() to execute each time so eventually it should execute everything in the while(1) but perhaps it is taking a very long time ?

 

Ok, heres an update that might have some meat on it....

 

clawson wrote:
I take it the puts("Bit me") is seen to execute ?

Yes, BITE ME! prints.

 

clawson wrote:
If it doesn't hit the break on that then it's simply never getting as far as the if() in the first place. So something before this is either blocking or skipping it.

When I hit RUN and do nothing for a few seconds then hit PAUSE the window shows that the application is sitting in this spot:

while (rx_counter_usartc0==0);

which is a problem because at application launch, "rx_counter_usartc0" will be zero so the program is just sitting there meaning that the code is stuck and if I had anything else running it wont until a character is received...which is not constant...maybe once every 30 minutes or so something will come in.

 

Ok, so I type a character (the letter 'c') and then hit PAUSE and now 'rx_counter_usartc0' is at 0x01, R30 has 0x63 (the hexadecimal number for 'c' and R28 has the number 0x01 in it?!  WTH?

 

But even though R30 does not have the number I would think should be there, it is not equal to zero so the if statement should execute.

 

Grrr....

 

JIm

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

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

jgmdesign wrote:
which is a problem because at application launch, "rx_counter_usartc0" will be zero so the program is just sitting there meaning that the code is stuck and if I had anything else running it wont until a character is received...which is not constant...maybe once every 30 minutes or so something will come in.
So what is the code behind THAT line? As rx_counter_usartc0 must be "volatile" then the code should be something like:

while_wait:
    LDS R24, rx_counter_c0
    OR R24, R24
    BRNE carry_on
    RJMP while_wait
carry_on:

if the loop does not contain LD or LDS or whatever to actually keep re-reading the volatile then that would be a bit of a problem !

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

Cliff,

I pulled the entire ASM for the USART.  I am no expert, but it looks like the getchar() function is missing:

;/*******************************************************
;USARTs initialization created by the
;CodeWizardAVR V3.38 Automatic Program Generator
;© Copyright 1998-2019 Pavel Haiduc, HP InfoTech s.r.l.
;http://www.hpinfotech.com
;
;Project :
;*******************************************************/
;
;// I/O Registers definitions
;#include <xmega32e5.h>
;
;// USARTs initialization functions
;#include "usarts_init.h"
;
;// Disable an USART
;void usart_disable(USART_t *pu)
; 0007 0012 {

	.CSEG
_usart_disable:
; .FSTART _usart_disable
; 0007 0013 // Rx and Tx are off
; 0007 0014 pu->CTRLB=0;
	ST   -Y,R17
	ST   -Y,R16
	MOVW R16,R26
;	*pu -> R16,R17
	ADIW R26,3
	LDI  R30,LOW(0)
	ST   X,R30
; 0007 0015 // Ensure that all interrupts generated by the USART are off
; 0007 0016 pu->CTRLA=0;
	MOVW R26,R16
	ADIW R26,2
_0x2080004:
	ST   X,R30
; 0007 0017 }
_0x2080003:
	LD   R16,Y+
	LD   R17,Y+
	RET
; .FEND
;
;// USARTC0 initialization
;void usartc0_init(void)
; 0007 001B {
_usartc0_init:
; .FSTART _usartc0_init
; 0007 001C // Note: The correct PORTC direction for the RxD, TxD and XCK signals
; 0007 001D // is configured in the ports_init function.
; 0007 001E 
; 0007 001F // Transmitter is enabled
; 0007 0020 // Set TxD=1
; 0007 0021 PORTC.OUTSET=0x08;
	LDI  R30,LOW(8)
	STS  1605,R30
; 0007 0022 
; 0007 0023 // Communication mode: Asynchronous USART
; 0007 0024 // Data bits: 8
; 0007 0025 // Stop bits: 1
; 0007 0026 // Parity: Disabled
; 0007 0027 USARTC0.CTRLC=USART_CMODE_ASYNCHRONOUS_gc | USART_PMODE_DISABLED_gc | USART_CHSIZE_8BIT_gc;
	LDI  R30,LOW(3)
	STS  2244,R30
; 0007 0028 
; 0007 0029 // Receive complete interrupt: Low Level
; 0007 002A // Transmit complete interrupt: Low Level
; 0007 002B // Data register empty interrupt: Disabled
; 0007 002C USARTC0.CTRLA=(USARTC0.CTRLA & (~(USART_RXCINTLVL_gm | USART_TXCINTLVL_gm | USART_DREINTLVL_gm))) |
; 0007 002D 	USART_RXCINTLVL_LO_gc | USART_TXCINTLVL_LO_gc | USART_DREINTLVL_OFF_gc;
	LDS  R30,2242
	ANDI R30,LOW(0xC0)
	ORI  R30,LOW(0x14)
	STS  2242,R30
; 0007 002E 
; 0007 002F // Required Baud rate: 115200
; 0007 0030 // Real Baud Rate: 115200.0 (x1 Mode), Error: 0.0 %
; 0007 0031 USARTC0.BAUDCTRLA=0x80;
	LDI  R30,LOW(128)
	STS  2246,R30
; 0007 0032 USARTC0.BAUDCTRLB=((0x09 << USART_BSCALE_gp) & USART_BSCALE_gm) | 0x02;
	LDI  R30,LOW(146)
	STS  2247,R30
; 0007 0033 
; 0007 0034 // Receiver: On
; 0007 0035 // Transmitter: On
; 0007 0036 // Double transmission speed mode: Off
; 0007 0037 // Multi-processor communication mode: Off
; 0007 0038 USARTC0.CTRLB=(USARTC0.CTRLB & (~(USART_RXEN_bm | USART_TXEN_bm | USART_CLK2X_bm | USART_MPCM_bm | USART_TXB8_bm))) |
; 0007 0039 	USART_RXEN_bm | USART_TXEN_bm;
	LDS  R30,2243
	ANDI R30,LOW(0xE0)
	ORI  R30,LOW(0x18)
	STS  2243,R30
; 0007 003A }
	RET
; .FEND
;
;// Note: RX_BUFFER_SIZE_USARTC0 is #define-d in 'usarts_init.h' with the value 24
;char rx_buffer_usartc0[RX_BUFFER_SIZE_USARTC0];
;
;#if RX_BUFFER_SIZE_USARTC0 <= 256
;volatile unsigned char rx_wr_index_usartc0=0,rx_rd_index_usartc0=0;
;#else
;volatile unsigned int rx_wr_index_usartc0=0,rx_rd_index_usartc0=0;
;#endif
;
;#if RX_BUFFER_SIZE_USARTC0 < 256
;volatile unsigned char rx_counter_usartc0=0;
;#else
;volatile unsigned int rx_counter_usartc0=0;
;#endif
;
;// This flag is set on USARTC0 Receiver buffer overflow
;bit rx_buffer_overflow_usartc0=0;
;
;// USARTC0 Receiver interrupt service routine
;interrupt [USARTC0_RXC_vect] void usartc0_rx_isr(void)
; 0007 0050 {
_usartc0_rx_isr:
; .FSTART _usartc0_rx_isr
	ST   -Y,R26
	ST   -Y,R30
	ST   -Y,R31
	IN   R30,SREG
	ST   -Y,R30
; 0007 0051 unsigned char status;
; 0007 0052 char data;
; 0007 0053 
; 0007 0054 status=USARTC0.STATUS;
	ST   -Y,R17
	ST   -Y,R16
;	status -> R17
;	data -> R16
	LDS  R17,2241
; 0007 0055 data=USARTC0.DATA;
	LDS  R16,2240
; 0007 0056 if ((status & (USART_FERR_bm | USART_PERR_bm | USART_BUFOVF_bm)) == 0)
	MOV  R30,R17
	ANDI R30,LOW(0x1C)
	BRNE _0xE0003
; 0007 0057    {
; 0007 0058    rx_buffer_usartc0[rx_wr_index_usartc0++]=data;
	LDS  R30,_rx_wr_index_usartc0
	SUBI R30,-LOW(1)
	STS  _rx_wr_index_usartc0,R30
	SUBI R30,LOW(1)
	LDI  R31,0
	SUBI R30,LOW(-_rx_buffer_usartc0)
	SBCI R31,HIGH(-_rx_buffer_usartc0)
	ST   Z,R16
; 0007 0059 
; 0007 005A #if RX_BUFFER_SIZE_USARTC0 == 256
; 0007 005B    // special case for receiver buffer size=256
; 0007 005C    if (++rx_counter_usartc0 == 0) rx_buffer_overflow_usartc0=1;
; 0007 005D #else
; 0007 005E    if (rx_wr_index_usartc0 == RX_BUFFER_SIZE_USARTC0) rx_wr_index_usartc0=0;
	LDS  R26,_rx_wr_index_usartc0
	CPI  R26,LOW(0x18)
	BRNE _0xE0004
	LDI  R30,LOW(0)
	STS  _rx_wr_index_usartc0,R30
; 0007 005F    if (++rx_counter_usartc0 == RX_BUFFER_SIZE_USARTC0)
_0xE0004:
	LDS  R26,_rx_counter_usartc0
	SUBI R26,-LOW(1)
	STS  _rx_counter_usartc0,R26
	CPI  R26,LOW(0x18)
	BRNE _0xE0005
; 0007 0060       {
; 0007 0061       rx_counter_usartc0=0;
	LDI  R30,LOW(0)
	STS  _rx_counter_usartc0,R30
; 0007 0062       rx_buffer_overflow_usartc0=1;
	SBI  0x0,0
; 0007 0063       }
; 0007 0064 #endif
; 0007 0065    }
_0xE0005:
; 0007 0066 }
_0xE0003:
	LD   R16,Y+
	LD   R17,Y+
	RJMP _0xE0016
; .FEND
;
;// Receive a character from USARTC0
;// USARTC0 is used as the default input device by the 'getchar' function
;// #define _ALTERNATE_GETCHAR_ is inserted for this purpose
;// in the main program source file before #include <stdio.h>
;#pragma used+
;char getchar(void)
; 0007 006E {
; 0007 006F char data;
; 0007 0070 
; 0007 0071 while (rx_counter_usartc0==0);
;	data -> R17
; 0007 0072 data=rx_buffer_usartc0[rx_rd_index_usartc0++];
; 0007 0073 #if RX_BUFFER_SIZE_USARTC0 != 256
; 0007 0074 if (rx_rd_index_usartc0 == RX_BUFFER_SIZE_USARTC0) rx_rd_index_usartc0=0;
; 0007 0075 #endif
; 0007 0076 #asm("cli")
; 0007 0077 --rx_counter_usartc0;
; 0007 0078 #asm("sei")
; 0007 0079 return data;
; 0007 007A }
;#pragma used-
;
;// Note: TX_BUFFER_SIZE_USARTC0 is #define-d in 'usarts_init.h' with the value 32
;char tx_buffer_usartc0[TX_BUFFER_SIZE_USARTC0];
;
;#if TX_BUFFER_SIZE_USARTC0 <= 256
;volatile unsigned char tx_wr_index_usartc0=0,tx_rd_index_usartc0=0;
;#else
;volatile unsigned int tx_wr_index_usartc0=0,tx_rd_index_usartc0=0;
;#endif
;
;#if TX_BUFFER_SIZE_USARTC0 < 256
;volatile unsigned char tx_counter_usartc0=0;
;#else
;volatile unsigned int tx_counter_usartc0=0;
;#endif
;
;// USARTC0 Transmitter interrupt service routine
;interrupt [USARTC0_TXC_vect] void usartc0_tx_isr(void)
; 0007 008E {
_usartc0_tx_isr:
; .FSTART _usartc0_tx_isr
	ST   -Y,R26
	ST   -Y,R30
	ST   -Y,R31
	IN   R30,SREG
	ST   -Y,R30
; 0007 008F if (tx_counter_usartc0)
	LDS  R30,_tx_counter_usartc0
	CPI  R30,0
	BREQ _0xE000C
; 0007 0090    {
; 0007 0091    --tx_counter_usartc0;
	LDS  R30,_tx_counter_usartc0
	SUBI R30,LOW(1)
	STS  _tx_counter_usartc0,R30
; 0007 0092    USARTC0.DATA=tx_buffer_usartc0[tx_rd_index_usartc0++];
	LDS  R30,_tx_rd_index_usartc0
	SUBI R30,-LOW(1)
	STS  _tx_rd_index_usartc0,R30
	SUBI R30,LOW(1)
	LDI  R31,0
	SUBI R30,LOW(-_tx_buffer_usartc0)
	SBCI R31,HIGH(-_tx_buffer_usartc0)
	LD   R30,Z
	STS  2240,R30
; 0007 0093 #if TX_BUFFER_SIZE_USARTC0 != 256
; 0007 0094    if (tx_rd_index_usartc0 == TX_BUFFER_SIZE_USARTC0) tx_rd_index_usartc0=0;
	LDS  R26,_tx_rd_index_usartc0
	CPI  R26,LOW(0x20)
	BRNE _0xE000D
	LDI  R30,LOW(0)
	STS  _tx_rd_index_usartc0,R30
; 0007 0095 #endif
; 0007 0096    }
_0xE000D:
; 0007 0097 }
_0xE000C:
_0xE0016:
	LD   R30,Y+
	OUT  SREG,R30
	LD   R31,Y+
	LD   R30,Y+
	LD   R26,Y+
	RETI
; .FEND
;
;// Write a character to the USARTC0 Transmitter buffer
;// USARTC0 is used as the default output device by the 'putchar' function
;// #define _ALTERNATE_PUTCHAR_ is inserted for this purpose
;// in the main program source file before #include <stdio.h>
;#pragma used+
;void putchar(char c)
; 0007 009F {
_putchar:
; .FSTART _putchar
; 0007 00A0 while (tx_counter_usartc0 == TX_BUFFER_SIZE_USARTC0);
	ST   -Y,R17
	MOV  R17,R26
;	c -> R17
_0xE000E:
	LDS  R26,_tx_counter_usartc0
	CPI  R26,LOW(0x20)
	BREQ _0xE000E
; 0007 00A1 #asm("cli")
	CLI
; 0007 00A2 if (tx_counter_usartc0 || ((USARTC0.STATUS & USART_DREIF_bm)==0))
	LDS  R30,_tx_counter_usartc0
	CPI  R30,0
	BRNE _0xE0012
	LDS  R30,2241
	ANDI R30,LOW(0x20)
	BRNE _0xE0011
_0xE0012:
; 0007 00A3    {
; 0007 00A4    tx_buffer_usartc0[tx_wr_index_usartc0++]=c;
	LDS  R30,_tx_wr_index_usartc0
	SUBI R30,-LOW(1)
	STS  _tx_wr_index_usartc0,R30
	SUBI R30,LOW(1)
	LDI  R31,0
	SUBI R30,LOW(-_tx_buffer_usartc0)
	SBCI R31,HIGH(-_tx_buffer_usartc0)
	ST   Z,R17
; 0007 00A5 #if TX_BUFFER_SIZE_USARTC0 != 256
; 0007 00A6    if (tx_wr_index_usartc0 == TX_BUFFER_SIZE_USARTC0) tx_wr_index_usartc0=0;
	LDS  R26,_tx_wr_index_usartc0
	CPI  R26,LOW(0x20)
	BRNE _0xE0014
	LDI  R30,LOW(0)
	STS  _tx_wr_index_usartc0,R30
; 0007 00A7 #endif
; 0007 00A8    ++tx_counter_usartc0;
_0xE0014:
	LDS  R30,_tx_counter_usartc0
	SUBI R30,-LOW(1)
	STS  _tx_counter_usartc0,R30
; 0007 00A9    }
; 0007 00AA else
	RJMP _0xE0015
_0xE0011:
; 0007 00AB    USARTC0.DATA=c;
	STS  2240,R17
; 0007 00AC #asm("sei")
_0xE0015:
	SEI
; 0007 00AD }
_0x2080002:
	LD   R17,Y+
	RET
; .FEND
;#pragma used-
;

Jim

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

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

Eh?

 

;// Receive a character from USARTC0
;// USARTC0 is used as the default input device by the 'getchar' function
;// #define _ALTERNATE_GETCHAR_ is inserted for this purpose
;// in the main program source file before #include <stdio.h>
;#pragma used+
;char getchar(void)
; 0007 006E {
; 0007 006F char data;
; 0007 0070 
; 0007 0071 while (rx_counter_usartc0==0);
;	data -> R17
; 0007 0072 data=rx_buffer_usartc0[rx_rd_index_usartc0++];
; 0007 0073 #if RX_BUFFER_SIZE_USARTC0 != 256
; 0007 0074 if (rx_rd_index_usartc0 == RX_BUFFER_SIZE_USARTC0) rx_rd_index_usartc0=0;
; 0007 0075 #endif
; 0007 0076 #asm("cli")
; 0007 0077 --rx_counter_usartc0;
; 0007 0078 #asm("sei")
; 0007 0079 return data;
; 0007 007A }
;#pragma used-

(but I don't know enough about CV and how it does stdio to know really)

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

Just a random guess but what happens if you put #define _ALTERNATE_GETCHAR_ right next to the alternative getchar() function rather than at the top of main.c?

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "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."

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

clawson wrote:

Eh?

 

;// Receive a character from USARTC0
;// USARTC0 is used as the default input device by the 'getchar' function
;// #define _ALTERNATE_GETCHAR_ is inserted for this purpose
;// in the main program source file before #include <stdio.h>
;#pragma used+
;char getchar(void)
; 0007 006E {
; 0007 006F char data;
; 0007 0070 
; 0007 0071 while (rx_counter_usartc0==0);
;	data -> R17
; 0007 0072 data=rx_buffer_usartc0[rx_rd_index_usartc0++];
; 0007 0073 #if RX_BUFFER_SIZE_USARTC0 != 256
; 0007 0074 if (rx_rd_index_usartc0 == RX_BUFFER_SIZE_USARTC0) rx_rd_index_usartc0=0;
; 0007 0075 #endif
; 0007 0076 #asm("cli")
; 0007 0077 --rx_counter_usartc0;
; 0007 0078 #asm("sei")
; 0007 0079 return data;
; 0007 007A }
;#pragma used-

(but I don't know enough about CV and how it does stdio to know really)

 

Can you elaborate Cliff?  "EH?" can mean many things...

 

Brian Fairchild wrote:

Just a random guess but what happens if you put #define _ALTERNATE_GETCHAR_ right next to the alternative getchar() function rather than at the top of main.c?

THats only used if I have the second USART enabled(which I do not)  And I do not see the Alternative anywhere in the files CV generated.

 

Jim

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

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

As getchar()/putchar() are library functions then if you think you have a problem with those what happens if you simply switch to library URTA_get_byte() and UART_put_byte() functions instead.

 

(and my "Eh?" was responding to your suggestion that there was no getchar() and yet I thought I could see something called getchar() in the listing).

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

clawson wrote:
(and my "Eh?" was responding to your suggestion that there was no getchar() and yet I thought I could see something called getchar() in the listing).

 

Ahhh, Ok I know that GetChar() is a library function, but if you look at the code I posted the PUTCHAR() has actual code below teh comments and the GETCHAR() does not appear to.  HEnce my comment.  I am probably wrong, but it would not be the first time...

 

JIm

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

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

jgmdesign wrote:

When I hit RUN and do nothing for a few seconds then hit PAUSE the window shows that the application is sitting in this spot:

while (rx_counter_usartc0==0);

How does it get there?  I'd thought it was part of getchar(), which is not being reached.

Can you decipher the call stack?

Moderation in all things. -- ancient proverb

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

skeeve wrote:
Can you decipher the call stack?

Thats a little over my head.

 

skeeve wrote:

How does it get there?  I'd thought it was part of getchar(), which is not being reached.

 

Something I noticed in Studio....be it a GCC project, or CV is that when you start a debug session, something jumps to the ISR's and other functions.  I have seen this before and I cannot pin it down, but lets not go into that too much....for now.

 

In the meantime I have to step out for a little while.  When I return I will create a USART only project and see if this all works in that application.

 

Jim

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

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


jgmdesign wrote:
Thats a little over my head.
For example...

 

 

The call stack is showing that I'm currently at line 12 of delay_us function that was called from line 20 of main (because the return on the stack will be back to line 21).

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

Jim, can you create a small test program that just echos serial data?

Keep it simple and see if that works.  Just to check your using your tool chain correctly.

 

Jim

 

 

 

 

FF = PI > S.E.T

 

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

Please ZIP up your project and attach the ZIP.

 

I do not intend to reconstruct from a maze of pasted code.

It is much easier to just build your project and run it myself.

 

I don't have 32E5 but I do have 32A4U.   It should be straightforward to Simulate the 32E5 or to build and debug on a slightly different hardware chip.

 

Ideally,  you post a minimal project but if "everything is in the ZIP" a reader can unzip and build immediately.

 

David.

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

In earlier post you showed the snapshot of the variable value, and later the generated code for the lds. But you cut off the address in the watch window, so until you do we don't know for sure that it is the same.
Also if you never hit your infinite loop, how do you expect code to be carried out? Again, if you never...

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

david.prentice wrote:
Please ZIP up your project and attach the ZIP.

When I read this thread whilst at the office earlier today there definitely was a zipped project attached to one of Jim's posts. I thought to myself "A-Ha - I enjoy a challenge; I'll fire Studio up this evening and find the problem in no time".

 

What gives ?

 

Last Edited: Wed. Mar 11, 2020 - 08:21 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch wrote:
In earlier post you showed the snapshot of the variable value, and later the generated code for the lds. But you cut off the address in the watch window, so until you do we don't know for sure that it is the same.

 

Fair enough.  But I would think that the compiler would throw up something if there were two variables with the same name, but I won't argue.

 

theusch wrote:
Also if you never hit your infinite loop, how do you expect code to be carried out? Again, if you never...

THis is an interesting comment and it hits on what I posted in #30

jgmdesign wrote:
Something I noticed in Studio....be it a GCC project, or CV is that when you start a debug session, something jumps to the ISR's and other functions.  I have seen this before and I cannot pin it down, but lets not go into that too much....for now.

 

So, I took this suggestion:

ki0bk wrote:
Something I noticed in Studio....be it a GCC project, or CV is that when you start a debug session, something jumps to the ISR's and other functions.  I have seen this before and I cannot pin it down, but lets not go into that too much....for now.

 

And did just that.  Created a project using the wizard for JUST THE USARTC0 and nothing else.  I then added the #define and the IF, nothing else.  Hit the START DEBUGGING and let it sit.  Did not touch anything for 10 seconds and then hit PAUSE. 

 

Here is what the MAIN window shows as to where teh program is:

So the program goes straight to that while loop right out of the gate and sits there.  Thats not good.

I restart the process, and now I type a few letters on the keyboard and I get nothing back on the terminal screen.  I pause the debugger and this is what I see:

 

Typing a few letters gets me out of that while loop, and into the main loop, but the if statement is still not resolving.

 

From the LST file:

if (DATARECEIVED()) putchar(getchar());  //This does nothing.  No output

 

Let me know if you need anything else.

 

EDIT:

Project ZIP

Attachment(s): 

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

Last Edited: Wed. Mar 11, 2020 - 09:08 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

jgmdesign wrote:
I would think that the compiler would throw up something if there were two variables with the same name

Only if they also had the same scope 

 

EDIT

 

eg, it's possible for a variable in an "inner" scope to "hide" a variable with the same name in an "outer"  scope:

 

void func( void )
{
    int doris;
    
    // code here can access 'doris'
    :
    :
    
    {
        int doris; // "hides" the outer 'doris'
        
        // code here would access the "inner" doris
        
    }
    
    // code here accesses the "outer" doris
}

 

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: Wed. Mar 11, 2020 - 09:19 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

awneil wrote:

jgmdesign wrote:
I would think that the compiler would throw up something if there were two variables with the same name

Only if they also had the same scope 

 

Ok, I'll look that up.

 

What I have determined between my actual app, and a USARTC0 only app is that the both of them do the exact same things.  First is jump to he Getchar() function and sit in the first WHILE loop.  Which is not good.  Second, after they get out of the Getchar() function the IF statement does not appear to resolve....no matter how I write it.

 

JIm

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

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


I have recompiled the above test program and uncommented the puts line so that I can see the stuff coming out of the terminal correctly, all is well there.

 

Typing stuff into the terminal goes into the received buffer as you can see (123ABC) so the line #define DATARECEIVED() (rx_counter_usartc0 != 0) or the line if (DATARECEIVED()) putchar(getchar()); is not doing what one may think it should be doing ie send the data in the rx_buffer and decrement the counter. It may just be the case of rewriting the last line but I'm not the best person to do it, in assembler it would be a simple thing........ devil

 

 

 

John Samperi

Ampertronics Pty. Ltd.

https://www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

John,

if you let the app sit without typing anything and hit PAUSE, you will see that the app is sitting in a WHILE loop in the getchar() function which literally hold the app hostage from doing anything else.  Thats the part I dont understand why it does that.

 

With regards to the whole DEFINE and IF thingie,  if I do this instead:

 

if(rx_counter_usartc0 != 0)
{
    PORTA.OUTSET = PIN5_bm;
}

even after I type some characters into the buffer I still do not get anything to happen thats in teh brackets.

 

Frustrating.

 

JIm

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

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

I guess that you should not use getchar in your code as the chars are coming in via the interrupts?? (getchar is blocking) So if the counter is not zero then get the data and send it out??

 

I had the putchar(getchar()) bit sort of working somehow by just using the rx_counter_usartc0 != 0 as a variable but then I did some small changes and it is not working again.

 

It requires the help of some heavy duty C and CV gurus.laugh

John Samperi

Ampertronics Pty. Ltd.

https://www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

jgmdesign wrote:

First is jump to he Getchar() function and sit in the first WHILE loop.  Which is not good.

 

As John observed, the default getchar(), that the CV Wizard generates, is blocking and will sit there twiddling its thumbs until a character arrives. I deal with this in my code like this...

 

uint8_t getkey(void)
{
    uint8_t key;

    key = NULL;
    gNumeric = FALSE;

    if (rx_counter0) {
        key = getchar();
        if ((key >= '0') && (key <= '9')) {
            gNumeric = TRUE;
        }
    }

    return key;

}

(Apologies for the slightly uneven variable naming convention. 'rx_counter0' is the default CV name and is a global)

 

 

 

[EDIT]

 

Although your macro does do that check, and the generated code looks OK.

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "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."

Last Edited: Thu. Mar 12, 2020 - 08:10 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

jgmdesign wrote:

if you let the app sit without typing anything and hit PAUSE, you will see that the app is sitting in a WHILE loop in the getchar() function which literally hold the app hostage from doing anything else.  Thats the part I dont understand why it does that.

 

That is very weird. The generated code looks to be correct so the only way to get into getchar() on start up would be if rx_counter_usartc0 was non-zero.

 

                 _0x3:
                 ; 0000 005A       {
                 ; 0000 005B       // Place your code here
                 ; 0000 005C 	   if (DATARECEIVED()) putchar(getchar());  //This does nothing.  No output
000090 91e0 240a 	LDS  R30,_rx_counter_usartc0
000092 30e0      	CPI  R30,0
000093 f019      	BREQ _0x6
000094 d10a      	RCALL _getchar
000095 2fae      	MOV  R26,R30
000096 d14e      	RCALL _putchar
                 ; 0000 005D 
                 ; 0000 005E       }
                 _0x6:
000097 cff8      	RJMP _0x3
                 ; 0000 005F }
                 _0x7:
000098 cfff      	RJMP _0x7

 

Hmmm, how about a bit of defensive programming...

 

    rx_counter_usartc0 = 0;
    n = USARTC0.DATA;
    n = USARTC0.DATA;

    #asm("sei")


    while (1) {
        if (rx_counter_usartc0) {
            n= getchar();
            putchar(n);
        }
    }

The generated code in the while(1) loop is the same but you have separate lines there to set breakpoints on.

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "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."

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

Brian Fairchild wrote:
That is very weird. The generated code looks to be correct so the only way to get into getchar() on start up would be if rx_counter_usartc0 was non-zero.

 

I am reluctantly tempted to poke Pavel on this, and prepared for the nasty email response he usually gives.

 

Or I can simply bail on using CV for this and just go GCC and live life in peace. 

 

JIm

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

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

jgmdesign wrote:
Thats the part I dont understand why it does that.

getchar() is normally a blocking function, ie. it waits for a character to arrive before returning...

Normally if you don't want to block, you test for the presence of data in the buffer before calling getchar(). 

If using a polled input, then you test the received char flag in the USART reg, or if using an interrupt buffered input, then test for the presence of data in the buffer, either a non-zero count, or pointer positions, before calling getchar(). 

 

Jim

edit: spelling

 

FF = PI > S.E.T

 

Last Edited: Thu. Mar 12, 2020 - 01:58 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ki0bk wrote:
Normally if you don't want to block, you test for the presence of data in the buffer before calling getchar(). 
Isn't that exactly what (other) Jim's DATARECEIVED() macro is all about? It's checking the global RXC interrupt counter to see if there's anything in the ring buffer.

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

Yes,  Jim's macro is fine.  rx_counter_usartc0 is a global variable.   accessible to the user.

And testing before calling getchar() is a wise and safe approach.     DATARECEIVED() might not be the best choice of name but it is perfectly adequate.

 

I would worry more about the "quality" of any Serial Terminal software.    Especially from AS7.0

 

David.

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

jgmdesign wrote:

Or I can simply bail on using CV for this and just go GCC and live life in peace. 

 

I don't think it's a compiler problem; I've poked at the .lst file and everything looks right.

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "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."

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

Brian Fairchild wrote:
I don't think it's a compiler problem; I've poked at the .lst file and everything looks right.
Totally agree. This looks pretty unequivocal:

000090 91e0 240a 	LDS  R30,_rx_counter_usartc0
000092 30e0      	CPI  R30,0
000093 f019      	BREQ _0x6

Part of the mystery here seems to be Jim seeing rc_counter_usartc0 = 0x04 in the debugger but it apparently taking this branch anyway.

 

I have a rather strong distrust of debuggers myself based on a number of unpleasant experiences over the years so if I was backing anything here it would be that the debugger is lying about the 0x04 !

 

If CV produces a .map file I'd find the location of that global (I suppose one could extract it from 91E0 240A in fact?) and find out where the variable is really located then put a debugger raw "Memory Window" on that and see what's really there. (in case it's own symbolic mapping of the symbol to memory location is on the fritz).

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

CV is very pleasant to debug.   You can find most variables.   Trace execution,   ...

 

CV provides .LST and .MAP files as well as the .ASM file.

 

I would like to know what hardware is being used i.e. dongle,  RS232 cable, ...

and what Serial Terminal software is being used.

 

David.

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

clawson wrote:

If CV produces a .map file I'd find the location of that global...

 

It does...

 

Variable                                                                          Address   Size
------------------------------------------------------------------------------------------------
rx_buffer_usartc0                                                                 0x2400       8
rx_wr_index_usartc0                                                               0x2408       1
rx_rd_index_usartc0                                                               0x2409       1
rx_counter_usartc0                                                                0x240A       1
tx_buffer_usartc0                                                                 0x240B       8
tx_wr_index_usartc0                                                               0x2413       1
tx_rd_index_usartc0                                                               0x2414       1
tx_counter_usartc0                                                                0x2415       1

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "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."

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

FWIW I've just turned Jim's code into vanilla '328 code and it works as it should. Somewhere I have some 32E5s; I just need to find them.

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "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."

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

clawson wrote:
I have a rather strong distrust of debuggers myself based on a number of unpleasant experiences over the years so if I was backing anything here it would be that the debugger is lying about the 0x04 !

Or reads and clears the hardware register, making it 0 for the program when the if clause is evaluated.

With stm32 mcu's/debugger that can actually happen, and yes I have debugged for a "proplem" for day or two when it was just the debugger itself being the only proplem.

This is just a long shot, since i did notice anything about if you have tried running the program without debugging.

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

JoniS wrote:
Or reads and clears the hardware register, making it 0 for the program

Oh yes - there is that!

 

surprise

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...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

david.prentice wrote:

I would like to know what hardware is being used i.e. dongle,  RS232 cable, ...

and what Serial Terminal software is being used.

 

RS232 port on back of my Desktop PC. Direct cable to the Serial port of the STK600 and then to the XMEGA

 

Terminal software is Termite,  It sits quietly doing nothing until either it receves data, which it then displays, or it sends data if one types on the keyboard

 

JIm

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

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

My wild guess is that you have 2 competing functions for the UDR, getchar AND the ISR.

 

As soon as the RX flag is set (getchar would be waiting for this) the ISR fires, gets the data from the UDR, clears the flag and getchar never sees the RX flag.

John Samperi

Ampertronics Pty. Ltd.

https://www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

But john, There is NOTHING else in the code other than that one line.

 

Jim

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

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


 

Somehow missed the fact that this was an Xmega project and we have a basic prioritised interrupt controller to deal with.

Also struggling to debug this because the ELF contains no debug information:

C:\Users\Nigel\Documents\Atmel Studio\7.0\jgmdesign>avr-readelf -a Debug\Exe\xmega_just_usart.elf

ELF Header:

  Magic:   7f 45 4c 46 01 01 01 03 00 00 00 00 00 00 00 00

  Class:                             ELF32

  Data:                              2's complement, little endian

  Version:                           1 (current)

  OS/ABI:                            UNIX - GNU

  ABI Version:                       0

  Type:                              EXEC (Executable file)

  Machine:                           Atmel AVR 8-bit microcontroller

  Version:                           0x1

  Entry point address:               0x0

  Start of program headers:          52 (bytes into file)

  Start of section headers:          116 (bytes into file)

  Flags:                             0x0

  Size of this header:               52 (bytes)

  Size of program headers:           32 (bytes)

  Number of program headers:         2

  Size of section headers:           40 (bytes)

  Number of section headers:         4

  Section header string table index: 1

Section Headers:

  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al

  [ 0]                   NULL            00000000 000000 000000 00      0   0  0

  [ 1] .shstrtab         STRTAB          00000000 000114 00001c 00      0   0  0

  [ 2] .text             PROGBITS        00000000 000130 00049c 00  AX  0   0  2

  [ 3] .signature        PROGBITS        00840000 0005cc 000003 00  WA  0   0  1

Key to Flags:

  W (write), A (alloc), X (execute), M (merge), S (strings)

  I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)

  O (extra OS processing required) o (OS specific), p (processor specific)

There are no section groups in this file.

Program Headers:

  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align

  LOAD           0x000130 0x00000000 0x00000000 0x0049c 0x0049c R E 0x2

  LOAD           0x0005cc 0x00840000 0x00840000 0x00003 0x00003 RW  0x1

 Section to Segment mapping:

  Segment Sections...

   00     .text

   01     .signature

There is no dynamic section in this file.

There are no relocations in this file.

The decoding of unwind sections for machine type Atmel AVR 8-bit microcontroller is not currently supported.

No version information found in this file.

C:\Users\Nigel\Documents\Atmel Studio\7.0\jgmdesign>

Anyway using the simulator I get this:

 

 

The PC is stopped at the loop of interest but the USARTC0 appears to have interrupts disabled despite the comments in the (generated ?) code indicating that low-level was the intention.

 


{EDIT}

 

Oh that's just typical: A Refresh bug in  Atmel Studio 7 (Version: 7.0.2397 - )

The I/O registers don't get redrawn after {break} unless you close the fly-out then reopen the fly-out.

 

 

That's better.

I cannot be the only one who has been caught with this one.

 

Last Edited: Thu. Mar 12, 2020 - 09:31 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

There is NOTHING else in the code other than that one line.

But there are interrupts running in the background (clearing the RX flag??), that's what putting data into the receive buffer and increasing the rx counter.

 

See my screen shot here https://www.avrfreaks.net/commen...

John Samperi

Ampertronics Pty. Ltd.

https://www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

jgmdesign wrote:

david.prentice wrote:

I would like to know what hardware is being used i.e. dongle,  RS232 cable, ...

and what Serial Terminal software is being used.

 

RS232 port on back of my Desktop PC. Direct cable to the Serial port of the STK600 and then to the XMEGA

 

Terminal software is Termite,  It sits quietly doing nothing until either it receves data, which it then displays, or it sends data if one types on the keyboard

 

JIm

That all looks pretty reliable.   I don't see where anything can go wrong.    After all,   people have been handling USARTs with interrupts since day one.    And using a similar method to check whether "data is available" in the receive buffer.

In fact CV has provided interrupt-driven Serial comms since CV was first released.    Even for a Tiny2313.

 

I often change "Mega" device in an AS7.0 project.    It is not so simple with E5, A1, A4, ... which have some subtle differences.

All the same,   you can set up the basics in a CodeWizard file.    And generate for E5, A1, A4, ...

 

I don't have any hardware E5.   But the E5 appears to be a cut-down Xmega.    32E5 is the biggest in the family.

If there was a 128E5 it would be worth playing with.

 

David.

Last Edited: Thu. Mar 12, 2020 - 09:35 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

js wrote:

There is NOTHING else in the code other than that one line.

But there are interrupts running in the background (clearing the RX flag??), that's what putting data into the receive buffer and increasing the rx counter.

 

See my screen shot here https://www.avrfreaks.net/comment/2868156#comment-2868156

The counter only increments when i type something into the terminal. I can see if there is a flag set just before the sei, but the puts works and thats after the sei.

Groan. I may email Pavel and take my chances.
Jim

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

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



The counter only increments when i type something into the terminal.

Correct and the interrupts handle that as well as putting the data into the RX buffer.

 

The program just gets stuck in an endless loop at 0x00C5.

 

 

 

 

so there is something wrong with the line if (DATARECEIVED()) putchar(getchar()); or the way it is constructed

John Samperi

Ampertronics Pty. Ltd.

https://www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

js wrote:

...

The program just gets stuck in an endless loop at 0x00C5.

...

so there is something wrong with the line if (DATARECEIVED()) putchar(getchar()); or the way it is constructed

 

 

See #11.  That loop is the catch loop, for when you run off the end of main(). Now, how does one get there?

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

OK this HAS BEEN fun but it is interfering with piano practice and learn to read music. devil I have spent on this all the neurons I could afford.

 

Looking at the disassembly view this is what's happening:

 

1) The string is printed OK.

 

2) The code at the non working line keeps on looking for the counter to be above zero, this runs as long as nothing is typed into the terminal.

 

3) As soon as a char is typed in and the counter goes to 1 then the code seems to be getting the char and printing it??, the RX counter goes back to zero and then, SOMEHOW, the code goes to the endless loop at C5.

 

4) Any further chars typed in will increment the counter and the data gets stored into the RX buffer by the ISR but nothing else happens as the code is stuck in the endless loop.

 

and as porky pig would say tha..tha...that's all folks.

John Samperi

Ampertronics Pty. Ltd.

https://www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

js wrote:
then, SOMEHOW, the code goes to the endless loop at C5.

Doesn't this smell like an uncaught interrupt? 

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

I see Lee is having his fun......

 

Update:

 

Ok, I have made some progress.

 

If I Stick with the original:

while (1)
      {
         if (DATARECEIVED()) putchar(getchar());  //This does nothing.  No output

      }
}

The program goes to that loop and stays there.

 

But if I do this:

while (1)
      {
         if (DATARECEIVED()) putchar(getchar());  //This does nothing.  No output
		else
		{
			#asm("nop")
		}
			
	  }
}

It WORKS!! I can enter text on the terminal and it is echoed back

 

Or if I set a bit on PORTA:

while (1)
      {
         if (DATARECEIVED()) putchar(getchar());  //This does nothing.  No output
		
		PORTA.OUTSET = PIN5_bm;
	  }
}

This also works.  I can enter text on the terminal and it is echoed back

 

Jim

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

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

Well there you go! You are not just a pretty face. cheeky

 

Thanks for proving my theory wrong too, I can confirm your findings. The counter must get reset to zero every time a new char comes in and gets printed out but the data is still going into the RX circular buffer.

John Samperi

Ampertronics Pty. Ltd.

https://www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

js wrote:

Well there you go! You are not just a pretty face. cheeky

 

Thanks for proving my theory wrong too, I can confirm your findings. The counter must get reset to zero every time a new char comes in and gets printed out but the data is still going into the RX circular buffer.

 

Yabbut I am still scratching my head as to WHY just having:

while (1)
      {
         if (DATARECEIVED()) putchar(getchar());  //This does nothing.  No output

      }
}

Is causing such a fuss.  If it were a C issue I would think the compiler would spit up a fuss.  Then again......

 

Jim

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

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

js wrote:
The counter must get reset to zero every time a new char comes in and gets printed out but the data is still going into the RX circular buffer.

 

Not exactly.

 

If I wasn't constantly polling the counter, then it would increment by one every time a character came in.  Then once I did poll the counter and see that it no longer was zero I would have to run a routine to read out the buffer and clear the counter(through GETCHAR() )

 

And make sure I poll and readout before the counter resets and the buffer is over written.

 

Jim

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

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

jgmdesign wrote:

It WORKS!! I can enter text on the terminal and it is echoed back

 

This really doesn't make sense.

 

This...

    while (1)
    {
        if (DATARECEIVED()) putchar(getchar());  //This does nothing.  No output

    }

...generates this code...

                 ; 0000 0061     while (1)
                 _0x3:
                 ; 0000 0062     {
                 ; 0000 0063         if (DATARECEIVED()) putchar(getchar());  //This does nothing.  No output
000097 91e0 240a 	LDS  R30,_rx_counter_usartc0
000099 30e0      	CPI  R30,0
00009a f019      	BREQ _0x6
00009b d10a      	RCALL _getchar
00009c 2fae      	MOV  R26,R30
00009d d14e      	RCALL _putchar
                 ; 0000 0064 
                 ; 0000 0065     }
                 _0x6:
00009e cff8      	RJMP _0x3
                 ; 0000 0066 
                 ; 0000 0067 }
                 _0x7:
00009f cfff      	RJMP _0x7

 

Which is exactly what you'd expect.

 

Whereas this...

    while (1)
    {
        if (DATARECEIVED()) putchar(getchar());  //This does nothing.  No output
        else
        {
            #asm("nop")
        }
			
    }

...generates this...

                 ; 0000 0061     while (1)
                 _0x3:
                 ; 0000 0062     {
                 ; 0000 0063         if (DATARECEIVED()) putchar(getchar());  //This does nothing.  No output
000097 91e0 240a 	LDS  R30,_rx_counter_usartc0
000099 30e0      	CPI  R30,0
00009a f021      	BREQ _0x6
00009b d10c      	RCALL _getchar
00009c 2fae      	MOV  R26,R30
00009d d150      	RCALL _putchar
                 ; 0000 0064 		else
00009e c001      	RJMP _0x7
                 _0x6:
                 ; 0000 0065 		{
                 ; 0000 0066 			#asm("nop")
00009f 0000      	NOP
                 ; 0000 0067 		}
                 _0x7:
                 ; 0000 0068 
                 ; 0000 0069     }
0000a0 cff6      	RJMP _0x3
                 ; 0000 006A 
                 ; 0000 006B }
                 _0x8:
0000a1 cfff      	RJMP _0x8

 

Which is also what you'd expect.

 

We know the code works on a '328 because I've run it.

 

That leaves either some odd behaviour of the chip itself, something about the debug environment, or a hardware issue.

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "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."

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

It works fine on an A4U.   I can't see any reason for an E5 to behave differently.   Either the Compiler or the E5 chip.

 

I don't have an E5.   Can anyone (other than Jim) confirm E5 behaviour?

 

From a debugger point of view.   Move statements to separate lines.    Easier to identify / set Breakpoints.

It makes no difference to the generated code.

 

If the low pin count E5 had a 128k or 256k family member,   I would buy a board (or even a bare chip).

If someone can confirm the E5 misbehaviour,  I will buy the E5 XPLD board to satisfy my scepticism.

 

David.

Last Edited: Fri. Mar 13, 2020 - 08:51 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

david.prentice wrote:

It works fine on an A4U.   I can't see any reason for an E5 to behave differently.   Either the Compiler or the E5 chip.

 

Was that using Jim's posted code?

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "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."

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

Yes.   Generate from CodeWizard file.   (change device from 32E5 to 128A4U)

 

Do you own an E5 ?

 

It is Friday.   So Farnell would not deliver an XPLD until Monday.    I don't want to mess around with a bare chip.

 

David.

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


david.prentice wrote:

Do you own an E5 ?

 

Found my 32E5 breakout boards. A bit of a lash-up...

 

 

 

BUT...I can confirm Jim's findings.

 

This...

    while (1)
    {
        if (DATARECEIVED()) putchar(getchar());
    }

 

...does not work. Whereas this...

 

    while (1)
    {
        if (DATARECEIVED()) {
            putchar(getchar());
        } else {
            #asm("nop");
        }
    }

...does.

 

Very odd.

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "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."

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

For completeness I changed the first bit of code to this...

 

    while (1)
    {
        if (DATARECEIVED()) {
            putchar(getchar());
        } else {
//            #asm("nop");
        }
    }

...with the same result.

 

 

Generated code for the non-working version...

 

                 _0x4:
                 ; 0000 0062     {
                 ; 0000 0063         if (DATARECEIVED()) {
0000b1 91e0 2419 	LDS  R30,_rx_counter_usartc0
0000b3 30e0      	CPI  R30,0
0000b4 f019      	BREQ _0x7
                 ; 0000 0064             putchar(getchar());
0000b5 d10a      	RCALL _getchar
0000b6 2fae      	MOV  R26,R30
0000b7 d14e      	RCALL _putchar
                 ; 0000 0065         } else {
                 _0x7:
                 ; 0000 0066 //            #asm("nop");
                 ; 0000 0067         }
                 ; 0000 0068     }
0000b8 cff8      	RJMP _0x4
                 ; 0000 0069 
                 ; 0000 006A }
                 _0x9:
0000b9 cfff      	RJMP _0x9

 

And the working version...

 

                 _0x4:
                 ; 0000 0062     {
                 ; 0000 0063         if (DATARECEIVED()) {
0000b1 91e0 2419 	LDS  R30,_rx_counter_usartc0
0000b3 30e0      	CPI  R30,0
0000b4 f021      	BREQ _0x7
                 ; 0000 0064             putchar(getchar());
0000b5 d10c      	RCALL _getchar
0000b6 2fae      	MOV  R26,R30
0000b7 d150      	RCALL _putchar
                 ; 0000 0065         } else {
0000b8 c001      	RJMP _0x8
                 _0x7:
                 ; 0000 0066             #asm("nop");
0000b9 0000      	NOP
                 ; 0000 0067         }
                 _0x8:
                 ; 0000 0068     }
0000ba cff6      	RJMP _0x4

 

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "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."

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


OK, this gets weirder.

 

I've just run both ASM files through a Diff and the only differences are those in the generated code above.

 

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "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."

Last Edited: Fri. Mar 13, 2020 - 10:33 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Things that don't seem to make any difference....

 

1) Running TX and RX on different interrupt priority levels

2) Running on the same level but with Round Robin scheduling turned on

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "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."

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

Have to come back to this later - it's Friday so it must be paperwork day.

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "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."

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

Brian Fairchild wrote:
it's Friday so it must be paperwork day.
I've never heard beer described in that way!

 

As to the issue here. I wonder if there's anyone who has both "traditional Xmega" and "E5" to compare behaviour on the two ?

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

Is there some atomic protection that might be starved by the interrupts? The inclusion of a nop() would support that methinks.

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

I get exactly the same as you.   (as I would expect)

                 _0x4:
                 ; 0000 0057     {
                 ; 0000 0058         if (DATARECEIVED()) {
000163 91e0 2813 	LDS  R30,_rx_counter_usartc0
000165 30e0      	CPI  R30,0
000166 f019      	BREQ _0x7
                 ; 0000 0059             putchar(getchar());  //works fine on A4U
000167 d11d      	RCALL _getchar
000168 2fae      	MOV  R26,R30
000169 d161      	RCALL _putchar
                 ; 0000 005A         } else {
                 _0x7:
                 ; 0000 005B //            #asm("nop");
                 ; 0000 005C         }
                 ; 0000 005D     }
00016a cff8      	RJMP _0x4
                 ; 0000 005E }
                 _0x9:
00016b cfff      	RJMP _0x9

But my program works fine on the 128A4U target with or without the NOP.

 

I have far too many "evaluation boards".   Hey-ho.   My Farnell order for ATXMEGAE5-XPLD has just been placed.

 

David.

Last Edited: Fri. Mar 13, 2020 - 10:47 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Brian Fairchild wrote:
it's Friday so it must be paperwork day

That's not a euphemism for panic-buying toilet roll, is it ... ?

 

cheeky

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...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

A guess (I don't have the HW so I can't check).

 

perhaps 

DATARECEIVED()

stops putchar from working, and the NOP (any delay) makes it work.

 

A way to test is to change baudrate. With the NOP a slower TX will also fail, and with faster the org. code will work. 

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

theusch wrote:
Doesn't this smell like an uncaught interrupt? 

Sorry; uncaught interrupt by default would jump to zero.

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

Interesting findings.

I am not at my development PC today, but if someo e wants to try out a thought i had.....

Throw some code BEFORE the IF statement and remove the stuff after the IF and see what happens.

Another test is to add code before the IF statement, remove the else/NOP, and add some code to do something after the IF.

Jim

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

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

Look at the serial code - how is it doing the atomic protection?

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

Not working...

 

    while (1)
    {
        if (DATARECEIVED()) {
            #asm("nop");
             n =getchar();
             putchar(n);
        } else {
//            #asm("nop");
        }
    }

 

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "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."

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

OK, there's something odd going on as you switch between different optimisation levels.

 

Low and Speed optimisation works without the NOP, the other speed optimisations don't.

 

Ditto for the three size optimisations.

 

This is a vanilla file straight from the wizard with just the obvious additions at the bottom of main.

 

 

Attachment(s): 

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "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."

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

Jim...

 

what happens if you turn the optimisation down to LOW?

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "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."

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

>This is a vanilla file

 

Probably doesn't do much good without the lst file, as some do not have cv to compile with.

 

 

 

Put the nop as the first thing in the while loop, so every read via lds r30 is preceded by the nop. Doesn't seem like the lds r30 likes the back to back reads when no other memory access takes place between reads (lds r30, cpi r30, rjmp, rjmp). The nop does something, and you would think an interrupt that will take place would also 'correct' the problem (but maybe see below).

 

You could also try to get the buffer count read to use a pointer so the resulting code is not using lds r30, just to see what a different type of access acts like.

 

This is the end of the isr (from the jgm listing in the zip file, anyway)-

 

000200 91e9          LD   R30,Y+
000201 bfef          OUT  SREG,R30
000202 91f9          LD   R31,Y+
000203 91e9          LD   R30,Y+
000204 91a9          LD   R26,Y+
000205 9518          RETI

 

Maybe the the pointer register usage has something to do with it, as the isr leaves with its last memory access as a pointer type access. In the avr0/1, I saw a strange problem where writing to the sleep control register would not work when using a pointer register to access (compiler generated code used pointers for some reason, then the problem showed up), but either adding a nop or getting the compiler to produce lds/sts (normal), or splitting up the write into two ops 'fixed' the problem. Maybe there are combinations of x/y/z pointer use that create a problem, although if so it must be a rare combo or you would think it would be causing problems all over the place.

 

I'm not sure what can be done in cv, but if a nop could be inserted before the reti, that could also maybe reveal something useful. Maybe.

 

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

OK, this is it from me for a day or so.

 

This works with Speed, Low optimisation...

 

    while (1)
    {
        if (rx_counter_usartc0 != 0) {
            putchar(getchar());
//        } else {
//            #asm("nop");
        }
    }

As does this...

 

    while (1)
    {
        if (rx_counter_usartc0 != 0) {
            putchar(getchar());
        } else {
            #asm("nop");
        }
    }

 

This does not work with Speed, Maximal...

 

    while (1)
    {
        if (rx_counter_usartc0 != 0) {
            putchar(getchar());
//        } else {
//            #asm("nop");
        }
    }

 

Whereas this does...

 

    while (1)
    {
        if (rx_counter_usartc0 != 0) {
            putchar(getchar());
        } else {
            #asm("nop");
        }
    }

 

[this is as much about reminding me where I got to as anything else]

 

[That said I am very confused and may be going down the wrong rabbit hole]

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "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."

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

curtvm wrote:

Put the nop as the first thing in the while loop, so every read via lds r30 is preceded by the nop.

 

Like this?

 

    while (1)
    {
        #asm("nop");
        #asm("nop");
        #asm("nop");
        #asm("nop");
                    
        if (rx_counter_usartc0 != 0) {

            putchar(getchar());
//        } else {
//            #asm("nop");
        }
    }

Doesn't work.

 

The .lst file for this version (not working)...

 

    while (1)
    {
        if (rx_counter_usartc0 != 0) {
            putchar(getchar());
//        } else {
//            #asm("nop");
        }
    }

 

...is attached.

Attachment(s): 

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "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."

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

Can anyone (other than Jim) confirm E5 behaviour?

Don't people read replies?  wink I was the first to confirm the beahviour in #67.

My Farnell order for ATXMEGAE5-XPLD has just been placed.

I was going to offer you the Xplained board I got from Atmel even before the E5 was released. This of course goes against my hoarder instinct....

John Samperi

Ampertronics Pty. Ltd.

https://www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

js wrote:
I was going to offer you the Xplained board I got from Atmel even before the E5 was released.

The situation appears widespread (at least two have recreated?), but is it time to gather the date code/chip rev of the various setups?

 

In that vein, I was going to peek at errata.  Anyone have a hint to find the errata?  The datasheet just says "go to microchip.com".  And I saw no link in a pass at the product page.

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.

Last Edited: Fri. Mar 13, 2020 - 09:24 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Jesus guys, been following this post.  Has anyone figured the problem yet?  Strange!

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

The Xmega32E5 target is a barrier to many (including me).

 

I had a thought about using the simulator though. Has anyone been successful using the Atmel stimulus file (.stim) to inject characters into the simulator's USART ? (Documentation on .stim files is sparse)

 

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

The Xmega32E5 target is a barrier to many

Why? It's just a nice little chip. I have about 3,000 boards in the field with the E5.

John Samperi

Ampertronics Pty. Ltd.

https://www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

js wrote:

The Xmega32E5 target is a barrier to many

Why? It's just a nice little chip. I have about 3,000 boards in the field with the E5.

 

I have to agree.  It is a nice chip.

 

 

Back to topic,

I have a huge non-avr project I need to get on.  And I also need to start/finish the one with the XMEGA in so I am going to get back to writing the application and watching the behaviour of things.  I will email Pavel at some point and see if he has an explanation as to why things are happening.  We shall see what the Big PoohBahh has to say.

 

Stay tuned Kiddies!

 

JIm

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

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

One more thing to add.

 

I just fired up the program we have been dissecting and I deleted everything from teh WHIE() loop and hit RUN debugger.  The code sits in the while loop and does not go to the WHILE loop in getchar().

 

Very interesting why either the MACRO, or writing the line of code itself in the while loop causes the problem...

 

All for now

 

Jim

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

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

N.Winterbottom wrote:

The Xmega32E5 target is a barrier to many (including me).

What I meant by that is, because not many freaks can immediately lay their hands on some real silicon; that it's a barrier to solving the weird problem.

 

Hence my sub-question about injecting characters into the Atmel Simulator.

 

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

My 32E5-XPRO will arrive tomorrow.

 

It should be fairly simple to see whether the 32E5 silicon behaves differently to 32A4U silicon.   Or even mega4809, tiny817, ... silicon.

Or whether Codevision does something different for 32E5.

 

I am intrigued.   The 32E5 has been available for about 5 years.  XmegaA1 was released in 2007.   The Xmega, mega-0, tiny-0, tiny-1 have been available for several years.    There is nothing "new" but of course silicon is revised,  compilers are updated, ...

 

David.

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

It would be interesting to try the same tests with GCC.

 

I'm trying to come up with a test to determine exactly where the problem lies. The hierarchy, with CVAVR, from top to bottom is...

 

C Code -> Compiler -> ASM Output -> AVRASM -> .hex file -> xmega32E5

 

 

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "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."

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

 

Well I got the stimulus file working in Studio & Simulator. It wasn't really that hard. I didn't realise Studio could open the COF debug format file either so I can debug Jim's exact code properly.

 

Here's the .stim file to inject the character 'J' into the RX pin: (The # lines are actually cycle delays)

PORTC.IN |= 0b00000100
#999
// Send 'J' 0x50 0b01010000
PORTC.IN &= 0b11111011
#87
PORTC.IN |= 0b00000100
#17
PORTC.IN &= 0b11111011
#17
PORTC.IN |= 0b00000100
#18
PORTC.IN &= 0b11111011
#17
PORTC.IN |= 0b00000100
#999

 

And the result:

Well the code as compiled by Jim works on the simulator. I get a USART ISR and I can see my 'J' sitting there in the USARTC0.DATA. I can single step through getchar() and putchar() and see my character get written out to the USART.

 

 

Last Edited: Sun. Mar 15, 2020 - 06:13 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

A little more of an update.....

 

I am starting to wonder if the debugger is causing some of this.  I put a 'delay loop' using timer ticks at the beginning of the program.  In a debugging session the loop seems to be skipped, but if I run teh app on teh chip without the debugger it looks like it's there.  I have to wiggle a pin and use my logic analyser to confirm this.

 

Will post information once I try it.

 

Jim

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

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

jgmdesign wrote:
In a debugging session the loop seems to be skipped

How do you determine that?

 

There's an option to allow timers to continue to run during a debugger 'break'.

If that's happening, and you're single-stepping, the timer could well have expired during a "step" - so it seems like the wait loop has been skipped ... ?

 

 

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...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

My Xmega32E5-XPLD board arrived on Monday.

 

Sure enough.   Jim's UART Codevision code did not work on the 32E5.

But Brian's addition of a single NOP made it work.

The code works fine on a 32A4U chip (with or without a NOP)

 

I am gobsmacked.   I wrote a similar AS7.0 project using the AVR1307 App Note

It works fine with CV or GCC.    However the DATAAVAILABLE() function has a larger calling overhead cost than simple inspecting a RX_Counter variable.

 

So I adjusted the ISR() and the getch() function for a RX_Counter variable.

CV worked for 32A4U

CV failed for 32E5

GCC worked for 32A4U

GCC worked for 32E5

 

If I add the NOP,  CV works for 32E5

 

I diff-ed the generated ASM and  S files.

Codevision compiles into exactly the same ASM code for 32E5 as for 32A4U.    The interrupt vectors are different.  The USART registers have different addresses.

Likewise GCC compiles into exactly the same S files.

 

It is a complete mystery.  32A4U and 32E5 have the same internal Core.   I would expect them to behave the same.

 

It is pretty straightforward to use the AVR1307 driver:

Adjust buffer sizes in the H file

Adjust BAUD,  Clock speed in the Example file

 

I attach an AS7.0 solution.   All 4 projects share the same source code.   Set F_CPU in Project Symbols for GCC or in CV Project Configure.

 

David.

Attachment(s): 

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

david.prentice wrote:

It is a complete mystery.

 

I need to add where I am on this.

 

With a couple of tweaks to the code, to stop destination addresses of calls and jumps changing, I can generate IDENTICAL .hex files, except for the section in main() where the test and branch take place. One of which works, one of which doesn't.

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "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."

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

Since the chips I am using are from my stores and are at least three years old, and Davids new board should have a 'new' chip on it, would it be safe to say that it's not an issue with the silicon?  I see documentation on the Mchip site is becoming hit or miss, otherwise I would take Lee's jab at looking for erratas.

 

JIm

 

 

 

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

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

My XPLD board was made in 2017.   The pcb was designed in 2012 !

 

The previous solution uses the AVR1307 scheme i.e. RXC and DRE interrupts

I have written another project.   This time using the CV Wizard scheme i.e. with RXC and TXC interrupts

 

There are several ways to handle USART interrupts e.g. with TXC, DRE or both.    Since CV and GCC both perform 100% "with the NOP" it means that the interrupts are working ok.  

The only difference is down to the foreground code.

 

The GCC loop is:

        if (DATAAVAILABLE()) {
00000113  LDS R24,0x2020		Load direct from data space 
00000115  TST R24		Test for Zero or Minus 
00000116  BREQ PC+0x05		Branch if equal 
            putch(getch());
00000117  CALL 0x000000AC		Call subroutine 
00000119  CALL 0x00000075		Call subroutine 
        nop();  //CV works with this NOP
0000011B  NOP 		No operation 
    }
0000011C  RJMP PC-0x0009		Relative jump 

and the CV loop is

        if (DATAAVAILABLE()) {
000001C3  LDS R30,0x2425		Load direct from data space 
000001C5  CPI R30,0x00		Compare with immediate 
000001C6  BREQ PC+0x04		Branch if equal 
            putch(getch());
000001C7  RCALL PC-0x00C0		Relative call subroutine 
000001C8  MOV R26,R30		Copy register 
000001C9  RCALL PC-0x00FD		Relative call subroutine 
        nop();  //CV works with this NOP
000001CA  NOP 		No operation 
000001CB  RJMP PC-0x0008		Relative jump 

So I find it difficult to see what the difference might be "without the NOP".    The only thing is CPI instead of TST but I can't see why this would matter.

 

I have added the two new projects to the ZIP.   (and deleted the monster DBG files from the ZIP)

Codevision produces a lot of "files" but does not remove all of them with "clean"

 

David.

Attachment(s): 

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

Have anyone look into the test I suggested in #83 ?

 

 I fear that :

 

LDS R30,0x2425		Load direct from data space

done at at a specific time of the TX will mess up some of the HW flags.

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

david.prentice wrote:
So I find it difficult to see what the difference might be "without the NOP".    The only thing is CPI instead of TST but I can't see why this would matter.
They have different effects on SREG, not that that should matter.

@sparrow2 Likewise LDS should only affect the target register.

Moderation in all things. -- ancient proverb

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

Ok I expected that 

LDS R30,0x2425

was reading a IO 

 

If it's just a variable we really need to see how the data got there an when. 

 

add:

This is not to solve it but getting closer to what the real problem is.

 

Remember that some IO reads actually clear/change HW flags.

Last Edited: Thu. Mar 19, 2020 - 03:38 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The 0x2020 or 0x2425 is simply the global rx_counter_usartc0.

Yes it is incremented by the RXC interrupt and decremented by the User getch().   But getch() does it atomically.

 

LDS, CPI, BREQ should be no different to LDS, TST, BREQ.   It is only the Z flag that is used by BREQ.

 

The LDS is done from the foreground.   It is an uint8_t so is an atomic read.

If an RXC interrupt appears after the LDS it just means that it goes around the loop again.

 

But the same would apply to the GCC compiled version.   Or to the CV version for an A4U target chip.

 

If there is a Silicon "feature" I would expect it to appear with GCC too.

If it was a CV "feature" I would expect E5 and A4U to exhibit the same feature.

Any flag, register ... altered by an ISR() would crash both NOP and no-NOP loops.

 

David.

Last Edited: Thu. Mar 19, 2020 - 03:36 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So no one want to check if an other BAUD-rate change anything :(

 

 

add:

This is not to solve it but getting closer to what the real problem is.

 

Remember that some IO reads actually clear/change HW flags.

Last Edited: Thu. Mar 19, 2020 - 03:39 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You can change BAUD from 110 to 115200 with F_CPU from 2MHz to 32MHz.   It makes no difference.

I would expect the new 32E5 chip to behave like my 32A4U chip i.e. correctly.

 

David.

 

Edit.   It is fun watching a 32MHz Xmega send text at 110 baud.

Last Edited: Thu. Mar 19, 2020 - 03:44 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 2

david.prentice wrote:
It is fun watching a 32MHz Xmega send text at 110 baud.

"Fun" was watching my 1st computer running at 1MHz sending/receiving text (via phone modem) at 110 baud.

(It was also "fun" when about a month later I was able to double processor speed to 2MHz and modem speed to 300 baud...)

 

Now, it pains me to be stuck with a (slow!) 1GHz Enet connection...

David

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

In these work from time I will add:

my first computer "job" (about 1980) was to rewrite a commodore PET basic program so it reliable could RX/TX 300 BAUD. 

It was for an accountant that wanted to be able to work from home :)  

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

In the summer of 1980 I would've been using Commodore PET BASIC to control RF test gear using its HPIB (aka GPIB; nowadays IEEE 488) ...

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...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

awneil wrote:

In the summer of 1980 I would've been using Commodore PET BASIC to control RF test gear using its HPIB (aka GPIB; nowadays IEEE 488) ...

I too was doing something similar with an HP Basic desktop w/ HPIP, testing seismic gear performance after being repaired before returning the gear to the field crews. They working hard in order to find $30/barrel oil back then!

Got laid off when oil dropped to $15/barrel.....  it was fun while it lasted.

 

Jim

 

 

FF = PI > S.E.T

 

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

Jim I'm thinking that if your code was a real life app with anything more than just "that line" you would have never had any problems.

John Samperi

Ampertronics Pty. Ltd.

https://www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

Last Edited: Thu. Mar 19, 2020 - 09:02 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

js wrote:

Jim I'm thinking that if your code was a real life app with anything more than just "that line" you would have never had any problems.

 

I am thinking along the same lines, and the app itself does have stuff after it and has been running without much fuss with the debugging going on.  I am somewhat relieved/honored that David was able to replicate the issue I am having/had, so it's not some silly coding violation on my part.

 

Not abandoning teh fight on this, but for now taking a backseat as I need to get a project further along.

 

JIm

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

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

The cv generated code leaves the rx isr with its last instruction as a pointer type instruction (cv uses these in prologue/epilogue, where gcc uses push/pop). Your main loop has a single memory op of lds (and its target reg happens to be a pointer reg also). Maybe there is some internal 'hangup' after the isr reti that causes the lds to fail because of the pointer use (Y), and the nop happens to fix it for some reason.

 

It would be curious to know if other instructions besides nop fix it (like a lds r16,0x00, sei, whatever), or somehow change the lds r30 to use a non-pointer register, or get somehow get a nop inserted just before the reti, and so on. Would be odd that there would be any interaction problem such as this, but that code may also be quite unique.

 

If it was a problem as described above, one could create a simple test with asm and you would think it could be duplicated (on that avr anyway)-

 

#include <avr/io.h>

void test(); //asm code

int main(void) {

    //let tcc4 irq every 60 clocks
    TCC4.INTCTRLA = 1; //intlvl=low
    TCC4.PER = 60;     //give enough time to run through isr
    TCC4.CTRLA = 1;    //div1
    PMIC.CTRL = 1;     //lolvlen
    asm("sei");
    test();
}

 

;test.S

;isr increments rx_count

;main loop calls the dec_count when it sees rx_count is not 0

 

.set SREG, 0x3f
.set rx_count, 0x2000 ;first ram address

 

.global __vector_12 ;tcc4 ovf

__vector_12:
st -Y,r30 ;similar prologue style as cv
in r30,SREG
st -Y,R30

 

ldi r30,1
sts 0x80C,r30 ;intflags ovfif
lds r30,rx_count
subi r30,-1
sts rx_count,r30

 

ld r30,Y+ ;similar epilogue style as cv
out SREG,r30
ld r30,Y+ ;last memory instruction
reti

 

.global dec_count

dec_count:
lds r30,rx_count
subi r30,1
sts rx_count,r30
ret

 

.global test

test:
lds r30,rx_count
cpi r30,0
breq 1f
rcall dec_count ;breakpoint here, should get here if working correctly
1:
;nop ;fixer
rjmp test

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

Thanks for your comments.

1.  I can replace NOP in #109 with any instruction e.g. SEI, CLT, ...

2.  I can omit the NOP but replace RJMP PC-0x0008 with JMP PC-0x0008

3.  Either way works on the 32E5.   32A4U always works.

 

4.  Inserting NOP before RETI makes no difference.    CV has always used LD Rx,Y+

5.  According to AS7.0 my 32E5 is Revision B

 

6.  I only possess 128A1, 128A4U, 32A4U, 32E5 Xmegas.   Only the 32E5 misbehaves.

7.  What Xmegas do other readers have?

 

8.  I will try your GCC suggestion.    Both as GCC project and as AVRASM2

 

David.

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

I adjusted your code.  i.e. added a catch-all

.global test

test:
    lds r30,rx_count
    cpi r30,0
    breq 1f
    rcall dec_count ;breakpoint here, should get here if working correctly
1:
    ;nop ;fixer
    rjmp test
    nop
here:
    nop
    rjmp here

If I put a Breakpoint on the RCALL,  it stops reliably.

I always have a Breakpoint on the RJMP here NOP.

 

If I remove the RCALL Breakpoint,  I eventually fall through to the NOP breakpoint.

 

I could wiggle a GPIO or start up the RTC Timer to see how long it takes to fall through.   But fall through it does !!!

 

David.