ATMEGA48a freezes

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

Hi AVR Freaks Community,

I am curerently trying to build a tachometer (RPM-meter). The RPM is displayed on a 4x7segment display which is intefaced to a 4x7 segment driver/decoder. An Atmega48a sends SPI data to the registers of the driver to change the value of the display.

I ordered my own PCB I made on altium and soldered everything together myself.

I succeded to make it all work! I had a working project. The RPM was displayed but not to my taste so I wanted to make a few adjustements before putting it in my car. I came back 2 days after and everytime I put the power on it freezes in 2 seconds (with the same code as when it was working). I reduced my code to the minimum to isolate the problem but even with the minimum it would still freeze. I know it freezes because I have a bus pirate and I sniff the SPI from the Atmega48 and it suddenly stops. I can't put any less code because I won't notice it if it freezes.

 

The atmega48a is clocked via an external crystal at 20MHz.

The fuses are : L=C7, H=DF, E=01

 

here is my code after reduction:

 

#define F_CPU 20000000UL
#define window_Size 32
#define base_2_window 5

#include <avr/io.h>
#include <avr/interrupt.h>
#include "tachprj.h"
#include <util/delay.h>

char digits[4]={0};

int main(void)
{
	 
	UC_Init();
		
	while(1){
		SPI_Transmit(0xAA);
		_delay_ms(1000);		
    }
}

void UC_Init(void)
{
	
		 /*					Interrupts settings                  */
		 
		//sei();									//Global Interrupt enable
		 
		 //EICRA  |= ((1<<ISC10)|(1<<ISC00));		//Int0 and Int1 External Interrupt on any edge
		 //EIMSK  |= ((1<<INT1)|(1<<INT0));		//Enable Int0 and Int1
		
		 
		 
		 /*					Timers Settings						*/
		 
		//TCCR1B |= ((1<<CS11)|(1<<CS10));		//16 bit Timer 1 Enabled and Set prescaler to 64
		 
		 
		 /*					SPI Settings						*/
		 
		 
		 DDRB |= ((1<<PB3)|(1<<PB5));			//Sets SPI pins MOSI and CLK as outputs
		 SPCR	|= ((1<<SPE)|(1<<MSTR)|(1<<SPR1)|(1<<SPR0));						//Enable SPI,sets atmega as master, sets spi speed to 156.250 KHz, 
		 DDRD |= (1<<PD1);						//LOAD_pin set to output
		 PORTD |= (1<<PD1);						//initialise LOAD as a 1
		 
}

void SPI_Transmit(char cData)
{
	/* Start transmission */
	SPDR = cData;
	/* Wait for transmission complete */
	while(!(SPSR & (1<<SPIF)));
}

I have a lot of code missing but even the code you see above make the atmega48a freeze so I don't see the reason to put my whole code.

The code above is compiling though.

I have tried to simulate my code and it ends up into the "__builtin_avr_delay_cycles(__ticks_dc);" function and I can't go past it...

I have access to a voltmeter only and a bus pirate to sniff the spi data (also my programmer).

I provided the schematic design of my circuit in the attachments.

 

Hope I didn't overlook any infos,
Thanks everybody,
Marc

 

Attachment(s): 

This topic has a solution.

There are 11 types of people in the world. Those who understand binary, those who don't and those who make nerdy pun about it.

Last Edited: Tue. Aug 4, 2015 - 02:07 PM
This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
	 DDRB |= ((1<<PB3)|(1<<PB5));			//Sets SPI pins MOSI and CLK as outputs
		 SPCR	|= ((1<<SPE)|(1<<MSTR)|(1<<SPR1)|(1<<SPR0));						//Enable SPI,sets atmega as master, sets spi 

/SS is on PB2.  It needs to be made an output, or otherwise held high, to ensure that the SPI stays in master mode.  See the /SS discussion in the SPI chapter of the datasheet.

 

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

What about SS pin? On arduino it worked since I've attached wire to SS and touch it... It probably switched to slave mode and it is stucked on waiting to another master will do transmission?

Computers don't make errors - What they do they do on purpose.

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

/SS is on PB2.  It needs to be made an output, or otherwise held high, to ensure that the SPI stays in master mode.  See the /SS discussion in the SPI chapter of the datasheet.

 

I don't use the /SS pin, I manually set a "custom chip select" low via PD1. I know it's kind of wrong, but I like to have control over my chip select pin. Furthermore, It was proved to be a working method since it has worked before (I was able to communicate with the slave registers thousand of times).

In the code you see in my post, I don't address any device, I just generate SPI traffic to be able to detect when it freezes. I tell my sniffer to show me everything there is to see on the lines /SS low or high. 

There are 11 types of people in the world. Those who understand binary, those who don't and those who make nerdy pun about it.

Last Edited: Mon. Aug 3, 2015 - 09:16 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What about SS pin? On arduino it worked since I've attached wire to SS and touch it... It probably switched to slave mode and it is stucked on waiting to another master will do transmission?

I changed the code to:

 

	 DDRB |= ((1<<PB2)|(1<<PB3)|(1<<PB5));			//Sets SPI pins MOSI, SS and CLK as outputs
	PORTB |= (1<<PB2);								//Output High on SS pin

 

The Atmega48A is still freezing after I made theses changes.

 

 

There are 11 types of people in the world. Those who understand binary, those who don't and those who make nerdy pun about it.

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

I don't use the /SS pin, I manually set a "custom chip select" low via PD1. I know it's kind of wrong, but I like to have control over my chip select pin. Furthermore, It was proved to be a working method since it has worked before (I was able to communicate with the slave registers thousand of times).

???  How do you "lose control" by using PB2?  (In fact, if our speculation is correct you "lost control" by >>not<< paying attention to /SS level.)

 

And no matter how much you rail, and claim it worked forever during a particular test run, the fact is that an AVR8 SPI-peripheral /SS pin that is floating will eventually bite you in the butt when it floats low.  As you found out.

 

If otherwise not used, is it that hard to tie it high?  Or use internal pullup?  Or make it an output?

 

If SS is configured as an input, it must be held high to ensure Master SPI operation. If the SS pin is driven low by
peripheral circuitry when the SPI is configured as a Master with the SS pin defined as an input, the SPI system
interprets this as another master selecting the SPI as a slave and starting to send data to it. To avoid bus
contention, the SPI system takes the following actions:
1. The MSTR bit in SPCR is cleared and the SPI system becomes a Slave. As a result of the SPI becoming a Slave,
the MOSI and SCK pins become inputs.
2. The SPIF Flag in SPSR is set, and if the SPI interrupt is enabled, and the I-bit in SREG is set, the interrupt
routine will be executed.

 

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: Mon. Aug 3, 2015 - 09:44 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The Atmega48A is still freezing after I made theses changes.

 

I guess I don't have any words of wisdom, then.  If you disconnect the attached circuitry, does it still 'stop"?  perhaps a power issue?  Could it be the SPI slave that is "stopping"?  Do you still see activity on your chip select and SCK pijns with a 'scope, or not?

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

/SS pin that is floating will eventually bite you in the butt when it floats low.

 

Yes, you are right and I just made the changes as you will see in my previous post. It still freezes. Could the  MISO pin be affecting the communication? It is currently floating on my circuit.

 

 How do you "lose control" by using PB2?

You are also right, I wasn't aware, at the time of the conception,  that SS is also manually controled by the user.  

There are 11 types of people in the world. Those who understand binary, those who don't and those who make nerdy pun about it.

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

You have to set and clear /SS it in software. Nothing happens automagicalliy. So, how have you "lost control" of it.

 

As others have pointed out, you loose far more control by doing nothing.

 

Jim

 

Until Black Lives Matter, we do not have "All Lives Matter"!

 

 

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

Could it be the SPI slave that is "stopping"?

The slave is not used currently. I changed my code to the most simplistic I could. I can clearly see that the master (Atmaga48a)  stops sending SPI messages on my SPI sniffer. So I figured the slave had nothing to do with it.

 

Do you still see activity on your chip select and SCK pijns with a 'scope, or not?

The sniffer doesn't see anything after a certain amount of time (1 second).

 

 

 

 

There are 11 types of people in the world. Those who understand binary, those who don't and those who make nerdy pun about it.

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

Hey guys, I think you solved my problem.

It seems it was the SS pin that was randomly set low by the environment.
I know I previously said it didn't work but I was flashing the Release version of the build and not the debug (the one I changed).

 

You were spot on at your first try. Thanks a lot.

Do I have to put *SOLVED* into the title of my article now?

There are 11 types of people in the world. Those who understand binary, those who don't and those who make nerdy pun about it.

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

Do I have to put *SOLVED* into the title of my article now?

Click the "Mark as solution" button on post #2 (the post where you first got the answer).

 

Moderator

Last Edited: Tue. Aug 4, 2015 - 10:04 AM