We have built MicroPython for STM32F429DISC previously. We'll use it as a guide to port MicroPython to MPFS Discovery Kit, featuring a PolarFire SoC. It is straightforward to compile for the minimal configuration. We aim to achieve the same functionalities as STM32F429DISC. In the hardware-wise comparison, the shortage of non-volatile memory can be overcome by using a micro-SD card. PolarFire RISC V supports both single and double precision floating point; STM32F429 supports only single precision.
The STM32F429DISC build includes the following modules.
>>> help('modules')
__main__ builtins json select
_asyncio cmath machine socket
_onewire collections math stm
array deflate micropython struct
asyncio/__init__ dht network sys
asyncio/core errno onewire time
asyncio/event framebuf os uasyncio
asyncio/funcs gc platform uctypes
asyncio/lock hashlib pyb vfs
asyncio/stream heapq random
binascii io re
Plus any modules on the filesystem
The MicroPython does not seem have a good way to manage configurations. The #define parameters that affect the build can come from a number of places, many include files and many makefiles. And the dependencies are not always clear.
First MICROPY_CONFIG_ROM_LEVEL can range from minimum, core, basic, extra to full, which enables more feature. We can change it from minimum to extra. This enables the majority of features, including compiler, stack check, helper REPL, EMACS keys in REPL, scheduler, micropython module, etc.
Then we add the additional options enabled by STM32. We include FROZEN_MANIFEST, which requies in the micropython-lib submodule. We enable VFS, which turns out have some tricky dependencies. We have to define MICROPY_VFS_FAT in the makefile in order to bring in the oofatfs. This compiles to about 300K (text+data). STM32 uses a portion (112K out of 2M) of its Flash to make a file system that stores initialization files like "boot.py" and "main.py". We will make use of the micro SD card.
Next, we want to enable floating number. We run it on one of the application cores that support floating number. We set MICROPY_FLOAT_IMPL to double in the makefile. This causes additional variable to be set. This compiles to 360K and the math module is available.
We enable the machine module by defining MICRO_PY_MACHINE. The machine module supports peripherals such as uart, spi, i2c, timer etc; board specific code has to be write to make them work. Additional python modules can be added to manifest.py. We also include the network module. Another useful module in STM32 is stm, which provides access to peripheral registers and we implement a similar module. The compiles to 430K.
At this point, we have the following modules,
>>> help('modules')
__main__ builtins json select
_asyncio cmath machine socket
array collections math struct
asyncio/__init__ deflate micropython sys
asyncio/core errno mpfs time
asyncio/event framebuf network uasyncio
asyncio/funcs gc os uctypes
asyncio/lock hashlib platform vfs
asyncio/stream heapq random
binascii io re
Now we have to write some actual code. As a warm-up, we first add the LED control. Extra classes can be added by defining MACHINE_EXTRA_GLOBALS in the port modmachine.c, which is inserted into extmod/modmachine.c. We can borrow code from STM32 and only change the GPIO code. We can control the LED from Python.
Before we add the drivers for the peripherals, GPIO, SPI, I2C, UART, Timers, we want to look into the Micropython compilation and assembly code for RISC-V by defining EMIT_RV32 and EMIT_INLINE_RV32. The decorator @micropython.asm_rv32 seems to work, but @micropython.native does not. It crashes when running the function with that decorator. Interestingly, it does not work on STM32 either. We'll have to look into it.






