Customizing Clementine Core
If you’ve forked Clementine Core and compiled the project (Project > Compile), you’ll notice there is a top-level sheet called Clementine Core, plus a Memory, MicroSD, Power, and System sub-sheets.
Clementine Core takes full advantage of CircuitMaker’s advanced multi-sheet design capabilities; ports are used on the System sheet to bring out project-specific connectivity to the top sheet, allowing the designer to focus her attention on the details necessary to complete the project, without having to deal with the visual clutter of sorting through pages of schematics. Most users of Clementine Core will only need to modify the System sheet; no other changes will usually be necessary. I prefer to put project-specific circuitry on a separate sheet, then connect everything together in the top-level Clementine Core sheet.
So, what’s the minimum amount of stuff you have to add to Clementine Core to actually build something useful? Surprisingly, not much!
Clementine Core uses the built-in PMU functionality of the i.MX233, so you’ll only need to provide a 5V power source, connected to the “5V” net. While the i.MX233 has a built-in DC/DC converter, I’ve found it to be extremely sensitive to input voltage levels — many cell phone chargers I’ve tried produce strange behavior from i.MX233-based designs. To make the design more robust, I’ve disabled the DC/DC converter, relying on the built-in linear regulator. This decreases the efficiency of the board, but it allows a wider input voltage margin and simplifies the PCB design.
For basic operation, no other regulators are needed. Clementine Core will provide a 1V2_SYS, a 2V5_SYS, and a 3V3_SYS rail, as well as some low-power, low-noise analog supplies. Feel free to draw up to 100 mA from the 3V3_SYS rail for your own sensors/peripherals. However, if you want to drive a ton of LEDs, a TFT display, or any other high-current 3.3V devices, plan on adding your own 3.3V regulator to an isolated 3.3V net (do not wire it in parallel with the 3V3_SYS supply!).
The i.MX233 has built-in LiPo charging capabilities as well as soft power switching. You’ll have to modify the design slightly to activate this functionality — consult the Olimex OLinuXino i.MX233 schematics for an example. None of these customizations will require any software modification.
Note that all user-accessible I/O pins are wired for 3.3V operation. These pins are not 5V tolerant. First off, you should always break out the TTL serial debug connection to either 0.1” pin headers or the FTDI 3.5mm jack. This will allow you to interact with UBoot, see the Linux kernel messages, and interact with the console shell. If you don’t have room for connectors, try to at least lay down some test pads.
Almost all i.MX233-based designs end up with a USB connection used for WiFi or Ethernet networking, Bluetooth connectivity, or human input devices like keyboards or mice. Depending on your application, you may need additional USB ports, which can be easily integrated on-board with a USB hub IC, or off-board with an off-the-shelf USB hub.
Both the debug console and USB port are already broken out on the main sheet, ready for use. Other low-speed peripherals such as I2C, UART and SPI are available on several different pin multiplexings; consult the i.MX233 reference manual for a full list of available pin muxing options for these peripherals. Note that you’ll need to modify the Linux DTS file for the board if you want to activate any of these peripherals (the DTS configuration file is responsible for loading the peripheral’s driver, as well as configuring the driver and muxing the pins).
Clementine Core can directly drive a parallel TFT LCD with up to 18-bit color depth. Compared to DSI TFTs and displays with built-in controllers, parallel TFTs tend to be extremely low-cost (East Rising’s 480 x 272 resolution 4.3 inch display is only about $10 in single quantities, and their 800x480 resolution 5 inch display is only about $14). To get the display working in software, you’ll need to modify the DTS file for the board to mux the appropriate pins and configure/activate the LCD controller. See the i.MX233 EVM DTS file as a reference.
Pour a ground plane on the top and bottom layers of the board. Since CircuitMaker doesn’t have Altium Designer’s transparent layers functionality yet, I pour a hatched ground plane so I can see what’s going on under the pour. While the DDR routing is a bit out-of-spec, the design has been stress-tested and functions properly. Avoid altering the DDR or power distribution layouts unless you’re comfortable with high-speed design. Feel free to move the MicroSD connector (or swap the footprint) and re-route — but avoid extremely long traces, and keep a continuous ground plane under the traces at all times.
There are lots of different ways of getting Linux onto Clementine Core, and the method you choose largely depends on whether you need to customize the BSP at all, and how polished you want things to be.
If you want to quickly get started, Olimex has a Wiki page with pre-built MicroSD card image download links, and lots of information about getting Linux running. All of this is directly applicable to the Clementine Core (which is more or less an imx233-olinuxino-micro). Also, many posts on their forums explain things like kernel patching, bugfixes, and SD card image woes.
You can load a distro on an MicroSD card and use it just like a normal computer (albeit one with very little RAM and a slow, single-core processor), but if you’re designing a custom Linux board, you’ll probably have lots of goodies on-board that will interact with your system using I2C, SPI, or the LCD controller. To get these modules activated and configured, you’ll need to be able to compile a custom kernel (with a custom DTS configuration file). For most people new to embedded Linux, it’s not the actual code that’s overwhelming, but rather, setting up the environment. That’s totally outside the scope of this post, but I would recommend looking at either Yocto or Buildroot.
Both projects are used to build images you can boot from. Essentially, the build system will download and compile a toolchain, and then use that toolchain to cross-compile U-Boot, a Linux kernel, plus all the core software necessary to boot into Linux. These systems will also build other user applications and libraries you may want installed (like Firefox, or QT-Embedded, or XTerm). They will create the configuration files as well as the directory structure, initialization scripts, and everything else. Finally, they will create a virtual SD card image you can write to your MicroSD card.
Buildroot is a Makefile / menuconfig-based build system that’s quite simple to learn and understand. I think it’s slightly easier to iteratively develop code “in place” without futzing around with patches and custom build scripts than Yocto, but it’s not a very large project, and I think it’s mostly used by hobbyists and small firms.
However, if you want to build images the way the pros do, you’ll want to use Yocto. Yocto is a massive git/repo-based build system that uses inheritable Python configuration scripts parsed by the bitbake utility. It’s beautiful and ugly and wonderful and frustrating all at the same time. I wouldn’t recommend doing in-place iterative development with Yocto (in other words, building an image, then trying to edit the source code in the build system and rebuilding the image); it’s just too painful.
Instead, use Yocto to build a base image, then build a toolchain, install the toolchain, and copy the Linux source code into your own private area. Break things, experiment, make changes, and when you get your DTS file working and any other source code changes made, create a diff between your code and Yocto directory you copied it from, and wrap that patch into a recipe. Once you’ve done that, you’ll never have to touch the source code again, and you can focus on your userspace applications.
Freescale has a set of Yocto Training posts that will walk you through this process. Christian Jann’s blog provides useful instructions that are i.MX233-specific. Keep in mind that all of these posts were written several years ago; some things might be out of date. Always consult the latest documentation, and “fill in the blanks” with the Freescale-specific and i.MX233-specific stuff.
If you plan on building up a board based around Clementine Core, I would highly recommend you buy a few Olimex i.MX233 boards that you can use as reference platforms. Olimex is a great, open-source-centric company that spends a lot of effort on documenting things, so even if the boards weren’t extremely valuable for debugging purposes (which they are), I’d encourage you to support them anyway.