Hi guys,
I'm using QE128 bit bang to a Analog Device's DAC AD5308 which it has a 16-bit register instead of 8-bit. So I guess I can't use the i2c peripheral.
I've managed to write an assembler code for this application. However, I'd like to enhance my code efficiency which I think my code isn't that efficient.
DACDTA ds.B 2 DACBUF ds.B 1 DTACNT ds.B 1 txdac sthx DACDTA ;load data to DACDTA lda DACDTA+1 ;load hi-byte sta DACBUF lda #$00 sta SR txdacnxt lda #$07 ;setup data count sta DTACNT bclr SYNCDAC,PTBD ;clr SYNC to start tx txdac0 bclr SCLDAC,PTAD ;pulse clk jsr TDelay bset SCLDAC,PTAD lda DACBUF ;load data to acc asla ;left shift acc bcs txdac1 ;chk if carry = 1 bclr SDADAC,PTAD ;if /=1,clr SDA bra txdac2 txdac1 bset SDADAC,PTAD ;if =1,set SDA txdac2 jsr TDelay dbnz DTACNT,txdac0 ;dec data count to chk byte tx txdac3 brset 0,SR,txdac4 ;chk if hi-byte done tx bset 0,SR lda DACDTA+0 ;load lo-byte sta DACBUF bra txdacnxt ;repeat tx txdac4 bset SYNCDAC,PTBD ;clr SYNC to end tx rts
Please advise.
Hello Ming Yee,
The AD5308 actually uses an SPI interface, and it should be feasible to use the SPI hardware peripheral for better efficiency. Simply send the data as two bytes in succession, whilst the SYNC line is held low. The SYNC and LDAC lines would be GPIO pins.
; On entry, H:X = data word to be sent
DAC_send: SYNC_LOW ; Macro
LDA SPI1S
PSHH
PULA
STA SPI1D ; Send high byte
BRCLR SPI1S_SPRF,SPI1S,* ; Wait for transfer complete
LDA SPI1D ; Read register to clear flag
STX SPI1D ; Send low byte
BRCLR SPI1S_SPRF,SPI1S,* ; Wait for transfer complete
LDA SPI1D ; Read register to clear flag
SYNC_HIGH ; Macro
LDAC_PULSE ; Macro
RTS
Regards,
Mac
Hi bigmac,
I guess i cant use SPI interface as the only spare port i have on the pcb is i2c. Guess I will have to deal with the bit bang method.
I will take the SPI example for the next version of PCB which i am able to cater spi for it.
Thanks.
Regards,
MY
Hello Ming Yee,
For the bit-bang version, my approach would probably be a little different than yours. I would tend to use the stack, rather than create RAM variables. Additionally, the shift process could be tackled as a single 16-bit word, rather than two separate bytes. This should make the code a little less complex.
The following code demonstrates this approach. I have also created macros for the hardware interface, to make the code a little easier to follow. It also means that, should the hardware configuration ever alter, only the macros need to be changed to suit the new configuration.
SYNC_LOW: macro
bclr SYNCDAC,PTBD
endm
SYNC_HIGH:macro
bset SYNCDAC,PTBD
endm
CLK_LOW: macro
bclr SCLDAC,PTBD
endm
CLK_HIGH: macro
bset SCLDAC,PTBD
endm
SDO_LOW: macro
bclr SDADAC,PTBD
endm
SDO_HIGH: macro
bset SDADAC,PTBD
endm
TXDAC: lda #16 ; Bit count
psha ; (3,sp)
pshx ; LS byte (2,sp)
pshh ; MS byte (1,sp)
CLK_LOW ; Initialise clock state
SYNC_LOW ; SYNC low to enable send
TXD1: CLK_LOW ;[5] Strobe current data
; Left-shift data word
lsl 2,sp ;[6] LS byte
rol 1,sp ;[6] MS byte
; Set serial data output bit state
bcs TXD2 ;[3]
SDO_LOW ;[5] SDO = 0
bra TXD3 ;[3] Branch always
TXD2: SDO_HIGH ;[5] SD0 = 1
TXD3:
CLK_HIGH ;[5] Return serial clock high
dbnz 3,sp,TXD1 ;[8] Loop for next bit
CLK_LOW ;[5] Strobe last bit
SYNC_HIGH ; SYNC high to end send
ais #3 ; Adjust stack pointer
rts
Note that the clock period is 38 cycles, so the communications will be very slow (260 kHz for a 10MHz bus frequency). The period allowed for the data to settle is 18 cycles.
Regards,
Mac
Hi guys,
This is my updated routine which i found some bug in the earlier one.
Thanks.
txdac sthx DACDTA ;load data to DACDTA lda DACDTA+0 ;load hi-byte sta DACBUF lda #$00 sta DACF txdacnxt lda #$08 ;setup data count sta DTACNT bclr SYNCDAC,PTBD ;clr SYNC to start txtxdac0 jsr TDelay bset SCLDAC,PTAD ;pulse clk lda DACBUF ;load data to acc asla ;left shift acc sta DACBUF bcs txdac1 ;chk if carry = 1 bclr SDADAC,PTAD ;if /=1,clr SDA bra txdac2txdac1 bset SDADAC,PTAD ;if =1,set SDAtxdac2 jsr TDelay bclr SCLDAC,PTAD dbnz DTACNT,txdac0 ;dec data count to chk byte tx txdac3 brset 0,DACF,txdac4 ;chk if hi-byte done tx bset 0,DACF lda DACDTA+1 ;load lo-byte sta DACBUF bra txdacnxt ;repeat txtxdac4 bset SYNCDAC,PTBD ;clr SYNC to end tx rts
Regards.
MY
Hi can anyone tell me why the code i posted looks so weird ??
I clicked on the Code tab but seems like there is still some HTML issue.
I tried removing it n redo it, i still get the same result.
Please advise.
Thanks.
MY
mingyee wrote:Hi guys,
This is my updated routine which i found some bug in the earlier one.
Thanks.
txdac sthx DACDTA ;load data to DACDTA lda DACDTA+0 ;load hi-byte sta DACBUF lda #$00 sta DACF txdacnxt lda #$08 ;setup data count sta DTACNT bclr SYNCDAC,PTBD ;clr SYNC to start txtxdac0 jsr TDelay bset SCLDAC,PTAD ;pulse clk lda DACBUF ;load data to acc asla ;left shift acc sta DACBUF bcs txdac1 ;chk if carry = 1 bclr SDADAC,PTAD ;if /=1,clr SDA bra txdac2txdac1 bset SDADAC,PTAD ;if =1,set SDAtxdac2 jsr TDelay bclr SCLDAC,PTAD dbnz DTACNT,txdac0 ;dec data count to chk byte tx txdac3 brset 0,DACF,txdac4 ;chk if hi-byte done tx bset 0,DACF lda DACDTA+1 ;load lo-byte sta DACBUF bra txdacnxt ;repeat txtxdac4 bset SYNCDAC,PTBD ;clr SYNC to end tx rts
Regards.
MY
Message Edited by mingyee on 2009-09-21 08:52 PM