; Author : Гринев Сергей (for_dgf@mail.ru)
.include "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)		out	!Сигнал управления током симистора
; 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	VersionName "1Ц.4T.ДИ - Один импульс"		;Одноцилиндровый двигатель cо штатным индуктивным датчиком
							;Эмуляция второго датчика
#define _Betta 		12.0				;Угловое расстояние от ВМТ до метки Delta. 
#define	_Delta		18.0				;Угловой размер метка Delta
#define	_UOZMax		30.0				;Максимальный угол опережения зажигания (=<LBetta+LDelta-2.5)
#define	_UOZMin		_Betta				;Минимальный угол опережения зажигания (>=LBetta)
#define	_Alfa		15.0				;Угловое расстояние отключения сигнала зажигания после метки Delta
#define	_StopTime	2.0				;Время (сек) детектирования режима СТОП
#define	_Manual		0.0				;Угловая апертура ручного корректора УОЗ на +/- (не более половины Delta)
							;Ручной корректор отключается при ADCCanCorSelectr = 0. 
							;Середина кода АЦП соотвествует сдвигу 0 градусов
#define	_Load		0.0                             ;Угловая апертура корректора нагрузки в "-" (не более Delta)

.equ	Base		= 360				;Угол-база в градусах 
.equ	Fn		= 18				;Частота тактовых импульсов, поступающих на таймер Т1

.equ	TblCount	= 1				;Количество таблиц УОЗ  2N (N=1, 2, 4, 8, 16, 32). Номер активной таблицы 
							;переключается напряжением на входе канала АЦП ADCCanTblSelectr. 
							;При ADCCanTblSelectr = 0 номер таблицы выбирается  максимальным из доступных.
.equ	ADCBufferSize	= 8 				;Длина кольцевых буферов каналов АЦП (2, 4, 8, 16, 32)
.equ	LoadBufferSize	= 32 				;Длина кольцевого буфера корректора нагрузки (32, 64, 128)

.equ	ADCCanTblSelectr= 0				;Номер канала мультиплексора датчика ДАД/ДПЗД (выбор активной таблицы)
.equ	ADCCanCorSelectr= 0				;Номер канала мультиплексора ручного корректора УОЗ
.equ	ADCCanA		= 0                             ;Номер канала A пользователя. ADCCanA =0 – канал отключен.
.equ	ADCCanB		= 0                             ;Номер канала Б пользователя.  ADCCanB =0 – канал отключен.

.equ	ProtectClk	= 6				;Интервал дискретизации протокола защиты от пульсаций  в мкс
.equ	ProtectCount 	= 2				;Количество повторных чтений протоколом защиты с интервалом ProtectClk после первого 
							;изменения линии датчика. Значение может быть в пределах 1-7.
.equ	CmdLineBit	= 3				;Номер бита сигнала управления 
.equ	TriacLineBit	= 4                             ;Номер бита сигнала управления током симистора
.equ	StartDeltaCode	= 0b00001010			;Код начала метки Delta на цилиндре

.include "core.inc"					;Подключение Ядра (сегмент кода, сегмент данных)          

.dseg
.org EndCoreDseg

.equ	DeltaVitual	= int(_Delta/(Base-_Delta)*65536+0.5)		

.CSEG

.org EndCoreCSeg

reset:	sbi	DDRC,CmdLineBit				;Назначение линии PC0(adc0) контролера для работы на выход
	cbi	PORTC,CmdLineBit			;Деактивировать выходную линию
	sbi	DDRD,TriacLineBit                       ;Назначение линии PD4(t0) контролера для работы на выход
	sbi	PORTD,TriacLineBit			;Включить ток тиристора
	SetLEDCtrl  1       				;Светодиод на Arduino отражает состояние основного входного датчика
;0 - Выключен
;1 - Delta
;2 - CPU D2(PD2)
;3 - CPU D3(PD3)
;4 - CPU A3(PC3)
;5 - CPU A2(PC2)
;6 - CPU A1(PC1)
;7 - CPU A0(PC0)
;8 - Остановка
;9 - Низкие обороты
;10- УОЗ макс.
;11- УОЗ мин.
;12- Флаг  Ign1
;13- Флаг  Ign2
;14- UARTCtrl
;15- Включен
	load	A,CoreSetup				;Начальное значение 0b000000X0 (Все включено),
							;где X=ADCDisableBit устанавливает Сore при анализе параметров 
;___________________76543210				;ADCCanTblSelectr, ADCCanCorSelectr, ADCCanA, ADCCanB
	ori	A,0b10101100				;Настройка параметров Ядра
 	store	CoreSetup,A
;7 Отключен датчик DH2 
;6 Отключено усреднение по двум отсчетам Т1
;5 Отключен вызов события ServiceA 			
;4 Отключен вызов события ServiceB 			
;3 Отключен корректор для коммутатора ХХ.37.34
;2 Отключен корректор нагрузки
;1 Отключен АЦП
;0 Отключен UART
	ret						;Возврат в вызывающую программу

;Общее функционирование:

;"Глухой" цикл: 
;		Усреднение буферов АЦП.
;		Расчет добавки к УОЗ от ручного корректора (данные АЦП).
;		Расчет добавки к УОЗ от корректора нагрузки (рассчетные данные).
;		Переключение таблиц УОЗ (данные АЦП).		
;		Обслуживание UART в части выполнения команд от программы UOZ.exe 
;		Вызов события loop.
;		Обслуживание АЦП в режиме останова двигателя 
;"Глухой" цикл временно прерывается событиями в системе:

;- Завершение приема в буфер очередной команды по UART от программы UOZ.exe.

;- Прерывания от механизма контрольного чтения входных линий датчика. 
;  Начинаются после физического изменения уровня входных датчиков и повторяются заданное количество ProtectCount раз 
;  или вплоть до подтвреждение изменений c периодом ProtectClk (мкс). 

;1. Actions - Любое подтвержденное изменение сигнала датчика. В случае совпадения кодовой последовательности
;   значений уровня датчика в данный и 3 предыдущих моментах времени с цепочкой StartDeltaCode - запуск события 2.

;2. Начало DELTA (_Betta+_Delta {28 грд.}): Вычисления, АЦП (чтение), программирование событий 3 и 4,  

;3. Зажигание в цилиндре по событиям Ignition или UOZMinError (_Betta+_Delta..._Betta {28...10 грд.}).
;!![cобытие Ignition происходит при равенстве таймера OCR1А внутри виртуального импульса Delta]
;!![cобытие UOZMinError происходит в случае не возможности установки заданного угла]

;4. ServiceB - Завершение DELTA (_Betta {~ 10грд.}): АЦП (запуск), вычисление события 5, контрольная активации линии зажигания.
;!![cобытие ServiceB происходит при равенстве таймера OCR1B внутри виртуального импульса Delta]

;5. Service - (_Betta-_Alfa {~5 грд.}): Выключение сигнала зажигания, досрочное выполнение события 6 или его программирование.
;!![cобытие Service происходит при равенстве таймера OCR1B вне виртуального импульса Delta - измерительный интервал]

;Основная программа (вызывается Ядром постоянно)
loop:	ret                                             ;Возврат в вызывающую программу

Actions:
	cpi	Events,StartDeltaCode			;Сравнение регистра Событий с признаком начала метки на DH1
	brne	C_exit					;Если не равны, то проверка следующего кода
	sbrc	Selectr,7 				;Если обороты выше табличных то сразу зажигание
	sbi	PORTC,CmdLineBit	
	StartDelta                                      ;Макрос отметки времени (начало виртуального импульса Delta)
							;!!Программирование времени события Ignition							
	sbrc	Selectr,7				;Если обороты выше табличных то угол максимален
	sts	UOZCurrent,zerro
	sbrc	Selectr,7                               ;Если обороты выше табличных то угол максимален
	sts	UOZCurrent+1,zerro
	push	r0					;!!Вычисление времени завершения виртуального импульса LDELTA
	push	r1                                      ;По факту этого произойдет событие ServiceB
	ldi	temp,High(DeltaVitual)			
	mul	temp,NH	
	movw	ZH:ZL,r1:r0
	mul	temp,NL
	add	ZL,r1
	adc	ZH,zerro
	ldi	temp,Low(DeltaVitual)
	mul	temp,NH
	add	ZL,r1
	adc	ZH,zerro
	store	OCR1BH,ZH				;!!Программирование времени события ServiceB
	store	OCR1BL,ZL
	pop	r1
	pop	r0
C_exit:	ret        					;Возврат в вызывающую программу


ServiceA:
	ret						;Возврат в вызывающую программу
					
UOZMinError:
Ignition:	
	sbi	PORTC,CmdLineBit			;Включить сигнал зажигания принудительно на конце метки DELTA
	ret						;Возврат в вызывающую программу

Service:cbi	PORTC,CmdLineBit     		        ;Отключение сигнала зажигания 
	ret						;Возврат в вызывающую программу

ServiceB: 						;!!Конец виртуального импульса LDELTA
	sbi	PORTC,CmdLineBit			;!!!Включить сигнал зажигания принудительно на конце метки DELTA на 25 мкс.
	StopDelta                                       ;Макрос отметки времени (окончание виртуального импульса Delta) ~ 25 мкс
	ret						;Возврат в вызывающую программу

;****************************************************** Заполнение базовых таблиц из разметочной таблицы
FillIndex: 
	FTW	0xFFFF					;366  1/мин
	FTW	0x7530					;800  1/мин
	FTW	0x3A98					;1600  1/мин
	FTW	0x3726					;1700  1/мин
	FTW	0x3415					;1800  1/мин
	FTW	0x3158					;1900  1/мин
	FTW	0x2EE0					;2000  1/мин
	FTW	0x2CA5					;2100  1/мин
	FTW	0x2A9D					;2200  1/мин
	FTW	0x28C3					;2300  1/мин
	FTW	0x2710					;2400  1/мин
	FTW	0x2580					;2500  1/мин
	FTW	0x240F					;2600  1/мин
	FTW	0x22B9					;2700  1/мин
	FTW	0x217B					;2800  1/мин
	FTW	0x2054					;2900  1/мин
	FTW	0x1F40					;3000  1/мин
	FTW	0x1E3E					;3100  1/мин
	FTW	0x1D4C					;3200  1/мин
	FTW	0x1C69					;3300  1/мин
	FTW	0x1B93					;3400  1/мин
	FTW	0x1AC9					;3500  1/мин
	FTW	0x1A0B					;3600  1/мин
	FTW	0x1956					;3700  1/мин
	FTW	0x18AC					;3800  1/мин
	FTW	0x1770					;4000  1/мин
	FTW	0x1652					;4200  1/мин
	FTW	0x154F					;4400  1/мин
	FTW	0x1461					;4600  1/мин
	FTW	0x1388					;4800  1/мин
	FTW	0x11DB					;5250  1/мин
	FTW	0x110C					;5500  1/мин
	ret

FillTable: 
	FTB	0xFF					;12  град.
	FTB	0xF2					;13  град.
	FTB	0xF2					;13  град.
	FTB	0xE4					;14  град.
	FTB	0xD5					;15  град.
	FTB	0xC7					;16  град.
	FTB	0xB9					;17  град.
	FTB	0xAB					;18  град.
	FTB	0x9C					;19  град.
	FTB	0x8E					;20  град.
	FTB	0x80					;21  град.
	FTB	0x72					;22  град.
	FTB	0x64					;23  град.
	FTB	0x59					;23,74  град.
	FTB	0x4E					;24,52  град.
	FTB	0x44					;25,22  град.
	FTB	0x3B					;25,85  град.
	FTB	0x32					;26,48  град.
	FTB	0x2A					;27,05  град.
	FTB	0x23					;27,54  град.
	FTB	0x1D					;27,96  град.
	FTB	0x18					;28,31  град.
	FTB	0x14					;28,59  град.
	FTB	0x11					;28,8  град.
	FTB	0x0F					;28,95  град.
	FTB	0x0D					;29,09  град.
	FTB	0x0B					;29,23  град.
	FTB	0x09					;29,37  град.
	FTB	0x08					;29,44  град.
	FTB	0x05					;29,65  град.
	FTB	0x01					;29,93  град.
	FTB	0x00					;30  град.
	ret
	