<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://stm32world.com/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Niclas</id>
	<title>Stm32World Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://stm32world.com/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Niclas"/>
	<link rel="alternate" type="text/html" href="https://stm32world.com/wiki/Special:Contributions/Niclas"/>
	<updated>2026-06-21T21:09:33Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.35.0</generator>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Colibri_AQV&amp;diff=7605</id>
		<title>Colibri AQV</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Colibri_AQV&amp;diff=7605"/>
		<updated>2026-05-25T20:16:08Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* Test Report */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Colibri]]{{metadesc|Colibri AQV module}}&lt;br /&gt;
[[File:colibri_aqv-RevA-front3d.png|180px|thumb]]&lt;br /&gt;
[[File:colibri_aqv-RevA-back3d.png|180px|thumb]]&lt;br /&gt;
&lt;br /&gt;
Colibri AQV is an expansion module with two Analog 0-10 volt Outputs. &lt;br /&gt;
&lt;br /&gt;
MCP4725 is the 12 bit D/A converter used.&lt;br /&gt;
&lt;br /&gt;
=== I2C Addresses === &lt;br /&gt;
  M24M01  = 0x50-0x51&lt;br /&gt;
  MCP4725 = 0x60, 0x61&lt;br /&gt;
&lt;br /&gt;
= EEPROM factory layout =&lt;br /&gt;
&lt;br /&gt;
See the [[Colibri EEPROM Layout]] page for the full picture.&lt;br /&gt;
&lt;br /&gt;
== Calibration data in EEPROM ==&lt;br /&gt;
Work in progress. Not available in product if ordered now.&lt;br /&gt;
&lt;br /&gt;
{| class=wikitable&lt;br /&gt;
|-&lt;br /&gt;
! Address&lt;br /&gt;
! Length&lt;br /&gt;
! Description &lt;br /&gt;
|-&lt;br /&gt;
| 0x0080&lt;br /&gt;
| 4&lt;br /&gt;
| k-factor for AQ1&lt;br /&gt;
|-&lt;br /&gt;
| 0x0084&lt;br /&gt;
| 4&lt;br /&gt;
| m-offset for AQ1&lt;br /&gt;
|-&lt;br /&gt;
| 0x0088&lt;br /&gt;
| 4&lt;br /&gt;
| k-factor for AQ2&lt;br /&gt;
|-&lt;br /&gt;
| 0x008c&lt;br /&gt;
| 4&lt;br /&gt;
| m-offset for AQ2&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Test Report ==&lt;br /&gt;
Work in progress. Not available in product if ordered now.&lt;br /&gt;
&lt;br /&gt;
{| class=wikitable&lt;br /&gt;
|-&lt;br /&gt;
! Address&lt;br /&gt;
! Length&lt;br /&gt;
! Description &lt;br /&gt;
|-&lt;br /&gt;
| 0x0100&lt;br /&gt;
| 4&lt;br /&gt;
| Year * 12 + month&lt;br /&gt;
|-&lt;br /&gt;
| 0x0104&lt;br /&gt;
| 4&lt;br /&gt;
| Date * 24 + hour&lt;br /&gt;
|-&lt;br /&gt;
| 0x0108&lt;br /&gt;
| 8&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0110&lt;br /&gt;
| 4&lt;br /&gt;
| EEPROM write/read/erase test. 32 cycles. Each cycle is represented in one bit. 0=Success, 1=Fail.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0114&lt;br /&gt;
| 4&lt;br /&gt;
| Calibration parameters written to EEPROM. 0xffff=fail, 0x0=success&lt;br /&gt;
|-&lt;br /&gt;
| 0x0118&lt;br /&gt;
| 4&lt;br /&gt;
| zeptoforth program written to EEPROM. 0xffff=fail, Bytes written otherwise.&lt;br /&gt;
|-&lt;br /&gt;
| 0x011c&lt;br /&gt;
| 4&lt;br /&gt;
| WebAssembly program written to EEPROM. 0xffff=fail, Bytes written otherwise.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0120&lt;br /&gt;
| 32&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0140&lt;br /&gt;
| 4&lt;br /&gt;
| Set 0xFF0 to the DAC on AQ1. Measured value on terminal is written to this position, or 0xFFFF if test failed.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0144&lt;br /&gt;
| 4&lt;br /&gt;
| Set 0x800 to the DAC on AQ1. Measured value on terminal is written to this position, or 0xFFFF if test failed.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0148&lt;br /&gt;
| 4&lt;br /&gt;
| Set 0x010 to the DAC on AQ1. Measured value on terminal is written to this position, or 0xFFFF if test failed.&lt;br /&gt;
|-&lt;br /&gt;
| 0x014c&lt;br /&gt;
| 4&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0150&lt;br /&gt;
| 4&lt;br /&gt;
| Set 0xFF0 to the DAC on AQ2. Measured value on terminal is written to this position, or 0xFFFF if test failed.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0154&lt;br /&gt;
| 4&lt;br /&gt;
| Set 0x800 to the DAC on AQ2. Measured value on terminal is written to this position, or 0xFFFF if test failed.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0158&lt;br /&gt;
| 4&lt;br /&gt;
| Set 0x010 to the DAC on AQ2. Measured value on terminal is written to this position, or 0xFFFF if test failed.&lt;br /&gt;
|-&lt;br /&gt;
| 0x015c&lt;br /&gt;
| 4&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Documentation =&lt;br /&gt;
* [[File:Colibri aqv-RevA-schematics.pdf|thumb]]&lt;br /&gt;
* [[File:Colibri aqv-RevA-pcb.pdf|thumb]]&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Colibri_AQV&amp;diff=7604</id>
		<title>Colibri AQV</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Colibri_AQV&amp;diff=7604"/>
		<updated>2026-05-25T20:16:02Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* Calibration data in EEPROM */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Colibri]]{{metadesc|Colibri AQV module}}&lt;br /&gt;
[[File:colibri_aqv-RevA-front3d.png|180px|thumb]]&lt;br /&gt;
[[File:colibri_aqv-RevA-back3d.png|180px|thumb]]&lt;br /&gt;
&lt;br /&gt;
Colibri AQV is an expansion module with two Analog 0-10 volt Outputs. &lt;br /&gt;
&lt;br /&gt;
MCP4725 is the 12 bit D/A converter used.&lt;br /&gt;
&lt;br /&gt;
=== I2C Addresses === &lt;br /&gt;
  M24M01  = 0x50-0x51&lt;br /&gt;
  MCP4725 = 0x60, 0x61&lt;br /&gt;
&lt;br /&gt;
= EEPROM factory layout =&lt;br /&gt;
&lt;br /&gt;
See the [[Colibri EEPROM Layout]] page for the full picture.&lt;br /&gt;
&lt;br /&gt;
== Calibration data in EEPROM ==&lt;br /&gt;
Work in progress. Not available in product if ordered now.&lt;br /&gt;
&lt;br /&gt;
{| class=wikitable&lt;br /&gt;
|-&lt;br /&gt;
! Address&lt;br /&gt;
! Length&lt;br /&gt;
! Description &lt;br /&gt;
|-&lt;br /&gt;
| 0x0080&lt;br /&gt;
| 4&lt;br /&gt;
| k-factor for AQ1&lt;br /&gt;
|-&lt;br /&gt;
| 0x0084&lt;br /&gt;
| 4&lt;br /&gt;
| m-offset for AQ1&lt;br /&gt;
|-&lt;br /&gt;
| 0x0088&lt;br /&gt;
| 4&lt;br /&gt;
| k-factor for AQ2&lt;br /&gt;
|-&lt;br /&gt;
| 0x008c&lt;br /&gt;
| 4&lt;br /&gt;
| m-offset for AQ2&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Test Report ==&lt;br /&gt;
{| class=wikitable&lt;br /&gt;
|-&lt;br /&gt;
! Address&lt;br /&gt;
! Length&lt;br /&gt;
! Description &lt;br /&gt;
|-&lt;br /&gt;
| 0x0100&lt;br /&gt;
| 4&lt;br /&gt;
| Year * 12 + month&lt;br /&gt;
|-&lt;br /&gt;
| 0x0104&lt;br /&gt;
| 4&lt;br /&gt;
| Date * 24 + hour&lt;br /&gt;
|-&lt;br /&gt;
| 0x0108&lt;br /&gt;
| 8&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0110&lt;br /&gt;
| 4&lt;br /&gt;
| EEPROM write/read/erase test. 32 cycles. Each cycle is represented in one bit. 0=Success, 1=Fail.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0114&lt;br /&gt;
| 4&lt;br /&gt;
| Calibration parameters written to EEPROM. 0xffff=fail, 0x0=success&lt;br /&gt;
|-&lt;br /&gt;
| 0x0118&lt;br /&gt;
| 4&lt;br /&gt;
| zeptoforth program written to EEPROM. 0xffff=fail, Bytes written otherwise.&lt;br /&gt;
|-&lt;br /&gt;
| 0x011c&lt;br /&gt;
| 4&lt;br /&gt;
| WebAssembly program written to EEPROM. 0xffff=fail, Bytes written otherwise.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0120&lt;br /&gt;
| 32&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0140&lt;br /&gt;
| 4&lt;br /&gt;
| Set 0xFF0 to the DAC on AQ1. Measured value on terminal is written to this position, or 0xFFFF if test failed.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0144&lt;br /&gt;
| 4&lt;br /&gt;
| Set 0x800 to the DAC on AQ1. Measured value on terminal is written to this position, or 0xFFFF if test failed.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0148&lt;br /&gt;
| 4&lt;br /&gt;
| Set 0x010 to the DAC on AQ1. Measured value on terminal is written to this position, or 0xFFFF if test failed.&lt;br /&gt;
|-&lt;br /&gt;
| 0x014c&lt;br /&gt;
| 4&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0150&lt;br /&gt;
| 4&lt;br /&gt;
| Set 0xFF0 to the DAC on AQ2. Measured value on terminal is written to this position, or 0xFFFF if test failed.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0154&lt;br /&gt;
| 4&lt;br /&gt;
| Set 0x800 to the DAC on AQ2. Measured value on terminal is written to this position, or 0xFFFF if test failed.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0158&lt;br /&gt;
| 4&lt;br /&gt;
| Set 0x010 to the DAC on AQ2. Measured value on terminal is written to this position, or 0xFFFF if test failed.&lt;br /&gt;
|-&lt;br /&gt;
| 0x015c&lt;br /&gt;
| 4&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Documentation =&lt;br /&gt;
* [[File:Colibri aqv-RevA-schematics.pdf|thumb]]&lt;br /&gt;
* [[File:Colibri aqv-RevA-pcb.pdf|thumb]]&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Colibri_AIV&amp;diff=7603</id>
		<title>Colibri AIV</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Colibri_AIV&amp;diff=7603"/>
		<updated>2026-05-25T20:15:49Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* Test Report */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Colibri]]{{metadesc|Colibri AIV module}}&lt;br /&gt;
[[File:Colibri aiv-RevA-2.jpg|180px|thumb]]&lt;br /&gt;
[[File:Colibri aiv-RevA-1.jpg|180px|thumb]]&lt;br /&gt;
&lt;br /&gt;
Colibri AIV is an expansion module with two Analog 0-10 volt Inputs.&lt;br /&gt;
&lt;br /&gt;
ADS1115 is the A/D converter used, which is 16 bits and max sampling rate of 860 samples/second.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== I2C Addresses === &lt;br /&gt;
  M24M01  = 0x50-0x51&lt;br /&gt;
  ADS1115 = 0x48&lt;br /&gt;
&lt;br /&gt;
= EEPROM factory layout =&lt;br /&gt;
&lt;br /&gt;
See the [[Colibri EEPROM Layout]] page for the full picture.&lt;br /&gt;
&lt;br /&gt;
== Calibration data in EEPROM ==&lt;br /&gt;
Work in progress. Not available in product if ordered now.&lt;br /&gt;
&lt;br /&gt;
{| class=wikitable&lt;br /&gt;
|-&lt;br /&gt;
! Address&lt;br /&gt;
! Length&lt;br /&gt;
! Description &lt;br /&gt;
|-&lt;br /&gt;
| 0x0080&lt;br /&gt;
| 4&lt;br /&gt;
| k-factor for AI1&lt;br /&gt;
|-&lt;br /&gt;
| 0x0084&lt;br /&gt;
| 4&lt;br /&gt;
| m-offset for AI1&lt;br /&gt;
|-&lt;br /&gt;
| 0x0088&lt;br /&gt;
| 4&lt;br /&gt;
| k-factor for AI2&lt;br /&gt;
|-&lt;br /&gt;
| 0x008c&lt;br /&gt;
| 4&lt;br /&gt;
| m-offset for AI2&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Test Report ==&lt;br /&gt;
Work in progress. Not available in product if ordered now.&lt;br /&gt;
&lt;br /&gt;
{| class=wikitable&lt;br /&gt;
|-&lt;br /&gt;
! Address&lt;br /&gt;
! Length&lt;br /&gt;
! Description &lt;br /&gt;
|-&lt;br /&gt;
| 0x0100&lt;br /&gt;
| 4&lt;br /&gt;
| Year * 12 + month&lt;br /&gt;
|-&lt;br /&gt;
| 0x0104&lt;br /&gt;
| 4&lt;br /&gt;
| Date * 24 + hour&lt;br /&gt;
|-&lt;br /&gt;
| 0x0108&lt;br /&gt;
| 8&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0110&lt;br /&gt;
| 4&lt;br /&gt;
| EEPROM write/read/erase test. 32 cycles. Each cycle is represented in one bit. 0=Success, 1=Fail.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0114&lt;br /&gt;
| 4&lt;br /&gt;
| Calibration parameters written to EEPROM. 0xffff=fail, 0x0=success&lt;br /&gt;
|-&lt;br /&gt;
| 0x0118&lt;br /&gt;
| 4&lt;br /&gt;
| zeptoforth program written to EEPROM. 0xffff=fail, Bytes written otherwise.&lt;br /&gt;
|-&lt;br /&gt;
| 0x011c&lt;br /&gt;
| 4&lt;br /&gt;
| WebAssembly program written to EEPROM. 0xffff=fail, Bytes written otherwise.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0120&lt;br /&gt;
| 32&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0140&lt;br /&gt;
| 4&lt;br /&gt;
| Apply 10V input on AI1, check for within 5%, write raw value to this position, or 0xFFFF if fails.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0144&lt;br /&gt;
| 4&lt;br /&gt;
| Apply 5V input on AI1, check for within 5%, write raw value to this position, or 0xFFFF if fails.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0148&lt;br /&gt;
| 4&lt;br /&gt;
| Apply 0.1V input on AI1, check for within 5%, write raw value to this position, or 0xFFFF if fails.&lt;br /&gt;
|-&lt;br /&gt;
| 0x014c&lt;br /&gt;
| 4&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0150&lt;br /&gt;
| 4&lt;br /&gt;
| Apply 10V input on AI2, check for within 5%, write raw value to this position, or 0xFFFF if fails.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0154&lt;br /&gt;
| 4&lt;br /&gt;
| Apply 5V input on AI2, check for within 5%, write raw value to this position, or 0xFFFF if fails.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0158&lt;br /&gt;
| 4&lt;br /&gt;
| Apply 0.1V input on AI2, check for within 5%, write raw value to this position, or 0xFFFF if fails.&lt;br /&gt;
|-&lt;br /&gt;
| 0x015c&lt;br /&gt;
| 4&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Documentation ==&lt;br /&gt;
* [[:File:colibri_aiv-RevA-schematics.pdf]]&lt;br /&gt;
* [[:File:colibri_aiv-RevA-pcb.pdf]]&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Colibri_AIV&amp;diff=7602</id>
		<title>Colibri AIV</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Colibri_AIV&amp;diff=7602"/>
		<updated>2026-05-25T20:15:41Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* Calibration data in EEPROM */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Colibri]]{{metadesc|Colibri AIV module}}&lt;br /&gt;
[[File:Colibri aiv-RevA-2.jpg|180px|thumb]]&lt;br /&gt;
[[File:Colibri aiv-RevA-1.jpg|180px|thumb]]&lt;br /&gt;
&lt;br /&gt;
Colibri AIV is an expansion module with two Analog 0-10 volt Inputs.&lt;br /&gt;
&lt;br /&gt;
ADS1115 is the A/D converter used, which is 16 bits and max sampling rate of 860 samples/second.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== I2C Addresses === &lt;br /&gt;
  M24M01  = 0x50-0x51&lt;br /&gt;
  ADS1115 = 0x48&lt;br /&gt;
&lt;br /&gt;
= EEPROM factory layout =&lt;br /&gt;
&lt;br /&gt;
See the [[Colibri EEPROM Layout]] page for the full picture.&lt;br /&gt;
&lt;br /&gt;
== Calibration data in EEPROM ==&lt;br /&gt;
Work in progress. Not available in product if ordered now.&lt;br /&gt;
&lt;br /&gt;
{| class=wikitable&lt;br /&gt;
|-&lt;br /&gt;
! Address&lt;br /&gt;
! Length&lt;br /&gt;
! Description &lt;br /&gt;
|-&lt;br /&gt;
| 0x0080&lt;br /&gt;
| 4&lt;br /&gt;
| k-factor for AI1&lt;br /&gt;
|-&lt;br /&gt;
| 0x0084&lt;br /&gt;
| 4&lt;br /&gt;
| m-offset for AI1&lt;br /&gt;
|-&lt;br /&gt;
| 0x0088&lt;br /&gt;
| 4&lt;br /&gt;
| k-factor for AI2&lt;br /&gt;
|-&lt;br /&gt;
| 0x008c&lt;br /&gt;
| 4&lt;br /&gt;
| m-offset for AI2&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Test Report ==&lt;br /&gt;
{| class=wikitable&lt;br /&gt;
|-&lt;br /&gt;
! Address&lt;br /&gt;
! Length&lt;br /&gt;
! Description &lt;br /&gt;
|-&lt;br /&gt;
| 0x0100&lt;br /&gt;
| 4&lt;br /&gt;
| Year * 12 + month&lt;br /&gt;
|-&lt;br /&gt;
| 0x0104&lt;br /&gt;
| 4&lt;br /&gt;
| Date * 24 + hour&lt;br /&gt;
|-&lt;br /&gt;
| 0x0108&lt;br /&gt;
| 8&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0110&lt;br /&gt;
| 4&lt;br /&gt;
| EEPROM write/read/erase test. 32 cycles. Each cycle is represented in one bit. 0=Success, 1=Fail.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0114&lt;br /&gt;
| 4&lt;br /&gt;
| Calibration parameters written to EEPROM. 0xffff=fail, 0x0=success&lt;br /&gt;
|-&lt;br /&gt;
| 0x0118&lt;br /&gt;
| 4&lt;br /&gt;
| zeptoforth program written to EEPROM. 0xffff=fail, Bytes written otherwise.&lt;br /&gt;
|-&lt;br /&gt;
| 0x011c&lt;br /&gt;
| 4&lt;br /&gt;
| WebAssembly program written to EEPROM. 0xffff=fail, Bytes written otherwise.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0120&lt;br /&gt;
| 32&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0140&lt;br /&gt;
| 4&lt;br /&gt;
| Apply 10V input on AI1, check for within 5%, write raw value to this position, or 0xFFFF if fails.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0144&lt;br /&gt;
| 4&lt;br /&gt;
| Apply 5V input on AI1, check for within 5%, write raw value to this position, or 0xFFFF if fails.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0148&lt;br /&gt;
| 4&lt;br /&gt;
| Apply 0.1V input on AI1, check for within 5%, write raw value to this position, or 0xFFFF if fails.&lt;br /&gt;
|-&lt;br /&gt;
| 0x014c&lt;br /&gt;
| 4&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0150&lt;br /&gt;
| 4&lt;br /&gt;
| Apply 10V input on AI2, check for within 5%, write raw value to this position, or 0xFFFF if fails.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0154&lt;br /&gt;
| 4&lt;br /&gt;
| Apply 5V input on AI2, check for within 5%, write raw value to this position, or 0xFFFF if fails.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0158&lt;br /&gt;
| 4&lt;br /&gt;
| Apply 0.1V input on AI2, check for within 5%, write raw value to this position, or 0xFFFF if fails.&lt;br /&gt;
|-&lt;br /&gt;
| 0x015c&lt;br /&gt;
| 4&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Documentation ==&lt;br /&gt;
* [[:File:colibri_aiv-RevA-schematics.pdf]]&lt;br /&gt;
* [[:File:colibri_aiv-RevA-pcb.pdf]]&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Colibri_Runtime&amp;diff=7584</id>
		<title>Colibri Runtime</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Colibri_Runtime&amp;diff=7584"/>
		<updated>2026-05-17T10:27:14Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* Example 2 - Toggle SSR in slot 5 output 1 at 1Hz and output 2 at 5Hz */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Colibri Runtime is the custom firmware that is running on Colibri MCUs, an application in [[Colibri Zephyr]] orchestrating the hardware resources, I/O drivers and Lua '''user scripts'''.&lt;br /&gt;
&lt;br /&gt;
Initially, a single Lua script is supported. But more might follow. &lt;br /&gt;
&lt;br /&gt;
== User Program Requirements ==&lt;br /&gt;
The user program/script MUST contain the following functions;&lt;br /&gt;
&lt;br /&gt;
== Limits in Lua ==&lt;br /&gt;
&lt;br /&gt;
== Host API ==&lt;br /&gt;
&lt;br /&gt;
  event(event_id, value)&lt;br /&gt;
  publish(event, value)&lt;br /&gt;
  subscribe(event_type, value)&lt;br /&gt;
  unsubscribe(event_type)&lt;br /&gt;
  &lt;br /&gt;
  is_type(event_id, event_type)&lt;br /&gt;
&lt;br /&gt;
Event Types&lt;br /&gt;
  TIME_PERIOD&lt;br /&gt;
  COUNTER&lt;br /&gt;
  ERROR_CODE&lt;br /&gt;
  MEASURED_VALUE&lt;br /&gt;
  COMPUTED_VALUE&lt;br /&gt;
  SETPOINT&lt;br /&gt;
  MIN_VALUE&lt;br /&gt;
  MAX_VALUE&lt;br /&gt;
  LOW_THRESHOLD&lt;br /&gt;
  HIGH_THRESHOLD&lt;br /&gt;
  RUN_INDICATION&lt;br /&gt;
  ALARM_INDICATION&lt;br /&gt;
  RGB_SET&lt;br /&gt;
&lt;br /&gt;
== Example 1 - Blinky ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
  -- do..end is called an &amp;quot;explicit lexical scope&amp;quot;, and needed to&lt;br /&gt;
  -- allow for so called &amp;quot;upvalues&amp;quot;, that is the variables in that scope&lt;br /&gt;
  -- which will persist over invocations from the system.&lt;br /&gt;
&lt;br /&gt;
  do&lt;br /&gt;
    local next=0&lt;br /&gt;
    local state=0&lt;br /&gt;
    local period_id&lt;br /&gt;
    &lt;br /&gt;
    -- local functions are not visible to the host system.&lt;br /&gt;
    local function tick(now)&lt;br /&gt;
      if next &amp;lt; now then&lt;br /&gt;
        -- publish() is the main way to interact with the system&lt;br /&gt;
        -- Event type RGB_SET is making a request to set the RGB LED to the color value&lt;br /&gt;
        -- in the second argument, and that value is equal to (r &amp;lt;&amp;lt; 16 | g &amp;lt;&amp;lt; 8 | b)&lt;br /&gt;
        -- Negative colors are predefined colors, currently;&lt;br /&gt;
        --   -1  OK       (typically Green)&lt;br /&gt;
        --   -2  WARNING  (typically Yellow)&lt;br /&gt;
        --   -3  ERROR    (typically Red)&lt;br /&gt;
        --   -4  INFO     (typically Cyan)&lt;br /&gt;
        publish( RGB_SET, -state)&lt;br /&gt;
        state = (state + 1) % 5&lt;br /&gt;
        next = now + 300&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    -- Called once after program has been loaded into memory.&lt;br /&gt;
    -- To be called periodically, subscription to a TIME_PERIOD&lt;br /&gt;
    -- event should be established.&lt;br /&gt;
    function init()&lt;br /&gt;
      period_id = subscribe(TIME_PERIOD, 250)&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    -- Entry point for all events. All interaction with the&lt;br /&gt;
    -- system and I/O subsystem are handled through events.&lt;br /&gt;
    -- This is to ensure future-compatibility, so that firmware&lt;br /&gt;
    -- doesn't need to be upgraded when new I/O modules are &lt;br /&gt;
    -- introduced.&lt;br /&gt;
    function event(event_id, value)&lt;br /&gt;
      if event_id == period_id then&lt;br /&gt;
        tick(value)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    -- terminating() is called just before the program is terminated &lt;br /&gt;
    -- and removed from memory&lt;br /&gt;
    function terminating()&lt;br /&gt;
      publish(RGB_SET, 0)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Example 2 - Toggle SSR in slot 5 output 1 at 1Hz and output 2 at 5Hz ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
  -- do..end is called an &amp;quot;explicit lexical scope&amp;quot;, and needed to&lt;br /&gt;
  -- allow for so called &amp;quot;upvalues&amp;quot;, that is the variables in that scope&lt;br /&gt;
  -- which will persist over invocations from the system.&lt;br /&gt;
&lt;br /&gt;
  do&lt;br /&gt;
    local state1 = 0&lt;br /&gt;
    local state2 = 0&lt;br /&gt;
    local counter1 = 0&lt;br /&gt;
    &lt;br /&gt;
    -- local functions are not visible to the host system.&lt;br /&gt;
    local function tick()&lt;br /&gt;
      -- publish to slot 5, channel 2, and the value&lt;br /&gt;
      publish( create_io( 5, 2, state2 ) )&lt;br /&gt;
      state2 = !state2&lt;br /&gt;
&lt;br /&gt;
      if counter1 = 0 then&lt;br /&gt;
        -- publish to slot 5, channel 1, and the value&lt;br /&gt;
        publish( create_io( 5,1, state1 ) )&lt;br /&gt;
        state1 = !state1&lt;br /&gt;
      end&lt;br /&gt;
      counter1 = ( counter1 + 1 ) % 5&lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    -- Called once after program has been loaded into memory.&lt;br /&gt;
    function init()&lt;br /&gt;
      -- request the 5Hz&lt;br /&gt;
      period_id = subscribe( TIME_PERIOD, 200 )&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    -- Entry point for all events. All interaction with the&lt;br /&gt;
    -- system and I/O subsystem are handled through events.&lt;br /&gt;
    -- This is to ensure future-compatibility, so that firmware&lt;br /&gt;
    -- doesn't need to be upgraded when new I/O modules are &lt;br /&gt;
    -- introduced.&lt;br /&gt;
    function event( event, value )&lt;br /&gt;
      if event_type( event ) == period_type then&lt;br /&gt;
        tick()&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    -- terminating() is called just before the program is terminated &lt;br /&gt;
    -- and removed from memory&lt;br /&gt;
    function terminating()&lt;br /&gt;
      publish( RGB_SET, 0 )&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Example 3 - Set Analog Output 1 in Slot 4 ==&lt;br /&gt;
&lt;br /&gt;
== Example 4 - Raise an Alarm condition ==&lt;br /&gt;
&lt;br /&gt;
== Example 5 - Get Analog Input 2 in slot 1 ==&lt;br /&gt;
&lt;br /&gt;
== Example  - Level check == &lt;br /&gt;
Check every minute if Analog Input 2 in slot 2 is &amp;gt;10mA, if so set SSR output 1, and if input &amp;lt; 5mA turn it off.&lt;br /&gt;
&lt;br /&gt;
== Example  - PID implementation in Lua ==&lt;br /&gt;
&lt;br /&gt;
== Example  - Interface Colibri PID1 ==&lt;br /&gt;
Colibri PID1 has a co-processor on the I/O module, which measures temperature on Pt1000 input and use PID algorithm to regulate that with Analog Output. The program in that I/O module is fixed, but it has a lot of parameters that can be set.&lt;br /&gt;
&lt;br /&gt;
  SetP - Setpoint in ˚C&lt;br /&gt;
  Cycle - Sample frequency in ms&lt;br /&gt;
  P - Proportional constant&lt;br /&gt;
  I - Integral time&lt;br /&gt;
  D - Derivative time&lt;br /&gt;
  MD - Max Derivative value&lt;br /&gt;
  Min - Minimum value, default 0&lt;br /&gt;
  Max - Maximum value, default 100&lt;br /&gt;
&lt;br /&gt;
It also reports both Input (in ˚C) and Output (in Max/Min values) on each Cycle, if cycle is slower than I/O subsystem update time (typ 10ms).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Historical =&lt;br /&gt;
The Colibri Runtime is the custom firmware that is running on Colibri MCUs, an application in [[Colibri Zephyr]] orchestrating the hardware resources, WebAssembly engines with I/O drivers and user programs.&lt;br /&gt;
&lt;br /&gt;
NOTE: running in individual WebAssembly instances turned out to be more stressful than useful, so that thread has been closed but kept on this Wiki for historical purposes.&lt;br /&gt;
&lt;br /&gt;
== Development == &lt;br /&gt;
[[Colibri EEPROM Layout]]&lt;br /&gt;
&lt;br /&gt;
[[Colibri WebAssembly Notes]]&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Colibri_Runtime&amp;diff=7583</id>
		<title>Colibri Runtime</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Colibri_Runtime&amp;diff=7583"/>
		<updated>2026-05-17T10:26:14Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* Example 2 - Toggle SSR in slot 5 output 1 at 1Hz and output 2 at 5Hz */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Colibri Runtime is the custom firmware that is running on Colibri MCUs, an application in [[Colibri Zephyr]] orchestrating the hardware resources, I/O drivers and Lua '''user scripts'''.&lt;br /&gt;
&lt;br /&gt;
Initially, a single Lua script is supported. But more might follow. &lt;br /&gt;
&lt;br /&gt;
== User Program Requirements ==&lt;br /&gt;
The user program/script MUST contain the following functions;&lt;br /&gt;
&lt;br /&gt;
== Limits in Lua ==&lt;br /&gt;
&lt;br /&gt;
== Host API ==&lt;br /&gt;
&lt;br /&gt;
  event(event_id, value)&lt;br /&gt;
  publish(event, value)&lt;br /&gt;
  subscribe(event_type, value)&lt;br /&gt;
  unsubscribe(event_type)&lt;br /&gt;
  &lt;br /&gt;
  is_type(event_id, event_type)&lt;br /&gt;
&lt;br /&gt;
Event Types&lt;br /&gt;
  TIME_PERIOD&lt;br /&gt;
  COUNTER&lt;br /&gt;
  ERROR_CODE&lt;br /&gt;
  MEASURED_VALUE&lt;br /&gt;
  COMPUTED_VALUE&lt;br /&gt;
  SETPOINT&lt;br /&gt;
  MIN_VALUE&lt;br /&gt;
  MAX_VALUE&lt;br /&gt;
  LOW_THRESHOLD&lt;br /&gt;
  HIGH_THRESHOLD&lt;br /&gt;
  RUN_INDICATION&lt;br /&gt;
  ALARM_INDICATION&lt;br /&gt;
  RGB_SET&lt;br /&gt;
&lt;br /&gt;
== Example 1 - Blinky ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
  -- do..end is called an &amp;quot;explicit lexical scope&amp;quot;, and needed to&lt;br /&gt;
  -- allow for so called &amp;quot;upvalues&amp;quot;, that is the variables in that scope&lt;br /&gt;
  -- which will persist over invocations from the system.&lt;br /&gt;
&lt;br /&gt;
  do&lt;br /&gt;
    local next=0&lt;br /&gt;
    local state=0&lt;br /&gt;
    local period_id&lt;br /&gt;
    &lt;br /&gt;
    -- local functions are not visible to the host system.&lt;br /&gt;
    local function tick(now)&lt;br /&gt;
      if next &amp;lt; now then&lt;br /&gt;
        -- publish() is the main way to interact with the system&lt;br /&gt;
        -- Event type RGB_SET is making a request to set the RGB LED to the color value&lt;br /&gt;
        -- in the second argument, and that value is equal to (r &amp;lt;&amp;lt; 16 | g &amp;lt;&amp;lt; 8 | b)&lt;br /&gt;
        -- Negative colors are predefined colors, currently;&lt;br /&gt;
        --   -1  OK       (typically Green)&lt;br /&gt;
        --   -2  WARNING  (typically Yellow)&lt;br /&gt;
        --   -3  ERROR    (typically Red)&lt;br /&gt;
        --   -4  INFO     (typically Cyan)&lt;br /&gt;
        publish( RGB_SET, -state)&lt;br /&gt;
        state = (state + 1) % 5&lt;br /&gt;
        next = now + 300&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    -- Called once after program has been loaded into memory.&lt;br /&gt;
    -- To be called periodically, subscription to a TIME_PERIOD&lt;br /&gt;
    -- event should be established.&lt;br /&gt;
    function init()&lt;br /&gt;
      period_id = subscribe(TIME_PERIOD, 250)&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    -- Entry point for all events. All interaction with the&lt;br /&gt;
    -- system and I/O subsystem are handled through events.&lt;br /&gt;
    -- This is to ensure future-compatibility, so that firmware&lt;br /&gt;
    -- doesn't need to be upgraded when new I/O modules are &lt;br /&gt;
    -- introduced.&lt;br /&gt;
    function event(event_id, value)&lt;br /&gt;
      if event_id == period_id then&lt;br /&gt;
        tick(value)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    -- terminating() is called just before the program is terminated &lt;br /&gt;
    -- and removed from memory&lt;br /&gt;
    function terminating()&lt;br /&gt;
      publish(RGB_SET, 0)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Example 2 - Toggle SSR in slot 5 output 1 at 1Hz and output 2 at 5Hz ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
  -- do..end is called an &amp;quot;explicit lexical scope&amp;quot;, and needed to&lt;br /&gt;
  -- allow for so called &amp;quot;upvalues&amp;quot;, that is the variables in that scope&lt;br /&gt;
  -- which will persist over invocations from the system.&lt;br /&gt;
&lt;br /&gt;
  do&lt;br /&gt;
    local state1 = 0&lt;br /&gt;
    local state2 = 0&lt;br /&gt;
    local counter1 = 0&lt;br /&gt;
    &lt;br /&gt;
    -- local functions are not visible to the host system.&lt;br /&gt;
    local function tick()&lt;br /&gt;
      counter1 = ( counter1 + 1 ) % 5&lt;br /&gt;
      if counter1 = 0 then&lt;br /&gt;
        -- publish to slot 5, channel 1, and the value&lt;br /&gt;
        publish( create_io( 5,1, state1 ) )&lt;br /&gt;
        state1 = !state1&lt;br /&gt;
      end&lt;br /&gt;
      -- publish to slot 5, channel 2, and the value&lt;br /&gt;
      publish( create_io( 5, 2, state2 ) )&lt;br /&gt;
      state2 = !state2&lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    -- Called once after program has been loaded into memory.&lt;br /&gt;
    function init()&lt;br /&gt;
      -- request the 5Hz&lt;br /&gt;
      period_id = subscribe( TIME_PERIOD, 200 )&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    -- Entry point for all events. All interaction with the&lt;br /&gt;
    -- system and I/O subsystem are handled through events.&lt;br /&gt;
    -- This is to ensure future-compatibility, so that firmware&lt;br /&gt;
    -- doesn't need to be upgraded when new I/O modules are &lt;br /&gt;
    -- introduced.&lt;br /&gt;
    function event( event, value )&lt;br /&gt;
      if event_type( event ) == period_type then&lt;br /&gt;
        tick()&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    -- terminating() is called just before the program is terminated &lt;br /&gt;
    -- and removed from memory&lt;br /&gt;
    function terminating()&lt;br /&gt;
      publish( RGB_SET, 0 )&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Example 3 - Set Analog Output 1 in Slot 4 ==&lt;br /&gt;
&lt;br /&gt;
== Example 4 - Raise an Alarm condition ==&lt;br /&gt;
&lt;br /&gt;
== Example 5 - Get Analog Input 2 in slot 1 ==&lt;br /&gt;
&lt;br /&gt;
== Example  - Level check == &lt;br /&gt;
Check every minute if Analog Input 2 in slot 2 is &amp;gt;10mA, if so set SSR output 1, and if input &amp;lt; 5mA turn it off.&lt;br /&gt;
&lt;br /&gt;
== Example  - PID implementation in Lua ==&lt;br /&gt;
&lt;br /&gt;
== Example  - Interface Colibri PID1 ==&lt;br /&gt;
Colibri PID1 has a co-processor on the I/O module, which measures temperature on Pt1000 input and use PID algorithm to regulate that with Analog Output. The program in that I/O module is fixed, but it has a lot of parameters that can be set.&lt;br /&gt;
&lt;br /&gt;
  SetP - Setpoint in ˚C&lt;br /&gt;
  Cycle - Sample frequency in ms&lt;br /&gt;
  P - Proportional constant&lt;br /&gt;
  I - Integral time&lt;br /&gt;
  D - Derivative time&lt;br /&gt;
  MD - Max Derivative value&lt;br /&gt;
  Min - Minimum value, default 0&lt;br /&gt;
  Max - Maximum value, default 100&lt;br /&gt;
&lt;br /&gt;
It also reports both Input (in ˚C) and Output (in Max/Min values) on each Cycle, if cycle is slower than I/O subsystem update time (typ 10ms).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Historical =&lt;br /&gt;
The Colibri Runtime is the custom firmware that is running on Colibri MCUs, an application in [[Colibri Zephyr]] orchestrating the hardware resources, WebAssembly engines with I/O drivers and user programs.&lt;br /&gt;
&lt;br /&gt;
NOTE: running in individual WebAssembly instances turned out to be more stressful than useful, so that thread has been closed but kept on this Wiki for historical purposes.&lt;br /&gt;
&lt;br /&gt;
== Development == &lt;br /&gt;
[[Colibri EEPROM Layout]]&lt;br /&gt;
&lt;br /&gt;
[[Colibri WebAssembly Notes]]&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Colibri_Runtime&amp;diff=7582</id>
		<title>Colibri Runtime</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Colibri_Runtime&amp;diff=7582"/>
		<updated>2026-05-17T10:25:05Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* Example 2 - Toggle SSR in slot 5 output 1 at 1Hz and output 2 at 5Hz */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Colibri Runtime is the custom firmware that is running on Colibri MCUs, an application in [[Colibri Zephyr]] orchestrating the hardware resources, I/O drivers and Lua '''user scripts'''.&lt;br /&gt;
&lt;br /&gt;
Initially, a single Lua script is supported. But more might follow. &lt;br /&gt;
&lt;br /&gt;
== User Program Requirements ==&lt;br /&gt;
The user program/script MUST contain the following functions;&lt;br /&gt;
&lt;br /&gt;
== Limits in Lua ==&lt;br /&gt;
&lt;br /&gt;
== Host API ==&lt;br /&gt;
&lt;br /&gt;
  event(event_id, value)&lt;br /&gt;
  publish(event, value)&lt;br /&gt;
  subscribe(event_type, value)&lt;br /&gt;
  unsubscribe(event_type)&lt;br /&gt;
  &lt;br /&gt;
  is_type(event_id, event_type)&lt;br /&gt;
&lt;br /&gt;
Event Types&lt;br /&gt;
  TIME_PERIOD&lt;br /&gt;
  COUNTER&lt;br /&gt;
  ERROR_CODE&lt;br /&gt;
  MEASURED_VALUE&lt;br /&gt;
  COMPUTED_VALUE&lt;br /&gt;
  SETPOINT&lt;br /&gt;
  MIN_VALUE&lt;br /&gt;
  MAX_VALUE&lt;br /&gt;
  LOW_THRESHOLD&lt;br /&gt;
  HIGH_THRESHOLD&lt;br /&gt;
  RUN_INDICATION&lt;br /&gt;
  ALARM_INDICATION&lt;br /&gt;
  RGB_SET&lt;br /&gt;
&lt;br /&gt;
== Example 1 - Blinky ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
  -- do..end is called an &amp;quot;explicit lexical scope&amp;quot;, and needed to&lt;br /&gt;
  -- allow for so called &amp;quot;upvalues&amp;quot;, that is the variables in that scope&lt;br /&gt;
  -- which will persist over invocations from the system.&lt;br /&gt;
&lt;br /&gt;
  do&lt;br /&gt;
    local next=0&lt;br /&gt;
    local state=0&lt;br /&gt;
    local period_id&lt;br /&gt;
    &lt;br /&gt;
    -- local functions are not visible to the host system.&lt;br /&gt;
    local function tick(now)&lt;br /&gt;
      if next &amp;lt; now then&lt;br /&gt;
        -- publish() is the main way to interact with the system&lt;br /&gt;
        -- Event type RGB_SET is making a request to set the RGB LED to the color value&lt;br /&gt;
        -- in the second argument, and that value is equal to (r &amp;lt;&amp;lt; 16 | g &amp;lt;&amp;lt; 8 | b)&lt;br /&gt;
        -- Negative colors are predefined colors, currently;&lt;br /&gt;
        --   -1  OK       (typically Green)&lt;br /&gt;
        --   -2  WARNING  (typically Yellow)&lt;br /&gt;
        --   -3  ERROR    (typically Red)&lt;br /&gt;
        --   -4  INFO     (typically Cyan)&lt;br /&gt;
        publish( RGB_SET, -state)&lt;br /&gt;
        state = (state + 1) % 5&lt;br /&gt;
        next = now + 300&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    -- Called once after program has been loaded into memory.&lt;br /&gt;
    -- To be called periodically, subscription to a TIME_PERIOD&lt;br /&gt;
    -- event should be established.&lt;br /&gt;
    function init()&lt;br /&gt;
      period_id = subscribe(TIME_PERIOD, 250)&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    -- Entry point for all events. All interaction with the&lt;br /&gt;
    -- system and I/O subsystem are handled through events.&lt;br /&gt;
    -- This is to ensure future-compatibility, so that firmware&lt;br /&gt;
    -- doesn't need to be upgraded when new I/O modules are &lt;br /&gt;
    -- introduced.&lt;br /&gt;
    function event(event_id, value)&lt;br /&gt;
      if event_id == period_id then&lt;br /&gt;
        tick(value)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    -- terminating() is called just before the program is terminated &lt;br /&gt;
    -- and removed from memory&lt;br /&gt;
    function terminating()&lt;br /&gt;
      publish(RGB_SET, 0)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Example 2 - Toggle SSR in slot 5 output 1 at 1Hz and output 2 at 5Hz ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
  -- do..end is called an &amp;quot;explicit lexical scope&amp;quot;, and needed to&lt;br /&gt;
  -- allow for so called &amp;quot;upvalues&amp;quot;, that is the variables in that scope&lt;br /&gt;
  -- which will persist over invocations from the system.&lt;br /&gt;
&lt;br /&gt;
  do&lt;br /&gt;
    local state1 = 0&lt;br /&gt;
    local state2 = 0&lt;br /&gt;
    local counter1 = 0&lt;br /&gt;
    &lt;br /&gt;
    -- local functions are not visible to the host system.&lt;br /&gt;
    local function tick()&lt;br /&gt;
      counter1 = ( counter1 + 1 ) % 5&lt;br /&gt;
      if counter1 = 9 then&lt;br /&gt;
        -- publish to slot 5, channel 1, and the value&lt;br /&gt;
        publish( create_io( 5,1, state1 ) )&lt;br /&gt;
        state1 = !state1&lt;br /&gt;
      end&lt;br /&gt;
      -- publish to slot 5, channel 2, and the value&lt;br /&gt;
      publish( create_io( 5, 2, state2 ) )&lt;br /&gt;
      state2 = !state2&lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    -- Called once after program has been loaded into memory.&lt;br /&gt;
    function init()&lt;br /&gt;
      -- request the 5Hz&lt;br /&gt;
      period_id = subscribe( TIME_PERIOD, 200 )&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    -- Entry point for all events. All interaction with the&lt;br /&gt;
    -- system and I/O subsystem are handled through events.&lt;br /&gt;
    -- This is to ensure future-compatibility, so that firmware&lt;br /&gt;
    -- doesn't need to be upgraded when new I/O modules are &lt;br /&gt;
    -- introduced.&lt;br /&gt;
    function event( event, value )&lt;br /&gt;
      if event_type( event ) == period_type then&lt;br /&gt;
        tick()&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    -- terminating() is called just before the program is terminated &lt;br /&gt;
    -- and removed from memory&lt;br /&gt;
    function terminating()&lt;br /&gt;
      publish( RGB_SET, 0 )&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Example 3 - Set Analog Output 1 in Slot 4 ==&lt;br /&gt;
&lt;br /&gt;
== Example 4 - Raise an Alarm condition ==&lt;br /&gt;
&lt;br /&gt;
== Example 5 - Get Analog Input 2 in slot 1 ==&lt;br /&gt;
&lt;br /&gt;
== Example  - Level check == &lt;br /&gt;
Check every minute if Analog Input 2 in slot 2 is &amp;gt;10mA, if so set SSR output 1, and if input &amp;lt; 5mA turn it off.&lt;br /&gt;
&lt;br /&gt;
== Example  - PID implementation in Lua ==&lt;br /&gt;
&lt;br /&gt;
== Example  - Interface Colibri PID1 ==&lt;br /&gt;
Colibri PID1 has a co-processor on the I/O module, which measures temperature on Pt1000 input and use PID algorithm to regulate that with Analog Output. The program in that I/O module is fixed, but it has a lot of parameters that can be set.&lt;br /&gt;
&lt;br /&gt;
  SetP - Setpoint in ˚C&lt;br /&gt;
  Cycle - Sample frequency in ms&lt;br /&gt;
  P - Proportional constant&lt;br /&gt;
  I - Integral time&lt;br /&gt;
  D - Derivative time&lt;br /&gt;
  MD - Max Derivative value&lt;br /&gt;
  Min - Minimum value, default 0&lt;br /&gt;
  Max - Maximum value, default 100&lt;br /&gt;
&lt;br /&gt;
It also reports both Input (in ˚C) and Output (in Max/Min values) on each Cycle, if cycle is slower than I/O subsystem update time (typ 10ms).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Historical =&lt;br /&gt;
The Colibri Runtime is the custom firmware that is running on Colibri MCUs, an application in [[Colibri Zephyr]] orchestrating the hardware resources, WebAssembly engines with I/O drivers and user programs.&lt;br /&gt;
&lt;br /&gt;
NOTE: running in individual WebAssembly instances turned out to be more stressful than useful, so that thread has been closed but kept on this Wiki for historical purposes.&lt;br /&gt;
&lt;br /&gt;
== Development == &lt;br /&gt;
[[Colibri EEPROM Layout]]&lt;br /&gt;
&lt;br /&gt;
[[Colibri WebAssembly Notes]]&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Colibri_Runtime&amp;diff=7557</id>
		<title>Colibri Runtime</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Colibri_Runtime&amp;diff=7557"/>
		<updated>2026-05-12T05:53:03Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* Example 1 - Blinky */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Colibri Runtime is the custom firmware that is running on Colibri MCUs, an application in [[Colibri Zephyr]] orchestrating the hardware resources, I/O drivers and Lua '''user scripts'''.&lt;br /&gt;
&lt;br /&gt;
Initially, a single Lua script is supported. But more might follow. &lt;br /&gt;
&lt;br /&gt;
== User Program Requirements ==&lt;br /&gt;
The user program/script MUST contain the following functions;&lt;br /&gt;
&lt;br /&gt;
== Limits in Lua ==&lt;br /&gt;
&lt;br /&gt;
== Host API ==&lt;br /&gt;
&lt;br /&gt;
  event(event_id, value)&lt;br /&gt;
  publish(event, value)&lt;br /&gt;
  subscribe(event_type, value)&lt;br /&gt;
  unsubscribe(event_type)&lt;br /&gt;
  &lt;br /&gt;
  is_type(event_id, event_type)&lt;br /&gt;
&lt;br /&gt;
Event Types&lt;br /&gt;
  TIME_PERIOD&lt;br /&gt;
  COUNTER&lt;br /&gt;
  ERROR_CODE&lt;br /&gt;
  MEASURED_VALUE&lt;br /&gt;
  COMPUTED_VALUE&lt;br /&gt;
  SETPOINT&lt;br /&gt;
  MIN_VALUE&lt;br /&gt;
  MAX_VALUE&lt;br /&gt;
  LOW_THRESHOLD&lt;br /&gt;
  HIGH_THRESHOLD&lt;br /&gt;
  RUN_INDICATION&lt;br /&gt;
  ALARM_INDICATION&lt;br /&gt;
  RGB_SET&lt;br /&gt;
&lt;br /&gt;
== Example 1 - Blinky ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
  -- do..end is called an &amp;quot;explicit lexical scope&amp;quot;, and needed to&lt;br /&gt;
  -- allow for so called &amp;quot;upvalues&amp;quot;, that is the variables in that scope&lt;br /&gt;
  -- which will persist over invocations from the system.&lt;br /&gt;
&lt;br /&gt;
  do&lt;br /&gt;
    local next=0&lt;br /&gt;
    local state=0&lt;br /&gt;
    local period_id&lt;br /&gt;
    &lt;br /&gt;
    -- local functions are not visible to the host system.&lt;br /&gt;
    local function tick(now)&lt;br /&gt;
      if next &amp;lt; now then&lt;br /&gt;
        -- publish() is the main way to interact with the system&lt;br /&gt;
        -- Event type RGB_SET is making a request to set the RGB LED to the color value&lt;br /&gt;
        -- in the second argument, and that value is equal to (r &amp;lt;&amp;lt; 16 | g &amp;lt;&amp;lt; 8 | b)&lt;br /&gt;
        -- Negative colors are predefined colors, currently;&lt;br /&gt;
        --   -1  OK       (typically Green)&lt;br /&gt;
        --   -2  WARNING  (typically Yellow)&lt;br /&gt;
        --   -3  ERROR    (typically Red)&lt;br /&gt;
        --   -4  INFO     (typically Cyan)&lt;br /&gt;
        publish( RGB_SET, -state)&lt;br /&gt;
        state = (state + 1) % 5&lt;br /&gt;
        next = now + 300&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    -- Called once after program has been loaded into memory.&lt;br /&gt;
    -- To be called periodically, subscription to a TIME_PERIOD&lt;br /&gt;
    -- event should be established.&lt;br /&gt;
    function init()&lt;br /&gt;
      period_id = subscribe(TIME_PERIOD, 250)&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    -- Entry point for all events. All interaction with the&lt;br /&gt;
    -- system and I/O subsystem are handled through events.&lt;br /&gt;
    -- This is to ensure future-compatibility, so that firmware&lt;br /&gt;
    -- doesn't need to be upgraded when new I/O modules are &lt;br /&gt;
    -- introduced.&lt;br /&gt;
    function event(event_id, value)&lt;br /&gt;
      if event_id == period_id then&lt;br /&gt;
        tick(value)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    -- terminating() is called just before the program is terminated &lt;br /&gt;
    -- and removed from memory&lt;br /&gt;
    function terminating()&lt;br /&gt;
      publish(RGB_SET, 0)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Example 2 - Toggle SSR in slot 5 output 1 at 1Hz and output 2 at 5Hz ==&lt;br /&gt;
&lt;br /&gt;
== Example 3 - Set Analog Output 1 in Slot 4 ==&lt;br /&gt;
&lt;br /&gt;
== Example 4 - Raise an Alarm condition ==&lt;br /&gt;
&lt;br /&gt;
== Example 5 - Get Analog Input 2 in slot 1 ==&lt;br /&gt;
&lt;br /&gt;
== Example  - Level check == &lt;br /&gt;
Check every minute if Analog Input 2 in slot 2 is &amp;gt;10mA, if so set SSR output 1, and if input &amp;lt; 5mA turn it off.&lt;br /&gt;
&lt;br /&gt;
== Example  - PID implementation in Lua ==&lt;br /&gt;
&lt;br /&gt;
== Example  - Interface Colibri PID1 ==&lt;br /&gt;
Colibri PID1 has a co-processor on the I/O module, which measures temperature on Pt1000 input and use PID algorithm to regulate that with Analog Output. The program in that I/O module is fixed, but it has a lot of parameters that can be set.&lt;br /&gt;
&lt;br /&gt;
  SetP - Setpoint in ˚C&lt;br /&gt;
  Cycle - Sample frequency in ms&lt;br /&gt;
  P - Proportional constant&lt;br /&gt;
  I - Integral time&lt;br /&gt;
  D - Derivative time&lt;br /&gt;
  MD - Max Derivative value&lt;br /&gt;
  Min - Minimum value, default 0&lt;br /&gt;
  Max - Maximum value, default 100&lt;br /&gt;
&lt;br /&gt;
It also reports both Input (in ˚C) and Output (in Max/Min values) on each Cycle, if cycle is slower than I/O subsystem update time (typ 10ms).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Historical =&lt;br /&gt;
The Colibri Runtime is the custom firmware that is running on Colibri MCUs, an application in [[Colibri Zephyr]] orchestrating the hardware resources, WebAssembly engines with I/O drivers and user programs.&lt;br /&gt;
&lt;br /&gt;
NOTE: running in individual WebAssembly instances turned out to be more stressful than useful, so that thread has been closed but kept on this Wiki for historical purposes.&lt;br /&gt;
&lt;br /&gt;
== Development == &lt;br /&gt;
[[Colibri EEPROM Layout]]&lt;br /&gt;
&lt;br /&gt;
[[Colibri WebAssembly Notes]]&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Colibri_Runtime&amp;diff=7556</id>
		<title>Colibri Runtime</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Colibri_Runtime&amp;diff=7556"/>
		<updated>2026-05-12T05:43:21Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* Example 1 - Blinky */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Colibri Runtime is the custom firmware that is running on Colibri MCUs, an application in [[Colibri Zephyr]] orchestrating the hardware resources, I/O drivers and Lua '''user scripts'''.&lt;br /&gt;
&lt;br /&gt;
Initially, a single Lua script is supported. But more might follow. &lt;br /&gt;
&lt;br /&gt;
== User Program Requirements ==&lt;br /&gt;
The user program/script MUST contain the following functions;&lt;br /&gt;
&lt;br /&gt;
== Limits in Lua ==&lt;br /&gt;
&lt;br /&gt;
== Host API ==&lt;br /&gt;
&lt;br /&gt;
  event(event_id, value)&lt;br /&gt;
  publish(event, value)&lt;br /&gt;
  subscribe(event_type, value)&lt;br /&gt;
  unsubscribe(event_type)&lt;br /&gt;
  &lt;br /&gt;
  is_type(event_id, event_type)&lt;br /&gt;
&lt;br /&gt;
Event Types&lt;br /&gt;
  TIME_PERIOD&lt;br /&gt;
  COUNTER&lt;br /&gt;
  ERROR_CODE&lt;br /&gt;
  MEASURED_VALUE&lt;br /&gt;
  COMPUTED_VALUE&lt;br /&gt;
  SETPOINT&lt;br /&gt;
  MIN_VALUE&lt;br /&gt;
  MAX_VALUE&lt;br /&gt;
  LOW_THRESHOLD&lt;br /&gt;
  HIGH_THRESHOLD&lt;br /&gt;
  RUN_INDICATION&lt;br /&gt;
  ALARM_INDICATION&lt;br /&gt;
  RGB_SET&lt;br /&gt;
&lt;br /&gt;
== Example 1 - Blinky ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
  -- do..end is called an &amp;quot;explicit lexical scope&amp;quot;, and needed to&lt;br /&gt;
  -- allow for so called &amp;quot;upvalues&amp;quot;, that is the variables in that scope&lt;br /&gt;
  -- which will persist over invocations from the system.&lt;br /&gt;
  do&lt;br /&gt;
    local next=0&lt;br /&gt;
    local state=0&lt;br /&gt;
    local period_id&lt;br /&gt;
    &lt;br /&gt;
    -- local functions are not visible to the host system.&lt;br /&gt;
    local function tick(now)&lt;br /&gt;
      if next &amp;lt; now then&lt;br /&gt;
        -- publish() is the main way to interact with the system&lt;br /&gt;
        -- Event type RGB_SET is making a request to set the RGB LED to the color value&lt;br /&gt;
        -- in the second argument, and that value is equal to (r &amp;lt;&amp;lt; 16 | g &amp;lt;&amp;lt; 8 | b)&lt;br /&gt;
        -- Negative colors are predefined colors, currently;&lt;br /&gt;
        --   -1  OK       (typically Green)&lt;br /&gt;
        --   -2  WARNING  (typically Yellow)&lt;br /&gt;
        --   -3  ERROR    (typically Red)&lt;br /&gt;
        --   -4  INFO     (typically Cyan)&lt;br /&gt;
        publish( RGB_SET, -state)&lt;br /&gt;
        state = (state + 1) % 5&lt;br /&gt;
        next = now + 300&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    -- Called once after program has been loaded into memory.&lt;br /&gt;
    -- To be called periodically, subscription to a TIME_PERIOD&lt;br /&gt;
    -- event should be established.&lt;br /&gt;
    function init()&lt;br /&gt;
      period_id = subscribe(TIME_PERIOD, 250)&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    -- Entry point for all events. All interaction with the&lt;br /&gt;
    -- system and I/O subsystem are handled through events.&lt;br /&gt;
    -- This is to ensure future-compatibility, so that firmware&lt;br /&gt;
    -- doesn't need to be upgraded when new I/O modules are &lt;br /&gt;
    -- introduced.&lt;br /&gt;
    function event(event_id, value)&lt;br /&gt;
      if event_id == period_id then&lt;br /&gt;
        tick(value)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    -- terminating() is called just before the program is terminated &lt;br /&gt;
    -- and removed from memory&lt;br /&gt;
    function terminating()&lt;br /&gt;
      publish(RGB_SET, 0)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Example 2 - Toggle SSR in slot 5 output 1 at 1Hz and output 2 at 5Hz ==&lt;br /&gt;
&lt;br /&gt;
== Example 3 - Set Analog Output 1 in Slot 4 ==&lt;br /&gt;
&lt;br /&gt;
== Example 4 - Raise an Alarm condition ==&lt;br /&gt;
&lt;br /&gt;
== Example 5 - Get Analog Input 2 in slot 1 ==&lt;br /&gt;
&lt;br /&gt;
== Example  - Level check == &lt;br /&gt;
Check every minute if Analog Input 2 in slot 2 is &amp;gt;10mA, if so set SSR output 1, and if input &amp;lt; 5mA turn it off.&lt;br /&gt;
&lt;br /&gt;
== Example  - PID implementation in Lua ==&lt;br /&gt;
&lt;br /&gt;
== Example  - Interface Colibri PID1 ==&lt;br /&gt;
Colibri PID1 has a co-processor on the I/O module, which measures temperature on Pt1000 input and use PID algorithm to regulate that with Analog Output. The program in that I/O module is fixed, but it has a lot of parameters that can be set.&lt;br /&gt;
&lt;br /&gt;
  SetP - Setpoint in ˚C&lt;br /&gt;
  Cycle - Sample frequency in ms&lt;br /&gt;
  P - Proportional constant&lt;br /&gt;
  I - Integral time&lt;br /&gt;
  D - Derivative time&lt;br /&gt;
  MD - Max Derivative value&lt;br /&gt;
  Min - Minimum value, default 0&lt;br /&gt;
  Max - Maximum value, default 100&lt;br /&gt;
&lt;br /&gt;
It also reports both Input (in ˚C) and Output (in Max/Min values) on each Cycle, if cycle is slower than I/O subsystem update time (typ 10ms).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Historical =&lt;br /&gt;
The Colibri Runtime is the custom firmware that is running on Colibri MCUs, an application in [[Colibri Zephyr]] orchestrating the hardware resources, WebAssembly engines with I/O drivers and user programs.&lt;br /&gt;
&lt;br /&gt;
NOTE: running in individual WebAssembly instances turned out to be more stressful than useful, so that thread has been closed but kept on this Wiki for historical purposes.&lt;br /&gt;
&lt;br /&gt;
== Development == &lt;br /&gt;
[[Colibri EEPROM Layout]]&lt;br /&gt;
&lt;br /&gt;
[[Colibri WebAssembly Notes]]&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Colibri_Runtime&amp;diff=7555</id>
		<title>Colibri Runtime</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Colibri_Runtime&amp;diff=7555"/>
		<updated>2026-05-12T05:37:52Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* Example 1 - Blinky */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Colibri Runtime is the custom firmware that is running on Colibri MCUs, an application in [[Colibri Zephyr]] orchestrating the hardware resources, I/O drivers and Lua '''user scripts'''.&lt;br /&gt;
&lt;br /&gt;
Initially, a single Lua script is supported. But more might follow. &lt;br /&gt;
&lt;br /&gt;
== User Program Requirements ==&lt;br /&gt;
The user program/script MUST contain the following functions;&lt;br /&gt;
&lt;br /&gt;
== Limits in Lua ==&lt;br /&gt;
&lt;br /&gt;
== Host API ==&lt;br /&gt;
&lt;br /&gt;
  event(event_id, value)&lt;br /&gt;
  publish(event, value)&lt;br /&gt;
  subscribe(event_type, value)&lt;br /&gt;
  unsubscribe(event_type)&lt;br /&gt;
  &lt;br /&gt;
  is_type(event_id, event_type)&lt;br /&gt;
&lt;br /&gt;
Event Types&lt;br /&gt;
  TIME_PERIOD&lt;br /&gt;
  COUNTER&lt;br /&gt;
  ERROR_CODE&lt;br /&gt;
  MEASURED_VALUE&lt;br /&gt;
  COMPUTED_VALUE&lt;br /&gt;
  SETPOINT&lt;br /&gt;
  MIN_VALUE&lt;br /&gt;
  MAX_VALUE&lt;br /&gt;
  LOW_THRESHOLD&lt;br /&gt;
  HIGH_THRESHOLD&lt;br /&gt;
  RUN_INDICATION&lt;br /&gt;
  ALARM_INDICATION&lt;br /&gt;
  RGB_SET&lt;br /&gt;
&lt;br /&gt;
== Example 1 - Blinky ==&lt;br /&gt;
&lt;br /&gt;
  -- do..end is called an &amp;quot;explicit lexical scope&amp;quot;, and needed to&lt;br /&gt;
  -- allow for so called &amp;quot;upvalues&amp;quot;, that is the variables in that scope&lt;br /&gt;
  -- which will persist over invocations from the system.&lt;br /&gt;
  do&lt;br /&gt;
    local next=0&lt;br /&gt;
    local state=0&lt;br /&gt;
    local period_id&lt;br /&gt;
    &lt;br /&gt;
    -- local functions are not visible to the host system.&lt;br /&gt;
    local function tick(now)&lt;br /&gt;
      if next &amp;lt; now then&lt;br /&gt;
        -- publish() is the main way to interact with the system&lt;br /&gt;
        -- Event type RGB_SET is making a request to set the RGB LED to the color value&lt;br /&gt;
        -- in the second argument, and that value is equal to (r &amp;lt;&amp;lt; 16 | g &amp;lt;&amp;lt; 8 | b)&lt;br /&gt;
        -- Negative colors are predefined colors, currently;&lt;br /&gt;
        --   -1  OK       (typically Green)&lt;br /&gt;
        --   -2  WARNING  (typically Yellow)&lt;br /&gt;
        --   -3  ERROR    (typically Red)&lt;br /&gt;
        --   -4  INFO     (typically Cyan)&lt;br /&gt;
        publish( RGB_SET, -state)&lt;br /&gt;
        state = (state + 1) % 5&lt;br /&gt;
        next = now + 300&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
    -- Called once after program has been loaded into memory.&lt;br /&gt;
    -- To be called periodically, subscription to a TIME_PERIOD&lt;br /&gt;
    -- event should be established.&lt;br /&gt;
    function init()&lt;br /&gt;
      period_id = subscribe(TIME_PERIOD, 250)&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    -- Entry point for all events. All interaction with the&lt;br /&gt;
    -- system and I/O subsystem are handled through events.&lt;br /&gt;
    -- This is to ensure future-compatibility, so that firmware&lt;br /&gt;
    -- doesn't need to be upgraded when new I/O modules are &lt;br /&gt;
    -- introduced.&lt;br /&gt;
    function event(event_id, value)&lt;br /&gt;
      if event_id == period_id then&lt;br /&gt;
        tick(value)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    -- terminating() is called just before the program is terminated &lt;br /&gt;
    -- and removed from memory&lt;br /&gt;
    function terminating()&lt;br /&gt;
      publish(RGB_SET, 0)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== Example 2 - Toggle SSR in slot 5 output 1 at 1Hz and output 2 at 5Hz ==&lt;br /&gt;
&lt;br /&gt;
== Example 3 - Set Analog Output 1 in Slot 4 ==&lt;br /&gt;
&lt;br /&gt;
== Example 4 - Raise an Alarm condition ==&lt;br /&gt;
&lt;br /&gt;
== Example 5 - Get Analog Input 2 in slot 1 ==&lt;br /&gt;
&lt;br /&gt;
== Example  - Level check == &lt;br /&gt;
Check every minute if Analog Input 2 in slot 2 is &amp;gt;10mA, if so set SSR output 1, and if input &amp;lt; 5mA turn it off.&lt;br /&gt;
&lt;br /&gt;
== Example  - PID implementation in Lua ==&lt;br /&gt;
&lt;br /&gt;
== Example  - Interface Colibri PID1 ==&lt;br /&gt;
Colibri PID1 has a co-processor on the I/O module, which measures temperature on Pt1000 input and use PID algorithm to regulate that with Analog Output. The program in that I/O module is fixed, but it has a lot of parameters that can be set.&lt;br /&gt;
&lt;br /&gt;
  SetP - Setpoint in ˚C&lt;br /&gt;
  Cycle - Sample frequency in ms&lt;br /&gt;
  P - Proportional constant&lt;br /&gt;
  I - Integral time&lt;br /&gt;
  D - Derivative time&lt;br /&gt;
  MD - Max Derivative value&lt;br /&gt;
  Min - Minimum value, default 0&lt;br /&gt;
  Max - Maximum value, default 100&lt;br /&gt;
&lt;br /&gt;
It also reports both Input (in ˚C) and Output (in Max/Min values) on each Cycle, if cycle is slower than I/O subsystem update time (typ 10ms).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Historical =&lt;br /&gt;
The Colibri Runtime is the custom firmware that is running on Colibri MCUs, an application in [[Colibri Zephyr]] orchestrating the hardware resources, WebAssembly engines with I/O drivers and user programs.&lt;br /&gt;
&lt;br /&gt;
NOTE: running in individual WebAssembly instances turned out to be more stressful than useful, so that thread has been closed but kept on this Wiki for historical purposes.&lt;br /&gt;
&lt;br /&gt;
== Development == &lt;br /&gt;
[[Colibri EEPROM Layout]]&lt;br /&gt;
&lt;br /&gt;
[[Colibri WebAssembly Notes]]&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Colibri_Runtime&amp;diff=7554</id>
		<title>Colibri Runtime</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Colibri_Runtime&amp;diff=7554"/>
		<updated>2026-05-12T05:28:30Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* Example 1 - Blinky */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Colibri Runtime is the custom firmware that is running on Colibri MCUs, an application in [[Colibri Zephyr]] orchestrating the hardware resources, I/O drivers and Lua '''user scripts'''.&lt;br /&gt;
&lt;br /&gt;
Initially, a single Lua script is supported. But more might follow. &lt;br /&gt;
&lt;br /&gt;
== User Program Requirements ==&lt;br /&gt;
The user program/script MUST contain the following functions;&lt;br /&gt;
&lt;br /&gt;
== Limits in Lua ==&lt;br /&gt;
&lt;br /&gt;
== Host API ==&lt;br /&gt;
&lt;br /&gt;
  event(event_id, value)&lt;br /&gt;
  publish(event, value)&lt;br /&gt;
  subscribe(event_type, value)&lt;br /&gt;
  unsubscribe(event_type)&lt;br /&gt;
  &lt;br /&gt;
  is_type(event_id, event_type)&lt;br /&gt;
&lt;br /&gt;
Event Types&lt;br /&gt;
  TIME_PERIOD&lt;br /&gt;
  COUNTER&lt;br /&gt;
  ERROR_CODE&lt;br /&gt;
  MEASURED_VALUE&lt;br /&gt;
  COMPUTED_VALUE&lt;br /&gt;
  SETPOINT&lt;br /&gt;
  MIN_VALUE&lt;br /&gt;
  MAX_VALUE&lt;br /&gt;
  LOW_THRESHOLD&lt;br /&gt;
  HIGH_THRESHOLD&lt;br /&gt;
  RUN_INDICATION&lt;br /&gt;
  ALARM_INDICATION&lt;br /&gt;
  RGB_SET&lt;br /&gt;
&lt;br /&gt;
== Example 1 - Blinky ==&lt;br /&gt;
&lt;br /&gt;
  do&lt;br /&gt;
    local next=0&lt;br /&gt;
    local state=0&lt;br /&gt;
    local period_id&lt;br /&gt;
  &lt;br /&gt;
    local function tick(now)&lt;br /&gt;
      if next &amp;lt; now then&lt;br /&gt;
        -- publish() is the main way to interact with the system&lt;br /&gt;
        -- Event type RGB_SET is making a request to set the RGB LED to the color value&lt;br /&gt;
        -- in the second argument, and that value is equal to (r &amp;lt;&amp;lt; 16 | g &amp;lt;&amp;lt; 8 | b)&lt;br /&gt;
        -- Negative colors are predefined colors, currently;&lt;br /&gt;
        --   -1  OK       (typically Green)&lt;br /&gt;
        --   -2  WARNING  (typically Yellow)&lt;br /&gt;
        --   -3  ERROR    (typically Red)&lt;br /&gt;
        --   -4  INFO     (typically Cyan)&lt;br /&gt;
        publish( RGB_SET, -state)&lt;br /&gt;
        state = (state + 1) % 5&lt;br /&gt;
        next = now + 300&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    function init()&lt;br /&gt;
      period_id = subscribe(TIME_PERIOD, 250)&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    function event(event_id, value)&lt;br /&gt;
      if event_id == period_id then&lt;br /&gt;
        tick(value)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    function loaded()&lt;br /&gt;
      publish(RGB_SET, 0)&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    function unloading()&lt;br /&gt;
      publish(RGB_SET, 0)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== Example 2 - Toggle SSR in slot 5 output 1 at 1Hz and output 2 at 5Hz ==&lt;br /&gt;
&lt;br /&gt;
== Example 3 - Set Analog Output 1 in Slot 4 ==&lt;br /&gt;
&lt;br /&gt;
== Example 4 - Raise an Alarm condition ==&lt;br /&gt;
&lt;br /&gt;
== Example 5 - Get Analog Input 2 in slot 1 ==&lt;br /&gt;
&lt;br /&gt;
== Example  - Level check == &lt;br /&gt;
Check every minute if Analog Input 2 in slot 2 is &amp;gt;10mA, if so set SSR output 1, and if input &amp;lt; 5mA turn it off.&lt;br /&gt;
&lt;br /&gt;
== Example  - PID implementation in Lua ==&lt;br /&gt;
&lt;br /&gt;
== Example  - Interface Colibri PID1 ==&lt;br /&gt;
Colibri PID1 has a co-processor on the I/O module, which measures temperature on Pt1000 input and use PID algorithm to regulate that with Analog Output. The program in that I/O module is fixed, but it has a lot of parameters that can be set.&lt;br /&gt;
&lt;br /&gt;
  SetP - Setpoint in ˚C&lt;br /&gt;
  Cycle - Sample frequency in ms&lt;br /&gt;
  P - Proportional constant&lt;br /&gt;
  I - Integral time&lt;br /&gt;
  D - Derivative time&lt;br /&gt;
  MD - Max Derivative value&lt;br /&gt;
  Min - Minimum value, default 0&lt;br /&gt;
  Max - Maximum value, default 100&lt;br /&gt;
&lt;br /&gt;
It also reports both Input (in ˚C) and Output (in Max/Min values) on each Cycle, if cycle is slower than I/O subsystem update time (typ 10ms).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Historical =&lt;br /&gt;
The Colibri Runtime is the custom firmware that is running on Colibri MCUs, an application in [[Colibri Zephyr]] orchestrating the hardware resources, WebAssembly engines with I/O drivers and user programs.&lt;br /&gt;
&lt;br /&gt;
NOTE: running in individual WebAssembly instances turned out to be more stressful than useful, so that thread has been closed but kept on this Wiki for historical purposes.&lt;br /&gt;
&lt;br /&gt;
== Development == &lt;br /&gt;
[[Colibri EEPROM Layout]]&lt;br /&gt;
&lt;br /&gt;
[[Colibri WebAssembly Notes]]&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Colibri_Runtime&amp;diff=7553</id>
		<title>Colibri Runtime</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Colibri_Runtime&amp;diff=7553"/>
		<updated>2026-05-12T05:28:19Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* Example 1 - Blinky */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Colibri Runtime is the custom firmware that is running on Colibri MCUs, an application in [[Colibri Zephyr]] orchestrating the hardware resources, I/O drivers and Lua '''user scripts'''.&lt;br /&gt;
&lt;br /&gt;
Initially, a single Lua script is supported. But more might follow. &lt;br /&gt;
&lt;br /&gt;
== User Program Requirements ==&lt;br /&gt;
The user program/script MUST contain the following functions;&lt;br /&gt;
&lt;br /&gt;
== Limits in Lua ==&lt;br /&gt;
&lt;br /&gt;
== Host API ==&lt;br /&gt;
&lt;br /&gt;
  event(event_id, value)&lt;br /&gt;
  publish(event, value)&lt;br /&gt;
  subscribe(event_type, value)&lt;br /&gt;
  unsubscribe(event_type)&lt;br /&gt;
  &lt;br /&gt;
  is_type(event_id, event_type)&lt;br /&gt;
&lt;br /&gt;
Event Types&lt;br /&gt;
  TIME_PERIOD&lt;br /&gt;
  COUNTER&lt;br /&gt;
  ERROR_CODE&lt;br /&gt;
  MEASURED_VALUE&lt;br /&gt;
  COMPUTED_VALUE&lt;br /&gt;
  SETPOINT&lt;br /&gt;
  MIN_VALUE&lt;br /&gt;
  MAX_VALUE&lt;br /&gt;
  LOW_THRESHOLD&lt;br /&gt;
  HIGH_THRESHOLD&lt;br /&gt;
  RUN_INDICATION&lt;br /&gt;
  ALARM_INDICATION&lt;br /&gt;
  RGB_SET&lt;br /&gt;
&lt;br /&gt;
== Example 1 - Blinky ==&lt;br /&gt;
&lt;br /&gt;
  do&lt;br /&gt;
    local next=0&lt;br /&gt;
    local state=0&lt;br /&gt;
    local period_id&lt;br /&gt;
&lt;br /&gt;
    local function tick(now)&lt;br /&gt;
      if next &amp;lt; now then&lt;br /&gt;
        -- publish() is the main way to interact with the system&lt;br /&gt;
        -- Event type RGB_SET is making a request to set the RGB LED to the color value&lt;br /&gt;
        -- in the second argument, and that value is equal to (r &amp;lt;&amp;lt; 16 | g &amp;lt;&amp;lt; 8 | b)&lt;br /&gt;
        -- Negative colors are predefined colors, currently;&lt;br /&gt;
        --   -1  OK       (typically Green)&lt;br /&gt;
        --   -2  WARNING  (typically Yellow)&lt;br /&gt;
        --   -3  ERROR    (typically Red)&lt;br /&gt;
        --   -4  INFO     (typically Cyan)&lt;br /&gt;
        publish( RGB_SET, -state)&lt;br /&gt;
        state = (state + 1) % 5&lt;br /&gt;
        next = now + 300&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    function init()&lt;br /&gt;
      period_id = subscribe(TIME_PERIOD, 250)&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    function event(event_id, value)&lt;br /&gt;
      if event_id == period_id then&lt;br /&gt;
        tick(value)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    function loaded()&lt;br /&gt;
      publish(RGB_SET, 0)&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    function unloading()&lt;br /&gt;
      publish(RGB_SET, 0)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== Example 2 - Toggle SSR in slot 5 output 1 at 1Hz and output 2 at 5Hz ==&lt;br /&gt;
&lt;br /&gt;
== Example 3 - Set Analog Output 1 in Slot 4 ==&lt;br /&gt;
&lt;br /&gt;
== Example 4 - Raise an Alarm condition ==&lt;br /&gt;
&lt;br /&gt;
== Example 5 - Get Analog Input 2 in slot 1 ==&lt;br /&gt;
&lt;br /&gt;
== Example  - Level check == &lt;br /&gt;
Check every minute if Analog Input 2 in slot 2 is &amp;gt;10mA, if so set SSR output 1, and if input &amp;lt; 5mA turn it off.&lt;br /&gt;
&lt;br /&gt;
== Example  - PID implementation in Lua ==&lt;br /&gt;
&lt;br /&gt;
== Example  - Interface Colibri PID1 ==&lt;br /&gt;
Colibri PID1 has a co-processor on the I/O module, which measures temperature on Pt1000 input and use PID algorithm to regulate that with Analog Output. The program in that I/O module is fixed, but it has a lot of parameters that can be set.&lt;br /&gt;
&lt;br /&gt;
  SetP - Setpoint in ˚C&lt;br /&gt;
  Cycle - Sample frequency in ms&lt;br /&gt;
  P - Proportional constant&lt;br /&gt;
  I - Integral time&lt;br /&gt;
  D - Derivative time&lt;br /&gt;
  MD - Max Derivative value&lt;br /&gt;
  Min - Minimum value, default 0&lt;br /&gt;
  Max - Maximum value, default 100&lt;br /&gt;
&lt;br /&gt;
It also reports both Input (in ˚C) and Output (in Max/Min values) on each Cycle, if cycle is slower than I/O subsystem update time (typ 10ms).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Historical =&lt;br /&gt;
The Colibri Runtime is the custom firmware that is running on Colibri MCUs, an application in [[Colibri Zephyr]] orchestrating the hardware resources, WebAssembly engines with I/O drivers and user programs.&lt;br /&gt;
&lt;br /&gt;
NOTE: running in individual WebAssembly instances turned out to be more stressful than useful, so that thread has been closed but kept on this Wiki for historical purposes.&lt;br /&gt;
&lt;br /&gt;
== Development == &lt;br /&gt;
[[Colibri EEPROM Layout]]&lt;br /&gt;
&lt;br /&gt;
[[Colibri WebAssembly Notes]]&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Colibri_Runtime&amp;diff=7552</id>
		<title>Colibri Runtime</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Colibri_Runtime&amp;diff=7552"/>
		<updated>2026-05-12T05:11:06Z</updated>

		<summary type="html">&lt;p&gt;Niclas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Colibri Runtime is the custom firmware that is running on Colibri MCUs, an application in [[Colibri Zephyr]] orchestrating the hardware resources, I/O drivers and Lua '''user scripts'''.&lt;br /&gt;
&lt;br /&gt;
Initially, a single Lua script is supported. But more might follow. &lt;br /&gt;
&lt;br /&gt;
== User Program Requirements ==&lt;br /&gt;
The user program/script MUST contain the following functions;&lt;br /&gt;
&lt;br /&gt;
== Limits in Lua ==&lt;br /&gt;
&lt;br /&gt;
== Host API ==&lt;br /&gt;
&lt;br /&gt;
  event(event_id, value)&lt;br /&gt;
  publish(event, value)&lt;br /&gt;
  subscribe(event_type, value)&lt;br /&gt;
  unsubscribe(event_type)&lt;br /&gt;
  &lt;br /&gt;
  is_type(event_id, event_type)&lt;br /&gt;
&lt;br /&gt;
Event Types&lt;br /&gt;
  TIME_PERIOD&lt;br /&gt;
  COUNTER&lt;br /&gt;
  ERROR_CODE&lt;br /&gt;
  MEASURED_VALUE&lt;br /&gt;
  COMPUTED_VALUE&lt;br /&gt;
  SETPOINT&lt;br /&gt;
  MIN_VALUE&lt;br /&gt;
  MAX_VALUE&lt;br /&gt;
  LOW_THRESHOLD&lt;br /&gt;
  HIGH_THRESHOLD&lt;br /&gt;
  RUN_INDICATION&lt;br /&gt;
  ALARM_INDICATION&lt;br /&gt;
  RGB_SET&lt;br /&gt;
&lt;br /&gt;
== Example 1 - Blinky ==&lt;br /&gt;
&lt;br /&gt;
  do&lt;br /&gt;
    local next=0&lt;br /&gt;
    local state=0&lt;br /&gt;
  &lt;br /&gt;
    local function tick(now)&lt;br /&gt;
      if next &amp;lt; now then&lt;br /&gt;
        -- publish() is the main way to interact with the system&lt;br /&gt;
        -- Event type RGB_SET is making a request to set the RGB LED to the color value&lt;br /&gt;
        -- in the second argument, and that value is equal to (r &amp;lt;&amp;lt; 16 | g &amp;lt;&amp;lt; 8 | b)&lt;br /&gt;
        -- Negative colors are predefined colors, currently;&lt;br /&gt;
        --   -1  OK       (typically Green)&lt;br /&gt;
        --   -2  WARNING  (typically Yellow)&lt;br /&gt;
        --   -3  ERROR    (typically Red)&lt;br /&gt;
        --   -4  INFO     (typically Cyan)&lt;br /&gt;
        publish( RGB_SET, -state)&lt;br /&gt;
        state = (state + 1) % 5&lt;br /&gt;
        next = now + 300&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    function init()&lt;br /&gt;
      subscribe(TIME_PERIOD, 250)&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    function event(event_id, value)&lt;br /&gt;
      if is_type(event_id, TIME_PERIOD) then&lt;br /&gt;
        tick(value)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    function loaded()&lt;br /&gt;
      publish(RGB_SET, 0)&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    function unloading()&lt;br /&gt;
      publish(RGB_SET, 0)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== Example 2 - Toggle SSR in slot 5 output 1 at 1Hz and output 2 at 5Hz ==&lt;br /&gt;
&lt;br /&gt;
== Example 3 - Set Analog Output 1 in Slot 4 ==&lt;br /&gt;
&lt;br /&gt;
== Example 4 - Raise an Alarm condition ==&lt;br /&gt;
&lt;br /&gt;
== Example 5 - Get Analog Input 2 in slot 1 ==&lt;br /&gt;
&lt;br /&gt;
== Example  - Level check == &lt;br /&gt;
Check every minute if Analog Input 2 in slot 2 is &amp;gt;10mA, if so set SSR output 1, and if input &amp;lt; 5mA turn it off.&lt;br /&gt;
&lt;br /&gt;
== Example  - PID implementation in Lua ==&lt;br /&gt;
&lt;br /&gt;
== Example  - Interface Colibri PID1 ==&lt;br /&gt;
Colibri PID1 has a co-processor on the I/O module, which measures temperature on Pt1000 input and use PID algorithm to regulate that with Analog Output. The program in that I/O module is fixed, but it has a lot of parameters that can be set.&lt;br /&gt;
&lt;br /&gt;
  SetP - Setpoint in ˚C&lt;br /&gt;
  Cycle - Sample frequency in ms&lt;br /&gt;
  P - Proportional constant&lt;br /&gt;
  I - Integral time&lt;br /&gt;
  D - Derivative time&lt;br /&gt;
  MD - Max Derivative value&lt;br /&gt;
  Min - Minimum value, default 0&lt;br /&gt;
  Max - Maximum value, default 100&lt;br /&gt;
&lt;br /&gt;
It also reports both Input (in ˚C) and Output (in Max/Min values) on each Cycle, if cycle is slower than I/O subsystem update time (typ 10ms).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Historical =&lt;br /&gt;
The Colibri Runtime is the custom firmware that is running on Colibri MCUs, an application in [[Colibri Zephyr]] orchestrating the hardware resources, WebAssembly engines with I/O drivers and user programs.&lt;br /&gt;
&lt;br /&gt;
NOTE: running in individual WebAssembly instances turned out to be more stressful than useful, so that thread has been closed but kept on this Wiki for historical purposes.&lt;br /&gt;
&lt;br /&gt;
== Development == &lt;br /&gt;
[[Colibri EEPROM Layout]]&lt;br /&gt;
&lt;br /&gt;
[[Colibri WebAssembly Notes]]&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Colibri_Runtime&amp;diff=7551</id>
		<title>Colibri Runtime</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Colibri_Runtime&amp;diff=7551"/>
		<updated>2026-05-12T04:57:47Z</updated>

		<summary type="html">&lt;p&gt;Niclas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Colibri Runtime is the custom firmware that is running on Colibri MCUs, an application in [[Colibri Zephyr]] orchestrating the hardware resources, I/O drivers and Lua '''user scripts'''.&lt;br /&gt;
&lt;br /&gt;
Initially, a single Lua script is supported. But more might follow. &lt;br /&gt;
&lt;br /&gt;
== User Program Requirements ==&lt;br /&gt;
The user program/script MUST contain the following functions;&lt;br /&gt;
&lt;br /&gt;
== Limits in Lua ==&lt;br /&gt;
&lt;br /&gt;
== Host API ==&lt;br /&gt;
&lt;br /&gt;
  event(event_id, value)&lt;br /&gt;
  publish(event, value)&lt;br /&gt;
  subscribe(event_type, value)&lt;br /&gt;
  unsubscribe(event_type)&lt;br /&gt;
  &lt;br /&gt;
  is_type(event_id, event_type)&lt;br /&gt;
&lt;br /&gt;
Event Types&lt;br /&gt;
  TIME_PERIOD&lt;br /&gt;
  COUNTER&lt;br /&gt;
  ERROR_CODE&lt;br /&gt;
  MEASURED_VALUE&lt;br /&gt;
  COMPUTED_VALUE&lt;br /&gt;
  SETPOINT&lt;br /&gt;
  MIN_VALUE&lt;br /&gt;
  MAX_VALUE&lt;br /&gt;
  LOW_THRESHOLD&lt;br /&gt;
  HIGH_THRESHOLD&lt;br /&gt;
  RUN_INDICATION&lt;br /&gt;
  ALARM_INDICATION&lt;br /&gt;
  RGB_SET&lt;br /&gt;
&lt;br /&gt;
== Example 1 - Blinky ==&lt;br /&gt;
&lt;br /&gt;
  do&lt;br /&gt;
    local next=0&lt;br /&gt;
    local state=0&lt;br /&gt;
  &lt;br /&gt;
    local function tick(now)&lt;br /&gt;
      if next &amp;lt; now then&lt;br /&gt;
        -- publish() is the main way to interact with the system&lt;br /&gt;
        -- Event type RGB_SET is making a request to set the RGB LED to the color value&lt;br /&gt;
        -- in the second argument, and that value is equal to (r &amp;lt;&amp;lt; 16 | g &amp;lt;&amp;lt; 8 | b)&lt;br /&gt;
        -- Negative colors are predefined colors, currently;&lt;br /&gt;
        --   -1  OK       (typically Green)&lt;br /&gt;
        --   -2  WARNING  (typically Yellow)&lt;br /&gt;
        --   -3  ERROR    (typically Red)&lt;br /&gt;
        --   -4  INFO     (typically Cyan)&lt;br /&gt;
        publish( RGB_SET, -state)&lt;br /&gt;
        state = (state + 1) % 5&lt;br /&gt;
        next = now + 300&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    function init()&lt;br /&gt;
      subscribe(TIME_PERIOD, 250)&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    function event(event_id, value)&lt;br /&gt;
      if is_type(event_id, TIME_PERIOD) then&lt;br /&gt;
        tick(value)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    function loaded()&lt;br /&gt;
      publish(RGB_SET, 0)&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    function unloading()&lt;br /&gt;
      publish(RGB_SET, 0)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== Example 2 - Toggle SSR in slot 5 output 1 at 1Hz and output 2 at 5Hz ==&lt;br /&gt;
&lt;br /&gt;
== Example 3 - Set Analog Output 1 in Slot 4 ==&lt;br /&gt;
&lt;br /&gt;
== Example 4 - Raise an Alarm condition ==&lt;br /&gt;
&lt;br /&gt;
== Example 5 - Get Analog Input 2 in slot 1 ==&lt;br /&gt;
&lt;br /&gt;
== Example 6 - Level check == &lt;br /&gt;
Check every minute if Analog Input 2 in slot 2 is &amp;gt;10mA, if so set SSR output 1, and if input &amp;lt; 5mA turn it off.&lt;br /&gt;
&lt;br /&gt;
= Historical =&lt;br /&gt;
The Colibri Runtime is the custom firmware that is running on Colibri MCUs, an application in [[Colibri Zephyr]] orchestrating the hardware resources, WebAssembly engines with I/O drivers and user programs.&lt;br /&gt;
&lt;br /&gt;
NOTE: running in individual WebAssembly instances turned out to be more stressful than useful, so that thread has been closed but kept on this Wiki for historical purposes.&lt;br /&gt;
&lt;br /&gt;
== Development == &lt;br /&gt;
[[Colibri EEPROM Layout]]&lt;br /&gt;
&lt;br /&gt;
[[Colibri WebAssembly Notes]]&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Colibri_Runtime&amp;diff=7550</id>
		<title>Colibri Runtime</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Colibri_Runtime&amp;diff=7550"/>
		<updated>2026-05-12T04:52:55Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* Example 1 - Blinky */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Colibri Runtime is the custom firmware that is running on Colibri MCUs, an application in [[Colibri Zephyr]] orchestrating the hardware resources, I/O drivers and Lua '''user scripts'''.&lt;br /&gt;
&lt;br /&gt;
Initially, a single Lua script is supported. But more might follow. &lt;br /&gt;
&lt;br /&gt;
== User Program Requirements ==&lt;br /&gt;
The user program/script MUST contain the following functions;&lt;br /&gt;
&lt;br /&gt;
== Limits in Lua ==&lt;br /&gt;
&lt;br /&gt;
== Host API ==&lt;br /&gt;
&lt;br /&gt;
  event(event_id, value)&lt;br /&gt;
  publish(event, value)&lt;br /&gt;
  subscribe(event_type, value)&lt;br /&gt;
  unsubscribe(event_type)&lt;br /&gt;
  &lt;br /&gt;
  is_type(event_id, event_type)&lt;br /&gt;
&lt;br /&gt;
Event Types&lt;br /&gt;
  TIME_PERIOD&lt;br /&gt;
  COUNTER&lt;br /&gt;
  ERROR_CODE&lt;br /&gt;
  MEASURED_VALUE&lt;br /&gt;
  COMPUTED_VALUE&lt;br /&gt;
  SETPOINT&lt;br /&gt;
  MIN_VALUE&lt;br /&gt;
  MAX_VALUE&lt;br /&gt;
  LOW_THRESHOLD&lt;br /&gt;
  HIGH_THRESHOLD&lt;br /&gt;
  RUN_INDICATION&lt;br /&gt;
  ALARM_INDICATION&lt;br /&gt;
  RGB_SET&lt;br /&gt;
&lt;br /&gt;
== Example 1 - Blinky ==&lt;br /&gt;
&lt;br /&gt;
  do&lt;br /&gt;
    local next=0&lt;br /&gt;
    local state=0&lt;br /&gt;
  &lt;br /&gt;
    local function tick(now)&lt;br /&gt;
      if next &amp;lt; now then&lt;br /&gt;
        -- publish() is the main way to interact with the system&lt;br /&gt;
        -- Event type RGB_SET is making a request to set the RGB LED to the color value&lt;br /&gt;
        -- in the second argument, and that value is equal to (r &amp;lt;&amp;lt; 16 | g &amp;lt;&amp;lt; 8 | b)&lt;br /&gt;
        -- Negative colors are predefined colors, currently;&lt;br /&gt;
        --   -1  OK       (typically Green)&lt;br /&gt;
        --   -2  WARNING  (typically Yellow)&lt;br /&gt;
        --   -3  ERROR    (typically Red)&lt;br /&gt;
        --   -4  INFO     (typically Cyan)&lt;br /&gt;
        publish( RGB_SET, -state)&lt;br /&gt;
        state = (state + 1) % 5&lt;br /&gt;
        next = now + 300&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    function init()&lt;br /&gt;
      subscribe(TIME_PERIOD, 250)&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    function event(event_id, value)&lt;br /&gt;
      if is_type(event_id, TIME_PERIOD) then&lt;br /&gt;
        tick(value)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    function loaded()&lt;br /&gt;
      publish(RGB_SET, 0)&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    function unloading()&lt;br /&gt;
      publish(RGB_SET, 0)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
== Example 2 - Toggle SSR in slot 5 output 1 at 1Hz and output 2 at 5Hz ==&lt;br /&gt;
&lt;br /&gt;
== Example 3 - Set Analog Output 1 in Slot 4 ==&lt;br /&gt;
&lt;br /&gt;
== Example 4 - Raise an Alarm condition ==&lt;br /&gt;
&lt;br /&gt;
== Example 5 - Get Analog Input 2 in slot 1 ==&lt;br /&gt;
&lt;br /&gt;
== Example 6 - Check every minute if Analog Input 2 in slot 2 is &amp;gt;10mA, if so set SSR output 1, and if input &amp;lt; 5mA turn it off.&lt;br /&gt;
&lt;br /&gt;
= Historical =&lt;br /&gt;
The Colibri Runtime is the custom firmware that is running on Colibri MCUs, an application in [[Colibri Zephyr]] orchestrating the hardware resources, WebAssembly engines with I/O drivers and user programs.&lt;br /&gt;
&lt;br /&gt;
NOTE: running in individual WebAssembly instances turned out to be more stressful than useful, so that thread has been closed but kept on this Wiki for historical purposes.&lt;br /&gt;
&lt;br /&gt;
== Development == &lt;br /&gt;
[[Colibri EEPROM Layout]]&lt;br /&gt;
&lt;br /&gt;
[[Colibri WebAssembly Notes]]&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Colibri_Runtime&amp;diff=7549</id>
		<title>Colibri Runtime</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Colibri_Runtime&amp;diff=7549"/>
		<updated>2026-05-12T04:46:52Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* Example 1 - Blinky */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Colibri Runtime is the custom firmware that is running on Colibri MCUs, an application in [[Colibri Zephyr]] orchestrating the hardware resources, I/O drivers and Lua '''user scripts'''.&lt;br /&gt;
&lt;br /&gt;
Initially, a single Lua script is supported. But more might follow. &lt;br /&gt;
&lt;br /&gt;
== User Program Requirements ==&lt;br /&gt;
The user program/script MUST contain the following functions;&lt;br /&gt;
&lt;br /&gt;
== Limits in Lua ==&lt;br /&gt;
&lt;br /&gt;
== Host API ==&lt;br /&gt;
&lt;br /&gt;
  event(event_id, value)&lt;br /&gt;
  publish(event, value)&lt;br /&gt;
  subscribe(event_type, value)&lt;br /&gt;
  unsubscribe(event_type)&lt;br /&gt;
  &lt;br /&gt;
  is_type(event_id, event_type)&lt;br /&gt;
&lt;br /&gt;
Event Types&lt;br /&gt;
  TIME_PERIOD&lt;br /&gt;
  COUNTER&lt;br /&gt;
  ERROR_CODE&lt;br /&gt;
  MEASURED_VALUE&lt;br /&gt;
  COMPUTED_VALUE&lt;br /&gt;
  SETPOINT&lt;br /&gt;
  MIN_VALUE&lt;br /&gt;
  MAX_VALUE&lt;br /&gt;
  LOW_THRESHOLD&lt;br /&gt;
  HIGH_THRESHOLD&lt;br /&gt;
  RUN_INDICATION&lt;br /&gt;
  ALARM_INDICATION&lt;br /&gt;
  RGB_SET&lt;br /&gt;
&lt;br /&gt;
== Example 1 - Blinky ==&lt;br /&gt;
&lt;br /&gt;
  do&lt;br /&gt;
    local next=0&lt;br /&gt;
    local state=0&lt;br /&gt;
  &lt;br /&gt;
    local function tick(now)&lt;br /&gt;
      if next &amp;lt; now then&lt;br /&gt;
        -- publish() is the main way to interact with the system&lt;br /&gt;
        -- Event type RGB_SET is making a request to set the RGB LED to the color value&lt;br /&gt;
        -- in the second argument, and that value is equal to (r &amp;lt;&amp;lt; 16 | g &amp;lt;&amp;lt; 8 | b)&lt;br /&gt;
        -- Negative colors are predefined colors, currently;&lt;br /&gt;
        --   -1  OK       (typically Green)&lt;br /&gt;
        --   -2  WARNING  (typically Yellow)&lt;br /&gt;
        --   -3  ERROR    (typically Red)&lt;br /&gt;
        --   -4  INFO     (typically Cyan)&lt;br /&gt;
        publish( RGB_SET, -state)&lt;br /&gt;
        state = (state + 1) % 5&lt;br /&gt;
        next = now + 300&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    function init()&lt;br /&gt;
      subscribe(TIME_PERIOD, 250)&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    function event(event_id, value)&lt;br /&gt;
      if is_type(event_id, TIME_PERIOD) then&lt;br /&gt;
        tick(value)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    function loaded()&lt;br /&gt;
      publish(RGB_SET, 0)&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    function unloading()&lt;br /&gt;
      publish(RGB_SET, 0)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
= Historical =&lt;br /&gt;
The Colibri Runtime is the custom firmware that is running on Colibri MCUs, an application in [[Colibri Zephyr]] orchestrating the hardware resources, WebAssembly engines with I/O drivers and user programs.&lt;br /&gt;
&lt;br /&gt;
NOTE: running in individual WebAssembly instances turned out to be more stressful than useful, so that thread has been closed but kept on this Wiki for historical purposes.&lt;br /&gt;
&lt;br /&gt;
== Development == &lt;br /&gt;
[[Colibri EEPROM Layout]]&lt;br /&gt;
&lt;br /&gt;
[[Colibri WebAssembly Notes]]&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Colibri_Runtime&amp;diff=7548</id>
		<title>Colibri Runtime</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Colibri_Runtime&amp;diff=7548"/>
		<updated>2026-05-12T04:39:57Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* Example 1 - Blinky */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Colibri Runtime is the custom firmware that is running on Colibri MCUs, an application in [[Colibri Zephyr]] orchestrating the hardware resources, I/O drivers and Lua '''user scripts'''.&lt;br /&gt;
&lt;br /&gt;
Initially, a single Lua script is supported. But more might follow. &lt;br /&gt;
&lt;br /&gt;
== User Program Requirements ==&lt;br /&gt;
The user program/script MUST contain the following functions;&lt;br /&gt;
&lt;br /&gt;
== Limits in Lua ==&lt;br /&gt;
&lt;br /&gt;
== Host API ==&lt;br /&gt;
&lt;br /&gt;
  event(event_id, value)&lt;br /&gt;
  publish(event, value)&lt;br /&gt;
  subscribe(event_type, value)&lt;br /&gt;
  unsubscribe(event_type)&lt;br /&gt;
  &lt;br /&gt;
  is_type(event_id, event_type)&lt;br /&gt;
&lt;br /&gt;
Event Types&lt;br /&gt;
  TIME_PERIOD&lt;br /&gt;
  COUNTER&lt;br /&gt;
  ERROR_CODE&lt;br /&gt;
  MEASURED_VALUE&lt;br /&gt;
  COMPUTED_VALUE&lt;br /&gt;
  SETPOINT&lt;br /&gt;
  MIN_VALUE&lt;br /&gt;
  MAX_VALUE&lt;br /&gt;
  LOW_THRESHOLD&lt;br /&gt;
  HIGH_THRESHOLD&lt;br /&gt;
  RUN_INDICATION&lt;br /&gt;
  ALARM_INDICATION&lt;br /&gt;
  RGB_SET&lt;br /&gt;
&lt;br /&gt;
== Example 1 - Blinky ==&lt;br /&gt;
&lt;br /&gt;
  do&lt;br /&gt;
    local next=0&lt;br /&gt;
    local state=0&lt;br /&gt;
  &lt;br /&gt;
    local function tick(now)&lt;br /&gt;
      if next &amp;lt; now then&lt;br /&gt;
        publish( RGB_SET, -state)&lt;br /&gt;
        state = (state + 1) % 5&lt;br /&gt;
        next = now + 300&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    function init()&lt;br /&gt;
      subscribe(TIME_PERIOD, 250)&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    function event(event_id, value)&lt;br /&gt;
      if is_type(event_id, TIME_PERIOD) then&lt;br /&gt;
        tick(value)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    function loaded()&lt;br /&gt;
      publish(RGB_SET, 0)&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    function unloading()&lt;br /&gt;
      publish(RGB_SET, 0)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
= Historical =&lt;br /&gt;
The Colibri Runtime is the custom firmware that is running on Colibri MCUs, an application in [[Colibri Zephyr]] orchestrating the hardware resources, WebAssembly engines with I/O drivers and user programs.&lt;br /&gt;
&lt;br /&gt;
NOTE: running in individual WebAssembly instances turned out to be more stressful than useful, so that thread has been closed but kept on this Wiki for historical purposes.&lt;br /&gt;
&lt;br /&gt;
== Development == &lt;br /&gt;
[[Colibri EEPROM Layout]]&lt;br /&gt;
&lt;br /&gt;
[[Colibri WebAssembly Notes]]&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Colibri_Runtime&amp;diff=7547</id>
		<title>Colibri Runtime</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Colibri_Runtime&amp;diff=7547"/>
		<updated>2026-05-12T04:39:17Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* Example 1 - Blinky */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Colibri Runtime is the custom firmware that is running on Colibri MCUs, an application in [[Colibri Zephyr]] orchestrating the hardware resources, I/O drivers and Lua '''user scripts'''.&lt;br /&gt;
&lt;br /&gt;
Initially, a single Lua script is supported. But more might follow. &lt;br /&gt;
&lt;br /&gt;
== User Program Requirements ==&lt;br /&gt;
The user program/script MUST contain the following functions;&lt;br /&gt;
&lt;br /&gt;
== Limits in Lua ==&lt;br /&gt;
&lt;br /&gt;
== Host API ==&lt;br /&gt;
&lt;br /&gt;
  event(event_id, value)&lt;br /&gt;
  publish(event, value)&lt;br /&gt;
  subscribe(event_type, value)&lt;br /&gt;
  unsubscribe(event_type)&lt;br /&gt;
  &lt;br /&gt;
  is_type(event_id, event_type)&lt;br /&gt;
&lt;br /&gt;
Event Types&lt;br /&gt;
  TIME_PERIOD&lt;br /&gt;
  COUNTER&lt;br /&gt;
  ERROR_CODE&lt;br /&gt;
  MEASURED_VALUE&lt;br /&gt;
  COMPUTED_VALUE&lt;br /&gt;
  SETPOINT&lt;br /&gt;
  MIN_VALUE&lt;br /&gt;
  MAX_VALUE&lt;br /&gt;
  LOW_THRESHOLD&lt;br /&gt;
  HIGH_THRESHOLD&lt;br /&gt;
  RUN_INDICATION&lt;br /&gt;
  ALARM_INDICATION&lt;br /&gt;
  RGB_SET&lt;br /&gt;
&lt;br /&gt;
== Example 1 - Blinky ==&lt;br /&gt;
&lt;br /&gt;
  do&lt;br /&gt;
    local next=0&lt;br /&gt;
    local state=0&lt;br /&gt;
  &lt;br /&gt;
    local function tick()&lt;br /&gt;
      if next &amp;lt; value then&lt;br /&gt;
        publish( RGB_SET, -state)&lt;br /&gt;
        state = (state + 1) % 5&lt;br /&gt;
        next = value + 300&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    function init()&lt;br /&gt;
      subscribe(TIME_PERIOD, 250)&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    function event(event_id, value)&lt;br /&gt;
      if is_type(event_id, TIME_PERIOD) then&lt;br /&gt;
        tick()&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    function loaded()&lt;br /&gt;
      publish(RGB_SET, 0)&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    function unloading()&lt;br /&gt;
      publish(RGB_SET, 0)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
= Historical =&lt;br /&gt;
The Colibri Runtime is the custom firmware that is running on Colibri MCUs, an application in [[Colibri Zephyr]] orchestrating the hardware resources, WebAssembly engines with I/O drivers and user programs.&lt;br /&gt;
&lt;br /&gt;
NOTE: running in individual WebAssembly instances turned out to be more stressful than useful, so that thread has been closed but kept on this Wiki for historical purposes.&lt;br /&gt;
&lt;br /&gt;
== Development == &lt;br /&gt;
[[Colibri EEPROM Layout]]&lt;br /&gt;
&lt;br /&gt;
[[Colibri WebAssembly Notes]]&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Colibri_Runtime&amp;diff=7546</id>
		<title>Colibri Runtime</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Colibri_Runtime&amp;diff=7546"/>
		<updated>2026-05-12T04:37:49Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* Example 1 - Blinky */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Colibri Runtime is the custom firmware that is running on Colibri MCUs, an application in [[Colibri Zephyr]] orchestrating the hardware resources, I/O drivers and Lua '''user scripts'''.&lt;br /&gt;
&lt;br /&gt;
Initially, a single Lua script is supported. But more might follow. &lt;br /&gt;
&lt;br /&gt;
== User Program Requirements ==&lt;br /&gt;
The user program/script MUST contain the following functions;&lt;br /&gt;
&lt;br /&gt;
== Limits in Lua ==&lt;br /&gt;
&lt;br /&gt;
== Host API ==&lt;br /&gt;
&lt;br /&gt;
  event(event_id, value)&lt;br /&gt;
  publish(event, value)&lt;br /&gt;
  subscribe(event_type, value)&lt;br /&gt;
  unsubscribe(event_type)&lt;br /&gt;
  &lt;br /&gt;
  is_type(event_id, event_type)&lt;br /&gt;
&lt;br /&gt;
Event Types&lt;br /&gt;
  TIME_PERIOD&lt;br /&gt;
  COUNTER&lt;br /&gt;
  ERROR_CODE&lt;br /&gt;
  MEASURED_VALUE&lt;br /&gt;
  COMPUTED_VALUE&lt;br /&gt;
  SETPOINT&lt;br /&gt;
  MIN_VALUE&lt;br /&gt;
  MAX_VALUE&lt;br /&gt;
  LOW_THRESHOLD&lt;br /&gt;
  HIGH_THRESHOLD&lt;br /&gt;
  RUN_INDICATION&lt;br /&gt;
  ALARM_INDICATION&lt;br /&gt;
  RGB_SET&lt;br /&gt;
&lt;br /&gt;
== Example 1 - Blinky ==&lt;br /&gt;
&lt;br /&gt;
  do&lt;br /&gt;
    local next=0&lt;br /&gt;
    local state=0&lt;br /&gt;
  &lt;br /&gt;
    local function tick()&lt;br /&gt;
      if next &amp;lt; value then&lt;br /&gt;
        publish( RGB_SET, -state)&lt;br /&gt;
        state = (state + 1) % 5&lt;br /&gt;
        next = value + 300&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    function init()&lt;br /&gt;
      subscribe(TIME_PERIOD, 250)&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    function event (event_id, value)&lt;br /&gt;
      if is_type(event_id, TIME_PERIOD) then&lt;br /&gt;
        tick()&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    function loaded()&lt;br /&gt;
      publish(RGB_SET, 0)&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    function unloading()&lt;br /&gt;
      publish(RGB_SET, 0)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
= Historical =&lt;br /&gt;
The Colibri Runtime is the custom firmware that is running on Colibri MCUs, an application in [[Colibri Zephyr]] orchestrating the hardware resources, WebAssembly engines with I/O drivers and user programs.&lt;br /&gt;
&lt;br /&gt;
NOTE: running in individual WebAssembly instances turned out to be more stressful than useful, so that thread has been closed but kept on this Wiki for historical purposes.&lt;br /&gt;
&lt;br /&gt;
== Development == &lt;br /&gt;
[[Colibri EEPROM Layout]]&lt;br /&gt;
&lt;br /&gt;
[[Colibri WebAssembly Notes]]&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Colibri_Runtime&amp;diff=7545</id>
		<title>Colibri Runtime</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Colibri_Runtime&amp;diff=7545"/>
		<updated>2026-05-12T04:37:23Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* Host API */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Colibri Runtime is the custom firmware that is running on Colibri MCUs, an application in [[Colibri Zephyr]] orchestrating the hardware resources, I/O drivers and Lua '''user scripts'''.&lt;br /&gt;
&lt;br /&gt;
Initially, a single Lua script is supported. But more might follow. &lt;br /&gt;
&lt;br /&gt;
== User Program Requirements ==&lt;br /&gt;
The user program/script MUST contain the following functions;&lt;br /&gt;
&lt;br /&gt;
== Limits in Lua ==&lt;br /&gt;
&lt;br /&gt;
== Host API ==&lt;br /&gt;
&lt;br /&gt;
  event(event_id, value)&lt;br /&gt;
  publish(event, value)&lt;br /&gt;
  subscribe(event_type, value)&lt;br /&gt;
  unsubscribe(event_type)&lt;br /&gt;
  &lt;br /&gt;
  is_type(event_id, event_type)&lt;br /&gt;
&lt;br /&gt;
Event Types&lt;br /&gt;
  TIME_PERIOD&lt;br /&gt;
  COUNTER&lt;br /&gt;
  ERROR_CODE&lt;br /&gt;
  MEASURED_VALUE&lt;br /&gt;
  COMPUTED_VALUE&lt;br /&gt;
  SETPOINT&lt;br /&gt;
  MIN_VALUE&lt;br /&gt;
  MAX_VALUE&lt;br /&gt;
  LOW_THRESHOLD&lt;br /&gt;
  HIGH_THRESHOLD&lt;br /&gt;
  RUN_INDICATION&lt;br /&gt;
  ALARM_INDICATION&lt;br /&gt;
  RGB_SET&lt;br /&gt;
&lt;br /&gt;
== Example 1 - Blinky ==&lt;br /&gt;
&lt;br /&gt;
  do&lt;br /&gt;
    local next=0&lt;br /&gt;
    local state=0&lt;br /&gt;
  &lt;br /&gt;
    local function tick()&lt;br /&gt;
      if next &amp;lt; value then&lt;br /&gt;
        publish( RGB_SET(), -state)&lt;br /&gt;
        state = (state + 1) % 5&lt;br /&gt;
        next = value + 300&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    function init()&lt;br /&gt;
      subscribe(TIME_PERIOD(), 250)&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    function event (event_id, value)&lt;br /&gt;
      if is_type(event_id, TIME_PERIOD) then&lt;br /&gt;
        tick()&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    function loaded()&lt;br /&gt;
      publish(RGB_SET(), 0)&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    function unloading()&lt;br /&gt;
      publish(RGB_SET(), 0)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Historical =&lt;br /&gt;
The Colibri Runtime is the custom firmware that is running on Colibri MCUs, an application in [[Colibri Zephyr]] orchestrating the hardware resources, WebAssembly engines with I/O drivers and user programs.&lt;br /&gt;
&lt;br /&gt;
NOTE: running in individual WebAssembly instances turned out to be more stressful than useful, so that thread has been closed but kept on this Wiki for historical purposes.&lt;br /&gt;
&lt;br /&gt;
== Development == &lt;br /&gt;
[[Colibri EEPROM Layout]]&lt;br /&gt;
&lt;br /&gt;
[[Colibri WebAssembly Notes]]&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Colibri_Runtime&amp;diff=7544</id>
		<title>Colibri Runtime</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Colibri_Runtime&amp;diff=7544"/>
		<updated>2026-05-12T04:10:00Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* Host API */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Colibri Runtime is the custom firmware that is running on Colibri MCUs, an application in [[Colibri Zephyr]] orchestrating the hardware resources, I/O drivers and Lua '''user scripts'''.&lt;br /&gt;
&lt;br /&gt;
Initially, a single Lua script is supported. But more might follow. &lt;br /&gt;
&lt;br /&gt;
== User Program Requirements ==&lt;br /&gt;
The user program/script MUST contain the following functions;&lt;br /&gt;
&lt;br /&gt;
== Limits in Lua ==&lt;br /&gt;
&lt;br /&gt;
== Host API ==&lt;br /&gt;
&lt;br /&gt;
  event(event_id, value)&lt;br /&gt;
  publish(event, value)&lt;br /&gt;
  subscribe(event_type, value)&lt;br /&gt;
  unsubscribe(event_type)&lt;br /&gt;
  &lt;br /&gt;
  is_type(event_id, event_type)&lt;br /&gt;
&lt;br /&gt;
Event Types&lt;br /&gt;
  TIME_PERIOD()&lt;br /&gt;
  COUNTER()&lt;br /&gt;
  ERROR_CODE()&lt;br /&gt;
  MEASURED_VALUE()&lt;br /&gt;
  COMPUTED_VALUE()&lt;br /&gt;
  SETPOINT()&lt;br /&gt;
  MIN_VALUE()&lt;br /&gt;
  MAX_VALUE()&lt;br /&gt;
  LOW_THRESHOLD()&lt;br /&gt;
  HIGH_THRESHOLD()&lt;br /&gt;
  RUN_INDICATION()&lt;br /&gt;
  ALARM_INDICATION()&lt;br /&gt;
  RGB_SET()&lt;br /&gt;
&lt;br /&gt;
== Example 1 - Blinky ==&lt;br /&gt;
&lt;br /&gt;
  do&lt;br /&gt;
    local next=0&lt;br /&gt;
    local state=0&lt;br /&gt;
  &lt;br /&gt;
    local function tick()&lt;br /&gt;
      if next &amp;lt; value then&lt;br /&gt;
        publish( RGB_SET(), -state)&lt;br /&gt;
        state = (state + 1) % 5&lt;br /&gt;
        next = value + 300&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    function init()&lt;br /&gt;
      subscribe(TIME_PERIOD(), 250)&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    function event (event_id, value)&lt;br /&gt;
      if is_type(event_id, TIME_PERIOD) then&lt;br /&gt;
        tick()&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    function loaded()&lt;br /&gt;
      publish(RGB_SET(), 0)&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    function unloading()&lt;br /&gt;
      publish(RGB_SET(), 0)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Historical =&lt;br /&gt;
The Colibri Runtime is the custom firmware that is running on Colibri MCUs, an application in [[Colibri Zephyr]] orchestrating the hardware resources, WebAssembly engines with I/O drivers and user programs.&lt;br /&gt;
&lt;br /&gt;
NOTE: running in individual WebAssembly instances turned out to be more stressful than useful, so that thread has been closed but kept on this Wiki for historical purposes.&lt;br /&gt;
&lt;br /&gt;
== Development == &lt;br /&gt;
[[Colibri EEPROM Layout]]&lt;br /&gt;
&lt;br /&gt;
[[Colibri WebAssembly Notes]]&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Colibri_Runtime&amp;diff=7543</id>
		<title>Colibri Runtime</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Colibri_Runtime&amp;diff=7543"/>
		<updated>2026-05-12T04:09:41Z</updated>

		<summary type="html">&lt;p&gt;Niclas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Colibri Runtime is the custom firmware that is running on Colibri MCUs, an application in [[Colibri Zephyr]] orchestrating the hardware resources, I/O drivers and Lua '''user scripts'''.&lt;br /&gt;
&lt;br /&gt;
Initially, a single Lua script is supported. But more might follow. &lt;br /&gt;
&lt;br /&gt;
== User Program Requirements ==&lt;br /&gt;
The user program/script MUST contain the following functions;&lt;br /&gt;
&lt;br /&gt;
== Limits in Lua ==&lt;br /&gt;
&lt;br /&gt;
== Host API ==&lt;br /&gt;
&lt;br /&gt;
  event(event_id, value)&lt;br /&gt;
  publish(event, value)&lt;br /&gt;
  subscribe(event_type, value)&lt;br /&gt;
  unsubscribe(event_type)&lt;br /&gt;
  &lt;br /&gt;
  is_type(event_id, event_type)&lt;br /&gt;
&lt;br /&gt;
  // Event Types&lt;br /&gt;
  TIME_PERIOD()&lt;br /&gt;
  COUNTER()&lt;br /&gt;
  ERROR_CODE()&lt;br /&gt;
  MEASURED_VALUE()&lt;br /&gt;
  COMPUTED_VALUE()&lt;br /&gt;
  SETPOINT()&lt;br /&gt;
  MIN_VALUE()&lt;br /&gt;
  MAX_VALUE()&lt;br /&gt;
  LOW_THRESHOLD()&lt;br /&gt;
  HIGH_THRESHOLD()&lt;br /&gt;
  RUN_INDICATION()&lt;br /&gt;
  ALARM_INDICATION()&lt;br /&gt;
  RGB_SET()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Example 1 - Blinky ==&lt;br /&gt;
&lt;br /&gt;
  do&lt;br /&gt;
    local next=0&lt;br /&gt;
    local state=0&lt;br /&gt;
  &lt;br /&gt;
    local function tick()&lt;br /&gt;
      if next &amp;lt; value then&lt;br /&gt;
        publish( RGB_SET(), -state)&lt;br /&gt;
        state = (state + 1) % 5&lt;br /&gt;
        next = value + 300&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    function init()&lt;br /&gt;
      subscribe(TIME_PERIOD(), 250)&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    function event (event_id, value)&lt;br /&gt;
      if is_type(event_id, TIME_PERIOD) then&lt;br /&gt;
        tick()&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    function loaded()&lt;br /&gt;
      publish(RGB_SET(), 0)&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    function unloading()&lt;br /&gt;
      publish(RGB_SET(), 0)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Historical =&lt;br /&gt;
The Colibri Runtime is the custom firmware that is running on Colibri MCUs, an application in [[Colibri Zephyr]] orchestrating the hardware resources, WebAssembly engines with I/O drivers and user programs.&lt;br /&gt;
&lt;br /&gt;
NOTE: running in individual WebAssembly instances turned out to be more stressful than useful, so that thread has been closed but kept on this Wiki for historical purposes.&lt;br /&gt;
&lt;br /&gt;
== Development == &lt;br /&gt;
[[Colibri EEPROM Layout]]&lt;br /&gt;
&lt;br /&gt;
[[Colibri WebAssembly Notes]]&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Colibri_Runtime&amp;diff=7542</id>
		<title>Colibri Runtime</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Colibri_Runtime&amp;diff=7542"/>
		<updated>2026-05-12T04:00:50Z</updated>

		<summary type="html">&lt;p&gt;Niclas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Colibri Runtime is the custom firmware that is running on Colibri MCUs, an application in [[Colibri Zephyr]] orchestrating the hardware resources, I/O drivers and Lua '''user scripts'''.&lt;br /&gt;
&lt;br /&gt;
Initially, a single Lua script is supported. But more might follow. &lt;br /&gt;
&lt;br /&gt;
== User Program Requirements ==&lt;br /&gt;
The user program/script MUST contain the following functions;&lt;br /&gt;
&lt;br /&gt;
== Limits in Lua ==&lt;br /&gt;
&lt;br /&gt;
== Host API ==&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
= Legacy =&lt;br /&gt;
The Colibri Runtime is the custom firmware that is running on Colibri MCUs, an application in [[Colibri Zephyr]] orchestrating the hardware resources, WebAssembly engines with I/O drivers and user programs.&lt;br /&gt;
&lt;br /&gt;
NOTE: running in individual WebAssembly instances turned out to be more stressful than useful, so that thread has been closed but kept on this Wiki for historical purposes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
&lt;br /&gt;
  do&lt;br /&gt;
    local next=0&lt;br /&gt;
    local state=0&lt;br /&gt;
&lt;br /&gt;
    local function tick()&lt;br /&gt;
      if next &amp;lt; value then&lt;br /&gt;
        publish( create_event(RGB_SET, -state)&lt;br /&gt;
        state = (state + 1) % 5&lt;br /&gt;
        next = value + 300&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    function init()&lt;br /&gt;
      subscribe(TIME_PERIOD, 250)&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    function event (event_id, value)&lt;br /&gt;
      if is_type(event_id, TIME_PERIOD) then&lt;br /&gt;
        tick()&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  &lt;br /&gt;
    function loaded()&lt;br /&gt;
      publish(create_event(RGB_SET, 0)&lt;br /&gt;
    end\n\&lt;br /&gt;
  &lt;br /&gt;
    function unloading()&lt;br /&gt;
      publish(create_event(RGB_SET, 0)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Development == &lt;br /&gt;
[[Colibri EEPROM Layout]]&lt;br /&gt;
&lt;br /&gt;
[[Colibri WebAssembly Notes]]&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Colibri_EEPROM_Layout&amp;diff=7531</id>
		<title>Colibri EEPROM Layout</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Colibri_EEPROM_Layout&amp;diff=7531"/>
		<updated>2026-05-11T00:10:08Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* Vendor ID */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;All the Colibri I/O modules come with a 1Mbit EEPROM on board, that serves to store a few different things;&lt;br /&gt;
&lt;br /&gt;
* Vendor, Model and Revision of 'this' board.&lt;br /&gt;
* Calibration parameters needed to compensate for hardware tolerances.&lt;br /&gt;
* Test report (if any) from factory.&lt;br /&gt;
* The ''driver(s)'' (i.e. code) of the board, to be executed in the MCU module on behalf of the board.&lt;br /&gt;
* Any additional parameters, configuration that should survive over time.&lt;br /&gt;
* Any storage space an on-module co-MCU needs.&lt;br /&gt;
&lt;br /&gt;
= Memory Layout =&lt;br /&gt;
&lt;br /&gt;
{| class=wikitable&lt;br /&gt;
|-&lt;br /&gt;
! Address&lt;br /&gt;
! Length&lt;br /&gt;
! Description &lt;br /&gt;
|-&lt;br /&gt;
| 0x0000&lt;br /&gt;
| 4&lt;br /&gt;
| Contains the value 0xdeadbabe to indicate that it has been initialized.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0004&lt;br /&gt;
| 4&lt;br /&gt;
| Serial Number&lt;br /&gt;
|-&lt;br /&gt;
| 0x0008&lt;br /&gt;
| 8&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0010&lt;br /&gt;
| 4&lt;br /&gt;
| Vendor ID, according to table below.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0014&lt;br /&gt;
| 4&lt;br /&gt;
| Vendor Model identifier. This is specific to each vendor. Vendors are encouraged to add their tables on this page.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0018&lt;br /&gt;
| 4&lt;br /&gt;
| Vendor Hardware Revision, where revision 'A' is written as 0x00000041 and revision 'AC' is 0x00004341 &lt;br /&gt;
|-&lt;br /&gt;
| 0x001c&lt;br /&gt;
| 4&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0020&lt;br /&gt;
| 4&lt;br /&gt;
| Pointer to Vendor name, in ASCII.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0024&lt;br /&gt;
| 4&lt;br /&gt;
| Length of Vendor name&lt;br /&gt;
|-&lt;br /&gt;
| 0x0028&lt;br /&gt;
| 4&lt;br /&gt;
| Pointer to Model name, in ASCII.&lt;br /&gt;
|-&lt;br /&gt;
| 0x002c&lt;br /&gt;
| 4&lt;br /&gt;
| Length of Model name.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0030&lt;br /&gt;
| 4&lt;br /&gt;
| Pointer to Product Link&lt;br /&gt;
|-&lt;br /&gt;
| 0x0034&lt;br /&gt;
| 4&lt;br /&gt;
| Length of Product Link&lt;br /&gt;
|-&lt;br /&gt;
| 0x0038&lt;br /&gt;
| 4&lt;br /&gt;
| Pointer to Documentation Link&lt;br /&gt;
|-&lt;br /&gt;
| 0x003c&lt;br /&gt;
| 4&lt;br /&gt;
| Length of Documentation Link&lt;br /&gt;
|-&lt;br /&gt;
| 0x0040&lt;br /&gt;
| 4&lt;br /&gt;
| Size of ARM PIC (Position Independent Code).&lt;br /&gt;
|-&lt;br /&gt;
| 0x0044&lt;br /&gt;
| 60&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0080&lt;br /&gt;
| 128&lt;br /&gt;
| Calibration data, see each I/O module for details&lt;br /&gt;
|-&lt;br /&gt;
| 0x0100&lt;br /&gt;
| 256&lt;br /&gt;
| Test Reports, see each I/O module for details&lt;br /&gt;
|-&lt;br /&gt;
| 0x0200&lt;br /&gt;
| 1024&lt;br /&gt;
| Text area. Links points to here, i.e. Vendor name, model name, documentation link and product link.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0600&lt;br /&gt;
| 2560&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1000&lt;br /&gt;
| 2048&lt;br /&gt;
| Driver software/code. ARM PIC&lt;br /&gt;
|-&lt;br /&gt;
| 0x1800&lt;br /&gt;
| 26624&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x8000&lt;br /&gt;
| 32768&lt;br /&gt;
| Vendor area&lt;br /&gt;
|-&lt;br /&gt;
| 0x10000&lt;br /&gt;
| 65536&lt;br /&gt;
| Reserved for co-MCU on I/O module, or vendor defined.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Vendor ID =&lt;br /&gt;
Contact us at info@currentmakers.com if you have products you want added.&lt;br /&gt;
&lt;br /&gt;
{| class=wikitable&lt;br /&gt;
|-&lt;br /&gt;
! Vendor ID&lt;br /&gt;
! Company Name&lt;br /&gt;
! Webpage&lt;br /&gt;
! Models&lt;br /&gt;
|-&lt;br /&gt;
| 0&lt;br /&gt;
| Unknown/Not defined&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| CurrentMakers&lt;br /&gt;
| https://currentmakers.com/products/colibri/&lt;br /&gt;
| &lt;br /&gt;
    {| class=wikitable&lt;br /&gt;
    |-&lt;br /&gt;
    ! Model ID&lt;br /&gt;
    ! Model Name&lt;br /&gt;
    ! Webpage&lt;br /&gt;
    |-&lt;br /&gt;
    | 0&lt;br /&gt;
    | Experiment&lt;br /&gt;
    | &lt;br /&gt;
    |-&lt;br /&gt;
    | 1&lt;br /&gt;
    | Colibri AIV&lt;br /&gt;
    | https://currentmakers.com/products/colibri/colibri-aiv/&lt;br /&gt;
    |-&lt;br /&gt;
    | 2&lt;br /&gt;
    | Colibri AIC&lt;br /&gt;
    | https://currentmakers.com/products/colibri/colibri-aic/&lt;br /&gt;
    |-&lt;br /&gt;
    | 3&lt;br /&gt;
    | Colibri AQV&lt;br /&gt;
    | https://currentmakers.com/products/colibri/colibri-aqv/&lt;br /&gt;
    |-&lt;br /&gt;
    | 4&lt;br /&gt;
    | Colibri DII&lt;br /&gt;
    | https://currentmakers.com/products/colibri/colibri-dii/&lt;br /&gt;
    |-&lt;br /&gt;
    | 5&lt;br /&gt;
    | Colibri DIO1&lt;br /&gt;
    | https://currentmakers.com/products/colibri/colibri-dio1/&lt;br /&gt;
    |-&lt;br /&gt;
    | 6&lt;br /&gt;
    | Colibri DIU&lt;br /&gt;
    | https://currentmakers.com/products/colibri/colibri-diu/&lt;br /&gt;
    |-&lt;br /&gt;
    | 7&lt;br /&gt;
    | Colibri DP1&lt;br /&gt;
    | https://currentmakers.com/products/colibri/colibri-dp1/&lt;br /&gt;
    |-&lt;br /&gt;
    | 8&lt;br /&gt;
    | Colibri FET&lt;br /&gt;
    | https://currentmakers.com/products/colibri/colibri-fet/&lt;br /&gt;
    |-&lt;br /&gt;
    | 9&lt;br /&gt;
    | Colibri PID1&lt;br /&gt;
    | https://currentmakers.com/products/colibri/colibri-pid1/&lt;br /&gt;
    |-&lt;br /&gt;
    | 10&lt;br /&gt;
    | Colibri Pt1000&lt;br /&gt;
    | https://currentmakers.com/products/colibri/colibri-pt1000/&lt;br /&gt;
    |-&lt;br /&gt;
    | 11&lt;br /&gt;
    | Colibri RS485I&lt;br /&gt;
    | https://currentmakers.com/products/colibri/colibri-rs485i/&lt;br /&gt;
    |-&lt;br /&gt;
    | 12&lt;br /&gt;
    | Colibri RS485U&lt;br /&gt;
    | https://currentmakers.com/products/colibri/colibri-rs485u/&lt;br /&gt;
    |-&lt;br /&gt;
    | 13&lt;br /&gt;
    | Colibri SSR&lt;br /&gt;
    | https://currentmakers.com/products/colibri/colibri-ssr/&lt;br /&gt;
    |-&lt;br /&gt;
    | 14&lt;br /&gt;
    | Colibri TRIAC1&lt;br /&gt;
    | https://currentmakers.com/products/colibri/colibri-triac1/&lt;br /&gt;
    |}&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Colibri_EEPROM_Layout&amp;diff=7530</id>
		<title>Colibri EEPROM Layout</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Colibri_EEPROM_Layout&amp;diff=7530"/>
		<updated>2026-05-11T00:07:58Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* Vendor ID */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;All the Colibri I/O modules come with a 1Mbit EEPROM on board, that serves to store a few different things;&lt;br /&gt;
&lt;br /&gt;
* Vendor, Model and Revision of 'this' board.&lt;br /&gt;
* Calibration parameters needed to compensate for hardware tolerances.&lt;br /&gt;
* Test report (if any) from factory.&lt;br /&gt;
* The ''driver(s)'' (i.e. code) of the board, to be executed in the MCU module on behalf of the board.&lt;br /&gt;
* Any additional parameters, configuration that should survive over time.&lt;br /&gt;
* Any storage space an on-module co-MCU needs.&lt;br /&gt;
&lt;br /&gt;
= Memory Layout =&lt;br /&gt;
&lt;br /&gt;
{| class=wikitable&lt;br /&gt;
|-&lt;br /&gt;
! Address&lt;br /&gt;
! Length&lt;br /&gt;
! Description &lt;br /&gt;
|-&lt;br /&gt;
| 0x0000&lt;br /&gt;
| 4&lt;br /&gt;
| Contains the value 0xdeadbabe to indicate that it has been initialized.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0004&lt;br /&gt;
| 4&lt;br /&gt;
| Serial Number&lt;br /&gt;
|-&lt;br /&gt;
| 0x0008&lt;br /&gt;
| 8&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0010&lt;br /&gt;
| 4&lt;br /&gt;
| Vendor ID, according to table below.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0014&lt;br /&gt;
| 4&lt;br /&gt;
| Vendor Model identifier. This is specific to each vendor. Vendors are encouraged to add their tables on this page.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0018&lt;br /&gt;
| 4&lt;br /&gt;
| Vendor Hardware Revision, where revision 'A' is written as 0x00000041 and revision 'AC' is 0x00004341 &lt;br /&gt;
|-&lt;br /&gt;
| 0x001c&lt;br /&gt;
| 4&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0020&lt;br /&gt;
| 4&lt;br /&gt;
| Pointer to Vendor name, in ASCII.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0024&lt;br /&gt;
| 4&lt;br /&gt;
| Length of Vendor name&lt;br /&gt;
|-&lt;br /&gt;
| 0x0028&lt;br /&gt;
| 4&lt;br /&gt;
| Pointer to Model name, in ASCII.&lt;br /&gt;
|-&lt;br /&gt;
| 0x002c&lt;br /&gt;
| 4&lt;br /&gt;
| Length of Model name.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0030&lt;br /&gt;
| 4&lt;br /&gt;
| Pointer to Product Link&lt;br /&gt;
|-&lt;br /&gt;
| 0x0034&lt;br /&gt;
| 4&lt;br /&gt;
| Length of Product Link&lt;br /&gt;
|-&lt;br /&gt;
| 0x0038&lt;br /&gt;
| 4&lt;br /&gt;
| Pointer to Documentation Link&lt;br /&gt;
|-&lt;br /&gt;
| 0x003c&lt;br /&gt;
| 4&lt;br /&gt;
| Length of Documentation Link&lt;br /&gt;
|-&lt;br /&gt;
| 0x0040&lt;br /&gt;
| 4&lt;br /&gt;
| Size of ARM PIC (Position Independent Code).&lt;br /&gt;
|-&lt;br /&gt;
| 0x0044&lt;br /&gt;
| 60&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0080&lt;br /&gt;
| 128&lt;br /&gt;
| Calibration data, see each I/O module for details&lt;br /&gt;
|-&lt;br /&gt;
| 0x0100&lt;br /&gt;
| 256&lt;br /&gt;
| Test Reports, see each I/O module for details&lt;br /&gt;
|-&lt;br /&gt;
| 0x0200&lt;br /&gt;
| 1024&lt;br /&gt;
| Text area. Links points to here, i.e. Vendor name, model name, documentation link and product link.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0600&lt;br /&gt;
| 2560&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1000&lt;br /&gt;
| 2048&lt;br /&gt;
| Driver software/code. ARM PIC&lt;br /&gt;
|-&lt;br /&gt;
| 0x1800&lt;br /&gt;
| 26624&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x8000&lt;br /&gt;
| 32768&lt;br /&gt;
| Vendor area&lt;br /&gt;
|-&lt;br /&gt;
| 0x10000&lt;br /&gt;
| 65536&lt;br /&gt;
| Reserved for co-MCU on I/O module, or vendor defined.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Vendor ID =&lt;br /&gt;
Contact us at info@currentmakers.com if you have products you want added.&lt;br /&gt;
&lt;br /&gt;
{| class=wikitable&lt;br /&gt;
|-&lt;br /&gt;
! ID&lt;br /&gt;
! Company&lt;br /&gt;
! Webpage&lt;br /&gt;
! Models&lt;br /&gt;
|-&lt;br /&gt;
| 0&lt;br /&gt;
| Unknown/Not defined&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| CurrentMakers&lt;br /&gt;
| https://currentmakers.com/products/colibri/&lt;br /&gt;
| &lt;br /&gt;
    {| class=wikitable&lt;br /&gt;
    |-&lt;br /&gt;
    ! ID&lt;br /&gt;
    ! Model&lt;br /&gt;
    ! Webpage&lt;br /&gt;
    |-&lt;br /&gt;
    | 0&lt;br /&gt;
    | Experiment&lt;br /&gt;
    | &lt;br /&gt;
    |-&lt;br /&gt;
    | 1&lt;br /&gt;
    | Colibri AIV&lt;br /&gt;
    | https://currentmakers.com/products/colibri/colibri-aiv/&lt;br /&gt;
    |-&lt;br /&gt;
    | 2&lt;br /&gt;
    | Colibri AIC&lt;br /&gt;
    | https://currentmakers.com/products/colibri/colibri-aic/&lt;br /&gt;
    |-&lt;br /&gt;
    | 3&lt;br /&gt;
    | Colibri AQV&lt;br /&gt;
    | https://currentmakers.com/products/colibri/colibri-aqv/&lt;br /&gt;
    |-&lt;br /&gt;
    | 4&lt;br /&gt;
    | Colibri DII&lt;br /&gt;
    | https://currentmakers.com/products/colibri/colibri-dii/&lt;br /&gt;
    |-&lt;br /&gt;
    | 5&lt;br /&gt;
    | Colibri DIO1&lt;br /&gt;
    | https://currentmakers.com/products/colibri/colibri-dio1/&lt;br /&gt;
    |-&lt;br /&gt;
    | 6&lt;br /&gt;
    | Colibri DIU&lt;br /&gt;
    | https://currentmakers.com/products/colibri/colibri-diu/&lt;br /&gt;
    |-&lt;br /&gt;
    | 7&lt;br /&gt;
    | Colibri DP1&lt;br /&gt;
    | https://currentmakers.com/products/colibri/colibri-dp1/&lt;br /&gt;
    |-&lt;br /&gt;
    | 8&lt;br /&gt;
    | Colibri FET&lt;br /&gt;
    | https://currentmakers.com/products/colibri/colibri-fet/&lt;br /&gt;
    |-&lt;br /&gt;
    | 9&lt;br /&gt;
    | Colibri PID1&lt;br /&gt;
    | https://currentmakers.com/products/colibri/colibri-pid1/&lt;br /&gt;
    |-&lt;br /&gt;
    | 10&lt;br /&gt;
    | Colibri Pt1000&lt;br /&gt;
    | https://currentmakers.com/products/colibri/colibri-pt1000/&lt;br /&gt;
    |-&lt;br /&gt;
    | 11&lt;br /&gt;
    | Colibri RS485I&lt;br /&gt;
    | https://currentmakers.com/products/colibri/colibri-rs485i/&lt;br /&gt;
    |-&lt;br /&gt;
    | 12&lt;br /&gt;
    | Colibri RS485U&lt;br /&gt;
    | https://currentmakers.com/products/colibri/colibri-rs485u/&lt;br /&gt;
    |-&lt;br /&gt;
    | 13&lt;br /&gt;
    | Colibri SSR&lt;br /&gt;
    | https://currentmakers.com/products/colibri/colibri-ssr/&lt;br /&gt;
    |-&lt;br /&gt;
    | 14&lt;br /&gt;
    | Colibri TRIAC1&lt;br /&gt;
    | https://currentmakers.com/products/colibri/colibri-triac1/&lt;br /&gt;
    |}&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Colibri_EEPROM_Layout&amp;diff=7529</id>
		<title>Colibri EEPROM Layout</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Colibri_EEPROM_Layout&amp;diff=7529"/>
		<updated>2026-05-11T00:05:14Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* Vendor ID */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;All the Colibri I/O modules come with a 1Mbit EEPROM on board, that serves to store a few different things;&lt;br /&gt;
&lt;br /&gt;
* Vendor, Model and Revision of 'this' board.&lt;br /&gt;
* Calibration parameters needed to compensate for hardware tolerances.&lt;br /&gt;
* Test report (if any) from factory.&lt;br /&gt;
* The ''driver(s)'' (i.e. code) of the board, to be executed in the MCU module on behalf of the board.&lt;br /&gt;
* Any additional parameters, configuration that should survive over time.&lt;br /&gt;
* Any storage space an on-module co-MCU needs.&lt;br /&gt;
&lt;br /&gt;
= Memory Layout =&lt;br /&gt;
&lt;br /&gt;
{| class=wikitable&lt;br /&gt;
|-&lt;br /&gt;
! Address&lt;br /&gt;
! Length&lt;br /&gt;
! Description &lt;br /&gt;
|-&lt;br /&gt;
| 0x0000&lt;br /&gt;
| 4&lt;br /&gt;
| Contains the value 0xdeadbabe to indicate that it has been initialized.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0004&lt;br /&gt;
| 4&lt;br /&gt;
| Serial Number&lt;br /&gt;
|-&lt;br /&gt;
| 0x0008&lt;br /&gt;
| 8&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0010&lt;br /&gt;
| 4&lt;br /&gt;
| Vendor ID, according to table below.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0014&lt;br /&gt;
| 4&lt;br /&gt;
| Vendor Model identifier. This is specific to each vendor. Vendors are encouraged to add their tables on this page.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0018&lt;br /&gt;
| 4&lt;br /&gt;
| Vendor Hardware Revision, where revision 'A' is written as 0x00000041 and revision 'AC' is 0x00004341 &lt;br /&gt;
|-&lt;br /&gt;
| 0x001c&lt;br /&gt;
| 4&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0020&lt;br /&gt;
| 4&lt;br /&gt;
| Pointer to Vendor name, in ASCII.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0024&lt;br /&gt;
| 4&lt;br /&gt;
| Length of Vendor name&lt;br /&gt;
|-&lt;br /&gt;
| 0x0028&lt;br /&gt;
| 4&lt;br /&gt;
| Pointer to Model name, in ASCII.&lt;br /&gt;
|-&lt;br /&gt;
| 0x002c&lt;br /&gt;
| 4&lt;br /&gt;
| Length of Model name.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0030&lt;br /&gt;
| 4&lt;br /&gt;
| Pointer to Product Link&lt;br /&gt;
|-&lt;br /&gt;
| 0x0034&lt;br /&gt;
| 4&lt;br /&gt;
| Length of Product Link&lt;br /&gt;
|-&lt;br /&gt;
| 0x0038&lt;br /&gt;
| 4&lt;br /&gt;
| Pointer to Documentation Link&lt;br /&gt;
|-&lt;br /&gt;
| 0x003c&lt;br /&gt;
| 4&lt;br /&gt;
| Length of Documentation Link&lt;br /&gt;
|-&lt;br /&gt;
| 0x0040&lt;br /&gt;
| 4&lt;br /&gt;
| Size of ARM PIC (Position Independent Code).&lt;br /&gt;
|-&lt;br /&gt;
| 0x0044&lt;br /&gt;
| 60&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0080&lt;br /&gt;
| 128&lt;br /&gt;
| Calibration data, see each I/O module for details&lt;br /&gt;
|-&lt;br /&gt;
| 0x0100&lt;br /&gt;
| 256&lt;br /&gt;
| Test Reports, see each I/O module for details&lt;br /&gt;
|-&lt;br /&gt;
| 0x0200&lt;br /&gt;
| 1024&lt;br /&gt;
| Text area. Links points to here, i.e. Vendor name, model name, documentation link and product link.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0600&lt;br /&gt;
| 2560&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1000&lt;br /&gt;
| 2048&lt;br /&gt;
| Driver software/code. ARM PIC&lt;br /&gt;
|-&lt;br /&gt;
| 0x1800&lt;br /&gt;
| 26624&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x8000&lt;br /&gt;
| 32768&lt;br /&gt;
| Vendor area&lt;br /&gt;
|-&lt;br /&gt;
| 0x10000&lt;br /&gt;
| 65536&lt;br /&gt;
| Reserved for co-MCU on I/O module, or vendor defined.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Vendor ID =&lt;br /&gt;
Contact us at info@currentmakers.com if you have products you want added.&lt;br /&gt;
&lt;br /&gt;
{| class=wikitable&lt;br /&gt;
|-&lt;br /&gt;
! ID&lt;br /&gt;
! Company&lt;br /&gt;
! Webpage&lt;br /&gt;
! Models&lt;br /&gt;
|-&lt;br /&gt;
| 0&lt;br /&gt;
| Unknown/Not defined&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| CurrentMakers&lt;br /&gt;
| https://currentmakers.com&lt;br /&gt;
| &lt;br /&gt;
    {| class=wikitable&lt;br /&gt;
    |-&lt;br /&gt;
    ! ID&lt;br /&gt;
    ! Model&lt;br /&gt;
    ! Webpage&lt;br /&gt;
    |-&lt;br /&gt;
    | 0&lt;br /&gt;
    | Experiment&lt;br /&gt;
    | &lt;br /&gt;
    |-&lt;br /&gt;
    | 1&lt;br /&gt;
    | Colibri AIV&lt;br /&gt;
    | &lt;br /&gt;
    |-&lt;br /&gt;
    | 2&lt;br /&gt;
    | Colibri AIC&lt;br /&gt;
    | &lt;br /&gt;
    |-&lt;br /&gt;
    | 3&lt;br /&gt;
    | Colibri AQV&lt;br /&gt;
    | &lt;br /&gt;
    |-&lt;br /&gt;
    | 4&lt;br /&gt;
    | Colibri DII&lt;br /&gt;
    | &lt;br /&gt;
    |-&lt;br /&gt;
    | 5&lt;br /&gt;
    | Colibri DIO1&lt;br /&gt;
    | &lt;br /&gt;
    |-&lt;br /&gt;
    | 6&lt;br /&gt;
    | Colibri DIU&lt;br /&gt;
    | &lt;br /&gt;
    |-&lt;br /&gt;
    | 7&lt;br /&gt;
    | Colibri DP1&lt;br /&gt;
    | &lt;br /&gt;
    |-&lt;br /&gt;
    | 8&lt;br /&gt;
    | Colibri FET&lt;br /&gt;
    | &lt;br /&gt;
    |-&lt;br /&gt;
    | 9&lt;br /&gt;
    | Colibri PID1&lt;br /&gt;
    | &lt;br /&gt;
    |-&lt;br /&gt;
    | 10&lt;br /&gt;
    | Colibri Pt1000&lt;br /&gt;
    | &lt;br /&gt;
    |-&lt;br /&gt;
    | 11&lt;br /&gt;
    | Colibri RS485I&lt;br /&gt;
    | &lt;br /&gt;
    |-&lt;br /&gt;
    | 12&lt;br /&gt;
    | Colibri RS485U&lt;br /&gt;
    | &lt;br /&gt;
    |-&lt;br /&gt;
    | 13&lt;br /&gt;
    | Colibri SSR&lt;br /&gt;
    | &lt;br /&gt;
    |-&lt;br /&gt;
    | 14&lt;br /&gt;
    | Colibri TRIAC1&lt;br /&gt;
    | &lt;br /&gt;
    |}&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Colibri_EEPROM_Layout&amp;diff=7528</id>
		<title>Colibri EEPROM Layout</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Colibri_EEPROM_Layout&amp;diff=7528"/>
		<updated>2026-05-11T00:03:42Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* Vendor ID */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;All the Colibri I/O modules come with a 1Mbit EEPROM on board, that serves to store a few different things;&lt;br /&gt;
&lt;br /&gt;
* Vendor, Model and Revision of 'this' board.&lt;br /&gt;
* Calibration parameters needed to compensate for hardware tolerances.&lt;br /&gt;
* Test report (if any) from factory.&lt;br /&gt;
* The ''driver(s)'' (i.e. code) of the board, to be executed in the MCU module on behalf of the board.&lt;br /&gt;
* Any additional parameters, configuration that should survive over time.&lt;br /&gt;
* Any storage space an on-module co-MCU needs.&lt;br /&gt;
&lt;br /&gt;
= Memory Layout =&lt;br /&gt;
&lt;br /&gt;
{| class=wikitable&lt;br /&gt;
|-&lt;br /&gt;
! Address&lt;br /&gt;
! Length&lt;br /&gt;
! Description &lt;br /&gt;
|-&lt;br /&gt;
| 0x0000&lt;br /&gt;
| 4&lt;br /&gt;
| Contains the value 0xdeadbabe to indicate that it has been initialized.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0004&lt;br /&gt;
| 4&lt;br /&gt;
| Serial Number&lt;br /&gt;
|-&lt;br /&gt;
| 0x0008&lt;br /&gt;
| 8&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0010&lt;br /&gt;
| 4&lt;br /&gt;
| Vendor ID, according to table below.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0014&lt;br /&gt;
| 4&lt;br /&gt;
| Vendor Model identifier. This is specific to each vendor. Vendors are encouraged to add their tables on this page.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0018&lt;br /&gt;
| 4&lt;br /&gt;
| Vendor Hardware Revision, where revision 'A' is written as 0x00000041 and revision 'AC' is 0x00004341 &lt;br /&gt;
|-&lt;br /&gt;
| 0x001c&lt;br /&gt;
| 4&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0020&lt;br /&gt;
| 4&lt;br /&gt;
| Pointer to Vendor name, in ASCII.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0024&lt;br /&gt;
| 4&lt;br /&gt;
| Length of Vendor name&lt;br /&gt;
|-&lt;br /&gt;
| 0x0028&lt;br /&gt;
| 4&lt;br /&gt;
| Pointer to Model name, in ASCII.&lt;br /&gt;
|-&lt;br /&gt;
| 0x002c&lt;br /&gt;
| 4&lt;br /&gt;
| Length of Model name.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0030&lt;br /&gt;
| 4&lt;br /&gt;
| Pointer to Product Link&lt;br /&gt;
|-&lt;br /&gt;
| 0x0034&lt;br /&gt;
| 4&lt;br /&gt;
| Length of Product Link&lt;br /&gt;
|-&lt;br /&gt;
| 0x0038&lt;br /&gt;
| 4&lt;br /&gt;
| Pointer to Documentation Link&lt;br /&gt;
|-&lt;br /&gt;
| 0x003c&lt;br /&gt;
| 4&lt;br /&gt;
| Length of Documentation Link&lt;br /&gt;
|-&lt;br /&gt;
| 0x0040&lt;br /&gt;
| 4&lt;br /&gt;
| Size of ARM PIC (Position Independent Code).&lt;br /&gt;
|-&lt;br /&gt;
| 0x0044&lt;br /&gt;
| 60&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0080&lt;br /&gt;
| 128&lt;br /&gt;
| Calibration data, see each I/O module for details&lt;br /&gt;
|-&lt;br /&gt;
| 0x0100&lt;br /&gt;
| 256&lt;br /&gt;
| Test Reports, see each I/O module for details&lt;br /&gt;
|-&lt;br /&gt;
| 0x0200&lt;br /&gt;
| 1024&lt;br /&gt;
| Text area. Links points to here, i.e. Vendor name, model name, documentation link and product link.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0600&lt;br /&gt;
| 2560&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1000&lt;br /&gt;
| 2048&lt;br /&gt;
| Driver software/code. ARM PIC&lt;br /&gt;
|-&lt;br /&gt;
| 0x1800&lt;br /&gt;
| 26624&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x8000&lt;br /&gt;
| 32768&lt;br /&gt;
| Vendor area&lt;br /&gt;
|-&lt;br /&gt;
| 0x10000&lt;br /&gt;
| 65536&lt;br /&gt;
| Reserved for co-MCU on I/O module, or vendor defined.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Vendor ID =&lt;br /&gt;
Contact us at info@currentmakers.com if you have products you want added.&lt;br /&gt;
&lt;br /&gt;
{| class=wikitable&lt;br /&gt;
|-&lt;br /&gt;
! ID&lt;br /&gt;
! Company&lt;br /&gt;
! Webpage&lt;br /&gt;
! Models&lt;br /&gt;
|-&lt;br /&gt;
| 0&lt;br /&gt;
| Unknown/Not defined&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| CurrentMakers&lt;br /&gt;
| https://currentmakers.com&lt;br /&gt;
| &lt;br /&gt;
{| class=wikitable&lt;br /&gt;
|-&lt;br /&gt;
! ID&lt;br /&gt;
! Model&lt;br /&gt;
! Webpage&lt;br /&gt;
|-&lt;br /&gt;
| 0&lt;br /&gt;
| Experiment&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| Colibri AIV&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| Colibri AIC&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| Colibri AQV&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Colibri DII&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Colibri DIO1&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| Colibri DIU&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| Colibri DP1&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| Colibri FET&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 9&lt;br /&gt;
| Colibri PID1&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 10&lt;br /&gt;
| Colibri Pt1000&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 11&lt;br /&gt;
| Colibri RS485I&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 12&lt;br /&gt;
| Colibri RS485U&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 13&lt;br /&gt;
| Colibri SSR&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 14&lt;br /&gt;
| Colibri TRIAC1&lt;br /&gt;
| &lt;br /&gt;
|}&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Colibri_EEPROM_Layout&amp;diff=7527</id>
		<title>Colibri EEPROM Layout</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Colibri_EEPROM_Layout&amp;diff=7527"/>
		<updated>2026-05-11T00:02:08Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* Vendor ID */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;All the Colibri I/O modules come with a 1Mbit EEPROM on board, that serves to store a few different things;&lt;br /&gt;
&lt;br /&gt;
* Vendor, Model and Revision of 'this' board.&lt;br /&gt;
* Calibration parameters needed to compensate for hardware tolerances.&lt;br /&gt;
* Test report (if any) from factory.&lt;br /&gt;
* The ''driver(s)'' (i.e. code) of the board, to be executed in the MCU module on behalf of the board.&lt;br /&gt;
* Any additional parameters, configuration that should survive over time.&lt;br /&gt;
* Any storage space an on-module co-MCU needs.&lt;br /&gt;
&lt;br /&gt;
= Memory Layout =&lt;br /&gt;
&lt;br /&gt;
{| class=wikitable&lt;br /&gt;
|-&lt;br /&gt;
! Address&lt;br /&gt;
! Length&lt;br /&gt;
! Description &lt;br /&gt;
|-&lt;br /&gt;
| 0x0000&lt;br /&gt;
| 4&lt;br /&gt;
| Contains the value 0xdeadbabe to indicate that it has been initialized.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0004&lt;br /&gt;
| 4&lt;br /&gt;
| Serial Number&lt;br /&gt;
|-&lt;br /&gt;
| 0x0008&lt;br /&gt;
| 8&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0010&lt;br /&gt;
| 4&lt;br /&gt;
| Vendor ID, according to table below.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0014&lt;br /&gt;
| 4&lt;br /&gt;
| Vendor Model identifier. This is specific to each vendor. Vendors are encouraged to add their tables on this page.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0018&lt;br /&gt;
| 4&lt;br /&gt;
| Vendor Hardware Revision, where revision 'A' is written as 0x00000041 and revision 'AC' is 0x00004341 &lt;br /&gt;
|-&lt;br /&gt;
| 0x001c&lt;br /&gt;
| 4&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0020&lt;br /&gt;
| 4&lt;br /&gt;
| Pointer to Vendor name, in ASCII.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0024&lt;br /&gt;
| 4&lt;br /&gt;
| Length of Vendor name&lt;br /&gt;
|-&lt;br /&gt;
| 0x0028&lt;br /&gt;
| 4&lt;br /&gt;
| Pointer to Model name, in ASCII.&lt;br /&gt;
|-&lt;br /&gt;
| 0x002c&lt;br /&gt;
| 4&lt;br /&gt;
| Length of Model name.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0030&lt;br /&gt;
| 4&lt;br /&gt;
| Pointer to Product Link&lt;br /&gt;
|-&lt;br /&gt;
| 0x0034&lt;br /&gt;
| 4&lt;br /&gt;
| Length of Product Link&lt;br /&gt;
|-&lt;br /&gt;
| 0x0038&lt;br /&gt;
| 4&lt;br /&gt;
| Pointer to Documentation Link&lt;br /&gt;
|-&lt;br /&gt;
| 0x003c&lt;br /&gt;
| 4&lt;br /&gt;
| Length of Documentation Link&lt;br /&gt;
|-&lt;br /&gt;
| 0x0040&lt;br /&gt;
| 4&lt;br /&gt;
| Size of ARM PIC (Position Independent Code).&lt;br /&gt;
|-&lt;br /&gt;
| 0x0044&lt;br /&gt;
| 60&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0080&lt;br /&gt;
| 128&lt;br /&gt;
| Calibration data, see each I/O module for details&lt;br /&gt;
|-&lt;br /&gt;
| 0x0100&lt;br /&gt;
| 256&lt;br /&gt;
| Test Reports, see each I/O module for details&lt;br /&gt;
|-&lt;br /&gt;
| 0x0200&lt;br /&gt;
| 1024&lt;br /&gt;
| Text area. Links points to here, i.e. Vendor name, model name, documentation link and product link.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0600&lt;br /&gt;
| 2560&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1000&lt;br /&gt;
| 2048&lt;br /&gt;
| Driver software/code. ARM PIC&lt;br /&gt;
|-&lt;br /&gt;
| 0x1800&lt;br /&gt;
| 26624&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x8000&lt;br /&gt;
| 32768&lt;br /&gt;
| Vendor area&lt;br /&gt;
|-&lt;br /&gt;
| 0x10000&lt;br /&gt;
| 65536&lt;br /&gt;
| Reserved for co-MCU on I/O module, or vendor defined.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Vendor ID =&lt;br /&gt;
Contact us at info@currentmakers.com if you have products you want added.&lt;br /&gt;
&lt;br /&gt;
{| class=wikitable&lt;br /&gt;
|-&lt;br /&gt;
! ID&lt;br /&gt;
! Company&lt;br /&gt;
! Webpage&lt;br /&gt;
! Models&lt;br /&gt;
|-&lt;br /&gt;
| 0&lt;br /&gt;
| Unknown/Not defined&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| CurrentMakers&lt;br /&gt;
| https://currentmakers.com&lt;br /&gt;
| {| class=wikitable&lt;br /&gt;
|-&lt;br /&gt;
! ID&lt;br /&gt;
! Model&lt;br /&gt;
! Webpage&lt;br /&gt;
|-&lt;br /&gt;
| 0&lt;br /&gt;
| Experiment&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| Colibri AIV&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| Colibri AIC&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| Colibri AQV&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| Colibri DII&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| Colibri DIO1&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| Colibri DIU&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| Colibri DP1&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| Colibri FET&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 9&lt;br /&gt;
| Colibri PID1&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 10&lt;br /&gt;
| Colibri Pt1000&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 11&lt;br /&gt;
| Colibri RS485I&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 12&lt;br /&gt;
| Colibri RS485U&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 13&lt;br /&gt;
| Colibri SSR&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 14&lt;br /&gt;
| Colibri TRIAC1&lt;br /&gt;
| &lt;br /&gt;
|}&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Colibri_EEPROM_Layout&amp;diff=7526</id>
		<title>Colibri EEPROM Layout</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Colibri_EEPROM_Layout&amp;diff=7526"/>
		<updated>2026-05-10T23:56:11Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* Vendor ID */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;All the Colibri I/O modules come with a 1Mbit EEPROM on board, that serves to store a few different things;&lt;br /&gt;
&lt;br /&gt;
* Vendor, Model and Revision of 'this' board.&lt;br /&gt;
* Calibration parameters needed to compensate for hardware tolerances.&lt;br /&gt;
* Test report (if any) from factory.&lt;br /&gt;
* The ''driver(s)'' (i.e. code) of the board, to be executed in the MCU module on behalf of the board.&lt;br /&gt;
* Any additional parameters, configuration that should survive over time.&lt;br /&gt;
* Any storage space an on-module co-MCU needs.&lt;br /&gt;
&lt;br /&gt;
= Memory Layout =&lt;br /&gt;
&lt;br /&gt;
{| class=wikitable&lt;br /&gt;
|-&lt;br /&gt;
! Address&lt;br /&gt;
! Length&lt;br /&gt;
! Description &lt;br /&gt;
|-&lt;br /&gt;
| 0x0000&lt;br /&gt;
| 4&lt;br /&gt;
| Contains the value 0xdeadbabe to indicate that it has been initialized.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0004&lt;br /&gt;
| 4&lt;br /&gt;
| Serial Number&lt;br /&gt;
|-&lt;br /&gt;
| 0x0008&lt;br /&gt;
| 8&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0010&lt;br /&gt;
| 4&lt;br /&gt;
| Vendor ID, according to table below.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0014&lt;br /&gt;
| 4&lt;br /&gt;
| Vendor Model identifier. This is specific to each vendor. Vendors are encouraged to add their tables on this page.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0018&lt;br /&gt;
| 4&lt;br /&gt;
| Vendor Hardware Revision, where revision 'A' is written as 0x00000041 and revision 'AC' is 0x00004341 &lt;br /&gt;
|-&lt;br /&gt;
| 0x001c&lt;br /&gt;
| 4&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0020&lt;br /&gt;
| 4&lt;br /&gt;
| Pointer to Vendor name, in ASCII.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0024&lt;br /&gt;
| 4&lt;br /&gt;
| Length of Vendor name&lt;br /&gt;
|-&lt;br /&gt;
| 0x0028&lt;br /&gt;
| 4&lt;br /&gt;
| Pointer to Model name, in ASCII.&lt;br /&gt;
|-&lt;br /&gt;
| 0x002c&lt;br /&gt;
| 4&lt;br /&gt;
| Length of Model name.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0030&lt;br /&gt;
| 4&lt;br /&gt;
| Pointer to Product Link&lt;br /&gt;
|-&lt;br /&gt;
| 0x0034&lt;br /&gt;
| 4&lt;br /&gt;
| Length of Product Link&lt;br /&gt;
|-&lt;br /&gt;
| 0x0038&lt;br /&gt;
| 4&lt;br /&gt;
| Pointer to Documentation Link&lt;br /&gt;
|-&lt;br /&gt;
| 0x003c&lt;br /&gt;
| 4&lt;br /&gt;
| Length of Documentation Link&lt;br /&gt;
|-&lt;br /&gt;
| 0x0040&lt;br /&gt;
| 4&lt;br /&gt;
| Size of ARM PIC (Position Independent Code).&lt;br /&gt;
|-&lt;br /&gt;
| 0x0044&lt;br /&gt;
| 60&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0080&lt;br /&gt;
| 128&lt;br /&gt;
| Calibration data, see each I/O module for details&lt;br /&gt;
|-&lt;br /&gt;
| 0x0100&lt;br /&gt;
| 256&lt;br /&gt;
| Test Reports, see each I/O module for details&lt;br /&gt;
|-&lt;br /&gt;
| 0x0200&lt;br /&gt;
| 1024&lt;br /&gt;
| Text area. Links points to here, i.e. Vendor name, model name, documentation link and product link.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0600&lt;br /&gt;
| 2560&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1000&lt;br /&gt;
| 2048&lt;br /&gt;
| Driver software/code. ARM PIC&lt;br /&gt;
|-&lt;br /&gt;
| 0x1800&lt;br /&gt;
| 26624&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x8000&lt;br /&gt;
| 32768&lt;br /&gt;
| Vendor area&lt;br /&gt;
|-&lt;br /&gt;
| 0x10000&lt;br /&gt;
| 65536&lt;br /&gt;
| Reserved for co-MCU on I/O module, or vendor defined.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Vendor ID =&lt;br /&gt;
Contact us at info@currentmakers.com if you have products you want added.&lt;br /&gt;
&lt;br /&gt;
{| class=wikitable&lt;br /&gt;
|-&lt;br /&gt;
! ID&lt;br /&gt;
! Company&lt;br /&gt;
! Webpage&lt;br /&gt;
|-&lt;br /&gt;
| 0&lt;br /&gt;
| Unknown/Not defined&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| CurrentMakers&lt;br /&gt;
| https://currentmakers.com&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Colibri_EEPROM_Layout&amp;diff=7525</id>
		<title>Colibri EEPROM Layout</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Colibri_EEPROM_Layout&amp;diff=7525"/>
		<updated>2026-05-10T23:54:54Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* Memory Layout */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;All the Colibri I/O modules come with a 1Mbit EEPROM on board, that serves to store a few different things;&lt;br /&gt;
&lt;br /&gt;
* Vendor, Model and Revision of 'this' board.&lt;br /&gt;
* Calibration parameters needed to compensate for hardware tolerances.&lt;br /&gt;
* Test report (if any) from factory.&lt;br /&gt;
* The ''driver(s)'' (i.e. code) of the board, to be executed in the MCU module on behalf of the board.&lt;br /&gt;
* Any additional parameters, configuration that should survive over time.&lt;br /&gt;
* Any storage space an on-module co-MCU needs.&lt;br /&gt;
&lt;br /&gt;
= Memory Layout =&lt;br /&gt;
&lt;br /&gt;
{| class=wikitable&lt;br /&gt;
|-&lt;br /&gt;
! Address&lt;br /&gt;
! Length&lt;br /&gt;
! Description &lt;br /&gt;
|-&lt;br /&gt;
| 0x0000&lt;br /&gt;
| 4&lt;br /&gt;
| Contains the value 0xdeadbabe to indicate that it has been initialized.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0004&lt;br /&gt;
| 4&lt;br /&gt;
| Serial Number&lt;br /&gt;
|-&lt;br /&gt;
| 0x0008&lt;br /&gt;
| 8&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0010&lt;br /&gt;
| 4&lt;br /&gt;
| Vendor ID, according to table below.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0014&lt;br /&gt;
| 4&lt;br /&gt;
| Vendor Model identifier. This is specific to each vendor. Vendors are encouraged to add their tables on this page.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0018&lt;br /&gt;
| 4&lt;br /&gt;
| Vendor Hardware Revision, where revision 'A' is written as 0x00000041 and revision 'AC' is 0x00004341 &lt;br /&gt;
|-&lt;br /&gt;
| 0x001c&lt;br /&gt;
| 4&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0020&lt;br /&gt;
| 4&lt;br /&gt;
| Pointer to Vendor name, in ASCII.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0024&lt;br /&gt;
| 4&lt;br /&gt;
| Length of Vendor name&lt;br /&gt;
|-&lt;br /&gt;
| 0x0028&lt;br /&gt;
| 4&lt;br /&gt;
| Pointer to Model name, in ASCII.&lt;br /&gt;
|-&lt;br /&gt;
| 0x002c&lt;br /&gt;
| 4&lt;br /&gt;
| Length of Model name.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0030&lt;br /&gt;
| 4&lt;br /&gt;
| Pointer to Product Link&lt;br /&gt;
|-&lt;br /&gt;
| 0x0034&lt;br /&gt;
| 4&lt;br /&gt;
| Length of Product Link&lt;br /&gt;
|-&lt;br /&gt;
| 0x0038&lt;br /&gt;
| 4&lt;br /&gt;
| Pointer to Documentation Link&lt;br /&gt;
|-&lt;br /&gt;
| 0x003c&lt;br /&gt;
| 4&lt;br /&gt;
| Length of Documentation Link&lt;br /&gt;
|-&lt;br /&gt;
| 0x0040&lt;br /&gt;
| 4&lt;br /&gt;
| Size of ARM PIC (Position Independent Code).&lt;br /&gt;
|-&lt;br /&gt;
| 0x0044&lt;br /&gt;
| 60&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0080&lt;br /&gt;
| 128&lt;br /&gt;
| Calibration data, see each I/O module for details&lt;br /&gt;
|-&lt;br /&gt;
| 0x0100&lt;br /&gt;
| 256&lt;br /&gt;
| Test Reports, see each I/O module for details&lt;br /&gt;
|-&lt;br /&gt;
| 0x0200&lt;br /&gt;
| 1024&lt;br /&gt;
| Text area. Links points to here, i.e. Vendor name, model name, documentation link and product link.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0600&lt;br /&gt;
| 2560&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1000&lt;br /&gt;
| 2048&lt;br /&gt;
| Driver software/code. ARM PIC&lt;br /&gt;
|-&lt;br /&gt;
| 0x1800&lt;br /&gt;
| 26624&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x8000&lt;br /&gt;
| 32768&lt;br /&gt;
| Vendor area&lt;br /&gt;
|-&lt;br /&gt;
| 0x10000&lt;br /&gt;
| 65536&lt;br /&gt;
| Reserved for co-MCU on I/O module, or vendor defined.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Vendor ID =&lt;br /&gt;
Contact us at info@currentmakers.com if you have products you want added.&lt;br /&gt;
&lt;br /&gt;
{| class=wikitable&lt;br /&gt;
|-&lt;br /&gt;
! ID&lt;br /&gt;
! Company&lt;br /&gt;
! Webpage&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| CurrentMakers&lt;br /&gt;
| https://currentmakers.com&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Colibri_Runtime&amp;diff=7521</id>
		<title>Colibri Runtime</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Colibri_Runtime&amp;diff=7521"/>
		<updated>2026-05-09T09:35:23Z</updated>

		<summary type="html">&lt;p&gt;Niclas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Colibri Runtime is the custom firmware that is running on Colibri MCUs, an application in [[Colibri Zephyr]] orchestrating the hardware resources, WebAssembly engines with I/O drivers and user programs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Development == &lt;br /&gt;
[[Colibri EEPROM Layout]]&lt;br /&gt;
&lt;br /&gt;
[[Colibri WebAssembly Notes]]&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Colibri_Runtime&amp;diff=7520</id>
		<title>Colibri Runtime</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Colibri_Runtime&amp;diff=7520"/>
		<updated>2026-05-09T09:35:12Z</updated>

		<summary type="html">&lt;p&gt;Niclas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Colibri Runtime is the custom firmware that is running on Colibri MCUs, an application in [[Colibri Zephyr]] orchestrating the hardware resources, WebAssembly engines with I/O drivers and user programs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Development == &lt;br /&gt;
[[Colibri EEPROM Layout]]&lt;br /&gt;
[[Colibri WebAssembly Notes]]&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Colibri_EEPROM_Layout&amp;diff=7519</id>
		<title>Colibri EEPROM Layout</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Colibri_EEPROM_Layout&amp;diff=7519"/>
		<updated>2026-05-09T09:32:26Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* Memory Layout */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;All the Colibri I/O modules come with a 1Mbit EEPROM on board, that serves to store a few different things;&lt;br /&gt;
&lt;br /&gt;
* Vendor, Model and Revision of 'this' board.&lt;br /&gt;
* Calibration parameters needed to compensate for hardware tolerances.&lt;br /&gt;
* Test report (if any) from factory.&lt;br /&gt;
* The ''driver(s)'' (i.e. code) of the board, to be executed in the MCU module on behalf of the board.&lt;br /&gt;
* Any additional parameters, configuration that should survive over time.&lt;br /&gt;
* Any storage space an on-module co-MCU needs.&lt;br /&gt;
&lt;br /&gt;
= Memory Layout =&lt;br /&gt;
&lt;br /&gt;
{| class=wikitable&lt;br /&gt;
|-&lt;br /&gt;
! Address&lt;br /&gt;
! Length&lt;br /&gt;
! Description &lt;br /&gt;
|-&lt;br /&gt;
| 0x0000&lt;br /&gt;
| 4&lt;br /&gt;
| Contains the value 0xdeadbabe to indicate that it has been initialized.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0004&lt;br /&gt;
| 4&lt;br /&gt;
| Serial Number&lt;br /&gt;
|-&lt;br /&gt;
| 0x0008&lt;br /&gt;
| 8&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0010&lt;br /&gt;
| 4&lt;br /&gt;
| Vendor ID, according to table below.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0014&lt;br /&gt;
| 4&lt;br /&gt;
| Vendor Model identifier. This is specific to each vendor. Vendors are encouraged to add their tables on this page.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0018&lt;br /&gt;
| 4&lt;br /&gt;
| Vendor Hardware Revision, where revision 'A' is written as 0x00000041 and revision 'AC' is 0x00004341 &lt;br /&gt;
|-&lt;br /&gt;
| 0x001c&lt;br /&gt;
| 4&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0020&lt;br /&gt;
| 4&lt;br /&gt;
| Pointer to Vendor name, in ASCII.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0024&lt;br /&gt;
| 4&lt;br /&gt;
| Length of Vendor name&lt;br /&gt;
|-&lt;br /&gt;
| 0x0028&lt;br /&gt;
| 4&lt;br /&gt;
| Pointer to Model name, in ASCII.&lt;br /&gt;
|-&lt;br /&gt;
| 0x002c&lt;br /&gt;
| 4&lt;br /&gt;
| Length of Model name.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0030&lt;br /&gt;
| 4&lt;br /&gt;
| Pointer to Product Link&lt;br /&gt;
|-&lt;br /&gt;
| 0x0034&lt;br /&gt;
| 4&lt;br /&gt;
| Length of Product Link&lt;br /&gt;
|-&lt;br /&gt;
| 0x0038&lt;br /&gt;
| 4&lt;br /&gt;
| Pointer to Documentation Link&lt;br /&gt;
|-&lt;br /&gt;
| 0x003c&lt;br /&gt;
| 4&lt;br /&gt;
| Length of Documentation Link&lt;br /&gt;
|-&lt;br /&gt;
| 0x0040&lt;br /&gt;
| 4&lt;br /&gt;
| Size of ARM PIC (Position Independent Code).&lt;br /&gt;
|-&lt;br /&gt;
| 0x0044&lt;br /&gt;
| 60&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0080&lt;br /&gt;
| 128&lt;br /&gt;
| Calibration data, see each I/O module for details&lt;br /&gt;
|-&lt;br /&gt;
| 0x0100&lt;br /&gt;
| 256&lt;br /&gt;
| Test Reports, see each I/O module for details&lt;br /&gt;
|-&lt;br /&gt;
| 0x0200&lt;br /&gt;
| 2048&lt;br /&gt;
| Text area. Links points to here, i.e. Vendor name, model name, documentation link and product link.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0A00&lt;br /&gt;
| 1536&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1000&lt;br /&gt;
| 12288&lt;br /&gt;
| Vendor area&lt;br /&gt;
|-&lt;br /&gt;
| 0x4000&lt;br /&gt;
| 8192&lt;br /&gt;
| Driver software/code. ARM PIC&lt;br /&gt;
|-&lt;br /&gt;
| 0x6000&lt;br /&gt;
| 40960&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x10000&lt;br /&gt;
| 65536&lt;br /&gt;
| Reserved for co-MCU on I/O module, or vendor defined.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Vendor ID =&lt;br /&gt;
Contact us at info@currentmakers.com if you have products you want added.&lt;br /&gt;
&lt;br /&gt;
{| class=wikitable&lt;br /&gt;
|-&lt;br /&gt;
! ID&lt;br /&gt;
! Company&lt;br /&gt;
! Webpage&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| CurrentMakers&lt;br /&gt;
| https://currentmakers.com&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Colibri_EEPROM_Layout&amp;diff=7518</id>
		<title>Colibri EEPROM Layout</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Colibri_EEPROM_Layout&amp;diff=7518"/>
		<updated>2026-05-09T09:16:24Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* Memory Layout */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;All the Colibri I/O modules come with a 1Mbit EEPROM on board, that serves to store a few different things;&lt;br /&gt;
&lt;br /&gt;
* Vendor, Model and Revision of 'this' board.&lt;br /&gt;
* Calibration parameters needed to compensate for hardware tolerances.&lt;br /&gt;
* Test report (if any) from factory.&lt;br /&gt;
* The ''driver(s)'' (i.e. code) of the board, to be executed in the MCU module on behalf of the board.&lt;br /&gt;
* Any additional parameters, configuration that should survive over time.&lt;br /&gt;
* Any storage space an on-module co-MCU needs.&lt;br /&gt;
&lt;br /&gt;
= Memory Layout =&lt;br /&gt;
&lt;br /&gt;
{| class=wikitable&lt;br /&gt;
|-&lt;br /&gt;
! Address&lt;br /&gt;
! Length&lt;br /&gt;
! Description &lt;br /&gt;
|-&lt;br /&gt;
| 0x0000&lt;br /&gt;
| 4&lt;br /&gt;
| Contains the value 0xdeadbabe to indicate that it has been initialized.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0004&lt;br /&gt;
| 4&lt;br /&gt;
| Serial Number&lt;br /&gt;
|-&lt;br /&gt;
| 0x0008&lt;br /&gt;
| 8&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0010&lt;br /&gt;
| 4&lt;br /&gt;
| Vendor ID, according to table below.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0014&lt;br /&gt;
| 4&lt;br /&gt;
| Vendor Model identifier. This is specific to each vendor. Vendors are encouraged to add their tables on this page.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0018&lt;br /&gt;
| 4&lt;br /&gt;
| Vendor Hardware Revision, where revision 'A' is written as 0x00000041 and revision 'AC' is 0x00004341 &lt;br /&gt;
|-&lt;br /&gt;
| 0x001c&lt;br /&gt;
| 4&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0020&lt;br /&gt;
| 4&lt;br /&gt;
| Pointer to Vendor name, in ASCII.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0024&lt;br /&gt;
| 4&lt;br /&gt;
| Length of Vendor name&lt;br /&gt;
|-&lt;br /&gt;
| 0x0028&lt;br /&gt;
| 4&lt;br /&gt;
| Pointer to Model name, in ASCII.&lt;br /&gt;
|-&lt;br /&gt;
| 0x002c&lt;br /&gt;
| 4&lt;br /&gt;
| Length of Model name.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0030&lt;br /&gt;
| 4&lt;br /&gt;
| Pointer to Product Link&lt;br /&gt;
|-&lt;br /&gt;
| 0x0034&lt;br /&gt;
| 4&lt;br /&gt;
| Length of Product Link&lt;br /&gt;
|-&lt;br /&gt;
| 0x0038&lt;br /&gt;
| 4&lt;br /&gt;
| Pointer to Documentation Link&lt;br /&gt;
|-&lt;br /&gt;
| 0x003c&lt;br /&gt;
| 4&lt;br /&gt;
| Length of Documentation Link&lt;br /&gt;
|-&lt;br /&gt;
| 0x0040&lt;br /&gt;
| 4&lt;br /&gt;
| Size of ARM PIC (Position Independent Code).&lt;br /&gt;
|-&lt;br /&gt;
| 0x0044&lt;br /&gt;
| 60&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0080&lt;br /&gt;
| 128&lt;br /&gt;
| Calibration data, see each I/O module for details&lt;br /&gt;
|-&lt;br /&gt;
| 0x0100&lt;br /&gt;
| 256&lt;br /&gt;
| Test Reports, see each I/O module for details&lt;br /&gt;
|-&lt;br /&gt;
| 0x0200&lt;br /&gt;
| 2048&lt;br /&gt;
| Text area. Links points to here, i.e. Vendor name, model name, documentation link and product link.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0A00&lt;br /&gt;
| 1536&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1000&lt;br /&gt;
| 12288&lt;br /&gt;
| Vendor area&lt;br /&gt;
|-&lt;br /&gt;
| 0x4000&lt;br /&gt;
| 8192&lt;br /&gt;
| Driver software/code. ARM PIC&lt;br /&gt;
|-&lt;br /&gt;
| 0x6000&lt;br /&gt;
| 40960&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x10000&lt;br /&gt;
| 65536&lt;br /&gt;
| Reserved for co-MCU on I/O module, or vendor defined.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Colibri_EEPROM_Layout&amp;diff=7517</id>
		<title>Colibri EEPROM Layout</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Colibri_EEPROM_Layout&amp;diff=7517"/>
		<updated>2026-05-09T07:08:13Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* Memory Layout */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;All the Colibri I/O modules come with a 1Mbit EEPROM on board, that serves to store a few different things;&lt;br /&gt;
&lt;br /&gt;
* Vendor, Model and Revision of 'this' board.&lt;br /&gt;
* Calibration parameters needed to compensate for hardware tolerances.&lt;br /&gt;
* Test report (if any) from factory.&lt;br /&gt;
* The ''driver(s)'' (i.e. code) of the board, to be executed in the MCU module on behalf of the board.&lt;br /&gt;
* Any additional parameters, configuration that should survive over time.&lt;br /&gt;
* Any storage space an on-module co-MCU needs.&lt;br /&gt;
&lt;br /&gt;
= Memory Layout =&lt;br /&gt;
&lt;br /&gt;
{| class=wikitable&lt;br /&gt;
|-&lt;br /&gt;
! Address&lt;br /&gt;
! Length&lt;br /&gt;
! Description &lt;br /&gt;
|-&lt;br /&gt;
| 0x0000&lt;br /&gt;
| 4&lt;br /&gt;
| Contains the value 0xdeadbabe to indicate that it has been initialized.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0004&lt;br /&gt;
| 12&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0010&lt;br /&gt;
| 4&lt;br /&gt;
| Vendor ID, according to table below.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0014&lt;br /&gt;
| 4&lt;br /&gt;
| Vendor Model identifier. This is specific to each vendor. Vendors are encouraged to add their tables on this page.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0018&lt;br /&gt;
| 4&lt;br /&gt;
| Vendor Hardware Revision, where revision 'A' is written as 0x00000041 and revision 'AC' is 0x00004341 &lt;br /&gt;
|-&lt;br /&gt;
| 0x001c&lt;br /&gt;
| 4&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0020&lt;br /&gt;
| 4&lt;br /&gt;
| Pointer to Vendor name, in ASCII.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0024&lt;br /&gt;
| 4&lt;br /&gt;
| Length of Vendor name&lt;br /&gt;
|-&lt;br /&gt;
| 0x0028&lt;br /&gt;
| 4&lt;br /&gt;
| Pointer to Model name, in ASCII.&lt;br /&gt;
|-&lt;br /&gt;
| 0x002c&lt;br /&gt;
| 4&lt;br /&gt;
| Length of Model name.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0030&lt;br /&gt;
| 4&lt;br /&gt;
| Pointer to Product Link&lt;br /&gt;
|-&lt;br /&gt;
| 0x0034&lt;br /&gt;
| 4&lt;br /&gt;
| Length of Product Link&lt;br /&gt;
|-&lt;br /&gt;
| 0x0038&lt;br /&gt;
| 4&lt;br /&gt;
| Pointer to Documentation Link&lt;br /&gt;
|-&lt;br /&gt;
| 0x003c&lt;br /&gt;
| 4&lt;br /&gt;
| Length of Documentation Link&lt;br /&gt;
|-&lt;br /&gt;
| 0x0040&lt;br /&gt;
| 4&lt;br /&gt;
| Size of ARM PIC (Position Independent Code).&lt;br /&gt;
|-&lt;br /&gt;
| 0x0044&lt;br /&gt;
| 60&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0080&lt;br /&gt;
| 128&lt;br /&gt;
| Calibration data, see each I/O module for details&lt;br /&gt;
|-&lt;br /&gt;
| 0x0100&lt;br /&gt;
| 256&lt;br /&gt;
| Test Reports, see each I/O module for details&lt;br /&gt;
|-&lt;br /&gt;
| 0x0200&lt;br /&gt;
| 2048&lt;br /&gt;
| Text area. Links points to here, i.e. Vendor name, model name, documentation link and product link.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0A00&lt;br /&gt;
| 1536&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1000&lt;br /&gt;
| 12288&lt;br /&gt;
| Vendor area&lt;br /&gt;
|-&lt;br /&gt;
| 0x4000&lt;br /&gt;
| 8192&lt;br /&gt;
| Driver software/code. ARM PIC&lt;br /&gt;
|-&lt;br /&gt;
| 0x6000&lt;br /&gt;
| 40960&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x10000&lt;br /&gt;
| 65536&lt;br /&gt;
| Reserved for co-MCU on I/O module, or vendor defined.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Colibri_EEPROM_Layout&amp;diff=7516</id>
		<title>Colibri EEPROM Layout</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Colibri_EEPROM_Layout&amp;diff=7516"/>
		<updated>2026-05-09T06:57:13Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* Memory Layout */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;All the Colibri I/O modules come with a 1Mbit EEPROM on board, that serves to store a few different things;&lt;br /&gt;
&lt;br /&gt;
* Vendor, Model and Revision of 'this' board.&lt;br /&gt;
* Calibration parameters needed to compensate for hardware tolerances.&lt;br /&gt;
* Test report (if any) from factory.&lt;br /&gt;
* The ''driver(s)'' (i.e. code) of the board, to be executed in the MCU module on behalf of the board.&lt;br /&gt;
* Any additional parameters, configuration that should survive over time.&lt;br /&gt;
* Any storage space an on-module co-MCU needs.&lt;br /&gt;
&lt;br /&gt;
= Memory Layout =&lt;br /&gt;
&lt;br /&gt;
{| class=wikitable&lt;br /&gt;
|-&lt;br /&gt;
! Address&lt;br /&gt;
! Length&lt;br /&gt;
! Description &lt;br /&gt;
|-&lt;br /&gt;
| 0x0000&lt;br /&gt;
| 4&lt;br /&gt;
| Contains the value 0xdeadbabe to indicate that it has been initialized.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0004&lt;br /&gt;
| 12&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0010&lt;br /&gt;
| 4&lt;br /&gt;
| Vendor ID, according to table below.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0014&lt;br /&gt;
| 4&lt;br /&gt;
| Vendor Model identifier. This is specific to each vendor. Vendors are encouraged to add their tables on this page.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0018&lt;br /&gt;
| 4&lt;br /&gt;
| Vendor Hardware Revision, where revision 'A' is written as 0x00000041 and revision 'AC' is 0x00004341 &lt;br /&gt;
|-&lt;br /&gt;
| 0x001c&lt;br /&gt;
| 4&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0020&lt;br /&gt;
| 4&lt;br /&gt;
| Pointer to Vendor name, in ASCII.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0024&lt;br /&gt;
| 4&lt;br /&gt;
| Length of Vendor name&lt;br /&gt;
|-&lt;br /&gt;
| 0x0028&lt;br /&gt;
| 4&lt;br /&gt;
| Pointer to Model name, in ASCII.&lt;br /&gt;
|-&lt;br /&gt;
| 0x002c&lt;br /&gt;
| 4&lt;br /&gt;
| Length of Model name.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0030&lt;br /&gt;
| 4&lt;br /&gt;
| Pointer to Product Link&lt;br /&gt;
|-&lt;br /&gt;
| 0x0034&lt;br /&gt;
| 4&lt;br /&gt;
| Length of Product Link&lt;br /&gt;
|-&lt;br /&gt;
| 0x0038&lt;br /&gt;
| 4&lt;br /&gt;
| Pointer to Documentation Link&lt;br /&gt;
|-&lt;br /&gt;
| 0x003c&lt;br /&gt;
| 4&lt;br /&gt;
| Length of Documentation Link&lt;br /&gt;
|-&lt;br /&gt;
| 0x0040&lt;br /&gt;
| 4&lt;br /&gt;
| Size of ARM PIC (Position Independent Code).&lt;br /&gt;
|-&lt;br /&gt;
| 0x0044&lt;br /&gt;
| 60&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0080&lt;br /&gt;
| 128&lt;br /&gt;
| Calibration data, see each I/O module for details&lt;br /&gt;
|-&lt;br /&gt;
| 0x0100&lt;br /&gt;
| 256&lt;br /&gt;
| Test Reports, see each I/O module for details&lt;br /&gt;
|-&lt;br /&gt;
| 0x0200&lt;br /&gt;
| 1536&lt;br /&gt;
| Text area. Links points to here, i.e. Vendor name, model name, documentation link and product link.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0800&lt;br /&gt;
| 2048&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1000&lt;br /&gt;
| 12288&lt;br /&gt;
| Vendor area&lt;br /&gt;
|-&lt;br /&gt;
| 0x4000&lt;br /&gt;
| 8192&lt;br /&gt;
| Driver software/code. ARM PIC&lt;br /&gt;
|-&lt;br /&gt;
| 0x6000&lt;br /&gt;
| 40960&lt;br /&gt;
| Reserved for future use.&lt;br /&gt;
|-&lt;br /&gt;
| 0x10000&lt;br /&gt;
| 65536&lt;br /&gt;
| Reserved for co-MCU on I/O module, or vendor defined.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Colibri_Programming_Languages&amp;diff=7515</id>
		<title>Colibri Programming Languages</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Colibri_Programming_Languages&amp;diff=7515"/>
		<updated>2026-05-09T06:33:40Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* zeptoforth */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= zeptoforth =&lt;br /&gt;
&lt;br /&gt;
[[zeptoforth]] is a possible programming language for the Colibri family. Each I/O module will contain the source code for its own usage, meaning that the MCU's firmware doesn't need updating when new I/O modules are available and installed.&lt;br /&gt;
&lt;br /&gt;
Forth is a unique programming language and some people are very unhappy with it, and hence we will try to support additional programming languages to the best of our abilities.&lt;br /&gt;
&lt;br /&gt;
= MicroPython =&lt;br /&gt;
[[MicroPython]] is a rather large environment, and it will be challenging (or even impossible) to squeeze it into some of the MCUs (such as MCU1 with the LoraWAN stack).&lt;br /&gt;
&lt;br /&gt;
= Lua =&lt;br /&gt;
[[Lua]] is a  neat little language that is easily embeddable in any C hosted (and other) environment. The flash memory footprint is said to be in the 100-200kB range.&lt;br /&gt;
&lt;br /&gt;
= C++ - Arduino =&lt;br /&gt;
Since we are using most STM32 MCUs, and practically every MCU marketed at the Maker community is supporting the Arduino approach. Now, the recent acquisition of Arduino by Qualcomm might lead to a decline in the platoform's popularity, and CurrentMakers is too small to invest resources in this uncertainty. The only reason to use Arduino software platform is because of its incredible popularity.&lt;br /&gt;
&lt;br /&gt;
= C - STM32Cube HAL / Bare-metal =&lt;br /&gt;
It is of course very possible to implement a software stack for Colibri using C. Libraries for peripheral access is readily available, or it is quite easy to implement in bare metal programming, see STM32World's [[https://www.youtube.com/playlist?list=PLVfOnriB1RjUO4qv9lQcYVliGpt8T3gOR bare metal video series]].&lt;br /&gt;
&lt;br /&gt;
= OpenPLC =&lt;br /&gt;
[https://autonomylogic.com/ OpenPLC] (from a company called Autonomy) is an interesting choice, especially for PLC professionals. It allows for [https://en.wikipedia.org/wiki/IEC_61131-3 IEC 61131-3 standard] programs to be compiled to C and flashed into MCUs. It supports some STM32, ESP32 and RP2350 (external Flash). It is quite likely it is not too difficult to make this work.&lt;br /&gt;
&lt;br /&gt;
= WebAssembly =&lt;br /&gt;
WebAssembly is a kind of runtime sandbox with a well-defined instruction set and memory model. Many languages can be compiled to WebAssembly with the LLVM project. The main advantage to pull this off would be to have a stable runtime on the MCU and &amp;quot;upload&amp;quot; user programs without flashing a binary. What to compile ''from'' would still be up for debate.&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Colibri_WebAssembly_Notes&amp;diff=7511</id>
		<title>Colibri WebAssembly Notes</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Colibri_WebAssembly_Notes&amp;diff=7511"/>
		<updated>2026-05-07T04:02:09Z</updated>

		<summary type="html">&lt;p&gt;Niclas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Various notes, investigations and other useful information that might be needed later.&lt;br /&gt;
&lt;br /&gt;
= WASM3 peculiarity = &lt;br /&gt;
I am loading 8 different WASM binaries, and each are called its &amp;lt;code&amp;gt;event()&amp;lt;/code&amp;gt; function every 10ms.&lt;br /&gt;
&lt;br /&gt;
7 of the does the blinking of the RGB LEDs and the last one doesn't.&lt;br /&gt;
&lt;br /&gt;
I changed the last one to be the same as the first one. And again the last one doesn't blink the LED. So, it is not the WASM code that is the issue.&lt;br /&gt;
&lt;br /&gt;
I can single step through the wasm execution and there is nothing that stands out. However, since only the &amp;quot;if(next &amp;lt; now)&amp;quot; is executed, then there is not that much that is happening.&lt;br /&gt;
&lt;br /&gt;
= Zephyr Mutexes =&lt;br /&gt;
I now have a case where the a zephyr mutex was set up in main(), and later called from a different Zephyr thread, and immediately crashes.&lt;br /&gt;
&lt;br /&gt;
    k_mutex_lock(&amp;amp;data-&amp;gt;lock, K_FOREVER);&lt;br /&gt;
&lt;br /&gt;
That is an inlined function of&lt;br /&gt;
    __pinned_func&lt;br /&gt;
    static inline int k_mutex_lock(struct k_mutex * mutex, k_timeout_t timeout)&lt;br /&gt;
    {&lt;br /&gt;
        compiler_barrier();&lt;br /&gt;
        return z_impl_k_mutex_lock(mutex, timeout);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
And &amp;lt;code&amp;gt;compiler_barrier()&amp;lt;/code&amp;gt; expands to &lt;br /&gt;
&lt;br /&gt;
    do { __asm__ __volatile__ (&amp;quot;&amp;quot; ::: &amp;quot;memory&amp;quot;); }&lt;br /&gt;
    while (0);&lt;br /&gt;
&lt;br /&gt;
on the STM32.&lt;br /&gt;
&lt;br /&gt;
I am now moving code around to ensure that it is always the same thread calling the mutex.&lt;br /&gt;
&lt;br /&gt;
Hmmm... Now instead completely crashing, it is ending up in &lt;br /&gt;
&lt;br /&gt;
    void arch_system_halt(unsigned int reason){}&lt;br /&gt;
&lt;br /&gt;
with a reason=4, which is &amp;lt;code&amp;gt;K_ERR_KERNEL_PANIC&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Call stack reveals nothing.&lt;br /&gt;
&lt;br /&gt;
    arch_system_halt fatal.c:30&lt;br /&gt;
    k_sys_fatal_error_handler fatal.c:44&lt;br /&gt;
    z_fatal_error fatal.c:119&lt;br /&gt;
    z_arm_fatal_error fatal.c:93&lt;br /&gt;
    z_arm_fault fault.c:1090&lt;br /&gt;
    z_arm_usage_fault fault_s.S:103&lt;br /&gt;
    assert_post_action assert.c:44&lt;br /&gt;
    z_spinlock_validate_pre spinlock.h:132&lt;br /&gt;
    k_spin_lock spinlock.h:192&lt;br /&gt;
    z_unpend1_no_timeout sched.c:717&lt;br /&gt;
    z_impl_k_timer_stop timer.c:276&lt;br /&gt;
    z_log_msg_post_finalize log_core.c:195&lt;br /&gt;
    msg_commit log_core.c:717&lt;br /&gt;
    z_log_msg_commit log_core.c:723&lt;br /&gt;
    z_log_msg_finalize log_msg.c:54&lt;br /&gt;
    z_log_msg_simple_create log_msg.c:130&lt;br /&gt;
    z_impl_z_log_msg_simple_create_1 log_msg.c:229&lt;br /&gt;
    esf_dump fatal.c:67&lt;br /&gt;
    z_arm_fatal_error fatal.c:76&lt;br /&gt;
    z_do_kernel_oops fatal.c:141&lt;br /&gt;
    z_arm_svc svc.S:158&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Need more work here...&lt;br /&gt;
That was an unsolved PANIC, but after a bit more fiddling with memory settings, I got to a point where a very clear Stack Overflow occurred. And that was due to stack size for the I/O subsystem thread was set too small. 1024 wasn't enough to execute WASM3 and the stuff I had around it.&lt;br /&gt;
&lt;br /&gt;
= CMake for I/O drivers =&lt;br /&gt;
It is crucial that the wasm binary is stripped of all meta data. This is an example of a reasonable &amp;lt;code&amp;gt;CMakeLists.txt&amp;lt;/code&amp;gt; for the [[Colibri DIO1]] module.&lt;br /&gt;
&lt;br /&gt;
    cmake_minimum_required(VERSION 3.5)&lt;br /&gt;
    set(CMAKE_LINK_DEPENDS_USE_LINKER FALSE)&lt;br /&gt;
    project(io_dio1 C)&lt;br /&gt;
    &lt;br /&gt;
    set(CMAKE_C_STANDARD 11)&lt;br /&gt;
    set(CMAKE_C_COMPILER clang)&lt;br /&gt;
    &lt;br /&gt;
    include_directories(colibri-sdk/)&lt;br /&gt;
    &lt;br /&gt;
    add_executable(io_dio1 dio1.c)&lt;br /&gt;
    set_target_properties(io_dio1 PROPERTIES SUFFIX &amp;quot;.wasm&amp;quot;)&lt;br /&gt;
    &lt;br /&gt;
    target_compile_options(io_dio1 PRIVATE&lt;br /&gt;
            --target=wasm32&lt;br /&gt;
            -Oz&lt;br /&gt;
            -ffunction-sections&lt;br /&gt;
            -fdata-sections&lt;br /&gt;
    )&lt;br /&gt;
    &lt;br /&gt;
    target_link_options(io_dio1 PRIVATE&lt;br /&gt;
            --target=wasm32-unknown-unknown-wasm  # or just =wasm&lt;br /&gt;
            -nostdlib&lt;br /&gt;
            -Wl,--no-entry&lt;br /&gt;
            -Wl,--allow-undefined&lt;br /&gt;
            -Wl,--gc-sections&lt;br /&gt;
            -Wl,--strip-all&lt;br /&gt;
    &lt;br /&gt;
            # Exports&lt;br /&gt;
            -Wl,--export=event&lt;br /&gt;
            -Wl,--export=init&lt;br /&gt;
            -Wl,--export=loaded&lt;br /&gt;
            -Wl,--export=unloading&lt;br /&gt;
    &lt;br /&gt;
            # Memory Management&lt;br /&gt;
            -Wl,--import-memory        # Host provides the memory&lt;br /&gt;
            -Wl,--initial-memory=65536 # Request 2 pages (required for standard compliance)&lt;br /&gt;
            -Wl,--max-memory=65536     # Cap it at 2 pages&lt;br /&gt;
            -Wl,-z,stack-size=512      # Shrink WASM-internal stack (Default is often 64KB!)&lt;br /&gt;
    )&lt;br /&gt;
    &lt;br /&gt;
    add_custom_command(&lt;br /&gt;
            TARGET io_dio1 POST_BUILD&lt;br /&gt;
            COMMAND xxd -i -n io_dio1 ${CMAKE_BINARY_DIR}/io_dio1/io_dio1.wasm | sed 's/unsigned /const unsigned /' &amp;gt;${CMAKE_BINARY_DIR}/io_dio1.h&lt;br /&gt;
            WORKING_DIRECTORY ${CMAKE_BINARY_DIR}&lt;br /&gt;
            COMMENT &amp;quot;Generating io_dio1.h from io_dio1.wasm using xxd&amp;quot;&lt;br /&gt;
    )&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
= Memory Allocations =&lt;br /&gt;
This was an investigation into how much RAM is used to instantiate WebAssembly runtimes. 8 wasm files were deployed, each blinking the LED for the respective slot.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    ---- Program to be loaded  ----&lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
    #include &amp;quot;colibri.h&amp;quot;&lt;br /&gt;
    #define export __attribute__((visibility(&amp;quot;default&amp;quot;)))&lt;br /&gt;
    &lt;br /&gt;
    static int next = 0;&lt;br /&gt;
    static int state = 0;&lt;br /&gt;
    &lt;br /&gt;
    int tick(long time) {&lt;br /&gt;
        if (next &amp;lt; time) {&lt;br /&gt;
            if (state){&lt;br /&gt;
                set_rgb_error();&lt;br /&gt;
                next = time + 100;&lt;br /&gt;
            }&lt;br /&gt;
            else {&lt;br /&gt;
                set_rgb_off();&lt;br /&gt;
                next = time + 500;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        return state;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    export void event(int id, long value) {&lt;br /&gt;
        tick(value);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    export void init() {&lt;br /&gt;
        set_rgb_ok_color(0x000400);&lt;br /&gt;
        set_rgb_warning_color(0x040400);&lt;br /&gt;
        set_rgb_error_color(0x080000);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    export void loaded() {&lt;br /&gt;
        set_rgb_off();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    export void unloading() {&lt;br /&gt;
        set_rgb_off();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    Env      Heap @ 0x10000000    112  bytes&lt;br /&gt;
    wasm0    Heap @ 0x10000070    4960 bytes&lt;br /&gt;
    wasm1    Heap @ 0x100013D0    4368 bytes&lt;br /&gt;
    wasm2    Heap @ 0x100024E0    4368 bytes&lt;br /&gt;
    wasm3    Heap @ 0x100035f0    4368 bytes&lt;br /&gt;
    wasm4    Heap @ 0x10004700    4608 bytes&lt;br /&gt;
    wasm5    Heap @ 0x10005900    4368 bytes&lt;br /&gt;
    wasm6    Heap @ 0x10006a10    4368 bytes&lt;br /&gt;
    wasm7    Heap @ 0x10007b20    5200 bytes&lt;br /&gt;
    End      Heap @ 0x10008F70&lt;br /&gt;
    &lt;br /&gt;
    ----- Once -----&lt;br /&gt;
    NewEnvironment&lt;br /&gt;
        M3Environment struct    0x20&lt;br /&gt;
        AllocFuncType           0x09&lt;br /&gt;
        AllocFuncType           0x09&lt;br /&gt;
        AllocFuncType           0x09&lt;br /&gt;
        AllocFuncType           0x09&lt;br /&gt;
        AllocFuncType           0x09&lt;br /&gt;
        &lt;br /&gt;
    -----  Per wasm  ---&lt;br /&gt;
    &lt;br /&gt;
    NewRuntime&lt;br /&gt;
        M3Runtime  struct       0x434&lt;br /&gt;
        runtime-&amp;gt;origStack      0x410  (stack + 4 32bit words)        &lt;br /&gt;
        &lt;br /&gt;
    ParseModule&lt;br /&gt;
        M3Module    module      0x78&lt;br /&gt;
        io_module-&amp;gt;functTypes   0x0c&lt;br /&gt;
        AllocFuncType           0x08&lt;br /&gt;
        Free&lt;br /&gt;
        AllocFuncType           0x09&lt;br /&gt;
        Free&lt;br /&gt;
        AllocFuncType           0x0A&lt;br /&gt;
        Free&lt;br /&gt;
        PreAllocFunctions       0x154  (5 functions * 68 bytes?)&lt;br /&gt;
        &amp;quot;env&amp;quot;                   0x04   &lt;br /&gt;
        &amp;quot;memory&amp;quot;                0x07&lt;br /&gt;
        Free NULL                       (freeing import, module name)&lt;br /&gt;
        Free NULL                       (freeing import, field name)&lt;br /&gt;
        &amp;quot;env&amp;quot;                   0x04   &lt;br /&gt;
        &amp;quot;set_rgb_off&amp;quot;           0x0C&lt;br /&gt;
        Free NULL                       (freeing import, module name)&lt;br /&gt;
        Free NULL                       (freeing import, field name)&lt;br /&gt;
        &amp;quot;env&amp;quot;                   0x04   &lt;br /&gt;
        &amp;quot;set_rgb_ok_color&amp;quot;      0x11&lt;br /&gt;
        Free NULL                       (freeing import, module name)&lt;br /&gt;
        Free NULL                       (freeing import, field name)&lt;br /&gt;
        &amp;quot;env&amp;quot;                   0x04   &lt;br /&gt;
        &amp;quot;set_rgb_warning_color&amp;quot; 0x16&lt;br /&gt;
        Free NULL                       (freeing import, module name)&lt;br /&gt;
        Free NULL                       (freeing import, field name)&lt;br /&gt;
        &amp;quot;env&amp;quot;                   0x04   &lt;br /&gt;
        &amp;quot;set_rgb_error_color&amp;quot;   0x14&lt;br /&gt;
        Free NULL                       (freeing import, module name)&lt;br /&gt;
        Free NULL                       (freeing import, field name)&lt;br /&gt;
        Free NULL                       (freeing import, module name)&lt;br /&gt;
        Free NULL                       (freeing import, field name)&lt;br /&gt;
        PreAllocFunctions       0x220  &lt;br /&gt;
        AddGlobal               0x20&lt;br /&gt;
        &amp;quot;event&amp;quot;                 0x06    (exports)&lt;br /&gt;
        Free NULL                       (exported name)                       &lt;br /&gt;
        &amp;quot;init&amp;quot;                  0x05&lt;br /&gt;
        Free NULL                       (exported name)                       &lt;br /&gt;
        &amp;quot;loaded&amp;quot;                0x07&lt;br /&gt;
        Free NULL                       (exported name)                       &lt;br /&gt;
        &amp;quot;unloading&amp;quot;             0x0A&lt;br /&gt;
        Free NULL                       (exported name)                       &lt;br /&gt;
        Free NULL                       (one extra exported name)                       &lt;br /&gt;
        M3DataSegments          0x20    (0 data segment)&lt;br /&gt;
        &lt;br /&gt;
    LoadModule&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        Free NULL&lt;br /&gt;
        Free NULL&lt;br /&gt;
        Free NULL&lt;br /&gt;
        Free NULL&lt;br /&gt;
        AllocFuncType           0x09&lt;br /&gt;
        Free &lt;br /&gt;
        AllocFuncType           0x09&lt;br /&gt;
        Free &lt;br /&gt;
        AllocFuncType           0x09&lt;br /&gt;
        Free &lt;br /&gt;
        AllocFuncType           0x09&lt;br /&gt;
        Free &lt;br /&gt;
        AllocFuncType           0x09&lt;br /&gt;
        Free &lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        CompileFunction         0x08    (&amp;quot;event&amp;quot;)&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        CompileFunction         0x12    (&amp;quot;init&amp;quot;)&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        CompileFunction         0x14&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Colibri_WebAssembly_Notes&amp;diff=7510</id>
		<title>Colibri WebAssembly Notes</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Colibri_WebAssembly_Notes&amp;diff=7510"/>
		<updated>2026-05-06T08:42:00Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* Zephyr Mutexes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Various notes, investigations and other useful information that might be needed later.&lt;br /&gt;
&lt;br /&gt;
= Zephyr Mutexes =&lt;br /&gt;
I now have a case where the a zephyr mutex was set up in main(), and later called from a different Zephyr thread, and immediately crashes.&lt;br /&gt;
&lt;br /&gt;
    k_mutex_lock(&amp;amp;data-&amp;gt;lock, K_FOREVER);&lt;br /&gt;
&lt;br /&gt;
That is an inlined function of&lt;br /&gt;
    __pinned_func&lt;br /&gt;
    static inline int k_mutex_lock(struct k_mutex * mutex, k_timeout_t timeout)&lt;br /&gt;
    {&lt;br /&gt;
        compiler_barrier();&lt;br /&gt;
        return z_impl_k_mutex_lock(mutex, timeout);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
And &amp;lt;code&amp;gt;compiler_barrier()&amp;lt;/code&amp;gt; expands to &lt;br /&gt;
&lt;br /&gt;
    do { __asm__ __volatile__ (&amp;quot;&amp;quot; ::: &amp;quot;memory&amp;quot;); }&lt;br /&gt;
    while (0);&lt;br /&gt;
&lt;br /&gt;
on the STM32.&lt;br /&gt;
&lt;br /&gt;
I am now moving code around to ensure that it is always the same thread calling the mutex.&lt;br /&gt;
&lt;br /&gt;
Hmmm... Now instead completely crashing, it is ending up in &lt;br /&gt;
&lt;br /&gt;
    void arch_system_halt(unsigned int reason){}&lt;br /&gt;
&lt;br /&gt;
with a reason=4, which is &amp;lt;code&amp;gt;K_ERR_KERNEL_PANIC&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Call stack reveals nothing.&lt;br /&gt;
&lt;br /&gt;
    arch_system_halt fatal.c:30&lt;br /&gt;
    k_sys_fatal_error_handler fatal.c:44&lt;br /&gt;
    z_fatal_error fatal.c:119&lt;br /&gt;
    z_arm_fatal_error fatal.c:93&lt;br /&gt;
    z_arm_fault fault.c:1090&lt;br /&gt;
    z_arm_usage_fault fault_s.S:103&lt;br /&gt;
    assert_post_action assert.c:44&lt;br /&gt;
    z_spinlock_validate_pre spinlock.h:132&lt;br /&gt;
    k_spin_lock spinlock.h:192&lt;br /&gt;
    z_unpend1_no_timeout sched.c:717&lt;br /&gt;
    z_impl_k_timer_stop timer.c:276&lt;br /&gt;
    z_log_msg_post_finalize log_core.c:195&lt;br /&gt;
    msg_commit log_core.c:717&lt;br /&gt;
    z_log_msg_commit log_core.c:723&lt;br /&gt;
    z_log_msg_finalize log_msg.c:54&lt;br /&gt;
    z_log_msg_simple_create log_msg.c:130&lt;br /&gt;
    z_impl_z_log_msg_simple_create_1 log_msg.c:229&lt;br /&gt;
    esf_dump fatal.c:67&lt;br /&gt;
    z_arm_fatal_error fatal.c:76&lt;br /&gt;
    z_do_kernel_oops fatal.c:141&lt;br /&gt;
    z_arm_svc svc.S:158&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Need more work here...&lt;br /&gt;
&lt;br /&gt;
= CMake for I/O drivers =&lt;br /&gt;
It is crucial that the wasm binary is stripped of all meta data. This is an example of a reasonable &amp;lt;code&amp;gt;CMakeLists.txt&amp;lt;/code&amp;gt; for the [[Colibri DIO1]] module.&lt;br /&gt;
&lt;br /&gt;
    cmake_minimum_required(VERSION 3.5)&lt;br /&gt;
    set(CMAKE_LINK_DEPENDS_USE_LINKER FALSE)&lt;br /&gt;
    project(io_dio1 C)&lt;br /&gt;
    &lt;br /&gt;
    set(CMAKE_C_STANDARD 11)&lt;br /&gt;
    set(CMAKE_C_COMPILER clang)&lt;br /&gt;
    &lt;br /&gt;
    include_directories(colibri-sdk/)&lt;br /&gt;
    &lt;br /&gt;
    add_executable(io_dio1 dio1.c)&lt;br /&gt;
    set_target_properties(io_dio1 PROPERTIES SUFFIX &amp;quot;.wasm&amp;quot;)&lt;br /&gt;
    &lt;br /&gt;
    target_compile_options(io_dio1 PRIVATE&lt;br /&gt;
            --target=wasm32&lt;br /&gt;
            -Oz&lt;br /&gt;
            -ffunction-sections&lt;br /&gt;
            -fdata-sections&lt;br /&gt;
    )&lt;br /&gt;
    &lt;br /&gt;
    target_link_options(io_dio1 PRIVATE&lt;br /&gt;
            --target=wasm32-unknown-unknown-wasm  # or just =wasm&lt;br /&gt;
            -nostdlib&lt;br /&gt;
            -Wl,--no-entry&lt;br /&gt;
            -Wl,--allow-undefined&lt;br /&gt;
            -Wl,--gc-sections&lt;br /&gt;
            -Wl,--strip-all&lt;br /&gt;
    &lt;br /&gt;
            # Exports&lt;br /&gt;
            -Wl,--export=event&lt;br /&gt;
            -Wl,--export=init&lt;br /&gt;
            -Wl,--export=loaded&lt;br /&gt;
            -Wl,--export=unloading&lt;br /&gt;
    &lt;br /&gt;
            # Memory Management&lt;br /&gt;
            -Wl,--import-memory        # Host provides the memory&lt;br /&gt;
            -Wl,--initial-memory=65536 # Request 2 pages (required for standard compliance)&lt;br /&gt;
            -Wl,--max-memory=65536     # Cap it at 2 pages&lt;br /&gt;
            -Wl,-z,stack-size=512      # Shrink WASM-internal stack (Default is often 64KB!)&lt;br /&gt;
    )&lt;br /&gt;
    &lt;br /&gt;
    add_custom_command(&lt;br /&gt;
            TARGET io_dio1 POST_BUILD&lt;br /&gt;
            COMMAND xxd -i -n io_dio1 ${CMAKE_BINARY_DIR}/io_dio1/io_dio1.wasm | sed 's/unsigned /const unsigned /' &amp;gt;${CMAKE_BINARY_DIR}/io_dio1.h&lt;br /&gt;
            WORKING_DIRECTORY ${CMAKE_BINARY_DIR}&lt;br /&gt;
            COMMENT &amp;quot;Generating io_dio1.h from io_dio1.wasm using xxd&amp;quot;&lt;br /&gt;
    )&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
= Memory Allocations =&lt;br /&gt;
This was an investigation into how much RAM is used to instantiate WebAssembly runtimes. 8 wasm files were deployed, each blinking the LED for the respective slot.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    ---- Program to be loaded  ----&lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
    #include &amp;quot;colibri.h&amp;quot;&lt;br /&gt;
    #define export __attribute__((visibility(&amp;quot;default&amp;quot;)))&lt;br /&gt;
    &lt;br /&gt;
    static int next = 0;&lt;br /&gt;
    static int state = 0;&lt;br /&gt;
    &lt;br /&gt;
    int tick(long time) {&lt;br /&gt;
        if (next &amp;lt; time) {&lt;br /&gt;
            if (state){&lt;br /&gt;
                set_rgb_error();&lt;br /&gt;
                next = time + 100;&lt;br /&gt;
            }&lt;br /&gt;
            else {&lt;br /&gt;
                set_rgb_off();&lt;br /&gt;
                next = time + 500;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        return state;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    export void event(int id, long value) {&lt;br /&gt;
        tick(value);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    export void init() {&lt;br /&gt;
        set_rgb_ok_color(0x000400);&lt;br /&gt;
        set_rgb_warning_color(0x040400);&lt;br /&gt;
        set_rgb_error_color(0x080000);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    export void loaded() {&lt;br /&gt;
        set_rgb_off();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    export void unloading() {&lt;br /&gt;
        set_rgb_off();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    Env      Heap @ 0x10000000    112  bytes&lt;br /&gt;
    wasm0    Heap @ 0x10000070    4960 bytes&lt;br /&gt;
    wasm1    Heap @ 0x100013D0    4368 bytes&lt;br /&gt;
    wasm2    Heap @ 0x100024E0    4368 bytes&lt;br /&gt;
    wasm3    Heap @ 0x100035f0    4368 bytes&lt;br /&gt;
    wasm4    Heap @ 0x10004700    4608 bytes&lt;br /&gt;
    wasm5    Heap @ 0x10005900    4368 bytes&lt;br /&gt;
    wasm6    Heap @ 0x10006a10    4368 bytes&lt;br /&gt;
    wasm7    Heap @ 0x10007b20    5200 bytes&lt;br /&gt;
    End      Heap @ 0x10008F70&lt;br /&gt;
    &lt;br /&gt;
    ----- Once -----&lt;br /&gt;
    NewEnvironment&lt;br /&gt;
        M3Environment struct    0x20&lt;br /&gt;
        AllocFuncType           0x09&lt;br /&gt;
        AllocFuncType           0x09&lt;br /&gt;
        AllocFuncType           0x09&lt;br /&gt;
        AllocFuncType           0x09&lt;br /&gt;
        AllocFuncType           0x09&lt;br /&gt;
        &lt;br /&gt;
    -----  Per wasm  ---&lt;br /&gt;
    &lt;br /&gt;
    NewRuntime&lt;br /&gt;
        M3Runtime  struct       0x434&lt;br /&gt;
        runtime-&amp;gt;origStack      0x410  (stack + 4 32bit words)        &lt;br /&gt;
        &lt;br /&gt;
    ParseModule&lt;br /&gt;
        M3Module    module      0x78&lt;br /&gt;
        io_module-&amp;gt;functTypes   0x0c&lt;br /&gt;
        AllocFuncType           0x08&lt;br /&gt;
        Free&lt;br /&gt;
        AllocFuncType           0x09&lt;br /&gt;
        Free&lt;br /&gt;
        AllocFuncType           0x0A&lt;br /&gt;
        Free&lt;br /&gt;
        PreAllocFunctions       0x154  (5 functions * 68 bytes?)&lt;br /&gt;
        &amp;quot;env&amp;quot;                   0x04   &lt;br /&gt;
        &amp;quot;memory&amp;quot;                0x07&lt;br /&gt;
        Free NULL                       (freeing import, module name)&lt;br /&gt;
        Free NULL                       (freeing import, field name)&lt;br /&gt;
        &amp;quot;env&amp;quot;                   0x04   &lt;br /&gt;
        &amp;quot;set_rgb_off&amp;quot;           0x0C&lt;br /&gt;
        Free NULL                       (freeing import, module name)&lt;br /&gt;
        Free NULL                       (freeing import, field name)&lt;br /&gt;
        &amp;quot;env&amp;quot;                   0x04   &lt;br /&gt;
        &amp;quot;set_rgb_ok_color&amp;quot;      0x11&lt;br /&gt;
        Free NULL                       (freeing import, module name)&lt;br /&gt;
        Free NULL                       (freeing import, field name)&lt;br /&gt;
        &amp;quot;env&amp;quot;                   0x04   &lt;br /&gt;
        &amp;quot;set_rgb_warning_color&amp;quot; 0x16&lt;br /&gt;
        Free NULL                       (freeing import, module name)&lt;br /&gt;
        Free NULL                       (freeing import, field name)&lt;br /&gt;
        &amp;quot;env&amp;quot;                   0x04   &lt;br /&gt;
        &amp;quot;set_rgb_error_color&amp;quot;   0x14&lt;br /&gt;
        Free NULL                       (freeing import, module name)&lt;br /&gt;
        Free NULL                       (freeing import, field name)&lt;br /&gt;
        Free NULL                       (freeing import, module name)&lt;br /&gt;
        Free NULL                       (freeing import, field name)&lt;br /&gt;
        PreAllocFunctions       0x220  &lt;br /&gt;
        AddGlobal               0x20&lt;br /&gt;
        &amp;quot;event&amp;quot;                 0x06    (exports)&lt;br /&gt;
        Free NULL                       (exported name)                       &lt;br /&gt;
        &amp;quot;init&amp;quot;                  0x05&lt;br /&gt;
        Free NULL                       (exported name)                       &lt;br /&gt;
        &amp;quot;loaded&amp;quot;                0x07&lt;br /&gt;
        Free NULL                       (exported name)                       &lt;br /&gt;
        &amp;quot;unloading&amp;quot;             0x0A&lt;br /&gt;
        Free NULL                       (exported name)                       &lt;br /&gt;
        Free NULL                       (one extra exported name)                       &lt;br /&gt;
        M3DataSegments          0x20    (0 data segment)&lt;br /&gt;
        &lt;br /&gt;
    LoadModule&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        Free NULL&lt;br /&gt;
        Free NULL&lt;br /&gt;
        Free NULL&lt;br /&gt;
        Free NULL&lt;br /&gt;
        AllocFuncType           0x09&lt;br /&gt;
        Free &lt;br /&gt;
        AllocFuncType           0x09&lt;br /&gt;
        Free &lt;br /&gt;
        AllocFuncType           0x09&lt;br /&gt;
        Free &lt;br /&gt;
        AllocFuncType           0x09&lt;br /&gt;
        Free &lt;br /&gt;
        AllocFuncType           0x09&lt;br /&gt;
        Free &lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        CompileFunction         0x08    (&amp;quot;event&amp;quot;)&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        CompileFunction         0x12    (&amp;quot;init&amp;quot;)&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        CompileFunction         0x14&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Colibri_WebAssembly_Notes&amp;diff=7509</id>
		<title>Colibri WebAssembly Notes</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Colibri_WebAssembly_Notes&amp;diff=7509"/>
		<updated>2026-05-06T08:37:03Z</updated>

		<summary type="html">&lt;p&gt;Niclas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Various notes, investigations and other useful information that might be needed later.&lt;br /&gt;
&lt;br /&gt;
= Zephyr Mutexes =&lt;br /&gt;
I now have a case where the a zephyr mutex was set up in main(), and later called from a different Zephyr thread, and immediately crashes.&lt;br /&gt;
&lt;br /&gt;
    k_mutex_lock(&amp;amp;data-&amp;gt;lock, K_FOREVER);&lt;br /&gt;
&lt;br /&gt;
That is an inlined function of&lt;br /&gt;
    __pinned_func&lt;br /&gt;
    static inline int k_mutex_lock(struct k_mutex * mutex, k_timeout_t timeout)&lt;br /&gt;
    {&lt;br /&gt;
        compiler_barrier();&lt;br /&gt;
        return z_impl_k_mutex_lock(mutex, timeout);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
And &amp;lt;code&amp;gt;compiler_barrier()&amp;lt;/code&amp;gt; expands to &lt;br /&gt;
&lt;br /&gt;
    do { __asm__ __volatile__ (&amp;quot;&amp;quot; ::: &amp;quot;memory&amp;quot;); }&lt;br /&gt;
    while (0);&lt;br /&gt;
&lt;br /&gt;
on the STM32.&lt;br /&gt;
&lt;br /&gt;
I am now moving code around to ensure that it is always the same thread calling the mutex.&lt;br /&gt;
&lt;br /&gt;
Hmmm... Now instead completely crashing, it is ending up in &lt;br /&gt;
&lt;br /&gt;
    void arch_system_halt(unsigned int reason){}&lt;br /&gt;
&lt;br /&gt;
with a reason=4, which is &amp;lt;code&amp;gt;K_ERR_KERNEL_PANIC&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Need more work here...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= CMake for I/O drivers =&lt;br /&gt;
It is crucial that the wasm binary is stripped of all meta data. This is an example of a reasonable &amp;lt;code&amp;gt;CMakeLists.txt&amp;lt;/code&amp;gt; for the [[Colibri DIO1]] module.&lt;br /&gt;
&lt;br /&gt;
    cmake_minimum_required(VERSION 3.5)&lt;br /&gt;
    set(CMAKE_LINK_DEPENDS_USE_LINKER FALSE)&lt;br /&gt;
    project(io_dio1 C)&lt;br /&gt;
    &lt;br /&gt;
    set(CMAKE_C_STANDARD 11)&lt;br /&gt;
    set(CMAKE_C_COMPILER clang)&lt;br /&gt;
    &lt;br /&gt;
    include_directories(colibri-sdk/)&lt;br /&gt;
    &lt;br /&gt;
    add_executable(io_dio1 dio1.c)&lt;br /&gt;
    set_target_properties(io_dio1 PROPERTIES SUFFIX &amp;quot;.wasm&amp;quot;)&lt;br /&gt;
    &lt;br /&gt;
    target_compile_options(io_dio1 PRIVATE&lt;br /&gt;
            --target=wasm32&lt;br /&gt;
            -Oz&lt;br /&gt;
            -ffunction-sections&lt;br /&gt;
            -fdata-sections&lt;br /&gt;
    )&lt;br /&gt;
    &lt;br /&gt;
    target_link_options(io_dio1 PRIVATE&lt;br /&gt;
            --target=wasm32-unknown-unknown-wasm  # or just =wasm&lt;br /&gt;
            -nostdlib&lt;br /&gt;
            -Wl,--no-entry&lt;br /&gt;
            -Wl,--allow-undefined&lt;br /&gt;
            -Wl,--gc-sections&lt;br /&gt;
            -Wl,--strip-all&lt;br /&gt;
    &lt;br /&gt;
            # Exports&lt;br /&gt;
            -Wl,--export=event&lt;br /&gt;
            -Wl,--export=init&lt;br /&gt;
            -Wl,--export=loaded&lt;br /&gt;
            -Wl,--export=unloading&lt;br /&gt;
    &lt;br /&gt;
            # Memory Management&lt;br /&gt;
            -Wl,--import-memory        # Host provides the memory&lt;br /&gt;
            -Wl,--initial-memory=65536 # Request 2 pages (required for standard compliance)&lt;br /&gt;
            -Wl,--max-memory=65536     # Cap it at 2 pages&lt;br /&gt;
            -Wl,-z,stack-size=512      # Shrink WASM-internal stack (Default is often 64KB!)&lt;br /&gt;
    )&lt;br /&gt;
    &lt;br /&gt;
    add_custom_command(&lt;br /&gt;
            TARGET io_dio1 POST_BUILD&lt;br /&gt;
            COMMAND xxd -i -n io_dio1 ${CMAKE_BINARY_DIR}/io_dio1/io_dio1.wasm | sed 's/unsigned /const unsigned /' &amp;gt;${CMAKE_BINARY_DIR}/io_dio1.h&lt;br /&gt;
            WORKING_DIRECTORY ${CMAKE_BINARY_DIR}&lt;br /&gt;
            COMMENT &amp;quot;Generating io_dio1.h from io_dio1.wasm using xxd&amp;quot;&lt;br /&gt;
    )&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
= Memory Allocations =&lt;br /&gt;
This was an investigation into how much RAM is used to instantiate WebAssembly runtimes. 8 wasm files were deployed, each blinking the LED for the respective slot.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    ---- Program to be loaded  ----&lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
    #include &amp;quot;colibri.h&amp;quot;&lt;br /&gt;
    #define export __attribute__((visibility(&amp;quot;default&amp;quot;)))&lt;br /&gt;
    &lt;br /&gt;
    static int next = 0;&lt;br /&gt;
    static int state = 0;&lt;br /&gt;
    &lt;br /&gt;
    int tick(long time) {&lt;br /&gt;
        if (next &amp;lt; time) {&lt;br /&gt;
            if (state){&lt;br /&gt;
                set_rgb_error();&lt;br /&gt;
                next = time + 100;&lt;br /&gt;
            }&lt;br /&gt;
            else {&lt;br /&gt;
                set_rgb_off();&lt;br /&gt;
                next = time + 500;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        return state;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    export void event(int id, long value) {&lt;br /&gt;
        tick(value);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    export void init() {&lt;br /&gt;
        set_rgb_ok_color(0x000400);&lt;br /&gt;
        set_rgb_warning_color(0x040400);&lt;br /&gt;
        set_rgb_error_color(0x080000);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    export void loaded() {&lt;br /&gt;
        set_rgb_off();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    export void unloading() {&lt;br /&gt;
        set_rgb_off();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    Env      Heap @ 0x10000000    112  bytes&lt;br /&gt;
    wasm0    Heap @ 0x10000070    4960 bytes&lt;br /&gt;
    wasm1    Heap @ 0x100013D0    4368 bytes&lt;br /&gt;
    wasm2    Heap @ 0x100024E0    4368 bytes&lt;br /&gt;
    wasm3    Heap @ 0x100035f0    4368 bytes&lt;br /&gt;
    wasm4    Heap @ 0x10004700    4608 bytes&lt;br /&gt;
    wasm5    Heap @ 0x10005900    4368 bytes&lt;br /&gt;
    wasm6    Heap @ 0x10006a10    4368 bytes&lt;br /&gt;
    wasm7    Heap @ 0x10007b20    5200 bytes&lt;br /&gt;
    End      Heap @ 0x10008F70&lt;br /&gt;
    &lt;br /&gt;
    ----- Once -----&lt;br /&gt;
    NewEnvironment&lt;br /&gt;
        M3Environment struct    0x20&lt;br /&gt;
        AllocFuncType           0x09&lt;br /&gt;
        AllocFuncType           0x09&lt;br /&gt;
        AllocFuncType           0x09&lt;br /&gt;
        AllocFuncType           0x09&lt;br /&gt;
        AllocFuncType           0x09&lt;br /&gt;
        &lt;br /&gt;
    -----  Per wasm  ---&lt;br /&gt;
    &lt;br /&gt;
    NewRuntime&lt;br /&gt;
        M3Runtime  struct       0x434&lt;br /&gt;
        runtime-&amp;gt;origStack      0x410  (stack + 4 32bit words)        &lt;br /&gt;
        &lt;br /&gt;
    ParseModule&lt;br /&gt;
        M3Module    module      0x78&lt;br /&gt;
        io_module-&amp;gt;functTypes   0x0c&lt;br /&gt;
        AllocFuncType           0x08&lt;br /&gt;
        Free&lt;br /&gt;
        AllocFuncType           0x09&lt;br /&gt;
        Free&lt;br /&gt;
        AllocFuncType           0x0A&lt;br /&gt;
        Free&lt;br /&gt;
        PreAllocFunctions       0x154  (5 functions * 68 bytes?)&lt;br /&gt;
        &amp;quot;env&amp;quot;                   0x04   &lt;br /&gt;
        &amp;quot;memory&amp;quot;                0x07&lt;br /&gt;
        Free NULL                       (freeing import, module name)&lt;br /&gt;
        Free NULL                       (freeing import, field name)&lt;br /&gt;
        &amp;quot;env&amp;quot;                   0x04   &lt;br /&gt;
        &amp;quot;set_rgb_off&amp;quot;           0x0C&lt;br /&gt;
        Free NULL                       (freeing import, module name)&lt;br /&gt;
        Free NULL                       (freeing import, field name)&lt;br /&gt;
        &amp;quot;env&amp;quot;                   0x04   &lt;br /&gt;
        &amp;quot;set_rgb_ok_color&amp;quot;      0x11&lt;br /&gt;
        Free NULL                       (freeing import, module name)&lt;br /&gt;
        Free NULL                       (freeing import, field name)&lt;br /&gt;
        &amp;quot;env&amp;quot;                   0x04   &lt;br /&gt;
        &amp;quot;set_rgb_warning_color&amp;quot; 0x16&lt;br /&gt;
        Free NULL                       (freeing import, module name)&lt;br /&gt;
        Free NULL                       (freeing import, field name)&lt;br /&gt;
        &amp;quot;env&amp;quot;                   0x04   &lt;br /&gt;
        &amp;quot;set_rgb_error_color&amp;quot;   0x14&lt;br /&gt;
        Free NULL                       (freeing import, module name)&lt;br /&gt;
        Free NULL                       (freeing import, field name)&lt;br /&gt;
        Free NULL                       (freeing import, module name)&lt;br /&gt;
        Free NULL                       (freeing import, field name)&lt;br /&gt;
        PreAllocFunctions       0x220  &lt;br /&gt;
        AddGlobal               0x20&lt;br /&gt;
        &amp;quot;event&amp;quot;                 0x06    (exports)&lt;br /&gt;
        Free NULL                       (exported name)                       &lt;br /&gt;
        &amp;quot;init&amp;quot;                  0x05&lt;br /&gt;
        Free NULL                       (exported name)                       &lt;br /&gt;
        &amp;quot;loaded&amp;quot;                0x07&lt;br /&gt;
        Free NULL                       (exported name)                       &lt;br /&gt;
        &amp;quot;unloading&amp;quot;             0x0A&lt;br /&gt;
        Free NULL                       (exported name)                       &lt;br /&gt;
        Free NULL                       (one extra exported name)                       &lt;br /&gt;
        M3DataSegments          0x20    (0 data segment)&lt;br /&gt;
        &lt;br /&gt;
    LoadModule&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        Free NULL&lt;br /&gt;
        Free NULL&lt;br /&gt;
        Free NULL&lt;br /&gt;
        Free NULL&lt;br /&gt;
        AllocFuncType           0x09&lt;br /&gt;
        Free &lt;br /&gt;
        AllocFuncType           0x09&lt;br /&gt;
        Free &lt;br /&gt;
        AllocFuncType           0x09&lt;br /&gt;
        Free &lt;br /&gt;
        AllocFuncType           0x09&lt;br /&gt;
        Free &lt;br /&gt;
        AllocFuncType           0x09&lt;br /&gt;
        Free &lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        CompileFunction         0x08    (&amp;quot;event&amp;quot;)&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        CompileFunction         0x12    (&amp;quot;init&amp;quot;)&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        CompileFunction         0x14&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Colibri_WebAssembly_Notes&amp;diff=7508</id>
		<title>Colibri WebAssembly Notes</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Colibri_WebAssembly_Notes&amp;diff=7508"/>
		<updated>2026-05-06T05:04:09Z</updated>

		<summary type="html">&lt;p&gt;Niclas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Various notes, investigations and other useful information that might be needed later.&lt;br /&gt;
&lt;br /&gt;
= CMake for I/O drivers =&lt;br /&gt;
It is crucial that the wasm binary is stripped of all meta data. This is an example of a reasonable &amp;lt;code&amp;gt;CMakeLists.txt&amp;lt;/code&amp;gt; for the [[Colibri DIO1]] module.&lt;br /&gt;
&lt;br /&gt;
    cmake_minimum_required(VERSION 3.5)&lt;br /&gt;
    set(CMAKE_LINK_DEPENDS_USE_LINKER FALSE)&lt;br /&gt;
    project(io_dio1 C)&lt;br /&gt;
    &lt;br /&gt;
    set(CMAKE_C_STANDARD 11)&lt;br /&gt;
    set(CMAKE_C_COMPILER clang)&lt;br /&gt;
    &lt;br /&gt;
    include_directories(colibri-sdk/)&lt;br /&gt;
    &lt;br /&gt;
    add_executable(io_dio1 dio1.c)&lt;br /&gt;
    set_target_properties(io_dio1 PROPERTIES SUFFIX &amp;quot;.wasm&amp;quot;)&lt;br /&gt;
    &lt;br /&gt;
    target_compile_options(io_dio1 PRIVATE&lt;br /&gt;
            --target=wasm32&lt;br /&gt;
            -Oz&lt;br /&gt;
            -ffunction-sections&lt;br /&gt;
            -fdata-sections&lt;br /&gt;
    )&lt;br /&gt;
    &lt;br /&gt;
    target_link_options(io_dio1 PRIVATE&lt;br /&gt;
            --target=wasm32-unknown-unknown-wasm  # or just =wasm&lt;br /&gt;
            -nostdlib&lt;br /&gt;
            -Wl,--no-entry&lt;br /&gt;
            -Wl,--allow-undefined&lt;br /&gt;
            -Wl,--gc-sections&lt;br /&gt;
            -Wl,--strip-all&lt;br /&gt;
    &lt;br /&gt;
            # Exports&lt;br /&gt;
            -Wl,--export=event&lt;br /&gt;
            -Wl,--export=init&lt;br /&gt;
            -Wl,--export=loaded&lt;br /&gt;
            -Wl,--export=unloading&lt;br /&gt;
    &lt;br /&gt;
            # Memory Management&lt;br /&gt;
            -Wl,--import-memory        # Host provides the memory&lt;br /&gt;
            -Wl,--initial-memory=65536 # Request 2 pages (required for standard compliance)&lt;br /&gt;
            -Wl,--max-memory=65536     # Cap it at 2 pages&lt;br /&gt;
            -Wl,-z,stack-size=512      # Shrink WASM-internal stack (Default is often 64KB!)&lt;br /&gt;
    )&lt;br /&gt;
    &lt;br /&gt;
    add_custom_command(&lt;br /&gt;
            TARGET io_dio1 POST_BUILD&lt;br /&gt;
            COMMAND xxd -i -n io_dio1 ${CMAKE_BINARY_DIR}/io_dio1/io_dio1.wasm | sed 's/unsigned /const unsigned /' &amp;gt;${CMAKE_BINARY_DIR}/io_dio1.h&lt;br /&gt;
            WORKING_DIRECTORY ${CMAKE_BINARY_DIR}&lt;br /&gt;
            COMMENT &amp;quot;Generating io_dio1.h from io_dio1.wasm using xxd&amp;quot;&lt;br /&gt;
    )&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
= Memory Allocations =&lt;br /&gt;
This was an investigation into how much RAM is used to instantiate WebAssembly runtimes. 8 wasm files were deployed, each blinking the LED for the respective slot.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    ---- Program to be loaded  ----&lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
    #include &amp;quot;colibri.h&amp;quot;&lt;br /&gt;
    #define export __attribute__((visibility(&amp;quot;default&amp;quot;)))&lt;br /&gt;
    &lt;br /&gt;
    static int next = 0;&lt;br /&gt;
    static int state = 0;&lt;br /&gt;
    &lt;br /&gt;
    int tick(long time) {&lt;br /&gt;
        if (next &amp;lt; time) {&lt;br /&gt;
            if (state){&lt;br /&gt;
                set_rgb_error();&lt;br /&gt;
                next = time + 100;&lt;br /&gt;
            }&lt;br /&gt;
            else {&lt;br /&gt;
                set_rgb_off();&lt;br /&gt;
                next = time + 500;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        return state;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    export void event(int id, long value) {&lt;br /&gt;
        tick(value);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    export void init() {&lt;br /&gt;
        set_rgb_ok_color(0x000400);&lt;br /&gt;
        set_rgb_warning_color(0x040400);&lt;br /&gt;
        set_rgb_error_color(0x080000);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    export void loaded() {&lt;br /&gt;
        set_rgb_off();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    export void unloading() {&lt;br /&gt;
        set_rgb_off();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    Env      Heap @ 0x10000000    112  bytes&lt;br /&gt;
    wasm0    Heap @ 0x10000070    4960 bytes&lt;br /&gt;
    wasm1    Heap @ 0x100013D0    4368 bytes&lt;br /&gt;
    wasm2    Heap @ 0x100024E0    4368 bytes&lt;br /&gt;
    wasm3    Heap @ 0x100035f0    4368 bytes&lt;br /&gt;
    wasm4    Heap @ 0x10004700    4608 bytes&lt;br /&gt;
    wasm5    Heap @ 0x10005900    4368 bytes&lt;br /&gt;
    wasm6    Heap @ 0x10006a10    4368 bytes&lt;br /&gt;
    wasm7    Heap @ 0x10007b20    5200 bytes&lt;br /&gt;
    End      Heap @ 0x10008F70&lt;br /&gt;
    &lt;br /&gt;
    ----- Once -----&lt;br /&gt;
    NewEnvironment&lt;br /&gt;
        M3Environment struct    0x20&lt;br /&gt;
        AllocFuncType           0x09&lt;br /&gt;
        AllocFuncType           0x09&lt;br /&gt;
        AllocFuncType           0x09&lt;br /&gt;
        AllocFuncType           0x09&lt;br /&gt;
        AllocFuncType           0x09&lt;br /&gt;
        &lt;br /&gt;
    -----  Per wasm  ---&lt;br /&gt;
    &lt;br /&gt;
    NewRuntime&lt;br /&gt;
        M3Runtime  struct       0x434&lt;br /&gt;
        runtime-&amp;gt;origStack      0x410  (stack + 4 32bit words)        &lt;br /&gt;
        &lt;br /&gt;
    ParseModule&lt;br /&gt;
        M3Module    module      0x78&lt;br /&gt;
        io_module-&amp;gt;functTypes   0x0c&lt;br /&gt;
        AllocFuncType           0x08&lt;br /&gt;
        Free&lt;br /&gt;
        AllocFuncType           0x09&lt;br /&gt;
        Free&lt;br /&gt;
        AllocFuncType           0x0A&lt;br /&gt;
        Free&lt;br /&gt;
        PreAllocFunctions       0x154  (5 functions * 68 bytes?)&lt;br /&gt;
        &amp;quot;env&amp;quot;                   0x04   &lt;br /&gt;
        &amp;quot;memory&amp;quot;                0x07&lt;br /&gt;
        Free NULL                       (freeing import, module name)&lt;br /&gt;
        Free NULL                       (freeing import, field name)&lt;br /&gt;
        &amp;quot;env&amp;quot;                   0x04   &lt;br /&gt;
        &amp;quot;set_rgb_off&amp;quot;           0x0C&lt;br /&gt;
        Free NULL                       (freeing import, module name)&lt;br /&gt;
        Free NULL                       (freeing import, field name)&lt;br /&gt;
        &amp;quot;env&amp;quot;                   0x04   &lt;br /&gt;
        &amp;quot;set_rgb_ok_color&amp;quot;      0x11&lt;br /&gt;
        Free NULL                       (freeing import, module name)&lt;br /&gt;
        Free NULL                       (freeing import, field name)&lt;br /&gt;
        &amp;quot;env&amp;quot;                   0x04   &lt;br /&gt;
        &amp;quot;set_rgb_warning_color&amp;quot; 0x16&lt;br /&gt;
        Free NULL                       (freeing import, module name)&lt;br /&gt;
        Free NULL                       (freeing import, field name)&lt;br /&gt;
        &amp;quot;env&amp;quot;                   0x04   &lt;br /&gt;
        &amp;quot;set_rgb_error_color&amp;quot;   0x14&lt;br /&gt;
        Free NULL                       (freeing import, module name)&lt;br /&gt;
        Free NULL                       (freeing import, field name)&lt;br /&gt;
        Free NULL                       (freeing import, module name)&lt;br /&gt;
        Free NULL                       (freeing import, field name)&lt;br /&gt;
        PreAllocFunctions       0x220  &lt;br /&gt;
        AddGlobal               0x20&lt;br /&gt;
        &amp;quot;event&amp;quot;                 0x06    (exports)&lt;br /&gt;
        Free NULL                       (exported name)                       &lt;br /&gt;
        &amp;quot;init&amp;quot;                  0x05&lt;br /&gt;
        Free NULL                       (exported name)                       &lt;br /&gt;
        &amp;quot;loaded&amp;quot;                0x07&lt;br /&gt;
        Free NULL                       (exported name)                       &lt;br /&gt;
        &amp;quot;unloading&amp;quot;             0x0A&lt;br /&gt;
        Free NULL                       (exported name)                       &lt;br /&gt;
        Free NULL                       (one extra exported name)                       &lt;br /&gt;
        M3DataSegments          0x20    (0 data segment)&lt;br /&gt;
        &lt;br /&gt;
    LoadModule&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        Free NULL&lt;br /&gt;
        Free NULL&lt;br /&gt;
        Free NULL&lt;br /&gt;
        Free NULL&lt;br /&gt;
        AllocFuncType           0x09&lt;br /&gt;
        Free &lt;br /&gt;
        AllocFuncType           0x09&lt;br /&gt;
        Free &lt;br /&gt;
        AllocFuncType           0x09&lt;br /&gt;
        Free &lt;br /&gt;
        AllocFuncType           0x09&lt;br /&gt;
        Free &lt;br /&gt;
        AllocFuncType           0x09&lt;br /&gt;
        Free &lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        CompileFunction         0x08    (&amp;quot;event&amp;quot;)&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        CompileFunction         0x12    (&amp;quot;init&amp;quot;)&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        CompileFunction         0x14&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Colibri_WebAssembly_Notes&amp;diff=7507</id>
		<title>Colibri WebAssembly Notes</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Colibri_WebAssembly_Notes&amp;diff=7507"/>
		<updated>2026-05-06T04:54:38Z</updated>

		<summary type="html">&lt;p&gt;Niclas: Created page with &amp;quot;Various notes, investigations and other useful information that might be needed later.   = Meory Allocations = This was an investigation into how much RAM is used to instantia...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Various notes, investigations and other useful information that might be needed later.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Meory Allocations =&lt;br /&gt;
This was an investigation into how much RAM is used to instantiate WebAssembly runtimes. 8 wasm files were deployed, each blinking the LED for the respective slot.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    ---- Program to be loaded  ----&lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
    #include &amp;quot;colibri.h&amp;quot;&lt;br /&gt;
    #define export __attribute__((visibility(&amp;quot;default&amp;quot;)))&lt;br /&gt;
    &lt;br /&gt;
    static int next = 0;&lt;br /&gt;
    static int state = 0;&lt;br /&gt;
    &lt;br /&gt;
    int tick(long time) {&lt;br /&gt;
        if (next &amp;lt; time) {&lt;br /&gt;
            if (state){&lt;br /&gt;
                set_rgb_error();&lt;br /&gt;
                next = time + 100;&lt;br /&gt;
            }&lt;br /&gt;
            else {&lt;br /&gt;
                set_rgb_off();&lt;br /&gt;
                next = time + 500;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        return state;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    export void event(int id, long value) {&lt;br /&gt;
        tick(value);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    export void init() {&lt;br /&gt;
        set_rgb_ok_color(0x000400);&lt;br /&gt;
        set_rgb_warning_color(0x040400);&lt;br /&gt;
        set_rgb_error_color(0x080000);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    export void loaded() {&lt;br /&gt;
        set_rgb_off();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    export void unloading() {&lt;br /&gt;
        set_rgb_off();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    Env      Heap @ 0x10000000    112  bytes&lt;br /&gt;
    wasm0    Heap @ 0x10000070    4960 bytes&lt;br /&gt;
    wasm1    Heap @ 0x100013D0    4368 bytes&lt;br /&gt;
    wasm2    Heap @ 0x100024E0    4368 bytes&lt;br /&gt;
    wasm3    Heap @ 0x100035f0    4368 bytes&lt;br /&gt;
    wasm4    Heap @ 0x10004700    4608 bytes&lt;br /&gt;
    wasm5    Heap @ 0x10005900    4368 bytes&lt;br /&gt;
    wasm6    Heap @ 0x10006a10    4368 bytes&lt;br /&gt;
    wasm7    Heap @ 0x10007b20    5200 bytes&lt;br /&gt;
    End      Heap @ 0x10008F70&lt;br /&gt;
    &lt;br /&gt;
    ----- Once -----&lt;br /&gt;
    NewEnvironment&lt;br /&gt;
        M3Environment struct    0x20&lt;br /&gt;
        AllocFuncType           0x09&lt;br /&gt;
        AllocFuncType           0x09&lt;br /&gt;
        AllocFuncType           0x09&lt;br /&gt;
        AllocFuncType           0x09&lt;br /&gt;
        AllocFuncType           0x09&lt;br /&gt;
        &lt;br /&gt;
    -----  Per wasm  ---&lt;br /&gt;
    &lt;br /&gt;
    NewRuntime&lt;br /&gt;
        M3Runtime  struct       0x434&lt;br /&gt;
        runtime-&amp;gt;origStack      0x410  (stack + 4 32bit words)        &lt;br /&gt;
        &lt;br /&gt;
    ParseModule&lt;br /&gt;
        M3Module    module      0x78&lt;br /&gt;
        io_module-&amp;gt;functTypes   0x0c&lt;br /&gt;
        AllocFuncType           0x08&lt;br /&gt;
        Free&lt;br /&gt;
        AllocFuncType           0x09&lt;br /&gt;
        Free&lt;br /&gt;
        AllocFuncType           0x0A&lt;br /&gt;
        Free&lt;br /&gt;
        PreAllocFunctions       0x154  (5 functions * 68 bytes?)&lt;br /&gt;
        &amp;quot;env&amp;quot;                   0x04   &lt;br /&gt;
        &amp;quot;memory&amp;quot;                0x07&lt;br /&gt;
        Free NULL                       (freeing import, module name)&lt;br /&gt;
        Free NULL                       (freeing import, field name)&lt;br /&gt;
        &amp;quot;env&amp;quot;                   0x04   &lt;br /&gt;
        &amp;quot;set_rgb_off&amp;quot;           0x0C&lt;br /&gt;
        Free NULL                       (freeing import, module name)&lt;br /&gt;
        Free NULL                       (freeing import, field name)&lt;br /&gt;
        &amp;quot;env&amp;quot;                   0x04   &lt;br /&gt;
        &amp;quot;set_rgb_ok_color&amp;quot;      0x11&lt;br /&gt;
        Free NULL                       (freeing import, module name)&lt;br /&gt;
        Free NULL                       (freeing import, field name)&lt;br /&gt;
        &amp;quot;env&amp;quot;                   0x04   &lt;br /&gt;
        &amp;quot;set_rgb_warning_color&amp;quot; 0x16&lt;br /&gt;
        Free NULL                       (freeing import, module name)&lt;br /&gt;
        Free NULL                       (freeing import, field name)&lt;br /&gt;
        &amp;quot;env&amp;quot;                   0x04   &lt;br /&gt;
        &amp;quot;set_rgb_error_color&amp;quot;   0x14&lt;br /&gt;
        Free NULL                       (freeing import, module name)&lt;br /&gt;
        Free NULL                       (freeing import, field name)&lt;br /&gt;
        Free NULL                       (freeing import, module name)&lt;br /&gt;
        Free NULL                       (freeing import, field name)&lt;br /&gt;
        PreAllocFunctions       0x220  &lt;br /&gt;
        AddGlobal               0x20&lt;br /&gt;
        &amp;quot;event&amp;quot;                 0x06    (exports)&lt;br /&gt;
        Free NULL                       (exported name)                       &lt;br /&gt;
        &amp;quot;init&amp;quot;                  0x05&lt;br /&gt;
        Free NULL                       (exported name)                       &lt;br /&gt;
        &amp;quot;loaded&amp;quot;                0x07&lt;br /&gt;
        Free NULL                       (exported name)                       &lt;br /&gt;
        &amp;quot;unloading&amp;quot;             0x0A&lt;br /&gt;
        Free NULL                       (exported name)                       &lt;br /&gt;
        Free NULL                       (one extra exported name)                       &lt;br /&gt;
        M3DataSegments          0x20    (0 data segment)&lt;br /&gt;
        &lt;br /&gt;
    LoadModule&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        Free NULL&lt;br /&gt;
        Free NULL&lt;br /&gt;
        Free NULL&lt;br /&gt;
        Free NULL&lt;br /&gt;
        AllocFuncType           0x09&lt;br /&gt;
        Free &lt;br /&gt;
        AllocFuncType           0x09&lt;br /&gt;
        Free &lt;br /&gt;
        AllocFuncType           0x09&lt;br /&gt;
        Free &lt;br /&gt;
        AllocFuncType           0x09&lt;br /&gt;
        Free &lt;br /&gt;
        AllocFuncType           0x09&lt;br /&gt;
        Free &lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        CompileFunction         0x08    (&amp;quot;event&amp;quot;)&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        CompileFunction         0x12    (&amp;quot;init&amp;quot;)&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        NewCodePage             0x40&lt;br /&gt;
        CompileFunction         0x14&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Colibri_Runtime&amp;diff=7506</id>
		<title>Colibri Runtime</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Colibri_Runtime&amp;diff=7506"/>
		<updated>2026-05-06T04:49:46Z</updated>

		<summary type="html">&lt;p&gt;Niclas: Created page with &amp;quot;The Colibri Runtime is the custom firmware that is running on Colibri MCUs, an application in Colibri Zephyr orchestrating the hardware resources, WebAssembly engines with...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The Colibri Runtime is the custom firmware that is running on Colibri MCUs, an application in [[Colibri Zephyr]] orchestrating the hardware resources, WebAssembly engines with I/O drivers and user programs.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Development == &lt;br /&gt;
&lt;br /&gt;
[[Colibri WebAssembly Notes]]&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Streamline_Zephyr&amp;diff=7492</id>
		<title>Streamline Zephyr</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Streamline_Zephyr&amp;diff=7492"/>
		<updated>2026-05-02T02:54:23Z</updated>

		<summary type="html">&lt;p&gt;Niclas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:STM32]][[Category:Streamline]][[Category:Streamline Software]][[Category:Zephyr]][[Category:Work in progress]]{{metadesc|Zephyr on Streamline boards}}&lt;br /&gt;
&lt;br /&gt;
= Installation =&lt;br /&gt;
Let's see how we can easily setup a Zephyr development environment for some Streamline demos.&lt;br /&gt;
&lt;br /&gt;
   sudo apt update&lt;br /&gt;
   sudo apt upgrade&lt;br /&gt;
   sudo apt install --no-install-recommends git cmake ninja-build gperf \&lt;br /&gt;
     ccache dfu-util device-tree-compiler wget python3-dev python3-venv python3-tk \&lt;br /&gt;
     xz-utils file make gcc gcc-multilib g++-multilib libsdl2-dev libmagic1 curl&lt;br /&gt;
   &lt;br /&gt;
   mkdir streamline-demos&lt;br /&gt;
   cd streamline-demos&lt;br /&gt;
   python3 -m venv .venv&lt;br /&gt;
   echo &amp;quot;export ZEPHYR_BASE=`pwd`/zephyr&amp;quot; &amp;gt;&amp;gt;.venv/bin/activate&lt;br /&gt;
   echo &amp;quot;export ZEPHYR_TOOLCHAIN_VARIANT=zephyr&amp;quot; &amp;gt;&amp;gt;.venv/bin/activate&lt;br /&gt;
   echo &amp;quot;export ZEPHYR_SDK_INSTALL_DIR=$HOME/zephyr-sdk-1.0.1&amp;quot; &amp;gt;&amp;gt;.venv/bin/activate&lt;br /&gt;
   source .venv/bin/activate&lt;br /&gt;
   pip install west&lt;br /&gt;
   mkdir demo1&lt;br /&gt;
   echo &amp;quot;&lt;br /&gt;
   # @copyright Copyright (c) 2026, CurrentMakers.com and the individuals that has contributed to this project.&lt;br /&gt;
   #&lt;br /&gt;
   # SPDX-License-Identifier: Apache-2.0&lt;br /&gt;
   &lt;br /&gt;
   manifest:&lt;br /&gt;
     projects:&lt;br /&gt;
       - name: zephyr&lt;br /&gt;
         revision: v4.4.0&lt;br /&gt;
         url: https://github.com/zephyrproject-rtos/zephyr&lt;br /&gt;
         west-commands: scripts/west-commands.yml&lt;br /&gt;
         import:&lt;br /&gt;
           name-allowlist:&lt;br /&gt;
             - littlefs&lt;br /&gt;
             - picolibc&lt;br /&gt;
             - hal_stm32&lt;br /&gt;
             - hal_st&lt;br /&gt;
             - hal_nordic&lt;br /&gt;
             - hal_rpi_pico&lt;br /&gt;
             - cmsis_6&lt;br /&gt;
       - name: zephyr-cm&lt;br /&gt;
         url: https://github.com/currentmakers/zephyr-cm&lt;br /&gt;
         revision: master &lt;br /&gt;
         path: zephyr-cm&lt;br /&gt;
       - name: zephyr-ws2812b-pwm&lt;br /&gt;
         url: https://github.com/currentmakers/zephyr-ws2812b-pwm&lt;br /&gt;
         revision: master&lt;br /&gt;
         path: modules/lib/zephyr-ws2812b-pwm&lt;br /&gt;
     self:&lt;br /&gt;
       path: demo1&lt;br /&gt;
   &amp;quot;&amp;gt;demo1/west.yml&lt;br /&gt;
   cd demo1&lt;br /&gt;
   west init --local &lt;br /&gt;
   west update&lt;br /&gt;
   west zephyr-export&lt;br /&gt;
   west packages pip --install&lt;br /&gt;
   west sdk install -t arm-zephyr-eabi&lt;br /&gt;
   west config zephyr.toolchain-variant zephyr&lt;br /&gt;
   west config zephyr.sdk-install-dir $HOME/zephyr-sdk-1.0.1&lt;br /&gt;
&lt;br /&gt;
We also need to redirect the &amp;lt;code&amp;gt;st-flash&amp;lt;/code&amp;gt; to use the STM32CubeIDE TCL scripts, to support the newer STM32 families, like STM32H5 and STM32C5. So &lt;br /&gt;
&lt;br /&gt;
== Flashing ==&lt;br /&gt;
It is really difficult to get flashing to work reliably with new STM32 families, so I suggest the following;&lt;br /&gt;
&lt;br /&gt;
# Download the [https://www.st.com/en/development-tools/stm32cubeprog.html STM32CubeProgrammer].&lt;br /&gt;
# Install it &amp;quot;somewhere&amp;quot;, let's say ${HOME}/st&lt;br /&gt;
# Add a symlink of ${HOME}/st/STM32CubeProgrammer-2.22.0/bin/STM32_Programmer_CLI to a location which is on the PATH, such as ${HOME}/.local/bin&lt;br /&gt;
&lt;br /&gt;
When flashing with &amp;lt;code&amp;gt;west&amp;lt;/code&amp;gt; simply do&lt;br /&gt;
&lt;br /&gt;
    west flash --runner stm32cubeprogrammer&lt;br /&gt;
&lt;br /&gt;
== Demo 1 ==&lt;br /&gt;
&lt;br /&gt;
   west build --pristine always --board streamline_mcu_stm32f407 ../zephyr/samples/basic/blinky&lt;br /&gt;
   west flash --runner stm32cubeprogrammer&lt;br /&gt;
&lt;br /&gt;
And any of the following boards can be substituted;&lt;br /&gt;
&lt;br /&gt;
   streamline_mcu_stm32f407&lt;br /&gt;
   streamline_mcu_stm32h562&lt;br /&gt;
   streamline_mcu_stm32c551&lt;br /&gt;
   streamline_mcu_stm32l475&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Streamline_Zephyr&amp;diff=7489</id>
		<title>Streamline Zephyr</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Streamline_Zephyr&amp;diff=7489"/>
		<updated>2026-05-01T09:26:21Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* Installation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:STM32]][[Category:Streamline]][[Category:Streamline Software]][[Category:Zephyr]][[Category:Work in progress]]{{metadesc|Zephyr on Streamline boards}}&lt;br /&gt;
&lt;br /&gt;
= Installation =&lt;br /&gt;
Let's see how we can easily setup a Zephyr development environment for some Streamline demos.&lt;br /&gt;
&lt;br /&gt;
   sudo apt update&lt;br /&gt;
   sudo apt upgrade&lt;br /&gt;
   sudo apt install --no-install-recommends git cmake ninja-build gperf \&lt;br /&gt;
     ccache dfu-util device-tree-compiler wget python3-dev python3-venv python3-tk \&lt;br /&gt;
     xz-utils file make gcc gcc-multilib g++-multilib libsdl2-dev libmagic1 curl&lt;br /&gt;
   &lt;br /&gt;
   mkdir streamline-demos&lt;br /&gt;
   cd streamline-demos&lt;br /&gt;
   python3 -m venv .venv&lt;br /&gt;
   echo &amp;quot;export ZEPHYR_BASE=`pwd`/zephyr&amp;quot; &amp;gt;&amp;gt;.venv/bin/activate&lt;br /&gt;
   echo &amp;quot;export ZEPHYR_TOOLCHAIN_VARIANT=zephyr&amp;quot; &amp;gt;&amp;gt;.venv/bin/activate&lt;br /&gt;
   echo &amp;quot;export ZEPHYR_SDK_INSTALL_DIR=$HOME/zephyr-sdk-1.0.1&amp;quot; &amp;gt;&amp;gt;.venv/bin/activate&lt;br /&gt;
   source .venv/bin/activate&lt;br /&gt;
   pip install west&lt;br /&gt;
   mkdir demo1&lt;br /&gt;
   echo &amp;quot;&lt;br /&gt;
   # @copyright Copyright (c) 2026, CurrentMakers.com and the individuals that has contributed to this project.&lt;br /&gt;
   #&lt;br /&gt;
   # SPDX-License-Identifier: Apache-2.0&lt;br /&gt;
   &lt;br /&gt;
   manifest:&lt;br /&gt;
     projects:&lt;br /&gt;
       - name: zephyr&lt;br /&gt;
         revision: v4.4.0&lt;br /&gt;
         url: https://github.com/zephyrproject-rtos/zephyr&lt;br /&gt;
         west-commands: scripts/west-commands.yml&lt;br /&gt;
         import:&lt;br /&gt;
           name-allowlist:&lt;br /&gt;
             - littlefs&lt;br /&gt;
             - picolibc&lt;br /&gt;
             - hal_stm32&lt;br /&gt;
             - hal_st&lt;br /&gt;
             - hal_nordic&lt;br /&gt;
             - hal_rpi_pico&lt;br /&gt;
             - cmsis_6&lt;br /&gt;
       - name: zephyr-cm&lt;br /&gt;
         url: https://github.com/currentmakers/zephyr-cm&lt;br /&gt;
         revision: master &lt;br /&gt;
         path: zephyr-cm&lt;br /&gt;
       - name: zephyr-ws2812b-pwm&lt;br /&gt;
         url: https://github.com/currentmakers/zephyr-ws2812b-pwm&lt;br /&gt;
         revision: master&lt;br /&gt;
         path: modules/lib/zephyr-ws2812b-pwm&lt;br /&gt;
     self:&lt;br /&gt;
       path: demo1&lt;br /&gt;
   &amp;quot;&amp;gt;demo1/west.yml&lt;br /&gt;
   cd demo1&lt;br /&gt;
   west init --local &lt;br /&gt;
   west update&lt;br /&gt;
   west zephyr-export&lt;br /&gt;
   west packages pip --install&lt;br /&gt;
   west sdk install -t arm-zephyr-eabi&lt;br /&gt;
   west config zephyr.toolchain-variant zephyr&lt;br /&gt;
   west config zephyr.sdk-install-dir $HOME/zephyr-sdk-1.0.1&lt;br /&gt;
&lt;br /&gt;
We also need to redirect the &amp;lt;code&amp;gt;st-flash&amp;lt;/code&amp;gt; to use the STM32CubeIDE TCL scripts, to support the newer STM32 families, like STM32H5 and STM32C5. So &lt;br /&gt;
&lt;br /&gt;
   cd streamline-demos/demo1&lt;br /&gt;
   echo &amp;quot;set ST_SCRIPTS ${HOME}/st/stm32cubeide_2.1.1/plugins/com.st.stm32cube.ide.mcu.debug.openocd_2.3.300.202602021527/resources/openocd/st_scripts&amp;quot; &amp;gt;openocd_paths.cfg  # or wherever your stm32cubeide directory is.&lt;br /&gt;
&lt;br /&gt;
Unfortunately, I have not gotten the &amp;lt;code&amp;gt;west&amp;lt;/code&amp;gt; build system to do the right thing with that.&lt;br /&gt;
&lt;br /&gt;
== Demo 1 ==&lt;br /&gt;
&lt;br /&gt;
   west build --pristine always --board streamline_mcu_stm32f407 ../zephyr/samples/basic/blinky&lt;br /&gt;
   st-flash --connect-under-reset write build/zephyr/zephyr.bin 0x8000000&lt;br /&gt;
&lt;br /&gt;
And any of the following boards can be substituted;&lt;br /&gt;
&lt;br /&gt;
   streamline_mcu_stm32f407&lt;br /&gt;
   streamline_mcu_stm32h562&lt;br /&gt;
   streamline_mcu_stm32c551&lt;br /&gt;
   streamline_mcu_stm32l475&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Streamline_Zephyr&amp;diff=7488</id>
		<title>Streamline Zephyr</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Streamline_Zephyr&amp;diff=7488"/>
		<updated>2026-05-01T05:42:57Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* Demo 1 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:STM32]][[Category:Streamline]][[Category:Streamline Software]][[Category:Zephyr]][[Category:Work in progress]]{{metadesc|Zephyr on Streamline boards}}&lt;br /&gt;
&lt;br /&gt;
= Installation =&lt;br /&gt;
Let's see how we can easily setup a Zephyr development environment for some Streamline demos.&lt;br /&gt;
&lt;br /&gt;
   sudo apt update&lt;br /&gt;
   sudo apt upgrade&lt;br /&gt;
   sudo apt install --no-install-recommends git cmake ninja-build gperf \&lt;br /&gt;
     ccache dfu-util device-tree-compiler wget python3-dev python3-venv python3-tk \&lt;br /&gt;
     xz-utils file make gcc gcc-multilib g++-multilib libsdl2-dev libmagic1 curl&lt;br /&gt;
   &lt;br /&gt;
   mkdir streamline-demos&lt;br /&gt;
   cd streamline-demos&lt;br /&gt;
   python3 -m venv .venv&lt;br /&gt;
   echo &amp;quot;export ZEPHYR_BASE=`pwd`/zephyr&amp;quot; &amp;gt;&amp;gt;.venv/bin/activate&lt;br /&gt;
   echo &amp;quot;export ZEPHYR_TOOLCHAIN_VARIANT=zephyr&amp;quot; &amp;gt;&amp;gt;.venv/bin/activate&lt;br /&gt;
   echo &amp;quot;export ZEPHYR_SDK_INSTALL_DIR=$HOME/zephyr-sdk-1.0.1&amp;quot; &amp;gt;&amp;gt;.venv/bin/activate&lt;br /&gt;
   source .venv/bin/activate&lt;br /&gt;
   pip install west&lt;br /&gt;
   mkdir demo1&lt;br /&gt;
   echo &amp;quot;&lt;br /&gt;
   # @copyright Copyright (c) 2026, CurrentMakers.com and the individuals that has contributed to this project.&lt;br /&gt;
   #&lt;br /&gt;
   # SPDX-License-Identifier: Apache-2.0&lt;br /&gt;
   &lt;br /&gt;
   manifest:&lt;br /&gt;
     projects:&lt;br /&gt;
       - name: zephyr&lt;br /&gt;
         revision: v4.4.0&lt;br /&gt;
         url: https://github.com/zephyrproject-rtos/zephyr&lt;br /&gt;
         west-commands: scripts/west-commands.yml&lt;br /&gt;
         import:&lt;br /&gt;
           name-allowlist:&lt;br /&gt;
             - littlefs&lt;br /&gt;
             - picolibc&lt;br /&gt;
             - hal_stm32&lt;br /&gt;
             - hal_st&lt;br /&gt;
             - hal_nordic&lt;br /&gt;
             - hal_rpi_pico&lt;br /&gt;
             - cmsis_6&lt;br /&gt;
       - name: zephyr-cm&lt;br /&gt;
         url: https://github.com/currentmakers/zephyr-cm&lt;br /&gt;
         revision: master &lt;br /&gt;
         path: zephyr-cm&lt;br /&gt;
       - name: zephyr-ws2812b-pwm&lt;br /&gt;
         url: https://github.com/currentmakers/zephyr-ws2812b-pwm&lt;br /&gt;
         revision: master&lt;br /&gt;
         path: modules/lib/zephyr-ws2812b-pwm&lt;br /&gt;
     self:&lt;br /&gt;
       path: demo1&lt;br /&gt;
   &amp;quot;&amp;gt;demo1/west.yml&lt;br /&gt;
   cd demo1&lt;br /&gt;
   west init --local &lt;br /&gt;
   west update&lt;br /&gt;
   west zephyr-export&lt;br /&gt;
   west packages pip --install&lt;br /&gt;
   west sdk install -t arm-zephyr-eabi&lt;br /&gt;
   west config zephyr.toolchain-variant zephyr&lt;br /&gt;
   west config zephyr.sdk-install-dir $HOME/zephyr-sdk-1.0.1&lt;br /&gt;
&lt;br /&gt;
== Demo 1 ==&lt;br /&gt;
   cd streamline-demos/demo1&lt;br /&gt;
   west build --pristine always --board streamline_mcu_stm32f407 ../zephyr/samples/basic/blinky&lt;br /&gt;
   west flash --runner openocd&lt;br /&gt;
&lt;br /&gt;
And any of the following boards can be substituted;&lt;br /&gt;
&lt;br /&gt;
   streamline_mcu_stm32f407&lt;br /&gt;
   streamline_mcu_stm32h562&lt;br /&gt;
   streamline_mcu_stm32c551&lt;br /&gt;
   streamline_mcu_stm32l475&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Streamline_Zephyr&amp;diff=7487</id>
		<title>Streamline Zephyr</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Streamline_Zephyr&amp;diff=7487"/>
		<updated>2026-05-01T05:20:17Z</updated>

		<summary type="html">&lt;p&gt;Niclas: /* Demo 1 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:STM32]][[Category:Streamline]][[Category:Streamline Software]][[Category:Zephyr]][[Category:Work in progress]]{{metadesc|Zephyr on Streamline boards}}&lt;br /&gt;
&lt;br /&gt;
= Installation =&lt;br /&gt;
Let's see how we can easily setup a Zephyr development environment for some Streamline demos.&lt;br /&gt;
&lt;br /&gt;
   sudo apt update&lt;br /&gt;
   sudo apt upgrade&lt;br /&gt;
   sudo apt install --no-install-recommends git cmake ninja-build gperf \&lt;br /&gt;
     ccache dfu-util device-tree-compiler wget python3-dev python3-venv python3-tk \&lt;br /&gt;
     xz-utils file make gcc gcc-multilib g++-multilib libsdl2-dev libmagic1 curl&lt;br /&gt;
   &lt;br /&gt;
   mkdir streamline-demos&lt;br /&gt;
   cd streamline-demos&lt;br /&gt;
   python3 -m venv .venv&lt;br /&gt;
   echo &amp;quot;export ZEPHYR_BASE=`pwd`/zephyr&amp;quot; &amp;gt;&amp;gt;.venv/bin/activate&lt;br /&gt;
   echo &amp;quot;export ZEPHYR_TOOLCHAIN_VARIANT=zephyr&amp;quot; &amp;gt;&amp;gt;.venv/bin/activate&lt;br /&gt;
   echo &amp;quot;export ZEPHYR_SDK_INSTALL_DIR=$HOME/zephyr-sdk-1.0.1&amp;quot; &amp;gt;&amp;gt;.venv/bin/activate&lt;br /&gt;
   source .venv/bin/activate&lt;br /&gt;
   pip install west&lt;br /&gt;
   mkdir demo1&lt;br /&gt;
   echo &amp;quot;&lt;br /&gt;
   # @copyright Copyright (c) 2026, CurrentMakers.com and the individuals that has contributed to this project.&lt;br /&gt;
   #&lt;br /&gt;
   # SPDX-License-Identifier: Apache-2.0&lt;br /&gt;
   &lt;br /&gt;
   manifest:&lt;br /&gt;
     projects:&lt;br /&gt;
       - name: zephyr&lt;br /&gt;
         revision: v4.4.0&lt;br /&gt;
         url: https://github.com/zephyrproject-rtos/zephyr&lt;br /&gt;
         west-commands: scripts/west-commands.yml&lt;br /&gt;
         import:&lt;br /&gt;
           name-allowlist:&lt;br /&gt;
             - littlefs&lt;br /&gt;
             - picolibc&lt;br /&gt;
             - hal_stm32&lt;br /&gt;
             - hal_st&lt;br /&gt;
             - hal_nordic&lt;br /&gt;
             - hal_rpi_pico&lt;br /&gt;
             - cmsis_6&lt;br /&gt;
       - name: zephyr-cm&lt;br /&gt;
         url: https://github.com/currentmakers/zephyr-cm&lt;br /&gt;
         revision: master &lt;br /&gt;
         path: zephyr-cm&lt;br /&gt;
       - name: zephyr-ws2812b-pwm&lt;br /&gt;
         url: https://github.com/currentmakers/zephyr-ws2812b-pwm&lt;br /&gt;
         revision: master&lt;br /&gt;
         path: modules/lib/zephyr-ws2812b-pwm&lt;br /&gt;
     self:&lt;br /&gt;
       path: demo1&lt;br /&gt;
   &amp;quot;&amp;gt;demo1/west.yml&lt;br /&gt;
   cd demo1&lt;br /&gt;
   west init --local &lt;br /&gt;
   west update&lt;br /&gt;
   west zephyr-export&lt;br /&gt;
   west packages pip --install&lt;br /&gt;
   west sdk install -t arm-zephyr-eabi&lt;br /&gt;
   west config zephyr.toolchain-variant zephyr&lt;br /&gt;
   west config zephyr.sdk-install-dir $HOME/zephyr-sdk-1.0.1&lt;br /&gt;
&lt;br /&gt;
== Demo 1 ==&lt;br /&gt;
   cd streamline-demos/demo1&lt;br /&gt;
   west build --pristine always --board streamline_mcu_stm32f407 ../zephyr/samples/basic/blinky&lt;br /&gt;
   west flash --runner openocd&lt;br /&gt;
&lt;br /&gt;
And any of the following boards can be substituted;&lt;br /&gt;
&lt;br /&gt;
   streamline_mcu_stm32f407&lt;br /&gt;
   streamline_mcu_stm32h562&lt;br /&gt;
   streamline_mcu_stm32c551&lt;br /&gt;
   streamline_mcu_stm32l475 (not quite yet)&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Streamline_Zephyr&amp;diff=7486</id>
		<title>Streamline Zephyr</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Streamline_Zephyr&amp;diff=7486"/>
		<updated>2026-05-01T05:18:50Z</updated>

		<summary type="html">&lt;p&gt;Niclas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:STM32]][[Category:Streamline]][[Category:Streamline Software]][[Category:Zephyr]][[Category:Work in progress]]{{metadesc|Zephyr on Streamline boards}}&lt;br /&gt;
&lt;br /&gt;
= Installation =&lt;br /&gt;
Let's see how we can easily setup a Zephyr development environment for some Streamline demos.&lt;br /&gt;
&lt;br /&gt;
   sudo apt update&lt;br /&gt;
   sudo apt upgrade&lt;br /&gt;
   sudo apt install --no-install-recommends git cmake ninja-build gperf \&lt;br /&gt;
     ccache dfu-util device-tree-compiler wget python3-dev python3-venv python3-tk \&lt;br /&gt;
     xz-utils file make gcc gcc-multilib g++-multilib libsdl2-dev libmagic1 curl&lt;br /&gt;
   &lt;br /&gt;
   mkdir streamline-demos&lt;br /&gt;
   cd streamline-demos&lt;br /&gt;
   python3 -m venv .venv&lt;br /&gt;
   echo &amp;quot;export ZEPHYR_BASE=`pwd`/zephyr&amp;quot; &amp;gt;&amp;gt;.venv/bin/activate&lt;br /&gt;
   echo &amp;quot;export ZEPHYR_TOOLCHAIN_VARIANT=zephyr&amp;quot; &amp;gt;&amp;gt;.venv/bin/activate&lt;br /&gt;
   echo &amp;quot;export ZEPHYR_SDK_INSTALL_DIR=$HOME/zephyr-sdk-1.0.1&amp;quot; &amp;gt;&amp;gt;.venv/bin/activate&lt;br /&gt;
   source .venv/bin/activate&lt;br /&gt;
   pip install west&lt;br /&gt;
   mkdir demo1&lt;br /&gt;
   echo &amp;quot;&lt;br /&gt;
   # @copyright Copyright (c) 2026, CurrentMakers.com and the individuals that has contributed to this project.&lt;br /&gt;
   #&lt;br /&gt;
   # SPDX-License-Identifier: Apache-2.0&lt;br /&gt;
   &lt;br /&gt;
   manifest:&lt;br /&gt;
     projects:&lt;br /&gt;
       - name: zephyr&lt;br /&gt;
         revision: v4.4.0&lt;br /&gt;
         url: https://github.com/zephyrproject-rtos/zephyr&lt;br /&gt;
         west-commands: scripts/west-commands.yml&lt;br /&gt;
         import:&lt;br /&gt;
           name-allowlist:&lt;br /&gt;
             - littlefs&lt;br /&gt;
             - picolibc&lt;br /&gt;
             - hal_stm32&lt;br /&gt;
             - hal_st&lt;br /&gt;
             - hal_nordic&lt;br /&gt;
             - hal_rpi_pico&lt;br /&gt;
             - cmsis_6&lt;br /&gt;
       - name: zephyr-cm&lt;br /&gt;
         url: https://github.com/currentmakers/zephyr-cm&lt;br /&gt;
         revision: master &lt;br /&gt;
         path: zephyr-cm&lt;br /&gt;
       - name: zephyr-ws2812b-pwm&lt;br /&gt;
         url: https://github.com/currentmakers/zephyr-ws2812b-pwm&lt;br /&gt;
         revision: master&lt;br /&gt;
         path: modules/lib/zephyr-ws2812b-pwm&lt;br /&gt;
     self:&lt;br /&gt;
       path: demo1&lt;br /&gt;
   &amp;quot;&amp;gt;demo1/west.yml&lt;br /&gt;
   cd demo1&lt;br /&gt;
   west init --local &lt;br /&gt;
   west update&lt;br /&gt;
   west zephyr-export&lt;br /&gt;
   west packages pip --install&lt;br /&gt;
   west sdk install -t arm-zephyr-eabi&lt;br /&gt;
   west config zephyr.toolchain-variant zephyr&lt;br /&gt;
   west config zephyr.sdk-install-dir $HOME/zephyr-sdk-1.0.1&lt;br /&gt;
&lt;br /&gt;
== Demo 1 ==&lt;br /&gt;
   cd streamline-demos/demo1&lt;br /&gt;
   west build --pristine always --board streamline_mcu_stm32c551 ../zephyr/samples/basic/blinky&lt;br /&gt;
   west flash --runner openocd&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Streamline_Zephyr&amp;diff=7484</id>
		<title>Streamline Zephyr</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Streamline_Zephyr&amp;diff=7484"/>
		<updated>2026-04-30T11:57:19Z</updated>

		<summary type="html">&lt;p&gt;Niclas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:STM32]][[Category:Streamline]][[Category:Streamline Software]]{{metadesc|Zephyr on Streamline boards}}&lt;br /&gt;
&lt;br /&gt;
= Installation =&lt;br /&gt;
Let's see how we can easily setup a Zephyr development environment for some Streamline demos.&lt;br /&gt;
&lt;br /&gt;
   sudo apt update&lt;br /&gt;
   sudo apt upgrade&lt;br /&gt;
   sudo apt install --no-install-recommends git cmake ninja-build gperf \&lt;br /&gt;
     ccache dfu-util device-tree-compiler wget python3-dev python3-venv python3-tk \&lt;br /&gt;
     xz-utils file make gcc gcc-multilib g++-multilib libsdl2-dev libmagic1 curl&lt;br /&gt;
   &lt;br /&gt;
   mkdir streamline-demos&lt;br /&gt;
   cd streamline-demos&lt;br /&gt;
   python3 -m venv .venv&lt;br /&gt;
   echo &amp;quot;export ZEPHYR_BASE=`pwd`/zephyr&amp;quot; &amp;gt;&amp;gt;.venv/bin/activate&lt;br /&gt;
   echo &amp;quot;export ZEPHYR_TOOLCHAIN_VARIANT=zephyr&amp;quot; &amp;gt;&amp;gt;.venv/bin/activate&lt;br /&gt;
   echo &amp;quot;export ZEPHYR_SDK_INSTALL_DIR=$HOME/zephyr-sdk-1.0.1&amp;quot; &amp;gt;&amp;gt;.venv/bin/activate&lt;br /&gt;
   source .venv/bin/activate&lt;br /&gt;
   pip install west&lt;br /&gt;
   mkdir demo1&lt;br /&gt;
   echo &amp;quot;&lt;br /&gt;
   # @copyright Copyright (c) 2026, CurrentMakers.com and the individuals that has contributed to this project.&lt;br /&gt;
   #&lt;br /&gt;
   # SPDX-License-Identifier: Apache-2.0&lt;br /&gt;
   &lt;br /&gt;
   manifest:&lt;br /&gt;
     projects:&lt;br /&gt;
       - name: zephyr&lt;br /&gt;
         revision: v4.4.0&lt;br /&gt;
         url: https://github.com/zephyrproject-rtos/zephyr&lt;br /&gt;
         west-commands: scripts/west-commands.yml&lt;br /&gt;
         import:&lt;br /&gt;
           name-allowlist:&lt;br /&gt;
             - littlefs&lt;br /&gt;
             - picolibc&lt;br /&gt;
             - hal_stm32&lt;br /&gt;
             - hal_st&lt;br /&gt;
             - hal_nordic&lt;br /&gt;
             - hal_rpi_pico&lt;br /&gt;
             - cmsis_6&lt;br /&gt;
       - name: zephyr-cm&lt;br /&gt;
         url: https://github.com/currentmakers/zephyr-cm&lt;br /&gt;
         revision: master &lt;br /&gt;
         path: zephyr-cm&lt;br /&gt;
       - name: zephyr-ws2812b-pwm&lt;br /&gt;
         url: https://github.com/currentmakers/zephyr-ws2812b-pwm&lt;br /&gt;
         revision: master&lt;br /&gt;
         path: modules/lib/zephyr-ws2812b-pwm&lt;br /&gt;
     self:&lt;br /&gt;
       path: demo1&lt;br /&gt;
   &amp;quot;&amp;gt;demo1/west.yml&lt;br /&gt;
   cd demo1&lt;br /&gt;
   west init --local &lt;br /&gt;
   west update&lt;br /&gt;
   west zephyr-export&lt;br /&gt;
   west packages pip --install&lt;br /&gt;
   west sdk install -t arm-zephyr-eabi&lt;br /&gt;
   west config zephyr.toolchain-variant zephyr&lt;br /&gt;
   west config zephyr.sdk-install-dir $HOME/zephyr-sdk-1.0.1&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
	<entry>
		<id>https://stm32world.com/w/index.php?title=Streamline_Zephyr&amp;diff=7483</id>
		<title>Streamline Zephyr</title>
		<link rel="alternate" type="text/html" href="https://stm32world.com/w/index.php?title=Streamline_Zephyr&amp;diff=7483"/>
		<updated>2026-04-30T11:51:46Z</updated>

		<summary type="html">&lt;p&gt;Niclas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:STM32]][[Category:Streamline]][[Category:Streamline Software]]{{metadesc|Zephyr on Streamline boards}}&lt;br /&gt;
&lt;br /&gt;
= Installation =&lt;br /&gt;
Let's see how we can easily setup a Zephyr development environment for some Streamline demos.&lt;br /&gt;
&lt;br /&gt;
   sudo apt update&lt;br /&gt;
   sudo apt upgrade&lt;br /&gt;
   sudo apt install --no-install-recommends git cmake ninja-build gperf \&lt;br /&gt;
     ccache dfu-util device-tree-compiler wget python3-dev python3-venv python3-tk \&lt;br /&gt;
     xz-utils file make gcc gcc-multilib g++-multilib libsdl2-dev libmagic1 curl&lt;br /&gt;
   &lt;br /&gt;
   mkdir streamline-demos&lt;br /&gt;
   cd streamline-demos&lt;br /&gt;
   python3 -m venv .venv&lt;br /&gt;
   echo &amp;quot;export ZEPHYR_BASE=`pwd`/zephyr&amp;quot; &amp;gt;&amp;gt;.venv/bin/activate&lt;br /&gt;
   echo &amp;quot;export ZEPHYR_TOOLCHAIN_VARIANT=zephyr&amp;quot; &amp;gt;&amp;gt;.venv/bin/activate&lt;br /&gt;
   echo &amp;quot;export ZEPHYR_SDK_INSTALL_DIR=$HOME/zephyr-sdk-1.0.1&amp;quot; &amp;gt;&amp;gt;.venv/bin/activate&lt;br /&gt;
   source .venv/bin/activate&lt;br /&gt;
   pip install west&lt;br /&gt;
   mkdir demo1&lt;br /&gt;
   echo &amp;quot;&lt;br /&gt;
   # @copyright Copyright (c) 2026, CurrentMakers.com and the individuals that has contributed to this project.&lt;br /&gt;
   #&lt;br /&gt;
   # SPDX-License-Identifier: Apache-2.0&lt;br /&gt;
   &lt;br /&gt;
   manifest:&lt;br /&gt;
     projects:&lt;br /&gt;
       - name: zephyr&lt;br /&gt;
         revision: v4.4.0&lt;br /&gt;
         url: https://github.com/zephyrproject-rtos/zephyr&lt;br /&gt;
         west-commands: scripts/west-commands.yml&lt;br /&gt;
         import:&lt;br /&gt;
           name-allowlist:&lt;br /&gt;
             - littlefs&lt;br /&gt;
             - picolibc&lt;br /&gt;
             - hal_stm32&lt;br /&gt;
             - hal_st&lt;br /&gt;
             - hal_nordic&lt;br /&gt;
             - hal_rpi_pico&lt;br /&gt;
             - cmsis_6&lt;br /&gt;
       - name: zephyr-cm&lt;br /&gt;
         url: https://github.com/currentmakers/zephyr-cm&lt;br /&gt;
         revision: master &lt;br /&gt;
         path: zephyr-cm&lt;br /&gt;
       - name: zephyr-ws2812b-pwm&lt;br /&gt;
         url: https://github.com/currentmakers/zephyr-ws2812b-pwm&lt;br /&gt;
         revision: master&lt;br /&gt;
         path: modules/lib/zephyr-ws2812b-pwm&lt;br /&gt;
     self:&lt;br /&gt;
       path: demo1&lt;br /&gt;
   &amp;quot;&amp;gt;demo1/west.yml&lt;br /&gt;
   west init --local demo1&lt;br /&gt;
   west update&lt;br /&gt;
   west zephyr-export&lt;br /&gt;
   west packages pip --install&lt;br /&gt;
   west sdk install -t arm-zephyr-eabi&lt;br /&gt;
   west config zephyr.toolchain-variant zephyr&lt;br /&gt;
   west config zephyr.sdk-install-dir $HOME/zephyr-sdk-1.0.1&lt;/div&gt;</summary>
		<author><name>Niclas</name></author>
	</entry>
</feed>