123

Dependencies:   mbed

Fork of LG by igor Apu

DeviceDither.c

Committer:
Diletant
Date:
2016-06-26
Revision:
174:0f86eedd511c
Parent:
173:7f938afb0447
Child:
177:672ef279c8e0

File content as of revision 174:0f86eedd511c:

#include "Device.h"
extern Device device;
extern unsigned int SystemCoreClock1;

void InitDitherDefaultSettings(void){
  //Init pulse default settings
  device.dither.pulse.settings.width = 0x00001000;    //0.125
  device.dither.pulse.settings.min = 0x00000400;      //0.031
  device.dither.pulse.settings.max = 0x00004000;      //0.5
  
  //Init noise default settings
  device.dither.noise.settings.period = 20;
  device.dither.noise.settings.range = 20;
  device.dither.noise.settings.amplitude = 0x00000400; //0.031
  
  //Init dither cycle default settings
  device.dither.cycle.settings.enabled = 1;
  
  //Init phase detector default settings
  device.dither.detector.settings.filter.factor[0]  = -0x00010000;
  device.dither.detector.settings.filter.factor[1]  = -0x00010000;
  device.dither.detector.settings.filter.factor[2]  = -0x00010000;
  device.dither.detector.settings.filter.factor[3]  = -0x00010000;
  device.dither.detector.settings.filter.factor[4]  = -0x00010000;
  device.dither.detector.settings.filter.factor[5]  = -0x00010000;
  device.dither.detector.settings.filter.factor[6]  = -0x00010000;
  device.dither.detector.settings.filter.factor[7]  = -0x00010000;
  
  device.dither.detector.settings.filter.factor[8]  = -0x00010000;
  device.dither.detector.settings.filter.factor[9]  = -0x00010000;
  device.dither.detector.settings.filter.factor[10] = -0x00010000;
  device.dither.detector.settings.filter.factor[11] = -0x00010000;
  device.dither.detector.settings.filter.factor[12] = -0x00010000;
  device.dither.detector.settings.filter.factor[13] = -0x00010000;
  device.dither.detector.settings.filter.factor[14] = -0x00010000;
  device.dither.detector.settings.filter.factor[15] = -0x00010000;
  
  device.dither.detector.settings.filter.factor[16] =  0x00010000;
  device.dither.detector.settings.filter.factor[17] =  0x00010000;
  device.dither.detector.settings.filter.factor[18] =  0x00010000;
  device.dither.detector.settings.filter.factor[19] =  0x00010000;
  device.dither.detector.settings.filter.factor[20] =  0x00010000;
  device.dither.detector.settings.filter.factor[21] =  0x00010000;
  device.dither.detector.settings.filter.factor[22] =  0x00010000;
  device.dither.detector.settings.filter.factor[23] =  0x00010000;
  
  device.dither.detector.settings.filter.factor[24] =  0x00010000;
  device.dither.detector.settings.filter.factor[25] =  0x00010000;
  device.dither.detector.settings.filter.factor[26] =  0x00010000;
  device.dither.detector.settings.filter.factor[27] =  0x00010000;
  device.dither.detector.settings.filter.factor[28] =  0x00010000;
  device.dither.detector.settings.filter.factor[29] =  0x00010000;
  device.dither.detector.settings.filter.factor[30] =  0x00010000;
  device.dither.detector.settings.filter.factor[31] =  0x00010000;
  
  device.dither.detector.settings.transfer.points = 16;
  device.dither.detector.settings.transfer.raw[0] = -0x10000; //-1.0
  device.dither.detector.settings.transfer.restored[0] = -0x1921f; //-1.5707963267948966
  device.dither.detector.settings.transfer.raw[1] = -0xfa67; //-0.9781476007338056
  device.dither.detector.settings.transfer.restored[1] = -0x15c81; //-1.361356816555577
  device.dither.detector.settings.transfer.raw[2] = -0xe9de; //-0.9135454576426009
  device.dither.detector.settings.transfer.restored[2] = -0x126e4; //-1.1519173063162575
  device.dither.detector.settings.transfer.raw[3] = -0xcf1b; //-0.8090169943749475
  device.dither.detector.settings.transfer.restored[3] = -0xf146; //-0.9424777960769379
  device.dither.detector.settings.transfer.raw[4] = -0xab4c; //-0.6691306063588582
  device.dither.detector.settings.transfer.restored[4] = -0xbba8; //-0.7330382858376184
  device.dither.detector.settings.transfer.raw[5] = -0x8000; //-0.5
  device.dither.detector.settings.transfer.restored[5] = -0x860a; //-0.5235987755982989
  device.dither.detector.settings.transfer.raw[6] = -0x4f1b; //-0.3090169943749474
  device.dither.detector.settings.transfer.restored[6] = -0x506c; //-0.3141592653589793
  device.dither.detector.settings.transfer.raw[7] = -0x1ac2; //-0.10452846326765361
  device.dither.detector.settings.transfer.restored[7] = -0x1ace; //-0.10471975511965992
  device.dither.detector.settings.transfer.raw[8] = 0x1ac2; //0.10452846326765339
  device.dither.detector.settings.transfer.restored[8] = 0x1ace; //0.1047197551196597
  device.dither.detector.settings.transfer.raw[9] = 0x4f1b; //0.3090169943749474
  device.dither.detector.settings.transfer.restored[9] = 0x506c; //0.3141592653589793
  device.dither.detector.settings.transfer.raw[10] = 0x7fff; //0.49999999999999983
  device.dither.detector.settings.transfer.restored[10] = 0x860a; //0.5235987755982987
  device.dither.detector.settings.transfer.raw[11] = 0xab4c; //0.669130606358858
  device.dither.detector.settings.transfer.restored[11] = 0xbba8; //0.7330382858376181
  device.dither.detector.settings.transfer.raw[12] = 0xcf1b; //0.8090169943749475
  device.dither.detector.settings.transfer.restored[12] = 0xf146; //0.9424777960769379
  device.dither.detector.settings.transfer.raw[13] = 0xe9de; //0.9135454576426009
  device.dither.detector.settings.transfer.restored[13] = 0x126e4; //1.1519173063162573
  device.dither.detector.settings.transfer.raw[14] = 0xfa67; //0.9781476007338056
  device.dither.detector.settings.transfer.restored[14] = 0x15c81; //1.3613568165555767
  device.dither.detector.settings.transfer.raw[15] = 0x10000; //1.0
  device.dither.detector.settings.transfer.restored[15] = 0x1921f; //1.5707963267948966
  
  //Init frequency regulator default settings
  device.dither.frequency.settings.enabled = 1;
  device.dither.frequency.settings.min = 0x01860000; //390 Hz in 16.16 format
  device.dither.frequency.settings.max = 0x019A0000; //410 Hz in 16.16 format
  device.dither.frequency.settings.scale = 0x00001000; //0.0625Hz
  device.dither.frequency.settings.transfer.points = 16;
  device.dither.frequency.settings.transfer.error[0] = -0x140000; //-20.0Hz
  device.dither.frequency.settings.transfer.correction[0] = 0x10000; //1.0
  device.dither.frequency.settings.transfer.error[1] = -0x115555; //-17.333333333333332Hz
  device.dither.frequency.settings.transfer.correction[1] = 0xb473; //0.7048888888888889
  device.dither.frequency.settings.transfer.error[2] = -0xeaaaa; //-14.666666666666668Hz
  device.dither.frequency.settings.transfer.correction[2] = 0x7aa7; //0.47911111111111115
  device.dither.frequency.settings.transfer.error[3] = -0xc0000; //-12.0Hz
  device.dither.frequency.settings.transfer.correction[3] = 0x4fdf; //0.31199999999999994
  device.dither.frequency.settings.transfer.error[4] = -0x95555; //-9.333333333333334Hz
  device.dither.frequency.settings.transfer.correction[4] = 0x3161; //0.1928888888888889
  device.dither.frequency.settings.transfer.error[5] = -0x6aaaa; //-6.666666666666668Hz
  device.dither.frequency.settings.transfer.correction[5] = 0x1c71; //0.11111111111111113
  device.dither.frequency.settings.transfer.error[6] = -0x40000; //-4.0Hz
  device.dither.frequency.settings.transfer.correction[6] = 0xe56; //0.05599999999999999
  device.dither.frequency.settings.transfer.error[7] = -0x15555; //-1.3333333333333357Hz
  device.dither.frequency.settings.transfer.correction[7] = 0x452; //0.016888888888888884
  device.dither.frequency.settings.transfer.error[8] = 0x15555; //1.3333333333333321Hz
  device.dither.frequency.settings.transfer.correction[8] = -0x452; //-0.016888888888888884
  device.dither.frequency.settings.transfer.error[9] = 0x40000; //4.0Hz
  device.dither.frequency.settings.transfer.correction[9] = -0xe56; //-0.05599999999999999
  device.dither.frequency.settings.transfer.error[10] = 0x6aaaa; //6.666666666666664Hz
  device.dither.frequency.settings.transfer.correction[10] = -0x1c71; //-0.11111111111111108
  device.dither.frequency.settings.transfer.error[11] = 0x95555; //9.333333333333332Hz
  device.dither.frequency.settings.transfer.correction[11] = -0x3161; //-0.1928888888888888
  device.dither.frequency.settings.transfer.error[12] = 0xc0000; //12.0kHz
  device.dither.frequency.settings.transfer.correction[12] = -0x4fdf; //-0.31200000000000006
  device.dither.frequency.settings.transfer.error[13] = 0xeaaaa; //14.666666666666664Hz
  device.dither.frequency.settings.transfer.correction[13] = -0x7aa7; //-0.47911111111111115
  device.dither.frequency.settings.transfer.error[14] = 0x115555; //17.33333333333333Hz
  device.dither.frequency.settings.transfer.correction[14] = -0xb473; //-0.7048888888888889
  device.dither.frequency.settings.transfer.error[15] = 0x140000; //20.0Hz
  device.dither.frequency.settings.transfer.correction[15] = -0x10000; //-1.0
  
  //Init amplitude regulator default settings
  device.dither.amplitude.settings.enabled = 1;
  device.dither.amplitude.settings.scale = 0x00001000; //0.0625 (6.25%) of period
  device.dither.amplitude.settings.transfer.points = 16;
  device.dither.amplitude.settings.transfer.error[0] = -0x140000; //-20.0kHz
  device.dither.amplitude.settings.transfer.correction[0] = 0x10000; //1.0
  device.dither.amplitude.settings.transfer.error[1] = -0x115555; //-17.333333333333332kHz
  device.dither.amplitude.settings.transfer.correction[1] = 0xb473; //0.7048888888888889
  device.dither.amplitude.settings.transfer.error[2] = -0xeaaaa; //-14.666666666666668kHz
  device.dither.amplitude.settings.transfer.correction[2] = 0x7aa7; //0.47911111111111115
  device.dither.amplitude.settings.transfer.error[3] = -0xc0000; //-12.0kHz
  device.dither.amplitude.settings.transfer.correction[3] = 0x4fdf; //0.31199999999999994
  device.dither.amplitude.settings.transfer.error[4] = -0x95555; //-9.333333333333334kHz
  device.dither.amplitude.settings.transfer.correction[4] = 0x3161; //0.1928888888888889
  device.dither.amplitude.settings.transfer.error[5] = -0x6aaaa; //-6.666666666666668kHz
  device.dither.amplitude.settings.transfer.correction[5] = 0x1c71; //0.11111111111111113
  device.dither.amplitude.settings.transfer.error[6] = -0x40000; //-4.0kHz
  device.dither.amplitude.settings.transfer.correction[6] = 0xe56; //0.05599999999999999
  device.dither.amplitude.settings.transfer.error[7] = -0x15555; //-1.3333333333333357kHz
  device.dither.amplitude.settings.transfer.correction[7] = 0x452; //0.016888888888888884
  device.dither.amplitude.settings.transfer.error[8] = 0x15555; //1.3333333333333321kHz
  device.dither.amplitude.settings.transfer.correction[8] = -0x452; //-0.016888888888888884
  device.dither.amplitude.settings.transfer.error[9] = 0x40000; //4.0kHz
  device.dither.amplitude.settings.transfer.correction[9] = -0xe56; //-0.05599999999999999
  device.dither.amplitude.settings.transfer.error[10] = 0x6aaaa; //6.666666666666664kHz
  device.dither.amplitude.settings.transfer.correction[10] = -0x1c71; //-0.11111111111111108
  device.dither.amplitude.settings.transfer.error[11] = 0x95555; //9.333333333333332kHz
  device.dither.amplitude.settings.transfer.correction[11] = -0x3161; //-0.1928888888888888
  device.dither.amplitude.settings.transfer.error[12] = 0xc0000; //12.0kHz
  device.dither.amplitude.settings.transfer.correction[12] = -0x4fdf; //-0.31200000000000006
  device.dither.amplitude.settings.transfer.error[13] = 0xeaaaa; //14.666666666666664kHz
  device.dither.amplitude.settings.transfer.correction[13] = -0x7aa7; //-0.47911111111111115
  device.dither.amplitude.settings.transfer.error[14] = 0x115555; //17.33333333333333kHz
  device.dither.amplitude.settings.transfer.correction[14] = -0xb473; //-0.7048888888888889
  device.dither.amplitude.settings.transfer.error[15] = 0x140000; //20.0kHz
  device.dither.amplitude.settings.transfer.correction[15] = -0x10000; //-1.0
}

void InitDitherState(void){
  //Init pulse state
  device.dither.pulse.state.width = device.dither.pulse.settings.width;
  device.dither.pulse.state.min = device.dither.pulse.settings.min;
  device.dither.pulse.state.max = device.dither.pulse.settings.max;
  device.dither.pulse.state.rise = 0;
  device.dither.pulse.state.fall = 0;
  device.dither.pulse.state.counter = 0;
  
  //Init noise state
  device.dither.noise.state.enabled = device.dither.noise.settings.enabled;
  device.dither.noise.state.period = device.dither.noise.settings.period;
  device.dither.noise.state.range = device.dither.noise.settings.range;
  device.dither.noise.state.amplitude = device.dither.noise.settings.amplitude;
  device.dither.noise.state.counter = 0;
  device.dither.noise.state.trigger = 0;
  device.dither.noise.state.disturbance = 0;
  
  //Init dither cycle state
  device.dither.cycle.state.enabled = device.dither.cycle.settings.enabled;
  device.dither.cycle.state.pin1 = 0;
  device.dither.cycle.state.pin2 = 0;
  
  //Init phase detector state
  device.dither.detector.state.sum = 0;
  device.dither.detector.state.raw = 0;
  device.dither.detector.state.phase = 0;
  
  //Init frequency regulator state
  //TODO: min(temperature), max(temperature)
  device.dither.frequency.state.enabled = device.dither.frequency.settings.enabled;
  device.dither.frequency.state.min = device.dither.frequency.settings.min;
  device.dither.frequency.state.max = device.dither.frequency.settings.max;
  device.dither.frequency.state.scale = device.dither.frequency.settings.scale;
  device.dither.frequency.state.frequency = (device.dither.frequency.state.max + device.dither.frequency.state.min) / 2;
  device.dither.frequency.state.error = 0;
  device.dither.frequency.state.correction = 0;
  //Set measurement timer
  timersSetMeasurementPeriod((unsigned int)(SystemCoreClock1/(device.dither.frequency.state.frequency >> 11)));
  
  //Init amplitude regulator state
  device.dither.amplitude.state.enabled = device.dither.amplitude.settings.enabled;
  device.dither.amplitude.state.reference = device.dither.amplitude.settings.reference;
  device.dither.amplitude.state.scale = device.dither.amplitude.settings.scale;
  device.dither.amplitude.state.frequency = 0;
  device.dither.amplitude.state.error = 0;
  device.dither.amplitude.state.correction = 0;
}

void DeviceStartDither(void){
  DeviceStartMeasurementTimer();
}

//Call from regular cycle interrupt (or from main cycle?)
void ditherCycle(void){
  uint8_t pin1, pin2;
  //Use LPC_TIM1->TC instead of device.dither.pulse.state.counter?
  //  device.measurement.state.counter + (LPC_TIM1->TC << 16)/LPC_TIM1->MR0 - cycle phase 0...32 in 16.16 format
  //  "+": 100kHz timer will be just 10kHz timer if call DeviceDitherDoCycle() in main cycle
  if ((device.dither.pulse.state.counter > device.dither.pulse.state.rise) && (device.dither.pulse.state.counter < device.dither.pulse.state.fall)){
    pin1 = 1; pin2 = 1;  
  } else {
    pin1 = 0; pin2 = 0;
  }
  if (device.measurement.counter < 16){
      pin2 = 0;
  } else {
      pin1 = 0;
  }
  if (!device.dither.cycle.state.enabled) {
    pin1 = 0; pin2 = 0;
  }
  if (pin1 > device.dither.cycle.state.pin1) LPC_GPIO1->FIOCLR = 1<<25;
  if (pin1 < device.dither.cycle.state.pin1) LPC_GPIO1->FIOSET = 1<<25;
  if (pin2 > device.dither.cycle.state.pin2) LPC_GPIO1->FIOCLR = 1<<28;
  if (pin2 < device.dither.cycle.state.pin2) LPC_GPIO1->FIOSET = 1<<28;
  device.dither.cycle.state.pin1 = pin1;
  device.dither.cycle.state.pin2 = pin2;
}

int32_t ditherInterpolate(int32_t a,int32_t a1,int32_t a2,int32_t b1,int32_t b2) {
  int32_t ma, mb;
  while (1) {
    if (a1 == a) return b1;
    if (a2 == a) return b2;
                
    ma = (a1 + a2) >> 1;
    mb = (b1 + b2) >> 1;
      
    if (a < ma) {
      if (a2 == ma) return mb;
      if (b1 == mb) return mb;
      a2 = ma; b2 = mb;
    } else if (a > ma) {
      if (a1 == ma) return mb;
      if (b2 == mb) return mb;
      a1 = ma; b1 = mb;
    } else return mb;
  }
}

int32_t ditherRestorePhase(uint32_t raw) {
  int32_t r1, r2;
  for (uint8_t i = 1; i < device.dither.detector.settings.transfer.points; i++) {
    r1 = device.dither.detector.settings.transfer.raw[i - 1];
    if (raw < r1) {
      return device.dither.detector.settings.transfer.restored[i - 1];
    }

    r2 = device.dither.detector.settings.transfer.raw[i];
    if (raw < r2) {
      int32_t p1 = device.dither.detector.settings.transfer.restored[i - 1];
      int32_t p2 = device.dither.detector.settings.transfer.restored[i];
      return ditherInterpolate(raw, r1, r2, p1, p2);
    }
  }
  return device.dither.detector.settings.transfer.restored[device.dither.detector.settings.transfer.points - 1];  
}

int32_t ditherFrequencyCorrection(uint32_t error) {
  int32_t e1, e2;
  for (uint8_t i = 1; i < device.dither.frequency.settings.transfer.points; i++) {
    e1 = device.dither.frequency.settings.transfer.error[i - 1];
    if (error < e1) {
      return device.dither.frequency.settings.transfer.correction[i - 1];
    }

    e2 = device.dither.frequency.settings.transfer.error[i];
    if (error < e2) {
      int32_t c1 = device.dither.frequency.settings.transfer.correction[i - 1];
      int32_t c2 = device.dither.frequency.settings.transfer.correction[i];
      return ditherInterpolate(error, e1, e2, c1, c2);
    }
  }
  return device.dither.frequency.settings.transfer.correction[device.dither.frequency.settings.transfer.points - 1];  
}

int32_t ditherPulseCorrection(uint32_t error) {
  int32_t e1, e2;
  for (uint8_t i = 1; i < device.dither.amplitude.settings.transfer.points; i++) {
    e1 = device.dither.amplitude.settings.transfer.error[i - 1];
    if (error < e1) {
      return device.dither.amplitude.settings.transfer.correction[i - 1];
    }

    e2 = device.dither.amplitude.settings.transfer.error[i];
    if (error < e2) {
      int32_t c1 = device.dither.amplitude.settings.transfer.correction[i - 1];
      int32_t c2 = device.dither.amplitude.settings.transfer.correction[i];
      return ditherInterpolate(error, e1, e2, c1, c2);
    }
  }
  return device.dither.amplitude.settings.transfer.correction[device.dither.amplitude.settings.transfer.points - 1];  
}

void ditherProcessDetector(void) {
  //f(t) = f0 * cos(w * t)
  //x(t) = x0 * cos(w * t - fi)
  //fi = - arctan(const / (w0^2 - w^2))
  int32_t delta = device.counters.dither.state.delta[device.measurement.counter];
  int32_t factor = device.dither.detector.settings.filter.factor[device.measurement.counter]; //-1...+1 in 16.16 format
  device.dither.detector.state.sum += delta * factor; //-500...+500 in 16.16 format
}

void ditherProcessPhase(void) {
  //Raw phase -1...+1 in 16.16 format
  if (device.counters.dither.state.frequency > 0) {//0...+2500 in 32.0 format (1MHz/400Hz)
    device.dither.detector.state.phase = device.dither.detector.state.sum / device.counters.dither.state.frequency; //-1...+1 in 16.16 format
  } else {
    device.dither.detector.state.phase = 0;
  }
  //TODO: Transform required to actual phase in range -1...+1 or -Pi/2...+Pi/2 or -90...+90 degrees
  device.dither.detector.state.phase = ditherRestorePhase(device.dither.detector.state.raw);
}

void ditherProcessFrequency(void) {
  device.dither.frequency.state.error = -device.dither.detector.state.phase;
  device.dither.frequency.state.correction = (device.dither.frequency.state.scale * ditherFrequencyCorrection(device.dither.frequency.state.error)) >> 16;
  
  if (device.dither.frequency.state.enabled){
    device.dither.frequency.state.frequency += device.dither.frequency.state.correction;
  
    if (device.dither.frequency.state.frequency > device.dither.frequency.state.max) {
      device.dither.frequency.state.frequency = device.dither.frequency.state.max;
    } else if (device.dither.frequency.state.frequency < device.dither.frequency.state.min) {
      device.dither.frequency.state.frequency = device.dither.frequency.state.min;
    }
  
    timersSetMeasurementPeriod((unsigned int)(SystemCoreClock1/(device.dither.frequency.state.frequency >> 11)));
  }
}

void ditherProcessAmplitude(void) {
  //Frequency = device.counters.state.frequency * device.dither.frequency.state.frequency / 2;
  //                        500                 *           400Hz (0x01900000)              / 2 / 1000 = 100kHz (0x00640000)
  //                        500                 *             0x19000000                    / 2000 / 16 = 100kHz = 0x00640000
  device.dither.amplitude.state.frequency = (device.counters.dither.state.frequency * ((device.dither.frequency.state.frequency << 4) / 2000)) >> 4;
  device.dither.amplitude.state.error = device.dither.amplitude.state.frequency - device.dither.amplitude.state.reference; //0...200kHz 16.16 format
  device.dither.amplitude.state.correction = (device.dither.amplitude.state.scale * ditherPulseCorrection(device.dither.amplitude.state.error)) >> 16;
  
  if (device.dither.amplitude.state.enabled){
    device.dither.pulse.state.width += device.dither.amplitude.state.correction;
    if (device.dither.pulse.state.width < device.dither.pulse.state.min) device.dither.pulse.state.width = device.dither.pulse.state.min;
    if (device.dither.pulse.state.width > device.dither.pulse.state.max) device.dither.pulse.state.width = device.dither.pulse.state.max;
  }
}

void ditherProcessNoise(void) {
  if (device.dither.noise.state.counter == device.dither.noise.state.trigger) {
    //Set noise update state parameters
    device.dither.noise.state.counter = 0;
    device.dither.noise.state.trigger = device.dither.noise.state.period + rand() % device.dither.noise.state.range;
    
    //Set pulse width disturbance
    if (device.dither.noise.state.enabled) {
      device.dither.noise.state.disturbance = (device.dither.noise.state.amplitude * (-0x00010000 + 2 * rand())) >> 16; //-1...1
    } else {
      device.dither.noise.state.disturbance = 0;
    }
  }
}

void ditherProcessPulse(void) {
  int32_t max = device.controller.timer[0].state.MR0 / 2;
  int32_t mid = max / 2;
  int32_t half = (max * (device.dither.pulse.state.width + device.dither.noise.state.disturbance)) >> 17; //pulse half width in 10 mks ticks
  
  int32_t rise = mid - half; if (rise < 0) rise = 0;
  device.dither.pulse.state.rise = rise;
  int32_t fall = mid + half; if (fall > max) fall = max;
  device.dither.pulse.state.fall = fall;
  /*
  int32_t delta = (max * (device.dither.amplitude.state.correction + device.dither.noise.state.disturbance)) >> 17;
  
  device.dither.pulse.state.rise += delta;
  if (device.dither.pulse.state.rise < 0) device.dither.pulse.state.rise = 0;
  if (device.dither.pulse.state.rise > mid) device.dither.pulse.state.rise = mid;
  
  device.dither.pulse.state.fall -= delta;
  if (device.dither.pulse.state.fall > max) device.dither.pulse.state.fall = max;
  if (device.dither.pulse.state.fall < mid) device.dither.pulse.state.fall = mid;
  */
}

//Call from measurement timer interrupt
void ditherProcess(void) {
  ditherProcessDetector();
  if (device.measurement.counter == 31) {
    ditherProcessPhase();
    ditherProcessFrequency();
    ditherProcessAmplitude();
    ditherProcessNoise();
    ditherProcessPulse();
  }
}