; BlueDataDistributor - data distribution module from ethernet to 32 serial ports ; version 0.1 date 2006-09-18 ; Copyright (C) 2006 Stefan Schuermans ; a BlinkenArea project - http://www.blinkenarea.org/ #include .section .text ; output 0 = PB0 ; output 1 = PG2 ; output 2 = PB2 ; output 3 = PB3 ; output 4 = PB4 ; output 5 = PB5 ; output 6 = PB6 ; output 7 = PB7 ; output 8 = PF0 ; output 9 = PF1 ; output 10 = PF2 ; output 11 = PF3 ; output 12 = PF4 ; output 13 = PF5 ; output 14 = PF6 ; output 15 = PF7 ; output 16 = PD0 ; output 17 = PD1 ; output 18 = PD2 ; output 19 = PD3 ; output 20 = PD4 ; output 21 = PD5 ; output 22 = PD6 ; output 23 = PD7 ; output 24 = PG0 ; output 25 = PG1 ; output 26 = PE2 ; output 27 = PE3 ; output 28 = PG4 ; output 29 = PE5 ; output 30 = PE6 ; output 31 = PE7 .macro generatebit sourcemask, destreg, destbit ld R16, Z+ and R16, \sourcemask breq .+2 ; jump over next instruction sbr \destreg, 1 << \destbit .endm ; 5 cycles .macro generatebytes sourcemask clr R17 ; clear registers (5 cycles) clr R18 clr R19 clr R20 clr R21 generatebit \sourcemask, R17, 0 ; for PORTB generatebit \sourcemask, R21, 2 ; for PG2 generatebit \sourcemask, R17, 2 generatebit \sourcemask, R17, 3 generatebit \sourcemask, R17, 4 generatebit \sourcemask, R17, 5 generatebit \sourcemask, R17, 6 generatebit \sourcemask, R17, 7 generatebit \sourcemask, R20, 0 ; for PORTF generatebit \sourcemask, R20, 1 generatebit \sourcemask, R20, 2 generatebit \sourcemask, R20, 3 generatebit \sourcemask, R20, 4 generatebit \sourcemask, R20, 5 generatebit \sourcemask, R20, 6 generatebit \sourcemask, R20, 7 generatebit \sourcemask, R18, 0 ; for PORTD generatebit \sourcemask, R18, 1 generatebit \sourcemask, R18, 2 generatebit \sourcemask, R18, 3 generatebit \sourcemask, R18, 4 generatebit \sourcemask, R18, 5 generatebit \sourcemask, R18, 6 generatebit \sourcemask, R18, 7 generatebit \sourcemask, R21, 0 ; for PG0 generatebit \sourcemask, R21, 1 ; for PG1 generatebit \sourcemask, R19, 2 ; for PORTE generatebit \sourcemask, R19, 3 generatebit \sourcemask, R21, 4 ; for PG4 generatebit \sourcemask, R19, 5 generatebit \sourcemask, R19, 6 generatebit \sourcemask, R19, 7 .endm ; 4 * 8 * 5 + 5 cycles = 165 cycles .macro loadvalue value mov R17, \value mov R18, \value mov R19, \value mov R20, \value mov R21, \value .endm ; 5 cycles .macro outputbytes ori R17, 0x02 ; PB1 is programming clock, its pull-up must stay on ori R19, 0x01 ; PE0 is programming data input, its pull-up must stay on andi R19, 0xED ; PE1 is the programming data output, it must stay low ; PE4 is the RTL8019 interrupt input, it must stay low andi R21, 0x17 ; PG3 is the status LED output, it must keep its level (PG7..5 do not exist) lds R16, PORTG sbrc R16, 3 sbr R21, 0x08 out PORTB-0x20, R17 ; output out PORTD-0x20, R18 out PORTE-0x20, R19 sts PORTF, R20 sts PORTG, R21 .endm ; 15 cycles ; output the specified bit of a byte on every serial port ; - data must point to SERIAL_OUTPUT_CNT=32 bytes ; - bit_mask must be 0x01, 0x02, ... 0x80 for bits 0, 1, ..., 7 ; - bit_mask must be 0x00 for the start bit and 0xFF for the stop bit ; extern void SerialOutputBit( unsigned char * data, unsigned char bit_mask ); .global SerialOutputBit .func SerialOutputBit SerialOutputBit: push R16 push R17 push R18 push R19 push R20 push R21 ; parameters: R25:R24=data, R22=bit_mask mov ZL, R24 ; load data address into Z mov ZH, R25 cpi R22,0x00 ; check if to output a special bit breq SerialOutputBitSpecial2nop cpi R22,0xFF breq SerialOutputBitSpecial rjmp SerialOutputBitNormal SerialOutputBitSpecial2nop: nop nop SerialOutputBitSpecial: loadvalue R22 rcall wait159 rjmp SerialOutputBitOutput SerialOutputBitNormal: generatebytes R22 ; generate values to output SerialOutputBitOutput: outputbytes ; output pop R21 pop R20 pop R19 pop R18 pop R17 pop R16 ret .endfunc ; wait 159 cycles (including rcall and ret) wait159: ldi R16, 50 ; 1 cycle wait159_loop: dec R16 ; N cycles brne wait159_loop ; 2N-1 cycles nop ; 2 cycles nop ret ; 7 cycles (including rcall)