Chapter 7 - Performance

advertisement
Chapter 7 - Performance
Understanding the PIC32 Clock and
learning to optimize the memory
interface for maximum performance
PIC32MX3xx Clock Module
Di Jasio - Programming 32-bit Microcontrollers in C
The OSCCON register
Di Jasio - Programming 32-bit Microcontrollers in C
Primary Oscillator Clock Chain
Input
Divider
8 MHz
1:2
Output
Divider
PLL
4 MHz
Di Jasio - Programming 32-bit Microcontrollers in C
1 x 18
72 MHz
1:1
System
Clock
72 MHz
PIC32MX3xx Configuration Settings
FPLLODIV = DIV_1
Divide by 1
FPLLODIV = DIV_2
Divide by 2
FPLLODIV = DIV_4
Divide by 4
FPLLODIV = DIV_8
Divide by 8
FPLLODIV = DIV_16
Divide by 16
FPLLODIV = DIV_32
Divide by 32
FPLLODIV = DIV_64
Divide by 64
FPLLODIV = DIV_256
Divide by 256
#pragma config POSCMOD=XT, FNOSC=PRIPLL
#pragma config FPLLIDIV=DIV_2, FPLLMUL=MUL_18, FPLLODIV=DIV_1
#pragma config FPBDIV=DIV_2, FWDTEN=OFF, CP=OFF, BWP=OFF
NOTE: All PIC32MX devices are currently released to operate at frequencies
up to 80 MHz. FPLLMUL = MUL_20 gives the required multiplier.
Di Jasio - Programming 32-bit Microcontrollers in C
Fast Fourier Transform
// input vector
unsigned char inB[N_FFT];
// input complex vector
float
xr[N_FFT];
float
xi[N_FFT];
// Fast Fourier Transformation
void FFT( void)
{
int
m, k, i, j;
float
a,b,c,d,wwr,wwi,pr,pi;
// FFT loop
m = N_FFT/2;
j = 0;
while( m > 0)
{ /* log(N) cycle */
k = 0;
while( k < N_FFT)
{ // batterflies loop
for( i=0; i<m; i++)
{ // batterfly
a = xr[i+k];
b = xi[i+k];
c = xr[i+k+m];
d = xi[i+k+m];
wwr = wr[i<<j];
wwi = wi[i<<j];
pr = a-c;
pi = b-d;
xr[i+k]
= a + c;
xi[i+k]
= b + d;
xr[i+k+m] = pr * wwr - pi * wwi;
xi[i+k+m] = pr * wwi + pi * wwr;
} // for i
k += m<<1 ;
} // while k
m >>= 1;
j++;
} // while m
} // FFT
Di Jasio - Programming 32-bit Microcontrollers in C
Windowing
// apply Hann window to input vector
void windowFFT( unsigned char *s)
{
int i;
float *xrp, *xip, *wwp;
// apply window to input signal
xrp=xr; xip=xi; wwp=ww;
for( i=0; i<N_FFT; i++)
{
*xrp++ = (*s++ - 128) * (*wwp++);
*xip++ = 0;
} // for i
} // windowFFT
Di Jasio - Programming 32-bit Microcontrollers in C
Computing Power and Scaling
void powerScale( unsigned char *r)
{
int i, j;
float t, max;
float xrp, xip;
// compute signal power (in place) and find maximum
max = 0;
for( i=0; i<N_FFT/2; i++)
{
j = rev[ i];
xrp = xr[ j];
xip = xi[ j];
t = xrp*xrp + xip*xip;
xr[ j]=t;
if ( t > max)
max = t;
}
// bit reversal, scaling of output vector as unsigned char
max = 255.0/max;
for( i=0; i<N_FFT/2; i++)
{
t = xr[ rev[i]] * max;
*r++ = t;
}
} // powerScale
Di Jasio - Programming 32-bit Microcontrollers in C
Initialization
// input vector
unsigned char inB[N_FFT];
volatile int inCount;
// rotation vectors
float
wr[N_FFT/2];
float
wi[N_FFT/2];
// bit reversal vector
short
rev[N_FFT/2];
// window
float
ww[N_FFT];
void initFFT( void)
{
int i, m, t, k;
float *wwp;
for(i=0; i<N_FFT/2; i++)
{
// rotations
wr[i] = cos(PI2N * i);
wi[i] = sin(PI2N * i);
// bit reversal
t = i;
m = 0;
k = N_FFT-1;
while (k>0)
{
m = (m << 1) + (t & 1);
t = t >> 1;
k = k >> 1;
}
rev[i] = m;
} // for i
// initialize Hanning window vector
for( wwp=ww, i=0; i<N_FFT; i++)
*wwp++ = 0.5 - 0.5 * cos(PI2N * i);
} // initFFT
Di Jasio - Programming 32-bit Microcontrollers in C
“FFT.h”
/*
** FFT.h
**
** power of two optimized algorithm
*/
#include <math.h>
#define N_FFT
256
// samples must be power of 2
#define PI2N
2 * M_PI / N_FFT
extern unsigned char inB[];
extern volatile int inCount;
// preparation of the rotation vectors
void initFFT( void);
// input window
void windowFFT( unsigned char *source);
// fast fourier transform
void FFT( void);
// compute power and scale output
void powerScale( unsigned char *dest);
Di Jasio - Programming 32-bit Microcontrollers in C
The Running Project
/*
** Run.c
**
*/
// configuration bit settings
#pragma config POSCMOD=XT, FNOSC=PRIPLL
#pragma config FPLLIDIV=DIV_2, FPLLMUL=MUL_18, FPLLODIV=DIV_1
#pragma config FWDTEN=OFF, CP=OFF, BWP=OFF
#include <p32xxxx.h>
#include <plib.h>
#include "fft.h“
main()
{
int i, t;
double f;
// 1. initializations
initFFT();
// test sinusoid
for (i=0; i<N_FFT; i++)
{
f = sin(2 * PI2N * i );
inB[ i] = 128 + ( unsigned char) (120.0 * f);
} // for
// 2. perform FFT algorithm
windowFFT( inB);
FFT();
powerScale( inB);
Di Jasio - Programming 32-bit Microcontrollers in C
// 3. infinite loop
while( 1);
} // main
Capturing Time
// init 32-bit timer4/5
OpenTimer45( T4_ON | T4_SOURCE_INT, 0);
// clear the 32-bit timer count
WriteTimer45( 0);
// insert FFT function calls here
// read the timer count
t = ReadTimer45();
Di Jasio - Programming 32-bit Microcontrollers in C
The CHECON Register
Di Jasio - Programming 32-bit Microcontrollers in C
Optimizing WaitStates
SYSTEMConfigWaitStatesAndPB(72000000L);
Di Jasio - Programming 32-bit Microcontrollers in C
Turning the Cache ON
SYSTEMConfigWaitStatesAndPB(72000000L);
CheKseg0CacheOn();
Di Jasio - Programming 32-bit Microcontrollers in C
Enabling Pre-Fetch
SYSTEMConfigWaitStatesAndPB(72000000L);
CheKseg0CacheOn();
mCheConfigure( CHECON | 0x30);
Di Jasio - Programming 32-bit Microcontrollers in C
Remove RAM Wait States
// configure PB frequency and the number of wait states
SYSTEMConfigWaitStatesAndPB(72000000L);
// enable the cache for max performance
CheKseg0CacheOn();
// enable instruction prefetch
mCheConfigure( CHECON | 0x30);
// disable RAM wait states
mBMXDisableDRMWaitState();
SYSTEMConfigPerformance( 72000000L);
Di Jasio - Programming 32-bit Microcontrollers in C
Data Control & Monitor Interface
Di Jasio - Programming 32-bit Microcontrollers in C
The FFT Output
Di Jasio - Programming 32-bit Microcontrollers in C
Download