The oversampling feature has been introduced in the SDK version 3.6 which is currently in its beta phase and available at https://imperix.com/downloads.

In a standard configuration, the control algorithm is executed just after each sampling event. The oversampling feature enables the possibility to set up multiple sampling events between each control algorithm execution.

This note explains how to configure the sampling events and how to retrieve the oversampled values.

Configuration of the sampling events

We use the term “sampling events” instead of “sampling clock” because the delays between the sampling instants are not necessarily identical.

The sampling events are defined in one period of CLOCK_0 and repeated at each period. They consist of a collection of phases (from 0.0 to 1.0). Up to 64 of those events can be configured. Then one of these sampling events must be selected as the interrupt (containing control algorithm) starting point.

As shown below, once the code is loaded on the device, the configuration analysis can be performed graphically from the BB Control utility software. This scenario is taken as an example and does not have any particular application.

In the imperix library for Simulink, the sampling events are configured from the CONFIG block:

Either by entering a vector of phases and selecting after which sampling event the interrupt (the control algorithm) must be executed.

Or by sectioning a starting phase and an oversampling ratio. The block automatically generates the sampling phases vector so the sampling events are evenly distributed.

From PLECS

In the imperix library for PLECS, the sampling events are configured from the CONFIG block by entering a vector of phases and selecting after which sampling event the interrupt (the control algorithm) must be executed.

From C++

When using the C++ SDK, void Adc_AddSamplingEvent(float phase); must be used in the UserInit(void) function.

tUserSafe UserInit(void) {
  // Sets CLOCK_0 at 50 kHz
  Clock_SetFrequency(CLOCK_0, 50e3);
  
  // Adds some sampling events
  Adc_AddSamplingEvent(0.1);
  Adc_AddSamplingEvent(0.45);
  Adc_AddSamplingEvent(0.7);
  Adc_AddSamplingEvent(0.8);
  
  // Starts the interrupt after the sampling events performed at 0.45
  ConfigureMainInterrupt(UserInterrupt, CLOCK_0, 0.45);
  
  // some other code...
  
  return SAFE;
}

Retrieving the oversampled analog values

In its standard configuration, the ADC block or driver will only provide the last sampled value. To retrieve older values, the ADC history feature must be used.

From Simulink & PLECS

From the imperix library for Simulink or PLECS, the ADC history can be enabled and then the quantity of value to retrieve is configured using the history depth parameter. The ADC block will return a vector containing the values as shown below.


From C++

When using the C++ SDK, Adc_ConfigureHistory must be used in the UserInit(void) to enable the ADC history and configure its depth. Then the Adc_GetHistory can be used in the interrupt to get the older ADC values.

tUserSafe UserInit(void) {
  // Sets CLOCK_0 at 50 kHz
  Clock_SetFrequency(CLOCK_0, 50e3);
  
  // Adds some sampling events
  Adc_AddSamplingEvent(0.1);
  Adc_AddSamplingEvent(0.45);
  Adc_AddSamplingEvent(0.7);
  Adc_AddSamplingEvent(0.8);
  
  // Starts the interrupt after the sampling events performed at 0.45
  ConfigureMainInterrupt(UserInterrupt, CLOCK_0, 0.45);
  
  // Setup a history of 4 samples for ADC0
  Adc_ConfigureHistory(ADC0, 4);
  
  // some other code...
  
  return SAFE;
}

tUserSafe UserInit(void) {

  float s0, s1, s2, s3;
  
  s0 = Adc_GetHistory(ADC0, 0); // sample with index 0
  s1 = Adc_GetHistory(ADC0, 1); // sample with index 1
  s2 = Adc_GetHistory(ADC0, 2); // sample with index 2
  s3 = Adc_GetHistory(ADC0, 3); // sample with index 3
 
  return SAFE;
}
  • No labels