whiskeywhiskey | Posted: 31 Oct 2019, 06:58 PM |
---|---|
Member Posts: 6 Joined: 31-October 19 |
I read the writeup on the FLASH synth, and this resonated with me a lot: QUOTE
I spent some time a couple months ago writing an fm synth engine in go, and my plan was to run it on an stm32f469 discovery board, with a nice UI on its high-res LCD. There's a project called emgo which transpiles go into C for the stm. It's a little goofy, but it works. It deals with the HAL craziness in a fairly interesting way, there's basically drivers written in go that are selectively compiled based on build flags for the chip you're using, and gives a uniform go api which does the right thing in terms of register configuration etc. Unfortunately, I got stuck because the emgo project seems to focus more on the smaller chips without fancy peripherals like DSI and LTDC, so I had to dive into emgo and write drivers for the peripherals I needed to get the display going. I did enough of the work to expect it to be functional, but never managed to get anything to display, and I had nobody to discuss with to figure out where to focus my troubleshooting, so I got discouraged and cycled off the project. I still really like the idea of working with STMs using go, it's my language of choice by a wide margin, and aside from a few pretty major limitations (like lack of dynamic memory), emgo is a neat way to do it. If this sounds intriguing to anyone, I'd love to discuss it; I'll have to dig back into my past work in order to explain enough to get someone up to speed, but that kind of sounding board is what I need to make it happen. ------------- |
[top] | |
DAVID | Posted: 31 Oct 2019, 11:17 PM |
I love mcus Member Posts: 237 Joined: 10-September 17 |
I have never heard about the Go programming language before, So I wonder how did you implement sound in there. Did you use some kind of buffer that will get loaded in to a sound card? Maybe Timers? I´m interested ------------- |
[top] | |
DAVID | Posted: 31 Oct 2019, 11:24 PM |
I love mcus Member Posts: 237 Joined: 10-September 17 |
Also one thing that i hate about the STM mcus is that registers for all boards are not consistent like in the AVR architecture; It took me a whole month to figure out how to use the timers registers on the STM32F103CB. And I kind of dislike using the HAL libraries since it´s really hard to set them up by hand, so then you are stuck with IDEs ------------- |
[top] | |
whiskeywhiskey | Posted: 1 Nov 2019, 03:53 AM |
Member Posts: 6 Joined: 31-October 19 |
QUOTE (DAVID)
I have never heard about the Go programming language before, So I wonder how did you implement sound in there. Did you use some kind of buffer that will get loaded in to a sound card? Maybe Timers? I´m interested Go is a really great language, I've been using it professionally for over seven years now, and I try to avoid using any other language anymore. I wrote the fm engine first on my laptop, and it uses libportaudio as an abstraction for CoreAudio in osx. Portaudio will call a callback when it's ready for more data; I render all my audio in 128-sample buffers and throw those buffers into a channel until the channel blocks. When portaudio calls the callback, it reads a bufferful from the channel and returns it to portaudio. Works quite well on the laptop, I'm not sure what challenges I'll have working with the audio peripheral on the STM, but I think it should work fine. Here's the code for the engine, it's not anything like complete: https://github.com/ianmcmahon/fmsynth/blob/master/audio/engine.go It's designed around the concept of components that know how to render themselves a buffer at a time. The engine has an input, connected to that input is a Mixer component, it's got inputs that are connected to Voice components. The Voices have an Algorithm, the Algorithm has operators and envelopes and a mixer, and each of those components carry their setting and state data around with them. There's a mechanism for mapping a CC directly to a component, so midi messages get routed around properly. ------------- |
[top] | |
whiskeywhiskey | Posted: 1 Nov 2019, 03:56 AM |
Member Posts: 6 Joined: 31-October 19 |
I'm digging back into where I got stuck with the stm code; I believe I was having issues initializing the otm8009a lcd driver; it's done by sending a bunch of magic words over the DSI host's secondary configuration channel, and that's done by a bunch of writes to a register that pushes into an internal FIFO, and I recall having issues with code that is supposed to check the FIFO status flags and spin until it reports empty, and it would hang there indefinitely. https://github.com/ianmcmahon/emgo/blob/fc23788f151771e43b147b2a339c9e20efa5602e/egpath/src/stm32/hal/dsi/driver.go#L514 ------------- |
[top] | |
whiskeywhiskey | Posted: 1 Nov 2019, 03:59 AM |
Member Posts: 6 Joined: 31-October 19 |
I got hung up on the LCD because I really wanted a UI for the thing, because I was having a hard time finding sensible ranges for the various operator and envelope parameters, and I wanted some visualization of parameters while tweaking. My grand vision was to make a hardware groovebox/synth similar to the elektron digitone, but with my own spin on the UI and sequencer. ------------- |
[top] | |
DAVID | Posted: 1 Nov 2019, 05:02 AM |
I love mcus Member Posts: 237 Joined: 10-September 17 |
QUOTE (whiskeywhiskey)
I don´t think I can help with that, I haven´t played with TFTs before; but with the audio i think it would be somewhat "easy" to do, of all synth that I have made so far, none of them were made using a buffer, so I´ll just do some proof of concept code on the atmega328 and then try to port that into the HAL library and using something like I2S(I think it would be really hard to try using that golang converter for doing this).I got hung up on the LCD because I really wanted a UI for the thing ------------- |
[top] | |
mit | Posted: 1 Nov 2019, 02:04 PM |
yeah whatever Admin Posts: 562 Joined: 4-May 16 |
Hey. This is interesting - I have never used Go but just yesterday someone emailed me about using Go on microcontrollers with a project called TinyGo. It's funny how bad the stm32 abstraction libraries are, I only really realized when I used the raspberry pi's WiringPi library. The Pi is a much more complicated device, but the GPIO pins can be configured and used in a single line of code. Not sure if I'll play around with emgo but I'll take a look into it, even if just to see how they tackle the abstraction. ------------- |
[top] | |
whiskeywhiskey | Posted: 1 Nov 2019, 04:56 PM |
Member Posts: 6 Joined: 31-October 19 |
Here's a sample of what emgo code looks like for a blinky demo. I am about to jump on a meeting, but when I'm done I'll dig through the library and piece together how the abstraction works and post relevant bits
------------- |
[top] | |
whiskeywhiskey | Posted: 2 Nov 2019, 01:23 AM |
Member Posts: 6 Joined: 31-October 19 |
emgo uses build tags to conditionally compile implementation code depending on the chip. Here's where the instances of a gpio port are declared for f469:
Here is the generic code for a Port
EnableClock is implemented in here, this implementation is common to everything but f1:
Here's implementation code specific to the f4 chips:
There's a code generator called xgen in emgo that uses the chip definition headers from st's hal library and generates go code for each chip describing all the registers and pins. The generated constants for the f469 are here: https://github.com/ianmcmahon/emgo/tree/dsi-driver/egpath/src/stm32/o/f469xx/gpio and here are generated structs that wrap the registers for convenience: https://github.com/ianmcmahon/emgo/blob/dsi-driver/egpath/src/stm32/o/f469xx/gpio/xgen_gpio.go Emgo then includes a compiler that transpiles the go into C, and the resulting C is built using the standard arm-gcc toolchain ------------- |
[top] | |
mit | Posted: 6 Nov 2019, 12:42 PM |
yeah whatever Admin Posts: 562 Joined: 4-May 16 |
Thanks for sharing. It looks a lot like they've just re-implemented or ported the existing peripheral libraries. Which is fine. I just wonder why the "enable GPIO" command can't include compile-time or run-time code that detects whether the clock source to that block is already enabled. ------------- |
[top] | |
Sign in to post a reply.