; Author : Гринев Сергей (for_dgf@mail.ru)
.include "C:\ProgramData\SetUpCtrl\AVRProg\m328pdef.inc"
;****************************************************	Карта входов и выходов
; Порт B							
; PB0(icp)		in	!Свободен
; PB1(osc1)		in	!Свободен
; PB2(ss)		in	!Свободен
; PB3(mosi)		in	!Цифровой вход (Функция желтая перемычка)
; PB4(miso)		in	!Цифровой вход 
; PB5(sck)		out	!Вспомогательный светодиод на Ардуино
;*******************************************************************************
; Порт D 
; PD0(rxd)			!UART обмен  
; PD1(txd)			!UART обмен  
; PD2(int0)		in	!Вход датчика DH1	
; PD3(int1)		in	!Вход датчика DH2 
; PD4(t0)		in	!Свободен
; PD5(t1)		in	!Соединить с PD6 
; PD6(ain0)		out	!Соединить с PD5 
; PD7(ain1)		in	!Свободен
;*******************************************************************************
; Порт C	
; PC0(adc0)		out	!Сигнал зажигания выход
; PC1(adc1)		in	!Свободен
; PC2(adc2)		in	!Свободен
; PC3(adc3)		in	!Свободен
; PC4(adc4/scl)		in	!Канал АЦП выбора таблицы или Канал АЦП корректора
; PC5(adc5/sda)		in	!Канал АЦП выбора таблицы или Канал АЦП корректора
;     adc6		in	!Канал АЦП выбора таблицы или Канал АЦП корректора
;     adc7		in	!Канал АЦП выбора таблицы или Канал АЦП корректора
;!!Настройка параметров Ядра
;********************************  ПОЛНЫЙ НАБОР ПАРАМЕТРОВ ПО УМОЛЧАНИЮ (копировать отсюда по необходимости)
;#define _EngineInfo 		"Нет информации"	
;#define _Base			360		;Угол-база в градусах 			
;#define _Delta		30			;Угловой размер метки Delta
;#define _Beta		0			;Угловое расстояние от ВМТ до метки Delta
;#define _UOZMax 	_Beta +_Delta-1.5	;Максимальный угол опережения зажигания	
;#define _UOZMin 		_Beta		;Минимальный угол опережения зажигания	
;#define _Alfa			0.5             ;Угловое расстояние отключения сигнала зажигания 
;#define _Fn			8		;Частота тактовых импульсов, поступающих на таймер Т1
;#define _InternalClk				;Включить тактирование измерительного таймера от внутреннего делителя 2МГц. 
						;Команда _Fn при этом игнорируется. Параметр Fn становится равным 3. 
						;Освобождаются линии PD5(t1),PD6(ain0) и таймер T0(8 разрядов) и/или аналоговый компаратор.
						;Таймер может быть использован для формирования 2 ШИМ сигналов с одной частотой повторения 61, 244, 977, 7813 или 62500 Гц.
						;Как вариант с частотой импульсов, подаваемых на линию PD4 делённой на 256.
;#define _IntCompareA          CompareAProg	;*Вектор прерывания события равенства таймера канал А
;#define _IntCompareB          CompareBProg	;*Вектор прерывания события равенства таймера канал В
;#define _Overflow             OverflowProg	;*Вектор прерывания события переполнения таймера
;#define _IntAC                ACProg		;*Вектор прерывания от компаратора
			 			;Формат программы обработки прерывания
						;XXXProg:pushSREG
						;        do something
						;	 popSREG
						;	 reti
;#define _ProtectClk  		6		;Интервал дискретизации протокола защиты от пульсаций  в мкс
;#define _ProtectCount		2		;Количество повторных чтений протоколом защиты с интервалом 
						;ProtectClk после первого изменения линии датчика	
;#define _StopTime		1.5		;Время детектирования режима СТОП (отключение выходных линий при неизменных в течении этого времени входных линиях) 
;#define _CheckMaxRpm   10000			;Включить постоянную проверку на обороты выше предельных (10000)
						;Пропуск зажигания следует организовывать с помощью макроса SkipOnMaxRpm 
;#define _ADCBufferSize	8			;Длина кольцевых буферов каналов АЦП (2, 4, 8, 16, 32)
;#define _3734Enable				;Режим работы с коммутатором XX.37.34 (скважность сигнала управления 3)
						;В случае его включения следует указать _Alfa=Base/3 - !!работаю над автоматизацией
;#define _DoAverage				;Усреднение по двум отсчетам оценки скорости вращения
;#define _DoNotCoreLEDCtrl			;Отключено управление светодиодом в Ядре
;#define _DoInputPullUp	     			;Подключать подтягивающие резисторы на входах (по умолчанию выкл.)	
	                                        ;При отключении подтяжки ине выключенной функции Желтая перемычка
			 			;возможны ложные срабатывания без внешнего доп. резистора на линии PINB.3
;#define _YellowJumper				;Включить функцию "Желтая перемычка"
;#define _HalfDuplexTimeOut   5.5              	;*Включить режим поддержки полудуплекса со времением таймаута в мс      
						;По умолчанию FullDuplex без задержки
						;В режиме непрерывной трансляции то этот параметр игнорируется
;#define _AlwaysTransmite			;*Включить режим непрерывной трансляции группы параметров
                                                ;в формате [0x55,0xAA,0x55,Cnt,N1,N0,N,MDelta,UOZCurrent,TableCtrl.ADC,Manual.ADC,MAP.ADC,PCorr2,PCorr1,PCorr0]
						;на каждом обороте двигателя и при его остановке. Cnt - инкриментируется на каждом обороте.
						;Если соседние пакеты не имеют соседние номера, имеет факт пропуска пакета. 
						;В нормальном режиме пакеты идут подряд (оборот за оборотом)
						;Это не ошибка, а в большей части предупреждение.
;#define _ATBaudRate    115200         		;*Скорость передачи в режиме непрерывной трансляции параметров (программа UOZ не работает) (по умолчанию 115200)
						;Варианты - 9600, 19200, 38400, 57600, 115200. Иные значения меняются на 9600
;#define _UOZBaudRate   9600 			;Скорость передачи UART при работе с UOZ (по умолчанию 9600)
						;Варианты - 9600, 19200, 38400, 57600, 115200. Иные значения меняются на 9600
;Дескриптор переключателя таблиц (_TableCtrl) по умолчанию 
;#define _TableCtrl.ADC  	 0              ;Номер канала АЦП переключателя таблиц 4..7 или виртуальные 1..3 (следует использовать макрос SetADC)
;#define _TableCtrl.DoInvert  	 не задана      ;Инверсия кода АЦП канала _TableCtrl.ADC код = (255-код)
;#define _TableCtrl.TblCount    1
;#define _TableCtrl.DefaultTbl  TblCount	;Номер активной таблицы в случае отключенного канала АЦП _TableCtrl.ADC или всего АЦП в целом
;#define _TableCtrl.CurveAddress не задан	;Адрес таблицы произвольной зависимости номера таблицы от напряжения на входе АЦП
;Дескриптор корректора УОЗ (_Manual) по умолчанию 
;#define _Manual.ADC  	  0			;Номер канала АЦП корректора УОЗ 1..7
;#define _Manual.DoInvert       не задана	;Инверсия кода АЦП канала _Manual.ADC код = (255-код)
;#define _Manual.UOZ1    0.0			;Добавочный УОЗ при минимальном напряжении на АЦП
;#define _Manual.UOZ2    0.0			;Добавочный УОЗ при максимальном напряжении на АЦП. 
;#define _Manual.ScaleAddress	не задан	;Адрес таблицы глубины регулировок (%) от оборотов
;#define _Manual.CurveAddress	не задан	;Адрес таблицы произвольной зависимости корректора от АЦП
;Дескриптор корректора УОЗ (_MAP) по умолчанию 
;#define _MAP.ADC  	  0                     ;Номер канала АЦП ДАД  1..7
;#define _MAP.DoInvert          не задана	;Инверсия кода АЦП канала _MAP.ADC код = (255-код)
;#define _MAP.UOZ1       0.0			;Добавочный УОЗ при минимальном напряжении на АЦП
;#define _MAP.UOZ2       0.0			;Добавочный УОЗ при максимальном напряжении на АЦП
;#define _MAP.ScaleAddress      не задан	;Адрес таблицы глубины регулировок (%) от оборотов
;#define _MAP.CurveAddress      не задан	;Адрес таблицы произвольной зависимости УОЗ от АЦП канала _MAP.ADC 
;Дескриптор корректора нагрузки по умолчанию 
;Корректор нагрузки образует виртуальный АЦП, с которым следует связать канал корректоры УОЗ таблиц (_Manual или _MAP)
;#define _Load.ADC  	   0			;Номер канала АЦП для вывода 1..3
;#define _Load.BufferSize  32			;Длина кольцевого буфера корректора нагрузки (2, 4, 8, 16, 32, 64, 128, 256)
;
;Обработка входных линий производится путем сравнения регистра событий Events с заранее известным кодом.
;Events - состояние входных линий в четыре момента времени [DH2(n-3),DH2(n-2),DH2(n-1),DH2,DH1(n-3),DH1(n-2),DH1(n-1),DH1]
;Важно. Каждый момент времени соотвествует изменениям на любой из линий.Сравнение происходит в Ядре. 
;В нем также предопределены 4 программы обработки моментов совпадения _EventQ (Q=0..3)
;В моторной части следует задать код события командой:
;#define _EventQ  Код события 
;и программу обработки 
;EventQ:                                      
;       do something
;	ret
;Вызов этой подпрограммы произойдет при равенстве регистра событий с заданным кодом события
;В общем случае коды событий могут быть получены визуально с использованием утилиты EventMaker
;
;В случае, если какая то линия входная не нужна, то её можно отключить командой
;#define _DHNDisable   N=1..2. При этом значения уровня этой входной линии в регистре событий будет равно 0.
;При определении Кода событий это надо учитывать.
;
;Для обработки сложных сигналов предусмотрен режим общего маскирования c помощью команды
;#define _EventMaskQ	Код маски
;В этом случае перед сравнением Ядро выполнит маскрование "Кодом маски" и регистра Events и кода, заданного командой #define _EventN
;Этот режим позволяет не учитывать произвольный набор моментов времени в регистре событий, 
;например в случае неоднозначности.
;
;Для самых простых случаев предусмотрен упрошенный режим, который включается командой:
;#define _EventEasyMaskMode	
;Для каждого не отключенного входного канала определены константы (Q=1,2)
;DHQHigh  - высокий уровень линии
;DHQLow   - низкий уровень линии
;DHQUp    - фронт
;DHQDown  - спад
;
;Пример
;#define _EventEasyMaskMode	
;#define _Event1  DH1UP+DH2Low
;.
;.
;Event1: Подпрограмма "сработает" при условии возникновения фронта импульса на первом канале, и низком уровне на втором.                                     
;       do something
;	ret
;********************************  СОКРАЩЕННЫЙ НАБОР ПАРАМЕТРОВ 
;
;
;
;Параметры до удлинения 
;#define _Delta		18.0				;Угловой размер метки Delta 
;#define _Beta		14.0				;Угловое расстояние от ВМТ до метки Delta
;_Delta+_Beta = 32
;Хотим на 10 градусов расширить метку в сторону ВМТ
;_Beta = _Beta-10
;_Delta = _Delta+10
;_Delta+_Beta = 32
;
;
#define _EngineInfo	"1Ц.4Т.ИД - штатный датчик. Удлинение метки "

#define _Delta		20.0				;Угловой размер метки Delta
#define _Beta		5.0				;Угловое расстояние от ВМТ до метки Delta
#define _Fn		18				;Частота тактовых импульсов, поступающих на таймер Т1
#define _DoAverage					;Усреднение по двум отсчетам оценки скорости вращения

#define _DoInputPullUp					;Подключать подтягивающие резисторы на входах (по умолчанию выкл.)


#define _RealDelta	14.0				;!!!Настоящая длина метки устройства  25-11=14
#define _ServiceB	VirtualDeltaEnd 		;Определено событие VirtualDeltaEnd = _ServiceB
#define _EventMask0	0b00110011			;Определена маска регистра событий для _Event0
#define _Event0		0b00110010			;Определена реакция на код начала метки Delta на цилиндре
#define _EventMask1	0b00111000			;Определена маска регистра событий для _Event1
#define _Event1		0b00101000			;!!!Определена реакция на код завершения АППРАТАНОЙ метки на цилиндре
.include "C:\ProgramData\SetUpCtrl\AVRProg\core.inc"
.Dseg
.org EndCoreDseg

.CSEG
.org EndCoreCSeg

.equ	CmdLineBit	= 0				;Номер бита сигнала управления 

reset:  sbi	DDRC,CmdLineBit				;Назначение линии PC0(adc0) контролера для работы на выход
	cbi	PORTC,CmdLineBit			;Деактивировать выходную линию
	SetCoreSetup 0b00000100
	SetOptions LED,1				;Установка режима работы светодиода
	ret

Event0:	StartDelta                                      ;Макрос отметки времени (начало виртуального импульса Delta)
	ret

Event1: lds	MDeltaL,TCNT1L	                        ;Конец аппаратной метки, а виртуальная метка Delta идет дальше..
	lds	MDeltaH,TCNT1H 
	sbic	TIFR1,0					;Если есть переполнение таймера, то ограничение измеренной величины
	mov	MDeltaL,full
	sbic	TIFR1,0					
	mov	MDeltaH,full
	push	r0					;!!Вычисление времени завершения виртуального импульса DELTA
	push	r1      
	ldi	temp,int(2*(_Delta/_RealDelta-1)*256+1)>>1
	mul	temp,MDeltaH
	movw	XH:XL,r1:r0
	mul	temp,MDeltaL
	add	XL,r1
	adc	XH,zerro   
	add	XL,MDeltaL
	adc	XH,MDeltaH
	subiw	X,int(2*(ProtectCount*ProtectClk+6)*8/(1+Fn)+1)>>1
	sts	OCR1BH,XH				;!!Программирование времени события ServiceB
	sts	OCR1BL,XL
	pop	r1
	pop	r0
      	ret

VirtualDeltaEnd:
	SkipOnMaxRpm					;Завершение виртуального импульса Delta
	sbi	PORTC,CmdLineBit			;Включить сигнал зажигания принудительно на конце метки DELTA
	StopDelta                                       ;Макрос отметки времени (окончание виртуального импульса Delta)
	ret						;Возврат в вызывающую программу

Service:cbi	PORTC,CmdLineBit			;Отключить сигнал зажигания принудительно в начале виртуального импульса Delta
	ret        					;Возврат в вызывающую программу

Ignition:
	SkipOnMaxRpm	
	sbi	PORTC,CmdLineBit			;Включить сигнал зажигания 
	ret						;Возврат в вызывающую программу

;****************************************************** Заполнение базовых таблиц из разметочной таблицы
Index:
	.dw	0x10F2,0xC152,0x0000,0x1245,0xDFAC,0x0000,0x136A,0xC698,0x0000,0x14B4,0xAD60,0x0000,0x162E,0xE6C3,0x0000,0x174A,0xAC57,0x0001,0x17E3,0x9C2D,0x0001,0x1882,0x83C9,0x0001
	.dw	0x192B,0x6E1F,0x0001,0x19DE,0x5AC0,0x0001,0x1A9B,0x47AE,0x0001,0x1B63,0x33AE,0x0001,0x1C38,0x25E2,0x0001,0x1D17,0x1111,0x0001,0x1E07,0x0000,0x0001,0x1F07,0xF00F,0x0000
	.dw	0x2018,0xDFAC,0x0000,0x213D,0xD00D,0x0000,0x2278,0xC3A1,0x0000,0x23C7,0xB30F,0x0000,0x2535,0xA57F,0x0000,0x26C1,0x9869,0x0000,0x286F,0x8B70,0x0000,0x2A45,0x7F80,0x0000
	.dw	0x2C47,0x73FE,0x0000,0x2E7C,0x6A0C,0x0000,0x30E6,0x5E92,0x0000,0x339B,0x5490,0x0000,0x36A2,0x4B3E,0x0000,0x3A09,0x0475,0x0000,0x737E,0x01D2,0x0000,0xFFFF,0x0000,0x0000
	.db	0x13,0x13,0x13,0x13,0x13,0x14,0x16,0x17,0x18,0x1A,0x1B,0x1C,0x1E,0x1F,0x20,0x23,0x27,0x2C,0x34,0x3E,0x48,0x54,0x60,0x6F,0x7F,0x90,0xAA,0xC3,0xCC,0xD4,0xDD,0xE5
