arduino / ArduinoCore-mbed

345 stars 199 forks source link

RPI Pico: LED blinks 4 long, 4 short, then again #316

Closed rei-vilo closed 3 years ago

rei-vilo commented 3 years ago

I am using the Arduino SDK and IDE.

The program compiles and links successfully, but after uploading, the Pico LED starts blinking 4 long (400 ms on, 400 ms off, 4 times) and 4 short (150 ms on, 150 ms off, 4 times) , and again.

Below a logic trace:

Capture 2021-09-03 18-02-59

Is this a kind of error message like with the Raspberry Pi B board? Where can I find the related documentation?

I first reported the issue at https://www.raspberrypi.org/forums/viewtopic.php?f=144&t=318967, as the blinking LED might have been a message from the hardware, as Inside the RP2040 is a 'permanent ROM' USB UF2 bootloader.

I solved the problem by using another port of Arduino for the RP2040 Pico at https://github.com/earlephilhower/arduino-pico

So the questions are:

Thank you!

facchinm commented 3 years ago

Hi @rei-vilo , the blinking pattern means that the RTOS has crashed; you can recover a crash dump by connecting an USB to serial port to pins 0/1 (GP0/GP1 -> UART1) . Do you have any example of large projects failing? It could be related to the different way we allocate the ram between stack and heap.

rei-vilo commented 3 years ago

Please find the report from GPIOs 0/1:

++ MbedOS Fault Handler ++

FaultType: HardFault

Context:
R0   : 0000002B
R1   : 10018135
R2   : 202F2F00
R3   : 2000D9DA
R4   : 00000000
R5   : 00000002
R6   : 2000CFE0
R7   : 10018135
R8   : 00000000
R9   : 00000000
R10  : 00000000
R11  : 00000000
R12  : 20000361
SP   : 2000B668
LR   : 10000E39
PC   : 10000E42
xPSR : 01000000
PSP  : 2000B648
MSP  : 2003FFC0
CPUID: 410CC601
Mode : Thread
Priv : Privileged
Stack: PSP

-- MbedOS Fault Handler --

++ MbedOS Error Info ++
Error Status: 0x80FF013D Code: 317 Module: 255
Error Message: Fault exception
Location: 0x10000E42
Error Value: 0x2000CF78
Current Thread: main Id: 0x2000D5B0 Entry: 0x1000948D StackSize: 0x8000 StackMem: 0x200036E8 SP: 0x2000B668 
For more info, visit: https://mbed.com/s/error?error=0x80FF013D&osver=61300&core=0x410CC601&comp=2&ver=110100&tgt=RASPBERRY_PI...

-- MbedOS Error Info --

The link https://armmbed.github.io/mbedos-error/?error=0x80FF013D&osver=61300&core=0x410CC601&comp=2&ver=110100&tgt=RASPBERRY_PI redirects to https://os.mbed.com/docs/mbed-os/v6.14/debug-test/analyzing-mbed-os-crash-dump.html.

The project is an example from the PDLS_EXT3_Basic, which uses some RAM for a frame-buffer, ca. 11248 bytes.

facchinm commented 3 years ago

The trace only makes sense in conjunction with the elf file you are using; take a look at https://github.com/janjongboom/mbed-os-example-fault-handler#running-the-crash-log-parser , enable verbose compilation in the IDE to discover the elf and map file location and try to run it :wink: It should at least give some insight on what is going on but I think it might be memory related indeed (if it only happens if the sketch is big as you stated)

rei-vilo commented 3 years ago

Thank you for the pointers. The Pico still doesn't run the program but no longer sends details about the mbed fault handler. If it happens again, I know the procedure now.

I'm using now the https://github.com/earlephilhower/arduino-pico port.

Dresch123 commented 2 years ago

Hi @rei-vilo , the blinking pattern means that the RTOS has crashed; you can recover a crash dump by connecting an USB to serial port to pins 0/1 (GP0/GP1 -> UART1) . Do you have any example of large projects failing? It could be related to the different way we allocate the ram between stack and heap.

I have run into the same problem with my Pico Pi using the Arduino MBed core. I upload a sketch, any sketch, and all I get is a blinking LED (as described) any more. I was doing something similar I guess (allocating a video buffer) when this blinking began. Could you explain what needs to be done once the USB-UART is connected to CP0/GP1? I would really like to be able to use my Pico Pi again. I tried reloading the UF2 file and that did not help. Thanks, Bill

rei-vilo commented 2 years ago

@Dresch123 I let @facchinm answer your question.

In the meantime, feel free to try the https://github.com/earlephilhower/arduino-pico port. It doesn't rely on mbedOS but on the RP2040 SDK.

Dresch123 commented 2 years ago

Thank you for the pointers. The Pico still doesn't run the program but no longer sends details about the mbed fault handler. If it happens again, I know the procedure now.

I'm using now the https://github.com/earlephilhower/arduino-pico port.

Yes, I do use Mr. Philhower's core, which is truly impressive. But I am using TFT_eSPI for high speed video onto LCD displays and the MBed core is strangely faster than the Philhower core for that. If you run the TFT_eSPI example "Bouncing Circles" using the MBed core the frames per second rate is 45, When you run it with the Philhower core, it's 17. I don't know why (something with SPI handling?), but it is very repeatable.

It seems like there should be a way of "unbricking" the Mbed so it can be used again. One bad memory allocation should not destroy a Pico Pi for Mbed...
Thanks for the suggestion.

Dresch123 commented 2 years ago

Thank you for the pointers. The Pico still doesn't run the program but no longer sends details about the mbed fault handler. If it happens again, I know the procedure now. I'm using now the https://github.com/earlephilhower/arduino-pico port.

Yes, I do use Mr. Philhower's core, which is truly impressive. But I am using TFT_eSPI for high speed video onto LCD displays and the MBed core is strangely faster than the Philhower core for that. If you run the TFT_eSPI example "Bouncing Circles" using the MBed core the frames per second rate is 45, When you run it with the Philhower core, it's 17. I don't know why (something with SPI handling?), but it is very repeatable.

It seems like there should be a way of "unbricking" the Mbed so it can be used again. One bad memory allocation should not destroy a Pico Pi for Mbed... Thanks for the suggestion.

Well, I just did the same thing to a brand new Pico Pi, just out of the bag, the blink-of-death after an Arduino Mbed download. I was trying to download the TFT_eSPI example for Mandelbrot for the GC9A01 round LCD. As soon as I downloaded the sketch, the Pico began doing the LED blink pattern and nothing on the LCD screen.

I believe I can now cause the blink-of-death repeatedly. Oh yay.

facchinm commented 2 years ago

@Dresch123 the LED blinking pattern is 99% due to a misconfiguration of SPI pins. Any misconfiguration will cause a runtime error. I just tested with

#define TFT_MISO        MISO
#define TFT_MOSI        MOSI
#define TFT_SCLK        SCK

in User_Setup.h and there's no crash. For the Pico, default SPI pins are mapped as

#define PIN_SPI_MISO  (4u)
#define PIN_SPI_MOSI  (3u)
#define PIN_SPI_SCK   (2u)

You can choose any of these pins (https://github.com/arduino/mbed-os/blob/rp2040_pr/targets/TARGET_RASPBERRYPI/TARGET_RP2040/PeripheralPins.c#L123-L167) as long as they are bound to the same peripheral (SPI_0 or SPI_1)

For example, this combination should work (in User_Setup.h)

#define TFT_MISO        (24)
#define TFT_MOSI        (11)
#define TFT_SCLK        (14)
Dresch123 commented 2 years ago

Thanks! In my user definition I used SPI0, the standard Pico pins defined in TFT_eSPI Pico-ILI9431 user definition. I am away from my bench and computer for a few days, but it was a configuration I have used before and a same wiring, but I will triple check when I get back. Once it starts blinking, I have not been able to recover, even trying to run programs (like Coremark) that have no SPI definitions in them. One other thing, the Picos that have been doing this have come from Adafruit. Previously I have used Picos from Microcenter and had not seen this issue. Is it possible that the Adafruit Picos which were purchased later had a later software version or something that made them more prone to this behavior? I will be back at my bench on Friday if there is anything you would like me to try. Thank you again. Any suggestions appreciated. I am tired of frying even $4 micros.

facchinm commented 2 years ago

The second issue looks unrelated; Adafruit boards might use a different external flash chip but the outcome would be a totally unresponsive board, not an led blinking pattern. About the SPI pins, I noticed thet the pins defined in TFT_eSPI lib are https://github.com/Bodmer/TFT_eSPI/blob/9e64092f58bc4b2458d51ad5bcb0b2e7fdcb6507/User_Setups/Setup60_RP2040_ILI9341.h#L125-L127 , so you may want to change MISO into something different to avoid overriding the default Serial1 interface (however, if you don't use it, it shouldn't hurt). Let me know if you are able to test this change as soon as you are back :wink:

Dresch123 commented 2 years ago

The second issue looks unrelated; Adafruit boards might use a different external flash chip but the outcome would be a totally unresponsive board, not an led blinking pattern. About the SPI pins, I noticed thet the pins defined in TFT_eSPI lib are https://github.com/Bodmer/TFT_eSPI/blob/9e64092f58bc4b2458d51ad5bcb0b2e7fdcb6507/User_Setups/Setup60_RP2040_ILI9341.h#L125-L127 , so you may want to change MISO into something different to avoid overriding the default Serial1 interface (however, if you don't use it, it shouldn't hurt). Let me know if you are able to test this change as soon as you are back 😉

Great hint! I have a suspicion... but another question: Would it matter if I elect not to use an SPUI pin, like MISO? A lot of LCDs don't require the use of MISO and it is sometimes defined as -1 in the definition file to indicate it is not used. Thanks again.

facchinm commented 2 years ago

Not yet, but we merged this PR https://github.com/arduino/mbed-os/pull/19 to allow exatly this use case, and it will be live in upcoming core release

Dresch123 commented 2 years ago

Sorry for the delay. Yes you were completely correct on the issue. I was leaving MISO (which is unused) undefined and that caused the flashing LED. When I defined MISO to an SPI defined pin, the flashing LED went away.

The other problem I had, having the flashing LEDs continuously with any program I downloaded was taken care of by a reload of the MBed core in the Arduino IDE... that was do to my own mucking around in the Mbed directory. Thanks for your help, it was really appreciated. Bill

juanmitaboada commented 2 years ago

Hello:

I am facing the same issue with the blinking led (4 times slow 4 times fast) in a tiny program that is trying to work with the OneWire library ( https://www.arduinolibraries.info/libraries/one-wire ), I have tried versions 2.3.6 and 2.3.7. My Raspberry Pi Pico is from 2020. I can flash it again with any other program, and it works fine, but it just stuck with this one, and I don't understand what I am doing wrong. I also have tried other PINs like 3-4-5-10-20 with the same result. I am using PlatformIO 6.1.4.

The program is:

#include <OneWire.h>

#define PIN 15

OneWire onebus(PIN);

void setup(void) {
    // Boot wait
    delay(3000);

    // Set serial
    Serial.begin(115200);

    // Reset OneWire
    Serial.println("Try to reset and it will be stuck...");
    onebus.reset();
    Serial.println("The program doesn't get here!");
}

void loop(void) {
}

Thank you,

Dresch123 commented 2 years ago

Maybe try this OneWire library meant for the Pico Pi: https://github.com/adamboardman/pico-onewire

juanmitaboada commented 2 years ago

I have tried to make it work with PlatformIO without success.

juanmitaboada commented 2 years ago

This one works like a charm on PlatformIO: https://github.com/pstolarz/OneWireNg

Chick92 commented 2 years ago

I'm having the same issue -

Code works fine when micro is plugged into computer Code works fine when micro is plugged into robot computer (Pi4) when robot computer is already up and running micro crashes when plugged into robot computer and both are switched on together.

Is there a way of delaying the MBED RTOS from coming up for say 30 seconds? It's a standard raspberry pi pico.

facchinm commented 2 years ago

Hi @Chick92 , the problem is probably that the Pi4 switching on sends some unexpected (or out of order) message on the Pico and this crashed the usb stack entirely. If you could connect an USB-to-serial on pin 0 (UART TX) and grab the crash output I can try fixing it at a deeper level :slightly_smiling_face:

Chick92 commented 2 years ago

Hi @facchinm,

Yeah I came to the same conclusion. IT's strange though because it's running ROS, so it should ignore everything until it gets a proper ROS message, and it should also go into while loop until the ROS master registers with it.

Unfortunately I can't connect anything to the UART pins as it's deep within the robot under a ratsnest of wires and the pico is soldered to a custom breakout board.

I've tried the following:

Use https://github.com/earlephilhower/arduino-pico instead of arduino mbed, as that doesn't rely on the rtos. This works really well and has a lot of interesting features which the mbed core doesn't but, but unfortunately my code relies on some hardware PWM libaries and gpio stuff that only work with the mbed core (they don't work properly under this). Shame as this was the easiest fix.

setting the pi's eeprom to leave the USB power off for as long as possible - USB_MSD_PWR_OFF_TIME=5000 - this broke my pi and i had to do a firmware recovery on it.

powercycling the PI's USB ports at boot with a script using usbctl - https://github.com/mvp/uhubctl , but i can't get the script to run at boot properly.. different matter, but power cycling does work. That wouldn't adequately solve the problem anyway though, as the pico failure state is to activate the rear left drive motor at full power... This seems to happen after about 5 seconds of everything being turned on. So the robot would be crashing around until the pi was able to finish booting - potentially 20-30 seconds.

My current solution is to use this - https://thepihut.com/products/usb-power-switch-module it's a usb switch that's held low with a pull down resistor. My plan, when it arrives tomorrow is to integrate that such that after the pi has booted up, it brings a gpio pin high to activate the USB device, which is the pico in this case.

This has been a lot of work for something that I thought was already working, and only noticed when i brought the system up all together for the first time. irritating but that's engineering for you!

juanmitaboada commented 2 years ago

Hello again, I got it resolved with OneWireNg and DallasTemperature by @milesburton.

I have extracted the piece of code that you need (please, consider that this snippet is a part of a bigger source code at Alioli UAV ROV Submarine Drone Software Framework for Arduino which you may have to lookup up for better understanding):

#include <Wire.h>
#include <OneWireNg_CurrentPlatform.h>
#include <DallasTemperature.h>

void setup() {
    // Prepare access to sensors
    OneWire oneWireObject(PINOUT_ONEWIRE_BUS_PIN);
    DallasTemperature sensorDS18B20(&oneWireObject);

    // Startup sensor
    sensorDS18B20.begin();
}

void loop() {
    // Instance to OneWire and DallasTemperature classes
    OneWire oneWireObject(PINOUT_ONEWIRE_BUS_PIN);
    DallasTemperature sensorDS18B20(&oneWireObject);
    DeviceAddress temp1 = TEMPERATURE_SENSOR_1;
    DeviceAddress temp2 = TEMPERATURE_SENSOR_2;

    // Get temperature from the sensors
    sensorDS18B20.requestTemperatures();
    temperature1 = sensorDS18B20.getTempC(temp1);
    temperature2 = sensorDS18B20.getTempC(temp2);
}

Please, let me know if you got it working fine. Good luck!

Chick92 commented 2 years ago

Hi @juanmitaboada

My code doesnt actually use any i2c or SPI comms, just ROS via the USB serial.

The hack of having to turn on the pico with the usb switch works very well though, so not a massive issue anymore.

LioBou commented 1 year ago

@juanmitaboada : I could not make it work with this code:

Hello again, I got it resolved with OneWireNg and DallasTemperature by @milesburton.

I have extracted the piece of code that you need (please, consider that this snippet is a part of a bigger source code at Alioli UAV ROV Submarine Drone Software Framework for Arduino which you may have to lookup up for better understanding):

#include <Wire.h>
#include <OneWireNg_CurrentPlatform.h>
#include <DallasTemperature.h>

void setup() {

Please, let me know if you got it working fine. Good luck!

Having the same issue with DS18B20 sensor notworking on Raspberry Pico (I'm using Arduino IDE 2.0): same 'led-blink-of-the-death' issue.

However, the code which is proposed by OneWireNg library (Example > OneWireNg > arduino > DallasTemperature) works fine !

juanmitaboada commented 1 year ago

@LioBou, thank you for your feedback. I tested it with Platform.io so this is maybe the cause. The full code is working at Alioli Buoy.

LioBou commented 1 year ago

Unfortunately, I went too quick saying that the "code which is proposed by OneWireNg library (Example > OneWireNg > arduino > DallasTemperature) works fine !"... It works fine with 2 sensors on 2 different pins, but when adding a 3rd sensor on a 3rd pin, the "blinking of the death" is back again !! Incredible...

juanmitaboada commented 1 year ago

Have you tried my approach with Platfom.io? I got working 2 sensors on the same pin.

facchinm commented 1 year ago

Hi everyone, just two words about "led-blink-of-the-death"; while inconvenient, trapping errors this way allows spotting them early (and avoiding the frustration of a sketch that compiles, runs but doesn't provide the expected output). Second, connecting an FTDI converter to the default serial port (Pins 0/1 in case of the nano rp2040) allows getting a proper error, most of the times with an indication of the offending line. For example, adding the third pin as @LioBou did will print this:

*** PANIC ***

No PIO state machines are available

++ MbedOS Fault Handler ++

FaultType: HardFault

Context:
R0   : 0000000A
R1   : 0000000A
R2   : 00000000
R3   : 22400000
R4   : FFFFFFFF
R5   : 200028CC
R6   : 00000000
R7   : 00000003
R8   : 00000000
R9   : 00000000
R10  : 00000000
R11  : 00000000
R12  : 00000008
SP   : 2000A880
LR   : 1000E481
PC   : 1000C7D0
xPSR : 01000000
PSP  : 2000A860
MSP  : 2003FFC0
CPUID: 410CC601
Mode : Thread
Priv : Privileged
Stack: PSP

-- MbedOS Fault Handler --

++ MbedOS Error Info ++
Error Status: 0x80FF013D Code: 317 Module: 255
Error Message: Fault exception
Location: 0x1000C7D0
Error Value: 0x2000A924
Current Thread: main Id: 0x200027E0 Entry: 0x10006EB5 StackSize: 0x8000 StackMem: 0x20002920 SP: 0x2000A880 
For more info, visit: https://mbed.com/s/error?error=0x80FF013D&osver=61700&core=0x410CC601&comp=2&ver=90200&tgt=RASPBERRY_PI_PICO
-- MbedOS Error Info --

And the error is clear in the first lines (no PIO state machine is available) since the RP2040 only has two

pstolarz commented 1 year ago

@facchinm That's correct. Using OneWireNg's OneWireNg_PicoRP2040PIO (1-wire PIO driver), it's possible to create up to 4 different 1-wire drivers working on 4 different GPIO pins - 2 of them on PIO-0 and 2 on PIO-1 (provided no other PIO program is already uploaded). PIO number for use by the driver is passed by 3rd argument of OneWireNg_PicoRP2040PIO constructor (by default PIO-0 is used).

BTW: For Pico's Mbed core it's possible to use OneWireNg_ArduinoMbedHAL (1-wire bit-banging driver) to handle more than 4 pins as 1-wire masters. Additionaly there is also OneWireNg_PicoRP2040 bit-banging driver which is aimed mainly for PicoSDK API (no Mbed core), although in case of this driver there are observed some issues with UART communication (due to blocking interrupts while handling 1-wire activities by the driver) and in this case it's necessary to configure the library with relaxed interrupt handling (CONFIG_BITBANG_TIMING_RELAXED). As you can see there are plenty of options for using 1-wire on Pico HW via OneWireNg.

LioBou commented 1 year ago

Thank you all for your comments. I better understand why trying on 3 different Pins can not work. If I understood well, the OneWireNg library uses PIO (not GPIO) of the Pico/RP2040, so limiting the possible total number to 2 differrent PIO if I understand correctly the Pico datasheet ("2 × Programmable IO (PIO) blocks, 8 state machines total"). Am I correct ?

pstolarz commented 1 year ago

By default OneWireNg uses OneWireNg_PicoRP2040PIO (the PIO driver). There are 2 PIOs each consisting of 4 state machines and memory for 32 PIO program instructions. OneWireNg driver's PIO program consist of 16 instructions therefore it's possible to run only 2 drivers on a single PIO. It's possible to tell the library to use also PIO-1 (not only PIO-0 as for default) and extend the number of drivers to 4. It is also possible to use GPIO bit-banging driver OneWireNg_PicoRP2040PIO for unlimited number of 1-wire drivers.