- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Labels:
-
BLE
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I would suggest you to use the emEEProm (emulated EEProm) component which is easier to handle than handling flash rows.
Keep in mind that there will be a change in the system clocks while writing to flash, so best will be to have ble disabled during that time.
There is a C_language extension (I'm not quite satisfied with that way) using the "const" keyword to have a variable (structure or array) in flash:
const int32 MyVar = 123456;
The "const" keyword is needed AND the initialization is required for the compiler to put this var into flash. Within a function you will have to declare that variable as "static" or it would be allocated on stack.
Do not use AnotherVar = MyVar; // This wil set AnoterVar to 123456; regardless of a re-programming of MyVar!!
Instead use a memcpy() to transfer the emEEProm area to an sram area.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Currently the emulated eeprom is not supported for the BLE devices. You can use the API CySysFlashWriteRow itself to write to flash. First,you need to identify how much flash is currently consumed by the project. Each flash row is 128 bytes wide. Based on the address of the final flash byte (afterwards you may see full zeros (you can see from debugger)), you can divide that address by 128 to find the row number.
Another option is to force the compiler to store the flash data at some fixed locations. For e.g., if you want to place the flash data at address 0x1000, first Open Build Settings -> Linker -> Command Line -> Custom Flags and add: -Wl,--section-start=.MY_SECTION1=0x00001000
This places the data in Flash address 1000.
Now in your project, globally use: uint8 my_flash_data __attribute__ ((section(".MY_SECTION1")))={0xAA,0xBB,0xCC,0xDD};
Now the data AA, BB, CC and DD would be placed at addresses 1000-1003.
Hope this helps!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I used to write flash using method mentioned above with PICs & ST micros. But I was unable to write flash of PSoC BLE kit. It goes to exception handler every-time I try to write anything in the section. Even the variable above is uint8 and we are using it as array.
Queries:
1. Variable is uint8 type, but we are using it as array.
2. I used variable as an array, but I was unable to write using My_Flash_Data[0] = 12;. Whenever I do this code goes into exception handler.
3. I am not sure about Cypress flash, but in other micros flash 0xFF is written after a flash/sector erase. Technically it converts 1's to 0's based on modified values, but can never convert 0 to 1. For example - If you wrote 0x00 into flash after a erase you just can not write anything after this you need to erase that sector again. My question is, does Cypress flash behaves like this. If yes, then what are steps by which I can store data in a particular section of FLASH and read/write / store it as much as I want.
4. I also tried CyWriteRow method, going into exception there also.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Anish, post your complete project to write to BLE flash so that we all can have a look at all of your settings. To do so, use
Creator->File->Create Workspace Bundle (minimal)
and attach the resulting file.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello Bob, I was not calculating used flash correctly and was providing already used row in case of CySysFlashWriteRow function. Now I can read write data on Flash successfully.
But new issue that I am facing is whenever I try to connect with any BLE device, PSoC resets immediately. And if I comment flash read/write lines in my code, everything works smooth. Is there some issue with FLASH.
I am using BLE pioneer kit.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
When writing to flash there will be a change to the internal clocks (which is reverted when finished) and interrupts are not handled during the write. This will interfere with BLE.
Try to shut down BLE, prepare for no interrupt handling (and many when finished) and write to flash.
The BLE Pioneer kit has got some FRam on board which is connected via I2C and will be easier to handle in case of a power loss. Consider to use the FRam to store information which survive a power-down.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Oops, I was not aware that the emEEProm component was not yet released for PSoC4BLEs.
Writing into flash or EEProm has a critical point: When there is a power-loss during the write (which takes time in the ms-range) you will have corrupted data. When you have got a CY8CKIT-042-BLE you will find some FRam on the board that you can address via I2C. Writing to the FRam is in the µs range which can be easily bridged afterr a power-loss detection. Additionaly the number of FRam write-cycles is far larger than flash or EEProm.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Do you know if the EEProm component has been released yet?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You can design your power supply to 'hold up" long enough to handle
an internal FLASH write operation(s). Ie you can eliminate need for an
external memory. Goes something like this -
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello everybody,
I am trying to do the same thing, read and write data from flash. Basically I would like to use the rest of the flash to store values which will be then read and send over a communication protocol.
In this way and using the information from PSOC references I created a module presented here. The chip I used is CY8C4248BLQI-BL583 the chip has BLE and 256kB of FLASH arranged in 1024 rows (0-1023 as I observed) of 256 bytes each. Also do not get confused for me Start and End row are both 450 because I intended to start at 450 row(code is about 415 rows) and go along to 1023 but for testing I only want to fill a row and read it.
Also all of you fell free to use this code for your projects it it is ok for you of course. The only rows that you should modify are the first 2 , START and END rows numbers.
[UPDATE] Added some comments in the code. Also fell free to suggest improvements/find errors. I think the code can be done also using addresses, but I used rows since in PSOC if you write 3 elements in a row it will automatically delete the entire row.
<code>
#include "CyFlash.h"
/* Starting Row where you want to put data in Flash */
#define FLASH__nStoreStartRow 450
/* Last row where you want to put the data in Flash */
#define FLASH__nStoreEndRow 450 //1023
/* Heads to know the current write row and read row */
static uint32 FLASH__u32CurrentWriteRow = FLASH__nStoreStartRow;
static uint32 FLASH__u32CurrentReadRow = FLASH__nStoreStartRow;
/* Write to Flash method. The data received at input should ve size of an ROW, in my case 256 in others 128 */
int8 FLASH_i8StoreData(uint8 *pu8Data)
{
int8 enHALStatus = CY_SYS_FLASH_SUCCESS;
int8 i8Status = 1;
/* Checking to see if there are still rows available for write */
if(FLASH__u32CurrentWriteRow <= FLASH__nStoreEndRow)
{
enHALStatus = CySysFlashWriteRow(FLASH__u32CurrentWriteRow ,pu8Data);
/* Check status, if success increase Write row head, else return error code */
if(enHALStatus == CY_SYS_FLASH_SUCCESS)
{
FLASH__u32CurrentWriteRow++;
}
else
{
i8Status = -1;
}
}
else
{
i8Status = -1;
}
return i8Status;
}
/* Read merhod from Flash of an entire row; this method can be made to read less than a row if needed */
int8 FLASH_i8GetData(uint8 *pu8Data)
{
uint8 au8Data[CY_FLASH_SIZEOF_ROW];
uint8* pu8AuxPointer;
uint16 u16Index;
int8 i8Status = 0;
/* check if there is something in Flash using read and write heads */
if(FLASH__u32CurrentReadRow < FLASH__u32CurrentWriteRow)
{
/* Create the pointer address using the size of the row and the read row head */
pu8AuxPointer = (uint8 *)(CY_FLASH_BASE + (CY_FLASH_SIZEOF_ROW * FLASH__u32CurrentReadRow));
/* copy all the data of a row, This can also be done with memcpy but I did not tested yet */
for(u16Index = 0; u16Index < (uint16)CY_FLASH_SIZEOF_ROW; u16Index++)
{
au8Data[u16Index] = *(pu8AuxPointer + u16Index);
}
memcpy(pu8Data, au8Data,CY_FLASH_SIZEOF_ROW);
FLASH__u32CurrentReadRow++;
}
else
{
i8Status = -1;
}
return i8Status;
}
/* return the number of rows filled using, read and write heads */
uint32 FLASH_u32GetStoredItems(void)
{
uint32 u32Result;
if(FLASH__u32CurrentReadRow >= FLASH__u32CurrentWriteRow)
{
u32Result = 0;
}
else
{
u32Result = (FLASH__u32CurrentWriteRow - FLASH__u32CurrentReadRow);
}
return u32Result;
}
/* Reset the write and read heads This should be called after a flash empty operation*/
void FLASH_vResetStoredItems(void)
{
FLASH__u32CurrentWriteRow = FLASH__nStoreStartRow;
FLASH__u32CurrentReadRow = FLASH__nStoreStartRow;
}
</code>
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Update on this:
Hello,
It worked for some time but then I had some clock problems even if I used a 256KB FLASH chip and it is stated in data sheets that these chips should not have the clock problems, or any side effect problems. It turns out it have.
But good news Thanks to Cypress community using a technical ticket we corrected this in terms of using another function: CyBle_StoreAppData from BLE_StackHostMain.h file. In the header file you can check the description. if you replace the function FLASH_i8StoreData from my previous post with this function you are good to go. I am able to fully write the flash with BLE connection on and until now I did not have any problems at all.
<code>
int8 FLASH_i8StoreData(uint8 *pu8Data)
{
int8 i8Status = 1;
uint8* pu8AuxPointer;
if(FLASH__u32CurrentWriteRow <= FLASH__nStoreEndRow)
{
pu8AuxPointer = (uint8 *)(CY_FLASH_BASE + (CY_FLASH_SIZEOF_ROW * FLASH__u32CurrentWriteRow));
while(CyBle_StoreAppData(pu8Data,pu8AuxPointer,CY_FLASH_SIZEOF_ROW,0) != CYBLE_ERROR_OK)
{
;
}
FLASH__u32CurrentWriteRow++;
}
else
{
i8Status = -1;
}
return i8Status;
}
</code>