This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

C2000, spi

Other Parts Discussed in Thread: CONTROLSUITE, TIDM-DELFINO-ETHERCAT

Anyone with experience with Spi +dma+fifo on a c2000 or a f28377D?? an not get the example running

  • Hi Henk,

    Are you talking about this example: C:\ti\controlSUITE\device_support\F2837xD\v190\F2837xD_examples_Cpu1\spi_loopback_dma\cpu01
    If so, it does work very well.

    Regards,
    Gautam
  • Thanks for your reaction, Gautam.

    That sample works as is, but is unuseble, as in practice loopback will be off.

    Try to change the clock polarity to 1, although no peripheral I/O is programmed  and the loopback don't need a clock signal, the sample does not work any more.

    As soon as fifo is enabled, the spi communicarion with the ethernet device on my board becomes unreliable, with complete bursts missing. And, I need to use clockpolarity 1. This took me a month now and is killing the project. Without fifo everything works perfect and with very high speed (30 MHz), But the dma is essential for timing reasons. Is there still a bug in my TMX device? TMS only was available this year.

    Any help is welcome!!!

    Bye, Henk Schutte, Amsterdam

  • Henk let me forward this to C2000 team.

  • Hi Henk,

    I'm looking into this. Can you give me some more details about the specific failures you're seeing? You say it's DMA bursts going missing? Anything else?

    Thanks,

    Whitney

  • Hello Whitney,

    Basis of what I did was the example app spi+dma+fifo.

    This sample worked, of course.

    Then I checked the hi-speed options, as I need up to 40MHz, still succesful.

    Then I programmed the Gpio58...61 for HiSpeed connection with my ethernet device (Beckhoff ET1100). I changed the clock polarity (not phase) to 1, released the loopback, released the fifo (.SPIFFTX.bit.SPIFFENA = 0) and then all the communication was working perfect up to 33MHz.

    Then I switched on the fifo again and started dma:

            SpiState = 0;
            ReadReg(0x1300, &rdata, 256);         // this is the routine that works perfectly, view memory at 0x1300 shows the content of the ET1100
    ->        SpiaRegs.SPIFFTX.bit.SPIFFENA = 1;             // enable fifo  FFLvl = 8,
            GPIO_WritePin(61, 0); // active low
            StartDMACH6();        // Start SPI RX DMA channel
            StartDMACH5();        // Start SPI TX DMA channel
           while (SpiState == 0);        // wait until the DMA transfer is complete
    At this point I can not see the same data arriving at rdata, although the dma finished completely. (8-1 burst, 32-1 transfers) and the memory view showed 256 words mostly in red.

    Slowing the speed to 10 Mhz, introducing ...TXDLY = 8, ....nada.

    I tested also the ReadReg() function with fifo enabled as the only change, Same problem. Maybe the problem is in the fifo functionality. I tested this further::

    As soon as fifo is enabled, things go wrong. Inserting delay after a fifoenable does not work. Apparently, it is not possible to change fifoenable in a running program.

    Thanks a lot for your assistence.

    Henk

  • In addition to my earlier reply, I can affirm that the problem is indeed changing fifoenable on the fly. Why, is not clear, this needs some extra documentation from TI, I am afraid.
    I am currently rewriting al my spi routines to work with fifo enabled and keep fifo enabled all the time.
  • Hi Henk,

    I'm glad you managed to track down a way around the issue. I'm sending a note to a colleague who knows our SPI behavior better than I do to ask if he knows of any issues with enabling the FIFO on the fly and what notes we may need to add to the documentation.

    Edit: I know we do support changing the FIFO reset bits, but I think that's mostly with the intent of resetting the FIFO pointer.

    Thanks,
    Whitney

  • Well, I finished changing all the spi routines, so they work with fifoenabled. Things run completely predictable now, but I still miss 1 burst data at the beginning of the block (8 zero's). On the scope, things look normal, second word shows to be 0x0030, but in the data 0x0030 is on location 9. All fifo statusses are 0 at start. Hope this info helps.

    Henk

  • Henk,

    So the data on the scope looks good, but the received data in the buffer is missing or out of order?

    Do you mind sharing a snippet of what your DMA configuration code looks like for the transfer where the burst goes missing?

    Thanks,
    Whitney
  • Sure, Whitney,

    #define FIFO_LVL     8                //RX FIFO Interrupt Level
    #define BURST         8 // -1
    #define TRANSFER      27             //  -1   MEM_BUFFER_SIZE/BURST dus 208 words/8 = 26 bursts (+1 added burst to compensate for the empty first burst)

    // DMA setup for both TX and RX channels.
    void dma_init()
    {//Initialize DMA
        DMAInitialize();

        DMASource = (volatile Uint16*)&sdata;
        DMADest = (volatile Uint16*)&rDatag  -  9;//skip first burst + cmnd

        // configura DMACH5  for TX
        DMACH5AddrConfig(&SpiaRegs.SPITXBUF,DMASource);
        DMACH5BurstConfig(BURST-1,1,0);            // Burst size, src step, dest step
        DMACH5TransferConfig(TRANSFER-1,1,0);        // transfer size, src step, dest step
        DMACH5ModeConfig(DMA_SPIATX,PERINT_ENABLE,ONESHOT_DISABLE,CONT_DISABLE
                ,SYNC_DISABLE,SYNC_SRC,OVRFLOW_DISABLE,SIXTEEN_BIT,CHINT_END,CHINT_ENABLE);

        // configure DMA CH6 for RX
        DMACH6AddrConfig(DMADest,&SpiaRegs.SPIRXBUF);
        DMACH6BurstConfig(BURST-1,0,1);
        DMACH6TransferConfig(TRANSFER-1,0,1);
        DMACH6ModeConfig(DMA_SPIARX,PERINT_ENABLE,ONESHOT_DISABLE,CONT_DISABLE,
                SYNC_DISABLE,SYNC_SRC,OVRFLOW_DISABLE,SIXTEEN_BIT,CHINT_END,CHINT_ENABLE);
    }

  • Henk,

    It seems a little strange to me that you would be subtracting from rDatag instead of adding to it, but it's hard for me to guess just from this code how you have your buffers laid out. Do you have a buffer that is contiguous to it that is supposed to hold the first burst and command?

    Do you have both the TX and RX FIFO levels set to 8?

    Whitney
  • Hello Whitney,

    Yes, both fifolevels are 8.

    The subtracting (-9) is a little dirty solution to skip the first burst (and a not-significant word). I know that this memory is not in use. Anyway, before this dirty workaround, the first 8 words in rDatag were 0, loosing the last 8, now these meaningless words are located before rDatag.

    I ruled out the possibility that a former spi command was not finished properly, as the first dma code after reset already showed the problem.

    I stopped momentarily with the dma+fifo solution as a more serious problem did show up, so there is more at hand. I found that the memory of the ethernet chip was polluted with data at an address outside the dma/fifo addresses.

    For the moment I use a simple spi read routine that works reliably and which basically should do the same as the dma. But it holds the Delfino for an unacceptable 250 usec, only interrupt routines produce some functionality.

    As you may have noticed, the dma code is just copied from the TI-example.

    The dma was programmed to send part (first 208, 26 bursts, now 216, 27 bursts) of the data from sdata[256], which contains only zero's, except sdata[0] which contains the address+read-command. This must be the code that does not perform what I intended it to do.However, I confirmed that all the registers for DmaCh5 and 6 indeed contains the proper addresses.

    It seems unlikely that some hardware problem is at hand, as the TI-loopback example worked perfectly.

    I really hope you may come up with some useful suggestions.

  • Whitney, did you made any progress with the Spi problems.
    After I finished converting all the routines for fifo functionality, new problems arose. I abandoned the dma solution, and work now with filling the 16-level fifo, wait 20 us for a next interrupt, read data and send new 16 words, etc.
    This solves all the timing problems without dma. But soon strange things happens, such as writing one word to TXBUF and then observing a RXFFSTS of 2. Resetting with a RXFIFORESET 1, 0, 1 cycle leaves RXFFSTS to be 1. Only after at least 10 us repeating this, makes RXFFSTS zero. Also strange: as soon as fifo is enabled, I need to make CLK_PHASE 1, otherwise bits are shifted. (all with 10 and up to 40 MHz speed)
    Please stimulate your spi-colleague at TI to take some attention to this. Is it the TMX version that I use, are the problems solved with the TMS???
    Thanks,
    Henk Schutte
    Amsterdam NL
  • Hi Henk,

    I apologize for the slow response. You say you're using the ET1100, right? Their data sheet seems to say that the SPI clock speed should be <= 20MHz. I'm concerned that that could be the issue. Do you get better behavior at 20MHz? For example, can you keep the phase set to 0? Do the extra words in the FIFO go away?

    Our SPI module hasn't changed much across devices over the years, so F2837x's newness isn't likely to be an issue where SPI is concerned.

    Edit: Out of curiosity, have you looked at our ET1100 reference module? Or any of the software for it? http://www.ti.com/tool/TIDM-DELFINO-ETHERCAT

    Whitney

  • Thanks, Whithey,

    No at 10MHz it was the same. (In the TI example code (below) for the ET1100, even 50MHz is used)
    I missed the new ET1100 module from April, very nice to mention this, thank you. I now see from the example C code that I used mostly the same register values. I will test the effect of some small differences. Anyway, the example code uses PHASE 0, as my system shows to only work with phase 1.
    Henk
  • Henk,
    can you see if the relevant initialization from the example code works for you as well? You are using SPI as PDI to ET1100 - correct? is your EEPROM programmed properly, you can verify the EEPROM contents with one provided in the example as well, this might affect the behavior of SPI on ET1100.

    Also I don;t understand PHASE0 or PHASE1 you refer to, are you referring to SPI modes supported by ET1100?

    First if we could get the basic byte, word and block communication working between the MCU and ET1100 we can work on adding FIFO/DMA. Also can you let us know your use case, why are you trying to use DMA and FIFO? what is the nature of data transfer between MCU and ET1100?


    Best Regards
    Santosh Athuru
  • Hello Santosh,

    Thanks for your concern.

    Phase is the Spi clock_phase, together with polarity it provides four modes. The ET1100 is on Spi mode 3, corresponding to clock polarity = 1 and clock phase = 0. Al the communication between the F28377D and the ET runs reliably up to 40 MHz, although Beckhoff limits the ET to 20 MHz. On the scope, the DO signal from ET looks completely healthy at 40.

    The initial need for dma was saving time. I use almost the complete bandwidth of the f28377d to close a servo loop, which runs at high speed and high precision.

    Initially, things went completely out of control as soon I used the dma+fifo example from the TI F28377d.example codes in ControlSUITE. I did not know whether there was something wrong with dma or with fifo. Anyway, the example code uses loopback and runs perfectly this way, but then with clock polarity = 1 and then with the Gpio pins 58..60 programmed for spi, problems started.

    I decided first to rewrite all of the spi routines to work perfectly with fifo enabled. I use 16 bit as this seems to me the more efficient way to do in a F28 and the ET supports this too. I do not use addressing with wait states, like in the code ( that maybe you made), publshed  (ethercat_slave_c28x_hal.c). I control the SPISTE signal manually, this way you can insert the 200 ns delay required by Beckhoff.

    I analysed further the differences with the TI example and my code. Maybe essential was to insert a while loop for BUFFULL.between writes to SPITXBUF.

    At this moment I use the 16 level fifo as follows. First i send the address + command (Read) word to the ET (gpio61 first made low) and read one dummy word. Then I fill quickly the TX fifo 16x with zero words. In the next timer interrupt (48KHz timer) I read 16x RXBUF) and send another 16 zero's to TX. This is repeated until all data are in (208 words every millisec).

    I use the same trick for writing two 16 word blocks; that works reliably but only with the following.

    I found that the RXFFSTS is not always zero after RXFIFORESET 0...1. , also after some delay. also if repeated. For security I reset the complete spi (SPIRST) after writing all data, which I consider as a dirty solution.  I don't know if this happens randomly with reading as well, I am afraid this is the case as my motor runs not smoothly.

    I suspect that some unpredictable behaviour originates from the transfer of TXfifo to TXBUF to DATA with high data rates.

    It would be very nice to have your attention on my Spi problems, and maybe for the whole F28 community as well.

    By the way, I don't use TwinCat, but I use my own EtherCAT stack, a C++ translation of Simple Open EtherCat Master (SOEM) written by Arthur Ketels. This is a fast but not a real time solution in Windows, but my servo code runs inside the F28. SOEMaster runs on Windows 10, as my CNC code does. Everything will ultimately run in Win8 Embedded..

    Henk Schutte

    Amsterdam NL

  • Henk,
    thanks for the details. I will try to get my examples running with FIFO enabled and let you know how it goes.


    Best Regards
    Santosh
  • Santosh Athuru said:
    Henk,
    thanks for the details. I will try to get my examples running with FIFO enabled and let you know how it goes.


    Best Regards
    Santosh

    Hello Santosh,

    Anything to report already?

    You might also call me in Amsterdam, +31 651317847

    Thanks,

    Henk Schutte

  • Henk,

    I'm still looking into it among other things. Have the SPI RX FIFO working, need to add DMA and SPI TX FIFO.

    Will keep you updated.

    Best Regards

    Santosh

  • Henk,

    I'm still looking on this, just letting you know. Have been pulled into other priorities, hope to get back to this example mid week, next week.

    will keep you posted.

    Best Regards

    Santosh Athuru

  • Henk,

    I just read that you managed to get SOEM running under Windows 10.
    Can you give me some info which versions you used? (especially SOEM and WinPcap)?
    Do you know a more suitable forum to talk about this?

    Thanks
    Friedemann Stütz
  • Hello Friedeman,

    Actually, I started with some SOEM version, then rewrote all the sources to C++ classes, also removing all the redundancy; both ways reduced 3/4 of the code. With max. 8 nodes, the necessity of redundancy is zero: don't touch the RJ45 plugs while a machine is running and do not close the EtherCAT loop with a second port on the PC. If you want to automate a big plant, stay with Beckhoff. They wil come soon with a Win10 version of TwinCAT, I was told. Otherwise, run SOEM on Linux.

    What is left is quite simple code and runs perfectly. Biggest problem remains to be the non-real-time nature of Win10. You have to design clever tricks to have all the handshaking in 1 Ethernet frame, as sending 1 frame takes at least 400 usecs using WinPCap (latest version, there is also a Japanese Win10 version). My problem from the onset was extremely high data rates. Actually now, I am still finishing the handshake protocol.

    It took me some time to find out that an ultra-stripped minimum EtherCAT master is also possible, almost 10 times smaller then any other master. For example, an empty system with no mailbox and no sync manager etc. is still able to write directly to the ET1100 memory. And don't worry about the official protocol, as long as you use a Beckhoff slave chip, your system will automatically conform to EtherCAT. If you use commercially available slave (I/O) modules, the mailbox protocol will still be needed.

    According to Arthur Ketels, the original developer of SOEM, real time machine control with Windows and EtherCAT (and TwinCAT) is impossible. Well, it is quite difficult, but with some restrictions (big data buffers)  I came a long way. Arthur is the most capable EtherCAT expert in The Netherlands and helped me a lot. Also, the TI example code for C2000 and the ET1100 helps a lot for the slave side, although I did not use them, I was already finished when this was published.

    Let me know how things are going.

  • Hello Henk,

    Thanks for these very helpful hints.

    In the past (up to Windows 7) I developed a windows device driver with real time capabilities by directly handing the CPU timer interrupt.
    Based on that I made a CNC motion control software for stepping and servo drives.
    Now I try to implement an EtherCAT interface.

    As I am still a newbie in regard to EtherCAT this will take me a while.
    My first experiences under Win10 confirm your statement that real time will be a big problem as long as the communication is based on WinPCap. Do you know people trying to access the Ethernet hardware registers directly?

    So my next steps will be to go in depth under linux.
    If you have C++ code you are willing to share I would appreciate it.

    Right now I use SOEM version 1.3.1. and try remote debugging a linux target by Visual Studio with the VisualGDB plugin by Sysprogs.

    Thanks again
    Friedemann