WavePOD WaveLoop F

WaveLoop F
;*************************************************************************
; Arbitrary WaveForm Generator - High Precision 
;*************************************************************************
;
; DESCRIPTION   32 step arbitrary 8 bit pattern generator
;               with sub-hertz period control
;
; This Module uses the values in WAV_16..47 to set output values in PB0..7.
; The position index into this table is the top 5 bits of a running 29 bit
; counter (Phase Accumulator) with a  32 bit Phase increment. A 8uS loop per 
; step (125KHz step freq) results in a frequency control of about 0.01 Hz
     
; REGISTER MAP

; WAV_8,11      29 bit phase index      (int.frac 5.24)
; WAV_12,15     32 bit phase increment  (int.frac 8.24)
; VMR_16        Output value for step 0
; VMR_...
; VMR_47        Output value for step 31

; OPERATION
; 
; Top 5 bits of phase accumulator points into 32 byte table and the
; lower 24 bits of the phase accumulator are fractional phase
; Phase increment is full 32 bit - allowing phase steps greater than
; a single table location. If the phase increment is greater than 32
; it is also possible to step backwards through the table.
; 
; While the average frequency of the waveform generated is accurate to < 0.01Hz,
; the sample rate of the generator is 125KHz, which means there may be 
; jitter on the waveform of up to 8uS. If this Waveloop is used to generate
; reference signals, a low pass filter after the DAC is recommended.
;
; This WaveLoop operates until the PIC is reset

; HOW TO - change the Wave shape
;
; calculate 32 points in your waveform, remembering that 00 corresponds to 
; the most negative output of the DAC and ff the most positive output. 
; Alter the code in "init_wav" to your calculated values.  In the case
; where you wish to use this loop to generate a logic sequence, make a 
; Logic State table of 32 values and edit these into the code.
; The 32 values will be repeated indefinitely, at the rate determined by the
; Phase Increment register.

; HOW TO - set the loop frequency
;
; The control registers for this WaveLoop are the Phase accumulator and 
; the Phase Increment register. Both of these registers are 32 bits (4 bytes)
; in the form of integer.fraction binary numbers. This means that the msb (most
; signifigant byte) represents a integer number of steps through the 32 byte 
; wave table, and the other 3 bytes represent a 24 bit binary fraction of a step.
; The Phase accumulator is usually set at 0.000 - as the initial value is of 
; no interest. For a logic sequencer this may not be true and it should be 
; set accordingly.
; The Phase Increment parameter represents the exact number of steps (a.bcd) 
; that the phase accumulator is advanced each loop (8uS). The value to advance 
; 1 step per loop is 1.000. This will result in all 32 table entries being output
; in 32 x 8uS (256uS or F=3.90625KHz)
; In general, this means that the frequency of the waveform will be calculated
;
; F = 3906.25 x Phase_Inc Hz
;
; OR
;
; Phase_Inc = F / 3906.25
;
; To make a 100Hz waveform, we would calculate the Phase Increment as:-
;
; Phase_Inc = 100/3906.25
;           = 0.0256
;
; Convert this to a binary number - 16,777,216 x 0.0256  = 429497
; Which is 0.068db9  - the binary (int.frac) corresponding to 0.0256
; What will happen here is that about every 39 loops, the Phase accumulator
; will advance by one step.
;
; To make a 1000Hz waveform, we would calculate the Phase Increment as:-
;
; Phase_Inc = 1000/3906.25
;           = 0.256
;
; Convert this to a binary number - 16,777,216 x 0.0256  = 4,294,967
; Which is 00.418937  - the binary (int.frac) corresponding to 0.256
; What will happen here is that about every 4 loops, the Phase accumulator
; will advance by one step.

; HOW TO - make a very slow logic sequencer
;
; If the Phase Increment registers are set to 00.000001 (hex), this will mean that 
; each step through the 32 entry table will require 2^24 (16,777,216) 8uS loops
; to execute. This is 134.2 seconds - quite a long time. At this rate it will 
; take just over an hour to step through all 32 table entries.

; APPLICATIONS
;
; counter, pattern generator
; with DAC arbitrary waveform generator
; 32 step oscillator, 8 uS step
; frequency synth

waveloop_15                         ; initialize the 32 registers with 
                                    ; the wave table (sine wave)
; put in the values of a full scale sine wave

init_wav
        movlw   128                 ; WAV-0
        movwf   WAV_16              ; put it in RAM table
        movlw   153                 ; WAV-1
        movwf   WAV_17              ; put it in RAM table
        movlw   177                 ; WAV-2
        movwf   WAV_18              ; put it in RAM table
        movlw   199                 ; WAV-3
        movwf   WAV_19              ; put it in RAM table
        movlw   219                 ; WAV-4
        movwf   WAV_20              ; put it in RAM table
        movlw   234                 ; WAV-5
        movwf   WAV_21              ; put it in RAM table
        movlw   246                 ; WAV-6
        movwf   WAV_22              ; put it in RAM table
        movlw   253                 ; WAV-7
        movwf   WAV_23              ; put it in RAM table
        movlw   255                 ; WAV-8
        movwf   WAV_24              ; put it in RAM table
        movlw   253                 ; WAV-9
        movwf   WAV_25              ; put it in RAM table
        movlw   246                 ; WAV-10
        movwf   WAV_26              ; put it in RAM table
        movlw   234                 ; WAV-11
        movwf   WAV_27              ; put it in RAM table
        movlw   219                 ; WAV-12
        movwf   WAV_28              ; put it in RAM table
        movlw   199                 ; WAV-13
        movwf   WAV_29              ; put it in RAM table
        movlw   177                 ; WAV-14
        movwf   WAV_30              ; put it in RAM table
        movlw   153                 ; WAV-15
        movwf   WAV_31              ; put it in RAM table
        movlw   128                 ; WAV-16
        movwf   WAV_32              ; put it in RAM table
        movlw   103                 ; WAV-17
        movwf   WAV_33              ; put it in RAM table
        movlw   79                  ; WAV-18
        movwf   WAV_34              ; put it in RAM table
        movlw   57                  ; WAV-19
        movwf   WAV_35              ; put it in RAM table
        movlw   37                  ; WAV-20
        movwf   WAV_36              ; put it in RAM table
        movlw   22                  ; WAV-21
        movwf   WAV_37              ; put it in RAM table
        movlw   10                  ; WAV-22
        movwf   WAV_38              ; put it in RAM table
        movlw   3                   ; WAV-23
        movwf   WAV_39              ; put it in RAM table
        movlw   1                   ; WAV-24
        movwf   WAV_40              ; put it in RAM table
        movlw   3                   ; WAV-25
        movwf   WAV_41              ; put it in RAM table
        movlw   10                  ; WAV-26
        movwf   WAV_42              ; put it in RAM table
        movlw   22                  ; WAV-27
        movwf   WAV_43              ; put it in RAM table
        movlw   37                  ; WAV-28
        movwf   WAV_44              ; put it in RAM table
        movlw   57                  ; WAV-29
        movwf   WAV_45              ; put it in RAM table
        movlw   79                  ; WAV-30
        movwf   WAV_46              ; put it in RAM table
        movlw   103                 ; WAV-31
        movwf   WAV_47              ; put it in RAM table

; initialize the phase accumulator and the phase offset

        movlw   0x00                ; Phase Accumulator msb
        movwf   WAV_11              ; put in register
        movlw   0x00                ; Phase Accumulator 
        movwf   WAV_10              ; put in register
        movlw   0x00                ; Phase Accumulator 
        movwf   WAV_9               ; put in register
        movlw   0x00                ; Phase Accumulator lsb
        movwf   WAV_8               ; put in register


; put in here the example values to give a 1KHz wave

        movlw   0x00                ; Phase increment msb
        movwf   WAV_15              ; put in register
        movlw   0x41                ; Phase increment 
        movwf   WAV_14              ; put in register
        movlw   0x89                ; Phase increment 
        movwf   WAV_13              ; put in register
        movlw   0x37                ; Phase increment lsb
        movwf   WAV_12              ; put in register

; all the initial values of the registers are now set.

; this is the main loop which takes 8uS to complete.

l_15_1
        movlw   0x1f                ; mask for 5 bits of phase
        andwf   WAV_11,W            ; get the 5 msbs into W
        addlw   WAV_16              ; offset from VMR-16
        movwf   FSR                 ; put in reg pointer

        movf    INDF,W              ; put the reg in W
        movwf   PORTB               ; that is it!
                                    
                                    ; next step is to increment the phase

; 32 bit addition for phase + increment -> phase

        movf    WAV_12,W            ; get the lsb of increment
        addwf   WAV_8,F             ; add it to the lsb of phase
        clrz                        ; explicitly clear Z bit
        skpnc                       ; did we get a carry?
        setz                        ; yes - mirror it in Z bit
                                    ; ripple it up the 3 higher bytes
        skpnz                       ;
        incf    WAV_9,F             ;
        skpnz                       ;
        incf    WAV_10,F            ;
        skpnz                       ;
        incf    WAV_11,F            ;

        movf    WAV_13,W            ; get next byte
        addwf   WAV_9,F             ; add to phase
        clrz                        ; explicitly clear Z bit
        skpnc                       ; carry?
        setz                        ; yes - mirror it in Z bit
                                    ; ripple it up 2 bytes
        skpnz                       ;
        incf    WAV_10,F            ;
        skpnz                       ;
        incf    WAV_11,F            ;

        movf    WAV_14,W            ; get the next byte
        addwf   WAV_10,F            ; add to phase
        clrz                        ; explicitly clear Z bit
        skpnc                       ; carry?
        setz                        ; yes - mirror it in Z bit
                                    ; ripple it up last byte
        skpnz                       ;
        incf    WAV_11,F            ;

        movf    WAV_15,W            ; get the MSB
        addwf   WAV_11,F            ; and put in phase
                                    ; we don't care about C
        nop
        nop
        nop
        
        goto    l_15_1              ; loop again   
                                    ; loop is 40 instructions  (8uS)