1. 1.
    Create a module software instance structure for the ADC module to store the ADC driver state while in use.
    struct adc_module adc_instance;
    Note: This should never go out of scope as long as the module is in use. In most cases, this should be global.
  2. 2.
    Create a buffer for the ADC samples to be stored in by the driver asynchronously.
    #define ADC_SAMPLES 128
    uint16_t adc_result_buffer[ADC_SAMPLES];
  3. 3.
    Create a callback function that will be called each time the ADC completes an asynchronous read job.
    volatile bool adc_read_done = false;
    void adc_complete_callback(
            struct adc_module *const module)
        adc_read_done = true;
  4. 4.
    Configure the ADC module.
    1. 4.1.
      Create an ADC module configuration struct, which can be filled out to adjust the configuration of a physical ADC peripheral.
      struct adc_config config_adc;
    2. 4.2.
      Initialize the ADC configuration struct with the module's default values.
      Note: This should always be performed before using the configuration struct to ensure that all values are initialized to known default settings.
    3. 4.3.
      Change the ADC module configuration to suit the application.
      #if (!SAML21) && (!SAML22) && (!SAMC21)
          config_adc.gain_factor     = ADC_GAIN_FACTOR_DIV2;
          config_adc.clock_prescaler = ADC_CLOCK_PRESCALER_DIV8;
          config_adc.reference       = ADC_REFERENCE_INTVCC1;
      #if (SAMC21)
          config_adc.positive_input  = ADC_POSITIVE_INPUT_PIN5;
          config_adc.positive_input  = ADC_POSITIVE_INPUT_PIN6;
          config_adc.resolution      = ADC_RESOLUTION_12BIT;
    4. 4.4.
      Set ADC configurations.
      #if (SAMC21)
          adc_init(&adc_instance, ADC1, &config_adc);
          adc_init(&adc_instance, ADC, &config_adc);
    5. 4.5.
      Enable the ADC module so that conversions can be made.
  5. 5.
    Register and enable the ADC Read Buffer Complete callback handler.
    1. 5.1.
      Register the user-provided Read Buffer Complete callback function with the driver, so that it will be run when an asynchronous buffer read job completes.
              adc_complete_callback, ADC_CALLBACK_READ_BUFFER);
    2. 5.2.
      Enable the Read Buffer Complete callback so that it will generate callbacks.
      adc_enable_callback(&adc_instance, ADC_CALLBACK_READ_BUFFER);