AnsweredAssumed Answered

BF534 timer in WIDTH CAPTURE mode

Question asked by Colin on Jan 7, 2010
Latest reply on Jan 19, 2010 by Colin

  Hi,

  I'm using a BF534 with VDSP++ 5.0(update 7) and the SSL to  control a timer to try to capture the width

of a single, one off pulse.

 

  I've programmed the timer with:

static const ADI_TMR_GP_CMD_VALUE_PAIR   ambient_data[] = {

            // maintain this order
            // ****** order start
            { ADI_TMR_GP_CMD_SET_TIMER_MODE                , (void *)   2              }, //      WIDTH CAPTURE 
            { ADI_TMR_GP_CMD_SET_PULSE_HI                      , (void *)   1              }, //     measure high width
            { ADI_TMR_GP_CMD_SET_COUNT_METHOD          , (void *)   0              }, //      PERIOD_COUNT=0 => interrupt after counting width
            { ADI_TMR_GP_CMD_SET_INTERRUPT_ENABLE    , (void *)   1              }, //      Irq on capture
            { ADI_TMR_GP_CMD_SET_INPUT_SELECT              , (void *)   0              }, //      tin_sel=0 => TMR6 input for width capture
//          { ADI_TMR_GP_CMD_SET_OUTPUT_PAD_DISABLE, (void *)   1              }, // n/a 0 = ON, 1 = disable
//          { ADI_TMR_GP_CMD_SET_CLOCK_SELECT            , (void *)   0              }, // n/a   clk_sel=0
//          { ADI_TMR_GP_CMD_SET_TOGGLE_HI                    , (void *)   0              }, // n/a toggle = 0
            { ADI_TMR_GP_CMD_RUN_DURING_EMULATION    , (void *)   0              }, //      =1
            // ****** order end

 

        { ADI_TMR_GP_CMD_END                  , NULL                          }
    };

and

 

       tmErrorCheck(adi_tmr_Open(           TMI_TMR_BEEP));

 

       /* Assign the callback                 TimerID,                      WakeupFlag,         *ClientHandle,                    DCBHandle,     ClientCallback */
       tmErrorCheck(adi_tmr_InstallCallback(TMI_TMR_BEEP,           TRUE,  (void *)0x99999999,  adi_dcb_ManagerHandle,  callbackFunction ));

 

       /* Configure the timer for width capture */
       tmErrorCheck(adi_tmr_GPControl(      TMI_TMR_BEEP,    ADI_TMR_GP_CMD_TABLE          , (void *)&ambient_data));

 

       // are these needed ?
       tmErrorCheck(adi_tmr_GPControl(      TMI_TMR_BEEP,    ADI_TMR_GP_CMD_CLEAR_INTERRUPT, (void *)TRUE));
      tmErrorCheck(adi_tmr_GPControl(      TMI_TMR_BEEP,    ADI_TMR_GP_CMD_CLEAR_ERROR    , (void *)TRUE));

 

       /* Start timer */
       tmErrorCheck(adi_tmr_GPControl(      TMI_TMR_BEEP,    ADI_TMR_GP_CMD_ENABLE_TIMER   , (void *)TRUE))

 

 

The callback just reads the timer values and sets a flag for the main code to disable the timer:

. . .

      tmErrorCheck(adi_tmr_GPControl(TMI_TMR_BEEP, ADI_TMR_GP_CMD_GET_COUNTER   , (void *)&amb_counter) );
       tmErrorCheck(adi_tmr_GPControl(TMI_TMR_BEEP, ADI_TMR_GP_CMD_GET_WIDTH        , (void *)&amb_width)     );
       tmErrorCheck(adi_tmr_GPControl(TMI_TMR_BEEP, ADI_TMR_GP_CMD_GET_PERIOD      , (void *)&amb_period)    );

 

      tmErrorCheck(adi_tmr_GPControl(TMI_TMR_BEEP, ADI_TMR_GP_CMD_GET_ERROR_TYPE, (void *)&err_type)    );
       tmErrorCheck(adi_tmr_GPControl(TMI_TMR_BEEP, ADI_TMR_GP_CMD_IS_ERROR              , (void *)&tovf_err)     );

 

      if (err_type || tovf_err) {

           /* report errors */

      }

      state = DONE;

. . .

 

[ The "tmErrorCheck" wrapper is just a check on the result != 0 and hangs forever if so.  It has never detected an error. ]

 

  I find the callback is called on both rising and falling edges of the the next pulse.  This is regardless of which edge comes first!  If it is initialised during the low phase then the next rising edge generates and interrupt and the following falling edge.  If it's initialised during the high phase then enxt falling edge generates an interrupt and the the following rising edge.

 

At no time are there any errors or overflows reported.

 

For test purposes, I'm using a a pulse train of 1ms pulses 12ms apart.

 

The width and period are always just a few counts (133MHz SCLK) and the counter is only ever about 800.

 

I should be getting a width of 133000 approx.

 

Figures 15-13 and 15-15 of the ADSP-BF537 Hardware Reference suggests that the first edge just starts the timer and the second edge captures the width and causes the interrupt.

 

From the IDE,  the TIMER_STATUS and TIMER_CONFIG look correct.

 

I've tried using direct callbacks rather than deferred.  Same result.

I've tried PERIOD_COUNT=1,  Same result.

 

 

Can anyone suggest where to look next?

 

Regards

 

Colin Moloney

Outcomes