Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: FatFileSystem mbed
Fork of BTstack by
Revision 6:cf06ba884429, committed 2013-02-20
- Comitter:
- todotani
- Date:
- Wed Feb 20 14:18:38 2013 +0000
- Parent:
- 5:5fb56e13a1f9
- Commit message:
- Change tick timer to 1ms. Change attribute 0xFFF1 as read of DigitalIn p5
Changed in this revision
--- a/BLE_demo.cpp Mon Feb 11 14:10:57 2013 +0000
+++ b/BLE_demo.cpp Wed Feb 20 14:18:38 2013 +0000
@@ -14,7 +14,7 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
* 4. This software may not be used in a commercial product
- * without an explicit license granted by the copyright holder.
+ * without an explicit license granted by the copyright holder.
*
* THIS SOFTWARE IS PROVIDED BY MATTHIAS RINGWALD AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@@ -32,7 +32,7 @@
*/
/* Change history
- 2013/2/10: by todotani
+ 2013/2/10: by todotani
Modified tick event handler
Modified LED control
- LED 3 flush when connected
@@ -41,6 +41,9 @@
2013/2/11: by todotani
Changed serial pc.baud (115200 to 921600) to avoid imcomplete connection issue
Disable btstack debug-log
+2013/2/20: by todotani
+ Change tick timer interval 250ms to 1ms
+ Change Attribute 0xFFF1 as read DigitalIn p5 of mbed
*/
//*****************************************************************************
@@ -59,6 +62,7 @@
#include "mbed.h"
Serial pc(USBTX, USBRX);
DigitalOut led1(LED1), led2(LED2), led3(LED3);
+DigitalIn sw1(p5);
// from btstack ble_server.c
#include "global.h"
@@ -83,19 +87,24 @@
static uint16_t att_response_size = 0;
static uint8_t att_response_buffer[28];
-void hexdump2(void *data, int size){
+static uint8_t switch_new_state = 1;
+static uint8_t switch_old_state = 1;
+
+void hexdump2(void *data, int size)
+{
int i;
- for (i=0; i<size;i++){
+ for (i=0; i<size; i++) {
log_info("%02X ", ((uint8_t *)data)[i]);
}
log_info("\n");
}
-static void att_try_respond(void){
+static void att_try_respond(void)
+{
if (!att_response_size) return;
if (!att_response_handle) return;
if (!hci_can_send_packet_now(HCI_ACL_DATA_PACKET)) return;
-
+
// update state before sending packet
uint16_t size = att_response_size;
att_response_size = 0;
@@ -103,9 +112,10 @@
}
-static void att_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *packet, uint16_t size){
+static void att_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *packet, uint16_t size)
+{
if (packet_type != ATT_DATA_PACKET) return;
-
+
att_response_handle = handle;
att_response_size = att_handle_request(&att_connection, packet, size, att_response_buffer);
att_try_respond();
@@ -113,28 +123,28 @@
// enable LE, setup ADV data
-static void packet_handler (void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
+static void packet_handler (void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size)
+{
static bd_addr_t addr;
- //uint8_t adv_data[] = { 02, 01, 05, 03, 02, 0xf0, 0xff };
// Data for advertisement and scan response
- const uint8_t adv_data[31]="\x02\x01\x05" "\x06\x09SBDBT" "\x03\x02\xf0\xff";
+ const uint8_t adv_data[31]="\x02\x01\x05" "\x05\x09mbed" "\x03\x02\xf0\xff";
switch (packet_type) {
-
+
case HCI_EVENT_PACKET:
switch (packet[0]) {
-
+
case BTSTACK_EVENT_STATE:
// bt stack activated, get started - set local name
if (packet[2] == HCI_STATE_WORKING) {
- log_info("Working!\n");
+ log_info("Working!\n");
hci_send_cmd(&hci_read_local_supported_features);
}
break;
-
+
case DAEMON_EVENT_HCI_PACKET_SENT:
att_try_respond();
break;
-
+
case HCI_EVENT_LE_META:
switch (packet[2]) {
case HCI_SUBEVENT_LE_CONNECTION_COMPLETE:
@@ -155,67 +165,67 @@
log_info("NOT CONNECTED\n");
}
break;
-
+
case HCI_EVENT_DISCONNECTION_COMPLETE:
att_response_handle =0;
att_response_size = 0;
-
+
// restart advertising
hci_send_cmd(&hci_le_set_advertise_enable, 1);
break;
-
+
case HCI_EVENT_COMMAND_COMPLETE:
- if (COMMAND_COMPLETE_EVENT(packet, hci_read_bd_addr)){
+ if (COMMAND_COMPLETE_EVENT(packet, hci_read_bd_addr)) {
bt_flip_addr(addr, &packet[6]);
log_info("BD ADDR: %s\n", bd_addr_to_str(addr));
break;
}
- if (COMMAND_COMPLETE_EVENT(packet, hci_read_local_supported_features)){
+ if (COMMAND_COMPLETE_EVENT(packet, hci_read_local_supported_features)) {
log_info("Local supported features: %04lX%04lX\n", READ_BT_32(packet, 10), READ_BT_32(packet, 6));
hci_send_cmd(&hci_set_event_mask, 0xffffffff, 0x20001fff);
break;
}
- if (COMMAND_COMPLETE_EVENT(packet, hci_set_event_mask)){
+ if (COMMAND_COMPLETE_EVENT(packet, hci_set_event_mask)) {
hci_send_cmd(&hci_write_le_host_supported, 1, 1);
break;
}
- if (COMMAND_COMPLETE_EVENT(packet, hci_write_le_host_supported)){
+ if (COMMAND_COMPLETE_EVENT(packet, hci_write_le_host_supported)) {
hci_send_cmd(&hci_le_set_event_mask, 0xffffffff, 0xffffffff);
break;
}
- if (COMMAND_COMPLETE_EVENT(packet, hci_le_set_event_mask)){
+ if (COMMAND_COMPLETE_EVENT(packet, hci_le_set_event_mask)) {
hci_send_cmd(&hci_le_read_buffer_size);
break;
}
- if (COMMAND_COMPLETE_EVENT(packet, hci_le_read_buffer_size)){
+ if (COMMAND_COMPLETE_EVENT(packet, hci_le_read_buffer_size)) {
log_info("LE buffer size: %u, count %u\n", READ_BT_16(packet,6), packet[8]);
- hci_send_cmd(&hci_le_read_supported_states);
- break;
+ hci_send_cmd(&hci_le_read_supported_states);
+ break;
}
- if (COMMAND_COMPLETE_EVENT(packet, hci_le_read_supported_states)){
- hci_send_cmd(&hci_le_set_advertising_parameters, 0x0400, 0x0800, 0, 0, 0, &addr, 0x07, 0);
- break;
+ if (COMMAND_COMPLETE_EVENT(packet, hci_le_read_supported_states)) {
+ hci_send_cmd(&hci_le_set_advertising_parameters, 0x0400, 0x0800, 0, 0, 0, &addr, 0x07, 0);
+ break;
}
- if (COMMAND_COMPLETE_EVENT(packet, hci_le_set_advertising_parameters)){
- hci_send_cmd(&hci_le_set_advertising_data, sizeof(adv_data), adv_data);
- break;
+ if (COMMAND_COMPLETE_EVENT(packet, hci_le_set_advertising_parameters)) {
+ hci_send_cmd(&hci_le_set_advertising_data, sizeof(adv_data), adv_data);
+ break;
}
- if (COMMAND_COMPLETE_EVENT(packet, hci_le_set_advertising_data)){
- hci_send_cmd(&hci_le_set_scan_response_data, 10, adv_data);
- break;
+ if (COMMAND_COMPLETE_EVENT(packet, hci_le_set_advertising_data)) {
+ hci_send_cmd(&hci_le_set_scan_response_data, 10, adv_data);
+ break;
}
- if (COMMAND_COMPLETE_EVENT(packet, hci_le_set_scan_response_data)){
- hci_send_cmd(&hci_le_set_advertise_enable, 1);
- break;
+ if (COMMAND_COMPLETE_EVENT(packet, hci_le_set_scan_response_data)) {
+ hci_send_cmd(&hci_le_set_advertise_enable, 1);
+ break;
}
- if (COMMAND_COMPLETE_EVENT(packet, hci_le_set_advertise_enable)){
+ if (COMMAND_COMPLETE_EVENT(packet, hci_le_set_advertise_enable)) {
hci_discoverable_control(1);
log_info("startup_state=1\n");
startup_state=1;
led1 = 0;
break;
}
-
+
}
}
}
@@ -227,35 +237,37 @@
static uint8_t ledvalue;
// read requests
-static uint16_t att_read_callback(uint16_t handle, uint16_t offset, uint8_t * buffer, uint16_t buffer_size){
+static uint16_t att_read_callback(uint16_t handle, uint16_t offset, uint8_t * buffer, uint16_t buffer_size)
+{
uint16_t ret=0,val;
- if(buffer){
+ if(buffer) {
log_info("READ Callback, handle %04x\n", handle);
led2 = 1;
}
- switch(handle){
- // Correspond to Characteristics 0xFFF1
- case 0x000b:
- ret=strlen((char*)strbuf);
- if(buffer && ret<=buffer_size){
- log_info("Read text: %s\n", strbuf);
- memcpy(buffer,strbuf,ret);
+ switch(handle) {
+ // Correspond to Characteristics 0xFFF1
+ case 0x000b:
+ if(buffer && ret<=buffer_size) {
+ buffer[0] = sw1.read();
+ log_info("Read value: %u\n", buffer[0]);
}
+ ret = 1;
break;
- // Correspond to Characteristics 0xFFF2
+ // Correspond to Characteristics 0xFFF2
case 0x000d:
- if(buffer && buffer_size){
+ if(buffer && buffer_size) {
+ ledvalue = led1;
+ buffer[0] = ledvalue;
log_info("Read value: %u\n", buffer[0]);
- buffer[0]=ledvalue;
}
ret=1;
break;
- // Correspond to Characteristics 0x00001234-0000-1000-8000-00805F9B34FB
+ // Correspond to Characteristics 0x00001234-0000-1000-8000-00805F9B34FB
case 0x000f:
- if(buffer && buffer_size>=2){
+ if(buffer && buffer_size>=2) {
val=timer_counter;
log_info("Read value: %u\n", val);
buffer[0]=val&0xff;
@@ -268,28 +280,21 @@
}
// write requests
-static void att_write_callback(uint16_t handle, uint16_t transaction_mode, uint16_t offset, uint8_t *buffer, uint16_t buffer_size, signature_t * signature){
+static void att_write_callback(uint16_t handle, uint16_t transaction_mode, uint16_t offset, uint8_t *buffer, uint16_t buffer_size, signature_t * signature)
+{
log_info("WRITE Callback, handle %04x\n", handle);
led2 = 0;
- switch(handle){
- // Correspond to Characteristics 0xFFF1
+ switch(handle) {
+ // Correspond to Characteristics 0xFFF1
case 0x000b:
- buffer[buffer_size]=0;
- if(sizeof(strbuf)>buffer_size){
- strcpy((char*)strbuf,(char*)buffer);
- }
- log_info("New text: %s\n", buffer);
+ log_info("No action\n");
break;
-
- // Correspond to Characteristics 0xFFF2
+
+ // Correspond to Characteristics 0xFFF2
case 0x000d:
log_info("New value: %u\n", buffer[0]);
- ledvalue=buffer[0];
- if (buffer[0]){
- led1 = 1;
- } else {
- led1 = 0;
- }
+ ledvalue = buffer[0];
+ led1 = ledvalue;
break;
}
}
@@ -299,9 +304,17 @@
{
timer_counter++;
- if(connection_status){
- led3 = !led3;
- }else{
+ if(connection_status) {
+ if(timer_counter % 250 == 0) {
+ led3 = !led3;
+ // Under testing
+ // switch_new_state = (uint8_t)sw1.read();
+ // if (switch_new_state != switch_old_state) {
+ // log_info("Fire notification\n");
+ // switch_old_state = switch_new_state;
+ // att_prepare_handle_value_notification(&att_connection, 0x000b, &switch_new_state, 1, att_response_buffer);
+ }
+ } else {
led3 = 1;
}
}
@@ -310,16 +323,18 @@
int main(void)
{
pc.baud(921600);
+ //pc.baud(230400);
log_info("%s\n", __FILE__);
// init LEDs
led1 = led2 = led3 = 1;
-
- /// GET STARTED with BTstack ///
+ ledvalue = led1;
+
+ /// GET STARTED with BTstack ///
btstack_memory_init();
run_loop_init(RUN_LOOP_EMBEDDED);
hal_tick_set_handler(&hal_tick_event);
-
+
// init HCI
// use BlueUSB
hci_transport_t* transport = hci_transport_usb_instance();
@@ -327,30 +342,30 @@
hci_uart_config_t * config = NULL;
remote_device_db_t * remote_db = (remote_device_db_t *) &remote_device_db_memory;
hci_init(transport, config, control, remote_db);
-
+
// use eHCILL
// bt_control_cc256x_enable_ehcill(1);
-
+
// set up l2cap_le
l2cap_init();
l2cap_register_fixed_channel(att_packet_handler, L2CAP_CID_ATTRIBUTE_PROTOCOL);
l2cap_register_packet_handler(packet_handler);
-
+
// set up ATT
att_set_db(profile_data);
att_set_write_callback(att_write_callback);
att_set_read_callback(att_read_callback);
att_dump_attributes();
att_connection.mtu = 27;
-
- log_info("Run...\n\r");
+
+ log_info("Run...\n\n");
// turn on!
hci_power_control(HCI_POWER_ON);
// go!
- run_loop_execute();
-
+ run_loop_execute();
+
// happy compiler!
return 0;
}
--- a/BTstack/att.c Mon Feb 11 14:10:57 2013 +0000
+++ b/BTstack/att.c Wed Feb 20 14:18:38 2013 +0000
@@ -38,6 +38,7 @@
#include <string.h>
#include "att.h"
+#include "debug.h"
// from src/utils.
#define READ_BT_16( buffer, pos) ( ((uint16_t) buffer[pos]) | (((uint16_t)buffer[pos+1]) << 8))
@@ -53,21 +54,21 @@
static void hexdump2(void const *data, int size){
int i;
for (i=0; i<size;i++){
- printf("%02X ", ((uint8_t *)data)[i]);
+ log_info("%02X ", ((uint8_t *)data)[i]);
}
- printf("\n");
+ log_info("\n");
}
static void printUUID128(const uint8_t * uuid){
int i;
for (i=15; i >= 0 ; i--){
- printf("%02X", uuid[i]);
+ log_info("%02X", uuid[i]);
switch (i){
case 4:
case 6:
case 8:
case 10:
- printf("-");
+ log_info("-");
break;
default:
break;
@@ -209,16 +210,16 @@
while (att_iterator_has_next(&it)){
att_iterator_fetch_next(&it);
if (it.handle == 0) {
- printf("Handle: END\n");
+ log_info("Handle: END\n");
return;
}
- printf("Handle: 0x%04x, flags: 0x%04x, uuid: ", it.handle, it.flags);
+ log_info("Handle: 0x%04x, flags: 0x%04x, uuid: ", it.handle, it.flags);
if (it.flags & ATT_PROPERTY_UUID128){
printUUID128(it.uuid);
} else {
- printf("%04x", READ_BT_16(it.uuid, 0));
+ log_info("%04x", READ_BT_16(it.uuid, 0));
}
- printf(", value_len: %u, value: ", it.value_len);
+ log_info(", value_len: %u, value: ", it.value_len);
hexdump2(it.value, it.value_len);
}
}
@@ -268,7 +269,7 @@
static uint16_t handle_find_information_request2(uint8_t * response_buffer, uint16_t response_buffer_size,
uint16_t start_handle, uint16_t end_handle){
- printf("ATT_FIND_INFORMATION_REQUEST: from %04X to %04X\n", start_handle, end_handle);
+ log_info("ATT_FIND_INFORMATION_REQUEST: from %04X to %04X\n", start_handle, end_handle);
uint16_t offset = 1;
uint16_t pair_len = 0;
@@ -283,7 +284,7 @@
att_update_value_len(&it);
- // printf("Handle 0x%04x\n", it.handle);
+ // log_debug("Handle 0x%04x\n", it.handle);
// check if value has same len as last one
uint16_t this_pair_len = 2 + it.value_len;
@@ -346,7 +347,7 @@
uint16_t start_handle, uint16_t end_handle,
uint16_t attribute_type, uint16_t attribute_len, uint8_t* attribute_value){
- printf("ATT_FIND_BY_TYPE_VALUE_REQUEST: from %04X to %04X, type %04X, value: ", start_handle, end_handle, attribute_type);
+ log_info("ATT_FIND_BY_TYPE_VALUE_REQUEST: from %04X to %04X, type %04X, value: ", start_handle, end_handle, attribute_type);
hexdump2(attribute_value, attribute_len);
uint16_t offset = 1;
@@ -365,7 +366,7 @@
if (in_group &&
(it.handle == 0 || att_iterator_match_uuid16(&it, GATT_PRIMARY_SERVICE_UUID) || att_iterator_match_uuid16(&it, GATT_SECONDARY_SERVICE_UUID))){
- printf("End of group, handle 0x%04x\n", prev_handle);
+ log_info("End of group, handle 0x%04x\n", prev_handle);
bt_store_16(response_buffer, offset, prev_handle);
offset += 2;
in_group = 0;
@@ -381,7 +382,7 @@
// does current attribute match
if (it.handle && att_iterator_match_uuid16(&it, attribute_type) && attribute_len == it.value_len && memcmp(attribute_value, it.value, it.value_len) == 0){
- printf("Begin of group, handle 0x%04x\n", it.handle);
+ log_info("Begin of group, handle 0x%04x\n", it.handle);
bt_store_16(response_buffer, offset, it.handle);
offset += 2;
in_group = 1;
@@ -410,7 +411,7 @@
uint16_t start_handle, uint16_t end_handle,
uint16_t attribute_type_len, uint8_t * attribute_type){
- printf("ATT_READ_BY_TYPE_REQUEST: from %04X to %04X, type: ", start_handle, end_handle);
+ log_info("ATT_READ_BY_TYPE_REQUEST: from %04X to %04X, type: ", start_handle, end_handle);
hexdump2(attribute_type, attribute_type_len);
uint16_t offset = 1;
@@ -482,14 +483,14 @@
//
static uint16_t handle_read_request2(uint8_t * response_buffer, uint16_t response_buffer_size, uint16_t handle){
- printf("ATT_READ_REQUEST: handle %04x\n", handle);
+ log_info("ATT_READ_REQUEST: handle %04x\n", handle);
att_iterator_t it;
int ok = att_find_handle(&it, handle);
if (!ok){
return setup_error_atribute_not_found(response_buffer, ATT_READ_REQUEST, handle);
}
-
+
att_update_value_len(&it);
uint16_t offset = 1;
@@ -515,7 +516,7 @@
// MARK: ATT_READ_BLOB_REQUEST 0x0c
//
static uint16_t handle_read_blob_request2(uint8_t * response_buffer, uint16_t response_buffer_size, uint16_t handle, uint16_t value_offset){
- printf("ATT_READ_BLOB_REQUEST: handle %04x, offset %u\n", handle, value_offset);
+ log_info("ATT_READ_BLOB_REQUEST: handle %04x, offset %u\n", handle, value_offset);
att_iterator_t it;
int ok = att_find_handle(&it, handle);
@@ -552,7 +553,7 @@
// MARK: ATT_READ_MULTIPLE_REQUEST 0x0e
//
static uint16_t handle_read_multiple_request2(uint8_t * response_buffer, uint16_t response_buffer_size, uint16_t num_handles, uint16_t * handles){
- printf("ATT_READ_MULTIPLE_REQUEST: num handles %u\n", num_handles);
+ log_info("ATT_READ_MULTIPLE_REQUEST: num handles %u\n", num_handles);
uint16_t offset = 1;
@@ -603,7 +604,7 @@
uint16_t start_handle, uint16_t end_handle,
uint16_t attribute_type_len, uint8_t * attribute_type){
- printf("ATT_READ_BY_GROUP_TYPE_REQUEST: from %04X to %04X, buffer size %u, type: ", start_handle, end_handle, response_buffer_size);
+ log_info("ATT_READ_BY_GROUP_TYPE_REQUEST: from %04X to %04X, buffer size %u, type: ", start_handle, end_handle, response_buffer_size);
hexdump2(attribute_type, attribute_type_len);
uint16_t offset = 1;
@@ -625,7 +626,7 @@
if (in_group &&
(it.handle == 0 || att_iterator_match_uuid16(&it, GATT_PRIMARY_SERVICE_UUID) || att_iterator_match_uuid16(&it, GATT_SECONDARY_SERVICE_UUID))){
// TODO: check if handle is included in start/end range
- // printf("End of group, handle 0x%04x, val_len: %u\n", prev_handle, pair_len - 4);
+ // log_debug("End of group, handle 0x%04x, val_len: %u\n", prev_handle, pair_len - 4);
bt_store_16(response_buffer, offset, group_start_handle);
offset += 2;
@@ -645,7 +646,7 @@
prev_handle = it.handle;
// does current attribute match
- // printf("compare: %04x == %04x\n", *(uint16_t*) context->attribute_type, *(uint16_t*) uuid);
+ // log_debug("compare: %04x == %04x\n", *(uint16_t*) context->attribute_type, *(uint16_t*) uuid);
if (it.handle && att_iterator_match_uuid(&it, attribute_type, attribute_type_len)) {
// check if value has same len as last one
@@ -656,7 +657,7 @@
}
}
- // printf("Begin of group, handle 0x%04x\n", it.handle);
+ // log_debug("Begin of group, handle 0x%04x\n", it.handle);
// first
if (offset == 1) {
@@ -865,7 +866,7 @@
handle_signed_write_command(request_buffer, request_len, response_buffer, response_buffer_size);
break;
default:
- printf("Unhandled ATT Command: %02X, DATA: ", request_buffer[0]);
+ log_info("Unhandled ATT Command: %02X, DATA: ", request_buffer[0]);
hexdump2(&request_buffer[9], request_len-9);
break;
}
--- a/BTstack/hal_mbed/hal_tick.cpp Mon Feb 11 14:10:57 2013 +0000
+++ b/BTstack/hal_mbed/hal_tick.cpp Wed Feb 20 14:18:38 2013 +0000
@@ -54,10 +54,10 @@
return;
}
tick_handler = handler;
- tick.attach(tick_handler, 0.25);
+ tick.attach(tick_handler, 0.001);
}
int hal_tick_get_tick_period_in_ms(void){
- return 250;
+ return 1;
}
--- a/BTstack/profile.h Mon Feb 11 14:10:57 2013 +0000
+++ b/BTstack/profile.h Wed Feb 20 14:18:38 2013 +0000
@@ -25,10 +25,10 @@
0x08, 0x00, 0x02, 0x00, 0x08, 0x00, 0x05, 0x2a,
// 0x0009 PRIMARY_SERVICE-FFF0
0x0a, 0x00, 0x02, 0x00, 0x09, 0x00, 0x00, 0x28, 0xf0, 0xff,
- // 0x000a CHARACTERISTIC-FFF1-READ | WRITE | DYNAMIC
- 0x0d, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x03, 0x28, 0x0a, 0x0b, 0x00, 0xf1, 0xff,
- // 0x000b VALUE-FFF1-READ | WRITE | DYNAMIC-
- 0x08, 0x00, 0x0a, 0x01, 0x0b, 0x00, 0xf1, 0xff,
+ // 0x000a CHARACTERISTIC-FFF1-READ | DYNAMIC
+ 0x0d, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x03, 0x28, 0x02, 0x0b, 0x00, 0xf1, 0xff,
+ // 0x000b VALUE-FFF1-READ | DYNAMIC-
+ 0x08, 0x00, 0x02, 0x01, 0x0b, 0x00, 0xf1, 0xff,
// 0x000c CHARACTERISTIC-FFF2-READ | WRITE | DYNAMIC
0x0d, 0x00, 0x02, 0x00, 0x0c, 0x00, 0x03, 0x28, 0x0a, 0x0d, 0x00, 0xf2, 0xff,
// 0x000d VALUE-FFF2-READ | WRITE | DYNAMIC-
