select and multiple conditions

New to XMOS and XCore? Get started here.
Post Reply
User avatar
LyleHaze
Experienced Member
Posts: 71
Joined: Wed Apr 11, 2012 6:21 am
Contact:

select and multiple conditions

Post by LyleHaze »

Hello again.
I seem to be monopolizing the "Getting Started" forum, but so far nobody has asked me to leave. :)

I have written a "Channel Buffer", designed to go between a fast serial input and the code that writes to an SD Card.
The reason for the buffer? Serial will keep coming as individual characters, and the SD Write routines work in multiples of 512 bytes. A buffer in between should allow each to work as fast as possible.
The buffer has a few "features", It can respond to queries about how many characters it currently holds, how much time has passed since the last character arrived, how many errors have accumulated, etc. So far, it's all working great except.. the Select block.
Here's an (abbreviated) look at how it is (not) working:
Channel Buffer code:
streaming chanend input;
streaming chanend output;
chanend commands;

while(1)
{
select
{
case input :> c:
add_to_buffer(c);
break;
case commands :> comm:
do_command(com);
break;
}
if((wantmore) && (havemore))
output <: frombuffer(1);
}
The problem is that once some output is requested, I just get one character for each
subsequent arriving character or command.
A few ideas come to mind: I could call output <: frombuffer(wantmore) and dump it all at once, but I'm afraid I might be away too long and miss incoming serial. I plan on cranking the baud rate up as fast as possible later, so catching every input character is the highest priority.
Another option would be to add case t:> timer from a timer, set to some "interval" that will clock out characters with every timer event.. That would work, but I'm wondering if anyone wants to suggest a better way.

Of course, suggestions, ideas, corrections, and general chat on the subject are all welcomed!

LyleHaze


User avatar
segher
XCore Expert
Posts: 844
Joined: Sun Jul 11, 2010 1:31 am
Contact:

Post by segher »

LyleHaze wrote:Hello again.
I seem to be monopolizing the "Getting Started" forum, but so far nobody has asked me to leave. :)
Nobody else answered, so it's me again...

Code: Select all

while(1)
{
	select
	{
		case input :> c:
			add_to_buffer(c);
			break;
		case commands :> comm:
			do_command(com);
			break;
		default:
			if((wantmore) && (havemore))
			output <: frombuffer(1);
	}
}
will work better (btw, "code", not"quote" :-) ).

This still spins like mad when there is nothing to do; to fix that,
break the loop in two, one "idle" and one "work to do".

This still blocks if your output blocks.
Post Reply