Author Topic: Using Timer To Decode Manchester Coding  (Read 6786 times)

Offline ctkian

  • Newbie
  • *
  • Posts: 20
    • View Profile
Using Timer To Decode Manchester Coding
« on: October 18, 2010, 09:25:41 AM »
Hi All,

I am utasker on M5223X device. Now I need to decode a waveform using manchester coding method, the incoming waveform have a valid pulse width of 250us. I have tried to use hardware timer as below to tried to generated 10us interval but not successful, the below code can only give me a timeout in a period of about 200us(measure using a oscilloscope). As the pulse width is 250us, i may need to accept the pulse width between 200us - 300us as a valid incoming signal.

#define MILLISEC               MED_RES_MS
uTaskerGlobalMonoTimer( (UTASK_TASK)(OWN_TASK | HARDWARE_TIMER), (CLOCK_LIMIT)(0.01*MILLISEC),  E_TIMER_TEST_3MS );  // restart 3ms timer

I have tried to use a count down timer to obtain the period between incoming state change (either from high to low or low to high), I cannot get this method to work as the timer accuracy i get is too low (200us) where I need higher timer accuracy.

Please advice how I should do in order to correctly decoding the incoming manchester coding waveform.

Thank you very much.

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3191
    • View Profile
    • uTasker
Re: Using Timer To Decode Manchester Coding
« Reply #1 on: October 18, 2010, 01:49:56 PM »
Hi

I recommend using a DMA timer to do this since it will give better accuracy.

The SW timers are based on task scheduling and so won't achieve the same resolution as the DMA direct interrupt.

See the example in ADC_timers.h - #define TEST_DMA_TIMER as reference.
Also search the forum for some other examples.

Note also that the DMA timers can perform a DMA transfer when they fire. That means that it is possible to let a DMA timer run for a period of time with a number of timeouts. On each timeout it can be set up to transfer the value of an input port to a buffer.
After the programmed number of samples, it can stop and there is a buffer containing highly accurate input samples which can be used to extract waveform information and decode protocols. There is no example of this setup in the project but it is not that difficult to achieve.

Regards

Mark


Offline ctkian

  • Newbie
  • *
  • Posts: 20
    • View Profile
Re: Using Timer To Decode Manchester Coding
« Reply #2 on: October 19, 2010, 09:47:57 AM »
HI Mark,

Thanks for the information.

Below is the code I have tried:
////////////////////////////////////////////////
static void EM4095TimerInt(void)
{
   static U8_t i=0;
   
   DMA_TIMER_COUNTERS = 0;      //clear timer
   DMA_TIMER_EVENT = 0x03;      //clear event flag
   if(i)
   {
      OUT_EMSHD_ON;
      i=0;
   }
   else
   {
      OUT_EMSHD_OFF;
      i=1;
   }
}
static void EM4095_InitDMA(void)
{
    DMA_TIMER_SETUP EM_timer;
   
    EM_timer.int_type = DMA_TIMER_INTERRUPT;                       
    EM_timer.channel = EM4095_DMA_TIMER_CHANNEL;               
    EM_timer.int_priority = EM4095_DMA_TIMER_INTERRUPT_PRIORITY;
    EM_timer.int_handler = EM4095TimerInt;
    EM_timer.mode = (DMA_TIMER_INTERNAL_CLOCK|DMA_TIMER_PERIODIC_INTERRUPT);
   
   
   fnConfigureInterrupt((void *)&EM_timer);
}
//////////////////////////////
With above code, from scope measure a 100uS interval, please advice what further settings is require to get smaller interval, said 10uS.

Thank you very much.

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3191
    • View Profile
    • uTasker
Re: Using Timer To Decode Manchester Coding
« Reply #3 on: October 19, 2010, 02:33:40 PM »
Hi

I don't see the time that you are setting, to set 10us (for example) the following can be used:

EM_timer.count_delay = DMA_TIMER_US_DELAY(1,1,10);          // 10us delay using no dividers


In the interrupt routine

   DMA_TIMER_COUNTERS = 0;      //clear timer
   DMA_TIMER_EVENT = 0x03;      //clear event flag


are not required since the DMA interrupt handler is performing such work. In the case of a periodic interrupt it is fact performing
DTERx = (DMA_TIM_EVENT_REF | DMA_TIM_EVENT_CAP);
and not resetting the counter.

Regards

Mark

Offline ctkian

  • Newbie
  • *
  • Posts: 20
    • View Profile
Re: Using Timer To Decode Manchester Coding
« Reply #4 on: October 21, 2010, 04:20:29 AM »
Hi All,

After adding the line as Mark suggest (EM_timer.count_delay = DMA_TIMER_US_DELAY(1,1,10);) it is working fine now.

Just some additional information, we can use DMA_TIMER_US_DELAY to get interval of uS or DMA_TIMER_MS_DELAY for mS interval.

My latest code as below, the the DMA timer set to 100mS timeout period:
//////////////////////////////////
static void EM4095TimerInt(void)
{
   tEM4095RunTime[0].timer_off = 1;
   uTaskerStateChange(OWN_TASK, UTASKER_GO);
}

static void EM4095_ConfigDMATimer(DMA_TIMER_SETUP * EM_timer)
{
    EM_timer->int_type = DMA_TIMER_INTERRUPT;                       
    EM_timer->channel = EM4095_DMA_TIMER_CHANNEL;                   
    EM_timer->int_priority = EM4095_DMA_TIMER_INTERRUPT_PRIORITY;
    EM_timer->int_handler = EM4095TimerInt;
    EM_timer->mode = (DMA_TIMER_INTERNAL_CLOCK_DIV_16|DMA_TIMER_PERIODIC_INTERRUPT|DMA_TIMER_RESTART_ON_MATCH);
  EM_timer->count_delay =DMA_TIMER_MS_DELAY(16,1,100)            // 100ms delay
}
//////////////////////////////////
Thank you very much. Now I manage to decode the Manchester Coding signal.