1.目的
IIC通信,
2.分析
3.平台:
协议栈版本:DA1458x_SDK
编译软件:keil 5.20
硬件平台:开发板
例子:DA1458x_SDK5.0.3\DA1458x_SDK5.0.3\DA1458x_SDK\5.0.3\projects\target_apps\ble_examples\prox_reporter\Keil_4
4.步骤
a.添加对应的文件
添加对应的自定义服务问件
这几个文件在如下位置
SDK5.03\DA1458x_SDK1\5.0.3\sdk\ble_stack\profiles\custom
SDK5.03\DA1458x_SDK1\5.0.3\sdk\ble_stack\profiles\custom\custs
SDK5.03\DA1458x_SDK1\5.0.3\sdk\ble_stack\host\att\attm
在custs1.h中添加如下代码,打在自定义的宏
b.然后在prox_reporter\src\config.c文件夹里面建立一个新的文件user_custs_config.h并添加到工程里面 如下:
user_custs_config.h的内容如下
****************************************************************************************
*/
#include
#include "prf_types.h"
#include "attm_db_128.h"
#include "app_prf_types.h"
#include "app_customs.h"
/*
* DEFINES
****************************************************************************************
*/
#define DEF_CUST_SVC_UUID_128 {0x2F, 0x2A, 0x93, 0xA6, 0xBD, 0xD8, 0x41, 0x52, 0xAC, 0x0B, 0x10, 0x99, 0x2E, 0xC6, 0xFE, 0xED}
#define DEF_CUST_WRITE_CHAR_UUID_128 {0x6a,0xdf,0x23,0xc2,0x99,0xbe,0x00,0x80,0x00,0x10,0x66,0xe9,0x00,0x00,0xe6,0xc3}
#define DEF_CUST_READ_CHAR_UUID_128 {0x6a,0xdf,0x23,0xc2,0x99,0xbe,0x00,0x80,0x00,0x10,0x66,0xe9,0x01,0x00,0xe6,0xc3}
#define DEF_CUST_NOTIFY_CHAR_UUID_128 {0x6a,0xdf,0x23,0xc2,0x99,0xbe,0x00,0x80,0x00,0x10,0x66,0xe9,0x02,0x00,0xe6,0xc3}
#define DEF_CUST_CHAR_LEN 1
#define CUST_CHAR_USER_DESC "Custom"
/// CUSTOM Service Data Base Characteristic enum
enum
{
CUST_IDX_SVC = 0,
CUST_IDX_WRITE_CHAR,
CUST_IDX_WRITE_CHAR_VAL,
CUST_IDX_READ_CHAR,
CUST_IDX_READ_CHAR_VAL,
CUST_IDX_NOTIFY_CHAR,
CUST_IDX_NOTIFY_CHAR_VAL,
CUST_IDX_NOTIFY_NTF_CFG,
CUST_IDX_NB,
};
/*
* LOCAL VARIABLES
****************************************************************************************
*/
// Attribues max length used in write/read characteristic actions
static const uint8_t customs_att_max_size[CUST_IDX_NB] =
{
[CUST_IDX_SVC] = 0,
[CUST_IDX_WRITE_CHAR] = 0,
[CUST_IDX_WRITE_CHAR_VAL] = DEF_CUST_CHAR_LEN,
[CUST_IDX_READ_CHAR] = 0,
[CUST_IDX_READ_CHAR_VAL] = DEF_CUST_CHAR_LEN,
[CUST_IDX_NOTIFY_CHAR] = 0,
[CUST_IDX_NOTIFY_CHAR_VAL] = DEF_CUST_CHAR_LEN,
};
/*
* CUSTOM SERVER ATTRIBUTES VALUES DEFINITION
****************************************************************************************
*/
static const att_svc_desc128_t custom_svc = DEF_CUST_SVC_UUID_128;
static uint8_t CUST_WRITE_CHAR_UUID_128[ATT_UUID_128_LEN] = DEF_CUST_WRITE_CHAR_UUID_128;
static uint8_t CUST_READ_CHAR_UUID_128[ATT_UUID_128_LEN] = DEF_CUST_READ_CHAR_UUID_128;
static uint8_t CUST_NOTIFY_CHAR_UUID_128[ATT_UUID_128_LEN] = DEF_CUST_NOTIFY_CHAR_UUID_128;
static const struct att_char128_desc custom_write_char = {ATT_CHAR_PROP_WR,
{0, 0},
DEF_CUST_WRITE_CHAR_UUID_128};
static const struct att_char128_desc custom_read_char = {ATT_CHAR_PROP_RD,
{0, 0},
DEF_CUST_READ_CHAR_UUID_128};
static const struct att_char128_desc custom_notify_char = {ATT_CHAR_PROP_NTF | ATT_CHAR_PROP_RD,
{0, 0},
DEF_CUST_NOTIFY_CHAR_UUID_128};
/*
* CUSTS ATTRIBUTES
****************************************************************************************
*/
static const uint16_t att_decl_svc = ATT_DECL_PRIMARY_SERVICE;
static const uint16_t att_decl_char = ATT_DECL_CHARACTERISTIC;
static const uint16_t att_decl_cfg = ATT_DESC_CLIENT_CHAR_CFG;
static const uint16_t att_decl_user_desc = ATT_DESC_CHAR_USER_DESCRIPTION;
/// Full CUSTOM Database Description - Used to add attributes into the database
static const struct attm_desc_128 custs1_att_db[CUST_IDX_NB] =
{
// CUSTOM Service Declaration
[CUST_IDX_SVC] = {(uint8_t*)&att_decl_svc, ATT_UUID_16_LEN, PERM(RD, ENABLE),
sizeof(custom_svc), sizeof(custom_svc), (uint8_t*)&custom_svc},
// Custom Write Characteristic Declaration
[CUST_IDX_WRITE_CHAR] = {(uint8_t*)&att_decl_char, ATT_UUID_16_LEN, PERM(RD, ENABLE),
sizeof(custom_write_char), sizeof(custom_write_char), (uint8_t*)&custom_write_char},
// Custom Write Characteristic Value
[CUST_IDX_WRITE_CHAR_VAL] = {CUST_WRITE_CHAR_UUID_128, ATT_UUID_128_LEN, PERM(WR, ENABLE),
DEF_CUST_CHAR_LEN, 0, NULL},
// Custom Read Characteristic Declaration [CUST_IDX_READ_CHAR] = {(uint8_t*)&att_decl_char, ATT_UUID_16_LEN, PERM(RD, ENABLE),
sizeof(custom_read_char), sizeof(custom_read_char), (uint8_t*)&custom_read_char},
// Custom Read Characteristic Value
[CUST_IDX_READ_CHAR_VAL] = {CUST_READ_CHAR_UUID_128, ATT_UUID_128_LEN, PERM(RD, ENABLE),
DEF_CUST_CHAR_LEN, 0, NULL},
// Custom Read Characteristic Declaration
[CUST_IDX_NOTIFY_CHAR] = {(uint8_t*)&att_decl_char,
ATT_UUID_16_LEN,
PERM(RD, ENABLE),
sizeof(custom_notify_char),
sizeof(custom_notify_char),
(uint8_t*)&custom_notify_char},
// Custom Characteristic Value [CUST_IDX_NOTIFY_CHAR_VAL] = {CUST_NOTIFY_CHAR_UUID_128,
ATT_UUID_128_LEN,
PERM(RD, ENABLE) | PERM(NTF, ENABLE),
DEF_CUST_CHAR_LEN,
0,
NULL},
// Custom Characteristic - Client Characteristic Configuration Descriptor
[CUST_IDX_NOTIFY_NTF_CFG] = {(uint8_t*)&att_decl_cfg,
ATT_UUID_16_LEN,
PERM(RD, ENABLE)|PERM(WR, ENABLE),
sizeof(uint16_t),
0,
NULL},
};
/*
* LOCAL VARIABLES
****************************************************************************************
*/
/// Custom1/2 server function callback table
static const struct cust_prf_func_callbacks cust_prf_funcs[] =
{
#if (BLE_CUSTOM1_SERVER)
{ TASK_CUSTS1,
custs1_att_db,
CUST_IDX_NB,
#if (BLE_APP_PRESENT)
app_custs1_create_db,
app_custs1_enable,
#else
NULL, NULL,
#endif
custs1_init, NULL
},
#endif
#if (BLE_CUSTOM2_SERVER)
{ TASK_CUSTS2,
NULL,
0,
#if (BLE_APP_PRESENT)
app_custs2_create_db, app_custs2_enable,
#else
NULL, NULL,
#endif
custs2_init, NULL
},
#endif
{TASK_NONE, NULL, 0, NULL, NULL, NULL, NULL},// DO NOT MOVE. Must always be last
};
/// @} USER_CONFIG
#endif // _USER_CUSTS_CONFIG_H_
c.在user_proxr.c里面整体代码如下
/**
****************************************************************************************
*
* @file app_proxr_proj.c
*
* @brief Proximity project source code .
*
* Copyright (C) 2012. Dialog Semiconductor Ltd, unpublished work. This computer
* program includes Confidential, Proprietary Information and is a Trade Secret of
* Dialog Semiconductor Ltd. All use, disclosure, and/or reproduction is prohibited
* unless authorized in writing. All Rights Reserved.
*
* and contributors.
*****************************************************************************************
*/
/**
****************************************************************************************
* @addtogroup APP
* @{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include "rwip_config.h" // SW configuration
#include "user_periph_setup.h" // SW configuration
#include "wkupct_quadec.h" // SW configuration
#include "app_default_handlers.h"
#include "app_callback.h"
#include "app_easy_msg_utils.h"
#include "gpio.h"
#include "user_callback_config.h"
#include "app_security.h"
#include "user_proxr.h"
#include "arch_api.h"
#include "app_task.h"
//add code
#include "user_custs_config.h"
#include "custs1_task.h"
#include "prf_utils.h"
#if defined(__DA14583__) && (!SPOTAR_SPI_DISABLE)
#include "spi_flash.h"
#endif
//add 2161206
uint8_t char_value =11;
uint8_t notify_value =0x00;
timer_hnd notify_timer;
/*
* FUNCTION DEFINITIONS
****************************************************************************************
*/
/**
****************************************************************************************
* @brief Handles APP_WAKEUP_MSG sent when device exits deep sleep. Trigerred by button press.
*
* @param[in] msgid Id of the message received.
* @param[in] param Pointer to the parameters of the message.
* @param[in] dest_id ID of the receiving task instance (TASK_GAP).
* @param[in] src_id ID of the sending task instance.
*
* @return If the message was consumed or not.
* @return int.
****************************************************************************************
*/
void app_wakeup_cb(void)
{
// If state is not idle, ignore the message
if (ke_state_get(TASK_APP) == APP_CONNECTABLE)
//app_adv_start();
EXECUTE_DEFAULT_OPERATION_VOID(default_operation_adv);
}
/**
****************************************************************************************
* @brief Button press callback function. Registered in WKUPCT driver.
*
* @return void.
****************************************************************************************
*/
void app_button_press_cb(void)
{
#if BLE_PROX_REPORTER
if (alert_state.lvl != PROXR_ALERT_NONE)
{
app_proxr_alert_stop();
}
else
#endif
{
#if BLE_FINDME_LOCATOR
if (ke_state_get(TASK_FINDL) == FINDL_CONNECTED)
{
app_findl_set_alert();
}
#endif
}
if(GetBits16(SYS_STAT_REG, PER_IS_DOWN))
periph_init();
if (arch_ble_ext_wakeup_get())
{
arch_set_sleep_mode(app_default_sleep_mode);
//SetBits32(GP_CONTROL_REG, BLE_WAKEUP_REQ, 1);
arch_ble_force_wakeup( );
arch_ble_ext_wakeup_off();
// ke_msg_send_basic(APP_WAKEUP_MSG, TASK_APP, 0);
app_easy_wakeup();
}
app_button_enable();
}
/**
****************************************************************************************
* @brief Enable push button. Register callback function for button press event. Must be called in periph_init();
*
* @return void.
****************************************************************************************
*/
void app_button_enable(void)
{
app_easy_wakeup_set(app_wakeup_cb);
wkupct_register_callback(app_button_press_cb);
#if USE_PUSH_BUTTON
if (GPIO_GetPinStatus( GPIO_BUTTON_PORT, GPIO_BUTTON_PIN ))
wkupct_enable_irq(WKUPCT_PIN_SELECT(GPIO_BUTTON_PORT, GPIO_BUTTON_PIN), // select pin (GPIO_BUTTON_PORT, GPIO_BUTTON_PIN)
WKUPCT_PIN_POLARITY(GPIO_BUTTON_PORT, GPIO_BUTTON_PIN, WKUPCT_PIN_POLARITY_LOW), // polarity low
1, // 1 event
0); // debouncing time = 0
#endif
}
#if BLE_SPOTA_RECEIVER
/**
****************************************************************************************
* @brief SPOTAR session start or stop event handler.
*
* @param[in] spotar_event SPOTAR_START/SPOTAR_STOP
*
* @return void
****************************************************************************************
*/
void on_spotar_status_change( const uint8_t spotar_event)
{
#if defined(__DA14583__) && (!SPOTAR_SPI_DISABLE)
int8_t man_dev_id = 0;
man_dev_id = spi_flash_enable(SPI_EN_GPIO_PORT, SPI_EN_GPIO_PIN);
if (man_dev_id == SPI_FLASH_AUTO_DETECT_NOT_DETECTED)
{
// The device was not identified. The default parameters are used.
// Alternatively, an error can be asserted here.
spi_flash_init(SPI_FLASH_DEFAULT_SIZE, SPI_FLASH_DEFAULT_PAGE);
}
if( spotar_event == SPOTAR_END )
{
// Power down SPI Flash
spi_flash_power_down();
}
#endif
}
#endif // (BLE_SPOTA_RECEIVER)
void app_advertise_complete (const uint8_t param)
{
#if BLE_PROX_REPORTER
app_proxr_alert_stop();
#endif
// disable wakeup for BLe and timer events. Only external (GPIO) wakeup events can wakeup processor.
if (param == GAP_ERR_CANCELED)
arch_ble_ext_wakeup_on();
app_button_enable();
default_app_on_adv_undirect_complete(param);
return;
}
//Ìí¼Ó´úÂë
static void notify_charactertistic_update(void)
{
// Information get in the DB
att_size_t att_length;
uint8_t *att_value;
attmdb_att_get_value(custs1_env.shdl + CUST_IDX_NOTIFY_NTF_CFG,&att_length, &att_value);
// Send indication through GATT
if ((uint16_t)*((uint16_t*)&att_value[0]) == PRF_CLI_START_NTF)
{
notify_value++;
// // Update Database
// attmdb_att_set_value(custs1_env.shdl + CUST_IDX_NOTIFY_CHAR_VAL,
// DEF_CUST_CHAR_LEN, (uint8_t *)¬ify_value);
prf_server_send_event((prf_env_struct *)&custs1_env, false,
custs1_env.shdl + CUST_IDX_NOTIFY_CHAR_VAL);
// Restart timer
//notify_timer = app_easy_timer(100, notify_charactertistic_update);
}
app_easy_timer(100, notify_charactertistic_update);
}
void user_app_on_connection(uint8_t connection_idx, struct gapc_connection_req_ind const *param)
{
default_app_on_connection(connection_idx, param);
app_easy_timer(100, notify_charactertistic_update);
}
void user_app_on_disconnect( struct gapc_disconnect_ind const *param )
{
default_app_on_disconnect(param);
app_easy_timer_cancel(notify_timer);
}
void user_on_db_init_complete( void )
{
default_app_on_db_init_complete();
// Set initial values in Database
attmdb_att_set_value(custs1_env.shdl + CUST_IDX_READ_CHAR_VAL,
DEF_CUST_CHAR_LEN, (uint8_t *)&char_value);
}
//ϵͳ»Øµ÷º¯Êý
void user_catch_rest_hndl(ke_msg_id_t const msgid,
void const *param,
ke_task_id_t const dest_id,
ke_task_id_t const src_id)
{
uint16_t temp = 0;
switch(msgid)
{
case CUSTS1_VAL_WRITE_IND:
{
struct custs1_val_write_ind const *msg_param = (struct custs1_val_write_ind const *)(param);
switch (msg_param->handle)
{
case CUST_IDX_WRITE_CHAR_VAL:
{
// Set new value based on written value
char_value = msg_param->value[0];
// Update value in Database
attmdb_att_set_value(custs1_env.shdl + CUST_IDX_READ_CHAR_VAL,
DEF_CUST_CHAR_LEN, (uint8_t *)&char_value);
break;
}
}
}
case CUSTS1_VAL_SET_REQ :
{
}
break;
case CUSTS1_VAL_IND_CFM:
{
}
break;
case CUSTS1_VAL_NTF_CFM:
break;
case CUSTS1_VAL_NTF_REQ:
{
}
break;
}
}
/// @} APP
/**
****************************************************************************************
*
* @file user_proxr.h
*
* @brief Proximity Project application header file.
*
* Copyright (C) 2015. Dialog Semiconductor Ltd, unpublished work. This computer
* program includes Confidential, Proprietary Information and is a Trade Secret of
* Dialog Semiconductor Ltd. All use, disclosure, and/or reproduction is prohibited
* unless authorized in writing. All Rights Reserved.
*
* and contributors.
*
****************************************************************************************
*/
#ifndef _USER_PROXR_H_
#define _USER_PROXR_H_
/**
****************************************************************************************
* @addtogroup APP
* @ingroup RICOW
*
* @brief User Application entry point.
*
* @{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include "rwble_config.h"
#include "app.h" // application definitions
#include "arch_api.h" // error code definitions
/*
* TYPE DEFINITIONS
****************************************************************************************
*/
/*
* DEFINES
****************************************************************************************
*/
/*
* FUNCTION DECLARATIONS
****************************************************************************************
*/
void app_button_enable(void);
void user_app_on_connection(uint8_t connection_idx, struct gapc_connection_req_ind const *param);
void user_app_on_disconnect( struct gapc_disconnect_ind const *param );
void user_on_db_init_complete( void );
void user_catch_rest_hndl(ke_msg_id_t const msgid,
void const *param,
ke_task_id_t constdest_id,
ke_task_id_t constsrc_id);
/// @} APP
#endif // _USER_PROXR_H_
在user_profiles_config.h里面添加头文件
编译程序 下载进芯片,用lightbule 打开蓝牙,如下 定义的uuid就是我们刚才在user_custs_config.h里面定义的UUID
打开最有一个特征值,点击linsen to notifitions 结果如下 收到了数据
注意:参考了网上别人的资料,在此基础上做了优化