Add LED pattern class for RX51
authorPhilipp Zabel <philipp.zabel@gmail.com>
Wed, 24 Feb 2010 16:54:43 +0000 (17:54 +0100)
committerPhilipp Zabel <philipp.zabel@gmail.com>
Wed, 24 Feb 2010 17:55:50 +0000 (18:55 +0100)
Makefile
src/led-pattern-rx51.vala [new file with mode: 0644]
src/led-pattern.vala [new file with mode: 0644]

index db4d954..f57d8f9 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -20,7 +20,9 @@ all: ${pluginlib_LTLIBRARY}
 led_pattern_editor_SOURCES = $(patsubst %.vala,%.c,${led_pattern_editor_VALASOURCES})
 
 led_pattern_editor_VALASOURCES = \
-       src/led-pattern-editor.vala
+       src/led-pattern-editor.vala \
+       src/led-pattern.vala \
+       src/led-pattern-rx51.vala
 
 led_pattern_editor_VALAFLAGS = --pkg hildon-1 --pkg libosso
 
diff --git a/src/led-pattern-rx51.vala b/src/led-pattern-rx51.vala
new file mode 100644 (file)
index 0000000..84c7ca8
--- /dev/null
@@ -0,0 +1,237 @@
+/* This file is part of LED Pattern Editor.
+ *
+ * Copyright (C) 2010 Philipp Zabel
+ *
+ * LED Pattern Editor is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * LED Pattern Editor is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with LED Pattern Editor. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+class LedPatternRX51 : LedPattern {
+       public string led_map;
+       public List<LedCommandRX51> engine1;
+       public List<LedCommandRX51> engine2;
+
+       public void parse (string line) {
+               string[] key_value = line.split ("=");
+
+               if (key_value.length != 2) {
+                       print ("pattern line does not contain '=': %s\n", line);
+                       return;
+               }
+
+               string[] p = key_value[1].split (";");
+               if (p.length != 6) {
+                       print ("pattern does not contain 6 components: %d\n", p.length);
+                       return;
+               }
+
+               if (p[4].length > 16*4 || p[5].length > 16*4) {
+                       print ("pattern too long!\n");
+                       return;
+               }
+
+               name = key_value[0];
+               priority = p[0].to_int ();
+               screen_on = p[1].to_int ();
+               timeout = p[2].to_int ();
+               led_map = p[3];
+               engine1 = parse_pattern (p[4]);
+               engine2 = parse_pattern (p[5]);
+
+               if (engine1.first ().data.code != 0x9d80) {
+                       print ("engine1 pattern doesn't start with refresh mux command\n");
+               }
+               if (engine2.first ().data.code != 0x9d80) {
+                       print ("engine2 pattern doesn't start with refresh mux command\n");
+               }
+
+               on_changed ();
+       }
+
+       private List<LedCommandRX51> parse_pattern (string pattern) {
+               var list = new List<LedCommandRX51> ();
+               var length = pattern.length;
+
+               if (length % 4 != 0)
+                       return list;
+
+               char *p = ((char*) pattern) + length - 4;
+               while (p >= (char*) pattern) {
+                       var command = new LedCommandRX51.with_code ((uint16) ((string) p).to_ulong (null, 16));
+                       command.changed.connect (on_changed);
+                       list.prepend (command);
+                       p[0] = '\0';
+                       p -= 4;
+               }
+
+               return list;
+       }
+
+       public string dump () {
+               return "%s=%d;%d;%d;%s;%s;%s".printf (name, priority, screen_on, timeout, led_map,
+                                                     dump_pattern (engine1), dump_pattern (engine2));
+       }
+
+       private string dump_pattern (List<LedCommandRX51> list) {
+               string result = "";
+               foreach (LedCommandRX51 command in list) {
+                       result += "%04x".printf (command.code);
+               }
+               return result;
+       }
+
+       public LedPatternRX51 copy () {
+               var pattern = new LedPatternRX51 ();
+
+               pattern.name = name.dup ();
+               pattern.priority = priority;
+               pattern.screen_on = screen_on;
+               pattern.timeout = timeout;
+
+               pattern.duration = duration;
+
+               pattern.led_map = led_map;
+               pattern.engine1 = deep_copy (pattern, engine1);
+               pattern.engine2 = deep_copy (pattern, engine2);
+
+               return pattern;
+       }
+
+       public List<LedCommandRX51> deep_copy (LedPatternRX51 pattern, List<LedCommandRX51> list) {
+               var list2 = new List<LedCommandRX51> ();
+
+               foreach (LedCommandRX51 command in list) {
+                       var command2 = command.copy ();
+                       command2.changed.connect (pattern.on_changed);
+                       list2.append (command2);
+               }
+
+               return list2;
+       }
+
+       public void replace_with (LedPatternRX51 pattern) {
+               name = pattern.name;
+               priority = pattern.priority;
+               screen_on = pattern.screen_on;
+               timeout = pattern.timeout;
+
+               duration = pattern.duration;
+
+               led_map = pattern.led_map;
+               engine1 = deep_copy (this, pattern.engine1);
+               engine2 = deep_copy (this, pattern.engine2);
+
+               changed ();
+       }
+
+       void on_changed () {
+               // calculate timing and level info
+               double time = 0;
+               int level = 0;
+               foreach (LedCommandRX51 command in engine1) {
+                       command.time = time;
+                       time += command.duration;
+                       if (command.type == CommandType.SET_PWM) {
+                               level = command.level;
+                       } else {
+                               command.level = level;
+                               level += command.steps;
+                       }
+                       if (level < 0)
+                               level = 0;
+                       if (level > 255)
+                               level = 255;
+               }
+               duration = time;
+               changed ();
+       }
+}
+
+class LedCommandRX51 : LedCommand {
+       public uint16 code;
+
+       public LedCommandRX51 () {
+       }
+
+       public LedCommandRX51.with_code (uint16 _code) {
+               code = _code;
+               if ((code & 0x8000) == 0) {
+                       if (code == 0x0000) {
+                               type = CommandType.REPEAT;
+                       } else if ((code & 0x3e00) != 0) {
+                               type = CommandType.RAMP_WAIT;
+                               steps = code & 0xff;
+                               step_time = code >> 9;
+                               if ((code & 0x4000) == 0)
+                                       step_time = (code >> 9) * 0.49;
+                               else {
+                                       step_time = ((code & 0x3e00) >> 9) * 15.6;
+                               }
+                               duration = step_time * (steps + 1);
+                               if ((code & 0x100) != 0)
+                                       steps = -steps;
+                       } else {
+                               type = CommandType.SET_PWM;
+                               level = code & 0xff;
+                       }
+               } else {
+                       if (code == 0x9d80)
+                               type = CommandType.RESET_MUX;
+                       if (code == 0xc000)
+                               type = CommandType.STOP;
+                       //if (code == 0xe0??)
+                       //      type = CommandType.TRIGGER_WAIT;
+               }
+       }
+
+       public override void set_pwm (int _level) {
+               code = 0x4000 | _level;
+               base.set_pwm (_level);
+       }
+
+       public override void ramp_wait (double _step_time, int _steps) requires (_step_time >= 0.49) {
+               int step_time;
+               if (_step_time <= 31*0.49) {
+                       step_time = (int) ((_step_time + 0.001) / 0.49);
+                       code = (uint16) step_time << 9;
+                       _step_time = step_time * 0.49;
+               } else if (_step_time <= 31*15.6) {
+                       step_time = (int) ((_step_time + 0.01) / 15.6);
+                       code = 0x4000 | (step_time << 9);
+                       _step_time = step_time * 15.6;
+               } else {
+                       return;
+               }
+               if (_steps < 0) {
+                       code |= 0x100 | (-_steps);
+               } else {
+                       code |= _steps;
+               }
+               base.ramp_wait (_step_time, _steps);
+       }
+
+       public LedCommandRX51 copy () {
+               var command = new LedCommandRX51 ();
+
+               command.type = type;
+               command.time = time;
+               command.step_time = step_time;
+               command.duration = duration;
+               command.level = level;
+               command.steps = steps;
+
+               command.code = code;
+
+               return command;
+       }
+}
diff --git a/src/led-pattern.vala b/src/led-pattern.vala
new file mode 100644 (file)
index 0000000..25f1ae5
--- /dev/null
@@ -0,0 +1,75 @@
+/* This file is part of LED Pattern Editor.
+ *
+ * Copyright (C) 2010 Philipp Zabel
+ *
+ * LED Pattern Editor is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * LED Pattern Editor is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with LED Pattern Editor. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+class LedPattern : Object {
+       enum ScreenOn {
+               DISPLAY_OFF = 0,
+               DISPLAY_ON = 1,
+               DISPLAY_OFF_ACT_DEAD = 2,
+               DISPLAY_ON_ACT_DEAD = 3,
+               DISPLAY_OFF_OR_ACT_DEAD = 4,
+               DISABLED = 5
+       }
+
+       public string name;
+       public int priority;
+       public int screen_on;
+       public int timeout;
+
+       public double duration;
+
+       public signal void changed ();
+}
+
+enum CommandType {
+       UNKNOWN,
+       RESET_MUX,
+       SET_PWM,
+       RAMP_WAIT,
+       REPEAT,
+       STOP
+}
+
+class LedCommand : Object {
+       public CommandType type;
+       public double time;
+       public double step_time;
+       public double duration;
+       public int level;
+       public int steps;
+
+       public virtual void set_pwm (int _level) {
+               type = CommandType.SET_PWM;
+               level = _level;
+               changed ();
+       }
+
+       public virtual void ramp_wait (double _step_time, int _steps) {
+               type = CommandType.RAMP_WAIT;
+               step_time = _step_time;
+               steps = _steps;
+               if (steps < 0)
+                       duration = step_time * (1 - steps);
+               else
+                       duration = step_time * (steps + 1);
+               changed ();
+       }
+
+       public signal void changed ();
+}
+