Problem with variable, depending on order of declaration

Hi,
I'm have a soft SPI library which work fine on nano board, STM32 board but i discover that on attiny85, it doesn't get the MISO signal. After some borring search (nothing to debug on the attiny), i find this :

class TINYSPI {
    public:
        uint8_t mosi_bit;
        uint8_t mosi_port;
        volatile uint8_t *mosi_reg;
        volatile uint8_t *mosi_out;

        uint8_t miso_bit;
        uint8_t miso_port;
        volatile uint8_t *miso_reg;
        volatile uint8_t *miso_out;
        volatile uint8_t *miso_in;

        uint8_t sck_bit;
        uint8_t sck_port;
        volatile uint8_t *sck_reg;
        volatile uint8_t *sck_out;

    TINYSPI(uint8_t _mosi, uint8_t _miso, uint8_t _sck) {
        mosi_bit = digitalPinToBitMask(_mosi);
        mosi_port = digitalPinToPort(_mosi);
        mosi_reg = portModeRegister(mosi_port);
        mosi_out = portOutputRegister(mosi_port);

        miso_bit = digitalPinToBitMask(_miso);
        miso_port = digitalPinToPort(_miso);
        miso_reg = portModeRegister(miso_port);
        miso_out = portOutputRegister(miso_port);
        miso_in = portInputRegister(miso_port);

        sck_bit = digitalPinToBitMask(_sck);
        sck_port = digitalPinToPort(_sck);
        sck_reg = portModeRegister(sck_port);
        sck_out = portOutputRegister(sck_port);
}
[...]

If i try to read the MOSI port with *miso_in & miso_bit, i get no value only on Attiny85.

If i change my code by permutting the declaration beetween miso_out and miso_in, it works :

class TINYSPI {
    public:
        uint8_t mosi_bit;
        uint8_t mosi_port;
        volatile uint8_t *mosi_reg;
        volatile uint8_t *mosi_out;

        uint8_t miso_bit;
        uint8_t miso_port;
        volatile uint8_t *miso_reg;
        volatile uint8_t *miso_in;
        volatile uint8_t *miso_out;

        uint8_t sck_bit;
        uint8_t sck_port;
        volatile uint8_t *sck_reg;
        volatile uint8_t *sck_out;

[...]

So, i keep the first example and add another attribute for miso_in in another part of my code : "miso_in = portInputRegister(miso_port);" in case of problem on miso_out and ... it runs too.

Any idea why ?

(with some test, i should have 70B of free RAM while using that library)

Thx in advance,
regards,

How much of the Tiny85 ram are you using? It only has 512 bytes.

1 Like

Try a hardware approach with SPI on the ATtiny85, like this one, which should use a fraction of the memory.

SPI is not a well defined and universally agreed-upon protocol, and you should certainly expect trouble when trying to use SPI to communicate between different microprocessors. TTL-RS232 serial is much easier to implement and more reliable.

I have around 70b RAM free at that moment

@ jremington
The problem is not SPI, the problem is why changing order of variable declaration make the value of variable usable or not.

What the other posts are getting at is that using the software SPI is consuming too much RAM. The result is that the stack is overwriting the RAM being used for variables. When you re-arrange the order of the variable declarations, the memory locations for those variables change, resulting in different variables being overwritten by the stack. That may result in the problem moving to some other section of the code, or no noticeable problem at all, depending on which specific variable gets overwritten and how that variable is used.

1 Like

You do not know what is causing the problem, but being so low on memory is a blindingly obvious issue. Anything you can do to improve that situation is a good idea.

2 Likes

This is a classic symptom of low memory causing overwriting of variables.

I agree, but if i check for memory free, i have "a lot" more (70B). My sketch leave 170B in RAM and i don't use a lot after. 100B in that case

1 Like

So, here was a problem and looks working now.

I got the SPI class, called outside cpp file of two other class :

file my_prog.ino:
#if defined(call_Class1)
#include Class1.h
#elif defined(call_Class2)
#include Class2.h
#endif

file Class1.cpp :
TINYSPI Class1_SPI TINYSPI(1,2,3)
Class1{
[...]
}

file Class2.cpp :
TINYSPI Class2_SPI TINYSPI(1,2,3)
Class2{
[...]
}

Inside avr-debug, i can see that Class2_SPI exist despite there is no include of Class2.cpp. It should not make any problem, but i don't know why now its working. (-20B of RAM)
I know you said that its memory problem, but make no sens with all the free RAM i have.

I see that Cleopatra isn't the only Queen of de-Nile.

70B is not "a lot" of memory by any stretch of the imagination given that it doesn't account for any stack use.

2 Likes

Maybe you could argue more than being sarcastic ?

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.