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.

TMS570LS3137: Sending multiple 24 bit transfer groups

Part Number: TMS570LS3137
Other Parts Discussed in Thread: HALCOGEN,

I am using MIBSPI1 to communicate with a AD5676 SPI interface 8 channel DAC.  It uses 24 bit transfers. 

I can successfully write and read to the DAC with a single transfer group length=3, Data format=8 bits, Chip Select Hold=1.

I need to send 8 commands (configure all 8 channels) to the DAC in an ISR -- without CPU intervention for each command.  Or in other words I need to send 8 24 bit transfer groups automatically, from within an ISR.

I looked at the HALCoGen DMA SPI example, but it doesn't appear to work for my situation. 

Chaining transfers using IRQ won't work as I need to initiate the transfer in a ISR that is a FIQ??

How can I do this?

Thanks,

-Joe

  • Hi Joe,

    I just confused with your requirement!

    I need to send 8 commands (configure all 8 channels) to the DAC in an ISR -- without CPU intervention for each command.  Or in other words I need to send 8 24 bit transfer groups automatically, from within an ISR.

    See ISR requires CPU intervention. ISR routine execution cannot be happen without CPU intervention.

    You can use either interrupt mode or DMA mode. You can't combine both of them. DMA mode is the mode which doesn't require CPU intervention.

    --

    Thanks & regards,
    Jagadish.

  • Hi Jagadish,

    Thanks for the reply. 

    By CPU intervention, I mean I'm OK for the CPU to start the 8 command transfers from the ISR, but not handle each command separately by the CPU.

    Can you point me to an example of how to use DMA to send multiple 24 bit transfer groups?

    Thanks!

    -Joe

  • Hi Joe,

    Apologies for the delay, here in India we have holidays for the last three days.

    Can you please look into below thread:

    (+) [FAQ] TMS570LC4357: Examples and Demos available for Hercules Controllers (E.g. TMS570x, RM57x and RM46x etc) - Arm-based microcontrollers forum - Arm-based microcontrollers - TI E2E support forums

    Here you can find several SPI DMA examples, just search with keyword "SPI".

    --

    Thanks & regards,
    Jagadish.

  • Hi Jagadish, thanks for those additional code samples, I hadn't seen them before.

    I looked at hercules_examples-master\Application\TMS570_SPI_DMA closely, but due to my unfamiliarity with Hercules DMA, I remain confused on how to send 8 different 24 bit transfer groups via DMA without using interrupts.  Is there an application note that accompanies the TMS570_SPI_DMA example code?

    Thanks and regards,

    -Joe

  • Hi Joe,

    Actually, the SPI doesn't support 24bit character length by default:

    It can support max of 16bit character length only. So, my question here is that, in normal mode (without DMA) you said you were able to operate without any issue, right?

    So, what is the character length you defined?

    Are you sending byte by byte?

    Are you using chip select in your communication?

    Can i see the waveforms of MOSI, CLK and CS like something below?

    If you provide above details, then i can provide ideal solution.

    --

    Thanks & regards,
    Jagadish.

  • Hi Jagadish,

    Yes, using MIBSPI1 I can successfully send single 24 bit transfers to  AD5676 by sending 3 8-bit data formats in a transfer group using the built-in CS_0 with "Chip Select Hold" checked.  See below HALCoGen configuration screen shots.

    This is my current transmit code:

    // Copy data to SPI data register
    mibspiSetData(DAC_MIBSPI, c_spiTransferGroup0, g_spiTransmitBuffer);

    // Start SPI transfer
    mibspiTransfer(DAC_MIBSPI, c_spiTransferGroup0);

    // Wait for transfer to complete
    while (!(mibspiIsTransferComplete(DAC_MIBSPI, c_spiTransferGroup0)));

    Unfortunately, I don't have the ability to do a oscilloscope capture of a transaction right now.  Let me know if this is critical and I can take steps to get it setup. 

    Your help figuring out how to send 8 back-to-back 24 bit commands (each command with it's own CS assertion/deassertion) with the CPU just initiating the process would be greatly appreciated,

    Best regards,

    -Joe

  • Hi Joe,

    Thanks for providing details!

    If i understand your requirement correctly, here is what you are trying to do.

    You want to activate the CS and want to send 3 bytes and after that you want to toggle the CS line, and again you want to send the 3 more bytes  and want to toggle the CS bit at the end of 3 bytes, and this process should need to continue for 8 commands (total 24 bytes).

    For example i want to implement the following thing:

    I want to write to 8 DAC input registers with the value of 0x0000.

    So, command would be 0x1 and Address bits would be 0x0 to 0x7, So i want to send below eight 24bits data to the frame

    0x100000, 0x110000, 0x120000, 0x130000, 0x140000, 0x150000, 0x160000 and 0x170000.

    To do this i am just following your method only, i wan to transfer the data in the byte format and i want to hold the CS line for every 3 bytes. 

    That means, i want to divide the previous data as below

    0x10, 0x00, 0x00, 0x11, 0x00, 0x00, 0x12, 0x00, 0x00, 0x13, 0x00, 0x00, 0x14, 0x00, 0x00, 0x15, 0x00, 0x00, 0x16, 0x00, 0x00, 0x17, 0x00, 0x00.

    But the very important thing while using DMA in this method is, i just don't want to transfer 8bit data only.

    As i need to control the CSHOLD bit also right, that is why i want to do 32bit transfers from DMA.

    That means i want to write CSHOLD bit as 1 if i want to hold the CS line and i want to write CSHOLD bit as 0 if i don't want to hold the CSHOLD bit.

    That means i want to HOLD the CS line for first two bytes and i don't want to hold the CSHOLD while sending 3rd byte.

    That means my DMA transfer data will become as below

    0x10FE0010, 0x10FE0000, 0x00FE0000, 0x10FE0011, 0x10FE0000, 0x00FE0000, 0x10FE0012, 0x10FE0000, 0x00FE0000, 0x10FE0013, 0x10FE0000, 0x00FE0000, 0x10FE0014, 0x10FE0000, 0x00FE0000, 0x10FE0015, 0x10FE0000, 0x00FE0000, 0x10FE0016, 0x10FE0000, 0x00FE0000, 0x10FE0017, 0x10FE0000, 0x00FE0000

    If you decode one word, e.g. 0x10FE0010

    Here CSHOLD 28th bit is 1.

    CSNR will be 0xFE as i am using CS0.

    TXDATA is 0x0010 as we configured 8 bit transfer right so the higher byte will not send to the slave only lower byte i.e. 0x10 will send to the slave.

    So here is my implementation:

    And after testing, here is my result:

    And here is my complete project for your reference:

    4300.SPI_DMA_TEST_LC4357.zip

    --

    Thanks & regards,
    Jagadish.

  • Hi Jagadish,

    Thanks so much for the example code and the clear explanation.  Your output waveform looks exactly what I need.

    I copied your code to a new TMS570LS3137 HALCoGen project and made some edits to convert from using SPI3 to SPI1, but I was unable to get any output on SPI1 CS or CLK on my TMS570LS3137 HDK board. 

    Here is my complete project for your reference in hopes you can spot something wrong. SPI_DMA_TEST.zip

    Do you have access to a TMS570LS31x HDK? 

    I'm wondering if there are needed code differences between the LC4357 and the LS3137?

    Best regards,

    -Joe

  • Hi Joe,

    Do you have access to a TMS570LS31x HDK? 

    Unfortunately, i don't have TMS570LS31x board with me.

    Give me some time i will just try to create the example for SPI1 on LC4357.

    --

    Thanks & regards,
    Jagadish.

  • Hi Jagadish,

    I now have SPI1 CLK and CS working, but CS stays asserted the entire transfer, see attached oscilloscope photo.  Sorry about the low resolution and only 2 channels.  The lower waveform is CLK and the upper waveform is CS0/.

    To get this to work this far I changed the DMA PORTASGN value from 1 to 4 in dmaConfigCtrlTxPacket() per another 3137 MIBSPI DMA example.  I presume this is difference between the 3137 and the LC4357.

         g_dmaCTRLPKT_TX.PORTASGN = 4; // PORTA_READ_PORTB_WRITE;

    I've attached my project as reference.

    SPI_DMA_TEST_11Oct2023.zip

    It appears as if the DMA to the SPI1 TX is working fine. 

    The data being sent is the same as your example, I'm wondering what could cause the CS to not deassert per the CSHOLD values in the data?

    Thanks again for all your help!

    Best Regards,

    -Joe

  • Hi Jagadish,

    I found that the CS de-assertion pulses are too narrow to show up on my oscilloscope, but the 8 DMA transactions (when I remove the oscilloscope from the circuit) are successful in writing to the DAC! :-)  

    Thanks so much for all your help, code, and great explanations!

    -Joe

  • Hi Jagadish,

    Another, hopefully last?, question:

    What is your recommended way of telling if when/if the DMA transaction has completed?

    Thanks and best regards,

    -Joe

  • Hi Joe,

    What is your recommended way of telling if when/if the DMA transaction has completed?

    You can find out by either polling or enabling the BTC interrupt.

    In your case this flag will get SET after all the 8 commands transmitted.

    --

    Thanks & regards,
    Jagadish.

  • Hi Jagadish,

    While I can do 1 8 command DMA transfer, I an unable to do a 2nd successful one.  I wait and check to make sure the 1st is complete by polling the BTC flag, 

    Do I need to reset the DMA engine each time?

    Can you do a quick test on your system to see if you can do 2 or 3 8 command transactions?

    Thanks,

    -Joe

  • Hi Joe,

    Do I need to reset the DMA engine each time?

    No need to do reset the DMA engine.

    The simplest way is just clear the BTC flag before you reenabling the channel, like something below:

    --
    Thanks & regards,
    Jagadish.