AnsweredAssumed Answered

Using AT25DF321A with MKL05Z32

Question asked by Andrei Tatar on Feb 1, 2013
Latest reply on Feb 7, 2013 by Andrei Tatar

I have the FRDM-KL05Z dev board and I'm trying to use AT25DF321A flash chip via SPI.

 

This is basically all the code I'm using:

 

uint8_t spi_ReadWriteByte(uint8_t data)
{
  while (!(SPI0_BASE_PTR->S & SPI_S_SPTEF_MASK)); //wait TX to be empty
  SPI0_BASE_PTR->D = data;
  while (!(SPI0_BASE_PTR->S & SPI_S_SPRF_MASK)); //wait RX to be full

  volatile uint8_t retData = SPI0_BASE_PTR->D;
  return retData;
}

#define EXT_SELECT() MEM_CS_MODULE_BASE_ADDRESS->PCOR = MEM_CS_PORT_MASK
#define EXT_DESELECT() MEM_CS_MODULE_BASE_ADDRESS->PSOR = MEM_CS_PORT_MASK




#define CMD_STATUS_READ

0x05


#define CMD_STATUS_WRITE
0x01


#define CMD_ERASE_CHIP

0xC7


#define CMD_WR_ENABLE

0x06


#define CMD_PROGRAM


0x02


#define CMD_READ


0x03





static uint8_t readStatus();





#define WAIT_WHILE_BUSY()
while (readStatus() & 0x01)








#define SEND_ADDRESS(addr)






\





spi_ReadWriteByte((addr >> 16) & 0xFF);
\





spi_ReadWriteByte((addr >> 8) & 0xFF);
\





spi_ReadWriteByte(addr & 0xFF)








#define CMD(cmd)






\





EXT_SELECT();




\





spi_ReadWriteByte(cmd);


\





EXT_DESELECT()








#define CMD_AND_WRITE(cmd, x)



\





EXT_SELECT();




\





spi_ReadWriteByte(cmd);


\





spi_ReadWriteByte(x);


\





EXT_DESELECT()








#define CMD_AND_READ(cmd, x)



\





EXT_SELECT();




\





spi_ReadWriteByte(cmd);


\





x = spi_ReadWriteByte(0xAA);
\





EXT_DESELECT()





static uint8_t readStatus()
{




uint8_t status;



CMD_AND_READ(0x05, status);




return status;



}


void extRead(uint32_t address, uint8_t *buffer, uint16_t count)
{




EXT_SELECT();



spi_ReadWriteByte(CMD_READ); //read command



SEND_ADDRESS(address);



while (count --) *buffer++ = spi_ReadWriteByte(0x00);



EXT_DESELECT();



}


static void extUnprotect(void)
{




CMD(CMD_WR_ENABLE);



CMD_AND_WRITE(CMD_STATUS_WRITE, 0x00);



}


void extWrite(uint32_t address, uint8_t *buffer, uint16_t count)
{




extUnprotect();



CMD(CMD_WR_ENABLE);







EXT_SELECT();



spi_ReadWriteByte(CMD_PROGRAM); 



SEND_ADDRESS(address);



while (count--) spi_ReadWriteByte(*buffer++);



EXT_DESELECT();







WAIT_WHILE_BUSY();



}


void extErase(void)
{




extUnprotect();



CMD(CMD_WR_ENABLE);



CMD(CMD_ERASE_CHIP);



WAIT_WHILE_BUSY();



}

 

The erase function takes about 20-30 sec, so it seems to work well, but when I send auxBuffer over serial, all I get is 0xFF's.

 

rxBuffer containts the correct data, everything seems just fine, but it just won't work. I tried different addresses, but same thing.

 

SPI is working, status seems correct (0x10 - 1st byte, 0x00 - 2nd byte), and if I read manufacturer id, I get 0x1F, 0x47, 0x01, 0x00. I also tried different SPI clocks (from few 100 kHz to 10 MHz), tried 2 different chips and they have the same exact behavior, tried adding delays between/after asserting/deasserting /CS.

 

I also tried setting clock polarity to high (I'm using processor expert to initialize SPI) and when I write a page (256 bytes) of AA 55 AA 55's, I get in return 55 2A D5 2A D5 2A...

 

/Hold and /WP pins are tied to VCC.

 

I'm waiting for my logic analyzer delivery I just ordered. I think the problem is an uneven number of bits in the write command but I'm not really sure...

 

Any other suggestions until then?

 

Thanks

 

 

Outcomes