Reply by Daniel DeBusschere April 21, 20042004-04-21
I took your sample code and made changes as follows that work. Using
the University VC33 DSK attach a SONY Walkman (tuned into a good
stereo FM station) or any MP3 player to the input jack and attach a
headphone to the output jack. Assemble the attached code with the
DSK assembler to get a sample.dsk file and load and go with either
DSK3D.EXE or DSK3DW.EXE. Compare this code to your code to find the
changes:

; **********************************************
; * Simple loopback for PCM3003 using VC33 DSK *
; **********************************************
GIE .set 0x2000 ; This bit in ST turns on interrupts
; .include "C3XMMRS.ASM" ; include the addresses for mem mapped
registers
.start "codec",0x809802 ; start assembling here in a safe place
.sect "codec"
.entry START ; on starting program go to this point
LRCIN .word 0x80A000 ; LRCIN is bit 4 of this location
S0_rst .word 0x2BF3000
S0_run .word 0xEBF3000
ADC_R .word 0x0
ADC_L .word 0x0
START ldp @START
ldi @stack,SP ; setup the stack
call AICINIT ; sets up the DSK.
or 0x34,IE ; Enable the XINT RINT INT2
; THE TIMER AND SERIAL PORT ARE NOW BOTH RUNNING - ENABLE INTTERUPT.
main or GIE,ST ; Turn on INTS
idle ; wait for interrupt
andn GIE,ST ; Turn off INTS
br main ; pointless endless loop.
; ***********************************
; * XINT0 Interrupt Service Routine *
; ***********************************
XINT0 push ST ; Interrupt service routine
push R0 ; save fp significance
pushf R0 ;
push AR1 ;
ldi @LRCIN,AR1 ;
ldi *AR1,R0 ;
and 0x10,R0 ; this isolates the LRCIN bit
bnz lft
ldi @ADC_R,R0
br shift
lft ldi @ADC_L,R0
shift lsh -12,R0
sti R0,@S0_xdata
pop AR1 ;
popf R0 ;
pop R0 ; restore significance
pop ST ;
reti
; ***********************************
; *RINT0 Interrupt Service Routine *
; ***********************************
RINT0 push ST ; Interrupt service routine
push R0 ; save fp significance
pushf R0 ;
push AR1 ;
ldi @LRCIN,AR1 ;
ldi *AR1,R0 ;
; Sample the LRCIN bit, and then store the data in the right place
and 0x10,R0 ; isolated the LRCIN bit
bnz left
right ldi @S0_rdata,R0
sti R0,@ADC_R
br fin_int
left ldi @S0_rdata,R0
sti R0,@ADC_L
fin_int
pop AR1 ;
popf R0 ;
pop R0 ; restore significance
pop ST ;
reti
; **************************************************
; * CODE TO INITIALISE THE TIMER AND SERIAL PORTS. *
; **************************************************
; params for aic PCM3003 initialization ;
; *****************************************************;
T0_ctrl .set 0x808020 ; TIM0 gl control
T0_count .set 0x808024 ; TIM0 count
T0_prd .set 0x808028 ; TIM0 prd
T1_ctrl .set 0x808030 ; TIM1 gl control
T1_count .set 0x808034 ; TIM1 count
T1_prd .set 0x808038 ; TIM1 prd
S0_gctrl .set 0x808040 ; SP 0 global control
S0_xctrl .set 0x808042 ; SP 0 FSX/DX/CLKX port ctl
S0_rctrl .set 0x808043 ; SP 0 FSR/DR/CLKR port ctl
S0_xdata .set 0x808048 ; SP 0 Data transmit
S0_rdata .set 0x80804C ; SP 0 Data receive
TIM0_PRD .set 2 ; Timer diviser
S0_gctrl_val .word 0x0E970300 ; Serial port control register values
S0_xctrl_val .word 0x00000111 ;
S0_rctrl_val .word 0x00000111 ;
;--------------------------------
XCLKSRCE .set 0 << 6 ; 0=external 1= internal
RCLKSRCE .set 0 << 7 ;
XVAREN .set 0 << 8 ; VAREN 0 1
RVAREN .set 0 << 9 ; FS ____---------_____
XFSM .set 0 <<10 ; 0=burst 1=continuous
RFSM .set 0 <<11 ;
CLKXP .set 1 <<12 ;
CLKRP .set 1 <<13 ;
DXP .set 0 <<14 ;
DRP .set 0 <<15 ;
FSXP .set 1 <<16 ;
FSRP .set 1 <<17 ;
XLEN .set 11b<<18 ; 00=8 01 10$ 112
RLEN .set 11b<<20 ;
EXTINT .set 0 <<22 ;
EXINT .set 1 <<23 ;
ERTINT .set 0 <<24 ;
ERINT .set 1 <<25 ;
S0 .sdef
XCLKSRCE|RCLKSRCE|XVAREN|RVAREN|XFSM|RFSM|CLKXP|CLKRP
S0 .sdef S0|DXP|DRP|FSXP|FSRP|EXTINT|EXINT|ERTINT|ERINT
SPBITS .set 32
BITSEL .set ((SPBITS/8)-1) // 0=8, 1, 2$ and 32 bits
S0 .sdef S0|(BITSEL<<18)|(BITSEL<<20)
S0gctrl_rst .word S0
S0gctrl_run .word S0|0x0C000000
S0xctrl .set 0x00000111
S0rctrl .set 0x00000111
S0cpld .word 0x80A000 // CPLD status byte contains LRCIN
;====================================================================
; initializes the serial port, codec and timers
; JP4
; Pins 1-2 16bit open; 32bit short
; Pins 3-4 DEM1 short to pullup (Deemphasis 1)
; Pins 5-6 DEM0 short to pullup (Deemphasis 0)
; JP1
; Pins 1-2 short to AVDD Mic channel 1
; Pins 3-4 short to AVDD Mic channel 2
;====================================================================
AICINIT:
ldi 0x00,R0 ; halt the timer
sti R0,@T0_ctrl
ldi 0x03, R0 ; put a count in prd
sti R0,@T0_prd
ldi 0x283,R0 ; set bits to start timer
sti R0,@T0_ctrl ; timer is now running!
ldi 0,R0 ;
sti R0,@T0_count ; T0_count = 0
;------------------------------
ldi S0xctrl,R0 ; Init xmit/recv pin control
sti R0,@S0_xctrl ; S0_xctrl = S0xctrl
; transmit control
ldi S0rctrl,R0 ;
sti R0,@S0_rctrl ; S0_rctrl = S0rctrl
; receive control
ldi @S0gctrl_rst,R0 ; Reset serial port
sti R0,@S0_gctrl ; S0_gctrl = S0gctrl_rst
ldi @S0gctrl_run,R0 ; Run serial port
sti R0,@S0_gctrl ; S0_gctrl = S0gctrl_run
ldi 0,R0 ;
sti R0,@S0_rdata ;
sti R0,@ADC_L ;
sti R0,@ADC_R ;
rets ; return from subroutine
; *****************************
; * STACK *
; *****************************
stack .word $+1 ; the word at stack is the address of the next cell
; Now install the interrupt vector
.start "int_vects", 0x809FC5 ; here's where the XINT0 vector is
.sect "int_vects" ; name the section something
br XINT0
br RINT0
.end


Reply by richardwebb2000 April 13, 20042004-04-13
Hello. I've just started using the VC33 DSK and i'm starting off by
writing a basic bit of code to sample some values from the PCM3003
and send them straight back out (loopback). The code I have written
works ... sometimes. If i load the code into the DSK and run it, it
will often sit in the main loop and no interrupts from the codec
happen. If i stop and restart the code, or leave it running long
enough it will suddenely start working! I don't understand this!
Something is causing interrupts to not be trigger, but i don't see
how this can be intermittant.
Also with the code I have written the LRCIN bit read in the from
CPLD doesn't ever seem to change, so my decision sections are never
executed properly, and sample is taken in and stored in the ADC_L
location only. I hope someone can help me solve these issues.

Many thanks,
Rich W.

; **********************************************
; * Simple loopback for PCM3003 using VC33 DSK *
; **********************************************

.include "C3XMMRS.ASM" ; include the addresses for
mem mapped registers
.start "codec", 0x809802 ; start assembling here in a
safe place
.sect "codec"
.entry START ; on starting program go to
this point LRCIN .word 0x80A000 ; LRCIN is bit 4 of this
location
S0_rst .word 0x2BF3000
S0_run .word 0xEBF3000
ADC_R .word 0x0
ADC_L .word 0x0

START ldp @START
ldi @stack, SP ; setup the stack
call AICINIT ; sets up the DSK. main nop
br main ; pointless endless loop.

; ***********************************
; * XINT0 Interrupt Service Routine *
; ***********************************

XINT0 ldi @LRCIN,R0
and 0x10,R0 ; this isolates the LRCIN bit
bnz lft
ldi @ADC_R,R0
br shift
lft ldi @ADC_L,R0
shift lsh -12,R0
sti R0,@S0_xdata
reti

; ***********************************
; *RINT0 Interrupt Service Routine *
; ***********************************

RINT0 ldi @LRCIN,R0 ; Sample the LRCIN bit, and
then store the data in the right place
and 0x10,R0 ; isolated the LRCIN bit
bnz left
right ldi @S0_rdata,R0
sti R0,@ADC_R
br fin_int
left ldi @S0_rdata,R0
sti R0,@ADC_L
fin_int reti

; **************************************************
; * CODE TO INITIALISE THE TIMER AND SERIAL PORTS. *
; **************************************************
AICINIT push ST
push R0
pushf R0

ldp T0_ctrl
ldi 0x00, R0 ; halt the timer
sti R0,@T0_ctrl
ldi 0x03, R0 ; put a count in prd
sti R0,@T0_prd
ldi 0x283, R0 ; set bits to start timer
sti R0,@T0_ctrl ; timer is now running!

ldp S0_gctrl
ldi 0x00, R0
sti R0, @S0_gctrl ; This stop the serial port
operating.
ldi @S0_rst,R0
sti R0,@S0_gctrl ; Serial port setup but still
held stopped
ldi 0x111, R0
sti R0,@S0_xctrl ; set FSX control reg
ldi 0x111, R0
sti R0,@S0_rctrl ; set FSR control reg

; Ok the serial port is now setup correctly, we must start it
running.

ldi @S0_run,R0
sti R0,@S0_gctrl ; Global control now set to
run serial port.

ldi 0x0,R0
sti R0,@S0_xdata ; kick start xmit by sending
a zero.

; THE TIMER AND SERIAL PORT ARE NOW BOTH RUNNING - ENABLE
INTTERUPT.

or 0x2000, ST ; set the global interrupt
enable
or 0x34, IE ; Enable the XINT interrupt
(keepign INT2 active)
popf R0
pop R0
pop ST
rets ; return from subroutine

; *****************************
; * STACK *
; *****************************
stack .word $+1 ; the word at stack is the
address of the next cell ; Now install the interrupt vector

.start "int_vects", 0x809FC5 ; here's where the XINT0
vector is
.sect "int_vects" ; name the section something
br XINT0
br RINT0

.end ; stop assembling here!!!