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.

CAN and DMA, TMS570 3137 HDK

Other Parts Discussed in Thread: HALCOGEN

Hello, dear Collegues

For my application I have made an adjustable tree-based memory class that provides me with two main operations:

  1. memGET(uint16 ID) // returns 64-bit value stored under this ID
  2. memPUT(uint16 ID, uint64 VALUE) //stores fiven value in given ID
The purpose is to have a storage system that will adjust (less time spend storing and retrieving more often accessed IDs) to incoming CAN traffic, since on my bus some channels are transmitted way more often then others. So some data is received and it should be stored using memPUT, after that a math parser is executed and it accesses the data using memGET, performs mathematical operations on data and saves it to some other IDs using memPUT, after that some other functions are called working with data. That is happening in loop with realtime data that is updating a fixed number of CAN IDs.
I would like to know if it is possible to have a DMA transfer from CAN message box to some place in memory whose address depends on the ID of the given message? Or that immediately involves processing overhead and cannot be done by CAN? I mean if we get CAN ID 0x100 we save it e.g. to 0x10000100 (just example) in memory, and if 0x200 we save it to 0x10000200. In that case I could insert memGET routine in the main loop before the math parser and it could fill my memory based on some lookup table and DMA would be working underneath all the time without impact on R4.
Thank you in advance!
Regards,
Kirill
  • Hello Kirill,

    I don't think this is possible, using a straight forward setup of DMA and DCAN. However, I am forwarding your email to one of our DMA experts that might be able to think of a way to set this up. One thought I had is to set it up to use different mailboxes in DCAN for specific IDs and triggering software triggered DMA channels tied to the mailbox number to transfer data to the defined memory locations. I don't know if this is possible for sure so I will let them add any further details and confirm if this is possible or not.

  • Thank you, Chuck!

    I will wait for their reply, however your reply -- if they confirm it is possibe -- is very close to my intuition telling me that in theory I can have a max of 64 mailboxes (per CAN port) each "mapped to" a specific CAN ID and triggering DMA transfer to location whose value is a certain "hashed" value of the ID assigned to mailbox. Did I get you right?

    P.S. I had an accidental power failure and both power supply of HDK and my laptop has stopped for some time during debug. Now that I restarted everything I cannot load a program to HDK, it sends a strange error of endiannes mismath in CCS debug. I guess the previous debug state is hanging or something. Is there a way to make a full reset to be able to load a new code to HDK (via normal CCS debug)?

    UPD. I will separate the last issue into another post, since I still cannot solve it, but would not like to diverge from the main topic here. Thanks!

    Thank you for your fast reply, Chuck!

    Best regards,

    Kirill

  • Good evening Chuck,

    Are there any news on CAN + DMA or comments to my reply?

    Looking forward to hearing from you!

    Thank you and best regards,

    Kirill

  • Hello Kirill,

    I apologize for the delay. I'll send an internal message to our DMA expert to make sure he is aware of your question and your need for some guidance on this topic.

  • Hi Kirill

    Looks like you are more concerned on the Message receive. I can think of following use case, again it is not straight forward.

    1) You can configure 1 to 64 mailbox with different ID's, ( up whatever you want. ). 

    2) Statically Configure DMA to be a Software trigger, with One Channel and Control Packets configured so that start address is IF3 data. ( Destination address we will configure kust before triggering). 

    3) Configure IF3 to update and receive the Message, Enable IF3 Interrupt, so that Every Message reception will trigger an interrupt.

    4) In the IF3 ISR do following
               a) Read the ID.
               b) do the "Hash" thing, update the DMA Control packets destination address. 
                c) Trigger DMA.

    Happy Programming!!!

  • Thank you Chuck and Prathap!

    This scenario seems like the most "natural" one. However could I ask you whether there will be actually some benefit from DMA in that case? Since my ID-value pairs are stored in a self-balancing tree I will anyway have to run some maintenance code after each write. Am I right suspecting that DMA could be fruitful in a less complicated storage system, but not that much here?

    P.S. That said, would you mind if at some point I ask a bit more specific technical questions following your 1-4 steps?

    Thank you very much,

    Kirill

  • Sure Kirill.

  • Dear Prathap,

    Looks like I need more assistance with the register setup work required to implement the approach you mentioned above. I am a bit lost because I don't understand what can be done in Halcogen, and what can be done manually. For the manual approach I am not yet experienced enough, but I prefer to be able to control everything manually, so I need some examples if possible. Say a code that sets up DCAN1 mailbox 1 for 0x100 id and 2 for 0x108 ID -- both for receival; Configures the DMA from IF3, leaving destination for the interrupt handler; -- here comes the question, how are mailboxes and the IDs I setup there correlated with IF3? Is mailbox setup functioning like an acceptance filter for only configured channels to get "trapped" in IF3? I would like to know that relation. I need to be able to provide user-configurable acceptance range in the end. So I am interested in such code example and the way to configure IF3 to "update and receive the message" --  as you say, and enable interrupt.

    I tried to draft the following for CAN: 

    canREG1->IF3MSK = (uint32)0x0; // would that receive all CAN messages?
    canREG1->IF3ARB = (uint32)0x0; // would that receive all CAN messages?
    canREG1->IF3MCTL =(uint32)0x0;
    canREG1->IF3MCTL SET(10); //Receive Interrupt Enable
    /* DLC 8 bytes */
    canREG1->IF3MCTL SET(3);
    canREG1->IF3MCTL SET(2);
    canREG1->IF3MCTL SET(1);
    canREG1->IF3MCTL SET(0);
    /* IF3 Observation Register setup */
    canREG1->IF3OBS SET(1); //Arbitration
    canREG1->IF3OBS SET(3); //Data A
    canREG1->IF3OBS SET(4); //Data B
    /* IF3 Automatic update enable */
    canREG1->IF3UEy[0] SET(0); //MessageBox 1
    canREG1->IF3UEy[0] SET(1); //MessageBox 2
    canREG1->BTR = ((uint32)0U << 16U) | (((uint32)1U - 1U) << 12U) | ((((uint32)7U + (uint32)1U) - 1U) << 8U) | (((uint32)1U - 1U) << 6U) | (uint32)7U;
    /** - CAN1 Port output values */
    canREG1->TIOC = ((uint32)1U << 18U ) | ((uint32)0U << 17U ) | ((uint32)1U << 3U ) | ((uint32)0U << 2U ) | ((uint32)0U <<1U ) | ((uint32)0U );
    canREG1->RIOC = ((uint32)1U << 18U ) | ((uint32)0U << 17U ) | ((uint32)1U << 3U ) | ((uint32)0U << 2U ) | ((uint32)0U <<1U ) | ((uint32)0U );
    /* Leave configuration and initialization mode */
    canREG1->CTL &= ~(0x00000041U);

    For DMA I thought of the following: 

    dmaEnable(); 
    dmaReqAssign(0,1 );
    dmaConfigCtrlPacket ((uint32)(&(canREG1->IF3DATx[0])),&PhysicCAN.packet,64);   // ERROR dmaConfigCtrlPacket
    dmaSetCtrlPacket(DMA_CH0,g_dmaCTRLPKT);  //COMPILER ERROR g_dmaCTRLPKT


    If you have some source examples, maybe it is simpler for both of us if you can share them?

    All the best,

    Kirill

  • Hi Kirill

    Attached is a simple DMA + CAN RX example. Hope this can be taken and tweeked according to your needs.

    1423.CAN+DMA.zip

  • Hi Prathap,

    Thank you for the code. Although it does clarify some things, could I kindly ask you to give me a particular and simple example that receives any message (from external CAN bus unit) on CAN1 and automatically transfers it to some location in memory. I just need to see the mechanism transparently including the interrupt handler where I can specify the destination of DMA transfer in the manner you nicely outlined before.

    Thanks in advance,

    Kirill

  • Hi Kirill

    Please find the attached example, Where I enable IF interrupt and in the ISR I trigger a DMA. I tried to simulate your condition by dynamically changing the destination address based on the ID. Hope this helps.8030.CAN+DMA_new.zip

  • This is perfect, dear Prathap!

    Thank you very much! I am moving forward with your help!