'ATtiny861 'PA4 serves as CDL1 (Compelled Data 1 Line, LOW towards receiver indicates binary "1" Bit) 'PA5 serves as CDL0 (Compelled Data 0 Line, LOW towards receiver indicates binary "0" Bit) 'IDE: BASCOM-AVR Demo V2.0.7.5 $regfile = "ATtiny861.DAT" $framesize = 32 $swstack = 32 $hwstack = 38 $crystal = 16000000 'interner Oszillator, PLL Dim Flash_data_address_lo As Byte Dim Flash_data_address_hi As Byte Dim Flash_data_address As Word At Flash_data_address_lo Overlay Dim Char_count As Byte Dim Read_char As Byte Dim Flash_data(12) As Byte Dim Send_bytes_tmp As Byte Dim Rem_block_size As Byte Porta.4 = 1 'CDL1 pullup on Porta.5 = 1 'CDL0 pullup on Open "comb.4:19200,8,n,1" For Input As #2 'debug inputs via UART 'Tastatureingaben zum Basictest der Übertragungsroutinen, nicht "bulletproofed" 'Für die richtige Eingabe und Reihenfolge der Eingaben MUß der Bediener sorgen. 'ATtiny861 als Sender, ATtiny25 als Empfänger 'Nach Power ON, Reset oder Übertragung eines Blocks (11 Byte) darf nur ein "ENTER" 'zur Übertragungsinitialisierung eines neuen Blocks eingegeben werden. '1. Nur "ENTER" überträgt 3 fest programmierte Bytes zur Übertragungsinitialisierung: ' Erstes Byte: Write Bit = 1, Blocksize = 11 -> Dezimal = 139 ' Zweites und drittes Byte = 0 - reserviert '2. Eingabe von 1 bis 8 Ziffern von 0 bis 9 ' Die Ziffern werden gesammelt und gezählt '3. Eingabe von "ENTER" überträgt die gesammelten Ziffern '3.a. Es müssen für einen Block 11 Bytes übertragen werden ' Wurden nicht genügend Ziffern für einen vollständigen Block eingegeben ' und "ENTER" gedrückt, werden die vorhandenen Ziffern übertragen und danach ' eine Übertragungspause gesendet (CDL0 und CDL1 gleichzeitig kurz nach low) ' Danach geht der Sender "Offline" und wartet auf neue Tastatureingaben. ' Der Receiver geht damit auch "Offline" und kann andere Aufgaben abarbeiten. ' Wird ein weiteres Byte übertragen, erwartet der Empfänger, daß es ein Datenbyte ist. '3.b. Sind alle 11 Bytes eines Blockes (3 Initialisierungsbytes, 8 Datenbytes) ' vollständig, wird am Ende kein besonderes Zeichen übertragen. Der Empfänger "weiß" ' anhand der Initialisierungsbytes, daß der Block vollständig ist und geht ' von selbst "Offline". Bei neuer Übertragung erwartet er neue Initialisierungsbytes. '4. Weiter bei 1. Do Read_char = Waitkey(#2) If Read_char > 29 Then Read_char = Read_char - 48 If Read_char = 13 And Char_count = 0 Then 'send block header by only CR from keyboard Send_bytes_tmp = 3 Gosub Blockstart Gosub Send_data_towards_flash Elseif Read_char <> 13 Then 'collect digits 0..1 Incr Char_count 'nuber of collected digits (max 8) Flash_data(char_count) = Read_char Elseif Read_char = 13 And Char_count <> 0 Then 'send collected digits Send_bytes_tmp = Char_count 'hand over to sending routine Gosub Send_data_towards_flash Char_count = 0 End If Loop End 'end program Blockstart: Rem_block_size = 11 Flash_data_address = 0 Flash_data(1) = &B1000_1011 'dec. 139 Flash_data(2) = Flash_data_address_hi 'dec. 0 Flash_data(3) = Flash_data_address_lo 'dec. 0 Return Send_data_towards_flash: '############################################################################### ' 'serial sending routine via a compelled signalling method over two wires ' 'r16 Data to send 'r17 bit counter for sent bits per byte, initialized with 8 'r18 counter for sent bytes, initialised with number of bytes to send ' 'sends MSBs first. Signal/data lines are at PA4(CDL1) and PA5(CDL0) ' 'In idle state, CDL1 and CDL0 are inputs with activated internal pullup 'resistors, medium impedance, high potential to receiver on both lines. Receiver 'supplies the same electrical conditions (inputs, medium impedance, high potential.. ' 'To send a data bit as a HIGH Bit ("1"), CDL1 becomes an output and switches to LOW potential. 'Receiver sends acknowledement via the other data line CDL0 back to sender with LOW potential. 'Sender removes bit at CDL1 -> CDL1 becomes high potential again 'Receiver removes acknowledgement at CDL0 -> CDL0 becomes high again. CDL0 and CDL1 both HIGH -> idle 'Ready to send another bit. ' 'To send a data bit as a LOW bit ("0"), CDL0 becomes an output and switches to LOW potential. 'Receiver sends acknowledement via the other data line CDL1 back to sender with LOW potential. 'Sender removes bit at CDL0 -> CDL0 becomes HIGH potential again 'Receiver removes acknowledgement at CDL1 -> CDL1 becomes high again. CDL0 and CDL1 both HIGH -> idle 'Ready to send another bit. ' '############################################################################### $asm lds r18,{Send_bytes_tmp} 'r18 loop variable, number of bytes to be send in a row lds r19,{rem_block_size} Sub R19 , R18 sts {rem_block_size},r19 Loadadr Flash_data(1) , X 'load address of array into r26, r27 Next_byte: ld r16,x+ 'load byte to be send ldi r17,8 'r17 loop variable, number of bits of the byte to be send Wait_for_idle_lines: 'CDL0 and CDL1 must be HIGH to start transmission sbis pina,4 'check for HIGH at CDL1 rjmp Wait_for_idle_lines sbis pina,5 'check for HIGH at CDL0 rjmp Wait_for_idle_lines Start_transmission: SBrs r16,7 'skip next if bit to be send is high rjmp Send_low_bit Send_high_bit: 'switch CDL1 to LOW, keep CDL0 as input sbi ddra,4 'CDL1 as output Cbi porta,4 'CDL1 to LOW Check_ack_for_high_bit: sbic pinA,5 'wait ack. from Receiver (LOW at CDL0) rjmp Check_ack_for_high_bit Sbi portA,4 'ack received: reset CDL1 to HIGH CbI ddrA,4 'reset CDL1 to an input rjmp Next_bit Send_low_bit: 'switch CDL0 to LOW, keep CDL1 as input sbi ddrA,5 'CDL0 as output Cbi portA,5 'CDL0 to LOW Check_ack_for_low_bit: sbic pinA,4 'wait ack. from receiver (a LOW at CDL1) rjmp check_ack_for_low_bit Sbi portA,5 'ack received: CDL0 back to HIGH CbI ddrA,5 'CDL0 back to an INPUT Next_bit: lsl R16 'shift next data bit to send position (to pos 7 in R16) dec R17 'decrement counter of transmitted bits brne Wait_for_idle_lines 'branch if more bits to send dec r18 'complete byte transmitted: decrement counter of transmitted bytes Brne next_byte 'branch if more bytes to be send tst r19 'test if complete Block was sent breq end_of_sub 'block complete -> end End_of_transmission: 'block not complete send break sbis pina,4 'make sure CDL1 is HIGH rjmp End_of_transmission sbis pina,5 'make sure CDL0 is HIGH rjmp End_of_transmission 'break signal start sbi ddrA,4 'CDL1 as output sbi ddrA,5 'CDL0 as output cli 'CDL0 and CDL1 must change "simultaneously" to low Cbi portA,4 'CDL1 to LOW Cbi portA,5 'CDL0 to LOW sei nop 'give receiver detection time nop 'give receiver detection time nop 'give receiver detection time sbi portA,4 'CDL1 to high sbi portA,5 'CDL0 to high cbi ddrA,4 'CDL1 as input cbi ddrA,5 'CDL0 as input 'break signal stop End_of_sub: $end Asm Return