nrf8001: added new BLE module with broadcasting example
authorKiveisha Yevgeniy <yevgeniy.kiveisha@intel.com>
Tue, 12 Aug 2014 23:40:47 +0000 (23:40 +0000)
committerKiveisha Yevgeniy <yevgeniy.kiveisha@intel.com>
Tue, 12 Aug 2014 23:40:47 +0000 (23:40 +0000)
Signed-off-by: Kiveisha Yevgeniy <yevgeniy.kiveisha@intel.com>
29 files changed:
examples/CMakeLists.txt
examples/nrf8001_broadcast.cxx [new file with mode: 0644]
examples/nrf8001_broadcast.h [new file with mode: 0644]
src/nrf8001/CMakeLists.txt [new file with mode: 0644]
src/nrf8001/aci.h [new file with mode: 0644]
src/nrf8001/aci_cmds.h [new file with mode: 0644]
src/nrf8001/aci_evts.h [new file with mode: 0644]
src/nrf8001/aci_protocol_defines.h [new file with mode: 0644]
src/nrf8001/aci_queue.cpp [new file with mode: 0644]
src/nrf8001/aci_queue.h [new file with mode: 0644]
src/nrf8001/aci_setup.cpp [new file with mode: 0644]
src/nrf8001/aci_setup.h [new file with mode: 0644]
src/nrf8001/acilib.cpp [new file with mode: 0644]
src/nrf8001/acilib.h [new file with mode: 0644]
src/nrf8001/acilib_defs.h [new file with mode: 0644]
src/nrf8001/acilib_if.h [new file with mode: 0644]
src/nrf8001/acilib_types.h [new file with mode: 0644]
src/nrf8001/boards.h [new file with mode: 0644]
src/nrf8001/dtm.h [new file with mode: 0644]
src/nrf8001/hal_aci_tl.cpp [new file with mode: 0644]
src/nrf8001/hal_aci_tl.h [new file with mode: 0644]
src/nrf8001/hal_platform.h [new file with mode: 0644]
src/nrf8001/jsupm_nrf8001.i [new file with mode: 0644]
src/nrf8001/lib_aci.cpp [new file with mode: 0644]
src/nrf8001/lib_aci.h [new file with mode: 0644]
src/nrf8001/nrf8001.cxx [new file with mode: 0644]
src/nrf8001/nrf8001.h [new file with mode: 0644]
src/nrf8001/pyupm_nrf8001.i [new file with mode: 0644]
src/nrf8001/uart_over_ble.h [new file with mode: 0644]

index e36a293..6c0b6fe 100644 (file)
@@ -24,6 +24,7 @@ add_executable (mpu9150-example mpu9150-example.cxx)
 add_executable (maxds3231m-example maxds3231m.cxx)
 add_executable (max31723-example max31723.cxx)
 add_executable (max5487-example max5487.cxx)
+add_executable (nrf8001-broadcast-example nrf8001_broadcast.cxx)
 
 include_directories (${PROJECT_SOURCE_DIR}/src/hmc5883l)
 include_directories (${PROJECT_SOURCE_DIR}/src/grove)
@@ -46,6 +47,7 @@ include_directories (${PROJECT_SOURCE_DIR}/src/mpu9150)
 include_directories (${PROJECT_SOURCE_DIR}/src/maxds3231m)
 include_directories (${PROJECT_SOURCE_DIR}/src/max31723)
 include_directories (${PROJECT_SOURCE_DIR}/src/max5487)
+include_directories (${PROJECT_SOURCE_DIR}/src/nrf8001)
 
 target_link_libraries (compass hmc5883l ${CMAKE_THREAD_LIBS_INIT})
 target_link_libraries (groveled grove ${CMAKE_THREAD_LIBS_INIT})
@@ -73,3 +75,4 @@ target_link_libraries (mpu9150-example mpu9150 ${CMAKE_THREAD_LIBS_INIT})
 target_link_libraries (maxds3231m-example maxds3231m ${CMAKE_THREAD_LIBS_INIT})
 target_link_libraries (max31723-example max31723 ${CMAKE_THREAD_LIBS_INIT})
 target_link_libraries (max5487-example max5487 ${CMAKE_THREAD_LIBS_INIT})
+target_link_libraries (nrf8001-broadcast-example nrf8001 ${CMAKE_THREAD_LIBS_INIT})
diff --git a/examples/nrf8001_broadcast.cxx b/examples/nrf8001_broadcast.cxx
new file mode 100644 (file)
index 0000000..c4b5128
--- /dev/null
@@ -0,0 +1,177 @@
+/*
+ * Author: Yevgeniy Kiveisha <yevgeniy.kiveisha@intel.com>
+ * Copyright (c) 2014 Intel Corporation.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <unistd.h>
+#include <iostream>
+#include "nrf8001.h"
+#include "nrf8001_broadcast.h"
+#include <lib_aci.h>
+#include <aci_setup.h>
+#include <signal.h>
+
+#ifdef SERVICES_PIPE_TYPE_MAPPING_CONTENT
+    static services_pipe_type_mapping_t
+        services_pipe_type_mapping[NUMBER_OF_PIPES] = SERVICES_PIPE_TYPE_MAPPING_CONTENT;
+#else
+    #define NUMBER_OF_PIPES 0
+    static services_pipe_type_mapping_t * services_pipe_type_mapping = NULL;
+#endif
+
+/**
+ * Store the setup for the nRF8001 in the flash of the AVR to save on RAM
+ */
+static hal_aci_data_t setup_msgs[NB_SETUP_MESSAGES] = SETUP_MESSAGES_CONTENT;
+
+/**
+ * aci_struct that will contain
+ * total initial credits
+ * current credit
+ * current state of the aci (setup/standby/active/sleep)
+ * open remote pipe pending
+ * close remote pipe pending
+ * Current pipe available bitmap
+ * Current pipe closed bitmap
+ * Current connection interval, slave latency and link supervision timeout
+ * Current State of the the GATT client (Service Discovery)
+ * Status of the bond (R) Peer address
+ */
+static struct aci_state_t aci_state;
+
+/**
+ * Temporary buffers for sending ACI commands
+ */
+static hal_aci_evt_t  aci_data;
+
+void
+sig_handler(int signo)
+{
+    printf("got signal\n");
+    if (signo == SIGINT) {
+        printf("exiting application\n");
+    }
+}
+
+void
+init_aci_setup () {
+    /**
+     * Point ACI data structures to the the setup data that the nRFgo studio generated for the nRF8001
+     */
+    if (NULL != services_pipe_type_mapping) {
+        aci_state.aci_setup_info.services_pipe_type_mapping = &services_pipe_type_mapping[0];
+    } else {
+        aci_state.aci_setup_info.services_pipe_type_mapping = NULL;
+    }
+
+    aci_state.aci_setup_info.number_of_pipes    = NUMBER_OF_PIPES;
+    aci_state.aci_setup_info.setup_msgs         = setup_msgs;
+    aci_state.aci_setup_info.num_setup_msgs     = NB_SETUP_MESSAGES;
+}
+
+int
+main(int argc, char **argv)
+{
+    //! [Interesting]
+
+    init_aci_setup ();
+    init_local_interfaces (&aci_state, 10, 8, 4);
+
+    while (1) {
+        static bool setup_required = false;
+        if (lib_aci_event_get (&aci_state, &aci_data)) {
+            aci_evt_t * aci_evt;
+            aci_evt = &aci_data.evt;
+
+            switch(aci_evt->evt_opcode) {
+                /**
+                As soon as you reset the nRF8001 you will get an ACI Device Started Event
+                */
+                case ACI_EVT_DEVICE_STARTED: {
+                    aci_state.data_credit_available = aci_evt->params.device_started.credit_available;
+                    switch(aci_evt->params.device_started.device_mode) {
+                        case ACI_DEVICE_SETUP:
+                            /**
+                            When the device is in the setup mode
+                            */
+                            printf ("Evt Device Started: Setup\n");
+                            setup_required = true;
+                        break;
+
+                        case ACI_DEVICE_STANDBY:
+                            printf ("Evt Device Started: Standby\n");
+                            lib_aci_broadcast(10/* in seconds */, 0x0100 /* advertising interval 100ms */);
+                            printf ("Broadcasting started\n");
+                        break;
+                    }
+                }
+                break; //ACI Device Started Event
+
+                case ACI_EVT_CMD_RSP:
+                    if (ACI_STATUS_SUCCESS != aci_evt->params.cmd_rsp.cmd_status) {
+                        printf ("ACI_EVT_CMD_RSP\n");
+                        while (1);
+                    }
+                break;
+
+                case ACI_EVT_CONNECTED:
+                    printf ("ACI_EVT_CONNECTED\n");
+                    break;
+
+                case ACI_EVT_PIPE_STATUS:
+                    printf ("ACI_EVT_PIPE_STATUS\n");
+                    break;
+
+                case ACI_EVT_DISCONNECTED:
+                    if (ACI_STATUS_ERROR_ADVT_TIMEOUT == aci_evt->params.disconnected.aci_status) {
+                        printf ("Broadcasting timed out\n");
+                    } else {
+                        printf ("Evt Disconnected. Link Loss\n");
+                    }
+                    break;
+
+                case ACI_EVT_DATA_RECEIVED:
+                    printf ("ACI_EVT_DATA_RECEIVED\n");
+                    break;
+
+                case ACI_EVT_HW_ERROR:
+                    printf ("ACI_EVT_HW_ERROR\n");
+                    break;
+            }
+        }
+
+        if (setup_required) {
+            if (SETUP_SUCCESS == do_aci_setup(&aci_state)) {
+                setup_required = false;
+            }
+        }
+        usleep (100);
+    }
+
+    close_local_interfaces (&aci_state);
+
+    //! [Interesting]
+
+    std::cout << "exiting application" << std::endl;
+
+    return 0;
+}
diff --git a/examples/nrf8001_broadcast.h b/examples/nrf8001_broadcast.h
new file mode 100644 (file)
index 0000000..b6f8cb5
--- /dev/null
@@ -0,0 +1,93 @@
+#include "hal_platform.h"
+#include "aci.h"
+
+#pragma once
+
+#define PIPE_GAP_DEVICE_NAME_SET 1
+
+#define NUMBER_OF_PIPES 1
+
+#define SERVICES_PIPE_TYPE_MAPPING_CONTENT {\
+  {ACI_STORE_LOCAL, ACI_SET},   \
+}
+
+#define GAP_PPCP_MAX_CONN_INT 0xffff /**< Maximum connection interval as a multiple of 1.25 msec , 0xFFFF means no specific value requested */
+#define GAP_PPCP_MIN_CONN_INT  0xffff /**< Minimum connection interval as a multiple of 1.25 msec , 0xFFFF means no specific maximum*/
+#define GAP_PPCP_SLAVE_LATENCY 0
+#define GAP_PPCP_CONN_TIMEOUT 0xffff /** Connection Supervision timeout multiplier as a multiple of 10msec, 0xFFFF means no specific value requested */
+
+#define NB_SETUP_MESSAGES 13
+#define SETUP_MESSAGES_CONTENT {\
+    {0x00,\
+        {\
+            0x07,0x06,0x00,0x00,0x03,0x02,0x41,0xd7,\
+        },\
+    },\
+    {0x00,\
+        {\
+            0x1f,0x06,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x01,0x01,0x00,0x00,0x06,0x00,0x01,\
+            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
+        },\
+    },\
+    {0x00,\
+        {\
+            0x1f,0x06,0x10,0x1c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
+            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x90,0x00,0x64,\
+        },\
+    },\
+    {0x00,\
+        {\
+            0x1f,0x06,0x10,0x38,0x02,0xff,0x02,0x58,0x00,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
+            0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
+        },\
+    },\
+    {0x00,\
+        {\
+            0x05,0x06,0x10,0x54,0x00,0x00,\
+        },\
+    },\
+    {0x00,\
+        {\
+            0x1f,0x06,0x20,0x00,0x04,0x04,0x02,0x02,0x00,0x01,0x28,0x00,0x01,0x00,0x18,0x04,0x04,0x05,0x05,0x00,\
+            0x02,0x28,0x03,0x01,0x0e,0x03,0x00,0x00,0x2a,0x04,0x14,0x0b,\
+        },\
+    },\
+    {0x00,\
+        {\
+            0x1f,0x06,0x20,0x1c,0x05,0x00,0x03,0x2a,0x00,0x01,0x62,0x63,0x61,0x73,0x74,0x63,0x73,0x65,0x6d,0x69,\
+            0x2e,0x04,0x04,0x05,0x05,0x00,0x04,0x28,0x03,0x01,0x02,0x05,\
+        },\
+    },\
+    {0x00,\
+        {\
+            0x1f,0x06,0x20,0x38,0x00,0x01,0x2a,0x06,0x04,0x03,0x02,0x00,0x05,0x2a,0x01,0x01,0x00,0x00,0x04,0x04,\
+            0x05,0x05,0x00,0x06,0x28,0x03,0x01,0x02,0x07,0x00,0x04,0x2a,\
+        },\
+    },\
+    {0x00,\
+        {\
+            0x1f,0x06,0x20,0x54,0x06,0x04,0x09,0x08,0x00,0x07,0x2a,0x04,0x01,0xff,0xff,0xff,0xff,0x00,0x00,0xff,\
+            0xff,0x04,0x04,0x02,0x02,0x00,0x08,0x28,0x00,0x01,0x01,0x18,\
+        },\
+    },\
+    {0x00,\
+        {\
+            0x04,0x06,0x20,0x70,0x00,\
+        },\
+    },\
+    {0x00,\
+        {\
+            0x0d,0x06,0x40,0x00,0x2a,0x00,0x01,0x00,0x80,0x04,0x00,0x03,0x00,0x00,\
+        },\
+    },\
+    {0x00,\
+        {\
+            0x06,0x06,0x60,0x00,0x00,0x00,0x00,\
+        },\
+    },\
+    {0x00,\
+        {\
+            0x06,0x06,0xf0,0x00,0x03,0x4c,0xf2,\
+        },\
+    },\
+}
diff --git a/src/nrf8001/CMakeLists.txt b/src/nrf8001/CMakeLists.txt
new file mode 100644 (file)
index 0000000..a449e44
--- /dev/null
@@ -0,0 +1,5 @@
+set (libname "nrf8001")
+set (libdescription "BLE module from NordicSemiconductor family")
+set (module_src hal_aci_tl.cpp aci_setup.cpp aci_queue.cpp acilib.cpp lib_aci.cpp ${libname}.cxx)
+set (module_h hal_aci_tl.h aci_setup.h aci_queue.h acilib.h lib_aci.h ${libname}.h)
+upm_module_init()
diff --git a/src/nrf8001/aci.h b/src/nrf8001/aci.h
new file mode 100644 (file)
index 0000000..18810cb
--- /dev/null
@@ -0,0 +1,669 @@
+/* Copyright (c) 2014, Nordic Semiconductor ASA\r
+ *\r
+ * Permission is hereby granted, free of charge, to any person obtaining a copy\r
+ * of this software and associated documentation files (the "Software"), to deal\r
+ * in the Software without restriction, including without limitation the rights\r
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+ * copies of the Software, and to permit persons to whom the Software is\r
+ * furnished to do so, subject to the following conditions:\r
+ *\r
+ * The above copyright notice and this permission notice shall be included in all\r
+ * copies or substantial portions of the Software.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ */\r
+\r
+/**\r
+ * @file\r
+ *\r
+ * @defgroup aci aci\r
+ * @{\r
+ * @ingroup lib\r
+ *\r
+ * @brief Definitions for the ACI (Application Control Interface)\r
+ * @remarks\r
+ *\r
+ * Flow control from application mcu to nRF8001\r
+ *\r
+ * Data flow control:\r
+ * The flow control is credit based and the credit is initally given using the "device started" event.\r
+ * A credit of more than 1 is given to the application mcu.\r
+ * These credits are used only after the "ACI Connected Event" is sent to the application mcu.\r
+ *\r
+ * every send_data that is used decrements the credit available by 1. This is to be tracked by the application mcu.\r
+ * When the credit available reaches 0, the application mcu shall not send any more send_data.\r
+ * Credit is returned using the "credit event", this returned credit can then be used to send more send_data.\r
+ * This flow control is not necessary and not available for Broadcast.\r
+ * The entire credit available with the external mcu expires when a "disconnected" event arrives.\r
+ *\r
+ * Command flow control:\r
+ * When a command is sent over the ACI, the next command shall not be sent until after a response\r
+ * for the command sent has arrived.\r
+ *\r
+ */\r
+\r
+#ifndef ACI_H__\r
+#define ACI_H__\r
+\r
+/**\r
+ * Define an _aci_packed_ macro we can use in structure and enumerated type\r
+ * declarations so that the types are sized consistently across different\r
+ * platforms. In particular Arduino platforms using the GCC compiler and the\r
+ * Nordic processors using the Keil compiler.\r
+ *\r
+ * It's really the GNU compiler platforms that need a special keyword to get\r
+ * tight packing of values. On GNU platforms we can use the keyword:\r
+ *     __attribute__((__packed__))\r
+ * The thing is that while this keyword does the right thing with old and new\r
+ * versions of the gcc (C) compiler it only works right with g++ (C++) compiler\r
+ * versions that are version 4 or newer.\r
+ */\r
+#ifdef __GNUC__\r
+#  if __GNUC__ >= 4\r
+#    define _aci_packed_ __attribute__((__packed__))\r
+#  else\r
+#    error "older g++ versions don't handle packed attribute in typedefs"\r
+#  endif\r
+#else\r
+#  define _aci_packed_\r
+#endif\r
+\r
+#include <stdint.h>\r
+#include <cstddef>\r
+#include <string.h>\r
+#include <unistd.h>\r
+\r
+/*\r
+ * Define a macro that compares the size of the first parameter to the integer\r
+ * value of the second parameter. If they do not match, a compile time error\r
+ * for negative array size occurs (even gnu chokes on negative array size).\r
+ *\r
+ * This compare is done by creating a typedef for an array. No variables are\r
+ * created and no memory is consumed with this check. The created type is\r
+ * used for checking only and is not for use by any other code. The value\r
+ * of 10 in this macro is arbitrary, it just needs to be a value larger\r
+ * than one to result in a positive number for the array size.\r
+ */\r
+#define ACI_ASSERT_SIZE(x,y) typedef char x ## _assert_size_t[-1+10*(sizeof(x) == (y))]\r
+\r
+/**\r
+ * @def ACI_VERSION\r
+ * @brief Current ACI protocol version. 0 means a device that is not yet released.\r
+ * A numer greater than 0 refers to a specific ACI version documented and released.\r
+ * The ACI consists of the ACI commands, ACI events and error codes.\r
+ */\r
+#define ACI_VERSION   (0x02)\r
+/**\r
+ * @def BTLE_DEVICE_ADDRESS_SIZE\r
+ * @brief Size in bytes of a Bluetooth Address\r
+ */\r
+#define BTLE_DEVICE_ADDRESS_SIZE                 (6)\r
+/**\r
+ * @def ACI_PACKET_MAX_LEN\r
+ * @brief Maximum length in bytes of a full ACI packet, including length prefix, opcode and payload\r
+ */\r
+#define ACI_PACKET_MAX_LEN                       (32)\r
+/**\r
+ * @def ACI_ECHO_DATA_MAX_LEN\r
+ * @brief Maximum length in bytes of the echo data portion\r
+ */\r
+#define ACI_ECHO_DATA_MAX_LEN                    (ACI_PACKET_MAX_LEN - 3)\r
+/**\r
+ * @def ACI_DEVICE_MAX_PIPES\r
+ * @brief Maximum number of ACI pipes\r
+ */\r
+#define ACI_DEVICE_MAX_PIPES                       (62)\r
+/**\r
+ * @def ACI_PIPE_TX_DATA_MAX_LEN\r
+ * @brief Maximum length in bytes of a transmission data pipe packet\r
+ */\r
+#define ACI_PIPE_TX_DATA_MAX_LEN                   (20)\r
+/**\r
+ * @def ACI_PIPE_RX_DATA_MAX_LEN\r
+ * @brief Maximum length in bytes of a reception data pipe packet\r
+ */\r
+#define ACI_PIPE_RX_DATA_MAX_LEN                   (22)\r
+/**\r
+ * @def ACI_GAP_DEVNAME_MAX_LEN\r
+ * @brief Maximum length in bytes of the GAP device name\r
+ */\r
+#define ACI_GAP_DEVNAME_MAX_LEN                 (20)\r
+/**\r
+ * @def ACI_AD_PACKET_MAX_LEN\r
+ * @brief Maximum length in bytes of an AD packet\r
+ */\r
+#define ACI_AD_PACKET_MAX_LEN                   (31)\r
+/**\r
+ * @def ACI_AD_PACKET_MAX_USER_LEN\r
+ * @brief Maximum usable length in bytes of an AD packet\r
+ */\r
+#define ACI_AD_PACKET_MAX_USER_LEN              (31 - 3)\r
+/**\r
+ * @def ACI_PIPE_INVALID\r
+ * @brief Invalid pipe number\r
+ */\r
+#define ACI_PIPE_INVALID                        (0xFF)\r
+\r
+/**\r
+ * @enum aci_pipe_store_t\r
+ * @brief Storage type identifiers: local and remote\r
+ */\r
+typedef enum\r
+{\r
+  ACI_STORE_INVALID = 0x0,\r
+  ACI_STORE_LOCAL= 0x01,\r
+  ACI_STORE_REMOTE= 0x02\r
+} _aci_packed_ aci_pipe_store_t;\r
+\r
+/**\r
+ * @enum aci_pipe_type_t\r
+ * @brief Pipe types\r
+ */\r
+typedef enum\r
+{\r
+  ACI_TX_BROADCAST = 0x0001,\r
+  ACI_TX           = 0x0002,\r
+  ACI_TX_ACK       = 0x0004,\r
+  ACI_RX           = 0x0008,\r
+  ACI_RX_ACK       = 0x0010,\r
+  ACI_TX_REQ       = 0x0020,\r
+  ACI_RX_REQ       = 0x0040,\r
+  ACI_SET          = 0x0080,\r
+  ACI_TX_SIGN      = 0x0100,\r
+  ACI_RX_SIGN      = 0x0200,\r
+  ACI_RX_ACK_AUTO  = 0x0400\r
+} _aci_packed_ aci_pipe_type_t;\r
+\r
+ACI_ASSERT_SIZE(aci_pipe_type_t, 2);\r
+\r
+/**\r
+ * @enum aci_bd_addr_type_t\r
+ * @brief Bluetooth Address types\r
+ */\r
+typedef enum\r
+{\r
+  ACI_BD_ADDR_TYPE_INVALID  = 0x00,\r
+  ACI_BD_ADDR_TYPE_PUBLIC  = 0x01,\r
+  ACI_BD_ADDR_TYPE_RANDOM_STATIC  = 0x02,\r
+  ACI_BD_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE  = 0x03,\r
+  ACI_BD_ADDR_TYPE_RANDOM_PRIVATE_UNRESOLVABLE  = 0x04\r
+} _aci_packed_ aci_bd_addr_type_t;\r
+\r
+/**\r
+ * @enum aci_device_output_power_t\r
+ * @brief Radio output power levels\r
+ */\r
+typedef enum\r
+{\r
+  ACI_DEVICE_OUTPUT_POWER_MINUS_18DBM = 0x00, /**< Output power set to -18dBm */\r
+  ACI_DEVICE_OUTPUT_POWER_MINUS_12DBM = 0x01, /**< Output power set to -12dBm */\r
+  ACI_DEVICE_OUTPUT_POWER_MINUS_6DBM  = 0x02, /**< Output power set to -6dBm  */\r
+  ACI_DEVICE_OUTPUT_POWER_0DBM  = 0x03  /**< Output power set to 0dBm   - DEFAULT*/\r
+} _aci_packed_ aci_device_output_power_t;\r
+\r
+/**\r
+ * @enum aci_device_operation_mode_t\r
+ * @brief Device operation modes\r
+ */\r
+typedef enum\r
+{\r
+  ACI_DEVICE_INVALID   =0x00,\r
+  ACI_DEVICE_TEST      =0x01,\r
+  ACI_DEVICE_SETUP     =0x02,\r
+  ACI_DEVICE_STANDBY   =0x03,\r
+  ACI_DEVICE_SLEEP     =0x04\r
+} _aci_packed_ aci_device_operation_mode_t;\r
+\r
+/**\r
+ * @enum aci_disconnect_reason_t\r
+ * @brief Reason enumeration for ACI_CMD_DISCONNECT\r
+ */\r
+typedef enum\r
+{\r
+  ACI_REASON_TERMINATE      =0x01, /**< Use this to disconnect (does a terminate request), you need to wait for the "disconnected" event */\r
+  ACI_REASON_BAD_TIMING     =0x02 /*<Use this to disconnect and inform the peer, that the timing on the link is not acceptable for the device, you need to wait for the "disconnected" event */\r
+} _aci_packed_ aci_disconnect_reason_t;\r
+\r
+/**\r
+ * @enum aci_test_mode_change_t\r
+ * @brief Device test mode control\r
+ */\r
+typedef enum\r
+{\r
+  ACI_TEST_MODE_DTM_UART    = 0x01,\r
+  ACI_TEST_MODE_DTM_ACI     = 0x02,\r
+  ACI_TEST_MODE_EXIT        = 0xFF\r
+\r
+} _aci_packed_ aci_test_mode_change_t;\r
+\r
+ACI_ASSERT_SIZE(aci_test_mode_change_t, 1);\r
+\r
+/**\r
+ * @enum aci_permissions_t\r
+ * @brief Data store permissions\r
+ */\r
+typedef enum\r
+{\r
+  ACI_PERMISSIONS_NONE               =0x00,\r
+  ACI_PERMISSIONS_LINK_AUTHENTICATED =0x01\r
+} _aci_packed_ aci_permissions_t;\r
+\r
+/**\r
+ * @def ACI_VS_UUID_128_MAX_COUNT\r
+ * @brief Maximum number of 128-bit Vendor Specific\r
+ *        UUIDs that can be set\r
+ */\r
+#define ACI_VS_UUID_128_MAX_COUNT  64 /** #0 reserved for invalid, #1 reservered for BT SIG and a maximum of 1024 bytes (16*64) */\r
+\r
+/**\r
+ * @struct aci_ll_conn_params_t\r
+ * @brief Link Layer Connection Parameters\r
+ */\r
+typedef struct\r
+{\r
+  uint16_t min_conn_interval;   /**< Minimum connection interval requested from peer */\r
+    #define ACI_PPCP_MIN_CONN_INTVL_NONE  0xFFFF\r
+    #define ACI_PPCP_MIN_CONN_INTVL_MIN   0x0006\r
+    #define ACI_PPCP_MIN_CONN_INTVL_MAX   0x0C80\r
+  uint16_t max_conn_interval;   /**< Maximum connection interval requested from peer */\r
+    #define ACI_PPCP_MAX_CONN_INTVL_NONE  0xFFFF\r
+    #define ACI_PPCP_MAX_CONN_INTVL_MIN   0x0006\r
+    #define ACI_PPCP_MAX_CONN_INTVL_MAX   0x0C80\r
+  uint16_t slave_latency;       /**< Connection interval latency requested from peer */\r
+    #define ACI_PPCP_SLAVE_LATENCY_MAX    0x03E8\r
+  uint16_t timeout_mult;        /**< Link supervisor timeout multiplier requested from peer */\r
+    #define ACI_PPCP_TIMEOUT_MULT_NONE    0xFFFF\r
+    #define ACI_PPCP_TIMEOUT_MULT_MIN     0x000A\r
+    #define ACI_PPCP_TIMEOUT_MULT_MAX     0x0C80\r
+} _aci_packed_ aci_ll_conn_params_t;\r
+\r
+/**\r
+ * @def aci_gap_ppcp_t\r
+ * @brief GAP Peripheral Preferred Connection Parameters\r
+ */\r
+#define aci_gap_ppcp_t aci_ll_conn_params_t\r
+\r
+/**\r
+ * @def ACI_AD_LOC_SVCUUID_16_MAX_COUNT\r
+ * @brief Maximum number of 16-bit UUIDs that can\r
+ *        be inserted in the Services tag of AD\r
+ */\r
+#define ACI_AD_LOC_SVCUUID_16_MAX_COUNT  5\r
+\r
+/**\r
+ * @def ACI_AD_LOC_SVCUUID_128_MAX_COUNT\r
+ * @brief Maximum number of 128-bit UUIDs that can\r
+ *        be inserted in the Services tag of AD\r
+ */\r
+#define ACI_AD_LOC_SVCUUID_128_MAX_COUNT  1\r
+\r
+/**\r
+ * @def ACI_AD_SOL_SVCUUID_16_MAX_COUNT\r
+ * @brief Maximum number of UUIDs that can\r
+ *        be inserted in the Solicited Services tag of AD\r
+ */\r
+#define ACI_AD_SOL_SVCUUID_16_MAX_COUNT  5\r
+\r
+/**\r
+ * @def ACI_AD_SOL_SVCUUID_128_MAX_COUNT\r
+ * @brief Maximum number of UUIDs that can\r
+ *        be inserted in the Solicited Services tag of AD\r
+ */\r
+#define ACI_AD_SOL_SVCUUID_128_MAX_COUNT  1\r
+\r
+/**\r
+ * @def ACI_SEC_ENCKEY_SIZE_MIN\r
+ * @brief Minimum encryption key size\r
+ */\r
+#define ACI_SEC_ENCKEY_SIZE_MIN        7\r
+/**\r
+ * @def ACI_SEC_ENCKEY_SIZE_MAX\r
+ * @brief Maximum encryption key size\r
+ */\r
+#define ACI_SEC_ENCKEY_SIZE_MAX        16\r
+/**\r
+ * @def ACI_CUSTOM_AD_TYPE_MAX_COUNT\r
+ * @brief Maximum number of custom ad types\r
+ */\r
+#define ACI_CUSTOM_AD_TYPE_MAX_COUNT 8\r
+/**\r
+ * @def ACI_CUSTOM_AD_TYPE_MAX_DATA_LENGTH\r
+ * @brief Maximum custom ad type data size\r
+ */\r
+#define ACI_CUSTOM_AD_TYPE_MAX_DATA_LENGTH 20\r
+\r
+/**\r
+ * @struct aci_tx_data_t\r
+ * @brief Generic ACI transmit data structure\r
+ */\r
+typedef struct\r
+{\r
+  uint8_t pipe_number;\r
+  uint8_t aci_data[ACI_PIPE_TX_DATA_MAX_LEN];\r
+} _aci_packed_ aci_tx_data_t;\r
+\r
+ACI_ASSERT_SIZE(aci_tx_data_t, ACI_PIPE_TX_DATA_MAX_LEN + 1);\r
+\r
+/**\r
+ * @struct aci_rx_data_t\r
+ * @brief Generic ACI receive data structure\r
+ */\r
+typedef struct\r
+{\r
+  uint8_t pipe_number;\r
+  uint8_t aci_data[ACI_PIPE_RX_DATA_MAX_LEN];\r
+} _aci_packed_ aci_rx_data_t;\r
+\r
+ACI_ASSERT_SIZE(aci_rx_data_t, ACI_PIPE_RX_DATA_MAX_LEN + 1);\r
+\r
+/**\r
+ * @enum aci_hw_error_t\r
+ * @brief Hardware Error codes\r
+ */\r
+typedef enum\r
+{\r
+  ACI_HW_ERROR_NONE     = 0x00,\r
+  ACI_HW_ERROR_FATAL    = 0x01\r
+} _aci_packed_ aci_hw_error_t;\r
+\r
+/**\r
+ * @enum aci_clock_accuracy_t\r
+ * @brief Bluetooth Low Energy Clock Accuracy\r
+ */\r
+typedef enum\r
+{\r
+  ACI_CLOCK_ACCURACY_500_PPM = 0x00,\r
+  ACI_CLOCK_ACCURACY_250_PPM = 0x01,\r
+  ACI_CLOCK_ACCURACY_150_PPM = 0x02,\r
+  ACI_CLOCK_ACCURACY_100_PPM = 0x03,\r
+  ACI_CLOCK_ACCURACY_75_PPM  = 0x04,\r
+  ACI_CLOCK_ACCURACY_50_PPM  = 0x05,\r
+  ACI_CLOCK_ACCURACY_30_PPM  = 0x06,\r
+  ACI_CLOCK_ACCURACY_20_PPM  = 0x07\r
+} _aci_packed_ aci_clock_accuracy_t;\r
+\r
+/**\r
+ * @enum aci_app_latency_mode_t\r
+ * @brief Application latency modes\r
+ */\r
+typedef enum\r
+{\r
+  ACI_APP_LATENCY_DISABLE = 0,\r
+  ACI_APP_LATENCY_ENABLE = 1\r
+} _aci_packed_ aci_app_latency_mode_t;\r
+\r
+/**\r
+ * @enum gatt_format_t\r
+ * @brief GATT format definitions\r
+ */\r
+typedef enum\r
+{\r
+  ACI_GATT_FORMAT_NONE        = 0x00, /**< No characteristic format available */\r
+  ACI_GATT_FORMAT_BOOLEAN     = 0x01, /**< Not Supported */\r
+  ACI_GATT_FORMAT_2BIT        = 0x02, /**< Not Supported */\r
+  ACI_GATT_FORMAT_NIBBLE      = 0x03, /**< Not Supported */\r
+  ACI_GATT_FORMAT_UINT8       = 0x04,\r
+  ACI_GATT_FORMAT_UINT12      = 0x05,\r
+  ACI_GATT_FORMAT_UINT16      = 0x06,\r
+  ACI_GATT_FORMAT_UINT24      = 0x07,\r
+  ACI_GATT_FORMAT_UINT32      = 0x08,\r
+  ACI_GATT_FORMAT_UINT48      = 0x09,\r
+  ACI_GATT_FORMAT_UINT64      = 0x0A,\r
+  ACI_GATT_FORMAT_UINT128     = 0x0B,\r
+  ACI_GATT_FORMAT_SINT8       = 0x0C,\r
+  ACI_GATT_FORMAT_SINT12      = 0x0D,\r
+  ACI_GATT_FORMAT_SINT16      = 0x0E,\r
+  ACI_GATT_FORMAT_SINT24      = 0x0F,\r
+  ACI_GATT_FORMAT_SINT32      = 0x10,\r
+  ACI_GATT_FORMAT_SINT48      = 0x11,\r
+  ACI_GATT_FORMAT_SINT64      = 0x12,\r
+  ACI_GATT_FORMAT_SINT128     = 0x13,\r
+  ACI_GATT_FORMAT_FLOAT32     = 0x14,\r
+  ACI_GATT_FORMAT_FLOAT64     = 0x15,\r
+  ACI_GATT_FORMAT_SFLOAT      = 0x16,\r
+  ACI_GATT_FORMAT_FLOAT       = 0x17,\r
+  ACI_GATT_FORMAT_DUINT16     = 0x18,\r
+  ACI_GATT_FORMAT_UTF8S       = 0x19,\r
+  ACI_GATT_FORMAT_UTF16S      = 0x1A,\r
+  ACI_GATT_FORMAT_STRUCT      = 0x1B\r
+} _aci_packed_ aci_gatt_format_t;\r
+\r
+/**\r
+ * @brief GATT Bluetooth namespace\r
+ */\r
+typedef enum\r
+{\r
+  ACI_GATT_NAMESPACE_INVALID  = 0x00,\r
+  ACI_GATT_NAMESPACE_BTSIG    = 0x01 /**< Bluetooth SIG */\r
+} _aci_packed_ aci_gatt_namespace_t;\r
+\r
+/**\r
+ * @brief Security key types\r
+ */\r
+typedef enum\r
+{\r
+  ACI_KEY_TYPE_INVALID  = 0x00,\r
+  ACI_KEY_TYPE_PASSKEY  = 0x01\r
+} _aci_packed_ aci_key_type_t;\r
+\r
+/**\r
+ * @enum aci_bond_status_code_t\r
+ * @brief Bond status code\r
+ */\r
+typedef enum\r
+{\r
+ /**\r
+  * Bonding succeeded\r
+  */\r
+  ACI_BOND_STATUS_SUCCESS                             = 0x00,\r
+ /**\r
+  * Bonding failed\r
+  */\r
+  ACI_BOND_STATUS_FAILED                              = 0x01,\r
+ /**\r
+  * Bonding error: Timeout can occur when link termination is unexpected or did not get connected OR SMP timer expired\r
+  */\r
+  ACI_BOND_STATUS_FAILED_TIMED_OUT                    = 0x02,\r
+ /**\r
+  * Bonding error: Passkey entry failed\r
+  */\r
+  ACI_BOND_STATUS_FAILED_PASSKEY_ENTRY_FAILED        = 0x81,\r
+ /**\r
+  * Bonding error: OOB unavailable\r
+  */\r
+  ACI_BOND_STATUS_FAILED_OOB_UNAVAILABLE             = 0x82,\r
+ /**\r
+  * Bonding error: Authentication request failed\r
+  */\r
+  ACI_BOND_STATUS_FAILED_AUTHENTICATION_REQ          = 0x83,\r
+ /**\r
+  * Bonding error: Confirm value failed\r
+  */\r
+  ACI_BOND_STATUS_FAILED_CONFIRM_VALUE               = 0x84,\r
+ /**\r
+  * Bonding error: Pairing unsupported\r
+  */\r
+  ACI_BOND_STATUS_FAILED_PAIRING_UNSUPPORTED         = 0x85,\r
+ /**\r
+  * Bonding error: Invalid encryption key size\r
+  */\r
+  ACI_BOND_STATUS_FAILED_ENCRYPTION_KEY_SIZE         = 0x86,\r
+ /**\r
+  * Bonding error: Unsupported SMP command\r
+  */\r
+  ACI_BOND_STATUS_FAILED_SMP_CMD_UNSUPPORTED         = 0x87,\r
+ /**\r
+  * Bonding error: Unspecified reason\r
+  */\r
+  ACI_BOND_STATUS_FAILED_UNSPECIFIED_REASON          = 0x88,\r
+ /**\r
+  * Bonding error: Too many attempts\r
+  */\r
+  ACI_BOND_STATUS_FAILED_REPEATED_ATTEMPTS           = 0x89,\r
+ /**\r
+  * Bonding error: Invalid parameters\r
+  */\r
+  ACI_BOND_STATUS_FAILED_INVALID_PARAMETERS          = 0x8A\r
+\r
+} _aci_packed_ aci_bond_status_code_t;\r
+\r
+ACI_ASSERT_SIZE(aci_bond_status_code_t, 1);\r
+\r
+/**\r
+ * @enum aci_bond_status_source_t\r
+ * @brief Source of a bond status code\r
+ */\r
+typedef enum\r
+{\r
+  ACI_BOND_STATUS_SOURCE_INVALID                  = 0x00,\r
+  ACI_BOND_STATUS_SOURCE_LOCAL                    = 0x01,\r
+  ACI_BOND_STATUS_SOURCE_REMOTE                   = 0x02\r
+\r
+} _aci_packed_ aci_bond_status_source_t;\r
+\r
+/**\r
+ * @enum aci_status_code_t\r
+ * @brief ACI status codes\r
+ */\r
+typedef enum\r
+{\r
+ /**\r
+  * Success\r
+  */\r
+  ACI_STATUS_SUCCESS                                        = 0x00,\r
+ /**\r
+  * Transaction continuation status\r
+  */\r
+  ACI_STATUS_TRANSACTION_CONTINUE                           = 0x01,\r
+ /**\r
+  * Transaction completed\r
+  */\r
+  ACI_STATUS_TRANSACTION_COMPLETE                           = 0x02,\r
+ /**\r
+  * Extended status, further checks needed\r
+  */\r
+  ACI_STATUS_EXTENDED                                       = 0x03,\r
+ /**\r
+  * Unknown error.\r
+  */\r
+  ACI_STATUS_ERROR_UNKNOWN                                  = 0x80,\r
+ /**\r
+  * Internal error.\r
+  */\r
+  ACI_STATUS_ERROR_INTERNAL                                 = 0x81,\r
+ /**\r
+  * Unknown command\r
+  */\r
+  ACI_STATUS_ERROR_CMD_UNKNOWN                              = 0x82,\r
+ /**\r
+  * Command invalid in the current device state\r
+  */\r
+  ACI_STATUS_ERROR_DEVICE_STATE_INVALID                     = 0x83,\r
+ /**\r
+  * Invalid length\r
+  */\r
+  ACI_STATUS_ERROR_INVALID_LENGTH                           = 0x84,\r
+ /**\r
+  * Invalid input parameters\r
+  */\r
+  ACI_STATUS_ERROR_INVALID_PARAMETER                        = 0x85,\r
+ /**\r
+  * Busy\r
+  */\r
+  ACI_STATUS_ERROR_BUSY                                     = 0x86,\r
+ /**\r
+  * Invalid data format or contents\r
+  */\r
+  ACI_STATUS_ERROR_INVALID_DATA                             = 0x87,\r
+ /**\r
+  * CRC mismatch\r
+  */\r
+  ACI_STATUS_ERROR_CRC_MISMATCH                             = 0x88,\r
+ /**\r
+  * Unsupported setup format\r
+  */\r
+  ACI_STATUS_ERROR_UNSUPPORTED_SETUP_FORMAT                 = 0x89,\r
+ /**\r
+  * Invalid sequence number during a write dynamic data sequence\r
+  */\r
+  ACI_STATUS_ERROR_INVALID_SEQ_NO                           = 0x8A,\r
+ /**\r
+  * Setup data is locked and cannot be modified\r
+  */\r
+  ACI_STATUS_ERROR_SETUP_LOCKED                             = 0x8B,\r
+ /**\r
+  * Setup error due to lock verification failure\r
+  */\r
+  ACI_STATUS_ERROR_LOCK_FAILED                              = 0x8C,\r
+ /**\r
+  * Bond required: Local Pipes need bonded/trusted peer\r
+  */\r
+  ACI_STATUS_ERROR_BOND_REQUIRED                            = 0x8D,\r
+ /**\r
+  * Command rejected as a transaction is still pending\r
+  */\r
+  ACI_STATUS_ERROR_REJECTED                                 = 0x8E,\r
+  /**\r
+  * Pipe Error Event : Data size exceeds size specified for pipe : Transmit failed\r
+  */\r
+  ACI_STATUS_ERROR_DATA_SIZE                                = 0x8F,\r
+ /**\r
+  * Pipe Error Event : Invalid pipe\r
+  */\r
+  ACI_STATUS_ERROR_PIPE_INVALID                             = 0x90,\r
+ /**\r
+  * Pipe Error Event : Credit not available\r
+  */\r
+  ACI_STATUS_ERROR_CREDIT_NOT_AVAILABLE                     = 0x91,\r
+ /**\r
+  * Pipe Error Event : Peer device has sent an error on an pipe operation on the remote characteristic\r
+  */\r
+  ACI_STATUS_ERROR_PEER_ATT_ERROR                           = 0x92,\r
+ /**\r
+  * Connection was not established before the BTLE advertising was stopped\r
+  */\r
+  ACI_STATUS_ERROR_ADVT_TIMEOUT                             = 0x93,\r
+ /**\r
+  * Peer has triggered a Security Manager Protocol Error\r
+  */\r
+  ACI_STATUS_ERROR_PEER_SMP_ERROR                           = 0x94,\r
+ /**\r
+  * Pipe Error Event : Pipe type invalid for the selected operation\r
+  */\r
+  ACI_STATUS_ERROR_PIPE_TYPE_INVALID                        = 0x95,\r
+ /**\r
+  * Pipe Error Event : Pipe state invalid for the selected operation\r
+  */\r
+  ACI_STATUS_ERROR_PIPE_STATE_INVALID                       = 0x96,\r
+ /**\r
+  * Invalid key size provided\r
+  */\r
+  ACI_STATUS_ERROR_INVALID_KEY_SIZE                         = 0x97,\r
+ /**\r
+  * Invalid key data provided\r
+  */\r
+  ACI_STATUS_ERROR_INVALID_KEY_DATA                         = 0x98,\r
+ /**\r
+  * Reserved range start\r
+  */\r
+  ACI_STATUS_RESERVED_START                                 = 0xF0,\r
+ /**\r
+  * Reserved range end\r
+  */\r
+  ACI_STATUS_RESERVED_END                                   = 0xFF\r
+\r
+} _aci_packed_ aci_status_code_t;\r
+\r
+ACI_ASSERT_SIZE(aci_status_code_t, 1);\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+#endif // ACI_H__\r
diff --git a/src/nrf8001/aci_cmds.h b/src/nrf8001/aci_cmds.h
new file mode 100644 (file)
index 0000000..4ce75e1
--- /dev/null
@@ -0,0 +1,435 @@
+/* Copyright (c) 2014, Nordic Semiconductor ASA\r
+ *\r
+ * Permission is hereby granted, free of charge, to any person obtaining a copy\r
+ * of this software and associated documentation files (the "Software"), to deal\r
+ * in the Software without restriction, including without limitation the rights\r
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+ * copies of the Software, and to permit persons to whom the Software is\r
+ * furnished to do so, subject to the following conditions:\r
+ *\r
+ * The above copyright notice and this permission notice shall be included in all\r
+ * copies or substantial portions of the Software.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ */\r
+\r
+/**\r
+ * @file\r
+ *\r
+ * @ingroup aci\r
+ *\r
+ * @brief Definitions for the ACI (Application Control Interface) commands\r
+ * @remarks\r
+ *\r
+ */\r
+\r
+#ifndef ACI_CMDS_H__\r
+#define ACI_CMDS_H__\r
+\r
+#include "aci.h"\r
+\r
+/**\r
+ * @enum aci_cmd_opcode_t\r
+ * @brief ACI command opcodes\r
+ */\r
+typedef enum\r
+{\r
+ /**\r
+  * Enter test mode\r
+  */\r
+  ACI_CMD_TEST                    = 0x01,\r
+ /**\r
+  * Echo (loopback) test command\r
+  */\r
+  ACI_CMD_ECHO                    = 0x02,\r
+ /**\r
+  * Send a BTLE DTM command to the radio\r
+  */\r
+  ACI_CMD_DTM_CMD                 = 0x03,\r
+  /**\r
+  * Put the device to sleep\r
+  */\r
+  ACI_CMD_SLEEP                   = 0x04,\r
+ /**\r
+  * Wakeup the device from deep sleep\r
+  */\r
+  ACI_CMD_WAKEUP                  = 0x05,\r
+ /**\r
+  * Replace the contents of the internal database with\r
+  * user provided data\r
+  */\r
+  ACI_CMD_SETUP                   = 0x06,\r
+ /**\r
+  * Read the portions of memory required to be restored after a power cycle\r
+  */\r
+  ACI_CMD_READ_DYNAMIC_DATA       = 0x07,\r
+ /**\r
+  * Write back the data retrieved using ACI_CMD_READ_DYNAMIC_DATA\r
+  */\r
+  ACI_CMD_WRITE_DYNAMIC_DATA      = 0x08,\r
+  /**\r
+  * Retrieve the device's version information\r
+  */\r
+  ACI_CMD_GET_DEVICE_VERSION      = 0x09,\r
+ /**\r
+  * Request the Bluetooth address and its type\r
+  */\r
+  ACI_CMD_GET_DEVICE_ADDRESS      = 0x0A,\r
+  /**\r
+  * Request the battery level measured by nRF8001\r
+  */\r
+  ACI_CMD_GET_BATTERY_LEVEL       = 0x0B,\r
+ /**\r
+  * Request the temperature value measured by nRF8001\r
+  */\r
+  ACI_CMD_GET_TEMPERATURE         = 0x0C,\r
+ /**\r
+  * Write to the local Attribute Database\r
+  */\r
+  ACI_CMD_SET_LOCAL_DATA          = 0x0D,\r
+ /**\r
+  * Reset the baseband and radio and go back to idle\r
+  */\r
+  ACI_CMD_RADIO_RESET          = 0x0E,\r
+ /**\r
+  * Start advertising and wait for a master connection\r
+  */\r
+  ACI_CMD_CONNECT                 = 0x0F,\r
+ /**\r
+  * Start advertising and wait for a master connection\r
+  */\r
+  ACI_CMD_BOND                    = 0x10,\r
+ /**\r
+  * Start advertising and wait for a master connection\r
+  */\r
+  ACI_CMD_DISCONNECT              = 0x11,\r
+ /**\r
+  * Throttles the Radio transmit power\r
+  */\r
+  ACI_CMD_SET_TX_POWER            = 0x12,\r
+ /**\r
+  * Trigger a connection parameter update\r
+  */\r
+  ACI_CMD_CHANGE_TIMING           = 0x13,\r
+ /**\r
+  * Open a remote pipe for data reception\r
+  */\r
+  ACI_CMD_OPEN_REMOTE_PIPE        = 0x14,\r
+ /**\r
+  * Transmit data over an open pipe\r
+  */\r
+  ACI_CMD_SEND_DATA               = 0x15,\r
+ /**\r
+  * Send an acknowledgment of received data\r
+  */\r
+  ACI_CMD_SEND_DATA_ACK           = 0x16,\r
+ /**\r
+  * Request data over an open pipe\r
+  */\r
+  ACI_CMD_REQUEST_DATA            = 0x17,\r
+ /**\r
+  * NACK a data reception\r
+  */\r
+  ACI_CMD_SEND_DATA_NACK          = 0x18,\r
+ /**\r
+  * Set application latency\r
+  */\r
+  ACI_CMD_SET_APP_LATENCY         = 0x19,\r
+ /**\r
+  * Set a security key\r
+  */\r
+  ACI_CMD_SET_KEY                 = 0x1A,\r
+ /**\r
+  * Open Advertising Pipes\r
+  */\r
+  ACI_CMD_OPEN_ADV_PIPE           = 0x1B,\r
+ /**\r
+  * Start non-connectable advertising\r
+  */\r
+  ACI_CMD_BROADCAST               = 0x1C,\r
+ /**\r
+  * Start a security request in bonding mode\r
+  */\r
+  ACI_CMD_BOND_SECURITY_REQUEST   = 0x1D,\r
+ /**\r
+  * Start Directed advertising towards a Bonded Peer\r
+  */\r
+  ACI_CMD_CONNECT_DIRECT          = 0x1E,\r
+ /**\r
+  * Close a previously opened remote pipe\r
+  */\r
+  ACI_CMD_CLOSE_REMOTE_PIPE       = 0x1F,\r
+ /**\r
+  * Invalid ACI command opcode\r
+  */\r
+  ACI_CMD_INVALID                 = 0xFF\r
+\r
+} _aci_packed_ aci_cmd_opcode_t;\r
+\r
+ACI_ASSERT_SIZE(aci_cmd_opcode_t, 1);\r
+\r
+/**\r
+ * @struct aci_cmd_params_test_t\r
+ * @brief  Structure for the ACI_CMD_TEST ACI command parameters\r
+ */\r
+typedef struct\r
+{\r
+  aci_test_mode_change_t test_mode_change; /**< enum aci_test_mode_change_t */\r
+} _aci_packed_ aci_cmd_params_test_t;\r
+\r
+ACI_ASSERT_SIZE(aci_cmd_params_test_t, 1);\r
+\r
+/**\r
+ * @struct aci_cmd_params_echo_t\r
+ * @brief  Structure for the ACI_CMD_ECHO ACI command parameters\r
+ */\r
+typedef struct\r
+{\r
+  uint8_t echo_data[ACI_ECHO_DATA_MAX_LEN];\r
+} _aci_packed_ aci_cmd_params_echo_t;\r
+\r
+ACI_ASSERT_SIZE(aci_cmd_params_echo_t, ACI_ECHO_DATA_MAX_LEN);\r
+\r
+/**\r
+ * @struct aci_cmd_params_dtm_cmd_t\r
+ * @brief  Structure for the ACI_CMD_DTM_CMD ACI command parameters\r
+ */\r
+typedef struct\r
+{\r
+  uint8_t                 cmd_msb;\r
+  uint8_t                 cmd_lsb;\r
+} _aci_packed_ aci_cmd_params_dtm_cmd_t;\r
+\r
+/**\r
+ * @struct aci_cmd_params_setup_t\r
+ * @brief  Structure for the ACI_CMD_SETUP ACI command parameters\r
+ */\r
+typedef struct\r
+{\r
+  uint8_t                 setup_data[1];\r
+} _aci_packed_ aci_cmd_params_setup_t;\r
+\r
+ACI_ASSERT_SIZE(aci_cmd_params_setup_t, 1);\r
+\r
+/**\r
+ * @struct aci_cmd_params_write_dynamic_data_t\r
+ * @brief  Structure for the ACI_CMD_WRITE_DYNAMIC_DATA ACI command parameters\r
+ * @note Dynamic data chunk size in this command is defined to go up to ACI_PACKET_MAX_LEN - 3\r
+ */\r
+typedef struct\r
+{\r
+  uint8_t                 seq_no;\r
+  uint8_t                 dynamic_data[1];\r
+} _aci_packed_ aci_cmd_params_write_dynamic_data_t;\r
+\r
+/**\r
+ * @define aci_cmd_params_set_local_data_t\r
+ * @brief  Structure for the ACI_CMD_SET_LOCAL_DATA ACI command parameters\r
+ */\r
+typedef struct\r
+{\r
+  aci_tx_data_t tx_data;\r
+} _aci_packed_ aci_cmd_params_set_local_data_t;\r
+\r
+/**\r
+ * @struct aci_cmd_params_connect_t\r
+ * @brief  Structure for the ACI_CMD_CONNECT ACI command parameters\r
+ */\r
+typedef struct\r
+{\r
+  uint16_t        timeout;  /**< 0x0000 (no timeout) to 0x3FFF */\r
+  uint16_t        adv_interval;     /**< 16 bits of advertising interval for general discovery */\r
+} _aci_packed_ aci_cmd_params_connect_t;\r
+\r
+ACI_ASSERT_SIZE(aci_cmd_params_connect_t, 4);\r
+\r
+/**\r
+ * @define aci_cmd_params_bond_t\r
+ * @brief  Structure for the ACI_CMD_BOND ACI command parameters\r
+ */\r
+typedef struct\r
+{\r
+  uint16_t        timeout;  /**< 0x0000 (no timeout) to 0x3FFF */\r
+  uint16_t        adv_interval;     /**< 16 bits of advertising interval for general discovery */\r
+} _aci_packed_ aci_cmd_params_bond_t;\r
+\r
+ACI_ASSERT_SIZE(aci_cmd_params_bond_t, 4);\r
+\r
+/**\r
+ * @struct aci_cmd_params_disconnect_t\r
+ * @brief  Structure for the ACI_CMD_DISCONNECT ACI command parameters\r
+ */\r
+typedef struct\r
+{\r
+  aci_disconnect_reason_t         reason; /**< enum aci_disconnect_reason_t */\r
+} _aci_packed_ aci_cmd_params_disconnect_t;\r
+\r
+ACI_ASSERT_SIZE(aci_cmd_params_disconnect_t, 1);\r
+\r
+/**\r
+ * @struct aci_cmd_params_set_tx_power_t\r
+ * @brief  Structure for the ACI_CMD_SET_TX_POWER ACI command parameters\r
+ */\r
+typedef struct\r
+{\r
+  aci_device_output_power_t   device_power; /**< enum aci_device_output_power_t */\r
+} _aci_packed_ aci_cmd_params_set_tx_power_t;\r
+\r
+ACI_ASSERT_SIZE(aci_cmd_params_set_tx_power_t, 1);\r
+/**\r
+ * @struct aci_cmd_params_change_timing_t\r
+ * @brief  Structure for the ACI_CMD_CHANGE_TIMING ACI command parameters\r
+ */\r
+typedef struct\r
+{\r
+  aci_ll_conn_params_t    conn_params;\r
+} _aci_packed_ aci_cmd_params_change_timing_t;\r
+\r
+ACI_ASSERT_SIZE(aci_cmd_params_change_timing_t, 8);\r
+\r
+/**\r
+ * @struct aci_cmd_params_open_remote_pipe_t\r
+ * @brief  Structure for the ACI_CMD_OPEN_REMOTE_PIPE ACI command parameters\r
+ */\r
+typedef struct\r
+{\r
+  uint8_t pipe_number;\r
+} _aci_packed_ aci_cmd_params_open_remote_pipe_t;\r
+\r
+/**\r
+ * @struct aci_cmd_params_send_data_t\r
+ * @brief  Structure for the ACI_CMD_SEND_DATA ACI command parameters\r
+ */\r
+typedef struct\r
+{\r
+  aci_tx_data_t tx_data;\r
+} _aci_packed_ aci_cmd_params_send_data_t;\r
+\r
+/**\r
+ * @define aci_cmd_params_send_data_ack_t\r
+ * @brief  Structure for the ACI_CMD_SEND_DATA_ACK ACI command parameters\r
+ */\r
+typedef struct\r
+{\r
+  uint8_t pipe_number;\r
+} _aci_packed_ aci_cmd_params_send_data_ack_t;\r
+\r
+/**\r
+ * @struct aci_cmd_params_send_data_t\r
+ * @brief  Structure for the ACI_CMD_SEND_DATA ACI command parameters\r
+ */\r
+typedef struct\r
+{\r
+  uint8_t pipe_number;\r
+} _aci_packed_ aci_cmd_params_request_data_t;\r
+\r
+/**\r
+ * @define aci_cmd_params_send_data_nack_t\r
+ * @brief  Structure for the ACI_CMD_SEND_DATA_NACK ACI command parameters\r
+ */\r
+typedef struct\r
+{\r
+  uint8_t pipe_number;\r
+  uint8_t error_code;\r
+} _aci_packed_ aci_cmd_params_send_data_nack_t;\r
+\r
+ACI_ASSERT_SIZE(aci_cmd_params_send_data_nack_t, 2);\r
+\r
+/**\r
+ * @define aci_cmd_params_set_app_latency_t\r
+ * @brief  Structure for the ACI_CMD_SET_APP_LATENCY ACI command parameters\r
+ */\r
+typedef struct\r
+{\r
+  aci_app_latency_mode_t mode;\r
+  uint16_t latency;\r
+} _aci_packed_ aci_cmd_params_set_app_latency_t;\r
+\r
+ACI_ASSERT_SIZE(aci_cmd_params_set_app_latency_t, 3);\r
+/**\r
+ * @define aci_cmd_params_set_key_t\r
+ * @brief  Structure for the ACI_CMD_SET_KEY ACI command parameters\r
+ */\r
+typedef struct\r
+{\r
+  aci_key_type_t key_type;\r
+  union\r
+  {\r
+    uint8_t passkey[6];\r
+    uint8_t oob_key[16];\r
+  } key;\r
+} _aci_packed_ aci_cmd_params_set_key_t;\r
+\r
+ACI_ASSERT_SIZE(aci_cmd_params_set_key_t, 17);\r
+/**\r
+ * @define aci_cmd_params_open_adv_pipe_t\r
+ * @brief  Structure for the ACI_CMD_OPEN_ADV_PIPE ACI command parameters\r
+ */\r
+typedef struct\r
+{\r
+  uint8_t pipes[8];\r
+} _aci_packed_ aci_cmd_params_open_adv_pipe_t;\r
+\r
+/**\r
+ * @define aci_cmd_params_broadcast_t\r
+ * @brief  Structure for the ACI_CMD_BROADCAST ACI command parameters\r
+ */\r
+typedef struct\r
+{\r
+  uint16_t        timeout;  /**< 0x0000 (no timeout) to 0x3FFF */\r
+  uint16_t        adv_interval;     /**< 16 bits of advertising interval for general discovery */\r
+} _aci_packed_ aci_cmd_params_broadcast_t;\r
+\r
+/**\r
+ * @struct aci_cmd_params_close_remote_pipe_t\r
+ * @brief  Structure for the ACI_CMD_CLOSE_REMOTE_PIPE ACI command parameters\r
+ */\r
+typedef struct\r
+{\r
+  uint8_t pipe_number;\r
+} _aci_packed_ aci_cmd_params_close_remote_pipe_t;\r
+\r
+/**\r
+ * @struct aci_cmd_t\r
+ * @brief  Encapsulates a generic ACI command\r
+ */\r
+typedef struct\r
+{\r
+  uint8_t len;        /**< Length of the ACI command */\r
+  aci_cmd_opcode_t cmd_opcode; /**< enum aci_cmd_opcode_t -> Opcode of the ACI command */\r
+  union\r
+  {\r
+    aci_cmd_params_test_t                       test;\r
+    aci_cmd_params_echo_t                       echo;\r
+    aci_cmd_params_dtm_cmd_t                    dtm_cmd;\r
+    aci_cmd_params_setup_t                      setup;\r
+    aci_cmd_params_write_dynamic_data_t         write_dynamic_data;\r
+    aci_cmd_params_set_local_data_t             set_local_data;\r
+    aci_cmd_params_connect_t                    connect;\r
+    aci_cmd_params_bond_t                       bond;\r
+    aci_cmd_params_disconnect_t                 disconnect;\r
+    aci_cmd_params_set_tx_power_t               set_tx_power;\r
+    aci_cmd_params_change_timing_t              change_timing;\r
+    aci_cmd_params_open_remote_pipe_t           open_remote_pipe;\r
+    aci_cmd_params_send_data_t                  send_data;\r
+    aci_cmd_params_send_data_ack_t              send_data_ack;\r
+    aci_cmd_params_request_data_t               request_data;\r
+    aci_cmd_params_send_data_nack_t             send_data_nack;\r
+    aci_cmd_params_set_app_latency_t            set_app_latency;\r
+    aci_cmd_params_set_key_t                    set_key;\r
+    aci_cmd_params_open_adv_pipe_t              open_adv_pipe;\r
+    aci_cmd_params_broadcast_t                  broadcast;\r
+    aci_cmd_params_close_remote_pipe_t          close_remote_pipe;\r
+\r
+  } params;\r
+} _aci_packed_ aci_cmd_t;\r
+\r
+#endif // ACI_CMDS_H__\r
+\r
+\r
diff --git a/src/nrf8001/aci_evts.h b/src/nrf8001/aci_evts.h
new file mode 100644 (file)
index 0000000..0a577f5
--- /dev/null
@@ -0,0 +1,397 @@
+/* Copyright (c) 2014, Nordic Semiconductor ASA\r
+ *\r
+ * Permission is hereby granted, free of charge, to any person obtaining a copy\r
+ * of this software and associated documentation files (the "Software"), to deal\r
+ * in the Software without restriction, including without limitation the rights\r
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+ * copies of the Software, and to permit persons to whom the Software is\r
+ * furnished to do so, subject to the following conditions:\r
+ *\r
+ * The above copyright notice and this permission notice shall be included in all\r
+ * copies or substantial portions of the Software.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ */\r
+\r
+/**\r
+ * @file\r
+ *\r
+ * @ingroup aci\r
+ *\r
+ * @brief Definitions for the ACI (Application Control Interface) events\r
+ */\r
+\r
+#ifndef ACI_EVTS_H__\r
+#define ACI_EVTS_H__\r
+\r
+#include "aci.h"\r
+\r
+/**\r
+ * @enum aci_evt_opcode_t\r
+ * @brief ACI event opcodes\r
+ */\r
+typedef enum\r
+{\r
+ /**\r
+  * Invalid event code\r
+  */\r
+  ACI_EVT_INVALID                     = 0x00,\r
+ /**\r
+  * Sent every time the device starts\r
+  */\r
+  ACI_EVT_DEVICE_STARTED              = 0x81,\r
+ /**\r
+  * Mirrors the ACI_CMD_ECHO\r
+  */\r
+  ACI_EVT_ECHO                        = 0x82,\r
+ /**\r
+  * Asynchronous hardware error event\r
+  */\r
+  ACI_EVT_HW_ERROR                  = 0x83,\r
+ /**\r
+  * Event opcode used as a event response for all commands\r
+  */\r
+  ACI_EVT_CMD_RSP                     = 0x84,\r
+ /**\r
+  * Link connected\r
+  */\r
+  ACI_EVT_CONNECTED                   = 0x85,\r
+ /**\r
+  * Link disconnected\r
+  */\r
+  ACI_EVT_DISCONNECTED                = 0x86,\r
+ /**\r
+  * Bond completion result\r
+  */\r
+  ACI_EVT_BOND_STATUS                 = 0x87,\r
+  /**\r
+  * Pipe bitmap for available pipes\r
+  */\r
+  ACI_EVT_PIPE_STATUS             = 0x88,\r
+ /**\r
+  * Sent to the application when the radio enters a connected state\r
+  * or when the timing of the radio connection changes\r
+  */\r
+  ACI_EVT_TIMING                      = 0x89,\r
+ /**\r
+  * Notification to the application that transmit credits are\r
+  * available\r
+  */\r
+  ACI_EVT_DATA_CREDIT                 = 0x8A,\r
+ /**\r
+  * Data acknowledgement event\r
+  */\r
+  ACI_EVT_DATA_ACK                    = 0x8B,\r
+ /**\r
+  * Data received notification event\r
+  */\r
+  ACI_EVT_DATA_RECEIVED               = 0x8C,\r
+ /**\r
+  * Error notification event\r
+  */\r
+  ACI_EVT_PIPE_ERROR                  = 0x8D,\r
+ /**\r
+  * Display Passkey Event\r
+  */\r
+  ACI_EVT_DISPLAY_PASSKEY             = 0x8E,\r
+ /**\r
+  * Security Key request\r
+  */\r
+  ACI_EVT_KEY_REQUEST                 = 0x8F\r
+\r
+} _aci_packed_ aci_evt_opcode_t;\r
+\r
+ACI_ASSERT_SIZE(aci_evt_opcode_t, 1);\r
+\r
+/**\r
+ * @struct aci_evt_params_device_started_t\r
+ * @brief Structure for the ACI_EVT_DEVICE_STARTED event return parameters\r
+ */\r
+typedef struct\r
+{\r
+  aci_device_operation_mode_t device_mode; /**< Mode in which the device is being started */\r
+  aci_hw_error_t hw_error;  /**< Hardware Error if available for the start */\r
+  uint8_t credit_available; /**< Flow control credit available for this specific FW build */\r
+} _aci_packed_ aci_evt_params_device_started_t;\r
+\r
+ACI_ASSERT_SIZE(aci_evt_params_device_started_t, 3);\r
+\r
+/**\r
+ * @struct aci_evt_params_hw_error_t\r
+ * @brief Structure for the ACI_EVT_HW_ERROR event return parameters\r
+ */\r
+typedef struct\r
+{\r
+  uint16_t line_num;\r
+  uint8_t file_name[20];\r
+} _aci_packed_ aci_evt_params_hw_error_t;\r
+\r
+ACI_ASSERT_SIZE(aci_evt_params_hw_error_t, 22);\r
+\r
+/**\r
+ * @struct aci_evt_cmd_rsp_params_dtm_cmd_t\r
+ * @brief Structure for the ACI_EVT_CMD_RSP event with opcode=ACI_CMD_DTM_CMD event return parameters\r
+ */\r
+typedef struct\r
+{\r
+  uint8_t  evt_msb;\r
+  uint8_t  evt_lsb;\r
+} _aci_packed_ aci_evt_cmd_rsp_params_dtm_cmd_t;\r
+\r
+/**\r
+ * @struct aci_evt_cmd_rsp_read_dynamic_data_t\r
+ * @brief Structure for the ACI_EVT_CMD_RSP event with opcode=ACI_CMD_READ_DYNAMIC_DATA event return parameters\r
+ * @note Dynamic data chunk size in this event is defined to go up to ACI_PACKET_MAX_LEN - 5\r
+ */\r
+typedef struct\r
+{\r
+  uint8_t seq_no;\r
+  uint8_t dynamic_data[1];\r
+} _aci_packed_ aci_evt_cmd_rsp_read_dynamic_data_t;\r
+\r
+/**\r
+ * @struct aci_evt_cmd_rsp_params_get_device_version_t\r
+ * @brief Structure for the ACI_EVT_CMD_RSP event with opcode=ACI_CMD_GET_DEVICE_VERSION event return parameters\r
+ */\r
+typedef struct\r
+{\r
+  uint16_t  configuration_id;\r
+  uint8_t   aci_version;\r
+  uint8_t   setup_format;\r
+  uint32_t  setup_id;\r
+  uint8_t   setup_status;\r
+} _aci_packed_ aci_evt_cmd_rsp_params_get_device_version_t;\r
+\r
+ACI_ASSERT_SIZE(aci_evt_cmd_rsp_params_get_device_version_t, 9);\r
+\r
+/**\r
+ * @struct aci_evt_cmd_rsp_params_get_device_address_t\r
+ * @brief Structure for the ACI_EVT_CMD_RSP event with opcode=ACI_CMD_GET_DEVICE_ADDRESS event return parameters\r
+ */\r
+typedef struct\r
+{\r
+  uint8_t  bd_addr_own[BTLE_DEVICE_ADDRESS_SIZE];\r
+  aci_bd_addr_type_t bd_addr_type;\r
+} _aci_packed_ aci_evt_cmd_rsp_params_get_device_address_t;\r
+\r
+ACI_ASSERT_SIZE(aci_evt_cmd_rsp_params_get_device_address_t, BTLE_DEVICE_ADDRESS_SIZE + 1);\r
+\r
+/**\r
+ * @struct aci_evt_cmd_rsp_params_get_battery_level_t\r
+ * @brief Structure for the ACI_EVT_CMD_RSP event with opcode=ACI_CMD_GET_BATTERY_LEVEL event return parameters\r
+ */\r
+typedef struct\r
+{\r
+  uint16_t battery_level;\r
+} _aci_packed_ aci_evt_cmd_rsp_params_get_battery_level_t;\r
+\r
+/**\r
+ * @struct aci_evt_cmd_rsp_params_get_temperature_t\r
+ * @brief Structure for the ACI_EVT_CMD_RSP event with opcode=ACI_CMD_GET_TEMPERATURE event return parameters\r
+ */\r
+typedef struct\r
+{\r
+  int16_t temperature_value;\r
+} _aci_packed_ aci_evt_cmd_rsp_params_get_temperature_t;\r
+\r
+/**\r
+ * @struct aci_evt_params_cmd_rsp_t\r
+ * @brief Structure for the ACI_EVT_CMD_RSP event return parameters\r
+ */\r
+typedef struct\r
+{\r
+  aci_cmd_opcode_t cmd_opcode; /**< Command opcode for which the event response is being sent */\r
+  aci_status_code_t cmd_status; /**< Status of the command that was sent. Used in the context of the command. */\r
+  union\r
+  {\r
+    aci_evt_cmd_rsp_params_dtm_cmd_t dtm_cmd;\r
+    aci_evt_cmd_rsp_read_dynamic_data_t read_dynamic_data;\r
+    aci_evt_cmd_rsp_params_get_device_version_t get_device_version;\r
+    aci_evt_cmd_rsp_params_get_device_address_t get_device_address;\r
+    aci_evt_cmd_rsp_params_get_battery_level_t  get_battery_level;\r
+    aci_evt_cmd_rsp_params_get_temperature_t    get_temperature;\r
+    uint8_t                                     padding[29];\r
+  } params;\r
+} _aci_packed_ aci_evt_params_cmd_rsp_t;\r
+\r
+ACI_ASSERT_SIZE(aci_evt_params_cmd_rsp_t, 31);\r
+\r
+/**\r
+ * @struct aci_evt_params_connected_t\r
+ * @brief Structure for the ACI_EVT_CONNECTED event return parameters\r
+ */\r
+typedef struct\r
+{\r
+  aci_bd_addr_type_t dev_addr_type;\r
+  uint8_t  dev_addr[BTLE_DEVICE_ADDRESS_SIZE];\r
+  uint16_t conn_rf_interval;  /**< rf_interval = conn_rf_interval * 1.25 ms Range:0x0006 to 0x0C80 */\r
+  uint16_t conn_slave_rf_latency; /**< Number of RF events the slave can skip */\r
+  uint16_t conn_rf_timeout; /**< Timeout as a multiple of 10ms i.e timeout = conn_rf_timeout * 10ms Range: 0x000A to 0x0C80 */\r
+  aci_clock_accuracy_t master_clock_accuracy; /**< Clock accuracy of Bluetooth master: Enumerated list of values from 500 ppm to 20 ppm */\r
+} _aci_packed_ aci_evt_params_connected_t;\r
+\r
+ACI_ASSERT_SIZE(aci_evt_params_connected_t, 14);\r
+\r
+/**\r
+ * @struct aci_evt_params_disconnected_t\r
+ * @brief Structure for the ACI_EVT_DISCONNECTED event return parameters\r
+ */\r
+typedef struct\r
+{\r
+  aci_status_code_t   aci_status;\r
+  uint8_t btle_status;\r
+} _aci_packed_ aci_evt_params_disconnected_t;\r
+\r
+ACI_ASSERT_SIZE(aci_evt_params_disconnected_t, 2);\r
+\r
+/**\r
+ * @struct aci_evt_params_bond_status_t\r
+ * @brief Structure for the ACI_EVT_BOND_STATUS event return parameters\r
+ */\r
+typedef struct\r
+{\r
+  aci_bond_status_code_t status_code;\r
+  aci_bond_status_source_t status_source;\r
+  uint8_t secmode1_bitmap;\r
+  uint8_t secmode2_bitmap;\r
+  uint8_t keys_exchanged_slave;\r
+  uint8_t keys_exchanged_master;\r
+} _aci_packed_ aci_evt_params_bond_status_t;\r
+\r
+ACI_ASSERT_SIZE(aci_evt_params_bond_status_t, 6);\r
+\r
+/**\r
+ * @struct aci_evt_params_pipe_status_t\r
+ * @brief Structure for the ACI_EVT_PIPE_STATUS event return parameters\r
+ */\r
+typedef struct\r
+{\r
+  uint8_t  pipes_open_bitmap[8];\r
+  uint8_t  pipes_closed_bitmap[8];\r
+} _aci_packed_ aci_evt_params_pipe_status_t;\r
+\r
+ACI_ASSERT_SIZE(aci_evt_params_pipe_status_t, 16);\r
+\r
+/**\r
+ * @struct aci_evt_params_timing_t\r
+ * @brief Structure for the ACI_EVT_TIMING event return parameters\r
+ */\r
+typedef struct\r
+{\r
+  uint16_t conn_rf_interval;  /**< rf_interval = conn_rf_interval * 1.25 ms Range:0x0006 to 0x0C80 */\r
+  uint16_t conn_slave_rf_latency; /**< Number of RF events the slave can skip */\r
+  uint16_t conn_rf_timeout; /**< Timeout as a multiple of 10ms i.e timeout = conn_rf_timeout * 10ms Range: 0x000A to 0x0C80 */\r
+} _aci_packed_ aci_evt_params_timing_t;\r
+\r
+ACI_ASSERT_SIZE(aci_evt_params_timing_t, 6);\r
+\r
+/**\r
+ * @struct aci_evt_params_data_credit_t\r
+ * @brief Structure for the ACI_EVT_DATA_CREDIT event return parameters\r
+ */\r
+typedef struct\r
+{\r
+  uint8_t credit;\r
+} _aci_packed_ aci_evt_params_data_credit_t;\r
+\r
+/**\r
+ * @struct aci_evt_params_data_ack_t\r
+ * @brief Structure for the ACI_EVT_DATA_ACK event return parameters\r
+ */\r
+typedef struct\r
+{\r
+  uint8_t pipe_number;\r
+} _aci_packed_ aci_evt_params_data_ack_t;\r
+\r
+/**\r
+ * @struct aci_evt_params_data_received_t\r
+ * @brief Structure for the ACI_EVT_DATA_RECEIVED event return parameters\r
+ */\r
+typedef struct\r
+{\r
+  aci_rx_data_t rx_data;\r
+} _aci_packed_ aci_evt_params_data_received_t;\r
+\r
+typedef struct\r
+{\r
+  uint8_t content[1];\r
+} _aci_packed_ error_data_t;\r
+\r
+/**\r
+ * @struct aci_evt_params_pipe_error_t\r
+ * @brief Structure for the ACI_EVT_PIPE_ERROR event return parameters\r
+ */\r
+typedef struct\r
+{\r
+  uint8_t pipe_number;\r
+  uint8_t error_code;\r
+  union\r
+  {\r
+    error_data_t  error_data;\r
+  } params;\r
+} _aci_packed_ aci_evt_params_pipe_error_t;\r
+\r
+/**\r
+ * @struct aci_evt_params_display_passkey_t\r
+ * @brief Structure for the ACI_EVT_DISPLAY_PASSKEY event return parameters\r
+ */\r
+typedef struct\r
+{\r
+  uint8_t passkey[6];\r
+} _aci_packed_ aci_evt_params_display_passkey_t;\r
+\r
+/**\r
+ * @struct aci_evt_params_key_request_t\r
+ * @brief Structure for the ACI_EVT_KEY_REQUEST event return parameters\r
+ */\r
+typedef struct\r
+{\r
+  aci_key_type_t key_type;\r
+} _aci_packed_ aci_evt_params_key_request_t;\r
+\r
+/**\r
+ * @struct aci_event_params_echo_t\r
+ * @brief  Structure for the ACI_EVT_ECHO ACI event parameters\r
+ */\r
+typedef struct\r
+{\r
+  uint8_t echo_data[ACI_ECHO_DATA_MAX_LEN];\r
+} _aci_packed_ aci_evt_params_echo_t;\r
+\r
+/**\r
+ * @struct aci_evt_t\r
+ * @brief  Encapsulates a generic ACI event\r
+ */\r
+typedef struct\r
+{\r
+  uint8_t len;\r
+  aci_evt_opcode_t evt_opcode;\r
+  union\r
+  {\r
+    aci_evt_params_device_started_t                     device_started;\r
+    aci_evt_params_echo_t                               echo;\r
+    aci_evt_params_hw_error_t                           hw_error;\r
+    aci_evt_params_cmd_rsp_t                            cmd_rsp;\r
+    aci_evt_params_connected_t                          connected;\r
+    aci_evt_params_disconnected_t                       disconnected;\r
+    aci_evt_params_bond_status_t                        bond_status;\r
+    aci_evt_params_pipe_status_t                        pipe_status;\r
+    aci_evt_params_timing_t                             timing;\r
+    aci_evt_params_data_credit_t                        data_credit;\r
+    aci_evt_params_data_ack_t                           data_ack;\r
+    aci_evt_params_data_received_t                      data_received;\r
+    aci_evt_params_pipe_error_t                         pipe_error;\r
+    aci_evt_params_display_passkey_t                    display_passkey;\r
+    aci_evt_params_key_request_t                        key_request;\r
+  } params;\r
+} _aci_packed_ aci_evt_t;\r
+\r
+ACI_ASSERT_SIZE(aci_evt_t, 33);\r
+\r
+#endif // ACI_EVTS_H__\r
diff --git a/src/nrf8001/aci_protocol_defines.h b/src/nrf8001/aci_protocol_defines.h
new file mode 100644 (file)
index 0000000..4dc82b5
--- /dev/null
@@ -0,0 +1,188 @@
+/* Copyright (c) 2014, Nordic Semiconductor ASA\r
+ *\r
+ * Permission is hereby granted, free of charge, to any person obtaining a copy\r
+ * of this software and associated documentation files (the "Software"), to deal\r
+ * in the Software without restriction, including without limitation the rights\r
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+ * copies of the Software, and to permit persons to whom the Software is\r
+ * furnished to do so, subject to the following conditions:\r
+ *\r
+ * The above copyright notice and this permission notice shall be included in all\r
+ * copies or substantial portions of the Software.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ */\r
+\r
+/*\r
+ * This file contents defines for the position of all the fields of ACI\r
+ * command or event messages\r
+ */\r
+\r
+#ifndef ACI_OFFSET_H__\r
+#define ACI_OFFSET_H__\r
+\r
+\r
+    #define OFFSET_ACI_LL_CONN_PARAMS_T_MIN_CONN_INTERVAL_LSB 0\r
+    #define OFFSET_ACI_LL_CONN_PARAMS_T_MIN_CONN_INTERVAL_MSB 1\r
+    #define OFFSET_ACI_LL_CONN_PARAMS_T_MAX_CONN_INTERVAL_LSB 2\r
+    #define OFFSET_ACI_LL_CONN_PARAMS_T_MAX_CONN_INTERVAL_MSB 3\r
+    #define OFFSET_ACI_LL_CONN_PARAMS_T_SLAVE_LATENCY_LSB 4\r
+    #define OFFSET_ACI_LL_CONN_PARAMS_T_SLAVE_LATENCY_MSB 5\r
+    #define OFFSET_ACI_LL_CONN_PARAMS_T_TIMEOUT_MULT_LSB 6\r
+    #define OFFSET_ACI_LL_CONN_PARAMS_T_TIMEOUT_MULT_MSB 7\r
+    #define OFFSET_ACI_TX_DATA_T_PIPE_NUMBER 0\r
+    #define OFFSET_ACI_TX_DATA_T_ACI_DATA 1\r
+    #define OFFSET_ACI_RX_DATA_T_PIPE_NUMBER 0\r
+    #define OFFSET_ACI_RX_DATA_T_ACI_DATA 1\r
+    #define OFFSET_ACI_CMD_PARAMS_TEST_T_TEST_MODE_CHANGE 0\r
+    #define OFFSET_ACI_CMD_PARAMS_ECHO_T_ECHO_DATA 0\r
+    #define OFFSET_ACI_CMD_PARAMS_DTM_CMD_T_CMD_MSB 0\r
+    #define OFFSET_ACI_CMD_PARAMS_DTM_CMD_T_CMD_LSB 1\r
+    #define OFFSET_ACI_CMD_PARAMS_SETUP_T_SETUP_DATA 0\r
+    #define OFFSET_ACI_CMD_PARAMS_WRITE_DYNAMIC_DATA_T_SEQ_NO 0\r
+    #define OFFSET_ACI_CMD_PARAMS_WRITE_DYNAMIC_DATA_T_DYNAMIC_DATA 1\r
+    #define OFFSET_ACI_CMD_PARAMS_SET_LOCAL_DATA_T_TX_DATA 0\r
+    #define OFFSET_ACI_CMD_PARAMS_CONNECT_T_TIMEOUT_LSB 0\r
+    #define OFFSET_ACI_CMD_PARAMS_CONNECT_T_TIMEOUT_MSB 1\r
+    #define OFFSET_ACI_CMD_PARAMS_CONNECT_T_ADV_INTERVAL_LSB 2\r
+    #define OFFSET_ACI_CMD_PARAMS_CONNECT_T_ADV_INTERVAL_MSB 3\r
+    #define OFFSET_ACI_CMD_PARAMS_BOND_T_TIMEOUT_LSB 0\r
+    #define OFFSET_ACI_CMD_PARAMS_BOND_T_TIMEOUT_MSB 1\r
+    #define OFFSET_ACI_CMD_PARAMS_BOND_T_ADV_INTERVAL_LSB 2\r
+    #define OFFSET_ACI_CMD_PARAMS_BOND_T_ADV_INTERVAL_MSB 3\r
+    #define OFFSET_ACI_CMD_PARAMS_DISCONNECT_T_REASON 0\r
+    #define OFFSET_ACI_CMD_PARAMS_SET_TX_POWER_T_DEVICE_POWER 0\r
+    #define OFFSET_ACI_CMD_PARAMS_CHANGE_TIMING_T_CONN_PARAMS 0\r
+    #define OFFSET_ACI_CMD_PARAMS_OPEN_REMOTE_PIPE_T_PIPE_NUMBER 0\r
+    #define OFFSET_ACI_CMD_PARAMS_SEND_DATA_T_TX_DATA 0\r
+    #define OFFSET_ACI_CMD_PARAMS_SEND_DATA_ACK_T_PIPE_NUMBER 0\r
+    #define OFFSET_ACI_CMD_PARAMS_REQUEST_DATA_T_PIPE_NUMBER 0\r
+    #define OFFSET_ACI_CMD_PARAMS_SEND_DATA_NACK_T_PIPE_NUMBER 0\r
+    #define OFFSET_ACI_CMD_PARAMS_SEND_DATA_NACK_T_ERROR_CODE 1\r
+    #define OFFSET_ACI_CMD_PARAMS_SET_APP_LATENCY_T_MODE 0\r
+    #define OFFSET_ACI_CMD_PARAMS_SET_APP_LATENCY_T_LATENCY_LSB 1\r
+    #define OFFSET_ACI_CMD_PARAMS_SET_APP_LATENCY_T_LATENCY_MSB 2\r
+    #define OFFSET_ACI_CMD_PARAMS_SET_KEY_T_KEY_TYPE 0\r
+    #define OFFSET_ACI_CMD_PARAMS_SET_KEY_T_PASSKEY 1\r
+    #define OFFSET_ACI_CMD_PARAMS_SET_KEY_T_OOB_KEY 1\r
+    #define OFFSET_ACI_CMD_PARAMS_OPEN_ADV_PIPE_T_PIPES 0\r
+    #define OFFSET_ACI_CMD_PARAMS_BROADCAST_T_TIMEOUT_LSB 0\r
+    #define OFFSET_ACI_CMD_PARAMS_BROADCAST_T_TIMEOUT_MSB 1\r
+    #define OFFSET_ACI_CMD_PARAMS_BROADCAST_T_ADV_INTERVAL_LSB 2\r
+    #define OFFSET_ACI_CMD_PARAMS_BROADCAST_T_ADV_INTERVAL_MSB 3\r
+    #define OFFSET_ACI_CMD_PARAMS_CLOSE_REMOTE_PIPE_T_PIPE_NUMBER 0\r
+    #define OFFSET_ACI_CMD_T_LEN 0\r
+    #define OFFSET_ACI_CMD_T_CMD_OPCODE 1\r
+    #define OFFSET_ACI_CMD_T_TEST 2\r
+    #define OFFSET_ACI_CMD_T_ECHO 2\r
+    #define OFFSET_ACI_CMD_T_DTM_CMD 2\r
+    #define OFFSET_ACI_CMD_T_SETUP 2\r
+    #define OFFSET_ACI_CMD_T_WRITE_DYNAMIC_DATA 2\r
+    #define OFFSET_ACI_CMD_T_SET_LOCAL_DATA 2\r
+    #define OFFSET_ACI_CMD_T_CONNECT 2\r
+    #define OFFSET_ACI_CMD_T_BOND 2\r
+    #define OFFSET_ACI_CMD_T_DISCONNECT 2\r
+    #define OFFSET_ACI_CMD_T_SET_TX_POWER 2\r
+    #define OFFSET_ACI_CMD_T_CHANGE_TIMING 2\r
+    #define OFFSET_ACI_CMD_T_OPEN_REMOTE_PIPE 2\r
+    #define OFFSET_ACI_CMD_T_SEND_DATA 2\r
+    #define OFFSET_ACI_CMD_T_SEND_DATA_ACK 2\r
+    #define OFFSET_ACI_CMD_T_REQUEST_DATA 2\r
+    #define OFFSET_ACI_CMD_T_SEND_DATA_NACK 2\r
+    #define OFFSET_ACI_CMD_T_SET_APP_LATENCY 2\r
+    #define OFFSET_ACI_CMD_T_SET_KEY 2\r
+    #define OFFSET_ACI_CMD_T_OPEN_ADV_PIPE 2\r
+    #define OFFSET_ACI_CMD_T_BROADCAST 2\r
+    #define OFFSET_ACI_CMD_T_CLOSE_REMOTE_PIPE 2\r
+    #define OFFSET_ACI_EVT_PARAMS_DEVICE_STARTED_T_DEVICE_MODE 0\r
+    #define OFFSET_ACI_EVT_PARAMS_DEVICE_STARTED_T_HW_ERROR 1\r
+    #define OFFSET_ACI_EVT_PARAMS_DEVICE_STARTED_T_CREDIT_AVAILABLE 2\r
+    #define OFFSET_ACI_EVT_PARAMS_HW_ERROR_T_LINE_NUM_LSB 0\r
+    #define OFFSET_ACI_EVT_PARAMS_HW_ERROR_T_LINE_NUM_MSB 1\r
+    #define OFFSET_ACI_EVT_PARAMS_HW_ERROR_T_FILE_NAME 2\r
+    #define OFFSET_ACI_EVT_CMD_RSP_PARAMS_DTM_CMD_T_EVT_MSB 0\r
+    #define OFFSET_ACI_EVT_CMD_RSP_PARAMS_DTM_CMD_T_EVT_LSB 1\r
+    #define OFFSET_ACI_EVT_CMD_RSP_READ_DYNAMIC_DATA_T_SEQ_NO 0\r
+    #define OFFSET_ACI_EVT_CMD_RSP_READ_DYNAMIC_DATA_T_DYNAMIC_DATA 1\r
+    #define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_CONFIGURATION_ID_LSB 0\r
+    #define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_CONFIGURATION_ID_MSB 1\r
+    #define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_ACI_VERSION 2\r
+    #define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_SETUP_FORMAT 3\r
+    #define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_SETUP_ID_LSB0 4\r
+    #define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_SETUP_ID_LSB1 5\r
+    #define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_SETUP_ID_MSB0 6\r
+    #define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_SETUP_ID_MSB1 7\r
+    #define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_SETUP_STATUS 8\r
+    #define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_ADDRESS_T_BD_ADDR_OWN 0\r
+    #define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_ADDRESS_T_BD_ADDR_TYPE 6\r
+    #define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_BATTERY_LEVEL_T_BATTERY_LEVEL_LSB 0\r
+    #define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_BATTERY_LEVEL_T_BATTERY_LEVEL_MSB 1\r
+    #define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_TEMPERATURE_T_TEMPERATURE_VALUE_LSB 0\r
+    #define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_TEMPERATURE_T_TEMPERATURE_VALUE_MSB 1\r
+    #define OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_CMD_OPCODE 0\r
+    #define OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_CMD_STATUS 1\r
+    #define OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_DTM_CMD 2\r
+    #define OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_READ_DYNAMIC_DATA 2\r
+    #define OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_DEVICE_VERSION 2\r
+    #define OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_DEVICE_ADDRESS 2\r
+    #define OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_BATTERY_LEVEL 2\r
+    #define OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_TEMPERATURE 2\r
+    #define OFFSET_ACI_EVT_PARAMS_CONNECTED_T_DEV_ADDR_TYPE 0\r
+    #define OFFSET_ACI_EVT_PARAMS_CONNECTED_T_DEV_ADDR 1\r
+    #define OFFSET_ACI_EVT_PARAMS_CONNECTED_T_CONN_RF_INTERVAL_LSB 7\r
+    #define OFFSET_ACI_EVT_PARAMS_CONNECTED_T_CONN_RF_INTERVAL_MSB 8\r
+    #define OFFSET_ACI_EVT_PARAMS_CONNECTED_T_CONN_SLAVE_RF_LATENCY_LSB 9\r
+    #define OFFSET_ACI_EVT_PARAMS_CONNECTED_T_CONN_SLAVE_RF_LATENCY_MSB 10\r
+    #define OFFSET_ACI_EVT_PARAMS_CONNECTED_T_CONN_RF_TIMEOUT_LSB 11\r
+    #define OFFSET_ACI_EVT_PARAMS_CONNECTED_T_CONN_RF_TIMEOUT_MSB 12\r
+    #define OFFSET_ACI_EVT_PARAMS_CONNECTED_T_MASTER_CLOCK_ACCURACY 13\r
+    #define OFFSET_ACI_EVT_PARAMS_DISCONNECTED_T_ACI_STATUS 0\r
+    #define OFFSET_ACI_EVT_PARAMS_DISCONNECTED_T_BTLE_STATUS 1\r
+    #define OFFSET_ACI_EVT_PARAMS_BOND_STATUS_T_STATUS_CODE 0\r
+    #define OFFSET_ACI_EVT_PARAMS_BOND_STATUS_T_STATUS_SOURCE 1\r
+    #define OFFSET_ACI_EVT_PARAMS_BOND_STATUS_T_SECMODE1_BITMAP 2\r
+    #define OFFSET_ACI_EVT_PARAMS_BOND_STATUS_T_SECMODE2_BITMAP 3\r
+    #define OFFSET_ACI_EVT_PARAMS_BOND_STATUS_T_KEYS_EXCHANGED_SLAVE 4\r
+    #define OFFSET_ACI_EVT_PARAMS_BOND_STATUS_T_KEYS_EXCHANGED_MASTER 5\r
+    #define OFFSET_ACI_EVT_PARAMS_PIPE_STATUS_T_PIPES_OPEN_BITMAP 0\r
+    #define OFFSET_ACI_EVT_PARAMS_PIPE_STATUS_T_PIPES_CLOSED_BITMAP 8\r
+    #define OFFSET_ACI_EVT_PARAMS_TIMING_T_CONN_RF_INTERVAL_LSB 0\r
+    #define OFFSET_ACI_EVT_PARAMS_TIMING_T_CONN_RF_INTERVAL_MSB 1\r
+    #define OFFSET_ACI_EVT_PARAMS_TIMING_T_CONN_SLAVE_RF_LATENCY_LSB 2\r
+    #define OFFSET_ACI_EVT_PARAMS_TIMING_T_CONN_SLAVE_RF_LATENCY_MSB 3\r
+    #define OFFSET_ACI_EVT_PARAMS_TIMING_T_CONN_RF_TIMEOUT_LSB 4\r
+    #define OFFSET_ACI_EVT_PARAMS_TIMING_T_CONN_RF_TIMEOUT_MSB 5\r
+    #define OFFSET_ACI_EVT_PARAMS_DATA_CREDIT_T_CREDIT 0\r
+    #define OFFSET_ACI_EVT_PARAMS_DATA_ACK_T_PIPE_NUMBER 0\r
+    #define OFFSET_ACI_EVT_PARAMS_DATA_RECEIVED_T_RX_DATA 0\r
+    #define OFFSET_ERROR_DATA_T_CONTENT 0\r
+    #define OFFSET_ACI_EVT_PARAMS_PIPE_ERROR_T_PIPE_NUMBER 0\r
+    #define OFFSET_ACI_EVT_PARAMS_PIPE_ERROR_T_ERROR_CODE 1\r
+    #define OFFSET_ACI_EVT_PARAMS_PIPE_ERROR_T_ERROR_DATA 2\r
+    #define OFFSET_ACI_EVT_PARAMS_DISPLAY_PASSKEY_T_PASSKEY 0\r
+    #define OFFSET_ACI_EVT_PARAMS_KEY_REQUEST_T_KEY_TYPE 0\r
+    #define OFFSET_ACI_EVT_T_LEN 0\r
+    #define OFFSET_ACI_EVT_T_EVT_OPCODE 1\r
+    #define OFFSET_ACI_EVT_T_DEVICE_STARTED 2\r
+    #define OFFSET_ACI_EVT_T_HW_ERROR 2\r
+    #define OFFSET_ACI_EVT_T_CMD_RSP 2\r
+    #define OFFSET_ACI_EVT_T_CONNECTED 2\r
+    #define OFFSET_ACI_EVT_T_DISCONNECTED 2\r
+    #define OFFSET_ACI_EVT_T_BOND_STATUS 2\r
+    #define OFFSET_ACI_EVT_T_PIPE_STATUS 2\r
+    #define OFFSET_ACI_EVT_T_TIMING 2\r
+    #define OFFSET_ACI_EVT_T_DATA_CREDIT 2\r
+    #define OFFSET_ACI_EVT_T_DATA_ACK 2\r
+    #define OFFSET_ACI_EVT_T_DATA_RECEIVED 2\r
+    #define OFFSET_ACI_EVT_T_PIPE_ERROR 2\r
+    #define OFFSET_ACI_EVT_T_DISPLAY_PASSKEY 2\r
+    #define OFFSET_ACI_EVT_T_KEY_REQUEST 2\r
+\r
+#endif //ACI_OFFSET_H__\r
+\r
diff --git a/src/nrf8001/aci_queue.cpp b/src/nrf8001/aci_queue.cpp
new file mode 100644 (file)
index 0000000..63ac0f8
--- /dev/null
@@ -0,0 +1,201 @@
+/* Copyright (c) 2014, Nordic Semiconductor ASA\r
+ *\r
+ * Permission is hereby granted, free of charge, to any person obtaining a copy\r
+ * of this software and associated documentation files (the "Software"), to deal\r
+ * in the Software without restriction, including without limitation the rights\r
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+ * copies of the Software, and to permit persons to whom the Software is\r
+ * furnished to do so, subject to the following conditions:\r
+ *\r
+ * The above copyright notice and this permission notice shall be included in all\r
+ * copies or substantial portions of the Software.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ */\r
+\r
+ /** @file\r
+@brief Implementation of a circular queue for ACI data\r
+*/\r
+\r
+#include "hal_aci_tl.h"\r
+#include "aci_queue.h"\r
+\r
+void aci_queue_init(aci_queue_t *aci_q)\r
+{\r
+  uint8_t loop;\r
+\r
+  // ble_assert(NULL != aci_q);\r
+\r
+  aci_q->head = 0;\r
+  aci_q->tail = 0;\r
+  for(loop=0; loop<ACI_QUEUE_SIZE; loop++)\r
+  {\r
+    aci_q->aci_data[loop].buffer[0] = 0x00;\r
+    aci_q->aci_data[loop].buffer[1] = 0x00;\r
+  }\r
+}\r
+\r
+bool aci_queue_dequeue(aci_queue_t *aci_q, hal_aci_data_t *p_data)\r
+{\r
+  // ble_assert(NULL != aci_q);\r
+  // ble_assert(NULL != p_data);\r
+\r
+  if (aci_queue_is_empty(aci_q))\r
+  {\r
+    return false;\r
+  }\r
+\r
+  memcpy((uint8_t *)p_data, (uint8_t *)&(aci_q->aci_data[aci_q->head]), sizeof(hal_aci_data_t));\r
+  aci_q->head = (aci_q->head + 1) % ACI_QUEUE_SIZE;\r
+\r
+  return true;\r
+}\r
+\r
+bool aci_queue_dequeue_from_isr(aci_queue_t *aci_q, hal_aci_data_t *p_data)\r
+{\r
+  // ble_assert(NULL != aci_q);\r
+  // ble_assert(NULL != p_data);\r
+\r
+  if (aci_queue_is_empty_from_isr(aci_q))\r
+  {\r
+    return false;\r
+  }\r
+\r
+  memcpy((uint8_t *)p_data, (uint8_t *)&(aci_q->aci_data[aci_q->head]), sizeof(hal_aci_data_t));\r
+  aci_q->head = (aci_q->head + 1) % ACI_QUEUE_SIZE;\r
+\r
+  return true;\r
+}\r
+\r
+bool aci_queue_enqueue(aci_queue_t *aci_q, hal_aci_data_t *p_data)\r
+{\r
+  const uint8_t length = p_data->buffer[0];\r
+\r
+  // ble_assert(NULL != aci_q);\r
+  // ble_assert(NULL != p_data);\r
+\r
+  if (aci_queue_is_full(aci_q))\r
+  {\r
+    return false;\r
+  }\r
+\r
+  aci_q->aci_data[aci_q->tail].status_byte = 0;\r
+  memcpy((uint8_t *)&(aci_q->aci_data[aci_q->tail].buffer[0]), (uint8_t *)&p_data->buffer[0], length + 1);\r
+  aci_q->tail = (aci_q->tail + 1) % ACI_QUEUE_SIZE;\r
+\r
+  return true;\r
+}\r
+\r
+bool aci_queue_enqueue_from_isr(aci_queue_t *aci_q, hal_aci_data_t *p_data)\r
+{\r
+  const uint8_t length = p_data->buffer[0];\r
+\r
+  // ble_assert(NULL != aci_q);\r
+  // ble_assert(NULL != p_data);\r
+\r
+  if (aci_queue_is_full_from_isr(aci_q))\r
+  {\r
+    return false;\r
+  }\r
+\r
+  aci_q->aci_data[aci_q->tail].status_byte = 0;\r
+  memcpy((uint8_t *)&(aci_q->aci_data[aci_q->tail].buffer[0]), (uint8_t *)&p_data->buffer[0], length + 1);\r
+  aci_q->tail = (aci_q->tail + 1) % ACI_QUEUE_SIZE;\r
+\r
+  return true;\r
+}\r
+\r
+bool aci_queue_is_empty(aci_queue_t *aci_q)\r
+{\r
+  bool state = false;\r
+\r
+  // ble_assert(NULL != aci_q);\r
+\r
+  //Critical section\r
+  // noInterrupts();\r
+  if (aci_q->head == aci_q->tail)\r
+  {\r
+    state = true;\r
+  }\r
+  // interrupts();\r
+\r
+  return state;\r
+}\r
+\r
+bool aci_queue_is_empty_from_isr(aci_queue_t *aci_q)\r
+{\r
+  // ble_assert(NULL != aci_q);\r
+\r
+  return aci_q->head == aci_q->tail;\r
+}\r
+\r
+bool aci_queue_is_full(aci_queue_t *aci_q)\r
+{\r
+  uint8_t next;\r
+  bool state;\r
+\r
+  // ble_assert(NULL != aci_q);\r
+\r
+  //This should be done in a critical section\r
+  // noInterrupts();\r
+  next = (aci_q->tail + 1) % ACI_QUEUE_SIZE;\r
+\r
+  if (next == aci_q->head)\r
+  {\r
+    state = true;\r
+  }\r
+  else\r
+  {\r
+    state = false;\r
+  }\r
+\r
+  // interrupts();\r
+  //end\r
+\r
+  return state;\r
+}\r
+\r
+bool aci_queue_is_full_from_isr(aci_queue_t *aci_q)\r
+{\r
+  const uint8_t next = (aci_q->tail + 1) % ACI_QUEUE_SIZE;\r
+\r
+  // ble_assert(NULL != aci_q);\r
+\r
+  return next == aci_q->head;\r
+}\r
+\r
+bool aci_queue_peek(aci_queue_t *aci_q, hal_aci_data_t *p_data)\r
+{\r
+  // ble_assert(NULL != aci_q);\r
+  // ble_assert(NULL != p_data);\r
+\r
+  if (aci_queue_is_empty(aci_q))\r
+  {\r
+    return false;\r
+  }\r
+\r
+  memcpy((uint8_t *)p_data, (uint8_t *)&(aci_q->aci_data[aci_q->head]), sizeof(hal_aci_data_t));\r
+\r
+  return true;\r
+}\r
+\r
+bool aci_queue_peek_from_isr(aci_queue_t *aci_q, hal_aci_data_t *p_data)\r
+{\r
+  // ble_assert(NULL != aci_q);\r
+  // ble_assert(NULL != p_data);\r
+\r
+  if (aci_queue_is_empty_from_isr(aci_q))\r
+  {\r
+    return false;\r
+  }\r
+\r
+  memcpy((uint8_t *)p_data, (uint8_t *)&(aci_q->aci_data[aci_q->head]), sizeof(hal_aci_data_t));\r
+\r
+  return true;\r
+}\r
diff --git a/src/nrf8001/aci_queue.h b/src/nrf8001/aci_queue.h
new file mode 100644 (file)
index 0000000..13ebd6a
--- /dev/null
@@ -0,0 +1,76 @@
+/* Copyright (c) 2014, Nordic Semiconductor ASA\r
+ *\r
+ * Permission is hereby granted, free of charge, to any person obtaining a copy\r
+ * of this software and associated documentation files (the "Software"), to deal\r
+ * in the Software without restriction, including without limitation the rights\r
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+ * copies of the Software, and to permit persons to whom the Software is\r
+ * furnished to do so, subject to the following conditions:\r
+ *\r
+ * The above copyright notice and this permission notice shall be included in all\r
+ * copies or substantial portions of the Software.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ */\r
+\r
+/** @file\r
+ * @brief Interface for buffer.\r
+ */\r
+\r
+/** @defgroup aci_queue aci_queue\r
+@{\r
+@ingroup aci_queue\r
+\r
+*/\r
+\r
+#ifndef ACI_QUEUE_H__\r
+#define ACI_QUEUE_H__\r
+\r
+#include "aci.h"\r
+#include "hal_aci_tl.h"\r
+\r
+/***********************************************************************    */\r
+/* The ACI_QUEUE_SIZE determines the memory usage of the system.            */\r
+/* Successfully tested to a ACI_QUEUE_SIZE of 4 (interrupt) and 4 (polling) */\r
+/***********************************************************************    */\r
+#define ACI_QUEUE_SIZE  4\r
+\r
+/** Data type for queue of data packets to send/receive from radio.\r
+ *\r
+ *  A FIFO queue is maintained for packets. New packets are added (enqueued)\r
+ *  at the tail and taken (dequeued) from the head. The head variable is the\r
+ *  index of the next packet to dequeue while the tail variable is the index of\r
+ *  where the next packet should be queued.\r
+ */\r
+\r
+typedef struct {\r
+    hal_aci_data_t           aci_data[ACI_QUEUE_SIZE];\r
+    uint8_t                  head;\r
+    uint8_t                  tail;\r
+} aci_queue_t;\r
+\r
+void aci_queue_init(aci_queue_t *aci_q);\r
+\r
+bool aci_queue_dequeue(aci_queue_t *aci_q, hal_aci_data_t *p_data);\r
+bool aci_queue_dequeue_from_isr(aci_queue_t *aci_q, hal_aci_data_t *p_data);\r
+\r
+bool aci_queue_enqueue(aci_queue_t *aci_q, hal_aci_data_t *p_data);\r
+bool aci_queue_enqueue_from_isr(aci_queue_t *aci_q, hal_aci_data_t *p_data);\r
+\r
+bool aci_queue_is_empty(aci_queue_t *aci_q);\r
+bool aci_queue_is_empty_from_isr(aci_queue_t *aci_q);\r
+\r
+bool aci_queue_is_full(aci_queue_t *aci_q);\r
+bool aci_queue_is_full_from_isr(aci_queue_t *aci_q);\r
+\r
+bool aci_queue_peek(aci_queue_t *aci_q, hal_aci_data_t *p_data);\r
+bool aci_queue_peek_from_isr(aci_queue_t *aci_q, hal_aci_data_t *p_data);\r
+\r
+#endif /* ACI_QUEUE_H__ */\r
+/** @} */\r
diff --git a/src/nrf8001/aci_setup.cpp b/src/nrf8001/aci_setup.cpp
new file mode 100644 (file)
index 0000000..dca6d4e
--- /dev/null
@@ -0,0 +1,177 @@
+/* Copyright (c) 2014, Nordic Semiconductor ASA\r
+ *\r
+ * Permission is hereby granted, free of charge, to any person obtaining a copy\r
+ * of this software and associated documentation files (the "Software"), to deal\r
+ * in the Software without restriction, including without limitation the rights\r
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+ * copies of the Software, and to permit persons to whom the Software is\r
+ * furnished to do so, subject to the following conditions:\r
+ *\r
+ * The above copyright notice and this permission notice shall be included in all\r
+ * copies or substantial portions of the Software.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ */\r
+\r
+\r
+#include "aci.h"\r
+#include "hal_aci_tl.h"\r
+#include <lib_aci.h>\r
+#include "aci_setup.h"\r
+\r
+\r
+// aci_struct that will contain\r
+// total initial credits\r
+// current credit\r
+// current state of the aci (setup/standby/active/sleep)\r
+// open remote pipe pending\r
+// close remote pipe pending\r
+// Current pipe available bitmap\r
+// Current pipe closed bitmap\r
+// Current connection interval, slave latency and link supervision timeout\r
+// Current State of the the GATT client (Service Discovery status)\r
+\r
+\r
+// hal_aci_data_t msg_to_send;\r
+extern hal_aci_data_t msg_to_send;\r
+\r
+\r
+/**************************************************************************                */\r
+/* Utility function to fill the the ACI command queue                                      */\r
+/* aci_stat               Pointer to the ACI state                                         */\r
+/* num_cmd_offset(in/out) Offset in the Setup message array to start from                  */\r
+/*                        offset is updated to the new index after the queue is filled     */\r
+/*                        or the last message us placed in the queue                       */\r
+/* Returns                true if at least one message was transferred                     */\r
+/***************************************************************************/\r
+bool aci_setup_fill(aci_state_t *aci_stat, uint8_t *num_cmd_offset)\r
+{\r
+  bool ret_val = false;\r
+\r
+  while (*num_cmd_offset < aci_stat->aci_setup_info.num_setup_msgs)\r
+  {\r
+    //Board dependent defines\r
+    /*#if defined (__AVR__)\r
+        //For Arduino copy the setup ACI message from Flash to RAM.\r
+        memcpy_P(&msg_to_send, &(aci_stat->aci_setup_info.setup_msgs[*num_cmd_offset]),\r
+                  pgm_read_byte_near(&(aci_stat->aci_setup_info.setup_msgs[*num_cmd_offset].buffer[0]))+2);\r
+    #elif defined(__PIC32MX__)\r
+        //In ChipKit we store the setup messages in RAM\r
+        //Add 2 bytes to the length byte for status byte, length for the total number of bytes\r
+        memcpy(&msg_to_send, &(aci_stat->aci_setup_info.setup_msgs[*num_cmd_offset]),\r
+                  (aci_stat->aci_setup_info.setup_msgs[*num_cmd_offset].buffer[0]+2));\r
+    #endif*/\r
+\r
+    memcpy(&msg_to_send, &(aci_stat->aci_setup_info.setup_msgs[*num_cmd_offset]),\r
+                  (aci_stat->aci_setup_info.setup_msgs[*num_cmd_offset].buffer[0]+2));\r
+\r
+    //Put the Setup ACI message in the command queue\r
+    if (!hal_aci_tl_send(&msg_to_send))\r
+    {\r
+      //ACI Command Queue is full\r
+      // *num_cmd_offset is now pointing to the index of the Setup command that did not get sent\r
+      return ret_val;\r
+   }\r
+\r
+    ret_val = true;\r
+\r
+    (*num_cmd_offset)++;\r
+  }\r
+\r
+  return ret_val;\r
+}\r
+\r
+uint8_t do_aci_setup(aci_state_t *aci_stat)\r
+{\r
+  uint8_t setup_offset         = 0;\r
+  uint32_t i                   = 0x0000;\r
+  aci_evt_t * aci_evt          = NULL;\r
+  aci_status_code_t cmd_status = ACI_STATUS_ERROR_CRC_MISMATCH;\r
+\r
+  /*\r
+  We are using the same buffer since we are copying the contents of the buffer\r
+  when queuing and immediately processing the buffer when receiving\r
+  */\r
+  hal_aci_evt_t  *aci_data = (hal_aci_evt_t *)&msg_to_send;\r
+\r
+  /* Messages in the outgoing queue must be handled before the Setup routine can run.\r
+   * If it is non-empty we return. The user should then process the messages before calling\r
+   * do_aci_setup() again.\r
+   */\r
+  if (!lib_aci_command_queue_empty())\r
+  {\r
+    return SETUP_FAIL_COMMAND_QUEUE_NOT_EMPTY;\r
+  }\r
+\r
+  /* If there are events pending from the device that are not relevant to setup, we return false\r
+   * so that the user can handle them. At this point we don't care what the event is,\r
+   * as any event is an error.\r
+   */\r
+  if (lib_aci_event_peek(aci_data))\r
+  {\r
+    return SETUP_FAIL_EVENT_QUEUE_NOT_EMPTY;\r
+  }\r
+\r
+  /* Fill the ACI command queue with as many Setup messages as it will hold. */\r
+  aci_setup_fill(aci_stat, &setup_offset);\r
+\r
+  while (cmd_status != ACI_STATUS_TRANSACTION_COMPLETE)\r
+  {\r
+    /* This counter is used to ensure that this function does not loop forever. When the device\r
+     * returns a valid response, we reset the counter.\r
+     */\r
+    if (i++ > 0xFFFFE)\r
+    {\r
+      return SETUP_FAIL_TIMEOUT;\r
+    }\r
+\r
+    if (lib_aci_event_peek(aci_data))\r
+    {\r
+      aci_evt = &(aci_data->evt);\r
+\r
+      if (ACI_EVT_CMD_RSP != aci_evt->evt_opcode)\r
+      {\r
+        //Receiving something other than a Command Response Event is an error.\r
+        return SETUP_FAIL_NOT_COMMAND_RESPONSE;\r
+      }\r
+\r
+      cmd_status = (aci_status_code_t) aci_evt->params.cmd_rsp.cmd_status;\r
+      switch (cmd_status)\r
+      {\r
+        case ACI_STATUS_TRANSACTION_CONTINUE:\r
+          //As the device is responding, reset guard counter\r
+          i = 0;\r
+\r
+          /* As the device has processed the Setup messages we put in the command queue earlier,\r
+           * we can proceed to fill the queue with new messages\r
+           */\r
+          aci_setup_fill(aci_stat, &setup_offset);\r
+          break;\r
+\r
+        case ACI_STATUS_TRANSACTION_COMPLETE:\r
+          //Break out of the while loop when this status code appears\r
+          break;\r
+\r
+        default:\r
+          //An event with any other status code should be handled by the application\r
+          return SETUP_FAIL_NOT_SETUP_EVENT;\r
+      }\r
+\r
+      /* If we haven't returned at this point, the event was either ACI_STATUS_TRANSACTION_CONTINUE\r
+       * or ACI_STATUS_TRANSACTION_COMPLETE. We don't need the event itself, so we simply\r
+       * remove it from the queue.\r
+       */\r
+       lib_aci_event_get (aci_stat, aci_data);\r
+    }\r
+  }\r
+\r
+  return SETUP_SUCCESS;\r
+}\r
+\r
+\r
diff --git a/src/nrf8001/aci_setup.h b/src/nrf8001/aci_setup.h
new file mode 100644 (file)
index 0000000..865d7d3
--- /dev/null
@@ -0,0 +1,45 @@
+/* Copyright (c) 2014, Nordic Semiconductor ASA\r
+ *\r
+ * Permission is hereby granted, free of charge, to any person obtaining a copy\r
+ * of this software and associated documentation files (the "Software"), to deal\r
+ * in the Software without restriction, including without limitation the rights\r
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+ * copies of the Software, and to permit persons to whom the Software is\r
+ * furnished to do so, subject to the following conditions:\r
+ *\r
+ * The above copyright notice and this permission notice shall be included in all\r
+ * copies or substantial portions of the Software.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ */\r
+\r
+\r
+#ifndef H_ACI_SETUP\r
+#define H_ACI_SETUP\r
+\r
+#define SETUP_SUCCESS                        0\r
+#define SETUP_FAIL_COMMAND_QUEUE_NOT_EMPTY   1\r
+#define SETUP_FAIL_EVENT_QUEUE_NOT_EMPTY     2\r
+#define SETUP_FAIL_TIMEOUT                   3\r
+#define SETUP_FAIL_NOT_SETUP_EVENT           4\r
+#define SETUP_FAIL_NOT_COMMAND_RESPONSE      5\r
+\r
+bool aci_setup_fill(aci_state_t *aci_stat, uint8_t *num_cmd_offset);\r
+/** @brief Setup the nRF8001 device\r
+ *  @details\r
+ *  Performs ACI Setup by transmitting the setup messages generated by nRFgo Studio to the\r
+ *  nRF8001, and should be called when the nRF8001 starts or resets.\r
+ *  Once all messages are sent, the nRF8001 will send a Device Started Event.\r
+ *  The function requires that the Command queue is empty when it is invoked, and will fail\r
+ *  otherwise.\r
+ *  @returns An integer indicating the reason the function terminated\r
+ */\r
+uint8_t do_aci_setup(aci_state_t *aci_stat);\r
+\r
+#endif\r
diff --git a/src/nrf8001/acilib.cpp b/src/nrf8001/acilib.cpp
new file mode 100644 (file)
index 0000000..4e7f41f
--- /dev/null
@@ -0,0 +1,610 @@
+/* Copyright (c) 2014, Nordic Semiconductor ASA\r
+ *\r
+ * Permission is hereby granted, free of charge, to any person obtaining a copy\r
+ * of this software and associated documentation files (the "Software"), to deal\r
+ * in the Software without restriction, including without limitation the rights\r
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+ * copies of the Software, and to permit persons to whom the Software is\r
+ * furnished to do so, subject to the following conditions:\r
+ *\r
+ * The above copyright notice and this permission notice shall be included in all\r
+ * copies or substantial portions of the Software.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ */\r
+\r
+/**\r
+ * @file\r
+ *\r
+ * @ingroup group_acilib\r
+ *\r
+ * @brief Implementation of the acilib module.\r
+ */\r
+\r
+\r
+#include "hal_platform.h"\r
+#include "aci.h"\r
+#include "aci_cmds.h"\r
+#include "aci_evts.h"\r
+#include "acilib.h"\r
+#include "aci_protocol_defines.h"\r
+#include "acilib_defs.h"\r
+#include "acilib_if.h"\r
+#include "acilib_types.h"\r
+\r
+\r
+void acil_encode_cmd_set_test_mode(uint8_t *buffer, aci_cmd_params_test_t *p_aci_cmd_params_test)\r
+{\r
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = 2;\r
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_TEST;\r
+  *(buffer + OFFSET_ACI_CMD_T_TEST + OFFSET_ACI_CMD_PARAMS_TEST_T_TEST_MODE_CHANGE) = p_aci_cmd_params_test->test_mode_change;\r
+}\r
+\r
+void acil_encode_cmd_sleep(uint8_t *buffer)\r
+{\r
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = 1;\r
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_SLEEP;\r
+}\r
+\r
+void acil_encode_cmd_get_device_version(uint8_t *buffer)\r
+{\r
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = 1;\r
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_GET_DEVICE_VERSION;\r
+}\r
+\r
+void acil_encode_cmd_set_local_data(uint8_t *buffer, aci_cmd_params_set_local_data_t *p_aci_cmd_params_set_local_data, uint8_t data_size)\r
+{\r
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_SET_LOCAL_DATA_BASE_LEN + data_size;\r
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_SET_LOCAL_DATA;\r
+  *(buffer + OFFSET_ACI_CMD_T_SET_LOCAL_DATA + OFFSET_ACI_CMD_PARAMS_SEND_DATA_T_TX_DATA + OFFSET_ACI_TX_DATA_T_PIPE_NUMBER) = p_aci_cmd_params_set_local_data->tx_data.pipe_number;\r
+  memcpy(buffer + OFFSET_ACI_CMD_T_SET_LOCAL_DATA + OFFSET_ACI_CMD_PARAMS_SEND_DATA_T_TX_DATA + OFFSET_ACI_TX_DATA_T_ACI_DATA,  &(p_aci_cmd_params_set_local_data->tx_data.aci_data[0]), data_size);\r
+}\r
+\r
+void acil_encode_cmd_connect(uint8_t *buffer, aci_cmd_params_connect_t *p_aci_cmd_params_connect)\r
+{\r
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_CONNECT_LEN;\r
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_CONNECT;\r
+  *(buffer + OFFSET_ACI_CMD_T_CONNECT + OFFSET_ACI_CMD_PARAMS_CONNECT_T_TIMEOUT_MSB) = (uint8_t)(p_aci_cmd_params_connect->timeout >> 8);\r
+  *(buffer + OFFSET_ACI_CMD_T_CONNECT + OFFSET_ACI_CMD_PARAMS_CONNECT_T_TIMEOUT_LSB) = (uint8_t)(p_aci_cmd_params_connect->timeout);\r
+  *(buffer + OFFSET_ACI_CMD_T_CONNECT + OFFSET_ACI_CMD_PARAMS_CONNECT_T_ADV_INTERVAL_MSB) = (uint8_t)(p_aci_cmd_params_connect->adv_interval >> 8);\r
+  *(buffer + OFFSET_ACI_CMD_T_CONNECT + OFFSET_ACI_CMD_PARAMS_CONNECT_T_ADV_INTERVAL_LSB) = (uint8_t)(p_aci_cmd_params_connect->adv_interval);\r
+}\r
+\r
+void acil_encode_cmd_bond(uint8_t *buffer, aci_cmd_params_bond_t *p_aci_cmd_params_bond)\r
+{\r
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_BOND_LEN;\r
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_BOND;\r
+  *(buffer + OFFSET_ACI_CMD_T_BOND + OFFSET_ACI_CMD_PARAMS_BOND_T_TIMEOUT_MSB) = (uint8_t)(p_aci_cmd_params_bond->timeout >> 8);\r
+  *(buffer + OFFSET_ACI_CMD_T_BOND + OFFSET_ACI_CMD_PARAMS_BOND_T_TIMEOUT_LSB) = (uint8_t)(p_aci_cmd_params_bond->timeout);\r
+  *(buffer + OFFSET_ACI_CMD_T_BOND + OFFSET_ACI_CMD_PARAMS_BOND_T_ADV_INTERVAL_MSB) = (uint8_t)(p_aci_cmd_params_bond->adv_interval >> 8);\r
+  *(buffer + OFFSET_ACI_CMD_T_BOND + OFFSET_ACI_CMD_PARAMS_BOND_T_ADV_INTERVAL_LSB) = (uint8_t)(p_aci_cmd_params_bond->adv_interval);\r
+}\r
+\r
+void acil_encode_cmd_disconnect(uint8_t *buffer, aci_cmd_params_disconnect_t *p_aci_cmd_params_disconnect)\r
+{\r
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_DISCONNECT_LEN;\r
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_DISCONNECT;\r
+  *(buffer + OFFSET_ACI_CMD_T_DISCONNECT + OFFSET_ACI_CMD_PARAMS_DISCONNECT_T_REASON) = (uint8_t)(p_aci_cmd_params_disconnect->reason);\r
+}\r
+\r
+void acil_encode_baseband_reset(uint8_t *buffer)\r
+{\r
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_BASEBAND_RESET_LEN;\r
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_RADIO_RESET;\r
+}\r
+\r
+void acil_encode_direct_connect(uint8_t *buffer)\r
+{\r
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_DIRECT_CONNECT_LEN;\r
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_CONNECT_DIRECT;\r
+}\r
+\r
+void acil_encode_cmd_wakeup(uint8_t *buffer)\r
+{\r
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_WAKEUP_LEN;\r
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_WAKEUP;\r
+}\r
+\r
+void acil_encode_cmd_set_radio_tx_power(uint8_t *buffer, aci_cmd_params_set_tx_power_t *p_aci_cmd_params_set_tx_power)\r
+{\r
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_SET_RADIO_TX_POWER_LEN;\r
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_SET_TX_POWER;\r
+  *(buffer + OFFSET_ACI_CMD_T_SET_TX_POWER + OFFSET_ACI_CMD_PARAMS_SET_TX_POWER_T_DEVICE_POWER) = (uint8_t)p_aci_cmd_params_set_tx_power->device_power;\r
+}\r
+\r
+void acil_encode_cmd_get_address(uint8_t *buffer)\r
+{\r
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_GET_DEVICE_ADDR_LEN;\r
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_GET_DEVICE_ADDRESS;\r
+}\r
+\r
+void acil_encode_cmd_send_data(uint8_t *buffer, aci_cmd_params_send_data_t *p_aci_cmd_params_send_data_t, uint8_t data_size)\r
+{\r
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_SEND_DATA_BASE_LEN + data_size;\r
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_SEND_DATA;\r
+  *(buffer + OFFSET_ACI_CMD_T_SEND_DATA + OFFSET_ACI_CMD_PARAMS_SEND_DATA_T_TX_DATA + OFFSET_ACI_TX_DATA_T_PIPE_NUMBER) = p_aci_cmd_params_send_data_t->tx_data.pipe_number;\r
+  memcpy((buffer + OFFSET_ACI_CMD_T_SEND_DATA + OFFSET_ACI_CMD_PARAMS_SEND_DATA_T_TX_DATA + OFFSET_ACI_TX_DATA_T_ACI_DATA), &(p_aci_cmd_params_send_data_t->tx_data.aci_data[0]), data_size);\r
+}\r
+\r
+void acil_encode_cmd_request_data(uint8_t *buffer, aci_cmd_params_request_data_t *p_aci_cmd_params_request_data)\r
+{\r
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_DATA_REQUEST_LEN;\r
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_REQUEST_DATA;\r
+  *(buffer + OFFSET_ACI_CMD_T_REQUEST_DATA + OFFSET_ACI_CMD_PARAMS_REQUEST_DATA_T_PIPE_NUMBER) = p_aci_cmd_params_request_data->pipe_number;\r
+}\r
+\r
+void acil_encode_cmd_open_remote_pipe(uint8_t *buffer, aci_cmd_params_open_remote_pipe_t *p_aci_cmd_params_open_remote_pipe)\r
+{\r
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_OPEN_REMOTE_PIPE_LEN;\r
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_OPEN_REMOTE_PIPE;\r
+  *(buffer + OFFSET_ACI_CMD_T_OPEN_REMOTE_PIPE + OFFSET_ACI_CMD_PARAMS_OPEN_REMOTE_PIPE_T_PIPE_NUMBER) = p_aci_cmd_params_open_remote_pipe->pipe_number;\r
+}\r
+\r
+void acil_encode_cmd_close_remote_pipe(uint8_t *buffer, aci_cmd_params_close_remote_pipe_t *p_aci_cmd_params_close_remote_pipe)\r
+{\r
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_CLOSE_REMOTE_PIPE_LEN;\r
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_CLOSE_REMOTE_PIPE;\r
+  *(buffer + OFFSET_ACI_CMD_T_CLOSE_REMOTE_PIPE + OFFSET_ACI_CMD_PARAMS_CLOSE_REMOTE_PIPE_T_PIPE_NUMBER) = p_aci_cmd_params_close_remote_pipe->pipe_number;\r
+}\r
+\r
+void acil_encode_cmd_echo_msg(uint8_t *buffer, aci_cmd_params_echo_t *p_cmd_params_echo, uint8_t msg_size)\r
+{\r
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_ECHO_MSG_CMD_BASE_LEN + msg_size;\r
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_ECHO;\r
+  memcpy((buffer + OFFSET_ACI_CMD_T_ECHO + OFFSET_ACI_CMD_PARAMS_ECHO_T_ECHO_DATA), &(p_cmd_params_echo->echo_data[0]), msg_size);\r
+}\r
+\r
+void acil_encode_cmd_battery_level(uint8_t *buffer)\r
+{\r
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = 1;\r
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_GET_BATTERY_LEVEL;\r
+}\r
+\r
+void acil_encode_cmd_temparature(uint8_t *buffer)\r
+{\r
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = 1;\r
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_GET_TEMPERATURE;\r
+}\r
+\r
+void acil_encode_cmd_read_dynamic_data(uint8_t *buffer)\r
+{\r
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = 1;\r
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_READ_DYNAMIC_DATA;\r
+}\r
+\r
+void acil_encode_cmd_write_dynamic_data(uint8_t *buffer, uint8_t seq_no, uint8_t* dynamic_data, uint8_t dynamic_data_size)\r
+{\r
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_WRITE_DYNAMIC_DATA_BASE_LEN + dynamic_data_size;\r
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_WRITE_DYNAMIC_DATA;\r
+  *(buffer + OFFSET_ACI_CMD_T_WRITE_DYNAMIC_DATA + OFFSET_ACI_CMD_PARAMS_WRITE_DYNAMIC_DATA_T_SEQ_NO) = seq_no;\r
+  memcpy((buffer + OFFSET_ACI_CMD_T_WRITE_DYNAMIC_DATA + OFFSET_ACI_CMD_PARAMS_WRITE_DYNAMIC_DATA_T_DYNAMIC_DATA), dynamic_data, dynamic_data_size);\r
+}\r
+\r
+void acil_encode_cmd_change_timing_req(uint8_t *buffer, aci_cmd_params_change_timing_t *p_aci_cmd_params_change_timing)\r
+{\r
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_CHANGE_TIMING_LEN;\r
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_CHANGE_TIMING;\r
+  *(buffer + OFFSET_ACI_CMD_T_CHANGE_TIMING + OFFSET_ACI_CMD_PARAMS_CHANGE_TIMING_T_CONN_PARAMS + OFFSET_ACI_LL_CONN_PARAMS_T_MIN_CONN_INTERVAL_MSB) = (uint8_t)(p_aci_cmd_params_change_timing->conn_params.min_conn_interval >> 8);\r
+  *(buffer + OFFSET_ACI_CMD_T_CHANGE_TIMING + OFFSET_ACI_CMD_PARAMS_CHANGE_TIMING_T_CONN_PARAMS + OFFSET_ACI_LL_CONN_PARAMS_T_MIN_CONN_INTERVAL_LSB) = (uint8_t)(p_aci_cmd_params_change_timing->conn_params.min_conn_interval);\r
+  *(buffer + OFFSET_ACI_CMD_T_CHANGE_TIMING + OFFSET_ACI_CMD_PARAMS_CHANGE_TIMING_T_CONN_PARAMS + OFFSET_ACI_LL_CONN_PARAMS_T_MAX_CONN_INTERVAL_MSB) = (uint8_t)(p_aci_cmd_params_change_timing->conn_params.max_conn_interval >> 8);\r
+  *(buffer + OFFSET_ACI_CMD_T_CHANGE_TIMING + OFFSET_ACI_CMD_PARAMS_CHANGE_TIMING_T_CONN_PARAMS + OFFSET_ACI_LL_CONN_PARAMS_T_MAX_CONN_INTERVAL_LSB) = (uint8_t)(p_aci_cmd_params_change_timing->conn_params.max_conn_interval);\r
+  *(buffer + OFFSET_ACI_CMD_T_CHANGE_TIMING + OFFSET_ACI_CMD_PARAMS_CHANGE_TIMING_T_CONN_PARAMS + OFFSET_ACI_LL_CONN_PARAMS_T_SLAVE_LATENCY_MSB    ) = (uint8_t)(p_aci_cmd_params_change_timing->conn_params.slave_latency >> 8);\r
+  *(buffer + OFFSET_ACI_CMD_T_CHANGE_TIMING + OFFSET_ACI_CMD_PARAMS_CHANGE_TIMING_T_CONN_PARAMS + OFFSET_ACI_LL_CONN_PARAMS_T_SLAVE_LATENCY_LSB    ) = (uint8_t)(p_aci_cmd_params_change_timing->conn_params.slave_latency);\r
+  *(buffer + OFFSET_ACI_CMD_T_CHANGE_TIMING + OFFSET_ACI_CMD_PARAMS_CHANGE_TIMING_T_CONN_PARAMS + OFFSET_ACI_LL_CONN_PARAMS_T_TIMEOUT_MULT_MSB     ) = (uint8_t)(p_aci_cmd_params_change_timing->conn_params.timeout_mult >> 8);\r
+  *(buffer + OFFSET_ACI_CMD_T_CHANGE_TIMING + OFFSET_ACI_CMD_PARAMS_CHANGE_TIMING_T_CONN_PARAMS + OFFSET_ACI_LL_CONN_PARAMS_T_TIMEOUT_MULT_LSB     ) = (uint8_t)(p_aci_cmd_params_change_timing->conn_params.timeout_mult);\r
+}\r
+\r
+void acil_encode_cmd_set_app_latency(uint8_t *buffer, aci_cmd_params_set_app_latency_t *p_aci_cmd_params_set_app_latency)\r
+{\r
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_SET_APP_LATENCY_LEN;\r
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_SET_APP_LATENCY;\r
+  *(buffer + OFFSET_ACI_CMD_T_SET_APP_LATENCY + OFFSET_ACI_CMD_PARAMS_SET_APP_LATENCY_T_MODE) = (uint8_t)( p_aci_cmd_params_set_app_latency->mode);\r
+  *(buffer + OFFSET_ACI_CMD_T_SET_APP_LATENCY + OFFSET_ACI_CMD_PARAMS_SET_APP_LATENCY_T_LATENCY_MSB) = (uint8_t)( p_aci_cmd_params_set_app_latency->latency>>8);\r
+  *(buffer + OFFSET_ACI_CMD_T_SET_APP_LATENCY + OFFSET_ACI_CMD_PARAMS_SET_APP_LATENCY_T_LATENCY_LSB) = (uint8_t)( p_aci_cmd_params_set_app_latency->latency);\r
+}\r
+\r
+void acil_encode_cmd_change_timing_req_GAP_PPCP(uint8_t *buffer)\r
+{\r
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_CHANGE_TIMING_LEN_GAP_PPCP;\r
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_CHANGE_TIMING;\r
+}\r
+\r
+\r
+void acil_encode_cmd_setup(uint8_t *buffer, aci_cmd_params_setup_t *p_aci_cmd_params_setup, uint8_t setup_data_size)\r
+{\r
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = setup_data_size + MSG_SETUP_CMD_BASE_LEN;\r
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_SETUP;\r
+  memcpy((buffer + OFFSET_ACI_CMD_T_SETUP), &(p_aci_cmd_params_setup->setup_data[0]), setup_data_size);\r
+}\r
+\r
+void acil_encode_cmd_dtm_cmd(uint8_t *buffer, aci_cmd_params_dtm_cmd_t *p_aci_cmd_params_dtm_cmd)\r
+{\r
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_DTM_CMD;\r
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_DTM_CMD;\r
+  *(buffer + OFFSET_ACI_CMD_T_DTM_CMD) = p_aci_cmd_params_dtm_cmd->cmd_msb;\r
+  *(buffer + OFFSET_ACI_CMD_T_DTM_CMD + 1) = p_aci_cmd_params_dtm_cmd->cmd_lsb;\r
+}\r
+\r
+void acil_encode_cmd_send_data_ack(uint8_t *buffer, const uint8_t pipe_number )\r
+{\r
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_ACK_LEN;\r
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_SEND_DATA_ACK;\r
+  *(buffer + OFFSET_ACI_CMD_T_SEND_DATA_ACK + OFFSET_ACI_CMD_PARAMS_SEND_DATA_ACK_T_PIPE_NUMBER) = pipe_number;\r
+}\r
+\r
+void acil_encode_cmd_send_data_nack(uint8_t *buffer, const uint8_t pipe_number, const uint8_t err_code )\r
+{\r
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_NACK_LEN;\r
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_SEND_DATA_NACK;\r
+  *(buffer + OFFSET_ACI_CMD_T_SEND_DATA_NACK + OFFSET_ACI_CMD_PARAMS_SEND_DATA_NACK_T_PIPE_NUMBER) = pipe_number;\r
+  *(buffer + OFFSET_ACI_CMD_T_SEND_DATA_NACK + OFFSET_ACI_CMD_PARAMS_SEND_DATA_NACK_T_ERROR_CODE) = err_code;\r
+}\r
+\r
+void acil_encode_cmd_bond_security_request(uint8_t *buffer)\r
+{\r
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = 1;\r
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_BOND_SECURITY_REQUEST;\r
+}\r
+\r
+void acil_encode_cmd_broadcast(uint8_t *buffer, aci_cmd_params_broadcast_t * p_aci_cmd_params_broadcast)\r
+{\r
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_BROADCAST_LEN;\r
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_BROADCAST;\r
+  *(buffer + OFFSET_ACI_CMD_T_BROADCAST + OFFSET_ACI_CMD_PARAMS_BROADCAST_T_TIMEOUT_LSB) = (p_aci_cmd_params_broadcast->timeout & 0xff);\r
+  *(buffer + OFFSET_ACI_CMD_T_BROADCAST + OFFSET_ACI_CMD_PARAMS_BROADCAST_T_TIMEOUT_MSB) = (uint8_t)(p_aci_cmd_params_broadcast->timeout >> 8);\r
+  *(buffer + OFFSET_ACI_CMD_T_BROADCAST + OFFSET_ACI_CMD_PARAMS_BROADCAST_T_ADV_INTERVAL_LSB) = (p_aci_cmd_params_broadcast->adv_interval & 0xff);\r
+  *(buffer + OFFSET_ACI_CMD_T_BROADCAST + OFFSET_ACI_CMD_PARAMS_BROADCAST_T_ADV_INTERVAL_MSB) = (uint8_t)(p_aci_cmd_params_broadcast->adv_interval >> 8);\r
+}\r
+\r
+void acil_encode_cmd_open_adv_pipes(uint8_t *buffer, aci_cmd_params_open_adv_pipe_t * p_aci_cmd_params_open_adv_pipe)\r
+{\r
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_OPEN_ADV_PIPES_LEN;\r
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_OPEN_ADV_PIPE;\r
+  memcpy(buffer + OFFSET_ACI_CMD_T_OPEN_ADV_PIPE + OFFSET_ACI_CMD_PARAMS_OPEN_ADV_PIPE_T_PIPES, p_aci_cmd_params_open_adv_pipe->pipes, 8);\r
+}\r
+\r
+\r
+void acil_encode_cmd_set_key(uint8_t *buffer, aci_cmd_params_set_key_t *p_aci_cmd_params_set_key)\r
+{\r
+  /*\r
+  The length of the key is computed based on the type of key transaction.\r
+  - Key Reject\r
+  - Key type is passkey\r
+  */\r
+  uint8_t len;\r
+\r
+  switch (p_aci_cmd_params_set_key->key_type)\r
+  {\r
+    case ACI_KEY_TYPE_INVALID:\r
+    len = MSG_SET_KEY_REJECT_LEN;\r
+    break;\r
+    case ACI_KEY_TYPE_PASSKEY:\r
+    len = MSG_SET_KEY_PASSKEY_LEN;\r
+    break;\r
+    default:\r
+    len=0;\r
+    break;\r
+  }\r
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = len;\r
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_SET_KEY;\r
+  *(buffer + OFFSET_ACI_CMD_T_SET_KEY + OFFSET_ACI_CMD_PARAMS_SET_KEY_T_KEY_TYPE) = p_aci_cmd_params_set_key->key_type;\r
+  memcpy((buffer + OFFSET_ACI_CMD_T_SET_KEY + OFFSET_ACI_CMD_PARAMS_SET_KEY_T_PASSKEY), (uint8_t * )&(p_aci_cmd_params_set_key->key), len-2);//Reducing 2 for the opcode byte and type\r
+}\r
+\r
+bool acil_encode_cmd(uint8_t *buffer, aci_cmd_t *p_aci_cmd)\r
+{\r
+  bool ret_val = false;\r
+\r
+  switch(p_aci_cmd->cmd_opcode)\r
+  {\r
+    case ACI_CMD_TEST:\r
+      acil_encode_cmd_set_test_mode(buffer, &(p_aci_cmd->params.test));\r
+      break;\r
+    case ACI_CMD_SLEEP:\r
+      acil_encode_cmd_sleep(buffer);\r
+      break;\r
+    case ACI_CMD_GET_DEVICE_VERSION:\r
+      acil_encode_cmd_get_device_version(buffer);\r
+      break;\r
+    case ACI_CMD_WAKEUP:\r
+      acil_encode_cmd_wakeup(buffer);\r
+      break;\r
+    case ACI_CMD_ECHO:\r
+      acil_encode_cmd_echo_msg(buffer, &(p_aci_cmd->params.echo), (p_aci_cmd->len - MSG_ECHO_MSG_CMD_BASE_LEN));\r
+      break;\r
+    case ACI_CMD_GET_BATTERY_LEVEL:\r
+      acil_encode_cmd_battery_level(buffer);\r
+      break;\r
+    case ACI_CMD_GET_TEMPERATURE:\r
+      acil_encode_cmd_temparature(buffer);\r
+      break;\r
+    case ACI_CMD_GET_DEVICE_ADDRESS:\r
+      acil_encode_cmd_get_address(buffer);\r
+      break;\r
+    case ACI_CMD_SET_TX_POWER:\r
+      acil_encode_cmd_set_radio_tx_power(buffer, &(p_aci_cmd->params.set_tx_power));\r
+      break;\r
+    case ACI_CMD_CONNECT:\r
+      acil_encode_cmd_connect(buffer, &(p_aci_cmd->params.connect));\r
+      break;\r
+    case ACI_CMD_BOND:\r
+      acil_encode_cmd_bond(buffer, &(p_aci_cmd->params.bond));\r
+      break;\r
+    case ACI_CMD_DISCONNECT:\r
+      acil_encode_cmd_disconnect(buffer, &(p_aci_cmd->params.disconnect));\r
+      break;\r
+    case ACI_CMD_RADIO_RESET:\r
+      acil_encode_baseband_reset(buffer);\r
+      break;\r
+    case ACI_CMD_CHANGE_TIMING:\r
+      acil_encode_cmd_change_timing_req(buffer, &(p_aci_cmd->params.change_timing));\r
+      break;\r
+    case ACI_CMD_SETUP:\r
+      acil_encode_cmd_setup(buffer, &(p_aci_cmd->params.setup), (p_aci_cmd->len - MSG_SETUP_CMD_BASE_LEN));\r
+      break;\r
+    case ACI_CMD_DTM_CMD:\r
+      acil_encode_cmd_dtm_cmd(buffer, &(p_aci_cmd->params.dtm_cmd));\r
+      break;\r
+    case ACI_CMD_READ_DYNAMIC_DATA:\r
+      acil_encode_cmd_read_dynamic_data(buffer);\r
+      break;\r
+    case ACI_CMD_WRITE_DYNAMIC_DATA:\r
+      acil_encode_cmd_write_dynamic_data(buffer, p_aci_cmd->params.write_dynamic_data.seq_no, &(p_aci_cmd->params.write_dynamic_data.dynamic_data[0]), (p_aci_cmd->len - MSG_WRITE_DYNAMIC_DATA_BASE_LEN));\r
+      break;\r
+    case ACI_CMD_OPEN_REMOTE_PIPE:\r
+      acil_encode_cmd_open_remote_pipe(buffer, &(p_aci_cmd->params.open_remote_pipe));\r
+      break;\r
+    case ACI_CMD_SEND_DATA:\r
+      acil_encode_cmd_send_data(buffer, &(p_aci_cmd->params.send_data), (p_aci_cmd->len - MSG_SEND_DATA_BASE_LEN));\r
+      break;\r
+    case ACI_CMD_SEND_DATA_ACK:\r
+      acil_encode_cmd_send_data_ack(buffer, p_aci_cmd->params.send_data_ack.pipe_number );\r
+      break;\r
+    case ACI_CMD_REQUEST_DATA:\r
+      acil_encode_cmd_request_data(buffer, &(p_aci_cmd->params.request_data));\r
+      break;\r
+    case ACI_CMD_SET_LOCAL_DATA:\r
+      acil_encode_cmd_set_local_data(buffer, (aci_cmd_params_set_local_data_t *)(&(p_aci_cmd->params.send_data)), (p_aci_cmd->len - MSG_SET_LOCAL_DATA_BASE_LEN));\r
+      break;\r
+    case ACI_CMD_BOND_SECURITY_REQUEST:\r
+      acil_encode_cmd_bond_security_request(buffer);\r
+      break;\r
+    default:\r
+      break;\r
+  }\r
+  return ret_val;\r
+}\r
+\r
+void acil_decode_evt_command_response(uint8_t *buffer_in, aci_evt_params_cmd_rsp_t *p_evt_params_cmd_rsp)\r
+{\r
+  aci_evt_cmd_rsp_params_get_device_version_t *p_device_version;\r
+  aci_evt_cmd_rsp_params_get_device_address_t *p_device_address;\r
+  aci_evt_cmd_rsp_params_get_temperature_t    *p_temperature;\r
+  aci_evt_cmd_rsp_params_get_battery_level_t  *p_batt_lvl;\r
+  aci_evt_cmd_rsp_read_dynamic_data_t         *p_read_dyn_data;\r
+  aci_evt_cmd_rsp_params_dtm_cmd_t            *p_dtm_evt;\r
+\r
+  p_evt_params_cmd_rsp->cmd_opcode = (aci_cmd_opcode_t)*(buffer_in + OFFSET_ACI_EVT_T_CMD_RSP + OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_CMD_OPCODE);\r
+  p_evt_params_cmd_rsp->cmd_status = (aci_status_code_t)*(buffer_in + OFFSET_ACI_EVT_T_CMD_RSP + OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_CMD_STATUS);\r
+\r
+  switch (p_evt_params_cmd_rsp->cmd_opcode)\r
+  {\r
+    case ACI_CMD_GET_DEVICE_VERSION:\r
+      p_device_version = &(p_evt_params_cmd_rsp->params.get_device_version);\r
+      p_device_version->configuration_id  = (uint16_t)*(buffer_in + OFFSET_ACI_EVT_T_CMD_RSP + OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_DEVICE_VERSION + OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_CONFIGURATION_ID_LSB);\r
+      p_device_version->configuration_id |= (uint16_t)*(buffer_in + OFFSET_ACI_EVT_T_CMD_RSP + OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_DEVICE_VERSION + OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_CONFIGURATION_ID_MSB) << 8;\r
+      p_device_version->aci_version       = *(buffer_in + OFFSET_ACI_EVT_T_CMD_RSP + OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_DEVICE_VERSION + OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_ACI_VERSION);\r
+      p_device_version->setup_format      = *(buffer_in + OFFSET_ACI_EVT_T_CMD_RSP + OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_DEVICE_VERSION + OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_SETUP_FORMAT);\r
+      p_device_version->setup_id          = (uint32_t)*(buffer_in + OFFSET_ACI_EVT_T_CMD_RSP + OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_DEVICE_VERSION + OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_SETUP_ID_LSB0);\r
+      p_device_version->setup_id         |= (uint32_t)*(buffer_in + OFFSET_ACI_EVT_T_CMD_RSP + OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_DEVICE_VERSION + OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_SETUP_ID_LSB1) << 8;\r
+      p_device_version->setup_id         |= (uint32_t)*(buffer_in + OFFSET_ACI_EVT_T_CMD_RSP + OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_DEVICE_VERSION + OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_SETUP_ID_MSB0) << 16;\r
+      p_device_version->setup_id         |= (uint32_t)*(buffer_in + OFFSET_ACI_EVT_T_CMD_RSP + OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_DEVICE_VERSION + OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_SETUP_ID_MSB1) << 24;\r
+      p_device_version->setup_status      = *(buffer_in + OFFSET_ACI_EVT_T_CMD_RSP + OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_DEVICE_VERSION + OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_SETUP_STATUS);\r
+      break;\r
+\r
+    case ACI_CMD_GET_DEVICE_ADDRESS:\r
+      p_device_address = &(p_evt_params_cmd_rsp->params.get_device_address);\r
+      memcpy((uint8_t *)(p_device_address->bd_addr_own), (buffer_in + OFFSET_ACI_EVT_T_CMD_RSP+OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_DEVICE_ADDRESS+OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_ADDRESS_T_BD_ADDR_OWN), BTLE_DEVICE_ADDRESS_SIZE);\r
+      p_device_address->bd_addr_type = (aci_bd_addr_type_t) *(buffer_in + OFFSET_ACI_EVT_T_CMD_RSP+OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_DEVICE_ADDRESS+OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_ADDRESS_T_BD_ADDR_TYPE);\r
+      break;\r
+\r
+    case ACI_CMD_GET_TEMPERATURE:\r
+      p_temperature = &(p_evt_params_cmd_rsp->params.get_temperature);\r
+      p_temperature->temperature_value =  (int16_t)*(buffer_in + OFFSET_ACI_EVT_T_CMD_RSP + OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_TEMPERATURE + OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_TEMPERATURE_T_TEMPERATURE_VALUE_LSB);\r
+      p_temperature->temperature_value |= (int16_t)*(buffer_in + OFFSET_ACI_EVT_T_CMD_RSP + OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_TEMPERATURE + OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_TEMPERATURE_T_TEMPERATURE_VALUE_MSB) << 8;\r
+      break;\r
+\r
+    case ACI_CMD_GET_BATTERY_LEVEL:\r
+      p_batt_lvl = &(p_evt_params_cmd_rsp->params.get_battery_level);\r
+      p_batt_lvl->battery_level =  (int16_t)*(buffer_in + OFFSET_ACI_EVT_T_CMD_RSP + OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_BATTERY_LEVEL + OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_BATTERY_LEVEL_T_BATTERY_LEVEL_LSB);\r
+      p_batt_lvl->battery_level |= (int16_t)*(buffer_in + OFFSET_ACI_EVT_T_CMD_RSP + OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_BATTERY_LEVEL + OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_BATTERY_LEVEL_T_BATTERY_LEVEL_MSB) << 8;\r
+      break;\r
+\r
+    case ACI_CMD_READ_DYNAMIC_DATA:\r
+      p_read_dyn_data = &(p_evt_params_cmd_rsp->params.read_dynamic_data);\r
+      p_read_dyn_data->seq_no =  (uint8_t)*(buffer_in + OFFSET_ACI_EVT_T_CMD_RSP + OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_READ_DYNAMIC_DATA + OFFSET_ACI_EVT_CMD_RSP_READ_DYNAMIC_DATA_T_SEQ_NO);\r
+      memcpy((uint8_t *)(p_read_dyn_data->dynamic_data), (buffer_in + OFFSET_ACI_EVT_T_CMD_RSP + OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_READ_DYNAMIC_DATA + OFFSET_ACI_CMD_PARAMS_WRITE_DYNAMIC_DATA_T_DYNAMIC_DATA), ACIL_DECODE_EVT_GET_LENGTH(buffer_in) - 3); // 3 bytes subtracted account for EventCode, CommandOpCode and Status bytes.\r
+      // Now that the p_read_dyn_data->dynamic_data will be pointing to memory location with enough space to accommodate upto 27 bytes of dynamic data received. This is because of the padding element in aci_evt_params_cmd_rsp_t\r
+      break;\r
+\r
+    case ACI_CMD_DTM_CMD:\r
+      p_dtm_evt = &(p_evt_params_cmd_rsp->params.dtm_cmd);\r
+      p_dtm_evt->evt_msb = (uint8_t)*(buffer_in + OFFSET_ACI_EVT_T_CMD_RSP + OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_DTM_CMD + OFFSET_ACI_EVT_CMD_RSP_PARAMS_DTM_CMD_T_EVT_MSB);\r
+      p_dtm_evt->evt_lsb = (uint8_t)*(buffer_in + OFFSET_ACI_EVT_T_CMD_RSP + OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_DTM_CMD + OFFSET_ACI_EVT_CMD_RSP_PARAMS_DTM_CMD_T_EVT_LSB);\r
+      break;\r
+  }\r
+}\r
+\r
+void acil_decode_evt_device_started(uint8_t *buffer_in, aci_evt_params_device_started_t *p_evt_params_device_started)\r
+{\r
+  p_evt_params_device_started->device_mode = (aci_device_operation_mode_t) *(buffer_in + OFFSET_ACI_EVT_T_DEVICE_STARTED+OFFSET_ACI_EVT_PARAMS_DEVICE_STARTED_T_DEVICE_MODE);\r
+  p_evt_params_device_started->hw_error = (aci_hw_error_t) *(buffer_in + OFFSET_ACI_EVT_T_DEVICE_STARTED+OFFSET_ACI_EVT_PARAMS_DEVICE_STARTED_T_HW_ERROR);\r
+  p_evt_params_device_started->credit_available = *(buffer_in + OFFSET_ACI_EVT_T_DEVICE_STARTED+OFFSET_ACI_EVT_PARAMS_DEVICE_STARTED_T_CREDIT_AVAILABLE);\r
+}\r
+\r
+void acil_decode_evt_pipe_status(uint8_t *buffer_in, aci_evt_params_pipe_status_t *p_aci_evt_params_pipe_status)\r
+{\r
+  memcpy((uint8_t *)p_aci_evt_params_pipe_status->pipes_open_bitmap, (buffer_in + OFFSET_ACI_EVT_T_PIPE_STATUS + OFFSET_ACI_EVT_PARAMS_PIPE_STATUS_T_PIPES_OPEN_BITMAP), 8);\r
+  memcpy((uint8_t *)p_aci_evt_params_pipe_status->pipes_closed_bitmap, (buffer_in + OFFSET_ACI_EVT_T_PIPE_STATUS + OFFSET_ACI_EVT_PARAMS_PIPE_STATUS_T_PIPES_CLOSED_BITMAP), 8);\r
+}\r
+\r
+void acil_decode_evt_disconnected(uint8_t *buffer_in, aci_evt_params_disconnected_t *p_aci_evt_params_disconnected)\r
+{\r
+  p_aci_evt_params_disconnected->aci_status = (aci_status_code_t)*(buffer_in + OFFSET_ACI_EVT_T_DISCONNECTED + OFFSET_ACI_EVT_PARAMS_DISCONNECTED_T_ACI_STATUS);\r
+  p_aci_evt_params_disconnected->btle_status = *(buffer_in + OFFSET_ACI_EVT_T_DISCONNECTED + OFFSET_ACI_EVT_PARAMS_DISCONNECTED_T_BTLE_STATUS);\r
+}\r
+\r
+void acil_decode_evt_bond_status(uint8_t *buffer_in, aci_evt_params_bond_status_t *p_aci_evt_params_bond_status)\r
+{\r
+  p_aci_evt_params_bond_status->status_code = (aci_bond_status_code_t)*(buffer_in + OFFSET_ACI_EVT_T_BOND_STATUS + OFFSET_ACI_EVT_PARAMS_BOND_STATUS_T_STATUS_CODE);\r
+  p_aci_evt_params_bond_status->status_source = (aci_bond_status_source_t)*(buffer_in + OFFSET_ACI_EVT_T_BOND_STATUS + OFFSET_ACI_EVT_PARAMS_BOND_STATUS_T_STATUS_SOURCE);\r
+  p_aci_evt_params_bond_status->secmode1_bitmap = *(buffer_in + OFFSET_ACI_EVT_T_BOND_STATUS + OFFSET_ACI_EVT_PARAMS_BOND_STATUS_T_SECMODE1_BITMAP);\r
+  p_aci_evt_params_bond_status->secmode2_bitmap = *(buffer_in + OFFSET_ACI_EVT_T_BOND_STATUS + OFFSET_ACI_EVT_PARAMS_BOND_STATUS_T_SECMODE2_BITMAP);\r
+  p_aci_evt_params_bond_status->keys_exchanged_slave = *(buffer_in + OFFSET_ACI_EVT_T_BOND_STATUS + OFFSET_ACI_EVT_PARAMS_BOND_STATUS_T_KEYS_EXCHANGED_SLAVE);\r
+  p_aci_evt_params_bond_status->keys_exchanged_master = *(buffer_in + OFFSET_ACI_EVT_T_BOND_STATUS + OFFSET_ACI_EVT_PARAMS_BOND_STATUS_T_KEYS_EXCHANGED_MASTER);\r
+}\r
+\r
+uint8_t acil_decode_evt_data_received(uint8_t *buffer_in, aci_evt_params_data_received_t *p_evt_params_data_received)\r
+{\r
+  uint8_t size = *( buffer_in + OFFSET_ACI_EVT_T_LEN) - (OFFSET_ACI_EVT_T_DATA_RECEIVED + OFFSET_ACI_RX_DATA_T_ACI_DATA) + 1 ;\r
+  p_evt_params_data_received->rx_data.pipe_number = *(buffer_in + OFFSET_ACI_EVT_T_DATA_RECEIVED + OFFSET_ACI_RX_DATA_T_PIPE_NUMBER);\r
+  memcpy((uint8_t *)p_evt_params_data_received->rx_data.aci_data, (buffer_in + OFFSET_ACI_EVT_T_DATA_RECEIVED + OFFSET_ACI_RX_DATA_T_ACI_DATA), size);\r
+  return size;\r
+}\r
+\r
+void acil_decode_evt_data_ack(uint8_t *buffer_in, aci_evt_params_data_ack_t *p_evt_params_data_ack)\r
+{\r
+  p_evt_params_data_ack->pipe_number = *(buffer_in + OFFSET_ACI_EVT_T_DATA_ACK + OFFSET_ACI_EVT_PARAMS_DATA_ACK_T_PIPE_NUMBER);\r
+}\r
+\r
+uint8_t acil_decode_evt_hw_error(uint8_t *buffer_in, aci_evt_params_hw_error_t *p_aci_evt_params_hw_error)\r
+{\r
+  uint8_t size = *(buffer_in + OFFSET_ACI_EVT_T_LEN) - (OFFSET_ACI_EVT_T_HW_ERROR + OFFSET_ACI_EVT_PARAMS_HW_ERROR_T_FILE_NAME) + 1;\r
+  p_aci_evt_params_hw_error->line_num = (uint16_t)(*(buffer_in + OFFSET_ACI_EVT_T_HW_ERROR + OFFSET_ACI_EVT_PARAMS_HW_ERROR_T_LINE_NUM_MSB)) << 8;\r
+  p_aci_evt_params_hw_error->line_num |= (uint16_t)*(buffer_in + OFFSET_ACI_EVT_T_HW_ERROR + OFFSET_ACI_EVT_PARAMS_HW_ERROR_T_LINE_NUM_LSB);\r
+  memcpy((uint8_t *)p_aci_evt_params_hw_error->file_name, (buffer_in + OFFSET_ACI_EVT_T_HW_ERROR + OFFSET_ACI_EVT_PARAMS_HW_ERROR_T_FILE_NAME), size);\r
+  return size;\r
+}\r
+\r
+void acil_decode_evt_credit(uint8_t *buffer_in, aci_evt_params_data_credit_t *p_evt_params_data_credit)\r
+{\r
+  p_evt_params_data_credit->credit = *(buffer_in + OFFSET_ACI_EVT_T_DATA_CREDIT + OFFSET_ACI_EVT_PARAMS_DATA_CREDIT_T_CREDIT);\r
+}\r
+\r
+void acil_decode_evt_connected(uint8_t *buffer_in, aci_evt_params_connected_t *p_aci_evt_params_connected)\r
+{\r
+  p_aci_evt_params_connected->dev_addr_type = (aci_bd_addr_type_t)*(buffer_in + OFFSET_ACI_EVT_T_CONNECTED + OFFSET_ACI_EVT_PARAMS_CONNECTED_T_DEV_ADDR_TYPE);\r
+  memcpy(&(p_aci_evt_params_connected->dev_addr[0]), (buffer_in + OFFSET_ACI_EVT_T_CONNECTED + OFFSET_ACI_EVT_PARAMS_CONNECTED_T_DEV_ADDR), BTLE_DEVICE_ADDRESS_SIZE);\r
+  p_aci_evt_params_connected->conn_rf_interval       = (uint16_t)*(buffer_in + OFFSET_ACI_EVT_T_CONNECTED + OFFSET_ACI_EVT_PARAMS_CONNECTED_T_CONN_RF_INTERVAL_MSB) << 8;\r
+  p_aci_evt_params_connected->conn_rf_interval      |= (uint16_t)*(buffer_in + OFFSET_ACI_EVT_T_CONNECTED + OFFSET_ACI_EVT_PARAMS_CONNECTED_T_CONN_RF_INTERVAL_LSB);\r
+  p_aci_evt_params_connected->conn_slave_rf_latency  = (uint16_t)*(buffer_in + OFFSET_ACI_EVT_T_CONNECTED + OFFSET_ACI_EVT_PARAMS_CONNECTED_T_CONN_SLAVE_RF_LATENCY_MSB) << 8;\r
+  p_aci_evt_params_connected->conn_slave_rf_latency |= (uint16_t)*(buffer_in + OFFSET_ACI_EVT_T_CONNECTED + OFFSET_ACI_EVT_PARAMS_CONNECTED_T_CONN_SLAVE_RF_LATENCY_LSB);\r
+  p_aci_evt_params_connected->conn_rf_timeout        = (uint16_t)*(buffer_in + OFFSET_ACI_EVT_T_CONNECTED + OFFSET_ACI_EVT_PARAMS_CONNECTED_T_CONN_RF_TIMEOUT_MSB) << 8;\r
+  p_aci_evt_params_connected->conn_rf_timeout       |= (uint16_t)*(buffer_in + OFFSET_ACI_EVT_T_CONNECTED + OFFSET_ACI_EVT_PARAMS_CONNECTED_T_CONN_RF_TIMEOUT_LSB);\r
+  p_aci_evt_params_connected->master_clock_accuracy  = (aci_clock_accuracy_t)*(buffer_in + OFFSET_ACI_EVT_T_CONNECTED + OFFSET_ACI_EVT_PARAMS_CONNECTED_T_MASTER_CLOCK_ACCURACY);\r
+\r
+}\r
+\r
+void acil_decode_evt_timing(uint8_t *buffer_in, aci_evt_params_timing_t *p_evt_params_timing)\r
+{\r
+  p_evt_params_timing->conn_rf_interval       = *(buffer_in + OFFSET_ACI_EVT_T_TIMING + OFFSET_ACI_EVT_PARAMS_TIMING_T_CONN_RF_INTERVAL_MSB) << 8;\r
+  p_evt_params_timing->conn_rf_interval      |= (uint16_t)*(buffer_in + OFFSET_ACI_EVT_T_TIMING + OFFSET_ACI_EVT_PARAMS_TIMING_T_CONN_RF_INTERVAL_LSB);\r
+  p_evt_params_timing->conn_slave_rf_latency  = (uint16_t)*(buffer_in + OFFSET_ACI_EVT_T_TIMING + OFFSET_ACI_EVT_PARAMS_TIMING_T_CONN_SLAVE_RF_LATENCY_MSB) << 8;\r
+  p_evt_params_timing->conn_slave_rf_latency |= (uint16_t)*(buffer_in + OFFSET_ACI_EVT_T_TIMING + OFFSET_ACI_EVT_PARAMS_TIMING_T_CONN_SLAVE_RF_LATENCY_LSB);\r
+  p_evt_params_timing->conn_rf_timeout        = (uint16_t)*(buffer_in + OFFSET_ACI_EVT_T_TIMING + OFFSET_ACI_EVT_PARAMS_TIMING_T_CONN_RF_TIMEOUT_MSB) << 8;\r
+  p_evt_params_timing->conn_rf_timeout       |= *(buffer_in + OFFSET_ACI_EVT_T_TIMING + OFFSET_ACI_EVT_PARAMS_TIMING_T_CONN_RF_TIMEOUT_LSB);\r
+}\r
+\r
+void acil_decode_evt_pipe_error(uint8_t *buffer_in, aci_evt_params_pipe_error_t *p_evt_params_pipe_error)\r
+{\r
+  //volatile uint8_t size = *(buffer_in + OFFSET_ACI_EVT_T_LEN) - (OFFSET_ACI_EVT_T_PIPE_ERROR + OFFSET_ACI_EVT_PARAMS_PIPE_ERROR_T_ERROR_DATA) + 1;\r
+  p_evt_params_pipe_error->pipe_number = *(buffer_in + OFFSET_ACI_EVT_T_PIPE_ERROR + OFFSET_ACI_EVT_PARAMS_PIPE_ERROR_T_PIPE_NUMBER);\r
+  p_evt_params_pipe_error->error_code = *(buffer_in + OFFSET_ACI_EVT_T_PIPE_ERROR + OFFSET_ACI_EVT_PARAMS_PIPE_ERROR_T_ERROR_CODE);\r
+  p_evt_params_pipe_error->params.error_data.content[0] = *(buffer_in + OFFSET_ACI_EVT_T_PIPE_ERROR + OFFSET_ACI_EVT_PARAMS_PIPE_ERROR_T_ERROR_DATA + OFFSET_ERROR_DATA_T_CONTENT);\r
+}\r
+\r
+void acil_decode_evt_key_request(uint8_t *buffer_in, aci_evt_params_key_request_t *p_evt_params_key_request)\r
+{\r
+  p_evt_params_key_request->key_type = (aci_key_type_t)*(buffer_in + OFFSET_ACI_EVT_T_KEY_REQUEST + OFFSET_ACI_EVT_PARAMS_KEY_REQUEST_T_KEY_TYPE);\r
+}\r
+\r
+uint8_t acil_decode_evt_echo(uint8_t *buffer_in, aci_evt_params_echo_t *aci_evt_params_echo)\r
+{\r
+  uint8_t size = *(buffer_in + OFFSET_ACI_EVT_T_LEN) - 1;\r
+  memcpy(&aci_evt_params_echo->echo_data[0], (buffer_in + OFFSET_ACI_EVT_T_EVT_OPCODE + 1), size);\r
+  return size;\r
+}\r
+\r
+void acil_decode_evt_display_passkey(uint8_t *buffer_in, aci_evt_params_display_passkey_t *p_aci_evt_params_display_passkey)\r
+{\r
+  p_aci_evt_params_display_passkey->passkey[0] = *(buffer_in + OFFSET_ACI_EVT_T_DISPLAY_PASSKEY +  OFFSET_ACI_EVT_PARAMS_DISPLAY_PASSKEY_T_PASSKEY + 0);\r
+  p_aci_evt_params_display_passkey->passkey[1] = *(buffer_in + OFFSET_ACI_EVT_T_DISPLAY_PASSKEY +  OFFSET_ACI_EVT_PARAMS_DISPLAY_PASSKEY_T_PASSKEY + 1);\r
+  p_aci_evt_params_display_passkey->passkey[2] = *(buffer_in + OFFSET_ACI_EVT_T_DISPLAY_PASSKEY +  OFFSET_ACI_EVT_PARAMS_DISPLAY_PASSKEY_T_PASSKEY + 2);\r
+  p_aci_evt_params_display_passkey->passkey[3] = *(buffer_in + OFFSET_ACI_EVT_T_DISPLAY_PASSKEY +  OFFSET_ACI_EVT_PARAMS_DISPLAY_PASSKEY_T_PASSKEY + 3);\r
+  p_aci_evt_params_display_passkey->passkey[4] = *(buffer_in + OFFSET_ACI_EVT_T_DISPLAY_PASSKEY +  OFFSET_ACI_EVT_PARAMS_DISPLAY_PASSKEY_T_PASSKEY + 4);\r
+  p_aci_evt_params_display_passkey->passkey[5] = *(buffer_in + OFFSET_ACI_EVT_T_DISPLAY_PASSKEY +  OFFSET_ACI_EVT_PARAMS_DISPLAY_PASSKEY_T_PASSKEY + 5);\r
+}\r
+\r
+bool acil_decode_evt(uint8_t *buffer_in, aci_evt_t *p_aci_evt)\r
+{\r
+  bool ret_val = true;\r
+\r
+  p_aci_evt->len = ACIL_DECODE_EVT_GET_LENGTH(buffer_in);\r
+  p_aci_evt->evt_opcode = (aci_evt_opcode_t)ACIL_DECODE_EVT_GET_OPCODE(buffer_in);\r
+\r
+  switch(p_aci_evt->evt_opcode)\r
+  {\r
+    case ACI_EVT_DEVICE_STARTED:\r
+      acil_decode_evt_device_started(buffer_in, &(p_aci_evt->params.device_started));\r
+      break;\r
+    case ACI_EVT_HW_ERROR:\r
+      acil_decode_evt_hw_error(buffer_in, &(p_aci_evt->params.hw_error));\r
+      break;\r
+    case ACI_EVT_CMD_RSP:\r
+      acil_decode_evt_command_response(buffer_in, &(p_aci_evt->params.cmd_rsp));\r
+      break;\r
+    case ACI_EVT_DATA_CREDIT:\r
+      acil_decode_evt_credit(buffer_in, &(p_aci_evt->params.data_credit));\r
+      break;\r
+    case ACI_EVT_CONNECTED:\r
+      acil_decode_evt_connected(buffer_in, &(p_aci_evt->params.connected));\r
+      break;\r
+    case ACI_EVT_PIPE_STATUS:\r
+      acil_decode_evt_pipe_status(buffer_in, &(p_aci_evt->params.pipe_status));\r
+      break;\r
+    case ACI_EVT_DISCONNECTED:\r
+      acil_decode_evt_disconnected(buffer_in, &(p_aci_evt->params.disconnected));\r
+      break;\r
+    case ACI_EVT_BOND_STATUS:\r
+      acil_decode_evt_bond_status(buffer_in, &(p_aci_evt->params.bond_status));\r
+      break;\r
+    case ACI_EVT_TIMING:\r
+      acil_decode_evt_timing(buffer_in, &(p_aci_evt->params.timing));\r
+      break;\r
+    case ACI_EVT_DATA_ACK:\r
+      acil_decode_evt_data_ack(buffer_in, &(p_aci_evt->params.data_ack));\r
+      break;\r
+    case ACI_EVT_DATA_RECEIVED:\r
+      acil_decode_evt_data_received(buffer_in, &(p_aci_evt->params.data_received));\r
+      break;\r
+    case ACI_EVT_PIPE_ERROR:\r
+      acil_decode_evt_pipe_error(buffer_in, &(p_aci_evt->params.pipe_error));\r
+      break;\r
+    case ACI_EVT_KEY_REQUEST:\r
+      acil_decode_evt_key_request(buffer_in, &(p_aci_evt->params.key_request));\r
+      break;\r
+    case ACI_EVT_DISPLAY_PASSKEY:\r
+      acil_decode_evt_display_passkey(buffer_in, &(p_aci_evt->params.display_passkey));\r
+      break;\r
+    default:\r
+      ret_val = false;\r
+      break;\r
+  }\r
+  return ret_val;\r
+}\r
diff --git a/src/nrf8001/acilib.h b/src/nrf8001/acilib.h
new file mode 100644 (file)
index 0000000..f152e75
--- /dev/null
@@ -0,0 +1,61 @@
+/* Copyright (c) 2014, Nordic Semiconductor ASA\r
+ *\r
+ * Permission is hereby granted, free of charge, to any person obtaining a copy\r
+ * of this software and associated documentation files (the "Software"), to deal\r
+ * in the Software without restriction, including without limitation the rights\r
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+ * copies of the Software, and to permit persons to whom the Software is\r
+ * furnished to do so, subject to the following conditions:\r
+ *\r
+ * The above copyright notice and this permission notice shall be included in all\r
+ * copies or substantial portions of the Software.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ */\r
+\r
+/**\r
+ * @file\r
+ *\r
+ * @ingroup group_acilib\r
+ *\r
+ * @brief Internal prototype for acilib module.\r
+ */\r
+\r
+#ifndef _acilib_H_\r
+#define _acilib_H_\r
+\r
+#define MSG_SET_LOCAL_DATA_BASE_LEN              2\r
+#define MSG_CONNECT_LEN                          5\r
+#define MSG_BOND_LEN                             5\r
+#define MSG_DISCONNECT_LEN                       2\r
+#define MSG_BASEBAND_RESET_LEN                   1\r
+#define MSG_WAKEUP_LEN                           1\r
+#define MSG_SET_RADIO_TX_POWER_LEN               2\r
+#define MSG_GET_DEVICE_ADDR_LEN                  1\r
+#define MSG_SEND_DATA_BASE_LEN                   2\r
+#define MSG_DATA_REQUEST_LEN                     2\r
+#define MSG_OPEN_REMOTE_PIPE_LEN                 2\r
+#define MSG_CLOSE_REMOTE_PIPE_LEN                2\r
+#define MSG_DTM_CMD                              3\r
+#define MSG_WRITE_DYNAMIC_DATA_BASE_LEN          2\r
+#define MSG_SETUP_CMD_BASE_LEN                   1\r
+#define MSG_ECHO_MSG_CMD_BASE_LEN                1\r
+#define MSG_CHANGE_TIMING_LEN                    9\r
+#define MSG_SET_APP_LATENCY_LEN                  4\r
+#define MSG_CHANGE_TIMING_LEN_GAP_PPCP           1\r
+#define MSG_DIRECT_CONNECT_LEN                   1\r
+#define MSG_SET_KEY_REJECT_LEN                   2\r
+#define MSG_SET_KEY_PASSKEY_LEN                  8\r
+#define MSG_SET_KEY_OOB_LEN                      18\r
+#define MSG_ACK_LEN                              2\r
+#define MSG_NACK_LEN                             3\r
+#define MSG_BROADCAST_LEN                        5\r
+#define MSG_OPEN_ADV_PIPES_LEN                   9\r
+\r
+#endif /* _acilib_H_ */\r
diff --git a/src/nrf8001/acilib_defs.h b/src/nrf8001/acilib_defs.h
new file mode 100644 (file)
index 0000000..dc64d86
--- /dev/null
@@ -0,0 +1,37 @@
+/* Copyright (c) 2014, Nordic Semiconductor ASA\r
+ *\r
+ * Permission is hereby granted, free of charge, to any person obtaining a copy\r
+ * of this software and associated documentation files (the "Software"), to deal\r
+ * in the Software without restriction, including without limitation the rights\r
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+ * copies of the Software, and to permit persons to whom the Software is\r
+ * furnished to do so, subject to the following conditions:\r
+ *\r
+ * The above copyright notice and this permission notice shall be included in all\r
+ * copies or substantial portions of the Software.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ */\r
+\r
+/**\r
+ * @file\r
+ *\r
+ * @ingroup group_acilib\r
+ *\r
+ * @brief Definitions for the acilib interfaces\r
+ */\r
+\r
+#ifndef _acilib_DEFS_H_\r
+#define _acilib_DEFS_H_\r
+\r
+#define ACIL_DECODE_EVT_GET_LENGTH(buffer_in) (*(buffer_in + OFFSET_ACI_EVT_T_LEN))\r
+\r
+#define ACIL_DECODE_EVT_GET_OPCODE(buffer_in) (*(buffer_in + OFFSET_ACI_EVT_T_EVT_OPCODE))\r
+\r
+#endif /* _acilib_DEFS_H_ */\r
diff --git a/src/nrf8001/acilib_if.h b/src/nrf8001/acilib_if.h
new file mode 100644 (file)
index 0000000..1413094
--- /dev/null
@@ -0,0 +1,471 @@
+/* Copyright (c) 2014, Nordic Semiconductor ASA\r
+ *\r
+ * Permission is hereby granted, free of charge, to any person obtaining a copy\r
+ * of this software and associated documentation files (the "Software"), to deal\r
+ * in the Software without restriction, including without limitation the rights\r
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+ * copies of the Software, and to permit persons to whom the Software is\r
+ * furnished to do so, subject to the following conditions:\r
+ *\r
+ * The above copyright notice and this permission notice shall be included in all\r
+ * copies or substantial portions of the Software.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ */\r
+\r
+/**\r
+ * @file\r
+ *\r
+ * @ingroup group_acilib\r
+ *\r
+ * @brief Prototypes for the acilib interfaces.\r
+ */\r
+\r
+#ifndef _acilib_IF_H_\r
+#define _acilib_IF_H_\r
+\r
+/** @brief Encode the ACI message for set test mode command\r
+ *\r
+ *  @param[in,out]  buffer      Pointer to ACI message buffer\r
+ *  @param[in]      test_mode   Pointer to the test mode in ::aci_cmd_params_test_t\r
+ *\r
+ *  @return         None\r
+ */\r
+void acil_encode_cmd_set_test_mode(uint8_t *buffer, aci_cmd_params_test_t *p_aci_cmd_params_test);\r
+\r
+/** @brief Encode the ACI message for sleep command\r
+ *\r
+ *  @param[in,out]  buffer      Pointer to ACI message buffer\r
+ *\r
+ *  @return         None\r
+ */\r
+void acil_encode_cmd_sleep(uint8_t *buffer);\r
+\r
+/** @brief Encode the ACI message for get device version\r
+ *\r
+ *  @param[in,out]  buffer      Pointer to ACI message buffer\r
+ *\r
+ *  @return         None\r
+ */\r
+void acil_encode_cmd_get_device_version(uint8_t *buffer);\r
+\r
+/** @brief Encode the ACI message for set local data\r
+ *\r
+ *  @param[in,out]  buffer                           Pointer to ACI message buffer\r
+ *  @param[in]      p_aci_cmd_params_set_local_data  Pointer to the local data parameters in ::aci_cmd_params_set_local_data_t\r
+ *  @param[in]      data_size                        Size of data message\r
+ *\r
+ *  @return         None\r
+ */\r
+void acil_encode_cmd_set_local_data(uint8_t *buffer, aci_cmd_params_set_local_data_t *p_aci_cmd_params_set_local_data, uint8_t data_size);\r
+\r
+/** @brief Encode the ACI message to connect\r
+ *\r
+ *  @param[in,out]  buffer                    Pointer to ACI message buffer\r
+ *  @param[in]      p_aci_cmd_params_connect  Pointer to the run parameters in ::aci_cmd_params_connect_t\r
+ *\r
+ *  @return         None\r
+ */\r
+void acil_encode_cmd_connect(uint8_t *buffer, aci_cmd_params_connect_t *p_aci_cmd_params_connect);\r
+\r
+/** @brief Encode the ACI message to bond\r
+ *\r
+ *  @param[in,out]  buffer                 Pointer to ACI message buffer\r
+ *  @param[in]      p_aci_cmd_params_bond  Pointer to the run parameters in ::aci_cmd_params_bond_t\r
+ *\r
+ *  @return         None\r
+ */\r
+void acil_encode_cmd_bond(uint8_t *buffer, aci_cmd_params_bond_t *p_aci_cmd_params_bond);\r
+\r
+/** @brief Encode the ACI message to disconnect\r
+ *\r
+ *  @param[in,out]  buffer                       Pointer to ACI message buffer\r
+ *  @param[in]      p_aci_cmd_params_disconnect  Pointer to the run parameters in ::aci_cmd_params_disconnect_t\r
+ *\r
+ *  @return         None\r
+ */\r
+void acil_encode_cmd_disconnect(uint8_t *buffer, aci_cmd_params_disconnect_t *p_aci_cmd_params_disconnect);\r
+\r
+/** @brief Encode the ACI message to baseband reset\r
+ *\r
+ *  @param[in,out]  buffer        Pointer to ACI message buffer\r
+ *\r
+ *  @return         None\r
+ */\r
+ void acil_encode_baseband_reset(uint8_t *buffer);\r
+\r
+ /** @brief Encode the ACI message for Directed Advertising\r
+ *\r
+ *  @param[in,out]  buffer        Pointer to ACI message buffer\r
+ *\r
+ *  @return         None\r
+ */\r
+ void acil_encode_direct_connect(uint8_t *buffer);\r
+\r
+/** @brief Encode the ACI message to wakeup\r
+ *\r
+ *  @param[in,out]  buffer        Pointer to ACI message buffer\r
+ *\r
+ *  @return         None\r
+ */\r
+void acil_encode_cmd_wakeup(uint8_t *buffer);\r
+\r
+/** @brief Encode the ACI message for set radio Tx power\r
+ *\r
+ *  @param[in,out]  buffer                         Pointer to ACI message buffer\r
+ *  @param[in]      p_aci_cmd_params_set_tx_power  Pointer to the set Tx power parameters in ::aci_cmd_params_set_tx_power_t\r
+ *\r
+ *  @return         None\r
+ */\r
+void acil_encode_cmd_set_radio_tx_power(uint8_t *buffer, aci_cmd_params_set_tx_power_t *p_aci_cmd_params_set_tx_power);\r
+\r
+/** @brief Encode the ACI message for get device address\r
+ *\r
+ *  @param[in,out]  buffer            Pointer to ACI message buffer\r
+ *\r
+ *  @return         None\r
+ */\r
+void acil_encode_cmd_get_address(uint8_t *buffer);\r
+\r
+/** @brief Encode the ACI message for send data\r
+ *\r
+ *  @param[in,out]  buffer                        Pointer to ACI message buffer\r
+ *  @param[in]      p_aci_cmd_params_send_data_t  Pointer to the data parameters in ::aci_cmd_params_send_data_t\r
+ *  @param[in]      data_size                     Size of data message\r
+ *\r
+ *  @return         None\r
+ */\r
+void acil_encode_cmd_send_data(uint8_t *buffer, aci_cmd_params_send_data_t *p_aci_cmd_params_send_data_t, uint8_t data_size);\r
+\r
+/** @brief Encode the ACI message for request data\r
+ *\r
+ *  @param[in,out]  buffer                          Pointer to ACI message buffer\r
+ *  @param[in]      p_aci_cmd_params_request_data   Pointer to the request data parameters in ::aci_cmd_params_request_data_t\r
+ *\r
+ *  @return         None\r
+ */\r
+void acil_encode_cmd_request_data(uint8_t *buffer, aci_cmd_params_request_data_t *p_aci_cmd_params_request_data);\r
+\r
+/** @brief Encode the ACI message for open remote pipe\r
+ *\r
+ *  @param[in,out]  buffer                              Pointer to ACI message buffer\r
+ *  @param[in]      p_aci_cmd_params_open_remote_pipe   Pointer to the dynamic data parameters in ::aci_cmd_params_open_remote_pipe_t\r
+ *\r
+ *  @return         None\r
+ */\r
+void acil_encode_cmd_open_remote_pipe(uint8_t *buffer, aci_cmd_params_open_remote_pipe_t *p_aci_cmd_params_open_remote_pipe);\r
+\r
+/** @brief Encode the ACI message for close remote pipe\r
+ *\r
+ *  @param[in,out]  buffer                              Pointer to ACI message buffer\r
+ *  @param[in]      p_aci_cmd_params_close_remote_pipe   Pointer to the dynamic data parameters in ::aci_cmd_params_close_remote_pipe_t\r
+ *\r
+ *  @return         None\r
+ */\r
+void acil_encode_cmd_close_remote_pipe(uint8_t *buffer, aci_cmd_params_close_remote_pipe_t *p_aci_cmd_params_close_remote_pipe);\r
+\r
+/** @brief Encode the ACI message for echo message\r
+ *\r
+ *  @param[in,out]  buffer             Pointer to ACI message buffer\r
+ *  @param[in]      p_cmd_params_echo  Pointer to the dynamic data parameters in ::aci_cmd_params_echo_t\r
+ *  @param[in]      msg_size           Size of the message\r
+ *\r
+ *  @return         None\r
+ */\r
+void acil_encode_cmd_echo_msg(uint8_t *buffer, aci_cmd_params_echo_t *p_cmd_params_echo, uint8_t msg_size);\r
+\r
+/** @brief Encode the ACI message to battery level\r
+ *\r
+ *  @param[in,out]  buffer  Pointer to ACI message buffer\r
+ *\r
+ *  @return         None\r
+ */\r
+void acil_encode_cmd_battery_level(uint8_t *buffer);\r
+\r
+/** @brief Encode the ACI message to temparature\r
+ *\r
+ *  @param[in,out]  buffer  Pointer to ACI message buffer\r
+ *\r
+ *  @return         None\r
+ */\r
+void acil_encode_cmd_temparature(uint8_t *buffer);\r
+\r
+/** @brief Encode the ACI message to read dynamic data\r
+ *\r
+ *  @param[in,out]  buffer  Pointer to ACI message buffer\r
+ *\r
+ *  @return         None\r
+ */\r
+void acil_encode_cmd_read_dynamic_data(uint8_t *buffer);\r
+\r
+/** @brief Encode the ACI message to change timing request\r
+ *\r
+ *  @param[in,out]  buffer  Pointer to ACI message buffer\r
+ *  @param[in]      p_aci_cmd_params_change_timing  Pointer to the change timing parameters in ::aci_cmd_params_change_timing_t\r
+ *\r
+ *  @return         None\r
+ */\r
+void acil_encode_cmd_change_timing_req(uint8_t *buffer, aci_cmd_params_change_timing_t *p_aci_cmd_params_change_timing);\r
+\r
+/** @brief Encode the ACI message to change timing request using the timing parameters from GAP PPCP\r
+ *\r
+ *  @param[in,out]  buffer  Pointer to ACI message buffer\r
+ *  @param[in]      p_aci_cmd_params_change_timing  Pointer to the change timing parameters in ::aci_cmd_params_change_timing_t\r
+ *\r
+ *  @return         None\r
+ */\r
+void acil_encode_cmd_change_timing_req_GAP_PPCP(uint8_t *buffer);\r
+\r
+\r
+/** @brief Encode the ACI message for write dynamic data\r
+ *\r
+ *  @param[in,out]  buffer                          Pointer to ACI message buffer\r
+ *  @param[in]      seq_no                          Sequence number of the dynamic data (as received in the response to @c Read Dynamic Data)\r
+ *  @param[in]      dynamic_data                    Pointer to the dynamic data\r
+ *  @param[in]      dynamic_data_size               Size of dynamic data\r
+ *\r
+ *  @return         None\r
+ */\r
+void acil_encode_cmd_write_dynamic_data(uint8_t *buffer, uint8_t seq_no, uint8_t* dynamic_data, uint8_t dynamic_data_size);\r
+\r
+/** @brief Encode the ACI message to send data acknowledgement\r
+ *\r
+ *  @param[in,out]  buffer  Pointer to ACI message buffer\r
+ *  @param[in]      pipe_number Pipe number for which the ack is to be sent\r
+ *\r
+ *  @return         None\r
+ */\r
+void acil_encode_cmd_send_data_ack(uint8_t *buffer, const uint8_t pipe_number);\r
+\r
+/** @brief Encode the ACI message to send negative acknowledgement\r
+ *\r
+ *  @param[in,out]  buffer  Pointer to ACI message buffer\r
+ *  @param[in]    pipe_number Pipe number for which the nack is to be sent\r
+ *  @param[in]    error_code Error code that has to be sent in the NACK\r
+ *\r
+ *  @return         None\r
+ */\r
+void acil_encode_cmd_send_data_nack(uint8_t *buffer, const uint8_t pipe_number,const uint8_t error_code);\r
+\r
+/** @brief Encode the ACI message to set the application latency\r
+ *\r
+ *  @param[in,out]  buffer  Pointer to ACI message buffer\r
+ *  @param[in]      p_aci_cmd_params_set_app_latency  Pointer to the set_application_latency command parameters in ::aci_cmd_params_dtm_cmd_t\r
+ *\r
+ *  @return         None\r
+ */\r
+void acil_encode_cmd_set_app_latency(uint8_t *buffer, aci_cmd_params_set_app_latency_t *p_aci_cmd_params_set_app_latency);\r
+\r
+/** @brief Encode the ACI message for setup\r
+ *\r
+ *  @param[in,out]  buffer                          Pointer to ACI message buffer\r
+ *  @param[in]      p_cmd_params_set_run_behaviour  Pointer to the setup data in ::aci_cmd_params_setup_t\r
+ *  @param[in]      setup_data_size                 Size of setup message\r
+ *\r
+ *  @return         None\r
+ */\r
+void acil_encode_cmd_setup(uint8_t *buffer, aci_cmd_params_setup_t *p_aci_cmd_params_setup, uint8_t setup_data_size);\r
+\r
+/** @brief Encode the ACI message for DTM command\r
+ *\r
+ *  @param[in,out]  buffer                          Pointer to ACI message buffer\r
+ *  @param[in]      p_cmd_params_set_run_behaviour  Pointer to the DTM command parameters in ::aci_cmd_params_dtm_cmd_t\r
+ *\r
+ *  @return         None\r
+ */\r
+void acil_encode_cmd_dtm_cmd(uint8_t *buffer, aci_cmd_params_dtm_cmd_t *p_aci_cmd_params_dtm_cmd);\r
+\r
+/** @brief Encode the ACI message for Set Key Request command\r
+ *\r
+ *  @param[in,out]  buffer      Pointer to ACI message buffer\r
+ *\r
+ *  @return         None\r
+ */\r
+void acil_encode_cmd_set_key(uint8_t *buffer, aci_cmd_params_set_key_t *p_aci_cmd_params_set_key);\r
+\r
+/** @brief Encode the ACI message for Bond Security Request command\r
+ *\r
+ *  @param[in,out]  buffer      Pointer to ACI message buffer\r
+ *\r
+ *  @return         None\r
+ */\r
+void acil_encode_cmd_bond_security_request(uint8_t *buffer);\r
+\r
+/** @brief Encode the ACI message\r
+ *\r
+ *  @param[in,out]  buffer      Pointer to ACI message buffer\r
+ *  @param[in]      p_aci_cmd   Pointer to ACI command data in ::aci_cmd_t\r
+ *  @param[in]      bool\r
+ *\r
+ *  @return         bool         true, if succesful, else returns false\r
+ */\r
+bool acil_encode_cmd(uint8_t *buffer, aci_cmd_t *p_aci_cmd);\r
+\r
+/** @brief Encode the ACI message for Broadcast command\r
+ *\r
+ *  @param[in,out]  buffer      Pointer to ACI message buffer\r
+ *  @param[in]      p_aci_cmd   Pointer to ACI command data in ::aci_cmd_params_broadcast_t\r
+ *\r
+ *  @return         None\r
+ */\r
+void acil_encode_cmd_broadcast(uint8_t *buffer,  aci_cmd_params_broadcast_t * p_aci_cmd_params_broadcast);\r
+\r
+/** @brief Encode the ACI message for Open Adv Pipes\r
+ *\r
+ *  @param[in,out]  buffer      Pointer to ACI message buffer\r
+ *  @param[in]      p_aci_cmd   Pointer to ACI command data in ::aci_cmd_params_open_adv_pipe_t\r
+ *\r
+ *  @return         None\r
+ */\r
+void acil_encode_cmd_open_adv_pipes(uint8_t *buffer, aci_cmd_params_open_adv_pipe_t * p_aci_cmd_params_set_adv_svc_data);\r
+\r
+/** @brief Decode the ACI event command response\r
+ *\r
+ *  @param[in]      buffer_in  Pointer to message received\r
+ *  @param[in,out]  buffer     Pointer to the decoded message in ::aci_evt_params_cmd_rsp_t\r
+ *\r
+ *  @return         None\r
+ */\r
+void acil_decode_evt_command_response(uint8_t *buffer_in, aci_evt_params_cmd_rsp_t *p_evt_params_cmd_rsp);\r
+\r
+/** @brief Decode the ACI event device started\r
+ *\r
+ *  @param[in]      buffer_in  Pointer to message received\r
+ *  @param[in,out]  p_aci_evt  Pointer to the decoded message in ::aci_evt_params_device_started_t\r
+ *\r
+ *  @return         None\r
+ */\r
+void acil_decode_evt_device_started(uint8_t *buffer_in, aci_evt_params_device_started_t *p_evt_params_device_started);\r
+\r
+/** @brief Decode the ACI event pipe status\r
+ *\r
+ *  @param[in]      buffer_in  Pointer to message received\r
+ *  @param[in,out]  p_aci_evt_params_pipe_status  Pointer to the decoded message in ::aci_evt_params_pipe_status_t\r
+ *\r
+ *  @return         None\r
+ */\r
+void acil_decode_evt_pipe_status(uint8_t *buffer_in, aci_evt_params_pipe_status_t *p_aci_evt_params_pipe_status);\r
+\r
+/** @brief Decode the ACI event for disconnected\r
+ *\r
+ *  @param[in]      buffer_in                      Pointer to message received\r
+ *  @param[in,out]  p_aci_evt_params_disconnected  Pointer to the decoded message in ::aci_evt_params_disconnected_t\r
+ *\r
+ *  @return         None\r
+ */\r
+void acil_decode_evt_disconnected(uint8_t *buffer_in, aci_evt_params_disconnected_t *p_aci_evt_params_disconnected);\r
+\r
+/** @brief Decode the ACI event for bond status\r
+ *\r
+ *  @param[in]      buffer_in                     Pointer to message received\r
+ *  @param[in,out]  p_aci_evt_params_bond_status  Pointer to the decoded message in ::aci_evt_params_bond_status_t\r
+ *\r
+ *  @return         None\r
+ */\r
+void acil_decode_evt_bond_status(uint8_t *buffer_in, aci_evt_params_bond_status_t *p_aci_evt_params_bond_status);\r
+\r
+/** @brief Decode the ACI event for data received\r
+ *\r
+ *  @param[in]      buffer_in                   Pointer to message received\r
+ *  @param[in,out]  p_evt_params_data_received  Pointer to the decoded message in ::aci_evt_params_data_received_t\r
+ *\r
+ *  @return         size                        Received data size\r
+ */\r
+uint8_t acil_decode_evt_data_received(uint8_t *buffer_in, aci_evt_params_data_received_t *p_evt_params_data_received);\r
+\r
+/** @brief Decode the ACI event data acknowledgement\r
+ *\r
+ *  @param[in]      buffer_in               Pointer to message received\r
+ *  @param[in,out]  p_evt_params_data_ack   Pointer to the decoded message in ::aci_evt_params_data_ack_t\r
+ *\r
+ *  @return         None\r
+ */\r
+void acil_decode_evt_data_ack(uint8_t *buffer_in, aci_evt_params_data_ack_t *p_evt_params_data_ack);\r
+\r
+/** @brief Decode the ACI event for hardware error\r
+ *\r
+ *  @param[in]      buffer_in                  Pointer to message received\r
+ *  @param[in,out]  p_aci_evt_params_hw_error  Pointer to the decoded message in ::aci_evt_params_hw_error_t\r
+ *\r
+ *  @return         size                     Size of debug information\r
+ */\r
+uint8_t acil_decode_evt_hw_error(uint8_t *buffer_in, aci_evt_params_hw_error_t *p_aci_evt_params_hw_error);\r
+\r
+/** @brief Decode the ACI event data credit\r
+ *\r
+ *  @param[in]      buffer_in                 Pointer to message received\r
+ *  @param[in,out]  p_evt_params_data_credit  Pointer to the decoded message in ::aci_evt_params_data_credit_t\r
+ *\r
+ *  @return         None\r
+ */\r
+void acil_decode_evt_credit(uint8_t *buffer_in, aci_evt_params_data_credit_t *p_evt_params_data_credit);\r
+\r
+/** @brief Decode the ACI event for connected\r
+ *\r
+ *  @param[in]      buffer_in                   Pointer to message received\r
+ *  @param[in,out]  p_aci_evt_params_connected  Pointer to the decoded message in ::aci_evt_params_connected_t\r
+ *\r
+ *  @return         None\r
+ */\r
+void acil_decode_evt_connected(uint8_t *buffer_in, aci_evt_params_connected_t *p_aci_evt_params_connected);\r
+\r
+/** @brief Decode the ACI event for timing\r
+ *\r
+ *  @param[in]      buffer_in             Pointer to message received\r
+ *  @param[in,out]  p_evt_params_timing   Pointer to the decoded message in ::aci_evt_params_timing_t\r
+ *\r
+ *  @return         None\r
+ */\r
+void acil_decode_evt_timing(uint8_t *buffer_in, aci_evt_params_timing_t *p_evt_params_timing);\r
+\r
+/** @brief Decode the ACI event for pipe error\r
+ *\r
+ *  @param[in]      buffer_in                 Pointer to message received\r
+ *  @param[in,out]  p_evt_params_pipe_error   Pointer to the decoded message in ::aci_evt_params_pipe_error_t\r
+ *\r
+ */\r
+void acil_decode_evt_pipe_error(uint8_t *buffer_in, aci_evt_params_pipe_error_t *p_evt_params_pipe_error);\r
+\r
+/** @brief Decode the ACI event for key request\r
+ *\r
+ *  @param[in]      buffer_in               Pointer to message received\r
+ *  @param[in,out]  p_evt_params_key_type   Pointer to the decoded message in ::aci_evt_params_key_type_t\r
+ *\r
+ *  @return         None\r
+ */\r
+void acil_decode_evt_key_request(uint8_t *buffer_in, aci_evt_params_key_request_t *p_evt_params_key_request);\r
+\r
+/** @brief Decode the ACI event for echo\r
+ *\r
+ *  @param[in]      buffer_in    Pointer to message received\r
+ *  @param[in,out]  buffer_out   Pointer to the echo message (max size of buffer ::ACI_ECHO_DATA_MAX_LEN)\r
+ *\r
+ *  @return         size         Received echo message size\r
+ */\r
+uint8_t acil_decode_evt_echo(uint8_t *buffer_in, aci_evt_params_echo_t *buffer_out);\r
+\r
+/** @brief Decode the ACI event\r
+ *\r
+ *  @param[in]      buffer_in   Pointer to message received\r
+ *  @param[in,out]  p_aci_evt   Pointer to the decoded message in ::aci_evt_t\r
+ *\r
+ *  @return         bool         true, if succesful, else returns false\r
+ */\r
+bool acil_decode_evt(uint8_t *buffer_in, aci_evt_t *p_aci_evt);\r
+\r
+/** @brief Decode the Display Key Event\r
+ *\r
+ *  @param[in]      buffer_in   Pointer to message received\r
+ *  @param[in,out]  p_aci_evt   Pointer to the decoded message in ::aci_evt_params_display_passkey_t\r
+ *\r
+ *  @return         None\r
+ */\r
+void acil_decode_evt_display_passkey(uint8_t *buffer_in, aci_evt_params_display_passkey_t *p_aci_evt_params_display_passkey);\r
+\r
+#endif /* _acilib_IF_H_ */\r
diff --git a/src/nrf8001/acilib_types.h b/src/nrf8001/acilib_types.h
new file mode 100644 (file)
index 0000000..9421478
--- /dev/null
@@ -0,0 +1,33 @@
+/* Copyright (c) 2014, Nordic Semiconductor ASA\r
+ *\r
+ * Permission is hereby granted, free of charge, to any person obtaining a copy\r
+ * of this software and associated documentation files (the "Software"), to deal\r
+ * in the Software without restriction, including without limitation the rights\r
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+ * copies of the Software, and to permit persons to whom the Software is\r
+ * furnished to do so, subject to the following conditions:\r
+ *\r
+ * The above copyright notice and this permission notice shall be included in all\r
+ * copies or substantial portions of the Software.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ */\r
+\r
+/**\r
+ * @file\r
+ *\r
+ * @ingroup group_acilib\r
+ *\r
+ * @brief Type used in the acilib interfaces\r
+ */\r
+\r
+#ifndef _acilib_TYPES_H_\r
+#define _acilib_TYPES_H_\r
+\r
+#endif /* _acilib_TYPES_H_ */\r
diff --git a/src/nrf8001/boards.h b/src/nrf8001/boards.h
new file mode 100644 (file)
index 0000000..d49ef6e
--- /dev/null
@@ -0,0 +1,34 @@
+/* Copyright (c) 2014, Nordic Semiconductor ASA\r
+ *\r
+ * Permission is hereby granted, free of charge, to any person obtaining a copy\r
+ * of this software and associated documentation files (the "Software"), to deal\r
+ * in the Software without restriction, including without limitation the rights\r
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+ * copies of the Software, and to permit persons to whom the Software is\r
+ * furnished to do so, subject to the following conditions:\r
+ *\r
+ * The above copyright notice and this permission notice shall be included in all\r
+ * copies or substantial portions of the Software.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ */\r
+\r
+/** @file\r
+ * @brief Defines for the different Bluetooth low energy boards\r
+ */\r
+\r
+#ifndef _BLE_BOARDS_H_\r
+#define _BLE_BOARDS_H_\r
+\r
+#define BOARD_DEFAULT               0 //Use this if you do not know the board you are using or you are creating a new one\r
+#define REDBEARLAB_SHIELD_V1_1      1 //Redbearlab Bluetooth low energy shield v1.1\r
+#define REDBEARLAB_SHIELD_V2012_07  1 //Identical to Redbearlab v1.1 shield\r
+#define REDBEARLAB_SHIELD_V2        0 //Redbearlab Bluetooth low energy shield v2.x - No special handling required for pin reset same as default\r
+\r
+#endif\r
diff --git a/src/nrf8001/dtm.h b/src/nrf8001/dtm.h
new file mode 100644 (file)
index 0000000..ef5ab64
--- /dev/null
@@ -0,0 +1,63 @@
+/* Copyright (c) 2014, Nordic Semiconductor ASA\r
+ *\r
+ * Permission is hereby granted, free of charge, to any person obtaining a copy\r
+ * of this software and associated documentation files (the "Software"), to deal\r
+ * in the Software without restriction, including without limitation the rights\r
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+ * copies of the Software, and to permit persons to whom the Software is\r
+ * furnished to do so, subject to the following conditions:\r
+ *\r
+ * The above copyright notice and this permission notice shall be included in all\r
+ * copies or substantial portions of the Software.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ */\r
+\r
+/**\r
+ * @file\r
+ *\r
+ * @ingroup group_acilib\r
+ *\r
+ * @brief Internal prototype for acilib module.\r
+ */\r
+\r
+#ifndef DTM_H__\r
+#define DTM_H__\r
+\r
+/** @brief DTM command codes (upper two bits in the DTM command), use a bitwise OR with the frequency N = 0x00 - 0x27: N = (F-2402)/2 Frequency Range 2402 MHz\r
+to 2480 MHz*/\r
+#define DTM_LE_CMD_RESET            0x00\r
+#define DTM_LE_CMD_RECEIVER_TEST    0x40\r
+#define DTM_LE_CMD_TRANSMITTER_TEST 0x80\r
+#define DTM_LE_CMD_TEST_END         0xC0\r
+\r
+\r
+/** @brief Defined packet types for DTM */\r
+#define DTM_LE_PKT_PRBS9      0x00       /**< Bit pattern PRBS9.    */\r
+#define DTM_LE_PKT_0X0F       0x01       /**< Bit pattern 11110000 (LSB is the leftmost bit). */\r
+#define DTM_LE_PKT_0X55       0x02       /**< Bit pattern 10101010 (LSB is the leftmost bit). */\r
+#define DTM_LE_PKT_VENDOR     0x03       /**< Vendor specific. Nordic: continous carrier test */\r
+\r
+/** @brief Defined bit fields for DTM responses. */\r
+#define LE_PACKET_REPORTING_EVENT_MSB_BIT   0x80\r
+#define LE_TEST_STATUS_EVENT_LSB_BIT        0x01\r
+\r
+/** @brief DTM response types. */\r
+#define LE_TEST_STATUS_EVENT                0x00\r
+#define LE_TEST_PACKET_REPORT_EVENT         0x80\r
+\r
+/** @brief DTM return values. */\r
+#define LE_TEST_STATUS_SUCCESS              0x00\r
+#define LE_TEST_STATUS_FAILURE              0x01\r
+\r
+\r
+\r
+#endif //DTM_H__\r
+\r
+/** @} */\r
diff --git a/src/nrf8001/hal_aci_tl.cpp b/src/nrf8001/hal_aci_tl.cpp
new file mode 100644 (file)
index 0000000..b15f4b4
--- /dev/null
@@ -0,0 +1,454 @@
+/* Copyright (c) 2014, Nordic Semiconductor ASA\r
+ *\r
+ * Permission is hereby granted, free of charge, to any person obtaining a copy\r
+ * of this software and associated documentation files (the "Software"), to deal\r
+ * in the Software without restriction, including without limitation the rights\r
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+ * copies of the Software, and to permit persons to whom the Software is\r
+ * furnished to do so, subject to the following conditions:\r
+ *\r
+ * The above copyright notice and this permission notice shall be included in all\r
+ * copies or substantial portions of the Software.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ */\r
+\r
+/** @file\r
+@brief Implementation of the ACI transport layer module\r
+*/\r
+\r
+#include <stdio.h>\r
+\r
+#include "hal_platform.h"\r
+#include "hal_aci_tl.h"\r
+#include "aci_queue.h"\r
+\r
+#define HIGH                    1\r
+#define LOW                     0\r
+\r
+#define REVERSE_BITS(byte) (((reverse_lookup[(byte & 0x0F)]) << 4) + reverse_lookup[((byte & 0xF0) >> 4)])\r
+static const uint8_t reverse_lookup[] = { 0, 8,  4, 12, 2, 10, 6, 14,1, 9, 5, 13,3, 11, 7, 15 };\r
+\r
+static void m_aci_data_print(hal_aci_data_t *p_data);\r
+static void m_aci_event_check(void);\r
+static void m_aci_isr(void);\r
+static void m_aci_pins_set(aci_pins_t *a_pins_ptr);\r
+static inline void m_aci_reqn_disable (void);\r
+static inline void m_aci_reqn_enable (void);\r
+static void m_aci_q_flush(void);\r
+static bool m_aci_spi_transfer(hal_aci_data_t * data_to_send, hal_aci_data_t * received_data);\r
+\r
+static uint8_t        spi_readwrite(uint8_t aci_byte);\r
+\r
+static bool           aci_debug_print = false;\r
+\r
+aci_queue_t    aci_tx_q;\r
+aci_queue_t    aci_rx_q;\r
+\r
+static aci_pins_t    *a_pins_local_ptr;\r
+\r
+void m_aci_data_print(hal_aci_data_t *p_data)\r
+{\r
+  const uint8_t length = p_data->buffer[0];\r
+  uint8_t i;\r
+  printf("%d\n", length);\r
+  printf(" :\n");\r
+  for (i=0; i<=length; i++)\r
+  {\r
+    printf("%x", p_data->buffer[i]);\r
+    printf(", ");\r
+  }\r
+  printf("\n");\r
+}\r
+\r
+/*\r
+  Interrupt service routine called when the RDYN line goes low. Runs the SPI transfer.\r
+*/\r
+static void m_aci_isr(void)\r
+{\r
+  hal_aci_data_t data_to_send;\r
+  hal_aci_data_t received_data;\r
+\r
+  // Receive from queue\r
+  if (!aci_queue_dequeue_from_isr(&aci_tx_q, &data_to_send))\r
+  {\r
+    /* queue was empty, nothing to send */\r
+    data_to_send.status_byte = 0;\r
+    data_to_send.buffer[0] = 0;\r
+  }\r
+\r
+  // Receive and/or transmit data\r
+  m_aci_spi_transfer(&data_to_send, &received_data);\r
+\r
+  if (!aci_queue_is_full_from_isr(&aci_rx_q) && !aci_queue_is_empty_from_isr(&aci_tx_q))\r
+  {\r
+    m_aci_reqn_enable();\r
+  }\r
+\r
+  // Check if we received data\r
+  if (received_data.buffer[0] > 0)\r
+  {\r
+    if (!aci_queue_enqueue_from_isr(&aci_rx_q, &received_data))\r
+    {\r
+      /* Receive Buffer full.\r
+         Should never happen.\r
+         Spin in a while loop.\r
+      */\r
+      while(1);\r
+    }\r
+\r
+    // Disable ready line interrupt until we have room to store incoming messages\r
+    if (aci_queue_is_full_from_isr(&aci_rx_q))\r
+    {\r
+      // detachInterrupt(a_pins_local_ptr->interrupt_number);\r
+    }\r
+  }\r
+\r
+  return;\r
+}\r
+\r
+/*\r
+  Checks the RDYN line and runs the SPI transfer if required.\r
+*/\r
+static void m_aci_event_check(void)\r
+{\r
+  hal_aci_data_t data_to_send;\r
+  hal_aci_data_t received_data;\r
+\r
+  // No room to store incoming messages\r
+  if (aci_queue_is_full(&aci_rx_q))\r
+  {\r
+    return;\r
+  }\r
+\r
+  // If the ready line is disabled and we have pending messages outgoing we enable the request line\r
+  if (HIGH == mraa_gpio_read (a_pins_local_ptr->m_rdy_ctx))\r
+  // if (HIGH == digitalRead(a_pins_local_ptr->rdyn_pin))\r
+  {\r
+    if (!aci_queue_is_empty(&aci_tx_q))\r
+    {\r
+      m_aci_reqn_enable();\r
+    }\r
+\r
+    return;\r
+  }\r
+\r
+  // Receive from queue\r
+  if (!aci_queue_dequeue(&aci_tx_q, &data_to_send))\r
+  {\r
+    /* queue was empty, nothing to send */\r
+    data_to_send.status_byte = 0;\r
+    data_to_send.buffer[0] = 0;\r
+  }\r
+\r
+  // Receive and/or transmit data\r
+  m_aci_spi_transfer(&data_to_send, &received_data);\r
+\r
+  /* If there are messages to transmit, and we can store the reply, we request a new transfer */\r
+  if (!aci_queue_is_full(&aci_rx_q) && !aci_queue_is_empty(&aci_tx_q))\r
+  {\r
+    m_aci_reqn_enable();\r
+  }\r
+\r
+  // Check if we received data\r
+  if (received_data.buffer[0] > 0)\r
+  {\r
+    if (!aci_queue_enqueue(&aci_rx_q, &received_data))\r
+    {\r
+      /* Receive Buffer full.\r
+         Should never happen.\r
+         Spin in a while loop.\r
+      */\r
+      while(1);\r
+    }\r
+  }\r
+\r
+  return;\r
+}\r
+\r
+/** @brief Point the low level library at the ACI pins specified\r
+ *  @details\r
+ *  The ACI pins are specified in the application and a pointer is made available for\r
+ *  the low level library to use\r
+ */\r
+static void m_aci_pins_set(aci_pins_t *a_pins_ptr)\r
+{\r
+  a_pins_local_ptr = a_pins_ptr;\r
+}\r
+\r
+static inline void m_aci_reqn_disable (void)\r
+{\r
+    mraa_gpio_write (a_pins_local_ptr->m_req_ctx, HIGH);\r
+}\r
+\r
+static inline void m_aci_reqn_enable (void)\r
+{\r
+    mraa_gpio_write (a_pins_local_ptr->m_req_ctx, LOW);\r
+}\r
+\r
+static void m_aci_q_flush(void)\r
+{\r
+  // noInterrupts();\r
+  /* re-initialize aci cmd queue and aci event queue to flush them*/\r
+  aci_queue_init(&aci_tx_q);\r
+  aci_queue_init(&aci_rx_q);\r
+  // interrupts();\r
+}\r
+\r
+static bool m_aci_spi_transfer(hal_aci_data_t * data_to_send, hal_aci_data_t * received_data)\r
+{\r
+  uint8_t byte_cnt;\r
+  uint8_t byte_sent_cnt;\r
+  uint8_t max_bytes;\r
+\r
+  m_aci_reqn_enable();\r
+\r
+  // Send length, receive header\r
+  byte_sent_cnt = 0;\r
+  received_data->status_byte = spi_readwrite(data_to_send->buffer[byte_sent_cnt++]);\r
+  // Send first byte, receive length from slave\r
+  received_data->buffer[0] = spi_readwrite(data_to_send->buffer[byte_sent_cnt++]);\r
+  if (0 == data_to_send->buffer[0])\r
+  {\r
+    max_bytes = received_data->buffer[0];\r
+  }\r
+  else\r
+  {\r
+    // Set the maximum to the biggest size. One command byte is already sent\r
+    max_bytes = (received_data->buffer[0] > (data_to_send->buffer[0] - 1))\r
+                                          ? received_data->buffer[0]\r
+                                          : (data_to_send->buffer[0] - 1);\r
+  }\r
+\r
+  if (max_bytes > HAL_ACI_MAX_LENGTH)\r
+  {\r
+    max_bytes = HAL_ACI_MAX_LENGTH;\r
+  }\r
+\r
+  // Transmit/receive the rest of the packet\r
+  for (byte_cnt = 0; byte_cnt < max_bytes; byte_cnt++)\r
+  {\r
+    received_data->buffer[byte_cnt+1] =  spi_readwrite(data_to_send->buffer[byte_sent_cnt++]);\r
+  }\r
+\r
+  // RDYN should follow the REQN line in approx 100ns\r
+  m_aci_reqn_disable();\r
+\r
+  return (max_bytes > 0);\r
+}\r
+\r
+void hal_aci_tl_debug_print(bool enable)\r
+{\r
+    aci_debug_print = enable;\r
+}\r
+\r
+void hal_aci_tl_pin_reset(void)\r
+{\r
+    if (UNUSED != a_pins_local_ptr->reset_pin)\r
+    {\r
+        // pinMode(a_pins_local_ptr->reset_pin, OUTPUT);\r
+\r
+        if ((REDBEARLAB_SHIELD_V1_1     == a_pins_local_ptr->board_name) ||\r
+            (REDBEARLAB_SHIELD_V2012_07 == a_pins_local_ptr->board_name))\r
+        {\r
+            //The reset for the Redbearlab v1.1 and v2012.07 boards are inverted and has a Power On Reset\r
+            //circuit that takes about 100ms to trigger the reset\r
+            mraa_gpio_write (a_pins_local_ptr->m_rst_ctx, HIGH);\r
+            usleep (100000);\r
+            mraa_gpio_write (a_pins_local_ptr->m_rst_ctx, LOW);\r
+        }\r
+        else\r
+        {\r
+            mraa_gpio_write (a_pins_local_ptr->m_rst_ctx, HIGH);\r
+            mraa_gpio_write (a_pins_local_ptr->m_rst_ctx, LOW);\r
+            mraa_gpio_write (a_pins_local_ptr->m_rst_ctx, HIGH);\r
+        }\r
+    }\r
+}\r
+\r
+bool hal_aci_tl_event_peek(hal_aci_data_t *p_aci_data)\r
+{\r
+  if (!a_pins_local_ptr->interface_is_interrupt)\r
+  {\r
+    m_aci_event_check();\r
+  }\r
+\r
+  if (aci_queue_peek(&aci_rx_q, p_aci_data))\r
+  {\r
+    return true;\r
+  }\r
+\r
+  return false;\r
+}\r
+\r
+bool hal_aci_tl_event_get(hal_aci_data_t *p_aci_data)\r
+{\r
+  bool was_full;\r
+\r
+  if (!a_pins_local_ptr->interface_is_interrupt && !aci_queue_is_full(&aci_rx_q))\r
+  {\r
+    m_aci_event_check();\r
+  }\r
+\r
+  was_full = aci_queue_is_full(&aci_rx_q);\r
+\r
+  if (aci_queue_dequeue(&aci_rx_q, p_aci_data))\r
+  {\r
+    if (aci_debug_print)\r
+    {\r
+      printf(" E");\r
+      m_aci_data_print(p_aci_data);\r
+    }\r
+\r
+    if (was_full && a_pins_local_ptr->interface_is_interrupt)\r
+    {\r
+      /* Enable RDY line interrupt again */\r
+      // attachInterrupt(a_pins_local_ptr->interrupt_number, m_aci_isr, LOW);\r
+    }\r
+\r
+    /* Attempt to pull REQN LOW since we've made room for new messages */\r
+    if (!aci_queue_is_full(&aci_rx_q) && !aci_queue_is_empty(&aci_tx_q))\r
+    {\r
+      m_aci_reqn_enable();\r
+    }\r
+\r
+    return true;\r
+  }\r
+\r
+  return false;\r
+}\r
+\r
+void hal_aci_tl_init(aci_pins_t *a_pins, bool debug)\r
+{\r
+    mraa_result_t error = MRAA_SUCCESS;\r
+    aci_debug_print = debug;\r
+\r
+    /* Needs to be called as the first thing for proper intialization*/\r
+    m_aci_pins_set(a_pins);\r
+\r
+    /*\r
+     * Init SPI\r
+     */\r
+    a_pins->m_spi = mraa_spi_init (0);\r
+    if (a_pins->m_spi == NULL) {\r
+        printf ("[ERROR] SPI failed to initilize\n");\r
+    }\r
+\r
+    mraa_spi_frequency (a_pins->m_spi, 2000000);\r
+    mraa_spi_mode (a_pins->m_spi, MRAA_SPI_MODE0);\r
+    mraa_spi_lsbmode (a_pins->m_spi, 1);\r
+\r
+    /* Initialize the ACI Command queue. This must be called after the delay above. */\r
+    aci_queue_init(&aci_tx_q);\r
+    aci_queue_init(&aci_rx_q);\r
+\r
+    // Configure the IO lines\r
+    a_pins->m_rdy_ctx = mraa_gpio_init (a_pins->rdyn_pin);\r
+    if (a_pins->m_rdy_ctx == NULL) {\r
+        printf ("[ERROR] GPIO failed to initilize \n");\r
+    }\r
+\r
+    a_pins->m_req_ctx = mraa_gpio_init (a_pins->reqn_pin);\r
+    if (a_pins->m_req_ctx == NULL) {\r
+        printf ("[ERROR] GPIO failed to initilize \n");\r
+    }\r
+\r
+    a_pins->m_rst_ctx = mraa_gpio_init (a_pins->reset_pin);\r
+    if (a_pins->m_rst_ctx == NULL) {\r
+        printf ("[ERROR] GPIO failed to initilize \n");\r
+    }\r
+\r
+    error = mraa_gpio_dir (a_pins->m_rdy_ctx, MRAA_GPIO_IN);\r
+    if (error != MRAA_SUCCESS) {\r
+        printf ("[ERROR] GPIO failed to initilize \n");\r
+    }\r
+\r
+    error = mraa_gpio_dir (a_pins->m_req_ctx, MRAA_GPIO_OUT);\r
+    if (error != MRAA_SUCCESS) {\r
+        printf ("[ERROR] GPIO failed to initilize \n");\r
+    }\r
+\r
+    error = mraa_gpio_dir (a_pins->m_rst_ctx, MRAA_GPIO_OUT);\r
+    if (error != MRAA_SUCCESS) {\r
+        printf ("[ERROR] GPIO failed to initilize \n");\r
+    }\r
+\r
+    if (UNUSED != a_pins->active_pin) {\r
+    }\r
+\r
+  /* Pin reset the nRF8001, required when the nRF8001 setup is being changed */\r
+  hal_aci_tl_pin_reset();\r
+\r
+  /* Set the nRF8001 to a known state as required by the datasheet*/\r
+  mraa_gpio_write (a_pins->m_req_ctx, LOW);\r
+\r
+  usleep(30000); //Wait for the nRF8001 to get hold of its lines - the lines float for a few ms after the reset\r
+\r
+    /* Attach the interrupt to the RDYN line as requested by the caller */\r
+    if (a_pins->interface_is_interrupt) {\r
+        // We use the LOW level of the RDYN line as the atmega328 can wakeup from sleep only on LOW\r
+        // attachInterrupt(a_pins->interrupt_number, m_aci_isr, LOW);\r
+    }\r
+}\r
+\r
+bool hal_aci_tl_send(hal_aci_data_t *p_aci_cmd)\r
+{\r
+  const uint8_t length = p_aci_cmd->buffer[0];\r
+  bool ret_val = false;\r
+\r
+  if (length > HAL_ACI_MAX_LENGTH)\r
+  {\r
+    return false;\r
+  }\r
+\r
+  ret_val = aci_queue_enqueue(&aci_tx_q, p_aci_cmd);\r
+  if (ret_val)\r
+  {\r
+    if(!aci_queue_is_full(&aci_rx_q))\r
+    {\r
+      // Lower the REQN only when successfully enqueued\r
+      m_aci_reqn_enable();\r
+    }\r
+  }\r
+\r
+  return ret_val;\r
+}\r
+\r
+static uint8_t spi_readwrite(const uint8_t aci_byte)\r
+{\r
+    uint8_t reversed, ret;\r
+    reversed = mraa_spi_write (a_pins_local_ptr->m_spi, REVERSE_BITS (aci_byte));\r
+    ret = REVERSE_BITS (reversed);\r
+    return ret;\r
+}\r
+\r
+bool hal_aci_tl_rx_q_empty (void)\r
+{\r
+  return aci_queue_is_empty(&aci_rx_q);\r
+}\r
+\r
+bool hal_aci_tl_rx_q_full (void)\r
+{\r
+  return aci_queue_is_full(&aci_rx_q);\r
+}\r
+\r
+bool hal_aci_tl_tx_q_empty (void)\r
+{\r
+  return aci_queue_is_empty(&aci_tx_q);\r
+}\r
+\r
+bool hal_aci_tl_tx_q_full (void)\r
+{\r
+  return aci_queue_is_full(&aci_tx_q);\r
+}\r
+\r
+void hal_aci_tl_q_flush (void)\r
+{\r
+  m_aci_q_flush();\r
+}\r
diff --git a/src/nrf8001/hal_aci_tl.h b/src/nrf8001/hal_aci_tl.h
new file mode 100644 (file)
index 0000000..68e25b3
--- /dev/null
@@ -0,0 +1,188 @@
+/* Copyright (c) 2014, Nordic Semiconductor ASA\r
+ *\r
+ * Permission is hereby granted, free of charge, to any person obtaining a copy\r
+ * of this software and associated documentation files (the "Software"), to deal\r
+ * in the Software without restriction, including without limitation the rights\r
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+ * copies of the Software, and to permit persons to whom the Software is\r
+ * furnished to do so, subject to the following conditions:\r
+ *\r
+ * The above copyright notice and this permission notice shall be included in all\r
+ * copies or substantial portions of the Software.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ */\r
+\r
+/** @file\r
+ * @brief Interface for hal_aci_tl.\r
+ */\r
+\r
+/** @defgroup hal_aci_tl hal_aci_tl\r
+@{\r
+@ingroup hal\r
+\r
+@brief Module for the ACI Transport Layer interface\r
+@details This module is responsible for sending and receiving messages over the ACI interface of the nRF8001 chip.\r
+ The hal_aci_tl_send_cmd() can be called directly to send ACI commands.\r
+\r
+\r
+The RDYN line is hooked to an interrupt on the MCU when the level is low.\r
+The SPI master clocks in the interrupt context.\r
+The ACI Command is taken from the head of the command queue is sent over the SPI\r
+and the received ACI event is placed in the tail of the event queue.\r
+\r
+*/\r
+\r
+#ifndef HAL_ACI_TL_H__\r
+#define HAL_ACI_TL_H__\r
+\r
+#include "hal_platform.h"\r
+#include "aci.h"\r
+#include "boards.h"\r
+\r
+#include <mraa/aio.h>\r
+#include <mraa/gpio.h>\r
+#include <mraa/spi.h>\r
+\r
+#ifndef HAL_ACI_MAX_LENGTH\r
+#define HAL_ACI_MAX_LENGTH 31\r
+#endif\r
+\r
+/************************************************************************/\r
+/* Unused nRF8001 pin                                                    */\r
+/************************************************************************/\r
+#define UNUSED          255\r
+\r
+/** Data type for ACI commands and events */\r
+typedef struct {\r
+  uint8_t status_byte;\r
+  uint8_t buffer[HAL_ACI_MAX_LENGTH+1];\r
+} _aci_packed_ hal_aci_data_t;\r
+\r
+ACI_ASSERT_SIZE(hal_aci_data_t, HAL_ACI_MAX_LENGTH + 2);\r
+\r
+/** Datatype for ACI pins and interface (polling/interrupt)*/\r
+typedef struct aci_pins_t\r
+{\r
+    mraa_spi_context        m_spi;\r
+    mraa_gpio_context       m_rdy_ctx;\r
+    mraa_gpio_context       m_req_ctx;\r
+    mraa_gpio_context       m_rst_ctx;\r
+\r
+    uint8_t board_name;             //Optional : Use BOARD_DEFAULT if you do not know. See boards.h\r
+    uint8_t reqn_pin;               //Required\r
+    uint8_t rdyn_pin;               //Required\r
+    uint8_t mosi_pin;               //Required\r
+    uint8_t miso_pin;               //Required\r
+    uint8_t sck_pin;                //Required\r
+\r
+    uint8_t spi_clock_divider;      //Required : Clock divider on the SPI clock : nRF8001 supports a maximum clock of 3MHz\r
+\r
+    uint8_t reset_pin;              //Recommended but optional - Set it to UNUSED when not connected\r
+    uint8_t active_pin;             //Optional - Set it to UNUSED when not connected\r
+    uint8_t optional_chip_sel_pin;  //Optional - Used only when the reqn line is required to be separate from the SPI chip select. Eg. Arduino DUE\r
+\r
+    bool    interface_is_interrupt; //Required - true = Uses interrupt on RDYN pin. false - Uses polling on RDYN pin\r
+\r
+    uint8_t interrupt_number;       //Required when using interrupts, otherwise ignored\r
+} aci_pins_t;\r
+\r
+/** @brief ACI Transport Layer initialization.\r
+ *  @details\r
+ *  This function initializes the transport layer, including configuring the SPI, creating\r
+ *  message queues for Commands and Events and setting up interrupt if required.\r
+ *  @param a_pins Pins on the MCU used to connect to the nRF8001\r
+ *  @param bool True if debug printing should be enabled on the Serial.\r
+ */\r
+void hal_aci_tl_init(aci_pins_t *a_pins, bool debug);\r
+\r
+/** @brief Sends an ACI command to the radio.\r
+ *  @details\r
+ *  This function sends an ACI command to the radio. This queue up the message to send and\r
+ *  lower the request line. When the device lowers the ready line, @ref m_aci_spi_transfer()\r
+ *  will send the data.\r
+ *  @param aci_buffer Pointer to the message to send.\r
+ *  @return True if the data was successfully queued for sending,\r
+ *  false if there is no more space to store messages to send.\r
+ */\r
+bool hal_aci_tl_send(hal_aci_data_t *aci_buffer);\r
+\r
+/** @brief Process pending transactions.\r
+ *  @details\r
+ *  The library code takes care of calling this function to check if the nRF8001 RDYN line indicates a\r
+ *  pending transaction. It will send a pending message if there is one and return any receive message\r
+ *  that was pending.\r
+ *  @return Points to data buffer for received data. Length byte in buffer is 0 if no data received.\r
+ */\r
+hal_aci_data_t * hal_aci_tl_poll_get(void);\r
+\r
+/** @brief Get an ACI event from the event queue\r
+ *  @details\r
+ *  Call this function from the main context to get an event from the ACI event queue\r
+ *  This is called by lib_aci_event_get\r
+ */\r
+bool hal_aci_tl_event_get(hal_aci_data_t *p_aci_data);\r
+\r
+/** @brief Peek an ACI event from the event queue\r
+ *  @details\r
+ *  Call this function from the main context to peek an event from the ACI event queue.\r
+ *  This is called by lib_aci_event_peek\r
+ */\r
+bool hal_aci_tl_event_peek(hal_aci_data_t *p_aci_data);\r
+\r
+/** @brief Enable debug printing of all ACI commands sent and ACI events received\r
+ *  @details\r
+ *  when the enable parameter is true. The debug printing is enabled on the Serial.\r
+ *  When the enable parameter is false. The debug printing is disabled on the Serial.\r
+ *  By default the debug printing is disabled.\r
+ */\r
+void hal_aci_tl_debug_print(bool enable);\r
+\r
+\r
+/** @brief Pin reset the nRF8001\r
+ *  @details\r
+ *  The reset line of the nF8001 needs to kept low for 200 ns.\r
+ *  Redbearlab shield v1.1 and v2012.07 are exceptions as they\r
+ *  have a Power ON Reset circuit that works differently.\r
+ *  The function handles the exceptions based on the board_name in aci_pins_t\r
+ */\r
+void hal_aci_tl_pin_reset(void);\r
+\r
+/** @brief Return full status of transmit queue\r
+ *  @details\r
+ *\r
+ */\r
+ bool hal_aci_tl_rx_q_full(void);\r
+\r
+ /** @brief Return empty status of receive queue\r
+ *  @details\r
+ *\r
+ */\r
+ bool hal_aci_tl_rx_q_empty(void);\r
+\r
+/** @brief Return full status of receive queue\r
+ *  @details\r
+ *\r
+ */\r
+ bool hal_aci_tl_tx_q_full(void);\r
+\r
+ /** @brief Return empty status of transmit queue\r
+ *  @details\r
+ *\r
+ */\r
+ bool hal_aci_tl_tx_q_empty(void);\r
+\r
+/** @brief Flush the ACI command Queue and the ACI Event Queue\r
+ *  @details\r
+ *  Call this function in the main thread\r
+ */\r
+void hal_aci_tl_q_flush(void);\r
+\r
+#endif // HAL_ACI_TL_H__\r
+/** @} */\r
diff --git a/src/nrf8001/hal_platform.h b/src/nrf8001/hal_platform.h
new file mode 100644 (file)
index 0000000..70f7119
--- /dev/null
@@ -0,0 +1,76 @@
+/* Copyright (c) 2014, Nordic Semiconductor ASA\r
+ *\r
+ * Permission is hereby granted, free of charge, to any person obtaining a copy\r
+ * of this software and associated documentation files (the "Software"), to deal\r
+ * in the Software without restriction, including without limitation the rights\r
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+ * copies of the Software, and to permit persons to whom the Software is\r
+ * furnished to do so, subject to the following conditions:\r
+ *\r
+ * The above copyright notice and this permission notice shall be included in all\r
+ * copies or substantial portions of the Software.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ */\r
+\r
+#ifndef PLATFORM_H__\r
+#define PLATFORM_H__\r
+\r
+/** @file\r
+* @brief\r
+*/\r
+\r
+//Board dependent defines\r
+#if defined (__AVR__)\r
+    //For Arduino this AVR specific library has to be used for reading from Flash memory\r
+    #include <avr/pgmspace.h>\r
+    #include "Arduino.h"\r
+    #ifdef PROGMEM\r
+        #undef PROGMEM\r
+        #define PROGMEM __attribute__(( section(".progmem.data") ))\r
+        #endif\r
+#elif defined(__PIC32MX__)\r
+    //For Chipkit add the following libraries.\r
+    #include <stdint.h>\r
+    #include <stdbool.h>\r
+    #include <string.h>\r
+    #include <wiring.h>\r
+    #include <WProgram.h>\r
+\r
+    //For making the Serial.Print compatible between Arduino and Chipkit\r
+    #define F(X) (X)\r
+\r
+    //For ChipKit neither PROGMEM or PSTR are needed for PIC32\r
+    #define PROGMEM\r
+    #define PSTR(s) (s)\r
+\r
+    #define pgm_read_byte(x)            (*((char *)x))\r
+    #define pgm_read_byte_near(x)   (*((char *)x))\r
+    #define pgm_read_byte_far(x)        (*((char *)x))\r
+    #define pgm_read_word(x)            (*((short *)x))\r
+    #define pgm_read_word_near(x)   (*((short *)x))\r
+    #define pgm_read_workd_far(x)   (*((short *)x))\r
+\r
+    #define prog_void       const void\r
+    #define prog_char       const char\r
+    #define prog_uchar      const unsigned char\r
+    #define prog_int8_t     const int8_t\r
+    #define prog_uint8_t    const uint8_t\r
+    #define prog_int16_t    const int16_t\r
+    #define prog_uint16_t   const uint16_t\r
+    #define prog_int32_t    const int32_t\r
+    #define prog_uint32_t   const uint32_t\r
+    #define prog_int64_t    const int64_t\r
+    #define prog_uint64_t   const uint64_t\r
+\r
+    //Redefine the function for reading from flash in ChipKit\r
+    #define memcpy_P        memcpy\r
+#endif\r
+\r
+#endif /* PLATFORM_H__ */\r
diff --git a/src/nrf8001/jsupm_nrf8001.i b/src/nrf8001/jsupm_nrf8001.i
new file mode 100644 (file)
index 0000000..cb1aadd
--- /dev/null
@@ -0,0 +1,8 @@
+%module jsupm_nrf8001
+%include "../upm.i"
+
+%{
+    #include "nrf8001.h"
+%}
+
+%include "nrf8001.h"
diff --git a/src/nrf8001/lib_aci.cpp b/src/nrf8001/lib_aci.cpp
new file mode 100644 (file)
index 0000000..c194876
--- /dev/null
@@ -0,0 +1,742 @@
+/* Copyright (c) 2014, Nordic Semiconductor ASA\r
+ *\r
+ * Permission is hereby granted, free of charge, to any person obtaining a copy\r
+ * of this software and associated documentation files (the "Software"), to deal\r
+ * in the Software without restriction, including without limitation the rights\r
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+ * copies of the Software, and to permit persons to whom the Software is\r
+ * furnished to do so, subject to the following conditions:\r
+ *\r
+ * The above copyright notice and this permission notice shall be included in all\r
+ * copies or substantial portions of the Software.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ */\r
+\r
+/** @file\r
+  @brief Implementation of the ACI library.\r
+ */\r
+\r
+#include "hal_platform.h"\r
+#include "aci.h"\r
+#include "aci_cmds.h"\r
+#include "aci_evts.h"\r
+#include "aci_protocol_defines.h"\r
+#include "acilib_defs.h"\r
+#include "acilib_if.h"\r
+#include "hal_aci_tl.h"\r
+#include "aci_queue.h"\r
+#include "lib_aci.h"\r
+\r
+\r
+#define LIB_ACI_DEFAULT_CREDIT_NUMBER   1\r
+\r
+/*\r
+Global additionally used used in aci_setup\r
+*/\r
+hal_aci_data_t  msg_to_send;\r
+\r
+\r
+static services_pipe_type_mapping_t * p_services_pipe_type_map;\r
+static hal_aci_data_t *               p_setup_msgs;\r
+\r
+\r
+\r
+\r
+static bool is_request_operation_pending;\r
+static bool is_indicate_operation_pending;\r
+static bool is_open_remote_pipe_pending;\r
+static bool is_close_remote_pipe_pending;\r
+\r
+static uint8_t request_operation_pipe = 0;\r
+static uint8_t indicate_operation_pipe = 0;\r
+\r
+\r
+// The following structure (aci_cmd_params_open_adv_pipe) will be used to store the complete command\r
+// including the pipes to be opened.\r
+static aci_cmd_params_open_adv_pipe_t aci_cmd_params_open_adv_pipe;\r
+\r
+\r
+\r
+extern aci_queue_t    aci_rx_q;\r
+extern aci_queue_t    aci_tx_q;\r
+\r
+bool lib_aci_is_pipe_available(aci_state_t *aci_stat, uint8_t pipe)\r
+{\r
+  uint8_t byte_idx;\r
+\r
+  byte_idx = pipe / 8;\r
+  if (aci_stat->pipes_open_bitmap[byte_idx] & (0x01 << (pipe % 8)))\r
+  {\r
+    return(true);\r
+  }\r
+  return(false);\r
+}\r
+\r
+\r
+bool lib_aci_is_pipe_closed(aci_state_t *aci_stat, uint8_t pipe)\r
+{\r
+  uint8_t byte_idx;\r
+\r
+  byte_idx = pipe / 8;\r
+  if (aci_stat->pipes_closed_bitmap[byte_idx] & (0x01 << (pipe % 8)))\r
+  {\r
+    return(true);\r
+  }\r
+  return(false);\r
+}\r
+\r
+\r
+bool lib_aci_is_discovery_finished(aci_state_t *aci_stat)\r
+{\r
+  return(aci_stat->pipes_open_bitmap[0]&0x01);\r
+}\r
+\r
+void lib_aci_board_init(aci_state_t *aci_stat)\r
+{\r
+    hal_aci_evt_t *aci_data = NULL;\r
+    aci_data = (hal_aci_evt_t *)&msg_to_send;\r
+\r
+    if (REDBEARLAB_SHIELD_V1_1 == aci_stat->aci_pins.board_name)\r
+    {\r
+      /*\r
+      The Bluetooth low energy Arduino shield v1.1 requires about 100ms to reset.\r
+      This is not required for the nRF2740, nRF2741 modules\r
+      */\r
+      usleep(100000);\r
+\r
+      /*\r
+      Send the soft reset command to the nRF8001 to get the nRF8001 to a known state.\r
+      */\r
+      lib_aci_radio_reset();\r
+\r
+      while (1)\r
+      {\r
+        /*Wait for the command response of the radio reset command.\r
+        as the nRF8001 will be in either SETUP or STANDBY after the ACI Reset Radio is processed\r
+        */\r
+\r
+\r
+        if (true == lib_aci_event_get(aci_stat, aci_data))\r
+        {\r
+          aci_evt_t * aci_evt;\r
+          aci_evt = &(aci_data->evt);\r
+\r
+          if (ACI_EVT_CMD_RSP == aci_evt->evt_opcode)\r
+          {\r
+                if (ACI_STATUS_ERROR_DEVICE_STATE_INVALID == aci_evt->params.cmd_rsp.cmd_status) //in SETUP\r
+                {\r
+                    //Inject a Device Started Event Setup to the ACI Event Queue\r
+                    msg_to_send.buffer[0] = 4;    //Length\r
+                    msg_to_send.buffer[1] = 0x81; //Device Started Event\r
+                    msg_to_send.buffer[2] = 0x02; //Setup\r
+                    msg_to_send.buffer[3] = 0;    //Hardware Error -> None\r
+                    msg_to_send.buffer[4] = 2;    //Data Credit Available\r
+                    aci_queue_enqueue(&aci_rx_q, &msg_to_send);\r
+                }\r
+                else if (ACI_STATUS_SUCCESS == aci_evt->params.cmd_rsp.cmd_status) //We are now in STANDBY\r
+                {\r
+                    //Inject a Device Started Event Standby to the ACI Event Queue\r
+                    msg_to_send.buffer[0] = 4;    //Length\r
+                    msg_to_send.buffer[1] = 0x81; //Device Started Event\r
+                    msg_to_send.buffer[2] = 0x03; //Standby\r
+                    msg_to_send.buffer[3] = 0;    //Hardware Error -> None\r
+                    msg_to_send.buffer[4] = 2;    //Data Credit Available\r
+                    aci_queue_enqueue(&aci_rx_q, &msg_to_send);\r
+                }\r
+                else if (ACI_STATUS_ERROR_CMD_UNKNOWN == aci_evt->params.cmd_rsp.cmd_status) //We are now in TEST\r
+                {\r
+                    //Inject a Device Started Event Test to the ACI Event Queue\r
+                    msg_to_send.buffer[0] = 4;    //Length\r
+                    msg_to_send.buffer[1] = 0x81; //Device Started Event\r
+                    msg_to_send.buffer[2] = 0x01; //Test\r
+                    msg_to_send.buffer[3] = 0;    //Hardware Error -> None\r
+                    msg_to_send.buffer[4] = 0;    //Data Credit Available\r
+                    aci_queue_enqueue(&aci_rx_q, &msg_to_send);\r
+                }\r
+\r
+                printf ("BREAK\n");\r
+                //Break out of the while loop\r
+                break;\r
+          }\r
+          else\r
+          {\r
+            //Serial.println(F("Discard any other ACI Events"));\r
+          }\r
+\r
+        }\r
+      }\r
+    }\r
+}\r
+\r
+\r
+void lib_aci_init(aci_state_t *aci_stat, bool debug)\r
+{\r
+    uint8_t i;\r
+\r
+    for (i = 0; i < PIPES_ARRAY_SIZE; i++) {\r
+        aci_stat->pipes_open_bitmap[i]          = 0;\r
+        aci_stat->pipes_closed_bitmap[i]        = 0;\r
+        aci_cmd_params_open_adv_pipe.pipes[i]   = 0;\r
+    }\r
+\r
+    is_request_operation_pending     = false;\r
+    is_indicate_operation_pending    = false;\r
+    is_open_remote_pipe_pending      = false;\r
+    is_close_remote_pipe_pending     = false;\r
+\r
+    request_operation_pipe           = 0;\r
+    indicate_operation_pipe          = 0;\r
+\r
+    p_services_pipe_type_map = aci_stat->aci_setup_info.services_pipe_type_mapping;\r
+    p_setup_msgs             = aci_stat->aci_setup_info.setup_msgs;\r
+\r
+    hal_aci_tl_init (&aci_stat->aci_pins, debug);\r
+    lib_aci_board_init (aci_stat);\r
+}\r
+\r
+\r
+uint8_t lib_aci_get_nb_available_credits(aci_state_t *aci_stat)\r
+{\r
+  return aci_stat->data_credit_available;\r
+}\r
+\r
+uint16_t lib_aci_get_cx_interval_ms(aci_state_t *aci_stat)\r
+{\r
+  uint32_t cx_rf_interval_ms_32bits;\r
+  uint16_t cx_rf_interval_ms;\r
+\r
+  cx_rf_interval_ms_32bits  = aci_stat->connection_interval;\r
+  cx_rf_interval_ms_32bits *= 125;                      // the connection interval is given in multiples of 0.125 milliseconds\r
+  cx_rf_interval_ms         = cx_rf_interval_ms_32bits / 100;\r
+\r
+  return cx_rf_interval_ms;\r
+}\r
+\r
+\r
+uint16_t lib_aci_get_cx_interval(aci_state_t *aci_stat)\r
+{\r
+  return aci_stat->connection_interval;\r
+}\r
+\r
+\r
+uint16_t lib_aci_get_slave_latency(aci_state_t *aci_stat)\r
+{\r
+  return aci_stat->slave_latency;\r
+}\r
+\r
+\r
+bool lib_aci_set_app_latency(uint16_t latency, aci_app_latency_mode_t latency_mode)\r
+{\r
+  aci_cmd_params_set_app_latency_t aci_set_app_latency;\r
+\r
+  aci_set_app_latency.mode    = latency_mode;\r
+  aci_set_app_latency.latency = latency;\r
+  acil_encode_cmd_set_app_latency(&(msg_to_send.buffer[0]), &aci_set_app_latency);\r
+\r
+  return hal_aci_tl_send(&msg_to_send);\r
+}\r
+\r
+\r
+bool lib_aci_test(aci_test_mode_change_t enter_exit_test_mode)\r
+{\r
+  aci_cmd_params_test_t aci_cmd_params_test;\r
+  aci_cmd_params_test.test_mode_change = enter_exit_test_mode;\r
+  acil_encode_cmd_set_test_mode(&(msg_to_send.buffer[0]), &aci_cmd_params_test);\r
+  return hal_aci_tl_send(&msg_to_send);\r
+}\r
+\r
+\r
+bool lib_aci_sleep()\r
+{\r
+  acil_encode_cmd_sleep(&(msg_to_send.buffer[0]));\r
+  return hal_aci_tl_send(&msg_to_send);\r
+}\r
+\r
+\r
+bool lib_aci_radio_reset()\r
+{\r
+  acil_encode_baseband_reset(&(msg_to_send.buffer[0]));\r
+  return hal_aci_tl_send(&msg_to_send);\r
+}\r
+\r
+\r
+bool lib_aci_direct_connect()\r
+{\r
+  acil_encode_direct_connect(&(msg_to_send.buffer[0]));\r
+  return hal_aci_tl_send(&msg_to_send);\r
+}\r
+\r
+\r
+bool lib_aci_device_version()\r
+{\r
+  acil_encode_cmd_get_device_version(&(msg_to_send.buffer[0]));\r
+  return hal_aci_tl_send(&msg_to_send);\r
+}\r
+\r
+\r
+bool lib_aci_set_local_data(aci_state_t *aci_stat, uint8_t pipe, uint8_t *p_value, uint8_t size)\r
+{\r
+  aci_cmd_params_set_local_data_t aci_cmd_params_set_local_data;\r
+\r
+  if ((p_services_pipe_type_map[pipe-1].location != ACI_STORE_LOCAL)\r
+      ||\r
+      (size > ACI_PIPE_TX_DATA_MAX_LEN))\r
+  {\r
+    return false;\r
+  }\r
+\r
+  aci_cmd_params_set_local_data.tx_data.pipe_number = pipe;\r
+  memcpy(&(aci_cmd_params_set_local_data.tx_data.aci_data[0]), p_value, size);\r
+  acil_encode_cmd_set_local_data(&(msg_to_send.buffer[0]), &aci_cmd_params_set_local_data, size);\r
+  return hal_aci_tl_send(&msg_to_send);\r
+}\r
+\r
+bool lib_aci_connect(uint16_t run_timeout, uint16_t adv_interval)\r
+{\r
+  aci_cmd_params_connect_t aci_cmd_params_connect;\r
+  aci_cmd_params_connect.timeout      = run_timeout;\r
+  aci_cmd_params_connect.adv_interval = adv_interval;\r
+  acil_encode_cmd_connect(&(msg_to_send.buffer[0]), &aci_cmd_params_connect);\r
+  return hal_aci_tl_send(&msg_to_send);\r
+}\r
+\r
+\r
+bool lib_aci_disconnect(aci_state_t *aci_stat, aci_disconnect_reason_t reason)\r
+{\r
+  bool ret_val;\r
+  uint8_t i;\r
+  aci_cmd_params_disconnect_t aci_cmd_params_disconnect;\r
+  aci_cmd_params_disconnect.reason = reason;\r
+  acil_encode_cmd_disconnect(&(msg_to_send.buffer[0]), &aci_cmd_params_disconnect);\r
+  ret_val = hal_aci_tl_send(&msg_to_send);\r
+  // If we have actually sent the disconnect\r
+  if (ret_val)\r
+  {\r
+    // Update pipes immediately so that while the disconnect is happening,\r
+    // the application can't attempt sending another message\r
+    // If the application sends another message before we updated this\r
+    //    a ACI Pipe Error Event will be received from nRF8001\r
+    for (i=0; i < PIPES_ARRAY_SIZE; i++)\r
+    {\r
+      aci_stat->pipes_open_bitmap[i] = 0;\r
+      aci_stat->pipes_closed_bitmap[i] = 0;\r
+    }\r
+  }\r
+  return ret_val;\r
+}\r
+\r
+\r
+bool lib_aci_bond(uint16_t run_timeout, uint16_t adv_interval)\r
+{\r
+  aci_cmd_params_bond_t aci_cmd_params_bond;\r
+  aci_cmd_params_bond.timeout = run_timeout;\r
+  aci_cmd_params_bond.adv_interval = adv_interval;\r
+  acil_encode_cmd_bond(&(msg_to_send.buffer[0]), &aci_cmd_params_bond);\r
+  return hal_aci_tl_send(&msg_to_send);\r
+}\r
+\r
+\r
+bool lib_aci_wakeup()\r
+{\r
+  acil_encode_cmd_wakeup(&(msg_to_send.buffer[0]));\r
+  return hal_aci_tl_send(&msg_to_send);\r
+}\r
+\r
+\r
+bool lib_aci_set_tx_power(aci_device_output_power_t tx_power)\r
+{\r
+  aci_cmd_params_set_tx_power_t aci_cmd_params_set_tx_power;\r
+  aci_cmd_params_set_tx_power.device_power = tx_power;\r
+  acil_encode_cmd_set_radio_tx_power(&(msg_to_send.buffer[0]), &aci_cmd_params_set_tx_power);\r
+  return hal_aci_tl_send(&msg_to_send);\r
+}\r
+\r
+\r
+bool lib_aci_get_address()\r
+{\r
+  acil_encode_cmd_get_address(&(msg_to_send.buffer[0]));\r
+  return hal_aci_tl_send(&msg_to_send);\r
+}\r
+\r
+\r
+bool lib_aci_get_temperature()\r
+{\r
+  acil_encode_cmd_temparature(&(msg_to_send.buffer[0]));\r
+  return hal_aci_tl_send(&msg_to_send);\r
+}\r
+\r
+\r
+bool lib_aci_get_battery_level()\r
+{\r
+  acil_encode_cmd_battery_level(&(msg_to_send.buffer[0]));\r
+  return hal_aci_tl_send(&msg_to_send);\r
+}\r
+\r
+\r
+bool lib_aci_send_data(uint8_t pipe, uint8_t *p_value, uint8_t size)\r
+{\r
+  bool ret_val = false;\r
+  aci_cmd_params_send_data_t aci_cmd_params_send_data;\r
+\r
+\r
+  if(!((p_services_pipe_type_map[pipe-1].pipe_type == ACI_TX) ||\r
+      (p_services_pipe_type_map[pipe-1].pipe_type == ACI_TX_ACK)))\r
+  {\r
+    return false;\r
+  }\r
+\r
+  if (size > ACI_PIPE_TX_DATA_MAX_LEN)\r
+  {\r
+    return false;\r
+  }\r
+  {\r
+      aci_cmd_params_send_data.tx_data.pipe_number = pipe;\r
+      memcpy(&(aci_cmd_params_send_data.tx_data.aci_data[0]), p_value, size);\r
+      acil_encode_cmd_send_data(&(msg_to_send.buffer[0]), &aci_cmd_params_send_data, size);\r
+\r
+      ret_val = hal_aci_tl_send(&msg_to_send);\r
+  }\r
+  return ret_val;\r
+}\r
+\r
+\r
+bool lib_aci_request_data(aci_state_t *aci_stat, uint8_t pipe)\r
+{\r
+  bool ret_val = false;\r
+  aci_cmd_params_request_data_t aci_cmd_params_request_data;\r
+\r
+  if(!((p_services_pipe_type_map[pipe-1].location == ACI_STORE_REMOTE)&&(p_services_pipe_type_map[pipe-1].pipe_type == ACI_RX_REQ)))\r
+  {\r
+    return false;\r
+  }\r
+\r
+\r
+  {\r
+\r
+    {\r
+\r
+\r
+\r
+      aci_cmd_params_request_data.pipe_number = pipe;\r
+      acil_encode_cmd_request_data(&(msg_to_send.buffer[0]), &aci_cmd_params_request_data);\r
+\r
+      ret_val = hal_aci_tl_send(&msg_to_send);\r
+    }\r
+  }\r
+  return ret_val;\r
+}\r
+\r
+\r
+bool lib_aci_change_timing(uint16_t minimun_cx_interval, uint16_t maximum_cx_interval, uint16_t slave_latency, uint16_t timeout)\r
+{\r
+  aci_cmd_params_change_timing_t aci_cmd_params_change_timing;\r
+  aci_cmd_params_change_timing.conn_params.min_conn_interval = minimun_cx_interval;\r
+  aci_cmd_params_change_timing.conn_params.max_conn_interval = maximum_cx_interval;\r
+  aci_cmd_params_change_timing.conn_params.slave_latency     = slave_latency;\r
+  aci_cmd_params_change_timing.conn_params.timeout_mult      = timeout;\r
+  acil_encode_cmd_change_timing_req(&(msg_to_send.buffer[0]), &aci_cmd_params_change_timing);\r
+  return hal_aci_tl_send(&msg_to_send);\r
+}\r
+\r
+\r
+bool lib_aci_change_timing_GAP_PPCP()\r
+{\r
+  acil_encode_cmd_change_timing_req_GAP_PPCP(&(msg_to_send.buffer[0]));\r
+  return hal_aci_tl_send(&msg_to_send);\r
+}\r
+\r
+\r
+bool lib_aci_open_remote_pipe(aci_state_t *aci_stat, uint8_t pipe)\r
+{\r
+  bool ret_val = false;\r
+  aci_cmd_params_open_remote_pipe_t aci_cmd_params_open_remote_pipe;\r
+\r
+  if(!((p_services_pipe_type_map[pipe-1].location == ACI_STORE_REMOTE)&&\r
+                ((p_services_pipe_type_map[pipe-1].pipe_type == ACI_RX)||\r
+                (p_services_pipe_type_map[pipe-1].pipe_type == ACI_RX_ACK_AUTO)||\r
+                (p_services_pipe_type_map[pipe-1].pipe_type == ACI_RX_ACK))))\r
+  {\r
+    return false;\r
+  }\r
+\r
+\r
+  {\r
+\r
+    is_request_operation_pending = true;\r
+    is_open_remote_pipe_pending = true;\r
+    request_operation_pipe = pipe;\r
+    aci_cmd_params_open_remote_pipe.pipe_number = pipe;\r
+    acil_encode_cmd_open_remote_pipe(&(msg_to_send.buffer[0]), &aci_cmd_params_open_remote_pipe);\r
+    ret_val = hal_aci_tl_send(&msg_to_send);\r
+  }\r
+  return ret_val;\r
+}\r
+\r
+\r
+bool lib_aci_close_remote_pipe(aci_state_t *aci_stat, uint8_t pipe)\r
+{\r
+  bool ret_val = false;\r
+  aci_cmd_params_close_remote_pipe_t aci_cmd_params_close_remote_pipe;\r
+\r
+  if(!((p_services_pipe_type_map[pipe-1].location == ACI_STORE_REMOTE)&&\r
+        ((p_services_pipe_type_map[pipe-1].pipe_type == ACI_RX)||\r
+         (p_services_pipe_type_map[pipe-1].pipe_type == ACI_RX_ACK_AUTO)||\r
+         (p_services_pipe_type_map[pipe-1].pipe_type == ACI_RX_ACK))))\r
+  {\r
+    return false;\r
+  }\r
+\r
+\r
+  {\r
+\r
+    is_request_operation_pending = true;\r
+    is_close_remote_pipe_pending = true;\r
+    request_operation_pipe = pipe;\r
+    aci_cmd_params_close_remote_pipe.pipe_number = pipe;\r
+    acil_encode_cmd_close_remote_pipe(&(msg_to_send.buffer[0]), &aci_cmd_params_close_remote_pipe);\r
+    ret_val = hal_aci_tl_send(&msg_to_send);\r
+  }\r
+  return ret_val;\r
+}\r
+\r
+\r
+bool lib_aci_set_key(aci_key_type_t key_rsp_type, uint8_t *key, uint8_t len)\r
+{\r
+  aci_cmd_params_set_key_t aci_cmd_params_set_key;\r
+  aci_cmd_params_set_key.key_type = key_rsp_type;\r
+  memcpy((uint8_t*)&(aci_cmd_params_set_key.key), key, len);\r
+  acil_encode_cmd_set_key(&(msg_to_send.buffer[0]), &aci_cmd_params_set_key);\r
+  return hal_aci_tl_send(&msg_to_send);\r
+}\r
+\r
+\r
+bool lib_aci_echo_msg(uint8_t msg_size, uint8_t *p_msg_data)\r
+{\r
+  aci_cmd_params_echo_t aci_cmd_params_echo;\r
+  if(msg_size > (ACI_ECHO_DATA_MAX_LEN))\r
+  {\r
+    return false;\r
+  }\r
+\r
+  if (msg_size > (ACI_ECHO_DATA_MAX_LEN))\r
+  {\r
+    msg_size = ACI_ECHO_DATA_MAX_LEN;\r
+  }\r
+\r
+  memcpy(&(aci_cmd_params_echo.echo_data[0]), p_msg_data, msg_size);\r
+  acil_encode_cmd_echo_msg(&(msg_to_send.buffer[0]), &aci_cmd_params_echo, msg_size);\r
+\r
+  return hal_aci_tl_send(&msg_to_send);\r
+}\r
+\r
+\r
+bool lib_aci_bond_request()\r
+{\r
+  acil_encode_cmd_bond_security_request(&(msg_to_send.buffer[0]));\r
+  return hal_aci_tl_send(&msg_to_send);\r
+}\r
+\r
+bool lib_aci_event_peek(hal_aci_evt_t *p_aci_evt_data)\r
+{\r
+  return hal_aci_tl_event_peek((hal_aci_data_t *)p_aci_evt_data);\r
+}\r
+\r
+bool lib_aci_event_get(aci_state_t *aci_stat, hal_aci_evt_t *p_aci_evt_data)\r
+{\r
+  bool status = false;\r
+\r
+  status = hal_aci_tl_event_get((hal_aci_data_t *)p_aci_evt_data);\r
+\r
+  /**\r
+  Update the state of the ACI with the\r
+  ACI Events -> Pipe Status, Disconnected, Connected, Bond Status, Pipe Error\r
+  */\r
+  if (true == status)\r
+  {\r
+    aci_evt_t * aci_evt;\r
+\r
+    aci_evt = &p_aci_evt_data->evt;\r
+\r
+    switch(aci_evt->evt_opcode)\r
+    {\r
+        case ACI_EVT_PIPE_STATUS:\r
+            {\r
+                uint8_t i=0;\r
+\r
+                for (i=0; i < PIPES_ARRAY_SIZE; i++)\r
+                {\r
+                  aci_stat->pipes_open_bitmap[i]   = aci_evt->params.pipe_status.pipes_open_bitmap[i];\r
+                  aci_stat->pipes_closed_bitmap[i] = aci_evt->params.pipe_status.pipes_closed_bitmap[i];\r
+                }\r
+            }\r
+            break;\r
+\r
+        case ACI_EVT_DISCONNECTED:\r
+            {\r
+                uint8_t i=0;\r
+\r
+                for (i=0; i < PIPES_ARRAY_SIZE; i++)\r
+                {\r
+                  aci_stat->pipes_open_bitmap[i] = 0;\r
+                  aci_stat->pipes_closed_bitmap[i] = 0;\r
+                }\r
+                aci_stat->confirmation_pending = false;\r
+                aci_stat->data_credit_available = aci_stat->data_credit_total;\r
+\r
+            }\r
+            break;\r
+\r
+        case ACI_EVT_TIMING:\r
+                aci_stat->connection_interval = aci_evt->params.timing.conn_rf_interval;\r
+                aci_stat->slave_latency       = aci_evt->params.timing.conn_slave_rf_latency;\r
+                aci_stat->supervision_timeout = aci_evt->params.timing.conn_rf_timeout;\r
+            break;\r
+\r
+        default:\r
+            /* Need default case to avoid compiler warnings about missing enum\r
+             * values on some platforms.\r
+             */\r
+            break;\r
+\r
+\r
+\r
+    }\r
+  }\r
+  return status;\r
+}\r
+\r
+\r
+bool lib_aci_send_ack(aci_state_t *aci_stat, const uint8_t pipe)\r
+{\r
+  bool ret_val = false;\r
+  {\r
+    acil_encode_cmd_send_data_ack(&(msg_to_send.buffer[0]), pipe);\r
+\r
+    ret_val = hal_aci_tl_send(&msg_to_send);\r
+  }\r
+  return ret_val;\r
+}\r
+\r
+\r
+bool lib_aci_send_nack(aci_state_t *aci_stat, const uint8_t pipe, const uint8_t error_code)\r
+{\r
+  bool ret_val = false;\r
+\r
+  {\r
+\r
+    acil_encode_cmd_send_data_nack(&(msg_to_send.buffer[0]), pipe, error_code);\r
+    ret_val = hal_aci_tl_send(&msg_to_send);\r
+  }\r
+  return ret_val;\r
+}\r
+\r
+\r
+bool lib_aci_broadcast(const uint16_t timeout, const uint16_t adv_interval)\r
+{\r
+  aci_cmd_params_broadcast_t aci_cmd_params_broadcast;\r
+  if (timeout > 16383)\r
+  {\r
+    return false;\r
+  }\r
+\r
+  // The adv_interval should be between 160 and 16384 (which translates to the advertisement\r
+  // interval values 100 ms and 10.24 s.\r
+  if ((160 > adv_interval) || (adv_interval > 16384))\r
+  {\r
+    return false;\r
+  }\r
+\r
+  aci_cmd_params_broadcast.timeout = timeout;\r
+  aci_cmd_params_broadcast.adv_interval = adv_interval;\r
+  acil_encode_cmd_broadcast(&(msg_to_send.buffer[0]), &aci_cmd_params_broadcast);\r
+  return hal_aci_tl_send(&msg_to_send);\r
+}\r
+\r
+\r
+bool lib_aci_open_adv_pipes(const uint8_t * const adv_service_data_pipes)\r
+{\r
+  uint8_t i;\r
+\r
+  for (i = 0; i < PIPES_ARRAY_SIZE; i++)\r
+  {\r
+    aci_cmd_params_open_adv_pipe.pipes[i] = adv_service_data_pipes[i];\r
+  }\r
+\r
+  acil_encode_cmd_open_adv_pipes(&(msg_to_send.buffer[0]), &aci_cmd_params_open_adv_pipe);\r
+  return hal_aci_tl_send(&msg_to_send);\r
+}\r
+\r
+bool lib_aci_open_adv_pipe(const uint8_t pipe)\r
+{\r
+  uint8_t byte_idx = pipe / 8;\r
+\r
+  aci_cmd_params_open_adv_pipe.pipes[byte_idx] |= (0x01 << (pipe % 8));\r
+  acil_encode_cmd_open_adv_pipes(&(msg_to_send.buffer[0]), &aci_cmd_params_open_adv_pipe);\r
+  return hal_aci_tl_send(&msg_to_send);\r
+}\r
+\r
+\r
+bool lib_aci_read_dynamic_data()\r
+{\r
+  acil_encode_cmd_read_dynamic_data(&(msg_to_send.buffer[0]));\r
+  return hal_aci_tl_send(&msg_to_send);\r
+}\r
+\r
+\r
+bool lib_aci_write_dynamic_data(uint8_t sequence_number, uint8_t* dynamic_data, uint8_t length)\r
+{\r
+  acil_encode_cmd_write_dynamic_data(&(msg_to_send.buffer[0]), sequence_number, dynamic_data, length);\r
+  return hal_aci_tl_send(&msg_to_send);\r
+}\r
+\r
+bool lib_aci_dtm_command(uint8_t dtm_command_msbyte, uint8_t dtm_command_lsbyte)\r
+{\r
+  aci_cmd_params_dtm_cmd_t aci_cmd_params_dtm_cmd;\r
+  aci_cmd_params_dtm_cmd.cmd_msb = dtm_command_msbyte;\r
+  aci_cmd_params_dtm_cmd.cmd_lsb = dtm_command_lsbyte;\r
+  acil_encode_cmd_dtm_cmd(&(msg_to_send.buffer[0]), &aci_cmd_params_dtm_cmd);\r
+  return hal_aci_tl_send(&msg_to_send);\r
+}\r
+\r
+void lib_aci_flush(void)\r
+{\r
+  hal_aci_tl_q_flush();\r
+}\r
+\r
+void lib_aci_debug_print(bool enable)\r
+{\r
+  hal_aci_tl_debug_print(enable);\r
+\r
+}\r
+\r
+void lib_aci_pin_reset(void)\r
+{\r
+    hal_aci_tl_pin_reset();\r
+}\r
+\r
+bool lib_aci_event_queue_empty(void)\r
+{\r
+  return hal_aci_tl_rx_q_empty();\r
+}\r
+\r
+bool lib_aci_event_queue_full(void)\r
+{\r
+  return hal_aci_tl_rx_q_full();\r
+}\r
+\r
+bool lib_aci_command_queue_empty(void)\r
+{\r
+  return hal_aci_tl_tx_q_empty();\r
+}\r
+\r
+bool lib_aci_command_queue_full(void)\r
+{\r
+  return hal_aci_tl_tx_q_full();\r
+}\r
diff --git a/src/nrf8001/lib_aci.h b/src/nrf8001/lib_aci.h
new file mode 100644 (file)
index 0000000..39266c5
--- /dev/null
@@ -0,0 +1,564 @@
+/* Copyright (c) 2014, Nordic Semiconductor ASA\r
+ *\r
+ * Permission is hereby granted, free of charge, to any person obtaining a copy\r
+ * of this software and associated documentation files (the "Software"), to deal\r
+ * in the Software without restriction, including without limitation the rights\r
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+ * copies of the Software, and to permit persons to whom the Software is\r
+ * furnished to do so, subject to the following conditions:\r
+ *\r
+ * The above copyright notice and this permission notice shall be included in all\r
+ * copies or substantial portions of the Software.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ */\r
+\r
+#ifndef LIB_ACI_H__\r
+#define LIB_ACI_H__\r
+\r
+/** @file\r
+* @brief ACI library\r
+*/\r
+\r
+/** @addtogroup lib_aci\r
+@{\r
+@brief Library for the logical part of the Application Controller Interface (ACI)\r
+*/\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+#include "hal_platform.h"\r
+#include "hal_aci_tl.h"\r
+#include "aci_queue.h"\r
+#include "aci.h"\r
+#include "aci_cmds.h"\r
+#include "aci_evts.h"\r
+\r
+#define EVT_CMD_RESPONSE_MIN_LENGTH              3\r
+\r
+#define PIPES_ARRAY_SIZE                ((ACI_DEVICE_MAX_PIPES + 7)/8)\r
+\r
+/* Same size as a hal_aci_data_t */\r
+typedef struct {\r
+  uint8_t   debug_byte;\r
+  aci_evt_t evt;\r
+} _aci_packed_ hal_aci_evt_t;\r
+\r
+ACI_ASSERT_SIZE(hal_aci_evt_t, 34);\r
+\r
+typedef struct\r
+{\r
+  uint8_t  location; /**< enum aci_pipe_store_t */\r
+  aci_pipe_type_t   pipe_type;\r
+} services_pipe_type_mapping_t;\r
+\r
+typedef struct aci_setup_info_t\r
+{\r
+  services_pipe_type_mapping_t *services_pipe_type_mapping;\r
+  uint8_t                       number_of_pipes;\r
+  hal_aci_data_t               *setup_msgs;\r
+  uint8_t                       num_setup_msgs;\r
+} aci_setup_info_t;\r
+\r
+\r
+\r
+// aci_struct that will contain\r
+// total initial credits\r
+// current credit\r
+// current state of the aci (setup/standby/active/sleep)\r
+// open remote pipe pending\r
+// close remote pipe pending\r
+// Current pipe available bitmap\r
+// Current pipe closed bitmap\r
+// Current connection interval, slave latency and link supervision timeout\r
+// Current State of the the GATT client (Service Discovery status)\r
+// Relationship of bond to peer address\r
+typedef struct aci_state_t\r
+{\r
+    aci_pins_t                    aci_pins;                               /* Pins on the MCU used to connect to the nRF8001 */\r
+    aci_setup_info_t              aci_setup_info;                         /* Data structures that are created from nRFgo Studio */\r
+    uint8_t                       bonded;                                 /* ( aci_bond_status_code_t ) Is the nRF8001 bonded to a peer device */\r
+    uint8_t                       data_credit_total;                      /* Total data credit available for the specific version of the nRF8001, total equals available when a link is established */\r
+    aci_device_operation_mode_t   device_state;                           /* Operating mode of the nRF8001 */\r
+\r
+    /* */\r
+\r
+    /* Start : Variables that are valid only when in a connection */\r
+    uint8_t                       data_credit_available;                  /* Available data credits at a specific point of time, ACI_EVT_DATA_CREDIT updates the available credits */\r
+\r
+    uint16_t                      connection_interval;                    /* Multiply by 1.25 to get the connection interval in milliseconds*/\r
+    uint16_t                      slave_latency;                          /* Number of consecutive connection intervals that the nRF8001 is not required to transmit. Use this to save power */\r
+    uint16_t                      supervision_timeout;                    /* Multiply by 10 to get the supervision timeout in milliseconds */\r
+\r
+    uint8_t                       pipes_open_bitmap[PIPES_ARRAY_SIZE];    /* Bitmap -> pipes are open and can be used for sending data over the air */\r
+    uint8_t                       pipes_closed_bitmap[PIPES_ARRAY_SIZE];  /* Bitmap -> pipes are closed and cannot be used for sending data over the air */\r
+    bool                          confirmation_pending;                   /* Attribute protocol Handle Value confirmation is pending for a Handle Value Indication\r
+                                                                        (ACK is pending for a TX_ACK pipe) on local GATT Server*/\r
+    /* End : Variables that are valid only when in a connection */\r
+\r
+} aci_state_t;\r
+\r
+\r
+\r
+#define DISCONNECT_REASON_CX_TIMEOUT                 0x08\r
+#define DISCONNECT_REASON_CX_CLOSED_BY_PEER_DEVICE   0x13\r
+#define DISCONNECT_REASON_POWER_LOSS                 0x14\r
+#define DISCONNECT_REASON_CX_CLOSED_BY_LOCAL_DEVICE  0x16\r
+#define DISCONNECT_REASON_ADVERTISER_TIMEOUT         0x50\r
+\r
+\r
+/** @name Functions for library management */\r
+//@{\r
+\r
+/** @brief Function to enable printing of all ACI commands sent and ACI events received\r
+ *  @details This function shall be used to enable or disable the debug printing.\r
+              Debug printing is disabled by default.\r
+ */\r
+void lib_aci_debug_print(bool enable);\r
+\r
+/** @brief Function to pin reset the nRF8001\r
+ *  @details Pin resets the nRF8001 also handles differences between development boards\r
+ */\r
+void lib_aci_pin_reset(void);\r
+\r
+/** @brief Initialization function.\r
+ *  @details This function shall be used to initialize/reset ACI Library and also Resets the\r
+ *           nRF8001 by togging the reset pin of the nRF8001. This function will reset\r
+ *           all the variables locally used by ACI library to their respective default values.\r
+ *  @param bool True if the data was successfully queued for sending,\r
+ *  false if there is no more space to store messages to send.\r
+ */\r
+void lib_aci_init(aci_state_t *aci_stat, bool debug);\r
+\r
+\r
+/** @brief Gets the number of currently available ACI credits.\r
+ *  @return Number of ACI credits.\r
+ */\r
+uint8_t lib_aci_get_nb_available_credits(aci_state_t *aci_stat);\r
+\r
+/** @brief Gets the connection interval in milliseconds.\r
+ *  @return Connection interval in milliseconds.\r
+ */\r
+uint16_t lib_aci_get_cx_interval_ms(aci_state_t *aci_stat);\r
+\r
+/** @brief Gets the connection interval in multiple of 1.25&nbsp;ms.\r
+ *  @return Connection interval in multiple of 1.25&nbsp;ms.\r
+ */\r
+uint16_t lib_aci_get_cx_interval(aci_state_t *aci_stat);\r
+\r
+/** @brief Gets the current slave latency.\r
+ *  @return Current slave latency.\r
+ */\r
+uint16_t lib_aci_get_slave_latency(aci_state_t *aci_stat);\r
+\r
+/** @brief Checks if a given pipe is available.\r
+ *  @param pipe Pipe to check.\r
+ *  @return True if the pipe is available, otherwise false.\r
+ */\r
+bool lib_aci_is_pipe_available(aci_state_t *aci_stat, uint8_t pipe);\r
+\r
+/** @brief Checks if a given pipe is closed.\r
+ *  @param pipe Pipe to check.\r
+ *  @return True if the pipe is closed, otherwise false.\r
+ */\r
+bool lib_aci_is_pipe_closed(aci_state_t *aci_stat, uint8_t pipe);\r
+\r
+/** @brief Checks if the discovery operation is finished.\r
+ *  @return True if the discovery is finished.\r
+ */\r
+bool lib_aci_is_discovery_finished(aci_state_t *aci_stat);\r
+\r
+\r
+\r
+//@}\r
+\r
+/** @name ACI Commands available in all modes */\r
+//@{\r
+\r
+/** @brief Sets the radio in sleep mode.\r
+ *  @details The function sends a @c sleep command to the radio.\r
+ *  If the radio is advertising or connected, it sends back an error, then use lib_aci_radio_reset\r
+ *  if advertising or disconnect if in a connection.\r
+ *  @return True if the transaction is successfully initiated.\r
+ */\r
+bool lib_aci_sleep(void);\r
+\r
+/** @brief Resets the radio.\r
+ *  @details The function sends a @c BasebandReset command to the radio.\r
+ *  @return True if the transaction is successfully initiated.\r
+ */\r
+bool lib_aci_radio_reset(void);\r
+\r
+/** @brief Radio starts directed advertising to bonded device.\r
+ *  @details The function sends a @c DirectedConnect command to the radio.\r
+ *  @return True if the transaction is successfully initiated.\r
+ */\r
+bool lib_aci_direct_connect(void);\r
+\r
+/** @brief Gets the radio's version.\r
+ *  @details This function sends a @c GetDeviceVersion command.\r
+ *  @return True if the transaction is successfully initiated.\r
+ */\r
+bool lib_aci_device_version(void);\r
+\r
+/** @brief Gets the device address.\r
+ *  @details This function sends a @c GetDeviceAddress command.\r
+ *  @return True if the transaction is successfully initiated.\r
+ */\r
+bool lib_aci_get_address(void);\r
+\r
+/** @brief Gets the temperature.\r
+ *  @details This function sends a @c GetTemperature command. lib_aci\r
+ *  calls the @ref lib_aci_transaction_finished_hook() function when the temperature is received.\r
+ *  @return True if the transaction is successfully initiated.\r
+ */\r
+bool lib_aci_get_temperature(void);\r
+\r
+/** @brief Gets the battery level.\r
+ *  @details This function sends a @c GetBatteryLevel command.\r
+ *  @return True if the transaction is successfully initiated.\r
+ */\r
+bool lib_aci_get_battery_level(void);\r
+\r
+//@}\r
+\r
+/** @name ACI commands available in Sleep mode */\r
+//@{\r
+\r
+/** @brief Wakes up the radio.\r
+ *  @details This function sends a @c Wakeup command to wake up the radio from\r
+ *  sleep mode. When woken up the radio sends a @c DeviceStartedEvent and\r
+ *  a @c CommandResponseEvent.\r
+ *  @return True if the transaction is successfully initiated.\r
+ */\r
+bool lib_aci_wakeup(void);\r
+\r
+//@}\r
+\r
+/** @name ACI commands available in Active mode */\r
+//@{\r
+\r
+/** @brief Sets the radio in test mode.\r
+ *  @details This function sends a @c Test command to the radio. There are two\r
+ *  Test modes available:\r
+ *  - UART: DTM commands are received over UART.\r
+ *  - ACI: DTM commands are received over ACI.\r
+ *  The same command is used to exit the test mode When receiving\r
+ *  a @c DeviceStartedEvent the radio has entered the new mode.\r
+ *  @param enter_exit_test_mode Enter a Test mode, or exit Test mode.\r
+ *  @return True if the transaction is successfully initiated.\r
+ */\r
+bool lib_aci_test(aci_test_mode_change_t enter_exit_test_mode);\r
+\r
+/** @brief Sets the radio's TX power.\r
+ *  @details This function sends a @c SetTxPower command.\r
+ *  @param tx_power TX power to be used by the radio.\r
+ *  @return True if the transaction is successfully initiated.\r
+ */\r
+bool lib_aci_set_tx_power(aci_device_output_power_t tx_power);\r
+\r
+/** @brief Tries to connect to a peer device.\r
+ *  @details This function sends a @c Connect command to the radio.\r
+ *  @param run_timeout Maximum advertising time in seconds (0 means infinite).\r
+ *  @param adv_interval Advertising interval (in multiple of 0.625&nbsp;ms).\r
+ *  @return True if the transaction is successfully initiated.\r
+ */\r
+bool lib_aci_connect(uint16_t run_timeout, uint16_t adv_interval);\r
+\r
+/** @brief Tries to bond with a peer device.\r
+ *  @details This function sends a @c Bond command to the radio.\r
+ *  @param run_timeout Maximum advertising time in seconds (0 means infinite).\r
+ *  @param adv_interval Advertising interval (in multiple of 0.625&nbsp;ms).\r
+ *  @return True if the transaction is successfully initiated.\r
+ */\r
+bool lib_aci_bond(uint16_t run_timeout, uint16_t adv_interval);\r
+\r
+/** @brief Disconnects from peer device.\r
+ *  @details This function sends a @c Disconnect command to the radio.\r
+ *  @param reason Reason for disconnecting.\r
+ *  @return True if the transaction is successfully initiated.\r
+ */\r
+bool lib_aci_disconnect(aci_state_t *aci_stat, aci_disconnect_reason_t reason);\r
+\r
+/**@brief Sets Local Data.\r
+ *  @details\r
+ *  This command updates the value of the characteristic value or the characteristic descriptor stored locally on the device.\r
+ *  Can be called for all types of pipes as long as the data is stored locally.\r
+ *  @param ACI state structure\r
+ *  @param pipe Pipe number on which the data should be set.\r
+ *  @param value Pointer to the data to set.\r
+ *  @param size Size of the data to set.\r
+ *  @return True if the transaction is successfully initiated.\r
+*/\r
+bool lib_aci_set_local_data(aci_state_t *aci_stat, uint8_t pipe, uint8_t *value, uint8_t size);\r
+\r
+/** @brief Sends Broadcast message to the radio.\r
+ *  @details The Broadcast message starts advertisement procedure\r
+ *  using the given interval with the intention of broadcasting data to a peer device.\r
+ *  @param timeout Time, in seconds, to advertise before exiting to standby mode (0 means infinite).\r
+ *  Valid values: 0 to 16383.\r
+ *  @param adv_interval Advertising interval (in multiple of 0.625&nbsp;ms).\r
+ *  Valid values: 160 to 16384 (which corresponds to an interval from 100 ms to 10.24 s).\r
+ *  @return True if the broadcast message is sent successfully to the radio.\r
+*/\r
+bool lib_aci_broadcast(const uint16_t timeout, const uint16_t adv_interval);\r
+\r
+/** @name Open Advertising Pipes.  */\r
+\r
+/** @brief Sends a command to the radio to set the input pipe to be placed in Advertisement Service Data.\r
+ *  @details This function sends a command to the radio that places the pipe in\r
+ *  advertisement service data.  To start advertising service data, call this function before\r
+ *  Connecting, Broadcasting or Bonding to peer. The data that should be sent in the advertisement packets\r
+ *  must be set using the @c lib_aci_set_local_data function. This function can be called during\r
+ *  advertising to enable/disable broadcast pipes.\r
+ *  @param pipe The pipe that has to be placed in advertising service data.\r
+ *  @return True if the Open Adv Pipe message is sent successfully to the radio.\r
+*/\r
+bool lib_aci_open_adv_pipe(const uint8_t pipe);\r
+\r
+\r
+/** @name Open Advertising Pipes  */\r
+\r
+/** @brief Sends a command to the radio to set the pipes to be placed in Advertisement Service Data.\r
+ *  @details This function will send a command to the radio that will set the pipes to be placed in\r
+ *  advertisement Service Data.  To start advertising service data, this function should be called before\r
+ *  Connecting, Broadcasting or Bonding to peer. This function can be called during\r
+ *  advertising to enable/disable broadcast pipes. Use this as an alternative to @ref lib_aci_open_adv_pipe\r
+ *  to avoid multiple function calls for placing multiple pipes in the adv data.\r
+ *  @param adv_service_data_pipes Pipe bitmap, where '1' indicates that the corresponding\r
+ *  Valid Values: 0000000000000000 to FEFFFFFFFFFFFF7F (See the ACI Pipe Status Evt bitmap in the nRF8001 datasheet\r
+ *  TX_BROADCAST pipe data is to be placed in Advertising Service Data fields\r
+ *  @return true if the Open Adv Pipe message was sent successfully to the radio.\r
+*/\r
+bool lib_aci_open_adv_pipes(const uint8_t * const adv_service_data_pipes);\r
+\r
+\r
+//@}\r
+\r
+/** @name ACI commands available in Connected mode */\r
+//@{\r
+\r
+\r
+/** @brief Sets a given application latency.\r
+ *  @details This function sends a @c setApplicationLatency command.\r
+ *  @return True if the transaction is successfully initiated.\r
+ */\r
+bool lib_aci_set_app_latency(uint16_t latency, aci_app_latency_mode_t latency_mode);\r
+\r
+/** @brief Opens a remote pipe.\r
+ *  @details This function sends an @c OpenRemotePipe command.\r
+ *  @param pipe Number of the pipe to open.\r
+ *  @return True if the transaction is successfully initiated.\r
+ */\r
+bool lib_aci_open_remote_pipe(aci_state_t *aci_stat, uint8_t pipe);\r
+\r
+/** @brief Closes a remote pipe.\r
+ *  @details This function sends an @c CloseRemotePipe command.\r
+ *  @param pipe Pipe number to close.\r
+ *  @return True if the transaction is successfully initiated.\r
+ */\r
+bool lib_aci_close_remote_pipe(aci_state_t *aci_stat, uint8_t pipe);\r
+\r
+/** @brief Sends data on a given pipe.\r
+ *  @details This function sends a @c SendData command with application data to\r
+ *  the radio. This function memorizes credit use, and checks that\r
+ *  enough credits are available.\r
+ *  @param pipe Pipe number on which the data should be sent.\r
+ *  @param value Pointer to the data to send.\r
+ *  @param size Size of the data to send.\r
+ *  @return True if the transaction is successfully initiated.\r
+ */\r
+bool lib_aci_send_data(uint8_t pipe, uint8_t *value, uint8_t size);\r
+\r
+/** @brief Requests data from a given pipe.\r
+ *  @details This function sends a @c RequestData command to the radio. This\r
+ *  function memorizes credit uses, and check that enough credits are available.\r
+ *  After this command, the radio sends back either a @c DataReceivedEvent\r
+ *  or a @c PipeErrorEvent.\r
+ *  @param pipe Pipe number on which the data is requested.\r
+ *  @return True if the transaction is successfully initiated.\r
+ */\r
+bool lib_aci_request_data(aci_state_t *aci_stat, uint8_t pipe);\r
+\r
+/** @brief Sends a L2CAP change connection parameters request.\r
+ *  @details This function sends a @c ChangeTiming command to the radio.  This command triggers a "L2CAP change connection parameters" request\r
+ *  to the master. If the master rejects or accepts but doesn't change the connection parameters within\r
+ *  30 seconds, a timing event with the unchanged connection parameters is sent by the radio.\r
+ *  If the request is accepted and the master changes connection parameters, a timing event with\r
+ *  the new connection parameters is sent by the radio.\r
+ *  If the master doesn't reply to the request within 60 seconds, the radio disconnects.\r
+ *  @param minimun_cx_interval Minimum connection interval requested, in multiple of 1.25&nbsp;ms.\r
+ *  @param maximum_cx_interval Maximum connection interval requested, in multiple of 1.25&nbsp;ms.\r
+ *  @param slave_latency requested slave latency.\r
+ *  @param timeout requested slave timeout, in multiple of 10&nbsp;ms.\r
+ *  @return True if the transaction is successfully initiated.\r
+ */\r
+bool lib_aci_change_timing(uint16_t minimun_cx_interval, uint16_t maximum_cx_interval, uint16_t slave_latency, uint16_t timeout);\r
+\r
+/** @brief Sends a L2CAP change connection parameters request with the connection predefined preffered connection parameters.\r
+ *  @details This function sends a @c ChangeTiming command to the radio. This command triggers a "L2CAP change connection parameters" request\r
+ *  to the master. If the master rejects or accepts but doesn't change the connection parameters within\r
+ *  30 seconds, a timing event with the unchanged connection parameters is sent by the radio.\r
+ *  If the request is accepted and the master changes connection parameters, a timing event with\r
+ *  the new connection parameters is sent by the radio.\r
+ *  If the master doesn't reply to the request within 60 seconds, the radio disconnects.\r
+ *  The timing parameters used are the Timing parameters in the GAP settings in the nRFgo Studio.\r
+ *  The Timing parameters as stored as the GAP Preferred Peripheral Connection Parameters.\r
+ *  @return True if the transaction is successfully initiated.\r
+ */\r
+bool lib_aci_change_timing_GAP_PPCP(void);\r
+\r
+/** @brief Sends acknowledgement message to peer.\r
+ *  @details This function sends @c SendDataAck command to radio. The radio is expected\r
+ *  to send either Handle Value Confirmation or Write response depending\r
+ *  on whether the data is stored remotely or locally.\r
+ *  @param pipe Pipe number for which the acknowledgement is to be sent.\r
+ *  @return True if the ack was sent successfully. False otherwise.\r
+*/\r
+bool lib_aci_send_ack(aci_state_t *aci_stat, const uint8_t pipe);\r
+\r
+/** @brief Sends negative acknowledgement message to peer.\r
+ *  @details This function sends @c SendDataNack command to radio. The radio is expected\r
+ *  to send Error Response to the peer.\r
+ *  @param pipe Pipe number for which the nack is to be sent.\r
+ *  @param error_code Error code to be sent in the NACk.\r
+ *  @return True if the nack was sent successfully. False otherwise.\r
+*/\r
+bool lib_aci_send_nack(aci_state_t *aci_stat, const uint8_t pipe, const uint8_t error_code);\r
+\r
+/** @brief Sends ReadDynamicData command to the host.\r
+ *  @details This function sends @c ReadDynamicData command to host. The host is expected\r
+ *  to send @c CommandResponse back with the dynamic data. The application is expected to\r
+ *  call this function in a loop until all the dynamic data is read out from the host.\r
+ *  As long as there is dynamic data to be read from the host, the command response\r
+ *  for this message has its status field set to ACI_STATUS_TRANSACTION_CONTINUE (0x01).\r
+ *  The application may chose to store this read out data in a non-volatile memory location\r
+ *  and later chose to write it back using the function lib_aci_write_dynamic_data.\r
+ *  @return True if the command was sent successfully through the ACI. False otherwise.\r
+*/\r
+bool lib_aci_read_dynamic_data(void);\r
+\r
+/** @brief Sends WriteDynamicData command to the host.\r
+ *  @details This function sends @c WriteDynamicData command to host. The host is expected\r
+ *  to send @c CommandResponse with the status of this operation. As long as the status field\r
+ *  in the @c CommandResponse is ACI_STATUS_TRANSACTION_CONTINUE (0x01), the hosts expects\r
+ *  more dynamic data to be written. This function should ideally be called in a cycle,\r
+ *  until all the stored dynamic data is sent to the host. This function should be\r
+ *  called with the dynamic data obtained from the response to a @c ReadDynamicData\r
+ *  (see @c lib_aci_read_dynamic_data) command.\r
+ *  @param sequence_number Sequence number of the dynamic data to be sent.\r
+ *  @param dynamic_data Pointer to the dynamic data.\r
+ *  @param length Length of the dynamic data.\r
+ *  @return True if the command was sent successfully through the ACI. False otherwise.\r
+*/\r
+bool lib_aci_write_dynamic_data(uint8_t sequence_number, uint8_t* dynamic_data, uint8_t length);\r
+//@}\r
+\r
+/** @name ACI commands available while connected in Bond mode */\r
+//@{\r
+\r
+/** @brief Sends a SMP Security Request.\r
+ *  @details This function send a @c BondRequest command to the radio.\r
+ *  This command triggers a SMP Security Request to the master. If the\r
+ *  master rejects with a pairing failed or if the bond timer expires the connection is closed.\r
+ *  @return True if the transaction is successfully initiated.\r
+ */\r
+bool lib_aci_bond_request(void);\r
+\r
+/** @brief Set the key requested by the 8001.\r
+ *  @details This function sends an @c SetKey command to the radio.\r
+ *  @param key_rsp_type Type of key.\r
+ *  @param key Pointer to the key to set.\r
+ *  @param len Length of the key.\r
+ *  @return True if the transaction is successfully initiated.\r
+*/\r
+bool lib_aci_set_key(aci_key_type_t key_rsp_type, uint8_t *key, uint8_t len);\r
+\r
+//@}\r
+\r
+\r
+\r
+/** @name ACI commands available in Test mode */\r
+//@{\r
+\r
+/** @brief Sends an echo message\r
+ *  @details This function sends an @c Echo command to the radio. lib_aci\r
+ *  places the Echp ACI command in the ACI command queue\r
+ *  @param message_size Length of the data to send.\r
+ *  @param message_data Pointer to the data to send.\r
+ *  @return True if the transaction is successfully initiated.\r
+*/\r
+bool lib_aci_echo_msg(uint8_t message_size, uint8_t *message_data);\r
+\r
+/** @brief Sends an DTM command\r
+ *  @details This function sends an @c DTM command to the radio.\r
+ *  @param dtm_command_msbyte Most significant byte of the DTM command.\r
+ *  @param dtm_command_lsbyte Least significant byte of the DTM command.\r
+ *  @return True if the transaction is successfully initiated.\r
+*/\r
+bool lib_aci_dtm_command(uint8_t dtm_command_msbyte, uint8_t dtm_command_lsbyte);\r
+\r
+/** @brief Gets an ACI event from the ACI Event Queue\r
+ *  @details This function gets an ACI event from the ACI event queue.\r
+ *  The queue is updated by the SPI driver for the ACI running in the interrupt context\r
+ *  @param aci_stat pointer to the state of the ACI.\r
+ *  @param p_aci_data pointer to the ACI Event. The ACI Event received will be copied into this pointer.\r
+ *  @return True if an ACI Event was copied to the pointer.\r
+*/\r
+bool lib_aci_event_get(aci_state_t *aci_stat, hal_aci_evt_t * aci_evt);\r
+\r
+/** @brief Peeks an ACI event from the ACI Event Queue\r
+ * @details This function peeks at the top event in the ACI event queue.\r
+ * In polling mode, this function will query the nRF8001 for pending events, but unlike\r
+ * lib_aci_event_get() it will not dequeue the event from the local queue, but will instead\r
+ * only peek at it.\r
+ * @return True if an ACI Event was copied to the pointer.\r
+*/\r
+bool lib_aci_event_peek(hal_aci_evt_t *p_aci_evt_data);\r
+\r
+/** @brief Flushes the events in the ACI command queues and ACI Event queue\r
+ *\r
+*/\r
+void lib_aci_flush(void);\r
+\r
+/** @brief Return full status of the Event queue\r
+ *  @details\r
+ *\r
+ */\r
+ bool lib_aci_event_queue_full(void);\r
+\r
+ /** @brief Return empty status of the Event queue\r
+ *  @details\r
+ *\r
+ */\r
+ bool lib_aci_event_queue_empty(void);\r
+\r
+/** @brief Return full status of Command queue\r
+ *  @details\r
+ *\r
+ */\r
+ bool lib_aci_command_queue_full(void);\r
+\r
+ /** @brief Return empty status of Command queue\r
+ *  @details\r
+ *\r
+ */\r
+ bool lib_aci_command_queue_empty(void);\r
+\r
+//@}\r
+\r
+/** @} */\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /* LIB_ACI_H__ */\r
diff --git a/src/nrf8001/nrf8001.cxx b/src/nrf8001/nrf8001.cxx
new file mode 100644 (file)
index 0000000..b771436
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Author: Yevgeniy Kiveisha <yevgeniy.kiveisha@intel.com>
+ * Copyright (c) 2014 Intel Corporation.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+#include "nrf8001.h"
+
+/**
+ * Include the services_lock.h to put the setup in the OTP memory of the nRF8001.
+ * This would mean that the setup cannot be changed once put in.
+ * However this removes the need to do the setup of the nRF8001 on every reset.
+*/
+
+void
+init_local_interfaces (aci_state_t* aci, uint8_t reqn, uint8_t rdyn, uint8_t rst) {
+    /**
+     * Tell the ACI library, the MCU to nRF8001 pin connections.
+     * The Active pin is optional and can be marked UNUSED
+     */
+    aci->aci_pins.board_name                = BOARD_DEFAULT;    // See board.h for details REDBEARLAB_SHIELD_V1_1 or BOARD_DEFAULT
+    aci->aci_pins.reqn_pin                  = reqn;             // SS for Nordic board, 9 for REDBEARLAB_SHIELD_V1_1
+    aci->aci_pins.rdyn_pin                  = rdyn;             // 3 for Nordic board, 8 for REDBEARLAB_SHIELD_V1_1
+
+    aci->aci_pins.reset_pin                 = rst;              // 4 for Nordic board, UNUSED for REDBEARLAB_SHIELD_V1_1
+    aci->aci_pins.active_pin                = UNUSED;
+    aci->aci_pins.optional_chip_sel_pin     = UNUSED;
+
+    aci->aci_pins.interface_is_interrupt    = false;            // Interrupts still not available in Chipkit
+    aci->aci_pins.interrupt_number          = 1;
+
+    lib_aci_init (aci, false);
+}
+
+void
+close_local_interfaces (aci_state_t* aci) {
+    mraa_result_t error = MRAA_SUCCESS;
+
+    error = mraa_spi_stop(aci->aci_pins.m_spi);
+    if (error != MRAA_SUCCESS) {
+
+    }
+    error = mraa_gpio_close (aci->aci_pins.m_rdy_ctx);
+    if (error != MRAA_SUCCESS) {
+
+    }
+    error = mraa_gpio_close (aci->aci_pins.m_req_ctx);
+    if (error != MRAA_SUCCESS) {
+
+    }
+    error = mraa_gpio_close (aci->aci_pins.m_rst_ctx);
+    if (error != MRAA_SUCCESS) {
+
+    }
+}
diff --git a/src/nrf8001/nrf8001.h b/src/nrf8001/nrf8001.h
new file mode 100644 (file)
index 0000000..c90dd81
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Author: Yevgeniy Kiveisha <yevgeniy.kiveisha@intel.com>
+ * Copyright (c) 2014 Intel Corporation.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#pragma once
+
+#include <string>
+#include <mraa/aio.h>
+#include <mraa/gpio.h>
+#include <mraa/spi.h>
+
+#include <lib_aci.h>
+#include <aci_setup.h>
+
+void init_local_interfaces (aci_state_t* aci, uint8_t reqn, uint8_t rdyn, uint8_t rst);
+void close_local_interfaces (aci_state_t* aci);
diff --git a/src/nrf8001/pyupm_nrf8001.i b/src/nrf8001/pyupm_nrf8001.i
new file mode 100644 (file)
index 0000000..0c56852
--- /dev/null
@@ -0,0 +1,9 @@
+%module pyupm_nrf8001
+%include "../upm.i"
+
+%feature("autodoc", "3");
+
+%include "nrf8001.h"
+%{
+    #include "nrf8001.h"
+%}
diff --git a/src/nrf8001/uart_over_ble.h b/src/nrf8001/uart_over_ble.h
new file mode 100644 (file)
index 0000000..b941c6e
--- /dev/null
@@ -0,0 +1,73 @@
+/*  Copyright (c) 2013, Nordic Semiconductor ASA\r
+ *  All rights reserved.\r
+ *\r
+ *  Redistribution and use in source and binary forms, with or without modification,\r
+ *  are permitted provided that the following conditions are met:\r
+ *\r
+ *  Redistributions of source code must retain the above copyright notice, this\r
+ *  list of conditions and the following disclaimer.\r
+ *\r
+ *  Redistributions in binary form must reproduce the above copyright notice, this\r
+ *  list of conditions and the following disclaimer in the documentation and/or\r
+ *  other materials provided with the distribution.\r
+ *\r
+ *  Neither the name of Nordic Semiconductor ASA nor the names of its\r
+ *  contributors may be used to endorse or promote products derived from\r
+ *  this software without specific prior written permission.\r
+ *\r
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND\r
+ *  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+ *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r
+ *  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR\r
+ *  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+ *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON\r
+ *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
+ *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+\r
+#ifndef UART_OVER_BLE_H__\r
+#define UART_OVER_BLE_H__\r
+\r
+/**\r
+ * @def UART_OVER_BLE_DISCONNECT\r
+ * @brief\r
+ * Command to queue a ACI Disconnect to the nRF8001\r
+ */\r
+#define UART_OVER_BLE_DISCONNECT      (0x01)\r
+\r
+\r
+/**\r
+ * @def UART_OVER_BLE_LINK_TIMING_REQ\r
+ * @brief\r
+ * Command to queue a ACI Change Timing to the nRF8001\r
+ */\r
+#define UART_OVER_BLE_LINK_TIMING_REQ (0x02)\r
+\r
+/**\r
+ * @def UART_OVER_BLE_TRANSMIT_STOP\r
+ * @brief\r
+ * Command to stop sending UART over BLE packets\r
+ */\r
+#define UART_OVER_BLE_TRANSMIT_STOP   (0x03)\r
+\r
+\r
+/**\r
+ * @def UART_OVER_BLE_TRANSMIT_OK\r
+ * @brief\r
+ * Command to allow sending UART over BLE packets\r
+ */\r
+#define UART_OVER_BLE_TRANSMIT_OK     (0x04)\r
+\r
+typedef struct\r
+{\r
+    uint8_t uart_rts_local;  /* State of the local UART RTS  */\r
+    uint8_t uart_rts_remote; /* State of the remote UART RTS */\r
+} uart_over_ble_t;\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+#endif // UART_OVER_BLE_H__\r