浏览代码

nrf8001: added new BLE module with broadcasting example

Signed-off-by: Kiveisha Yevgeniy <yevgeniy.kiveisha@intel.com>
Kiveisha Yevgeniy 10 年前
父节点
当前提交
044037b892

+ 3
- 0
examples/CMakeLists.txt 查看文件

@@ -24,6 +24,7 @@ add_executable (mpu9150-example mpu9150-example.cxx)
24 24
 add_executable (maxds3231m-example maxds3231m.cxx)
25 25
 add_executable (max31723-example max31723.cxx)
26 26
 add_executable (max5487-example max5487.cxx)
27
+add_executable (nrf8001-broadcast-example nrf8001_broadcast.cxx)
27 28
 
28 29
 include_directories (${PROJECT_SOURCE_DIR}/src/hmc5883l)
29 30
 include_directories (${PROJECT_SOURCE_DIR}/src/grove)
@@ -46,6 +47,7 @@ include_directories (${PROJECT_SOURCE_DIR}/src/mpu9150)
46 47
 include_directories (${PROJECT_SOURCE_DIR}/src/maxds3231m)
47 48
 include_directories (${PROJECT_SOURCE_DIR}/src/max31723)
48 49
 include_directories (${PROJECT_SOURCE_DIR}/src/max5487)
50
+include_directories (${PROJECT_SOURCE_DIR}/src/nrf8001)
49 51
 
50 52
 target_link_libraries (compass hmc5883l ${CMAKE_THREAD_LIBS_INIT})
51 53
 target_link_libraries (groveled grove ${CMAKE_THREAD_LIBS_INIT})
@@ -73,3 +75,4 @@ target_link_libraries (mpu9150-example mpu9150 ${CMAKE_THREAD_LIBS_INIT})
73 75
 target_link_libraries (maxds3231m-example maxds3231m ${CMAKE_THREAD_LIBS_INIT})
74 76
 target_link_libraries (max31723-example max31723 ${CMAKE_THREAD_LIBS_INIT})
75 77
 target_link_libraries (max5487-example max5487 ${CMAKE_THREAD_LIBS_INIT})
78
+target_link_libraries (nrf8001-broadcast-example nrf8001 ${CMAKE_THREAD_LIBS_INIT})

+ 177
- 0
examples/nrf8001_broadcast.cxx 查看文件

@@ -0,0 +1,177 @@
1
+/*
2
+ * Author: Yevgeniy Kiveisha <yevgeniy.kiveisha@intel.com>
3
+ * Copyright (c) 2014 Intel Corporation.
4
+ *
5
+ * Permission is hereby granted, free of charge, to any person obtaining
6
+ * a copy of this software and associated documentation files (the
7
+ * "Software"), to deal in the Software without restriction, including
8
+ * without limitation the rights to use, copy, modify, merge, publish,
9
+ * distribute, sublicense, and/or sell copies of the Software, and to
10
+ * permit persons to whom the Software is furnished to do so, subject to
11
+ * the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be
14
+ * included in all copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+ */
24
+
25
+#include <unistd.h>
26
+#include <iostream>
27
+#include "nrf8001.h"
28
+#include "nrf8001_broadcast.h"
29
+#include <lib_aci.h>
30
+#include <aci_setup.h>
31
+#include <signal.h>
32
+
33
+#ifdef SERVICES_PIPE_TYPE_MAPPING_CONTENT
34
+    static services_pipe_type_mapping_t
35
+        services_pipe_type_mapping[NUMBER_OF_PIPES] = SERVICES_PIPE_TYPE_MAPPING_CONTENT;
36
+#else
37
+    #define NUMBER_OF_PIPES 0
38
+    static services_pipe_type_mapping_t * services_pipe_type_mapping = NULL;
39
+#endif
40
+
41
+/**
42
+ * Store the setup for the nRF8001 in the flash of the AVR to save on RAM
43
+ */
44
+static hal_aci_data_t setup_msgs[NB_SETUP_MESSAGES] = SETUP_MESSAGES_CONTENT;
45
+
46
+/**
47
+ * aci_struct that will contain
48
+ * total initial credits
49
+ * current credit
50
+ * current state of the aci (setup/standby/active/sleep)
51
+ * open remote pipe pending
52
+ * close remote pipe pending
53
+ * Current pipe available bitmap
54
+ * Current pipe closed bitmap
55
+ * Current connection interval, slave latency and link supervision timeout
56
+ * Current State of the the GATT client (Service Discovery)
57
+ * Status of the bond (R) Peer address
58
+ */
59
+static struct aci_state_t aci_state;
60
+
61
+/**
62
+ * Temporary buffers for sending ACI commands
63
+ */
64
+static hal_aci_evt_t  aci_data;
65
+
66
+void
67
+sig_handler(int signo)
68
+{
69
+    printf("got signal\n");
70
+    if (signo == SIGINT) {
71
+        printf("exiting application\n");
72
+    }
73
+}
74
+
75
+void
76
+init_aci_setup () {
77
+    /**
78
+     * Point ACI data structures to the the setup data that the nRFgo studio generated for the nRF8001
79
+     */
80
+    if (NULL != services_pipe_type_mapping) {
81
+        aci_state.aci_setup_info.services_pipe_type_mapping = &services_pipe_type_mapping[0];
82
+    } else {
83
+        aci_state.aci_setup_info.services_pipe_type_mapping = NULL;
84
+    }
85
+
86
+    aci_state.aci_setup_info.number_of_pipes    = NUMBER_OF_PIPES;
87
+    aci_state.aci_setup_info.setup_msgs         = setup_msgs;
88
+    aci_state.aci_setup_info.num_setup_msgs     = NB_SETUP_MESSAGES;
89
+}
90
+
91
+int
92
+main(int argc, char **argv)
93
+{
94
+    //! [Interesting]
95
+
96
+    init_aci_setup ();
97
+    init_local_interfaces (&aci_state, 10, 8, 4);
98
+
99
+    while (1) {
100
+        static bool setup_required = false;
101
+        if (lib_aci_event_get (&aci_state, &aci_data)) {
102
+            aci_evt_t * aci_evt;
103
+            aci_evt = &aci_data.evt;
104
+
105
+            switch(aci_evt->evt_opcode) {
106
+                /**
107
+                As soon as you reset the nRF8001 you will get an ACI Device Started Event
108
+                */
109
+                case ACI_EVT_DEVICE_STARTED: {
110
+                    aci_state.data_credit_available = aci_evt->params.device_started.credit_available;
111
+                    switch(aci_evt->params.device_started.device_mode) {
112
+                        case ACI_DEVICE_SETUP:
113
+                            /**
114
+                            When the device is in the setup mode
115
+                            */
116
+                            printf ("Evt Device Started: Setup\n");
117
+                            setup_required = true;
118
+                        break;
119
+
120
+                        case ACI_DEVICE_STANDBY:
121
+                            printf ("Evt Device Started: Standby\n");
122
+                            lib_aci_broadcast(10/* in seconds */, 0x0100 /* advertising interval 100ms */);
123
+                            printf ("Broadcasting started\n");
124
+                        break;
125
+                    }
126
+                }
127
+                break; //ACI Device Started Event
128
+
129
+                case ACI_EVT_CMD_RSP:
130
+                    if (ACI_STATUS_SUCCESS != aci_evt->params.cmd_rsp.cmd_status) {
131
+                        printf ("ACI_EVT_CMD_RSP\n");
132
+                        while (1);
133
+                    }
134
+                break;
135
+
136
+                case ACI_EVT_CONNECTED:
137
+                    printf ("ACI_EVT_CONNECTED\n");
138
+                    break;
139
+
140
+                case ACI_EVT_PIPE_STATUS:
141
+                    printf ("ACI_EVT_PIPE_STATUS\n");
142
+                    break;
143
+
144
+                case ACI_EVT_DISCONNECTED:
145
+                    if (ACI_STATUS_ERROR_ADVT_TIMEOUT == aci_evt->params.disconnected.aci_status) {
146
+                        printf ("Broadcasting timed out\n");
147
+                    } else {
148
+                        printf ("Evt Disconnected. Link Loss\n");
149
+                    }
150
+                    break;
151
+
152
+                case ACI_EVT_DATA_RECEIVED:
153
+                    printf ("ACI_EVT_DATA_RECEIVED\n");
154
+                    break;
155
+
156
+                case ACI_EVT_HW_ERROR:
157
+                    printf ("ACI_EVT_HW_ERROR\n");
158
+                    break;
159
+            }
160
+        }
161
+
162
+        if (setup_required) {
163
+            if (SETUP_SUCCESS == do_aci_setup(&aci_state)) {
164
+                setup_required = false;
165
+            }
166
+        }
167
+        usleep (100);
168
+    }
169
+
170
+    close_local_interfaces (&aci_state);
171
+
172
+    //! [Interesting]
173
+
174
+    std::cout << "exiting application" << std::endl;
175
+
176
+    return 0;
177
+}

+ 93
- 0
examples/nrf8001_broadcast.h 查看文件

@@ -0,0 +1,93 @@
1
+#include "hal_platform.h"
2
+#include "aci.h"
3
+
4
+#pragma once
5
+
6
+#define PIPE_GAP_DEVICE_NAME_SET 1
7
+
8
+#define NUMBER_OF_PIPES 1
9
+
10
+#define SERVICES_PIPE_TYPE_MAPPING_CONTENT {\
11
+  {ACI_STORE_LOCAL, ACI_SET},   \
12
+}
13
+
14
+#define GAP_PPCP_MAX_CONN_INT 0xffff /**< Maximum connection interval as a multiple of 1.25 msec , 0xFFFF means no specific value requested */
15
+#define GAP_PPCP_MIN_CONN_INT  0xffff /**< Minimum connection interval as a multiple of 1.25 msec , 0xFFFF means no specific maximum*/
16
+#define GAP_PPCP_SLAVE_LATENCY 0
17
+#define GAP_PPCP_CONN_TIMEOUT 0xffff /** Connection Supervision timeout multiplier as a multiple of 10msec, 0xFFFF means no specific value requested */
18
+
19
+#define NB_SETUP_MESSAGES 13
20
+#define SETUP_MESSAGES_CONTENT {\
21
+    {0x00,\
22
+        {\
23
+            0x07,0x06,0x00,0x00,0x03,0x02,0x41,0xd7,\
24
+        },\
25
+    },\
26
+    {0x00,\
27
+        {\
28
+            0x1f,0x06,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x01,0x01,0x00,0x00,0x06,0x00,0x01,\
29
+            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
30
+        },\
31
+    },\
32
+    {0x00,\
33
+        {\
34
+            0x1f,0x06,0x10,0x1c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
35
+            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x90,0x00,0x64,\
36
+        },\
37
+    },\
38
+    {0x00,\
39
+        {\
40
+            0x1f,0x06,0x10,0x38,0x02,0xff,0x02,0x58,0x00,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
41
+            0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
42
+        },\
43
+    },\
44
+    {0x00,\
45
+        {\
46
+            0x05,0x06,0x10,0x54,0x00,0x00,\
47
+        },\
48
+    },\
49
+    {0x00,\
50
+        {\
51
+            0x1f,0x06,0x20,0x00,0x04,0x04,0x02,0x02,0x00,0x01,0x28,0x00,0x01,0x00,0x18,0x04,0x04,0x05,0x05,0x00,\
52
+            0x02,0x28,0x03,0x01,0x0e,0x03,0x00,0x00,0x2a,0x04,0x14,0x0b,\
53
+        },\
54
+    },\
55
+    {0x00,\
56
+        {\
57
+            0x1f,0x06,0x20,0x1c,0x05,0x00,0x03,0x2a,0x00,0x01,0x62,0x63,0x61,0x73,0x74,0x63,0x73,0x65,0x6d,0x69,\
58
+            0x2e,0x04,0x04,0x05,0x05,0x00,0x04,0x28,0x03,0x01,0x02,0x05,\
59
+        },\
60
+    },\
61
+    {0x00,\
62
+        {\
63
+            0x1f,0x06,0x20,0x38,0x00,0x01,0x2a,0x06,0x04,0x03,0x02,0x00,0x05,0x2a,0x01,0x01,0x00,0x00,0x04,0x04,\
64
+            0x05,0x05,0x00,0x06,0x28,0x03,0x01,0x02,0x07,0x00,0x04,0x2a,\
65
+        },\
66
+    },\
67
+    {0x00,\
68
+        {\
69
+            0x1f,0x06,0x20,0x54,0x06,0x04,0x09,0x08,0x00,0x07,0x2a,0x04,0x01,0xff,0xff,0xff,0xff,0x00,0x00,0xff,\
70
+            0xff,0x04,0x04,0x02,0x02,0x00,0x08,0x28,0x00,0x01,0x01,0x18,\
71
+        },\
72
+    },\
73
+    {0x00,\
74
+        {\
75
+            0x04,0x06,0x20,0x70,0x00,\
76
+        },\
77
+    },\
78
+    {0x00,\
79
+        {\
80
+            0x0d,0x06,0x40,0x00,0x2a,0x00,0x01,0x00,0x80,0x04,0x00,0x03,0x00,0x00,\
81
+        },\
82
+    },\
83
+    {0x00,\
84
+        {\
85
+            0x06,0x06,0x60,0x00,0x00,0x00,0x00,\
86
+        },\
87
+    },\
88
+    {0x00,\
89
+        {\
90
+            0x06,0x06,0xf0,0x00,0x03,0x4c,0xf2,\
91
+        },\
92
+    },\
93
+}

+ 5
- 0
src/nrf8001/CMakeLists.txt 查看文件

@@ -0,0 +1,5 @@
1
+set (libname "nrf8001")
2
+set (libdescription "BLE module from NordicSemiconductor family")
3
+set (module_src hal_aci_tl.cpp aci_setup.cpp aci_queue.cpp acilib.cpp lib_aci.cpp ${libname}.cxx)
4
+set (module_h hal_aci_tl.h aci_setup.h aci_queue.h acilib.h lib_aci.h ${libname}.h)
5
+upm_module_init()

+ 669
- 0
src/nrf8001/aci.h 查看文件

@@ -0,0 +1,669 @@
1
+/* Copyright (c) 2014, Nordic Semiconductor ASA
2
+ *
3
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ * of this software and associated documentation files (the "Software"), to deal
5
+ * in the Software without restriction, including without limitation the rights
6
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ * copies of the Software, and to permit persons to whom the Software is
8
+ * furnished to do so, subject to the following conditions:
9
+ *
10
+ * The above copyright notice and this permission notice shall be included in all
11
+ * copies or substantial portions of the Software.
12
+ *
13
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ * SOFTWARE.
20
+ */
21
+
22
+/**
23
+ * @file
24
+ *
25
+ * @defgroup aci aci
26
+ * @{
27
+ * @ingroup lib
28
+ *
29
+ * @brief Definitions for the ACI (Application Control Interface)
30
+ * @remarks
31
+ *
32
+ * Flow control from application mcu to nRF8001
33
+ *
34
+ * Data flow control:
35
+ * The flow control is credit based and the credit is initally given using the "device started" event.
36
+ * A credit of more than 1 is given to the application mcu.
37
+ * These credits are used only after the "ACI Connected Event" is sent to the application mcu.
38
+ *
39
+ * every send_data that is used decrements the credit available by 1. This is to be tracked by the application mcu.
40
+ * When the credit available reaches 0, the application mcu shall not send any more send_data.
41
+ * Credit is returned using the "credit event", this returned credit can then be used to send more send_data.
42
+ * This flow control is not necessary and not available for Broadcast.
43
+ * The entire credit available with the external mcu expires when a "disconnected" event arrives.
44
+ *
45
+ * Command flow control:
46
+ * When a command is sent over the ACI, the next command shall not be sent until after a response
47
+ * for the command sent has arrived.
48
+ *
49
+ */
50
+
51
+#ifndef ACI_H__
52
+#define ACI_H__
53
+
54
+/**
55
+ * Define an _aci_packed_ macro we can use in structure and enumerated type
56
+ * declarations so that the types are sized consistently across different
57
+ * platforms. In particular Arduino platforms using the GCC compiler and the
58
+ * Nordic processors using the Keil compiler.
59
+ *
60
+ * It's really the GNU compiler platforms that need a special keyword to get
61
+ * tight packing of values. On GNU platforms we can use the keyword:
62
+ *     __attribute__((__packed__))
63
+ * The thing is that while this keyword does the right thing with old and new
64
+ * versions of the gcc (C) compiler it only works right with g++ (C++) compiler
65
+ * versions that are version 4 or newer.
66
+ */
67
+#ifdef __GNUC__
68
+#  if __GNUC__ >= 4
69
+#    define _aci_packed_ __attribute__((__packed__))
70
+#  else
71
+#    error "older g++ versions don't handle packed attribute in typedefs"
72
+#  endif
73
+#else
74
+#  define _aci_packed_
75
+#endif
76
+
77
+#include <stdint.h>
78
+#include <cstddef>
79
+#include <string.h>
80
+#include <unistd.h>
81
+
82
+/*
83
+ * Define a macro that compares the size of the first parameter to the integer
84
+ * value of the second parameter. If they do not match, a compile time error
85
+ * for negative array size occurs (even gnu chokes on negative array size).
86
+ *
87
+ * This compare is done by creating a typedef for an array. No variables are
88
+ * created and no memory is consumed with this check. The created type is
89
+ * used for checking only and is not for use by any other code. The value
90
+ * of 10 in this macro is arbitrary, it just needs to be a value larger
91
+ * than one to result in a positive number for the array size.
92
+ */
93
+#define ACI_ASSERT_SIZE(x,y) typedef char x ## _assert_size_t[-1+10*(sizeof(x) == (y))]
94
+
95
+/**
96
+ * @def ACI_VERSION
97
+ * @brief Current ACI protocol version. 0 means a device that is not yet released.
98
+ * A numer greater than 0 refers to a specific ACI version documented and released.
99
+ * The ACI consists of the ACI commands, ACI events and error codes.
100
+ */
101
+#define ACI_VERSION   (0x02)
102
+/**
103
+ * @def BTLE_DEVICE_ADDRESS_SIZE
104
+ * @brief Size in bytes of a Bluetooth Address
105
+ */
106
+#define BTLE_DEVICE_ADDRESS_SIZE                 (6)
107
+/**
108
+ * @def ACI_PACKET_MAX_LEN
109
+ * @brief Maximum length in bytes of a full ACI packet, including length prefix, opcode and payload
110
+ */
111
+#define ACI_PACKET_MAX_LEN                       (32)
112
+/**
113
+ * @def ACI_ECHO_DATA_MAX_LEN
114
+ * @brief Maximum length in bytes of the echo data portion
115
+ */
116
+#define ACI_ECHO_DATA_MAX_LEN                    (ACI_PACKET_MAX_LEN - 3)
117
+/**
118
+ * @def ACI_DEVICE_MAX_PIPES
119
+ * @brief Maximum number of ACI pipes
120
+ */
121
+#define ACI_DEVICE_MAX_PIPES                       (62)
122
+/**
123
+ * @def ACI_PIPE_TX_DATA_MAX_LEN
124
+ * @brief Maximum length in bytes of a transmission data pipe packet
125
+ */
126
+#define ACI_PIPE_TX_DATA_MAX_LEN                   (20)
127
+/**
128
+ * @def ACI_PIPE_RX_DATA_MAX_LEN
129
+ * @brief Maximum length in bytes of a reception data pipe packet
130
+ */
131
+#define ACI_PIPE_RX_DATA_MAX_LEN                   (22)
132
+/**
133
+ * @def ACI_GAP_DEVNAME_MAX_LEN
134
+ * @brief Maximum length in bytes of the GAP device name
135
+ */
136
+#define ACI_GAP_DEVNAME_MAX_LEN                 (20)
137
+/**
138
+ * @def ACI_AD_PACKET_MAX_LEN
139
+ * @brief Maximum length in bytes of an AD packet
140
+ */
141
+#define ACI_AD_PACKET_MAX_LEN                   (31)
142
+/**
143
+ * @def ACI_AD_PACKET_MAX_USER_LEN
144
+ * @brief Maximum usable length in bytes of an AD packet
145
+ */
146
+#define ACI_AD_PACKET_MAX_USER_LEN              (31 - 3)
147
+/**
148
+ * @def ACI_PIPE_INVALID
149
+ * @brief Invalid pipe number
150
+ */
151
+#define ACI_PIPE_INVALID                        (0xFF)
152
+
153
+/**
154
+ * @enum aci_pipe_store_t
155
+ * @brief Storage type identifiers: local and remote
156
+ */
157
+typedef enum
158
+{
159
+  ACI_STORE_INVALID = 0x0,
160
+  ACI_STORE_LOCAL= 0x01,
161
+  ACI_STORE_REMOTE= 0x02
162
+} _aci_packed_ aci_pipe_store_t;
163
+
164
+/**
165
+ * @enum aci_pipe_type_t
166
+ * @brief Pipe types
167
+ */
168
+typedef enum
169
+{
170
+  ACI_TX_BROADCAST = 0x0001,
171
+  ACI_TX           = 0x0002,
172
+  ACI_TX_ACK       = 0x0004,
173
+  ACI_RX           = 0x0008,
174
+  ACI_RX_ACK       = 0x0010,
175
+  ACI_TX_REQ       = 0x0020,
176
+  ACI_RX_REQ       = 0x0040,
177
+  ACI_SET          = 0x0080,
178
+  ACI_TX_SIGN      = 0x0100,
179
+  ACI_RX_SIGN      = 0x0200,
180
+  ACI_RX_ACK_AUTO  = 0x0400
181
+} _aci_packed_ aci_pipe_type_t;
182
+
183
+ACI_ASSERT_SIZE(aci_pipe_type_t, 2);
184
+
185
+/**
186
+ * @enum aci_bd_addr_type_t
187
+ * @brief Bluetooth Address types
188
+ */
189
+typedef enum
190
+{
191
+  ACI_BD_ADDR_TYPE_INVALID  = 0x00,
192
+  ACI_BD_ADDR_TYPE_PUBLIC  = 0x01,
193
+  ACI_BD_ADDR_TYPE_RANDOM_STATIC  = 0x02,
194
+  ACI_BD_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE  = 0x03,
195
+  ACI_BD_ADDR_TYPE_RANDOM_PRIVATE_UNRESOLVABLE  = 0x04
196
+} _aci_packed_ aci_bd_addr_type_t;
197
+
198
+/**
199
+ * @enum aci_device_output_power_t
200
+ * @brief Radio output power levels
201
+ */
202
+typedef enum
203
+{
204
+  ACI_DEVICE_OUTPUT_POWER_MINUS_18DBM = 0x00, /**< Output power set to -18dBm */
205
+  ACI_DEVICE_OUTPUT_POWER_MINUS_12DBM = 0x01, /**< Output power set to -12dBm */
206
+  ACI_DEVICE_OUTPUT_POWER_MINUS_6DBM  = 0x02, /**< Output power set to -6dBm  */
207
+  ACI_DEVICE_OUTPUT_POWER_0DBM  = 0x03  /**< Output power set to 0dBm   - DEFAULT*/
208
+} _aci_packed_ aci_device_output_power_t;
209
+
210
+/**
211
+ * @enum aci_device_operation_mode_t
212
+ * @brief Device operation modes
213
+ */
214
+typedef enum
215
+{
216
+  ACI_DEVICE_INVALID   =0x00,
217
+  ACI_DEVICE_TEST      =0x01,
218
+  ACI_DEVICE_SETUP     =0x02,
219
+  ACI_DEVICE_STANDBY   =0x03,
220
+  ACI_DEVICE_SLEEP     =0x04
221
+} _aci_packed_ aci_device_operation_mode_t;
222
+
223
+/**
224
+ * @enum aci_disconnect_reason_t
225
+ * @brief Reason enumeration for ACI_CMD_DISCONNECT
226
+ */
227
+typedef enum
228
+{
229
+  ACI_REASON_TERMINATE      =0x01, /**< Use this to disconnect (does a terminate request), you need to wait for the "disconnected" event */
230
+  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 */
231
+} _aci_packed_ aci_disconnect_reason_t;
232
+
233
+/**
234
+ * @enum aci_test_mode_change_t
235
+ * @brief Device test mode control
236
+ */
237
+typedef enum
238
+{
239
+  ACI_TEST_MODE_DTM_UART    = 0x01,
240
+  ACI_TEST_MODE_DTM_ACI     = 0x02,
241
+  ACI_TEST_MODE_EXIT        = 0xFF
242
+
243
+} _aci_packed_ aci_test_mode_change_t;
244
+
245
+ACI_ASSERT_SIZE(aci_test_mode_change_t, 1);
246
+
247
+/**
248
+ * @enum aci_permissions_t
249
+ * @brief Data store permissions
250
+ */
251
+typedef enum
252
+{
253
+  ACI_PERMISSIONS_NONE               =0x00,
254
+  ACI_PERMISSIONS_LINK_AUTHENTICATED =0x01
255
+} _aci_packed_ aci_permissions_t;
256
+
257
+/**
258
+ * @def ACI_VS_UUID_128_MAX_COUNT
259
+ * @brief Maximum number of 128-bit Vendor Specific
260
+ *        UUIDs that can be set
261
+ */
262
+#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) */
263
+
264
+/**
265
+ * @struct aci_ll_conn_params_t
266
+ * @brief Link Layer Connection Parameters
267
+ */
268
+typedef struct
269
+{
270
+  uint16_t min_conn_interval;   /**< Minimum connection interval requested from peer */
271
+    #define ACI_PPCP_MIN_CONN_INTVL_NONE  0xFFFF
272
+    #define ACI_PPCP_MIN_CONN_INTVL_MIN   0x0006
273
+    #define ACI_PPCP_MIN_CONN_INTVL_MAX   0x0C80
274
+  uint16_t max_conn_interval;   /**< Maximum connection interval requested from peer */
275
+    #define ACI_PPCP_MAX_CONN_INTVL_NONE  0xFFFF
276
+    #define ACI_PPCP_MAX_CONN_INTVL_MIN   0x0006
277
+    #define ACI_PPCP_MAX_CONN_INTVL_MAX   0x0C80
278
+  uint16_t slave_latency;       /**< Connection interval latency requested from peer */
279
+    #define ACI_PPCP_SLAVE_LATENCY_MAX    0x03E8
280
+  uint16_t timeout_mult;        /**< Link supervisor timeout multiplier requested from peer */
281
+    #define ACI_PPCP_TIMEOUT_MULT_NONE    0xFFFF
282
+    #define ACI_PPCP_TIMEOUT_MULT_MIN     0x000A
283
+    #define ACI_PPCP_TIMEOUT_MULT_MAX     0x0C80
284
+} _aci_packed_ aci_ll_conn_params_t;
285
+
286
+/**
287
+ * @def aci_gap_ppcp_t
288
+ * @brief GAP Peripheral Preferred Connection Parameters
289
+ */
290
+#define aci_gap_ppcp_t aci_ll_conn_params_t
291
+
292
+/**
293
+ * @def ACI_AD_LOC_SVCUUID_16_MAX_COUNT
294
+ * @brief Maximum number of 16-bit UUIDs that can
295
+ *        be inserted in the Services tag of AD
296
+ */
297
+#define ACI_AD_LOC_SVCUUID_16_MAX_COUNT  5
298
+
299
+/**
300
+ * @def ACI_AD_LOC_SVCUUID_128_MAX_COUNT
301
+ * @brief Maximum number of 128-bit UUIDs that can
302
+ *        be inserted in the Services tag of AD
303
+ */
304
+#define ACI_AD_LOC_SVCUUID_128_MAX_COUNT  1
305
+
306
+/**
307
+ * @def ACI_AD_SOL_SVCUUID_16_MAX_COUNT
308
+ * @brief Maximum number of UUIDs that can
309
+ *        be inserted in the Solicited Services tag of AD
310
+ */
311
+#define ACI_AD_SOL_SVCUUID_16_MAX_COUNT  5
312
+
313
+/**
314
+ * @def ACI_AD_SOL_SVCUUID_128_MAX_COUNT
315
+ * @brief Maximum number of UUIDs that can
316
+ *        be inserted in the Solicited Services tag of AD
317
+ */
318
+#define ACI_AD_SOL_SVCUUID_128_MAX_COUNT  1
319
+
320
+/**
321
+ * @def ACI_SEC_ENCKEY_SIZE_MIN
322
+ * @brief Minimum encryption key size
323
+ */
324
+#define ACI_SEC_ENCKEY_SIZE_MIN        7
325
+/**
326
+ * @def ACI_SEC_ENCKEY_SIZE_MAX
327
+ * @brief Maximum encryption key size
328
+ */
329
+#define ACI_SEC_ENCKEY_SIZE_MAX        16
330
+/**
331
+ * @def ACI_CUSTOM_AD_TYPE_MAX_COUNT
332
+ * @brief Maximum number of custom ad types
333
+ */
334
+#define ACI_CUSTOM_AD_TYPE_MAX_COUNT 8
335
+/**
336
+ * @def ACI_CUSTOM_AD_TYPE_MAX_DATA_LENGTH
337
+ * @brief Maximum custom ad type data size
338
+ */
339
+#define ACI_CUSTOM_AD_TYPE_MAX_DATA_LENGTH 20
340
+
341
+/**
342
+ * @struct aci_tx_data_t
343
+ * @brief Generic ACI transmit data structure
344
+ */
345
+typedef struct
346
+{
347
+  uint8_t pipe_number;
348
+  uint8_t aci_data[ACI_PIPE_TX_DATA_MAX_LEN];
349
+} _aci_packed_ aci_tx_data_t;
350
+
351
+ACI_ASSERT_SIZE(aci_tx_data_t, ACI_PIPE_TX_DATA_MAX_LEN + 1);
352
+
353
+/**
354
+ * @struct aci_rx_data_t
355
+ * @brief Generic ACI receive data structure
356
+ */
357
+typedef struct
358
+{
359
+  uint8_t pipe_number;
360
+  uint8_t aci_data[ACI_PIPE_RX_DATA_MAX_LEN];
361
+} _aci_packed_ aci_rx_data_t;
362
+
363
+ACI_ASSERT_SIZE(aci_rx_data_t, ACI_PIPE_RX_DATA_MAX_LEN + 1);
364
+
365
+/**
366
+ * @enum aci_hw_error_t
367
+ * @brief Hardware Error codes
368
+ */
369
+typedef enum
370
+{
371
+  ACI_HW_ERROR_NONE     = 0x00,
372
+  ACI_HW_ERROR_FATAL    = 0x01
373
+} _aci_packed_ aci_hw_error_t;
374
+
375
+/**
376
+ * @enum aci_clock_accuracy_t
377
+ * @brief Bluetooth Low Energy Clock Accuracy
378
+ */
379
+typedef enum
380
+{
381
+  ACI_CLOCK_ACCURACY_500_PPM = 0x00,
382
+  ACI_CLOCK_ACCURACY_250_PPM = 0x01,
383
+  ACI_CLOCK_ACCURACY_150_PPM = 0x02,
384
+  ACI_CLOCK_ACCURACY_100_PPM = 0x03,
385
+  ACI_CLOCK_ACCURACY_75_PPM  = 0x04,
386
+  ACI_CLOCK_ACCURACY_50_PPM  = 0x05,
387
+  ACI_CLOCK_ACCURACY_30_PPM  = 0x06,
388
+  ACI_CLOCK_ACCURACY_20_PPM  = 0x07
389
+} _aci_packed_ aci_clock_accuracy_t;
390
+
391
+/**
392
+ * @enum aci_app_latency_mode_t
393
+ * @brief Application latency modes
394
+ */
395
+typedef enum
396
+{
397
+  ACI_APP_LATENCY_DISABLE = 0,
398
+  ACI_APP_LATENCY_ENABLE = 1
399
+} _aci_packed_ aci_app_latency_mode_t;
400
+
401
+/**
402
+ * @enum gatt_format_t
403
+ * @brief GATT format definitions
404
+ */
405
+typedef enum
406
+{
407
+  ACI_GATT_FORMAT_NONE        = 0x00, /**< No characteristic format available */
408
+  ACI_GATT_FORMAT_BOOLEAN     = 0x01, /**< Not Supported */
409
+  ACI_GATT_FORMAT_2BIT        = 0x02, /**< Not Supported */
410
+  ACI_GATT_FORMAT_NIBBLE      = 0x03, /**< Not Supported */
411
+  ACI_GATT_FORMAT_UINT8       = 0x04,
412
+  ACI_GATT_FORMAT_UINT12      = 0x05,
413
+  ACI_GATT_FORMAT_UINT16      = 0x06,
414
+  ACI_GATT_FORMAT_UINT24      = 0x07,
415
+  ACI_GATT_FORMAT_UINT32      = 0x08,
416
+  ACI_GATT_FORMAT_UINT48      = 0x09,
417
+  ACI_GATT_FORMAT_UINT64      = 0x0A,
418
+  ACI_GATT_FORMAT_UINT128     = 0x0B,
419
+  ACI_GATT_FORMAT_SINT8       = 0x0C,
420
+  ACI_GATT_FORMAT_SINT12      = 0x0D,
421
+  ACI_GATT_FORMAT_SINT16      = 0x0E,
422
+  ACI_GATT_FORMAT_SINT24      = 0x0F,
423
+  ACI_GATT_FORMAT_SINT32      = 0x10,
424
+  ACI_GATT_FORMAT_SINT48      = 0x11,
425
+  ACI_GATT_FORMAT_SINT64      = 0x12,
426
+  ACI_GATT_FORMAT_SINT128     = 0x13,
427
+  ACI_GATT_FORMAT_FLOAT32     = 0x14,
428
+  ACI_GATT_FORMAT_FLOAT64     = 0x15,
429
+  ACI_GATT_FORMAT_SFLOAT      = 0x16,
430
+  ACI_GATT_FORMAT_FLOAT       = 0x17,
431
+  ACI_GATT_FORMAT_DUINT16     = 0x18,
432
+  ACI_GATT_FORMAT_UTF8S       = 0x19,
433
+  ACI_GATT_FORMAT_UTF16S      = 0x1A,
434
+  ACI_GATT_FORMAT_STRUCT      = 0x1B
435
+} _aci_packed_ aci_gatt_format_t;
436
+
437
+/**
438
+ * @brief GATT Bluetooth namespace
439
+ */
440
+typedef enum
441
+{
442
+  ACI_GATT_NAMESPACE_INVALID  = 0x00,
443
+  ACI_GATT_NAMESPACE_BTSIG    = 0x01 /**< Bluetooth SIG */
444
+} _aci_packed_ aci_gatt_namespace_t;
445
+
446
+/**
447
+ * @brief Security key types
448
+ */
449
+typedef enum
450
+{
451
+  ACI_KEY_TYPE_INVALID  = 0x00,
452
+  ACI_KEY_TYPE_PASSKEY  = 0x01
453
+} _aci_packed_ aci_key_type_t;
454
+
455
+/**
456
+ * @enum aci_bond_status_code_t
457
+ * @brief Bond status code
458
+ */
459
+typedef enum
460
+{
461
+ /**
462
+  * Bonding succeeded
463
+  */
464
+  ACI_BOND_STATUS_SUCCESS                             = 0x00,
465
+ /**
466
+  * Bonding failed
467
+  */
468
+  ACI_BOND_STATUS_FAILED                              = 0x01,
469
+ /**
470
+  * Bonding error: Timeout can occur when link termination is unexpected or did not get connected OR SMP timer expired
471
+  */
472
+  ACI_BOND_STATUS_FAILED_TIMED_OUT                    = 0x02,
473
+ /**
474
+  * Bonding error: Passkey entry failed
475
+  */
476
+  ACI_BOND_STATUS_FAILED_PASSKEY_ENTRY_FAILED        = 0x81,
477
+ /**
478
+  * Bonding error: OOB unavailable
479
+  */
480
+  ACI_BOND_STATUS_FAILED_OOB_UNAVAILABLE             = 0x82,
481
+ /**
482
+  * Bonding error: Authentication request failed
483
+  */
484
+  ACI_BOND_STATUS_FAILED_AUTHENTICATION_REQ          = 0x83,
485
+ /**
486
+  * Bonding error: Confirm value failed
487
+  */
488
+  ACI_BOND_STATUS_FAILED_CONFIRM_VALUE               = 0x84,
489
+ /**
490
+  * Bonding error: Pairing unsupported
491
+  */
492
+  ACI_BOND_STATUS_FAILED_PAIRING_UNSUPPORTED         = 0x85,
493
+ /**
494
+  * Bonding error: Invalid encryption key size
495
+  */
496
+  ACI_BOND_STATUS_FAILED_ENCRYPTION_KEY_SIZE         = 0x86,
497
+ /**
498
+  * Bonding error: Unsupported SMP command
499
+  */
500
+  ACI_BOND_STATUS_FAILED_SMP_CMD_UNSUPPORTED         = 0x87,
501
+ /**
502
+  * Bonding error: Unspecified reason
503
+  */
504
+  ACI_BOND_STATUS_FAILED_UNSPECIFIED_REASON          = 0x88,
505
+ /**
506
+  * Bonding error: Too many attempts
507
+  */
508
+  ACI_BOND_STATUS_FAILED_REPEATED_ATTEMPTS           = 0x89,
509
+ /**
510
+  * Bonding error: Invalid parameters
511
+  */
512
+  ACI_BOND_STATUS_FAILED_INVALID_PARAMETERS          = 0x8A
513
+
514
+} _aci_packed_ aci_bond_status_code_t;
515
+
516
+ACI_ASSERT_SIZE(aci_bond_status_code_t, 1);
517
+
518
+/**
519
+ * @enum aci_bond_status_source_t
520
+ * @brief Source of a bond status code
521
+ */
522
+typedef enum
523
+{
524
+  ACI_BOND_STATUS_SOURCE_INVALID                  = 0x00,
525
+  ACI_BOND_STATUS_SOURCE_LOCAL                    = 0x01,
526
+  ACI_BOND_STATUS_SOURCE_REMOTE                   = 0x02
527
+
528
+} _aci_packed_ aci_bond_status_source_t;
529
+
530
+/**
531
+ * @enum aci_status_code_t
532
+ * @brief ACI status codes
533
+ */
534
+typedef enum
535
+{
536
+ /**
537
+  * Success
538
+  */
539
+  ACI_STATUS_SUCCESS                                        = 0x00,
540
+ /**
541
+  * Transaction continuation status
542
+  */
543
+  ACI_STATUS_TRANSACTION_CONTINUE                           = 0x01,
544
+ /**
545
+  * Transaction completed
546
+  */
547
+  ACI_STATUS_TRANSACTION_COMPLETE                           = 0x02,
548
+ /**
549
+  * Extended status, further checks needed
550
+  */
551
+  ACI_STATUS_EXTENDED                                       = 0x03,
552
+ /**
553
+  * Unknown error.
554
+  */
555
+  ACI_STATUS_ERROR_UNKNOWN                                  = 0x80,
556
+ /**
557
+  * Internal error.
558
+  */
559
+  ACI_STATUS_ERROR_INTERNAL                                 = 0x81,
560
+ /**
561
+  * Unknown command
562
+  */
563
+  ACI_STATUS_ERROR_CMD_UNKNOWN                              = 0x82,
564
+ /**
565
+  * Command invalid in the current device state
566
+  */
567
+  ACI_STATUS_ERROR_DEVICE_STATE_INVALID                     = 0x83,
568
+ /**
569
+  * Invalid length
570
+  */
571
+  ACI_STATUS_ERROR_INVALID_LENGTH                           = 0x84,
572
+ /**
573
+  * Invalid input parameters
574
+  */
575
+  ACI_STATUS_ERROR_INVALID_PARAMETER                        = 0x85,
576
+ /**
577
+  * Busy
578
+  */
579
+  ACI_STATUS_ERROR_BUSY                                     = 0x86,
580
+ /**
581
+  * Invalid data format or contents
582
+  */
583
+  ACI_STATUS_ERROR_INVALID_DATA                             = 0x87,
584
+ /**
585
+  * CRC mismatch
586
+  */
587
+  ACI_STATUS_ERROR_CRC_MISMATCH                             = 0x88,
588
+ /**
589
+  * Unsupported setup format
590
+  */
591
+  ACI_STATUS_ERROR_UNSUPPORTED_SETUP_FORMAT                 = 0x89,
592
+ /**
593
+  * Invalid sequence number during a write dynamic data sequence
594
+  */
595
+  ACI_STATUS_ERROR_INVALID_SEQ_NO                           = 0x8A,
596
+ /**
597
+  * Setup data is locked and cannot be modified
598
+  */
599
+  ACI_STATUS_ERROR_SETUP_LOCKED                             = 0x8B,
600
+ /**
601
+  * Setup error due to lock verification failure
602
+  */
603
+  ACI_STATUS_ERROR_LOCK_FAILED                              = 0x8C,
604
+ /**
605
+  * Bond required: Local Pipes need bonded/trusted peer
606
+  */
607
+  ACI_STATUS_ERROR_BOND_REQUIRED                            = 0x8D,
608
+ /**
609
+  * Command rejected as a transaction is still pending
610
+  */
611
+  ACI_STATUS_ERROR_REJECTED                                 = 0x8E,
612
+  /**
613
+  * Pipe Error Event : Data size exceeds size specified for pipe : Transmit failed
614
+  */
615
+  ACI_STATUS_ERROR_DATA_SIZE                                = 0x8F,
616
+ /**
617
+  * Pipe Error Event : Invalid pipe
618
+  */
619
+  ACI_STATUS_ERROR_PIPE_INVALID                             = 0x90,
620
+ /**
621
+  * Pipe Error Event : Credit not available
622
+  */
623
+  ACI_STATUS_ERROR_CREDIT_NOT_AVAILABLE                     = 0x91,
624
+ /**
625
+  * Pipe Error Event : Peer device has sent an error on an pipe operation on the remote characteristic
626
+  */
627
+  ACI_STATUS_ERROR_PEER_ATT_ERROR                           = 0x92,
628
+ /**
629
+  * Connection was not established before the BTLE advertising was stopped
630
+  */
631
+  ACI_STATUS_ERROR_ADVT_TIMEOUT                             = 0x93,
632
+ /**
633
+  * Peer has triggered a Security Manager Protocol Error
634
+  */
635
+  ACI_STATUS_ERROR_PEER_SMP_ERROR                           = 0x94,
636
+ /**
637
+  * Pipe Error Event : Pipe type invalid for the selected operation
638
+  */
639
+  ACI_STATUS_ERROR_PIPE_TYPE_INVALID                        = 0x95,
640
+ /**
641
+  * Pipe Error Event : Pipe state invalid for the selected operation
642
+  */
643
+  ACI_STATUS_ERROR_PIPE_STATE_INVALID                       = 0x96,
644
+ /**
645
+  * Invalid key size provided
646
+  */
647
+  ACI_STATUS_ERROR_INVALID_KEY_SIZE                         = 0x97,
648
+ /**
649
+  * Invalid key data provided
650
+  */
651
+  ACI_STATUS_ERROR_INVALID_KEY_DATA                         = 0x98,
652
+ /**
653
+  * Reserved range start
654
+  */
655
+  ACI_STATUS_RESERVED_START                                 = 0xF0,
656
+ /**
657
+  * Reserved range end
658
+  */
659
+  ACI_STATUS_RESERVED_END                                   = 0xFF
660
+
661
+} _aci_packed_ aci_status_code_t;
662
+
663
+ACI_ASSERT_SIZE(aci_status_code_t, 1);
664
+
665
+/**
666
+ * @}
667
+ */
668
+
669
+#endif // ACI_H__

+ 435
- 0
src/nrf8001/aci_cmds.h 查看文件

@@ -0,0 +1,435 @@
1
+/* Copyright (c) 2014, Nordic Semiconductor ASA
2
+ *
3
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ * of this software and associated documentation files (the "Software"), to deal
5
+ * in the Software without restriction, including without limitation the rights
6
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ * copies of the Software, and to permit persons to whom the Software is
8
+ * furnished to do so, subject to the following conditions:
9
+ *
10
+ * The above copyright notice and this permission notice shall be included in all
11
+ * copies or substantial portions of the Software.
12
+ *
13
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ * SOFTWARE.
20
+ */
21
+
22
+/**
23
+ * @file
24
+ *
25
+ * @ingroup aci
26
+ *
27
+ * @brief Definitions for the ACI (Application Control Interface) commands
28
+ * @remarks
29
+ *
30
+ */
31
+
32
+#ifndef ACI_CMDS_H__
33
+#define ACI_CMDS_H__
34
+
35
+#include "aci.h"
36
+
37
+/**
38
+ * @enum aci_cmd_opcode_t
39
+ * @brief ACI command opcodes
40
+ */
41
+typedef enum
42
+{
43
+ /**
44
+  * Enter test mode
45
+  */
46
+  ACI_CMD_TEST                    = 0x01,
47
+ /**
48
+  * Echo (loopback) test command
49
+  */
50
+  ACI_CMD_ECHO                    = 0x02,
51
+ /**
52
+  * Send a BTLE DTM command to the radio
53
+  */
54
+  ACI_CMD_DTM_CMD                 = 0x03,
55
+  /**
56
+  * Put the device to sleep
57
+  */
58
+  ACI_CMD_SLEEP                   = 0x04,
59
+ /**
60
+  * Wakeup the device from deep sleep
61
+  */
62
+  ACI_CMD_WAKEUP                  = 0x05,
63
+ /**
64
+  * Replace the contents of the internal database with
65
+  * user provided data
66
+  */
67
+  ACI_CMD_SETUP                   = 0x06,
68
+ /**
69
+  * Read the portions of memory required to be restored after a power cycle
70
+  */
71
+  ACI_CMD_READ_DYNAMIC_DATA       = 0x07,
72
+ /**
73
+  * Write back the data retrieved using ACI_CMD_READ_DYNAMIC_DATA
74
+  */
75
+  ACI_CMD_WRITE_DYNAMIC_DATA      = 0x08,
76
+  /**
77
+  * Retrieve the device's version information
78
+  */
79
+  ACI_CMD_GET_DEVICE_VERSION      = 0x09,
80
+ /**
81
+  * Request the Bluetooth address and its type
82
+  */
83
+  ACI_CMD_GET_DEVICE_ADDRESS      = 0x0A,
84
+  /**
85
+  * Request the battery level measured by nRF8001
86
+  */
87
+  ACI_CMD_GET_BATTERY_LEVEL       = 0x0B,
88
+ /**
89
+  * Request the temperature value measured by nRF8001
90
+  */
91
+  ACI_CMD_GET_TEMPERATURE         = 0x0C,
92
+ /**
93
+  * Write to the local Attribute Database
94
+  */
95
+  ACI_CMD_SET_LOCAL_DATA          = 0x0D,
96
+ /**
97
+  * Reset the baseband and radio and go back to idle
98
+  */
99
+  ACI_CMD_RADIO_RESET          = 0x0E,
100
+ /**
101
+  * Start advertising and wait for a master connection
102
+  */
103
+  ACI_CMD_CONNECT                 = 0x0F,
104
+ /**
105
+  * Start advertising and wait for a master connection
106
+  */
107
+  ACI_CMD_BOND                    = 0x10,
108
+ /**
109
+  * Start advertising and wait for a master connection
110
+  */
111
+  ACI_CMD_DISCONNECT              = 0x11,
112
+ /**
113
+  * Throttles the Radio transmit power
114
+  */
115
+  ACI_CMD_SET_TX_POWER            = 0x12,
116
+ /**
117
+  * Trigger a connection parameter update
118
+  */
119
+  ACI_CMD_CHANGE_TIMING           = 0x13,
120
+ /**
121
+  * Open a remote pipe for data reception
122
+  */
123
+  ACI_CMD_OPEN_REMOTE_PIPE        = 0x14,
124
+ /**
125
+  * Transmit data over an open pipe
126
+  */
127
+  ACI_CMD_SEND_DATA               = 0x15,
128
+ /**
129
+  * Send an acknowledgment of received data
130
+  */
131
+  ACI_CMD_SEND_DATA_ACK           = 0x16,
132
+ /**
133
+  * Request data over an open pipe
134
+  */
135
+  ACI_CMD_REQUEST_DATA            = 0x17,
136
+ /**
137
+  * NACK a data reception
138
+  */
139
+  ACI_CMD_SEND_DATA_NACK          = 0x18,
140
+ /**
141
+  * Set application latency
142
+  */
143
+  ACI_CMD_SET_APP_LATENCY         = 0x19,
144
+ /**
145
+  * Set a security key
146
+  */
147
+  ACI_CMD_SET_KEY                 = 0x1A,
148
+ /**
149
+  * Open Advertising Pipes
150
+  */
151
+  ACI_CMD_OPEN_ADV_PIPE           = 0x1B,
152
+ /**
153
+  * Start non-connectable advertising
154
+  */
155
+  ACI_CMD_BROADCAST               = 0x1C,
156
+ /**
157
+  * Start a security request in bonding mode
158
+  */
159
+  ACI_CMD_BOND_SECURITY_REQUEST   = 0x1D,
160
+ /**
161
+  * Start Directed advertising towards a Bonded Peer
162
+  */
163
+  ACI_CMD_CONNECT_DIRECT          = 0x1E,
164
+ /**
165
+  * Close a previously opened remote pipe
166
+  */
167
+  ACI_CMD_CLOSE_REMOTE_PIPE       = 0x1F,
168
+ /**
169
+  * Invalid ACI command opcode
170
+  */
171
+  ACI_CMD_INVALID                 = 0xFF
172
+
173
+} _aci_packed_ aci_cmd_opcode_t;
174
+
175
+ACI_ASSERT_SIZE(aci_cmd_opcode_t, 1);
176
+
177
+/**
178
+ * @struct aci_cmd_params_test_t
179
+ * @brief  Structure for the ACI_CMD_TEST ACI command parameters
180
+ */
181
+typedef struct
182
+{
183
+  aci_test_mode_change_t test_mode_change; /**< enum aci_test_mode_change_t */
184
+} _aci_packed_ aci_cmd_params_test_t;
185
+
186
+ACI_ASSERT_SIZE(aci_cmd_params_test_t, 1);
187
+
188
+/**
189
+ * @struct aci_cmd_params_echo_t
190
+ * @brief  Structure for the ACI_CMD_ECHO ACI command parameters
191
+ */
192
+typedef struct
193
+{
194
+  uint8_t echo_data[ACI_ECHO_DATA_MAX_LEN];
195
+} _aci_packed_ aci_cmd_params_echo_t;
196
+
197
+ACI_ASSERT_SIZE(aci_cmd_params_echo_t, ACI_ECHO_DATA_MAX_LEN);
198
+
199
+/**
200
+ * @struct aci_cmd_params_dtm_cmd_t
201
+ * @brief  Structure for the ACI_CMD_DTM_CMD ACI command parameters
202
+ */
203
+typedef struct
204
+{
205
+  uint8_t                 cmd_msb;
206
+  uint8_t                 cmd_lsb;
207
+} _aci_packed_ aci_cmd_params_dtm_cmd_t;
208
+
209
+/**
210
+ * @struct aci_cmd_params_setup_t
211
+ * @brief  Structure for the ACI_CMD_SETUP ACI command parameters
212
+ */
213
+typedef struct
214
+{
215
+  uint8_t                 setup_data[1];
216
+} _aci_packed_ aci_cmd_params_setup_t;
217
+
218
+ACI_ASSERT_SIZE(aci_cmd_params_setup_t, 1);
219
+
220
+/**
221
+ * @struct aci_cmd_params_write_dynamic_data_t
222
+ * @brief  Structure for the ACI_CMD_WRITE_DYNAMIC_DATA ACI command parameters
223
+ * @note Dynamic data chunk size in this command is defined to go up to ACI_PACKET_MAX_LEN - 3
224
+ */
225
+typedef struct
226
+{
227
+  uint8_t                 seq_no;
228
+  uint8_t                 dynamic_data[1];
229
+} _aci_packed_ aci_cmd_params_write_dynamic_data_t;
230
+
231
+/**
232
+ * @define aci_cmd_params_set_local_data_t
233
+ * @brief  Structure for the ACI_CMD_SET_LOCAL_DATA ACI command parameters
234
+ */
235
+typedef struct
236
+{
237
+  aci_tx_data_t tx_data;
238
+} _aci_packed_ aci_cmd_params_set_local_data_t;
239
+
240
+/**
241
+ * @struct aci_cmd_params_connect_t
242
+ * @brief  Structure for the ACI_CMD_CONNECT ACI command parameters
243
+ */
244
+typedef struct
245
+{
246
+  uint16_t        timeout;  /**< 0x0000 (no timeout) to 0x3FFF */
247
+  uint16_t        adv_interval;     /**< 16 bits of advertising interval for general discovery */
248
+} _aci_packed_ aci_cmd_params_connect_t;
249
+
250
+ACI_ASSERT_SIZE(aci_cmd_params_connect_t, 4);
251
+
252
+/**
253
+ * @define aci_cmd_params_bond_t
254
+ * @brief  Structure for the ACI_CMD_BOND ACI command parameters
255
+ */
256
+typedef struct
257
+{
258
+  uint16_t        timeout;  /**< 0x0000 (no timeout) to 0x3FFF */
259
+  uint16_t        adv_interval;     /**< 16 bits of advertising interval for general discovery */
260
+} _aci_packed_ aci_cmd_params_bond_t;
261
+
262
+ACI_ASSERT_SIZE(aci_cmd_params_bond_t, 4);
263
+
264
+/**
265
+ * @struct aci_cmd_params_disconnect_t
266
+ * @brief  Structure for the ACI_CMD_DISCONNECT ACI command parameters
267
+ */
268
+typedef struct
269
+{
270
+  aci_disconnect_reason_t         reason; /**< enum aci_disconnect_reason_t */
271
+} _aci_packed_ aci_cmd_params_disconnect_t;
272
+
273
+ACI_ASSERT_SIZE(aci_cmd_params_disconnect_t, 1);
274
+
275
+/**
276
+ * @struct aci_cmd_params_set_tx_power_t
277
+ * @brief  Structure for the ACI_CMD_SET_TX_POWER ACI command parameters
278
+ */
279
+typedef struct
280
+{
281
+  aci_device_output_power_t   device_power; /**< enum aci_device_output_power_t */
282
+} _aci_packed_ aci_cmd_params_set_tx_power_t;
283
+
284
+ACI_ASSERT_SIZE(aci_cmd_params_set_tx_power_t, 1);
285
+/**
286
+ * @struct aci_cmd_params_change_timing_t
287
+ * @brief  Structure for the ACI_CMD_CHANGE_TIMING ACI command parameters
288
+ */
289
+typedef struct
290
+{
291
+  aci_ll_conn_params_t    conn_params;
292
+} _aci_packed_ aci_cmd_params_change_timing_t;
293
+
294
+ACI_ASSERT_SIZE(aci_cmd_params_change_timing_t, 8);
295
+
296
+/**
297
+ * @struct aci_cmd_params_open_remote_pipe_t
298
+ * @brief  Structure for the ACI_CMD_OPEN_REMOTE_PIPE ACI command parameters
299
+ */
300
+typedef struct
301
+{
302
+  uint8_t pipe_number;
303
+} _aci_packed_ aci_cmd_params_open_remote_pipe_t;
304
+
305
+/**
306
+ * @struct aci_cmd_params_send_data_t
307
+ * @brief  Structure for the ACI_CMD_SEND_DATA ACI command parameters
308
+ */
309
+typedef struct
310
+{
311
+  aci_tx_data_t tx_data;
312
+} _aci_packed_ aci_cmd_params_send_data_t;
313
+
314
+/**
315
+ * @define aci_cmd_params_send_data_ack_t
316
+ * @brief  Structure for the ACI_CMD_SEND_DATA_ACK ACI command parameters
317
+ */
318
+typedef struct
319
+{
320
+  uint8_t pipe_number;
321
+} _aci_packed_ aci_cmd_params_send_data_ack_t;
322
+
323
+/**
324
+ * @struct aci_cmd_params_send_data_t
325
+ * @brief  Structure for the ACI_CMD_SEND_DATA ACI command parameters
326
+ */
327
+typedef struct
328
+{
329
+  uint8_t pipe_number;
330
+} _aci_packed_ aci_cmd_params_request_data_t;
331
+
332
+/**
333
+ * @define aci_cmd_params_send_data_nack_t
334
+ * @brief  Structure for the ACI_CMD_SEND_DATA_NACK ACI command parameters
335
+ */
336
+typedef struct
337
+{
338
+  uint8_t pipe_number;
339
+  uint8_t error_code;
340
+} _aci_packed_ aci_cmd_params_send_data_nack_t;
341
+
342
+ACI_ASSERT_SIZE(aci_cmd_params_send_data_nack_t, 2);
343
+
344
+/**
345
+ * @define aci_cmd_params_set_app_latency_t
346
+ * @brief  Structure for the ACI_CMD_SET_APP_LATENCY ACI command parameters
347
+ */
348
+typedef struct
349
+{
350
+  aci_app_latency_mode_t mode;
351
+  uint16_t latency;
352
+} _aci_packed_ aci_cmd_params_set_app_latency_t;
353
+
354
+ACI_ASSERT_SIZE(aci_cmd_params_set_app_latency_t, 3);
355
+/**
356
+ * @define aci_cmd_params_set_key_t
357
+ * @brief  Structure for the ACI_CMD_SET_KEY ACI command parameters
358
+ */
359
+typedef struct
360
+{
361
+  aci_key_type_t key_type;
362
+  union
363
+  {
364
+    uint8_t passkey[6];
365
+    uint8_t oob_key[16];
366
+  } key;
367
+} _aci_packed_ aci_cmd_params_set_key_t;
368
+
369
+ACI_ASSERT_SIZE(aci_cmd_params_set_key_t, 17);
370
+/**
371
+ * @define aci_cmd_params_open_adv_pipe_t
372
+ * @brief  Structure for the ACI_CMD_OPEN_ADV_PIPE ACI command parameters
373
+ */
374
+typedef struct
375
+{
376
+  uint8_t pipes[8];
377
+} _aci_packed_ aci_cmd_params_open_adv_pipe_t;
378
+
379
+/**
380
+ * @define aci_cmd_params_broadcast_t
381
+ * @brief  Structure for the ACI_CMD_BROADCAST ACI command parameters
382
+ */
383
+typedef struct
384
+{
385
+  uint16_t        timeout;  /**< 0x0000 (no timeout) to 0x3FFF */
386
+  uint16_t        adv_interval;     /**< 16 bits of advertising interval for general discovery */
387
+} _aci_packed_ aci_cmd_params_broadcast_t;
388
+
389
+/**
390
+ * @struct aci_cmd_params_close_remote_pipe_t
391
+ * @brief  Structure for the ACI_CMD_CLOSE_REMOTE_PIPE ACI command parameters
392
+ */
393
+typedef struct
394
+{
395
+  uint8_t pipe_number;
396
+} _aci_packed_ aci_cmd_params_close_remote_pipe_t;
397
+
398
+/**
399
+ * @struct aci_cmd_t
400
+ * @brief  Encapsulates a generic ACI command
401
+ */
402
+typedef struct
403
+{
404
+  uint8_t len;        /**< Length of the ACI command */
405
+  aci_cmd_opcode_t cmd_opcode; /**< enum aci_cmd_opcode_t -> Opcode of the ACI command */
406
+  union
407
+  {
408
+    aci_cmd_params_test_t                       test;
409
+    aci_cmd_params_echo_t                       echo;
410
+    aci_cmd_params_dtm_cmd_t                    dtm_cmd;
411
+    aci_cmd_params_setup_t                      setup;
412
+    aci_cmd_params_write_dynamic_data_t         write_dynamic_data;
413
+    aci_cmd_params_set_local_data_t             set_local_data;
414
+    aci_cmd_params_connect_t                    connect;
415
+    aci_cmd_params_bond_t                       bond;
416
+    aci_cmd_params_disconnect_t                 disconnect;
417
+    aci_cmd_params_set_tx_power_t               set_tx_power;
418
+    aci_cmd_params_change_timing_t              change_timing;
419
+    aci_cmd_params_open_remote_pipe_t           open_remote_pipe;
420
+    aci_cmd_params_send_data_t                  send_data;
421
+    aci_cmd_params_send_data_ack_t              send_data_ack;
422
+    aci_cmd_params_request_data_t               request_data;
423
+    aci_cmd_params_send_data_nack_t             send_data_nack;
424
+    aci_cmd_params_set_app_latency_t            set_app_latency;
425
+    aci_cmd_params_set_key_t                    set_key;
426
+    aci_cmd_params_open_adv_pipe_t              open_adv_pipe;
427
+    aci_cmd_params_broadcast_t                  broadcast;
428
+    aci_cmd_params_close_remote_pipe_t          close_remote_pipe;
429
+
430
+  } params;
431
+} _aci_packed_ aci_cmd_t;
432
+
433
+#endif // ACI_CMDS_H__
434
+
435
+

+ 397
- 0
src/nrf8001/aci_evts.h 查看文件

@@ -0,0 +1,397 @@
1
+/* Copyright (c) 2014, Nordic Semiconductor ASA
2
+ *
3
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ * of this software and associated documentation files (the "Software"), to deal
5
+ * in the Software without restriction, including without limitation the rights
6
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ * copies of the Software, and to permit persons to whom the Software is
8
+ * furnished to do so, subject to the following conditions:
9
+ *
10
+ * The above copyright notice and this permission notice shall be included in all
11
+ * copies or substantial portions of the Software.
12
+ *
13
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ * SOFTWARE.
20
+ */
21
+
22
+/**
23
+ * @file
24
+ *
25
+ * @ingroup aci
26
+ *
27
+ * @brief Definitions for the ACI (Application Control Interface) events
28
+ */
29
+
30
+#ifndef ACI_EVTS_H__
31
+#define ACI_EVTS_H__
32
+
33
+#include "aci.h"
34
+
35
+/**
36
+ * @enum aci_evt_opcode_t
37
+ * @brief ACI event opcodes
38
+ */
39
+typedef enum
40
+{
41
+ /**
42
+  * Invalid event code
43
+  */
44
+  ACI_EVT_INVALID                     = 0x00,
45
+ /**
46
+  * Sent every time the device starts
47
+  */
48
+  ACI_EVT_DEVICE_STARTED              = 0x81,
49
+ /**
50
+  * Mirrors the ACI_CMD_ECHO
51
+  */
52
+  ACI_EVT_ECHO                        = 0x82,
53
+ /**
54
+  * Asynchronous hardware error event
55
+  */
56
+  ACI_EVT_HW_ERROR                  = 0x83,
57
+ /**
58
+  * Event opcode used as a event response for all commands
59
+  */
60
+  ACI_EVT_CMD_RSP                     = 0x84,
61
+ /**
62
+  * Link connected
63
+  */
64
+  ACI_EVT_CONNECTED                   = 0x85,
65
+ /**
66
+  * Link disconnected
67
+  */
68
+  ACI_EVT_DISCONNECTED                = 0x86,
69
+ /**
70
+  * Bond completion result
71
+  */
72
+  ACI_EVT_BOND_STATUS                 = 0x87,
73
+  /**
74
+  * Pipe bitmap for available pipes
75
+  */
76
+  ACI_EVT_PIPE_STATUS             = 0x88,
77
+ /**
78
+  * Sent to the application when the radio enters a connected state
79
+  * or when the timing of the radio connection changes
80
+  */
81
+  ACI_EVT_TIMING                      = 0x89,
82
+ /**
83
+  * Notification to the application that transmit credits are
84
+  * available
85
+  */
86
+  ACI_EVT_DATA_CREDIT                 = 0x8A,
87
+ /**
88
+  * Data acknowledgement event
89
+  */
90
+  ACI_EVT_DATA_ACK                    = 0x8B,
91
+ /**
92
+  * Data received notification event
93
+  */
94
+  ACI_EVT_DATA_RECEIVED               = 0x8C,
95
+ /**
96
+  * Error notification event
97
+  */
98
+  ACI_EVT_PIPE_ERROR                  = 0x8D,
99
+ /**
100
+  * Display Passkey Event
101
+  */
102
+  ACI_EVT_DISPLAY_PASSKEY             = 0x8E,
103
+ /**
104
+  * Security Key request
105
+  */
106
+  ACI_EVT_KEY_REQUEST                 = 0x8F
107
+
108
+} _aci_packed_ aci_evt_opcode_t;
109
+
110
+ACI_ASSERT_SIZE(aci_evt_opcode_t, 1);
111
+
112
+/**
113
+ * @struct aci_evt_params_device_started_t
114
+ * @brief Structure for the ACI_EVT_DEVICE_STARTED event return parameters
115
+ */
116
+typedef struct
117
+{
118
+  aci_device_operation_mode_t device_mode; /**< Mode in which the device is being started */
119
+  aci_hw_error_t hw_error;  /**< Hardware Error if available for the start */
120
+  uint8_t credit_available; /**< Flow control credit available for this specific FW build */
121
+} _aci_packed_ aci_evt_params_device_started_t;
122
+
123
+ACI_ASSERT_SIZE(aci_evt_params_device_started_t, 3);
124
+
125
+/**
126
+ * @struct aci_evt_params_hw_error_t
127
+ * @brief Structure for the ACI_EVT_HW_ERROR event return parameters
128
+ */
129
+typedef struct
130
+{
131
+  uint16_t line_num;
132
+  uint8_t file_name[20];
133
+} _aci_packed_ aci_evt_params_hw_error_t;
134
+
135
+ACI_ASSERT_SIZE(aci_evt_params_hw_error_t, 22);
136
+
137
+/**
138
+ * @struct aci_evt_cmd_rsp_params_dtm_cmd_t
139
+ * @brief Structure for the ACI_EVT_CMD_RSP event with opcode=ACI_CMD_DTM_CMD event return parameters
140
+ */
141
+typedef struct
142
+{
143
+  uint8_t  evt_msb;
144
+  uint8_t  evt_lsb;
145
+} _aci_packed_ aci_evt_cmd_rsp_params_dtm_cmd_t;
146
+
147
+/**
148
+ * @struct aci_evt_cmd_rsp_read_dynamic_data_t
149
+ * @brief Structure for the ACI_EVT_CMD_RSP event with opcode=ACI_CMD_READ_DYNAMIC_DATA event return parameters
150
+ * @note Dynamic data chunk size in this event is defined to go up to ACI_PACKET_MAX_LEN - 5
151
+ */
152
+typedef struct
153
+{
154
+  uint8_t seq_no;
155
+  uint8_t dynamic_data[1];
156
+} _aci_packed_ aci_evt_cmd_rsp_read_dynamic_data_t;
157
+
158
+/**
159
+ * @struct aci_evt_cmd_rsp_params_get_device_version_t
160
+ * @brief Structure for the ACI_EVT_CMD_RSP event with opcode=ACI_CMD_GET_DEVICE_VERSION event return parameters
161
+ */
162
+typedef struct
163
+{
164
+  uint16_t  configuration_id;
165
+  uint8_t   aci_version;
166
+  uint8_t   setup_format;
167
+  uint32_t  setup_id;
168
+  uint8_t   setup_status;
169
+} _aci_packed_ aci_evt_cmd_rsp_params_get_device_version_t;
170
+
171
+ACI_ASSERT_SIZE(aci_evt_cmd_rsp_params_get_device_version_t, 9);
172
+
173
+/**
174
+ * @struct aci_evt_cmd_rsp_params_get_device_address_t
175
+ * @brief Structure for the ACI_EVT_CMD_RSP event with opcode=ACI_CMD_GET_DEVICE_ADDRESS event return parameters
176
+ */
177
+typedef struct
178
+{
179
+  uint8_t  bd_addr_own[BTLE_DEVICE_ADDRESS_SIZE];
180
+  aci_bd_addr_type_t bd_addr_type;
181
+} _aci_packed_ aci_evt_cmd_rsp_params_get_device_address_t;
182
+
183
+ACI_ASSERT_SIZE(aci_evt_cmd_rsp_params_get_device_address_t, BTLE_DEVICE_ADDRESS_SIZE + 1);
184
+
185
+/**
186
+ * @struct aci_evt_cmd_rsp_params_get_battery_level_t
187
+ * @brief Structure for the ACI_EVT_CMD_RSP event with opcode=ACI_CMD_GET_BATTERY_LEVEL event return parameters
188
+ */
189
+typedef struct
190
+{
191
+  uint16_t battery_level;
192
+} _aci_packed_ aci_evt_cmd_rsp_params_get_battery_level_t;
193
+
194
+/**
195
+ * @struct aci_evt_cmd_rsp_params_get_temperature_t
196
+ * @brief Structure for the ACI_EVT_CMD_RSP event with opcode=ACI_CMD_GET_TEMPERATURE event return parameters
197
+ */
198
+typedef struct
199
+{
200
+  int16_t temperature_value;
201
+} _aci_packed_ aci_evt_cmd_rsp_params_get_temperature_t;
202
+
203
+/**
204
+ * @struct aci_evt_params_cmd_rsp_t
205
+ * @brief Structure for the ACI_EVT_CMD_RSP event return parameters
206
+ */
207
+typedef struct
208
+{
209
+  aci_cmd_opcode_t cmd_opcode; /**< Command opcode for which the event response is being sent */
210
+  aci_status_code_t cmd_status; /**< Status of the command that was sent. Used in the context of the command. */
211
+  union
212
+  {
213
+    aci_evt_cmd_rsp_params_dtm_cmd_t dtm_cmd;
214
+    aci_evt_cmd_rsp_read_dynamic_data_t read_dynamic_data;
215
+    aci_evt_cmd_rsp_params_get_device_version_t get_device_version;
216
+    aci_evt_cmd_rsp_params_get_device_address_t get_device_address;
217
+    aci_evt_cmd_rsp_params_get_battery_level_t  get_battery_level;
218
+    aci_evt_cmd_rsp_params_get_temperature_t    get_temperature;
219
+    uint8_t                                     padding[29];
220
+  } params;
221
+} _aci_packed_ aci_evt_params_cmd_rsp_t;
222
+
223
+ACI_ASSERT_SIZE(aci_evt_params_cmd_rsp_t, 31);
224
+
225
+/**
226
+ * @struct aci_evt_params_connected_t
227
+ * @brief Structure for the ACI_EVT_CONNECTED event return parameters
228
+ */
229
+typedef struct
230
+{
231
+  aci_bd_addr_type_t dev_addr_type;
232
+  uint8_t  dev_addr[BTLE_DEVICE_ADDRESS_SIZE];
233
+  uint16_t conn_rf_interval;  /**< rf_interval = conn_rf_interval * 1.25 ms Range:0x0006 to 0x0C80 */
234
+  uint16_t conn_slave_rf_latency; /**< Number of RF events the slave can skip */
235
+  uint16_t conn_rf_timeout; /**< Timeout as a multiple of 10ms i.e timeout = conn_rf_timeout * 10ms Range: 0x000A to 0x0C80 */
236
+  aci_clock_accuracy_t master_clock_accuracy; /**< Clock accuracy of Bluetooth master: Enumerated list of values from 500 ppm to 20 ppm */
237
+} _aci_packed_ aci_evt_params_connected_t;
238
+
239
+ACI_ASSERT_SIZE(aci_evt_params_connected_t, 14);
240
+
241
+/**
242
+ * @struct aci_evt_params_disconnected_t
243
+ * @brief Structure for the ACI_EVT_DISCONNECTED event return parameters
244
+ */
245
+typedef struct
246
+{
247
+  aci_status_code_t   aci_status;
248
+  uint8_t btle_status;
249
+} _aci_packed_ aci_evt_params_disconnected_t;
250
+
251
+ACI_ASSERT_SIZE(aci_evt_params_disconnected_t, 2);
252
+
253
+/**
254
+ * @struct aci_evt_params_bond_status_t
255
+ * @brief Structure for the ACI_EVT_BOND_STATUS event return parameters
256
+ */
257
+typedef struct
258
+{
259
+  aci_bond_status_code_t status_code;
260
+  aci_bond_status_source_t status_source;
261
+  uint8_t secmode1_bitmap;
262
+  uint8_t secmode2_bitmap;
263
+  uint8_t keys_exchanged_slave;
264
+  uint8_t keys_exchanged_master;
265
+} _aci_packed_ aci_evt_params_bond_status_t;
266
+
267
+ACI_ASSERT_SIZE(aci_evt_params_bond_status_t, 6);
268
+
269
+/**
270
+ * @struct aci_evt_params_pipe_status_t
271
+ * @brief Structure for the ACI_EVT_PIPE_STATUS event return parameters
272
+ */
273
+typedef struct
274
+{
275
+  uint8_t  pipes_open_bitmap[8];
276
+  uint8_t  pipes_closed_bitmap[8];
277
+} _aci_packed_ aci_evt_params_pipe_status_t;
278
+
279
+ACI_ASSERT_SIZE(aci_evt_params_pipe_status_t, 16);
280
+
281
+/**
282
+ * @struct aci_evt_params_timing_t
283
+ * @brief Structure for the ACI_EVT_TIMING event return parameters
284
+ */
285
+typedef struct
286
+{
287
+  uint16_t conn_rf_interval;  /**< rf_interval = conn_rf_interval * 1.25 ms Range:0x0006 to 0x0C80 */
288
+  uint16_t conn_slave_rf_latency; /**< Number of RF events the slave can skip */
289
+  uint16_t conn_rf_timeout; /**< Timeout as a multiple of 10ms i.e timeout = conn_rf_timeout * 10ms Range: 0x000A to 0x0C80 */
290
+} _aci_packed_ aci_evt_params_timing_t;
291
+
292
+ACI_ASSERT_SIZE(aci_evt_params_timing_t, 6);
293
+
294
+/**
295
+ * @struct aci_evt_params_data_credit_t
296
+ * @brief Structure for the ACI_EVT_DATA_CREDIT event return parameters
297
+ */
298
+typedef struct
299
+{
300
+  uint8_t credit;
301
+} _aci_packed_ aci_evt_params_data_credit_t;
302
+
303
+/**
304
+ * @struct aci_evt_params_data_ack_t
305
+ * @brief Structure for the ACI_EVT_DATA_ACK event return parameters
306
+ */
307
+typedef struct
308
+{
309
+  uint8_t pipe_number;
310
+} _aci_packed_ aci_evt_params_data_ack_t;
311
+
312
+/**
313
+ * @struct aci_evt_params_data_received_t
314
+ * @brief Structure for the ACI_EVT_DATA_RECEIVED event return parameters
315
+ */
316
+typedef struct
317
+{
318
+  aci_rx_data_t rx_data;
319
+} _aci_packed_ aci_evt_params_data_received_t;
320
+
321
+typedef struct
322
+{
323
+  uint8_t content[1];
324
+} _aci_packed_ error_data_t;
325
+
326
+/**
327
+ * @struct aci_evt_params_pipe_error_t
328
+ * @brief Structure for the ACI_EVT_PIPE_ERROR event return parameters
329
+ */
330
+typedef struct
331
+{
332
+  uint8_t pipe_number;
333
+  uint8_t error_code;
334
+  union
335
+  {
336
+    error_data_t  error_data;
337
+  } params;
338
+} _aci_packed_ aci_evt_params_pipe_error_t;
339
+
340
+/**
341
+ * @struct aci_evt_params_display_passkey_t
342
+ * @brief Structure for the ACI_EVT_DISPLAY_PASSKEY event return parameters
343
+ */
344
+typedef struct
345
+{
346
+  uint8_t passkey[6];
347
+} _aci_packed_ aci_evt_params_display_passkey_t;
348
+
349
+/**
350
+ * @struct aci_evt_params_key_request_t
351
+ * @brief Structure for the ACI_EVT_KEY_REQUEST event return parameters
352
+ */
353
+typedef struct
354
+{
355
+  aci_key_type_t key_type;
356
+} _aci_packed_ aci_evt_params_key_request_t;
357
+
358
+/**
359
+ * @struct aci_event_params_echo_t
360
+ * @brief  Structure for the ACI_EVT_ECHO ACI event parameters
361
+ */
362
+typedef struct
363
+{
364
+  uint8_t echo_data[ACI_ECHO_DATA_MAX_LEN];
365
+} _aci_packed_ aci_evt_params_echo_t;
366
+
367
+/**
368
+ * @struct aci_evt_t
369
+ * @brief  Encapsulates a generic ACI event
370
+ */
371
+typedef struct
372
+{
373
+  uint8_t len;
374
+  aci_evt_opcode_t evt_opcode;
375
+  union
376
+  {
377
+    aci_evt_params_device_started_t                     device_started;
378
+    aci_evt_params_echo_t                               echo;
379
+    aci_evt_params_hw_error_t                           hw_error;
380
+    aci_evt_params_cmd_rsp_t                            cmd_rsp;
381
+    aci_evt_params_connected_t                          connected;
382
+    aci_evt_params_disconnected_t                       disconnected;
383
+    aci_evt_params_bond_status_t                        bond_status;
384
+    aci_evt_params_pipe_status_t                        pipe_status;
385
+    aci_evt_params_timing_t                             timing;
386
+    aci_evt_params_data_credit_t                        data_credit;
387
+    aci_evt_params_data_ack_t                           data_ack;
388
+    aci_evt_params_data_received_t                      data_received;
389
+    aci_evt_params_pipe_error_t                         pipe_error;
390
+    aci_evt_params_display_passkey_t                    display_passkey;
391
+    aci_evt_params_key_request_t                        key_request;
392
+  } params;
393
+} _aci_packed_ aci_evt_t;
394
+
395
+ACI_ASSERT_SIZE(aci_evt_t, 33);
396
+
397
+#endif // ACI_EVTS_H__

+ 188
- 0
src/nrf8001/aci_protocol_defines.h 查看文件

@@ -0,0 +1,188 @@
1
+/* Copyright (c) 2014, Nordic Semiconductor ASA
2
+ *
3
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ * of this software and associated documentation files (the "Software"), to deal
5
+ * in the Software without restriction, including without limitation the rights
6
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ * copies of the Software, and to permit persons to whom the Software is
8
+ * furnished to do so, subject to the following conditions:
9
+ *
10
+ * The above copyright notice and this permission notice shall be included in all
11
+ * copies or substantial portions of the Software.
12
+ *
13
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ * SOFTWARE.
20
+ */
21
+
22
+/*
23
+ * This file contents defines for the position of all the fields of ACI
24
+ * command or event messages
25
+ */
26
+
27
+#ifndef ACI_OFFSET_H__
28
+#define ACI_OFFSET_H__
29
+
30
+
31
+    #define OFFSET_ACI_LL_CONN_PARAMS_T_MIN_CONN_INTERVAL_LSB 0
32
+    #define OFFSET_ACI_LL_CONN_PARAMS_T_MIN_CONN_INTERVAL_MSB 1
33
+    #define OFFSET_ACI_LL_CONN_PARAMS_T_MAX_CONN_INTERVAL_LSB 2
34
+    #define OFFSET_ACI_LL_CONN_PARAMS_T_MAX_CONN_INTERVAL_MSB 3
35
+    #define OFFSET_ACI_LL_CONN_PARAMS_T_SLAVE_LATENCY_LSB 4
36
+    #define OFFSET_ACI_LL_CONN_PARAMS_T_SLAVE_LATENCY_MSB 5
37
+    #define OFFSET_ACI_LL_CONN_PARAMS_T_TIMEOUT_MULT_LSB 6
38
+    #define OFFSET_ACI_LL_CONN_PARAMS_T_TIMEOUT_MULT_MSB 7
39
+    #define OFFSET_ACI_TX_DATA_T_PIPE_NUMBER 0
40
+    #define OFFSET_ACI_TX_DATA_T_ACI_DATA 1
41
+    #define OFFSET_ACI_RX_DATA_T_PIPE_NUMBER 0
42
+    #define OFFSET_ACI_RX_DATA_T_ACI_DATA 1
43
+    #define OFFSET_ACI_CMD_PARAMS_TEST_T_TEST_MODE_CHANGE 0
44
+    #define OFFSET_ACI_CMD_PARAMS_ECHO_T_ECHO_DATA 0
45
+    #define OFFSET_ACI_CMD_PARAMS_DTM_CMD_T_CMD_MSB 0
46
+    #define OFFSET_ACI_CMD_PARAMS_DTM_CMD_T_CMD_LSB 1
47
+    #define OFFSET_ACI_CMD_PARAMS_SETUP_T_SETUP_DATA 0
48
+    #define OFFSET_ACI_CMD_PARAMS_WRITE_DYNAMIC_DATA_T_SEQ_NO 0
49
+    #define OFFSET_ACI_CMD_PARAMS_WRITE_DYNAMIC_DATA_T_DYNAMIC_DATA 1
50
+    #define OFFSET_ACI_CMD_PARAMS_SET_LOCAL_DATA_T_TX_DATA 0
51
+    #define OFFSET_ACI_CMD_PARAMS_CONNECT_T_TIMEOUT_LSB 0
52
+    #define OFFSET_ACI_CMD_PARAMS_CONNECT_T_TIMEOUT_MSB 1
53
+    #define OFFSET_ACI_CMD_PARAMS_CONNECT_T_ADV_INTERVAL_LSB 2
54
+    #define OFFSET_ACI_CMD_PARAMS_CONNECT_T_ADV_INTERVAL_MSB 3
55
+    #define OFFSET_ACI_CMD_PARAMS_BOND_T_TIMEOUT_LSB 0
56
+    #define OFFSET_ACI_CMD_PARAMS_BOND_T_TIMEOUT_MSB 1
57
+    #define OFFSET_ACI_CMD_PARAMS_BOND_T_ADV_INTERVAL_LSB 2
58
+    #define OFFSET_ACI_CMD_PARAMS_BOND_T_ADV_INTERVAL_MSB 3
59
+    #define OFFSET_ACI_CMD_PARAMS_DISCONNECT_T_REASON 0
60
+    #define OFFSET_ACI_CMD_PARAMS_SET_TX_POWER_T_DEVICE_POWER 0
61
+    #define OFFSET_ACI_CMD_PARAMS_CHANGE_TIMING_T_CONN_PARAMS 0
62
+    #define OFFSET_ACI_CMD_PARAMS_OPEN_REMOTE_PIPE_T_PIPE_NUMBER 0
63
+    #define OFFSET_ACI_CMD_PARAMS_SEND_DATA_T_TX_DATA 0
64
+    #define OFFSET_ACI_CMD_PARAMS_SEND_DATA_ACK_T_PIPE_NUMBER 0
65
+    #define OFFSET_ACI_CMD_PARAMS_REQUEST_DATA_T_PIPE_NUMBER 0
66
+    #define OFFSET_ACI_CMD_PARAMS_SEND_DATA_NACK_T_PIPE_NUMBER 0
67
+    #define OFFSET_ACI_CMD_PARAMS_SEND_DATA_NACK_T_ERROR_CODE 1
68
+    #define OFFSET_ACI_CMD_PARAMS_SET_APP_LATENCY_T_MODE 0
69
+    #define OFFSET_ACI_CMD_PARAMS_SET_APP_LATENCY_T_LATENCY_LSB 1
70
+    #define OFFSET_ACI_CMD_PARAMS_SET_APP_LATENCY_T_LATENCY_MSB 2
71
+    #define OFFSET_ACI_CMD_PARAMS_SET_KEY_T_KEY_TYPE 0
72
+    #define OFFSET_ACI_CMD_PARAMS_SET_KEY_T_PASSKEY 1
73
+    #define OFFSET_ACI_CMD_PARAMS_SET_KEY_T_OOB_KEY 1
74
+    #define OFFSET_ACI_CMD_PARAMS_OPEN_ADV_PIPE_T_PIPES 0
75
+    #define OFFSET_ACI_CMD_PARAMS_BROADCAST_T_TIMEOUT_LSB 0
76
+    #define OFFSET_ACI_CMD_PARAMS_BROADCAST_T_TIMEOUT_MSB 1
77
+    #define OFFSET_ACI_CMD_PARAMS_BROADCAST_T_ADV_INTERVAL_LSB 2
78
+    #define OFFSET_ACI_CMD_PARAMS_BROADCAST_T_ADV_INTERVAL_MSB 3
79
+    #define OFFSET_ACI_CMD_PARAMS_CLOSE_REMOTE_PIPE_T_PIPE_NUMBER 0
80
+    #define OFFSET_ACI_CMD_T_LEN 0
81
+    #define OFFSET_ACI_CMD_T_CMD_OPCODE 1
82
+    #define OFFSET_ACI_CMD_T_TEST 2
83
+    #define OFFSET_ACI_CMD_T_ECHO 2
84
+    #define OFFSET_ACI_CMD_T_DTM_CMD 2
85
+    #define OFFSET_ACI_CMD_T_SETUP 2
86
+    #define OFFSET_ACI_CMD_T_WRITE_DYNAMIC_DATA 2
87
+    #define OFFSET_ACI_CMD_T_SET_LOCAL_DATA 2
88
+    #define OFFSET_ACI_CMD_T_CONNECT 2
89
+    #define OFFSET_ACI_CMD_T_BOND 2
90
+    #define OFFSET_ACI_CMD_T_DISCONNECT 2
91
+    #define OFFSET_ACI_CMD_T_SET_TX_POWER 2
92
+    #define OFFSET_ACI_CMD_T_CHANGE_TIMING 2
93
+    #define OFFSET_ACI_CMD_T_OPEN_REMOTE_PIPE 2
94
+    #define OFFSET_ACI_CMD_T_SEND_DATA 2
95
+    #define OFFSET_ACI_CMD_T_SEND_DATA_ACK 2
96
+    #define OFFSET_ACI_CMD_T_REQUEST_DATA 2
97
+    #define OFFSET_ACI_CMD_T_SEND_DATA_NACK 2
98
+    #define OFFSET_ACI_CMD_T_SET_APP_LATENCY 2
99
+    #define OFFSET_ACI_CMD_T_SET_KEY 2
100
+    #define OFFSET_ACI_CMD_T_OPEN_ADV_PIPE 2
101
+    #define OFFSET_ACI_CMD_T_BROADCAST 2
102
+    #define OFFSET_ACI_CMD_T_CLOSE_REMOTE_PIPE 2
103
+    #define OFFSET_ACI_EVT_PARAMS_DEVICE_STARTED_T_DEVICE_MODE 0
104
+    #define OFFSET_ACI_EVT_PARAMS_DEVICE_STARTED_T_HW_ERROR 1
105
+    #define OFFSET_ACI_EVT_PARAMS_DEVICE_STARTED_T_CREDIT_AVAILABLE 2
106
+    #define OFFSET_ACI_EVT_PARAMS_HW_ERROR_T_LINE_NUM_LSB 0
107
+    #define OFFSET_ACI_EVT_PARAMS_HW_ERROR_T_LINE_NUM_MSB 1
108
+    #define OFFSET_ACI_EVT_PARAMS_HW_ERROR_T_FILE_NAME 2
109
+    #define OFFSET_ACI_EVT_CMD_RSP_PARAMS_DTM_CMD_T_EVT_MSB 0
110
+    #define OFFSET_ACI_EVT_CMD_RSP_PARAMS_DTM_CMD_T_EVT_LSB 1
111
+    #define OFFSET_ACI_EVT_CMD_RSP_READ_DYNAMIC_DATA_T_SEQ_NO 0
112
+    #define OFFSET_ACI_EVT_CMD_RSP_READ_DYNAMIC_DATA_T_DYNAMIC_DATA 1
113
+    #define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_CONFIGURATION_ID_LSB 0
114
+    #define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_CONFIGURATION_ID_MSB 1
115
+    #define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_ACI_VERSION 2
116
+    #define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_SETUP_FORMAT 3
117
+    #define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_SETUP_ID_LSB0 4
118
+    #define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_SETUP_ID_LSB1 5
119
+    #define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_SETUP_ID_MSB0 6
120
+    #define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_SETUP_ID_MSB1 7
121
+    #define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_VERSION_T_SETUP_STATUS 8
122
+    #define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_ADDRESS_T_BD_ADDR_OWN 0
123
+    #define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_DEVICE_ADDRESS_T_BD_ADDR_TYPE 6
124
+    #define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_BATTERY_LEVEL_T_BATTERY_LEVEL_LSB 0
125
+    #define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_BATTERY_LEVEL_T_BATTERY_LEVEL_MSB 1
126
+    #define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_TEMPERATURE_T_TEMPERATURE_VALUE_LSB 0
127
+    #define OFFSET_ACI_EVT_CMD_RSP_PARAMS_GET_TEMPERATURE_T_TEMPERATURE_VALUE_MSB 1
128
+    #define OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_CMD_OPCODE 0
129
+    #define OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_CMD_STATUS 1
130
+    #define OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_DTM_CMD 2
131
+    #define OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_READ_DYNAMIC_DATA 2
132
+    #define OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_DEVICE_VERSION 2
133
+    #define OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_DEVICE_ADDRESS 2
134
+    #define OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_BATTERY_LEVEL 2
135
+    #define OFFSET_ACI_EVT_PARAMS_CMD_RSP_T_GET_TEMPERATURE 2
136
+    #define OFFSET_ACI_EVT_PARAMS_CONNECTED_T_DEV_ADDR_TYPE 0
137
+    #define OFFSET_ACI_EVT_PARAMS_CONNECTED_T_DEV_ADDR 1
138
+    #define OFFSET_ACI_EVT_PARAMS_CONNECTED_T_CONN_RF_INTERVAL_LSB 7
139
+    #define OFFSET_ACI_EVT_PARAMS_CONNECTED_T_CONN_RF_INTERVAL_MSB 8
140
+    #define OFFSET_ACI_EVT_PARAMS_CONNECTED_T_CONN_SLAVE_RF_LATENCY_LSB 9
141
+    #define OFFSET_ACI_EVT_PARAMS_CONNECTED_T_CONN_SLAVE_RF_LATENCY_MSB 10
142
+    #define OFFSET_ACI_EVT_PARAMS_CONNECTED_T_CONN_RF_TIMEOUT_LSB 11
143
+    #define OFFSET_ACI_EVT_PARAMS_CONNECTED_T_CONN_RF_TIMEOUT_MSB 12
144
+    #define OFFSET_ACI_EVT_PARAMS_CONNECTED_T_MASTER_CLOCK_ACCURACY 13
145
+    #define OFFSET_ACI_EVT_PARAMS_DISCONNECTED_T_ACI_STATUS 0
146
+    #define OFFSET_ACI_EVT_PARAMS_DISCONNECTED_T_BTLE_STATUS 1
147
+    #define OFFSET_ACI_EVT_PARAMS_BOND_STATUS_T_STATUS_CODE 0
148
+    #define OFFSET_ACI_EVT_PARAMS_BOND_STATUS_T_STATUS_SOURCE 1
149
+    #define OFFSET_ACI_EVT_PARAMS_BOND_STATUS_T_SECMODE1_BITMAP 2
150
+    #define OFFSET_ACI_EVT_PARAMS_BOND_STATUS_T_SECMODE2_BITMAP 3
151
+    #define OFFSET_ACI_EVT_PARAMS_BOND_STATUS_T_KEYS_EXCHANGED_SLAVE 4
152
+    #define OFFSET_ACI_EVT_PARAMS_BOND_STATUS_T_KEYS_EXCHANGED_MASTER 5
153
+    #define OFFSET_ACI_EVT_PARAMS_PIPE_STATUS_T_PIPES_OPEN_BITMAP 0
154
+    #define OFFSET_ACI_EVT_PARAMS_PIPE_STATUS_T_PIPES_CLOSED_BITMAP 8
155
+    #define OFFSET_ACI_EVT_PARAMS_TIMING_T_CONN_RF_INTERVAL_LSB 0
156
+    #define OFFSET_ACI_EVT_PARAMS_TIMING_T_CONN_RF_INTERVAL_MSB 1
157
+    #define OFFSET_ACI_EVT_PARAMS_TIMING_T_CONN_SLAVE_RF_LATENCY_LSB 2
158
+    #define OFFSET_ACI_EVT_PARAMS_TIMING_T_CONN_SLAVE_RF_LATENCY_MSB 3
159
+    #define OFFSET_ACI_EVT_PARAMS_TIMING_T_CONN_RF_TIMEOUT_LSB 4
160
+    #define OFFSET_ACI_EVT_PARAMS_TIMING_T_CONN_RF_TIMEOUT_MSB 5
161
+    #define OFFSET_ACI_EVT_PARAMS_DATA_CREDIT_T_CREDIT 0
162
+    #define OFFSET_ACI_EVT_PARAMS_DATA_ACK_T_PIPE_NUMBER 0
163
+    #define OFFSET_ACI_EVT_PARAMS_DATA_RECEIVED_T_RX_DATA 0
164
+    #define OFFSET_ERROR_DATA_T_CONTENT 0
165
+    #define OFFSET_ACI_EVT_PARAMS_PIPE_ERROR_T_PIPE_NUMBER 0
166
+    #define OFFSET_ACI_EVT_PARAMS_PIPE_ERROR_T_ERROR_CODE 1
167
+    #define OFFSET_ACI_EVT_PARAMS_PIPE_ERROR_T_ERROR_DATA 2
168
+    #define OFFSET_ACI_EVT_PARAMS_DISPLAY_PASSKEY_T_PASSKEY 0
169
+    #define OFFSET_ACI_EVT_PARAMS_KEY_REQUEST_T_KEY_TYPE 0
170
+    #define OFFSET_ACI_EVT_T_LEN 0
171
+    #define OFFSET_ACI_EVT_T_EVT_OPCODE 1
172
+    #define OFFSET_ACI_EVT_T_DEVICE_STARTED 2
173
+    #define OFFSET_ACI_EVT_T_HW_ERROR 2
174
+    #define OFFSET_ACI_EVT_T_CMD_RSP 2
175
+    #define OFFSET_ACI_EVT_T_CONNECTED 2
176
+    #define OFFSET_ACI_EVT_T_DISCONNECTED 2
177
+    #define OFFSET_ACI_EVT_T_BOND_STATUS 2
178
+    #define OFFSET_ACI_EVT_T_PIPE_STATUS 2
179
+    #define OFFSET_ACI_EVT_T_TIMING 2
180
+    #define OFFSET_ACI_EVT_T_DATA_CREDIT 2
181
+    #define OFFSET_ACI_EVT_T_DATA_ACK 2
182
+    #define OFFSET_ACI_EVT_T_DATA_RECEIVED 2
183
+    #define OFFSET_ACI_EVT_T_PIPE_ERROR 2
184
+    #define OFFSET_ACI_EVT_T_DISPLAY_PASSKEY 2
185
+    #define OFFSET_ACI_EVT_T_KEY_REQUEST 2
186
+
187
+#endif //ACI_OFFSET_H__
188
+

+ 201
- 0
src/nrf8001/aci_queue.cpp 查看文件

@@ -0,0 +1,201 @@
1
+/* Copyright (c) 2014, Nordic Semiconductor ASA
2
+ *
3
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ * of this software and associated documentation files (the "Software"), to deal
5
+ * in the Software without restriction, including without limitation the rights
6
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ * copies of the Software, and to permit persons to whom the Software is
8
+ * furnished to do so, subject to the following conditions:
9
+ *
10
+ * The above copyright notice and this permission notice shall be included in all
11
+ * copies or substantial portions of the Software.
12
+ *
13
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ * SOFTWARE.
20
+ */
21
+
22
+ /** @file
23
+@brief Implementation of a circular queue for ACI data
24
+*/
25
+
26
+#include "hal_aci_tl.h"
27
+#include "aci_queue.h"
28
+
29
+void aci_queue_init(aci_queue_t *aci_q)
30
+{
31
+  uint8_t loop;
32
+
33
+  // ble_assert(NULL != aci_q);
34
+
35
+  aci_q->head = 0;
36
+  aci_q->tail = 0;
37
+  for(loop=0; loop<ACI_QUEUE_SIZE; loop++)
38
+  {
39
+    aci_q->aci_data[loop].buffer[0] = 0x00;
40
+    aci_q->aci_data[loop].buffer[1] = 0x00;
41
+  }
42
+}
43
+
44
+bool aci_queue_dequeue(aci_queue_t *aci_q, hal_aci_data_t *p_data)
45
+{
46
+  // ble_assert(NULL != aci_q);
47
+  // ble_assert(NULL != p_data);
48
+
49
+  if (aci_queue_is_empty(aci_q))
50
+  {
51
+    return false;
52
+  }
53
+
54
+  memcpy((uint8_t *)p_data, (uint8_t *)&(aci_q->aci_data[aci_q->head]), sizeof(hal_aci_data_t));
55
+  aci_q->head = (aci_q->head + 1) % ACI_QUEUE_SIZE;
56
+
57
+  return true;
58
+}
59
+
60
+bool aci_queue_dequeue_from_isr(aci_queue_t *aci_q, hal_aci_data_t *p_data)
61
+{
62
+  // ble_assert(NULL != aci_q);
63
+  // ble_assert(NULL != p_data);
64
+
65
+  if (aci_queue_is_empty_from_isr(aci_q))
66
+  {
67
+    return false;
68
+  }
69
+
70
+  memcpy((uint8_t *)p_data, (uint8_t *)&(aci_q->aci_data[aci_q->head]), sizeof(hal_aci_data_t));
71
+  aci_q->head = (aci_q->head + 1) % ACI_QUEUE_SIZE;
72
+
73
+  return true;
74
+}
75
+
76
+bool aci_queue_enqueue(aci_queue_t *aci_q, hal_aci_data_t *p_data)
77
+{
78
+  const uint8_t length = p_data->buffer[0];
79
+
80
+  // ble_assert(NULL != aci_q);
81
+  // ble_assert(NULL != p_data);
82
+
83
+  if (aci_queue_is_full(aci_q))
84
+  {
85
+    return false;
86
+  }
87
+
88
+  aci_q->aci_data[aci_q->tail].status_byte = 0;
89
+  memcpy((uint8_t *)&(aci_q->aci_data[aci_q->tail].buffer[0]), (uint8_t *)&p_data->buffer[0], length + 1);
90
+  aci_q->tail = (aci_q->tail + 1) % ACI_QUEUE_SIZE;
91
+
92
+  return true;
93
+}
94
+
95
+bool aci_queue_enqueue_from_isr(aci_queue_t *aci_q, hal_aci_data_t *p_data)
96
+{
97
+  const uint8_t length = p_data->buffer[0];
98
+
99
+  // ble_assert(NULL != aci_q);
100
+  // ble_assert(NULL != p_data);
101
+
102
+  if (aci_queue_is_full_from_isr(aci_q))
103
+  {
104
+    return false;
105
+  }
106
+
107
+  aci_q->aci_data[aci_q->tail].status_byte = 0;
108
+  memcpy((uint8_t *)&(aci_q->aci_data[aci_q->tail].buffer[0]), (uint8_t *)&p_data->buffer[0], length + 1);
109
+  aci_q->tail = (aci_q->tail + 1) % ACI_QUEUE_SIZE;
110
+
111
+  return true;
112
+}
113
+
114
+bool aci_queue_is_empty(aci_queue_t *aci_q)
115
+{
116
+  bool state = false;
117
+
118
+  // ble_assert(NULL != aci_q);
119
+
120
+  //Critical section
121
+  // noInterrupts();
122
+  if (aci_q->head == aci_q->tail)
123
+  {
124
+    state = true;
125
+  }
126
+  // interrupts();
127
+
128
+  return state;
129
+}
130
+
131
+bool aci_queue_is_empty_from_isr(aci_queue_t *aci_q)
132
+{
133
+  // ble_assert(NULL != aci_q);
134
+
135
+  return aci_q->head == aci_q->tail;
136
+}
137
+
138
+bool aci_queue_is_full(aci_queue_t *aci_q)
139
+{
140
+  uint8_t next;
141
+  bool state;
142
+
143
+  // ble_assert(NULL != aci_q);
144
+
145
+  //This should be done in a critical section
146
+  // noInterrupts();
147
+  next = (aci_q->tail + 1) % ACI_QUEUE_SIZE;
148
+
149
+  if (next == aci_q->head)
150
+  {
151
+    state = true;
152
+  }
153
+  else
154
+  {
155
+    state = false;
156
+  }
157
+
158
+  // interrupts();
159
+  //end
160
+
161
+  return state;
162
+}
163
+
164
+bool aci_queue_is_full_from_isr(aci_queue_t *aci_q)
165
+{
166
+  const uint8_t next = (aci_q->tail + 1) % ACI_QUEUE_SIZE;
167
+
168
+  // ble_assert(NULL != aci_q);
169
+
170
+  return next == aci_q->head;
171
+}
172
+
173
+bool aci_queue_peek(aci_queue_t *aci_q, hal_aci_data_t *p_data)
174
+{
175
+  // ble_assert(NULL != aci_q);
176
+  // ble_assert(NULL != p_data);
177
+
178
+  if (aci_queue_is_empty(aci_q))
179
+  {
180
+    return false;
181
+  }
182
+
183
+  memcpy((uint8_t *)p_data, (uint8_t *)&(aci_q->aci_data[aci_q->head]), sizeof(hal_aci_data_t));
184
+
185
+  return true;
186
+}
187
+
188
+bool aci_queue_peek_from_isr(aci_queue_t *aci_q, hal_aci_data_t *p_data)
189
+{
190
+  // ble_assert(NULL != aci_q);
191
+  // ble_assert(NULL != p_data);
192
+
193
+  if (aci_queue_is_empty_from_isr(aci_q))
194
+  {
195
+    return false;
196
+  }
197
+
198
+  memcpy((uint8_t *)p_data, (uint8_t *)&(aci_q->aci_data[aci_q->head]), sizeof(hal_aci_data_t));
199
+
200
+  return true;
201
+}

+ 76
- 0
src/nrf8001/aci_queue.h 查看文件

@@ -0,0 +1,76 @@
1
+/* Copyright (c) 2014, Nordic Semiconductor ASA
2
+ *
3
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ * of this software and associated documentation files (the "Software"), to deal
5
+ * in the Software without restriction, including without limitation the rights
6
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ * copies of the Software, and to permit persons to whom the Software is
8
+ * furnished to do so, subject to the following conditions:
9
+ *
10
+ * The above copyright notice and this permission notice shall be included in all
11
+ * copies or substantial portions of the Software.
12
+ *
13
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ * SOFTWARE.
20
+ */
21
+
22
+/** @file
23
+ * @brief Interface for buffer.
24
+ */
25
+
26
+/** @defgroup aci_queue aci_queue
27
+@{
28
+@ingroup aci_queue
29
+
30
+*/
31
+
32
+#ifndef ACI_QUEUE_H__
33
+#define ACI_QUEUE_H__
34
+
35
+#include "aci.h"
36
+#include "hal_aci_tl.h"
37
+
38
+/***********************************************************************    */
39
+/* The ACI_QUEUE_SIZE determines the memory usage of the system.            */
40
+/* Successfully tested to a ACI_QUEUE_SIZE of 4 (interrupt) and 4 (polling) */
41
+/***********************************************************************    */
42
+#define ACI_QUEUE_SIZE  4
43
+
44
+/** Data type for queue of data packets to send/receive from radio.
45
+ *
46
+ *  A FIFO queue is maintained for packets. New packets are added (enqueued)
47
+ *  at the tail and taken (dequeued) from the head. The head variable is the
48
+ *  index of the next packet to dequeue while the tail variable is the index of
49
+ *  where the next packet should be queued.
50
+ */
51
+
52
+typedef struct {
53
+    hal_aci_data_t           aci_data[ACI_QUEUE_SIZE];
54
+    uint8_t                  head;
55
+    uint8_t                  tail;
56
+} aci_queue_t;
57
+
58
+void aci_queue_init(aci_queue_t *aci_q);
59
+
60
+bool aci_queue_dequeue(aci_queue_t *aci_q, hal_aci_data_t *p_data);
61
+bool aci_queue_dequeue_from_isr(aci_queue_t *aci_q, hal_aci_data_t *p_data);
62
+
63
+bool aci_queue_enqueue(aci_queue_t *aci_q, hal_aci_data_t *p_data);
64
+bool aci_queue_enqueue_from_isr(aci_queue_t *aci_q, hal_aci_data_t *p_data);
65
+
66
+bool aci_queue_is_empty(aci_queue_t *aci_q);
67
+bool aci_queue_is_empty_from_isr(aci_queue_t *aci_q);
68
+
69
+bool aci_queue_is_full(aci_queue_t *aci_q);
70
+bool aci_queue_is_full_from_isr(aci_queue_t *aci_q);
71
+
72
+bool aci_queue_peek(aci_queue_t *aci_q, hal_aci_data_t *p_data);
73
+bool aci_queue_peek_from_isr(aci_queue_t *aci_q, hal_aci_data_t *p_data);
74
+
75
+#endif /* ACI_QUEUE_H__ */
76
+/** @} */

+ 177
- 0
src/nrf8001/aci_setup.cpp 查看文件

@@ -0,0 +1,177 @@
1
+/* Copyright (c) 2014, Nordic Semiconductor ASA
2
+ *
3
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ * of this software and associated documentation files (the "Software"), to deal
5
+ * in the Software without restriction, including without limitation the rights
6
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ * copies of the Software, and to permit persons to whom the Software is
8
+ * furnished to do so, subject to the following conditions:
9
+ *
10
+ * The above copyright notice and this permission notice shall be included in all
11
+ * copies or substantial portions of the Software.
12
+ *
13
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ * SOFTWARE.
20
+ */
21
+
22
+
23
+#include "aci.h"
24
+#include "hal_aci_tl.h"
25
+#include <lib_aci.h>
26
+#include "aci_setup.h"
27
+
28
+
29
+// aci_struct that will contain
30
+// total initial credits
31
+// current credit
32
+// current state of the aci (setup/standby/active/sleep)
33
+// open remote pipe pending
34
+// close remote pipe pending
35
+// Current pipe available bitmap
36
+// Current pipe closed bitmap
37
+// Current connection interval, slave latency and link supervision timeout
38
+// Current State of the the GATT client (Service Discovery status)
39
+
40
+
41
+// hal_aci_data_t msg_to_send;
42
+extern hal_aci_data_t msg_to_send;
43
+
44
+
45
+/**************************************************************************                */
46
+/* Utility function to fill the the ACI command queue                                      */
47
+/* aci_stat               Pointer to the ACI state                                         */
48
+/* num_cmd_offset(in/out) Offset in the Setup message array to start from                  */
49
+/*                        offset is updated to the new index after the queue is filled     */
50
+/*                        or the last message us placed in the queue                       */
51
+/* Returns                true if at least one message was transferred                     */
52
+/***************************************************************************/
53
+bool aci_setup_fill(aci_state_t *aci_stat, uint8_t *num_cmd_offset)
54
+{
55
+  bool ret_val = false;
56
+
57
+  while (*num_cmd_offset < aci_stat->aci_setup_info.num_setup_msgs)
58
+  {
59
+    //Board dependent defines
60
+    /*#if defined (__AVR__)
61
+        //For Arduino copy the setup ACI message from Flash to RAM.
62
+        memcpy_P(&msg_to_send, &(aci_stat->aci_setup_info.setup_msgs[*num_cmd_offset]),
63
+                  pgm_read_byte_near(&(aci_stat->aci_setup_info.setup_msgs[*num_cmd_offset].buffer[0]))+2);
64
+    #elif defined(__PIC32MX__)
65
+        //In ChipKit we store the setup messages in RAM
66
+        //Add 2 bytes to the length byte for status byte, length for the total number of bytes
67
+        memcpy(&msg_to_send, &(aci_stat->aci_setup_info.setup_msgs[*num_cmd_offset]),
68
+                  (aci_stat->aci_setup_info.setup_msgs[*num_cmd_offset].buffer[0]+2));
69
+    #endif*/
70
+
71
+    memcpy(&msg_to_send, &(aci_stat->aci_setup_info.setup_msgs[*num_cmd_offset]),
72
+                  (aci_stat->aci_setup_info.setup_msgs[*num_cmd_offset].buffer[0]+2));
73
+
74
+    //Put the Setup ACI message in the command queue
75
+    if (!hal_aci_tl_send(&msg_to_send))
76
+    {
77
+      //ACI Command Queue is full
78
+      // *num_cmd_offset is now pointing to the index of the Setup command that did not get sent
79
+      return ret_val;
80
+   }
81
+
82
+    ret_val = true;
83
+
84
+    (*num_cmd_offset)++;
85
+  }
86
+
87
+  return ret_val;
88
+}
89
+
90
+uint8_t do_aci_setup(aci_state_t *aci_stat)
91
+{
92
+  uint8_t setup_offset         = 0;
93
+  uint32_t i                   = 0x0000;
94
+  aci_evt_t * aci_evt          = NULL;
95
+  aci_status_code_t cmd_status = ACI_STATUS_ERROR_CRC_MISMATCH;
96
+
97
+  /*
98
+  We are using the same buffer since we are copying the contents of the buffer
99
+  when queuing and immediately processing the buffer when receiving
100
+  */
101
+  hal_aci_evt_t  *aci_data = (hal_aci_evt_t *)&msg_to_send;
102
+
103
+  /* Messages in the outgoing queue must be handled before the Setup routine can run.
104
+   * If it is non-empty we return. The user should then process the messages before calling
105
+   * do_aci_setup() again.
106
+   */
107
+  if (!lib_aci_command_queue_empty())
108
+  {
109
+    return SETUP_FAIL_COMMAND_QUEUE_NOT_EMPTY;
110
+  }
111
+
112
+  /* If there are events pending from the device that are not relevant to setup, we return false
113
+   * so that the user can handle them. At this point we don't care what the event is,
114
+   * as any event is an error.
115
+   */
116
+  if (lib_aci_event_peek(aci_data))
117
+  {
118
+    return SETUP_FAIL_EVENT_QUEUE_NOT_EMPTY;
119
+  }
120
+
121
+  /* Fill the ACI command queue with as many Setup messages as it will hold. */
122
+  aci_setup_fill(aci_stat, &setup_offset);
123
+
124
+  while (cmd_status != ACI_STATUS_TRANSACTION_COMPLETE)
125
+  {
126
+    /* This counter is used to ensure that this function does not loop forever. When the device
127
+     * returns a valid response, we reset the counter.
128
+     */
129
+    if (i++ > 0xFFFFE)
130
+    {
131
+      return SETUP_FAIL_TIMEOUT;
132
+    }
133
+
134
+    if (lib_aci_event_peek(aci_data))
135
+    {
136
+      aci_evt = &(aci_data->evt);
137
+
138
+      if (ACI_EVT_CMD_RSP != aci_evt->evt_opcode)
139
+      {
140
+        //Receiving something other than a Command Response Event is an error.
141
+        return SETUP_FAIL_NOT_COMMAND_RESPONSE;
142
+      }
143
+
144
+      cmd_status = (aci_status_code_t) aci_evt->params.cmd_rsp.cmd_status;
145
+      switch (cmd_status)
146
+      {
147
+        case ACI_STATUS_TRANSACTION_CONTINUE:
148
+          //As the device is responding, reset guard counter
149
+          i = 0;
150
+
151
+          /* As the device has processed the Setup messages we put in the command queue earlier,
152
+           * we can proceed to fill the queue with new messages
153
+           */
154
+          aci_setup_fill(aci_stat, &setup_offset);
155
+          break;
156
+
157
+        case ACI_STATUS_TRANSACTION_COMPLETE:
158
+          //Break out of the while loop when this status code appears
159
+          break;
160
+
161
+        default:
162
+          //An event with any other status code should be handled by the application
163
+          return SETUP_FAIL_NOT_SETUP_EVENT;
164
+      }
165
+
166
+      /* If we haven't returned at this point, the event was either ACI_STATUS_TRANSACTION_CONTINUE
167
+       * or ACI_STATUS_TRANSACTION_COMPLETE. We don't need the event itself, so we simply
168
+       * remove it from the queue.
169
+       */
170
+       lib_aci_event_get (aci_stat, aci_data);
171
+    }
172
+  }
173
+
174
+  return SETUP_SUCCESS;
175
+}
176
+
177
+

+ 45
- 0
src/nrf8001/aci_setup.h 查看文件

@@ -0,0 +1,45 @@
1
+/* Copyright (c) 2014, Nordic Semiconductor ASA
2
+ *
3
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ * of this software and associated documentation files (the "Software"), to deal
5
+ * in the Software without restriction, including without limitation the rights
6
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ * copies of the Software, and to permit persons to whom the Software is
8
+ * furnished to do so, subject to the following conditions:
9
+ *
10
+ * The above copyright notice and this permission notice shall be included in all
11
+ * copies or substantial portions of the Software.
12
+ *
13
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ * SOFTWARE.
20
+ */
21
+
22
+
23
+#ifndef H_ACI_SETUP
24
+#define H_ACI_SETUP
25
+
26
+#define SETUP_SUCCESS                        0
27
+#define SETUP_FAIL_COMMAND_QUEUE_NOT_EMPTY   1
28
+#define SETUP_FAIL_EVENT_QUEUE_NOT_EMPTY     2
29
+#define SETUP_FAIL_TIMEOUT                   3
30
+#define SETUP_FAIL_NOT_SETUP_EVENT           4
31
+#define SETUP_FAIL_NOT_COMMAND_RESPONSE      5
32
+
33
+bool aci_setup_fill(aci_state_t *aci_stat, uint8_t *num_cmd_offset);
34
+/** @brief Setup the nRF8001 device
35
+ *  @details
36
+ *  Performs ACI Setup by transmitting the setup messages generated by nRFgo Studio to the
37
+ *  nRF8001, and should be called when the nRF8001 starts or resets.
38
+ *  Once all messages are sent, the nRF8001 will send a Device Started Event.
39
+ *  The function requires that the Command queue is empty when it is invoked, and will fail
40
+ *  otherwise.
41
+ *  @returns An integer indicating the reason the function terminated
42
+ */
43
+uint8_t do_aci_setup(aci_state_t *aci_stat);
44
+
45
+#endif

+ 610
- 0
src/nrf8001/acilib.cpp 查看文件

@@ -0,0 +1,610 @@
1
+/* Copyright (c) 2014, Nordic Semiconductor ASA
2
+ *
3
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ * of this software and associated documentation files (the "Software"), to deal
5
+ * in the Software without restriction, including without limitation the rights
6
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ * copies of the Software, and to permit persons to whom the Software is
8
+ * furnished to do so, subject to the following conditions:
9
+ *
10
+ * The above copyright notice and this permission notice shall be included in all
11
+ * copies or substantial portions of the Software.
12
+ *
13
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ * SOFTWARE.
20
+ */
21
+
22
+/**
23
+ * @file
24
+ *
25
+ * @ingroup group_acilib
26
+ *
27
+ * @brief Implementation of the acilib module.
28
+ */
29
+
30
+
31
+#include "hal_platform.h"
32
+#include "aci.h"
33
+#include "aci_cmds.h"
34
+#include "aci_evts.h"
35
+#include "acilib.h"
36
+#include "aci_protocol_defines.h"
37
+#include "acilib_defs.h"
38
+#include "acilib_if.h"
39
+#include "acilib_types.h"
40
+
41
+
42
+void acil_encode_cmd_set_test_mode(uint8_t *buffer, aci_cmd_params_test_t *p_aci_cmd_params_test)
43
+{
44
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = 2;
45
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_TEST;
46
+  *(buffer + OFFSET_ACI_CMD_T_TEST + OFFSET_ACI_CMD_PARAMS_TEST_T_TEST_MODE_CHANGE) = p_aci_cmd_params_test->test_mode_change;
47
+}
48
+
49
+void acil_encode_cmd_sleep(uint8_t *buffer)
50
+{
51
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = 1;
52
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_SLEEP;
53
+}
54
+
55
+void acil_encode_cmd_get_device_version(uint8_t *buffer)
56
+{
57
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = 1;
58
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_GET_DEVICE_VERSION;
59
+}
60
+
61
+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)
62
+{
63
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_SET_LOCAL_DATA_BASE_LEN + data_size;
64
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_SET_LOCAL_DATA;
65
+  *(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;
66
+  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);
67
+}
68
+
69
+void acil_encode_cmd_connect(uint8_t *buffer, aci_cmd_params_connect_t *p_aci_cmd_params_connect)
70
+{
71
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_CONNECT_LEN;
72
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_CONNECT;
73
+  *(buffer + OFFSET_ACI_CMD_T_CONNECT + OFFSET_ACI_CMD_PARAMS_CONNECT_T_TIMEOUT_MSB) = (uint8_t)(p_aci_cmd_params_connect->timeout >> 8);
74
+  *(buffer + OFFSET_ACI_CMD_T_CONNECT + OFFSET_ACI_CMD_PARAMS_CONNECT_T_TIMEOUT_LSB) = (uint8_t)(p_aci_cmd_params_connect->timeout);
75
+  *(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);
76
+  *(buffer + OFFSET_ACI_CMD_T_CONNECT + OFFSET_ACI_CMD_PARAMS_CONNECT_T_ADV_INTERVAL_LSB) = (uint8_t)(p_aci_cmd_params_connect->adv_interval);
77
+}
78
+
79
+void acil_encode_cmd_bond(uint8_t *buffer, aci_cmd_params_bond_t *p_aci_cmd_params_bond)
80
+{
81
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_BOND_LEN;
82
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_BOND;
83
+  *(buffer + OFFSET_ACI_CMD_T_BOND + OFFSET_ACI_CMD_PARAMS_BOND_T_TIMEOUT_MSB) = (uint8_t)(p_aci_cmd_params_bond->timeout >> 8);
84
+  *(buffer + OFFSET_ACI_CMD_T_BOND + OFFSET_ACI_CMD_PARAMS_BOND_T_TIMEOUT_LSB) = (uint8_t)(p_aci_cmd_params_bond->timeout);
85
+  *(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);
86
+  *(buffer + OFFSET_ACI_CMD_T_BOND + OFFSET_ACI_CMD_PARAMS_BOND_T_ADV_INTERVAL_LSB) = (uint8_t)(p_aci_cmd_params_bond->adv_interval);
87
+}
88
+
89
+void acil_encode_cmd_disconnect(uint8_t *buffer, aci_cmd_params_disconnect_t *p_aci_cmd_params_disconnect)
90
+{
91
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_DISCONNECT_LEN;
92
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_DISCONNECT;
93
+  *(buffer + OFFSET_ACI_CMD_T_DISCONNECT + OFFSET_ACI_CMD_PARAMS_DISCONNECT_T_REASON) = (uint8_t)(p_aci_cmd_params_disconnect->reason);
94
+}
95
+
96
+void acil_encode_baseband_reset(uint8_t *buffer)
97
+{
98
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_BASEBAND_RESET_LEN;
99
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_RADIO_RESET;
100
+}
101
+
102
+void acil_encode_direct_connect(uint8_t *buffer)
103
+{
104
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_DIRECT_CONNECT_LEN;
105
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_CONNECT_DIRECT;
106
+}
107
+
108
+void acil_encode_cmd_wakeup(uint8_t *buffer)
109
+{
110
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_WAKEUP_LEN;
111
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_WAKEUP;
112
+}
113
+
114
+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)
115
+{
116
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_SET_RADIO_TX_POWER_LEN;
117
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_SET_TX_POWER;
118
+  *(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;
119
+}
120
+
121
+void acil_encode_cmd_get_address(uint8_t *buffer)
122
+{
123
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_GET_DEVICE_ADDR_LEN;
124
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_GET_DEVICE_ADDRESS;
125
+}
126
+
127
+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)
128
+{
129
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_SEND_DATA_BASE_LEN + data_size;
130
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_SEND_DATA;
131
+  *(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;
132
+  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);
133
+}
134
+
135
+void acil_encode_cmd_request_data(uint8_t *buffer, aci_cmd_params_request_data_t *p_aci_cmd_params_request_data)
136
+{
137
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_DATA_REQUEST_LEN;
138
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_REQUEST_DATA;
139
+  *(buffer + OFFSET_ACI_CMD_T_REQUEST_DATA + OFFSET_ACI_CMD_PARAMS_REQUEST_DATA_T_PIPE_NUMBER) = p_aci_cmd_params_request_data->pipe_number;
140
+}
141
+
142
+void acil_encode_cmd_open_remote_pipe(uint8_t *buffer, aci_cmd_params_open_remote_pipe_t *p_aci_cmd_params_open_remote_pipe)
143
+{
144
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_OPEN_REMOTE_PIPE_LEN;
145
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_OPEN_REMOTE_PIPE;
146
+  *(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;
147
+}
148
+
149
+void acil_encode_cmd_close_remote_pipe(uint8_t *buffer, aci_cmd_params_close_remote_pipe_t *p_aci_cmd_params_close_remote_pipe)
150
+{
151
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_CLOSE_REMOTE_PIPE_LEN;
152
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_CLOSE_REMOTE_PIPE;
153
+  *(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;
154
+}
155
+
156
+void acil_encode_cmd_echo_msg(uint8_t *buffer, aci_cmd_params_echo_t *p_cmd_params_echo, uint8_t msg_size)
157
+{
158
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_ECHO_MSG_CMD_BASE_LEN + msg_size;
159
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_ECHO;
160
+  memcpy((buffer + OFFSET_ACI_CMD_T_ECHO + OFFSET_ACI_CMD_PARAMS_ECHO_T_ECHO_DATA), &(p_cmd_params_echo->echo_data[0]), msg_size);
161
+}
162
+
163
+void acil_encode_cmd_battery_level(uint8_t *buffer)
164
+{
165
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = 1;
166
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_GET_BATTERY_LEVEL;
167
+}
168
+
169
+void acil_encode_cmd_temparature(uint8_t *buffer)
170
+{
171
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = 1;
172
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_GET_TEMPERATURE;
173
+}
174
+
175
+void acil_encode_cmd_read_dynamic_data(uint8_t *buffer)
176
+{
177
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = 1;
178
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_READ_DYNAMIC_DATA;
179
+}
180
+
181
+void acil_encode_cmd_write_dynamic_data(uint8_t *buffer, uint8_t seq_no, uint8_t* dynamic_data, uint8_t dynamic_data_size)
182
+{
183
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_WRITE_DYNAMIC_DATA_BASE_LEN + dynamic_data_size;
184
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_WRITE_DYNAMIC_DATA;
185
+  *(buffer + OFFSET_ACI_CMD_T_WRITE_DYNAMIC_DATA + OFFSET_ACI_CMD_PARAMS_WRITE_DYNAMIC_DATA_T_SEQ_NO) = seq_no;
186
+  memcpy((buffer + OFFSET_ACI_CMD_T_WRITE_DYNAMIC_DATA + OFFSET_ACI_CMD_PARAMS_WRITE_DYNAMIC_DATA_T_DYNAMIC_DATA), dynamic_data, dynamic_data_size);
187
+}
188
+
189
+void acil_encode_cmd_change_timing_req(uint8_t *buffer, aci_cmd_params_change_timing_t *p_aci_cmd_params_change_timing)
190
+{
191
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_CHANGE_TIMING_LEN;
192
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_CHANGE_TIMING;
193
+  *(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);
194
+  *(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);
195
+  *(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);
196
+  *(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);
197
+  *(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);
198
+  *(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);
199
+  *(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);
200
+  *(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);
201
+}
202
+
203
+void acil_encode_cmd_set_app_latency(uint8_t *buffer, aci_cmd_params_set_app_latency_t *p_aci_cmd_params_set_app_latency)
204
+{
205
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_SET_APP_LATENCY_LEN;
206
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_SET_APP_LATENCY;
207
+  *(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);
208
+  *(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);
209
+  *(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);
210
+}
211
+
212
+void acil_encode_cmd_change_timing_req_GAP_PPCP(uint8_t *buffer)
213
+{
214
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_CHANGE_TIMING_LEN_GAP_PPCP;
215
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_CHANGE_TIMING;
216
+}
217
+
218
+
219
+void acil_encode_cmd_setup(uint8_t *buffer, aci_cmd_params_setup_t *p_aci_cmd_params_setup, uint8_t setup_data_size)
220
+{
221
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = setup_data_size + MSG_SETUP_CMD_BASE_LEN;
222
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_SETUP;
223
+  memcpy((buffer + OFFSET_ACI_CMD_T_SETUP), &(p_aci_cmd_params_setup->setup_data[0]), setup_data_size);
224
+}
225
+
226
+void acil_encode_cmd_dtm_cmd(uint8_t *buffer, aci_cmd_params_dtm_cmd_t *p_aci_cmd_params_dtm_cmd)
227
+{
228
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_DTM_CMD;
229
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_DTM_CMD;
230
+  *(buffer + OFFSET_ACI_CMD_T_DTM_CMD) = p_aci_cmd_params_dtm_cmd->cmd_msb;
231
+  *(buffer + OFFSET_ACI_CMD_T_DTM_CMD + 1) = p_aci_cmd_params_dtm_cmd->cmd_lsb;
232
+}
233
+
234
+void acil_encode_cmd_send_data_ack(uint8_t *buffer, const uint8_t pipe_number )
235
+{
236
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_ACK_LEN;
237
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_SEND_DATA_ACK;
238
+  *(buffer + OFFSET_ACI_CMD_T_SEND_DATA_ACK + OFFSET_ACI_CMD_PARAMS_SEND_DATA_ACK_T_PIPE_NUMBER) = pipe_number;
239
+}
240
+
241
+void acil_encode_cmd_send_data_nack(uint8_t *buffer, const uint8_t pipe_number, const uint8_t err_code )
242
+{
243
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_NACK_LEN;
244
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_SEND_DATA_NACK;
245
+  *(buffer + OFFSET_ACI_CMD_T_SEND_DATA_NACK + OFFSET_ACI_CMD_PARAMS_SEND_DATA_NACK_T_PIPE_NUMBER) = pipe_number;
246
+  *(buffer + OFFSET_ACI_CMD_T_SEND_DATA_NACK + OFFSET_ACI_CMD_PARAMS_SEND_DATA_NACK_T_ERROR_CODE) = err_code;
247
+}
248
+
249
+void acil_encode_cmd_bond_security_request(uint8_t *buffer)
250
+{
251
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = 1;
252
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_BOND_SECURITY_REQUEST;
253
+}
254
+
255
+void acil_encode_cmd_broadcast(uint8_t *buffer, aci_cmd_params_broadcast_t * p_aci_cmd_params_broadcast)
256
+{
257
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_BROADCAST_LEN;
258
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_BROADCAST;
259
+  *(buffer + OFFSET_ACI_CMD_T_BROADCAST + OFFSET_ACI_CMD_PARAMS_BROADCAST_T_TIMEOUT_LSB) = (p_aci_cmd_params_broadcast->timeout & 0xff);
260
+  *(buffer + OFFSET_ACI_CMD_T_BROADCAST + OFFSET_ACI_CMD_PARAMS_BROADCAST_T_TIMEOUT_MSB) = (uint8_t)(p_aci_cmd_params_broadcast->timeout >> 8);
261
+  *(buffer + OFFSET_ACI_CMD_T_BROADCAST + OFFSET_ACI_CMD_PARAMS_BROADCAST_T_ADV_INTERVAL_LSB) = (p_aci_cmd_params_broadcast->adv_interval & 0xff);
262
+  *(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);
263
+}
264
+
265
+void acil_encode_cmd_open_adv_pipes(uint8_t *buffer, aci_cmd_params_open_adv_pipe_t * p_aci_cmd_params_open_adv_pipe)
266
+{
267
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = MSG_OPEN_ADV_PIPES_LEN;
268
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_OPEN_ADV_PIPE;
269
+  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);
270
+}
271
+
272
+
273
+void acil_encode_cmd_set_key(uint8_t *buffer, aci_cmd_params_set_key_t *p_aci_cmd_params_set_key)
274
+{
275
+  /*
276
+  The length of the key is computed based on the type of key transaction.
277
+  - Key Reject
278
+  - Key type is passkey
279
+  */
280
+  uint8_t len;
281
+
282
+  switch (p_aci_cmd_params_set_key->key_type)
283
+  {
284
+    case ACI_KEY_TYPE_INVALID:
285
+    len = MSG_SET_KEY_REJECT_LEN;
286
+    break;
287
+    case ACI_KEY_TYPE_PASSKEY:
288
+    len = MSG_SET_KEY_PASSKEY_LEN;
289
+    break;
290
+    default:
291
+    len=0;
292
+    break;
293
+  }
294
+  *(buffer + OFFSET_ACI_CMD_T_LEN) = len;
295
+  *(buffer + OFFSET_ACI_CMD_T_CMD_OPCODE) = ACI_CMD_SET_KEY;
296
+  *(buffer + OFFSET_ACI_CMD_T_SET_KEY + OFFSET_ACI_CMD_PARAMS_SET_KEY_T_KEY_TYPE) = p_aci_cmd_params_set_key->key_type;
297
+  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
298
+}
299
+
300
+bool acil_encode_cmd(uint8_t *buffer, aci_cmd_t *p_aci_cmd)
301
+{
302
+  bool ret_val = false;
303
+
304
+  switch(p_aci_cmd->cmd_opcode)
305
+  {
306
+    case ACI_CMD_TEST:
307
+      acil_encode_cmd_set_test_mode(buffer, &(p_aci_cmd->params.test));
308
+      break;
309
+    case ACI_CMD_SLEEP:
310
+      acil_encode_cmd_sleep(buffer);
311
+      break;
312
+    case ACI_CMD_GET_DEVICE_VERSION:
313
+      acil_encode_cmd_get_device_version(buffer);
314
+      break;
315
+    case ACI_CMD_WAKEUP:
316
+      acil_encode_cmd_wakeup(buffer);
317
+      break;
318
+    case ACI_CMD_ECHO:
319
+      acil_encode_cmd_echo_msg(buffer, &(p_aci_cmd->params.echo), (p_aci_cmd->len - MSG_ECHO_MSG_CMD_BASE_LEN));
320
+      break;
321
+    case ACI_CMD_GET_BATTERY_LEVEL:
322
+      acil_encode_cmd_battery_level(buffer);
323
+      break;
324
+    case ACI_CMD_GET_TEMPERATURE:
325
+      acil_encode_cmd_temparature(buffer);
326
+      break;
327
+    case ACI_CMD_GET_DEVICE_ADDRESS:
328
+      acil_encode_cmd_get_address(buffer);
329
+      break;
330
+    case ACI_CMD_SET_TX_POWER:
331
+      acil_encode_cmd_set_radio_tx_power(buffer, &(p_aci_cmd->params.set_tx_power));
332
+      break;
333
+    case ACI_CMD_CONNECT:
334
+      acil_encode_cmd_connect(buffer, &(p_aci_cmd->params.connect));
335
+      break;
336
+    case ACI_CMD_BOND:
337
+      acil_encode_cmd_bond(buffer, &(p_aci_cmd->params.bond));
338
+      break;
339
+    case ACI_CMD_DISCONNECT:
340
+      acil_encode_cmd_disconnect(buffer, &(p_aci_cmd->params.disconnect));
341
+      break;
342
+    case ACI_CMD_RADIO_RESET:
343
+      acil_encode_baseband_reset(buffer);
344
+      break;
345
+    case ACI_CMD_CHANGE_TIMING:
346
+      acil_encode_cmd_change_timing_req(buffer, &(p_aci_cmd->params.change_timing));
347
+      break;
348
+    case ACI_CMD_SETUP:
349
+      acil_encode_cmd_setup(buffer, &(p_aci_cmd->params.setup), (p_aci_cmd->len - MSG_SETUP_CMD_BASE_LEN));
350
+      break;
351
+    case ACI_CMD_DTM_CMD:
352
+      acil_encode_cmd_dtm_cmd(buffer, &(p_aci_cmd->params.dtm_cmd));
353
+      break;
354
+    case ACI_CMD_READ_DYNAMIC_DATA:
355
+      acil_encode_cmd_read_dynamic_data(buffer);
356
+      break;
357
+    case ACI_CMD_WRITE_DYNAMIC_DATA:
358
+      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));
359
+      break;
360
+    case ACI_CMD_OPEN_REMOTE_PIPE:
361
+      acil_encode_cmd_open_remote_pipe(buffer, &(p_aci_cmd->params.open_remote_pipe));
362
+      break;
363
+    case ACI_CMD_SEND_DATA:
364
+      acil_encode_cmd_send_data(buffer, &(p_aci_cmd->params.send_data), (p_aci_cmd->len - MSG_SEND_DATA_BASE_LEN));
365
+      break;
366
+    case ACI_CMD_SEND_DATA_ACK:
367
+      acil_encode_cmd_send_data_ack(buffer, p_aci_cmd->params.send_data_ack.pipe_number );
368
+      break;
369
+    case ACI_CMD_REQUEST_DATA:
370
+      acil_encode_cmd_request_data(buffer, &(p_aci_cmd->params.request_data));
371
+      break;
372
+    case ACI_CMD_SET_LOCAL_DATA:
373
+      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));
374
+      break;
375
+    case ACI_CMD_BOND_SECURITY_REQUEST:
376
+      acil_encode_cmd_bond_security_request(buffer);
377
+      break;
378
+    default:
379
+      break;
380
+  }
381
+  return ret_val;
382
+}
383
+
384
+void acil_decode_evt_command_response(uint8_t *buffer_in, aci_evt_params_cmd_rsp_t *p_evt_params_cmd_rsp)
385
+{
386
+  aci_evt_cmd_rsp_params_get_device_version_t *p_device_version;
387
+  aci_evt_cmd_rsp_params_get_device_address_t *p_device_address;
388
+  aci_evt_cmd_rsp_params_get_temperature_t    *p_temperature;
389
+  aci_evt_cmd_rsp_params_get_battery_level_t  *p_batt_lvl;
390
+  aci_evt_cmd_rsp_read_dynamic_data_t         *p_read_dyn_data;
391
+  aci_evt_cmd_rsp_params_dtm_cmd_t            *p_dtm_evt;
392
+
393
+  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);
394
+  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);
395
+
396
+  switch (p_evt_params_cmd_rsp->cmd_opcode)
397
+  {
398
+    case ACI_CMD_GET_DEVICE_VERSION:
399
+      p_device_version = &(p_evt_params_cmd_rsp->params.get_device_version);
400
+      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);
401
+      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;
402
+      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);
403
+      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);
404
+      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);
405
+      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;
406
+      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;
407
+      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;
408
+      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);
409
+      break;
410
+
411
+    case ACI_CMD_GET_DEVICE_ADDRESS:
412
+      p_device_address = &(p_evt_params_cmd_rsp->params.get_device_address);
413
+      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);
414
+      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);
415
+      break;
416
+
417
+    case ACI_CMD_GET_TEMPERATURE:
418
+      p_temperature = &(p_evt_params_cmd_rsp->params.get_temperature);
419
+      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);
420
+      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;
421
+      break;
422
+
423
+    case ACI_CMD_GET_BATTERY_LEVEL:
424
+      p_batt_lvl = &(p_evt_params_cmd_rsp->params.get_battery_level);
425
+      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);
426
+      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;
427
+      break;
428
+
429
+    case ACI_CMD_READ_DYNAMIC_DATA:
430
+      p_read_dyn_data = &(p_evt_params_cmd_rsp->params.read_dynamic_data);
431
+      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);
432
+      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.
433
+      // 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
434
+      break;
435
+
436
+    case ACI_CMD_DTM_CMD:
437
+      p_dtm_evt = &(p_evt_params_cmd_rsp->params.dtm_cmd);
438
+      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);
439
+      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);
440
+      break;
441
+  }
442
+}
443
+
444
+void acil_decode_evt_device_started(uint8_t *buffer_in, aci_evt_params_device_started_t *p_evt_params_device_started)
445
+{
446
+  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);
447
+  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);
448
+  p_evt_params_device_started->credit_available = *(buffer_in + OFFSET_ACI_EVT_T_DEVICE_STARTED+OFFSET_ACI_EVT_PARAMS_DEVICE_STARTED_T_CREDIT_AVAILABLE);
449
+}
450
+
451
+void acil_decode_evt_pipe_status(uint8_t *buffer_in, aci_evt_params_pipe_status_t *p_aci_evt_params_pipe_status)
452
+{
453
+  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);
454
+  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);
455
+}
456
+
457
+void acil_decode_evt_disconnected(uint8_t *buffer_in, aci_evt_params_disconnected_t *p_aci_evt_params_disconnected)
458
+{
459
+  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);
460
+  p_aci_evt_params_disconnected->btle_status = *(buffer_in + OFFSET_ACI_EVT_T_DISCONNECTED + OFFSET_ACI_EVT_PARAMS_DISCONNECTED_T_BTLE_STATUS);
461
+}
462
+
463
+void acil_decode_evt_bond_status(uint8_t *buffer_in, aci_evt_params_bond_status_t *p_aci_evt_params_bond_status)
464
+{
465
+  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);
466
+  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);
467
+  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);
468
+  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);
469
+  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);
470
+  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);
471
+}
472
+
473
+uint8_t acil_decode_evt_data_received(uint8_t *buffer_in, aci_evt_params_data_received_t *p_evt_params_data_received)
474
+{
475
+  uint8_t size = *( buffer_in + OFFSET_ACI_EVT_T_LEN) - (OFFSET_ACI_EVT_T_DATA_RECEIVED + OFFSET_ACI_RX_DATA_T_ACI_DATA) + 1 ;
476
+  p_evt_params_data_received->rx_data.pipe_number = *(buffer_in + OFFSET_ACI_EVT_T_DATA_RECEIVED + OFFSET_ACI_RX_DATA_T_PIPE_NUMBER);
477
+  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);
478
+  return size;
479
+}
480
+
481
+void acil_decode_evt_data_ack(uint8_t *buffer_in, aci_evt_params_data_ack_t *p_evt_params_data_ack)
482
+{
483
+  p_evt_params_data_ack->pipe_number = *(buffer_in + OFFSET_ACI_EVT_T_DATA_ACK + OFFSET_ACI_EVT_PARAMS_DATA_ACK_T_PIPE_NUMBER);
484
+}
485
+
486
+uint8_t acil_decode_evt_hw_error(uint8_t *buffer_in, aci_evt_params_hw_error_t *p_aci_evt_params_hw_error)
487
+{
488
+  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;
489
+  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;
490
+  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);
491
+  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);
492
+  return size;
493
+}
494
+
495
+void acil_decode_evt_credit(uint8_t *buffer_in, aci_evt_params_data_credit_t *p_evt_params_data_credit)
496
+{
497
+  p_evt_params_data_credit->credit = *(buffer_in + OFFSET_ACI_EVT_T_DATA_CREDIT + OFFSET_ACI_EVT_PARAMS_DATA_CREDIT_T_CREDIT);
498
+}
499
+
500
+void acil_decode_evt_connected(uint8_t *buffer_in, aci_evt_params_connected_t *p_aci_evt_params_connected)
501
+{
502
+  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);
503
+  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);
504
+  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;
505
+  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);
506
+  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;
507
+  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);
508
+  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;
509
+  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);
510
+  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);
511
+
512
+}
513
+
514
+void acil_decode_evt_timing(uint8_t *buffer_in, aci_evt_params_timing_t *p_evt_params_timing)
515
+{
516
+  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;
517
+  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);
518
+  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;
519
+  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);
520
+  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;
521
+  p_evt_params_timing->conn_rf_timeout       |= *(buffer_in + OFFSET_ACI_EVT_T_TIMING + OFFSET_ACI_EVT_PARAMS_TIMING_T_CONN_RF_TIMEOUT_LSB);
522
+}
523
+
524
+void acil_decode_evt_pipe_error(uint8_t *buffer_in, aci_evt_params_pipe_error_t *p_evt_params_pipe_error)
525
+{
526
+  //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;
527
+  p_evt_params_pipe_error->pipe_number = *(buffer_in + OFFSET_ACI_EVT_T_PIPE_ERROR + OFFSET_ACI_EVT_PARAMS_PIPE_ERROR_T_PIPE_NUMBER);
528
+  p_evt_params_pipe_error->error_code = *(buffer_in + OFFSET_ACI_EVT_T_PIPE_ERROR + OFFSET_ACI_EVT_PARAMS_PIPE_ERROR_T_ERROR_CODE);
529
+  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);
530
+}
531
+
532
+void acil_decode_evt_key_request(uint8_t *buffer_in, aci_evt_params_key_request_t *p_evt_params_key_request)
533
+{
534
+  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);
535
+}
536
+
537
+uint8_t acil_decode_evt_echo(uint8_t *buffer_in, aci_evt_params_echo_t *aci_evt_params_echo)
538
+{
539
+  uint8_t size = *(buffer_in + OFFSET_ACI_EVT_T_LEN) - 1;
540
+  memcpy(&aci_evt_params_echo->echo_data[0], (buffer_in + OFFSET_ACI_EVT_T_EVT_OPCODE + 1), size);
541
+  return size;
542
+}
543
+
544
+void acil_decode_evt_display_passkey(uint8_t *buffer_in, aci_evt_params_display_passkey_t *p_aci_evt_params_display_passkey)
545
+{
546
+  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);
547
+  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);
548
+  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);
549
+  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);
550
+  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);
551
+  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);
552
+}
553
+
554
+bool acil_decode_evt(uint8_t *buffer_in, aci_evt_t *p_aci_evt)
555
+{
556
+  bool ret_val = true;
557
+
558
+  p_aci_evt->len = ACIL_DECODE_EVT_GET_LENGTH(buffer_in);
559
+  p_aci_evt->evt_opcode = (aci_evt_opcode_t)ACIL_DECODE_EVT_GET_OPCODE(buffer_in);
560
+
561
+  switch(p_aci_evt->evt_opcode)
562
+  {
563
+    case ACI_EVT_DEVICE_STARTED:
564
+      acil_decode_evt_device_started(buffer_in, &(p_aci_evt->params.device_started));
565
+      break;
566
+    case ACI_EVT_HW_ERROR:
567
+      acil_decode_evt_hw_error(buffer_in, &(p_aci_evt->params.hw_error));
568
+      break;
569
+    case ACI_EVT_CMD_RSP:
570
+      acil_decode_evt_command_response(buffer_in, &(p_aci_evt->params.cmd_rsp));
571
+      break;
572
+    case ACI_EVT_DATA_CREDIT:
573
+      acil_decode_evt_credit(buffer_in, &(p_aci_evt->params.data_credit));
574
+      break;
575
+    case ACI_EVT_CONNECTED:
576
+      acil_decode_evt_connected(buffer_in, &(p_aci_evt->params.connected));
577
+      break;
578
+    case ACI_EVT_PIPE_STATUS:
579
+      acil_decode_evt_pipe_status(buffer_in, &(p_aci_evt->params.pipe_status));
580
+      break;
581
+    case ACI_EVT_DISCONNECTED:
582
+      acil_decode_evt_disconnected(buffer_in, &(p_aci_evt->params.disconnected));
583
+      break;
584
+    case ACI_EVT_BOND_STATUS:
585
+      acil_decode_evt_bond_status(buffer_in, &(p_aci_evt->params.bond_status));
586
+      break;
587
+    case ACI_EVT_TIMING:
588
+      acil_decode_evt_timing(buffer_in, &(p_aci_evt->params.timing));
589
+      break;
590
+    case ACI_EVT_DATA_ACK:
591
+      acil_decode_evt_data_ack(buffer_in, &(p_aci_evt->params.data_ack));
592
+      break;
593
+    case ACI_EVT_DATA_RECEIVED:
594
+      acil_decode_evt_data_received(buffer_in, &(p_aci_evt->params.data_received));
595
+      break;
596
+    case ACI_EVT_PIPE_ERROR:
597
+      acil_decode_evt_pipe_error(buffer_in, &(p_aci_evt->params.pipe_error));
598
+      break;
599
+    case ACI_EVT_KEY_REQUEST:
600
+      acil_decode_evt_key_request(buffer_in, &(p_aci_evt->params.key_request));
601
+      break;
602
+    case ACI_EVT_DISPLAY_PASSKEY:
603
+      acil_decode_evt_display_passkey(buffer_in, &(p_aci_evt->params.display_passkey));
604
+      break;
605
+    default:
606
+      ret_val = false;
607
+      break;
608
+  }
609
+  return ret_val;
610
+}

+ 61
- 0
src/nrf8001/acilib.h 查看文件

@@ -0,0 +1,61 @@
1
+/* Copyright (c) 2014, Nordic Semiconductor ASA
2
+ *
3
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ * of this software and associated documentation files (the "Software"), to deal
5
+ * in the Software without restriction, including without limitation the rights
6
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ * copies of the Software, and to permit persons to whom the Software is
8
+ * furnished to do so, subject to the following conditions:
9
+ *
10
+ * The above copyright notice and this permission notice shall be included in all
11
+ * copies or substantial portions of the Software.
12
+ *
13
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ * SOFTWARE.
20
+ */
21
+
22
+/**
23
+ * @file
24
+ *
25
+ * @ingroup group_acilib
26
+ *
27
+ * @brief Internal prototype for acilib module.
28
+ */
29
+
30
+#ifndef _acilib_H_
31
+#define _acilib_H_
32
+
33
+#define MSG_SET_LOCAL_DATA_BASE_LEN              2
34
+#define MSG_CONNECT_LEN                          5
35
+#define MSG_BOND_LEN                             5
36
+#define MSG_DISCONNECT_LEN                       2
37
+#define MSG_BASEBAND_RESET_LEN                   1
38
+#define MSG_WAKEUP_LEN                           1
39
+#define MSG_SET_RADIO_TX_POWER_LEN               2
40
+#define MSG_GET_DEVICE_ADDR_LEN                  1
41
+#define MSG_SEND_DATA_BASE_LEN                   2
42
+#define MSG_DATA_REQUEST_LEN                     2
43
+#define MSG_OPEN_REMOTE_PIPE_LEN                 2
44
+#define MSG_CLOSE_REMOTE_PIPE_LEN                2
45
+#define MSG_DTM_CMD                              3
46
+#define MSG_WRITE_DYNAMIC_DATA_BASE_LEN          2
47
+#define MSG_SETUP_CMD_BASE_LEN                   1
48
+#define MSG_ECHO_MSG_CMD_BASE_LEN                1
49
+#define MSG_CHANGE_TIMING_LEN                    9
50
+#define MSG_SET_APP_LATENCY_LEN                  4
51
+#define MSG_CHANGE_TIMING_LEN_GAP_PPCP           1
52
+#define MSG_DIRECT_CONNECT_LEN                   1
53
+#define MSG_SET_KEY_REJECT_LEN                   2
54
+#define MSG_SET_KEY_PASSKEY_LEN                  8
55
+#define MSG_SET_KEY_OOB_LEN                      18
56
+#define MSG_ACK_LEN                              2
57
+#define MSG_NACK_LEN                             3
58
+#define MSG_BROADCAST_LEN                        5
59
+#define MSG_OPEN_ADV_PIPES_LEN                   9
60
+
61
+#endif /* _acilib_H_ */

+ 37
- 0
src/nrf8001/acilib_defs.h 查看文件

@@ -0,0 +1,37 @@
1
+/* Copyright (c) 2014, Nordic Semiconductor ASA
2
+ *
3
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ * of this software and associated documentation files (the "Software"), to deal
5
+ * in the Software without restriction, including without limitation the rights
6
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ * copies of the Software, and to permit persons to whom the Software is
8
+ * furnished to do so, subject to the following conditions:
9
+ *
10
+ * The above copyright notice and this permission notice shall be included in all
11
+ * copies or substantial portions of the Software.
12
+ *
13
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ * SOFTWARE.
20
+ */
21
+
22
+/**
23
+ * @file
24
+ *
25
+ * @ingroup group_acilib
26
+ *
27
+ * @brief Definitions for the acilib interfaces
28
+ */
29
+
30
+#ifndef _acilib_DEFS_H_
31
+#define _acilib_DEFS_H_
32
+
33
+#define ACIL_DECODE_EVT_GET_LENGTH(buffer_in) (*(buffer_in + OFFSET_ACI_EVT_T_LEN))
34
+
35
+#define ACIL_DECODE_EVT_GET_OPCODE(buffer_in) (*(buffer_in + OFFSET_ACI_EVT_T_EVT_OPCODE))
36
+
37
+#endif /* _acilib_DEFS_H_ */

+ 471
- 0
src/nrf8001/acilib_if.h 查看文件

@@ -0,0 +1,471 @@
1
+/* Copyright (c) 2014, Nordic Semiconductor ASA
2
+ *
3
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ * of this software and associated documentation files (the "Software"), to deal
5
+ * in the Software without restriction, including without limitation the rights
6
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ * copies of the Software, and to permit persons to whom the Software is
8
+ * furnished to do so, subject to the following conditions:
9
+ *
10
+ * The above copyright notice and this permission notice shall be included in all
11
+ * copies or substantial portions of the Software.
12
+ *
13
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ * SOFTWARE.
20
+ */
21
+
22
+/**
23
+ * @file
24
+ *
25
+ * @ingroup group_acilib
26
+ *
27
+ * @brief Prototypes for the acilib interfaces.
28
+ */
29
+
30
+#ifndef _acilib_IF_H_
31
+#define _acilib_IF_H_
32
+
33
+/** @brief Encode the ACI message for set test mode command
34
+ *
35
+ *  @param[in,out]  buffer      Pointer to ACI message buffer
36
+ *  @param[in]      test_mode   Pointer to the test mode in ::aci_cmd_params_test_t
37
+ *
38
+ *  @return         None
39
+ */
40
+void acil_encode_cmd_set_test_mode(uint8_t *buffer, aci_cmd_params_test_t *p_aci_cmd_params_test);
41
+
42
+/** @brief Encode the ACI message for sleep command
43
+ *
44
+ *  @param[in,out]  buffer      Pointer to ACI message buffer
45
+ *
46
+ *  @return         None
47
+ */
48
+void acil_encode_cmd_sleep(uint8_t *buffer);
49
+
50
+/** @brief Encode the ACI message for get device version
51
+ *
52
+ *  @param[in,out]  buffer      Pointer to ACI message buffer
53
+ *
54
+ *  @return         None
55
+ */
56
+void acil_encode_cmd_get_device_version(uint8_t *buffer);
57
+
58
+/** @brief Encode the ACI message for set local data
59
+ *
60
+ *  @param[in,out]  buffer                           Pointer to ACI message buffer
61
+ *  @param[in]      p_aci_cmd_params_set_local_data  Pointer to the local data parameters in ::aci_cmd_params_set_local_data_t
62
+ *  @param[in]      data_size                        Size of data message
63
+ *
64
+ *  @return         None
65
+ */
66
+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);
67
+
68
+/** @brief Encode the ACI message to connect
69
+ *
70
+ *  @param[in,out]  buffer                    Pointer to ACI message buffer
71
+ *  @param[in]      p_aci_cmd_params_connect  Pointer to the run parameters in ::aci_cmd_params_connect_t
72
+ *
73
+ *  @return         None
74
+ */
75
+void acil_encode_cmd_connect(uint8_t *buffer, aci_cmd_params_connect_t *p_aci_cmd_params_connect);
76
+
77
+/** @brief Encode the ACI message to bond
78
+ *
79
+ *  @param[in,out]  buffer                 Pointer to ACI message buffer
80
+ *  @param[in]      p_aci_cmd_params_bond  Pointer to the run parameters in ::aci_cmd_params_bond_t
81
+ *
82
+ *  @return         None
83
+ */
84
+void acil_encode_cmd_bond(uint8_t *buffer, aci_cmd_params_bond_t *p_aci_cmd_params_bond);
85
+
86
+/** @brief Encode the ACI message to disconnect
87
+ *
88
+ *  @param[in,out]  buffer                       Pointer to ACI message buffer
89
+ *  @param[in]      p_aci_cmd_params_disconnect  Pointer to the run parameters in ::aci_cmd_params_disconnect_t
90
+ *
91
+ *  @return         None
92
+ */
93
+void acil_encode_cmd_disconnect(uint8_t *buffer, aci_cmd_params_disconnect_t *p_aci_cmd_params_disconnect);
94
+
95
+/** @brief Encode the ACI message to baseband reset
96
+ *
97
+ *  @param[in,out]  buffer        Pointer to ACI message buffer
98
+ *
99
+ *  @return         None
100
+ */
101
+ void acil_encode_baseband_reset(uint8_t *buffer);
102
+
103
+ /** @brief Encode the ACI message for Directed Advertising
104
+ *
105
+ *  @param[in,out]  buffer        Pointer to ACI message buffer
106
+ *
107
+ *  @return         None
108
+ */
109
+ void acil_encode_direct_connect(uint8_t *buffer);
110
+
111
+/** @brief Encode the ACI message to wakeup
112
+ *
113
+ *  @param[in,out]  buffer        Pointer to ACI message buffer
114
+ *
115
+ *  @return         None
116
+ */
117
+void acil_encode_cmd_wakeup(uint8_t *buffer);
118
+
119
+/** @brief Encode the ACI message for set radio Tx power
120
+ *
121
+ *  @param[in,out]  buffer                         Pointer to ACI message buffer
122
+ *  @param[in]      p_aci_cmd_params_set_tx_power  Pointer to the set Tx power parameters in ::aci_cmd_params_set_tx_power_t
123
+ *
124
+ *  @return         None
125
+ */
126
+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);
127
+
128
+/** @brief Encode the ACI message for get device address
129
+ *
130
+ *  @param[in,out]  buffer            Pointer to ACI message buffer
131
+ *
132
+ *  @return         None
133
+ */
134
+void acil_encode_cmd_get_address(uint8_t *buffer);
135
+
136
+/** @brief Encode the ACI message for send data
137
+ *
138
+ *  @param[in,out]  buffer                        Pointer to ACI message buffer
139
+ *  @param[in]      p_aci_cmd_params_send_data_t  Pointer to the data parameters in ::aci_cmd_params_send_data_t
140
+ *  @param[in]      data_size                     Size of data message
141
+ *
142
+ *  @return         None
143
+ */
144
+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);
145
+
146
+/** @brief Encode the ACI message for request data
147
+ *
148
+ *  @param[in,out]  buffer                          Pointer to ACI message buffer
149
+ *  @param[in]      p_aci_cmd_params_request_data   Pointer to the request data parameters in ::aci_cmd_params_request_data_t
150
+ *
151
+ *  @return         None
152
+ */
153
+void acil_encode_cmd_request_data(uint8_t *buffer, aci_cmd_params_request_data_t *p_aci_cmd_params_request_data);
154
+
155
+/** @brief Encode the ACI message for open remote pipe
156
+ *
157
+ *  @param[in,out]  buffer                              Pointer to ACI message buffer
158
+ *  @param[in]      p_aci_cmd_params_open_remote_pipe   Pointer to the dynamic data parameters in ::aci_cmd_params_open_remote_pipe_t
159
+ *
160
+ *  @return         None
161
+ */
162
+void acil_encode_cmd_open_remote_pipe(uint8_t *buffer, aci_cmd_params_open_remote_pipe_t *p_aci_cmd_params_open_remote_pipe);
163
+
164
+/** @brief Encode the ACI message for close remote pipe
165
+ *
166
+ *  @param[in,out]  buffer                              Pointer to ACI message buffer
167
+ *  @param[in]      p_aci_cmd_params_close_remote_pipe   Pointer to the dynamic data parameters in ::aci_cmd_params_close_remote_pipe_t
168
+ *
169
+ *  @return         None
170
+ */
171
+void acil_encode_cmd_close_remote_pipe(uint8_t *buffer, aci_cmd_params_close_remote_pipe_t *p_aci_cmd_params_close_remote_pipe);
172
+
173
+/** @brief Encode the ACI message for echo message
174
+ *
175
+ *  @param[in,out]  buffer             Pointer to ACI message buffer
176
+ *  @param[in]      p_cmd_params_echo  Pointer to the dynamic data parameters in ::aci_cmd_params_echo_t
177
+ *  @param[in]      msg_size           Size of the message
178
+ *
179
+ *  @return         None
180
+ */
181
+void acil_encode_cmd_echo_msg(uint8_t *buffer, aci_cmd_params_echo_t *p_cmd_params_echo, uint8_t msg_size);
182
+
183
+/** @brief Encode the ACI message to battery level
184
+ *
185
+ *  @param[in,out]  buffer  Pointer to ACI message buffer
186
+ *
187
+ *  @return         None
188
+ */
189
+void acil_encode_cmd_battery_level(uint8_t *buffer);
190
+
191
+/** @brief Encode the ACI message to temparature
192
+ *
193
+ *  @param[in,out]  buffer  Pointer to ACI message buffer
194
+ *
195
+ *  @return         None
196
+ */
197
+void acil_encode_cmd_temparature(uint8_t *buffer);
198
+
199
+/** @brief Encode the ACI message to read dynamic data
200
+ *
201
+ *  @param[in,out]  buffer  Pointer to ACI message buffer
202
+ *
203
+ *  @return         None
204
+ */
205
+void acil_encode_cmd_read_dynamic_data(uint8_t *buffer);
206
+
207
+/** @brief Encode the ACI message to change timing request
208
+ *
209
+ *  @param[in,out]  buffer  Pointer to ACI message buffer
210
+ *  @param[in]      p_aci_cmd_params_change_timing  Pointer to the change timing parameters in ::aci_cmd_params_change_timing_t
211
+ *
212
+ *  @return         None
213
+ */
214
+void acil_encode_cmd_change_timing_req(uint8_t *buffer, aci_cmd_params_change_timing_t *p_aci_cmd_params_change_timing);
215
+
216
+/** @brief Encode the ACI message to change timing request using the timing parameters from GAP PPCP
217
+ *
218
+ *  @param[in,out]  buffer  Pointer to ACI message buffer
219
+ *  @param[in]      p_aci_cmd_params_change_timing  Pointer to the change timing parameters in ::aci_cmd_params_change_timing_t
220
+ *
221
+ *  @return         None
222
+ */
223
+void acil_encode_cmd_change_timing_req_GAP_PPCP(uint8_t *buffer);
224
+
225
+
226
+/** @brief Encode the ACI message for write dynamic data
227
+ *
228
+ *  @param[in,out]  buffer                          Pointer to ACI message buffer
229
+ *  @param[in]      seq_no                          Sequence number of the dynamic data (as received in the response to @c Read Dynamic Data)
230
+ *  @param[in]      dynamic_data                    Pointer to the dynamic data
231
+ *  @param[in]      dynamic_data_size               Size of dynamic data
232
+ *
233
+ *  @return         None
234
+ */
235
+void acil_encode_cmd_write_dynamic_data(uint8_t *buffer, uint8_t seq_no, uint8_t* dynamic_data, uint8_t dynamic_data_size);
236
+
237
+/** @brief Encode the ACI message to send data acknowledgement
238
+ *
239
+ *  @param[in,out]  buffer  Pointer to ACI message buffer
240
+ *  @param[in]      pipe_number Pipe number for which the ack is to be sent
241
+ *
242
+ *  @return         None
243
+ */
244
+void acil_encode_cmd_send_data_ack(uint8_t *buffer, const uint8_t pipe_number);
245
+
246
+/** @brief Encode the ACI message to send negative acknowledgement
247
+ *
248
+ *  @param[in,out]  buffer  Pointer to ACI message buffer
249
+ *  @param[in]    pipe_number Pipe number for which the nack is to be sent
250
+ *  @param[in]    error_code Error code that has to be sent in the NACK
251
+ *
252
+ *  @return         None
253
+ */
254
+void acil_encode_cmd_send_data_nack(uint8_t *buffer, const uint8_t pipe_number,const uint8_t error_code);
255
+
256
+/** @brief Encode the ACI message to set the application latency
257
+ *
258
+ *  @param[in,out]  buffer  Pointer to ACI message buffer
259
+ *  @param[in]      p_aci_cmd_params_set_app_latency  Pointer to the set_application_latency command parameters in ::aci_cmd_params_dtm_cmd_t
260
+ *
261
+ *  @return         None
262
+ */
263
+void acil_encode_cmd_set_app_latency(uint8_t *buffer, aci_cmd_params_set_app_latency_t *p_aci_cmd_params_set_app_latency);
264
+
265
+/** @brief Encode the ACI message for setup
266
+ *
267
+ *  @param[in,out]  buffer                          Pointer to ACI message buffer
268
+ *  @param[in]      p_cmd_params_set_run_behaviour  Pointer to the setup data in ::aci_cmd_params_setup_t
269
+ *  @param[in]      setup_data_size                 Size of setup message
270
+ *
271
+ *  @return         None
272
+ */
273
+void acil_encode_cmd_setup(uint8_t *buffer, aci_cmd_params_setup_t *p_aci_cmd_params_setup, uint8_t setup_data_size);
274
+
275
+/** @brief Encode the ACI message for DTM command
276
+ *
277
+ *  @param[in,out]  buffer                          Pointer to ACI message buffer
278
+ *  @param[in]      p_cmd_params_set_run_behaviour  Pointer to the DTM command parameters in ::aci_cmd_params_dtm_cmd_t
279
+ *
280
+ *  @return         None
281
+ */
282
+void acil_encode_cmd_dtm_cmd(uint8_t *buffer, aci_cmd_params_dtm_cmd_t *p_aci_cmd_params_dtm_cmd);
283
+
284
+/** @brief Encode the ACI message for Set Key Request command
285
+ *
286
+ *  @param[in,out]  buffer      Pointer to ACI message buffer
287
+ *
288
+ *  @return         None
289
+ */
290
+void acil_encode_cmd_set_key(uint8_t *buffer, aci_cmd_params_set_key_t *p_aci_cmd_params_set_key);
291
+
292
+/** @brief Encode the ACI message for Bond Security Request command
293
+ *
294
+ *  @param[in,out]  buffer      Pointer to ACI message buffer
295
+ *
296
+ *  @return         None
297
+ */
298
+void acil_encode_cmd_bond_security_request(uint8_t *buffer);
299
+
300
+/** @brief Encode the ACI message
301
+ *
302
+ *  @param[in,out]  buffer      Pointer to ACI message buffer
303
+ *  @param[in]      p_aci_cmd   Pointer to ACI command data in ::aci_cmd_t
304
+ *  @param[in]      bool
305
+ *
306
+ *  @return         bool         true, if succesful, else returns false
307
+ */
308
+bool acil_encode_cmd(uint8_t *buffer, aci_cmd_t *p_aci_cmd);
309
+
310
+/** @brief Encode the ACI message for Broadcast command
311
+ *
312
+ *  @param[in,out]  buffer      Pointer to ACI message buffer
313
+ *  @param[in]      p_aci_cmd   Pointer to ACI command data in ::aci_cmd_params_broadcast_t
314
+ *
315
+ *  @return         None
316
+ */
317
+void acil_encode_cmd_broadcast(uint8_t *buffer,  aci_cmd_params_broadcast_t * p_aci_cmd_params_broadcast);
318
+
319
+/** @brief Encode the ACI message for Open Adv Pipes
320
+ *
321
+ *  @param[in,out]  buffer      Pointer to ACI message buffer
322
+ *  @param[in]      p_aci_cmd   Pointer to ACI command data in ::aci_cmd_params_open_adv_pipe_t
323
+ *
324
+ *  @return         None
325
+ */
326
+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);
327
+
328
+/** @brief Decode the ACI event command response
329
+ *
330
+ *  @param[in]      buffer_in  Pointer to message received
331
+ *  @param[in,out]  buffer     Pointer to the decoded message in ::aci_evt_params_cmd_rsp_t
332
+ *
333
+ *  @return         None
334
+ */
335
+void acil_decode_evt_command_response(uint8_t *buffer_in, aci_evt_params_cmd_rsp_t *p_evt_params_cmd_rsp);
336
+
337
+/** @brief Decode the ACI event device started
338
+ *
339
+ *  @param[in]      buffer_in  Pointer to message received
340
+ *  @param[in,out]  p_aci_evt  Pointer to the decoded message in ::aci_evt_params_device_started_t
341
+ *
342
+ *  @return         None
343
+ */
344
+void acil_decode_evt_device_started(uint8_t *buffer_in, aci_evt_params_device_started_t *p_evt_params_device_started);
345
+
346
+/** @brief Decode the ACI event pipe status
347
+ *
348
+ *  @param[in]      buffer_in  Pointer to message received
349
+ *  @param[in,out]  p_aci_evt_params_pipe_status  Pointer to the decoded message in ::aci_evt_params_pipe_status_t
350
+ *
351
+ *  @return         None
352
+ */
353
+void acil_decode_evt_pipe_status(uint8_t *buffer_in, aci_evt_params_pipe_status_t *p_aci_evt_params_pipe_status);
354
+
355
+/** @brief Decode the ACI event for disconnected
356
+ *
357
+ *  @param[in]      buffer_in                      Pointer to message received
358
+ *  @param[in,out]  p_aci_evt_params_disconnected  Pointer to the decoded message in ::aci_evt_params_disconnected_t
359
+ *
360
+ *  @return         None
361
+ */
362
+void acil_decode_evt_disconnected(uint8_t *buffer_in, aci_evt_params_disconnected_t *p_aci_evt_params_disconnected);
363
+
364
+/** @brief Decode the ACI event for bond status
365
+ *
366
+ *  @param[in]      buffer_in                     Pointer to message received
367
+ *  @param[in,out]  p_aci_evt_params_bond_status  Pointer to the decoded message in ::aci_evt_params_bond_status_t
368
+ *
369
+ *  @return         None
370
+ */
371
+void acil_decode_evt_bond_status(uint8_t *buffer_in, aci_evt_params_bond_status_t *p_aci_evt_params_bond_status);
372
+
373
+/** @brief Decode the ACI event for data received
374
+ *
375
+ *  @param[in]      buffer_in                   Pointer to message received
376
+ *  @param[in,out]  p_evt_params_data_received  Pointer to the decoded message in ::aci_evt_params_data_received_t
377
+ *
378
+ *  @return         size                        Received data size
379
+ */
380
+uint8_t acil_decode_evt_data_received(uint8_t *buffer_in, aci_evt_params_data_received_t *p_evt_params_data_received);
381
+
382
+/** @brief Decode the ACI event data acknowledgement
383
+ *
384
+ *  @param[in]      buffer_in               Pointer to message received
385
+ *  @param[in,out]  p_evt_params_data_ack   Pointer to the decoded message in ::aci_evt_params_data_ack_t
386
+ *
387
+ *  @return         None
388
+ */
389
+void acil_decode_evt_data_ack(uint8_t *buffer_in, aci_evt_params_data_ack_t *p_evt_params_data_ack);
390
+
391
+/** @brief Decode the ACI event for hardware error
392
+ *
393
+ *  @param[in]      buffer_in                  Pointer to message received
394
+ *  @param[in,out]  p_aci_evt_params_hw_error  Pointer to the decoded message in ::aci_evt_params_hw_error_t
395
+ *
396
+ *  @return         size                     Size of debug information
397
+ */
398
+uint8_t acil_decode_evt_hw_error(uint8_t *buffer_in, aci_evt_params_hw_error_t *p_aci_evt_params_hw_error);
399
+
400
+/** @brief Decode the ACI event data credit
401
+ *
402
+ *  @param[in]      buffer_in                 Pointer to message received
403
+ *  @param[in,out]  p_evt_params_data_credit  Pointer to the decoded message in ::aci_evt_params_data_credit_t
404
+ *
405
+ *  @return         None
406
+ */
407
+void acil_decode_evt_credit(uint8_t *buffer_in, aci_evt_params_data_credit_t *p_evt_params_data_credit);
408
+
409
+/** @brief Decode the ACI event for connected
410
+ *
411
+ *  @param[in]      buffer_in                   Pointer to message received
412
+ *  @param[in,out]  p_aci_evt_params_connected  Pointer to the decoded message in ::aci_evt_params_connected_t
413
+ *
414
+ *  @return         None
415
+ */
416
+void acil_decode_evt_connected(uint8_t *buffer_in, aci_evt_params_connected_t *p_aci_evt_params_connected);
417
+
418
+/** @brief Decode the ACI event for timing
419
+ *
420
+ *  @param[in]      buffer_in             Pointer to message received
421
+ *  @param[in,out]  p_evt_params_timing   Pointer to the decoded message in ::aci_evt_params_timing_t
422
+ *
423
+ *  @return         None
424
+ */
425
+void acil_decode_evt_timing(uint8_t *buffer_in, aci_evt_params_timing_t *p_evt_params_timing);
426
+
427
+/** @brief Decode the ACI event for pipe error
428
+ *
429
+ *  @param[in]      buffer_in                 Pointer to message received
430
+ *  @param[in,out]  p_evt_params_pipe_error   Pointer to the decoded message in ::aci_evt_params_pipe_error_t
431
+ *
432
+ */
433
+void acil_decode_evt_pipe_error(uint8_t *buffer_in, aci_evt_params_pipe_error_t *p_evt_params_pipe_error);
434
+
435
+/** @brief Decode the ACI event for key request
436
+ *
437
+ *  @param[in]      buffer_in               Pointer to message received
438
+ *  @param[in,out]  p_evt_params_key_type   Pointer to the decoded message in ::aci_evt_params_key_type_t
439
+ *
440
+ *  @return         None
441
+ */
442
+void acil_decode_evt_key_request(uint8_t *buffer_in, aci_evt_params_key_request_t *p_evt_params_key_request);
443
+
444
+/** @brief Decode the ACI event for echo
445
+ *
446
+ *  @param[in]      buffer_in    Pointer to message received
447
+ *  @param[in,out]  buffer_out   Pointer to the echo message (max size of buffer ::ACI_ECHO_DATA_MAX_LEN)
448
+ *
449
+ *  @return         size         Received echo message size
450
+ */
451
+uint8_t acil_decode_evt_echo(uint8_t *buffer_in, aci_evt_params_echo_t *buffer_out);
452
+
453
+/** @brief Decode the ACI event
454
+ *
455
+ *  @param[in]      buffer_in   Pointer to message received
456
+ *  @param[in,out]  p_aci_evt   Pointer to the decoded message in ::aci_evt_t
457
+ *
458
+ *  @return         bool         true, if succesful, else returns false
459
+ */
460
+bool acil_decode_evt(uint8_t *buffer_in, aci_evt_t *p_aci_evt);
461
+
462
+/** @brief Decode the Display Key Event
463
+ *
464
+ *  @param[in]      buffer_in   Pointer to message received
465
+ *  @param[in,out]  p_aci_evt   Pointer to the decoded message in ::aci_evt_params_display_passkey_t
466
+ *
467
+ *  @return         None
468
+ */
469
+void acil_decode_evt_display_passkey(uint8_t *buffer_in, aci_evt_params_display_passkey_t *p_aci_evt_params_display_passkey);
470
+
471
+#endif /* _acilib_IF_H_ */

+ 33
- 0
src/nrf8001/acilib_types.h 查看文件

@@ -0,0 +1,33 @@
1
+/* Copyright (c) 2014, Nordic Semiconductor ASA
2
+ *
3
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ * of this software and associated documentation files (the "Software"), to deal
5
+ * in the Software without restriction, including without limitation the rights
6
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ * copies of the Software, and to permit persons to whom the Software is
8
+ * furnished to do so, subject to the following conditions:
9
+ *
10
+ * The above copyright notice and this permission notice shall be included in all
11
+ * copies or substantial portions of the Software.
12
+ *
13
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ * SOFTWARE.
20
+ */
21
+
22
+/**
23
+ * @file
24
+ *
25
+ * @ingroup group_acilib
26
+ *
27
+ * @brief Type used in the acilib interfaces
28
+ */
29
+
30
+#ifndef _acilib_TYPES_H_
31
+#define _acilib_TYPES_H_
32
+
33
+#endif /* _acilib_TYPES_H_ */

+ 34
- 0
src/nrf8001/boards.h 查看文件

@@ -0,0 +1,34 @@
1
+/* Copyright (c) 2014, Nordic Semiconductor ASA
2
+ *
3
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ * of this software and associated documentation files (the "Software"), to deal
5
+ * in the Software without restriction, including without limitation the rights
6
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ * copies of the Software, and to permit persons to whom the Software is
8
+ * furnished to do so, subject to the following conditions:
9
+ *
10
+ * The above copyright notice and this permission notice shall be included in all
11
+ * copies or substantial portions of the Software.
12
+ *
13
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ * SOFTWARE.
20
+ */
21
+
22
+/** @file
23
+ * @brief Defines for the different Bluetooth low energy boards
24
+ */
25
+
26
+#ifndef _BLE_BOARDS_H_
27
+#define _BLE_BOARDS_H_
28
+
29
+#define BOARD_DEFAULT               0 //Use this if you do not know the board you are using or you are creating a new one
30
+#define REDBEARLAB_SHIELD_V1_1      1 //Redbearlab Bluetooth low energy shield v1.1
31
+#define REDBEARLAB_SHIELD_V2012_07  1 //Identical to Redbearlab v1.1 shield
32
+#define REDBEARLAB_SHIELD_V2        0 //Redbearlab Bluetooth low energy shield v2.x - No special handling required for pin reset same as default
33
+
34
+#endif

+ 63
- 0
src/nrf8001/dtm.h 查看文件

@@ -0,0 +1,63 @@
1
+/* Copyright (c) 2014, Nordic Semiconductor ASA
2
+ *
3
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ * of this software and associated documentation files (the "Software"), to deal
5
+ * in the Software without restriction, including without limitation the rights
6
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ * copies of the Software, and to permit persons to whom the Software is
8
+ * furnished to do so, subject to the following conditions:
9
+ *
10
+ * The above copyright notice and this permission notice shall be included in all
11
+ * copies or substantial portions of the Software.
12
+ *
13
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ * SOFTWARE.
20
+ */
21
+
22
+/**
23
+ * @file
24
+ *
25
+ * @ingroup group_acilib
26
+ *
27
+ * @brief Internal prototype for acilib module.
28
+ */
29
+
30
+#ifndef DTM_H__
31
+#define DTM_H__
32
+
33
+/** @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
34
+to 2480 MHz*/
35
+#define DTM_LE_CMD_RESET            0x00
36
+#define DTM_LE_CMD_RECEIVER_TEST    0x40
37
+#define DTM_LE_CMD_TRANSMITTER_TEST 0x80
38
+#define DTM_LE_CMD_TEST_END         0xC0
39
+
40
+
41
+/** @brief Defined packet types for DTM */
42
+#define DTM_LE_PKT_PRBS9      0x00       /**< Bit pattern PRBS9.    */
43
+#define DTM_LE_PKT_0X0F       0x01       /**< Bit pattern 11110000 (LSB is the leftmost bit). */
44
+#define DTM_LE_PKT_0X55       0x02       /**< Bit pattern 10101010 (LSB is the leftmost bit). */
45
+#define DTM_LE_PKT_VENDOR     0x03       /**< Vendor specific. Nordic: continous carrier test */
46
+
47
+/** @brief Defined bit fields for DTM responses. */
48
+#define LE_PACKET_REPORTING_EVENT_MSB_BIT   0x80
49
+#define LE_TEST_STATUS_EVENT_LSB_BIT        0x01
50
+
51
+/** @brief DTM response types. */
52
+#define LE_TEST_STATUS_EVENT                0x00
53
+#define LE_TEST_PACKET_REPORT_EVENT         0x80
54
+
55
+/** @brief DTM return values. */
56
+#define LE_TEST_STATUS_SUCCESS              0x00
57
+#define LE_TEST_STATUS_FAILURE              0x01
58
+
59
+
60
+
61
+#endif //DTM_H__
62
+
63
+/** @} */

+ 454
- 0
src/nrf8001/hal_aci_tl.cpp 查看文件

@@ -0,0 +1,454 @@
1
+/* Copyright (c) 2014, Nordic Semiconductor ASA
2
+ *
3
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ * of this software and associated documentation files (the "Software"), to deal
5
+ * in the Software without restriction, including without limitation the rights
6
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ * copies of the Software, and to permit persons to whom the Software is
8
+ * furnished to do so, subject to the following conditions:
9
+ *
10
+ * The above copyright notice and this permission notice shall be included in all
11
+ * copies or substantial portions of the Software.
12
+ *
13
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ * SOFTWARE.
20
+ */
21
+
22
+/** @file
23
+@brief Implementation of the ACI transport layer module
24
+*/
25
+
26
+#include <stdio.h>
27
+
28
+#include "hal_platform.h"
29
+#include "hal_aci_tl.h"
30
+#include "aci_queue.h"
31
+
32
+#define HIGH                    1
33
+#define LOW                     0
34
+
35
+#define REVERSE_BITS(byte) (((reverse_lookup[(byte & 0x0F)]) << 4) + reverse_lookup[((byte & 0xF0) >> 4)])
36
+static const uint8_t reverse_lookup[] = { 0, 8,  4, 12, 2, 10, 6, 14,1, 9, 5, 13,3, 11, 7, 15 };
37
+
38
+static void m_aci_data_print(hal_aci_data_t *p_data);
39
+static void m_aci_event_check(void);
40
+static void m_aci_isr(void);
41
+static void m_aci_pins_set(aci_pins_t *a_pins_ptr);
42
+static inline void m_aci_reqn_disable (void);
43
+static inline void m_aci_reqn_enable (void);
44
+static void m_aci_q_flush(void);
45
+static bool m_aci_spi_transfer(hal_aci_data_t * data_to_send, hal_aci_data_t * received_data);
46
+
47
+static uint8_t        spi_readwrite(uint8_t aci_byte);
48
+
49
+static bool           aci_debug_print = false;
50
+
51
+aci_queue_t    aci_tx_q;
52
+aci_queue_t    aci_rx_q;
53
+
54
+static aci_pins_t    *a_pins_local_ptr;
55
+
56
+void m_aci_data_print(hal_aci_data_t *p_data)
57
+{
58
+  const uint8_t length = p_data->buffer[0];
59
+  uint8_t i;
60
+  printf("%d\n", length);
61
+  printf(" :\n");
62
+  for (i=0; i<=length; i++)
63
+  {
64
+    printf("%x", p_data->buffer[i]);
65
+    printf(", ");
66
+  }
67
+  printf("\n");
68
+}
69
+
70
+/*
71
+  Interrupt service routine called when the RDYN line goes low. Runs the SPI transfer.
72
+*/
73
+static void m_aci_isr(void)
74
+{
75
+  hal_aci_data_t data_to_send;
76
+  hal_aci_data_t received_data;
77
+
78
+  // Receive from queue
79
+  if (!aci_queue_dequeue_from_isr(&aci_tx_q, &data_to_send))
80
+  {
81
+    /* queue was empty, nothing to send */
82
+    data_to_send.status_byte = 0;
83
+    data_to_send.buffer[0] = 0;
84
+  }
85
+
86
+  // Receive and/or transmit data
87
+  m_aci_spi_transfer(&data_to_send, &received_data);
88
+
89
+  if (!aci_queue_is_full_from_isr(&aci_rx_q) && !aci_queue_is_empty_from_isr(&aci_tx_q))
90
+  {
91
+    m_aci_reqn_enable();
92
+  }
93
+
94
+  // Check if we received data
95
+  if (received_data.buffer[0] > 0)
96
+  {
97
+    if (!aci_queue_enqueue_from_isr(&aci_rx_q, &received_data))
98
+    {
99
+      /* Receive Buffer full.
100
+         Should never happen.
101
+         Spin in a while loop.
102
+      */
103
+      while(1);
104
+    }
105
+
106
+    // Disable ready line interrupt until we have room to store incoming messages
107
+    if (aci_queue_is_full_from_isr(&aci_rx_q))
108
+    {
109
+      // detachInterrupt(a_pins_local_ptr->interrupt_number);
110
+    }
111
+  }
112
+
113
+  return;
114
+}
115
+
116
+/*
117
+  Checks the RDYN line and runs the SPI transfer if required.
118
+*/
119
+static void m_aci_event_check(void)
120
+{
121
+  hal_aci_data_t data_to_send;
122
+  hal_aci_data_t received_data;
123
+
124
+  // No room to store incoming messages
125
+  if (aci_queue_is_full(&aci_rx_q))
126
+  {
127
+    return;
128
+  }
129
+
130
+  // If the ready line is disabled and we have pending messages outgoing we enable the request line
131
+  if (HIGH == mraa_gpio_read (a_pins_local_ptr->m_rdy_ctx))
132
+  // if (HIGH == digitalRead(a_pins_local_ptr->rdyn_pin))
133
+  {
134
+    if (!aci_queue_is_empty(&aci_tx_q))
135
+    {
136
+      m_aci_reqn_enable();
137
+    }
138
+
139
+    return;
140
+  }
141
+
142
+  // Receive from queue
143
+  if (!aci_queue_dequeue(&aci_tx_q, &data_to_send))
144
+  {
145
+    /* queue was empty, nothing to send */
146
+    data_to_send.status_byte = 0;
147
+    data_to_send.buffer[0] = 0;
148
+  }
149
+
150
+  // Receive and/or transmit data
151
+  m_aci_spi_transfer(&data_to_send, &received_data);
152
+
153
+  /* If there are messages to transmit, and we can store the reply, we request a new transfer */
154
+  if (!aci_queue_is_full(&aci_rx_q) && !aci_queue_is_empty(&aci_tx_q))
155
+  {
156
+    m_aci_reqn_enable();
157
+  }
158
+
159
+  // Check if we received data
160
+  if (received_data.buffer[0] > 0)
161
+  {
162
+    if (!aci_queue_enqueue(&aci_rx_q, &received_data))
163
+    {
164
+      /* Receive Buffer full.
165
+         Should never happen.
166
+         Spin in a while loop.
167
+      */
168
+      while(1);
169
+    }
170
+  }
171
+
172
+  return;
173
+}
174
+
175
+/** @brief Point the low level library at the ACI pins specified
176
+ *  @details
177
+ *  The ACI pins are specified in the application and a pointer is made available for
178
+ *  the low level library to use
179
+ */
180
+static void m_aci_pins_set(aci_pins_t *a_pins_ptr)
181
+{
182
+  a_pins_local_ptr = a_pins_ptr;
183
+}
184
+
185
+static inline void m_aci_reqn_disable (void)
186
+{
187
+    mraa_gpio_write (a_pins_local_ptr->m_req_ctx, HIGH);
188
+}
189
+
190
+static inline void m_aci_reqn_enable (void)
191
+{
192
+    mraa_gpio_write (a_pins_local_ptr->m_req_ctx, LOW);
193
+}
194
+
195
+static void m_aci_q_flush(void)
196
+{
197
+  // noInterrupts();
198
+  /* re-initialize aci cmd queue and aci event queue to flush them*/
199
+  aci_queue_init(&aci_tx_q);
200
+  aci_queue_init(&aci_rx_q);
201
+  // interrupts();
202
+}
203
+
204
+static bool m_aci_spi_transfer(hal_aci_data_t * data_to_send, hal_aci_data_t * received_data)
205
+{
206
+  uint8_t byte_cnt;
207
+  uint8_t byte_sent_cnt;
208
+  uint8_t max_bytes;
209
+
210
+  m_aci_reqn_enable();
211
+
212
+  // Send length, receive header
213
+  byte_sent_cnt = 0;
214
+  received_data->status_byte = spi_readwrite(data_to_send->buffer[byte_sent_cnt++]);
215
+  // Send first byte, receive length from slave
216
+  received_data->buffer[0] = spi_readwrite(data_to_send->buffer[byte_sent_cnt++]);
217
+  if (0 == data_to_send->buffer[0])
218
+  {
219
+    max_bytes = received_data->buffer[0];
220
+  }
221
+  else
222
+  {
223
+    // Set the maximum to the biggest size. One command byte is already sent
224
+    max_bytes = (received_data->buffer[0] > (data_to_send->buffer[0] - 1))
225
+                                          ? received_data->buffer[0]
226
+                                          : (data_to_send->buffer[0] - 1);
227
+  }
228
+
229
+  if (max_bytes > HAL_ACI_MAX_LENGTH)
230
+  {
231
+    max_bytes = HAL_ACI_MAX_LENGTH;
232
+  }
233
+
234
+  // Transmit/receive the rest of the packet
235
+  for (byte_cnt = 0; byte_cnt < max_bytes; byte_cnt++)
236
+  {
237
+    received_data->buffer[byte_cnt+1] =  spi_readwrite(data_to_send->buffer[byte_sent_cnt++]);
238
+  }
239
+
240
+  // RDYN should follow the REQN line in approx 100ns
241
+  m_aci_reqn_disable();
242
+
243
+  return (max_bytes > 0);
244
+}
245
+
246
+void hal_aci_tl_debug_print(bool enable)
247
+{
248
+    aci_debug_print = enable;
249
+}
250
+
251
+void hal_aci_tl_pin_reset(void)
252
+{
253
+    if (UNUSED != a_pins_local_ptr->reset_pin)
254
+    {
255
+        // pinMode(a_pins_local_ptr->reset_pin, OUTPUT);
256
+
257
+        if ((REDBEARLAB_SHIELD_V1_1     == a_pins_local_ptr->board_name) ||
258
+            (REDBEARLAB_SHIELD_V2012_07 == a_pins_local_ptr->board_name))
259
+        {
260
+            //The reset for the Redbearlab v1.1 and v2012.07 boards are inverted and has a Power On Reset
261
+            //circuit that takes about 100ms to trigger the reset
262
+            mraa_gpio_write (a_pins_local_ptr->m_rst_ctx, HIGH);
263
+            usleep (100000);
264
+            mraa_gpio_write (a_pins_local_ptr->m_rst_ctx, LOW);
265
+        }
266
+        else
267
+        {
268
+            mraa_gpio_write (a_pins_local_ptr->m_rst_ctx, HIGH);
269
+            mraa_gpio_write (a_pins_local_ptr->m_rst_ctx, LOW);
270
+            mraa_gpio_write (a_pins_local_ptr->m_rst_ctx, HIGH);
271
+        }
272
+    }
273
+}
274
+
275
+bool hal_aci_tl_event_peek(hal_aci_data_t *p_aci_data)
276
+{
277
+  if (!a_pins_local_ptr->interface_is_interrupt)
278
+  {
279
+    m_aci_event_check();
280
+  }
281
+
282
+  if (aci_queue_peek(&aci_rx_q, p_aci_data))
283
+  {
284
+    return true;
285
+  }
286
+
287
+  return false;
288
+}
289
+
290
+bool hal_aci_tl_event_get(hal_aci_data_t *p_aci_data)
291
+{
292
+  bool was_full;
293
+
294
+  if (!a_pins_local_ptr->interface_is_interrupt && !aci_queue_is_full(&aci_rx_q))
295
+  {
296
+    m_aci_event_check();
297
+  }
298
+
299
+  was_full = aci_queue_is_full(&aci_rx_q);
300
+
301
+  if (aci_queue_dequeue(&aci_rx_q, p_aci_data))
302
+  {
303
+    if (aci_debug_print)
304
+    {
305
+      printf(" E");
306
+      m_aci_data_print(p_aci_data);
307
+    }
308
+
309
+    if (was_full && a_pins_local_ptr->interface_is_interrupt)
310
+    {
311
+      /* Enable RDY line interrupt again */
312
+      // attachInterrupt(a_pins_local_ptr->interrupt_number, m_aci_isr, LOW);
313
+    }
314
+
315
+    /* Attempt to pull REQN LOW since we've made room for new messages */
316
+    if (!aci_queue_is_full(&aci_rx_q) && !aci_queue_is_empty(&aci_tx_q))
317
+    {
318
+      m_aci_reqn_enable();
319
+    }
320
+
321
+    return true;
322
+  }
323
+
324
+  return false;
325
+}
326
+
327
+void hal_aci_tl_init(aci_pins_t *a_pins, bool debug)
328
+{
329
+    mraa_result_t error = MRAA_SUCCESS;
330
+    aci_debug_print = debug;
331
+
332
+    /* Needs to be called as the first thing for proper intialization*/
333
+    m_aci_pins_set(a_pins);
334
+
335
+    /*
336
+     * Init SPI
337
+     */
338
+    a_pins->m_spi = mraa_spi_init (0);
339
+    if (a_pins->m_spi == NULL) {
340
+        printf ("[ERROR] SPI failed to initilize\n");
341
+    }
342
+
343
+    mraa_spi_frequency (a_pins->m_spi, 2000000);
344
+    mraa_spi_mode (a_pins->m_spi, MRAA_SPI_MODE0);
345
+    mraa_spi_lsbmode (a_pins->m_spi, 1);
346
+
347
+    /* Initialize the ACI Command queue. This must be called after the delay above. */
348
+    aci_queue_init(&aci_tx_q);
349
+    aci_queue_init(&aci_rx_q);
350
+
351
+    // Configure the IO lines
352
+    a_pins->m_rdy_ctx = mraa_gpio_init (a_pins->rdyn_pin);
353
+    if (a_pins->m_rdy_ctx == NULL) {
354
+        printf ("[ERROR] GPIO failed to initilize \n");
355
+    }
356
+
357
+    a_pins->m_req_ctx = mraa_gpio_init (a_pins->reqn_pin);
358
+    if (a_pins->m_req_ctx == NULL) {
359
+        printf ("[ERROR] GPIO failed to initilize \n");
360
+    }
361
+
362
+    a_pins->m_rst_ctx = mraa_gpio_init (a_pins->reset_pin);
363
+    if (a_pins->m_rst_ctx == NULL) {
364
+        printf ("[ERROR] GPIO failed to initilize \n");
365
+    }
366
+
367
+    error = mraa_gpio_dir (a_pins->m_rdy_ctx, MRAA_GPIO_IN);
368
+    if (error != MRAA_SUCCESS) {
369
+        printf ("[ERROR] GPIO failed to initilize \n");
370
+    }
371
+
372
+    error = mraa_gpio_dir (a_pins->m_req_ctx, MRAA_GPIO_OUT);
373
+    if (error != MRAA_SUCCESS) {
374
+        printf ("[ERROR] GPIO failed to initilize \n");
375
+    }
376
+
377
+    error = mraa_gpio_dir (a_pins->m_rst_ctx, MRAA_GPIO_OUT);
378
+    if (error != MRAA_SUCCESS) {
379
+        printf ("[ERROR] GPIO failed to initilize \n");
380
+    }
381
+
382
+    if (UNUSED != a_pins->active_pin) {
383
+    }
384
+
385
+  /* Pin reset the nRF8001, required when the nRF8001 setup is being changed */
386
+  hal_aci_tl_pin_reset();
387
+
388
+  /* Set the nRF8001 to a known state as required by the datasheet*/
389
+  mraa_gpio_write (a_pins->m_req_ctx, LOW);
390
+
391
+  usleep(30000); //Wait for the nRF8001 to get hold of its lines - the lines float for a few ms after the reset
392
+
393
+    /* Attach the interrupt to the RDYN line as requested by the caller */
394
+    if (a_pins->interface_is_interrupt) {
395
+        // We use the LOW level of the RDYN line as the atmega328 can wakeup from sleep only on LOW
396
+        // attachInterrupt(a_pins->interrupt_number, m_aci_isr, LOW);
397
+    }
398
+}
399
+
400
+bool hal_aci_tl_send(hal_aci_data_t *p_aci_cmd)
401
+{
402
+  const uint8_t length = p_aci_cmd->buffer[0];
403
+  bool ret_val = false;
404
+
405
+  if (length > HAL_ACI_MAX_LENGTH)
406
+  {
407
+    return false;
408
+  }
409
+
410
+  ret_val = aci_queue_enqueue(&aci_tx_q, p_aci_cmd);
411
+  if (ret_val)
412
+  {
413
+    if(!aci_queue_is_full(&aci_rx_q))
414
+    {
415
+      // Lower the REQN only when successfully enqueued
416
+      m_aci_reqn_enable();
417
+    }
418
+  }
419
+
420
+  return ret_val;
421
+}
422
+
423
+static uint8_t spi_readwrite(const uint8_t aci_byte)
424
+{
425
+    uint8_t reversed, ret;
426
+    reversed = mraa_spi_write (a_pins_local_ptr->m_spi, REVERSE_BITS (aci_byte));
427
+    ret = REVERSE_BITS (reversed);
428
+    return ret;
429
+}
430
+
431
+bool hal_aci_tl_rx_q_empty (void)
432
+{
433
+  return aci_queue_is_empty(&aci_rx_q);
434
+}
435
+
436
+bool hal_aci_tl_rx_q_full (void)
437
+{
438
+  return aci_queue_is_full(&aci_rx_q);
439
+}
440
+
441
+bool hal_aci_tl_tx_q_empty (void)
442
+{
443
+  return aci_queue_is_empty(&aci_tx_q);
444
+}
445
+
446
+bool hal_aci_tl_tx_q_full (void)
447
+{
448
+  return aci_queue_is_full(&aci_tx_q);
449
+}
450
+
451
+void hal_aci_tl_q_flush (void)
452
+{
453
+  m_aci_q_flush();
454
+}

+ 188
- 0
src/nrf8001/hal_aci_tl.h 查看文件

@@ -0,0 +1,188 @@
1
+/* Copyright (c) 2014, Nordic Semiconductor ASA
2
+ *
3
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ * of this software and associated documentation files (the "Software"), to deal
5
+ * in the Software without restriction, including without limitation the rights
6
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ * copies of the Software, and to permit persons to whom the Software is
8
+ * furnished to do so, subject to the following conditions:
9
+ *
10
+ * The above copyright notice and this permission notice shall be included in all
11
+ * copies or substantial portions of the Software.
12
+ *
13
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ * SOFTWARE.
20
+ */
21
+
22
+/** @file
23
+ * @brief Interface for hal_aci_tl.
24
+ */
25
+
26
+/** @defgroup hal_aci_tl hal_aci_tl
27
+@{
28
+@ingroup hal
29
+
30
+@brief Module for the ACI Transport Layer interface
31
+@details This module is responsible for sending and receiving messages over the ACI interface of the nRF8001 chip.
32
+ The hal_aci_tl_send_cmd() can be called directly to send ACI commands.
33
+
34
+
35
+The RDYN line is hooked to an interrupt on the MCU when the level is low.
36
+The SPI master clocks in the interrupt context.
37
+The ACI Command is taken from the head of the command queue is sent over the SPI
38
+and the received ACI event is placed in the tail of the event queue.
39
+
40
+*/
41
+
42
+#ifndef HAL_ACI_TL_H__
43
+#define HAL_ACI_TL_H__
44
+
45
+#include "hal_platform.h"
46
+#include "aci.h"
47
+#include "boards.h"
48
+
49
+#include <mraa/aio.h>
50
+#include <mraa/gpio.h>
51
+#include <mraa/spi.h>
52
+
53
+#ifndef HAL_ACI_MAX_LENGTH
54
+#define HAL_ACI_MAX_LENGTH 31
55
+#endif
56
+
57
+/************************************************************************/
58
+/* Unused nRF8001 pin                                                    */
59
+/************************************************************************/
60
+#define UNUSED          255
61
+
62
+/** Data type for ACI commands and events */
63
+typedef struct {
64
+  uint8_t status_byte;
65
+  uint8_t buffer[HAL_ACI_MAX_LENGTH+1];
66
+} _aci_packed_ hal_aci_data_t;
67
+
68
+ACI_ASSERT_SIZE(hal_aci_data_t, HAL_ACI_MAX_LENGTH + 2);
69
+
70
+/** Datatype for ACI pins and interface (polling/interrupt)*/
71
+typedef struct aci_pins_t
72
+{
73
+    mraa_spi_context        m_spi;
74
+    mraa_gpio_context       m_rdy_ctx;
75
+    mraa_gpio_context       m_req_ctx;
76
+    mraa_gpio_context       m_rst_ctx;
77
+
78
+    uint8_t board_name;             //Optional : Use BOARD_DEFAULT if you do not know. See boards.h
79
+    uint8_t reqn_pin;               //Required
80
+    uint8_t rdyn_pin;               //Required
81
+    uint8_t mosi_pin;               //Required
82
+    uint8_t miso_pin;               //Required
83
+    uint8_t sck_pin;                //Required
84
+
85
+    uint8_t spi_clock_divider;      //Required : Clock divider on the SPI clock : nRF8001 supports a maximum clock of 3MHz
86
+
87
+    uint8_t reset_pin;              //Recommended but optional - Set it to UNUSED when not connected
88
+    uint8_t active_pin;             //Optional - Set it to UNUSED when not connected
89
+    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
90
+
91
+    bool    interface_is_interrupt; //Required - true = Uses interrupt on RDYN pin. false - Uses polling on RDYN pin
92
+
93
+    uint8_t interrupt_number;       //Required when using interrupts, otherwise ignored
94
+} aci_pins_t;
95
+
96
+/** @brief ACI Transport Layer initialization.
97
+ *  @details
98
+ *  This function initializes the transport layer, including configuring the SPI, creating
99
+ *  message queues for Commands and Events and setting up interrupt if required.
100
+ *  @param a_pins Pins on the MCU used to connect to the nRF8001
101
+ *  @param bool True if debug printing should be enabled on the Serial.
102
+ */
103
+void hal_aci_tl_init(aci_pins_t *a_pins, bool debug);
104
+
105
+/** @brief Sends an ACI command to the radio.
106
+ *  @details
107
+ *  This function sends an ACI command to the radio. This queue up the message to send and
108
+ *  lower the request line. When the device lowers the ready line, @ref m_aci_spi_transfer()
109
+ *  will send the data.
110
+ *  @param aci_buffer Pointer to the message to send.
111
+ *  @return True if the data was successfully queued for sending,
112
+ *  false if there is no more space to store messages to send.
113
+ */
114
+bool hal_aci_tl_send(hal_aci_data_t *aci_buffer);
115
+
116
+/** @brief Process pending transactions.
117
+ *  @details
118
+ *  The library code takes care of calling this function to check if the nRF8001 RDYN line indicates a
119
+ *  pending transaction. It will send a pending message if there is one and return any receive message
120
+ *  that was pending.
121
+ *  @return Points to data buffer for received data. Length byte in buffer is 0 if no data received.
122
+ */
123
+hal_aci_data_t * hal_aci_tl_poll_get(void);
124
+
125
+/** @brief Get an ACI event from the event queue
126
+ *  @details
127
+ *  Call this function from the main context to get an event from the ACI event queue
128
+ *  This is called by lib_aci_event_get
129
+ */
130
+bool hal_aci_tl_event_get(hal_aci_data_t *p_aci_data);
131
+
132
+/** @brief Peek an ACI event from the event queue
133
+ *  @details
134
+ *  Call this function from the main context to peek an event from the ACI event queue.
135
+ *  This is called by lib_aci_event_peek
136
+ */
137
+bool hal_aci_tl_event_peek(hal_aci_data_t *p_aci_data);
138
+
139
+/** @brief Enable debug printing of all ACI commands sent and ACI events received
140
+ *  @details
141
+ *  when the enable parameter is true. The debug printing is enabled on the Serial.
142
+ *  When the enable parameter is false. The debug printing is disabled on the Serial.
143
+ *  By default the debug printing is disabled.
144
+ */
145
+void hal_aci_tl_debug_print(bool enable);
146
+
147
+
148
+/** @brief Pin reset the nRF8001
149
+ *  @details
150
+ *  The reset line of the nF8001 needs to kept low for 200 ns.
151
+ *  Redbearlab shield v1.1 and v2012.07 are exceptions as they
152
+ *  have a Power ON Reset circuit that works differently.
153
+ *  The function handles the exceptions based on the board_name in aci_pins_t
154
+ */
155
+void hal_aci_tl_pin_reset(void);
156
+
157
+/** @brief Return full status of transmit queue
158
+ *  @details
159
+ *
160
+ */
161
+ bool hal_aci_tl_rx_q_full(void);
162
+
163
+ /** @brief Return empty status of receive queue
164
+ *  @details
165
+ *
166
+ */
167
+ bool hal_aci_tl_rx_q_empty(void);
168
+
169
+/** @brief Return full status of receive queue
170
+ *  @details
171
+ *
172
+ */
173
+ bool hal_aci_tl_tx_q_full(void);
174
+
175
+ /** @brief Return empty status of transmit queue
176
+ *  @details
177
+ *
178
+ */
179
+ bool hal_aci_tl_tx_q_empty(void);
180
+
181
+/** @brief Flush the ACI command Queue and the ACI Event Queue
182
+ *  @details
183
+ *  Call this function in the main thread
184
+ */
185
+void hal_aci_tl_q_flush(void);
186
+
187
+#endif // HAL_ACI_TL_H__
188
+/** @} */

+ 76
- 0
src/nrf8001/hal_platform.h 查看文件

@@ -0,0 +1,76 @@
1
+/* Copyright (c) 2014, Nordic Semiconductor ASA
2
+ *
3
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ * of this software and associated documentation files (the "Software"), to deal
5
+ * in the Software without restriction, including without limitation the rights
6
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ * copies of the Software, and to permit persons to whom the Software is
8
+ * furnished to do so, subject to the following conditions:
9
+ *
10
+ * The above copyright notice and this permission notice shall be included in all
11
+ * copies or substantial portions of the Software.
12
+ *
13
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ * SOFTWARE.
20
+ */
21
+
22
+#ifndef PLATFORM_H__
23
+#define PLATFORM_H__
24
+
25
+/** @file
26
+* @brief
27
+*/
28
+
29
+//Board dependent defines
30
+#if defined (__AVR__)
31
+    //For Arduino this AVR specific library has to be used for reading from Flash memory
32
+    #include <avr/pgmspace.h>
33
+    #include "Arduino.h"
34
+    #ifdef PROGMEM
35
+        #undef PROGMEM
36
+        #define PROGMEM __attribute__(( section(".progmem.data") ))
37
+        #endif
38
+#elif defined(__PIC32MX__)
39
+    //For Chipkit add the following libraries.
40
+    #include <stdint.h>
41
+    #include <stdbool.h>
42
+    #include <string.h>
43
+    #include <wiring.h>
44
+    #include <WProgram.h>
45
+
46
+    //For making the Serial.Print compatible between Arduino and Chipkit
47
+    #define F(X) (X)
48
+
49
+    //For ChipKit neither PROGMEM or PSTR are needed for PIC32
50
+    #define PROGMEM
51
+    #define PSTR(s) (s)
52
+
53
+    #define pgm_read_byte(x)            (*((char *)x))
54
+    #define pgm_read_byte_near(x)   (*((char *)x))
55
+    #define pgm_read_byte_far(x)        (*((char *)x))
56
+    #define pgm_read_word(x)            (*((short *)x))
57
+    #define pgm_read_word_near(x)   (*((short *)x))
58
+    #define pgm_read_workd_far(x)   (*((short *)x))
59
+
60
+    #define prog_void       const void
61
+    #define prog_char       const char
62
+    #define prog_uchar      const unsigned char
63
+    #define prog_int8_t     const int8_t
64
+    #define prog_uint8_t    const uint8_t
65
+    #define prog_int16_t    const int16_t
66
+    #define prog_uint16_t   const uint16_t
67
+    #define prog_int32_t    const int32_t
68
+    #define prog_uint32_t   const uint32_t
69
+    #define prog_int64_t    const int64_t
70
+    #define prog_uint64_t   const uint64_t
71
+
72
+    //Redefine the function for reading from flash in ChipKit
73
+    #define memcpy_P        memcpy
74
+#endif
75
+
76
+#endif /* PLATFORM_H__ */

+ 8
- 0
src/nrf8001/jsupm_nrf8001.i 查看文件

@@ -0,0 +1,8 @@
1
+%module jsupm_nrf8001
2
+%include "../upm.i"
3
+
4
+%{
5
+    #include "nrf8001.h"
6
+%}
7
+
8
+%include "nrf8001.h"

+ 742
- 0
src/nrf8001/lib_aci.cpp 查看文件

@@ -0,0 +1,742 @@
1
+/* Copyright (c) 2014, Nordic Semiconductor ASA
2
+ *
3
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ * of this software and associated documentation files (the "Software"), to deal
5
+ * in the Software without restriction, including without limitation the rights
6
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ * copies of the Software, and to permit persons to whom the Software is
8
+ * furnished to do so, subject to the following conditions:
9
+ *
10
+ * The above copyright notice and this permission notice shall be included in all
11
+ * copies or substantial portions of the Software.
12
+ *
13
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ * SOFTWARE.
20
+ */
21
+
22
+/** @file
23
+  @brief Implementation of the ACI library.
24
+ */
25
+
26
+#include "hal_platform.h"
27
+#include "aci.h"
28
+#include "aci_cmds.h"
29
+#include "aci_evts.h"
30
+#include "aci_protocol_defines.h"
31
+#include "acilib_defs.h"
32
+#include "acilib_if.h"
33
+#include "hal_aci_tl.h"
34
+#include "aci_queue.h"
35
+#include "lib_aci.h"
36
+
37
+
38
+#define LIB_ACI_DEFAULT_CREDIT_NUMBER   1
39
+
40
+/*
41
+Global additionally used used in aci_setup
42
+*/
43
+hal_aci_data_t  msg_to_send;
44
+
45
+
46
+static services_pipe_type_mapping_t * p_services_pipe_type_map;
47
+static hal_aci_data_t *               p_setup_msgs;
48
+
49
+
50
+
51
+
52
+static bool is_request_operation_pending;
53
+static bool is_indicate_operation_pending;
54
+static bool is_open_remote_pipe_pending;
55
+static bool is_close_remote_pipe_pending;
56
+
57
+static uint8_t request_operation_pipe = 0;
58
+static uint8_t indicate_operation_pipe = 0;
59
+
60
+
61
+// The following structure (aci_cmd_params_open_adv_pipe) will be used to store the complete command
62
+// including the pipes to be opened.
63
+static aci_cmd_params_open_adv_pipe_t aci_cmd_params_open_adv_pipe;
64
+
65
+
66
+
67
+extern aci_queue_t    aci_rx_q;
68
+extern aci_queue_t    aci_tx_q;
69
+
70
+bool lib_aci_is_pipe_available(aci_state_t *aci_stat, uint8_t pipe)
71
+{
72
+  uint8_t byte_idx;
73
+
74
+  byte_idx = pipe / 8;
75
+  if (aci_stat->pipes_open_bitmap[byte_idx] & (0x01 << (pipe % 8)))
76
+  {
77
+    return(true);
78
+  }
79
+  return(false);
80
+}
81
+
82
+
83
+bool lib_aci_is_pipe_closed(aci_state_t *aci_stat, uint8_t pipe)
84
+{
85
+  uint8_t byte_idx;
86
+
87
+  byte_idx = pipe / 8;
88
+  if (aci_stat->pipes_closed_bitmap[byte_idx] & (0x01 << (pipe % 8)))
89
+  {
90
+    return(true);
91
+  }
92
+  return(false);
93
+}
94
+
95
+
96
+bool lib_aci_is_discovery_finished(aci_state_t *aci_stat)
97
+{
98
+  return(aci_stat->pipes_open_bitmap[0]&0x01);
99
+}
100
+
101
+void lib_aci_board_init(aci_state_t *aci_stat)
102
+{
103
+    hal_aci_evt_t *aci_data = NULL;
104
+    aci_data = (hal_aci_evt_t *)&msg_to_send;
105
+
106
+    if (REDBEARLAB_SHIELD_V1_1 == aci_stat->aci_pins.board_name)
107
+    {
108
+      /*
109
+      The Bluetooth low energy Arduino shield v1.1 requires about 100ms to reset.
110
+      This is not required for the nRF2740, nRF2741 modules
111
+      */
112
+      usleep(100000);
113
+
114
+      /*
115
+      Send the soft reset command to the nRF8001 to get the nRF8001 to a known state.
116
+      */
117
+      lib_aci_radio_reset();
118
+
119
+      while (1)
120
+      {
121
+        /*Wait for the command response of the radio reset command.
122
+        as the nRF8001 will be in either SETUP or STANDBY after the ACI Reset Radio is processed
123
+        */
124
+
125
+
126
+        if (true == lib_aci_event_get(aci_stat, aci_data))
127
+        {
128
+          aci_evt_t * aci_evt;
129
+          aci_evt = &(aci_data->evt);
130
+
131
+          if (ACI_EVT_CMD_RSP == aci_evt->evt_opcode)
132
+          {
133
+                if (ACI_STATUS_ERROR_DEVICE_STATE_INVALID == aci_evt->params.cmd_rsp.cmd_status) //in SETUP
134
+                {
135
+                    //Inject a Device Started Event Setup to the ACI Event Queue
136
+                    msg_to_send.buffer[0] = 4;    //Length
137
+                    msg_to_send.buffer[1] = 0x81; //Device Started Event
138
+                    msg_to_send.buffer[2] = 0x02; //Setup
139
+                    msg_to_send.buffer[3] = 0;    //Hardware Error -> None
140
+                    msg_to_send.buffer[4] = 2;    //Data Credit Available
141
+                    aci_queue_enqueue(&aci_rx_q, &msg_to_send);
142
+                }
143
+                else if (ACI_STATUS_SUCCESS == aci_evt->params.cmd_rsp.cmd_status) //We are now in STANDBY
144
+                {
145
+                    //Inject a Device Started Event Standby to the ACI Event Queue
146
+                    msg_to_send.buffer[0] = 4;    //Length
147
+                    msg_to_send.buffer[1] = 0x81; //Device Started Event
148
+                    msg_to_send.buffer[2] = 0x03; //Standby
149
+                    msg_to_send.buffer[3] = 0;    //Hardware Error -> None
150
+                    msg_to_send.buffer[4] = 2;    //Data Credit Available
151
+                    aci_queue_enqueue(&aci_rx_q, &msg_to_send);
152
+                }
153
+                else if (ACI_STATUS_ERROR_CMD_UNKNOWN == aci_evt->params.cmd_rsp.cmd_status) //We are now in TEST
154
+                {
155
+                    //Inject a Device Started Event Test to the ACI Event Queue
156
+                    msg_to_send.buffer[0] = 4;    //Length
157
+                    msg_to_send.buffer[1] = 0x81; //Device Started Event
158
+                    msg_to_send.buffer[2] = 0x01; //Test
159
+                    msg_to_send.buffer[3] = 0;    //Hardware Error -> None
160
+                    msg_to_send.buffer[4] = 0;    //Data Credit Available
161
+                    aci_queue_enqueue(&aci_rx_q, &msg_to_send);
162
+                }
163
+
164
+                printf ("BREAK\n");
165
+                //Break out of the while loop
166
+                break;
167
+          }
168
+          else
169
+          {
170
+            //Serial.println(F("Discard any other ACI Events"));
171
+          }
172
+
173
+        }
174
+      }
175
+    }
176
+}
177
+
178
+
179
+void lib_aci_init(aci_state_t *aci_stat, bool debug)
180
+{
181
+    uint8_t i;
182
+
183
+    for (i = 0; i < PIPES_ARRAY_SIZE; i++) {
184
+        aci_stat->pipes_open_bitmap[i]          = 0;
185
+        aci_stat->pipes_closed_bitmap[i]        = 0;
186
+        aci_cmd_params_open_adv_pipe.pipes[i]   = 0;
187
+    }
188
+
189
+    is_request_operation_pending     = false;
190
+    is_indicate_operation_pending    = false;
191
+    is_open_remote_pipe_pending      = false;
192
+    is_close_remote_pipe_pending     = false;
193
+
194
+    request_operation_pipe           = 0;
195
+    indicate_operation_pipe          = 0;
196
+
197
+    p_services_pipe_type_map = aci_stat->aci_setup_info.services_pipe_type_mapping;
198
+    p_setup_msgs             = aci_stat->aci_setup_info.setup_msgs;
199
+
200
+    hal_aci_tl_init (&aci_stat->aci_pins, debug);
201
+    lib_aci_board_init (aci_stat);
202
+}
203
+
204
+
205
+uint8_t lib_aci_get_nb_available_credits(aci_state_t *aci_stat)
206
+{
207
+  return aci_stat->data_credit_available;
208
+}
209
+
210
+uint16_t lib_aci_get_cx_interval_ms(aci_state_t *aci_stat)
211
+{
212
+  uint32_t cx_rf_interval_ms_32bits;
213
+  uint16_t cx_rf_interval_ms;
214
+
215
+  cx_rf_interval_ms_32bits  = aci_stat->connection_interval;
216
+  cx_rf_interval_ms_32bits *= 125;                      // the connection interval is given in multiples of 0.125 milliseconds
217
+  cx_rf_interval_ms         = cx_rf_interval_ms_32bits / 100;
218
+
219
+  return cx_rf_interval_ms;
220
+}
221
+
222
+
223
+uint16_t lib_aci_get_cx_interval(aci_state_t *aci_stat)
224
+{
225
+  return aci_stat->connection_interval;
226
+}
227
+
228
+
229
+uint16_t lib_aci_get_slave_latency(aci_state_t *aci_stat)
230
+{
231
+  return aci_stat->slave_latency;
232
+}
233
+
234
+
235
+bool lib_aci_set_app_latency(uint16_t latency, aci_app_latency_mode_t latency_mode)
236
+{
237
+  aci_cmd_params_set_app_latency_t aci_set_app_latency;
238
+
239
+  aci_set_app_latency.mode    = latency_mode;
240
+  aci_set_app_latency.latency = latency;
241
+  acil_encode_cmd_set_app_latency(&(msg_to_send.buffer[0]), &aci_set_app_latency);
242
+
243
+  return hal_aci_tl_send(&msg_to_send);
244
+}
245
+
246
+
247
+bool lib_aci_test(aci_test_mode_change_t enter_exit_test_mode)
248
+{
249
+  aci_cmd_params_test_t aci_cmd_params_test;
250
+  aci_cmd_params_test.test_mode_change = enter_exit_test_mode;
251
+  acil_encode_cmd_set_test_mode(&(msg_to_send.buffer[0]), &aci_cmd_params_test);
252
+  return hal_aci_tl_send(&msg_to_send);
253
+}
254
+
255
+
256
+bool lib_aci_sleep()
257
+{
258
+  acil_encode_cmd_sleep(&(msg_to_send.buffer[0]));
259
+  return hal_aci_tl_send(&msg_to_send);
260
+}
261
+
262
+
263
+bool lib_aci_radio_reset()
264
+{
265
+  acil_encode_baseband_reset(&(msg_to_send.buffer[0]));
266
+  return hal_aci_tl_send(&msg_to_send);
267
+}
268
+
269
+
270
+bool lib_aci_direct_connect()
271
+{
272
+  acil_encode_direct_connect(&(msg_to_send.buffer[0]));
273
+  return hal_aci_tl_send(&msg_to_send);
274
+}
275
+
276
+
277
+bool lib_aci_device_version()
278
+{
279
+  acil_encode_cmd_get_device_version(&(msg_to_send.buffer[0]));
280
+  return hal_aci_tl_send(&msg_to_send);
281
+}
282
+
283
+
284
+bool lib_aci_set_local_data(aci_state_t *aci_stat, uint8_t pipe, uint8_t *p_value, uint8_t size)
285
+{
286
+  aci_cmd_params_set_local_data_t aci_cmd_params_set_local_data;
287
+
288
+  if ((p_services_pipe_type_map[pipe-1].location != ACI_STORE_LOCAL)
289
+      ||
290
+      (size > ACI_PIPE_TX_DATA_MAX_LEN))
291
+  {
292
+    return false;
293
+  }
294
+
295
+  aci_cmd_params_set_local_data.tx_data.pipe_number = pipe;
296
+  memcpy(&(aci_cmd_params_set_local_data.tx_data.aci_data[0]), p_value, size);
297
+  acil_encode_cmd_set_local_data(&(msg_to_send.buffer[0]), &aci_cmd_params_set_local_data, size);
298
+  return hal_aci_tl_send(&msg_to_send);
299
+}
300
+
301
+bool lib_aci_connect(uint16_t run_timeout, uint16_t adv_interval)
302
+{
303
+  aci_cmd_params_connect_t aci_cmd_params_connect;
304
+  aci_cmd_params_connect.timeout      = run_timeout;
305
+  aci_cmd_params_connect.adv_interval = adv_interval;
306
+  acil_encode_cmd_connect(&(msg_to_send.buffer[0]), &aci_cmd_params_connect);
307
+  return hal_aci_tl_send(&msg_to_send);
308
+}
309
+
310
+
311
+bool lib_aci_disconnect(aci_state_t *aci_stat, aci_disconnect_reason_t reason)
312
+{
313
+  bool ret_val;
314
+  uint8_t i;
315
+  aci_cmd_params_disconnect_t aci_cmd_params_disconnect;
316
+  aci_cmd_params_disconnect.reason = reason;
317
+  acil_encode_cmd_disconnect(&(msg_to_send.buffer[0]), &aci_cmd_params_disconnect);
318
+  ret_val = hal_aci_tl_send(&msg_to_send);
319
+  // If we have actually sent the disconnect
320
+  if (ret_val)
321
+  {
322
+    // Update pipes immediately so that while the disconnect is happening,
323
+    // the application can't attempt sending another message
324
+    // If the application sends another message before we updated this
325
+    //    a ACI Pipe Error Event will be received from nRF8001
326
+    for (i=0; i < PIPES_ARRAY_SIZE; i++)
327
+    {
328
+      aci_stat->pipes_open_bitmap[i] = 0;
329
+      aci_stat->pipes_closed_bitmap[i] = 0;
330
+    }
331
+  }
332
+  return ret_val;
333
+}
334
+
335
+
336
+bool lib_aci_bond(uint16_t run_timeout, uint16_t adv_interval)
337
+{
338
+  aci_cmd_params_bond_t aci_cmd_params_bond;
339
+  aci_cmd_params_bond.timeout = run_timeout;
340
+  aci_cmd_params_bond.adv_interval = adv_interval;
341
+  acil_encode_cmd_bond(&(msg_to_send.buffer[0]), &aci_cmd_params_bond);
342
+  return hal_aci_tl_send(&msg_to_send);
343
+}
344
+
345
+
346
+bool lib_aci_wakeup()
347
+{
348
+  acil_encode_cmd_wakeup(&(msg_to_send.buffer[0]));
349
+  return hal_aci_tl_send(&msg_to_send);
350
+}
351
+
352
+
353
+bool lib_aci_set_tx_power(aci_device_output_power_t tx_power)
354
+{
355
+  aci_cmd_params_set_tx_power_t aci_cmd_params_set_tx_power;
356
+  aci_cmd_params_set_tx_power.device_power = tx_power;
357
+  acil_encode_cmd_set_radio_tx_power(&(msg_to_send.buffer[0]), &aci_cmd_params_set_tx_power);
358
+  return hal_aci_tl_send(&msg_to_send);
359
+}
360
+
361
+
362
+bool lib_aci_get_address()
363
+{
364
+  acil_encode_cmd_get_address(&(msg_to_send.buffer[0]));
365
+  return hal_aci_tl_send(&msg_to_send);
366
+}
367
+
368
+
369
+bool lib_aci_get_temperature()
370
+{
371
+  acil_encode_cmd_temparature(&(msg_to_send.buffer[0]));
372
+  return hal_aci_tl_send(&msg_to_send);
373
+}
374
+
375
+
376
+bool lib_aci_get_battery_level()
377
+{
378
+  acil_encode_cmd_battery_level(&(msg_to_send.buffer[0]));
379
+  return hal_aci_tl_send(&msg_to_send);
380
+}
381
+
382
+
383
+bool lib_aci_send_data(uint8_t pipe, uint8_t *p_value, uint8_t size)
384
+{
385
+  bool ret_val = false;
386
+  aci_cmd_params_send_data_t aci_cmd_params_send_data;
387
+
388
+
389
+  if(!((p_services_pipe_type_map[pipe-1].pipe_type == ACI_TX) ||
390
+      (p_services_pipe_type_map[pipe-1].pipe_type == ACI_TX_ACK)))
391
+  {
392
+    return false;
393
+  }
394
+
395
+  if (size > ACI_PIPE_TX_DATA_MAX_LEN)
396
+  {
397
+    return false;
398
+  }
399
+  {
400
+      aci_cmd_params_send_data.tx_data.pipe_number = pipe;
401
+      memcpy(&(aci_cmd_params_send_data.tx_data.aci_data[0]), p_value, size);
402
+      acil_encode_cmd_send_data(&(msg_to_send.buffer[0]), &aci_cmd_params_send_data, size);
403
+
404
+      ret_val = hal_aci_tl_send(&msg_to_send);
405
+  }
406
+  return ret_val;
407
+}
408
+
409
+
410
+bool lib_aci_request_data(aci_state_t *aci_stat, uint8_t pipe)
411
+{
412
+  bool ret_val = false;
413
+  aci_cmd_params_request_data_t aci_cmd_params_request_data;
414
+
415
+  if(!((p_services_pipe_type_map[pipe-1].location == ACI_STORE_REMOTE)&&(p_services_pipe_type_map[pipe-1].pipe_type == ACI_RX_REQ)))
416
+  {
417
+    return false;
418
+  }
419
+
420
+
421
+  {
422
+
423
+    {
424
+
425
+
426
+
427
+      aci_cmd_params_request_data.pipe_number = pipe;
428
+      acil_encode_cmd_request_data(&(msg_to_send.buffer[0]), &aci_cmd_params_request_data);
429
+
430
+      ret_val = hal_aci_tl_send(&msg_to_send);
431
+    }
432
+  }
433
+  return ret_val;
434
+}
435
+
436
+
437
+bool lib_aci_change_timing(uint16_t minimun_cx_interval, uint16_t maximum_cx_interval, uint16_t slave_latency, uint16_t timeout)
438
+{
439
+  aci_cmd_params_change_timing_t aci_cmd_params_change_timing;
440
+  aci_cmd_params_change_timing.conn_params.min_conn_interval = minimun_cx_interval;
441
+  aci_cmd_params_change_timing.conn_params.max_conn_interval = maximum_cx_interval;
442
+  aci_cmd_params_change_timing.conn_params.slave_latency     = slave_latency;
443
+  aci_cmd_params_change_timing.conn_params.timeout_mult      = timeout;
444
+  acil_encode_cmd_change_timing_req(&(msg_to_send.buffer[0]), &aci_cmd_params_change_timing);
445
+  return hal_aci_tl_send(&msg_to_send);
446
+}
447
+
448
+
449
+bool lib_aci_change_timing_GAP_PPCP()
450
+{
451
+  acil_encode_cmd_change_timing_req_GAP_PPCP(&(msg_to_send.buffer[0]));
452
+  return hal_aci_tl_send(&msg_to_send);
453
+}
454
+
455
+
456
+bool lib_aci_open_remote_pipe(aci_state_t *aci_stat, uint8_t pipe)
457
+{
458
+  bool ret_val = false;
459
+  aci_cmd_params_open_remote_pipe_t aci_cmd_params_open_remote_pipe;
460
+
461
+  if(!((p_services_pipe_type_map[pipe-1].location == ACI_STORE_REMOTE)&&
462
+                ((p_services_pipe_type_map[pipe-1].pipe_type == ACI_RX)||
463
+                (p_services_pipe_type_map[pipe-1].pipe_type == ACI_RX_ACK_AUTO)||
464
+                (p_services_pipe_type_map[pipe-1].pipe_type == ACI_RX_ACK))))
465
+  {
466
+    return false;
467
+  }
468
+
469
+
470
+  {
471
+
472
+    is_request_operation_pending = true;
473
+    is_open_remote_pipe_pending = true;
474
+    request_operation_pipe = pipe;
475
+    aci_cmd_params_open_remote_pipe.pipe_number = pipe;
476
+    acil_encode_cmd_open_remote_pipe(&(msg_to_send.buffer[0]), &aci_cmd_params_open_remote_pipe);
477
+    ret_val = hal_aci_tl_send(&msg_to_send);
478
+  }
479
+  return ret_val;
480
+}
481
+
482
+
483
+bool lib_aci_close_remote_pipe(aci_state_t *aci_stat, uint8_t pipe)
484
+{
485
+  bool ret_val = false;
486
+  aci_cmd_params_close_remote_pipe_t aci_cmd_params_close_remote_pipe;
487
+
488
+  if(!((p_services_pipe_type_map[pipe-1].location == ACI_STORE_REMOTE)&&
489
+        ((p_services_pipe_type_map[pipe-1].pipe_type == ACI_RX)||
490
+         (p_services_pipe_type_map[pipe-1].pipe_type == ACI_RX_ACK_AUTO)||
491
+         (p_services_pipe_type_map[pipe-1].pipe_type == ACI_RX_ACK))))
492
+  {
493
+    return false;
494
+  }
495
+
496
+
497
+  {
498
+
499
+    is_request_operation_pending = true;
500
+    is_close_remote_pipe_pending = true;
501
+    request_operation_pipe = pipe;
502
+    aci_cmd_params_close_remote_pipe.pipe_number = pipe;
503
+    acil_encode_cmd_close_remote_pipe(&(msg_to_send.buffer[0]), &aci_cmd_params_close_remote_pipe);
504
+    ret_val = hal_aci_tl_send(&msg_to_send);
505
+  }
506
+  return ret_val;
507
+}
508
+
509
+
510
+bool lib_aci_set_key(aci_key_type_t key_rsp_type, uint8_t *key, uint8_t len)
511
+{
512
+  aci_cmd_params_set_key_t aci_cmd_params_set_key;
513
+  aci_cmd_params_set_key.key_type = key_rsp_type;
514
+  memcpy((uint8_t*)&(aci_cmd_params_set_key.key), key, len);
515
+  acil_encode_cmd_set_key(&(msg_to_send.buffer[0]), &aci_cmd_params_set_key);
516
+  return hal_aci_tl_send(&msg_to_send);
517
+}
518
+
519
+
520
+bool lib_aci_echo_msg(uint8_t msg_size, uint8_t *p_msg_data)
521
+{
522
+  aci_cmd_params_echo_t aci_cmd_params_echo;
523
+  if(msg_size > (ACI_ECHO_DATA_MAX_LEN))
524
+  {
525
+    return false;
526
+  }
527
+
528
+  if (msg_size > (ACI_ECHO_DATA_MAX_LEN))
529
+  {
530
+    msg_size = ACI_ECHO_DATA_MAX_LEN;
531
+  }
532
+
533
+  memcpy(&(aci_cmd_params_echo.echo_data[0]), p_msg_data, msg_size);
534
+  acil_encode_cmd_echo_msg(&(msg_to_send.buffer[0]), &aci_cmd_params_echo, msg_size);
535
+
536
+  return hal_aci_tl_send(&msg_to_send);
537
+}
538
+
539
+
540
+bool lib_aci_bond_request()
541
+{
542
+  acil_encode_cmd_bond_security_request(&(msg_to_send.buffer[0]));
543
+  return hal_aci_tl_send(&msg_to_send);
544
+}
545
+
546
+bool lib_aci_event_peek(hal_aci_evt_t *p_aci_evt_data)
547
+{
548
+  return hal_aci_tl_event_peek((hal_aci_data_t *)p_aci_evt_data);
549
+}
550
+
551
+bool lib_aci_event_get(aci_state_t *aci_stat, hal_aci_evt_t *p_aci_evt_data)
552
+{
553
+  bool status = false;
554
+
555
+  status = hal_aci_tl_event_get((hal_aci_data_t *)p_aci_evt_data);
556
+
557
+  /**
558
+  Update the state of the ACI with the
559
+  ACI Events -> Pipe Status, Disconnected, Connected, Bond Status, Pipe Error
560
+  */
561
+  if (true == status)
562
+  {
563
+    aci_evt_t * aci_evt;
564
+
565
+    aci_evt = &p_aci_evt_data->evt;
566
+
567
+    switch(aci_evt->evt_opcode)
568
+    {
569
+        case ACI_EVT_PIPE_STATUS:
570
+            {
571
+                uint8_t i=0;
572
+
573
+                for (i=0; i < PIPES_ARRAY_SIZE; i++)
574
+                {
575
+                  aci_stat->pipes_open_bitmap[i]   = aci_evt->params.pipe_status.pipes_open_bitmap[i];
576
+                  aci_stat->pipes_closed_bitmap[i] = aci_evt->params.pipe_status.pipes_closed_bitmap[i];
577
+                }
578
+            }
579
+            break;
580
+
581
+        case ACI_EVT_DISCONNECTED:
582
+            {
583
+                uint8_t i=0;
584
+
585
+                for (i=0; i < PIPES_ARRAY_SIZE; i++)
586
+                {
587
+                  aci_stat->pipes_open_bitmap[i] = 0;
588
+                  aci_stat->pipes_closed_bitmap[i] = 0;
589
+                }
590
+                aci_stat->confirmation_pending = false;
591
+                aci_stat->data_credit_available = aci_stat->data_credit_total;
592
+
593
+            }
594
+            break;
595
+
596
+        case ACI_EVT_TIMING:
597
+                aci_stat->connection_interval = aci_evt->params.timing.conn_rf_interval;
598
+                aci_stat->slave_latency       = aci_evt->params.timing.conn_slave_rf_latency;
599
+                aci_stat->supervision_timeout = aci_evt->params.timing.conn_rf_timeout;
600
+            break;
601
+
602
+        default:
603
+            /* Need default case to avoid compiler warnings about missing enum
604
+             * values on some platforms.
605
+             */
606
+            break;
607
+
608
+
609
+
610
+    }
611
+  }
612
+  return status;
613
+}
614
+
615
+
616
+bool lib_aci_send_ack(aci_state_t *aci_stat, const uint8_t pipe)
617
+{
618
+  bool ret_val = false;
619
+  {
620
+    acil_encode_cmd_send_data_ack(&(msg_to_send.buffer[0]), pipe);
621
+
622
+    ret_val = hal_aci_tl_send(&msg_to_send);
623
+  }
624
+  return ret_val;
625
+}
626
+
627
+
628
+bool lib_aci_send_nack(aci_state_t *aci_stat, const uint8_t pipe, const uint8_t error_code)
629
+{
630
+  bool ret_val = false;
631
+
632
+  {
633
+
634
+    acil_encode_cmd_send_data_nack(&(msg_to_send.buffer[0]), pipe, error_code);
635
+    ret_val = hal_aci_tl_send(&msg_to_send);
636
+  }
637
+  return ret_val;
638
+}
639
+
640
+
641
+bool lib_aci_broadcast(const uint16_t timeout, const uint16_t adv_interval)
642
+{
643
+  aci_cmd_params_broadcast_t aci_cmd_params_broadcast;
644
+  if (timeout > 16383)
645
+  {
646
+    return false;
647
+  }
648
+
649
+  // The adv_interval should be between 160 and 16384 (which translates to the advertisement
650
+  // interval values 100 ms and 10.24 s.
651
+  if ((160 > adv_interval) || (adv_interval > 16384))
652
+  {
653
+    return false;
654
+  }
655
+
656
+  aci_cmd_params_broadcast.timeout = timeout;
657
+  aci_cmd_params_broadcast.adv_interval = adv_interval;
658
+  acil_encode_cmd_broadcast(&(msg_to_send.buffer[0]), &aci_cmd_params_broadcast);
659
+  return hal_aci_tl_send(&msg_to_send);
660
+}
661
+
662
+
663
+bool lib_aci_open_adv_pipes(const uint8_t * const adv_service_data_pipes)
664
+{
665
+  uint8_t i;
666
+
667
+  for (i = 0; i < PIPES_ARRAY_SIZE; i++)
668
+  {
669
+    aci_cmd_params_open_adv_pipe.pipes[i] = adv_service_data_pipes[i];
670
+  }
671
+
672
+  acil_encode_cmd_open_adv_pipes(&(msg_to_send.buffer[0]), &aci_cmd_params_open_adv_pipe);
673
+  return hal_aci_tl_send(&msg_to_send);
674
+}
675
+
676
+bool lib_aci_open_adv_pipe(const uint8_t pipe)
677
+{
678
+  uint8_t byte_idx = pipe / 8;
679
+
680
+  aci_cmd_params_open_adv_pipe.pipes[byte_idx] |= (0x01 << (pipe % 8));
681
+  acil_encode_cmd_open_adv_pipes(&(msg_to_send.buffer[0]), &aci_cmd_params_open_adv_pipe);
682
+  return hal_aci_tl_send(&msg_to_send);
683
+}
684
+
685
+
686
+bool lib_aci_read_dynamic_data()
687
+{
688
+  acil_encode_cmd_read_dynamic_data(&(msg_to_send.buffer[0]));
689
+  return hal_aci_tl_send(&msg_to_send);
690
+}
691
+
692
+
693
+bool lib_aci_write_dynamic_data(uint8_t sequence_number, uint8_t* dynamic_data, uint8_t length)
694
+{
695
+  acil_encode_cmd_write_dynamic_data(&(msg_to_send.buffer[0]), sequence_number, dynamic_data, length);
696
+  return hal_aci_tl_send(&msg_to_send);
697
+}
698
+
699
+bool lib_aci_dtm_command(uint8_t dtm_command_msbyte, uint8_t dtm_command_lsbyte)
700
+{
701
+  aci_cmd_params_dtm_cmd_t aci_cmd_params_dtm_cmd;
702
+  aci_cmd_params_dtm_cmd.cmd_msb = dtm_command_msbyte;
703
+  aci_cmd_params_dtm_cmd.cmd_lsb = dtm_command_lsbyte;
704
+  acil_encode_cmd_dtm_cmd(&(msg_to_send.buffer[0]), &aci_cmd_params_dtm_cmd);
705
+  return hal_aci_tl_send(&msg_to_send);
706
+}
707
+
708
+void lib_aci_flush(void)
709
+{
710
+  hal_aci_tl_q_flush();
711
+}
712
+
713
+void lib_aci_debug_print(bool enable)
714
+{
715
+  hal_aci_tl_debug_print(enable);
716
+
717
+}
718
+
719
+void lib_aci_pin_reset(void)
720
+{
721
+    hal_aci_tl_pin_reset();
722
+}
723
+
724
+bool lib_aci_event_queue_empty(void)
725
+{
726
+  return hal_aci_tl_rx_q_empty();
727
+}
728
+
729
+bool lib_aci_event_queue_full(void)
730
+{
731
+  return hal_aci_tl_rx_q_full();
732
+}
733
+
734
+bool lib_aci_command_queue_empty(void)
735
+{
736
+  return hal_aci_tl_tx_q_empty();
737
+}
738
+
739
+bool lib_aci_command_queue_full(void)
740
+{
741
+  return hal_aci_tl_tx_q_full();
742
+}

+ 564
- 0
src/nrf8001/lib_aci.h 查看文件

@@ -0,0 +1,564 @@
1
+/* Copyright (c) 2014, Nordic Semiconductor ASA
2
+ *
3
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ * of this software and associated documentation files (the "Software"), to deal
5
+ * in the Software without restriction, including without limitation the rights
6
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ * copies of the Software, and to permit persons to whom the Software is
8
+ * furnished to do so, subject to the following conditions:
9
+ *
10
+ * The above copyright notice and this permission notice shall be included in all
11
+ * copies or substantial portions of the Software.
12
+ *
13
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ * SOFTWARE.
20
+ */
21
+
22
+#ifndef LIB_ACI_H__
23
+#define LIB_ACI_H__
24
+
25
+/** @file
26
+* @brief ACI library
27
+*/
28
+
29
+/** @addtogroup lib_aci
30
+@{
31
+@brief Library for the logical part of the Application Controller Interface (ACI)
32
+*/
33
+
34
+#ifdef __cplusplus
35
+extern "C" {
36
+#endif
37
+
38
+#include "hal_platform.h"
39
+#include "hal_aci_tl.h"
40
+#include "aci_queue.h"
41
+#include "aci.h"
42
+#include "aci_cmds.h"
43
+#include "aci_evts.h"
44
+
45
+#define EVT_CMD_RESPONSE_MIN_LENGTH              3
46
+
47
+#define PIPES_ARRAY_SIZE                ((ACI_DEVICE_MAX_PIPES + 7)/8)
48
+
49
+/* Same size as a hal_aci_data_t */
50
+typedef struct {
51
+  uint8_t   debug_byte;
52
+  aci_evt_t evt;
53
+} _aci_packed_ hal_aci_evt_t;
54
+
55
+ACI_ASSERT_SIZE(hal_aci_evt_t, 34);
56
+
57
+typedef struct
58
+{
59
+  uint8_t  location; /**< enum aci_pipe_store_t */
60
+  aci_pipe_type_t   pipe_type;
61
+} services_pipe_type_mapping_t;
62
+
63
+typedef struct aci_setup_info_t
64
+{
65
+  services_pipe_type_mapping_t *services_pipe_type_mapping;
66
+  uint8_t                       number_of_pipes;
67
+  hal_aci_data_t               *setup_msgs;
68
+  uint8_t                       num_setup_msgs;
69
+} aci_setup_info_t;
70
+
71
+
72
+
73
+// aci_struct that will contain
74
+// total initial credits
75
+// current credit
76
+// current state of the aci (setup/standby/active/sleep)
77
+// open remote pipe pending
78
+// close remote pipe pending
79
+// Current pipe available bitmap
80
+// Current pipe closed bitmap
81
+// Current connection interval, slave latency and link supervision timeout
82
+// Current State of the the GATT client (Service Discovery status)
83
+// Relationship of bond to peer address
84
+typedef struct aci_state_t
85
+{
86
+    aci_pins_t                    aci_pins;                               /* Pins on the MCU used to connect to the nRF8001 */
87
+    aci_setup_info_t              aci_setup_info;                         /* Data structures that are created from nRFgo Studio */
88
+    uint8_t                       bonded;                                 /* ( aci_bond_status_code_t ) Is the nRF8001 bonded to a peer device */
89
+    uint8_t                       data_credit_total;                      /* Total data credit available for the specific version of the nRF8001, total equals available when a link is established */
90
+    aci_device_operation_mode_t   device_state;                           /* Operating mode of the nRF8001 */
91
+
92
+    /* */
93
+
94
+    /* Start : Variables that are valid only when in a connection */
95
+    uint8_t                       data_credit_available;                  /* Available data credits at a specific point of time, ACI_EVT_DATA_CREDIT updates the available credits */
96
+
97
+    uint16_t                      connection_interval;                    /* Multiply by 1.25 to get the connection interval in milliseconds*/
98
+    uint16_t                      slave_latency;                          /* Number of consecutive connection intervals that the nRF8001 is not required to transmit. Use this to save power */
99
+    uint16_t                      supervision_timeout;                    /* Multiply by 10 to get the supervision timeout in milliseconds */
100
+
101
+    uint8_t                       pipes_open_bitmap[PIPES_ARRAY_SIZE];    /* Bitmap -> pipes are open and can be used for sending data over the air */
102
+    uint8_t                       pipes_closed_bitmap[PIPES_ARRAY_SIZE];  /* Bitmap -> pipes are closed and cannot be used for sending data over the air */
103
+    bool                          confirmation_pending;                   /* Attribute protocol Handle Value confirmation is pending for a Handle Value Indication
104
+                                                                        (ACK is pending for a TX_ACK pipe) on local GATT Server*/
105
+    /* End : Variables that are valid only when in a connection */
106
+
107
+} aci_state_t;
108
+
109
+
110
+
111
+#define DISCONNECT_REASON_CX_TIMEOUT                 0x08
112
+#define DISCONNECT_REASON_CX_CLOSED_BY_PEER_DEVICE   0x13
113
+#define DISCONNECT_REASON_POWER_LOSS                 0x14
114
+#define DISCONNECT_REASON_CX_CLOSED_BY_LOCAL_DEVICE  0x16
115
+#define DISCONNECT_REASON_ADVERTISER_TIMEOUT         0x50
116
+
117
+
118
+/** @name Functions for library management */
119
+//@{
120
+
121
+/** @brief Function to enable printing of all ACI commands sent and ACI events received
122
+ *  @details This function shall be used to enable or disable the debug printing.
123
+              Debug printing is disabled by default.
124
+ */
125
+void lib_aci_debug_print(bool enable);
126
+
127
+/** @brief Function to pin reset the nRF8001
128
+ *  @details Pin resets the nRF8001 also handles differences between development boards
129
+ */
130
+void lib_aci_pin_reset(void);
131
+
132
+/** @brief Initialization function.
133
+ *  @details This function shall be used to initialize/reset ACI Library and also Resets the
134
+ *           nRF8001 by togging the reset pin of the nRF8001. This function will reset
135
+ *           all the variables locally used by ACI library to their respective default values.
136
+ *  @param bool True if the data was successfully queued for sending,
137
+ *  false if there is no more space to store messages to send.
138
+ */
139
+void lib_aci_init(aci_state_t *aci_stat, bool debug);
140
+
141
+
142
+/** @brief Gets the number of currently available ACI credits.
143
+ *  @return Number of ACI credits.
144
+ */
145
+uint8_t lib_aci_get_nb_available_credits(aci_state_t *aci_stat);
146
+
147
+/** @brief Gets the connection interval in milliseconds.
148
+ *  @return Connection interval in milliseconds.
149
+ */
150
+uint16_t lib_aci_get_cx_interval_ms(aci_state_t *aci_stat);
151
+
152
+/** @brief Gets the connection interval in multiple of 1.25&nbsp;ms.
153
+ *  @return Connection interval in multiple of 1.25&nbsp;ms.
154
+ */
155
+uint16_t lib_aci_get_cx_interval(aci_state_t *aci_stat);
156
+
157
+/** @brief Gets the current slave latency.
158
+ *  @return Current slave latency.
159
+ */
160
+uint16_t lib_aci_get_slave_latency(aci_state_t *aci_stat);
161
+
162
+/** @brief Checks if a given pipe is available.
163
+ *  @param pipe Pipe to check.
164
+ *  @return True if the pipe is available, otherwise false.
165
+ */
166
+bool lib_aci_is_pipe_available(aci_state_t *aci_stat, uint8_t pipe);
167
+
168
+/** @brief Checks if a given pipe is closed.
169
+ *  @param pipe Pipe to check.
170
+ *  @return True if the pipe is closed, otherwise false.
171
+ */
172
+bool lib_aci_is_pipe_closed(aci_state_t *aci_stat, uint8_t pipe);
173
+
174
+/** @brief Checks if the discovery operation is finished.
175
+ *  @return True if the discovery is finished.
176
+ */
177
+bool lib_aci_is_discovery_finished(aci_state_t *aci_stat);
178
+
179
+
180
+
181
+//@}
182
+
183
+/** @name ACI Commands available in all modes */
184
+//@{
185
+
186
+/** @brief Sets the radio in sleep mode.
187
+ *  @details The function sends a @c sleep command to the radio.
188
+ *  If the radio is advertising or connected, it sends back an error, then use lib_aci_radio_reset
189
+ *  if advertising or disconnect if in a connection.
190
+ *  @return True if the transaction is successfully initiated.
191
+ */
192
+bool lib_aci_sleep(void);
193
+
194
+/** @brief Resets the radio.
195
+ *  @details The function sends a @c BasebandReset command to the radio.
196
+ *  @return True if the transaction is successfully initiated.
197
+ */
198
+bool lib_aci_radio_reset(void);
199
+
200
+/** @brief Radio starts directed advertising to bonded device.
201
+ *  @details The function sends a @c DirectedConnect command to the radio.
202
+ *  @return True if the transaction is successfully initiated.
203
+ */
204
+bool lib_aci_direct_connect(void);
205
+
206
+/** @brief Gets the radio's version.
207
+ *  @details This function sends a @c GetDeviceVersion command.
208
+ *  @return True if the transaction is successfully initiated.
209
+ */
210
+bool lib_aci_device_version(void);
211
+
212
+/** @brief Gets the device address.
213
+ *  @details This function sends a @c GetDeviceAddress command.
214
+ *  @return True if the transaction is successfully initiated.
215
+ */
216
+bool lib_aci_get_address(void);
217
+
218
+/** @brief Gets the temperature.
219
+ *  @details This function sends a @c GetTemperature command. lib_aci
220
+ *  calls the @ref lib_aci_transaction_finished_hook() function when the temperature is received.
221
+ *  @return True if the transaction is successfully initiated.
222
+ */
223
+bool lib_aci_get_temperature(void);
224
+
225
+/** @brief Gets the battery level.
226
+ *  @details This function sends a @c GetBatteryLevel command.
227
+ *  @return True if the transaction is successfully initiated.
228
+ */
229
+bool lib_aci_get_battery_level(void);
230
+
231
+//@}
232
+
233
+/** @name ACI commands available in Sleep mode */
234
+//@{
235
+
236
+/** @brief Wakes up the radio.
237
+ *  @details This function sends a @c Wakeup command to wake up the radio from
238
+ *  sleep mode. When woken up the radio sends a @c DeviceStartedEvent and
239
+ *  a @c CommandResponseEvent.
240
+ *  @return True if the transaction is successfully initiated.
241
+ */
242
+bool lib_aci_wakeup(void);
243
+
244
+//@}
245
+
246
+/** @name ACI commands available in Active mode */
247
+//@{
248
+
249
+/** @brief Sets the radio in test mode.
250
+ *  @details This function sends a @c Test command to the radio. There are two
251
+ *  Test modes available:
252
+ *  - UART: DTM commands are received over UART.
253
+ *  - ACI: DTM commands are received over ACI.
254
+ *  The same command is used to exit the test mode When receiving
255
+ *  a @c DeviceStartedEvent the radio has entered the new mode.
256
+ *  @param enter_exit_test_mode Enter a Test mode, or exit Test mode.
257
+ *  @return True if the transaction is successfully initiated.
258
+ */
259
+bool lib_aci_test(aci_test_mode_change_t enter_exit_test_mode);
260
+
261
+/** @brief Sets the radio's TX power.
262
+ *  @details This function sends a @c SetTxPower command.
263
+ *  @param tx_power TX power to be used by the radio.
264
+ *  @return True if the transaction is successfully initiated.
265
+ */
266
+bool lib_aci_set_tx_power(aci_device_output_power_t tx_power);
267
+
268
+/** @brief Tries to connect to a peer device.
269
+ *  @details This function sends a @c Connect command to the radio.
270
+ *  @param run_timeout Maximum advertising time in seconds (0 means infinite).
271
+ *  @param adv_interval Advertising interval (in multiple of 0.625&nbsp;ms).
272
+ *  @return True if the transaction is successfully initiated.
273
+ */
274
+bool lib_aci_connect(uint16_t run_timeout, uint16_t adv_interval);
275
+
276
+/** @brief Tries to bond with a peer device.
277
+ *  @details This function sends a @c Bond command to the radio.
278
+ *  @param run_timeout Maximum advertising time in seconds (0 means infinite).
279
+ *  @param adv_interval Advertising interval (in multiple of 0.625&nbsp;ms).
280
+ *  @return True if the transaction is successfully initiated.
281
+ */
282
+bool lib_aci_bond(uint16_t run_timeout, uint16_t adv_interval);
283
+
284
+/** @brief Disconnects from peer device.
285
+ *  @details This function sends a @c Disconnect command to the radio.
286
+ *  @param reason Reason for disconnecting.
287
+ *  @return True if the transaction is successfully initiated.
288
+ */
289
+bool lib_aci_disconnect(aci_state_t *aci_stat, aci_disconnect_reason_t reason);
290
+
291
+/**@brief Sets Local Data.
292
+ *  @details
293
+ *  This command updates the value of the characteristic value or the characteristic descriptor stored locally on the device.
294
+ *  Can be called for all types of pipes as long as the data is stored locally.
295
+ *  @param ACI state structure
296
+ *  @param pipe Pipe number on which the data should be set.
297
+ *  @param value Pointer to the data to set.
298
+ *  @param size Size of the data to set.
299
+ *  @return True if the transaction is successfully initiated.
300
+*/
301
+bool lib_aci_set_local_data(aci_state_t *aci_stat, uint8_t pipe, uint8_t *value, uint8_t size);
302
+
303
+/** @brief Sends Broadcast message to the radio.
304
+ *  @details The Broadcast message starts advertisement procedure
305
+ *  using the given interval with the intention of broadcasting data to a peer device.
306
+ *  @param timeout Time, in seconds, to advertise before exiting to standby mode (0 means infinite).
307
+ *  Valid values: 0 to 16383.
308
+ *  @param adv_interval Advertising interval (in multiple of 0.625&nbsp;ms).
309
+ *  Valid values: 160 to 16384 (which corresponds to an interval from 100 ms to 10.24 s).
310
+ *  @return True if the broadcast message is sent successfully to the radio.
311
+*/
312
+bool lib_aci_broadcast(const uint16_t timeout, const uint16_t adv_interval);
313
+
314
+/** @name Open Advertising Pipes.  */
315
+
316
+/** @brief Sends a command to the radio to set the input pipe to be placed in Advertisement Service Data.
317
+ *  @details This function sends a command to the radio that places the pipe in
318
+ *  advertisement service data.  To start advertising service data, call this function before
319
+ *  Connecting, Broadcasting or Bonding to peer. The data that should be sent in the advertisement packets
320
+ *  must be set using the @c lib_aci_set_local_data function. This function can be called during
321
+ *  advertising to enable/disable broadcast pipes.
322
+ *  @param pipe The pipe that has to be placed in advertising service data.
323
+ *  @return True if the Open Adv Pipe message is sent successfully to the radio.
324
+*/
325
+bool lib_aci_open_adv_pipe(const uint8_t pipe);
326
+
327
+
328
+/** @name Open Advertising Pipes  */
329
+
330
+/** @brief Sends a command to the radio to set the pipes to be placed in Advertisement Service Data.
331
+ *  @details This function will send a command to the radio that will set the pipes to be placed in
332
+ *  advertisement Service Data.  To start advertising service data, this function should be called before
333
+ *  Connecting, Broadcasting or Bonding to peer. This function can be called during
334
+ *  advertising to enable/disable broadcast pipes. Use this as an alternative to @ref lib_aci_open_adv_pipe
335
+ *  to avoid multiple function calls for placing multiple pipes in the adv data.
336
+ *  @param adv_service_data_pipes Pipe bitmap, where '1' indicates that the corresponding
337
+ *  Valid Values: 0000000000000000 to FEFFFFFFFFFFFF7F (See the ACI Pipe Status Evt bitmap in the nRF8001 datasheet
338
+ *  TX_BROADCAST pipe data is to be placed in Advertising Service Data fields
339
+ *  @return true if the Open Adv Pipe message was sent successfully to the radio.
340
+*/
341
+bool lib_aci_open_adv_pipes(const uint8_t * const adv_service_data_pipes);
342
+
343
+
344
+//@}
345
+
346
+/** @name ACI commands available in Connected mode */
347
+//@{
348
+
349
+
350
+/** @brief Sets a given application latency.
351
+ *  @details This function sends a @c setApplicationLatency command.
352
+ *  @return True if the transaction is successfully initiated.
353
+ */
354
+bool lib_aci_set_app_latency(uint16_t latency, aci_app_latency_mode_t latency_mode);
355
+
356
+/** @brief Opens a remote pipe.
357
+ *  @details This function sends an @c OpenRemotePipe command.
358
+ *  @param pipe Number of the pipe to open.
359
+ *  @return True if the transaction is successfully initiated.
360
+ */
361
+bool lib_aci_open_remote_pipe(aci_state_t *aci_stat, uint8_t pipe);
362
+
363
+/** @brief Closes a remote pipe.
364
+ *  @details This function sends an @c CloseRemotePipe command.
365
+ *  @param pipe Pipe number to close.
366
+ *  @return True if the transaction is successfully initiated.
367
+ */
368
+bool lib_aci_close_remote_pipe(aci_state_t *aci_stat, uint8_t pipe);
369
+
370
+/** @brief Sends data on a given pipe.
371
+ *  @details This function sends a @c SendData command with application data to
372
+ *  the radio. This function memorizes credit use, and checks that
373
+ *  enough credits are available.
374
+ *  @param pipe Pipe number on which the data should be sent.
375
+ *  @param value Pointer to the data to send.
376
+ *  @param size Size of the data to send.
377
+ *  @return True if the transaction is successfully initiated.
378
+ */
379
+bool lib_aci_send_data(uint8_t pipe, uint8_t *value, uint8_t size);
380
+
381
+/** @brief Requests data from a given pipe.
382
+ *  @details This function sends a @c RequestData command to the radio. This
383
+ *  function memorizes credit uses, and check that enough credits are available.
384
+ *  After this command, the radio sends back either a @c DataReceivedEvent
385
+ *  or a @c PipeErrorEvent.
386
+ *  @param pipe Pipe number on which the data is requested.
387
+ *  @return True if the transaction is successfully initiated.
388
+ */
389
+bool lib_aci_request_data(aci_state_t *aci_stat, uint8_t pipe);
390
+
391
+/** @brief Sends a L2CAP change connection parameters request.
392
+ *  @details This function sends a @c ChangeTiming command to the radio.  This command triggers a "L2CAP change connection parameters" request
393
+ *  to the master. If the master rejects or accepts but doesn't change the connection parameters within
394
+ *  30 seconds, a timing event with the unchanged connection parameters is sent by the radio.
395
+ *  If the request is accepted and the master changes connection parameters, a timing event with
396
+ *  the new connection parameters is sent by the radio.
397
+ *  If the master doesn't reply to the request within 60 seconds, the radio disconnects.
398
+ *  @param minimun_cx_interval Minimum connection interval requested, in multiple of 1.25&nbsp;ms.
399
+ *  @param maximum_cx_interval Maximum connection interval requested, in multiple of 1.25&nbsp;ms.
400
+ *  @param slave_latency requested slave latency.
401
+ *  @param timeout requested slave timeout, in multiple of 10&nbsp;ms.
402
+ *  @return True if the transaction is successfully initiated.
403
+ */
404
+bool lib_aci_change_timing(uint16_t minimun_cx_interval, uint16_t maximum_cx_interval, uint16_t slave_latency, uint16_t timeout);
405
+
406
+/** @brief Sends a L2CAP change connection parameters request with the connection predefined preffered connection parameters.
407
+ *  @details This function sends a @c ChangeTiming command to the radio. This command triggers a "L2CAP change connection parameters" request
408
+ *  to the master. If the master rejects or accepts but doesn't change the connection parameters within
409
+ *  30 seconds, a timing event with the unchanged connection parameters is sent by the radio.
410
+ *  If the request is accepted and the master changes connection parameters, a timing event with
411
+ *  the new connection parameters is sent by the radio.
412
+ *  If the master doesn't reply to the request within 60 seconds, the radio disconnects.
413
+ *  The timing parameters used are the Timing parameters in the GAP settings in the nRFgo Studio.
414
+ *  The Timing parameters as stored as the GAP Preferred Peripheral Connection Parameters.
415
+ *  @return True if the transaction is successfully initiated.
416
+ */
417
+bool lib_aci_change_timing_GAP_PPCP(void);
418
+
419
+/** @brief Sends acknowledgement message to peer.
420
+ *  @details This function sends @c SendDataAck command to radio. The radio is expected
421
+ *  to send either Handle Value Confirmation or Write response depending
422
+ *  on whether the data is stored remotely or locally.
423
+ *  @param pipe Pipe number for which the acknowledgement is to be sent.
424
+ *  @return True if the ack was sent successfully. False otherwise.
425
+*/
426
+bool lib_aci_send_ack(aci_state_t *aci_stat, const uint8_t pipe);
427
+
428
+/** @brief Sends negative acknowledgement message to peer.
429
+ *  @details This function sends @c SendDataNack command to radio. The radio is expected
430
+ *  to send Error Response to the peer.
431
+ *  @param pipe Pipe number for which the nack is to be sent.
432
+ *  @param error_code Error code to be sent in the NACk.
433
+ *  @return True if the nack was sent successfully. False otherwise.
434
+*/
435
+bool lib_aci_send_nack(aci_state_t *aci_stat, const uint8_t pipe, const uint8_t error_code);
436
+
437
+/** @brief Sends ReadDynamicData command to the host.
438
+ *  @details This function sends @c ReadDynamicData command to host. The host is expected
439
+ *  to send @c CommandResponse back with the dynamic data. The application is expected to
440
+ *  call this function in a loop until all the dynamic data is read out from the host.
441
+ *  As long as there is dynamic data to be read from the host, the command response
442
+ *  for this message has its status field set to ACI_STATUS_TRANSACTION_CONTINUE (0x01).
443
+ *  The application may chose to store this read out data in a non-volatile memory location
444
+ *  and later chose to write it back using the function lib_aci_write_dynamic_data.
445
+ *  @return True if the command was sent successfully through the ACI. False otherwise.
446
+*/
447
+bool lib_aci_read_dynamic_data(void);
448
+
449
+/** @brief Sends WriteDynamicData command to the host.
450
+ *  @details This function sends @c WriteDynamicData command to host. The host is expected
451
+ *  to send @c CommandResponse with the status of this operation. As long as the status field
452
+ *  in the @c CommandResponse is ACI_STATUS_TRANSACTION_CONTINUE (0x01), the hosts expects
453
+ *  more dynamic data to be written. This function should ideally be called in a cycle,
454
+ *  until all the stored dynamic data is sent to the host. This function should be
455
+ *  called with the dynamic data obtained from the response to a @c ReadDynamicData
456
+ *  (see @c lib_aci_read_dynamic_data) command.
457
+ *  @param sequence_number Sequence number of the dynamic data to be sent.
458
+ *  @param dynamic_data Pointer to the dynamic data.
459
+ *  @param length Length of the dynamic data.
460
+ *  @return True if the command was sent successfully through the ACI. False otherwise.
461
+*/
462
+bool lib_aci_write_dynamic_data(uint8_t sequence_number, uint8_t* dynamic_data, uint8_t length);
463
+//@}
464
+
465
+/** @name ACI commands available while connected in Bond mode */
466
+//@{
467
+
468
+/** @brief Sends a SMP Security Request.
469
+ *  @details This function send a @c BondRequest command to the radio.
470
+ *  This command triggers a SMP Security Request to the master. If the
471
+ *  master rejects with a pairing failed or if the bond timer expires the connection is closed.
472
+ *  @return True if the transaction is successfully initiated.
473
+ */
474
+bool lib_aci_bond_request(void);
475
+
476
+/** @brief Set the key requested by the 8001.
477
+ *  @details This function sends an @c SetKey command to the radio.
478
+ *  @param key_rsp_type Type of key.
479
+ *  @param key Pointer to the key to set.
480
+ *  @param len Length of the key.
481
+ *  @return True if the transaction is successfully initiated.
482
+*/
483
+bool lib_aci_set_key(aci_key_type_t key_rsp_type, uint8_t *key, uint8_t len);
484
+
485
+//@}
486
+
487
+
488
+
489
+/** @name ACI commands available in Test mode */
490
+//@{
491
+
492
+/** @brief Sends an echo message
493
+ *  @details This function sends an @c Echo command to the radio. lib_aci
494
+ *  places the Echp ACI command in the ACI command queue
495
+ *  @param message_size Length of the data to send.
496
+ *  @param message_data Pointer to the data to send.
497
+ *  @return True if the transaction is successfully initiated.
498
+*/
499
+bool lib_aci_echo_msg(uint8_t message_size, uint8_t *message_data);
500
+
501
+/** @brief Sends an DTM command
502
+ *  @details This function sends an @c DTM command to the radio.
503
+ *  @param dtm_command_msbyte Most significant byte of the DTM command.
504
+ *  @param dtm_command_lsbyte Least significant byte of the DTM command.
505
+ *  @return True if the transaction is successfully initiated.
506
+*/
507
+bool lib_aci_dtm_command(uint8_t dtm_command_msbyte, uint8_t dtm_command_lsbyte);
508
+
509
+/** @brief Gets an ACI event from the ACI Event Queue
510
+ *  @details This function gets an ACI event from the ACI event queue.
511
+ *  The queue is updated by the SPI driver for the ACI running in the interrupt context
512
+ *  @param aci_stat pointer to the state of the ACI.
513
+ *  @param p_aci_data pointer to the ACI Event. The ACI Event received will be copied into this pointer.
514
+ *  @return True if an ACI Event was copied to the pointer.
515
+*/
516
+bool lib_aci_event_get(aci_state_t *aci_stat, hal_aci_evt_t * aci_evt);
517
+
518
+/** @brief Peeks an ACI event from the ACI Event Queue
519
+ * @details This function peeks at the top event in the ACI event queue.
520
+ * In polling mode, this function will query the nRF8001 for pending events, but unlike
521
+ * lib_aci_event_get() it will not dequeue the event from the local queue, but will instead
522
+ * only peek at it.
523
+ * @return True if an ACI Event was copied to the pointer.
524
+*/
525
+bool lib_aci_event_peek(hal_aci_evt_t *p_aci_evt_data);
526
+
527
+/** @brief Flushes the events in the ACI command queues and ACI Event queue
528
+ *
529
+*/
530
+void lib_aci_flush(void);
531
+
532
+/** @brief Return full status of the Event queue
533
+ *  @details
534
+ *
535
+ */
536
+ bool lib_aci_event_queue_full(void);
537
+
538
+ /** @brief Return empty status of the Event queue
539
+ *  @details
540
+ *
541
+ */
542
+ bool lib_aci_event_queue_empty(void);
543
+
544
+/** @brief Return full status of Command queue
545
+ *  @details
546
+ *
547
+ */
548
+ bool lib_aci_command_queue_full(void);
549
+
550
+ /** @brief Return empty status of Command queue
551
+ *  @details
552
+ *
553
+ */
554
+ bool lib_aci_command_queue_empty(void);
555
+
556
+//@}
557
+
558
+/** @} */
559
+
560
+#ifdef __cplusplus
561
+}
562
+#endif
563
+
564
+#endif /* LIB_ACI_H__ */

+ 77
- 0
src/nrf8001/nrf8001.cxx 查看文件

@@ -0,0 +1,77 @@
1
+/*
2
+ * Author: Yevgeniy Kiveisha <yevgeniy.kiveisha@intel.com>
3
+ * Copyright (c) 2014 Intel Corporation.
4
+ *
5
+ * Permission is hereby granted, free of charge, to any person obtaining
6
+ * a copy of this software and associated documentation files (the
7
+ * "Software"), to deal in the Software without restriction, including
8
+ * without limitation the rights to use, copy, modify, merge, publish,
9
+ * distribute, sublicense, and/or sell copies of the Software, and to
10
+ * permit persons to whom the Software is furnished to do so, subject to
11
+ * the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be
14
+ * included in all copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+ */
24
+
25
+#include <unistd.h>
26
+#include <stdlib.h>
27
+#include <stdint.h>
28
+
29
+#include "nrf8001.h"
30
+
31
+/**
32
+ * Include the services_lock.h to put the setup in the OTP memory of the nRF8001.
33
+ * This would mean that the setup cannot be changed once put in.
34
+ * However this removes the need to do the setup of the nRF8001 on every reset.
35
+*/
36
+
37
+void
38
+init_local_interfaces (aci_state_t* aci, uint8_t reqn, uint8_t rdyn, uint8_t rst) {
39
+    /**
40
+     * Tell the ACI library, the MCU to nRF8001 pin connections.
41
+     * The Active pin is optional and can be marked UNUSED
42
+     */
43
+    aci->aci_pins.board_name                = BOARD_DEFAULT;    // See board.h for details REDBEARLAB_SHIELD_V1_1 or BOARD_DEFAULT
44
+    aci->aci_pins.reqn_pin                  = reqn;             // SS for Nordic board, 9 for REDBEARLAB_SHIELD_V1_1
45
+    aci->aci_pins.rdyn_pin                  = rdyn;             // 3 for Nordic board, 8 for REDBEARLAB_SHIELD_V1_1
46
+
47
+    aci->aci_pins.reset_pin                 = rst;              // 4 for Nordic board, UNUSED for REDBEARLAB_SHIELD_V1_1
48
+    aci->aci_pins.active_pin                = UNUSED;
49
+    aci->aci_pins.optional_chip_sel_pin     = UNUSED;
50
+
51
+    aci->aci_pins.interface_is_interrupt    = false;            // Interrupts still not available in Chipkit
52
+    aci->aci_pins.interrupt_number          = 1;
53
+
54
+    lib_aci_init (aci, false);
55
+}
56
+
57
+void
58
+close_local_interfaces (aci_state_t* aci) {
59
+    mraa_result_t error = MRAA_SUCCESS;
60
+
61
+    error = mraa_spi_stop(aci->aci_pins.m_spi);
62
+    if (error != MRAA_SUCCESS) {
63
+
64
+    }
65
+    error = mraa_gpio_close (aci->aci_pins.m_rdy_ctx);
66
+    if (error != MRAA_SUCCESS) {
67
+
68
+    }
69
+    error = mraa_gpio_close (aci->aci_pins.m_req_ctx);
70
+    if (error != MRAA_SUCCESS) {
71
+
72
+    }
73
+    error = mraa_gpio_close (aci->aci_pins.m_rst_ctx);
74
+    if (error != MRAA_SUCCESS) {
75
+
76
+    }
77
+}

+ 35
- 0
src/nrf8001/nrf8001.h 查看文件

@@ -0,0 +1,35 @@
1
+/*
2
+ * Author: Yevgeniy Kiveisha <yevgeniy.kiveisha@intel.com>
3
+ * Copyright (c) 2014 Intel Corporation.
4
+ *
5
+ * Permission is hereby granted, free of charge, to any person obtaining
6
+ * a copy of this software and associated documentation files (the
7
+ * "Software"), to deal in the Software without restriction, including
8
+ * without limitation the rights to use, copy, modify, merge, publish,
9
+ * distribute, sublicense, and/or sell copies of the Software, and to
10
+ * permit persons to whom the Software is furnished to do so, subject to
11
+ * the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be
14
+ * included in all copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+ */
24
+#pragma once
25
+
26
+#include <string>
27
+#include <mraa/aio.h>
28
+#include <mraa/gpio.h>
29
+#include <mraa/spi.h>
30
+
31
+#include <lib_aci.h>
32
+#include <aci_setup.h>
33
+
34
+void init_local_interfaces (aci_state_t* aci, uint8_t reqn, uint8_t rdyn, uint8_t rst);
35
+void close_local_interfaces (aci_state_t* aci);

+ 9
- 0
src/nrf8001/pyupm_nrf8001.i 查看文件

@@ -0,0 +1,9 @@
1
+%module pyupm_nrf8001
2
+%include "../upm.i"
3
+
4
+%feature("autodoc", "3");
5
+
6
+%include "nrf8001.h"
7
+%{
8
+    #include "nrf8001.h"
9
+%}

+ 73
- 0
src/nrf8001/uart_over_ble.h 查看文件

@@ -0,0 +1,73 @@
1
+/*  Copyright (c) 2013, Nordic Semiconductor ASA
2
+ *  All rights reserved.
3
+ *
4
+ *  Redistribution and use in source and binary forms, with or without modification,
5
+ *  are permitted provided that the following conditions are met:
6
+ *
7
+ *  Redistributions of source code must retain the above copyright notice, this
8
+ *  list of conditions and the following disclaimer.
9
+ *
10
+ *  Redistributions in binary form must reproduce the above copyright notice, this
11
+ *  list of conditions and the following disclaimer in the documentation and/or
12
+ *  other materials provided with the distribution.
13
+ *
14
+ *  Neither the name of Nordic Semiconductor ASA nor the names of its
15
+ *  contributors may be used to endorse or promote products derived from
16
+ *  this software without specific prior written permission.
17
+ *
18
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19
+ *  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20
+ *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
+ *  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
22
+ *  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23
+ *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24
+ *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
25
+ *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27
+ *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
+ */
29
+
30
+#ifndef UART_OVER_BLE_H__
31
+#define UART_OVER_BLE_H__
32
+
33
+/**
34
+ * @def UART_OVER_BLE_DISCONNECT
35
+ * @brief
36
+ * Command to queue a ACI Disconnect to the nRF8001
37
+ */
38
+#define UART_OVER_BLE_DISCONNECT      (0x01)
39
+
40
+
41
+/**
42
+ * @def UART_OVER_BLE_LINK_TIMING_REQ
43
+ * @brief
44
+ * Command to queue a ACI Change Timing to the nRF8001
45
+ */
46
+#define UART_OVER_BLE_LINK_TIMING_REQ (0x02)
47
+
48
+/**
49
+ * @def UART_OVER_BLE_TRANSMIT_STOP
50
+ * @brief
51
+ * Command to stop sending UART over BLE packets
52
+ */
53
+#define UART_OVER_BLE_TRANSMIT_STOP   (0x03)
54
+
55
+
56
+/**
57
+ * @def UART_OVER_BLE_TRANSMIT_OK
58
+ * @brief
59
+ * Command to allow sending UART over BLE packets
60
+ */
61
+#define UART_OVER_BLE_TRANSMIT_OK     (0x04)
62
+
63
+typedef struct
64
+{
65
+    uint8_t uart_rts_local;  /* State of the local UART RTS  */
66
+    uint8_t uart_rts_remote; /* State of the remote UART RTS */
67
+} uart_over_ble_t;
68
+
69
+/**
70
+ * @}
71
+ */
72
+
73
+#endif // UART_OVER_BLE_H__