Close

Identifying Undocumented I/O Registers

A project log for Sensors Based on the Padauk RFC Peripheral

Exploring the undocumented Resistance to Frequency Converter (RFC) peripheral of the Padauk PFS173 Microcontroller

timTim 09/14/2020 at 22:380 Comments

Padauk is a Taiwanese supplier of ultra-low cost microcontrollers, notorious for the "3 cent MCU". The supplier itself only offers a closed tool chain with a proprietary C-style language. In the mean time, an open sourced and independently created tool-chain, partially based on reverse engineering, became available.

There are still some areas that are not completely understood. One topic is the initial state of the I/O registers. The behavior of the real device is somewhat inconsistent to the datasheet, which may be due to an errata or due to different behavior of the proprietary and open toolchain.

To investigate this behavior in detail on the Padauk PFS173-S16,  a small program was used to copy the entire I/O space to the RAM directly after startup. Since no indexed access of the I/O registers is possible, individual instructions had to be generated to copy each address.

After proper initialization of the MCU peripherals, the I/O area back up is dumped via the serial port.

The image above shows a dump of the entire I/O area directly after reset. There are 128 possible registers, but only some are used and documented - only few registers actually show a nonzero value.

One interesting aspect is that some values are repeated, like the 0xF0 in address 00 and  01. This is particularily striking since the registere at 0x01 is actually unused. Some more experimentation reveal that actually the content of the last access registers is repeated. The behavior looks very much like a floating internal bus - if the accessed register does not exist, no new information is written to the bus; the logic level from the last access is stored due to the parasitic capacitance. This would, of course, be a nice side channel if this were a security critical device. But we can still utilize this effect to identify which I/O addressed are actually utilized and which are not.

To probe for unused registers, I simply wrote 0x55 to a known register directly before the I/O read. If the next read access was to an unused I/O location, it would read as 0x55 and could be easily identified. As you can see in the image above, many I/O addresses now read 0x55 and are therefore unused or write only. Most of the used registers could be easily crosschecked to the documentation.

There are, however, a few registers that cannot be assigned. The first, marked in red, at 0x23 and a group, marked in green, at 0x2d,0x2e,02f. A bit further probing revelad that 0x2d is clearly a control register. Reset state is 0xE0. Bits 7-5,3,1,2 are R/W, Bits 4 and 2 RO or WO. 0x2e and 0x2f appeared to be read only.

Some excellent sleuthing by JS in the EEVBlog-Forum revealed a very interesting explanation for the green registers: It seems that earlier padauk microcontrollers included a peripheral called the Resistance to Frequency Converter (RFC), which can still be found in an old datasheet version at a reseller. The bit configuration of these registers exactly follows the findings, so that there is a good chance for a match.

It's not clear why this peripheral was left undocumented. It is still mentioned in the catalogue of Padauk, but not a single device with this feature set is listed.

The purpose of the undocumented register 0x23 (red) could be easily identified: It actually contains additional LSBs of the ADC. It appears that Padauk has a standard IP block for a 11 bit ADC that was also used in the PFS173. For some reason it was declared as 8 bit ADC and the lower three bits were left undocuments. Possibly there is a noise issue?

Discussions