fast-feedback virtual target task code on STM Nucleo

Dependencies:   mbed

Committer:
gwappa
Date:
Tue Jun 19 10:11:23 2018 +0000
Revision:
10:7c216d528c35
Parent:
9:e136394bdb39
Child:
11:897ecd5413e0
This is according to the way I planned originally

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 4:fcf597f82632 4 #include "IO.h"
gwappa 4:fcf597f82632 5
gwappa 4:fcf597f82632 6 #define STATE_IS_LOGGED
gwappa 4:fcf597f82632 7
gwappa 4:fcf597f82632 8 #ifdef STATE_IS_LOGGED
gwappa 4:fcf597f82632 9 #define LOGSTATE(S) IO::info(#S);
gwappa 4:fcf597f82632 10 #else
gwappa 4:fcf597f82632 11 #define LOGSTATE(S)
gwappa 4:fcf597f82632 12 #endif
gwappa 4:fcf597f82632 13
gwappa 4:fcf597f82632 14 void (*whiskhandler)() = 0;
gwappa 4:fcf597f82632 15 void (*lickhandler)() = 0;
gwappa 4:fcf597f82632 16 bool logged = false;
gwappa 4:fcf597f82632 17
gwappa 4:fcf597f82632 18 void whiskcallback() {
gwappa 4:fcf597f82632 19 if (logged) {
gwappa 4:fcf597f82632 20 trial.whisking_events.add(timer.read_ms());
gwappa 4:fcf597f82632 21 }
gwappa 4:fcf597f82632 22 if (whiskhandler != 0) {
gwappa 4:fcf597f82632 23 whiskhandler();
gwappa 4:fcf597f82632 24 }
gwappa 4:fcf597f82632 25 }
gwappa 4:fcf597f82632 26
gwappa 4:fcf597f82632 27 void lickcallback() {
gwappa 4:fcf597f82632 28 if (logged) {
gwappa 4:fcf597f82632 29 trial.licking_events.add(timer.read_ms());
gwappa 4:fcf597f82632 30 }
gwappa 4:fcf597f82632 31 if (lickhandler != 0) {
gwappa 4:fcf597f82632 32 lickhandler();
gwappa 4:fcf597f82632 33 }
gwappa 4:fcf597f82632 34 }
gwappa 4:fcf597f82632 35
gwappa 9:e136394bdb39 36 void turnOff_trialStart() {
gwappa 9:e136394bdb39 37 trialStart.write(0);
gwappa 9:e136394bdb39 38 }
gwappa 9:e136394bdb39 39
gwappa 9:e136394bdb39 40 void stopReward() {
gwappa 9:e136394bdb39 41 rewardOut.write(0);
gwappa 9:e136394bdb39 42 }
gwappa 9:e136394bdb39 43
gwappa 4:fcf597f82632 44 void finalize() {
gwappa 7:6744ec9ccc25 45 cueOut.write(0); // if any
gwappa 9:e136394bdb39 46 trialEnd.write(1);
gwappa 9:e136394bdb39 47 wait_us(ms_to_us(TRIGGER_DUR_MS));
gwappa 9:e136394bdb39 48
gwappa 4:fcf597f82632 49 trial.writeToSerial();
gwappa 4:fcf597f82632 50 timer.stop();
gwappa 4:fcf597f82632 51 timer.reset();
gwappa 4:fcf597f82632 52 }
gwappa 4:fcf597f82632 53
gwappa 4:fcf597f82632 54 void Delay::setup() {
gwappa 4:fcf597f82632 55 LOGSTATE(Delay)
gwappa 4:fcf597f82632 56
gwappa 4:fcf597f82632 57 // initialize the trial-related params
gwappa 4:fcf597f82632 58 trial.reset(task);
gwappa 4:fcf597f82632 59
gwappa 4:fcf597f82632 60 // configure the flags
gwappa 4:fcf597f82632 61 cueOut.write(0);
gwappa 9:e136394bdb39 62 if ( (task.mode.value == WithCue) || (task.mode.value == Report) ) {
gwappa 7:6744ec9ccc25 63 enableOut.write(1);
gwappa 7:6744ec9ccc25 64 } else {
gwappa 7:6744ec9ccc25 65 enableOut.write(0);
gwappa 7:6744ec9ccc25 66 }
gwappa 4:fcf597f82632 67 rewardOut.write(0);
gwappa 4:fcf597f82632 68
gwappa 4:fcf597f82632 69 // configure the interrupts
gwappa 4:fcf597f82632 70 whiskIn.rise(&whiskcallback);
gwappa 4:fcf597f82632 71 lickIn.rise(&lickcallback);
gwappa 4:fcf597f82632 72 // no whisk handler, no lick handler
gwappa 4:fcf597f82632 73 // only to be logged
gwappa 4:fcf597f82632 74 logged = true;
gwappa 4:fcf597f82632 75
gwappa 4:fcf597f82632 76 // sets the timeout for the next state
gwappa 9:e136394bdb39 77 switch (task.mode.value) {
gwappa 9:e136394bdb39 78 case Pair:
gwappa 9:e136394bdb39 79 stateTimeout.attach_us(&automaton::jump<Delay,Paired>, ms_to_us(trial.delay_dur_ms + task.prep_dur_ms.value));
gwappa 9:e136394bdb39 80 break;
gwappa 9:e136394bdb39 81 case WithCue:
gwappa 9:e136394bdb39 82 stateTimeout.attach_us(&automaton::jump<Delay,Cued>, ms_to_us(trial.delay_dur_ms + task.prep_dur_ms.value));
gwappa 9:e136394bdb39 83 break;
gwappa 9:e136394bdb39 84 default:
gwappa 7:6744ec9ccc25 85 stateTimeout.attach_us(&automaton::jump<Delay,Prepare>, ms_to_us(trial.delay_dur_ms));
gwappa 7:6744ec9ccc25 86 }
gwappa 4:fcf597f82632 87
gwappa 9:e136394bdb39 88 // trigger trialStart
gwappa 9:e136394bdb39 89 trialStart.write(1);
gwappa 9:e136394bdb39 90 triggerTimeout.attach_us(&turnOff_trialStart, ms_to_us(TRIGGER_DUR_MS));
gwappa 9:e136394bdb39 91
gwappa 4:fcf597f82632 92 // update the timestamp
gwappa 4:fcf597f82632 93 trial.starting = timer.read_ms();
gwappa 4:fcf597f82632 94 timer.start();
gwappa 4:fcf597f82632 95 }
gwappa 4:fcf597f82632 96
gwappa 4:fcf597f82632 97 void Delay::teardown() {
gwappa 4:fcf597f82632 98 // do nothing
gwappa 4:fcf597f82632 99 }
gwappa 4:fcf597f82632 100
gwappa 7:6744ec9ccc25 101 void Prepare::setup() {
gwappa 7:6744ec9ccc25 102 // mostly the same with for Delay
gwappa 7:6744ec9ccc25 103 // except that the animal cannot lick freely
gwappa 7:6744ec9ccc25 104 LOGSTATE(Prepare)
gwappa 7:6744ec9ccc25 105
gwappa 7:6744ec9ccc25 106 // configure the interrupts
gwappa 7:6744ec9ccc25 107 // no whisk handler (i.e. only to be logged)
gwappa 7:6744ec9ccc25 108 lickhandler = &automaton::jump<Prepare,Abort>;
gwappa 7:6744ec9ccc25 109
gwappa 7:6744ec9ccc25 110 // set timeout for the next state
gwappa 7:6744ec9ccc25 111 stateTimeout.attach_us(&automaton::jump<Prepare,Cued>, ms_to_us(task.prep_dur_ms.value));
gwappa 7:6744ec9ccc25 112 }
gwappa 7:6744ec9ccc25 113
gwappa 7:6744ec9ccc25 114 void Prepare::teardown() {
gwappa 7:6744ec9ccc25 115 // de-register lick inhibition
gwappa 7:6744ec9ccc25 116 lickhandler = 0;
gwappa 7:6744ec9ccc25 117 }
gwappa 7:6744ec9ccc25 118
gwappa 9:e136394bdb39 119 void Paired::setup() {
gwappa 9:e136394bdb39 120 LOGSTATE(Paired)
gwappa 9:e136394bdb39 121 trial.response |= TrialFlags::Cues;
gwappa 9:e136394bdb39 122 lickhandler = &automaton::jump<Paired,WithResp>;
gwappa 9:e136394bdb39 123
gwappa 9:e136394bdb39 124 // reward & visual feedback
gwappa 9:e136394bdb39 125 enableOut.write(1);
gwappa 10:7c216d528c35 126 trial.cuestarting = timer.read_ms();
gwappa 10:7c216d528c35 127 trial.waiting = trial.cuestarting - trial.starting;
gwappa 9:e136394bdb39 128
gwappa 9:e136394bdb39 129 rewardOut.write(1);
gwappa 9:e136394bdb39 130 rewardTimeout.attach_us(&stopReward, ms_to_us(task.reward_ms.value));
gwappa 9:e136394bdb39 131
gwappa 9:e136394bdb39 132 stateTimeout.attach_us(&automaton::jump<Paired,NoResp>, ms_to_us(task.cue_dur_ms.value));
gwappa 9:e136394bdb39 133 }
gwappa 9:e136394bdb39 134
gwappa 9:e136394bdb39 135 void Paired::teardown() {
gwappa 9:e136394bdb39 136 enableOut.write(0);
gwappa 9:e136394bdb39 137 }
gwappa 9:e136394bdb39 138
gwappa 4:fcf597f82632 139 void Cued::setup() {
gwappa 4:fcf597f82632 140 LOGSTATE(Cued)
gwappa 4:fcf597f82632 141
gwappa 7:6744ec9ccc25 142 if (task.mode.value == Report) {
gwappa 7:6744ec9ccc25 143 enableOut.write(1); // enable the feedback only during Cued
gwappa 7:6744ec9ccc25 144 }
gwappa 7:6744ec9ccc25 145
gwappa 4:fcf597f82632 146 // configure the interrupts
gwappa 9:e136394bdb39 147 if (task.mode.value == WithCue) {
gwappa 8:973dcd190672 148 whiskhandler = &automaton::jump<Cued,WithResp>;
gwappa 8:973dcd190672 149 trial.response |= TrialFlags::Cues;
gwappa 8:973dcd190672 150 lickhandler = 0;
gwappa 7:6744ec9ccc25 151
gwappa 7:6744ec9ccc25 152 } else {
gwappa 7:6744ec9ccc25 153 whiskhandler = &Cued::gate;
gwappa 7:6744ec9ccc25 154 lickhandler = &automaton::jump<Cued,Abort>;
gwappa 7:6744ec9ccc25 155 }
gwappa 7:6744ec9ccc25 156
gwappa 7:6744ec9ccc25 157 // start cue output
gwappa 7:6744ec9ccc25 158 cueOut.write(1);
gwappa 4:fcf597f82632 159
gwappa 4:fcf597f82632 160 // sets the timeout for the next state
gwappa 7:6744ec9ccc25 161 stateTimeout.attach_us(&automaton::jump<Cued,NoResp>, ms_to_us(task.cue_dur_ms.value));
gwappa 4:fcf597f82632 162
gwappa 4:fcf597f82632 163 // update the timestamp
gwappa 4:fcf597f82632 164 trial.cuestarting = timer.read_ms();
gwappa 4:fcf597f82632 165 trial.waiting = trial.cuestarting - trial.starting;
gwappa 4:fcf597f82632 166 }
gwappa 4:fcf597f82632 167
gwappa 7:6744ec9ccc25 168 void Cued::gate() {
gwappa 7:6744ec9ccc25 169 whiskhandler = 0; // logging only
gwappa 8:973dcd190672 170 trial.response |= TrialFlags::Cues;
gwappa 7:6744ec9ccc25 171 lickhandler = &automaton::jump<Cued,WithResp>;
gwappa 7:6744ec9ccc25 172 }
gwappa 7:6744ec9ccc25 173
gwappa 4:fcf597f82632 174 void Cued::teardown() {
gwappa 4:fcf597f82632 175 whiskhandler = 0;
gwappa 7:6744ec9ccc25 176 lickhandler = 0;
gwappa 7:6744ec9ccc25 177 // end cue output
gwappa 7:6744ec9ccc25 178 cueOut.write(0);
gwappa 7:6744ec9ccc25 179
gwappa 4:fcf597f82632 180 stateTimeout.detach();
gwappa 7:6744ec9ccc25 181
gwappa 7:6744ec9ccc25 182 if (task.mode.value == Report) {
gwappa 7:6744ec9ccc25 183 enableOut.write(0);
gwappa 7:6744ec9ccc25 184 }
gwappa 7:6744ec9ccc25 185 }
gwappa 7:6744ec9ccc25 186
gwappa 7:6744ec9ccc25 187 void Abort::setup() {
gwappa 7:6744ec9ccc25 188 LOGSTATE(Abort)
gwappa 8:973dcd190672 189 trial.waiting = timer.read_ms() - trial.starting;
gwappa 8:973dcd190672 190 trial.response = TrialFlags::Licked;
gwappa 8:973dcd190672 191 stateTimeout.attach_us(&automaton::done<Abort>, ms_to_us(task.post_dur_ms.value));
gwappa 7:6744ec9ccc25 192 }
gwappa 7:6744ec9ccc25 193
gwappa 7:6744ec9ccc25 194 void Abort::teardown() {
gwappa 7:6744ec9ccc25 195 finalize();
gwappa 4:fcf597f82632 196 }
gwappa 4:fcf597f82632 197
gwappa 4:fcf597f82632 198 void WithResp::setup() {
gwappa 4:fcf597f82632 199 LOGSTATE(WithResp)
gwappa 4:fcf597f82632 200
gwappa 4:fcf597f82632 201 trial.response |= TrialFlags::Responded;
gwappa 4:fcf597f82632 202
gwappa 7:6744ec9ccc25 203 whiskhandler = 0;
gwappa 7:6744ec9ccc25 204 lickhandler = 0;
gwappa 7:6744ec9ccc25 205
gwappa 9:e136394bdb39 206 if (task.mode.value != Pair) {
gwappa 9:e136394bdb39 207 // open/close the valve
gwappa 9:e136394bdb39 208 rewardOut.write(1);
gwappa 9:e136394bdb39 209 rewardTimeout.attach_us(&stopReward, ms_to_us(task.reward_ms.value));
gwappa 9:e136394bdb39 210 }
gwappa 4:fcf597f82632 211
gwappa 5:849446d19406 212 stateTimeout.attach_us(&automaton::done<WithResp>, ms_to_us(task.post_dur_ms.value));
gwappa 4:fcf597f82632 213 }
gwappa 4:fcf597f82632 214
gwappa 4:fcf597f82632 215 void WithResp::teardown() {
gwappa 4:fcf597f82632 216 finalize();
gwappa 4:fcf597f82632 217 }
gwappa 4:fcf597f82632 218
gwappa 4:fcf597f82632 219 void NoResp::setup() {
gwappa 4:fcf597f82632 220 LOGSTATE(NoResp)
gwappa 4:fcf597f82632 221
gwappa 7:6744ec9ccc25 222 // no reward here
gwappa 7:6744ec9ccc25 223
gwappa 5:849446d19406 224 stateTimeout.attach_us(&automaton::done<NoResp>, ms_to_us(task.post_dur_ms.value));
gwappa 4:fcf597f82632 225 }
gwappa 4:fcf597f82632 226 void NoResp::teardown() {
gwappa 4:fcf597f82632 227 finalize();
gwappa 8:973dcd190672 228 }
gwappa 8:973dcd190672 229
gwappa 8:973dcd190672 230 void TestReward::setup() {
gwappa 8:973dcd190672 231 LOGSTATE(TestReward)
gwappa 8:973dcd190672 232
gwappa 8:973dcd190672 233 // open/close the valve
gwappa 8:973dcd190672 234 rewardOut.write(1);
gwappa 9:e136394bdb39 235 rewardTimeout.attach_us(&stopReward, ms_to_us(task.reward_ms.value));
gwappa 8:973dcd190672 236 stateTimeout.attach_us(&automaton::done<TestReward>, ms_to_us(task.reward_ms.value+20));
gwappa 8:973dcd190672 237 }
gwappa 8:973dcd190672 238
gwappa 8:973dcd190672 239 void TestReward::teardown() {
gwappa 8:973dcd190672 240 // do nothing
gwappa 4:fcf597f82632 241 }