Colibri i.MX6 SPI Communication Failure Need Help

Hello,

I’m developing an application where I need to communicate with the Dual Channel DAC MCP4922.

I made all the connections and I’ve written the code in C# following the official toradex example but I don’t see any result because the output voltage of the DAC is always ZERO.

I’m using the latest Toradex libraries toradexcelibraries_2.3b4555-20190107.

The connections of the DAC are the following:

MCP4922IRIS
Pin 1 (VDD) → 3.3V
Pin 3 (CS) → SSPFRM
Pin 4 (SCK) → SSPSCLK
Pin 5 (SDI) → SSPTXD
Pin 8 (SHDN) → 3.3V
Pin 9 (LDAC) → 3.3V
Pn 10 (VOUTB)
Pin 11 (VREFB) → 3.3V
Pin 12 (VSS) → GND
Pin 13 (VREFA) → 3.3V
Pin 14 (VOUTA)

The code I use is the following:

public class MCP4922
    {
        IntPtr spiHandle = IntPtr.Zero;
        uint returnValue = 0;

        private const float LSB = 1 / 4095;
        public const int MAX_VALUE = 4095; //VOUT = InputCode*LSB/MAX_VAçLUE 4095
        public const int MIN_VALUE = 0;

        public uint DeviceAddress;

        public MCP4922()
        {
            spiHandle = spi_imx6.Imx6Spi_Init("SPI2");                                                               ///< Init SPI library 
            if (spiHandle == IntPtr.Zero)
            {
                Program.cGlobals.cLogging.LogMessage("MCP4922 --> Error initializing the SPI Library");
            }
            spi_imx6.Imx6Spi_SetConfigInt(spiHandle, "SpiMode", 0, TdxCommon.ParamStorageType.StoreVolatile);        ///< Set SPI on Mode 0
            spi_imx6.Imx6Spi_SetConfigInt(spiHandle, "BitRateHz", 10000, TdxCommon.ParamStorageType.StoreVolatile);  ///< Set SPI clock 26000 Lhz 
 
            if (!spi_imx6.Imx6Spi_Open(spiHandle))
            {
                Program.cGlobals.cLogging.LogMessage("MCP4922 --> Failed to open SPI");
            }
            spi_imx6.Imx6Spi_SetConfigInt(spiHandle, "ioCS", 86, TdxCommon.ParamStorageType.StoreVolatile);          ///< Set Chip Select pin sodimm 86
        }

       
        public void WriteRegister(int DACNumber, int BufferControl, int Gain, int Shutdown, int iValue)
        {
            //DACNumber=0 => Registro A - DACNumber=1 => Registro B
            //BufferControl=0 => Unbuffered - BufferControl=1 => Buffered
            //Gain=0 => VOUT = 2 * VREF * D/4096 - Gain=1 => VOUT = VREF * D/4096 dove D è il valore del registro D11-D0
            //Shutdown=0 => Shutdown the selected DAC channel - Shutdown=1 => Active mode operation. VOUT is available

            if (DACNumber==0 && bReverse_A_Reg)
                iValue = MAX_VALUE - iValue;

            if (DACNumber == 1 && bReverse_B_Reg)
                iValue = MAX_VALUE - iValue;

            uint bufferLenght = 2;
            Byte[] DataToWrite = new Byte[bufferLenght];
            int SetupValue = DACNumber * 8 + BufferControl * 4 + Gain * 2 + Shutdown;
            //DataToWrite[0] = (byte)(((iValue & 3840) >> 8) | (SetupValue * 16));
            //DataToWrite[1] = (byte)(iValue & 255);

            DataToWrite[0] = (byte)(63);
            DataToWrite[1] = (byte)(63);

            try
            {
                unsafe
                {
                    fixed (byte* for_Casting_Intptr_to_Byte = DataToWrite)
                    {
                        //returnValue = spi.Spi_Write(spiHandle, (IntPtr)for_Casting_Intptr_to_Byte, bufferLenght);
                        returnValue = spi_imx6.Imx6Spi_Write(spiHandle, (IntPtr)for_Casting_Intptr_to_Byte, bufferLenght);
                        if (returnValue == 0)
                            throw new Exception();                                            ///< If Write operation returns 0
                    }
                }
            }
            catch (Exception ex)
            {
                Program.cGlobals.cLogging.LogMessage("Scrittura Configurazione Fallita - Codice Errore: " + ex.Message);
            }
        }

        public void Exit()
        {
            spi_imx6.Imx6Spi_Close(spiHandle);
            spi_imx6.Imx6Spi_Deinit(spiHandle);                                                                       ///< De-Initializes SPI
        }

    }

I don’t receive any error during the initialization and after a write the returned value is 2.

I’ve tryied to change the init string to SPI1 and I’ve tryied all the SPI modes but nothing, the VOUT is allways ZERO.

I’ve checked with the oscilloscope and strange I’ve found that no clock signal is revealed out of the pin SSPSCLK.

Probably I’m missing something and I hope you can help me.

Thanks in advance,

Giuseppe

After some experiments I’ve found that if I init with the string name SPI1 I can see the clock signal and the TX signal when I try to write but I cannot see the drop down of CS, it stays on 3.3V ever. Could it be the problem?

Dear @emmettbrown
Please be aware that the SPI signals are arranged in groups on the i.MX6, so you cannot randomly mix pins from different SPI interfaces.

The ioCs on pin 86 matches only with

  • IoCLK on pin 88
  • ioMiso on pin 90
  • ioMosi on pin 92

This port with SODIMM pins {86, 88, 90, 92} is called L"SPI1" by default. (See library documentation, SPI pin availability for Colibri iMX6S/iMX6DL).

If you use these pins, and call spiHandle = spi_imx6.Imx6Spi_Init("SPI2");, no further pin setup should be required.

Regards, Andy

If you see my last comment you can see that already I’ve modified the code using SPI1 but I cannot see any result. The connection should be already correct:

MCP4922 – IRIS

Pin 1 (VDD) → 3.3V

Pin 3 (CS) → SSPFRM → THIS IS PIN 86

Pin 4 (SCK) → SSPSCLK → THIS IS PIN 88

Pin 5 (SDI) → SSPTXD → THIS IS PIN 92

Pin 8 (SHDN) → 3.3V

Pin 9 (LDAC) → 3.3V

Pn 10 (VOUTB)

Pin 11 (VREFB) → 3.3V

Pin 12 (VSS) → GND

Pin 13 (VREFA) → 3.3V

Pin 14 (VOUTA)

Why I don’t see any voltage from the DAC outputs?

With the oscilloscope I can see the clock pulse and the data transmission but the SSPFRM signal is HIGH forever, I think this is the problem.

Why?

Dear @emmettbrown,

Quickly tested with our Toradex CE libraries SPI_demo(…\libDemos\Spi_Demo) application and I am able to see SPI chip select is toggling on V1.4 WEC2013 release image. Could you test the same and let us know the feedback.

Thank you.

Thanks @andy.tx but if you can see my previpus comment, I’ve already found that the right port name was SPI1 but it’s still not working.

I’m right I think since I’m using the right pins, as you can see here:

MCP4922 – IRIS

Pin 1 (VDD) → 3.3V

Pin 3 (CS) → SSPFRM [ PIN 86 ]

Pin 4 (SCK) → SSPSCLK [ PIN 88 ]

Pin 5 (SDI) → SSPTXD [ PIN 92 ]

Pin 8 (SHDN) → 3.3V

Pin 9 (LDAC) → 3.3V

Pn 10 (VOUTB)

Pin 11 (VREFB) → 3.3V

Pin 12 (VSS) → GND

Pin 13 (VREFA) → 3.3V

Pin 14 (VOUTA)

As you can see I’ve written that using an oscilloscope I can see the clock signal and the data transmission but what I don’t see is the SSPFRM becoming low after the transmission. Infact it seems to stay high forever.

Have any idea?
Thanks

Hello @raja.tx ,

I’ve tried updating the CE Image to the last version but it doesn’t work. After I’ve tryied with a VF50 module and it works perfectly.

So probably my IMX6 is damaged. Since is already in warranty can I send you? What is the procedure please?

@raja.tx An Important Update

Since I have another i.MX6 I’ve updated it with the latest Windows CE8 Image and I’ve tested the software.

The same software SPIDemo works on VF50 and doesn’t work on i.MX6 Colibri.

I’m using the latest libraries also in this demo project.

So what’s the problem? The code is correct since it works with VF50.

Please let me find the solution, I’m spending many days.

Hi @emmettbrown,

Could you share the whole project with binary and source form and let me test that here and get back you.

You would use https://share.toradex.com/ to share the project with us and don’t forget to post the link here.

You can use the Toradex easy installer or IMX6 Recovery procedure to recover the damaged module.

Let us know if you have any other questions.

Dear @emmettbrown,

You should use the below method to assign chip select to the library. Updated source code and uploaded here.

ioCs.number = 86;
ioCs.type = (ushort)gpio.tIoType.ioColibriPin;

spi.Spi_SetConfigInt(spiHandle, "ioCS", ioCs.GenericDefinition, TdxCommon.ParamStorageType.StoreVolatile);          ///< Set Chip Select pin sodimm 86

Let us know if you have any other questions.

Dear @emmettbrown,

I have tested the same application on iMX6S and I am able to see CS and CLK toggling. Please refer attached picture and log message. Could you also share the snapshot of measuring setup and debug log and let me check that.

Dear @emmettbrown,

We have Gpio config tool using that you can verify SPI CS pin alternate functionality mode after SPI_Open API is called.

@raja.tx now it works!

This is why I love Toradex, since your professionality and your support is the best.

Thank you very much!

@raja.tx Now it works!

Thank you very much.

Your help was very precious!

MANY THANKS

@raja.tx

Thanks,

here is the link of the project:

https://share.toradex.com/f7h5ttbgbxhaxp0

Kind regards

@raja.tx

Thank you very much, I will give you a feedback.

@raja.tx sorry but it doesn’t work.

With your code the VF50 works but the i.MX6 doesn’t.

Hello @raja.tx ,

I’ve used GPIO Config on VF50 and i.MX6 using the versions required (vybrid for VF50) and I can see the same behaviour: after the open function that CS Pin becomes Output and goes to 0.
I don’t know how much could be useful this test since this tool seems to be used with the evaluation board and I’m working on Iris Board.

With the oscilloscope now I can see for each CPU modules the CS, Clock and Write signals as pulse trains but still now only the VF50 produces a wave form outside the MCP4922 DAC.

I’ve taken the debug log for each module, please download here:

link text

Here are the snapshots of my test equipment working on VF50:

[upload|MmYdsk/MxzbUMdOaGL2jRYo9LUc=]

[upload|X+WlUc6+mN/W289f1o4IInu31gI=]

[upload|JqPDrs2t8yGT6eR5JrFnzP3R3jU=]

[upload|AsWN33zHkWXkD4Mrm1/co2K56tY=]

Hope you will give me the final solution because I’m really disappointed since the system works perfectly for VF50 and not for the iMX6 with all the same hardware. PLEASE

@raja.tx Hello,

I’m waiting you and Toradex hoping for a solution. Please don’t forget me. It’s a very strange issue since the system works with VF50 and doesn’t work with the i.MX6, the same system.

Are you sure there’s no bug in the last libraries?

I’m waiting from a friend a Toradex T20 to make another test and I’m waiting also for the Development Board, just to be sure.

So please keep me informed.

Kind regards,

Giuseppe

Dear @emmettbrown,

Did you set BitsPerWord to 8?
spi.Spi_SetConfigInt(spiHandle, “BitsPerWord”, 8, TdxCommon.ParamStorageType.StoreVolatile);

Unfortunately, default BitsPerWord is different for Vybrid and iMX6, that can be configurable through API.
I updated the already shared application and uploaded here.

Probably this would have found it if we already probed SPI signals and compared.

Please let us if it doesn’t work.

Thank you.