fast-feedback virtual target task code on STM Nucleo

Dependencies:   mbed

Revision:
12:06ea96546af1
Parent:
11:897ecd5413e0
Child:
13:8ea85a33e37a
--- a/states.cpp	Thu Jun 21 17:57:22 2018 +0000
+++ b/states.cpp	Mon Jun 25 12:10:31 2018 +0000
@@ -1,6 +1,7 @@
 #include "states.h"
 #include "rig.h"
 #include "automaton.h"
+#include "events.h"
 #include "IO.h"
 
 #define STATE_IS_LOGGED
@@ -11,53 +12,10 @@
 #define LOGSTATE(S)
 #endif
 
-void (*whiskhandler)() = 0;
-void (*lickhandler)() = 0;
-void (*gatehandler)() = 0;
-bool logged = false;
-
-void whiskcallback() {
-    if (logged) {
-        trial.whisking_events.add(timer.read_ms());
-    }
-    if (whiskhandler != 0) {
-        whiskhandler();
-    }
-}
-
-void lickcallback() {
-    if (logged) {
-        trial.licking_events.add(timer.read_ms());
-    }
-    if (lickhandler != 0) {
-        lickhandler();
-    }
-}
-
-void gateReward() {
-    if (gatehandler != 0) {
-        gatehandler();
-    }
-}
-
 void tickBuzzer() {
     audioOut = !audioOut;
 }
 
-void setupInterrupts() {
-    // configure the interrupts
-    whiskIn.rise(&whiskcallback);
-    lickIn.rise(&lickcallback);
-    
-    whiskhandler = 0;
-    lickhandler  = 0;
-    gatehandler  = 0;
-    
-    // no whisk handler, no lick handler
-    // only to be logged
-    logged = true;
-}
-
 void finalize() {
     audioOut.write(0); // if any
     trial.markTrialEnd();
@@ -68,10 +26,14 @@
     
     // initialize the trial-related params
     trial.reset(task);
-    visualOut.reset(task, (task.mode.value==Associate)||(task.mode.value==Motion));
+    // TODO: reset visualOut with the nice parameters
+    // visualOut.reset(task, (task.mode.value==Associate)||(task.mode.value==Motion));
+    if ((task.mode.value == Report) || (task.mode.value == Associate)) {
+        visualOut.attachTurnOnCallback(&events::gate);
+    }
     audioOut.write(0);
     rewardOut.setDuration(ms_to_us(task.reward_ms.value));
-    setupInterrupts();
+    events::setup(true);
     
     // set up the timeout for the next state
     switch (task.mode.value) {
@@ -82,8 +44,6 @@
         stateTimeout.attach_us(&automaton::jump<Delay,Prepare>, ms_to_us(trial.delay_dur_ms));
     }
     
-    // TODO: start visual stim sequence for Associate mode
-    
     trial.markTrialStart();
 }
 
@@ -95,8 +55,8 @@
     LOGSTATE(Paired)
     trial.markEndOfWait();
     
-    trial.response |= TrialFlags::Cues;
-    lickhandler     = &automaton::jump<Paired,WithResp>;
+    trial.response      |= TrialFlags::Cues;
+    events::lickhandler  = &automaton::jump<Paired,WithResp>;
     
     // reward & visual feedback
     visualOut.direct(true);
@@ -107,7 +67,7 @@
 
 void Paired::teardown() {
     visualOut.direct(false);
-    lickhandler = 0;
+    events::lickhandler = 0;
 }
 
 void Prepare::setup() {
@@ -116,22 +76,16 @@
     LOGSTATE(Prepare)
     
     // configure the interrupts
-    // no whisk handler (i.e. only to be logged)
-    lickhandler = &automaton::jump<Prepare,Abort>;
+    // 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));
-    if (task.mode.value != Motion) {
-        visualOut.startPrepare();
-    }
 }
 
 void Prepare::teardown() {
     // de-register lick inhibition
-    lickhandler = 0;
-    if (task.mode.value != Motion) {
-        visualOut.endState();
-    }
+    events::lickhandler = 0;
 }
 
 void Cued::setup() {
@@ -140,25 +94,18 @@
     trial.markEndOfWait();
     
     // configure the interrupts
-    lickhandler     = &automaton::jump<Cued,Abort>;
+    events::lickhandler = &automaton::jump<Cued,Abort>;
     
     // "cue" comes from either internal visual stimulus generation (Report, Associate)
     // or the animal's whisker motion (Motion)
     if (task.mode.value == Motion) {
-        whiskhandler = &Cued::gate;
+        events::whiskhandler = &Cued::gate;
     } else {
-        gatehandler  = &Cued::gate;
+        events::gatehandler  = &Cued::gate;
     }
     
     // start cue output
-    switch (task.mode.value) {
-    case Report:
-        visualOut.startCue(&gateReward);
-        break;
-    case Associate:
-        visualOut.startCue(&gateReward);
-        // fallthrough
-    case Motion:
+    if (task.mode.value == Motion) {
         audioOut.write(1);
         buzzerTicker.attach_us(&tickBuzzer, trial.aud_ticker_cycle);
     }
@@ -168,21 +115,21 @@
 }
 
 void Cued::gate() {
-    gatehandler  = 0;
-    whiskhandler = 0;
-    trial.response |= TrialFlags::Cues;
-    lickhandler  = &automaton::jump<Cued,WithResp>;
+    events::gatehandler  = 0;
+    events::whiskhandler = 0;
+    trial.response      |= TrialFlags::Cues;
+    events::lickhandler  = &automaton::jump<Cued,WithResp>;
 }
 
 void Cued::teardown() {
-    whiskhandler = 0;
-    lickhandler  = 0;
-    gatehandler  = 0;
+    events::whiskhandler = 0;
+    events::lickhandler  = 0;
+    events::gatehandler  = 0;
     // end cue output
     buzzerTicker.detach();
     audioOut.write(0);
     if (task.mode.value != Motion) {
-        visualOut.endState();
+        visualOut.stop();
     }
 }
 
@@ -208,15 +155,9 @@
     }
     
     stateTimeout.attach_us(&automaton::done<WithResp>, ms_to_us(task.post_dur_ms.value));
-    if (task.mode.value != Motion) {
-        visualOut.startPrepare();
-    }
 }
 
 void WithResp::teardown() {
-    if (task.mode.value != Motion) {
-        visualOut.endState();
-    }
     finalize();
 }
 
@@ -226,14 +167,8 @@
     // no reward here no matter the mode
     
     stateTimeout.attach_us(&automaton::done<NoResp>, ms_to_us(task.post_dur_ms.value));
-    if (task.mode.value != Motion) {
-        visualOut.startPrepare();
-    }
 }
 void NoResp::teardown() {
-    if (task.mode.value != Motion) {
-        visualOut.endState();
-    }
     finalize();
 }