WavePOD WaveLoop F

 Smart Port Wave POD Waveforms
```;*************************************************************************
; 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
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
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
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)
```