Author Topic: SPI Conflict between RFM69 and SD library  (Read 12254 times)

Lensdigital

  • Full Member
  • ***
  • Posts: 151
    • Xronos Clock
SPI Conflict between RFM69 and SD library
« on: January 24, 2016, 09:19:45 PM »
I have a question about RFM69 library.
In my Xronos clocks I used to use both RFM12b and my version of WaveShield with SD card.  Since RFM12b and SD Card share SPI bus I used different SS pins for each. I still had conflict between too, but I was able to remedy it by putting RFM12b into sleep with radio.sleep() command just before playing wave from SD card. This worked pretty well.
Now I built new version with RFM69 chip and this trick doesn't work anymore... :(
As soon as I initialize RADIO, SD card stops working... Both work on their own but not together. radio.sleep no longer does the trick, it must work different in new library...
Just FYI I'm using ATMega1284p. SS for RFM is D18 (I use radio.setCS(18))  and for SD card it's D4.
Is there some kind of command that disables RFM69 chip temporary other than sleep()?
Check out my hand made open source Xronos Alarm Clock!
http://www.xronosclock.com

emjay

  • Full Member
  • ***
  • Posts: 119
  • Country: nl
Re: SPI Conflict between RFM69 and SD library
« Reply #1 on: January 25, 2016, 02:55:49 AM »
You have a firm pullup on D18?

perky

  • Hero Member
  • *****
  • Posts: 873
  • Country: gb
Re: SPI Conflict between RFM69 and SD library
« Reply #2 on: January 25, 2016, 06:33:15 AM »
I did a project some time ago that shared the SPI bus with an SD card. You might want to look at the MISO signal with a 'scope, I found that some SD cards don't release their MISO signal to high impedance when its chip select is inactive. You'll see if that happens because you'll get an undefined logic level on the MISO. The solution was to place a 470R resistor between the SD card's MISO and the MCU, that way whatever you're accessing can overdrive the MCU's MISO.

Mark.

Lensdigital

  • Full Member
  • ***
  • Posts: 151
    • Xronos Clock
Re: SPI Conflict between RFM69 and SD library
« Reply #3 on: January 25, 2016, 07:36:40 AM »
Yup I have 10K pullups on both SS.
Mark, thats interesting, I'll check MISO with scope. Althogh  in my case RFM overrides SD card. I made a little progress. If I initialize SD card after RFM, I can read files, but as soon as data pocket comes over radio I no longer able to read SD. Its like RFM refuses to release SS. I'll check it with scope today...
Check out my hand made open source Xronos Alarm Clock!
http://www.xronosclock.com

perky

  • Hero Member
  • *****
  • Posts: 873
  • Country: gb
Re: SPI Conflict between RFM69 and SD library
« Reply #4 on: January 25, 2016, 08:07:19 AM »
OK, it could be the other way round (I presume you mean it's like the RFM is not releasing MISO to high impedance, the SS is controlled by the MCU). Maybe the state of the MISO pin from the RFM actually determines whether the SD card can override it and that state could be different from the initialization state after a packet has been received. That would explain things, but your 'scope is going to show something. The solution might be the other way round then, either add a tri-statable buffer between the RFM' MISO and the MCU or put a 470R resistor between it and the MCU.
Mark.

Lensdigital

  • Full Member
  • ***
  • Posts: 151
    • Xronos Clock
Re: SPI Conflict between RFM69 and SD library
« Reply #5 on: January 25, 2016, 09:03:22 AM »
Will try that too. Although I'm a noob when it comes to scope, so I need to figure that out :)
Done more testing before going to work. This time I was only sending data without requesting for ACK. 
i.e. send pocket, read SD card and it works great. I'm able to read SD card right after transmitting even without putting radio to sleep!  But if I do request for ACK it locks SD card :( So Transmissions are ok, receives do not release SPI or SS line. 
Maybe Felix has a suggestion since he knows his code best :)
Check out my hand made open source Xronos Alarm Clock!
http://www.xronosclock.com

TomWS

  • Hero Member
  • *****
  • Posts: 1925
Re: SPI Conflict between RFM69 and SD library
« Reply #6 on: January 25, 2016, 10:47:36 AM »
I use SD  card in my gateways using the same SPI interface as the radio and did have an issue with older version cards. HC cards work well.
Tom

Lensdigital

  • Full Member
  • ***
  • Posts: 151
    • Xronos Clock
Re: SPI Conflict between RFM69 and SD library
« Reply #7 on: January 25, 2016, 12:03:02 PM »
I use SD  card in my gateways using the same SPI interface as the radio and did have an issue with older version cards. HC cards work well.
Tom
What kind of issues did you have?
Check out my hand made open source Xronos Alarm Clock!
http://www.xronosclock.com

Felix

  • Administrator
  • Hero Member
  • *****
  • Posts: 6332
  • Country: us
    • LowPowerLab
Re: SPI Conflict between RFM69 and SD library
« Reply #8 on: January 25, 2016, 01:05:48 PM »
My first thought is that you might need to stop interrupts from the radio with noInterrupts(), then do your SD work, then reenable with interrupts().

Lensdigital

  • Full Member
  • ***
  • Posts: 151
    • Xronos Clock
Re: SPI Conflict between RFM69 and SD library
« Reply #9 on: January 25, 2016, 02:13:55 PM »
My first thought is that you might need to stop interrupts from the radio with noInterrupts(), then do your SD work, then reenable with interrupts().
Thanks Felix. No unfortunately noInterrupts() also kills Audio playback :( I think DAC uses internal interrupts as well...
Check out my hand made open source Xronos Alarm Clock!
http://www.xronosclock.com

Felix

  • Administrator
  • Hero Member
  • *****
  • Posts: 6332
  • Country: us
    • LowPowerLab
Re: SPI Conflict between RFM69 and SD library
« Reply #10 on: January 25, 2016, 02:16:41 PM »
Then just specifically disable the interrupt on pin D2 (interrupt 0 of the atmega328p).

Lensdigital

  • Full Member
  • ***
  • Posts: 151
    • Xronos Clock
Re: SPI Conflict between RFM69 and SD library
« Reply #11 on: January 25, 2016, 02:41:18 PM »
Then just specifically disable the interrupt on pin D2 (interrupt 0 of the atmega328p).
Good idea! I tried it, but it didn't work :( 
detachInterrupt (2); (tried 0 and 1 as well)
Meanwhile I found a workaround... If I call "initialize" SD Card command before next read, it works. I'm now trying to "deconstruct" and understand that part of SDReader.cpp library to see which action gives control back to SD card...
« Last Edit: January 25, 2016, 05:41:13 PM by Lensdigital »
Check out my hand made open source Xronos Alarm Clock!
http://www.xronosclock.com

Lensdigital

  • Full Member
  • ***
  • Posts: 151
    • Xronos Clock
Re: SPI Conflict between RFM69 and SD library
« Reply #12 on: January 25, 2016, 05:46:22 PM »
Here it is "magic code" that re-enables SD card for reading. I'm not going to pretend I understand most of it, but these is bare minimum code I was able to extract from WaveHC library (specifically SdReader.cpp) in order for it to resurrect SD card after RFM69 recieved data...
I measured timing and it takes 1-122 milliseconds to execute (usually 1-2 but sometimes I see it takes 122, that's when waitNotBusy function is running)...
Code: [Select]
void sdReset() {
  byte r;
  // initialize card and send host supports SDHC if SD2
  for (uint16_t t0 = millis();;) {
    cardCommand(CMD55, 0);
    r = cardCommand(ACMD41, SD_CARD_TYPE_SD2 ? 0X40000000 : 0);
    if (r == R1_READY_STATE) break;
  }
}

/** Send a byte to the card */
void spiSend(byte b) {
  SPDR = b; while(!(SPSR & (1 << SPIF)));}

/** Receive a byte from the card */
byte spiRec(void) {spiSend(0XFF); return SPDR;}

// send command to card
byte cardCommand(byte cmd, uint32_t arg) {
  byte r1;
  // wait up to 300 ms if busy
  waitNotBusy(300);
  // send command
  spiSend(cmd | 0x40);
  // wait for response
  for (byte retry = 0; ((r1 = spiRec()) & 0X80) && retry != 0XFF; retry++){
  }
  return r1;
}

//------------------------------------------------------------------------------
// wait for card to go not busy
byte waitNotBusy(uint16_t timeoutMillis) {
  uint16_t t0 = millis();
  while (spiRec() != 0XFF) {
    if (((uint16_t)millis() - t0) > timeoutMillis) return false;
  }
  return true;
}

Just execute sdReset() after all radio stuff is done (i.e. send ACK, etc.)
Hope it helps someone who might experience similar conflict. And if anyone can understand what this code does, I'd love to hear explanation! :)
Check out my hand made open source Xronos Alarm Clock!
http://www.xronosclock.com

perky

  • Hero Member
  • *****
  • Posts: 873
  • Country: gb
Re: SPI Conflict between RFM69 and SD library
« Reply #13 on: January 25, 2016, 07:57:40 PM »
Just wondered if you've been able to look at MISO at all. One thing you could try is simply read a single byte from it rather than initialize as a read uses 0xFF as the write data, this would leave MISO high. Also try reading but using 0x00 as the write data instead to leave MISO low. Just curious if it has an effect.
Mark.

oric_dan

  • Jr. Member
  • **
  • Posts: 64
Re: SPI Conflict between RFM69 and SD library
« Reply #14 on: January 25, 2016, 09:08:37 PM »
Trying to share the SPI port between multiple devices is fraught with potential problems. The original Arduino SD libraries had the MISO hang problem, the newer libraries have supposedly this fixed. I'm not sure which library Moteino uses. Whether this is the current problem or not, the following thread may be of some interest:
http://forum.arduino.cc/index.php?topic=276274.0

This is an especial problem when SPI uses hardware [external] interrupts. FWIW, the Teensy guy attempted to create a workaround with his beginTransaction() and endTransaction() functions, but I don't know how effective his solution is [also, I've never ever been able to figure out how interrupts work on the Teensy boards using ARM chips].

So, I'm tossing this out _ONLY_ in the case anyone wants to take the time to try and figure "Transactions" out [!!!], but I don't understand it very well myself:
http://www.pjrc.com/teensy/td_libs_SPI.html
« Last Edit: January 26, 2016, 02:39:29 PM by oric_dan »

Lensdigital

  • Full Member
  • ***
  • Posts: 151
    • Xronos Clock
Re: SPI Conflict between RFM69 and SD library
« Reply #15 on: February 14, 2016, 07:29:28 PM »
I'm still banging my head on the wall over this one. My "workaround" didn't work in long run, whole micro-controller freezes when radio signal comes in while it's playing WAV file from SD Card.
Felix as you suggested, I was able to figure out how to disable correct interrupt and it works with SD card
Code: [Select]
detachInterrupt(digitalPinToInterrupt(2));
But to get Radio working again I need enable it, and so far I couldn't figure out how to do it...
In your library it ran during init:
Code: [Select]
attachInterrupt(_interruptNum, RFM69::isr0, RISING);
I've tried running this from my sketch:
Code: [Select]
attachInterrupt(digitalPinToInterrupt(2), radio.isr0(), RISING);
But it gives me error:
RFM69.h:122:17: error: 'static void RFM69::isr0()' is protected

Is there any way I can attach interrupt within my program?
Check out my hand made open source Xronos Alarm Clock!
http://www.xronosclock.com

TomWS

  • Hero Member
  • *****
  • Posts: 1925
Re: SPI Conflict between RFM69 and SD library
« Reply #16 on: February 15, 2016, 08:23:19 AM »
Just call radio.initialize() again.  It will reattach its own interrupt.  You could also simply mask and unmask interrupt 2.  A simple DAGS will provide code for this.

Tom

TD22057

  • Newbie
  • *
  • Posts: 26
  • Country: us
Re: SPI Conflict between RFM69 and SD library
« Reply #17 on: February 15, 2016, 11:29:03 AM »
Just a coding note:
isr0 is a static function - you don't need the 'radio' variable instance to access it or call it.  In your attachInterrupt code, you want to pass the function, not call it and pass the return value.  So:

Code: [Select]
// WRONG:
attachInterrupt(digitalPinToInterrupt(2), radio.isr0(), RISING);
// RIGHT:
attachInterrupt(digitalPinToInterrupt(2), RFM69::isr0, RISING);

Of course it's still protected.  But if you wanted to inherit from RFM69, you can do something like this and then call the add/del methods to take care of the interrupt.

Code: [Select]
class MyRFM69 : public RFM69 {
public:
   // Pass through constructor
   MyRFM69(uint8_t slaveSelectPin=RF69_SPI_CS, uint8_t interruptPin=RF69_IRQ_PIN,
           bool isRFM69HW=false, uint8_t interruptNum=RF69_IRQ_NUM)
      : RFM69(slaveSelectPin, interruptPin, isRFM69HW, interruptNum) {
   }

   void enableInterrupt() {
      attachInterrupt(_interruptNum, RFM69::isr0, RISING);
      }
   void disableInterrupt() {
      detachInterrupt(_interruptNum);
   }
};

Lensdigital

  • Full Member
  • ***
  • Posts: 151
    • Xronos Clock
Re: SPI Conflict between RFM69 and SD library
« Reply #18 on: February 15, 2016, 03:53:57 PM »
Just call radio.initialize() again.  It will reattach its own interrupt.  You could also simply mask and unmask interrupt 2.  A simple DAGS will provide code for this.

Thanks Tom!  I actually am calling radio.initialize() every time after Audio finished playing. I think I'm also have call radio.encrypt() as well, so I'm doing it just in case. 
I'm not sure I understand what do you mean by unamsk interrupt? And what is DAGS?

Code: [Select]
// ==================================================
// -- Turns off radio and keeps track of it's status
void turnOffRadio() {
 if (!isRadioPresent) return;
 //radio.Sleep();
 if (radioOn) {
   //radio.sleep();
   radioOn=false;
  putstring_nl ("Radio Off!");
  delay (5);
  detachInterrupt(digitalPinToInterrupt(2));
 }
}

// ====================================================================
// -- Re-initializes radio after it was diabled by interrupt function
void reEnableRadio() {
  if (!isRadioPresent) return;
  if (radioOn) return;
  if (isInMenu) return;
  if (soundAlarm[0] || soundAlarm[1]) return;
  if (wave.isplaying) return;
  if (isInQMenu) return;
  putstring_nl("Re-enable Radio");
  radio.initialize(FREQUENCY, NODEID, NETWORKID);
  radio.encrypt(KEY);
  radioOn=true;
  radio.sleep();
  card.init(); // Reset SD Card
}

So before playing audio I call turnOffRadio() function.  reEnableRadio() is running in main loop, and once it sees it can do it's thing it reinitialize radio (and SD card).  This seems to work pretty well, but probably uses unnecessary resources.

TD22057, thanks so much for your code! I'll try to add it to the library.
Check out my hand made open source Xronos Alarm Clock!
http://www.xronosclock.com

TomWS

  • Hero Member
  • *****
  • Posts: 1925
Re: SPI Conflict between RFM69 and SD library
« Reply #19 on: February 15, 2016, 04:34:06 PM »
Just call radio.initialize() again.  It will reattach its own interrupt.  You could also simply mask and unmask interrupt 2.  A simple DAGS will provide code for this.

Thanks Tom!  I actually am calling radio.initialize() every time after Audio finished playing. I think I'm also have call radio.encrypt() as well, so I'm doing it just in case. 
I'm not sure I understand what do you mean by unamsk interrupt? And what is DAGS?
DAGS:= 'Do A Google Search'

DAGS "AVR disable INT0" and you will find, among other things:

Code: [Select]
EIMSK &= ~(1 << INT0);

DAGS "AVR Enable INT0" and you will probably find:
Code: [Select]
EIMSK |= (1 << INT0);

This, of course, assumes that you are using a 328P.  If using a Mega the INT# is different and the mask register is different but a simple DAGS will find it for you.


Tom
UPDATE:  Of course, it would probably be a BETTER google search if you mention AtMega328P since THAT processor uses the EIMSK register, NOT the GICR register.  Code is corrected above.  :-[

And in the case of the AtMega1284, the INT for the Radio is INT2 so... EIMSK &= ~(1<<INT2);
« Last Edit: February 15, 2016, 04:56:43 PM by TomWS »

Lensdigital

  • Full Member
  • ***
  • Posts: 151
    • Xronos Clock
Re: SPI Conflict between RFM69 and SD library
« Reply #20 on: February 15, 2016, 04:49:09 PM »
Ah ok! Cool, I'll try to figure it out then from Datasheet :)
I'm using ATmega1284p, so far no easy google results on that one :)
Check out my hand made open source Xronos Alarm Clock!
http://www.xronosclock.com

Lensdigital

  • Full Member
  • ***
  • Posts: 151
    • Xronos Clock
Re: SPI Conflict between RFM69 and SD library
« Reply #21 on: February 15, 2016, 05:32:30 PM »
Thanks again Tom.
Is "INT2" a variable of some sort? Cause it doesn't compile :(
Code: [Select]
EIMSK &= ~(1<<INT2);

'INT2' was not declared in this scope

Check out my hand made open source Xronos Alarm Clock!
http://www.xronosclock.com

TomWS

  • Hero Member
  • *****
  • Posts: 1925
Re: SPI Conflict between RFM69 and SD library
« Reply #22 on: February 15, 2016, 06:13:33 PM »
Thanks again Tom.
Is "INT2" a variable of some sort? Cause it doesn't compile :(
Code: [Select]
EIMSK &= ~(1<<INT2);

'INT2' was not declared in this scope
You DO have the Moteino Mega selected as your Board in the Tools menu, right?????


Lensdigital

  • Full Member
  • ***
  • Posts: 151
    • Xronos Clock
Re: SPI Conflict between RFM69 and SD library
« Reply #23 on: February 15, 2016, 06:25:12 PM »
You DO have the Moteino Mega selected as your Board in the Tools menu, right?????
LOL, no :)
It's my own board, for clocks that I make :)
Bootloader is "Maniacbug" Mighty 1284p
« Last Edit: February 15, 2016, 06:26:43 PM by Lensdigital »
Check out my hand made open source Xronos Alarm Clock!
http://www.xronosclock.com

Felix

  • Administrator
  • Hero Member
  • *****
  • Posts: 6332
  • Country: us
    • LowPowerLab
Re: SPI Conflict between RFM69 and SD library
« Reply #24 on: February 16, 2016, 09:22:13 AM »
If you use my libraries I would suggest using my 1284p core, which was Mighty 1284p based, but I think I had to make some other changes. That gives you a Tools > Boards > MoteinoMEGA option. I had to make this specifically for the 1284p based board I produce.

Lensdigital

  • Full Member
  • ***
  • Posts: 151
    • Xronos Clock
Re: SPI Conflict between RFM69 and SD library
« Reply #25 on: February 16, 2016, 09:26:54 AM »
If you use my libraries I would suggest using my 1284p core, which was Mighty 1284p based, but I think I had to make some other changes. That gives you a Tools > Boards > MoteinoMEGA option. I had to make this specifically for the 1284p based board I produce.
Thanks Felix, I'll try your bootloader.  Did you base it on any other bootloader or did you write it from scratch?

I see all pins match, except that you have blink routing on D15.  Do you share your source files for this bootloader? I'd like to modify it because I use D15 for my LED Matrix Clock pin...
« Last Edit: February 16, 2016, 09:59:34 AM by Lensdigital »
Check out my hand made open source Xronos Alarm Clock!
http://www.xronosclock.com

Lensdigital

  • Full Member
  • ***
  • Posts: 151
    • Xronos Clock
Re: SPI Conflict between RFM69 and SD library
« Reply #26 on: February 16, 2016, 10:26:39 AM »
I'm not sure what's happening but it's now compiling with INT2...   :o
I think I had wrong board selected or something yesterday :D
Seems to be working so far. 
And here's something interesting I discovered (which you guys probably already knew). It seems that RFM69W "caches" transmission. When Interrupt being off, I send message, and when interrupt turns on in few seconds, it shows that message!  Pretty cool! :)
« Last Edit: February 16, 2016, 10:33:13 AM by Lensdigital »
Check out my hand made open source Xronos Alarm Clock!
http://www.xronosclock.com

Felix

  • Administrator
  • Hero Member
  • *****
  • Posts: 6332
  • Country: us
    • LowPowerLab
Re: SPI Conflict between RFM69 and SD library
« Reply #27 on: February 16, 2016, 11:12:34 AM »
Did you base it on any other bootloader or did you write it from scratch?
Do you share your source files for this bootloader? I'd like to modify it because I use D15 for my LED Matrix Clock pin...

My bootloader is called DualOptiboot (my own naming), it is based on Optiboot. The sources and binary are posted here.

And here's something interesting I discovered (which you guys probably already knew). It seems that RFM69W "caches" transmission. When Interrupt being off, I send message, and when interrupt turns on in few seconds, it shows that message!  Pretty cool! :)
If I understand this correctly, and without digging the MCU datasheets, I think the interrupts are only triggered when they are enabled, even if they happen while they are disabled (interrupt bits will get set in their registers but the handlers will not be called until the interrupt enable registers bits are enabled).

TD22057

  • Newbie
  • *
  • Posts: 26
  • Country: us
Re: SPI Conflict between RFM69 and SD library
« Reply #28 on: February 16, 2016, 11:57:57 AM »
And here's something interesting I discovered (which you guys probably already knew). It seems that RFM69W "caches" transmission. When Interrupt being off, I send message, and when interrupt turns on in few seconds, it shows that message!  Pretty cool! :)

Thanks for posting this.  I'm trying to hack the RFM69 library to understand it better and experiment with a "callback on state change" API and I was actually wondering about that very question yesterday.  So your post saved me a bunch of time - Thanks!

Lensdigital

  • Full Member
  • ***
  • Posts: 151
    • Xronos Clock
Re: SPI Conflict between RFM69 and SD library
« Reply #29 on: February 16, 2016, 03:57:07 PM »
Thanks for posting this.  I'm trying to hack the RFM69 library to understand it better and experiment with a "callback on state change" API and I was actually wondering about that very question yesterday.  So your post saved me a bunch of time - Thanks!

Glad it was useful :)
It frustrates me when these issues happen, but on the other hand I'm very happy it happened. I think I learned more about SPI during last couple of weeks than I did in few last years that I've been involved with micro-controllers :)   Couldn't have done this without you guys, really thankful for the interrupt solution!  My code seems to work great now, directing which SPI device can do what and when like a traffic light, so "accidents" don't happen :)  I've been bombarding my clocks with radio transmissions during audio playbacks and so far wasn't able to make them freeze. Very happy :)
« Last Edit: February 16, 2016, 04:02:34 PM by Lensdigital »
Check out my hand made open source Xronos Alarm Clock!
http://www.xronosclock.com

Felix

  • Administrator
  • Hero Member
  • *****
  • Posts: 6332
  • Country: us
    • LowPowerLab
Re: SPI Conflict between RFM69 and SD library
« Reply #30 on: February 16, 2016, 04:13:34 PM »
Man, nice clocks :)

Lensdigital

  • Full Member
  • ***
  • Posts: 151
    • Xronos Clock
Re: SPI Conflict between RFM69 and SD library
« Reply #31 on: February 16, 2016, 06:07:23 PM »
Check out my hand made open source Xronos Alarm Clock!
http://www.xronosclock.com

Lensdigital

  • Full Member
  • ***
  • Posts: 151
    • Xronos Clock
Re: SPI Conflict between RFM69 and SD library
« Reply #32 on: August 02, 2016, 10:27:49 PM »
Well I just wanted to report that "fix" didn't work in the long term. Lockups happen so randomly that sometimes it can take 2 weeks, and sometimes it happens 5 times a day. But when SPI locks up SD Card, only removing power fixes it (I tried using watchdog timers, but it didn't help)...
That obviously put my whole Xronos 3 project on hold until further notice. Recently I had some spare time to work on it again, and I'm going to see if I can modify RFM69 library to use SPI.beginTransaction and SPI.endTransaction methods which was added to Arduino SPI library recently...
OricDan I know you were talking about this from beginning, but I didn't understand it then :)
« Last Edit: August 02, 2016, 10:29:54 PM by Lensdigital »
Check out my hand made open source Xronos Alarm Clock!
http://www.xronosclock.com

TomWS

  • Hero Member
  • *****
  • Posts: 1925
Re: SPI Conflict between RFM69 and SD library
« Reply #33 on: August 03, 2016, 07:31:01 AM »
FWIW, I'm becoming more and more convinced that an SD Card needs to be isolated from the SPI bus when it's not being accessed.  Level translator with enable should work.  And be sure to pull up key pins like SCK (or pulldown if you're using Mode0), MISO, MOSI, and the unused reserved pins on the Micro-SD side.

Tom

perky

  • Hero Member
  • *****
  • Posts: 873
  • Country: gb
Re: SPI Conflict between RFM69 and SD library
« Reply #34 on: August 03, 2016, 10:47:12 AM »
Has anyone tried the 470R resistor hack on the SD card's MISO signal? I've worked on systems where the SD card is shared and this was found to be necessary because some SD cards don't release MISO even with dummy clocks with CS# high.
Mark.

Lensdigital

  • Full Member
  • ***
  • Posts: 151
    • Xronos Clock
Re: SPI Conflict between RFM69 and SD library
« Reply #35 on: August 03, 2016, 12:52:54 PM »
I haven't heard about 470R SD card hack. Might be worth a try. Pullup or pulldown?
Tom, thanks for the suggestion!  It might be a pain tho to add all these extra resistors, but I'll try with MISO...
Also have very similar devices (Xronos Clock 2) but it uses RFM12b instead of RFM69. Zero issues there (I've been making them for over 3 years now). I just do radio.sleep() before reading SD card.
Actually I'm going to try RFM12b on new boards as well (I made radio module plug-in so it can be easily swapped)...
Check out my hand made open source Xronos Alarm Clock!
http://www.xronosclock.com

perky

  • Hero Member
  • *****
  • Posts: 873
  • Country: gb
Re: SPI Conflict between RFM69 and SD library
« Reply #36 on: August 03, 2016, 01:06:20 PM »
No, I don't mean a pull-up on MISO. If the SD card does not release the MISO then adding a series resistor directly at the SD card's MISO output allows other devices to over-drive it (you wire the SD card MISO to a 470R resistor, then the other side of the resistor goes to the MCU MISO and the other device(s) MISO).
Mark.

Lensdigital

  • Full Member
  • ***
  • Posts: 151
    • Xronos Clock
Re: SPI Conflict between RFM69 and SD library
« Reply #37 on: August 03, 2016, 03:27:00 PM »
Ah I see! Thanks!
BTW here's my RFM breakout. Works with both RFM12b and RFM69W and also can be connected to BT module. Very useful if you need to swap frequencies, etc...

« Last Edit: August 03, 2016, 05:16:31 PM by Lensdigital »
Check out my hand made open source Xronos Alarm Clock!
http://www.xronosclock.com

TomWS

  • Hero Member
  • *****
  • Posts: 1925
Re: SPI Conflict between RFM69 and SD library
« Reply #38 on: August 03, 2016, 09:09:35 PM »
No, I don't mean a pull-up on MISO. If the SD card does not release the MISO then adding a series resistor directly at the SD card's MISO output allows other devices to over-drive it (you wire the SD card MISO to a 470R resistor, then the other side of the resistor goes to the MCU MISO and the other device(s) MISO).
Mark.
Mark, in my experience it's the SD card that gets hosed, not the rest of the SPI devices.  I would think the issue you've raised is more about messing up other device's transactions - unless I'm missing something.

I've found if you can keep the SD card operation atomic - Open the SD device, do your thing, close it without doing any other SPI device operation in the middle of this, your chance of success is much much better.  Additionally, I've not had much success with anything other than SDSC cards (on AVR platforms).

Tom
« Last Edit: August 03, 2016, 09:15:31 PM by TomWS »

perky

  • Hero Member
  • *****
  • Posts: 873
  • Country: gb
Re: SPI Conflict between RFM69 and SD library
« Reply #39 on: August 03, 2016, 11:43:58 PM »
Ah, OK. The scenario I had was that I produced a 'dongle' with an AVR and an SD card so that a customer could update an FPGA board in the field. The dongle interface had an SPI interface to the FPGA's serial flash. The problem was that the SD card refused to release MISO, so the dongle had trouble accessing the SPI flash. Adding a series resistor fixed it. In that case though I was doing full 512 byte bursts so the SD accesses were atomic.

Mark.

TomWS

  • Hero Member
  • *****
  • Posts: 1925
Re: SPI Conflict between RFM69 and SD library
« Reply #40 on: August 04, 2016, 07:44:25 AM »
In that case though I was doing full 512 byte bursts so the SD accesses were atomic.
I've even tried that and failed.  It was only when I did SD.init(), Open file, write blocks, close file in one operation...

Tom

perky

  • Hero Member
  • *****
  • Posts: 873
  • Country: gb
Re: SPI Conflict between RFM69 and SD library
« Reply #41 on: August 04, 2016, 11:33:44 AM »
Interesting. I wonder if the SD library has an effect (specifically dummy clocks and cleanly starting/stopping things). I use FatFs, or for simple things PetitFs. I used to use EFS but that was bloated and bug ridden. I've never had any problems with PetitFs:
http://elm-chan.org/fsw/ff/00index_p.html
Mark.

Lensdigital

  • Full Member
  • ***
  • Posts: 151
    • Xronos Clock
Re: SPI Conflict between RFM69 and SD library
« Reply #42 on: August 04, 2016, 12:37:19 PM »
FYI I'm using SD Library that's part of WaveHC library (by Adafruit). Not sure how to integrate another one.
For now I'm going to see if I can resolve this issue in software. I finally ported my code to work with Both RFM12b and RFM69. Had to build RFM12b weather sensor and so far it's working... But time will tell.
I hope it locks up, then I can try hardware solution (resistors)....
BTW if anyone interested to write code for both modules, it's quite easy, just use defines..
Code: [Select]
//#define RFM69_CHIP // Comment out for RFM12b
#if defined (RFM69_CHIP)
  #include <RFM69.h>
#else
  #include <RFM12B_arssi.h>
#endif

#if defined (RFM69_CHIP)
  RFM69 radio;
#else
  RFM12B radio;
#endif

... and so on...
« Last Edit: August 04, 2016, 12:39:19 PM by Lensdigital »
Check out my hand made open source Xronos Alarm Clock!
http://www.xronosclock.com

TomWS

  • Hero Member
  • *****
  • Posts: 1925
Re: SPI Conflict between RFM69 and SD library
« Reply #43 on: August 04, 2016, 05:26:04 PM »
Interesting. I wonder if the SD library has an effect (specifically dummy clocks and cleanly starting/stopping things). I use FatFs, or for simple things PetitFs. I used to use EFS but that was bloated and bug ridden. I've never had any problems with PetitFs:
http://elm-chan.org/fsw/ff/00index_p.html
Mark.
Thanks for the links, Mark.  I'll try them out.  I've been using SD_Fat so this might be a worthwhile change.

Tom

XFVB56

  • Newbie
  • *
  • Posts: 2
  • Country: us
Re: SPI Conflict between RFM69 and SD library
« Reply #44 on: September 20, 2016, 08:36:20 AM »
Well I just wanted to report that "fix" didn't work in the long term. Lockups happen so randomly that sometimes it can take 2 weeks, and sometimes it happens 5 times a day. But when SPI locks up SD Card, only removing power fixes it (I tried using watchdog timers, but it didn't help)...
That obviously put my whole Xronos 3 project on hold until further notice.
Hi, I'm new here.  This  reminded me of a similar problem that hung me up for weeks on a design job a number of years ago. SPI is designed to support bus sharing, but as soon as you add interrupts to the mix things get complicated.  Without (even with!) a real time debugger and a logic analyzer it can be very hard to solve hardware bus contention problems. You might try to divide and conquer. Create a  software bit-banged SPI port to drive one of the SPI devices, and use the hardware port to drive the other.   If you drive the Software SPI port with an ISR routine it won't take all that much CPU time. If that's not fast enough, you could change hardware to a CPU that has more than one hardware SPI port. You can get "official" Arduino software support using the same processor that's in the Arduino Zero and the Adafruit Feather M0. That is the ARM Cortex M0 part # ATSAMD21G18.  It has a ton of memory and most important for your design,  six hardware communications ports. Any of these can be used as a UART, I2C, or SPI port.

Lensdigital

  • Full Member
  • ***
  • Posts: 151
    • Xronos Clock
Re: SPI Conflict between RFM69 and SD library
« Reply #45 on: September 20, 2016, 01:02:15 PM »
Ha that's very interesting. I wanted to move on to ARM price, this one sounds like a dream! I might even be able to decode mp3 on it...
Thanks for suggestion!
Check out my hand made open source Xronos Alarm Clock!
http://www.xronosclock.com

boroko

  • Newbie
  • *
  • Posts: 2
Re: SPI Conflict between RFM69 and SD library
« Reply #46 on: May 10, 2018, 07:13:39 AM »
Quote
If that's not fast enough, you could change hardware to a CPU that has more than one hardware SPI port. You can get "official" Arduino software support using the same processor that's in the Arduino Zero and the Adafruit Feather M0.

You just saved me a bunch of panic.  Been working on a long project that requires sending fairly sizable data logs from a SD card over a RFM69.  Been working on the hardware, storage, and comm flow over USB, and was just starting to integrate the radio.  Everything I was seeing pointed to a big problem using the radio and the SD together.  Phew! 

Now if I can just understand how to migrate from wired comm to using the radio ...  Strangely, I'm having trouble finding examples of doing this with multi Kb files.  I would have thought it would be a heavily discussed topic. I'm looking to understand data structures better to see if that's my path.

bo
« Last Edit: May 10, 2018, 07:19:02 AM by boroko »