Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
states.cpp
- Committer:
- gwappa
- Date:
- 2018-07-03
- Revision:
- 24:e236faf66935
- Parent:
- 22:41163fb3fdc6
- Child:
- 25:56c4b22ec034
File content as of revision 24:e236faf66935:
#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, task.lick_debounce_ms.value);
// 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>, trial.cued_dur_us);
}
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;
// open/close the valve, only when the cue was there
// (for Pair, reward will be there no matter the response)
if ((task.mode.value == Pair) || trial.flag.cued ) {
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, except for Pair
if (task.mode.value == Pair) {
rewardOut.start();
}
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
}