.include "tn2313adef.inc"

.device attiny2313a

.def	Temp=R16
.def 	Temp1=R17
.def 	Temp2=R18
.def	dt=R19
.def 	tim=R20
.def 	rtl=R21
.def 	rth=R22
.def 	bri=R23
.def 	scn=R24

.equ 	MOSI=0x00	;PortB 0 - данные
.equ 	SCK=0x01	;PortB 1 - такт
.equ 	RCK=0x02	;PortB 2 - защёлка

.cseg	;сегмент программ
.org 0	;начинаем с нулевого адреса

rjmp Reset            ;вектора прерываний
rjmp INT_0
rjmp INT_1
rjmp Timer1_capt1
rjmp Timer1_COMPA
rjmp Timer1_OVF1
rjmp Timer0_OVF0
rjmp UART_RX
rjmp UART_UDRE
rjmp UART_TX
rjmp ANA_COMP
rjmp PCINT ; Pin Change Interrupt
rjmp TIMER1_COMPB ; Timer1 Compare B Handler
rjmp TIMER0_COMPA ; Timer0 Compare A Handler
rjmp TIMER0_COMPB ; Timer0 Compare B Handler
rjmp USI_START ; USI Start Handler
rjmp USI_OVERFLOW ; USI Overflow Handler
rjmp EE_READY ; EEPROM Ready Handler
rjmp WDT_OVERFLOW ; Watchdog Overflow Handler


;Reset:
;INT_0:
;INT_1:
Timer1_capt1:
;Timer1_COMPA:
Timer1_OVF1:
;Timer0_OVF0:
UART_RX:
UART_UDRE:
UART_TX:
ANA_COMP:
PCINT: 
;TIMER1_COMPB:
TIMER0_COMPA:
TIMER0_COMPB:
USI_START:
USI_OVERFLOW:
EE_READY:
WDT_OVERFLOW:
reti

;ИННИЦИАЛИЗАЦИЯ
Reset:
	cli ;запрещаем прерывания

	ldi Temp, 0b00001111	;настройка портов
	out DDRB, Temp
	cbi PortB, 0x00
	cbi PortB, 0x01
	cbi PortB, 0x02
	sbi PortB, 0x03


	ldi Temp, 0b01000000
	out DDRD, Temp
	sbi PortD, 0x06

	ldi Temp, 0b00100101	;настраиваем спящий режим, прерывание по внешнему событию
	out MCUCR, Temp
	ldi Temp, 0b11000000	;разрешаем прерывание INT0, INT1
	out GIMSK, Temp

	ldi Temp, 0b00000000	;инициализируем таймер0, обычный режим, останавливаем счёт
	out TCCR0B, Temp
	ldi Temp, 0b01100010	;разрешаем прерываения переполнения t0 и компаратора A,B t1
	out TIMSK, Temp
	ldi Temp, 0x00			;интервал зажигания индикатора приёмника - 0,01 сек
	out OCR1BH, Temp
	ldi Temp, 0xB4
	out OCR1BL, Temp
	ldi Temp, 0b00000101	;запускаем таймер
	out TCCR1B, Temp

;	ldi Temp, 0b00000000	;настройка UART
;	out UCSRA, Temp
;	ldi Temp, 0b10011000
;	out UCSRB, Temp
;	ldi Temp, 0b00000110
;	out UCSRC, Temp
;	ldi Temp, 0x00	;скорость передачи
;	out UBRRH, Temp
;	ldi Temp, 0x09
;	out UBRRL, Temp

	ldi Temp, 0x62	; начальное i,j
	sts 0x60, Temp	;0x60 - индекс буфера, при отправке
	sts 0x61, Temp	;0x61 - индекс буфера при заполнении
	;0x62..0x69 - буфер, 8 байт
	ldi Temp, 0b00000000	;индекс приёма посылки, 0..3-индекс, 6-состояние пина, 7-h- указание полупериода
	sts 0x6A, Temp
	ldi Temp, 0x00 		;принятая посылка
	sts 0x6B, Temp	;команда (0..5)
	sts 0x6C, Temp	; (0..4 -адрес, 5 - toggle bit, 6..7 - стартовые биты)
	ldi Temp, 0b10000000
	sts 0x6D, Temp	; регистр повтора (0..5 - предыдущая команда;6 - предыдущий toggle bit,7 - флаг обнуления регистра/1-регистр обнулён, 0-в регистре данные/)
	ldi Temp, 0b00000000
	sts 0x6E, Temp 	; регистр повтора при удержании (0..3 - счётчик)
	ldi Temp, 0b11111111
	sts 0x6F, Temp 	; сохраняет значение яркости при отключении
	ldi	Temp, 0x23
	sts 0x70, Temp 	; частота стробоскопа L
	ldi Temp, 0x28
	sts 0x71, Temp 	; частота стробоскопа H
	;0x72 0x73 - передача значения компаратора
	;0x80 - хранит состояние SREG при возникновении прерывания

	ldi bri, 0x00 ;устанавлмвем значение при запуске
	rcall shift_reg
	ldi scn, 0x10 ;режим ожидания

			ldi tim, 0xE1	;;ОТЛАДКА!!
			rcall fifo_in

sei 	;глобально разрешаем прерывания

loop:
;зацикливаем контроллер
	sleep 	;если ничего не выполняем - усыпляем контроллер
;	nop
;	lds Temp2, 0x60
;	lds Temp1, 0x61
;	cp Temp2, Temp1		;проверяем есть ли байт на передачу
;	breq loop		;если есть - начинаем передачу
;	usart_tx:
;	sbis UCSRA,UDRE	;ждём готовности передатчика
;	rjmp usart_tx
;	ldi XH, 0x00
;	lds XL, 0x60
;	ld Temp2, X+
;	out UDR, Temp2	;если достигнута последняя ячейка буфера перемещаемся на первую
;	cpi XL, 0x6A
;	brne no_res_X
;	ldi XL, 0x62
;	no_res_X:
;	sts 0x60, XL


rjmp loop


;ПРИЁМ/ПЕРЕДАЧА по UART
;UART_RX:	;прерывание по принятию
;сохраняем состояние регистров
;in Temp, SREG
;sts 0x80, Temp
;	;обработка приёма данных UART
;	in dt, UDR
;		cpi dt, 0b10000000
;		brsh nval
;		mov bri, dt
;		lsl bri
;		rjmp ch_val
;	nval:
;		cpi dt, 0xA0
;		brne nval_1
;		ldi Temp, 0x02
;		sub bri, Temp
;		rjmp ch_val
;	nval_1:
;		cpi dt, 0xB0
;		brne nval_2
;		ldi Temp, 0x02
;		add bri, Temp
;		rjmp ch_val
;	nval_2:
;		rjmp no_do_uart
;	ch_val:
;	no_do_uart:
;		rcall shift_reg
;		mov tim, bri
;		rcall fifo_in
;
;восстанавливаем значение регистров
;lds Temp, 0x80
;out SREG, Temp	
;reti


;**РАБОТА С ДУ
INT_0: ;приём команды с ДУ
;сохраняем состояние регистров
;in Temp, SREG
;sts 0x80, Temp

	in tim, TCNT0	;передаём значение таймера
		
;		rcall fifo_in ;;ОТЛАДКА!!!

	ldi Temp, 0x00			;обнуляем таймер
	out TCNT0, Temp

	lds dt, 0x6A	;загружаем индекс приёма в dt, с ним будем работать по ходу прерывания

	in Temp, PinD	;
	bst Temp, 0x02	;загружаем состояние в Т
;	in Temp, PortB
;	bld Temp, 0x06
;	out PortD, Temp
	bld dt, 0x06 ;сохраняем состояние пина

	bst dt, 0x07	;сохраняем h в T

	cpi dt, 0b00000000	;определяем начало посылки
	brne no_vir
		;обработка первого импульса
		ldi dt, 0b10000001	;h=1, k=1

		ldi Temp, 0b00000100	;запускаем таймер
		out TCCR0B, Temp
		rjmp not_over
	no_vir:

	;проверяем длинну импульса
	cpi tim, 0x32	;нижняя гранца короткого импульса
	brlo error_reciv
	cpi	tim, 0x4F 	;верхняя граница короткого импульса
	brsh test_long
		;короткий импульс
;		mov tim, dt ;;ОТЛАДКА!!
;		rcall fifo_in
		brts sh_h1	;состояние h сейчас находится в Т, поэтому переходим через Т
			ori dt, 0b10000000
			rjmp test_over
		sh_h1:
			andi dt, 0b01111111
			rcall push_bit ;сохряняем принятый бит
		rjmp test_over
	test_long:
	cpi tim, 0x64
	brlo error_reciv
	cpi tim, 0x9C
	brsh error_reciv
		;длинный импульс
;		mov tim, dt ;;ОТЛАДКА!!
;		rcall fifo_in
			rcall push_bit ;сохряняем принятый бит
		rjmp test_over

	error_reciv:	;при обнаружении ошибки..
		ldi Temp, 0b10000000	;обнуляем регистра повтора
		sts 0x6D, Temp
		rcall reset_tx	;сбрасываем приём
		rjmp not_over
	test_over:
	cpi dt, 0b11001110		;если последний импульс - ноль
	brne zero_end
			andi dt, 0b00111111	;обнуляем h, PinD2
			rcall push_bit		;сохраняем последний бит - 0
			ori dt, 0b01000000 	;создаём условие конца посылки
	zero_end:
	
	cpi dt, 0b01001111		;определяем конец посылки
	brne not_over
		;конец посылки проверяем условия выполнения команды
;			mov tim, rth	;;ОТЛАДКА!!
;			rcall fifo_in
;			mov tim, rtl
;			rcall fifo_in

		mov Temp, rth	;проверка стартовых бит и адреса
		andi Temp, 0b11011111
		cpi Temp, 0b11000000
		brne skip_exec	;пропускаем если стартовых бит не обнаружено или адрес не соответсвует
				sbi PortD, 0x06	 ;зажигаем светодиод - индиктор принятой команды
				ldi Temp, 0b00000101	;запускаем таймер
				out TCCR1B, Temp
			mov tim, rth	;;ОТЛАДКА!!
			rcall fifo_in

			mov tim, rtl	;проверка изменения toggle bit, команды
			bst rth, 0x05
			bld tim, 0x06
					;rcall fifo_in ;;ОТЛАДКА!!
			lds Temp, 0x6D
			cp tim, Temp
			brne exec_com	;если бит или команда поменялись, значит выполняем команду, если нет - переходим к счётчику
					cpi rtl, 0x0C	;выпонлнять команду PWR без повтора
					breq skip_exec
					cpi rtl, 0x0E	;PP
					breq skip_exec
					cpi rtl, 0x3F 	;ESC
					breq skip_exec
				lds Temp, 0x6E	;проверяем счётчик повторов
				cpi Temp, 0b00000100
				breq exec_com_r	; если набралось достаточно - выпоняем команду
					inc Temp	;если нет - добавляем значение счётчика
					sts 0x6E, Temp
					rjmp skip_exec ;выходим
			exec_com:
			ldi Temp, 0x00	;обнуляем счётчик
			sts 0x6E, Temp
			sts 0x6D, tim	;сохраняем новое значение toggle bit и команды
			exec_com_r:
		;подпрограмма выполнения принятой команды

			rcall com_decode

		skip_exec:
		rcall reset_tx
	not_over:
	sts 0x6A, dt ;сохраняем индекс приёма

;восстанавливаем значение регистров
;lds Temp, 0x80
;out SREG, Temp	
reti

push_bit:	;сохранение бита dt6
	bst dt, 0x06	;состояние PinD2 в T
	mov Temp, dt		;загружаем в Temp значение счётчика
	;разбиваем приём в разные регистры (ячейки ОЗУ)
	andi Temp, 0b00001111
	cpi Temp, 0x09
	brsh k_8_13
		;приём 13..6 бит (сначала идут старшие биты)
		lsl rth
		bld rth, 0x00
		rjmp k_over
	k_8_13:
		;приём 5..0 бит (сначала идут старшие биты)
		lsl rtl
		bld rtl, 0x00
	k_over:
	inc dt
ret

reset_tx:	;сброс принятых данных, индекса, остановка таймера
	ldi rtl, 0x00			;сбрасываем принятые данные
	ldi rth, 0x00
	ldi dt, 0b00000000	;обнуляем индекс приёма

	ldi Temp, 0b00000000	;останавливаем таймер
	out TCCR0B, Temp
ret

com_decode:	;продпрограмма выполнения команды.
	sbrc scn, 0x07	;проверяем не идёт ли задержка после отключения
	rjmp no_do_dec		;если идёт - пропускаем выполнение
	
	cpi rtl, 0x0A
	brsh n_com1		;выбираем яркость в зависимости от цифры
		ldi ZL, Low(bri_sel_db*2)	;указываем начальный адрес таблицы
		ldi ZH, High(bri_sel_db*2)
		ldi Temp, 0x00
		add ZL, rtl			;сдвигаемся на ячейку соответствующую клавише
		adc ZH, Temp
		lpm bri, Z		;загружаем значение
		ldi scn, 0x10 	;переходим в режим ожидания
		rjmp out_dec
	n_com1:
	cpi rtl, 0x3C 	;/'экранчик'
	brne n_com2
		ldi scn, 0x04 	;устававливаем флаг сцены стробоскопа
		lds Temp, 0x71 	;загружаем частоту мерцания
		out OCR1AH, Temp
		lds Temp, 0x70
		out OCR1AL, Temp
		rjmp out_dec
	n_com2:
	cpi rtl, 0x29 	; >|<
	brne n_com3
		lds XH, 0x71	;загружаем текущее значение 
		lds XL, 0x70
		ldi YH, 0x01	;прибавляем 0,025 сек
		ldi YL, 0xC2
		sub XL, YL
		sbc XH, YH
		brcc set_strob 	;если дошло до переполнения 
			ldi XH, 0x00 	;ставим минимальное значение
			ldi XL, 0x01
			rjmp set_strob
	n_com3:
	cpi rtl, 0x2B 	; <|>
	brne n_com4
		lds XH, 0x71	;загружаем текущее значение 
		lds XL, 0x70
		ldi YH, 0x01	;прибавляем 0,025 сек
		ldi YL, 0xC2
		add XL, YL
		adc XH, YH
		brcc set_strob 	;если дошло до переполнения 
			ldi XH, 0xFF 	;ставим максимальное значение
			ldi XL, 0xFF
		set_strob: 		;устанавливем значение
			sts 0x71, XH 
			sts 0x70, XL
		rjmp out_dec
	n_com4:
	cpi rtl, 0x10	;V+
	breq up_bri
	cpi rtl, 0x11	;V-
	breq down_bri
	cpi rtl, 0x0C 	;PWR
	breq sw_pwr_m
	cpi rtl, 0x0E	;PP
	breq sw_pwr_s
	cpi rtl, 0x0F 	;M
	breq sc_min_bri

		rjmp no_do_dec
	out_dec:
	rcall shift_reg
	no_do_dec:
ret
	;выносим большие куски
	;/
	up_bri:	
		cpi bri, 0b11111110	;если достигнута максимальная яркость - ничего не далать
		brsh out_dec
		ldi Temp, 0x02	;увелививаем яркость
		add bri, Temp
		ldi scn, 0x10 	;переходим в режим ожидания
		rjmp out_dec
	down_bri:
		cpi bri, 0b00000010	;если достигнута минимальная яркость - ничего не делаем
		brlo out_dec
		ldi Temp, 0x02	;уменьшаем яркость
		sub bri, Temp
		ldi scn, 0x10 	;переходим в режим ожидания
		rjmp out_dec
	sw_pwr_m: ;плавное включение/отключение
		bst bri, 0x00 	;проверяем включена ли лампа
		brts l_off		;если включена - переходим к отключению
			ldi scn, 0x80 	;устанавливаем флаг задержки перед сценой включения
			ldi Temp, 0x05	;передаём значения компаратора для установки после задержки
			sts 0x73, Temp	;0,08 сек
			ldi Temp, 0xA0
			sts 0x72, Temp

			ldi Temp, 0x31 	;задержка перед повышением яркости - 0,7 сек
			out OCR1AH, Temp
			ldi Temp, 0x38
			out OCR1AL, Temp
			ldi bri, 0b00000001 	;включаем на минимальной яркости
			rjmp out_dec
		l_off:
			ldi scn, 0x01	;устанавливаем флаг сцены отключения
			ldi Temp, 0x02 	;такт - 0,04 сек
			out OCR1AH, Temp
			ldi Temp, 0xD0
			out OCR1AL, Temp
			sts 0x6F, bri	;сохраняем значение яркости для последующего включения
			rjmp out_dec
	sw_pwr_s: 	;медленное (~5мин со 100%) включение/отключение
		bst bri, 0x00 	;проверяем включена ли лампа
		brts s_off		;если включена - переходим к отключению
			ldi scn, 0x02 	;устанавливаем флаг сценария включения
			ldi Temp, 0xA5 	;такт - 2,35 сек
			out OCR1AH, Temp
			ldi Temp, 0x3C
			out OCR1AL, Temp
			ldi bri, 0b00000001 	;включаем на минимальной яркости
			rjmp out_dec
		s_off:
			ldi scn, 0x01	;устанавливаем флаг сцены отключения
			ldi Temp, 0xA5 	;такт - 2,35 сек
			out OCR1AH, Temp
			ldi Temp, 0x3C
			out OCR1AL, Temp
			sts 0x6F, bri	;сохраняем значение яркости для последующего включения
			rjmp out_dec
	sc_min_bri:
		bst bri, 0x00 	;проверяем включена ли лампа
		brtc out_dec		;если отключена - ничего не делаем
			ldi scn, 0x03	;иначе запускаем сценарий гашения
			ldi Temp, 0xE6 	;такт - 3,28 сек
			out OCR1AH, Temp
			ldi Temp, 0xA0
			out OCR1AL, Temp
			rjmp out_dec
	;\

Timer0_OVF0:
;сохраняем состояние регистров
;in Temp, SREG
;sts 0x80, Temp

;	sbi PortB, 0x07
	ldi tim, 0xFF	;;ОТЛАДКА!!
	rcall fifo_in

ldi Temp, 0b10000000	;обнуляем регистра повтора
sts 0x6D, Temp
rcall reset_tx	;сбрасываем приём
sts 0x6A, dt ;сохраняем индекс приёма

;восстанавливаем значение регистров
;lds Temp, 0x80
;out SREG, Temp	
reti




fifo_in:		;подпрограмма добавления в стек отправки по UART
	ldi YH, 0x00		;сохраняем значение в стек
	lds YL, 0x61
	st Y+, tim
	cpi YL, 0x6A		;если достигнута последняя ячейка буфера перемещаемся на первую
	brne no_res_Y
	ldi YL, 0x62
	no_res_Y:
	sts 0x61, YL
	lds Temp, 0x60		;проверяем переполнение стека
	cp YL, Temp
	brne no_ovr
	nop		;обработка переполнения стека
	no_ovr:
ret


shift_reg:	;обновление регистра
	ldi tim, 8
	mov Temp, bri
	spi_loop:
		lsl Temp	;сдвигаем влево
		brcc set_0	;если бит=0 устанавливаем 0
		sbi PortB, MOSI	;иначе ставим 1
		rjmp takt
	set_0:
		cbi PortB, MOSI
	takt:
		sbi PortB, SCK	;подаём тактовый импульс
		cbi PortB, SCK
		dec tim			;если передали последний бит - 
		brne spi_loop
		sbi PortB, RCK	;защёлка
		cbi PortB, RCK
ret


Timer1_COMPA:
;сохраняем состояние регистров
;in Temp, SREG
;sts 0x80, Temp
	ldi Temp, 0x00		;обнуляем таймер
	out TCNT1H, Temp
	out TCNT1L, Temp
	sbi PortD, 0x06 	;зажигаем светодиод для индикации хода сценария
	mov dt, scn 	;убираем ненужные для проверки биты
	cbr dt, 0b01110000
	cpi dt, 0x01 ;сцена отключения
	brne scn1
		cpi bri, 0b00000001 	;проверяем пороговое значение
		breq t_off		;если достигнуто - отключаем
			ldi Temp, 0x02	;иначе - уменьшаем яркость
			sub bri, Temp
			rjmp q_scn
		t_off:
;			ldi tim, 0x02	;;ОТЛАДКА!!
;			rcall fifo_in

			ldi bri, 0b00000000		;отключаем
			ldi scn, 0x80 	;делаем задержку перед повторным включением
			ldi Temp, 0xD2 	;такт - 3,00 сек
			out OCR1AH, Temp
			ldi Temp, 0xF0
			out OCR1AL, Temp
			rjmp q_scn

	scn1:
	cpi dt, 0x02 	;сцена включения
	brne scn2
		lds Temp, 0x6F	;загружаем пороговое значение
		cp bri, Temp	;если достигнуто - завершаем сцену
		brlo sc_up_bri 	;иначе - повышаем яркость
;			ldi tim, 0x01	;;ОТЛАДКА!!
;			rcall fifo_in
			bst scn, 0x06 	;если после включения кнопку не отпускали - не отменять отключение
			brts sc_hold
			sbr scn, 0b00100000 	;ставим флаг отмены отключения
			rjmp stop_scn
		sc_up_bri:
;			ldi tim, 0x01	;;ОТЛАДКА!!
;			rcall fifo_in

			ldi Temp, 0x02	;увелививаем яркость
			add bri, Temp
			rjmp q_scn
	scn2:
	cpi dt, 0x03 	;сцена плавного гашения (без отключения)
	brne scn3
		cpi bri, 0b00000001 	;проверяем пороговое значение
		breq sc_mbri 	; если достигнуто - переходим в режим ожидания
			ldi Temp, 0x02	;иначе - уменьшаем яркость
			sub bri, Temp
			rjmp q_scn
		sc_mbri:
			sbr scn, 0b00100000 	;ставим флаг отмены отключения
			rjmp stop_scn
	scn3:
	cpi dt, 0x04 	;стробоскоп
	brne scn4
		cpi bri, 0b11111111 ; проверяем включена ли лампа
		breq strob_down	; если включена - выключаем
			ldi bri, 0b11111111 	;иначе включем
			ldi Temp, 0x07 	;задержка - 0,1 сек
			out OCR1AH, Temp
			ldi Temp, 0x08
			out OCR1AL, Temp
			rjmp q_scn
		strob_down:
			ldi bri, 0b00000001 ; гасим
			lds Temp, 0x71 	;загружаем частоту мерцания
			out OCR1AH, Temp
			lds Temp, 0x70
			out OCR1AL, Temp
			rjmp q_scn
	scn4:
;	cpi dt, 0x05 	;инверсный стробоскоп (резерв)
;	brne scn5
;		nop
;	scn5:
	cpi dt, 0x06 	;задержка перед гашением
	brne scn6
		ldi scn, 0x03	;запускаем сценарий гашения
		ldi Temp, 0x07 	;такт - 0,1 сек
		out OCR1AH, Temp
		ldi Temp, 0x08
		out OCR1AL, Temp
		rjmp q_scn
	scn6:
	cpi dt, 0x80 	;задержка перед повышением яркости
	brne scn5
		sbrs bri, 0x00 	;если включена - продолжаем сцену включения
		rjmp sc_hold 	;иначе - 
			sbr scn, 0x02 	;устанавливаем флаг сценария включения
			cbr scn, 0x80 	;снимаем флаг задержки
			lds Temp, 0x73 	;загружаем переданное значение компаратора
			out OCR1AH, Temp
			lds Temp, 0x72
			out OCR1AL, Temp
			rjmp q_scn
		sc_hold:
		ldi scn, 0x10
		rjmp q_scn
	scn5:
		;если нет выполняемых сцен - 
		;rjmp no_scn
	stop_scn:

		sbr scn, 0x10 	;ставим флаг режима ожидания
		rjmp no_scn
	q_scn:
	rcall shift_reg
	no_scn:
;восстанавливаем значение регистров
;lds Temp, 0x80
;out SREG, Temp	
reti


TIMER1_COMPB:
;сохраняем состояние регистров
;in Temp, SREG
;sts 0x80, Temp
;			ldi tim, 0x9E	;;ОТЛАДКА!!
;			rcall fifo_in

	cbi PortD, 0x06	;гасим светодиод

	bst scn, 0x04	;если находимся в режиме ожидания - 
	brtc cont_tim
;		ldi scn, 0x10
		ldi Temp, 0x00		;обнуляем таймер
		out TCNT1H, Temp
		out TCNT1L, Temp

		ldi Temp, 0b00000000	;останавливаем таймер
		out TCCR1B, Temp
	cont_tim:
;восстанавливаем значение регистров
;lds Temp, 0x80
;out SREG, Temp	
reti


INT_1: 		;ВЫКЛЮЧАТЕЛЬ
;сохраняем состояние регистров
;in Temp, SREG
;sts 0x80, Temp
 			mov tim, scn	;;ОТЛАДКА!!
			rcall fifo_in
	sbrc scn, 0x07	;проверяем не идёт ли задержка
	rjmp no_do_sw	;если идёт - пропускаем выполнение
		cpi scn, 0x02	;идёт сцена включения?
		brne sw_sc_on 	;если нет - переходим дальше, иначе..
			ldi scn, 0x10 	;включаем режим ожидания
			rjmp no_do_sw
		sw_sc_on:
		sbis PinD, 0x03 	;если клавиша отпущена - ..
		rjmp sw_ton 	;иначе - переходим
			cpi scn, 0x03 	;..если идёт сцена гащения - ..
			brne sw_sc_mbri 	;иначе переходим
				ldi scn, 0x10 	;..включаем режим ожидания
				rjmp no_do_sw
			sw_sc_mbri:
				bst bri, 0x00 	;проверяем включена ли лампа
				brtc no_do_sw 	;если отключена - пропускаем установку отключения
				bst scn, 0x05 	;проверяем флаг отмены отключения
				brts sw_set_wait 	;если есть - переходим в режим ожидания
				ldi scn, 0x01	;устанавливаем флаг сцены отключения
				ldi Temp, 0x02 	;такт - 0,04 сек
				out OCR1AH, Temp
				ldi Temp, 0xD0
				out OCR1AL, Temp
				rjmp no_do_sw
			
			sw_set_wait:
				ldi scn, 0x10 	;ставим флаг режима ожидания
				rjmp no_do_sw	
		sw_ton:
		bst bri, 0x00 	;проверяем включена ли лампа
		brts sw_is_ton 	;если включена - переходим, иначе.. включаем с задержкой
			ldi scn, 0x80 	;устанавливаем флаг задержки перед сценой включения
			ldi Temp, 0x05	;передаём значения компаратора для установки после задержки
			sts 0x73, Temp	;0,08 сек
			ldi Temp, 0xA0
			sts 0x72, Temp

			ldi Temp, 0x31 	;задержка перед повышением яркости - 0,7 сек
			out OCR1AH, Temp
			ldi Temp, 0x38
			out OCR1AL, Temp
			ldi bri, 0b00000001 	;включаем на минимальной яркости

			ldi Temp, 0b11111111 	;до максимальной яркости
			sts 0x6F, Temp 

			sbr scn, 0b01000000 	;ставим флаг включения (для совместимомти с обычным выключаетелем)
			rjmp q_sw
		sw_is_ton:
		bst scn, 0x04 	;если находимся в режиме ожидания - ..
		brtc sw_no_hold 	;иначе переходим 
			ldi scn, 0x06 	;запускаем гашение с прдварительной задержкой
			ldi Temp, 0x23 	;задержка перед гашением - 0,5 сек
			out OCR1AH, Temp
			ldi Temp, 0x28
			out OCR1AL, Temp
			rjmp no_do_sw
		sw_no_hold:
		cpi scn, 0x01 	;если идет сцена отключения
		brne sw_no_sc_off
			ldi scn, 0x02	;устанавливаем флаг сцены включения
			ldi Temp, 0x07 	;такт - 0,1 сек
			out OCR1AH, Temp
			ldi Temp, 0x08
			out OCR1AL, Temp
			ldi Temp, 0b11111111 ;поднимаем вплоть до максимума
			sts 0x6F, Temp 
			rjmp no_do_sw
		sw_no_sc_off:
			rjmp sw_sc_mbri 	;переходим к установке сцены отключения
	q_sw:
		rcall shift_reg 	;обновляем состояние
	no_do_sw:
		sbi PortD, 0x06	 ;зажигаем светодиод - индиктор принятой команды
		ldi Temp, 0b00000101	;запускаем таймер
		out TCCR1B, Temp
 			mov tim, scn	;;ОТЛАДКА!!
			rcall fifo_in

;восстанавливаем значение регистров
;lds Temp, 0x80
;out SREG, Temp	
reti

bri_sel_db:
.db 	0xFF, 0x01 ;0,1
.db 	0x11, 0x19 ;2,3
.db 	0x29, 0x3D ;4,5
.db 	0x51, 0x65 ;6,7
.db 	0x8D, 0xB5 ;8,9
