9.e. Serial-to-I²C App
This app turns a Wixel into a serial-to-I²C bridge, acting as a master controller on a single-master I²C bus. To perform I²C operations, another device can issue serial ASCII commands to the Wixel on its radio, UART, or USB interface.
I²C is a two-wire interface that is commonly used for communications on peripherals like the LSM303DLHC compass and the BMP085 pressure sensor. The official specification (371k pdf) for the I²C bus is published by NXP.
Download the Serial-to-I²C App (v1.0) (26k wxl). Open it with the Wixel Configuration Utility, choose your parameters, and then write it to a Wixel. See Section 4 for more information on how this is done.
|P1_0||SCL||I²C clock (0–3.3 V)|
|P1_1||SDA||I²C data (0–3.3 V)|
|P1_6||TX||transmits serial data (0–3.3 V)|
|P1_7||RX||receives serial data (0–3.3 V)|
This device appears to the USB host as a Virtual COM Port (with USB product ID 0x2200). If you are using Windows, you should see an entry labeled “Wixel” in your Device Manager in the “Ports (COM & LPT)” category while the app is running.
There are three basic bridge modes that can be selected:
- Radio-to-I²C: Serial commands from the radio are used to control I²C transfers. Data read from the I²C slave is returned to the radio. Another Wixel running the standard Wireless Serial app can be used to communicate with this Wixel wirelessly.
- UART-to-I²C: Serial commands from the UART’s RX line are used to control I²C transfers. Data read from the I²C slave is returned to the UART’s TX line.
- USB-to-I²C: Serial commands from the USB virtual COM port are used to control I²C transfers. Data read from the I²C slave is returned to the virtual COM port.
You can select which bridge mode you want to use by setting the bridge_mode parameter to the appropriate number (from the list above). The default bridge mode is Radio-to-I²C (0).
The UART RX pin has an internal 20 kΩ pull-up resistor.
The I²C lines (SCL and SDA) are on P1_0 and P1_1, respectively, by default; these can be changed with the I2C_SCL_pin and I2C_SDA_pin parameters. They do not have pull-ups enabled, so external pull-ups must be added to form a bus that conforms to the I²C specification. (Some carrier boards for I²C devices include pull-ups on these lines.)
The I²C bus frequency is 100 kHz by default, which can be changed with the I2C_freq_kHz parameter. This app does not support I²C arbitration, which means it cannot be used on multi-master I²C buses.
This app listens on the selected serial interface for commands and performs the corresponding I²C transactions. The command format is similar to the one used by the NXP SC18IM700 Master I²C-bus controller with UART interface. Three commands, in the form of ASCII characters, are recognized:
The general format for a command sequence begins with a START command (‘S’), followed by a slave device address, the number of data bytes to be written or read, the data to be written (if a write is being done), and finally a STOP command (‘P’). If a read is being done, the data read from the slave device will be returned on the serial interface. The least significant bit of the slave device address (the data direction bit) indicates whether the operation is a write (0) or a read (1). A repeated START condition can be generated by issuing another START command without sending a STOP command.
For example, to write the value 0x2E to register 0xF4 on a slave device with the write address 0xEE, the following sequence of bytes could be sent to the Wixel:
‘S’, 0xEE, 2, 0xF4, 0x2E, ‘P’
To read a two-byte value from register 0xF6 on the same device, whose read address would be 0xEF, the following sequence could be issued (the second ‘S’ generates a repeated START):
‘S’, 0xEE, 1, 0xF6, ‘S’, 0xEF, 2, ‘P’
The Wixel would respond with the two data bytes read from the slave.
Any invalid or unrecognized command is ignored and causes the Invalid Command error bit to be set.
To prevent an unfinished command sequence from leaving the I²C bus in an unusual state, this app will time out and reset the bus if a byte is not received on the serial interface within 500 ms of the last byte. After this happens, the Command Timeout error bit will be set, and a new command sequence must be initiated with a START command. The command timeout delay can be changed with the cmd_timeout_ms parameter; a value of 0 disables this timeout.
If the Wixel receives a Get Errors command (‘E’), it will respond with a single byte containing the status of several error conditions. This command can be issued any time the app is not expecting a slave address or data byte.
When an error occurs, the corresponding bit in the error byte is set and remains set until the errors are read with the Get Errors command, after which it is cleared internally. The following table shows the error condition that corresponds to each bit:
|0 (LSB)||I²C NACK on Address||A NACK was received on the I²C bus after a slave device address was transmitted.|
|1||I²C NACK on Data||A NACK was received on the I²C bus after a data byte was transmitted.|
|2||I²C Timeout||The SCL line stayed low for too long (possibly because a slave device was holding it low) and the I²C bus was reset. The allowed delay until this timeout occurs is 10 ms by default and can be changed with the I2C_timeout_ms parameter.|
|3||Invalid Command||An invalid command byte was received on the serial interface.|
|4||Command Timeout||The next byte of an unfinished command sequence took too long to be received on the serial interface. The timeout is 500 ms by default and can be changed or disabled with the cmd_timeout_ms parameter.|
|5||UART Overflow||The UART’s receive buffer is full.|
|6||UART Framing Error||A framing error occurred on the UART.|
The green LED behaves as described in Section 1.a, and also flickers when there is data transferred over USB.
The yellow LED is on when VIN power is detected.
The red LED indicates an error condition when lit; it can be reset by issuing a Get Errors command (described above).
- bridge_mode: Selects the bridge mode (0–2, see list above). The default is 0.
- baud_rate: The baud rate to use for the UART, in bits per second. The default is 9600. We recommend not exceeding 115200. This parameter has no effect on serial communication over the virtual COM port (USB).
- I2C_freq_kHz: The clock frequency of the I²C bus, in kilohertz. The default is 100. Common I²C speeds are 10 kHz (low speed), 100 kHz (standard), and 400 kHz (high speed). The range of possible frequencies is 2-500 kHz; because of rounding inaccuracies and timing constraints, the actual frequency might be lower than the selected frequency, but it is guaranteed never to be higher.
- I2C_timeout_ms: The allowed delay, in milliseconds, before a low SCL line causes an I²C bus timeout. This resets the bus and sets the I²C Timeout error bit. The default is 10.
- cmd_timeout_ms: The allowed delay, in milliseconds, before failure to receive the next byte of a command sequence causes a command timeout. This resets the I²C bus and sets the Command Timeout error bit. The default is 500. A value of 0 disables this timeout.
- radio_channel: The channel number is from 0 to 255 and determines which frequency to broadcast on. The default is 128. Wixels must be on the same channel to communicate with each other. To avoid interference, Wixels that aren’t supposed to talk to each other should be at least 2 channels away from each other. For example, you could have one pair of Wixels on channel 128 and another pair on 130.
Pin Assignment Parameters
The following parameters can be used to reassign the I²C lines to different pins on the Wixel. The value of each parameter must be the number of an unused pin on the Wixel. The number can be computed by multiplying the first digit in the pin name by 10 and adding it to the second digit in the pin name. For example, if you wanted to assign the SCL pin to P1_2, you would set I2C_SCL_pin to 12.
- I2C_SCL_pin: The pin assignment for the I²C SCL (clock) line. The default is 10 (P1_0).
- I2C_SDA_pin: The pin assignment for the I²C SDA (data) line. The default is 11 (P1_1).
Data will be lost if the Wixel receives commands on the UART’s RX line faster than they can be processed on the I²C bus. If you have trouble, try reducing the amount of data sent to the RX line by lowering the baud rate or adding delays to your microcontroller’s code. Using the Get Errors command and checking the UART Overflow error bit is a good way to detect this problem.
Caution: The Wixel’s I/O lines are not 5V tolerant. You must use level-shifters, diodes, or voltage dividers to connect the Wixel to outputs from 5V systems. Also, avoid drawing more current from an I/O line than it can provide (see the discussion of P1_0 and P1_1 in Section 1.a). Avoid connecting multiple output pins together.
The Wixel does not support the RS-232 voltage levels typically used by DB9 serial ports. The Wixel’s I/O lines, including the RX and TX lines, operate on voltages between 0 and 3.3 V. To connect the Wixel to an RS-232 serial signal, you will need additional level-shifting and inverting hardware like the Pololu 23201a serial adapter (RS-232 serial is inverted; the Wixel’s serial interface expects non-inverted serial).
- Serial-to-I²C App v1.0 (26k wxl), released 2011-05-03: Initial release.