Over the past several months, I've been been learning to use the CH551 and CH552 MCUs. Learning generic 8051 programming was the easy part, as there is lots of old documentation available, with Philips having written some of the best. The learning curve for WCH's additions to the MCS-51 architecture has been steeper, requiring careful reading of the datasheets, and reading the SDK headers and examples. I've found that the CH55x chips have some quirks that I've never encountered on any other MCUs.
The GPIO modes are controlled by two registers: MOD_OC and DIR_PU. The register values are explained in the datasheet and in ch554.h in the SDK. Figure 10.2.1 in the datasheet shows a schematic diagram for the GPIO. Modes 0, 1, and 2 are for high-Z input, push-pull, and open-drain respectively. Mode 3, "standard 8051 mode" is the most complicated. It's an open drain mode with internal pullup, but with the output driven high for two cycles when the GPIO changes from a 0 to a 1. This ensures a fast signal rise time. The part that took me the longest to figure out was the operation of the pullup. The GPIO diagram shows 70k and 10k, but section 10 of the datasheet does not explain their operation. Therefore I've highlighted a part of the schematic in green. When the pin input schmitt trigger output is 1, the inverter in the top right of the diagram will output a low signal to turn on the pFET activating the 10k pullup. When port input value is 0, only the weak 70k pullup is active.
The pullups aren't actually implemented as resistors on the IC. They are specially-designed FETs with a high drain-source resistance (RDS). Since RDS varies with gate-source voltage (Vgs), the pullup resistance will vary inversely with Vcc. Using a 5V supply, the pullup resistance will be close to the 70k shown in the schematic. Using a 3.3V supply, the pullup resistance is close to 125k. Although it is not obvious, this information can be found in section 18 of the datasheet, with the specifications for IUP5 and IUP3. These numbers are the amount of current a grounded pin will source when the pullup is enabled.
The reset pin has an internal pulldown, which seems to be weak like the GPIO pullups. At times when working with a CH552 running at 3V3, the chip reset when I inadvertently touched the RST pin with my finger. This was easily solved by keeping the RST pin shorted to ground.
The last issue I encountered is more of a documentation issue than a quirk. The maximum reliable clock speed of an IC is depended on the supply voltage. All of the AVR MCUs I've worked with have a graph in the datasheet showing the voltage required to ensure safe operation at a given speed. For the CH55x MCUs, there is a subtle difference in the electrical specs at section 18 of the datasheet. At 5V, total supply current at 24MHz is specified, whereas the specs for 3.3V specify total operating current at 16Mhz. When I tried running a CH552T at 24MHz with a 3.3V supply, it never worked. The same part worked perfectly at 16MHz.
Despite the quirks, I think the CH55x MCUs are still a good value. Current quantity 10 pricing at LCSC is 36c for the CH552T, and 26c for the CH551G. I recently purchased a small tube of the CH552T, and have plans to test the touch, ADC, PWM, and SPI peripherals.