Last Updated on : 2024-11-20 08:51:40
A number of the available pins can be used for multiple purposes other than the function they are intended to perform. Such pins are referred to as multiplexed pins. For example, the UART pins are multiplexed so that you can designate and use them as GPIO pins when needed.
This topic describes how to set a hardware pin to a specified mode without compromising its original function. We use the BT3L module as an example to illustrate how to change the function of your pins.
Take the Telink as an example. To set the GPIO_PB1(UART TX)
to operate in PWM mode, you need to initialize the UART after the device is powered on. If the device enters the test mode within one second, do not configure this pin as output. Otherwise, configure it as output.
Advantages: easy-to-configure and wide applicability.
Disadvantages: This method has no immediate effect. You have to wait for some time before pin configuration.
//app.c
uint32_t m_uart_muti_use_tick = 0;// Define a global variable
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: Determine if the device enters the testing mode.
*/
uint8_t tuya_ble_is_productI/On_test_effective(void)
{
return tuya_ble_productI/On_test_flag;
}
Take the Telink as an example. To set the GPIO_PB1(UART TX)
to operate in PWM mode, you need to configure this pin to PWM mode upon power on and scan for Bluetooth signals for one second. The UART initialization is started only after the module scans for the ty_prod
packet.
Advantages: You can configure pins upon power on.
Disadvantages: The scanning feature and a Bluetooth beacon are required.
//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();
}
Is this page helpful?
YesFeedbackIs this page helpful?
YesFeedback