8 Replies Latest reply on Oct 19, 2018 12:47 PM by molvera_3689726

    Reading Register from SPI Slave (Display)

    molvera_3689726

      I am currently trying to write to a few registers of my NHD-4.3-480272FT-CTXL-T display. When I am debugging, on my CY8C5888LTI-LP097, my return value for my read register functions are always returning zero. I was reading the SPI Getting Started datasheet, and it said that in order to read from a register, you must first send it a dummy byte to it can show up in the Rx buffer where I can then read it. However, this is not happening and I am always getting 0x00 back.

       

      These are my functions to read:

       

      unsigned char ft81xMemRead8(unsigned long ftAddress)

      {

        unsigned char ftData8 = 0x00;

        ss_Write(0); // Set CS# low

        SPIM_ClearRxBuffer();

        SPIM_ClearTxBuffer();

        SPIM_WriteTxData((char)(ftAddress >> 16) | MEM_READ); // Send Memory Write plus high address byte MEM_READ (command that reads)

        SPIM_WriteTxData((char)(ftAddress >> 8)); // Send middle address byte

        SPIM_WriteTxData((char)(ftAddress)); // Send low address byte

        SPIM_WriteTxData(0x00);// Send dummy byte according to datasheet of display

        SPIM_WriteTxData(0x00);// send dummy byte to get next Rx Byte.

           ftData8 = SPIM_ReadRxData(); // Read data byte

        ss_Write(1); // Set CS# high

       

       

        return ftData8; // Return byte read

      }

       

      unsigned int ft81xMemRead16(unsigned long ftAddress)

      {

        unsigned long ftData16 = 0x00;

        ss_Write(0); // Set CS# low

        SPIM_ClearRxBuffer();

        SPIM_ClearTxBuffer();

        SPIM_WriteTxData((char)(ftAddress >> 16) | MEM_READ); // Send Memory Write plus high address byte

        SPIM_WriteTxData((char)(ftAddress >> 8)); // Send middle address byte

        SPIM_WriteTxData((char)(ftAddress)); // Send low address byte

        SPIM_WriteTxData(0x00); // Send dummy byte display datsheet

        SPIM_WriteTxData(0x00);// to get Rx Buffer. I have tried debugging with and without this line.

       

       

        ftData16 = (SPIM_ReadRxData()); // Read low byte

       

       

        SPIM_WriteTxData(0x00); //added this*******************

       

       

        ftData16 = ftData16 | (SPIM_ReadRxData() << 8); // Read high byte

       

       

        ss_Write(1); // Set CS#hHigh

       

       

        return ftData16; // Return integer read

      }

       

      Message was edited by: Monica Olvera

        • 1. Re: Reading Register from SPI Slave (Display)
          user_78878863

          Each write of a SPI master also reads data from the slave. So when you write 5 bytes, 5 bytes will eb in the RX FIFO (or rather 4 since it probably is not big enough).

          Just read the RX FIFO after each byte write to remove the last value.

          • 2. Re: Reading Register from SPI Slave (Display)
            molvera_3689726

            I only have RX_FIFO_CLEAR and SPIM_STS_RX_FIFO_FULL. Which one of these would I use in order to read the Rx data?

            • 3. Re: Reading Register from SPI Slave (Display)
              user_80002741

              Thanks for posting this question. I'm doing an SPI program now. Would you be willing to upload your complete program?

               

              Thanks,

              Joe

              • 4. Re: Reading Register from SPI Slave (Display)
                user_78878863

                As soon as you call SPIM_ReadRxData() one byte is taken from the RX FIFO. Easiest is to configure to SPI to have a big enough buffer, then wait for the SPI transfer to be finished after placing the last byte to the TX buffer, and then read all the bytes you need to get to the data you want.

                • 5. Re: Reading Register from SPI Slave (Display)
                  molvera_3689726

                  So since I don't have a digital analyzer, I went to my oscilloscope and read the MISO and MOSI

                   

                  MISO: 0x00/0x4A/0x43/0x42/0xE0<-- (LSB)

                  MOSI: 0x30/0x20/0x34/0x00/0x00 <-- Address and 2 dummy bytes (MSB)

                   

                  *DISCLOSURE. I am an idiot*

                  So that last byte of my MISO is the lower byte of the data I want to read. I want to read 0x1E0 .

                  So my SPI is configured as MSB, but when I'm reading data I am reading LSB first. Is there a way to read the data as LSB instead of MSB? That's why I think I was always getting 0x00. Also I tried to increase the buffer to 6 and wasn't able to see the higher byte (0x1).

                  • 6. Re: Reading Register from SPI Slave (Display)
                    molvera_3689726

                    I just added it to my original post.

                    • 7. Re: Reading Register from SPI Slave (Display)
                      user_78878863

                      To repeat: when you send 5 bytes to the SPI slave, 5 bytes will be read by the master. Thats how SPI works. The solution to your problem is to actually read 5 bytes from the SPI RX buffer (from your description it reads as if you actuelkly need to send and read 6 bytes, and the 6th one will then be 0x01).

                      This has nothing to do with the SPI configuration (the MSB vs. LSB stand for the bit-ordering in a byte, not in the byte-ordering of the SPI slaves answer).

                      So just do 5 times a SPIM_ReadRxData().

                      • 8. Re: Reading Register from SPI Slave (Display)
                        molvera_3689726

                        Ok. I went back and I'm only using my write/read 1 byte functions (taking a step back).

                         

                        unsigned char ft81xMemRead8(unsigned long ftAddress)

                        {

                          unsigned char ftData8;

                          uint8 data_read;

                            

                          ss_Write(0); // Set CS# low

                          SPIM_ClearRxBuffer();

                          SPIM_ClearTxBuffer();

                          SPIM_WriteTxData((ftAddress >> 16) | MEM_READ); // Send Memory Write plus high address byte

                          SPIM_WriteTxData((ftAddress >> 8)); // Send middle address byte

                          SPIM_WriteTxData((ftAddress)); // Send low address byte

                          SPIM_WriteTxData(0x00); //send dummy byte

                            CyDelay(20);

                            SPIM_WriteTxData(0x00);

                            data_read = SPIM_ReadRxData();

                            SPIM_WriteTxData(0x00);

                            data_read = SPIM_ReadRxData();

                            SPIM_WriteTxData(0x00);

                            data_read = SPIM_ReadRxData();

                            SPIM_WriteTxData(0x00);

                            data_read = SPIM_ReadRxData();

                            SPIM_WriteTxData(0x00);

                            data_read = SPIM_ReadRxData();

                            SPIM_WriteTxData(0x00);

                            data_read = SPIM_ReadRxData();

                           

                          ss_Write(1); // Set CS# high

                         

                         

                          return data_read; // Return byte read

                        }

                         

                         

                        Again, I looked at my data lines in the oscilloscope

                         

                        MOSI:0x30 | 0x20| 0x6C | 0x0  | 0x0 (Sends 3 byte address one dummy byte(per display datasheet), and one dummy byte to move                                                                    last read byte in rx buffer

                        MISO: 0x0 | 0x4A | 0x43 | 0x42| 0x01 (first 4 bytes are bogus except the last one. The value I want)

                         

                        on the first "SPIM_WriteTxData(0x00)" I read a 0x00.

                        on the second one, I read 0x42. After this, if I keep reading the rx data, it's all zero. It looks like it's reading the 4th byte. My settings for SPI_Master are :

                         

                         

                        How will I be able to read the 0x01? Would I have to increase my data bits size? I tried increasing Rx and Tx Buffer Size, but then I only got 0x00s for all the bytes I was reading.