Main Site Documentation

SPI Chip Select Toggle


#1

Does anyone know if the SPI.WriteRead method toggles the Chip Select pin after every byte?


#2

no. it is per transaction


#3

So the CS (Chip Select) pin is only toggled after the data is sent/recived? What would I have to do If I wanted CS to toggle after every byte?


#4

Send one byte per transaction.


#5

@ Arch, Is that really it? :frowning: Sounds weird.


#6

Whats weird is that your chip needs that; not that the SPI implementation doesn’t do that :slight_smile: The normal use of CS means that anything on the MOSI/MISO lines are for the chip with the active CS; the act of unselecting the chip and then reselecting it seems to be like an additional clocking? Whats your application/chip?


#7

@ Bret; It is the L6470 Stepper Driver. http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/DATASHEET/CD00255075.pdf on page 36.

[quote]After each byte transmission the CS input must be raised and be kept high for at least tdisCS
in order to allow the device to decode the received command and put into the shift register
the return value.[/quote]

The device supports daisy chaining, so it is possible to have 8 deviecs that you are using to communicate with on the same set of SPI and chip select pins.


#8

It is impossible!

http://forums.netduino.com/index.php?/topic/1375-spiwriteread-returns-junk/

From the link, one of the reponders says that the SPI.ReadWrite sets up and tears down the configuration each time WriteRead is called. This causes unwanted clock and CS signals to be sent to the device.

I guess this means big banging, unless anyone else has another suggestion?


#9

Yes but GHI devices do not do that :slight_smile: we fixed out those glitches


#10

@ Gus, damn. Now I’m at a loss. Can you recommend a course of action to diagnose the problem?

I’ve tried the bit banging to no avail either.


#11

I looked at the specification. It should work.
Show your code and explain where do you have problems.


#12

@ Arch, Here is the code as it stands:


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

namespace EVAL6470
{
    public class Program
    {

        static SPI spiPort = null;
        public static void Main()
        {
            SPI.Configuration _spiConfig = new SPI.Configuration((Cpu.Pin)FEZ_Pin.Digital.Di10,
                !true, // Chip Select, active-low
                0, // 0 (nanoseconds?) setup time
                0, // 0 (nanoseconds?) hold time
                true, // Clock low on idle
                true, // Data valid on falling edge
                1, // 1Khz Clock Rate
                SPI.SPI_module.SPI1); //SPI device 1
            spiPort = new SPI(_spiConfig);


            while (true)
            {
                PrintBuffer(WriteRead(new byte[] { 0x18, 0, 0 })); /// this is the command to get the value  of the configu register. 
                                                                   /// at power up I expect back 2 bytes{ 2E and 88 }
            }
        }

        static byte[] WriteRead(byte[] data)
        {
            byte[] _receive = new byte[data.Length];
            for (int i = 0; i < data.Length; i++)
            {
                byte[] _txData = new byte[1];
                byte[] _rxData = new byte[1];
                _txData[0] = data[i];
                spiPort.WriteRead(_txData, _rxData);

                _receive[i] = _rxData[0];
            }
            return _receive;
        }

        static void PrintBuffer(byte[] data)
        {
            Debug.Print("Buffer Data : " + BitConverter.ToString(data, 0));
        }
    }

    public static class BitConverter
    {
        public static string ToString(byte[] value, int index = 0)
        {
            return ToString(value, index, value.Length - index);
        }
        public static string ToString(byte[] value, int index, int length)
        {
            char[] c = new char[length * 3];
            byte b;
            for (int y = 0, x = 0; y < length; ++y, ++x)
            {
                b = (byte)(value[index + y] >> 4);
                c[x] = (char)(b > 9 ? b + 0x37 : b + 0x30);
                b = (byte)(value[index + y] & 0xF);
                c[++x] = (char)(b > 9 ? b + 0x37 : b + 0x30); 
                c[++x] = ' ';
            }
            return new string(c, 0, c.Length - 1);
        }
    }
}

I’m only getting back FF for this command when it should be 2E and 88. I had thought that the communication was working and that I wasn’t sending the correct commands, but sadly I think that it’s the communication now.


#13

Spi configuration is wrong, try 5MHz


#14

Tried 5Mhz, 1Mhz and a bunch of others. No avali. Will try again however.


#15

Check section 6.1. I think you have to check for the end of the power-up condition,because all IO are disabled during the power-up. Also try 2MHz, because that seems to be the clock value after the reset according to the specification.


#16

@ Arch, will try 2Mhz.

I thought that clock speed wasn’t really important with SPI though?


#17

It is very important.


#18

I tried 5mhz again as well as 2mhz. Still no luck. I wouln’t like to believe that I’m incapable of connecting 5 wires correctly, so I’m assuming it’s wired properley.


#19

Ok. I think I figured it out. To write to a register you need to use SetParam command. To read from a register you need to use GetParam command. PARAM will be the address of the register you want to access.


#20

Humm… Good pint It’s command then arguments. Which means that this line:

WriteRead(new byte[] { 0x18, 0, 0 })

is wrong (what have i been thinking)

Trying to figure out what I’m changing too…

Ok something weird just happened.

In experimenting it seems that the Get Status Command is returning a value. It’s returning 00 7E 02 consistantly now.

Here is the entire code:


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

namespace EVAL6470
{
    public class Program
    {

        static SPI spiPort = null;
        public static void Main()
        {
            SPI.Configuration _spiConfig = new SPI.Configuration((Cpu.Pin)FEZ_Pin.Digital.Di10,
                !true, // Chip Select, active-low
                1000, // 0 (nanoseconds?) setup time
                1000, // 0 (nanoseconds?) hold time
                true, // Clock low on idle
                true, // Data valid on falling edge
                5000, // 5Mhz Clock Rate
                SPI.SPI_module.SPI1); //SPI device 1
            spiPort = new SPI(_spiConfig);


            while (true)
            {
                PrintBuffer(WriteRead(new byte[] { 0xD0, 0, 0 })); /// GetStatus, however I am not sure what I'm supposed to get back
                                                                   
            }
        }

        static byte[] WriteRead(byte[] data)
        {
            byte[] _receive = new byte[data.Length];
            for (int i = 0; i < data.Length; i++)
            {
                byte[] _txData = new byte[1];
                byte[] _rxData = new byte[1];
                _txData[0] = data[i];
                spiPort.WriteRead(_txData, _rxData);

                _receive[i] = _rxData[0];
            }
            return _receive;
        }

        static void PrintBuffer(byte[] data)
        {
            Debug.Print("Buffer Data : " + BitConverter.ToString(data, 0));
        }
    }

    public static class BitConverter
    {
        public static string ToString(byte[] value, int index = 0)
        {
            return ToString(value, index, value.Length - index);
        }
        public static string ToString(byte[] value, int index, int length)
        {
            char[] c = new char[length * 3];
            byte b;
            for (int y = 0, x = 0; y < length; ++y, ++x)
            {
                b = (byte)(value[index + y] >> 4);
                c[x] = (char)(b > 9 ? b + 0x37 : b + 0x30);
                b = (byte)(value[index + y] & 0xF);
                c[++x] = (char)(b > 9 ? b + 0x37 : b + 0x30); 
                c[++x] = ' ';
            }
            return new string(c, 0, c.Length - 1);
        }
    }
}