<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://devzone.nordicsemi.com/cfs-file/__key/system/syndication/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Simple Volume Control w/iOS</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/58799/simple-volume-control-w-ios</link><description>Hi, 
 I&amp;#39;m relatively new to your product line, but have been spending a bit of time trying to bring the volume control functionality into a SDK16/PCA10056/s140 configuration. I&amp;#39;m using the nRF52480DK. 
 I have worked through a number of button handling</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Tue, 10 Mar 2020 17:29:55 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/58799/simple-volume-control-w-ios" /><item><title>RE: Simple Volume Control w/iOS</title><link>https://devzone.nordicsemi.com/thread/239207?ContentTypeID=1</link><pubDate>Tue, 10 Mar 2020 17:29:55 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:62d38fbb-d30e-42a3-a11f-f673d550241a</guid><dc:creator>dr9</dc:creator><description>&lt;p&gt;Hi Hung,&lt;/p&gt;
&lt;p&gt;I managed to get it running late last night (SDK16.0 | s140).&amp;nbsp; Modifications are as follows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;bsp function was modified to handle button press/release events as follows:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;         // Volume Down
         case BSP_EVENT_KEY_2_RELEASE:
            if (m_conn_handle != BLE_CONN_HANDLE_INVALID)
            {
              consumer_control_send(RELEASE_KEY);
            }
            break;
        case BSP_EVENT_KEY_2:
            if (m_conn_handle != BLE_CONN_HANDLE_INVALID)
              {
              consumer_control_send(CONSUMER_CTRL_VOL_DW);
              }
          break;
&lt;/pre&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;button_leds_init:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;
/**@brief Function for initializing buttons and leds.
 *
 * @param[out] p_erase_bonds  Will be true if the clear bonding button was pressed to wake the application up.
 */
static void buttons_leds_init(bool * p_erase_bonds)
{
    ret_code_t err_code;
    bsp_event_t startup_event;

    err_code = bsp_init(BSP_INIT_LEDS | BSP_INIT_BUTTONS, bsp_event_handler);
    APP_ERROR_CHECK(err_code);

    err_code = bsp_btn_ble_init(NULL, &amp;amp;startup_event);
    APP_ERROR_CHECK(err_code);

    // define button release action
    // see bsp.h for additional details of expanded typedef enum expansion
    bsp_event_to_button_action_assign(3, BSP_BUTTON_ACTION_RELEASE, BSP_EVENT_KEY_3_RELEASE);
    bsp_event_to_button_action_assign(2, BSP_BUTTON_ACTION_RELEASE, BSP_EVENT_KEY_2_RELEASE);
    bsp_event_to_button_action_assign(1, BSP_BUTTON_ACTION_RELEASE, BSP_EVENT_KEY_1_RELEASE);
    bsp_event_to_button_action_assign(0, BSP_BUTTON_ACTION_RELEASE, BSP_EVENT_KEY_0_RELEASE);

    *p_erase_bonds = (startup_event == BSP_EVENT_CLEAR_BONDING_DATA);
}&lt;/pre&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the bsp.h file&amp;#39;s enum bsp_event_t was expanded to include four BSP_EVENT_KEY_0_RELEASE enumerations (where 0 is 0-3 for each button instance).&lt;/li&gt;
&lt;li&gt;and the hids_init function became:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;
/**@brief Function for initializing HID Service.
 */
static void hids_init(void)
{
    ret_code_t                    err_code;
    ble_hids_init_t               hids_init_obj;
    ble_hids_inp_rep_init_t     * p_input_report;
    ble_hids_outp_rep_init_t    * p_output_report;
    ble_hids_feature_rep_init_t * p_feature_report;
    uint8_t                       hid_info_flags;

    static ble_hids_inp_rep_init_t     input_report_array[1];
    static ble_hids_outp_rep_init_t    output_report_array[1];
    static ble_hids_feature_rep_init_t feature_report_array[1];
    static uint8_t report_map_data[] =
    {
        // Report ID 2: Advanced buttons
        0x05, 0x0C,                     // Usage Page (Consumer)
        0x09, 0x01,                     // Usage (Consumer Control)
        0xA1, 0x01,                     // Collection (Application)
        0x85, 0x02,                     //     Report Id (2)
        0x15, 0x00,                     //     Logical minimum (0)
        0x25, 0x01,                     //     Logical maximum (1)
        0x75, 0x01,                     //     Report Size (1)
        0x95, 0x01,                     //     Report Count (1)

        0x09, 0xCD,                     //     Usage (Play/Pause)
        0x81, 0x02,                     //     Input (Data,Value,Relative,Bit Field)
        0x0A, 0x83, 0x01,               //     Usage (AL Consumer Control Configuration)
        0x81, 0x02,                     //     Input (Data,Value,Relative,Bit Field)
        0x09, 0xB5,                     //     Usage (Scan Next Track)
        0x81, 0x02,                     //     Input (Data,Value,Relative,Bit Field)
        0x09, 0xB6,                     //     Usage (Scan Previous Track)
        0x81, 0x02,                     //     Input (Data,Value,Relative,Bit Field)

        0x09, 0xEA,                     //     Usage (Volume Down)
        0x81, 0x02,                     //     Input (Data,Value,Relative,Bit Field)
        0x09, 0xE9,                     //     Usage (Volume Up)
        0x81, 0x02,                     //     Input (Data,Value,Relative,Bit Field)
        0x0A, 0x25, 0x02,               //     Usage (AC Forward)
        0x81, 0x02,                     //     Input (Data,Value,Relative,Bit Field)
        0x0A, 0x24, 0x02,               //     Usage (AC Back)
        0x81, 0x02,                     //     Input (Data,Value,Relative,Bit Field)
        0xC0                            // End Collection		
    };

    memset((void *)input_report_array, 0, sizeof(ble_hids_inp_rep_init_t));
    memset((void *)output_report_array, 0, sizeof(ble_hids_outp_rep_init_t));
    memset((void *)feature_report_array, 0, sizeof(ble_hids_feature_rep_init_t));

    // Initialize HID Service
    p_input_report                      = &amp;amp;input_report_array[INPUT_REPORT_KEYS_INDEX];
    p_input_report-&amp;gt;max_len             = INPUT_REPORT_KEYS_MAX_LEN;
    p_input_report-&amp;gt;rep_ref.report_id   = INPUT_REP_REF_ID;
    p_input_report-&amp;gt;rep_ref.report_type = BLE_HIDS_REP_TYPE_INPUT;

    p_input_report-&amp;gt;sec.cccd_wr = SEC_JUST_WORKS;
    p_input_report-&amp;gt;sec.wr      = SEC_JUST_WORKS;
    p_input_report-&amp;gt;sec.rd      = SEC_JUST_WORKS;

    p_output_report                      = &amp;amp;output_report_array[OUTPUT_REPORT_INDEX];
    p_output_report-&amp;gt;max_len             = OUTPUT_REPORT_MAX_LEN;
    p_output_report-&amp;gt;rep_ref.report_id   = OUTPUT_REP_REF_ID;
    p_output_report-&amp;gt;rep_ref.report_type = BLE_HIDS_REP_TYPE_OUTPUT;

    p_output_report-&amp;gt;sec.wr = SEC_JUST_WORKS;
    p_output_report-&amp;gt;sec.rd = SEC_JUST_WORKS;
    
    // Consumer Control HID Service Init
    p_input_report                      = &amp;amp;input_report_array[INPUT_CCONTROL_KEYS_INDEX];
    p_input_report-&amp;gt;max_len             = INPUT_CC_REPORT_KEYS_MAX_LEN;
    p_input_report-&amp;gt;rep_ref.report_id   = INPUT_CC_REP_REF_ID;
    p_input_report-&amp;gt;rep_ref.report_type = BLE_HIDS_REP_TYPE_INPUT;

    p_input_report-&amp;gt;sec.cccd_wr = SEC_JUST_WORKS;
    p_input_report-&amp;gt;sec.wr      = SEC_JUST_WORKS;
    p_input_report-&amp;gt;sec.rd      = SEC_JUST_WORKS;
    
    // Feature Report Init
    p_feature_report                      = &amp;amp;feature_report_array[FEATURE_REPORT_INDEX];
    p_feature_report-&amp;gt;max_len             = FEATURE_REPORT_MAX_LEN;
    p_feature_report-&amp;gt;rep_ref.report_id   = FEATURE_REP_REF_ID;
    p_feature_report-&amp;gt;rep_ref.report_type = BLE_HIDS_REP_TYPE_FEATURE;

    p_feature_report-&amp;gt;sec.rd              = SEC_JUST_WORKS;
    p_feature_report-&amp;gt;sec.wr              = SEC_JUST_WORKS;

    hid_info_flags = HID_INFO_FLAG_REMOTE_WAKE_MSK | HID_INFO_FLAG_NORMALLY_CONNECTABLE_MSK;

    memset(&amp;amp;hids_init_obj, 0, sizeof(hids_init_obj));

    hids_init_obj.evt_handler                    = on_hids_evt;
    hids_init_obj.error_handler                  = service_error_handler;
    hids_init_obj.is_kb                          = true;
    hids_init_obj.is_mouse                       = false;
    hids_init_obj.inp_rep_count                  = 2;
    hids_init_obj.p_inp_rep_array                = input_report_array;
    hids_init_obj.outp_rep_count                 = 1;
    hids_init_obj.p_outp_rep_array               = output_report_array;
    hids_init_obj.feature_rep_count              = 1;
    hids_init_obj.p_feature_rep_array            = feature_report_array;
    hids_init_obj.rep_map.data_len               = sizeof(report_map_data);
    hids_init_obj.rep_map.p_data                 = report_map_data;
    hids_init_obj.hid_information.bcd_hid        = BASE_USB_HID_SPEC_VERSION;
    hids_init_obj.hid_information.b_country_code = 0;
    hids_init_obj.hid_information.flags          = hid_info_flags;
    hids_init_obj.included_services_count        = 0;
    hids_init_obj.p_included_services_array      = NULL;

    hids_init_obj.rep_map.rd_sec         = SEC_JUST_WORKS;
    hids_init_obj.hid_information.rd_sec = SEC_JUST_WORKS;

    hids_init_obj.boot_kb_inp_rep_sec.cccd_wr = SEC_JUST_WORKS;
    hids_init_obj.boot_kb_inp_rep_sec.rd      = SEC_JUST_WORKS;

    hids_init_obj.boot_kb_outp_rep_sec.rd = SEC_JUST_WORKS;
    hids_init_obj.boot_kb_outp_rep_sec.wr = SEC_JUST_WORKS;

    hids_init_obj.protocol_mode_rd_sec = SEC_JUST_WORKS;
    hids_init_obj.protocol_mode_wr_sec = SEC_JUST_WORKS;
    hids_init_obj.ctrl_point_wr_sec    = SEC_JUST_WORKS;

    err_code = ble_hids_init(&amp;amp;m_hids, &amp;amp;hids_init_obj);
    APP_ERROR_CHECK(err_code);
}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Thanks for the support.&amp;nbsp; More questions will likely follow as I build upon my current code.&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Dan&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Simple Volume Control w/iOS</title><link>https://devzone.nordicsemi.com/thread/239194?ContentTypeID=1</link><pubDate>Tue, 10 Mar 2020 16:36:01 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:7b1a83be-d0ab-4c45-bfe4-d31d327bfa3c</guid><dc:creator>Hung Bui</dc:creator><description>&lt;p&gt;Hi Dan,&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I am struggling to test the example in&amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="https://github.com/Rallare/nrf51_ble_app_hids_kbd_consumercontrol/tree/SDK15"&gt;https://github.com/Rallare/nrf51_ble_app_hids_kbd_consumercontrol/tree/SDK15&lt;/a&gt;&amp;nbsp;because of an hardfault in on_connect() function in ble_hids.c&amp;nbsp;&lt;/p&gt;
&lt;p&gt;But the one in SDK v11 in the same repo worked fine and I can control the volume on iPhone.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I also tested yours but saw the same issue as you have seen, no reaction on the phone.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;We would need more time to debug this. In the mean time, maybe you can have a look at the SDK v11 example and maybe can port the modification to SDK v16 ?&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Simple Volume Control w/iOS</title><link>https://devzone.nordicsemi.com/thread/238604?ContentTypeID=1</link><pubDate>Fri, 06 Mar 2020 17:30:40 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:419d26e9-9709-41fd-bd51-48b82a54892e</guid><dc:creator>dr9</dc:creator><description>&lt;p&gt;Hi Hung,&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Yes, I have extensively searched the devzone threads that are related to the issues I am having.&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I do have that usage page included in my main.c file.&amp;nbsp; It is appended to the usage page that comes built into the example you furnish.&amp;nbsp; I have also made the appropriate adjustments to the indicies.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Dan&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Simple Volume Control w/iOS</title><link>https://devzone.nordicsemi.com/thread/238590?ContentTypeID=1</link><pubDate>Fri, 06 Mar 2020 16:22:35 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:40a9a525-53fc-4d7c-9d9b-cd6d71168006</guid><dc:creator>Hung Bui</dc:creator><description>&lt;p&gt;Hi dr9,&lt;/p&gt;
&lt;p&gt;I don&amp;#39;t have much experience with this but have you checked the answer from Runar here:&amp;nbsp;&lt;a href="https://devzone.nordicsemi.com/f/nordic-q-a/13745/audio-controls-for-ios-and-android"&gt;https://devzone.nordicsemi.com/f/nordic-q-a/13745/audio-controls-for-ios-and-android&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Do you have the keyboard usage page included ?&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>