Modify the file main.cpp for M487

Files at this revision

API Documentation at this revision

Comitter:
shliu1
Date:
Fri Sep 29 05:44:02 2017 +0000
Commit message:
main.cpp adds the setting of TARGET_NUMAKER_PFM_M487 for M487

Changed in this revision

.gitignore Show annotated file Show diff for this revision Revisions of this file
NuMaker-mbed-NuBrick.lib Show annotated file Show diff for this revision Revisions of this file
NuMaker-mbed-NuBrick/NuBrickField.h Show annotated file Show diff for this revision Revisions of this file
NuMaker-mbed-NuBrick/NuBrickMaster.cpp Show annotated file Show diff for this revision Revisions of this file
NuMaker-mbed-NuBrick/NuBrickMaster.h Show annotated file Show diff for this revision Revisions of this file
NuMaker-mbed-NuBrick/NuBrickMasterAHRS.cpp Show annotated file Show diff for this revision Revisions of this file
NuMaker-mbed-NuBrick/NuBrickMasterAHRS.h Show annotated file Show diff for this revision Revisions of this file
NuMaker-mbed-NuBrick/NuBrickMasterBuzzer.cpp Show annotated file Show diff for this revision Revisions of this file
NuMaker-mbed-NuBrick/NuBrickMasterBuzzer.h Show annotated file Show diff for this revision Revisions of this file
NuMaker-mbed-NuBrick/NuBrickMasterGas.cpp Show annotated file Show diff for this revision Revisions of this file
NuMaker-mbed-NuBrick/NuBrickMasterGas.h Show annotated file Show diff for this revision Revisions of this file
NuMaker-mbed-NuBrick/NuBrickMasterIR.cpp Show annotated file Show diff for this revision Revisions of this file
NuMaker-mbed-NuBrick/NuBrickMasterIR.h Show annotated file Show diff for this revision Revisions of this file
NuMaker-mbed-NuBrick/NuBrickMasterKeys.cpp Show annotated file Show diff for this revision Revisions of this file
NuMaker-mbed-NuBrick/NuBrickMasterKeys.h Show annotated file Show diff for this revision Revisions of this file
NuMaker-mbed-NuBrick/NuBrickMasterLED.cpp Show annotated file Show diff for this revision Revisions of this file
NuMaker-mbed-NuBrick/NuBrickMasterLED.h Show annotated file Show diff for this revision Revisions of this file
NuMaker-mbed-NuBrick/NuBrickMasterSonar.cpp Show annotated file Show diff for this revision Revisions of this file
NuMaker-mbed-NuBrick/NuBrickMasterSonar.h Show annotated file Show diff for this revision Revisions of this file
NuMaker-mbed-NuBrick/NuBrickMasterTemp.cpp Show annotated file Show diff for this revision Revisions of this file
NuMaker-mbed-NuBrick/NuBrickMasterTemp.h Show annotated file Show diff for this revision Revisions of this file
NuMaker-mbed-NuBrick/README.md Show annotated file Show diff for this revision Revisions of this file
NuMaker-mbed-NuBrick/nubrick.h Show annotated file Show diff for this revision Revisions of this file
NuMaker-mbed-NuBrick/nubrick_prot.h Show annotated file Show diff for this revision Revisions of this file
README.md Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed-os.lib Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.gitignore	Fri Sep 29 05:44:02 2017 +0000
@@ -0,0 +1,4 @@
+.build
+.mbed
+projectfiles
+*.py*
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/NuMaker-mbed-NuBrick.lib	Fri Sep 29 05:44:02 2017 +0000
@@ -0,0 +1,1 @@
+https://github.com/OpenNuvoton/NuMaker-mbed-NuBrick/#3c1fd0e4e1ecd7763bbb27dbfbbed4b42e3a02e7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/NuMaker-mbed-NuBrick/NuBrickField.h	Fri Sep 29 05:44:02 2017 +0000
@@ -0,0 +1,77 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2016 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef NUBRICK_FIELD_H
+#define NUBRICK_FIELD_H
+
+#include "mbed.h"
+#include <utility>
+
+/** An open field of a NuMaker Brick device
+ *
+ * @Note Synchronization level: Thread safe
+ *
+ */
+class NuBrickField {
+    friend class NuBrickMaster;
+    
+public:
+    typedef std::pair<uint16_t, const char *> IndexName;
+    
+public:
+    NuBrickField(uint8_t field_index, const char *name):
+        _field_index(field_index),
+        _length(0), 
+        _minimum(0),
+        _maximum(0),
+        _value(0),
+        _name(name) {
+        // Do nothing
+    };
+    
+    /** Get minimum value of the open field of a NuBrick device
+     */
+    uint16_t get_minimum(void) {
+        return _minimum;
+    };
+    
+    /** Get maximum value of the open field of a NuBrick device
+     */
+    uint16_t get_maximum(void) {
+        return _maximum;
+    }
+    
+    /** Get value of the open field of a NuBrick device
+     */
+    uint16_t get_value(void) {
+        return _value;
+    }
+    
+    /** Set value of the open field of a NuBrick device
+     */
+    void set_value(uint16_t value) {
+        _value = value;
+    }
+    
+private:
+    uint16_t        _field_index;
+    uint16_t        _length;
+    uint16_t        _minimum;
+    uint16_t        _maximum;
+    uint16_t        _value;
+    const char *    _name;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/NuMaker-mbed-NuBrick/NuBrickMaster.cpp	Fri Sep 29 05:44:02 2017 +0000
@@ -0,0 +1,743 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2016 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "NuBrickMaster.h"
+#include <cstring>
+
+SingletonPtr<PlatformMutex> NuBrickMaster::_mutex;
+
+NuBrickMaster::NuBrickMaster(I2C &i2c, int i2c_addr, bool debug)
+    : _i2c(i2c), _i2c_addr(i2c_addr), 
+        _i2c_buf_pos(_i2c_buf), _i2c_buf_end(_i2c_buf + sizeof (_i2c_buf) / sizeof (_i2c_buf[0])), _i2c_buf_overflow(false),
+        _connected(false), _debug(debug), _null_field(0, ""),
+        _feature_report_fields(NULL), _num_feature_report_fields(0), 
+        _input_report_fields(NULL), _num_input_report_fields(0),
+        _output_report_fields(NULL), _num_output_report_fields(0) {
+        
+    // No lock needed in the constructor
+
+    // Set I2C bus clock to 100K.
+    _i2c.frequency(100000);
+    
+    memset(_i2c_buf, 0x00, sizeof (_i2c_buf));
+}
+
+NuBrickMaster::~NuBrickMaster() {
+    
+    // Remove fields of feature report allocated by subclass
+    remove_feature_fields();
+    // Remove fields of input report allocated by subclass
+    remove_input_fields();
+    // Remove fields of output report allocated by subclass
+    remove_output_fields();
+}
+    
+bool NuBrickMaster::connect(void) {
+    // Support thread-safe
+    MutexGuard guard;
+    
+    if (_connected) {
+        return true;
+    }
+    
+    // Get device descriptor
+    if (! pull_device_desc()) {
+        _connected = false;
+        NUBRICK_ERROR_RETURN_FALSE("pull_device_desc() failed\r\n");
+    }
+    // Get report descriptor
+    if (! pull_report_desc()) {
+        _connected = false;
+        NUBRICK_ERROR_RETURN_FALSE("pull_report_desc() failed\r\n");
+    }
+    
+    _connected = true;
+    return true;
+}
+
+NuBrickField &NuBrickMaster::operator[](const char *report_field_name) {
+    // Support thread-safe
+    MutexGuard guard;
+    
+    if (! report_field_name) {
+        NUBRICK_ERROR_RETURN_NULL_FIELD("NULL string not support\r\n");
+    }
+    
+    const char *dot_plus_field_name = strchr(report_field_name, '.');
+    if (dot_plus_field_name == NULL) {
+        NUBRICK_ERROR_RETURN_NULL_FIELD("%s not support\r\n", report_field_name);
+    }
+  
+    const char *field_name = dot_plus_field_name + 1;
+    unsigned report_name_len = dot_plus_field_name - report_field_name;
+    
+    if (strncmp("feature", report_field_name, report_name_len) == 0) {
+        NuBrickField *field = _feature_report_fields;
+        NuBrickField *field_end = _feature_report_fields + _num_feature_report_fields;
+    
+        for (; field != field_end; field ++) {
+            const char *field_name_iter = field->_name;
+            
+            if (strcmp(field_name, field_name_iter) == 0) {
+                return *field;
+            }
+        }
+        NUBRICK_ERROR_RETURN_NULL_FIELD("%s not support\r\n", report_field_name);
+    }
+    else if (strncmp("input", report_field_name, report_name_len) == 0) {
+        NuBrickField *field = _input_report_fields;
+        NuBrickField *field_end = _input_report_fields + _num_input_report_fields;
+    
+        for (; field != field_end; field ++) {
+            const char *field_name_iter = field->_name;
+            
+            if (strcmp(field_name, field_name_iter) == 0) {
+                return *field;
+            }
+        }
+        NUBRICK_ERROR_RETURN_NULL_FIELD("%s not support\r\n", report_field_name);
+        
+    }
+    else if (strncmp("output", report_field_name, report_name_len) == 0) {
+        NuBrickField *field = _output_report_fields;
+        NuBrickField *field_end = _output_report_fields + _num_output_report_fields;
+    
+        for (; field != field_end; field ++) {
+            const char *field_name_iter = field->_name;
+            
+            if (strcmp(field_name, field_name_iter) == 0) {
+                return *field;
+            }
+        }
+        NUBRICK_ERROR_RETURN_NULL_FIELD("%s not support\r\n", report_field_name);
+    }
+    else {
+        NUBRICK_ERROR_RETURN_NULL_FIELD("%s not support\r\n", report_field_name);
+    }
+    
+}
+    
+bool NuBrickMaster::pull_device_desc(void) {
+    // Support thread-safe
+    MutexGuard guard;
+    
+    // Send GetDeviceDescriptor command
+    nu_set16_le(_i2c_buf, NuBrick_Comm_GetDeviceDesc);    
+    if (_i2c.write(_i2c_addr, (char *) _i2c_buf, 2, true)) {
+        NUBRICK_ERROR_RETURN_FALSE("i2c.write() failed\r\n");
+    }
+    
+    // Receive device descriptor
+    if (_i2c.read(_i2c_addr, (char *) _i2c_buf, NuBrick_DeviceDesc_Len, false)) {
+        NUBRICK_ERROR_RETURN_FALSE("i2c.read() failed\r\n");
+    }
+    
+    // Un-serialize device descriptor
+    _i2c_buf_pos = _i2c_buf;
+    if (! unserialize_device_desc()) {
+        NUBRICK_ERROR_RETURN_FALSE("unserialize_device_desc() failed\r\n");
+    }
+    
+    return true;
+}
+
+bool NuBrickMaster::pull_report_desc(void) {
+    // Support thread-safe
+    MutexGuard guard;
+    
+    // Send GetReportDescriptor command
+    nu_set16_le(_i2c_buf, NuBrick_Comm_GetReportDesc);    
+    if (_i2c.write(_i2c_addr, (char *) _i2c_buf, 2, true)) {
+        NUBRICK_ERROR_RETURN_FALSE("i2c.write() failed\r\n");
+    }
+    
+    // Receive report descriptor
+    if (_i2c.read(_i2c_addr, (char *) _i2c_buf, _dev_desc.report_desc_len, false)) {
+        NUBRICK_ERROR_RETURN_FALSE("i2c.read() failed\r\n");
+    }
+    
+    // Un-serialize report descriptor
+    _i2c_buf_pos = _i2c_buf;
+    if (! unserialize_report_desc()) {
+        NUBRICK_ERROR_RETURN_FALSE("unserialize_report_desc() failed\r\n");
+    }
+    
+    return true;
+}
+    
+bool NuBrickMaster::pull_input_report(void) {
+    // Support thread-safe
+    MutexGuard guard;
+    
+    NUBRICK_CHECK_CONNECT();
+    
+    // Send GetInputReport command
+    nu_set16_le(_i2c_buf, NuBrick_Comm_GetInputReport);    
+    if (_i2c.write(_i2c_addr, (char *) _i2c_buf, 2, true)) {
+        NUBRICK_ERROR_RETURN_FALSE("i2c.write() failed\r\n");
+    }
+    
+    // Receive input report
+    if (_i2c.read(_i2c_addr, (char *) _i2c_buf, _dev_desc.input_report_len, false)) {
+        NUBRICK_ERROR_RETURN_FALSE("i2c.read() failed\r\n");
+    }
+    
+    // Un-serialize input report
+    _i2c_buf_pos = _i2c_buf;
+    if (! unserialize_input_report()) {
+        NUBRICK_ERROR_RETURN_FALSE("unserialize_input_report() failed\r\n");
+    }
+    
+    return true;
+}
+
+bool NuBrickMaster::push_output_report(void) {
+    // Support thread-safe
+    MutexGuard guard;
+    
+    NUBRICK_CHECK_CONNECT();
+    
+    _i2c_buf_pos = _i2c_buf;
+    
+    // Send SetOutputReport command
+    set16_le_next(NuBrick_Comm_SetOutputReport);    
+    
+    // Serialize output report
+    if (! serialize_output_report()) {
+        NUBRICK_ERROR_RETURN_FALSE("serialize_output_report() failed\r\n");
+    }
+    
+    // Send Output report
+    if (_i2c.write(_i2c_addr, (char *) _i2c_buf, _i2c_buf_pos - _i2c_buf, false)) {
+        NUBRICK_ERROR_RETURN_FALSE("i2c.write() failed\r\n");
+    }
+    
+    return true;
+}
+    
+bool NuBrickMaster::pull_feature_report(void) {
+    // Support thread-safe
+    MutexGuard guard;
+    
+    NUBRICK_CHECK_CONNECT();
+    
+    // Send GetFeatureReport command
+    nu_set16_le(_i2c_buf, NuBrick_Comm_GetFeatureReport);    
+    if (_i2c.write(_i2c_addr, (char *) _i2c_buf, 2, true)) {
+        NUBRICK_ERROR_RETURN_FALSE("i2c.write() failed\r\n");
+    }
+    
+    // Receive feature report
+    if (_i2c.read(_i2c_addr, (char *) _i2c_buf, _dev_desc.getfeat_report_len, false)) {
+        NUBRICK_ERROR_RETURN_FALSE("i2c.read() failed\r\n");
+    }
+    
+    // Un-serialize feature report
+    _i2c_buf_pos = _i2c_buf;
+    if (! unserialize_feature_report()) {
+        NUBRICK_ERROR_RETURN_FALSE("unserialize_feature_report() failed\r\n");
+    }
+    
+    return true;
+}
+
+bool NuBrickMaster::push_feature_report(void) {
+    // Support thread-safe
+    MutexGuard guard;
+    
+    NUBRICK_CHECK_CONNECT();
+    
+    _i2c_buf_pos = _i2c_buf;
+    
+    // Send SetFeatureReport command
+    set16_le_next(NuBrick_Comm_SetFeatureReport);    
+   
+    // Serialize feature report
+    if (! serialize_feature_report()) {
+        NUBRICK_ERROR_RETURN_FALSE("serialize_feature_report() failed\r\n");
+    }
+    
+    // Send feature report
+    if (_i2c.write(_i2c_addr, (char *) _i2c_buf, _i2c_buf_pos - _i2c_buf, false)) {
+        NUBRICK_ERROR_RETURN_FALSE("i2c.write() failed\r\n");
+    }
+    
+    return true;
+}
+
+bool NuBrickMaster::print_device_desc(void) {
+    // Support thread-safe
+    MutexGuard guard;
+    
+    NUBRICK_CHECK_CONNECT();
+    
+    printf("Device descriptor length\t\t%d\r\n", _dev_desc.dev_desc_len);
+    printf("Report descriptor length\t\t%d\r\n", _dev_desc.report_desc_len);
+    printf("Input report length\t\t\t%d\r\n", _dev_desc.input_report_len);
+    printf("Output report length\t\t\t%d\r\n", _dev_desc.output_report_len);
+    printf("Get feature report length\t\t%d\r\n", _dev_desc.getfeat_report_len);
+    printf("Set feature report length\t\t%d\r\n", _dev_desc.setfeat_report_len);
+    printf("Company ID\t\t\t\t%d\r\n", _dev_desc.cid);
+    printf("Device ID\t\t\t\t%d\r\n", _dev_desc.did);
+    printf("Product ID\t\t\t\t%d\r\n", _dev_desc.pid);
+    printf("Product ID\t\t\t\t%d\r\n", _dev_desc.uid);
+    printf("Product ID\t\t\t\t%d\r\n", _dev_desc.ucid);
+    
+    return true;
+}
+    
+bool NuBrickMaster::print_feature_report(void) {
+    // Support thread-safe
+    MutexGuard guard;
+    
+    NUBRICK_CHECK_CONNECT();
+    
+    print_report(_feature_report_fields, _num_feature_report_fields, "feature report");
+    
+    return true;
+}
+    
+    
+bool NuBrickMaster::print_input_report(void) {
+    // Support thread-safe
+    MutexGuard guard;
+    
+    NUBRICK_CHECK_CONNECT();
+    
+    print_report(_input_report_fields, _num_input_report_fields, "input report");
+    
+    return true;
+}
+    
+    
+bool NuBrickMaster::print_output_report(void) {
+    // Support thread-safe
+    MutexGuard guard;
+    
+    NUBRICK_CHECK_CONNECT();
+    
+    print_report(_output_report_fields, _num_output_report_fields, "output report");
+    
+    return true;
+}
+
+void NuBrickMaster::add_feature_fields(const NuBrickField::IndexName *field_index_name, unsigned num_index_name) {
+    
+    remove_report_fields(_feature_report_fields, _num_feature_report_fields);
+    add_report_fields(field_index_name, num_index_name, _feature_report_fields, _num_feature_report_fields);
+}
+
+void NuBrickMaster::remove_feature_fields(void) {
+    
+    remove_report_fields(_feature_report_fields, _num_feature_report_fields);
+}
+
+void NuBrickMaster::add_input_fields(const NuBrickField::IndexName *field_index_name, unsigned num_index_name) {
+    
+    remove_report_fields(_input_report_fields, _num_input_report_fields);
+    add_report_fields(field_index_name, num_index_name, _input_report_fields, _num_input_report_fields);
+}
+
+void NuBrickMaster::remove_input_fields(void) {
+    
+   remove_report_fields(_input_report_fields, _num_input_report_fields);
+}
+
+void NuBrickMaster::add_output_fields(const NuBrickField::IndexName *field_index_name, unsigned num_index_name) {
+    
+    remove_report_fields(_output_report_fields, _num_output_report_fields);
+    add_report_fields(field_index_name, num_index_name, _output_report_fields, _num_output_report_fields);
+}
+
+void NuBrickMaster::remove_output_fields(void) {
+    
+    remove_report_fields(_output_report_fields, _num_output_report_fields);
+}
+
+void NuBrickMaster::add_report_fields(const NuBrickField::IndexName *field_index_name, unsigned num_index_name, 
+        NuBrickField *&report_fields, unsigned &num_report_fields) {
+    
+    MBED_ASSERT(report_fields == NULL);
+    MBED_ASSERT(num_report_fields == 0);
+    
+    unsigned i;
+    
+    num_report_fields = num_index_name;
+    void *raw_memory = ::operator new(sizeof (NuBrickField) * num_index_name);
+    report_fields = static_cast<NuBrickField *>(raw_memory);
+    for (i = 0; i < num_index_name; i ++) {
+        NuBrickField *field = report_fields + i;
+        new (field) NuBrickField(field_index_name[i].first,  field_index_name[i].second);
+    }
+}
+    
+void NuBrickMaster::NuBrickMaster::remove_report_fields(NuBrickField *&report_fields, unsigned &num_report_fields) {
+    
+    unsigned i;
+    
+    for (i = 0; i < num_report_fields; i ++) {
+        NuBrickField *field = report_fields + i;
+        field->~NuBrickField();
+    }
+    
+    ::operator delete((void *) report_fields);
+    report_fields = NULL;
+    num_report_fields = 0;
+}
+
+bool NuBrickMaster::unserialize_device_desc(void) {
+
+    // Device descriptor length
+    _dev_desc.dev_desc_len = get16_le_next();
+    
+    // Report descriptor length
+    _dev_desc.report_desc_len = get16_le_next();
+    
+    // Input report length
+    _dev_desc.input_report_len = get16_le_next();
+    
+    // Output report length
+    _dev_desc.output_report_len = get16_le_next();
+    
+    // Get feature report length
+    _dev_desc.getfeat_report_len = get16_le_next();
+    
+    // Set feature report length
+    _dev_desc.setfeat_report_len = get16_le_next();
+    
+    // CID
+    _dev_desc.cid = get16_le_next();
+    
+    // DID
+    _dev_desc.did = get16_le_next();
+    
+    // PID
+    _dev_desc.pid = get16_le_next();
+    
+    // UID
+    _dev_desc.uid = get16_le_next();
+    
+    // UCID
+    _dev_desc.ucid = get16_le_next();
+    
+    // Reserved 1
+    _dev_desc.reserved1 = get16_le_next();
+    
+    // Reserved 2
+    _dev_desc.reserved2 = get16_le_next();
+    
+    if (_dev_desc.dev_desc_len != NuBrick_DeviceDesc_Len) {
+        NUBRICK_ERROR_RETURN_FALSE("Length of device descriptor doesn't match\r\n");
+    }
+    
+    return true;
+}
+
+
+bool NuBrickMaster::unserialize_report_desc(void) {
+    
+    // Report descriptor length
+    uint16_t report_desc_len = get16_le_next();
+    if (report_desc_len != _dev_desc.report_desc_len) {
+        NUBRICK_ERROR_RETURN_FALSE("Length of report descriptor doesn't match\r\n");
+    }
+    
+    uint16_t desc_type;
+    NuBrickField *field = NULL;
+    NuBrickField *field_end = NULL;
+    
+    // Check no feature report descriptor
+    if (! _num_feature_report_fields) {
+        return true;
+    }
+    
+    // Feature report descriptor type
+    desc_type = get16_be_next();
+    if (desc_type != NuBrick_DescType_FeatureReport) {
+        NUBRICK_ERROR_RETURN_FALSE("Expect feature report descriptor type %d, but %d received\r\n", NuBrick_DescType_FeatureReport, desc_type);
+    }
+    
+    // Un-serialize feature report fields from report descriptor
+    field = _feature_report_fields;
+    field_end = _feature_report_fields + _num_feature_report_fields;
+    for (; field != field_end; field ++) {
+        if (! unserialize_field_from_report_desc(field)) {
+            NUBRICK_ERROR_RETURN_FALSE("unserialize_field_from_report_desc() failed\r\n");
+        }
+    }
+
+    // Check no input report descriptor
+    if (! _num_input_report_fields) {
+        return true;
+    }
+    
+    // Input report descriptor type
+    desc_type = get16_be_next();
+    if (desc_type != NuBrick_DescType_InputReport) {
+        NUBRICK_ERROR_RETURN_FALSE("Expect input report descriptor type %d, but %d received\r\n", NuBrick_DescType_InputReport, desc_type);
+    }
+    
+    // Un-serialize input report fields from report descriptor
+    field = _input_report_fields;
+    field_end = _input_report_fields + _num_input_report_fields;
+    for (; field != field_end; field ++) {
+        if (! unserialize_field_from_report_desc(field)) {
+            NUBRICK_ERROR_RETURN_FALSE("unserialize_field_from_report_desc() failed\r\n");
+        }
+    }
+    
+    // Check no output report descriptor
+    if (! _num_output_report_fields) {
+        return true;
+    }
+    
+    // Output report descriptor type
+    desc_type = get16_be_next();
+    if (desc_type != NuBrick_DescType_OutputReport) {
+        NUBRICK_ERROR_RETURN_FALSE("Expect output report descriptor type %d, but %d received\r\n", NuBrick_DescType_OutputReport, desc_type);
+    }
+    
+    // Un-serialize output report fields from report descriptor
+    field = _output_report_fields;
+    field_end = _output_report_fields + _num_output_report_fields;
+    for (; field != field_end; field ++) {
+        if (! unserialize_field_from_report_desc(field)) {
+            NUBRICK_ERROR_RETURN_FALSE("unserialize_field_from_report_desc() failed\r\n");
+        }
+    }
+    
+    return true;
+}
+    
+bool NuBrickMaster::unserialize_input_report(void) {
+    
+    // Input report length
+    uint16_t report_len = get16_le_next();
+    if (report_len != _dev_desc.input_report_len) {
+        NUBRICK_ERROR_RETURN_FALSE("Length of input report doesn't match\r\n");
+    }
+
+    // Un-serialize fields from input report
+    NuBrickField *field = _input_report_fields;
+    NuBrickField *field_end = _input_report_fields + _num_input_report_fields;
+    for (; field != field_end; field ++) {
+        if (! unserialize_field_from_report(field)) {
+            NUBRICK_ERROR_RETURN_FALSE("unserialize_field_from_report() failed\r\n");
+        }
+    }
+    
+    return true;
+}
+    
+bool NuBrickMaster::serialize_output_report(void) {
+    
+    uint8_t *i2c_buf_beg = _i2c_buf_pos;
+    
+    // Output report length
+    set16_le_next(_dev_desc.output_report_len);
+
+    // Serialize fields to output report
+    NuBrickField *field = _output_report_fields;
+    NuBrickField *field_end = _output_report_fields + _num_output_report_fields;
+    for (; field != field_end; field ++) {
+        if (! serialize_field_to_report(field)) {
+            NUBRICK_ERROR_RETURN_FALSE("serialize_field_to_report() failed\r\n");
+        }
+    }
+    
+    if ((_i2c_buf_pos - i2c_buf_beg) != _dev_desc.output_report_len) {
+        NUBRICK_ERROR_RETURN_FALSE("Length of output report doesn't match\r\n");
+    }
+    
+    return true;
+}
+    
+bool NuBrickMaster::unserialize_feature_report(void) {
+    
+    // Feature report length
+    uint16_t report_len = get16_le_next();
+    if (report_len != _dev_desc.getfeat_report_len) {
+        NUBRICK_ERROR_RETURN_FALSE("Length of feature report doesn't match\r\n");
+    }
+    
+    // Un-serialize fields from feature report
+    NuBrickField *field = _feature_report_fields;
+    NuBrickField *field_end = _feature_report_fields + _num_feature_report_fields;
+    for (; field != field_end; field ++) {
+        if (! unserialize_field_from_report(field)) {
+            NUBRICK_ERROR_RETURN_FALSE("unserialize_field_from_report() failed\r\n");
+        }
+    }
+    
+    return true;
+}
+    
+bool NuBrickMaster::serialize_feature_report(void) {
+    
+    uint8_t *i2c_buf_beg = _i2c_buf_pos;
+    
+    // Feature report length
+    set16_le_next(_dev_desc.setfeat_report_len);
+
+    // Serialize fields to feature report
+    NuBrickField *field = _feature_report_fields;
+    NuBrickField *field_end = _feature_report_fields + _num_feature_report_fields;
+    for (; field != field_end; field ++) {
+        if (! serialize_field_to_report(field)) {
+            NUBRICK_ERROR_RETURN_FALSE("serialize_field_to_report() failed\r\n");
+        }
+    }
+    
+    if ((_i2c_buf_pos - i2c_buf_beg) != _dev_desc.setfeat_report_len) {
+        NUBRICK_ERROR_RETURN_FALSE("Length of set feature report doesn't match\r\n");
+    }
+    
+    return true;
+}
+
+bool NuBrickMaster::unserialize_field_from_report_desc(NuBrickField *field) {
+    // Number/length of the field
+    uint8_t field_index = get8_next();
+    if (field_index != field->_field_index) {
+        NUBRICK_ERROR_RETURN_FALSE("Expect field index %d, but %d received\r\n", field->_field_index, field_index);
+    }
+    
+    // Length of the field
+    field->_length = get8_next();
+    if (field->_length != 1 && field->_length != 2) {
+        NUBRICK_ERROR_RETURN_FALSE("Expect field length 1/2, but %d received\r\n", field->_length);
+    }
+    
+    // Minimum of the field
+    uint8_t min = get8_next();
+    switch (min) {
+        case NuBrick_ReportDesc_Min_Plus1:
+            field->_minimum = get8_next();
+            break;
+        
+        case NuBrick_ReportDesc_Min_Plus2:
+            field->_minimum = get16_le_next();
+            break;
+            
+        default:
+            NUBRICK_ERROR_RETURN_FALSE("Expect field minimum %d/%d, but %d received\r\n", NuBrick_ReportDesc_Min_Plus1, NuBrick_ReportDesc_Min_Plus2, min);
+    }
+    
+    // Maximum of the field
+    uint8_t max = get8_next();
+    switch (max) {
+        case NuBrick_ReportDesc_Max_Plus1:
+            field->_maximum = get8_next();
+            break;
+        
+        case NuBrick_ReportDesc_Max_Plus2:
+            field->_maximum = get16_le_next();
+            break;
+            
+        default:
+            NUBRICK_ERROR_RETURN_FALSE("Expect field maximum %d/%d, but %d received\r\n", NuBrick_ReportDesc_Max_Plus1, NuBrick_ReportDesc_Max_Plus2, max);
+    }
+    
+    return true;
+}
+
+bool NuBrickMaster::unserialize_field_from_report(NuBrickField *field) {
+    // Value of the field
+    switch (field->_length) {
+        case 1:
+            field->_value = get8_next();
+            break;
+            
+        case 2:
+            field->_value = get16_le_next();
+            break;
+            
+        default:
+            NUBRICK_ERROR_RETURN_FALSE("Expect field length 1/2, but %d received\r\n", field->_length);
+    }
+    
+    return true;
+}
+
+bool NuBrickMaster::serialize_field_to_report(const NuBrickField *field) {
+    // Value of the field
+    switch (field->_length) {
+        case 1:
+            set8_next(field->_value);
+            break;
+            
+        case 2:
+            set16_le_next(field->_value);
+            break;
+            
+        default:
+            NUBRICK_ERROR_RETURN_FALSE("Expect field length 1/2, but %d received\r\n", field->_length);
+    }
+    
+    return true;
+}
+
+uint8_t NuBrickMaster::get8_next(void) {
+    NUBRICK_CHECK_GETN_NEXT(1);
+    
+    uint8_t val = *_i2c_buf_pos ++;
+    return val;
+}
+    
+void NuBrickMaster::set8_next(uint8_t val) {
+    NUBRICK_CHECK_SETN_NEXT(1);
+    
+    *_i2c_buf_pos ++ = val;
+}
+    
+uint16_t NuBrickMaster::get16_le_next(void) {
+    NUBRICK_CHECK_GETN_NEXT(2);
+    
+    uint16_t val = nu_get16_le(_i2c_buf_pos);
+    _i2c_buf_pos += 2;
+    return val;
+}
+    
+void NuBrickMaster::set16_le_next(uint16_t val) {
+    NUBRICK_CHECK_SETN_NEXT(2);
+    
+    nu_set16_le(_i2c_buf_pos, val);
+    _i2c_buf_pos += 2;
+}
+    
+uint16_t NuBrickMaster::get16_be_next(void) {
+    NUBRICK_CHECK_GETN_NEXT(2);
+    
+    uint16_t val = nu_get16_be(_i2c_buf_pos);
+    _i2c_buf_pos += 2;
+    return val;
+}
+    
+void NuBrickMaster::print_report(NuBrickField *fields, unsigned num_fields, const char *report_name) {
+    
+    printf("Number of fields of %s\t%d\r\n", report_name, num_fields);
+    
+    unsigned i;
+    for (i = 0; i < num_fields; i ++) {
+        NuBrickField *field = fields + i;
+        
+        printf("Name\t\t%s\r\n", field->_name);
+        printf("Length\t\t%d\r\n", field->_length);
+        printf("Value\t\t%d\r\n", field->_value);
+        printf("Minimum\t\t%d\r\n", field->_minimum);
+        printf("Maximum\t\t%d\r\n", field->_maximum);
+        printf("\r\n");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/NuMaker-mbed-NuBrick/NuBrickMaster.h	Fri Sep 29 05:44:02 2017 +0000
@@ -0,0 +1,317 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2016 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef NUBRICK_MASTER_H
+#define NUBRICK_MASTER_H
+
+#include "mbed.h"
+#include "mbed_debug.h"
+#include "NuBrickField.h"
+#include "nubrick_prot.h"
+#include "targets/TARGET_NUVOTON/nu_bitutil.h"
+
+/** Print error message and return null field
+ *
+ *  @note For internal use
+ */
+#define NUBRICK_ERROR_RETURN_NULL_FIELD(...)                \
+    do {                                                    \
+        debug_if(_debug, __VA_ARGS__);                      \
+        return _null_field;                                 \
+    } while (0);
+
+/** Print error message and return false
+ *
+ *  @note For internal use
+ */
+#define NUBRICK_ERROR_RETURN_FALSE(...)                     \
+    do {                                                    \
+        debug_if(_debug, __VA_ARGS__);                      \
+        return false;                                       \
+    } while (0);
+
+/** Check if NuMaker Brick I2C slave module has connected
+ *
+ *  @note For internal use
+ */
+#define NUBRICK_CHECK_CONNECT()                                                                     \
+    do {                                                                                            \
+        if (! _connected) {                                                                         \
+            NUBRICK_ERROR_RETURN_FALSE("NuMaker Brick I2C slave module not connected yet!!!\r\n");  \
+        }                                                                                           \
+    } while (0);
+    
+/** Check if I2C buffer is overflow on getN calls
+ *
+ *  @note For internal use
+ */
+#define NUBRICK_CHECK_GETN_NEXT(N)                                      \
+    do {                                                                \
+        if ((_i2c_buf_pos + N) > _i2c_buf_end) {                        \
+            error("%s:%s: I2C buffer overflow", __FILE__, __func__);    \
+            return 0;                                                   \
+        }                                                               \
+    } while (0);
+
+/** Check if I2C buffer is overflow on setN calls
+ *
+ *  @note For internal use
+ */
+#define NUBRICK_CHECK_SETN_NEXT(N)                                  \
+    do {                                                            \
+        if ((_i2c_buf_pos + N) > _i2c_buf_end) {                    \
+            error("%s: I2C buffer overflow", __func__);             \
+        }                                                           \
+    } while (0);
+    
+/** A NuMaker Brick I2C master, used for communicating with NuMaker Brick I2C slave modules
+ *
+ * @note Synchronization level: Thread safe
+ *
+ */
+class NuBrickMaster {
+
+public:
+
+    /** Create an I2C interface, connected to the specified pins
+     *
+     *  @param i2c I2C object
+     *  @param address 8-bit I2C slave address [ addr | 0 ]
+     */
+    NuBrickMaster(I2C &i2c, int i2c_addr, bool debug);
+
+    virtual ~NuBrickMaster();
+    
+    /** Connect to the NuBrick I2C slave module
+     *
+     *  @return true if success, false if failure
+     *
+     *  @note On success, device descriptor and report descriptor will be fetched.
+     */
+    bool connect(void);
+    
+    /** Is the NuBrick I2C slave module connected?
+     *
+     *  @return true if success, false if failure
+     */
+    bool connected(void) {
+        return _connected;
+    }
+    
+    /** Get one field of the NuBrick I2C slave module in "report.field" format, e.g. "feature.sleep_period". 
+     *
+     *  @return non-NULL if success, NULL if failure
+     *
+     *  @note See subclasses for supported report.field names
+     *  @note If passed name is incorrect or not supported, a null object is returned.
+     *        Operations on this null object will do nothing.
+     *
+     */
+    NuBrickField &operator[](const char *report_field_name);
+    
+    /** Pull device descriptor from the NuBrick I2C slave module
+     *
+     *  @return true if success, false if failure
+     */
+    bool pull_device_desc(void);
+    
+    /** Pull report descriptor from the NuBrick I2C slave module
+     *
+     *  @return true if success, false if failure
+     */
+    bool pull_report_desc(void);
+    
+    /** Pull input report from the NuBrick I2C slave module
+     *
+     *  @return true if success, false if failure
+     */
+    bool pull_input_report(void);
+
+    /** Push output report to the NuBrick I2C slave module
+     *
+     *  @return true if success, false if failure
+     */
+    bool push_output_report(void);
+    
+    /** Pull feature report from the NuBrick I2C slave module
+     *
+     *  @return true if success, false if failure
+     */
+    bool pull_feature_report(void);
+    
+    /** Push feature report to the NuBrick I2C slave module
+     *
+     *  @return true if success, false if failure
+     */
+    bool push_feature_report(void);
+    
+    /** Print device descriptor
+     */
+    bool print_device_desc(void);
+    
+    /** Print feature report
+     */
+    bool print_feature_report(void);
+    
+    /** Print input report
+     */
+    bool print_input_report(void);
+    
+    /** Print output report
+     */
+    bool print_output_report(void);
+    
+protected:
+    I2C &                               _i2c;
+    int                                 _i2c_addr;
+    uint8_t                             _i2c_buf[80];
+    uint8_t *                           _i2c_buf_pos;
+    uint8_t * const                     _i2c_buf_end;
+    bool                                _i2c_buf_overflow;
+    bool                                _connected;
+    bool                                _debug;
+    NuBrick_Device_Descriptor           _dev_desc;
+    NuBrickField                        _null_field;
+    NuBrickField *                      _feature_report_fields;
+    unsigned                            _num_feature_report_fields;
+    NuBrickField *                      _input_report_fields;
+    unsigned                            _num_input_report_fields;
+    NuBrickField *                      _output_report_fields;
+    unsigned                            _num_output_report_fields;
+    
+    /** Using RAII idiom for mutex lock/unlock
+     */
+    class MutexGuard {
+    public:
+        MutexGuard() {
+            _mutex->lock();
+        }
+        
+        ~MutexGuard() {
+            _mutex->unlock();
+        }
+    };
+    
+    static SingletonPtr<PlatformMutex>  _mutex;
+    
+    /** Add fields of feature report
+     */
+    void add_feature_fields(const NuBrickField::IndexName *field_index_name, unsigned num_index_name);
+    
+    /** Remove fields of feature report
+     */
+    void remove_feature_fields(void);
+    
+    /** Add fields of input report
+     */
+    void add_input_fields(const NuBrickField::IndexName *field_index_name, unsigned num_index_name);
+    
+    /** Remove fields of input report
+     */
+    void remove_input_fields(void);
+    
+    /** Add fields of output report
+     */
+    void add_output_fields(const NuBrickField::IndexName *field_index_name, unsigned num_index_name);
+    
+    /** Remove fields of output report
+     */
+    void remove_output_fields(void);
+    
+    /** Add fields of specific report
+     */
+    void add_report_fields(const NuBrickField::IndexName *field_index_name, unsigned num_index_name, 
+        NuBrickField *&report_fields, unsigned &num_report_fields);
+    
+    /** Remove fields of specific report
+     */
+    void remove_report_fields(NuBrickField *&report_fields, unsigned &num_report_fields);
+    
+    /** Un-serialize device descriptor from the NuBrick I2C slave module
+     *
+     *  @return true if success, false if failure
+     */
+    bool unserialize_device_desc(void);
+    
+    /** Un-serialize report descriptor from the NuBrick I2C slave module
+     *
+     *  @return true if success, false if failure
+     */
+    virtual bool unserialize_report_desc(void);
+    
+    /** Un-serialize input report from the NuBrick I2C slave module
+     *
+     *  @return true if success, false if failure
+     */
+    virtual bool unserialize_input_report(void);
+    
+    /** Serialize output report to the NuBrick I2C slave module
+     *
+     *  @return true if success, false if failure
+     */
+    virtual bool serialize_output_report(void);
+    
+    /** Un-serialize feature report from the NuBrick I2C slave module
+     *
+     *  @return true if success, false if failure
+     */
+    virtual bool unserialize_feature_report(void);
+    
+    /** Serialize feature report to the NuBrick I2C slave module
+     *
+     *  @return true if success, false if failure
+     */
+    virtual bool serialize_feature_report(void);
+    
+    /** Un-serialize field from report descriptor
+     */
+    bool unserialize_field_from_report_desc(NuBrickField *field);
+    
+    /** Un-serialize field from report
+     */
+    bool unserialize_field_from_report(NuBrickField *field);
+    
+    /** Serialize field to report
+     */
+    bool serialize_field_to_report(const NuBrickField *field);
+    
+    /** Un-serialize from little-endian stream to uint8_t type and advance stream position
+     */
+    uint8_t get8_next(void);
+    
+    /** Serialize from uint8_t type to little-endian stream and advance stream position
+     */
+    void set8_next(uint8_t val);
+    
+    /** Un-serialize from little-endian stream to uint16_t type and advance stream position
+     */
+    uint16_t get16_le_next(void);
+    
+    /** Serialize from uint16_t type to little-endian stream and advance stream position
+     */
+    void set16_le_next(uint16_t val);
+    
+    /** Un-serialize from big-endian stream to uint16_t type and advance stream position
+     */
+    uint16_t get16_be_next(void);
+    
+    /** Print specified report
+     *
+     *  @param name report name
+     */
+    void print_report(NuBrickField *fields, unsigned num_fields, const char *report_name);
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/NuMaker-mbed-NuBrick/NuBrickMasterAHRS.cpp	Fri Sep 29 05:44:02 2017 +0000
@@ -0,0 +1,43 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2016 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "NuBrickMasterAHRS.h"
+
+NuBrickMasterAHRS::NuBrickMasterAHRS(I2C &i2c, bool debug) :
+    NuBrickMaster(i2c, NuBrick_I2CAddr_AHRS, debug) {
+
+    static const NuBrickField::IndexName ahrs_feature_field_index_name_arr[] = {
+        NuBrickField::IndexName(NuBrick_ReportDesc_FieldIndex1_Plus1, "sleep_period"),
+        NuBrickField::IndexName(NuBrick_ReportDesc_FieldIndex2_Plus1, "pre_vibration_AT")
+    };
+
+    static const NuBrickField::IndexName ahrs_input_field_index_name_arr[] = {
+        NuBrickField::IndexName(NuBrick_ReportDesc_FieldIndex1_Plus1, "vibration"),
+        NuBrickField::IndexName(NuBrick_ReportDesc_FieldIndex2_Plus1, "over_flag")
+    };
+
+    // Add fields of feature report
+    add_feature_fields(ahrs_feature_field_index_name_arr,
+        sizeof (ahrs_feature_field_index_name_arr) / sizeof (ahrs_feature_field_index_name_arr[0]));
+        
+    // Add fields of input report
+    add_input_fields(ahrs_input_field_index_name_arr,
+        sizeof (ahrs_input_field_index_name_arr) / sizeof (ahrs_input_field_index_name_arr[0]));
+    
+    // Add fields of output report
+    
+    // No lock needed in the constructor
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/NuMaker-mbed-NuBrick/NuBrickMasterAHRS.h	Fri Sep 29 05:44:02 2017 +0000
@@ -0,0 +1,48 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2016 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef NUBRICK_MASTER_AHRS_H
+#define NUBRICK_MASTER_AHRS_H
+
+#include "mbed.h"
+#include "NuBrickMaster.h"
+
+
+/** A NuMaker Brick I2C master, used for communicating with NuMaker Brick I2C slave module AHRS
+ *
+ * @Note Synchronization level: Thread safe
+ *
+ * @details Support fields for access through [] operator:
+ *          - feature.sleep_period
+ *          - feature.pre_vibration_AT
+ *          - input.vibration
+ *          - input.over_flag
+ */
+class NuBrickMasterAHRS : public NuBrickMaster {
+
+public:
+
+    /** Create an I2C interface, connected to the specified pins
+     *
+     *  @param i2c I2C object
+     */
+    NuBrickMasterAHRS(I2C &i2c, bool debug);
+
+    virtual ~NuBrickMasterAHRS() {
+        // Do nothing
+    }
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/NuMaker-mbed-NuBrick/NuBrickMasterBuzzer.cpp	Fri Sep 29 05:44:02 2017 +0000
@@ -0,0 +1,54 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2016 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "NuBrickMasterBuzzer.h"
+
+NuBrickMasterBuzzer::NuBrickMasterBuzzer(I2C &i2c, bool debug) :
+    NuBrickMaster(i2c, NuBrick_I2CAddr_Buzzer, debug) {
+
+    static const NuBrickField::IndexName buzzer_feature_field_index_name_arr[] = {
+        NuBrickField::IndexName(NuBrick_ReportDesc_FieldIndex1_Plus1, "sleep_period"),
+        NuBrickField::IndexName(NuBrick_ReportDesc_FieldIndex2_Plus1, "volume"),
+        NuBrickField::IndexName(NuBrick_ReportDesc_FieldIndex3_Plus1, "tone"),
+        NuBrickField::IndexName(NuBrick_ReportDesc_FieldIndex4_Plus1, "song"),
+        NuBrickField::IndexName(NuBrick_ReportDesc_FieldIndex5_Plus1, "period"),
+        NuBrickField::IndexName(NuBrick_ReportDesc_FieldIndex6_Plus1, "duty"),
+        NuBrickField::IndexName(NuBrick_ReportDesc_FieldIndex7_Plus1, "latency")
+    };
+
+    static const NuBrickField::IndexName buzzer_input_field_index_name_arr[] = {
+        NuBrickField::IndexName(NuBrick_ReportDesc_FieldIndex1_Plus1, "execute_flag")
+    };
+
+    static const NuBrickField::IndexName buzzer_output_field_index_name_arr[] = {
+        NuBrickField::IndexName(NuBrick_ReportDesc_FieldIndex1_Plus1, "start_flag"),
+        NuBrickField::IndexName(NuBrick_ReportDesc_FieldIndex2_Plus1, "stop_flag")
+    };
+
+    // Add fields of feature report
+    add_feature_fields(buzzer_feature_field_index_name_arr,
+        sizeof (buzzer_feature_field_index_name_arr) / sizeof (buzzer_feature_field_index_name_arr[0]));
+        
+    // Add fields of input report
+    add_input_fields(buzzer_input_field_index_name_arr,
+        sizeof (buzzer_input_field_index_name_arr) / sizeof (buzzer_input_field_index_name_arr[0]));
+        
+    // Add fields of output report
+    add_output_fields(buzzer_output_field_index_name_arr,
+        sizeof (buzzer_output_field_index_name_arr) / sizeof (buzzer_output_field_index_name_arr[0]));
+    
+    // No lock needed in the constructor
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/NuMaker-mbed-NuBrick/NuBrickMasterBuzzer.h	Fri Sep 29 05:44:02 2017 +0000
@@ -0,0 +1,54 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2016 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef NUBRICK_MASTER_BUZZER_H
+#define NUBRICK_MASTER_BUZZER_H
+
+#include "mbed.h"
+#include "NuBrickMaster.h"
+
+
+/** A NuMaker Brick I2C master, used for communicating with NuMaker Brick I2C slave module Buzzer
+ *
+ * @Note Synchronization level: Thread safe
+ *
+ * @details Support fields for access through [] operator:
+ *          - feature.sleep_period
+ *          - feature.volume
+ *          - feature.tone
+ *          - feature.song
+ *          - feature.period
+ *          - feature.duty
+ *          - feature.latency
+ *          - input.execute_flag
+ *          - output.start_flag
+ *          - output.stop_flag
+ */
+class NuBrickMasterBuzzer : public NuBrickMaster {
+
+public:
+
+    /** Create an I2C interface, connected to the specified pins
+     *
+     *  @param i2c I2C object
+     */
+    NuBrickMasterBuzzer(I2C &i2c, bool debug);
+
+    virtual ~NuBrickMasterBuzzer() {
+        // Do nothing
+    }
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/NuMaker-mbed-NuBrick/NuBrickMasterGas.cpp	Fri Sep 29 05:44:02 2017 +0000
@@ -0,0 +1,43 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2016 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "NuBrickMasterGas.h"
+
+NuBrickMasterGas::NuBrickMasterGas(I2C &i2c, bool debug) :
+    NuBrickMaster(i2c, NuBrick_I2CAddr_Gas, debug) {
+
+    static const NuBrickField::IndexName gas_feature_field_index_name_arr[] = {
+        NuBrickField::IndexName(NuBrick_ReportDesc_FieldIndex1_Plus1, "sleep_period"),
+        NuBrickField::IndexName(NuBrick_ReportDesc_FieldIndex2_Plus1, "gas_AT")
+    };
+
+    static const NuBrickField::IndexName gas_input_field_index_name_arr[] = {
+        NuBrickField::IndexName(NuBrick_ReportDesc_FieldIndex1_Plus1, "gas"),
+        NuBrickField::IndexName(NuBrick_ReportDesc_FieldIndex2_Plus1, "over_flag")
+    };
+
+    // Add fields of feature report
+    add_feature_fields(gas_feature_field_index_name_arr,
+        sizeof (gas_feature_field_index_name_arr) / sizeof (gas_feature_field_index_name_arr[0]));
+        
+    // Add fields of input report
+    add_input_fields(gas_input_field_index_name_arr,
+        sizeof (gas_input_field_index_name_arr) / sizeof (gas_input_field_index_name_arr[0]));
+    
+    // Add fields of output report
+    
+    // No lock needed in the constructor
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/NuMaker-mbed-NuBrick/NuBrickMasterGas.h	Fri Sep 29 05:44:02 2017 +0000
@@ -0,0 +1,48 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2016 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef NUBRICK_MASTER_GAS_H
+#define NUBRICK_MASTER_GAS_H
+
+#include "mbed.h"
+#include "NuBrickMaster.h"
+
+
+/** A NuMaker Brick I2C master, used for communicating with NuMaker Brick I2C slave module Gas
+ *
+ * @Note Synchronization level: Thread safe
+ *
+ * @details Support fields for access through [] operator:
+ *          - feature.sleep_period
+ *          - feature.gas_AT
+ *          - input.gas
+ *          - input.over_flag
+ */
+class NuBrickMasterGas : public NuBrickMaster {
+
+public:
+
+    /** Create an I2C interface, connected to the specified pins
+     *
+     *  @param i2c I2C object
+     */
+    NuBrickMasterGas(I2C &i2c, bool debug);
+
+    virtual ~NuBrickMasterGas() {
+        // Do nothing
+    }
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/NuMaker-mbed-NuBrick/NuBrickMasterIR.cpp	Fri Sep 29 05:44:02 2017 +0000
@@ -0,0 +1,52 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2016 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "NuBrickMasterIR.h"
+
+NuBrickMasterIR::NuBrickMasterIR(I2C &i2c, bool debug) :
+    NuBrickMaster(i2c, NuBrick_I2CAddr_IR, debug) {
+
+    static const NuBrickField::IndexName ir_feature_field_index_name_arr[] = {
+        NuBrickField::IndexName(NuBrick_ReportDesc_FieldIndex1_Plus1, "sleep_period"),
+        NuBrickField::IndexName(NuBrick_ReportDesc_FieldIndex2_Plus1, "num_learned_data"),
+        NuBrickField::IndexName(NuBrick_ReportDesc_FieldIndex3_Plus1, "using_data_type"),
+        NuBrickField::IndexName(NuBrick_ReportDesc_FieldIndex4_Plus1, "index_orig_data_to_send"),
+        NuBrickField::IndexName(NuBrick_ReportDesc_FieldIndex5_Plus1, "index_learned_data_to_send")
+    };
+
+    static const NuBrickField::IndexName ir_input_field_index_name_arr[] = {
+        NuBrickField::IndexName(NuBrick_ReportDesc_FieldIndex1_Plus1, "received_data_flag")
+    };
+
+    static const NuBrickField::IndexName ir_output_field_index_name_arr[] = {
+        NuBrickField::IndexName(NuBrick_ReportDesc_FieldIndex1_Plus1, "send_IR_flag"),
+        NuBrickField::IndexName(NuBrick_ReportDesc_FieldIndex2_Plus1, "learn_IR_flag")
+    };
+
+    // Add fields of feature report
+    add_feature_fields(ir_feature_field_index_name_arr,
+        sizeof (ir_feature_field_index_name_arr) / sizeof (ir_feature_field_index_name_arr[0]));
+        
+    // Add fields of input report
+    add_input_fields(ir_input_field_index_name_arr,
+        sizeof (ir_input_field_index_name_arr) / sizeof (ir_input_field_index_name_arr[0]));
+        
+    // Add fields of output report
+    add_output_fields(ir_output_field_index_name_arr,
+        sizeof (ir_output_field_index_name_arr) / sizeof (ir_output_field_index_name_arr[0]));
+    
+    // No lock needed in the constructor
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/NuMaker-mbed-NuBrick/NuBrickMasterIR.h	Fri Sep 29 05:44:02 2017 +0000
@@ -0,0 +1,52 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2016 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef NUBRICK_MASTER_IR_H
+#define NUBRICK_MASTER_IR_H
+
+#include "mbed.h"
+#include "NuBrickMaster.h"
+
+
+/** A NuMaker Brick I2C master, used for communicating with NuMaker Brick I2C slave module IR
+ *
+ * @Note Synchronization level: Thread safe
+ *
+ * @details Support fields for access through [] operator:
+ *          - feature.sleep_period
+ *          - feature.num_learned_data
+ *          - feature.using_data_type
+ *          - feature.index_orig_data_to_send
+ *          - feature.index_learned_data_to_send
+ *          - input.received_data_flag
+ *          - output.send_IR_flag
+ *          - output.learn_IR_flag
+ */
+class NuBrickMasterIR : public NuBrickMaster {
+
+public:
+
+    /** Create an I2C interface, connected to the specified pins
+     *
+     *  @param i2c I2C object
+     */
+    NuBrickMasterIR(I2C &i2c, bool debug);
+
+    virtual ~NuBrickMasterIR() {
+        // Do nothing
+    }
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/NuMaker-mbed-NuBrick/NuBrickMasterKeys.cpp	Fri Sep 29 05:44:02 2017 +0000
@@ -0,0 +1,41 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2016 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "NuBrickMasterKeys.h"
+
+NuBrickMasterKeys::NuBrickMasterKeys(I2C &i2c, bool debug) :
+    NuBrickMaster(i2c, NuBrick_I2CAddr_Key, debug) {
+
+    static const NuBrickField::IndexName keys_feature_field_index_name_arr[] = {
+        NuBrickField::IndexName(NuBrick_ReportDesc_FieldIndex1_Plus1, "sleep_period")
+    };
+
+    static const NuBrickField::IndexName keys_input_field_index_name_arr[] = {
+        NuBrickField::IndexName(NuBrick_ReportDesc_FieldIndex1_Plus1, "key_state")
+    };
+
+    // Add fields of feature report
+    add_feature_fields(keys_feature_field_index_name_arr,
+        sizeof (keys_feature_field_index_name_arr) / sizeof (keys_feature_field_index_name_arr[0]));
+        
+    // Add fields of input report
+    add_input_fields(keys_input_field_index_name_arr,
+        sizeof (keys_input_field_index_name_arr) / sizeof (keys_input_field_index_name_arr[0]));
+        
+    // Add fields of output report
+    
+    // No lock needed in the constructor
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/NuMaker-mbed-NuBrick/NuBrickMasterKeys.h	Fri Sep 29 05:44:02 2017 +0000
@@ -0,0 +1,46 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2016 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef NUBRICK_MASTER_KEYS_H
+#define NUBRICK_MASTER_KEYS_H
+
+#include "mbed.h"
+#include "NuBrickMaster.h"
+
+
+/** A NuMaker Brick I2C master, used for communicating with NuMaker Brick I2C slave module Keys
+ *
+ * @Note Synchronization level: Thread safe
+ *
+ * @details Support fields for access through [] operator:
+ *          - feature.sleep_period
+ *          - input.key_state
+ */
+class NuBrickMasterKeys : public NuBrickMaster {
+
+public:
+
+    /** Create an I2C interface, connected to the specified pins
+     *
+     *  @param i2c I2C object
+     */
+    NuBrickMasterKeys(I2C &i2c, bool debug);
+
+    virtual ~NuBrickMasterKeys() {
+        // Do nothing
+    }
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/NuMaker-mbed-NuBrick/NuBrickMasterLED.cpp	Fri Sep 29 05:44:02 2017 +0000
@@ -0,0 +1,55 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2016 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "NuBrickMasterLED.h"
+
+NuBrickMasterLED::NuBrickMasterLED(I2C &i2c, bool debug):
+    NuBrickMaster(i2c, NuBrick_I2CAddr_LED, debug) {
+
+    static const NuBrickField::IndexName led_feature_field_index_name_arr[] = {
+        NuBrickField::IndexName(NuBrick_ReportDesc_FieldIndex1_Plus1, "sleep_period"),
+        NuBrickField::IndexName(NuBrick_ReportDesc_FieldIndex2_Plus1, "brightness"),
+        NuBrickField::IndexName(NuBrick_ReportDesc_FieldIndex3_Plus1, "color"),
+        NuBrickField::IndexName(NuBrick_ReportDesc_FieldIndex4_Plus1, "blink"),
+        NuBrickField::IndexName(NuBrick_ReportDesc_FieldIndex5_Plus1, "period"),
+        NuBrickField::IndexName(NuBrick_ReportDesc_FieldIndex6_Plus1, "duty"),
+        NuBrickField::IndexName(NuBrick_ReportDesc_FieldIndex7_Plus1, "latency")
+    };
+
+    static const NuBrickField::IndexName led_input_field_index_name_arr[] = {
+        NuBrickField::IndexName(NuBrick_ReportDesc_FieldIndex1_Plus1, "execute_flag")
+    };
+
+    static const NuBrickField::IndexName led_output_field_index_name_arr[] = {
+        NuBrickField::IndexName(NuBrick_ReportDesc_FieldIndex1_Plus1, "start_flag"),
+        NuBrickField::IndexName(NuBrick_ReportDesc_FieldIndex2_Plus1, "stop_flag")
+    };
+
+    // Add fields of feature report
+    add_feature_fields(led_feature_field_index_name_arr,
+        sizeof (led_feature_field_index_name_arr) / sizeof (led_feature_field_index_name_arr[0]));
+        
+    // Add fields of input report
+    add_input_fields(led_input_field_index_name_arr,
+        sizeof (led_input_field_index_name_arr) / sizeof (led_input_field_index_name_arr[0]));
+        
+    // Add fields of output report
+    add_output_fields(led_output_field_index_name_arr,
+        sizeof (led_output_field_index_name_arr) / sizeof (led_output_field_index_name_arr[0]));
+    
+    
+    // No lock needed in the constructor
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/NuMaker-mbed-NuBrick/NuBrickMasterLED.h	Fri Sep 29 05:44:02 2017 +0000
@@ -0,0 +1,54 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2016 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef NUBRICK_MASTER_LED_H
+#define NUBRICK_MASTER_LED_H
+
+#include "mbed.h"
+#include "NuBrickMaster.h"
+
+
+/** A NuMaker Brick I2C master, used for communicating with NuMaker Brick I2C slave module LED
+ *
+ * @Note Synchronization level: Thread safe
+ *
+ * @details Support fields for access through [] operator:
+ *          - feature.sleep_period
+ *          - feature.brightness
+ *          - feature.color
+ *          - feature.blink
+ *          - feature.period
+ *          - feature.duty
+ *          - feature.latency
+ *          - input.execute_flag
+ *          - output.start_flag
+ *          - output.stop_flag
+ */
+class NuBrickMasterLED : public NuBrickMaster {
+
+public:
+
+    /** Create an I2C interface, connected to the specified pins
+     *
+     *  @param i2c I2C object
+     */
+    NuBrickMasterLED(I2C &i2c, bool debug);
+
+    virtual ~NuBrickMasterLED() {
+        // Do nothing
+    }
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/NuMaker-mbed-NuBrick/NuBrickMasterSonar.cpp	Fri Sep 29 05:44:02 2017 +0000
@@ -0,0 +1,43 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2016 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "NuBrickMasterSonar.h"
+
+NuBrickMasterSonar::NuBrickMasterSonar(I2C &i2c, bool debug) :
+    NuBrickMaster(i2c, NuBrick_I2CAddr_Sonar, debug) {
+
+    static const NuBrickField::IndexName sonar_feature_field_index_name_arr[] = {
+        NuBrickField::IndexName(NuBrick_ReportDesc_FieldIndex1_Plus1, "sleep_period"),
+        NuBrickField::IndexName(NuBrick_ReportDesc_FieldIndex2_Plus1, "distance_AT")
+    };
+
+    static const NuBrickField::IndexName sonar_input_field_index_name_arr[] = {
+        NuBrickField::IndexName(NuBrick_ReportDesc_FieldIndex1_Plus1, "distance"),
+        NuBrickField::IndexName(NuBrick_ReportDesc_FieldIndex2_Plus1, "over_flag")
+    };
+
+    // Add fields of feature report
+    add_feature_fields(sonar_feature_field_index_name_arr,
+        sizeof (sonar_feature_field_index_name_arr) / sizeof (sonar_feature_field_index_name_arr[0]));
+        
+    // Add fields of input report
+    add_input_fields(sonar_input_field_index_name_arr,
+        sizeof (sonar_input_field_index_name_arr) / sizeof (sonar_input_field_index_name_arr[0]));
+        
+    // Add fields of output report
+    
+    // No lock needed in the constructor
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/NuMaker-mbed-NuBrick/NuBrickMasterSonar.h	Fri Sep 29 05:44:02 2017 +0000
@@ -0,0 +1,48 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2016 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef NUBRICK_MASTER_SONAR_H
+#define NUBRICK_MASTER_SONAR_H
+
+#include "mbed.h"
+#include "NuBrickMaster.h"
+
+
+/** A NuMaker Brick I2C master, used for communicating with NuMaker Brick I2C slave module Sonar
+ *
+ * @Note Synchronization level: Thread safe
+ *
+ * @details Support fields for access through [] operator:
+ *          - feature.sleep_period
+ *          - feature.distance_AT
+ *          - input.distance
+ *          - input.over_flag
+ */
+class NuBrickMasterSonar : public NuBrickMaster {
+
+public:
+
+    /** Create an I2C interface, connected to the specified pins
+     *
+     *  @param i2c I2C object
+     */
+    NuBrickMasterSonar(I2C &i2c, bool debug);
+
+    virtual ~NuBrickMasterSonar() {
+        // Do nothing
+    }
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/NuMaker-mbed-NuBrick/NuBrickMasterTemp.cpp	Fri Sep 29 05:44:02 2017 +0000
@@ -0,0 +1,46 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2016 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "NuBrickMasterTemp.h"
+
+NuBrickMasterTemp::NuBrickMasterTemp(I2C &i2c, bool debug) :
+    NuBrickMaster(i2c, NuBrick_I2CAddr_Temp, debug) {
+
+    static const NuBrickField::IndexName temp_feature_field_index_name_arr[] = {
+        NuBrickField::IndexName(NuBrick_ReportDesc_FieldIndex1_Plus1, "sleep_period"),
+        NuBrickField::IndexName(NuBrick_ReportDesc_FieldIndex2_Plus1, "temp_AT"),
+        NuBrickField::IndexName(NuBrick_ReportDesc_FieldIndex3_Plus1, "hum_AT")
+    };
+
+    static const NuBrickField::IndexName temp_input_field_index_name_arr[] = {
+        NuBrickField::IndexName(NuBrick_ReportDesc_FieldIndex1_Plus1, "temp"),
+        NuBrickField::IndexName(NuBrick_ReportDesc_FieldIndex2_Plus1, "hum"),
+        NuBrickField::IndexName(NuBrick_ReportDesc_FieldIndex3_Plus1, "temp_over_flag"),
+        NuBrickField::IndexName(NuBrick_ReportDesc_FieldIndex4_Plus1, "hum_over_flag")
+    };
+
+    // Add fields of feature report
+    add_feature_fields(temp_feature_field_index_name_arr,
+        sizeof (temp_feature_field_index_name_arr) / sizeof (temp_feature_field_index_name_arr[0]));
+        
+    // Add fields of input report
+    add_input_fields(temp_input_field_index_name_arr,
+        sizeof (temp_input_field_index_name_arr) / sizeof (temp_input_field_index_name_arr[0]));
+        
+    // Add fields of output report
+ 
+    // No lock needed in the constructor
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/NuMaker-mbed-NuBrick/NuBrickMasterTemp.h	Fri Sep 29 05:44:02 2017 +0000
@@ -0,0 +1,51 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2016 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef NUBRICK_MASTER_TEMP_H
+#define NUBRICK_MASTER_TEMP_H
+
+#include "mbed.h"
+#include "NuBrickMaster.h"
+
+
+/** A NuMaker Brick I2C master, used for communicating with NuMaker Brick I2C slave module Temperature & Humidity
+ *
+ * @Note Synchronization level: Thread safe
+ *
+ * @details Support fields for access through [] operator:
+ *          - feature.sleep_period
+ *          - feature.temp_AT
+ *          - feature.hum_AT
+ *          - input.temp
+ *          - input.hum
+ *          - input.tem_over_flag
+ *          - input.hum_over_flag
+ */
+class NuBrickMasterTemp : public NuBrickMaster {
+
+public:
+
+    /** Create an I2C interface, connected to the specified pins
+     *
+     *  @param i2c I2C object
+     */
+    NuBrickMasterTemp(I2C &i2c, bool debug);
+
+    virtual ~NuBrickMasterTemp() {
+        // Do nothing
+    }
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/NuMaker-mbed-NuBrick/README.md	Fri Sep 29 05:44:02 2017 +0000
@@ -0,0 +1,83 @@
+# NuMaker-mbed-NuBrick
+This library contains mbed implementation of [NuMaker Brick](http://www.nuvoton.com/hq/support/tool-and-software/development-tool-hardware/numaker-brick/?__locale=en) I2C protocol to communicate with NuMaker Brick slave modules.
+To see how this library is used in practice, we created a [NuMaker Brick example](https://developer.mbed.org/teams/Nuvoton/code/NuMaker-mbed-NuBrick-example/) to show how mbed enabled boards could communicate with NuMaker Brick slave modules.
+
+## Support NuMaker Brick slave modules
+- Buzzer
+- LED
+- AHRS
+- Sonar
+- Temperature & Humidity
+- Gas
+- IR
+- Keys
+
+## HID-like protocol on I2C bus
+To communicate with the outside, NuMaker Brick platform defines simplified HID-like protocol on I2C bus. NuMaker Brick slave modules run as I2C slaves.
+This library encapsulates master side logic. Through this library, users can communicate with NuMaker Brick slave modules without needing to know the protocol in detail.
+
+## I2C
+To communicate with NuMaker Brick slave devices, users need to instantiate respective `NuBrickMaster` objects with `I2C` object passed in to its constructor.
+For example, instantiate `NuBrickMasterBuzzer` object to communicate with the NuMaker Brick slave device _Buzzer_.
+```
+I2C i2c(D14, D15);
+NuBrickMasterBuzzer master_buzzer(i2c, true);       // Debug enabled
+```
+
+## Reports and Fields
+NuMaker Brick slave modules export three types of reports to the outside. Each report consists of one or more fields.
+
+### Types of reports
+1. Feature report. Bidirectional. Used to configure NuMaker Brick slave modules.
+1. Input report. Unidirectional. Used to receive e.g. sensor data from NuMaker Brick slave modules.
+1. Output report. Unidirectional. Used to send e.g. trigger command to NuMaker Brick slave modules.
+
+### Fields
+A `NuBrickMaster` object exports associative array interface to access a field. Through the interface, users can:
+- Get minimum value of the field
+- Get maximum value of the field
+- Get/Set value of the field
+
+To access a specific field in a NuMaker Brick slave module, users need to pass field name in _report.field_ format into the C++ [] operator.
+Here, _report_ could only be _feature_, _input_, or _output_. For supported _report.field_ names in a NuMaker Brick slave module,
+please refer to respective `NuBrickMasterXxx.h` file in this library. For detailed description of each field, please refer to
+[user manual](http://www.nuvoton-m0.com/forum.php?mod=attachment&aid=MjI1OHw5MzU0ZDYzYXwxNDgwMDQ3NDEzfDB8MTcxMw%3D%3D)
+in the [zh-cn link](http://www.nuvoton-m0.com/forum.php?mod=viewthread&tid=1713&extra=page%3D1).
+
+### Example: configure the NuMaker Brick slave module Buzzer
+
+1. Pull in feature report from the module.
+
+    ```
+    master_buzzer.pull_feature_report();
+    ```
+1. Update fields of the feature report locally.
+
+    ```
+    master_buzzer["feature.sleep_period"].set_value(100);
+    master_buzzer["feature.volume"].set_value(60);          // Volume in %
+    master_buzzer["feature.tone"].set_value(196);           // Tone in Hz
+    master_buzzer["feature.song"].set_value(0);             // 0 (mono), 1 (Bee)
+    master_buzzer["feature.period"].set_value(200);         // Period in ms
+    master_buzzer["feature.duty"].set_value(30);            // Duty in %
+    master_buzzer["feature.latency"].set_value(3);          // Alarm for time secs
+    ```
+1. Push out the updated feature report to the module.
+
+    ```
+    master_buzzer.push_feature_report();,
+    ```
+    
+### Example: sound the NuMaker Brick slave module Buzzer
+
+1. Update fields of the output report locally.
+
+    ```
+    master_buzzer["output.start_flag"].set_value(1);
+    master_buzzer["output.stop_flag"].set_value(0);
+    ```
+1. Push out the updated output report to the module.
+
+    ```
+    master_buzzer.push_output_report();
+    ```
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/NuMaker-mbed-NuBrick/nubrick.h	Fri Sep 29 05:44:02 2017 +0000
@@ -0,0 +1,29 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2015-2016 Nuvoton
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef NUBRICK_H
+#define NUBRICK_H
+
+#include "NuBrickMasterBuzzer.h"
+#include "NuBrickMasterLED.h"
+#include "NuBrickMasterAHRS.h"
+#include "NuBrickMasterSonar.h"
+#include "NuBrickMasterTemp.h"
+#include "NuBrickMasterGas.h"
+#include "NuBrickMasterIR.h"
+#include "NuBrickMasterKeys.h"
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/NuMaker-mbed-NuBrick/nubrick_prot.h	Fri Sep 29 05:44:02 2017 +0000
@@ -0,0 +1,110 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2015-2016 Nuvoton
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef NUBRICK_PROT_H
+#define NUBRICK_PROT_H
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Predefined I2C addresses for NuMaker Brick I2C slave devices
+ */
+enum NuBrick_I2CAddr {
+    NuBrick_I2CAddr_Buzzer          = 0x15 << 1,
+    NuBrick_I2CAddr_LED             = 0x16 << 1,
+    NuBrick_I2CAddr_AHRS            = 0x17 << 1,
+    NuBrick_I2CAddr_Sonar           = 0x18 << 1,
+    NuBrick_I2CAddr_Temp            = 0x19 << 1,
+    NuBrick_I2CAddr_Gas             = 0x1A << 1,
+    NuBrick_I2CAddr_IR              = 0x1B << 1,
+    NuBrick_I2CAddr_Key             = 0x1C << 1,
+    NuBrick_I2CAddr_Reserved9       = 0x1D << 1,
+    NuBrick_I2CAddr_Reserved10      = 0x1E << 1,
+    NuBrick_I2CAddr_Reserved11      = 0x1F << 1,
+    NuBrick_I2CAddr_Reserved12      = 0x20 << 1,
+    NuBrick_I2CAddr_Reserved13      = 0x21 << 1,
+    NuBrick_I2CAddr_Reserved14      = 0x22 << 1,
+};
+
+/** NuMaker Brick protocol: command code
+ */
+enum NuBrick_Comm {
+    NuBrick_Comm_None               = 0,
+    NuBrick_Comm_GetDeviceDesc      = 1,    // Get device descriptor
+    NuBrick_Comm_GetReportDesc      = 2,    // Get report descriptor (feature/input/output)
+    NuBrick_Comm_GetInputReport     = 3,    // Get input report
+    NuBrick_Comm_SetOutputReport    = 4,    // Set output report
+    NuBrick_Comm_GetFeatureReport   = 5,    // Get feature report
+    NuBrick_Comm_SetFeatureReport   = 6,    // Set feature report
+};
+
+/** NuMaker Brick protocol: descriptor type
+ */
+enum NuBrick_DescType {
+    NuBrick_DescType_FeatureReport  = 257,
+    NuBrick_DescType_InputReport    = 258,
+    NuBrick_DescType_OutputReport   = 259,
+};
+
+/** NuMaker Brick protocol: report descriptor
+ */
+enum NuBrick_ReportDesc {
+    NuBrick_ReportDesc_Min_Plus1   = 9,
+    NuBrick_ReportDesc_Min_Plus2   = 10,
+    NuBrick_ReportDesc_Max_Plus1   = 13,
+    NuBrick_ReportDesc_Max_Plus2   = 14,
+    
+    NuBrick_ReportDesc_FieldIndex1_Plus1    = 5,
+    NuBrick_ReportDesc_FieldIndex2_Plus1    = 17,
+    NuBrick_ReportDesc_FieldIndex3_Plus1    = 29,
+    NuBrick_ReportDesc_FieldIndex4_Plus1    = 41,
+    NuBrick_ReportDesc_FieldIndex5_Plus1    = 53,
+    NuBrick_ReportDesc_FieldIndex6_Plus1    = 65,
+    NuBrick_ReportDesc_FieldIndex7_Plus1    = 77,
+    NuBrick_ReportDesc_FieldIndex8_Plus1    = 89,
+    NuBrick_ReportDesc_FieldIndex9_Plus1    = 101,
+    NuBrick_ReportDesc_FieldIndex10_Plus1   = 113,
+};
+
+enum {
+    NuBrick_DeviceDesc_Len          = 26,   // Device descriptor length
+};
+
+struct NuBrick_Device_Descriptor {
+    uint16_t dev_desc_len;                  // Device descriptor length
+    uint16_t report_desc_len;               // Report descriptor length
+    uint16_t input_report_len;              // Input report length
+    uint16_t output_report_len;             // Output report length
+    uint16_t getfeat_report_len;            // Get feature report length
+    uint16_t setfeat_report_len;            // Set feature report length
+    uint16_t cid;                           // Company ID
+    uint16_t did;                           // Device ID
+    uint16_t pid;                           // Product ID
+    uint16_t uid;                           // Product ID
+    uint16_t ucid;                          // Product ID
+    uint16_t reserved1;                     // Reserved 1
+    uint16_t reserved2;                     // Reserved 2
+};
+
+    
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/README.md	Fri Sep 29 05:44:02 2017 +0000
@@ -0,0 +1,16 @@
+# Getting started sample with I2C slave device on mbed OS
+
+
+### Import NuMaker-mbed-NuBrick-example from on-line IDE
+1. Please choose Nuvoton NuMaker-PFM-XXX as your target platform.
+2. Please press the left-up icon "New", then choose "NuMaker Brick I2C slave devices" from the template list.
+3. Your NuMaker-mbed-NuBrick-example program is existed.
+
+#### Now compile
+Please press compile icon.
+
+#### Burn Code & Execute
+1. Connect the board NuMaker-PFM-XXX with your PC by USB cable, then there will be one "mbed" disk.
+2. Copy the built binary file into "mbed" disk on you PC.
+3. Press device's reset button to execute, user could test I2C slave devices.
+   
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Fri Sep 29 05:44:02 2017 +0000
@@ -0,0 +1,216 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2016 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mbed.h"
+#include "nubrick.h"
+ 
+#if defined(TARGET_NUMAKER_PFM_NUC472)
+I2C i2c(D14, D15);
+
+#elif defined(TARGET_NUMAKER_PFM_M453)
+I2C i2c(D14, D15);
+
+#elif defined(TARGET_NUMAKER_PFM_M487)
+I2C i2c(D14, D15);   // in M487 D14 is SDA, D15 is SCL
+#endif
+
+/** Connect to one NuBrick slave via NuBrick master object
+ */
+#define NUBRICK_CONNECT(MASTER, NAME)                                   \
+    do {                                                                \
+        printf("\r\n\r\n");                                             \
+        if (! MASTER.connect()) {                                       \
+            printf("Connect to NuBrick:\t\t"NAME" failed\r\n\r\n");     \
+            return;                                                     \
+        }                                                               \
+        else {                                                          \
+            printf("Connect to NuBrick:\t\t"NAME" OK\r\n\r\n");         \
+            MASTER.print_device_desc();                                 \
+        }                                                               \
+    } while (0);
+
+/** Define NuBrick master objects to communicate with NuBrick slave devices
+ */
+NuBrickMasterBuzzer master_buzzer(i2c, true);
+NuBrickMasterLED master_led(i2c, true);
+NuBrickMasterAHRS master_ahrs(i2c, true);
+NuBrickMasterSonar master_sonar(i2c, true);
+NuBrickMasterTemp master_temp(i2c, true);
+NuBrickMasterGas master_gas(i2c, true);
+NuBrickMasterIR master_ir(i2c, true);
+NuBrickMasterKeys master_keys(i2c, true);
+
+/** Test NuBrick slave devices
+ */
+void test_nubrick_buzzer(void);
+void test_nubrick_led(void);
+void test_nubrick_ahrs(void);
+void test_nubrick_sonar(void);
+void test_nubrick_temp(void);
+void test_nubrick_gas(void);
+void test_nubrick_ir(void);
+void test_nubrick_keys(void);
+
+int main() {
+    
+    // Test all supported NuBrick slave devices
+    test_nubrick_buzzer();
+    test_nubrick_led();
+    test_nubrick_ahrs();
+    test_nubrick_sonar();
+    test_nubrick_temp();
+    test_nubrick_gas();
+    test_nubrick_ir();
+    test_nubrick_keys();
+
+    return 0;
+}
+
+void test_nubrick_buzzer(void) {
+    
+    NUBRICK_CONNECT(master_buzzer, "Buzzer");
+
+    // Configure the Buzzer
+    master_buzzer.pull_feature_report();
+    master_buzzer["feature.sleep_period"].set_value(100);
+    master_buzzer["feature.volume"].set_value(60);          // Volume in %
+    master_buzzer["feature.tone"].set_value(196);           // Tone in Hz
+    master_buzzer["feature.song"].set_value(0);             // 0 (mono), 1 (Bee)
+    master_buzzer["feature.period"].set_value(200);         // Period in ms
+    master_buzzer["feature.duty"].set_value(30);            // Duty in %
+    master_buzzer["feature.latency"].set_value(3);          // Alarm for time secs
+    master_buzzer.push_feature_report();
+    
+    // The NuBrick I2C device may not respond in time. Add delay here.
+    wait_ms(50);
+    
+    // Start sounding the buzzer
+    master_buzzer["output.start_flag"].set_value(1);
+    master_buzzer["output.stop_flag"].set_value(0);
+    master_buzzer.push_output_report();
+}
+
+void test_nubrick_led(void) {
+    
+    NUBRICK_CONNECT(master_led, "LED");
+     
+    // Configure the LED
+    master_led.pull_feature_report();
+    master_led["feature.sleep_period"].set_value(100);
+    master_led["feature.brightness"].set_value(30);         // Brightness in %
+    master_led["feature.color"].set_value(0xF0);            // 0x0F: full blue, 0xF0: full green, 0x0F00: full red
+    master_led["feature.blink"].set_value(0);               // Blink method: 0: blink to setting, 1: blink to the song Bee
+    master_led["feature.period"].set_value(500);            // Blink period in ms
+    master_led["feature.duty"].set_value(30);               // Blink duty in %
+    master_led["feature.latency"].set_value(1);             // Blink for time in secs
+    master_led.push_feature_report();
+    
+    // The NuBrick I2C device may not respond in time. Add delay here.
+    wait_ms(50);
+    
+    // Start blinking the LED
+    master_led["output.start_flag"].set_value(1);
+    master_led["output.stop_flag"].set_value(0);
+    master_led.push_output_report();
+}
+
+void test_nubrick_ahrs(void) {
+    
+    NUBRICK_CONNECT(master_ahrs, "AHRS");
+    
+    master_ahrs.pull_feature_report();    
+    // Prescaled vibration alarm threshold
+    printf("Prescaled vibration alarm threshold\t\t%d\r\n", master_ahrs["feature.pre_vibration_AT"].get_value());
+    
+    master_ahrs.pull_input_report();
+    // Detected vibration
+    printf("Detected vibration\t\t\t\t%d\r\n", master_ahrs["input.vibration"].get_value());
+}
+
+void test_nubrick_sonar(void) {
+    
+    NUBRICK_CONNECT(master_sonar, "Sonar");
+    
+    master_sonar.pull_feature_report();
+    // Distance alarm threshold in cm
+    printf("Distance alarm threshold\t\t%d\r\n", master_sonar["feature.distance_AT"].get_value());
+    
+    master_sonar.pull_input_report();
+    // Detected distance in cm
+    printf("Detected distance\t\t\t%d\r\n", master_sonar["input.distance"].get_value());
+}
+
+void test_nubrick_temp(void) {
+    
+    NUBRICK_CONNECT(master_temp, "Temperature & Humidity");
+    
+    master_temp.pull_feature_report();
+    // Temp. alarm threshold in Celsius
+    printf("Temp. alarm threshold\t\t%d\r\n", master_temp["feature.temp_AT"].get_value());
+    // Hum. alarm threshold in %
+    printf("Hum. alarm threshold\t\t%d\r\n", master_temp["feature.hum_AT"].get_value());
+    
+    master_temp.pull_input_report();
+    // Detected temp in Celsius
+    printf("Detected temp.\t\t\t%d\r\n", master_temp["input.temp"].get_value());
+    // Detected hum. in %
+    printf("Detected hum.\t\t\t%d\r\n", master_temp["input.hum"].get_value());
+}
+
+void test_nubrick_gas(void) {
+    
+    NUBRICK_CONNECT(master_gas, "Gas");
+    
+    master_gas.pull_feature_report();
+    // Gas alarm threshold in %.
+    printf("Gas alarm threshold\t\t%d\r\n", master_gas["feature.gas_AT"].get_value());
+    
+    master_gas.pull_input_report();
+    // Detected gas in %. 80% above for normal.
+    printf("Gas\t\t\t\t%d\r\n", master_gas["input.gas"].get_value());
+}
+
+void test_nubrick_ir(void) {
+    
+    NUBRICK_CONNECT(master_ir, "IR");
+    
+    master_ir.pull_feature_report();
+    printf("Number of learned data\t\t%d\r\n", master_ir["feature.num_learned_data"].get_value());
+    printf("Using data type\t\t\t%d\r\n", master_ir["feature.using_data_type"].get_value());
+    printf("Index of original data to send\t%d\r\n", master_ir["feature.index_orig_data_to_send"].get_value());
+    printf("Index of learned data to send\t%d\r\n", master_ir["feature.index_learned_data_to_send"].get_value());
+    
+    master_ir.pull_input_report();
+    printf("Has received data flag\t\t%d\r\n", master_ir["input.received_data_flag"].get_value());
+}
+
+void test_nubrick_keys(void) {
+    
+    NUBRICK_CONNECT(master_keys, "Key");
+    
+    // Detect 8 keys
+    master_keys.pull_input_report();
+    uint16_t key_state = master_keys["input.key_state"].get_value();
+    unsigned i = 0;
+    for (i = 0; i < 8; i ++) {
+        if (key_state & (1 << i)) {
+            printf("KEY%d PRESSED\r\n", i + 1);
+        }
+        else {
+           printf("KEY%d RELEASED\r\n", i + 1);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-os.lib	Fri Sep 29 05:44:02 2017 +0000
@@ -0,0 +1,1 @@
+https://github.com/ARMmbed/mbed-os/#ca661f9d28526ca8f874b05432493a489c9671ea