The codebase to run the *spark d-fuser controller www.sparkav.co.uk/dvimixer

Dependencies:   SPK-TVOne DMX DmxArtNet NetServicesMin OSC PinDetect mRotaryEncoder iniparser mbed spk_oled_ssd1305 filter

Committer:
tobyspark
Date:
Sun May 12 18:38:47 2013 +0000
Revision:
57:14d37904c889
Parent:
51:98cc27390484
Child:
62:523de36d2f88
UX around EDID changing (and detecting that, and enqueueing the messages)

Who changed what in which revision?

UserRevisionLine numberNew contents of line
tobyspark 8:d46cc49f0f37 1 // *SPARK D-FUSER
tobyspark 8:d46cc49f0f37 2 // A project by Toby Harris
tobyspark 8:d46cc49f0f37 3 // Copyright *spark audio-visual 2012
tobyspark 8:d46cc49f0f37 4 //
tobyspark 8:d46cc49f0f37 5 // SPK_UTILS provides utility classes for the main SPK-DVIMXR codebase, most significantly the menu system.
tobyspark 8:d46cc49f0f37 6
tobyspark 0:87aab40d5806 7 #include <string>
tobyspark 0:87aab40d5806 8 #include <vector>
tobyspark 57:14d37904c889 9 #include <queue>
tobyspark 0:87aab40d5806 10
tobyspark 0:87aab40d5806 11 class SPKIndexInRange {
tobyspark 0:87aab40d5806 12 public:
tobyspark 0:87aab40d5806 13 void operator = (int newIndex) {
tobyspark 0:87aab40d5806 14 set(newIndex);
tobyspark 0:87aab40d5806 15 }
tobyspark 0:87aab40d5806 16
tobyspark 0:87aab40d5806 17 void operator ++ (int) {
tobyspark 0:87aab40d5806 18 if (idx == max) idx = wrap ? min : max;
tobyspark 0:87aab40d5806 19 else idx++;
tobyspark 0:87aab40d5806 20 }
tobyspark 0:87aab40d5806 21
tobyspark 0:87aab40d5806 22 void operator -- (int) {
tobyspark 0:87aab40d5806 23 if (idx == min) idx = wrap ? max : min;
tobyspark 0:87aab40d5806 24 else idx--;
tobyspark 0:87aab40d5806 25 }
tobyspark 0:87aab40d5806 26
tobyspark 0:87aab40d5806 27 void set (int newIndex) {
tobyspark 0:87aab40d5806 28 if (newIndex > max) idx = max;
tobyspark 0:87aab40d5806 29 else if (newIndex < min) idx = min;
tobyspark 0:87aab40d5806 30 else idx = newIndex;
tobyspark 0:87aab40d5806 31 }
tobyspark 0:87aab40d5806 32
tobyspark 0:87aab40d5806 33 void set (int newMin, int newMax, int newIndex = 0, bool newWrap = false) {
tobyspark 0:87aab40d5806 34 min = newMin;
tobyspark 0:87aab40d5806 35 max = newMax;
tobyspark 0:87aab40d5806 36 wrap = newWrap;
tobyspark 0:87aab40d5806 37 set(newIndex);
tobyspark 0:87aab40d5806 38 }
tobyspark 0:87aab40d5806 39
tobyspark 0:87aab40d5806 40 void setMax(int newMax) {
tobyspark 0:87aab40d5806 41 max = newMax;
tobyspark 0:87aab40d5806 42 }
tobyspark 0:87aab40d5806 43
tobyspark 0:87aab40d5806 44 SPKIndexInRange () {
tobyspark 0:87aab40d5806 45 min = 0;
tobyspark 0:87aab40d5806 46 max = 1;
tobyspark 0:87aab40d5806 47 wrap = true;
tobyspark 0:87aab40d5806 48 idx = 0;
tobyspark 0:87aab40d5806 49 }
tobyspark 0:87aab40d5806 50
tobyspark 0:87aab40d5806 51 SPKIndexInRange (int newMin, int newMax, int newIndex = 0, bool newWrap = false) {
tobyspark 0:87aab40d5806 52 set(newMin, newMax, newIndex, newWrap);
tobyspark 0:87aab40d5806 53 }
tobyspark 0:87aab40d5806 54
tobyspark 0:87aab40d5806 55 int index() {
tobyspark 0:87aab40d5806 56 return idx;
tobyspark 0:87aab40d5806 57 }
tobyspark 0:87aab40d5806 58
tobyspark 0:87aab40d5806 59 private:
tobyspark 0:87aab40d5806 60 int idx;
tobyspark 0:87aab40d5806 61 int min, max;
tobyspark 0:87aab40d5806 62 bool wrap;
tobyspark 0:87aab40d5806 63 };
tobyspark 0:87aab40d5806 64
tobyspark 23:909928cafb95 65 class SPKMenu;
tobyspark 23:909928cafb95 66
tobyspark 23:909928cafb95 67 class SPKMenuItem {
tobyspark 23:909928cafb95 68 public:
tobyspark 49:16309f39cead 69 enum itemType { changesToMenu, sendsCommand, hasHandler };
tobyspark 23:909928cafb95 70 itemType type;
tobyspark 23:909928cafb95 71 string text;
tobyspark 49:16309f39cead 72 void (*handler)(int, bool);
tobyspark 23:909928cafb95 73 union {
tobyspark 23:909928cafb95 74 SPKMenu* menu;
tobyspark 23:909928cafb95 75 int32_t command[2];
tobyspark 49:16309f39cead 76 void (*handler)(int, bool);
tobyspark 23:909928cafb95 77 } payload;
tobyspark 23:909928cafb95 78
tobyspark 49:16309f39cead 79 SPKMenuItem(string title, SPKMenu* menu)
tobyspark 23:909928cafb95 80 {
tobyspark 23:909928cafb95 81 text = title;
tobyspark 23:909928cafb95 82 type = changesToMenu;
tobyspark 23:909928cafb95 83 payload.menu = menu;
tobyspark 23:909928cafb95 84 }
tobyspark 23:909928cafb95 85
tobyspark 49:16309f39cead 86 SPKMenuItem(void (*menuItemHandler)(int, bool))
tobyspark 49:16309f39cead 87 {
tobyspark 49:16309f39cead 88 text = "[has handler]";
tobyspark 49:16309f39cead 89 type = hasHandler;
tobyspark 49:16309f39cead 90 payload.handler = menuItemHandler;
tobyspark 49:16309f39cead 91 }
tobyspark 49:16309f39cead 92
tobyspark 23:909928cafb95 93 SPKMenuItem(string title, int32_t command)
tobyspark 23:909928cafb95 94 {
tobyspark 23:909928cafb95 95 text = title;
tobyspark 23:909928cafb95 96 type = sendsCommand;
tobyspark 23:909928cafb95 97 payload.command[0] = command;
tobyspark 23:909928cafb95 98 payload.command[1] = 0;
tobyspark 23:909928cafb95 99 }
tobyspark 23:909928cafb95 100
tobyspark 23:909928cafb95 101 SPKMenuItem(string title, int32_t command1, int32_t command2)
tobyspark 23:909928cafb95 102 {
tobyspark 23:909928cafb95 103 text = title;
tobyspark 23:909928cafb95 104 type = sendsCommand;
tobyspark 23:909928cafb95 105 payload.command[0] = command1;
tobyspark 23:909928cafb95 106 payload.command[1] = command2;
tobyspark 23:909928cafb95 107 }
tobyspark 23:909928cafb95 108 };
tobyspark 23:909928cafb95 109
tobyspark 23:909928cafb95 110
tobyspark 0:87aab40d5806 111 class SPKMenu {
tobyspark 0:87aab40d5806 112 public:
tobyspark 0:87aab40d5806 113 SPKMenu() {
tobyspark 0:87aab40d5806 114 selected.set(0, 0, 0, true);
tobyspark 0:87aab40d5806 115 }
tobyspark 0:87aab40d5806 116
tobyspark 0:87aab40d5806 117 std::string title;
tobyspark 0:87aab40d5806 118
tobyspark 5:f8b285ca41ba 119 SPKMenu& operator = (const int &newIndex) {
tobyspark 0:87aab40d5806 120 selected = newIndex;
tobyspark 5:f8b285ca41ba 121 return *this;
tobyspark 0:87aab40d5806 122 }
tobyspark 0:87aab40d5806 123
tobyspark 0:87aab40d5806 124 void operator ++ () {
tobyspark 0:87aab40d5806 125 selected++;
tobyspark 0:87aab40d5806 126 }
tobyspark 0:87aab40d5806 127
tobyspark 0:87aab40d5806 128 void operator -- () {
tobyspark 0:87aab40d5806 129 selected--;
tobyspark 0:87aab40d5806 130 }
tobyspark 0:87aab40d5806 131
tobyspark 23:909928cafb95 132 void addMenuItem (SPKMenuItem menuItem) {
tobyspark 23:909928cafb95 133 items.push_back(menuItem);
tobyspark 23:909928cafb95 134 selected.setMax(items.size()-1);
tobyspark 23:909928cafb95 135 }
tobyspark 23:909928cafb95 136
tobyspark 23:909928cafb95 137 void clearMenuItems() {
tobyspark 23:909928cafb95 138 items.clear();
tobyspark 23:909928cafb95 139 selected.setMax(0);
tobyspark 0:87aab40d5806 140 }
tobyspark 0:87aab40d5806 141
tobyspark 0:87aab40d5806 142 int selectedIndex() {
tobyspark 0:87aab40d5806 143 return selected.index();
tobyspark 0:87aab40d5806 144 }
tobyspark 0:87aab40d5806 145
tobyspark 24:49c6624119ae 146 std::string selectedString() {
tobyspark 24:49c6624119ae 147 if (items.size() == 0) printf("SPKMenu no items");
tobyspark 23:909928cafb95 148 return items[selected.index()].text;
tobyspark 23:909928cafb95 149 }
tobyspark 23:909928cafb95 150
tobyspark 23:909928cafb95 151 SPKMenuItem selectedItem() {
tobyspark 24:49c6624119ae 152 if (items.size() == 0) printf("SPKMenu no items");
tobyspark 23:909928cafb95 153 return items[selected.index()];
tobyspark 0:87aab40d5806 154 }
tobyspark 0:87aab40d5806 155
tobyspark 0:87aab40d5806 156 protected:
tobyspark 0:87aab40d5806 157 SPKIndexInRange selected;
tobyspark 23:909928cafb95 158 std::vector<SPKMenuItem> items;
tobyspark 0:87aab40d5806 159 };
tobyspark 0:87aab40d5806 160
tobyspark 0:87aab40d5806 161
tobyspark 0:87aab40d5806 162 class SPKSign {
tobyspark 0:87aab40d5806 163 public:
tobyspark 0:87aab40d5806 164 SPKSign(PinName signWrite, PinName signError) {
tobyspark 0:87aab40d5806 165 writeDO = new DigitalOut(signWrite);
tobyspark 0:87aab40d5806 166 errorDO = new DigitalOut(signError);
tobyspark 0:87aab40d5806 167 }
tobyspark 0:87aab40d5806 168
tobyspark 0:87aab40d5806 169 ~SPKSign() {
tobyspark 0:87aab40d5806 170 delete writeDO;
tobyspark 0:87aab40d5806 171 delete errorDO;
tobyspark 0:87aab40d5806 172 }
tobyspark 0:87aab40d5806 173
tobyspark 0:87aab40d5806 174 void serialWrite() {
tobyspark 0:87aab40d5806 175 signWriteTimeout.detach();
tobyspark 0:87aab40d5806 176 signWriteTimeout.attach(this, &SPKSign::writeOff, 0.25);
tobyspark 0:87aab40d5806 177 *writeDO = 1;
tobyspark 0:87aab40d5806 178 }
tobyspark 0:87aab40d5806 179
tobyspark 0:87aab40d5806 180 void serialError() {
tobyspark 0:87aab40d5806 181 signErrorTimeout.detach();
tobyspark 0:87aab40d5806 182 signErrorTimeout.attach(this, &SPKSign::errorOff, 0.25);
tobyspark 0:87aab40d5806 183 *errorDO = 1;
tobyspark 0:87aab40d5806 184 }
tobyspark 0:87aab40d5806 185
tobyspark 0:87aab40d5806 186 private:
tobyspark 0:87aab40d5806 187 void writeOff() {
tobyspark 0:87aab40d5806 188 *writeDO = 0;
tobyspark 0:87aab40d5806 189 }
tobyspark 0:87aab40d5806 190
tobyspark 0:87aab40d5806 191 void errorOff() {
tobyspark 0:87aab40d5806 192 *errorDO = 0;
tobyspark 0:87aab40d5806 193 }
tobyspark 0:87aab40d5806 194
tobyspark 0:87aab40d5806 195 DigitalOut *writeDO;
tobyspark 0:87aab40d5806 196 DigitalOut *errorDO;
tobyspark 0:87aab40d5806 197 Timeout signWriteTimeout;
tobyspark 0:87aab40d5806 198 Timeout signErrorTimeout;
tobyspark 0:87aab40d5806 199 };
tobyspark 0:87aab40d5806 200
tobyspark 48:c0fedfa8c525 201 class SPKMessageHold {
tobyspark 48:c0fedfa8c525 202 public:
tobyspark 0:87aab40d5806 203
tobyspark 48:c0fedfa8c525 204 SPKMessageHold() {
tobyspark 48:c0fedfa8c525 205 holding = false;
tobyspark 48:c0fedfa8c525 206 currentMessage = "";
tobyspark 57:14d37904c889 207 savedMessage = "";
tobyspark 48:c0fedfa8c525 208 }
tobyspark 48:c0fedfa8c525 209
tobyspark 57:14d37904c889 210 void addMessage(string message, float minimumSeconds)
tobyspark 57:14d37904c889 211 {
tobyspark 57:14d37904c889 212 if (holding)
tobyspark 48:c0fedfa8c525 213 {
tobyspark 57:14d37904c889 214 if (minimumSeconds > 0.0f) enqueuedMessages.push( make_pair(message, minimumSeconds) );
tobyspark 57:14d37904c889 215 else savedMessage = message;
tobyspark 48:c0fedfa8c525 216 }
tobyspark 48:c0fedfa8c525 217 else
tobyspark 48:c0fedfa8c525 218 {
tobyspark 57:14d37904c889 219 if (minimumSeconds > 0.0f)
tobyspark 57:14d37904c889 220 {
tobyspark 57:14d37904c889 221 timeout.detach();
tobyspark 57:14d37904c889 222 timeout.attach(this, &SPKMessageHold::handleTimeout, minimumSeconds);
tobyspark 57:14d37904c889 223 holding = true;
tobyspark 57:14d37904c889 224 savedMessage = currentMessage;
tobyspark 57:14d37904c889 225 currentMessage = message;
tobyspark 57:14d37904c889 226 }
tobyspark 57:14d37904c889 227 else
tobyspark 57:14d37904c889 228 {
tobyspark 57:14d37904c889 229 currentMessage = message;
tobyspark 57:14d37904c889 230 }
tobyspark 48:c0fedfa8c525 231 }
tobyspark 48:c0fedfa8c525 232 }
tobyspark 48:c0fedfa8c525 233
tobyspark 48:c0fedfa8c525 234 string message() { return currentMessage; }
tobyspark 0:87aab40d5806 235
tobyspark 48:c0fedfa8c525 236 private:
tobyspark 57:14d37904c889 237 void handleTimeout()
tobyspark 57:14d37904c889 238 {
tobyspark 57:14d37904c889 239 if (enqueuedMessages.empty())
tobyspark 57:14d37904c889 240 {
tobyspark 57:14d37904c889 241 currentMessage = savedMessage;
tobyspark 57:14d37904c889 242 holding = false;
tobyspark 57:14d37904c889 243 }
tobyspark 57:14d37904c889 244 else
tobyspark 57:14d37904c889 245 {
tobyspark 57:14d37904c889 246 currentMessage = enqueuedMessages.front().first;
tobyspark 57:14d37904c889 247 float secs = enqueuedMessages.front().second;
tobyspark 57:14d37904c889 248 enqueuedMessages.pop();
tobyspark 57:14d37904c889 249
tobyspark 57:14d37904c889 250 timeout.attach(this, &SPKMessageHold::handleTimeout, secs);
tobyspark 57:14d37904c889 251 }
tobyspark 48:c0fedfa8c525 252 }
tobyspark 48:c0fedfa8c525 253
tobyspark 48:c0fedfa8c525 254 bool holding;
tobyspark 48:c0fedfa8c525 255 string currentMessage;
tobyspark 57:14d37904c889 256 string savedMessage;
tobyspark 57:14d37904c889 257 queue< pair<string, float> >enqueuedMessages;
tobyspark 48:c0fedfa8c525 258 Timeout timeout;
tobyspark 48:c0fedfa8c525 259 };