- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
My NVRAM is a serial flash connected to SPIFFY1. To protect my system I want to read Unique ID Number from sflash.
How can I access this data using SPIFFY1 interface ? Since SPIFFY1 has limited availability for application use is it possible at all ? How can I assert CS since this pin is not accessible from application ? Is it always asserted ?
Solved! Go to Solution.
- Labels:
-
FlashEEPROM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I just realized that for this API, txLen + rxLen must be <= 14. Split your transaction into two reads. The other thing you may have to do is to put the SF out of deep sleep before reading and then put it back in deep sleep after you are done. Since you are bypassing the serial flash driver, you have to request the SF driver to do it for you. Here is some pseudocode:
extern void sfi_exitDeepPowerDown(void);
extern void sfi_enterDeepPowerDown(void);
extern void spiffy_txrxBlock(UINT32 txLen, const UINT8* txBuf, UINT32 rxLen, UINT8* rxBuf, void* ctxt);
UINT8 txBuf[5] = {0x5A, 0x11, 0x22, 0x33, 0x00}; /// instruction, 3 byte address, dummy byte
UINT8 rxBuf[12];
// Bring the SF out of deep sleep first
sfi_exitDeepPowerDown();
// Read keep rx + tx <= 14
spiffy_txrxBlock(5, txBuf, 9, rxBuf, (void*)spiffy_cfg_adr);
// --> Update address to read here.
spiffy_txrxBlock(5, txBuf, 3, rxBuf + 9, (void*)spiffy_cfg_adr);
// Put the SF back in deep sleep.
sfi_enterDeepPowerDown();
- 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
You don't want to use the SPIFFY interface to access the serial flash. SPIFFY is the lower level driver to access SPI (like if you want to read/write to a sensor). You have to use the serial flash API or an easier method would be to use the API ws_upgrade.c uses. See bleappfwu_readMem(), bleappfwu_writeMem() and bleappfwu_eraseMem() - so you can use this with EEPROM or SF. Make sure that you are accessing only the sectors that are not used by the firmware for SS1/SS2, VS1/VS2 and DS1/DS2. See ws_upgrade.c for the default locations and sizes of these sections.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
How can I send the right instruction code (0x5A) prior reading UID when using suggested functions ?
Here is the full sequence to read the UID
1. Send instruction code (0x5A)
2. Send 21-bit address (0x80)
3. Send one dummy byte of clock
4. Read 96-bit UID
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Sorry, I didn't realize that you wanted to read a specific register/send a specific command to the SF. You cannot do that with bleappfwu_* - they only allow you to access storage locations in the SF, not control.
You have to use the much lower level API for this. These are currently not documented, but try using this:
/// Transmit a buffer and then receive a buffer.
/// \param txLen Number of bytes to transmit.
/// \param txBuf The buffer with the bytes to transmit.
/// \param rxLen The number of bytes to receive after the transmit.
/// \param rxBuf The buffer into which to store the received bytes.
/// \param ctxt Context. For SPIFFY1, always use (void*)spiffy_cfg_adr. #include "20732mapa1.h" for the definition.
extern void spiffy_txrxBlock(UINT32 txLen, const UINT8* txBuf, UINT32 rxLen, UINT8* rxBuf, void* ctxt);
So you would have something like this:
#include "20732mapa1.h"
UINT8 txBuf[5] = {0x5A, 0x11, 0x22, 0x33, 0x00}; /// instruction, 3 byte address, dummy byte
UINT8 rxBuf[12];
spiffy_txrxBlock(5, txBuf, 12, rxBuf, (void*)spiffy_cfg_adr);
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you, I will try and let you know
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Unfortunately after adding this function the system keeps rebooting.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
OK, let me check what I missed in using that API.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I just realized that for this API, txLen + rxLen must be <= 14. Split your transaction into two reads. The other thing you may have to do is to put the SF out of deep sleep before reading and then put it back in deep sleep after you are done. Since you are bypassing the serial flash driver, you have to request the SF driver to do it for you. Here is some pseudocode:
extern void sfi_exitDeepPowerDown(void);
extern void sfi_enterDeepPowerDown(void);
extern void spiffy_txrxBlock(UINT32 txLen, const UINT8* txBuf, UINT32 rxLen, UINT8* rxBuf, void* ctxt);
UINT8 txBuf[5] = {0x5A, 0x11, 0x22, 0x33, 0x00}; /// instruction, 3 byte address, dummy byte
UINT8 rxBuf[12];
// Bring the SF out of deep sleep first
sfi_exitDeepPowerDown();
// Read keep rx + tx <= 14
spiffy_txrxBlock(5, txBuf, 9, rxBuf, (void*)spiffy_cfg_adr);
// --> Update address to read here.
spiffy_txrxBlock(5, txBuf, 3, rxBuf + 9, (void*)spiffy_cfg_adr);
// Put the SF back in deep sleep.
sfi_enterDeepPowerDown();
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
First I don't think we have to send again 5 bytes of instruction, address and dummy byte in the second call to spiffy_txrxBlock. I think this is would be correct:
spiffy_txrxBlock(0, txBuf, 3, rxBuf + 9, (void*)spiffy_cfg_adr);
or even:
spiffy_txrxBlock(0, NULL, 3, rxBuf + 9, (void*)spiffy_cfg_adr);
Well I tested this solution and it does not work, though the chip does not reboot but it reads back all 0xFF.
Any other ideas ?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
> spiffy_txrxBlock(0, txBuf, 3, rxBuf + 9, (void*)spiffy_cfg_adr);
> or even:
> spiffy_txrxBlock(0, NULL, 3, rxBuf + 9, (void*)spiffy_cfg_adr);
None of this will work. The API requires non-zero TX and non-zero RX lengths.
> though the chip does not reboot but it reads back all 0xFF.
Did you bring the SF out of deep power down using sfi_exitDeepPowerDown() before trying to read?
> Any other ideas ?
I would put a scope on the SPI bus to see if the SF is really responding with 0xFF. Or try to read a few bytes from 0x00 using a regular read command (most SFs use 0x0B, 0xHH, 0xMM, 0xLL sequence - where HH is the high byte, MM is the middle byte and LL is the low byte of the address).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The sequence to read the UID is first send 5 bytes and then read 12.
Since there is a limitation rx + tx <= 14 we can only read 9 bytes (after sending 5):
spiffy_txrxBlock(5, txBuf, 9, rxBuf, (void*)spiffy_cfg_adr);
The above is clear for me.
Now we just need to read the remaining 3 bytes.
You suggested using this:
spiffy_txrxBlock(5, txBuf, 3, rxBuf + 9, (void*)spiffy_cfg_adr);
Correct me if I am wrong but I think this will send again 5 bytes prior reading the remaining 3.
Yes, I am bringing SF out of deep power down.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
> You suggested using this:
> spiffy_txrxBlock(5, txBuf, 3, rxBuf + 9, (void*)spiffy_cfg_adr);
Yes, assuming you updated/are allowed to update txBuf to now point to 9 bytes further into the SF memory. If all of this has to be done in one transaction, then this is not possible.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Arvinds do you have sample code on how to init SPIFFY1