Question: A flash read operation in PSoC® 4 does not work as expected when you try to access the first 192 locations using a pointer. What is the reason behind this? Do you have to change any settings before accessing the flash contents? Does this issue apply to PSoC 5LP as well?
Answer: PSoC 4 uses an Arm® Cortex®-M0 CPU core. The Cortex-M0 has its exception (interrupt) vector table at the fixed CPU address range 0x00000000–0x000000BF. The exception vector table holds the starting addresses of the exception and interrupt handlers. The exception vector table can be in flash (0x00000000–0x000000BF) or in SRAM (0x20000000–0x200000BF). The startup code in PSoC Creator™ stores it in SRAM by default.
Whenever you try to access the contents from flash locations 0x00000000–0x000000BF through firmware, the CPU subsystem translates it to the vector table address / SRAM address 0x20000000–0x200000BF. Therefore, when you access the first 192 flash locations (for example, 0x00000000–0x000000BF), you will receive incorrect values (for example, from 0x20000000–0x200000BF instead of 0x00000000–0x000000BF). You will get the correct values from the remaining flash locations. To receive correct values for the first 192 flash locations, you should configure the CPU not to manipulate the given address by implementing the following steps:
Relocate the exception vector table to flash instead of SRAM so that any access to the flash address is not redirected to SRAM. To do that, the VECS_IN_RAM field of the CPUSS_CONFIG register (address: 0x40000000) must be set to false. For more information see Section 4, “CPUSS Registers” in the PSoC 4 Registers TRM.
In your PSoC Creator project, find the Cm0start.c file in Workspace Explorer. Open the file and modify the line that says
CY_CPUSS_CONFIG_REG |= CY_CPUSS_CONFIG_VECT_IN_RAM;
CY_CPUSS_CONFIG_REG |= 0;
as shown in Figure 1. This setting places the entire vector table into flash except the ones from addresses 0x00000000–0x00000007. Now, you should be able to read the flash contents from addresses 0x00000008–0x000000BF through firmware.
Figure 1. Relocating the Exception Vector Table to Flash
Address 0x00000000–0x00000007 stands for the main stack pointer (MSP) and the reset vector. To fetch the values from these addresses using the CPU, you need to set the CPUSS_NO_RST_OVR bit (bit number 27) in the CPUSS_SYSREQ (address: 0x40000004) register.
To implement this in PSoC Creator, you need to append the statement
CY_SET_REG32(CYREG_CPUSS_SYSREQ, CY_GET_REG32(CYREG_CPUSS_SYSREQ) | 0x08000000);
after the line
CY_CPUSS_CONFIG_REG |= 0;
in the Cm0start.c file as shown in Figure 2. After completing step 2, you will be able to read the values from all the flash locations.
Figure 2. Moving the MSP and Reset Vector to Flash
For more information, see Section 5.10, “Exception - Initialization and Configuration” in the PSoC 4 Architecture TRM. You can also read more about CPUSS_CONFIG and CPUSS_SYSREQ registers in Section 4, “CPUSS Registers” of the PSoC 4 Registers TRM.
Note that these above modifications only apply to PSoC 4 projects. This issue does not apply to PSoC 5LP (Cortex-M3 core).