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.

HalCoGen: RTI and Enable via VIC vs. Enable Vectored Floating Point

Other Parts Discussed in Thread: HALCOGEN, UNIFLASH

RM48L952ZWT | R4-MPU-PMU | Cortex-R4 | General Configuration:


Is the text "Enable IRQ Handling via VIC Controller" and "Enable Vectored Floating Point Unit" reversed in HalCoGen, as RTI only works with Vectored floating point. Floating Point is math, not interrupts.

  • Sarah,

    I don't think so - if you look at the xml file
    C:\ti\Hercules\HALCoGen\v04.05.02\drivers\RM48L952ZWT\RM48L952ZWT.xml
    the checkboxes and their variables seem associated correctly... lines 2501 through 2508 in HalCoGen v4.05.02

    Does your GUI look funny? graphics not lined up with controls? There are issues is you are not set to display at 100%
    the program is not able to handle different DPI settings... so maybe if things look funny you are just checking the wrong box because text and
    checkbox are not aligned?

    Otherwise - you can see the variables set by these checkboxes, "CORE_IRQ_VIC_ENABLE" and "CORE_VFP_ENABLE"

    If you search through the folder C:\ti\Hercules\HALCoGen\v04.05.02\drivers\TMS570LS3137ZWT\RTI570v000 you could look for any hits on these variables to see what they affect. I did using Notepad++ and dont' get any hits.

    So if something is going wrong here I think it is likely 'indirect' and might be good to back up and figure out what isn't working properly then trace back from there.

    Last note - if you are using a different HalCoGen version please repeat the checks I did above.

    Thanks and Best Regards,
    Anthony
  • The reason for the post was that the EE and I could only get the timer function to work if we had "Enable Vectored Floating Point Unit" checked, as you see in the screenshot. He thought that "Enable IRQ Handling via VIC Controller" would be more appropriate for us and to remove the check from "Enable Vectored Floating Point Unit", as we do not need math capabilities. When we made that change, we stopped receiving timer interrupts (RTI). The Blinky example failed to mention the "Vectored Floating Point Unit" requirement, hence our puzzlement. Can you shed some light as to the connection between floating point units and timer interrupts?

  • Sarah,

    Should not be a direct relationship.

    You can build ok with out the VFP but it just runs incorrectly?

    Have you tried rebuilding all your object files?
  • 
    

    We both tried several times and 100%, at least yesterday, interrupts fired only with VFP checked. the screenshot shows the configuration of those 2 check boxes, which allowed interrupts. Deviation caused interrupts to cease.

    Of course, I saved the project and generated the code again after making GUI configuration changes.

    The only reason we stumbled into this issue was that I Saturday evening, we tried to reorder the VIM RAM priorities using

    void doInitVim()
    {
    	// Initailize: VIM Table
    	vimInit();
    //	vimChannelMap(9, 2, &gioHighLevelInterrupt);  // GPIOA Interrupts (BUSOK), see 1.3.2 (GIOA[0] BUSOK), 1.4.3, 1.8.4.1 in interface specification, and GIO tab bit 0
    //	vimChannelMap(23, 3, &gioLowLevelInterrupt);  // GPIOA Interrupts (ACOK), see 1.3.3 (GIOA[1] ACOK), 1.4.3, 1.8.4.2 in interface specification, and GIO tab bit 1
    //	vimChannelMap(2, 4, &rtiCompare0Interrupt);   // Timer: Watchdog
    //	vimChannelMap(64, 5, &sciHighLevelInterrupt); // COM1 RX: SCI Level 0, which makes it Interrupt Request 64
    //	vimChannelMap(13, 6, &linHighLevelInterrupt); // COM2 RX: LIN/SCI Level 0, which makes it Interrupt Request 13
    //	vimChannelMap(74, 7, &sciLowLevelInterrupt);  // COM1 TX: SCI Level 1, which makes it Interrupt Request 74
    //	vimChannelMap(27, 8, &linLowLevelInterrupt);  // COM2 TX: LIN/SCI Level 1, which makes it Interrupt Request 27
    //	vimChannelMap(3, 9, &rtiCompare1Interrupt);   // Timer: Combined
    }

    NOTE: We do NOT use the HDK board, but rather our own board.

    Taking out the comments caused the board to not work. We wanted GPIOA[0] to be the highest priority interrupt, followed by GPIOA[1], and then the watchdog, and everything else, as you see. The EE thought that checking the "Enable IRQ for VIC..." would solve the problem. He then said that we do not use math, so we should take out the floating point stuff. The VIM stuff still did not work, so we adjourned for the evening. Yesterday morning, nothing worked. I mean not one thing. I got upset, as we had the watchdog kicking, interrupts, and serial communication working just fine. It took a while, but we figured out that removing the floating point unit caused all our grief. He then asked me to contact TI and have them explain to us/him what he does not understand and why HalCoGen/Hercules requires the floating point unit for functionality to work. In addition, the blinky example should have called out this very important requirement.

  • Sarah,

    Your checkboxes look fine. it doesn't look like the DPI issue where the checkboxes and text do not align..

    Do you have the issue if you leave the interrupt priority in the default ordering?

    The reason I ask is that if you change the interrupt priority (channel mapping) you probably also need to change the VIM RAM
    to align with the new proirity scheme... as the VIM RAM entries I believe are *after* the mapping.

    To debug this there are flags in the RTI and in the VIM that will tell you the status of the interrupt pending ..
    Also I would check to make sure that interrupts are enabled in the CPSR register (the I bit.)

    Don't expect a direct link between RTI and VFP here so it has to be something indirect.. and for that I'd start with the basics like checking the status flags and enables.

    Thanks and Best Regards,
    Anthony
  • Hi Anthony, as you can see, I commented out the VIM RAM channel mapping, as taking the comments out caused things to not work. That being said, disabling the floating point unit also caused things to not work.

    This ticket is really about 2 issues, sorry. The original issue, the floating point unit requirement for interrupts, especially RTI interrupts, was for your understanding, while the cause to even ask this question was because we tried to change the interrupt priority. The board will have very little time if we lose either AC or Bus power, so processing that task are the highest priority tasks followed by petting the watchdog, receiving serial port communication, sending serial port communication, and doing everything else.

    I do not follow what I must do besides the vimChannelMap stuff. With respect to the VIM priority issue, here is what I have so far:

    and as you already saw, here is the code:

    /* USER CODE END */
    void doInitVim();
    
    void main(void)
    {
    /* USER CODE BEGIN (3) */
    	// Initialize: GIO
    	gioInit();
    
    	doInitRti();
    	doInitSci();
    	doInitVim();
    	doInitAcbusok();
    	doInitAdc();
    
    	// Enable interrupts
        //   - Clear I flag in CPS register
    	//   - Note: This is usually done by the OS or in an svc dispatcher
    	_enable_IRQ();
    ...
    }
    
    void doInitVim()
    {
    	// Initailize: VIM Table
    	vimInit();
    //	vimChannelMap(9, 2, &gioHighLevelInterrupt);  // GPIOA Interrupts (BUSOK), see 1.3.2 (GIOA[0] BUSOK), 1.4.3, 1.8.4.1 in interface specification, and GIO tab bit 0
    //	vimChannelMap(23, 3, &gioLowLevelInterrupt);  // GPIOA Interrupts (ACOK), see 1.3.3 (GIOA[1] ACOK), 1.4.3, 1.8.4.2 in interface specification, and GIO tab bit 1
    //	vimChannelMap(2, 4, &rtiCompare0Interrupt);   // Timer: Watchdog
    //	vimChannelMap(64, 5, &sciHighLevelInterrupt); // COM1 RX: SCI Level 0, which makes it Interrupt Request 64
    //	vimChannelMap(13, 6, &linHighLevelInterrupt); // COM2 RX: LIN/SCI Level 0, which makes it Interrupt Request 13
    //	vimChannelMap(74, 7, &sciLowLevelInterrupt);  // COM1 TX: SCI Level 1, which makes it Interrupt Request 74
    //	vimChannelMap(27, 8, &linLowLevelInterrupt);  // COM2 TX: LIN/SCI Level 1, which makes it Interrupt Request 27
    //	vimChannelMap(3, 9, &rtiCompare1Interrupt);   // Timer: Combined
    }

    Assuming that I were to remove the comments, thereby activating the channel remapping, what else do I need to do?

    There has to be a relationship between RTI and VFP, as I can go from working to not working, and I/we have, simply by checking and unchecking the VFP blox. Yes, I save the project, generate the code, build using CCS, and use UniFlash to upload the new code. When you said checking the basics like status flags and enables, what did you have in mind? I presume you mean with VFP disabled, as having VFP enabled causes everything to work and disabling VFP makes a door stop out of our board, not that the board would make a good door stop,

  • Sarah,

    We should probably leave the VFP to the side for the moment - and focus on the VIM.
    I think the VFP issue is an indirect problem .. might be a stack push/pop issue or something else unexpected.
    I do not see any direct linkage in the templates. We should come back to this question though.

    I see in the code that vimChannelMap function would theoretically take care of both the channel mapping and also the VIM RAM entry for the channel. But it doesn't move the 'enable' along with it so that could be an issue.

    Also - there are some potential issues with the channel mapping.

    First, when you move the channel say like this;

    vimChannelMap(9, 2, &gioHighLevelInterrupt);

    This makes the GIO interrupt on level 2 but it leaves the GIO interrupting on level 9 as well.
    And the RTI compare interrupt needs to go somewhere.

    In this case I see you've got it covered:
    vimChannelMap(3, 9, &rtiCompare1Interrupt);

    But for:
    vimChannelMap(23, 3, &gioLowLevelInterrupt);

    what's going on on channel 23 now and where did rtiCompare1Interrupt get relocated to?



    Second, of course the enable needs to be moved along with the mapping.

    So the assuming you have just swapped the GIO high and RTI and both interrupts were enabled, everything should be fine but not so necessarily for GIO low..

    For some reason I am unable to move the CHANMAP in the GUI of HalCoGen.
    It would be nicer if you could make all the changes through the GUI to avoid having to make the explicit calls that you are making - so I will ask why these boxes are not able to be edited.


    Some other things - if vimInit() is called twice that may be an issue.
    I don't know for sure but I think this is going to be called in the startup code before main.
    Some of the HalCoGen functions that are for init() do not like being called a second time.
    I think that's worth investigation.

    And I would move your vim initialization changes to *before* any of the peripheral initializations like RTI and SCI. That way these are not firing off interrupts *before* the VIM is reconfigured.

    Otherwise I would start by asking these questions:
    a) is the RTI interrupt flag being set?
    b) can you see it's flag reflected in the VIM interrupt pending register in the correct location?
    c) is that channel in the VIM enabled (what does the interrupt mask say).

    ...

    -Anthony
  • Also,

    Make sure you check rtiCompare0Interrupt to see if it is executing. It *should* always just call rtiNotification(rtiNOTIFICATION_COMPARE0);
    but if you only break in rtiNotification then there might be something wrong.

    Best Regards,
    Anthony
  • Hi Anthony,

    Thank you for the detailed response.

    To address the comment of where the displaced interrupt goes, here a modified channel mapping. I propose moving the displaced channel mapping to interrupts that currently have phantom mapping. The VIM RAM tab shows quite a few of them and I only need 5.

    void main(void)
    {
    /* USER CODE BEGIN (3) */
    	// Initialize: GIO
    	doInitVim();		// Call first, so that other peripherals do not fire interrupts *before* the VIM is reconfigured. 
    	gioInit();			// Initialize: GIO
    	doInitRti();		// Initialize: RTI (Real Time Interrupt, timer)
    	doInitSci();		// Initialize: SCI (Serial Communicaton Interface)
    	doInitAcbusok();	// Initialize: ACOK/BUSOK lines
    	doInitAdc();		// Initialize: AD/C
    
    	// Enable interrupts
    	_enable_IRQ();
    
    	// Start RTI Counter Block 0.
    	rtiStartCounter(rtiCOUNTER_BLOCK0);
    
    	while(1);
    }
    
    void doInitVim()
    {
    	// Initailize: VIM Table
    	vimInit();
    // 18 originally phantomInterrupt
    // 21 originally phantomInterrupt
    // 22 originally phantomInterrupt
    // 25 originally phantomInterrupt
    // 31 originally phantomInterrupt
    //  vimChannelMap(9, 2, &gioHighLevelInterrupt);  // GPIOA Interrupts (BUSOK), see 1.3.2 (GIOA[0] BUSOK), 1.4.3, 1.8.4.1 in interface specification, and GIO tab bit 0
    //  vimChannelMap(23, 3, &gioLowLevelInterrupt);  // GPIOA Interrupts (ACOK), see 1.3.3 (GIOA[1] ACOK), 1.4.3, 1.8.4.2 in interface specification, and GIO tab bit 1
    //  vimChannelMap(2, 4, &rtiCompare0Interrupt);   // Timer: Watchdog
    //  vimChannelMap(64, 5, &sciHighLevelInterrupt); // COM1 RX: SCI Level 0, which makes it Interrupt Request 64
    //  vimChannelMap(13, 6, &linHighLevelInterrupt); // COM2 RX: LIN/SCI Level 0, which makes it Interrupt Request 13
    //  vimChannelMap(74, 7, &sciLowLevelInterrupt);  // COM1 TX: SCI Level 1, which makes it Interrupt Request 74
    //  vimChannelMap(27, 8, &linLowLevelInterrupt);  // COM2 TX: LIN/SCI Level 1, which makes it Interrupt Request 27
    //  vimChannelMap(3, 9, &rtiCompare1Interrupt);   // Timer: Combined
    //  vimChannelMap(4, 18, &rtiCompare2Interrupt);   // RTI Compare 2
    //  vimChannelMap(5, 21, &rtiCompare3Interrupt);   // RTI Compare 3
    //  vimChannelMap(6, 22, &rtiOverflow0Interrupt);  // RTI Overflow 0
    //  vimChannelMap(7, 25, &rtiOverflow1Interrupt);  // RTI Overflow 1
    //  vimChannelMap(8, 31, &rtiTimebaseInterrupt);   // RTI Timebase
    }

    So in one case:

    9 goes to 2, 2 goes to 4, and 4 went to 18, which was a phantom interrupt. I believe that I took care of all displaced interrupts. Does that take care of the displaced interrupt issue?

    You said:

    First, when you move the channel say like this;

    vimChannelMap(9, 2, &gioHighLevelInterrupt);

    This makes the GIO interrupt on level 2 but it leaves the GIO interrupting on level 9 as well.

    The command above places GIO High at level 2, as you said, but why does this still leave GIO High firing at level 9 as well? The other command that I have

    // vimChannelMap(3, 9, &rtiCompare1Interrupt); // Timer: Combined

    causes rtiCompare1Interrupt to fire at level 9. Does that mean that after the execution of these two commands that level 9 has both GIO and RTI Compare 1, namely that software gets interrupted twice? Does that not defeat the purpose of remapping interrupts?

    You said:

    Second, of course the enable needs to be moved along with the mapping. 

    You did not say what the updated enable looks like.

    You you elaborate the statement. I do not know what specifically you did or what happened.

    For some reason I am unable to move the CHANMAP in the GUI of HalCoGen

    You said:

    It would be nicer if you could make all the changes through the GUI to avoid having to make the explicit calls that you are making - so I will ask why these boxes are not able to be edited.

    I would be happy to make the priority changes through the GUI. How?

    If I understand your comment, you are asking me why I cannot simply do the following in the VIM RAM tab.

    0x0000000C:02 [gioHighLevelInterrupt]

    From my understanding that merely changes the ISR handler name, not the priority. If I were to do the following:

    0x0000000C:02 [ohMightyCarson]

    RTI Compare 0 Interrupt would still be at level 2, just the name of the interrupt handler would be ohMightyCarson rather than rtiCompare0Interrupt. I am not sure why anyone would want to do that, but based on what I understand that is what would happen. My interrupt handler would be ohMightyCarson (think The Tonight Show with Johnny Carson from years ago) and that would still call rtiNotification.

    You said:

    Some other things - if vimInit() is called twice that may be an issue. 

    What functions get called before main()?

    I am calling emif_ASYNC1Init() and emif_ASYNC2Init() in my main() code. Do these initialization functions get called before main too?

    Where in the help file does vimInit() state that HalCoGen calls the function prior to main, so that engineers should not? Why have the function exposed in the help file, if already called?

    You said:

    Some of the HalCoGen functions that are for init() do not like being called a second time.  I think that's worth investigation.

    Which ones?

    And I would move your vim initialization changes to *before* any of the peripheral initializations like RTI and SCI. That way these are not firing off interrupts *before* the VIM is reconfigured. 

    Done.

  • Hi Sarah,


    Sadly - I get the Johnny Carson reference too well ;0  

    The command above places GIO High at level 2, as you said, but why does this still leave GIO High firing at level 9 as well? The other command that I have

    // vimChannelMap(3, 9, &rtiCompare1Interrupt); // Timer: Combined

    causes rtiCompare1Interrupt to fire at level 9. Does that mean that after the execution of these two commands that level 9 has both GIO and RTI Compare 1, namely that software gets interrupted twice? Does that not defeat the purpose of remapping interrupts?

    The channel mapping is basically a mux in front of each channel that selects any of the inputs.    So it maps by answering the question:  which input goes to channel N.  

    Now it defaults that the answer is Input N.

    So by default  channel 2 takes input 2,  and channel 9 takes input 9.


    The first function call:


    vimChannelMap(9, 2, &gioHighLevelInterrupt);


    changes channel 2 to take input 9 ...  but it doesn't change channel 9 which also takes input 9.

    So in this case you now have the GIO high level interrupt setup to trigger two different VIM channels 2 & 9.

    And the rti Compare0 interrupt goes nowhere.

    That gets corrected with:

    vimChannelMap(3, 9, &rtiCompare1Interrupt);

    But I didn't notice a similar 'correction' for other channels.

    If you added them then that's fine.


    BTW The 'phantom' vector doesn't mean that there is no interrupt from a peripheral it means that you haven't enabled the interrupt in your HalCoGen configuration.   If you enable the interrupt later through code you would also need to replace the phantom vector (actually before enabling the interrupt you would do this..)

    If I understand your comment, you are asking me why I cannot simply do the following in the VIM RAM tab.

    0x0000000C:02 [gioHighLevelInterrupt]

    From my understanding that merely changes the ISR handler name, not the priority. If I were to do the following:

    0x0000000C:02 [ohMightyCarson]

    RTI Compare 0 Interrupt would still be at level 2, just the name of the interrupt handler would be ohMightyCarson rather than rtiCompare0Interrupt. I am not sure why anyone would want to do that, but based on what I understand that is what would happen. My interrupt handler would be ohMightyCarson (think The Tonight Show with Johnny Carson from years ago) and that would still call rtiNotification.

    This is correct.    What I meant was just that the function names needed to be swapped when the channels were swapped..  I think you did this.

    You said:

    It would be nicer if you could make all the changes through the GUI to avoid having to make the explicit calls that you are making - so I will ask why these boxes are not able to be edited.

    I would be happy to make the priority changes through the GUI. How?

    Sorry what I meant by this wasn't so much specifically 'you' but anyone.   I tried to change the channel mapping through the GUI but the boxes are stuck.

    It's difficult to configure something like VIM if half the configuration is graphical and the other half is through API functions.

    Especially with VIM where the checkbox to enable the interrupt will 'move' if you later re-order the channels.

    This is what I was referring to in terms of a GUI problem:


    It would be nice to edit the column (1) because then the enables to the right of the number would at least 'track.

    What I mean by this is that (2) is the enable for channel 2 which is RTI Compare 0 now but when you reconfigure it as GIO,

    the GIO will be enabled.   If you moved the RTI to a channel that wasn't checked.. the RTI would no longer be enabled.
    Which might explain why you are not getting RTI interrupts.

    it is hard to visualize this when you cannot configure the channel mapping through the GUI.

    Where in the help file does vimInit() state that HalCoGen calls the function prior to main, so that engineers should not? Why have the function exposed in the help file, if already called?

    It's not really documented but there isn't a real 'user doc' for HalCoGen other than the Doxygen generated HTML files.
    You have to look at 'sys_startup.c' to see what is done before calling main.

    I can see vim is initialized prior to main  in sys_startup.c:

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

        /* Initialize VIM table */
        vimInit();    

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

        /* Configure system response to error conditions signaled to the ESM group1 */
        /* This function can be configured from the ESM tab of HALCoGen */
        esmInit();
        /* initialize copy table */
        __TI_auto_init();
    /* USER CODE BEGIN (75) */
    /* USER CODE END */
        
        /* call the application */
    /*SAFETYMCUSW 296 S MR:8.6 <APPROVED> "Startup code(library functions at block scope)" */
    /*SAFETYMCUSW 326 S MR:8.2 <APPROVED> "Startup code(Declaration for main in library)" */
    /*SAFETYMCUSW 60 D MR:8.8 <APPROVED> "Startup code(Declaration for main in library;Only doing an extern for the same)" */
        main();

    /* USER CODE BEGIN (76) */
    /* USER CODE END */
    /*SAFETYMCUSW 122 S MR:20.11 <APPROVED> "Startup code(exit and abort need to be present)" */
        exit(0);

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

    You said:

    Some of the HalCoGen functions that are for init() do not like being called a second time.  I think that's worth investigation.

    Which ones?

    This is just my observation.  We had trouble in a MATLAB PIL package calling sciInit() a second time in the stream 'close()' function.
    And I know that not all the code is not written to assume the peripheral is in an unknown state and to take it into a known state before
     init().   Most of the code expects the peripheral is just out of reset.   This is my own observation - so when looking at your code it is one thing that I would think is worth trying.

    I am calling emif_ASYNC1Init() and emif_ASYNC2Init() in my main() code. Do these initialization functions get called before main too?

    No,  they are not called in sys_startup.c.    The reset vector is in sys_startup.c  (function _c_int00()) 

    Generally 'system' peripherals like VIM, ESM, MPU are initialized before main and everything else (especially with "IO") is up to the application to initialize.

    Will post another entry with suggestions.

  • I think the next step would be to get screenshots of the registers of VIM and RTI as well as the value in the CPU CPSR when the device is running the code that you expect should be generating RTI interrupts but is not.

    If you send screenshots of VIM and RTI like below and tell us the value in CPSR we should be able to figure out what is going on.

    For VIM it's a big screenshot - if you cannot capture the whole thing at once please capture it in two pieces.  We need to see at least the
     IrqIVec down to the first few ChanCtrl registers.

    This is what I'd be looking for in screenshots:

    And remember the device needs to be in the state where you have run enough code to 'expect' the RTI interrupt but where you are not seeing it.

    Everything we need to figure this out should be in these two screenshots  and in the value of CPSR.

    BTW in case you are still ramping up on ARM,   CPSR is a CPU Core register where the mode and global interrupt enable bits are kept:

  • Hi Anthony, thank you for the detailed response.

    Interrupt channel priorities to change:

    	// Initailize: VIM Table
    	// Channel 31 originally 18 phantomInterrupt
    	// Channel 31 originally 21 phantomInterrupt
    	// Channel 31 originally 22 phantomInterrupt
    	// Channel 31 originally 25 phantomInterrupt
    	// Channel 31 originally phantomInterrupt
    	vimChannelMap(9, 2, &gioHighLevelInterrupt);  // GPIOA Interrupts (BUSOK), see 1.3.2 (GIOA[0] BUSOK), 1.4.3, 1.8.4.1 in interface specification, and GIO tab bit 0
    	vimChannelMap(23, 3, &gioLowLevelInterrupt);  // GPIOA Interrupts (ACOK), see 1.3.3 (GIOA[1] ACOK), 1.4.3, 1.8.4.2 in interface specification, and GIO tab bit 1
    	vimChannelMap(2, 4, &rtiCompare0Interrupt);   // Timer: Watchdog
    	vimChannelMap(64, 5, &sciHighLevelInterrupt); // COM1 RX: SCI Level 0, which makes it Interrupt Request 64
    	vimChannelMap(13, 6, &linHighLevelInterrupt); // COM2 RX: LIN/SCI Level 0, which makes it Interrupt Request 13
    	vimChannelMap(74, 7, &sciLowLevelInterrupt);  // COM1 TX: SCI Level 1, which makes it Interrupt Request 74
    	vimChannelMap(27, 8, &linLowLevelInterrupt);  // COM2 TX: LIN/SCI Level 1, which makes it Interrupt Request 27
    	vimChannelMap(3, 9, &rtiCompare1Interrupt);   // Timer: Combined
    	vimChannelMap(4, 18, &rtiCompare2Interrupt);   // For displaced RTI Compare 2
    	vimChannelMap(5, 21, &rtiCompare3Interrupt);   // For displaced RTI Compare 3
    	vimChannelMap(6, 22, &rtiOverflow0Interrupt);  // For displaced RTI Overflow 0
    	vimChannelMap(7, 25, &rtiOverflow1Interrupt);  // For displaced RTI Overflow 1
    	vimChannelMap(8, 31, &rtiTimebaseInterrupt);   // For displaced RTI Timebase

    I would need to modify the RM48L952ZWT | VIM Channel 0-31 tab as follows:

    Top Half:

    Bottom Half:

    I would then need to save the project and generate the code. Sadly, this action results in the following error:

    <Linking>
    
     undefined             first referenced     
      symbol                   in file          
     ---------             ----------------     
     rtiCompare2Interrupt  ./source/sys_main.obj
     rtiCompare3Interrupt  ./source/sys_main.obj
     rtiOverflow0Interrupt ./source/sys_main.obj
     rtiOverflow1Interrupt ./source/sys_main.obj
     rtiTimebaseInterrupt  ./source/sys_main.obj
    
    error #10234-D: unresolved symbols remain
    error #10010: errors encountered during linking; "CCMv3.out" not built
    
    >> Compilation failure
    gmake: *** [CCMv3.out] Error 1
    gmake: Target `all' not remade because of errors.

    Aside from the compile bugs, I have the following issues:

    1. Very not obvious and does not work, hence the errors
    2. What you propose here is that another module generates the code for the interrupt. In the first case, where 'GIO High' (9) remaps to 'RTI Compare 0' (2), the RTI notificaion module, rti.c, would call the notification handler for `GIO High`.
    3. If I understand what you say properly, remapping just causes grief and is dangerous
    4. Poor coding practice
    5. GUI should equal code

    Do I understand what you want? If so, why do I get linker errors?

    Also, nobody has felt the need to respond on my inability to debug using CCS:

    e2e.ti.com/support/development_tools/code_composer_studio/f/81/t/515332

  • Hi Sarah,

    I don't think this is going to be fixed quickly - at least via HalCoGen. Seems like nobody has tried the channel mapping before because it doesn't work in the GUI.

    1st:
    Is it possible for you to send the project (at least HalCoGen folder with .hcg, .dil files?) That way we can analyze what is going on. We need to analyze the issue and get the appropriate defect reports filed so that the development team has a clear idea what to fix.

    Ok - now backtracking -

    2nd:
    If you would please send those register dumps of the RTI and VIM - we can at least see where the RTI interrupt is being 'blocked' or rather not being propogated further. (Previous post0.

    3rd:
    You are not really getting a compiler error but a linker error. This error occurs when there is an extern reference in one file that isn't satisfied at link time (sure you probably know this given your experience level so apologize if obvious...). So this is really IMO an issue with the code generation from HalCoGen.

    Not sure why this is happening - it's what we'll want to analyze when you send the .HCG / .DIL files.

    But I know that HalCoGen tries not to emit code for functions you are not using. For example it may not generate the ISR code if it sees interrupts disabled. Otherwise if it generated an ISR handler for every interrupt channel that is disabled - even 'blinky' would be pretty huge.

    If I had to guess - it's trying to be 'too smart' here and it's getting outsmarted by what you are doing.
    We just need to sort through that and get it fixed.

    4th:
    Sorry about your CCS forum post. That's the right place and the forums are monitored & we get scored on response % and response time. Not sure why this was missed.

    If I had to guess looking at your post - maybe you did a check-in / check-out of a version control system that messed with the .xml file (maybe doing dos->unix CR/LF changes or something?) Just a wild guess. If you attach the .ccxml file that it's complaining about I am sure we could check it out to see what the actual issue is.

    Thanks and Best Regards
    Anthony
  • Also - if you think that your code with the 'VIC/VFP' stopping RTI would run and also fail on one of our HDKs .. and it's possible to send the code for that too - that would be great. I am pretty sure (>%99) that we'd see the problem just in the register dumps of VIM & RTI but if you don't have the time to get these dumps and the project is portable enough to run on an HDK -- that works too.

    If you can send but cannot post on the public forum let me know and I will setup a 'box' folder for you. Or you can send it attached to a direct email through this forum. (click my name / picture and send me a message directly).
  • Hi Anthony,

    1. I do not know what a box folder is, but as long as it is private/secure.

    2. I corrected myself at the end and mentioned linker errors, 3rd line from the end. Build errors would have been more lawyerly, or since I am still fuming at my speeding ticket, policely.

    3. I can send the HalCoGen files, but I already undid the earlier changes, as I received the build errors. You can simply redo things. I did not do anything special, though the correct answer is that TI does not support channel mapping, if what you say is correct that one has to monkey with the GUI to make things ridiculously confusing.
  • Hi Sarah,

    Ok let me setup a folder. BOX strictly speaking is not for NDA material so if you feel like this thing you are sending me is that proprietary then we should do something else. But it is basically a 'cloud' storage solution and I can setup a folder with a password that I invite you to - so only you and I can see it. And then we can delete the contents after they are transferred .. which is lot better than having them sit as an attachment perpetually to a forum post.

    -Anthony
  • Hi Sarah,

    Ok I think we have the answer for 'Part I' regarding why the VFP checkbox is causing your RTI to not interrupt.

    The RTI *is* actually interrupting.   And the actual compare interrupt handler rtiCompare0Interrupt() is being hit.

    But the notification is not called because you get stuck with an undefined instruction exception.

    The reason for this is that the rtiCompare0Interrupt is still compiled with the --float_support =VFPV3D16 which causes the compiler to

    save the floating point registers as required by the EABI when it compiles a function that is an IRQ interrupt handler.

    The compiler can't know that you flipped the switch in HalCoGen to not enable the VFP  [might be some way to make this happen but I am not smart enough - I can ask.. ]

    Anyway - it does what it thinks is correct which is to save and restore the critical FPU registers - see blue arrows for 'save' of the FPU regs.

    But the way that the Cortex R works - the VFP is a coprocessor and is optional.   Originally all the coprocessor instructions were designed to generate undefined instruction exceptions so that you could write an optimized 'floating point emulator' that would read the instruction,  emulate it with fixed point math, and return from the exception.   So that you could have the same binary run on machines with and without the floating point coprocessor.   I guess this goes back to the era of '386 ;) but anyway now the compiler will just emit calls to it's floating point functions instead of trying to go through this floating point emulator path..   that is what the '--float_support=vfplib' switch does.

    So you get the interrupt,  go to the rtiCompare0Interrupt() function, but on the 2nd instruction 'vrms' you hit the undefined exception where there is right now just a 'B Self' loop.

    There's an easy fix and a more complex fix for this...

    Easy fixes are:

      a)  Enable the VFP in HalCoGen & leave global compiler settings the same.

      b)  Disable the VFP and change the global compiler settings:

                -change to:  --float_support=vfplib

                - link with F021_API_CortexR4_LE.lib  instead of the VFPV3D16 version.

                - link with the fixed point version of the runtime library as well.

                    for this last step in b .. the library doesn't normally 'exist' but if you change the name of the runtime

                    library to  'libc.a'  then CCS looks at your global project settings,  decides which runtime lib variant you need,

                    and builds it for you automatically the first time.   After that the library will exist and you will just link against it.

                    (first time takes 5-6 minutes).

    Ok sophisticated fix is motivated by wanting to use the FPU but not pay the penalty in all your ISR routines.

    Here's that RTI compare interrupt code:

        

    Those blue lines are the 'overhead' for saving the FPU context.    Now that's a lot of stuff to save because all of those 'd' registers

    are actually 64-bits. 

    The good news is that the Cortex R has 2x 64-bit ports to TCM RAM (a DSP-like architecture) and it can get this push done faster than it may seem at first.  It should only be costing you 18 cycles even though there are 5 instructions to execute and 18 32-bit words of data to write to memory split over three seperate 'push' instructions.   That's faster than normal but still something you might want to get rid of in your ISRs if they do not need to use floating point. 

    Now let's say you have a model from simulink where it's very nice to execute in floating point -- so some tasks are going to be using the FPU.   But you want to have rapid interrupt responses. 

    The way to make this happen is to change on a *PER FILE* basis the compiler option. 

    So you would leave your global (project level) compiler switch set to '--float_support=VFPV3D16'  but for your interrupt handler code and any functions that they call ... as well as any other exception handlers that are not going to use the VFP - you would file by file change the --float_support to 'vfplib'. 

    You can also set on those files you change to '--float_support=vfplib" this option:   –floating_operations_allowed = none 

    where you will get a compiler error if you accidently try to use a variable of type 'float' for instance..    That way you don't inadvertantly wind up linking the soft floating point library functions too. 


    I suppose you could also 'flip' the VFP global setting to 'vfplib' and set the default option to –floating_operations_allowed = none  then only on the files that you want to allow to use floating point - make them have local compiler options that allow VFPV3D16.    Have never tried that way.   I'd pick the method with the fewest 'overrides' and that probably depends on the nature of your code. 

    Will look at the other issue now..   Sorry this one should have been more obvious to me - as soon as I saw the Undef exception though I knew what was going on. 


    Thanks and Best Regards,

    Anthony

  • Wow!

    Thank you for the thorough answer on the first part.

    "Should have been more obvious"
    That was so major not obviousness, although now that I read what you wrote that makes total sense, but major not obviousness.

    Method:
    EASY over sophisticated and dealing with compiler switches. The 18-cycle loss is par for the course, not to bad. There are other losses. Heck, if performance was an issue, we would run the chip not at 16 MHz but rather 220 MHz.

    Comment:
    You mentioned a holdover from the 386. The previous version of this board used an Intel 80386EX! The project calls for finally replacing that part with the TI RM48L952ZWT Hercules processor.

    I will mark Verified Answer on the answer, as that answers the direct question, however there is still the second part, which is coming up!

  • Hi Sarah,  

    Thanks!

    I think on the 2nd issue - I steered you down the wrong path in changing the VIM RAM table in the GUI.     While the table needs to be changed, now I see what HalCoGen is doing...  

    It assumes that the channels are fixed,  and that whatever name you enter into the VIM RAM table is the name that is should use when it generates the corresponding ISR. 

    It's obvious now that I look at the generated rti.c file:

    It's taking the RTI Compare 2 interrupt routine and just renaming it rtiCompare0Interrupt  but that's just a name and could be 'pizza'.

    However, now it's *not* generating a function called 'rtiCompare2Interrupt' I think because 

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

    /** @fn void rtiCompare0Interrupt(void)
    * @brief RTI1 Compare 2 Interrupt Handler
    *
    * RTI1 Compare 2 interrupt handler
    *
    */
    #pragma CODE_STATE(rtiCompare0Interrupt, 32)
    #pragma INTERRUPT(rtiCompare0Interrupt, IRQ)

    /* SourceId : RTI_SourceId_024 */
    /* DesignId : RTI_DesignId_022 */
    /* Requirements : HL_SR95 */
    void rtiCompare0Interrupt(void)
    {
    /* USER CODE BEGIN (80) */
    /* USER CODE END */

    rtiREG1->INTFLAG = 4U;
    rtiNotification(rtiNOTIFICATION_COMPARE2);

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


    So I think I started you down the wrong path by working in the GUI. 

    It looks like this entire remapping needs to be done through the APIs. 

    What makes it tricky though is that if you do not 'enable' the interrupt in the VIM  "Channel x-y' tab, 

    then HalCoGen doesn't even generate the handler routine for that interrupt.  

    So one button has 2 functions: 

       - emit code 

       - enable VIM channel

    And we need to pick a middle option where the code is emitted, but the channel isn't enabled. 

    I'll see if I can't figure something out based on your 'no priority' version of the project.  

    But this does seem to be highlighting a pretty major deficiency in the GUI and it's lack of support for channel mapping. 

    Thanks and Best Regards,
    Anthony

  • Thank you Anthony for the nice reply. I look forward to the follow-up.

    ;-) I said the same thing earlier about simply a rename, when I renamed the interrupt handler OhMightCarson, or something like that.

    TI created the remapping function but fell short on actually using that function, otherwise engineering would have realized the same thing that I did and that you now do, namely HalCoGen needs support for remapping. Enabling and generate code should also be separate. I see no reason why the next version cannot feature a GUI remapping.

    Sarah
  • Hi Sarah,

    I think you were close in your first post with the code for 'doInitVim()'

    But in addition to calling vimChannelMap, you would also call vimEnableInterrupt() and vimDisableInterrupt() as needed.
    And to be complete you might want to 'fixup' vimREG->FIRQPR0 although this really isn't necessary if you always leave all
    interrupts on IRQ except for the ESM's..

    This type of approach in 'doInitVim()' seems to keep you insulated from changes in HalCoGen to some extent -- if there is a critical bug fix to the initial VIM initialization for example hopefully you would inherit this.

    But there are some deficiencies - there is a function vimGetConfigValue() that would still return the original HalCoGen values
    for the 'InitialValue'. I need to check with the software team but I suspect this function and the #defines in the header file are all there for 'safety' purposes - implementing some sort of 'read back register values to make sure no bits flipped' type of function.
    So overriding the register values may make later adding this sort of check more complicated.

    Same goes if you ever had a parity error that needed to be corrected. In addition to having to rewrite the value from "s_vim_init[]' in sys_vim.c, you would need to then apply all your changes again.

    In a nutshell I'd normally err towards what you started doing - but there are some reasons to consider fixing up 'sys_vim.c' and 'sys_vim.h' but then that means any future changes made through the HalCoGen GUI to VIM would need to be manually carried over to the 'copies'. Not a great solution either.

    But given the current GUI and generator I think it's got to be one of these two options.

    What do you think is the best approach for now?

    Thanks and Best Regards,
    Anthony