5213 and spi eeprom

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

5213 and spi eeprom

3,109 Views
airswit
Contributor III
hi everyone,

i am trying to connect a serial eeprom (through spi) to my controller, and i have written some code that looks good in my mind, but doesn't seem to be working. Has anyone out there had experience with the microchip 25lc010aa eeprom? I will show my code that i have written. I am trying to use the readstring and storestring routines to write a block of 8 bytes to the memory. any help appreciated

#include "QSPI_functions.h"
#define EEPROM_CS 0xB
#define STORE_ADDR 0x10

//these are our instructions to send to the eeprom for various operations
#define EEPROM_READ 0x03
#define EEPROM_WRITE 0x02
#define EEPROM_WRDI 0x04
#define EEPROM_WREN 0x06
#define EEPROM_RDSR 0x05
#define EEPROM_WRSR 0x01

//this function saves a single value to the EEPROM sitting on the SPI Bus

void storeByte(uint8 addr,uint8 value)
{
uint16 cs[5] = {EEPROM_CS,0xFF,EEPROM_CS,EEPROM_CS,EEPROM_CS};
uint16 send[] = {EEPROM_WREN,0x00,EEPROM_WRITE,0x00,0x00};
uint16 receive[5];
send[3] = addr;
send[4] = value;

QSPIInit8Bit();
while(!eepromReady()); ///make sure there is not a write in progress!
QSPITransferCommandAlt(cs,5);
QSPITransferData(send,receive,5);

}

//this function sends a block of data to the eeprom. data length is limited
//by the qspi controller to be 14 bytes or less, but this should not be a
//problem (hopefully won't need this much space, as it is!)

void storeString(uint8 addr,uint8* values,uint8 length)
{
uint8 i;
uint16 cs[16] = {EEPROM_CS,EEPROM_CS,EEPROM_CS,EEPROM_CS,EEPROM_CS,EEPROM_CS,EEPROM_CS,EEPROM_CS,EEPROM_CS,EEPROM_CS,EEPROM_CS,EEPROM_CS,EEPROM_CS,EEPROM_CS,EEPROM_CS,EEPROM_CS};
uint16 send[16] = {EEPROM_WREN},receive[16];
QSPIInit8Bit();
while(!eepromReady()); //wait for the mem to be ready
QSPITransferCommandAlt(cs,1); //set write mode
QSPITransferData(send,receive,1);
send[0] = EEPROM_WRITE;
send[1] = addr;
for(i=0 ; i
send[i+2] = values[i]; //copy our data to qspi array
QSPITransferCommandAlt(cs,length+2);
QSPITransferData(send,receive,length+2); //send our write command and data!
}

void readByte(uint8 addr,uint8* value)
{
uint16 cs[3] = {EEPROM_CS,EEPROM_CS,EEPROM_CS};
uint16 send[3] = {EEPROM_READ,0x00,0x00};
uint16 receive[3];
send[1] = addr;
QSPIInit8Bit();
QSPITransferCommandAlt(cs,3);
QSPITransferData(send,receive,3); //send instruction/read value!
*value = receive[2]; //return the value
}

//reads the whole block of data (well, 14 bytes...), and returns it

void readString(uint8 addr, uint8* values)
{
uint8 i;
uint16 cs[16] = {EEPROM_CS,EEPROM_CS,EEPROM_CS,EEPROM_CS,EEPROM_CS,EEPROM_CS,EEPROM_CS,EEPROM_CS,EEPROM_CS,EEPROM_CS,EEPROM_CS,EEPROM_CS,EEPROM_CS,EEPROM_CS,EEPROM_CS,EEPROM_CS};
uint16 send[16] = {EEPROM_READ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},receive[16];
send[2] = addr;
QSPIInit8Bit();
QSPITransferCommandAlt(cs,16);
QSPITransferData(send,receive,16);
for(i=0 ; i14 ; i++)
values[i] = receive[i+2];
}


uint8 eepromReady()
{
uint16 cs[2] = {EEPROM_CS,EEPROM_CS};
uint16 send[3] = {EEPROM_RDSR,0x00},receive[3];
QSPIInit8Bit();
QSPITransferCommandAlt(cs,2);
QSPITransferData(send,receive,2);
return !(receive[1] & 0x01);
}


---------------------------and in another file (qspifunctions.h/.c):-----------

void QSPIInit(void)
{
/* Setting the QSPI pins for QSPI purposes (by default they are GPIO's)*/
// MCF_GPIO_PQSPAR = 0x15;
MCF_GPIO_PQSPAR = 0x1555; ///get all QSPI Pins as QSPI Functions
MCF_QSPI_QMR = (MCF_QSPI_QMR_MSTR
| MCF_QSPI_QMR_BITS_16
| MCF_QSPI_QMR_CPHA
//| MCF_QSPI_QMR_BITS_8
| MCF_QSPI_QMR_BAUD(10));
//^^ settings:master,16 bit xfers,falling edge data clock,4MHz clock

MCF_QSPI_QDLYR = (MCF_QSPI_QDLYR_QCD(1) | MCF_QSPI_QDLYR_DTL(1));
MCF_QSPI_QIR = (MCF_QSPI_QIR_WCEFB | MCF_QSPI_QIR_ABRTB |
MCF_QSPI_QIR_ABRTL | MCF_QSPI_QIR_WCEF |
MCF_QSPI_QIR_ABRT | MCF_QSPI_QIR_SPIF);
MCF_QSPI_QWR |= MCF_QSPI_QWR_CSIV; //active low chip selects
return;
}

void QSPIInit8Bit(void)
{
MCF_GPIO_PQSPAR = 0x1555;
MCF_QSPI_QMR = (MCF_QSPI_QMR_MSTR
| MCF_QSPI_QMR_BITS(8)
| MCF_QSPI_QMR_CPHA
| MCF_QSPI_QMR_BAUD(10));
MCF_QSPI_QDLYR = (MCF_QSPI_QDLYR_QCD(1) | MCF_QSPI_QDLYR_DTL(1));
MCF_QSPI_QIR = (MCF_QSPI_QIR_WCEFB | MCF_QSPI_QIR_ABRTB |
MCF_QSPI_QIR_ABRTL | MCF_QSPI_QIR_WCEF |
MCF_QSPI_QIR_ABRT | MCF_QSPI_QIR_SPIF);
MCF_QSPI_QWR |= MCF_QSPI_QWR_CSIV; //active low chip selects
return;

}

/*
* In each command buffer put the control and chipselect
*/
void QSPITransferCommand(uint16 *chipselect, uint8 length )
{

unsigned char i;
MCF_QSPI_QAR = 0x20;
MCF_QSPI_QWR = MCF_QSPI_QWR_CSIV
| MCF_QSPI_QWR_ENDQP(length-1)
| MCF_QSPI_QWR_NEWQP(0x00);
for(i = 0 ; i length; i++)
{
QSPISetTransferCommand(chipselect[i],0);
}
return;
}

//this is the same as above, but keeps the CS line constant throughout xfer
void QSPITransferCommandAlt(uint16 *chipselect, uint8 length )
{

unsigned char i;
MCF_QSPI_QAR = 0x20;
MCF_QSPI_QWR = MCF_QSPI_QWR_CSIV
| MCF_QSPI_QWR_ENDQP(length-1)
| MCF_QSPI_QWR_NEWQP(0x00);
for(i = 0 ; i length; i++)
{
QSPISetTransferCommand(chipselect[i],1);
}
return;
}



/*
* fill the data buffer with the data we want to send and sended
*/
void QSPITransferData(uint16 *send, uint16 *receive, uint8 length)
{

unsigned char i;
uint16 temp;

MCF_QSPI_QAR = 0x00; //addr of 'data ram'
for(i = 0; i length; i++) //send all data values to data ram
MCF_QSPI_QDR = send[i];

MCF_QSPI_QDLYR |= MCF_QSPI_QDLYR_SPE; //enable transfer

while (!(MCF_QSPI_QIR & MCF_QSPI_QIR_SPIF))
; /* Empty Body */

MCF_QSPI_QAR = 0x10;
for (i = 0; i length; i++)
receive[i] = MCF_QSPI_QDR;

return;
}
/*
* build the control word with the chipselect
*/
void QSPISetTransferCommand (unsigned char u8CS, unsigned char u8Cont)
{

MCF_QSPI_QCR = (u8Cont 15)| (MCF_QSPI_QCR_BITSE | MCF_QSPI_QCR_DT |
MCF_QSPI_QCR_DSCK | MCF_QSPI_QCR_CS(u8CS));
return;
}



the code in qspifunctions should be working, because i have successfully used them to write to a d/a on the bus.

any thoughts?!


thanks in advance,
Trevor
Labels (1)
0 Kudos
3 Replies

884 Views
mjbcswitzerland
Specialist V
Hi Trevor

I use the M95512 from Microchip as EEPROM based file system via SPI for the M5223X. The QSPI is compatible with the 5213 and also the project has been run on a 5213.

I haven't used the 25lc010aa but know that the other one requires te CS to be stable for a complete transfer and I found it easier to control the CS as simple port output rather than program the QSPI buffers to perform the job. Just setting up the buffers requires rather more code and then maintenance of it is difficult since it requires detailed knowledge of the QSPI operation. This may be worth checking in your project.

There is a tutorial about building and using an EEPROM based SPI file system here:
http://www.mjbc.ch/documents/uTasker/uTaskerSPI_EEPROM.PDF

Full code and support for it is available as part of the uTasker project which is free for educational and other non-commerical projects. See the following post for more details and links, including online demos:
http://forums.freescale.com/freescale/board/message?board.id=CFCOMM&message.id=274
The project supports the M5223X and M9S12NE64 and is aimed at embedded IP project but also works with the 5213 (apart from the Ethernet part of course).

See also the uTasker's own web site at www.uTasker.com

Regards

Mark Butcher
www.mjbc.ch
0 Kudos

884 Views
airswit
Contributor III
alright, so i have been able to look at the waveform on a scope, and my problem is that the qspi module is not transmitting the data that i want to send. it correctly sends 8 clock pulses, but the data line is always low during all 16 xfers (trying to read a 14byte block, + send the read command+ send the addr). the command word and the address are not all zeros, yet when i try to send them, only zeros get sent. My transfer functions work with a 16 bit d/a, so that doesn't seem to be the problem. the only difference i have between xfering to my d/a and this eeprom is that the eeprom is 8 bits (set bit 14 in the command register for the 16 bit xfer,clear for 8), and i cleared the cpha bit in the mode register (chip selects stay in active state between transfers).

Does anyone know why this is happening?!
0 Kudos

884 Views
steve_fae
Senior Contributor I

Not trying to make things more difficult, but I am about to write some DSC code to store a big table in an SPI eeprom.

The typical 25xx series device has only 16 bytes per page.  So if I have to store 400 elements, basically a table of 17 elements x 19 rows its going to be painful.  Cypress bought Ramtron's FRAM.  So for my 400 element table, I only have to worry about 2 pages and I don't have to worry about testing the eeprom to make sure the write cycle is complete.

Nonvolatile SRAMs - nvSRAM - Memory - Cypress Semiconductor

Hope this helps. 

0 Kudos