From 2aa86ffa70e4ce9848989513d26a41435189a46e Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Wed, 24 Feb 2010 17:54:43 +0100 Subject: [PATCH] Add LED pattern class for RX51 --- Makefile | 4 +- src/led-pattern-rx51.vala | 237 +++++++++++++++++++++++++++++++++++++++++++++ src/led-pattern.vala | 75 ++++++++++++++ 3 files changed, 315 insertions(+), 1 deletion(-) create mode 100644 src/led-pattern-rx51.vala create mode 100644 src/led-pattern.vala diff --git a/Makefile b/Makefile index db4d954..f57d8f9 100644 --- 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 index 0000000..84c7ca8 --- /dev/null +++ b/src/led-pattern-rx51.vala @@ -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 . + */ + +class LedPatternRX51 : LedPattern { + public string led_map; + public List engine1; + public List 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 parse_pattern (string pattern) { + var list = new List (); + 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 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 deep_copy (LedPatternRX51 pattern, List list) { + var list2 = new List (); + + 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 index 0000000..25f1ae5 --- /dev/null +++ b/src/led-pattern.vala @@ -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 . + */ + +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 (); +} + -- 1.7.9.5