1 2 Previous Next 21 Replies Latest reply on Oct 20, 2015 3:07 AM by user_1377889

    SPI Data From Slave Device Not Displaying correct data on LCD

    mnauss_1472621

      Greetings, I have been trying to get my PSoC5LP to communicate with a Freescale MPL115A Barometer via a SPI 4 wire bus. I have encountered a problem that I am having trouble resolving. I will list the details.

         

      SETUP:

             

      PROBLEM:

         

      Data is being sent out from SPI master (PSoC5LP), MPL115A responds to data read and sends data back to SPI master.

         

      Data displayed on LCD for MSB is 00, Data for LSB is 00 should be other than zero, like 0x7E, 0xC0  See images attached for DSO data capture and LCD readout. The blue trace is data from the SPIM, yellow trace is data from MPL115A.

         

      At this point, I am not sure if I am reading the data from the MPL115 device, or is the problem with the way I am trying to display the data. I have attached the build bundle and my code is below:

         
         

      /* ========================================
       *
       * Copyright ConCon Engineering LLC, 2015
       * All Rights Reserved
       * UNPUBLISHED, LICENSED SOFTWARE.
       *
       * CONFIDENTIAL AND PROPRIETARY INFORMATION
       * WHICH IS THE PROPERTY OF ConCon Engineering LLC.
       *
       * Purpose of this design is to communicate to MPL115 Barometer and Temp sensors via SPI bus
       * Barometer and temp is used for gas sensor data correction
       * ========================================
      */
      /*  MPL115 BreakOut ------------------CY8CKIT-050
                      SDN ------------------P0[3]
                      CSN ------------------P0[2]     CS_n
                      SDO ------------------P0[1]     MISI
                      SDI ------------------P0[0]     MOSI
                      SCK ------------------P0[5]     SCLK
                      GND ------------------System conn pin P6 - 7
                      VDD ------------------System conn pin P6 - 3
      */
                      
      /* MPL115 Memory Map
         For reads must set bit 7 to 1. So a read will be 0x8X ie. Tadc_MSB 0x82           
        Address Name      Description                 Size (bits)
          0x00 Padc_MSB 10-bit Pressure output value    MSB 8
          0x01 Padc_LSB 10-bit Pressure output value    LSB 2
          0x02 Tadc_MSB 10-bit Temperature output value MSB 8
          0x03 Tadc_LSB 10-bit Temperature output value LSB 2
          0x04 a0MSB a0 coefficient MSB 8
          0x05 a0LSB a0 coefficient LSB 8
          0x06 b1MSB b1 coefficient MSB 8
          0x07 b1LSB b1 coefficient LSB 8
          0x08 b2MSB b2 coefficient MSB 8
          0x09 b2LSB b2 coefficient LSB 8
          0x0A c12MSB c12 coefficient MSB 8
          0x0B c12LSB c12 coefficient LSB 8
      */

         

      #include <project.h>
      #include <cylib.h>
      #include <stdio.h>

         

      //======================//
      //          Macros            //
      //======================//

         

      #define Wait(x)                                //    Just for better reading
      #define FALSE        0                        //    Boolean false
      #define TRUE        !FALSE                    //    and true
      #define forever        1                        //    I like that

         

      //======================//
      //     Global Variables    //
      //======================//

         

      uint8 BitStuff = 0x00u;

         


      /* *******************
      MPL115A1 Functions
      **********************/

         

      /*******************************************************************************
      * Function Name: ControlReg and ControlReg1_Write
      ********************************************************************************
      * Function enables hardware to display LED value of status register
      * Parameters led
      ********************************************************************************/
      void ControlReg1_Write (uint8 ledZ); // declaring the function
      void ControlReg_Write (uint8);
      /*****************************************************************************
      / SPI Master Read and write function (This function calls SPIM_WriteTxData
      / and SPIM_ReadRxData functions
      ******************************************************************************/

         

      void CyDelay(uint32 milliseconds);

         

      int main()
      {
      /************************
          Local variables
      *************************/
      //uint8 MyData;
      uint16 Tadc_MSB = 0x00; //Store MSB of SPI Rx data
      uint16 Tadc_LSB = 0x00;
      uint8 GoBit = 0x00;  //Press SW3 to force main to loop once else it waits
          
           CyGlobalIntEnable; /* Always enable global interrupts. */
      //********************************************************************
      //      This section of code is just for debug, remove when not needed  
      //********************************************************************
          uint8 ledZ = 0x01; //code debug
          ControlReg1_Write(ledZ);
          CyDelay(250);
          ledZ = 0x00;
          ControlReg1_Write(ledZ);
          CyDelay(250);
          ledZ = 0x01;
          ControlReg1_Write(ledZ);
          CyDelay(250);
          ledZ = 0x00;
          ControlReg1_Write(ledZ);
          CyDelay(250);
       //*******************************************************************
          
          /* Place your initialization/startup code here (e.g. MyInst_Start()) */
      // Start the LCD and Display
      LCD_Start ();
      LCD_Position(0u,0u);
      LCD_PrintString("SPI Master");
      LCD_Position(1u,0u);
      LCD_PrintString("Test Code");
      CyDelay(2000);
      ledZ = 0x01;
      ControlReg1_Write(ledZ);
      CyDelay(1000);

         

      //Start the SPI master component
      // while(!(SPIS_ReadTxStatus() & SPIS_STS_SPI_DONE)); // SPIS_STS_SPI_DONE from function
      SPIM_Start();

         


          //while(forever) //This loops forever, part of design template
         do //start of do while loop
          {
               while(SPIM_GetTxBufferSize()) Wait();            //    Wait until all bytes transmitted
                  SPIM_WriteTxData(0x24u);  // MPL115A Start Conversion
                  SPIM_WriteTxData(BitStuff); //MPL115 expects 1 byte all zeros
                  CyDelay(5);
                  
              /* Must write address to MPL115, then read Rx data buffer */
              while(SPIM_GetTxBufferSize()) Wait();            //    Wait until all bytes transmitted
                  SPIM_WriteTxData(0x84u);  // MPL115A MSB of Temp data
                  SPIM_WriteTxData(BitStuff);
              
              while(SPIM_GetRxBufferSize())
                  Tadc_MSB = SPIM_ReadRxData(); // Read the temp MSB data in Rx buffer
                  
                  
              while(SPIM_GetTxBufferSize()) Wait();            //    Wait until all bytes transmitted
                  SPIM_WriteTxData(0x86u);  // MPL115A LSB of Temp data
                  SPIM_WriteTxData(BitStuff);
                  
              while(SPIM_GetRxBufferSize())       
                  Tadc_LSB = SPIM_ReadRxData(); // Read the temp LSB data in Rx buffer
                  
              
              LCD_Position(1u,0u);
              LCD_PrintString("Tadc_LSB  ");
              LCD_PrintHexUint16(Tadc_LSB);
                      
              LCD_Position(0u,0u);
              LCD_PrintString("Tadc_MSB  ");
              LCD_PrintHexUint16(Tadc_MSB);
              
              
              ledZ = 0x02;
              ControlReg1_Write(ledZ);
              CyDelay (1000);
              ledZ = 0x03;
              ControlReg1_Write(ledZ);
              CyDelay (1000);
              
              GoBit = StatusReg_Read(); //Read sw3 (GoBit) If true repeat loop
          } while (GoBit);
          
      }

         

       

         

      // [] END OF FILE */

         

      Appreciate any help you can provide. At this stage I am in the learning process, so I am sure the problem will be a bonehead thing on my part.

        • 1. Re: SPI Data From Slave Device Not Displaying correct data on LCD
          user_1377889

          Your SPI-logic does not follow exactly what you want to have.

             

          Keep in mind: For every bit (byte) the master sends a bit (byte) is returned immediately. Whether the returned data contain valid information or not the slave's datasheet will tell. Your master's buffer for keeping the returned results is only 4 bytes deep, you may increase that at need.

             

           

             

          Bob

          • 2. Re: SPI Data From Slave Device Not Displaying correct data on LCD
            mnauss_1472621

            Thanks, I changed the RX buffer from 4 to 8, the MSB now reads correctly (0x7E), but LSB is still 00.

            • 3. Re: SPI Data From Slave Device Not Displaying correct data on LCD
              user_1377889

              And did you already change something in the logic?

                 

               

                 

              Bob

              • 4. Re: SPI Data From Slave Device Not Displaying correct data on LCD
                mnauss_1472621

                Okay I am really trying to get a handle on this so, don't think I am being lazy. I think there is something that I am just not getting, because I am just not getting where my problem lies.

                   

                I decided to sit down with a printout of my code and write down the steps 1 at a time to see if something stuck out at me.

                   

                This is how I think it is suppose to work.

                   

                SPI write/read sequence:

                   

                    1. Get Tx buffer size (according to Cypress SPI video we need to make sure buffer is empty).

                   

                Link to SPI video:  https://www.youtube.com/watch?v=oWLriIreYRU

                   

                Write Tx Data (0x24),(0x00) - MPL115 data sheet says a dummy byte of zeros must be sent after a write

                   

                MPL115 will send 2 bytes of garbage (According to Bob M. Description of writes. For every bit (byte) the master sends a bit (byte) is returned immediately.)                    2 bytes of data in RX buffer

                   

                    2. Get Tx Buffer size

                   

                write Tx Data (0x84), (0x00)

                   

                MPL115 returns 2 bytes 1 byte 00, 1 byte raw data (4 bytes of data in Rx Buffer).

                   

                     3. Get Rx Buffer Size (ensure buffer not empty) Then read Read RX data buffer MSB. ( This part displays correctly).

                   

                     4. Get Tx Buffer size; write Tx Data (0x86),(0x00)

                   

                MPL115 returns 2 bytes, 1 byte of 00, 1 byte raw data (should be LSB) (6 bytes of data in Rx Buffer).

                   

                     5. Get Rx Buffer size; Read Rx data buffer. Should be LSB but is 0x0000.

                   

                My only thought was to clear the RX data buffer after step 1, since the returned data is garbage. I inserted the function SPIM_ClearRxBuffer(); after the first write 0x24, 0x00;

                   

                What resulted was MSB read 0000 and LSB read C000 which is correct for LSB. So I am not sure what is exactly happening.

                   

                Thanks

                • 5. Re: SPI Data From Slave Device Not Displaying correct data on LCD
                  user_1377889

                  2. Get Tx Buffer size

                     

                  write Tx Data (0x84), (0x00)

                     

                  I cannot follow where you get the 0x84-address from. Also, we need the exact device name, I could only find an MPL115A2 with an I2C interface.

                     

                   

                     

                  Bob

                  • 6. Re: SPI Data From Slave Device Not Displaying correct data on LCD
                    mnauss_1472621

                    I thought I posted the link in my first message. I am using the MPL115A1.

                       

                    http://www.freescale.com/products/sensors/pressure-sensors/barometric-pressure-15-to-115-kpa/50-to-115kpa-absolute-digital-pressure-sensor:MPL115A

                       

                    This is from datasheet:

                       

                    Table 5. Example SPI Read Commands
                    Command Binary HEX(1)
                    1. The command byte needs to be paired with a 0x00 as part of the SPI exchange to complete the passing of stated
                    command.
                    Read Pressure MSB 1000000X 0x80
                    Read Pressure LSB 1000001X 0x82
                    Read Temperature MSB 1000010X 0x84
                    Read Temperature LSB 1000011X 0x86
                    Read Coefficient data byte 1 1000100X 0x88
                    X = don’t care

                    • 7. Re: SPI Data From Slave Device Not Displaying correct data on LCD
                      user_1377889

                      I just found it in your code snippet as comment: MPL115A1. Now I got a datasheet. Still need actual workspace bundle.

                         

                       

                         

                      Bob

                      • 8. Re: SPI Data From Slave Device Not Displaying correct data on LCD
                        mnauss_1472621

                        I sent my workspace bundle in the first post.

                        • 9. Re: SPI Data From Slave Device Not Displaying correct data on LCD
                          user_1377889

                          So no changes at all or no help wanted?

                             

                           

                             

                          Bob

                          • 10. Re: SPI Data From Slave Device Not Displaying correct data on LCD
                            mnauss_1472621

                            Your right, my bad. And yes I do want help. Thank you.

                            • 11. Re: SPI Data From Slave Device Not Displaying correct data on LCD
                              user_1377889

                              OK:

                                 

                              When you count the bytes (1 up for each write and 1 down for each read) that will be kept in the receive buffer you'll see that there will be some leftovers. And keep in mind: it is a FIFO buffer!

                                 

                              When you look at the datasheet of MPL115A1

                                 

                               at page 10 there is an interesting list. Watch the CS-line!!! For the SPIM component, the SS-line will go up again when the tx-buffer is empty, so I would suggest at first to use a pin for SS (CS) and handle it manually as shown in the example.

                                 

                              The SPIM-write functions are blocking, so when there is no room in the buffer the function will wait (Interrupts must be enabled as you did). Nonetheless I would suggest you to increase both buffers to something like 10 or 20 (there is plenty of SRam in your PSoC5).

                                 

                              So you can reduce/remove your wait-functions line by line to get a short tough routine for reading pressure.

                                 

                              BTW: What are you measuring? Height of a plane or copter?

                                 

                               

                                 

                              Bob

                              • 12. Re: SPI Data From Slave Device Not Displaying correct data on LCD
                                mnauss_1472621

                                Thanks, I will try to implement the suggestions you made. The barometer is used because I have some gas sensors onboard that vary with barometric pressure, the barometric data will be used to make corrections to the gas sensor data input. Thanks for your assistance, it is greatly appreciated.

                                • 13. Re: SPI Data From Slave Device Not Displaying correct data on LCD
                                  davidgarnett

                                  Just a thought ... Have you looked at the SPI signals on a logic analyzer?  I have had trouble with the Cypress SPI component's handling of the chip select signal.  I expected the chip select to stay active for an entire transfer.  Instead, it toggled on every byte.  That confused the slave device I was using.

                                  • 14. Re: SPI Data From Slave Device Not Displaying correct data on LCD
                                    mnauss_1472621

                                    Hello, I had to take a few days off this problem to put out some other fires, but back on it now. I have discovered a few things and made some changes.

                                       

                                    I tried to streamline the code as suggested by Bob, which has helped me figure out what is going on. I also added some hardware in the PSoC to count the amount of times the SPIM generates a chip select as that seemed to be in question. As it turns out there are 2 chip selects generated for the whole transaction.

                                       

                                    I also take the Rx buffer and output the entire contents as raw data to the display, to see if I have the right data in the buffer.

                                       

                                    The results displayed in the buffer is as follows: [00][00][00][7D][00][C0], note the 7D and C0 is real data, the rest is just empty bytes sent by the slave. The first 2 bytes are a result of the start conversion command sent by the SPIM, so after the start cmd. I added a clear Rx buffer so I end up with [00][7D][00][C0]. The slave device always sends a byte of zero's then the actual data. So my problem is, how do I extract the data only 7DC0? My original problem was when I read the data my output was 7D00, so not sure how to handle this. I hope I was able to explain well enough. Below is my code and I am attaching my build file. Thanks

                                       

                                    /* ========================================
                                     *
                                     * Copyright ConCon Engineering LLC, 2015
                                     * All Rights Reserved
                                     * UNPUBLISHED, LICENSED SOFTWARE.
                                     *
                                     * CONFIDENTIAL AND PROPRIETARY INFORMATION
                                     * WHICH IS THE PROPERTY OF ConCon Engineering LLC.
                                     *
                                     * Purpose of this design is to communicate to MPL115 Barometer and Temp sensors via SPI bus
                                     * Barometer and temp is used for gas sensor data correction
                                     * ========================================
                                    */
                                    /*  MPL115 BreakOut ------------------CY8CKIT-050
                                                    SDN ------------------P0[3]
                                                    CSN ------------------P0[2]     CS_n
                                                    SDO ------------------P0[1]     MISI
                                                    SDI ------------------P0[0]     MOSI
                                                    SCK ------------------P0[5]     SCLK
                                                    GND ------------------System conn pin P6 - 7
                                                    VDD ------------------System conn pin P6 - 3
                                    */
                                                    
                                    /* MPL115 Memory Map
                                       For reads must set bit 7 to 1. So a read will be 0x8X ie. Tadc_MSB 0x82           
                                      Address Name      Description                 Size (bits)
                                        0x00 Padc_MSB 10-bit Pressure output value    MSB 8
                                        0x01 Padc_LSB 10-bit Pressure output value    LSB 2
                                        0x02 Tadc_MSB 10-bit Temperature output value MSB 8
                                        0x03 Tadc_LSB 10-bit Temperature output value LSB 2
                                        0x04 a0MSB a0 coefficient MSB 8
                                        0x05 a0LSB a0 coefficient LSB 8
                                        0x06 b1MSB b1 coefficient MSB 8
                                        0x07 b1LSB b1 coefficient LSB 8
                                        0x08 b2MSB b2 coefficient MSB 8
                                        0x09 b2LSB b2 coefficient LSB 8
                                        0x0A c12MSB c12 coefficient MSB 8
                                        0x0B c12LSB c12 coefficient LSB 8
                                    */

                                       

                                    #include <project.h>
                                    #include <cylib.h>
                                    #include <stdio.h>

                                       

                                    //======================//
                                    //          Macros            //
                                    //======================//

                                       

                                    #define Wait(x)                                //    Just for better reading
                                    #define FALSE        0                        //    Boolean false
                                    #define TRUE        !FALSE                    //    and true
                                    #define forever        1                        //    I like that

                                       

                                    //======================//
                                    //     Global Variables    //
                                    //======================//

                                       

                                    uint8 BitStuff = 0x00u;

                                       


                                    /* *******************
                                    MPL115A1 Functions
                                    **********************/

                                       

                                    /*******************************************************************************
                                    * Function Name: ControlReg and ControlReg1_Write
                                    ********************************************************************************
                                    * Function enables hardware to display LED value of status register
                                    * Parameters led
                                    ********************************************************************************/
                                    void ControlReg1_Write (uint8); // declaring the function
                                    void ChipSelect_Write (uint8);
                                    uint8 ssCountReg_Read (void);
                                    /*****************************************************************************
                                    / SPI Master Read and write function (This function calls SPIM_WriteTxData
                                    / and SPIM_ReadRxData functions
                                    ******************************************************************************/

                                       

                                    void CyDelay(uint32 milliseconds);

                                       

                                    int main()
                                    {
                                    /************************
                                        Local variables
                                    *************************/
                                    //uint8 MyData;
                                    uint8 Tadc_MSB = 0x55; //Store MSB of SPI Rx data
                                    uint8 Tadc_LSB = 0x55;
                                    uint8 GoBit = 0x00;  //Press SW3 to force main to loop once else it waits
                                    uint8 i = 0u;  
                                    //uint8 ssCountBits = 0x00; //Count how many times SS is asserted
                                        
                                         CyGlobalIntEnable; /* Always enable global interrupts. */

                                       

                                        
                                        /* Place your initialization/startup code here (e.g. MyInst_Start()) */
                                    // Start the LCD and Display
                                    LCD_Start ();
                                    //LCD_Position(0u,0u);
                                    //LCD_PrintString("SPI Master");
                                    //LCD_Position(1u,0u);
                                    //LCD_PrintString("Test Code");

                                       


                                    //Start the SPI master component
                                    SPIM_Start();

                                       

                                        //while(forever) //This loops forever, part of design template
                                       do //start of do while loop
                                        {
                                             while(SPIM_GetTxBufferSize()) Wait();            //    Wait until all bytes transmitted
                                                SPIM_WriteTxData(0x24u);  // MPL115A Start Conversion
                                                SPIM_WriteTxData(BitStuff); //MPL115 expects 1 byte all zeros
                                                CyDelay(5);
                                                SPIM_ClearRxBuffer(); //Clear some bogus bytes sent by MPL115
                                                
                                                SPIM_WriteTxData(0x84u);  // MPL115A MSB of Temp data
                                                SPIM_WriteTxData(BitStuff);
                                         //   while(SPIM_GetRxBufferSize())
                                         //       Tadc_MSB = SPIM_ReadRxData(); // Read the temp MSB data in Rx buffer
                                                
                                                SPIM_WriteTxData(0x86u);  // MPL115A LSB of Temp data
                                                SPIM_WriteTxData(BitStuff);        
                                                
                                         //   while(SPIM_GetRxBufferSize())       
                                         //       Tadc_LSB = SPIM_ReadRxData(); // Read the temp LSB data in Rx buffer
                                                
                                        while(!(SPIM_ReadTxStatus() & SPIM_STS_SPI_DONE)) // SPIM_STS_SPI_DONE from function       
                                        
                                        //ssCountBits = ssCountReg_Read();
                                        ControlReg1_Write (ssCountReg_Read()); //Just for debug display number of chip selects
                                        
                                            LCD_Position(0u,0u);
                                            for (i=0u; i<8u; i++)
                                            {
                                            LCD_PrintHexUint8(SPIM_ReadRxData());
                                            }
                                            LCD_Position(1u,0u);
                                            LCD_PrintHexUint8(ssCountReg_Read()); //Displays number of chip selects
                                            
                                           // LCD_PrintString("Tadc_MSB  ");
                                          //  LCD_PrintHexUint16(Tadc_MSB);
                                            
                                           // LCD_Position(1u,0u);
                                          //  LCD_PrintString("Tadc_LSB  ");
                                         //   LCD_PrintHexUint16(Tadc_LSB);
                                       
                                            
                                            GoBit = StatusReg_Read(); //Read sw3 (GoBit) If true repeat loop
                                        } while (GoBit);
                                        
                                    }

                                       

                                     

                                       

                                    // [] END OF FILE */

                                    1 2 Previous Next