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!!! |
|
Why is this VC33 DSK code unreliable!!
Started by ●April 13, 2004
Reply by ●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 |