From c9caa5ffc9e8d82c2637004861ff4c1126551d8d Mon Sep 17 00:00:00 2001 From: Nick Date: Sat, 22 May 2021 15:36:42 -0400 Subject: [PATCH 1/9] Move from assumed-installed pip filepaths to local filepaths --- cloudbuild-deploy.yaml | 2 +- cloudbuild.yaml | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/cloudbuild-deploy.yaml b/cloudbuild-deploy.yaml index d8e370d..d8021aa 100644 --- a/cloudbuild-deploy.yaml +++ b/cloudbuild-deploy.yaml @@ -26,7 +26,7 @@ steps: args: - 'cyanobyte/codegen.py' - '-t' - - 'doc' + - 'cyanobyte-templates/doc.md' - '-o' - './docs/content/docs/Reference/Peripheral Docs' - 'peripherals/ADS1015.yaml' diff --git a/cloudbuild.yaml b/cloudbuild.yaml index ea51db4..0aa6a47 100644 --- a/cloudbuild.yaml +++ b/cloudbuild.yaml @@ -29,15 +29,17 @@ steps: args: - 'cyanobyte/codegen.py' - '-t' - - 'raspberrypi' + - 'cyanobyte-templates/raspberrypi.py' - '-t' - - 'arduino' + - 'cyanobyte-templates/arduino.cpp' + - '-t' + - 'cyanobyte-templates/arduino.h' - '-t' - 'templates/kubos.c' - '-t' - - 'cmsis' + - 'cyanobyte-templates/cmsis.svg' - '-t' - - 'datasheet' + - 'cyanobyte-templates/datasheet.tex' - '-e' - '/workspace/emboss' - '-o' From 2af451aee877ced5d362bab34d983c876eb94274 Mon Sep 17 00:00:00 2001 From: Nick Date: Sat, 22 May 2021 15:37:44 -0400 Subject: [PATCH 2/9] Fix Kubos --- cloudbuild.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloudbuild.yaml b/cloudbuild.yaml index 0aa6a47..a3f1fd3 100644 --- a/cloudbuild.yaml +++ b/cloudbuild.yaml @@ -35,7 +35,7 @@ steps: - '-t' - 'cyanobyte-templates/arduino.h' - '-t' - - 'templates/kubos.c' + - 'cyanobyte-templates/kubos.c' - '-t' - 'cyanobyte-templates/cmsis.svg' - '-t' From 8e032e71c53f6069914d512f8d2457203d33f41d Mon Sep 17 00:00:00 2001 From: Nick Date: Sat, 22 May 2021 16:56:59 -0400 Subject: [PATCH 3/9] Start Pigweed template C++ source and header files Test with BMP180 and Example peripherals --- cyanobyte-templates/pigweed.cpp | 230 ++++++++++++++++++++++++++++ cyanobyte-templates/pigweed.h | 108 +++++++++++++ test/sampleData/pigweed/BMP180.cpp | 208 +++++++++++++++++++++++++ test/sampleData/pigweed/BMP180.h | 135 ++++++++++++++++ test/sampleData/pigweed/Example.cpp | 184 ++++++++++++++++++++++ test/sampleData/pigweed/Example.h | 148 ++++++++++++++++++ 6 files changed, 1013 insertions(+) create mode 100644 cyanobyte-templates/pigweed.cpp create mode 100644 cyanobyte-templates/pigweed.h create mode 100644 test/sampleData/pigweed/BMP180.cpp create mode 100644 test/sampleData/pigweed/BMP180.h create mode 100644 test/sampleData/pigweed/Example.cpp create mode 100644 test/sampleData/pigweed/Example.h diff --git a/cyanobyte-templates/pigweed.cpp b/cyanobyte-templates/pigweed.cpp new file mode 100644 index 0000000..454741c --- /dev/null +++ b/cyanobyte-templates/pigweed.cpp @@ -0,0 +1,230 @@ +{% import 'macros.jinja2' as utils %} +{% import 'base.c.jinja2' as cpp %} +{% set template = namespace(enum=false, sign=false, math=false, struct=false) %} +/* +{{ utils.pad_string('* ', utils.license(info.copyright.name, info.copyright.date, info.license.name)) -}} +* +* Auto-generated file for {{ info.title }} v{{ info.version }}. +* Generated from {{ fileName }} using Cyanobyte Codegen v{{ version }} +* Class for {{ info.title }} +{{utils.pad_string("* ", info.description)}} +*/ + +{% macro logic(logicalSteps, function) -%} + +{% for step in logicalSteps %} +{% for key in step.keys() %} +{# // Check if a raw read-op #} +{% if step[key] is mapping and 'rawRead' in step[key] %} + {% set bytes = (step[key].rawRead / 8) | round(1, 'ceil') | int %} + ByteBuffer byte_buffer; + + // can i even call this? + PutRegisterAddressInByteBuffer( + byte_buffer, DEVICE_ADDRESS, order_, register_address_size_ + ) + + if (!byte_buffer.ok()) { + return pw::Status::Internal() + } + + ByteSpan return_data; + + WriteReadFor(byte_buffer.data(), byte_buffer.size(), + return_data.data(), return_data.size(), std::chrono::seconds(1)); + + uint8_t _datum; + _datum = return_data.data(); + {{key}} = _datum; // Post-process? + {% break %} +{% endif %} +{# // Check if assignment is a send-op #} +{% if key == '$cmdWrite' %} + {% if 'value' in step[key] %} + write{{step[key].register[12:]}}({{step[key].value}}); + {% else %} + write{{step[key].register[12:]}}(); + {% endif %} + {% break %} +{% endif %} +{% if key == "$delay" %} + {# Blocking impl #} + _time_pt = TimePointAfterAtLeast({{step[key].for}}); + while (SystemClock::now() < _time_pt) {} +{{ logic(step[key].after, function) }} + {% break %} +{% endif %} +{# // Check if assignment op #} +{% if step[key] is string and step[key][0:1] == "=" %} + {{key}} {{step[key]}}; +{% endif %} +{# // Check if assignment is a send-op #} +{% if key == 'send' %} + write{{function.register[12:]}}({{step[key]}}); +{% endif %} +{# // Check if assignment is register read op #} +{% if step[key] is string and step[key][:12] == '#/registers/' %} + {{key}} = read{{step[key][12:]}}(); +{% endif %} +{# // Check if assignment is function call op #} +{% if step[key] is string and step[key][:12] == '#/functions/' %} + {{key}} = {{step[key] | regex_replace('#/functions/(?P.+)/(?P.+)', '\\g\\g')}}(); +{% endif %} +{# // If the value is a list, then this is a logical setter #} +{% if step[key] is iterable and step[key] is not string %} + {{key}} = {{cpp.recursiveAssignLogic(step[key][0], step[key][0].keys()) -}}; +{% endif %} +{% endfor %} +{% endfor %} +{%- endmacro %} + +{% if i2c.endian == 'little' %} +static short _swap_endian(short val) { + // Swap the endianness of a short only + return (val & 0xFF00) >> 8 | (val & 0xFF) << 8; +} +{% endif %} + +{# Add signing function if needed #} +{% for key,register in registers|dictsort %} +{% if register.signed %} +{% if template.sign is sameas false %} +static short _sign(short val, char length) { + // Convert unsigned integer to signed integer + if (val & (1 << (length - 1))) { + return val - (1 << length); + } + return val; +} +{% set template.sign = true %} +{% endif %} +{% endif %} +{% endfor %} + +{% if i2c.address is number %} +#define DEVICE_ADDRESS {{i2c.address}} +{% endif %} + +{% for key,register in registers|dictsort %} +#define REGISTER_{{key.upper()}} {{register.address}} +{% endfor %} + +{{info.title}}::{{info.title}}(Initiator& initiator, + {% if i2c.address is iterable and i2c.address is not string %}Address address{% endif %} + ): RegisterDevice(initiator, {% if i2c.address is iterable and i2c.address is not string %}Address address{% else %}Address({{i2c.address}}){% endif %}), +{% if i2c.endian == 'little' %} std::endian::little{% else %} std::endian::big{% endif %}, + {# FIXME #}register_address_size_(RegisterAddressSize::k1Byte) + ) { + {% if i2c.address is iterable and i2c.address is not string %} + DEVICE_ADDRESS ( address ) + {% endif %} + } + +{% for key,register in registers|dictsort -%} +{% set length = register.length %} +{% set bytes = (register.length / 8) | round(1, 'ceil') | int %} +{% if (not 'readWrite' in register) or ('readWrite' in register and 'R' is in(register.readWrite)) %} +Result<{{cpp.numtype(length)}}> {{info.title}}::read{{key}}() { + // Hard-coded timeout of 1s. + {% if length == 0 %} + return ReadRegister8(REGISTER_{{key.upper()}}, std::chrono::seconds(1)); + {% else %} + return ReadRegister{{length}}(REGISTER_{{key.upper()}}, std::chrono::seconds(1)); + {% endif %} +} +{% endif %} + +{% if (not 'readWrite' in register) or ('readWrite' in register and 'W' is in(register.readWrite)) %} +Status {{info.title}}::write{{key}}({% if length > 0 %}{{cpp.numtype(length)}} data{% endif %}) { + // Hard-coded timeout of 1s. + {% if length == 0 %} + return WriteRegister8(REGISTER_{{key.upper()}}, 0, std::chrono::seconds(1)) + {% else %} + return WriteRegister{{length}}(REGISTER_{{key.upper()}}, data, std::chrono::seconds(1)) + {% endif %} +} +{% endif %} + +{% endfor %} + +{% if fields %} +{% for key,field in fields|dictsort %} +{% if 'R' is in(field.readWrite) %} +{# Getter #} +Result<{{cpp.registerSize(registers, field.register[12:])}}> {{info.title}}::get{{key}}() { + // Read register data + // '#/registers/{{field.register[12:]}}' > '{{field.register[12:]}}' + Result<{{cpp.registerSize(registers, field.register[12:])}}> res = read{{field.register[12:]}}(); + {# Assume it is good #} + {{cpp.registerSize(registers, field.register[12:])}} val = res.value(); + // Mask register value + val = val & {{utils.mask(field.bitStart, field.bitEnd)}}; + {% if field.bitEnd %} + // Bitshift value + val = val >> {{field.bitEnd}}; + {% endif %} + // Rewrap in a Result + Result<{{cpp.registerSize(registers, field.register[12:])}}> result = new Result(val); + return result; +} +{% endif -%} + +{%- if 'W' is in(field.readWrite) %} +{# Setter #} + +Status {{info.title}}::set{{key}}(uint8_t data) { + {% if field.bitEnd %} + // Bitshift value + data = data << {{field.bitEnd}}; + {% endif %} + // Read current register data + // '#/registers/{{field.register[12:]}}' > '{{field.register[12:]}}' + Result<{{cpp.registerSize(registers, field.register[12:])}}> res = read{{field.register[12:]}}(); + {{cpp.registerSize(registers, field.register[12:])}} register_data = res.value() + register_data = register_data | data; + return write{{field.register[12:]}}(register_data); +} +{% endif %} +{% endfor %} +{% endif %} + +{% if functions %} +{% for key,function in functions|dictsort %} +{% for ckey,compute in function.computed|dictsort %} +{% if 'input' in compute %} +{{cpp.returnType(compute)}} {{info.title}}::{{key}}{{ckey}}({{cpp.params(compute)}}) { +{% else %} +{{cpp.returnType(compute)}} {{info.title}}::{{key}}{{ckey}}({{cpp.params(compute)}}) { +{% endif %} + {# Declare our variables #} +{{ cpp.variables(compute.variables) }} + + {# Read `value` if applicable #} + {% if 'input' in compute %} + {%- for vkey,variable in compute.input|dictsort %} + {% if vkey == 'value' %} + // Read value of register into a variable + {{cpp.numconv(variable)}} value = read{{function.register[12:]}}(); + {% endif %} + {% endfor %} + {% endif %} + {# Handle the logic #} +{{ logic(compute.logic, function) }} + + {# Return if applicable #} + {# Return a tuple #} + {% if 'return' in compute and compute.return is not string %} + {# In C languages, the array is a parameter `returnArray` you fill #} + {% for variable in compute.return %} + returnArray[{{loop.index - 1}}] = {{variable}}; + {% endfor %} + {% endif %} + {# Return a plain value #} + {% if compute.return is string %} + return {{compute.return}}; + {% endif %} +} + +{% endfor %} +{% endfor %} +{% endif %} diff --git a/cyanobyte-templates/pigweed.h b/cyanobyte-templates/pigweed.h new file mode 100644 index 0000000..150da7b --- /dev/null +++ b/cyanobyte-templates/pigweed.h @@ -0,0 +1,108 @@ +{% import 'macros.jinja2' as utils %} +{% import 'base.c.jinja2' as cpp %} +{% set template = namespace(math=false) %} +/* +{{ utils.pad_string('* ', utils.license(info.copyright.name, info.copyright.date, info.license.name)) -}} +* +* Auto-generated file for {{ info.title }} v{{ info.version }}. +* Generated from {{ fileName }} using Cyanobyte Codegen v{{ version }} +* Class for {{ info.title }} +{{utils.pad_string("* ", info.description)}} +*/ + +#pragma once + +#include "pw_bytes/byte_builder.h" +#include "pw_chrono/system_clock.h" +#include "pw_i2c/address.h" +#include "pw_i2c/device.h" +#include "pw_i2c/initiator.h" +#include "pw_result/result.h" +#include "pw_status/status.h" + +{# Create enums for fields #} +{% if fields %} +{% for key,field in fields|dictsort %} +{% if field.enum %} +{# Create enum #} +/* +{{utils.pad_string(" * ", "Valid values for " + field.title)}} + */ +enum {{key}} { + {% set args = namespace(index=0) %} + {% for ekey,enum in field.enum|dictsort %} + {{key.upper()}}_{{ekey.upper()}} = {{enum.value}}{{- "," if args.index + 1 < field.enum | length }} // {{enum.title}} + {% set args.index = args.index + 1 %} + {% endfor %} +}; +typedef enum {{key}} {{key}}_t; +{% endif %} +{% endfor %} +{% endif %} +{% if i2c.address is iterable and i2c.address is not string %} +enum deviceAddress { + {% for address in i2c.address %} + I2C_ADDRESS_{{address}} = {{address}}{{ "," if not loop.last }} + {% endfor %} +}; +typedef enum deviceAddress deviceAddress_t; +{% endif %} + +class {{info.title}} : RegisterDevice { + public: + {% if i2c.address is iterable and i2c.address is not string %} + {{info.title}}(Initiator& initiator, deviceAddress_t address); + deviceAddress_t DEVICE_ADDRESS; + {% else %} + {{info.title}}(Initiator& initiator); + {% endif %} + + {% for key,register in registers|dictsort -%} + {% set length = register.length %} + {% if (not 'readWrite' in register) or ('readWrite' in register and 'R' is in(register.readWrite)) %} + /** +{{utils.pad_string(" * ", register.description)}} + */ + Result<{{cpp.numtype(register.length)}}> read{{key}}(); + {% endif %} + + {% if (not 'readWrite' in register) or ('readWrite' in register and 'W' is in(register.readWrite)) %} + /** +{{utils.pad_string(" * ", register.description)}} + */ + Status write{{key}}({% if length > 0 %}{{cpp.numtype(length)}} data{% endif %});{% endif %} + + {% endfor %} + {% if fields %} + {% for key,field in fields|dictsort %} + {% if 'R' is in(field.readWrite) %} + /** +{{utils.pad_string(" * ", field.description)}} + */ + Result<{{cpp.registerSize(registers, field.register[12:])}}> get{{key}}(); + {% endif %} + {% if 'W' is in(field.readWrite) %} + /** +{{utils.pad_string(" * ", field.description)}} + */ + Status set{{key}}(uint8_t data); + {% endif %} + {% endfor %} + {% endif %} + + {% if functions %} + {% for key,function in functions|dictsort %} + {% for ckey,compute in function.computed|dictsort %} + /** +{{utils.pad_string(" * ", function.description)}} + */ + {% if 'input' in compute %} + {{cpp.returnType(compute)}} {{key}}{{ckey}}({{cpp.params(compute)}}); + {% else %} + {{cpp.returnType(compute)}} {{key}}{{ckey}}({{cpp.params(compute)}}); + {% endif %} + {% endfor %} + + {% endfor %} + {% endif %} +}; diff --git a/test/sampleData/pigweed/BMP180.cpp b/test/sampleData/pigweed/BMP180.cpp new file mode 100644 index 0000000..c9e6a61 --- /dev/null +++ b/test/sampleData/pigweed/BMP180.cpp @@ -0,0 +1,208 @@ +/* +* Copyright (C) 2020 Google Inc. +* +* 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. +* +* Auto-generated file for BMP180 v0.1.0. +* Generated from peripherals/BMP180.yaml using Cyanobyte Codegen v0.0.2 +* Class for BMP180 +* Bosch Digital Temperature / Pressure Sensor + +*/ + + + + +#define DEVICE_ADDRESS 119 + +#define REGISTER_CONTROL 244 +#define REGISTER_PRESSURECALAC1 170 +#define REGISTER_PRESSURECALAC2 172 +#define REGISTER_PRESSURECALVB1 182 +#define REGISTER_PRESSURECALVB2 184 +#define REGISTER_RESULT 246 +#define REGISTER_TEMPCAL3 174 +#define REGISTER_TEMPCAL4 176 +#define REGISTER_TEMPCAL5 178 +#define REGISTER_TEMPCAL6 180 +#define REGISTER_TEMPCALMC 188 +#define REGISTER_TEMPCALMD 190 + +BMP180::BMP180(Initiator& initiator, + ): RegisterDevice(initiator, Address(119)), + std::endian::big, +register_address_size_(RegisterAddressSize::k1Byte) + ) { + } + + +Status BMP180::writeControl(uint8_t data) { + // Hard-coded timeout of 1s. + return WriteRegister8(REGISTER_CONTROL, data, std::chrono::seconds(1)) +} + +Result BMP180::readPressureCalAC1() { + // Hard-coded timeout of 1s. + return ReadRegister16(REGISTER_PRESSURECALAC1, std::chrono::seconds(1)); +} + + +Result BMP180::readPressureCalAC2() { + // Hard-coded timeout of 1s. + return ReadRegister16(REGISTER_PRESSURECALAC2, std::chrono::seconds(1)); +} + + +Result BMP180::readPressureCalVB1() { + // Hard-coded timeout of 1s. + return ReadRegister16(REGISTER_PRESSURECALVB1, std::chrono::seconds(1)); +} + + +Result BMP180::readPressureCalVB2() { + // Hard-coded timeout of 1s. + return ReadRegister16(REGISTER_PRESSURECALVB2, std::chrono::seconds(1)); +} + + +Result BMP180::readResult() { + // Hard-coded timeout of 1s. + return ReadRegister16(REGISTER_RESULT, std::chrono::seconds(1)); +} + + +Result BMP180::readTempCal3() { + // Hard-coded timeout of 1s. + return ReadRegister16(REGISTER_TEMPCAL3, std::chrono::seconds(1)); +} + + +Result BMP180::readTempCal4() { + // Hard-coded timeout of 1s. + return ReadRegister16(REGISTER_TEMPCAL4, std::chrono::seconds(1)); +} + + +Result BMP180::readTempCal5() { + // Hard-coded timeout of 1s. + return ReadRegister16(REGISTER_TEMPCAL5, std::chrono::seconds(1)); +} + + +Result BMP180::readTempCal6() { + // Hard-coded timeout of 1s. + return ReadRegister16(REGISTER_TEMPCAL6, std::chrono::seconds(1)); +} + + +Result BMP180::readTempCalMC() { + // Hard-coded timeout of 1s. + return ReadRegister16(REGISTER_TEMPCALMC, std::chrono::seconds(1)); +} + + +Result BMP180::readTempCalMD() { + // Hard-coded timeout of 1s. + return ReadRegister16(REGISTER_TEMPCALMD, std::chrono::seconds(1)); +} + + + + +float BMP180::pressureasMbars() { + short ac1; // Variable declaration + short ac2; // Variable declaration + short ac3; // Variable declaration + uint16_t ac4; // Variable declaration + float b1; // Variable declaration + float c3; // Variable declaration + float c4; // Variable declaration + float p0; // Variable declaration + float p1; // Variable declaration + float p2; // Variable declaration + float pressure; // Variable declaration + float rawComp; // Variable declaration + float temperature; // Variable declaration + short vb1; // Variable declaration + short vb2; // Variable declaration + float x; // Variable declaration + float x1; // Variable declaration + float x2; // Variable declaration + float y; // Variable declaration + float y0; // Variable declaration + float y1; // Variable declaration + float y2; // Variable declaration + float z; // Variable declaration + + + writeControl(52); + pressure = readResult(); + temperature = temperatureasCelsius(); + _time_pt = TimePointAfterAtLeast(10); + while (SystemClock::now() < _time_pt) {} + rawComp = (temperature-25); + ac1 = readPressureCalAC1(); + ac2 = readPressureCalAC2(); + x1 = (160*pow(2, -13)*ac2); + vb2 = readPressureCalVB2(); + x2 = (pow(160, 2)*pow(2, -25)*vb2); + x = ((x2*pow(rawComp, 2))+(x1*rawComp)+ac1); + ac3 = readTempCal3(); + c3 = (160*pow(2, -15)*ac3); + ac4 = readTempCal4(); + c4 = (pow(10, -3)*pow(2, -15)*ac4); + vb1 = readPressureCalVB1(); + b1 = (pow(160, 2)*pow(2, -30)*vb1); + y0 = (c4*pow(2, 15)); + y1 = (c4*c3); + y2 = (c4*b1); + y = ((y2*pow(rawComp, 2))+(y1*rawComp)+y0); + z = ((pressure-x)/y); + p0 = ((3791-8)/1600); + p1 = (1-(7357*pow(2, -30))); + p2 = (3038*100*pow(2, -36)); + pressure = ((p2*pow(z, 2))+(p1*z)+p0); + + + + return pressure; +} + +float BMP180::temperatureasCelsius() { + short rawComp; // Variable declaration + short rawMc; // Variable declaration + short rawMd; // Variable declaration + float temperature; // Variable declaration + uint16_t varAc5; // Variable declaration + uint16_t varAc6; // Variable declaration + float varC5; // Variable declaration + float varMc; // Variable declaration + float varMd; // Variable declaration + + + writeControl(46); + temperature = readResult(); + varAc5 = readTempCal5(); + varAc6 = readTempCal6(); + varC5 = ((pow(2, -15)/160)*varAc5); + rawComp = (varC5*(temperature-varAc6)); + rawMc = readTempCalMC(); + varMc = ((pow(2, 11)/pow(160, 2))*rawMc); + rawMd = readTempCalMD(); + varMd = (rawMd/160); + temperature = (rawComp+(varMc/(rawComp+varMd))); + + + return temperature; +} + diff --git a/test/sampleData/pigweed/BMP180.h b/test/sampleData/pigweed/BMP180.h new file mode 100644 index 0000000..d6beff2 --- /dev/null +++ b/test/sampleData/pigweed/BMP180.h @@ -0,0 +1,135 @@ +/* +* Copyright (C) 2020 Google Inc. +* +* 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. +* +* Auto-generated file for BMP180 v0.1.0. +* Generated from peripherals/BMP180.yaml using Cyanobyte Codegen v0.0.2 +* Class for BMP180 +* Bosch Digital Temperature / Pressure Sensor + +*/ + +#pragma once + +#include "pw_bytes/byte_builder.h" +#include "pw_chrono/system_clock.h" +#include "pw_i2c/address.h" +#include "pw_i2c/device.h" +#include "pw_i2c/initiator.h" +#include "pw_result/result.h" +#include "pw_status/status.h" + + +class BMP180 : RegisterDevice { + public: + BMP180(Initiator& initiator); + + + /** + * Stores the current measurement type. + + */ + Status writeControl(uint8_t data); + /** + * Constant register for pressure measurement calibration. + + */ + Result readPressureCalAC1(); + + + /** + * Constant register for pressure measurement calibration. + + */ + Result readPressureCalAC2(); + + + /** + * Constant register for pressure measurement calibration. + + */ + Result readPressureCalVB1(); + + + /** + * Constant register for pressure measurement calibration. + + */ + Result readPressureCalVB2(); + + + /** + * Stores the most recent measurement result. + + */ + Result readResult(); + + + /** + * Third constant register for temperature measurement calibration. + + */ + Result readTempCal3(); + + + /** + * Fourth constant register for temperature measurement calibration. + + */ + Result readTempCal4(); + + + /** + * Fifth constant register for temperature measurement calibration. + + */ + Result readTempCal5(); + + + /** + * Sixth constant register for temperature measurement calibration. + + */ + Result readTempCal6(); + + + /** + * Constant register for temperature measurement calibration. + + */ + Result readTempCalMC(); + + + /** + * Constant register for temperature measurement calibration. + + */ + Result readTempCalMD(); + + + + /** + * Reads the pressure in absolute millibars, + * not compensated for sea level. + + */ + float pressureasMbars(); + + /** + * Reads the temperature as a raw value or in Celsius. + + */ + float temperatureasCelsius(); + +}; \ No newline at end of file diff --git a/test/sampleData/pigweed/Example.cpp b/test/sampleData/pigweed/Example.cpp new file mode 100644 index 0000000..3cacec5 --- /dev/null +++ b/test/sampleData/pigweed/Example.cpp @@ -0,0 +1,184 @@ +/* +* Copyright (C) 2019 Google Inc. +* +* 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. +* +* Auto-generated file for Example v0.1.0. +* Generated from peripherals/example.yaml using Cyanobyte Codegen v0.0.2 +* Class for Example +* Example of a package + +*/ + + + + + +#define REGISTER_REGISTERA 0 +#define REGISTER_REGISTERB 1 +#define REGISTER_REGISTERC 2 +#define REGISTER_REGISTERD 3 + +Example::Example(Initiator& initiator, +Address address ): RegisterDevice(initiator, Address address), + std::endian::big, +register_address_size_(RegisterAddressSize::k1Byte) + ) { + DEVICE_ADDRESS ( address ) + } + +Result Example::readRegisterA() { + // Hard-coded timeout of 1s. + return ReadRegister8(REGISTER_REGISTERA, std::chrono::seconds(1)); +} + +Status Example::writeRegisterA(uint8_t data) { + // Hard-coded timeout of 1s. + return WriteRegister8(REGISTER_REGISTERA, data, std::chrono::seconds(1)) +} + +Result Example::readRegisterB() { + // Hard-coded timeout of 1s. + return ReadRegister16(REGISTER_REGISTERB, std::chrono::seconds(1)); +} + +Status Example::writeRegisterB(uint16_t data) { + // Hard-coded timeout of 1s. + return WriteRegister16(REGISTER_REGISTERB, data, std::chrono::seconds(1)) +} + +Result Example::readRegisterC() { + // Hard-coded timeout of 1s. + return ReadRegister32(REGISTER_REGISTERC, std::chrono::seconds(1)); +} + +Status Example::writeRegisterC(uint32_t data) { + // Hard-coded timeout of 1s. + return WriteRegister32(REGISTER_REGISTERC, data, std::chrono::seconds(1)) +} + +Result Example::readRegisterD() { + // Hard-coded timeout of 1s. + return ReadRegister8(REGISTER_REGISTERD, std::chrono::seconds(1)); +} + +Status Example::writeRegisterD() { + // Hard-coded timeout of 1s. + return WriteRegister8(REGISTER_REGISTERD, 0, std::chrono::seconds(1)) +} + + +Result Example::getFieldA() { + // Read register data + // '#/registers/RegisterA' > 'RegisterA' + Result res = readRegisterA(); + uint8_t val = res.value(); + // Mask register value + val = val & 0b0000000011110000; + // Bitshift value + val = val >> 4; + // Rewrap in a Result + Result result = new Result(val); + return result; +} + +Status Example::setFieldB(uint8_t data) { + // Bitshift value + data = data << 2; + // Read current register data + // '#/registers/RegisterA' > 'RegisterA' + Result res = readRegisterA(); + uint8_t register_data = res.value() + register_data = register_data | data; + return writeRegisterA(register_data); +} +Result Example::getFieldC() { + // Read register data + // '#/registers/RegisterA' > 'RegisterA' + Result res = readRegisterA(); + uint8_t val = res.value(); + // Mask register value + val = val & 0b0000000000000010; + // Bitshift value + val = val >> 1; + // Rewrap in a Result + Result result = new Result(val); + return result; +} + +Status Example::setFieldC(uint8_t data) { + // Bitshift value + data = data << 1; + // Read current register data + // '#/registers/RegisterA' > 'RegisterA' + Result res = readRegisterA(); + uint8_t register_data = res.value() + register_data = register_data | data; + return writeRegisterA(register_data); +} + +char Example::_lifecycleBegin() { + char output; // Variable declaration + + + output = 1; + writeRegisterA(output); + + + return output; +} + +char Example::_lifecycleEnd() { + char output; // Variable declaration + + + output = 1; + writeRegisterA(output); + + + return output; +} + +void Example::ReturnArray(short * returnArray) { + short summation; // Variable declaration + + + summation = (1024+1024); + writeRegisterA(summation); + + + returnArray[0] = summation; + returnArray[1] = summation; +} + +short Example::ReturnNumber() { + short summation; // Variable declaration + + + summation = (1024+1024); + writeRegisterA(summation); + + + return summation; +} + +void Example::ReturnVoid() { + short summation; // Variable declaration + + + summation = (1024+1024); + writeRegisterA(summation); + + +} + diff --git a/test/sampleData/pigweed/Example.h b/test/sampleData/pigweed/Example.h new file mode 100644 index 0000000..6578ce2 --- /dev/null +++ b/test/sampleData/pigweed/Example.h @@ -0,0 +1,148 @@ +/* +* Copyright (C) 2019 Google Inc. +* +* 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. +* +* Auto-generated file for Example v0.1.0. +* Generated from peripherals/example.yaml using Cyanobyte Codegen v0.0.2 +* Class for Example +* Example of a package + +*/ + +#pragma once + +#include "pw_bytes/byte_builder.h" +#include "pw_chrono/system_clock.h" +#include "pw_i2c/address.h" +#include "pw_i2c/device.h" +#include "pw_i2c/initiator.h" +#include "pw_result/result.h" +#include "pw_status/status.h" + +/* + * Valid values for Write-only fields for RegisterA + + */ +enum FieldB { + FIELDB_VAL_1 = 1, // Value 1 + FIELDB_VAL_2 = 2, // Value 2 + FIELDB_VAL_3 = 4, // Value 3 + FIELDB_VAL_4 = 8 // Value 4 +}; +typedef enum FieldB FieldB_t; +enum deviceAddress { + I2C_ADDRESS_16 = 16, + I2C_ADDRESS_32 = 32, + I2C_ADDRESS_48 = 48 +}; +typedef enum deviceAddress deviceAddress_t; + +class Example : RegisterDevice { + public: + Example(Initiator& initiator, deviceAddress_t address); + deviceAddress_t DEVICE_ADDRESS; + + /** + * An 8-bit register + + */ + Result readRegisterA(); + + /** + * An 8-bit register + + */ + Status writeRegisterA(uint8_t data); + /** + * A 16-bit register + + */ + Result readRegisterB(); + + /** + * A 16-bit register + + */ + Status writeRegisterB(uint16_t data); + /** + * A 32-bit register + + */ + Result readRegisterC(); + + /** + * A 32-bit register + + */ + Status writeRegisterC(uint32_t data); + /** + * A dummy register that has no data + + */ + Result readRegisterD(); + + /** + * A dummy register that has no data + + */ + Status writeRegisterD(); + /** + * This is a few bits + + */ + Result getFieldA(); + /** + * This is fewer bits + + */ + Status setFieldB(uint8_t data); + /** + * A single-bit + + */ + Result getFieldC(); + /** + * A single-bit + + */ + Status setFieldC(uint8_t data); + + /** + * Enables features on device + + */ + char _lifecycleBegin(); + /** + * Enables features on device + + */ + char _lifecycleEnd(); + + /** + * Computes and returns + + */ + void ReturnArray(short * returnArray); + /** + * Computes and returns + + */ + short ReturnNumber(); + /** + * Computes and returns + + */ + void ReturnVoid(); + +}; \ No newline at end of file From ba3aa32a1d3b1cdbb98d33dbb2c9791a5f8843e2 Mon Sep 17 00:00:00 2001 From: Nick Date: Sat, 22 May 2021 16:58:25 -0400 Subject: [PATCH 4/9] Fix Arduino types --- cyanobyte-templates/arduino.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cyanobyte-templates/arduino.cpp b/cyanobyte-templates/arduino.cpp index d3a2a98..1cedd2f 100644 --- a/cyanobyte-templates/arduino.cpp +++ b/cyanobyte-templates/arduino.cpp @@ -179,7 +179,7 @@ int {{info.title}}::write{{key}}({% if length > 0 %}{{cpp.numtype(length)}} data {{cpp.registerSize(registers, field.register[12:])}} {{info.title}}::get{{key}}() { // Read register data // '#/registers/{{field.register[12:]}}' > '{{field.register[12:]}}' - uint8_t val = read{{field.register[12:]}}(); + {{cpp.registerSize(registers, field.register[12:])}} val = read{{field.register[12:]}}(); // Mask register value val = val & {{utils.mask(field.bitStart, field.bitEnd)}}; {% if field.bitEnd %} @@ -200,7 +200,7 @@ int {{info.title}}::set{{key}}(uint8_t data) { {% endif %} // Read current register data // '#/registers/{{field.register[12:]}}' > '{{field.register[12:]}}' - uint8_t register_data = read{{field.register[12:]}}(); + {{cpp.registerSize(registers, field.register[12:])}} register_data = read{{field.register[12:]}}(); register_data = register_data | data; return write{{field.register[12:]}}(register_data); } From ade324b493a84d531c3262e8054562da693f09ba Mon Sep 17 00:00:00 2001 From: Nick Felker Date: Sat, 22 May 2021 16:58:58 -0400 Subject: [PATCH 5/9] Start Pigweed template C++ source and header files Test with BMP180 and Example peripherals --- cyanobyte-templates/pigweed.cpp | 460 ++++++++++++++-------------- cyanobyte-templates/pigweed.h | 216 ++++++------- test/sampleData/pigweed/BMP180.cpp | 416 ++++++++++++------------- test/sampleData/pigweed/BMP180.h | 268 ++++++++-------- test/sampleData/pigweed/Example.cpp | 368 +++++++++++----------- test/sampleData/pigweed/Example.h | 294 +++++++++--------- 6 files changed, 1011 insertions(+), 1011 deletions(-) diff --git a/cyanobyte-templates/pigweed.cpp b/cyanobyte-templates/pigweed.cpp index 454741c..11c8e86 100644 --- a/cyanobyte-templates/pigweed.cpp +++ b/cyanobyte-templates/pigweed.cpp @@ -1,230 +1,230 @@ -{% import 'macros.jinja2' as utils %} -{% import 'base.c.jinja2' as cpp %} -{% set template = namespace(enum=false, sign=false, math=false, struct=false) %} -/* -{{ utils.pad_string('* ', utils.license(info.copyright.name, info.copyright.date, info.license.name)) -}} -* -* Auto-generated file for {{ info.title }} v{{ info.version }}. -* Generated from {{ fileName }} using Cyanobyte Codegen v{{ version }} -* Class for {{ info.title }} -{{utils.pad_string("* ", info.description)}} -*/ - -{% macro logic(logicalSteps, function) -%} - -{% for step in logicalSteps %} -{% for key in step.keys() %} -{# // Check if a raw read-op #} -{% if step[key] is mapping and 'rawRead' in step[key] %} - {% set bytes = (step[key].rawRead / 8) | round(1, 'ceil') | int %} - ByteBuffer byte_buffer; - - // can i even call this? - PutRegisterAddressInByteBuffer( - byte_buffer, DEVICE_ADDRESS, order_, register_address_size_ - ) - - if (!byte_buffer.ok()) { - return pw::Status::Internal() - } - - ByteSpan return_data; - - WriteReadFor(byte_buffer.data(), byte_buffer.size(), - return_data.data(), return_data.size(), std::chrono::seconds(1)); - - uint8_t _datum; - _datum = return_data.data(); - {{key}} = _datum; // Post-process? - {% break %} -{% endif %} -{# // Check if assignment is a send-op #} -{% if key == '$cmdWrite' %} - {% if 'value' in step[key] %} - write{{step[key].register[12:]}}({{step[key].value}}); - {% else %} - write{{step[key].register[12:]}}(); - {% endif %} - {% break %} -{% endif %} -{% if key == "$delay" %} - {# Blocking impl #} - _time_pt = TimePointAfterAtLeast({{step[key].for}}); - while (SystemClock::now() < _time_pt) {} -{{ logic(step[key].after, function) }} - {% break %} -{% endif %} -{# // Check if assignment op #} -{% if step[key] is string and step[key][0:1] == "=" %} - {{key}} {{step[key]}}; -{% endif %} -{# // Check if assignment is a send-op #} -{% if key == 'send' %} - write{{function.register[12:]}}({{step[key]}}); -{% endif %} -{# // Check if assignment is register read op #} -{% if step[key] is string and step[key][:12] == '#/registers/' %} - {{key}} = read{{step[key][12:]}}(); -{% endif %} -{# // Check if assignment is function call op #} -{% if step[key] is string and step[key][:12] == '#/functions/' %} - {{key}} = {{step[key] | regex_replace('#/functions/(?P.+)/(?P.+)', '\\g\\g')}}(); -{% endif %} -{# // If the value is a list, then this is a logical setter #} -{% if step[key] is iterable and step[key] is not string %} - {{key}} = {{cpp.recursiveAssignLogic(step[key][0], step[key][0].keys()) -}}; -{% endif %} -{% endfor %} -{% endfor %} -{%- endmacro %} - -{% if i2c.endian == 'little' %} -static short _swap_endian(short val) { - // Swap the endianness of a short only - return (val & 0xFF00) >> 8 | (val & 0xFF) << 8; -} -{% endif %} - -{# Add signing function if needed #} -{% for key,register in registers|dictsort %} -{% if register.signed %} -{% if template.sign is sameas false %} -static short _sign(short val, char length) { - // Convert unsigned integer to signed integer - if (val & (1 << (length - 1))) { - return val - (1 << length); - } - return val; -} -{% set template.sign = true %} -{% endif %} -{% endif %} -{% endfor %} - -{% if i2c.address is number %} -#define DEVICE_ADDRESS {{i2c.address}} -{% endif %} - -{% for key,register in registers|dictsort %} -#define REGISTER_{{key.upper()}} {{register.address}} -{% endfor %} - -{{info.title}}::{{info.title}}(Initiator& initiator, - {% if i2c.address is iterable and i2c.address is not string %}Address address{% endif %} - ): RegisterDevice(initiator, {% if i2c.address is iterable and i2c.address is not string %}Address address{% else %}Address({{i2c.address}}){% endif %}), -{% if i2c.endian == 'little' %} std::endian::little{% else %} std::endian::big{% endif %}, - {# FIXME #}register_address_size_(RegisterAddressSize::k1Byte) - ) { - {% if i2c.address is iterable and i2c.address is not string %} - DEVICE_ADDRESS ( address ) - {% endif %} - } - -{% for key,register in registers|dictsort -%} -{% set length = register.length %} -{% set bytes = (register.length / 8) | round(1, 'ceil') | int %} -{% if (not 'readWrite' in register) or ('readWrite' in register and 'R' is in(register.readWrite)) %} -Result<{{cpp.numtype(length)}}> {{info.title}}::read{{key}}() { - // Hard-coded timeout of 1s. - {% if length == 0 %} - return ReadRegister8(REGISTER_{{key.upper()}}, std::chrono::seconds(1)); - {% else %} - return ReadRegister{{length}}(REGISTER_{{key.upper()}}, std::chrono::seconds(1)); - {% endif %} -} -{% endif %} - -{% if (not 'readWrite' in register) or ('readWrite' in register and 'W' is in(register.readWrite)) %} -Status {{info.title}}::write{{key}}({% if length > 0 %}{{cpp.numtype(length)}} data{% endif %}) { - // Hard-coded timeout of 1s. - {% if length == 0 %} - return WriteRegister8(REGISTER_{{key.upper()}}, 0, std::chrono::seconds(1)) - {% else %} - return WriteRegister{{length}}(REGISTER_{{key.upper()}}, data, std::chrono::seconds(1)) - {% endif %} -} -{% endif %} - -{% endfor %} - -{% if fields %} -{% for key,field in fields|dictsort %} -{% if 'R' is in(field.readWrite) %} -{# Getter #} -Result<{{cpp.registerSize(registers, field.register[12:])}}> {{info.title}}::get{{key}}() { - // Read register data - // '#/registers/{{field.register[12:]}}' > '{{field.register[12:]}}' - Result<{{cpp.registerSize(registers, field.register[12:])}}> res = read{{field.register[12:]}}(); - {# Assume it is good #} - {{cpp.registerSize(registers, field.register[12:])}} val = res.value(); - // Mask register value - val = val & {{utils.mask(field.bitStart, field.bitEnd)}}; - {% if field.bitEnd %} - // Bitshift value - val = val >> {{field.bitEnd}}; - {% endif %} - // Rewrap in a Result - Result<{{cpp.registerSize(registers, field.register[12:])}}> result = new Result(val); - return result; -} -{% endif -%} - -{%- if 'W' is in(field.readWrite) %} -{# Setter #} - -Status {{info.title}}::set{{key}}(uint8_t data) { - {% if field.bitEnd %} - // Bitshift value - data = data << {{field.bitEnd}}; - {% endif %} - // Read current register data - // '#/registers/{{field.register[12:]}}' > '{{field.register[12:]}}' - Result<{{cpp.registerSize(registers, field.register[12:])}}> res = read{{field.register[12:]}}(); - {{cpp.registerSize(registers, field.register[12:])}} register_data = res.value() - register_data = register_data | data; - return write{{field.register[12:]}}(register_data); -} -{% endif %} -{% endfor %} -{% endif %} - -{% if functions %} -{% for key,function in functions|dictsort %} -{% for ckey,compute in function.computed|dictsort %} -{% if 'input' in compute %} -{{cpp.returnType(compute)}} {{info.title}}::{{key}}{{ckey}}({{cpp.params(compute)}}) { -{% else %} -{{cpp.returnType(compute)}} {{info.title}}::{{key}}{{ckey}}({{cpp.params(compute)}}) { -{% endif %} - {# Declare our variables #} -{{ cpp.variables(compute.variables) }} - - {# Read `value` if applicable #} - {% if 'input' in compute %} - {%- for vkey,variable in compute.input|dictsort %} - {% if vkey == 'value' %} - // Read value of register into a variable - {{cpp.numconv(variable)}} value = read{{function.register[12:]}}(); - {% endif %} - {% endfor %} - {% endif %} - {# Handle the logic #} -{{ logic(compute.logic, function) }} - - {# Return if applicable #} - {# Return a tuple #} - {% if 'return' in compute and compute.return is not string %} - {# In C languages, the array is a parameter `returnArray` you fill #} - {% for variable in compute.return %} - returnArray[{{loop.index - 1}}] = {{variable}}; - {% endfor %} - {% endif %} - {# Return a plain value #} - {% if compute.return is string %} - return {{compute.return}}; - {% endif %} -} - -{% endfor %} -{% endfor %} -{% endif %} +{% import 'macros.jinja2' as utils %} +{% import 'base.c.jinja2' as cpp %} +{% set template = namespace(enum=false, sign=false, math=false, struct=false) %} +/* +{{ utils.pad_string('* ', utils.license(info.copyright.name, info.copyright.date, info.license.name)) -}} +* +* Auto-generated file for {{ info.title }} v{{ info.version }}. +* Generated from {{ fileName }} using Cyanobyte Codegen v{{ version }} +* Class for {{ info.title }} +{{utils.pad_string("* ", info.description)}} +*/ + +{% macro logic(logicalSteps, function) -%} + +{% for step in logicalSteps %} +{% for key in step.keys() %} +{# // Check if a raw read-op #} +{% if step[key] is mapping and 'rawRead' in step[key] %} + {% set bytes = (step[key].rawRead / 8) | round(1, 'ceil') | int %} + ByteBuffer byte_buffer; + + // can i even call this? + PutRegisterAddressInByteBuffer( + byte_buffer, DEVICE_ADDRESS, order_, register_address_size_ + ) + + if (!byte_buffer.ok()) { + return pw::Status::Internal() + } + + ByteSpan return_data; + + WriteReadFor(byte_buffer.data(), byte_buffer.size(), + return_data.data(), return_data.size(), std::chrono::seconds(1)); + + uint8_t _datum; + _datum = return_data.data(); + {{key}} = _datum; // Post-process? + {% break %} +{% endif %} +{# // Check if assignment is a send-op #} +{% if key == '$cmdWrite' %} + {% if 'value' in step[key] %} + write{{step[key].register[12:]}}({{step[key].value}}); + {% else %} + write{{step[key].register[12:]}}(); + {% endif %} + {% break %} +{% endif %} +{% if key == "$delay" %} + {# Blocking impl #} + _time_pt = TimePointAfterAtLeast({{step[key].for}}); + while (SystemClock::now() < _time_pt) {} +{{ logic(step[key].after, function) }} + {% break %} +{% endif %} +{# // Check if assignment op #} +{% if step[key] is string and step[key][0:1] == "=" %} + {{key}} {{step[key]}}; +{% endif %} +{# // Check if assignment is a send-op #} +{% if key == 'send' %} + write{{function.register[12:]}}({{step[key]}}); +{% endif %} +{# // Check if assignment is register read op #} +{% if step[key] is string and step[key][:12] == '#/registers/' %} + {{key}} = read{{step[key][12:]}}(); +{% endif %} +{# // Check if assignment is function call op #} +{% if step[key] is string and step[key][:12] == '#/functions/' %} + {{key}} = {{step[key] | regex_replace('#/functions/(?P.+)/(?P.+)', '\\g\\g')}}(); +{% endif %} +{# // If the value is a list, then this is a logical setter #} +{% if step[key] is iterable and step[key] is not string %} + {{key}} = {{cpp.recursiveAssignLogic(step[key][0], step[key][0].keys()) -}}; +{% endif %} +{% endfor %} +{% endfor %} +{%- endmacro %} + +{% if i2c.endian == 'little' %} +static short _swap_endian(short val) { + // Swap the endianness of a short only + return (val & 0xFF00) >> 8 | (val & 0xFF) << 8; +} +{% endif %} + +{# Add signing function if needed #} +{% for key,register in registers|dictsort %} +{% if register.signed %} +{% if template.sign is sameas false %} +static short _sign(short val, char length) { + // Convert unsigned integer to signed integer + if (val & (1 << (length - 1))) { + return val - (1 << length); + } + return val; +} +{% set template.sign = true %} +{% endif %} +{% endif %} +{% endfor %} + +{% if i2c.address is number %} +#define DEVICE_ADDRESS {{i2c.address}} +{% endif %} + +{% for key,register in registers|dictsort %} +#define REGISTER_{{key.upper()}} {{register.address}} +{% endfor %} + +{{info.title}}::{{info.title}}(Initiator& initiator, + {% if i2c.address is iterable and i2c.address is not string %}Address address{% endif %} + ): RegisterDevice(initiator, {% if i2c.address is iterable and i2c.address is not string %}Address address{% else %}Address({{i2c.address}}){% endif %}), +{% if i2c.endian == 'little' %} std::endian::little{% else %} std::endian::big{% endif %}, + {# FIXME #}register_address_size_(RegisterAddressSize::k1Byte) + ) { + {% if i2c.address is iterable and i2c.address is not string %} + DEVICE_ADDRESS ( address ) + {% endif %} + } + +{% for key,register in registers|dictsort -%} +{% set length = register.length %} +{% set bytes = (register.length / 8) | round(1, 'ceil') | int %} +{% if (not 'readWrite' in register) or ('readWrite' in register and 'R' is in(register.readWrite)) %} +Result<{{cpp.numtype(length)}}> {{info.title}}::read{{key}}() { + // Hard-coded timeout of 1s. + {% if length == 0 %} + return ReadRegister8(REGISTER_{{key.upper()}}, std::chrono::seconds(1)); + {% else %} + return ReadRegister{{length}}(REGISTER_{{key.upper()}}, std::chrono::seconds(1)); + {% endif %} +} +{% endif %} + +{% if (not 'readWrite' in register) or ('readWrite' in register and 'W' is in(register.readWrite)) %} +Status {{info.title}}::write{{key}}({% if length > 0 %}{{cpp.numtype(length)}} data{% endif %}) { + // Hard-coded timeout of 1s. + {% if length == 0 %} + return WriteRegister8(REGISTER_{{key.upper()}}, 0, std::chrono::seconds(1)) + {% else %} + return WriteRegister{{length}}(REGISTER_{{key.upper()}}, data, std::chrono::seconds(1)) + {% endif %} +} +{% endif %} + +{% endfor %} + +{% if fields %} +{% for key,field in fields|dictsort %} +{% if 'R' is in(field.readWrite) %} +{# Getter #} +Result<{{cpp.registerSize(registers, field.register[12:])}}> {{info.title}}::get{{key}}() { + // Read register data + // '#/registers/{{field.register[12:]}}' > '{{field.register[12:]}}' + Result<{{cpp.registerSize(registers, field.register[12:])}}> res = read{{field.register[12:]}}(); + {# Assume it is good #} + {{cpp.registerSize(registers, field.register[12:])}} val = res.value(); + // Mask register value + val = val & {{utils.mask(field.bitStart, field.bitEnd)}}; + {% if field.bitEnd %} + // Bitshift value + val = val >> {{field.bitEnd}}; + {% endif %} + // Rewrap in a Result + Result<{{cpp.registerSize(registers, field.register[12:])}}> result = new Result(val); + return result; +} +{% endif -%} + +{%- if 'W' is in(field.readWrite) %} +{# Setter #} + +Status {{info.title}}::set{{key}}(uint8_t data) { + {% if field.bitEnd %} + // Bitshift value + data = data << {{field.bitEnd}}; + {% endif %} + // Read current register data + // '#/registers/{{field.register[12:]}}' > '{{field.register[12:]}}' + Result<{{cpp.registerSize(registers, field.register[12:])}}> res = read{{field.register[12:]}}(); + {{cpp.registerSize(registers, field.register[12:])}} register_data = res.value() + register_data = register_data | data; + return write{{field.register[12:]}}(register_data); +} +{% endif %} +{% endfor %} +{% endif %} + +{% if functions %} +{% for key,function in functions|dictsort %} +{% for ckey,compute in function.computed|dictsort %} +{% if 'input' in compute %} +{{cpp.returnType(compute)}} {{info.title}}::{{key}}{{ckey}}({{cpp.params(compute)}}) { +{% else %} +{{cpp.returnType(compute)}} {{info.title}}::{{key}}{{ckey}}({{cpp.params(compute)}}) { +{% endif %} + {# Declare our variables #} +{{ cpp.variables(compute.variables) }} + + {# Read `value` if applicable #} + {% if 'input' in compute %} + {%- for vkey,variable in compute.input|dictsort %} + {% if vkey == 'value' %} + // Read value of register into a variable + {{cpp.numconv(variable)}} value = read{{function.register[12:]}}(); + {% endif %} + {% endfor %} + {% endif %} + {# Handle the logic #} +{{ logic(compute.logic, function) }} + + {# Return if applicable #} + {# Return a tuple #} + {% if 'return' in compute and compute.return is not string %} + {# In C languages, the array is a parameter `returnArray` you fill #} + {% for variable in compute.return %} + returnArray[{{loop.index - 1}}] = {{variable}}; + {% endfor %} + {% endif %} + {# Return a plain value #} + {% if compute.return is string %} + return {{compute.return}}; + {% endif %} +} + +{% endfor %} +{% endfor %} +{% endif %} diff --git a/cyanobyte-templates/pigweed.h b/cyanobyte-templates/pigweed.h index 150da7b..066abc1 100644 --- a/cyanobyte-templates/pigweed.h +++ b/cyanobyte-templates/pigweed.h @@ -1,108 +1,108 @@ -{% import 'macros.jinja2' as utils %} -{% import 'base.c.jinja2' as cpp %} -{% set template = namespace(math=false) %} -/* -{{ utils.pad_string('* ', utils.license(info.copyright.name, info.copyright.date, info.license.name)) -}} -* -* Auto-generated file for {{ info.title }} v{{ info.version }}. -* Generated from {{ fileName }} using Cyanobyte Codegen v{{ version }} -* Class for {{ info.title }} -{{utils.pad_string("* ", info.description)}} -*/ - -#pragma once - -#include "pw_bytes/byte_builder.h" -#include "pw_chrono/system_clock.h" -#include "pw_i2c/address.h" -#include "pw_i2c/device.h" -#include "pw_i2c/initiator.h" -#include "pw_result/result.h" -#include "pw_status/status.h" - -{# Create enums for fields #} -{% if fields %} -{% for key,field in fields|dictsort %} -{% if field.enum %} -{# Create enum #} -/* -{{utils.pad_string(" * ", "Valid values for " + field.title)}} - */ -enum {{key}} { - {% set args = namespace(index=0) %} - {% for ekey,enum in field.enum|dictsort %} - {{key.upper()}}_{{ekey.upper()}} = {{enum.value}}{{- "," if args.index + 1 < field.enum | length }} // {{enum.title}} - {% set args.index = args.index + 1 %} - {% endfor %} -}; -typedef enum {{key}} {{key}}_t; -{% endif %} -{% endfor %} -{% endif %} -{% if i2c.address is iterable and i2c.address is not string %} -enum deviceAddress { - {% for address in i2c.address %} - I2C_ADDRESS_{{address}} = {{address}}{{ "," if not loop.last }} - {% endfor %} -}; -typedef enum deviceAddress deviceAddress_t; -{% endif %} - -class {{info.title}} : RegisterDevice { - public: - {% if i2c.address is iterable and i2c.address is not string %} - {{info.title}}(Initiator& initiator, deviceAddress_t address); - deviceAddress_t DEVICE_ADDRESS; - {% else %} - {{info.title}}(Initiator& initiator); - {% endif %} - - {% for key,register in registers|dictsort -%} - {% set length = register.length %} - {% if (not 'readWrite' in register) or ('readWrite' in register and 'R' is in(register.readWrite)) %} - /** -{{utils.pad_string(" * ", register.description)}} - */ - Result<{{cpp.numtype(register.length)}}> read{{key}}(); - {% endif %} - - {% if (not 'readWrite' in register) or ('readWrite' in register and 'W' is in(register.readWrite)) %} - /** -{{utils.pad_string(" * ", register.description)}} - */ - Status write{{key}}({% if length > 0 %}{{cpp.numtype(length)}} data{% endif %});{% endif %} - - {% endfor %} - {% if fields %} - {% for key,field in fields|dictsort %} - {% if 'R' is in(field.readWrite) %} - /** -{{utils.pad_string(" * ", field.description)}} - */ - Result<{{cpp.registerSize(registers, field.register[12:])}}> get{{key}}(); - {% endif %} - {% if 'W' is in(field.readWrite) %} - /** -{{utils.pad_string(" * ", field.description)}} - */ - Status set{{key}}(uint8_t data); - {% endif %} - {% endfor %} - {% endif %} - - {% if functions %} - {% for key,function in functions|dictsort %} - {% for ckey,compute in function.computed|dictsort %} - /** -{{utils.pad_string(" * ", function.description)}} - */ - {% if 'input' in compute %} - {{cpp.returnType(compute)}} {{key}}{{ckey}}({{cpp.params(compute)}}); - {% else %} - {{cpp.returnType(compute)}} {{key}}{{ckey}}({{cpp.params(compute)}}); - {% endif %} - {% endfor %} - - {% endfor %} - {% endif %} -}; +{% import 'macros.jinja2' as utils %} +{% import 'base.c.jinja2' as cpp %} +{% set template = namespace(math=false) %} +/* +{{ utils.pad_string('* ', utils.license(info.copyright.name, info.copyright.date, info.license.name)) -}} +* +* Auto-generated file for {{ info.title }} v{{ info.version }}. +* Generated from {{ fileName }} using Cyanobyte Codegen v{{ version }} +* Class for {{ info.title }} +{{utils.pad_string("* ", info.description)}} +*/ + +#pragma once + +#include "pw_bytes/byte_builder.h" +#include "pw_chrono/system_clock.h" +#include "pw_i2c/address.h" +#include "pw_i2c/device.h" +#include "pw_i2c/initiator.h" +#include "pw_result/result.h" +#include "pw_status/status.h" + +{# Create enums for fields #} +{% if fields %} +{% for key,field in fields|dictsort %} +{% if field.enum %} +{# Create enum #} +/* +{{utils.pad_string(" * ", "Valid values for " + field.title)}} + */ +enum {{key}} { + {% set args = namespace(index=0) %} + {% for ekey,enum in field.enum|dictsort %} + {{key.upper()}}_{{ekey.upper()}} = {{enum.value}}{{- "," if args.index + 1 < field.enum | length }} // {{enum.title}} + {% set args.index = args.index + 1 %} + {% endfor %} +}; +typedef enum {{key}} {{key}}_t; +{% endif %} +{% endfor %} +{% endif %} +{% if i2c.address is iterable and i2c.address is not string %} +enum deviceAddress { + {% for address in i2c.address %} + I2C_ADDRESS_{{address}} = {{address}}{{ "," if not loop.last }} + {% endfor %} +}; +typedef enum deviceAddress deviceAddress_t; +{% endif %} + +class {{info.title}} : RegisterDevice { + public: + {% if i2c.address is iterable and i2c.address is not string %} + {{info.title}}(Initiator& initiator, deviceAddress_t address); + deviceAddress_t DEVICE_ADDRESS; + {% else %} + {{info.title}}(Initiator& initiator); + {% endif %} + + {% for key,register in registers|dictsort -%} + {% set length = register.length %} + {% if (not 'readWrite' in register) or ('readWrite' in register and 'R' is in(register.readWrite)) %} + /** +{{utils.pad_string(" * ", register.description)}} + */ + Result<{{cpp.numtype(register.length)}}> read{{key}}(); + {% endif %} + + {% if (not 'readWrite' in register) or ('readWrite' in register and 'W' is in(register.readWrite)) %} + /** +{{utils.pad_string(" * ", register.description)}} + */ + Status write{{key}}({% if length > 0 %}{{cpp.numtype(length)}} data{% endif %});{% endif %} + + {% endfor %} + {% if fields %} + {% for key,field in fields|dictsort %} + {% if 'R' is in(field.readWrite) %} + /** +{{utils.pad_string(" * ", field.description)}} + */ + Result<{{cpp.registerSize(registers, field.register[12:])}}> get{{key}}(); + {% endif %} + {% if 'W' is in(field.readWrite) %} + /** +{{utils.pad_string(" * ", field.description)}} + */ + Status set{{key}}(uint8_t data); + {% endif %} + {% endfor %} + {% endif %} + + {% if functions %} + {% for key,function in functions|dictsort %} + {% for ckey,compute in function.computed|dictsort %} + /** +{{utils.pad_string(" * ", function.description)}} + */ + {% if 'input' in compute %} + {{cpp.returnType(compute)}} {{key}}{{ckey}}({{cpp.params(compute)}}); + {% else %} + {{cpp.returnType(compute)}} {{key}}{{ckey}}({{cpp.params(compute)}}); + {% endif %} + {% endfor %} + + {% endfor %} + {% endif %} +}; diff --git a/test/sampleData/pigweed/BMP180.cpp b/test/sampleData/pigweed/BMP180.cpp index c9e6a61..89e5f33 100644 --- a/test/sampleData/pigweed/BMP180.cpp +++ b/test/sampleData/pigweed/BMP180.cpp @@ -1,208 +1,208 @@ -/* -* Copyright (C) 2020 Google Inc. -* -* 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. -* -* Auto-generated file for BMP180 v0.1.0. -* Generated from peripherals/BMP180.yaml using Cyanobyte Codegen v0.0.2 -* Class for BMP180 -* Bosch Digital Temperature / Pressure Sensor - -*/ - - - - -#define DEVICE_ADDRESS 119 - -#define REGISTER_CONTROL 244 -#define REGISTER_PRESSURECALAC1 170 -#define REGISTER_PRESSURECALAC2 172 -#define REGISTER_PRESSURECALVB1 182 -#define REGISTER_PRESSURECALVB2 184 -#define REGISTER_RESULT 246 -#define REGISTER_TEMPCAL3 174 -#define REGISTER_TEMPCAL4 176 -#define REGISTER_TEMPCAL5 178 -#define REGISTER_TEMPCAL6 180 -#define REGISTER_TEMPCALMC 188 -#define REGISTER_TEMPCALMD 190 - -BMP180::BMP180(Initiator& initiator, - ): RegisterDevice(initiator, Address(119)), - std::endian::big, -register_address_size_(RegisterAddressSize::k1Byte) - ) { - } - - -Status BMP180::writeControl(uint8_t data) { - // Hard-coded timeout of 1s. - return WriteRegister8(REGISTER_CONTROL, data, std::chrono::seconds(1)) -} - -Result BMP180::readPressureCalAC1() { - // Hard-coded timeout of 1s. - return ReadRegister16(REGISTER_PRESSURECALAC1, std::chrono::seconds(1)); -} - - -Result BMP180::readPressureCalAC2() { - // Hard-coded timeout of 1s. - return ReadRegister16(REGISTER_PRESSURECALAC2, std::chrono::seconds(1)); -} - - -Result BMP180::readPressureCalVB1() { - // Hard-coded timeout of 1s. - return ReadRegister16(REGISTER_PRESSURECALVB1, std::chrono::seconds(1)); -} - - -Result BMP180::readPressureCalVB2() { - // Hard-coded timeout of 1s. - return ReadRegister16(REGISTER_PRESSURECALVB2, std::chrono::seconds(1)); -} - - -Result BMP180::readResult() { - // Hard-coded timeout of 1s. - return ReadRegister16(REGISTER_RESULT, std::chrono::seconds(1)); -} - - -Result BMP180::readTempCal3() { - // Hard-coded timeout of 1s. - return ReadRegister16(REGISTER_TEMPCAL3, std::chrono::seconds(1)); -} - - -Result BMP180::readTempCal4() { - // Hard-coded timeout of 1s. - return ReadRegister16(REGISTER_TEMPCAL4, std::chrono::seconds(1)); -} - - -Result BMP180::readTempCal5() { - // Hard-coded timeout of 1s. - return ReadRegister16(REGISTER_TEMPCAL5, std::chrono::seconds(1)); -} - - -Result BMP180::readTempCal6() { - // Hard-coded timeout of 1s. - return ReadRegister16(REGISTER_TEMPCAL6, std::chrono::seconds(1)); -} - - -Result BMP180::readTempCalMC() { - // Hard-coded timeout of 1s. - return ReadRegister16(REGISTER_TEMPCALMC, std::chrono::seconds(1)); -} - - -Result BMP180::readTempCalMD() { - // Hard-coded timeout of 1s. - return ReadRegister16(REGISTER_TEMPCALMD, std::chrono::seconds(1)); -} - - - - -float BMP180::pressureasMbars() { - short ac1; // Variable declaration - short ac2; // Variable declaration - short ac3; // Variable declaration - uint16_t ac4; // Variable declaration - float b1; // Variable declaration - float c3; // Variable declaration - float c4; // Variable declaration - float p0; // Variable declaration - float p1; // Variable declaration - float p2; // Variable declaration - float pressure; // Variable declaration - float rawComp; // Variable declaration - float temperature; // Variable declaration - short vb1; // Variable declaration - short vb2; // Variable declaration - float x; // Variable declaration - float x1; // Variable declaration - float x2; // Variable declaration - float y; // Variable declaration - float y0; // Variable declaration - float y1; // Variable declaration - float y2; // Variable declaration - float z; // Variable declaration - - - writeControl(52); - pressure = readResult(); - temperature = temperatureasCelsius(); - _time_pt = TimePointAfterAtLeast(10); - while (SystemClock::now() < _time_pt) {} - rawComp = (temperature-25); - ac1 = readPressureCalAC1(); - ac2 = readPressureCalAC2(); - x1 = (160*pow(2, -13)*ac2); - vb2 = readPressureCalVB2(); - x2 = (pow(160, 2)*pow(2, -25)*vb2); - x = ((x2*pow(rawComp, 2))+(x1*rawComp)+ac1); - ac3 = readTempCal3(); - c3 = (160*pow(2, -15)*ac3); - ac4 = readTempCal4(); - c4 = (pow(10, -3)*pow(2, -15)*ac4); - vb1 = readPressureCalVB1(); - b1 = (pow(160, 2)*pow(2, -30)*vb1); - y0 = (c4*pow(2, 15)); - y1 = (c4*c3); - y2 = (c4*b1); - y = ((y2*pow(rawComp, 2))+(y1*rawComp)+y0); - z = ((pressure-x)/y); - p0 = ((3791-8)/1600); - p1 = (1-(7357*pow(2, -30))); - p2 = (3038*100*pow(2, -36)); - pressure = ((p2*pow(z, 2))+(p1*z)+p0); - - - - return pressure; -} - -float BMP180::temperatureasCelsius() { - short rawComp; // Variable declaration - short rawMc; // Variable declaration - short rawMd; // Variable declaration - float temperature; // Variable declaration - uint16_t varAc5; // Variable declaration - uint16_t varAc6; // Variable declaration - float varC5; // Variable declaration - float varMc; // Variable declaration - float varMd; // Variable declaration - - - writeControl(46); - temperature = readResult(); - varAc5 = readTempCal5(); - varAc6 = readTempCal6(); - varC5 = ((pow(2, -15)/160)*varAc5); - rawComp = (varC5*(temperature-varAc6)); - rawMc = readTempCalMC(); - varMc = ((pow(2, 11)/pow(160, 2))*rawMc); - rawMd = readTempCalMD(); - varMd = (rawMd/160); - temperature = (rawComp+(varMc/(rawComp+varMd))); - - - return temperature; -} - +/* +* Copyright (C) 2020 Google Inc. +* +* 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. +* +* Auto-generated file for BMP180 v0.1.0. +* Generated from peripherals/BMP180.yaml using Cyanobyte Codegen v0.0.2 +* Class for BMP180 +* Bosch Digital Temperature / Pressure Sensor + +*/ + + + + +#define DEVICE_ADDRESS 119 + +#define REGISTER_CONTROL 244 +#define REGISTER_PRESSURECALAC1 170 +#define REGISTER_PRESSURECALAC2 172 +#define REGISTER_PRESSURECALVB1 182 +#define REGISTER_PRESSURECALVB2 184 +#define REGISTER_RESULT 246 +#define REGISTER_TEMPCAL3 174 +#define REGISTER_TEMPCAL4 176 +#define REGISTER_TEMPCAL5 178 +#define REGISTER_TEMPCAL6 180 +#define REGISTER_TEMPCALMC 188 +#define REGISTER_TEMPCALMD 190 + +BMP180::BMP180(Initiator& initiator, + ): RegisterDevice(initiator, Address(119)), + std::endian::big, +register_address_size_(RegisterAddressSize::k1Byte) + ) { + } + + +Status BMP180::writeControl(uint8_t data) { + // Hard-coded timeout of 1s. + return WriteRegister8(REGISTER_CONTROL, data, std::chrono::seconds(1)) +} + +Result BMP180::readPressureCalAC1() { + // Hard-coded timeout of 1s. + return ReadRegister16(REGISTER_PRESSURECALAC1, std::chrono::seconds(1)); +} + + +Result BMP180::readPressureCalAC2() { + // Hard-coded timeout of 1s. + return ReadRegister16(REGISTER_PRESSURECALAC2, std::chrono::seconds(1)); +} + + +Result BMP180::readPressureCalVB1() { + // Hard-coded timeout of 1s. + return ReadRegister16(REGISTER_PRESSURECALVB1, std::chrono::seconds(1)); +} + + +Result BMP180::readPressureCalVB2() { + // Hard-coded timeout of 1s. + return ReadRegister16(REGISTER_PRESSURECALVB2, std::chrono::seconds(1)); +} + + +Result BMP180::readResult() { + // Hard-coded timeout of 1s. + return ReadRegister16(REGISTER_RESULT, std::chrono::seconds(1)); +} + + +Result BMP180::readTempCal3() { + // Hard-coded timeout of 1s. + return ReadRegister16(REGISTER_TEMPCAL3, std::chrono::seconds(1)); +} + + +Result BMP180::readTempCal4() { + // Hard-coded timeout of 1s. + return ReadRegister16(REGISTER_TEMPCAL4, std::chrono::seconds(1)); +} + + +Result BMP180::readTempCal5() { + // Hard-coded timeout of 1s. + return ReadRegister16(REGISTER_TEMPCAL5, std::chrono::seconds(1)); +} + + +Result BMP180::readTempCal6() { + // Hard-coded timeout of 1s. + return ReadRegister16(REGISTER_TEMPCAL6, std::chrono::seconds(1)); +} + + +Result BMP180::readTempCalMC() { + // Hard-coded timeout of 1s. + return ReadRegister16(REGISTER_TEMPCALMC, std::chrono::seconds(1)); +} + + +Result BMP180::readTempCalMD() { + // Hard-coded timeout of 1s. + return ReadRegister16(REGISTER_TEMPCALMD, std::chrono::seconds(1)); +} + + + + +float BMP180::pressureasMbars() { + short ac1; // Variable declaration + short ac2; // Variable declaration + short ac3; // Variable declaration + uint16_t ac4; // Variable declaration + float b1; // Variable declaration + float c3; // Variable declaration + float c4; // Variable declaration + float p0; // Variable declaration + float p1; // Variable declaration + float p2; // Variable declaration + float pressure; // Variable declaration + float rawComp; // Variable declaration + float temperature; // Variable declaration + short vb1; // Variable declaration + short vb2; // Variable declaration + float x; // Variable declaration + float x1; // Variable declaration + float x2; // Variable declaration + float y; // Variable declaration + float y0; // Variable declaration + float y1; // Variable declaration + float y2; // Variable declaration + float z; // Variable declaration + + + writeControl(52); + pressure = readResult(); + temperature = temperatureasCelsius(); + _time_pt = TimePointAfterAtLeast(10); + while (SystemClock::now() < _time_pt) {} + rawComp = (temperature-25); + ac1 = readPressureCalAC1(); + ac2 = readPressureCalAC2(); + x1 = (160*pow(2, -13)*ac2); + vb2 = readPressureCalVB2(); + x2 = (pow(160, 2)*pow(2, -25)*vb2); + x = ((x2*pow(rawComp, 2))+(x1*rawComp)+ac1); + ac3 = readTempCal3(); + c3 = (160*pow(2, -15)*ac3); + ac4 = readTempCal4(); + c4 = (pow(10, -3)*pow(2, -15)*ac4); + vb1 = readPressureCalVB1(); + b1 = (pow(160, 2)*pow(2, -30)*vb1); + y0 = (c4*pow(2, 15)); + y1 = (c4*c3); + y2 = (c4*b1); + y = ((y2*pow(rawComp, 2))+(y1*rawComp)+y0); + z = ((pressure-x)/y); + p0 = ((3791-8)/1600); + p1 = (1-(7357*pow(2, -30))); + p2 = (3038*100*pow(2, -36)); + pressure = ((p2*pow(z, 2))+(p1*z)+p0); + + + + return pressure; +} + +float BMP180::temperatureasCelsius() { + short rawComp; // Variable declaration + short rawMc; // Variable declaration + short rawMd; // Variable declaration + float temperature; // Variable declaration + uint16_t varAc5; // Variable declaration + uint16_t varAc6; // Variable declaration + float varC5; // Variable declaration + float varMc; // Variable declaration + float varMd; // Variable declaration + + + writeControl(46); + temperature = readResult(); + varAc5 = readTempCal5(); + varAc6 = readTempCal6(); + varC5 = ((pow(2, -15)/160)*varAc5); + rawComp = (varC5*(temperature-varAc6)); + rawMc = readTempCalMC(); + varMc = ((pow(2, 11)/pow(160, 2))*rawMc); + rawMd = readTempCalMD(); + varMd = (rawMd/160); + temperature = (rawComp+(varMc/(rawComp+varMd))); + + + return temperature; +} + diff --git a/test/sampleData/pigweed/BMP180.h b/test/sampleData/pigweed/BMP180.h index d6beff2..85ecd36 100644 --- a/test/sampleData/pigweed/BMP180.h +++ b/test/sampleData/pigweed/BMP180.h @@ -1,135 +1,135 @@ -/* -* Copyright (C) 2020 Google Inc. -* -* 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. -* -* Auto-generated file for BMP180 v0.1.0. -* Generated from peripherals/BMP180.yaml using Cyanobyte Codegen v0.0.2 -* Class for BMP180 -* Bosch Digital Temperature / Pressure Sensor - -*/ - -#pragma once - -#include "pw_bytes/byte_builder.h" -#include "pw_chrono/system_clock.h" -#include "pw_i2c/address.h" -#include "pw_i2c/device.h" -#include "pw_i2c/initiator.h" -#include "pw_result/result.h" -#include "pw_status/status.h" - - -class BMP180 : RegisterDevice { - public: - BMP180(Initiator& initiator); - - - /** - * Stores the current measurement type. - - */ - Status writeControl(uint8_t data); - /** - * Constant register for pressure measurement calibration. - - */ - Result readPressureCalAC1(); - - - /** - * Constant register for pressure measurement calibration. - - */ - Result readPressureCalAC2(); - - - /** - * Constant register for pressure measurement calibration. - - */ - Result readPressureCalVB1(); - - - /** - * Constant register for pressure measurement calibration. - - */ - Result readPressureCalVB2(); - - - /** - * Stores the most recent measurement result. - - */ - Result readResult(); - - - /** - * Third constant register for temperature measurement calibration. - - */ - Result readTempCal3(); - - - /** - * Fourth constant register for temperature measurement calibration. - - */ - Result readTempCal4(); - - - /** - * Fifth constant register for temperature measurement calibration. - - */ - Result readTempCal5(); - - - /** - * Sixth constant register for temperature measurement calibration. - - */ - Result readTempCal6(); - - - /** - * Constant register for temperature measurement calibration. - - */ - Result readTempCalMC(); - - - /** - * Constant register for temperature measurement calibration. - - */ - Result readTempCalMD(); - - - - /** - * Reads the pressure in absolute millibars, - * not compensated for sea level. - - */ - float pressureasMbars(); - - /** - * Reads the temperature as a raw value or in Celsius. - - */ - float temperatureasCelsius(); - +/* +* Copyright (C) 2020 Google Inc. +* +* 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. +* +* Auto-generated file for BMP180 v0.1.0. +* Generated from peripherals/BMP180.yaml using Cyanobyte Codegen v0.0.2 +* Class for BMP180 +* Bosch Digital Temperature / Pressure Sensor + +*/ + +#pragma once + +#include "pw_bytes/byte_builder.h" +#include "pw_chrono/system_clock.h" +#include "pw_i2c/address.h" +#include "pw_i2c/device.h" +#include "pw_i2c/initiator.h" +#include "pw_result/result.h" +#include "pw_status/status.h" + + +class BMP180 : RegisterDevice { + public: + BMP180(Initiator& initiator); + + + /** + * Stores the current measurement type. + + */ + Status writeControl(uint8_t data); + /** + * Constant register for pressure measurement calibration. + + */ + Result readPressureCalAC1(); + + + /** + * Constant register for pressure measurement calibration. + + */ + Result readPressureCalAC2(); + + + /** + * Constant register for pressure measurement calibration. + + */ + Result readPressureCalVB1(); + + + /** + * Constant register for pressure measurement calibration. + + */ + Result readPressureCalVB2(); + + + /** + * Stores the most recent measurement result. + + */ + Result readResult(); + + + /** + * Third constant register for temperature measurement calibration. + + */ + Result readTempCal3(); + + + /** + * Fourth constant register for temperature measurement calibration. + + */ + Result readTempCal4(); + + + /** + * Fifth constant register for temperature measurement calibration. + + */ + Result readTempCal5(); + + + /** + * Sixth constant register for temperature measurement calibration. + + */ + Result readTempCal6(); + + + /** + * Constant register for temperature measurement calibration. + + */ + Result readTempCalMC(); + + + /** + * Constant register for temperature measurement calibration. + + */ + Result readTempCalMD(); + + + + /** + * Reads the pressure in absolute millibars, + * not compensated for sea level. + + */ + float pressureasMbars(); + + /** + * Reads the temperature as a raw value or in Celsius. + + */ + float temperatureasCelsius(); + }; \ No newline at end of file diff --git a/test/sampleData/pigweed/Example.cpp b/test/sampleData/pigweed/Example.cpp index 3cacec5..a38b4e6 100644 --- a/test/sampleData/pigweed/Example.cpp +++ b/test/sampleData/pigweed/Example.cpp @@ -1,184 +1,184 @@ -/* -* Copyright (C) 2019 Google Inc. -* -* 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. -* -* Auto-generated file for Example v0.1.0. -* Generated from peripherals/example.yaml using Cyanobyte Codegen v0.0.2 -* Class for Example -* Example of a package - -*/ - - - - - -#define REGISTER_REGISTERA 0 -#define REGISTER_REGISTERB 1 -#define REGISTER_REGISTERC 2 -#define REGISTER_REGISTERD 3 - -Example::Example(Initiator& initiator, -Address address ): RegisterDevice(initiator, Address address), - std::endian::big, -register_address_size_(RegisterAddressSize::k1Byte) - ) { - DEVICE_ADDRESS ( address ) - } - -Result Example::readRegisterA() { - // Hard-coded timeout of 1s. - return ReadRegister8(REGISTER_REGISTERA, std::chrono::seconds(1)); -} - -Status Example::writeRegisterA(uint8_t data) { - // Hard-coded timeout of 1s. - return WriteRegister8(REGISTER_REGISTERA, data, std::chrono::seconds(1)) -} - -Result Example::readRegisterB() { - // Hard-coded timeout of 1s. - return ReadRegister16(REGISTER_REGISTERB, std::chrono::seconds(1)); -} - -Status Example::writeRegisterB(uint16_t data) { - // Hard-coded timeout of 1s. - return WriteRegister16(REGISTER_REGISTERB, data, std::chrono::seconds(1)) -} - -Result Example::readRegisterC() { - // Hard-coded timeout of 1s. - return ReadRegister32(REGISTER_REGISTERC, std::chrono::seconds(1)); -} - -Status Example::writeRegisterC(uint32_t data) { - // Hard-coded timeout of 1s. - return WriteRegister32(REGISTER_REGISTERC, data, std::chrono::seconds(1)) -} - -Result Example::readRegisterD() { - // Hard-coded timeout of 1s. - return ReadRegister8(REGISTER_REGISTERD, std::chrono::seconds(1)); -} - -Status Example::writeRegisterD() { - // Hard-coded timeout of 1s. - return WriteRegister8(REGISTER_REGISTERD, 0, std::chrono::seconds(1)) -} - - -Result Example::getFieldA() { - // Read register data - // '#/registers/RegisterA' > 'RegisterA' - Result res = readRegisterA(); - uint8_t val = res.value(); - // Mask register value - val = val & 0b0000000011110000; - // Bitshift value - val = val >> 4; - // Rewrap in a Result - Result result = new Result(val); - return result; -} - -Status Example::setFieldB(uint8_t data) { - // Bitshift value - data = data << 2; - // Read current register data - // '#/registers/RegisterA' > 'RegisterA' - Result res = readRegisterA(); - uint8_t register_data = res.value() - register_data = register_data | data; - return writeRegisterA(register_data); -} -Result Example::getFieldC() { - // Read register data - // '#/registers/RegisterA' > 'RegisterA' - Result res = readRegisterA(); - uint8_t val = res.value(); - // Mask register value - val = val & 0b0000000000000010; - // Bitshift value - val = val >> 1; - // Rewrap in a Result - Result result = new Result(val); - return result; -} - -Status Example::setFieldC(uint8_t data) { - // Bitshift value - data = data << 1; - // Read current register data - // '#/registers/RegisterA' > 'RegisterA' - Result res = readRegisterA(); - uint8_t register_data = res.value() - register_data = register_data | data; - return writeRegisterA(register_data); -} - -char Example::_lifecycleBegin() { - char output; // Variable declaration - - - output = 1; - writeRegisterA(output); - - - return output; -} - -char Example::_lifecycleEnd() { - char output; // Variable declaration - - - output = 1; - writeRegisterA(output); - - - return output; -} - -void Example::ReturnArray(short * returnArray) { - short summation; // Variable declaration - - - summation = (1024+1024); - writeRegisterA(summation); - - - returnArray[0] = summation; - returnArray[1] = summation; -} - -short Example::ReturnNumber() { - short summation; // Variable declaration - - - summation = (1024+1024); - writeRegisterA(summation); - - - return summation; -} - -void Example::ReturnVoid() { - short summation; // Variable declaration - - - summation = (1024+1024); - writeRegisterA(summation); - - -} - +/* +* Copyright (C) 2019 Google Inc. +* +* 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. +* +* Auto-generated file for Example v0.1.0. +* Generated from peripherals/example.yaml using Cyanobyte Codegen v0.0.2 +* Class for Example +* Example of a package + +*/ + + + + + +#define REGISTER_REGISTERA 0 +#define REGISTER_REGISTERB 1 +#define REGISTER_REGISTERC 2 +#define REGISTER_REGISTERD 3 + +Example::Example(Initiator& initiator, +Address address ): RegisterDevice(initiator, Address address), + std::endian::big, +register_address_size_(RegisterAddressSize::k1Byte) + ) { + DEVICE_ADDRESS ( address ) + } + +Result Example::readRegisterA() { + // Hard-coded timeout of 1s. + return ReadRegister8(REGISTER_REGISTERA, std::chrono::seconds(1)); +} + +Status Example::writeRegisterA(uint8_t data) { + // Hard-coded timeout of 1s. + return WriteRegister8(REGISTER_REGISTERA, data, std::chrono::seconds(1)) +} + +Result Example::readRegisterB() { + // Hard-coded timeout of 1s. + return ReadRegister16(REGISTER_REGISTERB, std::chrono::seconds(1)); +} + +Status Example::writeRegisterB(uint16_t data) { + // Hard-coded timeout of 1s. + return WriteRegister16(REGISTER_REGISTERB, data, std::chrono::seconds(1)) +} + +Result Example::readRegisterC() { + // Hard-coded timeout of 1s. + return ReadRegister32(REGISTER_REGISTERC, std::chrono::seconds(1)); +} + +Status Example::writeRegisterC(uint32_t data) { + // Hard-coded timeout of 1s. + return WriteRegister32(REGISTER_REGISTERC, data, std::chrono::seconds(1)) +} + +Result Example::readRegisterD() { + // Hard-coded timeout of 1s. + return ReadRegister8(REGISTER_REGISTERD, std::chrono::seconds(1)); +} + +Status Example::writeRegisterD() { + // Hard-coded timeout of 1s. + return WriteRegister8(REGISTER_REGISTERD, 0, std::chrono::seconds(1)) +} + + +Result Example::getFieldA() { + // Read register data + // '#/registers/RegisterA' > 'RegisterA' + Result res = readRegisterA(); + uint8_t val = res.value(); + // Mask register value + val = val & 0b0000000011110000; + // Bitshift value + val = val >> 4; + // Rewrap in a Result + Result result = new Result(val); + return result; +} + +Status Example::setFieldB(uint8_t data) { + // Bitshift value + data = data << 2; + // Read current register data + // '#/registers/RegisterA' > 'RegisterA' + Result res = readRegisterA(); + uint8_t register_data = res.value() + register_data = register_data | data; + return writeRegisterA(register_data); +} +Result Example::getFieldC() { + // Read register data + // '#/registers/RegisterA' > 'RegisterA' + Result res = readRegisterA(); + uint8_t val = res.value(); + // Mask register value + val = val & 0b0000000000000010; + // Bitshift value + val = val >> 1; + // Rewrap in a Result + Result result = new Result(val); + return result; +} + +Status Example::setFieldC(uint8_t data) { + // Bitshift value + data = data << 1; + // Read current register data + // '#/registers/RegisterA' > 'RegisterA' + Result res = readRegisterA(); + uint8_t register_data = res.value() + register_data = register_data | data; + return writeRegisterA(register_data); +} + +char Example::_lifecycleBegin() { + char output; // Variable declaration + + + output = 1; + writeRegisterA(output); + + + return output; +} + +char Example::_lifecycleEnd() { + char output; // Variable declaration + + + output = 1; + writeRegisterA(output); + + + return output; +} + +void Example::ReturnArray(short * returnArray) { + short summation; // Variable declaration + + + summation = (1024+1024); + writeRegisterA(summation); + + + returnArray[0] = summation; + returnArray[1] = summation; +} + +short Example::ReturnNumber() { + short summation; // Variable declaration + + + summation = (1024+1024); + writeRegisterA(summation); + + + return summation; +} + +void Example::ReturnVoid() { + short summation; // Variable declaration + + + summation = (1024+1024); + writeRegisterA(summation); + + +} + diff --git a/test/sampleData/pigweed/Example.h b/test/sampleData/pigweed/Example.h index 6578ce2..13a333d 100644 --- a/test/sampleData/pigweed/Example.h +++ b/test/sampleData/pigweed/Example.h @@ -1,148 +1,148 @@ -/* -* Copyright (C) 2019 Google Inc. -* -* 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. -* -* Auto-generated file for Example v0.1.0. -* Generated from peripherals/example.yaml using Cyanobyte Codegen v0.0.2 -* Class for Example -* Example of a package - -*/ - -#pragma once - -#include "pw_bytes/byte_builder.h" -#include "pw_chrono/system_clock.h" -#include "pw_i2c/address.h" -#include "pw_i2c/device.h" -#include "pw_i2c/initiator.h" -#include "pw_result/result.h" -#include "pw_status/status.h" - -/* - * Valid values for Write-only fields for RegisterA - - */ -enum FieldB { - FIELDB_VAL_1 = 1, // Value 1 - FIELDB_VAL_2 = 2, // Value 2 - FIELDB_VAL_3 = 4, // Value 3 - FIELDB_VAL_4 = 8 // Value 4 -}; -typedef enum FieldB FieldB_t; -enum deviceAddress { - I2C_ADDRESS_16 = 16, - I2C_ADDRESS_32 = 32, - I2C_ADDRESS_48 = 48 -}; -typedef enum deviceAddress deviceAddress_t; - -class Example : RegisterDevice { - public: - Example(Initiator& initiator, deviceAddress_t address); - deviceAddress_t DEVICE_ADDRESS; - - /** - * An 8-bit register - - */ - Result readRegisterA(); - - /** - * An 8-bit register - - */ - Status writeRegisterA(uint8_t data); - /** - * A 16-bit register - - */ - Result readRegisterB(); - - /** - * A 16-bit register - - */ - Status writeRegisterB(uint16_t data); - /** - * A 32-bit register - - */ - Result readRegisterC(); - - /** - * A 32-bit register - - */ - Status writeRegisterC(uint32_t data); - /** - * A dummy register that has no data - - */ - Result readRegisterD(); - - /** - * A dummy register that has no data - - */ - Status writeRegisterD(); - /** - * This is a few bits - - */ - Result getFieldA(); - /** - * This is fewer bits - - */ - Status setFieldB(uint8_t data); - /** - * A single-bit - - */ - Result getFieldC(); - /** - * A single-bit - - */ - Status setFieldC(uint8_t data); - - /** - * Enables features on device - - */ - char _lifecycleBegin(); - /** - * Enables features on device - - */ - char _lifecycleEnd(); - - /** - * Computes and returns - - */ - void ReturnArray(short * returnArray); - /** - * Computes and returns - - */ - short ReturnNumber(); - /** - * Computes and returns - - */ - void ReturnVoid(); - +/* +* Copyright (C) 2019 Google Inc. +* +* 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. +* +* Auto-generated file for Example v0.1.0. +* Generated from peripherals/example.yaml using Cyanobyte Codegen v0.0.2 +* Class for Example +* Example of a package + +*/ + +#pragma once + +#include "pw_bytes/byte_builder.h" +#include "pw_chrono/system_clock.h" +#include "pw_i2c/address.h" +#include "pw_i2c/device.h" +#include "pw_i2c/initiator.h" +#include "pw_result/result.h" +#include "pw_status/status.h" + +/* + * Valid values for Write-only fields for RegisterA + + */ +enum FieldB { + FIELDB_VAL_1 = 1, // Value 1 + FIELDB_VAL_2 = 2, // Value 2 + FIELDB_VAL_3 = 4, // Value 3 + FIELDB_VAL_4 = 8 // Value 4 +}; +typedef enum FieldB FieldB_t; +enum deviceAddress { + I2C_ADDRESS_16 = 16, + I2C_ADDRESS_32 = 32, + I2C_ADDRESS_48 = 48 +}; +typedef enum deviceAddress deviceAddress_t; + +class Example : RegisterDevice { + public: + Example(Initiator& initiator, deviceAddress_t address); + deviceAddress_t DEVICE_ADDRESS; + + /** + * An 8-bit register + + */ + Result readRegisterA(); + + /** + * An 8-bit register + + */ + Status writeRegisterA(uint8_t data); + /** + * A 16-bit register + + */ + Result readRegisterB(); + + /** + * A 16-bit register + + */ + Status writeRegisterB(uint16_t data); + /** + * A 32-bit register + + */ + Result readRegisterC(); + + /** + * A 32-bit register + + */ + Status writeRegisterC(uint32_t data); + /** + * A dummy register that has no data + + */ + Result readRegisterD(); + + /** + * A dummy register that has no data + + */ + Status writeRegisterD(); + /** + * This is a few bits + + */ + Result getFieldA(); + /** + * This is fewer bits + + */ + Status setFieldB(uint8_t data); + /** + * A single-bit + + */ + Result getFieldC(); + /** + * A single-bit + + */ + Status setFieldC(uint8_t data); + + /** + * Enables features on device + + */ + char _lifecycleBegin(); + /** + * Enables features on device + + */ + char _lifecycleEnd(); + + /** + * Computes and returns + + */ + void ReturnArray(short * returnArray); + /** + * Computes and returns + + */ + short ReturnNumber(); + /** + * Computes and returns + + */ + void ReturnVoid(); + }; \ No newline at end of file From 57e7d85d6a28208b1f9a65389b6dd87e14b9cfd5 Mon Sep 17 00:00:00 2001 From: Nick Date: Wed, 9 Jun 2021 18:34:58 -0400 Subject: [PATCH 6/9] Update Pigweed output to match expectations --- .../{pigweed.cpp => pigweed.cc} | 461 +++++++++--------- cyanobyte-templates/pigweed.gn | 45 ++ cyanobyte-templates/pigweed.h | 17 +- cyanobyte-templates/pigweed_test.cc | 31 ++ 4 files changed, 317 insertions(+), 237 deletions(-) rename cyanobyte-templates/{pigweed.cpp => pigweed.cc} (85%) create mode 100644 cyanobyte-templates/pigweed.gn create mode 100644 cyanobyte-templates/pigweed_test.cc diff --git a/cyanobyte-templates/pigweed.cpp b/cyanobyte-templates/pigweed.cc similarity index 85% rename from cyanobyte-templates/pigweed.cpp rename to cyanobyte-templates/pigweed.cc index 11c8e86..20c4a7c 100644 --- a/cyanobyte-templates/pigweed.cpp +++ b/cyanobyte-templates/pigweed.cc @@ -1,230 +1,231 @@ -{% import 'macros.jinja2' as utils %} -{% import 'base.c.jinja2' as cpp %} -{% set template = namespace(enum=false, sign=false, math=false, struct=false) %} -/* -{{ utils.pad_string('* ', utils.license(info.copyright.name, info.copyright.date, info.license.name)) -}} -* -* Auto-generated file for {{ info.title }} v{{ info.version }}. -* Generated from {{ fileName }} using Cyanobyte Codegen v{{ version }} -* Class for {{ info.title }} -{{utils.pad_string("* ", info.description)}} -*/ - -{% macro logic(logicalSteps, function) -%} - -{% for step in logicalSteps %} -{% for key in step.keys() %} -{# // Check if a raw read-op #} -{% if step[key] is mapping and 'rawRead' in step[key] %} - {% set bytes = (step[key].rawRead / 8) | round(1, 'ceil') | int %} - ByteBuffer byte_buffer; - - // can i even call this? - PutRegisterAddressInByteBuffer( - byte_buffer, DEVICE_ADDRESS, order_, register_address_size_ - ) - - if (!byte_buffer.ok()) { - return pw::Status::Internal() - } - - ByteSpan return_data; - - WriteReadFor(byte_buffer.data(), byte_buffer.size(), - return_data.data(), return_data.size(), std::chrono::seconds(1)); - - uint8_t _datum; - _datum = return_data.data(); - {{key}} = _datum; // Post-process? - {% break %} -{% endif %} -{# // Check if assignment is a send-op #} -{% if key == '$cmdWrite' %} - {% if 'value' in step[key] %} - write{{step[key].register[12:]}}({{step[key].value}}); - {% else %} - write{{step[key].register[12:]}}(); - {% endif %} - {% break %} -{% endif %} -{% if key == "$delay" %} - {# Blocking impl #} - _time_pt = TimePointAfterAtLeast({{step[key].for}}); - while (SystemClock::now() < _time_pt) {} -{{ logic(step[key].after, function) }} - {% break %} -{% endif %} -{# // Check if assignment op #} -{% if step[key] is string and step[key][0:1] == "=" %} - {{key}} {{step[key]}}; -{% endif %} -{# // Check if assignment is a send-op #} -{% if key == 'send' %} - write{{function.register[12:]}}({{step[key]}}); -{% endif %} -{# // Check if assignment is register read op #} -{% if step[key] is string and step[key][:12] == '#/registers/' %} - {{key}} = read{{step[key][12:]}}(); -{% endif %} -{# // Check if assignment is function call op #} -{% if step[key] is string and step[key][:12] == '#/functions/' %} - {{key}} = {{step[key] | regex_replace('#/functions/(?P.+)/(?P.+)', '\\g\\g')}}(); -{% endif %} -{# // If the value is a list, then this is a logical setter #} -{% if step[key] is iterable and step[key] is not string %} - {{key}} = {{cpp.recursiveAssignLogic(step[key][0], step[key][0].keys()) -}}; -{% endif %} -{% endfor %} -{% endfor %} -{%- endmacro %} - -{% if i2c.endian == 'little' %} -static short _swap_endian(short val) { - // Swap the endianness of a short only - return (val & 0xFF00) >> 8 | (val & 0xFF) << 8; -} -{% endif %} - -{# Add signing function if needed #} -{% for key,register in registers|dictsort %} -{% if register.signed %} -{% if template.sign is sameas false %} -static short _sign(short val, char length) { - // Convert unsigned integer to signed integer - if (val & (1 << (length - 1))) { - return val - (1 << length); - } - return val; -} -{% set template.sign = true %} -{% endif %} -{% endif %} -{% endfor %} - -{% if i2c.address is number %} -#define DEVICE_ADDRESS {{i2c.address}} -{% endif %} - -{% for key,register in registers|dictsort %} -#define REGISTER_{{key.upper()}} {{register.address}} -{% endfor %} - -{{info.title}}::{{info.title}}(Initiator& initiator, - {% if i2c.address is iterable and i2c.address is not string %}Address address{% endif %} - ): RegisterDevice(initiator, {% if i2c.address is iterable and i2c.address is not string %}Address address{% else %}Address({{i2c.address}}){% endif %}), -{% if i2c.endian == 'little' %} std::endian::little{% else %} std::endian::big{% endif %}, - {# FIXME #}register_address_size_(RegisterAddressSize::k1Byte) - ) { - {% if i2c.address is iterable and i2c.address is not string %} - DEVICE_ADDRESS ( address ) - {% endif %} - } - -{% for key,register in registers|dictsort -%} -{% set length = register.length %} -{% set bytes = (register.length / 8) | round(1, 'ceil') | int %} -{% if (not 'readWrite' in register) or ('readWrite' in register and 'R' is in(register.readWrite)) %} -Result<{{cpp.numtype(length)}}> {{info.title}}::read{{key}}() { - // Hard-coded timeout of 1s. - {% if length == 0 %} - return ReadRegister8(REGISTER_{{key.upper()}}, std::chrono::seconds(1)); - {% else %} - return ReadRegister{{length}}(REGISTER_{{key.upper()}}, std::chrono::seconds(1)); - {% endif %} -} -{% endif %} - -{% if (not 'readWrite' in register) or ('readWrite' in register and 'W' is in(register.readWrite)) %} -Status {{info.title}}::write{{key}}({% if length > 0 %}{{cpp.numtype(length)}} data{% endif %}) { - // Hard-coded timeout of 1s. - {% if length == 0 %} - return WriteRegister8(REGISTER_{{key.upper()}}, 0, std::chrono::seconds(1)) - {% else %} - return WriteRegister{{length}}(REGISTER_{{key.upper()}}, data, std::chrono::seconds(1)) - {% endif %} -} -{% endif %} - -{% endfor %} - -{% if fields %} -{% for key,field in fields|dictsort %} -{% if 'R' is in(field.readWrite) %} -{# Getter #} -Result<{{cpp.registerSize(registers, field.register[12:])}}> {{info.title}}::get{{key}}() { - // Read register data - // '#/registers/{{field.register[12:]}}' > '{{field.register[12:]}}' - Result<{{cpp.registerSize(registers, field.register[12:])}}> res = read{{field.register[12:]}}(); - {# Assume it is good #} - {{cpp.registerSize(registers, field.register[12:])}} val = res.value(); - // Mask register value - val = val & {{utils.mask(field.bitStart, field.bitEnd)}}; - {% if field.bitEnd %} - // Bitshift value - val = val >> {{field.bitEnd}}; - {% endif %} - // Rewrap in a Result - Result<{{cpp.registerSize(registers, field.register[12:])}}> result = new Result(val); - return result; -} -{% endif -%} - -{%- if 'W' is in(field.readWrite) %} -{# Setter #} - -Status {{info.title}}::set{{key}}(uint8_t data) { - {% if field.bitEnd %} - // Bitshift value - data = data << {{field.bitEnd}}; - {% endif %} - // Read current register data - // '#/registers/{{field.register[12:]}}' > '{{field.register[12:]}}' - Result<{{cpp.registerSize(registers, field.register[12:])}}> res = read{{field.register[12:]}}(); - {{cpp.registerSize(registers, field.register[12:])}} register_data = res.value() - register_data = register_data | data; - return write{{field.register[12:]}}(register_data); -} -{% endif %} -{% endfor %} -{% endif %} - -{% if functions %} -{% for key,function in functions|dictsort %} -{% for ckey,compute in function.computed|dictsort %} -{% if 'input' in compute %} -{{cpp.returnType(compute)}} {{info.title}}::{{key}}{{ckey}}({{cpp.params(compute)}}) { -{% else %} -{{cpp.returnType(compute)}} {{info.title}}::{{key}}{{ckey}}({{cpp.params(compute)}}) { -{% endif %} - {# Declare our variables #} -{{ cpp.variables(compute.variables) }} - - {# Read `value` if applicable #} - {% if 'input' in compute %} - {%- for vkey,variable in compute.input|dictsort %} - {% if vkey == 'value' %} - // Read value of register into a variable - {{cpp.numconv(variable)}} value = read{{function.register[12:]}}(); - {% endif %} - {% endfor %} - {% endif %} - {# Handle the logic #} -{{ logic(compute.logic, function) }} - - {# Return if applicable #} - {# Return a tuple #} - {% if 'return' in compute and compute.return is not string %} - {# In C languages, the array is a parameter `returnArray` you fill #} - {% for variable in compute.return %} - returnArray[{{loop.index - 1}}] = {{variable}}; - {% endfor %} - {% endif %} - {# Return a plain value #} - {% if compute.return is string %} - return {{compute.return}}; - {% endif %} -} - -{% endfor %} -{% endfor %} -{% endif %} +{% import 'macros.jinja2' as utils %} +{% import 'base.c.jinja2' as cpp %} +{% set template = namespace(enum=false, sign=false, math=false, struct=false) %} +/* +{{ utils.pad_string('* ', utils.license(info.copyright.name, info.copyright.date, info.license.name)) -}} +* +* Auto-generated file for {{ info.title }} v{{ info.version }}. +* Generated from {{ fileName }} using Cyanobyte Codegen v{{ version }} +* Class for {{ info.title }} +{{utils.pad_string("* ", info.description)}} +*/ + +{% macro logic(logicalSteps, function) -%} + +{% for step in logicalSteps %} +{% for key in step.keys() %} +{# // Check if a raw read-op #} +{% if step[key] is mapping and 'rawRead' in step[key] %} + {% set bytes = (step[key].rawRead / 8) | round(1, 'ceil') | int %} + ByteBuffer byte_buffer; + + // can i even call this? + PutRegisterAddressInByteBuffer( + byte_buffer, DEVICE_ADDRESS, order_, register_address_size_ + ) + + if (!byte_buffer.ok()) { + return pw::Status::Internal() + } + + ByteSpan return_data; + + WriteReadFor(byte_buffer.data(), byte_buffer.size(), + return_data.data(), return_data.size(), std::chrono::seconds(1)); + + uint8_t _datum; + _datum = return_data.data(); + {{key}} = _datum; // Post-process? + {% break %} +{% endif %} +{# // Check if assignment is a send-op #} +{% if key == '$cmdWrite' %} + {% if 'value' in step[key] %} + write{{step[key].register[12:]}}({{step[key].value}}); + {% else %} + write{{step[key].register[12:]}}(); + {% endif %} + {% break %} +{% endif %} +{% if key == "$delay" %} + {# Blocking impl #} + pw::chrono::SystemClock::time_point before = pw::chrono::SystemClock::now(); + while (pw::chrono::SystemClock::now() - before < std::chrono::milliseconds(10)) {} +{{ logic(step[key].after, function) }} + {% break %} +{% endif %} +{# // Check if assignment op #} +{% if step[key] is string and step[key][0:1] == "=" %} + {{key}} {{step[key]}}; +{% endif %} +{# // Check if assignment is a send-op #} +{% if key == 'send' %} + write{{function.register[12:]}}({{step[key]}}); +{% endif %} +{# // Check if assignment is register read op #} +{% if step[key] is string and step[key][:12] == '#/registers/' %} + {# Unwrap result #} + {{key}} = read{{step[key][12:]}}().value(); +{% endif %} +{# // Check if assignment is function call op #} +{% if step[key] is string and step[key][:12] == '#/functions/' %} + {{key}} = {{step[key] | regex_replace('#/functions/(?P.+)/(?P.+)', '\\g\\g')}}(); +{% endif %} +{# // If the value is a list, then this is a logical setter #} +{% if step[key] is iterable and step[key] is not string %} + {{key}} = {{cpp.recursiveAssignLogic(step[key][0], step[key][0].keys()) -}}; +{% endif %} +{% endfor %} +{% endfor %} +{%- endmacro %} + +{% if i2c.endian == 'little' %} +static short _swap_endian(short val) { + // Swap the endianness of a short only + return (val & 0xFF00) >> 8 | (val & 0xFF) << 8; +} +{% endif %} + +{# Add signing function if needed #} +{% for key,register in registers|dictsort %} +{% if register.signed %} +{% if template.sign is sameas false %} +static short _sign(short val, char length) { + // Convert unsigned integer to signed integer + if (val & (1 << (length - 1))) { + return val - (1 << length); + } + return val; +} +{% set template.sign = true %} +{% endif %} +{% endif %} +{% endfor %} + +#include "{{info.title}}.h" + +{% if i2c.address is number %} +#define DEVICE_ADDRESS {{i2c.address}} +{% endif %} + +{% for key,register in registers|dictsort %} +#define REGISTER_{{key.upper()}} {{register.address}} +{% endfor %} + +{{info.title}}::{{info.title}}(pw::i2c::Initiator& initiator{% if i2c.address is iterable and i2c.address is not string %}, pw::i2c::Address address{% endif %}): RegisterDevice(initiator, {% if i2c.address is iterable and i2c.address is not string %}address{% else %}pw::i2c::Address({{i2c.address}}){% endif %}), +{% if i2c.endian == 'little' %} std::endian::little{% else %} std::endian::big{% endif %}, + pw::i2c::RegisterAddressSize::k1Byte) + { + {% if i2c.address is iterable and i2c.address is not string %} + DEVICE_ADDRESS ( address ) + {% endif %} + } + +{% for key,register in registers|dictsort -%} +{% set length = register.length %} +{% set bytes = (register.length / 8) | round(1, 'ceil') | int %} +{% if (not 'readWrite' in register) or ('readWrite' in register and 'R' is in(register.readWrite)) %} +pw::Result<{{cpp.numtype(length)}}> {{info.title}}::read{{key}}() { + // Hard-coded timeout of 1s. + {% if length == 0 %} + return ReadRegister8(REGISTER_{{key.upper()}}, std::chrono::seconds(1)); + {% else %} + return ReadRegister{{length}}(REGISTER_{{key.upper()}}, std::chrono::seconds(1)); + {% endif %} +} +{% endif %} + +{% if (not 'readWrite' in register) or ('readWrite' in register and 'W' is in(register.readWrite)) %} +pw::Status {{info.title}}::write{{key}}({% if length > 0 %}{{cpp.numtype(length)}} data{% endif %}) { + // Hard-coded timeout of 1s. + {% if length == 0 %} + return WriteRegister8(REGISTER_{{key.upper()}}, 0 /* No data */, std::chrono::seconds(1)); + {% else %} + return WriteRegister{{length}}(REGISTER_{{key.upper()}}, data, std::chrono::seconds(1)); + {% endif %} +} +{% endif %} + +{% endfor %} + +{% if fields %} +{% for key,field in fields|dictsort %} +{% if 'R' is in(field.readWrite) %} +{# Getter #} +pw::Result<{{cpp.registerSize(registers, field.register[12:])}}> {{info.title}}::get{{key}}() { + // Read register data + // '#/registers/{{field.register[12:]}}' > '{{field.register[12:]}}' + Result<{{cpp.registerSize(registers, field.register[12:])}}> res = read{{field.register[12:]}}(); + {# Assume it is good #} + {{cpp.registerSize(registers, field.register[12:])}} val = res.value(); + // Mask register value + val = val & {{utils.mask(field.bitStart, field.bitEnd)}}; + {% if field.bitEnd %} + // Bitshift value + val = val >> {{field.bitEnd}}; + {% endif %} + // Rewrap in a Result + Result<{{cpp.registerSize(registers, field.register[12:])}}> result = new Result(val); + return result; +} +{% endif -%} + +{%- if 'W' is in(field.readWrite) %} +{# Setter #} + +pw::Status {{info.title}}::set{{key}}(uint8_t data) { + {% if field.bitEnd %} + // Bitshift value + data = data << {{field.bitEnd}}; + {% endif %} + // Read current register data + // '#/registers/{{field.register[12:]}}' > '{{field.register[12:]}}' + Result<{{cpp.registerSize(registers, field.register[12:])}}> res = read{{field.register[12:]}}(); + {{cpp.registerSize(registers, field.register[12:])}} register_data = res.value() + register_data = register_data | data; + return write{{field.register[12:]}}(register_data); +} +{% endif %} +{% endfor %} +{% endif %} + +{% if functions %} +{% for key,function in functions|dictsort %} +{% for ckey,compute in function.computed|dictsort %} +{% if 'input' in compute %} +{{cpp.returnType(compute)}} {{info.title}}::{{key}}{{ckey}}({{cpp.params(compute)}}) { +{% else %} +{{cpp.returnType(compute)}} {{info.title}}::{{key}}{{ckey}}({{cpp.params(compute)}}) { +{% endif %} + {# Declare our variables #} +{{ cpp.variables(compute.variables) }} + + {# Read `value` if applicable #} + {% if 'input' in compute %} + {%- for vkey,variable in compute.input|dictsort %} + {% if vkey == 'value' %} + // Read value of register into a variable + {{cpp.numconv(variable)}} value = read{{function.register[12:]}}(); + {% endif %} + {% endfor %} + {% endif %} + {# Handle the logic #} +{{ logic(compute.logic, function) }} + + {# Return if applicable #} + {# Return a tuple #} + {% if 'return' in compute and compute.return is not string %} + {# In C languages, the array is a parameter `returnArray` you fill #} + {% for variable in compute.return %} + returnArray[{{loop.index - 1}}] = {{variable}}; + {% endfor %} + {% endif %} + {# Return a plain value #} + {% if compute.return is string %} + return {{compute.return}}; + {% endif %} +} + +{% endfor %} +{% endfor %} +{% endif %} diff --git a/cyanobyte-templates/pigweed.gn b/cyanobyte-templates/pigweed.gn new file mode 100644 index 0000000..eeb0b41 --- /dev/null +++ b/cyanobyte-templates/pigweed.gn @@ -0,0 +1,45 @@ +# Copyright 2021 Google LLC +# +# 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 +# +# https://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. + +import("//build_overrides/pigweed.gni") + +import("$dir_pw_build/target_types.gni") +import("$dir_pw_chrono/backend.gni") +import("$dir_pw_docgen/docs.gni") +import("$dir_pw_unit_test/test.gni") + +pw_source_set("{{ info.title }}") { + public = [ "{{ info.title }}.h" ] + sources = [ "{{ info.title }}.cc" ] + deps = [ + "$dir_pw_bytes", + "$dir_pw_chrono:system_clock", + "$dir_pw_i2c:address", + "$dir_pw_i2c:device", + "$dir_pw_i2c:initiator", + "$dir_pw_result", + "$dir_pw_status", + ] +} + +pw_test_group("tests") { + tests = [ + ":{{ info.title }}_test", + ] +} + +pw_test("{{ info.title }}_test") { + sources = [ "{{ info.title }}_test.cc" ] + deps = [ ":{{ info.title }}" ] +} diff --git a/cyanobyte-templates/pigweed.h b/cyanobyte-templates/pigweed.h index 066abc1..add597d 100644 --- a/cyanobyte-templates/pigweed.h +++ b/cyanobyte-templates/pigweed.h @@ -12,10 +12,13 @@ #pragma once +#include + #include "pw_bytes/byte_builder.h" #include "pw_chrono/system_clock.h" #include "pw_i2c/address.h" #include "pw_i2c/device.h" +#include "pw_i2c/register_device.h" #include "pw_i2c/initiator.h" #include "pw_result/result.h" #include "pw_status/status.h" @@ -48,13 +51,13 @@ enum deviceAddress { typedef enum deviceAddress deviceAddress_t; {% endif %} -class {{info.title}} : RegisterDevice { +class {{info.title}} : pw::i2c::RegisterDevice { public: {% if i2c.address is iterable and i2c.address is not string %} - {{info.title}}(Initiator& initiator, deviceAddress_t address); + {{info.title}}(pw::i2c::Initiator& initiator, deviceAddress_t address); deviceAddress_t DEVICE_ADDRESS; {% else %} - {{info.title}}(Initiator& initiator); + {{info.title}}(pw::i2c::Initiator& initiator); {% endif %} {% for key,register in registers|dictsort -%} @@ -63,14 +66,14 @@ class {{info.title}} : RegisterDevice { /** {{utils.pad_string(" * ", register.description)}} */ - Result<{{cpp.numtype(register.length)}}> read{{key}}(); + pw::Result<{{cpp.numtype(register.length)}}> read{{key}}(); {% endif %} {% if (not 'readWrite' in register) or ('readWrite' in register and 'W' is in(register.readWrite)) %} /** {{utils.pad_string(" * ", register.description)}} */ - Status write{{key}}({% if length > 0 %}{{cpp.numtype(length)}} data{% endif %});{% endif %} + pw::Status write{{key}}({% if length > 0 %}{{cpp.numtype(length)}} data{% endif %});{% endif %} {% endfor %} {% if fields %} @@ -79,13 +82,13 @@ class {{info.title}} : RegisterDevice { /** {{utils.pad_string(" * ", field.description)}} */ - Result<{{cpp.registerSize(registers, field.register[12:])}}> get{{key}}(); + pw::Result<{{cpp.registerSize(registers, field.register[12:])}}> get{{key}}(); {% endif %} {% if 'W' is in(field.readWrite) %} /** {{utils.pad_string(" * ", field.description)}} */ - Status set{{key}}(uint8_t data); + pw::Status set{{key}}(uint8_t data); {% endif %} {% endfor %} {% endif %} diff --git a/cyanobyte-templates/pigweed_test.cc b/cyanobyte-templates/pigweed_test.cc new file mode 100644 index 0000000..72ab554 --- /dev/null +++ b/cyanobyte-templates/pigweed_test.cc @@ -0,0 +1,31 @@ +// Copyright 2021 Google LLC +// +// 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 +// +// https://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 +#include +#include + +#include "gtest/gtest.h" + +using namespace std::literals::chrono_literals; + +namespace pw::i2c { +namespace { + +TEST(Transaction, Read) { + EXPECT_EQ(1, 1); +} + +} // namespace +} // namespace pw::i2c \ No newline at end of file From 44a8886d9f2864d3522f71bc4de53274951eb3ae Mon Sep 17 00:00:00 2001 From: Nick Date: Wed, 9 Jun 2021 18:40:08 -0400 Subject: [PATCH 7/9] Add example files --- .../pigweed/{BMP180.cpp => BMP180.cc} | 417 +++++++++--------- test/sampleData/pigweed/BMP180.gn | 45 ++ test/sampleData/pigweed/BMP180.h | 31 +- test/sampleData/pigweed/BMP180_test.cc | 31 ++ .../pigweed/{Example.cpp => Example.cc} | 369 ++++++++-------- test/sampleData/pigweed/Example.gn | 45 ++ test/sampleData/pigweed/Example.h | 31 +- test/sampleData/pigweed/Example_test.cc | 31 ++ 8 files changed, 580 insertions(+), 420 deletions(-) rename test/sampleData/pigweed/{BMP180.cpp => BMP180.cc} (77%) create mode 100644 test/sampleData/pigweed/BMP180.gn create mode 100644 test/sampleData/pigweed/BMP180_test.cc rename test/sampleData/pigweed/{Example.cpp => Example.cc} (79%) create mode 100644 test/sampleData/pigweed/Example.gn create mode 100644 test/sampleData/pigweed/Example_test.cc diff --git a/test/sampleData/pigweed/BMP180.cpp b/test/sampleData/pigweed/BMP180.cc similarity index 77% rename from test/sampleData/pigweed/BMP180.cpp rename to test/sampleData/pigweed/BMP180.cc index 89e5f33..ceac905 100644 --- a/test/sampleData/pigweed/BMP180.cpp +++ b/test/sampleData/pigweed/BMP180.cc @@ -1,208 +1,209 @@ -/* -* Copyright (C) 2020 Google Inc. -* -* 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. -* -* Auto-generated file for BMP180 v0.1.0. -* Generated from peripherals/BMP180.yaml using Cyanobyte Codegen v0.0.2 -* Class for BMP180 -* Bosch Digital Temperature / Pressure Sensor - -*/ - - - - -#define DEVICE_ADDRESS 119 - -#define REGISTER_CONTROL 244 -#define REGISTER_PRESSURECALAC1 170 -#define REGISTER_PRESSURECALAC2 172 -#define REGISTER_PRESSURECALVB1 182 -#define REGISTER_PRESSURECALVB2 184 -#define REGISTER_RESULT 246 -#define REGISTER_TEMPCAL3 174 -#define REGISTER_TEMPCAL4 176 -#define REGISTER_TEMPCAL5 178 -#define REGISTER_TEMPCAL6 180 -#define REGISTER_TEMPCALMC 188 -#define REGISTER_TEMPCALMD 190 - -BMP180::BMP180(Initiator& initiator, - ): RegisterDevice(initiator, Address(119)), - std::endian::big, -register_address_size_(RegisterAddressSize::k1Byte) - ) { - } - - -Status BMP180::writeControl(uint8_t data) { - // Hard-coded timeout of 1s. - return WriteRegister8(REGISTER_CONTROL, data, std::chrono::seconds(1)) -} - -Result BMP180::readPressureCalAC1() { - // Hard-coded timeout of 1s. - return ReadRegister16(REGISTER_PRESSURECALAC1, std::chrono::seconds(1)); -} - - -Result BMP180::readPressureCalAC2() { - // Hard-coded timeout of 1s. - return ReadRegister16(REGISTER_PRESSURECALAC2, std::chrono::seconds(1)); -} - - -Result BMP180::readPressureCalVB1() { - // Hard-coded timeout of 1s. - return ReadRegister16(REGISTER_PRESSURECALVB1, std::chrono::seconds(1)); -} - - -Result BMP180::readPressureCalVB2() { - // Hard-coded timeout of 1s. - return ReadRegister16(REGISTER_PRESSURECALVB2, std::chrono::seconds(1)); -} - - -Result BMP180::readResult() { - // Hard-coded timeout of 1s. - return ReadRegister16(REGISTER_RESULT, std::chrono::seconds(1)); -} - - -Result BMP180::readTempCal3() { - // Hard-coded timeout of 1s. - return ReadRegister16(REGISTER_TEMPCAL3, std::chrono::seconds(1)); -} - - -Result BMP180::readTempCal4() { - // Hard-coded timeout of 1s. - return ReadRegister16(REGISTER_TEMPCAL4, std::chrono::seconds(1)); -} - - -Result BMP180::readTempCal5() { - // Hard-coded timeout of 1s. - return ReadRegister16(REGISTER_TEMPCAL5, std::chrono::seconds(1)); -} - - -Result BMP180::readTempCal6() { - // Hard-coded timeout of 1s. - return ReadRegister16(REGISTER_TEMPCAL6, std::chrono::seconds(1)); -} - - -Result BMP180::readTempCalMC() { - // Hard-coded timeout of 1s. - return ReadRegister16(REGISTER_TEMPCALMC, std::chrono::seconds(1)); -} - - -Result BMP180::readTempCalMD() { - // Hard-coded timeout of 1s. - return ReadRegister16(REGISTER_TEMPCALMD, std::chrono::seconds(1)); -} - - - - -float BMP180::pressureasMbars() { - short ac1; // Variable declaration - short ac2; // Variable declaration - short ac3; // Variable declaration - uint16_t ac4; // Variable declaration - float b1; // Variable declaration - float c3; // Variable declaration - float c4; // Variable declaration - float p0; // Variable declaration - float p1; // Variable declaration - float p2; // Variable declaration - float pressure; // Variable declaration - float rawComp; // Variable declaration - float temperature; // Variable declaration - short vb1; // Variable declaration - short vb2; // Variable declaration - float x; // Variable declaration - float x1; // Variable declaration - float x2; // Variable declaration - float y; // Variable declaration - float y0; // Variable declaration - float y1; // Variable declaration - float y2; // Variable declaration - float z; // Variable declaration - - - writeControl(52); - pressure = readResult(); - temperature = temperatureasCelsius(); - _time_pt = TimePointAfterAtLeast(10); - while (SystemClock::now() < _time_pt) {} - rawComp = (temperature-25); - ac1 = readPressureCalAC1(); - ac2 = readPressureCalAC2(); - x1 = (160*pow(2, -13)*ac2); - vb2 = readPressureCalVB2(); - x2 = (pow(160, 2)*pow(2, -25)*vb2); - x = ((x2*pow(rawComp, 2))+(x1*rawComp)+ac1); - ac3 = readTempCal3(); - c3 = (160*pow(2, -15)*ac3); - ac4 = readTempCal4(); - c4 = (pow(10, -3)*pow(2, -15)*ac4); - vb1 = readPressureCalVB1(); - b1 = (pow(160, 2)*pow(2, -30)*vb1); - y0 = (c4*pow(2, 15)); - y1 = (c4*c3); - y2 = (c4*b1); - y = ((y2*pow(rawComp, 2))+(y1*rawComp)+y0); - z = ((pressure-x)/y); - p0 = ((3791-8)/1600); - p1 = (1-(7357*pow(2, -30))); - p2 = (3038*100*pow(2, -36)); - pressure = ((p2*pow(z, 2))+(p1*z)+p0); - - - - return pressure; -} - -float BMP180::temperatureasCelsius() { - short rawComp; // Variable declaration - short rawMc; // Variable declaration - short rawMd; // Variable declaration - float temperature; // Variable declaration - uint16_t varAc5; // Variable declaration - uint16_t varAc6; // Variable declaration - float varC5; // Variable declaration - float varMc; // Variable declaration - float varMd; // Variable declaration - - - writeControl(46); - temperature = readResult(); - varAc5 = readTempCal5(); - varAc6 = readTempCal6(); - varC5 = ((pow(2, -15)/160)*varAc5); - rawComp = (varC5*(temperature-varAc6)); - rawMc = readTempCalMC(); - varMc = ((pow(2, 11)/pow(160, 2))*rawMc); - rawMd = readTempCalMD(); - varMd = (rawMd/160); - temperature = (rawComp+(varMc/(rawComp+varMd))); - - - return temperature; -} - +/* +* Copyright (C) 2020 Google Inc. +* +* 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. +* +* Auto-generated file for BMP180 v0.1.0. +* Generated from peripherals/BMP180.yaml using Cyanobyte Codegen v0.0.2 +* Class for BMP180 +* Bosch Digital Temperature / Pressure Sensor + +*/ + + + + +#include "BMP180.h" + +#define DEVICE_ADDRESS 119 + +#define REGISTER_CONTROL 244 +#define REGISTER_PRESSURECALAC1 170 +#define REGISTER_PRESSURECALAC2 172 +#define REGISTER_PRESSURECALVB1 182 +#define REGISTER_PRESSURECALVB2 184 +#define REGISTER_RESULT 246 +#define REGISTER_TEMPCAL3 174 +#define REGISTER_TEMPCAL4 176 +#define REGISTER_TEMPCAL5 178 +#define REGISTER_TEMPCAL6 180 +#define REGISTER_TEMPCALMC 188 +#define REGISTER_TEMPCALMD 190 + +BMP180::BMP180(pw::i2c::Initiator& initiator): RegisterDevice(initiator, pw::i2c::Address(119)), + std::endian::big, + pw::i2c::RegisterAddressSize::k1Byte) + { + } + + +pw::Status BMP180::writeControl(uint8_t data) { + // Hard-coded timeout of 1s. + return WriteRegister8(REGISTER_CONTROL, data, std::chrono::seconds(1)); +} + +pw::Result BMP180::readPressureCalAC1() { + // Hard-coded timeout of 1s. + return ReadRegister16(REGISTER_PRESSURECALAC1, std::chrono::seconds(1)); +} + + +pw::Result BMP180::readPressureCalAC2() { + // Hard-coded timeout of 1s. + return ReadRegister16(REGISTER_PRESSURECALAC2, std::chrono::seconds(1)); +} + + +pw::Result BMP180::readPressureCalVB1() { + // Hard-coded timeout of 1s. + return ReadRegister16(REGISTER_PRESSURECALVB1, std::chrono::seconds(1)); +} + + +pw::Result BMP180::readPressureCalVB2() { + // Hard-coded timeout of 1s. + return ReadRegister16(REGISTER_PRESSURECALVB2, std::chrono::seconds(1)); +} + + +pw::Result BMP180::readResult() { + // Hard-coded timeout of 1s. + return ReadRegister16(REGISTER_RESULT, std::chrono::seconds(1)); +} + + +pw::Result BMP180::readTempCal3() { + // Hard-coded timeout of 1s. + return ReadRegister16(REGISTER_TEMPCAL3, std::chrono::seconds(1)); +} + + +pw::Result BMP180::readTempCal4() { + // Hard-coded timeout of 1s. + return ReadRegister16(REGISTER_TEMPCAL4, std::chrono::seconds(1)); +} + + +pw::Result BMP180::readTempCal5() { + // Hard-coded timeout of 1s. + return ReadRegister16(REGISTER_TEMPCAL5, std::chrono::seconds(1)); +} + + +pw::Result BMP180::readTempCal6() { + // Hard-coded timeout of 1s. + return ReadRegister16(REGISTER_TEMPCAL6, std::chrono::seconds(1)); +} + + +pw::Result BMP180::readTempCalMC() { + // Hard-coded timeout of 1s. + return ReadRegister16(REGISTER_TEMPCALMC, std::chrono::seconds(1)); +} + + +pw::Result BMP180::readTempCalMD() { + // Hard-coded timeout of 1s. + return ReadRegister16(REGISTER_TEMPCALMD, std::chrono::seconds(1)); +} + + + + +float BMP180::pressureasMbars() { + short ac1; // Variable declaration + short ac2; // Variable declaration + short ac3; // Variable declaration + uint16_t ac4; // Variable declaration + float b1; // Variable declaration + float c3; // Variable declaration + float c4; // Variable declaration + float p0; // Variable declaration + float p1; // Variable declaration + float p2; // Variable declaration + float pressure; // Variable declaration + float rawComp; // Variable declaration + float temperature; // Variable declaration + short vb1; // Variable declaration + short vb2; // Variable declaration + float x; // Variable declaration + float x1; // Variable declaration + float x2; // Variable declaration + float y; // Variable declaration + float y0; // Variable declaration + float y1; // Variable declaration + float y2; // Variable declaration + float z; // Variable declaration + + + writeControl(52); + pressure = readResult().value(); + temperature = temperatureasCelsius(); + pw::chrono::SystemClock::time_point before = pw::chrono::SystemClock::now(); + while (pw::chrono::SystemClock::now() - before < std::chrono::milliseconds(10)) {} + rawComp = (temperature-25); + ac1 = readPressureCalAC1().value(); + ac2 = readPressureCalAC2().value(); + x1 = (160*pow(2, -13)*ac2); + vb2 = readPressureCalVB2().value(); + x2 = (pow(160, 2)*pow(2, -25)*vb2); + x = ((x2*pow(rawComp, 2))+(x1*rawComp)+ac1); + ac3 = readTempCal3().value(); + c3 = (160*pow(2, -15)*ac3); + ac4 = readTempCal4().value(); + c4 = (pow(10, -3)*pow(2, -15)*ac4); + vb1 = readPressureCalVB1().value(); + b1 = (pow(160, 2)*pow(2, -30)*vb1); + y0 = (c4*pow(2, 15)); + y1 = (c4*c3); + y2 = (c4*b1); + y = ((y2*pow(rawComp, 2))+(y1*rawComp)+y0); + z = ((pressure-x)/y); + p0 = ((3791-8)/1600); + p1 = (1-(7357*pow(2, -30))); + p2 = (3038*100*pow(2, -36)); + pressure = ((p2*pow(z, 2))+(p1*z)+p0); + + + + return pressure; +} + +float BMP180::temperatureasCelsius() { + short rawComp; // Variable declaration + short rawMc; // Variable declaration + short rawMd; // Variable declaration + float temperature; // Variable declaration + uint16_t varAc5; // Variable declaration + uint16_t varAc6; // Variable declaration + float varC5; // Variable declaration + float varMc; // Variable declaration + float varMd; // Variable declaration + + + writeControl(46); + temperature = readResult().value(); + varAc5 = readTempCal5().value(); + varAc6 = readTempCal6().value(); + varC5 = ((pow(2, -15)/160)*varAc5); + rawComp = (varC5*(temperature-varAc6)); + rawMc = readTempCalMC().value(); + varMc = ((pow(2, 11)/pow(160, 2))*rawMc); + rawMd = readTempCalMD().value(); + varMd = (rawMd/160); + temperature = (rawComp+(varMc/(rawComp+varMd))); + + + return temperature; +} + diff --git a/test/sampleData/pigweed/BMP180.gn b/test/sampleData/pigweed/BMP180.gn new file mode 100644 index 0000000..6d18201 --- /dev/null +++ b/test/sampleData/pigweed/BMP180.gn @@ -0,0 +1,45 @@ +# Copyright 2021 Google LLC +# +# 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 +# +# https://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. + +import("//build_overrides/pigweed.gni") + +import("$dir_pw_build/target_types.gni") +import("$dir_pw_chrono/backend.gni") +import("$dir_pw_docgen/docs.gni") +import("$dir_pw_unit_test/test.gni") + +pw_source_set("BMP180") { + public = [ "BMP180.h" ] + sources = [ "BMP180.cc" ] + deps = [ + "$dir_pw_bytes", + "$dir_pw_chrono:system_clock", + "$dir_pw_i2c:address", + "$dir_pw_i2c:device", + "$dir_pw_i2c:initiator", + "$dir_pw_result", + "$dir_pw_status", + ] +} + +pw_test_group("tests") { + tests = [ + ":BMP180_test", + ] +} + +pw_test("BMP180_test") { + sources = [ "BMP180_test.cc" ] + deps = [ ":BMP180" ] +} \ No newline at end of file diff --git a/test/sampleData/pigweed/BMP180.h b/test/sampleData/pigweed/BMP180.h index 85ecd36..fb707cf 100644 --- a/test/sampleData/pigweed/BMP180.h +++ b/test/sampleData/pigweed/BMP180.h @@ -22,100 +22,103 @@ #pragma once +#include + #include "pw_bytes/byte_builder.h" #include "pw_chrono/system_clock.h" #include "pw_i2c/address.h" #include "pw_i2c/device.h" +#include "pw_i2c/register_device.h" #include "pw_i2c/initiator.h" #include "pw_result/result.h" #include "pw_status/status.h" -class BMP180 : RegisterDevice { +class BMP180 : pw::i2c::RegisterDevice { public: - BMP180(Initiator& initiator); + BMP180(pw::i2c::Initiator& initiator); /** * Stores the current measurement type. */ - Status writeControl(uint8_t data); + pw::Status writeControl(uint8_t data); /** * Constant register for pressure measurement calibration. */ - Result readPressureCalAC1(); + pw::Result readPressureCalAC1(); /** * Constant register for pressure measurement calibration. */ - Result readPressureCalAC2(); + pw::Result readPressureCalAC2(); /** * Constant register for pressure measurement calibration. */ - Result readPressureCalVB1(); + pw::Result readPressureCalVB1(); /** * Constant register for pressure measurement calibration. */ - Result readPressureCalVB2(); + pw::Result readPressureCalVB2(); /** * Stores the most recent measurement result. */ - Result readResult(); + pw::Result readResult(); /** * Third constant register for temperature measurement calibration. */ - Result readTempCal3(); + pw::Result readTempCal3(); /** * Fourth constant register for temperature measurement calibration. */ - Result readTempCal4(); + pw::Result readTempCal4(); /** * Fifth constant register for temperature measurement calibration. */ - Result readTempCal5(); + pw::Result readTempCal5(); /** * Sixth constant register for temperature measurement calibration. */ - Result readTempCal6(); + pw::Result readTempCal6(); /** * Constant register for temperature measurement calibration. */ - Result readTempCalMC(); + pw::Result readTempCalMC(); /** * Constant register for temperature measurement calibration. */ - Result readTempCalMD(); + pw::Result readTempCalMD(); diff --git a/test/sampleData/pigweed/BMP180_test.cc b/test/sampleData/pigweed/BMP180_test.cc new file mode 100644 index 0000000..72ab554 --- /dev/null +++ b/test/sampleData/pigweed/BMP180_test.cc @@ -0,0 +1,31 @@ +// Copyright 2021 Google LLC +// +// 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 +// +// https://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 +#include +#include + +#include "gtest/gtest.h" + +using namespace std::literals::chrono_literals; + +namespace pw::i2c { +namespace { + +TEST(Transaction, Read) { + EXPECT_EQ(1, 1); +} + +} // namespace +} // namespace pw::i2c \ No newline at end of file diff --git a/test/sampleData/pigweed/Example.cpp b/test/sampleData/pigweed/Example.cc similarity index 79% rename from test/sampleData/pigweed/Example.cpp rename to test/sampleData/pigweed/Example.cc index a38b4e6..6f6dfb2 100644 --- a/test/sampleData/pigweed/Example.cpp +++ b/test/sampleData/pigweed/Example.cc @@ -1,184 +1,185 @@ -/* -* Copyright (C) 2019 Google Inc. -* -* 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. -* -* Auto-generated file for Example v0.1.0. -* Generated from peripherals/example.yaml using Cyanobyte Codegen v0.0.2 -* Class for Example -* Example of a package - -*/ - - - - - -#define REGISTER_REGISTERA 0 -#define REGISTER_REGISTERB 1 -#define REGISTER_REGISTERC 2 -#define REGISTER_REGISTERD 3 - -Example::Example(Initiator& initiator, -Address address ): RegisterDevice(initiator, Address address), - std::endian::big, -register_address_size_(RegisterAddressSize::k1Byte) - ) { - DEVICE_ADDRESS ( address ) - } - -Result Example::readRegisterA() { - // Hard-coded timeout of 1s. - return ReadRegister8(REGISTER_REGISTERA, std::chrono::seconds(1)); -} - -Status Example::writeRegisterA(uint8_t data) { - // Hard-coded timeout of 1s. - return WriteRegister8(REGISTER_REGISTERA, data, std::chrono::seconds(1)) -} - -Result Example::readRegisterB() { - // Hard-coded timeout of 1s. - return ReadRegister16(REGISTER_REGISTERB, std::chrono::seconds(1)); -} - -Status Example::writeRegisterB(uint16_t data) { - // Hard-coded timeout of 1s. - return WriteRegister16(REGISTER_REGISTERB, data, std::chrono::seconds(1)) -} - -Result Example::readRegisterC() { - // Hard-coded timeout of 1s. - return ReadRegister32(REGISTER_REGISTERC, std::chrono::seconds(1)); -} - -Status Example::writeRegisterC(uint32_t data) { - // Hard-coded timeout of 1s. - return WriteRegister32(REGISTER_REGISTERC, data, std::chrono::seconds(1)) -} - -Result Example::readRegisterD() { - // Hard-coded timeout of 1s. - return ReadRegister8(REGISTER_REGISTERD, std::chrono::seconds(1)); -} - -Status Example::writeRegisterD() { - // Hard-coded timeout of 1s. - return WriteRegister8(REGISTER_REGISTERD, 0, std::chrono::seconds(1)) -} - - -Result Example::getFieldA() { - // Read register data - // '#/registers/RegisterA' > 'RegisterA' - Result res = readRegisterA(); - uint8_t val = res.value(); - // Mask register value - val = val & 0b0000000011110000; - // Bitshift value - val = val >> 4; - // Rewrap in a Result - Result result = new Result(val); - return result; -} - -Status Example::setFieldB(uint8_t data) { - // Bitshift value - data = data << 2; - // Read current register data - // '#/registers/RegisterA' > 'RegisterA' - Result res = readRegisterA(); - uint8_t register_data = res.value() - register_data = register_data | data; - return writeRegisterA(register_data); -} -Result Example::getFieldC() { - // Read register data - // '#/registers/RegisterA' > 'RegisterA' - Result res = readRegisterA(); - uint8_t val = res.value(); - // Mask register value - val = val & 0b0000000000000010; - // Bitshift value - val = val >> 1; - // Rewrap in a Result - Result result = new Result(val); - return result; -} - -Status Example::setFieldC(uint8_t data) { - // Bitshift value - data = data << 1; - // Read current register data - // '#/registers/RegisterA' > 'RegisterA' - Result res = readRegisterA(); - uint8_t register_data = res.value() - register_data = register_data | data; - return writeRegisterA(register_data); -} - -char Example::_lifecycleBegin() { - char output; // Variable declaration - - - output = 1; - writeRegisterA(output); - - - return output; -} - -char Example::_lifecycleEnd() { - char output; // Variable declaration - - - output = 1; - writeRegisterA(output); - - - return output; -} - -void Example::ReturnArray(short * returnArray) { - short summation; // Variable declaration - - - summation = (1024+1024); - writeRegisterA(summation); - - - returnArray[0] = summation; - returnArray[1] = summation; -} - -short Example::ReturnNumber() { - short summation; // Variable declaration - - - summation = (1024+1024); - writeRegisterA(summation); - - - return summation; -} - -void Example::ReturnVoid() { - short summation; // Variable declaration - - - summation = (1024+1024); - writeRegisterA(summation); - - -} - +/* +* Copyright (C) 2019 Google Inc. +* +* 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. +* +* Auto-generated file for Example v0.1.0. +* Generated from peripherals/example.yaml using Cyanobyte Codegen v0.0.2 +* Class for Example +* Example of a package + +*/ + + + + +#include "Example.h" + + +#define REGISTER_REGISTERA 0 +#define REGISTER_REGISTERB 1 +#define REGISTER_REGISTERC 2 +#define REGISTER_REGISTERD 3 + +Example::Example(pw::i2c::Initiator& initiator, pw::i2c::Address address): RegisterDevice(initiator, address), + std::endian::big, + pw::i2c::RegisterAddressSize::k1Byte) + { + DEVICE_ADDRESS ( address ) + } + +pw::Result Example::readRegisterA() { + // Hard-coded timeout of 1s. + return ReadRegister8(REGISTER_REGISTERA, std::chrono::seconds(1)); +} + +pw::Status Example::writeRegisterA(uint8_t data) { + // Hard-coded timeout of 1s. + return WriteRegister8(REGISTER_REGISTERA, data, std::chrono::seconds(1)); +} + +pw::Result Example::readRegisterB() { + // Hard-coded timeout of 1s. + return ReadRegister16(REGISTER_REGISTERB, std::chrono::seconds(1)); +} + +pw::Status Example::writeRegisterB(uint16_t data) { + // Hard-coded timeout of 1s. + return WriteRegister16(REGISTER_REGISTERB, data, std::chrono::seconds(1)); +} + +pw::Result Example::readRegisterC() { + // Hard-coded timeout of 1s. + return ReadRegister32(REGISTER_REGISTERC, std::chrono::seconds(1)); +} + +pw::Status Example::writeRegisterC(uint32_t data) { + // Hard-coded timeout of 1s. + return WriteRegister32(REGISTER_REGISTERC, data, std::chrono::seconds(1)); +} + +pw::Result Example::readRegisterD() { + // Hard-coded timeout of 1s. + return ReadRegister8(REGISTER_REGISTERD, std::chrono::seconds(1)); +} + +pw::Status Example::writeRegisterD() { + // Hard-coded timeout of 1s. + return WriteRegister8(REGISTER_REGISTERD, 0 /* No data */, std::chrono::seconds(1)); +} + + +pw::Result Example::getFieldA() { + // Read register data + // '#/registers/RegisterA' > 'RegisterA' + Result res = readRegisterA(); + uint8_t val = res.value(); + // Mask register value + val = val & 0b0000000011110000; + // Bitshift value + val = val >> 4; + // Rewrap in a Result + Result result = new Result(val); + return result; +} + +pw::Status Example::setFieldB(uint8_t data) { + // Bitshift value + data = data << 2; + // Read current register data + // '#/registers/RegisterA' > 'RegisterA' + Result res = readRegisterA(); + uint8_t register_data = res.value() + register_data = register_data | data; + return writeRegisterA(register_data); +} +pw::Result Example::getFieldC() { + // Read register data + // '#/registers/RegisterA' > 'RegisterA' + Result res = readRegisterA(); + uint8_t val = res.value(); + // Mask register value + val = val & 0b0000000000000010; + // Bitshift value + val = val >> 1; + // Rewrap in a Result + Result result = new Result(val); + return result; +} + +pw::Status Example::setFieldC(uint8_t data) { + // Bitshift value + data = data << 1; + // Read current register data + // '#/registers/RegisterA' > 'RegisterA' + Result res = readRegisterA(); + uint8_t register_data = res.value() + register_data = register_data | data; + return writeRegisterA(register_data); +} + +char Example::_lifecycleBegin() { + char output; // Variable declaration + + + output = 1; + writeRegisterA(output); + + + return output; +} + +char Example::_lifecycleEnd() { + char output; // Variable declaration + + + output = 1; + writeRegisterA(output); + + + return output; +} + +void Example::ReturnArray(short * returnArray) { + short summation; // Variable declaration + + + summation = (1024+1024); + writeRegisterA(summation); + + + returnArray[0] = summation; + returnArray[1] = summation; +} + +short Example::ReturnNumber() { + short summation; // Variable declaration + + + summation = (1024+1024); + writeRegisterA(summation); + + + return summation; +} + +void Example::ReturnVoid() { + short summation; // Variable declaration + + + summation = (1024+1024); + writeRegisterA(summation); + + +} + diff --git a/test/sampleData/pigweed/Example.gn b/test/sampleData/pigweed/Example.gn new file mode 100644 index 0000000..11e62dc --- /dev/null +++ b/test/sampleData/pigweed/Example.gn @@ -0,0 +1,45 @@ +# Copyright 2021 Google LLC +# +# 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 +# +# https://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. + +import("//build_overrides/pigweed.gni") + +import("$dir_pw_build/target_types.gni") +import("$dir_pw_chrono/backend.gni") +import("$dir_pw_docgen/docs.gni") +import("$dir_pw_unit_test/test.gni") + +pw_source_set("Example") { + public = [ "Example.h" ] + sources = [ "Example.cc" ] + deps = [ + "$dir_pw_bytes", + "$dir_pw_chrono:system_clock", + "$dir_pw_i2c:address", + "$dir_pw_i2c:device", + "$dir_pw_i2c:initiator", + "$dir_pw_result", + "$dir_pw_status", + ] +} + +pw_test_group("tests") { + tests = [ + ":Example_test", + ] +} + +pw_test("Example_test") { + sources = [ "Example_test.cc" ] + deps = [ ":Example" ] +} \ No newline at end of file diff --git a/test/sampleData/pigweed/Example.h b/test/sampleData/pigweed/Example.h index 13a333d..48d09c1 100644 --- a/test/sampleData/pigweed/Example.h +++ b/test/sampleData/pigweed/Example.h @@ -22,10 +22,13 @@ #pragma once +#include + #include "pw_bytes/byte_builder.h" #include "pw_chrono/system_clock.h" #include "pw_i2c/address.h" #include "pw_i2c/device.h" +#include "pw_i2c/register_device.h" #include "pw_i2c/initiator.h" #include "pw_result/result.h" #include "pw_status/status.h" @@ -48,75 +51,75 @@ enum deviceAddress { }; typedef enum deviceAddress deviceAddress_t; -class Example : RegisterDevice { +class Example : pw::i2c::RegisterDevice { public: - Example(Initiator& initiator, deviceAddress_t address); + Example(pw::i2c::Initiator& initiator, deviceAddress_t address); deviceAddress_t DEVICE_ADDRESS; /** * An 8-bit register */ - Result readRegisterA(); + pw::Result readRegisterA(); /** * An 8-bit register */ - Status writeRegisterA(uint8_t data); + pw::Status writeRegisterA(uint8_t data); /** * A 16-bit register */ - Result readRegisterB(); + pw::Result readRegisterB(); /** * A 16-bit register */ - Status writeRegisterB(uint16_t data); + pw::Status writeRegisterB(uint16_t data); /** * A 32-bit register */ - Result readRegisterC(); + pw::Result readRegisterC(); /** * A 32-bit register */ - Status writeRegisterC(uint32_t data); + pw::Status writeRegisterC(uint32_t data); /** * A dummy register that has no data */ - Result readRegisterD(); + pw::Result readRegisterD(); /** * A dummy register that has no data */ - Status writeRegisterD(); + pw::Status writeRegisterD(); /** * This is a few bits */ - Result getFieldA(); + pw::Result getFieldA(); /** * This is fewer bits */ - Status setFieldB(uint8_t data); + pw::Status setFieldB(uint8_t data); /** * A single-bit */ - Result getFieldC(); + pw::Result getFieldC(); /** * A single-bit */ - Status setFieldC(uint8_t data); + pw::Status setFieldC(uint8_t data); /** * Enables features on device diff --git a/test/sampleData/pigweed/Example_test.cc b/test/sampleData/pigweed/Example_test.cc new file mode 100644 index 0000000..72ab554 --- /dev/null +++ b/test/sampleData/pigweed/Example_test.cc @@ -0,0 +1,31 @@ +// Copyright 2021 Google LLC +// +// 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 +// +// https://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 +#include +#include + +#include "gtest/gtest.h" + +using namespace std::literals::chrono_literals; + +namespace pw::i2c { +namespace { + +TEST(Transaction, Read) { + EXPECT_EQ(1, 1); +} + +} // namespace +} // namespace pw::i2c \ No newline at end of file From 4679edbb5e7f53db4acf4aa79332d4cccc538090 Mon Sep 17 00:00:00 2001 From: Nick Date: Wed, 9 Jun 2021 18:41:54 -0400 Subject: [PATCH 8/9] Remove changes in this PR --- cloudbuild-deploy.yaml | 2 +- cloudbuild.yaml | 12 +++++------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/cloudbuild-deploy.yaml b/cloudbuild-deploy.yaml index d8021aa..46070db 100644 --- a/cloudbuild-deploy.yaml +++ b/cloudbuild-deploy.yaml @@ -26,7 +26,7 @@ steps: args: - 'cyanobyte/codegen.py' - '-t' - - 'cyanobyte-templates/doc.md' + - 'doc.md' - '-o' - './docs/content/docs/Reference/Peripheral Docs' - 'peripherals/ADS1015.yaml' diff --git a/cloudbuild.yaml b/cloudbuild.yaml index a3f1fd3..ea51db4 100644 --- a/cloudbuild.yaml +++ b/cloudbuild.yaml @@ -29,17 +29,15 @@ steps: args: - 'cyanobyte/codegen.py' - '-t' - - 'cyanobyte-templates/raspberrypi.py' + - 'raspberrypi' - '-t' - - 'cyanobyte-templates/arduino.cpp' + - 'arduino' - '-t' - - 'cyanobyte-templates/arduino.h' + - 'templates/kubos.c' - '-t' - - 'cyanobyte-templates/kubos.c' + - 'cmsis' - '-t' - - 'cyanobyte-templates/cmsis.svg' - - '-t' - - 'cyanobyte-templates/datasheet.tex' + - 'datasheet' - '-e' - '/workspace/emboss' - '-o' From a3c27d6439e95e74a361070ae02b10c1aaad3c95 Mon Sep 17 00:00:00 2001 From: Nick Date: Wed, 9 Jun 2021 18:42:19 -0400 Subject: [PATCH 9/9] Remove changes in this PR --- cloudbuild-deploy.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloudbuild-deploy.yaml b/cloudbuild-deploy.yaml index 46070db..d8e370d 100644 --- a/cloudbuild-deploy.yaml +++ b/cloudbuild-deploy.yaml @@ -26,7 +26,7 @@ steps: args: - 'cyanobyte/codegen.py' - '-t' - - 'doc.md' + - 'doc' - '-o' - './docs/content/docs/Reference/Peripheral Docs' - 'peripherals/ADS1015.yaml'