EEE527 Embedded Systems Lecture 5: Chapter 6 and7 Configuration & memory Ian McCrumRoom 5B18, Tel: voice mail on 6 th ring Web site: Adapted from the text “Programming 32-bit Microcontrollers in C – Exploring the PIC32, © 2008.” Lucio di Jasio Adapted from the datasheet “PIC32MX1xx-2xx__DS61168E( ) “ from
Strings.c Example /* ** Strings */ #include // 1. variable declarations const char a[] = "Exploring the PIC32"; char b[100] = "Initialized"; // 2. main program main() { strcpy( b, "MPLAB C32");// assign new content to b } // main
Using the Watch Window Under the menu D)ebug->New watch window Set a breakpoint on line 11 and click “Debug Main Project
Experiment with the Watch Window Note the initialisation of a[ ]
Experiment with the Watch Window Note the new value of all 100 elements of b[ ]
Disassembly Listing (W)indow->Output->disassembly Listing 7: const char a[] = "Exploring the PIC32"; 9D C029D00 LUI V0, D00026C 8C4603CC LW A2, 972(V0) 9D CC ADDIU V1, V0, 972 9D C LW A1, 4(V1) 9D CC ADDIU V1, V0, 972 9D00027C 8C LW A0, 8(V1) 9D CC ADDIU V1, V0, 972 9D C63000C LW V1, 12(V1) 9D CC ADDIU V0, V0, 972 9D00028C 8C LW V0, 16(V0) 9D AFC60010 SW A2, 16(S8) 9D AFC50014 SW A1, 20(S8) 9D AFC40018 SW A0, 24(S8) 9D00029C AFC3001C SW V1, 28(S8) 9D0002A0 AFC20020 SW V0, 32(S8)
Disassembly Listing (W)indow->Output->disassembly Listing 8: char b[100] = "Initialized"; 9D0002A4 3C029D00 LUI V0, D0002A8 8C4403E0 LW A0, 992(V0) 9D0002AC E0 ADDIU V1, V0, 992 9D0002B0 8C LW V1, 4(V1) 9D0002B E0 ADDIU V0, V0, 992 9D0002B8 8C LW V0, 8(V0) 9D0002BC AFC40024 SW A0, 36(S8) 9D0002C0 AFC30028 SW V1, 40(S8) 9D0002C4 AFC2002C SW V0, 44(S8) 9D0002C8 27C30030 ADDIU V1, S8, 48 9D0002CC ADDIU V0, ZERO, 88 9D0002D ADDU A0, V1, ZERO 9D0002D ADDU A1, ZERO, ZERO 9D0002D ADDU A2, V0, ZERO 9D0002DC 0F4000C6 JAL 0x9D D0002E NOP
Disassembly Listing (W)indow->Output->disassembly Listing 9: // 2. main program 10: strcpy( b, "MPLAB C32");// assign new content to b 9D0002E4 27C20024 ADDIU V0, S8, 36 9D0002E ADDU A0, V0, ZERO 9D0002EC 3C029D00 LUI V0, D0002F C0 ADDIU A1, V0, 960 9D0002F A ADDIU A2, ZERO, 10 9D0002F8 0F JAL 0x9D D0002FC NOP 11: } // main
Looking at the “Map” In the folders./build/default/production beneath project.X
Looking at the “Map” In the folders./build/default/production beneath project.X
Memory Map Sections There are 64 entries in the vector table, most are just default handlers
Memory Map Sections
The Memory Window Under W)indow->Pic memory Views->data
The Memory Window Under W)indow->Pic memory Views->Configuration
Advanced Material Fixed Translation Map User and Kernel Virtual Memory Maps
The PIC32 Fixed Translation Map
Phisical Addressing Space RAM FLASH SFRSFR SFRSFR 0x x1D x1F BOOTBOOT BOOTBOOT 0x1FC000000xFFFFFFFF
RAM Partitioning Kernel RAM (Data) Kernel RAM (Data) 0x BMXDUDBA0xBF BMXDUDBA User RAM (Data) User RAM (Data) 0xFFFFFFFF User RAM (Prog) Kernel RAM (Prog) Kernel RAM (Prog) BMXDKDBA0xBF BMXDUPBA
User Mode Virtual Memory Map 0x7F BMXDUDBA User RAM (Data) User RAM (Data) 0x7F BMXDUPBA User RAM (Prog) User RAM (Prog) 0x User SpaceKernel Space User FLAS H Generate an immediate exception if access is attempted! 0xFFFFFFFF 0x x7D000000
Kernel Mode Virtual Memory Map 0x BMXDKPBA User Space Kernel Space FLAS H Cached (Kseg0 ) FLAS H Cached (Kseg0 ) 0xFFFFFFFF0x x9D RAM (Data) RAM (Data) RAM (Prog) RAM (Prog) FLAS H Un- Cached (Kseg1 ) FLAS H Un- Cached (Kseg1 ) 0xBD x SFRSFR SFRSFR 0xBF BOOTBOOT BOOTBOOT 0xBFC00000
Chapter 7 - Performance Understanding the PIC32 Clock and learning to optimize the memory interface for maximum performance
PIC32MX3xx Clock Module
The OSCCON register
Primary Oscillator Clock Chain Input Divider Input Divider PLL Output Divider Output Divider 4 MHz72 MHz8 MHz 1 : 21 x 181 : 1 System Clock 72 MHz
PIC32MX3xx Configuration Settings #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. Use the data sheet as well as the HELP files in MPLAB X
Typical config statements if using pickit3 // Include Header Files #include // will include chip specific header file #include / include peripheral library functions // Configuration Bits #pragma config FNOSC = FRCPLL // Internal Fast RC oscillator (8 MHz) w/ PLL #pragma config FPLLIDIV = DIV_2 // Divide FRC before PLL (now 4 MHz) #pragma config FPLLMUL = MUL_20 // PLL Multiply (now 80 MHz) #pragma config FPLLODIV = DIV_2 // Divide After PLL (now 40 MHz) #pragma config FWDTEN = OFF // Watchdog Timer Disabled #pragma config ICESEL = ICS_PGx1 // ICE/ICD Comm Channel Select #pragma config JTAGEN = OFF // Disable JTAG #pragma config FSOSCEN = OFF // Disable Secondary Oscillator #pragma config FPBDIV = DIV_1 // PBCLK = SYCLK // Defines #define SYSCLK L
The datasheet DS_PICMX1xx-2xx.pdf
The datasheet DS_PICMX1xx-2xx.pdf
Please look at the Handout – page 94 of Datasheet DS61168E.pdf PIC32MX1xx-2xx family
As well as understanding the diagrams of the clock and peripheral circuitry, and understanding what patterns of bits to put in the various SFRs you also need to know what name XC32’s include files have given the SFR and the bit or bit groups in each register. C:\Program Files (x86)\Microchip\xc32\v1.21\ pic32-libs\include\proc\p32mx250f128b.h It is 13,000 lines long so you need to read the datasheet first and know what you are looking for, and also to use the MPLAB X help on config, again make sure you refer it to the datasheet.
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
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 ) * (*wwp++); *xip++ = 0; } // for i } // windowFFT
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
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++ = * cos(PI2N * i); } // initFFT
“FFT.h” /* ** FFT.h ** ** power of two optimized algorithm */ #include #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);
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 #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] = ( unsigned char) (120.0 * f); } // for // 2. perform FFT algorithm windowFFT( inB); FFT(); powerScale( inB); // 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();
The CHECON Register
Optimizing WaitStates SYSTEMConfigWaitStatesAndPB( L);
Turning the Cache ON SYSTEMConfigWaitStatesAndPB( L); CheKseg0CacheOn();
Enabling Pre-Fetch SYSTEMConfigWaitStatesAndPB( L); CheKseg0CacheOn(); mCheConfigure( CHECON | 0x30);
Remove RAM Wait States // configure PB frequency and the number of wait states SYSTEMConfigWaitStatesAndPB( L); // enable the cache for max performance CheKseg0CacheOn(); // enable instruction prefetch mCheConfigure( CHECON | 0x30); // disable RAM wait states mBMXDisableDRMWaitState(); SYSTEMConfigPerformance( L);
Data Control & Monitor Interface
The FFT Output