PSoC 4 Flash Emulate EEPROM with Non-blocking Feature – KBA233049
- Subscribe to RSS Feed
- Mark as New
- Mark as Read
- Bookmark
- Subscribe
- Printer Friendly Page
- Report Inappropriate Content
Version: **
Question:
How to use non-blocking method instead of blocking method in PSoC™ 4 flash?
Answer:
When executing flash erase or write action, the low-level driver uses blocking write method, disables all CPU interrupts until the end of the operation. Sometimes, the system needs to use non-blocking write. The following steps show how to use the non-blocking method using the CY8CKIT-041 Demo Kit:
1. Add the following lines of code to main.c, and make sure to set IMO to 48 Mhz in the *.cydwr clocks.
#define SPC_INT_IRQ 9u //the SPC interrupt No. follow the table
PSOC series |
SPCIF IRQ |
PSOC 4000S |
9 |
PSOC 4100S |
12 |
PSOC 4100S plus |
15 |
#define REG(addr) (*((volatile uint32 *) (addr)))
#define CPUSS_CONFIG_REG REG( 0x40100000 )
extern void SpcIntHandler();
void main()
{
…
CyIntSetVector(SPC_INT_IRQ,SpcIntHandler);
CyIntSetPriority(SPC_INT_IRQ,3);
CyIntEnable(SPC_INT_IRQ);
/* Set CPUSS_CONFIG.VECS_IN_RAM because SPC ISR should be in SRAM */
CPUSS_CONFIG_REG |= 0x00000001;
…
}
2. Go to Project → Build Settings. In the Build Settings dialog, set Skip Code Generation to False. Then, compile the project to generate the low-level driver.
.data : ALIGN(8)
{
__cy_region_start_data = .;
KEEP(*(.jcr))
*(.got.plt) *(.got)
*(.shdata)
*(.data .data.* .gnu.linkonce.d.*)
. = ALIGN (8);
*(.ram)
KEEP(*(.sramCode))
. = ALIGN (8);
_edata = .;
} >ram AT>rom
4. Define and assign the following three functions to the RAM section of the flash.c file.
/* Variable to keep track of how many times SPC ISR is triggered */
uint32 iStatusInt = 0;
CY_SECTION(".sramCode") __attribute__((used))
void DoStuffRunningInSram(void)
{
CY_NOP;
}
CY_SECTION(".sramCode") __attribute__((used))
void SpcIntHandler(void)
{
volatile uint32 parameters[1];
/* Write key1, key2 parameters to SRAM */
parameters[0u] = (uint32) (((uint32) CY_FLASH_KEY_TWO(0x09) << CY_FLASH_PARAM_KEY_TWO_OFFSET) | CY_FLASH_KEY_ONE);
/* Write the address of key1 to the CPUSS_SYSARG arg */
CY_FLASH_CPUSS_SYSARG_REG = (uint32) ¶meters[0u];
/* Write the API code = 0x09 to the CPUSS_SYSREQ.COMMAND
* register and assert the sysreq bit */
CY_FLASH_CPUSS_SYSREQ_REG = CY_FLASH_CPUSS_REQ_START | 0x09;
/* Number of times the ISR has triggered */
iStatusInt ++;
}
/*******************************************************************************
* Function Name: CySysFlashWriteRow
****************************************************************************//**
*
* Erases a row of Flash and programs it with the new data
********************************************************************************/
CY_SECTION(".sramCode") __attribute__((used))
uint32 CySysFlashWriteRow(uint32 rowNum, const uint8 rowData[])
{…}
5. Set the other interrupt, such as the 2 ms timer interrupt service routine in main.c,. Add the following code. The CPU will run into this handler every 2 ms.
CY_SECTION(".sramCode") __attribute__((used))
CY_ISR(Isr_Timer)
{
/* Clear the TCPWM terminal count interrupt */
Timer_ClearInterrupt(Timer_INTR_MASK_TC);
LED_Blue_Write(~LED_Blue_Read());
msCount++;
if(msCount >= 2)//////1000
{
/* Toggle the green LED state */
LED_Red_Write(~LED_Red_Read());
msCount = 0;
secFlag = 1;
}
Assign the API in the interrupt handler to the RAM:
6. In the Build Settings dialog, set Skip Code Generation to True. Then, compile the project.
7. Download the hex to the chip. The blue and red lights will be ON without any blinking. If using the blocking mode, the light will blink because the CPU could not operate flash when it is writing or erasing. Then, the timer interrupt handler will be pending until the operation finishes. The minimum time of flash operation should be 15 ms to 20 ms.