After getting a blinky program to work on both the PSoC4200 and the PSoC4200M series (the code is the same), I wanted to continue with some communication. For this purpose I took a look at the Serial Communication Block (SCB) peripheral. An SCB can do either UART, SPI or I²C. After looking at the registers, I realised there are no registers specifying the communication speed. So, the speed must be determined by a clock coming from elsewhere. Therefore I decided to take a look at the clock first. Now, the clock tree is a place where the 4200 and the 4200M series diverge. However, the part where the main clock is set up appears to be the same. So, I decided to start there.
The PSoC4 has an internal oscillator, that can be configured from 3 to 48 MHz in 1 MHz steps. (Only 24 MHz in CY8C4x2x models). The clock speed in controlled by the System Resources Sub System (SRSS) peripheral. At first sight, it looked like all that was required is to set the IMO_TRIM2 register to the desired frequency. I decided to ignore the IMO_TRIM1 register, used to fine-tune the frequency, using a factory calibration stored in SFLASH. At this stage, I didn’t care if I request 10 MHz, I might get 10,1 MHz.
So, according to the TRM, I used the following
[ 3MHz-12MHz] : [ 3-12] [13MHz-24MHz] : [14-25] [25MHz-33MHz] : [27-35] [34MHz-40MHz] : [37-43] [41MHz-48MHz] : [46-53]
This would work up to 37 MHz, but setting anything faster would result in a crash, which appeared to be data corruption. At first, I thought the values in TRIM1, TRIM4 and TRIM5 needed to be written too. Especially because, when changing speed, the TRM mentions, when speeding up, they should be written prior to changing speed, and when slowing down, they should be written after doing so. So, I figured, whatever these TRIM4 and TRIM5 values do, they must be set when speeding up.
However, this didn’t change anything. For a while, I was puzzled by this behaviour. And then it hit me. Knowing a little about microcontroller architectures, and having read some code for other microcontrollers, the STM32 series, made me realise what the problem was. WAIT STATES. When speeding up the clock, the microcontroller also reads the flash faster, and we’re going to fast for the flash to keep up. That explains the data corruption.
Taking another look at the Registers TRM, I noticed a bit HALF_EN, which enables a WAIT STATE. And surely enough, setting this bit when going faster then 24 MHz makes the PSoC 4200 run fine at speeds up to 48 MHz. However, the 4200M still crashed. I have double checked, the HALF_EN bit are the same on both micros! So, another dive into the TRM. It turned out, the 4200M TRM mentions another WAIT STATE register. In the CPUSS_FLASH_CTL register, I can specify a WAIT STATE of 0, 1 or 2. Setting this register, and the 4200M also runs fine at 48 MHz. This makes me wonder, does the HALF_EN bit even work on the 4200M, and might this be a copied page in the datasheet, where this bit is no longer in use? Regardless, it works now.
As a test, I’ve written to this register directly. I still need to create header files for the CPUSS peripheral. This is also a peripheral where the two families differ. As the 4200M is a more recent chip, it would make sense to call the 4200 version CPUSSv1 and the 4200M CPUSSv2. Looking at the 4000 series TRM, it describes the same registers as present in the 4200M series, and it mentions CPUSSv2. It seems my naming, at least for the v2 part, matches with official documentation.
Looking at the 4000 TRM, it also mentions a bit for WAIT STATES for ROM. In here, it mentions
The older design requires 1 wait
state for frequencies above 24 MHz. The newer design never requires wait states. All chips after
Street Fighter will use the newer design. As a result, all chips after Street Fighter can always use
0 wait states.
I assume Street Figher is a codename for some chip. But which of them is? I haven’t been able to find any references to codenames. However, googeling this, make me do an interesting discovery. Exactly the same phrase showed up in an application note of a microcontroller by ON Semiconductor. Looking through the document, the peripherals and their names exactly look like Cypress PSoC4. This strongly suggests this ON Semiconductor part is a rebranded Cyprss part. At the bottom of the document it says “Portions Copyright 2018 Cypress Semiconductor Corporation”, which seems to confirm my conclusions. This is an unexpected discovery.