7 Replies Latest reply on May 31, 2019 2:27 AM by SudheeshK_26

    SPI communication between CY15B104Q-LHXI and PIC16LF18446 - Need help

    user_4203386

      Hello,

      I would like some help to set up or correct my SPI communication.

      I've been looking for two days now and trying to make changes in vain and I don't know if the problem is in the pin configuration or in the SPI functions.

       

      Here is a summary of my situation:

      I use a PIC16LF18446 (running at 8Mhz = 32Mhz/4) and a CY15B104Q-LHXI memory purchased from Mouser. I try to read the device ID but I only get 0 or F depending on whether the pin RC2 = SDI1 is in analog or digital mode. I also tried to write a value to an address and read it but this is not conclusive. Notation : nXX = XX_bar for the XX with the bar above.

       

      Nevertheless, my pin configuration is as follows:

       

      Memory <= 400kHz => PIC



      Configuration (* = requested in the documentation of the PIC)
      SO <=> SDI1 = RC2 as Input*, digital, weak pull-up disable, open-drain
      nCS <=> nSS1 = RB4 as Input*, digital, weak pull-up disable, push-pull
      SI <=> SDO1 = RB5as Output*, digital, weak pull-up disable, push-pull
      SCK <=> SCK1 = RB6 as Output*, digital, weak pull-up disable, push-pull

       

      Is this sounds correct?

       

      Then, the SPI modes described in the PIC do not match those in the memory. With the information from both sides, I deduced that:

      PIC-Mode
      0123
      CKP0011
      CKE1010
      Memory-Mode03
      CPOL

       

      01
      CPHA01

       

      I set myself in the PIC-mode 1 configuration in order to be in Memory-mode 0 and I force the SCK to be at zero to detect mode 0 when nSS1 is set to LOW. This is converted to :

      SSP1STAT = 0b 0000 0000 ; // Mode 0 with sampled at the middle

      SSP1CON1 = 0x2A

      SSP1CON2 = 0x00

       

      Is this configuration sounds correct?

       

      Now, here is my code:

       

      In the file main.c

      En-tête 1

      #include <xc.h>

      #include "./mcc.h"

      #include <string.h>

       

      // Prototype -----------------------

      void print_bytes(void *ptr, int size);

       

      void main(void)

      {

                      PMD_Initialize();

      PIN_MANAGER_Initialize();

         

       

          printf("\n=== SPI 25.04 TEST ===\n\n");

      __delay_ms(2000);  

                     

          // Write at 0x012345 the value 0xAB, then read this latter

          uint8_t     ReadBuffer = 0x01;

          uint8_t     WriteBuffer = 0xAB;

          uint8_t     DummyBuffer = 0x00;

          long        addresse = 0x00012345;

          uint8_t     add_0 = (uint8_t)(addresse>>0);

          uint8_t     add_1 = (uint8_t)(addresse>>8);

          uint8_t     add_2 = (uint8_t)(addresse>>16);

          uint8_t     add_3 = (uint8_t)(addresse>>24);

       

       

          spi1_Initialize();

          __delay_ms(2000);

       

          printf("\n\n=== WRITING ===\n\n");

       

          printf("Step 1: Send WREN \n");

          SS1_bar_SetLow();   // nCS à 0

          DummyBuffer = spi1_exchangeByte(SPI_WREN);

          SS1_bar_SetHigh();  // nCS à 1

       

          printf("Step 2: Send WRITE \n");

          DummyBuffer = spi1_exchangeByte(SPI_WRITE);

       

          printf("Step 3: Send the addresse\n");

          DummyBuffer = spi1_exchangeByte(add_2);

          DummyBuffer = spi1_exchangeByte(add_1);

          DummyBuffer = spi1_exchangeByte(add_0);

       

          printf("Step 4: Write the value\n");

          DummyBuffer = spi1_exchangeByte(WriteBuffer);

          SS1_bar_SetHigh();  // nCS à 1

       

          printf("\n=== WRITING DONE ===\n");

       

       

       

          printf("\n\n=== READING ===\n\n");

       

          printf("Step 2: Send READ \n");

          SS1_bar_SetLow();   // nCS à 0

          DummyBuffer = spi1_exchangeByte(SPI_READ);

       

          printf("Step 3: Send the address\n");

          DummyBuffer = spi1_exchangeByte(add_2);

          DummyBuffer = spi1_exchangeByte(add_1);

          DummyBuffer = spi1_exchangeByte(add_0);

       

          printf("Step 4: Read the value\n");

          ReadBuffer = spi1_exchangeByte(DummyBuffer);

          SS1_bar_SetHigh();   // nCS à 1

       

          printf("\n=== READING DONE ===\n");

          printf("RB=%2X\n",ReadBuffer);

          print_bytes(&ReadBuffer, 1);

       

      } // End of main

       

       

       

      void print_bytes(void *ptr, int size)

      {

          unsigned char *p = ptr;

          int i;

          for (i=0; i<size; i++) {

              printf("%02hhX ", p[i]);

          }

          printf("\n");

      }

       

       

      In the file spi.c (generated with the help of the MCC of MPLAB IDE and with my modifications):

      En-tête 1

      #include <xc.h>

      #include "pin_manager.h"

      #include "spi_MCC.h"

       

      #pragma warning disable 520    

       

      uint8_t dummy = 0;

       

       

      void SPI_Read_Device_ID(uint8_t *data)

      {

          dummy = SSP1BUF; // Clear Tx buffer

         

          // RDID opcode

                      //SS1_bar_SetLow();   // nCS à 0

          dummy = spi1_exchangeByte(SPI_RDID);

       

          // Take only the fisrt byte of the device ID

                      data[0] = spi1_exchangeByte(dummy);

         

          // To read the device ID

          //spi1_exchangeBlock(data, SPI_DEV_ID_LENGTH);

                 

          SS1_bar_SetHigh(); // nCS à 1

      }

       

       

      void spi1_close(void)

      {

          SSP1CON1bits.SSPEN = 0;

      }

       

       

      //Setup SPI

      void spi1_Initialize(void)

      {

              //setup SPI

              //SSP1STAT = 0x80; // Mode 0(PIC) = Mode 0(Mem), sample at the END

              //SSP1STAT = 0x00; // Mode 0(PIC) = Mode 0(Mem), sample at the MIDDLE

              //SSP1STAT = 0xC0; // Mode 1(PIC) = Mode 0(Mem), sample at the END

              SSP1STAT = 0x40; // Mode 1(PIC) = Mode 0(Mem), sample at the MIDDLE

       

              // SSPEN enabled; CKP Idle:Low, Active:High; SSPM FOSC/4_SSPxADD;

              SSP1CON1 = 0x2A;

             

              SSP1CON2 = 0x00;

              //SSP1CON3 = 0x00;

             

              // Divider of the clock => 400 kHz

              SSP1ADD = 0x04;

       

              // Fix the SCK at 0, so when nCS is LOW, it will detect the mode 0, p.5 last §

              TRISBbits.TRISB6 = 0x00;

      }

       

       

      // Full Duplex SPI Functions

      uint8_t spi1_exchangeByte(uint8_t b)

      {

          // Clear the Write Collision flag, to allow writing

          SSP1CON1bits.WCOL = 0;

         

          SSP1BUF = b;

          while(!PIR3bits.SSP1IF);

          PIR3bits.SSP1IF = 0;

          return SSP1BUF;

      }

       

       

      void spi1_exchangeBlock(void *block, size_t blockSize)

      {

          uint8_t *data = block;

          while(blockSize--)

          {

              *data = spi1_exchangeByte(*data);

              data++;

          }

      }

       

       

      // Half Duplex SPI Functions

      void spi1_writeBlock(void *block, size_t blockSize)

      {

          uint8_t *data = block;

          while(blockSize--)

          {

              spi1_exchangeByte(*data++);

          }

      }

       

       

      void spi1_readBlock(void *block, size_t blockSize)

      {

          uint8_t *data = block;

          while(blockSize--)

          {

              *data++ = spi1_exchangeByte(0);

          }

      }

       

       

      Thank you in advance if you have taken the time to read all the way and help me.

      I remain at your disposal for further information.

       

       

      Have a good day.

      Best regards,

       

      Michael