Mikromedia-M4 With Chibios

For a while I’ve been looking for a development board that meets the following requirements:

  • Small board with LCD + touchscreen
  • STM32, preferably F4
  • Documentation

The latter point is quite important as there is a proliferation of no-name chinese STM32 LCD boards on ebay, but they tend to be poorly documented, with some sellers not even giving a datasheet or schematic before purchase!

Ultimately I stumbled upon the mikromedia for stm32f4 that met my needs. Most attractively it was a single board module, unlike the majority of boards on ebay, which are two stacked PCBs.

The nice thing about this module is that it comes well packaged (and you’d expect that given the cost..), with printed documentation and schematics that is almost big enough to read without straining your eyes.

The time that I ordered this board happened to coincide with a 15$ discount, which made ordering direct from mikroe more economical than from farnell, even including duty + import taxes, and it meant I could get some of the prototyping shields which aren’t available on farnell. It took about 3-4 days to make its way from Belgrade to Cornwall.




In my opinion there is one big omission with this board, and its in the way the LCD is interfaced. The high density STM32 chips have a peripheral called FSMC (flexible static memory controller), which memory maps reads/writes to the display, working in either 8 or 16 bit modes. Unfortunately the designers of the board have opted to use standard GPIO pins for the parallel interface, which requires extra commands and has no fine grain control over timing like the FSMC peripheral has. It is a shame, but not the end of the world. Presumably they did this so that they can have code that is compatible with the other mikromedia kits, which use different microcontrollers.


The board has a microSD slot wired up via SPI. SDC would’ve been nice, but SPI works.


The board is clearly designed and sold to be used with Mikroe’s comercial (and non-free) compiler and GUI libraries, but I had other plans for it – to use the freely available GCC compiler with a RTOS (ChibiOS) and a an embedded GUI project that I was quite involved with in the early days, writing and adapting low level drivers for several displays – ugfx.

Getting ChibiOS up and running on this was fairly painless, given that it has excellent support for the STM32 family. All it takes is to produce a board definition for the module, create a makefile based project by copying an existing STM32F4 project as a base, and setting the appropriate board to use as oscillator settings (took me a while to realise that the mikromedia does not have a high speed external crystal!). An empty git repo that makes getting started with this combo is provided at the end.

Once the project was set up, it is built by running ‘make’, and I programmed the chip using an ST-LinkV2 and OpenOCD 0.7:

[code] openocd -f interface/stlink-v2.cfg -f \
target/stm32f4x_stlink.cfg -c "init" -c "reset init" -c \
"flash write_image erase build/ch.bin 0x08000000" -c \
"reset" -c "shutdown"[/code]

Display Driver

This is the fun part. Recent version of this board have an ILI9341, according to a leaflet in the box. I’ve been referring to this datasheet for the module, and the datasheet for ILI9341.

The LCD is wired up in 8 bit mode, with IM3:0 = 0011, which according to the datasheet means it is an ‘8080 MCU 18-bit bus interface’:

but this can’t be correct as the LCD is only wired up with 8 bit data! So either the schematic is wrong or they’ve bodged it. Given that the data pins go to DB10:17, I think it must be in ‘8080 MCU 8-bit bus interface II’ mode, which means that IM3:0 should = 1001.

To be continued!

Chibios C++ Notifications templates

I’ve found myself using memory pools + mailboxes a lot to pass data between different processes.

For example, I read sensors, pass the data to a process which filters that, and then pass the result to another process which saves it.

Originally I had one memory pool / mailbox per server process, but I found that limiting for several reasons – I didn’t want the main server thread to have to wait if a client was being slow processing the data, and I wanted the client to have control over how much data it needed buffering. So instead I swapped it around, and created a few helper classes for automating the process.

Firstly I define a message:

class SensorData : public NotifierMsg<SensorData> {
    int16_t _acc[3], _gyro[3], _mag[3];
    float acc[3], gyro[3], mag[3];
    systime_t time;
    uint32_t status;
    bool_t magData(void);

Then the server:

class SensorHandler : public EnhancedThread<256>, public Notifier<SensorData> {
    Sensor *acc, *mag, *gyro;
    virtual msg_t Main(void);
    SensorHandler(Sensor*, Sensor*, Sensor*);

And then start the process:

SensorHandler sensors( acc, gyro, mag);

The client thread registers a listener on the server, specifying a cache of 2:

Listener<SensorData, 2> sensor_listener(&sensors);

Then in my server thread I populate the message and ‘broadcast’ it:

d.status = (gyro->getData(d._gyro, d.gyro) << SENS_GYR_DATA) |
(acc->getData(d._acc, d.acc) << SENS_ACC_DATA) |
(mag->getData(d._mag, d.mag) << SENS_MAG_DATA);

/* broadcast data */

Meanwhile I create a client Listener, and handle the data:

Listener<SensorData, 2> sensor_listener(&sensors);
int i=0;

i = 99;
while(true) {
    SensorData *data = sensor_listener.getData();
    if(++i == 100) {
        cPrintf("[%d %d %d] ", data->_acc[0], data->_acc[1], data->_acc[2]);
        cPrintf("[%d %d %d]\r\n", data->_gyro[0], data->_gyro[1], data->_gyro[2]);
        i = 0;

The full code can be found on GitHub.