Design and Implementation

Hardware

To best describe what's in the hardware, here is the block diagram

The main processor being used is the NXP LPC5528 microcontroller. It is an ARM Cortex-M33F based microcontroller manufactured at the latest (as of 2020) 40nm eNVM process. It has a hardware single-precision floating-point unit, which would allow running floating-point DSP algorithms much faster. It has 256KB of internal RAM and 512KB of internal flash. The DAC being used is the Cirrus Logic CS43131 DAC. It is a high-performance audio DAC with an internal charge pump and headphone driver. Integrated solutions allow us to make the device smaller. The screen is the GoodDisplay GDEH0213B72, which is a 2.13” E-ink display with a resolution of 250x122. Additionally, ADI LTC3554 and ADI ADP150 are being used for voltage regulating and charge control, regulating the power. For precise estimation of the remaining battery capacity, a fuel gauge (LTC2942-1) is also used onboard, providing tracking for the total energy used. This can be also useful for measuring power consumption.

(R0.2 hardware running software MP3 decoder and showing power consumption)

Software

The software is built on top of the FreeRTOS. The system software consists of 3 concurrent threads:

  • one for the user interface
  • one for fetching data from the SD card
  • one for decoding the audio.

The reason for using a multithreading software than a single thread one is the different nature of these three tasks. The data fetching task is a typical I/O bound task, meaning the speed is mostly limited by the speed of the I/O device (SD card in this case). The decoding task is a typical CPU bound task, meaning the speed is mostly limited by the processing speed. The user interface task is an I/O bound task as well, as it spends a lot of time just waiting for user input or screen update. By using a multithreaded approach, these tasks can be easily interleaved and so the CPU can spend less time waiting and more time computing. It could either reduce the CPU load or make the CPU capable of decoding more demanding audio formats under the same load. The rule of thumb is that, if it takes fewer cycles to do something, then the CPU can lower the clock speed or spend more time sleeping, lowering the power consumption. 

Besides FreeRTOS, several other open-source frameworks are used:

  • The FatFs by ELM-ChaN is used for handling the file system on the SD card. 
  • The minimp3 by lieff is used for decoding the mp3 audio file.
  • The TJpgDec by ELM-ChaN is used to decode the JPG cover art embedded in the audio file.
  • The id3v2lib by larsbs is used to read metadata from MP3 files. The id3v2lib is modified to allow buffer less operation due to the limited RAM amount.

To display the cover art, a block-based bilinear image scaling algorithm is implemented. The screen, despite being capable of displaying up to 16 level grayscale, is being advertised as a monochrome screen. Only monochrome (black and white only, without greyscale) example driver is provided by the screen vendor. The greyscale driver for the E-ink driver is then developed to allow displaying grayscale images. Mixing grayscale and monochrome content is also allowed and implemented.

Personally I listen to lot of Chinese and Japanese songs, so support for displaying these characters are important to me. To summarize my requirements:

  • At least 2 font size for reasonable UI design
  • Capable of display hiragana, katakana and most commonly used kanji glyphs
  • Supports UTF8 encoded unicode. GBK and JIS supports are nice to have but not necessary
  • Antialiasing is not necessary
  • Fit in 512KB internal flash

Which may sounds quite reasonable, but it's not that easy, especially the last requirement of fit into 512KB. If without compression, 16x16px glyph takes 16*16/8=32 bytes each, 12x12px glyph takes 12*12/8=18 bytes each. So overall each glyph takes 50 bytes. Because it needs to support unicode, only considering...

Read more »