PIC16F690 interfacing with 93LC46B

Thread Starter

maverik007

Joined Feb 6, 2009
25
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
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);
TESTSPI.C
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); 
     } 
 }
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!
 
Top