Saturday, January 2, 2021

Trying to test a "ten cent" tiny ARM-M0 MCU part 2

After my first look at the HK32F030MF4P6, I wondered if the HK part, unlike the STM32F030 it is modeled after, does not have 5V tolerant IO.  I changed the solder jumpers to 3V3 on the CH552 module I'm using as a CMSIS-DAP adapter, which caused it to stop working.  This was because the CH552 requires a 5V supply in order to run reliably at 24Mhz.  After re-flashing the CMSIS-DAP firmware set to run at 16MHz, the module worked, and I was finally able to talk to the HK MCU via SWD.

In the screen shot above, I chose the stm32f051 target because pyocd does not have the HK MCU nor the STM32F030 among it's builtin targets.  For basic SWD communications, the target option is not even necessary.  With the target specified, it's possible to specify peripheral registers by name, rather than having to specify a memory address to read or write.

In the screen shot above, I'm using the "connect_mode" option to bring the nRST line low on the target device when entering debug mode.  Usually this is not necessary for SWD, however some of the probing I did would cause the MCU to crash.  This required a power cycle or reset to restore communications via SWD.

The first tests I did with the HK MCU were to probe the flash and RAM.  The HK datasheet shows the flash at address 0.  In the STM32F0, the flash is at address 0x8000000, and is mapped to address 0 when the boot0 pin is low.  Although the HK MCU doesn't have a boot0 pin, data at address 0x8000000 is mirrored at address 0 as well.  What was most unusal about the HK MCU is that the flash was not erased to all 0xFF as is typical with other flash-based MCUs.  Most of the flash contents was zeros, except for some data at address 0x400, which was the same on the 2 MCUs I checked:

By writing to memory starting at 0x20000000 using the 'ww' command, I discovered that the MCUs I received have 4kB or RAM, rather than the 2kB specified in the datasheet.  Writing to 0x20001000 (beyond 4kB) results in a crash.

For writing and erasing the flash, I initially tried using the pyOCD 'erase' and 'flash' commands.  Since the MCU flash interface is not part of Cortex-M specification, the flash interface peripheral will vary from one MCU vendor to the next.  The flash interface on the STM32F051 is almost identical to the flash interface on the STM32F030, however the 'erase' and 'flash' commands caused the HK MCU to crash when I ran them.  Testing on a genuine STM32F030 crashed as well, and after some debugging and reading through the pyOCD code, I realized the STM32F051 flash routines need 8kB of RAM.  Even after downloading and installing the STM32F0 device pack, I could not erase or flash the HK MCU.

Next I reviewed the STM32F030 programming manual, and tried to access the flash peripheral registers directly.  This was when I found a pyOCD bug with the wreg command.  I was able to unlock the flash by writing the magic sequence of 0x45670123 followed by 0xCDEF89AB to flash.keyr.  I tried erasing the first page at address 0, and although flash.sr and flash.cr updated as expected, the memory contents did not change.  What did work was erasing the page at address 0x8000000, which cleared the contents at address 0 as well.  I still find it strange that the erase operation sets all bits to 0 instead of 1.  The HK datasheet says a flash page is 128 bytes, and erasing a page resulted in 128 bytes set to all zero.

I was only partially successful in writing data to the flash.  Writing to 0x8000000 did not work, however writing a 16-bits to address 0 using the 'wh' command was successful.  Trying to write 16-bits to address 2 updated the flash.ar and flash.sr as expected, but did not change the data.  Writing to any 4-byte aligned address in the erased page worked, but writing to addresses that were only 2-byte aligned left all 16 bits at zero.  I tried writing bytes with 'wb' and full words with 'ww', both of which crashed the MCU, likely from a hard fault interrrupt.  I even made sure there isn't a bug with the 'wh' command by writing 16-bits at a time to RAM.

While searching the CHK website for more documentation, I found a page with IAR device packs.  Although pyOCD uses Kiel device packs, I downloaded the HK32F0 pack, which is a self-extracting RAR file, which saves the uncompressed files in AppData\Local\Temp\RarSFX0.

Since .pack files are just zip files with a different extension, I zipped the files back up as a .pack file.  However pyOCD couldn't read it: "0000731:CRITICAL:__main__:CMSIS-Pack './HK32F0.pack' is missing a .pdsc file".  Manually examining the files confirmed some of my earlier discoveries, such as flash at address 0x8000000, remapped to address zero.  I found a file named HK32F030M.svd, which contains XML definitions of the peripheral registers.  pyOCD's builtin devices appear to use svd files, so it may be possible to add HKD32F0 support to pyOCD.

Copies of the IAR support pack, datasheet, and pyocd page erase sequence can be found in my github repository.


No comments:

Post a Comment