Atmega64 and I/O activation in function

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

Hi,

 

I have an issue that I can't understand with Atmega64. Below is the code.

 

This code works (I measure 5V on Pin E7 and Pin D7):

#include <avr/io.h>

int main(void)
{
    DDRE|=(1<<DDE7);
    DDRD|=(1<<DDD7);

    PORTE |= (1<<PORTE7);
    PORTD |= (1<<PORTD7);
    while (1) 
    {
    }
}

 

This codes also works (I measure 5V on Pin E7 and Pin D7):

#include <avr/io.h>

void SelectChannel()
{

    Some program here...
}

int main(void)
{
    DDRE|=(1<<DDE7);
    DDRD|=(1<<DDD7);

    PORTE |= (1<<PORTE7);
    SelectChannel();
    PORTD |= (1<<PORTD7);
    while (1) 
    {
    }
}

 

But this doesn't work and I can't find why (I measure 0V on Pin D7 and 5V on Pin E7):

#include <avr/io.h>

void SelectChannel()
{
    PORTE |= (1<<PORTE7);
}

int main(void)
{
    DDRE|=(1<<DDE7);
    DDRD|=(1<<DDD7);
    SelectChannel();
    PORTD |= (1<<PORTD7);
    while (1) 
    {
    }
}

 

Is there something wrong with playing on I/O in a function? If I remember well, I hadn't encountered such a problem with Atmega8.

 

Thanks,

This topic has a solution.
Last Edited: Tue. Sep 6, 2016 - 10:04 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Your observations indeed sem to be illogical, but your way of determining the logic level of a pin is not very reliable. In fact you need to put at least a slight load ontop the pin to really see in which state it is, i.e. a 1K resistor.

Einstein was right: "Two things are unlimited: the universe and the human stupidity. But i'm not quite sure about the former..."

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

M103C my friend

 

(this is one of the classics!!)

 

[the thing that surprises me though is that SelectChannel() was not inlined rather than CALL'd - are you building without optimisation or something?]

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

@clawson: I don't know what is this M103C fuse but when I uncecked it, the problem was solved. So thank you :).

Concerning SelectChannel: Yes, the posted code here is simplified. I took the only the part that had a problem.

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

For your info: The mega64 and mega128 replaced the original mega103. Presumably Atmel had a very big customer for the original M103 because they decided to ship all mega64 and mega128 preset to mega103 compatibility mode so they could just be a slot in replacement. That compatibility mode is controlled by the "M103C" (Mega103 Compatibility) fuse. Until you switch it off what you have in your hands is not a mega64 or mega128 but a mega103. It has a different memory map and a restricted set of peripherals. It's the memory map thing that bit you here. You built your code, which included a CALL/RET when you introduced SelectChannel(), for "mega64" so the compiler will have generated code to start by setting the stack pointer to the place where RAM ends in the mega64. Only thing is the mega103 did not have RAM at that location. So the stack pointer was set to an invalid address. You only begin to notice this when there is a "CALL SelectChannel" and the return address is PUSHd onto the stack (that does not exist!). When that function then gets to RET it tries to read back a return address that was not successfully stored and that's why you had problems.

 

The mega64 and mega128 used to be used a lot as the "big AVR" and we used to get tons of threads here about this. Whenever anyone said something wasn't working and mentioned mega64 or mega128 the first thought would be "M103C fuse". But now we don't see so many as people pick other "big AVRs" like mega640/1280/1281/2560/1284/etc and the venerable old mega64/mega128 aren't used very much any more.