UKSS_ICE/v120/DSP2833x_examples/eqep_freqcal/Example_freqcal.c
nelolik b8a0477c5c init commit.
Проект каким он достался от Димы.
2021-02-15 09:56:27 +03:00

187 lines
6.9 KiB
C

// TI File $Revision: /main/10 $
// Checkin $Date: April 21, 2008 15:42:07 $
//###########################################################################
//
// FILE: Example_freqcal.c
//
// TITLE: Frequency measurement using EQEP peripheral
//
// DESCRIPTION:
//
// This file includes the EQEP initialization and frequency calcuation
// functions called by Example_2833xEqep_freqcal.c. The frequency calculation
// steps performed by FREQCAL_Calc()at SYSCLKOUT = 150 MHz and 100 MHz are
// described below:
//
// For 150 MHz Operation:
// ----------------------
//
// 1. This program calculates: **freqhz_fr**
// freqhz_fr or v = (x2-x1)/T - Equation 1
//
// If max/base freq = 10kHz: 10kHz = (x2-x1)/(2/100Hz) - Equation 2
// max (x2-x1) = 200 counts = freqScaler_fr
// Note: T = 2/100Hz. 2 is from (x2-x1)/2 - because QPOSCNT counts 2 edges per cycle
// (rising and falling)
//
// If both sides of Equation 2 are divided by 10 kHz, then:
// 1 = (x2-x1)/[10kHz*(2/100Hz)] where [10kHz* (2/100Hz)] = 200
// Because (x2-x1) must be <200 (max),
// (x2-x1)/200 < 1 for all frequencies less than max
// freq_fr = (x2-x1)/200 or (x2-x1)/[10kHz*(2/100Hz)] - Equation 3
//
// To get back to original velocity equation, Equation 1, multiply Equation 3 by 10 kHz
// freqhz_fr (or velocity) = 10kHz*(x2-x1)/[10kHz*(2/100Hz)]
// = (x2-x1)/(2/100Hz) - Final equation
//
// 2. min freq = 1 count/(2/100Hz) = 50 Hz
//
// 3. **freqhz_pr**
// freqhz_pr or v = X/(t2-t1) - Equation 4
//
// If max/base freq = 10kHz: 10kHz = (4/2)/T = 4/2T
// where 4 = QCAPCTL [UPPS] (Unit timeout - once every 4 edges)
// 2 = divide by 2 because QPOSCNT counts 2 edges per cycle (rising and falling)
// T = time in seconds
// = t2-t1/(150MHz/128), t2-t1= # of QCAPCLK cycles, and
// 1 QCAPCLK cycle = 1/(150MHz/128)
// = QCPRDLAT
//
// So: 10 kHz = 4(150MHz/128)/2(t2-t1)
// t2-t1 = 4(150MHz/128)/(10kHz*2) = (150MHz/128)/(2*10kHz/4) - Equation 5
// = 234 QCAPCLK cycles = maximum (t2-t1) = freqScaler_pr
//
// Divide both sides by (t2-t1), and:
// 1 = 234/(t2-t1) = [150MHz/128)/(2*10kHz/4)]/(t2-t1)
// Because (t2-t1) must be <234 (max).
// 234/(t2-t1) < 1 for all frequencies less than max
// freq_pr = 234/(t2-t1) or [150MHz/128)/(2*10kHz/4)]/(t2-t1) - Equation 6
// Now within velocity limits, to get back to original velocity equation, Equation 1,
// multiply Equation 6 by 10 kHz:
// freqhz_fr (or velocity) = 10kHz*[150MHz/128)/(2*10kHz/4)]/(t2-t1)
// = (105MHz/128)*4/[2(t2-t1)]
// or 4/[2*(t2-t1)(QCPRDLAT)] - Final Equation
//
//
// For 100 MHz Operation:
// ----------------------
//
// The same calculations as above are performed, but with 100 MHz
// instead of 150MHz when calculating freqhz_pr, and at UPPS of 8 instead of 4.
// The value for freqScaler_pr becomes: (100MHz/128)/(2*10kHz/8) = 313
// More detailed calculation results can be found in the Example_freqcal.xls
// spreadsheet included in the example folder.
//
//
// This file contains source for the freq calculation module
//
//###########################################################################
// Original Author: SD
//
// $TI Release: DSP2833x/DSP2823x Header Files V1.20 $
// $Release Date: August 1, 2008 $
//###########################################################################
#include "DSP28x_Project.h" // Device Headerfile and Examples Include File
#include "Example_freqcal.h" // Example specific include file
void FREQCAL_Init(void)
{
#if (CPU_FRQ_150MHZ)
EQep1Regs.QUPRD=1500000; // Unit Timer for 100Hz at 150MHz SYSCLKOUT
#endif
#if (CPU_FRQ_100MHZ)
EQep1Regs.QUPRD=1000000; // Unit Timer for 100Hz at 100MHz SYSCLKOUT
#endif
EQep1Regs.QDECCTL.bit.QSRC=2; // Up count mode (freq. measurement)
EQep1Regs.QDECCTL.bit.XCR=0; // 2x resolution (cnt falling and rising edges)
EQep1Regs.QEPCTL.bit.FREE_SOFT=2;
EQep1Regs.QEPCTL.bit.PCRM=00; // QPOSCNT reset on index evnt
EQep1Regs.QEPCTL.bit.UTE=1; // Unit Timer Enable
EQep1Regs.QEPCTL.bit.QCLM=1; // Latch on unit time out
EQep1Regs.QPOSMAX=0xffffffff;
EQep1Regs.QEPCTL.bit.QPEN=1; // QEP enable
#if (CPU_FRQ_150MHZ)
EQep1Regs.QCAPCTL.bit.UPPS=2; // 1/4 for unit position at 150MHz SYSCLKOUT
#endif
#if (CPU_FRQ_100MHZ)
EQep1Regs.QCAPCTL.bit.UPPS=3; // 1/8 for unit position at 100MHz SYSCLKOUT
#endif
EQep1Regs.QCAPCTL.bit.CCPS=7; // 1/128 for CAP clock
EQep1Regs.QCAPCTL.bit.CEN=1; // QEP Capture Enable
}
void FREQCAL_Calc(FREQCAL *p)
{
unsigned long tmp;
_iq newp,oldp;
//**** Freq Calcultation using QEP position counter ****//
// Check unit Time out-event for speed calculation:
// Unit Timer is configured for 100Hz in INIT function
// For a more detailed explanation of the calculation, read
// the description at the top of this file
if(EQep1Regs.QFLG.bit.UTO==1) // Unit Timeout event
{
/** Differentiator **/
newp=EQep1Regs.QPOSLAT; // Latched POSCNT value
oldp=p->oldpos;
if (newp>oldp)
tmp = newp - oldp; // x2-x1 in v=(x2-x1)/T equation
else
tmp = (0xFFFFFFFF-oldp)+newp;
p->freq_fr = _IQdiv(tmp,p->freqScaler_fr); // p->freq_fr = (x2-x1)/(T*10KHz)
tmp=p->freq_fr;
if (tmp>=_IQ(1)) // is freq greater than max freq (10KHz for this example)?
p->freq_fr = _IQ(1);
else
p->freq_fr = tmp;
p->freqhz_fr = _IQmpy(p->BaseFreq,p->freq_fr); // Q0 = Q0*GLOBAL_Q => _IQXmpy(), X = GLOBAL_Q
// p->freqhz_fr = (p->freq_fr)*10kHz = (x2-x1)/T
// Update position counter
p->oldpos = newp;
//=======================================
EQep1Regs.QCLR.bit.UTO=1; // Clear interrupt flag
}
//**** Freq Calcultation using QEP capture counter ****//
if(EQep1Regs.QEPSTS.bit.UPEVNT==1) // Unit Position Event
{
if(EQep1Regs.QEPSTS.bit.COEF==0) // No Capture overflow
tmp=(unsigned long)EQep1Regs.QCPRDLAT;
else // Capture overflow, saturate the result
tmp=0xFFFF;
p->freq_pr = _IQdiv(p->freqScaler_pr,tmp); // p->freq_pr = X/[(t2-t1)*10KHz]
tmp=p->freq_pr;
if (tmp>_IQ(1))
p->freq_pr = _IQ(1);
else
p->freq_pr = tmp;
p->freqhz_pr = _IQmpy(p->BaseFreq,p->freq_pr); // Q0 = Q0*GLOBAL_Q => _IQXmpy(), X = GLOBAL_Q
// p->freqhz_pr =( p->freq_pr)*10kHz = X/(t2-t1)
EQep1Regs.QEPSTS.all=0x88; // Clear Unit position event flag
// Clear overflow error flag
}
}