ADC max1027

From ArmadeusWiki
Jump to: navigation, search


The MAX1027 is an 8 channels 10 bits analog-to-digital converter (ADC) with an internal reference and an internal temperature sensor.
Only 7 channels can be used (AIN0-AIN6) when AIN7 is configured as "start of conversion". As the MAX1027 is a quite complicated component to drive (because of its versatility), we recommand to read its datasheet before going further.


Depending on your needs (ie sampling slow or fast signals) there are 2 ways to use the max1027 Linux driver:

For slow signals (temperature or battery level monitoring):

The driver can be strictly controlled from its /sys interface: /sys/bus/spi/devices/spiN.0/ (N depending on the number of SPI devices declared for your target).
Moreover, if needed (lm-sensors & Co), you can add it a Linux Hardware Monitoring API (hwmon) compatible/standardized interface: /sys/class/hwmon/hwmonN/device/ (N depending on the ID given by hwmon). This interface mimics the /sys/bus/spi/devices/ one.

For "fast" signals (<10kHz):

The driver has a /dev interface which can be configured through /sys/bus/spi/devices/spiX.0/.


Max1027 driver is now by default installed on standard rootfs. so these instructions are kept here as reference.


  • On the target, the driver can be started like this:
 # modprobe max1027
 max1027 v0.5 successfully probed !
Note Note: In the following chapters, ADC_SPI will refer to spi1.0 in case of an APF9328 and to spi0.0 in case of the APF27Dev.

So for convenience you can do:

# export ADC_SPI="spi1.0"  (on APF9328)
# export ADC_SPI="spi0.0"  (on APF27DevFull)

"Slow" & configuration interface

Several interfaces in /sys/bus/spi/devices/spi... are created in order to:

  • read the 7 analog inputs values: inx_input (in mV)
  • read the temperature: temp1_input (in m°C)
  • modify the max1027 registers: conversion, setup & averaging
 # ls /sys/bus/spi/devices/$ADC_SPI/
 averaging    driver       in2_input    in5_input    modalias     temp1_input
 bus          in0_input    in3_input    in6_input    setup        uevent
 conversion   in1_input    in4_input    in7_input    subsystem

An input can be read like that:

 # cat /sys/bus/spi/devices/$ADC_SPI/in0_input

The temperature can be read like that:

 # cat /sys/bus/spi/devices/$ADC_SPI/temp1_input
Note Note: These values are only updated each time you launch a conversion, ie access the MAX1027 conversion register, after having configured setup register accordingly. So this interface is only suitable to measure slow evolving greats.


 # let set=0x62; echo $set > /sys/bus/spi/devices/$ADC_SPI/setup           (configure MAX1027; needed only once)

 # let conv=0x87; echo $conv > /sys/bus/spi/devices/$ADC_SPI/conversion    (launch 1 conversion of temp & AN0) 
 # cat /sys/bus/spi/devices/$ADC_SPI/temp1_input
 32750   (m°C)
 # cat /sys/bus/spi/devices/$ADC_SPI/in0_input
 1135    (mV)

"Fast" interface (frequencies > 10Hz)

In that case you can use the /dev interface (using blocking read to wait end of conversion). To create /dev nodes you can use the script located in armadeus/target/linux/modules/max1027 (driver's MAJOR number is dynamically allocated, so /dev needs to be dynamically created).

  • if not already installed:
 $ cp target/linux/modules/max1027/ /tftpboot/
 # tftp -g -r 192.168.0.X    (192.168.0.X = your Host PC's IP address)
 # sh
  • first, the conversion mode has to be chosen (channel 0->6 and temp):
 # let conv=0xb1; echo $conv > /sys/bus/spi/devices/$ADC_SPI/conversion
  • and eventually the averaging and setup registers as well (refer to the max1027 documentation for more details):
 # let set=0x48; echo $set > /sys/bus/spi/devices/$ADC_SPI/setup
 # let avg=0x20; echo $avg > /sys/bus/spi/devices/$ADC_SPI/averaging
  • then you can for example repeatedly read value of analog input 0 (variable sampling rate = depends on system load):
 # cat /dev/max1027/AIN0 | hexdump
  • read analog input 0 once:
 # time dd if=/dev/max1027/AIN0 bs=2 count=1 > tmp.bin
 # hexdump tmp.bin

This mode is activated by default in the Max1027 driver. If you switched to "slow" mode you can activate "fast" mode again with:

 # let set=0x48; echo $set > /sys/bus/spi/devices/$ADC_SPI/setup

Chip registers configuration

Independent of the mode, /sys interfaces allow direct access to the corresponding register in the MAX1027:

 # let conv=0xb1; echo $conv > /sys/bus/spi/devices/$ADC_SPI/conversion

You can also get current (hexadecimal) values of conversion, averaging and setup registers with (for example):

 # cat /sys/bus/spi/devices/$ADC_SPI/setup

For more details on how to use these registers, take a look at the datasheet.

Shell examples

  • Get channel 0 and temperature values:
 # let conv=0x87; echo $conv > /sys/bus/spi/devices/$ADC_SPI/conversion
 # cat /sys/class/hwmon/hwmon0/device/temp1_input
 # cat /sys/class/hwmon/hwmon0/device/in0_input
  • Get channels [0-6] and temperature values:
 # let conv=0xb1; echo $conv > /sys/bus/spi/devices/$ADC_SPI/conversion
  • Get 4 average values (of 32 conversions) for channel 0:
 # let avg=0x3c; echo $avg > /sys/bus/spi/devices/$ADC_SPI/averaging
 # let conv=0x84; echo $conv > /sys/bus/spi/devices/$ADC_SPI/conversion

MAX1027 on APF27Dev board

The MAX1027 is optionnaly mounted on the APF27Dev board. It is ready to use and the ADC inputs can be accessed through J6

figure 1 - MAX1027 localisation on APF27Dev

MAX1027 on APF9328 board

It is mounted (in option) on the APF9328 module. To know if you have one on your APF938, take a look at the connectors side of the module:

figure 2 - MAX1027 localisation on APF9328

If you don't have one and are a good electrician, you can order a sample at Maxim's website and solder it directly on your board (footprint is available).

Hardware interface

Warning Warning: The 8 ADC inputs voltage range is [0 - 3,3V]. Don't try to put higher voltage !!

By default internal reference voltage is used (2,5V), so if you apply analog values > 2,5V, they will be truncated.

figure 3 - MAX1027 connections

On APF9328

The i.MXL SPI_1 interface is used to communicate with the device.

Warning Warning:

In the original design we thought using AIN7 as analog input (instead of #CNVST) and thought too we won't need #EOC; but due to some chip bugs, it is now required. So if you want to use the MAX1027 then you will have to connect #EOC pin (End Of Conversion) and #CNVST pin (conversion start) to two i.MXL GPIOs.

By default the driver is using:

  • PA13 (CSI_HSYNC) for #EOC
  • and PA14 (CSI_PIXCLK) for #CNVST

So for example on the APF9328DevFull board you will have to connect:

  • pin 11 of ADC connector (right of the Ethernet one) to pin 12 of CSI connector (below RS232 one)
  • and pin 10 of the ADC connector to pin 9 of the CSI connector

On APF27Dev

Nothing special to do: MAX1027 is already set in "fast mode" and using #EOC and #CNVST pins.


Use case
(APF27, SPI Clock ~4MHz)
System -> Driver SPI comm Acquisition time EOC IT handling
(depends on system: speed, load)
SPI comm Driver -> System Total time / Max speed
1 channel acquisition through /sys/ (SPI trigerred conv, no averaging)  ??? 27uS 44uS 100uS 26uS  ???
1 channel acquisition through /sys/
(SPI trigerred conv, averaging = 8)
 ??? 25uS 78uS 160uS 30uS  ???
1 channel acquisition through /sys/
(SPI trigerred conv, averaging = 32)
 ??? 26uS 190uS 140uS 31uS  ???
1 channel + Temp acquisition through /sys/
(SPI trigerred conv, no averaging)
 ??? 25uS 90uS 114uS 44uS ???
1 channel + Temp acquisition through /sys/
(SPI trigerred conv, averaging = 32)
 ??? 24uS 234uS 136uS 48uS ???

CPU used masked time CPU used