fast-feedback virtual target task code on STM Nucleo

Dependencies:   mbed

Committer:
gwappa
Date:
Tue May 29 14:40:50 2018 +0000
Revision:
7:6744ec9ccc25
Parent:
5:849446d19406
Child:
8:973dcd190672
add Report and Appear modes

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