Home : I/O Peripherals Library | Pulse Width Modulation

Description

<TODO>

Naming Conventions

<TODO>

Interface Functions

<TODO>

Example Usage

<TODO>

Configuration

<TODO>

Source Files

xperipherals_pwm.h PWM peripheral interface
xperipherals_pwm_1.xc PWM peripheral #1 implementation
xperipherals_pwm_2.xc PWM peripheral #2 implementation
xperipherals_pwm_3.xc PWM peripheral #3 implementation

Source Listings

xperipherals_pwm.h

#ifndef XPERIPHERALS_PWM__INCLUDED
#define XPERIPHERALS_PWM__INCLUDED

#include "xsystem_types.h"

// These must be defined in "xconfig.h" for each peripheral bus being used
//
// XPERIPHERALS_PWM_n                   No value
// XPERIPHERALS_PWM_n__TILE_NUMBER      Integer, XS1 tile number
// XPERIPHERALS_PWM_n__CHANNEL_COUNT    Integer, 1 ... 6
// XPERIPHERALS_PWM_n__BITS_PER_SAMPLE  Ingteger, 8 ... 16
// XPERIPHERALS_PWM_n__EDGE_ALIGNMENT   0 for left, 1 for centered
// XPERIPHERALS_PWM_n__BIT_CLOCK        XS1 clock-block identifier
// XPERIPHERALS_PWM_n__PWM1_PORT        XS1 port identifier
// XPERIPHERALS_PWM_n__PWM2_PORT        XS1 port identifier
// XPERIPHERALS_PWM_n__PWM3_PORT        XS1 port identifier
// XPERIPHERALS_PWM_n__PWM4_PORT        XS1 port identifier
// XPERIPHERALS_PWM_n__PWM5_PORT        XS1 port identifier
// XPERIPHERALS_PWM_n__PWM6_PORT        XS1 port identifier

// Data Transfer Sequence for One PWM Output Cycle.
// Note: Two writes are required to output a full sample.
//
// xperipherals_pwm_N__start_cycle ();
// xperipherals_pwm_N__write_sample( pwm output sample ); same sample as previous write
// xperipherals_pwm_N__write_sample( pwm output sample - same sample as previous write )
// xperipherals_pwm_N__end_cycle   ();

#define XPERIPHERALS_PWM__INTERFACE( N ) \
\
void xperipherals_pwm_##N##__initialize ( void ); \
void xperipherals_pwm_##N##__start_cycle( void ); \
void xperipherals_pwm_##N##__write_left ( xuint pwm_sample ); \
void xperipherals_pwm_##N##__write_right( xuint pwm_sample ); \
void xperipherals_pwm_##N##__end_cycle  ( void );

XPERIPHERALS_PWM__INTERFACE( 1 )
XPERIPHERALS_PWM__INTERFACE( 2 )
XPERIPHERALS_PWM__INTERFACE( 3 )

#endif

xperipherals_pwm_1.xc

#include <xs1.h>
#include <platform.h>
#include <xclib.h>
#include <print.h>

#include "xperipherals_pwm.h"

#ifdef XPERIPHERALS_PWM_1

extern clock XPERIPHERALS_pwm_1__bit_clock;
on tile[XPERIPHERALS_PWM_1__TILE_NUMBER] : out buffered port:32 _xperipherals_pwm_1__pwm_port[XPERIPHERALS_PWM_1__CHANNEL_COUNT] =
{
    #if XPERIPHERALS_PWM_1__CHANNEL_COUNT >= 1
    XPERIPHERALS_PWM_1__OUTPUT1_PORT
    #endif
    #if XPERIPHERALS_PWM_1__CHANNEL_COUNT >= 2
    , XPERIPHERALS_PWM_2__OUTPUT1_PORT
    #endif
    #if XPERIPHERALS_PWM_1__CHANNEL_COUNT >= 3
    , XPERIPHERALS_PWM_3__OUTPUT1_PORT
    #endif
    #if XPERIPHERALS_PWM_1__CHANNEL_COUNT >= 4
    , XPERIPHERALS_PWM_4__OUTPUT1_PORT
    #endif
    #if XPERIPHERALS_PWM_1__CHANNEL_COUNT >= 5
    , XPERIPHERALS_PWM_5__OUTPUT1_PORT
    #endif
    #if XPERIPHERALS_PWM_1__CHANNEL_COUNT >= 6
    , XPERIPHERALS_PWM_6__OUTPUT1_PORT
    #endif
};

static xuint _xperipherals_pwm_1__first_pass;
static xuint _xperipherals_pwm_1__sample_num;
static xuint _xperipherals_pwm_1__bit_time;
static xuint _xperipherals_pwm_1__wire_index;

void XPERIPHERALS_pwm__initialize( void )
{
    for( int i = 0; i < XPERIPHERALS_PWM_1__CHANNEL_COUNT; ++i )
    {
        configure_out_port_no_ready( _xperipherals_pwm_1__pwm_port[i], XPERIPHERALS_pwm_1__bit_clock, 0 );
            clearbuf( _xperipherals_pwm_1__pwm_port[i] );
    }
        _xperipherals_pwm_1__first_pass = TRUE;
        _xperipherals_pwm_1__sample_num = 0;
        _xperipherals_pwm_1__wire_index = 0;
}

static void _xperipherals_pwm__synchronize( void )
{
    _xperipherals_pwm_1__bit_time = 100;
    // Clear the output buffer for each port so that no output is present (so that FIFO buffers are empty)
    #pragma loop unroll
    for( int i = 0; i < XPERIPHERALS_PWM_1__CHANNEL_COUNT; ++i ) clearbuf( _xperipherals_pwm_1__pwm_port[i] );
    _xperipherals_pwm_1__first_pass = FALSE;
}

static unsigned int _xperipherals_pwm__pattern[32] =
{
    0x80000000,0xC0000000,0xE0000000,0xF0000000,0xF8000000,0xFC000000,0xFE000000,0xFF000000,
    0xFF800000,0xFFC00000,0xFFE00000,0xFFF00000,0xFFF80000,0xFFFC0000,0xFFFE0000,0xFFFF0000,
    0xFFFF8000,0xFFFFC000,0xFFFFE000,0xFFFFF000,0xFFFFF800,0xFFFFFC00,0xFFFFFE00,0xFFFFFF00,
    0xFFFFFF80,0xFFFFFFC0,0xFFFFFFE0,0xFFFFFFF0,0xFFFFFFF8,0xFFFFFFFC,0xFFFFFFFE,0xFFFFFFFE,
};

#define _XPERIPHERALS_PWM_1__BITS_PER_PERIOD  (1<<XPERIPHERALS_PWM_1__BITS_PER_SAMPLE)

void XPERIPHERALS_pwm_1__start_cycle( void )
{
    _xperipherals_pwm_1__wire_index = 0;
    #if XPERIPHERALS_PWM_1__EDGE_ALIGNMENT == 0
    _xperipherals_pwm_1__bit_time += 1 * _XPERIPHERALS_PWM_1__BITS_PER_PERIOD; // Left Aligned
    #endif
    #if XPERIPHERALS_PWM_1__EDGE_ALIGNMENT == 1
    _xperipherals_pwm_1__bit_time += 2 * _XPERIPHERALS_PWM_1__BITS_PER_PERIOD; // Center Aligned
    #endif
}

void XPERIPHERALS_pwm_1__write_left( xuint pwm_sample )
{
    if( pwm_sample-- > 0 )
        _xperipherals_pwm_1__pwm_port[_xperipherals_pwm_1__wire_index++] @
            (_xperipherals_pwm_1__bit_time - 32 - (pwm_sample & 0xFFFFFFE0))
                <: _xperipherals_pwm__pattern[pwm_sample & 31];
}

void XPERIPHERALS_pwm_1__write_right( xuint pwm_sample )
{
    if( pwm_sample-- > 0 )
        _xperipherals_pwm_1__pwm_port[_xperipherals_pwm_1__wire_index++] @
            (_xperipherals_pwm_1__bit_time + (pwm_sample & 0xFFFFFFE0))
                <: bitrev( _xperipherals_pwm__pattern[pwm_sample & 31] );
}

#endif

xperipherals_pwm_2.xc

#include <xs1.h>
#include <platform.h>
#include <xclib.h>
#include <print.h>

#include "xperipherals_pwm.h"

#ifdef XPERIPHERALS_PWM_2

extern clock XPERIPHERALS_pwm_2__bit_clock;
on tile[XPERIPHERALS_PWM_2__TILE_NUMBER] : out buffered port:32 _xperipherals_pwm_2__pwm_port[XPERIPHERALS_PWM_2__CHANNEL_COUNT] =
{
    #if XPERIPHERALS_PWM_2__CHANNEL_COUNT >= 1
    XPERIPHERALS_PWM_2__OUTPUT1_PORT
    #endif
    #if XPERIPHERALS_PWM_2__CHANNEL_COUNT >= 2
    , XPERIPHERALS_PWM_2__OUTPUT1_PORT
    #endif
    #if XPERIPHERALS_PWM_2__CHANNEL_COUNT >= 3
    , XPERIPHERALS_PWM_3__OUTPUT1_PORT
    #endif
    #if XPERIPHERALS_PWM_2__CHANNEL_COUNT >= 4
    , XPERIPHERALS_PWM_4__OUTPUT1_PORT
    #endif
    #if XPERIPHERALS_PWM_2__CHANNEL_COUNT >= 5
    , XPERIPHERALS_PWM_5__OUTPUT1_PORT
    #endif
    #if XPERIPHERALS_PWM_2__CHANNEL_COUNT >= 6
    , XPERIPHERALS_PWM_6__OUTPUT1_PORT
    #endif
};

static xuint _xperipherals_pwm_2__first_pass;
static xuint _xperipherals_pwm_2__sample_num;
static xuint _xperipherals_pwm_2__bit_time;
static xuint _xperipherals_pwm_2__wire_index;

void XPERIPHERALS_pwm__initialize( void )
{
    for( int i = 0; i < XPERIPHERALS_PWM_2__CHANNEL_COUNT; ++i )
    {
        configure_out_port_no_ready( _xperipherals_pwm_2__pwm_port[i], XPERIPHERALS_pwm_2__bit_clock, 0 );
            clearbuf( _xperipherals_pwm_2__pwm_port[i] );
    }
        _xperipherals_pwm_2__first_pass = TRUE;
        _xperipherals_pwm_2__sample_num = 0;
        _xperipherals_pwm_2__wire_index = 0;
}

static void _xperipherals_pwm__synchronize( void )
{
    _xperipherals_pwm_2__bit_time = 100;
    // Clear the output buffer for each port so that no output is present (so that FIFO buffers are empty)
    #pragma loop unroll
    for( int i = 0; i < XPERIPHERALS_PWM_2__CHANNEL_COUNT; ++i ) clearbuf( _xperipherals_pwm_2__pwm_port[i] );
    _xperipherals_pwm_2__first_pass = FALSE;
}

static unsigned int _xperipherals_pwm__pattern[32] =
{
    0x80000000,0xC0000000,0xE0000000,0xF0000000,0xF8000000,0xFC000000,0xFE000000,0xFF000000,
    0xFF800000,0xFFC00000,0xFFE00000,0xFFF00000,0xFFF80000,0xFFFC0000,0xFFFE0000,0xFFFF0000,
    0xFFFF8000,0xFFFFC000,0xFFFFE000,0xFFFFF000,0xFFFFF800,0xFFFFFC00,0xFFFFFE00,0xFFFFFF00,
    0xFFFFFF80,0xFFFFFFC0,0xFFFFFFE0,0xFFFFFFF0,0xFFFFFFF8,0xFFFFFFFC,0xFFFFFFFE,0xFFFFFFFE,
};

#define _XPERIPHERALS_PWM_2__BITS_PER_PERIOD  (1<<XPERIPHERALS_PWM_2__BITS_PER_SAMPLE)

void XPERIPHERALS_pwm_2__start_cycle( void )
{
    _xperipherals_pwm_2__wire_index = 0;
    #if XPERIPHERALS_PWM_2__EDGE_ALIGNMENT == 0
    _xperipherals_pwm_2__bit_time += 1 * _XPERIPHERALS_PWM_2__BITS_PER_PERIOD; // Left Aligned
    #endif
    #if XPERIPHERALS_PWM_2__EDGE_ALIGNMENT == 1
    _xperipherals_pwm_2__bit_time += 2 * _XPERIPHERALS_PWM_2__BITS_PER_PERIOD; // Center Aligned
    #endif
}

void XPERIPHERALS_pwm_2__write_left( xuint pwm_sample )
{
    if( pwm_sample-- > 0 )
        _xperipherals_pwm_2__pwm_port[_xperipherals_pwm_2__wire_index++] @
            (_xperipherals_pwm_2__bit_time - 32 - (pwm_sample & 0xFFFFFFE0))
                <: _xperipherals_pwm__pattern[pwm_sample & 31];
}

void XPERIPHERALS_pwm_2__write_right( xuint pwm_sample )
{
    if( pwm_sample-- > 0 )
        _xperipherals_pwm_2__pwm_port[_xperipherals_pwm_2__wire_index++] @
            (_xperipherals_pwm_2__bit_time + (pwm_sample & 0xFFFFFFE0))
                <: bitrev( _xperipherals_pwm__pattern[pwm_sample & 31] );
}

#endif

xperipherals_pwm_3.xc

#include <xs1.h>
#include <platform.h>
#include <xclib.h>
#include <print.h>

#include "xperipherals_pwm.h"

#ifdef XPERIPHERALS_PWM_3

extern clock XPERIPHERALS_pwm_3__bit_clock;
on tile[XPERIPHERALS_PWM_3__TILE_NUMBER] : out buffered port:32 _xperipherals_pwm_3__pwm_port[XPERIPHERALS_PWM_3__CHANNEL_COUNT] =
{
    #if XPERIPHERALS_PWM_3__CHANNEL_COUNT >= 1
    XPERIPHERALS_PWM_3__OUTPUT1_PORT
    #endif
    #if XPERIPHERALS_PWM_3__CHANNEL_COUNT >= 2
    , XPERIPHERALS_PWM_3__OUTPUT1_PORT
    #endif
    #if XPERIPHERALS_PWM_3__CHANNEL_COUNT >= 3
    , XPERIPHERALS_PWM_3__OUTPUT1_PORT
    #endif
    #if XPERIPHERALS_PWM_3__CHANNEL_COUNT >= 4
    , XPERIPHERALS_PWM_4__OUTPUT1_PORT
    #endif
    #if XPERIPHERALS_PWM_3__CHANNEL_COUNT >= 5
    , XPERIPHERALS_PWM_5__OUTPUT1_PORT
    #endif
    #if XPERIPHERALS_PWM_3__CHANNEL_COUNT >= 6
    , XPERIPHERALS_PWM_6__OUTPUT1_PORT
    #endif
};

static xuint _xperipherals_pwm_3__first_pass;
static xuint _xperipherals_pwm_3__sample_num;
static xuint _xperipherals_pwm_3__bit_time;
static xuint _xperipherals_pwm_3__wire_index;

void XPERIPHERALS_pwm__initialize( void )
{
    for( int i = 0; i < XPERIPHERALS_PWM_3__CHANNEL_COUNT; ++i )
    {
        configure_out_port_no_ready( _xperipherals_pwm_3__pwm_port[i], XPERIPHERALS_pwm_3__bit_clock, 0 );
            clearbuf( _xperipherals_pwm_3__pwm_port[i] );
    }
        _xperipherals_pwm_3__first_pass = TRUE;
        _xperipherals_pwm_3__sample_num = 0;
        _xperipherals_pwm_3__wire_index = 0;
}

static void _xperipherals_pwm__synchronize( void )
{
    _xperipherals_pwm_3__bit_time = 100;
    // Clear the output buffer for each port so that no output is present (so that FIFO buffers are empty)
    #pragma loop unroll
    for( int i = 0; i < XPERIPHERALS_PWM_3__CHANNEL_COUNT; ++i ) clearbuf( _xperipherals_pwm_3__pwm_port[i] );
    _xperipherals_pwm_3__first_pass = FALSE;
}

static unsigned int _xperipherals_pwm__pattern[32] =
{
    0x80000000,0xC0000000,0xE0000000,0xF0000000,0xF8000000,0xFC000000,0xFE000000,0xFF000000,
    0xFF800000,0xFFC00000,0xFFE00000,0xFFF00000,0xFFF80000,0xFFFC0000,0xFFFE0000,0xFFFF0000,
    0xFFFF8000,0xFFFFC000,0xFFFFE000,0xFFFFF000,0xFFFFF800,0xFFFFFC00,0xFFFFFE00,0xFFFFFF00,
    0xFFFFFF80,0xFFFFFFC0,0xFFFFFFE0,0xFFFFFFF0,0xFFFFFFF8,0xFFFFFFFC,0xFFFFFFFE,0xFFFFFFFE,
};

#define _XPERIPHERALS_PWM_3__BITS_PER_PERIOD  (1<<XPERIPHERALS_PWM_3__BITS_PER_SAMPLE)

void XPERIPHERALS_pwm_3__start_cycle( void )
{
    _xperipherals_pwm_3__wire_index = 0;
    #if XPERIPHERALS_PWM_3__EDGE_ALIGNMENT == 0
    _xperipherals_pwm_3__bit_time += 1 * _XPERIPHERALS_PWM_3__BITS_PER_PERIOD; // Left Aligned
    #endif
    #if XPERIPHERALS_PWM_3__EDGE_ALIGNMENT == 1
    _xperipherals_pwm_3__bit_time += 2 * _XPERIPHERALS_PWM_3__BITS_PER_PERIOD; // Center Aligned
    #endif
}

void XPERIPHERALS_pwm_3__write_left( xuint pwm_sample )
{
    if( pwm_sample-- > 0 )
        _xperipherals_pwm_3__pwm_port[_xperipherals_pwm_3__wire_index++] @
            (_xperipherals_pwm_3__bit_time - 32 - (pwm_sample & 0xFFFFFFE0))
                <: _xperipherals_pwm__pattern[pwm_sample & 31];
}

void XPERIPHERALS_pwm_3__write_right( xuint pwm_sample )
{
    if( pwm_sample-- > 0 )
        _xperipherals_pwm_3__pwm_port[_xperipherals_pwm_3__wire_index++] @
            (_xperipherals_pwm_3__bit_time + (pwm_sample & 0xFFFFFFE0))
                <: bitrev( _xperipherals_pwm__pattern[pwm_sample & 31] );
}

#endif