fast-feedback virtual target task code on STM Nucleo

Dependencies:   mbed

Committer:
gwappa
Date:
Mon Jun 25 14:47:41 2018 +0000
Revision:
14:af3adf5d5ddf
Parent:
13:8ea85a33e37a
Child:
15:20f7f737c256
working version

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 12:06ea96546af1 4 #include "events.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 11:897ecd5413e0 15 void tickBuzzer() {
gwappa 11:897ecd5413e0 16 audioOut = !audioOut;
gwappa 9:e136394bdb39 17 }
gwappa 9:e136394bdb39 18
gwappa 4:fcf597f82632 19 void finalize() {
gwappa 11:897ecd5413e0 20 audioOut.write(0); // if any
gwappa 11:897ecd5413e0 21 trial.markTrialEnd();
gwappa 4:fcf597f82632 22 }
gwappa 4:fcf597f82632 23
gwappa 4:fcf597f82632 24 void Delay::setup() {
gwappa 4:fcf597f82632 25 LOGSTATE(Delay)
gwappa 4:fcf597f82632 26
gwappa 4:fcf597f82632 27 // initialize the trial-related params
gwappa 4:fcf597f82632 28 trial.reset(task);
gwappa 11:897ecd5413e0 29 audioOut.write(0);
gwappa 11:897ecd5413e0 30 rewardOut.setDuration(ms_to_us(task.reward_ms.value));
gwappa 12:06ea96546af1 31 events::setup(true);
gwappa 4:fcf597f82632 32
gwappa 11:897ecd5413e0 33 // set up the timeout for the next state
gwappa 9:e136394bdb39 34 switch (task.mode.value) {
gwappa 9:e136394bdb39 35 case Pair:
gwappa 9:e136394bdb39 36 stateTimeout.attach_us(&automaton::jump<Delay,Paired>, ms_to_us(trial.delay_dur_ms + task.prep_dur_ms.value));
gwappa 9:e136394bdb39 37 break;
gwappa 9:e136394bdb39 38 default:
gwappa 7:6744ec9ccc25 39 stateTimeout.attach_us(&automaton::jump<Delay,Prepare>, ms_to_us(trial.delay_dur_ms));
gwappa 7:6744ec9ccc25 40 }
gwappa 4:fcf597f82632 41
gwappa 11:897ecd5413e0 42 trial.markTrialStart();
gwappa 4:fcf597f82632 43 }
gwappa 4:fcf597f82632 44
gwappa 4:fcf597f82632 45 void Delay::teardown() {
gwappa 4:fcf597f82632 46 // do nothing
gwappa 4:fcf597f82632 47 }
gwappa 4:fcf597f82632 48
gwappa 11:897ecd5413e0 49 void Paired::setup() {
gwappa 11:897ecd5413e0 50 LOGSTATE(Paired)
gwappa 11:897ecd5413e0 51 trial.markEndOfWait();
gwappa 11:897ecd5413e0 52
gwappa 12:06ea96546af1 53 trial.response |= TrialFlags::Cues;
gwappa 12:06ea96546af1 54 events::lickhandler = &automaton::jump<Paired,WithResp>;
gwappa 11:897ecd5413e0 55
gwappa 11:897ecd5413e0 56 // reward & visual feedback
gwappa 11:897ecd5413e0 57 visualOut.direct(true);
gwappa 11:897ecd5413e0 58 rewardOut.start();
gwappa 11:897ecd5413e0 59
gwappa 11:897ecd5413e0 60 stateTimeout.attach_us(&automaton::jump<Paired,NoResp>, ms_to_us(task.aud_dur_ms.value));
gwappa 11:897ecd5413e0 61 }
gwappa 11:897ecd5413e0 62
gwappa 11:897ecd5413e0 63 void Paired::teardown() {
gwappa 11:897ecd5413e0 64 visualOut.direct(false);
gwappa 12:06ea96546af1 65 events::lickhandler = 0;
gwappa 11:897ecd5413e0 66 }
gwappa 11:897ecd5413e0 67
gwappa 7:6744ec9ccc25 68 void Prepare::setup() {
gwappa 7:6744ec9ccc25 69 // mostly the same with for Delay
gwappa 7:6744ec9ccc25 70 // except that the animal cannot lick freely
gwappa 7:6744ec9ccc25 71 LOGSTATE(Prepare)
gwappa 7:6744ec9ccc25 72
gwappa 7:6744ec9ccc25 73 // configure the interrupts
gwappa 12:06ea96546af1 74 // no whisk handler
gwappa 12:06ea96546af1 75 events::lickhandler = &automaton::jump<Prepare,Abort>;
gwappa 7:6744ec9ccc25 76
gwappa 7:6744ec9ccc25 77 // set timeout for the next state
gwappa 7:6744ec9ccc25 78 stateTimeout.attach_us(&automaton::jump<Prepare,Cued>, ms_to_us(task.prep_dur_ms.value));
gwappa 7:6744ec9ccc25 79 }
gwappa 7:6744ec9ccc25 80
gwappa 7:6744ec9ccc25 81 void Prepare::teardown() {
gwappa 7:6744ec9ccc25 82 // de-register lick inhibition
gwappa 12:06ea96546af1 83 events::lickhandler = 0;
gwappa 9:e136394bdb39 84 }
gwappa 9:e136394bdb39 85
gwappa 4:fcf597f82632 86 void Cued::setup() {
gwappa 4:fcf597f82632 87 LOGSTATE(Cued)
gwappa 4:fcf597f82632 88
gwappa 11:897ecd5413e0 89 trial.markEndOfWait();
gwappa 7:6744ec9ccc25 90
gwappa 4:fcf597f82632 91 // configure the interrupts
gwappa 12:06ea96546af1 92 events::lickhandler = &automaton::jump<Cued,Abort>;
gwappa 11:897ecd5413e0 93
gwappa 11:897ecd5413e0 94 // "cue" comes from either internal visual stimulus generation (Report, Associate)
gwappa 11:897ecd5413e0 95 // or the animal's whisker motion (Motion)
gwappa 11:897ecd5413e0 96 if (task.mode.value == Motion) {
gwappa 12:06ea96546af1 97 events::whiskhandler = &Cued::gate;
gwappa 7:6744ec9ccc25 98 } else {
gwappa 12:06ea96546af1 99 events::gatehandler = &Cued::gate;
gwappa 7:6744ec9ccc25 100 }
gwappa 7:6744ec9ccc25 101
gwappa 7:6744ec9ccc25 102 // start cue output
gwappa 14:af3adf5d5ddf 103 switch(task.mode.value) {
gwappa 14:af3adf5d5ddf 104 case Report:
gwappa 14:af3adf5d5ddf 105 case Associate:
gwappa 14:af3adf5d5ddf 106 visualOut.run();
gwappa 14:af3adf5d5ddf 107 // fallthrough
gwappa 14:af3adf5d5ddf 108 case Motion:
gwappa 11:897ecd5413e0 109 audioOut.write(1);
gwappa 11:897ecd5413e0 110 buzzerTicker.attach_us(&tickBuzzer, trial.aud_ticker_cycle);
gwappa 11:897ecd5413e0 111 }
gwappa 4:fcf597f82632 112
gwappa 4:fcf597f82632 113 // sets the timeout for the next state
gwappa 11:897ecd5413e0 114 stateTimeout.attach_us(&automaton::jump<Cued,NoResp>, ms_to_us(task.aud_dur_ms.value));
gwappa 4:fcf597f82632 115 }
gwappa 4:fcf597f82632 116
gwappa 7:6744ec9ccc25 117 void Cued::gate() {
gwappa 12:06ea96546af1 118 events::gatehandler = 0;
gwappa 12:06ea96546af1 119 events::whiskhandler = 0;
gwappa 12:06ea96546af1 120 trial.response |= TrialFlags::Cues;
gwappa 12:06ea96546af1 121 events::lickhandler = &automaton::jump<Cued,WithResp>;
gwappa 7:6744ec9ccc25 122 }
gwappa 7:6744ec9ccc25 123
gwappa 4:fcf597f82632 124 void Cued::teardown() {
gwappa 12:06ea96546af1 125 events::whiskhandler = 0;
gwappa 12:06ea96546af1 126 events::lickhandler = 0;
gwappa 12:06ea96546af1 127 events::gatehandler = 0;
gwappa 7:6744ec9ccc25 128 // end cue output
gwappa 11:897ecd5413e0 129 buzzerTicker.detach();
gwappa 11:897ecd5413e0 130 audioOut.write(0);
gwappa 11:897ecd5413e0 131 if (task.mode.value != Motion) {
gwappa 12:06ea96546af1 132 visualOut.stop();
gwappa 7:6744ec9ccc25 133 }
gwappa 7:6744ec9ccc25 134 }
gwappa 7:6744ec9ccc25 135
gwappa 7:6744ec9ccc25 136 void Abort::setup() {
gwappa 7:6744ec9ccc25 137 LOGSTATE(Abort)
gwappa 14:af3adf5d5ddf 138 events::whiskhandler = 0;
gwappa 14:af3adf5d5ddf 139 events::lickhandler = 0;
gwappa 14:af3adf5d5ddf 140 events::gatehandler = 0;
gwappa 11:897ecd5413e0 141 trial.markEndOfWait();
gwappa 8:973dcd190672 142 trial.response = TrialFlags::Licked;
gwappa 8:973dcd190672 143 stateTimeout.attach_us(&automaton::done<Abort>, ms_to_us(task.post_dur_ms.value));
gwappa 7:6744ec9ccc25 144 }
gwappa 7:6744ec9ccc25 145
gwappa 7:6744ec9ccc25 146 void Abort::teardown() {
gwappa 7:6744ec9ccc25 147 finalize();
gwappa 4:fcf597f82632 148 }
gwappa 4:fcf597f82632 149
gwappa 4:fcf597f82632 150 void WithResp::setup() {
gwappa 4:fcf597f82632 151 LOGSTATE(WithResp)
gwappa 4:fcf597f82632 152
gwappa 4:fcf597f82632 153 trial.response |= TrialFlags::Responded;
gwappa 14:af3adf5d5ddf 154 events::whiskhandler = 0;
gwappa 14:af3adf5d5ddf 155 events::lickhandler = 0;
gwappa 14:af3adf5d5ddf 156 events::gatehandler = 0;
gwappa 4:fcf597f82632 157
gwappa 9:e136394bdb39 158 if (task.mode.value != Pair) {
gwappa 9:e136394bdb39 159 // open/close the valve
gwappa 11:897ecd5413e0 160 rewardOut.start();
gwappa 9:e136394bdb39 161 }
gwappa 4:fcf597f82632 162
gwappa 5:849446d19406 163 stateTimeout.attach_us(&automaton::done<WithResp>, ms_to_us(task.post_dur_ms.value));
gwappa 4:fcf597f82632 164 }
gwappa 4:fcf597f82632 165
gwappa 4:fcf597f82632 166 void WithResp::teardown() {
gwappa 4:fcf597f82632 167 finalize();
gwappa 4:fcf597f82632 168 }
gwappa 4:fcf597f82632 169
gwappa 4:fcf597f82632 170 void NoResp::setup() {
gwappa 4:fcf597f82632 171 LOGSTATE(NoResp)
gwappa 14:af3adf5d5ddf 172 events::whiskhandler = 0;
gwappa 14:af3adf5d5ddf 173 events::lickhandler = 0;
gwappa 14:af3adf5d5ddf 174 events::gatehandler = 0;
gwappa 4:fcf597f82632 175
gwappa 11:897ecd5413e0 176 // no reward here no matter the mode
gwappa 7:6744ec9ccc25 177
gwappa 5:849446d19406 178 stateTimeout.attach_us(&automaton::done<NoResp>, ms_to_us(task.post_dur_ms.value));
gwappa 4:fcf597f82632 179 }
gwappa 4:fcf597f82632 180 void NoResp::teardown() {
gwappa 4:fcf597f82632 181 finalize();
gwappa 8:973dcd190672 182 }
gwappa 8:973dcd190672 183
gwappa 8:973dcd190672 184 void TestReward::setup() {
gwappa 8:973dcd190672 185 LOGSTATE(TestReward)
gwappa 8:973dcd190672 186
gwappa 8:973dcd190672 187 // open/close the valve
gwappa 11:897ecd5413e0 188 rewardOut.setDuration(ms_to_us(task.reward_ms.value));
gwappa 11:897ecd5413e0 189 rewardOut.start();
gwappa 8:973dcd190672 190 stateTimeout.attach_us(&automaton::done<TestReward>, ms_to_us(task.reward_ms.value+20));
gwappa 8:973dcd190672 191 }
gwappa 8:973dcd190672 192
gwappa 8:973dcd190672 193 void TestReward::teardown() {
gwappa 8:973dcd190672 194 // do nothing
gwappa 4:fcf597f82632 195 }