the main usb i/o chip can send asynchronous serial data to other chips 16 adresses for slaves max 16 data bytes per packet P is a parity bit belonging to it's byte packet format: # 8 7 6 5 4 3 2 1 0 0 P| ADDR | SIZE-1 1 P| DATA1 2 P| DATA2 . n P| DATAn n+1 P| XOR of DATA[1-n] (starting with b'11111111') since it makes no sense to send packets with no data, we store SIZE-1, this allows packet sizes from 1 to 16 inclusive the ping-pong buffers live at 0x20 and 0x30 in bank0 variables buf0 16 bytes buf1 16 bytes buf_size <- used by receiver buf_len <- used during processing address A A A A X X X X, address of this device 4 bits FSR_tmp usartrstate 7 6 5 4 3 2 1 0 A P X X X S S S A: buffer is available for processing, it should be cleared if processing is finished P: ping-pong state (which buffer belongs to the receiver...) X: unused S: state FSR 0 0 1 H L L L L H buffer wherin would be written if there were something to be written L address within buffer Receiver: - byte enters through UART... - check OERR * if OERR = 1: clear error, ignore byte, set state0 - check FERR * if FERR = 1: ignore byte, set state0 - check parity * if FAIL : ignore byte, set state0 - check timeout * if timeout = 1 set state0, continue - reset timeout - call usart_state receiver state machine ~~~~~~~~~~~~~~~~~~~~~~ state0: 'address' - set buf_size, FSR &= 11110000, buf_xor = 0xFF - match address * if MATCH set state1 * else set state3 (increment buf_size twice) state1: 'data' - store byte at INDF, xor with buf_xor - match lowest 4 bits of buf_size with same bits of FSR * if MATCH switch to state2 state2: 'checksum' - compare byte with buf_xor * if EQUAL // transfer is finished - is the other buffer free? (if no, this buffer will be lost) * YES - flip P, set A, set FSR to other buffer - set state0 state3: 'throw bytes away that are not adressed to us' dimmer protocol ~~~~~~~~~~~~~~~ addressed commands: * 0EFFAAAA EFF is command: G = 0 (respective value applies to each selected) ALWAYS 4 values 1 (one value applies to all selected) FF = 00 dim value 01 inc value 10 inc/dec + prescaler value AAAA is address of dimmers 3-0, so AAAA=1011 means: dim3,dim1 and dim0 * 10XXXDDD DDD is dimmer codepage, may not all be zero * 110XXXXD