electro-smith / libDaisy

Hardware Library for the Daisy Audio Platform
https://www.electro-smith.com/daisy
MIT License
328 stars 138 forks source link

change libdaisy.h to daisy.h #51

Closed PaulBatchelor closed 4 years ago

PaulBatchelor commented 4 years ago

The "lib" is redundant (every library filename needs to have lib prefix in front of it), and is more common to not use it. Libsndfile, for instance, has a header called "sndfile.h"

stephenhensley commented 4 years ago

yup.

Had this exact thought myself the other day.

should be easy, and won't really break any examples since they all include dsy_seed.h

PaulBatchelor commented 4 years ago

@stephenhensley it may take some shuffling around, but I think it would eventually be great to make the examples just include a "daisy.h", "daisysp.h" and nothing else. What do you think about that?

stephenhensley commented 4 years ago

@PaulBatchelor it would, but it removes the ability to configure the hardware, or make custom hardware based on the daisy family.

For example, the daisy seed is currently the only "brain board" in use, but if we do a different size factor or something later it would likely require pin changes in certain spots.

Same goes for the common hardware platforms (Patch, Petal, Pod, Field, etc.) and custom platforms.

So very similar to what you want, all things that aren't platform specific include dsy_seed.h

Once you want to start using the knobs and stuff a certain level of platform-specific configuration is mandatory (how many knobs, how many LEDs, what kind of switches, etc.) all come into play. this is where the bsp files come in.

I updated the verb example to use the dsy_patch_bsp.h file. (So it only needs to include dsy_patch_bsp.h, and daisysp.h)

the daisy_patch type has a daisy_handle for the seed (with all of its internal configuration) as well as the stuff unique to the Patch hardware. Knob configuration, types of buttons, etc.

Without this level of flexibility hardware development would be a lot more difficult. When we started the library I had a lot of the hardware config baked into the peripheral drivers, but even doing a backwards compatible rev2 with a few minor pin changes was a nightmare to handle.

Now you can create an entire new hardware platform, and set it up to use libdaisy just by making a new bsp file (which doesn't have to be kept as part of the library).

And if someone even wanted to put the MCU onto their own custom PCB, and still use it with libdaisy all they would have to do is write a new file like dsy_seed.h without having to edit the internal bits of the library.

I think this is a happy medium, as it still lets a user include only one file per library, its just a matter of the amount of specific hardware configuration that they include.

Thoughts?

PaulBatchelor commented 4 years ago

it would, but it removes the ability to configure the hardware, or make custom hardware based on the daisy family.

Gotcha. That is very understandable. And I agree! You want to make this easy on yourself.

For clarification, I have no idea what is in libdaisy.h right now, or what the functionality is compared to the other header files. I'm just thinking it would be nice to reserve daisy.h for a user-space API that abstracts away the hardware considerations, and to allow people to peel away those layers for more hardware-specific tasks. That way, you could design + refactoring things below that layer without worrying about breaking projects your users are working on.

So very similar to what you want, all things that aren't platform specific include dsy_seed.h

I just want to make sure I got this right in my head. The "seed" refers to the board itself? As a User (TM), I guess it's just confusing because I've been calling it a "Daisy", not a "Seed".

I updated the verb example to use the dsy_patch_bsp.h file. (So it only needs to include dsy_patch_bsp.h, and daisysp.h)

Putting on my User hat again. What is a BSP? What is a "Patch"? This is all nomenclature in your system that I'm not going to know about. It's all very overwhelming for someone who just wants to get sound out.

In my mind, there shouldn't be anything hardware specific in this example. The hardware needs to have audio ins/outs, and 4 input knobs. That could be a eurorack module or a pedal, or something else.

Now you can create an entire new hardware platform, and set it up to use libdaisy just by making a new bsp file (which doesn't have to be kept as part of the library).

What does this process look like? Also, I still don't know what a BSP is.

Without this level of flexibility hardware development would be a lot more difficult. When we started the library I had a lot of the hardware config baked into the peripheral drivers, but even doing a backwards compatible rev2 with a few minor pin changes was a nightmare to handle.

Maybe this is something we can look at together. If the Arduino folk can seamlessy make the Arduino API work on a variety of chipsets, the Daisy should be able to do the same.

Is this all making sense? What I'm suggestion now is way different than what I was originally suggesting when I made this issue. Now I'm thinking about the design of a user-facing API for daisy that is encapsulated in "daisy.h".

I'd be curious to know your thoughts and opinions on this.

stephenhensley commented 4 years ago

Ah, sorry for all the unknown terminology.

Daisy is the family of products, encompassing the eurorack module, the small "brain board", and several other platforms we are wrapping up (guitar pedal, desktop synth, standalone hacking board, etc.)

The Daisy Seed is the small "Brain board" placed in the center of the eurorack module.

The Daisy Patch is the eurorack module. (Petal is the guitar pedal, Field is the Desktop synth, Pod is the hacking board).


A BSP is a "Board Support Package" this is what I consider hardware configuration.

So for the Patch it has 16 LEDs, 2 Buttons, 1 Toggle, 4 Knobs, 4 CVs, etc. etc.

The desktop synth has a one octave keyboard, like 24 LEDs, 8 knobs, with 4 CVs, and a few other things.

The guitar pedal has 6 knobs, and encoder, and 8 RGB leds (24 LED channels), and four single color LEDs, etc. etc.

The seed itself even falls into this, since it has a specific feature set that maybe the Daisy Plus, or something like that might not have exactly.

You get my point. . . All of these things should be able to use the same libdaisy library with as much freedom as possible (even to make a custom PCB). The in-between headers like dsy_seed.h/dsy_patch_bsp, etc. seem like a good way to do this on a users end without requiring compile flags, or library bloat (especially on embedded systems where memory is gold).

Arduino is an amazing platform (which already works with the Daisy by the way via stm32duino libraries -- I just have a few pull requests to make, and to get in touch with the developers.). However, the code size is huge for even a small blink example. This is due to the dense system that allows it to work on almost any embedded system.

The BSP files are meant as a time-saver for users. Since the embedded hardware is fixed, there's no need for the user to worry about initializing all of the controls for the buttons, knobs, and toggles on board every time they want to make something.

The main difference here is that we have actual hardware to set the Seed in. Where as most arduinos are connected to third-party shields or custom circuits, where you need to be able to say, this pin is an input and works this way. Where as we have supported hardware that we'd like users to be able to jump into all ready to go.

On top of that, once someones made something they might want to make a custom board, and then sell it. With this 'BSP' system, all they have to do is make a new .h file for their hardware, and bam.

That said, you could completely configure everything that's done in dsy_seed yourself with the documentation (that hasn't been written yet), and just include daisy.h. Similar to the way you would on a much simpler arduino device. But I think most people would like to get the hardware, and be able to simple read KNOB 1 and learn something about signal processing or writing code rather than look up how a knob works, and how and ADC works, and do all the tedious stuff needed to do something cool or fun.


I am open to other ideas here, but I think motivating product integration, and hardware development is just as important as making the library accessible, and easy to use.

Hope that clears some stuff up, I look forward to your thoughts

PaulBatchelor commented 4 years ago

Okay! This is helpful. It sounds like your idea of a user is a hardware manufacturer who wants to bootstrap their way up to Daisy. Up to this point, I've been envisioning a prototypical user as a creative DSP guy who wishes to work their way down to the Daisy. Classic hardware vs software people.

I think I'm going to need to develop a better understanding of what a BSP is. It seems to be something you've put a lot of thought into, and one of the core design aspects to daisy so far. From what I gather, it's a kind of interface you built that allows hardware manufacturers to bootstrap up to the daisy platform. Is this close to right? What do I need to look at to see the BSP we're using right now for the Patch?

andrewikenberry commented 4 years ago

@PaulBatchelor you bring up a good point about the prototypical user. The goal is to be accessible to the creative DSP guy, or even just musician interested in code, as well as being useful to a hardware manufacturer who already knows what they're doing and just wants a good affordable platform for product design. Regarding the nomenclature confusion, we should definitely document this somewhere. Thanks for bringing that up! It's very easy for us to miss things like that being so close to the project.

PaulBatchelor commented 4 years ago

@andrewikenberry it may be worth looking into how to use the github wiki. I've lightly brushed against it, but never remember how to actually use it.

@stephenhensley You do bring up a great point about the Arduino API being really bloated for doing simple things. Let's not do that.

stephenhensley commented 4 years ago

Absolutely, I think that both of our users should be able to feel comfortable using this.

In the context of our projects the "bsp" files are simply header files that have a single inlined init function and a bunch enums/defines. Here is the current Patch BSP And here's the one for the desktop synth, Field


I can think of one solution to hiding this stuff from the user a bit better, but the board specific structs would have to become the same/similar (which might be better anyway, as you said).

This solution would entail adding two -D flags: DSY_SEED and any one of DSY_PATCH, DSY_FIELD, DSY_POD, etc.

Then daisy.h could then include the proper "BSP" file to initialize the hardware. The struct would have to be defined in libdaisy for user ease.

The struct would look something like:

typedef struct
{
    dsy_sdram_handle_t sdram_handle;
    dsy_qspi_handle_t  qspi_handle;
    dsy_sai_handle_t   sai_handle;
    dsy_i2c_handle_t   i2c1_handle, i2c2_handle;
    dsy_adc_handle_t   adc_handle;
    dsy_dac_handle_t   dac_handle;
    dsy_gpio_t   led, testpoint;
    dsy_switch_t switches[SW_LAST];
    dsy_gpio_t gate_inputs[GATE_IN_LAST];
        dsy_gpio_t gate_outputs[GATE_OUT_LAST];
    float knobs[KNOB_LAST];
    float cvs[CV_LAST];
} daisy_handle;

This could also have placeholder members for LEDs and the like as well.

Something internal to a "daisy_init()" would then call the proper init for the defined board, and/or subboard under the hood, without the user seeing it.

It's a bit more complexity, but it would take the load off of the user.


And yeah, we use github wiki's fairly frequently. I'll start adding some stuff to it today.

PaulBatchelor commented 4 years ago

@stephenhensley

inline functions can have weird side effects, and they are not all that portable. I would instead build a function in libdaisy called daisy_init_patch, then have daisy_init be a macro:

#ifdef DSY_PATCH
#define daisy_init daisy_init_patch
#endif

The struct would have to be defined in libdaisy for user ease.

You could also make it an opaque struct with setters/getters to indirectly access + read struct contents. If you do it this way, it'll be easier to make different versions and refactor things without having to break user-space. I'm also not entirely convinced that you even need to see a struct? I feel like that could be a global variable hidden away somewhere, abstracted away. Somehow. This aspect is still half-baked.

stephenhensley commented 4 years ago

Good points.

There is a lot to consider here. I'm going to take some time to think it all over and maybe draft up some potential solutions.