fast-feedback virtual target task code on STM Nucleo

Dependencies:   mbed

Committer:
gwappa
Date:
Mon Jun 25 13:20:00 2018 +0000
Revision:
13:8ea85a33e37a
Parent:
12:06ea96546af1
Child:
14:af3adf5d5ddf
add random pulse feature

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