sandeepmistry / arduino-nRF5

Arduino Core for Nordic Semiconductor nRF5 based boards
Other
898 stars 278 forks source link

Two SPI buses and one I2C (wire) bus on nRF52 #385

Open JamesWArcher opened 5 years ago

JamesWArcher commented 5 years ago

I am trying to use 2 SPI buses and 1 I2C bus. SPI bus is connected to an SD card and SPI1 is connected to sensor A and I2C is connected to sensor B.

I used the following pins for each bus: SPI MISO: 4 SPI MOSI: 3 SPI SCK: 2 SPI1 MISO: 14 SPI1 MOSI: 13 SPI1 SCK: 12 I2C SDA: 15 I2C SCL: 16

When I test this out the following happens:

I have checked with Nordic and they have confirmed that this pin/buss configuration is possible as each peripheral (SPI, SPI1 and I2C) have their own base address.

I am using my own nrf52832 board, but I am using the Adafruit Bluefruit Feather nRF52832 as my target board in the Arduino IDE. I modified the flowing lines of code in the variance.h file to enable my dual SPI setup:

#define SPI_INTERFACES_COUNT 2 

#define PIN_SPI_MISO         (4) 
#define PIN_SPI_MOSI         (3) 
#define PIN_SPI_SCK          (2)  

#define PIN_SPI1_MISO         (14) 
#define PIN_SPI1_MOSI         (13) 
#define PIN_SPI1_SCK          (12) 

Here is a simplified version of my code that I have been using for testing, as I mentioned before each bus works there is just a conflict between SPI1 and I2C.

#include "Wire.h"
#include <SPI.h>
#include <SD.h>

extern SPIClass SPI1; // nrf52 SPI1.h does not define this 

void setup() {
    // Serial coms setup
    Serial.begin(115200);

    // Sensor A setup
    Wire.begin();
    Setup_sensor_A();

    // Sensor B setup
    SPI1.begin();
    SPI1.beginTransaction(SPISettings(1500000, MSBFIRST, SPI_MODE3));
    Setup_sensor_B();

    // SD setup
    SD.begin(SD_sel);
}

void loop() {

  //Read SPI1 sensor
  read_sensor_A();

  //Read  I2C sensor
  read_sensor_B();

  // Write to SD card
  String dataString = String("test string");
  File dataFile = SD.open("datalog.txt", FILE_WRITE);
  // if the file is available, write to it:
  if (dataFile) {
    dataFile.println(dataString);
    dataFile.close();
    // print to the serial port too:
    Serial.println(dataString);
  }
  // if the file isn't open, pop up an error:
  else {
    Serial.println("error opening datalog.txt");
  }
}

Any help would be much appreciated thank you.

JamesWArcher commented 5 years ago

This was Nordics response when I asked them if this configuration was possible:

Yes, as long as they have different base address / instantiation ID.

For the nRF52832;

SPI can use SPIM0 (0x40003000) , SPIM1 (0x40004000) and SPIM2 (0x40023000)

TWI can use TWIM0(0x40003000) and TWIM1(0x40004000).

Since you are using 2x SPI and 1x TWI/I2C, you could then use e.g. SPIM1 and SPIM2 for the SPI devices, and TWIM0 for your TWI/I2C device. You should then not have any resource conflict.

JamesWArcher commented 5 years ago

I notice that when you execute the Wire.begin() function it uses TWIM1 instead of TWIM0, this creates a conflict with SPI1 which I was originally using for Sensor B.

To fix the peripheral base address conflict problem I am now using SPI0 for my SD card, and SPI2 for sensor A and TWIM1 for sensor B. My code is now working as expected.