Riiiver Sample FW
With this sample firmware, you can learn how Riiiver works on the Qualcomm QCC5100.
The demonstration requires a smartphone(iOS or Android is OK) to install the sample app.
What this firmware does:
- Start advertising and connect with Smartphone
- Assign Riiiver function to the button of QCC5100.
- Send the command to the Smartphone via the button pressed, and QCC5100 receives the result from Riiiver.
- Display the result of Riiiver feature (called "iiidea").
Qualcomm devices [RiiiverSampleFW for QCC5100, QualComm Development Board (EVB)].
Riiiver device [smartphone, SampleApp for smartphone].
Cloud [Riiiver Server].
- Note
- - Qualcomm devices [RiiiverSampleFW for QCC5100, QualComm Development Board (EVB)].
- Riiiver device [smartphone, RiiiverSampleApp for smartphone].
- Cloud [Riiiver Server].
System Requirements
Software | version |
---|---|
windows | windows10 |
linux | v16.04 long-term support (LTS) or later |
Arm compiler | v6.14.1 or v6.15 |
Python | v3.8.10 |
LVGL | v8.3 |
Installation
Downloading the project, you will see flash.bin
under the /Binary
directory. Write that binary file to QCC5100, and you can run the demonstration.
. └── Binary/Flash.bin
The procedure how for writing the binary is described in QCC5100__Software_User_Guide: 5 Load QCC5100 images to device
. It can be operated with Linux or Windows.
Build
Riiiver Sample FW already complexed to the Binary File. So, you can write it without Build.
If you want to change the code of Riiiver Sample FW and to build.
Refer to QCC5100__Software_User_Guide: 4 Build software for QCC5100/QCC5100+
.
Use the following commands for build.
Windows:./build.bat --standalone_dutplus --auo-sod-97706 --enable_disp_hostless 2>&1 | tee build.log linux: ./build.sh --standalone_dutplus --auo-sod-97706 --enable_disp_hostless 2>&1 | tee build.log
Usage
Here, you can find a quick guide for the demonstration of Riiiver utilizing the QCC5100 UART serial interface-QCLI.
1.Turn on the QCC5100 after writing the flash.bin
, and you can find the Riiiver_Demo
is listed in the command list of the QCLI. Select the Riiiver_Demo
.
2.Run the 4 1
command to start the Riiiver_Demo
app.
3.Run the 4 2
command, which initializes the Riiiver_Demo
app and starts to advertising after completing the initialization.
When completing the initialization, the home screen appears on the display of the evaluation board(EVB).
4.Using the sample app in Smartphone, start scanning the peripheral devices nearby and connect to the EVB.
5.Set up the Riiiver features with the sample app. In details, also refer to the sample app document: How does this sample demonstrate?.
6.Run the 4 3 or 4 4 command, which corresponds to button 1 pressed or button 2 pressed respectively, FW will notify the event to the sample app as the BLE sequence.
Once you enter the 4 3
or 4 4
command, In the BLE sequence, While waiting for the response from the smartphone, the running animation appears on the display of the EVB.
- Note
- Another new command is not accepted while this animation is on.
7.You will see the result returned from the sample app on the display of the EVB.
Project structures
The Riiiver Sample FW
is made based on qcc5100-fr-1-0_ap_standard_oem
. The project structure is shown as follows. Most of the files used for the Riiiver demonstration are provided under the riiiver
directory.
. └── apps_proc/ └── fw/ └── app/ └── demo/ └── QCLI_demo/ └── src/ └── riiiver
File Name | What kind of features are implemented |
---|---|
riiiver_bluetooth | Bluetooth communication. |
riiiver_button | Manage the event regarding the physical button. |
riiiver_demo | The main() function for the Riiiver demonstration. |
riiiver_global_data | Declare variables globally. |
riiiver_gui | Graphic features. |
riiiver_util | Declare some functions commonly used. |
In addition, other changes have been made to work RiiiverDemo.
See the appendix for details below.
wear_bt_app_domain_interdace.c
BLE Specifications
The Riiiver Sample FW
provides an original GATT communication service. This section describes the characteristics that service has.
Here, let the EVB be the Qualcomm device (peripheral device) and the smartphone be the Riiiver device (central device).
The Qualcomm device is the GATT Server Role and the Riiiver device is the GATT Client Role.
The Qualcomm device advertises and the Riiver device scans and connects.
CustomService is a BLE Service that exists on the Qualcomm device side.
Peripheral Riiiver Service
The Peripheral Riiiver Service
exposes events and some data related to Qualcomm devices and Riiiver devices.
The service is identified with UUID 0000A000-0000-1000-8000-00805F9B34FB
.
This service consists of 2 characteristics, OnBoardUserEvent
characteristic and CommandReceiver
characteristic.
CharacteristicName | UUID | Properties | note |
---|---|---|---|
OnBoardUserEvent | 0000A001-0000-1000-8000-00805F9B34FB | Indicate | Shall be used to send the event that occured on the Qualcomm device. |
CommandReceiver | 0000A002-0000-1000-8000-00805F9B34FB | Write | Shall be used to recieve the result of an iiidea from Riiiver device. |
OnBoardUserEvent
The OnBoardUserEvent
is performed to send the event that occurred on the Qualcomm device.
Characteristic behavior
It is configured with the Client characteristic descriptor, If some event would be happens such as pressing the button of QCC5100 EVB, it will indicate the event information to Riiiver Device. The event types are defined as follows:
- The button 1 on the EVB is pressed
- The button 2 on the EVB is pressed
- An operation succeeds
- An operation fails
The send data value follows the format, which is described on Data format part later.
CommandReceiver
The CommandReceiver
is performed to recieve the result of an iiidea from Riiiver device.
Characteristic behavior
When CommandReceiver characteristic value is written by the Riiiver server,
Qualcomm device will interpret the value and display the result on its screen.
The value is required to follow in the Data format below.
Data format
The data sent between the client and the server is required to be formatted following specific rules. The data format is as follows:
The IDs for the OnBoardUserEvent characteristic
name | size | Constraints / Notes |
---|---|---|
Data Size | 2 byte | Must be little-endian. |
Command | 1 byte | This ID indicates the event type. This value is selected from the command list described below. |
Identification Data | X byte | For Command ID 0x2 or 0x3, Button1Event = 0x0, Button2Event = 0x1 is set. Normally, 0x0 is set. |
The Data format for the CommandReceiver characteristic
name | size | Constraints / Notes |
---|---|---|
Data Size | 2 byte | Must be little-endian. |
Command | 1 byte | This ID indicates the event type. This value is selected from the command list described below. |
iiidea Result | X byte | The result of the Riiiver feature(iiidea). |
Data Size
Data size describes as followings:
DataSize = Y[Byte], then X = Y-1[Byte]
The length of this data must be 2 bytes and to be in little-endian order.
Command
This ID indicates the event type. The command IDs are different according to the direction of the data, i.e. from the Qualcomm device to the Riiiver device or from the Riiiver device to the Qualcomm device.
The IDs for the OnBoardUserEvent characteristic
Id | command |
---|---|
0x00 | The button 1 on the EVB is pressed. |
0x01 | The button 2 on the EVB is pressed. |
0x02 | An operation succeeds. |
0x03 | An operation fails. |
The IDs for the CommandReceiver characteristic
Id | command |
---|---|
0x00 | The result of the iiidea kicked by pressing the button 1. |
0x01 | The result of the iiidea kicked by pressing the button 2. |
0x02 | Shall be used to send data by taking the Riiiver device as a starting point. |
0x03 | Shall be used to notify that some event succeeded. |
0x04 | Shall be used to notify that some event failed. |
Value to Display
The value (iiideea Result) includes the key, tab and String message to display the result on the screen.
The value can include a key that specifies the logo image appearing with the messages. The key and the messages must be separated by a tab character.
If only String message (text message) are present, the messages appear on the screen with the default logo image.
If a non-existent key is specified, "GUI DATA ERROR" will be displayed on the screen.
The format of the string is as follows.
Result key character code: UTF-8
Result string character code: UTF-8
Terminating character (NULL character): None
Keys for Logo
Key | iiidea that is expected to be used with | What it looks like |
---|---|---|
w_00 | weather | Sunny |
w_01 | weather | Cloudy |
w_02 | weather | Rainy |
w_03 | weather | Partly cloudy |
w_04 | weather | Partly rainy |
g_00 | Gmail | Mail envelope |
g_10 | Google Calendar | Calendar |
f_00 | Flight Information | Air plane |
s_00 | Sports Score | American Football |
s_10 | Sports Score | Basketball |
s_20 | Sports Score | Baseball |
s_30 | Sports Score | Ice Hockey |
Example: Execute an iiidea by pressing button
When the button1 on the EVB is pressed, the value of theOnBoardUserEvent
characteristic would be updated to 0x 02 00 00 00
.
The server that subscribes theOnBoardUserEvent
characteristic descriptor receives the updates and executes the iiidea according to the value.
Riiiver device receives the OnBoardUserEvent characteristic updates and will execute the iiidea according to command ID of the value.
After executing iiidea, Riiiver device writes the result of the iiidea as the value for the CommandReceiver
characteristic.
for example,
If the value set 0x 0b 00 00 77 5f 30 30 09 53 75 6e 6e 79,
field allocation would be bellow.
Data architecture is little-endian, So, “0b 00” can be replaced with “0x000b”.
Then, we can find the Data Size that the succeeding data length is 12 bytes.
The Command ID00
respresents that the value is the result of the iiidea kicked by pressing button 1(refer to Table The IDs for the OnBoardUserEvent characteristic).
The value to display 0x 77 5f 30 30 09 53 75 6e 6e 79
is decoded as follows:
decoded = w_00\tSunny
Therefore, in this case, the client shall display the message "Sunny" with the weather icon specified with key w_00
on its screen.
Seaquence
License
LVGL (https://lvgl.io/) is used to draw on the screen.
Follow MIT for the LVGL code.
(https://opensource.org/licenses/mit-license.php )
appendix
Riiiver Sample FW code changes for implementation
wear_bt_app_domain_interdace.c
. └── apps_proc/ └── fw/ └── app/ └── productsw/ └── wear_bt_app/ └── src/
Line: 48 - + #include "riiiver_bluetooth.h" Line: 119 - const uint8 btApp_adv_dataExtended[] = {11, 0x09, 'S', 'L', 'A', 'T', 'E', '_', '+' , '_', 'E', '\0'}; + const uint8 btApp_adv_dataExtended[] = {11, 0x09, 'R', 'i', 'i', 'i', 'v', 'e', 'r' ,'_', 'E', '\0'}; Line: 789 case QAPI_BT_GATT_SERVER_INIT_COMPLETE: { WEARBTAPP_LOG("QAPI_BT_GATT_SERVER_INIT_COMPLETE %x", id); /* Allocate Database in the stack*/- qapi_bt_GattServer_DBAllocRequest(&bt_gatt_server_task, 20, 1); + qapi_bt_GattServer_DBAllocRequest(&bt_gatt_server_task, 60, 1); } Line: 758 - 781 #ifdef WEAR_BT_ENABLE_EVENT_COUNTER_REPORTING - if(NULL != ind->bt_gatt_access_write_ind_message.writeUnit) - { - WEARBTAPP_LOG("<== QAPI_BT_GATT_SERVER_DB_ACCESS_WRITE_IND Attr hndl %d, value length: %d", - ind->bt_gatt_access_write_ind_message.writeUnit[0].attrHandle, ind->bt_gatt_access_write_ind_message.writeUnit[0].valueLength); - } - else - { - WEARBTAPP_LOG("<== QAPI_BT_GATT_SERVER_DB_ACCESS_WRITE_IND received write unit as NULL"); - } + boolean is_complete_receive = FALSE; + if(NULL != ind->bt_gatt_access_write_ind_message.writeUnit) + { + if(ind->bt_gatt_access_write_ind_message.attrHandle == 0x1b){ + WEARBTAPP_LOG("APP_TO_WATCH MESSAGE"); + is_complete_receive = riiiver_received_data_handler(ind->bt_gatt_access_write_ind_message.writeUnit[0].valueLength, + ind->bt_gatt_access_write_ind_message.writeUnit[0].value); + }else{ + WEARBTAPP_LOG("discard message" ); + } + } + else + { + WEARBTAPP_LOG("<== QAPI_BT_GATT_SERVER_DB_ACCESS_WRITE_IND received write unit as NULL"); + } Line: 2641-2687 head = qapi_BT_GATT_Util_Create_Primary_Service_With_16_Bit_Uuid(head, &attrHandle, 0xA000, /* Temp UUID */ FALSE, &tail); BT_APP_LOG("Sample GATT service attr hndl :%d",attrHandle); - properties = QAPI_BT_GATT_CHARAC_PROPERTIES_WRITE | QAPI_BT_GATT_CHARAC_PROPERTIES_READ | \ - QAPI_BT_GATT_CHARAC_PROPERTIES_NOTIFY | QAPI_BT_GATT_CHARAC_PROPERTIES_INDICATE; + properties = QAPI_BT_GATT_CHARAC_PROPERTIES_READ | QAPI_BT_GATT_CHARAC_PROPERTIES_INDICATE; attrValueFlags = (QAPI_BT_GATT_ATTR_FLAGS_IRQ_READ | QAPI_BT_GATT_ATTR_FLAGS_IRQ_WRITE); head = qapi_BT_GATT_Util_Create_Charac_Definition_With_16_Bit_Uuid(head, &attrHandle, properties, 0xA001, /* Temp UUID */ attrValueFlags, 2,value, &tail); BT_APP_LOG("Sample GATT characteristic attr hndl :%d",attrHandle); - head = qapi_BT_GATT_Util_Create_Client_Charac_Configuration(head, - &attrHandle, - CSR_BT_GATT_ATTR_FLAGS_IRQ_WRITE, - &tail); + head = qapi_BT_GATT_Util_Create_Client_Charac_Configuration(head, + &attrHandle, + CSR_BT_GATT_ATTR_FLAGS_IRQ_WRITE, + &tail); + BT_APP_LOG("Sample GATT CCCD attr hndl :%d",attrHandle); + properties = QAPI_BT_GATT_CHARAC_PROPERTIES_WRITE; + attrValueFlags = (QAPI_BT_GATT_ATTR_FLAGS_IRQ_READ | QAPI_BT_GATT_ATTR_FLAGS_IRQ_WRITE); + head = qapi_BT_GATT_Util_Create_Charac_Definition_With_16_Bit_Uuid(head, + &attrHandle, + properties, + 0xA002, /* Temp UUID */+ attrValueFlags, + 2,value, + &tail); + + BT_APP_LOG("Sample GATT characteristic attr hndl :%d",attrHandle); + + + head = qapi_BT_GATT_Util_Create_Client_Charac_Configuration(head, + &attrHandle, + CSR_BT_GATT_ATTR_FLAGS_IRQ_WRITE, + &tail); Line 2940-2987 case BT_APP_SEND_GATT_NOTIFICATION: { /* Hardcoded, to be fetched from database source*/ uint16_t handle = 0x18; Wear_Bt_App_Context_t* app_context = BTApp_GetContext(); qapi_BT_Conn_Id_t activeBtConnId = app_context->cid; - uint16_t len = 2; - uint8_t *value = malloc(len); + uint16_t len = (((uint8*)(data->params))[0]); + uint8_t *value; + value = malloc(len+1); if(value == NULL) { /* Error fatal. malloc failure */ WEARBTAPP_ERROR_FATAL_LOG("malloc failure"); } else { - value[0] = (((uint8*)(data->params))[0]); - value[1] = (((uint8*)(data->params))[1]); + value[0] = (((uint8*)(data->params))[0]); + value[1] = (((uint8*)(data->params))[1]); + value[2] = (((uint8*)(data->params))[2]); WEARBTAPP_LOG("==> qapi_BT_GATT_Indication_Req"); - qapi_bt_GattServer_NotificationReq(&bt_gatt_server_task, activeBtConnId, handle, len+1, value); + qapi_bt_GattServer_NotificationReq(&bt_gatt_server_task, activeBtConnId, handle, len, value); } break; } case BT_APP_SEND_GATT_INDICATION: { /* Hardcoded, to be fetched from database source*/ uint16_t handle = 0x18; Wear_Bt_App_Context_t* app_context = BTApp_GetContext(); qapi_BT_Conn_Id_t activeBtConnId = app_context->cid; - uint16_t len = 2; - uint8_t *value = malloc(len); + uint16_t len = (((uint8*)(data->params))[0]); + uint8_t *value; + value = malloc(len+1); if(value == NULL) { /* Error fatal. malloc failure */ WEARBTAPP_ERROR_FATAL_LOG("malloc failure"); } else { - value[0] = (((uint8*)(data->params))[0]); - value[1] = (((uint8*)(data->params))[1]); + value[0] = (((uint8*)(data->params))[0]); + value[1] = (((uint8*)(data->params))[1]); + value[2] = (((uint8*)(data->params))[2]); WEARBTAPP_LOG("==> qapi_BT_GATT_Indication_Req"); - qapi_bt_GattServer_IndicationReq(&bt_gatt_server_task, activeBtConnId, handle, len, value); + qapi_bt_GattServer_IndicationReq(&bt_gatt_server_task, activeBtConnId, handle, len+1, value); break; }