;*** Preizkus mikrokrmilnika - S53MV 10.03.2014 ***

;*** Vhodno/izhodni prikljucki LPC2138/01 @60MHz (kristal=20MHz) ***
;/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 -
;P0.6/MOSI0/CAP0.2/AD1.0 -
;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 ***

;*** Konstante programa ***
ISKLAD	EQU	0x40000100	;navzdol -256byte
SKLAD	EQU	0x40000400	;navzdol -768byte
ZSTEVEC	EQU	0x40000400	;stevec vzorcev v zapisu (32bit)
ZKAZALC	EQU	0x40000404	;kazalec vzorcev v zapisu (32bit)

;*** 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	PREKIN	;IRQ
	B	IZJEME	;FIQ

;*** Inicializiraj MAM in PCLK=CCLK *** (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]
	LDR	R0,=0xE01FC100	;APBDIV=1 PCLK=CCLK
	MOV	R1,#1
	STR	R1,[R0]
	BX	LR
	LTORG

;*** Inicializiraj PLL0 20MHzX3=60MHz *** (R0-2)
PLL0	LDR	R0,=0xE01FC084	;PLL0CFG=0x24 P=2,M=2
	MOV	R1,#0x22
	STRB	R1,[R0]
	LDR	R0,=0xE01FC080	;PLL0CON=0x01 PLL-enable
	MOV	R1,#0x01
	STRB	R1,[R0]
	LDR	R0,=0xE01FC08C	;PLL0FEED
	MOV	R1,#0xAA
	MOV	R2,#0x55
	STRB	R1,[R0]
	STRB	R2,[R0]
PLL01	LDR	R0,=0xE01FC088	;PLL0STAT cakanje uklenitve
	LDR	R1,[R0]
	ANDS	R1,R1,#0x400
	BEQ	PLL01
	LDR	R0,=0xE01FC080	;PLL0CON=0x03 PLL-enable&connect
	MOV	R1,#0x03
	STRB	R1,[R0]
	LDR	R0,=0xE01FC08C	;PLL0FEED
	MOV	R1,#0xAA
	MOV	R2,#0x55
	STRB	R1,[R0]
	STRB	R2,[R0]
	BX	LR
	LTORG

;*** Inicializiraj GPIO in DAC *** (R0-1)
GPIO	LDR	R0,=0xE002C000	;PINSEL0 P0.0-1=UART0 P0.4=AD0.6
	LDR	R1,=0x00000305
	STR	R1,[R0]
	LDR	R0,=0xE002C004	;PINSEL1 P0.25=AOUT
	LDR	R1,=0x00080000
	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]
	LDR	R0,=0xE006C000	;DACR sredina skale, visok tok
	LDR	R1,=0x00008000
	STR	R1,[R0]
	BX	LR
	LTORG

;*** Inicializiraj UART0 za 9600bps *** (R0-1)
UART0	LDR	R0,=0xE000C00C	;U0LCR=0x83 DLAB=1,no-parity,1stop,8bit
	MOV	R1,#0x83
	STRB	R1,[R0]
	LDR	R0,=0xE000C000	;U0DLL 
	MOV	R1,#0x87
	STRB	R1,[R0]
	LDR	R0,=0xE000C004	;U0DLM
	MOV	R1,#0x01
	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]
	BX	LR
	LTORG

;*** Prekinitveni podprogram za TIMER0 *** (R0-2)
	ALIGN	16
PREKIN	STR	R0,[SP,#-4]!	;resi registre R0,R1,R2
	STR	R1,[SP,#-4]!
	STR	R2,[SP,#-4]!
	MOV	R0,#0x80	;bajt za tisino
	LDR	R1,=ZSTEVEC	;stevec vzorcev v zapisu
	LDR	R2,[R1]
	MOVS	R2,R2
	BEQ	PREKIN1
	SUB	R2,R2,#1
	STR	R2,[R1]
	LDR	R1,=ZKAZALC	;kazalec vzorcev v zapisu
	LDR	R2,[R1]
	LDRB	R0,[R2],#1	;bajt iz zapisa
	STR	R2,[R1]
PREKIN1	MOV	R1,R0,LSL#8	;obdelaj bajt za DAC in nastavi glasnost
	LDR	R0,=0xE006C000	;naslov DACR
	STR	R1,[R0]
	LDR	R0,=0xE0004000	;T0IR=0xFF reset zahtev TIMER0
	MOV	R1,#0xFF
	STRB	R1,[R0]
	LDR	R2,[SP],#4	;povrni registre R2,R1,R0
	LDR	R1,[SP],#4
	LDR	R0,[SP],#4
	SUBS	PC,LR,#4	;izhod iz prekinitve
	LTORG

;*** Vkljuci prekinitve IRQ v ARM *** (R0)
IRQON	MRS	R0,CPSR		;preberi CPSR
	BIC	R0,R0,#0x01	;preklopi v nacin IRQ
	MSR	CPSR_c,R0	;popravi CPSR
	LDR	SP,=ISKLAD	;inicializiraj IRQ SP
	MRS	R0,CPSR		;preberi CPSR
	ORR	R0,R0,#0x03	;preklopi v nacin supervisor
	BIC	R0,R0,#0x80	;vkljuci prekinitve IRQ
	MSR	CPSR_c,R0	;popravi CPSR
	BX	LR

;*** Nastavi 8kHz prekinitve TIMER0 @60MHz *** (R0-1)
TIMER0	LDR	R0,=ZSTEVEC	;resetiraj stevec vzorcev v zapisu
	MOV	R1,#0
	STR	R1,[R0]
	LDR	R0,=0xE0004018	;T0MR0=7499 deli PCLK/7500
	LDR	R1,=7499
	STR	R1,[R0]
	LDR	R0,=0xE0004014	;T0MCR=0x0003 reset in int iz MR0
	MOV	R1,#0x0003
	STR	R1,[R0]
	LDR	R0,=0xFFFFF010	;VICIntEnable=0x00000010 TIMER0
	LDR	R1,=0x00000010
	STR	R1,[R0]
	LDR	R0,=0xE0004004	;T0TCR=0x01 vklop TIMER0
	MOV	R1,#0x01
	STR	R1,[R0]
	BX	LR
	LTORG

;*** Nepredznaceno deljenje R3/R0=R3, ostanek v R0 *** (R0-3)
NDELI	MOVS	R1,R0		;prepreci deljenje z 0?
	BXEQ	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
	BX	LR

;*** 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	T4MS		;zakasnitev 4ms
	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	T4MS		;zakasnitev 4ms
	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	0x15,0x0A,0x15,0x0A,0x15,0x0A,0x15,0x00	;0=sahovnica
	DCB	0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00	;1=enacrtica
	DCB	0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x00	;2=dvecrtici
	DCB	0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x00	;3=tricrtice
	DCB	0x15,0x0A,0x15,0x0A,0x15,0x0A,0x15,0x00	;0=sahovnica
	DCB	0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00	;1=enacrtica
	DCB	0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x00	;2=dvecrtici
	DCB	0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x00	;3=tricrtice
	ALIGN

;*** Rastoci stoplec v desno v drugi vrstici iz R3 *** (R0-3)
STOLP	STR	LR,[SP,#-4]!	;resi link
	MOV	R0,#0xC0	;set DDRAM address druga vrstica
	BL	UKAZ
	MOV	R2,#40
STOLP1	MOV	R0,#32		;presledek
	CMP	R3,#1		;ena crtica?
	MOVEQ	R0,#1
	CMP	R3,#2		;dve crtici?
	MOVEQ	R0,#2
	CMP	R3,#3		;tri crtice?
	MOVCS	R0,#3
	BL	ZNAK		;izpisi crtice
	SUBS	R3,R3,#3	;odstej 3 crtice, negativno ustavi?
	MOVMI	R3,#0
	SUBS	R2,R2,#1	;zanka 40 znakov
	BNE	STOLP1
	LDR	PC,[SP],#4	;povratek na link
	LTORG

;*** Besedilo iz [R3] v HD44780, zakljuceno z 0 ***
BESEDA	STR	LR,[SP,#-4]!	;resi link
BESEDA1	LDRB	R0,[R3],#1	;preberi znak
	MOVS	R0,R0
	LDREQ	PC,[SP],#4	;povratek na link ob izhodu
	BL	ZNAK		;izpisi znak
	B	BESEDA1

;*** 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	T100US		;zakasnitev 100us
	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	T100US		;zakasnitev 100us
	LDR	PC,[SP],#4	;povratek na link

;*** Zakasnitev 1us *** (R0)
	ALIGN	16
T1US	MOV	R0,#15
T1US1	SUBS	R0,R0,#1
	BPL	T1US1
	BX	LR

;*** Zakasnitev 100us *** (R0-1)
T100US	STR	LR,[SP,#-4]!	;resi link
	MOV	R1,#100
T100US1	BL	T1US
	SUBS	R1,R1,#1
	BPL	T100US1
	LDR	PC,[SP],#4	;povratek na link

;*** Zakasnitev 4ms *** (R0-2)
T4MS	STR	LR,[SP,#-4]!	;resi link
	MOV	R2,#40
T4MS1	BL	T100US
	SUBS	R2,R2,#1
	BPL	T4MS1
	LDR	PC,[SP],#4	;povratek na link

;*** Zakasnitev 100ms *** (R0-3)
T100MS	STR	LR,[SP,#-4]!	;resi link
	MOV	R3,#25
T100MS1	BL	T4MS
	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,#250
T1S1	BL	T4MS
	SUBS	R3,R3,#1
	BPL	T1S1
	LDR	PC,[SP],#4	;povratek na link

;*** Zacetek programa po resetu ***
ZACNI	LDR	SP,=SKLAD	;inicializiraj SP
	BL	MAM		;inicializiraj MAM in PCLK=CCLK
	BL	PLL0		;inicializiraj PLL0 20MHzX3=60MHz
	BL	GPIO		;inicializiraj GPIO in DAC
	BL	UART0		;inicializiraj UART0 za 9600bps
	BL	INILCD		;inicializiraj HD44780 5X7,2vrstici,CGRAM

	BL	TIMER0		;nastavi 8kHz prekinitve TIMER0 @60MHz
	BL	IRQON		;vkljuci prekinitve IRQ v ARM

	MOV	R0,#0x80	;prva vrstica besedila ob vklopu
	BL	UKAZ
	LDR	R3,=ZACNI1
	BL	BESEDA
	MOV	R0,#0xC0	;druga vrstica besedila ob vklopu
	BL	UKAZ
	LDR	R3,=ZACNI2
	BL	BESEDA
	BL	T1S		;zakasnitev 1s
	MOV	R0,#0x80	;pobrisi prvo vrstico
	BL	UKAZ
	LDR	R3,=ZACNI3
	BL	BESEDA
	B	ZANKA		;glavna zanka programa
	LTORG
ZACNI1	DCB	"V-meter  LPC2138",0
ZACNI2	DCB	"S53MV 10.03.2014",0
ZACNI3	DCB	"                ",0
	ALIGN	4

;*** Glavna zanka programa ***
ZANKA	MOV	R2,#1024	;zanka 1024 zaporednih A/D pretvorb
	MOV	R3,#0
ZANKA2	LDR	R0,=0xE0034000	;AD0CR START=001,PDN=1,CLKS=11,CLKDIV=224,SEL=6
	LDR	R1,=0x0120E040
	STR	R1,[R0]
ZANKA1	LDR	R0,=0xE0034004	;AD0GDR
	LDR	R1,[R0]
	TST	R1,#0x80000000
	BEQ	ZANKA1
	MOV	R1,R1,LSL#16
	ADD	R3,R3,R1,LSR#22
	SUBS	R2,R2,#1
	BNE	ZANKA2
	MOV	R3,R3,LSR#9	;deljenje rezultata /512
	STR	R3,[SP,#-4]!
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	MOV	R0,#"V"		;preračunaj R3 v desetiško obliko XX.XXV v sklad
	STR	R0,[SP,#-4]!
	MOV	R0,#10		;stotinke
	BL	NDELI
	ADD	R0,R0,#"0"
	STR	R0,[SP,#-4]!
	MOV	R0,#10		;desetinke
	BL	NDELI
	ADD	R0,R0,#"0"
	STR	R0,[SP,#-4]!
	MOV	R0,#"."		;pika
	STR	R0,[SP,#-4]!
	MOV	R0,#10		;enice
	BL	NDELI
	ADD	R0,R0,#"0"
	STR	R0,[SP,#-4]!
	MOV	R0,#10		;desetice
	BL	NDELI
	ADD	R0,R0,#"0"
	CMP	R0,#"0"
	MOVEQ	R0,#" "
	STR	R0,[SP,#-4]!
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	LDR	R2,=0xE000C000	;U0THR
	MOV	R0,#0x85	;polozaj v prvi vrstici
	BL	UKAZ
	LDR	R0,[SP],#4	;izpisi 6 znakov na UART0 in LCD
	STRB	R0,[R2]
	BL	ZNAK
	LDR	R0,[SP],#4
	STRB	R0,[R2]
	BL	ZNAK
	LDR	R0,[SP],#4
	STRB	R0,[R2]
	BL	ZNAK
	LDR	R0,[SP],#4
	STRB	R0,[R2]
	BL	ZNAK
	LDR	R0,[SP],#4
	STRB	R0,[R2]
	BL	ZNAK
	LDR	R0,[SP],#4
	STRB	R0,[R2]
	BL	ZNAK
	MOV	R0,#13		;CR nova vrstica na UART0
	STRB	R0,[R2]
	MOV	R0,#10		;LF
	STRB	R0,[R2]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	LDR	R3,[SP],#4	;stolpec v drugi vrstici
	MOV	R3,R3,LSR#5
	BL	STOLP
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	BL	GOVOR
	B	ZANKA
	LTORG

;*** Govor *** (R0-2)
GOVOR	LDR	R0,=ZSTEVEC	;veljaven (ZSTEVEC)?
	LDR	R1,[R0]
	MOVS	R1,R1
	BXNE	LR		;izhod med govorjenjem
	STR	LR,[SP,#-4]!	;resi link
	B	ZVOK6

GOVOR1	MOVS	R0,LR		;zacetek .WAV zapisa v R0
	LDREQ	PC,[SP],#4	;izhod za nicno sporocilo

	ADD	R0,R0,#46	;zacetek zvoka v (ZKAZALC)
	LDR	R1,=ZKAZALC
	STR	R0,[R1]
	LDRB	R1,[LR,#4]	;dolzina zvoka: dva bajta iz .WAV max 64kB
	LDRB	R2,[LR,#5]
	ADD	R1,R1,R2,LSL#8
	SUBS	R1,R1,#46	;odstej 30 bajtov glave
	MOVMI	R1,#0
	LDR	R0,=ZSTEVEC	;dolzina zvoka v (ZSTEVEC)
	STR	R1,[R0]

	LDR	PC,[SP],#4	;povratek na link

ZVOK6	BL	GOVOR1
	INCBIN	Wave1.WAV
	ALIGN	4

;*** Konec delovanja zbirnika ARM ***
	END
