xTIME studio programming problems

Technical questions regarding the XTC tools and programming with XMOS.
prichner
Junior Member
Posts: 7
Joined: Tue Jan 28, 2014 8:42 am

Post by prichner »

Thank you for the help. It does work with your example.


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

Post by infiniteimprobability »

The example is in the XC programming guide page 34.
Thanks for this. You're right - it uses the old naming of stdcore. Actually it is also missing the XC v2 stuff like interfaces and pointers too so it needs an overhaul. I've filed a bug against the doc stating that it shows old conventions, and this is the queue for an update. Personally, I have found this a very helpful document for writing XC so it gets my vote for an update..

Also, I'll second what Bianco said about generating PWM - it's so much better to use the timers in the port to do this because it will reduce CPU effort and increase accuracy (you can get right down to 10ns). Actually, the whole world of PWM can be quite complex, but if you're starting out and having a play, the tutorial example PWM component is probably worth a look (it uses port timers to delay an output to a particular time)

https://github.com/xcore/sc_pwm/blob/ma ... example.xc
prichner
Junior Member
Posts: 7
Joined: Tue Jan 28, 2014 8:42 am

Post by prichner »

Question 1: Witch function have the @ ?
Q2: Where is the big different between mine and the program from your link?
Q3: Can I make macros in the select/case part(see second programm)?
The program below works, but perhaps I can optmize him.

My current code:

Code: Select all

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

in port button1 = XS1_PORT_1K;
in port button2 = XS1_PORT_1L;

out port PWM_signal = XS1_PORT_4C;
out port led = XS1_PORT_4F;

void PWM_Signal(chanend chanel1, chanend chanel2)
{

    unsigned  int time;
    timer t;
    unsigned int onTime = 640, state = 0;
    const unsigned int PERIOD = 1280;
    int dat1,dat2;

    t :> time;
    time += onTime;
    PWM_signal <: 0b0000;

    while(1)
    {
   

        select
        {
            case chanel1 :> dat1 :
                   onTime += 10;
                break;

            case chanel2 :> dat2:
                   onTime -= 10;
                break;

            case t when timerafter (time) :> void :
                onTime %= PERIOD;
                if (state==1 )
                {
                    PWM_signal <: 0b0010;
                    time += onTime;
                }
                else
                {
                    PWM_signal <: 0b0000;
                    time += (PERIOD-onTime);
                }
                state = !state;

                break;
        }
    }
}

void readbutton1 (chanend chanel1)
{
    int dat,flag_button=0,dat2;
    while (1)
    {
        button1 :> dat2;
        if(dat2 == !flag_button)
        {
            button1 :> dat;
            chanel1 <: dat;
        }
        dat2 = flag_button;
        delay_microseconds(20);
  //      delay_milliseconds(500);
    }
}

void readbutton2 (chanend chanel2)
{
    int dat,flag_button=0,dat2;
    while (1)
    {
        button2 :> dat2;
        if(dat2 == !flag_button)
        {
            button2 :> dat;
            chanel2 <: dat;
        }
        dat2 = flag_button;
        delay_microseconds(20);
     //   delay_milliseconds(500);
     }
}
int main(void)
{
    while(1)
    {
        chan a,b;
        par
        {
            PWM_Signal(a,b);
            readbutton1(a);
            readbutton2(b);
        }

    }

    return 0;
}
Q3 example:
Like this it doesn't work. How can I make that it works with macros?
(Programm is the same how above)

Code: Select all

#define SetPwmOutOn  (PWM_signal <: 0b0010)
#define SetPwmOutOff (PWM_signal <: 0b0000)

select
        {
            case chanel1 :> dat1:
               onTime += 10;
                break;

            case chanel2 :> dat2:
               onTime -= 10;
                break;

            case t when timerafter (time) :> void :
                onTime %= PERIOD;
                if (state==1 )
                {
                    SetPwmOutOn;                // macro
                    time += onTime;
                }
                else
                {
                    SetPwmOutOff;                 // macro
                    time += (PERIOD-onTime);
                }
                state = !state;

                break;
        }
User avatar
Bianco
XCore Expert
Posts: 754
Joined: Thu Dec 10, 2009 6:56 pm
Contact:

Post by Bianco »

Using port timers such as in the example code in sc_pwm is still more accurate than using regular timers.

With regular timers as in your code you are doing the following: Wait for the timer to create an event and then you are doing this and that and this (including branches) and then you are doing an output to the port. So your accuracy still depends on instruction speed and branches. The instruction speed is important because with more than 4 xCORES used, the instruction speed may vary in the upper bound (the lower bound is guaranteed), therefore your PWM will also vary.

With port timers such as in sc_pwm you can tell a port to output a certain value at a certain time corresponding with the timer inside the port. This will decouple the timing of outputs from the instruction speed. The only thing you have to ensure is that your code is fast enough to set the new value each time. Therefore this approach will be much more accurate.

About the macro: XC doesn't like the (), so drop them and your macro should work.
prichner
Junior Member
Posts: 7
Joined: Tue Jan 28, 2014 8:42 am

Post by prichner »

Thank you for the answer.
One last question:
Witch function have the @ ?
User avatar
Bianco
XCore Expert
Posts: 754
Joined: Thu Dec 10, 2009 6:56 pm
Contact:

Post by Bianco »

From the PWM example:

Code: Select all

 //get the current port time
  p <: 0 @ now;
Get the port timer value of the time at which this output operation is executed.

Code: Select all

//output falling edge
      p @ edgetime <: 0;
Execute the output operation when the port timer has reached value edgetime (timed output).
The second one will block if you try to do new timed outputs before the old one has 'expired'.
Post Reply