py32f0-template icon indicating copy to clipboard operation
py32f0-template copied to clipboard

[not an issue] Re-purposing a Baofeng BF-666S board with a PY32F002AF15P6TU

Open cocus opened this issue 4 months ago • 5 comments

Hello all, First of all, this is an awesome project! I've done something similar for another cheap chinese chip (PHY6222) so I know the hurdles of navigating through poorly supported SDKs and chips. In any case, I have multiple boards of walkie talkies from Baofeng, which have one of the PY32F002AF15P6TU, and an integrated walkie talkie chip. No documentation on said chip is available online (AT1141). I've traced the footprint to be similar to the RDA1846 (at least the power lines, i2c lines, etc). However, doing a quick I2C logic dump reveals that it's indeed NOT a RDA1846 (even if it uses the same address!). In any case, I'm tracing the connections from all the chips on the board to the Puya MCU; I already have maped that the I2C lines are connected to PA0 and PA1 (which is weird since this MCU doesn't have I2C as an alternative functionality of these pads, but whatever). There are the SWD pins exposed on the backside of the board, but I've figured that either the MCU re-purposes those pins for something else, and/or the NRST is also used for something different than reset. I've verified that pulling NRST low and powering up the board makes it to not do absolutely anything; but once it "starts", pulling NRST low doesn't reset or holds the processor in reset. In any case, I'm using a J-Link ARM probe, I've tried the J-Flash with the JLinkDevices + jlink-script, and openocd with a custom config file (stolen from the stm32f0x, which I don't know which DAP tap id to use, so that's mostly what I wanted to ask here your thoughts); but nothing works. There's no reply from the device, and I suspect it's because they're using the SWDIO and SWDCLK pins for something else. Even if I connect the NRST pin to the J-Link probe, it can't reset it (as I've mentioned above).

In any case, the cfg file for openocd contains this (even if it's not working):

# SPDX-License-Identifier: GPL-2.0-or-later

# script for py32f02 family

#
# stm32 devices support SWD transports only.
#
source [find target/swj-dp.tcl]
source [find mem_helper.tcl]

if { [info exists CHIPNAME] } {
   set _CHIPNAME $CHIPNAME
} else {
   set _CHIPNAME py32f02
}

set _ENDIAN little

# Work-area is a space in RAM used for flash programming
if { [info exists WORKAREASIZE] } {
   set _WORKAREASIZE $WORKAREASIZE
} else {
   set _WORKAREASIZE 0xC00
}

# Allow overriding the Flash bank size
if { [info exists FLASH_SIZE] } {
	set _FLASH_SIZE $FLASH_SIZE
} else {
	# autodetect size
	set _FLASH_SIZE 0x5000
}

#jtag scan chain
if { [info exists CPUTAPID] } {
   set _CPUTAPID $CPUTAPID
} else {
   set _CPUTAPID 0x0bb11477 # this is not right
}

swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID
dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu

set _TARGETNAME $_CHIPNAME.cpu
target create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap

$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0

# flash size will be probed
set _FLASHNAME $_CHIPNAME.flash
#######flash bank $_FLASHNAME stm32f1x 0x08000000 $_FLASH_SIZE 0 0 $_TARGETNAME

# adapter speed should be <= F_CPU/6. F_CPU after reset is 8MHz, so use F_JTAG = 1MHz
adapter speed 1000

adapter srst delay 100

reset_config srst_nogate

if {![using_hla]} {
   # if srst is not fitted use SYSRESETREQ to
   # perform a soft reset
   cortex_m reset_config sysresetreq
}

# Default hooks
#######$_TARGETNAME configure -event examine-end { stm32f0x_default_examine_end }
#######$_TARGETNAME configure -event reset-start { stm32f0x_default_reset_start }
#######$_TARGETNAME configure -event reset-init { stm32f0x_default_reset_init }

I'm NOT changing the BOOT0 pin at all, it's held with its default value from the original circuit (which I think it's pulling it low? can't trace where it's connected though)

I'd appreciate any feedback you can give!

Thanks.

cocus avatar Aug 26 '25 22:08 cocus

A quick update: It turns out that the above script (removing # this is not right) works when I force the MCU to enter into the bootloader. Good! However, I'm pretty sure this device is locked and can't dump its memory.

I've dumped the UID:

0x1fff0e00:     0x4150344a      0x3230320b      0x00bf2d41      0x56051478
0x1fff0e10:     0x0220ffff      0x65ba78ba      0x9affffff      0x0affffff
0x1fff0e20:     0x1197ee68      0xffffffff      0xffffffff      0xffffffff
0x1fff0e30:     0xffffffff      0xffffffff      0xffffffff      0xffffffff
0x1fff0e40:     0x00000ef3      0x00002ef3      0x000050f3      0x00007114
0x1fff0e50:     0x00009110      0x000003ac      0x00000471      0xffffffff
0x1fff0e60:     0xffffffff      0xffffffff      0xffffffff      0xffffffff
0x1fff0e70:     0xffffffff      0xffffffff      0xffffffff      0xffffffff

The option bytes:

0x1fff0e80:     0x0155feaa      0xff0000ff      0xffffffff      0x0000ffff
0x1fff0e90:     0xffffffff      0xffffffff      0xffffffff      0xffffffff
0x1fff0ea0:     0xffffffff      0xffffffff      0xffffffff      0xffffffff
0x1fff0eb0:     0xffffffff      0xffffffff      0xffffffff      0xffffffff
0x1fff0ec0:     0xffffffff      0xffffffff      0xffffffff      0xffffffff
0x1fff0ed0:     0xffffffff      0xffffffff      0xffffffff      0xffffffff
0x1fff0ee0:     0xffffffff      0xffffffff      0xffffffff      0xffffffff
0x1fff0ef0:     0xffffffff      0xffffffff      0xffffffff      0xffffffff

The HSI trimming data:

0x1fff0f00:     0x000010c0      0x000030c0      0x000050fd      0x0000711a
0x1fff0f10:     0x00009118      0x000003ac      0x00000471      0x00481e1e
0x1fff0f20:     0x0120001e      0x000036b0      0x000036b0      0x03200fa0
0x1fff0f30:     0x00903c3c      0x0240003c      0x00006d60      0x00006d60
0x1fff0f40:     0x06401f40      0x01207878      0x04800078      0x0000dac0
0x1fff0f50:     0x0000dac0      0x0c803e80      0x018fa6a6      0x063900a6
0x1fff0f60:     0x00012e6c      0x00012e6c      0x11485668      0x01b0b4b4
0x1fff0f70:     0x06c000b4      0x00014820      0x00014820      0x12c05dc0

However, now that I think about it, I think I can read it:

0x8000000:      0x20000538      0x080000d5      0x08000bcd      0x08000b11
0x8000010:      0x00000000      0x00000000      0x00000000      0x00000000
0x8000020:      0x00000000      0x00000000      0x00000000      0x08000e2f
0x8000030:      0x00000000      0x00000000      0x08000c49      0x08000e31
0x8000040:      0x00000000      0x00000000      0x00000000      0x080000e7
0x8000050:      0x080000e7      0x080000e7      0x080000e7      0x080000e7
0x8000060:      0x00000000      0x00000000      0x00000000      0x00000000
0x8000070:      0x080000e7      0x080000e7      0x080000e7      0x00000000

The first int is the sp, the second one the reset pointer, etc, all standard from CortexM0 MCUs, I think!

EDIT: Yes, seems like I was able to just read the whole flash lol!

I've used the following commands on GDB to dump it (of course after running OpenOCD in the background). Then a bit of notepad++ macro magic to process the txt file :)

(gdb) target extended-remote localhost:3333
Remote debugging using localhost:3333
warning: No executable has been specified and target does not support
determining executable automatically.  Try using the "file" command.
0x1fff0910 in ?? ()
(gdb) set height 0
(gdb) set logging on
Copying output to gdb.txt.
(gdb) x/5120wx 0x08000000

By the way, I haven't checked how OpenOCD does it for STM32s, but, I assume they're doing the flash erase/write by just probing memory addresses instead of running a stub, right? Would be cool to use OpenOCD instead of the jlink app (or jlink gdb).

In any case, I'm not sure about what I've dumped. Even if the file is a raw cortex m0 binary (that's what file also reports), I can't make much sense of it as of now (decompiling it through IDA).

$ file bf-666s-firmware.bin
bf-666s-firmware.bin: ARM Cortex-M firmware, initial SP at 0x20000538, reset at 0x080000d4, NMI at 0x08000bcc, HardFault at 0x08000b10, SVCall at 0x08000e2e, PendSV at 0x08000c48

cocus avatar Aug 26 '25 23:08 cocus

Ok, getting back to this. I've seen some weird references to functions and data beyond the 20K of the flash, like the following code:

Image or Image

Is there an undocumented ROM after the flash? or is it that the flash is bigger? I'm pretty sure this is a 20K part, so this is a little bit puzzling. I'm still not sure if I've dumped the actual firmware or if this is the bootloader? I don't think so... but it has those references to odd memory locations, and it doesn't make any sense.

Well, in any case, any feedback is welcome!

Thanks!

cocus avatar Aug 29 '25 20:08 cocus

I've re-connected the target, and dumped an additional 12kb out of it, so the entire ROM is 32kB! the contents are fine, and OpenOCD doesn't complain when reading that section in between 0x08005000 - 0x08008000 which is not marked as anything on the datasheet!

Image

However, if I try to read from 0x08008000 or something in that "reserved" space, I do get errors on OpenOCD, which is expected. I'm thinking that MAYBE this thing has a larger flash than advertised?

cocus avatar Aug 29 '25 22:08 cocus

However, if I try to read from 0x08008000 or something in that "reserved" space, I do get errors on OpenOCD, which is expected. I'm thinking that MAYBE this thing has a larger flash than advertised?

Yes, it's known that 002A has 32KB flash, here is the discussion.

My apologies I cannot help the rom/flash reading for I am not an expert in this field. I searched the keyword AT1141 but the information is very limited:

  • There is a copyright application (certificats list) by company named 泉州市创新电子科技有限公司(Quanzhou Chuangxin Electronic Technology Co., Ltd) in 2022 for their software New wireless intercom technology program software based on AT1141, Baofeng company is also in Quanzhou so they might have business connections
  • RF chip AT1141 is a production of AUCTUS but they doesn't provide datasheet downloads, and there is no information on the Internet. I'll contact them and see if I can get some technical information.

IOsetting avatar Sep 04 '25 12:09 IOsetting

Yes, it's known that 002A has 32KB flash, here is the discussion.

Excellent, I tried to find something about it but... not much. that's good!

My apologies I cannot help the rom/flash reading for I am not an expert in this field. I searched the keyword AT1141 but the information is very limited:

Yes, I know this is kinda all private chips and such, thus why I'm reverse-engineering the firmware I've dumped from the puya. At first, most of it didn't make sense because I was missing the other 12KB of it (the firmware uses the 32kb!). Now I'm on track of figuring out what's going on. Nothing weird so far.

What I'd like to review is adding support for this chip on openocd. Once I feel I have mapped out the majority of the pins of the puya on this board, I'll try to make a simple blinky project and flash it through jlink, and start tinkering with flash routines for openocd. I'll try to commit these and open a PR.

This project is really cool and I've used it to map out the peripherals that the firmware is using, through the .h files and such. Thanks again for it.

I'll update this issue once I have more information.

cocus avatar Sep 04 '25 18:09 cocus