01101001 01101110
fn init() -> Result<()>
for x in 0..buf.len()
load(addr, 0xFF)
sys.run(0x4A, flags)
if val > 0 { dispatch() }
>> 0x00: READY
loop { poll(); yield; }
stream.flush()
0xDEAD :: 0xBEEF
bind(sock, &addr, len)
pub fn connect(host: &str)
match state {
State::Init => boot(),
State::Run => tick(),
_ => halt(),
}
reg[0x3] = 0b11001010
clk.tick()
assert!(val != null)
>> SIGNAL RECEIVED
buf[i] ^= key[i % klen]
let n = read(fd, buf, 64)
while !done { step(); }
push(stack, frame)
0x7F :: OK
type Handler = fn(Ctx)
emit(Event::Data, payload)
select! { rx => handle(rx) }
spawn(async move { run() })
>> 0x01: PROCESSING
map.insert(k, v)
drain().collect::<Vec<_>>()
let _ = tx.send(msg)
timeout(Duration::ms(100))
>> CHECKSUM PASS
fn encode(src: &[u8]) -> Vec
pipe.write_all(&frame)
crc32(data, len)
>> 0x00FF: ACK
schedule(task, interval)
lock.acquire()
>> SYNC COMPLETE
release(ptr)
0x00 0x00 0x00 0x01
watchdog.reset()
>> LINK ESTABLISHED
fn poll(&mut self) -> Poll
waker.wake_by_ref()
cx.waker().clone()
01101001 01101110
fn init() -> Result<()>
for x in 0..buf.len()
load(addr, 0xFF)
sys.run(0x4A, flags)
if val > 0 { dispatch() }
>> 0x00: READY
loop { poll(); yield; }
stream.flush()
0xDEAD :: 0xBEEF
bind(sock, &addr, len)
pub fn connect(host: &str)
match state {
State::Init => boot(),
State::Run => tick(),
_ => halt(),
}
reg[0x3] = 0b11001010
clk.tick()
assert!(val != null)
>> SIGNAL RECEIVED
buf[i] ^= key[i % klen]
let n = read(fd, buf, 64)
while !done { step(); }
push(stack, frame)
0x7F :: OK
type Handler = fn(Ctx)
emit(Event::Data, payload)
select! { rx => handle(rx) }
spawn(async move { run() })
>> 0x01: PROCESSING
map.insert(k, v)
drain().collect::<Vec<_>>()
let _ = tx.send(msg)
timeout(Duration::ms(100))
>> CHECKSUM PASS
fn encode(src: &[u8]) -> Vec
pipe.write_all(&frame)
crc32(data, len)
>> 0x00FF: ACK
schedule(task, interval)
lock.acquire()
>> SYNC COMPLETE
release(ptr)
0x00 0x00 0x00 0x01
watchdog.reset()
>> LINK ESTABLISHED
fn poll(&mut self) -> Poll
waker.wake_by_ref()
cx.waker().clone()
stream.flush()
0xDEAD :: 0xBEEF
bind(sock, &addr, len)
pub fn connect(host: &str)
match state {
State::Init => boot(),
State::Run => tick(),
_ => halt(),
}
reg[0x3] = 0b11001010
clk.tick()
assert!(val != null)
>> SIGNAL RECEIVED
buf[i] ^= key[i % klen]
let n = read(fd, buf, 64)
while !done { step(); }
push(stack, frame)
0x7F :: OK
type Handler = fn(Ctx)
emit(Event::Data, payload)
select! { rx => handle(rx) }
spawn(async move { run() })
>> 0x01: PROCESSING
map.insert(k, v)
drain().collect::<Vec<_>>()
let _ = tx.send(msg)
timeout(Duration::ms(100))
>> CHECKSUM PASS
fn encode(src: &[u8]) -> Vec
pipe.write_all(&frame)
crc32(data, len)
>> 0x00FF: ACK
schedule(task, interval)
lock.acquire()
>> SYNC COMPLETE
release(ptr)
0x00 0x00 0x00 0x01
watchdog.reset()
>> LINK ESTABLISHED
fn poll(&mut self) -> Poll
waker.wake_by_ref()
cx.waker().clone()
01101001 01101110
fn init() -> Result<()>
for x in 0..buf.len()
load(addr, 0xFF)
sys.run(0x4A, flags)
if val > 0 { dispatch() }
>> 0x00: READY
loop { poll(); yield; }
stream.flush()
0xDEAD :: 0xBEEF
bind(sock, &addr, len)
pub fn connect(host: &str)
match state {
State::Init => boot(),
State::Run => tick(),
_ => halt(),
}
reg[0x3] = 0b11001010
clk.tick()
assert!(val != null)
>> SIGNAL RECEIVED
buf[i] ^= key[i % klen]
let n = read(fd, buf, 64)
while !done { step(); }
push(stack, frame)
0x7F :: OK
type Handler = fn(Ctx)
emit(Event::Data, payload)
select! { rx => handle(rx) }
spawn(async move { run() })
>> 0x01: PROCESSING
map.insert(k, v)
drain().collect::<Vec<_>>()
let _ = tx.send(msg)
timeout(Duration::ms(100))
>> CHECKSUM PASS
fn encode(src: &[u8]) -> Vec
pipe.write_all(&frame)
crc32(data, len)
>> 0x00FF: ACK
schedule(task, interval)
lock.acquire()
>> SYNC COMPLETE
release(ptr)
0x00 0x00 0x00 0x01
watchdog.reset()
>> LINK ESTABLISHED
fn poll(&mut self) -> Poll
waker.wake_by_ref()
cx.waker().clone()
01101001 01101110
fn init() -> Result<()>
for x in 0..buf.len()
load(addr, 0xFF)
sys.run(0x4A, flags)
if val > 0 { dispatch() }
>> 0x00: READY
loop { poll(); yield; }
}
reg[0x3] = 0b11001010
clk.tick()
assert!(val != null)
>> SIGNAL RECEIVED
buf[i] ^= key[i % klen]
let n = read(fd, buf, 64)
while !done { step(); }
push(stack, frame)
0x7F :: OK
type Handler = fn(Ctx)
emit(Event::Data, payload)
select! { rx => handle(rx) }
spawn(async move { run() })
>> 0x01: PROCESSING
map.insert(k, v)
drain().collect::<Vec<_>>()
let _ = tx.send(msg)
timeout(Duration::ms(100))
>> CHECKSUM PASS
fn encode(src: &[u8]) -> Vec
pipe.write_all(&frame)
crc32(data, len)
>> 0x00FF: ACK
schedule(task, interval)
lock.acquire()
>> SYNC COMPLETE
release(ptr)
0x00 0x00 0x00 0x01
watchdog.reset()
>> LINK ESTABLISHED
fn poll(&mut self) -> Poll
waker.wake_by_ref()
cx.waker().clone()
01101001 01101110
fn init() -> Result<()>
for x in 0..buf.len()
load(addr, 0xFF)
sys.run(0x4A, flags)
if val > 0 { dispatch() }
>> 0x00: READY
loop { poll(); yield; }
stream.flush()
0xDEAD :: 0xBEEF
bind(sock, &addr, len)
pub fn connect(host: &str)
match state {
State::Init => boot(),
State::Run => tick(),
_ => halt(),
}
reg[0x3] = 0b11001010
clk.tick()
assert!(val != null)
>> SIGNAL RECEIVED
buf[i] ^= key[i % klen]
let n = read(fd, buf, 64)
while !done { step(); }
push(stack, frame)
0x7F :: OK
type Handler = fn(Ctx)
emit(Event::Data, payload)
select! { rx => handle(rx) }
spawn(async move { run() })
>> 0x01: PROCESSING
map.insert(k, v)
drain().collect::<Vec<_>>()
let _ = tx.send(msg)
timeout(Duration::ms(100))
>> CHECKSUM PASS
fn encode(src: &[u8]) -> Vec
pipe.write_all(&frame)
crc32(data, len)
>> 0x00FF: ACK
schedule(task, interval)
lock.acquire()
>> SYNC COMPLETE
release(ptr)
0x00 0x00 0x00 0x01
watchdog.reset()
>> LINK ESTABLISHED
fn poll(&mut self) -> Poll
waker.wake_by_ref()
cx.waker().clone()
01101001 01101110
fn init() -> Result<()>
for x in 0..buf.len()
load(addr, 0xFF)
sys.run(0x4A, flags)
if val > 0 { dispatch() }
>> 0x00: READY
loop { poll(); yield; }
stream.flush()
0xDEAD :: 0xBEEF
bind(sock, &addr, len)
pub fn connect(host: &str)
match state {
State::Init => boot(),
State::Run => tick(),
_ => halt(),
push(stack, frame)
0x7F :: OK
type Handler = fn(Ctx)
emit(Event::Data, payload)
select! { rx => handle(rx) }
spawn(async move { run() })
>> 0x01: PROCESSING
map.insert(k, v)
drain().collect::<Vec<_>>()
let _ = tx.send(msg)
timeout(Duration::ms(100))
>> CHECKSUM PASS
fn encode(src: &[u8]) -> Vec
pipe.write_all(&frame)
crc32(data, len)
>> 0x00FF: ACK
schedule(task, interval)
lock.acquire()
>> SYNC COMPLETE
release(ptr)
0x00 0x00 0x00 0x01
watchdog.reset()
>> LINK ESTABLISHED
fn poll(&mut self) -> Poll
waker.wake_by_ref()
cx.waker().clone()
01101001 01101110
fn init() -> Result<()>
for x in 0..buf.len()
load(addr, 0xFF)
sys.run(0x4A, flags)
if val > 0 { dispatch() }
>> 0x00: READY
loop { poll(); yield; }
stream.flush()
0xDEAD :: 0xBEEF
bind(sock, &addr, len)
pub fn connect(host: &str)
match state {
State::Init => boot(),
State::Run => tick(),
_ => halt(),
}
reg[0x3] = 0b11001010
clk.tick()
assert!(val != null)
>> SIGNAL RECEIVED
buf[i] ^= key[i % klen]
let n = read(fd, buf, 64)
while !done { step(); }
push(stack, frame)
0x7F :: OK
type Handler = fn(Ctx)
emit(Event::Data, payload)
select! { rx => handle(rx) }
spawn(async move { run() })
>> 0x01: PROCESSING
map.insert(k, v)
drain().collect::<Vec<_>>()
let _ = tx.send(msg)
timeout(Duration::ms(100))
>> CHECKSUM PASS
fn encode(src: &[u8]) -> Vec
pipe.write_all(&frame)
crc32(data, len)
>> 0x00FF: ACK
schedule(task, interval)
lock.acquire()
>> SYNC COMPLETE
release(ptr)
0x00 0x00 0x00 0x01
watchdog.reset()
>> LINK ESTABLISHED
fn poll(&mut self) -> Poll
waker.wake_by_ref()
cx.waker().clone()
01101001 01101110
fn init() -> Result<()>
for x in 0..buf.len()
load(addr, 0xFF)
sys.run(0x4A, flags)
if val > 0 { dispatch() }
>> 0x00: READY
loop { poll(); yield; }
stream.flush()
0xDEAD :: 0xBEEF
bind(sock, &addr, len)
pub fn connect(host: &str)
match state {
State::Init => boot(),
State::Run => tick(),
_ => halt(),
}
reg[0x3] = 0b11001010
clk.tick()
assert!(val != null)
>> SIGNAL RECEIVED
buf[i] ^= key[i % klen]
let n = read(fd, buf, 64)
while !done { step(); }
drain().collect::<Vec<_>>()
let _ = tx.send(msg)
timeout(Duration::ms(100))
>> CHECKSUM PASS
fn encode(src: &[u8]) -> Vec
pipe.write_all(&frame)
crc32(data, len)
>> 0x00FF: ACK
schedule(task, interval)
lock.acquire()
>> SYNC COMPLETE
release(ptr)
0x00 0x00 0x00 0x01
watchdog.reset()
>> LINK ESTABLISHED
fn poll(&mut self) -> Poll
waker.wake_by_ref()
cx.waker().clone()
01101001 01101110
fn init() -> Result<()>
for x in 0..buf.len()
load(addr, 0xFF)
sys.run(0x4A, flags)
if val > 0 { dispatch() }
>> 0x00: READY
loop { poll(); yield; }
stream.flush()
0xDEAD :: 0xBEEF
bind(sock, &addr, len)
pub fn connect(host: &str)
match state {
State::Init => boot(),
State::Run => tick(),
_ => halt(),
}
reg[0x3] = 0b11001010
clk.tick()
assert!(val != null)
>> SIGNAL RECEIVED
buf[i] ^= key[i % klen]
let n = read(fd, buf, 64)
while !done { step(); }
push(stack, frame)
0x7F :: OK
type Handler = fn(Ctx)
emit(Event::Data, payload)
select! { rx => handle(rx) }
spawn(async move { run() })
>> 0x01: PROCESSING
map.insert(k, v)
drain().collect::<Vec<_>>()
let _ = tx.send(msg)
timeout(Duration::ms(100))
>> CHECKSUM PASS
fn encode(src: &[u8]) -> Vec
pipe.write_all(&frame)
crc32(data, len)
>> 0x00FF: ACK
schedule(task, interval)
lock.acquire()
>> SYNC COMPLETE
release(ptr)
0x00 0x00 0x00 0x01
watchdog.reset()
>> LINK ESTABLISHED
fn poll(&mut self) -> Poll
waker.wake_by_ref()
cx.waker().clone()
01101001 01101110
fn init() -> Result<()>
for x in 0..buf.len()
load(addr, 0xFF)
sys.run(0x4A, flags)
if val > 0 { dispatch() }
>> 0x00: READY
loop { poll(); yield; }
stream.flush()
0xDEAD :: 0xBEEF
bind(sock, &addr, len)
pub fn connect(host: &str)
match state {
State::Init => boot(),
State::Run => tick(),
_ => halt(),
}
reg[0x3] = 0b11001010
clk.tick()
assert!(val != null)
>> SIGNAL RECEIVED
buf[i] ^= key[i % klen]
let n = read(fd, buf, 64)
while !done { step(); }
push(stack, frame)
0x7F :: OK
type Handler = fn(Ctx)
emit(Event::Data, payload)
select! { rx => handle(rx) }
spawn(async move { run() })
>> 0x01: PROCESSING
map.insert(k, v)
bind(sock, &addr, len)
pub fn connect(host: &str)
match state {
State::Init => boot(),
State::Run => tick(),
_ => halt(),
}
reg[0x3] = 0b11001010
clk.tick()
assert!(val != null)
>> SIGNAL RECEIVED
buf[i] ^= key[i % klen]
let n = read(fd, buf, 64)
while !done { step(); }
push(stack, frame)
0x7F :: OK
type Handler = fn(Ctx)
emit(Event::Data, payload)
select! { rx => handle(rx) }
spawn(async move { run() })
>> 0x01: PROCESSING
map.insert(k, v)
drain().collect::<Vec<_>>()
let _ = tx.send(msg)
timeout(Duration::ms(100))
>> CHECKSUM PASS
fn encode(src: &[u8]) -> Vec
pipe.write_all(&frame)
crc32(data, len)
>> 0x00FF: ACK
schedule(task, interval)
lock.acquire()
>> SYNC COMPLETE
release(ptr)
0x00 0x00 0x00 0x01
watchdog.reset()
>> LINK ESTABLISHED
fn poll(&mut self) -> Poll
waker.wake_by_ref()
cx.waker().clone()
01101001 01101110
fn init() -> Result<()>
for x in 0..buf.len()
load(addr, 0xFF)
sys.run(0x4A, flags)
if val > 0 { dispatch() }
>> 0x00: READY
loop { poll(); yield; }
stream.flush()
0xDEAD :: 0xBEEF
bind(sock, &addr, len)
pub fn connect(host: &str)
match state {
State::Init => boot(),
State::Run => tick(),
_ => halt(),
}
reg[0x3] = 0b11001010
clk.tick()
assert!(val != null)
>> SIGNAL RECEIVED
buf[i] ^= key[i % klen]
let n = read(fd, buf, 64)
while !done { step(); }
push(stack, frame)
0x7F :: OK
type Handler = fn(Ctx)
emit(Event::Data, payload)
select! { rx => handle(rx) }
spawn(async move { run() })
>> 0x01: PROCESSING
map.insert(k, v)
drain().collect::<Vec<_>>()
let _ = tx.send(msg)
timeout(Duration::ms(100))
>> CHECKSUM PASS
fn encode(src: &[u8]) -> Vec
pipe.write_all(&frame)
crc32(data, len)
>> 0x00FF: ACK
schedule(task, interval)
lock.acquire()
>> SYNC COMPLETE
release(ptr)
0x00 0x00 0x00 0x01
watchdog.reset()
>> LINK ESTABLISHED
fn poll(&mut self) -> Poll
waker.wake_by_ref()
cx.waker().clone()
01101001 01101110
fn init() -> Result<()>
for x in 0..buf.len()
load(addr, 0xFF)
sys.run(0x4A, flags)
if val > 0 { dispatch() }
>> 0x00: READY
loop { poll(); yield; }
stream.flush()
0xDEAD :: 0xBEEF
>> SIGNAL RECEIVED
buf[i] ^= key[i % klen]
let n = read(fd, buf, 64)
while !done { step(); }
push(stack, frame)
0x7F :: OK
type Handler = fn(Ctx)
emit(Event::Data, payload)
select! { rx => handle(rx) }
spawn(async move { run() })
>> 0x01: PROCESSING
map.insert(k, v)
drain().collect::<Vec<_>>()
let _ = tx.send(msg)
timeout(Duration::ms(100))
>> CHECKSUM PASS
fn encode(src: &[u8]) -> Vec
pipe.write_all(&frame)
crc32(data, len)
>> 0x00FF: ACK
schedule(task, interval)
lock.acquire()
>> SYNC COMPLETE
release(ptr)
0x00 0x00 0x00 0x01
watchdog.reset()
>> LINK ESTABLISHED
fn poll(&mut self) -> Poll
waker.wake_by_ref()
cx.waker().clone()
01101001 01101110
fn init() -> Result<()>
for x in 0..buf.len()
load(addr, 0xFF)
sys.run(0x4A, flags)
if val > 0 { dispatch() }
>> 0x00: READY
loop { poll(); yield; }
stream.flush()
0xDEAD :: 0xBEEF
bind(sock, &addr, len)
pub fn connect(host: &str)
match state {
State::Init => boot(),
State::Run => tick(),
_ => halt(),
}
reg[0x3] = 0b11001010
clk.tick()
assert!(val != null)
>> SIGNAL RECEIVED
buf[i] ^= key[i % klen]
let n = read(fd, buf, 64)
while !done { step(); }
push(stack, frame)
0x7F :: OK
type Handler = fn(Ctx)
emit(Event::Data, payload)
select! { rx => handle(rx) }
spawn(async move { run() })
>> 0x01: PROCESSING
map.insert(k, v)
drain().collect::<Vec<_>>()
let _ = tx.send(msg)
timeout(Duration::ms(100))
>> CHECKSUM PASS
fn encode(src: &[u8]) -> Vec
pipe.write_all(&frame)
crc32(data, len)
>> 0x00FF: ACK
schedule(task, interval)
lock.acquire()
>> SYNC COMPLETE
release(ptr)
0x00 0x00 0x00 0x01
watchdog.reset()
>> LINK ESTABLISHED
fn poll(&mut self) -> Poll
waker.wake_by_ref()
cx.waker().clone()
01101001 01101110
fn init() -> Result<()>
for x in 0..buf.len()
load(addr, 0xFF)
sys.run(0x4A, flags)
if val > 0 { dispatch() }
>> 0x00: READY
loop { poll(); yield; }
stream.flush()
0xDEAD :: 0xBEEF
bind(sock, &addr, len)
pub fn connect(host: &str)
match state {
State::Init => boot(),
State::Run => tick(),
_ => halt(),
}
reg[0x3] = 0b11001010
clk.tick()
assert!(val != null)
crc32(data, len)
>> 0x00FF: ACK
schedule(task, interval)
lock.acquire()
>> SYNC COMPLETE
release(ptr)
0x00 0x00 0x00 0x01
watchdog.reset()
>> LINK ESTABLISHED
fn poll(&mut self) -> Poll
waker.wake_by_ref()
cx.waker().clone()
01101001 01101110
fn init() -> Result<()>
for x in 0..buf.len()
load(addr, 0xFF)
sys.run(0x4A, flags)
if val > 0 { dispatch() }
>> 0x00: READY
loop { poll(); yield; }
stream.flush()
0xDEAD :: 0xBEEF
bind(sock, &addr, len)
pub fn connect(host: &str)
match state {
State::Init => boot(),
State::Run => tick(),
_ => halt(),
}
reg[0x3] = 0b11001010
clk.tick()
assert!(val != null)
>> SIGNAL RECEIVED
buf[i] ^= key[i % klen]
let n = read(fd, buf, 64)
while !done { step(); }
push(stack, frame)
0x7F :: OK
type Handler = fn(Ctx)
emit(Event::Data, payload)
select! { rx => handle(rx) }
spawn(async move { run() })
>> 0x01: PROCESSING
map.insert(k, v)
drain().collect::<Vec<_>>()
let _ = tx.send(msg)
timeout(Duration::ms(100))
>> CHECKSUM PASS
fn encode(src: &[u8]) -> Vec
pipe.write_all(&frame)
crc32(data, len)
>> 0x00FF: ACK
schedule(task, interval)
lock.acquire()
>> SYNC COMPLETE
release(ptr)
0x00 0x00 0x00 0x01
watchdog.reset()
>> LINK ESTABLISHED
fn poll(&mut self) -> Poll
waker.wake_by_ref()
cx.waker().clone()
01101001 01101110
fn init() -> Result<()>
for x in 0..buf.len()
load(addr, 0xFF)
sys.run(0x4A, flags)
if val > 0 { dispatch() }
>> 0x00: READY
loop { poll(); yield; }
stream.flush()
0xDEAD :: 0xBEEF
bind(sock, &addr, len)
pub fn connect(host: &str)
match state {
State::Init => boot(),
State::Run => tick(),
_ => halt(),
}
reg[0x3] = 0b11001010
clk.tick()
assert!(val != null)
>> SIGNAL RECEIVED
buf[i] ^= key[i % klen]
let n = read(fd, buf, 64)
while !done { step(); }
push(stack, frame)
0x7F :: OK
type Handler = fn(Ctx)
emit(Event::Data, payload)
select! { rx => handle(rx) }
spawn(async move { run() })
>> 0x01: PROCESSING
map.insert(k, v)
drain().collect::<Vec<_>>()
let _ = tx.send(msg)
timeout(Duration::ms(100))
>> CHECKSUM PASS
fn encode(src: &[u8]) -> Vec
pipe.write_all(&frame)
← JOURNAL
PUBLIC5 min read

Free TV From Facebook — One Dead MOSFET

hardwaremakerreverse-engineeringrepairelectronicsevening-hack

Someone listed a 65-inch Sony Bravia KD-65XG8096 on Facebook. "Faulty — backlight on but no picture. One board replaced." Free to collect.

That's my kind of evening.


What We Had

A 2019 Sony KD-65XG8096. 4K, Android TV, 258W. The previous owner had already swapped the T-con board trying to fix it. It didn't help. They gave up and listed it for free.

Model label — Sony KD-65XG8096, December 2019

On power-up: solid white LED (no fault codes), backlight clearly on behind the panel, but absolutely nothing on screen. No Sony logo on boot. No menu. Nothing. HDMI audio worked — you could hear content playing through the speakers. The TV thought it was running normally.


Ruling Things Out

The symptoms — backlight on, audio working, no picture, no error codes — point to the signal chain between the main board and the panel. The T-con had already been replaced, but that doesn't mean the T-con was ever the problem.

First test: disconnect the LVDS cable from the T-con and power on. On some Sony sets this triggers a built-in test pattern. We got grey — same grey with or without the LVDS cable connected. That told us the T-con wasn't driving the panel at all.

T-con board installed — BOE panel, Novatek NT53186

We swapped in the original T-con to rule out a bad replacement. Same result. Two different T-con boards, same dead screen. The T-con was never the fault.


Opening It Up

Back panel off. Three boards inside: main board (Sony BCX, handles HDMI/processing/Android), power supply (generates all the voltage rails), and the T-con (drives the LCD panel).

Full teardown — all three boards exposed

Main board — Sony BCX with heatsink over the SoC

The main board was clearly alive — processing HDMI, outputting audio, responding to the remote, accepting a firmware update from USB. Everything worked except sending a picture to the panel.


The Power Supply Told Us Everything

The power supply board had something most boards don't: a full pinout silkscreened right next to the main connector.

Power supply pinout — every rail labelled

Right there at the bottom: TCON_ON and TCON_VCC12V. The T-con gets its own dedicated 12V power rail from the power supply, switched by an enable signal from the main board.

We started probing:

| Pin | Expected | Measured | |-----|----------|----------| | TCON_ON | 3.3V (enable) | 3.3V | | REG12V | 12V | 12V | | TCON_VCC12V | 12V | 3.3V |

The enable signal was there. The 12V source was there. But the T-con's 12V output was reading 3.3V — just bleedthrough from the enable line. The switching circuit between REG12V and TCON_VCC12V was dead.


The MOSFET

On Sony power supply boards, a MOSFET switches the REG12V rail through to become TCON_VCC12V when the TCON_ON signal goes high. We found it near the connector — a Toshiba TK8A50D, N-channel, 500V 8A, TO-220 package.

Readings with the TV powered on:

| Pin | Expected | Measured | |-----|----------|----------| | Gate (left) | 3-5V | ~5V | | Drain (middle) | 12V | ~8V | | Source (right) | 12V | Fluctuating/resistive |

The gate was being driven. But instead of passing 12V cleanly from drain to source, it was dragging the drain down to 8V and giving a messy, unstable output. A healthy MOSFET with 5V on the gate should be fully on with near-zero voltage drop. This one was partially conducting — breaking down internally.

One dead MOSFET. That's the entire fault.


The Misdiagnosis Chain

This is a known failure pattern on Sony Bravia 65" TVs. The symptoms are misleading:

  1. Backlight on, no picture — looks like a T-con fault
  2. Previous owner replaces T-con — no change
  3. Previous owner gives up — lists TV as "faulty, one board replaced"

The T-con was never the problem. It wasn't getting power. A single MOSFET on the power supply wasn't switching the 12V rail through, so the T-con had no juice to drive the panel. Every other function — Android, HDMI, audio, backlight — runs off different rails and worked perfectly.

The replacement part is a TK8A50D or equivalent (TK8A55DA, TK8A60DA). TO-220 package. Under a fiver.


The Setup

This whole session was me on the bench with Claude running research in real-time — pulling service data, cross-referencing fault patterns on repair forums, identifying the switching circuit topology from the PSU pinout, and narrowing the diagnosis while I had probes on the board. AI doing the research, human doing the physical work. It's a good way to operate.

T-con board — BOE, Novatek NT53186, date code 2018


Status

Fault identified. Single MOSFET (TK8A50D) on the power supply board, failing to switch 12V to the T-con. Part on order. Once it's soldered in, this should be a working 65-inch 4K TV — rescued from a Facebook free listing for the cost of a single component.

The previous owner spent money on a T-con board that was never broken. The actual fault was a component worth less than a coffee.

That's why you probe before you swap.

// FEEDBACK

LEAVE A COMMENT

← BACK TO JOURNAL