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.

Creating a PWM using HET

Other Parts Discussed in Thread: HALCOGEN

Greetings,

I am currently working on a RTOS project using uC/OS-II and the Hercules HDK (TMS570). I am trying to generate two PWM signals using the HET module, but whenever I call hetInit(); my system seems to crash. Here is what I would like to do...

I would only like to initialize the two pins HET pins that I need, since some of the HET pins are configured by uC/OS-II, and reconfiguring them with the hetInit() call seems to cause problems. Once these two pins are configured, I would like to be able to use the function pwmSetDuty(hetRAM1, signal, value) to set the duty cycles for the two PWM signals. Also, I am having some trouble finding out where specific pins on the HET are actually located on the board. For instance, when I use Halcogen to try to create a PWM signal, it allows the user to select pins 0 - 31; where are these located on the HDK?

Any help would be greatly appreciated.

Regards,

Willis

  • Willis,

    Halcogen offers 8 PWMs to be generated by HET1. Each PWM can be connected to each of the HET1 - pins:

    HalCoGen -> HET1 -> Pwm0-7 -> PWM0 -> Pin (0...)  

    Assume you connect PWM0 to pin 0, the signal will be at pin HET1:0, marked as "100" in the HET-connector at the bottom side of the HDK.

     

     

  • Frank,

    Thanks and I agree with your comments.

    Willis,

    What type of 'crash' are you experiencing?   Can you halt the processor after the crash and tell me where the PC is?

    Best Regards,

    Anthony

  • Mr. Seely,

    Thank you for your response. I was able to figure out what HET pins correspond to what pins on my board by simply blinking them using the gioSetBit(hetPORT, X, X); function and by referencing the schematic. So that solves one problem.

    As I mentioned in the first post everything works fine in the RTOS except for my PWM signals. When I try to set the duty cycle the OS winds up in the OS_CSP_BSP_ExceptHandler. The function definition is shown below...

    /*
    *********************************************************************************************************
    * OS_CSP_BSP_ExceptHandler()
    *
    * Description : Handles ARM exceptions.
    *
    * Argument(s) : Exception type.
    *
    * CPU_ARM_EXCEPT_RST Reset exception.
    * CPU_ARM_EXCEPT_UND Undefined instruction.
    * CPU_ARM_EXCEPT_SWI Software interrupt.
    * CPU_ARM_EXCEPT_ABORT_PREFETCH Prefetch Abort.
    * CPU_ARM_EXCEPT_ABORT_DATA Data Abort.
    *
    * Return(s) : none.
    *
    * Caller(s) : OS_CPU_IntHandler().
    *
    * Note(s) : (1) This exception handler is implemented with an infinite loop for
    * debugging porpuses only.
    *********************************************************************************************************
    */

    void OS_CSP_BSP_ExceptHandler (CPU_INT08U except_type)
    {
    switch (except_type) {
    case CPU_ARM_EXCEPT_RST:
    case CPU_ARM_EXCEPT_UND:
    case CPU_ARM_EXCEPT_SWI:
    case CPU_ARM_EXCEPT_ABORT_PREFETCH:
    case CPU_ARM_EXCEPT_ABORT_DATA:
    while (DEF_TRUE) {
    ;
    }
    }
    }

    Thank you for the help, 

    Willis

  • Hi Willis,

    Good that makes it easy for us :)   What is the value of 'except_type'?  (CPU_ARM_EXCEPT_UND, CPU_ARM_EXCEPT_ABORT, etc... ?)

    Best Regards,

    Anthony

  • Mr. Seely,

    Execution stops in the while loop under the case CPU_ARM_EXCEPT_ABORT_DATA. 

    I have included a picture for you...

    Furthermore, if I watch the variable "except_type" under the Expressions window in debug mode it tells me that, when the system crashes, the value of this variable is 0x01. This is shown below...

    Thank you for your help so far, Willis.

  • Hi Willis,

    We can find the offending instruction by setting a breakpoint on the Data Abort Vector at 0x10.

    1. Please set a breakpoint at address 0x10 and try running your code again (from a cpu reset and a system reset).

    2. When you stop at address 0x10, please note the address in R14 (LR).  If you subtract 0x4 from this address, that will be the instruction that caused the abort.

    3. Then, please start over again but this time clear the breakpoint at 0x10 and set the breakpoint at the address of the offending instruction (whose address is value of R14 - 0x04 )  where value of R14 is the value you noted in step 2.

    4. You should be able to run your code (from a cpu reset and a system reset) and it should stop at the breakpoint you just set.

        Before doing anything, please make a note of the CPU register values especially the CPSR and the registers that are used by the instruction.

        (If in doubt just paste all the CPU registers). 

    5.  You should be able to single step and hit the data abort vector on the very next step, to confirm that we got the address right.

    That information should really help narrow the problem down.

    On a side note, please check the header of the source code for the HET functions that you are using.  I think uCOS/II might be including a relatively dated version of these files;  and the best solution might be to update them.    [But before we go there we should do the analysis above to understand what the problem is...]

    Best Regards,

    Anthony

  • Mr. Seely,

    How exactly do you go about setting a breakpoint at a specific address? I apologize but I have never done this.

    Regards,

    Willis

  • Hi Willis,

    No need to apologize. 

    The Breakpoints Tab is one way:   

    You can select from the 'New Breakpoint (Code Composer Studio) dropdown (furthest left on the breakpoints tab toolbar,  blue circle with yellow + sign and drop-down arrow) the type of breakpoint.   Please use "Hardware Breakpoint" because you will be setting this breakpoint in flash which can't be written over.    There are a limited number of hardware breakpoints (I think about 8), so if you already have other breakpoints set you might need to delete them first before you can add a new one.

    When you select 'Hardware Breakpoint' a dialog box appears and you can enter the address in the box:

    If you open the disassembly tab as I have done (see the first screen capture, bottom pane) and type address 0x10 you should see the blue breakpoint symbol in the margin to the left of address 0x10.

    Note: A second way to set/clear the breakpoint would be to double click on that icon in the margin tab of the disassembly window.

    Best Regards,

    Anthony

  • Mr. Seely,

    Nevermind I found out how. Here is what I have done....

    1. "Please set a breakpoint at address 0x10 and try running your code again (from a cpu reset and a system reset)."

    a. I set the breakpoint, as shown below...

    b. after setting the breakpoint I performed a CPU and a system reset and then ran the program. As far as I can tell the program never hits the breakpoint. I still end up in the except handler. I have included a screen capture below.

    I dont know if it would help, but I could send you a copy of my CCS project and my code.

    Also, to answer your side note, I do believe that I am using an older version of Halcogen. However, when I first started the project, I had a significant amount of trouble getting the RTOS to work with the Halcogen code ,so I have been very hesitant to upgrade.


    Regards,
    Willis 

  • Hi Willis,

    Great - looks like you have the breakpoint set.   Are you going to try the other steps though?  It looks like in the screenshot you've stopped at step 1?

    If you want to send me your code that could work too;  but it might be better to go through the debug process together to get the technique down.

    If your code can't be posted on the forum, then please send me a friend request so we can communicate directly and we can figure out a way to exchange the code.

    Best Regards,

    Anthony

  • Mr. Seely, 


    I was not sure if you wanted me to continue with the other steps since I was not able to stop at the breakpoint during the first step; let me go through the rest of the steps.

    1.b. After I set the breakpoint, as I mentioned, the program does not seem to stop at it. When I pause the program, execution is once again in the except handler; the value of R14 is shown below... (it does not change)

    2. Even though I did not hit the breakpoint, I use the the address in R14 (0x000104B0) - 4 = 0x000104AC as the next breakpoint...

    I then once again perform a system/cpu reset and then run the program. I have included a screen capture of where program execution halts...

    As requested, I noted the values of the CPU registers before I ran the program...

    and after I ran the program and hit the breakpoint...

    Regards,

    Willis

  • My apologies Willis, I didn't see that you were not able to halt on the breakpoint.

    After setting the breakpoint,  you probably need to make sure you start your code from a reset.

    You should use both the "CPU Reset" and the "System Reset" in code composer.  
    These are under the "Run" menu item.   I would do the CPU reset first.   This should put your program counter back at address 0x00.  Then the system reset; this will reset the hardware registers in the peripherals so you start from a clean state.

    If you do both of these and can't hit the breakpoint at 0x10 then it probably isn't a data abort that is getting you to the OS interrupt handler.

    Best Regards,

    Anthony

  • Mr. Seely,

    I have re-set the breakpoint to 0x10. After that, I performed a CPU reset, followed by a system reset. As you can see from the screenshot, program execution is at 0X00...

    After I run the code, the breakpoint is not hit. If I manually stop program execution, this is where it stops...

    Regards,

    Willis

  • Mr. Seely,

    I went back and updated the het.c and het.h files through updating Halcogen and this did not seem to make a difference.

    Thank you for your time.

    Regards,

    Willis

  • Hi Willis,

    I tried your code, but haven't gotten it to hang.  Perhaps I need to do something like send it a command over the serial port?

    -Anthony

  • Hi Willis,

    I think I got this figured out a little better.

    First, what we found was that the exception was actually UNDEF not data abort.

    Second, we found that this was due to the execution of a floating point instruction.

    Here is a screenshot from CCS that shows this:

     

    We trace this back to the offending code by checking R14 (B740h) and subtracting 4 to account for the pipeline.   Then the instruction that offended was the FMSR instruction at address 0xB73C.

    Now, that is a floating point opcode, and the VFP needs to be enabled before any floating point instructions are executed.

    What I found in looking at the sys_core.asm that came with the uCOS/II distribution but was based on HalCoGen is that a conditional has been added:

    the flag being '__TI_VFPV3D16_SUPPORT__".

    Turns out this flag is checked throughout the OS code both in C and assembly since saving the state of the CPU during context switch is different if VFP is enabled.

    So, I added this symbol to the predefined symbols in the project build:

    Note that I added __TI_VFPV3D16_SUPPORT__=1   not just the name of the symbol.

    Ok I thought this solved the problem, and indeed when I got to the main() function the VFP was enabled.

    VFP is enabled with VFP_SYSTEM_FPEXC has bit 30 set (0x40000000).

    So I ran the code again and bang - right back to UNDEF.

    Turns out that you also have to define you task as floating point or the FPU will be disabled when the task is entered, by adding "OS_TASK_OPT_SAVE_FP" to the options list.  That also seems to trigger enabling of the VFP.

     

    Ok so to summarize with these two changes:

      1)  Add -D__TI_VFPV3D16_SUPPORT__=1  to the compiler command line

      2) Add the option "OS_TASK_OPT_SAVE_FP" to the options when you create the task

    I can see that when the task is entered the VFP is enabled and there are no more UNDEF exceptions.

    CAUTION: I don't know if the save/restore of the VFP registers between context switching actually works or not; didn't test that far.  That's really a question for Micrium.  I did see in their documentation that the parameter right before the options,  'pext' , which is set to the null pointer in your code, is described as a pointer to memory to hold a TCB extension and the example they give is to hold floating point registers.   What I can't tell is whether they need you to supply them some memory for the ARM CORTEX R4F port or if they've handled this more elegantly and automatically when you make the two changes above.  In your specific case - if you are only using floating point inside the one task - I think you can get by for a while;  but you should confirm the right way before adding too much more to the project.

  • Mr. Seely,

    I tried the steps above and my system no longer crashes. I am still not able to generate a PWM, but i think this is just a configuration error. Thank you very much for your help.

    Kind Regards,
    Willis 

  • Thanks Willis,

    Good luck with your project.

    Best Regards,

    Anthony