Wednesday 25 April 2018

HI3518 Camera Module - Part 8 - I2C

Introduction

There are a number of HI3518 camera module designs available on sites such as Aliexpress. At least some of them, including the two modules I have got, have FM24C08 (AT24C08) EEPROM chips on them. I thought I would give a go at reading the EEPROM and also see if I could hook into the I2C lines and use them to control other devices.

HI3518 Camera Module - Part 7 - Hi3518 and HC-SR501 PIR Sensor Build

Introduction

In my previous blog post I managed to work out how to read the alarm pin found on the Hi3518 camera module I have been playing with. With this worked out, I decided to combine the Hi3518 with an HC-SR501 PIR sensor so that, with a bit of software written based on the samples in the Hi3518 SDK, I could save images from the camera whenever the PIR sensor detected motion. This worked well, so I ended up putting together a waterproof enclosure to house the camera and sensor.

Tuesday 24 April 2018

HI3518 Camera Module - Part 6 - Alarm/IR-Cut/GPIO Pins

Introduction

The HI3518 camera modules come in a range of designs. One common design has, in addition to connectors for power, serial and ethernet, two connectors for controlling an IR-cut filter, and a connnector that is shared by USB, audio and and an alarm input.

The following is an image provided on an Aliexpress listing:

https://ae01.alicdn.com/kf/HTB1aRdsKVXXXXXwXpXXq6xXFXXXW/XMEYE-WiFi-IP-Camera-Module-chip-board-Audio-input-1-4-OV9712-HI3518-1-0mp-720P.jpg

To make use of the IR cut and alarm features you need to know which pins on the SOC they are connected to.

Pins

I managed to work out the following pins:

  • IR-cut (ICR/IRC): GPIO4_6/GPIO4_7
  • Day/Night sensor input: GPIO3_0
  • Alarm in: GPIO6_1

The IR-cut control uses two pins connected to a BA6208 reversible motor driver. The day/night sensor input is designed to be connected to a light sensitive resistor. The alarm input has a pull-up resistor and blocking diode.

Controlling GPIO Pins

There are two ways to control the GPIO pins: directly or using the GPIO Sysfs Interface. In both cases you will need to refer to the HI3518 datasheet .

Direct Control

To control the pins using direct register writes you will need to configure the function of the pins using the IO configuration registers (0x200F_xxxx) and then configure the GPIO functionality.

An example of setting up the IR-cut filter pins you would use:

devmem 0x200F004C 8 0x00
devmem 0x200F0048 8 0x00
devmem 0x20180400 8 0xC0

To flip the IR-cut filter in one direction you would use:

devmem 0x20180300 32 0x40

To flip the IR-cut filter back in the other direction you would use:

devmem 0x20180300 32 0x80

GPIO Sysfs Interface

Alternatively, you can use the GPIO Sysfs interface. For the GPIO Sysfs interface to work you will need to have compiled support into the kernel.

If this is the case, you can then interact with the GPIO pins through the /sys/class/gpio directory.

The first thing you need to do is work out the name of the GPIO pin in the sysfs. The GPIO sysfs interface does not use the same names as the HI3518 datasheet for the pins. In the datasheet the pins are numbered in banks of 8, but in the sysfs they are sequentially numbered.

You will need to use the following formula to work out the pin number:

sysfs_pin_number = bank_number * 8 + pin_number

For example, the alarm pin is GPIO6_1. This means it is pin 1 of bank 6.

6 * 8 + 1 = 49

Once you know this you can interact with the pin using the standard GPIO sysfs interface. For example, to set up the alarm pin you would use:

devmem 0x200F0084 8 0x0
echo 49 > /sys/class/gpio/export
echo in > /sys/class/gpio/gpio49/direction

You will notice the first command is using a direct write to the IO configuration registers. I found this to be necessary even when using the sysfs interface.

You can then read the GPIO pin state using:

cat /sys/class/gpio/gpio49/value

HI3518 Camera Module - Part 5 - Filesystem Overlay

Introduction

The HI35xx targeted version of buildroot I've been using in this series of blog posts has support for an overlay filesystem. An init script has been added to the skeleton filesystem that uses arguments provided through the kernels command line parameters to mount the overlay. When it works, the result is that the overlay gets merged into the root filesystem at boot. However, I had some trouble getting it working.

Getting the Overlay Filesystem Working

The init script has been written to look for "overlay" and "overlayfstype" arguments in the kernel command line parameters. The typical use case is that you create a jffs2 partition on the flash and then set the "overlay" argument to point to that partition and set the "overlayfstype" argument to jffs2. I gave this a go but it did not work. After spending a bit of time investigating I realised the init script was not getting run. The idea is that the init script should get run as the first process and it should in turn run /sbin/init. However, it looked as if the kernel was running /sbin/init directly and skipping the init script. The solution was to explicitly tell the kernel to run the init script using the "init" kernel command line argument.

An example of the resulting boot arguments I needed to pass to the kernel was:

setenv bootargs mem=42M console=ttyAMA0,115200 root=/dev/mtdblock2 rootfstype=cramfs mtdparts=hi_sfc:256K(boot),1472K(uImage),5760K(rootfs),512K(overlay) overlay=/dev/mtdblock3 overlayfstype=jffs2 init=/init

Monday 23 April 2018

HI3518 Camera Module - Part 4 - NFS Root Filesystem

Introduction

In previous blog posts on the HI3518 I used an initramfs image, which combines the root filesystem (rootfs) and the Linux kernel into a single image. Instead of doing this you can also keep the root filesystem separate from the kernel and use the command line parameters passed to the kernel at boot to tell it how to mount the root filesystem. One option for where to store the root filesystem is on a network file share (NFS).

Mounting an NFS Root Filesystem

When the HI3518 module boots the first thing that gets run is U-Boot. If you have connected to the serial port on the module, you can press CTRL+C to drop into the U-Boot prompt.

From there you can boot a kernel by:

  • Loading the kernel into RAM, usually from FLASH or TFTP
  • Setting the bootargs
  • Running the bootm command

An example of booting a kernel stored on a TFTP server and mounting an NFS root filesystem would be:

tftp 0x82000000 uImage
setenv bootargs mem=40M console=ttyAMA0,115200 root=/dev/nfs rw nfsroot=192.168.2.1:/srv/nfs/hi3518-rootfs,v3,tcp ip=192.168.2.2::192.168.2.1:255.255.255.0:camera:eth0:off
bootm 0x82000000

Notes:

  • The kernel will need to have been compiled with support for an NFS root filesystem. If using buildroot run "make linux-menuconfig" and check File systems > Network File Systems > Root file system on NFS
  • You need to set the nfsroot argument to point to the location of the NFS.
  • The kernel needs to have been compiled with support for auto configuring the network. You can confirm this by checking: Networking support > Networking options > IP: kernel level autoconfiguration
  • In this example the IP address of the HI3518 module has been set to a static address of 192.168.2.2, it is also possible to use DHCP (see the kernel configuration in the previous bullet point).
  • Attention needs to the paid to the comma separated list of NFS options specified at the end of the nfsroot argument (i.e. "v3, tcp"). Getting these wrong will cause the kernel to fail to mount the root filesystem. You may need to use different options.

Sunday 17 September 2017

HI3518 Camera Module - Part 3 - Capturing Images with an HI3518/SC1035 Camera Module

Introduction

This is part 3 of a series of blog posts about a cheap HI3518 based camera module. In part 1, I showed how to build a custom image for the module. In part 2, I fixed a bug that was preventing the Ethernet from working. This part covers capturing an image.

Once I had built a custom image and got the Ethernet working I was ready to compile the HI3518 sample programs that are available in the SDK. To make this easier I set up an NFS share on my development computer and had the camera module automatically mount the share on boot up. This removed the need to include the programs in the image and so removed the need to build a new image each time I wanted to test a change to the programs, or the need to be constantly copying files around.

I was under the impression that the camera module I had contained an AR0130 image sensor. This is what the listing said, but it was also what the camera module reported in its boot logs. This however turned out not to be the case. I tried compiling the sample programs to target the AR0130 but could not get them to work. After a lot of playing around wondering what I was doing wrong I realised that the camera module I have actually contains an SC1035, which has a similar specification to the AR0130 but is not a drop in replacement. And, unfortunately the SDK did not include code for the SC1035.

The image below shows how you can distinguish between the two image sensors by looking at the layout of the contacts.



Comparison of the layout of the contacts of the AR0130 (left) and SC1035 (right)

Wednesday 2 August 2017

HI3518 Camera Module - Part 2 - Getting Ethernet Working

Introduction

This is part 2 of a series of posts involving a cheap camera module based on the HI3518 SoC, which is available on sites such as Aliexpress. In part 1 I described how to build a new Linux OS image for the module to replace the stock version of Linux that comes pre-installed on the module. The post ended with me showing how to boot the new image, but unfortunately on doing so I found that the Ethernet was not working, and this did not appear to be simply down to the need to configure it in the Linux OS.

It turned out that an issue about the Ethernet not working had already been added to the hi35xx/hi35xx-buildroot repository.


The issue appeared to describe the same problem I experienced, particularly the comment made by briaeros, which said:

"The led is barely orange when buildroot is "on" (as if there are not enough power).
On Uboot , it's brightly orange at start, then stay only green. And on the original firmware the two leds are brightly on."

The comments mention that you have to make sure that you have configured the Ethernet driver to either MII or RMII depending on how the Ethernet Phy chip has been connected to the HI3518. It is not possible to tell from looking at the circuit board how the HI3518 has been connected to the Ethernet Phy chip (in the case of the module I have, a IP101GR) so instead I booted in to the original Linux OS and checked the load3518.sh script. From this I determined that the module was using RMII. I then tried setting the CONFIG_HIETH_MII_RMII_MODE_U and CONFIG_HIETH_MII_RMII_MODE_D options in the Linux kernel to 1 (see the Solution section for how) as suggested in the issue. However this did not have any effect.

The comments in the issue also suggested looking at the boot options passed to the Linux kernel by U-Boot. However, this did not helped in getting the Ethernet working.

This post covers the steps I took to get the Ethernet working.