ST Microelectronics, to their credit, provide everything you could ever need for development on their line of processors. However, when it comes to a specific aspect of the hardware, they tend to abstract it to the nth degree.
In many applications it is acceptable to use the system FLASH i.e. unused areas of it, to store data. This is where EEPROM emulation comes in. Now, ST provide example code on how to do this- delivered via their STM32Cube suite. There is just one problem. Whomever wrote that code was a very big fan of abstraction, to the extent my head hurts and I couldn't get it to work. Compared to the STM32_StdPeriph_Library they provided, this was totally like reading C++ code where the developer went full retard with OOP. So, following the KISS principle, here is how I did it.
First things first
Knowledge of what you are doing is critical here. If you get it wrong, you will see the CPU throw hard fault exceptions in the debugger. Additionally, any source code presented here was only tested on the STM32F072RBT8 processor, and will require modification for other processors in the same family.
So, we know our application will fit into the 128k FLASH with space to spare. How we arrive at that is obvious. So we look in the reference manual to see where the FLASH resides:
So, the FLASH memory begins at 0x08000000 and continues upwards for 128k. Further in the reference manual we see a really important table, that gives us exactly where the last block of FLASH resides:
So from the above, page 63 is the last page in FLASH. Now we need to consider a few basic things about FLASH.
0x0801F800 through 0x0801FFFF
Making sure we don't use it
Now that we know where we will emulate EEPROM, a few modifications to the project's linker script is in order.
In the .ld file we find text that describes where stuff is allocated. Below is my modifications to a standard linker script that is generated by Atollic Truestudio:
The actual code
Couldn't be simpler than this: (eeprom.c)
I am pleased to say that, the tide is turning, albeit very very very very slowly over at the Ministry. This comment on DISQUS in response to this article, made my day:
Update: 9 October 2017
I had a feeling so I went to check... Jose's post has been removed. In addition the pussies banned the user account I used to comment on that post. So banning by association it seems...
The Digital Audio interface on the HDM01 was straightened out this weekend. Basically the solution to ensuring it doesn't affect the CPU was to use a circular buffer and a DMA channel. Using this arrangement, the byte order in the buffer is pretty much guaranteed to be correct. This is important. The DMA also ensures that there is only an interrupt every 8 stereo audio samples i.e. when the circular buffer is about to wrap-around.
Here are some details on audio formats on the desktop PC:
The above figure shows the relationship between what is sent on the I2S bus, from the source, in this case, a normal .WAV file.
With the STM32F0xx set up to use DMA on I2S interface 1, we find the following format of data appearing in the circular buffer:
In order to translate this buffered audio data to a VU meter on a graphic display, we need to delve into the PCM. The following is what I figured out from playing around with Cool Edit / Adobe Audition-
The values are, quite obviously, signed 2's complement. To translate this to VU display, we need to implement, in the digital domain, the method used for driving an analog VU meter. This used to be done typically with an amplifier and a full-wave rectifier consisting of germanium diodes.
First order of business is to convert the negative part of the signal, into a positive one, so that we're essentially doing full-wave rectification without a smoothing capacitor:
Sample Processing Code
The above code then means we have positive integers (unsigned) for the signal we receive, and since we only sample the level every 8 audio samples, it is technically damped. However this is not the entire story. More about this in the next instalment.