BK7231GUIFlashTool v98+ adds CH341-based SPI flashing and recovery for Beken BK7231/BK7252 chips, including bricked devices with overwritten bootloaders.
The tool uses CH341 DLL C# bindings to toggle CEN via D2, reset the chip, send 0xD2, then flash Beken chips like generic SPI memory.
Connections use P20, P21, P22, and P23 for SCK, CSN, SI, and SO, with CEN wired to D2 and the CH341 jumper set to I2C mode.
A sample read identifies JEDEC ID FF-EF-40-16 and a 4096 KB flash, and the same tool can Read, Write, Verify, and Erase firmware.
If CH341 is not detected or CEN toggle fails, check driver configuration, jumper position, SPI wiring, and power before trying Beken SPI mode again.
Wait, so.. the way you access DTR pins matter? C# api does not work on hub but winapi does? I was sure it goes through the same API...
perhaps more testing required on my part to be sure, if it's even necessary to consider going further. I did try to replicate esptool as close as possible with tweaked code.
I believe so. It's had extensive testing, revising and checks, but I appreciate there are a lot of changes. If there's anything you want me to check again, I can.
It did work, I don't recall the speed, but it almost(?) always needs a second try for the first didn't get the serial port. I didn't care, might also be a Linux/mono issue...
Ok guys @divadiow@insmod@max4elektroda Is there anything more that we can add to Easy Flasher now?
I am asking because... have you seen this topic?
https://www.elektroda.com/rtvforum/topic4163834.html I am planning to attempt flasher reimplementation in Flutter, so it would be good to have a "complete" version of flasher done first in C#.
Which features are still missing from Easy Flasher and could be added relatively easily?
So my plan for my next days (depending on free time) is a Flutter port, depending on how well it goes, probably starting with Beken. Any general hints or insights on that? Probably I will use a separate repo for that.
Do we have any crucial design mistakes or problems that we can avoid on the rewrite, etc?
But don't worry too much about it - it's just an experiment, I am not going to kill old flasher.
The only aspect I would bring in atm is maybe to rethink the tuya config parser.
I'm still in a testing mode, but I would think your(!) idea to have common base for analyzing the config would be great.
"mappings": [
{ "search": "/^rl_on(\\d+)_pin$/", "role": "BridgeFWD", "desc": "- Bridge Relay On (channel {number}) on P{value}" },
{ "search": "/^rl_off(\\d+)_pin$/", "role": "BridgeREV", "desc": "- Bridge Relay Off (channel {number}) on P{value}" },
{ "search": "/^rl(\\d+)_pin$/", "role": "Rel", "desc": "- Relay (channel {number}) on P{value}" },
{ "search": "/^led(\\d+)_pin$/", "role": "LED", "desc": "- LED (channel {number}) on P{value}" },
{ "search": "/^door(\\d+)_magt_pin$/", "role": "dInput", "desc": "- Door Sensor (channel {number}) on P{value}" },
{ "search": "/^bt(\\d+)_pin$/", "role": "Btn", "desc": "- Button (channel {number}) on P{value}" },
{ "search": "/^k(\\d+)pin_pin$/", "role": "Btn", "desc": "- Button (channel {number}) on P{value}" },
{ "search": "/^onoff(\\d+)$/", "role": "TglChanOnTgl", "desc": "- TglChannelToggle (channel {number}) on P{value}" },
{ "search": "/^netled(\\d*)_pin$/", "role": "WifiLED_n", "desc": "- WiFi LED on P{value}", "nochan": true },
{ "search": "gate_sensor_pin_pin", "role": "dInput", "desc": "- Door/Gate Sensor on P{value}", "nochan": true },
{ "search": "basic_pin_pin", "role": "dInput", "desc": "- PIR sensor on P{value}", "nochan": true },
{ "search": "ele_pin", "role": "BL0937CF", "desc": "- BL0937 ELE on P{value}", "nochan": true },
{ "search": "epin", "role": "BL0937CF", "desc": "- EPIN (alias for ele_pin) on P{value}", "nochan": true },
{ "search": "vi_pin", "role": "BL0937CF1", "desc": "- BL0937 VI on P{value}", "nochan": true },
{ "search": "ivpin", "role": "BL0937CF1", "desc": "- BL0937 VI (ivpin) on P{value}", "nochan": true },
{ "search": "sel_pin_pin", "role": "BL0937SEL", "desc": "- BL0937 SEL on P{value}", "nochan": true },
{ "search": "ivcpin", "role": "BL0937SEL", "desc": "- BL0937 SEL (ivcpin) on P{value}", "nochan": true },
It should also be possible to include to TuyaConfig.cs, but I didn't get that far (yet).
At least copilot made a first version I don't know how to test it ...
But I don't think this is first priority if this part is in your goal of a flasher rewrite at all?!?
And I must admit, I somehow missed that "Multi-platform support for USB to UART" thread.
I can't think of a feature I'd really like to see in EF. I did wonder about a terminal, but there are other tools for that, and EF main window is too small perhaps.
My thoughts are mostly with refining existing features. Eg, it's not immediately obvious which platforms support erase all function and if that's a full erase or partial.
Added after 2 [minutes]:
max4elektroda wrote:
The only aspect I would bring in atm is maybe to rethink the tuya config parser.
yes. this would be cool still.
Would make adding new mappings easier. Thinking of this for the future:https://www.elektroda.com/rtvforum/topic4065311.html#21834399
Added after 1 [hours] 8 [minutes]:
max4elektroda wrote:
At least copilot made a first version I don't know how to test it
If you mean testing how I think you mean, I was using some node thing to replace .vue files called by web app with a stash of local copies I was making changes to, then I remembered we can just change the web app URL!
so now I just run this in the webapp root and browse to test device as normal
At least copilot made a first version I don't know how to test it
If you mean testing how I think you mean, I was using some node thing to replace .vue files called by web app with a stash of local copies I was making changes to, then I remembered we can just change the web app URL!
I meant the C# code (TuyaConfig.cs) as part of the flashers "Extract Config from Tuya binary" tool.
So, flasher will have main pins tables for Tuya Config and will export JS?
Almost. I was thinking of one common json file with all the matching information which is used both in TemplateParser and in TuyaConfig.
JS can include json, that already works, and C# should also be able to use this (at least in theory) with
using System.Text.Json;
using System.Text.Json.Serialization;
I already have a changed TuyaConfig.cs but I'm not sure how I can test it, how to "build" my own BK7231Flasher.exe.
just playing with _lv values and their potential inclusion in Easy Flasher config of OBK on extraction after original firmware backup (plus plain-text indicator), eg:
but I notice only after a REAL backup/extraction from device do we see the extractions show under the configuration form in main flasher tab
so no visibility of OBK roles that will be assigned until you do it for real. is this correct? am I missing something obvious?
Yes, you can copy json to one of the importer forms in web app or cloudcutter page, but then you're not using EF's logic.
read retries: - Per-chunk retry (3 attempts per 4KB DumpBytes chunk) — if a single chunk read fails, it retries before giving up on the window
- Per-window retry (3 attempts per 256KB window) — if the SHA256 of the whole window doesn't match after all chunks read, the entire window is re-read from scratch, with a re-link attempt between tries
(two independent retry layers — a window can survive up to 3 chunk-level failures per chunk AND up to 3 full window re-reads if verification keeps failing)
write retries: - Per-window retry (3 attempts per 256KB window) — if XMODEM transfer or post-write hash verify fails, the window is re-sent, with baud fallback to 115200 and re-link between attempts
-Final full-image hash cross-check on completion
-Baud fallback to 115200 on baud change failure
-Hash polling uses 200ms slices so Stop button remains responsive
-ChangeBaud rewritten with two-attempt handshake and verified OK response
-Should cleanup com port/release buttons on all exit paths
-Port open/close lifecycle made safe and idempotent
-TryPingLink added with configurable retry count
-RunWithRecovery / RunWithRecoveryBytes wrappers added — all major operations (hash read, flash transmit) retry with re-link on failure rather than giving up immediately
-ReadTimeout stack introduced so nested operations can push/pop timeouts safely without leaving the port in an inconsistent state
-MemoryBoot command table scan: null return from DumpBytes no longer throws silently — skips the entry and continues scanning
-ReadFlashId: null return from DumpBytes now throws a clear exception rather than causing a NullReferenceException on the next line; calling code in doRead catches it cleanly with port close and error message
-ChangeBaud failure in read and write: now closes the port before returning, preventing GUI lockup
-flash pin detection (A7_A12 or B6_B12)
-update erase all confirmation box text to make clear erase support on each platform
-make erase all button and com port release after completion for all platforms
✨ BK7231GUIFlashTool version 98 and later introduces a new SPI flashing method for Beken BK7231/BK7252 devices using only a CH341 SPI programmer. This method enables recovery of bricked devices with overwritten bootloaders and functions as a general-purpose SPI flasher supporting various memory chips. The approach builds on previous SPI programming techniques using Python and Banana Pi, adapting them for CH341 hardware and C# implementation. Required hardware includes a CH341 programmer and soldering tools for wire attachment. Recent user feedback on version 98 highlights issues such as the tool requiring a COM port selection in SPI mode, lack of CH341A detection warnings, and missing ch341dll.dll errors. The developer has addressed the COM port requirement and plans to add the missing DLL, requesting further debugging via Visual Studio to handle CH341 initialization exceptions. Generated by the language model.
TL;DR: New BK7231GUIFlashTool v98+ adds SPI flashing for Beken chips; sample 4,096 KB flash detected. “Only a CH341 SPI programmer is required.” Use CH341A D2 to toggle CEN, send 0xD2, then read/write like generic SPI. [Elektroda, p.kaczmarek2, post #21711721]
Why it matters: It lets you recover bricked BK7231/BK7252 devices without a working bootloader, using low‑cost tools.
Who this is for: DIYers, repair techs, and firmware engineers asking how to unbrick or mass‑flash Beken SoCs via SPI with a CH341A and the latest tool.
What exactly is the new Beken SPI flashing method and what do I need?
The tool drives CH341A as an SPI master, resets BK via CEN on D2, sends 0xD2 to enter BK’s SPI-memory mode, then treats the chip like a standard SPI flash. You need a CH341A (jumper at I2C), 3.3 V power, and wiring for P20–P23 (SCK/CSN/SI/SO) plus CEN. Select “Beken SPI” in BK7231GUIFlashTool v98+. “Only a CH341 SPI programmer is required.” [Elektroda, p.kaczmarek2, post #21711721]
How do I wire CH341A to BK7231/BK7252 for SPI mode?
Connect CH341A SCK→P20, CS0→P21, MOSI→P22 (SI), MISO→P23 (SO), and D2→CEN. Keep MOSI→SI and MISO→SO mapping. Provide GND and target power. Some boards have pads labeled CE/TCK/TMS/TDI/TDO that map to CEN/SCK/CSN/SI/SO respectively. [Elektroda, p.kaczmarek2, post #21711721]
How do I reliably enter BK SPI mode? (3‑step)
Use CH341 D2 to pull CEN low then high to reset the BK chip. 2. Stream 0xD2 bytes repeatedly over SPI. 3. Issue 0x9F and confirm a valid JEDEC response; then proceed to Read/Write/Erase. [Elektroda, p.kaczmarek2, post #21711721]
I get “Failed to open CH341 device” or “Failed to toggle CEN.” What should I check?
Confirm CH341A is jumpered to I2C, recognized by Windows, and the D2 wire is soldered to CEN. Re‑seat USB, power the target, and verify SPI lines. The tool logs these errors when CH341 isn’t detected or CEN can’t be driven; fix wiring or driver, then retry. [Elektroda, p.kaczmarek2, post #21711721]
The app says “missing ch341dll.dll” or quits in SPI mode—how do I fix that?
Place CH341DLL.DLL alongside the GitHub build, or build from source in Visual Studio. Earlier builds could exit if CH341A wasn’t present; recent fixes improved handling, but adding the DLL resolved missing‑library errors during testing. [Elektroda, divadiow, post #21712310]
Do I need to select a COM port for SPI flashing?
No. As of v99, SPI mode does not require a COM port. This was confirmed after fixes; previous v98 prompts were removed. Ensure CH341A is connected; SPI operations run without a serial port. [Elektroda, divadiow, post #21712310]
What does the Verify button do?
Verify compares flash contents against the firmware file currently selected in the tool. Use it after Write or Erase to confirm success. “Verify verifies against selected firmware.” [Elektroda, p.kaczmarek2, post #21712551]
Can this recover a bricked BK7252 camera?
Yes. After wiring CEN and SPI lines, use Beken SPI mode to read/erase/write. The author provides a BK7252 camera recovery example using this exact method with CH341A and the new flasher. [Elektroda, p.kaczmarek2, post #21711721]
Can I use CH341 Programmer or NeoProgrammer once SPI mode is active?
Yes. After the 0xD2 hand‑off, the BK behaves like a generic SPI flash. You can then operate with common SPI flash tools (CH341 Programmer or NeoProgrammer) if you prefer. [Elektroda, p.kaczmarek2, post #21711721]
Linux support: what baud rates are stable under mono?
Mono 6.12 worked for testers. They reported stable operation at 921,600 baud; 1,500,000 worked on Windows, but they lowered to 921,600 on Linux. LAN Scanner and release downloader also worked. [Elektroda, insmod, post #21712663]
The tool shows a 4,096 KB device. Is that normal for these chips?
Yes. A sample JEDEC ID FF‑EF‑40‑16 decoded to 4,096 KB and printed by the tool. That confirms JEDEC read and size decoding in SPI mode. Actual sizes vary by module; always check the tool’s detected flash size. [Elektroda, p.kaczmarek2, post #21711721]
How do I just switch a BK device into SPI mode without reading or writing?
Use the new “Detect” button. It performs a zero‑length custom operation to toggle CEN and send the 0xD2 sync, placing the chip in SPI mode for use with other SPI tools. [Elektroda, p.kaczmarek2, post #21731041]
I flashed many times and now erase fails. What should I try?
Expand Unprotect logic before erase, similar to AsProgrammer. A contributor noted needing stronger Unprotect after many BK7252 cycles. Add an Unprotect/Status-Register release step, then retry the erase/write. [Elektroda, p.kaczmarek2, post #21714737]
What is OpenBeken (OBK) in this context?
OpenBeken is an open‑source firmware used across supported Wi‑Fi MCUs in this ecosystem. The author uses OBK devices for testing and demos, including camera boards and remote flashing concepts. [Elektroda, p.kaczmarek2, post #21714427]
Can I flash a BK device over Wi‑Fi/TCP instead of USB?
Yes, a Wi‑Fi flasher demo proxies UART over TCP and controls CEN via an OBK device. It’s a separate utility that mirrors the BK UART routines, useful when PC‑to‑target wiring is hard. [Elektroda, p.kaczmarek2, post #21720013]
Any known edge cases or failure symptoms I should expect?
If CH341DLL is missing, some GitHub builds previously exited. On mono/Linux, 1,500,000 baud may fail while 921,600 works. Also, after heavy cycling, protection bits may block erase until Unprotect expands. Address each symptom as noted, then retry. [Elektroda, divadiow, post #21712310]