一、前言
CYPRESS的PSOC BLE和PROC BLE芯片内部有个512Bytes的SFLash,用于保存用户指定的数据,接下来分享下如何对该区域进行读写
二、SFLASH的内部结构
从上图可以看出,SFLASH共有4行,每行128Bytes,其中第0行的前6个字节是存放BLE的MAC地址用的,用户不能修改否则MAC地址就会被篡改了。同时,SFLASH地址从0x0FFF F200~0x0FFF F380.
0
|
|
|
|
三、写SFLASH的关键代码实现
根据《cy_boot Component v5.30》手册的第8章所说,写SFLASH都是一次性写入128Bytes数据,不能一个Bytes一个Bytes地写入SFlash,但是我进行了相应的修改,一行可以在SFLASH地址范围指定的地方写入数据,代码如下:
1、使用到的宏定义:
- /*****************************************************
- * Enums and macros
- *****************************************************/
- #define SWITCH_PRESSED (0u) /* Active low user switch on BLE Pioneer kit */
- #define USER_SFLASH_ROW_SIZE (128u) /* SFlash row size for 128KB flash BLE device. For other PSoC 4 BLE devices
- * with higher flash size, this example project might need some modification.
- * Please check the device datasheet and TRM before using this code on non 128KB
- * flash devices */
- #define SFLASH_STARTING_VALUE (0x00) /* Starting value to be stored in user SFlash to demonstrate SFlash write API */
- #define USER_SFLASH_ROWS (4u) /* Total number of user SFlash rows supported by the device */
- #define USER_SFLASH_BASE_ADDRESS (0x0FFFF200u) /* Starting address of user SFlash row for 128KB PSoC 4 BLE device */
-
- #define LOAD_FLASH 0x80000004
- #define WRITE_USER_SFLASH_ROW 0x80000018
- #define USER_SFLASH_WRITE_SUCCESSFUL 0xA0000000
|
|
|
|
|
2、关键代码的实现:
- /*******************************************************************************
- * Function Name: WriteUserSFlashRow
- ********************************************************************************
- * Summary:
- * This routine calls the PSoC 4 BLE device supervisory ROM APIs to update
- * the user configuration area of Supervisory Flash (SFlash).
- *
- * Parameters:
- * userRowNUmber - User config SFlash row number to which data is to be written
- * dataPointer - Pointer to the data to be written. This API writes one row of
- * user config SFlash row at a time.
- *
- * Return:
- * uint32 - state of the user config SFlash write operation.
- *
- *******************************************************************************/
- #if defined (__GNUC__)
- #pragma GCC optimize ("O0")
- #endif /* End of #if defined (__GNUC__) */
- uint32 WriteUserSFlashRow(uint8 userRowNUmber, uint32 *dataPointer,uint8_t datalength,uint8_taddress)
- {
- uint8 localCount;
- volatile uint32 retValue=0;
- // volatile uint32 cmdDataBuffer[(CY_FLASH_SIZEOF_ROW/4) + 2];
- volatile uint32 cmdDataBuffer[datalength+2];
- volatile uint32 reg1,reg2,reg3,reg4,reg5,reg6;
-
- /* Store the clock settings temporarily */
- reg1 = CY_GET_XTND_REG32((void CYFAR *)(CYREG_CLK_SELECT));
- reg2 = CY_GET_XTND_REG32((void CYFAR *)(CYREG_CLK_IMO_CONFIG));
- reg3 = CY_GET_XTND_REG32((void CYFAR *)(CYREG_PWR_BG_TRIM4));
- reg4 = CY_GET_XTND_REG32((void CYFAR *)(CYREG_PWR_BG_TRIM5));
- reg5 = CY_GET_XTND_REG32((void CYFAR *)(CYREG_CLK_IMO_TRIM1));
- reg6 = CY_GET_XTND_REG32((void CYFAR *)(CYREG_CLK_IMO_TRIM2));
-
- /* Initialize the clock necessary for flash programming */
- CY_SET_REG32(CYREG_CPUSS_SYSARG, 0x0000e8b6);
- CY_SET_REG32(CYREG_CPUSS_SYSREQ, 0x80000015);
-
- /******* Initialize SRAM parameters for the LOAD FLASH command ******/
- /* byte 3 (i.e. 00) is the Macro_select */
- /* byte 2 (i.e. 00) is the Start addr of page latch */
- /* byte 1 (i.e. d7) is the key 2 */
- /* byte 0 (i.e. b6) is the key 1 */
- cmdDataBuffer[0]=0x0000d7b6|(address<<16);
- /****** Initialize SRAM parameters for the LOAD FLASH command ******/
- /* byte 3,2 and 1 are null */
- /* byte 0 (i.e. 7F) is the number of bytes to be written */
- cmdDataBuffer[1]=0x00000000|datalength-1;
- /* Initialize the SRAM buffer with data bytes */
- // cmdDataBuffer[2] = *dataPointer;
- for(localCount = 0; localCount < datalength; localCount++)
- {
- cmdDataBuffer[localCount + 2 = dataPointer[localCount];
- }
-
- /* Write the following to registers to execute a LOAD FLASH bytes */
- CY_SET_REG32(CYREG_CPUSS_SYSARG, &cmdDataBuffer[0]);
- CY_SET_REG32(CYREG_CPUSS_SYSREQ, LOAD_FLASH);
-
- /****** Initialize SRAM parameters for the WRITE ROW command ******/
- /* byte 3 & 2 are null */
- /* byte 1 (i.e. 0xeb) is the key 2 */
- /* byte 0 (i.e. 0xb6) is the key 1 */
- cmdDataBuffer[0 = 0x0000ebb6;
-
- /* byte 7,6 and 5 are null */
- /* byte 4 is desired SFlash user row
- * Allowed values 0 - row 4
- 1 - row 5
- 2 - row 6
- 3 - row 7 */
- cmdDataBuffer[1 = (uint32) userRowNUmber;
-
- /* Write the following to registers to execute a WRITE USER SFlash ROW command */
- CY_SET_REG32(CYREG_CPUSS_SYSARG, &cmdDataBuffer[0]);
- CY_SET_REG32(CYREG_CPUSS_SYSREQ, WRITE_USER_SFLASH_ROW);
-
- /* Read back SYSARG for the result. 0xA0000000 = SUCCESS; */
- retValue = CY_GET_REG32(CYREG_CPUSS_SYSARG);
-
- /* Restore the clock settings after the flash programming is done */
- CY_SET_XTND_REG32((void CYFAR *)(CYREG_CLK_SELECT),reg1);
- CY_SET_XTND_REG32((void CYFAR *)(CYREG_CLK_IMO_CONFIG),reg2);
- CY_SET_XTND_REG32((void CYFAR *)(CYREG_PWR_BG_TRIM4),reg3);
- CY_SET_XTND_REG32((void CYFAR *)(CYREG_PWR_BG_TRIM5),reg4);
- CY_SET_XTND_REG32((void CYFAR *)(CYREG_CLK_IMO_TRIM1),reg5);
- CY_SET_XTND_REG32((void CYFAR *)(CYREG_CLK_IMO_TRIM2),reg6);
-
- return retValue;
- }
- #if defined (__GNUC__)
- #pragma GCC reset_options
- #endif /* End of #if defined (__GNUC__) */
|
|
|
|
|
三、读SFLASH的内容
直接读x0FFF F200~0x0FFF F380地址的内容即可,代码实现如下:
- /*******************************************************************************
- * Function Name: ReadDataFromSFlash
- ********************************************************************************
- *
- *
- *
- * 读取SFlash中的数据
- * param none
- * return
- * None
- * SFlash中有506Bytes字节的用户可配置的空间
- ******************************************************************************/
- uint8_t ReadDataFromSFlash()
- {
-
- uint8_t FlashData=0;
- uint8_t *sflashPtr=(uint8_t *)USER_SFLASH_BASE_ADDRESS;//SFlash的首地址
- sflashPtr=sflashPtr+6;//前6字节是保存MAC地址,不能修改
- FlashData=*sflashPtr;
- return FlashData;
- }
|
|
|
|
|