You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by st...@apache.org on 2016/07/27 23:13:50 UTC

[21/51] [partial] incubator-mynewt-core git commit: add stm32 and nordic sdks based on new structure

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f06c2d2b/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/fds/fds.h
----------------------------------------------------------------------
diff --git a/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/fds/fds.h b/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/fds/fds.h
new file mode 100644
index 0000000..dc37df3
--- /dev/null
+++ b/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/fds/fds.h
@@ -0,0 +1,733 @@
+/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved.
+ *
+ * The information contained herein is property of Nordic Semiconductor ASA.
+ * Terms and conditions of usage are described in detail in NORDIC
+ * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
+ *
+ * Licensees are granted free, non-transferable use of the information. NO
+ * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
+ * the file.
+ *
+ */
+
+#ifndef FDS_H__
+#define FDS_H__
+
+/**
+ * @defgroup flash_data_storage Flash Data Storage
+ * @ingroup app_common
+ * @{
+ *
+ * @brief   Flash Data Storage (FDS).
+ *
+ * @details Flash Data Storage is a minimalistic, record-oriented file system for the on-chip
+ *          flash. Files are stored as a collection of  records of variable length. FDS supports
+ *          synchronous read operations and asynchronous write operations (write, update,
+ *          and delete). FDS can be used from multiple threads.
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "sdk_errors.h"
+
+
+/**@brief   Invalid file ID.
+ *
+ * This value must not be used as a file ID by the application.
+ */
+#define FDS_FILE_ID_INVALID     (0xFFFF)
+
+
+/**@brief   Record key for deleted records.
+ *
+ * This key is used to flag a record as "dirty", which means that it should be removed during
+ * the next garbage collection. This value must not be used as a record key by the application.
+ */
+#define FDS_RECORD_KEY_DIRTY    (0x0000)
+
+
+/**@brief   FDS return values.
+ */
+enum
+{
+    FDS_SUCCESS = NRF_SUCCESS,  //!< The operation completed successfully.
+    FDS_ERR_OPERATION_TIMEOUT,  //!< Error. The operation timed out.
+    FDS_ERR_NOT_INITIALIZED,    //!< Error. The module has not been initialized.
+    FDS_ERR_UNALIGNED_ADDR,     //!< Error. The input data is not aligned to a word boundary.
+    FDS_ERR_INVALID_ARG,        //!< Error. The parameter contains invalid data.
+    FDS_ERR_NULL_ARG,           //!< Error. The parameter is NULL.
+    FDS_ERR_NO_OPEN_RECORDS,    //!< Error. The record is not open, so it cannot be closed.
+    FDS_ERR_NO_SPACE_IN_FLASH,  //!< Error. There is no space in flash memory.
+    FDS_ERR_NO_SPACE_IN_QUEUES, //!< Error. There is no space in the internal queues.
+    FDS_ERR_RECORD_TOO_LARGE,   //!< Error. The record exceeds the maximum allowed size.
+    FDS_ERR_NOT_FOUND,          //!< Error. The record was not found.
+    FDS_ERR_NO_PAGES,           //!< Error. No flash pages are available.
+    FDS_ERR_USER_LIMIT_REACHED, //!< Error. The maximum number of users has been reached.
+    FDS_ERR_CRC_CHECK_FAILED,   //!< Error. The CRC check failed.
+    FDS_ERR_BUSY,               //!< Error. The underlying flash subsystem was busy.
+    FDS_ERR_INTERNAL,           //!< Error. An internal error occurred.
+};
+
+
+/**@brief   Part of the record metadata.
+ *
+ * Contains the record key and the length of the record data.
+ */
+typedef struct
+{
+    uint16_t record_key;    //!< The record key (must be in the range 0x0001 - 0xBFFF).
+    uint16_t length_words;  //!< The length of the record data (in 4-byte words).
+} fds_tl_t;
+
+
+/**@brief   Part of the record metadata.
+ *
+ * Contains the ID of the file that the record belongs to and the CRC16 check value of the record.
+ */
+typedef struct
+{
+    uint16_t file_id;   //!< The ID of the file that the record belongs to.
+
+    /**@brief   CRC16 check value.
+     *
+     * The CRC is calculated over the entire record as stored in flash (including the record
+     * metadata except the CRC field itself). The CRC standard employed is CRC-16-CCITT.
+     */
+    uint16_t crc16;
+} fds_ic_t;
+
+
+/**@brief   The record metadata as stored in flash.
+ */
+typedef struct
+{
+    fds_tl_t tl;        //!< See @ref fds_tl_t.
+    fds_ic_t ic;        //!< See @ref fds_ic_t.
+    uint32_t record_id; //!< The unique record ID (32 bits).
+} fds_header_t;
+
+
+/**@brief   The record descriptor structure that is used to manipulate records.
+ *
+ * This structure is used by the FDS module. You must provide the descriptor to the module when
+ * you manipulate existing records. However, you should never modify it or use any of its fields.
+ *
+ * @note Never reuse the same descriptor for different records.
+ */
+typedef struct
+{
+    uint32_t         record_id;         //!< The unique record ID.
+    uint32_t const * p_record;          //!< The last known location of the record in flash.
+    uint16_t         gc_run_count;      //!< Number of times garbage collection has been run.
+    bool             record_is_open;    //!< Whether the record is currently open.
+} fds_record_desc_t;
+
+
+/**@brief   Structure that can be used to read the contents of a record stored in flash.
+ *
+ * This structure does not reflect the physical layout of a record in flash, but it points 
+ * to the locations where the record header (metadata) and the record data are stored.
+ */
+typedef struct
+{
+    fds_header_t const * p_header;  //!< Location of the record header in flash.
+    void         const * p_data;    //!< Location of the record data in flash.
+} fds_flash_record_t;
+
+
+/**@brief   A chunk of record data to be written to flash.
+ *
+ * @p p_data must be aligned to a word boundary. Make sure to keep it in 
+ * memory until the operation has completed, which is indicated by the respective FDS event.
+ */
+typedef struct
+{
+    void     const * p_data;        //!< Pointer to the data to store. Must be word-aligned.
+    uint16_t         length_words;  //!< Length of data pointed to by @p p_data (in 4-byte words).
+} fds_record_chunk_t;
+
+
+/**@brief   A record to be written to flash.
+ */
+typedef struct
+{
+    uint16_t file_id;                           //!< The ID of the file that the record belongs to.
+    uint16_t key;                               //!< The record key.
+    struct
+    {
+        fds_record_chunk_t const * p_chunks;    //!< The chunks that make up the record data.
+        uint16_t                   num_chunks;  //!< The number of chunks that make up the data.
+    } data;
+} fds_record_t;
+
+
+/**@brief   A token to a reserved space in flash, created by @ref fds_reserve.
+ *
+ * This token can be used to write the record in the reserved space (@ref fds_record_write_reserved)
+ * or to cancel the reservation (@ref fds_reserve_cancel).
+ */
+typedef struct
+{
+    uint16_t page;           //!< The logical ID of the page where space was reserved.
+    uint16_t length_words;   //!< The amount of space reserved (in 4-byte words).
+} fds_reserve_token_t;
+
+
+/**@brief   A token to keep information about the progress of @ref fds_record_find,
+ *          @ref fds_record_find_by_key, and @ref fds_record_find_in_file.
+ *
+ * @note    Always zero-initialize the token before using it for the first time.
+ * @note    Never reuse the same token to search for different records.
+ */
+typedef struct
+{
+    uint32_t const * p_addr;
+    uint16_t         page;
+} fds_find_token_t;
+
+
+/**@brief   FDS event IDs.
+ */
+typedef enum
+{
+    FDS_EVT_INIT,       //!< Event for @ref fds_init.
+    FDS_EVT_WRITE,      //!< Event for @ref fds_record_write and @ref fds_record_write_reserved.
+    FDS_EVT_UPDATE,     //!< Event for @ref fds_record_update.
+    FDS_EVT_DEL_RECORD, //!< Event for @ref fds_record_delete.
+    FDS_EVT_DEL_FILE,   //!< Event for @ref fds_file_delete.
+    FDS_EVT_GC          //!< Event for @ref fds_gc.
+} fds_evt_id_t;
+
+
+#if defined(__CC_ARM)
+    #pragma push
+    #pragma anon_unions
+#elif defined(__ICCARM__)
+    #pragma language=extended
+#elif defined(__GNUC__)
+    /* anonymous unions are enabled by default */
+#endif
+
+/**@brief   An FDS event.
+ */
+typedef struct
+{
+    fds_evt_id_t id;        //!< The event ID. See @ref fds_evt_id_t.
+    ret_code_t   result;    //!< The result of the operation related to this event.
+    union
+    {
+        struct
+        {
+            /* Currently not used. */
+            uint16_t pages_not_mounted;
+        } init;
+        struct
+        {
+            uint32_t record_id;
+            uint16_t file_id;
+            uint16_t record_key;
+            bool     is_record_updated;
+        } write; //!< Information for @ref FDS_EVT_WRITE and @ref FDS_EVT_UPDATE events.
+        struct
+        {
+            uint32_t record_id;
+            uint16_t file_id;
+            uint16_t record_key;
+            uint16_t records_deleted_count;
+        } del; //!< Information for @ref FDS_EVT_DEL_RECORD and @ref FDS_EVT_DEL_FILE events.
+        struct
+        {
+            /* Currently not used. */
+            uint16_t pages_skipped;
+            uint16_t space_reclaimed;
+        } gc;
+    };
+} fds_evt_t;
+
+#if defined(__CC_ARM)
+    #pragma pop
+#elif defined(__ICCARM__)
+    /* leave anonymous unions enabled */
+#elif defined(__GNUC__)
+    /* anonymous unions are enabled by default */
+#endif
+
+
+/**@brief   File system statistics. */
+typedef struct
+{
+    uint16_t open_records;      //!< The number of open records.
+    uint16_t valid_records;     //!< The number of valid records.
+    uint16_t dirty_records;     //!< The number of deleted ("dirty") records.
+    uint16_t words_reserved;    //!< The number of words reserved by @ref fds_reserve().
+
+    /**@brief The number of words written to flash, including those reserved for future writes.
+     */
+    uint16_t words_used;
+
+    /**@brief The largest number of free contiguous words in the file system.
+     *
+     * This number determines the largest record that can be stored by FDS.
+     * It takes into account all reservations for future writes.
+     */
+    uint16_t largest_contig;
+
+    /**@brief The largest number of words that can be reclaimed by garbage collection.
+     *
+     * The actual amount of space freed by garbage collection might be less than this value if
+     * records are open while garbage collection is run.
+     */
+    uint16_t freeable_words;
+} fds_stat_t;
+
+
+/**@brief   FDS event handler function prototype.
+ *
+ * @param   p_evt   The event.
+ */
+typedef void (*fds_cb_t)(fds_evt_t const * const p_evt);
+
+
+/**@brief   Function for registering an FDS event handler.
+ *
+ * The maximum amount of handlers that can be registered can be configured by changing the value
+ * of @ref FDS_MAX_USERS in fds_config.h.
+ * 
+ * @param[in]   cb  The event handler function.
+ *
+ * @retval  FDS_SUCCESS                 If the event handler was registered successfully.
+ * @retval  FDS_ERR_USER_LIMIT_REACHED  If the maximum number of registered callbacks is reached.
+ */
+ret_code_t fds_register(fds_cb_t cb);
+
+
+/**@brief   Function for initializing the module.
+ *
+ * This function initializes the module and installs the file system (unless it is installed
+ * already).
+ *
+ * This function is asynchronous. Completion is reported through an event. Make sure to call
+ * @ref fds_register before calling @ref fds_init so that you receive the completion event.
+ *
+ * @retval  FDS_SUCCESS         If the operation was queued successfully.
+ * @retval  FDS_ERR_NO_PAGES    If there is no space available in flash memory to install the
+ *                              file system.
+ */
+ret_code_t fds_init(void);
+
+
+/**@brief   Function for writing a record to flash.
+ *
+ * There are no restrictions on the file ID and the record key, except that the record key must be
+ * different from @ref FDS_RECORD_KEY_DIRTY and the file ID must be different from
+ * @ref FDS_FILE_ID_INVALID. In particular, no restrictions are made regarding the uniqueness of
+ * the file ID or the record key. All records with the same file ID are grouped into one file.
+ * If no file with the specified ID exists, it is created. There can be multiple records with the
+ * same record key in a file.
+ *
+ * Record data can consist of multiple chunks. The data must be aligned to a 4 byte boundary, and
+ * because it is not buffered internally, it must be kept in memory until the callback for the
+ * operation has been received. The length of the data must not exceed @ref FDS_VIRTUAL_PAGE_SIZE
+ * words minus 14 bytes.
+ *
+ * This function is asynchronous. Completion is reported through an event that is sent to
+ * the registered event handler function.
+ *
+ * @param[out]  p_desc      The descriptor of the record that was written. Pass NULL if you do not
+ *                          need the descriptor.
+ * @param[in]   p_record    The record to be written to flash.
+ *
+ * @retval  FDS_SUCCESS                 If the operation was queued successfully.
+ * @retval  FDS_ERR_NOT_INITIALIZED     If the module is not initialized.
+ * @retval  FDS_ERR_NULL_ARG            If @p p_record is NULL.
+ * @retval  FDS_ERR_INVALID_ARG         If the file ID or the record key is invalid.
+ * @retval  FDS_ERR_UNALIGNED_ADDR      If the record data is not aligned to a 4 byte boundary.
+ * @retval  FDS_ERR_RECORD_TOO_LARGE    If the record data exceeds the maximum length.
+ * @retval  FDS_ERR_NO_SPACE_IN_QUEUES  If the operation queue is full or there are more record
+ *                                      chunks than can be buffered.
+ * @retval  FDS_ERR_NO_SPACE_IN_FLASH   If there is not enough free space in flash to store the
+ *                                      record.
+ */
+ret_code_t fds_record_write(fds_record_desc_t       * const p_desc,
+                            fds_record_t      const * const p_record);
+
+
+/**@brief   Function for reserving space in flash.
+ *
+ * This function can be used to reserve space in flash memory. To write a record into the reserved
+ * space, use @ref fds_record_write_reserved. Alternatively, use @ref fds_reserve_cancel to cancel
+ * a reservation.
+ *
+ * Note that this function does not write any data to flash.
+ *
+ * @param[out]  p_token         A token that can be used to write a record in the reserved space or
+ *                              cancel the reservation.
+ * @param[in]   length_words    The length of the record data (in 4-byte words).
+ *
+ * @retval  FDS_SUCCESS                 If the flash space was reserved successfully.
+ * @retval  FDS_ERR_NOT_INITIALIZED     If the module is not initialized.
+ * @retval  FDS_ERR_NULL_ARG            If @p p_token is NULL instead of a valid token address.
+ * @retval  FDS_ERR_RECORD_TOO_LARGE    If the record length exceeds the maximum length.
+ * @retval  FDS_ERR_NO_SPACE_IN_FLASH   If there is not enough free space in flash to store the
+ *                                      record.
+ */
+ret_code_t fds_reserve(fds_reserve_token_t * const p_token, uint16_t length_words);
+
+
+/**@brief   Function for canceling an @ref fds_reserve operation.
+ *
+ * @param[in]   p_token     The token that identifies the reservation, produced by @ref fds_reserve.
+ *
+ * @retval  FDS_SUCCESS             If the reservation was canceled.
+ * @retval  FDS_ERR_NOT_INITIALIZED If the module is not initialized.
+ * @retval  FDS_ERR_NULL_ARG        If @p p_token is NULL instead of a valid token address.
+ * @retval  FDS_ERR_INVALID_ARG     If @p p_token contains invalid data.
+ */
+ret_code_t fds_reserve_cancel(fds_reserve_token_t * const p_token);
+
+
+/**@brief   Function for writing a record to a space in flash that was reserved using
+ *          @ref fds_reserve.
+ *
+ * There are no restrictions on the file ID and the record key, except that the record key must be
+ * different from @ref FDS_RECORD_KEY_DIRTY and the file ID must be different from
+ * @ref FDS_FILE_ID_INVALID. In particular, no restrictions are made regarding the uniqueness of
+ * the file ID or the record key. All records with the same file ID are grouped into one file.
+ * If no file with the specified ID exists, it is created. There can be multiple records with the
+ * same record key in a file.
+ *
+ * Record data can consist of multiple chunks. The data must be aligned to a 4 byte boundary, and
+ * because it is not buffered internally, it must be kept in memory until the callback for the
+ * operation has been received. The length of the data must not exceed @ref FDS_VIRTUAL_PAGE_SIZE
+ * words minus 14 bytes.
+ *
+ * This function is asynchronous. Completion is reported through an event that is sent to the
+ * registered event handler function.
+ *
+ * @note
+ * This function behaves similarly to @ref fds_record_write, with the exception that it never
+ * fails with the error @ref FDS_ERR_NO_SPACE_IN_FLASH.
+ *
+ * @param[out]  p_desc      The descriptor of the record that was written. Pass NULL if you do not
+ *                          need the descriptor.
+ * @param[in]   p_record    The record to be written to flash.
+ * @param[in]   p_token     The token that identifies the space reserved in flash.
+ *
+ * @retval  FDS_SUCCESS                 If the operation was queued successfully.
+ * @retval  FDS_ERR_NOT_INITIALIZED     If the module is not initialized.
+ * @retval  FDS_ERR_NULL_ARG            If @p p_token is NULL instead of a valid token address.
+ * @retval  FDS_ERR_INVALID_ARG         If the file ID or the record key is invalid.
+ * @retval  FDS_ERR_UNALIGNED_ADDR      If the record data is not aligned to a 4 byte boundary.
+ * @retval  FDS_ERR_RECORD_TOO_LARGE    If the record data exceeds the maximum length.
+ * @retval  FDS_ERR_NO_SPACE_IN_QUEUES  If the operation queue is full or there are more record
+ *                                      chunks than can be buffered.
+ */
+ret_code_t fds_record_write_reserved(fds_record_desc_t         * const p_desc,
+                                     fds_record_t        const * const p_record,
+                                     fds_reserve_token_t const * const p_token);
+
+
+/**@brief   Function for deleting a record.
+ *
+ * Deleted records cannot be located using @ref fds_record_find, @ref fds_record_find_by_key, or
+ * @ref fds_record_find_in_file. Additionally, they can no longer be opened using
+ * @ref fds_record_open.
+ *
+ * Note that deleting a record does not free the space it occupies in flash memory.
+ * To reclaim flash space used by deleted records, call @ref fds_gc to run garbage collection.
+ *
+ * This function is asynchronous. Completion is reported through an event that is sent to the
+ * registered event handler function.
+ *
+ * @param[in]   p_desc      The descriptor of the record that should be deleted.
+ *
+ * @retval  FDS_SUCCESS                 If the operation was queued successfully.
+ * @retval  FDS_ERR_NOT_INITIALIZED     If the module is not initialized.
+ * @retval  FDS_ERR_NULL_ARG            If the specified record descriptor @p p_desc is NULL.
+ * @retval  FDS_ERR_NO_SPACE_IN_QUEUES  If the operation queue is full.
+ */
+ret_code_t fds_record_delete(fds_record_desc_t * const p_desc);
+
+
+/**@brief   Function for deleting all records in a file.
+ *
+ * This function deletes a file, including all its records. Deleted records cannot be located
+ * using @ref fds_record_find, @ref fds_record_find_by_key, or @ref fds_record_find_in_file.
+ * Additionally, they can no longer be opened using @ref fds_record_open.
+ *
+ * Note that deleting records does not free the space they occupy in flash memory.
+ * To reclaim flash space used by deleted records, call @ref fds_gc to run garbage collection.
+ *
+ * This function is asynchronous. Completion is reported through an event that is sent to the
+ * registered event handler function.
+ *
+ * @param[in]   file_id     The ID of the file to be deleted.
+ *
+ * @retval  FDS_SUCCESS                 If the operation was queued successfully.
+ * @retval  FDS_ERR_NOT_INITIALIZED     If the module is not initialized.
+ * @retval  FDS_ERR_INVALID_ARG         If the specified @p file_id is invalid.
+ * @retval  FDS_ERR_NO_SPACE_IN_QUEUES  If the operation queue is full.
+ */
+ret_code_t fds_file_delete(uint16_t file_id);
+
+
+/**@brief   Function for updating a record.
+ *
+ * Updating a record first writes a new record (@p p_record) to flash and then deletes the
+ * old record (identified by @p p_desc).
+ *
+ * There are no restrictions on the file ID and the record key, except that the record key must be
+ * different from @ref FDS_RECORD_KEY_DIRTY and the file ID must be different from
+ * @ref FDS_FILE_ID_INVALID. In particular, no restrictions are made regarding the uniqueness of
+ * the file ID or the record key. All records with the same file ID are grouped into one file.
+ * If no file with the specified ID exists, it is created. There can be multiple records with the
+ * same record key in a file.
+ *
+ * Record data can consist of multiple chunks. The data must be aligned to a 4 byte boundary, and
+ * because it is not buffered internally, it must be kept in memory until the callback for the
+ * operation has been received. The length of the data must not exceed @ref FDS_VIRTUAL_PAGE_SIZE
+ * words minus 14 bytes.
+ *
+ * This function is asynchronous. Completion is reported through an event that is sent to the
+ * registered event handler function.
+ * 
+ * @param[in, out]  p_desc      The descriptor of the record to update. When the function 
+ *                              returns with FDS_SUCCESS, this parameter contains the
+ *                              descriptor of the newly written record.
+ * @param[in]       p_record    The updated record to be written to flash.
+ *
+ * @retval  FDS_SUCCESS                 If the operation was queued successfully.
+ * @retval  FDS_ERR_NOT_INITIALIZED     If the module is not initialized.
+ * @retval  FDS_ERR_INVALID_ARG         If the file ID or the record key is invalid.
+ * @retval  FDS_ERR_UNALIGNED_ADDR      If the record data is not aligned to a 4 byte boundary.
+ * @retval  FDS_ERR_RECORD_TOO_LARGE    If the record data exceeds the maximum length.
+ * @retval  FDS_ERR_NO_SPACE_IN_QUEUES  If the operation queue is full or there are more record
+ *                                      chunks than can be buffered.
+ * @retval  FDS_ERR_NO_SPACE_IN_FLASH   If there is not enough free space in flash to store the
+ *                                      updated record.
+ */
+ret_code_t fds_record_update(fds_record_desc_t       * const p_desc,
+                             fds_record_t      const * const p_record);
+
+
+/**@brief   Function for iterating through all records in flash.
+ *
+ * To search for the next record, call the function again and supply the same @ref fds_find_token_t
+ * structure to resume searching from the last record that was found.
+ *
+ * Note that the order with which records are iterated is not defined.
+ *
+ * @param[out]  p_desc      The descriptor of the record that was found.
+ * @param[out]  p_token     A token containing information about the progress of the operation.
+ *
+ * @retval  FDS_SUCCESS                 If a record was found.
+ * @retval  FDS_ERR_NOT_INITIALIZED     If the module is not initialized.
+ * @retval  FDS_ERR_NULL_ARG            If @p p_desc or @p p_token is NULL.
+ * @retval  FDS_ERR_NOT_FOUND           If no matching record was found.
+ */
+ret_code_t fds_record_iterate(fds_record_desc_t * const p_desc,
+                              fds_find_token_t  * const p_token);
+
+
+/**@brief   Function for searching for records with a given record key in a file.
+ *
+ * This function finds the first record in a file that has the given record key. To search for the
+ * next record with the same key in the file, call the function again and supply the same
+ * @ref fds_find_token_t structure to resume searching from the last record that was found.
+ *
+ * @param[in]   file_id     The file ID.
+ * @param[in]   record_key  The record key.
+ * @param[out]  p_desc      The descriptor of the record that was found.
+ * @param[out]  p_token     A token containing information about the progress of the operation.
+ *
+ * @retval  FDS_SUCCESS                 If a record was found.
+ * @retval  FDS_ERR_NOT_INITIALIZED     If the module is not initialized.
+ * @retval  FDS_ERR_NULL_ARG            If @p p_desc or @p p_token is NULL.
+ * @retval  FDS_ERR_NOT_FOUND           If no matching record was found.
+ */
+ret_code_t fds_record_find(uint16_t                  file_id,
+                           uint16_t                  record_key,
+                           fds_record_desc_t * const p_desc,
+                           fds_find_token_t  * const p_token);
+
+
+/**@brief   Function for searching for records with a given record key.
+ *
+ * This function finds the first record with a given record key, independent of the file it
+ * belongs to. To search for the next record with the same key, call the function again and supply
+ * the same @ref fds_find_token_t structure to resume searching from the last record that was found.
+ *
+ * @param[in]   record_key  The record key.
+ * @param[out]  p_desc      The descriptor of the record that was found.
+ * @param[out]  p_token     A token containing information about the progress of the operation.
+ *
+ * @retval  FDS_SUCCESS                 If a record was found.
+ * @retval  FDS_ERR_NOT_INITIALIZED     If the module is not initialized.
+ * @retval  FDS_ERR_NULL_ARG            If @p p_desc or @p p_token is NULL.
+ * @retval  FDS_ERR_NOT_FOUND           If no record with the given key was found.
+ */
+ret_code_t fds_record_find_by_key(uint16_t                  record_key,
+                                  fds_record_desc_t * const p_desc,
+                                  fds_find_token_t  * const p_token);
+
+
+/**@brief   Function for searching for any record in a file.
+ *
+ * This function finds the first record in a file, independent of its record key.
+ * To search for the next record in the same file, call the function again and supply the same
+ * @ref fds_find_token_t structure to resume searching from the last record that was found.
+ *
+ * @param[in]   file_id     The file ID.
+ * @param[out]  p_desc      The descriptor of the record that was found.
+ * @param[out]  p_token     A token containing information about the progress of the operation.
+ *
+ * @retval  FDS_SUCCESS                 If a record was found.
+ * @retval  FDS_ERR_NOT_INITIALIZED     If the module is not initialized.
+ * @retval  FDS_ERR_NULL_ARG            If @p p_desc or @p p_token is NULL.
+ * @retval  FDS_ERR_NOT_FOUND           If no matching record was found.
+ */
+ret_code_t fds_record_find_in_file(uint16_t                  file_id,
+                                   fds_record_desc_t * const p_desc,
+                                   fds_find_token_t  * const p_token);
+
+
+/**@brief   Function for opening a record for reading.
+ *
+ * This function opens a record that is stored in flash, so that it can be read. The function
+ * initializes an @ref fds_flash_record_t structure, which can be used to access the record data as
+ * well as its associated metadata. The pointers provided in the @ref fds_flash_record_t structure
+ * are pointers to flash memory.
+ *
+ * Opening a record with @ref fds_record_open prevents garbage collection to run on the virtual
+ * flash page in which record is stored, so that the contents of the memory pointed by fields in
+ * @ref fds_flash_record_t are guaranteed to remain unmodified as long as the record is kept open.
+ *
+ * When you are done reading a record, call @ref fds_record_close to close it. Garbage collection
+ * can then reclaim space on the virtual page where the record is stored. Note that you must
+ * provide the same descriptor for @ref fds_record_close as you did for this function.
+ *
+ * @param[in]   p_desc          The descriptor of the record to open.
+ * @param[out]  p_flash_record  The record, as stored in flash.
+ *
+ * @retval  FDS_SUCCESS                 If the record was opened successfully.
+ * @retval  FDS_ERR_NULL_ARG            If @p p_desc or @p p_flash_record is NULL.
+ * @retval  FDS_ERR_NOT_FOUND           If the record was not found. It might have been deleted, or
+ *                                      it might not have been written yet.
+ * @retval  FDS_ERR_CRC_CHECK_FAILED    If the CRC check for the record failed.
+ */
+ret_code_t fds_record_open(fds_record_desc_t  * const p_desc,
+                           fds_flash_record_t * const p_flash_record);
+
+
+/**@brief   Function for closing a record.
+ *
+ * Closing a record allows garbage collection to run on the virtual page in which the record is
+ * stored (if no other records remain open on that page). The descriptor passed as an argument
+ * must be the same as the one used to open the record using @ref fds_record_open.
+ *
+ * Note that closing a record does not invalidate its descriptor. You can still supply the
+ * descriptor to all functions that accept a record descriptor as a parameter.
+ *
+ * @param[in]   p_desc  The descriptor of the record to close.
+ *
+ * @retval  FDS_SUCCESS             If the record was closed successfully.
+ * @retval  FDS_ERR_NULL_ARG        If @p p_desc is NULL.
+ * @retval  FDS_ERR_NO_OPEN_RECORDS If the record is not open.
+ * @retval  FDS_ERR_NOT_FOUND       If the record could not be found.
+ */
+ret_code_t fds_record_close(fds_record_desc_t * const p_desc);
+
+
+/**@brief   Function for running garbage collection.
+ *
+ * Garbage collection reclaims the flash space that is occupied by records that have been deleted,
+ * or that failed to be completely written due to, for example, a power loss.
+ *
+ * This function is asynchronous. Completion is reported through an event that is sent to the
+ * registered event handler function.
+ *
+ * @retval  FDS_SUCCESS                 If the operation was queued successfully.
+ * @retval  FDS_ERR_NOT_INITIALIZED     If the module is not initialized.
+ * @retval  FDS_ERR_NO_SPACE_IN_QUEUES  If the operation queue is full.
+ */
+ret_code_t fds_gc(void);
+
+
+/**@brief   Function for obtaining a descriptor from a record ID.
+ *
+ * This function can be used to reconstruct a descriptor from a record ID, like the one that is
+ * passed to the callback function.
+ *
+ * @note
+ * This function does not check whether a record with the given record ID exists.
+ * If a non-existing record ID is supplied, the resulting descriptor is invalid and will cause
+ * other functions to fail when it is supplied as parameter.
+ *
+ * @param[out]  p_desc      The descriptor of the record with the given record ID.
+ * @param[in]   record_id   The record ID for which a descriptor should be returned.
+ *
+ * @retval  FDS_SUCCESS         If a descriptor was returned.
+ * @retval  FDS_ERR_NULL_ARG    If @p p_desc is NULL.
+ */
+ret_code_t fds_descriptor_from_rec_id(fds_record_desc_t * const p_desc,
+                                      uint32_t                  record_id);
+
+
+/**@brief   Function for obtaining a record ID from a record descriptor.
+ *
+ * This function can be used to extract a record ID from a descriptor. For example, you could use
+ * it in the callback function to compare the record ID of an event to the record IDs of the
+ * records for which you have a descriptor.
+ *
+ * @warning
+ * This function does not check whether the record descriptor is valid. If the descriptor is not
+ * initialized or has been tampered with, the resulting record ID might be invalid.
+ *
+ * @param[in]   p_desc          The descriptor from which the record ID should be extracted.
+ * @param[out]  p_record_id     The record ID that is contained in the given descriptor.
+ *
+ * @retval  FDS_SUCCESS         If a record ID was returned.
+ * @retval  FDS_ERR_NULL_ARG    If @p p_desc or @p p_record_id is NULL.
+ */
+ret_code_t fds_record_id_from_desc(fds_record_desc_t const * const p_desc,
+                                   uint32_t                * const p_record_id);
+
+
+/**@brief   Function for retrieving file system statistics.
+ *
+ * This function retrieves file system statistics, such as the number of open records, the space
+ * that can be reclaimed by garbage collection, and others.
+ *
+ * @param[out]  p_stat      File system statistics.
+ *
+ * @retval  FDS_SUCCESS                 If the statistics were returned successfully.
+ * @retval  FDS_ERR_NOT_INITIALIZED     If the module is not initialized.
+ * @retval  FDS_ERR_NULL_ARG            If @p p_stat is NULL.
+ */
+ret_code_t fds_stat(fds_stat_t * const p_stat);
+
+
+#if defined(FDS_CRC_ENABLED)
+
+/**@brief   Function for enabling and disabling CRC verification for write operations.
+ *
+ * CRC verification ensures that data that is queued for writing does not change before the write
+ * actually happens. Use this function to enable or disable CRC verification. If verification is
+ * enabled, the error @ref FDS_ERR_CRC_CHECK_FAILED is returned in the event for
+ * @ref fds_record_write, @ref fds_record_write_reserved, or @ref fds_record_update if
+ * verification fails.
+ *
+ * @note
+ * CRC verification is enabled or disabled globally, thus for all users of the FDS module.
+ *
+ * @param[in]   enabled     1 to enable CRC verification. 0 to disable CRC verification.
+ *
+ * @retval  FDS_SUCCESS     If CRC verification was enabled or disabled successfully.
+ */
+ret_code_t fds_verify_crc_on_writes(bool enabled);
+
+#endif
+
+/** @} */
+
+#endif // FDS_H__

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f06c2d2b/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/fds/fds_internal_defs.h
----------------------------------------------------------------------
diff --git a/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/fds/fds_internal_defs.h b/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/fds/fds_internal_defs.h
new file mode 100644
index 0000000..4c2d165
--- /dev/null
+++ b/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/fds/fds_internal_defs.h
@@ -0,0 +1,305 @@
+/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved.
+ *
+ * The information contained herein is property of Nordic Semiconductor ASA.
+ * Terms and conditions of usage are described in detail in NORDIC
+ * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
+ *
+ * Licensees are granted free, non-transferable use of the information. NO
+ * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
+ * the file.
+ *
+ */
+
+#ifndef FDS_INTERNAL_DEFS_H__
+#define FDS_INTERNAL_DEFS_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "fds_config.h"
+
+#if defined (FDS_THREADS)
+    #include "nrf_soc.h"
+    #include "app_util_platform.h"
+#endif
+
+#define FDS_PAGE_TAG_SIZE       (2) // Page tag size, in 4-byte words.
+#define FDS_PAGE_TAG_WORD_0     (0) // Offset of the first word in the page tag from the page address.
+#define FDS_PAGE_TAG_WORD_1     (1) // Offset of the second word in the page tag from the page address.
+
+// Page tag constants
+#define FDS_PAGE_TAG_MAGIC      (0xDEADC0DE)
+#define FDS_PAGE_TAG_SWAP       (0xF11E01FF)
+#define FDS_PAGE_TAG_DATA       (0xF11E01FE)
+
+#define FDS_ERASED_WORD         (0xFFFFFFFF)
+
+#define FDS_OFFSET_TL           (0) // Offset of TL from the record base address, in 4-byte words.
+#define FDS_OFFSET_IC           (1) // Offset of IC from the record base address, in 4-byte words.
+#define FDS_OFFSET_ID           (2) // Offset of ID from the record base address, in 4-byte words.
+#define FDS_OFFSET_DATA         (3) // Offset of the data (chunks) from the record base address, in 4-byte words.
+
+#define FDS_HEADER_SIZE_TL      (1) // Size of the TL part of the header, in 4-byte words.
+#define FDS_HEADER_SIZE_IC      (1) // Size of the IC part of the header, in 4-byte words.
+#define FDS_HEADER_SIZE_ID      (1) // Size of the record ID in the header, in 4-byte words.
+#define FDS_HEADER_SIZE         (3) // Size of the whole header, in 4-byte words.
+
+#define FDS_OP_EXECUTING        (FS_SUCCESS)
+#define FDS_OP_COMPLETED        (0x1D1D)
+
+// The size of a physical page, in 4-byte words.
+#if   defined(NRF51)
+    #define FDS_PHY_PAGE_SIZE   (256)
+#elif defined(NRF52)
+    #define FDS_PHY_PAGE_SIZE   (1024)
+#endif
+
+// The number of physical pages to be used. This value is configured indirectly.
+#define FDS_PHY_PAGES               ((FDS_VIRTUAL_PAGES * FDS_VIRTUAL_PAGE_SIZE) / FDS_PHY_PAGE_SIZE)
+
+// The size of a virtual page, in number of physical pages.
+#define FDS_PHY_PAGES_IN_VPAGE      (FDS_VIRTUAL_PAGE_SIZE / FDS_PHY_PAGE_SIZE)
+
+// The number of pages available to store data; which is the total minus one (the swap).
+#define FDS_MAX_PAGES               (FDS_VIRTUAL_PAGES - 1)
+
+ // Just a shorter name for the size, in words, of a virtual page.
+#define FDS_PAGE_SIZE               (FDS_VIRTUAL_PAGE_SIZE)
+
+
+#if (FDS_VIRTUAL_PAGE_SIZE % FDS_PHY_PAGE_SIZE != 0)
+    #error "FDS_VIRTUAL_PAGE_SIZE must be a multiple of the size of a physical page."
+#endif
+
+#if (FDS_VIRTUAL_PAGES < 2)
+    #error "FDS requires at least two virtual pages."
+#endif
+
+
+// FDS internal status flags.
+typedef enum
+{
+    FDS_FLAG_INITIALIZING   = (1 << 0),  // The module is initializing.
+    FDS_FLAG_INITIALIZED    = (1 << 1),  // The module is initialized.
+    FDS_FLAG_PROCESSING     = (1 << 2),  // The queue is being processed.
+    FDS_FLAG_VERIFY_CRC     = (1 << 3),  // Verify CRC upon writing a record.
+} fds_flags_t;
+
+
+// Page types.
+typedef enum
+{
+    FDS_PAGE_DATA,      // Page is ready for storage.
+    FDS_PAGE_SWAP,      // Page is reserved for garbage collection.
+    FDS_PAGE_ERASED,    // Page is erased.
+    FDS_PAGE_UNDEFINED, // Undefined page type.
+} fds_page_type_t;
+
+
+typedef struct
+{
+    fds_page_type_t         page_type;      // The page type.
+    uint32_t        const * p_addr;         // The address of the page.
+    uint16_t                write_offset;   // The page write offset, in 4-byte words.
+    uint16_t                words_reserved; // The amount of words reserved by fds_write_reserve().
+    uint16_t                records_open;   // The number of records opened using fds_open().
+    bool                    can_gc;         // Indicates that there are some records that have been deleted.
+} fds_page_t;
+
+
+typedef struct
+{
+    uint32_t const * p_addr;
+    uint16_t         write_offset;
+} fds_swap_page_t;
+
+
+// FDS op-codes.
+typedef enum
+{
+    FDS_OP_NONE,
+    FDS_OP_INIT,        // Initialize the module.
+    FDS_OP_WRITE,       // Write a record to flash.
+    FDS_OP_UPDATE,      // Update a record.
+    FDS_OP_DEL_RECORD,  // Delete a record.
+    FDS_OP_DEL_FILE,    // Delete a file.
+    FDS_OP_GC           // Run garbage collection.
+} fds_op_code_t;
+
+
+typedef enum
+{
+    FDS_OP_INIT_TAG_SWAP,
+    FDS_OP_INIT_TAG_DATA,
+    FDS_OP_INIT_ERASE_SWAP,
+    FDS_OP_INIT_PROMOTE_SWAP,
+} fds_init_step_t;
+
+
+typedef enum
+{
+    FDS_OP_WRITE_HEADER_BEGIN,      // Write the record key and length.
+    FDS_OP_WRITE_HEADER_FINALIZE,   // Write the file ID and CRC.
+    FDS_OP_WRITE_RECORD_ID,         // Write the record ID.
+    FDS_OP_WRITE_CHUNKS,            // Write the record data.
+    FDS_OP_WRITE_FIND_RECORD,
+    FDS_OP_WRITE_FLAG_DIRTY,        // Flag a record as dirty (as part of an update operation).
+    FDS_OP_WRITE_DONE,
+} fds_write_step_t;
+
+
+typedef enum
+{
+    FDS_OP_DEL_RECORD_FLAG_DIRTY,   // Flag a record as dirty.
+    FDS_OP_DEL_FILE_FLAG_DIRTY,     // Flag multiple records as dirty.
+    FDS_OP_DEL_DONE,
+} fds_delete_step_t;
+
+
+#if defined(__CC_ARM)
+    #pragma push
+    #pragma anon_unions
+#elif defined(__ICCARM__)
+    #pragma language=extended
+#elif defined(__GNUC__)
+    // anonymous unions are enabled by default
+#endif
+
+typedef struct
+{
+    fds_op_code_t op_code;                      // The opcode for the operation.
+    union
+    {
+        struct
+        {
+            fds_init_step_t step;               // The current step the operation is at.
+        } init;
+        struct
+        {
+            fds_header_t     header;
+            fds_write_step_t step;              // The current step the operation is at.
+            uint16_t         page;              // The page the flash space for this command was reserved.
+            uint16_t         chunk_offset;      // Offset used for writing record chunks, in 4-byte words.
+            uint8_t          chunk_count;       // Number of chunks to be written.
+            uint32_t         record_to_delete;  // The record to delete in case this is an update.
+        } write;
+        struct
+        {
+            fds_delete_step_t step;
+            uint16_t          file_id;
+            uint16_t          record_key;
+            uint32_t          record_to_delete;
+        } del;
+    };
+} fds_op_t;
+
+#if defined(__CC_ARM)
+    #pragma pop
+#elif defined(__ICCARM__)
+    // leave anonymous unions enabled
+#elif defined(__GNUC__)
+    // anonymous unions are enabled by default
+#endif
+
+
+typedef struct
+{
+    fds_op_t op[FDS_OP_QUEUE_SIZE];    // Queued flash operations.
+    uint32_t rp;                       // The index of the command being executed.
+    uint32_t count;                    // Number of elements in the queue.
+} fds_op_queue_t;
+
+
+typedef struct
+{
+    fds_record_chunk_t chunk[FDS_CHUNK_QUEUE_SIZE];
+    uint32_t           rp;
+    uint32_t           count;
+} fds_chunk_queue_t;
+
+
+enum
+{
+    PAGE_ERASED = 0x1,
+    PAGE_DATA   = 0x2,
+    SWAP_EMPTY  = 0x4,
+    SWAP_DIRTY  = 0x8,
+};
+
+
+typedef enum
+{
+    // This is a fatal error.
+    NO_PAGES,
+
+    // All pages are erased. Perform a fresh installation.
+    FRESH_INSTALL     = (PAGE_ERASED),
+
+    // Swap is missing. Tag an erased page as swap.
+    TAG_SWAP          = (PAGE_ERASED | PAGE_DATA),
+
+    // Swap is empty. Tag all erased pages as data.
+    TAG_DATA         = (PAGE_ERASED | SWAP_EMPTY),
+
+    // Swap is empty. Tag all remaining erased pages as data.
+    TAG_DATA_INST    = (PAGE_ERASED | PAGE_DATA | SWAP_EMPTY),
+
+    // The swap is dirty. This indicates that the device powered off during GC. However, since there
+    // is also an erased page, it is possible to assume that that page had been entirely garbage
+    // collected. Hence, tag the swap as data, one erased page as swap and any remaining pages as data.
+    PROMOTE_SWAP      = (PAGE_ERASED | SWAP_DIRTY),
+
+    // Similar to the above. Tag the swap as data, one erased page as swap, and any remain
+    // pages as data.
+    PROMOTE_SWAP_INST = (PAGE_ERASED | PAGE_DATA | SWAP_DIRTY),
+
+    // The swap is dirty (written) and there are no erased pages. This indicates that the device
+    // was powered off during GC. It is safe to discard (erase) the swap, since data that was
+    // swapped out lies in one of the valid pages.
+    DISCARD_SWAP      = (PAGE_DATA  | SWAP_DIRTY),
+
+    // Do nothing.
+    ALREADY_INSTALLED = (PAGE_DATA  | SWAP_EMPTY),
+
+} fds_init_opts_t;
+
+
+typedef enum
+{
+    GC_BEGIN,               // Begin GC.
+    GC_NEXT_PAGE,           // GC a page.
+    GC_FIND_NEXT_RECORD,    // Find a valid record to copy.
+    GC_COPY_RECORD,         // Copy a valid record to swap.
+    GC_ERASE_PAGE,          // Erase the page being garbage collected.
+    GC_DISCARD_SWAP,        // Erase (discard) the swap page.
+    GC_PROMOTE_SWAP,        // Tag the swap as valid.
+    GC_TAG_NEW_SWAP         // Tag a freshly erased (GCed) page as swap.
+} fds_gc_state_t;
+
+
+// Holds garbage collection status and related data.
+typedef struct
+{
+    fds_gc_state_t   state;                     // The current GC step.
+    uint16_t         cur_page;                  // The current page being garbage collected.
+    uint32_t const * p_record_src;              // The current record being copied to swap.
+    uint16_t         run_count;                 // Total number of times GC was run.
+    bool             do_gc_page[FDS_MAX_PAGES]; // Controls which pages to garbage collect.
+    bool             resume;                    // Whether or not GC should be resumed.
+} fds_gc_data_t;
+
+
+// Macros to enable and disable application interrupts.
+#if defined (FDS_THREADS)
+
+    #define CRITICAL_SECTION_ENTER()    CRITICAL_REGION_ENTER()
+    #define CRITICAL_SECTION_EXIT()     CRITICAL_REGION_EXIT()
+
+#else
+
+    #define CRITICAL_SECTION_ENTER()
+    #define CRITICAL_SECTION_EXIT()
+
+#endif
+
+
+#endif // FDS_INTERNAL_DEFS_H__

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f06c2d2b/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/fifo/app_fifo.c
----------------------------------------------------------------------
diff --git a/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/fifo/app_fifo.c b/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/fifo/app_fifo.c
new file mode 100644
index 0000000..e0cfe9e
--- /dev/null
+++ b/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/fifo/app_fifo.c
@@ -0,0 +1,186 @@
+/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved.
+ *
+ * The information contained herein is property of Nordic Semiconductor ASA.
+ * Terms and conditions of usage are described in detail in NORDIC
+ * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
+ *
+ * Licensees are granted free, non-transferable use of the information. NO
+ * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
+ * the file.
+ *
+ */
+
+#include "app_fifo.h"
+#include "sdk_common.h"
+#include "nordic_common.h"
+
+static __INLINE uint32_t fifo_length(app_fifo_t * p_fifo)
+{
+    uint32_t tmp = p_fifo->read_pos;
+    return p_fifo->write_pos - tmp;
+}
+
+
+#define FIFO_LENGTH fifo_length(p_fifo)  /**< Macro for calculating the FIFO length. */
+
+
+/**@brief Put one byte to the FIFO. */
+static __INLINE void fifo_put(app_fifo_t * p_fifo, uint8_t byte)
+{
+    p_fifo->p_buf[p_fifo->write_pos & p_fifo->buf_size_mask] = byte;
+    p_fifo->write_pos++;
+}
+
+
+/**@brief Look at one byte in the FIFO. */
+static __INLINE void fifo_peek(app_fifo_t * p_fifo, uint16_t index, uint8_t * p_byte)
+{
+    *p_byte = p_fifo->p_buf[(p_fifo->read_pos + index) & p_fifo->buf_size_mask];
+}
+
+
+/**@brief Get one byte from the FIFO. */
+static __INLINE void fifo_get(app_fifo_t * p_fifo, uint8_t * p_byte)
+{
+    fifo_peek(p_fifo, 0, p_byte);
+    p_fifo->read_pos++;
+}
+
+
+uint32_t app_fifo_init(app_fifo_t * p_fifo, uint8_t * p_buf, uint16_t buf_size)
+{
+    // Check buffer for null pointer.
+    if (p_buf == NULL)
+    {
+        return NRF_ERROR_NULL;
+    }
+
+    // Check that the buffer size is a power of two.
+    if (!IS_POWER_OF_TWO(buf_size))
+    {
+        return NRF_ERROR_INVALID_LENGTH;
+    }
+
+    p_fifo->p_buf         = p_buf;
+    p_fifo->buf_size_mask = buf_size - 1;
+    p_fifo->read_pos      = 0;
+    p_fifo->write_pos     = 0;
+
+    return NRF_SUCCESS;
+}
+
+
+uint32_t app_fifo_put(app_fifo_t * p_fifo, uint8_t byte)
+{
+    if (FIFO_LENGTH <= p_fifo->buf_size_mask)
+    {
+        fifo_put(p_fifo, byte);
+        return NRF_SUCCESS;
+    }
+
+    return NRF_ERROR_NO_MEM;
+}
+
+
+uint32_t app_fifo_get(app_fifo_t * p_fifo, uint8_t * p_byte)
+{
+    if (FIFO_LENGTH != 0)
+    {
+        fifo_get(p_fifo, p_byte);
+        return NRF_SUCCESS;
+    }
+
+    return NRF_ERROR_NOT_FOUND;
+
+}
+
+
+uint32_t app_fifo_peek(app_fifo_t * p_fifo, uint16_t index, uint8_t * p_byte)
+{
+    if (FIFO_LENGTH > index)
+    {
+        fifo_peek(p_fifo, index, p_byte);
+        return NRF_SUCCESS;
+    }
+
+    return NRF_ERROR_NOT_FOUND;
+}
+
+
+uint32_t app_fifo_flush(app_fifo_t * p_fifo)
+{
+    p_fifo->read_pos = p_fifo->write_pos;
+    return NRF_SUCCESS;
+}
+
+
+uint32_t app_fifo_read(app_fifo_t * p_fifo, uint8_t * p_byte_array, uint32_t * p_size)
+{
+    VERIFY_PARAM_NOT_NULL(p_fifo);
+    VERIFY_PARAM_NOT_NULL(p_size);
+
+    const uint32_t byte_count    = fifo_length(p_fifo);
+    const uint32_t requested_len = (*p_size);
+    uint32_t       index         = 0;
+    uint32_t       read_size     = MIN(requested_len, byte_count);
+
+    (*p_size) = byte_count;
+
+    // Check if the FIFO is empty.
+    if (byte_count == 0)
+    {
+        return NRF_ERROR_NOT_FOUND;
+    }
+
+    // Check if application has requested only the size.
+    if (p_byte_array == NULL)
+    {
+        return NRF_SUCCESS;
+    }
+
+    // Fetch bytes from the FIFO.
+    while (index < read_size)
+    {
+        fifo_get(p_fifo, &p_byte_array[index++]);
+    }
+
+    (*p_size) = read_size;
+
+    return NRF_SUCCESS;
+}
+
+
+uint32_t app_fifo_write(app_fifo_t * p_fifo, uint8_t const * p_byte_array, uint32_t * p_size)
+{
+    VERIFY_PARAM_NOT_NULL(p_fifo);
+    VERIFY_PARAM_NOT_NULL(p_size);
+
+    const uint32_t available_count = p_fifo->buf_size_mask - fifo_length(p_fifo) + 1;
+    const uint32_t requested_len   = (*p_size);
+    uint32_t       index           = 0;
+    uint32_t       write_size      = MIN(requested_len, available_count);
+
+    (*p_size) = available_count;
+
+    // Check if the FIFO is FULL.
+    if (available_count == 0)
+    {
+        return NRF_ERROR_NO_MEM;
+    }
+
+    // Check if application has requested only the size.
+    if (p_byte_array == NULL)
+    {
+        return NRF_SUCCESS;
+    }
+
+    //Fetch bytes from the FIFO.
+    while (index < write_size)
+    {
+        fifo_put(p_fifo, p_byte_array[index++]);
+    }
+
+    (*p_size) = write_size;
+
+    return NRF_SUCCESS;
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f06c2d2b/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/fifo/app_fifo.h
----------------------------------------------------------------------
diff --git a/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/fifo/app_fifo.h b/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/fifo/app_fifo.h
new file mode 100644
index 0000000..300adca
--- /dev/null
+++ b/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/fifo/app_fifo.h
@@ -0,0 +1,145 @@
+/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved.
+ *
+ * The information contained herein is property of Nordic Semiconductor ASA.
+ * Terms and conditions of usage are described in detail in NORDIC
+ * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
+ *
+ * Licensees are granted free, non-transferable use of the information. NO
+ * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
+ * the file.
+ *
+ */
+
+/**@file
+ *
+ * @defgroup app_fifo FIFO implementation
+ * @{
+ * @ingroup app_common
+ *
+ * @brief FIFO implementation.
+ */
+
+#ifndef APP_FIFO_H__
+#define APP_FIFO_H__
+
+#include <stdint.h>
+#include <stdlib.h>
+
+/**@brief   A FIFO instance structure.
+ * @details Keeps track of which bytes to read and write next.
+ *          Also, it keeps the information about which memory is allocated for the buffer
+ *          and its size. This structure must be initialized by app_fifo_init() before use.
+ */
+typedef struct
+{
+    uint8_t *          p_buf;           /**< Pointer to FIFO buffer memory.                      */
+    uint16_t           buf_size_mask;   /**< Read/write index mask. Also used for size checking. */
+    volatile uint32_t  read_pos;        /**< Next read position in the FIFO buffer.              */
+    volatile uint32_t  write_pos;       /**< Next write position in the FIFO buffer.             */
+} app_fifo_t;
+
+/**@brief Function for initializing the FIFO.
+ *
+ * @param[out] p_fifo   FIFO object.
+ * @param[in]  p_buf    FIFO buffer for storing data. The buffer size must be a power of two.
+ * @param[in]  buf_size Size of the FIFO buffer provided. This size must be a power of two.
+ *
+ * @retval     NRF_SUCCESS              If initialization was successful.
+ * @retval     NRF_ERROR_NULL           If a NULL pointer is provided as buffer.
+ * @retval     NRF_ERROR_INVALID_LENGTH If size of buffer provided is not a power of two.
+ */
+uint32_t app_fifo_init(app_fifo_t * p_fifo, uint8_t * p_buf, uint16_t buf_size);
+
+/**@brief Function for adding an element to the FIFO.
+ *
+ * @param[in]  p_fifo   Pointer to the FIFO.
+ * @param[in]  byte     Data byte to add to the FIFO.
+ *
+ * @retval     NRF_SUCCESS              If an element has been successfully added to the FIFO.
+ * @retval     NRF_ERROR_NO_MEM         If the FIFO is full.
+ */
+uint32_t app_fifo_put(app_fifo_t * p_fifo, uint8_t byte);
+
+/**@brief Function for getting the next element from the FIFO.
+ *
+ * @param[in]  p_fifo   Pointer to the FIFO.
+ * @param[out] p_byte   Byte fetched from the FIFO.
+ *
+ * @retval     NRF_SUCCESS              If an element was returned.
+ * @retval     NRF_ERROR_NOT_FOUND      If there are no more elements in the queue.
+ */
+uint32_t app_fifo_get(app_fifo_t * p_fifo, uint8_t * p_byte);
+
+/**@brief Function for looking at an element in the FIFO, without consuming it.
+ *
+ * @param[in]  p_fifo   Pointer to the FIFO.
+ * @param[in]  index    Which element to look at. The lower the index, the earlier it was put.
+ * @param[out] p_byte   Byte fetched from the FIFO.
+ *
+ * @retval     NRF_SUCCESS              If an element was returned.
+ * @retval     NRF_ERROR_NOT_FOUND      If there are no more elements in the queue, or the index was
+ *                                      too large.
+ */
+uint32_t app_fifo_peek(app_fifo_t * p_fifo, uint16_t index, uint8_t * p_byte);
+
+/**@brief Function for flushing the FIFO.
+ *
+ * @param[in]  p_fifo   Pointer to the FIFO.
+ *
+ * @retval     NRF_SUCCESS              If the FIFO was flushed successfully.
+ */
+uint32_t app_fifo_flush(app_fifo_t * p_fifo);
+
+/**@brief Function for reading bytes from the FIFO.
+ *
+ * This function can also be used to get the number of bytes in the FIFO.
+ *
+ * @param[in]    p_fifo        Pointer to the FIFO. Must not be NULL.
+ * @param[out]   p_byte_array  Memory pointer where the read bytes are fetched from the FIFO.
+ *                             Can be NULL. If NULL, the number of bytes that can be read in the FIFO
+ *                             are returned in the p_size parameter.
+ * @param[inout] p_size        Address to memory indicating the maximum number of bytes to be read.
+ *                             The provided memory is overwritten with the actual number of bytes
+ *                             read if the procedure was successful. This field must not be NULL.
+ *                             If p_byte_array is set to NULL by the application, this parameter
+ *                             returns the number of bytes in the FIFO.
+ *
+ * @retval     NRF_SUCCESS          If the procedure is successful. The actual number of bytes read might
+ *                                  be less than the requested maximum, depending on how many elements exist
+ *                                  in the FIFO. Even if less bytes are returned, the procedure is considered
+ *                                  successful.
+ * @retval     NRF_ERROR_NULL       If a NULL parameter was passed for a parameter that must not
+ *                                  be NULL.
+ * @retval     NRF_ERROR_NOT_FOUND  If the FIFO is empty.
+ */
+uint32_t app_fifo_read(app_fifo_t * p_fifo, uint8_t * p_byte_array, uint32_t * p_size);
+
+/**@brief Function for writing bytes to the FIFO.
+ *
+ * This function can also be used to get the available size on the FIFO.
+ *
+ * @param[in]  p_fifo       Pointer to the FIFO. Must not be NULL.
+ * @param[in]  p_byte_array Memory pointer containing the bytes to be written to the FIFO.
+ *                          Can be NULL. If NULL, this function returns the number of bytes
+ *                          that can be written to the FIFO.
+ * @param[inout] p_size     Address to memory indicating the maximum number of bytes to be written.
+ *                          The provided memory is overwritten with the number of bytes that were actually
+ *                          written if the procedure is successful. This field must not be NULL.
+ *                          If p_byte_array is set to NULL by the application, this parameter
+ *                          returns the number of bytes available in the FIFO.
+ *
+ * @retval     NRF_SUCCESS       If the procedure is successful. The actual number of bytes written might
+ *                               be less than the requested maximum, depending on how much room there is in
+ *                               the FIFO. Even if less bytes are written, the procedure is considered
+ *                               successful. If the write was partial, the application should use
+ *                               subsequent calls to attempt writing the data again.
+ * @retval     NRF_ERROR_NULL    If a NULL parameter was passed for a parameter that must not
+ *                               be NULL.
+ * @retval     NRF_ERROR_NO_MEM  If the FIFO is full.
+ *
+ */
+uint32_t app_fifo_write(app_fifo_t * p_fifo, uint8_t const * p_byte_array, uint32_t * p_size);
+
+#endif // APP_FIFO_H__
+
+/** @} */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f06c2d2b/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/fstorage/config/fstorage_config.h
----------------------------------------------------------------------
diff --git a/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/fstorage/config/fstorage_config.h b/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/fstorage/config/fstorage_config.h
new file mode 100644
index 0000000..1423c01
--- /dev/null
+++ b/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/fstorage/config/fstorage_config.h
@@ -0,0 +1,59 @@
+/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved.
+ *
+ * The information contained herein is property of Nordic Semiconductor ASA.
+ * Terms and conditions of usage are described in detail in NORDIC
+ * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
+ *
+ * Licensees are granted free, non-transferable use of the information. NO
+ * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
+ * the file.
+ *
+ */
+
+#ifndef FS_CONFIG_H__
+#define FS_CONFIG_H__
+
+/**
+ * @defgroup fstorage_config fstorage configuration
+ * @ingroup fstorage
+ * @{
+ *
+ * @brief fstorage configuration options.
+ */
+
+
+/**@brief   Configures the size of fstorage internal queue.
+ * @details Increase this if there are many users, or if it is likely that many operation will be
+ *          queued at once without waiting for the previous operations to complete. In general,
+ *          increase the queue size if you frequently receive @ref FS_ERR_QUEUE_FULL errors when
+ *          calling @ref fs_store or @ref fs_erase.
+ */
+#define FS_QUEUE_SIZE       (4)
+
+/**@brief   Configures how many times should fstorage attempt to execute an operation if
+ *          the SoftDevice fails to schedule flash access due to high BLE activity.
+ * @details Increase this value if fstorage events return the @ref FS_ERR_OPERATION_TIMEOUT error
+ *          often.
+ */
+#define FS_OP_MAX_RETRIES   (3)
+
+
+/**@brief   Configures the maximum number of words to be written to flash in a single operation.
+ *          If data length exceeds this value, the data will be written down in several chunks,
+ *          as necessary.
+ *
+ * @details Tweaking this value can increase the chances of the SoftDevice being able to fit
+ *          flash operations in between radio activity. This value is bound by the maximum number
+ *          of words which the SoftDevice can write to flash in a single call to
+ *          @ref sd_flash_write, which is 256 words for nRF51 ICs and 1024 words for nRF52 ICs.
+ */
+#if   defined (NRF51)
+    #define FS_MAX_WRITE_SIZE_WORDS     (256)
+#elif defined (NRF52)
+    #define FS_MAX_WRITE_SIZE_WORDS     (1024)
+#endif
+
+/** @} */
+
+#endif // FS_CONFIG_H__
+

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f06c2d2b/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/fstorage/fstorage.c
----------------------------------------------------------------------
diff --git a/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/fstorage/fstorage.c b/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/fstorage/fstorage.c
new file mode 100644
index 0000000..b414597
--- /dev/null
+++ b/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/fstorage/fstorage.c
@@ -0,0 +1,494 @@
+/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved.
+ *
+ * The information contained herein is property of Nordic Semiconductor ASA.
+ * Terms and conditions of usage are described in detail in NORDIC
+ * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
+ *
+ * Licensees are granted free, non-transferable use of the information. NO
+ * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
+ * the file.
+ *
+ */
+
+#include "fstorage.h"
+#include "fstorage_config.h"
+#include "fstorage_internal_defs.h"
+
+#include <stdint.h>
+#include <string.h>
+#include <stdbool.h>
+#include "nrf_error.h"
+#include "nrf_soc.h"
+
+
+static uint8_t       m_flags;       // fstorage status flags.
+static fs_op_queue_t m_queue;       // Queue of requested operations.
+static uint8_t       m_retry_count; // Number of times the last flash operation was retried.
+
+
+// Sends events to the application.
+static void send_event(fs_op_t const * const p_op, fs_ret_t result)
+{
+    fs_evt_t evt;
+    memset(&evt, 0x00, sizeof(fs_evt_t));
+
+    switch (p_op->op_code)
+    {
+        case FS_OP_STORE:
+            evt.id                 = FS_EVT_STORE;
+            evt.store.p_data       = p_op->store.p_dest;
+            evt.store.length_words = p_op->store.length_words;
+            break;
+
+        case FS_OP_ERASE:
+            evt.id               = FS_EVT_ERASE;
+            evt.erase.first_page = p_op->erase.page - p_op->erase.pages_erased;
+            evt.erase.last_page  = p_op->erase.page;
+            break;
+
+        default:
+            // Should not happen.
+            break;
+    }
+
+    p_op->p_config->callback(&evt, result);
+}
+
+
+// Checks that a configuration is non-NULL and within section variable bounds.
+static bool check_config(fs_config_t const * const config)
+{
+    if ((config != NULL) &&
+        (FS_SECTION_VARS_START_ADDR <= (uint32_t)config) &&
+        (FS_SECTION_VARS_END_ADDR   >  (uint32_t)config))
+    {
+        return true;
+    }
+   
+    return false;
+}
+
+
+// Executes a store operation.
+static uint32_t store_execute(fs_op_t const * const p_op)
+{
+    uint16_t chunk_len;
+
+    if ((p_op->store.length_words - p_op->store.offset) < FS_MAX_WRITE_SIZE_WORDS)
+    {
+        chunk_len = p_op->store.length_words - p_op->store.offset;
+    }
+    else
+    {
+        chunk_len = FS_MAX_WRITE_SIZE_WORDS;
+    }
+
+    return sd_flash_write((uint32_t*)p_op->store.p_dest + p_op->store.offset,
+                          (uint32_t*)p_op->store.p_src  + p_op->store.offset,
+                          chunk_len);
+}
+
+
+// Executes an erase operation.
+static uint32_t erase_execute(fs_op_t const * const p_op)
+{
+    return sd_flash_page_erase(p_op->erase.page);
+}
+
+
+// Advances the queue, wrapping around if necessary.
+// If no elements are left in the queue, clears the FS_FLAG_PROCESSING flag.
+static void queue_advance(void)
+{
+    if (--m_queue.count == 0)
+    {
+        m_flags &= ~FS_FLAG_PROCESSING;
+    }
+
+    if (++m_queue.rp == FS_QUEUE_SIZE)
+    {
+        m_queue.rp = 0;
+    }
+}
+
+
+// Processes the current element in the queue. If the queue is empty, does nothing.
+static void queue_process(void)
+{
+    uint32_t         ret;
+    fs_op_t  * const p_op = &m_queue.op[m_queue.rp];
+
+    if (m_queue.count > 0)
+    {
+        switch (p_op->op_code)
+        {
+            case FS_OP_STORE:
+                ret = store_execute(p_op);
+                break;
+
+            case FS_OP_ERASE:
+                ret = erase_execute(p_op);
+                break;
+
+             default:
+                ret = FS_ERR_INTERNAL;
+                break;
+        }
+
+        // There is a pending flash operation which was not initiated by this module.
+        // Stop processing the queue and wait for a system event.
+        if (ret == NRF_ERROR_BUSY)
+        {
+            m_flags &= ~FS_FLAG_PROCESSING;
+            m_flags |= FS_FLAG_FLASH_REQ_PENDING;
+        }
+        else if (ret != NRF_SUCCESS)
+        {
+            // An error has occurred.
+            send_event(p_op, FS_ERR_INTERNAL);
+        }
+        else
+        {
+            // Operation is executing.
+        }
+    }
+}
+
+
+// Starts processing the queue if there are no pending flash operations, both inside and
+// outside this module. Returns immediately otherwise.
+static void queue_start(void)
+{
+    if (!(m_flags & FS_FLAG_PROCESSING) &&
+        !(m_flags & FS_FLAG_FLASH_REQ_PENDING))
+    {
+        m_flags |= FS_FLAG_PROCESSING;
+        queue_process();
+    }
+}
+
+
+// Flash operation success callback handler. Keeps track of the progress of an operation.
+// If it has finished, advances the queue and notifies the application.
+static void on_operation_success(fs_op_t * const p_op)
+{
+    m_retry_count = 0;
+
+    switch (p_op->op_code)
+    {
+        case FS_OP_STORE:
+        {
+            uint16_t chunk_len;
+
+            if ((p_op->store.length_words - p_op->store.offset) < FS_MAX_WRITE_SIZE_WORDS)
+            {
+                chunk_len = p_op->store.length_words - p_op->store.offset;
+            }
+            else
+            {
+                chunk_len = FS_MAX_WRITE_SIZE_WORDS;
+            }
+
+            p_op->store.offset += chunk_len;
+
+            if (p_op->store.offset == p_op->store.length_words)
+            {
+                // The operation has finished.
+                send_event(p_op, FS_SUCCESS);
+                queue_advance();
+            }
+        }
+        break;
+
+        case FS_OP_ERASE:
+        {
+            p_op->erase.page++;
+            p_op->erase.pages_erased++;
+
+            if (p_op->erase.pages_erased == p_op->erase.pages_to_erase)
+            {
+                send_event(p_op, FS_SUCCESS);
+                queue_advance();
+            }
+        }
+        break;
+
+        default:
+            // Should not happen.
+            break;
+    }
+}
+
+
+// Flash operation failure callback handler. If the maximum number of retries has
+// been reached, notifies the application and advances the queue.
+static void on_operation_failure(fs_op_t const * const p_op)
+{
+    if (++m_retry_count > FS_OP_MAX_RETRIES)
+    {
+        m_retry_count = 0;
+
+        send_event(p_op, FS_ERR_OPERATION_TIMEOUT);
+        queue_advance();
+    }
+}
+
+
+// Retrieves a pointer to the next free element in the queue.
+// Additionally, increases the number of elements stored in the queue.
+static bool queue_get_next_free(fs_op_t ** p_op)
+{
+    uint32_t idx;
+
+    if (m_queue.count == FS_QUEUE_SIZE)
+    {
+        return false;
+    }
+
+    idx = ((m_queue.rp + m_queue.count) < FS_QUEUE_SIZE) ?
+           (m_queue.rp + m_queue.count) : 0;
+
+    m_queue.count++;
+
+    // Zero the element so that unassigned fields will be zero.
+    memset(&m_queue.op[idx], 0x00, sizeof(fs_op_t));
+
+    *p_op = &m_queue.op[idx];
+
+    return true;
+}
+
+
+fs_ret_t fs_init(void)
+{
+    uint32_t const   users         = FS_SECTION_VARS_COUNT;
+    uint32_t const * p_current_end = FS_PAGE_END_ADDR;
+    uint32_t         index_max     = 0x00;
+    uint32_t         index_last    = 0xFFFFFFFF;
+
+    if (m_flags & FS_FLAG_INITIALIZED)
+    {
+        return FS_SUCCESS;
+    }
+
+    #if 0
+    // Check for configurations with duplicate priority.
+    for (uint32_t i = 0; i < users; i++)
+    {
+        for (uint32_t j = i + 1; j < users; j++)
+        {
+            fs_config_t const * const p_config_i = FS_SECTION_VARS_GET(i);
+            fs_config_t const * const p_config_j = FS_SECTION_VARS_GET(j);
+
+            if (p_config_i->page_order == p_config_j->page_order)
+            {
+                // Error.
+                return FS_ERR_INVALID_CFG;
+            }
+        }
+    }
+    #endif
+
+    // Assign pages to registered users, beginning with the ones with the highest
+    // priority, which will be assigned pages with the highest memory address.
+
+    for (uint32_t i = 0; i < users; i++)
+    {
+        uint8_t max_priority  = 0x00;
+
+        for (uint32_t j = 0; j < users; j++)
+        {
+            fs_config_t * const p_config = FS_SECTION_VARS_GET(j);
+
+            // Skip the one assigned during last iteration.
+            if (j == index_last)
+            {
+                continue;
+            }
+
+            if (p_config->priority >= max_priority)
+            {
+                max_priority = p_config->priority;
+                index_max    = j;
+            }
+        }
+
+        fs_config_t * const p_config = FS_SECTION_VARS_GET(index_max);
+
+        p_config->p_end_addr   = p_current_end;
+        p_config->p_start_addr = p_current_end - (p_config->num_pages * FS_PAGE_SIZE_WORDS);
+
+        p_current_end = p_config->p_start_addr;
+
+        index_last = index_max;
+    }
+
+    m_flags |= FS_FLAG_INITIALIZED;
+
+    return FS_SUCCESS;
+}
+
+
+fs_ret_t fs_store(fs_config_t const * const p_config,
+                  uint32_t    const * const p_dest,
+                  uint32_t    const * const p_src,
+                  uint16_t    const         length_words)
+{
+    fs_op_t * p_op;
+
+    if (!(m_flags & FS_FLAG_INITIALIZED))
+    {
+        return FS_ERR_NOT_INITIALIZED;
+    }
+
+    if (!check_config(p_config))
+    {
+        return FS_ERR_INVALID_CFG;
+    }
+
+    if ((p_src == NULL) || (p_dest == NULL))
+    {
+        return FS_ERR_NULL_ARG;
+    }
+
+    // Check that both pointers are word aligned.
+    if (((uint32_t)p_src  & 0x03) ||
+        ((uint32_t)p_dest & 0x03))
+    {
+        return FS_ERR_UNALIGNED_ADDR;
+    }
+
+    // Check that the operation doesn't go outside the client's memory boundaries.
+    if ((p_config->p_start_addr > p_dest) ||
+        (p_config->p_end_addr   < (p_dest + length_words)))
+    {
+        return FS_ERR_INVALID_ADDR;
+    }
+
+    if (length_words == 0)
+    {
+        return FS_ERR_INVALID_ARG;
+    }
+
+    if (!queue_get_next_free(&p_op))
+    {
+        return FS_ERR_QUEUE_FULL;
+    }
+
+    // Initialize the operation.
+    p_op->p_config           = p_config;
+    p_op->op_code            = FS_OP_STORE;
+    p_op->store.p_src        = p_src;
+    p_op->store.p_dest       = p_dest;
+    p_op->store.length_words = length_words;
+
+    queue_start();
+
+    return FS_SUCCESS;
+}
+
+
+fs_ret_t fs_erase(fs_config_t const * const p_config,
+                  uint32_t    const * const p_page_addr,
+                  uint16_t    const         num_pages)
+{
+    fs_op_t * p_op;
+
+    if (!(m_flags & FS_FLAG_INITIALIZED))
+    {
+        return FS_ERR_NOT_INITIALIZED;
+    }
+
+    if (!check_config(p_config))
+    {
+        return FS_ERR_INVALID_CFG;
+    }
+
+    if (p_page_addr == NULL)
+    {
+        return FS_ERR_NULL_ARG;
+    }
+
+    // Check that the page is aligned to a page boundary.
+    if (((uint32_t)p_page_addr % FS_PAGE_SIZE) != 0)
+    {
+        return FS_ERR_UNALIGNED_ADDR;
+    }
+
+    // Check that the operation doesn't go outside the client's memory boundaries.
+    if ((p_page_addr < p_config->p_start_addr) ||
+        (p_page_addr + (FS_PAGE_SIZE_WORDS * num_pages) > p_config->p_end_addr))
+    {
+        return FS_ERR_INVALID_ADDR;
+    }
+
+    if (num_pages == 0)
+    {
+        return FS_ERR_INVALID_ARG;
+    }
+
+    if (!queue_get_next_free(&p_op))
+    {
+        return FS_ERR_QUEUE_FULL;
+    }
+
+    // Initialize the operation.
+    p_op->p_config             = p_config;
+    p_op->op_code              = FS_OP_ERASE;
+    p_op->erase.page           = ((uint32_t)p_page_addr / FS_PAGE_SIZE);
+    p_op->erase.pages_to_erase = num_pages;
+
+    queue_start();
+
+    return FS_SUCCESS;
+}
+
+
+fs_ret_t fs_queued_op_count_get(uint32_t * const p_op_count)
+{
+    if (p_op_count == NULL)
+    {
+        return FS_ERR_NULL_ARG;
+    }
+
+    *p_op_count = m_queue.count;
+
+    return FS_SUCCESS;
+}
+
+
+void fs_sys_event_handler(uint32_t sys_evt)
+{
+    fs_op_t * const p_op = &m_queue.op[m_queue.rp];
+    
+    if (m_flags & FS_FLAG_PROCESSING)
+    {
+        // A flash operation was initiated by this module. Handle the result.
+        switch (sys_evt)
+        {
+            case NRF_EVT_FLASH_OPERATION_SUCCESS:
+                on_operation_success(p_op);
+                break;
+
+            case NRF_EVT_FLASH_OPERATION_ERROR:
+                on_operation_failure(p_op);
+                break;
+        }
+    }
+    else if ((m_flags & FS_FLAG_FLASH_REQ_PENDING))
+    {
+        // A flash operation was initiated outside this module.
+        // A callback which indicates that it has finished was received.
+        m_flags &= ~FS_FLAG_FLASH_REQ_PENDING;
+
+        // If there are any elements left in the queue, set FS_FLAG_PROCESSING.
+        if (m_queue.count > 0)
+        {
+           m_flags |= FS_FLAG_PROCESSING;
+        }
+    }
+
+    // Resume processing the queue, if necessary.
+    queue_process();
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f06c2d2b/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/fstorage/fstorage.h
----------------------------------------------------------------------
diff --git a/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/fstorage/fstorage.h b/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/fstorage/fstorage.h
new file mode 100644
index 0000000..7e2044b
--- /dev/null
+++ b/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/fstorage/fstorage.h
@@ -0,0 +1,235 @@
+/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved.
+ *
+ * The information contained herein is property of Nordic Semiconductor ASA.
+ * Terms and conditions of usage are described in detail in NORDIC
+ * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
+ *
+ * Licensees are granted free, non-transferable use of the information. NO
+ * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
+ * the file.
+ *
+ */
+
+#ifndef FSTORAGE_H__
+#define FSTORAGE_H__
+
+/**
+ * @defgroup fstorage fstorage
+ * @ingroup app_common
+ * @{
+ *
+ * @brief   Module which provides functionality to store data to flash and erase flash pages.
+ */
+
+#include <stdint.h>
+#include "section_vars.h"
+
+
+/**@brief   fstorage return values. */
+typedef enum
+{
+    FS_SUCCESS,
+    FS_ERR_NOT_INITIALIZED,     //!< Error. The module is not initialized.
+    FS_ERR_INVALID_CFG,         //!< Error. Invalid fstorage configuration.
+    FS_ERR_NULL_ARG,            //!< Error. Argument is NULL.
+    FS_ERR_INVALID_ARG,         //!< Error. Argument contains invalid data.
+    FS_ERR_INVALID_ADDR,        //!< Error. Address out of bounds.
+    FS_ERR_UNALIGNED_ADDR,      //!< Error. Unaligned address.
+    FS_ERR_QUEUE_FULL,          //!< Error. Queue is full.
+    FS_ERR_OPERATION_TIMEOUT,   //!< Error. The operation has timed out.
+    FS_ERR_INTERNAL,            //!< Error. Internal error.
+} fs_ret_t;
+
+
+/**@brief   fstorage event IDs. */
+typedef enum
+{
+    FS_EVT_STORE,   //!< Event for @ref fs_store.
+    FS_EVT_ERASE    //!< Event for @ref fs_erase.
+} fs_evt_id_t;
+
+
+#if defined(__CC_ARM)
+  #pragma push
+  #pragma anon_unions
+#elif defined(__ICCARM__)
+  #pragma language=extended
+#elif defined(__GNUC__)
+  /* anonymous unions are enabled by default */
+#endif
+
+/**@brief   An fstorage event. */
+typedef struct
+{
+    fs_evt_id_t id;                         //!< The event ID.
+    union
+    {
+        struct
+        {
+            uint32_t const * p_data;        //!< Pointer to the data stored in flash.
+            uint16_t         length_words;  //!< Length of the data, in 4-byte words.
+        } store;
+        struct
+        {
+            uint16_t first_page;            //!< First page erased.
+            uint16_t last_page;             //!< Last page erased.
+        } erase;
+    };
+} fs_evt_t;
+
+#if defined(__CC_ARM)
+  #pragma pop
+#elif defined(__ICCARM__)
+  /* leave anonymous unions enabled */
+#elif defined(__GNUC__)
+  /* anonymous unions are enabled by default */
+#endif
+
+
+/**@brief   fstorage event handler function prototype.
+ *
+ * @param[in]   evt     The event.
+ * @param[in]   result  The result of the operation.
+ */
+typedef void (*fs_cb_t)(fs_evt_t const * const evt, fs_ret_t result);
+
+
+/**@brief   fstorage application-specific configuration.
+ *
+ * @details Specifies the callback to invoke when an operation completes, the number of flash pages
+ *          requested by the application and the priority with which these are to be assigned, with
+ *          respect to other applications. Additionally, the configuration specifies the boundaries
+ *          of the flash space assigned to an application. The configuration must be provided as an
+ *          argument when invoking @ref fs_store and @ref fs_erase.
+ *
+ * @note    The fields @p p_start_addr and @p p_end_address are set by @ref fs_init, based on the
+ *          value of the field @p priority.
+ */
+typedef struct
+{
+    /**@brief   The beginning of the flash space assigned to the application which registered this
+     *          configuration. This field is set by @ref fs_init.
+     */
+    uint32_t const * p_start_addr;
+
+    /**@brief   The end of the flash space assigned to the application which registered this
+     *          configuration. This field is set by @ref fs_init.
+     */
+    uint32_t const * p_end_addr;
+
+    fs_cb_t  const   callback;    //!< Callback to run when a flash operation has completed.
+    uint8_t  const   num_pages;   //!< The number of flash pages requested.
+
+    /**@brief   The priority with which fstorage should assign flash pages to this application,
+     *          with respect to other applications. Applications with higher priority will be
+     *          assigned flash pages with a higher memory address. The highest priority is
+     *          reserved. Must be unique among configurations.
+     */
+    uint8_t  const   priority;
+} fs_config_t;
+
+
+/**@brief   Macro for registering with an fstorage configuration.
+ *          Applications which use fstorage must register with the module using this macro.
+ *          Registering involves defining a variable which holds the configuration of fstorage
+ *          specific to the application which invokes the macro.
+ *
+ * @details This macro places the configuration variable in a section named "fs_data" that
+ *          fstorage uses during initialization and regular operation.
+ *
+ * @param[in]   cfg_var     A @e definition of a @ref fs_config_t variable.
+ */
+#define FS_REGISTER_CFG(cfg_var) NRF_SECTION_VARS_ADD(fs_data, cfg_var)
+
+
+/**@brief   Function for initializing the module.
+ *
+ * @details This functions assigns pages in flash according to all registered configurations.
+ *
+ * @retval  FS_SUCCESS    If the module was successfully initialized.
+ */
+fs_ret_t fs_init(void);
+
+
+/**@brief   Function for storing data in flash.
+ *
+ * @details Copies @p length_words words from @p p_src to the location pointed by @p p_dest.
+ *          If the length of the data exceeds @ref FS_MAX_WRITE_SIZE_WORDS, the data will be
+ *          written down in several chunks, as necessary. Only one event will be sent to the
+ *          application upon completion. Both the source and the destination of the data must be
+ *          word aligned. This function is asynchronous, completion is reported via an event sent
+ *          the the callback function specified in the supplied configuration.
+ *
+ * @warning The data to be written to flash has to be kept in memory until the operation has
+ *          terminated, i.e., an event is received.
+ *
+ * @param[in]   p_config        fstorage configuration registered by the application.
+ * @param[in]   p_dest          The address in flash memory where to store the data.
+ * @param[in]   p_src           Pointer to the data to store in flash.
+ * @param[in]   length_words    Length of the data to store, in words.
+ *
+ * @retval  FS_SUCCESS              If the operation was queued successfully.
+ * @retval  FS_ERR_NOT_INITIALIZED  If the module is not initialized.
+ * @retval  FS_ERR_INVALID_CFG      If @p p_config is NULL or contains invalid data.
+ * @retval  FS_ERR_NULL_ARG         If @p p_dest or @p p_src are NULL.
+ * @retval  FS_ERR_INVALID_ARG      If @p length_words is zero.
+ * @retval  FS_ERR_INVALID_ADDR     If @p p_dest or @p p_src are outside of the flash memory
+ *                                  boundaries specified in @p p_config.
+ * @retval  FS_ERR_UNALIGNED_ADDR   If @p p_dest or @p p_src are not aligned to a word boundary.
+ * @retval  FS_ERR_QUEUE_FULL       If the internal operation queue is full.
+ */
+fs_ret_t fs_store(fs_config_t const * const p_config,
+                  uint32_t    const * const p_dest,
+                  uint32_t    const * const p_src,
+                  uint16_t                  length_words);
+
+
+/**@brief   Function for erasing flash pages.
+ *
+ * @details Starting from the page at @p p_page_addr, erases @p num_pages flash pages.
+ *          @p p_page_addr must be aligned to a page boundary. All pages to be erased must be
+ *          within the bounds specified in the supplied fstorage configuration.
+ *          This function is asynchronous. Completion is reported via an event.
+ *
+ * @param[in]   p_config        fstorage configuration registered by the application.
+ * @param[in]   p_page_addr     Address of the page to erase. Must be aligned to a page boundary.
+ * @param[in]   num_pages       Number of pages to erase. May not be zero.
+ *
+ * @retval  FS_SUCCESS              If the operation was queued successfully.
+ * @retval  FS_ERR_NOT_INITIALIZED  If the module is not initialized.
+ * @retval  FS_ERR_INVALID_CFG      If @p p_config is NULL or contains invalid data.
+ * @retval  FS_ERR_NULL_ARG         If @p p_page_addr is NULL.
+ * @retval  FS_ERR_INVALID_ARG      If @p num_pages is zero.
+ * @retval  FS_ERR_INVALID_ADDR     If the operation would go beyond the flash memory boundaries
+ *                                  specified in @p p_config.
+ * @retval  FS_ERR_UNALIGNED_ADDR   If @p p_page_addr is not aligned to a page boundary.
+ * @retval  FS_ERR_QUEUE_FULL       If the internal operation queue is full.
+ */
+fs_ret_t fs_erase(fs_config_t const * const p_config,
+                  uint32_t    const * const p_page_addr,
+                  uint16_t                  num_pages);
+
+
+/**@brief Function for retrieving the number of queued flash operations.
+ *
+ * @param[out]  p_op_count    The number of queued flash operations.
+ *
+ * @retval  FS_SUCCESS          If the number of queued operations was retrieved successfully.
+ * @retval  FS_ERR_NULL_ARG     If @p p_op_count is NULL.
+ */
+fs_ret_t fs_queued_op_count_get(uint32_t * const p_op_count);
+
+
+/**@brief   Function for handling system events from the SoftDevice.
+ *
+ * @details If any of the modules used by the application rely on fstorage, the application should
+ *          dispatch system events to fstorage using this function.
+ *
+ * @param[in]   sys_evt     System event from the SoftDevice.
+ */
+void fs_sys_event_handler(uint32_t sys_evt);
+
+
+/** @} */
+
+#endif // FSTORAGE_H__