Keisuke Sehara
/
STM32_Whisking
fast-feedback virtual target task code on STM Nucleo
states.cpp
- Committer:
- gwappa
- Date:
- 2018-10-01
- Revision:
- 29:1fb060aab1f8
- Parent:
- 28:797536a42b9f
- Child:
- 30:5f975f572ffb
File content as of revision 29:1fb060aab1f8:
#include "states.h" #include "rig.h" #include "automaton.h" #include "scheduler.h" #include "IO.h" #define STATE_IS_LOGGED #ifdef STATE_IS_LOGGED #define LOGSTATE(S) IO::info(#S); #else #define LOGSTATE(S) #endif void finalize() { trial.markTrialEnd(task); scheduler::reset(); } void Delay::setup() { LOGSTATE(Delay) // initialize the trial-related params trial.reset(task); // set up the timeout for the next state switch (task.mode.value) { case Condition: scheduler::set(ms_to_us(trial.delay_dur_ms + task.prep_dur_ms.value), &automaton::jump<Delay,Paired>); break; case MotionAlt: scheduler::set(ms_to_us(trial.delay_dur_ms + task.prep_dur_ms.value), &automaton::jump<Delay,Cued>); break; default: scheduler::set(ms_to_us(trial.delay_dur_ms), &automaton::jump<Delay,Prepare>); } trial.markTrialStart(); } void Delay::teardown() { // do nothing } void Paired::setup() { LOGSTATE(Paired) visualOut.run(); trial.flag.cued = true; visualOut.attachTurnOffCallback(&automaton::jump<Paired,Monitor>); } void Paired::teardown() { visualOut.detachTurnOffCallback(); trial.markEndOfWait(); } void Monitor::setup() { LOGSTATE(Monitor) rewardOut.run(); lickIn.attach(&automaton::jump<Monitor,WithResp>); scheduler::set(ms_to_us(task.resp_dur_ms.value), &automaton::jump<Monitor,NoResp>); } void Monitor::teardown() { lickIn.detach(); rewardOut.wait(); } void Prepare::setup() { // mostly the same with for Delay // except that the animal cannot lick freely LOGSTATE(Prepare) // configure the interrupts lickIn.attach(&automaton::jump<Prepare,Abort>); // set timeout for the next state scheduler::set(ms_to_us(task.prep_dur_ms.value), &automaton::jump<Prepare,Cued>); } void Prepare::teardown() { // de-register lick inhibition lickIn.detach(); } void Cued::setup() { LOGSTATE(Cued) trial.markEndOfWait(); switch (task.mode.value) { case Report: case Associate: case Motion: // wait for the visual cue to flag "cued" // use visual feedback trigger as the "gate" response // licking without a visual "go-cue" will be considered a "catch" response gateIn.attach(&Cued::gate); lickIn.attach(&automaton::jump<Cued,WithResp>); break; case MotionAlt: // jumps directly to WithResp with the visual cue Cued::gate(); gateIn.attach(&automaton::jump<Cued,WithResp>); break; } // start cue output visualOut.run(); audioOut.run(); // sets the timeout for the next state scheduler::set(ms_to_us(task.aud_dur_ms.value), &automaton::jump<Cued,NoResp>); } void Cued::gate() { gateIn.detach(); lickIn.attach(&automaton::jump<Cued,WithResp>); trial.flag.cued = true; // in case it has not been (i.e. other than MotionAlt) } void Cued::teardown() { lickIn.detach(); gateIn.detach(); // end cue output switch (task.mode.value) { case Report: case Associate: visualOut.stop(); } switch (task.mode.value) { case Associate: case Motion: case MotionAlt: audioOut.stop(); } } void Abort::setup() { LOGSTATE(Abort) lickIn.detach(); // if any gateIn.detach(); // if any trial.markEndOfWait(); trial.flag.reset = true; scheduler::set(ms_to_us(task.post_dur_ms.value), &automaton::done<Abort>); } void Abort::teardown() { finalize(); } void WithResp::setup() { LOGSTATE(WithResp) trial.flag.responded = true; lickIn.detach(); // if any gateIn.detach(); // if any if ( trial.flag.cued && (task.mode.value != Condition) ) { // reward will be there only when the cue was there rewardOut.start(); } scheduler::set(ms_to_us(task.post_dur_ms.value), &automaton::done<WithResp>); } void WithResp::teardown() { finalize(); } void NoResp::setup() { LOGSTATE(NoResp) lickIn.detach(); // if any gateIn.detach(); // if any scheduler::set(ms_to_us(task.post_dur_ms.value), &automaton::done<NoResp>); } void NoResp::teardown() { finalize(); } void TestReward::setup() { LOGSTATE(TestReward) // open/close the valve rewardOut.setOnset(0); rewardOut.setDuration(ms_to_us(task.reward_dur_ms.value)); rewardOut.start(); scheduler::set(ms_to_us(task.reward_dur_ms.value+100), &automaton::done<TestReward>); } void TestReward::teardown() { // do nothing }