Jellybean for i.MX6 Nitrogen6 Max

Published on July 26, 2014

Archived Notice

This article has been archived and may contain broken links, photos and out-of-date information. If you have any questions, please Contact Us.

We've just uploaded a new image of Android Jellybean for our BD-SL-i.MX6, Nitrogen6x, and for the first time, our new Nitrogen6 Max board.

This will be a lengthy post because it covers the details of a number of new features, and describes in some detail how the features of the our new Nitrogen6 Max board are made available.

For the impatient

You can download the image from here:

As usual, you'll need to register on our site and agree to the EULA because it contains Freescale content. The image is a 4GB SD card image that can be restored using zcat and dd under Linux or Alex Page's USB Image Tool under Windows.

Source access

The sources for this release are in the boundary-imx_jb4.3_1.0.0-ga branch of our Github repository (the main development branch), and the build steps are otherwise the same as in the second beta release.

We have added one additional component, the can-utils project for use in testing the CAN bus.

The highlights

The primary enhancements in this image (aside from 6 Max support) include:
  • Additional display and touch screen support.
  • Dual camera support.
  • Support for HDMI and SDI receiver inputs through the camera interfaces.
  • Updates to allow easy loading of on-board eMMC
Features that are specific to the Nitrogen6 Max board include:
  • Dual (separate) LVDS display support
  • Dual-channel LVDS display support for resolutions up to 1080P
  • RS-232/RS-485 support on UART5
  • There are some quirks related to the 4GiB of RAM on Nitrogen6 Max

Display and touch screen changes

Since the previous release of Jellybean, we've added support for touch controllers from Goodix and Ilitek, and increased the functionality of our FocalTech touch controllers.

Our 7" 1024x600, 7" 1280x800 and 10.1" 1280x800 displays now support 12-point touch instead of the original 5-point touch in the original driver.

The Ilitek touch controller is used in our new 10.1" sunlight-readable display.

Dual camera support

This feature has been a long time in coming, but for those of you using our 5 mega-pixel OV5640 MIPI camera, life is a bit easier.

Because our two primary camera modules shared an I2C bus and had the same address, previous releases required kernel re-compilation to swap between them. For this release, the Linux kernel drivers now reassign the I2C addresses during startup, allowing connection of both cameras simultaneously, and map the MIPI camera to the Back camera and the parallel camera to the Front camera in Android jargon.

Probably most importantly, this allows us to ship a single kernel image with both cameras enabled, so MIPI users don't have to re-compile or re-name files before using the camera.

Additional video inputs

Beside cameras, this release contains kernel support for a number of additional video input devices: Because these devices don't map readily to the simple Front Camera/Rear Camera model provided by Android, these devices are not currently supported by the Android HAL, and require customized Android builds in order to use them.

Recovery support

In an earlier post, we provided a customized kernel and RAM disk that turned our BD-SL-i.MX6 or Nitrogen6X boards into a very expensive SD card reader by using the g_mass_storage gadget.

This release extends that to support the Nitrogen6 Max board, and also updates the boot script to invoke this automatically if the Volume Down key on our Android button board is pressed during boot.

If you don't have an Android button board, you can short pins 7 and 8 of J14 with a paper clip (these pins are Volume down and Ground respectively).

Note that this feature is not specific to eMMC or to the Nitrogen6 Max board. It is also very handy for loading SATA drives or even SD cards.

The /init script in the RAM disk walks through and exposes each block device found on the system, making it available over the USB OTG port

The two files involved (uImage-recovery and uramdisk-recovery.img) can also be copied to a TFTP server and loaded by U-Boot using the usbrecover command as described in the release notes for U-Boot 2014.04.

CAN bus utilities

As mentioned earlier, we've included the can-utils package in this release. While we don't have a lot of experience with CAN, we have tested this by connecting multiple of our boards together, and using cansend and candump as follows: # on both boards: root@nitrogen6x:/ # ip link set can0 up type can bitrate 125000 root@nitrogen6x:/ # candump can0 & root@nitrogen6x:/ # cansend can0 5A1#11.22.33.44.55.66.77.88 can0 5A1 [8] 11 22 33 44 55 66 77 88

RS-232/RS-485

The Nitrogen6 Max board has a third serial port, which is software-selectable to support either RS-232 or RS-485 signalling. It is connected to UART5 on the processor, and exposed as /dev/ttymxc4 under Linux.

By default, the port is configured for RS-232. In order to configure it for RS-485, you can write to an entry in sysfs: root@nitrogen6x:/ # echo 1 > /sys/devices/platform/imx-uart.4/rs485_en If a board will be at the end of an RS-485 chain, you may also need to use SW5 to enable a termination resistor. There are silk screen labels showing the positions, and RS-485 means terminated as shown in the photo.

Dual independent LVDS

One of the primary features of the Nitrogen6 Max board is the addition of a second LVDS channel, that can be used to drive either two separate displays or a single, high-resolution display. Neither one of these is truly plug and play, and some effort is required to make use of them in this Android release.

To begin with, only a single panel (LVDS0 on the bottom side of the Nitrogen6 Max) is supported in U-Boot, and this must be defined as the primary display.

Since our boards only have a single I2C connector (J7) for use in connecting a touch screen, we can only detect one touch controller. Even if we did detect multiple displays, we have no way of knowing which you'd want to be the primary display. (You may not be aware of this, but the Android support for multiple displays uses the primary (/dev/graphics/fb0) display to define the screen resolution for applications and simply mirrors and scales the content to the secondary display)

The configuration process is simple though. You enable the second display by inserting multiple video= clauses with the dev=ldb flag to the bootargs variable in U-Boot.

For example, this fragment will configure our 1280x800 panel as the primary and a 1024x600 panel as the secondary display: video=mxcfb0:dev=ldb,1280x800MR@60,if=RGB666,bpp=32 video=mxcfb1:dev=ldb,1024x600MR@60,if=RGB666,bpp=32 You will need a custom boot script for this.

The next issue related to dual independent LVDS displays is the backlight. The Android userspace only has support for a single brightness control, and we have this connected to PWM4 to control the brightness of the primary panel (i.e. same as BD-SL-i.MX6 and Nitrogen6x).

The second LVDS port has its' backlight control on PWM3, and the only way you can control it is through sysfs:

full brightness root@nitrogen6x:/ # echo 255 > /sys/class/backlight/pwm-backlight.2/brightness minimum brightness root@nitrogen6x:/ # echo 0 > /sys/class/backlight/pwm-backlight.2/brightness (N.B. PWM4 maps to pwm-backlight.3 and PWM3 to pwm-backlight.2 because hardware folks start numbering at 1 for some unknown reason)

Dual-channel (bonded) LVDS

Dual-channel LVDS is much simpler, since it doesn't involve multiple backlights, but it does have some quirks because:
  • U-Boot doesn't yet support it, and
  • We don't have an off-the-shelf panel to auto-configure
We tested against a 22-inch 1080p display and added support for it to our boot script. You can configure for this resolution by setting the panel variable in U-Boot in the same manner as used for our 1280x800 displays:

U-Boot > setenv panel 1080P U-Boot > saveenv && reset We are looking for an HD panel to offer as a companion product. Please let us know what type/size of panel you'd like to see.

4 GiB quirks

Now for the fine print.

There appear to be some bugs in the GPU acceleration when operating with more than 2GiB of RAM. As discussed in this post on i.MX Community site, we saw some very odd behavior with multiple displays when porting our Nitrogen6 Max kernel to Android.

The problems went away if we either set the max memory to 2GiB using the mem=2G kernel command-line argument or if we disabled hardware overlays in the Developer Settings panel.

When enabled, the Hardware Overlays feature allows applications to write directly to GPU surfaces, which minimizes the number of copies needed when updating graphic elements. This is speculation, but we believe that some piece of the graphics stack is seeing physical addresses > 2GiB as being invalid in a similar way these gstreamer components. The gstreamer components were using virtual addresses, but we believe the issue to be related.

Unfortunately, the setting in Developer Options is not persistent, and the problem components are closed-source, so we'll have to defer to Freescale for a fix.

Fortunately, this is relatively easy to work around, and in this image, we've renamed the file /system/lib/hw/hwcomposer_viv.imx6.so to /system/lib/hw/hwcomposer_viv.imx6.so.disabled, which prevents the use of hardware overlays and doesn't seem to have a dramatic impact on performance.

If you're using this image on a BD-SL-i.MX6 or Nitrogen6x, you'll want to put this file back: root@nitrogen6x:/ # mount -o remount,rw /system root@nitrogen6x:/ # mv /system/lib/hw/hwcomposer_viv.imx6.so.disabled /system/lib/hw/hwcomposer_viv.imx6.so root@nitrogen6x:/ # sync && reboot