Table of Contents

Vaisala RS92-SGPD firmware

Sonde have 32KB EEPROM chip. Chip contains (probably) some firmware binary patches for VLSI DSP chip, configuration (transmitting frequency, name, callibration data, ..) and others.

Dumping EEPROM with Bus Pirate

EEPROM can be dumped trought servicing connector (flat one). Anny SPI can be used in configuration 00. Digital IO use 2.8V logic, but inputs are 3.3 V tollerant. As power supply can be used anny source in range 4.7-10 V. Voltages bellow cca 7V will result in power-saving mode, but this does not matter for interfacing with EEPROM. Wiring for Bus Pirate is bellow.

Pin RESET must be pulled-down for al least 2 second before anny other operation can start.

Bus Pirate pin Vaisala probe pin
GND 1 - GND
+3V3 NC
+5V 2 - VCC
ADC NC
Vpu NC
AUX 12 - RESET
CLK 10 - SPI_CLK
MOSI 9 - SPI_MOSI
CS 8 - SPI_SS_EEPROM
MISO 11 - SPI_MISO

Python script for EEPROM dump

http://nat.brmlab.cz/project/weathersonde/buspirate_dump_eeprom.py

TODO: eeprom manipulation scripts and tools

notes

The sonde first used 250kHz clock to read bytes from EEPROM up to addres 376 (included). Then switches to faster bus speed (2MHz).

EEPROM

address space description

Address space in EEPROM can be visualy divided into severall subblocks. Each subblock is separeted from others by wide field of 0x00. Start address of block shows nice alignment to multiple of 0x100 +- frew bytes, those bytes might be missalignment, or more probably footer of previous block.

start address end address name description
0x0000 0x07FF blob 1 firmware, stage 2 bootloader
0x0800 0x4FFF blob 2 firmware, compressed image of X and Y memory (I memory is mapped to X)
0x5000 0x6FFF blob 3 high entropy, (compressed?)
0x7000 0x71FF blob 4 configuration and callibration
0x7200 0x79FF blob 5 event log?
0x7A00 0x7FFF blob 6 runtime status?

blob 1 - stage 2 bootloader

// Structure description in pseudocode
const uint256_t eeprom[32768]; // EEPROM content
int idx = 0;  
while (eeprom[idx] == 1) {
  int data_len = eeprom[idx+1] | (eeprom[idx+2] << 8);
  int addr = eeprom[idx+3] | (eeprom[idx+4] << 8);
  // copy data: X[addr]..X[addr+data_len] = eeprom[idx+5]..eeprom[idx+5+data_len]
  // but some trick for writing program memmory are probably involved
  idx += 5 + data_len;
}
// end of content
if (eeprom[idx] == 3) {
  data_len = eeprom[idx+1] | (eeprom[idx+2] << 8);
  // data_len souhld be 0
  addr = eeprom[idx+3] | (eeprom[idx+4] << 8);
  goto addr;
}

blob 2

This block is compressed. Compression algirithm is rather simple, replaces identical sequences of data with copy-from operation.

struct compressed_block_t {
  chunk_t chunk1;
  ...
  chunk_t chunkN;
  chunk_t chunk_exec;    // chunks repeats until EOF chunk is found
}
struct chunk_t {
  chunk_header_t chunk_header;
  uint8_t chunk_data[];         // chunk size varies and ends with EOF code
}
struct chunk_header_t {
  uint8_t prefix;      // prefix code used for decompression
  uint1_t bus_type;    // (top bit of address word) 0 => X bus, 1 => Y
  uint15_t address;    // block destionation address
  uint8_t prefix_size; // size of prefix in bites, 0xff for EOF
}

blob 4 - configuration and calibration

This block (512B long) is repeatedly broadcasted by sonde, in first part of frame.

see Callibration data for details

blob 5 - log

TODO: (verification needed)

blob 6 - status

address symbol meanign
0x7A02 - 0x7A03 DOWN_CNT have something todo with frame count?
0x7A04 ST4 operation status

dumps

start date (UTC) ID type start location EEPROM dump
2013-02-25 00:00 H2813056 RS92-SGPD CZ, Prague - Libuš http://nat.brmlab.cz/project/weathersonde/cz_prague_2013_05_1xTtt.bin
2013-07-03 00:00 H4043220 RS92-SGPD CZ, Prague - Libuš TODO