To develop systems, we have to be able to communicate with more sophisticated external devices:
For that, we have to be able to communicate complex information:
In the case of even more sophisticated systems, even transport BJSON
data from one device to another.
The industry has developed multiple approaches for communication between devices with various properties and advantages/disadvantages.
In this course, we will name those approaches: communication buses
(that is only our internal convention)
All of these are just a specification of how to use pins of MCU
to transfer complex information.
In this course, we are interested only in some of those:
These are standardized (somehow) and a common approach is to pick hardware that implements some method compatible with your MCU.
For example:
If I want to measure temperature and I know that my MCU
can handle only I2C
, I will look for a temperature sensor that communicates over I2C
and use that.
We are also looking for common properties of these approaches, as that gives us the ability to compare them and decide what is preferable for the application.
For example: is it preferable to use an external ADC
that communicates over SPI
or I2C
?
The physical basis for communication is commonly an exchange of values with a signal wire.
Device A
will change the value of the signal wire and device B
would sample that same signal wire to read the value.
For communication buses, we can have synchronous
communication (ie: clk
signal wire dictates the pace of communication), or asynchronous
.
The process of communication happens in real time between devices.
At regular points in time, device A
will change the value of the signal pin to HIGH
or LOW
and device B
will sample it.
For this to work reliably, there has to be an agreement between devices:
setting value
and sampling value
If devices have a mismatch between these two, the communication will not work:
A
changes the value every 1s
but device B
samples the value every 1.11s
, after some time, device B
will skip one bit. (B
samples at 9.99s
, and 11.1s
, hence it misses that A
set a new value at 10s
)B
samples too soon after it was set by A
, the change of voltage on the signal wire might not propagate fast enough and B
might sample the previous variable.Some buses provide a clock
signal wire to prevent these kinds of problems.
The bus
clearly specifies which device can control the clock
signal and how that should happen, for example in the following manner:
clock
goes from HIGH
to LOW
clock
goes from LOW
to HIGH
This way, the frequency of setting/sampling of both devices is synchronized and we also got rid of the issues with offsets - set
and sample
operations are apart from each other.
It is up to the controlling device to control the clock
in a manner that is feasible to work with for the other device. (the other device has to be able to process the values at that frequency)
Hence we distinguish between buses
that are:
synchronous
- they have a dedicated clock
signal wireasynchronous
- they do not have a dedicated clock
signal wireWe distinguish between two modes of transferring data over signal wires:
serial
- one signal wire for all dataparallel
- more than one signal wire for transporting dataIn the case of a serial bus
, we transfer one bit at a time, with the benefit of requiring only one
signal wire for the bus
.
In the case of a parallel bus
, we send a batch of n
bits at a time, over n
signal wires.
Commonly all the wires are synchronized together - device A
sets the value on all n
wires at once and device B
samples all the wires at once.
The most crucial consequence of this is that serial
buses need much fewer wires for connecting the devices than parallel
buses.
Once the frequency of communication starts to be high enough, we also notice that the parallel
buses became sensitive to even small differences between the wires
.
The change in values between the wires will not fully propagate at the same time in device B
and that might cause desynchronization once the frequency is high enough.
Turns out that for scaling into high bandwidth, scaling the serial bus into higher frequency might be more feasible than adding parallelism.
The intuitive way to interconnect two devices is to use separate signal wires for each direction.
That is: we have a signal wire from device A
to device B
and a second signal wire from device B
to device A
.
Such a system is full-duplex
.
In some cases, to reduce the need for multiple wires, we can set up the system in a way that one signal wire is used for both directions.
That is, both devices use one wire to send data.
The system requires some sort of mechanism for the devices to select which one can use the signal wire.
We call these systems half-duplex
.
Note that in the case of a half-duplex
system, only one device can communicate at a time.
In a full-duplex
system, both devices can communicate at once.
In communication, we may have a hierarchy between the devices, for this course we consider two options:
master/slave
- one of the devices is in control of the communication (master
), and other devices follow the requests from the controlling device (slaves
).point-to-point
- typically in a situation with two devices, both devices are on equal footing.There are other options (for example: multi-master
), but only these two are relevant here.
signal rail
to signal wire
.