You can set the pwm for each channel with set_widths() at any time in the code.
The carrier frequency and precision can be modified by changing PWM_MAX_WIDTH in common_defs.h
A slightly higher (25.773kHz) carrier frequency could be achieved by refactoring the code so to use only one byte per channel, which would clearly limit PWM_MAX_WIDTH <= 255
An even higher (30.864kHz)) carrier frequecny could be achieved by taking the LBBO operation out of USER_LOOP in pru_pwm.p, however this would mean that some PWM values (either close to 100% or close to 0%) could not be achieved
 
#include <GPIOcontrol.h>
#include "prussdrv.h"
#include "pruss_intc_mapping.h"
#include <string.h>
#include "pru_pwm_bin.h"
#include "common_defs.h"
 
typedef uint16_t count_t;
 
uint32_t *gPRUCommunicationMem = 0;
 
bool load_pru(int pru_number);                  
bool start_pru(int pru_number);                 
void set_widths(count_t* counts, unsigned int length);
int gPruNumber;
 
{
        
                gPruNumber = 1;
        else
                gPruNumber = 0;
}
 
{
        
        if(!load_pru(gPruNumber)) {
                printf("Error: could not initialise user PRU code.\n");
                return false;
        }
 
        unsigned int length = 8;
        count_t counts[length];
        memset(gPRUCommunicationMem, 0, 128);
 
        for(unsigned int n = 0; n < length; ++n) {
                counts[n] = PWM_MAX_WIDTH * (1+n)/(float)length;
        }
        set_widths(counts, length);
 
        if(!start_pru(gPruNumber)) {
                printf("Error: could not start user PRU code.\n");
                return false;
        }
        return true;
}
 
{
 
 
}
 
{
    
    prussdrv_pru_disable(gPruNumber);
}
 
bool load_pru(int pru_number)
{
        void *pruMemRaw;
        uint32_t *pruMemInt;
 
        
 
    
    if(prussdrv_open(PRU_EVTOUT_1)) {
        rt_printf("Failed to open user-side PRU driver\n");
        return false;
    }
 
        
        prussdrv_map_prumem(PRUSS0_SHARED_DATARAM, (void **)&pruMemRaw);
 
        
        pruMemInt = (uint32_t *)pruMemRaw;
        gPRUCommunicationMem = &pruMemInt[0x800/sizeof(uint32_t)];
 
        return true;
}
 
bool start_pru(int pru_number)
{
        if(prussdrv_exec_code(pru_number, PRUcode, sizeof(PRUcode))) {
                rt_printf("Failed to execute user-side PRU code\n");
                return false;
        }
 
        return true;
}
 
void set_widths(count_t* counts, unsigned int length)
{
        
        memcpy(&gPRUCommunicationMem[PRU_COMM_USER_WIDTH], counts, length * sizeof(counts[0]));
}
void Bela_userSettings(BelaInitSettings *settings)
Initialise the data structure containing settings for Bela.
Definition render.cpp:64
void render(BelaContext *context, void *userData)
User-defined callback function to process audio and sensor data.
Definition render.cpp:68
bool setup(BelaContext *context, void *userData)
User-defined initialisation function which runs before audio rendering begins.
Definition render.cpp:51
void cleanup(BelaContext *context, void *userData)
User-defined cleanup function which runs when the program finishes.
Definition render.cpp:96
Structure holding audio and sensor settings and pointers to I/O data buffers.
Definition Bela.h:231
Structure containing initialisation parameters for the real-time audio control system.
Definition Bela.h:441
int pruNumber
Which PRU (0 or 1) the code should run on.
Definition Bela.h:483