Problem after upload code of Nano Sense to Nano IoT

I buy a Nano 33 BLE Sens and a Nano 33 IoT to learn Arduino. Both worked correctly and the port was recongnised perfectly but by error I upload an skecth without change the board in the menu.
Logically the upload does not finished and it was stopped at the beginning.

Now my Nano IoT is bricked. The double tapping does not work, the led 13 is off while the led green power is on and the port is not presented (not recognized). I can access by usual method to my IoT.

How can I reset to factory default?
Can I apply 3.3V from my Mega to the test point (ground, vcc and reset) of the IoT to hard reset?

Thank in avance

The double tapping does not work,

Try the double tap reset and upload with the Windows Device Manager (or Linux equivalent) open. Which COM ports do you see ?

I use a Mac Book Pro with Arduino IDE 1.8.11.
Previously to the error the port was recognized perfeclty, I play with some sketch without problem, etc all good! But after upload the BLE code to IoT the port go away and the double tap dont work. I connect the mini usb and the power led is ok but I can’t connect with IoT. I tried with Win7, Win10 and Linux to see if they could recognize the port but anyone show anything (Linux with lsusb dont show any information of the port). The communication with IoT is broken by mini usb.

Try what I suggested. The Nano 33 IOT changes its COM port during some operations

The port Mac shows is only the standard bluetooth (port also shown when anything is connected to the usb ports). I think that if IoT changed the port, it should be shown when I connect IoT to a Linux that never saw an Arduino, at least the lsusb in konsole should be show Bus Device and ID. But no!! nothing :frowning:
The problem happened two days ago and I read many post and webs but without reasonable solution (I never connected IoT to other power than the miniusb to avoid electrical damage, nor apply 3.3V to reset pin nor test points).
After work in the afternoon I will try if I can connect via IoT cloud and I will try double tapping and port scanning as you suggest (thanks) but I'm afraid that the only solution is a hard reset...

  1. Which was the last BLE sketch you uploaded to nano 33 IoT? Paste here
  2. Also, have you tried changing the cable?
  3. After double tapping, does the LED shows the behaviour of fading or pulsing?

Hi and thanks

  1. I dont remember exactly because I test other skecth with other arduinos but I think was the example SimpleGyroscope. I was testing the sensors of Nano BLE Sense and I changed to test the sensor of IoT... but I forget change the board. This was the problem!
  2. The cable was the same I used to upload other test skecth to BLE. When I try to detect the port in Linux I also used other cable. I think the cable is not the problem.
  3. Builtin led is off and when double (triple...) tapping does not show any light, nor blink, fading, pulse... absolutely no response

I think the machine code of BLE traslate to machine code of IoT block in some way the processor of IoT. I hope the upload direction of BLE applied to an IoT dont overwrite the bootloader of IoT.
That's why I'm looking for a way to erase the skect to zeros (nop), knowing that this is not warranty that resolve the problem but I think is the first step to recover IoT.

Note: alternative methods are described at the end of the post.

Using an Arduino board as the programmer

You’ll need

  • An extra Arduino board that runs at 3.3 V to use as the programmer.
    • Note: certain Arduino boards can’t be used with the sketch that converts it to a programmer.
      • Working: SAMD architecture boards (e.g., MKR boards, Nano 33 IoT, Zero).
      • Untested: AVR architecture boards (e.g., Uno), but the sketch does compile for them.
      • Not working: Nano 33 BLE
    • It is possible to use an Arduino board that runs at 5 V as the programmer, but you’ll need to use level shifting circuitry on the programming lines to avoid exposing the target board to 5 V logic levels, which would damage it.
  • An SD slot. This could be built into your Arduino board (e.g., MKR Zero), a shield (e.g., MKR SD Proto Shield), or one of the common SD modules.
  • An SD card that fits your SD slot.
  • A way to connect the SD card to your computer.
  • A way to make the connections to the SWD pins on your target Arduino board. For the Nano 33 IoT and the MKR Boards other than MKR1000, I like to use a 0.1" pitch 2x3 POGO adapter. You could also solder wires to the test points if you prefer. On the MKR boards other than the MKR1000, the SWD header is on the bottom of the board and is the footprint for a 0.1" pitch 2x3 SMD header (e.g., https://www.digikey.com/short/z3dvdv). On the MKR1000, it is a 0.05" pitch 2x5 male header on the top of the board, which you will need an adapter and cable for.

Instructions

  1. Connect an SD card to your computer.

  2. Open this link in your browser: https://github.com/arduino/ArduinoCore-samd/tree/master/bootloaders

  3. Click the folder that matches the name of your target board.

  4. Click the file that ends in .bin

  5. Click the Download button.

  6. Rename the downloaded file to fw.bin

  7. Move fw.bin to the SD card.

  8. Eject the SD card from your computer.

  9. Plug the USB cable of the Arduino board you will be using as a programmer into your computer.

  10. Select Sketch > Include Library > Manage Libraries… from the Arduino IDE’s menus.

  11. Wait for the download to finish.

  12. In the “Filter your search…” field, type “Adafruit DAP library”.

  13. Press Enter.

  14. Click on “Adafruit DAP library by Adafruit”.

  15. Click the “Install” button.

  16. Wait for the installation to finish.

  17. Click the Close button.

  18. Select File > Examples > Adafruit DAP library > flash_from_SD from the Arduino IDE’s menus.

  19. Change this line:

    #define SD_CS 4
    

    according to the Arduino pin connected to the SD CS pin. If your board has a built-in SD slot (e.g., MKR Zero), then you can change this line:

    if (!SD.begin(SD_CS)) {
    

    to:

    if (!SD.begin()) {
    
  20. Select the correct board from the Tools > Board from the Arduino IDE’s menus.

  21. Select the correct port from the Tools > Port from the Arduino IDE’s menus.

  22. Select Sketch > Upload from the Arduino IDE’s menus.

  23. Wait for the upload to finish successfully.

  24. Unplug the programmer Arduino board from your computer.

  25. Plug the SD card into the SD slot connected to your Arduino board.

  26. Connect the programmer Arduino board to the target Arduino board as follows:

    Programmer Target
    VCC +3V3
    10 SWDIO
    9 SWCLK
    GND GND
    11 RESETN

    SWD pads on MKR boards other than MKR 1000):
    MKR SWD
    MKR1000 SWD header pinout:
    MKR1000 SWD
    Nano 33 IoT SWD pads:
    Nano 33 IoT SWD

  27. Plug the USB cable of the programmer Arduino board into your computer.

  28. Select Tools > Serial Monitor from the Arduino IDE’s menus. You should now see the Serial Monitor output showing the target board detected, and the bootloader file flashed to it successfully.

  29. Unplug the programmer Arduino board from your computer.

  30. Disconnect the programmer Arduino board from the target Arduino board.


Alternatives

These are some alternatives to the “Adafruit DAP” method I described above.

Using a CMSIS-DAP debug probe as the programmer

If you have a CMSIS-DAP compliant debug probe, you can just do this instead:

  1. Connect the debug probe to your Arduino board.
  2. Select Tools > Programmer > Atmel EDBG from the Arduino IDE’s menus.
  3. Select Tools > Burn Bootloader from the Arduino IDE’s menus. - The “Burn Bootloader” process should now finish successfully.

I use this little open source debugger.


Using a J-Link as the programmer

Segger J-Link debug probes (e.g., J-Link EDU Mini) can be used with the Adalink software:
https://github.com/adafruit/Adafruit_Adalink

This is a fairly complex procedure, so I recommend against this option unless you already own a J-Link and don’t have the supplies on hand for one of the other options.

Thank you very much!

I will try to be a quick master of arduino with burning bootloader capacities from newbie this weekend! :slight_smile:

  1. extra Arduino 3.3V: I have a MKR-1010 and a Nano BLE Sense, I will use the first one
  2. SD Slot, this is my problem. I only have one on a Legoo screen, I will try to mount and connect in a breadboard with double check the connections
  3. rest I think ok

I will follow your great instructions. I'll tell you how it went
Thank you very much again

I think the MKR WiFi 1010 is a good choice. Adafruit_DAP should work with any Arduino board, but I haven't actually tested it with the Nano 33 BLE boards yet. I have done it with the MKR boards though, so I can tell you that the MKR WiFi 1010 will definitely work.

Although I had been burning bootloaders on AVR boards for years, I only recently tried it on the SAMD boards and had a bit of a challenging time getting it working at first, so I'm glad to be able to share what I've learned to hopefully make it an easier process for everyone else. Please let me know if you have any questions or if any of my instructions are unclear.

I'm hoping to hear that you've had success reviving your Nano 33 IoT soon!

Good news!
My Nano 33 IoT is alive!! The port is detected and the blink code was uploaded running as expected.

However, I had to change some steps of the great instructions of Pert to upload the boot loader without a SD card (I was no able to connect the SD card in my MKR-1010). The little changes was:

  1. I used the sketch flash_from_header.ino from Adafruit_DAP_library. To do, I wrote a little program in Ruby to read the bin file and to write the header file.
  2. I changed the number of pins following the '#define' in the sketch (9: SWDIO, 8: SWCLK, 7: SWRST/RESETN)

With patience, a 1 second delay after Serial.begin, and a 3x2 header pins I upload the boot loader without any welding in the test points. I plug the usb to my MKR-1010, I push the reset button and (thank delay) I push the 3x2 header on the test points and voilà! Upload done and IoT alive with yellow led pulsating waiting for an sketch.

Thank you very much for the great support

I'm very glad to hear it. It was not much fun the first time I "bricked" a SAMD board, but it forced me to learn how to recover it and now I feel more free to experiment with those boards.

Great work on getting the flash from header working. I've been meaning to look into the easiest way to do that, but I have that convenient MKR Zero with the built in SD slot handy, so I haven't gotten around to it yet.

Ephedrus:
2. I changed the number of pins following the '#define' in the sketch (9: SWDIO, 8: SWCLK, 7: SWRST/RESETN)

Was there a specific reason for doing that?

Ephedrus:
a 3x2 header pins

The forum member who told me about Adafruit_DAP also used that system of pressing a standard 2x3 male header on the SWD footprint on the MKR board. I thought that sounded tricky, but doing it on the smaller test pads of the Nano 33 IoT must have been even more so! I'm spoiled with my pogo adapter, but even that is a bit tricky. My technique is to get the pogo adapter on the pads, hold it in place with one hand, then plug the USB cable into the programmer board and open Serial Monitor with the other hand. Even that is challenging.

Once Arduino's hardware debugging system is released in the Pro IDE, I'd like to devise a better system for connecting a debug probe to the SWD pads, but I don't want to lose the breadboard compatibility. I guess soldering a ribbon cable on the pads and adding some hot glue for strain relief is the easiest solution.

I bought the Arduino to learn then the only issue with this problem was learn fastest that I expeted. Now I’m free to test with more aggressive code as write specific c header to my arduinos using direct i2c/spi addresses. I already know how to recover it if bricked by software!! :slight_smile:

To complete this line.

  1. I think the easiest of upload bootloader is with flash from header. Perhaps a trick was that the header variable with the hex code must be multiple of 256 (the size of the buffer in the DAP code, it seems that the bootloader is send in blocks of 256 bytes). Then, the code to write the header must be complete with 0x00 to be a final length multiple of 256. (If I knew how I would put the code here!)

  2. I changed the pin numbers (in programmer) because the DAP code use these pins to send the code to the target. I dont review the cpp code of the library yet but it’s clear that if #define is used in the example code to upload is to inform to the user where connect the cables. It is neccessary.

  3. The standard 3x2 male header worked fine but was necessary a lot of pacience. Now, I think that using a small elastic (like the one my daughter uses for hair) can make the life easier. If not adding a delay of e.g. 15 seconds, makes it easy to connect with both hands (one the target and the other one the 3x2 header) waiting for the code to be sent.

The result was that the only necessary to upload bootloader was a programmer arduino, a 3x2 standard male header and five male-female cables.

Waiting for me ahead hours of fun with Arduino!

bossac doesn't care what board is it. no invalid signature like with avrdude. now I can again find a way to burn the bootloader to MKR Zero.

I have a nano BLE Sense with the same problem. Is there a similar solution for that board?

You’ll need

  • ARM CMSIS-DAP compatible debug probe.
  • A way to make a connection to the debug probe. These usually use a 2x5 0.05" pitch header/cable.
  • A way to make the connections to the SWD pads on the Nano 33 BLE. Options:
    • Pogo adapter like https://www.sparkfun.com/products/11591
      Even with this adapter, it’s a bit challenging to get the pogo pins aligned with the small test pads on the Nano 33 BLE, but if you keep at it you’ll get it eventually. Better would be to have a jig like this, but if you’re not going to be doing this regularly then that’s probably overkill.
    • Some people have managed to use a regular 0.1" pitch 2x3 male header pressed down on the test pads to make the connections. I think that would be a bit more challenging, but it’s cheap enough and something you might already have on hand.
    • Soldering wires to the test points.

Instructions

  1. Start the Arduino IDE.

  2. Select Tools > Board > Arduino Nano 33 BLE from the Arduino IDE’s menus.

  3. Select Tools > Programmer > ARM CMSIS-DAP Compatible from the Arduino IDE’s menus.

  4. Make the connections between the debugger/programmer and the Nano 33 BLE:

    Programmer Target
    VCC +3V3
    SWDIO SWDIO
    SWCLK SWCLK
    GND GND
    RESET RESETN

    Here’s the pinout of the test pads on the Nano 33 BLE:
    Nano 33 BLE SWD1. Connect the USB cable of the programmer to your computer.

  5. Power the Nano 33 BLE (you can do this via the USB connector on the board). The debugger doesn’t power the board.

  6. Select Tools > Burn Bootloader from the Arduino IDE’s menus.

Hi Pert,

I have two Arduino nano IoT 33. It is possible to bootloader from a nano IoT 33 device to another nano IoT 33 device.

danielelec:
I have two Arduino nano IoT 33. It is possible to bootloader from a nano IoT 33 device to another nano IoT 33 device.

Yes. If you have an SD card module, you can just connect it to the Nano 33 IoT you want to use as the "Adafruit_DAP" programmer and then follow the instructions above. If you don't have an SD card module, the Adafruit_DAP library does have a "flash from header" example:
https://github.com/adafruit/Adafruit_DAP/blob/master/examples/flash_from_header/flash_from_header.ino
In this usage, you must put the bootloader data into the .h file. I don't have instructions for that usage but you might be able to use that example sketch as a reference.

Hi Pert

I am doing the tests to program the bootloader in the IoT Nano 33 but it does not work for me.

Attached the connections made between the devices.

I send the code that I upload to the Nano IoT programmer, but I changed the pins because the SPI communication of Nano IoT is through the ports:
Pin 7: CS
Pin 11: MOSI
Pin 12: MISO
Pin 13: SCK

I have doubts if I am doing wrong the process of changes of ports that are not declared in the program

The Program:

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

#define SD_CS 8
#define SWDIO 10
#define SWCLK 9
#define SWRST 7

#define FILENAME "fw.bin"

#define BUFSIZE 256 //don't change!
uint8_t buf[BUFSIZE];

//create a DAP for programming Atmel SAM devices
Adafruit_DAP_SAM dap;

// Function called when there's an SWD error
void error(const char *text) {
Serial.println(text);
while (1);
}

void setup() {
pinMode(13, OUTPUT);
Serial.begin(115200);
while(!Serial) {
delay(1); // will pause the chip until it opens serial console
}

dap.begin(SWCLK, SWDIO, SWRST, &error);

// see if the card is present and can be initialized:
if (!SD.begin(SD_CS)) {
error("Card failed, or not present");
}
Serial.println("Card initialized");

File dataFile = SD.open(FILENAME);

if(!dataFile){
error("Couldn't open file");
}

Serial.print("Connecting..."); 
if (! dap.dap_disconnect()) error(dap.error_message);

char debuggername[100];
if (! dap.dap_get_debugger_info(debuggername)) error(dap.error_message);
Serial.print(debuggername); Serial.print("\n\r");

if (! dap.dap_connect()) error(dap.error_message);

if (! dap.dap_transfer_configure(0, 128, 128)) error(dap.error_message);
if (! dap.dap_swd_configure(0)) error(dap.error_message);
if (! dap.dap_reset_link()) error(dap.error_message);
if (! dap.dap_swj_clock(50)) error(dap.error_message);
dap.dap_target_prepare();

uint32_t dsu_did;
if (! dap.select(&dsu_did)) {
Serial.print("Unknown device found 0x"); Serial.print(dsu_did, HEX);
error("Unknown device found");
}
for (device_t *device = dap.devices; device->dsu_did > 0; device++) {
if (device->dsu_did == dsu_did) {
Serial.print("Found Target: ");
Serial.print(device->name);
Serial.print("\tFlash size: ");
Serial.print(device->flash_size);
Serial.print("\tFlash pages: ");
Serial.println(device->n_pages);
//Serial.print("Page size: "); Serial.println(device->flash_size / device->n_pages);
}
}

/* Example of how to read and set fuses
Serial.print("Fuses... ");
dap.fuseRead(); //MUST READ FUSES BEFORE SETTING OR WRITING ANY
dap._USER_ROW.WDT_Period = 0x0A;
dap.fuseWrite();
*/

Serial.println(" done.");

Serial.print("Erasing... ");
dap.erase();
Serial.println(" done.");

Serial.print("Programming... ");
unsigned long t = millis();
uint32_t addr = dap.program_start();

while (dataFile.available()) {
memset(buf, BUFSIZE, 0xFF); // empty it out
dataFile.read(buf, BUFSIZE);
dap.programBlock(addr, buf);
addr += BUFSIZE;
}
dataFile.close();
Serial.println(millis() - t);
Serial.println("\nDone!");
dap.dap_set_clock(50);

dap.deselect();
dap.dap_disconnect();
}

void loop() {
//blink led on the host to show we're done
digitalWrite(13, HIGH);
delay(500); 
digitalWrite(13, LOW);
delay(500); 
}

You have your MISO and MOSI connections to the SD card module switched. Unlike serial, where we always must make the connections RX-TX, TX-RX (because "RX" stands for "receive" and "TX" stands for "transmit), with SPI, the connections are MISO-MISO, MOSI-MOSI. This is because "MISO" stands for the politically incorrect "master in, slave out", and MOSI for "master out, slave in".

Other than that, everything looks good. Switch those wires and give it another try. Hopefully you'll have luck this time!