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
Split Port
-
- Member++
- Posts: 17
- Joined: Wed Nov 28, 2012 4:31 pm
-
- XCore Expert
- Posts: 589
- Joined: Wed Feb 29, 2012 10:03 am
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:
You can read and write data on the port but you need to do some bit masking.on stdcore[CORE_AUD] : port p_led = XS1_PORT_8B
-
- Member++
- Posts: 17
- Joined: Wed Nov 28, 2012 4:31 pm
Ok, thank you for the quick answer !
Best regards
Rémi
Best regards
Rémi
-
- Member++
- Posts: 17
- Joined: Wed Nov 28, 2012 4:31 pm
I have another (silly?) question about port mapping...
I have 2 cores:
CORE_AUD
CORE_USB
for the moment i have
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.
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();
}
I think i have to change the port mapping in the ".xn" but i don't find an explicite documentation about this.
-
- XCore Legend
- Posts: 1126
- Joined: Thu May 27, 2010 10:08 am
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..
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..
-
- Member++
- Posts: 17
- Joined: Wed Nov 28, 2012 4:31 pm
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
The GPIO function just input and output the port with streaming channels.
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:
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
it doesn't work, but I don't understand why?
timing problems?
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);
}
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;
}
}
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;
}
now I have:
led=XXXX;
c_led<:led;
and in the main LCD loop , I have
Code: Select all
c_button:>buttons;
timing problems?
-
- Experienced Member
- Posts: 111
- Joined: Sun Mar 06, 2011 11:39 pm
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.it doesn't work, but I don't understand why?
What is "it"? What did you expect to see? What did you see instead?
-
- Member++
- Posts: 17
- Joined: Wed Nov 28, 2012 4:31 pm
Hi, thanks for the answer.TSC wrote: What is "it"? What did you expect to see? What did you see instead?
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.
-
- Experienced Member
- Posts: 111
- Joined: Sun Mar 06, 2011 11:39 pm
I've never used it, but it doesn't seem very useful.how works functions : set_thread_fast_mode_off(); & set_thread_fast_mode_on(); ?
From the XS1 architecture manual:
Apparently it only results in a tiny speed-up in most cases.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.
You can't set priorities of threads. They are handled fairly, in a round-robin fashion.how can I set priorities between threads?
how priorities are handled by default?
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.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?
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();
}
}
}
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.
-
- Member++
- Posts: 17
- Joined: Wed Nov 28, 2012 4:31 pm
But are the logical core independant? or are they like threads in a program (so they share the same calculation entity)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.