Hi,
I'm using a Piccolo ControlSTICK (with a 28027 DSP) and are aiming to sample a signal at highest possible sample rate (4.6Msps). However, I have quite a lot of trouble when configuring my ADC.
First off, I get the feeling that the highest sample rate, 4.6Msps, might be very optimistic. When I've tried to do continuous sampling, even at lower sampling rates, I get problems that seems to be that I cant manage to process the adc results before next interrupt occurs. Sampling at 4.6 Msps seems to be a very big challenge if I have trouble sampling at 850ksps. Is it even theoretically possible to sample that fast with a 28027 running at 60 MHz? And if not, what can be the highest achievable sample rate?
Back to my problem.
As you can see in the attached code I use all SOCs, and they are triggered by ADCINT1. ADCINT1 is triggered by EOC14. In the ContinousAdc-example EOC14 triggers ADCINT1, so I did that too. With INT1CONT set and the round-robin principle I suppose ADCIN1 should be sampled at a periodic rate?
This is a graph of my buffer (currently 256 bytes, theres a 4KHz sine on ADCIN1):

The reason for using all SOCs was basically that it might be possible to copy the ADC result in the interrupt without stalling the next ADC interrupt while doing so. Im not sure if this is the way to do it though. Any suggestions?
I use the internal clock at 60MHz.
A related question; In the errata, problems with "Initial conversion" is mentioned. If I sample continuously, will every 16th value be corrupt, or will be jst be the first value in my buffer?
Best regards
Henrik Karlsson
This is the code:
static uint16_t m_adcBuffer[ADC_BUFFER_SIZE];
static uint16_t *m_pAdcBuffer = m_adcBuffer;
static uint16_t *m_pAdcBufferEnd;
//@} End of Data
//////////////////////////////////////////////////////////////////////
/// @name Private Methods
//@{
interrupt void adc_isr(void)
{
    *m_pAdcBuffer++ = AdcResult.ADCRESULT0;
    *m_pAdcBuffer++ = AdcResult.ADCRESULT1;
    *m_pAdcBuffer++ = AdcResult.ADCRESULT2;
    *m_pAdcBuffer++ = AdcResult.ADCRESULT3;
    *m_pAdcBuffer++ = AdcResult.ADCRESULT4;
    *m_pAdcBuffer++ = AdcResult.ADCRESULT5;
    *m_pAdcBuffer++ = AdcResult.ADCRESULT6;
    *m_pAdcBuffer++ = AdcResult.ADCRESULT7;
    *m_pAdcBuffer++ = AdcResult.ADCRESULT8;
    *m_pAdcBuffer++ = AdcResult.ADCRESULT9;
    *m_pAdcBuffer++ = AdcResult.ADCRESULT10;
    *m_pAdcBuffer++ = AdcResult.ADCRESULT11;
    *m_pAdcBuffer++ = AdcResult.ADCRESULT12;
    *m_pAdcBuffer++ = AdcResult.ADCRESULT13;
    *m_pAdcBuffer++ = AdcResult.ADCRESULT14;
    *m_pAdcBuffer++ = AdcResult.ADCRESULT15;
    
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;   // Acknowledge interrupt to PIE
    if (m_pAdcBuffer == m_pAdcBufferEnd)
    {
        PieCtrlRegs.PIEIER1.bit.INTx1 = 0;
        AdcRegs.INTSEL1N2.bit.INT1E = 0;
        EVENT_ISR_SET_BIT(kSampleDataAvailable);
    }
}
//@} End of Private Methods
//////////////////////////////////////////////////////////////////////
/// @name Public Methods
//@{
#define AQUISITION_PRESCALE 0x3F
void adc_init(void)
{
    int i;
    memset(m_adcBuffer, 0, ADC_BUFFER_SIZE * sizeof(uint16_t));
    
    m_pAdcBufferEnd = m_adcBuffer + ADC_BUFFER_SIZE;
    
    DINT;
    // Setup ADC
    EALLOW;
    AdcRegs.ADCCTL1.bit.ADCREFSEL    = 0;    // Use internal bandgap
    AdcRegs.ADCCTL1.bit.ADCBGPWD    = 1;     // Power up band gap
    AdcRegs.ADCCTL1.bit.ADCREFPWD    = 1;   // Power up reference
    AdcRegs.ADCCTL1.bit.ADCPWDN     = 1;      // Power up rest of ADC
    AdcRegs.ADCCTL1.bit.ADCENABLE    = 1;    // Enable ADC
    for(i=0; i<5000; i++){}                                           // wait 60000 cycles = 1ms (each iteration is 12 cycles)
    AdcRegs.ADCCTL1.bit.INTPULSEPOS    = 1;    // create int pulses 1 cycle prior to output latch
    
    // Configure ADCINT1 to be triggered on ADC0 EOC 
    AdcRegs.INTSEL1N2.bit.INT1SEL = 14;        // Select which channel triggers Adc intrerupt 
    AdcRegs.INTSEL1N2.bit.INT1CONT = 1;       // Set ADCINT1 to auto clr
    AdcRegs.INTSEL1N2.bit.INT1E = 1;               // Enable ADCINT1
    // set S/H window to 6 clk cycles (117ns)
    AdcRegs.ADCSOC0CTL.bit.ACQPS = AQUISITION_PRESCALE;
    AdcRegs.ADCSOC1CTL.bit.ACQPS = AQUISITION_PRESCALE;
    AdcRegs.ADCSOC2CTL.bit.ACQPS = AQUISITION_PRESCALE;
    AdcRegs.ADCSOC3CTL.bit.ACQPS = AQUISITION_PRESCALE;
    AdcRegs.ADCSOC4CTL.bit.ACQPS = AQUISITION_PRESCALE;
    AdcRegs.ADCSOC5CTL.bit.ACQPS = AQUISITION_PRESCALE;
    AdcRegs.ADCSOC6CTL.bit.ACQPS = AQUISITION_PRESCALE;
    AdcRegs.ADCSOC7CTL.bit.ACQPS = AQUISITION_PRESCALE;
    AdcRegs.ADCSOC8CTL.bit.ACQPS = AQUISITION_PRESCALE;
    AdcRegs.ADCSOC9CTL.bit.ACQPS = AQUISITION_PRESCALE;
    AdcRegs.ADCSOC10CTL.bit.ACQPS = AQUISITION_PRESCALE;
    AdcRegs.ADCSOC11CTL.bit.ACQPS = AQUISITION_PRESCALE;
    AdcRegs.ADCSOC12CTL.bit.ACQPS = AQUISITION_PRESCALE;
    AdcRegs.ADCSOC13CTL.bit.ACQPS = AQUISITION_PRESCALE;
    AdcRegs.ADCSOC14CTL.bit.ACQPS = AQUISITION_PRESCALE;
    AdcRegs.ADCSOC15CTL.bit.ACQPS = AQUISITION_PRESCALE;
    // Configure all SOCs to start at ADC Interrupt 1
    AdcRegs.ADCINTSOCSEL1.bit.SOC0 = 1;
    AdcRegs.ADCINTSOCSEL1.bit.SOC1 = 1;
    AdcRegs.ADCINTSOCSEL1.bit.SOC2 = 1;
    AdcRegs.ADCINTSOCSEL1.bit.SOC3 = 1;
    AdcRegs.ADCINTSOCSEL1.bit.SOC4 = 1;
    AdcRegs.ADCINTSOCSEL1.bit.SOC5 = 1;
    AdcRegs.ADCINTSOCSEL1.bit.SOC6 = 1;
    AdcRegs.ADCINTSOCSEL1.bit.SOC7 = 1;
    AdcRegs.ADCINTSOCSEL2.bit.SOC8 = 1;
    AdcRegs.ADCINTSOCSEL2.bit.SOC9 = 1;
    AdcRegs.ADCINTSOCSEL2.bit.SOC10 = 1;
    AdcRegs.ADCINTSOCSEL2.bit.SOC11 = 1;
    AdcRegs.ADCINTSOCSEL2.bit.SOC12 = 1;
    AdcRegs.ADCINTSOCSEL2.bit.SOC13 = 1;
    AdcRegs.ADCINTSOCSEL2.bit.SOC14 = 1;
    AdcRegs.ADCINTSOCSEL2.bit.SOC15 = 1;
    // Configure all SOCs to convert channel 1
    AdcRegs.ADCSOC0CTL.bit.CHSEL = 1;
    AdcRegs.ADCSOC1CTL.bit.CHSEL = 1; 
    AdcRegs.ADCSOC2CTL.bit.CHSEL = 1;
    AdcRegs.ADCSOC3CTL.bit.CHSEL = 1;
    AdcRegs.ADCSOC4CTL.bit.CHSEL = 1;
    AdcRegs.ADCSOC5CTL.bit.CHSEL = 1;
    AdcRegs.ADCSOC6CTL.bit.CHSEL = 1;
    AdcRegs.ADCSOC7CTL.bit.CHSEL = 1;
    AdcRegs.ADCSOC8CTL.bit.CHSEL = 1;
    AdcRegs.ADCSOC9CTL.bit.CHSEL = 1;
    AdcRegs.ADCSOC10CTL.bit.CHSEL = 1;
    AdcRegs.ADCSOC11CTL.bit.CHSEL = 1;
    AdcRegs.ADCSOC12CTL.bit.CHSEL = 1;
    AdcRegs.ADCSOC13CTL.bit.CHSEL = 1;
    AdcRegs.ADCSOC14CTL.bit.CHSEL = 1;
    AdcRegs.ADCSOC15CTL.bit.CHSEL = 1;
    
    PieVectTable.ADCINT1 = &adc_isr;
    EDIS;
    
    // Enable ADCINT1 in PIE
    PieCtrlRegs.PIEIER1.bit.INTx1 = 1;        // Enable INT 1.1 in the PIE
    IER |= M_INT1;                                            // Enable CPU Interrupt 1
    EINT;                                                             // Enable Global interrupt INTM
    ERTM;                                                           // Enable Global realtime interrupt DBGM
}
void adc_start()
{
    memset(m_adcBuffer, 0, ADC_BUFFER_SIZE * sizeof(uint16_t));
    m_pAdcBuffer = m_adcBuffer;
    
    EALLOW;
    AdcRegs.ADCSOCFRC1.bit.SOC14 = 1;
    AdcRegs.INTSEL1N2.bit.INT1E = 1;
    PieCtrlRegs.PIEIER1.bit.INTx1 = 1;
    EDIS;
}
 
				 
		 
					 
                          