更新时间:2022-11-24 09:20:19
SDK 开发中经常会遇到这么一类问题,I/O 不够用,需要将串口脚需要用作输出口控制,但模组串口又需要用作烧录授权,于是有了冲突。
本文档将以案例的方式介绍既不影响串口授权产品,又可以将串口用作输出控制的方法。本文已 BT3L 举例,其他泰凌微模组或其他芯片平台方案类似。
以 Telink 平台为例,要复用的脚为 GPI/O_PB1(UART TX),用作 PWM 输出。上电先进行 UART 初始化,若 1 秒内进入了授权产测则不将串口脚初始化为输出控制脚,若超时则将串口脚初始化为输出控制脚。
//app.c
uint32_t m_uart_muti_use_tick = 0;//定义全局变量
void user_init_normal(void)
{
……
uart_init(9600);
……
m_uart_muti_use_tick = clock_time();
}
void main_loop (void)
{
static uint8_t PB1_init_flag =0;
////////////////////////////////////// BLE entry /////////////////////////////////
blt_sdk_main_loop();
blt_soft_timer_process(MAINLOOP_ENTRY);
if(clock_time_exceed(uart_muti_use_tick,1000*1000))
{
//init
if(PB1_init_flag==0)
{
PB1_init_flag = 1;
gpI/O_set_func(GPI/O_PB1, AS_PWM4);
pwm_set_mode(PWM4_ID, PWM_NORMAL_MODE);
pwm_set_phase(PWM4_ID, 0); //no phase at pwm beginning
pwm_set_cycle_and_duty(PWM4_ID, (u16) (1000 * CLOCK_SYS_CLOCK_1US), (u16) (667 * CLOCK_SYS_CLOCK_1US) );
pwm_start(PWM4_ID);
}
}
……
}
//……\tuya_ble_sdk\app\product_test\tuya_ble_app_productI/On_test.c
/*********************************************************
FN: 是否处于产测中
*/
uint8_t tuya_ble_is_productI/On_test_effective(void)
{
return tuya_ble_productI/On_test_flag;
}
效果如下:
以 Telink 平台为例,要复用的脚为 GPI/O_PB1(UART TX),用作 PWM 输出。上电就将 GPI/O_PB1 用作 PWM,持续 1 秒的蓝牙扫描。若扫描到了广播名为 “ty_prod” 的广播,才初始化为串口。
//add ty_ble_scan_tlsr825x.c
#include "tl_common.h"
#include "stack/ble/gap/gap.h"
#include "stack/ble/hci/hci_const.h"
#include "stack\ble\ll\ll_scan.h"
#include "stack\ble\ll\ll_whitelist.h"
static char m_ble_target_periph_name[8] = "ty_prod";
typedef struct
{
uint8_t * p_data; /**< Pointer to data. */
uint16_t data_len; /**< Length of data. */
} data_t;
uint32_t adv_report_parse(uint8_t type, data_t * p_advdata, data_t * p_typedata)
{
uint32_t index = 0;
uint8_t * p_data;
p_data = p_advdata->p_data;
while (index < p_advdata->data_len)
{
uint8_t field_length = p_data[index];
uint8_t field_type = p_data[index + 1];
if (field_type == type)
{
p_typedata->p_data = &p_data[index + 2];
p_typedata->data_len = field_length - 1;
return 0;//OPRT_OK
}
index += field_length + 1;
}
return 5;//OPRT_ERROR_NOT_FOUND
}
void tuya_ble_scan_evt_handler(uint32_t h, uint8_t *para, int n)
{
event_adv_report_t *pa = (event_adv_report_t *)para;
int8_t rssi = pa->data[pa->len];
static uint8_t uart_init_flag = 0;
data_t adv_data;
data_t dev_name;
adv_data.p_data = pa->data;
adv_data.data_len = pa->len;
if(0 == adv_report_parse(GAP_ADTYPE_LOCAL_NAME_COMPLETE,&adv_data,&dev_name))
{
if(memcmp(m_ble_target_periph_name,dev_name.p_data,dev_name.data_len)==0)
{
if(uart_init_flag==0)
{
uart_init_flag = 1;
uart_init(9600);
}
}
}
else
{
}
}
extern int controller_event_handler(u32 h, u8 *para, int n);
void tuya_ble_scan_init(void)
{
//scan set
extern u8 mac_public[6];
blc_ll_initScanning_module(mac_public); //scan module: optI/Onal
blc_hci_le_setEventMask_cmd(HCI_LE_EVT_MASK_ADVERTISING_REPORT);
//blc_hci_registerControllerEventHandler(tuya_ble_scan_evt_handler); //register event callback
blc_ll_setScanParameter(SCAN_TYPE_PASSIVE, SCAN_INTERVAL_30MS, SCAN_INTERVAL_30MS,
OWN_ADDRESS_PUBLIC, SCAN_FP_ALLOW_ADV_ANY);
}
uint8_t tuya_ble_scan_set_filter_name(char *bft_target_periph_name)
{
memcpy(m_ble_target_periph_name,bft_target_periph_name,7);
}
void tuya_ble_scan_start(void)
{
blc_hci_registerControllerEventHandler(tuya_ble_scan_evt_handler); //register event callback
blc_ll_addScanningInAdvState(); //add scan in adv state
blc_ll_addScanningInConnSlaveRole(); //add scan in conn slave role
blc_ll_setScanEnable (1, 0);
}
void tuya_ble_scan_stop(void)
{
blc_hci_registerControllerEventHandler(controller_event_handler); //register event callback
blc_ll_setScanEnable (0, 0);
blc_ll_removeScanningFromAdvState();
blc_ll_removeScanningFromConnSLaveRole();
}
//app.c
tuya_ble_timer_t first_init_scan_timer;
static void tuya_ble_first_init_scan_timeout_handler(tuya_ble_timer_t timer)
{
tuya_ble_scan_stop();
}
void tuya_ble_first_init_scan_timer_start(void)
{
static uint8_t init = 0;
tuya_ble_timer_create(&first_init_scan_timer,2000,TUYA_BLE_TIMER_SINGLE_SHOT,tuya_ble_first_init_scan_timeout_handler);
tuya_ble_timer_start(first_init_scan_timer);
if(init==0)
{
init = 1;
tuya_ble_scan_init();
}
tuya_ble_scan_start();
}
void user_init_normal(void)
{
……
gpI/O_set_func(GPI/O_PB1, AS_PWM4);
pwm_set_mode(PWM4_ID, PWM_NORMAL_MODE);
pwm_set_phase(PWM4_ID, 0); //no phase at pwm beginning
pwm_set_cycle_and_duty(PWM4_ID, (u16) (1000 * CLOCK_SYS_CLOCK_1US), (u16) (667 * CLOCK_SYS_CLOCK_1US) );
pwm_start(PWM4_ID);
tuya_ble_first_init_scan_timer_start();
}
该内容对您有帮助吗?
是意见反馈该内容对您有帮助吗?
是意见反馈