PlatformIO + ElectroSmith: libDaisy build issues

I’m having issues setting up a project using Daisy Seed libraries, specifically libDaisy, on platformio.

I’m running PIO v3.1.1 on VSCode v1.78.2.23132 installed via snap v2.59.2 on Ubuntu 23.04.

My platformio.ini file is as follows:

[env:electrosmith_daisy_libs]
platform = ststm32
board = electrosmith_daisy
framework = arduino
lib_ldf_mode = deep+
lib_deps = 
    https://github.com/electro-smith/DaisySP.git
    https://github.com/electro-smith/libDaisy.git
    https://github.com/electro-smith/DaisyDuino.git

build_flags = 
    ;-w                            ; optional - to suppress redundant definition warnings
    -D HAL_SDRAM_MODULE_ENABLED     ; required? build fails without this one
    ; These flags enable serial monitor over USB UART
    -D USBD_USE_CDC                 ; Define USB Communications Device Class (for serial I/O)
    -D USBCON                       ; Enable USB connection in Arduino (?)
; This is not documented on PlatformIO website but
; enables the DFU firmware upload (over USB)
upload_protocol = dfu

When I use PIOs list dependencies, I get:

Resolving electrosmith_daisy_libs dependencies...
Platform ststm32 @ 15.6.0 (required: ststm32)
├── framework-arduinoststm32 @ 4.20400.0 (required: platformio/framework-arduinoststm32 @ ~4.20400.0)
├── framework-cmsis @ 2.50700.210515 (required: platformio/framework-cmsis @ ~2.50700.0)
├── framework-stm32cubeh7 @ 1.9.0 (required: platformio/framework-stm32cubeh7 @ ~1.9.0)
├── tool-dfuutil @ 1.11.0 (required: platformio/tool-dfuutil @ ~1.11.0)
├── tool-ldscripts-ststm32 @ 0.2.0 (required: platformio/tool-ldscripts-ststm32 @ ~0.2.0)
└── toolchain-gccarmnoneeabi @ 1.90201.191206 (required: platformio/toolchain-gccarmnoneeabi @ ~1.90201.0)

Libraries
├── DaisyDuino @ 1.6.3+sha.0932d70 (required: git+https://github.com/electro-smith/DaisyDuino.git)
├── DaisySP @ 0.0.0+20230517121042.sha.ed11433 (required: git+https://github.com/electro-smith/DaisySP.git)
└── googletest @ 1.10.0+sha.b65a1ba (required: git+https://github.com/electro-smith/libDaisy.git)

Which means PIO is adding libDaisy as googletest for some reason…

While building, this is confirmed by this part of the output:

Scanning dependencies...
Dependency Graph
|-- DaisySP @ 0.0.0+20230517121042.sha.ed11433
|-- DaisyDuino @ 1.6.3+sha.0932d70
Building in release mode

libDaisy’s missing. When I look inside the libdeps folder:

Screenshot from 2023-05-17 12-16-53

Yup, it’s missing.

When I try to install the libDaisy manuall via pio cli:

pio pkg install --library "https://github.com/electro-smith/libDaisy.git#5.3.0"

This is the output I’m getting:

Resolving electrosmith_daisy_libs dependencies...
Library Manager: Installing git+https://github.com/electro-smith/libDaisy.git#v5.3.0
git version 2.39.2
Cloning into '/home/usr/.platformio/.cache/tmp/pkg-installing-c760dxgd'...
remote: Enumerating objects: 1049, done.
remote: Counting objects: 100% (1049/1049), done.
remote: Compressing objects: 100% (916/916), done.
remote: Total 1049 (delta 282), reused 330 (delta 119), pack-reused 0
Receiving objects: 100% (1049/1049), 8.07 MiB | 1.97 MiB/s, done.
Resolving deltas: 100% (282/282), done.
Note: switching to '07a813a09e8386b7dcb0b84bd867db0215f7c149'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -c with the switch command. Example:

  git switch -c <new-branch-name>

Or undo this operation with:

  git switch -

Turn off this advice by setting config variable advice.detachedHead to false

Submodule 'tests/googletest' (https://github.com/google/googletest.git) registered for path 'tests/googletest'
Cloning into '/home/usr/.platformio/.cache/tmp/pkg-installing-c760dxgd/tests/googletest'...
remote: Enumerating objects: 26287, done.        
remote: Counting objects: 100% (262/262), done.        
remote: Compressing objects: 100% (142/142), done.        
remote: Total 26287 (delta 137), reused 189 (delta 108), pack-reused 26025        
Receiving objects: 100% (26287/26287), 12.48 MiB | 2.15 MiB/s, done.
Resolving deltas: 100% (19409/19409), done.
Submodule path 'tests/googletest': checked out 'f5e592d8ee5ffb1d9af5be7f715ce3576b8bf9c4'
Library Manager: googletest@1.10.0+sha.07a813a has been installed!

So it seems that because libDaisy has a submodule named tests/googletest, libDaisy is being installed under that name and I guess that breaks the dependencies in PIO?

When trying to install from a folder (the one from DaisyExamples compiled right there with make) as defined in platformio.ini:

libDaisy=file:///home/usr/DaisyExamples/libDaisy/

The foldername is correct because I force it to be libDaisy, but the contents are those of tests/googletest YET AGAIN!!!

At this point I have no idea how to go about adding libDaisy in platformio. How can I do that correctly? Maybe I clone the librabry, remove the tests/googletest submodule and import it then? Would that work?

When we’re on that topic: why isn’t there an official instruction on how make Daisy work with PIO? Is PIO a platform the devs at ElectroSmith just don’t want to cooperate with?

Hi mjg!

I’m sorry to hear that there’s an issue with adding libDaisy in PlatformIO.
We wanted to clarify with you that PlatformIO is a community run integration and Electrosmith does not support it in an official capacity. That said, we would of course be happy to see Daisy integrated with it, but it’s just that we haven’t had the chance to do so.

I hope there’s a member of the Daisy community who had success with it and can chime in.
I’m sorry that I don’t have a concrete troubleshooting solution for you at the moment.

I just got my Daisy Patch yesterday, so I’m a bit new to all of this but I’ll try and explain what I understand so far.

DaisyDuino and libDaisy are separate HALs. DaisyDuino includes components of DaisySP without needing it as a separate library.

So to start with, you’ll need to decide if you’re using the Arduino framework and DaisyDuino, or CMSIS and libDaisy. If you’re planning on using DaisyDuino, you can simply use the library in PlatformIO’s registry like so:

[env:Daisy]
platform = ststm32
board = electrosmith_daisy
framework = arduino
lib_deps = 
  electro-smith/DaisyDuino@1.6.0

build_flags = 
    -D HAL_SDRAM_MODULE_ENABLED 
    -D USBD_USE_CDC
    -D USBCON

upload_protocol = jlink

This compiles and uploads with a simple test file in src/

#include "DaisyDuino.h"

DaisyHardware patch;

int main(void) {
  patch = DAISY.init(DAISY_PATCH, AUDIO_SR_48K);
  pinMode(LED_BUILTIN, OUTPUT);

  bool led_state = true;

  while (true) {
    digitalWrite(LED_BUILTIN, led_state);
    led_state = !led_state;
    System::Delay(500);
  }
}

If you’re trying to use bare CMSIS and libDaisy in PlatformIO, however, things get a bit more complicated.

You’ll need a copy of libDaisy on your computer somewhere, not installed by PlatformIO, either in the lib/ folder or a separate location using the file:// specifier as you already tried. I haven’t used the file:// resource locator, but it should work all the same, I just tend to use hardlinks.

At the top level of libDaisy (wherever it is), you’ll need to define a PlatformIO library.json definition, since one does not yet exist for libDaisy. This is based directly on the Makefiles and cmake scripts included in libDaisy, and I might be submitting this as a PR in the near future, idk.

{
  "name": "libDaisy",
  "version": "5.3.0",
  "keywords": "dsp, audio, midi, hal",
  "description": "Hardware Abstraction Library for the Daisy Audio Platform",
  "platforms": "ststm32",
  "build": {
    "srcDir": ".",
    "srcFilter": "+<src> +<core/startup_stm32h750xx.c> +<Drivers/STM32H7xx_HAL_Driver> +<Middlewares> -<Middlewares/Third_Party/FatFs/src/option> -<**/*_template.c>",
    "includeDir": "src",
    "extraScript": "platformio.py",
    "unflags": ["-std=gnu++11"],
    "flags": [
      "-mthumb",
      "-mcpu=cortex-m7",
      "-mfpu=fpv5-d16",
      "-mfloat-abi=hard",

      "-Wall",
      "-Wno-attributes",
      "-Wno-strict-aliasing",
      "-Wno-maybe-uninitialized",
      "-Wno-stringop-overflow",

      "-I src",
      "-I src/sys",
      "-I src/usbd",
      "-I src/usbh",
      "-I Drivers/CMSIS/Include ",
      "-I Drivers/CMSIS/Device/ST/STM32H7xx/Include",
      "-I Drivers/STM32H7xx_HAL_Driver/Inc",
      "-I Drivers/STM32H7xx_HAL_Driver/Inc/Legacy",
      "-I Middlewares/ST/STM32_USB_Device_Library/Core/Inc",
      "-I Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc",
      "-I Middlewares/ST/STM32_USB_Host_Library/Core/Inc",
      "-I Middlewares/ST/STM32_USB_Host_Library/Class/MSC/Inc",
      "-I Middlewares/Third_Party/FatFs/src",
      "-I src"
    ]
  }
}

You’ll also need a python script to add the correct conditional compiler and linker flags at platformio.py, again at the top level of libDaisy. This is also based directly on the Makefiles already in libDaisy.

Import("env")

C_DEFS = [
    "-DCORE_CM7",
    "-DSTM32H750xx",
    "-DSTM32H750IB",
    "-DARM_MATH_CM7",
    "-Dflash_layout",
    "-DHSE_VALUE=16000000",
    "-DUSE_HAL_DRIVER",
    "-DUSE_FULL_LL_DRIVER",
    "-DDATA_IN_D2_SRAM",
]

CPP_WARNINGS = [
    "-Wno-register"
]

CPPFLAGS = [
     "-fno-exceptions", 
     "-fno-rtti"
]

C_STANDARD = ["-std=gnu11"]
CPP_STANDARD = ["-std=gnu++11"]

env.Append(CFLAGS = C_STANDARD + C_DEFS)
env.Append(CXXFLAGS = CPP_STANDARD + CPPFLAGS + CPP_WARNINGS)

# linker flags
env.Append(
  LINKFLAGS=[
      "-mfloat-abi=hard",
      "-mfpu=fpv5-sp-d16",
      "--specs=nano.specs",
      "--specs=nosys.specs",
      "-Wl,--gc-sections"
  ]
)

With all of that out of the way, you can now declare a platformio.ini at the top level of your project that simply uses libDaisy:

[env]
platform = ststm32
board = electrosmith_daisy
board_build.ldscript = lib/libDaisy/core/STM32H750IB_flash.lds
lib_deps = libDaisy
build_unflags = 
  "-std=gnu++11" # libDaisy uses c++17, not c++11
build_flags =
  "-std=c++17"
  "-mfloat-abi=hard"
  "-mfpu=fpv5-sp-d16"

upload_protocol = jlink

[env:release]
build_type=release

[env:debug]
build_type = debug
debug_tool = jlink

Note the ldscript! You can change this path to use the other linker scripts for QSPI and SRAM.

There’s also no framework = cmsis needed here, as libDaisy already includes a copy of CMSIS in its source. You can add it if you need functions from CMSIS that aren’t in libDaisy. I haven’t had problems with collision yet, but it might happen, so just something to be aware of.

From here you can fully access the libDaisy contents and use it normally, such as with a generic Blink example in src/:

#include <daisy_seed.h>

daisy::DaisySeed hardware;

int main(void) {
  hardware.Init();

  bool led_state = true;
  while (true) {
    hardware.SetLed(led_state);
    led_state = !led_state;

    daisy::System::Delay(500);
  }
}

Hope this helps some!

2 Likes