TLI Picutre

This whole project started as a curbside find: An abandoned power meter. Without much hesitation I picked it up.

After getting home and doing some research I found it was part of a metering system called SGP+M (Sistema de Gerenciamento de Perdas + Medição/System for Management of Losses + Metering). After more googling, I could find a manual for that system (read it here). It has many awesome stuff I’ll probably never get to see, so let’s just focus on the TLI.

If I’m not mistaken, TLI stands for “Terminal de Leitura de Informações/Information Reading Terminal”.

The board has these 3 main ICs:

  • Z8 Encore! series microcontroller (Z8F0421), equipped with 4KB of flash.
  • ATA5744N RF IC (RX Only, sadly).
  • CF8566T LCD Driver.

There is a 6 pin debug header on the board. Here is the pinout:

  • 1 - DBG
  • 2 - VCC (capacitive dropper output)
  • 3 - 3.3V
  • 4 - NC
  • 5 - NC
  • 6 - GND

The DBG pin is Zilog’s authoral system for debugging their microcontrollers. It uses UART Half-Duplex for communication with automatic baud rate detection.

I found a post by Sean Young sharing their work on dumping a different Z8 Encore microcontroller. On this post there is a piece of code I managed to badly modify (with the help of ChatGPT) to not only transmit, but also receive the response data. It’s shown below, I flashed it on my STM32 Bluepill so I didn’t need logic level shifters.

#define pin PA0
#define BIT_DELAY 10  // microseconds per bit (your original timing)

// Your existing send_byte with small tweak
void send_byte(int b)
{
  pinMode(pin, OUTPUT);
  digitalWrite(pin, LOW);  // Start bit
  delayMicroseconds(BIT_DELAY);

  for (int i = 0; i < 8; i++) {
    if (b & (1 << i))
      digitalWrite(pin, HIGH);
    else
      digitalWrite(pin, LOW);
    delayMicroseconds(BIT_DELAY);
  }

  digitalWrite(pin, HIGH);  // Stop bit
  delayMicroseconds(BIT_DELAY);
}

// New bit-bang receiver matching that framing
int read_byte() {
  pinMode(pin, INPUT_PULLUP);

  // Wait for start bit (line goes LOW)
  while (digitalRead(pin) == HIGH);

  // Align to middle of first data bit
  delayMicroseconds(BIT_DELAY + BIT_DELAY / 2);

  int value = 0;
  for (int i = 0; i < 8; i++) {
    if (digitalRead(pin))
      value |= (1 << i);
    delayMicroseconds(BIT_DELAY);
  }

  // Optionally wait for stop bit, but ignoring it here
  delayMicroseconds(BIT_DELAY);

  return value;
}

void setup() {
  Serial.begin(115200);
  pinMode(pin, OUTPUT);
  digitalWrite(pin, HIGH);  // Idle HIGH
}


void loop() {
  Serial.println("Holding DBG LOW for manual power connection...");

  pinMode(pin, OUTPUT);
  digitalWrite(pin, LOW);
  delay(10000);  // <-- 10 seconds for you to connect target power

  Serial.println("Releasing DBG line...");
  digitalWrite(pin, HIGH);
  delay(1);

  Serial.println("Starting communication sequence...");

  // Your existing command sequence
  send_byte(0x80);
  send_byte(0x0B);
  send_byte(0x00);
  send_byte(0x00);
  send_byte(0x20);
  send_byte(0x00);

  Serial.println("Switching to receive mode...");

  pinMode(pin, INPUT_PULLUP);
  delayMicroseconds(50);

  for (int i = 0; i < 1024; i++) {
    int b = read_byte();
    Serial.print("RECV 0x");
    Serial.println(b, HEX);
  }

  Serial.println("Done.");
  while (1);
}

Sadly all I got was 0xFF, which means the MCU has read protection enabled. Scrolling further on Sean’s post, we can see they also got it, but that isn’t the end of it. Zilog has an application note named AN0117 that explains how to do gang programming on Z8 microcontrollers using something called the BYPASS mode.

Sean developed software to dump their MCU using a raspberry pi, but they didn’t release the full code.

I love hardware, but I’m a terrible programmer, so I just explained all my situation to ChatGPT and managed to build a full STM32CubeIDE project with a bit of intervention by me. The code is avaiable on a GitHub repository on my profile.

Now the only thing left is buying a breakout board and connecting the STM32 to the Z8.

I really hope it works, I’d be able to display custom stuff on the LCD (This time with vanilla hardware, differently from my MT1389 post where I tossed the original board and hooked the VFD to an arduino), decode smart meter signals maybe, and maybe contribute with Hash’s efforts on reverse engineering smart meters