diff options
| author | Tim Redfern <tim@getdrop.com> | 2018-01-28 22:20:49 +0000 |
|---|---|---|
| committer | Tim Redfern <tim@getdrop.com> | 2018-01-28 22:20:49 +0000 |
| commit | 64c89ab53447a004002ec0b0db94fd0a1e632cf6 (patch) | |
| tree | 65ce3b4802bbb0656cc1a8c843c81d7a3fcda8c9 /ofxHelios/libs/libheliosdac/includes/HeliosDac.h | |
| parent | 404746784ce6ef2b87c396a12451947fee28b244 (diff) | |
POC driver
Diffstat (limited to 'ofxHelios/libs/libheliosdac/includes/HeliosDac.h')
| -rw-r--r-- | ofxHelios/libs/libheliosdac/includes/HeliosDac.h | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/ofxHelios/libs/libheliosdac/includes/HeliosDac.h b/ofxHelios/libs/libheliosdac/includes/HeliosDac.h new file mode 100644 index 0000000..ed1c5fc --- /dev/null +++ b/ofxHelios/libs/libheliosdac/includes/HeliosDac.h @@ -0,0 +1,169 @@ +/* +SDK for Helios Laser DAC class, HEADER +By Gitle Mikkelsen +gitlem@gmail.com + +Dependencies: +Libusb 1.0 (GNU Lesser General Public License, see libusb.h) + +Standard: C++14 +git repo: https://github.com/Grix/helios_dac.git + +BASIC USAGE: +1. Call OpenDevices() to open devices, returns number of available devices. +2. To send a frame to the DAC, first call GetStatus(). If the function returns ready (1), + then you can call WriteFrame(). The status should be polled until it returns ready. + It can and sometimes will fail to return ready on the first try. +3. To stop output, use Stop(). To restart output you must send a new frame as described above. +4. When the DAC is no longer needed, destroy the instance (destructors will free everything and close the connection) + +The DAC is double-buffered. When it receives its first frame, it starts outputting it. When a second frame is sent to +the DAC while the first frame is being played, the second frame is stored in the DACs memory until the first frame +finishes playback, at which point the second, buffered frame will start playing. If the DAC finished playback of a frame +without having received and buffered a second frame, it will by default loop the first frame until a new frame is +received (but the flag HELIOS_FLAG_SINGLE_MODE will make it stop playback instead). +The GetStatus() function actually checks whether or not the buffer on the DAC is empty or full. If it is full, the DAC +cannot receive a new frame until the currently playing frame finishes, freeing up the buffer. +*/ + +#pragma once + +#include "libusb.h" +#include <cstring> +#include <cstdint> +#include <thread> +#include <mutex> +#include <vector> +#include <memory> +#include <chrono> + +#define HELIOS_SDK_VERSION 6 + +#define HELIOS_MAX_POINTS 0x1000 +#define HELIOS_MAX_RATE 0xFFFF +#define HELIOS_MIN_RATE 7 + +#define HELIOS_SUCCESS 1 +#define HELIOS_ERROR -1 //functions return this if something went wrong + +#define HELIOS_FLAGS_DEFAULT 0 +#define HELIOS_FLAGS_START_IMMEDIATELY (1 << 0) +#define HELIOS_FLAGS_SINGLE_MODE (1 << 1) +#define HELIOS_FLAGS_DONT_BLOCK (1 << 2) + +//usb properties +#define HELIOS_VID 0x1209 +#define HELIOS_PID 0xE500 +#define EP_BULK_OUT 0x02 +#define EP_BULK_IN 0x81 +#define EP_INT_OUT 0x06 +#define EP_INT_IN 0x83 + +#ifdef _DEBUG +#define LIBUSB_LOG_LEVEL LIBUSB_LOG_LEVEL_WARNING +#else +#define LIBUSB_LOG_LEVEL LIBUSB_LOG_LEVEL_NONE +#endif + +//point data structure +typedef struct +{ + std::uint16_t x; //12 bit (from 0 to 0xFFF) + std::uint16_t y; //12 bit (from 0 to 0xFFF) + std::uint8_t r; //8 bit (from 0 to 0xFF) + std::uint8_t g; //8 bit (from 0 to 0xFF) + std::uint8_t b; //8 bit (from 0 to 0xFF) + std::uint8_t i; //8 bit (from 0 to 0xFF) +} HeliosPoint; + +class HeliosDac +{ +public: + + HeliosDac(); + ~HeliosDac(); + + //unless otherwise specified, functions return HELIOS_SUCCESS if OK, and HELIOS_ERROR if something went wrong. + + //initializes drivers, opens connection to all devices. + //Returns number of available devices. + //NB: To re-scan for newly connected DACs after this function has once been called before, you must first call CloseDevices() + int OpenDevices(); + + //closes and frees all devices + int CloseDevices(); + + //writes and outputs a frame to the speficied dac + //devNum: dac number (0 to n where n+1 is the return value from OpenDevices() ) + //pps: rate of output in points per second + //flags: (default is 0) + // Bit 0 (LSB) = if 1, start output immediately, instead of waiting for current frame (if there is one) to finish playing + // Bit 1 = if 1, play frame only once, instead of repeating until another frame is written + // Bit 2 = if 1, don't let WriteFrame() block execution while waiting for the transfer to finish + // (NB: then the function might return 1 even if it fails) + // Bit 3-7 = reserved + //points: pointer to point data. See point structure declaration earlier in this document + //numOfPoints: number of points in the frame + int WriteFrame(unsigned int devNum, unsigned int pps, std::uint8_t flags, HeliosPoint* points, unsigned int numOfPoints); + + //Gets status of DAC, 1 means DAC is ready to receive frame, 0 means it is not + int GetStatus(unsigned int devNum); + + //Returns firmware version of DAC + int GetFirmwareVersion(unsigned int devNum); + + //Gets name of DAC (populates name with max 32 characters) + int GetName(unsigned int devNum, char* name); + + //Sets name of DAC (name must be max 31 characters incl. null terminator) + int SetName(unsigned int devNum, char* name); + + //Stops output of DAC until new frame is written (NB: blocks for 100ms) + int Stop(unsigned int devNum); + + //Sets shutter level of DAC + int SetShutter(unsigned int devNum, bool level); + + //Erase the firmware of the DAC, allowing it to be updated by accessing the SAM-BA bootloader + int EraseFirmware(unsigned int devNum); + +private: + + class HeliosDacDevice //individual dac, interal use + { + public: + + HeliosDacDevice(libusb_device_handle*); + ~HeliosDacDevice(); + int SendFrame(unsigned int pps, std::uint8_t flags, HeliosPoint* points, unsigned int numOfPoints); + int GetStatus(); + int GetFirmwareVersion(); + int GetName(char* name); + int SetName(char* name); + int SetShutter(bool level); + int Stop(); + int EraseFirmware(); + + private: + + int DoFrame(); + void FrameHandler(); + int SendControl(std::uint8_t* buffer, unsigned int bufferSize); + + struct libusb_transfer* interruptTransfer = NULL; + struct libusb_device_handle* usbHandle; + std::mutex frameLock; + bool frameReady = false; + int firmwareVersion = 0; + char name[32]; + bool closed = true; + std::uint8_t* frameBuffer; + unsigned int frameBufferSize; + int frameResult = -1; + + }; + + std::vector<std::unique_ptr<HeliosDacDevice>> deviceList; + std::mutex threadLock; + bool inited = false; +}; |
