Hardware components of the Changers.com solar charger

Components (ICs) on the top side:

  • Atmel ATmega32U4 8-bit microcontroller
  • LM393A dual differential comparator
  • 272BI LinCMOS precision dual operational amplifiers
  • FDS4897C dual N & P channel PowerTrench MOSFET
  • TS2951-50 150mA 5.0V ultra low dropout voltage regulator
  • IRLL2705 HEXFET Power MOSFET
  • 4511 AE T05C ?

Components (ICs) on the bottom side:

  • 85831 p09g 112 ?
  • tbc …
Advertisements

Reverse engineering and fixing your broken Ignis/Baukneckt/Whirlpool or Philips oven/ stove

As my oven/stove broke I started analyzing the system in order to find and fix the error. Basically the residual-current-operated protective device “blew” when I switched on the oven – the cooktop worked just fine.

Side note: Searching the spare parts showed that Ignis, Bauknecht, Whirlpool and Philips are using the same parts – or that the same oven is sold under different brand names.

Disclaimer: be careful when working with devices that are usually connected to mains power. Definitely disconnected the device from mains power before trying to fix it or even measuring something – and also do make sure that there’s no power!

Gaining a basic understanding

The oven is connected to mains power using the three phase conductors (L1, L2, L3), the neutral conductor (N) and protection earth (PE).

There’s a lot of components inside the device which basically can be seen as resistors. To calculate the power converted to heat simply use the following formula (derived from Ohm’s law): P=U²/R where U=230 V (mains power in Europe).

There’s a lot of cables inside the oven, some components and several knobs/ rotary switches.

Those rotary switches work the following way: dependent on the position of the know some pins on the left side are connected with their direct opposite pins on the right side. Pins on the left and on the right side can be connected among each other so that combinations of connections can be made.

About the oven

The oven consists of the following main parts (besides cabling, etc.):

  • Rotary function selector switch
  • Oven light/lamp
  • Fan on the back
  • Fan on the top
  • Heating indicator
  • Temperature selection rotary switch/knob
  • Heating element on top (for upper heat; consisting of two separate loops)
  • Heating element on the bottom (for lower heat; single loop)
  • Thermistor, fuse or bi-metal (haven’t checked it yet)

The oven has a rotary function selector switch with 7 positions. Each of the positions may connect one or several out of the 7 internal switches (it’s a coincidence that the number of switch positions equals the number of internal switches).

I have identified the following functions for each internal switch:

  • 1/P1: “enable” heating, lamp and fans (does not switch them on alone, another internal switch needs to be switched on for this!)
  • 2/P2: switch on the heating element on the bottom (for the lower heat)
  • 3/P3: switch on the outer loop of the heating element on the top (part of the upper heat; ~1600 W)
  • 4/P4: switch on the inner loop of the heating element on the top (part of the upper heat; ~900 W)
  • 5/P5: may “enable” the heating indicator, however, I think that this is strange…
  • 6/P6: switch on the fan on the back side of the oven
  • 7/P7: switch on the oven’s lamp and the fan on the top side of the oven

Which internal switches are closed/opened at which position of the rotary switch? You need to look it up in the table to get a deep understanding of that.

Textual explanation:

  • Pos. 0: everything is switched off
  • Pos. 1: switch on oven’s lamp and fan on the top
  • Pos. 2: switch on oven’s lamp, fan on the top, bottom heating element, outer loop of upper heating element and enable the heating indicator
  • Pos. 3: switch on oven’s lamp, fan on the top, bottom heating element, outer loop of upper heating element and switch on fan on the back
  • Pos. 4: switch on oven’s lamp, fan on the top, both loops of the upper heating element
  • Pos. 5: just like pos. 4 but additionally also the fan on the back
  • Pos. 6: switch on oven’s lamp and both fans (on top and on the back side), no heating element at all (used for defrosting)

Using the information gained during analysis lead me to the cause of the error: a broken heating element in the bottom of the oven. Fortunately, those are not very expensive so that I could order a new one.

About the cooktop / hot plates

The two main parts (besides cabling are):

  • Whirlpool AKM 896/IX ceran cooktop, 6.2 kW (cost of ~90 €)
  • “Kochplattenschalterblock”/”7-Takt-Schalter-Block” 4144723003 (cost of ~40 €)

Dependent on the position of the rotary switch there are different configurations of how current flows through the elements of the hot plates to generate heat. There’s a cable with 4 pins wired to each zone of the hot plates. Dependent on the position of the switch P1 and P2 are connected with different pins.

The following calculations are an example for the hot plates connected with the yellow connector (and assuming a mains voltage of 230 V):

  • Position 0: P1 not connected, P2 not connected
  • Position 1: P1 connected to pin 1, P2 connected to pin 2;
    the current will be limited by a resistance of 108+108 Ohms (~245 W)
  • Position 2: P1 → pin 3, P2 → pin 4;
    the current will be limited by a resistance of 108+64 Ohms (~308 W)
  • Position 3: P1 → pin 2, P2 → pin 4;
    the current will be limited by a resistance of 108 Ohms (~490 W)
  • Position 4: P1 → pin 2, P2 → pin 3;
    the current will be limited by a resistance of 64 Ohms (~827 W)
  • Position 5: P1 → pin 2, P2 → pins 3 and 4;
    there are two paths for the current now; the old one through the 64 Ohms and another one through 108 Ohms (~827+429=1256 W)
  • Position 6: P1 → pins 1 and 2, P2 → pins 3 and 4
    there are three current paths now; each limited by a resistance of 108/108/64 Ohms (~490+490+827=1807 W)

Schematic

As I have reverse engineered the whole device, I can offer the following schematic (which may not bee free of errors):

output

I have also included order numbers within the schematic.

Summary

It was quite interesting to see the different components of an oven/ stove and how they work internally. Basically it’s not too complicated to fix such a device, when a component is broken. And you don’t need many tools: a multimeter is enough – or even a device only measuring resistance can be enough.

 

This post may be (or may be not) updated with further details in the future.

The odyssey of getting my Funduino/Arduino UNO back to normal operation

Long, long time ago I had flashed the bootloader of my Funduino UNO.

When listing my USB devices it would appear as follows:

Bus 002 Device 017: ID 03eb:2042 Atmel Corp. LUFA Keyboard Demo Application

I had flashed a firmware to get an alternative to the makeymakey board with my own shield (basically with high-imedance resistors only). So I could not flash the ATmega328P microcontroller (in the socket) via the serial interface which is usually provided via the USB of the ATmega16U2. And unfortunately I didn’t have the old shield available anymore and the controller was constantly putting out data on the HID keyboard device which was quite annoying!

This page on sparkfun explains what a bootloader is, what it does and how it basically works: https://learn.sparkfun.com/tutorials/installing-an-arduino-bootloader

Burning the bootloader via the Arduino IDE failed:

arduino_burn_bootloader.png

I wasn’t too sure if my AVRISP mkII was working correctly. I remembered that I’d has issues with it before – and I hadn’t used it for a long, long time!

Same error when trying to talk to avrdude directly via command line:

avrdude -c avrispmkII -p m16u2
avrdude: stk500v2_command(): command failed
avrdude: stk500v2_program_enable(): bad AVRISPmkII connection status: Target not detected
avrdude: initialization failed, rc=-1
 Double check connections and try again, or use -F to override
 this check.
avrdude done. Thank you.

Similar error for the ATmega328P with the other connector (using “avrdude -c avrispmkII -p m328p”). How about adding the port and verbose options?

$ avrdude -c avrispmkII -p m328p -P usb -v

avrdude: Version 6.0.1, compiled on Oct 21 2013 at 15:55:32
 Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
 Copyright (c) 2007-2009 Joerg Wunsch

System wide configuration file is "/etc/avrdude.conf"
 User configuration file is "/home/maehw/.avrduderc"
 User configuration file does not exist or is not a regular file, skipping

Using Port : usb
 Using Programmer : avrispmkII
avrdude: usbdev_open(): Found AVRISP mkII, serno: 1337DEADBEEF
 AVR Part : ATmega328P
 Chip Erase delay : 9000 us
 PAGEL : PD7
 BS2 : PC2
 RESET disposition : dedicated
 RETRY pulse : SCK
 serial program mode : yes
 parallel program mode : yes
 Timeout : 200
 StabDelay : 100
 CmdexeDelay : 25
 SyncLoops : 32
 ByteDelay : 0
 PollIndex : 3
 PollValue : 0x53
 Memory Detail :

Block Poll Page Polled
 Memory Type Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack
 ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
 eeprom 65 20 4 0 no 1024 4 0 3600 3600 0xff 0xff
 flash 65 6 128 0 yes 32768 128 256 4500 4500 0xff 0xff
 lfuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
 hfuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
 efuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
 lock 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
 calibration 0 0 0 0 no 1 0 0 0 0 0x00 0x00
 signature 0 0 0 0 no 3 0 0 0 0 0x00 0x00

Programmer Type : STK500V2
 Description : Atmel AVR ISP mkII
 Programmer Model: AVRISP mkII
 Hardware Version: 1
 Firmware Version Master : 1.12
 Vtarget : 0.0 V
 SCK period : 4.00 us
(...)

The error message can also be found on avrfreaks.net and mikrocontroller.net (DE).

Relevant info: “-vvvv” gives a very verbose mode. Let’s assume my AVRISP mkII is broken. How to proceed? I’ve still got a working Arduino Leonardo lying around – let’s try to use it as an ISP: ArduinoISP – https://www.arduino.cc/en/Tutorial/ArduinoISP

Before loading the ArduinoISP sketch and resetting the board:

Bus 002 Device 023: ID 2341:8036 Arduino SA Leonardo (CDC ACM, HID)

Afterwards:

Bus 002 Device 024: ID 2341:0036 Arduino SA

The two Arduino board are connected with the following pins:

  • power supply 5V and GND from the programmer to the target Arduino
  • SPI interface (MOSI on target pin 11, MISO on target pin 12, CLK on target pin 13)
  • reset pin of the target Arduino with a controlling GPIO of the programmer Arduino

Checkout the following diagram:

If pins with the same numbers were connected with each other – like those SPI pins – wouldn’t this conflict? If MISO was connected to MISO and MOSI was connected to MOSI? Both controllers might drive the same line?

It probably would! I have stumbled across the logic in the ArduinoISP sketch and had to define:

#define USE_OLD_STYLE_WIRING

[Comment: “Uncomment following line to use the old Uno style wiring (using pin 11, 12 and 13 instead of the SPI header) on Leonardo, Due…”]

Avrdude didn’t complain about any wrong signatures anymore. I used:

$ avrdude -P /dev/ttyACM0 -c stk500v1 -b 19200 -F -v -v -p m328p

Back to the Arduino IDE, finally:

burn_bootloader

In a next step I compiled and downloaded the simple Blink example, that worked as well. Let’s try to unplug the Arduino Leonardo (the Arduino functioning as a programmer) and replug the USB connector to the Funduino/Arduino UNO. The LED still blinks after startup, however the UNO is still not available as a serial device to be programmed, but still the HID keyboard. The bootloader/firmware of the ATmega16U2 still needs to be flashed. The ATmega16U2 acts as a USB-serial bridge between the PC and the ATmega328P microcontroller.

Resetting the Arduino UNO connects the device in a different mode:

Bus 002 Device 062: ID 03eb:2fef Atmel Corp.

Then the dfu-programmer needs to be executed:

$ sudo dfu-programmer atmega16u2 erase

$ sudo dfu-programmer atmega16u2 flash Arduino-usbserial-atmega16u2-Uno-Rev3.hex 
Validating...
4034 bytes used (32.83%)

$ sudo dfu-programmer atmega16u2 reset

… and power-cycling the board finally did the trick for me: the device is back available as serial interface:

Bus 002 Device 064: ID 2341:0043 Arduino SA Uno R3 (CDC ACM)

And now it can also be programmed via the Arduino IDE back again! 🙂

 

Using Adafruit NeoPixel ring with Arduino

There’s a library for the Adafruit NeoPixel which can be used with the Arduino:

When the library is missing the Arduino IDE will complain about the missing C header file:

SomeSketch.ino:1:31: fatal error: Adafruit_NeoPixel.h: No such file or directory
 #include <Adafruit_NeoPixel.h>
 ^
compilation terminated.
exit status 1
Error compiling for board Arduino/Genuino Uno.

Install the missing library via the library manager:

adafruit_neopixel_lib

Compiling your sketch should now work out!

Gerber files in EAGLE

I have worked with files describing electronic schematics and PCB board layout. But so far I have never really worked with Gerber files myself. As I found out it’s not rocket science, it’s not complicated at all.

The Gerber format is used to describe monochrome vector images by an ordered stream of graphics objects. The format uses printable ASCII (7 bit) characters only.

The schematic and PCB design software EAGLE provides a job mechanism with the aid of which the creation of the output data for a board can be automated (CAM). This tool can be used to create Gerber files. The predefined job is called gerb274x.cam.

For a 2-layer PCB the standard process will lead to five Gerber files (where cmp stands for component side and sol for solder side):

  • Copper, component side (.cmp)
  • Copper, solder side (.sol)
  • Silk screen, component side (.plc)
  • Solder stop mask, component side (.stc)
  • Solder stop mask, solder side (.sts)

You might want to add (if your manufacturer allows you to have it:

  • Silk screen, solder side (.pls)

Additional steps: you may want to add a drill file, specified by the Excellon file format. That’s another job in Eagle called excellon.cam. The Excellon format (variant of the RS-274-C standard) is widely used to drive CNC drilling and routing machines in PCB manufacturing.

This will create the following two files:

 

  • Drill file (.drd)
  • Drill Station Info File (.dri)

The drill file is used by a drill program and includes sizes and locations of holes in the PCB.

To check my results I used the gerbv tool under Linux:

gerbv
Screenshot of gerbv tool

References:

 

Dumping a NAND flash, part 1

NAND flash organization

The memory of a NAND flash is organized in a hierarchy of:

  • blocks,
  • pages,
  • sectors,
  • planes.

The Hynix HY27UF084G2B consists of 4096 blocks. Each block of a NAND Flash consists of 64 pages. Each page consists of 4 sectors of data (512 Byte each) and 4 small sectors (16 Byte) of spare data, i.e. a single page consists of 2112 Byte where 2048 Bytes are data and 64 Bytes are spare. 2112 Byte blocks are also called “large block” opposed to “small blocks” of 528 Bytes (holding 512 Bytes of data and 16 Bytes of spare data).

Memory: 4096 blocks × 64 pages/block × 4 sectors/page × 512 Byte/sector = 512 MiB
Spare memory: 4096 blocks × 64 pages/block × 4 sectors/page × 16 Byte/sector = 16 MiB
Overall memory: 512 MiB + 16 MiB = 528 MiB

Flash memory is read and written in pages and erased in blocks of data. Memory must be erased before it is written to! This is also true for single byte writes.

Content of the spare areas: those out of band (OOB) area store data for error detection (e.g. a checksum), correction coding (ECC, most algorithms are based on Hamming codes) and bad block markers (if ECC cannot handle the amount of errors anymore). But can also contain data for the logical/virtual organization (blocks, pages) of physical blocks and pages. The ECC is usually a vendor/model dependent algorithm.

Creating a flash dump

Know your chip

Sometimes the interface to update firmware (e.g. via JTAG or serial port) is not exposed or not easy to find. It may then be an option to take the NAND flash device from the printed circuit board. The desoldering process is followed by dumping the flash memory, sometimes referred to as “off-chip forensics” (used in security analysis and data recovery).

In a next step the device is taken and put into a NAND flash reader/writer. There are commercial tools, but they can also be built from some basic hardware. A popular choice is to build a serial/parallel to USB adapter*. The FTDI FT2232H (and a breakout board) is a good starting point as you can toggle various GPIO pins in “bit bang” mode via its USB interface (mostly used as dual-port USB/serial converter). There’s also a project about using an Arduino NAND flash reader (no focus on speed).

It’s also good to know the NAND flash memory chip’s parameters and pinout in advance. Those specifications can be read from the datasheet, if you can read the labels written on the IC package. It is possible that your flash complies with the Open NAND Flash Interface specifications.

Taking the Hynix HY27UF084G2B again as an example:

  • 512M x 8bit NAND flash
  • package: 48-TSOP1, dimensions: 12x20x1mm, 0.5mm pitch
  • supply voltage: 3.3V (Vcc range: 2.7V..3.6V)
  • memory organization already mentioned above;
    page organization: separate data and spare areas, i.e. main field with 4x 512 Byte of data comes first, followed by 4x 16 Bytes spare
  • timings can be read from the datasheet
  • interface pins
    • x8 bus width I/O interface, i.e. IO0..IO7
    • nCE: chip enable
    • nWE: write enable
    • nRE: read enable
    • RnB: ready/busy indication
    • CLE: command latch enable
    • ALE: address latch enable
    • nWP: write protect
      (8 + 7 = 15 pins needed)
  • capacitance between Vcc and Vss as a buffer: 0.1 uF
  • address cycle map: which address bit is latched when on the I/O interface?
    • the HY27UF084G2B has 5 cycles, i.e. 5 x 8 bit = 40 potential bits
    • 512M addresses needed: log2(512M)=29, i.e. only 30 bits required (A29..A0) and 10 bits to be kept at a low logic level
  • definition of the device’s command set; some commands are single byte operations, others are composed of multiple bytes e.g.
    • READ1 (0x00 in 1st cycle, 0x30 in 2nd cycle)
    • READ ID (0x90 in 1st cycle)
    • RESET (0xFF)

The READ ID command is a good one to test if the connection with the flash can be established successfully and without causing a potentially high damage to the flash device. However, you should know what you do.

The ID to be read for my chip is: 0xAD 0xDC 0x10 0x95 0x54. Those bytes can be interpreted in the following way:

  1. Manufacturer Code: 0xAD (=Hynix)
  2. Device Identifier: 0xDC
  3. Device Identifier Description: 0x10 = 0b00010000
    • Write Cache: not supported
    • Interleave program between multiple chips: not supported
    • Number of simultaneously programmed pages: 2
    • Cell type: 2 level cell
    • Die/package: 1
  4. Device Identifier Description:0x95 = 0b10010101
    • Serial access time: 25 ns
    • Organization: X8
    • Block size (w/o spare area): 128K (see above: 64 pages × 2KB/page)
    • Spare area size (Bytes per 512 Byte): 16
    • Page size (w/o spare area): 2KB
  5. Device Identifier Description (Multiplane information): 0x54 = 0b01010100
    • Plane size: 2 Gbit = 256 MByte
    • Plane number: 2

(*Side note: our flash IC is a parallel flash, but a similar approach could be taken for an SPI flash as well, using an SPI to USB bridge.)

Building the hardware for a DIY NAND flash reader

Required hardware:

  • TSOP-48 socket
  • 0.1uF capacitor
  • wires & jumper wires
  • breakout board with the FTDI FT2232H (to read/write data from/to the NAND flash; communication with a host PC)
  • USB cable

The pins of the TSOP-48 socket (being directly connected with NAND flash memory device) are wired with the pins of the FTDI FT2232H.

(Side note: the TSOP socket may also be used to get the NAND flash memory working in it’s embedded system environment and eavesdropping on how it is accessed with a logic analyzer – flash memory at which addresses and when, e.g. at boot.)

Using software with the DIY NAND flash reader

I will run my DIY NAND flash reader under a Linux operating system. Therefore tools which already work under Windows are not applicable here. But at least the source code of spritesmods.com ftdinandreader (Download) and Bjoern Kerler’s advancement NAND Reader FTDI can help here. I may start from scratch but also may re-use some source code.

First I got the source code and build files for libftdi. The build process and the dependencies for libftdi in turn (e.g. libusb-*-dev) are documented well in README and README.build. Afterwards I could run one of the examples coming with libftdi as I had a small breakout board with an FTDI 232RQ laying around.

$ lsusb
Bus 002 Device 004: ID 0403:6001 Future Technology Devices International, Ltd FT232 Serial (UART) IC
(...)

Let’s use the example:

/libftdi1-1.3/build/examples $ ./find_all_pp -v 0x0403 -p 0x6001
Found devices ( VID: 0x403, PID: 0x6001 )
------------------------------------------------
FTDI (0x228c950): , ,  (Open FAILED)

Using higher access rights results in:

/libftdi1-1.3/build/examples $ ./find_all_pp -v 0x0403 -p 0x6001
Found devices ( VID: 0x403, PID: 0x6001 )
------------------------------------------------
FTDI (0xd64cb0): FTDI, FT232R USB UART, <#serial> (Open OK)

There’s another example, shipped with libftdi, to access the FTDI’s internal EEPROM memory:

/libftdi1-1.3/build/examples $ ./eeprom 
Chip type 3 ftdi_eeprom_size: 128
0x000: 00 40 03 04 01 60 00 00  a0 2d 08 00 00 00 98 0a .@...`.. .-......
0x010: a2 20 c2 12 23 10 05 00  0a 03 46 00 54 00 44 00 . ..#... ..F.T.D.
0x020: 49 00 20 03 46 00 54 00  32 00 33 00 32 00 52 00 I. .F.T. 2.3.2.R.
0x030: 20 00 55 00 53 00 42 00  20 00 55 00 41 00 52 00  .U.S.B.  .U.A.R.
0x040: 54 00 12 03 XX 00 XX 00  XX 00 XX 00 XX 00 XX 00 T...X.X. X.X.X.X.
0x050: XX 00 XX 00 c4 7a 34 70  00 00 00 00 00 00 00 00 X.X..z4p ........
0x060: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00 ........ ........
0x070: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 38 fd ........ ......8.
0x080: 28 04 d7 fb 00 00 c4 7a  34 70 42 00 00 00 00 00 (......z 4pB.....
0x090: 00 00 00 00 00 00 00 00  37 41 59 53 54 4c 46 43 ........ 7AYSTLFC
VID:     0x0403
PID:     0x6001
Release: 0x0000
Bus Powered:  90 mA USB Remote Wake Up
Manufacturer: FTDI
Product:      FT232R USB UART
Serial:       <#serial>
Checksum      : <#checksum>
Internal EEPROM
Oscillator: Internal
Enable Remote Wake Up
PNP: 1
Channel A has Mode UART VCP
C0 Function: TXLED
C1 Function: RXLED
C2 Function: TXDEN
C3 Function: PWREN
C4 Function: SLEEP

In a next step I used some of the example code and used it in my own first C file. I compiled it using a simple Makefile and the gcc build tools.

Next steps:

  • getting the required hardware
  • assemble the parts
  • unsolder the flash IC
  • use/develop software to dump the NAND flash memory
  • analyze the dump

Good resources

 

How to produce EXEs that only contain printable ASCII

Dr. Tom Murphy (@tom7) wrote a paper about “compilers, bits and assembly” – it is about producing DOS-executable EXE file which contain the limited set of only the printable ASCII bytes. In principle, he explains which steps to be taken and some necessary tricks/workarounds when writing a C89 compiler to fulfil these requirements. You can also learn something about the x86 instruction set. Find the paper (20 pages with some ASCII art in it) here. And he also made an explanation video:

SDS011 sensor data for air quality measurement

I got a Nova Fitness SDS011 sensor for measuring air quality. It has a serial interface and outputs data with 9600 baud. The serial interface pins Rx and Tx are specified as TTL with 3.3V levels.

It can be plugged into a USB port via the serial/USB converter (based on an CH340 IC) it is shipped with. dmesg outputs the following system log:

usb 2-1.2: ch341-uart converter now attached to ttyUSB0

Check lsusb‘s output:

Bus 002 Device 005: ID 1a86:7523 QinHeng Electronics HL-340 USB-Serial adapter

It uses a baud rate of 9600 (ssty). The serial data stream can be formatted with od as stream of hexadecimal numbers and printed to stdout:

# od -x < /dev/ttyUSB0 
0000000 c0aa 001a 001c 4bea ab6b c0aa 001a 001d
0000020 4bea ab6c c0aa 001a 001d 4bea ab6c c0aa
0000040 001a 001d 4bea ab6c c0aa 001a 001d 4bea
0000060 ab6c c0aa 001a 001d 4bea ab6c c0aa 001a
0000100 001e 4bea ab6d c0aa 001a 001e 4bea ab6d
...

The UART protocol (described in the datasheet) uses a packet of 10 Bytes sent each second. It contains two 16-bit values for both PM2.5 and PM10.

The blog article “Feinstaubmessung mit dem Raspberry Pi” [German] gives a good introduction of how to work on the raw data. It also provides an explanation of how to calculate the particulate matter measurement data in µg/m³ from the raw values. You can also find a Bash script on that site which can help as a “getting started” guide.

After some modifications you get two values per second (indoor test):

$ ./sds011_loop.sh 
preamble ok
[2017-03-20 19:40:50] particulate matter PM25: 14.8 µg/m³
[2017-03-20 19:40:50] particulate matter PM10: 36.1 µg/m³
preamble ok
[2017-03-20 19:40:51] particulate matter PM25: 14.9 µg/m³
[2017-03-20 19:40:51] particulate matter PM10: 36.4 µg/m³
preamble ok
[2017-03-20 19:40:52] particulate matter PM25: 14.9 µg/m³
[2017-03-20 19:40:52] particulate matter PM10: 36.4 µg/m³

The Bash script currently does not calculate and check the checksum which is also transmitted within the UART data stream.

Bern Laquai used an Arduino and described his step in the document “Arduino-basierte Auswertung von Messdaten und Data- Logging für den Feinstaubsensor SDS011 von Nova Fitness” [German pdf file].

The sensor itself has a limited service lifetime of “up to 8000 hours” – which would translate to 333.3 days or not even a whole calendar year. To prolong the service lifetime it’s recommended to power down the sensor and use it in a discontinuous way.

Possible next steps: use a simple wireless NodeMCU, add temperature and humidity sensor(s) and contribute to projects like “luftdaten.info – Feinstaub selber messen“.

Tiptoi firmware update

The firmware update files can directly be downloaded from Ravensburger’s website. The file names for the German version are Update3202.upd (~10.8 MiB) and update.upd (~6.1 MiB).

String analysis

The strings command can be run on those files to check for any insights into how the embedded system works or how updates are carried out. It would also be interesting to find out what is actually written to the NAND flash memory and possibly also other non-volatile memories.

Interesting entries:

  • List of NAND flash names (including the Hynix HY27UF084G2B with several others from Samsung, Hynix, Toshiba, Micron, ST and Intel)
  • Hints about the NTFL (NAND Flash Translation Layer)
  • Library/function names: FSLib (FS probably stands for filesystem), NandMtd, MtdLib (Mtd probably stands for “Memory Technology Device”), FatLib, MediaLib, Utl_*
  • Version strings
  • “Serial trace is active!”
  • File system names: FAT32, FAT16, FAT12
  • List of German words: Apfel, Auto, Baum, …, Wort, Wurm, Zelt – What could they be used for?
  • Strings containing references to media files (“ID3x”, “RIFF”, “WAVEfm”)
  • Strings containing the word “battery”
  • Strings referring to possible SCSI data transfers
  • Firmware version strings at the end, e.g. “ANYKA_IDRAV_N0038” and “RAV_V0136”
  • C file names (e.g. “medium.c”)
  • “End of userware”, “This is userware”
  • Warning and error messages, probably also debug strings

Both firmware update files seem to contain RIFF wave files. As a first indicator the number of matches is counted:

$ strings update.upd | grep RIFF | wc -l
49
$ strings Update3202.upd | grep RIFF | wc -l
58

Using burntool

There is a burntool for the AK98 / AK37 / AK39 / AK10L / 10xx / 11xx MCUs.

Firmware update files

Using the burntool the firmware update files are split up and stored separately in the subdirectory /Update_Files when being imported:

  • BOOT.bin (~27 kB; “nandboot”)
  • codepage.bin (~880 kB; “download_to_nand2”)
  • producer.bin (~111/88 kB; “producer”)
  • PROG.bin (~3.7 MB/1 MB; “download_to_nand1”)
  • voice/Chomp_Voice.bin (~4.3 MB; “download_to_udisk1”)
  • Language/BatLowUpdate[DUTCH|FRENCH|GERMAN].wav
  • Language/Update[DUTCH|FRENCH|GERMAN].wav

The tool can also be used to re-assemble those files to a single .upd firmware update file (export function).

Configuration

The burntool also comes with a configuration file (config.txt) where several settings can or need to be defined:

  • run address for the producer binary
  • MAC addresses and serial numbers to be written
  • chipset specific settings
    • MCU chip type (AK_*)
    • mode (there seems to be a reference to JTAG on the AK_11XX devices)
  • Download to different sections:
    • udisk: contents from PC directory /voice go here (audio files),
      UDISK destination is “A:VOIMG”
    • MTD: root file system files(?) from PC (root.jffs2, root.sqsh4) to be stored in device’s disks A and B; not sure if applicable for Tiptoi pen
    • Flash: PROG.bin and codepage.bin fo to the Flash memory
  • formatting with partition table
  • number of supported flash devices and
  • lists of those supported NAND flash, SPI NAND flash and SD card flash devices
  • definition of USB VID and PID
  • command line support

NAND flash configuration

The definition list of the NAND flash devices includes the following details: chip ID and chip organization:

  • page size (usually 512, 2048 or 4096 Bytes)
  • pages per block (usually 32, 64, 128)
  • total block count (e.g. 4096)
  • group block number[?]
  • plane block number[?]
  • spare size (16 or 64; Byte per page!)
  • column address cycle + last column address cycle mask bit
  • row address cycle + last column address cycle mask bit
  • custom NAND flash configuration (reserved for future use?)
  • flag (set of bits)
  • command length for timing considerations
  • data length for timing considerations
  • descriptor string (device name)

Those settings can be both read and written from the burntool GUI. So changes in the GUI can be tracked in the config.txt file and its file format can be understood.

Example configuration entry for a NAND flash device:

burntool NAND flash configuration list
burntool NAND flash configuration list

Corresponding entry in the config.txt (the entry no. is automatically filled in). You can see that some values are defined in decimal, others in hex:

nand supported count = ...
nand 1 = 0x2,    3,   4, 5, 6, 7,   8, 9, 10, 11,  12, 0xd, 0x14, 0x15, 0x16, 17

Instead of using this reverse engineering approach – there is one version of the burntool the data contained in the .upd file can be read on import and is then stored in the config.txt file. For the specific Flash IC mentioned above the line in the configuration file is:

nandXXX = 0x9510dcad, 2048,  64, 4096, 4096, 2048,  64, 2, 15, 3,   7, 0x2, 0x1, 0xf5ad1, 0x40203, Hynix HY27UF084G2B
  • chip ID: 0x9510dcad (seems to be a little endian representation of the ID which can be read from the IC with the READ ID command,
    i.e. 0xAD =Manufacturer Code for Hynix, 0xDC = Device Identifier,
    0x10 0x95 = Device Details, 0x54 = Multiplane info is missing however)
  • page size: 2048 Bytes
  • pages per block: 64
  • total block count: 4096
  • group block number[?]: 4096
  • plane block number[?]: 2048
  • spare size: 64 Byte per page
  • column address cycle + last column address cycle mask bit: 2, 15
  • row address cycle + last column address cycle mask bit: 3, 7
  • custom NAND flash configuration (reserved for future use?): 2
  • flag (set of bits): 0x1
  • command length for timing considerations: 0xf5ad1 = 1’006’289d
  • data length for timing considerations: 0x40203 = 262’659d
  • descriptor string (device name): Hynix HY27UF084G2B

The list of SPI flash configurations is not too important for us as the Tiptoi does not use SPI flash.

Partition table configuration

The data structure for a partition includes:

  • symbol (seen: A/B, probably A..G)
  • user disk (seen: yes/no)
  • “infor” (seen: normal/check/read-only)
  • attribute (seen: primary/slave/MMI/STANDARD/UNSTANDARD)
  • size
  • volume label (string)

Back to the .upd firmware update file

Maybe we can find out something about the format of the firmware update files. As we know that the string of the flash device is stored in the .upd file let’s have a look for its location and the area around it within the file using the strings command with option -t (-td for decimal, -tx for hex):

$ strings update.upd -tx | grep 'Hynix HY27UF084G2B'
   2ef8 Hynix HY27UF084G2B
$ strings Update3202.upd -td | grep 'Hynix HY27UF084G2B'
   3552 Hynix HY27UF084G2B

The firmware update files pretty much start with a list of the supported flash devices.

The entries have a fixed width/spacing of 287 bytes (measured between the start of strings) in update.upd. The entries end with the string (NULL-terminated, up to 255 bytes), the other information (32 byte) can be found before it:

flash_device_descriptor

  • 32-bit Chip ID (0x9510DCAD)
  • 16-bit: page size: value is 0x0800 = 2048 Bytes (little endian)
  • 16-bit: pages per block is 0x0040 = 64
  • 16-bit: total block count is 0x1000 = 4096
  • 16-bit: group block number[?] is 0x1000 = 4096
  • 16-bit: plane block number[?] is 0x0800 =2048
  • 8-bit: spare size is 0x40 = 64 Byte per page
  • 8-bit: column address cycle is 0x02 = 2
  • 8-bit: last column address cycle mask bit: 0x0F = 15
  • 8-bit: row address cycle: 0x03 = 3
  • 8-bit: last column address cycle mask bit:  0x0B = 11 != 7 (?)
  • 8-bit: custom NAND flash configuration (reserved for future use?): 0x02 = 2
  • 32-bit flag (set of bits): 0x09000001 != 0x1 (masked?)
  • 32-bit command length for timing considerations: 0xf5ad1 = 1’006’289d
  • 32-bit data length for timing considerations: 0x40203 = 262’659d (shifted by 4 bit?)
  • 255 byte NULL-terminated descriptor string (device name): Hynix HY27UF084G2B

The format used by Update32.upd is slightly different: the width/spacing of each entry is 64 bytes:

flash_device_descriptor_2

It’s just a more dense representation saving some NULL bytes in the descriptor string. The string may now only take up to 32 bytes instead of 255.

burntool program

About the burntool itself: BurnTool.exe (~1-2 MB): it is a PE32 executable (GUI) Intel 80386, for MS Windows. There’s different versions of the burntool available in the internet. Also found source code around the web for the burntool itself!

Open questions

  • Which sections of the .upd files are transferred to the Tiptoi device?
  • How to build a valid config.txt configuration file?
  • Which sections include actual firmware code and in which instruction set?
  • Which addresses are used and where are the peripherals mapped?
  • What is the difference in the firmware update files for the different languages?