#pragma once #include #include #include #include #include #ifndef __APPLE__ #include #endif #include #define TIMEOUT 0 #define SPI_BUF_SIZE 1024 // comms base class class PandaCommsHandle { public: PandaCommsHandle(std::string serial) {}; virtual ~PandaCommsHandle() {}; virtual void cleanup() = 0; std::string hw_serial; std::atomic connected = true; std::atomic comms_healthy = true; static std::vector list(); // HW communication virtual int control_write(uint8_t request, uint16_t param1, uint16_t param2, unsigned int timeout=TIMEOUT) = 0; virtual int control_read(uint8_t request, uint16_t param1, uint16_t param2, unsigned char *data, uint16_t length, unsigned int timeout=TIMEOUT) = 0; virtual int bulk_write(unsigned char endpoint, unsigned char* data, int length, unsigned int timeout=TIMEOUT) = 0; virtual int bulk_read(unsigned char endpoint, unsigned char* data, int length, unsigned int timeout=TIMEOUT) = 0; }; class PandaUsbHandle : public PandaCommsHandle { public: PandaUsbHandle(std::string serial); ~PandaUsbHandle(); 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); void cleanup(); static std::vector list(); private: libusb_context *ctx = NULL; libusb_device_handle *dev_handle = NULL; std::recursive_mutex hw_lock; void handle_usb_issue(int err, const char func[]); }; #ifndef __APPLE__ class PandaSpiHandle : public PandaCommsHandle { public: PandaSpiHandle(std::string serial); ~PandaSpiHandle(); 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); void cleanup(); static std::vector list(); private: int spi_fd = -1; uint8_t tx_buf[SPI_BUF_SIZE]; uint8_t rx_buf[SPI_BUF_SIZE]; inline static std::recursive_mutex hw_lock; int wait_for_ack(spi_ioc_transfer &transfer, uint8_t ack); int bulk_transfer(uint8_t endpoint, uint8_t *tx_data, uint16_t tx_len, uint8_t *rx_data, uint16_t rx_len, unsigned int timeout); int spi_transfer(uint8_t endpoint, uint8_t *tx_data, uint16_t tx_len, uint8_t *rx_data, uint16_t max_rx_len); int spi_transfer_retry(uint8_t endpoint, uint8_t *tx_data, uint16_t tx_len, uint8_t *rx_data, uint16_t max_rx_len, unsigned int timeout); }; #endif