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?
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.
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
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...
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!
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.
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.
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.
Plug the USB cable of the programmer Arduino board into your computer.
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.
Unplug the programmer Arduino board from your computer.
Disconnect the programmer Arduino board from the target Arduino board.
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.
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:
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.
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.
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!!
To complete this line.
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!)
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.
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.
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.
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.
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!