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); } diff --git a/cyanobyte-templates/pigweed.cc b/cyanobyte-templates/pigweed.cc new file mode 100644 index 0000000..20c4a7c --- /dev/null +++ b/cyanobyte-templates/pigweed.cc @@ -0,0 +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 #} + 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 new file mode 100644 index 0000000..add597d --- /dev/null +++ b/cyanobyte-templates/pigweed.h @@ -0,0 +1,111 @@ +{% 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 + +#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" + +{# 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}} : pw::i2c::RegisterDevice { + public: + {% if i2c.address is iterable and i2c.address is not string %} + {{info.title}}(pw::i2c::Initiator& initiator, deviceAddress_t address); + deviceAddress_t DEVICE_ADDRESS; + {% else %} + {{info.title}}(pw::i2c::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)}} + */ + 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)}} + */ + pw::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)}} + */ + pw::Result<{{cpp.registerSize(registers, field.register[12:])}}> get{{key}}(); + {% endif %} + {% if 'W' is in(field.readWrite) %} + /** +{{utils.pad_string(" * ", field.description)}} + */ + pw::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/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 diff --git a/test/sampleData/pigweed/BMP180.cc b/test/sampleData/pigweed/BMP180.cc new file mode 100644 index 0000000..ceac905 --- /dev/null +++ b/test/sampleData/pigweed/BMP180.cc @@ -0,0 +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 + +*/ + + + + +#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 new file mode 100644 index 0000000..fb707cf --- /dev/null +++ b/test/sampleData/pigweed/BMP180.h @@ -0,0 +1,138 @@ +/* +* 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 + +#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 : pw::i2c::RegisterDevice { + public: + BMP180(pw::i2c::Initiator& initiator); + + + /** + * Stores the current measurement type. + + */ + pw::Status writeControl(uint8_t data); + /** + * Constant register for pressure measurement calibration. + + */ + pw::Result readPressureCalAC1(); + + + /** + * Constant register for pressure measurement calibration. + + */ + pw::Result readPressureCalAC2(); + + + /** + * Constant register for pressure measurement calibration. + + */ + pw::Result readPressureCalVB1(); + + + /** + * Constant register for pressure measurement calibration. + + */ + pw::Result readPressureCalVB2(); + + + /** + * Stores the most recent measurement result. + + */ + pw::Result readResult(); + + + /** + * Third constant register for temperature measurement calibration. + + */ + pw::Result readTempCal3(); + + + /** + * Fourth constant register for temperature measurement calibration. + + */ + pw::Result readTempCal4(); + + + /** + * Fifth constant register for temperature measurement calibration. + + */ + pw::Result readTempCal5(); + + + /** + * Sixth constant register for temperature measurement calibration. + + */ + pw::Result readTempCal6(); + + + /** + * Constant register for temperature measurement calibration. + + */ + pw::Result readTempCalMC(); + + + /** + * Constant register for temperature measurement calibration. + + */ + pw::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/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.cc b/test/sampleData/pigweed/Example.cc new file mode 100644 index 0000000..6f6dfb2 --- /dev/null +++ b/test/sampleData/pigweed/Example.cc @@ -0,0 +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 + +*/ + + + + +#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 new file mode 100644 index 0000000..48d09c1 --- /dev/null +++ b/test/sampleData/pigweed/Example.h @@ -0,0 +1,151 @@ +/* +* 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 + +#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" + +/* + * 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 : pw::i2c::RegisterDevice { + public: + Example(pw::i2c::Initiator& initiator, deviceAddress_t address); + deviceAddress_t DEVICE_ADDRESS; + + /** + * An 8-bit register + + */ + pw::Result readRegisterA(); + + /** + * An 8-bit register + + */ + pw::Status writeRegisterA(uint8_t data); + /** + * A 16-bit register + + */ + pw::Result readRegisterB(); + + /** + * A 16-bit register + + */ + pw::Status writeRegisterB(uint16_t data); + /** + * A 32-bit register + + */ + pw::Result readRegisterC(); + + /** + * A 32-bit register + + */ + pw::Status writeRegisterC(uint32_t data); + /** + * A dummy register that has no data + + */ + pw::Result readRegisterD(); + + /** + * A dummy register that has no data + + */ + pw::Status writeRegisterD(); + /** + * This is a few bits + + */ + pw::Result getFieldA(); + /** + * This is fewer bits + + */ + pw::Status setFieldB(uint8_t data); + /** + * A single-bit + + */ + pw::Result getFieldC(); + /** + * A single-bit + + */ + pw::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 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