add/tested history, clock

This commit is contained in:
pvvx 2024-01-27 17:35:12 +03:00
parent ad38d7b758
commit 00013d3da7
20 changed files with 9219 additions and 7022 deletions

View file

@ -160,7 +160,7 @@ SRCS += $(SDK_PATH)/lib/ble_host/gap_devmgr.c
SRCS += $(SDK_PATH)/lib/ble_host/gap_linkmgr.c
SRCS += $(SDK_PATH)/lib/ble_host/gap_peridevmgr.c
SRCS += $(SDK_PATH)/lib/ble_host/gap_perilinkmgr.c
SRCS += $(SDK_PATH)/lib/ble_host/gap_simpletask.c
#SRCS += $(SDK_PATH)/lib/ble_host/gap_simpletask.c
SRCS += $(SDK_PATH)/lib/ble_host/gap_task.c
SRCS += $(SDK_PATH)/lib/ble_host/gatt_client.c
SRCS += $(SDK_PATH)/lib/ble_host/gatt_server.c

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -18,7 +18,7 @@ extern "C"
*/
// A complete list of interface commands for different devices.
// Not all commands are supported by a specific device (!)
enum CMD_ID_KEYS {
typedef enum {
CMD_ID_DEVID = 0x00, // Get dev id, version, services
CMD_ID_DNAME = 0x01, // Get/Set device name, "\0" - default: THB2_xxxx
CMD_ID_GDEVS = 0x02, // Get address devices
@ -65,7 +65,7 @@ enum CMD_ID_KEYS {
CMD_ID_LR_RESET = 0xDD, // Reset Long Range
CMD_ID_DEBUG = 0xDE // Test/Debug
};
} CMD_ID_KEYS;
// supported services by the device
typedef struct _dev_services_t{

View file

@ -86,6 +86,7 @@ void test_config(void) {
gapRole_MinConnInterval = periConnParameters.intervalMin = DEFAULT_DESIRED_MIN_CONN_INTERVAL;
gapRole_MaxConnInterval = periConnParameters.intervalMax = DEFAULT_DESIRED_MAX_CONN_INTERVAL;
gapRole_SlaveLatency = periConnParameters.latency = cfg.connect_latency;
periConnParameters.timeout = (cfg.connect_latency + 1) * 3 * 4;
if(periConnParameters.timeout > 2048)
periConnParameters.timeout = 2048; // 20.48 sec мax

View file

@ -101,7 +101,7 @@ const uint8_t lcd_init_cmd[] = {
* 0x5 = "°F"
* 0x6 = " ="
* 0x7 = "°E" */
void show_temp_symbol(uint8_t symbol) {
void show_temp_symbol(CLD_TEMP_SYMBOL symbol) {
display_buff[2] &= ~BIT(3);
display_buff[3] &= ~(BIT(7)|BIT(5)) ;
display_buff[2] |= (symbol << 2) & BIT(3);
@ -167,7 +167,7 @@ void show_big_number_x10(int16_t number) {
if (number > 99) display_buff[0] |= display_numbers[number / 100 % 10];
if (number > 9) display_buff[1] |= display_numbers[number / 10 % 10];
else display_buff[1] |= LCD_SYM_0; // "0"
display_buff[2] = display_numbers[number %10];
display_buff[2] |= display_numbers[number %10];
}
}

View file

@ -39,6 +39,23 @@
extern uint8_t lcd_i2c_addr; // LCD controller I2C address
extern uint8_t display_buff[LCD_BUF_SIZE];
/* 0x0 = " "
* 0x1 = "°Г"
* 0x2 = " _"
* 0x3 = "°C"
* 0x4 = " -"
* 0x5 = "°F"
* 0x6 = " ="
* 0x7 = "°E" */
typedef enum {
CLD_TSYMBOL_NONE, // " "
CLD_TSYMBOL_C = 3, // "°C"
CLD_TSYMBOL_F = 5, // "°F"
CLD_TSYMBOL_EQ = 6, // " ="
CLD_TSYMBOL_E = 7 // "°E"
} CLD_TEMP_SYMBOL;
void init_lcd(void);
void update_lcd(void);
void show_small_number(int16_t number, bool percent);
@ -46,6 +63,6 @@ void show_big_number_x10(int16_t number);
void show_battery_symbol(bool state);
void show_ble_symbol(bool state);
void show_smiley(uint8_t state);
void show_temp_symbol(uint8_t symbol);
void show_temp_symbol(CLD_TEMP_SYMBOL symbol);
#endif /* _LCD_TH05_H_ */

View file

@ -158,7 +158,6 @@ int send_memo_blk(uint8_t * send_buf) {
send_buf[1] = 0;
send_buf[2] = 0;
olen = 3;
// bls_pm_setManualLatency(cfg.connect_latency);
rd_memo.cnt = 0;
} else {
send_buf[1] = rd_memo.cur;

View file

@ -46,6 +46,24 @@
GLOBAL VARIABLES
*/
/*
extern l2capSegmentBuff_t l2capSegmentPkt[MAX_NUM_LL_CONN];
uint8_t notify_enable_TaskID;
extern uint16 gapRole_ConnectionHandle;
// add event free buf
uint16 _HCI_ProcessEvent( uint8 task_id, uint16 events ) {
uint16 ret = HCI_ProcessEvent(task_id, events);
if(ret == 0) {
if(notify_enable_TaskID) {
//&& l2capSegmentPkt[gapRole_ConnectionHandle].fragment
//&& l2capSegmentPkt[gapRole_ConnectionHandle].depth < 3) {
osal_set_event(notify_enable_TaskID, WRK_NOTIFY_EVT);
}
}
return ret;
}
*/
// The order in this table must be identical to the task initialization calls below in osalInitTask.
const pTaskEventHandlerFn tasksArr[] =
{
@ -73,7 +91,6 @@ uint16* tasksEvents;
/*********************************************************************
FUNCTIONS
*********************************************************************/
/*********************************************************************
@fn osalInitTasks

View file

@ -25,6 +25,8 @@
#include "cmd_parser.h"
#include "ble_ota.h"
#include "logger.h"
#include "hci.h"
#include "lcd_th05.h"
/*********************************************************************
* MACROS
@ -463,23 +465,32 @@ void new_ota_data(void) {
}
#endif
#if (DEV_SERVICES & SERVICE_HISTORY)
void wrk_notify(void) {
gattServerInfo_t* pServer;
attHandleValueNoti_t noti;
if (gattGetServerStatus( gapRole_ConnectionHandle, &pServer ) != bleTimeout) {
noti.len = 0;
#if (DEV_SERVICES & SERVICE_HISTORY)
// if(rd_memo.cnt)
noti.len = send_memo_blk(noti.value);
#endif
if(noti.len) {
noti.handle = simpleProfileAttrTbl[CDM_DATA_ATTR_IDX].handle;
if(ATT_HandleValueNoti(gapRole_ConnectionHandle, &noti) != SUCCESS || noti.len <= 3)
return;
osal_set_event(simpleBLEPeripheral_TaskID, WRK_NOTIFY_EVT);
} else
return;
// gattStoreServerInfo( pServer, simpleBLEPeripheral_TaskID );
noti.len = 0;
if(rd_memo.cnt) {
while(1) { // 4096 memo 43 sec [memo = 13 bytes] -> 1238 bytes/s
noti.handle = simpleProfileAttrTbl[CDM_DATA_ATTR_IDX].handle;
noti.len = send_memo_blk(noti.value);
if(noti.len) {
bStatus_t err = ATT_HandleValueNoti(gapRole_ConnectionHandle, &noti);
if(err == bleMemAllocError
|| err == MSG_BUFFER_NOT_AVAIL
|| err == HCI_ERROR_CODE_MEM_CAP_EXCEEDED) {
rd_memo.cur--;
osal_start_timerEx(simpleBLEPeripheral_TaskID, WRK_NOTIFY_EVT, (DEFAULT_DESIRED_MIN_CONN_INTERVAL *125)/100);
break;
} else if (err != SUCCESS || noti.len <= 3)
break;
} else
break;
}
}
} else
osal_start_timerEx(simpleBLEPeripheral_TaskID, WRK_NOTIFY_EVT, 30);
osal_start_timerEx(simpleBLEPeripheral_TaskID, WRK_NOTIFY_EVT, 30);
}
#endif

View file

@ -109,7 +109,7 @@ void chow_measure(void) {
show_big_number_x10(measured_data.temp/10);
show_small_number(measured_data.humi/100, true);
show_battery_symbol(measured_data.battery < 20);
show_temp_symbol(3);
show_temp_symbol(CLD_TSYMBOL_C);
#else
show_big_number_x10(measured_data.battery_mv/100);
show_small_number((measured_data.battery > 99)? 99 : measured_data.battery, true);
@ -159,6 +159,7 @@ static void set_mac(void)
}
}
set_def_name(ownPublicAddr);
// TODO: pGlobal_config[MAC_ADDRESS_LOC]
}
static void set_serial_number(void)
@ -484,9 +485,12 @@ void SimpleBLEPeripheral_Init( uint8 task_id )
// HCI_LE_SetDefaultPhyMode(0,0xff,0x01,0x01);
#ifdef MTU_SIZE
#if MTU_SIZE > ATT_MAX_MTU_SIZE
#error "MTU_SIZE > 517"
#endif
ATT_SetMTUSizeMax(MTU_SIZE);
#else
ATT_SetMTUSizeMax(23);
ATT_SetMTUSizeMax(ATT_MTU_SIZE_MIN);
#endif
// Setup a delayed profile startup
osal_set_event( simpleBLEPeripheral_TaskID, SBP_START_DEVICE_EVT );
@ -604,11 +608,13 @@ uint16 BLEPeripheral_ProcessEvent( uint8 task_id, uint16 events )
// return unprocessed events
return ( events ^ SBP_START_DEVICE_EVT );
}
#if (DEV_SERVICES & SERVICE_HISTORY)
if(events & WRK_NOTIFY_EVT) {
LOG("Wrk notify events\n");
wrk_notify();
return(events ^ WRK_NOTIFY_EVT);
}
#endif
if(events & SBP_CMDDATA) {
LOG("CMD data events\n");
new_cmd_data();
@ -636,7 +642,6 @@ static void simpleBLEPeripheral_ProcessOSALMsg( osal_event_hdr_t *pMsg )
switch ( pMsg->event ){
case HCI_GAP_EVENT_EVENT:{
switch( pMsg->status ){
case HCI_COMMAND_COMPLETE_EVENT_CODE:
#if DEBUG_INFO
pHciMsg = (hciEvt_CmdComplete_t *)pMsg;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,621 @@
<html class="phy6222Class"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" href="styles.css">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PHY62x2-BTHome тестовая версия</title>
</head>
<body>
<script>
//BLE values
const FLASH_SIZE = 0x80000;
var bluetoothDevice, gattServer, otaCharacteristic, myCharacteristic;
//Firmware values
var firmwareArray = "",
startTime = 0,
flgRdFF = false,
blockCount = 0;
//Connection values
var connectTrys = 0;
var $ = function(id) { return document.getElementById(id);}
function resetVariables() {
busy = false;
gattServer = null;
Theservice = null;
otaCharacteristic = null;
myCharacteristic = null;
$('btnDisconnect').disabled = true;
$('btnReadFF').disabled = true;
$('btnReadAddr').disabled = true;
$('btnSave').disabled = true;
$('btnStartDFU').disabled = true;
$('btnSendData').disabled = true;
$('btnSendCommand').disabled = true;
// showState("Ожидание соединения с устройством")
}
function handleError(text) {
showError(text);
resetVariables();
if (connectTrys < 5) {
connectTrys++;
addLog("Переподключение " + connectTrys + " из " + 5);
doConnect();
} else {
addLog("Подключиться не удалось!");
connectTrys = 0;
}
}
function doConnect() {
showState("Ожидание соединения с " + bluetoothDevice.name)
bluetoothDevice.gatt.connect().then(server => {
console.log("Найден GATT сервер");
gattServer = server;
return gattServer.getPrimaryService(0xfff0);
}).then(service => {
console.log("Найден Main сервис");
Theservice = service;
return service.getCharacteristic(0xfff3);
}).then(characteristic => {
console.log("Найдена OTA характеристика");
otaCharacteristic = characteristic;
return Theservice.getCharacteristic(0xfff4);
}).then(characteristic => {
console.log("Найдена CMD характеристика");
myCharacteristic = characteristic;
myCharacteristic.readValue().then(value => {
if(value.byteLength >= 10)
addLog("DevCfg: " + dump8(value, value.byteLength));
//flash_buf = new Uint8Array(FLASH_SIZE);
myCharacteristic.addEventListener('characteristicvaluechanged', event => customBlkParse(event.target.value));
myCharacteristic.startNotifications().then(_ => {
showState("Устройство подключено.");
$('btnDisconnect').disabled = false;
$('btnReconnect').disabled = false;
$('btnSendCommand').disabled = false;
$('btnReadFF').disabled = false;
$('btnReadAddr').disabled = false;
$('btnSendData').disabled = false;
$('btnStartDFU').disabled = false; })
})
}).catch(handleError);
}
function onDisconnected() {
resetVariables();
showState('Устройство отключено.');
}
function connect() {
var deviceOptions = {
optionalServices: [0xfff0],
services: [0x180a, 0x181c, 0x181e, 0xfff0],
acceptAllDevices: true };
const namePrefix = $('inpNamePrefix').value;
if (namePrefix) {
deviceOptions.acceptAllDevices = false;
deviceOptions.filters = namePrefix.split(",")
.map((x) => ({ namePrefix: x }));
} else {
deviceOptions.acceptAllDevices = false;
deviceOptions.filters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz_#@!*0123456789';,.<>{}[]"
.split("")
.map((x) => ({ namePrefix: x }));
}
if (bluetoothDevice != null) bluetoothDevice.gatt.disconnect();
resetVariables();
$('btnReconnect').disabled = true;
showState("Поиск устройств");
connectTrys = 0;
navigator.bluetooth.requestDevice(deviceOptions).then(device => {
bluetoothDevice = device;
bluetoothDevice.addEventListener('gattserverdisconnected', onDisconnected);
// addLog("Connecting to: " + bluetoothDevice.name);
doConnect();
}).catch(handleError);
}
function disconnect() {
addLog("Отключение");
if (bluetoothDevice != null) bluetoothDevice.gatt.disconnect();
}
function reconnect() {
addLog("Переподключение");
if (bluetoothDevice != null) bluetoothDevice.gatt.disconnect();
connectTrys = 0;
doConnect();
}
function startDFU() {
addLog("Start DFU");
updateBegin();
}
function addLog(text) {
var stime = new Date().toLocaleTimeString();
var string = stime + ": " + text;
console.log(string)
$("log").innerHTML += string + "<br>";
}
function clearLog() {
$("log").innerHTML = "";
}
function showState(text) {
// console.log("Status: " + status);
let s = "Состояние: " + text;
document.getElementById("lblStatus").className = "shadowbox";
$("lblStatus").innerHTML = s;
addLog(text);
}
function showError(text) {
// console.log("Status: " + status);
let s = "Ошибка: " + text;
document.getElementById("lblStatus").className = "shadowerror";
$("lblStatus").innerHTML = s;
addLog(text);
}
function showProgress(text) {
document.getElementById("lblStatus").className = "shadowprogress";
$("lblStatus").innerHTML = text;
}
function updateFail(err) {
let s = err + ". Update failed";
showError(s);
}
function decimalToHex(d, padding) {
var hex = Number(d).toString(16);
while (hex.length < 4) {
hex = "0" + hex;
}
return hex;
}
function hexToBytes(hex) {
for (var bytes = [], c = 0; c < hex.length; c += 2)
bytes.push(parseInt(hex.substr(c, 2), 16));
return new Uint8Array(bytes);
}
function bytesToHex(data) {
return new Uint8Array(data).reduce(function(memo, i) {
return memo + ("0" + i.toString(16)).slice(-2);
}, "");
}
function crc16_modbus(buffer) {
var crc = 0xFFFF;
var odd;
for (var i = 0; i < buffer.length; i++) {
crc = crc ^ buffer[i];
for (var j = 0; j < 8; j++) {
odd = crc & 0x0001;
crc = crc >> 1;
if (odd) {
crc = crc ^ 0xA001;
}
}
}
return crc;
};
function getHexCRC(data) {
var tempCRC = decimalToHex(crc16_modbus(hexToBytes(data)));
return tempCRC.substring(2, 4) + tempCRC.substring(0, 2);
}
function makeRandomID(length) {
var result = '';
var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
var charactersLength = characters.length;
for (var i = 0; i < length; i++) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
}
return bytesToHex(new TextEncoder("utf-8").encode(result));
}
function hex(number, len) {
var str = (number.toString(16)).toUpperCase();
while (str.length < len) str = '0' + str;
return str;
}
function hexToBytes(hex) {
for (var bytes = [], c = 0; c < hex.length; c += 2)
bytes.push(parseInt(hex.substr(c, 2), 16));
return new Uint8Array(bytes);
}
function dump(ar, len) {
let s = '';
for(let i=0; i < len; i++) {
s += hex(ar[i],2);
}
return s;
}
function dump8(ar, len) {
let s = '';
for(let i=0; i < len; i++) {
s += hex(ar.getUint8(i),2);
}
return s;
}
function hex2ascii(hexx) {
var hex = hexx.toString();
var str = '';
for (var i = 0;
(i < hex.length && hex.substr(i, 2) !== '00'); i += 2)
str += String.fromCharCode(parseInt(hex.substr(i, 2), 16));
return str;
}
function updateBegin() {
if (blockCount <= 0) {
showError("Не выбран файл!");
return;
}
setTimeout(function() {
otaCharSend("00ff").then(function(character) {
otaCharSend("01ff").then(function(character) {
setTimeout(function() {
startTime = new Date().getTime();
sendOTAblock(0);
}, 300);
}).catch(function(err) {
updateFail(err);
});
}).catch(function(err) {
updateFail(err);
});
}, 500);
}
function sendOTAblock(blockNr) {
if (blockNr >= blockCount) {
sendLastOTA();
return;
}
showProgress("Передан блок N: " + blockNr + " из " + blockCount + ", " + Math.floor(blockNr / (blockCount * 1.0) * 100) + "% успеха, время " + (new Date().getTime() - startTime) / 1000.0 + "сек");
var blockNrString = getHexBLockCount(blockNr);
var blockString = blockNrString + firmwareArray.substring(blockNr * 32, blockNr * 32 + 32);
var blockCRC = getHexCRC(blockString);
otaCharSend(blockString + blockCRC).then(function(character) {
setTimeout(function() {
if ((blockNr + 1) % 8 == 0) {
otaCharacteristic.readValue().then(function(result) {
console.log('Чтение OTA');
sendOTAblock(blockNr + 1);
}).catch(function(err) {
updateFail(err);
});
} else {
sendOTAblock(blockNr + 1);
}
}, 0);
}).catch(function(err) {
updateFail(err);
});
}
function getHexBLockCount(count) {
var tempHEX = decimalToHex(count);
return tempHEX.substring(2, 4) + tempHEX.substring(0, 2);
}
function sendLastOTA() {
var data = "02ff" + getHexBLockCount(blockCount - 1) + getHexBLockCount(~(blockCount - 1) & 0xffff);
otaCharSend(data).then(function(character) {
showProgress("Прошивка выполнена за " + (new Date().getTime() - startTime) / 1000 + " сек");
}).catch(function(err) {
updateFail(err);
});
}
var otaCharSend = function(data) {
return new Promise(function(resolve, reject) {
// console.log("OTA: " + data);
otaCharacteristic.writeValue(hexToBytes(data)).then(function(character) {
resolve("ok");
}).catch(function(err) {
reject("some error while sending char data");
});
});
}
var mainCharSend = function(data, characteristic) {
return new Promise(function(resolve, reject) {
console.log("Send: " + data);
characteristic.writeValue(hexToBytes(data)).then(function(character) {
resolve("OK");
}).catch(function(err) {
reject("Some error while sending char data");
});
});
}
function readAddr(addr) {
if (myCharacteristic) {
let blk = new Uint8Array([0xdb, addr&0xff, (addr>>8)&0xff, (addr>>16)&0xff, (addr>>24)&0xff]);
myCharacteristic.writeValue(blk).then(_ => {
startTime = new Date().getTime();
showState("Прочитано 16 байт из адреса 0x" + hex(addr,8));
});
}
}
function writeAddr(addr, data) {
if (myCharacteristic) {
len = data.length;
if(len != 0 && len <= 16) {
let blk = new Uint8Array(len + 5);
blk.set([0xdb, addr&0xff, (addr>>8)&0xff, (addr>>16)&0xff, (addr>>24)&0xff]);
blk.set(data, 5);
console.log(blk);
myCharacteristic.writeValue(blk);
showState("Записано " + len + " байт по адресу 0x" + hex(addr,8));
} else {
console.log(data);
showState('Ошибка, длина блока от 1 до 16 байт!');
}
}
}
function infoReadAddr() {
if(myCharacteristic) {
let faddr = parseInt($('inputAddr').value, 16);
readAddr(faddr);
}
}
function writeCmd(data) {
if(myCharacteristic) {
len = data.length;
if(len != 0 && len <= 20) {
let blk = new Uint8Array(data);
console.log(blk);
myCharacteristic.writeValue(blk);
} else {
console.log(data);
showState('Ошибка, длина команды от 1 до 20 байт!');
}
}
}
function sendData() {
let addr = parseInt($('inputAddr').value, 16);
let data = hexToBytes($('inputData').value);
if(data.length != 0 && data.length <= 16)
writeAddr(addr, data);
else
console.log('Ошибка, длина от 1 до 16 байт!');
}
function sendCommand() {
let data = hexToBytes($('inpCmdData').value);
if(data.length != 0 && data.length <= 20)
WriteCmd(data);
else
console.log('Должно быть от 1 до 20 hex байт!');
}
function customBlkParse(value) {
let len = value.byteLength;
if(len == 0) return;
len--; // size from cmd
let blkId = value.getUint8(0);
s = 'Ответ на команду Id: ' + hex(blkId,2) + ' data: ' + bytesToHex(value.buffer.slice(1));
addLog(s);
if((blkId == 0xdb) && (value.byteLength > 4)) {
len -= 4;
let addr = value.getUint32(1,true);
let s = bytesToHex(value.buffer.slice(5), len);
$('inputData').value = s;
addLog(hex(addr,8) + ':' + s);
showProgress("Считано: " + len + " байт из 0x" + hex(addr,8));
} else
console.log('blk: ' + dump8(value, value.byteLength));
}
var url;
function download(data, filename, type) {
var file = new Blob([data], {type: type});
if (window.navigator.msSaveOrOpenBlob) { // ie10+
window.navigator.msSaveOrOpenBlob(file, filename);
} else { // ff, chrome
url = URL.createObjectURL(file);
let a = document.createElement("a");
a.href = url;
a.download = filename;
document.body.appendChild(a);
a.click();
setTimeout(function(){document.body.removeChild(a);window.URL.revokeObjectURL(url);},0);
URL.revokeObjectURL(url);
}
}
function readFile(file) {
var reader = new FileReader();
if (file != null) {
reader.readAsArrayBuffer(file);
} else {
showError("Файл не загружен");
}
reader.onload = function() {
// console.log(this.result);
firmwareArray = bytesToHex(this.result);
if(firmwareArray.substring(0,4) != "1234"){
blockCount = 0;
firmwareArray = "";
$("lblFile").innerHTML = "не загружен";
alert("Выбранный файл не для PHY62x2 OTA!");
showError("Выбранный файл не для PHY62x2 OTA!");
return;
}
showState("Файл загружен, размер: " + firmwareArray.length / 2 + " байт");
if (firmwareArray.length % 32 !== 0) { // pad last block to 16bytes
var padHex = "ffffffffffffffffffffffffffffffff";
firmwareArray += padHex.substr(0, 32 - firmwareArray.length % 32);
}
blockCount = firmwareArray.length / 32;
addLog("Блоков: " + blockCount);
}
reader.onerror = function() {
console.log(this.error);
};
}
const selectFile = function() {
let regex = /[^\\]+$/
this.choose,
this.selected
this.msg = str => {
let prefix = '[selectFile]\n\nError: '
return alert(prefix+str)
}
this.check = () => {
if (this.choose && this.selected != null) {
let choose = document.getElementById(this.choose),
selected = document.getElementById(this.selected)
choose.addEventListener('change',() => {
if (choose.value != '') {
selected.innerHTML = choose.value.match(regex);
readFile(choose.files[0]);
}
})
} else {
this.msg('Targets not set.')
}
}
selectFile.prototype.targets = (trigger, filetext) => {
this.choose = trigger
this.selected = filetext
}
selectFile.prototype.simulate = () => {
if (this.choose != null) {
let choose = document.getElementById(this.choose)
if (typeof choose != 'undefined') {
choose.click()
this.check()
} else {
this.msg('Could not find element '+this.choose)
}
} else {
this.msg('Targets not set.')
}
}
};
var getFile = new selectFile;
getFile.targets('inpFile','lblFile');
function openTab(evt, tabName) {
var i, tabcontent, tablinks;
tabcontent = document.getElementsByClassName("tabcontent");
for (i = 0; i < tabcontent.length; i++) {
tabcontent[i].style.display = "none";
}
tablinks = document.getElementsByClassName("tablinks");
for (i = 0; i < tablinks.length; i++) {
tablinks[i].className = tablinks[i].className.replace(" active", "");
}
document.getElementById(tabName).style.display = "block";
evt.currentTarget.className += " active";
console.log(evt.currentTarget.className);
}
window.onload = function() {
$("btnSave").onclick = function() { download(flash_buf, 'ff.bin', 'application/octet-stream;charset=utf-8'); };
}
window.onload = (event) => {
// console.log("page is fully loaded");
showState("Нет подключения" )
openTab(event, 'tabOTA');
// Selected Tab header style
tablinks = document.getElementsByClassName("tablinks");
tablinks[0].className += " active";
};
</script>
<h2>PHY62x2-BTHome <a href="https://github.com/pvvx/THB2"><small>&#9432;</small></a></h2>
<label for="inpNamePrefix">Префикс названия устройств(а)</label><br>
<input type="text" id="inpNamePrefix" value="" placeholder="THB, BT">
<hr>
<label id="lblStatus">Состояние: загрузка страницы</label>
<br><br><hr>
<button type="button" id="btnConnect" onclick="connect()">Соединение</button>
<button type="button" id="btnDisconnect" onclick="disconnect()" disabled="true">Отключение</button>
<button type="button" id="btnReconnect" onclick="reconnect()" disabled="true">Переподключение</button>
<br><hr>
<div class="tab">
<button class="tablinks" onclick="openTab(event, 'tabOTA')">OTA</button>
<button class="tablinks" onclick="openTab(event, 'tabFlash')">Flash</button>
<button class="tablinks" onclick="openTab(event, 'tabService')">Service</button>
</div>
<div id="tabOTA" class="tabcontent">
<p>Файл прошивки:
<input type=file hidden id=inpFile>
<label id=lblFile>не выбран</label>
<button type=button onClick=getFile.simulate()>Выбрать</button>
<p>
<hr>
<button type="button"id="btnStartDFU" onclick="startDFU()" disabled="true" >Старт программирования</button>
</div>
<div id="tabFlash" class="tabcontent">
<p>
<button type="button" id="btnReadFF" onclick="startReadFF()" disabled="true">Прочитать</button>
<button type="button" id="btnSave" disabled="true">Сохранить в файл</button>
<p>
</div>
<div id="tabService" class="tabcontent">
Чтение и запись памяти:<br>
Адрес (hex): <input size="8" type="text" id="inputAddr" value="11000000" maxlength="8">
<button type="button" id="btnReadAddr" onclick="infoReadAddr()" disabled="true">Прочитать</button>
Данные (hex): <input size="32" type="text" id="inputData" value="?" maxlength="32">
<button type="button" id="btnSendData" onclick="sendData()" disabled="true">Записать</button><hr>
<button type="button" id="btnSendCommand" onclick="sendCommand()" disabled="true">Команда</button>
<input type="text" id="inpCmdData" value="55" size="40" maxlength="40"><hr>
</div>
<hr>
<button type="button" onclick="clearLog()">Очистить лог</button><br>
<div id="log"></div>
</body></html>

View file

@ -0,0 +1,40 @@
01ff 50485936 593601000000200100111001000020
01ff 01000000 50485936 593601000000200100111001000020
01ff 20010011 50485936 0100
01ff 20010011 50485936 0010
01ff 20010011 50485936 1200
ffffffff010000002000011110010000
0000504859360100000020000111100100004388
Ñòàðò DFU
OTA send: 00ff
OTA read: ver: 01, err: 0, dbg: 0, start: 0, offs: 0x11010020, idx: 0x0010, total: 0x0011, crc: 0xC012FD5E
OTA send: 01ff20000111504859361200
OTA read: ver: 01, err: 0, dbg: 0, start: 1, offs: 0x11010020, idx: 0xFFFF, total: 0x0012, crc: 0xC012FD5E
OTA send: 0000504859360100000020000111100100004388
OTA read: ver: 01, err: 0, dbg: 0, start: 1, offs: 0x11010020, idx: 0x0000, total: 0x0012, crc: 0x557AB31D
OTA send: 010020010000f00000002000011100000000440b
OTA read: ver: 01, err: 0, dbg: 0, start: 1, offs: 0x11010020, idx: 0x0001, total: 0x0012, crc: 0xD52EEB28
OTA send: 020000000000000000000000000000000000d05c
OTA read: ver: 01, err: 0, dbg: 0, start: 1, offs: 0x11010020, idx: 0x0002, total: 0x0012, crc: 0x04517BB9
OTA send: 03000000000000000000000000000000000081a0
OTA read: ver: 01, err: 0, dbg: 0, start: 1, offs: 0x11010020, idx: 0x0003, total: 0x0012, crc: 0xD28B9AE6
OTA send: 04000000000000000000000000000000000030d5
OTA read: ver: 01, err: 0, dbg: 0, start: 1, offs: 0x11010020, idx: 0x0004, total: 0x0012, crc: 0x5E306857
OTA send: 0500000000000000000000000000000000006129
OTA read: ver: 01, err: 0, dbg: 0, start: 1, offs: 0x11010020, idx: 0x0005, total: 0x0012, crc: 0xE0ADC600
OTA send: 060000000000000000000000000000000000916d
OTA read: ver: 01, err: 0, dbg: 0, start: 1, offs: 0x11010020, idx: 0x0006, total: 0x0012, crc: 0xF1F2471C
29:29: Ïîèñê óñòðîéñòâ
29:31: Connecting to: BTH01-31BDBC
29:31: OTA: FF010100200001111100120050485936E5394CC0
29:31: DevCfg: 000000001F501D000206B400
29:31: Óñòðîéñòâî ïîäêëþ÷åíî.
29:33: Ôàéë:
29:33: PHY6 OTA ID: 36594850, Ñåãìåíòîâ: 1, Ñòàðò: 0x11010000, Ðàçìåð: 20304 áàéò
29:33: Ðàçìåð ôàéëà: 20308 áàéò
29:33: Ñ÷åò÷èê: 1270
29:46: Ñòàðò ïðîãðàììèðîâàíèÿ...
31:56: Ïðîãðàììèðîâàíèå çàâåðøåíî çà 129.404 ñåêóíä

Binary file not shown.