📄 dac_ctrl.psm
字号:
store_channel_B: STORE s0, chan_B_lsb ;store value for D/A output
STORE s1, chan_B_msb
;
;
;Channel C is a square wave of 2KHz.
;
;Since the sample rate is 8KHz, this square wave is formed of two samples at a
;low level and two samples at a high level. This is used to demonstrate when the
;D/A converter output actually changes and how to determine the voltage levels.
;It is also used indirectly to form the signal for channel A.
;
;The low level voltage is 0.50v.
; The 12-bit value is therefore 4096 x 0.5 / 2.5 = 819 (333 hex)
;
;The high level voltage is 2.00v.
; The 12-bit value is therefore 4096 x 2.0 / 2.5 = 3277 (CCD hex)
;
;
FETCH s2, square_count ;read sample counter
TEST s2, 02 ;bit 1 has correct frequency
JUMP NZ, square_high
LOAD s1, 03 ;Set low level
LOAD s0, 33
JUMP store_channel_C
square_high: LOAD s1, 0C ;Set high level
LOAD s0, CD
store_channel_C: STORE s0, chan_C_lsb ;store value for D/A output
STORE s1, chan_C_msb
ADD s2, 01 ;increment sampel count
STORE s2, square_count ;store new sample count
;
;Sine wave for channel D
;
;A synthesis algorithm is used to generate a stable 770Hz sine wave
;which is one of the 8 tines used in DTMF telephone dialing.
;
CALL calc_next_sine
SR0 s9 ;reduce value to 12-bits
SRA s8
SR0 s9
SRA s8
SR0 s9
SRA s8
ADD s9, 08 ;Scale signed number to mid-rail of unsigned output
STORE s9, chan_D_msb ;store value for D/A output
STORE s8, chan_D_lsb
;
;
;Drive LEDs with simple binary count of the samples to indicate
;that the design is active.
;
FETCH s0, sample_count_lsb ;read sample counter
FETCH s1, sample_count_msb
ADD s0, 01 ;increment counter
ADDCY s1, 00
STORE s0, sample_count_lsb ;store new value
STORE s1, sample_count_msb
OUTPUT s1, LED_port ;upper bits are 31.25Hz and lower
;
JUMP warm_start ;wait for next interrupt
;
;**************************************************************************************
;Sine wave synthesis algorithm
;**************************************************************************************
;
;This example is set to generate 770Hz at a sample rate of 8KHz. 770Hz is one of
;the eight DTMF frequences. Please see design documentation for more details.
;
init_sine_wave: LOAD s0, 24 ;initial value 9216 (2400 hex)
STORE s0, sine_y_msb
LOAD s0, 00
STORE s0, sine_y_lsb
LOAD s0, 00 ;initial delayed value 0 (0000 hex)
STORE s0, sine_y1_msb
STORE s0, sine_y1_lsb
LOAD s0, D2 ;Coefficient for 770Hz is UFIX_16_15 value 53913/32768 = 1.64529
STORE s0, sine_k_msb
LOAD s0, 99
STORE s0, sine_k_lsb
RETURN
;
;
;Calculate a new output sample for a single tone.
;
;The tone sample is generated as a 16-bit signed integer.
;The waveform is virtually full scale deflection for a 15-bit integer
;such that the addition of two tones for DTMF will not exceed the 16-bits
;provided by two registers.
;
;Obtain current values from wscratch pad memory
;
calc_next_sine: FETCH sF, sine_y_msb ;[sF,sE] is Y
FETCH sE, sine_y_lsb
FETCH sD, sine_y1_msb ;[sD,sC] is Y1
FETCH sC, sine_y1_lsb
FETCH sB, sine_k_msb ;[sB,sA] is K
FETCH sA, sine_k_lsb
;
;16-bit signed by 16-bit unsigned multiplication. [s9,s8]=[sB,sA]x[sF,sE]
;
;The unsigned number is of format UFIX_16_15 resulting
;in a FIX_32_15 product. Since only the integer part of the
;product is to be retained as a 16-bit value, their is no
;shift of the result on the last cycle of the multiplication.
;Execution requires a maximum of 145 instructions.
;
LOAD s9, 00 ;clear temporary result registers [s9,s8]
LOAD s8, 00
LOAD s0, 10 ;16 bit multiply
mult_loop: SRX s9 ;signed divide result by 2
SRA s8
SR0 sB ;shift coefficient
SRA sA
JUMP NC, no_mult_add ;test for active bit
ADD s8, sE ;16-bit signed addition
ADDCY s9, sF
no_mult_add: SUB s0, 01 ;test for 16 cycles
JUMP NZ, mult_loop
;
;Subtract of delayed sample
;
SUB s8, sC ;16-bit signed subtract
SUBCY s9, sD
;
;Update scratch pad memory with new sample values
;
STORE sF, sine_y1_msb ;delayed sample gets previous output
STORE sE, sine_y1_lsb
STORE s9, sine_y_msb ;new current sample
STORE s8, sine_y_lsb
RETURN
;
;
;**************************************************************************************
;SPI communication routines for D/A Converter
;**************************************************************************************
;
;These routines will work with two output ports and one input port which should be
;defined as follows using CONSTANT directives.
; (replace 'pp' with appropriate port address in each case)
;In the list of CONSTANT directives, only the ones marked with a * are really required
;for the D/A Converter system. The other directives are to control (disable) or
;communicate with the other SPI components on the same SPI bus of the Spartan-3E Starter Kit.
;
;
;
;CONSTANT SPI_control_port, pp ;SPI clock and chip selects *
;CONSTANT SPI_sck, 01 ; SCK - bit0 *
;CONSTANT SPI_rom_cs, 02 ; serial rom select - bit1
;CONSTANT SPI_spare_control, 04 ; spare - bit2
;CONSTANT SPI_amp_cs, 08 ; amplifier select - bit3
;CONSTANT SPI_adc_conv, 10 ; A/D convert - bit4
;CONSTANT SPI_dac_cs, 20 ; D/A select - bit5 *
;CONSTANT SPI_amp_shdn, 40 ; amplifier SHDN - bit6
;CONSTANT SPI_dac_clr, 80 ; D/A clear - bit7 *
;
;CONSTANT SPI_output_port, pp ;SPI data output *
;CONSTANT SPI_sdo, 80 ; SDO - bit7 *
;
;CONSTANT SPI_input_port, pp ;SPI data input *
;CONSTANT SPI_sdi, 80 ; SDI - bit7 *
;CONSTANT SPI_amp_sdi, 40 ; amplifier SDI - bit6
;
;
;
;
;Initialise SPI bus
;
;This routine should be used to initialise the SPI bus.
;The SCK clock is made low.
;Device selections are made inactive as follows
; SPI_sck = 0 Clock is Low (required)
; SPI_rom_cs = 1 Deselect ROM
; spare = 1 spare control bit
; SPI_amp_cs = 1 Deselect amplifier
; SPI_adc_conv = 0 A/D convert ready to apply positive pulse
; SPI_dac_cs = 1 Deselect D/A
; SPI_amp_shdn = 0 Amplifier active and available
; SPI_dac_clr = 1 D/A clear off
;
SPI_init: LOAD s0, AE ;normally AE
OUTPUT s0, SPI_control_port
RETURN
;
;
;
;Send and receive one byte to and from the SPI D/A converter.
;
;The data supplied in register 's2' is transmitted to the SPI bus and
;at the same time the received byte is used to replace the value in 's2'.
;The SCK clock is generated by software and results in a communication rate of
;2.5Mbit/s with a 50MHz clock.
;
;Note that you must have previously selected the required device on the bus
;before attempting communication and you must subsequently deselect the device
;when appropriate.
;
;Entry to this routine assumes that register s0 defines the state of the SPI
;control signals including SCK which should be Low. The easiest way to achieve this is
;to use the SPI_init routine before calling this one for the first time.
;
;As a 'master' the signal sequence is as follows..
; Transmit data bit on SDO line
; Drive SCK transition from low to high
; Receive data bit from SDI line (D/A transmits on previous falling edge)
; Drive SCK transition from high to low.
;
;Important note
; The received data bit must be captured some time before SCK goes low.
; However the combination of relatively slow clock to output time of the
; LTC2624 combined with the low drive strength of its SDO output means that
; the received bit needs maximum time to settle. Therefore this routine
; schedules the read as late as it can.
;
SPI_dac_tx_rx: LOAD s1, 08 ;8-bits to transmit and receive
next_SPI_dac_bit: OUTPUT s2, SPI_output_port ;output data bit ready to be used on rising edge
XOR s0, SPI_sck ;clock High (bit0)
OUTPUT s0, SPI_control_port ;drive clock High
XOR s0, SPI_sck ;prepare clock Low (bit0)
INPUT s3, SPI_input_port ;read input bit
TEST s3, SPI_sdi ;detect state of received bit
SLA s2 ;shift new data into result and move to next transmit bit
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -