Keisuke Sehara
/
STM32_Whisking
fast-feedback virtual target task code on STM Nucleo
states.cpp@32:1416e015016c, 2018-12-13 (annotated)
- Committer:
- gwappa
- Date:
- Thu Dec 13 07:18:43 2018 +0000
- Revision:
- 32:1416e015016c
- Parent:
- 31:b320ca61a8c0
change to use the Staged state
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
gwappa | 4:fcf597f82632 | 1 | #include "states.h" |
gwappa | 4:fcf597f82632 | 2 | #include "rig.h" |
gwappa | 4:fcf597f82632 | 3 | #include "automaton.h" |
gwappa | 27:b31ea8d74f9e | 4 | #include "scheduler.h" |
gwappa | 4:fcf597f82632 | 5 | #include "IO.h" |
gwappa | 4:fcf597f82632 | 6 | |
gwappa | 4:fcf597f82632 | 7 | #define STATE_IS_LOGGED |
gwappa | 4:fcf597f82632 | 8 | |
gwappa | 4:fcf597f82632 | 9 | #ifdef STATE_IS_LOGGED |
gwappa | 4:fcf597f82632 | 10 | #define LOGSTATE(S) IO::info(#S); |
gwappa | 4:fcf597f82632 | 11 | #else |
gwappa | 4:fcf597f82632 | 12 | #define LOGSTATE(S) |
gwappa | 4:fcf597f82632 | 13 | #endif |
gwappa | 4:fcf597f82632 | 14 | |
gwappa | 4:fcf597f82632 | 15 | void finalize() { |
gwappa | 29:1fb060aab1f8 | 16 | trial.markTrialEnd(task); |
gwappa | 27:b31ea8d74f9e | 17 | scheduler::reset(); |
gwappa | 4:fcf597f82632 | 18 | } |
gwappa | 4:fcf597f82632 | 19 | |
gwappa | 4:fcf597f82632 | 20 | void Delay::setup() { |
gwappa | 4:fcf597f82632 | 21 | LOGSTATE(Delay) |
gwappa | 4:fcf597f82632 | 22 | |
gwappa | 4:fcf597f82632 | 23 | // initialize the trial-related params |
gwappa | 4:fcf597f82632 | 24 | trial.reset(task); |
gwappa | 4:fcf597f82632 | 25 | |
gwappa | 11:897ecd5413e0 | 26 | // set up the timeout for the next state |
gwappa | 9:e136394bdb39 | 27 | switch (task.mode.value) { |
gwappa | 16:33c17c62840e | 28 | case MotionAlt: |
gwappa | 32:1416e015016c | 29 | scheduler::set(ms_to_us(trial.delay_dur_ms + task.prep_dur_ms.value), &automaton::jump<Delay,Staged>); |
gwappa | 16:33c17c62840e | 30 | break; |
gwappa | 9:e136394bdb39 | 31 | default: |
gwappa | 31:b320ca61a8c0 | 32 | if (task.prep_dur_ms.value > 0) { |
gwappa | 31:b320ca61a8c0 | 33 | scheduler::set(ms_to_us(trial.delay_dur_ms), &automaton::jump<Delay,Prepare>); |
gwappa | 31:b320ca61a8c0 | 34 | } else { |
gwappa | 32:1416e015016c | 35 | switch (task.mode.value) { |
gwappa | 32:1416e015016c | 36 | case Pair: |
gwappa | 31:b320ca61a8c0 | 37 | scheduler::set(ms_to_us(trial.delay_dur_ms), &automaton::jump<Delay,Paired>); |
gwappa | 32:1416e015016c | 38 | break; |
gwappa | 32:1416e015016c | 39 | case Report: |
gwappa | 31:b320ca61a8c0 | 40 | scheduler::set(ms_to_us(trial.delay_dur_ms), &automaton::jump<Delay,Cued>); |
gwappa | 32:1416e015016c | 41 | break; |
gwappa | 32:1416e015016c | 42 | case Stage: |
gwappa | 32:1416e015016c | 43 | case Associate: |
gwappa | 32:1416e015016c | 44 | case Motion: |
gwappa | 32:1416e015016c | 45 | scheduler::set(ms_to_us(trial.delay_dur_ms), &automaton::jump<Delay,Staged>); |
gwappa | 31:b320ca61a8c0 | 46 | } |
gwappa | 31:b320ca61a8c0 | 47 | } |
gwappa | 7:6744ec9ccc25 | 48 | } |
gwappa | 4:fcf597f82632 | 49 | |
gwappa | 11:897ecd5413e0 | 50 | trial.markTrialStart(); |
gwappa | 4:fcf597f82632 | 51 | } |
gwappa | 4:fcf597f82632 | 52 | |
gwappa | 4:fcf597f82632 | 53 | void Delay::teardown() { |
gwappa | 4:fcf597f82632 | 54 | // do nothing |
gwappa | 4:fcf597f82632 | 55 | } |
gwappa | 4:fcf597f82632 | 56 | |
gwappa | 31:b320ca61a8c0 | 57 | void Prepare::setup() { |
gwappa | 31:b320ca61a8c0 | 58 | // mostly the same with for Delay |
gwappa | 31:b320ca61a8c0 | 59 | // except that the animal cannot lick freely |
gwappa | 31:b320ca61a8c0 | 60 | |
gwappa | 31:b320ca61a8c0 | 61 | LOGSTATE(Prepare) |
gwappa | 31:b320ca61a8c0 | 62 | |
gwappa | 31:b320ca61a8c0 | 63 | // configure the interrupts |
gwappa | 31:b320ca61a8c0 | 64 | lickIn.attach(&automaton::jump<Prepare,Abort>); |
gwappa | 31:b320ca61a8c0 | 65 | |
gwappa | 31:b320ca61a8c0 | 66 | // set timeout for the next state |
gwappa | 32:1416e015016c | 67 | switch (task.mode.value) { |
gwappa | 32:1416e015016c | 68 | case Pair: |
gwappa | 32:1416e015016c | 69 | scheduler::set(ms_to_us(task.prep_dur_ms.value), &automaton::jump<Prepare,Paired>); |
gwappa | 32:1416e015016c | 70 | break; |
gwappa | 32:1416e015016c | 71 | case Report: |
gwappa | 32:1416e015016c | 72 | scheduler::set(ms_to_us(task.prep_dur_ms.value), &automaton::jump<Prepare,Cued>); |
gwappa | 32:1416e015016c | 73 | break; |
gwappa | 32:1416e015016c | 74 | case Stage: |
gwappa | 32:1416e015016c | 75 | case Associate: |
gwappa | 32:1416e015016c | 76 | case Motion: |
gwappa | 32:1416e015016c | 77 | scheduler::set(ms_to_us(task.prep_dur_ms.value), &automaton::jump<Delay,Staged>); |
gwappa | 32:1416e015016c | 78 | } |
gwappa | 31:b320ca61a8c0 | 79 | } |
gwappa | 31:b320ca61a8c0 | 80 | |
gwappa | 31:b320ca61a8c0 | 81 | void Prepare::teardown() { |
gwappa | 31:b320ca61a8c0 | 82 | // de-register lick inhibition |
gwappa | 31:b320ca61a8c0 | 83 | lickIn.detach(); |
gwappa | 31:b320ca61a8c0 | 84 | } |
gwappa | 31:b320ca61a8c0 | 85 | |
gwappa | 32:1416e015016c | 86 | void Staged::setup() { |
gwappa | 32:1416e015016c | 87 | LOGSTATE(Staged) |
gwappa | 32:1416e015016c | 88 | |
gwappa | 32:1416e015016c | 89 | trial.markEndOfWait(); |
gwappa | 32:1416e015016c | 90 | audioOut.attachTurnOffCallback(&automaton::jump<Staged,NoResp>); |
gwappa | 32:1416e015016c | 91 | audioOut.run(); |
gwappa | 32:1416e015016c | 92 | |
gwappa | 32:1416e015016c | 93 | switch (task.mode.value) { |
gwappa | 32:1416e015016c | 94 | case Stage: |
gwappa | 32:1416e015016c | 95 | // no punishment in response to lick |
gwappa | 32:1416e015016c | 96 | if (visualOut.isEnabled()) { |
gwappa | 32:1416e015016c | 97 | lickIn.detach(); // if any |
gwappa | 32:1416e015016c | 98 | // silently goes to the paired state |
gwappa | 32:1416e015016c | 99 | visualOut.attachTurnOnCallback(&automaton::jump<Staged,Paired>); |
gwappa | 32:1416e015016c | 100 | } else { |
gwappa | 32:1416e015016c | 101 | lickIn.attach(&Staged::logCatch); |
gwappa | 32:1416e015016c | 102 | } |
gwappa | 32:1416e015016c | 103 | break; |
gwappa | 32:1416e015016c | 104 | case MotionAlt: |
gwappa | 32:1416e015016c | 105 | // no punishment in response to lick |
gwappa | 32:1416e015016c | 106 | // silently goes to the rewarded state |
gwappa | 32:1416e015016c | 107 | trial.flag.cued = true; |
gwappa | 32:1416e015016c | 108 | gateIn.attach(&automaton::jump<Staged,WithResp>); |
gwappa | 32:1416e015016c | 109 | break; |
gwappa | 32:1416e015016c | 110 | case Associate: |
gwappa | 32:1416e015016c | 111 | lickIn.attach(&automaton::jump<Staged,WithResp>); // catch trial |
gwappa | 32:1416e015016c | 112 | visualOut.attachTurnOnCallback(&automaton::jump<Staged,Cued>); |
gwappa | 32:1416e015016c | 113 | break; |
gwappa | 32:1416e015016c | 114 | case Motion: |
gwappa | 32:1416e015016c | 115 | lickIn.attach(&automaton::jump<Staged,WithResp>); // catch trial |
gwappa | 32:1416e015016c | 116 | gateIn.attach(&automaton::jump<Staged,Cued>); |
gwappa | 32:1416e015016c | 117 | } |
gwappa | 32:1416e015016c | 118 | |
gwappa | 32:1416e015016c | 119 | switch (task.mode.value) { |
gwappa | 32:1416e015016c | 120 | case Motion: |
gwappa | 32:1416e015016c | 121 | case MotionAlt: |
gwappa | 32:1416e015016c | 122 | break; |
gwappa | 32:1416e015016c | 123 | case Stage: |
gwappa | 32:1416e015016c | 124 | case Associate: |
gwappa | 32:1416e015016c | 125 | default: |
gwappa | 32:1416e015016c | 126 | visualOut.run(); // should run with an appropriate delay |
gwappa | 32:1416e015016c | 127 | // and activates gateIn later |
gwappa | 32:1416e015016c | 128 | } |
gwappa | 32:1416e015016c | 129 | } |
gwappa | 32:1416e015016c | 130 | |
gwappa | 32:1416e015016c | 131 | void Staged::logCatch() { |
gwappa | 32:1416e015016c | 132 | trial.flag.responded = true; |
gwappa | 32:1416e015016c | 133 | } |
gwappa | 32:1416e015016c | 134 | |
gwappa | 32:1416e015016c | 135 | void Staged::teardown() { |
gwappa | 32:1416e015016c | 136 | gateIn.detach(); |
gwappa | 32:1416e015016c | 137 | lickIn.detach(); // if any |
gwappa | 32:1416e015016c | 138 | audioOut.detachTurnOffCallback(); // in case the next state fails to do so |
gwappa | 32:1416e015016c | 139 | } |
gwappa | 32:1416e015016c | 140 | |
gwappa | 29:1fb060aab1f8 | 141 | void Paired::setup() { |
gwappa | 29:1fb060aab1f8 | 142 | LOGSTATE(Paired) |
gwappa | 28:797536a42b9f | 143 | |
gwappa | 32:1416e015016c | 144 | if (task.mode.value == Pair) { |
gwappa | 32:1416e015016c | 145 | trial.markEndOfWait(); |
gwappa | 32:1416e015016c | 146 | visualOut.run(); |
gwappa | 32:1416e015016c | 147 | } |
gwappa | 29:1fb060aab1f8 | 148 | trial.flag.cued = true; |
gwappa | 32:1416e015016c | 149 | visualOut.attachTurnOffCallback(&automaton::jump<Paired,Monitored>); |
gwappa | 31:b320ca61a8c0 | 150 | lickIn.attach(&automaton::jump<Paired,Hit>); |
gwappa | 28:797536a42b9f | 151 | } |
gwappa | 28:797536a42b9f | 152 | |
gwappa | 29:1fb060aab1f8 | 153 | void Paired::teardown() { |
gwappa | 31:b320ca61a8c0 | 154 | visualOut.detachTurnOffCallback(); // if any |
gwappa | 31:b320ca61a8c0 | 155 | lickIn.detach(); // if any |
gwappa | 31:b320ca61a8c0 | 156 | } |
gwappa | 31:b320ca61a8c0 | 157 | |
gwappa | 31:b320ca61a8c0 | 158 | void Hit::setup() { |
gwappa | 31:b320ca61a8c0 | 159 | LOGSTATE(Hit) |
gwappa | 31:b320ca61a8c0 | 160 | trial.flag.rewarded = false; // force "test" trial mode |
gwappa | 31:b320ca61a8c0 | 161 | scheduler::set(ms_to_us(1), &automaton::jump<Hit,WithResp>); |
gwappa | 31:b320ca61a8c0 | 162 | } |
gwappa | 31:b320ca61a8c0 | 163 | |
gwappa | 31:b320ca61a8c0 | 164 | void Hit::teardown() { |
gwappa | 31:b320ca61a8c0 | 165 | // do nothing |
gwappa | 28:797536a42b9f | 166 | } |
gwappa | 28:797536a42b9f | 167 | |
gwappa | 4:fcf597f82632 | 168 | void Cued::setup() { |
gwappa | 4:fcf597f82632 | 169 | LOGSTATE(Cued) |
gwappa | 4:fcf597f82632 | 170 | |
gwappa | 32:1416e015016c | 171 | if (task.mode.value == Report) { |
gwappa | 32:1416e015016c | 172 | trial.markEndOfWait(); |
gwappa | 32:1416e015016c | 173 | scheduler::set(ms_to_us(task.vis_dur_ms.value + task.resp_dur_ms.value), &automaton::jump<Cued,NoResp>); |
gwappa | 7:6744ec9ccc25 | 174 | } |
gwappa | 32:1416e015016c | 175 | scheduler::set(ms_to_us(task.vis_dur_ms.value + task.resp_dur_ms.value), &automaton::jump<Cued,NoResp>); |
gwappa | 32:1416e015016c | 176 | trial.flag.cued = true; |
gwappa | 7:6744ec9ccc25 | 177 | |
gwappa | 26:b4421d1ee57a | 178 | lickIn.attach(&automaton::jump<Cued,WithResp>); |
gwappa | 7:6744ec9ccc25 | 179 | } |
gwappa | 7:6744ec9ccc25 | 180 | |
gwappa | 4:fcf597f82632 | 181 | void Cued::teardown() { |
gwappa | 26:b4421d1ee57a | 182 | lickIn.detach(); |
gwappa | 20:4c06d3041337 | 183 | |
gwappa | 7:6744ec9ccc25 | 184 | // end cue output |
gwappa | 20:4c06d3041337 | 185 | switch (task.mode.value) { |
gwappa | 20:4c06d3041337 | 186 | case Report: |
gwappa | 20:4c06d3041337 | 187 | case Associate: |
gwappa | 12:06ea96546af1 | 188 | visualOut.stop(); |
gwappa | 7:6744ec9ccc25 | 189 | } |
gwappa | 20:4c06d3041337 | 190 | |
gwappa | 20:4c06d3041337 | 191 | switch (task.mode.value) { |
gwappa | 32:1416e015016c | 192 | case Stage: |
gwappa | 20:4c06d3041337 | 193 | case Associate: |
gwappa | 20:4c06d3041337 | 194 | case Motion: |
gwappa | 20:4c06d3041337 | 195 | case MotionAlt: |
gwappa | 20:4c06d3041337 | 196 | audioOut.stop(); |
gwappa | 20:4c06d3041337 | 197 | } |
gwappa | 7:6744ec9ccc25 | 198 | } |
gwappa | 7:6744ec9ccc25 | 199 | |
gwappa | 7:6744ec9ccc25 | 200 | void Abort::setup() { |
gwappa | 7:6744ec9ccc25 | 201 | LOGSTATE(Abort) |
gwappa | 32:1416e015016c | 202 | |
gwappa | 32:1416e015016c | 203 | audioOut.stop(); // if any |
gwappa | 32:1416e015016c | 204 | visualOut.stop(); // if any |
gwappa | 11:897ecd5413e0 | 205 | trial.markEndOfWait(); |
gwappa | 19:50663f8815b8 | 206 | trial.flag.reset = true; |
gwappa | 27:b31ea8d74f9e | 207 | scheduler::set(ms_to_us(task.post_dur_ms.value), &automaton::done<Abort>); |
gwappa | 7:6744ec9ccc25 | 208 | } |
gwappa | 7:6744ec9ccc25 | 209 | |
gwappa | 7:6744ec9ccc25 | 210 | void Abort::teardown() { |
gwappa | 7:6744ec9ccc25 | 211 | finalize(); |
gwappa | 4:fcf597f82632 | 212 | } |
gwappa | 4:fcf597f82632 | 213 | |
gwappa | 32:1416e015016c | 214 | void Monitored::setup() { |
gwappa | 32:1416e015016c | 215 | LOGSTATE(Monitored) |
gwappa | 32:1416e015016c | 216 | |
gwappa | 32:1416e015016c | 217 | if (trial.flag.rewarded == true) { |
gwappa | 32:1416e015016c | 218 | rewardOut.run(); |
gwappa | 32:1416e015016c | 219 | } |
gwappa | 32:1416e015016c | 220 | lickIn.attach(&automaton::jump<Monitored,WithResp>); |
gwappa | 32:1416e015016c | 221 | scheduler::set(ms_to_us(task.resp_dur_ms.value), &automaton::jump<Monitored,NoResp>); |
gwappa | 32:1416e015016c | 222 | } |
gwappa | 32:1416e015016c | 223 | |
gwappa | 32:1416e015016c | 224 | void Monitored::teardown() { |
gwappa | 32:1416e015016c | 225 | audioOut.stop(); // if any |
gwappa | 32:1416e015016c | 226 | lickIn.detach(); |
gwappa | 32:1416e015016c | 227 | rewardOut.wait(); |
gwappa | 32:1416e015016c | 228 | } |
gwappa | 32:1416e015016c | 229 | |
gwappa | 4:fcf597f82632 | 230 | void WithResp::setup() { |
gwappa | 4:fcf597f82632 | 231 | LOGSTATE(WithResp) |
gwappa | 4:fcf597f82632 | 232 | |
gwappa | 19:50663f8815b8 | 233 | trial.flag.responded = true; |
gwappa | 32:1416e015016c | 234 | |
gwappa | 32:1416e015016c | 235 | audioOut.stop(); // if any (for Stage/MotionAlt) |
gwappa | 32:1416e015016c | 236 | visualOut.stop(); // if any |
gwappa | 4:fcf597f82632 | 237 | |
gwappa | 32:1416e015016c | 238 | switch (task.mode.value) { |
gwappa | 32:1416e015016c | 239 | case Pair: |
gwappa | 32:1416e015016c | 240 | case Stage: |
gwappa | 30:5f975f572ffb | 241 | if (!trial.flag.rewarded) { |
gwappa | 30:5f975f572ffb | 242 | rewardOut.start(); |
gwappa | 30:5f975f572ffb | 243 | } |
gwappa | 32:1416e015016c | 244 | break; |
gwappa | 32:1416e015016c | 245 | case Report: |
gwappa | 32:1416e015016c | 246 | case Associate: |
gwappa | 32:1416e015016c | 247 | case Motion: |
gwappa | 32:1416e015016c | 248 | case MotionAlt: |
gwappa | 32:1416e015016c | 249 | if (trial.flag.cued) { |
gwappa | 32:1416e015016c | 250 | rewardOut.start(); |
gwappa | 32:1416e015016c | 251 | } |
gwappa | 9:e136394bdb39 | 252 | } |
gwappa | 4:fcf597f82632 | 253 | |
gwappa | 27:b31ea8d74f9e | 254 | scheduler::set(ms_to_us(task.post_dur_ms.value), &automaton::done<WithResp>); |
gwappa | 4:fcf597f82632 | 255 | } |
gwappa | 4:fcf597f82632 | 256 | |
gwappa | 4:fcf597f82632 | 257 | void WithResp::teardown() { |
gwappa | 4:fcf597f82632 | 258 | finalize(); |
gwappa | 4:fcf597f82632 | 259 | } |
gwappa | 4:fcf597f82632 | 260 | |
gwappa | 4:fcf597f82632 | 261 | void NoResp::setup() { |
gwappa | 4:fcf597f82632 | 262 | LOGSTATE(NoResp) |
gwappa | 32:1416e015016c | 263 | |
gwappa | 27:b31ea8d74f9e | 264 | scheduler::set(ms_to_us(task.post_dur_ms.value), &automaton::done<NoResp>); |
gwappa | 4:fcf597f82632 | 265 | } |
gwappa | 4:fcf597f82632 | 266 | void NoResp::teardown() { |
gwappa | 4:fcf597f82632 | 267 | finalize(); |
gwappa | 8:973dcd190672 | 268 | } |
gwappa | 8:973dcd190672 | 269 | |
gwappa | 8:973dcd190672 | 270 | void TestReward::setup() { |
gwappa | 8:973dcd190672 | 271 | LOGSTATE(TestReward) |
gwappa | 8:973dcd190672 | 272 | |
gwappa | 8:973dcd190672 | 273 | // open/close the valve |
gwappa | 16:33c17c62840e | 274 | rewardOut.setOnset(0); |
gwappa | 16:33c17c62840e | 275 | rewardOut.setDuration(ms_to_us(task.reward_dur_ms.value)); |
gwappa | 11:897ecd5413e0 | 276 | rewardOut.start(); |
gwappa | 27:b31ea8d74f9e | 277 | |
gwappa | 27:b31ea8d74f9e | 278 | scheduler::set(ms_to_us(task.reward_dur_ms.value+100), &automaton::done<TestReward>); |
gwappa | 8:973dcd190672 | 279 | } |
gwappa | 8:973dcd190672 | 280 | |
gwappa | 8:973dcd190672 | 281 | void TestReward::teardown() { |
gwappa | 8:973dcd190672 | 282 | // do nothing |
gwappa | 30:5f975f572ffb | 283 | } |
gwappa | 30:5f975f572ffb | 284 | |
gwappa | 30:5f975f572ffb | 285 | void ClearTrialIndex::setup() { |
gwappa | 30:5f975f572ffb | 286 | trial.index = 1; |
gwappa | 31:b320ca61a8c0 | 287 | scheduler::set(ms_to_us(10), &automaton::done<ClearTrialIndex>); |
gwappa | 30:5f975f572ffb | 288 | } |
gwappa | 30:5f975f572ffb | 289 | |
gwappa | 30:5f975f572ffb | 290 | void ClearTrialIndex::teardown() { |
gwappa | 30:5f975f572ffb | 291 | // do nothing |
gwappa | 30:5f975f572ffb | 292 | } |