Author Topic: Can't Init Flash Memory on Moteino M0 [solved: pull radio CS HIGH!]  (Read 1950 times)

brandock

  • NewMember
  • *
  • Posts: 31
I'm new to the Moteino M0. I've mostly used Moteino USB and Moteino. I'm trying to upload and use the SPIFlash_ReadWrite example sketch in the library. I am using it as I found it, other than replacing SS_FLASHMEM with 8. I've pasted the sketch below, in case that is helpful.

When I load the sketch into an original Moteino, I get the expected output.

Code: [Select]
Start...Init OK!

************************
Available operations:
'c' - read flash chip's deviceID 10 times to ensure chip is present
'd' - dump first 256 bytes on the chip
'e' - erase entire flash chip
'i' - read deviceID
************************

DeviceID: EF30


Then I load the same sketch into the Moteino M0 and get no output. I hit "c" and "I" and get the following.

Code: [Select]
Checking chip is present ... FAIL, deviceID is inconsistent or 0x0000/0xffff
DeviceID: 0

Any suggestions?

Thanks,
Brandon

Code: [Select]
#include <SPIFlash.h>    //get it here: https://github.com/LowPowerLab/SPIFlash

#define SERIAL_BAUD      115200
char input = 0;
long lastPeriod = -1;

//////////////////////////////////////////
// flash(SPI_CS, MANUFACTURER_ID)
// SPI_CS          - CS pin attached to SPI flash chip (8 in case of Moteino)
// MANUFACTURER_ID - OPTIONAL, 0x1F44 for adesto(ex atmel) 4mbit flash
//                             0xEF30 for windbond 4mbit flash
//                             0xEF40 for windbond 64mbit flash
//////////////////////////////////////////
uint16_t expectedDeviceID=0xEF30;
SPIFlash flash(SS_FLASHMEM, expectedDeviceID);

void setup(){
  Serial.begin(SERIAL_BAUD);
  Serial.print("Start...");

  if (flash.initialize())
  {
    Serial.println("Init OK!");
    Blink(20, 10);
  }
  else {
    Serial.print("Init FAIL, expectedDeviceID(0x");
    Serial.print(expectedDeviceID, HEX);
    Serial.print(") mismatched the read value: 0x");
    Serial.println(flash.readDeviceId(), HEX);
  }

  Serial.println("\n************************");
  Serial.println("Available operations:");
  Serial.println("'c' - read flash chip's deviceID 10 times to ensure chip is present");
  Serial.println("'d' - dump first 256 bytes on the chip");
  Serial.println("'e' - erase entire flash chip");
  Serial.println("'i' - read deviceID");
  Serial.println("************************\n");
  delay(1000);
}

void loop(){
  // Handle serial input (to allow basic DEBUGGING of FLASH chip)
  // ie: display first 256 bytes in FLASH, erase chip, write bytes at first 10 positions, etc
  if (Serial.available() > 0) {
    input = Serial.read();
    if (input == 'd') //d=dump flash area
    {
      Serial.println("Flash content:");
      int counter = 0;

      while(counter<=256){
        Serial.print(flash.readByte(counter++), HEX);
        Serial.print('.');
      }
     
      Serial.println();
    }
    else if (input == 'c') {
      Serial.print("Checking chip is present ... ");
      uint16_t deviceID=0;
      for (uint8_t i=0;i<10;i++) {
        uint16_t idNow = flash.readDeviceId();
        if (idNow==0 || idNow==0xffff || (i>0 && idNow != deviceID)) {
          deviceID=0;
          break;
        }
        deviceID=idNow;
      }
      if (deviceID!=0) {
        Serial.print("OK, deviceID=0x");Serial.println(deviceID, HEX);
      }
      else Serial.println("FAIL, deviceID is inconsistent or 0x0000/0xffff");
    }
    else if (input == 'e')
    {
      Serial.print("Erasing Flash chip ... ");
      flash.chipErase();
      while(flash.busy());
      Serial.println("DONE");
    }
    else if (input == 'i')
    {
      Serial.print("DeviceID: ");
      Serial.println(flash.readDeviceId(), HEX);
    }
    else if (input >= 48 && input <= 57) //0-9
    {
      Serial.print("\nWriteByte("); Serial.print(input); Serial.print(")");
      flash.writeByte(input-48, millis()%2 ? 0xaa : 0xbb);
    }
  }

  // Periodically blink the onboard LED while listening for serial commands
  if ((int)(millis()/500) > lastPeriod)
  {
    lastPeriod++;
    pinMode(LED_BUILTIN, OUTPUT);
    digitalWrite(LED_BUILTIN, lastPeriod%2);
  }
}

void Blink(int DELAY_MS, byte loops)
{
  pinMode(LED_BUILTIN, OUTPUT);
  while (loops--)
  {
    digitalWrite(LED_BUILTIN,HIGH);
    delay(DELAY_MS);
    digitalWrite(LED_BUILTIN,LOW);
    delay(DELAY_MS); 
  }
}

« Last Edit: January 14, 2021, 03:42:11 PM by Felix »

Felix

  • Administrator
  • Hero Member
  • *****
  • Posts: 6866
  • Country: us
    • LowPowerLab
Re: Can't Init Flash Memory on Moteino M0
« Reply #1 on: January 12, 2021, 01:59:21 PM »
I posted this new example in the SPIFlash library:
https://github.com/LowPowerLab/SPIFlash/blob/master/examples/SPIFlash_Detect/SPIFlash_Detect.ino

Please try it out and the LED should blink slow (~500ms cycle) if flash is detected and fast (100ms cycle) if flash not detected.

brandock

  • NewMember
  • *
  • Posts: 31
Re: Can't Init Flash Memory on Moteino M0
« Reply #2 on: January 12, 2021, 02:39:28 PM »
It is blinking fast when I load this into the Moteino M0 from Arduino IDE.

I also loaded the sketch into an original Moteino, just for comparison. I had to replace SS_FLASHMEM with 8 to get it to compile for original Moteino, but then it loaded. The LED didn't blink, but the serial output showed success.
Code: [Select]
SPI Flash Init OK!
FLASH DeviceID: EF30
FLASH init OK
FLASH DeviceID: EF30
FLASH init OK
FLASH DeviceID: EF30
FLASH init OK
FLASH DeviceID: EF30
FLASH init OK
« Last Edit: January 12, 2021, 02:45:37 PM by brandock »

brandock

  • NewMember
  • *
  • Posts: 31
Re: Can't Init Flash Memory on Moteino M0
« Reply #3 on: January 12, 2021, 04:43:40 PM »
Felix, thanks for UF2 you emailed. When I load that UF2 via USB drive the LED blinks slowly to indicate the flash was detected. But when I compile and load your test sketch using Arduino IDE I get the not-detected result I wrote about above. So it seems something is amiss with my libraries, but I can't think what it would be. I just installed SPIFlash, and the Moteino SAMD M0 board in the board manager, so these should be up-to-date.

brandock

  • NewMember
  • *
  • Posts: 31
Re: Can't Init Flash Memory on Moteino M0
« Reply #4 on: January 13, 2021, 11:43:50 AM »
Here are the things I have tried since my last post. Since Felix was able to compile a UF2 that works, I am assuming that my Arduino IDE or libraries are the problem. So

I tried several 1.6.x versions of the Arduino IDE from .1 to .13, including 1.6.8 in particular, since I heard from Felix that is the version he is using.

I noticed that the SPI library in use when I compile for the Moteino M0 is /Users/brandock/Library/Arduino15/packages/Moteino/hardware/samd/1.6.0/libraries/SPI so I tried substituting the SPI library found in /Users/brandock/Library/Arduino15/packages/arduino/hardware/samd/1.8.4/libraries/SPI into the Moteino samd folder and compiling. No effect.

I noticed that the SPI library is here: https://github.com/arduino/ArduinoCore-samd/tree/master/libraries/SPI, so I tried merging in recent changes to SPI.cpp and SPI.h from GitHub to the SPI library in the Moteino samd folder. This was a long shot, and had the effect that the sketch would no longer compile at all.

Still stuck ...

brandock

  • NewMember
  • *
  • Posts: 31
Re: Can't Init Flash Memory on Moteino M0
« Reply #5 on: January 13, 2021, 12:01:19 PM »
Now I am trying moving backward through various versions of the Moteino M0 board manager.
Start with 1.6.0, which compiles, but doesn't find the flash memory.
Tried 1.5.0. No change.
Then tried 1.4.0. This doesn't compile, but does try to use the Arduino SPI library instead of the Moteino M0 SPI library

Code: [Select]
Using library SPIFlash_LowPowerLab at version 101.1.3 in folder: /Users/brandock/Dropbox/Arduino/libraries/SPIFlash_LowPowerLab 
Using library SPI at version 1.0 in folder: /Users/brandock/Library/Arduino15/packages/arduino/hardware/samd/1.8.4/libraries/SPI

Here is most of the output of the compile with 1.4.0

Code: [Select]
Detecting libraries used...
...
Archiving built core (caching) in: /var/folders/5q/dbszcldd4sdcs7sr8pyr160h0000gn/T/arduino_cache_758916/core/core_arduino_samd_arduino_zero_edbg_38c8a92792eafcfa47755020b8f05c4a.a
Linking everything together...
"/Users/brandock/Library/Arduino15/packages/arduino/tools/arm-none-eabi-gcc/7-2017q4/bin/arm-none-eabi-g++"  "-L/var/folders/5q/dbszcldd4sdcs7sr8pyr160h0000gn/T/arduino_build_732426" -Os -Wl,--gc-sections -save-temps  "-T/Users/brandock/Library/Arduino15/packages/arduino/hardware/samd/1.8.4/variants/arduino_zero/linker_scripts/gcc/flash_with_bootloader.ld" "-Wl,-Map,/var/folders/5q/dbszcldd4sdcs7sr8pyr160h0000gn/T/arduino_build_732426/sketch_jan12a.ino.map" --specs=nano.specs --specs=nosys.specs -mcpu=cortex-m0plus -mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -o "/var/folders/5q/dbszcldd4sdcs7sr8pyr160h0000gn/T/arduino_build_732426/sketch_jan12a.ino.elf" "/var/folders/5q/dbszcldd4sdcs7sr8pyr160h0000gn/T/arduino_build_732426/sketch/sketch_jan12a.ino.cpp.o" "/var/folders/5q/dbszcldd4sdcs7sr8pyr160h0000gn/T/arduino_build_732426/libraries/SPIFlash_LowPowerLab/SPIFlash.cpp.o" "/var/folders/5q/dbszcldd4sdcs7sr8pyr160h0000gn/T/arduino_build_732426/libraries/SPI/SPI.cpp.o" "/var/folders/5q/dbszcldd4sdcs7sr8pyr160h0000gn/T/arduino_build_732426/core/variant.cpp.o"  -Wl,--start-group "-L/Users/brandock/Library/Arduino15/packages/arduino/tools/CMSIS/4.5.0/CMSIS/Lib/GCC/" -larm_cortexM0l_math -lm "/var/folders/5q/dbszcldd4sdcs7sr8pyr160h0000gn/T/arduino_build_732426/core/core.a" -Wl,--end-group
"/Users/brandock/Library/Arduino15/packages/arduino/tools/arm-none-eabi-gcc/7-2017q4/bin/arm-none-eabi-objcopy" -O binary  "/var/folders/5q/dbszcldd4sdcs7sr8pyr160h0000gn/T/arduino_build_732426/sketch_jan12a.ino.elf" "/var/folders/5q/dbszcldd4sdcs7sr8pyr160h0000gn/T/arduino_build_732426/sketch_jan12a.ino.bin"
"/Users/brandock/Library/Arduino15/packages/arduino/tools/arm-none-eabi-gcc/7-2017q4/bin/arm-none-eabi-objcopy" -O ihex -R .eeprom  "/var/folders/5q/dbszcldd4sdcs7sr8pyr160h0000gn/T/arduino_build_732426/sketch_jan12a.ino.elf" "/var/folders/5q/dbszcldd4sdcs7sr8pyr160h0000gn/T/arduino_build_732426/sketch_jan12a.ino.hex"
Multiple libraries were found for "SPI.h"
 Used: /Users/brandock/Library/Arduino15/packages/arduino/hardware/samd/1.8.4/libraries/SPI
 Not used: /Users/brandock/Dropbox/Arduino/libraries/SPI
Using library SPIFlash_LowPowerLab at version 101.1.3 in folder: /Users/brandock/Dropbox/Arduino/libraries/SPIFlash_LowPowerLab
Using library SPI at version 1.0 in folder: /Users/brandock/Library/Arduino15/packages/arduino/hardware/samd/1.8.4/libraries/SPI
Sketch uses 13064 bytes (4%) of program storage space. Maximum is 262144 bytes.
Open On-Chip Debugger 0.10.0+dev-gf0767a31 (2018-06-11-13:48)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
debug_level: 0
none separate
adapter speed: 400 kHz
cortex_m reset_config sysresetreq
Error: unable to find CMSIS-DAP device
Error: No Valid JTAG Interface Configured.
Error: No Valid JTAG Interface Configured.

Felix

  • Administrator
  • Hero Member
  • *****
  • Posts: 6866
  • Country: us
    • LowPowerLab
Re: Can't Init Flash Memory on Moteino M0
« Reply #6 on: January 13, 2021, 02:20:16 PM »
Ok I have made a test and I made sure I have the latest:
- Arduino IDE 1.8.13
- Arduino SAMD Boards package 1.8.11
- Moteino SAMD Boards package 1.6.0
- SPIFlash library 101.1.3
- all other libraries are the defaults, whatever is included in arduino and (overrides) in the given packages above.

Compiling the SPIFlash_Detect example result:
no compilation errors, boards with/without FLASHMEM blink differently and as expected.
This is on W10. I don't believe I am missing something.

FWIW I would not recommend trying to replace or hack away at the arduino cores or anything deep in definition files/folders if you don't know exactly what you are doing.

brandock

  • NewMember
  • *
  • Posts: 31
Re: Can't Init Flash Memory on Moteino M0
« Reply #7 on: January 13, 2021, 05:24:15 PM »
I tried the same list of things exactly and did not have success.

But I did notice something by accident. If I jiggle the USB cable where it is plugged into the M0 I get intermittent success.

Code: [Select]
LASH init FAIL
FLASH DeviceID: 0
FLASH init FAIL
SPI Flash Init OK!
FLASH DeviceID: EF30
FLASH init OK
FLASH DeviceID: EF30
FLASH init OK
FLASH DeviceID: EF30
FLASH init OK
FLASH DeviceID: EF30
FLASH init OK
FLASH DeviceID: EF30
FLASH init OK
FLASH DeviceID: EF30
FLASH init OK
FLASH DeviceID: EF30
FLASH init OK
FLASH DeviceID: EF30
FLASH init OK
FLASH DeviceID: EF30
FLASH init OK
FLASH DeviceID: 0
FLASH init FAIL
FLASH DeviceID: 0
FLASH init FAIL
FLASH DeviceID: 0
FLASH init FAIL
FLASH DeviceID: 0
FLASH init FAIL
FLASH DeviceID: 0
FLASH init FAIL
FLASH DeviceID: 0

I tried various cables and various USB ports on my PC and that doesn't make a difference, so I'm wondering if it could be something with the USB input on the M0? But if so it is weird that I haven't detected other intermittent behavior. I can load Blink and DigitalReadSerial and other basic example sketches without difficulty.

brandock

  • NewMember
  • *
  • Posts: 31
Re: Can't Init Flash Memory on Moteino M0
« Reply #8 on: January 13, 2021, 11:09:31 PM »
Another test. I loaded the init test sketch and then disconnected the M0 from USB. I then booted it up by plugging it into a LIP0 battery with the JST connector. I immediately got the fast flashing light for a failed SPI flash init. I ran this test several times.

And yet another test. I loaded the test sketch via the UF2 method and watched the serial output. For some reason when it boots up after getting a new UF2 it will sometimes think the flash init went OK and start the slow blinking, but when I watch the serial output I can see that it is actually not able to init again right after that. It is blinking slow because in the sketch the blink pace is determined by the first init test, which sometimes works.

Code: [Select]
SPI Flash Init OK!
FLASH DeviceID: EF30
FLASH init OK
FLASH DeviceID: 0
FLASH init FAIL
FLASH DeviceID: 0
FLASH init FAIL
FLASH DeviceID: 0
FLASH init FAIL
FLASH DeviceID: 0
FLASH init FAIL

Felix

  • Administrator
  • Hero Member
  • *****
  • Posts: 6866
  • Country: us
    • LowPowerLab
Re: Can't Init Flash Memory on Moteino M0
« Reply #9 on: January 14, 2021, 03:36:46 PM »
Solved: Turned out that if a Moteino has a radio module installed, and the CS of the radio module is not pulled HIGH, it will interfere with the SPI/MISO data line and scramble the responses back to the microcontroller. Obvious fail.
The solution was to pull HIGH the radio CS and also add a flash.wakeup() call just for good practice, since any sleep() command would cause the FLASHMEM chip to only respond to wakeup commands.

This was all patched into the SPIFlash_Detect example.

brandock

  • NewMember
  • *
  • Posts: 31
Re: Can't Init Flash Memory on Moteino M0 [solved: pull radio CS HIGH!]
« Reply #10 on: January 17, 2021, 09:46:32 AM »
Yes. Thanks, Felix!

For others that might be here in the future, I've been loading examples from the Adafruit TinyUSB library into the Moteino M0. To compile them, I use the Feather M0 board manager and the TinyUSB stack. This means I need to do a couple of things to get them to work, one of which is setting the radio module CS pin HIGH. I use this in the setup().

Code: [Select]
  //ensure the radio module CS pin is pulled HIGH or it might interfere!
  pinMode(A2, OUTPUT);
  digitalWrite(A2, HIGH);

(The other things include setting an override for the CS pin, which is 8 on the Moteino M0, and I'm still working on getting the Winbond W25X40CL definition into Adafruit_SPIFlash/src/flash_devices.h.)

Code: [Select]
#define EXTERNAL_FLASH_USE_SPI SPI
#define EXTERNAL_FLASH_USE_CS 8

Felix

  • Administrator
  • Hero Member
  • *****
  • Posts: 6866
  • Country: us
    • LowPowerLab
Re: Can't Init Flash Memory on Moteino M0 [solved: pull radio CS HIGH!]
« Reply #11 on: January 18, 2021, 10:59:34 AM »
Thank you, please do follow up once you have a full working solution, I think what you're doing is of high interest!