コード例 #1
0
void PMU::procDirectDebugInstruction(StringBuilder *input) {
  const char* str = (char *) input->position(0);
  char c    = *str;
  int temp_int = 0;

  if (input->count() > 1) {
    // If there is a second token, we proceed on good-faith that it's an int.
    temp_int = input->position_as_int(1);
  }
  else if (strlen(str) > 1) {
    // We allow a short-hand for the sake of short commands that involve a single int.
    temp_int = atoi(str + 1);
  }

  switch (c) {
    case 'f':
    case 'F':
      cpu_scale(*(str) == 'f' ? 0 : 1);
      break;

    case 'w':
      // Find the current wattage draw.
      break;

    case 'p':
    case 'P':
      // Start or stop the periodic sensor read.
      if (temp_int) {
        _periodic_pmu_read.alterSchedulePeriod(temp_int * 10);
        local_log.concatf("_periodic_pmu_read set to %d ms period.\n", (temp_int * 10));
      }
      _periodic_pmu_read.enableSchedule(*(str) == 'P');
      local_log.concatf("%s _periodic_pmu_read.\n", (*(str) == 'p' ? "Stopping" : "Starting"));
      break;

    case 'e':
      // Read the present battery voltage.
      break;

    case 'm':   // Set the system-wide power mode.
      if (255 != temp_int) {
        ManuvrMsg* event = Kernel::returnEvent(MANUVR_MSG_SYS_POWER_MODE);
        event->addArg((uint8_t) temp_int);
        EventReceiver::raiseEvent(event);
        local_log.concatf("Power mode is now %d.\n", temp_int);
      }
      else {
      }
      break;

    default:
      EventReceiver::procDirectDebugInstruction(input);
      break;
  }

  flushLocalLog();
}
コード例 #2
0
ファイル: StandardIO.cpp プロジェクト: jspark311/ManuvrOS
// TODO: Perhaps reset the terminal?
int8_t StandardIO::reset() {
  #if defined(MANUVR_DEBUG)
    if (getVerbosity() > 5) local_log.concatf("StandardIO initialized.\n");
  #endif
  initialized(true);
  listen();
  connect();

  flushLocalLog();
  return 0;
}
コード例 #3
0
int8_t HapticStrap::notify(ManuvrMsg* active_event) {
  int8_t return_value = 0;

  switch (active_event->eventCode()) {
    default:
      return_value += EventReceiver::notify(active_event);
      break;
  }

  flushLocalLog();
  return return_value;
}
コード例 #4
0
ファイル: StandardIO.cpp プロジェクト: jspark311/ManuvrOS
int8_t StandardIO::notify(ManuvrMsg* active_event) {
  int8_t return_value = 0;

  switch (active_event->eventCode()) {
    case MANUVR_MSG_XPORT_RECEIVE:
    case MANUVR_MSG_XPORT_QUEUE_RDY:
      read_port();
      return_value++;
      break;
    default:
      return_value += ManuvrXport::notify(active_event);
      break;
  }

  flushLocalLog();
  return return_value;
}
コード例 #5
0
void HapticStrap::procDirectDebugInstruction(StringBuilder *input) {
  char* str = input->position(0);

  switch (*(str)) {
    case '[':  // Buzz vibrator 0
      break;
    case ']':  // Buzz vibrator 1
      break;
    default:
      #ifdef __MANUVR_DEBUG
      EventReceiver::procDirectDebugInstruction(input);
      #endif
      break;
  }

  flushLocalLog();
}
コード例 #6
0
int8_t PMU::notify(ManuvrMsg* active_event) {
  int8_t return_value = 0;

  switch (active_event->eventCode()) {
    case DIGITABULUM_MSG_PMU_READ:
      if (_ina219->isDirty()) {
        _ina219->isDirty();
      }
      _ina219->readSensor();
      return_value++;
      break;
    default:
      return_value += EventReceiver::notify(active_event);
      break;
  }

  flushLocalLog();
  return return_value;
}
コード例 #7
0
ファイル: StandardIO.cpp プロジェクト: jspark311/ManuvrOS
/**
* Read input from local keyboard.
*/
int8_t StandardIO::read_port() {
  char *input_text	= (char*) alloca(getMTU());	// Buffer to hold user-input.
  int read_len = 0;

  if (connected()) {
    bzero(input_text, getMTU());

    if (nullptr == fgets(input_text, getMTU()-1, stdin)) {
      return 0;
    }
    read_len = strlen(input_text);

    // NOTE: This should suffice to be binary-safe.
    //read_len = fread(input_text, 1, getMTU(), stdin);

    if (read_len > 0) {
      bytes_received += read_len;
      BufferPipe::fromCounterparty((uint8_t*) input_text, read_len, MEM_MGMT_RESPONSIBLE_BEARER);
    }
  }
  flushLocalLog();
  return read_len;
}
コード例 #8
0
void LegendManager::procDirectDebugInstruction(StringBuilder *input) {
  char* str = input->position(0);

  uint8_t temp_byte = 0;
  if (*(str) != 0) {
    temp_byte = atoi((char*) str+1);
  }

  StringBuilder parse_mule;

  switch (*(str)) {
    case 'v':
      parse_mule.concat(str);
      local_log.concatf("parse_mule split (%s) into %d positions.\n", str, parse_mule.split(","));
      parse_mule.drop_position(0);
      if (temp_byte < 17) {
        if (parse_mule.count() > 0) {
          int temp_int = parse_mule.position_as_int(0);
          iius[temp_byte].setVerbosity(temp_int);
        }
        local_log.concatf("Verbosity on IIU %d is %d.\n", temp_byte, iius[temp_byte].getVerbosity());
      }
      break;

    case 'i':
      if (1 == temp_byte) {
        local_log.concatf("The IIU preallocated measurements are stored at %p.\n", (uintptr_t) __prealloc);
      }
      else if (2 == temp_byte) {
        if (operating_legend) {
          operating_legend->printDebug(&local_log);
        }
      }
      else {
        int8_t old_verbosity = getVerbosity();
        if (temp_byte && (temp_byte < 7)) setVerbosity(temp_byte);
        printDebug(&local_log);
        if (temp_byte && (temp_byte < 7)) setVerbosity(old_verbosity);
      }
      break;

    case '-':
      if (operating_legend) {
        operating_legend->copy_frame();
        local_log.concat("Frame copied.\n");
        operating_legend->printDataset(&local_log);
      }
      break;
    case '+':
      if (temp_byte < 17) {
        iius[temp_byte].dumpPointers(&local_log);
      }
      break;


    // IMU DEBUG //////////////////////////////////////////////////////////////////
    case 'c':
      if (temp_byte < 17) {
        iius[temp_byte].printDebug(&local_log);
      }
      break;

    // IMU STATE CONTROL //////////////////////////////////////////////////////////
    case 'g':
      if (255 == temp_byte) {
        local_log.concat("Syncing all IIUs...\n");
        for (uint8_t i = 0; i < 17; i++) {
          iius[i].sync();
        }
      }
      else if (temp_byte < 17) {
        iius[temp_byte].sync();
        local_log.concatf("Syncing IIU %d.\n", temp_byte);
      }
      break;

    case 's':
      parse_mule.concat(str);
      parse_mule.split(",");
      parse_mule.drop_position(0);
      if (parse_mule.count() > 0) {
        int temp_int = parse_mule.position_as_int(0);

        if (255 == temp_byte) {
          for (uint8_t i = 0; i < 17; i++) {
            iius[i].setOperatingState(temp_int);
          }
        }
        else if (temp_byte < 17) {
          local_log.concatf("Setting the state of IMU %d to %d\n", temp_byte, temp_int);
          iius[temp_byte].setOperatingState(temp_int);
        }

      }
      break;

    case 'k':
      if ((temp_byte < 6) && (temp_byte >= 0)) {
        ManuvrMsg *event = Kernel::returnEvent(DIGITABULUM_MSG_IMU_INIT);
        event->addArg((uint8_t) temp_byte);  // Set the desired init stage.
        event->priority(0);
        raiseEvent(event);
        local_log.concatf("Broadcasting IMU_INIT for stage %u...\n", temp_byte);
      }
      else {
        local_log.concatf("Illegal INIT stage: %u\n", temp_byte);
      }
      break;

    case 'r':
      if (255 == temp_byte) {
        local_log.concat("Reseting all IIUs...\n");
        for (uint8_t i = 0; i < 17; i++) {
          iius[i].reset();
        }
      }
      else if (temp_byte < 17) {
        local_log.concatf("Resetting IIU %d.\n", temp_byte);
        iius[temp_byte].reset();
      }
      break;


    case 'T':
    case 't':
      if (temp_byte < 17) {
        ManuvrMsg *event = Kernel::returnEvent((*(str) == 'T') ? DIGITABULUM_MSG_IMU_DOUBLE_TAP : DIGITABULUM_MSG_IMU_TAP);
        event->setOriginator((EventReceiver*) this);
        event->addArg((uint8_t) temp_byte);
        Kernel::staticRaiseEvent(event);
        local_log.concatf("Sent %stap event for IMU %d.\n", ((*(str) == 'T') ? "double ":""), temp_byte);
      }
      break;

    case 'q':
      if (temp_byte < 17) {
        ManuvrMsg *event = Kernel::returnEvent(DIGITABULUM_MSG_IMU_QUAT_CRUNCH);
        event->specific_target = (EventReceiver*) this;
        event->addArg((uint8_t) temp_byte);
        Kernel::staticRaiseEvent(event);
        local_log.concatf("Running quat on IIU %d.\n", temp_byte);
      }
      break;



    // IMU DATA ///////////////////////////////////////////////////////////////////
    case 'j':
      switch (*(str+1)) {
        case '0':
          reflection_acc.x = -1;
          reflection_acc.y = 1;
          reflection_acc.z = -1;
          reflection_gyr.set(-1, 1, -1);
          reflection_mag.x = 1;
          reflection_mag.y = 1;
          reflection_mag.z = -1;
          break;
        case 'm':
          if (*(str+2) == 'x')      reflection_mag.x *= -1;
          else if (*(str+2) == 'y') reflection_mag.y *= -1;
          else if (*(str+2) == 'z') reflection_mag.z *= -1;
          break;

        case 'a':
          if (*(str+2) == 'x')      reflection_acc.x *= -1;
          else if (*(str+2) == 'y') reflection_acc.y *= -1;
          else if (*(str+2) == 'z') reflection_acc.z *= -1;
          break;

        case 'g':
          if (*(str+2) == 'x')      reflection_gyr.x *= -1;
          else if (*(str+2) == 'y') reflection_gyr.y *= -1;
          else if (*(str+2) == 'z') reflection_gyr.z *= -1;
          break;
      }
      local_log.concatf("Reflection vectors\n\tMag (%d, %d, %d)\n\tAcc (%d, %d, %d)\n\tGyr (%d, %d, %d)\n", reflection_mag.x, reflection_mag.y, reflection_mag.z, reflection_acc.x, reflection_acc.y, reflection_acc.z, reflection_gyr.x, reflection_gyr.y, reflection_gyr.z);
      break;

    case '[':
    case ']':
      if (255 == temp_byte) {
        local_log.concatf("%sabling spherical abberation correction on all IIUs.\n", ((*(str) == ']') ? "En":"Dis"));
        for (uint8_t i = 0; i < 17; i++) {
          iius[i].correctSphericalAbberation((*(str) == ']'));
        }
      }
      else if (temp_byte < 17) {
        iius[temp_byte].correctSphericalAbberation((*(str) == ']'));
        local_log.concatf("%sabling spherical abberation correction on IIU %d.\n", ((*(str) == ']') ? "En":"Dis"), temp_byte);
      }
      break;

    case 'u':
    case 'U':
      if (255 == temp_byte) {
        local_log.concatf("%sabling (clean-mag-is-zero) on all IIUs.\n", ((*(str) == 'U') ? "En":"Dis"));
        for (uint8_t i = 0; i < 17; i++) {
          iius[i].cleanMagZero((*(str) == 'U'));
        }
      }
      else if (temp_byte < 17) {
        iius[temp_byte].cleanMagZero((*(str) == 'U'));
        local_log.concatf("%sabling (clean-mag-is-zero) on IIU %d.\n", ((*(str) == 'U') ? "En":"Dis"), temp_byte);
      }
      break;

    case 'w':
    case 'W':
      if (255 == temp_byte) {
        local_log.concatf("%sabling mag data scrutiny on all IIUs.\n", ((*(str) == 'Z') ? "En":"Dis"));
        for (uint8_t i = 0; i < 17; i++) {
          iius[i].dropObviousBadMag((*(str) == 'Z'));
        }
      }
      else if (temp_byte < 17) {
        iius[temp_byte].dropObviousBadMag((*(str) == 'Z'));
        local_log.concatf("%sabling mag data scrutiny on IIU %d.\n", ((*(str) == 'Z') ? "En":"Dis"), temp_byte);
      }
      break;

    case 'z':
    case 'Z':
      if (255 == temp_byte) {
        local_log.concatf("%sabling autoscale on all IIUs.\n", ((*(str) == 'Z') ? "En":"Dis"));
        for (uint8_t i = 0; i < 17; i++) {
          iius[i].enableAutoscale((*(str) == 'Z'));
        }
      }
      else if (temp_byte < 17) {
        iius[temp_byte].enableAutoscale((*(str) == 'Z'));
        local_log.concatf("%sabling autoscale on IIU %d.\n", ((*(str) == 'Z') ? "En":"Dis"), temp_byte);
      }
      break;

    case 'n':
    case 'N':
      if (255 == temp_byte) {
        local_log.concatf("%sabling range-binding on all IIUs.\n", ((*(str) == 'N') ? "En":"Dis"));
        for (uint8_t i = 0; i < 17; i++) {
          iius[i].rangeBind((*(str) == 'N'));
        }
      }
      else if (temp_byte < 17) {
        iius[temp_byte].rangeBind((*(str) == 'N'));
        local_log.concatf("%sabling range-binding on IIU %d.\n", ((*(str) == 'N') ? "En":"Dis"), temp_byte);
      }
      break;

    case 'h':
    case 'H':
      if (255 == temp_byte) {
        local_log.concatf("%sabling quats on all IIUs.\n", ((*(str) == 'H') ? "En":"Dis"));
        for (uint8_t i = 0; i < 17; i++) {
          iius[i].processQuats((*(str) == 'H'));
        }
      }
      else if (temp_byte < 17) {
        iius[temp_byte].processQuats((*(str) == 'H'));
        local_log.concatf("%sabling quats on IIU %d.\n", ((*(str) == 'H') ? "En":"Dis"), temp_byte);
      }
      break;

    case 'x':
    case 'X':
      if (255 == temp_byte) {
        local_log.concatf("%sabling gyro error compensation on all IIUs.\n", ((*(str) == 'X') ? "En":"Dis"));
        for (uint8_t i = 0; i < 17; i++) {
          iius[i].nullGyroError((*(str) == 'X'));
        }
      }
      else if (temp_byte < 17) {
        iius[temp_byte].nullGyroError((*(str) == 'X'));
        local_log.concatf("%sabling gyro error compensation on IIU %d.\n", ((*(str) == 'X') ? "En":"Dis"), temp_byte);
      }
      break;

    case 'm':
    case 'M':
      if (255 == temp_byte) {
        local_log.concatf("%sabling gravity nullification on all IIUs.\n", ((*(str) == 'M') ? "En":"Dis"));
        for (uint8_t i = 0; i < 17; i++) {
          iius[i].nullifyGravity((*(str) == 'M'));
        }
      }
      else if (temp_byte < 17) {
        iius[temp_byte].nullifyGravity((*(str) == 'M'));
        local_log.concatf("%sabling gravity nullification on IIU %d.\n", ((*(str) == 'M') ? "En":"Dis"), temp_byte);
      }
      break;

    case 'y':
    case 'Y':
      if (255 == temp_byte) {
        local_log.concatf("%sabling bearing nullification on all IIUs.\n", ((*(str) == 'Y') ? "En":"Dis"));
        for (uint8_t i = 0; i < 17; i++) {
          iius[i].nullifyBearing((*(str) == 'Y'));
        }
      }
      else if (temp_byte < 17) {
        iius[temp_byte].nullifyBearing((*(str) == 'Y'));
        local_log.concatf("%sabling bearing nullification on IIU %d.\n", ((*(str) == 'Y') ? "En":"Dis"), temp_byte);
      }
      break;

    case 'Q':
      local_log.concatf("Madgwick iterations to %d on all IIUs.\n", temp_byte);
      for (uint8_t i = 0; i < 17; i++) {
        iius[i].madgwickIterations(temp_byte);
      }
      break;



    case ',':
      IIU::max_quats_per_event = temp_byte;
      local_log.concatf("IIU class now runs a maximum of %u quats per event.\n", IIU::max_quats_per_event);
      break;

    case 'b':
      for (uint8_t i = 0; i < 17; i++) {
        iius[i].beta = (float)temp_byte * 0.1;
      }
      local_log.concatf("Beta value is now %f.\n", (double) (temp_byte * 0.1f));
      break;

    case 'L':
      for (uint8_t i = 0; i < 17; i++) {
        iius[i].setSampleRateProfile(temp_byte);
      }
      local_log.concatf("Moving to sample rate profile %d.\n", temp_byte);
      break;

    case 'o':
      for (uint8_t i = 0; i < 17; i++) {
        iius[i].setGyroBaseFiler(temp_byte);
      }
      local_log.concatf("Setting GYR base filter to %d.\n", temp_byte);
      break;

    case 'O':
      for (uint8_t i = 0; i < 17; i++) {
        iius[i].setAccelBaseFiler(temp_byte);
      }
      local_log.concatf("Setting ACC base filter to %d.\n", temp_byte);
      break;

    case 'a':
      if (255 == temp_byte) {
        refreshIMU();
      }
      else if (17 > temp_byte) {
        refreshIMU(temp_byte);
      }
      break;

    case 'd':
      switch (temp_byte) {
        case 255:
          event_legend_frame_ready.fireNow();  // Fire a single frame transmission.
          local_log.concat("We are manually firing the IMU frame broadcasts schedule.\n");
          break;
        case 254:
          event_legend_frame_ready.enableSchedule(true);  // Enable the periodic read.
          local_log.concat("Enabled frame broadcasts.\n");
          break;
        #if defined(__MANUVR_DEBUG)
          case 253:
            event_legend_frame_ready.printDebug(&local_log);
            break;
        #endif
        case 252:
          send_map_event();
          local_log.concat("We are manually firing the IMU frame broadcasts schedule.\n");
          break;
        default:
          if (temp_byte) {
            event_legend_frame_ready.alterSchedulePeriod(temp_byte*10);
            local_log.concatf("Set periodic frame broadcast to once every %dms.\n", temp_byte*10);
          }
          else {
            event_legend_frame_ready.enableSchedule(false);  // Disable the periodic read.
            local_log.concat("Disabled frame broadcasts.\n");
          }
          break;
      }
      break;

    case 'f':
      switch (temp_byte) {
        case 255:
          event_iiu_read.fireNow();
          local_log.concat("We are manually firing the IMU read schedule.\n");
          break;
        case 254:
          event_iiu_read.enableSchedule(true);
          local_log.concat("Enabled periodic readback.\n");
          break;
        default:
          if (temp_byte) {
            event_iiu_read.alterSchedulePeriod(temp_byte*10);
            local_log.concatf("Set periodic read schedule to once every %dms.\n", temp_byte*10);
          }
          else {
            event_iiu_read.enableSchedule(false);  // Disable the periodic read.
            local_log.concat("Disabled periodic readback.\n");
          }
          break;
      }
      break;

    case 'p':
      {
        parse_mule.concat(str);
        parse_mule.split(",");
        parse_mule.drop_position(0);
        uint8_t start = (temp_byte < 17) ? temp_byte   : 0;
        uint8_t stop  = (temp_byte < 17) ? temp_byte+1 : 17;
        int temp_int  = (parse_mule.count() > 0) ? parse_mule.position_as_int(0) : 255;
        for (uint8_t i = start; i < stop; i++) {
          if (255 != temp_int) {  // The user wants to make a change..
            iius[i].enableProfiling(temp_int ? true:false);
          }
          local_log.concatf("Profiling IIU %d: %sabled.\n", i, (iius[i].enableProfiling() ? "en":"dis"));
        }
      }
      break;

    case 'e':
      if (temp_byte < 17) {
        iius[temp_byte].dumpPreformedElements(&local_log);
      }
      break;


    default:
      EventReceiver::procDirectDebugInstruction(input);
      break;
  }

  flushLocalLog();
}
コード例 #9
0
int8_t LegendManager::notify(ManuvrMsg* active_event) {
  int8_t return_value = 0;
  uint8_t temp_uint_8 = 0;

  /* Some class-specific set of conditionals below this line. */
  switch (active_event->eventCode()) {
    case DIGITABULUM_MSG_IMU_READ:
      iius[last_imu_read].readSensor();
      return_value++;
      break;


    case MANUVR_MSG_SESS_ESTABLISHED:
      event_legend_frame_ready.delaySchedule(1100);     // Enable the periodic frame broadcast.
      {
        ManuvrMsg *event = Kernel::returnEvent(DIGITABULUM_MSG_IMU_INIT);
        event->addArg((uint8_t) 4);  // Set the desired init stage.
        event->priority(0);
        raiseEvent(event);
      }
      event_iiu_read.delaySchedule(1000);  // Enable the periodic read after letting the dust settle.
      return_value++;
      break;

    case MANUVR_MSG_SESS_HANGUP:
      event_legend_frame_ready.enableSchedule(false);
      for (uint8_t i = 0; i < LEGEND_DATASET_IIU_COUNT; i++) {
        ManuvrMsg *event = Kernel::returnEvent(DIGITABULUM_MSG_IMU_INIT);
        event->addArg((uint8_t) 4);  // Set the desired init stage.
        event->priority(0);
        raiseEvent(event);
      }
      event_iiu_read.enableSchedule(false);    // Disable the periodic read.
      return_value++;
      break;

    case DIGITABULUM_MSG_IMU_INIT:
      /* This is a request (probably from elsewhere in this class) to move one-or-more
           IMUs into the given INIT stage. The argument forms are...
           None        A request to move all IMUs into the minimum meaningful INIT stage (INIT-1).
           uint8       A request to move all IMUs into the given INIT stage.
       */
      if (0 == active_event->argCount()) {
        if (last_imu_read > 16) {
          if (getVerbosity() > 1) local_log.concat("MSG_IMU_INIT: last_imu_read > 16.\n");
        }
        else {
          iius[last_imu_read].init();
          return_value++;
        }
      }
      else if (0 == active_event->getArgAs(&temp_uint_8)) {
        // If the arg was present, we interpret this as a specified INIT stage...
        if (temp_uint_8 > 16) {
          if (getVerbosity() > 1) local_log.concat("MSG_IMU_INIT had an IMU idx > 16.\n");
        }
        else {
          iius[last_imu_read].state_pass_through(temp_uint_8);
          return_value++;
        }
      }
      break;

    case DIGITABULUM_MSG_IMU_MAP_STATE:
      //if (0 == active_event->argCount()) {
        // No args means a request. Send it.
      //  send_map_event();
      //  return_value++;
      //}
      break;


    case DIGITABULUM_MSG_CPLD_RESET_COMPLETE:
      if (getVerbosity() > 3) local_log.concatf("Initializing IMUs...\n");
      // Range-bind everything....
      for (uint8_t i = 0; i < 17; i++) iius[i].rangeBind(true);

      // Fire the event to put the IMUs into INIT-1.
      //raiseEvent(Kernel::returnEvent(DIGITABULUM_MSG_IMU_INIT));
      return_value++;
      break;

    case DIGITABULUM_MSG_IMU_TAP:
      if (0 == active_event->argCount()) {
        // Somthing wants the thresholds for all configured taps.
      }
      else {
        // Otherwise, it means we've emitted the event. No need to respond.
      }
      break;

    case DIGITABULUM_MSG_IMU_QUAT_CRUNCH:
      if (0 == active_event->getArgAs(&temp_uint_8)) {
        if (temp_uint_8 > 16) {
          if (getVerbosity() > 1) local_log.concat("QUAT_CRUNCH had an IMU idx > 16.\n");
        }
        else {
          iius[temp_uint_8].MadgwickQuaternionUpdate();
        }
        return_value++;
      }
      else {
        if (getVerbosity() > 2) local_log.concatf("QUAT_CRUNCH handler (IIU %u) got a bad return from an Arg..\n", temp_uint_8);
      }
      break;

    default:
      return_value += EventReceiver::notify(active_event);
      break;
  }

  flushLocalLog();
  return return_value;
}
コード例 #10
0
/**
* If we find ourselves in this fxn, it means an event that this class built (the argument)
*   has been serviced and we are now getting the chance to see the results. The argument
*   to this fxn will never be NULL.
*
* Depending on class implementations, we might choose to handle the completed Event differently. We
*   might add values to event's Argument chain and return RECYCLE. We may also free() the event
*   ourselves and return DROP. By default, we will return REAP to instruct the Kernel
*   to either free() the event or return it to it's preallocate queue, as appropriate. If the event
*   was crafted to not be in the heap in its own allocation, we will return DROP instead.
*
* @param  event  The event for which service has been completed.
* @return A callback return code.
*/
int8_t LegendManager::callback_proc(ManuvrMsg* event) {
  /* Setup the default return code. If the event was marked as mem_managed, we return a DROP code.
     Otherwise, we will return a REAP code. Downstream of this assignment, we might choose differently. */
  int8_t return_value = (0 == event->refCount()) ? EVENT_CALLBACK_RETURN_REAP : EVENT_CALLBACK_RETURN_DROP;

  /* Some class-specific set of conditionals below this line. */
  switch (event->eventCode()) {
    case DIGITABULUM_MSG_IMU_READ:
      switch (last_imu_read) {
        case 0:
        case 1:
        case 2:
        case 3:
        case 4:
        case 5:
        case 6:
        case 7:
        case 8:
        case 9:
        case 10:
        case 11:
        case 12:
        case 13:
        case 14:
        case 15:
          last_imu_read++;
          return EVENT_CALLBACK_RETURN_RECYCLE;

        case 16:
          last_imu_read = 0;
          break;

        default:
          if (getVerbosity() > 2) local_log.concat("LegendManager::callback_proc(IMU_READ): Bad arg\n");
          last_imu_read = 0;
          break;
      }
      break;


    case DIGITABULUM_MSG_IMU_INIT:
      switch (last_imu_read) {
        case 0:
        case 1:
        case 2:
        case 3:
        case 4:
        case 5:
        case 6:
        case 7:
        case 8:
        case 9:
        case 10:
        case 11:
        case 12:
        case 13:
        case 14:
        case 15:
          last_imu_read++;
          if (getVerbosity() > 6) local_log.concat("LegendManager::callback_proc(IMU_INIT): RECYCLING\n");
          // We still have IMUs left to deal with. Recycle the event...
          return EVENT_CALLBACK_RETURN_RECYCLE;
        case 16:
          last_imu_read = 0;
          if (getVerbosity() > 6) local_log.concat("LegendManager::callback_proc(IMU_INIT): DROPPING\n");
          break;

        default:
          if (getVerbosity() > 2) local_log.concat("LegendManager::callback_proc(IMU_READ): Bad arg\n");
          last_imu_read = 0;
          break;
      }
      break;

    case DIGITABULUM_MSG_IMU_LEGEND:
      // We take this as an indication that our notice of altered Legend was sent.
      _er_set_flag(LEGEND_MGR_FLAGS_LEGEND_SENT);
      break;

    case DIGITABULUM_MSG_IMU_MAP_STATE:
      *(_ptr_sequence) = *(_ptr_sequence) + 1;
      if (operating_legend && _er_flag(LEGEND_MGR_FLAGS_LEGEND_SENT)) {
        operating_legend->copy_frame();
        Kernel::staticRaiseEvent(&event_legend_frame_ready);
        return 0;
      }
      break;

    case DIGITABULUM_MSG_IMU_QUAT_CRUNCH:
      {
        uint8_t temp_uint_8;
        if (0 == event->getArgAs(&temp_uint_8)) {
          if (iius[temp_uint_8 % 17].has_quats_left()) {
            return_value = EVENT_CALLBACK_RETURN_RECYCLE;
          }
        }
        else {
          local_log.concat("LegendManager::callback_proc(): QUAT crunch had no argument?!.\n");
        }
      }
      break;

    default:
      if (getVerbosity() > 5) {
        local_log.concat("LegendManager::callback_proc(): Default case.\n");
        #if defined(__MANUVR_DEBUG)
          event->printDebug(&local_log);
        #endif
        Kernel::log(&local_log);
      }
      break;
  }

  flushLocalLog();
  return return_value;
}