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 RX MessageBox IRQ Question(s)

Other Parts Discussed in Thread: HALCOGEN

Hello All,

This is hopefully and easy one for the people here; I have found some similar threads but haven't seen an (exact) answer for this.

I am using the '3137 - I have enabled IRQ's for the DCAN IF - I am using IF1 for xmit and IF2 for receive; also; message_box1 is assigned to IF1 and message_box2 is assigned to IF2.  I have generated some code with Halcogen as well.  (As an aside I do have the CAN Bootloader working - but I just want to use the canTransmit and canGetData functions for this.)

I am seeing both IRQ's go off for the TX (and message_box1) and I am never seeing the RX nor message_box2 ever in the IRQ routines.  

So, can someone point out what the proper settings are (mux, IF1xxx, IF2xxx etc) to tie message_box2 with the RX IRQ (prefer High Level) and always to make sure the TX IRQ only triggers the low level IRQ?

I also want to get DMA working with this but I need to get this working first.

Thanks In Advance,
johnw

  • John, have you verified that the problem is not generating the interrupt, or could it be that you are not receiving the CAN frame? Sometimes setting up the receive ID and mask can be tricky. Particularly if you are using extended IDs, make sure the mask supports all 29 bits. Also make sure that mailbox 2 is configured in HALCoGen for the proper ID size, 11 or 29 bits.
  • Bob,

    I am not seeing the RX IRQ. I am using the Komodo DUO from Total Phase. I ported the TI CAN Bootloader code to use the DUO and that works fine.
    Yes, in my OP - I am asking for these 'tricky' register settings - the crux of my request.

    I am seeing the TX IRQ fine; the packets show up on the DUO GUI. I see the packets being transmitted from the DUO fine - but never get an RX IRQ. I get TX IRQs fine.

    So, if you have an example of how these tricky message box registers are set for RX IRQ on MSG BOX 2 on CAN1 IF2 it would be appreciated.
    It would appear that Halcogen is incorrect in how it generates the IRQ code for this - using IF1 registers instead of IF2. The canGetData function looks correct though.

    Thanks,
    John W.
  • Bob,

    It appears Halcogen will enable the identifier extensions regardless if the checkbox on the CANX General page is clicked or not:

    /* USER CODE BEGIN (3) */
    /* USER CODE END */
    /* SourceId : CAN_SourceId_001 */
    /* DesignId : CAN_DesignId_001 */
    /* Requirements : HL_SR207 */
    void canInit(void)
    {
    /* USER CODE BEGIN (4) */
    /* USER CODE END */
    /** @b Initialize @b CAN1: */

    /** - Setup control register
    * - Disable automatic wakeup on bus activity
    * - Local power down mode disabled
    * - Disable DMA request lines
    * - Enable global Interrupt Line 0 and 1
    * - Disable debug mode
    * - Release from software reset
    * - Enable/Disable parity or ECC
    * - Enable/Disable auto bus on timer
    * - Setup message completion before entering debug state
    * - Setup normal operation mode
    * - Request write access to the configuration registers
    * - Setup automatic retransmission of messages
    * - Disable error interrupts
    * - Disable status interrupts
    * - Enter initialization mode
    */
    canREG1->CTL = (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)((uint32)0x00000005U << 10U)
    | (uint32)0x00020043U;

    /** - Clear all pending error flags and reset current status */
    canREG1->ES |= 0xFFFFFFFFU;

    /** - Assign interrupt level for messages */
    canREG1->INTMUXx[0U] = (uint32)0x00000000U
    | (uint32)0x00000002U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U;

    canREG1->INTMUXx[1U] = (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U;

    /** - Setup auto bus on timer period */
    canREG1->ABOTR = (uint32)0U;

    /** - Initialize message 1
    * - Wait until IF1 is ready for use
    * - Set message mask
    * - Set message control word
    * - Set message arbitration
    * - Set IF1 control byte
    * - Set IF1 message number
    */
    /*SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found - Hardware Status check for execution sequence" */
    while ((canREG1->IF1STAT & 0x80U) ==0x80U)
    {
    } /* Wait */


    canREG1->IF1MSK = 0xC0000000U | (uint32)((uint32)((uint32)0x000007FFU & (uint32)0x000007FFU) << (uint32)18U);
    canREG1->IF1ARB = (uint32)0x80000000U | (uint32)0x00000000U | (uint32)0x20000000U | (uint32)((uint32)((uint32)1U & (uint32)0x000007FFU) << (uint32)18U);
    canREG1->IF1MCTL = 0x00001080U | (uint32)0x00000800U | (uint32)0x00000000U | (uint32)8U;
    canREG1->IF1CMD = (uint8) 0xF8U;
    canREG1->IF1NO = 1U;

    /** - Initialize message 2
    * - Wait until IF2 is ready for use
    * - Set message mask
    * - Set message control word
    * - Set message arbitration
    * - Set IF2 control byte
    * - Set IF2 message number
    */
    /*SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found - Hardware Status check for execution sequence" */
    while ((canREG1->IF2STAT & 0x80U) ==0x80U)
    {
    } /* Wait */

    canREG1->IF2MSK = 0xC0000000U | (uint32)((uint32)((uint32)0x000007FFU & (uint32)0x000007FFU) << (uint32)18U);
    canREG1->IF2ARB = (uint32)0x80000000U | (uint32)0x00000000U | (uint32)0x00000000U | (uint32)((uint32)((uint32)2U & (uint32)0x000007FFU) << (uint32)18U);
    canREG1->IF2MCTL = 0x00001080U | (uint32)0x00000400U | (uint32)0x00000000U | (uint32)8U;
    canREG1->IF2CMD = (uint8) 0xF8U;
    canREG1->IF2NO = 2U;

    /** - Setup IF1 for data transmission
    * - Wait until IF1 is ready for use
    * - Set IF1 control byte
    */
    /*SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found - Hardware Status check for execution sequence" */
    while ((canREG1->IF1STAT & 0x80U) ==0x80U)
    {
    } /* Wait */
    canREG1->IF1CMD = 0x87U;

    /** - Setup IF2 for reading data
    * - Wait until IF1 is ready for use
    * - Set IF1 control byte
    */
    /*SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found - Hardware Status check for execution sequence" */
    while ((canREG1->IF2STAT & 0x80U) ==0x80U)
    {
    } /* Wait */
    canREG1->IF2CMD = 0x17U;

    /** - Setup bit timing
    * - Setup baud rate prescaler extension
    * - Setup TSeg2
    * - Setup TSeg1
    * - Setup sample jump width
    * - Setup baud rate prescaler
    */
    canREG1->BTR = (uint32)((uint32)0U << 16U) |
    (uint32)((uint32)(2U - 1U) << 12U) |
    (uint32)((uint32)((3U + 2U) - 1U) << 8U) |
    (uint32)((uint32)(2U - 1U) << 6U) |
    (uint32)19U;


    /** - CAN1 Port output values */
    canREG1->TIOC = (uint32)((uint32)1U << 18U )
    | (uint32)((uint32)0U << 17U )
    | (uint32)((uint32)0U << 16U )
    | (uint32)((uint32)1U << 3U )
    | (uint32)((uint32)1U << 2U )
    | (uint32)((uint32)1U << 1U );

    canREG1->RIOC = (uint32)((uint32)1U << 18U )
    | (uint32)((uint32)0U << 17U )
    | (uint32)((uint32)0U << 16U )
    | (uint32)((uint32)1U << 3U )
    | (uint32)((uint32)0U << 2U )
    | (uint32)((uint32)0U <<1U );

    /** - Leave configuration and initialization mode */
    canREG1->CTL &= ~(uint32)(0x00000041U);




    /** @note This function has to be called before the driver can be used.\n
    * This function has to be executed in privileged mode.\n
    */

    /* USER CODE BEGIN (5) */
    /* USER CODE END */
    }

    Aren't all of those left shifts for the id extentions?

    Thanks,
    John W.
  • Using HALCoGen 4.05.02 here is what I gotfor standard ID:

        canREG1->IF1ARB  = (uint32)0x80000000U | (uint32)0x00000000U | (uint32)0x00000000U | (uint32)((uint32)((uint32)0x100U & (uint32)0x000007FFU) << (uint32)18U);
    

    and here is what I got for extended ID:

        canREG1->IF1ARB  = (uint32)0x80000000U | (uint32)0x40000000U | (uint32)0x00000000U | (uint32)((uint32)((uint32)0x100U & (uint32)0x1FFFFFFFU) << (uint32)0U);
    

    Does the message you are receiving use standard or extended IDs?

  • Bob,

    OK - I guess in Halcogen if can.c is already created it won't update when something has been changed from the GUI. I had to create two new projects to get what I assume are correct results.

    Can you please answer this:
    So, if you have an example of how these tricky message box registers are set for RX IRQ on MSG BOX 2 on CAN1 IF2 it would be appreciated.

    I don't think Halcogen can do that. Can you please show me the code you have generated from Halcogen that does that correctly?

    Thanks,
    John W.
  • Bob/TI,

    Can someone answer this please? In my OP I stated this should be an easy one, and here we are, days later and it remains unanswered.

    Are these bit patterns that difficult to decode?

    Can someone answer my questions in the OP? I do not have to use Halogen. I want to know the bit patterns to program IF2 on DCAN1 that produces IRQs on RX using canMessageBox2. That is the question.

    I do not have to use ext IDs either.

    Thanks,
    John W.
  • John,

    Does this help?  In other words mailbox mapping to the high or low priority (0 or 1) interrupt request of the DCAN  seems not tied to the IF1xx fields but the register mentioned below.

    The IFxx registers are just shadow registers between the CPU and the CAN mailbox RAM and are defined by the DCAN controller 'core' that we licensed -  it doesn't know it's on a TI device with a VIM and that there are different interrupt levels it can use.   So it's only got bits for the types of interrupts to enable for that particular mailbox.

    Side note - DMA for the CAN is going to be a challenge because of the location of the magic 'byte' in the IFx register set that initiates the transfer from IF registers to CAN RAM.   This byte needs to be written last, but it is at a low address compared to the other IF registers and our DMA does not support negative indexes.    We had to use a chained channel to make this final 'write' before..   Unfortunately I don't have a code example for that handy.

  • Anthony,

    Do you have any example code that shows what you just discussed and will answer my OP? Not talking about DMA; in OP I stated I would get to that (DMA) after the questions in the OP were resolved.

    I have read the page you have pointed out many times.

    Thanks,
    John W.

  • Anthony/TI, 

    In light of what you have disclosed; maybe I should be asking this way:

    Can TI let me know who they licensed the DCAN core from so I can get these answers resolved in an unambiguous way? I have spent too much time trying to figure out something that should be extremely simple; and do not want to continue down a path with no results.

    I have tried about every bit pattern I can think of and have yet to see the RX IRQ fire on MSG2.

    You can enable IE0 and IE1; and check that during an IRQ; I understand that and my code already does that. There does seem to be some caveats when some registers can be changed hence why the test and debug modes have been added to this peripheral's interface.

    When you can find that DMA code I am interested in seeing it.

    Thanks,
    John W.

  • No I have never tried changing the level in CAN.

    It really should be a simple matter of writing a value to the correct INTMUX register (12, 34, 56, 78.. ) depending on the mailboxes you are using.

    There is a switch in HalCoGen for each mailbox..

    It looks like you did move mailbox #2 already to DCAN1INT based on the HalCoGen code above...

    /** - Assign interrupt level for messages */
    canREG1->INTMUXx[0U] = (uint32)0x00000000U
    | (uint32)0x00000002U
    | (uint32)0x00000000U

    I haven't decoded the IF1,IF2 encodings to understand what all those hex #'s mean and whether you have the RXIE bit set in the mailbox that you want to be giving you the RX interrupt.

    What exactly again are you trying to do?

    You don't need to use two different IFxx register sets to configure two different mailboxes.
    The reason to have different IFx register sets has to do with concurrency - they are a shared resource so with IF1, IF2 you could have Task1, Task2 working on different mailboxes in parallel without worrying about them stepping on each other.

    As soon as you add Task 3 then you'd need to worry that Task1 starts writing to IF1, gets interrupted by Task 3 which also writes IF1 and submits it's command, now when you get back to Task1 it only 'finishes' writing to IF1 but it really needs to start from scratch.

    IF3 is dedicated to DMA for the same 'reason' ...

    Are you trying to configure two different mailboxes - and you only want the transmit interrupt from one mailbox, and only the receive interrupt from the other mailbox?

    Maybe you can send a screenshot of the settings for each mailbox so it's easier to interpret.

    Sorry for the disconnect here - just trying to pick up the ball on this...
  • John,

    The core itself comes from Bosch Semiconductor, but the version is slightly different than the DCAN spec you will find on their website.
    The support needs to come from TI.

    Ok so I think you answered - you are trying to get the RX IRQ to fire for Mailbox 2.
    That's the one you have configured at the high interrupt level...

    I'll see if I can decode the hex #'s and see if it looks like you have the RXIE bit set in the stuff you are writing to that mailbox.
  • John,

    So it looks like you configure mailbox 2 (I should probably say 'message' like the TRM but can't get myself to do it.).. to receive and generate a receive interrupt when a message comes in w. 11-bit identifier matching 002.

    Assume you are sending such a message w. the Komodo if I understand the thread. But then you never get an interrupt.

    Do you ever see INTPND12 bit 1 (value 2) set? If not then it seems like the message was not received by the core.

    If that bit is set but you do not get an interrupt then it's a problem somewhere in the configuration of the wrapper around the can controller. But I suspect it's the former .. that the message was not properly recieved. Because it looks like you do have the RXIE bit set.

    An alternative might be if somehow you overwrote that mailbox configuration elsewhere in the code.. but hopefully this is something you could rule out for us.
  • Anthony,

    I can send my complete CAN code to you - I don't have a problem with that - but I want to do that via PM since there are errors in it obviously.

    But, here's my current configuration - note I tried to use QJ's code as a starting point since I have the CAN Bootloader running with the Komodo DUO - but that runs in a tight loop and doesn't use the IRQ vectors.

    Since Bob said to use Halcogen, I went back to Halcogen for the init stuff for the DCAN modules - note I have found some issues with Halcogen on this - such as using IF1 vs. IF2 in some places - but that code hasn't even executed yet due to not having a 'real' RX IRQ come through yet:

    void canInit(void)
    {
    /* USER CODE BEGIN (4) */
    /* USER CODE END */
    /** @b Initialize @b CAN1: */

    /** - Setup control register
    * - Disable automatic wakeup on bus activity
    * - Local power down mode disabled
    * - Disable DMA request lines
    * - Enable global Interrupt Line 0 and 1
    * - Disable debug mode
    * - Release from software reset
    * - Enable/Disable parity or ECC
    * - Enable/Disable auto bus on timer
    * - Setup message completion before entering debug state
    * - Setup normal operation mode
    * - Request write access to the configuration registers
    * - Setup automatic retransmission of messages
    * - Disable error interrupts
    * - Disable status interrupts
    * - Enter initialization mode
    */
    canREG1->CTL = (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)((uint32)0x00000005U << 10U)
    | (uint32)0x00020043U;

    /** - Clear all pending error flags and reset current status */
    canREG1->ES |= 0xFFFFFFFFU;

    /** - Assign interrupt level for messages */
    canREG1->INTMUXx[0U] = (uint32)0x00000000U
    | (uint32)0x00000002U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U;

    canREG1->INTMUXx[1U] = (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U
    | (uint32)0x00000000U;

    /** - Setup auto bus on timer period */
    canREG1->ABOTR = (uint32)0U;

    /** - Initialize message 1
    * - Wait until IF1 is ready for use
    * - Set message mask
    * - Set message control word
    * - Set message arbitration
    * - Set IF1 control byte
    * - Set IF1 message number
    */
    /*SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found - Hardware Status check for execution sequence" */
    while ((canREG1->IF1STAT & 0x80U) ==0x80U)
    {
    } /* Wait */

    #if USE_11_BIT
    canREG1->IF1MSK = 0xC0000000U | (uint32)((uint32)((uint32)0x000007FFU & (uint32)0x000007FFU) << (uint32)18U);
    canREG1->IF1ARB = (uint32)0x80000000U | (uint32)0x00000000U | (uint32)0x20000000U | (uint32)((uint32)((uint32)1U & (uint32)0x000007FFU) << (uint32)18U);
    canREG1->IF1MCTL = 0x00001080U | (uint32)0x00000800U | (uint32)0x00000000U | (uint32)8U;
    canREG1->IF1CMD = (uint8) 0xF8U;
    canREG1->IF1NO = 1U;
    #else
    canREG1->IF1MSK = 0xC0000000U | (uint32)((uint32)((uint32)0x000007FFU & (uint32)0x1FFFFFFFU) << (uint32)0U);
    canREG1->IF1ARB = (uint32)0x80000000U | (uint32)0x40000000U | (uint32)0x20000000U | (uint32)((uint32)((uint32)1U & (uint32)0x1FFFFFFFU) << (uint32)0U);
    canREG1->IF1MCTL = 0x00001080U | (uint32)0x00000000U | (uint32)0x00000000U | (uint32)8U; // (uint32)0x00000800U disable TXIE
    canREG1->IF1CMD = (uint8) 0xF8U;
    canREG1->IF1NO = 1U;
    #endif
    /** - Initialize message 2
    * - Wait until IF2 is ready for use
    * - Set message mask
    * - Set message control word
    * - Set message arbitration
    * - Set IF2 control byte
    * - Set IF2 message number
    */
    /*SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found - Hardware Status check for execution sequence" */
    while ((canREG1->IF2STAT & 0x80U) ==0x80U)
    {
    } /* Wait */
    #if USE_11_BIT

    canREG1->IF2MSK = 0xC0000000U | (uint32)((uint32)((uint32)0x000007FFU & (uint32)0x000007FFU) << (uint32)18U);
    canREG1->IF2ARB = (uint32)0x80000000U | (uint32)0x00000000U | (uint32)0x00000000U | (uint32)((uint32)((uint32)2U & (uint32)0x000007FFU) << (uint32)18U);
    canREG1->IF2MCTL = 0x00001080U | (uint32)0x00000400U | (uint32)0x00000000U | (uint32)8U;
    canREG1->IF2CMD = (uint8) 0xF8U;
    canREG1->IF2NO = 2U;
    #else
    canREG1->IF2MSK = 0xC0000000U | (uint32)((uint32)((uint32)0x000007FFU & (uint32)0x1FFFFFFFU) << (uint32)0U);
    canREG1->IF2ARB = (uint32)0x80000000U | (uint32)0x40000000U | (uint32)0x00000000U | (uint32)((uint32)((uint32)2U & (uint32)0x1FFFFFFFU) << (uint32)0U);
    canREG1->IF2MCTL = 0x00001080U | (uint32)0x00000400U | (uint32)0x00000000U | (uint32)8U;
    canREG1->IF2CMD = (uint8) 0xF8U;
    canREG1->IF2NO = 2U;
    #endif
    /** - Setup IF1 for data transmission
    * - Wait until IF1 is ready for use
    * - Set IF1 control byte
    */
    /*SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found - Hardware Status check for execution sequence" */
    while ((canREG1->IF1STAT & 0x80U) ==0x80U)
    {
    } /* Wait */
    canREG1->IF1CMD = 0x87U;

    /** - Setup IF2 for reading data
    * - Wait until IF1 is ready for use
    * - Set IF1 control byte
    */
    /*SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found - Hardware Status check for execution sequence" */
    while ((canREG1->IF2STAT & 0x80U) ==0x80U)
    {
    } /* Wait */
    canREG1->IF2CMD = 0x17U;

    /** - Setup bit timing
    * - Setup baud rate prescaler extension
    * - Setup TSeg2
    * - Setup TSeg1
    * - Setup sample jump width
    * - Setup baud rate prescaler
    */
    // 500 KHz:
    canREG1->BTR = (uint32)((uint32)0U << 16U) |
    (uint32)((uint32)(2U - 1U) << 12U) |
    (uint32)((uint32)((3U + 2U) - 1U) << 8U) |
    (uint32)((uint32)(2U - 1U) << 6U) |
    (uint32)19U;

    #if 1
    /** - CAN1 Port output values */
    canREG1->TIOC = (uint32)((uint32)1U << 18U )
    | (uint32)((uint32)0U << 17U )
    | (uint32)((uint32)0U << 16U )
    | (uint32)((uint32)1U << 3U )
    | (uint32)((uint32)1U << 2U )
    | (uint32)((uint32)1U << 1U );

    canREG1->RIOC = (uint32)((uint32)1U << 18U )
    | (uint32)((uint32)0U << 17U )
    | (uint32)((uint32)0U << 16U )
    | (uint32)((uint32)1U << 3U )
    | (uint32)((uint32)0U << 2U )
    | (uint32)((uint32)0U <<1U );
    #endif
    #if 0
    canREG1->TIOC = 0x0000004CU;
    canREG1->RIOC = 0x00000048U;
    // canREG1->CTL &= ~0x00000041U;
    #endif



    /** - Leave configuration and initialization mode */
    canREG1->CTL &= ~(uint32)(0x00000041U);




    /** @note This function has to be called before the driver can be used.\n
    * This function has to be executed in privileged mode.\n
    */

    /* USER CODE BEGIN (5) */
    /* USER CODE END */
    }
    and my irq's:
    /** @fn void can1LowLevelInterrupt(void)
    * @brief CAN1 Level 1 Interrupt Handler
    */
    // #pragma CODE_STATE(can1LowLevelInterrupt, 32)
    // #pragma INTERRUPT(can1LowLevelInterrupt, IRQ)
    // DCAN1INT LINE (29)
    __irq __arm void can1LowLevelInterrupt(void)
    {
    // uint32 messageBox = canREG1->INT >> 16U;
    uint32 messageBox;

    /* USER CODE BEGIN (44) */
    /* USER CODE END */

    messageBox = canREG1->INT >> 16U;


    switch ( messageBox )
    {

    case (0):
    break;

    default:

    /** - Setup IF1 for clear pending interrupt flag */
    /*SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found - Hardware Status check for execution sequence" */
    while ((canREG1->IF1STAT & 0x80U) ==0x80U)
    {
    } /* Wait */

    canREG1->IF1CMD = 0x08U;
    canREG1->IF1NO = (uint8) messageBox;

    /*SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found - Hardware Status check for execution sequence" */
    while ((canREG1->IF1STAT & 0x80U) ==0x80U)
    {
    } /* Wait */
    canREG1->IF1CMD = 0x87U;

    canMessageNotification(canREG1, messageBox);

    break;

    }


    /* USER CODE BEGIN (45) */
    /* USER CODE END */
    }
    /** @fn void can1HighLevelInterrupt(void)
    * @brief CAN1 Level 0 Interrupt Handler
    */
    /// IRQ

    /* SourceId : CAN_SourceId_020 */
    /* DesignId : CAN_DesignId_018 */
    /* Requirements : HL_SR221, HL_SR222, HL_SR223 */
    // DCAN0INT LINE (16)
    __irq __arm void can1HighLevelInterrupt(void)
    {
    uint32 value = canREG1->INT;
    uint32 ES_value;
    uint32_t ulBytes, ulCmd;


    /* USER CODE BEGIN (41) */
    /* USER CODE END */
    g_pucCommandBuffer = ((uint8_t *)g_pulDataBuffer);
    if (value == 0x8000U)
    {
    /* Read Error and Status Register*/
    ES_value = canREG1->ES;

    /* Check for Error (PES, Boff, EWarn & EPass) captured */
    if((ES_value & 0x1E0U) != 0U)
    {
    canErrorNotification(canREG1, ES_value & 0x1E0U);
    }
    else
    {
    /* Call General Can notification incase of RxOK, TxOK, PDA, WakeupPnd Interrupt */
    canStatusChangeNotification(canREG1, ES_value & 0x618U);
    }
    }
    else
    {

    switch ( value )
    {

    case (0):
    break;

    default:

    /** - Setup IF1 for clear pending interrupt flag */
    /*SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found - Hardware Status check for execution sequence" */
    while ((canREG1->IF2STAT & 0x80U) ==0x80U)
    {
    } /* Wait */

    // canREG1->IF2CMD = 0x08U;
    /*SAFETYMCUSW 93 S MR: 6.1,6.2,10.1,10.2,10.3,10.4 <APPROVED> "LDRA Tool issue" */

    ///XXX canREG1->IF2NO = (uint8) value;

    /// if ( value == canMESSAGE_BOX2 )
    {
    canREG1->IF2CMD = 0x08U;

    canREG1->IF2NO = (uint8) value; // just using MSG2 for rcv

    /*SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found - Hardware Status check for execution sequence" */
    while ((canREG1->IF2STAT & 0x80U) ==0x80U)
    {
    } /* Wait */
    canREG1->IF2CMD = 0x17U;

    canMessageNotification(canREG1, value);
    }

    break;

    }

    // ulBytes = 0;
    // ulCmd = PacketRead(canREG1, g_pucCommandBuffer, &ulBytes);

    }

    /* USER CODE BEGIN (42) */
    /* USER CODE END */

    }
    /* can interrupt notification */
    /* Note-You need to remove canMessageNotification from notification.c to avoid redefinition */
    void canMessageNotification(canBASE_t *node, uint32 messageBox)
    {

    // #define D_COUNT 8

    memset((void *)rx_data, 0, sizeof(rx_data));

    /* node 1 - transfer request */
    #if 0
    if(node==canREG1)
    {
    tx_done=1; /* confirm transfer request */
    }
    #endif
    #if 1
    if(messageBox!=canMESSAGE_BOX1)
    {
    while(!canIsRxMessageArrived(canREG1, messageBox));
    canGetData(canREG1, messageBox, rx_ptr); /* copy to RAM */
    uart_rx1_isr(rx_ptr);
    /// rx_ptr +=8;
    }
    #endif

    /* node 1 - receive complete */
    if(messageBox==canMESSAGE_BOX2)
    {
    while(!canIsRxMessageArrived(canREG1, canMESSAGE_BOX2));
    canGetData(canREG1, canMESSAGE_BOX2, rx_ptr); /* copy to RAM */
    uart_rx1_isr(rx_ptr);
    /// rx_ptr +=8;
    }

    I am using IAR vs. CCS for this.

    Thanks,
    John W.
  • Anthony,

    I don't think I have ever seen the IRQ Pending 2 - but I will need to double check that. The Komodo should be formatting the message correctly;
    but I don't think I see that. Reason being registers not being set correctly vs. Komodo doing something wrong is more likely.

    Please note I have replied to many of your messages and haven't seen them post - this is awkward for us to work this way.

    Regards,
    John W.
  • Hello Anthony,

    I PMed you.

    Regards,
    John W.
  • Bob/Anthony/TI,

    Just curious - did the FlexRay module come from Bosch Semiconductor also?

    Regards,
    John W.
  • Anthony,

    I am monitoring 0xFFF7DCB0 now; so I will see TX/RX as soon as they are set - if they are set. This will preclude any wrapper issues. I will tell you what I find out.
    The Bosch site does have a lot of helpful info regarding CAN/FlexRay, etc.

    So, I guess the cost of the Hecules parts includes the IP for the CAN protocol? Guess that's in the fine print someplace but that's interesting.

    Regards,
    John
  • Anthony,

    I think what I found out was the InitDbg bit has to be set and I could not get the trigger from 0xFFF7DCB0(3) as I had hoped.

    Do you see anything wrong with this Komodo set-up?  1 is MSG_BOX1 from the '3137 and 2 is being transmitted by the Komodo.

    Regards,

    John

  • John,

    Regarding this post - Bob was asking if you were sending w. Extended ID from the Komodo as this is a mismatch to how the CAN module is configured. There is a checkbox for extended ID checked in the GUI but it is greyed out. Not sure what that actually signifies and if you can uncheck it as I don't have a Komodo - but do you think you might be using extended ID on the Komodo by mistake?
  • Anthony,

    I was sending the 11-bit IDs and changed to the ext id format. The ID 0x00000001 above shows that it is working in extended mode - which is OK -
    the 0x00000001 is what is being sent by the '3137.

    Since the debug and/or test registers need to be set to read the registers during a debug session - it would be helpful to me right now to know what that sequence is - if I have TX going on - I am sending a periodic packet via 0x00000001 as shown above from the '3137, and I am sending 0x00000002 via Komodo; it would be nice to have a sequence where the InitDbg is set - then break and look at registers and memory; and then resume in a nice fashion.

    I have found that trying to run and break isn't that productive since this module is really its own processor and state machine and due to the nature of CAN - if you break at the wrong time you either can't see memory or registers (they show up all zero) - or it just doesn't show the latest and correct values.

    So, is there a graceful way to break out of this; examine the registers and DCAN memory; and resume gracefully? I think part of my problem getting to a solution is that just breaking and looking at registers really isn't the correct way to do this. The processor will set the initDbg bit if I break at the right time - but it is hit and miss. I am not sure if I can poll that bit and force a breakpoint; maybe that is a way to do it - but if you guys have a recommendation that would be helpful.

    Thanks,
    John

  • Hi John,

    You can view memory without halting the CPU or the DCAN through the DAP interface. This will avoid the DCAN entering debug alltogether.

    The way that I red the InitDbg section - this is a handshake bit in case you've configured IDS as '0' where you tell the DCAN to wait for the bus to be idle before entering it's own debug state. It just tells you that the bus went idle and the CAN controller finally halted - because there is a delay between the request to halt and the actual halt.

    So InitDbg is initiated by a CPU debug event - not the other way around. And therefore I can't think of a way that you could trigger the CPU to halt based on this.

    But, I would also expect that any time you break the CPU the CAN would enter the debug state before you'd get as far as even getting the first refresh of registers & memory via CCS.

    And it looks like this only effects the DCAN mailbox memory by memory mapping it rather than making you go through the IF register set.

    So the positive - it should be easy this way to confirm if the RXIE bit of the mailbox got cleared unexpectedly.

    But also the registers including the one holding the interrupt flag should be readable in this state. Are you sure *all* the can control registers read '0' sometimes ?? That sounds like something that would be difficult to explain at the level of the CAN controller but more like a problem in the system module.

    -Anthony
  • Anthony,

    I have definitely seen all of the DCAN1 registers be zero after I break; I am using IAR and don't know if that is an issue with my set-up or not - but I have seen it.

    I PMed you some code; I hope you got it OK.

    I will just make sure the InitDbg register is set.

    Thanks,
    John
  • Anthony,

    From the tech ref:

    24.16 Debug/Suspend Mode

    The module supports the usage of an external debug unit by providing functions like pausing DCAN

    activities and making Message RAM content accessible via VBUSP interface.

    Before entering debug/suspend mode, the circuit will either wait until a started transmission or reception

    will be finished and Bus idle state is recognized, or immediately interrupt a current transmission or

    reception. This is depending on bit IDSin CAN Control Register.

    Afterwards, the DCAN enters debug/suspend mode, indicated by InitDbg flag in CAN Control Register.

    During Debug/Suspend mode, all DCAN registers can be accessed. Reading reserved bits will return ‘0’.

    Writing to reserved bits will have no effect.

    Also, the Message RAM will be memory mapped. This allows the external debug unit to read the Message

    RAM. For the memory organization, see Section 24.5.3).

    NOTE: During Debug/Suspend Mode, the Message RAM cannot be accessed via the IFx register

    sets.

    Writing to control registers in debug/suspend mode may influence the CAN state machine

    and further message handling.

    For debug support, the auto clear functionality of the following DCAN registers is disabled:

    * Error and Status Register (clear of status flags by read)

    * IF1/IF2 Command Registers (clear of DMAActive flag by r/w)

    That should say:  This is depending on bit IDS in the CAN Control Register.

    So it would appear I can set that bit to 1:

    IDS Interruption Debug Support Enable
    0 When Debug/Suspend mode is requested, DCAN will wait for a started transmission or reception to
    be completed before entering Debug/Suspend mode
    1 When Debug/Suspend mode is requested, DCAN will interrupt any transmission or reception, and
    enter Debug/Suspend mode immediately.

    And force the CAN processor to enter debug/suspend mode - correct?

    Thanks,
    John

  • Yes that's the way I read it. For some of our peripherals we have 3 flavors:
    1) continue on suspend
    2) halt at next natural stopping point (finish what you're in the middle of then stop)
    3) halt immediately on suspend (even if mid 'action' or 'transaction')

    To me IDS sounds like option 3 if you program it to be '1' but option 2 above if you leave it '0'.

    Still I don't see how the CAN bus would normally be busy for very long without an idle / stopping point - so when compared to the timing of the emulation logic scanning the JTAG over USB or some other bus ... I can't imagine a human really 'seeing' the time between debug request and the IntDbg handshake coming back to indicated the can core actually halted.

    -Anthony
  • Anthony,

    Has more to do with how the registers look in IAR to me - setting IDS to 1 is working out better for some reason here.

    Thanks,
    John
  • Thanks for pointing out the wording issue - I submitted a ticket on the doc to get that fixed - SDOCM00122301
  • HI John,

    I wound up just starting from a clean HalCoGen project;  and I've got both levels of interrupts from both DCAN1 and 2 triggering on an HDK example project.   I actually generated the project for the "PGE" part (that code runs fine on the HDK with the 337ZWT though because the DCAN pins aren't muxed..)

    I basically just expanded on the DCAN with interrrupt example that ships w. HalCoGen.

    Will send it to you and include the .out file in the debug folder ... you *should* be able to load this into your board with IAR if you do not rebuild because it's an EABI output and hopefully also the IAR debugger will handle the symbols correctly for you.

    Here is one screenshot from CCS ... in the upper right you can see how I just set breakpoints on all of the CAN interrupt handlers - I hit run several times and hit each one as expected. (Hopefully I get the resolution correct and when you click on this image it will expand so you can read it)

  • Here is the HalCoGen screenshot for CAN2.   CAN1 is setup the opposite way [receives ID1 in MSG1, transmits ID2 in msg 2].

    I think this got the config you were trying to hit...  For CAN2 to receive ID 2 in Mailbox 2, and generate a high level interrupt.  

    But this is transmitting all the data correctly and I'm getting all 4 interrupts in any case.

    When the program runs it indicates all the TX/RX was successful:

    And using the NI CAN bus monitor tool we have I see the expected # of payloads transferred (8 in each direction) on MSG ID's 1 and 2...

    (NB:  I think I probably had the extended ID turned on so I'll repeat with it off.  that's what that * indicates if I understand the manual).

    Anyway here is a ZIP of the project, hopefully you can repeat and monitor w. Komodo to see if you can recreate the same result on either your HDK or your own hardware.  Then at least it gives something to compare against.

    Note that the baud rate is 500K...

    2476.dcan2_ext.zip

    Best Regards,

    Anthony

  • Anthony,

    Thanks for that; I will give it a try and let you know. I will have to look at the code to see where the issue is.

    Regards,
    John
  • Anthony,

    Can't find any difference in the code at first pass.

    Did you try using the NI I/F to xmit packets?

    I think that would be a better test since that is what I need to check. Effectively this is a loopback test with the same PHY.
    The CAN Bootloader xmits packets to the target.

    Can you please modify the code I sent to use the NI I/F to xmit packets to the DCAN and see if you get RX IRQ's?
    Or just modify your test to use the NI I/F to xmit packets and make sure you get the RX IRQ's on your target.

    That will be the real test here. Without doing that I cannot tell anything is different in the code that I sent and this example.
    It should be fairly quick to modify the CAN Bootloader code on the target side just to hit an IRQ.

    I will try this as well with my code and the Komodo. I was going to ask for your NI xmit setup but in this case the NI was only monitoring.
    I ported the code from the NI to the Komodo so I have a translation table of sorts where I can set this up.

    Seeing all of this makes me wonder if I have some kind of sync error. I don't have all of the error IRQ's enabled but I think I will do that now.

    Thanks for all of the effort here from TI,
    John W.
  • Anthony/Bob/TI/QJ Too,

    Here's an interesting tid-bit.

    I had changed the bit rate in QJ's code to run at 500kb/s - and it didn't work - I realize there are some delays built in and those may need to be updated when changing the bit rate - but just changing that from 125 to 500 broke it with the Komodo.

    So, naturally I changed the bit rate back to 125kb/s - but I am still not seeing the RX IRQ's in the app that I have.

    Next step is to add IRQ's to QJ's bootloader and see if I see those fire. Interestingly enough QJ does have this in his code but the int vects aren't installed into the VIM:

    /** - Assign interrupt level for messages */
    node->INTMUXx[0U] = 0x00000011U;
    node->INTMUXx[1U] = 0x00000000U;

    Regards,
    John
  • Anthony,

    I modified the CAN Bootloader to use IRQ's and I'm getting RX IRQ's mapped to

    // DCAN0INT LINE (16)
    __irq __arm void can1HighLevelInterrupt(void)

    which is good news and we know there isn't an issue with the Komodo.

    It is starting to look like the IFx stuff is getting over written maybe - I need to check that.

    Regards,
    John
  • John,

    This may be a dumb question but do you have the terminations on the CAN bus  (on your own board?).

    I think the HDK has them.. the 2x 62 ohm and 4.7nf.   Have heard that CAN doesn't work well without these.

  • Hi John,

    I am not using the NI as transmitter ..  (I actually don't know how to do this -- seems like the GUI that comes with is only a bus monitor and I'm not really proficient w. LabView that I can whip something out to transmit..  I'll have to check w. the other guys on the team.).

    It's not *exactly* a simple loopback at the IO level that I've got going though.   It's really going out over the CAN bus and through two transceivers.      

    So could be something in the bus timings that is working better when it's the same HalCoGen Config on TX/RX but it's definitely not an IO loopback test like some of the other HalCoGen tests - photo of the setup is here:

    I took a quick look at what you sent but it didn't have a project file & when I saw we had a canned HalCoGen example I thought that this would be the quickest way to verify the functionality works.

    I think the next logical steps are:

       - I need to test w. 11 bit addressing mode.   Like I said yesterday I made the mistake of using the extended.    Just to rule out a hardware or driver problem specific to 11 bit mode.. 

       - if that works I will send you those files too, and also send you a scope capture of the CAN RX data pin from the working setup.

         this will give you something you can visually compare against and just make sure we've got no difference on the *input* to that CAN2 module.

         that I think would go a long way to either pointing out or ruling out board level issues.

    To mod the files you sent will take a little longer - I can work on it next week as a background task but havent' done this in an IAR environment yet and the files you sent weren't a complete project so I'd need to stitch them into a HalCoGen project..  

  • Anthony,

    Our CAN bus is terminated just fine. I think the reason the bootloader doesn't work at 500K is due to the built in delays. You could verify that there by changing just the bitrate on the bootloader host and target code. It times out on the first ping.

    You do have code right now that uses the NI Interface; it is TI's CAN Bootloader code. Should be fairly straightforward to use that.

    My next step is to use the app vs the simple GUI tool to generate xmit traffic from the Komodo.

    The sortof funny thing I keep seeing with my code is even though I disable TXIE, as soon as I enable the Komodo I get an interrupt on MSG1 even though that should be disabled. Apparently it is triggering on the ACK that is coming back from the Komodo. My code should only have MSG2 triggers. That worked on the bootloader code I modified just fine.

    Thanks,
    John

  • /cfs-file/__key/communityserver-discussions-components-files/312/7384.dcan_5F00_ex3.zip

    John,

    Anthony asked me to modify his simple loopback test and then transmit on the CAN bus from the NI USB8473. I did that and verified that I am properly receiving on DCAN1 and DCAN2. I have attached the project. I used a 16MHz crystal and a 125K CAN baud rate, though you can change those settings in HALCoGen and regenerate the code. I verified proper operation by checking that the proper data was received in the rxdata register.

  • Hello Bob,

    Are you getting the RXIE's OK? I haven't looked at the code yet; and the RXIE has been the core of this discussion.

    Receiving vs. receiving via IRQ's isn't clear from your statement; but I am assuming you mean the RXIE's are OK - just want to verify that
    with you.

    So, you guys haven't ran the TI CAN Bootloader at 500kb/s I take it?

    Thanks,
    John
  • John,

    Yes, I am getting RX interrupts. The data from the CAN frame will only be stored into the buffer with an interrupt.
    No, neither Anthony nor I have used the CAN bootloader, but Anthony has been talking with the writer of the bootloader.
  • John,

    Yes I forgot.

    QJ isn't assigned to the Hercules forum now - he's in the TM4C rotation.

    So when you want to get his attention - (I noticed you put him in the 'TO' a couple times) there is a feature
    of the forum...

    You press '@' and start typing a name and let the system find him for you... Although he is listed

    That's his e2e profile and you can check to make sure he's the right guy by e2e.ti.com/.../10143

    QJ - can you please take a look.
    I think John has some concerns that there is something timing specific (fixed delay) in the bootloader code that could be causing a problem here.
  • Anthony, ,

    I am not saying this is what's causing this to fail.

    I am just making a remark. I modified my version of the CAN Bootloader that works with the Komodo to use 500kb/s vs. 125kb/s. It fails - but works fine at 125. I *think* it is due to the built in delays. There are some delays built in since the host side waits for responses from the target.

    I did this as a test to try and figure out if I could make the Komodo help to generate the RX IRQ's on the target; and it does - but that is just test code. I tried 500kb/s but had to back it down to 125kb/s - that is OK for this for now.

    I want to make sure no on here thinks I am saying something like this is breaking the CAN code and why the RXIE's aren't happening - that is not what I am saying.

    I just suggested that you may want to try the bootloader on your end; change the bitrate to 500000 Hz and see if it'll still work - just as a data point - that's all. More than likely a tweak of the delays fixes that.

    Thanks,
    John W.
  • Hi John,

    So just to be clear:
    1) you are able to get the receive interrupt with Komodo as the sender in a test environment [like the HalCoGen demo]
    2) you can get the receive interrupt with Komodo as the sender with the bootloader code at 125K
    3) the only problem is Komodo sender, bootloader, 500K and with this combination there is no receive interrupt?

    Is that a correct summary?

    Thanks and Best Regards,
    Anthony
  • Anthony,

    OK -
    1 - I can get the RXIE to fire properly on MSG2 using the Komodo and the CAN Bootloader with the bootloader code modified for IRQs.
    (as an 'aside' I had to run this at 125k vs. 500k due to what I think are built in delays designed for 125k.)
    This is the CAN Bootloader code supplied by TI - 'ported' to the Komodo my me; and using it on the HDK and PGE targets.

    2 - Yes - but I think I answered that in #1. To answer your #1 - when I do this I seem to be getting an interrupt on the ACK packet to the xmit on MSG1 and don't see the RX IRQ on MSG2 - but I think I may know what's going on now and want to see if I can fix that.

    3 - No - I can't get the Komodo and the CAN Bootloader code to work just changing the bitrate from 125000 Hz to 500000 Hz - it hangs on the first ping attempt. That's why I am saying there's probably just an issue with the built in delays - it should work. The host code has some delays built in - I am just taking a swag at that since I haven't drilled down into it too much yet. Why I asked you guys to give it a try there since just changing the bitrate is a quick change.

    Thanks,
    John
  • Thanks John,

    Ok so we've been really chasing the wrong problem - #1&2 in a sense.

    Really - the issue now is down to the bootloader code itself. No doubt about the hardware, the DCAN controller, or anything like that.

    Probably need to get help in that case.
  • Anthony,

    Until I resolve 'my' #2 above - this is still an issue for me. The bootloader really isn't the issue - just something that has been working fine at 125kb/s that I used for test code to help flush things out.

    But, at the same time; I think we should resolve why 500kb/s doesn't work; or at least I need to resolve that if you guys find out it's OK on your end.

    Thanks,
    John
  • Anthony,

    Sent you a PM - wanted to mention it here JIC you don't see it.

    I'll be back here within a day or so to update this thread - but my target/app is looking pretty good and I think we'll be able to close this as solved/resolved in a day or so.

    Again to Bob and Anthony, thanks for the time and help on this - it was very good and beneficial as to a positive outcome.

    Best Regards,
    John W.