Hi all,
I am facing some problems with SPI interfacing to a serial EEPROM, the 93LC46B. I have this chip on the QL200 dev board, so I am not worried about the circuit diagram.
My code (header and main code file) are given below,
SPICOMM.H
TESTSPI.C
1) 93LC46B serial eeprom - Instructions, addresses and write data are clocked into the EEPROM's DI pin on the rising edge of SCK. I have thus configured the SSP module for Mode(1,1) operation
2) spiWrite() not working as expected - Based on the timing diagrams for the various instructions in the EEPROM's http://ww1.microchip.com/.../DeviceDoc/21749G.pdf']datasheet[/link], the DO pin for the EEPROM, and thus the SDI pin (RB4) for the PIC must experience BUSY and READY signals. However, this doesn't seem to be happening. Please see the oscilloscope screenshot below. Ch1 is SCK, Ch2 is SDI. The behavior seems to be strange, and I guess if someone could illustrate where I am going wrong, that would be awesome!
3) spiWrite() actually working? - Is the spiWrite() actually working? I had to ask myself this question because when I place it inside a while(1) loop, and let it run through indefinitely, it doesn't stop at while(!SDI). This means that SDI is changing state, but then again, I can't seem to notice anything on the oscilloscope screen that would confirm this hunch. Could there be something else that's going on? Looks unlikely.
4) spiRead() - Assuming spiWrite() is working, I tried using spiRead() with the appropriate addresses, and I noticed that now the code gets stuck at the first while(!BF).
Overall, I am somewhat short on time, so I'd appreciate suggestions/replies ... anything that could get me thinking again, coz right now I have no clue what to do (just tired).
Thanks again!
I am facing some problems with SPI interfacing to a serial EEPROM, the 93LC46B. I have this chip on the QL200 dev board, so I am not worried about the circuit diagram.
My code (header and main code file) are given below,
SPICOMM.H
Rich (BB code):
#include <pic.h>
// DELAY VALUES FOR SPI COMM
#define _XTAL_FREQ 4e6 // Default operating frequency
#define DELAY_1U __delay_us(1);
#define DELAY_2U __delay_us(2);
#define DELAY_5U __delay_us(5);
// CONTROL LINES FOR SPI
#define CS RB5 // Chip select
#define SCK RB6 // Serial Clock
#define SDO RC7 // Serial Data Out (MOSI)
#define SDI RB4 // Serial Data In (MISO)
// EEPROM command base-bytes (logical OR of address necessary)
#define START 0x1 // Start
#define ERASE(x) (0xc0 | x) // Erase @ address x
#define ERAL 0x20 // Erase all memory locations
#define EWDS 0x00 // Erase/write disable
#define EWEN 0x30 // Erase/write enable
#define READ(x) (0x80 | x) // Read from address x
#define WRITE(x) (0x40 | x) // Write @ address x
#define WRAL 0x01 // Write to all memory locations
#define DUMMY 0x00 // Dummy data to push out
// SPI initialization function
void spiInit(void);
// Write to EEPROM
void spiWrite(unsigned int, unsigned char);
// Read from EEPROM
void spiRead(unsigned char);
Rich (BB code):
#include <pic.h>
#include "spicomm.h"
__CONFIG(FCMDIS & IESODIS & BORDIS & UNPROTECT & MCLRDIS & PWRTEN & WDTDIS & INTIO);
// Received data buffer
unsigned int recvData;
unsigned char recvByte;
// Macro function for communicating with SPI
#define SPI_COMM(x) { SSPBUF=START;\
BF=0;\
while(!BF);\
recvByte = SSPBUF;\
SSPBUF=x;\
BF=0;\
while(!BF);\
recvByte = SSPBUF;}
#define SPI_COMM8(x) { SSPBUF=x;\
BF=0;\
while(!BF);\
recvByte = SSPBUF;}
#define SPI_WREN { CS_HI;\
SPI_COMM(EWEN);\
CS_LO;}
#define SPI_WRDS { CS_HI;\
SPI_COMM(EWDS);\
CS_LO;}
#define CS_HI { DELAY_2U;\
CS=1;\
DELAY_2U;}
#define CS_LO { DELAY_2U;\
CS=0;\
DELAY_2U;}
// SPI initialization function
// CS RC2 // Chip select
// SCK RB6 // Serial Clock
// SDO RC7 // Serial Data Out (MOSI)
// SDI RB4 // Serial Data In (MISO)
void spiInit(void)
{
ANSELH = 0x00; // Configure ports for digital IO
ANSEL = 0x00;
TRISB = 0x10; // Configure SDI pin as input
TRISC = 0x00; // For PORTC pins to behave as outputs
INTCON = 0x00; // Disable interrupts
PIE1 = 0x00; // Disable peripheral interrupt
CS = 0; // Pull down Chip Select to low (standby mode)
SSPSTAT = 0x20;
SSPCON = 0x31; // @ Fosc/16
}
// Write to EEPROM
void spiWrite(unsigned int word, unsigned char addr)
{
if(addr > 63) // 64k x 16 memory
return;
SPI_WREN; // Write enable
CS_HI; // Come out of standby mode
SPI_COMM(WRITE(addr));
SPI_COMM((char)(word >> 8)); // Send MSB!!
SPI_COMM((char)word); // Send LSB!!
CS_LO;
CS_HI;
while(!SDI); // Busy-wait for EEPROM to write data
CS_LO;
SPI_WRDS;
}
// Read from EEPROM
void spiRead(unsigned char addr)
{
if(addr > 63) // 64k x 16 memory
return;
CS_HI;
SPI_COMM(READ(addr)); // Send READ command
SPI_COMM8(DUMMY); // Send dummy data
while(!BF);
recvData = SSPBUF;
SPI_COMM8(DUMMY); // Send dummy data
while(!BF); // Wait for low byte
recvData = (recvData << 8) + SSPBUF;
CS_LO;
}
// This is our main!!
int main(void)
{
char ch;
spiInit(); // Initialize SPI port
recvByte = 0x88;
WPUA = 0x33;
OPTION = OPTION | 0x80;
TRISA = 0x00;
while(1)
{
PORTA = 0x01;
spiWrite(0x1234,0x01);
PORTA = 0x02;
__delay_us(1);
}
}
2) spiWrite() not working as expected - Based on the timing diagrams for the various instructions in the EEPROM's http://ww1.microchip.com/.../DeviceDoc/21749G.pdf']datasheet[/link], the DO pin for the EEPROM, and thus the SDI pin (RB4) for the PIC must experience BUSY and READY signals. However, this doesn't seem to be happening. Please see the oscilloscope screenshot below. Ch1 is SCK, Ch2 is SDI. The behavior seems to be strange, and I guess if someone could illustrate where I am going wrong, that would be awesome!
3) spiWrite() actually working? - Is the spiWrite() actually working? I had to ask myself this question because when I place it inside a while(1) loop, and let it run through indefinitely, it doesn't stop at while(!SDI). This means that SDI is changing state, but then again, I can't seem to notice anything on the oscilloscope screen that would confirm this hunch. Could there be something else that's going on? Looks unlikely.
4) spiRead() - Assuming spiWrite() is working, I tried using spiRead() with the appropriate addresses, and I noticed that now the code gets stuck at the first while(!BF).
Overall, I am somewhat short on time, so I'd appreciate suggestions/replies ... anything that could get me thinking again, coz right now I have no clue what to do (just tired).
Thanks again!