15 Commits

Author SHA1 Message Date
Roy_01 ed7017c69d Merge branch 'dev/MEM2.0' into vscode 2025-09-01 16:24:23 +08:00
Roy_01 c2c3ea10b9 fix: adjust stream buffer length to 8K-12
- red frame = 8K-12
- green frame = 12
2025-09-01 16:24:11 +08:00
Roy_01 49e251cf54 Merge branch 'dev/MEMv2.0_PELv3.0_MMMv1.0' into vscode 2025-08-29 10:14:31 +08:00
Roy_01 f8972a3a58 fix: update swap_buf size 2025-08-28 17:48:24 +08:00
Roy_01 5a5ba7e215 fix: dispatch HOST instructions by link state 2025-08-26 16:43:03 +08:00
Roy_01 b02fd4c33f feat: INS_SCAN scan rsp 10 times 2025-08-26 16:35:28 +08:00
Roy_01 33dfa5692d feat: enable RESET pin 2025-08-26 16:17:22 +08:00
Roy_01 76cdaa4abf style: formatter host_cmd.py 2025-08-25 14:59:31 +08:00
Roy_01 d0950ba6e0 style: add Black formatter for Python 2025-08-25 14:32:10 +08:00
Roy_01 5a1b8cb193 feat: add detailed board info logs 2025-08-22 10:40:49 +08:00
Roy_01 9f510d5095 feat: update log message and python script 2025-08-21 17:03:31 +08:00
Roy_01 6a296b6b17 style: update clang-format 2025-08-21 16:52:14 +08:00
Roy_01 d19d4e08cf fix: fix cccd configure log 2025-08-15 17:35:51 +08:00
chain40 c2f018bd8e feat: porting for cmake prj 2025-07-16 01:17:10 +08:00
chain40 80fb19859f feat: creat vscode workspace 2025-07-16 01:12:10 +08:00
13 changed files with 243 additions and 95 deletions
+2 -3
View File
@@ -17,6 +17,7 @@ ColumnLimit: 0
BreakBeforeBraces: Custom
NamespaceIndentation: All
TabWidth: 4
UseTab: Never
IndentCaseLabels: true
AlignAfterOpenBracket: Align
PointerAlignment: Right
@@ -24,12 +25,12 @@ AlignOperands: true
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortLoopsOnASingleLine: true
AllowShortIfStatementsOnASingleLine: true
AllowShortFunctionsOnASingleLine: None
BinPackArguments: false
BinPackParameters: false
BreakBeforeBinaryOperators: None
BreakBeforeTernaryOperators: false
BreakAfterJavaFieldAnnotations: true
AlignConsecutiveAssignments: true
AlignTrailingComments: true
BreakConstructorInitializers: AfterColon
AlignConsecutiveMacros:
@@ -50,6 +51,4 @@ AlignConsecutiveBitFields:
AlignCompound: true
PadOperators: true
AlignEscapedNewlines: Right
BinPackArguments: false
BinPackParameters: false
...
+4 -2
View File
@@ -35,7 +35,8 @@
"rtos": "FreeRTOS",
"svdFile": "${workspaceRoot}/../bmd380_sdk/modules/nrfx/mdk/nrf52840.svd",
"runToEntryPoint": "main",
"preLaunchTask": "CMake: build"
"preLaunchTask": "CMake: build",
"serialNumber": ""
},
{
"cwd": "${workspaceRoot}",
@@ -68,7 +69,8 @@
"rtos": "FreeRTOS",
"svdFile": "${workspaceRoot}/../bmd380_sdk/modules/nrfx/mdk/nrf52840.svd",
"runToEntryPoint": "main",
"preLaunchTask": "CMake: build"
"preLaunchTask": "CMake: build",
"serialNumber": ""
},
]
}
+15
View File
@@ -0,0 +1,15 @@
{
"editor.formatOnSave": false,
"[c]": {
"editor.defaultFormatter": "xaver.clang-format",
"editor.formatOnSave": true
},
"[cpp]": {
"editor.defaultFormatter": "xaver.clang-format",
"editor.formatOnSave": true
},
"[python]": {
"editor.defaultFormatter": "ms-python.black-formatter",
"editor.formatOnSave": true
}
}
+1 -1
View File
@@ -51,7 +51,7 @@ set(COMMON_COMPILE_DEF
-DDEBUG=1
-DNRF52840_XXAA
-DS140_reserve
-DCONFIG_GPIO_AS_PIN
-DCONFIG_GPIO_AS_PINRESET
-DRESETHNRF_DFU_SETTINGS_VERSION=2
-DNRF_SD_BLE_API_VERSION=7
-D__STACK_SIZE=1024
+7 -1
View File
@@ -109,12 +109,18 @@ extern "C"
#define DEF_ELITE_EIS_11 0x00040101
#define DEF_ELITE_EIS_MINI_10 0x00040102
#define LE_DEVICE_NAME "CENRAL"
#define LE_DEVICE_NAME "CENRAL MEMv2.0"
#define MAJOR_PRODUCT_NUMBER 0
#define MINOR_PRODUCT_NUMBER 1
#define MAJOR_VERSION_NUMBER 0
#define MINOR_VERSION_NUMBER 1
#define VERSION_DATE_YEAR 25
#define VERSION_DATE_MONTH 9
#define VERSION_DATE_DAY 1
#define VERSION_DATE_HOUR 16
#define VERSION_DATE_MINUTE 24
#define ELITE_DEVICE_NAME_LIST \
{ \
"EIS", "EDC" \
+78 -29
View File
@@ -177,7 +177,7 @@ static void on_ins_connect(ins_connect_t *p_ins)
static void on_ins_write_char(ins_write_char_t *p_ins)
{
uint16_t write_size = p_ins->len - sizeof(p_ins->handle) - 1;
NRF_LOG_INFO("write handle: 0x%02X", p_ins->handle);
NRF_LOG_INFO("[BLE] write_char(W) handle 0x%02X data to peripheral:", p_ins->handle);
{
uint8_t *p_start = (void *)p_ins->write_data;
uint32_t loop = write_size / 8;
@@ -193,18 +193,35 @@ static void on_ins_write_char(ins_write_char_t *p_ins)
}
}
extern ret_code_t le_gatt_c_write_req(uint32_t handle, void *, uint16_t);
ret_code_t err_code = le_gatt_c_write_req(p_ins->handle, p_ins->write_data, write_size);
APP_ERROR_CHECK(err_code);
if (p_ins->handle == 0x0024 ||
p_ins->handle == 0x0028)
{
extern ret_code_t le_gatt_c_write_req(uint32_t handle, void *, uint16_t);
ret_code_t err_code = le_gatt_c_write_req(p_ins->handle, p_ins->write_data, write_size);
APP_ERROR_CHECK(err_code);
success_ack();
success_ack();
}
if (p_ins->handle == 0x0030)
{
uint32_t set_baud = *(uint32_t *)p_ins->write_data;
extern ret_code_t le_uart_baudrate_set(uint32_t baudrate);
ret_code_t err_code = le_uart_baudrate_set(set_baud);
APP_ERROR_CHECK(err_code);
success_ack();
}
}
static void on_ins_read_char(ins_read_char_t *p_ins)
{
NRF_LOG_INFO("read handle: 0x%02X", p_ins->handle);
extern ret_code_t le_gatt_c_read_char_req(uint32_t handle);
ret_code_t ret_code = le_gatt_c_read_char_req(p_ins->handle);
NRF_LOG_INFO("[BLE] read_char(R) handle 0x%02X data from peripheral:", p_ins->handle);
if (p_ins->handle == 0x0021)
{
extern ret_code_t le_gatt_c_read_char_req(uint32_t handle);
ret_code_t ret_code = le_gatt_c_read_char_req(p_ins->handle);
}
}
static void on_ins_disconnect(ins_disconnect_t *p_ins)
@@ -263,6 +280,7 @@ typedef struct
} __PACKED data;
} manu_spec_data_t;
static uint16_t scan_times = 0;
void host_scan_filter_match_cb(
void *p_manu_spec_data,
uint32_t manu_spec_data_len,
@@ -303,6 +321,12 @@ void host_scan_filter_match_cb(
host_scan_rsp.dev_name,
peer_addr_str,
rssi);
scan_times++;
if (scan_times >= 10)
{
extern void le_scan_stop(void);
le_scan_stop();
}
}
void host_connected_cb(void)
@@ -322,28 +346,53 @@ static void host_cmd_exec_task(void *p_arg)
size_t recv = xMessageBufferReceive(host_cmd_msg, buf, sizeof(buf), portMAX_DELAY);
switch (p_ins->raw.opcode)
extern bool le_gap_is_connected(void);
if (le_gap_is_connected())
{
case INS_SCAN:
on_ins_scan(&p_ins->scan);
break;
case INS_CONNECT:
on_ins_connect(&p_ins->connect);
break;
case INS_WRITE_CHAR:
on_ins_write_char(&p_ins->write_char);
break;
case INS_READ_CHAR:
on_ins_read_char(&p_ins->read_char);
break;
case INS_DISCONNECT:
on_ins_disconnect(&p_ins->disconnect);
break;
case INS_CHECK_SURVIVE:
on_ins_survive(&p_ins->survive);
break;
default:
break;
switch (p_ins->raw.opcode)
{
case INS_WRITE_CHAR:
NRF_LOG_INFO("[INS_WRITE_CHAR]");
on_ins_write_char(&p_ins->write_char);
break;
case INS_READ_CHAR:
NRF_LOG_INFO("[INS_READ_CHAR]");
on_ins_read_char(&p_ins->read_char);
break;
case INS_DISCONNECT:
NRF_LOG_INFO("[INS_DISCONNECT]");
on_ins_disconnect(&p_ins->disconnect);
break;
case INS_CHECK_SURVIVE:
NRF_LOG_INFO("[INS_CHECK_SURVIVE]");
on_ins_survive(&p_ins->survive);
break;
default:
NRF_LOG_INFO("unsupported INS");
break;
}
}
else
{
switch (p_ins->raw.opcode)
{
case INS_SCAN:
NRF_LOG_INFO("[INS_SCAN]");
on_ins_scan(&p_ins->scan);
scan_times = 0;
break;
case INS_CONNECT:
NRF_LOG_INFO("[INS_CONNECT]");
on_ins_connect(&p_ins->connect);
break;
case INS_CHECK_SURVIVE:
NRF_LOG_INFO("[INS_CHECK_SURVIVE]");
on_ins_survive(&p_ins->survive);
break;
default:
NRF_LOG_INFO("unsupported INS");
break;
}
}
}
}
+5 -5
View File
@@ -63,13 +63,13 @@ static void on_hvx(ble_gatt_c_t *p_ble_gatt_c, ble_evt_t const *p_ble_evt)
ble_gattc_evt_hvx_t *hvx = (void *)&p_ble_evt->evt.gattc_evt.params.hvx;
uint32_t len = hvx->len;
uint8_t *p = (uint8_t *)hvx->data;
extern void mem_notify_cb(uint8_t * p, uint32_t len);
extern void mem_notify_cb(uint8_t *p, uint32_t len);
mem_notify_cb(p, len);
}
static void on_read_rsp(ble_gatt_c_t *p_le_gatt_c, ble_evt_t const *p_ble_evt)
{
extern void host_read_char_cb(uint8_t * p_data, uint16_t len);
extern void host_read_char_cb(uint8_t *p_data, uint16_t len);
uint16_t handle = p_ble_evt->evt.gattc_evt.params.read_rsp.handle;
for (int i = 0; i < COUNTOF(p_le_gatt_c->char_handles); i++)
@@ -97,9 +97,9 @@ ret_code_t le_gatt_ccdc_configure(uint16_t conn_handle, uint16_t char_handle, bo
return NRF_ERROR_INVALID_PARAM;
}
NRF_LOG_INFO("Configuring CCCD Handle = 0x%04X, Connection Handle = 0x%04X",
NRF_LOG_INFO("Set CCCD(0x%04X) on Connection(0x%04X)",
char_handle + 1,
conn_handle);
notification_enable);
nrf_ble_gq_req_t cccd_req;
uint16_t cccd_val = notification_enable ? BLE_GATT_HVX_NOTIFICATION : BLE_GATT_HVX_INVALID;
@@ -225,7 +225,7 @@ void le_gatt_c_cccd_timer_cb(TimerHandle_t xTimer)
{
le_gatt_ccdc_configure(m_gatt_c.conn_handle, m_gatt_c.char_handles[i], true);
}
NRF_LOG_INFO("Enable notifications. ");
NRF_LOG_INFO("Enable EVENT notifications. ");
}
static TimerHandle_t le_gatt_c_cccd_timer = NULL;
+3 -3
View File
@@ -102,9 +102,9 @@ ret_code_t le_uart_ccdc_configure(uint16_t conn_handle, uint16_t char_handle, bo
return NRF_ERROR_INVALID_PARAM;
}
NRF_LOG_INFO("Configuring CCCD Handle = 0x%04X, Connection Handle = 0x%04X",
NRF_LOG_INFO("Set CCCD(0x%04X) on Connection(0x%04X)",
char_handle + 1,
conn_handle);
notification_enable);
nrf_ble_gq_req_t cccd_req;
uint16_t cccd_val = notification_enable ? BLE_GATT_HVX_NOTIFICATION : BLE_GATT_HVX_INVALID;
@@ -413,7 +413,7 @@ static void ble_uart_echo(void *p_arg)
uint32_t get_baud = 1000000;
uint32_t set_baud = 115200;
extern ret_code_t le_uart_baudrate_get(uint32_t * baudrate);
extern ret_code_t le_uart_baudrate_get(uint32_t *baudrate);
le_uart_baudrate_get(&get_baud);
NRF_LOG_INFO("Get Baud rate: %d", get_baud);
+12
View File
@@ -140,6 +140,18 @@ int main(void)
NRF_LOG_INIT(xTaskGetTickCount, configTICK_RATE_HZ);
NRF_LOG_DEFAULT_BACKENDS_INIT();
NRF_LOG_INFO("%s Build: %s %s", LE_DEVICE_NAME, __TIME__, __DATE__);
NRF_LOG_INFO("[Board] HW ver: %d.%d.%d.%d(%s)",
MAJOR_PRODUCT_NUMBER,
MINOR_PRODUCT_NUMBER,
MAJOR_VERSION_NUMBER,
MINOR_VERSION_NUMBER,
LE_DEVICE_NAME);
NRF_LOG_INFO("[Board] FW ver: %02d%02d%02d %02d:%02d",
VERSION_DATE_YEAR,
VERSION_DATE_MONTH,
VERSION_DATE_DAY,
VERSION_DATE_HOUR,
VERSION_DATE_MINUTE);
le_stack_Init();
+5 -5
View File
@@ -62,7 +62,7 @@ typedef struct
} __PACKED;
} header[3];
} green_frame;
uint8_t red_frame[2048];
uint8_t red_frame[8180]; // 8192-12
} mem_data_t;
mem_data_t mem_data;
uint32_t mem_notify_cnt = 0;
@@ -168,7 +168,7 @@ static void mem_drv_task(void *p_arg)
NRF_LOG_HEXDUMP_INFO(&p[(total_size / 32) * 32], total_size % 32);
}
#endif
NRF_LOG_INFO("Write: %4d bytes, and switch sram done!!!", total_size);
NRF_LOG_INFO("Write: %4d bytes, and switch sram done!!!\n", total_size);
}
}
@@ -187,7 +187,7 @@ void mem_notify_cb(uint8_t *p, uint32_t len)
uint8_t prefix;
uint8_t cnt;
uint8_t len;
uint8_t content[64];
uint8_t content[256];
} swap_buf;
swap_buf.prefix = 0xFF;
@@ -209,7 +209,7 @@ void mem_notify_cb(uint8_t *p, uint32_t len)
sum += swap_buf.prefix;
sum += swap_buf.cnt;
sum += swap_buf.len;
swap_buf.content[len + 5] = sum & 0xFF;
swap_buf.content[len + 5] = sum & 0xFF;
taskENTER_CRITICAL();
xStreamBufferSend(mem_drv_stream, &swap_buf, 3 + len + 6, 0);
@@ -243,7 +243,7 @@ void mem_board_init(void)
// Create Semphr & Task
mem_sel_semphr = xSemaphoreCreateBinary();
mem_drv_stream = xStreamBufferCreate(4096, 1);
mem_drv_stream = xStreamBufferCreate(8180, 1); // 8192-12=8180
xTaskCreate(mem_drv_task, "mem_drv", 256, NULL, 5, NULL);
sd_nvic_SetPriority(GPIOTE_IRQn, _PRIO_APP_MID);
+13
View File
@@ -24,6 +24,8 @@ extern "C"
#define HOST_UART_DRV_TX_PIN NRF_GPIO_PIN_MAP(0, 4)
#define HOST_UART_DRV_RX_PIN NRF_GPIO_PIN_MAP(0, 27)
#define PRINT_UART_DATA 0
static SemaphoreHandle_t uart_drv_tx_sem;
static SemaphoreHandle_t uart_drv_rx_sem;
static SemaphoreHandle_t uart_drv_tx_mutex;
@@ -48,6 +50,11 @@ uint32_t uart_drv_rx(void *p_data, uint16_t len)
nrf_uarte_task_trigger(HOST_UART, NRF_UARTE_TASK_STOPRX);
xSemaphoreTake(uart_drv_rx_sem, portMAX_DELAY);
uint32_t recv_bytes = nrf_uarte_rx_amount_get(HOST_UART);
if (PRINT_UART_DATA)
{
NRF_LOG_INFO("UART_BT_Rx:");
NRF_LOG_HEXDUMP_INFO(p_data, recv_bytes);
}
xSemaphoreGive(uart_drv_rx_mutex);
return recv_bytes;
}
@@ -64,6 +71,12 @@ void uart_drv_tx(void *p_data, uint16_t len)
nrf_uarte_task_trigger(HOST_UART, NRF_UARTE_TASK_STARTTX);
xSemaphoreTake(uart_drv_tx_sem, portMAX_DELAY);
xSemaphoreGive(uart_drv_tx_mutex);
if (PRINT_UART_DATA)
{
NRF_LOG_INFO("UART_BT_Tx:");
NRF_LOG_HEXDUMP_INFO(p_data, len);
NRF_LOG_INFO("\t");
}
}
void uart_drv_init(void)
+1 -7
View File
@@ -7,11 +7,5 @@
"path": "../bmd380_sdk"
}
],
"settings": {
"files.associations": {
"ble_db_discovery.h": "c",
"ble_dis_c.h": "c",
"sdk_config.h": "c"
}
}
"settings": {}
}
+97 -39
View File
@@ -1,34 +1,42 @@
import serial
import os
import time
def survive_cmd(ser):
send = [0x0A, 0x01, 0xF1]
ser.reset_input_buffer()
ser.write(send)
read = ser.read(4)
print("recv: " + " ".join("%02X" % b for b in read))
print("survive_cmd")
print("UART_BT_Tx:\t" + " ".join("%02X" % b for b in send))
print("UART_BT_Rx:\t" + " ".join("%02X" % b for b in read) + "\n")
def scan_cmd(ser, is_raw_data=True):
send = [0x03, 0x01, 0xF1]
ser.write(send)
peer_addr = []
send = [0x03, 0x01, 0xF1]
ser.reset_input_buffer()
ser.write(send)
print("scan_cmd")
print("UART_BT_Tx:\t" + " ".join("%02X" % b for b in send))
for i in range(10):
hci_packet_event = ser.read(2)
if int.from_bytes(hci_packet_event, "little") != 0x0004:
continue
len = ser.read(1)
payload = ser.read(int.from_bytes(len, "little"))
peer_addr = payload[0:6]
if is_raw_data:
print(
"recv: "
+ " ".join("0x%02X" % b for b in hci_packet_event)
"UART_BT_Rx:\t"
+ " ".join("%02X" % b for b in hci_packet_event)
+ " "
+ " ".join("0x%02X" % b for b in len)
+ " ".join("%02X" % b for b in len)
+ " "
+ " ".join("0x%02X" % b for b in payload)
+ " ".join("%02X" % b for b in payload)
)
else:
print("-" * 100)
@@ -43,76 +51,126 @@ def scan_cmd(ser, is_raw_data=True):
+ "V"
)
print(" device name: " + str(payload[21:], "utf-8"))
print("\n")
return peer_addr
def connect(ser, peer_addr=[]):
DISCONNECT_RSPONSE = [0x04, 0x00, 0x01, 0xFF]
CONNECTED_RSPONSE = [0x04, 0x00, 0x01, 0x03]
send = [0x05, 0x08, 0x00]
send += peer_addr
send += [0xF1]
ser.reset_input_buffer()
ser.write(send)
read = ser.read(4)
print("recv: " + " ".join("%02X" % b for b in read))
print("connect " + ":".join(f"{b:02X}" for b in peer_addr))
print("UART_BT_Tx:\t" + " ".join("%02X" % b for b in send))
print("UART_BT_Rx:\t" + " ".join("%02X" % b for b in read) + "\n")
if list(read) == DISCONNECT_RSPONSE:
return False
elif list(read) == CONNECTED_RSPONSE:
return True
else:
return False
def disconnect(ser):
send = [0x08, 0x01, 0xF1]
ser.reset_input_buffer()
ser.write(send)
read = ser.read(4)
print("recv: " + " ".join("%02X" % b for b in read))
print("disconnect")
print("UART_BT_Tx:\t" + " ".join("%02X" % b for b in send))
print("UART_BT_Rx:\t" + " ".join("%02X" % b for b in read) + "\n")
def write_char(ser: serial.Serial, handle: int, write_data: tuple):
send = [0x06, len(write_data)+2, handle]
send = [0x06, len(write_data) + 2, handle]
send += write_data
send += [0xF1]
send += [0xF1]
ser.reset_input_buffer()
ser.write(send)
read = ser.read(4)
print("write_char")
print("UART_BT_Tx:\t" + " ".join("%02X" % b for b in send))
print("UART_BT_Rx\t" + " ".join("%02X" % b for b in read) + "\n")
def read_char(ser: serial.Serial, handle: int):
send = [0x07, 0x02, handle, 0xF1]
ser.reset_input_buffer()
ser.write(send)
read = ser.read(0xFFFF)
print("recv: " + " ".join("%02X" % b for b in read))
print("read_char")
print("UART_BT_Tx:\t" + " ".join("%02X" % b for b in send))
print("UART_BT_Rx\t" + " ".join("%02X" % b for b in read) + "\n")
def main():
# set comport
ser = serial.Serial("COM15", 57600, 8, inter_byte_timeout=0.01)
ser = serial.Serial("COM14", 115200, 8, inter_byte_timeout=0.01)
# send survive cmd
survive_cmd(ser)
# send scan cmd
peer_addr = scan_cmd(ser, False)
time.sleep(10)
return
# send connect cmd with peer addr
connect(ser, peer_addr)
time.sleep(3)
# send write char to enable notify
write_char(ser, 0x0024, [0xc4,0xf0,0xf1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00])
peer_addr = scan_cmd(ser, True)
# want_connected_addr = bytes.fromhex("C0 38 14 75 AD A9")
want_connected_addr = bytes.fromhex("C8 DC F1 3B 07 74")
peer_addr = want_connected_addr
connect_success = connect(ser, peer_addr)
time.sleep(1)
if connect_success == False:
print("connect fail, exit python code")
ser.close()
return
# read version
write_char(ser, 0x0024, [0x74, 0x40])
read_char(ser, 0x0021)
time.sleep(0.1)
write_char(ser, 0x0024, [0x74,0x10,0xf1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00])
time.sleep(0.1)
read_char(ser, 0x0021)
# 130500040000000000000000000000000000001c
time.sleep(0.2)
# send write char to enable notify
#write_char(ser, 0x0028, 1)
#time.sleep(5)
# send write char to disable notify
#write_char(ser, 0x0028, 0)
# -----------------------------------------------------
# run auto scan mode
# -----------------------------------------------------
PEL_RUN_AUTO_SCAN_MODE = False
if PEL_RUN_AUTO_SCAN_MODE:
# send read char to disable notify
#read_char(ser, 0x0027)
# event_notify:enable
write_char(ser, 0x0028, [0x01, 0x00])
time.sleep(0.1)
# PELv3.0 start auto_scan_mode
write_char(
ser,
0x0024,
[0x35, 0x00, 0x02, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x05, 0x00, 0x0A],
)
print("---------- notify data ----------")
time.sleep(0.5)
print("--------------------------------")
# PELv3.0 stop auto_scan_mode
write_char(ser, 0x0024, [0x30, 0x00, 0x02, 0x00])
time.sleep(0.1)
# event_notify:disable
write_char(ser, 0x0028, [0x00, 0x00])
time.sleep(0.1)
# auto scan mode completed
# -----------------------------------------------------
# send disconnect cmd
disconnect(ser)
time.sleep(1)
ser.close()
return
if __name__ == "__main__":
main()