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.

[FAQ] CC2340R5: PWM example to produce a siren

Part Number: CC2340R5
Other Parts Discussed in Thread: BOOSTXL-AUDIO, SYSCONFIG

Hi,

Here is a step by step guide showing how to use the PWM example to produce a siren-like sound.

The example is based on F3 SDK 7.20.00.29.

A BOOSTXL-AUDIO is used to turn the PWM into sound (but other hardware could also be considered).

1- Apply the PWM patch by copy pasting the content of this zip file into the SDK installation (only required for SDK 7.20.00.29) /cfs-file/__key/communityserver-discussions-components-files/538/7532.pwm_5F00_patch.zip

2- If not already done, open CCS, create a workspace and configure it to use FreeRTOS.

3- Import the empty project from the SDK. For sanity, build the project once.

4- Copy in the project the files PWM.c, PWM.h, PWMTimerLPF3.c, PWMTimerLPF3.h. These files are in the folder <SDK>\source\ti\drivers.

5- Configure the PWM driver in SysConfig. Note that we enable the PWMsignal and its complementary channel (even if it not used here).


Once done, save, and close SysConfig.

6- Modify the code to use the PWM driver. I mainly used the code snippets provided in PWM.h.
All the changes are made in the empty.c file (the content should be used to replace the content of empty.c)

/*
 *  ======== empty.c ========
 */

/* For usleep() */
#include <unistd.h>
#include <stdint.h>
#include <stddef.h>

/* Driver Header files */
#include <ti/drivers/GPIO.h>
#include <ti/drivers/PWM.h>

/* Driver configuration */
#include "ti_drivers_config.h"

/*
 *  ======== mainThread ========
 */
void *mainThread(void *arg0)
{
    /* 10 ms delay */
    uint32_t time = 10000; //us

    const uint32_t PWM_PERIOD_MIN = 1000; //1kHz
    const uint32_t PWM_PERIOD_MAX = 8000; //8kHz
    const uint32_t PWM_PERIOD_STEP = 10; //10Hz

    int pwmIncrement = PWM_PERIOD_STEP;
    uint32_t pwmPeriodValue = PWM_PERIOD_MIN;

    /* Call driver init functions */
    GPIO_init();

    /* Configure the LED pin */
    GPIO_setConfig(CONFIG_GPIO_LED_0, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);

    /* Turn on user LED */
    GPIO_write(CONFIG_GPIO_LED_0, CONFIG_GPIO_LED_ON);

    PWM_Handle pwm;
    PWM_Params pwmParams;

    PWM_init();

    PWM_Params_init(&pwmParams);
    pwmParams.idleLevel = PWM_IDLE_LOW;
    pwmParams.periodUnits = PWM_PERIOD_HZ;
    pwmParams.periodValue = 1000;
    pwmParams.dutyUnits = PWM_DUTY_FRACTION;
    pwmParams.dutyValue = (uint32_t) (((uint64_t) PWM_DUTY_FRACTION_MAX * 50) / 100); // 50% duty cycle

    pwm = PWM_open(CONFIG_PWM_0, &pwmParams);

    PWM_start(pwm);

    if (pwm == NULL) {
        // PWM_open() failed
        while (1);
    }

    while (1)
    {
        usleep(time);
        GPIO_toggle(CONFIG_GPIO_LED_0);

        pwmPeriodValue += pwmIncrement;

        if(pwmPeriodValue < PWM_PERIOD_MIN)
        {
            pwmIncrement = PWM_PERIOD_STEP;
            pwmPeriodValue += pwmIncrement;
        }
        else if(pwmPeriodValue > PWM_PERIOD_MAX)
        {
            pwmIncrement = -PWM_PERIOD_STEP;
            pwmPeriodValue += pwmIncrement;
        }

        PWM_setPeriod(pwm, pwmPeriodValue);
    }
}

7- Build and run the code

8- Results:

I hope this will help,

Best regards,

  • Hi Clement,

    Thank you for sharing !!

  • Hi ,

    thanks for kindly posting this also on the other thread so I got the notification and for the like to my modified example, much appreciated! Yours is a very fun idea that keeps everything simple, too bad I don't have the audio BP, I didn't even know it existed. I haven't started porting to the PWM driver (although I have some preliminary findings already, like the implementation is different from other SimpleLink drivers or maybe it's just a Sysconfig 1.17.0  issue so I have excluded the driver config files from it and manipulating them. because I also need to sort out some LGPTimer intricacies first, like that I need some tight (<30μs) timings/interrupts for my app framework and I have to get them done in hardware since raising the FreeRTOS tick frequency would result in too much overhead. I have to test the interactions with the BLE Stack and the driver is different from what I was modeling on (still SimpleLink/FreeRTOS but on the MSP432, different peripheral module, different implementation and different core). This is OT, however, and I will share my issues and ask my questions in a separate thread(s).

    Kind regards,

    Stefano

  • Forgot to ask, since it's a fun example, why not post a short video with sound, so the poor guys like us who don't have unlimited access to exotic BPs can enjoy :-)?