XC: Read Bidirectional Port While Maintaining Output

Technical questions regarding the XTC tools and programming with XMOS.
User avatar
JasonWhiteman
Active Member
Posts: 63
Joined: Mon Jul 15, 2013 11:39 pm

XC: Read Bidirectional Port While Maintaining Output

Post by JasonWhiteman »

Forum,

As I have changed my architecture, the answer to this question is not in my critical path. However, it may come up in the future. In XC, I declare bidirectional ports by leaving out the "out" and "in". Normally, my usage is not to sample what's being driven on the bus by an external "master" - but to read the current state of what is being driven.

Actually, in pseudo-code - my intended use for these types of ports would be

Code: Select all

on stdcore[myfavcore] : port readbidir = PICKAPINORPINS;

main()
{
     readbidir <: 1; // drive a 1
     function_that_changes_readbidir (readbidir);
     if (readbidir) take_this_action_readbidir_ishigh; else take_this_action_readbidir_islow;
}
Understanding that I could change readbidir to an out port, keep track with a variable the state of the "readbidir" port using a variable and pass it back from the function_that_changes_readbidir -- I'm wondering if there's a "cleaner" way of accomplishing this by reading the value of the register that sets readbidir without causing readbidir to change to an input (and thus, cause problems on my signal due to no driver - line goes high-Z).

It may be possible with asm - but is there an XC method?

If I declared the port as an output, then I cannot read the port by using ":>" due to rules. As shown in the pseudo-code, I do not believe the "if (readbidir) ...." is valid as I believe I had issues treating ports as standard variables in this manner.

Additionally, although my example shows a port that could very well be an output (since I am never interested in what is being driven on the bus from an outside source) -- this same concept may also apply to true bidir ports where - while in output mode - I would like to read the state of what I am outputting rather than keeping track with a variable.

Regards,
Jason Whiteman
Last edited by JasonWhiteman on Sun Aug 18, 2013 12:13 am, edited 1 time in total.


User avatar
JasonWhiteman
Active Member
Posts: 63
Joined: Mon Jul 15, 2013 11:39 pm

Post by JasonWhiteman »

Answer for the search engine and/or debate:

Source: XMOS XS1 Architecture (link subject to change)
http://fplreflib.findlay.co.uk/articles ... tecture.pd

Code: Select all

The DRIVE, PULLDOWN and PULLUP modes determine the way the pins are
driven when outputting, and the way they are pulled when inputting. The CLOCKPORT,
READYPORT and INVERT settings can only be used with 1-bit ports.
Initially, the port is ready for input. Subsequently, it may change to output data
when an output instruction is executed; after outputting it may change back to
inputting when an input instruction is executed.
It is sometimes useful to read the data on the pins when the port is outputting;
this can be done using the PEEK instruction:
PEEK d <-- pins(p) read port pins
The above note seems to clarify a question I had after reading about PEEK in another source, the XS1 Library
Source: XS1-Library(X6020G).pdf (link subject to change)
https://www.xmos.com/download/public/XS ... 6020G).pdf

Code: Select all

unsigned peek(void port p)

Instructs the port to sample the current value on its pins.
The port provides the sampled port-width bits of data to the processor immediately,
regardless of its transfer width, clock, ready signals and buffering. The input has
no effect on subsequent I/O performed on the port.

This function has the following parameters:
p The port to peek at.

This function returns:
The value sampled on the pins.
The phrase "has no effect on subsequent I/O performed on the port" wasn't clear enough to me to denote that the buffer direction for bidirectional ports would not change. However, combined with logical assumption and the architecture manual - it appears that peek() is what I was looking for.

Regards,
Jason Whiteman
User avatar
Ross
XCore Expert
Posts: 967
Joined: Thu Dec 10, 2009 9:20 pm
Location: Bristol, UK

Post by Ross »

Yes, peek is the way forward - I use this trick quite a bit.

Especially useful if you are being naughty and accessing a port from multiple cores do to read, modify, write. Best to use a lock if you are hacking things like this!