Using AT25DF321A with MKL05Z32

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Using AT25DF321A with MKL05Z32

Jump to solution
831 Views
andreitatar
Contributor II

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

Labels (1)
0 Kudos
1 Solution
435 Views
andreitatar
Contributor II

Got it working! I had an inductive ringing effect (long wires all around the dev board). Added a 50 ohm resistor in series on the clock signal line and it works great now. Even at 10 MHz.

View solution in original post

0 Kudos
1 Reply
436 Views
andreitatar
Contributor II

Got it working! I had an inductive ringing effect (long wires all around the dev board). Added a 50 ohm resistor in series on the clock signal line and it works great now. Even at 10 MHz.

0 Kudos