Ray Liu
/
NuMaker-mbed-NuBrick-example
Modify the file main.cpp for M487
Revision 0:a67fc999dd68, committed 2017-09-29
- 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
--- /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