6.8.2.1.3 Workflow

  1. Create a module software instance structure for the DAC module to store the DAC driver state while in use.
    struct dac_module dac_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. RTC module is used as the event trigger for DAC in this case, create a module software instance structure for the RTC module to store the RTC driver state.
    struct rtc_module rtc_instance;
    
    Note: This should never go out of scope as long as the module is in use. In most cases, this should be global.
  3. Create a buffer for the DAC samples to be converted by the driver.
    static uint16_t dac_data[DATA_LENGTH];
    
  4. Create a callback function that will be called when DAC completes convert job.
    void dac_callback(uint8_t channel)
    {
        UNUSED(channel);
    
        transfer_is_done = true;
    }
    
  5. Configure the DAC module.
    1. Create a DAC module configuration struct, which can be filled out to adjust the configuration of a physical DAC peripheral.
      struct dac_config config_dac;
      
    2. Initialize the DAC configuration struct with the module's default values.
      dac_get_config_defaults(&config_dac);
      
      Note: This should always be performed before using the configuration struct to ensure that all values are initialized to known default settings.
    3. Configure the DAC module with starting conversion on event.
      #if (SAML21)
          dac_instance.start_on_event[DAC_CHANNEL_0] = true;
      #else
          dac_instance.start_on_event = true;
      #endif
      
    4. Initialize the DAC module.
      dac_init(&dac_instance, DAC, &config_dac);
      
    5. Enable DAC start on conversion mode.
      struct dac_events events =
      #if (SAML21)
              { .on_event_chan0_start_conversion = true };
      #else
              { .on_event_start_conversion = true };
      #endif
      
    6. Enable DAC event.
      dac_enable_events(&dac_instance, &events);
      
  6. Configure the DAC channel.
    1. Create a DAC channel configuration struct, which can be filled out to adjust the configuration of a physical DAC output channel.
      struct dac_chan_config config_dac_chan;
      
    2. Initialize the DAC channel configuration struct with the module's default values.
      dac_chan_get_config_defaults(&config_dac_chan);
      
      Note: This should always be performed before using the configuration struct to ensure that all values are initialized to known default settings.
    3. Configure the DAC channel with the desired channel settings.
      dac_chan_set_config(&dac_instance, DAC_CHANNEL_0,
              &config_dac_chan);
      
    4. Enable the DAC channel so that it can output a voltage.
      dac_chan_enable(&dac_instance, DAC_CHANNEL_0);
      
  7. Enable DAC module.
    dac_enable(&dac_instance);
    
  8. Configure the RTC module.
    1. Create an RTC module event struct, which can be filled out to adjust the configuration of a physical RTC peripheral.
      struct rtc_count_events  rtc_event;
      
    2. Create an RTC module configuration struct, which can be filled out to adjust the configuration of a physical RTC peripheral.
      struct rtc_count_config config_rtc_count;
      
    3. Initialize the RTC configuration struct with the module's default values.
      rtc_count_get_config_defaults(&config_rtc_count);
      
      Note: This should always be performed before using the configuration struct to ensure that all values are initialized to known default settings.
    4. Change the RTC module configuration to suit the application.
      config_rtc_count.prescaler           = RTC_COUNT_PRESCALER_DIV_1;
      config_rtc_count.mode                = RTC_COUNT_MODE_16BIT;
      #ifdef FEATURE_RTC_CONTINUOUSLY_UPDATED
          config_rtc_count.continuously_update = true;
      #endif
      
    5. Initialize the RTC module.
      rtc_count_init(&rtc_instance, RTC, &config_rtc_count);
      
    6. Configure the RTC module with overflow event.
      rtc_event.generate_event_on_overflow = true;
      
    7. Enable RTC module overflow event.
      rtc_count_enable_events(&rtc_instance, &rtc_event);
      
    8. Enable RTC module.
      rtc_count_enable(&rtc_instance);
      
  9. Configure the Event resource.
    1. Create an event resource config struct, which can be filled out to adjust the configuration of a physical event peripheral.
      struct events_config event_config;
      
    2. Initialize the event configuration struct with the module's default values.
      events_get_config_defaults(&event_config);
      
      Note: This should always be performed before using the configuration struct to ensure that all values are initialized to known default settings.
    3. Change the event module configuration to suit the application.
      event_config.generator      = EVSYS_ID_GEN_RTC_OVF;
      event_config.edge_detect    = EVENTS_EDGE_DETECT_RISING;
      event_config.path           = EVENTS_PATH_ASYNCHRONOUS;
      event_config.clock_source   = GCLK_GENERATOR_0;
      
    4. Allocate the event resource.
      events_allocate(&event_dac, &event_config);
      
    5. Attach the event resource with user DAC start.
      #if (SAML21)
          events_attach_user(&event_dac, EVSYS_ID_USER_DAC_START_0);
      #else
          events_attach_user(&event_dac, EVSYS_ID_USER_DAC_START);
      #endif
      
  10. Register and enable the DAC Write Buffer Complete callback handler.
    1. Register the user-provided Write Buffer Complete callback function with the driver, so that it will be run when an asynchronous buffer write job completes.
      dac_register_callback(&dac_instance, DAC_CHANNEL_0,
              dac_callback,DAC_CALLBACK_TRANSFER_COMPLETE);
      
    2. Enable the Read Buffer Complete callback so that it will generate callbacks.
      dac_chan_enable_callback(&dac_instance, DAC_CHANNEL_0,
              DAC_CALLBACK_TRANSFER_COMPLETE);