<root>
<document schema='101' license='0,14891962,V8Y5V7' title='' description='' target='PIC16.30F.30F4013' >
	<config data='!0,8711!10,3f!20,8730!30,310f!40,330f!50,7!60,c003%0,711%e,2%10,f%14,3%1f,0%20,0%24,3%27,0%28,7%2f,1%30,f%38,1%3c,3%40,f%48,3%4c,3%50,1%51,3%60,3%6e,1%6f,1' clkspd='40000000' simspd='1' usewdt='0' constif='0' />
	<plugins >
		<dll_dbg_icd enabled='0' >
			<data name='debug' value='1' />
			<data name='userpins' value='0' />
			<data name='speed' value='1000' />
			<data name='usev9' value='0' />
			<data name='breaks' value='8' />
			<data name='stacks' value='8' />
			<data name='clkport' value='1' />
			<data name='clkbit' value='6' />
			<data name='dataport' value='1' />
			<data name='databit' value='7' />
			<data name='monitor' value='1' />
			<data name='ictloop' value='1' />
			<data name='ictrate' value='1000' />
			<data name='ictmask' value='-1' />
		</dll_dbg_icd>
		<dll_models enabled='1' />
		<dll_upgrader enabled='1' />
		<dll_webhelp enabled='1' />
	</plugins>
	<supplement use='1' head='// DSP definitions and prototypes as the required include file is missing from FC4 for dsPIC
// (see Microchip document 16bit_language_tool_libraries_51456c.pdf)
typedef int             fractional;

typedef struct {
  fractional real;
  fractional imag;
} fractcomplex;

#define COEFFS_IN_DATA  0xFF00

extern fractcomplex* TwidFactorInit(int size,fractcomplex* twiddle, int complex);
extern fractional* VectorMultiply(int nElements, fractional* dst, fractional* src1, fractional* src2);
extern fractcomplex* FFTComplexIP(int size, fractcomplex* src, fractcomplex* twiddle, int page);
extern fractcomplex* BitReverseComplex(int size, fractcomplex* src);
extern fractional* SquareMagnitudeCplx (int size, fractcomplex* src, fractional* dst);
// end DSP definitions


// allocate DMA buffers
unsigned int BufferA[32] __attribute__ ((space(dma)));
unsigned int BufferB[32] __attribute__ ((space(dma)));

// FFT
#define SAMPLES		1024
#define L2SAMPLES	10

fractcomplex inputSignal[SAMPLES] __attribute__ ((space(ymemory), far, aligned(SAMPLES * 2 * 2)));
fractcomplex twiddleFactors[SAMPLES/2] __attribute__ ((section (&quot;.xbss, bss, xmemory&quot;), aligned(SAMPLES * 2)));
fractional windowFactors[SAMPLES*2] __attribute__ ((section (&quot;.xbss, bss, xmemory&quot;), aligned(SAMPLES * 2)));
fractional powerVector[SAMPLES] __attribute__ ((section (&quot;.xbss, bss, xmemory&quot;), aligned(SAMPLES)));

// globals for C code
unsigned char sampleCount = 0;
fractcomplex *inputPntr = &amp;inputSignal[0];' body='void ProcessSamples(unsigned int *buf) {
	int i;

	for (i = 0; i &lt; 32; i++) {
		(*inputPntr++).real = *buf++;
	}
}' />
	<debug />
	<components >
		<settings autoimg='1' center='1' unitscale='0' fixedscale='0' fixedx='1' fixedy='1' fixedz='1' headcode='0' />
		<definition guid='' vmin='0' vmaj='1' srcleaf='' visiblename='' description='' category='' catenable='1' author='' sysinfo='0' keywords='' dynamic='0' iconpath='' />
		<component class_type='root' codename='panel' x='0' y='0' z='0' xsz='1' ysz='1' zsz='1' xang='0' yang='0' zang='0' xquat='0' yquat='0' zquat='0' wquat='1' visible='1' interactive='1' solid='1' layer='0' poslock='0' >
			<resources />
			<properties />
			<values />
			<events />
			<apis />
			<variables >
				<variable public='0' >
					<def class_type='variable' name='RESULT' type='s16' description='' isconst='0' isinit='0' usrinit='0' setinit='' >
						<array size='512' />
					</def>
				</variable>
				<variable public='0' >
					<def class_type='variable' name='sampling' type='u8' description='' isconst='0' isinit='0' usrinit='0' setinit='' />
				</variable>
			</variables>
			<macros >
				<macro >
					<flowline name='StartADC' description='Start sampling input' >
						<command class_type='native' title='(Re)set parameters and start sampling' textarea='36,0,511,300' ccode='// zero complex part of measurement array
for (int i = 0; i &lt; SAMPLES; i++) {
	(*inputPntr++).imag = 0;
}

// Reset sample counter &amp; buffer pointer
sampleCount = 0;
inputPntr = &amp;inputSignal[0];

// Reset DMA
IFS3bits.DMA5IF = 0; //Clear the DMA interrupt flag bit
IEC3bits.DMA5IE = 1; //Set the DMA interrupt enable bit
DMA5CONbits.CHEN=1; // Enable DMA

// Turn on ADC
AD1CON1bits.ADON = 1;
' language='C' />
					</flowline>
				</macro>
				<macro >
					<flowline name='Dma5IntHandler' description='' />
				</macro>
				<macro >
					<flowline name='ProcessFFT' description='Process acquired values' >
						<command class_type='native' title='Perform FFT' textarea='36,0,511,300' ccode='// Scale back to [-0.5,0.5] range for FFT usage (otherwise FFT might saturate)
VectorMultiply(2*SAMPLES, &amp;inputSignal[0].real, &amp;inputSignal[0].real, &amp;windowFactors[0]);

// Process FFT
FFTComplexIP(L2SAMPLES, &amp;inputSignal[0], &amp;twiddleFactors[0], COEFFS_IN_DATA);

// Order the results
BitReverseComplex(L2SAMPLES, &amp;inputSignal[0]);

// Calculate magnitude (size) of the results
SquareMagnitudeCplx(SAMPLES, &amp;inputSignal[0], &amp;powerVector[0]);

// Copy powervectors to Flowcode addressable array
for (int i = 0; i &lt; 128; i++) {
	FCV_RESULT[i] = powerVector[i];
}
' language='C' />
					</flowline>
				</macro>
				<macro >
					<flowline name='InitADC' description='Initialize ADC' >
						<command class_type='native' title='Setup ADC' textarea='36,0,511,300' ccode='// Setup ADC
// Reference Microchip 70182b, example 22-5. Adapted to for 1 channel

AD1CON1bits.FORM = 3;	// Signed Fraction format
AD1CON1bits.SSRC = 2;	// Timer3 ends sampling and starts conversion
AD1CON1bits.ASAM = 1;	// Sampling starts immediately after conversion
AD1CON1bits.AD12B = 0;	// 10 bit operation
AD1CON2bits.BUFM = 0;
AD1CON2bits.CHPS = 0;	// Convert channel 0
AD1CON3bits.ADRC = 0;	// ADC clock derived from system clock
AD1CON3bits.ADCS = 29;	// Conversion Clock Tad = ( 1/40M ) * 30 = 750 ns
						// ADC Conversion time is Tconv = 12 * Tad = 9000 ns (~111.1 kHz)

// Select input
AD1CHS0bits.CH0NA = 0;	// Select Vref- for CH0 -ve input
AD1CHS0bits.CH0SA = 0;	// Select AN0 for CH0 +ve input
AD1CON2bits.VCFG = 0;
AD1CHS123bits.CH123SA = 0; // MUXA +ve input selection (AIN0) for CH1
AD1CHS123bits.CH123NA = 0; // MUXA -ve input selection (VREF-) for CH1

// Input Scan Selection
AD1CSSL = 1;			// Scan AN0

// Set port to A/D
AD1PCFGL = 0xFFFF;
AD1PCFGLbits.PCFG0 = 0;	// AN0 as Analog Input' language='C' />
						<command class_type='interrupt' title='Configure timer3 for ADC conversions (20 kHz)' textarea='36,0,511,300' enable='1' name='TMR3' call='TMR3IntrDummy' >
							<settings timer='1' prescale='1' postscale='-1' rollover='250' bitcount='-1' trigger='3' maskhi='-wAAAP8AAAD-AAAA-wAAAP8AAAD-AAAA-wAAAP8AAAD-AAAA-wAAAP8AAAD-AAAA-wAAAP8AAAD-AAAA-wAAAP8AAAD-AAAA-wAAAP8AAAD-AAAA-wAAAP8AAAD-AAAA-wAAAP8AAAD-AAAA-wAAAP8AAAD-AAAA-wAAAP8AAAA' masklo='-wAAAP8AAAD-AAAA-wAAAP8AAAD-AAAA-wAAAP8AAAD-AAAA-wAAAP8AAAD-AAAA-wAAAP8AAAD-AAAA-wAAAP8AAAD-AAAA-wAAAP8AAAD-AAAA-wAAAP8AAAD-AAAA-wAAAP8AAAD-AAAA-wAAAP8AAAD-AAAA-wAAAP8AAAA' >
								<option value='0' />
								<option value='0' />
								<option value='250' />
								<option value='-1' />
							</settings>
						</command>
						<command class_type='interrupt' title='Disable interrupts for timer3 (used for ADC only)' textarea='36,0,511,300' enable='0' name='TMR3' >
							<settings timer='1' prescale='1' postscale='-1' rollover='0' bitcount='-1' trigger='3' maskhi='-wAAAP8AAAD-AAAA-wAAAP8AAAD-AAAA-wAAAP8AAAD-AAAA-wAAAP8AAAD-AAAA-wAAAP8AAAD-AAAA-wAAAP8AAAD-AAAA-wAAAP8AAAD-AAAA-wAAAP8AAAD-AAAA-wAAAP8AAAD-AAAA-wAAAP8AAAD-AAAA-wAAAP8AAAA' masklo='-wAAAP8AAAD-AAAA-wAAAP8AAAD-AAAA-wAAAP8AAAD-AAAA-wAAAP8AAAD-AAAA-wAAAP8AAAD-AAAA-wAAAP8AAAD-AAAA-wAAAP8AAAD-AAAA-wAAAP8AAAD-AAAA-wAAAP8AAAD-AAAA-wAAAP8AAAD-AAAA-wAAAP8AAAA' >
								<option value='0' />
								<option value='0' />
								<option value='0' />
								<option value='0' />
							</settings>
						</command>
						<command class_type='native' title='Setup DMA channel 5' textarea='36,0,511,300' ccode='DMA5CONbits.AMODE = 0;	// Register indirect with post-increment
DMA5CONbits.MODE = 2;	// Continues Ping-Pong mode
DMA5PAD = (volatile unsigned int) &amp;ADC1BUF0;	// Source is ADC1BUF0
DMA5CNT = 31;			// 32 DMA transfers
DMA5REQ = 13;			// ADC1 as Request source

DMA5STA = __builtin_dmaoffset(BufferA);
DMA5STB = __builtin_dmaoffset(BufferB);

' language='C' />
						<command class_type='interrupt' title='DMA5' textarea='36,0,511,300' enable='1' name='' call='Dma5IntHandler' >
							<custom name='DMA5' handler='unsigned int Dma5BufferUsed = 0;

void __attribute__((__interrupt__)) _DMA5Interrupt(void)
{
     sampleCount++;
     if (sampleCount &gt;= (SAMPLES/32)) {
          FCV_SAMPLING = 0;
          // Disable ADC
          AD1CON1bits.ADON = 0;
         DMA5CONbits.CHEN=0; // Disable DMA
     }
    // Call Handler
    if (Dma5BufferUsed == 0) {
       ProcessSamples(BufferA);
    } else {
       ProcessSamples(BufferB);
    }
    Dma5BufferUsed ^= 1;
    IFS3bits.DMA5IF = 0; // Clear interrupt flag
}' enable='IFS3bits.DMA5IF = 0; //Clear the DMA interrupt flag bit
IEC3bits.DMA5IE = 1; //Set the DMA interrupt enable bit

DMA5CONbits.CHEN=1; // Enable DMA' disable='' />
						</command>
						<command class_type='native' title='Setup ADC to use DMA' textarea='36,0,511,300' ccode='AD1CON1bits.ADDMABM = 0;			// Use DMA in scatter/gather mode
AD1CON2bits.SMPI = 0;				// 1 ADC buffer
AD1CON4bits.DMABL = 5;				// 32 words

IFS0bits.AD1IF = 0;					// Clear ADC interrupt flag
IEC0bits.AD1IE = 0;					// Do not enable ADC interrupt' language='C' />
					</flowline>
				</macro>
				<macro >
					<flowline name='TMR3IntrDummy' description='' >
						<command class_type='comment' title='' comment='Dummy function required by the timer 3 interrupt setup' textarea='12,0,487,300' />
					</flowline>
				</macro>
				<macro >
					<flowline name='InitFFT' description='Initilialize for FFT' >
						<command class_type='native' title='Initialize FFT variables' textarea='36,0,511,300' ccode='// Prepare data required for FFT analysis
TwidFactorInit(L2SAMPLES, &amp;twiddleFactors[0], 0);

// Setup array of values 0.5 (1s15 format)
for (int i = 0; i &lt; SAMPLES*2; i++) {
	windowFactors[i] = 0x4000;
}' language='C' />
					</flowline>
				</macro>
				<macro >
					<flowline name='Main' description='' >
						<command class_type='native' title='Set clock and disable SPI' textarea='36,0,511,300' ccode='// Crystal = 12 MHz, Target Fosc = 80MHz --&gt; 40 MIPS
CLKDIVbits.PLLPRE = 1;	// Pre = / 3
PLLFBDbits.PLLDIV = 38; // PLL multiplier 40
CLKDIVbits.PLLPOST = 0;	// Post = /2

// Disable SPI to free RB12-RB15 for I/O
SPI1STATbits.SPIEN = 0;
' language='C' />
						<command class_type='delay' title='Small startup delay to settle external circuit after power-on' textarea='36,0,511,300' exp='1' type='2' />
						<command class_type='call' title='Initialize FFT' textarea='36,0,511,300' macro='InitFFT' />
						<command class_type='call' title='Initialize ADC' textarea='36,0,511,300' macro='InitADC' />
						<command class_type='loop' title='Loop' textarea='36,0,511,300' exp='1' type='0' start='1' count='1' breakend='0' >
							<flowline >
								<command class_type='calculation' title='Set flag' textarea='36,0,511,300' >
									<exp exp='sampling = 1' />
								</command>
								<command class_type='call' title='Call Macro' textarea='36,0,511,300' macro='StartADC' />
								<command class_type='loop' title='Loop' textarea='36,0,511,300' exp='sampling' type='0' start='1' count='1' breakend='0' >
									<flowline >
										<command class_type='comment' title='' comment='Do nothing while data is sampled' textarea='12,0,487,300' />
									</flowline>
								</command>
								<command class_type='call' title='Call Macro' textarea='36,0,511,300' macro='ProcessFFT' />
								<command class_type='decision' title='40 Hz present?' textarea='36,0,511,300' exp='RESULT[1]' swap='0' >
									<flowline />
									<flowline />
								</command>
								<command class_type='decision' title='120hz' textarea='36,0,511,300' exp='RESULT[3]' swap='0' >
									<flowline />
									<flowline />
								</command>
								<command class_type='decision' title='320 Hz present?' textarea='36,0,511,300' exp='RESULT[8]' swap='0' >
									<flowline />
									<flowline />
								</command>
							</flowline>
						</command>
					</flowline>
				</macro>
			</macros>
			<component class_type='ref' guid='c8da67a7-fc7b-48c0-8c3f-3264c74f4024' vmin='3' vmaj='1' codename='v5__ledarray0' x='0' y='0' z='0' xsz='1' ysz='1' zsz='1' xang='0' yang='0' zang='0' xquat='0' yquat='0' zquat='0' wquat='1' visible='1' interactive='1' solid='1' layer='0' poslock='0' >
				<resources />
				<properties />
				<values >
					<value target='count' data='8' />
					<value target='port' data='001' />
					<value target='pin0' data='$PORTB.0' />
					<value target='pin1' data='$PORTB.1' />
					<value target='pin2' data='$PORTB.2' />
					<value target='pin3' data='$PORTB.3' />
					<value target='pin4' data='$PORTB.4' />
					<value target='pin5' data='$PORTB.5' />
					<value target='pin6' data='$PORTB.6' />
					<value target='pin7' data='$PORTB.7' />
					<value target='polarity' data='001' />
					<value target='full_port' data='$PORTB' />
					<value target='align' data='1' />
					<value target='spacing' data='7.000000' />
					<value target='target_object' data='' />
					<value target='shape' data='4' />
					<value target='width' data='5.000000' />
					<value target='height' data='5.000000' />
					<value target='depth' data='2.500000' />
					<value target='color_same' data='1' />
					<value target='color_led0' data='255' />
					<value target='color_led1' data='65280' />
					<value target='color_led2' data='65280' />
					<value target='color_led3' data='65280' />
					<value target='color_led4' data='65535' />
					<value target='color_led5' data='65535' />
					<value target='color_led6' data='255' />
					<value target='color_led7' data='255' />
					<value target='bitmask' data='255' />
					<value target='inv_bitmask' data='-256' />
				</values>
				<events />
				<apis />
				<variables />
				<macros />
			</component>
		</component>
	</components>
	<keymap />
	<panel2d shadows='0' lighting='2' brightness='0' perspective='0' >
		<background rgb='9737364' img='' style='0' />
		<camera xe='0' ye='0' ze='300' xt='0' yt='0' zt='0' xquat='0' yquat='0' zquat='0' wquat='1' />
	</panel2d>
	<panel3d shadows='0' lighting='2' brightness='0' perspective='0' >
		<background rgb='8409120' img='' style='0' />
		<table rgb='7360576' img='' style='0' size='25' />
		<camera xe='0' ye='0' ze='300' xt='0' yt='0' zt='0' xquat='0' yquat='0' zquat='0' wquat='1' />
	</panel3d>
	<layout >
		<view type='0' name='InitADC' mode='0' placement='LAAAAAAAAAABAAAA---------------------wAAAAAUAAAA-AMAAMQCAAA' zoom='75' scrollx='0' scrolly='0' flags='0' />
		<view type='0' name='StartADC' mode='0' placement='LAAAAAAAAAABAAAA---------------------wAAAAAUAAAA-AMAAMQCAAA' zoom='75' scrollx='0' scrolly='0' flags='0' />
		<view type='0' name='Main' mode='0' placement='LAAAAAAAAAABAAAA---------------------wAAAAAUAAAA-AMAAMQCAAA' zoom='75' scrollx='0' scrolly='0' flags='0' />
	</layout>
</document>
</root>
