SPI.begin problem on MEGA 2560

After lots of troubleshooting I’ve discovered that even when using SPI.begin I still need to set the SS, SCK and MOSI pins to outputs myself. Otherwise there’re absolutely no signals on those pins.

The SPI library docs do say this is necessary for the SS pin, but senior forum members have categorically said that SPI.begin handles this automatically for SCK and MOSI, but that doesn’t seem to be the case for me.

So is the SPI library not recognizing that I have a MEGA 2560 for some reason? (I’ve set the Processor type in the Tools menu)

I also confirmed that the SS, SCK and MOSI constants all point to their respective pins (53, 52, 51) using Serial.print.

So any other ideas why SPI.begin may not be setting SCK and MOSI to OUTPUT mode?

#include <SPI.h>

void SetPot(byte potValue) {
  // SPI interface to MCP4110 Digital Pot to control the IR LED intensity
  // Max SPI Frequency 10MHz 10000000
  SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));

    // take the chip select low to select the device:
    digitalWrite(SS, LOW);
  
    SPI.transfer(0x11);
    SPI.transfer(potValue);
  
    // take the chip select high to de-select:
     digitalWrite(SS, HIGH);
    
  SPI.endTransaction();
}


void setup(void) {
  Serial.begin(9600);

  Serial.print (SS);
  Serial.print (SCK);
  Serial.print (MOSI);
  // Serial consoles now shows 535251

  // Initalize the CS chip select pin on the MCP4110 digital pot
  pinMode(SS, OUTPUT); //Avoid being in SPI Slave mode which apparently can happen if this pin is an Input.
  pinMode(SCK, OUTPUT);  // If I comment this line, SCK gives no output
  pinMode(MOSI, OUTPUT); //If I comment this line MOSI gives no output.
  
  SPI.begin;
  digitalWrite(SS, HIGH);
  
}

void loop() {


  SetPot(0);
  delay (5000);
  SetPot(0xFF);  
  delay(5000);

}

Please use code tags when posting code ("</>" button on editor).

Do you have a good reason for leaving the parentheses out from the call to SPI.begin()?

  SPI.begin;

What is the evidence that there are no signals on the SPI pins?

Here is where the Arduino SPI library begin method sets SS, SCK and MOSI as outputs:

void SPIClass::begin()
{
  uint8_t sreg = SREG;
  noInterrupts(); // Protect from a scheduler and prevent transactionBegin
  if (!initialized) {
    // Set SS to high so a connected chip will be "deselected" by default
    uint8_t port = digitalPinToPort(SS);
    uint8_t bit = digitalPinToBitMask(SS);
    volatile uint8_t *reg = portModeRegister(port);

    // if the SS pin is not already configured as an output
    // then set it high (to enable the internal pull-up resistor)
    if(!(*reg & bit)){
      digitalWrite(SS, HIGH);
    }

    // When the SS pin is set as OUTPUT, it can be used as
    // a general purpose output port (it doesn't influence
    // SPI operations).
    pinMode(SS, OUTPUT);

    // Warning: if the SS pin ever becomes a LOW INPUT then SPI
    // automatically switches to Slave, so the data direction of
    // the SS pin MUST be kept as OUTPUT.
    SPCR |= _BV(MSTR);
    SPCR |= _BV(SPE);

    // Set direction register for SCK and MOSI pin.
    // MISO pin automatically overrides to INPUT.
    // By doing this AFTER enabling SPI, we avoid accidentally
    // clocking in a single bit since the lines go directly
    // from "input" to SPI control.
    // http://code.google.com/p/arduino/issues/detail?id=888
    pinMode(SCK, OUTPUT);
    pinMode(MOSI, OUTPUT);
  }

This suggests that SPI.begin() does indeed set those pins to outputs, and if they are not, that SPI.begin() is not actually being called.

Hi jr

Thanks for catching my lack of () when calling SPI.begin... that was exactly the problem. Added () and no longer need to set SCK and MOSI to output mode.

As far as why I forgot it, I'm more familiar with other languages where the () are optional unless you actually need to pass parameters, so it didn't look odd to me and the compiler didn't flag it either. But luckily YOU did. :slight_smile:

Thanks for your fast and astute help!

The fact that leaving out the parentheses is not treated as an error, but does nothing useful, is in my opinion a stupidity of the language. Doing something silly like

k;

is also legal (if k was previously declared), and not flagged either.