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.

PWM divisor of LM4F232

Other Parts Discussed in Thread: LM3S6965

Hello,

I'm evaluating the LM4F232 with the evalboard EKK-LM4F232. I'm testing the PWM module for the moment on PG2 (LED of the evalboard) and I have some questions about the PWM divisor. The MCU is working at 80MHz but I tested with others frequencies.

If I set the PWM divider at specific values before the enable of the PWM, I feel that the MCU refuse to start (UART0 or SSI0 for example do not respond).
If I write the following lines :

SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);
ROM_SysCtlPWMClockSet(SYSCTL_PWMDIV_xx);  with xx = 1 or 2 it works well but not with divisor from 4 to 64.
I tried with differents SYSCTL_SYSDIV (just in case) without success.
To have the divisor which works with all values, I have to set the PWM divider after ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM1); If done before, the MCU seems to be blocked.

I tried to set config registers directly without better results

    //SYSCTL_RCC_R = 0x078E3D51;
    SYSCTL_RCC_R = (SYSCTL_RCC_SYSDIV_M /*| SYSCTL_RCC_USEPWMDIV | SYSCTL_RCC_PWMDIV_2*/ | SYSCTL_RCC_PWRDN | SYSCTL_RCC_BYPASS /*| SYSCTL_RCC_XTAL_16MHZ | SYSCTL_RCC_OSCSRC_INT | SYSCTL_RCC_MOSCDIS*/);
    //SYSCTL_RCC_R = 0x07900D40;
    SYSCTL_RCC_R = (SYSCTL_RCC_SYSDIV_M | /*SYSCTL_RCC_USEPWMDIV | SYSCTL_RCC_PWMDIV_2 |*/ SYSCTL_RCC_BYPASS | SYSCTL_RCC_XTAL_16MHZ);
    //SYSCTL_RCC2_R = 0xC1004800;
    SYSCTL_RCC2_R = (SYSCTL_RCC2_USERCC2 | SYSCTL_RCC2_DIV400 | SYSCTL_RCC2_SYSDIV2_2 | SYSCTL_RCC2_USBPWRDN | SYSCTL_RCC2_BYPASS2 | SYSCTL_RCC2_OSCSRC2_MO);
    //SYSCTL_RCC_R = 0x07D00D40;
    SYSCTL_RCC_R = (SYSCTL_RCC_SYSDIV_M | SYSCTL_RCC_USESYSDIV | SYSCTL_RCC_USEPWMDIV | SYSCTL_RCC_PWMDIV_4 | SYSCTL_RCC_BYPASS | SYSCTL_RCC_XTAL_16MHZ);
  while ((SYSCTL_RIS_R & SYSCTL_RIS_PLLLRIS) != SYSCTL_RIS_PLLLRIS) {}    // Waiting for the stabilization of the PLL
    //SYSCTL_RCC2_R = 0xC1004000;
    SYSCTL_RCC_R = (SYSCTL_RCC_SYSDIV_M | SYSCTL_RCC_USESYSDIV | SYSCTL_RCC_USEPWMDIV | SYSCTL_RCC_PWMDIV_4 | SYSCTL_RCC_XTAL_16MHZ);
    SYSCTL_RCC2_R = (SYSCTL_RCC2_USERCC2 | SYSCTL_RCC2_DIV400 | SYSCTL_RCC2_SYSDIV2_2 | SYSCTL_RCC2_USBPWRDN | SYSCTL_RCC2_OSCSRC2_MO);

With SYSCTL_RCC_PWMDIV_1 or SYSCTL_RCC_PWMDIV_2 it works but not with others values (MCU stopped too).

On the page 1274, it's recommended to clock the PWM before making changes in the PWM divisor but it's weird that it works with divider equal to 1 or 2 and block the MCU with the other values. From my experience on the LM3S6965, I can clock the PWM after setting the PWM divisor.

Best regards,

Sébastien

  • Sébastien

    This does not sound like correct behaviour.  Can you tell me what the full part number is on the chip?  I will try to replicate the problem in the meantime.

    Thanks,

    Sean

  • Sean,

    The part number is :

    980 YF
    LX4F232H
    50DFIGA1
    19AD23W
    G4

    Best regards,

    Sébastien

  • Sébastien,

    Based on the part number, I can see that you're running an A1 part.  It currently has an errata that prevents some device from reliably running at 80 MHz.  This was fixed in revision A3. Can you try running at 50 MHz and see if you still have the same problem?

    Thanks,

    Sean

  • Sebastien Thirion said:
    The MCU is working at 80MHz but I tested with others frequencies.

    He's "almost" anticipated your direction...  As described - I'd bet issue persists even @ 50MHz and below...

  • Sean, cb1_mobile,

    The MCU has been tested today at 80, 50, 20 and without PLL (with SYS_DIV_1 and 4) and I meet the same problem with PLL divisor equal or higher than 4.

    Did you have the time to check if you meet the same behaviour with A1 and also with A3 ?

    Best regards,

    Sébastien

  • Later today I'll see if your issue persists across our 64 pin, A1 ver. M4 - upon our custom board.  Have an older M3 board - can test that this weekend (in attempt to see if problem "pre-existed") - if req'd...

  • I'm quite sure that I didn't have this problem with the LM3S6965. In the past on LM3S6965, I always set the RCC register with PWM divisor enabled before enabling the PWM module.

    I will be interested to know if you (both) were able to reproduce this issue with others M4 and differents revisions just to know if it's a general problem or more related to my evalboard. Depending on the results, it may be necessary to switch to a newer revision.

  • Sébastien,

    I've been unable to reproduce the issue on my ek-lm4f232 with a RevA1 chip.  I'll see if I can find a couple more boards and try them. 

    Thanks,

    Sean

  • I'm late (sorry) but can report no issue with, "ROM_SysCtlPWMClockSet(SYSCTL_PWMDIV_yy);"  w/yy set/checked @ 2, 4, 8, & 16.  Sean & I appear to have near identical findings - no evidence of MCU being blocked/disabled.  And hard to fathom how PWM (not PLL) could cause such.  (is it possible your code "confuses" PWM w/ PLL - that would be a more reasonable, "cause agent.")  And strange things may happen w/late-nite programming bouts...

    Must say - frown upon your reliance on both Uart and SSI operation to determine if MCU is "blocked."  Simpler test most always is Led toggle - across multiple ports.

    In each case - we produce 5 quick Led blinks across 3 different Ports - our test did not extend into Uart nor SSI.  Of some note - one port drives the Led anode - second port pulls the cathode to ground - thus "two" Ports test/verified via single Led...  (we'd never employ in "real-world" but does cut port/pin testing/set-up substantially.  Four such leds can thus fully test/verify an 8 bit port - and proper pin layout or data selectors can extend such test to multiple ports - in timed sequence...

    Ours is custom board w/ 4F231H5QR Rev A1 (64 pin MCU) running @ 50MHz,  w/25MHz  xtal.

    As always - would be greatly instructive if you could test/replicate against additional boards...

  • 1057.PWM.rar

    Sorry to bother you again with my problem of PWM divisor. I attached a sample code (made with Keil 4.53). If the line 82 is used, my MCU  refuses to send caracters with the UART., to provide PWM signal on PG2 or to blink PA3 at 1Hz.

    I think that if you are able to make work this sample code, my evalboard should have some problems and it will be necessary to replace the MCU.

  • Sébastien,

    It's not a problem -- it's part of our job responsibilities to help on the forums.

    I was able to get your code working with a few changes with GCC.  I had to make a couple of updates to get it to compile with my version of StellarisWare.  I had to add some include some header files as well as update the timer setup.  Do you know which version of StellarisWare you are using?

    I had to change the UART code because it appeared to be sending 0.   I changed it to send this:

    ROM_UARTCharPutNonBlocking(UART0_BASE, 0x41);

    I see 'A' being printed with the PWM clock set function present.  If it still doesn't work after updating your copy of StellarisWare, then we likely need to RMA your board.

    Thanks,

    Sean

  • Sean de la Haye said:
    it's part of our job responsibilities

    While that may be true - your effort clearly, "above/beyond!"  That said - if not too much effort - could you post the, "couple of updates" mentioned - so that many could benefit?   I've yet to encounter such a condition - likely instructive to learn, "How to avoid..."   Thank you.

  • Sean,

    The version is the 9107.

  • Sébastien,

    Here are the changes I had to make to get the code compiling and printing over the UART with GCC and StellarisWare 9107:

    13d12
    < #include "driverlib/pin_map.h"
    115c114
    <       ROM_TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC);
    ---
    >       ROM_TimerConfigure(TIMER0_BASE, TIMER_CFG_32_BIT_PER);
    143,145c142
    <       ROM_UARTCharPutNonBlocking(UART0_BASE, 0x41);
    <       ROM_UARTCharPutNonBlocking(UART0_BASE, 0x0d);
    <       ROM_UARTCharPutNonBlocking(UART0_BASE, 0x0a);
    ---
    >       ROM_UARTCharPutNonBlocking(UART0_BASE, ulTemp & 0xFF);

    It must be a difference between compilers.  I will see if I can try it with Keil and some other LM4F boards.

    Sean

  • Just for your information because we are talking about compilers.

    The code which works (with the PWM divisor set after the PWM module enabled) is working only with optimization level at default (2 ?), 1, 2 and 3. With level at 0, I have nothing on the UART and PWM pins.

    Unfortunately, if the PWM divisor is set before the PWM module enabled, I tested with all optimization levels and I have nothing on UART and PWM pins.

  • Sébastien,

    Good news: We have been able to reproduce the issue with Keil.  When the PWM divisor is set too high, we're seeing a hard fault when the PWM module clock is enabled with the SysctlPeripheralEnable function.  We will look into the issue and let you know what we find as the cause.  In the meantime, set the PWM divider after the SysctlPeripheralEnable function -- that appears to work reliably.

    Thanks,

    Sean

  • Dear Sean,

    Thank you very much for spending so much time to reproduce my problem. I was starting to believe that my evalboard was cursed because you and cb1 were not able to reproduce my problem.

    I didn't know if I had to create a new thread but unfortunately, I feel that my problems of hard faults are not totally finished. In general, does a pointer can only point to global variable ? If I used a void (I tested others types) pointer to point to a global variable, there is no problem but the MCU seems to be blocked with a local variable.

    Code which works :

    void *ptr_void = 0;
    float Chrom_Voltage = 0.00;
    ...

    int main(void)
    {
    ...
    ptr_void = &Chrom_Voltage;
    ...

    }

    Code which does not work :

    void *ptr_void = 0;
    ...

    int main(void)
    {
    float Chrom_Voltage = 0.00;
    ...
    ptr_void = &Chrom_Voltage;
    ...

    }

    I also tested to define the void pointer and variable in the main but it seems that the MCU is blocked too.

    Best regards,

  • Pardon - can't assist w/CCS (IAR our preference) but I vaguely recall similar issue (long past) and the "cure" was to insert simple delays after critical clock or system settings.  One second should work - and if this corrects you can keep "carving away" until you find a safe minimum. 

    Another thought - wonder if the IDE "Set-Up" masks or intrudes - in the attempt to be, "helpful?"  (thank you very much - now go away!)  

    Long-shots - admittedly - but sometimes the unexpected surprises... 

  • Local variables are typically stored in registers or the stack.  If the variable is in a register, you can't get a pointer to it, but the compiler should move it to the stack if you are referring to its address.

    If you move out of the scope of the local variable, though, any pointer to it will now be invalid.  It's generally a bad idea to have a global variable that points to a local variable.  While your code may be valid, most likely there's some flaw in the code design, and you are asking for problems when using this.

    I also don't understand what you mean when you say the MCU is blocked.  Does it mean that you get a fault on the line where you assign the pointer to the variable, or does it mean something else entirely?