4ms / stm32mp1-baremetal

Baremetal framework and example projects for the STM32MP15x Cortex-A7 based MPU
Other
162 stars 28 forks source link

From examples to custom code (ADC and DDR) #23

Closed marcosartore closed 10 months ago

marcosartore commented 1 year ago

After getting Dan's help, I succeeded in compiling the provided examples starting from the simplest, I got the 'A' back from the minimal_boot program and then moved to the other examples. But I wish to know how far is the application I need to finally implement and even if it is feasible at all.

I work with the OSD32MP1-BRK board. I wish to acquire data by the embedded A/D converter (or by an external SPI driven ADC) and quickly store those data into the internal DDR memory. Later, when the acquisition is over (it would last hours at high acquisition rate and it's for this reason that I need a big memory) I would like to access the DDR in some way from a PC and download the acquired data on its hard disk.

Does the bare metal approach allow this ? If yes, how can I get started to manage DDR and ADC from my C code ?

Thanks in advance, Marco

danngreen commented 1 year ago

Glad you got it booting!

Accessing DDR RAM is not a problem, once the bootloader has loaded the application, (almost) all data and code is running in DDR RAM. So if you just made an array or some structure to hold the acquired data, it would automatically be in DDR RAM. How much memory do you need? Some of the example projects only set aside 1MB of memory for data, so you probably will want to change the linker script to set aside more memory. For example, the ctest example project has a linker.ld file that lists the memory layout like this:

MEMORY
{
    ROM (rx) : ORIGIN = 0xC2000040, LENGTH = 1M
    RAM (rwx): ORIGIN = 0xC0200000, LENGTH = 1M
    ...

There is only 1MB set aside for RAM here, from 0xC0200000 to +1MB more which is 0xC0300000. Notice that the RAM memory location is before the ROM memory location (starting at 0xC2000040). So If you want to increase it to something like 400MB, you would need to move the RAM section to the other side of the ROM section. Something like this:

MEMORY
{
    ROM (rx) : ORIGIN = 0xC2000040, LENGTH = 1M
    RAM (rwx): ORIGIN = 0xC2100040, LENGTH = 400M
    ...

Notice how the RAM section now begins where the ROM section ends (0xC2000040 + 1M = 0xC2100040). There is a total of 512MB of memory on the dev boards, so you still have some leftover.

Keep in mind that the ROM memory location is fixed, that is, the bootloader requires it to be there and this cannot be changed without modifying and re-compiling the bootloader.

There are lots of ways to layout your memory. It depends on what you want to do and how you want to go about it. Perhaps you need more memory allocated for the stack, then you would need to adjust this line instead:

    _user_stack_end = _user_stack_start + 0x10000;

The 0x10000 is the stack size for the user mode.

Also, keep in mind if you are acquiring data via DMA, then you may need to mark that region non-cacheable or else flush the cache whenever your code needs to access the data after the DMA has written it.

Regarding the external ADC via SPI, that should be easy to do. The STM32Cube HAL has SPI drivers that should meet your needs.

Good luck!