This is a simple Linux device driver for the Panasonic amg88xx-series thermal cameras. This project is still in a very early stage!
The amg88xx sensors use i2c-interface and a single interrupt line for communication. This driver exposes the i2c registers to userspace via sysfs. Some extra features are also exposed, please take a look at the sysfs interface chapter for more info.
- add support for the device interrupt
- sysfs entry for the interrupt
- interrupt handling in kernel
- notifying userspace through the sysfs
- complete the sysfs interface
- finish the devicetree overlay
- add support for an "easier" interface (/class/iio maybe?)
- write an example userspace application
First clone this reposity:
git clone https://github.com/vuorioi/amg88xx-kernel-driver.git
Then use the supplied Makefile to build the driver (make sure that you have the proper
kernel headers installed):
cd amg88xx-kernel-driver && make
In order for this driver to function properly the devicetree needs to have an entry for the amg88xx sensor. This repo provides a sample devicetree overlay for Raspberry.
Compile the devicetree overlay with dtc:
dtc -W no-unit_address_vs_reg -O dtb -I dts -o amg88xx.dtbo amg88xx-overlay.dts
And load it with dtoverlay:
sudo dtoverlay amg88xx.dtbo
Finally load the module:
sudo insmod amg88xx.ko
The sysfs entries are found in the /sys/bus/i2c/device/<device_name>/ directory. You can find
the right device_name by running the following command:
cd /sys/bus/i2c/devices/ && ls * | grep amg88xx */name
Before the device can be used it must be set to normal or one of the stand-by modes:
sudo sh -c "echo <mode> > device_mode"
mode can be any on of the following:
normalNormal operation, refresh rate chosen by the FPSC registersleepSleep mode, all register read as 0x0standby_60Stand-by mode with wake-up every 60 s to refresh the sensor and the irq linestandby_10Stand-by mode with wake-up every 10 s to refresh the sensor and the irq line
The amg88xx-overlay.dts contains an example devicetree overlay that can be used with Raspberry Pi. The devicetree needs the following nodes:
- node for the device pinctrl
- check the documentation for the gpio controller in your system for implementation
- this node should specify a single gpio as an input and use a pull up (if possible)
- node for the i2c device
reghas to be 0x68 or 0x69 (depending on the hw configuration)compatible = "panasonic,amg88xx"interrupt-gpioto tie gpio line for reading the interrupt state from the hwinterruptsshould be configured on the same gpio pin as the interrupt-gpiointerrupt-parentshould be set to point the interrupt controller of this node (propably a gpio controller node)- a link to the device pinctrl should be provided via
pinctrl-0andpinctrl-names
The sysfs interface is not fully implemented! This driver exposes the following sysfs files:
device_modei2c register: PCTL- reading this file returns the device mode:
normalNormal operation, refresh rate chosen by the FPSC registersleepSleep mode, all register read as 0x0standby_60Stand-by mode with wake-up every 60 s to refresh sensor and irq linestandby_10Stand-by mode with wake-up every 10 s to refresh sensor and irq line
- writing a correct device mode to this file sets the device mode
- reading this file returns the device mode:
reseti2c register: RST- following values can be writin to this file:
fulldevice is reseted to the initial statepartialonly the status register, interrupt flag and interrupt map is reseted
- following values can be writin to this file:
frameratei2c register: FPSC- reading this file returns the current framerate or 0 if the device is in sleep mode
- writing a valid value (
1or10) to this file sets the framerate
interrupt_statei2c register: INTC bit 0- reading this file returns the value of interrupt enabled bit:
enabledinterrupt line is in usedisabledinterrupt line is not in use
- writing this file changes the interrupt enabled bit
- reading this file returns the value of interrupt enabled bit:
interrupt_modei2c register: INTC bit 1- reading this file returns the value interrupt mode bit:
absolutedifferentialTODO what is the difference between the two
- writing this file changes the interrupt mode bit
- reading this file returns the value interrupt mode bit:
interrupt_levelsi2c registers: INTHL to IHYSH- reading this file returns the interrupt upper and lower limits and the
hysteresis in the following format:
upper,lower,hysteresis. All values are signed integers - writing this file sets the interrupt limits and hysteresis. All three values must be writen at the same time
- reading this file returns the interrupt upper and lower limits and the
hysteresis in the following format:
interruptthis file maps the interrupt gpio to userspace:activethe interrupt gppio pin is low, i.e. there is an active interruptnot_activethe interrupt gpio pin is high, i.e. there isn't an active interrupt- This file will recieve a notify from the kernel when a new interrupt is recieved. So the file can be poll()'ed by userspace programs. TODO add an example.
interrupt_mapi2c register: INT0 to INT7- reading this file returns a 8x8 map showing which pixels are generating interrupts
thermistori2c registers: TTHL and TTHH.- reading this file returns the thermistor output in signed integer format
sensori2c registers: T01L to 0xFF- reading this file returns the 8x8 array containing the sensor values in signed integer format