123

Dependencies:   mbed

Fork of LG by igor Apu

Revision:
166:c3c0b8a90d81
Parent:
161:efd949e8d536
Child:
167:bedc0a9d559a
diff -r b2bd0c810a4f -r c3c0b8a90d81 DeviceISACS.c
--- a/DeviceISACS.c	Fri May 20 14:03:58 2016 +0000
+++ b/DeviceISACS.c	Sun May 22 18:59:20 2016 +0000
@@ -3,38 +3,38 @@
 extern Device device;
 
 void InitISACSOutputWithDefaults(void){
-  device.isacs.output.settings.points = 2;
-  //Control point 1.5 volt
-  device.isacs.output.settings.voltage[0] = 0x00017fff;
-  device.isacs.output.settings.code[0] = 800;
-  //Control point 12.5 volt
-  device.isacs.output.settings.voltage[1] = 0x000c7fff;
-  device.isacs.output.settings.code[1] = 2048;
+  device.isacs.output.interpolator.settings.points = 2;
+  //Control point 1.5 volt - low output limit
+  device.isacs.output.interpolator.settings.voltage[0] = 0x00017fff;
+  device.isacs.output.interpolator.settings.code[0] = 800;
+  //Control point 12.5 volt - high output limit
+  device.isacs.output.interpolator.settings.voltage[1] = 0x000c7fff;
+  device.isacs.output.interpolator.settings.code[1] = 2048;
+  device.isacs.output.start.settings.voltage = 0x000c7fff; //+12.5V start
+  device.isacs.output.reset.settings.voltage = 0x00077fff; //+7.5V if regulator disabled at reset time
 }
 
 void InitISACSOutput(void){
-  device.isacs.output.state.voltage = 0x000c7fff;
-  isacsOutputCode();
+  //isacsSetOutputVoltage(device.isacs.output.start.settings.voltage);
 }
 
 void InitISACSRegulatorWithDefaults(void){
-  device.isacs.regulator.settings.enabled = 1;
   //Startup settings
+  device.isacs.regulator.settings.start.enabled = 1;
   device.isacs.regulator.settings.start.reference = 0x00020000; //Reference voltage 2V in 16.16 signed fixed point format
   device.isacs.regulator.settings.start.scale = 1; //Scale factor
   //Regular operation settings
+  device.isacs.regulator.settings.regular.enabled = 1;
   device.isacs.regulator.settings.regular.reference = 0x00020000; //Reference voltage 2V in 16.16 signed fixed point format
   device.isacs.regulator.settings.regular.scale = 1; //Scale factor
   //Reset operation settings
+  device.isacs.regulator.settings.reset.enabled = 1;
   device.isacs.regulator.settings.reset.reference = 0x00020000; //Reference voltage 2V in 16.16 signed fixed point format
   device.isacs.regulator.settings.reset.scale = 1; //Scale factor
-  //Amplifier settings
-  //device.isacs.amplifier.settings.reference = 0x00040000; //Reference voltage 4V in 16.16 signed fixed point format
-  //device.isacs.amplifier.settings.gain = 1; //Scale factor
 }
 
 void InitISACSRegulator(void){
-  device.isacs.regulator.state.enabled = device.isacs.regulator.settings.enabled;
+  device.isacs.regulator.state.enabled = device.isacs.regulator.settings.start.enabled;
   device.isacs.regulator.state.reference = device.isacs.regulator.settings.start.reference;
   device.isacs.regulator.state.scale = device.isacs.regulator.settings.start.scale;
 }
@@ -54,39 +54,161 @@
 void StartISACS(void){
 }
 
-void isacsOutputCode(void) {
-  uint32_t v1, v2;
-  for (uint8_t i = 1; i < device.isacs.output.settings.points; i++) {
-    v1 = device.isacs.output.settings.voltage[i - 1];
-    if (device.isacs.output.state.voltage < v1) {
-      device.isacs.output.state.code = device.isacs.output.settings.code[i - 1];
-      device.isacs.output.state.voltage = v1;
+/*
+//Count leading zeroes
+static uint8_t clz(uint32_t x) {
+  uint8_t result = 0;
+  if (x == 0) return 32;
+  while (!(x & 0xF0000000)) { result += 4; x <<= 4; }
+  while (!(x & 0x80000000)) { result += 1; x <<= 1; }
+  return result;
+}
+//Count trailing zeroes
+static uint8_t ctz(uint32_t x) {
+  uint8_t result = 0;
+  if (x == 0) return 32;
+  while (!(x & 0xF0000000)) { result += 4; x <<= 4; }
+  while (!(x & 0x80000000)) { result += 1; x <<= 1; }
+  return result;
+}
+*/
+
+int32_t isacsInterpolate(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 isacsInputCodeToVoltage(uint32_t code) {
+  int32_t c1, c2;
+  for (uint8_t i = 1; i < device.isacs.input.interpolator.settings.points; i++) {
+    c1 = device.isacs.input.interpolator.settings.code[i - 1];
+    if (code < c1) {
+      return device.isacs.input.interpolator.settings.voltage[i - 1];
+    }
+
+    c2 = device.isacs.input.interpolator.settings.code[i];
+    if (code < c2) {
+      int32_t v1 = device.isacs.input.interpolator.settings.voltage[i - 1];
+      int32_t v2 = device.isacs.input.interpolator.settings.voltage[i];
+      return isacsInterpolate(code, c1, c2, v1, v2);
+    }
+  }
+  return device.isacs.input.interpolator.settings.voltage[device.isacs.input.interpolator.settings.points - 1];  
+}
+
+int32_t isacsOutputVoltageToCode(uint32_t voltage) {
+  int32_t v1, v2;
+  for (uint8_t i = 1; i < device.isacs.output.interpolator.settings.points; i++) {
+    v1 = device.isacs.output.interpolator.settings.voltage[i - 1];
+    if (voltage < v1) {
+      return device.isacs.output.interpolator.settings.code[i - 1];
+    }
+
+    v2 = device.isacs.output.interpolator.settings.voltage[i];
+    if (voltage < v2) {
+      int32_t c1 = device.isacs.output.interpolator.settings.code[i - 1];
+      int32_t c2 = device.isacs.output.interpolator.settings.code[i];
+      return isacsInterpolate(voltage, v1, v2, c1, c2);
+    }
+  }
+  return device.isacs.output.interpolator.settings.code[device.isacs.output.interpolator.settings.points - 1];
+}
+
+/*
+void isacsSetOutputVoltage(int32_t voltage) {
+  int32_t v1, v2;
+  for (uint8_t i = 1; i < device.isacs.output.interpolator.settings.points; i++) {
+    v1 = device.isacs.output.interpolator.settings.voltage[i - 1];
+    if (voltage < v1) {
+      uint32_t code = device.isacs.output.interpolator.settings.code[i - 1];
+      device.isacs.output.voltage = v1;
+      device.controller.SSP.out[0] = code;
       return;
     }
 
-    v2 = device.isacs.output.settings.voltage[i];
-    if (device.isacs.output.state.voltage < v2) {
-      //max(c2 - c1) = 4096
-      //max(v - v1) = 25V = 0x00190000;
-      //max((c2 - c1) * (v - v1)) = 0x190000000
-      //0x190000000 >> 2 = 0x64000000 < 0x80000000: ok
-      uint32_t dv = (device.isacs.output.state.voltage - v1);
-      uint32_t dvi = (v2 - v1);
-      uint32_t c1 = device.isacs.output.settings.code[i - 1];
-      uint32_t c2 = device.isacs.output.settings.code[i];
-      uint32_t dc = c2 - c1;
-      uint32_t m = 1;
-      if (device.dac.settings.resolution > 16) {
-        dv >>= 7; dc >>= 7; dvi >>= 7; m <<= 7;//For 24 bit: (21 - 7) + (24 - 7) - (21 - 7) + 7 = 24
-      } else if (device.dac.settings.resolution > 12) {
-        dv >>= 3; dc >>= 3; dvi >>= 3; m <<= 3;//For 16 bit: (21 - 3) + (16 - 3) - (21 - 3) + 3 = 16
-      } else {
-        dv >>= 1; dc >>= 1; dvi >>= 1; m <<= 1;//For 12 bit: (21 - 1) + (12 - 1) - (21 - 1) + 1 = 12
-      }
-      device.isacs.output.state.code = c1 + dv * dc / dvi * m;
+    v2 = device.isacs.output.interpolator.settings.voltage[i];
+    if (voltage < v2) {
+      //int32_t dv = device.isacs.output.state.voltage - v1;
+      //int32_t dvi = v2 - v1;
+      //int32_t c1 = device.isacs.output.settings.code[i - 1];
+      //int32_t c2 = device.isacs.output.settings.code[i];
+      //int32_t dc = c2 - c1;
+      
+      //uint32_t m = 1;
+      //if (device.dac.settings.resolution > 16) {
+      //  dv >>= 7; dc >>= 7; dvi >>= 7; m <<= 7;//For 24 bit: (21 - 7) + (24 - 7) - (21 - 7) + 7 = 24
+      //} else if (device.dac.settings.resolution > 12) {
+      //  dv >>= 3; dc >>= 3; dvi >>= 3; m <<= 3;//For 16 bit: (21 - 3) + (16 - 3) - (21 - 3) + 3 = 16
+      //} else {
+      //  dv >>= 1; dc >>= 1; dvi >>= 1; m <<= 1;//For 12 bit: (21 - 1) + (12 - 1) - (21 - 1) + 1 = 12
+      //}
+      //device.isacs.output.state.code = c1 + dv * dc / dvi * m;
+      //device.isacs.output.state.voltage = voltage;
+      
+      int32_t c1 = device.isacs.output.interpolator.settings.code[i - 1];
+      int32_t c2 = device.isacs.output.interpolator.settings.code[i];
+      uint32_t code = isacsInterpolate(voltage, v1, v2, c1, c2);
+      device.isacs.output.voltage = voltage;
+      device.controller.SSP.out[0] = code;
       return;
     }
   }
-  device.isacs.output.state.code = device.isacs.output.settings.code[device.isacs.output.settings.points - 1];
-  device.isacs.output.state.voltage = device.isacs.output.settings.voltage[device.isacs.output.settings.points - 1];
+  uint32_t code = device.isacs.output.interpolator.settings.code[device.isacs.output.interpolator.settings.points - 1];
+  device.isacs.output.voltage = device.isacs.output.interpolator.settings.voltage[device.isacs.output.interpolator.settings.points - 1];
+  device.controller.SSP.out[0] = code;
+}
+
+void isacsSetOutputCode(int32_t code) {
+  int32_t c1, c2;
+  for (uint8_t i = 1; i < device.isacs.output.interpolator.settings.points; i++) {
+    c1 = device.isacs.output.interpolator.settings.code[i - 1];
+    if (code < c1) {
+      device.isacs.output.voltage = device.isacs.output.interpolator.settings.voltage[i - 1];
+      device.controller.SSP.out[0] = c1;
+      return;
+    }
+
+    c2 = device.isacs.output.interpolator.settings.code[i];
+    if (code < c2) {
+      int32_t v1 = device.isacs.output.interpolator.settings.voltage[i - 1];
+      int32_t v2 = device.isacs.output.interpolator.settings.voltage[i];
+      device.isacs.output.voltage = isacsInterpolate(code, c1, c2, v1, v2);
+      device.controller.SSP.out[0] = code;
+      return;
+    }
+  }
+  device.isacs.output.voltage = device.isacs.output.interpolator.settings.voltage[device.isacs.output.interpolator.settings.points - 1];
+  device.controller.SSP.out[0] = device.isacs.output.interpolator.settings.code[device.isacs.output.interpolator.settings.points - 1];
+}
+*/
+
+void isacsProcess(void) {
+  device.isacs.input.voltage = isacsInputCodeToVoltage(device.controller.SSP.in[4]);
+  device.isacs.input.sum += device.isacs.input.voltage;
+  if (device.measurement.counter == 31) {
+    device.isacs.input.average = device.isacs.input.sum >> 5;
+    device.isacs.input.sum = 0;
+    
+    if (device.isacs.regulator.state.enabled) {
+      device.isacs.regulator.state.error = device.isacs.regulator.state.reference - device.isacs.input.average;
+      device.isacs.output.voltage += device.isacs.regulator.state.error * device.isacs.regulator.state.scale;
+      device.controller.SSP.out[0] = isacsOutputVoltageToCode(device.isacs.output.voltage);
+    }
+  }
 }
\ No newline at end of file