Repository: google/cyanobyte (language: python)

Issue:
BMP280 Generated files for Arduino with the given datasheet is not working?
Hey, 

I have run cyanobyte-Codegen for Sensor BMP280 and generated code for Arduino.

> cyanobyte-codegen -t templates/arduino.cpp -o ./build peripherals/BMP280.yaml

> cyanobyte-codegen -t templates/arduino.h -o ./build peripherals/BMP280.yaml

Later I have used these generated library files and written these lines of code for Atmega 328(Arduino) 
```
#include "BMP280.h"
TwoWire Wire1;
BMP280 sensor(Wire1);

void setup() {
sensor.begin();
Serial.begin(9600);
}
void loop() {
Serial.println(sensor.temperatureasCelsius());
delay(2000);
}
```

But I get null output.
I have also confirmed my  my hardware to be working fine, since I have verifyed it with [adfruits library ](https://github.com/adafruit/Adafruit_BMP280_Library)





Discussion / hints:
In the cyanobyte datasheet Many registers are given wrong datasize #246 
```
uint16_t BMP280::readDigP8() {
    uint8_t datum;
    uint16_t value;
    _wire->beginTransmission(DEVICE_ADDRESS);
    _wire->write(REGISTER_DIGP8);
    if (_wire->endTransmission(false) != 0) {
        return -1;
    }

    if (_wire->requestFrom(DEVICE_ADDRESS, 2) != 2) {
        return 0;
    }

    datum = _wire->read();
    value = value << 8 | datum;
    datum = _wire->read();
    value = value << 8 | datum;

    return value;
}
```
This is the generated code of BMP280 for arduino, and  the **endianness** is ignored.
![image](https://user-images.githubusercontent.com/16455716/95298132-36f55b80-0899-11eb-844a-9ea11d31257a.png)


Yeah I'll need to re-review the datasheet and ensure that the registers are all correctly typed.
The template for Arduino doesn't have method to typecast variables.

Fix patch:
diff --git a/cyanobyte/codegen.py b/cyanobyte/codegen.py
index 93cf553..13f5772 100644
--- a/cyanobyte/codegen.py
+++ b/cyanobyte/codegen.py
@@ -38,6 +38,7 @@
 _CLEAN = False
 _TEMPLATES = dict(
     arduino=["./templates/arduino.cpp", "./templates/arduino.h"],
+    circuitpython=["./templates/circuitpython.py"],
     cmsis=["./templates/cmsis.svd"],
     datasheet=["./templates/datasheet.tex"],
     doc=["./templates/doc.md"],
@@ -48,6 +49,7 @@
     kubos=["./templates/kubos.c", "./templates/kubos.h"],
     micropython=["./templates/micropython.py"],
     raspberrypi=["./templates/raspberrypi.py"],
+    webpage=["./templates/webpage.html"],
 )
 _OPTIONS = dict(
     esp32="./templates/esp32.options.yaml"
diff --git a/docs/content/_index.html b/docs/content/_index.html
index b57ac56..3cdd050 100644
--- a/docs/content/_index.html
+++ b/docs/content/_index.html
@@ -139,6 +139,7 @@ <h2 class="text-center">
 	- CMSIS
 	- LaTeX Datasheets
 	- Markdown documentation
+	- Instructional webpage
 	{{% /blocks/feature %}}
 
 	{{% blocks/feature icon="fas fa-clipboard-list" title="Next Goals" %}}
diff --git a/templates/clang.jinja2 b/templates/clang.jinja2
index cbaca88..32c42fe 100644
--- a/templates/clang.jinja2
+++ b/templates/clang.jinja2
@@ -58,10 +58,17 @@ uint8_t
 short
 {%- elif cyan == 'uint16' -%}
 uint16_t
+{%- elif cyan == 'int32' -%}
+long
+{%- elif cyan == 'uint32' -%}
+uint32_t
 {%- elif cyan == 'float32' -%}
 float
+{%- elif cyan == 'float64' -%}
+double
 {%- else -%}
-/* ERROR UNDEFINED TYPE */
+{# Raise an error and take a guess #}
+/* ERROR UNDEFINED TYPE */ long double
 {%- endif -%}
 {%- endmacro %}
 
diff --git a/templates/webpage.html b/templates/webpage.html
new file mode 100644
index 0000000..1607562
--- /dev/null
+++ b/templates/webpage.html
@@ -0,0 +1,181 @@
+{% set template = namespace(registersToFields=dict()) %}
+{% if fields %}
+{# Create a dictionary linking a register to its associated fields #}
+{# for hierarchical display #}
+{% for key,field in fields|dictsort %}
+{% set rkey = field.register[12:] %}
+{% if rkey in template.registersToFields %}
+{% set _dummy = field.update({ 'key': key }) %}
+{{- template.registersToFields[rkey].append(field) or "" -}}
+{% else %}
+{% set _dummy = field.update({ 'key': key }) %}
+{% set _dummy = template.registersToFields.update({ rkey: [] }) %}
+{{- template.registersToFields[rkey].append(field) or "" -}}
+{% endif %}
+{% endfor %}
+
+{% endif %}
+
+<html>
+    <head>
+        <title>{{ info.title }}</title>
+    </head>
+    <body>
+        <style>
+            body {
+                font-family: sans-serif;
+                background-color: #efefef;
+            }
+            section.registers {
+                background-color: white;
+                box-shadow: 1px 1px 1px black;
+                border-radius: 4px;
+            }
+            section.registers table {
+                width: 100%;
+                border-style: solid;
+            }
+            section.registers td {
+                text-align: center;
+                vertical-align: middle;
+                border-style: solid;
+            }
+            section.registers td h1 {
+                font-size: 11pt;
+                margin-block: unset;
+                margin-bottom: 8px;
+            }
+            section.registers td h2 {
+                font-size: 10pt;
+                color: #333;
+                margin-block: unset;
+                font-weight: normal;
+                margin-bottom: 8px;
+            }
+            section.registers td h3 {
+                font-size: 9pt;
+                color: #555;
+                margin-block: unset;
+                font-weight: normal;
+            }
+            footer {
+                opacity: 0.75;
+                font-size: 9pt;
+            }
+        </style>
+        <h1>{{ info.title }}</h1>
+        <section class="description">
+            <p>
+                {{ info.description }}
+            </p>
+            <ul>
+            {% if i2c.address is iterable and i2c.address is not string %}
+            <li>Device addresses:
+            {% for address in i2c.address %}
+            {{address}}{{ "," if not loop.last }}
+            {% endfor %}
+            </li>
+            {% else %}
+            <li>Device address {{ i2c.address }}</li>
+            {% endif %}
+            <li>Address type {{ i2c.addressType }}</li>
+            {% if i2c.endian == 'little' %}
+            <li>Little Endian</li>
+            {% endif %}
+            </ul>
+        </section>
+        <section class="registers">
+            <table>
+                <tbody>
+                    {% set registersArray = registers.items()|sort(attribute="1.address") %}
+                    {% set maxlengthReg = registers.items()|sort(attribute="1.length")|last %}
+                    {% set maxlength = maxlengthReg[1].length %}
+                    {% if maxlength == 0 %}
+                    {% set maxlength = 2 %}
+                    {% endif %}
+                    {% for key,register in registersArray %}
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="{{ 1 / maxlength * 100 }}%">
+                            <h3>
+                                Addr {{register.address}} <br><br>
+                                {{register.length}}-bytes <br>
+                                {% if register.readWrite == "R" %}
+                                    <br><em>Read-only</em>
+                                {% endif %}
+                                {% if register.readWrite == "W" %}
+                                    <br><em>Write-only</em>
+                                {% endif %}
+                                {% if register.readWrite == "n" %}
+                                    <br><em>Inaccessible</em>
+                                {% endif %}
+                                {% if register.signed %}
+                                    <br><em>Signed value</em>
+                                {% endif %}
+                            </h3>
+                        </td>
+                        {% if key in template.registersToFields %}
+                        {% set fields = template.registersToFields[key] %}
+                        {% for field in fields|sort(attribute="bitStart", reverse=True) %}
+                        {% set length = (field.bitStart - field.bitEnd) + 1 %}
+                        <td colspan="{{length}}" width="{{ (length) / maxlength * 100}}%">
+                            <h1>{{ field.title }}</h1>
+                            <h2>{{ field.description }}</h2>
+                            <h3>
+                                [{{field.bitStart}}:{{field.bitEnd}}] | {{length}}-byte{% if length > 1 %}s{% endif %}
+                            {% if field.readWrite == "R" %}
+                                <br><em>Read-only</em>
+                            {% endif %}
+                            {% if field.readWrite == "W" %}
+                                <br><em>Write-only</em>
+                            {% endif %}
+                            {% if field.readWrite == "n" %}
+                                <br><em>Inaccessible</em>
+                            {% endif %}
+                            </h3>
+                        </td>
+                        {% endfor %}
+                        {% else %}
+                        <td colspan="{{register.length}}" width="{{ (register.length - 1) / maxlength * 100}}%">
+                            <h1>{{register.title}}</h1>
+                            <h2>{{register.description}}</h2>
+                        </td>
+                        {% if register.length < maxlength %}
+                        <td colspan="{{32 - 1 - register.length}}" width="{{ (maxlength - 1 - register.length) / maxlength * 100}}%">
+                            <!-- intentionally leave empty -->
+                        </td>
+                        {% endif %}
+                        {% endif %}
+                    </tr>
+                    {% endfor %}
+                </tbody>
+            </table>
+        </section>
+        {% if functions %}
+        <section class="functions">
+            <h2>Functions</h2>
+            <ul>
+                {% for key,function in functions|dictsort %}
+                {% for ckey,computation in function.computed|dictsort %}
+                <li>
+                    <b>{{key}}.{{ckey}}</b> -
+                    {{function.description}}
+                </li>
+                {% endfor %}
+                {% endfor %}
+            </ul>
+        </section>
+        {% endif %}
+        <hr>
+        <footer>
+            <p>
+                Contact <a href="mailto:{{ info.contact.email }}">{{ info.contact.name }}</a>.
+            </p>
+            <p>
+                Copyright {{info.copyright.name}} {{info.copyright.date}}. Published under {{info.license.name}} license.
+            </p>
+            <p>
+                Peripheral version {{info.version}} using Cyanobyte v{{cyanobyte}}.
+            </p>
+        </footer>
+    </body>
+</html>
\ No newline at end of file


Test patch:
diff --git a/test/sampleData/arduino/BMP280.cpp b/test/sampleData/arduino/BMP280.cpp
index 5ebffba..51df14b 100644
--- a/test/sampleData/arduino/BMP280.cpp
+++ b/test/sampleData/arduino/BMP280.cpp
@@ -453,20 +453,20 @@ uint8_t BMP280::readTempXlsb() {
 
 float BMP280::pressureasHpa() {
     float hpa; // Variable declaration
-    short rawComp1; // Variable declaration
-    short rawComp2; // Variable declaration
-    short rawComp3; // Variable declaration
-    short rawPressure; // Variable declaration
-    short rawTemperature; // Variable declaration
-    char valueDP1; // Variable declaration
-    char valueDP2; // Variable declaration
-    char valueDP3; // Variable declaration
-    char valueDP4; // Variable declaration
-    char valueDP5; // Variable declaration
-    char valueDP6; // Variable declaration
-    char valueDP7; // Variable declaration
-    char valueDP8; // Variable declaration
-    char valueDP9; // Variable declaration
+    long rawComp1; // Variable declaration
+    long rawComp2; // Variable declaration
+    long rawComp3; // Variable declaration
+    long rawPressure; // Variable declaration
+    long rawTemperature; // Variable declaration
+    short valueDP1; // Variable declaration
+    short valueDP2; // Variable declaration
+    short valueDP3; // Variable declaration
+    short valueDP4; // Variable declaration
+    short valueDP5; // Variable declaration
+    short valueDP6; // Variable declaration
+    short valueDP7; // Variable declaration
+    short valueDP8; // Variable declaration
+    short valueDP9; // Variable declaration
     char valueLsb; // Variable declaration
     char valueMsb; // Variable declaration
     char valueXlsb; // Variable declaration
@@ -505,8 +505,8 @@ float BMP280::pressureasHpa() {
     return hpa;
 }
 
-short BMP280::pressureasRaw() {
-    short output; // Variable declaration
+long BMP280::pressureasRaw() {
+    long output; // Variable declaration
     char valueLsb; // Variable declaration
     char valueMsb; // Variable declaration
     char valueXlsb; // Variable declaration
@@ -523,13 +523,13 @@ short BMP280::pressureasRaw() {
 
 float BMP280::temperatureasCelsius() {
     float celsius; // Variable declaration
-    short rawComp1; // Variable declaration
-    short rawComp2; // Variable declaration
-    short rawComp3; // Variable declaration
-    short rawTemp; // Variable declaration
-    char valueDT1; // Variable declaration
-    char valueDT2; // Variable declaration
-    char valueDT3; // Variable declaration
+    long rawComp1; // Variable declaration
+    long rawComp2; // Variable declaration
+    long rawComp3; // Variable declaration
+    long rawTemp; // Variable declaration
+    short valueDT1; // Variable declaration
+    short valueDT2; // Variable declaration
+    short valueDT3; // Variable declaration
     char valueLsb; // Variable declaration
     char valueMsb; // Variable declaration
     char valueXlsb; // Variable declaration
@@ -551,8 +551,8 @@ float BMP280::temperatureasCelsius() {
     return celsius;
 }
 
-short BMP280::temperatureasRaw() {
-    short output; // Variable declaration
+long BMP280::temperatureasRaw() {
+    long output; // Variable declaration
     char valueLsb; // Variable declaration
     char valueMsb; // Variable declaration
     char valueXlsb; // Variable declaration
diff --git a/test/sampleData/arduino/BMP280.h b/test/sampleData/arduino/BMP280.h
index 9e0f40e..1fb381b 100644
--- a/test/sampleData/arduino/BMP280.h
+++ b/test/sampleData/arduino/BMP280.h
@@ -168,7 +168,7 @@ class BMP280 {
          * Reads the atmospheric pressure
 
          */
-        short pressureasRaw();
+        long pressureasRaw();
 
         /**
          * Reads the temperature
@@ -179,7 +179,7 @@ class BMP280 {
          * Reads the temperature
 
          */
-        short temperatureasRaw();
+        long temperatureasRaw();
 
 
     private:
diff --git a/test/sampleData/circuitpython/BMP280.py b/test/sampleData/circuitpython/BMP280.py
index 92fd6e8..11e0592 100644
--- a/test/sampleData/circuitpython/BMP280.py
+++ b/test/sampleData/circuitpython/BMP280.py
@@ -241,6 +241,8 @@ def get_digt2(self):
             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_digt3(self):
diff --git a/test/sampleData/embedded-c/BMP280.c b/test/sampleData/embedded-c/BMP280.c
index 96ca404..c32e096 100644
--- a/test/sampleData/embedded-c/BMP280.c
+++ b/test/sampleData/embedded-c/BMP280.c
@@ -301,20 +301,20 @@ void bmp280_pressure_ashpa(
     int (*read)(uint8_t, uint8_t, int*, uint8_t)
 ) {
     float hpa; // Variable declaration
-    short rawComp1; // Variable declaration
-    short rawComp2; // Variable declaration
-    short rawComp3; // Variable declaration
-    short rawPressure; // Variable declaration
-    short rawTemperature; // Variable declaration
-    char valueDP1; // Variable declaration
-    char valueDP2; // Variable declaration
-    char valueDP3; // Variable declaration
-    char valueDP4; // Variable declaration
-    char valueDP5; // Variable declaration
-    char valueDP6; // Variable declaration
-    char valueDP7; // Variable declaration
-    char valueDP8; // Variable declaration
-    char valueDP9; // Variable declaration
+    long rawComp1; // Variable declaration
+    long rawComp2; // Variable declaration
+    long rawComp3; // Variable declaration
+    long rawPressure; // Variable declaration
+    long rawTemperature; // Variable declaration
+    short valueDP1; // Variable declaration
+    short valueDP2; // Variable declaration
+    short valueDP3; // Variable declaration
+    short valueDP4; // Variable declaration
+    short valueDP5; // Variable declaration
+    short valueDP6; // Variable declaration
+    short valueDP7; // Variable declaration
+    short valueDP8; // Variable declaration
+    short valueDP9; // Variable declaration
     char valueLsb; // Variable declaration
     char valueMsb; // Variable declaration
     char valueXlsb; // Variable declaration
@@ -354,10 +354,10 @@ void bmp280_pressure_ashpa(
 }
 
 void bmp280_pressure_asraw(
-    short* val,
+    long* val,
     int (*read)(uint8_t, uint8_t, int*, uint8_t)
 ) {
-    short output; // Variable declaration
+    long output; // Variable declaration
     char valueLsb; // Variable declaration
     char valueMsb; // Variable declaration
     char valueXlsb; // Variable declaration
@@ -377,13 +377,13 @@ void bmp280_temperature_ascelsius(
     int (*read)(uint8_t, uint8_t, int*, uint8_t)
 ) {
     float celsius; // Variable declaration
-    short rawComp1; // Variable declaration
-    short rawComp2; // Variable declaration
-    short rawComp3; // Variable declaration
-    short rawTemp; // Variable declaration
-    char valueDT1; // Variable declaration
-    char valueDT2; // Variable declaration
-    char valueDT3; // Variable declaration
+    long rawComp1; // Variable declaration
+    long rawComp2; // Variable declaration
+    long rawComp3; // Variable declaration
+    long rawTemp; // Variable declaration
+    short valueDT1; // Variable declaration
+    short valueDT2; // Variable declaration
+    short valueDT3; // Variable declaration
     char valueLsb; // Variable declaration
     char valueMsb; // Variable declaration
     char valueXlsb; // Variable declaration
@@ -406,10 +406,10 @@ void bmp280_temperature_ascelsius(
 }
 
 void bmp280_temperature_asraw(
-    short* val,
+    long* val,
     int (*read)(uint8_t, uint8_t, int*, uint8_t)
 ) {
-    short output; // Variable declaration
+    long output; // Variable declaration
     char valueLsb; // Variable declaration
     char valueMsb; // Variable declaration
     char valueXlsb; // Variable declaration
diff --git a/test/sampleData/embedded-c/BMP280.h b/test/sampleData/embedded-c/BMP280.h
index 03b52d3..b7cac19 100644
--- a/test/sampleData/embedded-c/BMP280.h
+++ b/test/sampleData/embedded-c/BMP280.h
@@ -203,7 +203,7 @@ void bmp280_pressure_ashpa(
 
 */
 void bmp280_pressure_asraw(
-    short* val,
+    long* val,
     int (*read)(uint8_t, uint8_t, int*, uint8_t)
 );
 
@@ -220,7 +220,7 @@ void bmp280_temperature_ascelsius(
 
 */
 void bmp280_temperature_asraw(
-    short* val,
+    long* val,
     int (*read)(uint8_t, uint8_t, int*, uint8_t)
 );
 
diff --git a/test/sampleData/esp32/BMP280.cpp b/test/sampleData/esp32/BMP280.cpp
index 2025e53..d0d054d 100644
--- a/test/sampleData/esp32/BMP280.cpp
+++ b/test/sampleData/esp32/BMP280.cpp
@@ -450,20 +450,20 @@ uint8_t BMP280::readTempXlsb() {
 
 float BMP280::pressureasHpa() {
     float hpa; // Variable declaration
-    short rawComp1; // Variable declaration
-    short rawComp2; // Variable declaration
-    short rawComp3; // Variable declaration
-    short rawPressure; // Variable declaration
-    short rawTemperature; // Variable declaration
-    char valueDP1; // Variable declaration
-    char valueDP2; // Variable declaration
-    char valueDP3; // Variable declaration
-    char valueDP4; // Variable declaration
-    char valueDP5; // Variable declaration
-    char valueDP6; // Variable declaration
-    char valueDP7; // Variable declaration
-    char valueDP8; // Variable declaration
-    char valueDP9; // Variable declaration
+    long rawComp1; // Variable declaration
+    long rawComp2; // Variable declaration
+    long rawComp3; // Variable declaration
+    long rawPressure; // Variable declaration
+    long rawTemperature; // Variable declaration
+    short valueDP1; // Variable declaration
+    short valueDP2; // Variable declaration
+    short valueDP3; // Variable declaration
+    short valueDP4; // Variable declaration
+    short valueDP5; // Variable declaration
+    short valueDP6; // Variable declaration
+    short valueDP7; // Variable declaration
+    short valueDP8; // Variable declaration
+    short valueDP9; // Variable declaration
     char valueLsb; // Variable declaration
     char valueMsb; // Variable declaration
     char valueXlsb; // Variable declaration
@@ -502,8 +502,8 @@ float BMP280::pressureasHpa() {
     return hpa;
 }
 
-short BMP280::pressureasRaw() {
-    short output; // Variable declaration
+long BMP280::pressureasRaw() {
+    long output; // Variable declaration
     char valueLsb; // Variable declaration
     char valueMsb; // Variable declaration
     char valueXlsb; // Variable declaration
@@ -520,13 +520,13 @@ short BMP280::pressureasRaw() {
 
 float BMP280::temperatureasCelsius() {
     float celsius; // Variable declaration
-    short rawComp1; // Variable declaration
-    short rawComp2; // Variable declaration
-    short rawComp3; // Variable declaration
-    short rawTemp; // Variable declaration
-    char valueDT1; // Variable declaration
-    char valueDT2; // Variable declaration
-    char valueDT3; // Variable declaration
+    long rawComp1; // Variable declaration
+    long rawComp2; // Variable declaration
+    long rawComp3; // Variable declaration
+    long rawTemp; // Variable declaration
+    short valueDT1; // Variable declaration
+    short valueDT2; // Variable declaration
+    short valueDT3; // Variable declaration
     char valueLsb; // Variable declaration
     char valueMsb; // Variable declaration
     char valueXlsb; // Variable declaration
@@ -548,8 +548,8 @@ float BMP280::temperatureasCelsius() {
     return celsius;
 }
 
-short BMP280::temperatureasRaw() {
-    short output; // Variable declaration
+long BMP280::temperatureasRaw() {
+    long output; // Variable declaration
     char valueLsb; // Variable declaration
     char valueMsb; // Variable declaration
     char valueXlsb; // Variable declaration
diff --git a/test/sampleData/esp32/BMP280.h b/test/sampleData/esp32/BMP280.h
index e25ac4c..eda2210 100644
--- a/test/sampleData/esp32/BMP280.h
+++ b/test/sampleData/esp32/BMP280.h
@@ -167,7 +167,7 @@ class BMP280 {
          * Reads the atmospheric pressure
 
          */
-        short pressureasRaw();
+        long pressureasRaw();
 
         /**
          * Reads the temperature
@@ -178,7 +178,7 @@ class BMP280 {
          * Reads the temperature
 
          */
-        short temperatureasRaw();
+        long temperatureasRaw();
 
 
     private:
diff --git a/test/sampleData/espruino/BMP280.js b/test/sampleData/espruino/BMP280.js
index 5b19130..d366d09 100644
--- a/test/sampleData/espruino/BMP280.js
+++ b/test/sampleData/espruino/BMP280.js
@@ -288,6 +288,8 @@ BMP280.prototype.getDigT2 = function() {
   for (var byte of read) {
     result = result << 8 | byte
   }
+  // Unsigned > Signed integer
+  result = _sign(result, 16)
   return result
 }
 
diff --git a/test/sampleData/kubos/BMP280.c b/test/sampleData/kubos/BMP280.c
index d629238..c826543 100644
--- a/test/sampleData/kubos/BMP280.c
+++ b/test/sampleData/kubos/BMP280.c
@@ -251,20 +251,20 @@ int bmp280_readTempXlsb(uint8_t* val) {
 
 void bmp280_pressure_ashpa(float* val) {
     float hpa; // Variable declaration
-    short rawComp1; // Variable declaration
-    short rawComp2; // Variable declaration
-    short rawComp3; // Variable declaration
-    short rawPressure; // Variable declaration
-    short rawTemperature; // Variable declaration
-    char valueDP1; // Variable declaration
-    char valueDP2; // Variable declaration
-    char valueDP3; // Variable declaration
-    char valueDP4; // Variable declaration
-    char valueDP5; // Variable declaration
-    char valueDP6; // Variable declaration
-    char valueDP7; // Variable declaration
-    char valueDP8; // Variable declaration
-    char valueDP9; // Variable declaration
+    long rawComp1; // Variable declaration
+    long rawComp2; // Variable declaration
+    long rawComp3; // Variable declaration
+    long rawPressure; // Variable declaration
+    long rawTemperature; // Variable declaration
+    short valueDP1; // Variable declaration
+    short valueDP2; // Variable declaration
+    short valueDP3; // Variable declaration
+    short valueDP4; // Variable declaration
+    short valueDP5; // Variable declaration
+    short valueDP6; // Variable declaration
+    short valueDP7; // Variable declaration
+    short valueDP8; // Variable declaration
+    short valueDP9; // Variable declaration
     char valueLsb; // Variable declaration
     char valueMsb; // Variable declaration
     char valueXlsb; // Variable declaration
@@ -303,8 +303,8 @@ void bmp280_pressure_ashpa(float* val) {
     val = hpa;
 }
 
-void bmp280_pressure_asraw(short* val) {
-    short output; // Variable declaration
+void bmp280_pressure_asraw(long* val) {
+    long output; // Variable declaration
     char valueLsb; // Variable declaration
     char valueMsb; // Variable declaration
     char valueXlsb; // Variable declaration
@@ -321,13 +321,13 @@ void bmp280_pressure_asraw(short* val) {
 
 void bmp280_temperature_ascelsius(float* val) {
     float celsius; // Variable declaration
-    short rawComp1; // Variable declaration
-    short rawComp2; // Variable declaration
-    short rawComp3; // Variable declaration
-    short rawTemp; // Variable declaration
-    char valueDT1; // Variable declaration
-    char valueDT2; // Variable declaration
-    char valueDT3; // Variable declaration
+    long rawComp1; // Variable declaration
+    long rawComp2; // Variable declaration
+    long rawComp3; // Variable declaration
+    long rawTemp; // Variable declaration
+    short valueDT1; // Variable declaration
+    short valueDT2; // Variable declaration
+    short valueDT3; // Variable declaration
     char valueLsb; // Variable declaration
     char valueMsb; // Variable declaration
     char valueXlsb; // Variable declaration
@@ -349,8 +349,8 @@ void bmp280_temperature_ascelsius(float* val) {
     val = celsius;
 }
 
-void bmp280_temperature_asraw(short* val) {
-    short output; // Variable declaration
+void bmp280_temperature_asraw(long* val) {
+    long output; // Variable declaration
     char valueLsb; // Variable declaration
     char valueMsb; // Variable declaration
     char valueXlsb; // Variable declaration
diff --git a/test/sampleData/kubos/BMP280.h b/test/sampleData/kubos/BMP280.h
index c70a42a..fdda146 100644
--- a/test/sampleData/kubos/BMP280.h
+++ b/test/sampleData/kubos/BMP280.h
@@ -150,7 +150,7 @@ void bmp280_pressure_ashpa(float* val);
  * Reads the atmospheric pressure
 
 */
-void bmp280_pressure_asraw(short* val);
+void bmp280_pressure_asraw(long* val);
 
 /**
  * Reads the temperature
@@ -161,7 +161,7 @@ void bmp280_temperature_ascelsius(float* val);
  * Reads the temperature
 
 */
-void bmp280_temperature_asraw(short* val);
+void bmp280_temperature_asraw(long* val);
 
 
 #endif
\ No newline at end of file
diff --git a/test/sampleData/micropython/BMP280.py b/test/sampleData/micropython/BMP280.py
index 0a5bf49..4e26859 100644
--- a/test/sampleData/micropython/BMP280.py
+++ b/test/sampleData/micropython/BMP280.py
@@ -251,6 +251,8 @@ def get_digt2(self):
         val = 0
         val = val << 8 | byte_list[0]
         val = val << 8 | byte_list[1]
+        # Unsigned > Signed integer
+        val = _sign(val, 16)
         return val
 
     def get_digt3(self):
diff --git a/test/sampleData/raspberrypi/BMP280.py b/test/sampleData/raspberrypi/BMP280.py
index 52dc801..a7ebdc3 100644
--- a/test/sampleData/raspberrypi/BMP280.py
+++ b/test/sampleData/raspberrypi/BMP280.py
@@ -194,6 +194,8 @@ def get_digt2(self):
             self.device_address,
             self.REGISTER_DIGT2
         )
+        # Unsigned > Signed integer
+        val = _sign(val, 16)
         return val
 
     def get_digt3(self):
diff --git a/test/sampleData/webpage/ADS1015.html b/test/sampleData/webpage/ADS1015.html
new file mode 100644
index 0000000..785a584
--- /dev/null
+++ b/test/sampleData/webpage/ADS1015.html
@@ -0,0 +1,142 @@
+
+
+<html>
+    <head>
+        <title>ADS1015</title>
+    </head>
+    <body>
+        <style>
+            body {
+                font-family: sans-serif;
+                background-color: #efefef;
+            }
+            section.registers {
+                background-color: white;
+                box-shadow: 1px 1px 1px black;
+                border-radius: 4px;
+            }
+            section.registers table {
+                width: 100%;
+                border-style: solid;
+            }
+            section.registers td {
+                text-align: center;
+                vertical-align: middle;
+                border-style: solid;
+            }
+            section.registers td h1 {
+                font-size: 11pt;
+                margin-block: unset;
+                margin-bottom: 8px;
+            }
+            section.registers td h2 {
+                font-size: 10pt;
+                color: #333;
+                margin-block: unset;
+                font-weight: normal;
+                margin-bottom: 8px;
+            }
+            section.registers td h3 {
+                font-size: 9pt;
+                color: #555;
+                margin-block: unset;
+                font-weight: normal;
+            }
+            footer {
+                opacity: 0.75;
+                font-size: 9pt;
+            }
+        </style>
+        <h1>ADS1015</h1>
+        <section class="description">
+            <p>
+                Texas Instruments Analog-Digital Converter
+            </p>
+            <ul>
+            <li>Device address 73</li>
+            <li>Address type 7-bit</li>
+            <li>Little Endian</li>
+            </ul>
+        </section>
+        <section class="registers">
+            <table>
+                <tbody>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="6.25%">
+                            <h3>
+                                Addr 0 <br><br>
+                                16-bytes <br>
+                                    <br><em>Read-only</em>
+                            </h3>
+                        </td>
+                        <td colspan="16" width="93.75%">
+                            <h1>ADC Value</h1>
+                            <h2>Conversion register contains the result of the last conversion</h2>
+                        </td>
+                    </tr>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="6.25%">
+                            <h3>
+                                Addr 1 <br><br>
+                                16-bytes <br>
+                            </h3>
+                        </td>
+                        <td colspan="3" width="18.75%">
+                            <h1>Set the channel to read</h1>
+                            <h2>This sets the channel for reading analog voltage
+</h2>
+                            <h3>
+                                [14:12] | 3-bytes                                <br><em>Inaccessible</em>
+                            </h3>
+                        </td>
+                        <td colspan="3" width="18.75%">
+                            <h1>Setup programmable gain</h1>
+                            <h2>This sets the programmable gain for reading analog voltage
+</h2>
+                            <h3>
+                                [11:9] | 3-bytes                                <br><em>Write-only</em>
+                            </h3>
+                        </td>
+                        <td colspan="1" width="6.25%">
+                            <h1>Set the operating mode</h1>
+                            <h2>This bit controls the operating mode
+</h2>
+                            <h3>
+                                [8:8] | 1-byte                                <br><em>Write-only</em>
+                            </h3>
+                        </td>
+                        <td colspan="3" width="18.75%">
+                            <h1>Setup sample rate for reading analog voltage</h1>
+                            <h2>This sets the samples-per-second value
+</h2>
+                            <h3>
+                                [7:5] | 3-bytes                                <br><em>Write-only</em>
+                            </h3>
+                        </td>
+                    </tr>
+                </tbody>
+            </table>
+        </section>
+        <section class="functions">
+            <h2>Functions</h2>
+            <ul>
+                <li>
+                    <b>analog.read</b> -
+                    Reads the analog voltage in Volts
+                </li>
+            </ul>
+        </section>
+        <hr>
+        <footer>
+            <p>
+                Contact <a href="mailto:felker@google.com">Nick Felker</a>.
+            </p>
+            <p>
+                Copyright Google Inc. 2019. Published under Apache-2.0 license.
+            </p>
+            <p>
+                Peripheral version 0.1.0 using Cyanobyte v0.1.0.
+            </p>
+        </footer>
+    </body>
+</html>
\ No newline at end of file
diff --git a/test/sampleData/webpage/BH1750FVI.html b/test/sampleData/webpage/BH1750FVI.html
new file mode 100644
index 0000000..eadcc7f
--- /dev/null
+++ b/test/sampleData/webpage/BH1750FVI.html
@@ -0,0 +1,252 @@
+
+<html>
+    <head>
+        <title>BH1750FVI</title>
+    </head>
+    <body>
+        <style>
+            body {
+                font-family: sans-serif;
+                background-color: #efefef;
+            }
+            section.registers {
+                background-color: white;
+                box-shadow: 1px 1px 1px black;
+                border-radius: 4px;
+            }
+            section.registers table {
+                width: 100%;
+                border-style: solid;
+            }
+            section.registers td {
+                text-align: center;
+                vertical-align: middle;
+                border-style: solid;
+            }
+            section.registers td h1 {
+                font-size: 11pt;
+                margin-block: unset;
+                margin-bottom: 8px;
+            }
+            section.registers td h2 {
+                font-size: 10pt;
+                color: #333;
+                margin-block: unset;
+                font-weight: normal;
+                margin-bottom: 8px;
+            }
+            section.registers td h3 {
+                font-size: 9pt;
+                color: #555;
+                margin-block: unset;
+                font-weight: normal;
+            }
+            footer {
+                opacity: 0.75;
+                font-size: 9pt;
+            }
+        </style>
+        <h1>BH1750FVI</h1>
+        <section class="description">
+            <p>
+                Rohm Light Sensor
+            </p>
+            <ul>
+            <li>Device addresses:
+            35,
+            92
+            </li>
+            <li>Address type 7-bit</li>
+            </ul>
+        </section>
+        <section class="registers">
+            <table>
+                <tbody>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="50.0%">
+                            <h3>
+                                Addr 0 <br><br>
+                                0-bytes <br>
+                                    <br><em>Write-only</em>
+                            </h3>
+                        </td>
+                        <td colspan="0" width="-50.0%">
+                            <h1>Power Down</h1>
+                            <h2>No active state</h2>
+                        </td>
+                        <td colspan="31" width="50.0%">
+                            <!-- intentionally leave empty -->
+                        </td>
+                    </tr>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="50.0%">
+                            <h3>
+                                Addr 1 <br><br>
+                                0-bytes <br>
+                                    <br><em>Write-only</em>
+                            </h3>
+                        </td>
+                        <td colspan="0" width="-50.0%">
+                            <h1>Power On</h1>
+                            <h2>Waiting for measurement command</h2>
+                        </td>
+                        <td colspan="31" width="50.0%">
+                            <!-- intentionally leave empty -->
+                        </td>
+                    </tr>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="50.0%">
+                            <h3>
+                                Addr 7 <br><br>
+                                0-bytes <br>
+                                    <br><em>Write-only</em>
+                            </h3>
+                        </td>
+                        <td colspan="0" width="-50.0%">
+                            <h1>Reset</h1>
+                            <h2>Reset data register value. Not accepted in Power Down mode.</h2>
+                        </td>
+                        <td colspan="31" width="50.0%">
+                            <!-- intentionally leave empty -->
+                        </td>
+                    </tr>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="50.0%">
+                            <h3>
+                                Addr 16 <br><br>
+                                0-bytes <br>
+                                    <br><em>Write-only</em>
+                            </h3>
+                        </td>
+                        <td colspan="0" width="-50.0%">
+                            <h1>Continuously H-Resolution Mode</h1>
+                            <h2>Start measurement at 1lx resolution. Typically 120ms.</h2>
+                        </td>
+                        <td colspan="31" width="50.0%">
+                            <!-- intentionally leave empty -->
+                        </td>
+                    </tr>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="50.0%">
+                            <h3>
+                                Addr 17 <br><br>
+                                0-bytes <br>
+                                    <br><em>Write-only</em>
+                            </h3>
+                        </td>
+                        <td colspan="0" width="-50.0%">
+                            <h1>Continously H-Resolution Mode2</h1>
+                            <h2>Start measurement at 0.5lx resolution. Typically 120ms.</h2>
+                        </td>
+                        <td colspan="31" width="50.0%">
+                            <!-- intentionally leave empty -->
+                        </td>
+                    </tr>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="50.0%">
+                            <h3>
+                                Addr 19 <br><br>
+                                0-bytes <br>
+                                    <br><em>Write-only</em>
+                            </h3>
+                        </td>
+                        <td colspan="0" width="-50.0%">
+                            <h1>Continuously L-Resolution Mode</h1>
+                            <h2>Start measurement at 4lx resolution. Typically 16ms.</h2>
+                        </td>
+                        <td colspan="31" width="50.0%">
+                            <!-- intentionally leave empty -->
+                        </td>
+                    </tr>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="50.0%">
+                            <h3>
+                                Addr 32 <br><br>
+                                0-bytes <br>
+                                    <br><em>Write-only</em>
+                            </h3>
+                        </td>
+                        <td colspan="0" width="-50.0%">
+                            <h1>One Time H-Resolution Mode</h1>
+                            <h2>Start measurement at 1lx resolution. Typically 120ms.
+Power Down after measurement.
+</h2>
+                        </td>
+                        <td colspan="31" width="50.0%">
+                            <!-- intentionally leave empty -->
+                        </td>
+                    </tr>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="50.0%">
+                            <h3>
+                                Addr 33 <br><br>
+                                0-bytes <br>
+                                    <br><em>Write-only</em>
+                            </h3>
+                        </td>
+                        <td colspan="0" width="-50.0%">
+                            <h1>One Time H-Resolution Mode2</h1>
+                            <h2>Start measurement at 0.5lx resolution. Typically 120ms.
+Power Down after measurement.
+</h2>
+                        </td>
+                        <td colspan="31" width="50.0%">
+                            <!-- intentionally leave empty -->
+                        </td>
+                    </tr>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="50.0%">
+                            <h3>
+                                Addr 35 <br><br>
+                                0-bytes <br>
+                                    <br><em>Write-only</em>
+                            </h3>
+                        </td>
+                        <td colspan="0" width="-50.0%">
+                            <h1>One Time L-Resolution Mode</h1>
+                            <h2>Start measurement at 4lx resolution. Typically 16ms.
+Power Down after measurement.
+</h2>
+                        </td>
+                        <td colspan="31" width="50.0%">
+                            <!-- intentionally leave empty -->
+                        </td>
+                    </tr>
+                </tbody>
+            </table>
+        </section>
+        <section class="functions">
+            <h2>Functions</h2>
+            <ul>
+                <li>
+                    <b>_lifecycle.Begin</b> -
+                    Sends a POWER ON cmd to device
+                </li>
+                <li>
+                    <b>command.PowerDown</b> -
+                    Things you can do to device
+                </li>
+                <li>
+                    <b>command.Reset</b> -
+                    Things you can do to device
+                </li>
+                <li>
+                    <b>read.LightIntensity</b> -
+                    Read light intensity from device
+                </li>
+            </ul>
+        </section>
+        <hr>
+        <footer>
+            <p>
+                Contact <a href="mailto:felker@google.com">Nick Felker</a>.
+            </p>
+            <p>
+                Copyright Google Inc. 2020. Published under Apache-2.0 license.
+            </p>
+            <p>
+                Peripheral version 0.1.0 using Cyanobyte v0.1.0.
+            </p>
+        </footer>
+    </body>
+</html>
\ No newline at end of file
diff --git a/test/sampleData/webpage/BMP180.html b/test/sampleData/webpage/BMP180.html
new file mode 100644
index 0000000..77865fb
--- /dev/null
+++ b/test/sampleData/webpage/BMP180.html
@@ -0,0 +1,246 @@
+
+<html>
+    <head>
+        <title>BMP180</title>
+    </head>
+    <body>
+        <style>
+            body {
+                font-family: sans-serif;
+                background-color: #efefef;
+            }
+            section.registers {
+                background-color: white;
+                box-shadow: 1px 1px 1px black;
+                border-radius: 4px;
+            }
+            section.registers table {
+                width: 100%;
+                border-style: solid;
+            }
+            section.registers td {
+                text-align: center;
+                vertical-align: middle;
+                border-style: solid;
+            }
+            section.registers td h1 {
+                font-size: 11pt;
+                margin-block: unset;
+                margin-bottom: 8px;
+            }
+            section.registers td h2 {
+                font-size: 10pt;
+                color: #333;
+                margin-block: unset;
+                font-weight: normal;
+                margin-bottom: 8px;
+            }
+            section.registers td h3 {
+                font-size: 9pt;
+                color: #555;
+                margin-block: unset;
+                font-weight: normal;
+            }
+            footer {
+                opacity: 0.75;
+                font-size: 9pt;
+            }
+        </style>
+        <h1>BMP180</h1>
+        <section class="description">
+            <p>
+                Bosch Digital Temperature / Pressure Sensor
+            </p>
+            <ul>
+            <li>Device address 119</li>
+            <li>Address type 7-bit</li>
+            </ul>
+        </section>
+        <section class="registers">
+            <table>
+                <tbody>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="6.25%">
+                            <h3>
+                                Addr 170 <br><br>
+                                16-bytes <br>
+                                    <br><em>Read-only</em>
+                            </h3>
+                        </td>
+                        <td colspan="16" width="93.75%">
+                            <h1>Pressure calibration AC1</h1>
+                            <h2>For calibration</h2>
+                        </td>
+                    </tr>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="6.25%">
+                            <h3>
+                                Addr 172 <br><br>
+                                16-bytes <br>
+                                    <br><em>Read-only</em>
+                            </h3>
+                        </td>
+                        <td colspan="16" width="93.75%">
+                            <h1>Pressure calibration AC2</h1>
+                            <h2>For calibration</h2>
+                        </td>
+                    </tr>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="6.25%">
+                            <h3>
+                                Addr 174 <br><br>
+                                16-bytes <br>
+                                    <br><em>Read-only</em>
+                            </h3>
+                        </td>
+                        <td colspan="16" width="93.75%">
+                            <h1>Temperature calibration 3</h1>
+                            <h2>For calibration</h2>
+                        </td>
+                    </tr>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="6.25%">
+                            <h3>
+                                Addr 176 <br><br>
+                                16-bytes <br>
+                                    <br><em>Read-only</em>
+                            </h3>
+                        </td>
+                        <td colspan="16" width="93.75%">
+                            <h1>Temperature calibration 4</h1>
+                            <h2>For calibration</h2>
+                        </td>
+                    </tr>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="6.25%">
+                            <h3>
+                                Addr 178 <br><br>
+                                16-bytes <br>
+                                    <br><em>Read-only</em>
+                            </h3>
+                        </td>
+                        <td colspan="16" width="93.75%">
+                            <h1>Temperature calibration 5</h1>
+                            <h2>For calibration</h2>
+                        </td>
+                    </tr>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="6.25%">
+                            <h3>
+                                Addr 180 <br><br>
+                                16-bytes <br>
+                                    <br><em>Read-only</em>
+                            </h3>
+                        </td>
+                        <td colspan="16" width="93.75%">
+                            <h1>Temperature calibration 6</h1>
+                            <h2>For calibration</h2>
+                        </td>
+                    </tr>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="6.25%">
+                            <h3>
+                                Addr 182 <br><br>
+                                16-bytes <br>
+                                    <br><em>Read-only</em>
+                            </h3>
+                        </td>
+                        <td colspan="16" width="93.75%">
+                            <h1>Pressure calibration VB1</h1>
+                            <h2>For calibration</h2>
+                        </td>
+                    </tr>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="6.25%">
+                            <h3>
+                                Addr 184 <br><br>
+                                16-bytes <br>
+                                    <br><em>Read-only</em>
+                            </h3>
+                        </td>
+                        <td colspan="16" width="93.75%">
+                            <h1>Pressure calibration VB2</h1>
+                            <h2>For calibration</h2>
+                        </td>
+                    </tr>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="6.25%">
+                            <h3>
+                                Addr 188 <br><br>
+                                16-bytes <br>
+                                    <br><em>Read-only</em>
+                            </h3>
+                        </td>
+                        <td colspan="16" width="93.75%">
+                            <h1>Temperature calibration MC</h1>
+                            <h2>For calibration</h2>
+                        </td>
+                    </tr>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="6.25%">
+                            <h3>
+                                Addr 190 <br><br>
+                                16-bytes <br>
+                                    <br><em>Read-only</em>
+                            </h3>
+                        </td>
+                        <td colspan="16" width="93.75%">
+                            <h1>Temperature calibration MD</h1>
+                            <h2>For calibration</h2>
+                        </td>
+                    </tr>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="6.25%">
+                            <h3>
+                                Addr 244 <br><br>
+                                8-bytes <br>
+                                    <br><em>Write-only</em>
+                            </h3>
+                        </td>
+                        <td colspan="8" width="43.75%">
+                            <h1>Register to write commands</h1>
+                            <h2>Register stores what the measurement type should be</h2>
+                        </td>
+                        <td colspan="23" width="43.75%">
+                            <!-- intentionally leave empty -->
+                        </td>
+                    </tr>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="6.25%">
+                            <h3>
+                                Addr 246 <br><br>
+                                16-bytes <br>
+                                    <br><em>Read-only</em>
+                            </h3>
+                        </td>
+                        <td colspan="16" width="93.75%">
+                            <h1>Register that stores measurement results</h1>
+                            <h2>Register stores most recent measurement result</h2>
+                        </td>
+                    </tr>
+                </tbody>
+            </table>
+        </section>
+        <section class="functions">
+            <h2>Functions</h2>
+            <ul>
+                <li>
+                    <b>temperature.asCelsius</b> -
+                    Reads the temperature
+                </li>
+            </ul>
+        </section>
+        <hr>
+        <footer>
+            <p>
+                Contact <a href="mailto:felker@google.com">Nick Felker</a>.
+            </p>
+            <p>
+                Copyright Google Inc. 2020. Published under Apache-2.0 license.
+            </p>
+            <p>
+                Peripheral version 0.1.0 using Cyanobyte v0.1.0.
+            </p>
+        </footer>
+    </body>
+</html>
\ No newline at end of file
diff --git a/test/sampleData/webpage/BMP280.html b/test/sampleData/webpage/BMP280.html
new file mode 100644
index 0000000..283d2b7
--- /dev/null
+++ b/test/sampleData/webpage/BMP280.html
@@ -0,0 +1,361 @@
+
+<html>
+    <head>
+        <title>BMP280</title>
+    </head>
+    <body>
+        <style>
+            body {
+                font-family: sans-serif;
+                background-color: #efefef;
+            }
+            section.registers {
+                background-color: white;
+                box-shadow: 1px 1px 1px black;
+                border-radius: 4px;
+            }
+            section.registers table {
+                width: 100%;
+                border-style: solid;
+            }
+            section.registers td {
+                text-align: center;
+                vertical-align: middle;
+                border-style: solid;
+            }
+            section.registers td h1 {
+                font-size: 11pt;
+                margin-block: unset;
+                margin-bottom: 8px;
+            }
+            section.registers td h2 {
+                font-size: 10pt;
+                color: #333;
+                margin-block: unset;
+                font-weight: normal;
+                margin-bottom: 8px;
+            }
+            section.registers td h3 {
+                font-size: 9pt;
+                color: #555;
+                margin-block: unset;
+                font-weight: normal;
+            }
+            footer {
+                opacity: 0.75;
+                font-size: 9pt;
+            }
+        </style>
+        <h1>BMP280</h1>
+        <section class="description">
+            <p>
+                Bosch Digital Pressure Sensor
+            </p>
+            <ul>
+            <li>Device address 119</li>
+            <li>Address type 7-bit</li>
+            </ul>
+        </section>
+        <section class="registers">
+            <table>
+                <tbody>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="6.25%">
+                            <h3>
+                                Addr 136 <br><br>
+                                16-bytes <br>
+                                    <br><em>Read-only</em>
+                            </h3>
+                        </td>
+                        <td colspan="16" width="93.75%">
+                            <h1>Digital Temperature Compensation 1</h1>
+                            <h2>Used for Celcius conversion</h2>
+                        </td>
+                    </tr>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="6.25%">
+                            <h3>
+                                Addr 138 <br><br>
+                                16-bytes <br>
+                                    <br><em>Read-only</em>
+                                    <br><em>Signed value</em>
+                            </h3>
+                        </td>
+                        <td colspan="16" width="93.75%">
+                            <h1>Digital Temperature Compensation 2</h1>
+                            <h2>Used for Celcius conversion</h2>
+                        </td>
+                    </tr>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="6.25%">
+                            <h3>
+                                Addr 140 <br><br>
+                                16-bytes <br>
+                                    <br><em>Read-only</em>
+                                    <br><em>Signed value</em>
+                            </h3>
+                        </td>
+                        <td colspan="16" width="93.75%">
+                            <h1>Digital Temperature Compensation 3</h1>
+                            <h2>Used for Celcius conversion</h2>
+                        </td>
+                    </tr>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="6.25%">
+                            <h3>
+                                Addr 142 <br><br>
+                                16-bytes <br>
+                                    <br><em>Read-only</em>
+                            </h3>
+                        </td>
+                        <td colspan="16" width="93.75%">
+                            <h1>Digital Pressure Compensation 1</h1>
+                            <h2>Used for Pascals conversion</h2>
+                        </td>
+                    </tr>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="6.25%">
+                            <h3>
+                                Addr 144 <br><br>
+                                16-bytes <br>
+                                    <br><em>Read-only</em>
+                                    <br><em>Signed value</em>
+                            </h3>
+                        </td>
+                        <td colspan="16" width="93.75%">
+                            <h1>Digital Pressure Compensation 2</h1>
+                            <h2>Used for Pascals conversion</h2>
+                        </td>
+                    </tr>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="6.25%">
+                            <h3>
+                                Addr 146 <br><br>
+                                16-bytes <br>
+                                    <br><em>Read-only</em>
+                                    <br><em>Signed value</em>
+                            </h3>
+                        </td>
+                        <td colspan="16" width="93.75%">
+                            <h1>Digital Pressure Compensation 3</h1>
+                            <h2>Used for Pascals conversion</h2>
+                        </td>
+                    </tr>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="6.25%">
+                            <h3>
+                                Addr 148 <br><br>
+                                16-bytes <br>
+                                    <br><em>Read-only</em>
+                                    <br><em>Signed value</em>
+                            </h3>
+                        </td>
+                        <td colspan="16" width="93.75%">
+                            <h1>Digital Pressure Compensation 4</h1>
+                            <h2>Used for Pascals conversion</h2>
+                        </td>
+                    </tr>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="6.25%">
+                            <h3>
+                                Addr 150 <br><br>
+                                16-bytes <br>
+                                    <br><em>Read-only</em>
+                                    <br><em>Signed value</em>
+                            </h3>
+                        </td>
+                        <td colspan="16" width="93.75%">
+                            <h1>Digital Pressure Compensation 5</h1>
+                            <h2>Used for Pascals conversion</h2>
+                        </td>
+                    </tr>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="6.25%">
+                            <h3>
+                                Addr 152 <br><br>
+                                16-bytes <br>
+                                    <br><em>Read-only</em>
+                                    <br><em>Signed value</em>
+                            </h3>
+                        </td>
+                        <td colspan="16" width="93.75%">
+                            <h1>Digital Pressure Compensation 6</h1>
+                            <h2>Used for Pascals conversion</h2>
+                        </td>
+                    </tr>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="6.25%">
+                            <h3>
+                                Addr 154 <br><br>
+                                16-bytes <br>
+                                    <br><em>Read-only</em>
+                                    <br><em>Signed value</em>
+                            </h3>
+                        </td>
+                        <td colspan="16" width="93.75%">
+                            <h1>Digital Pressure Compensation 7</h1>
+                            <h2>Used for Pascals conversion</h2>
+                        </td>
+                    </tr>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="6.25%">
+                            <h3>
+                                Addr 156 <br><br>
+                                16-bytes <br>
+                                    <br><em>Read-only</em>
+                                    <br><em>Signed value</em>
+                            </h3>
+                        </td>
+                        <td colspan="16" width="93.75%">
+                            <h1>Digital Pressure Compensation 8</h1>
+                            <h2>Used for Pascals conversion</h2>
+                        </td>
+                    </tr>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="6.25%">
+                            <h3>
+                                Addr 158 <br><br>
+                                16-bytes <br>
+                                    <br><em>Read-only</em>
+                                    <br><em>Signed value</em>
+                            </h3>
+                        </td>
+                        <td colspan="16" width="93.75%">
+                            <h1>Digital Pressure Compensation 9</h1>
+                            <h2>Used for Pascals conversion</h2>
+                        </td>
+                    </tr>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="6.25%">
+                            <h3>
+                                Addr 247 <br><br>
+                                8-bytes <br>
+                                    <br><em>Read-only</em>
+                            </h3>
+                        </td>
+                        <td colspan="8" width="43.75%">
+                            <h1>Pressure MSB</h1>
+                            <h2>Part 1 of Pressure</h2>
+                        </td>
+                        <td colspan="23" width="43.75%">
+                            <!-- intentionally leave empty -->
+                        </td>
+                    </tr>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="6.25%">
+                            <h3>
+                                Addr 248 <br><br>
+                                8-bytes <br>
+                                    <br><em>Read-only</em>
+                            </h3>
+                        </td>
+                        <td colspan="8" width="43.75%">
+                            <h1>Pressure LSB</h1>
+                            <h2>Part 2 of Pressure</h2>
+                        </td>
+                        <td colspan="23" width="43.75%">
+                            <!-- intentionally leave empty -->
+                        </td>
+                    </tr>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="6.25%">
+                            <h3>
+                                Addr 249 <br><br>
+                                8-bytes <br>
+                                    <br><em>Read-only</em>
+                            </h3>
+                        </td>
+                        <td colspan="8" width="43.75%">
+                            <h1>Pressure XLSB</h1>
+                            <h2>Part 3 of Pressure</h2>
+                        </td>
+                        <td colspan="23" width="43.75%">
+                            <!-- intentionally leave empty -->
+                        </td>
+                    </tr>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="6.25%">
+                            <h3>
+                                Addr 250 <br><br>
+                                8-bytes <br>
+                                    <br><em>Read-only</em>
+                            </h3>
+                        </td>
+                        <td colspan="8" width="43.75%">
+                            <h1>Temperature MSB</h1>
+                            <h2>Part 1 of temperature</h2>
+                        </td>
+                        <td colspan="23" width="43.75%">
+                            <!-- intentionally leave empty -->
+                        </td>
+                    </tr>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="6.25%">
+                            <h3>
+                                Addr 251 <br><br>
+                                8-bytes <br>
+                                    <br><em>Read-only</em>
+                            </h3>
+                        </td>
+                        <td colspan="8" width="43.75%">
+                            <h1>Temperature LSB</h1>
+                            <h2>Part 2 of temperature</h2>
+                        </td>
+                        <td colspan="23" width="43.75%">
+                            <!-- intentionally leave empty -->
+                        </td>
+                    </tr>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="6.25%">
+                            <h3>
+                                Addr 252 <br><br>
+                                8-bytes <br>
+                                    <br><em>Read-only</em>
+                            </h3>
+                        </td>
+                        <td colspan="8" width="43.75%">
+                            <h1>Temperature XLSB</h1>
+                            <h2>Final part of temperature</h2>
+                        </td>
+                        <td colspan="23" width="43.75%">
+                            <!-- intentionally leave empty -->
+                        </td>
+                    </tr>
+                </tbody>
+            </table>
+        </section>
+        <section class="functions">
+            <h2>Functions</h2>
+            <ul>
+                <li>
+                    <b>pressure.asHpa</b> -
+                    Reads the atmospheric pressure
+                </li>
+                <li>
+                    <b>pressure.asRaw</b> -
+                    Reads the atmospheric pressure
+                </li>
+                <li>
+                    <b>temperature.asCelsius</b> -
+                    Reads the temperature
+                </li>
+                <li>
+                    <b>temperature.asRaw</b> -
+                    Reads the temperature
+                </li>
+            </ul>
+        </section>
+        <hr>
+        <footer>
+            <p>
+                Contact <a href="mailto:felker@google.com">Nick Felker</a>.
+            </p>
+            <p>
+                Copyright Google Inc. 2019. Published under Apache-2.0 license.
+            </p>
+            <p>
+                Peripheral version 0.1.0 using Cyanobyte v0.1.0.
+            </p>
+        </footer>
+    </body>
+</html>
\ No newline at end of file
diff --git a/test/sampleData/webpage/Example.html b/test/sampleData/webpage/Example.html
new file mode 100644
index 0000000..c985737
--- /dev/null
+++ b/test/sampleData/webpage/Example.html
@@ -0,0 +1,185 @@
+
+
+<html>
+    <head>
+        <title>Example</title>
+    </head>
+    <body>
+        <style>
+            body {
+                font-family: sans-serif;
+                background-color: #efefef;
+            }
+            section.registers {
+                background-color: white;
+                box-shadow: 1px 1px 1px black;
+                border-radius: 4px;
+            }
+            section.registers table {
+                width: 100%;
+                border-style: solid;
+            }
+            section.registers td {
+                text-align: center;
+                vertical-align: middle;
+                border-style: solid;
+            }
+            section.registers td h1 {
+                font-size: 11pt;
+                margin-block: unset;
+                margin-bottom: 8px;
+            }
+            section.registers td h2 {
+                font-size: 10pt;
+                color: #333;
+                margin-block: unset;
+                font-weight: normal;
+                margin-bottom: 8px;
+            }
+            section.registers td h3 {
+                font-size: 9pt;
+                color: #555;
+                margin-block: unset;
+                font-weight: normal;
+            }
+            footer {
+                opacity: 0.75;
+                font-size: 9pt;
+            }
+        </style>
+        <h1>Example</h1>
+        <section class="description">
+            <p>
+                Example of a package
+            </p>
+            <ul>
+            <li>Device addresses:
+            16,
+            32,
+            48
+            </li>
+            <li>Address type 7-bit</li>
+            </ul>
+        </section>
+        <section class="registers">
+            <table>
+                <tbody>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="3.125%">
+                            <h3>
+                                Addr 0 <br><br>
+                                8-bytes <br>
+                            </h3>
+                        </td>
+                        <td colspan="4" width="12.5%">
+                            <h1>Read-only fields for RegisterA</h1>
+                            <h2>This is a few bits</h2>
+                            <h3>
+                                [7:4] | 4-bytes                                <br><em>Read-only</em>
+                            </h3>
+                        </td>
+                        <td colspan="2" width="6.25%">
+                            <h1>Write-only fields for RegisterA</h1>
+                            <h2>This is fewer bits</h2>
+                            <h3>
+                                [3:2] | 2-bytes                                <br><em>Write-only</em>
+                            </h3>
+                        </td>
+                        <td colspan="1" width="3.125%">
+                            <h1>Read/write field for RegisterA</h1>
+                            <h2>A single-bit</h2>
+                            <h3>
+                                [1:1] | 1-byte                            </h3>
+                        </td>
+                        <td colspan="1" width="3.125%">
+                            <h1>This field should never appear</h1>
+                            <h2>A bit that is neither readable nor writeable</h2>
+                            <h3>
+                                [0:0] | 1-byte                                <br><em>Inaccessible</em>
+                            </h3>
+                        </td>
+                    </tr>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="3.125%">
+                            <h3>
+                                Addr 1 <br><br>
+                                16-bytes <br>
+                            </h3>
+                        </td>
+                        <td colspan="16" width="46.875%">
+                            <h1>Second example</h1>
+                            <h2>A 16-bit register</h2>
+                        </td>
+                        <td colspan="15" width="46.875%">
+                            <!-- intentionally leave empty -->
+                        </td>
+                    </tr>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="3.125%">
+                            <h3>
+                                Addr 2 <br><br>
+                                32-bytes <br>
+                            </h3>
+                        </td>
+                        <td colspan="32" width="96.875%">
+                            <h1>Third example</h1>
+                            <h2>A 32-bit register</h2>
+                        </td>
+                    </tr>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="3.125%">
+                            <h3>
+                                Addr 3 <br><br>
+                                0-bytes <br>
+                            </h3>
+                        </td>
+                        <td colspan="0" width="-3.125%">
+                            <h1>Fourth example</h1>
+                            <h2>A dummy register that has no data</h2>
+                        </td>
+                        <td colspan="31" width="96.875%">
+                            <!-- intentionally leave empty -->
+                        </td>
+                    </tr>
+                </tbody>
+            </table>
+        </section>
+        <section class="functions">
+            <h2>Functions</h2>
+            <ul>
+                <li>
+                    <b>_lifecycle.Begin</b> -
+                    Enables features on device
+                </li>
+                <li>
+                    <b>_lifecycle.End</b> -
+                    Enables features on device
+                </li>
+                <li>
+                    <b>Return.Array</b> -
+                    Computes and returns
+                </li>
+                <li>
+                    <b>Return.Number</b> -
+                    Computes and returns
+                </li>
+                <li>
+                    <b>Return.Void</b> -
+                    Computes and returns
+                </li>
+            </ul>
+        </section>
+        <hr>
+        <footer>
+            <p>
+                Contact <a href="mailto:felker@google.com">Nick Felker</a>.
+            </p>
+            <p>
+                Copyright Google Inc. 2019. Published under Apache-2.0 license.
+            </p>
+            <p>
+                Peripheral version 0.1.0 using Cyanobyte v0.1.0.
+            </p>
+        </footer>
+    </body>
+</html>
\ No newline at end of file
diff --git a/test/sampleData/webpage/LSM303D.html b/test/sampleData/webpage/LSM303D.html
new file mode 100644
index 0000000..a98034b
--- /dev/null
+++ b/test/sampleData/webpage/LSM303D.html
@@ -0,0 +1,271 @@
+
+<html>
+    <head>
+        <title>LSM303D</title>
+    </head>
+    <body>
+        <style>
+            body {
+                font-family: sans-serif;
+                background-color: #efefef;
+            }
+            section.registers {
+                background-color: white;
+                box-shadow: 1px 1px 1px black;
+                border-radius: 4px;
+            }
+            section.registers table {
+                width: 100%;
+                border-style: solid;
+            }
+            section.registers td {
+                text-align: center;
+                vertical-align: middle;
+                border-style: solid;
+            }
+            section.registers td h1 {
+                font-size: 11pt;
+                margin-block: unset;
+                margin-bottom: 8px;
+            }
+            section.registers td h2 {
+                font-size: 10pt;
+                color: #333;
+                margin-block: unset;
+                font-weight: normal;
+                margin-bottom: 8px;
+            }
+            section.registers td h3 {
+                font-size: 9pt;
+                color: #555;
+                margin-block: unset;
+                font-weight: normal;
+            }
+            footer {
+                opacity: 0.75;
+                font-size: 9pt;
+            }
+        </style>
+        <h1>LSM303D</h1>
+        <section class="description">
+            <p>
+                STMicroelectronics accelerometer and magnetometer
+            </p>
+            <ul>
+            <li>Device address 29</li>
+            <li>Address type 7-bit</li>
+            </ul>
+        </section>
+        <section class="registers">
+            <table>
+                <tbody>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="12.5%">
+                            <h3>
+                                Addr 136 <br><br>
+                                8-bytes <br>
+                                    <br><em>Read-only</em>
+                            </h3>
+                        </td>
+                        <td colspan="8" width="87.5%">
+                            <h1>Magnetometer X</h1>
+                            <h2>Raw magnetometer data on X plane</h2>
+                        </td>
+                    </tr>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="12.5%">
+                            <h3>
+                                Addr 137 <br><br>
+                                8-bytes <br>
+                                    <br><em>Read-only</em>
+                            </h3>
+                        </td>
+                        <td colspan="8" width="87.5%">
+                            <h1>Magnetometer X</h1>
+                            <h2>Raw magnetometer data on X plane</h2>
+                        </td>
+                    </tr>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="12.5%">
+                            <h3>
+                                Addr 138 <br><br>
+                                8-bytes <br>
+                                    <br><em>Read-only</em>
+                            </h3>
+                        </td>
+                        <td colspan="8" width="87.5%">
+                            <h1>Magnetometer Y</h1>
+                            <h2>Raw magnetometer data on Y plane</h2>
+                        </td>
+                    </tr>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="12.5%">
+                            <h3>
+                                Addr 139 <br><br>
+                                8-bytes <br>
+                                    <br><em>Read-only</em>
+                            </h3>
+                        </td>
+                        <td colspan="8" width="87.5%">
+                            <h1>Magnetometer Y</h1>
+                            <h2>Raw magnetometer data on Y plane</h2>
+                        </td>
+                    </tr>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="12.5%">
+                            <h3>
+                                Addr 140 <br><br>
+                                8-bytes <br>
+                                    <br><em>Read-only</em>
+                            </h3>
+                        </td>
+                        <td colspan="8" width="87.5%">
+                            <h1>Magnetometer Z</h1>
+                            <h2>Raw magnetometer data on Z plane</h2>
+                        </td>
+                    </tr>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="12.5%">
+                            <h3>
+                                Addr 141 <br><br>
+                                8-bytes <br>
+                                    <br><em>Read-only</em>
+                            </h3>
+                        </td>
+                        <td colspan="8" width="87.5%">
+                            <h1>Magnetometer Z</h1>
+                            <h2>Raw magnetometer data on Z plane</h2>
+                        </td>
+                    </tr>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="12.5%">
+                            <h3>
+                                Addr 168 <br><br>
+                                8-bytes <br>
+                                    <br><em>Read-only</em>
+                            </h3>
+                        </td>
+                        <td colspan="8" width="87.5%">
+                            <h1>Accelerometer X</h1>
+                            <h2>Raw accelerometer data on X plane</h2>
+                        </td>
+                    </tr>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="12.5%">
+                            <h3>
+                                Addr 169 <br><br>
+                                8-bytes <br>
+                                    <br><em>Read-only</em>
+                            </h3>
+                        </td>
+                        <td colspan="8" width="87.5%">
+                            <h1>Accelerometer X</h1>
+                            <h2>Raw accelerometer data on X plane</h2>
+                        </td>
+                    </tr>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="12.5%">
+                            <h3>
+                                Addr 170 <br><br>
+                                8-bytes <br>
+                                    <br><em>Read-only</em>
+                            </h3>
+                        </td>
+                        <td colspan="8" width="87.5%">
+                            <h1>Accelerometer Y</h1>
+                            <h2>Raw accelerometer data on Y plane</h2>
+                        </td>
+                    </tr>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="12.5%">
+                            <h3>
+                                Addr 171 <br><br>
+                                8-bytes <br>
+                                    <br><em>Read-only</em>
+                            </h3>
+                        </td>
+                        <td colspan="8" width="87.5%">
+                            <h1>Accelerometer Y</h1>
+                            <h2>Raw accelerometer data on Y plane</h2>
+                        </td>
+                    </tr>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="12.5%">
+                            <h3>
+                                Addr 172 <br><br>
+                                8-bytes <br>
+                                    <br><em>Read-only</em>
+                            </h3>
+                        </td>
+                        <td colspan="8" width="87.5%">
+                            <h1>Accelerometer Z</h1>
+                            <h2>Raw accelerometer data on Z plane</h2>
+                        </td>
+                    </tr>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="12.5%">
+                            <h3>
+                                Addr 173 <br><br>
+                                8-bytes <br>
+                                    <br><em>Read-only</em>
+                            </h3>
+                        </td>
+                        <td colspan="8" width="87.5%">
+                            <h1>Accelerometer Z</h1>
+                            <h2>Raw accelerometer data on Z plane</h2>
+                        </td>
+                    </tr>
+                </tbody>
+            </table>
+        </section>
+        <section class="functions">
+            <h2>Functions</h2>
+            <ul>
+                <li>
+                    <b>acceleration.asG</b> -
+                    Measures the current acceleration
+                </li>
+                <li>
+                    <b>acceleration.xPlane</b> -
+                    Measures the current acceleration
+                </li>
+                <li>
+                    <b>acceleration.yPlane</b> -
+                    Measures the current acceleration
+                </li>
+                <li>
+                    <b>acceleration.zPlane</b> -
+                    Measures the current acceleration
+                </li>
+                <li>
+                    <b>orientation.heading</b> -
+                    Reads the magnetic orientation
+                </li>
+                <li>
+                    <b>orientation.xPlane</b> -
+                    Reads the magnetic orientation
+                </li>
+                <li>
+                    <b>orientation.yPlane</b> -
+                    Reads the magnetic orientation
+                </li>
+                <li>
+                    <b>orientation.zPlane</b> -
+                    Reads the magnetic orientation
+                </li>
+            </ul>
+        </section>
+        <hr>
+        <footer>
+            <p>
+                Contact <a href="mailto:felker@google.com">Nick Felker</a>.
+            </p>
+            <p>
+                Copyright Google Inc. 2019. Published under Apache-2.0 license.
+            </p>
+            <p>
+                Peripheral version 0.1.0 using Cyanobyte v0.1.0.
+            </p>
+        </footer>
+    </body>
+</html>
\ No newline at end of file
diff --git a/test/sampleData/webpage/MCP4725.html b/test/sampleData/webpage/MCP4725.html
new file mode 100644
index 0000000..2c7a5b3
--- /dev/null
+++ b/test/sampleData/webpage/MCP4725.html
@@ -0,0 +1,124 @@
+
+
+<html>
+    <head>
+        <title>MCP4725</title>
+    </head>
+    <body>
+        <style>
+            body {
+                font-family: sans-serif;
+                background-color: #efefef;
+            }
+            section.registers {
+                background-color: white;
+                box-shadow: 1px 1px 1px black;
+                border-radius: 4px;
+            }
+            section.registers table {
+                width: 100%;
+                border-style: solid;
+            }
+            section.registers td {
+                text-align: center;
+                vertical-align: middle;
+                border-style: solid;
+            }
+            section.registers td h1 {
+                font-size: 11pt;
+                margin-block: unset;
+                margin-bottom: 8px;
+            }
+            section.registers td h2 {
+                font-size: 10pt;
+                color: #333;
+                margin-block: unset;
+                font-weight: normal;
+                margin-bottom: 8px;
+            }
+            section.registers td h3 {
+                font-size: 9pt;
+                color: #555;
+                margin-block: unset;
+                font-weight: normal;
+            }
+            footer {
+                opacity: 0.75;
+                font-size: 9pt;
+            }
+        </style>
+        <h1>MCP4725</h1>
+        <section class="description">
+            <p>
+                Microchip 4725 Digital-to-Analog Converter
+            </p>
+            <ul>
+            <li>Device address 98</li>
+            <li>Address type 7-bit</li>
+            <li>Little Endian</li>
+            </ul>
+        </section>
+        <section class="registers">
+            <table>
+                <tbody>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="8.333333333333332%">
+                            <h3>
+                                Addr 64 <br><br>
+                                12-bytes <br>
+                            </h3>
+                        </td>
+                        <td colspan="12" width="91.66666666666666%">
+                            <h1>Output voltage</h1>
+                            <h2>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.
+</h2>
+                        </td>
+                    </tr>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="8.333333333333332%">
+                            <h3>
+                                Addr 96 <br><br>
+                                12-bytes <br>
+                            </h3>
+                        </td>
+                        <td colspan="13" width="108.33333333333333%">
+                            <h1>Digital (binary) output</h1>
+                            <h2>Only allows you to send fully on or off
+</h2>
+                            <h3>
+                                [12:0] | 13-bytes                            </h3>
+                        </td>
+                    </tr>
+                </tbody>
+            </table>
+        </section>
+        <section class="functions">
+            <h2>Functions</h2>
+            <ul>
+                <li>
+                    <b>getVOut.asVoltage</b> -
+                    get vout
+                </li>
+                <li>
+                    <b>setVOut.asVoltage</b> -
+                    set vout
+                </li>
+            </ul>
+        </section>
+        <hr>
+        <footer>
+            <p>
+                Contact <a href="mailto:felker@google.com">Nick Felker, Chris Frederickson</a>.
+            </p>
+            <p>
+                Copyright Google Inc. 2019. Published under Apache-2.0 license.
+            </p>
+            <p>
+                Peripheral version 0.1.0 using Cyanobyte v0.1.0.
+            </p>
+        </footer>
+    </body>
+</html>
\ No newline at end of file
diff --git a/test/sampleData/webpage/MCP9808.html b/test/sampleData/webpage/MCP9808.html
new file mode 100644
index 0000000..ac377a4
--- /dev/null
+++ b/test/sampleData/webpage/MCP9808.html
@@ -0,0 +1,117 @@
+
+
+<html>
+    <head>
+        <title>MCP9808</title>
+    </head>
+    <body>
+        <style>
+            body {
+                font-family: sans-serif;
+                background-color: #efefef;
+            }
+            section.registers {
+                background-color: white;
+                box-shadow: 1px 1px 1px black;
+                border-radius: 4px;
+            }
+            section.registers table {
+                width: 100%;
+                border-style: solid;
+            }
+            section.registers td {
+                text-align: center;
+                vertical-align: middle;
+                border-style: solid;
+            }
+            section.registers td h1 {
+                font-size: 11pt;
+                margin-block: unset;
+                margin-bottom: 8px;
+            }
+            section.registers td h2 {
+                font-size: 10pt;
+                color: #333;
+                margin-block: unset;
+                font-weight: normal;
+                margin-bottom: 8px;
+            }
+            section.registers td h3 {
+                font-size: 9pt;
+                color: #555;
+                margin-block: unset;
+                font-weight: normal;
+            }
+            footer {
+                opacity: 0.75;
+                font-size: 9pt;
+            }
+        </style>
+        <h1>MCP9808</h1>
+        <section class="description">
+            <p>
+                This is a test description
+            </p>
+            <ul>
+            <li>Device addresses:
+            24,
+            25,
+            26,
+            27,
+            28,
+            29,
+            30,
+            31
+            </li>
+            <li>Address type 7-bit</li>
+            </ul>
+        </section>
+        <section class="registers">
+            <table>
+                <tbody>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="6.25%">
+                            <h3>
+                                Addr 1 <br><br>
+                                16-bytes <br>
+                            </h3>
+                        </td>
+                        <td colspan="2" width="12.5%">
+                            <h1>TUPPER and TLOWER Limit Hysteresis bits</h1>
+                            <h2>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.
+</h2>
+                            <h3>
+                                [10:9] | 2-bytes                                <br><em>Read-only</em>
+                            </h3>
+                        </td>
+                        <td colspan="1" width="6.25%">
+                            <h1>Shutdown Mode bit</h1>
+                            <h2>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.
+</h2>
+                            <h3>
+                                [8:8] | 1-byte                                <br><em>Read-only</em>
+                            </h3>
+                        </td>
+                    </tr>
+                </tbody>
+            </table>
+        </section>
+        <hr>
+        <footer>
+            <p>
+                Contact <a href="mailto:joe@example.com">Joe Smith</a>.
+            </p>
+            <p>
+                Copyright Google Inc. 2019. Published under Apache-2.0 license.
+            </p>
+            <p>
+                Peripheral version 0.1.0 using Cyanobyte v0.1.0.
+            </p>
+        </footer>
+    </body>
+</html>
\ No newline at end of file
diff --git a/test/sampleData/webpage/TCS3472.html b/test/sampleData/webpage/TCS3472.html
new file mode 100644
index 0000000..9535844
--- /dev/null
+++ b/test/sampleData/webpage/TCS3472.html
@@ -0,0 +1,154 @@
+
+
+<html>
+    <head>
+        <title>TCS3472</title>
+    </head>
+    <body>
+        <style>
+            body {
+                font-family: sans-serif;
+                background-color: #efefef;
+            }
+            section.registers {
+                background-color: white;
+                box-shadow: 1px 1px 1px black;
+                border-radius: 4px;
+            }
+            section.registers table {
+                width: 100%;
+                border-style: solid;
+            }
+            section.registers td {
+                text-align: center;
+                vertical-align: middle;
+                border-style: solid;
+            }
+            section.registers td h1 {
+                font-size: 11pt;
+                margin-block: unset;
+                margin-bottom: 8px;
+            }
+            section.registers td h2 {
+                font-size: 10pt;
+                color: #333;
+                margin-block: unset;
+                font-weight: normal;
+                margin-bottom: 8px;
+            }
+            section.registers td h3 {
+                font-size: 9pt;
+                color: #555;
+                margin-block: unset;
+                font-weight: normal;
+            }
+            footer {
+                opacity: 0.75;
+                font-size: 9pt;
+            }
+        </style>
+        <h1>TCS3472</h1>
+        <section class="description">
+            <p>
+                Color Light-to-Digital Converter with IR Filter
+            </p>
+            <ul>
+            <li>Device address 41</li>
+            <li>Address type 7-bit</li>
+            </ul>
+        </section>
+        <section class="registers">
+            <table>
+                <tbody>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="6.25%">
+                            <h3>
+                                Addr 128 <br><br>
+                                8-bytes <br>
+                            </h3>
+                        </td>
+                        <td colspan="8" width="50.0%">
+                            <h1>Setup the device configuration</h1>
+                            <h2>Enable RGBC and Power</h2>
+                            <h3>
+                                [7:0] | 8-bytes                            </h3>
+                        </td>
+                    </tr>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="6.25%">
+                            <h3>
+                                Addr 180 <br><br>
+                                16-bytes <br>
+                                    <br><em>Read-only</em>
+                            </h3>
+                        </td>
+                        <td colspan="16" width="93.75%">
+                            <h1>Clear channel</h1>
+                            <h2>This is the ambient amount of detected light.</h2>
+                        </td>
+                    </tr>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="6.25%">
+                            <h3>
+                                Addr 182 <br><br>
+                                16-bytes <br>
+                                    <br><em>Read-only</em>
+                            </h3>
+                        </td>
+                        <td colspan="16" width="93.75%">
+                            <h1>Red channel</h1>
+                            <h2>Red light as an int. Divide by ambient light to get scaled number.</h2>
+                        </td>
+                    </tr>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="6.25%">
+                            <h3>
+                                Addr 184 <br><br>
+                                16-bytes <br>
+                                    <br><em>Read-only</em>
+                            </h3>
+                        </td>
+                        <td colspan="16" width="93.75%">
+                            <h1>Green channel</h1>
+                            <h2>Green light as an int. Divide by ambient light to get scaled number.</h2>
+                        </td>
+                    </tr>
+                    <tr aria-colspan="32">
+                        <td colspan="1" width="6.25%">
+                            <h3>
+                                Addr 186 <br><br>
+                                16-bytes <br>
+                                    <br><em>Read-only</em>
+                            </h3>
+                        </td>
+                        <td colspan="16" width="93.75%">
+                            <h1>Blue channel</h1>
+                            <h2>Blue light as an int. Divide by ambient light to get scaled number.</h2>
+                        </td>
+                    </tr>
+                </tbody>
+            </table>
+        </section>
+        <section class="functions">
+            <h2>Functions</h2>
+            <ul>
+                <li>
+                    <b>_lifecycle.Begin</b> -
+                    Enables features on device
+                </li>
+            </ul>
+        </section>
+        <hr>
+        <footer>
+            <p>
+                Contact <a href="mailto:felker@google.com">Nick Felker</a>.
+            </p>
+            <p>
+                Copyright Google Inc. 2019. Published under Apache-2.0 license.
+            </p>
+            <p>
+                Peripheral version 0.1.0 using Cyanobyte v0.1.0.
+            </p>
+        </footer>
+    </body>
+</html>
\ No newline at end of file
diff --git a/test/test_codegen.py b/test/test_codegen.py
index aaeb010..f963638 100644
--- a/test/test_codegen.py
+++ b/test/test_codegen.py
@@ -211,6 +211,12 @@ def test_rpi_emboss(self):
                     msg="{0} and {1} are not the same".format(test_path, tmp_path)
                 )
 
+    def test_webpage(self):
+        """
+        Verify output of webpage template.
+        """
+        self.gen_peripheral_tag('webpage')
+        self.compare_files('webpage', 'html')
 
 if __name__ == '__main__':
     unittest.main()