fast-feedback virtual target task code on STM Nucleo

Dependencies:   mbed

Committer:
gwappa
Date:
Thu May 31 15:25:37 2018 +0000
Revision:
8:973dcd190672
Parent:
7:6744ec9ccc25
Child:
9:e136394bdb39
current working

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 4:fcf597f82632 36 void finalize() {
gwappa 4:fcf597f82632 37 taskOut.write(0);
gwappa 7:6744ec9ccc25 38 cueOut.write(0); // if any
gwappa 4:fcf597f82632 39 trial.writeToSerial();
gwappa 4:fcf597f82632 40 timer.stop();
gwappa 4:fcf597f82632 41 timer.reset();
gwappa 4:fcf597f82632 42 }
gwappa 4:fcf597f82632 43
gwappa 4:fcf597f82632 44 void Delay::setup() {
gwappa 4:fcf597f82632 45 LOGSTATE(Delay)
gwappa 4:fcf597f82632 46
gwappa 4:fcf597f82632 47 // initialize the trial-related params
gwappa 4:fcf597f82632 48 trial.reset(task);
gwappa 4:fcf597f82632 49
gwappa 4:fcf597f82632 50 // configure the flags
gwappa 4:fcf597f82632 51 taskOut.write(1);
gwappa 4:fcf597f82632 52 cueOut.write(0);
gwappa 7:6744ec9ccc25 53 if ( (task.mode.value == Pair) || (task.mode.value == Report) ) {
gwappa 7:6744ec9ccc25 54 enableOut.write(1);
gwappa 7:6744ec9ccc25 55 } else {
gwappa 7:6744ec9ccc25 56 enableOut.write(0);
gwappa 7:6744ec9ccc25 57 }
gwappa 4:fcf597f82632 58 rewardOut.write(0);
gwappa 4:fcf597f82632 59
gwappa 4:fcf597f82632 60 // configure the interrupts
gwappa 4:fcf597f82632 61 whiskIn.rise(&whiskcallback);
gwappa 4:fcf597f82632 62 lickIn.rise(&lickcallback);
gwappa 4:fcf597f82632 63 // no whisk handler, no lick handler
gwappa 4:fcf597f82632 64 // only to be logged
gwappa 4:fcf597f82632 65 logged = true;
gwappa 4:fcf597f82632 66
gwappa 4:fcf597f82632 67 // sets the timeout for the next state
gwappa 7:6744ec9ccc25 68 if (task.mode.value == Pair) {
gwappa 7:6744ec9ccc25 69 stateTimeout.attach_us(&automaton::jump<Delay,Cued>, ms_to_us(trial.delay_dur_ms));
gwappa 7:6744ec9ccc25 70 } else {
gwappa 7:6744ec9ccc25 71 stateTimeout.attach_us(&automaton::jump<Delay,Prepare>, ms_to_us(trial.delay_dur_ms));
gwappa 7:6744ec9ccc25 72 }
gwappa 4:fcf597f82632 73
gwappa 4:fcf597f82632 74 // update the timestamp
gwappa 4:fcf597f82632 75 trial.starting = timer.read_ms();
gwappa 4:fcf597f82632 76 timer.start();
gwappa 4:fcf597f82632 77 }
gwappa 4:fcf597f82632 78
gwappa 4:fcf597f82632 79 void Delay::teardown() {
gwappa 4:fcf597f82632 80 // do nothing
gwappa 4:fcf597f82632 81 }
gwappa 4:fcf597f82632 82
gwappa 7:6744ec9ccc25 83 void Prepare::setup() {
gwappa 7:6744ec9ccc25 84 // mostly the same with for Delay
gwappa 7:6744ec9ccc25 85 // except that the animal cannot lick freely
gwappa 7:6744ec9ccc25 86 LOGSTATE(Prepare)
gwappa 7:6744ec9ccc25 87
gwappa 7:6744ec9ccc25 88 // configure the interrupts
gwappa 7:6744ec9ccc25 89 // no whisk handler (i.e. only to be logged)
gwappa 7:6744ec9ccc25 90 lickhandler = &automaton::jump<Prepare,Abort>;
gwappa 7:6744ec9ccc25 91
gwappa 7:6744ec9ccc25 92 // set timeout for the next state
gwappa 7:6744ec9ccc25 93 stateTimeout.attach_us(&automaton::jump<Prepare,Cued>, ms_to_us(task.prep_dur_ms.value));
gwappa 7:6744ec9ccc25 94 }
gwappa 7:6744ec9ccc25 95
gwappa 7:6744ec9ccc25 96 void Prepare::teardown() {
gwappa 7:6744ec9ccc25 97 // de-register lick inhibition
gwappa 7:6744ec9ccc25 98 lickhandler = 0;
gwappa 7:6744ec9ccc25 99 }
gwappa 7:6744ec9ccc25 100
gwappa 4:fcf597f82632 101 void Cued::setup() {
gwappa 4:fcf597f82632 102 LOGSTATE(Cued)
gwappa 4:fcf597f82632 103
gwappa 7:6744ec9ccc25 104 if (task.mode.value == Report) {
gwappa 7:6744ec9ccc25 105 enableOut.write(1); // enable the feedback only during Cued
gwappa 7:6744ec9ccc25 106 }
gwappa 7:6744ec9ccc25 107
gwappa 4:fcf597f82632 108 // configure the interrupts
gwappa 7:6744ec9ccc25 109 if (task.mode.value == Pair) {
gwappa 8:973dcd190672 110 whiskhandler = &automaton::jump<Cued,WithResp>;
gwappa 8:973dcd190672 111 trial.response |= TrialFlags::Cues;
gwappa 8:973dcd190672 112 lickhandler = 0;
gwappa 7:6744ec9ccc25 113
gwappa 7:6744ec9ccc25 114 } else {
gwappa 7:6744ec9ccc25 115 whiskhandler = &Cued::gate;
gwappa 7:6744ec9ccc25 116 lickhandler = &automaton::jump<Cued,Abort>;
gwappa 7:6744ec9ccc25 117 }
gwappa 7:6744ec9ccc25 118
gwappa 7:6744ec9ccc25 119 // start cue output
gwappa 7:6744ec9ccc25 120 cueOut.write(1);
gwappa 4:fcf597f82632 121
gwappa 4:fcf597f82632 122 // sets the timeout for the next state
gwappa 7:6744ec9ccc25 123 stateTimeout.attach_us(&automaton::jump<Cued,NoResp>, ms_to_us(task.cue_dur_ms.value));
gwappa 4:fcf597f82632 124
gwappa 4:fcf597f82632 125 // update the timestamp
gwappa 4:fcf597f82632 126 trial.cuestarting = timer.read_ms();
gwappa 4:fcf597f82632 127 trial.waiting = trial.cuestarting - trial.starting;
gwappa 4:fcf597f82632 128 }
gwappa 4:fcf597f82632 129
gwappa 7:6744ec9ccc25 130 void Cued::gate() {
gwappa 7:6744ec9ccc25 131 whiskhandler = 0; // logging only
gwappa 8:973dcd190672 132 trial.response |= TrialFlags::Cues;
gwappa 7:6744ec9ccc25 133 lickhandler = &automaton::jump<Cued,WithResp>;
gwappa 7:6744ec9ccc25 134 }
gwappa 7:6744ec9ccc25 135
gwappa 4:fcf597f82632 136 void Cued::teardown() {
gwappa 4:fcf597f82632 137 whiskhandler = 0;
gwappa 7:6744ec9ccc25 138 lickhandler = 0;
gwappa 7:6744ec9ccc25 139 // end cue output
gwappa 7:6744ec9ccc25 140 cueOut.write(0);
gwappa 7:6744ec9ccc25 141
gwappa 4:fcf597f82632 142 stateTimeout.detach();
gwappa 7:6744ec9ccc25 143
gwappa 7:6744ec9ccc25 144 if (task.mode.value == Report) {
gwappa 7:6744ec9ccc25 145 enableOut.write(0);
gwappa 7:6744ec9ccc25 146 }
gwappa 7:6744ec9ccc25 147 }
gwappa 7:6744ec9ccc25 148
gwappa 7:6744ec9ccc25 149 void Abort::setup() {
gwappa 7:6744ec9ccc25 150 LOGSTATE(Abort)
gwappa 8:973dcd190672 151 trial.waiting = timer.read_ms() - trial.starting;
gwappa 8:973dcd190672 152 trial.response = TrialFlags::Licked;
gwappa 8:973dcd190672 153 stateTimeout.attach_us(&automaton::done<Abort>, ms_to_us(task.post_dur_ms.value));
gwappa 7:6744ec9ccc25 154 }
gwappa 7:6744ec9ccc25 155
gwappa 7:6744ec9ccc25 156 void Abort::teardown() {
gwappa 7:6744ec9ccc25 157 finalize();
gwappa 4:fcf597f82632 158 }
gwappa 4:fcf597f82632 159
gwappa 4:fcf597f82632 160 void WithResp::setup() {
gwappa 4:fcf597f82632 161 LOGSTATE(WithResp)
gwappa 4:fcf597f82632 162
gwappa 4:fcf597f82632 163 trial.response |= TrialFlags::Responded;
gwappa 4:fcf597f82632 164
gwappa 7:6744ec9ccc25 165 whiskhandler = 0;
gwappa 7:6744ec9ccc25 166 lickhandler = 0;
gwappa 7:6744ec9ccc25 167
gwappa 7:6744ec9ccc25 168 // open/close the valve
gwappa 7:6744ec9ccc25 169 rewardOut.write(1);
gwappa 7:6744ec9ccc25 170 rewardTimeout.attach_us(&WithResp::stopReward, ms_to_us(task.reward_ms.value));
gwappa 4:fcf597f82632 171
gwappa 5:849446d19406 172 stateTimeout.attach_us(&automaton::done<WithResp>, ms_to_us(task.post_dur_ms.value));
gwappa 4:fcf597f82632 173 }
gwappa 4:fcf597f82632 174
gwappa 7:6744ec9ccc25 175 void WithResp::stopReward() {
gwappa 7:6744ec9ccc25 176 rewardOut.write(0);
gwappa 7:6744ec9ccc25 177 }
gwappa 7:6744ec9ccc25 178
gwappa 4:fcf597f82632 179 void WithResp::teardown() {
gwappa 4:fcf597f82632 180 finalize();
gwappa 4:fcf597f82632 181 }
gwappa 4:fcf597f82632 182
gwappa 4:fcf597f82632 183 void NoResp::setup() {
gwappa 4:fcf597f82632 184 LOGSTATE(NoResp)
gwappa 4:fcf597f82632 185
gwappa 7:6744ec9ccc25 186 // no reward here
gwappa 7:6744ec9ccc25 187
gwappa 5:849446d19406 188 stateTimeout.attach_us(&automaton::done<NoResp>, ms_to_us(task.post_dur_ms.value));
gwappa 4:fcf597f82632 189 }
gwappa 4:fcf597f82632 190 void NoResp::teardown() {
gwappa 4:fcf597f82632 191 finalize();
gwappa 8:973dcd190672 192 }
gwappa 8:973dcd190672 193
gwappa 8:973dcd190672 194 void TestReward::setup() {
gwappa 8:973dcd190672 195 LOGSTATE(TestReward)
gwappa 8:973dcd190672 196
gwappa 8:973dcd190672 197 // open/close the valve
gwappa 8:973dcd190672 198 rewardOut.write(1);
gwappa 8:973dcd190672 199 rewardTimeout.attach_us(&WithResp::stopReward, ms_to_us(task.reward_ms.value));
gwappa 8:973dcd190672 200 stateTimeout.attach_us(&automaton::done<TestReward>, ms_to_us(task.reward_ms.value+20));
gwappa 8:973dcd190672 201 }
gwappa 8:973dcd190672 202
gwappa 8:973dcd190672 203 void TestReward::teardown() {
gwappa 8:973dcd190672 204 // do nothing
gwappa 4:fcf597f82632 205 }