USART in SPI mode on ATmega32u4 not continuous

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

I am trying to send a continuous serial data stream consisting of 240 bits using the ATmega32U4 running at 16 MHz. I chose the USART SPI mode for the two byte buffer which Atmel/Microchip states can generate a continuous stream. The problem I am seeing is that the output stream has the correct clock frequency but is continuous for only ~19 ms (68 bytes) followed by a ~77 ms idle period. If I change the clock frequency the window times stay the same (at lower clock speed less bytes are sent)

 

Here is my simplified test code which reproduces the problem.

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

int main(void)
{
    CLKPR = 0x80;
    CLKPR = 0;
    UBRR1 = 0;
    DDRD |= (1 << PD5);
    UCSR1C = (1 << UMSEL11) | (1 << UMSEL10) | (1 << UCPOL1);
    UCSR1B = (1 << TXEN1) | (1 << UDRIE1);;
    UBRR1 = 19; /* 400 kHz */
    sei();

    while (1)
    {}
}

ISR(USART1_UDRE_vect)
{
    UDR1 = 0xAE;
}

Here is the output:

 

Of note, if I disable interrupts by removing the sei() call,there is a glitch on the clock line every ~96ms which correlates to the period of the data transmission and idle the base example.

 

I have tried two different chips that I have and both exhibit the same behavior.

 

Am I doing something wrong?  Has anyone else seen this behavior?

 

Thanks,

 

Ben

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

What happens if you drive it without the interrupt, ie. spin on UDRE in main?

Jim

 

 

(Possum Lodge oath) Quando omni flunkus, moritati.

"I thought growing old would take longer"

 

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

Polling yields the same results

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

Ok, This is strange. To program the device I have been using the factory DFU boot loader with HWB tied to ground and pulling reset low to enter the bootloader. My workflow was compile. DFU erase, DFU flash, DFU reset and then test. Under this workflow the problem occurs. If I do a power off-on restart, the problem goes away. 
I am guessing the DFU reset leaves something configured?

 

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

Simple programs can be deceiving with an optimizing compiler, example:

CLKPR = 0x80;
    CLKPR = 0;

the code above does not guarantee the needed 4 cycle timing window needed to set the cpu clock prescaler, you need to use the provided macros for this, check the gcc documentation for how to do this. 

Perhaps a gcc user will happen along with what is needed in more detail.

Jim

 

 

(Possum Lodge oath) Quando omni flunkus, moritati.

"I thought growing old would take longer"

 

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

found this:

#include <avr/power.h>

...

clock_prescale_set(clock_div_1);

Also make sure your not using optimize -o0 as its for use by compiler developers and gens bad (long) code!

Jim

 

(Possum Lodge oath) Quando omni flunkus, moritati.

"I thought growing old would take longer"

 

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

Thanks, I will use that going forward. 

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

dfuMANIFEST-WAIT-RESET if I correctly skimmed the megaAVR USB DFU (edit : bootloader) datasheet.

Exit by USB reset (USB D+ and D- go a specific single-ended) or power-on reset though reset by watchdog trip is mentioned.

USB Vbus cycling may be optional in USB hubs.

IIRC, USB DFU bootloader source code is in ASF3 (edit2 : Atmel Studio extension in Microchip Gallery?); the zip contains the files as burned at the packaging or test site (possibly UTAC Thailand and/or Microchip Thailand)

 

ATmega32U4 - 8-bit AVR Microcontrollers

https://www.microchip.com/mymicrochip/Reports.aspx?type=cpn&filter=ATmega32U4

USB Power Switch and Filter – Zak's Electronics Blog ~*

 

"Dare to be naïve." - Buckminster Fuller

Last Edited: Tue. Jan 28, 2020 - 11:04 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What if your main loop just toggles a pin - does that also generate the same pattern?

 

I would guess that the MCU is actually being reset. You could try adding a reset indication to your trace - e.g. generate a short positive pulse on another pin at start of main.

/Jakob Selbing

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

I think you need to check your fuse settings. If the WDTON fuse is set the code will run for ~16ms before restting. If the SUT fuses are set for slow-rising power, the system startup is delayed ~65ms after a reset. That describes the behavior your seeing.