From 4b29b6a223b960723b3cdf0a2b8377dfc8aaf58f Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 28 Dec 2023 22:04:57 +0700 Subject: [PATCH] add Brain::dap_readFlash(), add read_nrf52840_to_sdcard example --- .../program_esp32_uart/program_esp32_uart.ino | 63 +++++++++- .../.pico_rp2040_tinyusb.test.only | 0 .../read_nrf52840_to_sdcard.ino | 112 ++++++++++++++++++ src/Adafruit_TestBed_Brains.cpp | 49 +++++++- src/Adafruit_TestBed_Brains.h | 3 + 5 files changed, 218 insertions(+), 9 deletions(-) create mode 100644 examples/Brain/read_nrf52840_to_sdcard/.pico_rp2040_tinyusb.test.only create mode 100644 examples/Brain/read_nrf52840_to_sdcard/read_nrf52840_to_sdcard.ino diff --git a/examples/Brain/program_esp32_uart/program_esp32_uart.ino b/examples/Brain/program_esp32_uart/program_esp32_uart.ino index 62b89b2..7fbed13 100644 --- a/examples/Brain/program_esp32_uart/program_esp32_uart.ino +++ b/examples/Brain/program_esp32_uart/program_esp32_uart.ino @@ -47,9 +47,8 @@ void setup() { while (!Serial) delay(10); Serial.println("Tester Brains: Programming ESP with UART!"); - Brain.begin(); - Brain.usbh_setVBus(true); // enable VBUS for power - + // sync: wait for Brain.begin() called in core1 before accessing SD or other peripherals + while (!Brain.inited()) delay(10); while ( !Brain.esp32_begin(&ESP32BootROM, ESP32_BAUDRATE) ) { // retry syncing delay(100); @@ -77,3 +76,61 @@ void setup() { void loop() { } + +//--------------------------------------------------------------------+ +// Setup and Loop on Core1 +//--------------------------------------------------------------------+ + +// call usbh_begin() here to make pio usb background task run on core1 +// NOTE: Brain.begin() should be called here as well to prevent race condition +void setup1() { + Brain.begin(); + Brain.usbh_begin(); + + Brain.LCD_printf(0, "No USB attached"); + Brain.LCD_printf(1, "Plug your device"); +} + +// core1's loop: process usb host task on core1 +void loop1() { + if ( Brain.esp32_s3_inReset() ){ + // Note: S3 has an USB-OTG errata + // https://www.espressif.com/sites/default/files/documentation/esp32-s3_errata_en.pdf + // which is walkarounded by idf/arduino-esp32 to always mux JTAG to USB for + // uploading and/or power on. Afterwards USB-OTG will be set up if selected + // so. However rp2040 USBH is running too fast and can actually retrieve + // device/configuration descriptor of JTAG before the OTG is fully setup. + // We delay a bit here + delay(500); + + Brain.esp32_s3_clearReset(); + } + + Brain.USBHost.task(); + yield(); +} + +//--------------------------------------------------------------------+ +// TinyUSB Host callbacks +// Note: running in the same core where Brain.USBHost.task() is called +//--------------------------------------------------------------------+ +extern "C" { + +// Invoked when device is mounted (configured) +void tuh_mount_cb (uint8_t daddr) +{ + uint16_t vid, pid; + tuh_vid_pid_get(daddr, &vid, &pid); + + Serial.printf("Device attached, address = %d\r\n", daddr); + Brain.LCD_printf("USBID %04x:%04x", vid, pid); +} + +/// Invoked when device is unmounted (bus reset/unplugged) +void tuh_umount_cb(uint8_t dev_addr) +{ + (void) dev_addr; + Brain.LCD_printf(1, "No USB Device"); +} + +} diff --git a/examples/Brain/read_nrf52840_to_sdcard/.pico_rp2040_tinyusb.test.only b/examples/Brain/read_nrf52840_to_sdcard/.pico_rp2040_tinyusb.test.only new file mode 100644 index 0000000..e69de29 diff --git a/examples/Brain/read_nrf52840_to_sdcard/read_nrf52840_to_sdcard.ino b/examples/Brain/read_nrf52840_to_sdcard/read_nrf52840_to_sdcard.ino new file mode 100644 index 0000000..7b7195e --- /dev/null +++ b/examples/Brain/read_nrf52840_to_sdcard/read_nrf52840_to_sdcard.ino @@ -0,0 +1,112 @@ +// This sketch program SAMD with bin file from SDCard using Adafruit_DAP +// Hardware wiring: +// - Brain's header Reset <-> Target Reset +// - Brain's header SWDIO <-> Target SWDIO +// - Brain's header SWCLK <-> Target SWCLK +// - Brain's USB host to Target USB + +// required for Host MSC block device +#include "SdFat.h" + +// required for USB host +#include "pio_usb.h" +#include "Adafruit_TinyUSB.h" + +// required for DAP programming +#include "Adafruit_DAP.h" + +#include "Adafruit_TestBed_Brains.h" + +// file path on SDCard to hold nrf52840 binary +#define READ_FILE_PATH "nrf/readback.bin" +#define READ_SIZE (1024u*1024u) // 1 MB + +// DAP interface for nRF5x +Adafruit_DAP_nRF5x dap; + +//--------------------------------------------------------------------+ +// Setup and Loop on Core0 +//--------------------------------------------------------------------+ + +void print_speed(size_t count, uint32_t ms) { + Brain.LCD_printf(0, "%.01fKB in %.01fs", count/1000.0F, ms / 1000.0F); + + Serial.printf("Completed %u bytes in %.02f seconds.\r\n", count, ms / 1000.0F); + Serial.printf("Speed : %.02f KB/s\r\n", (count / 1000.0F) / (ms / 1000.0F)); +} + +void setup() { + Serial.begin(115200); + while (!Serial) delay(10); + Serial.println("Tester Brains: nRF52840 programming !"); + + // sync: wait for Brain.usbh_begin() called in core1 before accessing SD or other peripherals + while (!Brain.usbh_inited()) delay(10); + + Brain.SD_begin(SD_SCK_MHZ(16)); + + // Print out file on SD if Serial is connected + if (Serial) { + Serial.println(); + Serial.println("SD Contents:"); + Serial.printf("Card size = %0.1f GB\n", 0.000000512 * Brain.SD.card()->sectorCount()); + Brain.SD.ls(LS_R | LS_SIZE); + } + + Brain.targetReset(); + Brain.dap_begin(&dap); + Brain.dap_connect(); + + uint32_t ms = millis(); + size_t nbytes = Brain.dap_readFlash(READ_FILE_PATH, 0, READ_SIZE); + ms = millis() - ms; + print_speed(nbytes, ms); + + Brain.dap_disconnect(); + Brain.targetReset(); + +} + +void loop() { +} + +//--------------------------------------------------------------------+ +// Setup and Loop on Core1 +//--------------------------------------------------------------------+ + +// call usbh_begin() here to make pio usb background task run on core1 +// NOTE: Brain.begin() should be called here as well to prevent race condition +void setup1() { + Brain.begin(); + Brain.usbh_begin(); + Brain.LCD_printf(1, "No USB Device"); +} + +// core1's loop: process usb host task on core1 +void loop1() { + Brain.USBHost.task(); +} + +//--------------------------------------------------------------------+ +// TinyUSB Host callbacks +// Note: running in the same core where Brain.USBHost.task() is called +//--------------------------------------------------------------------+ +extern "C" { + +// Invoked when device is mounted (configured) +void tuh_mount_cb (uint8_t dev_addr) +{ + uint16_t vid, pid; + tuh_vid_pid_get(dev_addr, &vid, &pid); + + Brain.LCD_printf("USBID %04x:%04x", vid, pid); +} + +/// Invoked when device is unmounted (bus reset/unplugged) +void tuh_umount_cb(uint8_t dev_addr) +{ + (void) dev_addr; + Brain.LCD_printf(1, "No USB Device"); +} + +} diff --git a/src/Adafruit_TestBed_Brains.cpp b/src/Adafruit_TestBed_Brains.cpp index 60b597a..783491b 100644 --- a/src/Adafruit_TestBed_Brains.cpp +++ b/src/Adafruit_TestBed_Brains.cpp @@ -399,6 +399,49 @@ size_t Adafruit_TestBed_Brains::dap_programFlash(const char *fpath, return fsize; } +size_t Adafruit_TestBed_Brains::dap_readFlash(const char *fpath, uint32_t addr, + size_t size) { + if (!dap) { + return 0; + } + + size_t bufsize = 4096; + uint8_t *buf = (uint8_t *)malloc(bufsize); + if (!buf) { + return 0; + } + + File32 fsrc = SD.open(fpath, O_CREAT | O_WRONLY); + if (!fsrc) { + Serial.printf("SD: cannot open file: %s\r\n", fpath); + return 0; + } + + LCD_printf("Reading..."); + + size_t remain = size; + while (remain) { + uint32_t count = min(remain, bufsize); + + setLED(HIGH); + if (!dap->dap_read_block(addr, buf, (int)count)) { + Serial.printf("Failed to read block at %08lX\n", addr); + break; + } + setLED(LOW); + + fsrc.write(buf, count); + + addr += count; + remain -= count; + } + + fsrc.close(); + LCD_printf("Done!"); + + return size - remain; +} + //--------------------------------------------------------------------+ // SD Card //--------------------------------------------------------------------+ @@ -603,12 +646,6 @@ void Adafruit_TestBed_Brains::usbh_setVBus(bool en) { digitalWrite(_vbus_en_pin, en ? HIGH : LOW); } -void Adafruit_TestBed_Brains::usbh_VBusCycle(uint32_t off_time) { - usbh_setVBus(false); - delay(off_time); - usbh_setVBus(true); -} - bool Adafruit_TestBed_Brains::usbh_begin(void) { // Check for CPU frequency, must be multiple of 120Mhz for bit-banging USB uint32_t cpu_hz = clock_get_hz(clk_sys); diff --git a/src/Adafruit_TestBed_Brains.h b/src/Adafruit_TestBed_Brains.h index 0d9c18a..cad6805 100644 --- a/src/Adafruit_TestBed_Brains.h +++ b/src/Adafruit_TestBed_Brains.h @@ -76,6 +76,9 @@ public: size_t dap_programFlash(const char *fpath, uint32_t addr, bool do_verify = true); + // read dap target flash to file on SDCard + size_t dap_readFlash(const char *fpath, uint32_t addr, size_t size); + //--------------------------------------------------------------------+ // Public Variables //--------------------------------------------------------------------+