Breakin' the law! Bidirectional ports with the XS1-G04B

Technical questions regarding the XTC tools and programming with XMOS.
TjBordelon
Active Member
Posts: 39
Joined: Mon Jul 29, 2013 4:41 pm

Breakin' the law! Bidirectional ports with the XS1-G04B

Post by TjBordelon »

In various documents for the XS1-G04B-FB144, it is constantly stated that using bidirectional buffered ports is not supported in hardware. This is backed up by the compiler's warning when you try to do this in the port declaration. However in the architecture document it says you CAN do this.

The SDRAM demo breaks this rule, and I have successfully done the same in assembly. It seems to work fine.

I imagine that there is a caveat or issue and the decision was made at XMOS to simply say it doesn't work.

In my case, I'm trying to stream a bi-directional 8 bit bus (With clock) to connect a microcontroller to the XCORE and use it as a high-speed coprocessor and I/O device. I'm pumping some serious bandwidth out the xcore so without buffered I/O I cannot reach the transfer between the micro/xcore that is needed.

It would seem to me that my need here would be typical. If I don't use buffered, 2 cycles per word becomes 10+ as I have to read 4 and shift/or them together. A major hit.

Anyone know why this critical functionality discouraged?

I've attached the code I'm using to send fairly high bandwidth data to/from a PIC32 MIPS processor's parallel PMP port. I have it set up with 8 bidirectional data lines with separate read and write clocks. Seems like something many people would need to do. My first shock is that there is no existing component for this. Seems like most designs want to use this as a co-processor so a high bandwidth parallel port is a must! I'd love to use the XLINK, but most microcontrollers don't have an xlink in hardware. but they do have PMP ports.

So everyone who wants to get the XCORE to do USB and the rest of the missing stuff? What about doing it this way? Use a microcontroller that is good at that. Then use the XCORE which is good at what it does. Connect them together.

My second shock is that bidirectional buffered ports "are not supported in hardware". If I didn't do it this way my 2 cycles/word would turn into 10+ as I have to read 4 8 bit bytes, and swizzle them together with shifts and or's.

Note that this code works perfectly except it outputs a junk byte that I can't get rid of (yet). The first clock from the master outputs a junk byte. The next clock starts the real data.

Anyone know the official word on why this is discouraged?
You do not have the required permissions to view the files attached to this post.


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

Post by segher »

The architecture doc says
A BUFFERED port can change direction only after it has completed a transfer. This is
done by stopping and re-starting the port using SETC p, STOP and SETC p, START
instructions.
As long as you have a reasonably long time between sending and
receiving, you should be fine. Note that this tristates the bus; you
said you have separate control signals for read and write: as long
as you don't float _those_, things will work out fine (but check the
docs for the microcontroller you are talking to, see if that is okay
with everything you do :-) )
TjBordelon
Active Member
Posts: 39
Joined: Mon Jul 29, 2013 4:41 pm

Post by TjBordelon »

segher wrote:As long as you have a reasonably long time between sending and
receiving, you should be fine. Note that this tristates the bus; you
said you have separate control signals for read and write: as long
as you don't float _those_, things will work out fine (but check the
docs for the microcontroller you are talking to, see if that is okay
with everything you do :-) )
The master (in my case the PIC32) drives both the RD and WR lines, bringing the appropriate line high as it clocks in/out a new byte. There isn't an issue because of this. Tri-state is kinda implied because only the DATA lines go from being driven by the PIC32 then by the XCORE between the switchover, but the data lines have settled by the time the first read comes in. The RD/WR lines are always driven by the remote master and never glitch.

My only concern is why the warning from XMOS in the datasheet. Why tell everyone the most important port feature when it comes to port performance is not supported in hardware when , in fact, it is? I worry there is a landmine I will step on. Most likely when I have 1000 units in the field and the silicon changes. DOH!

Just to be clear-- they say BUFFERED BIDIRECTIONAL is not supported, whereas BIDIRECTIONAL is. Case and point:

on tile[0] : out buffered port:32 USER_DATA = XS1_PORT_16B; <---- WORKS

on tile[0] : buffered port:32 USER_DATA = XS1_PORT_16B; <---- FAIL

../src/Modem.xc:9: warning: bidirectional buffered port not supported in hardware (port should have in or out qualifier

I call shenanigans!

And as you point out, the architecture docs agree with observed results (and disagree with the above). Here's the full excerpt:
document X7879A wrote:A SYNCHRONISED port can change from input to output, or from output to input. The direction changes at the start of the next setup period. For a transfer initiated by a SETPT instruction, the direction will be input unless an output is executed before the time specified by the SETPT instruction. A BUFFERED port can change direction only after it has completed a transfer. This is done by stopping and re-starting the port using SETC p, STOP and SETC p, START instructions.
By the way-- in another post you were mentioning that you do all your setup code in .XC and pass the constants in. I did find a way to define constants in ASM (see my .s file above) that you might be interested in.

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

Post by segher »

My only concern is why the warning from XMOS in the datasheet. Why tell everyone the most important port feature when it comes to port performance is not supported in hardware when , in fact, it is?
Because, in fact, it is not :-P

Changing direction (by simply doing an IN or OUT) on a buffered
port fails miserably. Shutting down a port an then using it in the
other direction of course does work :-)
Just to be clear-- they say BUFFERED BIDIRECTIONAL is not supported, whereas BIDIRECTIONAL is.
That's in XC. Maybe it cannot re-init the port; maybe it has trouble
analysing stuff with this; maybe it's just playing it safe. Who knows :-)
By the way-- in another post you were mentioning that you do all your setup code in .XC and pass the constants in.
Must be a pretty old post -- I use plain C for almost everything these
days. What can I say, I like the pain?
I did find a way to define constants in ASM (see my .s file above) that you might be interested in.
My web browser doesn't want to display your attachment. Could you paste
it as text?

Cheers,


Segher
TjBordelon
Active Member
Posts: 39
Joined: Mon Jul 29, 2013 4:41 pm

Post by TjBordelon »

I would agree with you. But then why disallow declaring a bidirectional buffered port when they could just do the stop/start under the hood? It reads to me (as does the datasheet) as it isn't possible.

I'll post their official answer here-- I have a ticket open. At a minimum it's confusing. But I suspect there is more to this story.