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.

DM648 HWI

Hi,

 

I'm working on the DM648 on custom HW.  We have two raw video inputs on VP0 and VP1 and are using the UART to communicate with another processor.  Because we have had problems with the reliability of the UART I've written our own driver.  This tests ok in a seperate test project, but not in the video project (sem_pend has stopped blocking, can't see why).  I'm using HWI INT4, mapped to the UART as follows in the bios config file:

bios.HWI.instance("HWI_INT4").useDispatcher = 1;
bios.HWI.instance("HWI_INT4").fxn = prog.extern("M2_UART_HWI");
bios.HWI.instance("HWI_INT4").interruptSelectNumber = 36;

I'm wondering if this interrupt is also being used by the video ports or bios, but don't know how to find out.  How can I see which HWI are in use once the video drivers etc are up and running?  The video project is based on the encode/decode example in the DVSDK.

 

Thanks,

Simon

 

  • You might try looking at the HWI view in KOV in CCS 3 (or ROV in CCS 4). Hopefully this will show you what interrupts are currently plugged.

    Thanks,

    Chris

  • Scratch that; BIOS 5 ROV in CCSv4 doesn't have a HWI view, so KOV probably doesn't either. We'll see if there's something else we can suggest.

    Thanks,

    Chris

  • I am using CCS3.3 and BIOS 5.31.08.  I tried to open kernel/object view, but CCS hangs, I tried it several times from a clear start.  Other BIOS information like message log and CPU load work fine.

     

    Any other ideas?  I'm happy to send the .tcf and .cfg files if someone can work it out from them.  I've gone through what I can of the video drivers that come with DVSKD but I can't find what HWI are being used.  Also I'm sure BIOS will be using some for timers etc.

     

    Thanks

    Simon

  • Simon,

    You should be able to put breakpoints on the hardware interrupt vector and single step to determine what function is plugged into the HWI.

    The base of the interrupt vector table is ISTP register.  BIOS creates labels at each vector...something like "HWI_INT4" for interrupt vector 4.

    You can also try to decode what GEM event is plugged into which mappable interrupt vector (vectors 4-15 are re-mappable).  You can look at the interrupt mux registers which are 3 32-bit registers starting at address:  0x01800184.  Each byte of registers tells you the event number that is plugged for that vector.  You can find out what they are set to at static config time by looking at the generated *.map file and look for HWI_INTRMUX1, HWI_INTRMUX2, HWI_INTRMUX3.

    Judah

  • Thanks for the reply Judah,

     

    I have located the HWI_INTMUX registers.  With the HWI_5 assigned in the .tcf file to M2_UART_HWI, as in my first post, but using HWI5 now instead of 4 as using 4 wasn't stable, I can now see that HWI is assigned to event 36, the uart as I intended.  If I comment out the HWI_5 init code in the bios .tcf file HWI_5 is assigned to interrupt event 5, reserved according to table 6-25 in SPRS372F. 

    With HWI5 assigned in .tcf

    INTMUX1 = 0x00062404
    INTMUX2 = 0x0b030201
    INTMUX3 = 0x4543000c

     

    Without HWI assigned in .tcf

    INTMUX1 = 0x00060504
    INTMUX2 = 0x0b030201
    INTMUX3 = 0x4543000c

    Is this ok or does it need to be moved to a different interrupt?  Also decoding the HWI_INTMUX registers, HWI13 and 7 are both assigned to event 0, combiner 0.  Could this be a problem?

     

    judahvang said:

    You should be able to put breakpoints on the hardware interrupt vector and single step to determine what function is plugged into the HWI.

    The base of the interrupt vector table is ISTP register.  BIOS creates labels at each vector...something like "HWI_INT4" for interrupt vector 4.

     

    I can't find the address of the ISTP register, and don't know where to set the breakpoints to single step through to find the functions called on HWIs.  I want to see what is called for the combined events as I think there is a problem of clashing interrupts.  My program is hanging randomly after anything between half an hour and several hours, it's not a memory leak so other than HWIs problems I can't see what could be causing this problem.

     

    judahvang said:

    You can also try to decode what GEM event is plugged into which mappable interrupt vector

    Can you please give me more information on what you mean here?  I can't find any reference to a GEM event in the documentation I have.

     

    Many thanks,

    Simon

  • Simon,

    Is this ok or does it need to be moved to a different interrupt?  Also decoding the HWI_INTMUX registers, HWI13 and 7 are both assigned to event 0, combiner 0.  Could this be a problem?

    This should not be a problem because these interrupt should not be enabled by default.  If for some unkown reason the program enabled one or both of these interrupts then, that would be a problem.  The IER (Interrupt enabled register) of the cpu core registers lets you know which interrupts are enabled.

    ISTP is not a memory map register.  It is a CPU core register.  Are you using CCS?  If so you should be able to put literally "ISTP" in the disassembly window and it should show you the base of the interrupt vector table.  From there you will see HWI_INT1, HWI_INT2, etc....  You could put breakpoints at the HWI_INTX labels and single step to find out what ISR function it is calling.

    Can you please give me more information on what you mean here?  I can't find any reference to a GEM event in the documentation I have.

    By this, what I mean is did you actually check out the interrupt mux registers on the hardware?  You should realize that the symbols "HWI_INTMUX1", "HWI_INTMUX2', "HWI_INTMUX3" are whats generated from your static configuration.  If you plugged any HWI at runtime, then the values in the interrupt mux registers could be different from what was generated from your static configuration.  If you didn't plug any HWI at runtime, your probably okay.

    You should check to see that you don't overrun your stacks.  If you're on BIOS5, I recommend using LOG_printf along with RTDX to have visibility in real-time on the system.

    Judah

  • Thanks for the explanations.  I've checked the HWI_INTMUX registers and they are not changed dynamically.

     

    I have put a breakpoint on the HWIs as you suggested, when the DSP hangs we are in HWI0, HWI_reset.  I can run the code again and then halt it and it is always in this interrupt, but at a different location, so it looks as if it's looping in the function for some reason. Sometimes it goes to c_int00 and then back to HWI_reset.  Any ideas to why it's looping and not restarting?

     

    I've put a scope on the warm reset line and I can't see any problem with it.  Is it possible that software could call this because of an error, or is it only coming from HW?  I don't have any call to it in my code, but am using TI code for video port drivers, edma, JPEG etc. 

     

    Is it possible to modify the HWI_reset function to set a GPIO line, I can then use this to trigger the scope and look at all the power supply lines when the  reset occurs?  I can't find the source code for this function.

     

    The code at HWI_reset, from the disassembly view is:

            $package/cfg/M2_Video_To_JPEG_x64Pcfg.s62:851:869$, HWI_A_VECS, hwi0:
    E5CB0000 007A702A            MVK.S2        0xfffff4e0,B0
    E5CB0004 0072E56A            MVKH.S2       0xe5ca0000,B0
    E5CB0008 00000362            B.S2          B0
    E5CB000C 0000A35A            MVK.L2        0,B0
    E5CB0010 020003A2            MVC.S2        B0,IER
    E5CB0014 00000000            NOP          
    E5CB0018 00000000            NOP          
    E5CB001C 00000000            NOP          

     

    c_int00 is:

     c_int00:
    E5CAF4E0 0000A35A            MVK.L2        0,B0
    E5CAF4E4 000003A2            MVC.S2        B0,AMR
    E5CAF4E8 07C0B02A            MVK.S2        0xffff8160,SP
    E5CAF4EC FFF2E3EA            .word         0xfff2e3ea
    E5CAF4F0 000FFE2A            MVK.S2        0x1ffc,B0
    E5CAF4F4 000000EA            MVKH.S2       0x10000,B0
    E5CAF4F8 0781E842            ADD.D2        B0,SP,SP
    E5CAF4FC FCBF09F2            .word         0xfcbf09f2
    E5CAF500 0766602A            MVK.S2        0xffffccc0,DP
    E5CAF504 0072E56A            MVKH.S2       0xe5ca0000,B0
    E5CAF508 0180A35A            MVK.L2        0,B3
    E5CAF50C FF0C03A2            .word         0xff0c03a2
    E5CAF510 008C03A2            MVC.S2        B3,CSR
    E5CAF514 00D9CA28            MVK.S1        0xffffb394,A1
    E5CAF518 01F2D6E8            MVKH.S1       0xe5ad0000,A3
    E5CAF51C FC000000            .word         0xfc000000
    E5CAF520 000C1362            B.S2X         A3
    E5CAF524 07828162            ADDKPC.S2     C$RL0 (PC+8 = 0xe5caf528),SP,4

     

    How do I check if the stacks have overrun?  The system isn't dynamic, it's doing exactly the same processing to every frame to come from the video ports.  I am using BIOS5 and LOG_printf if that helps.

     

    Many thanks,

    Simon

  • I have checked for stack overrun, as described  here:

    http://processors.wiki.ti.com/index.php/Checking_for_Stack_Overflow_using_Unified_Breakpoint_Manager

    but the system or task stacks are not overrunning, I've checked multiple times, the HWI_reset is hit and all the stacks are ok.

     

    Any other suggestions of things to try?  I'd really like to know what can cause a HWI_reset other than a warm reset line, the emulator is still working so I'm sure it can't be a POR.

     

    Thanks,

    Simon

  • Simon,

    I'm not sure what reasons would cause a jump to "HWI0" but if you're getting there you can try to backtrace where it came from.  The register "B3" is the return address pointer so it tells you where your program should have returned.  This can give you a general idea of where the program failed.  SP - stack pointer, can let you know whether it was executing in a task (SP would be in a task stack) versus a Hwi or Swi (SP would be within the ISR stack).  IRP - interrup return pointer, this is the instruction to return to after servicing an interrupt, but not sure it applies in your case since your program jumped to the reset vector.

    One case where I have seen a jump to HWI0 is if there was an exception (Program would have jumped to HWI1 also known as NMI (non maskable interrupt)) and then another exception happened while it was processing this exception.  If you're not seeing a jump to HWI1, then something else must be causing the reset.

    Judah

  • Judah,

     

    You were right, the HWI0 was a result of an earlier call to HWI1, NMI.   I put a breakpoint at the start of HWI1 and the address in register B3 corresponds to a function called:         C$DW$L$_datCopy2D1D_host$4$B, C$DW$L$_datCopy2D1D_host$3$E, C$RL0:

    I have searched the project and can't find any instance of datCopy except in the .out file.  Do you know what this is?  I wonder if it is part of the JPEGenc library which I'm calling every frame.  The stack pointer corresponds to the video processing task where the JPEG takes place.  The task first sets up two RAW video ports and processes each frame; the processing involves pixel manipulation for contrast, brightness, remapping pixel locations (eg flipping lines) and false colour, lastly the JPEG encode is called.  For each JPEG frame the algorithm is activated, controlled, processed, then deactivated.  I've checked pointers and buffers and can't find any problems, it works correctly for some time before hanging.

     

    Is there any other advise you can give about tracking down why it ended up in the NMI?  The NMI pin on the chip is tied low via a 1k resistor.

     

    Many thanks,

    Simon

  • Simon Roper said:
    Is there any other advise you can give about tracking down why it ended up in the NMI?

    Once at the NMI breakpoint you can look at the BIOS trace logs and it should have a nicely formatted message as to what was the cause.  If you can't see it then you can manually get the same info by inspecting the CPU registers:

    • EFR will tell you whether it was caused by the NMI pin or by an "internal" exception
    • For internal exceptions see the IERR register for more details on what caused the issue.
    • NRP will contain the address of what was executing at the time the NMI/exception occurred.
    • Look in a disassembly window at the location corresponding to NRP.  Make sure everything disassembles properly (should NOT see ".word" in there).
  • Many thanks for you help on this, I've learnt a lot. 

     

    I think the problem is now fixed, I changed the PSC settings so that only the required parts of the chip are now powered up and I haven't see any problems since.  I think we have unused pin(s) floating which were causing the problems.

     

    Simon.

  • Simon,

     

    Your problem sounds similar to ours. Could you tell me which module/s you needed to disable? Most of the modules are documented as being in reset by default.

  • Geoff,

     

    The gel file which we were using, a modified version of the Lyrtech EVM one enabled all PSC modules, as did the device.c, used in the bootloader when running from FLASH.  I went through the modules and only selected the ones we needed to enable.  the section of my gel file is below:

     

     

    hotmenu Set_Psc_M2( )

    {

        unsigned int i=0;

        // int psc_modules[11] = {7, 10, 11, 12, 20, 21, 26, 27, 30, 31, 34};

     

        GEL_TextOut( "Power on all PSC modules and DSP domains... \n");

        if( BOOTCFG & 0x40000)

        {

            GEL_TextOut( "In DVR mode. \n" );

            Set_PSC_State(PD0, LPSC_TPCC, PSC_ENABLE);

            Set_PSC_State(PD0, 7, PSC_ENABLE);

            Set_PSC_State(PD0, 10, PSC_ENABLE);

            Set_PSC_State(PD0, 11, PSC_ENABLE);

            Set_PSC_State(PD0, 12, PSC_ENABLE);

            Set_PSC_State(PD0, 20, PSC_ENABLE);

            Set_PSC_State(PD0, 21, PSC_ENABLE);

            Set_PSC_State(PD0, 26, PSC_ENABLE);

            Set_PSC_State(PD0, 27, PSC_ENABLE);

            Set_PSC_State(PD0, 30, PSC_ENABLE);

            Set_PSC_State(PD0, 31, PSC_ENABLE);

            Set_PSC_State(PD0, 34, PSC_ENABLE);

            GEL_TextOut( "Power on all M2 needed PSC modules and DSP domains... Done.\n" );

        }

        else

    GEL_TextOut( "Power on all M2 needed PSC modules and DSP domains... ERROR.\n" );

    }

     

    Hope this helps.

    Simon