Update: 2017-OCT-7
This is a very simple I/O link supporting Plug&Play. This protocol works over UART and I2C at a minimal cost. I am also considering to support it over CAN.
I2C backplane master accepts commands from UART.
I use Tera Term as terminal software on my PC.
Typical setup:
[I2C backplane master(scheduler)]---UART---[FTDI]---USB---[Teraterm]
I2C backplane slave also accepts same commands as those for I2C backplane master:
[I2C backplane slave]---UART---[FTDI]---USB---[Teraterm]
Example (at Teraterm):
#WHO <--- I2C backplane master echoes back the command you enter at Teraterm
$:WHO:BACKPLANE-MASTER <--- Then returns a response to Teraterm
In addition to Teraterm, you can use any terminal software (e.g., putty) or any serial port libraries (e.g., "pyserial" for Python or "serialport" for Node.js) to get access to I2C backplane master via UART/USB.
[Menu bar] Setup -> Serial port -> Baud rate
115200 for I2C backplane master
9800 for I2C backplane slaves
All the commands ends with '\n' (new line char), so new line setting is as follows:
[Menu bar] Setup -> Terminal -> New-line
Receive: LF
Transmit: LF
An I2C slave address must be set to the device with WDA command.
If I2C address of the device is 19 then:
#WDA:19
WDA:19
I2C backplane master/slave Teraterm
|<------------WHO-------------|
| |
|-----$:WHO:<device_name>---->|
The current setting is saved to PIC'S EEPROM.
I2C backplane master/slave Teraterm
|<------------SAV-------------|
I2C backplane master/slave Teraterm
|<------------STA-------------|
I2C backplane master/slave Teraterm
|<------------STP-------------|
| |
|---------*:STP:ACK---------->|
I2C backplane master/slave Teraterm
|<--------SET:<value>---------|
I2C backplane master/slave Teraterm
|<------------GET-------------|
| |
|--------$:GET:<value>------->|
I2C backplane master/slave Teraterm
|<------WDA:<device_id>-------|
I2C backplane master/slave Teraterm
|<------------RDA-------------|
By setting I2C slave's device id (I2C address of I2C backplane slave) to I2C backplane master, you can get access to I2C backplane slave via I2C backplane master, and you can send commands to the slave.
address = 1 means I2C backplane Master.
I2C backplane master Teraterm
|<--I2C:<address in decimal>--|
I2C backplane master Teraterm
|<----------------MAP----------------------|
| |
|--$:MAP:<list of slave addresses in CSV-->|
*1 $:MAP:<list of slave addresses in CSV>
I2C backplane master Teraterm
|<------------CSC-------------|
I2C backplane master Teraterm
|<-------POS:<position>-------|
I2C backplane master Teraterm
|<------WSC:<device id>-------|
I2C backplane master Teraterm
|<------------RSC-------------|
| |
|------------<*1>------------>|
(*1) example output
$:RSC:0,0,0,0|0,0,0,0|0,0,0,19|0,0,0,0|0,0,0,0|0,0,0,0|0,0,0,0
I2C backplane master Teraterm
|<------------SSC-------------|
This is a filter for PUBSUB operations to filter out response with NO_DATA from I2C backplane slave, in reseponse to SEN from I2C backplane master.
I2C backplane master Teraterm
|<------------SFT-------------|
I2C backplane master Teraterm
|<------------UFT-------------|
I2C backplane master Teraterm
|---%<address>:<type:<data array in CSV>---->|
Example:
%10:FLOAT:0.09,-0.13,+1.06
If the target device is accelerometer (i2c slave address 19) then:
I2C backplane master Teraterm
|<-----SEN:<device_id>--------|
| |
|----------<data>------------>|
Example:
#SEN:19
%19:FLOAT:0.20,0.17,-0.97
I2C backplane master pyserial(Python)/serialport(Node.js)
| |
|<------------STP--------------| Send STP(Stop) to the slave to stop sending data.
|----------*:STP:ACK---------->| Confirm that ACK has been received on the master side.
| | Clear the output buffer on the master side.
| | Clear the input buffer on the master side.
|<------------WHO--------------| Send WHO(Who are you?) to get device ID of the block.
|-------$:WHO:<device ID>----->| Keep the device ID on the master side.
| |
|<---------SET:<value>---------| Send SET to configure the device.
| |
|<-----------SAV---------------| Send SAV to save the config on the slave side.
| |
|<-----------STA---------------| Send STA(Start) to make the device start sending data.
| |
I2C backplane master sends SEN to I2C backplane slave to fetch sensor data. The data follows this format, and MSB is sent before LSB:
+------+------+-------------------+
|Type |Length|Value |
|8bit |8bit |8bit * length |
+------+------+-------------------+
Type is one of the following data types:
- uint8_t: 0 ~ 255
- int8_t: -128 ~ 127
- uint16_t: 0 ~ 65535
- int16_t: -32768 ~ 32767
- (int16_t)(float * 100): -327.68 ~ 327.67
In case of uint16_t, int16_t and float, Value contains data in this form:
+------+------+----------+----------+----+
|Type |Length|[MSB][LSB]|[MSB][LSB]|... |
+------+------+----------+----------+----+
I2C backplane master sends EXT_I2C to I2C backplane slave to send a char array of extended command. The message follows this format:
+-------+------+---------------------------+
|Type |Length|Value |
|EXT_I2C|8bit |Char array ending with '\0'|
+-------+------+---------------------------+
Note that Length is the number of characters including '\0'.
You can send SET, STA, STP, SAV, WHO, SEN and GET commands to I2C backplane slave via I2C backplane master. Refer to I2C command described in the above.
This operation is performed in background at every 480msec(8msec x 60) interval.
I2C backplane slaves I2C backplane master
(dev addr 0x0n)
|<----General Call PLG------------|
|-----(I2C ACK bit on)----------->|
| | start device scan process
|<----WHO to dev addr 0x01------|
|<----WHO to dev addr 0x02----|
|<----WHO to dev addr 0x0n--------|
|-----<device ID>---------------->| detect new backplane slave
This operation is performed in background at every 4800msec(8msec x 600) interval.
I2C backplane slaves I2C backplane master
| | start device scan process
|<----WHO to dev addr 0x01------|
|<----WHO to dev addr 0x02----|
|<----WHO to dev addr 0x0n--------|
|-----<device ID>---------------->| detect new backplane slave
I2C backplane slave I2C backplane master
|<-------------INV----------------| invocation
| | delay
| | :
|<-------------SEN----------------|
|------<data in TLV format>------>|
Note: you can also send all of these commands to I2C backplane slave (AQM1602XA-RN-GBW) via I2C backplane master. Refer to I2C command described in the above.
I2C backplane slave Teraterm
|<------------INI-------------|
I2C backplane slave Teraterm
|<---------CMD:<cmd>-----------|
"cmd" is one-byte command in decimal.
I2C backplane slave Teraterm
|<---------DAT:<data>----------|
"data" is one-byte data in decimal.
I2C backplane slave Teraterm
|<-------------CLR-------------|
I2C backplane slave Teraterm
|<---------STR:<string>--------|
"string" is string data in ASCII code.
I2C backplane slave Teraterm
|<-------------CUL-------------|
I2C backplane slave Teraterm
|<-------------CUR-------------|
I2C backplane slave Teraterm
|<-------------NWL-------------|
I2C backplane slave Teraterm
|<-------------HOM-------------|
I2C backplane slave Teraterm
|<-----DSP<<line1><line2>>-----|
line1 and line2 are string data in ASCII code. Both line1 and line2 MUST be 16 characters in length (totally 32 characters).
SEN's value is a bit mask in decimal. Refer to the source code.
const adc_channel_t ANALOG_IN[AINS] = {
channel_AN2, channel_AN1, channel_AN0,
channel_AN7
};
SET:1 --> analog_in_flag[0] = 1;
SET:2 --> analog_in_flag[1] = 1;
SET:4 --> analog_in_flag[2] = 1;
SET:8 --> analog_in_flag[3] = 1;
SET:3 corresponds to "SET:1 and SET:2".
Address | Usage | Node |
---|---|---|
0 | Device ID | |
1 | Device setting | |
2~30 | Schedule | Backplane-master only |
- 0: every 8msec
- 1: every 16 msec (8 * 2)
- 2: every 48 msec (8 * 6): ~50msec
- 3: every 96 msec (8 * 12): ~100msec
- 4: every 480 msec (8 * 60): ~500msec
- 5: every 960 msec (8 * 120): ~1sec
- 6: every 4800 msec (8 * 600): ~5sec
Address | Device ID | Capability | FOSC | UART baud rate |
---|---|---|---|---|
0x01(01) | BACKPLANE-MASTER | I2C master (w/ 8msec timer) | 32MHz | 115200 |
0x10(16) | AQM1602XA-RN-GBW | Character LCD | 4MHz | 9600 |
0x11(17) | A1324LUA_T | Hall sensor | 4MHz | 9600 |
0x12(18) | HDC1000 | Temperature and humidity sensor | 4MHz | 9600 |
0x13(19) | KXR94-2050 | Three-axis accelerometer | 32MHz | 9600 |
0x14(20) | SHT31-DIS | Temperature and humidity sensor | 4MHz | 9600 |
0x15(21) | MULTI_A1324LUA_T | Hall sensor for position sensing | 4MHz | 9600 |
0x16(22) | MULTI_A1324LUA_T | Hall sensor for position sensing | 4MHz | 9600 |
Note: TI does not recommed using HDC1000 in a new design (http://www.ti.com/product/HDC1000/description), so I use SHT31-DIS from now on.