Ray Liu
/
NuMaker-mbed-NuBrick-example
Modify the file main.cpp for M487
NuMaker-mbed-NuBrick/NuBrickMaster.cpp@0:a67fc999dd68, 2017-09-29 (annotated)
- Committer:
- shliu1
- Date:
- Fri Sep 29 05:44:02 2017 +0000
- Revision:
- 0:a67fc999dd68
main.cpp adds the setting of TARGET_NUMAKER_PFM_M487 for M487
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
shliu1 | 0:a67fc999dd68 | 1 | /* mbed Microcontroller Library |
shliu1 | 0:a67fc999dd68 | 2 | * Copyright (c) 2016 ARM Limited |
shliu1 | 0:a67fc999dd68 | 3 | * |
shliu1 | 0:a67fc999dd68 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
shliu1 | 0:a67fc999dd68 | 5 | * you may not use this file except in compliance with the License. |
shliu1 | 0:a67fc999dd68 | 6 | * You may obtain a copy of the License at |
shliu1 | 0:a67fc999dd68 | 7 | * |
shliu1 | 0:a67fc999dd68 | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
shliu1 | 0:a67fc999dd68 | 9 | * |
shliu1 | 0:a67fc999dd68 | 10 | * Unless required by applicable law or agreed to in writing, software |
shliu1 | 0:a67fc999dd68 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
shliu1 | 0:a67fc999dd68 | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
shliu1 | 0:a67fc999dd68 | 13 | * See the License for the specific language governing permissions and |
shliu1 | 0:a67fc999dd68 | 14 | * limitations under the License. |
shliu1 | 0:a67fc999dd68 | 15 | */ |
shliu1 | 0:a67fc999dd68 | 16 | #include "NuBrickMaster.h" |
shliu1 | 0:a67fc999dd68 | 17 | #include <cstring> |
shliu1 | 0:a67fc999dd68 | 18 | |
shliu1 | 0:a67fc999dd68 | 19 | SingletonPtr<PlatformMutex> NuBrickMaster::_mutex; |
shliu1 | 0:a67fc999dd68 | 20 | |
shliu1 | 0:a67fc999dd68 | 21 | NuBrickMaster::NuBrickMaster(I2C &i2c, int i2c_addr, bool debug) |
shliu1 | 0:a67fc999dd68 | 22 | : _i2c(i2c), _i2c_addr(i2c_addr), |
shliu1 | 0:a67fc999dd68 | 23 | _i2c_buf_pos(_i2c_buf), _i2c_buf_end(_i2c_buf + sizeof (_i2c_buf) / sizeof (_i2c_buf[0])), _i2c_buf_overflow(false), |
shliu1 | 0:a67fc999dd68 | 24 | _connected(false), _debug(debug), _null_field(0, ""), |
shliu1 | 0:a67fc999dd68 | 25 | _feature_report_fields(NULL), _num_feature_report_fields(0), |
shliu1 | 0:a67fc999dd68 | 26 | _input_report_fields(NULL), _num_input_report_fields(0), |
shliu1 | 0:a67fc999dd68 | 27 | _output_report_fields(NULL), _num_output_report_fields(0) { |
shliu1 | 0:a67fc999dd68 | 28 | |
shliu1 | 0:a67fc999dd68 | 29 | // No lock needed in the constructor |
shliu1 | 0:a67fc999dd68 | 30 | |
shliu1 | 0:a67fc999dd68 | 31 | // Set I2C bus clock to 100K. |
shliu1 | 0:a67fc999dd68 | 32 | _i2c.frequency(100000); |
shliu1 | 0:a67fc999dd68 | 33 | |
shliu1 | 0:a67fc999dd68 | 34 | memset(_i2c_buf, 0x00, sizeof (_i2c_buf)); |
shliu1 | 0:a67fc999dd68 | 35 | } |
shliu1 | 0:a67fc999dd68 | 36 | |
shliu1 | 0:a67fc999dd68 | 37 | NuBrickMaster::~NuBrickMaster() { |
shliu1 | 0:a67fc999dd68 | 38 | |
shliu1 | 0:a67fc999dd68 | 39 | // Remove fields of feature report allocated by subclass |
shliu1 | 0:a67fc999dd68 | 40 | remove_feature_fields(); |
shliu1 | 0:a67fc999dd68 | 41 | // Remove fields of input report allocated by subclass |
shliu1 | 0:a67fc999dd68 | 42 | remove_input_fields(); |
shliu1 | 0:a67fc999dd68 | 43 | // Remove fields of output report allocated by subclass |
shliu1 | 0:a67fc999dd68 | 44 | remove_output_fields(); |
shliu1 | 0:a67fc999dd68 | 45 | } |
shliu1 | 0:a67fc999dd68 | 46 | |
shliu1 | 0:a67fc999dd68 | 47 | bool NuBrickMaster::connect(void) { |
shliu1 | 0:a67fc999dd68 | 48 | // Support thread-safe |
shliu1 | 0:a67fc999dd68 | 49 | MutexGuard guard; |
shliu1 | 0:a67fc999dd68 | 50 | |
shliu1 | 0:a67fc999dd68 | 51 | if (_connected) { |
shliu1 | 0:a67fc999dd68 | 52 | return true; |
shliu1 | 0:a67fc999dd68 | 53 | } |
shliu1 | 0:a67fc999dd68 | 54 | |
shliu1 | 0:a67fc999dd68 | 55 | // Get device descriptor |
shliu1 | 0:a67fc999dd68 | 56 | if (! pull_device_desc()) { |
shliu1 | 0:a67fc999dd68 | 57 | _connected = false; |
shliu1 | 0:a67fc999dd68 | 58 | NUBRICK_ERROR_RETURN_FALSE("pull_device_desc() failed\r\n"); |
shliu1 | 0:a67fc999dd68 | 59 | } |
shliu1 | 0:a67fc999dd68 | 60 | // Get report descriptor |
shliu1 | 0:a67fc999dd68 | 61 | if (! pull_report_desc()) { |
shliu1 | 0:a67fc999dd68 | 62 | _connected = false; |
shliu1 | 0:a67fc999dd68 | 63 | NUBRICK_ERROR_RETURN_FALSE("pull_report_desc() failed\r\n"); |
shliu1 | 0:a67fc999dd68 | 64 | } |
shliu1 | 0:a67fc999dd68 | 65 | |
shliu1 | 0:a67fc999dd68 | 66 | _connected = true; |
shliu1 | 0:a67fc999dd68 | 67 | return true; |
shliu1 | 0:a67fc999dd68 | 68 | } |
shliu1 | 0:a67fc999dd68 | 69 | |
shliu1 | 0:a67fc999dd68 | 70 | NuBrickField &NuBrickMaster::operator[](const char *report_field_name) { |
shliu1 | 0:a67fc999dd68 | 71 | // Support thread-safe |
shliu1 | 0:a67fc999dd68 | 72 | MutexGuard guard; |
shliu1 | 0:a67fc999dd68 | 73 | |
shliu1 | 0:a67fc999dd68 | 74 | if (! report_field_name) { |
shliu1 | 0:a67fc999dd68 | 75 | NUBRICK_ERROR_RETURN_NULL_FIELD("NULL string not support\r\n"); |
shliu1 | 0:a67fc999dd68 | 76 | } |
shliu1 | 0:a67fc999dd68 | 77 | |
shliu1 | 0:a67fc999dd68 | 78 | const char *dot_plus_field_name = strchr(report_field_name, '.'); |
shliu1 | 0:a67fc999dd68 | 79 | if (dot_plus_field_name == NULL) { |
shliu1 | 0:a67fc999dd68 | 80 | NUBRICK_ERROR_RETURN_NULL_FIELD("%s not support\r\n", report_field_name); |
shliu1 | 0:a67fc999dd68 | 81 | } |
shliu1 | 0:a67fc999dd68 | 82 | |
shliu1 | 0:a67fc999dd68 | 83 | const char *field_name = dot_plus_field_name + 1; |
shliu1 | 0:a67fc999dd68 | 84 | unsigned report_name_len = dot_plus_field_name - report_field_name; |
shliu1 | 0:a67fc999dd68 | 85 | |
shliu1 | 0:a67fc999dd68 | 86 | if (strncmp("feature", report_field_name, report_name_len) == 0) { |
shliu1 | 0:a67fc999dd68 | 87 | NuBrickField *field = _feature_report_fields; |
shliu1 | 0:a67fc999dd68 | 88 | NuBrickField *field_end = _feature_report_fields + _num_feature_report_fields; |
shliu1 | 0:a67fc999dd68 | 89 | |
shliu1 | 0:a67fc999dd68 | 90 | for (; field != field_end; field ++) { |
shliu1 | 0:a67fc999dd68 | 91 | const char *field_name_iter = field->_name; |
shliu1 | 0:a67fc999dd68 | 92 | |
shliu1 | 0:a67fc999dd68 | 93 | if (strcmp(field_name, field_name_iter) == 0) { |
shliu1 | 0:a67fc999dd68 | 94 | return *field; |
shliu1 | 0:a67fc999dd68 | 95 | } |
shliu1 | 0:a67fc999dd68 | 96 | } |
shliu1 | 0:a67fc999dd68 | 97 | NUBRICK_ERROR_RETURN_NULL_FIELD("%s not support\r\n", report_field_name); |
shliu1 | 0:a67fc999dd68 | 98 | } |
shliu1 | 0:a67fc999dd68 | 99 | else if (strncmp("input", report_field_name, report_name_len) == 0) { |
shliu1 | 0:a67fc999dd68 | 100 | NuBrickField *field = _input_report_fields; |
shliu1 | 0:a67fc999dd68 | 101 | NuBrickField *field_end = _input_report_fields + _num_input_report_fields; |
shliu1 | 0:a67fc999dd68 | 102 | |
shliu1 | 0:a67fc999dd68 | 103 | for (; field != field_end; field ++) { |
shliu1 | 0:a67fc999dd68 | 104 | const char *field_name_iter = field->_name; |
shliu1 | 0:a67fc999dd68 | 105 | |
shliu1 | 0:a67fc999dd68 | 106 | if (strcmp(field_name, field_name_iter) == 0) { |
shliu1 | 0:a67fc999dd68 | 107 | return *field; |
shliu1 | 0:a67fc999dd68 | 108 | } |
shliu1 | 0:a67fc999dd68 | 109 | } |
shliu1 | 0:a67fc999dd68 | 110 | NUBRICK_ERROR_RETURN_NULL_FIELD("%s not support\r\n", report_field_name); |
shliu1 | 0:a67fc999dd68 | 111 | |
shliu1 | 0:a67fc999dd68 | 112 | } |
shliu1 | 0:a67fc999dd68 | 113 | else if (strncmp("output", report_field_name, report_name_len) == 0) { |
shliu1 | 0:a67fc999dd68 | 114 | NuBrickField *field = _output_report_fields; |
shliu1 | 0:a67fc999dd68 | 115 | NuBrickField *field_end = _output_report_fields + _num_output_report_fields; |
shliu1 | 0:a67fc999dd68 | 116 | |
shliu1 | 0:a67fc999dd68 | 117 | for (; field != field_end; field ++) { |
shliu1 | 0:a67fc999dd68 | 118 | const char *field_name_iter = field->_name; |
shliu1 | 0:a67fc999dd68 | 119 | |
shliu1 | 0:a67fc999dd68 | 120 | if (strcmp(field_name, field_name_iter) == 0) { |
shliu1 | 0:a67fc999dd68 | 121 | return *field; |
shliu1 | 0:a67fc999dd68 | 122 | } |
shliu1 | 0:a67fc999dd68 | 123 | } |
shliu1 | 0:a67fc999dd68 | 124 | NUBRICK_ERROR_RETURN_NULL_FIELD("%s not support\r\n", report_field_name); |
shliu1 | 0:a67fc999dd68 | 125 | } |
shliu1 | 0:a67fc999dd68 | 126 | else { |
shliu1 | 0:a67fc999dd68 | 127 | NUBRICK_ERROR_RETURN_NULL_FIELD("%s not support\r\n", report_field_name); |
shliu1 | 0:a67fc999dd68 | 128 | } |
shliu1 | 0:a67fc999dd68 | 129 | |
shliu1 | 0:a67fc999dd68 | 130 | } |
shliu1 | 0:a67fc999dd68 | 131 | |
shliu1 | 0:a67fc999dd68 | 132 | bool NuBrickMaster::pull_device_desc(void) { |
shliu1 | 0:a67fc999dd68 | 133 | // Support thread-safe |
shliu1 | 0:a67fc999dd68 | 134 | MutexGuard guard; |
shliu1 | 0:a67fc999dd68 | 135 | |
shliu1 | 0:a67fc999dd68 | 136 | // Send GetDeviceDescriptor command |
shliu1 | 0:a67fc999dd68 | 137 | nu_set16_le(_i2c_buf, NuBrick_Comm_GetDeviceDesc); |
shliu1 | 0:a67fc999dd68 | 138 | if (_i2c.write(_i2c_addr, (char *) _i2c_buf, 2, true)) { |
shliu1 | 0:a67fc999dd68 | 139 | NUBRICK_ERROR_RETURN_FALSE("i2c.write() failed\r\n"); |
shliu1 | 0:a67fc999dd68 | 140 | } |
shliu1 | 0:a67fc999dd68 | 141 | |
shliu1 | 0:a67fc999dd68 | 142 | // Receive device descriptor |
shliu1 | 0:a67fc999dd68 | 143 | if (_i2c.read(_i2c_addr, (char *) _i2c_buf, NuBrick_DeviceDesc_Len, false)) { |
shliu1 | 0:a67fc999dd68 | 144 | NUBRICK_ERROR_RETURN_FALSE("i2c.read() failed\r\n"); |
shliu1 | 0:a67fc999dd68 | 145 | } |
shliu1 | 0:a67fc999dd68 | 146 | |
shliu1 | 0:a67fc999dd68 | 147 | // Un-serialize device descriptor |
shliu1 | 0:a67fc999dd68 | 148 | _i2c_buf_pos = _i2c_buf; |
shliu1 | 0:a67fc999dd68 | 149 | if (! unserialize_device_desc()) { |
shliu1 | 0:a67fc999dd68 | 150 | NUBRICK_ERROR_RETURN_FALSE("unserialize_device_desc() failed\r\n"); |
shliu1 | 0:a67fc999dd68 | 151 | } |
shliu1 | 0:a67fc999dd68 | 152 | |
shliu1 | 0:a67fc999dd68 | 153 | return true; |
shliu1 | 0:a67fc999dd68 | 154 | } |
shliu1 | 0:a67fc999dd68 | 155 | |
shliu1 | 0:a67fc999dd68 | 156 | bool NuBrickMaster::pull_report_desc(void) { |
shliu1 | 0:a67fc999dd68 | 157 | // Support thread-safe |
shliu1 | 0:a67fc999dd68 | 158 | MutexGuard guard; |
shliu1 | 0:a67fc999dd68 | 159 | |
shliu1 | 0:a67fc999dd68 | 160 | // Send GetReportDescriptor command |
shliu1 | 0:a67fc999dd68 | 161 | nu_set16_le(_i2c_buf, NuBrick_Comm_GetReportDesc); |
shliu1 | 0:a67fc999dd68 | 162 | if (_i2c.write(_i2c_addr, (char *) _i2c_buf, 2, true)) { |
shliu1 | 0:a67fc999dd68 | 163 | NUBRICK_ERROR_RETURN_FALSE("i2c.write() failed\r\n"); |
shliu1 | 0:a67fc999dd68 | 164 | } |
shliu1 | 0:a67fc999dd68 | 165 | |
shliu1 | 0:a67fc999dd68 | 166 | // Receive report descriptor |
shliu1 | 0:a67fc999dd68 | 167 | if (_i2c.read(_i2c_addr, (char *) _i2c_buf, _dev_desc.report_desc_len, false)) { |
shliu1 | 0:a67fc999dd68 | 168 | NUBRICK_ERROR_RETURN_FALSE("i2c.read() failed\r\n"); |
shliu1 | 0:a67fc999dd68 | 169 | } |
shliu1 | 0:a67fc999dd68 | 170 | |
shliu1 | 0:a67fc999dd68 | 171 | // Un-serialize report descriptor |
shliu1 | 0:a67fc999dd68 | 172 | _i2c_buf_pos = _i2c_buf; |
shliu1 | 0:a67fc999dd68 | 173 | if (! unserialize_report_desc()) { |
shliu1 | 0:a67fc999dd68 | 174 | NUBRICK_ERROR_RETURN_FALSE("unserialize_report_desc() failed\r\n"); |
shliu1 | 0:a67fc999dd68 | 175 | } |
shliu1 | 0:a67fc999dd68 | 176 | |
shliu1 | 0:a67fc999dd68 | 177 | return true; |
shliu1 | 0:a67fc999dd68 | 178 | } |
shliu1 | 0:a67fc999dd68 | 179 | |
shliu1 | 0:a67fc999dd68 | 180 | bool NuBrickMaster::pull_input_report(void) { |
shliu1 | 0:a67fc999dd68 | 181 | // Support thread-safe |
shliu1 | 0:a67fc999dd68 | 182 | MutexGuard guard; |
shliu1 | 0:a67fc999dd68 | 183 | |
shliu1 | 0:a67fc999dd68 | 184 | NUBRICK_CHECK_CONNECT(); |
shliu1 | 0:a67fc999dd68 | 185 | |
shliu1 | 0:a67fc999dd68 | 186 | // Send GetInputReport command |
shliu1 | 0:a67fc999dd68 | 187 | nu_set16_le(_i2c_buf, NuBrick_Comm_GetInputReport); |
shliu1 | 0:a67fc999dd68 | 188 | if (_i2c.write(_i2c_addr, (char *) _i2c_buf, 2, true)) { |
shliu1 | 0:a67fc999dd68 | 189 | NUBRICK_ERROR_RETURN_FALSE("i2c.write() failed\r\n"); |
shliu1 | 0:a67fc999dd68 | 190 | } |
shliu1 | 0:a67fc999dd68 | 191 | |
shliu1 | 0:a67fc999dd68 | 192 | // Receive input report |
shliu1 | 0:a67fc999dd68 | 193 | if (_i2c.read(_i2c_addr, (char *) _i2c_buf, _dev_desc.input_report_len, false)) { |
shliu1 | 0:a67fc999dd68 | 194 | NUBRICK_ERROR_RETURN_FALSE("i2c.read() failed\r\n"); |
shliu1 | 0:a67fc999dd68 | 195 | } |
shliu1 | 0:a67fc999dd68 | 196 | |
shliu1 | 0:a67fc999dd68 | 197 | // Un-serialize input report |
shliu1 | 0:a67fc999dd68 | 198 | _i2c_buf_pos = _i2c_buf; |
shliu1 | 0:a67fc999dd68 | 199 | if (! unserialize_input_report()) { |
shliu1 | 0:a67fc999dd68 | 200 | NUBRICK_ERROR_RETURN_FALSE("unserialize_input_report() failed\r\n"); |
shliu1 | 0:a67fc999dd68 | 201 | } |
shliu1 | 0:a67fc999dd68 | 202 | |
shliu1 | 0:a67fc999dd68 | 203 | return true; |
shliu1 | 0:a67fc999dd68 | 204 | } |
shliu1 | 0:a67fc999dd68 | 205 | |
shliu1 | 0:a67fc999dd68 | 206 | bool NuBrickMaster::push_output_report(void) { |
shliu1 | 0:a67fc999dd68 | 207 | // Support thread-safe |
shliu1 | 0:a67fc999dd68 | 208 | MutexGuard guard; |
shliu1 | 0:a67fc999dd68 | 209 | |
shliu1 | 0:a67fc999dd68 | 210 | NUBRICK_CHECK_CONNECT(); |
shliu1 | 0:a67fc999dd68 | 211 | |
shliu1 | 0:a67fc999dd68 | 212 | _i2c_buf_pos = _i2c_buf; |
shliu1 | 0:a67fc999dd68 | 213 | |
shliu1 | 0:a67fc999dd68 | 214 | // Send SetOutputReport command |
shliu1 | 0:a67fc999dd68 | 215 | set16_le_next(NuBrick_Comm_SetOutputReport); |
shliu1 | 0:a67fc999dd68 | 216 | |
shliu1 | 0:a67fc999dd68 | 217 | // Serialize output report |
shliu1 | 0:a67fc999dd68 | 218 | if (! serialize_output_report()) { |
shliu1 | 0:a67fc999dd68 | 219 | NUBRICK_ERROR_RETURN_FALSE("serialize_output_report() failed\r\n"); |
shliu1 | 0:a67fc999dd68 | 220 | } |
shliu1 | 0:a67fc999dd68 | 221 | |
shliu1 | 0:a67fc999dd68 | 222 | // Send Output report |
shliu1 | 0:a67fc999dd68 | 223 | if (_i2c.write(_i2c_addr, (char *) _i2c_buf, _i2c_buf_pos - _i2c_buf, false)) { |
shliu1 | 0:a67fc999dd68 | 224 | NUBRICK_ERROR_RETURN_FALSE("i2c.write() failed\r\n"); |
shliu1 | 0:a67fc999dd68 | 225 | } |
shliu1 | 0:a67fc999dd68 | 226 | |
shliu1 | 0:a67fc999dd68 | 227 | return true; |
shliu1 | 0:a67fc999dd68 | 228 | } |
shliu1 | 0:a67fc999dd68 | 229 | |
shliu1 | 0:a67fc999dd68 | 230 | bool NuBrickMaster::pull_feature_report(void) { |
shliu1 | 0:a67fc999dd68 | 231 | // Support thread-safe |
shliu1 | 0:a67fc999dd68 | 232 | MutexGuard guard; |
shliu1 | 0:a67fc999dd68 | 233 | |
shliu1 | 0:a67fc999dd68 | 234 | NUBRICK_CHECK_CONNECT(); |
shliu1 | 0:a67fc999dd68 | 235 | |
shliu1 | 0:a67fc999dd68 | 236 | // Send GetFeatureReport command |
shliu1 | 0:a67fc999dd68 | 237 | nu_set16_le(_i2c_buf, NuBrick_Comm_GetFeatureReport); |
shliu1 | 0:a67fc999dd68 | 238 | if (_i2c.write(_i2c_addr, (char *) _i2c_buf, 2, true)) { |
shliu1 | 0:a67fc999dd68 | 239 | NUBRICK_ERROR_RETURN_FALSE("i2c.write() failed\r\n"); |
shliu1 | 0:a67fc999dd68 | 240 | } |
shliu1 | 0:a67fc999dd68 | 241 | |
shliu1 | 0:a67fc999dd68 | 242 | // Receive feature report |
shliu1 | 0:a67fc999dd68 | 243 | if (_i2c.read(_i2c_addr, (char *) _i2c_buf, _dev_desc.getfeat_report_len, false)) { |
shliu1 | 0:a67fc999dd68 | 244 | NUBRICK_ERROR_RETURN_FALSE("i2c.read() failed\r\n"); |
shliu1 | 0:a67fc999dd68 | 245 | } |
shliu1 | 0:a67fc999dd68 | 246 | |
shliu1 | 0:a67fc999dd68 | 247 | // Un-serialize feature report |
shliu1 | 0:a67fc999dd68 | 248 | _i2c_buf_pos = _i2c_buf; |
shliu1 | 0:a67fc999dd68 | 249 | if (! unserialize_feature_report()) { |
shliu1 | 0:a67fc999dd68 | 250 | NUBRICK_ERROR_RETURN_FALSE("unserialize_feature_report() failed\r\n"); |
shliu1 | 0:a67fc999dd68 | 251 | } |
shliu1 | 0:a67fc999dd68 | 252 | |
shliu1 | 0:a67fc999dd68 | 253 | return true; |
shliu1 | 0:a67fc999dd68 | 254 | } |
shliu1 | 0:a67fc999dd68 | 255 | |
shliu1 | 0:a67fc999dd68 | 256 | bool NuBrickMaster::push_feature_report(void) { |
shliu1 | 0:a67fc999dd68 | 257 | // Support thread-safe |
shliu1 | 0:a67fc999dd68 | 258 | MutexGuard guard; |
shliu1 | 0:a67fc999dd68 | 259 | |
shliu1 | 0:a67fc999dd68 | 260 | NUBRICK_CHECK_CONNECT(); |
shliu1 | 0:a67fc999dd68 | 261 | |
shliu1 | 0:a67fc999dd68 | 262 | _i2c_buf_pos = _i2c_buf; |
shliu1 | 0:a67fc999dd68 | 263 | |
shliu1 | 0:a67fc999dd68 | 264 | // Send SetFeatureReport command |
shliu1 | 0:a67fc999dd68 | 265 | set16_le_next(NuBrick_Comm_SetFeatureReport); |
shliu1 | 0:a67fc999dd68 | 266 | |
shliu1 | 0:a67fc999dd68 | 267 | // Serialize feature report |
shliu1 | 0:a67fc999dd68 | 268 | if (! serialize_feature_report()) { |
shliu1 | 0:a67fc999dd68 | 269 | NUBRICK_ERROR_RETURN_FALSE("serialize_feature_report() failed\r\n"); |
shliu1 | 0:a67fc999dd68 | 270 | } |
shliu1 | 0:a67fc999dd68 | 271 | |
shliu1 | 0:a67fc999dd68 | 272 | // Send feature report |
shliu1 | 0:a67fc999dd68 | 273 | if (_i2c.write(_i2c_addr, (char *) _i2c_buf, _i2c_buf_pos - _i2c_buf, false)) { |
shliu1 | 0:a67fc999dd68 | 274 | NUBRICK_ERROR_RETURN_FALSE("i2c.write() failed\r\n"); |
shliu1 | 0:a67fc999dd68 | 275 | } |
shliu1 | 0:a67fc999dd68 | 276 | |
shliu1 | 0:a67fc999dd68 | 277 | return true; |
shliu1 | 0:a67fc999dd68 | 278 | } |
shliu1 | 0:a67fc999dd68 | 279 | |
shliu1 | 0:a67fc999dd68 | 280 | bool NuBrickMaster::print_device_desc(void) { |
shliu1 | 0:a67fc999dd68 | 281 | // Support thread-safe |
shliu1 | 0:a67fc999dd68 | 282 | MutexGuard guard; |
shliu1 | 0:a67fc999dd68 | 283 | |
shliu1 | 0:a67fc999dd68 | 284 | NUBRICK_CHECK_CONNECT(); |
shliu1 | 0:a67fc999dd68 | 285 | |
shliu1 | 0:a67fc999dd68 | 286 | printf("Device descriptor length\t\t%d\r\n", _dev_desc.dev_desc_len); |
shliu1 | 0:a67fc999dd68 | 287 | printf("Report descriptor length\t\t%d\r\n", _dev_desc.report_desc_len); |
shliu1 | 0:a67fc999dd68 | 288 | printf("Input report length\t\t\t%d\r\n", _dev_desc.input_report_len); |
shliu1 | 0:a67fc999dd68 | 289 | printf("Output report length\t\t\t%d\r\n", _dev_desc.output_report_len); |
shliu1 | 0:a67fc999dd68 | 290 | printf("Get feature report length\t\t%d\r\n", _dev_desc.getfeat_report_len); |
shliu1 | 0:a67fc999dd68 | 291 | printf("Set feature report length\t\t%d\r\n", _dev_desc.setfeat_report_len); |
shliu1 | 0:a67fc999dd68 | 292 | printf("Company ID\t\t\t\t%d\r\n", _dev_desc.cid); |
shliu1 | 0:a67fc999dd68 | 293 | printf("Device ID\t\t\t\t%d\r\n", _dev_desc.did); |
shliu1 | 0:a67fc999dd68 | 294 | printf("Product ID\t\t\t\t%d\r\n", _dev_desc.pid); |
shliu1 | 0:a67fc999dd68 | 295 | printf("Product ID\t\t\t\t%d\r\n", _dev_desc.uid); |
shliu1 | 0:a67fc999dd68 | 296 | printf("Product ID\t\t\t\t%d\r\n", _dev_desc.ucid); |
shliu1 | 0:a67fc999dd68 | 297 | |
shliu1 | 0:a67fc999dd68 | 298 | return true; |
shliu1 | 0:a67fc999dd68 | 299 | } |
shliu1 | 0:a67fc999dd68 | 300 | |
shliu1 | 0:a67fc999dd68 | 301 | bool NuBrickMaster::print_feature_report(void) { |
shliu1 | 0:a67fc999dd68 | 302 | // Support thread-safe |
shliu1 | 0:a67fc999dd68 | 303 | MutexGuard guard; |
shliu1 | 0:a67fc999dd68 | 304 | |
shliu1 | 0:a67fc999dd68 | 305 | NUBRICK_CHECK_CONNECT(); |
shliu1 | 0:a67fc999dd68 | 306 | |
shliu1 | 0:a67fc999dd68 | 307 | print_report(_feature_report_fields, _num_feature_report_fields, "feature report"); |
shliu1 | 0:a67fc999dd68 | 308 | |
shliu1 | 0:a67fc999dd68 | 309 | return true; |
shliu1 | 0:a67fc999dd68 | 310 | } |
shliu1 | 0:a67fc999dd68 | 311 | |
shliu1 | 0:a67fc999dd68 | 312 | |
shliu1 | 0:a67fc999dd68 | 313 | bool NuBrickMaster::print_input_report(void) { |
shliu1 | 0:a67fc999dd68 | 314 | // Support thread-safe |
shliu1 | 0:a67fc999dd68 | 315 | MutexGuard guard; |
shliu1 | 0:a67fc999dd68 | 316 | |
shliu1 | 0:a67fc999dd68 | 317 | NUBRICK_CHECK_CONNECT(); |
shliu1 | 0:a67fc999dd68 | 318 | |
shliu1 | 0:a67fc999dd68 | 319 | print_report(_input_report_fields, _num_input_report_fields, "input report"); |
shliu1 | 0:a67fc999dd68 | 320 | |
shliu1 | 0:a67fc999dd68 | 321 | return true; |
shliu1 | 0:a67fc999dd68 | 322 | } |
shliu1 | 0:a67fc999dd68 | 323 | |
shliu1 | 0:a67fc999dd68 | 324 | |
shliu1 | 0:a67fc999dd68 | 325 | bool NuBrickMaster::print_output_report(void) { |
shliu1 | 0:a67fc999dd68 | 326 | // Support thread-safe |
shliu1 | 0:a67fc999dd68 | 327 | MutexGuard guard; |
shliu1 | 0:a67fc999dd68 | 328 | |
shliu1 | 0:a67fc999dd68 | 329 | NUBRICK_CHECK_CONNECT(); |
shliu1 | 0:a67fc999dd68 | 330 | |
shliu1 | 0:a67fc999dd68 | 331 | print_report(_output_report_fields, _num_output_report_fields, "output report"); |
shliu1 | 0:a67fc999dd68 | 332 | |
shliu1 | 0:a67fc999dd68 | 333 | return true; |
shliu1 | 0:a67fc999dd68 | 334 | } |
shliu1 | 0:a67fc999dd68 | 335 | |
shliu1 | 0:a67fc999dd68 | 336 | void NuBrickMaster::add_feature_fields(const NuBrickField::IndexName *field_index_name, unsigned num_index_name) { |
shliu1 | 0:a67fc999dd68 | 337 | |
shliu1 | 0:a67fc999dd68 | 338 | remove_report_fields(_feature_report_fields, _num_feature_report_fields); |
shliu1 | 0:a67fc999dd68 | 339 | add_report_fields(field_index_name, num_index_name, _feature_report_fields, _num_feature_report_fields); |
shliu1 | 0:a67fc999dd68 | 340 | } |
shliu1 | 0:a67fc999dd68 | 341 | |
shliu1 | 0:a67fc999dd68 | 342 | void NuBrickMaster::remove_feature_fields(void) { |
shliu1 | 0:a67fc999dd68 | 343 | |
shliu1 | 0:a67fc999dd68 | 344 | remove_report_fields(_feature_report_fields, _num_feature_report_fields); |
shliu1 | 0:a67fc999dd68 | 345 | } |
shliu1 | 0:a67fc999dd68 | 346 | |
shliu1 | 0:a67fc999dd68 | 347 | void NuBrickMaster::add_input_fields(const NuBrickField::IndexName *field_index_name, unsigned num_index_name) { |
shliu1 | 0:a67fc999dd68 | 348 | |
shliu1 | 0:a67fc999dd68 | 349 | remove_report_fields(_input_report_fields, _num_input_report_fields); |
shliu1 | 0:a67fc999dd68 | 350 | add_report_fields(field_index_name, num_index_name, _input_report_fields, _num_input_report_fields); |
shliu1 | 0:a67fc999dd68 | 351 | } |
shliu1 | 0:a67fc999dd68 | 352 | |
shliu1 | 0:a67fc999dd68 | 353 | void NuBrickMaster::remove_input_fields(void) { |
shliu1 | 0:a67fc999dd68 | 354 | |
shliu1 | 0:a67fc999dd68 | 355 | remove_report_fields(_input_report_fields, _num_input_report_fields); |
shliu1 | 0:a67fc999dd68 | 356 | } |
shliu1 | 0:a67fc999dd68 | 357 | |
shliu1 | 0:a67fc999dd68 | 358 | void NuBrickMaster::add_output_fields(const NuBrickField::IndexName *field_index_name, unsigned num_index_name) { |
shliu1 | 0:a67fc999dd68 | 359 | |
shliu1 | 0:a67fc999dd68 | 360 | remove_report_fields(_output_report_fields, _num_output_report_fields); |
shliu1 | 0:a67fc999dd68 | 361 | add_report_fields(field_index_name, num_index_name, _output_report_fields, _num_output_report_fields); |
shliu1 | 0:a67fc999dd68 | 362 | } |
shliu1 | 0:a67fc999dd68 | 363 | |
shliu1 | 0:a67fc999dd68 | 364 | void NuBrickMaster::remove_output_fields(void) { |
shliu1 | 0:a67fc999dd68 | 365 | |
shliu1 | 0:a67fc999dd68 | 366 | remove_report_fields(_output_report_fields, _num_output_report_fields); |
shliu1 | 0:a67fc999dd68 | 367 | } |
shliu1 | 0:a67fc999dd68 | 368 | |
shliu1 | 0:a67fc999dd68 | 369 | void NuBrickMaster::add_report_fields(const NuBrickField::IndexName *field_index_name, unsigned num_index_name, |
shliu1 | 0:a67fc999dd68 | 370 | NuBrickField *&report_fields, unsigned &num_report_fields) { |
shliu1 | 0:a67fc999dd68 | 371 | |
shliu1 | 0:a67fc999dd68 | 372 | MBED_ASSERT(report_fields == NULL); |
shliu1 | 0:a67fc999dd68 | 373 | MBED_ASSERT(num_report_fields == 0); |
shliu1 | 0:a67fc999dd68 | 374 | |
shliu1 | 0:a67fc999dd68 | 375 | unsigned i; |
shliu1 | 0:a67fc999dd68 | 376 | |
shliu1 | 0:a67fc999dd68 | 377 | num_report_fields = num_index_name; |
shliu1 | 0:a67fc999dd68 | 378 | void *raw_memory = ::operator new(sizeof (NuBrickField) * num_index_name); |
shliu1 | 0:a67fc999dd68 | 379 | report_fields = static_cast<NuBrickField *>(raw_memory); |
shliu1 | 0:a67fc999dd68 | 380 | for (i = 0; i < num_index_name; i ++) { |
shliu1 | 0:a67fc999dd68 | 381 | NuBrickField *field = report_fields + i; |
shliu1 | 0:a67fc999dd68 | 382 | new (field) NuBrickField(field_index_name[i].first, field_index_name[i].second); |
shliu1 | 0:a67fc999dd68 | 383 | } |
shliu1 | 0:a67fc999dd68 | 384 | } |
shliu1 | 0:a67fc999dd68 | 385 | |
shliu1 | 0:a67fc999dd68 | 386 | void NuBrickMaster::NuBrickMaster::remove_report_fields(NuBrickField *&report_fields, unsigned &num_report_fields) { |
shliu1 | 0:a67fc999dd68 | 387 | |
shliu1 | 0:a67fc999dd68 | 388 | unsigned i; |
shliu1 | 0:a67fc999dd68 | 389 | |
shliu1 | 0:a67fc999dd68 | 390 | for (i = 0; i < num_report_fields; i ++) { |
shliu1 | 0:a67fc999dd68 | 391 | NuBrickField *field = report_fields + i; |
shliu1 | 0:a67fc999dd68 | 392 | field->~NuBrickField(); |
shliu1 | 0:a67fc999dd68 | 393 | } |
shliu1 | 0:a67fc999dd68 | 394 | |
shliu1 | 0:a67fc999dd68 | 395 | ::operator delete((void *) report_fields); |
shliu1 | 0:a67fc999dd68 | 396 | report_fields = NULL; |
shliu1 | 0:a67fc999dd68 | 397 | num_report_fields = 0; |
shliu1 | 0:a67fc999dd68 | 398 | } |
shliu1 | 0:a67fc999dd68 | 399 | |
shliu1 | 0:a67fc999dd68 | 400 | bool NuBrickMaster::unserialize_device_desc(void) { |
shliu1 | 0:a67fc999dd68 | 401 | |
shliu1 | 0:a67fc999dd68 | 402 | // Device descriptor length |
shliu1 | 0:a67fc999dd68 | 403 | _dev_desc.dev_desc_len = get16_le_next(); |
shliu1 | 0:a67fc999dd68 | 404 | |
shliu1 | 0:a67fc999dd68 | 405 | // Report descriptor length |
shliu1 | 0:a67fc999dd68 | 406 | _dev_desc.report_desc_len = get16_le_next(); |
shliu1 | 0:a67fc999dd68 | 407 | |
shliu1 | 0:a67fc999dd68 | 408 | // Input report length |
shliu1 | 0:a67fc999dd68 | 409 | _dev_desc.input_report_len = get16_le_next(); |
shliu1 | 0:a67fc999dd68 | 410 | |
shliu1 | 0:a67fc999dd68 | 411 | // Output report length |
shliu1 | 0:a67fc999dd68 | 412 | _dev_desc.output_report_len = get16_le_next(); |
shliu1 | 0:a67fc999dd68 | 413 | |
shliu1 | 0:a67fc999dd68 | 414 | // Get feature report length |
shliu1 | 0:a67fc999dd68 | 415 | _dev_desc.getfeat_report_len = get16_le_next(); |
shliu1 | 0:a67fc999dd68 | 416 | |
shliu1 | 0:a67fc999dd68 | 417 | // Set feature report length |
shliu1 | 0:a67fc999dd68 | 418 | _dev_desc.setfeat_report_len = get16_le_next(); |
shliu1 | 0:a67fc999dd68 | 419 | |
shliu1 | 0:a67fc999dd68 | 420 | // CID |
shliu1 | 0:a67fc999dd68 | 421 | _dev_desc.cid = get16_le_next(); |
shliu1 | 0:a67fc999dd68 | 422 | |
shliu1 | 0:a67fc999dd68 | 423 | // DID |
shliu1 | 0:a67fc999dd68 | 424 | _dev_desc.did = get16_le_next(); |
shliu1 | 0:a67fc999dd68 | 425 | |
shliu1 | 0:a67fc999dd68 | 426 | // PID |
shliu1 | 0:a67fc999dd68 | 427 | _dev_desc.pid = get16_le_next(); |
shliu1 | 0:a67fc999dd68 | 428 | |
shliu1 | 0:a67fc999dd68 | 429 | // UID |
shliu1 | 0:a67fc999dd68 | 430 | _dev_desc.uid = get16_le_next(); |
shliu1 | 0:a67fc999dd68 | 431 | |
shliu1 | 0:a67fc999dd68 | 432 | // UCID |
shliu1 | 0:a67fc999dd68 | 433 | _dev_desc.ucid = get16_le_next(); |
shliu1 | 0:a67fc999dd68 | 434 | |
shliu1 | 0:a67fc999dd68 | 435 | // Reserved 1 |
shliu1 | 0:a67fc999dd68 | 436 | _dev_desc.reserved1 = get16_le_next(); |
shliu1 | 0:a67fc999dd68 | 437 | |
shliu1 | 0:a67fc999dd68 | 438 | // Reserved 2 |
shliu1 | 0:a67fc999dd68 | 439 | _dev_desc.reserved2 = get16_le_next(); |
shliu1 | 0:a67fc999dd68 | 440 | |
shliu1 | 0:a67fc999dd68 | 441 | if (_dev_desc.dev_desc_len != NuBrick_DeviceDesc_Len) { |
shliu1 | 0:a67fc999dd68 | 442 | NUBRICK_ERROR_RETURN_FALSE("Length of device descriptor doesn't match\r\n"); |
shliu1 | 0:a67fc999dd68 | 443 | } |
shliu1 | 0:a67fc999dd68 | 444 | |
shliu1 | 0:a67fc999dd68 | 445 | return true; |
shliu1 | 0:a67fc999dd68 | 446 | } |
shliu1 | 0:a67fc999dd68 | 447 | |
shliu1 | 0:a67fc999dd68 | 448 | |
shliu1 | 0:a67fc999dd68 | 449 | bool NuBrickMaster::unserialize_report_desc(void) { |
shliu1 | 0:a67fc999dd68 | 450 | |
shliu1 | 0:a67fc999dd68 | 451 | // Report descriptor length |
shliu1 | 0:a67fc999dd68 | 452 | uint16_t report_desc_len = get16_le_next(); |
shliu1 | 0:a67fc999dd68 | 453 | if (report_desc_len != _dev_desc.report_desc_len) { |
shliu1 | 0:a67fc999dd68 | 454 | NUBRICK_ERROR_RETURN_FALSE("Length of report descriptor doesn't match\r\n"); |
shliu1 | 0:a67fc999dd68 | 455 | } |
shliu1 | 0:a67fc999dd68 | 456 | |
shliu1 | 0:a67fc999dd68 | 457 | uint16_t desc_type; |
shliu1 | 0:a67fc999dd68 | 458 | NuBrickField *field = NULL; |
shliu1 | 0:a67fc999dd68 | 459 | NuBrickField *field_end = NULL; |
shliu1 | 0:a67fc999dd68 | 460 | |
shliu1 | 0:a67fc999dd68 | 461 | // Check no feature report descriptor |
shliu1 | 0:a67fc999dd68 | 462 | if (! _num_feature_report_fields) { |
shliu1 | 0:a67fc999dd68 | 463 | return true; |
shliu1 | 0:a67fc999dd68 | 464 | } |
shliu1 | 0:a67fc999dd68 | 465 | |
shliu1 | 0:a67fc999dd68 | 466 | // Feature report descriptor type |
shliu1 | 0:a67fc999dd68 | 467 | desc_type = get16_be_next(); |
shliu1 | 0:a67fc999dd68 | 468 | if (desc_type != NuBrick_DescType_FeatureReport) { |
shliu1 | 0:a67fc999dd68 | 469 | NUBRICK_ERROR_RETURN_FALSE("Expect feature report descriptor type %d, but %d received\r\n", NuBrick_DescType_FeatureReport, desc_type); |
shliu1 | 0:a67fc999dd68 | 470 | } |
shliu1 | 0:a67fc999dd68 | 471 | |
shliu1 | 0:a67fc999dd68 | 472 | // Un-serialize feature report fields from report descriptor |
shliu1 | 0:a67fc999dd68 | 473 | field = _feature_report_fields; |
shliu1 | 0:a67fc999dd68 | 474 | field_end = _feature_report_fields + _num_feature_report_fields; |
shliu1 | 0:a67fc999dd68 | 475 | for (; field != field_end; field ++) { |
shliu1 | 0:a67fc999dd68 | 476 | if (! unserialize_field_from_report_desc(field)) { |
shliu1 | 0:a67fc999dd68 | 477 | NUBRICK_ERROR_RETURN_FALSE("unserialize_field_from_report_desc() failed\r\n"); |
shliu1 | 0:a67fc999dd68 | 478 | } |
shliu1 | 0:a67fc999dd68 | 479 | } |
shliu1 | 0:a67fc999dd68 | 480 | |
shliu1 | 0:a67fc999dd68 | 481 | // Check no input report descriptor |
shliu1 | 0:a67fc999dd68 | 482 | if (! _num_input_report_fields) { |
shliu1 | 0:a67fc999dd68 | 483 | return true; |
shliu1 | 0:a67fc999dd68 | 484 | } |
shliu1 | 0:a67fc999dd68 | 485 | |
shliu1 | 0:a67fc999dd68 | 486 | // Input report descriptor type |
shliu1 | 0:a67fc999dd68 | 487 | desc_type = get16_be_next(); |
shliu1 | 0:a67fc999dd68 | 488 | if (desc_type != NuBrick_DescType_InputReport) { |
shliu1 | 0:a67fc999dd68 | 489 | NUBRICK_ERROR_RETURN_FALSE("Expect input report descriptor type %d, but %d received\r\n", NuBrick_DescType_InputReport, desc_type); |
shliu1 | 0:a67fc999dd68 | 490 | } |
shliu1 | 0:a67fc999dd68 | 491 | |
shliu1 | 0:a67fc999dd68 | 492 | // Un-serialize input report fields from report descriptor |
shliu1 | 0:a67fc999dd68 | 493 | field = _input_report_fields; |
shliu1 | 0:a67fc999dd68 | 494 | field_end = _input_report_fields + _num_input_report_fields; |
shliu1 | 0:a67fc999dd68 | 495 | for (; field != field_end; field ++) { |
shliu1 | 0:a67fc999dd68 | 496 | if (! unserialize_field_from_report_desc(field)) { |
shliu1 | 0:a67fc999dd68 | 497 | NUBRICK_ERROR_RETURN_FALSE("unserialize_field_from_report_desc() failed\r\n"); |
shliu1 | 0:a67fc999dd68 | 498 | } |
shliu1 | 0:a67fc999dd68 | 499 | } |
shliu1 | 0:a67fc999dd68 | 500 | |
shliu1 | 0:a67fc999dd68 | 501 | // Check no output report descriptor |
shliu1 | 0:a67fc999dd68 | 502 | if (! _num_output_report_fields) { |
shliu1 | 0:a67fc999dd68 | 503 | return true; |
shliu1 | 0:a67fc999dd68 | 504 | } |
shliu1 | 0:a67fc999dd68 | 505 | |
shliu1 | 0:a67fc999dd68 | 506 | // Output report descriptor type |
shliu1 | 0:a67fc999dd68 | 507 | desc_type = get16_be_next(); |
shliu1 | 0:a67fc999dd68 | 508 | if (desc_type != NuBrick_DescType_OutputReport) { |
shliu1 | 0:a67fc999dd68 | 509 | NUBRICK_ERROR_RETURN_FALSE("Expect output report descriptor type %d, but %d received\r\n", NuBrick_DescType_OutputReport, desc_type); |
shliu1 | 0:a67fc999dd68 | 510 | } |
shliu1 | 0:a67fc999dd68 | 511 | |
shliu1 | 0:a67fc999dd68 | 512 | // Un-serialize output report fields from report descriptor |
shliu1 | 0:a67fc999dd68 | 513 | field = _output_report_fields; |
shliu1 | 0:a67fc999dd68 | 514 | field_end = _output_report_fields + _num_output_report_fields; |
shliu1 | 0:a67fc999dd68 | 515 | for (; field != field_end; field ++) { |
shliu1 | 0:a67fc999dd68 | 516 | if (! unserialize_field_from_report_desc(field)) { |
shliu1 | 0:a67fc999dd68 | 517 | NUBRICK_ERROR_RETURN_FALSE("unserialize_field_from_report_desc() failed\r\n"); |
shliu1 | 0:a67fc999dd68 | 518 | } |
shliu1 | 0:a67fc999dd68 | 519 | } |
shliu1 | 0:a67fc999dd68 | 520 | |
shliu1 | 0:a67fc999dd68 | 521 | return true; |
shliu1 | 0:a67fc999dd68 | 522 | } |
shliu1 | 0:a67fc999dd68 | 523 | |
shliu1 | 0:a67fc999dd68 | 524 | bool NuBrickMaster::unserialize_input_report(void) { |
shliu1 | 0:a67fc999dd68 | 525 | |
shliu1 | 0:a67fc999dd68 | 526 | // Input report length |
shliu1 | 0:a67fc999dd68 | 527 | uint16_t report_len = get16_le_next(); |
shliu1 | 0:a67fc999dd68 | 528 | if (report_len != _dev_desc.input_report_len) { |
shliu1 | 0:a67fc999dd68 | 529 | NUBRICK_ERROR_RETURN_FALSE("Length of input report doesn't match\r\n"); |
shliu1 | 0:a67fc999dd68 | 530 | } |
shliu1 | 0:a67fc999dd68 | 531 | |
shliu1 | 0:a67fc999dd68 | 532 | // Un-serialize fields from input report |
shliu1 | 0:a67fc999dd68 | 533 | NuBrickField *field = _input_report_fields; |
shliu1 | 0:a67fc999dd68 | 534 | NuBrickField *field_end = _input_report_fields + _num_input_report_fields; |
shliu1 | 0:a67fc999dd68 | 535 | for (; field != field_end; field ++) { |
shliu1 | 0:a67fc999dd68 | 536 | if (! unserialize_field_from_report(field)) { |
shliu1 | 0:a67fc999dd68 | 537 | NUBRICK_ERROR_RETURN_FALSE("unserialize_field_from_report() failed\r\n"); |
shliu1 | 0:a67fc999dd68 | 538 | } |
shliu1 | 0:a67fc999dd68 | 539 | } |
shliu1 | 0:a67fc999dd68 | 540 | |
shliu1 | 0:a67fc999dd68 | 541 | return true; |
shliu1 | 0:a67fc999dd68 | 542 | } |
shliu1 | 0:a67fc999dd68 | 543 | |
shliu1 | 0:a67fc999dd68 | 544 | bool NuBrickMaster::serialize_output_report(void) { |
shliu1 | 0:a67fc999dd68 | 545 | |
shliu1 | 0:a67fc999dd68 | 546 | uint8_t *i2c_buf_beg = _i2c_buf_pos; |
shliu1 | 0:a67fc999dd68 | 547 | |
shliu1 | 0:a67fc999dd68 | 548 | // Output report length |
shliu1 | 0:a67fc999dd68 | 549 | set16_le_next(_dev_desc.output_report_len); |
shliu1 | 0:a67fc999dd68 | 550 | |
shliu1 | 0:a67fc999dd68 | 551 | // Serialize fields to output report |
shliu1 | 0:a67fc999dd68 | 552 | NuBrickField *field = _output_report_fields; |
shliu1 | 0:a67fc999dd68 | 553 | NuBrickField *field_end = _output_report_fields + _num_output_report_fields; |
shliu1 | 0:a67fc999dd68 | 554 | for (; field != field_end; field ++) { |
shliu1 | 0:a67fc999dd68 | 555 | if (! serialize_field_to_report(field)) { |
shliu1 | 0:a67fc999dd68 | 556 | NUBRICK_ERROR_RETURN_FALSE("serialize_field_to_report() failed\r\n"); |
shliu1 | 0:a67fc999dd68 | 557 | } |
shliu1 | 0:a67fc999dd68 | 558 | } |
shliu1 | 0:a67fc999dd68 | 559 | |
shliu1 | 0:a67fc999dd68 | 560 | if ((_i2c_buf_pos - i2c_buf_beg) != _dev_desc.output_report_len) { |
shliu1 | 0:a67fc999dd68 | 561 | NUBRICK_ERROR_RETURN_FALSE("Length of output report doesn't match\r\n"); |
shliu1 | 0:a67fc999dd68 | 562 | } |
shliu1 | 0:a67fc999dd68 | 563 | |
shliu1 | 0:a67fc999dd68 | 564 | return true; |
shliu1 | 0:a67fc999dd68 | 565 | } |
shliu1 | 0:a67fc999dd68 | 566 | |
shliu1 | 0:a67fc999dd68 | 567 | bool NuBrickMaster::unserialize_feature_report(void) { |
shliu1 | 0:a67fc999dd68 | 568 | |
shliu1 | 0:a67fc999dd68 | 569 | // Feature report length |
shliu1 | 0:a67fc999dd68 | 570 | uint16_t report_len = get16_le_next(); |
shliu1 | 0:a67fc999dd68 | 571 | if (report_len != _dev_desc.getfeat_report_len) { |
shliu1 | 0:a67fc999dd68 | 572 | NUBRICK_ERROR_RETURN_FALSE("Length of feature report doesn't match\r\n"); |
shliu1 | 0:a67fc999dd68 | 573 | } |
shliu1 | 0:a67fc999dd68 | 574 | |
shliu1 | 0:a67fc999dd68 | 575 | // Un-serialize fields from feature report |
shliu1 | 0:a67fc999dd68 | 576 | NuBrickField *field = _feature_report_fields; |
shliu1 | 0:a67fc999dd68 | 577 | NuBrickField *field_end = _feature_report_fields + _num_feature_report_fields; |
shliu1 | 0:a67fc999dd68 | 578 | for (; field != field_end; field ++) { |
shliu1 | 0:a67fc999dd68 | 579 | if (! unserialize_field_from_report(field)) { |
shliu1 | 0:a67fc999dd68 | 580 | NUBRICK_ERROR_RETURN_FALSE("unserialize_field_from_report() failed\r\n"); |
shliu1 | 0:a67fc999dd68 | 581 | } |
shliu1 | 0:a67fc999dd68 | 582 | } |
shliu1 | 0:a67fc999dd68 | 583 | |
shliu1 | 0:a67fc999dd68 | 584 | return true; |
shliu1 | 0:a67fc999dd68 | 585 | } |
shliu1 | 0:a67fc999dd68 | 586 | |
shliu1 | 0:a67fc999dd68 | 587 | bool NuBrickMaster::serialize_feature_report(void) { |
shliu1 | 0:a67fc999dd68 | 588 | |
shliu1 | 0:a67fc999dd68 | 589 | uint8_t *i2c_buf_beg = _i2c_buf_pos; |
shliu1 | 0:a67fc999dd68 | 590 | |
shliu1 | 0:a67fc999dd68 | 591 | // Feature report length |
shliu1 | 0:a67fc999dd68 | 592 | set16_le_next(_dev_desc.setfeat_report_len); |
shliu1 | 0:a67fc999dd68 | 593 | |
shliu1 | 0:a67fc999dd68 | 594 | // Serialize fields to feature report |
shliu1 | 0:a67fc999dd68 | 595 | NuBrickField *field = _feature_report_fields; |
shliu1 | 0:a67fc999dd68 | 596 | NuBrickField *field_end = _feature_report_fields + _num_feature_report_fields; |
shliu1 | 0:a67fc999dd68 | 597 | for (; field != field_end; field ++) { |
shliu1 | 0:a67fc999dd68 | 598 | if (! serialize_field_to_report(field)) { |
shliu1 | 0:a67fc999dd68 | 599 | NUBRICK_ERROR_RETURN_FALSE("serialize_field_to_report() failed\r\n"); |
shliu1 | 0:a67fc999dd68 | 600 | } |
shliu1 | 0:a67fc999dd68 | 601 | } |
shliu1 | 0:a67fc999dd68 | 602 | |
shliu1 | 0:a67fc999dd68 | 603 | if ((_i2c_buf_pos - i2c_buf_beg) != _dev_desc.setfeat_report_len) { |
shliu1 | 0:a67fc999dd68 | 604 | NUBRICK_ERROR_RETURN_FALSE("Length of set feature report doesn't match\r\n"); |
shliu1 | 0:a67fc999dd68 | 605 | } |
shliu1 | 0:a67fc999dd68 | 606 | |
shliu1 | 0:a67fc999dd68 | 607 | return true; |
shliu1 | 0:a67fc999dd68 | 608 | } |
shliu1 | 0:a67fc999dd68 | 609 | |
shliu1 | 0:a67fc999dd68 | 610 | bool NuBrickMaster::unserialize_field_from_report_desc(NuBrickField *field) { |
shliu1 | 0:a67fc999dd68 | 611 | // Number/length of the field |
shliu1 | 0:a67fc999dd68 | 612 | uint8_t field_index = get8_next(); |
shliu1 | 0:a67fc999dd68 | 613 | if (field_index != field->_field_index) { |
shliu1 | 0:a67fc999dd68 | 614 | NUBRICK_ERROR_RETURN_FALSE("Expect field index %d, but %d received\r\n", field->_field_index, field_index); |
shliu1 | 0:a67fc999dd68 | 615 | } |
shliu1 | 0:a67fc999dd68 | 616 | |
shliu1 | 0:a67fc999dd68 | 617 | // Length of the field |
shliu1 | 0:a67fc999dd68 | 618 | field->_length = get8_next(); |
shliu1 | 0:a67fc999dd68 | 619 | if (field->_length != 1 && field->_length != 2) { |
shliu1 | 0:a67fc999dd68 | 620 | NUBRICK_ERROR_RETURN_FALSE("Expect field length 1/2, but %d received\r\n", field->_length); |
shliu1 | 0:a67fc999dd68 | 621 | } |
shliu1 | 0:a67fc999dd68 | 622 | |
shliu1 | 0:a67fc999dd68 | 623 | // Minimum of the field |
shliu1 | 0:a67fc999dd68 | 624 | uint8_t min = get8_next(); |
shliu1 | 0:a67fc999dd68 | 625 | switch (min) { |
shliu1 | 0:a67fc999dd68 | 626 | case NuBrick_ReportDesc_Min_Plus1: |
shliu1 | 0:a67fc999dd68 | 627 | field->_minimum = get8_next(); |
shliu1 | 0:a67fc999dd68 | 628 | break; |
shliu1 | 0:a67fc999dd68 | 629 | |
shliu1 | 0:a67fc999dd68 | 630 | case NuBrick_ReportDesc_Min_Plus2: |
shliu1 | 0:a67fc999dd68 | 631 | field->_minimum = get16_le_next(); |
shliu1 | 0:a67fc999dd68 | 632 | break; |
shliu1 | 0:a67fc999dd68 | 633 | |
shliu1 | 0:a67fc999dd68 | 634 | default: |
shliu1 | 0:a67fc999dd68 | 635 | NUBRICK_ERROR_RETURN_FALSE("Expect field minimum %d/%d, but %d received\r\n", NuBrick_ReportDesc_Min_Plus1, NuBrick_ReportDesc_Min_Plus2, min); |
shliu1 | 0:a67fc999dd68 | 636 | } |
shliu1 | 0:a67fc999dd68 | 637 | |
shliu1 | 0:a67fc999dd68 | 638 | // Maximum of the field |
shliu1 | 0:a67fc999dd68 | 639 | uint8_t max = get8_next(); |
shliu1 | 0:a67fc999dd68 | 640 | switch (max) { |
shliu1 | 0:a67fc999dd68 | 641 | case NuBrick_ReportDesc_Max_Plus1: |
shliu1 | 0:a67fc999dd68 | 642 | field->_maximum = get8_next(); |
shliu1 | 0:a67fc999dd68 | 643 | break; |
shliu1 | 0:a67fc999dd68 | 644 | |
shliu1 | 0:a67fc999dd68 | 645 | case NuBrick_ReportDesc_Max_Plus2: |
shliu1 | 0:a67fc999dd68 | 646 | field->_maximum = get16_le_next(); |
shliu1 | 0:a67fc999dd68 | 647 | break; |
shliu1 | 0:a67fc999dd68 | 648 | |
shliu1 | 0:a67fc999dd68 | 649 | default: |
shliu1 | 0:a67fc999dd68 | 650 | NUBRICK_ERROR_RETURN_FALSE("Expect field maximum %d/%d, but %d received\r\n", NuBrick_ReportDesc_Max_Plus1, NuBrick_ReportDesc_Max_Plus2, max); |
shliu1 | 0:a67fc999dd68 | 651 | } |
shliu1 | 0:a67fc999dd68 | 652 | |
shliu1 | 0:a67fc999dd68 | 653 | return true; |
shliu1 | 0:a67fc999dd68 | 654 | } |
shliu1 | 0:a67fc999dd68 | 655 | |
shliu1 | 0:a67fc999dd68 | 656 | bool NuBrickMaster::unserialize_field_from_report(NuBrickField *field) { |
shliu1 | 0:a67fc999dd68 | 657 | // Value of the field |
shliu1 | 0:a67fc999dd68 | 658 | switch (field->_length) { |
shliu1 | 0:a67fc999dd68 | 659 | case 1: |
shliu1 | 0:a67fc999dd68 | 660 | field->_value = get8_next(); |
shliu1 | 0:a67fc999dd68 | 661 | break; |
shliu1 | 0:a67fc999dd68 | 662 | |
shliu1 | 0:a67fc999dd68 | 663 | case 2: |
shliu1 | 0:a67fc999dd68 | 664 | field->_value = get16_le_next(); |
shliu1 | 0:a67fc999dd68 | 665 | break; |
shliu1 | 0:a67fc999dd68 | 666 | |
shliu1 | 0:a67fc999dd68 | 667 | default: |
shliu1 | 0:a67fc999dd68 | 668 | NUBRICK_ERROR_RETURN_FALSE("Expect field length 1/2, but %d received\r\n", field->_length); |
shliu1 | 0:a67fc999dd68 | 669 | } |
shliu1 | 0:a67fc999dd68 | 670 | |
shliu1 | 0:a67fc999dd68 | 671 | return true; |
shliu1 | 0:a67fc999dd68 | 672 | } |
shliu1 | 0:a67fc999dd68 | 673 | |
shliu1 | 0:a67fc999dd68 | 674 | bool NuBrickMaster::serialize_field_to_report(const NuBrickField *field) { |
shliu1 | 0:a67fc999dd68 | 675 | // Value of the field |
shliu1 | 0:a67fc999dd68 | 676 | switch (field->_length) { |
shliu1 | 0:a67fc999dd68 | 677 | case 1: |
shliu1 | 0:a67fc999dd68 | 678 | set8_next(field->_value); |
shliu1 | 0:a67fc999dd68 | 679 | break; |
shliu1 | 0:a67fc999dd68 | 680 | |
shliu1 | 0:a67fc999dd68 | 681 | case 2: |
shliu1 | 0:a67fc999dd68 | 682 | set16_le_next(field->_value); |
shliu1 | 0:a67fc999dd68 | 683 | break; |
shliu1 | 0:a67fc999dd68 | 684 | |
shliu1 | 0:a67fc999dd68 | 685 | default: |
shliu1 | 0:a67fc999dd68 | 686 | NUBRICK_ERROR_RETURN_FALSE("Expect field length 1/2, but %d received\r\n", field->_length); |
shliu1 | 0:a67fc999dd68 | 687 | } |
shliu1 | 0:a67fc999dd68 | 688 | |
shliu1 | 0:a67fc999dd68 | 689 | return true; |
shliu1 | 0:a67fc999dd68 | 690 | } |
shliu1 | 0:a67fc999dd68 | 691 | |
shliu1 | 0:a67fc999dd68 | 692 | uint8_t NuBrickMaster::get8_next(void) { |
shliu1 | 0:a67fc999dd68 | 693 | NUBRICK_CHECK_GETN_NEXT(1); |
shliu1 | 0:a67fc999dd68 | 694 | |
shliu1 | 0:a67fc999dd68 | 695 | uint8_t val = *_i2c_buf_pos ++; |
shliu1 | 0:a67fc999dd68 | 696 | return val; |
shliu1 | 0:a67fc999dd68 | 697 | } |
shliu1 | 0:a67fc999dd68 | 698 | |
shliu1 | 0:a67fc999dd68 | 699 | void NuBrickMaster::set8_next(uint8_t val) { |
shliu1 | 0:a67fc999dd68 | 700 | NUBRICK_CHECK_SETN_NEXT(1); |
shliu1 | 0:a67fc999dd68 | 701 | |
shliu1 | 0:a67fc999dd68 | 702 | *_i2c_buf_pos ++ = val; |
shliu1 | 0:a67fc999dd68 | 703 | } |
shliu1 | 0:a67fc999dd68 | 704 | |
shliu1 | 0:a67fc999dd68 | 705 | uint16_t NuBrickMaster::get16_le_next(void) { |
shliu1 | 0:a67fc999dd68 | 706 | NUBRICK_CHECK_GETN_NEXT(2); |
shliu1 | 0:a67fc999dd68 | 707 | |
shliu1 | 0:a67fc999dd68 | 708 | uint16_t val = nu_get16_le(_i2c_buf_pos); |
shliu1 | 0:a67fc999dd68 | 709 | _i2c_buf_pos += 2; |
shliu1 | 0:a67fc999dd68 | 710 | return val; |
shliu1 | 0:a67fc999dd68 | 711 | } |
shliu1 | 0:a67fc999dd68 | 712 | |
shliu1 | 0:a67fc999dd68 | 713 | void NuBrickMaster::set16_le_next(uint16_t val) { |
shliu1 | 0:a67fc999dd68 | 714 | NUBRICK_CHECK_SETN_NEXT(2); |
shliu1 | 0:a67fc999dd68 | 715 | |
shliu1 | 0:a67fc999dd68 | 716 | nu_set16_le(_i2c_buf_pos, val); |
shliu1 | 0:a67fc999dd68 | 717 | _i2c_buf_pos += 2; |
shliu1 | 0:a67fc999dd68 | 718 | } |
shliu1 | 0:a67fc999dd68 | 719 | |
shliu1 | 0:a67fc999dd68 | 720 | uint16_t NuBrickMaster::get16_be_next(void) { |
shliu1 | 0:a67fc999dd68 | 721 | NUBRICK_CHECK_GETN_NEXT(2); |
shliu1 | 0:a67fc999dd68 | 722 | |
shliu1 | 0:a67fc999dd68 | 723 | uint16_t val = nu_get16_be(_i2c_buf_pos); |
shliu1 | 0:a67fc999dd68 | 724 | _i2c_buf_pos += 2; |
shliu1 | 0:a67fc999dd68 | 725 | return val; |
shliu1 | 0:a67fc999dd68 | 726 | } |
shliu1 | 0:a67fc999dd68 | 727 | |
shliu1 | 0:a67fc999dd68 | 728 | void NuBrickMaster::print_report(NuBrickField *fields, unsigned num_fields, const char *report_name) { |
shliu1 | 0:a67fc999dd68 | 729 | |
shliu1 | 0:a67fc999dd68 | 730 | printf("Number of fields of %s\t%d\r\n", report_name, num_fields); |
shliu1 | 0:a67fc999dd68 | 731 | |
shliu1 | 0:a67fc999dd68 | 732 | unsigned i; |
shliu1 | 0:a67fc999dd68 | 733 | for (i = 0; i < num_fields; i ++) { |
shliu1 | 0:a67fc999dd68 | 734 | NuBrickField *field = fields + i; |
shliu1 | 0:a67fc999dd68 | 735 | |
shliu1 | 0:a67fc999dd68 | 736 | printf("Name\t\t%s\r\n", field->_name); |
shliu1 | 0:a67fc999dd68 | 737 | printf("Length\t\t%d\r\n", field->_length); |
shliu1 | 0:a67fc999dd68 | 738 | printf("Value\t\t%d\r\n", field->_value); |
shliu1 | 0:a67fc999dd68 | 739 | printf("Minimum\t\t%d\r\n", field->_minimum); |
shliu1 | 0:a67fc999dd68 | 740 | printf("Maximum\t\t%d\r\n", field->_maximum); |
shliu1 | 0:a67fc999dd68 | 741 | printf("\r\n"); |
shliu1 | 0:a67fc999dd68 | 742 | } |
shliu1 | 0:a67fc999dd68 | 743 | } |