Message Edited by rick123 on 2008-02-04 06:28 PM
Added p/n to subject.
if (PTAD_PTAD5 == 0) //write to the chip { address = 4; PTBD_PTBD5 = 0; //chip select low SPI_proc(6); // Command to enable the write latch PTBD_PTBD5 = 1; // chip select high PTBD_PTBD5 = 0; // chip select low SPI_proc(2); // Command to write data to EEPROM SPI_proc((address >> 16) & 0x01); // Send highest byte, only LSB matters SPI_proc((address >> 8) & 0xFF); // Send middle byte SPI_proc(address & 0xFF); SPI_proc('A' & 0xFF); // send charcter "A" to memory location 4 PTBD_PTBD5 = 1; //chip selct high }
byte SPI_proc (byte data){ while (!SPIS_SPTEF); /* Wait for Tx buffer empty */ SPID = data; /* Send byte */ while (!SPIS_SPRF); /* Wait for Rx buffer full */ return (SPID); /* Received byte value */}
void SPI_Write_Wait(void){ unsigned char Status_Register = 0x01; // Perhaps turn on an LED here if one is avaliable while (Status_Register == 0x01) // Continue until bit is cleared { PTBD_PTBD5 = 0; // Select the EEPROM SPI_proc(5); // Command to read the status register Status_Register = (SPI_proc(0xFF) & 0x01); // Write dummy bytes, read data back in and mask it PTBD_PTBD5 = 1; // Disable the EEPROM select } // Turn LED off if available}
Hello
I am using a microcontroller and a MC9S08QE128 MCF51QE128 QE128 module. I implemented the code that was corrected during the forum but I have problems.
When I read a byte from the same address, I get different values, I think I am not writing correctly in memory.
I wonder who could be wrong in the code. Below is the data EEPROM memory.
I do not know if my clock is set correctly or if the timing diagram of EEPROM memory that can fit the value of CPOL and CPHA.,
This is my code:
#include <hidef.h> /* for EnableInterrupts macro */
#include "derivative.h" /* include peripheral declarations */
typedef unsigned char UINT8;
typedef unsigned int UINT16;
void SPI_Write_Wait(void); //polling, de escritura realizandoze
UINT8 SPI_proc (byte data);
void SPI_registersetup(void);
void SPI_enable(void);
void delay(UINT16 a); //del demo SPI MASTER
/*********************************************************************/
/* Function declarations */
/*********************************************************************/
void delay (UINT16 a) {
UINT16 i = 0;
for (i; i<=a; i++){
}
}
void MCU_Init(void) {
SOPT1 = 0x23; /* Watchdog disable. Stop Mode Enable. Background Pin enable. RESET pin enable */
SCGC1 = 0x01; /* Bus Clock to the SCI1 module is enable */
SCGC2 = 0x02; /* Bus Clock to the SPI2 module is enabled */
}
void GPIO_Init(void) {
PTDD_PTDD3 = 1; /* The SS signal must be generated by software using a GPIO */
PTCDD = (UINT8) (PTCD | 0x3F); /* Configure PTC0-PTC6 as outputs */
PTEDD = (UINT8) (PTED | 0xC0); /* Configure PTE6 and PTE7 pins as outputs */
PTCD = 0x3F; /* Put 1's in port C in order to turn off the LEDs */
PTED = 0xC0; /* Put 1's in port E port in order to turn off the LEDs */
}
/*********************************************************************/
/* CONFIG SERIAL PORT */
/*********************************************************************/
void SCI_configuration (void) {
SCI1C1 = 0x00; /* 8-bit mode. Normal operation */
SCI1C2 = 0x2C; /* Receiver interrupt enable. Transmitter and receiver enable */
SCI1C3 = 0x00; /* Disable all errors interrupts */
SCI1BDL = 0x1A; /* This register and the SCI1BDH are used to configure the SCI baud rate */
SCI1BDH = 0x00; /* BUSCLK 4MHz */
/* Baud rate = -------------------- = ------------ = 9600bps */
} /* [SBR12BR0] x 16 26 x 16 */
/*********************************************************************/
/* FUNCTIONS SPI */
/*********************************************************************/
void SPI_Write_Wait(void) {
//Command to read the status register y verfificar si el ciclo de escritura esta en progreso
unsigned char Status_Register = 0x01;
// Perhaps turn on an LED here if one is avaliable
while (Status_Register == 0x01) // Continue until bit is cleared
{
PTDD_PTDD3 = 0; // Select the EEPROM
SPI_proc(5); // Command to read the status register//READ STATUS REGISTER (RDSR)
Status_Register = (SPI_proc(0xFF) & 0x01); // Write dummy bytes, read data back in and mask it
//Bit 0 (RDY) =1, entonces ciclo de escritura en progreso(pag 9)
PTDD_PTDD3 = 1; // Disable the EEPROM select
}
}
UINT8 SPI_proc (byte data){
while (!SPI2S_SPTEF); /* Wait for Tx buffer empty */
SPI2D = data; /* Send byte */
while (!SPI2S_SPRF); /* Wait for Rx buffer full */
return (SPI2D); /* Received byte value */
}
UINT8 SendRecieveSPI( UINT8 data ) /*---SPI_PROC opcional*/
{
SPI2D = data;
while(!SPI2S_SPRF) ;
data = SPI2D;
return data;
}
void SPI_registersetup(void)
{
PTDD_PTDD3 = 0; // Select the EEPROM
SPI_proc(1); // Command to write the status register
SPI_proc(0x00);
PTDD_PTDD3 = 1;
}
void SPI_enable(void)
{
PTDD_PTDD3 = 0;
SPI_proc(6); //Enable write latch
PTDD_PTDD3 = 1;
}
void SPI_configuration (void) {
SPI2BR = 0x76;//0x77;//0x75; /* Select the highest baud rate prescaler divisor and the highest baud rate divisor */
SPI2C1 = 0x52; //spi enabled polling para SPRF y SPTEF, tipo master and without interrupts
SPI2C2 = 0x10; /* Different pins for data input and data output */
(void)SPI2S;
(void)SPI2D;
}
/*********************************************************************/
/* MAIN */
/*********************************************************************/
void main(void) {
volatile unsigned long address=0;
volatile unsigned char memorydata=0;
volatile long int memorycounter=0;
volatile long int writecounter=0;
volatile UINT8 highAdd=0;
volatile UINT8 lowAdd=0;
MCU_Init(); /* Function that initializes the MCU */
GPIO_Init(); /* Function that initializes the Ports of the MCU */
SCI_configuration(); /* Function that initializes the SCI module */
SPI_configuration ();
EnableInterrupts; /* enable interrupts */
/* include your code here */
/*-------------READ--------------------*/
PTDD_PTDD3 = 0; //chip select low
SPI_proc(3); // Command to read data from EEPROM
SPI_proc(address & 0x00); // Send highest
SPI_proc(address & 0x00); //ssend lowest
for (memorycounter=0; memorycounter<10; memorycounter ++)
{
memorydata = SPI_proc(0xFF); // Read in a byte from the EEPROM
while (!SCI1S1_TDRE); // Make sure SCI transmit buffer is empty
SCI1D = memorydata;
}
PTDD_PTDD3 = 1; // chip select high
delay(600000);
//-----------------WRITE------------------------//
SPI_registersetup();
SPI_enable();//SPI_erase(); // erase the chip
SPI_Write_Wait();//SPI_statuscheck(); // make sure erase is complete
//delay(60000);
for (writecounter =0; writecounter <10; writecounter ++) //write to first 10 memory locations
{
highAdd = (writecounter >> 8) & 0xFF;
lowAdd = writecounter & 0xFF;
PTDD_PTDD3 = 0; //chip select low
SPI_proc(2); // Command to write data to EEPROM
SPI_proc(highAdd);//SPI_proc((writecounter >> 8) & 0xFF); // Send high add
SPI_proc(lowAdd); //SPI_proc(writecounter & 0xFF); // Send low add
SPI_proc(0xF0); //DATA send the current counter value to memory ??????
PTDD_PTDD3 = 1; //chip select low
SPI_Write_Wait();
}
PTCD_PTCD0 = 0; //LED
for(; {
} /* loop forever */
/* please make sure that you never leave main */
}
Thanks
Clearly format is CPOL=CPHA=0. Look at figure 4-1 in Atmel datasheet. You may notice that 1) before communication clock idles low, 2) in-data is sampled on rising edge, 3) out-data is shifted out on falling clock edge. Now open your QE reference manual and look at two figures with CPHA=0 format and CPHA=1 format. Clearly CPOL should be 0, because clock should idle low. Now decide do you need CPHA=0 or CPHA=1.
In SPI configuration you enabled SSOE bit. Clearly your should not use automatic SS and toggle chip select pin from your code. It looks like you are trying to do so, but SS pins is already driven automatically from SPI module. Try disabling SSOE and MODFEN.
Please comment all your magic (and annoying) figures, what each bit means. It is not nice at all to decifier them.
Thank you all for your help, I wrote "PTDD_PTDD3 = 1;"
and I had to change "PTDDD_PTDDD3 = 1;" for this right. I can now read and write. Thanks
byte SPI_proc (byte data){ while (!SPIS_SPTEF); /* Wait for Tx buffer empty */ SPDR = data; /* Send byte */ while (!SPIS_SPRF); /* Wait for Rx buffer full */ return (SPDR); /* Received byte value */}
SPI_proc(3); // Command to read data from EEPROMSPI_proc((address >> 16) & 0x01); // Send highest byte, only LSB mattersSPI_proc((address >> 8) & 0xFF); // Send middle byteSPI_proc(address & 0xFF); // Send lowest byte
for (memorycounter=0; memorycounter<50; memorycounter ++){ memorydata = SPI_proc(0xFF); // Read in a byte from the EEPROM while (!SCIS1_TDRE); // Make sure SCI transmit buffer is empty SCID = memorydata; // Send the byte over the SCI}
allawtterb wrote:
The first time that you use the SPI module though it should be initialized by the code JimDon posted:
(void)SPIS; // Read the status register
(void)SPID; // Read the device register