123
Fork of LG by
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(); } }