On the fly change in high frequecy clock pulse

Technical questions regarding the XTC tools and programming with XMOS.
Post Reply
sorab.baheti
Newbie
Posts: 1
Joined: Thu May 18, 2017 10:51 am

On the fly change in high frequecy clock pulse

Post by sorab.baheti »

Hello,

I am trying to use a while(1) select case timerafter(time) controlled loop to toggle a gpio pin (port <: 1 or port <: 0) in each consecutive iteration of the loop by adding a delay value to this time.Basically generating a clock pulse.

My end use is to drive a gpio at both high and low frequency but I want a fast response in its change at both high and low frequency. With my current methodology I call an interface by using select case and change the delay value by that.So my response time in the change is dependent on the delay of my loop which creates a lag in change of frequency at lower sides(for my use case lag is as high as 0.3 seconds). Is there a work around over which I can keep running a gpio and change its frequency without having to wait for my delay time.

Also the code works without any issues for lower frequency but as soon as I go for a delay in looptime to be less than 6 microseconds, the code doesn't run and ET error is shown with error line pointing to the port <: 0 line(I believe the time taken by <: command is more than my loop time so its getting stuck).

Is there anyway we can use timers to toggle the gpio with on the fly changing frequency of my pulse by using clocks.


User avatar
infiniteimprobability
XCore Legend
Posts: 1126
Joined: Thu May 27, 2010 10:08 am
Contact:

Post by infiniteimprobability »

Hi,
difficult to know exactly what is going on here without the source..

while(1) { select { is generally the right idiom to use although when you get over a MHz or two it is time to think about using the port hardware instead of software events. 6 microseconds (166KHz) sounds like a slow point for loops to run out of oomph (are you using -O3?) using timers and ports.

Can you outline the frequency range and response time you want to achieve? WHat is the mechanism for frequency change? WHat's your jitter spec?
User avatar
infiniteimprobability
XCore Legend
Posts: 1126
Joined: Thu May 27, 2010 10:08 am
Contact:

Post by infiniteimprobability »

How about something like this, using port timers and shared memory as a kind of 1 level deep fifo (which is safe in this instance). Manages 5MHz comfortably but lower end will be limited to 760Hz ish due to 16b port timer. Will need an if statement if you need to get a lower range.

Code: Select all

#include <stdlib.h>
#include <xs1.h>
#include <platform.h>

on tile[0]: out port p_clk =  XS1_PORT_1E;

//Shared memory stuff
unsigned period = 10; //Ticks @ 10ns per ticks so 10->5MHz
unsafe {
  volatile unsigned * unsafe period_ptr = &period;
}

void pulse_gen(void){
  unsigned port_timer_trig;
  p_clk <: 0 @  port_timer_trig; //Grab time
  while(1) unsafe{
     port_timer_trig += *period_ptr;
     p_clk @ port_timer_trig <: 1;
     port_timer_trig += *period_ptr;
     p_clk @ port_timer_trig <: 0;
  }
}

void test(void){
  delay_microseconds(1);
  unsafe{
    *period_ptr = 50000; //1000Hz
  }
  delay_milliseconds(5);
  _Exit(0); //Exit simulation
}

int main(void){
  par{
    on tile[0]: par {
      pulse_gen();
      test();
    }
  }
  return 0;
}
Post Reply