This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AT45DB081D serial EEPROM code not working ( uC LM3s5951 is used)

I am using AT45DB081D atmel IC and lm3s5951 stallaries controller
My code is working with GPIO but not with SPI my SPI code is as shown bellow:-

#define SSI_CLK       GPIO_PIN_0
#define SSI_CS        GPIO_PIN_1
#define SSI_TX        GPIO_PIN_3
#define SSI_RX        GPIO_PIN_2

unsigned long data;
int main(void){
  
    
unsigned long BufReception;
  
    
SysCtlClockSet(SYSCTL_SYSDIV_4 SYSCTL_USE_OSC SYSCTL_OSC_MAIN |
                   
SYSCTL_XTAL_8MHZ);
    
    
SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI1);
    
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);  

GPIOPinTypeGPIOOutPut(GPIO_PORTA_BASE, SSI_CS);
    
GPIOPinWrite(GPIO_PORTA_BASESSI_CSSSI_CS);
    
GPIOPinTypeSSI(GPIO_PORTA_BASESSI_CLK SSI_TX SSI_RX );

    
SSIConfigSetExpClk(SSI0_BASESysCtlClockGet(), SSI_FRF_MOTO_MODE_0
                       
SSI_MODE_MASTER, 10000008);
    
    
SSIEnable(SSI0_BASE);
DelayUs(10); //10uSec
Spi_erase();
Buffer_write(); // buffer 1 write
Buffer_read(); // buffer 1 read
LcdDisplay(data);//lcd display

}

void Spi_erase()
{
uint16 block_counter = 0;
unit8 addfld[2];

     Df_ReadyBusy();
   while(block_counter<512) //total 512 block
   {
    addfld[0]=((uint8)(block_counter>>4));
    addfld[1]=((uint8)(block_counter<<4));
   
GPIOPinWrite(GPIO_PORTA_BASESSI_CS0);  //chip select low
    
    
SSIDataPut(SSI0_BASE0x50);  //block erase 

    SSIDataGet(SSI0_BASE, &dummyBuf);//dummy to clear write buffer
    
SSIDataPut(SSI0_BASE, &addfld[0]);
    
SSIDataGet(SSI0_BASE, &dummyBuf);
    
SSIDataPut(SSI0_BASE, &addfld[0]);  //24 bits address
    
SSIDataGet(SSI0_BASE, &dummyBuf);
    
SSIDataPut(SSI0_BASE0x00);
    
SSIDataGet(SSI0_BASE, &dummyBuf);

    GPIOPinWrite(GPIO_PORTA_BASESSI_CSSSI_CS);//chip select high 
    Df_ReadyBusy();  
  
  }

}

void buffer_read()
{
   Df_ReadyBusy();
  GPIOPinWrite(GPIO_PORTA_BASESSI_CS0);  //chip select low
   
SSIDataPut(SSI0_BASE0xD4);  //read buffer 1 

    SSIDataGet(SSI0_BASE, &dummyBuf);//dummy to clear write buffer
    
SSIDataPut(SSI0_BASE, 0x00);
    
SSIDataGet(SSI0_BASE, &dummyBuf);//dummy to clear write buffer
    
SSIDataPut(SSI0_BASE, 0x00);  //24 bits address
    
SSIDataGet(SSI0_BASE, &dummyBuf);//dummy to clear write buffer
    
SSIDataPut(SSI0_BASE0x00);
   
SSIDataGet(SSI0_BASE, &dummyBuf);//dummy to clear write buffer

       SSIDataPut(SSI0_BASE0x00);

      SSIDataGet(SSI0_BASE, &data);//read data in 'data'

    GPIOPinWrite(GPIO_PORTA_BASESSI_CSSSI_CS);//chip select high 

}

void buffer_write()
{
   Df_ReadyBusy();
  GPIOPinWrite(GPIO_PORTA_BASESSI_CS0);  //chip select low
   
SSIDataPut(SSI0_BASE0x84);  //read buffer 1 

    SSIDataGet(SSI0_BASE, &dummyBuf);//dummy to clear write buffer
    
SSIDataPut(SSI0_BASE, 0x00);
    
SSIDataGet(SSI0_BASE, &dummyBuf);//dummy to clear write buffer
    
SSIDataPut(SSI0_BASE, 0x00);  //24 bits address
    
SSIDataGet(SSI0_BASE, &dummyBuf);//dummy to clear write buffer
    
SSIDataPut(SSI0_BASE0x00);
   
SSIDataGet(SSI0_BASE, &dummyBuf);//dummy to clear write buffer

       SSIDataGet(SSI0_BASE, 0x41); // 'A' character

    GPIOPinWrite(GPIO_PORTA_BASESSI_CSSSI_CS);//chip select high 

}

void  Df_ReadyBusy()
{
uint8 byResult;
for(;;)
{
byResult = GetFlashStatus();
if(byResult & 0x80)
{
break;
}
}
Delay(2);
}


unsigned long GetFlashStatus()
{
uint8 ret;
unsigned long ret1;
GPIOPinWrite(GPIO_PORTA_BASESSI_CS0);  //chip select low
 SSIDataPut(SSI0_BASE, 0x57);
SSIDataGet(SSI0_BASE, &ret1);

GPIOPinWrite(GPIO_PORTA_BASESSI_CSSSI_CS);//chip select high 
ret=(uint8)ret1;
return ret;


}

 My code is not working and it is hang in Df_ReadyBusy() function ,help me please................

 

 

 

 

  • please tell me whether any mistake in my code ...my SPI conf. is right or wrong .....is there need of dummy bit

  • Hi,

    Two problems with your code:

    a) while first you enabled the SSI1 peripheral, all further SPI functions calls uses SSI0;

    b) while erasing and writing the EEPROM: first send the command and then wait for completion (i.e. remove the calls to status at the beginning and let it active while command is executing).

    And one more - did not checked the data sheet of your device, but some EEPROMs need to write to them Write_enable command first before the write command - check your device sheet to see if that is the case.

    Petrei

  • Hi Petrei ,

    I have successfully completed reading and writing with GPIO ( so there is no problem of Write_enable ) , but i am unable to do the same with SPI

    As suggested by you ,

    Petrei said:

    Two problems with your code:

    a) while first you enabled the SSI1 peripheral, all further SPI functions calls uses SSI0;

    b) while erasing and writing the EEPROM: first send the command and then wait for completion (i.e. remove the calls to status at the beginning and let it active while command is executing).

     

     

    #define SSI_CLK       GPIO_PIN_0
    #define SSI_CS        GPIO_PIN_1
    #define SSI_TX        GPIO_PIN_3
    #define SSI_RX        GPIO_PIN_2

    unsigned long data;
    int main(void){
      
        
    unsigned long BufReception;
      
        
    SysCtlClockSet(SYSCTL_SYSDIV_4 SYSCTL_USE_OSC SYSCTL_OSC_MAIN |
                       
    SYSCTL_XTAL_8MHZ);
        
        
    SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI1);
        
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE); 

    GPIOPinConfigure(GPIO_PE0_SSI1CLK); //==========configure clk
    GPIOPinConfigure(GPIO_PE2_SSI1RX);// ==========configure Rx
    GPIOPinConfigure(GPIO_PE3_SSI1TX);// ==========configure Tx

    GPIOPinTypeGPIOOutPut(GPIO_PORTA_BASE, SSI_CS);
        
    GPIOPinWrite(GPIO_PORTA_BASESSI_CSSSI_CS);
        
    GPIOPinTypeSSI(GPIO_PORTA_BASESSI_CLK SSI_TX SSI_RX );

        
    SSIConfigSetExpClk(SSI0_BASESysCtlClockGet(), SSI_FRF_MOTO_MODE_0
                           
    SSI_MODE_MASTER, 10000008);
        
        
    SSIEnable(SSI0_BASE);
    DelayUs(10); //10uSec
    Spi_erase();
    Buffer_write(); // buffer 1 write
    Buffer_read(); // buffer 1 read
    LcdDisplay(data);//lcd display

    }

    void Spi_erase()
    {
    uint16 block_counter = 0;
    unit8 addfld[2];

         Df_ReadyBusy();
       while(block_counter<512) //total 512 block
       {
        addfld[0]=((uint8)(block_counter>>4));
        addfld[1]=((uint8)(block_counter<<4));
       
    GPIOPinWrite(GPIO_PORTA_BASESSI_CS0);  //chip select low
        
        
    SSIDataPut(SSI1_BASE0x50);  //block erase 

        SSIDataGet(SSI1_BASE, &dummyBuf);//dummy to clear write buffer
        
    SSIDataPut(SSI1_BASE, &addfld[0]);
        
    SSIDataGet(SSI1_BASE, &dummyBuf);
        
    SSIDataPut(SSI1_BASE, &addfld[0]);  //24 bits address
        
    SSIDataGet(SSI1_BASE, &dummyBuf);
        
    SSIDataPut(SSI1_BASE0x00);
        
    SSIDataGet(SSI1_BASE, &dummyBuf);

        GPIOPinWrite(GPIO_PORTE_BASESSI_CSSSI_CS);//chip select high 
        Df_ReadyBusy();  
      
      }

    }

    void buffer_read()
    {

      GPIOPinWrite(GPIO_PORTE_BASESSI_CS0);  //chip select low
       
    SSIDataPut(SSI1_BASE0xD4);  //read buffer 1 

        Df_ReadyBusy();

        SSIDataGet(SSI1_BASE, &dummyBuf);//dummy to clear write buffer
        
    SSIDataPut(SSI1_BASE, 0x00);
        
    SSIDataGet(SSI1_BASE, &dummyBuf);//dummy to clear write buffer
        
    SSIDataPut(SSI1_BASE, 0x00);  //24 bits address
        
    SSIDataGet(SSI1_BASE, &dummyBuf);//dummy to clear write buffer
        
    SSIDataPut(SSI1_BASE0x00);
       
    SSIDataGet(SSI1_BASE, &dummyBuf);//dummy to clear write buffer

           SSIDataPut(SSI1_BASE0x00);

          SSIDataGet(SSI1_BASE, &data);//read data in 'data'

        GPIOPinWrite(GPIO_PORTE_BASESSI_CSSSI_CS);//chip select high 
        Df_ReadyBusy();

    }

    void buffer_write()
    {
      
      GPIOPinWrite(GPIO_PORTE_BASESSI_CS0);  //chip select low
     
    SSIDataPut(SSI1_BASE0x84);  //read buffer 1 
          Df_ReadyBusy();

        SSIDataGet(SSI1_BASE, &dummyBuf);//dummy to clear write buffer

        SSIDataPut(SSI1_BASE, 0x00);
        
    SSIDataGet(SSI1_BASE, &dummyBuf);//dummy to clear write buffer
        
    SSIDataPut(SSI1_BASE, 0x00);  //24 bits address
        
    SSIDataGet(SSI1_BASE, &dummyBuf);//dummy to clear write buffer
        
    SSIDataPut(SSI1_BASE0x00);
       
    SSIDataGet(SSI1_BASE, &dummyBuf);//dummy to clear write buffer

           SSIDataGet(SSI1_BASE, 0x41); // 'A' character

        GPIOPinWrite(GPIO_PORTE_BASESSI_CSSSI_CS);//chip select high 
        Df_ReadyBusy();

    }

    void  Df_ReadyBusy()
    {
    uint8 byResult;
    for(;;)
    {
    byResult = GetFlashStatus();
    if(byResult & 0x80)
    {
    break;
    }
    }
    Delay(2);
    }


    unsigned long GetFlashStatus()
    {
    uint8 ret;
    unsigned long ret1;
    GPIOPinWrite(GPIO_PORTE_BASESSI_CS0);  //chip select low
     SSIDataPut(SSI1_BASE, 0x57);
    SSIDataGet(SSI1_BASE, &ret1);

    GPIOPinWrite(GPIO_PORTE_BASESSI_CSSSI_CS);//chip select high 
    ret=(uint8)ret1;
    return ret;


    }


    I have done changes as you told and added these commands
     GPIOPinConfigure(GPIO_PE0_SSI1CLK); //==========configure clk
    GPIOPinConfigure(GPIO_PE2_SSI1RX);// ==========configure Rx
    GPIOPinConfigure(GPIO_PE3_SSI1TX);// ==========configure Tx
    But still it is not working.Every time it read command read 255 only.I think there is problem in "SSI" configure but where i dont know



     

     

  • Hi,

    In this code (and similar) :

    void buffer_write()
    {
      
      GPIOPinWrite(GPIO_PORTE_BASE, SSI_CS, 0);  //chip select low
      SSIDataPut(SSI1_BASE, 0x84);  //read buffer 1 
          Df_ReadyBusy();

    Your call to this function Df.... first set  CS low, then high, so further access to SPI is done with CS high, instead low, so that's why I suggested you to remove this function at this place.

    Next, changing from SPI0 to needed SPI1 implies also some other pins - I did not cheched if they are the corect ones.

    Petrei

  • HI,

    I HAVE DONE CHANGES BUT STILL IT IS NOT WORKING..

    AS U SAID

    Petrei said:

    Hi,

    In this code (and similar) :

    void buffer_write()
    {
      
      GPIOPinWrite(GPIO_PORTE_BASE, SSI_CS, 0);  //chip select low
      SSIDataPut(SSI1_BASE, 0x84);  //read buffer 1 
          Df_ReadyBusy();

    Your call to this function Df.... first set  CS low, then high, so further access to SPI is done with CS high, instead low, so that's why I suggested you to remove this function at this place.

    Next, changing from SPI0 to needed SPI1 implies also some other pins - I did not cheched if they are the corect ones.

    Petrei

    STILL.....EVERY TIME IT READ 225

    #define SSI_CLK       GPIO_PIN_0
    #define SSI_CS        GPIO_PIN_1
    #define SSI_TX        GPIO_PIN_3
    #define SSI_RX        GPIO_PIN_2

    unsigned long data;
    int main(void){
      
        
    unsigned long BufReception;
      
        
    SysCtlClockSet(SYSCTL_SYSDIV_4 SYSCTL_USE_OSC SYSCTL_OSC_MAIN |
                       
    SYSCTL_XTAL_8MHZ);
        
        
    SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI1);
        
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE); 

    GPIOPinConfigure(GPIO_PE0_SSI1CLK); //==========configure clk
    GPIOPinConfigure(GPIO_PE2_SSI1RX);// ==========configure Rx
    GPIOPinConfigure(GPIO_PE3_SSI1TX);// ==========configure Tx

    GPIOPinTypeGPIOOutPut(GPIO_PORTA_BASE, SSI_CS);
        
    GPIOPinWrite(GPIO_PORTA_BASESSI_CSSSI_CS);
        
    GPIOPinTypeSSI(GPIO_PORTA_BASESSI_CLK SSI_TX SSI_RX );

        
    SSIConfigSetExpClk(SSI0_BASESysCtlClockGet(), SSI_FRF_MOTO_MODE_0
                           
    SSI_MODE_MASTER, 10000008);
        
        
    SSIEnable(SSI0_BASE);
    DelayUs(10); //10uSec
    Spi_erase();
    Buffer_write(); // buffer 1 write
    Buffer_read(); // buffer 1 read
    LcdDisplay(data);//lcd display

    }

    void Spi_erase()
    {
    uint16 block_counter = 0;
    unit8 addfld[2];

         Df_ReadyBusy();
       while(block_counter<512) //total 512 block
       {
        addfld[0]=((uint8)(block_counter>>4));
        addfld[1]=((uint8)(block_counter<<4));
       
    GPIOPinWrite(GPIO_PORTA_BASESSI_CS0);  //chip select low
        
        
    SSIDataPut(SSI1_BASE0x50);  //block erase 

        SSIDataGet(SSI1_BASE, &dummyBuf);//dummy to clear write buffer
        
    SSIDataPut(SSI1_BASE, &addfld[0]);
        
    SSIDataGet(SSI1_BASE, &dummyBuf);
        
    SSIDataPut(SSI1_BASE, &addfld[0]);  //24 bits address
        
    SSIDataGet(SSI1_BASE, &dummyBuf);
        
    SSIDataPut(SSI1_BASE0x00);
        
    SSIDataGet(SSI1_BASE, &dummyBuf);

        GPIOPinWrite(GPIO_PORTE_BASESSI_CSSSI_CS);//chip select high 
        Df_ReadyBusy();  
      
      }

    }

    void buffer_read()
    {

      GPIOPinWrite(GPIO_PORTE_BASESSI_CS0);  //chip select low
       
    SSIDataPut(SSI1_BASE0xD4);  //read buffer 1 

        SSIDataGet(SSI1_BASE, &dummyBuf);//dummy to clear write buffer
        
    SSIDataPut(SSI1_BASE, 0x00);
        
    SSIDataGet(SSI1_BASE, &dummyBuf);//dummy to clear write buffer
        
    SSIDataPut(SSI1_BASE, 0x00);  //24 bits address
        
    SSIDataGet(SSI1_BASE, &dummyBuf);//dummy to clear write buffer
        
    SSIDataPut(SSI1_BASE0x00);
       
    SSIDataGet(SSI1_BASE, &dummyBuf);//dummy to clear write buffer

           SSIDataPut(SSI1_BASE,dummyBuf);

          SSIDataGet(SSI1_BASE, &data);//read data in 'data'

        GPIOPinWrite(GPIO_PORTE_BASESSI_CSSSI_CS);//chip select high 
        Df_ReadyBusy();

    }

    void buffer_write()
    {
      
      GPIOPinWrite(GPIO_PORTE_BASESSI_CS0);  //chip select low
     
    SSIDataPut(SSI1_BASE0x84);  //read buffer 1 

        SSIDataGet(SSI1_BASE, &dummyBuf);//dummy to clear write buffer

        SSIDataPut(SSI1_BASE, 0x00);
        
    SSIDataGet(SSI1_BASE, &dummyBuf);//dummy to clear write buffer
        
    SSIDataPut(SSI1_BASE, 0x00);  //24 bits address
        
    SSIDataGet(SSI1_BASE, &dummyBuf);//dummy to clear write buffer
        
    SSIDataPut(SSI1_BASE0x00);
       
    SSIDataGet(SSI1_BASE, &dummyBuf);//dummy to clear write buffer

           SSIDataPut(SSI1_BASE, 0x41); // 'A' character

           SSIDataGet(SSI1_BASE, &dummyBuf);//dummy to clear write buffer

        GPIOPinWrite(GPIO_PORTE_BASESSI_CSSSI_CS);//chip select high 
        Df_ReadyBusy();

    }

    void  Df_ReadyBusy()
    {
    uint8 byResult;
    for(;;)
    {
    byResult = GetFlashStatus();
    if(byResult & 0x80)
    {
    break;
    }
    }
    Delay(2);
    }


    unsigned long GetFlashStatus()
    {
    uint8 ret;
    unsigned long ret1;
    GPIOPinWrite(GPIO_PORTE_BASESSI_CS0);  //chip select low
     SSIDataPut(SSI1_BASE, 0x57);
    SSIDataGet(SSI1_BASE, &ret1);

    GPIOPinWrite(GPIO_PORTE_BASESSI_CSSSI_CS);//chip select high 
    ret=(uint8)ret1;
    return ret;


    }
  • Hi,

    How did you configured the SPI? To use mode0 - but for this mode you should toggle CS pin for every transmitted word (Check the user manual). Also take into account the right SPI sequence - first you send something (Put) and then you read (Get) - check to see if you matched this way all your writes/reads (seems you modified in the last version). Use an oscilloscope and debug using breakpoints. Check the SPI pins status. 

    Also, as a general programming methodology, try to apply the "top-down" approach rather than "bottom-up" as it seems you have done. The last one is prone to errors and time consuming.

  • Hi,

    I downloaded the data sheet of your device and reading it confirmed my supposition in a previous post - this device has both hardware and software write protection. For hardware point of view: if you did not used, at least must have a pull-up resistor on /WP pin, do not let it floating. For software point of view, it is wise to send first the disable sector protection command before any write (see paragraph 8.1.2).

    Also, it is wise to use mode 3 - less hardware toggling. Try automatic toggling.