Active Flipper Controller Communication ======================================= The Active Flipper Controller can be controlled over SPI (mode0), serial (8N1) or I2C (7-bit addressing) communication. All three communication channels are available simultaneously. However, it is more appropriate or likely to pick one method for a set of displays. Communication is divided in command-bytes and data-bytes. Commands are identified with bit 7 set to '1'. Each command follows zero to seven data bytes with bit 7 set to '0'. The communication is self-synchronizing because of the bit 7 distinction. Commands sent with too few data-bytes are ignored. You can send a string of NOPs if, for any reason, you want to ensure that all displays are in a known state. Command and data format ======================= Command-byte: 1 ccc ssss ccc command ssss skip (forward if != 0) Data-byte: 0 xxxxxxx The number of data-bytes for each command is detailed below. Commands ======== 1 000 ssss clear all 1 001 ssss set all 1 010 ssss set pixel 0 a yyy xxx value a at pos x,y (x=0..6) 1 010 ssss shift display 0 ddnn 111 dd=direction, nn=number of rows 1 011 ssss set screen pixels 0 aaaaaaa value for all positions 0 aaaaaaa 0 aaaaaaa 0 aaaaaaa 0 aaaaaaa 0 aaaaaaa 0 aaaaaaa 1 100 ssss line 0 a yyy xxx a=value x,y=start pos 0 i yyy xxx i=invert x,y=end pos (note: invert=1 ignores value) 1 101 ssss rect 0 a yyy xxx a=value x,y=corner 1 0 f yyy xxx f=fill x,y=corner 2 1 110 ssss config 0 nnnnnnn 0 vvvvvvv n=index to set 0 - no operation (will return voltage) 1 - set flipdot size, large(v=1) small(v=0) 2 - set mirror X (v=[01]) 3 - set mirror Y (v=[01]) 4 - set exchage XY (v=[01]) 5 - set i2c address (v=address) 6 - set i2c slewrate (v=[01]) 7 - set i2c smbus compatibility (v=[01]) 8 - set baudrate (v=0..15) 42 - save config (v must be 0x69) 69 - reset controller (v must ve 0x42) v=value (input) or voltage (output) 1 111 ssss NOP s=always echoed as 'ssss'-1) Sending data, SPI ================= You may cascade up to 16 Active Flipper displays using the Active Flipper Controller. Addressing is embedded in the command structure. With 4 cascaded Active Flipper displays you can clear them all simultaneously by sending 4 bytes: 0x83 0x82 0x81 0x80 The commands result in the following rx/tx sequence: | Host_TX | Af0_RX | Af1_RX | Af2_RX | Af3_RX | Host_RX ---+---------+--------+--------+--------+--------+-------- 1 | 0x83 | 0x83 | 0xff | 0xff | 0xff | 0xff 2 | 0x82 | 0x82 | 0x82 | 0xfe | 0xfe | 0xfe 3 | 0x81 | 0x81 | 0x81 | 0x81 | 0xfd | 0xfd 4 | 0x80 | 0x80 | 0x80 | 0x80 | 0x80 | 0xfc The host has sent the first byte at Step 1, the second at Step 2, the third at Step 3 and the final fourth at Step 4. Every command that is not directed at the current controller will be echoed with the counter decreased by one. All Active Flipper Controllers have a command received that is directed at them (counter == 0) at Step 4 and all displays will simultaneously change the display state. Initially, the host will receive NOPs for each byte sent. The previous command(s) are echoed through the cascade with the counter set to maximum. If, for example, the next sequence should set all flipdots, then the following sequence would appear: | Host_TX | Af0_RX | Af1_RX | Af2_RX | Af3_RX | Host_RX ---+---------+--------+--------+--------+--------+-------- 5 | 0x93 | 0x93 | 0x8f | 0x8f | 0x8f | 0x8f 6 | 0x92 | 0x92 | 0x92 | 0x8e | 0x8e | 0x8e 7 | 0x91 | 0x91 | 0x91 | 0x91 | 0x8d | 0x8d 8 | 0x90 | 0x90 | 0x90 | 0x90 | 0x90 | 0x8c A subsequent clearing of one pixel for each display and adding some NOPs (for clarity) would have the sequence: | Host_TX | Af0_RX | Af1_RX | Af2_RX | Af3_RX | Host_RX ---+---------+--------+--------+--------+--------+-------- 9 | 0xa3 | 0xa3 | 0x9f | 0x9f | 0x9f | 0x9f 10 | 0x1b | 0x1b | 0xa2 | 0x9e | 0x9e | 0x9e 11 | 0xa2 | 0xa2 | 0x1b | 0xa1 | 0x9d | 0x9d 12 | 0x12 | 0x12 | 0xa1 | 0x1b | 0xa0 | 0x9c 13 | 0xa1 | 0xa1 | 0x12 | 0xa0 | 0x1b | 0xaf (set 3,3) 14 | 0x09 | 0x09 | 0xa0 | 0x12 | 0xaf | 0x1b (set 2,2) 15 | 0xa0 | 0xa0 | 0x09 | 0xaf | 0x12 | 0xae (set 1,1) 16 | 0x00 | 0x00 | 0xaf | 0x09 | 0xae | 0x12 (set 0,0) 17 | 0xff | 0xff | 0x00 | 0xae | 0x09 | 0xad 18 | 0xff | 0xff | 0xfe | 0x00 | 0xad | 0x09 19 | 0xff | 0xff | 0xfe | 0xfd | 0x00 | 0xac 20 | 0xff | 0xff | 0xfe | 0xfd | 0xfc | 0x00 21 | 0xff | 0xff | 0xfe | 0xfd | 0xfc | 0xfb 22 | 0xff | 0xff | 0xfe | 0xfd | 0xfc | 0xfb It should be clear from the sequences that you need to send enough data through the cascade to ensure that the target display receives both command- and data-bytes. If, for example, you need to set only one pixel at the last display in the cascade, you need to add NOPs to propagate the command- and data-byte(s) to the target display. Each byte gets delayed by one step for each intermediary it has to pass. Because all commands and data are echoed, it is possible to determine whether the displays received the correct data. Examining the exiting data-stream should result in the same stream as input, with the exception of all command-byte counts being changed to 16-N, where N is the number of displays in the cascade. This may be especially helpful in serial communication, where framing errors may occur. It is strictly seen not necessary to connect the RX line back to the sender if you are not interested in verifying the data from the cascade. Sending data, serial ==================== The difference between SPI and serial communication is the self-clocking nature of serial communication. As a consequence, you do not need to add any NOPS in the communication and any byte you send will traverse the entire cascade automatically. Each controller uses a store-and-forward method. When a communication byte is received, it is inspected, modified as appropriate and immediately sent again. A host sending a byte will receive an answer delayed by the number of controllers in its path. Sending data, I2C ================= Since I2C is a bus-structure and includes unique addressing, you must first assure that each Active Flipper Controller is setup with a unique I2C address. This can be accomplished through the console interface or through sending a SPI/serial configuration command. Valid I2C address range is 0x08..0x77 (7-bit addressing). The command/data structure follows the same format as above, with the exception that each display is addressed separately. There is therefore no need to add extra NOPs for data propagation purposes. Sending from a PC ================= You can standard use up to 16 Active Flipper Controllers cascaded on one communication line. However, you can address up to 64 Active Flipper Controllers with just one serial port from a PC when using the DTR and RTS lines as selectors. Please note that you must ensure proper logic levels for DTR, RTS, TX and RX. A level shifter may be required. TX de-multiplexing: +-----------+ | | RTS >----+ A0 Y0 +-----> TX0 | | DTR >----+ A1 Y1 +-----> TX1 | | TX >----+ EN Y2 +-----> TX2 | | | Y3 +-----> TX3 | | +-----------+ 1/2 74HC(T)139 RX multiplexing (optional): +-----------+ | | RTS >----+ S0 I0 +-----< RX0 | | DTR >----+ S1 I1 +-----< RX1 | | RX <----+ EN I2 +-----< RX2 | | | I3 +-----< RX3 | | +-----------+ 1/2 74HC(T)153 If you are prepared to do some bit-banging on the RTS and DTR lines, you can extend the number of displays to a very large number with only one serial port.