diff --git a/.gitignore b/.gitignore index 26deb9e..767843e 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ docs/public/ docs/resources/ package-lock.json **/.DS_Store +.vscode/ \ No newline at end of file diff --git a/docs/content/_index.html b/docs/content/_index.html index 48d136a..b57ac56 100644 --- a/docs/content/_index.html +++ b/docs/content/_index.html @@ -104,7 +104,8 @@

Current Status

At the moment Cyanobyte has support for I2C peripherals across many - peripherals and embedded platforms. + peripherals and embedded platforms. There is early support for other + serialization protocols like SPI. As Cyanobyte provides code generation support, there is @@ -130,6 +131,7 @@

- ESP32 - Espruino (Javascript) - KubOS + - CircuitPython - Micropython - Pimoroni I2C Device - Raspberry Pi @@ -142,6 +144,7 @@

{{% blocks/feature icon="fas fa-clipboard-list" title="Next Goals" %}} - Investigate other I2C peripherals like displays - Investigate support for new programming languages + - Improve support for other serial peripherals like SPI {{% /blocks/feature %}} {{< /blocks/section >}} diff --git a/requirements-dev.txt b/requirements-dev.txt index 80ba628..3e62033 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,3 +1,4 @@ cmsis-svd smbus -spidev \ No newline at end of file +spidev +adafruit-circuitpython-busdevice \ No newline at end of file diff --git a/templates/circuitpython.py b/templates/circuitpython.py new file mode 100644 index 0000000..c536de2 --- /dev/null +++ b/templates/circuitpython.py @@ -0,0 +1,235 @@ +{% import 'macros.jinja2' as utils %} +{% import 'python.jinja2' as py %} +{% set template = namespace(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 }} +""" +{% 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 %} + with self.i2c_device as i2c: + _byte_list = bytearray({{ bytes }}) + i2c.readinto(_byte_list) + {{key}} = 0 + {% for n in range(bytes) %} + {{key}} = {{key}} << 8 | _byte_list[{{n}}] + {% endfor %} + {% break %} +{% endif %} +{# Check if assignment is a send-op #} +{% if key == 'cmdWrite' %} + {% if 'value' in step[key] %} + self.set_{{step[key].register[12:].lower()}}({{step[key].value}}) + {% else %} + self.set_{{step[key].register[12:].lower()}}() + {% endif %} + {% break %} +{%- endif %} +{# Check if assignment op #} +{% if step[key] is string and step[key][0:1] == "=" %} + {{key | camel_to_snake}} {{step[key]}} +{%- endif %} +{# Check if assignment is a send-op #} +{% if key == 'send' %} + self.set_{{function.register[12:].lower()}}({{step[key]}}) +{%- endif %} +{# Check if assignment is register read op #} +{% if step[key] is string and step[key][:12] == '#/registers/' %} + {{key | camel_to_snake}} = self.get_{{step[key][12:].lower()}}() +{%- endif %} +{# Check if assignment is function call op #} +{% if step[key] is string and step[key][:12] == '#/functions/' %} + {{key | camel_to_snake}} = self.{{step[key].lower() | 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 | camel_to_snake}} = {{py.recursiveAssignLogic(step[key][0], step[key][0].keys()) -}} +{%- endif %} + +{% endfor %} +{%- endfor %} +{%- endmacro %} + +{{ py.importUstdLibs(fields, functions, template) -}} +from adafruit_bus_device.i2c_device import I2CDevice + +{# Create enums for fields #} +{% if fields %} +{% for key,field in fields|dictsort %} +{% if field.enum %} +{# Create enum-like constants #} +{% for ekey,enum in field.enum|dictsort %} +{{key.upper()}}_{{ekey.upper()}} = {{enum.value}} # {{enum.title}} +{% endfor %} + +{% endif %} +{% endfor %} +{% endif %} +{% if i2c.address is iterable and i2c.address is not string %} +{% for address in i2c.address %} +I2C_ADDRESS_{{address}} = {{address}} +{% endfor %} + +{% endif %} + +{{ py.importLittleEndian(i2c) }} + +{{ py.importSign(registers, template) }} + +class {{ info.title }}: + """ +{{utils.pad_string(" ", info.description)}} + """ + {% if i2c.address is number %} + device_address = {{i2c.address}} + {% endif %} + {% for key,register in registers|dictsort %} + REGISTER_{{key.upper()}} = {{register.address}} + {% endfor %} + + {% if i2c.address is iterable and i2c.address is not string %} + def __init__(self, i2c, address): + # Initialize connection to peripheral + self.i2c_device = I2CDevice(i2c, address) + self.device_address = address + {% else %} + def __init__(self, i2c): + # Initialize connection to peripheral + self.i2c_device = I2CDevice(i2c, {{ i2c.address }}) + self.i2c = i2c + {% endif %} + {% if '_lifecycle' in functions and 'Begin' in functions._lifecycle.computed %} + self._lifecycle_begin() + {% endif %} + + {% for key,register in registers|dictsort %} + {% set bytes = (register.length / 8) | round(1, 'ceil') | int %} + {% if (not 'readWrite' in register) or ('readWrite' in register and 'R' is in(register.readWrite)) %} + def get_{{key.lower()}}(self): + """ +{{utils.pad_string(" ", register.description)}} + """ + write_list = bytearray(1) + write_list[0] = self.REGISTER_{{key.upper()}} + read_list = bytearray({{ bytes }}) + with self.i2c_device as i2c: + i2c.write_then_readinto(write_list, read_list) + val = 0 + {% for n in range(bytes) %} + val = val << 8 | read_list[{{n}}] + {% endfor %} + {% if i2c.endian == 'little' %} + val = _swap_endian(val, {{register.length}}) + {% endif %} + {% if register.signed %} + # Unsigned > Signed integer + val = _sign(val, {{register.length}}) + {% endif %} + return val + {% endif %} + + {% if (not 'readWrite' in register) or ('readWrite' in register and 'W' is in(register.readWrite)) %} + def set_{{key.lower()}}(self{% if register.length > 0 %}, data{% endif %}): + """ +{{utils.pad_string(" ", register.description)}} + """ + {% if i2c.endian == 'little' %} + data = _swap_endian(data, {{register.length}}) + {% endif %} + buffer = bytearray({{ bytes }}) + {% for n in range(bytes) %} + buffer[{{n}}] = (data >> {{8 * (bytes - n - 1)}}) & 0xFF + {% endfor %} + with self.i2c_device as i2c: + i2c.write(buffer) + {% endif %} + {% endfor %} + + {% if fields %} + {% for key,field in fields|dictsort %} + {% if 'R' is in(field.readWrite) %} + {# Getter #} + + def get_{{key.lower()}}(self): + """ +{{utils.pad_string(" ", field.description)}} + """ + # Read register data + # '#/registers/{{field.register[12:]}}' > '{{field.register[12:]}}' + val = self.get_{{field.register[12:].lower()}}() + # Mask register value + val = val & {{utils.mask(field.bitStart, field.bitEnd)}} + {% if field.bitEnd %} + # Bitshift value + val = val >> {{field.bitEnd}} + {% endif %} + return val + {% endif -%} + + {%- if 'W' is in(field.readWrite) %} + {# Setter #} + + def set_{{key.lower()}}(self, data): + """ +{{utils.pad_string(" ", field.description)}} + """ + {% if field.bitEnd %} + # Bitshift value + data = data << {{field.bitEnd}} + {% endif %} + # Read current register data + # '#/registers/{{field.register[12:]}}' > '{{field.register[12:]}}' + register_data = self.get_{{field.register[12:].lower()}}() + register_data = register_data | data + self.set_{{field.register[12:].lower()}}(register_data) + {% endif %} + {% endfor %} + {% endif %} + {% if functions %} + {% for key,function in functions|dictsort %} + {% for ckey,compute in function.computed|dictsort %} + {% if compute.input %} + def {{key.lower()}}_{{ckey.lower()}}(self, {{py.params(compute.input)}}): + {% else %} + def {{key.lower()}}_{{ckey.lower()}}(self): + {% endif %} + """ +{{utils.pad_string(" ", function.description)}} + """ + {# Declare our variables #} +{{ py.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 + value = self.get_{{function.register[12:].lower()}}() + {% 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 %} + return [{% for returnValue in compute.return %}{{ returnValue | camel_to_snake }}{{ ", " if not loop.last }}{% endfor %}] + {# Return a plain value #} + {% elif compute.return is string %} + {# See if we need to massage the data type #} + {% if compute.output == 'int16' %} + # Convert from a unsigned short to a signed short + {{compute.return}} = ustruct.unpack("h", ustruct.pack("H", {{compute.return}}))[0] + {% endif %} + return {{compute.return}} + {% endif %} + {% endfor %} + {% endfor %} + {% endif %} \ No newline at end of file diff --git a/test/sampleData/circuitpython/ADS1015.py b/test/sampleData/circuitpython/ADS1015.py new file mode 100644 index 0000000..221218c --- /dev/null +++ b/test/sampleData/circuitpython/ADS1015.py @@ -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 ADS1015 v0.1.0. +# Generated from peripherals/ADS1015.yaml using Cyanobyte Codegen v0.1.0 +""" +Class for ADS1015 +""" + +from adafruit_bus_device.i2c_device import I2CDevice + +CHANNEL_CHANNEL_1 = 0 # Channel 1 +CHANNEL_CHANNEL_2 = 1 # Channel 2 +CHANNEL_CHANNEL_3 = 2 # Channel 3 +CHANNEL_CHANNEL_4 = 3 # Channel 4 + +DEVICEOPERATINGMODE_CONTINUOUS_CONVERSION = 0 # Continuous Conversion +DEVICEOPERATINGMODE_SINGLE_SHOT = 1 # Single-shot or power-down state + +PROGRAMMABLEGAIN_PGA0_256 = 5 # Plus/minus 0.256V +PROGRAMMABLEGAIN_PGA0_512 = 4 # Plus/minus 0.512V +PROGRAMMABLEGAIN_PGA1_024V = 3 # Plus/minus 1.024V +PROGRAMMABLEGAIN_PGA2_048V = 2 # Plus/minus 2.048V +PROGRAMMABLEGAIN_PGA4_096V = 1 # Plus/minus 4.096V +PROGRAMMABLEGAIN_PGA6_144V = 0 # Plus/minus 6.144V + +SAMPLERATE_HZ128 = 0 # 128 samples/second +SAMPLERATE_HZ1600 = 4 # 1600 samples/second +SAMPLERATE_HZ2400 = 5 # 2400 samples/second +SAMPLERATE_HZ250 = 1 # 250 samples/second +SAMPLERATE_HZ3300 = 6 # 3300 samples/second +SAMPLERATE_HZ490 = 2 # 490 samples/second +SAMPLERATE_HZ920 = 3 # 920 samples/second + + +def _swap_endian(val, length): + """ + Swap the endianness of a number + """ + if length <= 8: + return val + if length <= 16: + return (val & 0xFF00) >> 8 | (val & 0xFF) << 8 + if length <= 32: + return ((val & 0xFF000000) >> 24 | + (val & 0x00FF0000) >> 8 | + (val & 0x0000FF00) << 8 | + (val & 0x000000FF) << 24) + raise Exception('Cannot swap endianness for length ' + length) + + + + +class ADS1015: + """ + Texas Instruments Analog-Digital Converter + + """ + device_address = 73 + REGISTER_CONFIG = 1 + REGISTER_CONVERSION = 0 + + def __init__(self, i2c): + # Initialize connection to peripheral + self.i2c_device = I2CDevice(i2c, 73) + self.i2c = i2c + + def get_config(self): + """ + Describes the specifics of the sensing implementation + + """ + write_list = bytearray(1) + write_list[0] = self.REGISTER_CONFIG + read_list = bytearray(2) + with self.i2c_device as i2c: + i2c.write_then_readinto(write_list, read_list) + val = 0 + val = val << 8 | read_list[0] + val = val << 8 | read_list[1] + val = _swap_endian(val, 16) + return val + + def set_config(self, data): + """ + Describes the specifics of the sensing implementation + + """ + data = _swap_endian(data, 16) + buffer = bytearray(2) + buffer[0] = (data >> 8) & 0xFF + buffer[1] = (data >> 0) & 0xFF + with self.i2c_device as i2c: + i2c.write(buffer) + def get_conversion(self): + """ + Conversion register contains the result of the last conversion + + """ + write_list = bytearray(1) + write_list[0] = self.REGISTER_CONVERSION + read_list = bytearray(2) + with self.i2c_device as i2c: + i2c.write_then_readinto(write_list, read_list) + val = 0 + val = val << 8 | read_list[0] + val = val << 8 | read_list[1] + val = _swap_endian(val, 16) + return val + + + + def set_deviceoperatingmode(self, data): + """ + This bit controls the operating mode + + """ + # Bitshift value + data = data << 8 + # Read current register data + # '#/registers/Config' > 'Config' + register_data = self.get_config() + register_data = register_data | data + self.set_config(register_data) + + def set_programmablegain(self, data): + """ + This sets the programmable gain for reading analog voltage + + """ + # Bitshift value + data = data << 9 + # Read current register data + # '#/registers/Config' > 'Config' + register_data = self.get_config() + register_data = register_data | data + self.set_config(register_data) + + def set_samplerate(self, data): + """ + This sets the samples-per-second value + + """ + # Bitshift value + data = data << 5 + # Read current register data + # '#/registers/Config' > 'Config' + register_data = self.get_config() + register_data = register_data | data + self.set_config(register_data) + def analog_read(self, channel): + """ + Reads the analog voltage in Volts + + """ + config = None # Variable declaration + datum_a = None # Variable declaration + datum_b = None # Variable declaration + processed = None # Variable declaration + programmable_gain = None # Variable declaration + raw = None # Variable declaration + + config = self.get_config() + config = (config|(channel << 12)) + config = (config|32768) + self.set_config(config) + raw = self.get_conversion() + datum_a = (raw&65280) + datum_a = (datum_a >> 8) + datum_b = (raw&255) + processed = ((datum_a << 4)|(datum_b >> 4)) + programmable_gain = 6144 + processed = ((processed/2047/1000)*programmable_gain) + return processed diff --git a/test/sampleData/circuitpython/BH1750FVI.py b/test/sampleData/circuitpython/BH1750FVI.py new file mode 100644 index 0000000..2885f6a --- /dev/null +++ b/test/sampleData/circuitpython/BH1750FVI.py @@ -0,0 +1,172 @@ +# 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 BH1750FVI v0.1.0. +# Generated from peripherals/BH1750FVI.yaml using Cyanobyte Codegen v0.1.0 +""" +Class for BH1750FVI +""" + +from adafruit_bus_device.i2c_device import I2CDevice + +I2C_ADDRESS_35 = 35 +I2C_ADDRESS_92 = 92 + + + + + + +class BH1750FVI: + """ + Rohm Light Sensor + + """ + REGISTER_CONTINUOUSHRES2MODE = 17 + REGISTER_CONTINUOUSHRESMODE = 16 + REGISTER_CONTINUOUSLYLRESMODE = 19 + REGISTER_ONCEHRES2MODE = 33 + REGISTER_ONCEHRESMODE = 32 + REGISTER_ONCELRESMODE = 35 + REGISTER_POWERDOWN = 0 + REGISTER_POWERON = 1 + REGISTER_RESET = 7 + + def __init__(self, i2c, address): + # Initialize connection to peripheral + self.i2c_device = I2CDevice(i2c, address) + self.device_address = address + self._lifecycle_begin() + + + def set_continuoushres2mode(self): + """ + Start measurement at 0.5lx resolution. Typically 120ms. + + """ + buffer = bytearray(0) + with self.i2c_device as i2c: + i2c.write(buffer) + + def set_continuoushresmode(self): + """ + Start measurement at 1lx resolution. Typically 120ms. + + """ + buffer = bytearray(0) + with self.i2c_device as i2c: + i2c.write(buffer) + + def set_continuouslylresmode(self): + """ + Start measurement at 4lx resolution. Typically 16ms. + + """ + buffer = bytearray(0) + with self.i2c_device as i2c: + i2c.write(buffer) + + def set_oncehres2mode(self): + """ + Start measurement at 0.5lx resolution. Typically 120ms. + Power Down after measurement. + + """ + buffer = bytearray(0) + with self.i2c_device as i2c: + i2c.write(buffer) + + def set_oncehresmode(self): + """ + Start measurement at 1lx resolution. Typically 120ms. + Power Down after measurement. + + """ + buffer = bytearray(0) + with self.i2c_device as i2c: + i2c.write(buffer) + + def set_oncelresmode(self): + """ + Start measurement at 4lx resolution. Typically 16ms. + Power Down after measurement. + + """ + buffer = bytearray(0) + with self.i2c_device as i2c: + i2c.write(buffer) + + def set_powerdown(self): + """ + No active state + + """ + buffer = bytearray(0) + with self.i2c_device as i2c: + i2c.write(buffer) + + def set_poweron(self): + """ + Waiting for measurement command + + """ + buffer = bytearray(0) + with self.i2c_device as i2c: + i2c.write(buffer) + + def set_reset(self): + """ + Reset data register value. Not accepted in Power Down mode. + + """ + buffer = bytearray(0) + with self.i2c_device as i2c: + i2c.write(buffer) + + def _lifecycle_begin(self): + """ + Sends a POWER ON cmd to device + + """ + + self.set_poweron() + def command_powerdown(self): + """ + Things you can do to device + + """ + + self.set_powerdown() + def command_reset(self): + """ + Things you can do to device + + """ + + self.set_poweron() + self.set_reset() + def read_lightintensity(self): + """ + Read light intensity from device + + """ + intensity = None # Variable declaration + + with self.i2c_device as i2c: + _byte_list = bytearray(2) + i2c.readinto(_byte_list) + intensity = 0 + intensity = intensity << 8 | _byte_list[0] + intensity = intensity << 8 | _byte_list[1] + return intensity diff --git a/test/sampleData/circuitpython/BMP180.py b/test/sampleData/circuitpython/BMP180.py new file mode 100644 index 0000000..e6df047 --- /dev/null +++ b/test/sampleData/circuitpython/BMP180.py @@ -0,0 +1,255 @@ +# 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.1.0 +""" +Class for BMP180 +""" + +import math +from adafruit_bus_device.i2c_device import I2CDevice + + + + + + +class BMP180: + """ + Bosch Digital Temperature / Pressure Sensor + + """ + device_address = 119 + REGISTER_CONTROL = 244 + REGISTER_PRESSURECALAC1 = 170 + REGISTER_PRESSURECALAC2 = 172 + REGISTER_PRESSURECALVB1 = 182 + REGISTER_PRESSURECALVB2 = 184 + REGISTER_RESULT = 246 + REGISTER_TEMPCAL3 = 174 + REGISTER_TEMPCAL4 = 176 + REGISTER_TEMPCAL5 = 178 + REGISTER_TEMPCAL6 = 180 + REGISTER_TEMPCALMC = 188 + REGISTER_TEMPCALMD = 190 + + def __init__(self, i2c): + # Initialize connection to peripheral + self.i2c_device = I2CDevice(i2c, 119) + self.i2c = i2c + + + def set_control(self, data): + """ + Register stores what the measurement type should be + + """ + buffer = bytearray(1) + buffer[0] = (data >> 0) & 0xFF + with self.i2c_device as i2c: + i2c.write(buffer) + def get_pressurecalac1(self): + """ + For calibration + + """ + write_list = bytearray(1) + write_list[0] = self.REGISTER_PRESSURECALAC1 + read_list = bytearray(2) + with self.i2c_device as i2c: + i2c.write_then_readinto(write_list, read_list) + val = 0 + val = val << 8 | read_list[0] + val = val << 8 | read_list[1] + return val + + def get_pressurecalac2(self): + """ + For calibration + + """ + write_list = bytearray(1) + write_list[0] = self.REGISTER_PRESSURECALAC2 + read_list = bytearray(2) + with self.i2c_device as i2c: + i2c.write_then_readinto(write_list, read_list) + val = 0 + val = val << 8 | read_list[0] + val = val << 8 | read_list[1] + return val + + def get_pressurecalvb1(self): + """ + For calibration + + """ + write_list = bytearray(1) + write_list[0] = self.REGISTER_PRESSURECALVB1 + read_list = bytearray(2) + with self.i2c_device as i2c: + i2c.write_then_readinto(write_list, read_list) + val = 0 + val = val << 8 | read_list[0] + val = val << 8 | read_list[1] + return val + + def get_pressurecalvb2(self): + """ + For calibration + + """ + write_list = bytearray(1) + write_list[0] = self.REGISTER_PRESSURECALVB2 + read_list = bytearray(2) + with self.i2c_device as i2c: + i2c.write_then_readinto(write_list, read_list) + val = 0 + val = val << 8 | read_list[0] + val = val << 8 | read_list[1] + return val + + def get_result(self): + """ + Register stores most recent measurement result + + """ + write_list = bytearray(1) + write_list[0] = self.REGISTER_RESULT + read_list = bytearray(2) + with self.i2c_device as i2c: + i2c.write_then_readinto(write_list, read_list) + val = 0 + val = val << 8 | read_list[0] + val = val << 8 | read_list[1] + return val + + def get_tempcal3(self): + """ + For calibration + + """ + write_list = bytearray(1) + write_list[0] = self.REGISTER_TEMPCAL3 + read_list = bytearray(2) + with self.i2c_device as i2c: + i2c.write_then_readinto(write_list, read_list) + val = 0 + val = val << 8 | read_list[0] + val = val << 8 | read_list[1] + return val + + def get_tempcal4(self): + """ + For calibration + + """ + write_list = bytearray(1) + write_list[0] = self.REGISTER_TEMPCAL4 + read_list = bytearray(2) + with self.i2c_device as i2c: + i2c.write_then_readinto(write_list, read_list) + val = 0 + val = val << 8 | read_list[0] + val = val << 8 | read_list[1] + return val + + def get_tempcal5(self): + """ + For calibration + + """ + write_list = bytearray(1) + write_list[0] = self.REGISTER_TEMPCAL5 + read_list = bytearray(2) + with self.i2c_device as i2c: + i2c.write_then_readinto(write_list, read_list) + val = 0 + val = val << 8 | read_list[0] + val = val << 8 | read_list[1] + return val + + def get_tempcal6(self): + """ + For calibration + + """ + write_list = bytearray(1) + write_list[0] = self.REGISTER_TEMPCAL6 + read_list = bytearray(2) + with self.i2c_device as i2c: + i2c.write_then_readinto(write_list, read_list) + val = 0 + val = val << 8 | read_list[0] + val = val << 8 | read_list[1] + return val + + def get_tempcalmc(self): + """ + For calibration + + """ + write_list = bytearray(1) + write_list[0] = self.REGISTER_TEMPCALMC + read_list = bytearray(2) + with self.i2c_device as i2c: + i2c.write_then_readinto(write_list, read_list) + val = 0 + val = val << 8 | read_list[0] + val = val << 8 | read_list[1] + return val + + def get_tempcalmd(self): + """ + For calibration + + """ + write_list = bytearray(1) + write_list[0] = self.REGISTER_TEMPCALMD + read_list = bytearray(2) + with self.i2c_device as i2c: + i2c.write_then_readinto(write_list, read_list) + val = 0 + val = val << 8 | read_list[0] + val = val << 8 | read_list[1] + return val + + + def temperature_ascelsius(self): + """ + Reads the temperature + + """ + raw_comp = None # Variable declaration + raw_mc = None # Variable declaration + raw_md = None # Variable declaration + temperature = None # Variable declaration + var_ac5 = None # Variable declaration + var_ac6 = None # Variable declaration + var_c5 = None # Variable declaration + var_mc = None # Variable declaration + var_md = None # Variable declaration + + self.set_control(46) + temperature = self.get_result() + var_ac5 = self.get_tempcal5() + var_ac6 = self.get_tempcal6() + var_c5 = ((math.pow(2, -15)/160)*var_ac5) + raw_comp = (var_c5*(temperature-var_ac6)) + raw_mc = self.get_tempcalmc() + var_mc = ((math.pow(2, 11)/math.pow(160, 2))*raw_mc) + raw_md = self.get_tempcalmd() + var_md = (raw_md/160) + temperature = (raw_comp+(var_mc/(raw_comp+var_md))) + return temperature diff --git a/test/sampleData/circuitpython/BMP280.py b/test/sampleData/circuitpython/BMP280.py new file mode 100644 index 0000000..92fd6e8 --- /dev/null +++ b/test/sampleData/circuitpython/BMP280.py @@ -0,0 +1,459 @@ +# 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 BMP280 v0.1.0. +# Generated from peripherals/BMP280.yaml using Cyanobyte Codegen v0.1.0 +""" +Class for BMP280 +""" + +from adafruit_bus_device.i2c_device import I2CDevice + + + + +def _sign(val, length): + """ + Convert unsigned integer to signed integer + """ + if val & (1 << (length - 1)): + return val - (1 << length) + return val + + +class BMP280: + """ + Bosch Digital Pressure Sensor + + """ + device_address = 119 + REGISTER_DIGP1 = 142 + REGISTER_DIGP2 = 144 + REGISTER_DIGP3 = 146 + REGISTER_DIGP4 = 148 + REGISTER_DIGP5 = 150 + REGISTER_DIGP6 = 152 + REGISTER_DIGP7 = 154 + REGISTER_DIGP8 = 156 + REGISTER_DIGP9 = 158 + REGISTER_DIGT1 = 136 + REGISTER_DIGT2 = 138 + REGISTER_DIGT3 = 140 + REGISTER_PRESSURELSB = 248 + REGISTER_PRESSUREMSB = 247 + REGISTER_PRESSUREXLSB = 249 + REGISTER_TEMPLSB = 251 + REGISTER_TEMPMSB = 250 + REGISTER_TEMPXLSB = 252 + + def __init__(self, i2c): + # Initialize connection to peripheral + self.i2c_device = I2CDevice(i2c, 119) + self.i2c = i2c + + def get_digp1(self): + """ + Used for Pascals conversion + + """ + write_list = bytearray(1) + write_list[0] = self.REGISTER_DIGP1 + read_list = bytearray(2) + with self.i2c_device as i2c: + i2c.write_then_readinto(write_list, read_list) + val = 0 + val = val << 8 | read_list[0] + val = val << 8 | read_list[1] + return val + + def get_digp2(self): + """ + Used for Pascals conversion + + """ + write_list = bytearray(1) + write_list[0] = self.REGISTER_DIGP2 + read_list = bytearray(2) + with self.i2c_device as i2c: + i2c.write_then_readinto(write_list, read_list) + val = 0 + val = val << 8 | read_list[0] + val = val << 8 | read_list[1] + # Unsigned > Signed integer + val = _sign(val, 16) + return val + + def get_digp3(self): + """ + Used for Pascals conversion + + """ + write_list = bytearray(1) + write_list[0] = self.REGISTER_DIGP3 + read_list = bytearray(2) + with self.i2c_device as i2c: + i2c.write_then_readinto(write_list, read_list) + val = 0 + val = val << 8 | read_list[0] + val = val << 8 | read_list[1] + # Unsigned > Signed integer + val = _sign(val, 16) + return val + + def get_digp4(self): + """ + Used for Pascals conversion + + """ + write_list = bytearray(1) + write_list[0] = self.REGISTER_DIGP4 + read_list = bytearray(2) + with self.i2c_device as i2c: + i2c.write_then_readinto(write_list, read_list) + val = 0 + val = val << 8 | read_list[0] + val = val << 8 | read_list[1] + # Unsigned > Signed integer + val = _sign(val, 16) + return val + + def get_digp5(self): + """ + Used for Pascals conversion + + """ + write_list = bytearray(1) + write_list[0] = self.REGISTER_DIGP5 + read_list = bytearray(2) + with self.i2c_device as i2c: + i2c.write_then_readinto(write_list, read_list) + val = 0 + val = val << 8 | read_list[0] + val = val << 8 | read_list[1] + # Unsigned > Signed integer + val = _sign(val, 16) + return val + + def get_digp6(self): + """ + Used for Pascals conversion + + """ + write_list = bytearray(1) + write_list[0] = self.REGISTER_DIGP6 + read_list = bytearray(2) + with self.i2c_device as i2c: + i2c.write_then_readinto(write_list, read_list) + val = 0 + val = val << 8 | read_list[0] + val = val << 8 | read_list[1] + # Unsigned > Signed integer + val = _sign(val, 16) + return val + + def get_digp7(self): + """ + Used for Pascals conversion + + """ + write_list = bytearray(1) + write_list[0] = self.REGISTER_DIGP7 + read_list = bytearray(2) + with self.i2c_device as i2c: + i2c.write_then_readinto(write_list, read_list) + val = 0 + val = val << 8 | read_list[0] + val = val << 8 | read_list[1] + # Unsigned > Signed integer + val = _sign(val, 16) + return val + + def get_digp8(self): + """ + Used for Pascals conversion + + """ + write_list = bytearray(1) + write_list[0] = self.REGISTER_DIGP8 + read_list = bytearray(2) + with self.i2c_device as i2c: + i2c.write_then_readinto(write_list, read_list) + val = 0 + val = val << 8 | read_list[0] + val = val << 8 | read_list[1] + # Unsigned > Signed integer + val = _sign(val, 16) + return val + + def get_digp9(self): + """ + Used for Pascals conversion + + """ + write_list = bytearray(1) + write_list[0] = self.REGISTER_DIGP9 + read_list = bytearray(2) + with self.i2c_device as i2c: + i2c.write_then_readinto(write_list, read_list) + val = 0 + val = val << 8 | read_list[0] + val = val << 8 | read_list[1] + # Unsigned > Signed integer + val = _sign(val, 16) + return val + + def get_digt1(self): + """ + Used for Celcius conversion + + """ + write_list = bytearray(1) + write_list[0] = self.REGISTER_DIGT1 + read_list = bytearray(2) + with self.i2c_device as i2c: + i2c.write_then_readinto(write_list, read_list) + val = 0 + val = val << 8 | read_list[0] + val = val << 8 | read_list[1] + return val + + def get_digt2(self): + """ + Used for Celcius conversion + + """ + write_list = bytearray(1) + write_list[0] = self.REGISTER_DIGT2 + read_list = bytearray(2) + with self.i2c_device as i2c: + i2c.write_then_readinto(write_list, read_list) + val = 0 + val = val << 8 | read_list[0] + val = val << 8 | read_list[1] + return val + + def get_digt3(self): + """ + Used for Celcius conversion + + """ + write_list = bytearray(1) + write_list[0] = self.REGISTER_DIGT3 + read_list = bytearray(2) + with self.i2c_device as i2c: + i2c.write_then_readinto(write_list, read_list) + val = 0 + val = val << 8 | read_list[0] + val = val << 8 | read_list[1] + # Unsigned > Signed integer + val = _sign(val, 16) + return val + + def get_pressurelsb(self): + """ + Part 2 of Pressure + + """ + write_list = bytearray(1) + write_list[0] = self.REGISTER_PRESSURELSB + read_list = bytearray(1) + with self.i2c_device as i2c: + i2c.write_then_readinto(write_list, read_list) + val = 0 + val = val << 8 | read_list[0] + return val + + def get_pressuremsb(self): + """ + Part 1 of Pressure + + """ + write_list = bytearray(1) + write_list[0] = self.REGISTER_PRESSUREMSB + read_list = bytearray(1) + with self.i2c_device as i2c: + i2c.write_then_readinto(write_list, read_list) + val = 0 + val = val << 8 | read_list[0] + return val + + def get_pressurexlsb(self): + """ + Part 3 of Pressure + + """ + write_list = bytearray(1) + write_list[0] = self.REGISTER_PRESSUREXLSB + read_list = bytearray(1) + with self.i2c_device as i2c: + i2c.write_then_readinto(write_list, read_list) + val = 0 + val = val << 8 | read_list[0] + return val + + def get_templsb(self): + """ + Part 2 of temperature + + """ + write_list = bytearray(1) + write_list[0] = self.REGISTER_TEMPLSB + read_list = bytearray(1) + with self.i2c_device as i2c: + i2c.write_then_readinto(write_list, read_list) + val = 0 + val = val << 8 | read_list[0] + return val + + def get_tempmsb(self): + """ + Part 1 of temperature + + """ + write_list = bytearray(1) + write_list[0] = self.REGISTER_TEMPMSB + read_list = bytearray(1) + with self.i2c_device as i2c: + i2c.write_then_readinto(write_list, read_list) + val = 0 + val = val << 8 | read_list[0] + return val + + def get_tempxlsb(self): + """ + Final part of temperature + + """ + write_list = bytearray(1) + write_list[0] = self.REGISTER_TEMPXLSB + read_list = bytearray(1) + with self.i2c_device as i2c: + i2c.write_then_readinto(write_list, read_list) + val = 0 + val = val << 8 | read_list[0] + return val + + + def pressure_ashpa(self): + """ + Reads the atmospheric pressure + + """ + hpa = None # Variable declaration + raw_comp1 = None # Variable declaration + raw_comp2 = None # Variable declaration + raw_comp3 = None # Variable declaration + raw_pressure = None # Variable declaration + raw_temperature = None # Variable declaration + value_d_p1 = None # Variable declaration + value_d_p2 = None # Variable declaration + value_d_p3 = None # Variable declaration + value_d_p4 = None # Variable declaration + value_d_p5 = None # Variable declaration + value_d_p6 = None # Variable declaration + value_d_p7 = None # Variable declaration + value_d_p8 = None # Variable declaration + value_d_p9 = None # Variable declaration + value_lsb = None # Variable declaration + value_msb = None # Variable declaration + value_xlsb = None # Variable declaration + + value_msb = self.get_pressuremsb() + value_lsb = self.get_pressurelsb() + value_xlsb = self.get_pressurexlsb() + value_d_p1 = self.get_digp1() + value_d_p2 = self.get_digp2() + value_d_p3 = self.get_digp3() + value_d_p4 = self.get_digp4() + value_d_p5 = self.get_digp5() + value_d_p6 = self.get_digp6() + value_d_p7 = self.get_digp7() + value_d_p8 = self.get_digp8() + value_d_p9 = self.get_digp9() + raw_temperature = self.temperature_ascelsius() + raw_temperature = (raw_temperature*5120.0) + raw_pressure = ((value_msb << 12)+(value_lsb << 4)+(value_xlsb >> 4)) + raw_comp1 = ((raw_temperature/2)-64000.0) + raw_comp2 = ((raw_comp1*raw_comp1*value_d_p6)/32768.0) + raw_comp2 = (raw_comp2+(raw_comp1*value_d_p5*2.0)) + raw_comp2 = ((raw_comp2/4.0)+(value_d_p4*65536.0)) + raw_comp3 = (value_d_p3*raw_comp1*raw_comp1) + raw_comp1 = (((raw_comp3/524288.0)+(value_d_p2*raw_comp1))/524288.0) + raw_comp1 = ((1.0+(raw_comp1/32768.0))*value_d_p1) + hpa = (1048576.0-raw_pressure) + hpa = ((hpa-(raw_comp2/4096.0))*(6250.0/raw_comp1)) + raw_comp1 = ((value_d_p9*hpa*hpa)/2147483648.0) + raw_comp2 = ((hpa*value_d_p8)/32768.0) + hpa = (hpa+((raw_comp1+raw_comp2+value_d_p7)/16.0)) + hpa = (hpa/100.0) + return hpa + def pressure_asraw(self): + """ + Reads the atmospheric pressure + + """ + output = None # Variable declaration + value_lsb = None # Variable declaration + value_msb = None # Variable declaration + value_xlsb = None # Variable declaration + + value_msb = self.get_pressuremsb() + value_lsb = self.get_pressurelsb() + value_xlsb = self.get_pressurexlsb() + output = ((value_msb << 12)+(value_lsb << 4)+(value_xlsb >> 4)) + return output + def temperature_ascelsius(self): + """ + Reads the temperature + + """ + celsius = None # Variable declaration + raw_comp1 = None # Variable declaration + raw_comp2 = None # Variable declaration + raw_comp3 = None # Variable declaration + raw_temp = None # Variable declaration + value_d_t1 = None # Variable declaration + value_d_t2 = None # Variable declaration + value_d_t3 = None # Variable declaration + value_lsb = None # Variable declaration + value_msb = None # Variable declaration + value_xlsb = None # Variable declaration + + value_msb = self.get_tempmsb() + value_lsb = self.get_templsb() + value_xlsb = self.get_tempxlsb() + value_d_t1 = self.get_digt1() + value_d_t2 = self.get_digt2() + value_d_t3 = self.get_digt3() + raw_temp = ((value_msb << 12)+(value_lsb << 4)+(value_xlsb >> 4)) + raw_comp1 = (((raw_temp/16384.0)-(value_d_t1/1024.0))*value_d_t2) + raw_comp3 = ((raw_temp/131072.0)-(value_d_t1/8192.0)) + raw_comp2 = (raw_comp3*raw_comp3*value_d_t3) + celsius = ((raw_comp1+raw_comp2)/5120.0) + return celsius + def temperature_asraw(self): + """ + Reads the temperature + + """ + output = None # Variable declaration + value_lsb = None # Variable declaration + value_msb = None # Variable declaration + value_xlsb = None # Variable declaration + + value_msb = self.get_tempmsb() + value_lsb = self.get_templsb() + value_xlsb = self.get_tempxlsb() + output = ((value_msb << 12)+(value_lsb << 4)+(value_xlsb >> 4)) + return output diff --git a/test/sampleData/circuitpython/Example.py b/test/sampleData/circuitpython/Example.py new file mode 100644 index 0000000..d586179 --- /dev/null +++ b/test/sampleData/circuitpython/Example.py @@ -0,0 +1,254 @@ +# 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.1.0 +""" +Class for Example +""" + +from adafruit_bus_device.i2c_device import I2CDevice + +FIELDB_VAL_1 = 1 # Value 1 +FIELDB_VAL_2 = 2 # Value 2 +FIELDB_VAL_3 = 4 # Value 3 +FIELDB_VAL_4 = 8 # Value 4 + +I2C_ADDRESS_16 = 16 +I2C_ADDRESS_32 = 32 +I2C_ADDRESS_48 = 48 + + + + + + +class Example: + """ + Example of a package + + """ + REGISTER_REGISTERA = 0 + REGISTER_REGISTERB = 1 + REGISTER_REGISTERC = 2 + REGISTER_REGISTERD = 3 + + def __init__(self, i2c, address): + # Initialize connection to peripheral + self.i2c_device = I2CDevice(i2c, address) + self.device_address = address + self._lifecycle_begin() + + def get_registera(self): + """ + An 8-bit register + + """ + write_list = bytearray(1) + write_list[0] = self.REGISTER_REGISTERA + read_list = bytearray(1) + with self.i2c_device as i2c: + i2c.write_then_readinto(write_list, read_list) + val = 0 + val = val << 8 | read_list[0] + return val + + def set_registera(self, data): + """ + An 8-bit register + + """ + buffer = bytearray(1) + buffer[0] = (data >> 0) & 0xFF + with self.i2c_device as i2c: + i2c.write(buffer) + def get_registerb(self): + """ + A 16-bit register + + """ + write_list = bytearray(1) + write_list[0] = self.REGISTER_REGISTERB + read_list = bytearray(2) + with self.i2c_device as i2c: + i2c.write_then_readinto(write_list, read_list) + val = 0 + val = val << 8 | read_list[0] + val = val << 8 | read_list[1] + return val + + def set_registerb(self, data): + """ + A 16-bit register + + """ + buffer = bytearray(2) + buffer[0] = (data >> 8) & 0xFF + buffer[1] = (data >> 0) & 0xFF + with self.i2c_device as i2c: + i2c.write(buffer) + def get_registerc(self): + """ + A 32-bit register + + """ + write_list = bytearray(1) + write_list[0] = self.REGISTER_REGISTERC + read_list = bytearray(4) + with self.i2c_device as i2c: + i2c.write_then_readinto(write_list, read_list) + val = 0 + val = val << 8 | read_list[0] + val = val << 8 | read_list[1] + val = val << 8 | read_list[2] + val = val << 8 | read_list[3] + return val + + def set_registerc(self, data): + """ + A 32-bit register + + """ + buffer = bytearray(4) + buffer[0] = (data >> 24) & 0xFF + buffer[1] = (data >> 16) & 0xFF + buffer[2] = (data >> 8) & 0xFF + buffer[3] = (data >> 0) & 0xFF + with self.i2c_device as i2c: + i2c.write(buffer) + def get_registerd(self): + """ + A dummy register that has no data + + """ + write_list = bytearray(1) + write_list[0] = self.REGISTER_REGISTERD + read_list = bytearray(0) + with self.i2c_device as i2c: + i2c.write_then_readinto(write_list, read_list) + val = 0 + return val + + def set_registerd(self): + """ + A dummy register that has no data + + """ + buffer = bytearray(0) + with self.i2c_device as i2c: + i2c.write(buffer) + + + def get_fielda(self): + """ + This is a few bits + + """ + # Read register data + # '#/registers/RegisterA' > 'RegisterA' + val = self.get_registera() + # Mask register value + val = val & 0b0000000011110000 + # Bitshift value + val = val >> 4 + return val + + def set_fieldb(self, data): + """ + This is fewer bits + + """ + # Bitshift value + data = data << 2 + # Read current register data + # '#/registers/RegisterA' > 'RegisterA' + register_data = self.get_registera() + register_data = register_data | data + self.set_registera(register_data) + + def get_fieldc(self): + """ + A single-bit + + """ + # Read register data + # '#/registers/RegisterA' > 'RegisterA' + val = self.get_registera() + # Mask register value + val = val & 0b0000000000000010 + # Bitshift value + val = val >> 1 + return val + + def set_fieldc(self, data): + """ + A single-bit + + """ + # Bitshift value + data = data << 1 + # Read current register data + # '#/registers/RegisterA' > 'RegisterA' + register_data = self.get_registera() + register_data = register_data | data + self.set_registera(register_data) + def _lifecycle_begin(self): + """ + Enables features on device + + """ + output = None # Variable declaration + + output = 1 + self.set_registera(output) + return output + def _lifecycle_end(self): + """ + Enables features on device + + """ + output = None # Variable declaration + + output = 1 + self.set_registera(output) + return output + def return_array(self): + """ + Computes and returns + + """ + summation = None # Variable declaration + + summation = (1024+1024) + self.set_registera(summation) + return [summation, summation] + def return_number(self): + """ + Computes and returns + + """ + summation = None # Variable declaration + + summation = (1024+1024) + self.set_registera(summation) + return summation + def return_void(self): + """ + Computes and returns + + """ + summation = None # Variable declaration + + summation = (1024+1024) + self.set_registera(summation) diff --git a/test/sampleData/circuitpython/LSM303D.py b/test/sampleData/circuitpython/LSM303D.py new file mode 100644 index 0000000..a4212b0 --- /dev/null +++ b/test/sampleData/circuitpython/LSM303D.py @@ -0,0 +1,347 @@ +# 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 LSM303D v0.1.0. +# Generated from peripherals/LSM303D.yaml using Cyanobyte Codegen v0.1.0 +""" +Class for LSM303D +""" + +import math +import ustruct +from adafruit_bus_device.i2c_device import I2CDevice + + + + + + +class LSM303D: + """ + STMicroelectronics accelerometer and magnetometer + + """ + device_address = 29 + REGISTER_ACCELEROMETERX_HIGH = 169 + REGISTER_ACCELEROMETERX_LOW = 168 + REGISTER_ACCELEROMETERY_HIGH = 171 + REGISTER_ACCELEROMETERY_LOW = 170 + REGISTER_ACCELEROMETERZ_HIGH = 173 + REGISTER_ACCELEROMETERZ_LOW = 172 + REGISTER_MAGNETOMETERX_HIGH = 137 + REGISTER_MAGNETOMETERX_LOW = 136 + REGISTER_MAGNETOMETERY_HIGH = 139 + REGISTER_MAGNETOMETERY_LOW = 138 + REGISTER_MAGNETOMETERZ_HIGH = 141 + REGISTER_MAGNETOMETERZ_LOW = 140 + + def __init__(self, i2c): + # Initialize connection to peripheral + self.i2c_device = I2CDevice(i2c, 29) + self.i2c = i2c + + def get_accelerometerx_high(self): + """ + Raw accelerometer data on X plane + + """ + write_list = bytearray(1) + write_list[0] = self.REGISTER_ACCELEROMETERX_HIGH + read_list = bytearray(1) + with self.i2c_device as i2c: + i2c.write_then_readinto(write_list, read_list) + val = 0 + val = val << 8 | read_list[0] + return val + + def get_accelerometerx_low(self): + """ + Raw accelerometer data on X plane + + """ + write_list = bytearray(1) + write_list[0] = self.REGISTER_ACCELEROMETERX_LOW + read_list = bytearray(1) + with self.i2c_device as i2c: + i2c.write_then_readinto(write_list, read_list) + val = 0 + val = val << 8 | read_list[0] + return val + + def get_accelerometery_high(self): + """ + Raw accelerometer data on Y plane + + """ + write_list = bytearray(1) + write_list[0] = self.REGISTER_ACCELEROMETERY_HIGH + read_list = bytearray(1) + with self.i2c_device as i2c: + i2c.write_then_readinto(write_list, read_list) + val = 0 + val = val << 8 | read_list[0] + return val + + def get_accelerometery_low(self): + """ + Raw accelerometer data on Y plane + + """ + write_list = bytearray(1) + write_list[0] = self.REGISTER_ACCELEROMETERY_LOW + read_list = bytearray(1) + with self.i2c_device as i2c: + i2c.write_then_readinto(write_list, read_list) + val = 0 + val = val << 8 | read_list[0] + return val + + def get_accelerometerz_high(self): + """ + Raw accelerometer data on Z plane + + """ + write_list = bytearray(1) + write_list[0] = self.REGISTER_ACCELEROMETERZ_HIGH + read_list = bytearray(1) + with self.i2c_device as i2c: + i2c.write_then_readinto(write_list, read_list) + val = 0 + val = val << 8 | read_list[0] + return val + + def get_accelerometerz_low(self): + """ + Raw accelerometer data on Z plane + + """ + write_list = bytearray(1) + write_list[0] = self.REGISTER_ACCELEROMETERZ_LOW + read_list = bytearray(1) + with self.i2c_device as i2c: + i2c.write_then_readinto(write_list, read_list) + val = 0 + val = val << 8 | read_list[0] + return val + + def get_magnetometerx_high(self): + """ + Raw magnetometer data on X plane + + """ + write_list = bytearray(1) + write_list[0] = self.REGISTER_MAGNETOMETERX_HIGH + read_list = bytearray(1) + with self.i2c_device as i2c: + i2c.write_then_readinto(write_list, read_list) + val = 0 + val = val << 8 | read_list[0] + return val + + def get_magnetometerx_low(self): + """ + Raw magnetometer data on X plane + + """ + write_list = bytearray(1) + write_list[0] = self.REGISTER_MAGNETOMETERX_LOW + read_list = bytearray(1) + with self.i2c_device as i2c: + i2c.write_then_readinto(write_list, read_list) + val = 0 + val = val << 8 | read_list[0] + return val + + def get_magnetometery_high(self): + """ + Raw magnetometer data on Y plane + + """ + write_list = bytearray(1) + write_list[0] = self.REGISTER_MAGNETOMETERY_HIGH + read_list = bytearray(1) + with self.i2c_device as i2c: + i2c.write_then_readinto(write_list, read_list) + val = 0 + val = val << 8 | read_list[0] + return val + + def get_magnetometery_low(self): + """ + Raw magnetometer data on Y plane + + """ + write_list = bytearray(1) + write_list[0] = self.REGISTER_MAGNETOMETERY_LOW + read_list = bytearray(1) + with self.i2c_device as i2c: + i2c.write_then_readinto(write_list, read_list) + val = 0 + val = val << 8 | read_list[0] + return val + + def get_magnetometerz_high(self): + """ + Raw magnetometer data on Z plane + + """ + write_list = bytearray(1) + write_list[0] = self.REGISTER_MAGNETOMETERZ_HIGH + read_list = bytearray(1) + with self.i2c_device as i2c: + i2c.write_then_readinto(write_list, read_list) + val = 0 + val = val << 8 | read_list[0] + return val + + def get_magnetometerz_low(self): + """ + Raw magnetometer data on Z plane + + """ + write_list = bytearray(1) + write_list[0] = self.REGISTER_MAGNETOMETERZ_LOW + read_list = bytearray(1) + with self.i2c_device as i2c: + i2c.write_then_readinto(write_list, read_list) + val = 0 + val = val << 8 | read_list[0] + return val + + + def acceleration_asg(self): + """ + Measures the current acceleration + + """ + acceleration_scale = None # Variable declaration + value_x = None # Variable declaration + value_y = None # Variable declaration + value_z = None # Variable declaration + + acceleration_scale = 2 + value_x = self.acceleration_xplane() + value_y = self.acceleration_yplane() + value_z = self.acceleration_zplane() + value_x = ((value_x/math.pow(2, 15))*acceleration_scale) + value_y = ((value_y/math.pow(2, 15))*acceleration_scale) + value_z = ((value_z/math.pow(2, 15))*acceleration_scale) + return [value_x, value_y, value_z] + def acceleration_xplane(self): + """ + Measures the current acceleration + + """ + datum = None # Variable declaration + lower = None # Variable declaration + upper = None # Variable declaration + + lower = self.get_accelerometerx_low() + upper = self.get_accelerometerx_high() + datum = ((upper << 8)+lower) + # Convert from a unsigned short to a signed short + datum = ustruct.unpack("h", ustruct.pack("H", datum))[0] + return datum + def acceleration_yplane(self): + """ + Measures the current acceleration + + """ + datum = None # Variable declaration + lower = None # Variable declaration + upper = None # Variable declaration + + lower = self.get_accelerometery_low() + upper = self.get_accelerometery_high() + datum = ((upper << 8)+lower) + # Convert from a unsigned short to a signed short + datum = ustruct.unpack("h", ustruct.pack("H", datum))[0] + return datum + def acceleration_zplane(self): + """ + Measures the current acceleration + + """ + datum = None # Variable declaration + lower = None # Variable declaration + upper = None # Variable declaration + + lower = self.get_accelerometerz_low() + upper = self.get_accelerometerz_high() + datum = ((upper << 8)+lower) + # Convert from a unsigned short to a signed short + datum = ustruct.unpack("h", ustruct.pack("H", datum))[0] + return datum + def orientation_heading(self): + """ + Reads the magnetic orientation + + """ + dividend = None # Variable declaration + heading = None # Variable declaration + value_x = None # Variable declaration + value_y = None # Variable declaration + + value_x = self.orientation_xplane() + value_y = self.orientation_yplane() + dividend = (value_x/value_y) + heading = math.atan(dividend) + heading = (heading%(2*3.141592653589793)) + heading = ((heading/3.141592653589793)*180) + return heading + def orientation_xplane(self): + """ + Reads the magnetic orientation + + """ + datum = None # Variable declaration + lower = None # Variable declaration + upper = None # Variable declaration + + lower = self.get_magnetometerx_low() + upper = self.get_magnetometerx_high() + datum = ((upper << 8)+lower) + # Convert from a unsigned short to a signed short + datum = ustruct.unpack("h", ustruct.pack("H", datum))[0] + return datum + def orientation_yplane(self): + """ + Reads the magnetic orientation + + """ + datum = None # Variable declaration + lower = None # Variable declaration + upper = None # Variable declaration + + lower = self.get_magnetometery_low() + upper = self.get_magnetometery_high() + datum = ((upper << 8)+lower) + # Convert from a unsigned short to a signed short + datum = ustruct.unpack("h", ustruct.pack("H", datum))[0] + return datum + def orientation_zplane(self): + """ + Reads the magnetic orientation + + """ + datum = None # Variable declaration + lower = None # Variable declaration + upper = None # Variable declaration + + lower = self.get_magnetometerz_low() + upper = self.get_magnetometerz_high() + datum = ((upper << 8)+lower) + # Convert from a unsigned short to a signed short + datum = ustruct.unpack("h", ustruct.pack("H", datum))[0] + return datum diff --git a/test/sampleData/circuitpython/MCP4725.py b/test/sampleData/circuitpython/MCP4725.py new file mode 100644 index 0000000..c059e0b --- /dev/null +++ b/test/sampleData/circuitpython/MCP4725.py @@ -0,0 +1,159 @@ +# 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 MCP4725 v0.1.0. +# Generated from peripherals/MCP4725.yaml using Cyanobyte Codegen v0.1.0 +""" +Class for MCP4725 +""" + +from adafruit_bus_device.i2c_device import I2CDevice + +DIGITALOUT_GND = 0 # Ground +DIGITALOUT_VCC = 4095 # Vcc (full power) + + +def _swap_endian(val, length): + """ + Swap the endianness of a number + """ + if length <= 8: + return val + if length <= 16: + return (val & 0xFF00) >> 8 | (val & 0xFF) << 8 + if length <= 32: + return ((val & 0xFF000000) >> 24 | + (val & 0x00FF0000) >> 8 | + (val & 0x0000FF00) << 8 | + (val & 0x000000FF) << 24) + raise Exception('Cannot swap endianness for length ' + length) + + + + +class MCP4725: + """ + Microchip 4725 Digital-to-Analog Converter + + """ + device_address = 98 + REGISTER_EEPROM = 96 + REGISTER_VOUT = 64 + + def __init__(self, i2c): + # Initialize connection to peripheral + self.i2c_device = I2CDevice(i2c, 98) + self.i2c = i2c + + def get_eeprom(self): + """ + If EEPROM is set, the saved voltage output will + be loaded from power-on. + + """ + write_list = bytearray(1) + write_list[0] = self.REGISTER_EEPROM + read_list = bytearray(1) + with self.i2c_device as i2c: + i2c.write_then_readinto(write_list, read_list) + val = 0 + val = val << 8 | read_list[0] + val = _swap_endian(val, 12) + return val + + def set_eeprom(self, data): + """ + If EEPROM is set, the saved voltage output will + be loaded from power-on. + + """ + data = _swap_endian(data, 12) + buffer = bytearray(1) + buffer[0] = (data >> 0) & 0xFF + with self.i2c_device as i2c: + i2c.write(buffer) + def get_vout(self): + """ + VOut = (Vcc * value) / 4096 + The output is a range between 0 and Vcc with + steps of Vcc/4096. + In a 3.3v system, each step is 800 microvolts. + + """ + write_list = bytearray(1) + write_list[0] = self.REGISTER_VOUT + read_list = bytearray(1) + with self.i2c_device as i2c: + i2c.write_then_readinto(write_list, read_list) + val = 0 + val = val << 8 | read_list[0] + val = _swap_endian(val, 12) + return val + + def set_vout(self, data): + """ + VOut = (Vcc * value) / 4096 + The output is a range between 0 and Vcc with + steps of Vcc/4096. + In a 3.3v system, each step is 800 microvolts. + + """ + data = _swap_endian(data, 12) + buffer = bytearray(1) + buffer[0] = (data >> 0) & 0xFF + with self.i2c_device as i2c: + i2c.write(buffer) + + + def get_digitalout(self): + """ + Only allows you to send fully on or off + + """ + # Read register data + # '#/registers/EEPROM' > 'EEPROM' + val = self.get_eeprom() + # Mask register value + val = val & 0b0001111111111111 + return val + + def set_digitalout(self, data): + """ + Only allows you to send fully on or off + + """ + # Read current register data + # '#/registers/EEPROM' > 'EEPROM' + register_data = self.get_eeprom() + register_data = register_data | data + self.set_eeprom(register_data) + def getvout_asvoltage(self, vcc): + """ + get vout + + """ + voltage = None # Variable declaration + + # Read value of register into a variable + value = self.get_eeprom() + voltage = value / 4096 * vcc + return voltage + def setvout_asvoltage(self, output, vcc): + """ + set vout + + """ + + output = output / vcc * 4096 + self.set_eeprom(output) diff --git a/test/sampleData/circuitpython/MCP9808.py b/test/sampleData/circuitpython/MCP9808.py new file mode 100644 index 0000000..ff27988 --- /dev/null +++ b/test/sampleData/circuitpython/MCP9808.py @@ -0,0 +1,135 @@ +# 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 MCP9808 v0.1.0. +# Generated from peripherals/MCP9808.yaml using Cyanobyte Codegen v0.1.0 +""" +Class for MCP9808 +""" + +from adafruit_bus_device.i2c_device import I2CDevice + +LIMITHYSTERESIS_TEMP_0C = 0 # 0°C (power-up default) +LIMITHYSTERESIS_TEMP_1C5 = 1 # +1.5°C +LIMITHYSTERESIS_TEMP_3C = 2 # +3.0°C +LIMITHYSTERESIS_TEMP_6C = 3 # +6.0°C + +SHUTDOWNMODE_CONTINOUSCONVERSION = 0 # Continuous conversion (power-up default) +SHUTDOWNMODE_SHUTDOWN = 1 # Shutdown (Low-Power mode) + +I2C_ADDRESS_24 = 24 +I2C_ADDRESS_25 = 25 +I2C_ADDRESS_26 = 26 +I2C_ADDRESS_27 = 27 +I2C_ADDRESS_28 = 28 +I2C_ADDRESS_29 = 29 +I2C_ADDRESS_30 = 30 +I2C_ADDRESS_31 = 31 + + + + + + +class MCP9808: + """ + This is a test description + + """ + REGISTER_CONFIGURATION = 1 + + def __init__(self, i2c, address): + # Initialize connection to peripheral + self.i2c_device = I2CDevice(i2c, address) + self.device_address = address + + def get_configuration(self): + """ + The MCP9808 has a 16-bit Configuration register (CONFIG) that + allows the user to set various functions for a robust temperature + monitoring system. + Bits 10 through 0 are used to select the temperature alert output + hysteresis, device shutdown or Low-Power mode, temperature boundary + and critical temperature lock, and temperature Alert output + enable/disable. + In addition, Alert output condition (output set for TUPPER and + TLOWER temperature boundary or TCRIT only), Alert output status + and Alert output polarity and mode (Comparator Output or Interrupt + Output mode) are user-configurable. + + """ + write_list = bytearray(1) + write_list[0] = self.REGISTER_CONFIGURATION + read_list = bytearray(2) + with self.i2c_device as i2c: + i2c.write_then_readinto(write_list, read_list) + val = 0 + val = val << 8 | read_list[0] + val = val << 8 | read_list[1] + return val + + def set_configuration(self, data): + """ + The MCP9808 has a 16-bit Configuration register (CONFIG) that + allows the user to set various functions for a robust temperature + monitoring system. + Bits 10 through 0 are used to select the temperature alert output + hysteresis, device shutdown or Low-Power mode, temperature boundary + and critical temperature lock, and temperature Alert output + enable/disable. + In addition, Alert output condition (output set for TUPPER and + TLOWER temperature boundary or TCRIT only), Alert output status + and Alert output polarity and mode (Comparator Output or Interrupt + Output mode) are user-configurable. + + """ + buffer = bytearray(2) + buffer[0] = (data >> 8) & 0xFF + buffer[1] = (data >> 0) & 0xFF + with self.i2c_device as i2c: + i2c.write(buffer) + + + def get_limithysteresis(self): + """ + This bit can not be altered when either of the Lock bits are set + (bit 6 and bit 7). This bit can be programmed in Shutdown mode. + + """ + # Read register data + # '#/registers/configuration' > 'configuration' + val = self.get_configuration() + # Mask register value + val = val & 0b0000011000000000 + # Bitshift value + val = val >> 9 + return val + + def get_shutdownmode(self): + """ + In shutdown, all power-consuming activities are disabled, though + all registers can be written to or read. This bit cannot be set + to ‘1’ when either of the Lock bits is set (bit 6 and bit 7). + However, it can be cleared to ‘0’ for continuous conversion while + locked. + + """ + # Read register data + # '#/registers/configuration' > 'configuration' + val = self.get_configuration() + # Mask register value + val = val & 0b0000000100000000 + # Bitshift value + val = val >> 8 + return val diff --git a/test/sampleData/circuitpython/TCS3472.py b/test/sampleData/circuitpython/TCS3472.py new file mode 100644 index 0000000..0f2e84c --- /dev/null +++ b/test/sampleData/circuitpython/TCS3472.py @@ -0,0 +1,164 @@ +# 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 TCS3472 v0.1.0. +# Generated from peripherals/TCS3472.yaml using Cyanobyte Codegen v0.1.0 +""" +Class for TCS3472 +""" + +from adafruit_bus_device.i2c_device import I2CDevice + +INIT_POWER = 1 # Power +INIT_RGBC = 2 # Color + + + + + + +class TCS3472: + """ + Color Light-to-Digital Converter with IR Filter + + """ + device_address = 41 + REGISTER_BLUE = 186 + REGISTER_CLEAR = 180 + REGISTER_ENABLE = 128 + REGISTER_GREEN = 184 + REGISTER_RED = 182 + + def __init__(self, i2c): + # Initialize connection to peripheral + self.i2c_device = I2CDevice(i2c, 41) + self.i2c = i2c + self._lifecycle_begin() + + def get_blue(self): + """ + Blue light as an int. Divide by ambient light to get scaled number. + + """ + write_list = bytearray(1) + write_list[0] = self.REGISTER_BLUE + read_list = bytearray(2) + with self.i2c_device as i2c: + i2c.write_then_readinto(write_list, read_list) + val = 0 + val = val << 8 | read_list[0] + val = val << 8 | read_list[1] + return val + + def get_clear(self): + """ + This is the ambient amount of detected light. + + """ + write_list = bytearray(1) + write_list[0] = self.REGISTER_CLEAR + read_list = bytearray(2) + with self.i2c_device as i2c: + i2c.write_then_readinto(write_list, read_list) + val = 0 + val = val << 8 | read_list[0] + val = val << 8 | read_list[1] + return val + + def get_enable(self): + """ + Enable specific components of the peripheral + + """ + write_list = bytearray(1) + write_list[0] = self.REGISTER_ENABLE + read_list = bytearray(1) + with self.i2c_device as i2c: + i2c.write_then_readinto(write_list, read_list) + val = 0 + val = val << 8 | read_list[0] + return val + + def set_enable(self, data): + """ + Enable specific components of the peripheral + + """ + buffer = bytearray(1) + buffer[0] = (data >> 0) & 0xFF + with self.i2c_device as i2c: + i2c.write(buffer) + def get_green(self): + """ + Green light as an int. Divide by ambient light to get scaled number. + + """ + write_list = bytearray(1) + write_list[0] = self.REGISTER_GREEN + read_list = bytearray(2) + with self.i2c_device as i2c: + i2c.write_then_readinto(write_list, read_list) + val = 0 + val = val << 8 | read_list[0] + val = val << 8 | read_list[1] + return val + + def get_red(self): + """ + Red light as an int. Divide by ambient light to get scaled number. + + """ + write_list = bytearray(1) + write_list[0] = self.REGISTER_RED + read_list = bytearray(2) + with self.i2c_device as i2c: + i2c.write_then_readinto(write_list, read_list) + val = 0 + val = val << 8 | read_list[0] + val = val << 8 | read_list[1] + return val + + + + def get_init(self): + """ + Enable RGBC and Power + + """ + # Read register data + # '#/registers/enable' > 'enable' + val = self.get_enable() + # Mask register value + val = val & 0b0000000011111111 + return val + + def set_init(self, data): + """ + Enable RGBC and Power + + """ + # Read current register data + # '#/registers/enable' > 'enable' + register_data = self.get_enable() + register_data = register_data | data + self.set_enable(register_data) + def _lifecycle_begin(self): + """ + Enables features on device + + """ + enables = None # Variable declaration + + enables = (1+2) + self.set_enable(enables) diff --git a/test/test_codegen.py b/test/test_codegen.py index 82d27f0..65dc46c 100644 --- a/test/test_codegen.py +++ b/test/test_codegen.py @@ -90,6 +90,10 @@ def test_Arduino(self): self.compareFiles('arduino', 'cpp') self.compareFiles('arduino', 'h') + def test_Circuitpython(self): + self.generatePeripheralTemplate('circuitpython.py') + self.compareFiles('circuitpython', 'py') + def test_CMSIS_SVD(self): self.generatePeripheralTemplate('cmsis.svd') self.compareFiles('cmsis-svd', 'svd')