All signal processing applications require some type of filtering, but hand coding filters is hardly a good use of your time. If you’re designing around an RL78 MCU, that needn’t be a problem.

Last June Renesas introduced the RL78 Digital Signal Controller Library – Fixed Point and Motor including source code. They’ve now released the RL78 Digital Signal Controller Library – Filter, including source code, generic specifications, detailed specifications for filter algorithm kernels, and guidelines for using the RL78/G14 DSCL Library API.

Since several C-language functions may be associated with a single DSP kernel, the library refers to separate DSP algorithms as kernels. The library (v. 1.0) supports three kernels:

  • A generic FIR filter;
  • A biquad IIR filter;
  • A single-pole IIR filter.

Implementing each of these filters typically requires a number of API function calls, which are explained in the library documentation.

For example, the block finite impulse response (FIR) filter kernel operates on a user selectable number of input samples and produces the same number of output samples each time it is invoked. The FIR kernel uses a handle to the filter of type r_dscl_firfilter_t. This handle is passed as part of the call to the filter. The data structure for the handle type is as follows:

typdef struct

{

uint16_t taps;    // number of filter taps

void *coefs;      // pointer to filter coefficients

void *state;      // pointer to filter state data, including

// the filter’s delay line and any other

// implementation-dependent state

uint16_t options; // option flags that may specify rounding,

// saturation, or other behaviors

} r_dscl_firfilter_t;

 

The filter must now be initialized and with the contents of the FIR state; the filter coefficients; and any other contents of the data structure. The following is an example showing initialization and run-time usage for the FIR Filter.

#define NUM_TAPS (64)

#define NUM_SAMPLES (200)

r_dscl_firfilter_t myFilterHandle; // instantiate a handle for this filter

vector_t myInput;

vector_t myOutput;

// Coefficients should be stored in time-reversed order

int16_t myCoeffs[NUM_TAPS] = {…};

// The input data buffer should contain previous (T-1) input samples (i.e. delay line)

// contiguous with the present (N) input samples

int16_t inputData[NUM_TAPS - 1 + NUM_SAMPLES];

int16_t outputData[NUM_SAMPLES];

int16_t myFIRFlags;

/*-------------- Set up the FIR filter ------------*/

myFilterHandle.taps = NUM_TAPS;

myFilterHandle.options = 0; // default

/* No need to call StateSize API for FIR */

myFilterHandle.state = (void *)&inputData[0];

// starting address of Delayline

/*----- Initialize the coefficients and internal state ------*/

myFilterHandle.coefs = (void *)myCoeffs;

myFIRFlags = R_DSCL_FIR_Init_i16i16(&myFilterHandle);

/*---------------- Set up the input/output ----------------*/

myInput.n = NUM_SAMPLES;

myInput.data = (void *)&inputData[NUM_TAPS - 1]; // starting address of

current input block

myOutput.data = (void *)outputData;

/*------------------ Wait for input data ------------------*/

/*--------------- Main library function call --------------*/

myFIRFlags = R_DSCL_FIR_i16i16 (&myFilterHandle, &myInput, &myOutput);

/*--------------- Output data are now ready ---------------

* Note: At this point myOutput.n holds the number of output samples generated

By the library, where the data are written to the array pointed to by myOutput.data.

*------------------------------------------------------------*/

The FIR function is implemented by fixed point using a series of multiply-accumulate operations. The function is optimized for speed at the cost of precision and overflow protection, so care must be taken with regard to overflow and scaling.

The new RL78 DSC filter library provides some very useful functionality. Consider linking the library into your next RL78/G14 project.