;*** Dvokoanalni merilni sprejemnik - S53MV 05.09.2016 ***

;*** Konstante mikrokrmilnika LPC2138/01 ***
KVARC	EQU	14745600	;frekvenca kristala (Hz)
CLK	EQU	KVARC*4		;frekvenca jedra ARM (PLL)
PCLK	EQU	CLK/2		;frekvenca vhodno/izhodnih enot (APBDIV)
BAUD	EQU	PCLK/153600	;modulo deljenja UART za 9600bps*16
N1US	EQU	CLK/3000000	;konstanta cakanja T1US za HD44780
NADC	EQU	PCLK/1000000	;deljenje takta ADC0 & ADC1
NMERI	EQU	8		;stevilo meritev pri povprecenju
NSKALA	EQU	784*64/NMERI	;faktor skale pri povprečenju

;*** Vhodno/izhodni prikljucki LPC2138/01 ***
;/RESET - vhod vezan na /ERROR.LP2951 in na /DTR.FT231XS
;P0.0/TXD0/PWM1 - izhod vezan na RXD.FT231XS 
;P0.1/RXD0/PWM3/EINT0 - vhod vezan na TXD.FT231XS
;P0.2.od/SCL0/CAP0.0 -
;P0.3.od/SDA0/MAT0.0/EINT1 -
;P0.4/SCK0/CAP0.1/AD0.6 -
;P0.5/MISO0/MAT0.1/AD0.7 - analogni vhod dioda #1
;P0.6/MOSI0/CAP0.2/AD1.0 - analogni vhod dioda #2
;P0.7/SSEL0/PWM2/EINT2 -
;P0.8/TXD1/PWM4/AD1.1 -
;P0.9/RXD1/PWM6/EINT3 -
;P0.10/RTS1/CAP1.0/AD1.2 -
;P0.11.od/CTS1/CAP1.1/SCL1 -
;P0.12/DSR1/MAT1.0/AD1.3 -
;P0.13/DTR1/MAT1.1/AD1.4 -
;P0.14.od/DCD1/EINT1/SDA1/BOOTLOADER(!) - vhod vezan na /RTS.FT231XS 
;P0.15/RI1/EINT2/AD1.5 -
;P0.16-23 - digitalni izhodi za LCD D0-7.HD44780
;P0.24 - ne obstaja ***
;P0.25/AD0.4/AOUT -
;P0.26/AD0.5 -
;P0.27/AD0.0/CAP0.1/MAT0.1 -
;P0.28/AD0.1/CAP0.2/MAT0.2 -
;P0.29/AD0.2/CAP0.3/MAT0.3 -
;P0.30/AD0.3/EINT3/CAP0.0 -
;P0.31(!) - nepovezan ***
;P1.0-15 - ne obstajajo ***
;P1.16-19 - vhodi z vgrajenim PULL-UP za tipke na maso
;P1.20(!) - nepovezan ***
;P1.21 - digitalni izhod za LCD RS.HD44780
;P1.22-25 - nepovezani ***
;P1.26(!) - nepovezan ***
;P1.27-29 - nepovezani ***
;P1.30 - digitalni izhod za LCD E.HD44780
;P1.31 - nepovezan ***

;*** Dodelitev pomnilnika RAM ***
SKLAD	EQU	0x40000100	;sklad raste navzdol -256byte

;*** Ukazi za delovanje zbirnika ARM ***
	AREA	RESET, CODE, READONLY, ALIGN=9
	ENTRY
	CODE32

;*** Tabela izjem na zacetnem naslovu 0 ***
IZJEME	B	ZACNI	;RESET
	B	IZJEME	;Undef
	B	IZJEME	;SWI
	B	IZJEME	;PAbt
	B	IZJEME	;DAbt
	NOP		;Reserved Vector
	B	IZJEME	;IRQ
	B	IZJEME	;FIQ

;*** Pocisti pomnilnik do nevarne lokacije 0x000001FC ***
	ALIGN	512

;*** Inicializiraj MAM *** (R0-1)
MAM	LDR	R0,=0xE01FC000	;MAMCR=0
	MOV	R1,#0
	STRB	R1,[R0]
	LDR	R0,=0xE01FC004	;MAMTIM=3
	MOV	R1,#3
	STRB	R1,[R0]
	LDR	R0,=0xE01FC000	;MAMCR=2
	MOV	R1,#2
	STRB	R1,[R0]
	MOV	PC,LR
	LTORG

;*** Nastavi PCONP in APBDIV *** (R0-1)
PWRCLK	LDR	R0,=0xE01FC0C4	;PCONP
	LDR	R1,=0x00101008	;UART0,AD0,AD1
	STR	R1,[R0]
	LDR	R0,=0xE01FC100	;APBDIV=2
	MOV	R1,#2
	STRB	R1,[R0]
	MOV	PC,LR
	LTORG

;*** Inicializiraj PLL *** (R0-2)
PLL	LDR	R0,=0xE01FC084	;PLLCFG=0x24 P=2,M-1=3
	MOV	R1,#0x23
	STRB	R1,[R0]
	LDR	R0,=0xE01FC080	;PLLCON=0x01 PLL-enable
	MOV	R1,#0x01
	STRB	R1,[R0]
	LDR	R0,=0xE01FC08C	;PLLFEED
	MOV	R1,#0xAA
	MOV	R2,#0x55
	STRB	R1,[R0]
	STRB	R2,[R0]
PLL1	LDR	R0,=0xE01FC088	;PLLSTAT cakanje uklenitve
	LDR	R1,[R0]
	ANDS	R1,R1,#0x400
	BEQ	PLL1
	LDR	R0,=0xE01FC080	;PLLCON=0x03 PLL-enable&connect
	MOV	R1,#0x03
	STRB	R1,[R0]
	LDR	R0,=0xE01FC08C	;PLLFEED
	MOV	R1,#0xAA
	MOV	R2,#0x55
	STRB	R1,[R0]
	STRB	R2,[R0]
	MOV	PC,LR
	LTORG

;*** Inicializiraj GPIO in DAC *** (R0-1)
GPIO	LDR	R0,=0xE002C000	;PINSEL0 P0.0-1=UART0,P0.5=AD0.7,P0.6=AD1.0
	LDR	R1,=0x00003C05
	STR	R1,[R0]
	LDR	R0,=0xE002C004	;PINSEL1
	LDR	R1,=0x00000000
	STR	R1,[R0]
	LDR	R0,=0xE002C014	;PINSEL2 izklop JTAG&TRACE
	LDR	R1,[R0]
	BIC	R1,R1,#0x0C
	STR	R1,[R0]
	LDR	R0,=0xE01FC1A0	;SCS=0x03 high-speed GPIO 0&1
	MOV	R1,#0x03
	STR	R1,[R0]
	LDR	R0,=0x3FFFC014	;FIO0PIN vsi 1
	MOV	R1,#-1
	STR	R1,[R0]
	LDR	R0,=0x3FFFC034	;FIO1PIN vsi 0
	MOV	R1,#0
	STR	R1,[R0]
	LDR	R0,=0x3FFFC000	;FIO0DIR izhodi 0.0-0.31
	LDR	R1,=0xFFFFFFFF
	STR	R1,[R0]
	LDR	R0,=0x3FFFC020	;FIO1DIR izhodi 1.20-1.31
	LDR	R1,=0xFFF00000
	STR	R1,[R0]
	MOV	PC,LR
	LTORG

;*** Inicializiraj UART0 *** (R0-1)
UART0	LDR	R0,=0xE000C00C	;U0LCR=0x83 DLAB=1,no-parity,1stop,8bit
	MOV	R1,#0x83
	STRB	R1,[R0]
	LDR	R0,=0xE000C000	;U0DLL 
	LDR	R1,=BAUD
	STRB	R1,[R0]
	LDR	R0,=0xE000C004	;U0DLM
	MOV	R1,R1,LSR#8
	STRB	R1,[R0]
	LDR	R0,=0xE000C008	;U0FCR=0xC1 RXtrig=14bit,FIFOenable
	MOV	R1,#0xC1
	STRB	R1,[R0]
	LDR	R0,=0xE000C00C	;U0LCR=0x03 DLAB=0,no-parity,1stop,8bit
	MOV	R1,#0x03
	STRB	R1,[R0]
	MOV	PC,LR
	LTORG

;*** Inicializiraj HD44780 5X7,2vrstici,CGRAM *** (R0-3)
INILCD	STR	LR,[SP,#-4]!	;resi link
	BL	T100MS		;zakasnitev 100ms
	MOV	R0,#0x38	;function set 
	BL	UKAZ
	BL	T5MS		;zakasnitev 5ms
	MOV	R0,#0x38	;function set
	BL	UKAZ
	MOV	R0,#0x38	;function set
	BL	UKAZ
	MOV	R0,#0x08	;display off
	BL	UKAZ
	MOV	R0,#0x01	;display clear
	BL	UKAZ
	BL	T5MS		;zakasnitev 5ms
	MOV	R0,#0x06	;entry mode set
	BL	UKAZ
	MOV	R0,#0x0C	;display on
	BL	UKAZ
	MOV	R0,#0x40	;set CGRAM address
	BL	UKAZ
	MOV	R2,#64		;prepisi 8 znake = 64 bajtov
	LDR	R3,=INILCD2
INILCD1	LDRB	R0,[R3],#1
	BL	ZNAK
	SUBS	R2,R2,#1
	BNE	INILCD1
	MOV	R0,#0x80	;set DDRAM address zacetek prve vrstice
	BL	UKAZ
	LDR	PC,[SP],#4	;povratek na link
	LTORG
INILCD2	DCB	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04	;0=praznina
	DCB	0x00,0x10,0x10,0x10,0x10,0x10,0x00,0x04	;1=enacrtica
	DCB	0x00,0x14,0x14,0x14,0x14,0x14,0x00,0x04	;2=dvecrtici
	DCB	0x00,0x15,0x15,0x15,0x15,0x15,0x00,0x04	;3=tricrtice
	DCB	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F	;0=praznina podcrtana
	DCB	0x00,0x10,0x10,0x10,0x10,0x10,0x00,0x1F	;1=enacrtica podcrtana
	DCB	0x00,0x14,0x14,0x14,0x14,0x14,0x00,0x1F	;2=dvecrtici podcrtana
	DCB	0x00,0x15,0x15,0x15,0x15,0x15,0x00,0x1F	;3=tricrtice podcrtana
	ALIGN

;*** Podcrtan stolpec v desno v prvi/drugi vrstici iz R3 *** (R0-3)
STOLP	STR	LR,[SP,#-4]!	;resi link
	MOV	R2,#0
STOLP1	MOV	R0,#0		;praznina za velike korake po 16
	CMP	R3,#16		;ena crtica?
	MOVCS	R0,#1
	CMP	R3,#32		;dve crtici?
	MOVCS	R0,#2
	CMP	R3,#48		;tri crtice?
	MOVCS	R0,#3
	AND	R1,R3,#15	;podcrtaj pripadajoci znak za male korake po 1
	CMP	R1,R2
	ADDEQ	R0,R0,#4
	BL	ZNAK		;izpisi crtice
	SUBS	R3,R3,#48	;odstej 3 crtice, negativno ustavi?
	ANDMI	R3,R3,#15
	ADD	R2,R2,#1	;zanka 16 znakov
	CMP	R2,#16
	BMI	STOLP1
	LDR	PC,[SP],#4	;povratek na link
	LTORG

;*** Znak iz R0 v HD44780 *** (R0-1)
ZNAK	STR	LR,[SP,#-4]!	;resi link
	LDR	R1,=0x3FFFC016	;FIO0PIN2 podatek
	STRB	R0,[R1]
	LDR	R1,=0x3FFFC03A	;FIO1SET2
	MOV	R0,#0x20	;RS=1
	STRB	R0,[R1]
	BL	T1US		;zakasnitev 1us
	LDR	R1,=0x3FFFC03B	;FIO1SET3
	MOV	R0,#0x40	;vklopi E
	STRB	R0,[R1]
	BL	T1US		;zakasnitev 1us
	LDR	R1,=0x3FFFC03F	;FIO1CLR3
	MOV	R0,#0x40	;izklopi E
	STRB	R0,[R1]
	BL	T50US		;zakasnitev 50us
	LDR	PC,[SP],#4	;povratek na link
	LTORG

;*** Ukaz iz R0 v HD44780 *** (R0-1)
UKAZ	STR	LR,[SP,#-4]!	;resi link
	LDR	R1,=0x3FFFC016	;FIO0PIN2 podatek
	STRB	R0,[R1]
	LDR	R1,=0x3FFFC03E	;FIO1CLR2
	MOV	R0,#0x20	;RS=0
	STRB	R0,[R1]
	BL	T1US		;zakasnitev 1us
	LDR	R1,=0x3FFFC03B	;FIO1SET3
	MOV	R0,#0x40	;vklopi E
	STRB	R0,[R1]
	BL	T1US		;zakasnitev 1us
	LDR	R1,=0x3FFFC03F	;FIO1CLR3
	MOV	R0,#0x40	;izklopi E
	STRB	R0,[R1]
	BL	T50US		;zakasnitev 50us
	LDR	PC,[SP],#4	;povratek na link
	LTORG

;*** Zakasnitev 1us *** (R0)
	ALIGN	16
T1US	MOV	R0,#N1US
T1US1	SUBS	R0,R0,#1
	BPL	T1US1
	MOV	PC,LR

;*** Zakasnitev 50us *** (R0-1)
T50US	STR	LR,[SP,#-4]!	;resi link
	MOV	R1,#50
T50US1	BL	T1US
	SUBS	R1,R1,#1
	BPL	T50US1
	LDR	PC,[SP],#4	;povratek na link

;*** Zakasnitev 2ms *** (R0-2)
T2MS	STR	LR,[SP,#-4]!	;resi link
	MOV	R2,#40
T2MS1	BL	T50US
	SUBS	R2,R2,#1
	BPL	T2MS1
	LDR	PC,[SP],#4	;povratek na link

;*** Zakasnitev 5ms *** (R0-2)
T5MS	STR	LR,[SP,#-4]!	;resi link
	MOV	R2,#100
T5MS1	BL	T50US
	SUBS	R2,R2,#1
	BPL	T5MS1
	LDR	PC,[SP],#4	;povratek na link

;*** Zakasnitev 100ms *** (R0-3)
T100MS	STR	LR,[SP,#-4]!	;resi link
	MOV	R3,#20
T100MS1	BL	T5MS
	SUBS	R3,R3,#1
	BPL	T100MS1
	LDR	PC,[SP],#4	;povratek na link

;*** Zakasnitev 1s *** (R0-3)
T1S	STR	LR,[SP,#-4]!	;resi link
	MOV	R3,#200
T1S1	BL	T5MS
	SUBS	R3,R3,#1
	BPL	T1S1
	LDR	PC,[SP],#4	;povratek na link

;*** Nepredznaceno deljenje R3/R0=R3, ostanek v R0 *** (R0-3)
NDELI	MOVS	R1,R0		;prepreci deljenje z 0?
	MOVEQ	PC,LR
	MOV	R2,#1
	BMI	NDELI2
NDELI1	MOV	R2,R2,LSL#1	;enica delitelja v MSB
	MOVS	R1,R1,LSL#1
	BPL	NDELI1
NDELI2	MOV	R0,R3		;ostanek v R0
	MOV	R3,#0		;kvocient v R3
NDELI3	CMP	R0,R1
	SUBCS	R0,R0,R1
	ADDCS	R3,R3,R2
	MOV	R1,R1,LSR#1
	MOVS	R2,R2,LSR#1
	BNE	NDELI3
	MOV	PC,LR

;*** Izracunaj kvadratni koren sqrt(R5)=R4 *** (R0-5)
KOREN	STR	LR,[SP,#-4]!	;resi link
	MOV	R4,#1		;zacetni priblizek Y(0)=1
KOREN1	MOV	R3,R5
	MOV	R0,R4
	BL	NDELI		;nepredznaceno deljenje R3/R0=R3, ostanek v R0
	SUB	R0,R3,R4	;razlika priblizkov v R0
	ADD	R4,R4,R3	;izracunaj novi priblizek Y(n+1)=(Y(n)+X/(Y(n))/2
	MOV	R4,R4,LSR#1
	CMP	R0,#3		;ponovi, ce je razlika priblizkov 3 ali vec
	BCS	KOREN1
	LDR	PC,[SP],#4	;povratek na link

;*** Zacetek programa po resetu ***
ZACNI	LDR	SP,=SKLAD	;inicializiraj SP
	BL	MAM	;inicializiraj MAM
	BL	PWRCLK	;nastavi PCONP in APBDIV
	BL	PLL	;inicializiraj PLL
	BL	GPIO	;inicializiraj GPIO
	BL	UART0	;inicializiraj UART0
	BL	INILCD	;inicializiraj HD44780 5X7,2vrstici,CGRAM
	MOV	R0,#0x80	;prva vrstica besedila
	BL	UKAZ
	LDR	R2,=ZACNI5
ZACNI1	LDRB	R0,[R2],#1
	MOVS	R0,R0
	BEQ	ZACNI2
	BL	ZNAK
	B	ZACNI1
ZACNI2	MOV	R0,#0xC0	;druga vrstica besedila
	BL	UKAZ
	LDR	R2,=ZACNI6
ZACNI3	LDRB	R0,[R2],#1
	MOVS	R0,R0
	BEQ	ZACNI4
	BL	ZNAK
	B	ZACNI3
ZACNI4	BL	T1S		;zakasnitev 1s

	B	ZANKA	;glavna zanka programa
	LTORG
ZACNI5	DCB	"2*LIN merilni RX",0
ZACNI6	DCB	"S53MV 05.09.2016",0
	ALIGN	4

;*** Glavna zanka programa ***
ZANKA	MOV	R3,#NMERI	;stevilo meritev pri povprecenju
	MOV	R6,#0		;zacetna vsota sprejemnika #1
	MOV	R7,#0		;zacetna vsota sprejemnika #2
ZANKA1	MOV	R2,#NADC	;izracunaj vrednost CLKDIV
	SUB	R2,R2,#1
	LDR	R0,=0xE0034000	;AD0CR
	LDR	R1,=0x01200080	;START=001,PDN=1,CLKS=11,CLKDIV,SEL=7
	ORR	R1,R1,R2,LSL#8
	STR	R1,[R0]
	LDR	R0,=0xE0060000	;AD1CR
	LDR	R1,=0x01200001	;START=001,PDN=1,CLKS=11,CLKDIV,SEL=0
	ORR	R1,R1,R2,LSL#8
	STR	R1,[R0]
ZANKA2	LDR	R0,=0xE0034004	;AD0GDR cakaj konec pretvorbe
	LDR	R1,[R0]
	TST	R1,#0x80000000
	BEQ	ZANKA2
	LDR	R0,=0xE0060004	;AD1GDR cakaj konec pretvorbe
	LDR	R2,[R0]
	TST	R2,#0x80000000
	BEQ	ZANKA2
	MOV	R1,R1,LSL#16	;pristej AD0.7 povprecju sprejemnika #1 v R6
	ADD	R6,R6,R1,LSR#22
	MOV	R2,R2,LSL#16	;pristej AD1.0 povprecju sprejemnika #2 v R7
	ADD	R7,R7,R2,LSR#22
	SUBS	R3,R3,#1	;zanka zaporednih meritev
	BNE	ZANKA1

	MOV	R0,#NSKALA	;nastavi skalo R6 in popravi koleno
	MUL	R1,R0,R6
	MOV	R4,R1,LSR#8
	BL	KOLENO		;popravek kolena diode v R4
	MOV	R6,R4,LSR#8

	MOV	R0,#NSKALA	;nastavi skalo R7 in popravi koleno
	MUL	R1,R0,R7
	MOV	R4,R1,LSR#8
	BL	KOLENO		;popravek kolena diode v R4
	MOV	R7,R4,LSR#8

	MOV	R3,R6		;poslji povprecje #1 na UART0 v ASCII obliki
	MOV	R0,#10
	BL	NDELI		;nepredznaceno deljenje R3/R0=R3, ostanek v R0
	ADD	R4,R0,#"0"
	MOV	R0,#10
	BL	NDELI		;nepredznaceno deljenje R3/R0=R3, ostanek v R0
	ADD	R5,R0,#"0"
	ADD	R3,R3,#"0"
	LDR	R1,=0xE000C000	;U0THR
	STRB	R3,[R1]
	STRB	R5,[R1]
	STRB	R4,[R1]
	MOV	R0,#" "		;" " presledek za povprecjem #1 na UART0
	STRB	R0,[R1]
	MOV	R3,R7		;poslji povprecje #2 na UART0 v ASCII obliki
	MOV	R0,#10
	BL	NDELI		;nepredznaceno deljenje R3/R0=R3, ostanek v R0
	ADD	R4,R0,#"0"
	MOV	R0,#10
	BL	NDELI		;nepredznaceno deljenje R3/R0=R3, ostanek v R0
	ADD	R5,R0,#"0"
	ADD	R3,R3,#"0"
	LDR	R1,=0xE000C000	;U0THR
	STRB	R3,[R1]
	STRB	R5,[R1]
	STRB	R4,[R1]
	MOV	R0,#13		;CR nova vrstica za povprecjem #2 na UART0
	STRB	R0,[R1]
	MOV	R0,#10		;LF
	STRB	R0,[R1]
	MOV	R0,#0x80	;set DDRAM address prva vrstica
	BL	UKAZ
	MOV	R3,R6
	BL	STOLP		;podcrtan stolpec v desno v prvi vrstici
	MOV	R0,#0xC0	;set DDRAM address druga vrstica
	BL	UKAZ
	MOV	R3,R7
	BL	STOLP		;podcrtan stolpec v desno v drugi vrstici

	BL	T5MS
	BL	T5MS
	B	ZANKA
	LTORG

;*** Popravek kolena diode v R4 *** (R0-5,R8)
MEJA	EQU	60*256		;meja popravljanja kolena diode
KOLENO	STR	LR,[SP,#-4]!	;resi link
	LDR	R0,=MEJA	;nad mejo ni popravka?
	CMP	R4,R0
	LDRCS	PC,[SP],#4	;povratek na link
	MOV	R8,R4
	MUL	R5,R4,R0
	BL	KOREN		;izracunaj kvadratni koren sqrt(R5)=R4
	SUBS	R0,R4,R8
	MOVMI	R0,#0
	MUL	R3,R0,R8
	LDR	R0,=MEJA
	BL	NDELI		;nepredznaceno deljenje R3/R0=R3, ostanek v R0
	SUB	R4,R4,R3
	LDR	PC,[SP],#4	;povratek na link
	LTORG

;*** Konec delovanja zbirnika ARM ***
	END
