#include <avr/io.h>


//------------------------  ПОДПРОГРАММА  READ и  WRITE (Отправляет Cnt младших бит из Cmd) ---------------------------------
/*
    Cmd: 0 - продолжить
	     1 - команда записи данных в RAM
		 2 - чтение данных
		 4 - сброс

    Время на запись:
	     Ноль  - 100 т.и.
		 Один  - 69 т.и.
		 Сигнал- 143 т.и.

		 на чтение:

		 Ноль  - 100 т.и.
		 Один  - 69 т.и.
		 Сигнал- 123 т.и.


*/ 

/*
    Команды:
	    0 - далее 
		1 - сброс
		2 - чтение
		3 - запись
*/

// частота отлаживаемого микроконтроллера
#define FClk 14300//Частоты, на которых тестировалась отладка: 16934,14300,10000,7373,12000,18000,17734,20000,3686,
                  //На частотах 3579, 3600 4000 отладка не заработала

// следующие 3 строки надо привести в соответсвтие с используемым для отладки портом
#define PORT _SFR_IO_ADDR(PORTB)
#define DDR  _SFR_IO_ADDR(DDRB)
#define PIN  _SFR_IO_ADDR(PINB)

// номер бита выбранного порат, используемого для отладки
#define BitNum 0

   
// синонимы для регистров
#define  WaitCount r26 // счетчик в циклах ожидания
#define  BitCount  r27 // счетчик битов
#define  Res0      r28 // временно зранит результаты прошлых чтений
#define  Cmd       r29 // код обрабатываемой команды
#define  ByteCnt   r16 // счетчик отправленых байтов
#define  KS        r17 // контрольная сумма




.global Dbg

//-------------------  Основная ф-ия отладки. Именно она и вызывается  ------------------------------------

Dbg:   
    cbi PORT, BitNum

	push WaitCount
    sbi DDR, BitNum // пошел запрос прерывания (7 т.и.)
	
	ldi WaitCount, (65 * FClk - 140000) / 60000 + 1
	in   WaitCount, _SFR_IO_ADDR(SREG)
    push WaitCount

	clr  WaitCount

WaitSendItr: 
    dec WaitCount
	brne WaitSendItr
    push BitCount

    cbi DDR, BitNum // снятие запроса прерывания (надо что б единица устоялась)

    
	push Res0
	push Cmd     
	push ByteCnt
    push KS
	push r30
	push r31

Cikl: // перед начала цикла ждем завершения прошлого - единицы на линии.    
	clt // чтение
    cli 
	rcall ReadWrite
    mov   Cmd, Res0

	rcall ReadWrite
    mov r30, Res0

	rcall ReadWrite
    mov r31, Res0

	rcall ReadWrite
	
	cpi   Cmd, 1
	brcs  CmdContinue // был код 0

	breq  CmdWrite // был код 1	

M1: ldi   ByteCnt, 8
    set // передача
    ldi  KS, 0xAA
ReadCikl:
    ld   Res0, Z+ 
	add   KS, Res0
    rcall ReadWrite
	dec   ByteCnt
	brne  ReadCikl

	mov   Res0, KS
	rcall ReadWrite

    rjmp Cikl

CmdWrite:
    st Z, Res0
    rjmp Cikl

CmdContinue:
    set // передача
	ldi Res0, 0x55
	rcall ReadWrite

Exit: wdr // сброс WatchDog
    pop r31
	pop r30 
    pop  KS
	pop  ByteCnt
	pop  Cmd
	pop  Res0
	pop  BitCount
	pop  WaitCount
	out  _SFR_IO_ADDR(SREG), WaitCount
	pop  WaitCount
	ret
	

//-------------------------    ОСНОВНАЯ ПРОЦЕДУРА ЧТЕНИЯ - ЗАПИСИ  --------------------

ReadWrite:
/*
    Чтение: флаг T = 0
	          
*/    
    ldi  BitCount, 8
    

//-------------------------    ЖДЕМ УСТАНОВКИ НУЛЯ  --------------------------------------------
Wait0:
    sbic PIN, BitNum
	rjmp Wait0

    

//-------------------------    ТЕПЕРЬ ЖДЕМ СНЯТИЕ НУЛЯ  -----------------------------------------------

    
Wait1: 
    
    sbis PIN, BitNum
	rjmp Wait1
	
    
	
//----------------------------------  ЕСЛИ ЭТО ЗАПИСЬ - СТАВИМ СИГНАЛ----------------
    lsr Res0  
	brtc Reading

    brcs BitCikl   // если единица, то и делать ни чего не надо

    sbi  DDR, BitNum   // иначе устанавливаем 0


//-------------------------------------  ЗАДЕРЖКА ОТ 65 ДО 96 т.и. ПРИ 20 мГц  ----------------------


     ldi WaitCount, (65 * FClk - 140000) / 60000 + 1
SignalWait:
     dec WaitCount
     brne SignalWait
	
	cbi  DDR, BitNum   // возвращаем 1 
    
	rjmp BitCikl

//-------------------------    СНИМАЕМ РЕЗУЛЬТАТ    ------------------------------------------
Reading:
    
	ldi WaitCount, (79 * FClk - 120000) / 60000 + 1//от 73 до 105

EndReadingWait:
	dec WaitCount
    brne EndReadingWait 

	sbic PIN, BitNum
    ori  Res0, 0x80

//-------------------------    НУ И ИДЕМ ЖДАТЬ СЛЕДУЮЩЕГО ЦИКЛА     ----------------------------
BitCikl:
    dec BitCount
    brne Wait0

//-------------------------   ВЫХОД - ПРЕДВАРИТЕЛЬНО ЖДЕМ ПОЯВЛЕНИЯ 1  -------------------------

    
m0:
	sbis PIN, BitNum
	rjmp m0
    
	ret 



