00001
00002
00003
00004 #pragma once
00005 #ifndef MOTION_MODULE_H
00006 #define MOTION_MODULE_H
00007
00008 #include <mutex>
00009 #include <bitset>
00010
00011 #include "device.h"
00012
00013 namespace rsimpl
00014 {
00015 namespace motion_module
00016 {
00017 enum motion_module_errors
00018 {
00019 imu_not_responding = 0,
00020 illegal_configuration = 1,
00021 ts_fifo_overflow = 2,
00022 imu_fifo_overflow = 3,
00023 watchdog_reset = 4,
00024 crc_error = 5,
00025 missing_data_from_imu = 6,
00026 bootloader_failure = 7,
00027 eeprom_error = 8,
00028 bist_check_failed = 9,
00029 uctrl_not_responding = 10,
00030 cx3_fifo_overflow = 11,
00031 general_cx3_failure = 12,
00032 cx3_usb_failure = 13,
00033 reserved_1 = 14,
00034 reserved_2 = 15,
00035 max_mm_error
00036 };
00037
00038
00039 enum class mm_gyro_range : uint8_t
00040 {
00041 gyro_range_default = 0,
00042 gyro_range_1000 = 1,
00043 gyro_range_2000 = 2
00044 };
00045
00046 enum class mm_gyro_bandwidth : uint8_t
00047 {
00048 gyro_bw_default = 0,
00049 gyro_bw_200hz = 1
00050 };
00051
00052 enum class mm_accel_range : uint8_t
00053 {
00054 accel_range_default = 0,
00055 accel_range_4g = 1,
00056 accel_range_8g = 2,
00057 accel_range_16g = 3
00058 };
00059
00060 enum class mm_accel_bandwidth : uint8_t
00061 {
00062 accel_bw_default = 0,
00063 accel_bw_125hz = 1,
00064 accel_bw_250hz = 2
00065 };
00066
00067 struct motion_event_status
00068 {
00069 unsigned reserved_0 : 1;
00070 unsigned pwr_mode_change_done : 1;
00071 unsigned cx3_packet_number : 4;
00072 unsigned reserved_6_15 : 10;
00073 };
00074
00075 struct motion_event
00076 {
00077 std::bitset<16> error_state;
00078 motion_event_status status;
00079 unsigned short imu_entries_num;
00080 unsigned short non_imu_entries_num;
00081 unsigned long timestamp;
00082 rs_motion_data imu_packets[4];
00083 rs_timestamp_data non_imu_packets[8];
00084 };
00085
00086 #pragma pack(push, 1)
00087 struct mm_config
00088 {
00089 uint32_t mm_time_seed;
00090 mm_gyro_range gyro_range;
00091 mm_gyro_bandwidth gyro_bandwidth;
00092 mm_accel_range accel_range;
00093 mm_accel_bandwidth accel_bandwidth;
00094 };
00095
00096 #define FW_IMAGE_PACKET_PAYLOAD_LEN (128)
00097
00098 struct fw_image_packet {
00099 uint8_t op_code;
00100 uint32_t address;
00101 uint16_t length;
00102 uint8_t dummy;
00103 uint8_t data[FW_IMAGE_PACKET_PAYLOAD_LEN];
00104 };
00105 #pragma pack(pop)
00106
00107 void config(uvc::device & device, uint8_t gyro_bw, uint8_t gyro_range, uint8_t accel_bw, uint8_t accel_range, uint32_t time_seed);
00108
00109 enum mm_request : uint8_t
00110 {
00111 mm_output_undefined = 0,
00112 mm_video_output = 1,
00113 mm_events_output = 2
00114 };
00115
00116 inline const char* get_mm_request_name(mm_request request) {
00117 switch (request) {
00118 case mm_output_undefined: return "undefined";
00119 case mm_video_output: return "video";
00120 case mm_events_output: return "motion_tracking";
00121 default: return std::string(to_string() << "unresolved request id: " << request).c_str();
00122 }
00123 }
00124
00125 enum mm_state : uint8_t
00126 {
00127 mm_idle = 0,
00128 mm_streaming = 1,
00129 mm_eventing = 2,
00130 mm_full_load = 3
00131 };
00132
00133 inline const char* get_mm_state_name(mm_state state) {
00134 switch (state) {
00135 case mm_idle: return "idle";
00136 case mm_streaming: return "video";
00137 case mm_eventing: return "motion";
00138 case mm_full_load: return "video+motion";
00139 default: return std::string(to_string() << "unresolved mm state id: " << state).c_str();
00140 }
00141 }
00142
00143 struct motion_module_wraparound
00144 {
00145 motion_module_wraparound()
00146 : timestamp_wraparound(1, std::numeric_limits<uint32_t>::max()), frame_counter_wraparound(0, 0xfff)
00147 {}
00148 wraparound_mechanism<unsigned long long> timestamp_wraparound;
00149 wraparound_mechanism<unsigned long long> frame_counter_wraparound;
00150 };
00151
00152 struct motion_module_parser
00153 {
00154 motion_module_parser()
00155 : mm_data_wraparound(RS_EVENT_SOURCE_COUNT)
00156 {}
00157
00158 std::vector<motion_event> operator() (const unsigned char* data, const int& data_size);
00159 void parse_timestamp(const unsigned char* data, rs_timestamp_data &);
00160 rs_motion_data parse_motion(const unsigned char* data);
00161
00162 std::vector<motion_module_wraparound> mm_data_wraparound;
00163 };
00164
00165 class motion_module_state
00166 {
00167 public:
00168 motion_module_state() : state(mm_idle) {};
00169 mm_state state;
00170 int requested_state(mm_request, bool on) const;
00171 static bool valid(int check_state) { return ((check_state >= mm_idle) && (check_state <= mm_full_load)); }
00172 private:
00173 motion_module_state(const motion_module_state&);
00174 };
00175
00176 class motion_module_control
00177 {
00178 public:
00179
00180 motion_module_control(uvc::device *device, std::timed_mutex& usbMutex);
00181
00182 void toggle_motion_module_power(bool on);
00183 void toggle_motion_module_events(bool on);
00184
00185 void switch_to_iap();
00186 void switch_to_operational();
00187
00188 void firmware_upgrade(void *data, int size);
00189
00190 private:
00191 motion_module_control(const motion_module_control&);
00192 motion_module_state state_handler;
00193 uvc::device* device_handle;
00194 std::mutex mtx;
00195 std::timed_mutex& usbMutex;
00196 bool power_state;
00197
00198 void i2c_iap_write(uint16_t slave_address, uint8_t *buffer, uint16_t len);
00199
00200 void write_firmware(uint8_t *data, int size);
00201
00202 void impose(mm_request request, bool on);
00203 void enter_state(mm_state new_state);
00204 void set_control(mm_request request, bool on);
00205
00206 };
00207
00208 enum class i2c_register : uint32_t {
00209 REG_UCTRL_CFG = 0x00,
00210 REG_INT_ID_CONFIG = 0x04,
00211 REG_INT_TYPE_CONFIG = 0x08,
00212 REG_EEPROM_CMD = 0x0C,
00213 REG_EEPROM_DATA = 0xD0,
00214 REG_TIMER_PRESCALER = 0x14,
00215 REG_TIMER_RESET_VALUE = 0x18,
00216 REG_GYRO_BYPASS_CMD1 = 0x1C,
00217 REG_GYRO_BYPASS_CMD2 = 0x20,
00218 REG_GYRO_BYPASS_RDOUT1 = 0x24,
00219 REG_GYRO_BYPASS_RDOUT2 = 0x28,
00220 REG_ACC_BYPASS_CMD1 = 0x2C,
00221 REG_ACC_BYPASS_CMD2 = 0x30,
00222 REG_ACC_BYPASS_RDOUT1 = 0x34,
00223 REG_ACC_BYPASS_RDOUT2 = 0x38,
00224 REG_REQ_LTR = 0x3C,
00225 REG_STATUS_REG = 0x40,
00226 REG_FIFO_RD = 0x44,
00227 REG_FIRST_INT_IGNORE = 0x48,
00228 REG_IAP_REG = 0x4C,
00229 REG_INT_ENABLE = 0x50,
00230 REG_CURR_PWR_STATE = 0x54,
00231 REG_NEXT_PWR_STATE = 0x58,
00232 REG_ACC_BW = 0x5C,
00233 REG_GYRO_BW = 0x60,
00234 REG_ACC_RANGE = 0x64,
00235 REG_GYRO_RANGE = 0x68,
00236 REG_IMG_VER = 0x6C,
00237 REG_ERROR = 0x70,
00238 REG_JUMP_TO_APP = 0x77
00239 };
00240
00241 enum class power_states : uint32_t {
00242 PWR_STATE_DNR = 0x00,
00243 PWR_STATE_INIT = 0x02,
00244 PWR_STATE_ACTIVE = 0x03,
00245 PWR_STATE_PAUSE = 0x04,
00246 PWR_STATE_IAP = 0x05
00247 };
00248
00249 enum class adaptor_board_command : uint32_t
00250 {
00251 IRB = 0x01,
00252 IWB = 0x02,
00253 GVD = 0x03,
00254 IAP_IRB = 0x04,
00255 IAP_IWB = 0x05,
00256 FRCNT = 0x06,
00257 GLD = 0x07,
00258 GPW = 0x08,
00259 GPR = 0x09,
00260 MMPWR = 0x0A,
00261 DSPWR = 0x0B,
00262 EXT_TRIG = 0x0C,
00263 CX3FWUPD = 0x0D,
00264 MM_SNB = 0x10,
00265 MM_TRB = 0x11,
00266 MM_ACTIVATE = 0x0E
00267 };
00268 }
00269 }
00270
00271 #endif // MOTION_MODULE_H