Basic support for rebooting into the bootloader.
This commit is contained in:
parent
992df01067
commit
e7f788a72c
|
@ -34,6 +34,7 @@
|
|||
#include "pico/stdlib.h"
|
||||
#include "pico/usb_device.h"
|
||||
#include "pico/multicore.h"
|
||||
#include "pico/bootrom.h"
|
||||
#include "AudioClassCommon.h"
|
||||
|
||||
#include "run.h"
|
||||
|
@ -59,6 +60,10 @@ static struct {
|
|||
.freq = 48000,
|
||||
};
|
||||
|
||||
enum vendor_cmds {
|
||||
REBOOT_BOOTLOADER = 0
|
||||
};
|
||||
|
||||
int main(void) {
|
||||
setup();
|
||||
|
||||
|
@ -646,6 +651,20 @@ static bool do_set_current(struct usb_setup_packet *setup) {
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool ad_setup_request_handler(__unused struct usb_device *device, struct usb_setup_packet *setup) {
|
||||
setup = __builtin_assume_aligned(setup, 4);
|
||||
if (USB_REQ_TYPE_TYPE_VENDOR == (setup->bmRequestType & USB_REQ_TYPE_TYPE_MASK)) {
|
||||
// To prevent badly behaving software from accidentally triggering a reboot, e expect
|
||||
// the wValue to be equal to the Ploopy vendor id.
|
||||
if (setup->bRequest == REBOOT_BOOTLOADER && setup->wValue == 0x2E8A) {
|
||||
reset_usb_boot(0, 0);
|
||||
// reset_usb_boot does not return, so we will not respond to this command.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool ac_setup_request_handler(__unused struct usb_interface *interface, struct usb_setup_packet *setup) {
|
||||
setup = __builtin_assume_aligned(setup, 4);
|
||||
if (USB_REQ_TYPE_TYPE_CLASS == (setup->bmRequestType & USB_REQ_TYPE_TYPE_MASK)) {
|
||||
|
@ -726,6 +745,8 @@ void usb_sound_card_init() {
|
|||
count_of(boot_device_interfaces), _get_descriptor_string);
|
||||
|
||||
assert(device);
|
||||
|
||||
device->setup_request_handler = ad_setup_request_handler;
|
||||
audio_set_volume(DEFAULT_VOLUME);
|
||||
_audio_reconfigure();
|
||||
|
||||
|
|
|
@ -17,7 +17,21 @@ Run `filter_test` to process the PCM samples. The `filter_test` program takes tw
|
|||
You can listen to the PCM files using ffplay (which is usually included with ffmpeg):
|
||||
|
||||
```
|
||||
./ffplay -f s16le -ar 48000 -ac 2 output.pcm
|
||||
ffplay -f s16le -ar 48000 -ac 2 output.pcm
|
||||
```
|
||||
|
||||
If there are no obvious problems, go ahead and flash your firmware.
|
||||
|
||||
## reboot_bootloader.py
|
||||
If your Ploopy Headphones firmware is new enough, it has support for a USB vendor command that will cause the RP2040 to reboot into the
|
||||
bootloader. This will enable you to update the firmware without having to remove the case and short the pins on the board.
|
||||
|
||||
### Usage
|
||||
Connect the Ploopy headphones DAC and run:
|
||||
|
||||
```
|
||||
./reboot_bootloader.py
|
||||
```
|
||||
|
||||
You will need python3 and the pyusb module. If you get a permission denied error you may need to configure your udev rules, or run the
|
||||
script with administrator privileges.
|
|
@ -0,0 +1,29 @@
|
|||
#!/usr/bin/python3
|
||||
import usb.core
|
||||
from usb.util import *
|
||||
|
||||
REBOOT_BOOTLOADER = 0
|
||||
PLOOPY_VID = 0x2e8a
|
||||
PLOOPY_PID = 0xfedd
|
||||
|
||||
device_count = 0
|
||||
|
||||
# Find all connected Ploopy headphone devices
|
||||
for dev in usb.core.find(find_all=True, idVendor=PLOOPY_VID, idProduct=PLOOPY_PID):
|
||||
device_count += 1
|
||||
|
||||
# The vendor command expects the wValue to be equal to the Ploopy vendor id. This
|
||||
# will hopefully prevent badly behaved software from accidentally triggering bootloader
|
||||
# mode.
|
||||
try:
|
||||
dev.ctrl_transfer(CTRL_RECIPIENT_DEVICE | CTRL_TYPE_VENDOR, REBOOT_BOOTLOADER, PLOOPY_VID)
|
||||
except Exception as e:
|
||||
# The headphones do not respond to the vendor command, as they have already rebooted,
|
||||
# so for now, we always end up here.
|
||||
if e.errno == 32:
|
||||
# libusb pipe error, this is expected. OpenUSB doesnt report an error.
|
||||
pass
|
||||
else:
|
||||
print(e)
|
||||
|
||||
print(f"Sent a reboot command to {device_count} Ploopy devices.")
|
Loading…
Reference in New Issue