Shop OBEX P1 Docs P2 Docs Learn Events
XMOS chips vs. P2 - Page 6 — Parallax Forums

XMOS chips vs. P2

1468910

Comments

  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2011-08-04 09:37
    jazzed wrote:
    To further define the advantage, maybe you can talk about the different types of "professionals" and the ones who benefit from SPIN.

    The professionals who benefit from Spin and PASM are those who are neither hide-bound by organizational strictures nor afraid (or too busy) to learn something new that could aid productivity. I'm thinking of nimble, small or one-person dev "teams" who, like me, get to choose the tools they use for reasons other than convention or management fiat.

    How's that? :)

    -Phil
  • hippyhippy Posts: 1,981
    edited 2011-08-04 09:46
    Coley wrote: »
    At every opportunity you tell us how much better the XMOS is than Propeller.

    If it's so good then why not actually go and do something with it instead of wasting your time over here.

    Am I the only one here who is sick and tired of it?

    No you are not.

    It seems to me people mostly come here because they are using a Propeller and want some type of help, information, guidance, encouragement, brain-storming or other participation with that.

    Leon; your 'XMOS beats the Propeller' hands-down' responses do nothing to further those goals and it's ultimately hijacking the forum and tediously predictable as well. You seemingly take every opportunity to suggest XMOS is better than Propeller, that the Propeller is inferior to XMOS, and it looks like an agenda to me.

    It appears you are more interested in encouraging people elsewhere than encouraging their Propeller use or helping them with that. In the sense of this being a Propeller community; you're not only 'not a team player', you're playing for a different team.

    That's not to say that valid criticism of the Propeller and comparisons are always off-limit, but it's not necessary to seize every chance to promote an alternative. Taking that approach makes you look very much like an agent provocateur attempting to undermine Parallax and the Propeller.

    The bottom-line questions are; why are you here and who are you here to help - Parallax and the Propeller community or XMOS and the XMOS community ? I'm not looking for an answer, it is however something to reflect upon.
  • LeonLeon Posts: 7,620
    edited 2011-08-04 09:57
    I do a lot to help other members of this forum, look at my posts.

    I've started a wireless sensor project which uses the Propeller, and will be getting some low-cost PCBs made for anyone who wants to experiment with this technology:

    http://forums.parallax.com/showthread.php?133570-Propeller-based-wireless-sensor-using-the-nRF24L01&p=1024194#post1024194
  • TorTor Posts: 2,010
    edited 2011-08-04 11:22
    hippy wrote: »
    Leon; your 'XMOS beats the Propeller' hands-down' responses do nothing to further those goals and it's ultimately hijacking the forum and tediously predictable as well. You seemingly take every opportunity to suggest XMOS is better than Propeller, that the Propeller is inferior to XMOS, and it looks like an agenda to me.
    Sorry for jumping in on this thread, but the above is simply over the top. I've read everything Leon wrote about the XMOS in this thread, and some others, and never did he write _anything_ that gives you any right to interpret it as 'XMOS beats the Propeller hands-down', or anything else you write in the quote above. What utter rubbish. Sorry for saying that, but that what it is. Learn to read, please.

    -Tor
  • LeonLeon Posts: 7,620
    edited 2011-08-04 11:52
    hippy,

    I don't recall saying anything of the sort, either! Andre asked for input on XMOS chips vs. P2, and I answered him. What is wrong with that? If anything I said was incorrect, please point it out.
  • Sal AmmoniacSal Ammoniac Posts: 213
    edited 2011-08-04 12:36
    K2 wrote: »
    But if you think you can easily exploit the features that make XMOS uniquely XMOS, you are sniffing glue. One can rattle off a whole list of features, but they are all meaningless if you can't make them work. I know specific cases where very intelligent and motivated individuals wasted months of their lives on XMOS and finally gave up in disgust.

    Details, please.

    My experience with XMOS has been the opposite. I find the tools easy to use and have not had any trouble using the features that make XMOS unique. I even program it in its assembly language, which I find rather easy to use.
  • User NameUser Name Posts: 1,451
    edited 2011-08-04 12:44
    @ Tor - Leon's past walked into this thread with him. Hippy is right on the mark.

    BTW, the whole family had a laugh over the BBC video Coley posted yesterday There is another Harry Enfield video on YouTube called "Women: Know Your Limits." It is priceless, too. Highly recommended!
  • K2K2 Posts: 691
    edited 2011-08-04 14:26
    My experience with XMOS has been the opposite. I find the tools easy to use and have not had any trouble using the features that make XMOS unique. I even program it in its assembly language, which I find rather easy to use.

    Details yourself! :) Let's hear what you've done. Seriously. There is a dearth of factual experience in this thread. You could change that.

    If nothing else, post a hyperlink where interested parties might go to learn more about what you're doing and what you've learned.
  • K2K2 Posts: 691
    edited 2011-08-04 15:53
    Details, please.

    In the spirit of full disclosure, I confess that I'm juggling about six balls at once, so spending my time keeping up on XMOS has not been a priority. Furthermore, Leon's annoying trolling on the Forum was seriously alienating me to XMOS. But that's no fault of XMOS, except that they should have never comp'd him boards. ;)

    But at Sal Ammoniac's prompting, instead of getting my work done this afternoon I contacted several of the individuals who had delivered such negative reports of XMOS to me some time back. Seems like absent, inadequate, and inaccurate documentation plagued XMOS for a while after the release of chips. By all accounts this led to great frustration. Sources that I trust tell me that has largely disappeared. It takes a lot to get a new product out the door. Some things slip through the cracks in the rush.

    So, I offer my apologies to all non-trolling Subjects of the Crown, whose contributions here are legendary.

    Edit: Now if you'll excuse me, I'll turn Jethro Tull back up and get to work!
  • Sal AmmoniacSal Ammoniac Posts: 213
    edited 2011-08-04 16:02
    K2 wrote: »
    Details yourself! :) Let's hear what you've done. Seriously. There is a dearth of factual experience in this thread. You could change that.

    My most recent XMOS project is a high-speed data collection and analysis widget. I'm working on putting up a web page describing it and will post it here if anyone is interested when it's done.
  • rod1963rod1963 Posts: 752
    edited 2011-08-04 16:07
    Its amusing, all the vitriol is coming not from Leon who conducts himself quite well, though he says things that some of the fan bois here start spitting blood over. Heck a few of them just plain hate Leon from the looks of it. No matter where he post they stalk him.

    What a nice group of people Parallax is cultivating.
  • LeonLeon Posts: 7,620
    edited 2011-08-04 16:22
    If anyone is using the XMOS tools, you need to make sure that you are using the latest version, it gets updated frequently with bug fixes and new features. The current version is 11.2.2. I've found a minor bug - with some projects the symbol against an executable indicating whether it's a Release or Debug version indicates that the file is a Debug version although it is in the Release folder.

    The XDE comes with various applications. Here is an example of parallel processing with a messaage being output from each of four cores on an XC-1 or XC-1A board:
    /*
     ============================================================================
     Name        : Test.xc
     Description : Multicore Hello World in XC using channels 
     ============================================================================
     */
    
    #include <print.h>
    #include <platform.h>
    
    void hello0(chanend cout);
    void hello1(chanend cin, chanend cout);
    void hello2(chanend cin, chanend cout);
    void hello3(chanend cin);
    
    int main(void) {
    
        chan c1, c2, c3;
        
    	par{
    		on stdcore[0] : hello0(c1);
    		on stdcore[1] : hello1(c1, c2); 	
    		on stdcore[2] : hello2(c2, c3);
    		on stdcore[3] : hello3(c3);
    	}
    	return 0;
    }
    
    void hello0(chanend cout){
        printstrln("Hello from core 0!");
        cout <: 1;
    }
    
    void hello1(chanend cin, chanend cout){
        cin :> int;
        printstrln("Hello from core 1!");
        cout <: 1;
    }
    
    void hello2(chanend cin, chanend cout){
        cin :> int;
        printstrln("Hello from core 2!");
        cout <: 1;
    }
    
    void hello3(chanend cin){
        cin :> int;
        printstrln("Hello from core 3!");
    }
    

    One doesn't even have to use a terminal program, the output is directed to the XDE console on the PC. It illustrates how easy it is to do parallel processing on the XMOS devices. What makes it so easy are the XC par construct and the use of channels.

    It should be fairly self-evident how XC handles parallelism, even without reading any documentation, for anyone with some knowledge of C programming.
  • Kevin WoodKevin Wood Posts: 1,266
    edited 2011-08-04 17:27
    K2 wrote:
    In the spirit of full disclosure, I confess that I'm juggling about six balls at once, so spending my time keeping up on XMOS has not been a priority. Furthermore, Leon's annoying trolling on the Forum was seriously alienating me to XMOS.

    Be that as it may, your trolling wrt Leon is alienating people from Parallax.

    Considering that you've already publicly stated that you don't care if you stir up strife in these forums...
    K2 wrote:
    But this is a cause I believe in. That's way I'm willing to take all the abuse and even alienate a portion of the community against me. Truth is more important than popularity.

    ...then there is some question as to your true motives. Who knows, maybe Leon really does want to lead people to XMOS. But even if he does, he's not resorting to personal attacks to do so.

    The truth is, somebody finding this thread and trying to decide between the Propeller and XMOS can find enough information, provided by Leon, to go out and get started using the XMOS. There has been no equivalent, level-headed, easy to digest information provided by yourself, or anybody else whose primary contribution to this thread has been to attack Leon, for the Propeller.

    That's what people walk away with.

    Please stop demanding that everybody prove their value and worth to you via this, that, and the other. Post your own XMOS projects and let them speak for themselves. You've gone from calling out Leon to also calling out Sal Ammoniac, which is not your place to do so. Let Parallax do it if it's warranted.
  • jazzedjazzed Posts: 11,803
    edited 2011-08-04 19:46
    It's a perfect answer thanks.

    The "managed professionals" taking the "safe path" now have a chance to understand your independent perspective.

    The professionals who benefit from Spin and PASM are those who are neither hide-bound by organizational strictures nor afraid (or too busy) to learn something new that could aid productivity. I'm thinking of nimble, small or one-person dev "teams" who, like me, get to choose the tools they use for reasons other than convention or management fiat.

    How's that? :)

    -Phil
  • SapiehaSapieha Posts: 2,964
    edited 2011-08-04 20:51
    Hi Phil Pilgrim (PhiPi).

    I agree with You.

    BUT in my understanding that Professionals what can't work with that (Tools/Hardware). Them are not Professionals ---> Them are automatically evangelists on tools like "C" else that ones them understand

    The professionals who benefit from Spin and PASM are those who are neither hide-bound by organizational strictures nor afraid (or too busy) to learn something new that could aid productivity. I'm thinking of nimble, small or one-person dev "teams" who, like me, get to choose the tools they use for reasons other than convention or management fiat.

    How's that? :)

    -Phil
  • jmgjmg Posts: 15,148
    edited 2011-08-04 21:22
    To bring this back on topic, to compare Xmos / Prop / Prop2, I'll propose a simple benchmark or two.

    For starters, let a wizard in each core, code a Single Channel 32 bit Quadrature Counter to be as fast as possible, in each device.
    That's likely to be a few lines of Assembler, and maybe a small table.
    This counter should be atomic readable from another software thread.

    As a reality check, I'll add a Hardware assisted example, that allows a small amount of external logic, 'to do what the chip designers forgot'.
    Here, I'll add the smallest SPLD, a sub $1 16V8, which will precondition a Quad signal, to two UP COUNTS, pulsing 2 SysCLKs wide, each Quad edge
    (and the Quad is then the difference of the two counters).
    This solution would use 2 PHSx in a Prop, and the external Logic, and could Quad.Count at up to 20MHz (for a 80MHz SysCLK)
  • LeonLeon Posts: 7,620
    edited 2011-08-05 01:28
    I found a reference to this on the XCore Exchange forum:

    https://www.xmos.com/applications/robotics-and-motor-control/quadrature-decoder

    The code is written in XC with a standard C file with some assembler stuff for channel handling and is intended for the XC-1 board, using the buttons to simulate the encoder hardware and transmitting the data back to the PC. It compiles OK.

    I'll strip out all the irrelevant stuff and get some initial timings. It probably isn't suitable for this competition as it stands.
  • RossHRossH Posts: 5,353
    edited 2011-08-05 02:01
    Leon wrote: »
    I found a reference to this on the XCore Exchange forum:
    ...
    The code is written in XC with a standard C file with some assembler stuff for channel handling and is intended for the XC-1 board ...

    Man, that is some seriously un-froody code! Do you really have to use XC, C and embedded assembler just to do something like that?

    No wonder people say the XMOS is hard to use.

    Ross.
  • LeonLeon Posts: 7,620
    edited 2011-08-05 02:15
    It's a very old program (2008) and can be simplified a lot with the current tools and libraries. There isn't much code there, anyway - just a small XC and C file. The code in the C file is some inline assembler to set up the comms channels to/from the PC:
    /* Quadrature Decoder with Serial I/O and Clock LED Driver
     * (c)2008 Henrob Corporation
     * Written by P.J.Elliot with parts borrowed from XMOS examples
     * Distributed under the terms of the MIT license
     * This code is provided "as-is" without any warranty, use it at your own risk.
     *
     * This code runs on a XC-1 board with a 115,200 baud terminal provided by the
     * FDTI USB interface.
     *
     * Interaction:
     *
     *  Buttons: A/B - Quadrature pairs
     *             C - Index
     *             D - Home
     *
     *  Terminal:  i - Index
     *             r - Zero Revs
     *             h - Home
     *             , - Count Down
     *             . - Count Up
     *
     *  Clock LEDs:   Red - Revolution count
     *              Green - Counts within Revolution
     *
     * Note: For this example the counts per revolution has been set to '12'.
     *			 Normal encoder would have 2048/8192 counts per revolution.
     *
     */
    
    #include <xs1.h>
    
    #define CLK_REF					100000000
    
    // Clock LEDs and serial output clocks
    #define FLASH_PERIOD 		100000
    #define CYCLE_PERIOD 		100000000
    #define FREQUENCY 			12000
    #define OUTPUT_RATE 		100000000
    #define UPDATE_RATE 		1000000
    
    // Quadrature defines
    #define	MaxRevs					1024
    #define	MaxRevsM1				(MaxRevs-1)
    #define	MaxRevsD2				(MaxRevs/2)
    #define	MaxCounts				12
    #define	MaxCountsM1			(MaxCounts-1)
    
    #define MAX_GLITCH		250
    
    // Serial Communications Defines
    #define BIT_LENGTH			(CLK_REF/115200)
    #define STOP_BIT_LENGTH	BIT_LENGTH
    
    #define	FALSE	0
    #define TRUE	1
    
    //{{{  Function definitions
    // Function definitions
    void setRegVal(int processor, int psctl, int reg, int n);
    
    int QUADhandler(in port QuadPort, chanend c_command, chanend c_position,chanend c_sound);
    int LEDhandler(chanend c_command, chanend c_position, chanend c_utx, chanend c_urx, chanend c_sound);
    int UART_TXhandler(out port TxD, chanend c_utx);
    int UART_RXhandler(in port RxD, chanend c_urx);
    
    int sprintint(char bytes[], int value, int width, int dp);
    void printint(chanend txd, int value, int width, int dp);
    int printstr(chanend txd, char OutStr[], int Len);
    void newline(chanend txd);
    //}}}
    
    
    //{{{  Define Ports
    // Define Ports Used
    
    out port op_cled_0 	= XS1_PORT_4A;
    out port op_cled_1 	= XS1_PORT_4B;
    out port op_cled_2 	= XS1_PORT_4C;
    out port op_cled_g 	= XS1_PORT_1E;
    out port op_cled_r 	= XS1_PORT_1F;
    out port op_kled 		= XS1_PORT_8D;
    out port op_speaker = XS1_PORT_1K;
    
    out port op_TxD			= XS1_PORT_1H;
    in port ip_RxD			= XS1_PORT_1I;
    
    in port ip_buttons 	= XS1_PORT_4D;
    //}}}
    
    //{{{  Main Application
    int main(void) {
    	chan c_command, c_position, c_utx, c_urx, c_sound;
    
    //	setRegVal(processor,psctl,reg,val);
    	setRegVal(0, 0, 7, 128);	// CPU 0 - Low power link mode (Reg 7)
    	setRegVal(1, 1, 6, 128);	// CPU 1 - Low power mode (Reg 6)
    	setRegVal(2, 1, 6, 128);	// CPU 2 - Low power mode (Reg 6)
    	setRegVal(3, 1, 6, 128);	// CPU 3 - Low power mode (Reg 6)
    
    	par {
    		QUADhandler(ip_buttons, c_command, c_position, c_sound);
    		LEDhandler(c_command, c_position, c_utx, c_urx, c_sound);
    		UART_TXhandler(op_TxD, c_utx);
    		UART_RXhandler(ip_RxD, c_urx);
    	}
    	return 0;
    }
    
    
    //}}}
    
    
    //{{{  int LEDhandler(chanend c_command, chanend c_position, chanend c_uart_tx, chanend c_uart_rx, chanend c_sound)
    int LEDhandler(chanend c_command, chanend c_position, chanend c_utx, chanend c_urx, chanend c_sound) {
    	unsigned position = 0;
    	unsigned ledOn = 1;
    	unsigned Tone = 1;
    	unsigned ledVal_g = 0x0001;
    	unsigned ledVal_o = 0;
    	unsigned ledVal_r = 0x0001;
    	unsigned timeC, timeF, timeS, timeU;
    	unsigned SoundOn=0;
    	unsigned RXchar;
    
    	signed revs,cnts,value;
    
    
    	timer tmrC, tmrF, tmrS, tmrU;
    
    	tmrC :> timeC;
    	tmrF :> timeF;
    	tmrS :> timeS;
    	tmrU :> timeU;
    
    	while (1) {
    		select {
    			case tmrF when timerafter(timeF) :> int _ :
    				//{{{  Handle LED update
    				/********************************************************
    				 * Update LEDs RED ORANGE GREEN ORANGE RED etc...       *
    				 * with Orange given half the time, but displayed twice *
    				 ********************************************************/
    				if (ledOn<2) {
    					op_cled_g <: 1;
    					op_cled_r <: 0;
    				} else {
    					op_cled_g <: 0;
    					op_cled_r <: 1;
    				}
    				switch (ledOn){
    					case 0:
    					case 2:
    						op_cled_2 <: ledVal_o;
    						op_cled_0 <: (ledVal_o >> 4);
    						op_cled_1 <: (ledVal_o >> 8);
    						timeF += (FLASH_PERIOD/2);
    						break;
    					case 1:
    						op_cled_2 <: ledVal_g;
    						op_cled_0 <: (ledVal_g >> 4);
    						op_cled_1 <: (ledVal_g >> 8);
    						timeF += FLASH_PERIOD;
    						break;
    					case 3:
    						op_cled_2 <: ledVal_r;
    						op_cled_0 <: (ledVal_r >> 4);
    						op_cled_1 <: (ledVal_r >> 8);
    						timeF += FLASH_PERIOD;
    						break;
    				}
    				ledOn=(ledOn+1) & 0x03;
    				break;
    				//}}}
    
    			case tmrS when timerafter(timeS) :> int _ :
    				//{{{  Play tone when requested
    				/********************************************************
    				 * Play fixed tone for duration set in Variable SoundOn *
    				 * Change: FREQUENCY define to change the pitch         *
    				 ********************************************************/
    				if (SoundOn>0) {
    					op_speaker <: Tone;
    					Tone=~Tone;
    					SoundOn--;
    				}
    				timeS += FREQUENCY;
    				break;
    				//}}}
    
    			case tmrC when timerafter(timeC) :> int _ :
    				//{{{  Read Position
    				/********************************************************
    				 * Read position from Quadrature Task at 'UPDATE_RATE'  *
    				 * and update the red and green LED positions           *
    				 ********************************************************/
    				c_command <: 3;
    				c_position :> position;
    
    				revs=(position>>16);
    				if (revs>MaxRevsD2) ledVal_r = 0x0001 << (11-((MaxRevsM1-revs)%12));
    				else ledVal_r = 0x0001 << (revs%12);
    
    				cnts=(position & 0xFFFF);
    				if (cnts>MaxCountsM1) cnts=MaxCountsM1;
    				ledVal_g = 0x0001 << (((12*cnts)/MaxCounts)%12);
    
    				timeC += UPDATE_RATE;
    				break;
    				//}}}
    
    			case tmrU when timerafter(timeU) :> int _ :
    				//{{{  Send current position to terminal
    				/********************************************************
    				 * Read position from Quadrature Task at 'OUTPUT_RATE'  *
    				 * and send the Revs/Counts and mm (5mm/rev) to serial  *
    				 * port.                                                *
    				 * Note: Negative revs is displayed as a big +ve no.    *
    				 ********************************************************/
    				c_command <: 3;
    				c_position :> position;
    
    				revs=(position >> 16);
    				printstr(c_utx,"R:",2);
    				printint(c_utx,revs,0,0);
    				cnts=(position & 0xFFFF);
    				printstr(c_utx," C:",3);
    				printint(c_utx,cnts,0,0);
    
    				if (revs>MaxRevsD2) revs-=MaxRevs;
    				value=(revs*5000)+((cnts*5000)/MaxCounts);
    				printstr(c_utx," > Pos: ",-1);
    				printint(c_utx,value,0,3);
    				newline(c_utx);
    
    				timeU += OUTPUT_RATE;
    				break;
    				//}}}
    
    			case c_sound :> SoundOn :
    				break;
    			case c_urx :> RXchar :
    				//{{{  Handle uart input
    				/********************************************************
    				 * Handle uart input                                    *
    				 * Note: Unknown character is echoed and an tone played *
    				 ********************************************************/
    				switch (RXchar) {
    					case ',':	c_command <: 5; break;	// Decrement quad count
    					case '.':	c_command <: 4; break;	// Increment quad count
    					case 'i':	c_command <: 2; break;	// Index - zero count, keep revs same
    					case 'r':	c_command <: 1; break;	// Revs  - zero revs, keep count same
    					case 'h': c_command <: 0; break;  // Home  - zero revs and count
    					default:
    						c_utx <: RXchar;	// Echo input
    						newline(c_utx);		// Echo input
    						SoundOn=100;
    						break;
    				}
    				break;//}}}
    
    		}
    	}
    	return 0;
    }//}}}
    
    //{{{  int QUADhandler(chanend c_command, chanend c_position, chanend c_sound)
    /********************************************************
     * Provide Quadrature port using a four pin input port  *
     *   Pin 0 - Channel A                                  *
     *   Pin 1 - Channel B                                  *
     *   Pin 2 - Channel Index                              *
     *   Pin 3 - Channel Home                               *
     *                                                      *
     * MAX_GLITCH is the maximum glitch size filtered out   *
     ********************************************************/
    int QUADhandler(in port QuadPort, chanend c_command, chanend c_position, chanend c_sound) {
      unsigned Revolutions=0;
      unsigned Counts=0;
      unsigned oQuad,QuadAll,CtrlAll;
    	unsigned command;
      unsigned timeG;
      int IncDec=0;
    	int HomeIndex=0;
    
    	timer tmrG;
    
    													// 0000 0001 0010 0011 0100 0101 0110 0111
    	static int IncDecVals[]= {    0,   1,  -1,   0,  -1,   0,   0,   1,
    														    1,   0,   0,  -1,   0,  -1,   1,   0 };
    													// 1000 1001 1010 1011 1100 1101 1110 1111
    
    	//  0 = Invalid/No Transition
    	//  1 = Increment count
    	// -1 = Decrement count
    
    													// 0000 0001 0010 0011 0100 0101 0110 0111
    	static int HomeIdxVals[]={    0,   1,   2,   3,   1,   0,   3,   2,
    														    2,   3,   0,   1,   3,   2,   1,   0 };
    													// 1000 1001 1010 1011 1100 1101 1110 1111
    
    	// 0 = Invalid/No Transition
    	// 1 = Index Transition
    	// 2 = Home Transition
    	// 3 = Index & Home Transition
    
    	QuadPort :> oQuad;															// Read initial condition
    	QuadAll = ((oQuad & 0x03)<<2) + (oQuad & 0x03);	// Initialize QuadAll to oQuad.10|oQuad.10
    	CtrlAll = (oQuad & 0x0C) + ((oQuad & 0x0C)>>2);	// Initialize CtrlAll to oQuad.23|oQuad.23
    	while (1) {
    		select {
    			case  QuadPort when pinsneq(oQuad) :> oQuad :
    				op_kled <: (~oQuad << 4);
    				tmrG :> timeG;
    				select {
    					case QuadPort when pinsneq(oQuad) :> oQuad :
    						break;
    					case tmrG when timerafter(timeG+MAX_GLITCH) :> int _ :
    						QuadAll = ((QuadAll<<2) | (oQuad & 0x03)) & 0xF;
    						CtrlAll = ((CtrlAll<<2) | ((oQuad & 0x0C)>>2)) & 0xF;
    						HomeIndex=HomeIdxVals[CtrlAll];
    						if (HomeIndex>0) {			// Home/Index transition
    							if (HomeIndex & 01) {	// Index transition
    								//{{{  Handle Index Pulse
    								if ( (Counts>(MaxCounts/4)) && (Counts<((3*MaxCounts)/4)) ) {
    									if (Revolutions<MaxRevsM1) Revolutions++;
    									else Revolutions=0;
    								}
    								Counts=0;//}}}
    
    							}
    							if (HomeIndex & 02) {	// Home transition
    								//{{{  Handle Home Pulse
    								Revolutions=0;
    								Counts=0;//}}}
    
    							}
    						} else {
    							IncDec=IncDecVals[QuadAll];
    							//{{{  Inc/Dec position
    							if (IncDec==0) c_sound <: 200;
    							else if ((Counts==0) && (IncDec<0)) {
    								Counts=MaxCountsM1;
    								if (Revolutions==0) Revolutions=MaxRevsM1;
    								else Revolutions--;
    							}	else if ((Counts==MaxCountsM1) && (IncDec>0)) {
    								Counts=0;
    								if (Revolutions==MaxRevsM1) Revolutions=0;
    								else Revolutions++;
    							}	else Counts+=IncDec;
    							//}}}
    
    						}
    						break;
    				}
    				break;
    			case c_command :> command :
    				//{{{  Handle position request commands
    				/********************************************************
    				 * Handle Quadrature interaction commands from other    *
    				 * tasks via c_command channel                          *
    				 ********************************************************/
    
    				switch (command) {
    					case 0:	// Home - zero Revolutions and counts
    						Revolutions=0;
    						Counts=0;
    						break;
    					case 1:	// Zero Revolutions, leave counts untouched
    						Revolutions=0;
    						break;
    					case 2:	// Zero Counts and leave Revolutions untouched
    						Counts=0;
    						break;
    					case 3: // Return position with Revs in top 16 bits, Count in lower 16 bits
    						c_position <: ((Revolutions<<16) | Counts);
    						break;
    					case 4:	// Increment the count/revolutions
    						if (Counts==MaxCountsM1) {
    							Counts=0;
    							if (Revolutions==MaxRevsM1) Revolutions=0;
    							else Revolutions++;
    						} else Counts++;
    						break;
    					case 5: // Decrement the count/revolutions
    						if (Counts==0) {
    							Counts=MaxCountsM1;
    							if (Revolutions==0) Revolutions=MaxRevsM1;
    							else Revolutions--;
    						} else Counts--;
    						break;
    				}
    				break;//}}}
    
    		}
    	}
    	return 0;
    }//}}}
    
    //{{{  int UART_TXhandler(out port TxD, chanend c_uart_tx)
    /********************************************************
     * Provide FIFO Buffered output via the USB serial port *
     *                                                      *
     * Data sent in channel c_utx                           *
     * Serial output via port pin TxD                       *
     ********************************************************/
    int UART_TXhandler(out port TxD, chanend c_utx) {
    	unsigned j,NewByte;
    	unsigned values[32];
    	unsigned InPtr=0;
    	unsigned OutPtr=0;
    	unsigned Full=FALSE;
    	unsigned timeTX;
    
    	signed SendByte=-1;											// No data to send...
    
    	timer tmrTX;
    
    	TxD <: 1;																// Initialize Uart...
    	tmrTX :> timeTX;
    	tmrTX when timerafter(timeTX+STOP_BIT_LENGTH) :> int _ ;
    	while (1) {															// Loop forever
    		//{{{  Get next byte to send (wait if necessary)
    		if (InPtr!=OutPtr) {								//     Data available
    			/* Data in buffer */
    			SendByte=values[OutPtr];					//       Read data from FIFO
    			OutPtr=(OutPtr+1) & 31;						//       increment OutPtr, with wrap
    		} else c_utx :> SendByte;						//     Read data direct from channel!
    		//}}}
    
    		Full=FALSE; 													// Not full as I've pulled a character!
    
    		/* Send Data */
    		TxD <: 0;														// Send Start Bit
    		tmrTX :> timeTX;										// get port time
    		timeTX += BIT_LENGTH;
    		j=0;
    		while (j<9) {
    			if (Full==FALSE) {
    				select {
    					// Check Channel
    					case 	c_utx :> NewByte :				//     Read data from channel into FIFO
    						//{{{  Read new character and store in FIFO
    						values[InPtr]=NewByte;
    						InPtr=(InPtr+1) & 31;							//     increment InPtr, with wrap
    						Full=(InPtr==((OutPtr+31)&31));		// Update the FIFO full flag
    						break;//}}}
    
    					// Wait for next bit time
    					case tmrTX when timerafter(timeTX) :> int _ :
    						if (j<8) {
    							TxD <: >> SendByte;
    							timeTX += BIT_LENGTH;
    						} else {
    							TxD <: 1;
    							timeTX += STOP_BIT_LENGTH;
    						}
    						j++;
    						break;
    				}
    			} else {
    				// send only
    			 	tmrTX when timerafter(timeTX) :> int _;
    				if (j<8) {
    					TxD <: >> SendByte;
    					timeTX += BIT_LENGTH;
    				} else {
    					TxD <: 1;
    					timeTX += STOP_BIT_LENGTH;
    				}
    				j++;
    			}
    		}
    	 	tmrTX when timerafter(timeTX) :> int _;
    	}																								//
    	return 0;																				//
    }
    
    //}}}
    
    //{{{  int UART_RXhandler(in port RxD, chanend c_uart_rx)
    /********************************************************
     * Serial input via the USB serial port                 *
     *                                                      *
     * Data needs to be read from c_urx channel promptly to *
     * prevent underrun                                     *
     ********************************************************/
    int UART_RXhandler(in port RxD, chanend c_urx) {
    	int temp;
      int input_val;          // The current value being inputted
      unsigned time, timerRX;
    
    	timer tmrRX;
    
    	while (1) {
        input_val=0;
    
    		RxD when pinseq(0) :> int _;							// Wait for start bit
    		tmrRX :> timerRX;													// Read time it occurred
    		/* Wait until 0 returned for half of BIT_TIME or revert to a 1 on the port */
    		select {
    			case RxD when pinseq(1) :> int _ :			// False start bit (glitch)
    				break;																//   Don't do anything
    			case tmrRX when timerafter(timerRX+(BIT_LENGTH/2)) :> int _ :
    				RxD :> temp @ time;										// Get port time
    				for (int j=0; j<8; j++) {							// Data bits
    					time += BIT_LENGTH;									//   delay until next bit time
    					RxD @ time :> >> input_val; 				//   read input port at this time
    				}																			//
    				c_urx <: (input_val >> 24);				// Send Input (Data in high byte)
    				RxD @ (time + BIT_LENGTH) :> temp;		// discard stop bit
    				break;
    		}
    
    	}
      return 0;
    }
    
    //}}}
    
    
    //{{{  Serial/String Functions
    //{{{  void sprintint(char OutStr[], int value, int width)
    /********************************************************
     * Print Integer into string with negative sign and     *
     * fixed decimal point position                         *
     *   Input: Value, Width, Decimal Point Positions       *
     *  Output: String                                      *
     ********************************************************/
    int sprintint(char OutStr[], int value, int width, int dp) {
    	int i=0;
    	int negative=FALSE;
    	int j=10000000;
    	int digits,min_width,k;
    	int lastcell,negcell;
    	char IntStr[16];
    
    	if (value<0) { value*=-1;	negative=TRUE; }
    
    	//{{{  Form integer value in IntStr[]
    	// Form integer value in IntStr[]
    	if (value>0) {
    		digits=0;
    		while (j>0) {
    			if (value>=j) {
    				IntStr[digits++]=(char)((value/j)+'0');
    				value=value%j;
    			} else if (digits>0) IntStr[digits++]=(char)'0';
    			j/=10;
    		}
    		if (digits==0) digits++;
    	} else {
    		digits=1;
    		IntStr[0]='0';
    	}
    	// digits holds number of numbers (less . - and leading 0s) in number//}}}
    
    	//{{{  Calculate width needed
    	// Calculate number of characters needed to hold number
    	min_width=digits;
    	if (min_width<1) min_width=1;
    	if (dp) {
    		if (min_width>dp) min_width++;	// Add space for .
    		else min_width=(dp+2);					// Add space for . and leading 0s
    	}
    	if (negative) min_width++;				// Add space for -
    	//}}}
    
    
    	if (width<min_width) width=min_width;		// Increase output size to hold number
    	for (i=0; i<width; i++) OutStr[i]=' ';	// Wipe output string
    	OutStr[width]=0;												// Add end of string marker
    	lastcell=width;
    	negcell=(width-min_width);
    	if (negcell<0) negcell=0;
    
    	// Add leading zeros in fixed point number
    	if (dp) {
    		k=(width-1);
    		for (i=0; i<dp; i++) OutStr[k--]='0';	// Pad
    		OutStr[k--]='.';	// Pad
    		OutStr[k--]='0';	// Pad
    	}
    
    	// Fill number into string
    	i=(lastcell-1);
    	k=0;
    	for (j=(digits-1); j>=0; j--) {
    		if ((dp>0) && (k==dp)) i--;	// Skip over decimal place
    		OutStr[i--]=IntStr[j];
    		k++;
    	}
    
    	if (negative) OutStr[negcell]='-';
    	return width;
    }
    //}}}
    
    //{{{  void printint(chanend txd, int value, int width, int dp)
    /********************************************************
     * Print Integer to UART                                *
     ********************************************************/
    void printint(chanend txd, int value, int width, int dp) {
    	int i=0;
    	char OutStr[16];
    
    	i=sprintint(OutStr, value, width, dp);
    	printstr(txd,OutStr,i);
    }
    //}}}
    
    //{{{  void printstr(chanend txd, char OutStr[])
    /********************************************************
     * Print string to UART                                 *
     ********************************************************/
    int printstr(chanend txd, char OutStr[],int StrLen) {
    	int i=0;
    
    	if (StrLen<0) {
    		StrLen=0;
    		while (OutStr[i++]!=0) StrLen++;
    	}
    	for (i=0; i<StrLen; i++) txd <: (unsigned)OutStr[i];
    
    	return i;
    }
    //}}}
    
    //{{{  void newline(chanend txd)
    /********************************************************
     * Print newline to UART                                *
     ********************************************************/
    inline void newline(chanend txd) {
    	txd <: 13;
    	txd <: 10;
    }//}}}
    //}}}
    
    
    
    
    inline unsigned getchanend(unsigned otherside) {
    	unsigned chanend;
    	__asm__ __volatile__ ("getr %0, 2"
    	 : "=r" (chanend));
    	__asm__ __volatile__ ("setd res[%0], %1"
    	 : : "r" (chanend), "r" (otherside) );
    	return chanend;
    }
    
    inline void freechanend(unsigned chanend) {
    	__asm__ __volatile__ ("freer res[%0]"
    	 : /* no output */
    	 : "r" (chanend));
    }
    
    inline void getr(unsigned chan, unsigned token) {
    	__asm__ __volatile__ ("out res[%0], %1"
    	: /* no output */
    	: "r" (chan)
    	, "r" (token));
    }
    
    inline void outt(unsigned chan, unsigned token) {
    	__asm__ __volatile__ ("outt res[%0], %1"
    	: /* no output */
    	: "r" (chan)
      , "r" (token));
    }
    
    inline void outct(unsigned chan, unsigned token) {
    	__asm__ __volatile__ ("outct res[%0], %1"
    	: /* no output */
    	: "r" (chan)
    	, "r" (token));
    }
    
    inline void chkct(unsigned chan, unsigned token) {
    	__asm__ __volatile__ ("chkct res[%0], %1"
    	: /* no output */
    	: "r" (chan)
    	, "r" (token));
    }
    
    void setRegVal(int processor, int psctl, int reg, int n) {
    	int o = processor<<16 | (psctl ? 0xC20C : 0xC30C);
    	unsigned c = getchanend(o);
    	outct(c, 0xc0);  //CTOKEN_CWRITE
    	outt(c, 0);
    	outt(c, 0);
    	outt(c, (c>>8));
    	outt(c, 0);    // reg num
    	outt(c, reg);  // reg num
    	outt(c, 0);    // val
    	outt(c, 0);    // val
    	outt(c, 0);    // val
    	outt(c, n);  		// val
    	outct(c, 1);
    	chkct(c,3);
    	chkct(c,1);
    	freechanend(c);
    }
    
    /* Example
    main() {
    	setRegVal(1, 6, 1, 128);
    	setRegVal(1, 6, 2, 128);
    	setRegVal(1, 6, 3, 128);
    	setRegVal(0, 7, 0, 128);
    	//  setRegVal(1, 6, 0, 128);
    	while(1);
    }
    */
    
    

    I've just checked it on my XC-1 board and it seems to work OK, displaying data in RealTerm. It only took me a couple of minutes to build and test it. It's running on a 1600 MIPS XS1-G4 four-core chip.

    The QUADhandler function does all the actual work.
  • AleAle Posts: 2,363
    edited 2011-08-05 02:20
    Nice one Leon!

    The C/asm part is only to put the rest of the chip to sleep (not really needed, I only read about it in some documentation, never saw an implementation, nicely done)... nothing to do with the decode... As Leon pointed out, it is used for UART (I am sure it can be done some other way... like using puts directly via de debug port....).
    And to be fair the propeller version will need also assembler for the UART part... something that is implemented in XC...
  • RossHRossH Posts: 5,353
    edited 2011-08-05 02:23
    Nope, still not getting it. I need XC to talk to C to talk to assembler to talk to channels to ... um ... what was the point of the program again?

    Ross.
  • LeonLeon Posts: 7,620
    edited 2011-08-05 02:33
    The early version of the tools was very primitive, and didn't have any library functions for stuff like string handling and comms channels. With the current tools everything can be done in a small XC program. I don't think that users would find Catalina on the Propeller very easy to use with no library functions.

    Ale mentioned that the UART function would have to be written in PASM for the Propeller. That XC code runs at 115,200 baud and is quite trivial.

    Returning to the competition problem, perhaps I should mention it on the XCore Exchange and form a group so that we can investigate it in parallel. :)
  • TonyDTonyD Posts: 210
    edited 2011-08-05 03:01
    My most recent XMOS project is a high-speed data collection and analysis widget. I'm working on putting up a web page describing it and will post it here if anyone is interested when it's done.

    Yeah, I would be interested in seeing it posted, perhaps it would be best to post it in the xcore.com projects.
  • RossHRossH Posts: 5,353
    edited 2011-08-05 03:40
    Leon wrote: »
    Returning to the competition problem, perhaps I should mention it on the XCore Exchange and form a group so that we can investigate it in parallel. :)

    What competition problem? Have you forgotten the original subject of this thread? You are planning to start a competition between the XMOS and a chip that doesn't even exist yet? Ok - let me shortcut that process for you by emulating the P2 in my head ... There! P2 wins!

    Ross.
  • LeonLeon Posts: 7,620
    edited 2011-08-05 03:48
    I was referring to jmg's proposed benchmark competition:

    http://forums.parallax.com/showthread.php?133447-XMOS-chips-vs.-P2&p=1024397&viewfull=1#post1024397

    Perhaps someone from Parallax could be persuaded to simulate a P2 solution.
  • AleAle Posts: 2,363
    edited 2011-08-05 04:53
    A P2 simulator would be quite useful !... I wonder if the opcode table and blog are enough, though...
  • Heater.Heater. Posts: 21,230
    edited 2011-08-06 08:59
    Jmg,
    Taking you up on the quadrature challenge my first stab at an xcore version written in XC not assembler looks like it can sample, decode and count quadrature steps at 8.3 Mhz.
    That loop contains only 3 lines of XC.

    There is a down side in that the xcore only allows pins to be used in groups of 1, 4, 8, 16 pins. That means when using a 4 pin group the quadrature inputs we waste two pins.

    One could run two decoders from those 4 pins but then there is a speed hit.

    I'll post the code when I have more than this phone to chat on if anyone is interested.
  • Dave HeinDave Hein Posts: 6,347
    edited 2011-08-06 09:15
    Ale wrote: »
    A P2 simulator would be quite useful !... I wonder if the opcode table and blog are enough, though...
    As I mentioned on another thread, a P2 simulator is under development as part of the GCC project. However, the focus of the GCC project has been shifted toward the P1 since the P2 chip design is in progress. I believe there are still a number of open issues on the P2 design, so it impossible to complete a simulator at this time. It would also be a burden on the Parallax design team to have to provide a detailed spec at this time.
  • BatangBatang Posts: 234
    edited 2011-08-06 23:16
    What competition problem? Have you forgotten the original subject of this thread? You are planning to start a competition between the XMOS and a chip that doesn't even exist yet? Ok - let me shortcut that process for you by emulating the P2 in my head ... There! P2 wins!

    Such an asinine response.
  • Mike GreenMike Green Posts: 23,101
    edited 2011-08-06 23:48
    Please, everyone stop the vitriol. There have been some legitimate questions asked and some legitimate answers given here. There have also been way too many comments that are too critical / too personal, and haven't really contributed anything to the discussion. If you don't have anything constructive to add, please don't. If you don't like what's being said, consider spending your time contributing to some other discussion that you may feel better about.
Sign In or Register to comment.