;questo programma acquisisce, sotto interrupt, due dati esterni, ne
fa il quoziente e ;presenta il dato sulla seriale dopo averlo filtrato.
.start "CODE",0x809803 ; Il compilatore assembla il codice da
questa locazione di memoria.
.sect "CODE"
ldi 6,IOF; Il piedino XF0 viene mandato ad 1 per cui si disabilita
la eprom.
b BEGIN; Si rimanda l'esecuzione del programma alla riga BEGIN per
impedire al processore di passare
; nelle successive locazioni di memoria, manipolate solo durante
il boot.
;************************************
; Buffer dei campioni del FIR
;************************************
Last_x .float
0.0 ; inizialmente si pongono tutti i campioni
a 0. Il buffer ha 201 locazioni di memoria.
.float 0.0
.float 0.0
....................
....................
.float 0.0
First_x .float
0.0
;************************************
; Buffer dei coefficienti del FIR
;************************************
BEG_coef .float
.0000000000000000E+00 ; I coefficienti sono 201 e sono simmetrici.
.float -.2384185791015625E-06
.float -.1072883605957031E-05
.float -.2503395080566406E-05
.float -.4410743713378906E-05
..................................................
..................................................
.float -.4410743713378906E-05
.float -.2503395080566406E-05
.float -.1072883605957031E-05
.float -.2384185791015625E-06
.float .0000000000000000E+00
END_coef
;************************************
; Definizione locazioni di memoria e costanti usate nel programma.
;************************************
BufSz .set
END_coef - BEG_coef ; Locazione di
memoria contenente la lunghezza del buffer dei coeff.
Size
.word BufSz
; Lunghezza del filtro
Last_coef .word BEG_coef
; Indirizzo dell'ultimo coefficiente
Sample .word
Last_x
; Indirizzo del nuovo campione entrante nel FIR
S0_gctrl .set 0x808040
; Serial Port Global control
S0_xctrl .set 0x808042
; FSX/DX/CLKX Serial Port control
S0_xdata .set 0x808048
; Serial Port data transmit
S0_tctrl .set 0x808044
; Serial Port R/X timer control
S0_pctrl .set 0x808046
; Serial Port R/X period control
GIE .set
0x2000
; Abilitazione in ST degli interrupts
mac0 .set
0x80B000
; Locazione dividendo
mac1 .set
0x80B001
; Locazione divisore (differisce dalla
; precedente per l’ultimo bit)
;************************************
; Buffer tabella ascii
;************************************
loc_ini .word 0x809BA1
; Locazione inizio buffer
chr0 .set
0x809BA1
chr1 .set
0x809BA2
chr2 .set
0x809BA3
chr3 .set
0x809BA4
chr4 .set
0x809BA5
chr5 .set
0x809BA6
chr6 .set
0x809BA7
chr7 .set
0x809BA8
chr8 .set
0x809BA9
chr9 .set
0x809BAA
chrA .set
0x809BAB
chrB .set
0x809BAC
chrC .set
0x809BAD
chrD .set
0x809BAE
chrE .set
0x809BAF
chrF .set
0x809BB0
chrCR .set 0x809BB1
chrLF .set 0x809BB2
; Locazione fine buffer (loc_end)
;************************************
; Buffer dati già codificati
;************************************
w7 .set
0x809BB3
w6 .set
0x809BB4
w5 .set
0x809BB5
w4 .set
0x809BB6
w3 .set
0x809BB7
w2 .set
0x809BB8
w1 .set
0x809BB9
w0 .set
0x809BBA
wCR .set 0x809BBB
wLF .set
0x809BBC
;********************************************
; Valori da immagazzinare nei vari registri e buffer
;********************************************
S0_gctrl_val .word 0x4850244
; Valore del Serial Port Global control register
S0_xctrl_val .word 0x00000111
; Valore del FSX/DX/CLKX Serial Port control register
S0_tctrl_val .word 10FH
; Valore del Serial Port R/X timer control register
S0_pctrl_val .word 0x28B
; Valore del Serial Port R/X period control register
;***********************Valori ascii***************
; I seguenti valori in base 10 (il processore automaticamente
li trasformerà in esadecimali) corrispondono ai codici ascii
binari ottenuti invertendo l'ordine dei bit. Il buffer seriale del DSP
infatti viene svuotato a partire dal MSB,
; mentre il protocollo della seriale vuole il dato presentato dal LSB
al MSB.
;***********************************************
chr0_val .word 12
chr1_val .word 140
chr2_val .word 76
chr3_val .word 204
chr4_val .word 44
chr5_val .word 172
chr6_val .word 108
chr7_val .word 236
chr8_val .word 28
chr9_val .word 156
chrA_val .word 130
chrB_val .word 66
chrC_val .word 194
chrD_val .word 34
chrE_val .word 162
chrF_val .word 98
chrCR_val .word 176
chrLF_val .word 80
;*************************************************************
.entry
BEGIN ; Qui comincia l'esecuzione del programma,
dopo il boot. ; Il processore ha già eseguito le due
istruzioni ldi 6,IOF e b BEGIN.
BEGIN ldp S0_gctrl
; Si carica il registro DP con il valore 80h.
ldi @stack,SP ; Si definisce la posizione dello stack
pointer.
;********************************************
; Inizializzazione dei registri della seriale.
;********************************************
ldi @S0_xctrl_val,R0
sti R0,@S0_xctrl
ldi @S0_gctrl_val,R0
sti R0,@S0_gctrl
ldi @S0_tctrl_val,R0
sti R0,@S0_tctrl
ldi @S0_pctrl_val,R0
sti R0,@S0_pctrl
;********************************************
; Inizializzazione dei registri per il filtro FIR
;********************************************
ldi
@Size,RC
subi 2,RC
ldi
@Sample,AR3
ldi
@Size,BK
;********************************************
; Caricamento in memoria della tabella ascii
;********************************************
ldi @chr0_val,R0
sti R0,@chr0
ldi @chr1_val,R0
sti R0,@chr1
ldi @chr2_val,R0
sti R0,@chr2
ldi @chr3_val,R0
sti R0,@chr3
ldi @chr4_val,R0
sti R0,@chr4
ldi @chr5_val,R0
sti R0,@chr5
ldi @chr6_val,R0
sti R0,@chr6
ldi @chr7_val,R0
sti R0,@chr7
ldi @chr8_val,R0
sti R0,@chr8
ldi @chr9_val,R0
sti R0,@chr9
ldi @chrA_val,R0
sti R0,@chrA
ldi @chrB_val,R0
sti R0,@chrB
ldi @chrC_val,R0
sti R0,@chrC
ldi @chrD_val,R0
sti R0,@chrD
ldi @chrE_val,R0
sti R0,@chrE
ldi @chrF_val,R0
sti R0,@chrF
ldi @chrCR_val,R0
sti R0,@chrCR
ldi @chrLF_val,R0
sti R0,@chrLF
;****************************************************
; Loop principale
;****************************************************
ldi 0,R0
MAINP or GIE,ST ; Abilitazione degli interrupts
or 1,IE ; Abilitazione dell'interrupt
INT0
idle
ldi 0x27,R2 ; Controllo sul dato da inviare alla seriale (ricampionamento).
cmpi R0,R2
callz DSPSERI
b MAINP
;****************************************************
; Routine GET per l'acquisizione, la divisione e il FIR
;****************************************************
GET rpts 1
ldi @mac0,R1 ;acquisizione dato dal MAC0
rpts 1
ldi @mac1,R3 ;acquisizione dato dal MAC1
;****************************************************
; Calcolo del quoziente
;****************************************************
cmpi 0,R3
ldiz 1,R3
float R1,R2
pushf R2
pop AR6
lsh -24,AR6
float R3,R2
pushf R2
pop AR5
lsh -24,AR5
subi AR5,AR6
lsh AR6,R3
rpts AR6
subc R3,R1
ldi 1,R3
addi 1,AR6
lsh AR6,R3
subi 1,R3
and3 R3,R1,AR4 ; in AR4 ho il quoziente intero
lsh 4,AR4
not R3,R3
and3 R3,R1,R3
subi 1,AR6
ldi 0,AR5
subi AR6,AR5
lsh AR5,R3
ldi R3,R1 ; in R1 ho il resto
shiftato di 4
ldi 0,AR5
ldi 0,AR6
cmpi 0,R3
ldiz 1,R3
SOTT cmpi R3,R1
bn STORE
subi R3,R1
addi 1,AR5
b SOTT
STORE or3 AR4,AR5,R1
;****************************************************************
; Codice del FIR. In R1 ho il quoziente.
;****************************************************************
ldi @Size,RC
subi 2,RC
float R1,R1
stf R1,*AR3++(1)%
ldi @Last_coef,AR2
mpyf3 *AR2++,*AR3++(1)%,R1
ldf 0.0,R3
rpts RC
mpyf3 *AR2++,*AR3++(1)%,R1
|| addf3 R1,R3,R3
addf3 R1,R3,R1
ldf R1,R3
fix R3,R3
addi 1,R0 ; Ogni numero che acquisisco
incremento il contatore.
reti
;************************************************************
;Fine del loop principale e inizio della routine per la trasmissione
seriale
;************************************************************
DSPSERI ldi @loc_ini,AR0
ldi 0xF,R2
lsh 28,R2
and R3,R2
lsh -28,R2
ldi R2,IR0
ldi 1,R4 ; Si carica la stop
bit
ldi *+AR0(IR0),R2
lsh 1,R2 ; Sposta i dati di una posizione
per dare spazio allo stop bit
or R4,R2
sti R2,@bit7
ldi 0xF,R2
lsh 24,R2
and R3,R2
lsh -24,R2
ldi R2,IR0
ldi 1,R4
ldi *+AR0(IR0),R2
lsh 1,R2
or R4,R2
sti R2,@bit6
ldi 0xf,R2
lsh 20,R2
and R3,R2
lsh -20,R2
ldi R2,IR0
ldi 1,R4
ldi *+AR0(IR0),R2
lsh 1,R2
or R4,R2
sti R2,@bit5
ldi 0xf,R2
lsh 16,R2
and R3,R2
lsh -16,R2
ldi R2,IR0
ldi 1,R4
ldi *+AR0(IR0),R2
lsh 1,R2
or R4,R2
sti R2,@bit4
ldi 0xf00,R1
lsh 4,R1
and3 R1,R3,R2
lsh -12,R2
ldi R2,IR0
ldi 1,R4
ldi *+AR0(IR0),R2
lsh 1,R2
or R4,R2
sti R2,@bit3
ldi 0xf00,R1
and3 R1,R3,R2
lsh -8,R2
ldi R2,IR0
ldi 1,R4
ldi *+AR0(IR0),R2
lsh 1,R2
or R4,R2
sti R2,@bit2
ldi 0xf0,R1
and3 R1,R3,R2
lsh -4,R2
ldi R2,IR0
ldi 1,R4
ldi *+AR0(IR0),R2
lsh 1,R2
or R4,R2
sti R2,@bit1
ldi 0xf,R1
and3 R1,R3,R2
ldi R2,IR0
ldi 1,R4
ldi *+AR0(IR0),R2
lsh 1,R2
or R4,R2
sti R2,@bit0
ldi 16,IR0
ldi 1,R4
ldi *+AR0(IR0),R2
lsh 1,R2
or R4,R2
sti R2,@bitCR
ldi 17,IR0
ldi 1,R4
ldi *+AR0(IR0),R2
lsh 1,R2
or R4,R2
sti R2,@bitLF
ldi 0,IR1
MAINR or GIE,ST
ldi 0x11,IE ; Abilitazione interrupts
idle
ldi 10,R6
cmpi R6,IR1
bn MAINR
ldi 0,R0
rets
SERIAL or GIE,ST
or 1,IE ; Abilita
l'interrupt INT0 per rendere la routine interrompibile.
addi 1,IR0
nop ;
| Le due nop evitano i conflitti
nop ;
| di pipeline.
ldi *AR0(IR0),R2
sti R2,@S0_xdata
addi 1,IR1
reti
stack .word $ ; Posizione dello stack pointer.
;********************************************
;Settaggio interrups
;********************************************
.start
"INTVECTS",0x809FC1
.sect
"INTVECTS"
B
GET ; INT0
.start
"SP0VECTS",0x809FC5
.sect
"SP0VECTS"
B
SERIAL ; XINT0