*/
class LedPatternRX51 : LedPattern {
- public string led_map;
+ public LedColor color1;
+ public LedColor color2;
public List<LedCommandRX51> engine1;
public List<LedCommandRX51> engine2;
priority = p[0].to_int ();
screen_on = p[1].to_int ();
timeout = p[2].to_int ();
- led_map = p[3];
+ parse_led_map (p[3], out color1, out color2);
engine1 = parse_pattern (p[4]);
engine2 = parse_pattern (p[5]);
on_changed ();
}
+ private void parse_led_map (string led_map, out LedColor color1, out LedColor color2) {
+ color1 = LedColor.OFF;
+ color2 = LedColor.OFF;
+ if ("r" in led_map)
+ color1 |= LedColor.R;
+ if ("g" in led_map)
+ color1 |= LedColor.G;
+ if ("b" in led_map)
+ color1 |= LedColor.B;
+ if ("R" in led_map)
+ color2 |= LedColor.R;
+ if ("G" in led_map)
+ color2 |= LedColor.G;
+ if ("B" in led_map)
+ color2 |= LedColor.B;
+ }
+
private List<LedCommandRX51> parse_pattern (string pattern) {
var list = new List<LedCommandRX51> ();
var length = pattern.length;
}
public string dump () {
- return "%s=%d;%d;%d;%s;%s;%s".printf (name, priority, screen_on, timeout, led_map,
+ return "%s=%d;%d;%d;%s;%s;%s".printf (name, priority, screen_on, timeout, dump_led_map (),
dump_pattern (engine1), dump_pattern (engine2));
}
+ private string dump_led_map () {
+ string led_map = "";
+ if (LedColor.R in color1)
+ led_map += "r";
+ if (LedColor.R in color2)
+ led_map += "R";
+ if (LedColor.G in color1)
+ led_map += "g";
+ if (LedColor.G in color2)
+ led_map += "G";
+ if (LedColor.B in color1)
+ led_map += "b";
+ if (LedColor.B in color2)
+ led_map += "B";
+ return led_map;
+ }
+
private string dump_pattern (List<LedCommandRX51> list) {
string result = "";
foreach (LedCommandRX51 command in list) {
pattern.duration = duration;
- pattern.led_map = led_map;
+ pattern.color1 = color1;
+ pattern.color2 = color2;
pattern.engine1 = deep_copy (pattern, engine1);
pattern.engine2 = deep_copy (pattern, engine2);
duration = pattern.duration;
- led_map = pattern.led_map;
+ color1 = pattern.color1;
+ color2 = pattern.color2;
engine1 = deep_copy (this, pattern.engine1);
engine2 = deep_copy (this, pattern.engine2);
changed ();
}
- void on_changed () {
- // calculate timing and level info
+ public void on_changed () {
+ bool unresolved = calculate_timing ();
+ if (unresolved)
+ unresolved = calculate_timing ();
+ if (unresolved)
+ Hildon.Banner.show_information (null, null, "Timing unresolved");
+ changed ();
+ }
+
+ private bool calculate_timing () {
+ bool unresolved = false;
+ // Calculate timing and level info for engine 1
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 (command.type == CommandType.TRIGGER &&
+ (command.code & 0x0180) != 0) {
+ command.duration = wait_for_trigger (time, engine2);
+ if (command.duration == 0)
+ unresolved = true;
+ command.duration += 16 * LedCommandRX51.CYCLE_TIME_MS;
+ }
+ time += command.duration;
if (level < 0)
level = 0;
if (level > 255)
level = 255;
}
duration = time;
- changed ();
+ // Calculate timing and level info for engine 2
+ time = 0;
+ level = 0;
+ foreach (LedCommandRX51 command in engine2) {
+ command.time = time;
+ if (command.type == CommandType.SET_PWM) {
+ level = command.level;
+ } else {
+ command.level = level;
+ level += command.steps;
+ }
+ if (command.type == CommandType.TRIGGER &&
+ (command.code & 0x0180) != 0) {
+ command.duration = wait_for_trigger (time, engine1);
+ if (command.duration == 0)
+ unresolved = true;
+ command.duration += 16 * LedCommandRX51.CYCLE_TIME_MS;
+ }
+ time += command.duration;
+ if (level < 0)
+ level = 0;
+ if (level > 255)
+ level = 255;
+ }
+ if (time > duration)
+ duration = time;
+ return unresolved;
+ }
+
+ double wait_for_trigger (double time, List<LedCommandRX51> engine) {
+ double duration = 0;
+ bool repeat = false;
+ foreach (LedCommandRX51 command in engine) {
+ duration = command.time + command.duration;
+ if (command.type == CommandType.TRIGGER &&
+ (command.code & 0x0006) != 0 && command.time > time) {
+ return command.time - time;
+ }
+ if (command.type == CommandType.GO_TO_START) {
+ repeat = true;
+ break;
+ }
+ }
+ if (repeat) foreach (LedCommandRX51 command in engine) {
+ if (command.type == CommandType.TRIGGER &&
+ (command.code & 0x0006) != 0 && (duration + command.time) > time) {
+ return duration + command.time - time;
+ }
+ }
+ return 0;
}
}
class LedCommandRX51 : LedCommand {
- private const double CYCLE_TIME_MS = 1000.0 / 32768.0;
+ internal const double CYCLE_TIME_MS = 1000.0 / 32768.0;
public uint16 code;
// 0x1000: interrupt
if ((code & 0x0800) != 0) // Reset
steps = -255;
- } else if ((code & ~ 0x13f0) == 0xe000) {
+ } else if ((code & ~ 0x13fe) == 0xe000) {
type = CommandType.TRIGGER;
// 0x1000: wait ext
// 0x0380: wait B G R
// 0x0040: set ext
- // ??: set B G R
+ // 0x000e: set B G R
}
}
}
public override void ramp_wait (double _step_time, int _steps) requires (_step_time >= (16 * CYCLE_TIME_MS)) {
int step_time;
- if (_step_time <= 31 * (16 * CYCLE_TIME_MS)) {
+ if (_step_time < 32 * (16 * CYCLE_TIME_MS)) {
step_time = (int) ((_step_time + 0.001) / (16 * CYCLE_TIME_MS));
code = (uint16) step_time << 9;
_step_time = step_time * (16 * CYCLE_TIME_MS);
- } else if (_step_time <= 31*(512 * CYCLE_TIME_MS)) {
- step_time = (int) ((_step_time + 0.01) / (512 * CYCLE_TIME_MS));
+ } else if (_step_time < 32*(512 * CYCLE_TIME_MS)) {
+ step_time = (int) ((_step_time + 0.001) / (512 * CYCLE_TIME_MS));
code = 0x4000 | (step_time << 9);
_step_time = step_time * (512 * CYCLE_TIME_MS);
} else {
base.ramp_wait (_step_time, _steps);
}
+ public override void go_to_start () {
+ code = 0x0000;
+ base.go_to_start ();
+ }
+
+ public override void end (bool reset) {
+ code = 0xc000;
+ if (reset)
+ code |= 0x0800;
+ base.end (reset);
+ }
+
public LedCommandRX51 copy () {
var command = new LedCommandRX51 ();