fast-feedback virtual target task code on STM Nucleo

Dependencies:   mbed

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?

UserRevisionLine numberNew 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 }