<?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>Smart Remote 3 - Firmware Architecture Replication SDK 16.0.0</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/58865/smart-remote-3---firmware-architecture-replication-sdk-16-0-0</link><description>I recently came across the Smart Remote 3 product by Nordic. I currently have a product in development that is a remote that has very similar functionality. Even down to the key scan chip SX1509. I just developed a shield to go with the nRF52840 DK that</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Mon, 12 Oct 2020 09:08:40 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/58865/smart-remote-3---firmware-architecture-replication-sdk-16-0-0" /><item><title>RE: Smart Remote 3 - Firmware Architecture Replication SDK 16.0.0</title><link>https://devzone.nordicsemi.com/thread/274232?ContentTypeID=1</link><pubDate>Mon, 12 Oct 2020 09:08:40 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:5ab341c4-bfd6-46fe-891a-bc4bd69538b7</guid><dc:creator>Einar Thorsrud</dc:creator><description>&lt;p&gt;Hi Matt,&lt;/p&gt;
&lt;p&gt;Thank you for the feedback. It is good to hear you got it working.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Smart Remote 3 - Firmware Architecture Replication SDK 16.0.0</title><link>https://devzone.nordicsemi.com/thread/274093?ContentTypeID=1</link><pubDate>Fri, 09 Oct 2020 15:11:07 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:34980f3d-3898-4edf-b546-16b5fed2d39c</guid><dc:creator>matt_wilson</dc:creator><description>&lt;p&gt;Einar,&lt;/p&gt;
&lt;p&gt;Little behind on my reply but I did eventually get it to work. &amp;nbsp;I just can&amp;#39;t remember now what I did that made it work. &amp;nbsp;I do believe your question around structure being too large triggered the correct fix. &amp;nbsp;Thank you for your support.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Smart Remote 3 - Firmware Architecture Replication SDK 16.0.0</title><link>https://devzone.nordicsemi.com/thread/262859?ContentTypeID=1</link><pubDate>Mon, 03 Aug 2020 17:09:15 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:8ed9aeef-64ca-4811-822b-2e171c98595d</guid><dc:creator>Einar Thorsrud</dc:creator><description>&lt;p&gt;Hi,&lt;/p&gt;
&lt;p&gt;I do not see why having a uint32_t should cause a problem in itself. Could it be that this made the structure too large to fit in element size you had configured for the memory pool?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Smart Remote 3 - Firmware Architecture Replication SDK 16.0.0</title><link>https://devzone.nordicsemi.com/thread/262679?ContentTypeID=1</link><pubDate>Sun, 02 Aug 2020 17:44:49 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:13e8db08-9aab-4814-95bf-b957877be732</guid><dc:creator>matt_wilson</dc:creator><description>&lt;p&gt;Einar,&lt;/p&gt;
&lt;p&gt;Thanks for the reply. &amp;nbsp;After some long trial and error I did find the issue that I was experiencing. &amp;nbsp;For some reason NRF_BALLOC didn&amp;#39;t like having uint32_t for the hid usage in the event_t struct. &amp;nbsp;Just by commenting it out fixed it for now. &amp;nbsp;I still don&amp;#39;t know the root cause for the issue and why NRF_BALLOC couldn&amp;#39;t handle&amp;nbsp;uint32_t. &amp;nbsp;Do you have any ideas?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Smart Remote 3 - Firmware Architecture Replication SDK 16.0.0</title><link>https://devzone.nordicsemi.com/thread/262102?ContentTypeID=1</link><pubDate>Wed, 29 Jul 2020 07:04:05 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:6f76e77b-d6df-4926-8206-f37e571059f2</guid><dc:creator>Einar Thorsrud</dc:creator><description>&lt;p&gt;Hi Matt,&lt;/p&gt;
&lt;p&gt;I am sorry for the late reply. Did you make progress on this, or is the question from June 30 still relevant?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Smart Remote 3 - Firmware Architecture Replication SDK 16.0.0</title><link>https://devzone.nordicsemi.com/thread/257477?ContentTypeID=1</link><pubDate>Tue, 30 Jun 2020 02:08:48 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:8dd7528f-6aa1-49ab-91f6-18e92188a7ba</guid><dc:creator>matt_wilson</dc:creator><description>&lt;p&gt;Einar,&lt;/p&gt;
&lt;p&gt;I have decided to only replicate some of the high level design concepts of the Smart Remote. &amp;nbsp;I had a 3 month pause on the project but now I&amp;#39;m back on it. I am having an issue with the Event Bus&amp;nbsp;where when I submit an event it is allocating memory for it through a BALLOC pool. &amp;nbsp;When the application scheduler wakes up and process the event the point that is associated with the event has corrupted or partial data. &amp;nbsp;I do you have any suggestions of what could be causing this? &amp;nbsp;At first I thought it could have been the union structure in the event struct but can&amp;#39;t locate the issue. &amp;nbsp;Thanks for your guidence.&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;#ifndef __M_EVENT_BUS_H__
#define __M_EVENT_BUS_H__

// System Includes
#include &amp;lt;stdint.h&amp;gt;
#include &amp;lt;stdbool.h&amp;gt;

// nRF SDK Includes
#include &amp;quot;sdk_errors.h&amp;quot;

/**@brief Translate event type to event group. */
#define EVENT_GROUP(_event_type) (event_group_t)((unsigned long)(_event_type) &amp;gt;&amp;gt; 8)

/**@brief Event groups. */
typedef enum
{
    EVT_GROUP_SYSTEM,       /**&amp;lt; System state events. */
    EVT_GROUP_KEYPAD,       /**&amp;lt; Keypad input events. */
    EVT_GROUP_HID,          /**&amp;lt; HID report events. */
    EVT_GROUP_BT,           /**&amp;lt; Bluetooth events. */
    EVT_GROUP_DISPLAY,      /**&amp;lt; Display events. */
    EVT_GROUP_HAPTIC,       /**&amp;lt; Haptic events */
} event_group_t;

/**@brief Event types. */
typedef enum
{
    /* System Events */
    EVT_SYSTEM_BATTERY_LEVEL    = (EVT_GROUP_SYSTEM &amp;lt;&amp;lt; 8),

    /* Keypad input events */
    EVT_KEY_PRESS               = (EVT_GROUP_KEYPAD &amp;lt;&amp;lt; 8),

    /* HID report events */
    EVT_HID_REPORT_INPUT        = (EVT_GROUP_HID &amp;lt;&amp;lt; 8),
    EVT_HID_REPORT_OUTPUT,
    EVT_HID_REPORT_FEATURE,

    /* Bluetooth events */
    EVT_BT_CONN_STATE           = (EVT_GROUP_BT &amp;lt;&amp;lt; 8),
    EVT_BT_ADV_STATE,
    EVT_BT_ALERT_LEVEL,
    EVT_BT_DFU_STATE,
    EVT_BT_SIG_STRENGTH,

    /* Display events */
    EVT_DISPLAY_REFRESH         = (EVT_GROUP_DISPLAY &amp;lt;&amp;lt; 8),

    /* Haptic Events */
    EVT_HAPTIC_STATE            = (EVT_GROUP_HAPTIC &amp;lt;&amp;lt; 8),

} event_type_t;

typedef struct
{
    event_type_t type;

    union {
        // Valid for EVT_GROUP_SYSTEM.
        struct {
            uint8_t    data;
        } system;

        // Valid for EVT_GROUP_KEYPAD.
        struct {
            uint8_t    code;
            uint8_t    action_type;
        } keypad;

        // Valid for EVT_GROUP_HID,
        struct {
            uint32_t   usage;
            int16_t    report;
        } hid;

        // Valid for EVT_GROUP_BT,
        struct {
            uint8_t    data;
            uint16_t   conn_id;
            uint16_t   peer_id;
        } bt;
    };
} event_t;

// EVT_BT_CONN_STATE data
#define BT_CONN_STATE_DISCONNECTED      0
#define BT_CONN_STATE_CONNECTED         1
#define BT_CONN_STATE_SECURED           2

// EVT_BT_ADV_STATE data
#define BT_ADV_STATE_IDLE               0
#define BT_ADV_STATE_ACTIVE             1
#define BT_ADV_STATE_ACTIVE_BONDABLE    2

// EVT_BT_SIG_STRENGTH data
#define BT_SIG_STRENGTH_1               1
#define BT_SIG_STRENGTH_2               2
#define BT_SIG_STRENGTH_3               3
#define BT_SIG_STRENGTH_4               4
#define BT_SIG_STRENGTH_5               5

/**@brief Event handler.
 *
 * @param[in]   p_event Pointer to the event structure.
 *
 * @return      True if further processing of the given event should be abandoned.
 */
typedef bool (*event_handler_t)(const event_t *p_event);


/**@brief Function for initializing the event bus.
 *
 * @param[in]   event_handlers_table    Table with event handlers.
 *
 * @return      NRF_SUCCESS on success, otherwise an error code.
 */
ret_code_t event_bus_init(const event_handler_t *event_handlers_table);


/**@brief Function for sending an event.
 *
 * @param[in]   event_type  Event type.
 * @param[in]   ...         Event data.
 *
 * @note                    Event data elements are mapped one to one to data fields in the event structure.
 *
 * @return      NRF_SUCCESS on success, otherwise an error code.
 */
ret_code_t event_send(event_type_t event_type, ...);

#endif /* __M_EVENT_BUS_H__ */&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;#include &amp;quot;m_event_bus.h&amp;quot;

// System Includes
#include &amp;lt;stdarg.h&amp;gt;

// nRF SDK Includes
#include &amp;quot;nrf_balloc.h&amp;quot;
#include &amp;quot;app_scheduler.h&amp;quot;

#include &amp;quot;app_config.h&amp;quot;
#include &amp;quot;resources.h&amp;quot;

#define NRF_LOG_MODULE_NAME m_event_bus
#define NRF_LOG_LEVEL       CONFIG_EVENT_BUS_LOG_LEVEL
#include &amp;quot;nrf_log.h&amp;quot;
NRF_LOG_MODULE_REGISTER();

static const event_handler_t   *sp_event_handlers;  /**&amp;lt; Pointer to the event handlers table. */

// Define event allocator.
NRF_BALLOC_DEF(s_event_pool, sizeof(event_t), CONFIG_EVENT_POOL_SIZE);

#if CONFIG_EVENT_MONITOR_ENABLED
/**@brief Translate event type to string. */
static const char *event_type_str(const event_t *p_event) {
    ASSERT(p_event != NULL);

    switch (p_event-&amp;gt;type) {
        #define EVT2STR(_event_type); case _event_type: return #_event_type
            EVT2STR(EVT_SYSTEM_BATTERY_LEVEL)
            EVT2STR(EVT_KEY_PRESS);
            EVT2STR(EVT_BT_CONN_STATE);
            EVT2STR(EVT_BT_ADV_STATE);
            EVT2STR(EVT_BT_ALERT_LEVEL);
            EVT2STR(EVT_BT_DFU_STATE);
            EVT2STR(EVT_BT_SIG_STRENGTH);
            EVT2STR(EVT_DISPLAY_REFRESH);
            EVT2STR(EVT_HAPTIC_STATE);
        #undef EVT2STR

        default:
            return &amp;quot;UNKNOWN&amp;quot;;
    }
}

/**@brief Dump event in human-readable format. */
static void event_dump(const event_t *p_event) {
    uint32_t hold_time;

    switch (EVENT_GROUP(p_event-&amp;gt;type)) {
        case EVT_GROUP_SYSTEM:
            NRF_LOG_INFO(&amp;quot;&amp;lt; %s: %u &amp;gt;&amp;quot;, (uint32_t)event_type_str(p_event), p_event-&amp;gt;system.data);
            break;

        case EVT_GROUP_KEYPAD:
            NRF_LOG_INFO(&amp;quot;&amp;lt; %s: Code[0x%X] Action[0x%X] &amp;gt;&amp;quot;,
                      (uint32_t)event_type_str(p_event),
                      p_event-&amp;gt;keypad.code,
                      p_event-&amp;gt;keypad.action_type);
            break;

        case EVT_GROUP_HID:
            NRF_LOG_INFO(&amp;quot;&amp;lt; %s: 0x%04X:0x%04X %d &amp;gt;&amp;quot;, (uint32_t)event_type_str(p_event),
                         HID_USAGE_PAGE(p_event-&amp;gt;hid.usage), HID_USAGE_ID(p_event-&amp;gt;hid.usage),
                         p_event-&amp;gt;hid.report);
            break;

        case EVT_GROUP_BT:
            NRF_LOG_INFO(&amp;quot;&amp;lt; %s: %u 0x%04X 0x%04X &amp;gt;&amp;quot;,
                         (uint32_t)event_type_str(p_event),
                         p_event-&amp;gt;bt.data,
                         p_event-&amp;gt;bt.conn_id,
                         p_event-&amp;gt;bt.peer_id);
            break;

        case EVT_GROUP_DISPLAY:
            NRF_LOG_INFO(&amp;quot;&amp;lt; %s &amp;gt;&amp;quot;, (uint32_t)event_type_str(p_event));
            break;

        case EVT_GROUP_HAPTIC:
            NRF_LOG_INFO(&amp;quot;&amp;lt; %s &amp;gt;&amp;quot;, (uint32_t)event_type_str(p_event));
            break;

        default:
            NRF_LOG_INFO(&amp;quot;&amp;lt; UNKNOWN EVENT: 0x%02X &amp;gt;&amp;quot;, p_event-&amp;gt;type);
            break;
    }
}
#endif

/**@brief Process the event. */
static void event_process(void *p_event_data, uint16_t event_size) {
    const event_handler_t *p_handler = sp_event_handlers;
    event_t *p_event = p_event_data;

    ASSERT((p_event != NULL) &amp;amp;&amp;amp; (p_handler != NULL));

    #if CONFIG_EVENT_MONITOR_ENABLED
    if (CONFIG_EVENT_MONITOR_TYPES &amp;amp; (1ul &amp;lt;&amp;lt; EVENT_GROUP(p_event-&amp;gt;type))) {
        event_dump(p_event);
    }
    #endif

    // Pass the event to handlers.
    while (*p_handler != NULL) {
        if ((*p_handler++)(p_event)) {
            // Stop event processing if handler returned true.
            #if CONFIG_EVENT_MONITOR_ENABLED
            if (CONFIG_EVENT_MONITOR_TYPES &amp;amp; (1ul &amp;lt;&amp;lt; EVENT_GROUP(p_event-&amp;gt;type))) {
                NRF_LOG_INFO(&amp;quot;&amp;lt; ^^^^ EVENT CONSUMED ^^^^ &amp;gt;&amp;quot;);
            }
            #endif
            break;
        }
    }

    nrf_balloc_free(&amp;amp;s_event_pool, p_event);
}

/**@brief Function for sending an event. */
ret_code_t event_send(event_type_t event_type, ...) {
    ret_code_t status;
    event_t *p_event;
    va_list args;

    p_event = nrf_balloc_alloc(&amp;amp;s_event_pool);
    if (p_event == NULL) {
        NRF_LOG_WARNING(&amp;quot;%s(): WARNING: Allocation error: Event lost!&amp;quot;, (uint32_t)__func__);
        APP_ERROR_CHECK_BOOL(CONFIG_EVENT_FORCE_ERROR_CHECKING);
        return NRF_ERROR_NO_MEM;
    }

    va_start(args, event_type); /**&amp;lt; Initialize a variable argument list */
    p_event-&amp;gt;type = event_type;

    switch (EVENT_GROUP(p_event-&amp;gt;type))
    {
        case EVT_GROUP_SYSTEM:
            p_event-&amp;gt;system.data = va_arg(args, uint32_t);
            break;

        case EVT_GROUP_KEYPAD:
            p_event-&amp;gt;keypad.code = va_arg(args, uint32_t);
            p_event-&amp;gt;keypad.action_type = va_arg(args, uint32_t);
            break;

        case EVT_GROUP_HID:
            p_event-&amp;gt;hid.usage = va_arg(args, uint32_t);
            p_event-&amp;gt;hid.report = (int16_t)va_arg(args, int);
            break;

        case EVT_GROUP_BT:
            p_event-&amp;gt;system.data = 2;
            p_event-&amp;gt;bt.data = va_arg(args, uint32_t);
            p_event-&amp;gt;bt.conn_id = va_arg(args, uint32_t);
            p_event-&amp;gt;bt.peer_id = va_arg(args, uint32_t);
            break;

        case EVT_GROUP_DISPLAY:
            break;

        case EVT_GROUP_HAPTIC:
            break;

        default:
            APP_ERROR_CHECK_BOOL(false);
            break;
    }

    va_end(args); /**&amp;lt; End using variable argument list */

    //event_dump(p_event);
    status = app_sched_event_put(p_event, sizeof(p_event), event_process);
    if (status != NRF_SUCCESS) {
        nrf_balloc_free(&amp;amp;s_event_pool, p_event);

        NRF_LOG_WARNING(&amp;quot;%s(): WARNING: Scheduling error: Event lost!&amp;quot;, (uint32_t)__func__);
        APP_ERROR_CHECK_BOOL(CONFIG_EVENT_FORCE_ERROR_CHECKING);
    }

    return status;
}

/**@brief Function for initializing the event bus. */
ret_code_t event_bus_init(const event_handler_t *event_handlers_table) {
    if (event_handlers_table == NULL) {
        return NRF_ERROR_INVALID_PARAM;
    }

    sp_event_handlers = event_handlers_table;

    return nrf_balloc_init(&amp;amp;s_event_pool);
}&lt;/pre&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Smart Remote 3 - Firmware Architecture Replication SDK 16.0.0</title><link>https://devzone.nordicsemi.com/thread/238845?ContentTypeID=1</link><pubDate>Mon, 09 Mar 2020 13:47:15 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:5eca3f18-b8bb-4abf-ba62-f10532b90574</guid><dc:creator>Einar Thorsrud</dc:creator><description>&lt;p&gt;Hi,&lt;/p&gt;
[quote user=""]I find the Smart Remote 3 architecture design to be what I need to follow. &amp;nbsp;I have the source code for the Smart Remote 3&amp;nbsp;but it uses the SDK 14.2. &amp;nbsp;It&amp;#39;s day one of development and I&amp;#39;m starting the journey with the scheduler task and already ran into an issue with SDK version differences. [/quote]
&lt;p&gt;The Smart Remote 3 reference design is quite complex, so migrating to SDK 16 will be a bit of work. If you want to use the Smart Remote design I suggest you stick with SDK 14.2 unless you have a compelling reason for migrating.&lt;/p&gt;
[quote user=""]To continue on with the design of a background and foreground scheduler, what&amp;nbsp;does Nordic recommend since this &amp;quot;app_isched.h&amp;quot; source code isn&amp;#39;t compatible with SDK 16.0.0? With&amp;nbsp;SDK 16.0.0, do I even need this level of scheduling now and is the priority of handling the BLE Stack events already managed for me and I can just use app_timers to do my work? [/quote]
&lt;p&gt;I cannot say without knowing more about your application. Are you trying to migrate the SmartRemote 3, or not? If your own design, what are the requirements?&lt;/p&gt;
[quote user=""]Does the SDK scheduler have priority event options?[/quote]
&lt;p&gt;No. The SDK scheduler is a very simple scheduler without priorities. It&amp;#39;s only task is to move execution from an interrupt context to the main thread.&amp;nbsp;&lt;/p&gt;
[quote user=""]Are there any updated scheduler examples using SDK 16.0.0?[/quote]
&lt;p&gt;No. But the scheduler has not changed significantly for a long time. You can refer to the &lt;a href="https://devzone.nordicsemi.com/nordic/short-range-guides/b/software-development-kit/posts/scheduler-tutorial"&gt;scheduler tutorial&lt;/a&gt; for&amp;nbsp;an example (though not specifically for SDK 16).&lt;/p&gt;
[quote user=""]Should I consider FreeRTOS as a replacement solution?[/quote]
&lt;p&gt;Only if you need an RTOS (complex scheduler, event queues, etc). Using FreeRTOS can make complex designs simpler, but also makes simpler designs more complex. So you need to see if it is right for your design.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>