Implements synchronous master-mode I2C control at 100khz or 400khz (default). Optional "nunchuck" mode automatically polls and decodes data from an attached Wii Nunchuck.
The I2C clock is pin AN10 / B1. I2C data is pin AN12 / B0.
**NOTE:** I2C "open-drain" requires a pull-up resistor placed between the SCL and V+, SDA and V+ (typically, 1-4k ohms). The PIC18 runs at 5v but the V+ supply for I2C can be regulated down to 3.3v and the module will still work correctly (a level-translation circuit is not required).
**NOTE:** The 7-bit I2C address range is 0x00 - 0x7f (0-127). The "start byte" is the address shifted up by 1 bit, i.e. the address * 2. One should take note of this difference when reading the spec sheet for the slave device--sometimes the address is given, sometimes the start byte is given. The read and write messages in this I2C implementation accept the _address_ as the first argument.
--------
**/i2c/enable**
Turn I2C mode on/off. When I2C is on, analog inputs AN10 an AN12 are not available.
-------
**/i2c/nunchuck**
Enabled/disable automatic nunchuck-polling mode. When enabled, an attached Wii Nunchuck (or compatible device) will be automatically polled and interpreted. Other I2C devices may also be attached to the bus at the same time.
TX: [ /i2c/enable 1 ]
RX: [ /i2c/enable 1 ]
TX: [ /i2c/nunchuck 1 ]
RX: [ /i2c/nunchuck 1 ]
RX: [ /nunchuck ,fffffii (x-stick) (y-stick) (x-accel) (y-accel) (z-accel) (z-button) (c-button) ]
RX: [ /nunchuck ,fffffii (x-stick) (y-stick) (x-accel) (y-accel) (z-accel) (z-button) (c-button) ]
RX: [ /nunchuck ,fffffii (x-stick) (y-stick) (x-accel) (y-accel) (z-accel) (z-button) (c-button) ]
...
The nunchuck data is reported at about 50 times per second. The floating point numbers range over 0. to 1. and are not calibration corrected. (A future version may correctly read and use the builtin calibration data...).
-------
**/i2c/read**
Given an I2C address (7 bits), an address (8 bits or NULL / -1 to omit address pointer-setting), and a length n, reads n bytes from a device. Reports transaction status, "ok", "nak" (device did not acknowledge), "busy" (I2C bus error or not available) or "wcol" (write collision). Response data is a blob.
TX: [ /i2c/read 0x90 0x00 6 ]
RX: [ /i2c/read 0x90 0x00 "ok" (blob: 0x00, 0x00.... ) ]
The above example generates the following sequence on the I2C bus:
I2C Start
I2C Write 0x90
I2C Slave-ACK
I2C Write 0x00
I2C Slave-ACK
I2C Restart
I2C Slave-ACK
I2C Write 0x91
I2C Slave-ACK
I2C Read (byte #1)
I2C Master-ACK
I2C Read (byte #2)
I2C Master-ACK
...
I2C Read (byte #6)
I2C Master-ACK
I2C Stop
Many devices use the initial write + address + restart to set the internal address pointer, however this is not always applicable. If not, set the address to NULL or -1 as follows:
TX: [ /i2c/read 0x90 NULL 6 ]
RX: [ /i2c/read 0x90 NULL "ok" (blob: 6 bytes... ) ]
The above example generates the following sequence on the I2C bus:
I2C Start
I2C Write 0x91
I2C Slave-ACK
I2C Read (byte #1)
I2C Master-ACK
I2C Read (byte #2)
I2C Master-ACK
...
I2C Read (byte #6)
I2C Master-ACK
I2C Stop
-------
**/i2c/write**
Writes a sequence of data to the I2C device and address specified. Address may be NULL to skip (e.g. set address in the blob). Data is taken from blob, string or sequence of integers. Response indicates transaction status and number of bytes sent.
TX: [ /i2c/write 0x90 0x00 (blob: data... e.g., 6 bytes ) ]
RX: [ /i2c/write 0x90 0x00 6 ]
The above example generates the following sequence on the I2C bus:
I2C Start
I2C Write 0x90
I2C Slave-ACK
I2C Write 0x00
I2C Slave-ACK
I2C Write (byte #1)
I2C Slave-ACK
I2C Write (byte #2)
I2C Slave-ACK
...
I2C Read (byte #6)
I2C Slave-ACK
I2C Stop
The following additional messages are equivalent forms:
Data as a null-terminated string: (this type cannot transmit the byte 0x00)
TX: [ /i2c/write ,iis 0x90 0x00 "123456" ]
Data as a sequence of ints (only the least-significant 8 bits are taken):
TX: [ /i2c/write ,iiiiiiii 0x90 0x00 1 2 3 4 5 6 ]
The address (second argument) may be omitted with a NULL or -1. In this case the user may put the address as the first byte in the data section.
TX: [ /i2c/write ,iNiiiiiii 0x90 NULL 0x00 1 2 3 4 5 6 ]