Keisuke Sehara
/
STM32_Whisking
fast-feedback virtual target task code on STM Nucleo
Diff: states.cpp
- Revision:
- 7:6744ec9ccc25
- Parent:
- 5:849446d19406
- Child:
- 8:973dcd190672
--- a/states.cpp Thu May 24 15:34:58 2018 +0000 +++ b/states.cpp Tue May 29 14:40:50 2018 +0000 @@ -40,6 +40,7 @@ void finalize() { taskOut.write(0); + cueOut.write(0); // if any trial.writeToSerial(); timer.stop(); timer.reset(); @@ -54,7 +55,11 @@ // configure the flags taskOut.write(1); cueOut.write(0); - enableOut.write(1); // for Pair + if ( (task.mode.value == Pair) || (task.mode.value == Report) ) { + enableOut.write(1); + } else { + enableOut.write(0); + } rewardOut.write(0); // configure the interrupts @@ -65,7 +70,11 @@ logged = true; // sets the timeout for the next state - stateTimeout.attach_us(&automaton::jump<Delay,Cued>, ms_to_us(trial.delay_dur_ms)); // for Pair + if (task.mode.value == Pair) { + stateTimeout.attach_us(&automaton::jump<Delay,Cued>, ms_to_us(trial.delay_dur_ms)); + } else { + stateTimeout.attach_us(&automaton::jump<Delay,Prepare>, ms_to_us(trial.delay_dur_ms)); + } // update the timestamp trial.starting = timer.read_ms(); @@ -76,25 +85,78 @@ // do nothing } +void Prepare::setup() { + // mostly the same with for Delay + // except that the animal cannot lick freely + LOGSTATE(Prepare) + + // configure the interrupts + // no whisk handler (i.e. only to be logged) + lickhandler = &automaton::jump<Prepare,Abort>; + + // set timeout for the next state + stateTimeout.attach_us(&automaton::jump<Prepare,Cued>, ms_to_us(task.prep_dur_ms.value)); +} + +void Prepare::teardown() { + // de-register lick inhibition + lickhandler = 0; +} + void Cued::setup() { LOGSTATE(Cued) + if (task.mode.value == Report) { + enableOut.write(1); // enable the feedback only during Cued + } + // configure the interrupts - whiskhandler = &automaton::jump<Cued,WithResp>; - // no lick handler - // remains to be logged + if (task.mode.value == Pair) { + whiskhandler = &automaton::jump<Cued,WithResp>; + lickhandler = 0; + + } else { + whiskhandler = &Cued::gate; + lickhandler = &automaton::jump<Cued,Abort>; + } + + // start cue output + cueOut.write(1); // sets the timeout for the next state - stateTimeout.attach_us(&automaton::jump<Cued,NoResp>, ms_to_us(task.cue_dur_ms.value)); // for Pair + stateTimeout.attach_us(&automaton::jump<Cued,NoResp>, ms_to_us(task.cue_dur_ms.value)); // update the timestamp trial.cuestarting = timer.read_ms(); trial.waiting = trial.cuestarting - trial.starting; } +void Cued::gate() { + whiskhandler = 0; // logging only + lickhandler = &automaton::jump<Cued,WithResp>; +} + void Cued::teardown() { whiskhandler = 0; + lickhandler = 0; + // end cue output + cueOut.write(0); + stateTimeout.detach(); + + if (task.mode.value == Report) { + enableOut.write(0); + } +} + +void Abort::setup() { + LOGSTATE(Abort) + trial.response |= TrialFlags::Licked; + automaton::done<Abort>(); +} + +void Abort::teardown() { + finalize(); } void WithResp::setup() { @@ -102,11 +164,20 @@ trial.response |= TrialFlags::Responded; - // TODO: open/close the valve + whiskhandler = 0; + lickhandler = 0; + + // open/close the valve + rewardOut.write(1); + rewardTimeout.attach_us(&WithResp::stopReward, ms_to_us(task.reward_ms.value)); stateTimeout.attach_us(&automaton::done<WithResp>, ms_to_us(task.post_dur_ms.value)); } +void WithResp::stopReward() { + rewardOut.write(0); +} + void WithResp::teardown() { finalize(); } @@ -116,6 +187,8 @@ trial.response &= ~TrialFlags::Responded; + // no reward here + stateTimeout.attach_us(&automaton::done<NoResp>, ms_to_us(task.post_dur_ms.value)); } void NoResp::teardown() {