dear dialog support,
my name is Kevin. i have 2 project and i am using ble_peripheral_example as my basic. and i am using DA14580 devkit basic. i still confuse about where i should put my program.
1. i want to turn on led when da14580 is connected to any bluetooth device, and turn off led when da14580 is not conected to any devices. also when it is connected i want it to go to the sleep mode, but i want to wake it up every time i give command via ble, but when it is disconnect, da14580 goes to arch_ext_sleep.
2.当我按下按钮2次时,我要打开LED,然后导致LED一段时间,然后再次关闭。如果按钮仅按1次,则无效。我使用的按钮是使用中断唤醒MCU的相同按钮。以下是user_peripheral.c中的程序,是否正确?
/ **
****************************************************************************************
*
* @file user_peripheral.c.
*
* @brief外围项目源代码。
*
*版权所有(c)2015.对话半导体有限公司yabo国际娱乐未发表的工作。这台电脑
* program includes Confidential, Proprietary Information and is a Trade Secret of
* Dialog Semiconductor Ltd. All use, disclosure, and/or reproduction is prohibited
*除非书面授权。版权所有。
*
* and contributors.
*
****************************************************************************************
* /
/ **
****************************************************************************************
* @addtogroup APP
* @ {
****************************************************************************************
* /
/ *
*包括文件
****************************************************************************************
* /
#include“rwip_config.h”// sw配置
#include“user_peripheral.h”
#include "user_custs1_impl.h"
#include "arch_api.h"
#include“user_custs1_def.h”
#include "gap.h"
#include "pwm.h"
#include“app_default_handlers.h”
#include "wkupct_quadec.h"
#include "gpio.h"
#include“user_periph_setup.h”
/ *
*类型定义
****************************************************************************************
* /
//制造商特定数据adv结构类型
struct mnf_specific_data_ad_structure.
{
uint8_t ad_structure_size;
uint8_t ad_structure_type;
UINT8_T 亚博全网COMPANY_ID [APP_AD_MSD_COMPANY_ID_LEN];
UINT8_T PREARIETARY_DATA [APP_AD_MSD_DATA_LEN];
};
/ *
* GLOBAL VARIABLE DEFINITIONS
****************************************************************************************
* /
uint8_t app_connection_idx;
timer_hnd app_add_data_update_timer_used;
timer_hnd app_param_update_request_timer_used;
// Manufacturer Specific Data
struct mnf_specific_data_ad_structure mnf_data __attribute __((部分(“保留_mem_area0”),zero_init));// @保留记忆
/ *
*功能定义
****************************************************************************************
* /
/ **
****************************************************************************************
* @brief Initialize Manufacturer Specific Data
* @return void.
****************************************************************************************
* /
静态void mnf_data_init()
{
mnf_data.ad_structure_size = sizeof(struct mnf_specific_data_ad_structure) - sizeof(uint8_t);//减去ad_structure_size字段的大小
mnf_data.ad_structure_type = GAP_AD_TYPE_MANU_SPECIFIC_DATA;
mnf_data.company_id[0] = APP_AD_MSD_COMPANY_ID & 0xFF; // LSB
mnf_data.亚博全网company_id [1] =(app_ad_msd_company_id >> 8)&0xff;// MSB.
mnf_data.proprietary_data[0] = 0;
mnf_data.proprietary_data[1] = 0;
}
/ **
****************************************************************************************
* @brief更新制造商特定数据
* @return void.
****************************************************************************************
* /
static void mnf_data_update()
{
uint16_t data;
data = mnf_data.proprietary_data [0] |(mnf_data.proprietary_data [1] << 8);
数据+ = 1;
mnf_data.proprietary_data[0] = data & 0xFF;
mnf_data.proprietary_data[1] = (data >> 8) & 0xFF;
if (data == 0xFFFF) {
mnf_data.proprietary_data[0] = 0;
mnf_data.proprietary_data[1] = 0;
}
}
/ **
****************************************************************************************
* @brief广告数据定时器更新回调函数。
* @return void.
****************************************************************************************
* /
static void adv_data_update_timer_cb()
{
app_easy_gap_advertise_stop();
}
/ **
****************************************************************************************
* @brief参数更新请求定时器回调函数。
* @return void.
****************************************************************************************
* /
静态void param_update_request_timer_cb()
{
app_easy_gap_param_update_start(app_connection_idx);
app_param_update_request_timer_used = EASY_TIMER_INVALID_TIMER;
}
void user_app_init(void)
{
app_param_update_request_timer_used = EASY_TIMER_INVALID_TIMER;
// Initialize Manufacturer Specific Data
mnf_data_init();
default_app_on_init();
}
/ **
* @brief Add an AD structure in the Advertising or Scan Response Data of the GAPM_START_ADVERTISE_CMD parameter struct.
* @param[in] cmd GAPM_START_ADVERTISE_CMD parameter struct
* @param [in] ad_struct_data广告结构缓冲区
* @param[in] ad_struct_len AD structure length
* @return void.
* /
静态void app_add_ad_struct(struct gapm_start_advertise_cmd * cmd,void * ad_struct_data,uint8_t ad_struct_len)
{
if((app_add_data_max_size - cmd-> info.host.adv_data_len)> = ad_struct_len)
{
//复制数据
memcpy(&cmd-> info.host.addata [cmd-> info.host.adrstruct_data,ad_struct_len));
// Update Advertising Data Length
cmd->info.host.adv_data_len += ad_struct_len;
}
否则if((app_scan_resp_data_max_size - cmd-> info.host.scan_rsp_data_len)> = ad_struct_len)
{
//复制数据
memcpy(&cmd-> info.host.scan_rsp_data [cmd-> info.host.scan_rsp_data_len],ad_struct_data,ad_struct_len);
//更新扫描回应数据长度
cmd->info.host.scan_rsp_data_len += ad_struct_len;
}
别的
{
// Manufacturer Specific Data do not fit in either Advertising Data or Scan Response Data
assert_error(0);
}
}
void user_app_adv_start(void)
{
// Schedule the next advertising data update
app_add_data_update_timer_used = app_easy_timer(app_add_data_update_to,avd_data_update_timer_cb);
struct gapm_start_advertise_cmd * cmd;
cmd = app_easy_gap_undirected_advertise_get_active();
//动态添加制造商特定数据
mnf_data_update();
app_add_ad_struct(cmd,&mnf_data,sizeof(struct mnf_specific_data_ad_structure));
app_easy_gap_undircated_advertise_start();
}
void user_app_connection(uint8_t connection_idx, struct gapc_connection_req_ind const *param)
{
if(app_env [connection_idx] .conidx!= gap_invalid_conidx)
{
app_connection_idx = connection_idx;
// Stop the advertising data update timer
app_easy_timer_cancel(app_add_data_update_timer_used);
//检查已建立连接的参数是否是首选的参数。
//如果没有,则计划连接参数更新请求。
if ((param->con_interval < user_connection_param_conf.intv_min) ||
(param-> con_interval> user_connection_param_conf.intv_max)||
(param->con_latency != user_connection_param_conf.latency) ||
(param-> sup_to!= user_connection_param_conf.time_out))
{
// Connection params are not these that we expect
app_param_update_request_timer_used = app_easy_timer(app_param_update_request_to,param_update_request_timer_cb);
}
}
别的
{
// No connection has been established, restart advertising
user_app_adv_start();
}
default_app_on_connection(connection_idx,param);
}
/ **
****************************************************************************************
* @brief按钮按回调函数。在Wkupct驱动程序中注册。
* @return void.
****************************************************************************************
* /
静态void app_button_press_cb(void)
{
if(getBits16(sys_stat_reg,per_is_down))
{
periph_init();
}
if (arch_ble_ext_wakeup_get())
{
ARCH_SET_SLEEP_MODE(app_default_sleep_mode);
arch_ble_force_wakeup();
ARCH_BLE_EXT_WAKEUP_OFF();
app_easy_wakeup();
}
if(ke_state_get(task_app)== app_connected)
{
gpio_setactive(GPIO_BUTTON_PIN, GPIO_BUTTON_PORT);
延迟(1000);
gpio_setinactive(gpio_button_pin,gpio_button_port);
req->conhdl = app_env->conhdl;
req->handle = CUST1_IDX_PIPE_VAL;
req-> length = def_cust1_pipe_char_len;
memcpy(req->值,&kirim,def_cust1_pipe_char_len);
ke_msg_send(req);
}
if(ke_state_get(task_app)!= app_connected)
{
gpio_setactive(GPIO_BUTTON_PIN, GPIO_BUTTON_PORT);
延迟(1000);
gpio_setinactive(gpio_button_pin,gpio_button_port);
}
}
/ **
****************************************************************************************
* @brief Application wakeup callback function. Registerd in API message utility.
* @return void.
****************************************************************************************
* /
静态void app_wakeup_cb(void)
{
//如果状态不空闲,请忽略该消息
if (ke_state_get(TASK_APP) == APP_CONNECTABLE)
{
user_app_adv_start();
}
}
/ **
****************************************************************************************
* @brief设置按钮作为唤醒触发器
* @return void.
****************************************************************************************
* /
静态void app_button_enable(void)
{
app_easy_wakeup_set(app_wakeup_cb);
wkupct_register_callback(app_button_press_cb);
wkupct_enable_irq(wkupct_pin_select(gpio_button_port,gpio_button_pin),//选择pin(gpio_button_port,gpio_button_pin)
WKUPCT_PIN_POLARITY(GPIO_BUTTON_PORT, GPIO_BUTTON_PIN, WKUPCT_PIN_POLARITY_LOW), // polarity low
1, / / 1事件
40);// debouncing time = 0
}
void user_app_add_undirect_complete(uint8_t状态)
{
//如果广告被取消,则更新广告数据并再次启动广告
// Disable wakeup for BLE and timer events. Only external (GPIO) wakeup events can wakeup processor.
if(status == gap_err_canceled)
{
user_app_adv_start();
ARCH_BLE_EXT_WAKEUP_ON();
//配置唤醒按钮
app_button_enable();
}
}
void user_app_disconnect(struct gapc_disconnect_ind const * param)
{
//取消参数更新请求计时器
if (app_param_update_request_timer_used != EASY_TIMER_INVALID_TIMER)
{
app_easy_timer_cancel(app_param_update_request_timer_used);
app_param_update_request_timer_used = EASY_TIMER_INVALID_TIMER;
}
uint8_t state = ke_state_get(task_app);
if ((state == APP_SECURITY) ||
(state == APP_CONNECTED) ||
(state == app_param_upd))
{
// Restart Advertising
user_app_adv_start();
}
别的
{
// We are not in a Connected State
ASSERT_ERR(0);
}
}
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)
{
switch(msgid)
{
案例custs1_val_write_ind:
{
struct musts1_val_write_ind const * msg_param =(struct custs1_val_write_ind const *)(param);
交换机(msg_param->句柄)
{
Case Cust1_DX_PIPE_VAL:
user_custs1_pipe_wr_ind_handler(msgd,msg_param,dest_id,src_id);
break;
default:
break;
}
} 休息;
案例gapc_param_updated_ind:
{
// Cast the void pointer to the appropriate message structure
struct gapc_param_updated_ind const * msg_param =(struct gapc_param_updated_ind const *)(param);
// Check if updated Conn Params filled to preffered ones
if((msg_param-> con_interval> = user_connection_param_conf.intv_min)&&
(msg_param-> con_interval <= user_connection_param_conf.intv_max)&&
(msg_param->con_latency == user_connection_param_conf.latency) &&
(msg_param->sup_to == user_connection_param_conf.time_out))
{
}
} 休息;
case CUSTS1_VAL_NTF_CFM:
{
struct musts1_val_ntf_cfm const * msg_param =(struct custs1_val_ntf_cfm const *)(param);
交换机(msg_param->句柄)
{
Case Cust1_DX_PIPE_VAL:
break;
default:
break;
}
} 休息;
default:
break;
}
}
/// @} 应用程序
Hi kevleo94,
1)如果您想在设备连接后立即转动LED,那么您应该在User_App_Connection()回调中设置相应的GPIO,并且在断开连接时将LED设置为OFF状态,您应该关闭在user_app_disconnect()回调中。请注意,当设备在休眠模式下运行时,当设备睡眠时,销钉会保留它们的状态,但在唤醒时,从user_periph_setup()函数重新配置引脚,因此您应该在连接或断开连接时保持额外的变量和配置根据其最后状态,每个唤醒都正确地销钉。
2) If you would like to turn on the led if pressed two times then a counter in the wake up interrupt routine (app_wakeup_cb or app_button_press_cb) should do the trick and if you would like to stay on for a specific amount of timer you can use the app_easy_timer() in order to set a kernel timer and turn the LED off as soon as the callback occurs.
Thanks MT_dialog