logo elektroda
logo elektroda
X
logo elektroda

Creating a simple BW16E (RTL8720DN) DIY flash tool command line utility

p.kaczmarek2 408 23
ADVERTISEMENT
📢 Listen (AI):
  • Creating a simple BW16E (RTL8720DN) DIY flash tool command line utility
    I've been recently experimenting with simple flashing code for BW16E (RTL8720DN AmebaD) board, in theory also working for any of RTL872xDx family. RTL8720DN is a WiFi (2.4GHz and 5GHz) and Bluetooth (LE 5.0) module that features dual core CPU using KM4 and KM0 cores. It can be bought for as low as 1$. Here I will show my experiences with programming this board and briefly describe the flashing process.
    Creating a simple BW16E (RTL8720DN) DIY flash tool command line utility Creating a simple BW16E (RTL8720DN) DIY flash tool command line utility
    The goal of this topic will be to create a simple C# flash tool that can write OpenBeken firwmare port to RTL8720DN.

    First experiments
    I've started by looking for simple and easy to use flashers supporting RTL8720DN. After some time, I've decided to RTL872xDx python tool.rar that was shown previously on our forum. Reading seemed to work well, however we had to add longer delay to function waiting for MCU response. Read command:
    
    python rtltool.py -p COM7 -b1500000 rf 0x0 0x400000 bw16_rtltool.bin
    

    I couldn't get it to write, though. It worked for other boards, but failed on RTL8720DN every time:
    
    python rtltool.py -p COM4 -b 100000 wf 0 ff1_4mb.bin

    Error message was:
    
    error: Set Flash Status

    Same problem was reported by other users. I played around with the code and figured out that the culprit is the unsupported flash unprotect, which seems to work on other RTLs, but breaks on RTL8720. Commenting it out solved the issue and flashing proceeded correctly.



    Simple flasher implementation
    My simple flasher is available on Github, here:
    https://github.com/openshwprojects/SharpRTL872xTool
    Released repository also contains sample scripts and dumps:
    https://github.com/openshwprojects/SharpRTL872xTool/tree/main/samples
    If there is no imgtool_flashloader_amebad.bin next to downloaded exe, make sure to download it from there!

    The flash read procedure seems fairly simple. It can be divided into the following steps:
    - first, MCU is put in flashing mode and reset via RTS/DTS pins
    - next, a simple xmodem loader code is read from file and put into the device RAM (this step is skipped if code section header bytes are already present in RAM)
    - finally, flash is read in 1024/128 chunks via Xmodem protocol
    Similar approach is used for flash write, altough then, first required sectors are erased and then written.

    Let's consider procedure in details.

    Initial reset sequence
    BW16E board, like many other boards, features RESET and BOOT pins. They are controlled via CH340 DTR and RTS lines. Boot must be held low while RESET is released in order to enter flashing mode.
    Code: C#
    Log in, to see the code


    Command system
    Command system is very simple. First N bytes are written and then flasher waits for a single expected byte. If no expected response is met, then communication is assumed to have failed. I am suprised by the simplicity of this approach, I was rather expecting at least some kind of CRC check somewhere in the way, but original rtltool is missing it as well.
    Code: C#
    Log in, to see the code

    Baud setting
    Baud setting is tricky, because the MCU would just lose the communication if not notified about change. That's why there is a specific packet that first sends new value to the MCU, then waits for acknowledge, and then, finally, adjusts the baud.
    Code: C#
    Log in, to see the code


    Writing RAM code
    To communicate with flash memory, a helper binary (imgtool_flashloader_amebad.bin) must be uploaded into MCU SRAM. This file contains the flashloader used by Realtek’s official tools. Before uploading, the flasher checks whether the RAM already contains a valid loader by examining the first 4 bytes. If not present, the file is sent using XMODEM protocol.
    Code: C#
    Log in, to see the code

    NOTE: 33 dec is 0x21 hex, and so on.
    Creating a simple BW16E (RTL8720DN) DIY flash tool command line utility

    Writing memory
    After RAM is loaded with the loader code, commands like erase, write, and read can be executed. Writing uses XMODEM and automatically breaks data into 1024 or 128 byte chunks, depending on how much remains.
    Code: C#
    Log in, to see the code



    Test scripts
    To verify and experiment with the flasher tool, I prepared several simple batch scripts that perform common operations such as erasing, writing, and reading flash memory. These scripts automate the command line usage of the flasher executable and help to easily reproduce basic flash operations.

    The first script, erase_4mb.cmd, erases the first 4 megabytes of flash starting at address 0. This is useful for clearing the entire main flash region before writing new firmware or data. OpenBeken was not booting correctly without it! The erase command (ef) takes the start address and length as parameters:
    
    RTL872xDx_Flasher.exe -p COM3 -b 1500000 ef 0 0x400000
    pause
    

    Next, write_obk.cmd writes a full firmware image file to the flash memory starting at address 0. This script is essential for flashing a new program image to the device after erasing:
    
    RTL872xDx_Flasher.exe -p COM3 -b 1500000 wf 0 OpenRTL8720D_1.18.135.bin
    pause
    

    OpenBeken then should be able to boot:
    Creating a simple BW16E (RTL8720DN) DIY flash tool command line utility
    Creating a simple BW16E (RTL8720DN) DIY flash tool command line utility

    However, I've added some more test scripts. They operate on smaller flash section, so are quicker to run.
    For a simple test, try erase_4096.cmd and then read_4096_dump_bin.cmd, you should get:
    Creating a simple BW16E (RTL8720DN) DIY flash tool command line utility
    After doing write_lorem_ipsum.cmd the read_4096_dump_bin.cmd should give:
    Creating a simple BW16E (RTL8720DN) DIY flash tool command line utility
    Similary, read back after write_obk.cmd should show:
    Creating a simple BW16E (RTL8720DN) DIY flash tool command line utility
    This way you can reliably check whether read and write works.

    Summary
    The mentioned repository should provide a basic method for flashing RTL8720DN. I am not sure if it will work for other RTLs from the same family, as I omited the flash protection code. Soon I'm going to try them as well, but first I will most likely integrate ported code with our easy flasher
    Do you have any similar RTL boards? Let us know if this flashing solution works for you!

    Cool? Ranking DIY
    Helpful post? Buy me a coffee.
    About Author
    p.kaczmarek2
    Moderator Smart Home
    Offline 
    p.kaczmarek2 wrote 12116 posts with rating 10107, helped 579 times. Been with us since 2014 year.
  • ADVERTISEMENT
  • #2 21605786
    divadiow
    Level 34  
    RTL872xDx_Flasher.exe -p COM45 -b 1500000 rf 0 0x400000 dump.bin

    Code: Text
    Log in, to see the code


    success.

    With EF v24 the RTL8720DN read currently makes EF quit when sending stub

    Creating a simple BW16E (RTL8720DN) DIY flash tool command line utility
  • ADVERTISEMENT
  • #3 21605829
    p.kaczmarek2
    Moderator Smart Home
    What? Easy Flasher can't read RTL? Let me check...
    Creating a simple BW16E (RTL8720DN) DIY flash tool command line utility
    Ah wait, you don't have stub!
    Creating a simple BW16E (RTL8720DN) DIY flash tool command line utility
    Helpful post? Buy me a coffee.
  • #4 21605841
    divadiow
    Level 34  
    oh. ok sure. I assumed it was embedded in somehow already. cool

    Screenshot of a chat conversation in Polish about functionality and integration.
  • #5 21605855
    p.kaczmarek2
    Moderator Smart Home
    Do you have other RTLs from the same family to try? Do they need flash unprotect?
    Helpful post? Buy me a coffee.
  • #6 21605865
    divadiow
    Level 34  
    negative. I never did get a WBRG1 in the end. @insmod and @DeDaMrAz have that module though.

    I only have CR3L/RTL8720CM and RTL8720CF options - Z2
  • #7 21605869
    p.kaczmarek2
    Moderator Smart Home
    I see.... I am considering next steps to take now, of course, first I will port write to Easy Flasher, and then, maybe this:
    https://github.com/openshwprojects/FlashTools/tree/main/Realtek/AmebaZ_FlashTool
    Or LN882H.
    Helpful post? Buy me a coffee.
  • ADVERTISEMENT
  • #9 21605920
    p.kaczmarek2
    Moderator Smart Home
    Which of those RTLs support variable flash size (i.e. external flash memory)?
    Helpful post? Buy me a coffee.
  • ADVERTISEMENT
  • #12 21606055
    insmod
    Level 25  
    Usually, if chip last letter is F - means embedded flash, M - external.
    All RTL8710B have external flash.
    Almost all RTL8720D/CS except RTL8720DF (4mb), Normal BW16 usually comes with 2MB flash chip, which i successfully replaced with 4MB on one module. WBRG1 of course comes with 8MB.
    RTL8721DAx/RTL8721DCx/RTL8721DGx (all amebadplus) if F - 4mb integrated, if M - external.
    Same with AmebaZ2 (CF - 2mb embedded, CM/CN/CX - external) and Ameba1 (AF - 1mb embedded, AM - external)
    RTL8720E (EAF - 4 or 8mb embedded, EAM - external)
  • #13 21606153
    p.kaczmarek2
    Moderator Smart Home
    So if I unshield the board from the topic, then I can give it like 8MB flash or something, like it's often done with ESP? Nice, gotta try someday.

    Easy Flasher progress report - read and write are almost fully integrated now. There are still some issues coming from the fact that tool was designed with only Beken in mind, but hopefully I will manage to tidy it up a bit more.
    Screenshot of Easy Flasher software showing progress in reading and writing flash memory.
    We need to check is there a way to auto-detect RTL flash size.
    Helpful post? Buy me a coffee.
  • Helpful post
    #14 21606159
    insmod
    Level 25  
    >>21606153
    Can you somehow get flash id?
    If so, then do it like i've done on RTL8721DA (1 << (flash_ID[2] - 0x11)) / 8
    Same method can be applied to beken (like those 4mb BK7252)
  • #15 21606173
    divadiow
    Level 34  
    p.kaczmarek2 wrote:
    We need to check is there a way to auto-detect RTL flash size.

    definitely +1 on this. otherwise users will only get half or quarter backup depending on device. custom read or another tool becomes the favourable option in this case.

    also. BK7252N/BK7252U split..? :)
  • #16 21606205
    p.kaczmarek2
    Moderator Smart Home
    Is there anyone with 2MB version of this RTL?

    I had a weird idea, because I did this SPI driver from previous article, you know?
    https://www.elektroda.com/rtvforum/topic4129001.html
    And I tried to use this CMD_GFS to plug classix 0x9F command from SPIs...
    Code: C#
    Log in, to see the code

    Here's what I got:
    Creating a simple BW16E (RTL8720DN) DIY flash tool command line utility
    0x684016
    Huh
    Creating a simple BW16E (RTL8720DN) DIY flash tool command line utility
    I tried the first random idea and it seems to work? What's the chance of that?
    Helpful post? Buy me a coffee.
  • #17 21606226
    insmod
    Level 25  
    >>21606205
    I have 2MB BW16.
    I could also solder 16mb chip to another BW16.
    Is GH branch or binary available somewhere?
  • #18 21606258
    p.kaczmarek2
    Moderator Smart Home
    I will push code in a moment.
    I just HAD to check.
    Creating a simple BW16E (RTL8720DN) DIY flash tool command line utility
    Creating a simple BW16E (RTL8720DN) DIY flash tool command line utility
    Creating a simple BW16E (RTL8720DN) DIY flash tool command line utility
    Creating a simple BW16E (RTL8720DN) DIY flash tool command line utility

    Added after 49 [minutes]:

    @insmod here: https://github.com/openshwprojects/BK7231GUIFlashTool binary should be ready soon.
    @divadiow if you can, keep an eye for Beken flashing, I hope I didn't break anything.

    I've did more checks and it seems that this really works, NeoProgrammer confirms, and btw, it only works after loading RAMCode
    Helpful post? Buy me a coffee.
  • #19 21606319
    insmod
    Level 25  
    2mb ok
    Serial port open!
    Sending RAM code...
    Setting baud rate 1500000 (given as 1500000)...... OK!
    Write SRAM at 0x00082000 to 0x00083250 from file: imgtool_flashloader_amebad.bin
    Write at 0x000000...Write complete!
    Setting baud rate 1500000 (given as 1500000)...... OK!
    Sending Flash ID Read...
    Flash ID: 0x684015
    RAM code ready!
    Read block at 0x000000...ok. Read block at 0x010000...ok. Read block at 0x020000...ok. Read block at 0x030000...ok. Read block at 0x040000...ok. Read block at 0x050000...ok. Read block at 0x060000...ok. Read block at 0x070000...ok. Read block at 0x080000...ok. Read block at 0x090000...ok. Read block at 0x0A0000...ok. Read block at 0x0B0000...ok. Read block at 0x0C0000...ok. Read block at 0x0D0000...ok. Read block at 0x0E0000...ok. Read block at 0x0F0000...ok. Read block at 0x100000...ok. Read block at 0x110000...ok. Read block at 0x120000...ok. Read block at 0x130000...ok. Read block at 0x140000...ok. Read block at 0x150000...ok. Read block at 0x160000...ok. Read block at 0x170000...ok. Read block at 0x180000...ok. Read block at 0x190000...ok. Read block at 0x1A0000...ok. Read block at 0x1B0000...ok. Read block at 0x1C0000...ok. Read block at 0x1D0000...ok. Read block at 0x1E0000...ok. Read block at 0x1F0000...ok. All read!
    Loaded total 0x200000 bytes 
    


    Maybe instead of loading amebad flashloader from disk, just convert it to bytes and store it in code? Its only 5kb.

    Added after 2 [minutes]:

    4mb not ok
    Serial port open!
    Sending RAM code...
    Setting baud rate 1500000 (given as 1500000)...... OK!
    Write SRAM at 0x00082000 to 0x00083250 from file: imgtool_flashloader_amebad.bin
    Write at 0x000000...Write complete!
    Setting baud rate 1500000 (given as 1500000)...... OK!
    Sending Flash ID Read...
    Flash ID: 0xEF4016
    RAM code ready!
    Read block at 0x000000...ok. Read block at 0x010000...ok. Read block at 0x020000...ok. Read block at 0x030000...ok. Read block at 0x040000...ok. Read block at 0x050000...ok. Read block at 0x060000...ok. Read block at 0x070000...ok. Read block at 0x080000...ok. Read block at 0x090000...ok. Read block at 0x0A0000...ok. Read block at 0x0B0000...ok. Read block at 0x0C0000...ok. Read block at 0x0D0000...ok. Read block at 0x0E0000...ok. Read block at 0x0F0000...ok. Read block at 0x100000...ok. Read block at 0x110000...ok. Read block at 0x120000...ok. Read block at 0x130000...ok. Read block at 0x140000...ok. Read block at 0x150000...ok. Read block at 0x160000...ok. Read block at 0x170000...ok. Read block at 0x180000...ok. Read block at 0x190000...ok. Read block at 0x1A0000...ok. Read block at 0x1B0000...ok. Read block at 0x1C0000...ok. Read block at 0x1D0000...ok. Read block at 0x1E0000...ok. Read block at 0x1F0000...ok. All read!
    Loaded total 0x200000 bytes 
  • #20 21606322
    p.kaczmarek2
    Moderator Smart Home
    I didn't do automatic size determination yet, it always reads 2MB. The only thing you can check so far is whether flash ID read works.

    Added after 1 [minutes]:

    I can see in your log that it recognized your flash ID as 0xEF4016, so I guess it works. I can move to the next step and use it to set flash size for the operations.
    Helpful post? Buy me a coffee.
  • #21 21606329
    divadiow
    Level 34  
    p.kaczmarek2 wrote:
    @divadiow if you can, keep an eye for Beken flashing, I hope I didn't break anything.

    yes. I can try stuff this evening.

    insmod wrote:
    Maybe instead of loading amebad flashloader from disk, just convert it to bytes and store it in code? Its only 5kb.

    Upgrade Tools does this in Python code for uploading stub to W800. It is the extraction of this stub that has fascilitated W80x whole-flash read experiments - https://www.elektroda.com/rtvforum/topic4120455.html#21542722
  • #22 21606338
    p.kaczmarek2
    Moderator Smart Home
    I wanted to just copy that uploading stub from repository to Release archive, but for some reasons nothing is copied - ideas?
    https://github.com/openshwprojects/SharpRTL872xTool
    https://github.com/openshwprojects/SharpRTL872xTool/blob/main/.github/workflows/build.yml
    Code: YAML
    Log in, to see the code

    Ah wait... I can see the issue... it's probably there:
    Code: YAML
    Log in, to see the code

    I can just add copy command to Easy Flasher as well, so stub is included in releases
    Helpful post? Buy me a coffee.
  • #24 21606388
    p.kaczmarek2
    Moderator Smart Home
    Loaders are now included in zip:
    Creating a simple BW16E (RTL8720DN) DIY flash tool command line utility
    Helpful post? Buy me a coffee.
📢 Listen (AI):

Topic summary

The discussion focuses on developing a simple command line flash tool in C# for the BW16E (RTL8720DN AmebaD) module, which supports WiFi (2.4GHz/5GHz) and Bluetooth LE 5.0 with dual KM4 and KM0 cores. Initial experiments involved using the RTL872xDx Python flasher tool to read and write firmware, specifically targeting OpenBeken firmware ports. Successful flash reading was demonstrated using RTL872xDx_Flasher.exe at 1.5 Mbps baud rate, with the necessity of loading a flash stub (flashloader) into SRAM before operations. The conversation highlights challenges such as the absence of embedded stubs in some tools and the need to port write functionality to Easy Flasher. Various related modules and variants were mentioned, including BW15, BW20-12F, RTL8720CM, RTL8720CF, and WBRG1, with some uncertainty about support for variable external flash sizes. References to existing open-source flash tools for AmebaZ and LN882H were also noted for potential adaptation.
Summary generated by the language model.
ADVERTISEMENT