We have developed our own low-level drivers for frequency and/or period measurement, using any of the Quad Timers that have an I/O pin. Details on our low-level drivers are in 2 messages I posted to this group: - 10:09am, September 24, 2002: "RE: [motoroladsp] Doubt regarding context saving for SCI callback routine." - 6:43am, September 25, 2002: "RE: [motoroladsp] Timer Pins, more I/O" The first message describes the "Super Fast" interrupt for the Quad Timer frequency and/or period measurement, and the second message has a ZIP file that contains the complete source code for the interrupt and data processing functions, in the file "io_func.c". These functions are: static void init_frequency_inputs(void); static void read_frequency_inputs( void ); void process_frequency_inputs( void ); void Freq_Period_Input_ISR( WORD status, // Status read from the DSP Timer DSP_TIMER_T *p_dsp_timer, // Pointer to the DSP Timer DSPTMR_FP_DATA_T *p_dsp_fp_data // Pointer to the input data structure ); The attached file "anaiodef.h" contains the following typedef for the DSPTMR_FP_DATA_T structure: // Frequency/period input data structure (one for each input). typedef struct { SWORD ad_idx; // Index into the ANA_DATA array union { // Union for the raw data input LWORD fp_count; // The whole frequency/period count struct { // Structure for the parts of the count WORD fp_lsw; // Freq./Period least significant word WORD fp_msw; // Freq./Period most significant word } parts; } raw_data; LWORD fp_start_val; // Count at the start point LWORD fp_end_val; // Count at the end point SWORD fp_meas_type; // 0 == count pulses, else from period SWORD ignore_count; // Ignore next count when mode changed SWORD count_index; // Index into the count_data[] array WORD count_data[ FREQ_COUNTS_PER_SEC ]; SWORD raw_fp_meas_type; // 0 == count pulses, else from period LWORD raw_fp_data; // Raw frequency data (period or count) } DSPTMR_FP_DATA_T; This low-level driver software uses the Overflow Interrupt to extend the counter to 32 bits, by counting overflows in the "raw_data.parts.fp_msw" variable. The 32-bit value of the counter is read from the "raw_data.fp_count" variable. By reading from the Capture Register (CAP), we are able to read the number of IPBus clock cycles with zero error, please see Section 14.7.5 "Capture Register (CAP)" in the DSP56F80x User's Manual. Our software only captures one edge of the input signal, but you can put a different value in the Status and Control Register (SCR) Input Capture Mode value, please see Section 14.7.2.9 "Input Capture Mode (Capture Mode) - Bits 7-6" in the DSP56F80x User's Manual. The period of one cycle is the difference between the "end" and "start" values in the structure, for example: LWORD period_value; DSPTMR_FP_DATA_T *p_fp_data = &g_dsp_tmrb0_data; period_value = p_fp_data->fp_end_val - p_fp_data->fp_start_val; This is, of course, the count of Primary Count Source clock pulses (ie IP_Bus_Clock/1) in one complete cycle. This is converted to the frequency value in the function process_frequency_inputs(). You can use a similar calculation to convert the count to the true period value. We don't use the SDK low-level I/O drivers at all, so if you want to use the method shown above, you will have to figure out how to do it on your own. I hope this information is helpful to you. Regards, Art Johnson Senior Systems Analyst PMC Prime Mover Controls Inc. 3600 Gilmore Way Burnaby, B.C., Canada V5G 4R8 Phone: 604 433-4644 FAX: 604 433-5570 Email: http://www.pmc-controls.com -----Original Message----- From: dflieb20 [mailto:] Sent: Tuesday, November 26, 2002 12:53 PM To: Subject: [motoroladsp] Measuring PW using Quad Timer Captures Hello- I am using the 56807 with the Motorola SDK. I am tryng to measure the pulse-width of a ~50Hz squarewave using the capture registers on two timers (one to save the rise time, one to save the fall time). The rise and fall interrupts fire correctly, but the values returned by the SDK function ioctl(...,QT_READ_CAPTURE_REG,...) are strange at best (the rise and fall times are usually separated by only 1 clock cycle, which is near impossible). I am connecting the signal generator to timer D0 and using that pin as input to both timers. Here is the code - thanks for any input. dave #include <stdio.h> #include "port.h" #include "arch.h" #include "io.h" #include "led.h" #include "qtimerdrv.h" #include "periph.h" #include "fcntl.h" #include "quadraturetimer.h" static void CallbackOnRisingEdge(qt_eCallbackType CallbackType, void* pParam); static void CallbackOnFallingEdge(qt_eCallbackType CallbackType, void* pParam); const qt_sState quadParam1 = { /* Mode = */ qtCount, /* InputSource = */ qtCounter0Input, /* InputPolarity = */ qtNormal, /* SecondaryInputSource = */ 0, /* CountFrequency = */ qtRepeatedly, /* CountLength = */ qtPastCompare, /* CountDirection = */ qtUp, /* OutputMode = */ qtToggleOnCompare, /* OutputPolarity = */ qtNormal, /* OutputDisabled = */ 0, /* Master = */ 0, /* OutputOnMaster = */ 0, /* CoChannelInitialize = */ 0, /* AssertWhenForced = */ 0, /* CaptureMode = */ qtRisingEdge, /* CompareValue1 = */ 0xFFFF, /* CompareValue2 = */ 0xFFFF, /* InitialLoadValue = */ 0x0000, /* CallbackOnCompare = */ { 0, 0 }, /* CallbackOnOverflow = */ { 0, 0 }, /* CallbackOnInputEdge = */ { CallbackOnRisingEdge, 0 } }; const qt_sState quadParam2 = { /* Mode = */ qtCount, /* InputSource = */ qtCounter0Input, /* InputPolarity = */ qtNormal, /* SecondaryInputSource = */ 0, /* CountFrequency = */ qtRepeatedly, /* CountLength = */ qtPastCompare, /* CountDirection = */ qtUp, /* OutputMode = */ qtToggleOnCompare, /* OutputPolarity = */ qtNormal, /* OutputDisabled = */ 0, /* Master = */ 0, /* OutputOnMaster = */ 0, /* CoChannelInitialize = */ 0, /* AssertWhenForced = */ 0, /* CaptureMode = */ qtFallingEdge, /* CompareValue1 = */ 0xFFFF, /* CompareValue2 = */ 0xFFFF, /* InitialLoadValue = */ 0x0000, /* CallbackOnCompare = */ { 0, 0 }, /* CallbackOnOverflow = */ { 0, 0 }, /* CallbackOnInputEdge = */ { CallbackOnFallingEdge, 0 } }; Word16 RiseTime=0, FallTime=0, PW=0; int PwUpdated =0, PrevPW=0;; UWord16 TimerD0; /* file handles */ UWord16 TimerD1; static int LedFD; /********************************************************************* ********/ main() { LedFD = open(BSP_DEVICE_NAME_LED_0, 0); ioctl(LedFD, LED_OFF, LED_GREEN); TimerD0 = open(BSP_DEVICE_NAME_QUAD_TIMER_D_0, 0, &quadParam1 ); TimerD1 = open(BSP_DEVICE_NAME_QUAD_TIMER_D_1, 0, &quadParam2 ); ioctl(TimerD0, QT_DISABLE, (void*)&quadParam1 ); ioctl(TimerD1, QT_DISABLE, (void*)&quadParam2 ); ioctl(TimerD0, QT_ENABLE_CAPTURE_REG, (void*)&quadParam1 ); ioctl(TimerD1, QT_ENABLE_CAPTURE_REG, (void*)&quadParam2 ); ioctl(TimerD0, QT_ENABLE, (void*)&quadParam1 ); ioctl(TimerD1, QT_ENABLE, (void*)&quadParam2 ); while(1) /* executive loop */ { if (PwUpdated) { PrevPW = PW; PwUpdated = 0; } } } /********************************************************************* ********/ void CallbackOnRisingEdge(qt_eCallbackType CallbackType, void* pParam) { ioctl(LedFD, LED_ON, LED_GREEN); ioctl(LedFD, LED_OFF, LED_RED); RiseTime = ioctl(TimerD0, QT_READ_CAPTURE_REG, (void*) &quadParam1 ); } void CallbackOnFallingEdge(qt_eCallbackType CallbackType, void* pParam) { ioctl(LedFD, LED_OFF, LED_GREEN); ioctl(LedFD, LED_ON, LED_RED); FallTime = ioctl(TimerD1, QT_READ_CAPTURE_REG, (void*) &quadParam2 ); PW = FallTime-RiseTime; PwUpdated = 1; } _____________________________________ Note: If you do a simple "reply" with your email client, only the author of this message will receive your answer. You need to do a "reply all" if you want your answer to be distributed to the entire group. _____________________________________ About this discussion group: To Join: To Post: To Leave: Archives: http://www.yahoogroups.com/group/motoroladsp More Groups: http://www.dsprelated.com/groups.php3 ">http://docs.yahoo.com/info/terms/ | |||
|