SPI include problem

Hi,

I'm porting SPI to the STM32 architecture, but I"m having issues with the SPI instance of SPIClass being instantiated or declared

#include <SPI.h>
void setup() {
SPI.begin();
}
void loop() {}

Gives the error

sketch_nov16a.ino: In function 'void setup()':
sketch_nov16a.ino:7:1: error: 'SPI' was not declared in this scope
Error compiling.

Bascially what I have done is taken the AVR SPI.cpp and SPI.h and copied them to my new hardware folder

hardware\Arduino_STM32\STM32F1XX\libraries\SPI

I know that both the cpp and the .h are both getting compiled and I get this message

Using library SPI in folder: C:\Users\rclark\Documents\Arduino\hardware\Arduino_STM32\STM32F1XX\libraries\SPI (legacy)

But I don't know what this means.

If I put a delibarate error in SPI.CPP or SPI.h I get a compile error

e.g. if I put

aaa bbb;

in SPI.cpp it immediately gives a compile error e.g

C:\Users\rclark\Documents\Arduino\hardware\Arduino_STM32\STM32F1XX\libraries\SPI\SPI.cpp:15:1: error: 'aaa' does not name a type
aaa bbb;
^
Error compiling.

I really dont understand, why if I take out SPI.begin() it compiles my stub functions, but as soon as I put SPI.begin() into setup, it immediately falls over

I don't think its SPI.cpp or SPI.h are the issue, but here they are.

As they are just the AVR files with all the methods converted into sub functions, just to get it to compile.

ummm unless the problem is just that there is no useful code ???

/*
 * Copyright (c) 2010 by Cristian Maglie <c.maglie@bug.st>
 * Copyright (c) 2014 by Paul Stoffregen <paul@pjrc.com> (Transaction API)
 * SPI Master library for arduino.
 *
 * This file is free software; you can redistribute it and/or modify
 * it under the terms of either the GNU General Public License version 2
 * or the GNU Lesser General Public License version 2.1, both as
 * published by the Free Software Foundation.
 */

#include "SPI.h"
//#include "pins_arduino.h"

SPIClass SPI;

uint8_t SPIClass::interruptMode = 0;
uint8_t SPIClass::interruptMask = 0;
uint8_t SPIClass::interruptSave = 0;
#ifdef SPI_TRANSACTION_MISMATCH_LED
uint8_t SPIClass::inTransactionFlag = 0;
#endif

void SPIClass::begin() {
}

void SPIClass::end() {
}



void SPIClass::usingInterrupt(uint8_t interruptNumber)
{
}
/*
 * Copyright (c) 2010 by Cristian Maglie <c.maglie@bug.st>
 * Copyright (c) 2014 by Paul Stoffregen <paul@pjrc.com> (Transaction API)
 * Copyright (c) 2014 by Matthijs Kooijman <matthijs@stdin.nl> (SPISettings AVR)
 * SPI Master library for arduino.
 *
 * This file is free software; you can redistribute it and/or modify
 * it under the terms of either the GNU General Public License version 2
 * or the GNU Lesser General Public License version 2.1, both as
 * published by the Free Software Foundation.
 */

#ifndef _SPI_H_INCLUDED
#define _SPI_H_INCLUDED

#include <Arduino.h>

// SPI_HAS_TRANSACTION means SPI has beginTransaction(), endTransaction(),
// usingInterrupt(), and SPISetting(clock, bitOrder, dataMode)
#define SPI_HAS_TRANSACTION 1

// Uncomment this line to add detection of mismatched begin/end transactions.
// A mismatch occurs if other libraries fail to use SPI.endTransaction() for
// each SPI.beginTransaction().  Connect a LED to this pin.  The LED will turn
// on if any mismatch is ever detected.
//#define SPI_TRANSACTION_MISMATCH_LED 5

#ifndef LSBFIRST
#define LSBFIRST 0
#endif
#ifndef MSBFIRST
#define MSBFIRST 1
#endif

class SPISettings {
};


class SPIClass {
public:
  // Initialize the SPI library
  static void begin();

  // If SPI is to used from within an interrupt, this function registers
  // that interrupt with the SPI library, so beginTransaction() can
  // prevent conflicts.  The input interruptNumber is the number used
  // with attachInterrupt.  If SPI is used from a different interrupt
  // (eg, a timer), interruptNumber should be 255.
  static void usingInterrupt(uint8_t interruptNumber);

  // Before using SPI.transfer() or asserting chip select pins,
  // this function is used to gain exclusive access to the SPI bus
  // and configure the correct settings.
  inline static void beginTransaction(SPISettings settings) 
  {
    
  }

  // Write to the SPI bus (MOSI pin) and also receive (MISO pin)
  inline static uint8_t transfer(uint8_t data) {
    return 0;
  }
  inline static uint16_t transfer16(uint16_t data) {
	
    return 0;
  }
  inline static void transfer(void *buf, size_t count) {
    
  }
  // After performing a group of transfers and releasing the chip select
  // signal, this function allows others to access the SPI bus
  inline static void endTransaction(void) {
   
  }

  // Disable the SPI bus
  static void end();

  // This function is deprecated.  New applications should use
  // beginTransaction() to configure SPI settings.
  inline static void setBitOrder(uint8_t bitOrder) {
  }
  // This function is deprecated.  New applications should use
  // beginTransaction() to configure SPI settings.
  inline static void setDataMode(uint8_t dataMode) {
  }
  // This function is deprecated.  New applications should use
  // beginTransaction() to configure SPI settings.
  inline static void setClockDivider(uint8_t clockDiv) {
  }
  // These undocumented functions should not be used.  SPI.transfer()
  // polls the hardware flag which is automatically cleared as the
  // AVR responds to SPI's interrupt
  inline static void attachInterrupt() {  }
  inline static void detachInterrupt() { }

private:
  static uint8_t interruptMode; // 0=none, 1=mask, 2=global
  static uint8_t interruptMask; // which interrupts to mask
  static uint8_t interruptSave; // temp storage, to restore state
  #ifdef SPI_TRANSACTION_MISMATCH_LED
  static uint8_t inTransactionFlag;
  #endif
};

extern SPIClass SPI;

#endif

To avoid errors in adding libraries to the ide and your code its easiest to use the ide to load the library from the downloaded zip folder, from the Sketch menu ->Import Library -> add library, and select the downloaded zip file.

Interesting. I don't have the core files for STM32 but decided to recreate the problem by replacing my SPI.h and SPI.cpp with those you have here. Then attempting to compile the small example. I get no errors.

Just to check it's using the new ones, I then added #error blobby blobby to the .cpp Attempting to compile again, sure enough I get error #error blobby blobby

Removing the blobby I then decided to move SPI.h and SPI.cpp to arduino/cores/arduino Attempting to compile under these conditions I get a whole raft of errors being kicked out by C:\arduino\arduino-1.0.5-r2\libraries\Robot_Control\ArduinoRobot.cpp WTF (the board selected in the ide is "Arduino Mega 2560 or Meg ADK" )

Yet still no complaints about SPI being not defined

Sorry I'm at a loss. :frowning:

I don't think I would name my different libraries with the names of the original ones.

Guys,

As far as I can tell, each hardware defines its own SPI and Wire classes (which isnt much of a surprise as they are hardware specific)

ie

For AVR

C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\SPI (and Wire, and SoftwareSerial and EEPROM)

For (SAM)

C:\Program Files (x86)\Arduino\hardware\arduino\sam\libraries\SPI (and Wire)

Hence in any new hardware architecture, there also needs to be a definition for both Wire and SPI

So I have
... Documents\Arduino\hardware\Arduino_STM32\STM32F1XX\libraries\SPI (and Wire and some EEPROM and some other architecture specific code)

This works fine for Wire and EEPROM, however SPI seems to be a special case

The IDE seems to pre-parse the file and look for SPI and the first thing it does is display a message about using "(Legacy) SPI"

Which makes me very suspicious about what is happening behind the scenes with the IDE.

I'm not sure if this is the correct part of the forum to try to get information about the internal workings of the IDE, so if its wrong, can a moderator please move this thread.

The weird thing with this, is that if I don't put in SPI.Begin() I can see the whole thing compile (in verbose mode)

But as soon as I even try to declare an instance of SPIClass, I immediately get an error, even though I just say it compile SPI.C which also declares an instance of SPI.

If not... It looks like my only option is to download the source code for the IDE and work out when and why that message is generated.
So I've no started to download the IDE sources, but its going to take some time.

I just found this

I guess my best option is to try this new library format, but I'm not sure if it applies to core libraries

OK

I think I've solved my own problem, with a bit of a hack

I'm not sure why this is necessary, but if I put this into the equivalent of Arduino.h

#include <../../libraries/SPI/src/SPI.h>

It all compiles OK and I can add SPI.begin() to my code without it freaking out.

Actually, now that I look at it.

This is basically with the SAM core seems to do

Arduino.h includes Chip.h which includes SPI.h

So I guess there is a precedence for this.

It still seems weird that there are no includes for wire.h in Arduino.h or now chain of includes from Arduino.h that appear to include Wire.h from Arduino.h

So I'm still a bit perplexed what the difference there is between these two types of perpipheral that the code handles them differently

I have no idea how the IDE works except by deduction from observation.