<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://Robo.Fish/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Kai</id>
	<title>Robo.Fish Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://Robo.Fish/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Kai"/>
	<link rel="alternate" type="text/html" href="https://Robo.Fish/wiki/index.php?title=Special:Contributions/Kai"/>
	<updated>2026-06-06T23:19:05Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.1</generator>
	<entry>
		<id>https://Robo.Fish/wiki/index.php?title=Fischertechnik_Maker_Kit_Car&amp;diff=3307</id>
		<title>Fischertechnik Maker Kit Car</title>
		<link rel="alternate" type="text/html" href="https://Robo.Fish/wiki/index.php?title=Fischertechnik_Maker_Kit_Car&amp;diff=3307"/>
		<updated>2025-05-20T18:15:43Z</updated>

		<summary type="html">&lt;p&gt;Kai: /* Traction and Steering */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The &#039;&#039;fischertechnik Maker Kit Car&#039;&#039; is a toy-sized vehicle platform constructed of plastic molded parts from the fischertechnik parts library, combined with a low-rpm brushed DC motor and a tiny servo motor for powering the rear-wheel drive and front-wheel steering, respectively.&lt;br /&gt;
&lt;br /&gt;
== Unboxing and Assembling ==&lt;br /&gt;
&lt;br /&gt;
[[File:ft-mkc-1.jpg | x350px | a look inside the box]] [[File:ft-mkc-2.jpg | x350px | box contents laid out]]&lt;br /&gt;
&lt;br /&gt;
== Traction and Steering ==&lt;br /&gt;
&lt;br /&gt;
[[Media:ft-mkc-moving.mov]]&lt;/div&gt;</summary>
		<author><name>Kai</name></author>
	</entry>
	<entry>
		<id>https://Robo.Fish/wiki/index.php?title=Fischertechnik_Maker_Kit_Car&amp;diff=3306</id>
		<title>Fischertechnik Maker Kit Car</title>
		<link rel="alternate" type="text/html" href="https://Robo.Fish/wiki/index.php?title=Fischertechnik_Maker_Kit_Car&amp;diff=3306"/>
		<updated>2025-05-20T18:12:53Z</updated>

		<summary type="html">&lt;p&gt;Kai: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The &#039;&#039;fischertechnik Maker Kit Car&#039;&#039; is a toy-sized vehicle platform constructed of plastic molded parts from the fischertechnik parts library, combined with a low-rpm brushed DC motor and a tiny servo motor for powering the rear-wheel drive and front-wheel steering, respectively.&lt;br /&gt;
&lt;br /&gt;
== Unboxing and Assembling ==&lt;br /&gt;
&lt;br /&gt;
[[File:ft-mkc-1.jpg | x350px | a look inside the box]] [[File:ft-mkc-2.jpg | x350px | box contents laid out]]&lt;br /&gt;
&lt;br /&gt;
== Traction and Steering ==&lt;br /&gt;
&lt;br /&gt;
[[File:ft-mkc-moving.mov]]&lt;/div&gt;</summary>
		<author><name>Kai</name></author>
	</entry>
	<entry>
		<id>https://Robo.Fish/wiki/index.php?title=Fischertechnik_Maker_Kit_Car&amp;diff=3305</id>
		<title>Fischertechnik Maker Kit Car</title>
		<link rel="alternate" type="text/html" href="https://Robo.Fish/wiki/index.php?title=Fischertechnik_Maker_Kit_Car&amp;diff=3305"/>
		<updated>2025-05-20T18:11:29Z</updated>

		<summary type="html">&lt;p&gt;Kai: /* Unboxing and Assembling */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The &#039;&#039;fischertechnik Maker Kit Car&#039;&#039; is a toy-sized vehicle platform constructed of plastic molded parts from the fischertechnik parts library, combined with a low-rpm brushed DC motor and a tiny servo motor for powering the rear-wheel drive and front-wheel steering, respectively.&lt;br /&gt;
&lt;br /&gt;
== Unboxing and Assembling ==&lt;br /&gt;
&lt;br /&gt;
[[File:ft-mkc-1.jpg | x350px | a look inside the box]] [[File:ft-mkc-2.jpg | x350px | box contents laid out]]&lt;/div&gt;</summary>
		<author><name>Kai</name></author>
	</entry>
	<entry>
		<id>https://Robo.Fish/wiki/index.php?title=Fischertechnik_Maker_Kit_Car&amp;diff=3304</id>
		<title>Fischertechnik Maker Kit Car</title>
		<link rel="alternate" type="text/html" href="https://Robo.Fish/wiki/index.php?title=Fischertechnik_Maker_Kit_Car&amp;diff=3304"/>
		<updated>2025-05-20T16:28:50Z</updated>

		<summary type="html">&lt;p&gt;Kai: /* Unboxing and Assembling */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The &#039;&#039;fischertechnik Maker Kit Car&#039;&#039; is a toy-sized vehicle platform constructed of plastic molded parts from the fischertechnik parts library, combined with a low-rpm brushed DC motor and a tiny servo motor for powering the rear-wheel drive and front-wheel steering, respectively.&lt;br /&gt;
&lt;br /&gt;
== Unboxing and Assembling ==&lt;br /&gt;
&lt;br /&gt;
[[File:ft-mkc-1.jpg| x350 | a look inside the box]]&lt;br /&gt;
&lt;br /&gt;
[[File:ft-mkc-2.jpg| x350 | box contents laid out]]&lt;/div&gt;</summary>
		<author><name>Kai</name></author>
	</entry>
	<entry>
		<id>https://Robo.Fish/wiki/index.php?title=File:Ft-mkc-2.jpg&amp;diff=3303</id>
		<title>File:Ft-mkc-2.jpg</title>
		<link rel="alternate" type="text/html" href="https://Robo.Fish/wiki/index.php?title=File:Ft-mkc-2.jpg&amp;diff=3303"/>
		<updated>2025-05-20T16:28:14Z</updated>

		<summary type="html">&lt;p&gt;Kai: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Kai</name></author>
	</entry>
	<entry>
		<id>https://Robo.Fish/wiki/index.php?title=File:Ft-mkc-1.jpg&amp;diff=3302</id>
		<title>File:Ft-mkc-1.jpg</title>
		<link rel="alternate" type="text/html" href="https://Robo.Fish/wiki/index.php?title=File:Ft-mkc-1.jpg&amp;diff=3302"/>
		<updated>2025-05-20T16:27:46Z</updated>

		<summary type="html">&lt;p&gt;Kai: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Kai</name></author>
	</entry>
	<entry>
		<id>https://Robo.Fish/wiki/index.php?title=Fischertechnik_Maker_Kit_Car&amp;diff=3301</id>
		<title>Fischertechnik Maker Kit Car</title>
		<link rel="alternate" type="text/html" href="https://Robo.Fish/wiki/index.php?title=Fischertechnik_Maker_Kit_Car&amp;diff=3301"/>
		<updated>2025-05-20T16:26:38Z</updated>

		<summary type="html">&lt;p&gt;Kai: Created page with &amp;quot;The &amp;#039;&amp;#039;fischertechnik Maker Kit Car&amp;#039;&amp;#039; is a toy-sized vehicle platform constructed of plastic molded parts from the fischertechnik parts library, combined with a low-rpm brushed DC motor and a tiny servo motor for powering the rear-wheel drive and front-wheel steering, respectively.  == Unboxing and Assembling ==   a look inside the box   box contents laid out&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The &#039;&#039;fischertechnik Maker Kit Car&#039;&#039; is a toy-sized vehicle platform constructed of plastic molded parts from the fischertechnik parts library, combined with a low-rpm brushed DC motor and a tiny servo motor for powering the rear-wheel drive and front-wheel steering, respectively.&lt;br /&gt;
&lt;br /&gt;
== Unboxing and Assembling ==&lt;br /&gt;
&lt;br /&gt;
[[File:ft-mkc-1.jpg| x400 | a look inside the box]]&lt;br /&gt;
&lt;br /&gt;
[[File:ft-mkc-2.jpg| x400 | box contents laid out]]&lt;/div&gt;</summary>
		<author><name>Kai</name></author>
	</entry>
	<entry>
		<id>https://Robo.Fish/wiki/index.php?title=LT2&amp;diff=3300</id>
		<title>LT2</title>
		<link rel="alternate" type="text/html" href="https://Robo.Fish/wiki/index.php?title=LT2&amp;diff=3300"/>
		<updated>2025-05-20T16:16:17Z</updated>

		<summary type="html">&lt;p&gt;Kai: Created page with &amp;quot;The LT2 uses the toy-sized fischertechnik Maker Kit Car molded-plastic vehicle platform that is rear-wheel driven and front-wheel steered, like a full-sized car. Motor control therefore differs from the Arexx RP5 used in the LT1.  == Hardware Components == * Raspberry Pi Pico W 2 microcontroller as  RSA * Raspberry Pi Compute Module 5 as  RTC * Raspberry Pi Camera Module 3 * HC-SR04 ultrasonic range sensor...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The LT2 uses the toy-sized [[fischertechnik Maker Kit Car]] molded-plastic vehicle platform that is rear-wheel driven and front-wheel steered, like a full-sized car. Motor control therefore differs from the [[Arexx RP5]] used in the [[LT1]].&lt;br /&gt;
&lt;br /&gt;
== Hardware Components ==&lt;br /&gt;
* Raspberry Pi Pico W 2 microcontroller as [[Robot State Agent | RSA]]&lt;br /&gt;
* Raspberry Pi Compute Module 5 as [[Robot Task Controller | RTC]]&lt;br /&gt;
* Raspberry Pi Camera Module 3&lt;br /&gt;
* [[HC-SR04]] ultrasonic range sensor&lt;br /&gt;
* [[fischertechnik Maker Kit Car]] chassis&lt;/div&gt;</summary>
		<author><name>Kai</name></author>
	</entry>
	<entry>
		<id>https://Robo.Fish/wiki/index.php?title=Main_Page&amp;diff=3299</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://Robo.Fish/wiki/index.php?title=Main_Page&amp;diff=3299"/>
		<updated>2025-05-20T15:53:04Z</updated>

		<summary type="html">&lt;p&gt;Kai: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;medium-6 columns&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;small-offset-2 small-8 columns&amp;quot; style=&amp;quot;margin: 0; padding: 0&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div style=&amp;quot;background-color:#bbb; color:white;text-align:center; display:block&amp;quot;&amp;gt;&lt;br /&gt;
Products&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;div style=&amp;quot;border: 0px solid black&amp;quot;&amp;gt;&lt;br /&gt;
* [[FishNet]]&lt;br /&gt;
* [[Underwater Data | Underwater]]&lt;br /&gt;
* [[RFX]]&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;medium-6 columns&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;small-offset-2 small-8 columns&amp;quot; style=&amp;quot;margin: 0; padding: 0&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div style=&amp;quot;background-color:#bbb; color:white; text-align:center&amp;quot;&amp;gt;&lt;br /&gt;
Milestones&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;div&amp;gt;&lt;br /&gt;
* [[Core Module]]&lt;br /&gt;
* land trainer [[LT0]]&lt;br /&gt;
* land trainer [[LT1]]&lt;br /&gt;
* land trainer [[LT2]]&lt;br /&gt;
* robo fish [[RF0]]&lt;br /&gt;
* robo fish [[RF1]]&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;medium-6 columns&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;small-offset-2 small-8 columns&amp;quot; style=&amp;quot;margin: 0; padding: 0&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div style=&amp;quot;background-color:#bbb; color:white;text-align:center&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;How To&amp;quot; Notes&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;div&amp;gt;&lt;br /&gt;
* [[Computer Vision]]&lt;br /&gt;
* [[Artificial Intelligence]]&lt;br /&gt;
* [[Robotics]]&lt;br /&gt;
* [[Circuit Design]]&lt;br /&gt;
* [[3D Printing]]&lt;br /&gt;
* [[Build Engineering]]&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;medium-6 columns&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;div class=&amp;quot;small-offset-2 small-8 columns&amp;quot; style=&amp;quot;margin: 0; padding: 0&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div style=&amp;quot;background-color:#bbb; color:white; text-align:center&amp;quot;&amp;gt;&lt;br /&gt;
Third Party&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
                &amp;lt;div&amp;gt;&lt;br /&gt;
* [[Third-Party Software]]&lt;br /&gt;
* [[Publications | Collected Publications]]&lt;br /&gt;
                &amp;lt;/div&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;small-centered small-4 medium-centered medium-3 large-centered large-3 columns&amp;quot;&amp;gt;[[File:splash.png]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>Kai</name></author>
	</entry>
	<entry>
		<id>https://Robo.Fish/wiki/index.php?title=GATT_Profile_Data_in_Bluetooth_Low_Energy&amp;diff=3298</id>
		<title>GATT Profile Data in Bluetooth Low Energy</title>
		<link rel="alternate" type="text/html" href="https://Robo.Fish/wiki/index.php?title=GATT_Profile_Data_in_Bluetooth_Low_Energy&amp;diff=3298"/>
		<updated>2025-05-10T08:27:41Z</updated>

		<summary type="html">&lt;p&gt;Kai: /* Property Flags */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This article explains the binary structure of the GATT attributes data array that many Bluetooth Low Energy application frameworks, like [https://bluekitchen-gmbh.com/btstack BTstack], expect as setup input.&lt;br /&gt;
&lt;br /&gt;
= GATT characteristic attribute (descriptor) types =&lt;br /&gt;
&lt;br /&gt;
== Characteristic declaration ==&lt;br /&gt;
&lt;br /&gt;
Let&#039;s have a look at an ATT attribute that declares a GATT characteristic. Here is the binary sequence (in hex representation) generated for an attribute that declares a GATT characteristic with attribute UUID &#039;&#039;B0B0F155-B0B0-B0B0-B0B0-B0B000000101&#039;&#039; and permissions &#039;&#039;READ | DYNAMIC&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0x1b, 0x00, 0x02, 0x00, 0x08, 0x00, 0x03, 0x28, 0x02, 0x09, 0x00, 0x01, 0x01, 0x00, 0x00, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0x55, 0xf1, 0xb0, 0xb0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The bytes are grouped from left to right according to this scheme:&lt;br /&gt;
* 2 bytes for the length of this attribute definition: 0x001b (= 27 bytes)&lt;br /&gt;
* 2 bytes for the access permission of this attribute: 0x0002 (= read-only)&lt;br /&gt;
* 2 bytes for the attribute handle: 0x0008&lt;br /&gt;
* 2 bytes for the attribute type: 0x2803 (short 16-bit UUID that indicates a characteristic declaration)&lt;br /&gt;
* 1 byte for the access permissions of the declared characteristic: 0x02 (= read-only)&lt;br /&gt;
* 2 bytes for the attribute handle of the characteristic value: 0x0009&lt;br /&gt;
* 16 bytes for the 128-bit UUID of the characteristic: 0xb0b0f155b0b0b0b0b0b0b0b000000101&lt;br /&gt;
where &#039;&#039;&#039;the bytes in each group are in reverse order&#039;&#039;&#039;!&lt;br /&gt;
&lt;br /&gt;
For the official specification of the Bluetooth 5.4 GATT characteristic declaration refer to section 3.3.1 in the [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html in the Bluetooth 5.4 Core Specification].&lt;br /&gt;
&lt;br /&gt;
== Characteristic value ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0x16, 0x00, 0x02, 0x03, 0x09, 0x00, 0x01, 0x01, 0x00, 0x00, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0x55, 0xf1, 0xb0, 0xb0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The bytes are grouped from left to right as follows:&lt;br /&gt;
* 2 bytes for the length of the attribute: 0x0016 (= 22 bytes)&lt;br /&gt;
* 2 bytes for the combined properties and access permissions bitmasks of the attribute: 0x0302 (= read-only, dynamic, 128-bit UUID)&lt;br /&gt;
* 2 bytes for the handle of the attribute: 0x0009&lt;br /&gt;
* 16 bytes for the UUID of the characteristic that the value is associated with: 0xb0b0f155b0b0b0b0b0b0b0b000000101&lt;br /&gt;
&lt;br /&gt;
The bitmask the determines the access permissions (or properties) for the value have an effect on the performance the communication between GATT client and server. A write operation that does not require waiting for an acknowledgement from the server is better suited, for example, for applications in which the client sends a stream of values to the server and it does not matter if some of the values are lost or overwritten by by the next value before the server can respond.&lt;br /&gt;
&lt;br /&gt;
==== Access Permission Flags ====&lt;br /&gt;
The following table (from the Bluetooth 5.4 specification) defines the flags for the 8-bit &#039;&#039;access permissions&#039;&#039; bitmask:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin:right&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Property !! Value !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Broadcast || 0x01 || If set, permits broadcasts of the Characteristic Value using Server Characteristic Configuration Descriptor. If set, the Server Characteristic Configuration Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
| Read || 0x02 || If set, permits reads of the Characteristic Value using procedures defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-66cf484d-50cd-199f-dd0d-d0d02ad02ce0 Section 4.8]&lt;br /&gt;
|-&lt;br /&gt;
| Write Without Response || 0x04 || If set, permit writes of the Characteristic Value without response using procedures defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-9f1c2e38-8fbe-f60c-d885-076707c88a43 Section 4.9.1].&lt;br /&gt;
|-&lt;br /&gt;
| Write || 0x08 || If set, permits writes of the Characteristic Value with response using procedures defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-ba4b856a-6994-01e4-97f6-357f9be40990 Section 4.9.3] or [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-6ab738ad-6d26-1da1-7417-e83da50e90c5 Section 4.9.4].&lt;br /&gt;
|-&lt;br /&gt;
| Notify || 0x10 || If set, permits notifications of a Characteristic Value without acknowledgment using the procedure defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-74673cc2-e704-a2fa-14bb-d175c27193ab Section 4.10]. If set, the Client Characteristic Configuration Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
| Indicate || 0x20 || If set, permits indications of a Characteristic Value with acknowledgment using the procedure defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-615ed0ff-f42b-827d-6427-6474fc21737c Section 4.11]. If set, the Client Characteristic Configuration Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
| Authenticated Signed Writes || 0x40 || If set, permits signed writes to the Characteristic Value using the procedure defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-516bd731-2079-87f9-8002-c3ca92fbed4b Section 4.9.2].&lt;br /&gt;
|-&lt;br /&gt;
| Extended Properties || 0x80 || If set, additional characteristic properties are defined in the Characteristic Extended Properties Descriptor defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-9154505c-6e2d-a35a-3f30-1da0383a2425 Section 3.3.3.1]. If set, the Characteristic Extended Properties Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Property Flags ====&lt;br /&gt;
This table lists the flags for the 8-bit &#039;&#039;properties&#039;&#039; bitmask (the higher byte that is grouped with the access permissions byte), the contents of which are not part of the Bluetooth Core Specification. These can be used Bluetooth frameworks for implementation-specific features.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin:right&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Property !! Value !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Dynamic || 0x01 || indicates in BTstack that read/write operations are implemented by custom user code&lt;br /&gt;
|-&lt;br /&gt;
| Long UUID || 0x02 || indicates that the UUID of the associated characteristic is 128 bits long (instead of 16 bits)&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Characteristic Client Configuration ==&lt;br /&gt;
&lt;br /&gt;
The client configuration attribute of a GATT characteristic allows the GATT client to change the notify (or indicate) behavior for value write operations. Let us examine the sections of this example attribute:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0x0a, 0x00, 0x0e, 0x01, 0x0e, 0x00, 0x02, 0x29, 0x00, 0x00&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
From left to right, there are&lt;br /&gt;
* 2 bytes for the length of the attribute: 0x000a (= 10 bytes)&lt;br /&gt;
* 2 bytes for the permissions of this attribute: 0x010e (indicates read | write | write_without_response, dynamic)&lt;br /&gt;
* 2 bytes for the handle of this attribute: 0x000e&lt;br /&gt;
* 2 bytes for the short 16-bit UUID of this attribute: 0x2902 (the UUID for client characteristic configuration)&lt;br /&gt;
* 2 bytes that indicate whether notification or indication messages are enabled: 0x0000 (both type of messages are disabled)&lt;br /&gt;
&lt;br /&gt;
For the last two bytes, the following options are possible, depending on the requests from the GATT client to enable or disable notification or indication messages (when the value of the associated characteristic changes):&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin:right&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| bit 0 || the least significant bit indicates whether sending notifications is enabled (1) or disabled (0)&lt;br /&gt;
|-&lt;br /&gt;
| bit 1 || the next significant bit indicates whether sending indications is enabled (1) or not (0)&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
All other bits are reserved for use in future changes to the GATT protocol.&lt;br /&gt;
&lt;br /&gt;
== User description ==&lt;br /&gt;
&lt;br /&gt;
Here is an example binary sequence for a GATT user description attribute.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0x08, 0x00, 0x0a, 0x01, 0x0a, 0x00, 0x01, 0x29&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let&#039;s break down the byte grouping from left to right:&lt;br /&gt;
* 2 bytes for the length of this attribute: 0x0008 (= 8 bytes)&lt;br /&gt;
* 2 bytes for permissions: 0x010a (= read, write, dynamic)&lt;br /&gt;
* 2 bytes for the handle of this attribute&lt;br /&gt;
* 2 bytes for the 16-bit short UUID that indicates a user description attribute: 0x2901&lt;br /&gt;
where the order of the bytes in each group needs to be reversed before analyzing.&lt;br /&gt;
&lt;br /&gt;
The attribute declaration does not include the user description text itself. User description text is always &amp;quot;dynamic&amp;quot;, meaning that it is served to the client on demand on the basis of the attribute handle. In BTstack, the implementation of the read callback is responsible for returning the UTF-8 bytes for the text string corresponding the attribute handle.&lt;/div&gt;</summary>
		<author><name>Kai</name></author>
	</entry>
	<entry>
		<id>https://Robo.Fish/wiki/index.php?title=GATT_Profile_Data_in_Bluetooth_Low_Energy&amp;diff=3297</id>
		<title>GATT Profile Data in Bluetooth Low Energy</title>
		<link rel="alternate" type="text/html" href="https://Robo.Fish/wiki/index.php?title=GATT_Profile_Data_in_Bluetooth_Low_Energy&amp;diff=3297"/>
		<updated>2025-05-10T07:18:45Z</updated>

		<summary type="html">&lt;p&gt;Kai: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This article explains the binary structure of the GATT attributes data array that many Bluetooth Low Energy application frameworks, like [https://bluekitchen-gmbh.com/btstack BTstack], expect as setup input.&lt;br /&gt;
&lt;br /&gt;
= GATT characteristic attribute (descriptor) types =&lt;br /&gt;
&lt;br /&gt;
== Characteristic declaration ==&lt;br /&gt;
&lt;br /&gt;
Let&#039;s have a look at an ATT attribute that declares a GATT characteristic. Here is the binary sequence (in hex representation) generated for an attribute that declares a GATT characteristic with attribute UUID &#039;&#039;B0B0F155-B0B0-B0B0-B0B0-B0B000000101&#039;&#039; and permissions &#039;&#039;READ | DYNAMIC&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0x1b, 0x00, 0x02, 0x00, 0x08, 0x00, 0x03, 0x28, 0x02, 0x09, 0x00, 0x01, 0x01, 0x00, 0x00, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0x55, 0xf1, 0xb0, 0xb0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The bytes are grouped from left to right according to this scheme:&lt;br /&gt;
* 2 bytes for the length of this attribute definition: 0x001b (= 27 bytes)&lt;br /&gt;
* 2 bytes for the access permission of this attribute: 0x0002 (= read-only)&lt;br /&gt;
* 2 bytes for the attribute handle: 0x0008&lt;br /&gt;
* 2 bytes for the attribute type: 0x2803 (short 16-bit UUID that indicates a characteristic declaration)&lt;br /&gt;
* 1 byte for the access permissions of the declared characteristic: 0x02 (= read-only)&lt;br /&gt;
* 2 bytes for the attribute handle of the characteristic value: 0x0009&lt;br /&gt;
* 16 bytes for the 128-bit UUID of the characteristic: 0xb0b0f155b0b0b0b0b0b0b0b000000101&lt;br /&gt;
where &#039;&#039;&#039;the bytes in each group are in reverse order&#039;&#039;&#039;!&lt;br /&gt;
&lt;br /&gt;
For the official specification of the Bluetooth 5.4 GATT characteristic declaration refer to section 3.3.1 in the [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html in the Bluetooth 5.4 Core Specification].&lt;br /&gt;
&lt;br /&gt;
== Characteristic value ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0x16, 0x00, 0x02, 0x03, 0x09, 0x00, 0x01, 0x01, 0x00, 0x00, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0x55, 0xf1, 0xb0, 0xb0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The bytes are grouped from left to right as follows:&lt;br /&gt;
* 2 bytes for the length of the attribute: 0x0016 (= 22 bytes)&lt;br /&gt;
* 2 bytes for the combined properties and access permissions bitmasks of the attribute: 0x0302 (= read-only, dynamic, 128-bit UUID)&lt;br /&gt;
* 2 bytes for the handle of the attribute: 0x0009&lt;br /&gt;
* 16 bytes for the UUID of the characteristic that the value is associated with: 0xb0b0f155b0b0b0b0b0b0b0b000000101&lt;br /&gt;
&lt;br /&gt;
The bitmask the determines the access permissions (or properties) for the value have an effect on the performance the communication between GATT client and server. A write operation that does not require waiting for an acknowledgement from the server is better suited, for example, for applications in which the client sends a stream of values to the server and it does not matter if some of the values are lost or overwritten by by the next value before the server can respond.&lt;br /&gt;
&lt;br /&gt;
==== Access Permission Flags ====&lt;br /&gt;
The following table (from the Bluetooth 5.4 specification) defines the flags for the 8-bit &#039;&#039;access permissions&#039;&#039; bitmask:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin:right&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Property !! Value !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Broadcast || 0x01 || If set, permits broadcasts of the Characteristic Value using Server Characteristic Configuration Descriptor. If set, the Server Characteristic Configuration Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
| Read || 0x02 || If set, permits reads of the Characteristic Value using procedures defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-66cf484d-50cd-199f-dd0d-d0d02ad02ce0 Section 4.8]&lt;br /&gt;
|-&lt;br /&gt;
| Write Without Response || 0x04 || If set, permit writes of the Characteristic Value without response using procedures defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-9f1c2e38-8fbe-f60c-d885-076707c88a43 Section 4.9.1].&lt;br /&gt;
|-&lt;br /&gt;
| Write || 0x08 || If set, permits writes of the Characteristic Value with response using procedures defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-ba4b856a-6994-01e4-97f6-357f9be40990 Section 4.9.3] or [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-6ab738ad-6d26-1da1-7417-e83da50e90c5 Section 4.9.4].&lt;br /&gt;
|-&lt;br /&gt;
| Notify || 0x10 || If set, permits notifications of a Characteristic Value without acknowledgment using the procedure defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-74673cc2-e704-a2fa-14bb-d175c27193ab Section 4.10]. If set, the Client Characteristic Configuration Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
| Indicate || 0x20 || If set, permits indications of a Characteristic Value with acknowledgment using the procedure defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-615ed0ff-f42b-827d-6427-6474fc21737c Section 4.11]. If set, the Client Characteristic Configuration Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
| Authenticated Signed Writes || 0x40 || If set, permits signed writes to the Characteristic Value using the procedure defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-516bd731-2079-87f9-8002-c3ca92fbed4b Section 4.9.2].&lt;br /&gt;
|-&lt;br /&gt;
| Extended Properties || 0x80 || If set, additional characteristic properties are defined in the Characteristic Extended Properties Descriptor defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-9154505c-6e2d-a35a-3f30-1da0383a2425 Section 3.3.3.1]. If set, the Characteristic Extended Properties Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Property Flags ====&lt;br /&gt;
This table lists the flags for the 8-bit &#039;&#039;properties&#039;&#039; bitmask (the higher byte that is grouped with the access permissions byte)&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin:right&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Property !! Value !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Dynamic || 0x01 || indicates to the BLE framework (e.g., BTstack) that read/write operations are implemented by custom user code&lt;br /&gt;
|-&lt;br /&gt;
| Long UUID || 0x02 || indicates that the UUID of the associated characteristic is 128 bits long (instead of 16 bits)&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Characteristic Client Configuration ==&lt;br /&gt;
&lt;br /&gt;
The client configuration attribute of a GATT characteristic allows the GATT client to change the notify (or indicate) behavior for value write operations. Let us examine the sections of this example attribute:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0x0a, 0x00, 0x0e, 0x01, 0x0e, 0x00, 0x02, 0x29, 0x00, 0x00&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
From left to right, there are&lt;br /&gt;
* 2 bytes for the length of the attribute: 0x000a (= 10 bytes)&lt;br /&gt;
* 2 bytes for the permissions of this attribute: 0x010e (indicates read | write | write_without_response, dynamic)&lt;br /&gt;
* 2 bytes for the handle of this attribute: 0x000e&lt;br /&gt;
* 2 bytes for the short 16-bit UUID of this attribute: 0x2902 (the UUID for client characteristic configuration)&lt;br /&gt;
* 2 bytes that indicate whether notification or indication messages are enabled: 0x0000 (both type of messages are disabled)&lt;br /&gt;
&lt;br /&gt;
For the last two bytes, the following options are possible, depending on the requests from the GATT client to enable or disable notification or indication messages (when the value of the associated characteristic changes):&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin:right&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| bit 0 || the least significant bit indicates whether sending notifications is enabled (1) or disabled (0)&lt;br /&gt;
|-&lt;br /&gt;
| bit 1 || the next significant bit indicates whether sending indications is enabled (1) or not (0)&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
All other bits are reserved for use in future changes to the GATT protocol.&lt;br /&gt;
&lt;br /&gt;
== User description ==&lt;br /&gt;
&lt;br /&gt;
Here is an example binary sequence for a GATT user description attribute.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0x08, 0x00, 0x0a, 0x01, 0x0a, 0x00, 0x01, 0x29&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let&#039;s break down the byte grouping from left to right:&lt;br /&gt;
* 2 bytes for the length of this attribute: 0x0008 (= 8 bytes)&lt;br /&gt;
* 2 bytes for permissions: 0x010a (= read, write, dynamic)&lt;br /&gt;
* 2 bytes for the handle of this attribute&lt;br /&gt;
* 2 bytes for the 16-bit short UUID that indicates a user description attribute: 0x2901&lt;br /&gt;
where the order of the bytes in each group needs to be reversed before analyzing.&lt;br /&gt;
&lt;br /&gt;
The attribute declaration does not include the user description text itself. User description text is always &amp;quot;dynamic&amp;quot;, meaning that it is served to the client on demand on the basis of the attribute handle. In BTstack, the implementation of the read callback is responsible for returning the UTF-8 bytes for the text string corresponding the attribute handle.&lt;/div&gt;</summary>
		<author><name>Kai</name></author>
	</entry>
	<entry>
		<id>https://Robo.Fish/wiki/index.php?title=GATT_Profile_Data_in_Bluetooth_Low_Energy&amp;diff=3296</id>
		<title>GATT Profile Data in Bluetooth Low Energy</title>
		<link rel="alternate" type="text/html" href="https://Robo.Fish/wiki/index.php?title=GATT_Profile_Data_in_Bluetooth_Low_Energy&amp;diff=3296"/>
		<updated>2025-05-10T07:17:11Z</updated>

		<summary type="html">&lt;p&gt;Kai: /* Property Flags */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This article explains the binary structure of the GATT attributes data array that many Bluetooth Low Energy application frameworks, like BTstack, expect as setup input.&lt;br /&gt;
&lt;br /&gt;
= GATT characteristic attribute (descriptor) types =&lt;br /&gt;
&lt;br /&gt;
== Characteristic declaration ==&lt;br /&gt;
&lt;br /&gt;
Let&#039;s have a look at an ATT attribute that declares a GATT characteristic. Here is the binary sequence (in hex representation) generated for an attribute that declares a GATT characteristic with attribute UUID &#039;&#039;B0B0F155-B0B0-B0B0-B0B0-B0B000000101&#039;&#039; and permissions &#039;&#039;READ | DYNAMIC&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0x1b, 0x00, 0x02, 0x00, 0x08, 0x00, 0x03, 0x28, 0x02, 0x09, 0x00, 0x01, 0x01, 0x00, 0x00, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0x55, 0xf1, 0xb0, 0xb0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The bytes are grouped from left to right according to this scheme:&lt;br /&gt;
* 2 bytes for the length of this attribute definition: 0x001b (= 27 bytes)&lt;br /&gt;
* 2 bytes for the access permission of this attribute: 0x0002 (= read-only)&lt;br /&gt;
* 2 bytes for the attribute handle: 0x0008&lt;br /&gt;
* 2 bytes for the attribute type: 0x2803 (short 16-bit UUID that indicates a characteristic declaration)&lt;br /&gt;
* 1 byte for the access permissions of the declared characteristic: 0x02 (= read-only)&lt;br /&gt;
* 2 bytes for the attribute handle of the characteristic value: 0x0009&lt;br /&gt;
* 16 bytes for the 128-bit UUID of the characteristic: 0xb0b0f155b0b0b0b0b0b0b0b000000101&lt;br /&gt;
where &#039;&#039;&#039;the bytes in each group are in reverse order&#039;&#039;&#039;!&lt;br /&gt;
&lt;br /&gt;
For the official specification of the Bluetooth 5.4 GATT characteristic declaration refer to section 3.3.1 in the [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html in the Bluetooth 5.4 Core Specification].&lt;br /&gt;
&lt;br /&gt;
== Characteristic value ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0x16, 0x00, 0x02, 0x03, 0x09, 0x00, 0x01, 0x01, 0x00, 0x00, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0x55, 0xf1, 0xb0, 0xb0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The bytes are grouped from left to right as follows:&lt;br /&gt;
* 2 bytes for the length of the attribute: 0x0016 (= 22 bytes)&lt;br /&gt;
* 2 bytes for the combined properties and access permissions bitmasks of the attribute: 0x0302 (= read-only, dynamic, 128-bit UUID)&lt;br /&gt;
* 2 bytes for the handle of the attribute: 0x0009&lt;br /&gt;
* 16 bytes for the UUID of the characteristic that the value is associated with: 0xb0b0f155b0b0b0b0b0b0b0b000000101&lt;br /&gt;
&lt;br /&gt;
The bitmask the determines the access permissions (or properties) for the value have an effect on the performance the communication between GATT client and server. A write operation that does not require waiting for an acknowledgement from the server is better suited, for example, for applications in which the client sends a stream of values to the server and it does not matter if some of the values are lost or overwritten by by the next value before the server can respond.&lt;br /&gt;
&lt;br /&gt;
==== Access Permission Flags ====&lt;br /&gt;
The following table (from the Bluetooth 5.4 specification) defines the flags for the 8-bit &#039;&#039;access permissions&#039;&#039; bitmask:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin:right&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Property !! Value !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Broadcast || 0x01 || If set, permits broadcasts of the Characteristic Value using Server Characteristic Configuration Descriptor. If set, the Server Characteristic Configuration Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
| Read || 0x02 || If set, permits reads of the Characteristic Value using procedures defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-66cf484d-50cd-199f-dd0d-d0d02ad02ce0 Section 4.8]&lt;br /&gt;
|-&lt;br /&gt;
| Write Without Response || 0x04 || If set, permit writes of the Characteristic Value without response using procedures defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-9f1c2e38-8fbe-f60c-d885-076707c88a43 Section 4.9.1].&lt;br /&gt;
|-&lt;br /&gt;
| Write || 0x08 || If set, permits writes of the Characteristic Value with response using procedures defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-ba4b856a-6994-01e4-97f6-357f9be40990 Section 4.9.3] or [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-6ab738ad-6d26-1da1-7417-e83da50e90c5 Section 4.9.4].&lt;br /&gt;
|-&lt;br /&gt;
| Notify || 0x10 || If set, permits notifications of a Characteristic Value without acknowledgment using the procedure defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-74673cc2-e704-a2fa-14bb-d175c27193ab Section 4.10]. If set, the Client Characteristic Configuration Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
| Indicate || 0x20 || If set, permits indications of a Characteristic Value with acknowledgment using the procedure defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-615ed0ff-f42b-827d-6427-6474fc21737c Section 4.11]. If set, the Client Characteristic Configuration Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
| Authenticated Signed Writes || 0x40 || If set, permits signed writes to the Characteristic Value using the procedure defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-516bd731-2079-87f9-8002-c3ca92fbed4b Section 4.9.2].&lt;br /&gt;
|-&lt;br /&gt;
| Extended Properties || 0x80 || If set, additional characteristic properties are defined in the Characteristic Extended Properties Descriptor defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-9154505c-6e2d-a35a-3f30-1da0383a2425 Section 3.3.3.1]. If set, the Characteristic Extended Properties Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Property Flags ====&lt;br /&gt;
This table lists the flags for the 8-bit &#039;&#039;properties&#039;&#039; bitmask (the higher byte that is grouped with the access permissions byte)&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin:right&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Property !! Value !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Dynamic || 0x01 || indicates to the BLE framework (e.g., BTstack) that read/write operations are implemented by custom user code&lt;br /&gt;
|-&lt;br /&gt;
| Long UUID || 0x02 || indicates that the UUID of the associated characteristic is 128 bits long (instead of 16 bits)&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Characteristic Client Configuration ==&lt;br /&gt;
&lt;br /&gt;
The client configuration attribute of a GATT characteristic allows the GATT client to change the notify (or indicate) behavior for value write operations. Let us examine the sections of this example attribute:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0x0a, 0x00, 0x0e, 0x01, 0x0e, 0x00, 0x02, 0x29, 0x00, 0x00&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
From left to right, there are&lt;br /&gt;
* 2 bytes for the length of the attribute: 0x000a (= 10 bytes)&lt;br /&gt;
* 2 bytes for the permissions of this attribute: 0x010e (indicates read | write | write_without_response, dynamic)&lt;br /&gt;
* 2 bytes for the handle of this attribute: 0x000e&lt;br /&gt;
* 2 bytes for the short 16-bit UUID of this attribute: 0x2902 (the UUID for client characteristic configuration)&lt;br /&gt;
* 2 bytes that indicate whether notification or indication messages are enabled: 0x0000 (both type of messages are disabled)&lt;br /&gt;
&lt;br /&gt;
For the last two bytes, the following options are possible, depending on the requests from the GATT client to enable or disable notification or indication messages (when the value of the associated characteristic changes):&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin:right&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| bit 0 || the least significant bit indicates whether sending notifications is enabled (1) or disabled (0)&lt;br /&gt;
|-&lt;br /&gt;
| bit 1 || the next significant bit indicates whether sending indications is enabled (1) or not (0)&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
All other bits are reserved for use in future changes to the GATT protocol.&lt;br /&gt;
&lt;br /&gt;
== User description ==&lt;br /&gt;
&lt;br /&gt;
Here is an example binary sequence for a GATT user description attribute.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0x08, 0x00, 0x0a, 0x01, 0x0a, 0x00, 0x01, 0x29&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let&#039;s break down the byte grouping from left to right:&lt;br /&gt;
* 2 bytes for the length of this attribute: 0x0008 (= 8 bytes)&lt;br /&gt;
* 2 bytes for permissions: 0x010a (= read, write, dynamic)&lt;br /&gt;
* 2 bytes for the handle of this attribute&lt;br /&gt;
* 2 bytes for the 16-bit short UUID that indicates a user description attribute: 0x2901&lt;br /&gt;
where the order of the bytes in each group needs to be reversed before analyzing.&lt;br /&gt;
&lt;br /&gt;
The attribute declaration does not include the user description text itself. User description text is always &amp;quot;dynamic&amp;quot;, meaning that it is served to the client on demand on the basis of the attribute handle. In BTstack, the implementation of the read callback is responsible for returning the UTF-8 bytes for the text string corresponding the attribute handle.&lt;/div&gt;</summary>
		<author><name>Kai</name></author>
	</entry>
	<entry>
		<id>https://Robo.Fish/wiki/index.php?title=GATT_Profile_Data_in_Bluetooth_Low_Energy&amp;diff=3295</id>
		<title>GATT Profile Data in Bluetooth Low Energy</title>
		<link rel="alternate" type="text/html" href="https://Robo.Fish/wiki/index.php?title=GATT_Profile_Data_in_Bluetooth_Low_Energy&amp;diff=3295"/>
		<updated>2025-05-10T07:09:12Z</updated>

		<summary type="html">&lt;p&gt;Kai: /* Characteristic value */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This article explains the binary structure of the GATT attributes data array that many Bluetooth Low Energy application frameworks, like BTstack, expect as setup input.&lt;br /&gt;
&lt;br /&gt;
= GATT characteristic attribute (descriptor) types =&lt;br /&gt;
&lt;br /&gt;
== Characteristic declaration ==&lt;br /&gt;
&lt;br /&gt;
Let&#039;s have a look at an ATT attribute that declares a GATT characteristic. Here is the binary sequence (in hex representation) generated for an attribute that declares a GATT characteristic with attribute UUID &#039;&#039;B0B0F155-B0B0-B0B0-B0B0-B0B000000101&#039;&#039; and permissions &#039;&#039;READ | DYNAMIC&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0x1b, 0x00, 0x02, 0x00, 0x08, 0x00, 0x03, 0x28, 0x02, 0x09, 0x00, 0x01, 0x01, 0x00, 0x00, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0x55, 0xf1, 0xb0, 0xb0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The bytes are grouped from left to right according to this scheme:&lt;br /&gt;
* 2 bytes for the length of this attribute definition: 0x001b (= 27 bytes)&lt;br /&gt;
* 2 bytes for the access permission of this attribute: 0x0002 (= read-only)&lt;br /&gt;
* 2 bytes for the attribute handle: 0x0008&lt;br /&gt;
* 2 bytes for the attribute type: 0x2803 (short 16-bit UUID that indicates a characteristic declaration)&lt;br /&gt;
* 1 byte for the access permissions of the declared characteristic: 0x02 (= read-only)&lt;br /&gt;
* 2 bytes for the attribute handle of the characteristic value: 0x0009&lt;br /&gt;
* 16 bytes for the 128-bit UUID of the characteristic: 0xb0b0f155b0b0b0b0b0b0b0b000000101&lt;br /&gt;
where &#039;&#039;&#039;the bytes in each group are in reverse order&#039;&#039;&#039;!&lt;br /&gt;
&lt;br /&gt;
For the official specification of the Bluetooth 5.4 GATT characteristic declaration refer to section 3.3.1 in the [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html in the Bluetooth 5.4 Core Specification].&lt;br /&gt;
&lt;br /&gt;
== Characteristic value ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0x16, 0x00, 0x02, 0x03, 0x09, 0x00, 0x01, 0x01, 0x00, 0x00, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0x55, 0xf1, 0xb0, 0xb0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The bytes are grouped from left to right as follows:&lt;br /&gt;
* 2 bytes for the length of the attribute: 0x0016 (= 22 bytes)&lt;br /&gt;
* 2 bytes for the combined properties and access permissions bitmasks of the attribute: 0x0302 (= read-only, dynamic, 128-bit UUID)&lt;br /&gt;
* 2 bytes for the handle of the attribute: 0x0009&lt;br /&gt;
* 16 bytes for the UUID of the characteristic that the value is associated with: 0xb0b0f155b0b0b0b0b0b0b0b000000101&lt;br /&gt;
&lt;br /&gt;
The bitmask the determines the access permissions (or properties) for the value have an effect on the performance the communication between GATT client and server. A write operation that does not require waiting for an acknowledgement from the server is better suited, for example, for applications in which the client sends a stream of values to the server and it does not matter if some of the values are lost or overwritten by by the next value before the server can respond.&lt;br /&gt;
&lt;br /&gt;
==== Access Permission Flags ====&lt;br /&gt;
The following table (from the Bluetooth 5.4 specification) defines the flags for the 8-bit &#039;&#039;access permissions&#039;&#039; bitmask:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin:right&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Property !! Value !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Broadcast || 0x01 || If set, permits broadcasts of the Characteristic Value using Server Characteristic Configuration Descriptor. If set, the Server Characteristic Configuration Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
| Read || 0x02 || If set, permits reads of the Characteristic Value using procedures defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-66cf484d-50cd-199f-dd0d-d0d02ad02ce0 Section 4.8]&lt;br /&gt;
|-&lt;br /&gt;
| Write Without Response || 0x04 || If set, permit writes of the Characteristic Value without response using procedures defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-9f1c2e38-8fbe-f60c-d885-076707c88a43 Section 4.9.1].&lt;br /&gt;
|-&lt;br /&gt;
| Write || 0x08 || If set, permits writes of the Characteristic Value with response using procedures defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-ba4b856a-6994-01e4-97f6-357f9be40990 Section 4.9.3] or [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-6ab738ad-6d26-1da1-7417-e83da50e90c5 Section 4.9.4].&lt;br /&gt;
|-&lt;br /&gt;
| Notify || 0x10 || If set, permits notifications of a Characteristic Value without acknowledgment using the procedure defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-74673cc2-e704-a2fa-14bb-d175c27193ab Section 4.10]. If set, the Client Characteristic Configuration Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
| Indicate || 0x20 || If set, permits indications of a Characteristic Value with acknowledgment using the procedure defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-615ed0ff-f42b-827d-6427-6474fc21737c Section 4.11]. If set, the Client Characteristic Configuration Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
| Authenticated Signed Writes || 0x40 || If set, permits signed writes to the Characteristic Value using the procedure defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-516bd731-2079-87f9-8002-c3ca92fbed4b Section 4.9.2].&lt;br /&gt;
|-&lt;br /&gt;
| Extended Properties || 0x80 || If set, additional characteristic properties are defined in the Characteristic Extended Properties Descriptor defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-9154505c-6e2d-a35a-3f30-1da0383a2425 Section 3.3.3.1]. If set, the Characteristic Extended Properties Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Property Flags ====&lt;br /&gt;
This table lists the flags for the 8-bit &#039;&#039;properties&#039;&#039; bitmask (the higher byte that is grouped with the access permissions byte)&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin:right&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Property !! Value !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Dynamic || 0x01 || indicates that the read and write operations need to be implemented by custom application code in the GATT server&lt;br /&gt;
|-&lt;br /&gt;
| Long UUID || 0x02 || indicates that the UUID of the associated characteristic is 128 bits long (instead of 16 bits)&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Characteristic Client Configuration ==&lt;br /&gt;
&lt;br /&gt;
The client configuration attribute of a GATT characteristic allows the GATT client to change the notify (or indicate) behavior for value write operations. Let us examine the sections of this example attribute:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0x0a, 0x00, 0x0e, 0x01, 0x0e, 0x00, 0x02, 0x29, 0x00, 0x00&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
From left to right, there are&lt;br /&gt;
* 2 bytes for the length of the attribute: 0x000a (= 10 bytes)&lt;br /&gt;
* 2 bytes for the permissions of this attribute: 0x010e (indicates read | write | write_without_response, dynamic)&lt;br /&gt;
* 2 bytes for the handle of this attribute: 0x000e&lt;br /&gt;
* 2 bytes for the short 16-bit UUID of this attribute: 0x2902 (the UUID for client characteristic configuration)&lt;br /&gt;
* 2 bytes that indicate whether notification or indication messages are enabled: 0x0000 (both type of messages are disabled)&lt;br /&gt;
&lt;br /&gt;
For the last two bytes, the following options are possible, depending on the requests from the GATT client to enable or disable notification or indication messages (when the value of the associated characteristic changes):&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin:right&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| bit 0 || the least significant bit indicates whether sending notifications is enabled (1) or disabled (0)&lt;br /&gt;
|-&lt;br /&gt;
| bit 1 || the next significant bit indicates whether sending indications is enabled (1) or not (0)&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
All other bits are reserved for use in future changes to the GATT protocol.&lt;br /&gt;
&lt;br /&gt;
== User description ==&lt;br /&gt;
&lt;br /&gt;
Here is an example binary sequence for a GATT user description attribute.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0x08, 0x00, 0x0a, 0x01, 0x0a, 0x00, 0x01, 0x29&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let&#039;s break down the byte grouping from left to right:&lt;br /&gt;
* 2 bytes for the length of this attribute: 0x0008 (= 8 bytes)&lt;br /&gt;
* 2 bytes for permissions: 0x010a (= read, write, dynamic)&lt;br /&gt;
* 2 bytes for the handle of this attribute&lt;br /&gt;
* 2 bytes for the 16-bit short UUID that indicates a user description attribute: 0x2901&lt;br /&gt;
where the order of the bytes in each group needs to be reversed before analyzing.&lt;br /&gt;
&lt;br /&gt;
The attribute declaration does not include the user description text itself. User description text is always &amp;quot;dynamic&amp;quot;, meaning that it is served to the client on demand on the basis of the attribute handle. In BTstack, the implementation of the read callback is responsible for returning the UTF-8 bytes for the text string corresponding the attribute handle.&lt;/div&gt;</summary>
		<author><name>Kai</name></author>
	</entry>
	<entry>
		<id>https://Robo.Fish/wiki/index.php?title=GATT_Profile_Data_in_Bluetooth_Low_Energy&amp;diff=3294</id>
		<title>GATT Profile Data in Bluetooth Low Energy</title>
		<link rel="alternate" type="text/html" href="https://Robo.Fish/wiki/index.php?title=GATT_Profile_Data_in_Bluetooth_Low_Energy&amp;diff=3294"/>
		<updated>2025-05-10T06:17:44Z</updated>

		<summary type="html">&lt;p&gt;Kai: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This article explains the binary structure of the GATT attributes data array that many Bluetooth Low Energy application frameworks, like BTstack, expect as setup input.&lt;br /&gt;
&lt;br /&gt;
= GATT characteristic attribute (descriptor) types =&lt;br /&gt;
&lt;br /&gt;
== Characteristic declaration ==&lt;br /&gt;
&lt;br /&gt;
Let&#039;s have a look at an ATT attribute that declares a GATT characteristic. Here is the binary sequence (in hex representation) generated for an attribute that declares a GATT characteristic with attribute UUID &#039;&#039;B0B0F155-B0B0-B0B0-B0B0-B0B000000101&#039;&#039; and permissions &#039;&#039;READ | DYNAMIC&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0x1b, 0x00, 0x02, 0x00, 0x08, 0x00, 0x03, 0x28, 0x02, 0x09, 0x00, 0x01, 0x01, 0x00, 0x00, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0x55, 0xf1, 0xb0, 0xb0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The bytes are grouped from left to right according to this scheme:&lt;br /&gt;
* 2 bytes for the length of this attribute definition: 0x001b (= 27 bytes)&lt;br /&gt;
* 2 bytes for the access permission of this attribute: 0x0002 (= read-only)&lt;br /&gt;
* 2 bytes for the attribute handle: 0x0008&lt;br /&gt;
* 2 bytes for the attribute type: 0x2803 (short 16-bit UUID that indicates a characteristic declaration)&lt;br /&gt;
* 1 byte for the access permissions of the declared characteristic: 0x02 (= read-only)&lt;br /&gt;
* 2 bytes for the attribute handle of the characteristic value: 0x0009&lt;br /&gt;
* 16 bytes for the 128-bit UUID of the characteristic: 0xb0b0f155b0b0b0b0b0b0b0b000000101&lt;br /&gt;
where &#039;&#039;&#039;the bytes in each group are in reverse order&#039;&#039;&#039;!&lt;br /&gt;
&lt;br /&gt;
For the official specification of the Bluetooth 5.4 GATT characteristic declaration refer to section 3.3.1 in the [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html in the Bluetooth 5.4 Core Specification].&lt;br /&gt;
&lt;br /&gt;
== Characteristic value ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0x16, 0x00, 0x02, 0x03, 0x09, 0x00, 0x01, 0x01, 0x00, 0x00, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0x55, 0xf1, 0xb0, 0xb0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The bytes are grouped from left to right as follows:&lt;br /&gt;
* 2 bytes for the length of the attribute: 0x0016 (= 22 bytes)&lt;br /&gt;
* 2 bytes for the permissions (properties) of the attribute: 0x0302 (= read-only, dynamic, 128-bit UUID)&lt;br /&gt;
* 2 bytes for the handle of the attribute: 0x0009&lt;br /&gt;
* 16 bytes for the UUID of the characteristic that the value is associated with: 0xb0b0f155b0b0b0b0b0b0b0b000000101&lt;br /&gt;
&lt;br /&gt;
The permission/property flags for the value have an effect on the performance the communication between GATT client and server. A write operation that does not require waiting for an acknowledgement from the server is better suited, for example, for applications in which the client sends a stream of values to the server and it does not matter if some of the values are lost or overwritten by by the next value before the server can respond.&lt;br /&gt;
&lt;br /&gt;
The following table (from the Bluetooth 5.4 specification) defines the flags that can be combined to set the properties of an attribute:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin:right&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Property !! Value !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Broadcast || 0x01 || If set, permits broadcasts of the Characteristic Value using Server Characteristic Configuration Descriptor. If set, the Server Characteristic Configuration Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
| Read || 0x02 || If set, permits reads of the Characteristic Value using procedures defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-66cf484d-50cd-199f-dd0d-d0d02ad02ce0 Section 4.8]&lt;br /&gt;
|-&lt;br /&gt;
| Write Without Response || 0x04 || If set, permit writes of the Characteristic Value without response using procedures defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-9f1c2e38-8fbe-f60c-d885-076707c88a43 Section 4.9.1].&lt;br /&gt;
|-&lt;br /&gt;
| Write || 0x08 || If set, permits writes of the Characteristic Value with response using procedures defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-ba4b856a-6994-01e4-97f6-357f9be40990 Section 4.9.3] or [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-6ab738ad-6d26-1da1-7417-e83da50e90c5 Section 4.9.4].&lt;br /&gt;
|-&lt;br /&gt;
| Notify || 0x10 || If set, permits notifications of a Characteristic Value without acknowledgment using the procedure defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-74673cc2-e704-a2fa-14bb-d175c27193ab Section 4.10]. If set, the Client Characteristic Configuration Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
| Indicate || 0x20 || If set, permits indications of a Characteristic Value with acknowledgment using the procedure defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-615ed0ff-f42b-827d-6427-6474fc21737c Section 4.11]. If set, the Client Characteristic Configuration Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
| Authenticated Signed Writes || 0x40 || If set, permits signed writes to the Characteristic Value using the procedure defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-516bd731-2079-87f9-8002-c3ca92fbed4b Section 4.9.2].&lt;br /&gt;
|-&lt;br /&gt;
| Extended Properties || 0x80 || If set, additional characteristic properties are defined in the Characteristic Extended Properties Descriptor defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-9154505c-6e2d-a35a-3f30-1da0383a2425 Section 3.3.3.1]. If set, the Characteristic Extended Properties Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Characteristic Client Configuration ==&lt;br /&gt;
&lt;br /&gt;
The client configuration attribute of a GATT characteristic allows the GATT client to change the notify (or indicate) behavior for value write operations. Let us examine the sections of this example attribute:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0x0a, 0x00, 0x0e, 0x01, 0x0e, 0x00, 0x02, 0x29, 0x00, 0x00&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
From left to right, there are&lt;br /&gt;
* 2 bytes for the length of the attribute: 0x000a (= 10 bytes)&lt;br /&gt;
* 2 bytes for the permissions of this attribute: 0x010e (indicates read | write | write_without_response, dynamic)&lt;br /&gt;
* 2 bytes for the handle of this attribute: 0x000e&lt;br /&gt;
* 2 bytes for the short 16-bit UUID of this attribute: 0x2902 (the UUID for client characteristic configuration)&lt;br /&gt;
* 2 bytes that indicate whether notification or indication messages are enabled: 0x0000 (both type of messages are disabled)&lt;br /&gt;
&lt;br /&gt;
For the last two bytes, the following options are possible, depending on the requests from the GATT client to enable or disable notification or indication messages (when the value of the associated characteristic changes):&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin:right&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| bit 0 || the least significant bit indicates whether sending notifications is enabled (1) or disabled (0)&lt;br /&gt;
|-&lt;br /&gt;
| bit 1 || the next significant bit indicates whether sending indications is enabled (1) or not (0)&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
All other bits are reserved for use in future changes to the GATT protocol.&lt;br /&gt;
&lt;br /&gt;
== User description ==&lt;br /&gt;
&lt;br /&gt;
Here is an example binary sequence for a GATT user description attribute.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0x08, 0x00, 0x0a, 0x01, 0x0a, 0x00, 0x01, 0x29&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let&#039;s break down the byte grouping from left to right:&lt;br /&gt;
* 2 bytes for the length of this attribute: 0x0008 (= 8 bytes)&lt;br /&gt;
* 2 bytes for permissions: 0x010a (= read, write, dynamic)&lt;br /&gt;
* 2 bytes for the handle of this attribute&lt;br /&gt;
* 2 bytes for the 16-bit short UUID that indicates a user description attribute: 0x2901&lt;br /&gt;
where the order of the bytes in each group needs to be reversed before analyzing.&lt;br /&gt;
&lt;br /&gt;
The attribute declaration does not include the user description text itself. User description text is always &amp;quot;dynamic&amp;quot;, meaning that it is served to the client on demand on the basis of the attribute handle. In BTstack, the implementation of the read callback is responsible for returning the UTF-8 bytes for the text string corresponding the attribute handle.&lt;/div&gt;</summary>
		<author><name>Kai</name></author>
	</entry>
	<entry>
		<id>https://Robo.Fish/wiki/index.php?title=GATT_Profile_Data_in_Bluetooth_Low_Energy&amp;diff=3293</id>
		<title>GATT Profile Data in Bluetooth Low Energy</title>
		<link rel="alternate" type="text/html" href="https://Robo.Fish/wiki/index.php?title=GATT_Profile_Data_in_Bluetooth_Low_Energy&amp;diff=3293"/>
		<updated>2025-05-10T05:32:26Z</updated>

		<summary type="html">&lt;p&gt;Kai: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This article explains the binary structure of the GATT attributes data array that many Bluetooth Low Energy application frameworks, like BTstack, expect as setup input.&lt;br /&gt;
&lt;br /&gt;
= GATT characteristic attribute (descriptor) types =&lt;br /&gt;
&lt;br /&gt;
== Characteristic declaration ==&lt;br /&gt;
&lt;br /&gt;
Let&#039;s have a look at an ATT attribute that declares a GATT characteristic. Here is the binary sequence (in hex representation) generated for an attribute that declares a GATT characteristic with attribute UUID &#039;&#039;B0B0F155-B0B0-B0B0-B0B0-B0B000000101&#039;&#039; and permissions &#039;&#039;READ | DYNAMIC&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0x1b, 0x00, 0x02, 0x00, 0x08, 0x00, 0x03, 0x28, 0x02, 0x09, 0x00, 0x01, 0x01, 0x00, 0x00, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0x55, 0xf1, 0xb0, 0xb0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The bytes are grouped from left to right according to this scheme:&lt;br /&gt;
* 2 bytes for the length of this attribute definition: 0x001b (= 27 bytes)&lt;br /&gt;
* 2 bytes for the access permission of this attribute: 0x0002 (= read-only)&lt;br /&gt;
* 2 bytes for the attribute handle: 0x0008&lt;br /&gt;
* 2 bytes for the attribute type: 0x2803 (short 16-bit UUID that indicates a characteristic declaration)&lt;br /&gt;
* 1 byte for the access permissions of the declared characteristic: 0x02 (= read-only)&lt;br /&gt;
* 2 bytes for the attribute handle of the characteristic value: 0x0009&lt;br /&gt;
* 16 bytes for the 128-bit UUID of the characteristic: 0xb0b0f155b0b0b0b0b0b0b0b000000101&lt;br /&gt;
where &#039;&#039;&#039;the bytes in each group are in reverse order&#039;&#039;&#039;!&lt;br /&gt;
&lt;br /&gt;
For the official specification of the Bluetooth 5.4 GATT characteristic declaration refer to section 3.3.1 in the [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html in the Bluetooth 5.4 Core Specification]. That section also lists the characteristics permissions (or properties):&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin:auto&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Properties !! Value !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Broadcast || 0x01 || If set, permits broadcasts of the Characteristic Value using Server Characteristic Configuration Descriptor. If set, the Server Characteristic Configuration Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
| Read || 0x02 || If set, permits reads of the Characteristic Value using procedures defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-66cf484d-50cd-199f-dd0d-d0d02ad02ce0 Section 4.8]&lt;br /&gt;
|-&lt;br /&gt;
| Write Without Response || 0x04 || If set, permit writes of the Characteristic Value without response using procedures defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-9f1c2e38-8fbe-f60c-d885-076707c88a43 Section 4.9.1].&lt;br /&gt;
|-&lt;br /&gt;
| Write || 0x08 || If set, permits writes of the Characteristic Value with response using procedures defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-ba4b856a-6994-01e4-97f6-357f9be40990 Section 4.9.3] or [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-6ab738ad-6d26-1da1-7417-e83da50e90c5 Section 4.9.4].&lt;br /&gt;
|-&lt;br /&gt;
| Notify || 0x10 || If set, permits notifications of a Characteristic Value without acknowledgment using the procedure defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-74673cc2-e704-a2fa-14bb-d175c27193ab Section 4.10]. If set, the Client Characteristic Configuration Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
| Indicate || 0x20 || If set, permits indications of a Characteristic Value with acknowledgment using the procedure defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-615ed0ff-f42b-827d-6427-6474fc21737c Section 4.11]. If set, the Client Characteristic Configuration Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
| Authenticated Signed Writes || 0x40 || If set, permits signed writes to the Characteristic Value using the procedure defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-516bd731-2079-87f9-8002-c3ca92fbed4b Section 4.9.2].&lt;br /&gt;
|-&lt;br /&gt;
| Extended Properties || 0x80 || If set, additional characteristic properties are defined in the Characteristic Extended Properties Descriptor defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-9154505c-6e2d-a35a-3f30-1da0383a2425 Section 3.3.3.1]. If set, the Characteristic Extended Properties Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Characteristic value ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0x16, 0x00, 0x02, 0x03, 0x09, 0x00, 0x01, 0x01, 0x00, 0x00, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0x55, 0xf1, 0xb0, 0xb0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The bytes are grouped from left to right as follows:&lt;br /&gt;
* 2 bytes for the length of the attribute: 0x0016 (= 22 bytes)&lt;br /&gt;
* 2 bytes for the permissions (properties) of the attribute: 0x0302 (= read-only, dynamic, 128-bit UUID)&lt;br /&gt;
* 2 bytes for the handle of the attribute: 0x0009&lt;br /&gt;
* 16 bytes for the UUID of the characteristic that the value is associated with: 0xb0b0f155b0b0b0b0b0b0b0b000000101 &lt;br /&gt;
&lt;br /&gt;
== Characteristic Client Configuration ==&lt;br /&gt;
&lt;br /&gt;
The client configuration attribute of a GATT characteristic allows the GATT client to change the notify (or indicate) behavior for value write operations. Let us examine the sections of this example attribute:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0x0a, 0x00, 0x0e, 0x01, 0x0e, 0x00, 0x02, 0x29, 0x00, 0x00&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
From left to right, there are&lt;br /&gt;
* 2 bytes for the length of the attribute: 0x000a (= 10 bytes)&lt;br /&gt;
* 2 bytes for the permissions of this attribute: 0x010e (indicates read | write | write_without_response, dynamic)&lt;br /&gt;
* 2 bytes for the handle of this attribute: 0x000e&lt;br /&gt;
* 2 bytes for the short 16-bit UUID of this attribute: 0x2902 (the UUID for client characteristic configuration)&lt;br /&gt;
* 2 bytes that indicate whether notification or indication messages are enabled: 0x0000 (both type of messages are disabled)&lt;br /&gt;
&lt;br /&gt;
For the last two bytes, the following options are possible, depending on the requests from the GATT client to enable or disable notification or indication messages (when the value of the associated characteristic changes):&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin:right&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| bit 0 || the least significant bit indicates whether sending notifications is enabled (1) or disabled (0)&lt;br /&gt;
|-&lt;br /&gt;
| bit 1 || the next significant bit indicates whether sending indications is enabled (1) or not (0)&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
All other bits are reserved for use in future changes to the GATT protocol.&lt;br /&gt;
&lt;br /&gt;
== User description ==&lt;br /&gt;
&lt;br /&gt;
Here is an example binary sequence for a GATT user description attribute.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0x08, 0x00, 0x0a, 0x01, 0x0a, 0x00, 0x01, 0x29&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let&#039;s break down the byte grouping from left to right:&lt;br /&gt;
* 2 bytes for the length of this attribute: 0x0008 (= 8 bytes)&lt;br /&gt;
* 2 bytes for permissions: 0x010a (= read, write, dynamic)&lt;br /&gt;
* 2 bytes for the handle of this attribute&lt;br /&gt;
* 2 bytes for the 16-bit short UUID that indicates a user description attribute: 0x2901&lt;br /&gt;
where the order of the bytes in each group needs to be reversed before analyzing.&lt;br /&gt;
&lt;br /&gt;
The attribute declaration does not include the user description text itself. User description text is always &amp;quot;dynamic&amp;quot;, meaning that it is served to the client on demand on the basis of the attribute handle. In BTstack, the implementation of the read callback is responsible for returning the UTF-8 bytes for the text string corresponding the attribute handle.&lt;/div&gt;</summary>
		<author><name>Kai</name></author>
	</entry>
	<entry>
		<id>https://Robo.Fish/wiki/index.php?title=GATT_Profile_Data_in_Bluetooth_Low_Energy&amp;diff=3292</id>
		<title>GATT Profile Data in Bluetooth Low Energy</title>
		<link rel="alternate" type="text/html" href="https://Robo.Fish/wiki/index.php?title=GATT_Profile_Data_in_Bluetooth_Low_Energy&amp;diff=3292"/>
		<updated>2025-05-10T05:28:56Z</updated>

		<summary type="html">&lt;p&gt;Kai: /* GATT characteristic client configuration attribute */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This article explains the binary structure of the GATT attributes data array that many Bluetooth Low Energy application frameworks, like BTstack, expect as setup input.&lt;br /&gt;
&lt;br /&gt;
== GATT characteristic declaration attribute ==&lt;br /&gt;
&lt;br /&gt;
Let&#039;s have a look at an ATT attribute that declares a GATT characteristic. Here is the binary sequence (in hex representation) generated for an attribute that declares a GATT characteristic with attribute UUID &#039;&#039;B0B0F155-B0B0-B0B0-B0B0-B0B000000101&#039;&#039; and permissions &#039;&#039;READ | DYNAMIC&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0x1b, 0x00, 0x02, 0x00, 0x08, 0x00, 0x03, 0x28, 0x02, 0x09, 0x00, 0x01, 0x01, 0x00, 0x00, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0x55, 0xf1, 0xb0, 0xb0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The bytes are grouped from left to right according to this scheme:&lt;br /&gt;
* 2 bytes for the length of this attribute definition: 0x001b (= 27 bytes)&lt;br /&gt;
* 2 bytes for the access permission of this attribute: 0x0002 (= read-only)&lt;br /&gt;
* 2 bytes for the attribute handle: 0x0008&lt;br /&gt;
* 2 bytes for the attribute type: 0x2803 (short 16-bit UUID that indicates a characteristic declaration)&lt;br /&gt;
* 1 byte for the access permissions of the declared characteristic: 0x02 (= read-only)&lt;br /&gt;
* 2 bytes for the attribute handle of the characteristic value: 0x0009&lt;br /&gt;
* 16 bytes for the 128-bit UUID of the characteristic: 0xb0b0f155b0b0b0b0b0b0b0b000000101&lt;br /&gt;
where &#039;&#039;&#039;the bytes in each group are in reverse order&#039;&#039;&#039;!&lt;br /&gt;
&lt;br /&gt;
For the official specification of the Bluetooth 5.4 GATT characteristic declaration refer to section 3.3.1 in the [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html in the Bluetooth 5.4 Core Specification]. That section also lists the characteristics permissions (or properties):&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin:auto&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Properties !! Value !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Broadcast || 0x01 || If set, permits broadcasts of the Characteristic Value using Server Characteristic Configuration Descriptor. If set, the Server Characteristic Configuration Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
| Read || 0x02 || If set, permits reads of the Characteristic Value using procedures defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-66cf484d-50cd-199f-dd0d-d0d02ad02ce0 Section 4.8]&lt;br /&gt;
|-&lt;br /&gt;
| Write Without Response || 0x04 || If set, permit writes of the Characteristic Value without response using procedures defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-9f1c2e38-8fbe-f60c-d885-076707c88a43 Section 4.9.1].&lt;br /&gt;
|-&lt;br /&gt;
| Write || 0x08 || If set, permits writes of the Characteristic Value with response using procedures defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-ba4b856a-6994-01e4-97f6-357f9be40990 Section 4.9.3] or [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-6ab738ad-6d26-1da1-7417-e83da50e90c5 Section 4.9.4].&lt;br /&gt;
|-&lt;br /&gt;
| Notify || 0x10 || If set, permits notifications of a Characteristic Value without acknowledgment using the procedure defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-74673cc2-e704-a2fa-14bb-d175c27193ab Section 4.10]. If set, the Client Characteristic Configuration Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
| Indicate || 0x20 || If set, permits indications of a Characteristic Value with acknowledgment using the procedure defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-615ed0ff-f42b-827d-6427-6474fc21737c Section 4.11]. If set, the Client Characteristic Configuration Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
| Authenticated Signed Writes || 0x40 || If set, permits signed writes to the Characteristic Value using the procedure defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-516bd731-2079-87f9-8002-c3ca92fbed4b Section 4.9.2].&lt;br /&gt;
|-&lt;br /&gt;
| Extended Properties || 0x80 || If set, additional characteristic properties are defined in the Characteristic Extended Properties Descriptor defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-9154505c-6e2d-a35a-3f30-1da0383a2425 Section 3.3.3.1]. If set, the Characteristic Extended Properties Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== GATT characteristic value attribute ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0x16, 0x00, 0x02, 0x03, 0x09, 0x00, 0x01, 0x01, 0x00, 0x00, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0x55, 0xf1, 0xb0, 0xb0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The bytes are grouped from left to right as follows:&lt;br /&gt;
* 2 bytes for the length of the attribute: 0x0016 (= 22 bytes)&lt;br /&gt;
* 2 bytes for the permissions (properties) of the attribute: 0x0302 (= read-only, dynamic, 128-bit UUID)&lt;br /&gt;
* 2 bytes for the handle of the attribute: 0x0009&lt;br /&gt;
* 16 bytes for the UUID of the characteristic that the value is associated with: 0xb0b0f155b0b0b0b0b0b0b0b000000101 &lt;br /&gt;
&lt;br /&gt;
== GATT characteristic client configuration attribute ==&lt;br /&gt;
&lt;br /&gt;
The client characteristic configuration attribute (descriptor) of a GATT characteristic allows the GATT client to change the notify (or indicate) behavior for value write operations. Let us examine the sections of this example attribute:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0x0a, 0x00, 0x0e, 0x01, 0x0e, 0x00, 0x02, 0x29, 0x00, 0x00&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
From left to right, there are&lt;br /&gt;
* 2 bytes for the length of the attribute: 0x000a (= 10 bytes)&lt;br /&gt;
* 2 bytes for the permissions of this attribute: 0x010e (indicates read | write | write_without_response, dynamic)&lt;br /&gt;
* 2 bytes for the handle of this attribute: 0x000e&lt;br /&gt;
* 2 bytes for the short 16-bit UUID of this attribute: 0x2902 (the UUID for client characteristic configuration)&lt;br /&gt;
* 2 bytes that indicate whether notification or indication messages are enabled: 0x0000 (both type of messages are disabled)&lt;br /&gt;
&lt;br /&gt;
For the last two bytes, the following options are possible, depending on the requests from the GATT client to enable or disable notification or indication messages (when the value of the associated characteristic changes):&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin:right&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| bit 0 || the least significant bit indicates whether sending notifications is enabled (1) or disabled (0)&lt;br /&gt;
|-&lt;br /&gt;
| bit 1 || the next significant bit indicates whether sending indications is enabled (1) or not (0)&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
All other bits are reserved for use in future changes to the GATT protocol.&lt;br /&gt;
&lt;br /&gt;
== GATT characteristic user description attribute ==&lt;br /&gt;
&lt;br /&gt;
Here is an example binary sequence for a GATT user description attribute.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0x08, 0x00, 0x0a, 0x01, 0x0a, 0x00, 0x01, 0x29&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let&#039;s break down the byte grouping from left to right:&lt;br /&gt;
* 2 bytes for the length of this attribute: 0x0008 (= 8 bytes)&lt;br /&gt;
* 2 bytes for permissions: 0x010a (= read, write, dynamic)&lt;br /&gt;
* 2 bytes for the handle of this attribute&lt;br /&gt;
* 2 bytes for the 16-bit short UUID that indicates a user description attribute: 0x2901&lt;br /&gt;
where the order of the bytes in each group needs to be reversed before analyzing.&lt;br /&gt;
&lt;br /&gt;
The attribute declaration does not include the user description text itself. User description text is always &amp;quot;dynamic&amp;quot;, meaning that it is served to the client on demand on the basis of the attribute handle. In BTstack, the implementation of the read callback is responsible for returning the UTF-8 bytes for the text string corresponding the attribute handle.&lt;/div&gt;</summary>
		<author><name>Kai</name></author>
	</entry>
	<entry>
		<id>https://Robo.Fish/wiki/index.php?title=Raspberry_Pi_Microcontrollers&amp;diff=3291</id>
		<title>Raspberry Pi Microcontrollers</title>
		<link rel="alternate" type="text/html" href="https://Robo.Fish/wiki/index.php?title=Raspberry_Pi_Microcontrollers&amp;diff=3291"/>
		<updated>2025-05-09T23:08:31Z</updated>

		<summary type="html">&lt;p&gt;Kai: /* GATT Profiles, Services, Characteristics, and Descriptors */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Pico Series =&lt;br /&gt;
* Raspberry Pi Pico and Pico W&lt;br /&gt;
** Dual [https://developer.arm.com/Processors/Cortex-M0-Plus Arm Cortex-M0+] with Armv6-M programming model, up to 133 MHz&lt;br /&gt;
* Raspberry Pi Pico 2 and Pico 2 W&lt;br /&gt;
** Dual [https://developer.arm.com/Processors/Cortex-M33 Arm Cortex-M33] with Armv8-M programming model, up to 150 MHz&lt;br /&gt;
&lt;br /&gt;
== Development Setup ==&lt;br /&gt;
&lt;br /&gt;
=== Using the Raspberry Pi Debug Probe ===&lt;br /&gt;
The Debug Probe is a RP2040 based USB-to-UART/SWD board for connecting the USB slot of a development machine to the SWD or UART pins of a target device.&lt;br /&gt;
&lt;br /&gt;
=== Using A Pico To Debug Another Pico ===&lt;br /&gt;
A Pico can be used to debug another Pico (a.k.a. target device)  by flashing it with the [https://github.com/raspberrypi/debugprobe debugprobe] binary and wiring to the target Pico as shown below.&lt;br /&gt;
&lt;br /&gt;
[[File:Wiring_rpi_pico_as_debugger.png | x320 px | A Raspberry Pi Pico wired to debug another Pico]]&lt;br /&gt;
&lt;br /&gt;
From the debugger Pico to the target Pico,&lt;br /&gt;
* pin #4 (GP2) connects to pin SWCLK,&lt;br /&gt;
* pin #5 (GP3) connects to SWDIO,&lt;br /&gt;
* pin #6 (GP4, UART1 TX) connects to pin #2 (GP1, UART0 RX),&lt;br /&gt;
* pin #7 (GP5, UART1 RX) connects to pin #1 (GP0, UART0, TX).&lt;br /&gt;
&lt;br /&gt;
The debugger Pico serves both as a USB-to-SWD and USB-to-UART bridge to the target device. The development machine, therefore, needs to be connected via USB only to the debugger Pico. Console output on the target Pico is relayed through the debugger. It is possible, though, to connect a second USB cable from the development machine to the target device for (simultaneous) direct access to the console output. This debugger setup works not just with Pico targets but with any microcontroller that supports the CMSIS-DAP protocol over SWD.&lt;br /&gt;
&lt;br /&gt;
=== Software Tools for Debugging ===&lt;br /&gt;
Whether we use the Raspberry Pi Debug Probe or a spare Pico as debug probe, the software tools used for debugging are the same:&lt;br /&gt;
* openocd&lt;br /&gt;
&lt;br /&gt;
== Notes on Programming with the C SDK ==&lt;br /&gt;
&lt;br /&gt;
=== Async Context ===&lt;br /&gt;
In the C SDK, an [https://www.raspberrypi.com/documentation/pico-sdk/high_level.html#group_pico_async_context async_context] is used in concurrent programming to make sure that functions are executed on the same thread and in the order they were submitted, similar to dispatch queues in Apple&#039;s [https://developer.apple.com/documentation/dispatch?language=objc Dispatch framework]. The &#039;&#039;async_context&#039;&#039; data structure is a container of linked lists of worker functions that are executed within a single thread of a single processor core.&lt;br /&gt;
&lt;br /&gt;
=== Bluetooth with BTstack ===&lt;br /&gt;
&lt;br /&gt;
The C SDK integrates the third-party [https://bluekitchen-gmbh.com/btstack BTstack] framework as its Bluetooth API that interfaces with the Infineon CYW43 wireless communication module (on Pico W models) via the Host-Controller Interface (HCI) protocol.&lt;br /&gt;
&lt;br /&gt;
==== Setup ====&lt;br /&gt;
&lt;br /&gt;
Before we can call any BTstack functions (and hope for some meaningful outcome), we need to add a &#039;&#039;&#039;btstack_config.h&#039;&#039;&#039; header file to our project. In it, we add all the compile-time switches that fit our application. On a microcontroller, a frequent use case for BTstack is to implement a BLE peripheral. For this we, our config header should look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#ifndef MY_BTSTACK_CONFIG_H&lt;br /&gt;
#define MY_BTSTACK_CONFIG_H&lt;br /&gt;
&lt;br /&gt;
#ifndef ENABLE_BLE&lt;br /&gt;
#error In CMakeLists.txt add the &#039;pico_btstack_ble&#039; library to target_link_libraries(...)&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// logging&lt;br /&gt;
#define ENABLE_LOG_INFO&lt;br /&gt;
#define ENABLE_LOG_ERROR&lt;br /&gt;
#define ENABLE_PRINTF_HEXDUMP // required for hci_dump_init()&lt;br /&gt;
&lt;br /&gt;
#if 1 // configure as peripheral (GATT server)&lt;br /&gt;
	#define ENABLE_LE_PERIPHERAL&lt;br /&gt;
	#define MAX_NR_GATT_CLIENTS 0&lt;br /&gt;
#else // configure as central (GATT client)&lt;br /&gt;
	#define ENABLE_LE_CENTRAL&lt;br /&gt;
	#define MAX_NR_GATT_CLIENTS 1&lt;br /&gt;
//#define ENABLE_GATT_CLIENT_PAIRING&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// Setting various buffer sizes related to HCI communication&lt;br /&gt;
#define HCI_OUTGOING_PRE_BUFFER_SIZE 4&lt;br /&gt;
#define HCI_ACL_PAYLOAD_SIZE (255 + 4)&lt;br /&gt;
#define HCI_ACL_CHUNK_SIZE_ALIGNMENT 4&lt;br /&gt;
#define MAX_NR_HCI_CONNECTIONS 1&lt;br /&gt;
#define MAX_NR_SM_LOOKUP_ENTRIES 3&lt;br /&gt;
#define MAX_NR_WHITELIST_ENTRIES 16&lt;br /&gt;
#define MAX_NR_LE_DEVICE_DB_ENTRIES 16&lt;br /&gt;
&lt;br /&gt;
// Choosing a fixed-size attributes table over using malloc.&lt;br /&gt;
// We want to use BTstack without heap memory allocations.&lt;br /&gt;
#if 1&lt;br /&gt;
#define MAX_ATT_DB_SIZE 512&lt;br /&gt;
#else&lt;br /&gt;
#define HAVE_MALLOC&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// Enabling timers&lt;br /&gt;
#if 1&lt;br /&gt;
#define HAVE_EMBEDDED_TIME_MS&lt;br /&gt;
#else&lt;br /&gt;
#define HAVE_EMBEDDED_TICK&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// Limiting the amount of nonvolatile (flash) memory used for storing peer bonding information&lt;br /&gt;
#define NVM_NUM_DEVICE_DB_ENTRIES 16&lt;br /&gt;
#define NVM_NUM_LINK_KEYS 16&lt;br /&gt;
&lt;br /&gt;
// Configuring HCI Controller-to-Host flow control and related buffers to avoid overrunning the cyw43 shared bus&lt;br /&gt;
#define ENABLE_HCI_CONTROLLER_TO_HOST_FLOW_CONTROL&lt;br /&gt;
#define HCI_HOST_ACL_PACKET_LEN (255+4)&lt;br /&gt;
#define HCI_HOST_ACL_PACKET_NUM 3&lt;br /&gt;
#define HCI_HOST_SCO_PACKET_LEN 120&lt;br /&gt;
#define HCI_HOST_SCO_PACKET_NUM 3&lt;br /&gt;
#define MAX_NR_CONTROLLER_SCO_PACKETS 3&lt;br /&gt;
#define MAX_NR_CONTROLLER_ACL_BUFFERS 3&lt;br /&gt;
&lt;br /&gt;
// Enabling btstack_assert, acting just like normal assert()&lt;br /&gt;
#define HAVE_ASSERT&lt;br /&gt;
&lt;br /&gt;
// Setting HCI resend timeout in case the Bluetooth module needs more time to response.&lt;br /&gt;
#define HCI_RESET_RESEND_TIMEOUT_MS 800&lt;br /&gt;
&lt;br /&gt;
// Configuring security&lt;br /&gt;
#define ENABLE_SOFTWARE_AES128&lt;br /&gt;
#define ENABLE_MICRO_ECC_FOR_LE_SECURE_CONNECTIONS&lt;br /&gt;
&lt;br /&gt;
#endif // MY_BTSTACK_CONFIG_H&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== GATT Profiles, Services, Characteristics, and Descriptors ====&lt;br /&gt;
&lt;br /&gt;
A Bluetooth Low Energy Peripheral organizes the served data in a linear attributes table or database, referred to as  ATT. The GATT (Generic Attributes) profile used in BLE is, contrary to what the name suggests, a specific organizational structure imposed on the ATT table, where the data table as a whole is referred to as &amp;quot;profile&amp;quot;. The profile attributes can be broken down into consecutive &amp;quot;service&amp;quot; attributes, the service attributes into &amp;quot;characteristic&amp;quot; attributes, the characteristics into &amp;quot;descriptor&amp;quot; attributes. So, all in all there linear ATT table becomes a tree structure with four levels in GATT. A BLE peripheral, acting as a GATT server when connected to, will advertise its profile over GAP. A BLE central, acting as a GATT client after establishing a connection to the peripheral, can read the complete GATT hierarchy to find out about the profile contents.&lt;br /&gt;
&lt;br /&gt;
BTstack allows defining a GATT table as a human-readable text file. The translation of that file into a C header by a Python script is a build step that can be included in &#039;&#039;CMakeLists.txt&#039;&#039; using the function &#039;&#039;pico_btstack_make_gatt_header()&#039;&#039;. The generated C header contains the GATT table as an array of hex-coded bytes, laid out one line per attribute, with comments between the lines for orientation. Application code that needs to access the GATT table data then simply &amp;quot;#include&amp;quot;s this generated header file.&lt;br /&gt;
&lt;br /&gt;
When defining the GATT table in BTstack&#039;s text format, we can use the following keywords for the attribute permissions of a characteristic:&lt;br /&gt;
* READ&lt;br /&gt;
* WRITE&lt;br /&gt;
* WRITE_WITH_RESPONSE&lt;br /&gt;
* NOTIFY: Adds a &#039;&#039;Client Configuration&#039;&#039; descriptor to the characteristic that allows a GATT client to control whether a notification is to be sent to the client each time the value of the characteristic changes.&lt;br /&gt;
* DYNAMIC: Indicates that reading and writing to this characteristic requires adding this case to the read and write callbacks.&lt;br /&gt;
&lt;br /&gt;
We expect the BTstack Python script to generate GATT profile data as described on the page [[GATT Profile Data in Bluetooth Low Energy]]. However, the script leaves out the Client Characteristic Configuration attribute when the declaration of the characteristic in the BTstack &#039;&#039;.gatt&#039;&#039; file does not include a NOTIFY or INDICATE keyword in the permissions section. It also generates GATT profile data incompatible with most popular BLE scanner applications &#039;&#039;&#039;when combining WRITE_WITHOUT_RESPONSE with NOTIFY&#039;&#039;&#039;.  Therefore, &#039;&#039;&#039;manual tweaking of the generated GATT profile data may be needed if the output of the script does not satisfy our needs.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==== The BTstack runloop ====&lt;br /&gt;
&lt;br /&gt;
The following articles by Hunter Adams offer a detailed analysis of how BTstack works on the Pico:&lt;br /&gt;
# [https://vanhunteradams.com/Pico/BLE/BTStack_HCI.html BTstack and RP2040: HCI (Host Controller Interface)].&amp;lt;br /&amp;gt;This article delves, among other things, into how the BTstack runloop is executed inside a Pico [[#Async_Context | async_context]].&amp;lt;br /&amp;gt;&amp;lt;blockquote&amp;gt;[...] we have just one &#039;&#039;when_pending_worker&#039;&#039; in our async_context. This worker is called &#039;&#039;cyw43_poll_worker&#039;&#039;, and its &#039;&#039;do_work&#039;&#039; function points to &#039;&#039;cyw43_poll_func()&#039;&#039;, listed above. This function ends up calling &#039;&#039;btstack_run_loop_poll_data_sources_from_irq()&#039;&#039;, about which we&#039;ll learn more shortly. This worker gets marked as pending in a GPIO interrupt. So, this provides a mechanism by which the CYW43 can tell the RP2040 to run &#039;&#039;btstack_run_loop_poll_data_sources_from_irq()&#039;&#039; which, as we&#039;re going to learn, goes and gets data from the device.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
# [https://vanhunteradams.com/Pico/BLE/GATT_Server.html Building a Bluetooth GATT Server on the Pi Pico W]&lt;br /&gt;
&lt;br /&gt;
==== GATT Characteristic read and write operations ====&lt;br /&gt;
&lt;br /&gt;
The struct &amp;lt;code&amp;gt;att_service_handler_t&amp;lt;/code&amp;gt; represents a GATT service. After the fields of the struct have been filled in by the application code, it holds all the information needed for the BLE peripheral to make it available to the BLE central. Some of the fields of the struct hold the ATT handles that define the start and end of the collection of characteristics belonging to the service. Other fields of the struct (&amp;lt;code&amp;gt;read_callback&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;write_callback&amp;lt;/code&amp;gt;) hold pointers to functions that handle reading from and writing to characteristic values.&lt;br /&gt;
&lt;br /&gt;
Note that the &#039;&#039;read&#039;&#039; callback for a descriptor of a GATT characteristic (i.e., an ATT attribute) is called twice. In the first call, the buffer pointer passed to the callback function is NULL. In the second call, it&#039;s a valid pointer. The first call is made by BTstack to query the size of the data that will be returned by the second call. BTstack needs to make sure its transmission buffers can hold the amount of data before making the second call.&lt;br /&gt;
&lt;br /&gt;
At the end of a writing operation, if the characteristic was configured to send back notifications to the BLE peer, one more callback function comes into play. It is part of another struct, &amp;lt;code&amp;gt;btstack_context_callback_registration_t&amp;lt;/code&amp;gt;, that is used for the deferred sending of characteristic update notification to the BLE central. In this callback, &amp;lt;code&amp;gt;att_server_notify()&amp;lt;/code&amp;gt; is called to finally send the write notification to the peer.&lt;/div&gt;</summary>
		<author><name>Kai</name></author>
	</entry>
	<entry>
		<id>https://Robo.Fish/wiki/index.php?title=GATT_Profile_Data_in_Bluetooth_Low_Energy&amp;diff=3290</id>
		<title>GATT Profile Data in Bluetooth Low Energy</title>
		<link rel="alternate" type="text/html" href="https://Robo.Fish/wiki/index.php?title=GATT_Profile_Data_in_Bluetooth_Low_Energy&amp;diff=3290"/>
		<updated>2025-05-09T23:05:15Z</updated>

		<summary type="html">&lt;p&gt;Kai: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This article explains the binary structure of the GATT attributes data array that many Bluetooth Low Energy application frameworks, like BTstack, expect as setup input.&lt;br /&gt;
&lt;br /&gt;
== GATT characteristic declaration attribute ==&lt;br /&gt;
&lt;br /&gt;
Let&#039;s have a look at an ATT attribute that declares a GATT characteristic. Here is the binary sequence (in hex representation) generated for an attribute that declares a GATT characteristic with attribute UUID &#039;&#039;B0B0F155-B0B0-B0B0-B0B0-B0B000000101&#039;&#039; and permissions &#039;&#039;READ | DYNAMIC&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0x1b, 0x00, 0x02, 0x00, 0x08, 0x00, 0x03, 0x28, 0x02, 0x09, 0x00, 0x01, 0x01, 0x00, 0x00, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0x55, 0xf1, 0xb0, 0xb0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The bytes are grouped from left to right according to this scheme:&lt;br /&gt;
* 2 bytes for the length of this attribute definition: 0x001b (= 27 bytes)&lt;br /&gt;
* 2 bytes for the access permission of this attribute: 0x0002 (= read-only)&lt;br /&gt;
* 2 bytes for the attribute handle: 0x0008&lt;br /&gt;
* 2 bytes for the attribute type: 0x2803 (short 16-bit UUID that indicates a characteristic declaration)&lt;br /&gt;
* 1 byte for the access permissions of the declared characteristic: 0x02 (= read-only)&lt;br /&gt;
* 2 bytes for the attribute handle of the characteristic value: 0x0009&lt;br /&gt;
* 16 bytes for the 128-bit UUID of the characteristic: 0xb0b0f155b0b0b0b0b0b0b0b000000101&lt;br /&gt;
where &#039;&#039;&#039;the bytes in each group are in reverse order&#039;&#039;&#039;!&lt;br /&gt;
&lt;br /&gt;
For the official specification of the Bluetooth 5.4 GATT characteristic declaration refer to section 3.3.1 in the [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html in the Bluetooth 5.4 Core Specification]. That section also lists the characteristics permissions (or properties):&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin:auto&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Properties !! Value !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Broadcast || 0x01 || If set, permits broadcasts of the Characteristic Value using Server Characteristic Configuration Descriptor. If set, the Server Characteristic Configuration Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
| Read || 0x02 || If set, permits reads of the Characteristic Value using procedures defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-66cf484d-50cd-199f-dd0d-d0d02ad02ce0 Section 4.8]&lt;br /&gt;
|-&lt;br /&gt;
| Write Without Response || 0x04 || If set, permit writes of the Characteristic Value without response using procedures defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-9f1c2e38-8fbe-f60c-d885-076707c88a43 Section 4.9.1].&lt;br /&gt;
|-&lt;br /&gt;
| Write || 0x08 || If set, permits writes of the Characteristic Value with response using procedures defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-ba4b856a-6994-01e4-97f6-357f9be40990 Section 4.9.3] or [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-6ab738ad-6d26-1da1-7417-e83da50e90c5 Section 4.9.4].&lt;br /&gt;
|-&lt;br /&gt;
| Notify || 0x10 || If set, permits notifications of a Characteristic Value without acknowledgment using the procedure defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-74673cc2-e704-a2fa-14bb-d175c27193ab Section 4.10]. If set, the Client Characteristic Configuration Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
| Indicate || 0x20 || If set, permits indications of a Characteristic Value with acknowledgment using the procedure defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-615ed0ff-f42b-827d-6427-6474fc21737c Section 4.11]. If set, the Client Characteristic Configuration Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
| Authenticated Signed Writes || 0x40 || If set, permits signed writes to the Characteristic Value using the procedure defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-516bd731-2079-87f9-8002-c3ca92fbed4b Section 4.9.2].&lt;br /&gt;
|-&lt;br /&gt;
| Extended Properties || 0x80 || If set, additional characteristic properties are defined in the Characteristic Extended Properties Descriptor defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-9154505c-6e2d-a35a-3f30-1da0383a2425 Section 3.3.3.1]. If set, the Characteristic Extended Properties Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== GATT characteristic value attribute ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0x16, 0x00, 0x02, 0x03, 0x09, 0x00, 0x01, 0x01, 0x00, 0x00, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0x55, 0xf1, 0xb0, 0xb0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The bytes are grouped from left to right as follows:&lt;br /&gt;
* 2 bytes for the length of the attribute: 0x0016 (= 22 bytes)&lt;br /&gt;
* 2 bytes for the permissions (properties) of the attribute: 0x0302 (= read-only, dynamic, 128-bit UUID)&lt;br /&gt;
* 2 bytes for the handle of the attribute: 0x0009&lt;br /&gt;
* 16 bytes for the UUID of the characteristic that the value is associated with: 0xb0b0f155b0b0b0b0b0b0b0b000000101 &lt;br /&gt;
&lt;br /&gt;
== GATT characteristic client configuration attribute ==&lt;br /&gt;
&lt;br /&gt;
The client configuration attribute (descriptor) of a GATT characteristic allows the GATT client to change the notify (or indicate) behavior for value write operations.&lt;br /&gt;
&lt;br /&gt;
== GATT characteristic user description attribute ==&lt;br /&gt;
&lt;br /&gt;
Here is an example binary sequence for a GATT user description attribute.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0x08, 0x00, 0x0a, 0x01, 0x0a, 0x00, 0x01, 0x29&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let&#039;s break down the byte grouping from left to right:&lt;br /&gt;
* 2 bytes for the length of this attribute: 0x0008 (= 8 bytes)&lt;br /&gt;
* 2 bytes for permissions: 0x010a (= read, write, dynamic)&lt;br /&gt;
* 2 bytes for the handle of this attribute&lt;br /&gt;
* 2 bytes for the 16-bit short UUID that indicates a user description attribute: 0x2901&lt;br /&gt;
where the order of the bytes in each group needs to be reversed before analyzing.&lt;br /&gt;
&lt;br /&gt;
The attribute declaration does not include the user description text itself. User description text is always &amp;quot;dynamic&amp;quot;, meaning that it is served to the client on demand on the basis of the attribute handle. In BTstack, the implementation of the read callback is responsible for returning the UTF-8 bytes for the text string corresponding the attribute handle.&lt;/div&gt;</summary>
		<author><name>Kai</name></author>
	</entry>
	<entry>
		<id>https://Robo.Fish/wiki/index.php?title=GATT_Profile_Data_in_Bluetooth_Low_Energy&amp;diff=3289</id>
		<title>GATT Profile Data in Bluetooth Low Energy</title>
		<link rel="alternate" type="text/html" href="https://Robo.Fish/wiki/index.php?title=GATT_Profile_Data_in_Bluetooth_Low_Energy&amp;diff=3289"/>
		<updated>2025-05-09T22:47:43Z</updated>

		<summary type="html">&lt;p&gt;Kai: /* GATT Profile Data */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This article explains the binary structure of the GATT attributes data array that many Bluetooth Low Energy application frameworks, like BTstack, expect as setup input.&lt;br /&gt;
&lt;br /&gt;
== GATT characteristic declaration attribute ==&lt;br /&gt;
&lt;br /&gt;
Let&#039;s have a look at an ATT attribute that declares a GATT characteristic. Here is the binary sequence (in hex representation) generated for an attribute that declares a GATT characteristic with attribute UUID &#039;&#039;B0B0F155-B0B0-B0B0-B0B0-B0B000000101&#039;&#039; and permissions &#039;&#039;READ | DYNAMIC&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0x1b, 0x00, 0x02, 0x00, 0x08, 0x00, 0x03, 0x28, 0x02, 0x09, 0x00, 0x01, 0x01, 0x00, 0x00, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0x55, 0xf1, 0xb0, 0xb0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The bytes are grouped from left to right according to this scheme:&lt;br /&gt;
* 2 bytes for the length of this attribute definition: 0x001b (= 27 bytes)&lt;br /&gt;
* 2 bytes for the access permission of this attribute: 0x0002 (= read-only)&lt;br /&gt;
* 2 bytes for the attribute handle: 0x0008&lt;br /&gt;
* 2 bytes for the attribute type: 0x2803 (short 16-bit UUID that indicates a characteristic declaration)&lt;br /&gt;
* 1 byte for the access permissions of the declared characteristic: 0x02 (= read-only)&lt;br /&gt;
* 2 bytes for the attribute handle of the characteristic value: 0x0009&lt;br /&gt;
* 16 bytes for the 128-bit UUID of the characteristic: 0xb0b0f155b0b0b0b0b0b0b0b000000101&lt;br /&gt;
where &#039;&#039;&#039;the bytes in each group are in reverse order&#039;&#039;&#039;!&lt;br /&gt;
&lt;br /&gt;
For the official specification of the Bluetooth 5.4 GATT characteristic declaration refer to section 3.3.1 in the [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html in the Bluetooth 5.4 Core Specification]. That section also lists the characteristics permissions (or properties):&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin:auto&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Properties !! Value !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Broadcast || 0x01 || If set, permits broadcasts of the Characteristic Value using Server Characteristic Configuration Descriptor. If set, the Server Characteristic Configuration Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
| Read || 0x02 || If set, permits reads of the Characteristic Value using procedures defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-66cf484d-50cd-199f-dd0d-d0d02ad02ce0 Section 4.8]&lt;br /&gt;
|-&lt;br /&gt;
| Write Without Response || 0x04 || If set, permit writes of the Characteristic Value without response using procedures defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-9f1c2e38-8fbe-f60c-d885-076707c88a43 Section 4.9.1].&lt;br /&gt;
|-&lt;br /&gt;
| Write || 0x08 || If set, permits writes of the Characteristic Value with response using procedures defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-ba4b856a-6994-01e4-97f6-357f9be40990 Section 4.9.3] or [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-6ab738ad-6d26-1da1-7417-e83da50e90c5 Section 4.9.4].&lt;br /&gt;
|-&lt;br /&gt;
| Notify || 0x10 || If set, permits notifications of a Characteristic Value without acknowledgment using the procedure defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-74673cc2-e704-a2fa-14bb-d175c27193ab Section 4.10]. If set, the Client Characteristic Configuration Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
| Indicate || 0x20 || If set, permits indications of a Characteristic Value with acknowledgment using the procedure defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-615ed0ff-f42b-827d-6427-6474fc21737c Section 4.11]. If set, the Client Characteristic Configuration Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
| Authenticated Signed Writes || 0x40 || If set, permits signed writes to the Characteristic Value using the procedure defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-516bd731-2079-87f9-8002-c3ca92fbed4b Section 4.9.2].&lt;br /&gt;
|-&lt;br /&gt;
| Extended Properties || 0x80 || If set, additional characteristic properties are defined in the Characteristic Extended Properties Descriptor defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-9154505c-6e2d-a35a-3f30-1da0383a2425 Section 3.3.3.1]. If set, the Characteristic Extended Properties Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== GATT characteristic value attribute ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0x16, 0x00, 0x02, 0x03, 0x09, 0x00, 0x01, 0x01, 0x00, 0x00, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0x55, 0xf1, 0xb0, 0xb0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The bytes are grouped from left to right as follows:&lt;br /&gt;
* 2 bytes for the length of the attribute: 0x0016 (= 22 bytes)&lt;br /&gt;
* 2 bytes for the permissions (properties) of the attribute: 0x0302 (= read-only, dynamic, 128-bit UUID)&lt;br /&gt;
* 2 bytes for the handle of the attribute: 0x0009&lt;br /&gt;
* 16 bytes for the UUID of the characteristic that the value is associated with: 0xb0b0f155b0b0b0b0b0b0b0b000000101 &lt;br /&gt;
&lt;br /&gt;
== GATT characteristic user description attribute ==&lt;br /&gt;
&lt;br /&gt;
Here is an example binary sequence for a GATT user description attribute.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0x08, 0x00, 0x0a, 0x01, 0x0a, 0x00, 0x01, 0x29&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let&#039;s break down the byte grouping from left to right:&lt;br /&gt;
* 2 bytes for the length of this attribute: 0x0008 (= 8 bytes)&lt;br /&gt;
* 2 bytes for permissions: 0x010a (= read, write, dynamic)&lt;br /&gt;
* 2 bytes for the handle of this attribute&lt;br /&gt;
* 2 bytes for the 16-bit short UUID that indicates a user description attribute: 0x2901&lt;br /&gt;
where the order of the bytes in each group needs to be reversed before analyzing.&lt;br /&gt;
&lt;br /&gt;
The attribute declaration does not include the user description text itself. User description text is always &amp;quot;dynamic&amp;quot;, meaning that it is served to the client on demand on the basis of the attribute handle. In BTstack, the implementation of the read callback is responsible for returning the UTF-8 bytes for the text string corresponding the attribute handle.&lt;/div&gt;</summary>
		<author><name>Kai</name></author>
	</entry>
	<entry>
		<id>https://Robo.Fish/wiki/index.php?title=GATT_Profile_Data_in_Bluetooth_Low_Energy&amp;diff=3288</id>
		<title>GATT Profile Data in Bluetooth Low Energy</title>
		<link rel="alternate" type="text/html" href="https://Robo.Fish/wiki/index.php?title=GATT_Profile_Data_in_Bluetooth_Low_Energy&amp;diff=3288"/>
		<updated>2025-05-09T22:47:12Z</updated>

		<summary type="html">&lt;p&gt;Kai: Created page with &amp;quot;= GATT Profile Data =  This article explains the binary structure of the GATT attributes data array that many Bluetooth Low Energy application frameworks, like BTstack, expect as setup input.  == GATT characteristic declaration attribute ==  Let&amp;#039;s have a look at an ATT attribute that declares a GATT characteristic. Here is the binary sequence (in hex representation) generated for an attribute that declares a GATT characteristic with attribute UUID &amp;#039;&amp;#039;B0B0F155-B0B0-B0B0-B0...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= GATT Profile Data =&lt;br /&gt;
&lt;br /&gt;
This article explains the binary structure of the GATT attributes data array that many Bluetooth Low Energy application frameworks, like BTstack, expect as setup input.&lt;br /&gt;
&lt;br /&gt;
== GATT characteristic declaration attribute ==&lt;br /&gt;
&lt;br /&gt;
Let&#039;s have a look at an ATT attribute that declares a GATT characteristic. Here is the binary sequence (in hex representation) generated for an attribute that declares a GATT characteristic with attribute UUID &#039;&#039;B0B0F155-B0B0-B0B0-B0B0-B0B000000101&#039;&#039; and permissions &#039;&#039;READ | DYNAMIC&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0x1b, 0x00, 0x02, 0x00, 0x08, 0x00, 0x03, 0x28, 0x02, 0x09, 0x00, 0x01, 0x01, 0x00, 0x00, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0x55, 0xf1, 0xb0, 0xb0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The bytes are grouped from left to right according to this scheme:&lt;br /&gt;
* 2 bytes for the length of this attribute definition: 0x001b (= 27 bytes)&lt;br /&gt;
* 2 bytes for the access permission of this attribute: 0x0002 (= read-only)&lt;br /&gt;
* 2 bytes for the attribute handle: 0x0008&lt;br /&gt;
* 2 bytes for the attribute type: 0x2803 (short 16-bit UUID that indicates a characteristic declaration)&lt;br /&gt;
* 1 byte for the access permissions of the declared characteristic: 0x02 (= read-only)&lt;br /&gt;
* 2 bytes for the attribute handle of the characteristic value: 0x0009&lt;br /&gt;
* 16 bytes for the 128-bit UUID of the characteristic: 0xb0b0f155b0b0b0b0b0b0b0b000000101&lt;br /&gt;
where &#039;&#039;&#039;the bytes in each group are in reverse order&#039;&#039;&#039;!&lt;br /&gt;
&lt;br /&gt;
For the official specification of the Bluetooth 5.4 GATT characteristic declaration refer to section 3.3.1 in the [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html in the Bluetooth 5.4 Core Specification]. That section also lists the characteristics permissions (or properties):&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin:auto&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Properties !! Value !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Broadcast || 0x01 || If set, permits broadcasts of the Characteristic Value using Server Characteristic Configuration Descriptor. If set, the Server Characteristic Configuration Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
| Read || 0x02 || If set, permits reads of the Characteristic Value using procedures defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-66cf484d-50cd-199f-dd0d-d0d02ad02ce0 Section 4.8]&lt;br /&gt;
|-&lt;br /&gt;
| Write Without Response || 0x04 || If set, permit writes of the Characteristic Value without response using procedures defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-9f1c2e38-8fbe-f60c-d885-076707c88a43 Section 4.9.1].&lt;br /&gt;
|-&lt;br /&gt;
| Write || 0x08 || If set, permits writes of the Characteristic Value with response using procedures defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-ba4b856a-6994-01e4-97f6-357f9be40990 Section 4.9.3] or [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-6ab738ad-6d26-1da1-7417-e83da50e90c5 Section 4.9.4].&lt;br /&gt;
|-&lt;br /&gt;
| Notify || 0x10 || If set, permits notifications of a Characteristic Value without acknowledgment using the procedure defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-74673cc2-e704-a2fa-14bb-d175c27193ab Section 4.10]. If set, the Client Characteristic Configuration Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
| Indicate || 0x20 || If set, permits indications of a Characteristic Value with acknowledgment using the procedure defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-615ed0ff-f42b-827d-6427-6474fc21737c Section 4.11]. If set, the Client Characteristic Configuration Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
| Authenticated Signed Writes || 0x40 || If set, permits signed writes to the Characteristic Value using the procedure defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-516bd731-2079-87f9-8002-c3ca92fbed4b Section 4.9.2].&lt;br /&gt;
|-&lt;br /&gt;
| Extended Properties || 0x80 || If set, additional characteristic properties are defined in the Characteristic Extended Properties Descriptor defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-9154505c-6e2d-a35a-3f30-1da0383a2425 Section 3.3.3.1]. If set, the Characteristic Extended Properties Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== GATT characteristic value attribute ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0x16, 0x00, 0x02, 0x03, 0x09, 0x00, 0x01, 0x01, 0x00, 0x00, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0x55, 0xf1, 0xb0, 0xb0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The bytes are grouped from left to right as follows:&lt;br /&gt;
* 2 bytes for the length of the attribute: 0x0016 (= 22 bytes)&lt;br /&gt;
* 2 bytes for the permissions (properties) of the attribute: 0x0302 (= read-only, dynamic, 128-bit UUID)&lt;br /&gt;
* 2 bytes for the handle of the attribute: 0x0009&lt;br /&gt;
* 16 bytes for the UUID of the characteristic that the value is associated with: 0xb0b0f155b0b0b0b0b0b0b0b000000101 &lt;br /&gt;
&lt;br /&gt;
== GATT characteristic user description attribute ==&lt;br /&gt;
&lt;br /&gt;
Here is an example binary sequence for a GATT user description attribute.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0x08, 0x00, 0x0a, 0x01, 0x0a, 0x00, 0x01, 0x29&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let&#039;s break down the byte grouping from left to right:&lt;br /&gt;
* 2 bytes for the length of this attribute: 0x0008 (= 8 bytes)&lt;br /&gt;
* 2 bytes for permissions: 0x010a (= read, write, dynamic)&lt;br /&gt;
* 2 bytes for the handle of this attribute&lt;br /&gt;
* 2 bytes for the 16-bit short UUID that indicates a user description attribute: 0x2901&lt;br /&gt;
where the order of the bytes in each group needs to be reversed before analyzing.&lt;br /&gt;
&lt;br /&gt;
The attribute declaration does not include the user description text itself. User description text is always &amp;quot;dynamic&amp;quot;, meaning that it is served to the client on demand on the basis of the attribute handle. In BTstack, the implementation of the read callback is responsible for returning the UTF-8 bytes for the text string corresponding the attribute handle.&lt;/div&gt;</summary>
		<author><name>Kai</name></author>
	</entry>
	<entry>
		<id>https://Robo.Fish/wiki/index.php?title=Raspberry_Pi_Microcontrollers&amp;diff=3287</id>
		<title>Raspberry Pi Microcontrollers</title>
		<link rel="alternate" type="text/html" href="https://Robo.Fish/wiki/index.php?title=Raspberry_Pi_Microcontrollers&amp;diff=3287"/>
		<updated>2025-05-09T22:31:28Z</updated>

		<summary type="html">&lt;p&gt;Kai: /* Bluetooth with BTstack */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Pico Series =&lt;br /&gt;
* Raspberry Pi Pico and Pico W&lt;br /&gt;
** Dual [https://developer.arm.com/Processors/Cortex-M0-Plus Arm Cortex-M0+] with Armv6-M programming model, up to 133 MHz&lt;br /&gt;
* Raspberry Pi Pico 2 and Pico 2 W&lt;br /&gt;
** Dual [https://developer.arm.com/Processors/Cortex-M33 Arm Cortex-M33] with Armv8-M programming model, up to 150 MHz&lt;br /&gt;
&lt;br /&gt;
== Development Setup ==&lt;br /&gt;
&lt;br /&gt;
=== Using the Raspberry Pi Debug Probe ===&lt;br /&gt;
The Debug Probe is a RP2040 based USB-to-UART/SWD board for connecting the USB slot of a development machine to the SWD or UART pins of a target device.&lt;br /&gt;
&lt;br /&gt;
=== Using A Pico To Debug Another Pico ===&lt;br /&gt;
A Pico can be used to debug another Pico (a.k.a. target device)  by flashing it with the [https://github.com/raspberrypi/debugprobe debugprobe] binary and wiring to the target Pico as shown below.&lt;br /&gt;
&lt;br /&gt;
[[File:Wiring_rpi_pico_as_debugger.png | x320 px | A Raspberry Pi Pico wired to debug another Pico]]&lt;br /&gt;
&lt;br /&gt;
From the debugger Pico to the target Pico,&lt;br /&gt;
* pin #4 (GP2) connects to pin SWCLK,&lt;br /&gt;
* pin #5 (GP3) connects to SWDIO,&lt;br /&gt;
* pin #6 (GP4, UART1 TX) connects to pin #2 (GP1, UART0 RX),&lt;br /&gt;
* pin #7 (GP5, UART1 RX) connects to pin #1 (GP0, UART0, TX).&lt;br /&gt;
&lt;br /&gt;
The debugger Pico serves both as a USB-to-SWD and USB-to-UART bridge to the target device. The development machine, therefore, needs to be connected via USB only to the debugger Pico. Console output on the target Pico is relayed through the debugger. It is possible, though, to connect a second USB cable from the development machine to the target device for (simultaneous) direct access to the console output. This debugger setup works not just with Pico targets but with any microcontroller that supports the CMSIS-DAP protocol over SWD.&lt;br /&gt;
&lt;br /&gt;
=== Software Tools for Debugging ===&lt;br /&gt;
Whether we use the Raspberry Pi Debug Probe or a spare Pico as debug probe, the software tools used for debugging are the same:&lt;br /&gt;
* openocd&lt;br /&gt;
&lt;br /&gt;
== Notes on Programming with the C SDK ==&lt;br /&gt;
&lt;br /&gt;
=== Async Context ===&lt;br /&gt;
In the C SDK, an [https://www.raspberrypi.com/documentation/pico-sdk/high_level.html#group_pico_async_context async_context] is used in concurrent programming to make sure that functions are executed on the same thread and in the order they were submitted, similar to dispatch queues in Apple&#039;s [https://developer.apple.com/documentation/dispatch?language=objc Dispatch framework]. The &#039;&#039;async_context&#039;&#039; data structure is a container of linked lists of worker functions that are executed within a single thread of a single processor core.&lt;br /&gt;
&lt;br /&gt;
=== Bluetooth with BTstack ===&lt;br /&gt;
&lt;br /&gt;
The C SDK integrates the third-party [https://bluekitchen-gmbh.com/btstack BTstack] framework as its Bluetooth API that interfaces with the Infineon CYW43 wireless communication module (on Pico W models) via the Host-Controller Interface (HCI) protocol.&lt;br /&gt;
&lt;br /&gt;
==== Setup ====&lt;br /&gt;
&lt;br /&gt;
Before we can call any BTstack functions (and hope for some meaningful outcome), we need to add a &#039;&#039;&#039;btstack_config.h&#039;&#039;&#039; header file to our project. In it, we add all the compile-time switches that fit our application. On a microcontroller, a frequent use case for BTstack is to implement a BLE peripheral. For this we, our config header should look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#ifndef MY_BTSTACK_CONFIG_H&lt;br /&gt;
#define MY_BTSTACK_CONFIG_H&lt;br /&gt;
&lt;br /&gt;
#ifndef ENABLE_BLE&lt;br /&gt;
#error In CMakeLists.txt add the &#039;pico_btstack_ble&#039; library to target_link_libraries(...)&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// logging&lt;br /&gt;
#define ENABLE_LOG_INFO&lt;br /&gt;
#define ENABLE_LOG_ERROR&lt;br /&gt;
#define ENABLE_PRINTF_HEXDUMP // required for hci_dump_init()&lt;br /&gt;
&lt;br /&gt;
#if 1 // configure as peripheral (GATT server)&lt;br /&gt;
	#define ENABLE_LE_PERIPHERAL&lt;br /&gt;
	#define MAX_NR_GATT_CLIENTS 0&lt;br /&gt;
#else // configure as central (GATT client)&lt;br /&gt;
	#define ENABLE_LE_CENTRAL&lt;br /&gt;
	#define MAX_NR_GATT_CLIENTS 1&lt;br /&gt;
//#define ENABLE_GATT_CLIENT_PAIRING&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// Setting various buffer sizes related to HCI communication&lt;br /&gt;
#define HCI_OUTGOING_PRE_BUFFER_SIZE 4&lt;br /&gt;
#define HCI_ACL_PAYLOAD_SIZE (255 + 4)&lt;br /&gt;
#define HCI_ACL_CHUNK_SIZE_ALIGNMENT 4&lt;br /&gt;
#define MAX_NR_HCI_CONNECTIONS 1&lt;br /&gt;
#define MAX_NR_SM_LOOKUP_ENTRIES 3&lt;br /&gt;
#define MAX_NR_WHITELIST_ENTRIES 16&lt;br /&gt;
#define MAX_NR_LE_DEVICE_DB_ENTRIES 16&lt;br /&gt;
&lt;br /&gt;
// Choosing a fixed-size attributes table over using malloc.&lt;br /&gt;
// We want to use BTstack without heap memory allocations.&lt;br /&gt;
#if 1&lt;br /&gt;
#define MAX_ATT_DB_SIZE 512&lt;br /&gt;
#else&lt;br /&gt;
#define HAVE_MALLOC&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// Enabling timers&lt;br /&gt;
#if 1&lt;br /&gt;
#define HAVE_EMBEDDED_TIME_MS&lt;br /&gt;
#else&lt;br /&gt;
#define HAVE_EMBEDDED_TICK&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// Limiting the amount of nonvolatile (flash) memory used for storing peer bonding information&lt;br /&gt;
#define NVM_NUM_DEVICE_DB_ENTRIES 16&lt;br /&gt;
#define NVM_NUM_LINK_KEYS 16&lt;br /&gt;
&lt;br /&gt;
// Configuring HCI Controller-to-Host flow control and related buffers to avoid overrunning the cyw43 shared bus&lt;br /&gt;
#define ENABLE_HCI_CONTROLLER_TO_HOST_FLOW_CONTROL&lt;br /&gt;
#define HCI_HOST_ACL_PACKET_LEN (255+4)&lt;br /&gt;
#define HCI_HOST_ACL_PACKET_NUM 3&lt;br /&gt;
#define HCI_HOST_SCO_PACKET_LEN 120&lt;br /&gt;
#define HCI_HOST_SCO_PACKET_NUM 3&lt;br /&gt;
#define MAX_NR_CONTROLLER_SCO_PACKETS 3&lt;br /&gt;
#define MAX_NR_CONTROLLER_ACL_BUFFERS 3&lt;br /&gt;
&lt;br /&gt;
// Enabling btstack_assert, acting just like normal assert()&lt;br /&gt;
#define HAVE_ASSERT&lt;br /&gt;
&lt;br /&gt;
// Setting HCI resend timeout in case the Bluetooth module needs more time to response.&lt;br /&gt;
#define HCI_RESET_RESEND_TIMEOUT_MS 800&lt;br /&gt;
&lt;br /&gt;
// Configuring security&lt;br /&gt;
#define ENABLE_SOFTWARE_AES128&lt;br /&gt;
#define ENABLE_MICRO_ECC_FOR_LE_SECURE_CONNECTIONS&lt;br /&gt;
&lt;br /&gt;
#endif // MY_BTSTACK_CONFIG_H&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== GATT Profiles, Services, Characteristics, and Descriptors ====&lt;br /&gt;
&lt;br /&gt;
A Bluetooth Low Energy Peripheral organizes the served data in a linear attributes table or database, referred to as  ATT. The GATT (Generic Attributes) profile used in BLE is, contrary to what the name suggests, a specific organizational structure imposed on the ATT table, where the data table as a whole is referred to as &amp;quot;profile&amp;quot;. The profile attributes can be broken down into consecutive &amp;quot;service&amp;quot; attributes, the service attributes into &amp;quot;characteristic&amp;quot; attributes, the characteristics into &amp;quot;descriptor&amp;quot; attributes. So, all in all there linear ATT table becomes a tree structure with four levels in GATT. A BLE peripheral, acting as a GATT server when connected to, will advertise its profile over GAP. A BLE central, acting as a GATT client after establishing a connection to the peripheral, can read the complete GATT hierarchy to find out about the profile contents.&lt;br /&gt;
&lt;br /&gt;
BTstack allows defining a GATT table as a human-readable text file. The translation of that file into a C header by a Python script is a build step that can be included in &#039;&#039;CMakeLists.txt&#039;&#039; using the function &#039;&#039;pico_btstack_make_gatt_header()&#039;&#039;. The generated C header contains the GATT table as an array of hex-coded bytes, laid out one line per attribute, with comments between the lines for orientation. Application code that needs to access the GATT table data then simply &amp;quot;#include&amp;quot;s this generated header file.&lt;br /&gt;
&lt;br /&gt;
When defining the GATT table in BTstack&#039;s text format, we can use the following keywords for the attribute permissions of a characteristic:&lt;br /&gt;
* READ&lt;br /&gt;
* WRITE&lt;br /&gt;
* WRITE_WITH_RESPONSE&lt;br /&gt;
* NOTIFY: Adds a &#039;&#039;Client Configuration&#039;&#039; descriptor to the characteristic that allows a GATT client to control whether a notification is to be sent to the client each time the value of the characteristic changes.&lt;br /&gt;
* DYNAMIC: Indicates that reading and writing to this characteristic requires adding this case to the read and write callbacks.&lt;br /&gt;
&lt;br /&gt;
We expect the BTstack Python script to generate GATT profile data as described on the page [[GATT Profile Data in Bluetooth Low Energy]]. However, the script leaves out the Client Characteristic Configuration attribute when the declaration of the characteristic in the BTstack &#039;&#039;.gatt&#039;&#039; file does not include a NOTIFY or INDICATE keyword in the permissions section. Many popular BLE scanner applications rely on the presence of the Client Characteristic Configuration attribute, however, in order to extract the characteristic value access permissions. &#039;&#039;&#039;Manual editing of the generated GATT profile data is needed if script-generated attributes do not satisfy our needs.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==== The BTstack runloop ====&lt;br /&gt;
&lt;br /&gt;
The following articles by Hunter Adams offer a detailed analysis of how BTstack works on the Pico:&lt;br /&gt;
# [https://vanhunteradams.com/Pico/BLE/BTStack_HCI.html BTstack and RP2040: HCI (Host Controller Interface)].&amp;lt;br /&amp;gt;This article delves, among other things, into how the BTstack runloop is executed inside a Pico [[#Async_Context | async_context]].&amp;lt;br /&amp;gt;&amp;lt;blockquote&amp;gt;[...] we have just one &#039;&#039;when_pending_worker&#039;&#039; in our async_context. This worker is called &#039;&#039;cyw43_poll_worker&#039;&#039;, and its &#039;&#039;do_work&#039;&#039; function points to &#039;&#039;cyw43_poll_func()&#039;&#039;, listed above. This function ends up calling &#039;&#039;btstack_run_loop_poll_data_sources_from_irq()&#039;&#039;, about which we&#039;ll learn more shortly. This worker gets marked as pending in a GPIO interrupt. So, this provides a mechanism by which the CYW43 can tell the RP2040 to run &#039;&#039;btstack_run_loop_poll_data_sources_from_irq()&#039;&#039; which, as we&#039;re going to learn, goes and gets data from the device.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
# [https://vanhunteradams.com/Pico/BLE/GATT_Server.html Building a Bluetooth GATT Server on the Pi Pico W]&lt;br /&gt;
&lt;br /&gt;
==== GATT Characteristic read and write operations ====&lt;br /&gt;
&lt;br /&gt;
The struct &amp;lt;code&amp;gt;att_service_handler_t&amp;lt;/code&amp;gt; represents a GATT service. After the fields of the struct have been filled in by the application code, it holds all the information needed for the BLE peripheral to make it available to the BLE central. Some of the fields of the struct hold the ATT handles that define the start and end of the collection of characteristics belonging to the service. Other fields of the struct (&amp;lt;code&amp;gt;read_callback&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;write_callback&amp;lt;/code&amp;gt;) hold pointers to functions that handle reading from and writing to characteristic values.&lt;br /&gt;
&lt;br /&gt;
Note that the &#039;&#039;read&#039;&#039; callback for a descriptor of a GATT characteristic (i.e., an ATT attribute) is called twice. In the first call, the buffer pointer passed to the callback function is NULL. In the second call, it&#039;s a valid pointer. The first call is made by BTstack to query the size of the data that will be returned by the second call. BTstack needs to make sure its transmission buffers can hold the amount of data before making the second call.&lt;br /&gt;
&lt;br /&gt;
At the end of a writing operation, if the characteristic was configured to send back notifications to the BLE peer, one more callback function comes into play. It is part of another struct, &amp;lt;code&amp;gt;btstack_context_callback_registration_t&amp;lt;/code&amp;gt;, that is used for the deferred sending of characteristic update notification to the BLE central. In this callback, &amp;lt;code&amp;gt;att_server_notify()&amp;lt;/code&amp;gt; is called to finally send the write notification to the peer.&lt;/div&gt;</summary>
		<author><name>Kai</name></author>
	</entry>
	<entry>
		<id>https://Robo.Fish/wiki/index.php?title=Raspberry_Pi_Microcontrollers&amp;diff=3286</id>
		<title>Raspberry Pi Microcontrollers</title>
		<link rel="alternate" type="text/html" href="https://Robo.Fish/wiki/index.php?title=Raspberry_Pi_Microcontrollers&amp;diff=3286"/>
		<updated>2025-05-09T22:12:43Z</updated>

		<summary type="html">&lt;p&gt;Kai: Adds description of the binary sequence of a GATT attribute for a characteristic value&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Pico Series =&lt;br /&gt;
* Raspberry Pi Pico and Pico W&lt;br /&gt;
** Dual [https://developer.arm.com/Processors/Cortex-M0-Plus Arm Cortex-M0+] with Armv6-M programming model, up to 133 MHz&lt;br /&gt;
* Raspberry Pi Pico 2 and Pico 2 W&lt;br /&gt;
** Dual [https://developer.arm.com/Processors/Cortex-M33 Arm Cortex-M33] with Armv8-M programming model, up to 150 MHz&lt;br /&gt;
&lt;br /&gt;
== Development Setup ==&lt;br /&gt;
&lt;br /&gt;
=== Using the Raspberry Pi Debug Probe ===&lt;br /&gt;
The Debug Probe is a RP2040 based USB-to-UART/SWD board for connecting the USB slot of a development machine to the SWD or UART pins of a target device.&lt;br /&gt;
&lt;br /&gt;
=== Using A Pico To Debug Another Pico ===&lt;br /&gt;
A Pico can be used to debug another Pico (a.k.a. target device)  by flashing it with the [https://github.com/raspberrypi/debugprobe debugprobe] binary and wiring to the target Pico as shown below.&lt;br /&gt;
&lt;br /&gt;
[[File:Wiring_rpi_pico_as_debugger.png | x320 px | A Raspberry Pi Pico wired to debug another Pico]]&lt;br /&gt;
&lt;br /&gt;
From the debugger Pico to the target Pico,&lt;br /&gt;
* pin #4 (GP2) connects to pin SWCLK,&lt;br /&gt;
* pin #5 (GP3) connects to SWDIO,&lt;br /&gt;
* pin #6 (GP4, UART1 TX) connects to pin #2 (GP1, UART0 RX),&lt;br /&gt;
* pin #7 (GP5, UART1 RX) connects to pin #1 (GP0, UART0, TX).&lt;br /&gt;
&lt;br /&gt;
The debugger Pico serves both as a USB-to-SWD and USB-to-UART bridge to the target device. The development machine, therefore, needs to be connected via USB only to the debugger Pico. Console output on the target Pico is relayed through the debugger. It is possible, though, to connect a second USB cable from the development machine to the target device for (simultaneous) direct access to the console output. This debugger setup works not just with Pico targets but with any microcontroller that supports the CMSIS-DAP protocol over SWD.&lt;br /&gt;
&lt;br /&gt;
=== Software Tools for Debugging ===&lt;br /&gt;
Whether we use the Raspberry Pi Debug Probe or a spare Pico as debug probe, the software tools used for debugging are the same:&lt;br /&gt;
* openocd&lt;br /&gt;
&lt;br /&gt;
== Notes on Programming with the C SDK ==&lt;br /&gt;
&lt;br /&gt;
=== Async Context ===&lt;br /&gt;
In the C SDK, an [https://www.raspberrypi.com/documentation/pico-sdk/high_level.html#group_pico_async_context async_context] is used in concurrent programming to make sure that functions are executed on the same thread and in the order they were submitted, similar to dispatch queues in Apple&#039;s [https://developer.apple.com/documentation/dispatch?language=objc Dispatch framework]. The &#039;&#039;async_context&#039;&#039; data structure is a container of linked lists of worker functions that are executed within a single thread of a single processor core.&lt;br /&gt;
&lt;br /&gt;
=== Bluetooth with BTstack ===&lt;br /&gt;
&lt;br /&gt;
The C SDK integrates the third-party [https://bluekitchen-gmbh.com/btstack BTstack] framework as its Bluetooth API that interfaces with the Infineon CYW43 wireless communication module (on Pico W models) via the Host-Controller Interface (HCI) protocol.&lt;br /&gt;
&lt;br /&gt;
==== Setup ====&lt;br /&gt;
&lt;br /&gt;
Before we can call any BTstack functions (and hope for some meaningful outcome), we need to add a &#039;&#039;&#039;btstack_config.h&#039;&#039;&#039; header file to our project. In it, we add all the compile-time switches that fit our application. On a microcontroller, a frequent use case for BTstack is to implement a BLE peripheral. For this we, our config header should look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#ifndef MY_BTSTACK_CONFIG_H&lt;br /&gt;
#define MY_BTSTACK_CONFIG_H&lt;br /&gt;
&lt;br /&gt;
#ifndef ENABLE_BLE&lt;br /&gt;
#error In CMakeLists.txt add the &#039;pico_btstack_ble&#039; library to target_link_libraries(...)&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// logging&lt;br /&gt;
#define ENABLE_LOG_INFO&lt;br /&gt;
#define ENABLE_LOG_ERROR&lt;br /&gt;
#define ENABLE_PRINTF_HEXDUMP // required for hci_dump_init()&lt;br /&gt;
&lt;br /&gt;
#if 1 // configure as peripheral (GATT server)&lt;br /&gt;
	#define ENABLE_LE_PERIPHERAL&lt;br /&gt;
	#define MAX_NR_GATT_CLIENTS 0&lt;br /&gt;
#else // configure as central (GATT client)&lt;br /&gt;
	#define ENABLE_LE_CENTRAL&lt;br /&gt;
	#define MAX_NR_GATT_CLIENTS 1&lt;br /&gt;
//#define ENABLE_GATT_CLIENT_PAIRING&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// Setting various buffer sizes related to HCI communication&lt;br /&gt;
#define HCI_OUTGOING_PRE_BUFFER_SIZE 4&lt;br /&gt;
#define HCI_ACL_PAYLOAD_SIZE (255 + 4)&lt;br /&gt;
#define HCI_ACL_CHUNK_SIZE_ALIGNMENT 4&lt;br /&gt;
#define MAX_NR_HCI_CONNECTIONS 1&lt;br /&gt;
#define MAX_NR_SM_LOOKUP_ENTRIES 3&lt;br /&gt;
#define MAX_NR_WHITELIST_ENTRIES 16&lt;br /&gt;
#define MAX_NR_LE_DEVICE_DB_ENTRIES 16&lt;br /&gt;
&lt;br /&gt;
// Choosing a fixed-size attributes table over using malloc.&lt;br /&gt;
// We want to use BTstack without heap memory allocations.&lt;br /&gt;
#if 1&lt;br /&gt;
#define MAX_ATT_DB_SIZE 512&lt;br /&gt;
#else&lt;br /&gt;
#define HAVE_MALLOC&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// Enabling timers&lt;br /&gt;
#if 1&lt;br /&gt;
#define HAVE_EMBEDDED_TIME_MS&lt;br /&gt;
#else&lt;br /&gt;
#define HAVE_EMBEDDED_TICK&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// Limiting the amount of nonvolatile (flash) memory used for storing peer bonding information&lt;br /&gt;
#define NVM_NUM_DEVICE_DB_ENTRIES 16&lt;br /&gt;
#define NVM_NUM_LINK_KEYS 16&lt;br /&gt;
&lt;br /&gt;
// Configuring HCI Controller-to-Host flow control and related buffers to avoid overrunning the cyw43 shared bus&lt;br /&gt;
#define ENABLE_HCI_CONTROLLER_TO_HOST_FLOW_CONTROL&lt;br /&gt;
#define HCI_HOST_ACL_PACKET_LEN (255+4)&lt;br /&gt;
#define HCI_HOST_ACL_PACKET_NUM 3&lt;br /&gt;
#define HCI_HOST_SCO_PACKET_LEN 120&lt;br /&gt;
#define HCI_HOST_SCO_PACKET_NUM 3&lt;br /&gt;
#define MAX_NR_CONTROLLER_SCO_PACKETS 3&lt;br /&gt;
#define MAX_NR_CONTROLLER_ACL_BUFFERS 3&lt;br /&gt;
&lt;br /&gt;
// Enabling btstack_assert, acting just like normal assert()&lt;br /&gt;
#define HAVE_ASSERT&lt;br /&gt;
&lt;br /&gt;
// Setting HCI resend timeout in case the Bluetooth module needs more time to response.&lt;br /&gt;
#define HCI_RESET_RESEND_TIMEOUT_MS 800&lt;br /&gt;
&lt;br /&gt;
// Configuring security&lt;br /&gt;
#define ENABLE_SOFTWARE_AES128&lt;br /&gt;
#define ENABLE_MICRO_ECC_FOR_LE_SECURE_CONNECTIONS&lt;br /&gt;
&lt;br /&gt;
#endif // MY_BTSTACK_CONFIG_H&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== GATT Profiles, Services, Characteristics, and Descriptors ====&lt;br /&gt;
&lt;br /&gt;
A Bluetooth Low Energy Peripheral organizes the served data in a linear attributes table or database, referred to as  ATT. The GATT (Generic Attributes) profile used in BLE is, contrary to what the name suggests, a specific organizational structure imposed on the ATT table, where the data table as a whole is referred to as &amp;quot;profile&amp;quot;. The profile attributes can be broken down into consecutive &amp;quot;service&amp;quot; attributes, the service attributes into &amp;quot;characteristic&amp;quot; attributes, the characteristics into &amp;quot;descriptor&amp;quot; attributes. So, all in all there linear ATT table becomes a tree structure with four levels in GATT. A BLE peripheral, acting as a GATT server when connected to, will advertise its profile over GAP. A BLE central, acting as a GATT client after establishing a connection to the peripheral, can read the complete GATT hierarchy to find out about the profile contents.&lt;br /&gt;
&lt;br /&gt;
BTstack allows defining a GATT table as a human-readable text file. The translation of that file into a C header by a Python script is a build step that can be included in &#039;&#039;CMakeLists.txt&#039;&#039; using the function &#039;&#039;pico_btstack_make_gatt_header()&#039;&#039;. The generated C header contains the GATT table as an array of hex-coded bytes, laid out one line per attribute, with comments between the lines for orientation. Application code that needs to access the GATT table data then simply &amp;quot;#include&amp;quot;s this generated header file.&lt;br /&gt;
&lt;br /&gt;
When defining the GATT table in BTstack&#039;s text format, we can use the following keywords for the attribute permissions of a characteristic:&lt;br /&gt;
* READ&lt;br /&gt;
* WRITE&lt;br /&gt;
* WRITE_WITH_RESPONSE&lt;br /&gt;
* NOTIFY: Adds a &#039;&#039;Client Configuration&#039;&#039; descriptor to the characteristic that allows a GATT client to control whether a notification is to be sent to the client each time the value of the characteristic changes.&lt;br /&gt;
* DYNAMIC: Indicates that reading and writing to this characteristic requires adding this case to the read and write callbacks.&lt;br /&gt;
&lt;br /&gt;
===== BTStack Python script output for a GATT characteristic declaration attribute =====&lt;br /&gt;
&lt;br /&gt;
Let&#039;s have a look at the output of the BTstack Python script that converts the .gatt file to a C header and let&#039;s narrow it down to just the characteristic attributes (descriptors).&lt;br /&gt;
&lt;br /&gt;
Here is the binary sequence (in hex representation) generated for an attribute that declares a GATT characteristic with attribute UUID &#039;&#039;B0B0F155-B0B0-B0B0-B0B0-B0B000000101&#039;&#039; and permissions &#039;&#039;READ | DYNAMIC&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0x1b, 0x00, 0x02, 0x00, 0x08, 0x00, 0x03, 0x28, 0x02, 0x09, 0x00, 0x01, 0x01, 0x00, 0x00, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0x55, 0xf1, 0xb0, 0xb0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The bytes are grouped from left to right according to this scheme:&lt;br /&gt;
* 2 bytes for the length of this attribute definition: 0x001b (= 27 bytes)&lt;br /&gt;
* 2 bytes for the access permission of this attribute: 0x0002 (= read-only)&lt;br /&gt;
* 2 bytes for the attribute handle: 0x0008&lt;br /&gt;
* 2 bytes for the attribute type: 0x2803 (short 16-bit UUID that indicates a characteristic declaration)&lt;br /&gt;
* 1 byte for the access permissions of the declared characteristic: 0x02 (= read-only)&lt;br /&gt;
* 2 bytes for the attribute handle of the characteristic value: 0x0009&lt;br /&gt;
* 16 bytes for the 128-bit UUID of the characteristic: 0xb0b0f155b0b0b0b0b0b0b0b000000101&lt;br /&gt;
where &#039;&#039;&#039;the bytes in each group are in reverse order&#039;&#039;&#039;!&lt;br /&gt;
&lt;br /&gt;
For the official specification of the Bluetooth 5.4 GATT characteristic declaration refer to section 3.3.1 in the [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html in the Bluetooth 5.4 Core Specification]. That section also lists the characteristics permissions (or properties):&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin:auto&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Properties !! Value !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Broadcast || 0x01 || If set, permits broadcasts of the Characteristic Value using Server Characteristic Configuration Descriptor. If set, the Server Characteristic Configuration Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
| Read || 0x02 || If set, permits reads of the Characteristic Value using procedures defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-66cf484d-50cd-199f-dd0d-d0d02ad02ce0 Section 4.8]&lt;br /&gt;
|-&lt;br /&gt;
| Write Without Response || 0x04 || If set, permit writes of the Characteristic Value without response using procedures defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-9f1c2e38-8fbe-f60c-d885-076707c88a43 Section 4.9.1].&lt;br /&gt;
|-&lt;br /&gt;
| Write || 0x08 || If set, permits writes of the Characteristic Value with response using procedures defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-ba4b856a-6994-01e4-97f6-357f9be40990 Section 4.9.3] or [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-6ab738ad-6d26-1da1-7417-e83da50e90c5 Section 4.9.4].&lt;br /&gt;
|-&lt;br /&gt;
| Notify || 0x10 || If set, permits notifications of a Characteristic Value without acknowledgment using the procedure defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-74673cc2-e704-a2fa-14bb-d175c27193ab Section 4.10]. If set, the Client Characteristic Configuration Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
| Indicate || 0x20 || If set, permits indications of a Characteristic Value with acknowledgment using the procedure defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-615ed0ff-f42b-827d-6427-6474fc21737c Section 4.11]. If set, the Client Characteristic Configuration Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
| Authenticated Signed Writes || 0x40 || If set, permits signed writes to the Characteristic Value using the procedure defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-516bd731-2079-87f9-8002-c3ca92fbed4b Section 4.9.2].&lt;br /&gt;
|-&lt;br /&gt;
| Extended Properties || 0x80 || If set, additional characteristic properties are defined in the Characteristic Extended Properties Descriptor defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-9154505c-6e2d-a35a-3f30-1da0383a2425 Section 3.3.3.1]. If set, the Characteristic Extended Properties Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== BTStack Python script output for a GATT characteristic value attribute =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0x16, 0x00, 0x02, 0x03, 0x09, 0x00, 0x01, 0x01, 0x00, 0x00, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0x55, 0xf1, 0xb0, 0xb0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The bytes are grouped from left to right as follows:&lt;br /&gt;
* 2 bytes for the length of the attribute: 0x0016 (= 22 bytes)&lt;br /&gt;
* 2 bytes for the permissions (properties) of the attribute: 0x0302 (= read-only, dynamic, 128-bit UUID)&lt;br /&gt;
* 2 bytes for the handle of the attribute: 0x0009&lt;br /&gt;
* 16 bytes for the UUID of the characteristic that the value is associated with: 0xb0b0f155b0b0b0b0b0b0b0b000000101 &lt;br /&gt;
&lt;br /&gt;
===== BTStack Python script output for a GATT characteristic user description attribute =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0x08, 0x00, 0x0a, 0x01, 0x0a, 0x00, 0x01, 0x29&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The bytes are grouped from left to right as follows:&lt;br /&gt;
* 2 bytes for the length of this attribute: 0x0008 (= 8 bytes)&lt;br /&gt;
* 2 bytes for permissions: 0x010a (= read, write, dynamic)&lt;br /&gt;
* 2 bytes for the handle of this attribute&lt;br /&gt;
* 2 bytes for the 16-bit short UUID that indicates a user description attribute: 0x2901&lt;br /&gt;
where the order of the bytes in each group needs to be reversed before analyzing.&lt;br /&gt;
&lt;br /&gt;
The attribute declaration does not include the user description text itself. User description text is always &amp;quot;dynamic&amp;quot;, meaning that it is served to the client on demand on the basis of the attribute handle. In BTstack, the implementation of the read callback is responsible for returning the UTF-8 bytes for the text string corresponding the attribute handle.&lt;br /&gt;
&lt;br /&gt;
==== The BTstack runloop ====&lt;br /&gt;
&lt;br /&gt;
The following articles by Hunter Adams offer a detailed analysis of how BTstack works on the Pico:&lt;br /&gt;
# [https://vanhunteradams.com/Pico/BLE/BTStack_HCI.html BTstack and RP2040: HCI (Host Controller Interface)].&amp;lt;br /&amp;gt;This article delves, among other things, into how the BTstack runloop is executed inside a Pico [[#Async_Context | async_context]].&amp;lt;br /&amp;gt;&amp;lt;blockquote&amp;gt;[...] we have just one &#039;&#039;when_pending_worker&#039;&#039; in our async_context. This worker is called &#039;&#039;cyw43_poll_worker&#039;&#039;, and its &#039;&#039;do_work&#039;&#039; function points to &#039;&#039;cyw43_poll_func()&#039;&#039;, listed above. This function ends up calling &#039;&#039;btstack_run_loop_poll_data_sources_from_irq()&#039;&#039;, about which we&#039;ll learn more shortly. This worker gets marked as pending in a GPIO interrupt. So, this provides a mechanism by which the CYW43 can tell the RP2040 to run &#039;&#039;btstack_run_loop_poll_data_sources_from_irq()&#039;&#039; which, as we&#039;re going to learn, goes and gets data from the device.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
# [https://vanhunteradams.com/Pico/BLE/GATT_Server.html Building a Bluetooth GATT Server on the Pi Pico W]&lt;br /&gt;
&lt;br /&gt;
==== GATT Characteristic read and write operations ====&lt;br /&gt;
&lt;br /&gt;
The struct &amp;lt;code&amp;gt;att_service_handler_t&amp;lt;/code&amp;gt; represents a GATT service. After the fields of the struct have been filled in by the application code, it holds all the information needed for the BLE peripheral to make it available to the BLE central. Some of the fields of the struct hold the ATT handles that define the start and end of the collection of characteristics belonging to the service. Other fields of the struct (&amp;lt;code&amp;gt;read_callback&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;write_callback&amp;lt;/code&amp;gt;) hold pointers to functions that handle reading from and writing to characteristic values.&lt;br /&gt;
&lt;br /&gt;
Note that the &#039;&#039;read&#039;&#039; callback for a descriptor of a GATT characteristic (i.e., an ATT attribute) is called twice. In the first call, the buffer pointer passed to the callback function is NULL. In the second call, it&#039;s a valid pointer. The first call is made by BTstack to query the size of the data that will be returned by the second call. BTstack needs to make sure its transmission buffers can hold the amount of data before making the second call.&lt;br /&gt;
&lt;br /&gt;
At the end of a writing operation, if the characteristic was configured to send back notifications to the BLE peer, one more callback function comes into play. It is part of another struct, &amp;lt;code&amp;gt;btstack_context_callback_registration_t&amp;lt;/code&amp;gt;, that is used for the deferred sending of characteristic update notification to the BLE central. In this callback, &amp;lt;code&amp;gt;att_server_notify()&amp;lt;/code&amp;gt; is called to finally send the write notification to the peer.&lt;/div&gt;</summary>
		<author><name>Kai</name></author>
	</entry>
	<entry>
		<id>https://Robo.Fish/wiki/index.php?title=Raspberry_Pi_Microcontrollers&amp;diff=3285</id>
		<title>Raspberry Pi Microcontrollers</title>
		<link rel="alternate" type="text/html" href="https://Robo.Fish/wiki/index.php?title=Raspberry_Pi_Microcontrollers&amp;diff=3285"/>
		<updated>2025-05-09T20:49:23Z</updated>

		<summary type="html">&lt;p&gt;Kai: /* BTStack Python script output for a GATT user description declaration attribute */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Pico Series =&lt;br /&gt;
* Raspberry Pi Pico and Pico W&lt;br /&gt;
** Dual [https://developer.arm.com/Processors/Cortex-M0-Plus Arm Cortex-M0+] with Armv6-M programming model, up to 133 MHz&lt;br /&gt;
* Raspberry Pi Pico 2 and Pico 2 W&lt;br /&gt;
** Dual [https://developer.arm.com/Processors/Cortex-M33 Arm Cortex-M33] with Armv8-M programming model, up to 150 MHz&lt;br /&gt;
&lt;br /&gt;
== Development Setup ==&lt;br /&gt;
&lt;br /&gt;
=== Using the Raspberry Pi Debug Probe ===&lt;br /&gt;
The Debug Probe is a RP2040 based USB-to-UART/SWD board for connecting the USB slot of a development machine to the SWD or UART pins of a target device.&lt;br /&gt;
&lt;br /&gt;
=== Using A Pico To Debug Another Pico ===&lt;br /&gt;
A Pico can be used to debug another Pico (a.k.a. target device)  by flashing it with the [https://github.com/raspberrypi/debugprobe debugprobe] binary and wiring to the target Pico as shown below.&lt;br /&gt;
&lt;br /&gt;
[[File:Wiring_rpi_pico_as_debugger.png | x320 px | A Raspberry Pi Pico wired to debug another Pico]]&lt;br /&gt;
&lt;br /&gt;
From the debugger Pico to the target Pico,&lt;br /&gt;
* pin #4 (GP2) connects to pin SWCLK,&lt;br /&gt;
* pin #5 (GP3) connects to SWDIO,&lt;br /&gt;
* pin #6 (GP4, UART1 TX) connects to pin #2 (GP1, UART0 RX),&lt;br /&gt;
* pin #7 (GP5, UART1 RX) connects to pin #1 (GP0, UART0, TX).&lt;br /&gt;
&lt;br /&gt;
The debugger Pico serves both as a USB-to-SWD and USB-to-UART bridge to the target device. The development machine, therefore, needs to be connected via USB only to the debugger Pico. Console output on the target Pico is relayed through the debugger. It is possible, though, to connect a second USB cable from the development machine to the target device for (simultaneous) direct access to the console output. This debugger setup works not just with Pico targets but with any microcontroller that supports the CMSIS-DAP protocol over SWD.&lt;br /&gt;
&lt;br /&gt;
=== Software Tools for Debugging ===&lt;br /&gt;
Whether we use the Raspberry Pi Debug Probe or a spare Pico as debug probe, the software tools used for debugging are the same:&lt;br /&gt;
* openocd&lt;br /&gt;
&lt;br /&gt;
== Notes on Programming with the C SDK ==&lt;br /&gt;
&lt;br /&gt;
=== Async Context ===&lt;br /&gt;
In the C SDK, an [https://www.raspberrypi.com/documentation/pico-sdk/high_level.html#group_pico_async_context async_context] is used in concurrent programming to make sure that functions are executed on the same thread and in the order they were submitted, similar to dispatch queues in Apple&#039;s [https://developer.apple.com/documentation/dispatch?language=objc Dispatch framework]. The &#039;&#039;async_context&#039;&#039; data structure is a container of linked lists of worker functions that are executed within a single thread of a single processor core.&lt;br /&gt;
&lt;br /&gt;
=== Bluetooth with BTstack ===&lt;br /&gt;
&lt;br /&gt;
The C SDK integrates the third-party [https://bluekitchen-gmbh.com/btstack BTstack] framework as its Bluetooth API that interfaces with the Infineon CYW43 wireless communication module (on Pico W models) via the Host-Controller Interface (HCI) protocol.&lt;br /&gt;
&lt;br /&gt;
==== Setup ====&lt;br /&gt;
&lt;br /&gt;
Before we can call any BTstack functions (and hope for some meaningful outcome), we need to add a &#039;&#039;&#039;btstack_config.h&#039;&#039;&#039; header file to our project. In it, we add all the compile-time switches that fit our application. On a microcontroller, a frequent use case for BTstack is to implement a BLE peripheral. For this we, our config header should look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#ifndef MY_BTSTACK_CONFIG_H&lt;br /&gt;
#define MY_BTSTACK_CONFIG_H&lt;br /&gt;
&lt;br /&gt;
#ifndef ENABLE_BLE&lt;br /&gt;
#error In CMakeLists.txt add the &#039;pico_btstack_ble&#039; library to target_link_libraries(...)&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// logging&lt;br /&gt;
#define ENABLE_LOG_INFO&lt;br /&gt;
#define ENABLE_LOG_ERROR&lt;br /&gt;
#define ENABLE_PRINTF_HEXDUMP // required for hci_dump_init()&lt;br /&gt;
&lt;br /&gt;
#if 1 // configure as peripheral (GATT server)&lt;br /&gt;
	#define ENABLE_LE_PERIPHERAL&lt;br /&gt;
	#define MAX_NR_GATT_CLIENTS 0&lt;br /&gt;
#else // configure as central (GATT client)&lt;br /&gt;
	#define ENABLE_LE_CENTRAL&lt;br /&gt;
	#define MAX_NR_GATT_CLIENTS 1&lt;br /&gt;
//#define ENABLE_GATT_CLIENT_PAIRING&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// Setting various buffer sizes related to HCI communication&lt;br /&gt;
#define HCI_OUTGOING_PRE_BUFFER_SIZE 4&lt;br /&gt;
#define HCI_ACL_PAYLOAD_SIZE (255 + 4)&lt;br /&gt;
#define HCI_ACL_CHUNK_SIZE_ALIGNMENT 4&lt;br /&gt;
#define MAX_NR_HCI_CONNECTIONS 1&lt;br /&gt;
#define MAX_NR_SM_LOOKUP_ENTRIES 3&lt;br /&gt;
#define MAX_NR_WHITELIST_ENTRIES 16&lt;br /&gt;
#define MAX_NR_LE_DEVICE_DB_ENTRIES 16&lt;br /&gt;
&lt;br /&gt;
// Choosing a fixed-size attributes table over using malloc.&lt;br /&gt;
// We want to use BTstack without heap memory allocations.&lt;br /&gt;
#if 1&lt;br /&gt;
#define MAX_ATT_DB_SIZE 512&lt;br /&gt;
#else&lt;br /&gt;
#define HAVE_MALLOC&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// Enabling timers&lt;br /&gt;
#if 1&lt;br /&gt;
#define HAVE_EMBEDDED_TIME_MS&lt;br /&gt;
#else&lt;br /&gt;
#define HAVE_EMBEDDED_TICK&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// Limiting the amount of nonvolatile (flash) memory used for storing peer bonding information&lt;br /&gt;
#define NVM_NUM_DEVICE_DB_ENTRIES 16&lt;br /&gt;
#define NVM_NUM_LINK_KEYS 16&lt;br /&gt;
&lt;br /&gt;
// Configuring HCI Controller-to-Host flow control and related buffers to avoid overrunning the cyw43 shared bus&lt;br /&gt;
#define ENABLE_HCI_CONTROLLER_TO_HOST_FLOW_CONTROL&lt;br /&gt;
#define HCI_HOST_ACL_PACKET_LEN (255+4)&lt;br /&gt;
#define HCI_HOST_ACL_PACKET_NUM 3&lt;br /&gt;
#define HCI_HOST_SCO_PACKET_LEN 120&lt;br /&gt;
#define HCI_HOST_SCO_PACKET_NUM 3&lt;br /&gt;
#define MAX_NR_CONTROLLER_SCO_PACKETS 3&lt;br /&gt;
#define MAX_NR_CONTROLLER_ACL_BUFFERS 3&lt;br /&gt;
&lt;br /&gt;
// Enabling btstack_assert, acting just like normal assert()&lt;br /&gt;
#define HAVE_ASSERT&lt;br /&gt;
&lt;br /&gt;
// Setting HCI resend timeout in case the Bluetooth module needs more time to response.&lt;br /&gt;
#define HCI_RESET_RESEND_TIMEOUT_MS 800&lt;br /&gt;
&lt;br /&gt;
// Configuring security&lt;br /&gt;
#define ENABLE_SOFTWARE_AES128&lt;br /&gt;
#define ENABLE_MICRO_ECC_FOR_LE_SECURE_CONNECTIONS&lt;br /&gt;
&lt;br /&gt;
#endif // MY_BTSTACK_CONFIG_H&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== GATT Profiles, Services, Characteristics, and Descriptors ====&lt;br /&gt;
&lt;br /&gt;
A Bluetooth Low Energy Peripheral organizes the served data in a linear attributes table or database, referred to as  ATT. The GATT (Generic Attributes) profile used in BLE is, contrary to what the name suggests, a specific organizational structure imposed on the ATT table, where the data table as a whole is referred to as &amp;quot;profile&amp;quot;. The profile attributes can be broken down into consecutive &amp;quot;service&amp;quot; attributes, the service attributes into &amp;quot;characteristic&amp;quot; attributes, the characteristics into &amp;quot;descriptor&amp;quot; attributes. So, all in all there linear ATT table becomes a tree structure with four levels in GATT. A BLE peripheral, acting as a GATT server when connected to, will advertise its profile over GAP. A BLE central, acting as a GATT client after establishing a connection to the peripheral, can read the complete GATT hierarchy to find out about the profile contents.&lt;br /&gt;
&lt;br /&gt;
BTstack allows defining a GATT table as a human-readable text file. The translation of that file into a C header by a Python script is a build step that can be included in &#039;&#039;CMakeLists.txt&#039;&#039; using the function &#039;&#039;pico_btstack_make_gatt_header()&#039;&#039;. The generated C header contains the GATT table as an array of hex-coded bytes, laid out one line per attribute, with comments between the lines for orientation. Application code that needs to access the GATT table data then simply &amp;quot;#include&amp;quot;s this generated header file.&lt;br /&gt;
&lt;br /&gt;
When defining the GATT table in BTstack&#039;s text format, we can use the following keywords for the attribute permissions of a characteristic:&lt;br /&gt;
* READ&lt;br /&gt;
* WRITE&lt;br /&gt;
* WRITE_WITH_RESPONSE&lt;br /&gt;
* NOTIFY: Adds a &#039;&#039;Client Configuration&#039;&#039; descriptor to the characteristic that allows a GATT client to control whether a notification is to be sent to the client each time the value of the characteristic changes.&lt;br /&gt;
* DYNAMIC: Indicates that reading and writing to this characteristic requires adding this case to the read and write callbacks.&lt;br /&gt;
&lt;br /&gt;
===== BTStack Python script output for a GATT characteristic declaration attribute =====&lt;br /&gt;
&lt;br /&gt;
Let&#039;s have a look at the output of the BTstack Python script that converts the .gatt file to a C header and let&#039;s narrow it down to just the characteristic declarations.&lt;br /&gt;
&lt;br /&gt;
Here is the binary sequence (in hex representation) generated for an attribute that declares a GATT characteristic with attribute UUID &#039;&#039;B0B0F155-B0B0-B0B0-B0B0-B0B000000101&#039;&#039; and permissions &#039;&#039;READ | DYNAMIC&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0x1b, 0x00, 0x02, 0x00, 0x08, 0x00, 0x03, 0x28, 0x02, 0x09, 0x00, 0x01, 0x01, 0x00, 0x00, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0x55, 0xf1, 0xb0, 0xb0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The bytes are grouped from left to right according to this scheme:&lt;br /&gt;
* 2 bytes for the length of this attribute definition: 0x001b (= 27 bytes)&lt;br /&gt;
* 2 bytes for the access permission of this attribute: 0x0002 (= read-only)&lt;br /&gt;
* 2 bytes for the attribute handle: 0x0008&lt;br /&gt;
* 2 bytes for the attribute type: 0x2803 (short 16-bit UUID that indicates a characteristic declaration)&lt;br /&gt;
* 1 byte for the access permissions of the declared characteristic: 0x02 (= read-only)&lt;br /&gt;
* 2 bytes for the attribute handle of the characteristic value: 0x0009&lt;br /&gt;
* 16 bytes for the 128-bit UUID of the characteristic: 0xb0b0f155b0b0b0b0b0b0b0b000000101&lt;br /&gt;
where &#039;&#039;&#039;the bytes in each group are in reverse order&#039;&#039;&#039;!&lt;br /&gt;
&lt;br /&gt;
For the official specification of the Bluetooth 5.4 GATT characteristic declaration refer to section 3.3.1 in the [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html in the Bluetooth 5.4 Core Specification]. That section also lists the characteristics permissions (or properties):&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin:auto&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Properties !! Value !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Broadcast || 0x01 || If set, permits broadcasts of the Characteristic Value using Server Characteristic Configuration Descriptor. If set, the Server Characteristic Configuration Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
| Read || 0x02 || If set, permits reads of the Characteristic Value using procedures defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-66cf484d-50cd-199f-dd0d-d0d02ad02ce0 Section 4.8]&lt;br /&gt;
|-&lt;br /&gt;
| Write Without Response || 0x04 || If set, permit writes of the Characteristic Value without response using procedures defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-9f1c2e38-8fbe-f60c-d885-076707c88a43 Section 4.9.1].&lt;br /&gt;
|-&lt;br /&gt;
| Write || 0x08 || If set, permits writes of the Characteristic Value with response using procedures defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-ba4b856a-6994-01e4-97f6-357f9be40990 Section 4.9.3] or [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-6ab738ad-6d26-1da1-7417-e83da50e90c5 Section 4.9.4].&lt;br /&gt;
|-&lt;br /&gt;
| Notify || 0x10 || If set, permits notifications of a Characteristic Value without acknowledgment using the procedure defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-74673cc2-e704-a2fa-14bb-d175c27193ab Section 4.10]. If set, the Client Characteristic Configuration Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
| Indicate || 0x20 || If set, permits indications of a Characteristic Value with acknowledgment using the procedure defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-615ed0ff-f42b-827d-6427-6474fc21737c Section 4.11]. If set, the Client Characteristic Configuration Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
| Authenticated Signed Writes || 0x40 || If set, permits signed writes to the Characteristic Value using the procedure defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-516bd731-2079-87f9-8002-c3ca92fbed4b Section 4.9.2].&lt;br /&gt;
|-&lt;br /&gt;
| Extended Properties || 0x80 || If set, additional characteristic properties are defined in the Characteristic Extended Properties Descriptor defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-9154505c-6e2d-a35a-3f30-1da0383a2425 Section 3.3.3.1]. If set, the Characteristic Extended Properties Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== BTStack Python script output for a GATT user description declaration attribute =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0x08, 0x00, 0x0a, 0x01, 0x0a, 0x00, 0x01, 0x29&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The bytes are grouped from left to right as follows:&lt;br /&gt;
* 2 bytes for the length of this attribute: 0x0008 (= 8 bytes)&lt;br /&gt;
* 2 bytes for permissions: 0x010a (= read, write, dynamic)&lt;br /&gt;
* 2 bytes for the handle of this attribute&lt;br /&gt;
* 2 bytes for the 16-bit short UUID that indicates a user description attribute: 0x2901&lt;br /&gt;
where the order of the bytes in each group needs to be reversed before analyzing.&lt;br /&gt;
&lt;br /&gt;
The attribute declaration does not include the user description text itself. User description text is always &amp;quot;dynamic&amp;quot;, meaning that it is served to the client on demand on the basis of the attribute handle. In BTstack, the implementation of the read callback is responsible for returning the UTF-8 bytes for the text string corresponding the attribute handle.&lt;br /&gt;
&lt;br /&gt;
==== The BTstack runloop ====&lt;br /&gt;
&lt;br /&gt;
The following articles by Hunter Adams offer a detailed analysis of how BTstack works on the Pico:&lt;br /&gt;
# [https://vanhunteradams.com/Pico/BLE/BTStack_HCI.html BTstack and RP2040: HCI (Host Controller Interface)].&amp;lt;br /&amp;gt;This article delves, among other things, into how the BTstack runloop is executed inside a Pico [[#Async_Context | async_context]].&amp;lt;br /&amp;gt;&amp;lt;blockquote&amp;gt;[...] we have just one &#039;&#039;when_pending_worker&#039;&#039; in our async_context. This worker is called &#039;&#039;cyw43_poll_worker&#039;&#039;, and its &#039;&#039;do_work&#039;&#039; function points to &#039;&#039;cyw43_poll_func()&#039;&#039;, listed above. This function ends up calling &#039;&#039;btstack_run_loop_poll_data_sources_from_irq()&#039;&#039;, about which we&#039;ll learn more shortly. This worker gets marked as pending in a GPIO interrupt. So, this provides a mechanism by which the CYW43 can tell the RP2040 to run &#039;&#039;btstack_run_loop_poll_data_sources_from_irq()&#039;&#039; which, as we&#039;re going to learn, goes and gets data from the device.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
# [https://vanhunteradams.com/Pico/BLE/GATT_Server.html Building a Bluetooth GATT Server on the Pi Pico W]&lt;br /&gt;
&lt;br /&gt;
==== GATT Characteristic read and write operations ====&lt;br /&gt;
&lt;br /&gt;
The struct &amp;lt;code&amp;gt;att_service_handler_t&amp;lt;/code&amp;gt; represents a GATT service. After the fields of the struct have been filled in by the application code, it holds all the information needed for the BLE peripheral to make it available to the BLE central. Some of the fields of the struct hold the ATT handles that define the start and end of the collection of characteristics belonging to the service. Other fields of the struct (&amp;lt;code&amp;gt;read_callback&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;write_callback&amp;lt;/code&amp;gt;) hold pointers to functions that handle reading from and writing to characteristic values.&lt;br /&gt;
&lt;br /&gt;
Note that the &#039;&#039;read&#039;&#039; callback for a descriptor of a GATT characteristic (i.e., an ATT attribute) is called twice. In the first call, the buffer pointer passed to the callback function is NULL. In the second call, it&#039;s a valid pointer. The first call is made by BTstack to query the size of the data that will be returned by the second call. BTstack needs to make sure its transmission buffers can hold the amount of data before making the second call.&lt;br /&gt;
&lt;br /&gt;
At the end of a writing operation, if the characteristic was configured to send back notifications to the BLE peer, one more callback function comes into play. It is part of another struct, &amp;lt;code&amp;gt;btstack_context_callback_registration_t&amp;lt;/code&amp;gt;, that is used for the deferred sending of characteristic update notification to the BLE central. In this callback, &amp;lt;code&amp;gt;att_server_notify()&amp;lt;/code&amp;gt; is called to finally send the write notification to the peer.&lt;/div&gt;</summary>
		<author><name>Kai</name></author>
	</entry>
	<entry>
		<id>https://Robo.Fish/wiki/index.php?title=Raspberry_Pi_Microcontrollers&amp;diff=3284</id>
		<title>Raspberry Pi Microcontrollers</title>
		<link rel="alternate" type="text/html" href="https://Robo.Fish/wiki/index.php?title=Raspberry_Pi_Microcontrollers&amp;diff=3284"/>
		<updated>2025-05-09T20:21:13Z</updated>

		<summary type="html">&lt;p&gt;Kai: /* BTStack Python script output for a GATT user description declaration attribute */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Pico Series =&lt;br /&gt;
* Raspberry Pi Pico and Pico W&lt;br /&gt;
** Dual [https://developer.arm.com/Processors/Cortex-M0-Plus Arm Cortex-M0+] with Armv6-M programming model, up to 133 MHz&lt;br /&gt;
* Raspberry Pi Pico 2 and Pico 2 W&lt;br /&gt;
** Dual [https://developer.arm.com/Processors/Cortex-M33 Arm Cortex-M33] with Armv8-M programming model, up to 150 MHz&lt;br /&gt;
&lt;br /&gt;
== Development Setup ==&lt;br /&gt;
&lt;br /&gt;
=== Using the Raspberry Pi Debug Probe ===&lt;br /&gt;
The Debug Probe is a RP2040 based USB-to-UART/SWD board for connecting the USB slot of a development machine to the SWD or UART pins of a target device.&lt;br /&gt;
&lt;br /&gt;
=== Using A Pico To Debug Another Pico ===&lt;br /&gt;
A Pico can be used to debug another Pico (a.k.a. target device)  by flashing it with the [https://github.com/raspberrypi/debugprobe debugprobe] binary and wiring to the target Pico as shown below.&lt;br /&gt;
&lt;br /&gt;
[[File:Wiring_rpi_pico_as_debugger.png | x320 px | A Raspberry Pi Pico wired to debug another Pico]]&lt;br /&gt;
&lt;br /&gt;
From the debugger Pico to the target Pico,&lt;br /&gt;
* pin #4 (GP2) connects to pin SWCLK,&lt;br /&gt;
* pin #5 (GP3) connects to SWDIO,&lt;br /&gt;
* pin #6 (GP4, UART1 TX) connects to pin #2 (GP1, UART0 RX),&lt;br /&gt;
* pin #7 (GP5, UART1 RX) connects to pin #1 (GP0, UART0, TX).&lt;br /&gt;
&lt;br /&gt;
The debugger Pico serves both as a USB-to-SWD and USB-to-UART bridge to the target device. The development machine, therefore, needs to be connected via USB only to the debugger Pico. Console output on the target Pico is relayed through the debugger. It is possible, though, to connect a second USB cable from the development machine to the target device for (simultaneous) direct access to the console output. This debugger setup works not just with Pico targets but with any microcontroller that supports the CMSIS-DAP protocol over SWD.&lt;br /&gt;
&lt;br /&gt;
=== Software Tools for Debugging ===&lt;br /&gt;
Whether we use the Raspberry Pi Debug Probe or a spare Pico as debug probe, the software tools used for debugging are the same:&lt;br /&gt;
* openocd&lt;br /&gt;
&lt;br /&gt;
== Notes on Programming with the C SDK ==&lt;br /&gt;
&lt;br /&gt;
=== Async Context ===&lt;br /&gt;
In the C SDK, an [https://www.raspberrypi.com/documentation/pico-sdk/high_level.html#group_pico_async_context async_context] is used in concurrent programming to make sure that functions are executed on the same thread and in the order they were submitted, similar to dispatch queues in Apple&#039;s [https://developer.apple.com/documentation/dispatch?language=objc Dispatch framework]. The &#039;&#039;async_context&#039;&#039; data structure is a container of linked lists of worker functions that are executed within a single thread of a single processor core.&lt;br /&gt;
&lt;br /&gt;
=== Bluetooth with BTstack ===&lt;br /&gt;
&lt;br /&gt;
The C SDK integrates the third-party [https://bluekitchen-gmbh.com/btstack BTstack] framework as its Bluetooth API that interfaces with the Infineon CYW43 wireless communication module (on Pico W models) via the Host-Controller Interface (HCI) protocol.&lt;br /&gt;
&lt;br /&gt;
==== Setup ====&lt;br /&gt;
&lt;br /&gt;
Before we can call any BTstack functions (and hope for some meaningful outcome), we need to add a &#039;&#039;&#039;btstack_config.h&#039;&#039;&#039; header file to our project. In it, we add all the compile-time switches that fit our application. On a microcontroller, a frequent use case for BTstack is to implement a BLE peripheral. For this we, our config header should look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#ifndef MY_BTSTACK_CONFIG_H&lt;br /&gt;
#define MY_BTSTACK_CONFIG_H&lt;br /&gt;
&lt;br /&gt;
#ifndef ENABLE_BLE&lt;br /&gt;
#error In CMakeLists.txt add the &#039;pico_btstack_ble&#039; library to target_link_libraries(...)&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// logging&lt;br /&gt;
#define ENABLE_LOG_INFO&lt;br /&gt;
#define ENABLE_LOG_ERROR&lt;br /&gt;
#define ENABLE_PRINTF_HEXDUMP // required for hci_dump_init()&lt;br /&gt;
&lt;br /&gt;
#if 1 // configure as peripheral (GATT server)&lt;br /&gt;
	#define ENABLE_LE_PERIPHERAL&lt;br /&gt;
	#define MAX_NR_GATT_CLIENTS 0&lt;br /&gt;
#else // configure as central (GATT client)&lt;br /&gt;
	#define ENABLE_LE_CENTRAL&lt;br /&gt;
	#define MAX_NR_GATT_CLIENTS 1&lt;br /&gt;
//#define ENABLE_GATT_CLIENT_PAIRING&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// Setting various buffer sizes related to HCI communication&lt;br /&gt;
#define HCI_OUTGOING_PRE_BUFFER_SIZE 4&lt;br /&gt;
#define HCI_ACL_PAYLOAD_SIZE (255 + 4)&lt;br /&gt;
#define HCI_ACL_CHUNK_SIZE_ALIGNMENT 4&lt;br /&gt;
#define MAX_NR_HCI_CONNECTIONS 1&lt;br /&gt;
#define MAX_NR_SM_LOOKUP_ENTRIES 3&lt;br /&gt;
#define MAX_NR_WHITELIST_ENTRIES 16&lt;br /&gt;
#define MAX_NR_LE_DEVICE_DB_ENTRIES 16&lt;br /&gt;
&lt;br /&gt;
// Choosing a fixed-size attributes table over using malloc.&lt;br /&gt;
// We want to use BTstack without heap memory allocations.&lt;br /&gt;
#if 1&lt;br /&gt;
#define MAX_ATT_DB_SIZE 512&lt;br /&gt;
#else&lt;br /&gt;
#define HAVE_MALLOC&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// Enabling timers&lt;br /&gt;
#if 1&lt;br /&gt;
#define HAVE_EMBEDDED_TIME_MS&lt;br /&gt;
#else&lt;br /&gt;
#define HAVE_EMBEDDED_TICK&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// Limiting the amount of nonvolatile (flash) memory used for storing peer bonding information&lt;br /&gt;
#define NVM_NUM_DEVICE_DB_ENTRIES 16&lt;br /&gt;
#define NVM_NUM_LINK_KEYS 16&lt;br /&gt;
&lt;br /&gt;
// Configuring HCI Controller-to-Host flow control and related buffers to avoid overrunning the cyw43 shared bus&lt;br /&gt;
#define ENABLE_HCI_CONTROLLER_TO_HOST_FLOW_CONTROL&lt;br /&gt;
#define HCI_HOST_ACL_PACKET_LEN (255+4)&lt;br /&gt;
#define HCI_HOST_ACL_PACKET_NUM 3&lt;br /&gt;
#define HCI_HOST_SCO_PACKET_LEN 120&lt;br /&gt;
#define HCI_HOST_SCO_PACKET_NUM 3&lt;br /&gt;
#define MAX_NR_CONTROLLER_SCO_PACKETS 3&lt;br /&gt;
#define MAX_NR_CONTROLLER_ACL_BUFFERS 3&lt;br /&gt;
&lt;br /&gt;
// Enabling btstack_assert, acting just like normal assert()&lt;br /&gt;
#define HAVE_ASSERT&lt;br /&gt;
&lt;br /&gt;
// Setting HCI resend timeout in case the Bluetooth module needs more time to response.&lt;br /&gt;
#define HCI_RESET_RESEND_TIMEOUT_MS 800&lt;br /&gt;
&lt;br /&gt;
// Configuring security&lt;br /&gt;
#define ENABLE_SOFTWARE_AES128&lt;br /&gt;
#define ENABLE_MICRO_ECC_FOR_LE_SECURE_CONNECTIONS&lt;br /&gt;
&lt;br /&gt;
#endif // MY_BTSTACK_CONFIG_H&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== GATT Profiles, Services, Characteristics, and Descriptors ====&lt;br /&gt;
&lt;br /&gt;
A Bluetooth Low Energy Peripheral organizes the served data in a linear attributes table or database, referred to as  ATT. The GATT (Generic Attributes) profile used in BLE is, contrary to what the name suggests, a specific organizational structure imposed on the ATT table, where the data table as a whole is referred to as &amp;quot;profile&amp;quot;. The profile attributes can be broken down into consecutive &amp;quot;service&amp;quot; attributes, the service attributes into &amp;quot;characteristic&amp;quot; attributes, the characteristics into &amp;quot;descriptor&amp;quot; attributes. So, all in all there linear ATT table becomes a tree structure with four levels in GATT. A BLE peripheral, acting as a GATT server when connected to, will advertise its profile over GAP. A BLE central, acting as a GATT client after establishing a connection to the peripheral, can read the complete GATT hierarchy to find out about the profile contents.&lt;br /&gt;
&lt;br /&gt;
BTstack allows defining a GATT table as a human-readable text file. The translation of that file into a C header by a Python script is a build step that can be included in &#039;&#039;CMakeLists.txt&#039;&#039; using the function &#039;&#039;pico_btstack_make_gatt_header()&#039;&#039;. The generated C header contains the GATT table as an array of hex-coded bytes, laid out one line per attribute, with comments between the lines for orientation. Application code that needs to access the GATT table data then simply &amp;quot;#include&amp;quot;s this generated header file.&lt;br /&gt;
&lt;br /&gt;
When defining the GATT table in BTstack&#039;s text format, we can use the following keywords for the attribute permissions of a characteristic:&lt;br /&gt;
* READ&lt;br /&gt;
* WRITE&lt;br /&gt;
* WRITE_WITH_RESPONSE&lt;br /&gt;
* NOTIFY: Adds a &#039;&#039;Client Configuration&#039;&#039; descriptor to the characteristic that allows a GATT client to control whether a notification is to be sent to the client each time the value of the characteristic changes.&lt;br /&gt;
* DYNAMIC: Indicates that reading and writing to this characteristic requires adding this case to the read and write callbacks.&lt;br /&gt;
&lt;br /&gt;
===== BTStack Python script output for a GATT characteristic declaration attribute =====&lt;br /&gt;
&lt;br /&gt;
Let&#039;s have a look at the output of the BTstack Python script that converts the .gatt file to a C header and let&#039;s narrow it down to just the characteristic declarations.&lt;br /&gt;
&lt;br /&gt;
Here is the binary sequence (in hex representation) generated for an attribute that declares a GATT characteristic with attribute UUID &#039;&#039;B0B0F155-B0B0-B0B0-B0B0-B0B000000101&#039;&#039; and permissions &#039;&#039;READ | DYNAMIC&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0x1b, 0x00, 0x02, 0x00, 0x08, 0x00, 0x03, 0x28, 0x02, 0x09, 0x00, 0x01, 0x01, 0x00, 0x00, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0x55, 0xf1, 0xb0, 0xb0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The bytes are grouped from left to right according to this scheme:&lt;br /&gt;
* 2 bytes for the length of this attribute definition: 0x001b (= 27 bytes)&lt;br /&gt;
* 2 bytes for the access permission of this attribute: 0x0002 (= read-only)&lt;br /&gt;
* 2 bytes for the attribute handle: 0x0008&lt;br /&gt;
* 2 bytes for the attribute type: 0x2803 (short 16-bit UUID that indicates a characteristic declaration)&lt;br /&gt;
* 1 byte for the access permissions of the declared characteristic: 0x02 (= read-only)&lt;br /&gt;
* 2 bytes for the attribute handle of the characteristic value: 0x0009&lt;br /&gt;
* 16 bytes for the 128-bit UUID of the characteristic: 0xb0b0f155b0b0b0b0b0b0b0b000000101&lt;br /&gt;
where &#039;&#039;&#039;the bytes in each group are in reverse order&#039;&#039;&#039;!&lt;br /&gt;
&lt;br /&gt;
For the official specification of the Bluetooth 5.4 GATT characteristic declaration refer to section 3.3.1 in the [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html in the Bluetooth 5.4 Core Specification]. That section also lists the characteristics permissions (or properties):&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin:auto&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Properties !! Value !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Broadcast || 0x01 || If set, permits broadcasts of the Characteristic Value using Server Characteristic Configuration Descriptor. If set, the Server Characteristic Configuration Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
| Read || 0x02 || If set, permits reads of the Characteristic Value using procedures defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-66cf484d-50cd-199f-dd0d-d0d02ad02ce0 Section 4.8]&lt;br /&gt;
|-&lt;br /&gt;
| Write Without Response || 0x04 || If set, permit writes of the Characteristic Value without response using procedures defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-9f1c2e38-8fbe-f60c-d885-076707c88a43 Section 4.9.1].&lt;br /&gt;
|-&lt;br /&gt;
| Write || 0x08 || If set, permits writes of the Characteristic Value with response using procedures defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-ba4b856a-6994-01e4-97f6-357f9be40990 Section 4.9.3] or [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-6ab738ad-6d26-1da1-7417-e83da50e90c5 Section 4.9.4].&lt;br /&gt;
|-&lt;br /&gt;
| Notify || 0x10 || If set, permits notifications of a Characteristic Value without acknowledgment using the procedure defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-74673cc2-e704-a2fa-14bb-d175c27193ab Section 4.10]. If set, the Client Characteristic Configuration Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
| Indicate || 0x20 || If set, permits indications of a Characteristic Value with acknowledgment using the procedure defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-615ed0ff-f42b-827d-6427-6474fc21737c Section 4.11]. If set, the Client Characteristic Configuration Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
| Authenticated Signed Writes || 0x40 || If set, permits signed writes to the Characteristic Value using the procedure defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-516bd731-2079-87f9-8002-c3ca92fbed4b Section 4.9.2].&lt;br /&gt;
|-&lt;br /&gt;
| Extended Properties || 0x80 || If set, additional characteristic properties are defined in the Characteristic Extended Properties Descriptor defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-9154505c-6e2d-a35a-3f30-1da0383a2425 Section 3.3.3.1]. If set, the Characteristic Extended Properties Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== BTStack Python script output for a GATT user description declaration attribute =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0x08, 0x00, 0x0a, 0x01, 0x0a, 0x00, 0x01, 0x29,&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The bytes are grouped from left to right as follows:&lt;br /&gt;
* 2 bytes for the length of this attribute: 0x0008 (= 8 bytes)&lt;br /&gt;
* 2 bytes for permissions: 0x010a (= read, write, dynamic)&lt;br /&gt;
* 2 bytes for the handle of this attribute&lt;br /&gt;
* 2 bytes for the 16-bit short UUID that indicates a user description attribute: 0x2901&lt;br /&gt;
&lt;br /&gt;
==== The BTstack runloop ====&lt;br /&gt;
&lt;br /&gt;
The following articles by Hunter Adams offer a detailed analysis of how BTstack works on the Pico:&lt;br /&gt;
# [https://vanhunteradams.com/Pico/BLE/BTStack_HCI.html BTstack and RP2040: HCI (Host Controller Interface)].&amp;lt;br /&amp;gt;This article delves, among other things, into how the BTstack runloop is executed inside a Pico [[#Async_Context | async_context]].&amp;lt;br /&amp;gt;&amp;lt;blockquote&amp;gt;[...] we have just one &#039;&#039;when_pending_worker&#039;&#039; in our async_context. This worker is called &#039;&#039;cyw43_poll_worker&#039;&#039;, and its &#039;&#039;do_work&#039;&#039; function points to &#039;&#039;cyw43_poll_func()&#039;&#039;, listed above. This function ends up calling &#039;&#039;btstack_run_loop_poll_data_sources_from_irq()&#039;&#039;, about which we&#039;ll learn more shortly. This worker gets marked as pending in a GPIO interrupt. So, this provides a mechanism by which the CYW43 can tell the RP2040 to run &#039;&#039;btstack_run_loop_poll_data_sources_from_irq()&#039;&#039; which, as we&#039;re going to learn, goes and gets data from the device.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
# [https://vanhunteradams.com/Pico/BLE/GATT_Server.html Building a Bluetooth GATT Server on the Pi Pico W]&lt;br /&gt;
&lt;br /&gt;
==== GATT Characteristic read and write operations ====&lt;br /&gt;
&lt;br /&gt;
The struct &amp;lt;code&amp;gt;att_service_handler_t&amp;lt;/code&amp;gt; represents a GATT service. After the fields of the struct have been filled in by the application code, it holds all the information needed for the BLE peripheral to make it available to the BLE central. Some of the fields of the struct hold the ATT handles that define the start and end of the collection of characteristics belonging to the service. Other fields of the struct (&amp;lt;code&amp;gt;read_callback&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;write_callback&amp;lt;/code&amp;gt;) hold pointers to functions that handle reading from and writing to characteristic values.&lt;br /&gt;
&lt;br /&gt;
Note that the &#039;&#039;read&#039;&#039; callback for a descriptor of a GATT characteristic (i.e., an ATT attribute) is called twice. In the first call, the buffer pointer passed to the callback function is NULL. In the second call, it&#039;s a valid pointer. The first call is made by BTstack to query the size of the data that will be returned by the second call. BTstack needs to make sure its transmission buffers can hold the amount of data before making the second call.&lt;br /&gt;
&lt;br /&gt;
At the end of a writing operation, if the characteristic was configured to send back notifications to the BLE peer, one more callback function comes into play. It is part of another struct, &amp;lt;code&amp;gt;btstack_context_callback_registration_t&amp;lt;/code&amp;gt;, that is used for the deferred sending of characteristic update notification to the BLE central. In this callback, &amp;lt;code&amp;gt;att_server_notify()&amp;lt;/code&amp;gt; is called to finally send the write notification to the peer.&lt;/div&gt;</summary>
		<author><name>Kai</name></author>
	</entry>
	<entry>
		<id>https://Robo.Fish/wiki/index.php?title=Raspberry_Pi_Microcontrollers&amp;diff=3283</id>
		<title>Raspberry Pi Microcontrollers</title>
		<link rel="alternate" type="text/html" href="https://Robo.Fish/wiki/index.php?title=Raspberry_Pi_Microcontrollers&amp;diff=3283"/>
		<updated>2025-05-09T19:24:53Z</updated>

		<summary type="html">&lt;p&gt;Kai: BTstack Python output for a GATT user description declaration attribute&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Pico Series =&lt;br /&gt;
* Raspberry Pi Pico and Pico W&lt;br /&gt;
** Dual [https://developer.arm.com/Processors/Cortex-M0-Plus Arm Cortex-M0+] with Armv6-M programming model, up to 133 MHz&lt;br /&gt;
* Raspberry Pi Pico 2 and Pico 2 W&lt;br /&gt;
** Dual [https://developer.arm.com/Processors/Cortex-M33 Arm Cortex-M33] with Armv8-M programming model, up to 150 MHz&lt;br /&gt;
&lt;br /&gt;
== Development Setup ==&lt;br /&gt;
&lt;br /&gt;
=== Using the Raspberry Pi Debug Probe ===&lt;br /&gt;
The Debug Probe is a RP2040 based USB-to-UART/SWD board for connecting the USB slot of a development machine to the SWD or UART pins of a target device.&lt;br /&gt;
&lt;br /&gt;
=== Using A Pico To Debug Another Pico ===&lt;br /&gt;
A Pico can be used to debug another Pico (a.k.a. target device)  by flashing it with the [https://github.com/raspberrypi/debugprobe debugprobe] binary and wiring to the target Pico as shown below.&lt;br /&gt;
&lt;br /&gt;
[[File:Wiring_rpi_pico_as_debugger.png | x320 px | A Raspberry Pi Pico wired to debug another Pico]]&lt;br /&gt;
&lt;br /&gt;
From the debugger Pico to the target Pico,&lt;br /&gt;
* pin #4 (GP2) connects to pin SWCLK,&lt;br /&gt;
* pin #5 (GP3) connects to SWDIO,&lt;br /&gt;
* pin #6 (GP4, UART1 TX) connects to pin #2 (GP1, UART0 RX),&lt;br /&gt;
* pin #7 (GP5, UART1 RX) connects to pin #1 (GP0, UART0, TX).&lt;br /&gt;
&lt;br /&gt;
The debugger Pico serves both as a USB-to-SWD and USB-to-UART bridge to the target device. The development machine, therefore, needs to be connected via USB only to the debugger Pico. Console output on the target Pico is relayed through the debugger. It is possible, though, to connect a second USB cable from the development machine to the target device for (simultaneous) direct access to the console output. This debugger setup works not just with Pico targets but with any microcontroller that supports the CMSIS-DAP protocol over SWD.&lt;br /&gt;
&lt;br /&gt;
=== Software Tools for Debugging ===&lt;br /&gt;
Whether we use the Raspberry Pi Debug Probe or a spare Pico as debug probe, the software tools used for debugging are the same:&lt;br /&gt;
* openocd&lt;br /&gt;
&lt;br /&gt;
== Notes on Programming with the C SDK ==&lt;br /&gt;
&lt;br /&gt;
=== Async Context ===&lt;br /&gt;
In the C SDK, an [https://www.raspberrypi.com/documentation/pico-sdk/high_level.html#group_pico_async_context async_context] is used in concurrent programming to make sure that functions are executed on the same thread and in the order they were submitted, similar to dispatch queues in Apple&#039;s [https://developer.apple.com/documentation/dispatch?language=objc Dispatch framework]. The &#039;&#039;async_context&#039;&#039; data structure is a container of linked lists of worker functions that are executed within a single thread of a single processor core.&lt;br /&gt;
&lt;br /&gt;
=== Bluetooth with BTstack ===&lt;br /&gt;
&lt;br /&gt;
The C SDK integrates the third-party [https://bluekitchen-gmbh.com/btstack BTstack] framework as its Bluetooth API that interfaces with the Infineon CYW43 wireless communication module (on Pico W models) via the Host-Controller Interface (HCI) protocol.&lt;br /&gt;
&lt;br /&gt;
==== Setup ====&lt;br /&gt;
&lt;br /&gt;
Before we can call any BTstack functions (and hope for some meaningful outcome), we need to add a &#039;&#039;&#039;btstack_config.h&#039;&#039;&#039; header file to our project. In it, we add all the compile-time switches that fit our application. On a microcontroller, a frequent use case for BTstack is to implement a BLE peripheral. For this we, our config header should look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#ifndef MY_BTSTACK_CONFIG_H&lt;br /&gt;
#define MY_BTSTACK_CONFIG_H&lt;br /&gt;
&lt;br /&gt;
#ifndef ENABLE_BLE&lt;br /&gt;
#error In CMakeLists.txt add the &#039;pico_btstack_ble&#039; library to target_link_libraries(...)&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// logging&lt;br /&gt;
#define ENABLE_LOG_INFO&lt;br /&gt;
#define ENABLE_LOG_ERROR&lt;br /&gt;
#define ENABLE_PRINTF_HEXDUMP // required for hci_dump_init()&lt;br /&gt;
&lt;br /&gt;
#if 1 // configure as peripheral (GATT server)&lt;br /&gt;
	#define ENABLE_LE_PERIPHERAL&lt;br /&gt;
	#define MAX_NR_GATT_CLIENTS 0&lt;br /&gt;
#else // configure as central (GATT client)&lt;br /&gt;
	#define ENABLE_LE_CENTRAL&lt;br /&gt;
	#define MAX_NR_GATT_CLIENTS 1&lt;br /&gt;
//#define ENABLE_GATT_CLIENT_PAIRING&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// Setting various buffer sizes related to HCI communication&lt;br /&gt;
#define HCI_OUTGOING_PRE_BUFFER_SIZE 4&lt;br /&gt;
#define HCI_ACL_PAYLOAD_SIZE (255 + 4)&lt;br /&gt;
#define HCI_ACL_CHUNK_SIZE_ALIGNMENT 4&lt;br /&gt;
#define MAX_NR_HCI_CONNECTIONS 1&lt;br /&gt;
#define MAX_NR_SM_LOOKUP_ENTRIES 3&lt;br /&gt;
#define MAX_NR_WHITELIST_ENTRIES 16&lt;br /&gt;
#define MAX_NR_LE_DEVICE_DB_ENTRIES 16&lt;br /&gt;
&lt;br /&gt;
// Choosing a fixed-size attributes table over using malloc.&lt;br /&gt;
// We want to use BTstack without heap memory allocations.&lt;br /&gt;
#if 1&lt;br /&gt;
#define MAX_ATT_DB_SIZE 512&lt;br /&gt;
#else&lt;br /&gt;
#define HAVE_MALLOC&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// Enabling timers&lt;br /&gt;
#if 1&lt;br /&gt;
#define HAVE_EMBEDDED_TIME_MS&lt;br /&gt;
#else&lt;br /&gt;
#define HAVE_EMBEDDED_TICK&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// Limiting the amount of nonvolatile (flash) memory used for storing peer bonding information&lt;br /&gt;
#define NVM_NUM_DEVICE_DB_ENTRIES 16&lt;br /&gt;
#define NVM_NUM_LINK_KEYS 16&lt;br /&gt;
&lt;br /&gt;
// Configuring HCI Controller-to-Host flow control and related buffers to avoid overrunning the cyw43 shared bus&lt;br /&gt;
#define ENABLE_HCI_CONTROLLER_TO_HOST_FLOW_CONTROL&lt;br /&gt;
#define HCI_HOST_ACL_PACKET_LEN (255+4)&lt;br /&gt;
#define HCI_HOST_ACL_PACKET_NUM 3&lt;br /&gt;
#define HCI_HOST_SCO_PACKET_LEN 120&lt;br /&gt;
#define HCI_HOST_SCO_PACKET_NUM 3&lt;br /&gt;
#define MAX_NR_CONTROLLER_SCO_PACKETS 3&lt;br /&gt;
#define MAX_NR_CONTROLLER_ACL_BUFFERS 3&lt;br /&gt;
&lt;br /&gt;
// Enabling btstack_assert, acting just like normal assert()&lt;br /&gt;
#define HAVE_ASSERT&lt;br /&gt;
&lt;br /&gt;
// Setting HCI resend timeout in case the Bluetooth module needs more time to response.&lt;br /&gt;
#define HCI_RESET_RESEND_TIMEOUT_MS 800&lt;br /&gt;
&lt;br /&gt;
// Configuring security&lt;br /&gt;
#define ENABLE_SOFTWARE_AES128&lt;br /&gt;
#define ENABLE_MICRO_ECC_FOR_LE_SECURE_CONNECTIONS&lt;br /&gt;
&lt;br /&gt;
#endif // MY_BTSTACK_CONFIG_H&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== GATT Profiles, Services, Characteristics, and Descriptors ====&lt;br /&gt;
&lt;br /&gt;
A Bluetooth Low Energy Peripheral organizes the served data in a linear attributes table or database, referred to as  ATT. The GATT (Generic Attributes) profile used in BLE is, contrary to what the name suggests, a specific organizational structure imposed on the ATT table, where the data table as a whole is referred to as &amp;quot;profile&amp;quot;. The profile attributes can be broken down into consecutive &amp;quot;service&amp;quot; attributes, the service attributes into &amp;quot;characteristic&amp;quot; attributes, the characteristics into &amp;quot;descriptor&amp;quot; attributes. So, all in all there linear ATT table becomes a tree structure with four levels in GATT. A BLE peripheral, acting as a GATT server when connected to, will advertise its profile over GAP. A BLE central, acting as a GATT client after establishing a connection to the peripheral, can read the complete GATT hierarchy to find out about the profile contents.&lt;br /&gt;
&lt;br /&gt;
BTstack allows defining a GATT table as a human-readable text file. The translation of that file into a C header by a Python script is a build step that can be included in &#039;&#039;CMakeLists.txt&#039;&#039; using the function &#039;&#039;pico_btstack_make_gatt_header()&#039;&#039;. The generated C header contains the GATT table as an array of hex-coded bytes, laid out one line per attribute, with comments between the lines for orientation. Application code that needs to access the GATT table data then simply &amp;quot;#include&amp;quot;s this generated header file.&lt;br /&gt;
&lt;br /&gt;
When defining the GATT table in BTstack&#039;s text format, we can use the following keywords for the attribute permissions of a characteristic:&lt;br /&gt;
* READ&lt;br /&gt;
* WRITE&lt;br /&gt;
* WRITE_WITH_RESPONSE&lt;br /&gt;
* NOTIFY: Adds a &#039;&#039;Client Configuration&#039;&#039; descriptor to the characteristic that allows a GATT client to control whether a notification is to be sent to the client each time the value of the characteristic changes.&lt;br /&gt;
* DYNAMIC: Indicates that reading and writing to this characteristic requires adding this case to the read and write callbacks.&lt;br /&gt;
&lt;br /&gt;
===== BTStack Python script output for a GATT characteristic declaration attribute =====&lt;br /&gt;
&lt;br /&gt;
Let&#039;s have a look at the output of the BTstack Python script that converts the .gatt file to a C header and let&#039;s narrow it down to just the characteristic declarations.&lt;br /&gt;
&lt;br /&gt;
Here is the binary sequence (in hex representation) generated for an attribute that declares a GATT characteristic with attribute UUID &#039;&#039;B0B0F155-B0B0-B0B0-B0B0-B0B000000101&#039;&#039; and permissions &#039;&#039;READ | DYNAMIC&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0x1b, 0x00, 0x02, 0x00, 0x08, 0x00, 0x03, 0x28, 0x02, 0x09, 0x00, 0x01, 0x01, 0x00, 0x00, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0x55, 0xf1, 0xb0, 0xb0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The bytes are grouped from left to right according to this scheme:&lt;br /&gt;
* 2 bytes for the length of this attribute definition: 0x001b (= 27 bytes)&lt;br /&gt;
* 2 bytes for the access permission of this attribute: 0x0002 (= read-only)&lt;br /&gt;
* 2 bytes for the attribute handle: 0x0008&lt;br /&gt;
* 2 bytes for the attribute type: 0x2803 (short 16-bit UUID that indicates a characteristic declaration)&lt;br /&gt;
* 1 byte for the access permissions of the declared characteristic: 0x02 (= read-only)&lt;br /&gt;
* 2 bytes for the attribute handle of the characteristic value: 0x0009&lt;br /&gt;
* 16 bytes for the 128-bit UUID of the characteristic: 0xb0b0f155b0b0b0b0b0b0b0b000000101&lt;br /&gt;
where &#039;&#039;&#039;the bytes in each group are in reverse order&#039;&#039;&#039;!&lt;br /&gt;
&lt;br /&gt;
For the official specification of the Bluetooth 5.4 GATT characteristic declaration refer to section 3.3.1 in the [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html in the Bluetooth 5.4 Core Specification]. That section also lists the characteristics permissions (or properties):&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin:auto&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Properties !! Value !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Broadcast || 0x01 || If set, permits broadcasts of the Characteristic Value using Server Characteristic Configuration Descriptor. If set, the Server Characteristic Configuration Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
| Read || 0x02 || If set, permits reads of the Characteristic Value using procedures defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-66cf484d-50cd-199f-dd0d-d0d02ad02ce0 Section 4.8]&lt;br /&gt;
|-&lt;br /&gt;
| Write Without Response || 0x04 || If set, permit writes of the Characteristic Value without response using procedures defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-9f1c2e38-8fbe-f60c-d885-076707c88a43 Section 4.9.1].&lt;br /&gt;
|-&lt;br /&gt;
| Write || 0x08 || If set, permits writes of the Characteristic Value with response using procedures defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-ba4b856a-6994-01e4-97f6-357f9be40990 Section 4.9.3] or [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-6ab738ad-6d26-1da1-7417-e83da50e90c5 Section 4.9.4].&lt;br /&gt;
|-&lt;br /&gt;
| Notify || 0x10 || If set, permits notifications of a Characteristic Value without acknowledgment using the procedure defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-74673cc2-e704-a2fa-14bb-d175c27193ab Section 4.10]. If set, the Client Characteristic Configuration Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
| Indicate || 0x20 || If set, permits indications of a Characteristic Value with acknowledgment using the procedure defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-615ed0ff-f42b-827d-6427-6474fc21737c Section 4.11]. If set, the Client Characteristic Configuration Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
| Authenticated Signed Writes || 0x40 || If set, permits signed writes to the Characteristic Value using the procedure defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-516bd731-2079-87f9-8002-c3ca92fbed4b Section 4.9.2].&lt;br /&gt;
|-&lt;br /&gt;
| Extended Properties || 0x80 || If set, additional characteristic properties are defined in the Characteristic Extended Properties Descriptor defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-9154505c-6e2d-a35a-3f30-1da0383a2425 Section 3.3.3.1]. If set, the Characteristic Extended Properties Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== BTStack Python script output for a GATT user description declaration attribute =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0x08, 0x00, 0x0a, 0x01, 0x0a, 0x00, 0x01, 0x29,&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== The BTstack runloop ====&lt;br /&gt;
&lt;br /&gt;
The following articles by Hunter Adams offer a detailed analysis of how BTstack works on the Pico:&lt;br /&gt;
# [https://vanhunteradams.com/Pico/BLE/BTStack_HCI.html BTstack and RP2040: HCI (Host Controller Interface)].&amp;lt;br /&amp;gt;This article delves, among other things, into how the BTstack runloop is executed inside a Pico [[#Async_Context | async_context]].&amp;lt;br /&amp;gt;&amp;lt;blockquote&amp;gt;[...] we have just one &#039;&#039;when_pending_worker&#039;&#039; in our async_context. This worker is called &#039;&#039;cyw43_poll_worker&#039;&#039;, and its &#039;&#039;do_work&#039;&#039; function points to &#039;&#039;cyw43_poll_func()&#039;&#039;, listed above. This function ends up calling &#039;&#039;btstack_run_loop_poll_data_sources_from_irq()&#039;&#039;, about which we&#039;ll learn more shortly. This worker gets marked as pending in a GPIO interrupt. So, this provides a mechanism by which the CYW43 can tell the RP2040 to run &#039;&#039;btstack_run_loop_poll_data_sources_from_irq()&#039;&#039; which, as we&#039;re going to learn, goes and gets data from the device.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
# [https://vanhunteradams.com/Pico/BLE/GATT_Server.html Building a Bluetooth GATT Server on the Pi Pico W]&lt;br /&gt;
&lt;br /&gt;
==== GATT Characteristic read and write operations ====&lt;br /&gt;
&lt;br /&gt;
The struct &amp;lt;code&amp;gt;att_service_handler_t&amp;lt;/code&amp;gt; represents a GATT service. After the fields of the struct have been filled in by the application code, it holds all the information needed for the BLE peripheral to make it available to the BLE central. Some of the fields of the struct hold the ATT handles that define the start and end of the collection of characteristics belonging to the service. Other fields of the struct (&amp;lt;code&amp;gt;read_callback&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;write_callback&amp;lt;/code&amp;gt;) hold pointers to functions that handle reading from and writing to characteristic values.&lt;br /&gt;
&lt;br /&gt;
Note that the &#039;&#039;read&#039;&#039; callback for a descriptor of a GATT characteristic (i.e., an ATT attribute) is called twice. In the first call, the buffer pointer passed to the callback function is NULL. In the second call, it&#039;s a valid pointer. The first call is made by BTstack to query the size of the data that will be returned by the second call. BTstack needs to make sure its transmission buffers can hold the amount of data before making the second call.&lt;br /&gt;
&lt;br /&gt;
At the end of a writing operation, if the characteristic was configured to send back notifications to the BLE peer, one more callback function comes into play. It is part of another struct, &amp;lt;code&amp;gt;btstack_context_callback_registration_t&amp;lt;/code&amp;gt;, that is used for the deferred sending of characteristic update notification to the BLE central. In this callback, &amp;lt;code&amp;gt;att_server_notify()&amp;lt;/code&amp;gt; is called to finally send the write notification to the peer.&lt;/div&gt;</summary>
		<author><name>Kai</name></author>
	</entry>
	<entry>
		<id>https://Robo.Fish/wiki/index.php?title=Raspberry_Pi_Microcontrollers&amp;diff=3282</id>
		<title>Raspberry Pi Microcontrollers</title>
		<link rel="alternate" type="text/html" href="https://Robo.Fish/wiki/index.php?title=Raspberry_Pi_Microcontrollers&amp;diff=3282"/>
		<updated>2025-05-09T19:22:36Z</updated>

		<summary type="html">&lt;p&gt;Kai: /* BTStack Python script output for different attribute permission combinations */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Pico Series =&lt;br /&gt;
* Raspberry Pi Pico and Pico W&lt;br /&gt;
** Dual [https://developer.arm.com/Processors/Cortex-M0-Plus Arm Cortex-M0+] with Armv6-M programming model, up to 133 MHz&lt;br /&gt;
* Raspberry Pi Pico 2 and Pico 2 W&lt;br /&gt;
** Dual [https://developer.arm.com/Processors/Cortex-M33 Arm Cortex-M33] with Armv8-M programming model, up to 150 MHz&lt;br /&gt;
&lt;br /&gt;
== Development Setup ==&lt;br /&gt;
&lt;br /&gt;
=== Using the Raspberry Pi Debug Probe ===&lt;br /&gt;
The Debug Probe is a RP2040 based USB-to-UART/SWD board for connecting the USB slot of a development machine to the SWD or UART pins of a target device.&lt;br /&gt;
&lt;br /&gt;
=== Using A Pico To Debug Another Pico ===&lt;br /&gt;
A Pico can be used to debug another Pico (a.k.a. target device)  by flashing it with the [https://github.com/raspberrypi/debugprobe debugprobe] binary and wiring to the target Pico as shown below.&lt;br /&gt;
&lt;br /&gt;
[[File:Wiring_rpi_pico_as_debugger.png | x320 px | A Raspberry Pi Pico wired to debug another Pico]]&lt;br /&gt;
&lt;br /&gt;
From the debugger Pico to the target Pico,&lt;br /&gt;
* pin #4 (GP2) connects to pin SWCLK,&lt;br /&gt;
* pin #5 (GP3) connects to SWDIO,&lt;br /&gt;
* pin #6 (GP4, UART1 TX) connects to pin #2 (GP1, UART0 RX),&lt;br /&gt;
* pin #7 (GP5, UART1 RX) connects to pin #1 (GP0, UART0, TX).&lt;br /&gt;
&lt;br /&gt;
The debugger Pico serves both as a USB-to-SWD and USB-to-UART bridge to the target device. The development machine, therefore, needs to be connected via USB only to the debugger Pico. Console output on the target Pico is relayed through the debugger. It is possible, though, to connect a second USB cable from the development machine to the target device for (simultaneous) direct access to the console output. This debugger setup works not just with Pico targets but with any microcontroller that supports the CMSIS-DAP protocol over SWD.&lt;br /&gt;
&lt;br /&gt;
=== Software Tools for Debugging ===&lt;br /&gt;
Whether we use the Raspberry Pi Debug Probe or a spare Pico as debug probe, the software tools used for debugging are the same:&lt;br /&gt;
* openocd&lt;br /&gt;
&lt;br /&gt;
== Notes on Programming with the C SDK ==&lt;br /&gt;
&lt;br /&gt;
=== Async Context ===&lt;br /&gt;
In the C SDK, an [https://www.raspberrypi.com/documentation/pico-sdk/high_level.html#group_pico_async_context async_context] is used in concurrent programming to make sure that functions are executed on the same thread and in the order they were submitted, similar to dispatch queues in Apple&#039;s [https://developer.apple.com/documentation/dispatch?language=objc Dispatch framework]. The &#039;&#039;async_context&#039;&#039; data structure is a container of linked lists of worker functions that are executed within a single thread of a single processor core.&lt;br /&gt;
&lt;br /&gt;
=== Bluetooth with BTstack ===&lt;br /&gt;
&lt;br /&gt;
The C SDK integrates the third-party [https://bluekitchen-gmbh.com/btstack BTstack] framework as its Bluetooth API that interfaces with the Infineon CYW43 wireless communication module (on Pico W models) via the Host-Controller Interface (HCI) protocol.&lt;br /&gt;
&lt;br /&gt;
==== Setup ====&lt;br /&gt;
&lt;br /&gt;
Before we can call any BTstack functions (and hope for some meaningful outcome), we need to add a &#039;&#039;&#039;btstack_config.h&#039;&#039;&#039; header file to our project. In it, we add all the compile-time switches that fit our application. On a microcontroller, a frequent use case for BTstack is to implement a BLE peripheral. For this we, our config header should look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#ifndef MY_BTSTACK_CONFIG_H&lt;br /&gt;
#define MY_BTSTACK_CONFIG_H&lt;br /&gt;
&lt;br /&gt;
#ifndef ENABLE_BLE&lt;br /&gt;
#error In CMakeLists.txt add the &#039;pico_btstack_ble&#039; library to target_link_libraries(...)&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// logging&lt;br /&gt;
#define ENABLE_LOG_INFO&lt;br /&gt;
#define ENABLE_LOG_ERROR&lt;br /&gt;
#define ENABLE_PRINTF_HEXDUMP // required for hci_dump_init()&lt;br /&gt;
&lt;br /&gt;
#if 1 // configure as peripheral (GATT server)&lt;br /&gt;
	#define ENABLE_LE_PERIPHERAL&lt;br /&gt;
	#define MAX_NR_GATT_CLIENTS 0&lt;br /&gt;
#else // configure as central (GATT client)&lt;br /&gt;
	#define ENABLE_LE_CENTRAL&lt;br /&gt;
	#define MAX_NR_GATT_CLIENTS 1&lt;br /&gt;
//#define ENABLE_GATT_CLIENT_PAIRING&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// Setting various buffer sizes related to HCI communication&lt;br /&gt;
#define HCI_OUTGOING_PRE_BUFFER_SIZE 4&lt;br /&gt;
#define HCI_ACL_PAYLOAD_SIZE (255 + 4)&lt;br /&gt;
#define HCI_ACL_CHUNK_SIZE_ALIGNMENT 4&lt;br /&gt;
#define MAX_NR_HCI_CONNECTIONS 1&lt;br /&gt;
#define MAX_NR_SM_LOOKUP_ENTRIES 3&lt;br /&gt;
#define MAX_NR_WHITELIST_ENTRIES 16&lt;br /&gt;
#define MAX_NR_LE_DEVICE_DB_ENTRIES 16&lt;br /&gt;
&lt;br /&gt;
// Choosing a fixed-size attributes table over using malloc.&lt;br /&gt;
// We want to use BTstack without heap memory allocations.&lt;br /&gt;
#if 1&lt;br /&gt;
#define MAX_ATT_DB_SIZE 512&lt;br /&gt;
#else&lt;br /&gt;
#define HAVE_MALLOC&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// Enabling timers&lt;br /&gt;
#if 1&lt;br /&gt;
#define HAVE_EMBEDDED_TIME_MS&lt;br /&gt;
#else&lt;br /&gt;
#define HAVE_EMBEDDED_TICK&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// Limiting the amount of nonvolatile (flash) memory used for storing peer bonding information&lt;br /&gt;
#define NVM_NUM_DEVICE_DB_ENTRIES 16&lt;br /&gt;
#define NVM_NUM_LINK_KEYS 16&lt;br /&gt;
&lt;br /&gt;
// Configuring HCI Controller-to-Host flow control and related buffers to avoid overrunning the cyw43 shared bus&lt;br /&gt;
#define ENABLE_HCI_CONTROLLER_TO_HOST_FLOW_CONTROL&lt;br /&gt;
#define HCI_HOST_ACL_PACKET_LEN (255+4)&lt;br /&gt;
#define HCI_HOST_ACL_PACKET_NUM 3&lt;br /&gt;
#define HCI_HOST_SCO_PACKET_LEN 120&lt;br /&gt;
#define HCI_HOST_SCO_PACKET_NUM 3&lt;br /&gt;
#define MAX_NR_CONTROLLER_SCO_PACKETS 3&lt;br /&gt;
#define MAX_NR_CONTROLLER_ACL_BUFFERS 3&lt;br /&gt;
&lt;br /&gt;
// Enabling btstack_assert, acting just like normal assert()&lt;br /&gt;
#define HAVE_ASSERT&lt;br /&gt;
&lt;br /&gt;
// Setting HCI resend timeout in case the Bluetooth module needs more time to response.&lt;br /&gt;
#define HCI_RESET_RESEND_TIMEOUT_MS 800&lt;br /&gt;
&lt;br /&gt;
// Configuring security&lt;br /&gt;
#define ENABLE_SOFTWARE_AES128&lt;br /&gt;
#define ENABLE_MICRO_ECC_FOR_LE_SECURE_CONNECTIONS&lt;br /&gt;
&lt;br /&gt;
#endif // MY_BTSTACK_CONFIG_H&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== GATT Profiles, Services, Characteristics, and Descriptors ====&lt;br /&gt;
&lt;br /&gt;
A Bluetooth Low Energy Peripheral organizes the served data in a linear attributes table or database, referred to as  ATT. The GATT (Generic Attributes) profile used in BLE is, contrary to what the name suggests, a specific organizational structure imposed on the ATT table, where the data table as a whole is referred to as &amp;quot;profile&amp;quot;. The profile attributes can be broken down into consecutive &amp;quot;service&amp;quot; attributes, the service attributes into &amp;quot;characteristic&amp;quot; attributes, the characteristics into &amp;quot;descriptor&amp;quot; attributes. So, all in all there linear ATT table becomes a tree structure with four levels in GATT. A BLE peripheral, acting as a GATT server when connected to, will advertise its profile over GAP. A BLE central, acting as a GATT client after establishing a connection to the peripheral, can read the complete GATT hierarchy to find out about the profile contents.&lt;br /&gt;
&lt;br /&gt;
BTstack allows defining a GATT table as a human-readable text file. The translation of that file into a C header by a Python script is a build step that can be included in &#039;&#039;CMakeLists.txt&#039;&#039; using the function &#039;&#039;pico_btstack_make_gatt_header()&#039;&#039;. The generated C header contains the GATT table as an array of hex-coded bytes, laid out one line per attribute, with comments between the lines for orientation. Application code that needs to access the GATT table data then simply &amp;quot;#include&amp;quot;s this generated header file.&lt;br /&gt;
&lt;br /&gt;
When defining the GATT table in BTstack&#039;s text format, we can use the following keywords for the attribute permissions of a characteristic:&lt;br /&gt;
* READ&lt;br /&gt;
* WRITE&lt;br /&gt;
* WRITE_WITH_RESPONSE&lt;br /&gt;
* NOTIFY: Adds a &#039;&#039;Client Configuration&#039;&#039; descriptor to the characteristic that allows a GATT client to control whether a notification is to be sent to the client each time the value of the characteristic changes.&lt;br /&gt;
* DYNAMIC: Indicates that reading and writing to this characteristic requires adding this case to the read and write callbacks.&lt;br /&gt;
&lt;br /&gt;
===== BTStack Python script output for a GATT characteristic declaration =====&lt;br /&gt;
&lt;br /&gt;
Let&#039;s have a look at the output of the BTstack Python script that converts the .gatt file to a C header and let&#039;s narrow it down to just the characteristic declarations.&lt;br /&gt;
&lt;br /&gt;
Here is the binary sequence (in hex representation) generated for an attribute that declares a GATT characteristic with attribute UUID &#039;&#039;B0B0F155-B0B0-B0B0-B0B0-B0B000000101&#039;&#039; and permissions &#039;&#039;READ | DYNAMIC&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0x1b, 0x00, 0x02, 0x00, 0x08, 0x00, 0x03, 0x28, 0x02, 0x09, 0x00, 0x01, 0x01, 0x00, 0x00, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0x55, 0xf1, 0xb0, 0xb0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The bytes are grouped from left to right according to this scheme:&lt;br /&gt;
* 2 bytes for the length of this attribute definition: 0x001b (= 27 bytes)&lt;br /&gt;
* 2 bytes for the access permission of this attribute: 0x0002 (= read-only)&lt;br /&gt;
* 2 bytes for the attribute handle: 0x0008&lt;br /&gt;
* 2 bytes for the attribute type: 0x2803 (short 16-bit UUID that indicates a characteristic declaration)&lt;br /&gt;
* 1 byte for the access permissions of the declared characteristic: 0x02 (= read-only)&lt;br /&gt;
* 2 bytes for the attribute handle of the characteristic value: 0x0009&lt;br /&gt;
* 16 bytes for the 128-bit UUID of the characteristic: 0xb0b0f155b0b0b0b0b0b0b0b000000101&lt;br /&gt;
where &#039;&#039;&#039;the bytes in each group are in reverse order&#039;&#039;&#039;!&lt;br /&gt;
&lt;br /&gt;
For the official specification of the Bluetooth 5.4 GATT characteristic declaration refer to section 3.3.1 in the [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html in the Bluetooth 5.4 Core Specification]. That section also lists the characteristics permissions (or properties):&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin:auto&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Properties !! Value !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Broadcast || 0x01 || If set, permits broadcasts of the Characteristic Value using Server Characteristic Configuration Descriptor. If set, the Server Characteristic Configuration Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
| Read || 0x02 || If set, permits reads of the Characteristic Value using procedures defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-66cf484d-50cd-199f-dd0d-d0d02ad02ce0 Section 4.8]&lt;br /&gt;
|-&lt;br /&gt;
| Write Without Response || 0x04 || If set, permit writes of the Characteristic Value without response using procedures defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-9f1c2e38-8fbe-f60c-d885-076707c88a43 Section 4.9.1].&lt;br /&gt;
|-&lt;br /&gt;
| Write || 0x08 || If set, permits writes of the Characteristic Value with response using procedures defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-ba4b856a-6994-01e4-97f6-357f9be40990 Section 4.9.3] or [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-6ab738ad-6d26-1da1-7417-e83da50e90c5 Section 4.9.4].&lt;br /&gt;
|-&lt;br /&gt;
| Notify || 0x10 || If set, permits notifications of a Characteristic Value without acknowledgment using the procedure defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-74673cc2-e704-a2fa-14bb-d175c27193ab Section 4.10]. If set, the Client Characteristic Configuration Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
| Indicate || 0x20 || If set, permits indications of a Characteristic Value with acknowledgment using the procedure defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-615ed0ff-f42b-827d-6427-6474fc21737c Section 4.11]. If set, the Client Characteristic Configuration Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
| Authenticated Signed Writes || 0x40 || If set, permits signed writes to the Characteristic Value using the procedure defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-516bd731-2079-87f9-8002-c3ca92fbed4b Section 4.9.2].&lt;br /&gt;
|-&lt;br /&gt;
| Extended Properties || 0x80 || If set, additional characteristic properties are defined in the Characteristic Extended Properties Descriptor defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-9154505c-6e2d-a35a-3f30-1da0383a2425 Section 3.3.3.1]. If set, the Characteristic Extended Properties Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== The BTstack runloop ====&lt;br /&gt;
&lt;br /&gt;
The following articles by Hunter Adams offer a detailed analysis of how BTstack works on the Pico:&lt;br /&gt;
# [https://vanhunteradams.com/Pico/BLE/BTStack_HCI.html BTstack and RP2040: HCI (Host Controller Interface)].&amp;lt;br /&amp;gt;This article delves, among other things, into how the BTstack runloop is executed inside a Pico [[#Async_Context | async_context]].&amp;lt;br /&amp;gt;&amp;lt;blockquote&amp;gt;[...] we have just one &#039;&#039;when_pending_worker&#039;&#039; in our async_context. This worker is called &#039;&#039;cyw43_poll_worker&#039;&#039;, and its &#039;&#039;do_work&#039;&#039; function points to &#039;&#039;cyw43_poll_func()&#039;&#039;, listed above. This function ends up calling &#039;&#039;btstack_run_loop_poll_data_sources_from_irq()&#039;&#039;, about which we&#039;ll learn more shortly. This worker gets marked as pending in a GPIO interrupt. So, this provides a mechanism by which the CYW43 can tell the RP2040 to run &#039;&#039;btstack_run_loop_poll_data_sources_from_irq()&#039;&#039; which, as we&#039;re going to learn, goes and gets data from the device.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
# [https://vanhunteradams.com/Pico/BLE/GATT_Server.html Building a Bluetooth GATT Server on the Pi Pico W]&lt;br /&gt;
&lt;br /&gt;
==== GATT Characteristic read and write operations ====&lt;br /&gt;
&lt;br /&gt;
The struct &amp;lt;code&amp;gt;att_service_handler_t&amp;lt;/code&amp;gt; represents a GATT service. After the fields of the struct have been filled in by the application code, it holds all the information needed for the BLE peripheral to make it available to the BLE central. Some of the fields of the struct hold the ATT handles that define the start and end of the collection of characteristics belonging to the service. Other fields of the struct (&amp;lt;code&amp;gt;read_callback&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;write_callback&amp;lt;/code&amp;gt;) hold pointers to functions that handle reading from and writing to characteristic values.&lt;br /&gt;
&lt;br /&gt;
Note that the &#039;&#039;read&#039;&#039; callback for a descriptor of a GATT characteristic (i.e., an ATT attribute) is called twice. In the first call, the buffer pointer passed to the callback function is NULL. In the second call, it&#039;s a valid pointer. The first call is made by BTstack to query the size of the data that will be returned by the second call. BTstack needs to make sure its transmission buffers can hold the amount of data before making the second call.&lt;br /&gt;
&lt;br /&gt;
At the end of a writing operation, if the characteristic was configured to send back notifications to the BLE peer, one more callback function comes into play. It is part of another struct, &amp;lt;code&amp;gt;btstack_context_callback_registration_t&amp;lt;/code&amp;gt;, that is used for the deferred sending of characteristic update notification to the BLE central. In this callback, &amp;lt;code&amp;gt;att_server_notify()&amp;lt;/code&amp;gt; is called to finally send the write notification to the peer.&lt;/div&gt;</summary>
		<author><name>Kai</name></author>
	</entry>
	<entry>
		<id>https://Robo.Fish/wiki/index.php?title=Raspberry_Pi_Microcontrollers&amp;diff=3281</id>
		<title>Raspberry Pi Microcontrollers</title>
		<link rel="alternate" type="text/html" href="https://Robo.Fish/wiki/index.php?title=Raspberry_Pi_Microcontrollers&amp;diff=3281"/>
		<updated>2025-05-09T19:18:57Z</updated>

		<summary type="html">&lt;p&gt;Kai: Expanding on the GATT attribute that declares a characteristic&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Pico Series =&lt;br /&gt;
* Raspberry Pi Pico and Pico W&lt;br /&gt;
** Dual [https://developer.arm.com/Processors/Cortex-M0-Plus Arm Cortex-M0+] with Armv6-M programming model, up to 133 MHz&lt;br /&gt;
* Raspberry Pi Pico 2 and Pico 2 W&lt;br /&gt;
** Dual [https://developer.arm.com/Processors/Cortex-M33 Arm Cortex-M33] with Armv8-M programming model, up to 150 MHz&lt;br /&gt;
&lt;br /&gt;
== Development Setup ==&lt;br /&gt;
&lt;br /&gt;
=== Using the Raspberry Pi Debug Probe ===&lt;br /&gt;
The Debug Probe is a RP2040 based USB-to-UART/SWD board for connecting the USB slot of a development machine to the SWD or UART pins of a target device.&lt;br /&gt;
&lt;br /&gt;
=== Using A Pico To Debug Another Pico ===&lt;br /&gt;
A Pico can be used to debug another Pico (a.k.a. target device)  by flashing it with the [https://github.com/raspberrypi/debugprobe debugprobe] binary and wiring to the target Pico as shown below.&lt;br /&gt;
&lt;br /&gt;
[[File:Wiring_rpi_pico_as_debugger.png | x320 px | A Raspberry Pi Pico wired to debug another Pico]]&lt;br /&gt;
&lt;br /&gt;
From the debugger Pico to the target Pico,&lt;br /&gt;
* pin #4 (GP2) connects to pin SWCLK,&lt;br /&gt;
* pin #5 (GP3) connects to SWDIO,&lt;br /&gt;
* pin #6 (GP4, UART1 TX) connects to pin #2 (GP1, UART0 RX),&lt;br /&gt;
* pin #7 (GP5, UART1 RX) connects to pin #1 (GP0, UART0, TX).&lt;br /&gt;
&lt;br /&gt;
The debugger Pico serves both as a USB-to-SWD and USB-to-UART bridge to the target device. The development machine, therefore, needs to be connected via USB only to the debugger Pico. Console output on the target Pico is relayed through the debugger. It is possible, though, to connect a second USB cable from the development machine to the target device for (simultaneous) direct access to the console output. This debugger setup works not just with Pico targets but with any microcontroller that supports the CMSIS-DAP protocol over SWD.&lt;br /&gt;
&lt;br /&gt;
=== Software Tools for Debugging ===&lt;br /&gt;
Whether we use the Raspberry Pi Debug Probe or a spare Pico as debug probe, the software tools used for debugging are the same:&lt;br /&gt;
* openocd&lt;br /&gt;
&lt;br /&gt;
== Notes on Programming with the C SDK ==&lt;br /&gt;
&lt;br /&gt;
=== Async Context ===&lt;br /&gt;
In the C SDK, an [https://www.raspberrypi.com/documentation/pico-sdk/high_level.html#group_pico_async_context async_context] is used in concurrent programming to make sure that functions are executed on the same thread and in the order they were submitted, similar to dispatch queues in Apple&#039;s [https://developer.apple.com/documentation/dispatch?language=objc Dispatch framework]. The &#039;&#039;async_context&#039;&#039; data structure is a container of linked lists of worker functions that are executed within a single thread of a single processor core.&lt;br /&gt;
&lt;br /&gt;
=== Bluetooth with BTstack ===&lt;br /&gt;
&lt;br /&gt;
The C SDK integrates the third-party [https://bluekitchen-gmbh.com/btstack BTstack] framework as its Bluetooth API that interfaces with the Infineon CYW43 wireless communication module (on Pico W models) via the Host-Controller Interface (HCI) protocol.&lt;br /&gt;
&lt;br /&gt;
==== Setup ====&lt;br /&gt;
&lt;br /&gt;
Before we can call any BTstack functions (and hope for some meaningful outcome), we need to add a &#039;&#039;&#039;btstack_config.h&#039;&#039;&#039; header file to our project. In it, we add all the compile-time switches that fit our application. On a microcontroller, a frequent use case for BTstack is to implement a BLE peripheral. For this we, our config header should look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#ifndef MY_BTSTACK_CONFIG_H&lt;br /&gt;
#define MY_BTSTACK_CONFIG_H&lt;br /&gt;
&lt;br /&gt;
#ifndef ENABLE_BLE&lt;br /&gt;
#error In CMakeLists.txt add the &#039;pico_btstack_ble&#039; library to target_link_libraries(...)&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// logging&lt;br /&gt;
#define ENABLE_LOG_INFO&lt;br /&gt;
#define ENABLE_LOG_ERROR&lt;br /&gt;
#define ENABLE_PRINTF_HEXDUMP // required for hci_dump_init()&lt;br /&gt;
&lt;br /&gt;
#if 1 // configure as peripheral (GATT server)&lt;br /&gt;
	#define ENABLE_LE_PERIPHERAL&lt;br /&gt;
	#define MAX_NR_GATT_CLIENTS 0&lt;br /&gt;
#else // configure as central (GATT client)&lt;br /&gt;
	#define ENABLE_LE_CENTRAL&lt;br /&gt;
	#define MAX_NR_GATT_CLIENTS 1&lt;br /&gt;
//#define ENABLE_GATT_CLIENT_PAIRING&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// Setting various buffer sizes related to HCI communication&lt;br /&gt;
#define HCI_OUTGOING_PRE_BUFFER_SIZE 4&lt;br /&gt;
#define HCI_ACL_PAYLOAD_SIZE (255 + 4)&lt;br /&gt;
#define HCI_ACL_CHUNK_SIZE_ALIGNMENT 4&lt;br /&gt;
#define MAX_NR_HCI_CONNECTIONS 1&lt;br /&gt;
#define MAX_NR_SM_LOOKUP_ENTRIES 3&lt;br /&gt;
#define MAX_NR_WHITELIST_ENTRIES 16&lt;br /&gt;
#define MAX_NR_LE_DEVICE_DB_ENTRIES 16&lt;br /&gt;
&lt;br /&gt;
// Choosing a fixed-size attributes table over using malloc.&lt;br /&gt;
// We want to use BTstack without heap memory allocations.&lt;br /&gt;
#if 1&lt;br /&gt;
#define MAX_ATT_DB_SIZE 512&lt;br /&gt;
#else&lt;br /&gt;
#define HAVE_MALLOC&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// Enabling timers&lt;br /&gt;
#if 1&lt;br /&gt;
#define HAVE_EMBEDDED_TIME_MS&lt;br /&gt;
#else&lt;br /&gt;
#define HAVE_EMBEDDED_TICK&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// Limiting the amount of nonvolatile (flash) memory used for storing peer bonding information&lt;br /&gt;
#define NVM_NUM_DEVICE_DB_ENTRIES 16&lt;br /&gt;
#define NVM_NUM_LINK_KEYS 16&lt;br /&gt;
&lt;br /&gt;
// Configuring HCI Controller-to-Host flow control and related buffers to avoid overrunning the cyw43 shared bus&lt;br /&gt;
#define ENABLE_HCI_CONTROLLER_TO_HOST_FLOW_CONTROL&lt;br /&gt;
#define HCI_HOST_ACL_PACKET_LEN (255+4)&lt;br /&gt;
#define HCI_HOST_ACL_PACKET_NUM 3&lt;br /&gt;
#define HCI_HOST_SCO_PACKET_LEN 120&lt;br /&gt;
#define HCI_HOST_SCO_PACKET_NUM 3&lt;br /&gt;
#define MAX_NR_CONTROLLER_SCO_PACKETS 3&lt;br /&gt;
#define MAX_NR_CONTROLLER_ACL_BUFFERS 3&lt;br /&gt;
&lt;br /&gt;
// Enabling btstack_assert, acting just like normal assert()&lt;br /&gt;
#define HAVE_ASSERT&lt;br /&gt;
&lt;br /&gt;
// Setting HCI resend timeout in case the Bluetooth module needs more time to response.&lt;br /&gt;
#define HCI_RESET_RESEND_TIMEOUT_MS 800&lt;br /&gt;
&lt;br /&gt;
// Configuring security&lt;br /&gt;
#define ENABLE_SOFTWARE_AES128&lt;br /&gt;
#define ENABLE_MICRO_ECC_FOR_LE_SECURE_CONNECTIONS&lt;br /&gt;
&lt;br /&gt;
#endif // MY_BTSTACK_CONFIG_H&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== GATT Profiles, Services, Characteristics, and Descriptors ====&lt;br /&gt;
&lt;br /&gt;
A Bluetooth Low Energy Peripheral organizes the served data in a linear attributes table or database, referred to as  ATT. The GATT (Generic Attributes) profile used in BLE is, contrary to what the name suggests, a specific organizational structure imposed on the ATT table, where the data table as a whole is referred to as &amp;quot;profile&amp;quot;. The profile attributes can be broken down into consecutive &amp;quot;service&amp;quot; attributes, the service attributes into &amp;quot;characteristic&amp;quot; attributes, the characteristics into &amp;quot;descriptor&amp;quot; attributes. So, all in all there linear ATT table becomes a tree structure with four levels in GATT. A BLE peripheral, acting as a GATT server when connected to, will advertise its profile over GAP. A BLE central, acting as a GATT client after establishing a connection to the peripheral, can read the complete GATT hierarchy to find out about the profile contents.&lt;br /&gt;
&lt;br /&gt;
BTstack allows defining a GATT table as a human-readable text file. The translation of that file into a C header by a Python script is a build step that can be included in &#039;&#039;CMakeLists.txt&#039;&#039; using the function &#039;&#039;pico_btstack_make_gatt_header()&#039;&#039;. The generated C header contains the GATT table as an array of hex-coded bytes, laid out one line per attribute, with comments between the lines for orientation. Application code that needs to access the GATT table data then simply &amp;quot;#include&amp;quot;s this generated header file.&lt;br /&gt;
&lt;br /&gt;
When defining the GATT table in BTstack&#039;s text format, we can use the following keywords for the attribute permissions of a characteristic:&lt;br /&gt;
* READ&lt;br /&gt;
* WRITE&lt;br /&gt;
* WRITE_WITH_RESPONSE&lt;br /&gt;
* NOTIFY: Adds a &#039;&#039;Client Configuration&#039;&#039; descriptor to the characteristic that allows a GATT client to control whether a notification is to be sent to the client each time the value of the characteristic changes.&lt;br /&gt;
* DYNAMIC: Indicates that reading and writing to this characteristic requires adding this case to the read and write callbacks.&lt;br /&gt;
&lt;br /&gt;
===== BTStack Python script output for different attribute permission combinations =====&lt;br /&gt;
&lt;br /&gt;
Let&#039;s have a look at the output of the BTstack Python script that converts the .gatt file to a C header and let&#039;s narrow it down to just the characteristic declarations.&lt;br /&gt;
&lt;br /&gt;
Here is the binary sequence (in hex representation) generated for an attribute that declares a GATT characteristic with attribute UUID &#039;&#039;B0B0F155-B0B0-B0B0-B0B0-B0B000000101&#039;&#039; and permissions &#039;&#039;READ | DYNAMIC&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
0x1b, 0x00, 0x02, 0x00, 0x08, 0x00, 0x03, 0x28, 0x02, 0x09, 0x00, 0x01, 0x01, 0x00, 0x00, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0x55, 0xf1, 0xb0, 0xb0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
The bytes are grouped from left to right according to this scheme:&lt;br /&gt;
* 2 bytes for the length of this attribute definition: 0x001b (= 27 bytes)&lt;br /&gt;
* 2 bytes for the access permission of this attribute: 0x0002 (= read-only)&lt;br /&gt;
* 2 bytes for the attribute handle: 0x0008&lt;br /&gt;
* 2 bytes for the attribute type: 0x2803 (short 16-bit UUID that indicates a characteristic declaration)&lt;br /&gt;
* 1 byte for the access permissions of the declared characteristic: 0x02 (= read-only)&lt;br /&gt;
* 2 bytes for the attribute handle of the characteristic value: 0x0009&lt;br /&gt;
* 16 bytes for the 128-bit UUID of the characteristic: 0xb0b0f155b0b0b0b0b0b0b0b000000101&lt;br /&gt;
where &#039;&#039;&#039;the bytes in each group are in reverse order&#039;&#039;&#039;!&lt;br /&gt;
&lt;br /&gt;
For the official specification of the Bluetooth 5.4 GATT characteristic declaration refer to section 3.3.1 in the [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html in the Bluetooth 5.4 Core Specification]. That section also lists the characteristics permissions (or properties):&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin:auto&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Properties !! Value !! Description&lt;br /&gt;
|-&lt;br /&gt;
| Broadcast || 0x01 || If set, permits broadcasts of the Characteristic Value using Server Characteristic Configuration Descriptor. If set, the Server Characteristic Configuration Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
| Read || 0x02 || If set, permits reads of the Characteristic Value using procedures defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-66cf484d-50cd-199f-dd0d-d0d02ad02ce0 Section 4.8]&lt;br /&gt;
|-&lt;br /&gt;
| Write Without Response || 0x04 || If set, permit writes of the Characteristic Value without response using procedures defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-9f1c2e38-8fbe-f60c-d885-076707c88a43 Section 4.9.1].&lt;br /&gt;
|-&lt;br /&gt;
| Write || 0x08 || If set, permits writes of the Characteristic Value with response using procedures defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-ba4b856a-6994-01e4-97f6-357f9be40990 Section 4.9.3] or [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-6ab738ad-6d26-1da1-7417-e83da50e90c5 Section 4.9.4].&lt;br /&gt;
|-&lt;br /&gt;
| Notify || 0x10 || If set, permits notifications of a Characteristic Value without acknowledgment using the procedure defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-74673cc2-e704-a2fa-14bb-d175c27193ab Section 4.10]. If set, the Client Characteristic Configuration Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
| Indicate || 0x20 || If set, permits indications of a Characteristic Value with acknowledgment using the procedure defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-615ed0ff-f42b-827d-6427-6474fc21737c Section 4.11]. If set, the Client Characteristic Configuration Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
| Authenticated Signed Writes || 0x40 || If set, permits signed writes to the Characteristic Value using the procedure defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-516bd731-2079-87f9-8002-c3ca92fbed4b Section 4.9.2].&lt;br /&gt;
|-&lt;br /&gt;
| Extended Properties || 0x80 || If set, additional characteristic properties are defined in the Characteristic Extended Properties Descriptor defined in [https://www.bluetooth.com/wp-content/uploads/Files/Specification/HTML/Core-54/out/en/host/generic-attribute-profile--gatt-.html#UUID-9154505c-6e2d-a35a-3f30-1da0383a2425 Section 3.3.3.1]. If set, the Characteristic Extended Properties Descriptor shall exist.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== The BTstack runloop ====&lt;br /&gt;
&lt;br /&gt;
The following articles by Hunter Adams offer a detailed analysis of how BTstack works on the Pico:&lt;br /&gt;
# [https://vanhunteradams.com/Pico/BLE/BTStack_HCI.html BTstack and RP2040: HCI (Host Controller Interface)].&amp;lt;br /&amp;gt;This article delves, among other things, into how the BTstack runloop is executed inside a Pico [[#Async_Context | async_context]].&amp;lt;br /&amp;gt;&amp;lt;blockquote&amp;gt;[...] we have just one &#039;&#039;when_pending_worker&#039;&#039; in our async_context. This worker is called &#039;&#039;cyw43_poll_worker&#039;&#039;, and its &#039;&#039;do_work&#039;&#039; function points to &#039;&#039;cyw43_poll_func()&#039;&#039;, listed above. This function ends up calling &#039;&#039;btstack_run_loop_poll_data_sources_from_irq()&#039;&#039;, about which we&#039;ll learn more shortly. This worker gets marked as pending in a GPIO interrupt. So, this provides a mechanism by which the CYW43 can tell the RP2040 to run &#039;&#039;btstack_run_loop_poll_data_sources_from_irq()&#039;&#039; which, as we&#039;re going to learn, goes and gets data from the device.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
# [https://vanhunteradams.com/Pico/BLE/GATT_Server.html Building a Bluetooth GATT Server on the Pi Pico W]&lt;br /&gt;
&lt;br /&gt;
==== GATT Characteristic read and write operations ====&lt;br /&gt;
&lt;br /&gt;
The struct &amp;lt;code&amp;gt;att_service_handler_t&amp;lt;/code&amp;gt; represents a GATT service. After the fields of the struct have been filled in by the application code, it holds all the information needed for the BLE peripheral to make it available to the BLE central. Some of the fields of the struct hold the ATT handles that define the start and end of the collection of characteristics belonging to the service. Other fields of the struct (&amp;lt;code&amp;gt;read_callback&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;write_callback&amp;lt;/code&amp;gt;) hold pointers to functions that handle reading from and writing to characteristic values.&lt;br /&gt;
&lt;br /&gt;
Note that the &#039;&#039;read&#039;&#039; callback for a descriptor of a GATT characteristic (i.e., an ATT attribute) is called twice. In the first call, the buffer pointer passed to the callback function is NULL. In the second call, it&#039;s a valid pointer. The first call is made by BTstack to query the size of the data that will be returned by the second call. BTstack needs to make sure its transmission buffers can hold the amount of data before making the second call.&lt;br /&gt;
&lt;br /&gt;
At the end of a writing operation, if the characteristic was configured to send back notifications to the BLE peer, one more callback function comes into play. It is part of another struct, &amp;lt;code&amp;gt;btstack_context_callback_registration_t&amp;lt;/code&amp;gt;, that is used for the deferred sending of characteristic update notification to the BLE central. In this callback, &amp;lt;code&amp;gt;att_server_notify()&amp;lt;/code&amp;gt; is called to finally send the write notification to the peer.&lt;/div&gt;</summary>
		<author><name>Kai</name></author>
	</entry>
	<entry>
		<id>https://Robo.Fish/wiki/index.php?title=Raspberry_Pi_Microcontrollers&amp;diff=3280</id>
		<title>Raspberry Pi Microcontrollers</title>
		<link rel="alternate" type="text/html" href="https://Robo.Fish/wiki/index.php?title=Raspberry_Pi_Microcontrollers&amp;diff=3280"/>
		<updated>2025-05-08T21:19:15Z</updated>

		<summary type="html">&lt;p&gt;Kai: Adding information about BLE GATT tables and BTstack&amp;#039;s GATT files.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Pico Series =&lt;br /&gt;
* Raspberry Pi Pico and Pico W&lt;br /&gt;
** Dual [https://developer.arm.com/Processors/Cortex-M0-Plus Arm Cortex-M0+] with Armv6-M programming model, up to 133 MHz&lt;br /&gt;
* Raspberry Pi Pico 2 and Pico 2 W&lt;br /&gt;
** Dual [https://developer.arm.com/Processors/Cortex-M33 Arm Cortex-M33] with Armv8-M programming model, up to 150 MHz&lt;br /&gt;
&lt;br /&gt;
== Development Setup ==&lt;br /&gt;
&lt;br /&gt;
=== Using the Raspberry Pi Debug Probe ===&lt;br /&gt;
The Debug Probe is a RP2040 based USB-to-UART/SWD board for connecting the USB slot of a development machine to the SWD or UART pins of a target device.&lt;br /&gt;
&lt;br /&gt;
=== Using A Pico To Debug Another Pico ===&lt;br /&gt;
A Pico can be used to debug another Pico (a.k.a. target device)  by flashing it with the [https://github.com/raspberrypi/debugprobe debugprobe] binary and wiring to the target Pico as shown below.&lt;br /&gt;
&lt;br /&gt;
[[File:Wiring_rpi_pico_as_debugger.png | x320 px | A Raspberry Pi Pico wired to debug another Pico]]&lt;br /&gt;
&lt;br /&gt;
From the debugger Pico to the target Pico,&lt;br /&gt;
* pin #4 (GP2) connects to pin SWCLK,&lt;br /&gt;
* pin #5 (GP3) connects to SWDIO,&lt;br /&gt;
* pin #6 (GP4, UART1 TX) connects to pin #2 (GP1, UART0 RX),&lt;br /&gt;
* pin #7 (GP5, UART1 RX) connects to pin #1 (GP0, UART0, TX).&lt;br /&gt;
&lt;br /&gt;
The debugger Pico serves both as a USB-to-SWD and USB-to-UART bridge to the target device. The development machine, therefore, needs to be connected via USB only to the debugger Pico. Console output on the target Pico is relayed through the debugger. It is possible, though, to connect a second USB cable from the development machine to the target device for (simultaneous) direct access to the console output. This debugger setup works not just with Pico targets but with any microcontroller that supports the CMSIS-DAP protocol over SWD.&lt;br /&gt;
&lt;br /&gt;
=== Software Tools for Debugging ===&lt;br /&gt;
Whether we use the Raspberry Pi Debug Probe or a spare Pico as debug probe, the software tools used for debugging are the same:&lt;br /&gt;
* openocd&lt;br /&gt;
&lt;br /&gt;
== Notes on Programming with the C SDK ==&lt;br /&gt;
&lt;br /&gt;
=== Async Context ===&lt;br /&gt;
In the C SDK, an [https://www.raspberrypi.com/documentation/pico-sdk/high_level.html#group_pico_async_context async_context] is used in concurrent programming to make sure that functions are executed on the same thread and in the order they were submitted, similar to dispatch queues in Apple&#039;s [https://developer.apple.com/documentation/dispatch?language=objc Dispatch framework]. The &#039;&#039;async_context&#039;&#039; data structure is a container of linked lists of worker functions that are executed within a single thread of a single processor core.&lt;br /&gt;
&lt;br /&gt;
=== Bluetooth with BTstack ===&lt;br /&gt;
&lt;br /&gt;
The C SDK integrates the third-party [https://bluekitchen-gmbh.com/btstack BTstack] framework as its Bluetooth API that interfaces with the Infineon CYW43 wireless communication module (on Pico W models) via the Host-Controller Interface (HCI) protocol.&lt;br /&gt;
&lt;br /&gt;
==== Setup ====&lt;br /&gt;
&lt;br /&gt;
Before we can call any BTstack functions (and hope for some meaningful outcome), we need to add a &#039;&#039;&#039;btstack_config.h&#039;&#039;&#039; header file to our project. In it, we add all the compile-time switches that fit our application. On a microcontroller, a frequent use case for BTstack is to implement a BLE peripheral. For this we, our config header should look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#ifndef MY_BTSTACK_CONFIG_H&lt;br /&gt;
#define MY_BTSTACK_CONFIG_H&lt;br /&gt;
&lt;br /&gt;
#ifndef ENABLE_BLE&lt;br /&gt;
#error In CMakeLists.txt add the &#039;pico_btstack_ble&#039; library to target_link_libraries(...)&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// logging&lt;br /&gt;
#define ENABLE_LOG_INFO&lt;br /&gt;
#define ENABLE_LOG_ERROR&lt;br /&gt;
#define ENABLE_PRINTF_HEXDUMP // required for hci_dump_init()&lt;br /&gt;
&lt;br /&gt;
#if 1 // configure as peripheral (GATT server)&lt;br /&gt;
	#define ENABLE_LE_PERIPHERAL&lt;br /&gt;
	#define MAX_NR_GATT_CLIENTS 0&lt;br /&gt;
#else // configure as central (GATT client)&lt;br /&gt;
	#define ENABLE_LE_CENTRAL&lt;br /&gt;
	#define MAX_NR_GATT_CLIENTS 1&lt;br /&gt;
//#define ENABLE_GATT_CLIENT_PAIRING&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// Setting various buffer sizes related to HCI communication&lt;br /&gt;
#define HCI_OUTGOING_PRE_BUFFER_SIZE 4&lt;br /&gt;
#define HCI_ACL_PAYLOAD_SIZE (255 + 4)&lt;br /&gt;
#define HCI_ACL_CHUNK_SIZE_ALIGNMENT 4&lt;br /&gt;
#define MAX_NR_HCI_CONNECTIONS 1&lt;br /&gt;
#define MAX_NR_SM_LOOKUP_ENTRIES 3&lt;br /&gt;
#define MAX_NR_WHITELIST_ENTRIES 16&lt;br /&gt;
#define MAX_NR_LE_DEVICE_DB_ENTRIES 16&lt;br /&gt;
&lt;br /&gt;
// Choosing a fixed-size attributes table over using malloc.&lt;br /&gt;
// We want to use BTstack without heap memory allocations.&lt;br /&gt;
#if 1&lt;br /&gt;
#define MAX_ATT_DB_SIZE 512&lt;br /&gt;
#else&lt;br /&gt;
#define HAVE_MALLOC&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// Enabling timers&lt;br /&gt;
#if 1&lt;br /&gt;
#define HAVE_EMBEDDED_TIME_MS&lt;br /&gt;
#else&lt;br /&gt;
#define HAVE_EMBEDDED_TICK&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// Limiting the amount of nonvolatile (flash) memory used for storing peer bonding information&lt;br /&gt;
#define NVM_NUM_DEVICE_DB_ENTRIES 16&lt;br /&gt;
#define NVM_NUM_LINK_KEYS 16&lt;br /&gt;
&lt;br /&gt;
// Configuring HCI Controller-to-Host flow control and related buffers to avoid overrunning the cyw43 shared bus&lt;br /&gt;
#define ENABLE_HCI_CONTROLLER_TO_HOST_FLOW_CONTROL&lt;br /&gt;
#define HCI_HOST_ACL_PACKET_LEN (255+4)&lt;br /&gt;
#define HCI_HOST_ACL_PACKET_NUM 3&lt;br /&gt;
#define HCI_HOST_SCO_PACKET_LEN 120&lt;br /&gt;
#define HCI_HOST_SCO_PACKET_NUM 3&lt;br /&gt;
#define MAX_NR_CONTROLLER_SCO_PACKETS 3&lt;br /&gt;
#define MAX_NR_CONTROLLER_ACL_BUFFERS 3&lt;br /&gt;
&lt;br /&gt;
// Enabling btstack_assert, acting just like normal assert()&lt;br /&gt;
#define HAVE_ASSERT&lt;br /&gt;
&lt;br /&gt;
// Setting HCI resend timeout in case the Bluetooth module needs more time to response.&lt;br /&gt;
#define HCI_RESET_RESEND_TIMEOUT_MS 800&lt;br /&gt;
&lt;br /&gt;
// Configuring security&lt;br /&gt;
#define ENABLE_SOFTWARE_AES128&lt;br /&gt;
#define ENABLE_MICRO_ECC_FOR_LE_SECURE_CONNECTIONS&lt;br /&gt;
&lt;br /&gt;
#endif // MY_BTSTACK_CONFIG_H&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== GATT Profiles, Services, Characteristics, and Descriptors ====&lt;br /&gt;
&lt;br /&gt;
A Bluetooth Low Energy Peripheral organizes the served data in a linear attributes table or database, referred to as  ATT. The GATT (Generic Attributes) profile used in BLE is, contrary to what the name suggests, a specific organizational structure imposed on the ATT table, where the data table as a whole is referred to as &amp;quot;profile&amp;quot;. The profile attributes can be broken down into consecutive &amp;quot;service&amp;quot; attributes, the service attributes into &amp;quot;characteristic&amp;quot; attributes, the characteristics into &amp;quot;descriptor&amp;quot; attributes. So, all in all there linear ATT table becomes a tree structure with four levels in GATT. A BLE peripheral, acting as a GATT server when connected to, will advertise its profile over GAP. A BLE central, acting as a GATT client after establishing a connection to the peripheral, can read the complete GATT hierarchy to find out about the profile contents.&lt;br /&gt;
&lt;br /&gt;
BTstack allows defining a GATT table as a human-readable text file. The translation of that file into a C header by a Python script is a build step that can be included in &#039;&#039;CMakeLists.txt&#039;&#039; using the function &#039;&#039;pico_btstack_make_gatt_header()&#039;&#039;. The generated C header contains the GATT table as an array of hex-coded bytes, laid out one line per attribute, with comments between the lines for orientation. Application code that needs to access the GATT table data then simply &amp;quot;#include&amp;quot;s this generated header file.&lt;br /&gt;
&lt;br /&gt;
When defining the GATT table in BTstack&#039;s text format, we can use the following keywords for the attribute permissions of a characteristic:&lt;br /&gt;
* READ&lt;br /&gt;
* WRITE&lt;br /&gt;
* WRITE_WITH_RESPONSE&lt;br /&gt;
* NOTIFY: Adds a &#039;&#039;Client Configuration&#039;&#039; descriptor to the characteristic that allows a GATT client to control whether a notification is to be sent to the client each time the value of the characteristic changes.&lt;br /&gt;
* DYNAMIC&lt;br /&gt;
&lt;br /&gt;
==== The BTstack runloop ====&lt;br /&gt;
&lt;br /&gt;
The following articles by Hunter Adams offer a detailed analysis of how BTstack works on the Pico:&lt;br /&gt;
# [https://vanhunteradams.com/Pico/BLE/BTStack_HCI.html BTstack and RP2040: HCI (Host Controller Interface)].&amp;lt;br /&amp;gt;This article delves, among other things, into how the BTstack runloop is executed inside a Pico [[#Async_Context | async_context]].&amp;lt;br /&amp;gt;&amp;lt;blockquote&amp;gt;[...] we have just one &#039;&#039;when_pending_worker&#039;&#039; in our async_context. This worker is called &#039;&#039;cyw43_poll_worker&#039;&#039;, and its &#039;&#039;do_work&#039;&#039; function points to &#039;&#039;cyw43_poll_func()&#039;&#039;, listed above. This function ends up calling &#039;&#039;btstack_run_loop_poll_data_sources_from_irq()&#039;&#039;, about which we&#039;ll learn more shortly. This worker gets marked as pending in a GPIO interrupt. So, this provides a mechanism by which the CYW43 can tell the RP2040 to run &#039;&#039;btstack_run_loop_poll_data_sources_from_irq()&#039;&#039; which, as we&#039;re going to learn, goes and gets data from the device.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
# [https://vanhunteradams.com/Pico/BLE/GATT_Server.html Building a Bluetooth GATT Server on the Pi Pico W]&lt;br /&gt;
&lt;br /&gt;
==== GATT Characteristic read and write operations ====&lt;br /&gt;
&lt;br /&gt;
The struct &amp;lt;code&amp;gt;att_service_handler_t&amp;lt;/code&amp;gt; represents a GATT service. After the fields of the struct have been filled in by the application code, it holds all the information needed for the BLE peripheral to make it available to the BLE central. Some of the fields of the struct hold the ATT handles that define the start and end of the collection of characteristics belonging to the service. Other fields of the struct (&amp;lt;code&amp;gt;read_callback&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;write_callback&amp;lt;/code&amp;gt;) hold pointers to functions that handle reading from and writing to characteristic values.&lt;br /&gt;
&lt;br /&gt;
Note that the &#039;&#039;read&#039;&#039; callback for a descriptor of a GATT characteristic (i.e., an ATT attribute) is called twice. In the first call, the buffer pointer passed to the callback function is NULL. In the second call, it&#039;s a valid pointer. The first call is made by BTstack to query the size of the data that will be returned by the second call. BTstack needs to make sure its transmission buffers can hold the amount of data before making the second call.&lt;br /&gt;
&lt;br /&gt;
At the end of a writing operation, if the characteristic was configured to send back notifications to the BLE peer, one more callback function comes into play. It is part of another struct, &amp;lt;code&amp;gt;btstack_context_callback_registration_t&amp;lt;/code&amp;gt;, that is used for the deferred sending of characteristic update notification to the BLE central. In this callback, &amp;lt;code&amp;gt;att_server_notify()&amp;lt;/code&amp;gt; is called to finally send the write notification to the peer.&lt;/div&gt;</summary>
		<author><name>Kai</name></author>
	</entry>
	<entry>
		<id>https://Robo.Fish/wiki/index.php?title=Raspberry_Pi_Microcontrollers&amp;diff=3279</id>
		<title>Raspberry Pi Microcontrollers</title>
		<link rel="alternate" type="text/html" href="https://Robo.Fish/wiki/index.php?title=Raspberry_Pi_Microcontrollers&amp;diff=3279"/>
		<updated>2025-05-08T08:44:53Z</updated>

		<summary type="html">&lt;p&gt;Kai: /* Setup */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Pico Series =&lt;br /&gt;
* Raspberry Pi Pico and Pico W&lt;br /&gt;
** Dual [https://developer.arm.com/Processors/Cortex-M0-Plus Arm Cortex-M0+] with Armv6-M programming model, up to 133 MHz&lt;br /&gt;
* Raspberry Pi Pico 2 and Pico 2 W&lt;br /&gt;
** Dual [https://developer.arm.com/Processors/Cortex-M33 Arm Cortex-M33] with Armv8-M programming model, up to 150 MHz&lt;br /&gt;
&lt;br /&gt;
== Development Setup ==&lt;br /&gt;
&lt;br /&gt;
=== Using the Raspberry Pi Debug Probe ===&lt;br /&gt;
The Debug Probe is a RP2040 based USB-to-UART/SWD board for connecting the USB slot of a development machine to the SWD or UART pins of a target device.&lt;br /&gt;
&lt;br /&gt;
=== Using A Pico To Debug Another Pico ===&lt;br /&gt;
A Pico can be used to debug another Pico (a.k.a. target device)  by flashing it with the [https://github.com/raspberrypi/debugprobe debugprobe] binary and wiring to the target Pico as shown below.&lt;br /&gt;
&lt;br /&gt;
[[File:Wiring_rpi_pico_as_debugger.png | x320 px | A Raspberry Pi Pico wired to debug another Pico]]&lt;br /&gt;
&lt;br /&gt;
From the debugger Pico to the target Pico,&lt;br /&gt;
* pin #4 (GP2) connects to pin SWCLK,&lt;br /&gt;
* pin #5 (GP3) connects to SWDIO,&lt;br /&gt;
* pin #6 (GP4, UART1 TX) connects to pin #2 (GP1, UART0 RX),&lt;br /&gt;
* pin #7 (GP5, UART1 RX) connects to pin #1 (GP0, UART0, TX).&lt;br /&gt;
&lt;br /&gt;
The debugger Pico serves both as a USB-to-SWD and USB-to-UART bridge to the target device. The development machine, therefore, needs to be connected via USB only to the debugger Pico. Console output on the target Pico is relayed through the debugger. It is possible, though, to connect a second USB cable from the development machine to the target device for (simultaneous) direct access to the console output. This debugger setup works not just with Pico targets but with any microcontroller that supports the CMSIS-DAP protocol over SWD.&lt;br /&gt;
&lt;br /&gt;
=== Software Tools for Debugging ===&lt;br /&gt;
Whether we use the Raspberry Pi Debug Probe or a spare Pico as debug probe, the software tools used for debugging are the same:&lt;br /&gt;
* openocd&lt;br /&gt;
&lt;br /&gt;
== Notes on Programming with the C SDK ==&lt;br /&gt;
&lt;br /&gt;
=== Async Context ===&lt;br /&gt;
In the C SDK, an [https://www.raspberrypi.com/documentation/pico-sdk/high_level.html#group_pico_async_context async_context] is used in concurrent programming to make sure that functions are executed on the same thread and in the order they were submitted, similar to dispatch queues in Apple&#039;s [https://developer.apple.com/documentation/dispatch?language=objc Dispatch framework]. The &#039;&#039;async_context&#039;&#039; data structure is a container of linked lists of worker functions that are executed within a single thread of a single processor core.&lt;br /&gt;
&lt;br /&gt;
=== Bluetooth with BTstack ===&lt;br /&gt;
&lt;br /&gt;
The C SDK integrates the third-party [https://bluekitchen-gmbh.com/btstack BTstack] framework as its Bluetooth API that interfaces with the Infineon CYW43 wireless communication module (on Pico W models) via the Host-Controller Interface (HCI) protocol.&lt;br /&gt;
&lt;br /&gt;
==== Setup ====&lt;br /&gt;
&lt;br /&gt;
Before we can call any BTstack functions (and hope for some meaningful outcome), we need to add a &#039;&#039;&#039;btstack_config.h&#039;&#039;&#039; header file to our project. In it, we add all the compile-time switches that fit our application. On a microcontroller, a frequent use case for BTstack is to implement a BLE peripheral. For this we, our config header should look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#ifndef MY_BTSTACK_CONFIG_H&lt;br /&gt;
#define MY_BTSTACK_CONFIG_H&lt;br /&gt;
&lt;br /&gt;
#ifndef ENABLE_BLE&lt;br /&gt;
#error In CMakeLists.txt add the &#039;pico_btstack_ble&#039; library to target_link_libraries(...)&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// logging&lt;br /&gt;
#define ENABLE_LOG_INFO&lt;br /&gt;
#define ENABLE_LOG_ERROR&lt;br /&gt;
#define ENABLE_PRINTF_HEXDUMP // required for hci_dump_init()&lt;br /&gt;
&lt;br /&gt;
#if 1 // configure as peripheral (GATT server)&lt;br /&gt;
	#define ENABLE_LE_PERIPHERAL&lt;br /&gt;
	#define MAX_NR_GATT_CLIENTS 0&lt;br /&gt;
#else // configure as central (GATT client)&lt;br /&gt;
	#define ENABLE_LE_CENTRAL&lt;br /&gt;
	#define MAX_NR_GATT_CLIENTS 1&lt;br /&gt;
//#define ENABLE_GATT_CLIENT_PAIRING&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// Setting various buffer sizes related to HCI communication&lt;br /&gt;
#define HCI_OUTGOING_PRE_BUFFER_SIZE 4&lt;br /&gt;
#define HCI_ACL_PAYLOAD_SIZE (255 + 4)&lt;br /&gt;
#define HCI_ACL_CHUNK_SIZE_ALIGNMENT 4&lt;br /&gt;
#define MAX_NR_HCI_CONNECTIONS 1&lt;br /&gt;
#define MAX_NR_SM_LOOKUP_ENTRIES 3&lt;br /&gt;
#define MAX_NR_WHITELIST_ENTRIES 16&lt;br /&gt;
#define MAX_NR_LE_DEVICE_DB_ENTRIES 16&lt;br /&gt;
&lt;br /&gt;
// Choosing a fixed-size attributes table over using malloc.&lt;br /&gt;
// We want to use BTstack without heap memory allocations.&lt;br /&gt;
#if 1&lt;br /&gt;
#define MAX_ATT_DB_SIZE 512&lt;br /&gt;
#else&lt;br /&gt;
#define HAVE_MALLOC&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// Enabling timers&lt;br /&gt;
#if 1&lt;br /&gt;
#define HAVE_EMBEDDED_TIME_MS&lt;br /&gt;
#else&lt;br /&gt;
#define HAVE_EMBEDDED_TICK&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// Limiting the amount of nonvolatile (flash) memory used for storing peer bonding information&lt;br /&gt;
#define NVM_NUM_DEVICE_DB_ENTRIES 16&lt;br /&gt;
#define NVM_NUM_LINK_KEYS 16&lt;br /&gt;
&lt;br /&gt;
// Configuring HCI Controller-to-Host flow control and related buffers to avoid overrunning the cyw43 shared bus&lt;br /&gt;
#define ENABLE_HCI_CONTROLLER_TO_HOST_FLOW_CONTROL&lt;br /&gt;
#define HCI_HOST_ACL_PACKET_LEN (255+4)&lt;br /&gt;
#define HCI_HOST_ACL_PACKET_NUM 3&lt;br /&gt;
#define HCI_HOST_SCO_PACKET_LEN 120&lt;br /&gt;
#define HCI_HOST_SCO_PACKET_NUM 3&lt;br /&gt;
#define MAX_NR_CONTROLLER_SCO_PACKETS 3&lt;br /&gt;
#define MAX_NR_CONTROLLER_ACL_BUFFERS 3&lt;br /&gt;
&lt;br /&gt;
// Enabling btstack_assert, acting just like normal assert()&lt;br /&gt;
#define HAVE_ASSERT&lt;br /&gt;
&lt;br /&gt;
// Setting HCI resend timeout in case the Bluetooth module needs more time to response.&lt;br /&gt;
#define HCI_RESET_RESEND_TIMEOUT_MS 800&lt;br /&gt;
&lt;br /&gt;
// Configuring security&lt;br /&gt;
#define ENABLE_SOFTWARE_AES128&lt;br /&gt;
#define ENABLE_MICRO_ECC_FOR_LE_SECURE_CONNECTIONS&lt;br /&gt;
&lt;br /&gt;
#endif // MY_BTSTACK_CONFIG_H&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== The BTstack runloop ====&lt;br /&gt;
&lt;br /&gt;
The following articles by Hunter Adams offer a detailed analysis of how BTstack works on the Pico:&lt;br /&gt;
# [https://vanhunteradams.com/Pico/BLE/BTStack_HCI.html BTstack and RP2040: HCI (Host Controller Interface)].&amp;lt;br /&amp;gt;This article delves, among other things, into how the BTstack runloop is executed inside a Pico [[#Async_Context | async_context]].&amp;lt;br /&amp;gt;&amp;lt;blockquote&amp;gt;[...] we have just one &#039;&#039;when_pending_worker&#039;&#039; in our async_context. This worker is called &#039;&#039;cyw43_poll_worker&#039;&#039;, and its &#039;&#039;do_work&#039;&#039; function points to &#039;&#039;cyw43_poll_func()&#039;&#039;, listed above. This function ends up calling &#039;&#039;btstack_run_loop_poll_data_sources_from_irq()&#039;&#039;, about which we&#039;ll learn more shortly. This worker gets marked as pending in a GPIO interrupt. So, this provides a mechanism by which the CYW43 can tell the RP2040 to run &#039;&#039;btstack_run_loop_poll_data_sources_from_irq()&#039;&#039; which, as we&#039;re going to learn, goes and gets data from the device.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
# [https://vanhunteradams.com/Pico/BLE/GATT_Server.html Building a Bluetooth GATT Server on the Pi Pico W]&lt;br /&gt;
&lt;br /&gt;
==== GATT Characteristic read and write operations ====&lt;br /&gt;
&lt;br /&gt;
The struct &amp;lt;code&amp;gt;att_service_handler_t&amp;lt;/code&amp;gt; represents a GATT service. After the fields of the struct have been filled in by the application code, it holds all the information needed for the BLE peripheral to make it available to the BLE central. Some of the fields of the struct hold the ATT handles that define the start and end of the collection of characteristics belonging to the service. Other fields of the struct (&amp;lt;code&amp;gt;read_callback&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;write_callback&amp;lt;/code&amp;gt;) hold pointers to functions that handle reading from and writing to characteristic values.&lt;br /&gt;
&lt;br /&gt;
Note that the &#039;&#039;read&#039;&#039; callback for a descriptor of a GATT characteristic (i.e., an ATT attribute) is called twice. In the first call, the buffer pointer passed to the callback function is NULL. In the second call, it&#039;s a valid pointer. The first call is made by BTstack to query the size of the data that will be returned by the second call. BTstack needs to make sure its transmission buffers can hold the amount of data before making the second call.&lt;br /&gt;
&lt;br /&gt;
At the end of a writing operation, if the characteristic was configured to send back notifications to the BLE peer, one more callback function comes into play. It is part of another struct, &amp;lt;code&amp;gt;btstack_context_callback_registration_t&amp;lt;/code&amp;gt;, that is used for the deferred sending of characteristic update notification to the BLE central. In this callback, &amp;lt;code&amp;gt;att_server_notify()&amp;lt;/code&amp;gt; is called to finally send the write notification to the peer.&lt;/div&gt;</summary>
		<author><name>Kai</name></author>
	</entry>
	<entry>
		<id>https://Robo.Fish/wiki/index.php?title=Raspberry_Pi_Microcontrollers&amp;diff=3278</id>
		<title>Raspberry Pi Microcontrollers</title>
		<link rel="alternate" type="text/html" href="https://Robo.Fish/wiki/index.php?title=Raspberry_Pi_Microcontrollers&amp;diff=3278"/>
		<updated>2025-05-08T07:36:16Z</updated>

		<summary type="html">&lt;p&gt;Kai: Note on why BTstack calls the read callback twice.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Pico Series =&lt;br /&gt;
* Raspberry Pi Pico and Pico W&lt;br /&gt;
** Dual [https://developer.arm.com/Processors/Cortex-M0-Plus Arm Cortex-M0+] with Armv6-M programming model, up to 133 MHz&lt;br /&gt;
* Raspberry Pi Pico 2 and Pico 2 W&lt;br /&gt;
** Dual [https://developer.arm.com/Processors/Cortex-M33 Arm Cortex-M33] with Armv8-M programming model, up to 150 MHz&lt;br /&gt;
&lt;br /&gt;
== Development Setup ==&lt;br /&gt;
&lt;br /&gt;
=== Using the Raspberry Pi Debug Probe ===&lt;br /&gt;
The Debug Probe is a RP2040 based USB-to-UART/SWD board for connecting the USB slot of a development machine to the SWD or UART pins of a target device.&lt;br /&gt;
&lt;br /&gt;
=== Using A Pico To Debug Another Pico ===&lt;br /&gt;
A Pico can be used to debug another Pico (a.k.a. target device)  by flashing it with the [https://github.com/raspberrypi/debugprobe debugprobe] binary and wiring to the target Pico as shown below.&lt;br /&gt;
&lt;br /&gt;
[[File:Wiring_rpi_pico_as_debugger.png | x320 px | A Raspberry Pi Pico wired to debug another Pico]]&lt;br /&gt;
&lt;br /&gt;
From the debugger Pico to the target Pico,&lt;br /&gt;
* pin #4 (GP2) connects to pin SWCLK,&lt;br /&gt;
* pin #5 (GP3) connects to SWDIO,&lt;br /&gt;
* pin #6 (GP4, UART1 TX) connects to pin #2 (GP1, UART0 RX),&lt;br /&gt;
* pin #7 (GP5, UART1 RX) connects to pin #1 (GP0, UART0, TX).&lt;br /&gt;
&lt;br /&gt;
The debugger Pico serves both as a USB-to-SWD and USB-to-UART bridge to the target device. The development machine, therefore, needs to be connected via USB only to the debugger Pico. Console output on the target Pico is relayed through the debugger. It is possible, though, to connect a second USB cable from the development machine to the target device for (simultaneous) direct access to the console output. This debugger setup works not just with Pico targets but with any microcontroller that supports the CMSIS-DAP protocol over SWD.&lt;br /&gt;
&lt;br /&gt;
=== Software Tools for Debugging ===&lt;br /&gt;
Whether we use the Raspberry Pi Debug Probe or a spare Pico as debug probe, the software tools used for debugging are the same:&lt;br /&gt;
* openocd&lt;br /&gt;
&lt;br /&gt;
== Notes on Programming with the C SDK ==&lt;br /&gt;
&lt;br /&gt;
=== Async Context ===&lt;br /&gt;
In the C SDK, an [https://www.raspberrypi.com/documentation/pico-sdk/high_level.html#group_pico_async_context async_context] is used in concurrent programming to make sure that functions are executed on the same thread and in the order they were submitted, similar to dispatch queues in Apple&#039;s [https://developer.apple.com/documentation/dispatch?language=objc Dispatch framework]. The &#039;&#039;async_context&#039;&#039; data structure is a container of linked lists of worker functions that are executed within a single thread of a single processor core.&lt;br /&gt;
&lt;br /&gt;
=== Bluetooth with BTstack ===&lt;br /&gt;
&lt;br /&gt;
The C SDK integrates the third-party [https://bluekitchen-gmbh.com/btstack BTstack] framework as its Bluetooth API that interfaces with the Infineon CYW43 wireless communication module (on Pico W models) via the Host-Controller Interface (HCI) protocol.&lt;br /&gt;
&lt;br /&gt;
==== Setup ====&lt;br /&gt;
&lt;br /&gt;
Before we can call any BTstack functions (and hope for some meaningful outcome), we need to add a &#039;&#039;&#039;btstack_config.h&#039;&#039;&#039; header file to our project. In it, we add all the compile-time switches that fit our application. On a microcontroller, a frequent use case for BTstack is to implement a BLE peripheral. For this we, our config header should look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#ifndef MY_BTSTACK_CONFIG_H&lt;br /&gt;
#define MY_BTSTACK_CONFIG_H&lt;br /&gt;
&lt;br /&gt;
#ifndef ENABLE_BLE&lt;br /&gt;
#error In CMakeLists.txt add the &#039;pico_btstack_ble&#039; library to target_link_libraries(...)&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
#define ENABLE_LOG_INFO&lt;br /&gt;
#define ENABLE_LOG_ERROR&lt;br /&gt;
&lt;br /&gt;
#if 1 // configure as peripheral (GATT server)&lt;br /&gt;
	#define ENABLE_LE_PERIPHERAL&lt;br /&gt;
	#define MAX_NR_GATT_CLIENTS 0&lt;br /&gt;
#else // configure as central (GATT client)&lt;br /&gt;
	#define ENABLE_LE_CENTRAL&lt;br /&gt;
	#define MAX_NR_GATT_CLIENTS 1&lt;br /&gt;
//#define ENABLE_GATT_CLIENT_PAIRING&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// Setting various buffer sizes related to HCI communication&lt;br /&gt;
#define HCI_OUTGOING_PRE_BUFFER_SIZE 4&lt;br /&gt;
#define HCI_ACL_PAYLOAD_SIZE (255 + 4)&lt;br /&gt;
#define HCI_ACL_CHUNK_SIZE_ALIGNMENT 4&lt;br /&gt;
#define MAX_NR_HCI_CONNECTIONS 1&lt;br /&gt;
#define MAX_NR_SM_LOOKUP_ENTRIES 3&lt;br /&gt;
#define MAX_NR_WHITELIST_ENTRIES 16&lt;br /&gt;
#define MAX_NR_LE_DEVICE_DB_ENTRIES 16&lt;br /&gt;
&lt;br /&gt;
#define ENABLE_PRINTF_HEXDUMP&lt;br /&gt;
&lt;br /&gt;
// Choosing a fixed-size attributes table over using malloc.&lt;br /&gt;
// We want to use BTstack without heap memory allocations.&lt;br /&gt;
#if 1&lt;br /&gt;
#define MAX_ATT_DB_SIZE 512&lt;br /&gt;
#else&lt;br /&gt;
#define HAVE_MALLOC&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// Enabling timers&lt;br /&gt;
#if 1&lt;br /&gt;
#define HAVE_EMBEDDED_TIME_MS&lt;br /&gt;
#else&lt;br /&gt;
#define HAVE_EMBEDDED_TICK&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// Limiting the amount of nonvolatile (flash) memory used for storing peer bonding information&lt;br /&gt;
#define NVM_NUM_DEVICE_DB_ENTRIES 16&lt;br /&gt;
#define NVM_NUM_LINK_KEYS 16&lt;br /&gt;
&lt;br /&gt;
// Configuring HCI Controller-to-Host flow control and related buffers to avoid overrunning the cyw43 shared bus&lt;br /&gt;
#define ENABLE_HCI_CONTROLLER_TO_HOST_FLOW_CONTROL&lt;br /&gt;
#define HCI_HOST_ACL_PACKET_LEN (255+4)&lt;br /&gt;
#define HCI_HOST_ACL_PACKET_NUM 3&lt;br /&gt;
#define HCI_HOST_SCO_PACKET_LEN 120&lt;br /&gt;
#define HCI_HOST_SCO_PACKET_NUM 3&lt;br /&gt;
#define MAX_NR_CONTROLLER_SCO_PACKETS 3&lt;br /&gt;
#define MAX_NR_CONTROLLER_ACL_BUFFERS 3&lt;br /&gt;
&lt;br /&gt;
// Enabling btstack_assert, acting just like normal assert()&lt;br /&gt;
#define HAVE_ASSERT&lt;br /&gt;
&lt;br /&gt;
// Setting HCI resend timeout in case the Bluetooth module needs more time to response.&lt;br /&gt;
#define HCI_RESET_RESEND_TIMEOUT_MS 800&lt;br /&gt;
&lt;br /&gt;
// Configuring security&lt;br /&gt;
#define ENABLE_SOFTWARE_AES128&lt;br /&gt;
#define ENABLE_MICRO_ECC_FOR_LE_SECURE_CONNECTIONS&lt;br /&gt;
&lt;br /&gt;
#endif // MY_BTSTACK_CONFIG_H&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== The BTstack runloop ====&lt;br /&gt;
&lt;br /&gt;
The following articles by Hunter Adams offer a detailed analysis of how BTstack works on the Pico:&lt;br /&gt;
# [https://vanhunteradams.com/Pico/BLE/BTStack_HCI.html BTstack and RP2040: HCI (Host Controller Interface)].&amp;lt;br /&amp;gt;This article delves, among other things, into how the BTstack runloop is executed inside a Pico [[#Async_Context | async_context]].&amp;lt;br /&amp;gt;&amp;lt;blockquote&amp;gt;[...] we have just one &#039;&#039;when_pending_worker&#039;&#039; in our async_context. This worker is called &#039;&#039;cyw43_poll_worker&#039;&#039;, and its &#039;&#039;do_work&#039;&#039; function points to &#039;&#039;cyw43_poll_func()&#039;&#039;, listed above. This function ends up calling &#039;&#039;btstack_run_loop_poll_data_sources_from_irq()&#039;&#039;, about which we&#039;ll learn more shortly. This worker gets marked as pending in a GPIO interrupt. So, this provides a mechanism by which the CYW43 can tell the RP2040 to run &#039;&#039;btstack_run_loop_poll_data_sources_from_irq()&#039;&#039; which, as we&#039;re going to learn, goes and gets data from the device.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
# [https://vanhunteradams.com/Pico/BLE/GATT_Server.html Building a Bluetooth GATT Server on the Pi Pico W]&lt;br /&gt;
&lt;br /&gt;
==== GATT Characteristic read and write operations ====&lt;br /&gt;
&lt;br /&gt;
The struct &amp;lt;code&amp;gt;att_service_handler_t&amp;lt;/code&amp;gt; represents a GATT service. After the fields of the struct have been filled in by the application code, it holds all the information needed for the BLE peripheral to make it available to the BLE central. Some of the fields of the struct hold the ATT handles that define the start and end of the collection of characteristics belonging to the service. Other fields of the struct (&amp;lt;code&amp;gt;read_callback&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;write_callback&amp;lt;/code&amp;gt;) hold pointers to functions that handle reading from and writing to characteristic values.&lt;br /&gt;
&lt;br /&gt;
Note that the &#039;&#039;read&#039;&#039; callback for a descriptor of a GATT characteristic (i.e., an ATT attribute) is called twice. In the first call, the buffer pointer passed to the callback function is NULL. In the second call, it&#039;s a valid pointer. The first call is made by BTstack to query the size of the data that will be returned by the second call. BTstack needs to make sure its transmission buffers can hold the amount of data before making the second call.&lt;br /&gt;
&lt;br /&gt;
At the end of a writing operation, if the characteristic was configured to send back notifications to the BLE peer, one more callback function comes into play. It is part of another struct, &amp;lt;code&amp;gt;btstack_context_callback_registration_t&amp;lt;/code&amp;gt;, that is used for the deferred sending of characteristic update notification to the BLE central. In this callback, &amp;lt;code&amp;gt;att_server_notify()&amp;lt;/code&amp;gt; is called to finally send the write notification to the peer.&lt;/div&gt;</summary>
		<author><name>Kai</name></author>
	</entry>
	<entry>
		<id>https://Robo.Fish/wiki/index.php?title=Raspberry_Pi_Microcontrollers&amp;diff=3277</id>
		<title>Raspberry Pi Microcontrollers</title>
		<link rel="alternate" type="text/html" href="https://Robo.Fish/wiki/index.php?title=Raspberry_Pi_Microcontrollers&amp;diff=3277"/>
		<updated>2025-05-07T17:25:08Z</updated>

		<summary type="html">&lt;p&gt;Kai: /* Bluetooth with BTstack */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Pico Series =&lt;br /&gt;
* Raspberry Pi Pico and Pico W&lt;br /&gt;
** Dual [https://developer.arm.com/Processors/Cortex-M0-Plus Arm Cortex-M0+] with Armv6-M programming model, up to 133 MHz&lt;br /&gt;
* Raspberry Pi Pico 2 and Pico 2 W&lt;br /&gt;
** Dual [https://developer.arm.com/Processors/Cortex-M33 Arm Cortex-M33] with Armv8-M programming model, up to 150 MHz&lt;br /&gt;
&lt;br /&gt;
== Development Setup ==&lt;br /&gt;
&lt;br /&gt;
=== Using the Raspberry Pi Debug Probe ===&lt;br /&gt;
The Debug Probe is a RP2040 based USB-to-UART/SWD board for connecting the USB slot of a development machine to the SWD or UART pins of a target device.&lt;br /&gt;
&lt;br /&gt;
=== Using A Pico To Debug Another Pico ===&lt;br /&gt;
A Pico can be used to debug another Pico (a.k.a. target device)  by flashing it with the [https://github.com/raspberrypi/debugprobe debugprobe] binary and wiring to the target Pico as shown below.&lt;br /&gt;
&lt;br /&gt;
[[File:Wiring_rpi_pico_as_debugger.png | x320 px | A Raspberry Pi Pico wired to debug another Pico]]&lt;br /&gt;
&lt;br /&gt;
From the debugger Pico to the target Pico,&lt;br /&gt;
* pin #4 (GP2) connects to pin SWCLK,&lt;br /&gt;
* pin #5 (GP3) connects to SWDIO,&lt;br /&gt;
* pin #6 (GP4, UART1 TX) connects to pin #2 (GP1, UART0 RX),&lt;br /&gt;
* pin #7 (GP5, UART1 RX) connects to pin #1 (GP0, UART0, TX).&lt;br /&gt;
&lt;br /&gt;
The debugger Pico serves both as a USB-to-SWD and USB-to-UART bridge to the target device. The development machine, therefore, needs to be connected via USB only to the debugger Pico. Console output on the target Pico is relayed through the debugger. It is possible, though, to connect a second USB cable from the development machine to the target device for (simultaneous) direct access to the console output. This debugger setup works not just with Pico targets but with any microcontroller that supports the CMSIS-DAP protocol over SWD.&lt;br /&gt;
&lt;br /&gt;
=== Software Tools for Debugging ===&lt;br /&gt;
Whether we use the Raspberry Pi Debug Probe or a spare Pico as debug probe, the software tools used for debugging are the same:&lt;br /&gt;
* openocd&lt;br /&gt;
&lt;br /&gt;
== Notes on Programming with the C SDK ==&lt;br /&gt;
&lt;br /&gt;
=== Async Context ===&lt;br /&gt;
In the C SDK, an [https://www.raspberrypi.com/documentation/pico-sdk/high_level.html#group_pico_async_context async_context] is used in concurrent programming to make sure that functions are executed on the same thread and in the order they were submitted, similar to dispatch queues in Apple&#039;s [https://developer.apple.com/documentation/dispatch?language=objc Dispatch framework]. The &#039;&#039;async_context&#039;&#039; data structure is a container of linked lists of worker functions that are executed within a single thread of a single processor core.&lt;br /&gt;
&lt;br /&gt;
=== Bluetooth with BTstack ===&lt;br /&gt;
&lt;br /&gt;
The C SDK integrates the third-party [https://bluekitchen-gmbh.com/btstack BTstack] framework as its Bluetooth API that interfaces with the Infineon CYW43 wireless communication module (on Pico W models) via the Host-Controller Interface (HCI) protocol.&lt;br /&gt;
&lt;br /&gt;
==== Setup ====&lt;br /&gt;
&lt;br /&gt;
Before we can call any BTstack functions (and hope for some meaningful outcome), we need to add a &#039;&#039;&#039;btstack_config.h&#039;&#039;&#039; header file to our project. In it, we add all the compile-time switches that fit our application. On a microcontroller, a frequent use case for BTstack is to implement a BLE peripheral. For this we, our config header should look something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#ifndef MY_BTSTACK_CONFIG_H&lt;br /&gt;
#define MY_BTSTACK_CONFIG_H&lt;br /&gt;
&lt;br /&gt;
#ifndef ENABLE_BLE&lt;br /&gt;
#error In CMakeLists.txt add the &#039;pico_btstack_ble&#039; library to target_link_libraries(...)&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
#define ENABLE_LOG_INFO&lt;br /&gt;
#define ENABLE_LOG_ERROR&lt;br /&gt;
&lt;br /&gt;
#if 1 // configure as peripheral (GATT server)&lt;br /&gt;
	#define ENABLE_LE_PERIPHERAL&lt;br /&gt;
	#define MAX_NR_GATT_CLIENTS 0&lt;br /&gt;
#else // configure as central (GATT client)&lt;br /&gt;
	#define ENABLE_LE_CENTRAL&lt;br /&gt;
	#define MAX_NR_GATT_CLIENTS 1&lt;br /&gt;
//#define ENABLE_GATT_CLIENT_PAIRING&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// Setting various buffer sizes related to HCI communication&lt;br /&gt;
#define HCI_OUTGOING_PRE_BUFFER_SIZE 4&lt;br /&gt;
#define HCI_ACL_PAYLOAD_SIZE (255 + 4)&lt;br /&gt;
#define HCI_ACL_CHUNK_SIZE_ALIGNMENT 4&lt;br /&gt;
#define MAX_NR_HCI_CONNECTIONS 1&lt;br /&gt;
#define MAX_NR_SM_LOOKUP_ENTRIES 3&lt;br /&gt;
#define MAX_NR_WHITELIST_ENTRIES 16&lt;br /&gt;
#define MAX_NR_LE_DEVICE_DB_ENTRIES 16&lt;br /&gt;
&lt;br /&gt;
#define ENABLE_PRINTF_HEXDUMP&lt;br /&gt;
&lt;br /&gt;
// Choosing a fixed-size attributes table over using malloc.&lt;br /&gt;
// We want to use BTstack without heap memory allocations.&lt;br /&gt;
#if 1&lt;br /&gt;
#define MAX_ATT_DB_SIZE 512&lt;br /&gt;
#else&lt;br /&gt;
#define HAVE_MALLOC&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// Enabling timers&lt;br /&gt;
#if 1&lt;br /&gt;
#define HAVE_EMBEDDED_TIME_MS&lt;br /&gt;
#else&lt;br /&gt;
#define HAVE_EMBEDDED_TICK&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// Limiting the amount of nonvolatile (flash) memory used for storing peer bonding information&lt;br /&gt;
#define NVM_NUM_DEVICE_DB_ENTRIES 16&lt;br /&gt;
#define NVM_NUM_LINK_KEYS 16&lt;br /&gt;
&lt;br /&gt;
// Configuring HCI Controller-to-Host flow control and related buffers to avoid overrunning the cyw43 shared bus&lt;br /&gt;
#define ENABLE_HCI_CONTROLLER_TO_HOST_FLOW_CONTROL&lt;br /&gt;
#define HCI_HOST_ACL_PACKET_LEN (255+4)&lt;br /&gt;
#define HCI_HOST_ACL_PACKET_NUM 3&lt;br /&gt;
#define HCI_HOST_SCO_PACKET_LEN 120&lt;br /&gt;
#define HCI_HOST_SCO_PACKET_NUM 3&lt;br /&gt;
#define MAX_NR_CONTROLLER_SCO_PACKETS 3&lt;br /&gt;
#define MAX_NR_CONTROLLER_ACL_BUFFERS 3&lt;br /&gt;
&lt;br /&gt;
// Enabling btstack_assert, acting just like normal assert()&lt;br /&gt;
#define HAVE_ASSERT&lt;br /&gt;
&lt;br /&gt;
// Setting HCI resend timeout in case the Bluetooth module needs more time to response.&lt;br /&gt;
#define HCI_RESET_RESEND_TIMEOUT_MS 800&lt;br /&gt;
&lt;br /&gt;
// Configuring security&lt;br /&gt;
#define ENABLE_SOFTWARE_AES128&lt;br /&gt;
#define ENABLE_MICRO_ECC_FOR_LE_SECURE_CONNECTIONS&lt;br /&gt;
&lt;br /&gt;
#endif // MY_BTSTACK_CONFIG_H&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== The BTstack runloop ====&lt;br /&gt;
&lt;br /&gt;
The following articles by Hunter Adams offer a detailed analysis of how BTstack works on the Pico:&lt;br /&gt;
# [https://vanhunteradams.com/Pico/BLE/BTStack_HCI.html BTstack and RP2040: HCI (Host Controller Interface)].&amp;lt;br /&amp;gt;This article delves, among other things, into how the BTstack runloop is executed inside a Pico [[#Async_Context | async_context]].&amp;lt;br /&amp;gt;&amp;lt;blockquote&amp;gt;[...] we have just one &#039;&#039;when_pending_worker&#039;&#039; in our async_context. This worker is called &#039;&#039;cyw43_poll_worker&#039;&#039;, and its &#039;&#039;do_work&#039;&#039; function points to &#039;&#039;cyw43_poll_func()&#039;&#039;, listed above. This function ends up calling &#039;&#039;btstack_run_loop_poll_data_sources_from_irq()&#039;&#039;, about which we&#039;ll learn more shortly. This worker gets marked as pending in a GPIO interrupt. So, this provides a mechanism by which the CYW43 can tell the RP2040 to run &#039;&#039;btstack_run_loop_poll_data_sources_from_irq()&#039;&#039; which, as we&#039;re going to learn, goes and gets data from the device.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
# [https://vanhunteradams.com/Pico/BLE/GATT_Server.html Building a Bluetooth GATT Server on the Pi Pico W]&lt;br /&gt;
&lt;br /&gt;
==== GATT Characteristic read and write operations ====&lt;br /&gt;
&lt;br /&gt;
The struct &amp;lt;code&amp;gt;att_service_handler_t&amp;lt;/code&amp;gt; represents a GATT service. After the fields of the struct have been filled in by the application code, it holds all the information needed for the BLE peripheral to make it available to the BLE central. Some of the fields of the struct hold the ATT handles that define the start and end of the collection of characteristics belonging to the service. Other fields of the struct (&amp;lt;code&amp;gt;read_callback&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;write_callback&amp;lt;/code&amp;gt;) hold pointers to functions that handle reading from and writing to characteristic values.&lt;br /&gt;
&lt;br /&gt;
At the end of a writing operation, if the characteristic was configured to send back notifications to the BLE peer, one more callback function comes into play. It is part of another struct, &amp;lt;code&amp;gt;btstack_context_callback_registration_t&amp;lt;/code&amp;gt;, that is used for the deferred sending of characteristic update notification to the BLE central. In this callback, &amp;lt;code&amp;gt;att_server_notify()&amp;lt;/code&amp;gt; is called to finally send the write notification to the peer.&lt;/div&gt;</summary>
		<author><name>Kai</name></author>
	</entry>
	<entry>
		<id>https://Robo.Fish/wiki/index.php?title=Raspberry_Pi_Microcontrollers&amp;diff=3276</id>
		<title>Raspberry Pi Microcontrollers</title>
		<link rel="alternate" type="text/html" href="https://Robo.Fish/wiki/index.php?title=Raspberry_Pi_Microcontrollers&amp;diff=3276"/>
		<updated>2025-05-07T17:04:13Z</updated>

		<summary type="html">&lt;p&gt;Kai: /* Bluetooth with BTstack */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Pico Series =&lt;br /&gt;
* Raspberry Pi Pico and Pico W&lt;br /&gt;
** Dual [https://developer.arm.com/Processors/Cortex-M0-Plus Arm Cortex-M0+] with Armv6-M programming model, up to 133 MHz&lt;br /&gt;
* Raspberry Pi Pico 2 and Pico 2 W&lt;br /&gt;
** Dual [https://developer.arm.com/Processors/Cortex-M33 Arm Cortex-M33] with Armv8-M programming model, up to 150 MHz&lt;br /&gt;
&lt;br /&gt;
== Development Setup ==&lt;br /&gt;
&lt;br /&gt;
=== Using the Raspberry Pi Debug Probe ===&lt;br /&gt;
The Debug Probe is a RP2040 based USB-to-UART/SWD board for connecting the USB slot of a development machine to the SWD or UART pins of a target device.&lt;br /&gt;
&lt;br /&gt;
=== Using A Pico To Debug Another Pico ===&lt;br /&gt;
A Pico can be used to debug another Pico (a.k.a. target device)  by flashing it with the [https://github.com/raspberrypi/debugprobe debugprobe] binary and wiring to the target Pico as shown below.&lt;br /&gt;
&lt;br /&gt;
[[File:Wiring_rpi_pico_as_debugger.png | x320 px | A Raspberry Pi Pico wired to debug another Pico]]&lt;br /&gt;
&lt;br /&gt;
From the debugger Pico to the target Pico,&lt;br /&gt;
* pin #4 (GP2) connects to pin SWCLK,&lt;br /&gt;
* pin #5 (GP3) connects to SWDIO,&lt;br /&gt;
* pin #6 (GP4, UART1 TX) connects to pin #2 (GP1, UART0 RX),&lt;br /&gt;
* pin #7 (GP5, UART1 RX) connects to pin #1 (GP0, UART0, TX).&lt;br /&gt;
&lt;br /&gt;
The debugger Pico serves both as a USB-to-SWD and USB-to-UART bridge to the target device. The development machine, therefore, needs to be connected via USB only to the debugger Pico. Console output on the target Pico is relayed through the debugger. It is possible, though, to connect a second USB cable from the development machine to the target device for (simultaneous) direct access to the console output. This debugger setup works not just with Pico targets but with any microcontroller that supports the CMSIS-DAP protocol over SWD.&lt;br /&gt;
&lt;br /&gt;
=== Software Tools for Debugging ===&lt;br /&gt;
Whether we use the Raspberry Pi Debug Probe or a spare Pico as debug probe, the software tools used for debugging are the same:&lt;br /&gt;
* openocd&lt;br /&gt;
&lt;br /&gt;
== Notes on Programming with the C SDK ==&lt;br /&gt;
&lt;br /&gt;
=== Async Context ===&lt;br /&gt;
In the C SDK, an [https://www.raspberrypi.com/documentation/pico-sdk/high_level.html#group_pico_async_context async_context] is used in concurrent programming to make sure that functions are executed on the same thread and in the order they were submitted, similar to dispatch queues in Apple&#039;s [https://developer.apple.com/documentation/dispatch?language=objc Dispatch framework]. The &#039;&#039;async_context&#039;&#039; data structure is a container of linked lists of worker functions that are executed within a single thread of a single processor core.&lt;br /&gt;
&lt;br /&gt;
=== Bluetooth with BTstack ===&lt;br /&gt;
&lt;br /&gt;
The C SDK integrates the third-party [https://bluekitchen-gmbh.com/btstack BTstack] framework as its Bluetooth API that interfaces with the Infineon CYW43 wireless communication module (on Pico W models) via the Host-Controller Interface (HCI) protocol.&lt;br /&gt;
&lt;br /&gt;
==== The BTstack runloop ====&lt;br /&gt;
&lt;br /&gt;
The following articles by Hunter Adams offer a detailed analysis of how BTstack works on the Pico:&lt;br /&gt;
# [https://vanhunteradams.com/Pico/BLE/BTStack_HCI.html BTstack and RP2040: HCI (Host Controller Interface)].&amp;lt;br /&amp;gt;This article delves, among other things, into how the BTstack runloop is executed inside a Pico [[#Async_Context | async_context]].&amp;lt;br /&amp;gt;&amp;lt;blockquote&amp;gt;[...] we have just one &#039;&#039;when_pending_worker&#039;&#039; in our async_context. This worker is called &#039;&#039;cyw43_poll_worker&#039;&#039;, and its &#039;&#039;do_work&#039;&#039; function points to &#039;&#039;cyw43_poll_func()&#039;&#039;, listed above. This function ends up calling &#039;&#039;btstack_run_loop_poll_data_sources_from_irq()&#039;&#039;, about which we&#039;ll learn more shortly. This worker gets marked as pending in a GPIO interrupt. So, this provides a mechanism by which the CYW43 can tell the RP2040 to run &#039;&#039;btstack_run_loop_poll_data_sources_from_irq()&#039;&#039; which, as we&#039;re going to learn, goes and gets data from the device.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
# [https://vanhunteradams.com/Pico/BLE/GATT_Server.html Building a Bluetooth GATT Server on the Pi Pico W]&lt;br /&gt;
&lt;br /&gt;
==== GATT Characteristic read and write operations ====&lt;br /&gt;
&lt;br /&gt;
The struct &amp;lt;code&amp;gt;att_service_handler_t&amp;lt;/code&amp;gt; represents a GATT service. After the fields of the struct have been filled in by the application code, it holds all the information needed for the BLE peripheral to make it available to the BLE central. Some of the fields of the struct hold the ATT handles that define the start and end of the collection of characteristics belonging to the service. Other fields of the struct (&amp;lt;code&amp;gt;read_callback&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;write_callback&amp;lt;/code&amp;gt;) hold pointers to functions that handle reading from and writing to characteristic values.&lt;br /&gt;
&lt;br /&gt;
At the end of a writing operation, if the characteristic was configured to send back notifications to the BLE peer, one more callback function comes into play. It is part of another struct, &amp;lt;code&amp;gt;btstack_context_callback_registration_t&amp;lt;/code&amp;gt;, that is used for the deferred sending of characteristic update notification to the BLE central. In this callback, &amp;lt;code&amp;gt;att_server_notify()&amp;lt;/code&amp;gt; is called to finally send the write notification to the peer.&lt;/div&gt;</summary>
		<author><name>Kai</name></author>
	</entry>
	<entry>
		<id>https://Robo.Fish/wiki/index.php?title=Raspberry_Pi_Microcontrollers&amp;diff=3275</id>
		<title>Raspberry Pi Microcontrollers</title>
		<link rel="alternate" type="text/html" href="https://Robo.Fish/wiki/index.php?title=Raspberry_Pi_Microcontrollers&amp;diff=3275"/>
		<updated>2025-05-07T16:11:53Z</updated>

		<summary type="html">&lt;p&gt;Kai: /* Bluetooth */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Pico Series =&lt;br /&gt;
* Raspberry Pi Pico and Pico W&lt;br /&gt;
** Dual [https://developer.arm.com/Processors/Cortex-M0-Plus Arm Cortex-M0+] with Armv6-M programming model, up to 133 MHz&lt;br /&gt;
* Raspberry Pi Pico 2 and Pico 2 W&lt;br /&gt;
** Dual [https://developer.arm.com/Processors/Cortex-M33 Arm Cortex-M33] with Armv8-M programming model, up to 150 MHz&lt;br /&gt;
&lt;br /&gt;
== Development Setup ==&lt;br /&gt;
&lt;br /&gt;
=== Using the Raspberry Pi Debug Probe ===&lt;br /&gt;
The Debug Probe is a RP2040 based USB-to-UART/SWD board for connecting the USB slot of a development machine to the SWD or UART pins of a target device.&lt;br /&gt;
&lt;br /&gt;
=== Using A Pico To Debug Another Pico ===&lt;br /&gt;
A Pico can be used to debug another Pico (a.k.a. target device)  by flashing it with the [https://github.com/raspberrypi/debugprobe debugprobe] binary and wiring to the target Pico as shown below.&lt;br /&gt;
&lt;br /&gt;
[[File:Wiring_rpi_pico_as_debugger.png | x320 px | A Raspberry Pi Pico wired to debug another Pico]]&lt;br /&gt;
&lt;br /&gt;
From the debugger Pico to the target Pico,&lt;br /&gt;
* pin #4 (GP2) connects to pin SWCLK,&lt;br /&gt;
* pin #5 (GP3) connects to SWDIO,&lt;br /&gt;
* pin #6 (GP4, UART1 TX) connects to pin #2 (GP1, UART0 RX),&lt;br /&gt;
* pin #7 (GP5, UART1 RX) connects to pin #1 (GP0, UART0, TX).&lt;br /&gt;
&lt;br /&gt;
The debugger Pico serves both as a USB-to-SWD and USB-to-UART bridge to the target device. The development machine, therefore, needs to be connected via USB only to the debugger Pico. Console output on the target Pico is relayed through the debugger. It is possible, though, to connect a second USB cable from the development machine to the target device for (simultaneous) direct access to the console output. This debugger setup works not just with Pico targets but with any microcontroller that supports the CMSIS-DAP protocol over SWD.&lt;br /&gt;
&lt;br /&gt;
=== Software Tools for Debugging ===&lt;br /&gt;
Whether we use the Raspberry Pi Debug Probe or a spare Pico as debug probe, the software tools used for debugging are the same:&lt;br /&gt;
* openocd&lt;br /&gt;
&lt;br /&gt;
== Notes on Programming with the C SDK ==&lt;br /&gt;
&lt;br /&gt;
=== Async Context ===&lt;br /&gt;
In the C SDK, an [https://www.raspberrypi.com/documentation/pico-sdk/high_level.html#group_pico_async_context async_context] is used in concurrent programming to make sure that functions are executed on the same thread and in the order they were submitted, similar to dispatch queues in Apple&#039;s [https://developer.apple.com/documentation/dispatch?language=objc Dispatch framework]. The &#039;&#039;async_context&#039;&#039; data structure is a container of linked lists of worker functions that are executed within a single thread of a single processor core.&lt;br /&gt;
&lt;br /&gt;
=== Bluetooth with BTstack ===&lt;br /&gt;
&lt;br /&gt;
The C SDK integrates the third-party [https://bluekitchen-gmbh.com/btstack BTstack] framework as its Bluetooth API that interfaces with the Infineon CYW43 wireless communication module (on Pico W models) via the Host-Controller Interface (HCI) protocol.&lt;br /&gt;
&lt;br /&gt;
The following articles by Hunter Adams offer a detailed analysis of how BTstack works on the Pico:&lt;br /&gt;
# [https://vanhunteradams.com/Pico/BLE/BTStack_HCI.html BTstack and RP2040: HCI (Host Controller Interface)].&amp;lt;br /&amp;gt;This article delves, among other things, into how the BTstack runloop is executed inside a Pico [[#Async_Context | async_context]].&amp;lt;br /&amp;gt;&amp;lt;blockquote&amp;gt;[...] we have just one &#039;&#039;when_pending_worker&#039;&#039; in our async_context. This worker is called &#039;&#039;cyw43_poll_worker&#039;&#039;, and its &#039;&#039;do_work&#039;&#039; function points to &#039;&#039;cyw43_poll_func()&#039;&#039;, listed above. This function ends up calling &#039;&#039;btstack_run_loop_poll_data_sources_from_irq()&#039;&#039;, about which we&#039;ll learn more shortly. This worker gets marked as pending in a GPIO interrupt. So, this provides a mechanism by which the CYW43 can tell the RP2040 to run &#039;&#039;btstack_run_loop_poll_data_sources_from_irq()&#039;&#039; which, as we&#039;re going to learn, goes and gets data from the device.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
# [https://vanhunteradams.com/Pico/BLE/GATT_Server.html Building a Bluetooth GATT Server on the Pi Pico W]&lt;br /&gt;
&lt;br /&gt;
==== Characteristic write operations ====&lt;br /&gt;
&lt;br /&gt;
The struct &amp;lt;code&amp;gt;att_service_handler_t&amp;lt;/code&amp;gt; represents a GATT service. After the fields of the struct have been filled in by the application code, it holds all the information needed for the BLE peripheral to make it available to the BLE central. Some of the fields of the struct hold the ATT handles that define the start and end of the collection of characteristics belonging to the service. Other fields of the struct (&amp;lt;code&amp;gt;read_callback&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;write_callback&amp;lt;/code&amp;gt;) hold pointers to functions that handle reading from and writing to characteristic values.&lt;br /&gt;
&lt;br /&gt;
At the end of a writing operation, if the characteristic was configured to send back &#039;&#039;did-update&#039;&#039; notifications to the BLE peer, one more callback function comes into play. It is part of another struct, &amp;lt;code&amp;gt;btstack_context_callback_registration_t&amp;lt;/code&amp;gt;, that is used for the deferred sending of characteristic update notification to the BLE central.&lt;/div&gt;</summary>
		<author><name>Kai</name></author>
	</entry>
	<entry>
		<id>https://Robo.Fish/wiki/index.php?title=Raspberry_Pi_Microcontrollers&amp;diff=3274</id>
		<title>Raspberry Pi Microcontrollers</title>
		<link rel="alternate" type="text/html" href="https://Robo.Fish/wiki/index.php?title=Raspberry_Pi_Microcontrollers&amp;diff=3274"/>
		<updated>2025-05-06T06:36:44Z</updated>

		<summary type="html">&lt;p&gt;Kai: /* Bluetooth */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Pico Series =&lt;br /&gt;
* Raspberry Pi Pico and Pico W&lt;br /&gt;
** Dual [https://developer.arm.com/Processors/Cortex-M0-Plus Arm Cortex-M0+] with Armv6-M programming model, up to 133 MHz&lt;br /&gt;
* Raspberry Pi Pico 2 and Pico 2 W&lt;br /&gt;
** Dual [https://developer.arm.com/Processors/Cortex-M33 Arm Cortex-M33] with Armv8-M programming model, up to 150 MHz&lt;br /&gt;
&lt;br /&gt;
== Development Setup ==&lt;br /&gt;
&lt;br /&gt;
=== Using the Raspberry Pi Debug Probe ===&lt;br /&gt;
The Debug Probe is a RP2040 based USB-to-UART/SWD board for connecting the USB slot of a development machine to the SWD or UART pins of a target device.&lt;br /&gt;
&lt;br /&gt;
=== Using A Pico To Debug Another Pico ===&lt;br /&gt;
A Pico can be used to debug another Pico (a.k.a. target device)  by flashing it with the [https://github.com/raspberrypi/debugprobe debugprobe] binary and wiring to the target Pico as shown below.&lt;br /&gt;
&lt;br /&gt;
[[File:Wiring_rpi_pico_as_debugger.png | x320 px | A Raspberry Pi Pico wired to debug another Pico]]&lt;br /&gt;
&lt;br /&gt;
From the debugger Pico to the target Pico,&lt;br /&gt;
* pin #4 (GP2) connects to pin SWCLK,&lt;br /&gt;
* pin #5 (GP3) connects to SWDIO,&lt;br /&gt;
* pin #6 (GP4, UART1 TX) connects to pin #2 (GP1, UART0 RX),&lt;br /&gt;
* pin #7 (GP5, UART1 RX) connects to pin #1 (GP0, UART0, TX).&lt;br /&gt;
&lt;br /&gt;
The debugger Pico serves both as a USB-to-SWD and USB-to-UART bridge to the target device. The development machine, therefore, needs to be connected via USB only to the debugger Pico. Console output on the target Pico is relayed through the debugger. It is possible, though, to connect a second USB cable from the development machine to the target device for (simultaneous) direct access to the console output. This debugger setup works not just with Pico targets but with any microcontroller that supports the CMSIS-DAP protocol over SWD.&lt;br /&gt;
&lt;br /&gt;
=== Software Tools for Debugging ===&lt;br /&gt;
Whether we use the Raspberry Pi Debug Probe or a spare Pico as debug probe, the software tools used for debugging are the same:&lt;br /&gt;
* openocd&lt;br /&gt;
&lt;br /&gt;
== Notes on Programming with the C SDK ==&lt;br /&gt;
&lt;br /&gt;
=== Async Context ===&lt;br /&gt;
In the C SDK, an [https://www.raspberrypi.com/documentation/pico-sdk/high_level.html#group_pico_async_context async_context] is used in concurrent programming to make sure that functions are executed on the same thread and in the order they were submitted, similar to dispatch queues in Apple&#039;s [https://developer.apple.com/documentation/dispatch?language=objc Dispatch framework]. The &#039;&#039;async_context&#039;&#039; data structure is a container of linked lists of worker functions that are executed within a single thread of a single processor core.&lt;br /&gt;
&lt;br /&gt;
=== Bluetooth ===&lt;br /&gt;
&lt;br /&gt;
The C SDK integrates the third-party [https://bluekitchen-gmbh.com/btstack BTstack] framework as its Bluetooth API that interfaces with the Infineon CYW43 wireless communication module (on Pico W models) via the Host-Controller Interface (HCI) protocol.&lt;br /&gt;
&lt;br /&gt;
The following articles by Hunter Adams offer a detailed analysis of how BTstack works on the Pico:&lt;br /&gt;
# [https://vanhunteradams.com/Pico/BLE/BTStack_HCI.html BTstack and RP2040: HCI (Host Controller Interface)].&amp;lt;br /&amp;gt;This article delves, among other things, into how the BTstack runloop is executed inside a Pico [[#Async_Context | async_context]].&amp;lt;br /&amp;gt;&amp;lt;blockquote&amp;gt;[...] we have just one &#039;&#039;when_pending_worker&#039;&#039; in our async_context. This worker is called &#039;&#039;cyw43_poll_worker&#039;&#039;, and its &#039;&#039;do_work&#039;&#039; function points to &#039;&#039;cyw43_poll_func()&#039;&#039;, listed above. This function ends up calling &#039;&#039;btstack_run_loop_poll_data_sources_from_irq()&#039;&#039;, about which we&#039;ll learn more shortly. This worker gets marked as pending in a GPIO interrupt. So, this provides a mechanism by which the CYW43 can tell the RP2040 to run &#039;&#039;btstack_run_loop_poll_data_sources_from_irq()&#039;&#039; which, as we&#039;re going to learn, goes and gets data from the device.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
# [https://vanhunteradams.com/Pico/BLE/GATT_Server.html Building a Bluetooth GATT Server on the Pi Pico W]&lt;/div&gt;</summary>
		<author><name>Kai</name></author>
	</entry>
	<entry>
		<id>https://Robo.Fish/wiki/index.php?title=Raspberry_Pi_Microcontrollers&amp;diff=3273</id>
		<title>Raspberry Pi Microcontrollers</title>
		<link rel="alternate" type="text/html" href="https://Robo.Fish/wiki/index.php?title=Raspberry_Pi_Microcontrollers&amp;diff=3273"/>
		<updated>2025-05-06T06:28:22Z</updated>

		<summary type="html">&lt;p&gt;Kai: /* Bluetooth */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Pico Series =&lt;br /&gt;
* Raspberry Pi Pico and Pico W&lt;br /&gt;
** Dual [https://developer.arm.com/Processors/Cortex-M0-Plus Arm Cortex-M0+] with Armv6-M programming model, up to 133 MHz&lt;br /&gt;
* Raspberry Pi Pico 2 and Pico 2 W&lt;br /&gt;
** Dual [https://developer.arm.com/Processors/Cortex-M33 Arm Cortex-M33] with Armv8-M programming model, up to 150 MHz&lt;br /&gt;
&lt;br /&gt;
== Development Setup ==&lt;br /&gt;
&lt;br /&gt;
=== Using the Raspberry Pi Debug Probe ===&lt;br /&gt;
The Debug Probe is a RP2040 based USB-to-UART/SWD board for connecting the USB slot of a development machine to the SWD or UART pins of a target device.&lt;br /&gt;
&lt;br /&gt;
=== Using A Pico To Debug Another Pico ===&lt;br /&gt;
A Pico can be used to debug another Pico (a.k.a. target device)  by flashing it with the [https://github.com/raspberrypi/debugprobe debugprobe] binary and wiring to the target Pico as shown below.&lt;br /&gt;
&lt;br /&gt;
[[File:Wiring_rpi_pico_as_debugger.png | x320 px | A Raspberry Pi Pico wired to debug another Pico]]&lt;br /&gt;
&lt;br /&gt;
From the debugger Pico to the target Pico,&lt;br /&gt;
* pin #4 (GP2) connects to pin SWCLK,&lt;br /&gt;
* pin #5 (GP3) connects to SWDIO,&lt;br /&gt;
* pin #6 (GP4, UART1 TX) connects to pin #2 (GP1, UART0 RX),&lt;br /&gt;
* pin #7 (GP5, UART1 RX) connects to pin #1 (GP0, UART0, TX).&lt;br /&gt;
&lt;br /&gt;
The debugger Pico serves both as a USB-to-SWD and USB-to-UART bridge to the target device. The development machine, therefore, needs to be connected via USB only to the debugger Pico. Console output on the target Pico is relayed through the debugger. It is possible, though, to connect a second USB cable from the development machine to the target device for (simultaneous) direct access to the console output. This debugger setup works not just with Pico targets but with any microcontroller that supports the CMSIS-DAP protocol over SWD.&lt;br /&gt;
&lt;br /&gt;
=== Software Tools for Debugging ===&lt;br /&gt;
Whether we use the Raspberry Pi Debug Probe or a spare Pico as debug probe, the software tools used for debugging are the same:&lt;br /&gt;
* openocd&lt;br /&gt;
&lt;br /&gt;
== Notes on Programming with the C SDK ==&lt;br /&gt;
&lt;br /&gt;
=== Async Context ===&lt;br /&gt;
In the C SDK, an [https://www.raspberrypi.com/documentation/pico-sdk/high_level.html#group_pico_async_context async_context] is used in concurrent programming to make sure that functions are executed on the same thread and in the order they were submitted, similar to dispatch queues in Apple&#039;s [https://developer.apple.com/documentation/dispatch?language=objc Dispatch framework]. The &#039;&#039;async_context&#039;&#039; data structure is a container of linked lists of worker functions that are executed within a single thread of a single processor core.&lt;br /&gt;
&lt;br /&gt;
=== Bluetooth ===&lt;br /&gt;
&lt;br /&gt;
The C SDK integrates the third-party [https://bluekitchen-gmbh.com/btstack BTstack] framework as its Bluetooth API that interfaces with the Infineon CYW43 wireless communication module (on Pico W models) via the Host-Controller Interface (HCI) protocol.&lt;br /&gt;
&lt;br /&gt;
The following articles by Hunter Adams offer a detailed analysis of how BTstack works on the Pico:&lt;br /&gt;
# [https://vanhunteradams.com/Pico/BLE/BTStack_HCI.html BTstack and RP2040: HCI (Host Controller Interface)].&amp;lt;br /&amp;gt;This article delves, among other things, into how the BTstack runloop is executed inside a Pico [[#Async_Context | async_context]].&amp;lt;br /&amp;gt;&amp;lt;blockquote&amp;gt;[...] we have just one &#039;&#039;when_pending_worker&#039;&#039; in our async_context. This worker is called &#039;&#039;cyw43_poll_worker&#039;&#039;, and its &#039;&#039;do_work&#039;&#039; function points to &#039;&#039;cyw43_poll_func()&#039;&#039;, listed above. This function ends up calling &#039;&#039;btstack_run_loop_poll_data_sources_from_irq()&#039;&#039;, about which we&#039;ll learn more shortly. This worker gets marked as pending in a GPIO interrupt. So, this provides a mechanism by which the CYW43 can tell the RP2040 to run &#039;&#039;btstack_run_loop_poll_data_sources_from_irq()&#039;&#039; which, as we&#039;re going to learn, goes and gets data from the device.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# [https://vanhunteradams.com/Pico/BLE/GATT_Server.html Building a Bluetooth GATT Server on the Pi Pico W]&lt;/div&gt;</summary>
		<author><name>Kai</name></author>
	</entry>
	<entry>
		<id>https://Robo.Fish/wiki/index.php?title=Raspberry_Pi_Microcontrollers&amp;diff=3272</id>
		<title>Raspberry Pi Microcontrollers</title>
		<link rel="alternate" type="text/html" href="https://Robo.Fish/wiki/index.php?title=Raspberry_Pi_Microcontrollers&amp;diff=3272"/>
		<updated>2025-05-06T06:17:12Z</updated>

		<summary type="html">&lt;p&gt;Kai: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Pico Series =&lt;br /&gt;
* Raspberry Pi Pico and Pico W&lt;br /&gt;
** Dual [https://developer.arm.com/Processors/Cortex-M0-Plus Arm Cortex-M0+] with Armv6-M programming model, up to 133 MHz&lt;br /&gt;
* Raspberry Pi Pico 2 and Pico 2 W&lt;br /&gt;
** Dual [https://developer.arm.com/Processors/Cortex-M33 Arm Cortex-M33] with Armv8-M programming model, up to 150 MHz&lt;br /&gt;
&lt;br /&gt;
== Development Setup ==&lt;br /&gt;
&lt;br /&gt;
=== Using the Raspberry Pi Debug Probe ===&lt;br /&gt;
The Debug Probe is a RP2040 based USB-to-UART/SWD board for connecting the USB slot of a development machine to the SWD or UART pins of a target device.&lt;br /&gt;
&lt;br /&gt;
=== Using A Pico To Debug Another Pico ===&lt;br /&gt;
A Pico can be used to debug another Pico (a.k.a. target device)  by flashing it with the [https://github.com/raspberrypi/debugprobe debugprobe] binary and wiring to the target Pico as shown below.&lt;br /&gt;
&lt;br /&gt;
[[File:Wiring_rpi_pico_as_debugger.png | x320 px | A Raspberry Pi Pico wired to debug another Pico]]&lt;br /&gt;
&lt;br /&gt;
From the debugger Pico to the target Pico,&lt;br /&gt;
* pin #4 (GP2) connects to pin SWCLK,&lt;br /&gt;
* pin #5 (GP3) connects to SWDIO,&lt;br /&gt;
* pin #6 (GP4, UART1 TX) connects to pin #2 (GP1, UART0 RX),&lt;br /&gt;
* pin #7 (GP5, UART1 RX) connects to pin #1 (GP0, UART0, TX).&lt;br /&gt;
&lt;br /&gt;
The debugger Pico serves both as a USB-to-SWD and USB-to-UART bridge to the target device. The development machine, therefore, needs to be connected via USB only to the debugger Pico. Console output on the target Pico is relayed through the debugger. It is possible, though, to connect a second USB cable from the development machine to the target device for (simultaneous) direct access to the console output. This debugger setup works not just with Pico targets but with any microcontroller that supports the CMSIS-DAP protocol over SWD.&lt;br /&gt;
&lt;br /&gt;
=== Software Tools for Debugging ===&lt;br /&gt;
Whether we use the Raspberry Pi Debug Probe or a spare Pico as debug probe, the software tools used for debugging are the same:&lt;br /&gt;
* openocd&lt;br /&gt;
&lt;br /&gt;
== Notes on Programming with the C SDK ==&lt;br /&gt;
&lt;br /&gt;
=== Async Context ===&lt;br /&gt;
In the C SDK, an [https://www.raspberrypi.com/documentation/pico-sdk/high_level.html#group_pico_async_context async_context] is used in concurrent programming to make sure that functions are executed on the same thread and in the order they were submitted, similar to dispatch queues in Apple&#039;s [https://developer.apple.com/documentation/dispatch?language=objc Dispatch framework]. The &#039;&#039;async_context&#039;&#039; data structure is a container of linked lists of worker functions that are executed within a single thread of a single processor core.&lt;br /&gt;
&lt;br /&gt;
=== Bluetooth ===&lt;br /&gt;
&lt;br /&gt;
The C SDK integrates the third-party [https://bluekitchen-gmbh.com/btstack BTstack] framework as its Bluetooth API that interfaces with the Infineon CYW43 wireless communication module (on Pico W models) via the Host-Controller Interface (HCI) protocol.&lt;br /&gt;
&lt;br /&gt;
The following articles by Hunter Adams offer a detailed analysis of how BTstack works on the Pico:&lt;br /&gt;
# [https://vanhunteradams.com/Pico/BLE/BTStack_HCI.html BTstack and RP2040: HCI (Host Controller Interface)]&lt;br /&gt;
# [https://vanhunteradams.com/Pico/BLE/GATT_Server.html Building a Bluetooth GATT Server on the Pi Pico W]&lt;br /&gt;
&lt;br /&gt;
The BTstack runloop is executed inside a Pico [[#Async_Context | async_context]]. This is explained in article 1:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
[...] we have just one &#039;&#039;when_pending_worker&#039;&#039; in our async_context. This worker is called &#039;&#039;cyw43_poll_worker&#039;&#039;, and its &#039;&#039;do_work&#039;&#039; function points to &#039;&#039;cyw43_poll_func()&#039;&#039;, listed above. This function ends up calling &#039;&#039;btstack_run_loop_poll_data_sources_from_irq()&#039;&#039;, about which we&#039;ll learn more shortly. This worker gets marked as pending in a GPIO interrupt. So, this provides a mechanism by which the CYW43 can tell the RP2040 to run &#039;&#039;btstack_run_loop_poll_data_sources_from_irq()&#039;&#039; which, as we&#039;re going to learn, goes and gets data from the device.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;/div&gt;</summary>
		<author><name>Kai</name></author>
	</entry>
	<entry>
		<id>https://Robo.Fish/wiki/index.php?title=LT1&amp;diff=3271</id>
		<title>LT1</title>
		<link rel="alternate" type="text/html" href="https://Robo.Fish/wiki/index.php?title=LT1&amp;diff=3271"/>
		<updated>2025-05-03T06:57:15Z</updated>

		<summary type="html">&lt;p&gt;Kai: /* RSA application */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
LT1 is the land training platform for learning vehicle maneuvering skills.&lt;br /&gt;
=== Software Components ===&lt;br /&gt;
==== RSA application ====&lt;br /&gt;
Software stack&lt;br /&gt;
* [https://gitlab.com/robo.fish/edc EDC] library for controlling electronic devices.&lt;br /&gt;
* Raspberry Pi Pico C SDK&lt;br /&gt;
* [https://bluekitchen-gmbh.com/btstack BTstack] for Bluetooth LE communication&lt;br /&gt;
&lt;br /&gt;
==== RTC application ====&lt;br /&gt;
* Uses the Core library.&lt;br /&gt;
* Operating environment based on Yocto 5.0 (Scarthgap)&lt;br /&gt;
* Uses the ROS 2 library.&lt;br /&gt;
=== Hardware Components ===&lt;br /&gt;
* [[Raspberry_Pi_Microcontrollers#Raspberry_Pi_Pico_Series | Raspberry Pi Pico W]] based [[Robot_State_Agent | RSA]] unit that controls the sensors and motors and provides remote control capabilities.&lt;br /&gt;
* [https://www.raspberrypi.com/products/compute-module-4/ Raspberry Pi Compute Module 4] based [[Robot_Task_Controller | RTC]] unit for computer vision and ROS integration.&lt;br /&gt;
* [https://www.waveshare.com/product/raspberry-pi/boards-kits/compute-module-4-4s-cat/cm4-nano-b.htm Waveshare Nano Base Board (B)] for Raspberry Pi Compute Module 4&lt;br /&gt;
* [https://www.raspberrypi.com/products/camera-module-v2 Raspberry Pi Camera Module 2]&lt;br /&gt;
* [[Arexx RP5]] tracked vehicle chassis with 2 DC motors.&lt;br /&gt;
* 7.4 V lithium-polymer battery&lt;br /&gt;
* Sensors&lt;br /&gt;
** [[HC-SR04]] ultrasonic range sensor&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
The design of LT1 is open. The project files are available [https://gitlab.com/robo.fish/robots/LT1 on GitLab].&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Roadmap ===&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:#888&amp;quot;&amp;gt;Structural design&amp;lt;/span&amp;gt;&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:#888&amp;quot;&amp;gt;Electrical design&amp;lt;/span&amp;gt;&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:#888&amp;quot;&amp;gt;Manufacturing&amp;lt;/span&amp;gt;&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:#888&amp;quot;&amp;gt;Basic functional software&amp;lt;/span&amp;gt;&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:#888&amp;quot;&amp;gt;Testing and debugging&amp;lt;/span&amp;gt;&lt;/div&gt;</summary>
		<author><name>Kai</name></author>
	</entry>
	<entry>
		<id>https://Robo.Fish/wiki/index.php?title=LT1&amp;diff=3270</id>
		<title>LT1</title>
		<link rel="alternate" type="text/html" href="https://Robo.Fish/wiki/index.php?title=LT1&amp;diff=3270"/>
		<updated>2025-05-02T22:06:12Z</updated>

		<summary type="html">&lt;p&gt;Kai: /* Hardware Components */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
LT1 is the land training platform for learning vehicle maneuvering skills.&lt;br /&gt;
=== Software Components ===&lt;br /&gt;
==== RSA application ====&lt;br /&gt;
* Uses the EDC library for controlling electronic devices.&lt;br /&gt;
* Uses the Raspberry Pi Pico C SDK&lt;br /&gt;
==== RTC application ====&lt;br /&gt;
* Uses the Core library.&lt;br /&gt;
* Operating environment based on Yocto 5.0 (Scarthgap)&lt;br /&gt;
* Uses the ROS 2 library.&lt;br /&gt;
=== Hardware Components ===&lt;br /&gt;
* [[Raspberry_Pi_Microcontrollers#Raspberry_Pi_Pico_Series | Raspberry Pi Pico W]] based [[Robot_State_Agent | RSA]] unit that controls the sensors and motors and provides remote control capabilities.&lt;br /&gt;
* [https://www.raspberrypi.com/products/compute-module-4/ Raspberry Pi Compute Module 4] based [[Robot_Task_Controller | RTC]] unit for computer vision and ROS integration.&lt;br /&gt;
* [https://www.waveshare.com/product/raspberry-pi/boards-kits/compute-module-4-4s-cat/cm4-nano-b.htm Waveshare Nano Base Board (B)] for Raspberry Pi Compute Module 4&lt;br /&gt;
* [https://www.raspberrypi.com/products/camera-module-v2 Raspberry Pi Camera Module 2]&lt;br /&gt;
* [[Arexx RP5]] tracked vehicle chassis with 2 DC motors.&lt;br /&gt;
* 7.4 V lithium-polymer battery&lt;br /&gt;
* Sensors&lt;br /&gt;
** [[HC-SR04]] ultrasonic range sensor&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
The design of LT1 is open. The project files are available [https://gitlab.com/robo.fish/robots/LT1 on GitLab].&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Roadmap ===&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:#888&amp;quot;&amp;gt;Structural design&amp;lt;/span&amp;gt;&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:#888&amp;quot;&amp;gt;Electrical design&amp;lt;/span&amp;gt;&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:#888&amp;quot;&amp;gt;Manufacturing&amp;lt;/span&amp;gt;&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:#888&amp;quot;&amp;gt;Basic functional software&amp;lt;/span&amp;gt;&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:#888&amp;quot;&amp;gt;Testing and debugging&amp;lt;/span&amp;gt;&lt;/div&gt;</summary>
		<author><name>Kai</name></author>
	</entry>
	<entry>
		<id>https://Robo.Fish/wiki/index.php?title=LT1&amp;diff=3269</id>
		<title>LT1</title>
		<link rel="alternate" type="text/html" href="https://Robo.Fish/wiki/index.php?title=LT1&amp;diff=3269"/>
		<updated>2025-05-02T21:54:12Z</updated>

		<summary type="html">&lt;p&gt;Kai: /* Hardware Components */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
LT1 is the land training platform for learning vehicle maneuvering skills.&lt;br /&gt;
=== Software Components ===&lt;br /&gt;
==== RSA application ====&lt;br /&gt;
* Uses the EDC library for controlling electronic devices.&lt;br /&gt;
* Uses the Raspberry Pi Pico C SDK&lt;br /&gt;
==== RTC application ====&lt;br /&gt;
* Uses the Core library.&lt;br /&gt;
* Operating environment based on Yocto 5.0 (Scarthgap)&lt;br /&gt;
* Uses the ROS 2 library.&lt;br /&gt;
=== Hardware Components ===&lt;br /&gt;
* [[Raspberry_Pi_Microcontrollers#Raspberry_Pi_Pico_Series | Raspberry Pi Pico W]] based [[Robot_State_Agent | RSA]] unit that controls the sensors and motors and provides remote control capabilities.&lt;br /&gt;
* [https://www.raspberrypi.com/products/compute-module-4/ Raspberry Pi Compute Module 4] based [[Robot_Task_Controller | RTC]] unit for computer vision and ROS integration.&lt;br /&gt;
* [https://www.waveshare.com/product/raspberry-pi/boards-kits/compute-module-4-4s-cat/cm4-nano-b.htm Waveshare Nano Base Board (B)] for Raspberry Pi Compute Module 4&lt;br /&gt;
* [[Arexx RP5]] tracked vehicle chassis with 2 DC motors.&lt;br /&gt;
* 7.4 V lithium-polymer battery&lt;br /&gt;
* Sensors&lt;br /&gt;
** [[HC-SR04]] ultrasonic range sensor&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
The design of LT1 is open. The project files are available [https://gitlab.com/robo.fish/robots/LT1 on GitLab].&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Roadmap ===&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:#888&amp;quot;&amp;gt;Structural design&amp;lt;/span&amp;gt;&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:#888&amp;quot;&amp;gt;Electrical design&amp;lt;/span&amp;gt;&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:#888&amp;quot;&amp;gt;Manufacturing&amp;lt;/span&amp;gt;&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:#888&amp;quot;&amp;gt;Basic functional software&amp;lt;/span&amp;gt;&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:#888&amp;quot;&amp;gt;Testing and debugging&amp;lt;/span&amp;gt;&lt;/div&gt;</summary>
		<author><name>Kai</name></author>
	</entry>
	<entry>
		<id>https://Robo.Fish/wiki/index.php?title=LT1&amp;diff=3268</id>
		<title>LT1</title>
		<link rel="alternate" type="text/html" href="https://Robo.Fish/wiki/index.php?title=LT1&amp;diff=3268"/>
		<updated>2025-05-02T18:50:58Z</updated>

		<summary type="html">&lt;p&gt;Kai: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
LT1 is the land training platform for learning vehicle maneuvering skills.&lt;br /&gt;
=== Software Components ===&lt;br /&gt;
==== RSA application ====&lt;br /&gt;
* Uses the EDC library for controlling electronic devices.&lt;br /&gt;
* Uses the Raspberry Pi Pico C SDK&lt;br /&gt;
==== RTC application ====&lt;br /&gt;
* Uses the Core library.&lt;br /&gt;
* Operating environment based on Yocto 5.0 (Scarthgap)&lt;br /&gt;
* Uses the ROS 2 library.&lt;br /&gt;
=== Hardware Components ===&lt;br /&gt;
* Raspberry Pi Pico W based [[Robot_State_Agent | RSA]] unit that controls the sensors and motors and provides remote control capabilities.&lt;br /&gt;
* Raspberry Pi 5 or 6 based [[Robot_Task_Controller | RTC]] unit for computer vision and ROS integration.&lt;br /&gt;
* [[Arexx RP5]] tracked vehicle chassis with 2 DC motors.&lt;br /&gt;
* 7.4 V lithium-polymer battery&lt;br /&gt;
* Sensors&lt;br /&gt;
** [[HC-SR04]] ultrasonic range sensor&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
The design of LT1 is open. The project files are available [https://gitlab.com/robo.fish/robots/LT1 on GitLab].&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
=== Roadmap ===&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:#888&amp;quot;&amp;gt;Structural design&amp;lt;/span&amp;gt;&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:#888&amp;quot;&amp;gt;Electrical design&amp;lt;/span&amp;gt;&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:#888&amp;quot;&amp;gt;Manufacturing&amp;lt;/span&amp;gt;&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:#888&amp;quot;&amp;gt;Basic functional software&amp;lt;/span&amp;gt;&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:#888&amp;quot;&amp;gt;Testing and debugging&amp;lt;/span&amp;gt;&lt;/div&gt;</summary>
		<author><name>Kai</name></author>
	</entry>
	<entry>
		<id>https://Robo.Fish/wiki/index.php?title=LT1&amp;diff=3267</id>
		<title>LT1</title>
		<link rel="alternate" type="text/html" href="https://Robo.Fish/wiki/index.php?title=LT1&amp;diff=3267"/>
		<updated>2025-05-02T18:29:28Z</updated>

		<summary type="html">&lt;p&gt;Kai: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
LT1 is the land training platform that the Core can be connected to in order to learn typical land vehicle maneuvering skills. It consists of&lt;br /&gt;
* [[Core Module | Core]]&lt;br /&gt;
* [[Arexx RP5]] tracked vehicle chassis with 2 DC motors.&lt;br /&gt;
* 7.4 V lithium-polymer battery&lt;br /&gt;
* Raspberry Pi Pico W based [[Robot_State_Agent | RSA]] unit that controls the sensors and motors and provides remote control capabilities.&lt;br /&gt;
* Raspberry Pi 5 or 6 based [[Robot_Task_Controller | RTC]] unit for computer vision and ROS integration.&lt;br /&gt;
* Sensors&lt;br /&gt;
** [[HC-SR04]] ultrasonic range sensor&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
The design of LT1 is open. The project files are available [https://gitlab.com/robo.fish/robots/LT1 on GitLab].&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
=== Roadmap ===&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:#888&amp;quot;&amp;gt;Structural design&amp;lt;/span&amp;gt;&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:#888&amp;quot;&amp;gt;Electrical design&amp;lt;/span&amp;gt;&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:#888&amp;quot;&amp;gt;Manufacturing&amp;lt;/span&amp;gt;&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:#888&amp;quot;&amp;gt;Basic functional software&amp;lt;/span&amp;gt;&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:#888&amp;quot;&amp;gt;Testing and debugging&amp;lt;/span&amp;gt;&lt;/div&gt;</summary>
		<author><name>Kai</name></author>
	</entry>
	<entry>
		<id>https://Robo.Fish/wiki/index.php?title=File:RP5_Chassis_3D_Model.png&amp;diff=3266</id>
		<title>File:RP5 Chassis 3D Model.png</title>
		<link rel="alternate" type="text/html" href="https://Robo.Fish/wiki/index.php?title=File:RP5_Chassis_3D_Model.png&amp;diff=3266"/>
		<updated>2025-05-02T18:17:55Z</updated>

		<summary type="html">&lt;p&gt;Kai: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Kai</name></author>
	</entry>
	<entry>
		<id>https://Robo.Fish/wiki/index.php?title=Arexx_RP5&amp;diff=3265</id>
		<title>Arexx RP5</title>
		<link rel="alternate" type="text/html" href="https://Robo.Fish/wiki/index.php?title=Arexx_RP5&amp;diff=3265"/>
		<updated>2025-05-02T18:17:35Z</updated>

		<summary type="html">&lt;p&gt;Kai: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:RP5_Chassis.jpg | x380px ]]&lt;br /&gt;
&lt;br /&gt;
The RP5 is a toy-sized barebones chassis for home robotics projects. It includes 2 DC motors, optical encoder wheels attached to the traction wheel axis, and a battery holder for 6 Mignon batteries. The RP5 is an obsolete product and has not been on sale for many years now.&lt;br /&gt;
&lt;br /&gt;
== RP6 ==&lt;br /&gt;
The RP6 was a tracked vehicle robot built on top of the RP5. It was designed by the company Arexx Engineering and sold in Germany by Conrad Electronics in the late 2010s. Arexx Engineering have since stopped operating their original website (http:arexx.com). Detailed information about the RP6 and the improved version &#039;&#039;RP6v2&#039;&#039; is still available on these websites:&lt;br /&gt;
* https://rn-wissen.de/wiki/index.php?title=RP6&lt;br /&gt;
* https://rn-wissen.de/wiki/index.php?title=RP6v2&lt;br /&gt;
&lt;br /&gt;
== 3D Models ==&lt;br /&gt;
A [https://www.freecad.org FreeCAD] model of the RP5 is available [https://gitlab.com/robo.fish/robots/hardware-design-library/-/blob/master/FreeCAD/RP5_CHASSIS.FCStd?ref_type=heads here].&lt;br /&gt;
&lt;br /&gt;
[[File:RP5_Chassis_3D_Model.png | x380px ]]&lt;/div&gt;</summary>
		<author><name>Kai</name></author>
	</entry>
	<entry>
		<id>https://Robo.Fish/wiki/index.php?title=Arexx_RP5&amp;diff=3264</id>
		<title>Arexx RP5</title>
		<link rel="alternate" type="text/html" href="https://Robo.Fish/wiki/index.php?title=Arexx_RP5&amp;diff=3264"/>
		<updated>2025-05-02T18:09:50Z</updated>

		<summary type="html">&lt;p&gt;Kai: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:RP5_Chassis.jpg | x380px ]]&lt;br /&gt;
&lt;br /&gt;
The RP5 is a toy-sized barebones chassis for home robotics projects. It includes 2 DC motors, optical encoder wheels attached to the traction wheel axis, and a battery holder for 6 Mignon batteries. The RP5 is an obsolete product and has not been on sale for many years now.&lt;br /&gt;
&lt;br /&gt;
== RP6 ==&lt;br /&gt;
The RP6 was a tracked vehicle robot built on top of the RP5. It was designed by the company Arexx Engineering and sold in Germany by Conrad Electronics in the late 2010s. Arexx Engineering have since stopped operating their original website (http:arexx.com). Detailed information about the RP6 and the improved version &#039;&#039;RP6v2&#039;&#039; is still available on these websites:&lt;br /&gt;
* https://rn-wissen.de/wiki/index.php?title=RP6&lt;br /&gt;
* https://rn-wissen.de/wiki/index.php?title=RP6v2&lt;br /&gt;
&lt;br /&gt;
== 3D Models ==&lt;br /&gt;
A [https://www.freecad.org FreeCAD] model of the RP5 is available [https://gitlab.com/robo.fish/robots/hardware-design-library/-/blob/master/FreeCAD/RP5_CHASSIS.FCStd?ref_type=heads here].&lt;/div&gt;</summary>
		<author><name>Kai</name></author>
	</entry>
	<entry>
		<id>https://Robo.Fish/wiki/index.php?title=Arexx_RP5&amp;diff=3263</id>
		<title>Arexx RP5</title>
		<link rel="alternate" type="text/html" href="https://Robo.Fish/wiki/index.php?title=Arexx_RP5&amp;diff=3263"/>
		<updated>2025-05-02T18:03:56Z</updated>

		<summary type="html">&lt;p&gt;Kai: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:RP5_Chassis.jpg | x380px ]]&lt;br /&gt;
&lt;br /&gt;
== RP5 and RP6 ==&lt;br /&gt;
The RP5 is the barebones chassis part of the Arexx &#039;&#039;RP6&#039;&#039;. The RP6 was a toy-sized tracked vehicle robotics kit designed by the company Arexx Engineering and sold by Conrad Electronics in Germany in 2018. Arexx Engineering have since stopped operating their original website (http:arexx.com). Detailed information about the RP6 and the improved version &#039;&#039;RP6v2&#039;&#039; is still available on these websites:&lt;br /&gt;
* https://rn-wissen.de/wiki/index.php?title=RP6&lt;br /&gt;
* https://rn-wissen.de/wiki/index.php?title=RP6v2&lt;br /&gt;
&lt;br /&gt;
== 3D Models ==&lt;br /&gt;
A [https://www.freecad.org FreeCAD] model of the RP5 is available [https://gitlab.com/robo.fish/robots/hardware-design-library/-/blob/master/FreeCAD/RP5_CHASSIS.FCStd?ref_type=heads here].&lt;/div&gt;</summary>
		<author><name>Kai</name></author>
	</entry>
	<entry>
		<id>https://Robo.Fish/wiki/index.php?title=File:RP5_Chassis.jpg&amp;diff=3262</id>
		<title>File:RP5 Chassis.jpg</title>
		<link rel="alternate" type="text/html" href="https://Robo.Fish/wiki/index.php?title=File:RP5_Chassis.jpg&amp;diff=3262"/>
		<updated>2025-05-02T18:03:18Z</updated>

		<summary type="html">&lt;p&gt;Kai: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Kai</name></author>
	</entry>
	<entry>
		<id>https://Robo.Fish/wiki/index.php?title=Arexx_RP5&amp;diff=3261</id>
		<title>Arexx RP5</title>
		<link rel="alternate" type="text/html" href="https://Robo.Fish/wiki/index.php?title=Arexx_RP5&amp;diff=3261"/>
		<updated>2025-05-02T18:00:57Z</updated>

		<summary type="html">&lt;p&gt;Kai: Adds image at the top&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:RP5_Chassis.jpg | x400px ]]&lt;br /&gt;
&lt;br /&gt;
== RP5 and RP6 ==&lt;br /&gt;
The RP5 is the barebones chassis part of the Arexx &#039;&#039;RP6&#039;&#039;. The RP6 was a toy-sized tracked vehicle robotics kit designed by the company Arexx Engineering and sold by Conrad Electronics in Germany in 2018. Arexx Engineering have since stopped operating their original website (http:arexx.com). Detailed information about the RP6 and the improved version &#039;&#039;RP6v2&#039;&#039; is still available on these websites:&lt;br /&gt;
* https://rn-wissen.de/wiki/index.php?title=RP6&lt;br /&gt;
* https://rn-wissen.de/wiki/index.php?title=RP6v2&lt;br /&gt;
&lt;br /&gt;
== 3D Models ==&lt;br /&gt;
A [https://www.freecad.org FreeCAD] model of the RP5 is available [https://gitlab.com/robo.fish/robots/hardware-design-library/-/blob/master/FreeCAD/RP5_CHASSIS.FCStd?ref_type=heads here].&lt;/div&gt;</summary>
		<author><name>Kai</name></author>
	</entry>
	<entry>
		<id>https://Robo.Fish/wiki/index.php?title=LT1&amp;diff=3260</id>
		<title>LT1</title>
		<link rel="alternate" type="text/html" href="https://Robo.Fish/wiki/index.php?title=LT1&amp;diff=3260"/>
		<updated>2025-05-02T17:58:34Z</updated>

		<summary type="html">&lt;p&gt;Kai: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
LT1 is the land training platform that the Core can be connected to in order to learn typical land vehicle maneuvering skills. It consists of&lt;br /&gt;
* [[Core Module | Core]]&lt;br /&gt;
* [[Arexx RP5]] tracked vehicle chassis with 2 DC motors.&lt;br /&gt;
* 11.1 V lithium-polymer battery&lt;br /&gt;
* Arduino-based power and motor control circuitry&lt;br /&gt;
* [[HC-SR04]] ultrasonic range sensor&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
The design of LT1 is open. The project files are available [https://gitlab.com/robo.fish/robots/LT1 on GitLab]. At the moment, there is only a FreeCAD model of the RP5.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
=== Roadmap ===&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:#888&amp;quot;&amp;gt;Structural design&amp;lt;/span&amp;gt;&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:#888&amp;quot;&amp;gt;Electrical design&amp;lt;/span&amp;gt;&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:#888&amp;quot;&amp;gt;Manufacturing&amp;lt;/span&amp;gt;&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:#888&amp;quot;&amp;gt;Basic functional software&amp;lt;/span&amp;gt;&lt;br /&gt;
* &amp;lt;span style=&amp;quot;color:#888&amp;quot;&amp;gt;Testing and debugging&amp;lt;/span&amp;gt;&lt;/div&gt;</summary>
		<author><name>Kai</name></author>
	</entry>
	<entry>
		<id>https://Robo.Fish/wiki/index.php?title=Arexx_RP5&amp;diff=3259</id>
		<title>Arexx RP5</title>
		<link rel="alternate" type="text/html" href="https://Robo.Fish/wiki/index.php?title=Arexx_RP5&amp;diff=3259"/>
		<updated>2025-05-02T17:55:36Z</updated>

		<summary type="html">&lt;p&gt;Kai: Created page with &amp;quot;== RP5 and RP6 == The RP5 is the barebones chassis part of the Arexx &amp;#039;&amp;#039;RP6&amp;#039;&amp;#039;. The RP6 was a toy-sized tracked vehicle robotics kit designed by the company Arexx Engineering and sold by Conrad Electronics in Germany in 2018. Arexx Engineering have since stopped operating their original website (http:arexx.com). Detailed information about the RP6 and the improved version &amp;#039;&amp;#039;RP6v2&amp;#039;&amp;#039; is still available on these websites: * https://rn-wissen.de/wiki/index.php?title=RP6 * https...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== RP5 and RP6 ==&lt;br /&gt;
The RP5 is the barebones chassis part of the Arexx &#039;&#039;RP6&#039;&#039;. The RP6 was a toy-sized tracked vehicle robotics kit designed by the company Arexx Engineering and sold by Conrad Electronics in Germany in 2018. Arexx Engineering have since stopped operating their original website (http:arexx.com). Detailed information about the RP6 and the improved version &#039;&#039;RP6v2&#039;&#039; is still available on these websites:&lt;br /&gt;
* https://rn-wissen.de/wiki/index.php?title=RP6&lt;br /&gt;
* https://rn-wissen.de/wiki/index.php?title=RP6v2&lt;br /&gt;
&lt;br /&gt;
== 3D Models ==&lt;br /&gt;
A [https://www.freecad.org FreeCAD] model of the RP5 is available [https://gitlab.com/robo.fish/robots/hardware-design-library/-/blob/master/FreeCAD/RP5_CHASSIS.FCStd?ref_type=heads here].&lt;/div&gt;</summary>
		<author><name>Kai</name></author>
	</entry>
	<entry>
		<id>https://Robo.Fish/wiki/index.php?title=HC-SR04&amp;diff=3258</id>
		<title>HC-SR04</title>
		<link rel="alternate" type="text/html" href="https://Robo.Fish/wiki/index.php?title=HC-SR04&amp;diff=3258"/>
		<updated>2025-05-02T17:39:56Z</updated>

		<summary type="html">&lt;p&gt;Kai: /* Wiring and Voltage Levels */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
[[File:sensor_HC-SR04_wiring.jpg | x600px ]]&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;p style=&amp;quot;text-align:justify; margin-top:1em&amp;quot;&amp;gt;&lt;br /&gt;
The information here about the HC-SR04 ultrasonic distance sensor is based on vendor datasheets and various online sources, including [http://www.modmypi.com/blog/hc-sr04-ultrasonic-range-sensor-on-the-raspberry-pi a ModMyPi article] for Raspberry Pi and [http://www.elecfreaks.com/store/download/product/Sensor/HC-SR04/HC-SR04_Ultrasonic_Module_User_Guide.pdf the Elecfreaks user guide] for integration into Arduino.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
=== Sensor Properties ===&lt;br /&gt;
{|&lt;br /&gt;
| Operating Voltage || 5 V DC &lt;br /&gt;
|-&lt;br /&gt;
| Operating Current || 15 mA&lt;br /&gt;
|-&lt;br /&gt;
| Operating Frequency || 40 kHz&lt;br /&gt;
|-&lt;br /&gt;
| Nearest Range || 3 cm&lt;br /&gt;
|-&lt;br /&gt;
| Farthest Range || 4 m&lt;br /&gt;
|-&lt;br /&gt;
| Beam Angle || 15 degrees&lt;br /&gt;
|-&lt;br /&gt;
| Input Trigger Signal || 10 μs TTL pulse (low: 0-0.8 V, high: 2 V to VCC, where VCC = 5 V ±10%)&lt;br /&gt;
|-&lt;br /&gt;
| Output Echo Signal || Output TTL level signal, proportional to range&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Wiring and Voltage Levels ===&lt;br /&gt;
The sensor module is connected via the four header pins on the board:&lt;br /&gt;
&lt;br /&gt;
[[File:sensor_HC-SR04_pin_assignment.png | 120px]]&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;Vcc&#039;&#039; for the 5 V supply voltage,&lt;br /&gt;
* &#039;&#039;Trig&#039;&#039; for the ultrasonic burst trigger signal input,&lt;br /&gt;
* &#039;&#039;Echo&#039;&#039; for the ultrasonic echo output signal, and&lt;br /&gt;
* &#039;&#039;Gnd&#039;&#039; for Ground.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p style=&amp;quot;text-align:justify;  margin-top:1em&amp;quot;&amp;gt;&lt;br /&gt;
The sensor circuit is designed for TTL-level signals (0 V for LOW and 5 V for HIGH) while the GPIO pins of most microcontrollers and single-board-computers (SBC) are designed for 3.3 V. We definitely need to drop the signal coming from the &#039;&#039;Echo&#039;&#039; pin to 3.3 V, otherwise we risk damaging the connected GPIO input. One would assume that we also need to transform the 3.3 V trigger signal from the GPIO to 5 V before feeding it to the &#039;&#039;Trig&#039;&#039; pin. Such a circuit is depicted below, where a simple voltage divider is used on &#039;&#039;Echo&#039;&#039; and a BJT transistor is used to step up the voltage for &#039;&#039;Trig&#039;&#039;.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
[[File:Sensor_HC-SR04_schematic_full_level_shifting.png | x250px ]]&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
It turns out that we don&#039;t need to shift the 3.3 V trigger GPIO output to 5 V. The &#039;&#039;Trig&#039;&#039; input of the HC-SR04 can be connected directly to the GPIO pin of the microcontroller or SBC because the HIGH voltage of the trigger pulse just needs to be higher than 2 V. The simplified circuit below, with just the voltage divider is our preferred solution then.&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
[[File:Sensor_HC-SR04_schematic_voltage_divider_only.png | x250px ]]&lt;br /&gt;
&lt;br /&gt;
=== Operation ===&lt;br /&gt;
The controller starts the range measurement by raising pin &#039;&#039;Trig&#039;&#039; to 5 V for at least 10 μs and thereby triggering eight 40 kHz ultrasonic pulses (beyond the 20 kHz high frequency limit of human hearing). The pulse waves bounce off any nearby objects and some are reflected back to the sensor. The sensor detects these reflected waves and raises the &#039;&#039;Echo&#039;&#039; pin to 5 V for a duration proportional to the distance of the objects that the waves are reflected from. &lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
[[File:sensor_HC-SR04_timing.png | 450px]]&lt;br /&gt;
&amp;lt;p style=&amp;quot;text-align:justify;  margin-top:2em;&amp;quot;&amp;gt;&lt;br /&gt;
A single range measurement is therefore performed like this:&lt;br /&gt;
* Initialize by setting the &#039;&#039;Trig&#039;&#039; and &#039;&#039;Echo&#039;&#039; pins to LOW.&lt;br /&gt;
* Raise the &#039;&#039;Trig&#039;&#039; pin to HIGH for at least 10 μs.&lt;br /&gt;
* Wait for a rising edge on the &#039;&#039;Echo&#039;&#039; pin, start a timer when detected.&lt;br /&gt;
* Wait for the falling edge on the &#039;&#039;Echo&#039;&#039; pin, stop the timer when detected.&lt;br /&gt;
* Calculate the distance from the time that the ultrasonic waves spent travelling in air (distance = time * velocity / 2, where the velocity of ultrasonic waves in air is 340 m/s).&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p style=&amp;quot;margin-top: 2em&amp;quot;&amp;gt;&lt;br /&gt;
This capture from an oscilloscope shows the short trigger pulse (blue), and the following long echo pulse (green) for an object placed approximately 12 cm in front of the sensor.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
[[File:Sensor_HC-SR04_signals.png | x400px ]]&lt;br /&gt;
&lt;br /&gt;
=== Limitations ===&lt;br /&gt;
The ultrasonic sensor is not able to measure distances to objects with highly diffuse surfaces or surfaces that are angled so that most incoming waves are reflected away from the sensor.&lt;br /&gt;
&lt;br /&gt;
=== Programming Examples ===&lt;br /&gt;
==== For Raspberry Pi, using Python ====&lt;br /&gt;
&lt;br /&gt;
Before trying out the code example below, make sure that Raspberry Pi GPIO support for the Python programming environment is installed via&lt;br /&gt;
&amp;lt;pre class=&amp;quot;terminal&amp;gt;&lt;br /&gt;
sudo apt install python-rpi.gpio&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
The code below assumes that the output to the sensor&#039;s &#039;&#039;Trig&#039;&#039; pin is connected to GPIO pin #23 and the input from the sensor&#039;s &#039;&#039;Echo&#039;&#039; pin is connected to GPIO pin #24.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import RPi.GPIO as GPIO&lt;br /&gt;
import time&lt;br /&gt;
GPIO.setmode(GPIO.BCM)&lt;br /&gt;
&lt;br /&gt;
TRIG = 23&lt;br /&gt;
ECHO = 24&lt;br /&gt;
&lt;br /&gt;
print &amp;quot;Distance Measurement In Progress&amp;quot;&lt;br /&gt;
&lt;br /&gt;
GPIO.setup(TRIG,GPIO.OUT)&lt;br /&gt;
GPIO.setup(ECHO,GPIO.IN)&lt;br /&gt;
&lt;br /&gt;
GPIO.output(TRIG, False)&lt;br /&gt;
print &amp;quot;Waiting For Sensor To Settle&amp;quot;&lt;br /&gt;
time.sleep(0.25)&lt;br /&gt;
&lt;br /&gt;
GPIO.output(TRIG, True)&lt;br /&gt;
time.sleep(0.00001)&lt;br /&gt;
GPIO.output(TRIG, False)&lt;br /&gt;
&lt;br /&gt;
while GPIO.input(ECHO)==0:&lt;br /&gt;
  pulse_start = time.time()&lt;br /&gt;
&lt;br /&gt;
while GPIO.input(ECHO)==1:&lt;br /&gt;
  pulse_end = time.time()      &lt;br /&gt;
&lt;br /&gt;
pulse_duration = pulse_end - pulse_start&lt;br /&gt;
&lt;br /&gt;
distance = pulse_duration * 17150&lt;br /&gt;
distance = round(distance, 2)&lt;br /&gt;
print &amp;quot;Distance:&amp;quot;,distance,&amp;quot;cm&amp;quot;&lt;br /&gt;
&lt;br /&gt;
GPIO.cleanup()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== For Raspberry Pi Pico, using the C SDK ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C++&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;hardware/gpio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;pico/stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;pico/types.h&amp;gt;&lt;br /&gt;
#include &amp;lt;pico/time.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// GPIO pins&lt;br /&gt;
const uint TRIG = 6;&lt;br /&gt;
const uint ECHO = 9;&lt;br /&gt;
&lt;br /&gt;
const uint64_t SpeedOfSound = 34300; // centimeters per second&lt;br /&gt;
&lt;br /&gt;
/// @return distance in centimeters, or -1 if there was an error&lt;br /&gt;
int measure()&lt;br /&gt;
{&lt;br /&gt;
	// configuring GPIO pins&lt;br /&gt;
	gpio_init(TRIG);&lt;br /&gt;
	gpio_set_dir(TRIG, GPIO_OUT);&lt;br /&gt;
	gpio_put(TRIG, false);&lt;br /&gt;
&lt;br /&gt;
	gpio_init(ECHO);&lt;br /&gt;
	gpio_set_dir(ECHO, GPIO_IN);&lt;br /&gt;
	gpio_set_input_enabled(ECHO, true);&lt;br /&gt;
&lt;br /&gt;
	absolute_time_t echoRiseTime = nil_time;&lt;br /&gt;
	absolute_time_t echoFallTime = nil_time;&lt;br /&gt;
	absolute_time_t echoTimeoutTime = nil_time;&lt;br /&gt;
&lt;br /&gt;
	// sending the trigger pulse&lt;br /&gt;
	gpio_put(TRIG, true);&lt;br /&gt;
	sleep_us(20); // must be at least 10 microseconds&lt;br /&gt;
	gpio_put(TRIG, false);&lt;br /&gt;
	echoTimeoutTime = make_timeout_time_ms(500); // 0.5 second&lt;br /&gt;
&lt;br /&gt;
	// waiting for the echo signal&lt;br /&gt;
	while (echoFallTime == nil_time) {&lt;br /&gt;
		sleep_us(3);&lt;br /&gt;
		auto now = get_absolute_time();&lt;br /&gt;
		if (now &amp;gt; echoTimeoutTime) {&lt;br /&gt;
			return -1;&lt;br /&gt;
		}&lt;br /&gt;
		bool const echoIsHigh = gpio_get(ECHO);&lt;br /&gt;
		if (echoRiseTime == nil_time) {&lt;br /&gt;
			if (echoIsHigh) {&lt;br /&gt;
				echoRiseTime = now;&lt;br /&gt;
			}&lt;br /&gt;
		} else if (echoIsHigh == false) {&lt;br /&gt;
			echoFallTime = now;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (echoRiseTime == nil_time || echoFallTime == nil_time || (echoRiseTime &amp;gt;= echoFallTime)) {&lt;br /&gt;
		return -1;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	// calculating the distance&lt;br /&gt;
	auto duration = echoFallTime - echoRiseTime;&lt;br /&gt;
	auto distance = (int)(duration * SpeedOfSound / 2 / 1000000);&lt;br /&gt;
	return distance;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Kai</name></author>
	</entry>
</feed>