Init commit with many years of arduino sketches and projects. I dont know if the esp8266 includes much, but there are also libraries. I hope they dont have crazy automatic versioning through the Arduino IDE.

This commit is contained in:
2019-05-30 23:41:53 +02:00
parent 2d047634f2
commit 6c84b31f2c
1480 changed files with 198581 additions and 0 deletions

View File

@@ -0,0 +1,608 @@
/* Copyright (c) 2010 Nordic Semiconductor. All Rights Reserved.
*
* The information contained herein is property of Nordic Semiconductor ASA.
* Terms and conditions of usage are described in detail in NORDIC
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
*
* Licensees are granted free, non-transferable use of the information. NO
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
* the file.
*
* $LastChangedRevision$
*/
/**
* @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__
/**
* @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_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_pipe_type_t;
/**
* @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_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_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_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_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_test_mode_change_t;
/**
* @enum aci_permissions_t
* @brief Data store permissions
*/
typedef enum
{
ACI_PERMISSIONS_NONE =0x00,
ACI_PERMISSIONS_LINK_AUTHENTICATED =0x01
} 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_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_tx_data_t;
/**
* @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_rx_data_t;
/**
* @enum aci_hw_error_t
* @brief Hardware Error codes
*/
typedef enum
{
ACI_HW_ERROR_NONE = 0x00,
ACI_HW_ERROR_FATAL = 0x01
} 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_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_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_gatt_format_t;
/**
* @brief GATT Bluetooth namespace
*/
typedef enum
{
ACI_GATT_NAMESPACE_INVALID = 0x00,
ACI_GATT_NAMESPACE_BTSIG = 0x01 /**< Bluetooth SIG */
} aci_gatt_namespace_t;
/**
* @brief Security key types
*/
typedef enum
{
ACI_KEY_TYPE_INVALID = 0x00,
ACI_KEY_TYPE_PASSKEY = 0x01
} 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_bond_status_code_t;
/**
* @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_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_status_code_t;
/**
* @}
*/
#endif // ACI_H__

View File

@@ -0,0 +1,404 @@
/* Copyright (c) 2010 Nordic Semiconductor. All Rights Reserved.
*
* The information contained herein is property of Nordic Semiconductor ASA.
* Terms and conditions of usage are described in detail in NORDIC
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
*
* Licensees are granted free, non-transferable use of the information. NO
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
* the file.
*
* $LastChangedRevision$
*/
/**
* @file
*
* @ingroup aci
*
* @brief Definitions for the ACI (Application Control Interface) commands
* @remarks
*
*/
#ifndef ACI_CMDS_H__
#define ACI_CMDS_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_cmd_opcode_t;
/**
* @struct aci_cmd_params_test_t
* @brief Structure for the ACI_CMD_TEST ACI command parameters
*/
typedef struct
{
uint8_t test_mode_change; /**< enum aci_test_mode_change_t */
} aci_cmd_params_test_t;
/**
* @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_cmd_params_echo_t;
/**
* @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_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_cmd_params_setup_t;
/**
* @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_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_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_cmd_params_connect_t;
/**
* @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_cmd_params_bond_t;
/**
* @struct aci_cmd_params_disconnect_t
* @brief Structure for the ACI_CMD_DISCONNECT ACI command parameters
*/
typedef struct
{
uint8_t reason; /**< enum aci_disconnect_reason_t */
} aci_cmd_params_disconnect_t;
/**
* @struct aci_cmd_params_set_tx_power_t
* @brief Structure for the ACI_CMD_SET_TX_POWER ACI command parameters
*/
typedef struct
{
uint8_t device_power; /**< enum aci_device_output_power_t */
} aci_cmd_params_set_tx_power_t;
/**
* @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_cmd_params_change_timing_t;
/**
* @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_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_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_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_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_cmd_params_send_data_nack_t;
/**
* @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_cmd_params_set_app_latency_t;
/**
* @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_cmd_params_set_key_t;
/**
* @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_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_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_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 */
uint8_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_cmd_t;
#endif // ACI_CMDS_H__

View File

@@ -0,0 +1,364 @@
/* Copyright (c) 2010 Nordic Semiconductor. All Rights Reserved.
*
* The information contained herein is property of Nordic Semiconductor ASA.
* Terms and conditions of usage are described in detail in NORDIC
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
*
* Licensees are granted free, non-transferable use of the information. NO
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
* the file.
*
* $LastChangedRevision$
*/
/**
* @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_evt_opcode_t;
/**
* @struct aci_evt_params_device_started_t
* @brief Structure for the ACI_EVT_DEVICE_STARTED event return parameters
*/
typedef struct
{
uint8_t device_mode; /**< enum aci_device_operation_mode_t -> Mode in which the device is being started */
uint8_t hw_error; /**< enum aci_hw_error_t -> Hardware Error if available for the start */
uint8_t credit_available; /**< Flow control credit available for this specific FW build */
} aci_evt_params_device_started_t;
/**
* @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_evt_params_hw_error_t;
/**
* @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_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_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_evt_cmd_rsp_params_get_device_version_t;
/**
* @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];
uint8_t bd_addr_type; /**< enum aci_bd_addr_type_t */
} aci_evt_cmd_rsp_params_get_device_address_t;
/**
* @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_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_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
{
uint8_t cmd_opcode; /**< enum aci_cmd_opcode_t -> Command opcode for which the event response is being sent */
uint8_t cmd_status; /**< enum aci_status_code_t -> 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_evt_params_cmd_rsp_t;
/**
* @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 */
uint8_t master_clock_accuracy; /**< enum aci_clock_accuracy_t -> Clock accuracy of Bluetooth master: Enumerated list of values from 500 ppm to 20 ppm */
} aci_evt_params_connected_t;
/**
* @struct aci_evt_params_disconnected_t
* @brief Structure for the ACI_EVT_DISCONNECTED event return parameters
*/
typedef struct
{
uint8_t aci_status; /**< enum aci_status_code_t */
uint8_t btle_status;
} aci_evt_params_disconnected_t;
/**
* @struct aci_evt_params_bond_status_t
* @brief Structure for the ACI_EVT_BOND_STATUS event return parameters
*/
typedef struct
{
uint8_t status_code;
uint8_t status_source; /**< enum aci_bond_status_source_t */
uint8_t secmode1_bitmap;
uint8_t secmode2_bitmap;
uint8_t keys_exchanged_slave;
uint8_t keys_exchanged_master;
} aci_evt_params_bond_status_t;
/**
* @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_evt_params_pipe_status_t;
/**
* @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_evt_params_timing_t;
/**
* @struct aci_evt_params_data_credit_t
* @brief Structure for the ACI_EVT_DATA_CREDIT event return parameters
*/
typedef struct
{
uint8_t credit;
} 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_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_evt_params_data_received_t;
typedef struct
{
uint8_t content[1];
} 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_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_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
{
uint8_t key_type; /**< enum aci_key_type_t */
} 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_evt_params_echo_t;
/**
* @struct aci_evt_t
* @brief Encapsulates a generic ACI event
*/
typedef struct
{
uint8_t len;
uint8_t evt_opcode; /** enum aci_evt_opcode_t */
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_evt_t;
#endif // ACI_EVTS_H__

View File

@@ -0,0 +1,178 @@
/* Copyright (c) 2009 Nordic Semiconductor. All Rights Reserved. *
* *
* The information contained herein is property of Nordic Semiconductor ASA.*
* Terms and conditions of usage are described in detail in NORDIC *
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT. *
* *
* Licensees are granted free, non-transferable use of the information. NO *
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from *
* the file. *
* */
/* *
* 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 0
#define OFFSET_ACI_CMD_PARAMS_SET_APP_LATENCY_T_LATENCY_MSB 1
#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__

View File

@@ -0,0 +1,131 @@
/* Copyright (c) 2009 Nordic Semiconductor. All Rights Reserved.
*
* The information contained herein is property of Nordic Semiconductor ASA.
* Terms and conditions of usage are described in detail in NORDIC
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
*
* Licensees are granted free, non-transferable use of the information. NO
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
* the file.
*
* $LastChangedRevision$
*/
/**
* My project template
*/
#include <avr/pgmspace.h>
#include <ble_system.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)
static hal_aci_evt_t aci_data;
static hal_aci_data_t aci_cmd;
aci_status_code_t aci_setup(aci_state_t *aci_stat, uint8_t num_cmds, uint8_t num_cmd_offset)
{
uint8_t i = 0;
uint8_t evt_count = 0;
aci_evt_t * aci_evt = NULL;
while (i < num_cmds)
{
//Copy the setup ACI message from Flash to RAM
//Add 2 bytes to the length byte for status byte, length for the total number of bytes
memcpy_P(&aci_cmd, &(aci_stat->aci_setup_info.setup_msgs[num_cmd_offset+i]),
pgm_read_byte_near(&(aci_stat->aci_setup_info.setup_msgs[num_cmd_offset+i].buffer[0]))+2);
//Put the Setup ACI message in the command queue
if (!hal_aci_tl_send(&aci_cmd))
{
Serial.println(F("Cmd Queue Full"));
return ACI_STATUS_ERROR_INTERNAL;
}
else
{
//Debug messages:
//Serial.print(F("Setup msg"));
//Serial.println(i, DEC);
}
i++;
}
while (1)
{
//We will sit here if we do not get the same number of command response evts as the commands sent to the ACI
//
//@check The setup wil fail in the while(1) below when the 32KHz source for the nRF8001 is in-correct in the setup generated in the nRFgo studio
if (true == lib_aci_event_get(aci_stat, &aci_data))
{
aci_evt = &aci_data.evt;
evt_count++;
if (ACI_EVT_CMD_RSP != aci_evt->evt_opcode )
{
//Got something other than a command response evt -> Error
return ACI_STATUS_ERROR_INTERNAL;
}
if (!((ACI_STATUS_TRANSACTION_CONTINUE == aci_evt->params.cmd_rsp.cmd_status) ||
(ACI_STATUS_TRANSACTION_COMPLETE == aci_evt->params.cmd_rsp.cmd_status)))
{
return (aci_status_code_t )aci_evt->params.cmd_rsp.cmd_status;
}
else
{
//Serial.print(F("Cmd Response Evt "));
//Serial.println(evt_count);
}
if (num_cmds == evt_count)
{
break;
}
}
}
return ((aci_status_code_t)aci_evt->params.cmd_rsp.cmd_status);
}
aci_status_code_t do_aci_setup(aci_state_t *aci_stat)
{
aci_status_code_t status = ACI_STATUS_ERROR_CRC_MISMATCH;
uint8_t i=0;
if(ACI_QUEUE_SIZE >= aci_stat->aci_setup_info.num_setup_msgs)
{
status = aci_setup(aci_stat, aci_stat->aci_setup_info.num_setup_msgs, 0);
}
else
{
for(i=0; i<(aci_stat->aci_setup_info.num_setup_msgs/ACI_QUEUE_SIZE); i++)
{
//Serial.print(ACI_QUEUE_SIZE, DEC);
//Serial.print(F(" "));
//Serial.println(0+(ACI_QUEUE_SIZE*i), DEC);
status = aci_setup(aci_stat, ACI_QUEUE_SIZE, (ACI_QUEUE_SIZE*i));
}
if ((aci_stat->aci_setup_info.num_setup_msgs % ACI_QUEUE_SIZE) != 0)
{
status = aci_setup(aci_stat, aci_stat->aci_setup_info.num_setup_msgs % ACI_QUEUE_SIZE, (ACI_QUEUE_SIZE*i));
}
}
return status;
}

View File

@@ -0,0 +1,12 @@
#ifndef H_ACI_SETUP
#define H_ACI_SETUP
#define ACI_CMD_Q_SIZE 16
/**
Do the ACI setup by sending the setup messages generated by the nRFgo studio to the nRF8001.
After all the setup messages are sent. The nRF8001 will send a Device Started Event (Mode = STANDBY)
*/
aci_status_code_t do_aci_setup(aci_state_t *aci_stat);
#endif

View File

@@ -0,0 +1,602 @@
/* Copyright (c) 2010 Nordic Semiconductor. All Rights Reserved.
*
* The information contained herein is property of Nordic Semiconductor ASA.
* Terms and conditions of usage are described in detail in NORDIC
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
*
* Licensees are granted free, non-transferable use of the information. NO
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
* the file.
*
* $LastChangedRevision$
*/
/**
* @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;
}

View File

@@ -0,0 +1,53 @@
/* Copyright (c) 2010 Nordic Semiconductor. All Rights Reserved.
*
* The information contained herein is property of Nordic Semiconductor ASA.
* Terms and conditions of usage are described in detail in NORDIC
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
*
* Licensees are granted free, non-transferable use of the information. NO
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
* the file.
*
* $LastChangedRevision$
*/
/**
* @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_ */

View File

@@ -0,0 +1,29 @@
/* Copyright (c) 2010 Nordic Semiconductor. All Rights Reserved.
*
* The information contained herein is property of Nordic Semiconductor ASA.
* Terms and conditions of usage are described in detail in NORDIC
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
*
* Licensees are granted free, non-transferable use of the information. NO
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
* the file.
*
* $LastChangedRevision$
*/
/**
* @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_ */

View File

@@ -0,0 +1,463 @@
/* Copyright (c) 2010 Nordic Semiconductor. All Rights Reserved.
*
* The information contained herein is property of Nordic Semiconductor ASA.
* Terms and conditions of usage are described in detail in NORDIC
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
*
* Licensees are granted free, non-transferable use of the information. NO
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
* the file.
*
* $LastChangedRevision$
*/
/**
* @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_ */

View File

@@ -0,0 +1,25 @@
/* Copyright (c) 2010 Nordic Semiconductor. All Rights Reserved.
*
* The information contained herein is property of Nordic Semiconductor ASA.
* Terms and conditions of usage are described in detail in NORDIC
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
*
* Licensees are granted free, non-transferable use of the information. NO
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
* the file.
*
* $LastChangedRevision$
*/
/**
* @file
*
* @ingroup group_acilib
*
* @brief Type used in the acilib interfaces
*/
#ifndef _acilib_TYPES_H_
#define _acilib_TYPES_H_
#endif /* _acilib_TYPES_H_ */

View File

@@ -0,0 +1,22 @@
#ifndef BLE_SYSTEM_H_
#define BLE_SYSTEM_H
/*
#define HAL_IO_RADIO_CSN SS
#define HAL_IO_RADIO_REQN SS
#define HAL_IO_RADIO_RDY 3
#define HAL_IO_RADIO_SCK SCK
#define HAL_IO_RADIO_MOSI MOSI
#define HAL_IO_RADIO_MISO MISO
#define HAL_IO_RADIO_RESET 9
#define HAL_IO_RADIO_ACTIVE 8
//#define HAL_IO_LED0 2
//#define HAL_IO_LED1 6
*/
#define ENABLE_INTERRUPTS() sei()
#define DISABLE_INTERRUPTS() cli()
#define ARE_INTERRUPTS_ENABLED() ((SREG & 0x80) == 0x80)
#endif

View File

@@ -0,0 +1,55 @@
/* Copyright (c) 2010 Nordic Semiconductor. All Rights Reserved.
*
* The information contained herein is property of Nordic Semiconductor ASA.
* Terms and conditions of usage are described in detail in NORDIC
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
*
* Licensees are granted free, non-transferable use of the information. NO
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
* the file.
*
* $LastChangedRevision$
*/
/**
* @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 <20> 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__
/** @} */

View File

@@ -0,0 +1,108 @@
/* Copyright (c) 2009 Nordic Semiconductor. All Rights Reserved.
*
* The information contained herein is property of Nordic Semiconductor ASA.
* Terms and conditions of usage are described in detail in NORDIC
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
*
* Licensees are granted free, non-transferable use of the information. NO
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
* the file.
*
* $LastChangedRevision$
*/
/** @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"
#ifndef HAL_ACI_MAX_LENGTH
#define HAL_ACI_MAX_LENGTH 31
#endif //HAL_ACI_MAX_LENGTH
#define ACI_QUEUE_SIZE 8
/** Data type for ACI commands and events */
typedef struct hal_aci_data_t{
uint8_t status_byte;
uint8_t buffer[HAL_ACI_MAX_LENGTH+1];
} hal_aci_data_t;
/** @brief Message received hook function.
* @details A hook function that must be implemented by the client of this module.
* The function will be called by this module when a new message has been received from the nRF8001.
* @param received_msg Pointer to a structure containing a pointer to the received data.
*/
extern void hal_aci_tl_msg_rcv_hook(hal_aci_data_t *received_msg);
/** ACI Transport Layer configures inputs/outputs.
*/
void hal_aci_tl_io_config(void);
/** ACI Transport Layer initialization.
*/
void hal_aci_tl_init(void);
/**@brief Sends an ACI command to the radio.
* @details
* This function sends an ACI command to the radio. This will memorize the pointer of the message to send and
* lower the request line. When the device lowers the ready line, @ref hal_aci_tl_poll_rdy_line() will send the data.
* @param aci_buffer Pointer to the message to send.
* @return True if the send is started successfully, false if a transaction is already running.
*/
bool hal_aci_tl_send(hal_aci_data_t *aci_buffer);
/** @brief Check for pending transaction.
* @details
* Call this function from the main context at regular intervals to check if the nRF8001 RDYN line indicates a pending transaction.
* If a transaction is pending, this function will treat it and call the receive hook.
*/
void hal_aci_tl_poll_rdy_line(void);
hal_aci_data_t * hal_aci_tl_poll_get(void);
bool hal_aci_tl_event_get(hal_aci_data_t *p_aci_data);
/** @brief Flush the ACI command Queue and the ACI Event Queue
* @details
* Call this function in the main thread
*/
void m_aci_q_flush(void);
/** @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_debug_print(bool enable);
#endif // HAL_ACI_TL_H__
/** @} */

View File

@@ -0,0 +1,71 @@
/* Copyright (c) 2009 Nordic Semiconductor. All Rights Reserved.
*
* The information contained herein is property of Nordic Semiconductor ASA.
* Terms and conditions of usage are described in detail in NORDIC
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
*
* Licensees are granted free, non-transferable use of the information. NO
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
* the file.
*
* $LastChangedRevision$
*/
/** @file
*/
/** @defgroup hal_io hal_io
* @{
* @ingroup hal
* @brief Macros input/output management
*/
#include "hal_platform.h"
#ifndef HAL_IO_H__
#define HAL_IO_H__
#define HAL_IO_P00 PIN0
#define HAL_IO_P01 PIN1
#define HAL_IO_P02 PIN2
#define HAL_IO_P03 PIN3
#define HAL_IO_P04 PIN4
#define HAL_IO_P05 PIN5
#define HAL_IO_P06 PIN6
#define HAL_IO_P07 PIN7
#define HAL_IO_P08 PIN8
#define HAL_IO_P09 PIN9
#define HAL_IO_OUTPUT OUTPUT
#define HAL_IO_INPUT INPUT
/**@brief Macro to configure an I/O.
* @details
* This macro configures a given I/O to input or output with pullup/buffer configuration.
* @param io_name I/O to configure.
* @param is_input Indicate if the I/O is to be set as an input.
* @param io_mode Pull resistor and buffer configuration (must be HAL_IO_OUTPUT_NORMAL_STRENGTH, HAL_IO_OUTPUT_HIGH_STRENGTH, HAL_IO_INPUT_BUF_ON_NO_PULL,
* HAL_IO_INPUT_BUF_ON_PULL_DOWN, HAL_IO_INPUT_BUF_ON_PULL_UP, or HAL_IO_INPUT_BUF_OFF).
*/
#define HAL_IO_CONFIG(io_name, is_input, io_mode) pinMode(io_name, is_input)
/**@brief Macro to set an output.
* @details
* This macro sets the given output to the given level (1 -> high, 0 -> low).
* @param io_name Output to change.
* @param io_state Level to set.
*/
#define HAL_IO_SET_STATE(io_name, io_state) digitalWrite(io_name, io_state)
/**@brief Macro that reads the current state of an input.
* @details
* This macro reads the current state of a logical input.
* @param io_name Input to read.
* @return Input state level (1 if high, 0 if low).
*/
#define HAL_IO_READ(io_name) digitalRead(io_name)
#endif //HAL_IO_H__
/** @} */

View File

@@ -0,0 +1,425 @@
/* Copyright (c) 2009 Nordic Semiconductor. All Rights Reserved.
*
* The information contained herein is property of Nordic Semiconductor ASA.
* Terms and conditions of usage are described in detail in NORDIC
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
*
* Licensees are granted free, non-transferable use of the information. NO
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
* the file.
*
* $LastChangedRevision: 4808 $
*/
/** @file
@brief Implementation of the ACI transport layer module
*/
#include <SPI.h>
#include "hal_platform.h"
#include "hal/hal_aci_tl.h"
#include "hal/hal_io.h"
#include "ble_system.h"
#include <avr/sleep.h>
extern int8_t HAL_IO_RADIO_RESET, HAL_IO_RADIO_REQN, HAL_IO_RADIO_RDY, HAL_IO_RADIO_IRQ;
static const uint8_t dreqinttable[] = {
#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) || defined (__AVR_ATmega328__) || defined(__AVR_ATmega8__)
2, 0,
3, 1,
#elif defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1280__)
2, 0,
3, 1,
21, 2,
20, 3,
19, 4,
18, 5,
#elif defined(__AVR_ATmega32U4__) && defined(CORE_TEENSY)
5, 0,
6, 1,
7, 2,
8, 3,
#elif defined(__AVR_AT90USB1286__) && defined(CORE_TEENSY)
0, 0,
1, 1,
2, 2,
3, 3,
36, 4,
37, 5,
18, 6,
19, 7,
#elif defined(__arm__) && defined(CORE_TEENSY)
0, 0, 1, 1, 2, 2, 3, 3, 4, 4,
5, 5, 6, 6, 7, 7, 8, 8, 9, 9,
10, 10, 11, 11, 12, 12, 13, 13, 14, 14,
15, 15, 16, 16, 17, 17, 18, 18, 19, 19,
20, 20, 21, 21, 22, 22, 23, 23, 24, 24,
25, 25, 26, 26, 27, 27, 28, 28, 29, 29,
30, 30, 31, 31, 32, 32, 33, 33,
#elif defined(__AVR_ATmega32U4__)
7, 4,
3, 0,
2, 1,
0, 2,
1, 3,
#elif defined(__AVR_ATmega256RFR2__)
4, 0,
5, 1,
15, 2,
16, 3,
13, 4,
14, 5,
7, 6,
18, 7,
#endif
};
static void m_print_aci_data(hal_aci_data_t *p_data);
typedef struct {
hal_aci_data_t aci_data[ACI_QUEUE_SIZE];
uint8_t head;
uint8_t tail;
} aci_queue_t;
static hal_aci_data_t received_data;
static uint8_t spi_readwrite(uint8_t aci_byte);
static bool aci_debug_print;
static aci_queue_t aci_tx_q;
static aci_queue_t aci_rx_q;
static void m_aci_q_init(aci_queue_t *aci_q)
{
uint8_t loop;
aci_debug_print = false;
aci_q->head = 0;
aci_q->tail = 0;
for(loop=0; loop<ACI_QUEUE_SIZE; loop++)
{
aci_tx_q.aci_data[loop].buffer[0] = 0x00;
aci_tx_q.aci_data[loop].buffer[1] = 0x00;
}
}
void hal_aci_debug_print(bool enable)
{
aci_debug_print = enable;
}
static bool m_aci_q_enqueue(aci_queue_t *aci_q, hal_aci_data_t *p_data)
{
const uint8_t next = (aci_q->tail + 1) % ACI_QUEUE_SIZE;
const uint8_t length = p_data->buffer[0];
if (next == aci_q->head)
{
/* full queue */
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 = next;
return true;
}
//@comment after a port have test for the queue states, esp. the full and the empty states
static bool m_aci_q_dequeue(aci_queue_t *aci_q, hal_aci_data_t *p_data)
{
if (aci_q->head == aci_q->tail)
{
/* empty queue */
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;
}
static bool m_aci_q_is_empty(aci_queue_t *aci_q)
{
return (aci_q->head == aci_q->tail);
}
static bool m_aci_q_is_full(aci_queue_t *aci_q)
{
uint8_t next;
bool state;
//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;
}
void m_print_aci_data(hal_aci_data_t *p_data)
{
const uint8_t length = p_data->buffer[0];
uint8_t i;
Serial.print(length, DEC);
Serial.print(" :");
for (i=0; i<=length; i++)
{
Serial.print(p_data->buffer[i], HEX);
Serial.print(F(", "));
}
Serial.println(F(""));
}
void toggle_eimsk(bool state)
{
/* ToDo: This will currently only work with the UNO/ATMega48/88/128/328 */
/* due to EIMSK. Abstract this away to something MCU nuetral! */
uint8_t eimsk_bit = 0xFF;
for (uint8_t i=0; i<sizeof(dreqinttable); i+=2) {
if (HAL_IO_RADIO_RDY == dreqinttable[i]) {
eimsk_bit = dreqinttable[i+1];
}
}
if (eimsk_bit != 0xFF)
{
if (state)
EIMSK |= (1 << eimsk_bit);
else
EIMSK &= ~(1 << eimsk_bit);
}
else
{
/* RDY isn't a valid HW INT pin! */
while(1);
}
}
void m_rdy_line_handle(void)
{
hal_aci_data_t *p_aci_data;
sleep_disable();
detachInterrupt(HAL_IO_RADIO_IRQ);
// Receive or transmit data
p_aci_data = hal_aci_tl_poll_get();
// Check if we received data
if (p_aci_data->buffer[0] > 0)
{
if (!m_aci_q_enqueue(&aci_rx_q, p_aci_data))
{
/* Receive Buffer full.
Should never happen.
Spin in a while loop.
*/
while(1);
}
if (m_aci_q_is_full(&aci_rx_q))
{
/* Disable RDY line interrupt.
Will latch any pending RDY lines, so when enabled it again this
routine should be taken again */
toggle_eimsk(false);
}
}
}
bool hal_aci_tl_event_get(hal_aci_data_t *p_aci_data)
{
bool was_full = m_aci_q_is_full(&aci_rx_q);
if (m_aci_q_dequeue(&aci_rx_q, p_aci_data))
{
if (true == aci_debug_print)
{
Serial.print(" E");
m_print_aci_data(p_aci_data);
}
if (was_full)
{
toggle_eimsk(true);
}
return true;
}
else
{
return false;
}
}
void hal_aci_tl_init()
{
received_data.buffer[0] = 0;
SPI.begin();
SPI.setBitOrder(LSBFIRST);
SPI.setClockDivider(SPI_CLOCK_DIV8);
SPI.setDataMode(SPI_MODE0);
/* initialize aci cmd queue */
m_aci_q_init(&aci_tx_q);
m_aci_q_init(&aci_rx_q);
//Configure the IO lines
pinMode(HAL_IO_RADIO_RESET, OUTPUT);
pinMode(HAL_IO_RADIO_RDY, INPUT_PULLUP);
pinMode(HAL_IO_RADIO_REQN, OUTPUT);
digitalWrite(HAL_IO_RADIO_RESET, 1);
delay(100);
digitalWrite(HAL_IO_RADIO_RESET, 0);
digitalWrite(HAL_IO_RADIO_RESET, 1);
digitalWrite(SCK, 0);
digitalWrite(MOSI, 0);
digitalWrite(HAL_IO_RADIO_REQN, 1);
digitalWrite(SCK, 0);
HAL_IO_RADIO_IRQ = 0xFF;
for (uint8_t i=0; i<sizeof(dreqinttable); i+=2) {
if (HAL_IO_RADIO_RDY == dreqinttable[i]) {
HAL_IO_RADIO_IRQ = dreqinttable[i+1];
}
}
delay(30); //Wait for the nRF8001 to get hold of its lines - the lines float for a few ms after the reset
if (HAL_IO_RADIO_IRQ != 0xFF)
attachInterrupt(HAL_IO_RADIO_IRQ, m_rdy_line_handle, LOW);
// We use the LOW level of the RDYN line as the atmega328 can wakeup from sleep only on 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;
}
else
{
if (m_aci_q_enqueue(&aci_tx_q, p_aci_cmd))
{
ret_val = true;
}
}
if (true == aci_debug_print)
{
Serial.print("C");
m_print_aci_data(p_aci_cmd);
}
HAL_IO_SET_STATE(HAL_IO_RADIO_REQN, 0);
return ret_val;
}
hal_aci_data_t * hal_aci_tl_poll_get(void)
{
uint8_t byte_cnt;
uint8_t byte_sent_cnt;
uint8_t max_bytes;
hal_aci_data_t data_to_send;
//SPI.begin();
HAL_IO_SET_STATE(HAL_IO_RADIO_REQN, 0);
// Receive from queue
if (m_aci_q_dequeue(&aci_tx_q, &data_to_send) == false)
{
/* queue was empty, nothing to send */
data_to_send.status_byte = 0;
data_to_send.buffer[0] = 0;
}
//Change this if your mcu has DMA for the master SPI
// 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++]);
}
HAL_IO_SET_STATE(HAL_IO_RADIO_REQN, 1);
//SPI.end()
//RDYN should follow the REQN line in approx 100ns
sleep_enable();
attachInterrupt(HAL_IO_RADIO_IRQ, m_rdy_line_handle, LOW);
if (false == m_aci_q_is_empty(&aci_tx_q))
{
//Lower the REQN line to start a new ACI transaction
HAL_IO_SET_STATE(HAL_IO_RADIO_REQN, 0);
}
/* valid Rx available or transmit finished*/
return (&received_data);
}
static uint8_t spi_readwrite(const uint8_t aci_byte)
{
return SPI.transfer(aci_byte);
}
void m_aci_q_flush(void)
{
noInterrupts();
/* re-initialize aci cmd queue and aci event queue to flush them*/
m_aci_q_init(&aci_tx_q);
m_aci_q_init(&aci_rx_q);
interrupts();
}

View File

@@ -0,0 +1,69 @@
/* Copyright (c) 2011 Nordic Semiconductor. All Rights Reserved.
*
* The information contained herein is property of Nordic Semiconductor ASA.
* Terms and conditions of usage are described in detail in NORDIC
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
*
* Licensees are granted free, non-transferable use of the information. NO
* WARRENTY of ANY KIND is provided. This heading must NOT be removed from
* the file.
*
* $LastChangedRevision$
*/
#ifndef PLATFORM_H__
#define PLATFORM_H__
/** @file
* @brief
*/
#include "Arduino.h"
#define hal_pltf_clear_spi_master_config() do { SPCR = 0; } while(0)
//SPI2X=1 SPS0=1 SPR0=1 -> 250KHz
//DORD=1 LSBit first
//SPE=1 Enable the SPI
//MSTR=1 Enable master mode
//CPOL=0 See Section 7 in the nRF8001 PS (Clock Polarity)
//CPHA=0 See Section 7 in the nRF8001 PS (Clock Phase)
/*
Atmega328
Table 18-5. Relationship Between SCK and the Oscillator Frequency
SPI2X SPR1 SPR0 SCK Frequency
0 0 0 fosc/4
0 0 1 fosc/16
0 1 0 fosc/64
0 1 1 fosc/128
1 0 0 fosc/2
1 0 1 fosc/8
1 1 0 fosc/32
1 1 1 fosc/64
*/
/*
#define hal_pltf_spi_master_config() do { \
pinMode(SCK, OUTPUT);\
pinMode(MOSI, OUTPUT);\
pinMode(SS, OUTPUT);\
pinMode(MISO, INPUT);\
digitalWrite(SCK, LOW);\
digitalWrite(MOSI, LOW);\
digitalWrite(SS, HIGH);\
SPCR = 0; \
SPSR = 0; \
SPSR = (1<<SPI2X);\
SPCR = ((1<<SPE)|(1<<MSTR)|(0<<SPR1) | (1<<SPR0) | (1<<DORD) | (0<<CPOL) | (0<<CPHA));}\
while(0)
*/
#define hal_pltf_enable_spi() do { SPCR |= _BV(SPE); } while(0)
#define hal_pltf_disable_spi() do { SPCR &= ~_BV(SPE); } while(0)
#define hal_pltf_configure_spi_for_aci() do{\
hal_pltf_spi_master_config();\
}while(0)
#endif /* PLATFORM_H__ */

View File

@@ -0,0 +1,645 @@
/* Copyright (c) 2009 Nordic Semiconductor. All Rights Reserved.
*
* The information contained herein is property of Nordic Semiconductor ASA.
* Terms and conditions of usage are described in detail in NORDIC
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
*
* Licensees are granted free, non-transferable use of the information. NO
* WARRENTY of ANY KIND is provided. This heading must NOT be removed from
* the file.
*
* $LastChangedRevision: 4808 $
*/
/* Attention!
* To maintain compliance with Nordic Semiconductor ASA<53>s Bluetooth profile
* qualification listings, this section of source code must not be modified.
*/
/** @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/hal_aci_tl.h"
#include "lib_aci.h"
#define LIB_ACI_DEFAULT_CREDIT_NUMBER 1
static services_pipe_type_mapping_t * p_services_pipe_type_map;
static uint8_t pipe_count;
static hal_aci_data_t * p_setup_msgs;
static uint8_t setup_msgs_count;
static hal_aci_data_t msg_to_send;
static hal_aci_data_t *p_rcvd_evt;
static uint8_t cur_transaction_cmd;
static uint8_t memorized_rcvd_cmd_opcode;
static uint8_t memorized_transaction_cmd_opcode;
static bool is_cmd_response_expected;
static uint16_t cx_rf_interval; // rf_interval = cx_rf_interval * 1.25 ms Range:0x0006 to 0x0C80
static uint16_t current_slave_latency;
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;
static uint8_t cur_error_code;
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_init(aci_state_t *aci_stat)
{
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;
cur_transaction_cmd = ACI_CMD_INVALID;
memorized_rcvd_cmd_opcode = ACI_CMD_INVALID;
memorized_transaction_cmd_opcode = ACI_CMD_INVALID;
cx_rf_interval = 0;
current_slave_latency = 0;
request_operation_pipe = 0;
indicate_operation_pipe = 0;
cur_error_code = 0;
p_rcvd_evt = NULL;
p_services_pipe_type_map = aci_stat->aci_setup_info.services_pipe_type_mapping;
pipe_count = aci_stat->aci_setup_info.number_of_pipes;
p_setup_msgs = aci_stat->aci_setup_info.setup_msgs;
setup_msgs_count = aci_stat->aci_setup_info.num_setup_msgs;
hal_aci_tl_init();
}
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 multiple 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);
is_cmd_response_expected = false;
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_get(aci_state_t *aci_stat, hal_aci_evt_t *p_aci_evt_data)
{
bool status;
status = hal_aci_tl_event_get((hal_aci_data_t *)p_aci_evt_data);
/**
Update the state of the ACI witn the
ACI Events -> Pipe Status, Disconnected, Connected, Bond Status, Pipe Error
*/
{
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;
}
}
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);
is_cmd_response_expected = false;
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;
{
is_cmd_response_expected = 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)
{
m_aci_q_flush();
}
void lib_aci_debug_print(bool enable)
{
hal_aci_debug_print(enable);
}

View File

@@ -0,0 +1,507 @@
/* Copyright (c) 2009 Nordic Semiconductor. All Rights Reserved.
*
* The information contained herein is property of Nordic Semiconductor ASA.
* Terms and conditions of usage are described in detail in NORDIC
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
*
* Licensees are granted free, non-transferable use of the information. NO
* WARRENTY of ANY KIND is provided. This heading must NOT be removed from
* the file.
*
* $LastChangedRevision$
*/
/* Attention!
* To maintain compliance with Nordic Semiconductor ASA<53>s Bluetooth profile
* qualification listings, this section of source code must not be modified.
*/
#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)
*/
#include "hal_platform.h"
#include "hal/hal_aci_tl.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 hal_aci_evt_t{
uint8_t debug_byte;
aci_evt_t evt;
} hal_aci_evt_t;
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_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 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.
*/
void lib_aci_init(aci_state_t *aci_stat);
/** @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&nbsp;ms.
* @return Connection interval in multiple of 1.25&nbsp;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&nbsp;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&nbsp;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&nbsp;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&nbsp;ms.
* @param maximum_cx_interval Maximum connection interval requested, in multiple of 1.25&nbsp;ms.
* @param slave_latency requested slave latency.
* @param timeout requested slave timeout, in multiple of 10&nbsp;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 Flushes the events in the ACI command queues and ACI Event queue
*
*/
void lib_aci_flush(void);
//@}
/** @} */
#endif /* LIB_ACI_H__ */

View File

@@ -0,0 +1,142 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE AttributeServer>
<Profile Version="1.3">
<SetupId>0</SetupId>
<Device>nRF8001_Dx</Device>
<Service Type="local" PrimaryService="true">
<Name>UART over BTLE</Name>
<Uuid BaseUUID="6e400000b5a3f393e0a9e50e24dcca9e" BaseUUIDName="Custom UART">0001</Uuid>
<Characteristic>
<Name>UART RX</Name>
<Uuid BaseUUID="6e400000b5a3f393e0a9e50e24dcca9e" BaseUUIDName="Custom UART">0002</Uuid>
<DefaultValue></DefaultValue>
<UsePresentationFormat>0</UsePresentationFormat>
<UserDescription></UserDescription>
<MaxDataLength>20</MaxDataLength>
<AttributeLenType>2</AttributeLenType>
<ForceOpen>false</ForceOpen>
<Properties>
<WriteWithoutResponse>true</WriteWithoutResponse>
<Write>false</Write>
<Notify>false</Notify>
<Indicate>false</Indicate>
<Broadcast>false</Broadcast>
</Properties>
<SetPipe>false</SetPipe>
<AckIsAuto>false</AckIsAuto>
<PresentationFormatDescriptor Value="0000" Exponent="0" Format="1" NameSpace="01" Unit="0000"/>
<PeriodForReadingThisCharacteristic>0</PeriodForReadingThisCharacteristic>
<PeriodForProperties/>
</Characteristic>
<Characteristic>
<Name>UART TX</Name>
<Uuid BaseUUID="6e400000b5a3f393e0a9e50e24dcca9e" BaseUUIDName="Custom UART">0003</Uuid>
<DefaultValue></DefaultValue>
<UsePresentationFormat>0</UsePresentationFormat>
<UserDescription></UserDescription>
<MaxDataLength>20</MaxDataLength>
<AttributeLenType>2</AttributeLenType>
<ForceOpen>false</ForceOpen>
<Properties>
<WriteWithoutResponse>false</WriteWithoutResponse>
<Write>false</Write>
<Notify>true</Notify>
<Indicate>false</Indicate>
<Broadcast>false</Broadcast>
</Properties>
<SetPipe>false</SetPipe>
<AckIsAuto>false</AckIsAuto>
<PresentationFormatDescriptor Value="0000" Exponent="0" Format="1" NameSpace="01" Unit="0000"/>
<PeriodForReadingThisCharacteristic>0</PeriodForReadingThisCharacteristic>
<PeriodForProperties/>
</Characteristic>
</Service>
<Service Type="local" PrimaryService="true">
<Name>Device Information</Name>
<Uuid>180a</Uuid>
<Characteristic>
<Name>Hardware Revision String</Name>
<Uuid>2a27</Uuid>
<DefaultValue>0A</DefaultValue>
<UsePresentationFormat>0</UsePresentationFormat>
<UserDescription></UserDescription>
<MaxDataLength>9</MaxDataLength>
<AttributeLenType>2</AttributeLenType>
<ForceOpen>false</ForceOpen>
<Properties>
<WriteWithoutResponse>false</WriteWithoutResponse>
<Write>false</Write>
<Notify>false</Notify>
<Indicate>false</Indicate>
<Broadcast>false</Broadcast>
</Properties>
<SetPipe>true</SetPipe>
<AckIsAuto>false</AckIsAuto>
<PresentationFormatDescriptor Value="0000" Exponent="0" Format="25" NameSpace="01" Unit="0000"/>
<PeriodForReadingThisCharacteristic>0</PeriodForReadingThisCharacteristic>
<PeriodForProperties/>
</Characteristic>
</Service>
<Gapsettings>
<Name>UART</Name>
<DeviceNameWriteLength>7</DeviceNameWriteLength>
<LocalPipeOnDeviceName>true</LocalPipeOnDeviceName>
<DeviceNameShortLength>0</DeviceNameShortLength>
<Apperance>0000</Apperance>
<SecurityLevel>0</SecurityLevel>
<AuthenticationReq>0</AuthenticationReq>
<IoCapabilities>0</IoCapabilities>
<BondTimeout>600</BondTimeout>
<SecurityRequestDelay>0</SecurityRequestDelay>
<MinimumKeySize>7</MinimumKeySize>
<MaximumKeySize>16</MaximumKeySize>
<AdvertisingDataBondedBitmap>1a</AdvertisingDataBondedBitmap>
<AdvertisingDataGeneralBitmap>1a</AdvertisingDataGeneralBitmap>
<AdvertisingDataBrodcastBitmap>10</AdvertisingDataBrodcastBitmap>
<AdvertisingDataBondedScanResponseBitmap>0</AdvertisingDataBondedScanResponseBitmap>
<AdvertisingDataGeneralScanResponseBitmap>0</AdvertisingDataGeneralScanResponseBitmap>
<AdvertisingDataBrodcastScanResponseBitmap>0</AdvertisingDataBrodcastScanResponseBitmap>
<AdvertisingDataBondedBitmapCustom>0</AdvertisingDataBondedBitmapCustom>
<AdvertisingDataGeneralBitmapCustom>0</AdvertisingDataGeneralBitmapCustom>
<AdvertisingDataBrodcastBitmapCustom>0</AdvertisingDataBrodcastBitmapCustom>
<AdvertisingDataBondedScanResponseBitmapCustom>0</AdvertisingDataBondedScanResponseBitmapCustom>
<AdvertisingDataGeneralScanResponseBitmapCustom>0</AdvertisingDataGeneralScanResponseBitmapCustom>
<AdvertisingDataBrodcastScanResponseBitmapCustom>0</AdvertisingDataBrodcastScanResponseBitmapCustom>
<TxPowerLevelOffset>0</TxPowerLevelOffset>
<MinimumConnectionInterval>6</MinimumConnectionInterval>
<MaximumConnectionInterval>18</MaximumConnectionInterval>
<SlaveLatency>0</SlaveLatency>
<TimeoutMultipler>10</TimeoutMultipler>
<ServiceToAdvertise>
<Uuid BaseUUID="6e400000b5a3f393e0a9e50e24dcca9e" BaseUUIDName="Custom UART">0001</Uuid>
</ServiceToAdvertise>
<CustomAdTypes>
<AdType index="1">
<Type>19</Type>
<Value>0000</Value>
</AdType>
<AdType index="2">
<Type>18</Type>
<Value></Value>
</AdType>
</CustomAdTypes>
</Gapsettings>
<Hardwaresettings>
<Clocksource>1</Clocksource>
<ClockAccuracy>1</ClockAccuracy>
<InitialTxPower>3</InitialTxPower>
<HfClkSource>0</HfClkSource>
<DcDcConverter>0</DcDcConverter>
<ActiveSignalModeIndex>0</ActiveSignalModeIndex>
<ActiveSignalToTickDistance>0</ActiveSignalToTickDistance>
<DynamicWindowLimitingEnabled>false</DynamicWindowLimitingEnabled>
</Hardwaresettings>
<CurrentInput>
<BatteryCharge>220</BatteryCharge>
<Master32KhzClockAccuracy>10</Master32KhzClockAccuracy>
<ConnectionInterval>1000</ConnectionInterval>
<PercentOfTimeSleeping>10</PercentOfTimeSleeping>
<PercentOfTimeAdvertising>10</PercentOfTimeAdvertising>
<AdvertisingInterval>1280</AdvertisingInterval>
</CurrentInput>
</Profile>

View File

@@ -0,0 +1,164 @@
/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved.
*
* The information contained herein is property of Nordic Semiconductor ASA.
* Terms and conditions of usage are described in detail in NORDIC
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
*
* Licensees are granted free, non-transferable use of the information. NO
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
* the file.
*/
/**
* This file is autogenerated by nRFgo Studio 1.14.1.2369
*/
#ifndef SETUP_MESSAGES_H__
#define SETUP_MESSAGES_H__
#include "hal_platform.h"
#include "aci.h"
#define PIPE_GAP_DEVICE_NAME_SET 1
#define PIPE_UART_OVER_BTLE_UART_RX_RX 2
#define PIPE_UART_OVER_BTLE_UART_TX_TX 3
#define PIPE_DEVICE_INFORMATION_HARDWARE_REVISION_STRING_SET 4
#define NUMBER_OF_PIPES 4
#define SERVICES_PIPE_TYPE_MAPPING_CONTENT {\
{ACI_STORE_LOCAL, ACI_SET}, \
{ACI_STORE_LOCAL, ACI_RX}, \
{ACI_STORE_LOCAL, ACI_TX}, \
{ACI_STORE_LOCAL, ACI_SET}, \
}
#define GAP_PPCP_MAX_CONN_INT 0x12 /**< Maximum connection interval as a multiple of 1.25 msec , 0xFFFF means no specific value requested */
#define GAP_PPCP_MIN_CONN_INT 0x6 /**< 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 0xa /** Connection Supervision timeout multiplier as a multiple of 10msec, 0xFFFF means no specific value requested */
#define NB_SETUP_MESSAGES 21
#define SETUP_MESSAGES_CONTENT {\
{0x00,\
{\
0x07,0x06,0x00,0x00,0x03,0x02,0x41,0xd7,\
},\
},\
{0x00,\
{\
0x1f,0x06,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x04,0x01,0x01,0x00,0x00,0x06,0x00,0x00,\
0x90,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
},\
},\
{0x00,\
{\
0x1f,0x06,0x10,0x1c,0x01,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
0x00,0x00,0x00,0x14,0x00,0x00,0x00,0x14,0x03,0x90,0x01,0x64,\
},\
},\
{0x00,\
{\
0x1f,0x06,0x10,0x38,0x02,0xff,0x02,0x58,0x00,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
0x00,0x10,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,0x07,\
},\
},\
{0x00,\
{\
0x1f,0x06,0x20,0x1c,0x04,0x00,0x03,0x2a,0x00,0x01,0x55,0x41,0x52,0x54,0x69,0x63,0x73,0x04,0x04,0x05,\
0x05,0x00,0x04,0x28,0x03,0x01,0x02,0x05,0x00,0x01,0x2a,0x06,\
},\
},\
{0x00,\
{\
0x1f,0x06,0x20,0x38,0x04,0x03,0x02,0x00,0x05,0x2a,0x01,0x01,0x00,0x00,0x04,0x04,0x05,0x05,0x00,0x06,\
0x28,0x03,0x01,0x02,0x07,0x00,0x04,0x2a,0x06,0x04,0x09,0x08,\
},\
},\
{0x00,\
{\
0x1f,0x06,0x20,0x54,0x00,0x07,0x2a,0x04,0x01,0x06,0x00,0x12,0x00,0x00,0x00,0x0a,0x00,0x04,0x04,0x02,\
0x02,0x00,0x08,0x28,0x00,0x01,0x01,0x18,0x04,0x04,0x10,0x10,\
},\
},\
{0x00,\
{\
0x1f,0x06,0x20,0x70,0x00,0x09,0x28,0x00,0x01,0x9e,0xca,0xdc,0x24,0x0e,0xe5,0xa9,0xe0,0x93,0xf3,0xa3,\
0xb5,0x01,0x00,0x40,0x6e,0x04,0x04,0x13,0x13,0x00,0x0a,0x28,\
},\
},\
{0x00,\
{\
0x1f,0x06,0x20,0x8c,0x03,0x01,0x04,0x0b,0x00,0x9e,0xca,0xdc,0x24,0x0e,0xe5,0xa9,0xe0,0x93,0xf3,0xa3,\
0xb5,0x02,0x00,0x40,0x6e,0x44,0x10,0x14,0x00,0x00,0x0b,0x00,\
},\
},\
{0x00,\
{\
0x1f,0x06,0x20,0xa8,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x04,0x13,0x13,0x00,0x0c,\
},\
},\
{0x00,\
{\
0x1f,0x06,0x20,0xc4,0x28,0x03,0x01,0x10,0x0d,0x00,0x9e,0xca,0xdc,0x24,0x0e,0xe5,0xa9,0xe0,0x93,0xf3,\
0xa3,0xb5,0x03,0x00,0x40,0x6e,0x14,0x00,0x14,0x00,0x00,0x0d,\
},\
},\
{0x00,\
{\
0x1f,0x06,0x20,0xe0,0x00,0x03,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x46,0x14,0x03,0x02,0x00,\
},\
},\
{0x00,\
{\
0x1f,0x06,0x20,0xfc,0x0e,0x29,0x02,0x01,0x00,0x00,0x04,0x04,0x02,0x02,0x00,0x0f,0x28,0x00,0x01,0x0a,\
0x18,0x04,0x04,0x05,0x05,0x00,0x10,0x28,0x03,0x01,0x02,0x11,\
},\
},\
{0x00,\
{\
0x19,0x06,0x21,0x18,0x00,0x27,0x2a,0x04,0x04,0x09,0x01,0x00,0x11,0x2a,0x27,0x01,0x0a,0x00,0x00,0x00,\
0x00,0x00,0x00,0x00,0x00,0x00,\
},\
},\
{0x00,\
{\
0x1f,0x06,0x40,0x00,0x2a,0x00,0x01,0x00,0x80,0x04,0x00,0x03,0x00,0x00,0x00,0x02,0x02,0x00,0x08,0x04,\
0x00,0x0b,0x00,0x00,0x00,0x03,0x02,0x00,0x02,0x04,0x00,0x0d,\
},\
},\
{0x00,\
{\
0x0f,0x06,0x40,0x1c,0x00,0x0e,0x2a,0x27,0x01,0x00,0x80,0x04,0x00,0x11,0x00,0x00,\
},\
},\
{0x00,\
{\
0x13,0x06,0x50,0x00,0x9e,0xca,0xdc,0x24,0x0e,0xe5,0xa9,0xe0,0x93,0xf3,0xa3,0xb5,0x00,0x00,0x40,0x6e,\
},\
},\
{0x00,\
{\
0x0f,0x06,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\
},\
},\
{0x00,\
{\
0x06,0x06,0xf0,0x00,0x03,0xd3,0x88,\
},\
},\
}
#endif

View File

@@ -0,0 +1,117 @@
------------------------------------------------------------------------------
uBlue Setup generation report
Generated with uBlue setup DLL version: 1.0.0.16855
Generated: Sat Jan 12 11:40:44 2013 (UTC)
This file is automatically generated, do not modify
------------------------------------------------------------------------------
[Counts]
Setup data size = 547 bytes
Local database size = 302 bytes
Local attribute count = 4
Remote attribute count = 0
Total pipe count = 4
Dynamic data size = 181 bytes (worst case)
[Setup Area Layout]
Setup area, total = 1595 bytes
Setup area, used = 370 bytes ( 23% of total )
Local services = 302 bytes ( 81% of used )
Remote services = 0 bytes ( 0% of used )
Pipes = 40 bytes ( 10% of used )
VS UUID area = 16 bytes ( 4% of used )
Extended Attr area = 12 bytes ( 3% of used )
[Device Settings]
Setup ID = 0x00000000
Setup Format = 0x03
Security = OPEN (0)
Bond Timeout = 600
Security Request Delay = 0
Change Timing Delay = 5
Whitelist = Enabled
[Advertisement Data]
Bond Advertise = 0x00000014 [SERVICES_128_COMPLETE | LOCAL_NAME_COMPLETE]
Bond Scan Resp = 0x00000000 []
General Advertise = 0x00000014 [SERVICES_128_COMPLETE | LOCAL_NAME_COMPLETE]
General Scan Resp = 0x00000000 []
Broadcast Advertise = 0x00000010 [LOCAL_NAME_COMPLETE]
Broadcast Scan Resp = 0x00000000 []
Custom Bond Advertise = 0x00 []
Custom Bond Scan Resp = 0x00 []
Custom General Advertise = 0x00 []
Custom General Scan Resp = 0x00 []
Custom Broadcast Advertise = 0x00 []
Custom Broadcast Scan Resp = 0x00 []
No custom AD types
[Vendor Specific UUIDs]
VS UUID #0 (type=0x02): 0x9E 0xCA 0xDC 0x24 0x0E 0xE5 0xA9 0xE0 0x93 0xF3 0xA3 0xB5 0x00 0x00 0x40 0x6E
[Local Database]
Handle Pipes Structure
------ ----- ---------
0x0001 +----- Service (Primary): "GAP" (01:0x1800)
0x0002 |----- |Characteristic: "Device Name" (01:0x2A00) [rd|wwr|wr] [rd:allow|wr:none]
0x0003 x |Value: {0x55 0x41 0x52 0x54} [rd:allow|wr:allow]
0x0004 |----- |Characteristic: "Appearance" (01:0x2A01) [rd] [rd:allow|wr:none]
0x0005 |Value: {0x00 0x00} [rd:allow|wr:none]
0x0006 |----- |Characteristic: "PPCP" (01:0x2A04) [rd] [rd:allow|wr:none]
0x0007 |Value: {0x06 0x00 0x12 0x00 0x00 0x00 0x0A 0x00} [rd:allow|wr:none]
0x0008 +----- Service (Primary): "GATT" (01:0x1801)
0x0009 +----- Service (Primary): "?" (02:0x0001)
0x000A |----- |Characteristic: "?" (02:0x0002) [wwr] [rd:allow|wr:none]
0x000B < |Value: {} [rd:none|wr:allow]
0x000C |----- |Characteristic: "?" (02:0x0003) [not] [rd:allow|wr:none]
0x000D > |Value: {} [rd:none|wr:none]
0x000E |----- |Descriptor: "Client Characteristic Configuration" (01:0x2902) Value: {0x00 0x00} [rd:allow|wr:allow]
0x000F +----- Service (Primary): "Device Info" (01:0x180A)
0x0010 |----- |Characteristic: "HW Rev" (01:0x2A27) [rd] [rd:allow|wr:none]
0x0011 x |Value: {0x0A} [rd:allow|wr:none]
[Remote Database]
Handle Pipes Structure
------ ----- ---------
[Pipe Map]
Pipe Store Type Service Char. CPF Desc.
---- ------ ------ ---------- --------- ----------- ---------
01 Local SET 01:0x1800 01:0x2A00 -- --
02 Local RX 02:0x0001 02:0x0002 -- --
03 Local TX 02:0x0001 02:0x0003 -- --
04 Local SET 01:0x180A 01:0x2A27 -- --
[Setup Data]
07-06-00-00-03-02-41-D7
1F-06-10-00-00-00-00-00-00-00-04-00-04-01-01-00-00-06-00-00-90-00-00-00-00-00-00-00-00-00-00-00
1F-06-10-1C-01-02-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-14-00-00-00-14-03-90-01-64
1F-06-10-38-02-FF-02-58-00-05-00-00-00-00-00-00-00-00-00-00-00-10-00-00-00-00-00-00-00-00-00-00
05-06-10-54-00-00
1F-06-20-00-04-04-02-02-00-01-28-00-01-00-18-04-04-05-05-00-02-28-03-01-0E-03-00-00-2A-04-14-07
1F-06-20-1C-04-00-03-2A-00-01-55-41-52-54-69-63-73-04-04-05-05-00-04-28-03-01-02-05-00-01-2A-06
1F-06-20-38-04-03-02-00-05-2A-01-01-00-00-04-04-05-05-00-06-28-03-01-02-07-00-04-2A-06-04-09-08
1F-06-20-54-00-07-2A-04-01-06-00-12-00-00-00-0A-00-04-04-02-02-00-08-28-00-01-01-18-04-04-10-10
1F-06-20-70-00-09-28-00-01-9E-CA-DC-24-0E-E5-A9-E0-93-F3-A3-B5-01-00-40-6E-04-04-13-13-00-0A-28
1F-06-20-8C-03-01-04-0B-00-9E-CA-DC-24-0E-E5-A9-E0-93-F3-A3-B5-02-00-40-6E-44-10-14-00-00-0B-00
1F-06-20-A8-02-02-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-04-04-13-13-00-0C
1F-06-20-C4-28-03-01-10-0D-00-9E-CA-DC-24-0E-E5-A9-E0-93-F3-A3-B5-03-00-40-6E-14-00-14-00-00-0D
1F-06-20-E0-00-03-02-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-46-14-03-02-00
1F-06-20-FC-0E-29-02-01-00-00-04-04-02-02-00-0F-28-00-01-0A-18-04-04-05-05-00-10-28-03-01-02-11
19-06-21-18-00-27-2A-04-04-09-01-00-11-2A-27-01-0A-00-00-00-00-00-00-00-00-00
1F-06-40-00-2A-00-01-00-80-04-00-03-00-00-00-02-02-00-08-04-00-0B-00-00-00-03-02-00-02-04-00-0D
0F-06-40-1C-00-0E-2A-27-01-00-80-04-00-11-00-00
13-06-50-00-9E-CA-DC-24-0E-E5-A9-E0-93-F3-A3-B5-00-00-40-6E
0F-06-60-00-00-00-00-00-00-00-00-00-00-00-00-00
06-06-F0-00-83-42-00