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