DevI2C wrappers for Javascript.
Dependents: ST_SENSOR_JS MQTT_JS
DevI2C-js.cpp
00001 /** 00002 ****************************************************************************** 00003 * @file DevI2C-js.cpp 00004 * @author ST 00005 * @version V1.0.0 00006 * @date 25 October 2017 00007 * @brief Implementation of DevI2C for Javascript. 00008 ****************************************************************************** 00009 * @attention 00010 * 00011 * <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2> 00012 * 00013 * Redistribution and use in source and binary forms, with or without modification, 00014 * are permitted provided that the following conditions are met: 00015 * 1. Redistributions of source code must retain the above copyright notice, 00016 * this list of conditions and the following disclaimer. 00017 * 2. Redistributions in binary form must reproduce the above copyright notice, 00018 * this list of conditions and the following disclaimer in the documentation 00019 * and/or other materials provided with the distribution. 00020 * 3. Neither the name of STMicroelectronics nor the names of its contributors 00021 * may be used to endorse or promote products derived from this software 00022 * without specific prior written permission. 00023 * 00024 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00025 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00026 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00027 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 00028 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00029 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00030 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00031 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00032 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00033 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00034 * 00035 ****************************************************************************** 00036 */ 00037 00038 00039 /* Includes ------------------------------------------------------------------*/ 00040 00041 #include "jerryscript-mbed-util/logging.h" 00042 #include "jerryscript-mbed-library-registry/wrap_tools.h" 00043 00044 // Load the library that we'll wrap 00045 #include "DevI2C.h" 00046 00047 #include "mbed.h" 00048 00049 /* Class Implementation ------------------------------------------------------*/ 00050 00051 /** 00052 * DevI2C#destructor 00053 * @brief Called if/when the DevI2C object is GC'ed. 00054 */ 00055 void NAME_FOR_CLASS_NATIVE_DESTRUCTOR(DevI2C) (void *void_ptr) { 00056 delete static_cast<DevI2C*>(void_ptr); 00057 } 00058 00059 /** 00060 * Type infomation of the native DevI2C pointer 00061 * @brief Set DevI2C#destructor as the free callback. 00062 */ 00063 static const jerry_object_native_info_t native_obj_type_info = { 00064 .free_cb = NAME_FOR_CLASS_NATIVE_DESTRUCTOR(DevI2C) 00065 }; 00066 00067 /** 00068 * DevI2C#frequency (native JavaScript method) 00069 * @brief Set the frequency of the DevI2C bus. 00070 * 00071 * @param frequency New DevI2C Frequency 00072 */ 00073 DECLARE_CLASS_FUNCTION(DevI2C, frequency) { 00074 CHECK_ARGUMENT_COUNT(DevI2C, frequency, (args_count == 1)); 00075 CHECK_ARGUMENT_TYPE_ALWAYS(DevI2C, frequency, 0, number); 00076 00077 // Unwrap native DevI2C object 00078 void *void_ptr; 00079 const jerry_object_native_info_t *type_ptr; 00080 bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &type_ptr); 00081 00082 if (!has_ptr || type_ptr != &native_obj_type_info) { 00083 return jerry_create_error(JERRY_ERROR_TYPE, 00084 (const jerry_char_t *) "Failed to get native DevI2C pointer"); 00085 } 00086 00087 I2C *native_ptr = static_cast<I2C*>(void_ptr); 00088 00089 int hz = jerry_get_number_value(args[0]); 00090 native_ptr->frequency(hz); 00091 00092 return jerry_create_undefined(); 00093 } 00094 00095 /** 00096 * DevI2C#read (native JavaScript method) 00097 * @brief Read data from the DevI2C bus. 00098 * 00099 * @overload DevI2C#read(int) 00100 * Read a single byte from the DevI2C bus 00101 * 00102 * @param ack indicates if the byte is to be acknowledged (1 => acknowledge) 00103 * 00104 * @returns array: Data read from the DevI2C bus 00105 * 00106 * @overload DevI2C#read(int, array, int) 00107 * Read a series of bytes from the DevI2C bus 00108 * 00109 * @param address DevI2C address to read from 00110 * @param data Array to read into 00111 * @param length Length of data to read 00112 * 00113 * @returns array: Data read from the DevI2C bus 00114 */ 00115 DECLARE_CLASS_FUNCTION(DevI2C, read) { 00116 CHECK_ARGUMENT_COUNT(DevI2C, read, (args_count == 1 || args_count == 3 || args_count == 4)); 00117 00118 if (args_count == 1) { 00119 CHECK_ARGUMENT_TYPE_ALWAYS(DevI2C, read, 0, number); 00120 void *void_ptr; 00121 const jerry_object_native_info_t *type_ptr; 00122 bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &type_ptr); 00123 00124 if (!has_ptr || type_ptr != &native_obj_type_info) { 00125 return jerry_create_error(JERRY_ERROR_TYPE, 00126 (const jerry_char_t *) "Failed to get native DevI2C pointer"); 00127 } 00128 00129 I2C *native_ptr = static_cast<I2C*>(void_ptr); 00130 00131 int data = jerry_get_number_value(args[0]); 00132 int result = native_ptr->read(data); 00133 00134 return jerry_create_number(result); 00135 } else { 00136 CHECK_ARGUMENT_TYPE_ALWAYS(DevI2C, read, 0, number); 00137 CHECK_ARGUMENT_TYPE_ALWAYS(DevI2C, read, 1, array); 00138 CHECK_ARGUMENT_TYPE_ALWAYS(DevI2C, read, 2, number); 00139 00140 CHECK_ARGUMENT_TYPE_ON_CONDITION(DevI2C, read, 3, boolean, (args_count == 4)); 00141 00142 void *void_ptr; 00143 const jerry_object_native_info_t *type_ptr; 00144 bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &type_ptr); 00145 00146 if (!has_ptr || type_ptr != &native_obj_type_info) { 00147 return jerry_create_error(JERRY_ERROR_TYPE, 00148 (const jerry_char_t *) "Failed to get native DevI2C pointer"); 00149 } 00150 00151 I2C *native_ptr = static_cast<I2C*>(void_ptr); 00152 00153 const uint32_t data_len = jerry_get_array_length(args[1]); 00154 00155 int address = jerry_get_number_value(args[0]); 00156 int length = jerry_get_number_value(args[2]); 00157 00158 char *data = new char[data_len]; 00159 00160 bool repeated = false; 00161 if (args_count == 4) { 00162 repeated = jerry_get_boolean_value(args[3]); 00163 } 00164 00165 int result = native_ptr->read(address, data, length, repeated); 00166 00167 jerry_value_t out_array = jerry_create_array(data_len); 00168 00169 for (uint32_t i = 0; i < data_len; i++) { 00170 jerry_value_t val = jerry_create_number(double(data[i])); 00171 jerry_set_property_by_index(out_array, i, val); 00172 jerry_release_value(val); 00173 } 00174 00175 delete[] data; 00176 00177 if (result == 0) { 00178 // ACK 00179 return out_array; 00180 } else { 00181 // NACK 00182 const char *error_msg = "NACK received from DevI2C bus"; 00183 00184 jerry_release_value(out_array); 00185 return jerry_create_error(JERRY_ERROR_COMMON, reinterpret_cast<const jerry_char_t *>(error_msg)); 00186 } 00187 } 00188 } 00189 00190 /** 00191 * DevI2C#write (native JavaScript method) 00192 * @brief Writes to DevI2C bus 00193 * 00194 * @overload DevI2C#write(int) 00195 * Write a single byte to the DevI2C bus 00196 * 00197 * @param data Data byte to write to the DevI2C bus 00198 * 00199 * @returns 1 on success, 0 on failure 00200 * 00201 * @overload DevI2C#write(int, array, int, bool) 00202 * Write an array of data to a certain address on the DevI2C bus 00203 * 00204 * @param address 8-bit DevI2C slave address 00205 * @param data Array of bytes to send 00206 * @param length Length of data to write 00207 * @param repeated (optional) If true, do not send stop at end. 00208 * 00209 * @returns 0 on success, non-0 on failure 00210 */ 00211 DECLARE_CLASS_FUNCTION(DevI2C, write) { 00212 CHECK_ARGUMENT_COUNT(DevI2C, write, (args_count == 1 || args_count == 3 || args_count == 4)); 00213 00214 if (args_count == 1) { 00215 CHECK_ARGUMENT_TYPE_ALWAYS(DevI2C, write, 0, number); 00216 00217 // Extract native DevI2C object 00218 void *void_ptr; 00219 const jerry_object_native_info_t *type_ptr; 00220 bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &type_ptr); 00221 00222 if (!has_ptr || type_ptr != &native_obj_type_info) { 00223 return jerry_create_error(JERRY_ERROR_TYPE, 00224 (const jerry_char_t *) "Failed to get native DevI2C pointer"); 00225 } 00226 00227 I2C *native_ptr = static_cast<I2C*>(void_ptr); 00228 00229 // Unwrap arguments 00230 int data = jerry_get_number_value(args[0]); 00231 00232 int result = native_ptr->write(data); 00233 return jerry_create_number(result); 00234 } else { 00235 // 3 or 4 00236 CHECK_ARGUMENT_TYPE_ALWAYS(DevI2C, write, 0, number); 00237 CHECK_ARGUMENT_TYPE_ALWAYS(DevI2C, write, 1, array); 00238 CHECK_ARGUMENT_TYPE_ALWAYS(DevI2C, write, 2, number); 00239 CHECK_ARGUMENT_TYPE_ON_CONDITION(DevI2C, write, 3, boolean, (args_count == 4)); 00240 00241 // Extract native DevI2C object 00242 void *void_ptr; 00243 const jerry_object_native_info_t *type_ptr; 00244 bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &type_ptr); 00245 00246 if (!has_ptr || type_ptr != &native_obj_type_info) { 00247 return jerry_create_error(JERRY_ERROR_TYPE, 00248 (const jerry_char_t *) "Failed to get native DevI2C pointer"); 00249 } 00250 00251 I2C *native_ptr = static_cast<I2C*>(void_ptr); 00252 00253 // Unwrap arguments 00254 int address = jerry_get_number_value(args[0]); 00255 const uint32_t data_len = jerry_get_array_length(args[1]); 00256 int length = jerry_get_number_value(args[2]); 00257 bool repeated = args_count == 4 && jerry_get_boolean_value(args[3]); 00258 00259 // Construct data byte array 00260 char *data = new char[data_len]; 00261 for (uint32_t i = 0; i < data_len; i++) { 00262 data[i] = jerry_get_number_value(jerry_get_property_by_index(args[1], i)); 00263 } 00264 00265 int result = native_ptr->write(address, data, length, repeated); 00266 00267 // free dynamically allocated resources 00268 delete[] data; 00269 00270 return jerry_create_number(result); 00271 } 00272 } 00273 00274 /** 00275 * DevI2C#start (native JavaScript method) 00276 * @brief Creates a start condition on the DevI2C bus. 00277 */ 00278 DECLARE_CLASS_FUNCTION(DevI2C, start) { 00279 CHECK_ARGUMENT_COUNT(DevI2C, start, (args_count == 0)); 00280 00281 // Extract native DevI2C object 00282 void *void_ptr; 00283 const jerry_object_native_info_t *type_ptr; 00284 bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &type_ptr); 00285 00286 if (!has_ptr || type_ptr != &native_obj_type_info) { 00287 return jerry_create_error(JERRY_ERROR_TYPE, 00288 (const jerry_char_t *) "Failed to get native DevI2C pointer"); 00289 } 00290 00291 I2C *native_ptr = static_cast<I2C*>(void_ptr); 00292 00293 native_ptr->start(); 00294 return jerry_create_undefined(); 00295 } 00296 00297 /** 00298 * DevI2C#stop (native JavaScript method) 00299 * @brief Creates a stop condition on the DevI2C bus. 00300 */ 00301 DECLARE_CLASS_FUNCTION(DevI2C, stop) { 00302 CHECK_ARGUMENT_COUNT(DevI2C, stop, (args_count == 0)); 00303 00304 // Extract native DevI2C object 00305 void *void_ptr; 00306 const jerry_object_native_info_t *type_ptr; 00307 bool has_ptr = jerry_get_object_native_pointer(this_obj, &void_ptr, &type_ptr); 00308 00309 if (!has_ptr || type_ptr != &native_obj_type_info) { 00310 return jerry_create_error(JERRY_ERROR_TYPE, 00311 (const jerry_char_t *) "Failed to get native DevI2C pointer"); 00312 } 00313 00314 I2C *native_ptr = static_cast<I2C*>(void_ptr); 00315 00316 native_ptr->stop(); 00317 return jerry_create_undefined(); 00318 } 00319 00320 /** 00321 * DevI2C (native JavaScript constructor) 00322 * @brief Constructor 00323 * @param sda mbed pin for DevI2C data 00324 * @param scl mbed pin for DevI2C clock 00325 * @returns a JavaScript object representing the DevI2C bus. 00326 */ 00327 DECLARE_CLASS_CONSTRUCTOR(DevI2C) { 00328 CHECK_ARGUMENT_COUNT(DevI2C, __constructor, (args_count == 2)); 00329 CHECK_ARGUMENT_TYPE_ALWAYS(DevI2C, __constructor, 0, number); 00330 CHECK_ARGUMENT_TYPE_ALWAYS(DevI2C, __constructor, 1, number); 00331 00332 int sda = jerry_get_number_value(args[0]); 00333 int scl = jerry_get_number_value(args[1]); 00334 00335 DevI2C *native_ptr = new DevI2C((PinName)sda, (PinName)scl); 00336 00337 jerry_value_t js_object = jerry_create_object(); 00338 jerry_set_object_native_pointer(js_object, native_ptr, &native_obj_type_info); 00339 00340 ATTACH_CLASS_FUNCTION(js_object, DevI2C, frequency); 00341 ATTACH_CLASS_FUNCTION(js_object, DevI2C, read); 00342 ATTACH_CLASS_FUNCTION(js_object, DevI2C, write); 00343 ATTACH_CLASS_FUNCTION(js_object, DevI2C, start); 00344 ATTACH_CLASS_FUNCTION(js_object, DevI2C, stop); 00345 00346 return js_object; 00347 }
Generated on Tue Jul 12 2022 20:58:53 by 1.7.2