Trying to understand the adc_task

Technical questions regarding the XTC tools and programming with XMOS.
IgorLopez
Member++
Posts: 25
Joined: Tue Mar 11, 2014 8:16 pm

Trying to understand the adc_task

Post by IgorLopez »

Hi,

I am having some problems using the adc_task in the lib_startkit_support startkit_adc.xc module so I am trying to understand the code.
What I do not understand is how the data is transported over the chanend.
The state-machine is creating four rising edges to trigger the ADC to do a conversion for the four channels on the startkit and when all four triggers has been sent to the ADC and as soon adc_state is equal to 9 will it execute two get_adc_data:

Code: Select all

      case (adc_state == 9) => get_adc_data(c_adc, adc_samps[0]): //Get ADC packet (2 x 16b samps)
        get_adc_data(c_adc, adc_samps[1]);  //Get second packet
        chkct(c_adc, 1);                    //Wait for end token on ADC channel
        i_adc.complete();                   //Signal to client we're ready
        adc_state = 0;                      //Reset tigger state machine
        break;
// the variable adc_samps is declared as:
unsigned adc_samps[2] = {0, 0};         //The samples (2 lots of 16 bits packed into to unsigned ints)
where the local function get_adc_data is:

Code: Select all

void get_adc_data(chanend c_adc, unsigned &data){
    data = inuint(c_adc);                       //Get ADC packet one (2 x 16b samps)
}
Reading the documentation
The sampling of the ADC is controlled using GPIO pin X0D24 that
is triggered either by writing to port 1I, or by driving the pin externally. On each
rising edge of the sample pin the ADC samples, holds and converts the data value
from one of the analog input pins. Each of the 8 inputs can be enabled individually.
Each of the enabled analog inputs is sampled in turn, on successive rising edges of
the sample pin. The data is transmitted to the channel-end that the user configures
during initialization of the ADC. Data is transmitted over the channel in individual
packets, or in packets that contain multiple consecutive samples.
and I do not understand how the transmission of the two first samples are sort of held back until all four triggers has been received by the ADC.
The initialization of the ADC is:

Code: Select all

     data[0] = 0x10401;                         // 16 bits per sample, 4 samples per 32b packet, calibrate off, ADC on
     write_periph_32(adc_tile, 2, 0x20, 1, data);
where bit 0 is ADC enable, bit 15:8 Number of samples to be transmitted per packet (-> 4 samples per packet), Bits 17:16 Number of bits per sample (1 -> 16 bits per sample)
So the ADC is configured to transmit 4 16 bits samples per package but the code is reading the chanend twice addressing two 32 bit values.


User avatar
infiniteimprobability
XCore Legend
Posts: 1126
Joined: Thu May 27, 2010 10:08 am

Post by infiniteimprobability »

I do not understand how the transmission of the two first samples are sort of held back until all four triggers has been received by the ADC.
There's a buffer in the ADC which is used to generate the packet that is sent to the core reading it. It's configured to a value of 4. So 4 x 16 = 64b packet generated. The comment is misleading because it says its a 32b packet, which is wrong.. There's a limit to the size of packet (from memory I think it's about 5 x 32b words which is the buffering between the ADC and the core via thh switch) but we have headroom in this case.

At the consumer side, we read long words (32b) so we just need to chew off two of those to get the full 4 sample packet from a round of conversions..

So basically, the ADC is configured to write 16b words into the buffer and the core consumers 32b words, which it then separates into the 16b (well 12 + 0 padding) samples..

I've pushed corrected comments to the repo, so hopefully this will be less confusing...
IgorLopez
Member++
Posts: 25
Joined: Tue Mar 11, 2014 8:16 pm

Post by IgorLopez »

Thanks for that crystal clear explanation.