Inserting patch code into main FW code


#1

Hi All

finally I get - maybe in a week from now - some time to spend on the AXO board.
I already stated that my purpose with the board is to learn the ropes of programming the STM32 for audio applications, so I plan to leverage the written code and study it to learn how to deal with the controller and its peripherals.

Last time I managed to compile the FW as makefile project using gnu tool chain under Eclipse, adding some very stylish LED blinking of my own :grin: :joy:

Now my goal is to start working on basic filtering actions, with the easiest filter being a straight connection between IN and OUT.

This involves sending to and getting back data from the DAC/ADC, through SPI interface.
Since I wouldn't really know where to start with this, I thought I would put a simple patch together using the GUI, where a single in and out audio blocks are connected by a wire, and then try to embed its code (which is available in the file patch.cpp) somehow in the main of the FW.

However, I am not able to do so because it looks like the patch loading mechanism is different than a simple loading of functions...At least I wasn't able to figure out the proper actions to follow.

Can anyone point me in the right direction?

Alternatively, what is the simplest form of (DMA) transfer to and back from the ADC/DAC via SPI, using AXO?

Thank you in advance for any hint :smile:

Michele


#2

The "bible" for programming the processor is the RM0090 Reference manual from STMicro. It's a heavy document, over 1700 pages... PM0214 is also interesting, and the STM32F427 datasheet.
Let me first explain why splitting firmware and patch is interesting: if you 'd compile and flash both parts together, it takes far more time to flash. Erasing/writing the whole flash memory is slow, and can't keep a usb connection alive that way. Splitting firmware and patch keeps the compilation and upload time fast for the patch, while firmware is less likely to change as often.
The patch is compiled as a separate binary from the firmware, but can use exposed firmware functions and variable via hard linking though the --just-symbols linker flag. The patch main function returns a patchMeta_t struct containing the relevant callbacks.
The DAC/ADC does not use the SPI peripheral in the processor, but the SAI, it is more specialized for audio i/o. The codec register and DMA initialization is in firmware/codec_ADAU1961_SAI.c.
A DMA interrupt from SAI then wakes up the "ThreadDSP" thread in firmware/patch.c which in turn calls the patchMeta.fptr_dsp_process callback.

You can strip the firmware to bypass patch loading, but I'd suggest to have a look at the object editor in the Axoloti GUI. It accelerates code development, because it makes the edit/compile/evaluate cycle quite fast, and allows to validate algorithms-in-development with a variety of signal generators, and inspect the real-time output.


#3

Hi Johannes

Thanks, lots of good pointers in your answer.
Sure I've got the Bible as you call it, but as we stated elsewhere, there is no "learn STM" book out there, there is no path laid out for the general user. So I'm trying to see if I can build one of my own, with the limited time I have on my hands.

No questions about the usefulness of loading a test module only as opposed to uploading the whole infrastructure time and again.

I will look into your pointers:

  1. the struct of callbacks returned by main() in patch.cpp
  2. the patchMeta.fptr_dsp_process callback specifically
  3. the --just-symbols flag (which is totally obscure to me)
  4. SAI peripherial and its related initialization in firmare/codec_ADAU1961_SAI.c

I think I understand your final comment: from a perspective of developing algorithms, the AXO GUI is the real deal. You can just connect your blocks the way it visually makes sense and upload them in real time to see the effects.
This is a really powerful approach and I understand that a lot of work went into providing this infrastructure.

Before I get to that, however, I am interested in getting a first-pass understanding of the "guts" of the processing.
My key focus is not in algorithm creation right now, but in being able to understand the basics of data transfers firstly to and from the ADC/DAC, then (but I guess this will be easier) to other peripherals like I/O for "live" switching, MIDI and the like..

Thanks a lot for your help, I really appreciate your comments so...Keep them coming! :innocent:

Michele