How can I read an Unique ID number using SPIFFY1 ?

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Anonymous
Not applicable

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 ?

0 Likes
1 Solution

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();

View solution in original post

13 Replies
MichaelF_56
Moderator
Moderator
Moderator
250 sign-ins 25 comments on blog 10 comments on blog

Module or SOC?  Note that the module provides 1 I2C Master and that is internally connected to the EEPROM on the module.  The SCL+SDA on pins shared with SPIFFY1, so this interface is not readily available on the module.

j.t arvinds

0 Likes
asridharan
Employee
Employee
10 comments on KBA 5 comments on KBA First comment on KBA

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.

Anonymous
Not applicable

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

0 Likes

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);

0 Likes
Anonymous
Not applicable

Thank you, I will try and let you know

0 Likes
Anonymous
Not applicable

Unfortunately after adding this function the system keeps rebooting.

0 Likes

OK, let me check what I missed in using that API.

0 Likes

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();

Anonymous
Not applicable

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 ?


0 Likes

> 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).

Anonymous
Not applicable

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.



0 Likes

> 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.

0 Likes

Arvinds do you have sample code on how to init SPIFFY1

0 Likes