Split Port

Technical questions regarding the XTC tools and programming with XMOS.
User avatar
fullm3tal1991
Member++
Posts: 17
Joined: Wed Nov 28, 2012 4:31 pm

Split Port

Post by fullm3tal1991 »

Hi,

I'm currently working on the USB audio 2.0 MC development board.

I have a problem with my port declaration. Right now i have:

on stdcore[CORE_AUD] : out port p_led = XS1_PORT_8B;
so all the port is output.

But i need to split it, so i would have something like this:

on stdcore[CORE_AUD] : out port p_led = XS1_PORT_8B [7...4];
on stdcore[CORE_AUD] : in port p_led = XS1_PORT_8B [3...0];

is that possible?

thanks a lot for your help


User avatar
sethu_jangala
XCore Expert
Posts: 589
Joined: Wed Feb 29, 2012 10:03 am

Post by sethu_jangala »

It is not possible to declare some bits of a multi-bit port as input and some bits as output. You can declare the port as:
on stdcore[CORE_AUD] : port p_led = XS1_PORT_8B
You can read and write data on the port but you need to do some bit masking.
User avatar
fullm3tal1991
Member++
Posts: 17
Joined: Wed Nov 28, 2012 4:31 pm

Post by fullm3tal1991 »

Ok, thank you for the quick answer !

Best regards
Rémi
User avatar
fullm3tal1991
Member++
Posts: 17
Joined: Wed Nov 28, 2012 4:31 pm

Post by fullm3tal1991 »

I have another (silly?) question about port mapping...

I have 2 cores:
CORE_AUD
CORE_USB

for the moment i have

Code: Select all

on stdcore[CORE_AUD] : out port p_led                   = XS1_PORT_8B;
on stdcore[CORE_AUD] : in port p_gpio                  = XS1_PORT_4F; // 4 bits port GPIO
[...]
		on stdcore[CORE_AUD]:
		{
			LCD();
		}
but i want to do this process in CORE_USB, when I change CORE_AUD by CORE_USB it doesn't seems to work?

I think i have to change the port mapping in the ".xn" but i don't find an explicite documentation about this.
User avatar
infiniteimprobability
XCore Legend
Posts: 1126
Joined: Thu May 27, 2010 10:08 am

Post by infiniteimprobability »

Hi there,
you can't split wide ports into part in/part out directly, but there are options..

Firstly, most of the 8b ports are overlaid with 4b ports. For example 8B comes out on the same pins as 4C and 4D, so you can use those two instead, one as input, one as output.

Secondly, you can do the tick of having inputs connect to the port via a series resistor. Normally the port is an output - the series resistor stops any contention. You can then turn the port around (doing an input does this) momentarily and read the port periodically. You need to wait a few cycles for the value to change (XMOS I/O is very fast) but then you can get the input value. Then you set it back to output (just do an output to enable the output drivers).
This of course only works if your outputs can tolerate a glitch - something like front panel LEDs won't mind..

Regarding your last question - you can't just change tiles.. The core issuing the inputs/outputs needs to be on the same tile as the I/O port. The only connection between the two chips are the links - so you need to use those if you access something across on a different tile. Options for changing this include:

- Move your I/O port (hardware change)
- Send a message over a channel to a task on the core where the IO sits. select is your friend here..
User avatar
fullm3tal1991
Member++
Posts: 17
Joined: Wed Nov 28, 2012 4:31 pm

Post by fullm3tal1991 »

I have a USB 2.0 ref design so I can't change the hardware.
So with a program for LCD I tried to do it on 2 cores

Code: Select all

		on stdcore[CORE_USB]:
		{
			//set_thread_fast_mode_off();
			LCD(c_button,c_led);
		}

		on stdcore[CORE_AUD]:
		{
			//set_thread_fast_mode_off();
			GPIO(c_button,c_led);
		}
The GPIO function just input and output the port with streaming channels.

Code: Select all

extern in port p_gpio;
extern out port p_led;

void GPIO(streaming chanend c_button,streaming chanend c_led){
unsigned Temp;
	while(1)
	{
	p_gpio:>Temp;
	c_button<:Temp;

	c_led:>Temp;
	p_led<:Temp;
	}

}
and the LCD() function, is the one i used before (it was working)
but I change
p_gpio and p_led
now p_gpio and p_led are replaced by local variable, which take values from the streaming channels.

for exemple my function to send 4 bits instructions to the LCD screen is now:

Code: Select all

void Send4bitsInst(unsigned ToSend,streaming chanend c_led)
{
		ToSend=ToSend<<4;
		led=ToSend + 0b0010; // E=1 RS=0
		c_led<:led;
		// tempo
		t :> time;
		time += 1000000;
		t when timerafter(time) :> void;

		// falling edge
		led=ToSend + 0b0000; // E=0 RS=0
		c_led<:led;
		// tempo
		t :> time;
		time += 1000000;
		t when timerafter(time) :> void;
}
so each time I had a p_led <: XXXX
now I have:
led=XXXX;
c_led<:led;

and in the main LCD loop , I have

Code: Select all

c_button:>buttons;
it doesn't work, but I don't understand why?
timing problems?
User avatar
TSC
Experienced Member
Posts: 111
Joined: Sun Mar 06, 2011 11:39 pm

Post by TSC »

it doesn't work, but I don't understand why?
While most of your post explained your issue very well, I don't think the above line is descriptive enough for other people to help you.

What is "it"? What did you expect to see? What did you see instead?
User avatar
fullm3tal1991
Member++
Posts: 17
Joined: Wed Nov 28, 2012 4:31 pm

Post by fullm3tal1991 »

TSC wrote: What is "it"? What did you expect to see? What did you see instead?
Hi, thanks for the answer.
I put two projects in attachment. (sorry for the French comments on my codes... i'll correct it and make the code cleaner later).
The 1 Core LCD display project (everything on the core 1)
The 2 Core LCD display project (input/output in the core 1, calculation in the core 0)

So the LCD screen program with one core works. I use the 8 bits port p_led to send instructions to the screen and the 4 bits port p_gpio for the 4 buttons.
It's a simple program with 3 levels of display (the things which are displayed are just examples)

1st Level : The names of the effects => can navigate between the effects with button 3 and 4
2nd Level : One effect is selected => can navigate between the preset of the effect with button 3 and 4
3rd Level : One Preset is selected => can put the preset at the number you want with button 3 and 4

To Go 1 level up => button 1
To Go 1 level down => button 0

My problem was:
On the Core 1 I need all the core available for digital filter/audio effects. So my little interface with 4 butons, and the LCD screen is a waste of calculation.
My idea for the LCD is : input and output with the core 1 (i don't have the choice because of the hardware), and use streaming channel to share those values with core 0. So the core 0 can do all the calculation and I don't waste calcul power in the core 1.

With my code i don’t even succeed on init and display one character on the LCD…

But I think my problem is not really this one...
They are lots of things i don't understand, and I don't find the answers on xmos's website:
how works functions : set_thread_fast_mode_off(); & set_thread_fast_mode_on(); ?
how can I set priorities between threads?
how priorities are handled by default?
it's said the processor on the USB audio 2.0 mc ref design has 16 cores, but only 2 are used in the software release? how use the others?

I want to work, and I can read lots if things, and I'm motivate, but i think i’m wasting time by searching things in the wrong way, if you could help me just a little bit to help me to find a good way to learn properly, I will be very grateful to you.
You do not have the required permissions to view the files attached to this post.
User avatar
TSC
Experienced Member
Posts: 111
Joined: Sun Mar 06, 2011 11:39 pm

Post by TSC »

how works functions : set_thread_fast_mode_off(); & set_thread_fast_mode_on(); ?
I've never used it, but it doesn't seem very useful.

From the XS1 architecture manual:
To enable the virtual processor to perform one input or output per virtual cycle, a fast- mode is provided. When a thread is in fast-mode, it is not de-scheduled when an instruction can not complete; instead the instruction is re-issued until it completes.
Apparently it only results in a tiny speed-up in most cases.
how can I set priorities between threads?
how priorities are handled by default?
You can't set priorities of threads. They are handled fairly, in a round-robin fashion.
it's said the processor on the USB audio 2.0 mc ref design has 16 cores, but only 2 are used in the software release? how use the others?
Any function called from within a par {} block will run as a logical core. I notice that in your main.xc, the old terminology is used. Early this year, XMOS started using newer terminology for marketing reasons.

Oldspeak to newspeak conversion:
Thread -> Logical core.
Core -> Tile.

I recommend you use the newer terminology because that's what all current XMOS code uses, so it's less confusing.

E.g. Two logical cores running on each tile.

Code: Select all

par {
  on tile[CORE_USB]: {
    par {
      LCD(c_button,c_led);
      anotherCore();
    }
  }
  on tile[CORE_AUD]:  {
    par {
      GPIO(c_button,c_led);
      yetAnotherCore();
    }
  }
}
There can be a maximum of 8 logical cores running on each tile.

I recommend you don't use the fast thread and streaming functionality, because they are unnecessary for your design, and using them won't fix an existing faulty design. Try using the debugger to see where and why your program is experiencing deadlock.
User avatar
fullm3tal1991
Member++
Posts: 17
Joined: Wed Nov 28, 2012 4:31 pm

Post by fullm3tal1991 »

TSC wrote:I recommend you don't use the fast thread and streaming functionality, because they are unnecessary for your design, and using them won't fix an existing faulty design. Try using the debugger to see where and why your program is experiencing deadlock.
But are the logical core independant? or are they like threads in a program (so they share the same calculation entity)