Keisuke Sehara
/
STM32_Whisking
fast-feedback virtual target task code on STM Nucleo
main.cpp
- Committer:
- gwappa
- Date:
- 2018-05-14
- Revision:
- 0:f736749c33d2
- Child:
- 1:871d3066c2ab
File content as of revision 0:f736749c33d2:
#include "mbed.h" #include "IO.h" #include "random.h" /* * command characters */ #define CMD_MODE_PAIR 'P' #define CMD_MODE_APPEAR 'A' #define CMD_TEST_REWARD 'T' #define CMD_EXECUTE 'x' #define CHR_DELAY_MIN 'm' #define CHR_DELAY_VAR 'v' #define CHR_PREP_DUR 'p' #define CHR_CUE_DUR 'c' #define CHR_POST_DUR 'n' #define CHR_REWARD_DUR 'r' #define STR_DELIMITER ";" #define STR_NEWLINE "\r\n" Timeout interval; DigitalOut cue(LED1); InterruptIn whisking(USER_BUTTON); enum Mode { Pair, Appear }; /** * the trial mode. */ Mode mode = Pair; /** * the minimum duration for the delay. */ uint16_t delay_min_ms = 3500; /** * the average for the (exponential) variable duration of the delay. */ uint16_t delay_var_ms = 3000; /** * the duration of the "preparatory period", during which licking is not allowed. */ uint16_t prep_dur_ms = 1500; /** * the cue duration. */ uint16_t cue_dur_ms = 3000; /** * the post-reward recording duration. */ uint16_t post_dur_ms = 4000; /** * the duration of reward, in microseconds */ unsigned long reward_us = 40000; void writeModeToSerial(bool newline=true){ IO::write(IO::CONFIG_HEADER); #define WRITE(CHR, VAL) if (mode == (VAL)) { IO::write("[%c]",CHR); } else { IO::write("%c",CHR); } WRITE(CMD_MODE_PAIR, Pair) WRITE(CMD_MODE_APPEAR, Appear) #undef WRITE if (newline) { IO::write(STR_NEWLINE); } } void writeSettingsToSerial() { writeModeToSerial(false); IO::write(STR_DELIMITER); #define WRITE(CHR, PARAM, END) IO::write("%c%u",CHR,PARAM); if (END) { IO::write(STR_NEWLINE); } else { IO::write(STR_DELIMITER); } WRITE(CHR_DELAY_MIN, delay_min_ms, false) WRITE(CHR_DELAY_VAR, delay_var_ms, false) WRITE(CHR_PREP_DUR, prep_dur_ms, false) WRITE(CHR_CUE_DUR, cue_dur_ms, false) WRITE(CHR_POST_DUR, post_dur_ms, false) WRITE(CHR_REWARD_DUR, reward_us/1000, true) #undef WRITE } inline bool isWhitespace(const char& ch) { return (ch == ' ') || (ch == '\t') || (ch == '\r') || (ch == '\n') || (ch == '\v') || (ch == '\f'); } uint16_t parseUnsignedFromSerial(const uint16_t& orig) { uint16_t value = 0; while(true) { int readChar = IO::getc(); // only accepts digits if ((readChar >= 48) && (readChar <= 57)) { value = value * 10 + (readChar - 48); // continues parsing } else if ( isWhitespace((char)readChar) || (readChar == 59) ) { // space or ';' // ends parsing break; } else { IO::error("%c",(char)readChar); // set value back to original value = orig; break; } } return value; } void parse(const char& in) { if (isWhitespace(in)) { return; } switch(in) { case CMD_TEST_REWARD: // Cued::turnOnReward(); // while(Cued::phase != Cued::Done); // LOG_REWARDED IO::result("done"); break; case CMD_EXECUTE: // TRIAL_STARTING // automaton::run(); IO::result("done"); break; case '?': writeSettingsToSerial(); break; case CMD_MODE_PAIR: mode = Pair; writeModeToSerial(); break; case CMD_MODE_APPEAR: mode = Appear; writeModeToSerial(); break; #define PARSE(CHR, TYPE, PARAM, FACTOR) case (CHR): PARAM = ((TYPE)(parseUnsignedFromSerial((uint16_t)((PARAM)/(FACTOR)))))*(FACTOR);\ IO::config("%c%u",(CHR),((PARAM)/(FACTOR))); break; PARSE(CHR_DELAY_MIN, uint16_t, delay_min_ms, 1) PARSE(CHR_DELAY_VAR, uint16_t, delay_var_ms, 1) PARSE(CHR_PREP_DUR, uint16_t, prep_dur_ms, 1) PARSE(CHR_CUE_DUR, uint16_t, cue_dur_ms, 1) PARSE(CHR_POST_DUR, uint16_t, post_dur_ms, 1) PARSE(CHR_REWARD_DUR, unsigned long, reward_us, 1000) #undef PARSE default: IO::error("%c",in); break; } } int main() { // random::init(); // automaton::init<Delay>(); while(1){ // wait for the host to access parse(IO::getc()); } }