This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TMS320F2806 ADC duplicating sample values eight times



I have a simple polling loop in assembly called by a C application.

100MHz system clock.

SysCtrlRegs.HISPCP.all = 4; // HSPCLK = SYSCLKOUT/ADC_MODCLK   12.5 MHz (from examples)

I set up trying both single sample (0,0,0) and continuous with override (0,1,1)

I have 15 for ACQ_PS

	// Specific ADC setup for this example:
AdcRegs.ADCTRL1.all = 0x0F60;
//		AdcRegs.ADCTRL1.bit.SEQ_CASC = 0;        	// 0 not  Cascaded mode
//		AdcRegs.ADCTRL1.bit.CONT_RUN = 1;       	// Setup continuous run
//		AdcRegs.ADCTRL1.bit.SEQ_OVRD = 1;       	// Enable Sequencer override feature
//		AdcRegs.ADCTRL1.bit.ACQ_PS = ADC_SHCLK;  	// Simultaneous single-shot mode: Sample rate   = 1/[(2+2.5+ACQ_PS)*ADC clock in ns]
													// = 1/(23.5*80ns) = 1/1880ns = 532KHz (for 100 MHz devices) before ADCTRL3.ADCCLKPS

	AdcRegs.ADCTRL2.all = 0;
	//	      AdcRegs.ADCTRL2.bit.SOC_SEQ1 = 1;			// start
	//	      AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1;			// stop

	AdcRegs.ADCTRL3.all = 0x00E2; //0x00E4;
	//AdcRegs.ADCTRL3.bit.ADCCLKPS = ADC_CKPS;	// 1.820 us * factor --> start with 4x (0x02)
	//AdcRegs.ADCTRL3.bit.SMODE_SEL= 0;			// simultaneously take (but ignore) B4 so we can use SOCB out pin

	AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 0x0;  // convert and store in 1 result register

	AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x02;	// ADC channel A2

I have tried both AdcRegs and AdcMirror.

Assembler receives a pointer to array, starts ADC, waits for INT_SEQ1, clears the interrupt flag, stores the sample, and reloops for the next point.  The numbers are reasonable, but they are identical for 8 loops then change only every 8 samples.

FP	.set	XAR2
	.sect	".text"
	.global _asmMeasSamp
	.global _AdcRegs
	.global _AdcMirror

_asmMeasSamp:
        ADDB      SP,#2                 ;
;----------------------------------------------------------------------
;  39 | // start measurement
;  40 | AdcRegs.ADCTRL2.bit.SOC_SEQ1 = 1;                       // start
;----------------------------------------------------------------------
        MOVW      DP,#_AdcRegs+25       ;
        OR        @_AdcRegs+1,#0x2000   ;
;----------------------------------------------------------------------
;  27 | int i = 4096;                                                          
;  28 | loop:                                                                  
;----------------------------------------------------------------------
        SETC      SXM                   ; [CPU_] 
        MOV       *-SP[1],#2048         ; [CPU_] |27|
;----------------------------------------------------------------------
;  27 | while(!AdcRegs.ADCST.bit.INT_SEQ1)
;----------------------------------------------------------------------
WAITADC:
        MOVW      DP,#_AdcRegs+25       ;
        TBIT      @_AdcRegs+25,#0       ;
   		BF		  WAITADC,NTC			;
;----------------------------------------------------------------------
;  32 | AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;
;----------------------------------------------------------------------
        OR        @_AdcRegs+25,#0x0010  ;
;----------------------------------------------------------------------
;  29 | Samples[4095-i] = AdcRegs.ADCRESULT2;                                       
;----------------------------------------------------------------------
        MOVW      DP,#_AdcMirror     ; first tried AdcRegs+10  ;
        MOV       AL,@_AdcMirror       ; [CPU_] |29|
        ;LSL       ACC,3                 ;  Value is in ACC as Q12, make Q15
        MOV       *+XAR4[0],AL          ; [CPU_] |29| 
        ADDB      XAR4,#1               ; XAR4[i]
;----------------------------------------------------------------------
;  39 | // restart measurement
;  40 | AdcRegs.ADCTRL2.bit.SOC_SEQ1 = 1;                       // start
;----------------------------------------------------------------------
        ;OR        @_AdcRegs+1,#0x2000   ; comment if continuous mode;
;----------------------------------------------------------------------
;  30 | if (i--) goto loop;                                                    
;----------------------------------------------------------------------
        DEC       *-SP[1]               ; [CPU_] |30|
        BF        WAITADC,NEQ             ; [CPU_] |30|
;----------------------------------------------------------------------
;  31 | return;                                                                
;----------------------------------------------------------------------
        SUBB      SP,#2                 ; [CPU_U]
        LRETR     ; [CPU_] 

The code behaves the same regardless of continuous mode or single-shot.

Somehow I am getting 8 identical readings followed by a jump in value.

I could accept this if the jumps between sets were on the order of the real resolution (+/- 2) but there are significant jumps.

 Assumptions:

1) HISPCP.all = 4; gives 12.5 MHz as per the examples I looked at.  Just to be sure, I divided by 8 and still see the repetition.

2) INT_ENA_SEQ1 is zero unless I want to use an ISR.  I do not.  I just want flag set on data ready.

3) INT_MOD_SEQ1 is zero - I want a flag per sample.

4) ADCCLKPS = 1 or 2 should not affect anything except sampling rate.

5) In the debugger I see the flag set and clear as I step through.  The flag is set at the end of the sequence.  I *assume* this means the conversion is ready.  Even if not, I'd assume I would get a different conversion every time, one sample late or get corrupted and nonsensical values.

6) I assume the zero wait state mirror is loaded and available at the same time as the base result, just reads faster.  Do I need to delay between the INT flag and reading the register??

  • OK, I still do not know why stopping and starting conversions was not working, but the example I posted with continuous conversios should NOT have had sequence override set.  After re^nth-reading the datasheets I see that it caused the full 8 conversion sequence to run despite MaxConv...but I kept reading the same register 8 times.