1
\$\begingroup\$

enter image description here

I'm using the following eeprom FM25CL64 http://www.tme.eu/at/Document/f170062ad2f9464359d3dc53837256d8/fm25cl64ds_r3_2.pdf

I try to write data, read data by polling but it stays in infinite loop and the status register is always 0, and that's why I stay in infinite loop when I read the register.

here is my driver and here is how I use it

// extract a low byte from a 2 byte word.          
#define Lo(X)   (unsigned char)(X&0x00ff)

// extract a high byte from a 2 byte word.        
#define Hi(X)   (unsigned char)((X>>8)&0x00ff)
#define SPI_EEPROM_SELECT      0xFBFF          /* select EEPROM value */
#define SPI_EEPROM_DESELECT    0x0400          /* deselect EEPROM value */ 


#define EEPROM_CMD_WRSR        0x01            /* Write Status Register */
#define EEPROM_CMD_WRITE       0x02            /* Write Memory Data */
#define EEPROM_CMD_READ        0x03            /* Read Memory Data */
#define EEPROM_CMD_WRDI        0x04            /* Write Disable */
#define EEPROM_CMD_RDSR        0x05            /* Read Status Register */
#define EEPROM_CMD_WREN        0x06            /* Set Write Enable Latch */




struct  STATREG{
        unsigned    WIP:1;
        unsigned    WEL:1;
        unsigned    BP0:1;
        unsigned    BP1:1;
        unsigned    RESERVED:3;
        unsigned    WPEN:1;
};
union _EEPROMStatus_{
        struct  STATREG Bits;
        unsigned char   Char;
};

I'm using it with blackfin 533

void spi_eeprom_select_new(void)                        /* select EEPROM */
{
    *pSPI_FLG   = (*pSPI_FLG & SPI_EEPROM_SELECT );
     ssync();
}

void spi_eeprom_deselect_new(void)                      /* deselect EEPROM */  
{
    *pSPI_FLG   = (*pSPI_FLG | SPI_EEPROM_DESELECT);
    ssync();
}

///////////////////////////////////////////////////////////////////////
unsigned char  spi_trans_byte_bw_new(const unsigned char tx)
{      
   *pSPI_TDBR = tx;  
    int i;
    while ((*pSPI_STAT & 0x0001) == 0) ; 
    for( i = 0 ; i < 100; i++)
    {
    }

    unsigned char d = *pSPI_RDBR;
    return d; 
} 

// enable writeing to EEPROM
void EEPROMWriteEnable(void)
{
    unsigned char Local_8;
    spi_eeprom_select_new();
    Local_8 = spi_trans_byte_bw_new(EEPROM_CMD_WREN);
    spi_eeprom_deselect_new();
}

void EEPROMWriteDisable(void)
{
    unsigned char Local_8;
    spi_eeprom_select_new();
    Local_8 = spi_trans_byte_bw_new(EEPROM_CMD_WRDI);
    spi_eeprom_deselect_new();
}

// read status register
union _EEPROMStatus_ FM33256readStatus(void)
{
    unsigned char Local_8;
    spi_eeprom_select_new();
    Local_8 = spi_trans_byte_bw_new(EEPROM_CMD_RDSR);
    Local_8 = spi_trans_byte_bw_new(0);
    spi_eeprom_deselect_new();
    //printf("status %x\n",  Local_8);
    return (union _EEPROMStatus_)Local_8;
}

// write a byte to address (16 bits)
void FM33256write8(unsigned char Data, unsigned int Address)
{
    unsigned char Local_8;
    EEPROMWriteEnable();
    spi_eeprom_select_new();
    Local_8 = spi_trans_byte_bw_new(EEPROM_CMD_WRITE);
    Local_8 = spi_trans_byte_bw_new(Hi(Address));
    Local_8 = spi_trans_byte_bw_new(Lo(Address));
    Local_8 = spi_trans_byte_bw_new(Data);
    spi_eeprom_deselect_new();
    // wait for completion of previous write operation
    while(FM33256readStatus().Bits.WIP);  // it fails here
    spi_eeprom_deselect_new();
}


// read a byte from address (16 bit)
unsigned char FM33256read8(unsigned int Address)
{
    unsigned char Local_8;
    spi_eeprom_select_new();
    Local_8 = spi_trans_byte_bw_new(EEPROM_CMD_READ);
    Local_8 = spi_trans_byte_bw_new(Hi(Address));
    Local_8 = spi_trans_byte_bw_new(Lo(Address));
    Local_8 = spi_trans_byte_bw_new(0);
    spi_eeprom_deselect_new();
    return Local_8;
}

here is how I use it

unsigned char data = FM33256read8(15);
FM33256write8(10,15);
\$\endgroup\$
  • \$\begingroup\$ Add a schematic as well please. \$\endgroup\$ – Bence Kaulics Oct 14 '16 at 9:14
  • \$\begingroup\$ I added the schematic \$\endgroup\$ – Ahmed Saleh Oct 14 '16 at 9:16
  • \$\begingroup\$ What MCU is your code for? - Maybe you should write "FRAM" instead of "EEPROM". \$\endgroup\$ – JimmyB Oct 14 '16 at 10:24
  • \$\begingroup\$ I wrote it above, I use blackfin 533 \$\endgroup\$ – Ahmed Saleh Oct 14 '16 at 10:27
  • 2
    \$\begingroup\$ Please note that bit-fields are very poorly standardized. Have you verified that the binary of your bit-field results in 1 byte and not 4? In case of 4 bytes, have you verified that the endianess of this bit-field puts the bits where you expect them? Have you verified the bit order? Byte or bit padding? None of these things are guaranteed to function as you might expect. \$\endgroup\$ – Lundin Oct 14 '16 at 11:12
1
\$\begingroup\$

Why do you need to poll status register? Datasheet says that status register is used to identify write protection and other features. Writes to FRAM are instant, and you do not need to poll anything waiting for write cycle completion. Thus status register 0 means that everything is protected; to write to the device you need to issue special write enable command before any write (memory or status register).

\$\endgroup\$
  • \$\begingroup\$ what I get is just 0xFF, I don't know why. after transferring the commands, I get 0xFF \$\endgroup\$ – Ahmed Saleh Oct 14 '16 at 10:15
  • \$\begingroup\$ is the HI and LO macro are correct ? \$\endgroup\$ – Ahmed Saleh Oct 14 '16 at 10:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.