CC3000 mixed with other SPI perihperals

Status
Not open for further replies.

christoph

Well-known member
Hi all,

I'm trying to add a CC3000 (adafruit breakout board) to an existing design that uses SdFat and my DMA SPI driver already (those two go together quite well). However, I'm having difficulties figuring out what I would have to do to add the CC3000 to this. I'm currently just tinkering with the board and have succesfully built and tested adafruit's buildtest and webClient examples. That was very cool already.

I don't need to enable DMA for the CC3000, but I need a clean way of switching between SPI drivers. I'd be very happy if anyone can point out a way to enable the CC3000's SPI driver and disable it again, possibly including cleanup of the SPI registers.

Regards

Christoph
 
I had similar issues so far with using the Adafruit 2.8" TFT with touch, when I updated the display code to use the high speed SPI code that has the hardware also control the CS lines... Once I would start the Touch code which uses the SPI library, the display would stop working. So I hacked up my own code which I have mentioned in a few threads.

Just in case it would help, here is a simple test case I modified for a member up on the Lynxmotion forums.

Kurt
 

Attachments

  • Philtkp_Screen_Test-140623a.zip
    1.8 KB · Views: 146
I thought about writing an SPI switcher class that can create a copy of the relevant SPI settings after a driver has been initialized with begin() (or whatever the method might be called), and can switch between different "SPI contexts".
 
I've created a (currently still empty) repo for my SpiBackup class. I need this now because I have three SPI drivers fighting in my application (DmaSpi, SdFat and CC3000). This is what I have in mind for the interface:
Code:
Sd2Card card;
SpiBackup sdSpiBackup;
Adafruit_CC3000 cc3000;
SpiBackup cc3000SpiBackup;

void setup()
{
  if(!card.init(SPI_HALF_SPEED))
  {
    //... error handling
  }
  waitForSpi() ; <-- waits for the SPI to finish current transfers
  SdSpiBackup = createSpiBackup();
  haltSpi(); // <-- clears all SPI registers and pending flags
  
  // init more drivers and create SPI backups
  if (!cc3000.begin())
  {
    //... error handling
  }
  waitForSpi();
  cc3000SpiBackup = createSpiBackup();
  haltSpi();
}

void loop
{
  restoreSpi(sdSpiBackup); // <-- halts the SPI and initializes it for SD card usage
  
  // do SD card stuff here

  restoreSpi(cc3000SpiBackup);

  // do WiFi stuff here
}
I would probably move waitForSpi() and haltSpi() into createSpiBackup() because those would very likely be used together all the time.
 
Last edited:
For simple cases, it's even simpler than I thought. I've tested it with SDFat, adafruit's CC3000 driver, and DMA SPI mixed in one application.

Code:
#ifndef SPIBACKUP_H
#define SPIBACKUP_H

struct SpiBackup
{
  SpiBackup() = default;

  void create()
  {
    MCR = SPI0_MCR;
    CTAR0 = SPI0_CTAR0;
    CTAR1 = SPI0_CTAR1;
    RSER = SPI0_RSER;
  }
  uint32_t MCR;
  uint32_t CTAR0;
  uint32_t CTAR1;
  uint32_t RSER;

  void restore()
  {
    // halt SPI, clear all mode bits
    SPI0_MCR = SPI_MCR_HALT;
    // clear all pending flags
    SPI0_SR = 0xFFFFFFFF;
    // restore settings
    SPI0_RSER = RSER;
    SPI0_CTAR0 = CTAR0;
    SPI0_CTAR1 = CTAR1;
    // clear
    SPI0_MCR = MCR | SPI_MCR_CLR_RXF | SPI_MCR_CLR_TXF;
  }
};

#endif // SPIBACKUP_H

Pseudo-ish usage example:
Code:
SdFat sdFat;
SpiBackup sdFatSpiBackup;
SpiBackup dmaSpiBackup;
Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT,
                                         SPI_CLOCK_DIVIDER);
SpiBackup cc3000SpiBackup;

void setup()
{
  sdFat.begin(SD_CS_PIN, SPI_HALF_SPEED);
  sdFatSpiBackup.create();
  cc3000.begin();
  cc3000SpiBackup.create();
  DMASPI0.begin();
  dmaSpiBackup.create();
}

void loop()
{
  // do DMA SPI stuff
  
  sdFatSpiBackup.restore();
  // do SD card stuff

  cc3000SpiBackup.restore();
  // do WiFi stuff

  dmaSpiBackup.restore();
}

So if anyone tries this, please report any problems you run into!

I'll now add this to my repo.

Regards

Christoph
 
christoph, it is look as the good work, but doesnt work for me. I think, that you are using some dependent libraries. I try all libraries for adafruit cc3000, sdfat and DMI SPI, but still with errors and with some no defined functions. Please can you post whole code and attached all libraries in your code or help me someway. Thank you.
 
acharis, I never actually got those working together satisfyingly. There is a new version of the adafruit CC3000 library and a new version of the SdFat library that use SPI transactions. Here is the link: http://forum.pjrc.com/threads/26114...ary-non-blocking?p=51824&viewfull=1#post51824

So if your goal is to get SdFat and the CC3000 to work, the above link is probably all you need.

DmaSpi is currently being modified to work with teensyduino 1.20 RC2, but unfortunately, it doesn't seem to work satisfyingly (yet). See here: http://forum.pjrc.com/threads/26479-DmaSpi-for-teensyduino-1-20-RC2

The DmaSpi thread contains a link to the current github repo, and you should make sure to get the teensyduino_1.20_RC2 branch. That branch uses SPI transactions. Try the included loopback example first to see if everything works for you. If you have questions or run into problems, post in that thread, not here.

Regards

Christoph
 
acharis, I never actually got those working together satisfyingly. There is a new version of the adafruit CC3000 library and a new version of the SdFat library that use SPI transactions. Here is the link: http://forum.pjrc.com/threads/26114...ary-non-blocking?p=51824&viewfull=1#post51824

So if your goal is to get SdFat and the CC3000 to work, the above link is probably all you need.

DmaSpi is currently being modified to work with teensyduino 1.20 RC2, but unfortunately, it doesn't seem to work satisfyingly (yet). See here: http://forum.pjrc.com/threads/26479-DmaSpi-for-teensyduino-1-20-RC2

The DmaSpi thread contains a link to the current github repo, and you should make sure to get the teensyduino_1.20_RC2 branch. That branch uses SPI transactions. Try the included loopback example first to see if everything works for you. If you have questions or run into problems, post in that thread, not here.

Regards

Christoph

Thank you for explanation. At this moment I used workaround (software SPI on ArduinoMega).
 
If you are indeed using an ArduinoMega, DmaSpi cannot work for you because the mega2560 does not have DMA and DmaSpi is written for the Teensy 3.0/3.1 only.
 
Status
Not open for further replies.
Back
Top