B.3 Programma assembler del DSP
 

;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


Home | Precedente | Successivo