Code compiles/uploads to MEGA 2560, but not working with Arduino DUE

Hi all! I'm new to Arduino DUE, and have a couple of them to begin getting familiar with.

I have a short piece of code show below that successfully compiled and uploaded to the MEGA 2560. Before compiling the code in arduino IDE 1.8.8, I first needed to install a library that is supposed to work with a direct digital synthesis module (DDS) .... AD9959 module. So I installed the library zip file from : GitHub - cjheath/AD9959: AD9959 4-channel Direct Digital Synthesis Arduino Library

The code that a compiled, simply named "AD9959_test1.ino" also comes from the above site, which is pasted in the code section below:

#include <SPI.h>
#include <AD9959.h>

class MyAD9959 : public AD9959<
    9,              // Reset pin (active = high)
    10,              // Chip Enable (active = low)
    31,              // I/O_UPDATE: Apply config changes (pulse high)
    25000000,       // 25MHz crystal (optional)
    1000000        //SPI @ 1 MHz
    > {};
    
  MyAD9959  dds;

void setup() {
  Serial.begin(115200);
  dds.reset();
  dds.setClock(15, 0);  // multiplier: 15, calibration: 0

  dds.setFrequency(MyAD9959::Channel1, 50000000UL);  // 50.0 MHz
  dds.setAmplitude(MyAD9959::Channel2, 1023);    // Maximum amplitude value
  dds.setPhase(MyAD9959::Channel2, 16383);    // Maximum phase value (same as -1)

  dds.update();
}

void loop() {
}

No problems at all compiling and uploading to the MEGA 2560. This is nice, as I should be able to use the MEGA 2560 to get everything done.

Now ---- switching to the Arduino DUE, I attempted to compile the same code when using the arduino IDE with board settings for the Arduino DUE (in "Programming Port" mode), I see messages like:

AD9959_test1\AD9959_test1.ino: In member function 'void AD9959<ResetPin, ChipEnablePin, UpdatePin, reference_freq, SPIRate, SPIClkPin, SPIMISOPin, SPIMOSIPin>::reset(AD9959<ResetPin, ChipEnablePin, UpdatePin, reference_freq, SPIRate, SPIClkPin, SPIMISOPin, SPIMOSIPin>::CFR_Bits) [with unsigned char ResetPin = 9u; unsigned char ChipEnablePin = 10u; unsigned char UpdatePin = 31u; long unsigned int reference_freq = 25000000ul; long int SPIRate = 1000000l; unsigned char SPIClkPin = 13u; unsigned char SPIMISOPin = 12u; unsigned char SPIMOSIPin = 11u]':

AD9959_test1:16:13: error: invalid conversion from 'int' to 'AD9959<9u, 10u, 31u, 25000000ul, 1000000l>::CFR_Bits' [-fpermissive]

   dds.reset();

At the moment, it looks like this sort of error is over my head. So would like to ask if there's something that I can alter in the code in order to address that error. I don't understand what that error means right now, and was googling phrases like "error: invalid conversion from 'int', but didn't get anywhere yet! Any tips for pointing me in the right direction will be really greatly appreciated! Thanks in advance!

i don't think this will just fix the error, but 31,              // I/O_UPDATE: Apply config changes (pulse high)a DUE doesn't have that pin. Reading back from you error msg, the error occurs on line 16, i counted them and that is when there the call to dds.reset() so in that function there is a conversion from an int to the whole 'class' somehow, anyway there is a variable that may be out of range. The approach to verifying would be to open the library's source file probably AD9959.cpp but anyway also AD9959.h and whatever is referenced in there, and look for the AD9959::reset() function. You can use Notepad++ as an editor, and see what is in that function and what variables are used within it.

Deva_Rishi:
The approach to verifying would be to open the library's source file probably AD9959.cpp but anyway also AD9959.h and whatever is referenced in there, and look for the AD9959::reset() function. You can use Notepad++ as an editor, and see what is in that function and what variables are used within it.

Thanks very much Deva for going out of your way to help me out here. Also, for letting me know that DUE doesn't have a pin 31. I put the '31' there in the code only because I can see a digital pin 31 label on the DUE board ----- in the same place where the MEGA 2560 has the label '31'.

I'm really new to the DUE, so if that pin label '31' on the DUE isn't really a GPIO pin '31', then you really helped save me barking up the wrong tree! Definitely appreciated!

Also ...... thanks for mentioning the function called 'reset', and for pointing me to that area. In the AD9959.h file, I went into there (as you suggested), and saw the following code:

void reset(
    CFR_Bits cfr =
      CFR_Bits::DACFullScale |
      CFR_Bits::MatchPipeDelay |
      CFR_Bits::OutputSineWave
  )
  {
    pulse(ResetPin);                    // (minimum 5 cycles of the 30MHz clock)
    pulse(SPIClkPin);                   // Enable serial loading mode:
    pulse(UpdatePin);

    // Apply the requested CFR bits
    last_channels = ChannelNone;        // Ensure channels get set, not optimised out
    setChannels(ChannelAll);
    write(CFR, cfr);

    setChannels(ChannelNone);           // Disable all channels, set 3-wire MSB mode:
    pulse(UpdatePin);                   // Apply the changes
    setClock();                         // Set the PLL going
    // It will take up to a millisecond before the PLL locks and stabilises.
  }

Now ...... even though I don't know what was actually doing ...... I decided to just see what happens if I changed the line that says:

CFR_Bits cfr =

to

int cfr =

That is, I replaced the word "CFR_Bits" with the word "int".

Surprisingly, even though it's probably wrong what I did, the test code than compiled and it got uploaded into the DUE. I'm suspecting that my blindly replacing the word "CFR_Bits" with "int" isn't the right thing to do.

I do know that without that particular alteration, the original test code compiled and loaded into a MEGA 2560 without any changes to the AD9959.h file.

Thanks Deva!

Surprisingly, even though it's probably wrong what I did, the test code than compiled and it got uploaded into the DUE. I'm suspecting that my blindly replacing the word "CFR_Bits" with "int" isn't the right thing to do.

probably not, dig a little deeper, how is the 'type' defined ? (in AD9959.h) and what is the prototype declaration of void reset(... ); as it is in AD9959.h and mainly what does it say within the braces, there must be a default value, since you can just call .reset() without any arguments, and there, there may also be the clue as to why it compiles for the Mega, but not for the Due (possibly different default values)

Thanks very much Deva for going out of your way to help me out here. Also, for letting me know that DUE doesn't have a pin 31. I put the '31' there in the code only because I can see a digital pin 31 label on the DUE board ----- in the same place where the MEGA 2560 has the label '31'.

Yeah sorry, i overlooked the whole bottom edge on the pinout diagram.. it does have a pin 31.

Deva_Rishi:
probably not, dig a little deeper, how is the 'type' defined ? (in AD9959.h) and what is the prototype declaration of

void reset(... );

as it is in AD9959.h and mainly what does it say within the braces, there must be a default value, since you can just call .reset() without any arguments, and there, there may also be the clue as to why it compiles for the Mega, but not for the Due (possibly different default values)

Thanks again Deva! In the code that I pasted earlier, the reset function shows this at the beginning :

void reset(
    CFR_Bits cfr =
      CFR_Bits::DACFullScale |
      CFR_Bits::MatchPipeDelay |
      CFR_Bits::OutputSineWave
  )

The above code isn't compiling for the DUE, but no issue for the MEGA 2560.

But if I change the "CFR_Bits" with int or unsigned int, then compiling is ok for the DUE, such as the following will compile for the DUE.

void reset(
    unsigned int cfr =
      CFR_Bits::DACFullScale |
      CFR_Bits::MatchPipeDelay |
      CFR_Bits::OutputSineWave
  )

And ..... in another part of the code, "CFR_Bits" is associated with enum :

// Channel Function Register
  typedef enum {
    ModulationMode   = 0xC00000,        // Mask for modulation mode
    AmplitudeModulation = 0x400000,     // Mask for modulation mode
    FrequencyModulation = 0x800000,     // Mask for modulation mode
    PhaseModulation  = 0xC00000,        // Mask for modulation mode
    SweepNoDwell     = 0x008000,        // No dwell mode
    SweepEnable      = 0x004000,        // Enable the sweep
    SweepStepTimerExt = 0x002000,       // Reset the sweep step timer on I/O_UPDATE
    DACFullScale     = 0x000300,        // 1/8, 1/4, 1/2 or full DAC current
    DigitalPowerDown = 0x000080,        // Power down the DDS core
    DACPowerDown     = 0x000040,        // Power down the DAC
    MatchPipeDelay   = 0x000020,        // Compensate for pipeline delays
    AutoclearSweep   = 0x000010,        // Clear the sweep accumulator on I/O_UPDATE
    ClearSweep       = 0x000008,        // Clear the sweep accumulator immediately
    AutoclearPhase   = 0x000004,        // Clear the phase accumulator on I/O_UPDATE
    ClearPhase       = 0x000002,        // Clear the phase accumulator immediately
    OutputSineWave   = 0x000001,        // default is cosine
  } CFR_Bits;

And ..... in another part of the code, "CFR_Bits" is associated with enum :

where it is showing that 24 bits are used, by narrowing it to 16 (int) you have disabled the modulation modes as a possible parameter, so i would go for an unsigned long. or maybe even do

void reset(
    CFR_Bits cfr = (CFR_Bits)
      CFR_Bits::DACFullScale |
      CFR_Bits::MatchPipeDelay |
      CFR_Bits::OutputSineWave
  )

if that compiles.. (dunno) it seems that because the default values are all 16-bit or less (and literals) the optimizer reduces the literal to that and then it can not increase back to the 24 bit CFR_Bits, it is a bit odd. One would think that if any of the values in the enum are of a certain size that would be the size of all, but maybe if they are never used and optimized out then not. Final conclusion, Blame the optimizer, and if you never use the modulation modes of reset(), then what you've done is fine. We could still try and trick the optimizer.

Deva ..... thanks an incredible lot for sharing your knowledge in this area... and for teaching me not just what to look for...but also approaches for handling that situation. If I get the code working on either the mega 2560 or the DUE, then I'll definitely share it on arduino forums. Thanks again Deva. More than greatly appreciated.

You're welcome !