Keisuke Sehara
/
STM32_Whisking
fast-feedback virtual target task code on STM Nucleo
states.cpp
- Committer:
- gwappa
- Date:
- 2018-07-02
- Revision:
- 21:e51733fc1c36
- Parent:
- 20:4c06d3041337
- Child:
- 22:41163fb3fdc6
File content as of revision 21:e51733fc1c36:
#include "states.h" #include "rig.h" #include "automaton.h" #include "events.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(); } void Delay::setup() { LOGSTATE(Delay) // initialize the trial-related params trial.reset(task); events::setup(true); // set up the timeout for the next state switch (task.mode.value) { case Pair: case MotionAlt: stateTimeout.attach_us(&automaton::jump<Delay,Cued>, ms_to_us(trial.delay_dur_ms + task.prep_dur_ms.value)); break; default: stateTimeout.attach_us(&automaton::jump<Delay,Prepare>, ms_to_us(trial.delay_dur_ms)); } trial.markTrialStart(); } void Delay::teardown() { // 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 events::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 events::lickhandler = 0; } void Cued::setup() { LOGSTATE(Cued) trial.markEndOfWait(); switch (task.mode.value) { case Pair: case Report: case Associate: // wait for the visual cue to flag "cued" break; case Motion: case MotionAlt: trial.flag.cued = true; break; } // configure lick handler if (task.mode.value != MotionAlt) { // licking without a visual "go-cue" will be considered a "catch" response events::lickhandler = &automaton::jump<Cued,WithResp>; } else { // for MotionAlt } // configure whisk handler // matters only for Motion & MotionAlt conditions switch (task.mode.value) { case Motion: events::whiskhandler = &events::gate; break; case MotionAlt: events::whiskhandler = &automaton::jump<Cued,WithResp>; break; default: // do nothing break; } // configure gate handler // "gating" comes from the visual cue for Report & Associate // from the whisking for Motion if (task.mode.value != MotionAlt) { events::gatehandler = &Cued::gate; } // configure visual stimulus callback // only for Pair/Report/Associate switch (task.mode.value) { case Pair: case Report: case Associate: visualOut.attachTurnOnCallback(&events::gate); break; case Motion: case MotionAlt: // do nothing break; } // start cue output visualOut.run(); audioOut.run(); // sets the timeout for the next state stateTimeout.attach_us(&automaton::jump<Cued,NoResp>, ms_to_us(task.aud_dur_ms.value)); } void Cued::gate() { events::gatehandler = 0; events::whiskhandler = 0; trial.flag.cued = true; events::lickhandler = &automaton::jump<Cued,WithResp>; } void Cued::teardown() { events::whiskhandler = 0; events::lickhandler = 0; events::gatehandler = 0; // 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) events::whiskhandler = 0; events::lickhandler = 0; events::gatehandler = 0; trial.markEndOfWait(); trial.flag.reset = true; stateTimeout.attach_us(&automaton::done<Abort>, ms_to_us(task.post_dur_ms.value)); } void Abort::teardown() { finalize(); } void WithResp::setup() { LOGSTATE(WithResp) trial.flag.responded = true; events::whiskhandler = 0; events::lickhandler = 0; events::gatehandler = 0; if ((task.mode.value == Pair) || trial.flag.cued ) { // open/close the valve, only when the cue was there rewardOut.start(); } stateTimeout.attach_us(&automaton::done<WithResp>, ms_to_us(task.post_dur_ms.value)); } void WithResp::teardown() { finalize(); } void NoResp::setup() { LOGSTATE(NoResp) events::whiskhandler = 0; events::lickhandler = 0; events::gatehandler = 0; // no reward here no matter the mode stateTimeout.attach_us(&automaton::done<NoResp>, ms_to_us(task.post_dur_ms.value)); } 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(); stateTimeout.attach_us(&automaton::done<TestReward>, ms_to_us(task.reward_dur_ms.value+100)); } void TestReward::teardown() { // do nothing }