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.

Clarifications about DMA in TMS570LC4357

Other Parts Discussed in Thread: TMS570LC4357, HALCOGEN

Hai all,

These are not a questions actually. I Need some clarification of how DMA works in TMS570LC4357. Please anybody explain.

i. How DMA in TMS570lc4357 is handling any Two channels concurrently? For example, If Channel 1 reads a data from a 1000th location of the Memory and also Channel 2 wants to write a data to a 2000th location of the Memory, how these two operations can happen concurrently? How Two 64 bit * 4 level deep FIFO Buffer is involving in this event?

ii. As per technical reference manual, there are totally 32 DMA requests lines commonly for all 32 channels. But  DREQASI0 - DREQASI7 register explanation is like, each one channel can have only one DMA request line assigned among all 32 DMA request lines. ( i.e: if CH0ASI<29 - 24> = 0, then DMA request line 0 can only trigger Channel 0 and none of other DMA request lines. This is what I understands.This is only assig). Is it correct?  If so How these DMA request lines can be triggered (or) which event will trigger them?


iii. If we want to trigger a channel we can trigger it by SWCHENAS register. So what is the Purpose of CHAIN<21-16> bits in the CHCTRL bits?

I kindly request you to please explain the above doubts. I'm so confused.

And is there any material available focuses on DMA Module in TMS570LC4357? Please give a link if any.


Thanks in advance.

Regards,

Karthikeyan.k

  • Karthik,

    It is OK to ask questions ;-)

    I will try to answer/clarify some of your questions.

    Two channels will NOT be running concurrently on this DMA. Two active channels will run one after the other. I use TMS570LC12x and its TRM gives good enough information. TRM will not give you the mapping of the request lines and which peripheral trigger it, look in the DS for it.

    What I understand is that the FIFO enables packing/unpacking data, rd/wr width can be different.

    DMA channels can be triggered in hw/sw and also can be chained. That is you can trigger one channel with a request line and at the end of a frame/block, you can trigger another channel by setting the chain bits. So you could assign a request line ‘x’ for ch 0, ‘y’ for ch 1, ‘z’ for ch 2 and chain ch 3 to all channels 0-2; essentially channel 3 gets trigd by req x,y & z at the expense of 3 channels.

    Hope this helps,

    Joe

  • Hello Karthik,

      The DMA in LC4357 is an enhanced version from other Hercules devices. It has two ports, two FIFO and it supports multi-treaded transactions. So in your example, it is possible that the DMA is reading from 0x1000 in the system memory on one channel using one port while another port is reading from another location such as peripheral using another port. As I just mentioned the LC4357 can support multi-thread and out of order trnansction. It is possible to see the DMA issuing both a read and a write transactions to the L2 Flash and L2 SRAM respectively at the same time.

      The DREQASIx is to map any one of the 64 request lines to any one channel. For the request mapping please refer to the "Default DMA Request Map" section in the LC4357 datasheet.

      The SWCHENAs acts as a trigger. The CHAIN allows one channel to automatically trigger another channel. So if you have channel 0 chained with channel 1 and you apply a trigger on channel 0 using HWCHENA then both channel 0 and channel 1 will be serviced.

  • Thanks Charles for the correction. -Joe
  • Hello Joe & Charles,

    Thanks for your fast reply.

    Can we get it some what closer please..

    1. As per "Table 5-40. DMA Port Assignment", Both Reading from L2 Flash & writing to L2 SRAM should be done via the same PORTA. Then how these two tasks are possible to be happended at a same time if, Read element size = write element size = 64 bits wide (maximum for a trial)?

    2. So as per trm, CHAIN<21-16>bits in CHCTRL will just selects a channel (any one channel alone) that will be triggered next. It explaines not like "this" channel is chained with "that" channel if CHAIN<21-16> setting is made like "this". Then how it is said like one channel (or else any one of available channels) can trigger another channel? and Is it like, each channel can be chained only with any one of the channel among 32 available channels?

    (and One additional Question please..)

    3. There is only one register ISADDR. So how can I say the source address written in ISADDR is for Channel X, and for channel Y another source address can be set-up? Because as per trm, "Figure 20-5. Control Packet Organization and Memory Map" there are totally 32 Primary Control packets (Primary CP0 to Primary CP31) and 32 Working Control Packets (Working CP0 to Working CP31) are available. So where are they? and Which way I can access them (of course "Working CP0-CP31" can't be accessed.)?
    (Same Question applies for IDADDR, ITCOUNT, EIOFF, FIOFF, CSADDR, CDADDR, CTCOUNT also?)

    Favourably waiting for your reply.

    Thanks a lot in advance.

    Regards,

    Karthikeyan.K
  • Thanks Joe for your answer. Still can we get closer? Please.
  • Hello Karthik,

      1. In this case, reading from L2 flash and L2 SRAM can not happen at the same time. Let me give an example where parallelism is possible. You might try to transfer some data from L2 flash (Port A) to a peripheral X (Port B) uisng one channel. You might also have another channel trying to transfer data from L2 SRAM (Port A) to another peripheral Y (Port B) . While the DMA is reading from L2 flash, reading from L2 SRAM is not possible. However, after DMA first reads the data to its internal FIFO, it is possible for DMA to start reading from L2 SRAM on Port A while DMA is writing the data to peripheral X using Port B.

      2. Yes, any one channel can be chained to any one of the channel among the 32 available channels. Every channel is associated with a control packet where you can specify what is the next channel for the current channel to chain to.

      3. As i mentioned in #2, there is one primary control packet for each channel. Each primary control packet associated with each channel has its own ISAADDR along with other fields such as ITCOUNT, EIOFF and etc.  The primary control packets start at 0xFFF8_0000. Primary control packet 0 will occupies address range from 0xFFF8_0000 to 0xFFF8_001F. Primary control packet 1 will start at 0xFFF8_0020 and so on. The working control packet 0 will start at 0xFFF8_0800. Working control packet 1 will start at 0xFFF8_0810 and so on for subsequent channels.

  • Hai Charles,

    Really really really thank you a lot. All these explanations are awesome. You really helped me for understanding the DMA Module.

    Thank you Charles.

    Regards,
    Karthikeyan.K
  • Hai Charles,

    Again I come to trouble you. Please Clarify me.

    I had tried to Read 0x08000000th location from a memory and to write the data red in 0x080000FFth location in a Memory and the same data in the SCI1-TD register so that I can see the data in hyper terminal window.

    But Nothing comes in both the Hyper terminal window & Watch Window.

    Please guide me to how to do this.

    I thought probably you genius will some what busy, right?. So If suppose you have any example code for accessing PORTA & PORTB for Memory & Peripheral please kindly share with me.

    For TMS570LC4357, is there any Application Notes (like normally we have for any PIC micros)? How to get that? Normally I google it. This time it didn't work. That's why!.

    Anyhow, Thanks a lot Charles. Thanks for your help and again expecting your guidance.

    Regards,

    Karthikeyan.k
  • Hi Karthik,

    Try to have a look at the halcogen example file which should give most of what you are looking for,

    >\ti\Hercules\HALCoGen\vxx.xx.xx\examples\TMS570LC43x\example_sci_dma.c
  • Hai Raja,

    I had tried that also. Unfortunately that code uses hardware request of SCI3 for DMA access. But I wanna use SCI1 for communication. SCI1->TD register to be written by DMA module. SCI1 have no hardware request signal for DMA triggering.

    PORTA_READ_PORTA_WRITE also not working. :(

    Halcogen code actually shows "fail" result in Console window when LOOP_BACK_MODE defined.

    So If There is any example code, then it can be used to trace. Can you help me?

    Regards,

    Karthikeyan.K
  • Hai Charles,

    Here I have attached my try.

    I can't figure out the bud here. Are they Visible to you?

    My aim is to read from RAM & write that data again to RAM at different location and to see the result in watch window & hyper terminal.

    #include "HL_sys_common.h" #include "HL_sys_dma.h" #include "HL_reg_dma.h" #include "HL_reg_sci.h" #include "HL_sci.h" void SCIChr(char Chr) { sciSendByte(sciREG1,(uint8)Chr); } void SCIStr(char *Str) { while(*Str) { SCIChr(*Str); Str++; } } void Delay(uint16 Time) { uint16 i,j; for(i=0;i<Time;i++) for(j=0;j<1000;j++); } void main(void) { /* USER CODE BEGIN (3) */ uint32 *SRCPtr = (uint32 *)0x08000000; uint32 *DESPtr = (uint32 *)0x080000FF; *SRCPtr = 5; *DESPtr = 0; g_dmaCTRL CP0 = { 0x08000000, /* Initial source address */ 0x080000FF, /* Initial destination address */ 0, /* Next channel to be triggered + 1 */ 1, /* Frame count */ 1, /* Element count */ 0, /* Element destination offset */ 0, /* Element source offset */ 0, /* Frame destination offset */ 0, /* Frame source offset */ PORTA_READ_PORTA_WRITE, /* DMA port */ ACCESS_32_BIT, /* Read element size */ ACCESS_32_BIT, /* Write element size */ FRAME_TRANSFER, /* Trigger type - frame/block */ ADDR_FIXED, /* Addressing mode for source */ ADDR_FIXED, /* Addressing mode for destination */ AUTOINIT_OFF /* Auto-init mode */ }; sciInit(); SCIStr("I'm Ready..\r\n"); dmaEnable(); dmaSetCtrlPacket(DMA_CH0,CP0); dmaSetChEnable(DMA_CH0,DMA_SW); Delay(1000); SCIStr("Des: "); SCIChr((char)(*DESPtr+48)); SCIStr("\r\n"); while(1) { } /* USER CODE END */ }

    (I've used SCI1 with 9600 Baudrate in this try.).

    Thanks in advance,

    Regards,
    Karthikeyan.K.

  • Hai Charles,

    Here I have my code. I can't detect the bugs there. Are they visible to you?

    My aim in this code is to read a RAM memory and to write that data to another location in a RAM memory using DMA and see the result in the Watch Window.

    Additionally I used SCI1 at 9600 baudrate to read that destination address to ensure the write operation completed.

    But nothing happens when I burn this code.

    #include "HL_sys_common.h" #include "HL_sys_dma.h" #include "HL_reg_dma.h" #include "HL_reg_sci.h" #include "HL_sci.h" void SCIChr(char Chr) { sciSendByte(sciREG1,(uint8)Chr); } void SCIStr(char *Str) { while(*Str) { SCIChr(*Str); Str++; } } void Delay(uint16 Time) { uint16 i,j; for(i=0;i<Time;i++) for(j=0;j<1000;j++); } void main(void) { /* USER CODE BEGIN (3) */ uint32 *SRCPtr = (uint32 *)0x08000000; uint32 *DESPtr = (uint32 *)0x080000FF; *SRCPtr = 5; *DESPtr = 0; g_dmaCTRL CP0 = { 0x08000000, /* Initial source address */ 0x080000FF, /* Initial destination address */ 0, /* Next channel to be triggered + 1 */ 1, /* Frame count */ 1, /* Element count */ 0, /* Element destination offset */ 0, /* Element source offset */ 0, /* Frame destination offset */ 0, /* Frame source offset */ PORTA_READ_PORTA_WRITE, /* DMA port */ ACCESS_32_BIT, /* Read element size */ ACCESS_32_BIT, /* Write element size */ FRAME_TRANSFER, /* Trigger type - frame/block */ ADDR_FIXED, /* Addressing mode for source */ ADDR_FIXED, /* Addressing mode for destination */ AUTOINIT_OFF /* Auto-init mode */ }; sciInit(); SCIStr("I'm Ready..\r\n"); dmaEnable(); dmaSetCtrlPacket(DMA_CH0,CP0); dmaSetChEnable(DMA_CH0,DMA_SW); Delay(1000); SCIStr("Des: "); SCIChr((char)(*DESPtr+48)); SCIStr("\r\n"); while(1) { } /* USER CODE END */ }

    Please guide me to this operation.


    Thanks in advance,


    Regards,

    Karthikeyan.K
  • Hello Karthik,

      Your control packet is configured to transfer from L2RAM to L2RAM. And you also configure to use a S/W trigger. The setup is fine. I suspect the problem is the destination address alignment. The destination address is 0x080000FF. However, the transfer size is configured for 32bit. Can you configure the destination address to be 0x080000FC. Let's see if it is an address problem first. If you really want to keep the byte address for your destination you can change the destination address to 0x080000FC and also change the write element size to ACCESS_8_BIT.

  • Hello Charles,

    Very dull. It's not working even after the suggested changes. Anyhow thank you for correcting me to choose address locations correctly. And Charles, I make a try, just to ensure that DMA is working fine or in other words, I'm able to handle DMA. That's all. So If any changes are suggested, then really I welcome. I don't know why it is not working!. Still searching for an answer. Is there working samples with you? Or else Is there any app notes available for TMS570LC4357?

    With lots & lots of thanks,

    Karthikeyan.K
  • Hi Karthik,
    Currently I don't have a separate example other than the one that comes with the HalcoGen for LC4357. Can you take a screenshot of all the DMA registers and also the control packet 0 that you use for channel 0. It can give me some clues as to what when wrong. In the meantime I can try to create an example to transfer some data from L2RAM to L2RAM for illustration.
  • Hello Karthik,

     Here is a simple project to transfer 10 elements of data from L2SRAM to L2SRAM.

     

    5875.LC4357_DMA_SRAM_to_SRAM_transfer.zip

  • Hai Charles,


    Really Thanks a lot Charles. Your code is working perfectly. If I did any modification in your code as per my requirement, that also works fine. But If Suppose I create a new project and use your same void main() code, Nothing happens. So I suspect that generation of code using Halcogen. I disable all the peripheral if I create new project. Hope you also did the same thing. And I tried to compare your project using halcogen with a new project. By that way I found some differences on R5-MPU-PMU window, between your project and my new project. I suspect whether it causes an in-active response when running on IC.


    Did you initialise any special hardware initialisation when you generate code usiing HalCoGen? Or Did you touch the allocation of memory in R5-MPU-PMU window.

    Thanks,

    Regards,

    Karthikeyan.K

  • Hello Charles,

    Finally I Found a bug in my code. Actually the Bug is from MPU Default Settings. In HalCoGen Region 3 setting is PRIV_RO_USER_RO_NOEXEC. This the mistake actually. Because of this settings, L2SRAM is not accessed. So I make this region as PRIV_RW_USER_RW_EXEC. After I make this settings, everything is fine. So Next I have to hunt about Memory regions and their settings. Anyhow thanks a lot Charles. Thank you so much. Really you helped me a lot. Of Course Soon I will come with another Bug & ask you help. Thanks Charles.

    Regards,
    Karthikeyan.K.
  • Hi Karthik,

      Glad that you found the problem. Yes, the project I created was based off the HalcoGen with the default MPU setting. Please also note that the DMA is always operating in user mode even though its registers/control packets can only be configured in privilege mode. If you come across with other questions, please open a new thread and our team will be glad to help you.