Files
Jason Wen 14318d2f09 Merge commit '91b067cca0913d0cc9f8b5dab68e3302e278efdc' into sync-20260716
# Conflicts:
#	.github/labeler.yaml
#	.github/workflows/auto_pr_review.yaml
#	.github/workflows/docs.yaml
#	.github/workflows/release.yaml
#	.github/workflows/repo-maintenance.yaml
#	.github/workflows/tests.yaml
#	.github/workflows/ui_preview.yaml
#	README.md
#	SConstruct
#	conftest.py
#	docs/CARS.md
#	msgq_repo
#	opendbc_repo
#	openpilot/cereal/messaging/tests/validate_sp_cereal_upstream.py
#	openpilot/common/api.py
#	openpilot/common/hardware/hw.py
#	openpilot/common/version.py
#	openpilot/selfdrive/assets/fonts/Audiowide-Regular.ttf
#	openpilot/selfdrive/assets/sounds/prompt_single_high.wav
#	openpilot/selfdrive/assets/sounds/prompt_single_low.wav
#	openpilot/selfdrive/car/card.py
#	openpilot/selfdrive/car/helpers.py
#	openpilot/selfdrive/car/tests/test_car_interfaces.py
#	openpilot/selfdrive/car/tests/test_cruise_speed.py
#	openpilot/selfdrive/controls/lib/desire_helper.py
#	openpilot/selfdrive/controls/lib/longcontrol.py
#	openpilot/selfdrive/controls/plannerd.py
#	openpilot/selfdrive/controls/radard.py
#	openpilot/selfdrive/controls/tests/test_longcontrol.py
#	openpilot/selfdrive/modeld/compile_warp.py
#	openpilot/selfdrive/modeld/modeld.py
#	openpilot/selfdrive/monitoring/policy.py
#	openpilot/selfdrive/monitoring/test_monitoring.py
#	openpilot/selfdrive/selfdrived/events.py
#	openpilot/selfdrive/selfdrived/selfdrived.py
#	openpilot/selfdrive/ui/layouts/onboarding.py
#	openpilot/selfdrive/ui/mici/layouts/onboarding.py
#	openpilot/selfdrive/ui/soundd.py
#	openpilot/selfdrive/ui/tests/diff/replay.py
#	openpilot/selfdrive/ui/translations/app.pot
#	openpilot/system/athena/athenad.py
#	openpilot/system/athena/manage_athenad.py
#	openpilot/system/hardware/hardwared.py
#	openpilot/system/loggerd/config.py
#	openpilot/system/manager/github_runner.sh
#	openpilot/system/manager/manager.py
#	openpilot/system/updated/updated.py
#	panda
#	pyproject.toml
#	scripts/lint/lint.sh
#	system/manager/process_config.py
#	system/statsd.py
#	tinygrad_repo
#	tools/release/build_release.sh
#	tools/release/build_stripped.sh
#	uv.lock
2026-07-16 00:58:32 -04:00

96 lines
2.8 KiB
C++

#pragma once
#include <cstdint>
#include <ctime>
#include <functional>
#include <list>
#include <memory>
#include <optional>
#include <string>
#include <vector>
#include <atomic>
#include <mutex>
#include <libusb-1.0/libusb.h>
#include "openpilot/cereal/gen/cpp/car.capnp.h"
#include "openpilot/cereal/gen/cpp/log.capnp.h"
#include "panda/board/health.h"
#include "panda/board/can.h"
#define USB_TX_SOFT_LIMIT (0x100U)
#define USBPACKET_MAX_SIZE (0x40)
#define RECV_SIZE (0x4000U)
#define TIMEOUT 0
#define CAN_REJECTED_BUS_OFFSET 0xC0U
#define CAN_RETURNED_BUS_OFFSET 0x80U
#define PANDA_BUS_OFFSET 4
struct __attribute__((packed)) can_header {
uint8_t reserved : 1;
uint8_t bus : 3;
uint8_t data_len_code : 4;
uint8_t rejected : 1;
uint8_t returned : 1;
uint8_t extended : 1;
uint32_t addr : 29;
uint8_t checksum : 8;
};
struct can_frame {
long address;
std::string dat;
long src;
};
class Panda {
public:
Panda(std::string serial="", uint32_t bus_offset=0);
~Panda();
cereal::PandaState::PandaType hw_type = cereal::PandaState::PandaType::UNKNOWN;
const uint32_t bus_offset;
bool connected();
bool comms_healthy();
std::string hw_serial();
// Static functions
static std::vector<std::string> list(bool usb_only=false);
// Panda functionality
cereal::PandaState::PandaType get_hw_type();
void set_safety_model(cereal::CarParams::SafetyModel safety_model, uint16_t safety_param=0U);
void send_heartbeat(bool engaged, bool engaged_mads = false);
void set_can_speed_kbps(uint16_t bus, uint16_t speed);
void set_data_speed_kbps(uint16_t bus, uint16_t speed);
bool can_receive(std::vector<can_frame>& out_vec);
void can_reset_communications();
private:
// USB connection members
libusb_context *ctx = nullptr;
libusb_device_handle *dev_handle = nullptr;
std::string hw_serial_str;
std::atomic<bool> connected_flag = true;
std::atomic<bool> comms_healthy_flag = true;
// CAN buffer members
uint8_t receive_buffer[RECV_SIZE + sizeof(can_header) + 64];
uint32_t receive_buffer_size = 0;
// Internal methods
bool init_usb_connection(const std::string& serial);
void cleanup_usb();
void handle_usb_issue(int err, const char func[]);
int control_write(uint8_t request, uint16_t param1, uint16_t param2, unsigned int timeout=TIMEOUT);
int control_read(uint8_t request, uint16_t param1, uint16_t param2, unsigned char *data, uint16_t length, unsigned int timeout=TIMEOUT);
int bulk_write(unsigned char endpoint, unsigned char* data, int length, unsigned int timeout=TIMEOUT);
int bulk_read(unsigned char endpoint, unsigned char* data, int length, unsigned int timeout=TIMEOUT);
bool unpack_can_buffer(uint8_t *data, uint32_t &size, std::vector<can_frame> &out_vec);
uint8_t calculate_checksum(uint8_t *data, uint32_t len);
};