openpilot is an open source driver assistance system. openpilot performs the functions of Automated Lane Centering and Adaptive Cruise Control for over 200 supported car makes and models.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

237 lines
6.3 KiB

#pragma once
// The following ifdef block is the standard way of creating macros which make exporting
// from a DLL simpler. All files within this DLL are compiled with the PANDA_EXPORTS
// symbol defined on the command line. This symbol should not be defined on any project
// that uses this DLL. This way any other project whose source files include this file see
// PANDA_API functions as being imported from a DLL, whereas this DLL sees symbols
// defined with this macro as being exported.
#ifdef PANDA_EXPORTS
#define PANDA_API __declspec(dllexport)
#else
#define PANDA_API
#endif
#include <vector>
#include <string>
#include <unordered_map>
#include <memory>
#include <iostream>
#include <chrono>
#include <windows.h>
#include <winusb.h>
#if defined(UNICODE)
#define _tcout std::wcout
#define tstring std::wstring
#else
#define _tcout std::cout
#define tstring std::string
#endif
#define LIN_MSG_MAX_LEN 10
#define CAN_RX_QUEUE_LEN 10000
#define CAN_RX_MSG_LEN 1000
//template class __declspec(dllexport) std::basic_string<char>;
namespace panda {
typedef enum _PANDA_SAFETY_MODE : uint16_t {
SAFETY_NOOUTPUT = 0,
SAFETY_HONDA = 1,
SAFETY_ALLOUTPUT = 0x1337,
} PANDA_SAFETY_MODE;
typedef enum _PANDA_SERIAL_PORT : uint8_t {
SERIAL_DEBUG = 0,
SERIAL_ESP = 1,
SERIAL_LIN1 = 2,
SERIAL_LIN2 = 3,
} PANDA_SERIAL_PORT;
typedef enum _PANDA_SERIAL_PORT_PARITY : uint8_t {
PANDA_PARITY_OFF = 0,
PANDA_PARITY_EVEN = 1,
PANDA_PARITY_ODD = 2,
} PANDA_SERIAL_PORT_PARITY;
typedef enum _PANDA_CAN_PORT : uint8_t {
PANDA_CAN1 = 0,
PANDA_CAN2 = 1,
PANDA_CAN3 = 2,
PANDA_CAN_UNK = 0xFF,
} PANDA_CAN_PORT;
typedef enum _PANDA_CAN_PORT_CLEAR : uint16_t {
PANDA_CAN1_TX = 0,
PANDA_CAN2_TX = 1,
PANDA_CAN3_TX = 2,
PANDA_CAN_RX = 0xFFFF,
} PANDA_CAN_PORT_CLEAR;
typedef enum _PANDA_GMLAN_HOST_PORT : uint8_t {
PANDA_GMLAN_CLEAR = 0,
PANDA_GMLAN_CAN2 = 1,
PANDA_GMLAN_CAN3 = 2,
} PANDA_GMLAN_HOST_PORT;
#pragma pack(1)
typedef struct _PANDA_HEALTH {
uint32_t voltage;
uint32_t current;
uint8_t started;
uint8_t controls_allowed;
uint8_t gas_interceptor_detected;
uint8_t started_signal_detected;
uint8_t started_alt;
} PANDA_HEALTH, *PPANDA_HEALTH;
typedef struct _PANDA_CAN_MSG {
uint32_t addr;
unsigned long long recv_time; //In microseconds since device initialization
std::chrono::time_point<std::chrono::steady_clock> recv_time_point;
uint8_t dat[8];
uint8_t len;
PANDA_CAN_PORT bus;
bool is_receipt;
bool addr_29b;
} PANDA_CAN_MSG;
//Copied from https://stackoverflow.com/a/31488113
class Timer
{
using clock = std::chrono::steady_clock;
using time_point_type = std::chrono::time_point < clock, std::chrono::microseconds >;
public:
Timer() {
start = std::chrono::time_point_cast<std::chrono::microseconds>(clock::now());
}
// gets the time elapsed from construction.
unsigned long long /*microseconds*/ Timer::getTimePassedUS() {
// get the new time
auto end = std::chrono::time_point_cast<std::chrono::microseconds>(clock::now());
// return the difference of the times
return (end - start).count();
}
// gets the time elapsed from construction.
unsigned long long /*milliseconds*/ Timer::getTimePassedMS() {
// get the new time
auto end = std::chrono::time_point_cast<std::chrono::milliseconds>(clock::now());
// return the difference of the times
auto startms = std::chrono::time_point_cast<std::chrono::milliseconds>(start);
return (end - startms).count();
}
private:
time_point_type start;
};
// This class is exported from the panda.dll
class PANDA_API Panda {
public:
static std::vector<std::string> listAvailablePandas();
static std::unique_ptr<Panda> openPanda(std::string sn);
~Panda();
std::string get_usb_sn();
bool set_alt_setting(UCHAR alt_setting);
UCHAR get_current_alt_setting();
bool Panda::set_raw_io(bool val);
PANDA_HEALTH get_health();
bool enter_bootloader();
std::string get_version();
std::string get_serial();
std::string get_secret();
bool set_usb_power(bool on);
bool set_esp_power(bool on);
bool esp_reset(uint16_t bootmode);
bool set_safety_mode(PANDA_SAFETY_MODE mode);
bool set_can_forwarding(PANDA_CAN_PORT from_bus, PANDA_CAN_PORT to_bus);
bool set_gmlan(PANDA_GMLAN_HOST_PORT bus);
bool set_can_loopback(bool enable);
bool set_can_speed_cbps(PANDA_CAN_PORT bus, uint16_t speed);
bool set_can_speed_kbps(PANDA_CAN_PORT bus, uint16_t speed);
bool set_uart_baud(PANDA_SERIAL_PORT uart, uint32_t rate);
bool set_uart_parity(PANDA_SERIAL_PORT uart, PANDA_SERIAL_PORT_PARITY parity);
bool can_send_many(const std::vector<PANDA_CAN_MSG>& can_msgs);
bool can_send(uint32_t addr, bool addr_29b, const uint8_t *dat, uint8_t len, PANDA_CAN_PORT bus);
std::vector<PANDA_CAN_MSG> can_recv();
bool can_rx_q_push(HANDLE kill_event, DWORD timeoutms = INFINITE);
void can_rx_q_pop(PANDA_CAN_MSG msg_out[], int &count);
bool can_clear(PANDA_CAN_PORT_CLEAR bus);
std::string serial_read(PANDA_SERIAL_PORT port_number);
int serial_write(PANDA_SERIAL_PORT port_number, const void* buff, uint16_t len);
bool serial_clear(PANDA_SERIAL_PORT port_number);
private:
Panda(
WINUSB_INTERFACE_HANDLE WinusbHandle,
HANDLE DeviceHandle,
tstring devPath_,
std::string sn_
);
int control_transfer(
uint8_t bmRequestType,
uint8_t bRequest,
uint16_t wValue,
uint16_t wIndex,
void * data,
uint16_t wLength,
unsigned int timeout
);
int bulk_write(
UCHAR endpoint,
const void * buff,
ULONG length,
PULONG transferred,
ULONG timeout
);
int Panda::bulk_read(
UCHAR endpoint,
void * buff,
ULONG buff_size,
PULONG transferred,
ULONG timeout
);
#pragma pack(1)
typedef struct _PANDA_CAN_MSG_INTERNAL {
uint32_t rir;
uint32_t f2;
uint8_t dat[8];
} PANDA_CAN_MSG_INTERNAL;
typedef struct _CAN_RX_PIPE_READ {
unsigned char data[sizeof(PANDA_CAN_MSG_INTERNAL) * CAN_RX_MSG_LEN];
unsigned long count;
OVERLAPPED overlapped;
HANDLE complete;
DWORD error;
} CAN_RX_PIPE_READ;
PANDA_CAN_MSG parse_can_recv(PANDA_CAN_MSG_INTERNAL *in_msg_raw);
WINUSB_INTERFACE_HANDLE usbh;
HANDLE devh;
tstring devPath;
std::string sn;
bool loopback;
Timer runningTime;
CAN_RX_PIPE_READ can_rx_q[CAN_RX_QUEUE_LEN];
unsigned long w_ptr = 0;
unsigned long r_ptr = 0;
};
}