Main Site Documentation

Panda 2 and SPI not working?


#1

Thank you for your help.
I have a Panda II and all seems well except when I try to use SPI, I get the same result in the input array all the time. I have an old ‘scope’ and I can see the clock lines as well as data lines. But, I always get the same two bytes of data. I grounded the input data line, expecting data to go to 0x00, 0x00 but it did not change.
I must be doing something wrong.
My simple test code is below:

using System;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using System.Threading;
using GHIElectronics.NETMF.FEZ;

namespace MFConsoleApplication1
{
public class Program
{
static OutputPort MyLED = new OutputPort((Cpu.Pin)FEZ_Pin.Digital.LED, true);

    static OutputPort CS_N = new OutputPort((Cpu.Pin)FEZ_Pin.Digital.Di9, true);

    public static void Main()
    {
        // Configure an instance and then create an SPI Object - Di11, Di12 & Di13. Di2 is chip select
        SPI.Configuration MyConfig = new SPI.Configuration((Cpu.Pin)FEZ_Pin.Digital.Di10, 
            false, 
            20, 
            20, 
            false, 
            true, 
            200, 
            SPI.SPI_module.SPI1); // 200k bits n
         
        // Create SPI object here

        SPI MySPI = new SPI(MyConfig);
       
        string errormsg = string.Empty; 
        byte[] StartConversion =  { 0x24, 0x00 };
        byte[] ReadPresMSB =  { 0x80 , 0x00 };
        byte[] ReadPresLSB = { 0x82 , 0x00 };
        byte[] DummyBytes = new byte[2];  // receive the two bytes of SPI 
        bool LEDstate = true;

        byte[] PresMSB = new byte[2];
        byte[] PresLSB = new byte[2]; 

        int pResult = 0;
        int MSB = 0;
        int LSB = 0;
       

        for (int x = 0; x < 300000; x++)    // run a long time, but not forever
        {
           
            


         //   MySPI.Write(StartConversion); 
           
       MySPI.WriteRead(StartConversion, DummyBytes); // Send and receive SPI data
            Thread.Sleep(200);    // wait 200 ms for conversion

            LEDstate = !LEDstate;   // visual confirmation of running
            MyLED.Write(LEDstate);              

            
            MySPI.WriteRead(ReadPresMSB, PresMSB);
            MySPI.WriteRead(ReadPresLSB, PresLSB);
            CS_N.Write(true); 

            MSB = ReadPresMSB[0];
            LSB = ReadPresLSB[0];


            pResult = (Int16)(((MSB << 2)) & 0x03fc) + (Int16)((LSB << 2) & 0x0003);

           Debug.Print(pResult.ToString());  

        }

       
    }

}

}


#2

I’m not in a position to test this for the next 1/2 day, but I will try to.

Can you tell us what device you have here?

Can you edit your post and highlight the code with the [ c o d e ] tags?

Also I’d refactor your code for testing. At a minimum your FOR loop should have a thread.sleep(1000) or more at the end, so that you actually pause between SPI samples at least for testing; and you should have a thread.sleep(timeout.infinite) at the end of the main() so you never let the thread terminate.


#3

Thank you for your attention. I have added more detail:

Issue: Unexpected results from SPI on Panda 2 board.
I purchased an SPI barometer and attempted to hook it up to the Panda 2 board
I hooked up to the 8 pin connector on the board.
Ground to Ground
+5V to +5V
Di13* to SCK on barometer chip
Di12* to MISO (Master input)
Di11* to MOSI (Master output)
Di10* as CS*

Got the same reading over and over, so I guessed it was not working.
After some fooling around, I unplugged everything as still get the same values from the SPI port.
I then hooked a jumper from ground to the data in pin, Di12*, expecting data to change to 0x00, 0x00 - but stayed the same.

I get MSB = 0x80
LSB = 0x82

So, I think I am doing something wrong.
I do have a ‘scope’ and, as far as I can tell, the signals look good.
CS goes low and stays low during write-read cycle
Clock only active during write-read
I have changed the SPI configuration parameters but have seen no differences.
Also tried using SPI1 and SPI2 - no difference

Perhaps I am not understanding the SPI port pins, and thus am not connected correctly, but it seems simple. Or, perhaps there is some setup steps I am missing.

[CODE]
using System;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using System.Threading;
using GHIElectronics.NETMF.FEZ;

namespace MFConsoleApplication1
{
public class Program
{
static OutputPort MyLED = new OutputPort((Cpu.Pin)FEZ_Pin.Digital.LED, true);

    static OutputPort CS_N = new OutputPort((Cpu.Pin)FEZ_Pin.Digital.Di9, true);

    public static void Main()
    {
        // Configure an instance and then create an SPI Object - Di11, Di12 & Di13. Di2 is chip select
        SPI.Configuration MyConfig = new SPI.Configuration(
            (Cpu.Pin)FEZ_Pin.Digital.Di10, // chip select
            false, // set low when accessing the chip
            20, 
            20,
            true, // clock signal will be set to high while the device is idle
            true, // data is sampled on the SPI clock falling edge
            200, 
            SPI.SPI_module.SPI2); // 200k bits n
         
        // Create SPI object here

        SPI MySPI = new SPI(MyConfig);
       
        string errormsg = string.Empty; 
        byte[] StartConversion =  { 0x24, 0x00 };
        byte[] ReadPresMSB =  { 0x80 , 0x00 };
        byte[] ReadPresLSB = { 0x82 , 0x00 };
        byte[] DummyBytes = new byte[2];  // receive the two bytes of SPI 
        bool LEDstate = true;

        byte[] PresMSB = new byte[2];
        byte[] PresLSB = new byte[2]; 

        int pResult = 0;
        int MSB = 0;
        int LSB = 0;
       

        for (int x = 0; x < 300000; x++)    // run a long time, but not forever
        {
           
            


         //   MySPI.Write(StartConversion); 
           
       MySPI.WriteRead(StartConversion, DummyBytes); // Send and receive SPI data
            Thread.Sleep(200);    // wait 200 ms for conversion

            LEDstate = !LEDstate;   // visual confirmation of running
            MyLED.Write(LEDstate);              

            
            MySPI.WriteRead(ReadPresMSB, PresMSB);
            MySPI.WriteRead(ReadPresLSB, PresLSB);
            CS_N.Write(true); 

            MSB = ReadPresMSB[0];
            LSB = ReadPresLSB[0];


            pResult = (Int16)(((MSB << 2)) & 0x03fc) + (Int16)((LSB << 2) & 0x0003);

           Debug.Print(pResult.ToString());  

        }

        Thread.Sleep(Timeout.Infinite); 
        
    }

}

}

[CODE]


#4

@ BillWitt -

Try

[ code=cs ]

[ /code ]

but remove spaces between brackets

Edit: You didn’t removed the spaces :wink:


#5

Trying again, hope this is what you need:

Issue: Unexpected results from SPI on Panda 2 board.
I purchased an SPI barometer and attempted to hook it up to the Panda 2 board
I hooked up to the 8 pin connector on the board.
Ground to Ground
+5V to +5V
Di13* to SCK on barometer chip
Di12* to MISO (Master input)
Di11* to MOSI (Master output)
Di10* as CS*

Got the same reading over and over, so I guessed it was not working.
After some fooling around, I unplugged everything as still get the same values from the SPI port.
I then hooked a jumper from ground to the data in pin, Di12*, expecting data to change to 0x00, 0x00 - but stayed the same.

I get MSB = 0x80
LSB = 0x82

So, I think I am doing something wrong.
I do have a ‘scope’ and, as far as I can tell, the signals look good.
CS goes low and stays low during write-read cycle
Clock only active during write-read
I have changed the SPI configuration parameters but have seen no differences.
Also tried using SPI1 and SPI2 - no difference

Perhaps I am not understanding the SPI port pins, and thus am not connected correctly, but it seems simple. Or, perhaps there is some setup steps I am missing.

[ code=cs ]

using System;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using System.Threading;
using GHIElectronics.NETMF.FEZ;

namespace MFConsoleApplication1
{
public class Program
{
static OutputPort MyLED = new OutputPort((Cpu.Pin)FEZ_Pin.Digital.LED, true);

    static OutputPort CS_N = new OutputPort((Cpu.Pin)FEZ_Pin.Digital.Di9, true);

    public static void Main()
    {
        // Configure an instance and then create an SPI Object - Di11, Di12 & Di13. Di2 is chip select
        SPI.Configuration MyConfig = new SPI.Configuration(
            (Cpu.Pin)FEZ_Pin.Digital.Di10, // chip select
            false, // set low when accessing the chip
            20, 
            20,
            true, // clock signal will be set to high while the device is idle
            true, // data is sampled on the SPI clock falling edge
            200, 
            SPI.SPI_module.SPI2); // 200k bits n
         
        // Create SPI object here

        SPI MySPI = new SPI(MyConfig);
       
        string errormsg = string.Empty; 
        byte[] StartConversion =  { 0x24, 0x00 };
        byte[] ReadPresMSB =  { 0x80 , 0x00 };
        byte[] ReadPresLSB = { 0x82 , 0x00 };
        byte[] DummyBytes = new byte[2];  // receive the two bytes of SPI 
        bool LEDstate = true;

        byte[] PresMSB = new byte[2];
        byte[] PresLSB = new byte[2]; 

        int pResult = 0;
        int MSB = 0;
        int LSB = 0;
       

        for (int x = 0; x < 300000; x++)    // run a long time, but not forever
        {
           
            


         //   MySPI.Write(StartConversion); 
           
       MySPI.WriteRead(StartConversion, DummyBytes); // Send and receive SPI data
            Thread.Sleep(200);    // wait 200 ms for conversion

            LEDstate = !LEDstate;   // visual confirmation of running
            MyLED.Write(LEDstate);              

            
            MySPI.WriteRead(ReadPresMSB, PresMSB);
            MySPI.WriteRead(ReadPresLSB, PresLSB);
            CS_N.Write(true); 

            MSB = ReadPresMSB[0];
            LSB = ReadPresLSB[0];


            pResult = (Int16)(((MSB << 2)) & 0x03fc) + (Int16)((LSB << 2) & 0x0003);

           Debug.Print(pResult.ToString());  

        }

        Thread.Sleep(Timeout.Infinite); 
        
    }

}

}

[ /code ]


#6

@ BillWitt - What voltages does the SPI transmit at?


#7

Device is MPL115A pressure sensor - from spec sheet

SPI Outputs: DOUT

Low Level Output Voltage VOL1 At 3 mA sink current 0 — 0.4 V
VOL2
At 6 mA sink current 0 — 0.6

High Level Output Voltage VOH1 At 3 mA source current VDD - 0.4 V (VDD = 5.0 V)

Hope this is what your are asking


#8

A few more things.

edit your post, don’t repost it, please! The little pencil icon on the top right.

thanks for telling us the sensor. Please connect vcc to 3.3v not 5 and repeat your test.

you have an oscilloscope so please show us bit captures from a failed read transaction.


#9

Hi,
First, I don’t have a storage scope, so I can’t record a transaction.

Would you be willing to hook up a Panda two and run this code? Ground the data in pin with a jumper. I just set a break point after the first read, and look at the results. I always get the same results. Never all zeros, which is what I would expect.

It seems to me that if there is no device present, but the data input line was held to ground, the board would read 8 bits of 0.

I don’t find this to be true, so I expect I am making an error in my code, in my understanding of SPI or the board is not working correctly.

Thanks for your help.

Bill


#10

So I tested this. I think there’s a couple of obvious inconsistencies and problems in your code - which would have been helped had your code tagging worked.

First up is your SPI constructor.


            // Configure an instance and then create an SPI Object - Di11, Di12 & Di13. Di2 is chip select
            SPI.Configuration MyConfig = new SPI.Configuration(
            (Cpu.Pin)FEZ_Pin.Digital.Di10, // chip select
            false, // set low when accessing the chip
            20,
            20,
            true, // clock signal will be set to high while the device is idle
            true, // data is sampled on the SPI clock falling edge
            200,
            SPI.SPI_module.SPI2); // 200k bits n


Your code doesn’t match the comment. This creates a constructor on SPI2 not SPI1 (Di11/12/13 are SPI1). And your CS pin is defined as Di10 not Di2. So, what was your intent ?

The data you get in the MSB/LSB variables is what you set there in the first place. It seems to me your code should be:


MSB = PresMSB[0];
LSB = PresLSB[0];

as you want the value that is read, not the 0x80/0x82 value that you pre-load in ReadPresXXX[0].

When I used SPI1, and connect the pins to GND and 3v3 alternately, and make the change to MSB/LSB as above, I get a changed value.