PIC16F690 interfacing with 93LC46B

Discussion in 'The Projects Forum' started by maverik007, Oct 19, 2010.

  1. maverik007

    Thread Starter Member

    Feb 6, 2009
    25
    0
    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
    Code ( (Unknown Language)):
    1.  
    2.  #include <pic.h>
    3.  
    4.  // DELAY VALUES FOR SPI COMM
    5.  #define    _XTAL_FREQ    4e6                // Default operating frequency
    6.  #define    DELAY_1U    __delay_us(1);
    7.  #define    DELAY_2U    __delay_us(2);
    8.  #define    DELAY_5U    __delay_us(5);
    9.  
    10.  // CONTROL LINES FOR SPI
    11.  #define    CS        RB5        // Chip select
    12.  #define    SCK        RB6        // Serial Clock
    13.  #define    SDO        RC7        // Serial Data Out (MOSI)
    14.  #define    SDI        RB4        // Serial Data In (MISO)
    15.  
    16.  // EEPROM command base-bytes (logical OR of address necessary)
    17.  #define    START        0x1            // Start  
    18.  #define    ERASE(x)    (0xc0 | x)        // Erase @ address x
    19.  #define    ERAL        0x20            // Erase all memory locations  
    20.  #define    EWDS        0x00            // Erase/write disable
    21.  #define    EWEN        0x30            // Erase/write enable
    22.  #define    READ(x)        (0x80 | x)        // Read from address x
    23.  #define    WRITE(x)    (0x40 | x)        // Write @ address x
    24.  #define    WRAL        0x01            // Write to all memory locations
    25.  #define    DUMMY        0x00            // Dummy data to push out
    26.  
    27.      // SPI initialization function
    28.  void spiInit(void);
    29.  
    30.  // Write to EEPROM
    31.  void spiWrite(unsigned int, unsigned char);
    32.  
    33.  // Read from EEPROM
    34.  void spiRead(unsigned char);
    35.    
    TESTSPI.C
    Code ( (Unknown Language)):
    1.  
    2.  #include <pic.h>
    3.  #include "spicomm.h"
    4.  
    5.  __CONFIG(FCMDIS & IESODIS & BORDIS & UNPROTECT & MCLRDIS & PWRTEN & WDTDIS & INTIO);
    6.  
    7.  // Received data buffer
    8.  unsigned int    recvData;
    9.  unsigned char    recvByte;
    10.  
    11.  // Macro function for communicating with SPI
    12.  #define        SPI_COMM(x)        {    SSPBUF=START;\
    13.                                  BF=0;\
    14.                                  while(!BF);\
    15.                                  recvByte = SSPBUF;\
    16.                                  SSPBUF=x;\
    17.                                  BF=0;\
    18.                                  while(!BF);\
    19.                                  recvByte = SSPBUF;}
    20.  
    21.  #define        SPI_COMM8(x)    {    SSPBUF=x;\
    22.                                  BF=0;\
    23.                                  while(!BF);\
    24.                                  recvByte = SSPBUF;}
    25.  
    26.  #define        SPI_WREN        {    CS_HI;\
    27.                                  SPI_COMM(EWEN);\
    28.                                  CS_LO;}
    29.  
    30.  #define        SPI_WRDS        {    CS_HI;\
    31.                                  SPI_COMM(EWDS);\
    32.                                  CS_LO;}
    33.  
    34.  #define        CS_HI            {    DELAY_2U;\
    35.                                  CS=1;\
    36.                                  DELAY_2U;}
    37.  
    38.  #define        CS_LO            {    DELAY_2U;\
    39.                                  CS=0;\
    40.                                  DELAY_2U;}
    41.  
    42.  
    43.  // SPI initialization function
    44.  // CS        RC2        // Chip select
    45.  // SCK        RB6        // Serial Clock
    46.  // SDO        RC7        // Serial Data Out (MOSI)
    47.  // SDI        RB4        // Serial Data In (MISO)
    48.  void spiInit(void)
    49.  {
    50.      ANSELH = 0x00;        // Configure ports for digital IO
    51.      ANSEL = 0x00;
    52.      TRISB = 0x10;        // Configure SDI pin as input
    53.      TRISC = 0x00;        // For PORTC pins to behave as outputs
    54.  
    55.      INTCON = 0x00;        // Disable interrupts
    56.      PIE1 = 0x00;        // Disable peripheral interrupt
    57.      
    58.      CS = 0;                // Pull down Chip Select to low (standby mode)
    59.      SSPSTAT = 0x20;        
    60.      SSPCON = 0x31;        // @ Fosc/16
    61.  }
    62.  
    63.  // Write to EEPROM
    64.  void spiWrite(unsigned int word, unsigned char addr)
    65.  {
    66.      if(addr > 63)        // 64k x 16 memory
    67.          return;
    68.  
    69.      SPI_WREN;            // Write enable
    70.  
    71.      CS_HI;                    // Come out of standby mode
    72.      SPI_COMM(WRITE(addr));
    73.      SPI_COMM((char)(word >> 8));        // Send MSB!!
    74.      SPI_COMM((char)word);                // Send LSB!!
    75.      CS_LO;
    76.  
    77.      CS_HI;
    78.      while(!SDI);        // Busy-wait for EEPROM to write data
    79.      CS_LO;
    80.  
    81.      SPI_WRDS;
    82.  }
    83.  
    84.  // Read from EEPROM
    85.  void spiRead(unsigned char addr)
    86.  {
    87.      if(addr > 63)    // 64k x 16 memory
    88.          return;
    89.  
    90.      CS_HI;
    91.  
    92.      SPI_COMM(READ(addr));    // Send READ command
    93.  
    94.      SPI_COMM8(DUMMY);    // Send dummy data
    95.      while(!BF);
    96.      recvData = SSPBUF;
    97.  
    98.      SPI_COMM8(DUMMY);    // Send dummy data
    99.      while(!BF);            // Wait for low byte
    100.      recvData = (recvData << 8) + SSPBUF;
    101.  
    102.      CS_LO;
    103.  }
    104.  
    105.  // This is our main!!
    106.  int main(void)
    107.  {
    108.      char ch;
    109.      spiInit();        // Initialize SPI port
    110.      recvByte = 0x88;
    111.  
    112.      WPUA = 0x33;
    113.      OPTION = OPTION | 0x80;
    114.      TRISA = 0x00;
    115.  
    116.      while(1)
    117.      {
    118.          PORTA = 0x01;
    119.          spiWrite(0x1234,0x01);
    120.          PORTA = 0x02;
    121.          __delay_us(1);
    122.      }
    123.  }
    124.  
    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!

    [​IMG]

    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!
     
Loading...