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.

tm4c1294 pwm

Hello,

Does any have some basic code for the tm4c1294 launchpad that demonstrates use of its PWM capabilities (i.e. blinking the LEDs with the switches controlling the pulse width). Im having trouble finding the correct way to initialize all the gpios and pwm blocks and whatnots...

All the documentation out there is for the tm4c123... This code does not work. Please do not post code for the 123 or links to the 123...

Thanks much!

Bryce

  • Hello Bryce,

    I would suggest going through the example code in the TivaWare Installation

    D:\ti\TivaWare_C_Series-2.1.1.71\examples\peripherals\pwm

    This will help to understand module and IO initialization.

    Regards
    Amit
  • Bryce Smith said:
    Does any (one) have some basic code for the tm4c1294 launchpad

    Far simpler is use of one of the MCU's Timers - configured into PWM mode.

    Two caveats (restrictions) may apply:

    a) your board may not directly route a timer output to an "on board" Led.  (you'll likely have to do that)

    b) PWM Generator provides much more command/control  capability

    For your expressed, "Switch control of PWM Duty Cycle" use of a Timer (as described) provides a greatly eased & speeded solution.

    (we should note that PWM usually operates at frequencies well above those employed to "blink" an Led...)

  • Thanks i had given some consideration to using a timer. But i am primarily focused on familiarizing myself with the boards PWM modules.

    I was hoping to use PWM to dim/brighten the leds. Any basics for that?

  • Bryce Smith said:
    use PWM to dim/brighten the leds. Any basics for that?

    Well yes - there are "basics" - but if you miss set-up/config you may spend days in frustration.

    Our findings - most all "shortcuts" achieve the opposite!    Amit has guided you to the "slow, steady" code examples - which usually - but not always - insure that your set-up & config. are full & proper.

    Look (but not at bedtime) at the PWM section of the MCU Manual, too.   It's well written - but oozes with detail - it is nether a "quick nor pleasant" read.   Again - unless you're far smarter/gifted than most here - be prepared to "invest the time" to read and code - and repeat that process.

    We find that "feedback" either via an Led - but far better from even a simple scope - will help immensely.    Run your PWM at 100Hz or so in the beginning - going faster adds complications - later is time enough for tweaking.

    Again - the Timer should prove a 10 times (or more) faster/easier means to PWM Leds.    All the key/critical benefits of the PWM Generators are primarily reserved for their use in tandem (a la 3 phase BLDC motor, or power switching/generation) and not really/fully/properly harnessed by an Led...

  • Thanks. Yes the end game here is to use the board to do MPPT through PWM for a small underwater rotor... however i cannot even get the PWM modules to work for me. I tried using this code from another forum that you commented on https://e2e.ti.com/support/microcontrollers/tiva_arm/f/908/t/379458 

    the compiler says that  its having trouble with this portion 

        GPIOPinConfigure(GPIO_PA6_M1PWM2);

        GPIOPinConfigure(GPIO_PF0_M1PWM4);

        GPIOPinConfigure(GPIO_PF1_M1PWM5);

        GPIOPinConfigure(GPIO_PF2_M1PWM6);

        GPIOPinConfigure(GPIO_PF3_M1PWM7);

    that the GPIO_Pnn_MnPWMn isn't defined... why is this happening?

  • One additional note on using an LED to test PWM (I would also recommend a 'scope or logic analyser). LEDs have a very non-linear visual response. You often find that the total apparent visual change takes place over a narrow range of PWM values.

    Robert
  • My friend - too often the "lure" of the  End Game intrudes upon the necessity of building an adequate, "Beginning Game."

    Have you read and programmed the PWM example which vendor's Amit referenced?   If not - "blind copying" of another's code - proves ineffectual - just as you report.    When you report, "cannot even get the PWM modules to work" - what does that really mean?   (I can quickly/easily think of at least 3 PWM "issues.")

    You should avoid use of PF0 or PD7 at this stage - and you should model your code after the example aleady provided.  

    Earlier you were "alerted" to the fact that PWM Generator set-up & configuration is detailed & demanding.    And the "copy/paste code" you now present - provides only a "partial PWM initialization."  

    Devil is in the detail w/these MCUs - they're powerful but "shortcuts" - as you're discovering - are unlikely to ease - fully work or (even) "shorten."

  • are there any tutorials about? I've been plugging away with the manual for the board as well as the peripheral driver user guide...
    I've been looking at other code just to see how others have implemented PWM but honestly i feel like very little progress is being made, and resources are sparse.
    I am trying to write simple code but have been "blind copying" a bit to test if the code I'm looking at as examples even work... which so far few have.

    could you post the referenced example? the example PWM codes that i have access too are; dead_band, invert, and reload_interrupt. i got dead_band to compile but only with some tweaking, and it doesn't seem to line up with what I've been reading...
  • I've been kind of vague up to here so here is the gist of what I've been picking up so far. These are the general steps i need to move through to properly set up the PWM module, assuming I've included all the right headers and such;

    1. set the system clock.. etc.
    2. set the PWM clock from the system clock; PWMClockSet(PWM1_BASE, PWM_SYSCLK_DIV_1)
    3. enable the PWM Generator; PWMGenEnable(PWM1_BASE, PWM_GEN_1)
    4. configure The PWM generator; PWMGenConfigure(PWM1_BASE, PWM_GEN_1)
    5. set the period for the generator; PWMGenPeriodSet(PWM1_BASE, PWM_GEN_1, some unsigned long that is the period)
    6. enable PWM outputs; PWMOutputState(PWM1_BASE, PWM_OUT_n_BIT, TRUE) where n is 0-7
    7. set the pulse width; PWMPulseWidthSet(PWM1_BASE, PWM_OUT_2, unsigned long (ex. period/2))

    are these steps if implemented correctly enough to generate a PWM signal?
  • Hello Bryce,

    No. (Point 3 is in the end)

    1. set the system clock.. etc.
    >> Enable the PWM Module in the System Control using SysCtlPeripheralEnable, Enable the corresponding GPIO's as well
    >> Configure the GPIO to be PWM Pins
    2. set the PWM clock from the system clock; PWMClockSet(PWM1_BASE, PWM_SYSCLK_DIV_1)
    4. configure The PWM generator; PWMGenConfigure(PWM1_BASE, PWM_GEN_1)
    5. set the period for the generator; PWMGenPeriodSet(PWM1_BASE, PWM_GEN_1, some unsigned long that is the period)
    6. enable PWM outputs; PWMOutputState(PWM1_BASE, PWM_OUT_n_BIT, TRUE) where n is 0-7
    7. set the pulse width; PWMPulseWidthSet(PWM1_BASE, PWM_OUT_2, unsigned long (ex. period/2))
    3. enable the PWM Generator; PWMGenEnable(PWM1_BASE, PWM_GEN_1)

    Regards
    Amit
  • And - of course (and always) "avoid like the plague" any attempt @ PF0 or PD7 - both "blessed" by "special needs..."

    KISS dictates that you set-up/config only a single PWM Output - focus just on that - to speed, simplify & enhance your results.   Too much, too soon - never good - seldom succeeds.   (but great at introducing "FUD!")
     
    We note you've not once described how you are "monitoring" the MCU's output. Are you absolutely sure you're probing the correct pin - and that the chosen pin does indeed - reach a board-edge header?

  • ah thanks very much. How do i configure the GPIO to be PWM Pins?

    is it something like this?

    GPIOPinTypePWM(GPIO_PORTN_BASE, GPIO_PIN_2); 
    and do i need a line like this? 
    GPIOPinConfigure(GPIO_PF3_M1PWM7);
    the compiler fails to recognize this bit; "GPIO_PN3_M1PWM7" and i don't really understand what this line is doing...
  • is there a pin in particular (or pins) that you would suggest as the low hanging fruit?
  • Any pins other than PF0 or PD7.

    Indeed you must include both:

    ROM_GPIOPinTypePWM()
    ROM_GPIOPinConfigure()

    You are so close now - if still stuck - later tonight I'll provide exact code for a single PWM Generator. Which one appears on your board's header? (for your easy access)
  • Here - that which (I believe) to be the minimum code required to render a PWM output:  (assumes you've properly enabled both the port & that pwm generator)

    ROM_GPIOPinTypePWM(GPIO_PORTB_BASE, GPIO_PIN_6 | GPIO_PIN_7);

    ROM_GPIOPinConfigure(GPIO_PB6_M0PWM0);

    ROM_PWMGenConfigure(PWM0_BASE, PWM_GEN_0,

    ROM_PWMGenPeriodSet(PWM0_BASE, PWM_GEN_0

    ROM_PWMPulseWidthSet(PWM0_BASE, PWM_OUT_0,

    ROM_PWMGenEnable(PWM0_BASE, PWM_GEN_0

    ROM_PWMOutputState(PWM0_BASE, (PWM_OUT_0_BIT | PWM_OUT_1_BIT

    Note: Very carefully observe the parameters employed w/in each function!   That output state function (last one) confounds most due to the unique (krazed if you ask me) parameter description...   For code security reasons I've not "completed" the parameter "fill" - yet I've provided a good model!

    You do not have to employ the ROM function - but this has (always) worked for us - we ain't changing anytime soon.   Follow this code order - if you can use these pins - my hope was that these are "near universal!"  (work across most all of this vendor's MCUs...)

    Have copy/pasted "fast/furiously" - have concert tickets & now, "leave the building."    Bon chance mon ami.   (Verify could not hurt...)

  • ahhhh. so it didn't like the line ROM_GPIOPinConfigure(GPIO_PB6_M0PWM0); still....:

    "#20 identifier "GPIO_PB2_M0PWM0" is undefined"

    ps. i used b2 and b3 as they were mor easily accessible.

  • Good for you - persistence pays! Thank you for that needed Verify - appreciated.

    Might you "visit" the post, "What's Unclear" (atop the forum) help push it over 10K before midnight? Merci.
  • it still won't compile.... it doesn't like that one line of code.
  • Heres the code as is. i looked in the header files and there is no definition for GPIO_PB2_M0PWM0... =/ i have no idea how to resolve this

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /*Program to implement PWM, then perhaps make LED's dim and brighten, then modify the pulse width with the buttons*/
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    #include <stdbool.h>
    #include <stdint.h>
    #include "inc/hw_memmap.h"
    #include "driverlib/gpio.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/pwm.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/uart.h"
    #include "utils/uartstdio.h"
    #include "drivers/pinout.h"
    #include "driverlib/rom_map.h"

    //system clock variable
    uint32_t g_ui32SysClock;

    int main(void){

    /*1. set the system clock.. etc.
    * >> Enable the PWM Module in the System Control using SysCtlPeripheralEnable, Enable the corresponding GPIO's as well
    * >> Configure the GPIO to be PWM Pins
    * 2. set the PWM clock from the system clock; PWMClockSet(PWM1_BASE, PWM_SYSCLK_DIV_1)
    * 4. configure The PWM generator; PWMGenConfigure(PWM1_BASE, PWM_GEN_1,PWM_GEN_MODE_NO_SYNC)
    * 5. set the period for the generator; PWMGenPeriodSet(PWM1_BASE, PWM_GEN_1, some unsigned long that is the period)
    * 6. enable PWM outputs; PWMOutputState(PWM1_BASE, PWM_OUT_n_BIT, TRUE) where n is 0-7
    * 7. set the pulse width; PWMPulseWidthSet(PWM1_BASE, PWM_OUT_2, unsigned long (ex. period/2))
    * 3. enable the PWM Generator; PWMGenEnable(PWM1_BASE, PWM_GEN_1)*/

    //1. set the clock to run off of crystal at 25Mhz
    g_ui32SysClock = MAP_SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN \
    | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480), 120000000);

    //2. Enable the PWM Module in the System Control using
    //enable peripheral (port N)
    //configure pin as a PWM pin
    SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM0);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
    GPIOPinTypePWM(GPIO_PORTB_BASE, GPIO_PIN_2 | GPIO_PIN_3);




    >>>>>>>>>>>PROBLEM LINE>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>GPIOPinConfigure(GPIO_PB2_M0PWM0);




    //3. Set the pwm clock to the system clock/16
    PWMClockSet(PWM0_BASE, PWM_SYSCLK_DIV_16);

    //4. Configure the PWM generator
    PWMGenConfigure(PWM0_BASE, PWM_GEN_0, PWM_GEN_MODE_NO_SYNC);

    //5. Set the period for the generator
    //set pwm to run at 100hz . (N = (1 / f) * SysClk) ; (1 / 100Hz) * (120MHz/16) = 75000 cycles
    unsigned long period = 75000;
    PWMGenPeriodSet(PWM0_BASE, PWM_GEN_0, period);

    //6. Enable the PWM outputs
    // Enable the PWM0 Bit 0 (PB2) and Bit 1 (PB3) output signals.
    PWMOutputState(PWM0_BASE, (PWM_OUT_0_BIT | PWM_OUT_1_BIT), true);

    //7. set the pulse width
    PWMPulseWidthSet(PWM0_BASE, PWM_OUT_0, (period/2));

    //8. Enable the PWM Generator
    PWMGenEnable(PWM0_BASE, PWM_GEN_0);
    /*
    FOR COMPARISON!:
    ROM_PWMGenConfigure(PWM0_BASE, PWM_GEN_0,

    ROM_PWMGenPeriodSet(PWM0_BASE, PWM_GEN_0

    ROM_PWMPulseWidthSet(PWM0_BASE, PWM_OUT_0,

    ROM_PWMGenEnable(PWM0_BASE, PWM_GEN_0

    ROM_PWMOutputState(PWM0_BASE, (PWM_OUT_0_BIT | PWM_OUT_1_BIT*/


    }

  • Hello Bryce

    The PWM0 output pin 0 is on PF0 (locked pin). You would need to first unlock the pin, set the Commit Register and then call GPIOPinConfigure with the value GPIO_PF0_M0PWM0

    On how to unlock the following post will be helpful

    e2e.ti.com/.../374640

    Regards
    Amit
  • I'm not so sure that adding the complexity (and diversion) demanded by the use of PF0 makes great sense.    Instead - should you not (now) be able to some way/how find an appropriate PWM pin - and properly define it?   That's (really) all that's missing - isn't that so?

    Code extract I provided (which I listed as, "hope for universal") should work for LX4V & TM4C123 - but alas not your device.   (I recall your "ban" of 123 code - but in the "heat of battle" I thought a past, proven code dump "might" escape your wrath...

    To assist you in finding - then properly defining a PWM pin - here's how my firm went about that process:  (following directly from MCU datasheet)

    Thus - for TM4C (or LX4F) PB6 is indeed PWM Gen0's, 0 bit.    You are not forced to use that bit - and best that you "stick w/ PWM Gen0" - so as not to seriously disrupt my detailed code example.   Yet again - fighting the "endless" PF0 battle - steers you far from the PWM issue.   Seems an unnecessary & destructive diversion.

    You merely (now) have to choose an accessible bit (one "not" on the "banned bits list") - define it properly - and that should get you (at last) "On the Air."

  • Hey so here is the updated code. It now compiles cleanly! but there is no output on the PF0 pin... what am i doing wrong? i should be seeing a square wave on the o-scope now right?

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /*Program to implement PWM, then perhaps make LED's dim and brighten, then modify the pulse width with the buttons*/
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    #include <stdbool.h>
    #include <stdint.h>
    #include "inc/hw_types.h"
    #include "inc/hw_gpio.h"
    #include "inc/hw_memmap.h"
    #include "driverlib/gpio.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/pwm.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/uart.h"
    #include "utils/uartstdio.h"
    #include "drivers/pinout.h"
    #include "driverlib/rom_map.h"



    //system clock variable
    uint32_t g_ui32SysClock;

    int main(void){

    /*1. set the system clock.. etc.
    * >> Enable the PWM Module in the System Control using SysCtlPeripheralEnable, Enable the corresponding GPIO's as well
    * >> Configure the GPIO to be PWM Pins
    * 2. set the PWM clock from the system clock; PWMClockSet(PWM0_BASE, PWM_SYSCLK_DIV_1)
    * 4. configure The PWM generator; PWMGenConfigure(PWM0_BASE, PWM_GEN_1,PWM_GEN_MODE_NO_SYNC)
    * 5. set the period for the generator; PWMGenPeriodSet(PWM0_BASE, PWM_GEN_1, some unsigned long that is the period)
    * 6. enable PWM outputs; PWMOutputState(PWM0_BASE, PWM_OUT_n_BIT, TRUE) where n is 0-7
    * 7. set the pulse width; PWMPulseWidthSet(PWM0_BASE, PWM_OUT_2, unsigned long (ex. period/2))
    * 3. enable the PWM Generator; PWMGenEnable(PWM0_BASE, PWM_GEN_1)*/

    //1. set the clock to run off of crystal at 25Mhz
    g_ui32SysClock = MAP_SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN \
    | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480), 120000000);

    //1b. secret level; unlock port F0 so that we can use it!!! >=O
    HWREG(GPIO_PORTF_AHB_BASE+GPIO_O_LOCK) = GPIO_LOCK_KEY;
    HWREG(GPIO_PORTF_AHB_BASE+GPIO_O_CR) |= GPIO_PIN_0;

    //2. Enable the PWM Module in the System Control using
    //enable peripheral (port F)
    //configure pin as a PWM pin
    SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM0);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    GPIOPinTypePWM(GPIO_PORTF_BASE, GPIO_PIN_0 | GPIO_PIN_1);
    GPIOPinConfigure(GPIO_PF0_M0PWM0);

    //3. Set the pwm clock to the system clock/64
    PWMClockSet(PWM0_BASE, PWM_SYSCLK_DIV_64);

    //4. Configure the PWM generator
    PWMGenConfigure(PWM0_BASE, PWM_GEN_0, (PWM_GEN_MODE_DOWN | PWM_GEN_MODE_NO_SYNC));

    //5. Set the period for the generator
    //set pwm to run at 100hz . (N = (1 / f) * SysClk) ; (1 / 100Hz) * (120MHz/64) = 18750 cycles
    unsigned long period = 18750;
    PWMGenPeriodSet(PWM0_BASE, PWM_GEN_0, period);

    //6. Enable the PWM outputs
    // Enable the PWM1 Bit 0 (PF1) and Bit 1 (PF2) output signals.
    PWMOutputState(PWM0_BASE, (PWM_OUT_0_BIT | PWM_OUT_1_BIT), true);

    //7. set the pulse width
    PWMPulseWidthSet(PWM0_BASE, PWM_OUT_0, (period/2));

    //8. Enable the PWM Generator
    PWMGenEnable(PWM0_BASE, PWM_GEN_0);
    /*
    FOR COMPARISON!:
    ROM_PWMGenConfigure(PWM0_BASE, PWM_GEN_0,

    ROM_PWMGenPeriodSet(PWM0_BASE, PWM_GEN_0

    ROM_PWMPulseWidthSet(PWM0_BASE, PWM_OUT_0,

    ROM_PWMGenEnable(PWM0_BASE, PWM_GEN_0

    ROM_PWMOutputState(PWM0_BASE, (PWM_OUT_0_BIT | PWM_OUT_1_BIT*/

    }
  • Hello Bryce,

    The following two lines

    HWREG(GPIO_PORTF_AHB_BASE+GPIO_O_LOCK) = GPIO_LOCK_KEY;
    HWREG(GPIO_PORTF_AHB_BASE+GPIO_O_CR) |= GPIO_PIN_0;

    must be after

    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);

    The module must be enabled, then a check of the Peripheral Ready using while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOF)); and then the unlock.

    Regards
    Amit
  • cb1- said:
    Here - that which (I believe) to be the minimum code required to render a PWM output:  (assumes you've properly enabled both the port & that pwm generator)

    Agree w/Amit - note the quote from (atop) my past code listing - Devil very much in these details!

    I remain fearful of the use of any "banned bit."  (PF0/PD7 - so many have failed due to that unwise, cast in concrete, default to NMI decision!)

  • awesome, finally got it all running. Thanks so much CB1, and Amit. You've both been gentlemen and scholars, patiently working with a scrub like me!
    now to try modifying it... -_-

    here is the working code with a 50% duty cycle at 100Hz.
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /*Program to implement PWM, then perhaps make LED's dim and brighten, then modify the pulse width with the buttons*/
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    #include <stdbool.h>
    #include <stdint.h>
    #include "inc/hw_types.h"
    #include "inc/hw_gpio.h"
    #include "inc/hw_memmap.h"
    #include "driverlib/gpio.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/pwm.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/uart.h"
    #include "utils/uartstdio.h"
    #include "drivers/pinout.h"
    #include "driverlib/rom_map.h"


    //system clock variable
    uint32_t g_ui32SysClock;

    int main(void){

    //1. set the clock to run off of crystal at 25Mhz
    g_ui32SysClock = MAP_SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN \
    | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480), 120000000);

    //2. Enable the PWM Module in the System Control using
    //enable peripheral (port F)
    SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM0);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);

    //2b. secret level; unlock port F0 so that we can use it!!! >=O
    while(!(SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOF)));
    HWREG(GPIO_PORTF_AHB_BASE+GPIO_O_LOCK) = GPIO_LOCK_KEY;
    HWREG(GPIO_PORTF_AHB_BASE+GPIO_O_CR) |= GPIO_PIN_0;

    //configure pin as a PWM pin
    GPIOPinTypePWM(GPIO_PORTF_BASE, GPIO_PIN_0 | GPIO_PIN_1);
    GPIOPinConfigure(GPIO_PF0_M0PWM0);

    //3. Set the pwm clock to the system clock/64
    PWMClockSet(PWM0_BASE, PWM_SYSCLK_DIV_64);

    //4. Configure the PWM generator
    PWMGenConfigure(PWM0_BASE, PWM_GEN_0, (PWM_GEN_MODE_DOWN | PWM_GEN_MODE_NO_SYNC));

    //5. Set the period for the generator
    //set pwm to run at 100hz . (N = (1 / f) * SysClk) ; (1 / 100Hz) * (120MHz/64) = 18750 cycles
    unsigned long period = 18750;
    PWMGenPeriodSet(PWM0_BASE, PWM_GEN_0, period);

    //6. Enable the PWM outputs
    // Enable the PWM1 Bit 0 (PF1) and Bit 1 (PF2) output signals.
    PWMOutputState(PWM0_BASE, (PWM_OUT_0_BIT | PWM_OUT_1_BIT), true);

    //7. set the pulse width
    PWMPulseWidthSet(PWM0_BASE, PWM_OUT_0, (period/2));

    //8. Enable the PWM Generator
    PWMGenEnable(PWM0_BASE, PWM_GEN_0);
    }
  • Bryce Smith said:
    //6. Enable the PWM outputs
    // Enable the PWM1 Bit 0 (PF1) and Bit 1 (PF2) output signals.
    PWMOutputState(PWM0_BASE, (PWM_OUT_0_BIT | PWM_OUT_1_BIT), true);  

    Good for you!    But do look @ those red highlights w/in your comments!   That highlighted may not prove, "Good for Gov't Work!"  (3 errors reveal!)