vim: ai tw=90 et $Id$ (0) index (0) index (1) prerequisites (2) i2c protocol definition (2.1) opcodes and there meaning (2.1.1) channel commands (2.1.2) script commands (2.1.3) UPNP commands (2.1.4) global commands (2.1.5) memory mode commands (2.2) parameters (2.3) return values (2.3.1) rstat (2.3.2) rmask, RSTATMASK (2.3.3) rlen, RSTATINT (3) bootloader (3.1) memory mode (4) memory layout (4.1) UID (4.2) i2c-address (4.3) device config (4.4) offset-table (4.5) slot-table and scripts (1) prerequisites - bootloader the device has a special, i2c-capable bootloader that implements a subset of this protocol. see more in (3). (2) i2c protocol definition an i2c command consists of one 8-bit-opcode - the first byte sent over the channel - optional parameters and optional return values. obviously, the parameters are sent after the opcode. a return value, if required, is to be sent by the command-receiving device after all possible parameters and after complete execution of the command, if not otherwise mentioned. upon receipt of an unknown opcode, flush/clear all i2c-buffers and send an rstat as defined in (2.3.1). after receiving a memory-mode command except memory-mode:enter (0x7C), which calls the bootloader, the fnordlicht firmware (in contrast to the boot-loader) has to flush/clear all i2c-buffers and send an rstat as defined in (2.3.1). for more information on memory-mode commands, see (3.1). (2.1) opcodes and their meaning /--------command group bit 0. reserved for protocol-extensions, set to 0. | |/-------command group bit 1 || ||/------command group bit 2 ||| |||/-----read/write bit, also used to toggle modes between set/get |||| |||| //// Parameter bits opcode opcode in hex: in binary: command: parameters: return: ======= ========== ================= ============================================== ================================= (2.1.1) channel commands 00 0000 0000 channel: get channelmask (rstat | RSTATMASK), channelmask, |channelmask|*brightness send brightness of specified channels, if not in scripting mode. otherwise ignore command and set FAILED in rstat. 10 0001 000n channel: set channelmask, |channelmask|*brightness rstat 11 set specified channels to specified brightness, if not in script mode. otherwise ignore command and set FAILED in rstat. if n = 0, wait for sync if n = 1, set immediate 12 0001 001n channel: set fast channelmask, |channelmask|*brightness nil 13 set specified channels to specified brightness, if we are not in script mode. otherwise ignore command. don't send an answer if n = 0, wait for sync if n = 1, set immediate 14 0001 010n channel: fade channelmask, |channelmask|*{time, brightness} rstat 15 fade specified channels to specified brightness in specified time, if we are not in script mode. otherwise ignore command and set FAILED in rstat. if n = 0, wait for sync if n = 1, fade immediate 1E 0001 1110 channel: sync nil sync all channels, if not in scripting mode. otherwise ignore. 1F 0001 1111 clean command fifo rstat remove any fading and channel:set commands from the command fifo and stop any fading, if not in scripting mode. otherwise ignore command and set FAILED in rstat. (2.1.2) script commands 20 001n 0000 script: switch nil rstat 30 if n = 0: disable scripting engine if n = 1: enable scripting engine 34 0011 01nm script: config thread threadmask, slot rstat 35 configure specified script-thread: 36 script handler depends on (n,m): (37) (0,0): RAM (0,1): EEPROM (1,0): FLASH script to run is defined by slot. 38 0011 1000 script: disable thread threadmask rstat 39 0011 1001 script: enable thread threadmask rstat (2.1.3) UPNP commands 40 0100 0000 upnp: send uid i2c-address, UID, xor nil any light must ignore this command. it is supposed to send such a command to the segment-master after receiving a request. after sending, switch back to client mode. if this device has not yet a configured i2c-address, send 0 as i2c-address a fnordlicht may also send this command at any time to announce its existence to the segment master, e.g. after power-on of the device. 50 0101 0000 upnp: request uid i2c-address nil get UID and i2c-address of light to i2c-address (as master). upon this command, every receiving light is supposed to switch to i2c master-mode and send a upnp: send uid command this command may be directed to broadcast. 41 0100 0001 upnp: request i2c UID, xor nil any light must ignore this command. it may send this command to i2c-broadcast to request an i2c-address from the segment-master. 51 0101 0001 upnp: set i2c i2c-address, UID, xor nil set i2c-address, if UID matches and xor is ok. set in any case, even if we already have one. 41 0100 0010 upnp: read devconf rstat, data, xor read channel configuration from fnordlicht. fnordlicht answers with data in [device config], see X.X.X (2.1.4) global commands 60 0110 0000 nop rstat do nothing and return rstat 70 0111 0000 reset: device nil hardreset device (2.1.5) memory mode commands 6C 011n 1100 enter(n=1)/leave(n=0) rstat 7C switch to memory mode 6D 0110 1101 read from RAM offset, len rstat, data, xor 7D 0111 1101 write to RAM offset, len, data, xor rstat 6E 0110 1110 read from EEPROM offset, len rstat, data, xor 7E 0111 1110 write to EEPROM offset, len, data, xor rstat 6F 0110 1111 read from FLASH offset, len rstat, data, xor 7F 0111 1111 write to FLASH offset, len, data, xor rstat (2.2) parameters some opcodes have parameters as defined here: channelmask: 8 bit mask: a bitmask of channels to affect. least significant bit: 1st channel, most significant bit: last channel; brightness: 8 bit unsigned int: brightness value time: 16 bit: 8.8 bit fixed point value: time in which to fade first byte: lowbyte, right of comma = least significant bits second byte: highbyte, left of comma = most significant bits slot: 8 bit unsigned int (see 4.5): slot of script to be executed len: 8 bit unsigned int: some data-length i2c-address: 8 bit unsigned int (see 4.2): i2c-address of device UID: 32 bit unsigned int (see 4.1): unique id. each fnordlicht should have its own xor: 8 bit: xor over ALL previous parameters or return-values. this is used for data-integrity-tests. if it does not match, ignore the command and do not set ACK in a possibly returned rstat. (2.3) return values (2.3.1) rstat rstat is an 8 bit return value. if opcode was unknown, - set rstat = ( NOCMD ) (read: NACK, NOCMD) if opcode was a memory-mode command except memory-mode:enter (0x7C), - set rstat = ( ACK | NOCMD ) if not otherwise specified: - set SCRIPT bit depending on whether we are in scripting mode (set to 1) or not (set to 0). - set ACK and never set NOCMD. - set the RSTATMASK bit if there is some channel-brightness data coming after rstat. (see 2.3.2) - set the RSTATINT bit if there are other return-values (except channel brightness data) coming after rstat. (see 2.3.3) /--- rstat ---\ MSB 7 6 5 4 3 2 1 0 LSB | | | | | | | | | | | | | | | \_____________________________ RSTATINT long rstat: see (2.3.3) | | | | | | | | | | | | | \_______________________________ RSTATMASK long rstat: see (2.3.2) | | | | | | | | | | | \_________________________________ MEMORYMODE set to 0 | | | | | | | | | \___________________________________ % reserved, set to 0 | | | | | | | \_____________________________________ FAILED set to 0 if not otherwise specified. | | | | | \_______________________________________ SCRIPT 1 if in script mode, 0 if not | | | \_________________________________________ NOCMD invalid command if 1, ok if 0 | \___________________________________________ ACK ACK if 1, NACK if 0 (2.3.2) rmask, RSTATMASK if RSTATMASK is set, after rstat is coming rmask. rmask is an 8 bit bitmask, as described in (2.2):channelmask. after rmask, |rmask| (i.e.: how many bits in rmask are set in rmask) brightness-values must be transmitted, corresponding to the set bits and in the order: least significant channel first. (2.3.3) rlen, RSTATINT in rstat, RSTATINT is set, if there is more data coming after the rstat. the first byte coming after rstat is rlen. rlen is an 8 bit unsigned int describing the len of the following data in bytes. after this, (rlen) bytes have to be send, consisting of the data to be send. the fnordlicht firmware only needs to do this upon UPNP: read devconf (3) boot loader a special bootloader is required, capable of i2c and implementing a subset of the i2c-protocol as defined in (2). this subset consists of all commands defined in (2.1.4) and (2.1.5). (3.1) memory mode when entering memory mode, the fnordlicht firmware has to cease working and call a callback in the bootloader. this callback will provide the described subset of i2c-commands and a function to jump back into the fnordlicht-firmware. (4) memory layout FLASH /-----------------------\ | interrupt table | >-----------------------< | | | fnordlicht firmware | | | >-----------------------< | slot-table | > - - - - - - - - - - - < | scripts | >-----------------------< | boot loader | \-----------------------/ EEPROM /-----------------------\ | UID | >-----------------------< | i2c-address | >-----------------------< | device config | >-----------------------< | offset-table | | of flash-slot-table | | of eeprom-slot-table | | of memory-mode routine| >-----------------------< | slot-table | > - - - - - - - - - - - < | scripts | \-----------------------/ (4.1) UID: 32 bit a 32-bit unsignet int, unique fnordlicht identification number. should be set upon initial flashing of atmel. (4.2) i2c-address: 8 bit the i2c-address of this device. upon initial flashing, this may be set to a value or to 0. if 0, this device will be autoconfigured via upnp by the segment master. (4.3) device config: unknown some device configuration data, so far unspecified, but will consist of this stuff: - software version - hardware information: how many/which channels do exists, which color do they provide? (4.4) offset-table: 3 x 16 bit = 48 bit table of offsets of other tablesd. (4.5) slot-table and scripts: variable, space filling slot-table: 1 byte: number of scripts, table with offsets to script-starting-points in the scripts-area scripts: raw data containing scripts