'ATtiny25 or ATtiny45 NOT ATtiny85 because of some sram asm addressing!!! 'PB3 serves as CDL1 (Compelled Data 1 Line, LOW from sender indicates binary "1" Data) 'PB4 serves as CDL0 (Compelled Data 0 Line, LOW from sender indicates binary "0" Data) 'IDE: BASCOM-AVR Demo V2.0.7.5 'Datum 11.03.2017 $regfile = "ATtiny25.DAT" $framesize = 28 $swstack = 32 $hwstack = 34 $crystal = 16000000 'internal oscillator, PLL Osccal = 78 'adjust internal oscillator wg soft UART Dim Flash_data(12) As Byte At &H60 'receive array MUST start at beginning of sram at &h60 'element (1) holds last byte of a block Dim Received_block_size As Byte 'element (rec_bloc_size) holds first byte of a block Dim Block_array_write_pointer As Byte 'indexes receive array during receive <-> asm r26 Dim Helper_byte As Byte Dim Break_flag As Byte 'for debug outputs Dim Block_flag As Byte 'for debug outputs Dim Read_flag As Byte Dim Dummy As String * 10 Dummy = "TEST START" Open "comb.0:19200,8,n,1" For Output As #1 'for debug outputs via SW-UART Portb = Bits(pb3 , Pb4) 'Pullups active at PB3(CDL1), PB4(CDL0) Read_flag = 2 For Helper_byte = 1 To 12 Flash_data(helper_byte) = 99 Next Pcmsk = Bits(pcint3 , Pcint4) 'CDL1 and CDL0 cause interrupts On Pcint0 Isr_rec_data_compelled Nosave 'CDL, CDL0 activity -> data to be received Enable Pcint0 Set Gifr.pcif 'clear interrupt flag Enable Interrupts Print #1 , Dummy Do 'Receiverroutine empfängt Blöcke vom Sender. Die empf. Daten werden über UART ausgegeben 'Ein nicht vollständiger Block (Übertragungspause Signal festgestellt) wird mit "Break Flag" 'unter den Daten ausgegeben. 'Ein vervollständigter Block wird mit "Block Flag" unter den Daten ausgegeben. If Break_flag > 0 Then 'debug output Break_flag = 0 Print #1 , " " For Helper_byte = 1 To Received_block_size Print #1 , Flash_data(helper_byte) Next Print #1 , " Break_Flag" End If If Block_flag > 0 Then 'debug output Block_flag = 0 Print #1 , " " For Helper_byte = 1 To Received_block_size Print #1 , Flash_data(helper_byte) Flash_data(helper_byte) = 99 Next Print #1 , " Block_Flag" If Read_flag = 0 Then Read_flag = 2 Print #1 , " " Print #1 , " Master wants data" End If End If Loop Isr_rec_data_compelled: 'ISR called if PCINT at CDL0 or CLD1 'PB3 = CDL1, if low from sender -> logical "1" transmitted 'PB4 = CDL0, if low from sender -> logical "0" transmitted $asm push r16 'r16 receive register push r17 'r17 loop variable, counts down received bits of a byte push r26 'r26 indexes receive array in r16,sreg push r16 LDI R17,8 'r17 loop variable, counts down received bits of a byte lds r26,{block_array_write_pointer} 'r26 receive array index Get_next_bit: Check_for_low_bit: 'CDL0 = LOW means "0" to be received sbic pinb,4 'check for LOW at CDL0 rjmp Check_for_high_bit 'not low at CDL0 jump to check CDL1 Get_low_bit: sbi ddrb,3 'use CDL1 as ack-line, output cbi portb,3 'send ack (CDL1 to LOW) to sender lsl R16 'bit 0 beomes "0" in receive register Check_cdl0_bit_removal: sbis pinb,4 'check CDL0 for removal of bit rjmp Check_cdl0_bit_removal sbi portb,3 'CDL0 became idle -> remove ack from CDL1: CDL1 back to high cbi ddrb,3 'CDL1 back to input: idle rjmp bit_rec_complete Check_for_high_bit: 'CDL1 = LOW means "1" to be received sbic pinb,3 'check for LOW at CDL1 rjmp Check_for_low_bit 'not low at CDL1 jump to check CDL0 Get_high_bit: sbi ddrb,4 'use CDL0 as ack-line, output Cbi portb,4 'send ack (CDL0 to LOW) to sender lsl R16 'prepare bit receive position SBr R16,1 'bit position 0 in R16 to "1" Check_cdl1_bit_removal: sbis pinb,3 'check CDL1 for removal of bit rjmp Check_cdl1_bit_removal sbi portb,4 'CDL1 became idle -> remove ack from CDL0, CDL0 back to high cbi ddrb,4 'CDL0 back to input: idle Bit_rec_complete: dec R17 'Bit received -> decrase bit counter brne get_next_bit 'branch if byte not completed cpi r26,&H61 brsh Continue 'array pointer not on first byte of block -> "continue" bst r16,7 'save R/W Bit andi r16,&b01111111 'extract blocksize from 1st byte of block sts {Received_block_size},r16 'save block size for use in main prg ldi r26,&h60 'load sram start address add r26,r16 'calculate highest array index +1 bld r16,7 'restore R/W bit Continue: st -x,r16 'store received byte in receive array cpi r26,&h60 'more bytes in block to be received? breq end_of_transmission 'end of transmission if block completed Check_cdl1_for_break: 'check for break condition (CDL0 and CDL1 both low) sbic pinb,3 'check for LOW at CDL1 rjmp Check_cdl0_for_break 'not low at CDL1 jump to check CDL0 ldi r17,8 '(if no ldi insert nop for timing!)initialise bit counter for next byte to receive sbis pinb,4 'cdl1 and cdl0 means break of transmission rjmp transmission_break rjmp get_high_bit 'low only on CDL1 detected Check_cdl0_for_break: 'check for break condition (CDL0 and CDL1 both low) sbic pinb,4 'check for LOW at CDL0 rjmp Check_cdl1_for_break 'not low at CDL0 jump to check CDL0 sbis pinb,3 'cdl1 and cdl0 means break of transmission rjmp transmission_break ldi r17,8 'initialise bit counter for next byte to receive rjmp get_low_bit 'low only on CDL0 detected Transmission_break: ldi r16,1 'for debug output sts {break_flag},r16 'for debug output rjmp end_of_sub End_of_transmission: Ldi R16 , 1 'for debug output sts {block_flag},r16 'for debug output End_of_sub: sts {block_array_write_pointer},r26 'save current array index clr r16 bld R16 , 0 sts {read_flag},r16 'will be "0" if master wants to read data ldi r16,&b0010_0000 'clear eventually set interrupt flag PCIF Out Gifr , R16 'clear eventually set interrupt flag PCIF pop r16 Out Sreg , R16 pop r26 pop r17 pop r16 $end Asm Return End 'end program