The Let's Play Archive

SHENZHEN I/O

by Quackles

Part 23: Engineer's Corner #4: Putting It All Together

Engineer's Corner #4: Putting It All Together

"It is a truth universally acknowledged that a MC in possession of output pins must be in want of being connected to a second."
Pride and Prejudice and Microcontrollers, revised edition (2022)

OK, I made that quote up. But sooner or later you will have to connect two MCs together. And there's two ways to do it. Both have benefits and drawbacks.

1. Simple I/O

Simple I/O pins can take values from 0 to 100 (the exact voltages vary depending on whatever variant of MCX000 you're using - my simulator abstracts away the details). Once you push a value out to a simple I/O pin, that pin stays set to that value until you reset it to something else. You can read it at your leisure. Simple, right?

There's a catch, of course, and it's got to do with timing when you push a value out to a pin. The time a chip has run after it wakes up at the start of a time step can be measured in single instructions (I'll call them "ticks"). With the exception of instructions dealing with XBus I/O, which can run long waiting for data, every instruction takes one tick to run.

So, here's the problem - this came up in the virtual reality buzzer job. If you have two chips, and Chip #2 reads from Chip #1... but Chip #2 reads at 2 ticks after wake, and Chip #1 writes at 4 ticks after wake, Chip #2 will read old data unless you make it wait for Chip #1 by padding its script with 'nop' or other instructions.

The rule is that Chip #1 writes and Chip #2 reads, Chip #2 must read after the tick where Chip #1 writes the value, or it won't work.



If you're not clear what's going on in this example, note that last tick, MC #1 wrote a new value and MC #2 read (the old) value, on the same tick. Next tick, MC #2 will read the new value successfully.


2. XBus

XBus: The industry standard for digital I/O. Sends values from -999 to 999, and can send multiple values per time unit in a handy 'packet' form. There's even a special instruction - slx - that will cause a MC to wait for I/O from an XBus port, as many time units as necessary*.

Like you'd expect, there's a catch or two to this, too. XBus is a synchronized I/O protocol, meaning: If you send a value over XBus, there must be someone on the other end to receive it, and during the same time unit, too. If there isn't, the sending MC will block and that's an error. In the same vein, if you try to read a value over XBus, and there's no one on the other end to send it during the same time unit - yep. The receiving MC will block, and that's an error too.
(Though if your reading MC is ready before your writing MC, you can just use slx to make it wait*.)





On top of that, any value can only be read once - if you read from an XBus pin twice, the MC'll assume you're getting a two-value data packet and wait to receive two separate values. This can trip you up with parts like the radio, which will only send each value in a data packet once, and then report -999 (no more data).

One more thing: If you send a value over XBus and there's more than one MC connected that can receive the value, only one of them will get it. Whoever reads first wins. (If they both read at the same time, it's anyone's guess.)

*You only need to use slx if you expect the MC to receive XBus input in a later time unit. If you're, for example, sending something out with XBus and getting a reply in the same time unit, no slx is necessary - the read will wait properly, without drawing extra power or erroring out.


In Summary:

1. Simple I/O

Perks:
• Write once, read more than once (value stays stable once you set it)
• Write and read in different time units if you want
• Multiple readers from one source is fine!

Perils:
• 0-100 ONLY!
• Must time reads to run after writes, if they happen in the same time unit.
• Because of timing issues, reading more than one value in the same time unit isn't recommended

2. XBus

Perks:
• Any value, from -999 to 999
• Wait until you receive input with slx
• Multiple values in one time unit

Perils:
• Can only read a value once - this is what lets you read multiple values in one time unit!
• If there's no one at the other end of the line (now), your circuit breaks
• There can be only one! (reader for each writer, and vice versa)
• If using slx to wake a MC, you have to do something with the value being sent or it's an error