Conflicting SPI/stdlib libraries

Hello all, I hope you are doing well as you are reading this message.

Let me give some background on the issue at hand. I think I know what the problem is, however, I wouldn’t know how to go about fixing it.

I am using the Arduino DUE and the EVAL-CN0391-ARDZ Shield.

I currently am trying to get a thermo couple shield to function correctly. I have downloaded the necessary files needed to run an example sketch as directed by the Analog Devices webpage. I was almost successful in building the project but there was 2 errors (Both the same issue).

I will paste the entire error at the end of this post. But since this shield was originally made for the UNO, I think that it is trying to call generic libraries already implemented in the UNO but not the DUE. I am getting errors only on the ‘SPI_Write()’ and the ‘SPI_Read()’ functions with the shortened error message of: “conflicting declaration of C function ‘void SPI_Write(unsigned char, unsigned char*, unsigned char)’”

Here is the longer error message which I have trouble understanding:
In file included from src\All CPP Files\AD7124.cpp:50:0:
include/Communication.h:57:6: error: conflicting declaration of C function ‘void SPI_Write(unsigned char, unsigned char*, unsigned char)’
void SPI_Write(unsigned char slaveDeviceId, unsigned char* data, unsigned char bytesNumber);
^~~~~~~~~
In file included from C:\Users\Anthony.limon.platformio\packages\framework-arduino-sam\system\libsam/chip.h:58:0,
from C:\Users\Anthony.limon.platformio\packages\framework-arduino-sam\cores\arduino/Arduino.h:42,
from C:\Users\Anthony.limon.platformio\packages\framework-arduino-sam\variants\arduino_due_x/variant.h:25,
from C:\Users\Anthony.limon.platformio\packages\framework-arduino-sam\libraries\SPI\src/SPI.h:15,
from include/Communication.h:40,
from src\All CPP Files\AD7124.cpp:50:
C:\Users\Anthony.limon.platformio\packages\framework-arduino-sam\system\libsam/include/spi.h:93:13: note: previous declaration ‘void SPI_Write(Spi*, uint32_t, uint16_t)’
extern void SPI_Write( Spi* spi, uint32_t dwNpcs, uint16_t wData ) ;
^~~~~~~~~
In file included from src\All CPP Files\AD7124.cpp:50:0:
include/Communication.h:58:6: error: conflicting declaration of C function ‘void SPI_Read(unsigned char, unsigned char*, unsigned char)’
void SPI_Read(unsigned char slaveDeviceId, unsigned char* data, unsigned char bytesNumber);
^~~~~~~~
In file included from C:\Users\Anthony.limon.platformio\packages\framework-arduino-sam\system\libsam/chip.h:58:0,
from C:\Users\Anthony.limon.platformio\packages\framework-arduino-sam\cores\arduino/Arduino.h:42,
from C:\Users\Anthony.limon.platformio\packages\framework-arduino-sam\variants\arduino_due_x/variant.h:25,
from C:\Users\Anthony.limon.platformio\packages\framework-arduino-sam\libraries\SPI\src/SPI.h:15,
from include/Communication.h:40,
from src\All CPP Files\AD7124.cpp:50:
C:\Users\Anthony.limon.platformio\packages\framework-arduino-sam\system\libsam/include/spi.h:92:17: note: previous declaration ‘uint32_t SPI_Read(Spi*)’
extern uint32_t SPI_Read( Spi* spi ) ;
^~~~~~~~
In file included from src\All CPP Files\Communication.cpp:42:0:
include/Communication.h:57:6: error: conflicting declaration of C function ‘void SPI_Write(unsigned char, unsigned char*, unsigned char)’
void SPI_Write(unsigned char slaveDeviceId, unsigned char* data, unsigned char bytesNumber);
^~~~~~~~~
In file included from C:\Users\Anthony.limon.platformio\packages\framework-arduino-sam\system\libsam/chip.h:58:0,
from C:\Users\Anthony.limon.platformio\packages\framework-arduino-sam\cores\arduino/Arduino.h:42,
from C:\Users\Anthony.limon.platformio\packages\framework-arduino-sam\variants\arduino_due_x/variant.h:25,
from C:\Users\Anthony.limon.platformio\packages\framework-arduino-sam\libraries\SPI\src/SPI.h:15,
from include/Communication.h:40,
from src\All CPP Files\Communication.cpp:42:
C:\Users\Anthony.limon.platformio\packages\framework-arduino-sam\system\libsam/include/spi.h:93:13: note: previous declaration ‘void SPI_Write(Spi*, uint32_t, uint16_t)’
extern void SPI_Write( Spi* spi, uint32_t dwNpcs, uint16_t wData ) ;
^~~~~~~~~
In file included from src\All CPP Files\Communication.cpp:42:0:
include/Communication.h:58:6: error: conflicting declaration of C function ‘void SPI_Read(unsigned char, unsigned char*, unsigned char)’
void SPI_Read(unsigned char slaveDeviceId, unsigned char* data, unsigned char bytesNumber);
^~~~~~~~
In file included from C:\Users\Anthony.limon.platformio\packages\framework-arduino-sam\system\libsam/chip.h:58:0,
from C:\Users\Anthony.limon.platformio\packages\framework-arduino-sam\cores\arduino/Arduino.h:42,
from C:\Users\Anthony.limon.platformio\packages\framework-arduino-sam\variants\arduino_due_x/variant.h:25,
from C:\Users\Anthony.limon.platformio\packages\framework-arduino-sam\libraries\SPI\src/SPI.h:15,
from include/Communication.h:40,
from src\All CPP Files\Communication.cpp:42:
C:\Users\Anthony.limon.platformio\packages\framework-arduino-sam\system\libsam/include/spi.h:92:17: note: previous declaration ‘uint32_t SPI_Read(Spi*)’
extern uint32_t SPI_Read( Spi* spi ) ;
^~~~~~~~
src\All CPP Files\Communication.cpp: In function ‘void SPI_Write(unsigned char, unsigned char*, unsigned char)’:
src\All CPP Files\Communication.cpp:52:5: warning: this ‘if’ clause does not guard… [-Wmisleading-indentation]
if(slaveDeviceId == 0)
^~
src\All CPP Files\Communication.cpp:55:8: note: …this statement, but the latter is misleadingly indented as if it were guarded by the ‘if’
for(count = 0;count < bytesNumber;count++)
^~~
In file included from src\main.cpp:4:0:
include/Communication.h:57:6: error: conflicting declaration of C function ‘void SPI_Write(unsigned char, unsigned char*, unsigned char)’
void SPI_Write(unsigned char slaveDeviceId, unsigned char* data, unsigned char bytesNumber);
^~~~~~~~~
In file included from C:\Users\Anthony.limon.platformio\packages\framework-arduino-sam\system\libsam/chip.h:58:0,
from C:\Users\Anthony.limon.platformio\packages\framework-arduino-sam\cores\arduino/Arduino.h:42,
from src\main.cpp:1:
C:\Users\Anthony.limon.platformio\packages\framework-arduino-sam\system\libsam/include/spi.h:93:13: note: previous declaration ‘void SPI_Write(Spi*, uint32_t, uint16_t)’
extern void SPI_Write( Spi* spi, uint32_t dwNpcs, uint16_t wData ) ;
^~~~~~~~~
In file included from src\main.cpp:4:0:
include/Communication.h:58:6: error: conflicting declaration of C function ‘void SPI_Read(unsigned char, unsigned char*, unsigned char)’
void SPI_Read(unsigned char slaveDeviceId, unsigned char* data, unsigned char bytesNumber);
^~~~~~~~
In file included from C:\Users\Anthony.limon.platformio\packages\framework-arduino-sam\system\libsam/chip.h:58:0,
from C:\Users\Anthony.limon.platformio\packages\framework-arduino-sam\cores\arduino/Arduino.h:42,
from src\main.cpp:1:
C:\Users\Anthony.limon.platformio\packages\framework-arduino-sam\system\libsam/include/spi.h:92:17: note: previous declaration ‘uint32_t SPI_Read(Spi*)’
extern uint32_t SPI_Read( Spi* spi ) ;
^~~~~~~~
In file included from src\All CPP Files\CN0391.cpp:48:0:
include/Communication.h:57:6: error: conflicting declaration of C function ‘void SPI_Write(unsigned char, unsigned char*, unsigned char)’
void SPI_Write(unsigned char slaveDeviceId, unsigned char* data, unsigned char bytesNumber);
^~~~~~~~~
In file included from C:\Users\Anthony.limon.platformio\packages\framework-arduino-sam\system\libsam/chip.h:58:0,
from C:\Users\Anthony.limon.platformio\packages\framework-arduino-sam\cores\arduino/Arduino.h:42,
from src\All CPP Files\CN0391.cpp:41:
C:\Users\Anthony.limon.platformio\packages\framework-arduino-sam\system\libsam/include/spi.h:93:13: note: previous declaration ‘void SPI_Write(Spi*, uint32_t, uint16_t)’
extern void SPI_Write( Spi* spi, uint32_t dwNpcs, uint16_t wData ) ;
^~~~~~~~~
In file included from src\All CPP Files\CN0391.cpp:48:0:
include/Communication.h:58:6: error: conflicting declaration of C function ‘void SPI_Read(unsigned char, unsigned char*, unsigned char)’
void SPI_Read(unsigned char slaveDeviceId, unsigned char* data, unsigned char bytesNumber);
^~~~~~~~
In file included from C:\Users\Anthony.limon.platformio\packages\framework-arduino-sam\system\libsam/chip.h:58:0,
from C:\Users\Anthony.limon.platformio\packages\framework-arduino-sam\cores\arduino/Arduino.h:42,
from src\All CPP Files\CN0391.cpp:41:
C:\Users\Anthony.limon.platformio\packages\framework-arduino-sam\system\libsam/include/spi.h:92:17: note: previous declaration ‘uint32_t SPI_Read(Spi*)’
extern uint32_t SPI_Read( Spi* spi ) ;
^~~~~~~~
*** [.pio\build\due\src\All CPP Files\AD7124.cpp.o] Error 1
*** [.pio\build\due\src\main.cpp.o] Error 1
*** [.pio\build\due\src\All CPP Files\Communication.cpp.o] Error 1
*** [.pio\build\due\src\All CPP Files\CN0391.cpp.o] Error 1

An internal library used in the SAM Arduino core also happens to want to define the function SPI_Write, with C linkage (extern "C").

C has the property that a function can only exist once, even if it has different arguments. In C++, you can have overloaded functions that have the same name, but different arguments, and that’s still valid.

So sadly since the SPI_Write function in libsam/include/spi.h was declared with C linkage and you really don’t want to modify the Arduino core, you should instead rename your SPI_Write() defined in Communication.h and adapt all its original calling sites to match the new name.

1 Like

You never cease to help when no one else can. My posts have been getting views on other forums, but never get answered. Thank you for teaching me something new about C linkage error!

So after doing this, I wasn’t able to use the shield I am interfacing with. I marked the previous response as a solution because I was then able to compile and upload with the project. But I am not getting the correct readings for anything on the shield, all voltages are wrong and resistance values are off as well.

I am almost sure that this is an issue pertaining to the SPI.h/.c files in the DUE core. I think this because with the exact same code, I have no issue with reading correct values on the UNO. But the moment I plug the shield into the DUE, with the same code (fixed by renaming all new SPI_Read/SPI_Write to SPI_Read_EVAL0391/SPI_Write_EVAL0391 that came with downloading from files from Analog Devices), the serial output is showing me that perhaps certain registers are not being correctly written/read.

I am so confused because at this point I have spent days trying to do this on my own by reading through the code, posting on more than 3 forums, etc…

Not even the engineers in Analog Devices forum were able to help. Reasoning being, “You’d have to do a bit of research on your part for making it work on Due because ADI only offers the example for Uno.”

Any help would be appreciated, I do not think it is too deep, I am just definitely not experienced/intelligent in debugging a program that constantly rewrites and reads different registers.

Well I refuse to believe that it’s impossible to interface this puny SPI thermocouple chip with an Ardue Due.

Can you post the exact wireup and code you’re using for the Due, along with the output on the Due and the output on the Uno? Maybe something springs to mind.

Of course!

Here is the code that I am using, the only difference being that I changed all the SPI_Write/WPI_Read to SPI_Read_EVAL0391/SPI_Write_EVAL0391: arduino/Arduino Uno R3/examples/CN0391_example at master · analogdevicesinc/arduino · GitHub

Here is the correct output I am expecting, and that is coming from the Arduino UNO:

Here is the output for the same code on the DUE:


I will note that after the " RTD channel calibration completed ", there is a sort of time delay in comparison to the output of the the UNO code.

Here is the schematic of the shield that I am interfacing. It is connected in the exact same way that the UNO is connected:


Is there anything else you think would be helpful to know? I am going to try to print the data from many different registers in hope of seeing different register values in the two MCUs so that I can pinpoint what is being read correctly/incorrectly.

Well a smoking gun right there is that the 16777215 number is 0xffffff. That’s the 24-bit all-1 bitstring. This likely indicates that something is wrong with the SPI communication, like the MISO output not being read correctly (reading as always HIGH) or the thermocouple chip not receiving the SPI command correctly.

Do you have a logic analyzer probe? Like a Salaea clone that can be bought for <10$. You can use it to probe the SPI bus and see what’s actually going on there electrically.

I will do this, I actually randomly have a Saleae lent to me from a lab tech from my school! I will come back with results. Should I be reading in hex, decimal, or binary?

It still confuses me as this would indicate a software issue, but it works fine on the UNO, or am I confused?

Data is best in hex. SPI bus settings should be “mode 3” and 8-bit transfer size as normal.

No, not necessarily. It could still either an electrical or software problem.

What should I be looking for in my data though? I will paste some of what I got below. But I am not sure what would be useful to see.

This is the bunch of signals received after the full first display of messages:
image

Same image, zoomed in:

I am trying to match up those codes with this image:

Is this a trace when connected to the Due or the Uno?

Can you share the recorded trace file?

How should I share? Also, I exported data in two ways, Raw data in a .csv, and Capture in a Saleae Logic Capture (.sal).

.sal will do just fine.

I am unsure of how to get it to you. It is not letting me share it here.

I think if you ZIP it should work. Otherwise, Github, Google Drive, Dropbox, …

Here is the link from my Google Drive to the zip file: DUE Temp Reading.zip - Google Drive

Here is also the link for the normal file (if necessary):

The decoding is a bit hard to read because the delimiting CS signal was not captured. Could you recapture with CS (also called chip select / slave select) and reupload?

Channel 0: Chip Select
Channel 1: MOSI
Channel 2: CLK
Channel 3: MISO

New Link: DUE Temp Reading Part 2.sal - Google Drive
Link for UNO Saleae output (if helpful): UNO Temp Reading Part 2.sal - Google Drive

1 Like

Okay after editing the SPI decoder settings to use the Enable line as Channel 0 and set

  SPI.setDataMode(SPI_MODE3); //CPHA = CPOL = 1    MODE = 3

in the decoder like the sketch code says, the decoding looks much more sensible.

Comparing the first few transactions between the Due and the Uno,they’re equal.

UNO:

image

Due:

image

Question is whether the Due can correctly read this data at all. Let’s add some logging.

in SPI_Write_EVAL0391, change the code from

to

    for(count = 0;count < bytesNumber;count++)
    {
             SPI.transfer(data[count]);  // write instruction
             Serial.println("[TX] " + String(data[count], HEX));
    }

And in the read function from

to

          for(count = 0;count < bytesNumber;count++)
          {
            data[count] =  SPI.transfer(writeData[count]);
            Serial.println("[RX] " + String(data[count], HEX) + "for TX " + String(writeData[count], HEX) );
          }

Please upload the logs for that. To make it easier, you can also add

monitor_filters = log2file

to automatically create a log file via PlatformIO.

Changed the SPI_Write_EVALCN0391 function:

Changed the SPI_Read_EVALCN0391 function:

Here is the log file for the DUE program running:

Would it be helpful to try create log file for the UNO verison?
P.S. Thanks for teaching me this new logging function, makes life a bit easier.