Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
5c83794
protocoldetector: remove unnecessary include
jaxxzer Dec 19, 2023
c64f8bb
protocoldetector: quiet debug output by only printing buffer when it …
jaxxzer Dec 19, 2023
466c850
protocoldetector: update comment to reflect implementation
jaxxzer Dec 19, 2023
dcf1ddd
sensor: ping360: send motor_off command during destruction
jaxxzer Dec 19, 2023
eeab609
flash: make Flasher class valid baud rates available to qml
jaxxzer Dec 19, 2023
ea41de8
qml: use Flasher cpp object valid baudrates for selection
jaxxzer Dec 19, 2023
0635d5d
qml: FirmwareUpdate: use 115200 instead of 57600 for default flash ba…
jaxxzer Jan 24, 2024
93b3df3
qml: stop protocol detector when displaying manual connection page
jaxxzer Dec 19, 2023
50403f3
flash: refactor flasher class in preparation for Ping360 subclass
jaxxzer Dec 19, 2023
4b84c23
sensor: make sensor _flasher member a pointer to allow dynamic polymo…
jaxxzer Dec 19, 2023
c52933e
lib: add libcintelhex dependency for ping360 flashing
jaxxzer Dec 19, 2023
72d2084
flash: add new sources for Ping360 flashing
jaxxzer Dec 19, 2023
184cba1
cmake: add C language support for libcintelhex dependency
jaxxzer Dec 19, 2023
925e4d2
cmake: add libcintelhex to global includes
jaxxzer Dec 19, 2023
05c9c52
flash: cmake: add ping360 flash sources to build
jaxxzer Dec 19, 2023
32f7c46
link: seriallink: add method to get the current baudrate
jaxxzer Jan 31, 2024
7b8a2e6
sensor: ping360: implement firmware update functionality
jaxxzer Dec 19, 2023
443f27c
qml: MainPage: make FirmwareUpdate visible for ping360
jaxxzer Dec 19, 2023
37f53dc
protocoldetector: check for ping360 bootloader during scan
jaxxzer Dec 19, 2023
4e89797
sensor: ping360: add check for bootloader
jaxxzer Dec 19, 2023
679cd50
qml: Ping360Visualizer: add bootloader notification
jaxxzer Dec 19, 2023
b19ecbe
sensor: ping360: send async profile request when settings are valid
jaxxzer Dec 19, 2023
b2778e1
sensor: ping360: allow _profileRequestLogic.type to be updated more t…
jaxxzer Dec 19, 2023
791aba6
sensor: ping360: add some debug messages about profile timeout
jaxxzer Jan 23, 2024
0fc50cf
sensor: ping360: remove profile timeout for AUTO_DEVICE_DATA
jaxxzer Jan 23, 2024
085bc22
link: seriallink: extend delay for line break auto baudrate procedure
jaxxzer Feb 1, 2024
9a5558f
sensor: ping360: change default end_angle from 400 to 399
jaxxzer Feb 1, 2024
5822501
sensor: ping360: add num_steps to sensor settings struct
jaxxzer Feb 1, 2024
7ce0755
sensor: ping360: reset serial link during message timeout
jaxxzer Oct 8, 2024
a438fb7
qml: PingStatus: add patch number to firmware version number
jaxxzer Oct 9, 2024
b8ae0a0
sensor: ping360: handle NACK for AUTO_TRANSMIT, print nack messages a…
jaxxzer Oct 11, 2024
b2d4394
sensor: ping360: log async profile requests
jaxxzer Oct 11, 2024
2880c50
sensor: ping360: ensure valid settings in set_speed_of_sound
jaxxzer Oct 11, 2024
e2b6031
sensor: ping360: use startConfiguration after checking bootloader
jaxxzer Feb 21, 2025
366e109
abstractlink: allow 0 length for write
jaxxzer Mar 24, 2025
09d7b59
sensor: ping360: refactor resetting the baudrate, support network links
jaxxzer Mar 24, 2025
658307b
protocoldetector: signal line break for serial bridge program on netw…
jaxxzer Mar 24, 2025
cb78253
sensor: ping360: add counter for incoming messages before retrying a …
jaxxzer Mar 24, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,6 @@
[submodule "lib/fmt/fmt"]
path = lib/fmt/fmt
url = https://github.com/fmtlib/fmt
[submodule "lib/libcintelhex"]
path = lib/libcintelhex
url = https://github.com/jaxxzer/libcintelhex
5 changes: 3 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.12)
project(ping-viewer LANGUAGES CXX)
project(ping-viewer LANGUAGES CXX C)

set(CMAKE_CXX_STANDARD 17)
set(CXX_STANDARD_REQUIRED ON)
Expand Down Expand Up @@ -50,11 +50,12 @@ message(STATUS "Qt Version: ${Qt5_VERSION}")
# global include directories
include_directories(
lib/fmt/fmt/include/
lib/ping-cpp/ping-cpp/src/message/
lib/libcintelhex/include
lib/maddy/maddy/include/
lib/mavlink/c_library_v2/
lib/mavlink/c_library_v2/minimal
lib/mavlink/c_library_v2/common
lib/ping-cpp/ping-cpp/src/message/
)

add_subdirectory(lib/fmt/fmt)
Expand Down
1 change: 1 addition & 0 deletions lib/libcintelhex
Submodule libcintelhex added at 2db480
16 changes: 13 additions & 3 deletions qml/DeviceManagerViewer.qml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,14 @@ PingPopup {

closePolicy: Popup.NoAutoClose
onVisibleChanged: {
visible ? DeviceManager.startDetecting() : DeviceManager.stopDetecting();
print(stack.depth);
if (visible) {
if (stack.depth == 1)
DeviceManager.startDetecting();

} else {
DeviceManager.stopDetecting();
}
}
Component.onCompleted: {
if (!DeviceManager.primarySensor)
Expand Down Expand Up @@ -57,10 +64,13 @@ PingPopup {
Layout.fillWidth: true
onClicked: {
print(stack.depth);
if (stack.depth == 1)
if (stack.depth == 1) {
DeviceManager.stopDetecting();
stack.push(connectionMenu);
else
} else {
DeviceManager.startDetecting();
stack.pop();
}
}
}

Expand Down
5 changes: 2 additions & 3 deletions qml/FirmwareUpdate.qml
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,7 @@ RowLayout {
PingComboBox {
id: baudComboBox

// This should use the same values in Flasher::_validBaudRates
model: [57600, 115200, 230400]
model: ping.flasher.validBaudRates
Layout.fillWidth: true
visible: SettingsManager.debugMode
}
Expand Down Expand Up @@ -159,7 +158,7 @@ RowLayout {
Layout.fillWidth: true
enabled: !running && ((fwCombo.currentText != "" && !browseBt.visible) || (fileDialog.fileName != "" && browseBt.visible))
onClicked: {
var baud = SettingsManager.debugMode ? baudComboBox.model[baudComboBox.currentIndex] : 57600;
var baud = SettingsManager.debugMode ? baudComboBox.model[baudComboBox.currentIndex] : 115200;
var verify = SettingsManager.debugMode ? verifyCB.checked : true;
var path = automaticUpdateCB.currentIndex ? fileDialog.fileUrl : ping.firmwaresAvailable[fwCombo.currentText];
running = true;
Expand Down
1 change: 0 additions & 1 deletion qml/MainPage.qml
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,6 @@ Item {
PingItem {
id: firmwareUpdateItem

visible: ping ? ping.link.configuration.deviceType() == PingEnumNamespace.PingDeviceType.PING1D : false
isSubItem: true
icon: StyleManager.firmwareUpdateIcon()
onHideItemChanged: {
Expand Down
16 changes: 16 additions & 0 deletions qml/Ping360Visualizer.qml
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,22 @@ Item {
visible: false
}

Text {
id: bootloaderWarning

visible: ping.isBootloader
anchors.fill: waterfall
anchors.margins: 5
font.bold: true
font.family: "Arial"
font.pointSize: 15
text: "Ping360 is in Bootloader Mode. Please flash firmware."
color: "red"
z: 100
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}

Text {
id: mouseReadout

Expand Down
2 changes: 1 addition & 1 deletion qml/PingStatus.qml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Item {
if (!ping)
return ;

baseModel.model = ["FW: " + ping.firmware_version_major + "." + ping.firmware_version_minor, "SRC: " + ping.srcId + " DST: " + ping.dstId, "Device type: " + ping.device_type, "Device Revision: " + ping.device_revision, "Connection: " + ping.link.configuration.string, "RX Packets (#): " + ping.parsed_msgs, "RX Errors (#): " + ping.parser_errors, "TX speed (Bytes/s): " + ping.link.upSpeed, "RX speed (Bytes/s): " + ping.link.downSpeed, "Lost messages (#): " + ping.lost_messages, "Ascii text:\\n" + ping.ascii_text, "Error message:\\n" + ping.nack_message];
baseModel.model = ["FW: " + ping.firmware_version_major + "." + ping.firmware_version_minor + "." + ping.firmware_version_patch, "SRC: " + ping.srcId + " DST: " + ping.dstId, "Device type: " + ping.device_type, "Device Revision: " + ping.device_revision, "Connection: " + ping.link.configuration.string, "RX Packets (#): " + ping.parsed_msgs, "RX Errors (#): " + ping.parser_errors, "TX speed (Bytes/s): " + ping.link.upSpeed, "RX speed (Bytes/s): " + ping.link.downSpeed, "Lost messages (#): " + ping.lost_messages, "Ascii text:\\n" + ping.ascii_text, "Error message:\\n" + ping.nack_message];
}
}

Expand Down
10 changes: 10 additions & 0 deletions src/flash/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
file(GLOB LIBCINTELHEXFILES
${PROJECT_SOURCE_DIR}/lib/libcintelhex/src/ihex_parse.c
${PROJECT_SOURCE_DIR}/lib/libcintelhex/src/ihex_record.c
)

add_library(
flash
STATIC
flasher.cpp
pic-hex.cpp
ping360bootloaderpacket.cpp
ping360flasher.cpp
ping360flashworker.cpp
${LIBCINTELHEXFILES}
)

target_link_libraries(
Expand Down
3 changes: 2 additions & 1 deletion src/flash/flasher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@

PING_LOGGING_CATEGORY(FLASH, "ping.flash")

Flasher::Flasher(QObject* parent)
Flasher::Flasher(QObject* parent, const QList<QVariant> validBaudRates)
: QObject(parent)
, _validBaudRates(validBaudRates)
{
_binRelativePath =
#ifdef Q_OS_OSX
Expand Down
25 changes: 18 additions & 7 deletions src/flash/flasher.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ class Flasher : public QObject {
* @brief Construct a new Flasher object
*
* @param parent
* @param validBaudRates
*/
Flasher(QObject* parent = nullptr);
Flasher(QObject* parent = nullptr, const QList<QVariant> validBaudRates = {57600, 115200, 230400});

/**
* @brief Destroy the Flasher object
Expand Down Expand Up @@ -72,11 +73,17 @@ class Flasher : public QObject {
Flasher::States state() const { return _state; };
Q_PROPERTY(Flasher::States state READ state NOTIFY stateChanged)

/**
* @brief Return the valid baud rates for device communication
*/
const QVariantList& validBaudRates() const { return _validBaudRates; };
Q_PROPERTY(QVariant validBaudRates READ validBaudRates CONSTANT);

/**
* @brief Start the flash procedure
*
*/
void flash();
virtual void flash();

/**
* @brief Set the flash baud rate
Expand Down Expand Up @@ -111,17 +118,21 @@ class Flasher : public QObject {
void flashProgress(float progress);
void stateChanged(Flasher::States state);

protected:
int _baudRate = 57600;
QString _firmwareFilePath;
LinkConfiguration _link;
const QList<QVariant> _validBaudRates;
bool _verify = true;

private:
void firmwareUpdatePercentage(const QString& output);
static QString stm32flashPath();

int _baudRate = 57600;
QString _binRelativePath;
QString _firmwareFilePath;
QSharedPointer<QProcess> _firmwareProcess;
LinkConfiguration _link;
QString _message;
States _state = Idle;
const QList<int> _validBaudRates = {57600, 115200, 230400};
bool _verify = true;
};

Q_DECLARE_METATYPE(Flasher::States);
138 changes: 138 additions & 0 deletions src/flash/pic-hex.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
#include "pic-hex.h"

#include <stdio.h>
#include <string.h>

bool PicHex::pic_hex_read_file(const char* filename)
{
printf("extracting pic hex application data\n");
if (!pic_hex_extract_application(filename)) {
return false;
}
printf("extracting pic hex configuration data\n");
if (!pic_hex_extract_configuration(filename)) {
return false;
}
return true;
}

bool PicHex::pic_hex_extract_application(const char* filename)
{
ihex_recordset_t* record_set = ihex_rs_from_file(filename);

if (record_set == 0) {
printf("failed to read recordset from file %s\n", filename);
return false;
}

bool ret = pic_hex_mem_cpy(
record_set, pic_hex_application_data, sizeof(pic_hex_application_data), PROGRAM_MEMORY_OFFSET);
ihex_rs_free(record_set);
return ret;
}

bool PicHex::pic_hex_extract_configuration(const char* filename)
{
ihex_recordset_t* record_set = ihex_rs_from_file(filename);

if (record_set == 0) {
printf("failed to read recordset from file %s\n", filename);
return false;
}

bool ret = pic_hex_mem_cpy(
record_set, pic_hex_configuration_data, sizeof(pic_hex_configuration_data), CONFIGURATION_MEMORY_OFFSET);
ihex_rs_free(record_set);
return ret;
}

/*
* Address equations for your convenience:
*
* | ihex | pic | data |
* | 0x000000 | 0x000000 | 0x000000 |
* | 0x000800 | 0x000400 | 0x000600 |
* | 0x001000 | 0x000800 | 0x000c00 |
* | 0x001800 | 0x000c00 | 0x001200 |
* | 0x002000 | 0x001000 | 0x001800 |
*/
bool PicHex::pic_hex_mem_cpy(ihex_recordset_t* record_set, uint8_t* destination, uint32_t length, uint32_t offset)
{
uint_t i = 0; // current record #
uint32_t record_offset, record_address = 0x00;

// record iterator
ihex_record_t* record;

// zero-initialize destination data
memset(destination, 0, length);

do {
int r = ihex_rs_iterate_data(record_set, &i, &record, &record_offset);

// check error code
if (r) {
return false;
// check record is valid
} else if (record == 0) {
// we reached the end of the list
break;
}

////////////////////////////
// hex contains 16 bit words, addressed to 16 bit memory
////////////////////////////

// get the record address
record_address = (record_offset + record->ihr_address);

///////////////////////////////////////////
// memory contains 24 bit words, addressed to 32 bit memory (address/2)
///////////////////////////////////////////

record_address = record_address / 2;

// record out of range low
if (record_address < offset) {
// printf("warn, record %d address %08x below offset %08x\r\n", i, record_address, offset);
continue;
}

// record out of range high
if (record_address >= offset + length) {
// printf("warn, record %d address %08x beyond range %08x + %08x\r\n", i, record_address, offset, length);
continue;
}

//////////////////////////////////////////////////
// transmit data array contains 24 bit words *(3/2)
//////////////////////////////////////////////////

uint32_t destination_address = (3 * (record_address - offset)) / 2;

// record out of range high
if (destination_address >= length) {
// printf("warn, destination address %08x beyond range %08x + %08x\r\n", destination_address, offset,
// length);
continue;
}

for (int j = 0; j < record->ihr_length; j += 4) {
uint32_t destination_offset = destination_address + j - (j / 4);
if (destination_offset > length) {
// printf("warn, destination offset %08x beyond destination length %d", destination_offset, length);
continue;
}
// pointer to destination byte
uint8_t* target = (uint8_t*)(destination + destination_offset);

// copy a 24 bit word
for (int l = 0; (l < 3); l++) {

*(target++) = record->ihr_data[j + l];
}
}
} while (i > 0);

return true;
}
43 changes: 43 additions & 0 deletions src/flash/pic-hex.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#pragma once

#include <cintelhex.h>

/**
* @brief facilities to convert an intel hex to PIC microcontroller memory space
*/
class PicHex {
public:
// 86 pages * 512 words * 3 bytes
static const uint32_t PROGRAM_MEMORY_SIZE = 0x20400;
static const uint32_t PROGRAM_MEMORY_OFFSET = 0x0;

// 24 bytes configuration in separate memory region
static const uint32_t CONFIGURATION_MEMORY_SIZE = 24;
static const uint32_t CONFIGURATION_MEMORY_OFFSET = 0x00F80000;

/**
* @brief read a hex file and extract the firmware application and configuration data
* @param filename
* @return true if application and configuration data were successfully extracted
*/
bool pic_hex_read_file(const char* filename);

/**
* @brief The hex file data for the application memory region
* this data is valid if pic_hex_read_file returns true
*/
uint8_t pic_hex_application_data[PROGRAM_MEMORY_SIZE];

/**
* @brief The hex file data for the configuration memory region
* The configuration memory region is located at CONFIGURATION_MEMORY_OFFSET
* and is CONFIGURATION_MEMORY_SIZE bytes wide
* this data is valid if pic_hex_read_file returns true
*/
uint8_t pic_hex_configuration_data[CONFIGURATION_MEMORY_SIZE];

private:
bool pic_hex_mem_cpy(ihex_recordset_t* record_set, uint8_t* destination, uint32_t length, uint32_t offset);
bool pic_hex_extract_application(const char* filename);
bool pic_hex_extract_configuration(const char* filename);
};
Loading
Loading