/* * Updates the local state if warranted, but always returns local state. */ ChargeState PMU::getChargeState() { uint8_t idx = 0; bool s1 = readPin(_stat1_pin); bool s2 = readPin(_stat2_pin); _er_set_flag(DIGITAB_PMU_FLAG_STAT1, s1); _er_set_flag(DIGITAB_PMU_FLAG_STAT2, s2); idx += s1 ? 1 : 0; idx += s2 ? 2 : 0; switch (idx) { case 0: _charge_state = ChargeState::TEST; break; case 1: _charge_state = ChargeState::FULL; break; case 2: _charge_state = ChargeState::CHARGING; break; case 3: // Both pins high. No inference possible. default: break; } return _charge_state; }
void PMU::gpioSetup() { /* These Port B pins are inputs: * * # Default Purpose * ----------------------------------------------- * 0 0 CHG_STAT_1 * 1 0 CHG_STAT_2 */ // This will cause interrupts to be enabled for these pins. setPinFxn(_stat1_pin, CHANGE_PULL_UP, mcp73833_stat1_isr); setPinFxn(_stat2_pin, CHANGE_PULL_UP, mcp73833_stat2_isr); _er_set_flag(DIGITAB_PMU_FLAG_STAT1, readPin(_stat1_pin)); _er_set_flag(DIGITAB_PMU_FLAG_STAT2, readPin(_stat2_pin)); }
/** * 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; }
/******************************************************************************* * ___ _ ___ _ _ _ _ * / __| |__ _ ______ | _ ) ___(_) |___ _ _ _ __| |__ _| |_ ___ * | (__| / _` (_-<_-< | _ \/ _ \ | / -_) '_| '_ \ / _` | _/ -_) * \___|_\__,_/__/__/ |___/\___/_|_\___|_| | .__/_\__,_|\__\___| * |_| * Constructors/destructors, class initialization functions and so-forth... *******************************************************************************/ LegendManager::LegendManager(BusAdapter<SPIBusOp>* bus) : EventReceiver() { _bus = (CPLDDriver*) bus; // TODO: Make this cast unnecessary. setReceiverName("ManuMgmt"); INSTANCE = this; reflection_mag.x = 1; reflection_mag.y = 1; reflection_mag.z = -1; reflection_acc.x = -1; reflection_acc.y = 1; reflection_acc.z = -1; reflection_gyr.x = -1; reflection_gyr.y = 1; reflection_gyr.z = -1; _preformed_read_a.shouldReap(false); _preformed_read_a.devRegisterAdvance(true); _preformed_read_a.set_opcode(BusOpcode::RX); _preformed_read_a.callback = (BusOpCallback*) this; // Starting from the first accelerometer... // Read 6 bytes... // ...across 17 sensors... // ...from this base address... _preformed_read_a.setParams(CPLD_REG_IMU_DM_P_I|0x80, 6, 17, LSM9DS1_A_DATA_X); // ...and drop the results here. _preformed_read_a.buf = (uint8_t*) __frame_buf_a; _preformed_read_a.buf_len = 102; _preformed_read_g.shouldReap(false); _preformed_read_g.devRegisterAdvance(true); _preformed_read_g.set_opcode(BusOpcode::RX); _preformed_read_g.callback = (BusOpCallback*) this; // Starting from the first gyro... // Read 6 bytes... // ...across 17 sensors... // ...from this base address... _preformed_read_g.setParams(CPLD_REG_IMU_DM_P_I|0x80, 6, 17, LSM9DS1_G_DATA_X); // ...and drop the results here. _preformed_read_g.buf = (uint8_t*) __frame_buf_g; _preformed_read_g.buf_len = 102; _preformed_read_m.shouldReap(false); _preformed_read_m.devRegisterAdvance(true); _preformed_read_m.set_opcode(BusOpcode::RX); _preformed_read_m.callback = (BusOpCallback*) this; // Starting from the first magnetometer... // Read 6 bytes... // ...across 17 sensors... // ...from this base address... _preformed_read_m.setParams(CPLD_REG_IMU_DM_P_M|0x80, 6, 17, LSM9DS1_M_DATA_X); // ...and drop the results here. _preformed_read_m.buf = (uint8_t*) __frame_buf_m; _preformed_read_m.buf_len = 102; _preformed_fifo_read.shouldReap(false); _preformed_fifo_read.devRegisterAdvance(true); _preformed_fifo_read.set_opcode(BusOpcode::RX); _preformed_fifo_read.callback = (BusOpCallback*) this; // Starting from the first inertial... // Read 1 byte... // ...across 17 sensors... // ...from this base address... _preformed_fifo_read.setParams(CPLD_REG_IMU_DM_P_I|0x80, 1, 17, LSM9DS1_AG_FIFO_SRC); // ...and drop the results here. _preformed_fifo_read.buf = (uint8_t*) __fifo_levels; _preformed_fifo_read.buf_len = 17; /* Populate all the static preallocation slots for measurements. */ for (uint16_t i = 0; i < PREALLOCATED_IIU_MEASUREMENTS; i++) { __prealloc[i].wipe(); preallocd_measurements.insert(&__prealloc[i]); } // Zero the ManuLegend. for (int i = 0; i < LEGEND_MGR_MAX_DATASET_SIZE; i++) { *(__dataset + i) = 0; } // Global frame data for MAP_STATE. _ptr_sequence = (uint32_t*) (__dataset + LEGEND_DATASET_OFFSET_SEQUENCE/4); _ptr_delta_t = (float*) (__dataset + LEGEND_DATASET_OFFSET_DELTA_T/4); *(_ptr_sequence) = 0; _er_set_flag(LEGEND_MGR_FLAGS_LEGEND_STABLE, true); // Ick.... operating_legend = new ManuLegend(); operating_legend->sensorEnabled(true); //operating_legend->accNullGravity(true); operating_legend->accRaw(true); operating_legend->gyro(true); operating_legend->mag(true); operating_legend->orientation(true); operating_legend->temperature(true); if (operating_legend->finallize()) { local_log.concat("ManuLegend failed to finallize().\n"); } reconfigure_data_map(); setLegend(operating_legend); }