diff --git a/sdk/HeliosDac.cpp b/sdk/HeliosDac.cpp index f70976f..c927cff 100644 --- a/sdk/HeliosDac.cpp +++ b/sdk/HeliosDac.cpp @@ -1,5 +1,5 @@ /* -Driver API for Helios Laser DAC class, SOURCE +SDK for Helios Laser DAC class, SOURCE By Gitle Mikkelsen gitlem@gmail.com @@ -354,7 +354,23 @@ int HeliosDac::HeliosDacDevice::SendFrame(unsigned int pps, std::uint8_t flags, } } +//sends frame to DAC +int HeliosDac::HeliosDacDevice::DoFrame() +{ + if (closed) + return HELIOS_ERROR; + + int actualLength = 0; + int transferResult = libusb_bulk_transfer(usbHandle, EP_BULK_OUT, frameBuffer, frameBufferSize, &actualLength, 8 + (frameBufferSize >> 5)); + + if (transferResult == LIBUSB_SUCCESS) + return HELIOS_SUCCESS; + else + return HELIOS_ERROR; +} + //continually running thread, when a frame is ready, it is sent to the DAC +//only used if HELIOS_FLAGS_DONT_BLOCK is used with writeframe void HeliosDac::HeliosDacDevice::FrameHandler() { while (!closed) @@ -372,20 +388,6 @@ void HeliosDac::HeliosDacDevice::FrameHandler() } } -//sends frame to DAC -int HeliosDac::HeliosDacDevice::DoFrame() -{ - if (closed) - return HELIOS_ERROR; - - int actualLength = 0; - int transferResult = libusb_bulk_transfer(usbHandle, EP_BULK_OUT, frameBuffer, frameBufferSize, &actualLength, 8 + (frameBufferSize >> 5)); - - if (transferResult == LIBUSB_SUCCESS) - return HELIOS_SUCCESS; - else - return HELIOS_ERROR; -} //Gets firmware version of DAC int HeliosDac::HeliosDacDevice::GetFirmwareVersion() diff --git a/sdk/HeliosDac.h b/sdk/HeliosDac.h index d307276..14e1a29 100644 --- a/sdk/HeliosDac.h +++ b/sdk/HeliosDac.h @@ -1,5 +1,5 @@ /* -Driver API for Helios Laser DAC class, HEADER +SDK for Helios Laser DAC class, HEADER By Gitle Mikkelsen gitlem@gmail.com @@ -11,11 +11,19 @@ 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 new frame, first call GetStatus(). If the function returns ready (1), +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 diff --git a/sdk/HeliosDacAPI.cpp b/sdk/HeliosDacAPI.cpp index 2bfc713..a28a10a 100644 --- a/sdk/HeliosDacAPI.cpp +++ b/sdk/HeliosDacAPI.cpp @@ -1,12 +1,13 @@ /* -Driver API for Helios Laser DACs +Helios Laser DAC SDK shared library By Gitle Mikkelsen See HeliosDacAPI.h for documentation Dependencies: Libusb 1.0 (GNU Lesser General Public License, see libusb.h) -HeliosDAC class (part of this driver) +HeliosDAC class +OpenLaserShowControllerV1.0.0 header and .def file (only on windows) git repo: https://github.com/Grix/helios_dac.git */ diff --git a/sdk/HeliosDacAPI.h b/sdk/HeliosDacAPI.h index 6103980..abf762d 100644 --- a/sdk/HeliosDacAPI.h +++ b/sdk/HeliosDacAPI.h @@ -1,24 +1,32 @@ /* -Driver API for Helios Laser DAC shared library , HEADER +Helios Laser DAC SDK shared library, HEADER By Gitle Mikkelsen gitlem@gmail.com Dependencies: Libusb 1.0 (GNU Lesser General Public License, see libusb.h) -HeliosDAC class (part of this driver) -OpenLaserShowControllerV1.0.0 header and .def file (only supports windows) +HeliosDAC class +OpenLaserShowControllerV1.0.0 header and .def file (only on windows) Standard: C++14 BASIC USAGE: 1. Call OpenDevices() or OLSC_Initialize() to open devices, returns number of available devices -2. To send a new frame, first call GetStatus() or OLSC_GetStatus. If the function returns ready +2. To send a new frame, first call GetStatus() or OLSC_GetStatus(). If the function returns ready (1 for GetStatus, OLSC_STATUS_BUFFER_EMPTY for OLSC_GetStatus), then you can call WriteFrame() or OLSC_WriteFrame() / OLSC_WriteFrameEx(). 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() or OLSC_Pause(). To restart output you must send a new frame as described above. 4. When the DAC is no longer needed, free it using CloseDevices() or OLSC_Shutdown() See OpenLaserShowControllerV1.0.0-Mod.h for documentation on OLSC_* functions. Not recommended for cross-platform apps + +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 diff --git a/sdk/HeliosLaserDAC.dll b/sdk/HeliosLaserDAC.dll index b27ef22..9c6346a 100644 Binary files a/sdk/HeliosLaserDAC.dll and b/sdk/HeliosLaserDAC.dll differ diff --git a/sdk/examples/cpp/HeliosDac.cpp b/sdk/examples/cpp/HeliosDac.cpp index 82f10a8..c927cff 100644 --- a/sdk/examples/cpp/HeliosDac.cpp +++ b/sdk/examples/cpp/HeliosDac.cpp @@ -1,5 +1,5 @@ /* -Driver API for Helios Laser DAC class, SOURCE +SDK for Helios Laser DAC class, SOURCE By Gitle Mikkelsen gitlem@gmail.com @@ -313,12 +313,18 @@ int HeliosDac::HeliosDacDevice::SendFrame(unsigned int pps, std::uint8_t flags, return HELIOS_ERROR; unsigned int bufPos = 0; + + //this is a bug workaround, the mcu won't correctly receive transfers with these sizes + unsigned int ppsActual = pps; unsigned int numOfPointsActual = numOfPoints; if ((((int)numOfPoints-45) % 64) == 0) { numOfPointsActual--; + //adjust pps to keep the same frame duration even with one less point + ppsActual = (unsigned int)((pps * (double)numOfPointsActual / (double)numOfPoints) + 0.5); } + //prepare frame buffer for (unsigned int i = 0; i < numOfPointsActual; i++) { frameBuffer[bufPos++] = (points[i].x >> 4); @@ -329,8 +335,8 @@ int HeliosDac::HeliosDacDevice::SendFrame(unsigned int pps, std::uint8_t flags, frameBuffer[bufPos++] = points[i].b; frameBuffer[bufPos++] = points[i].i; } - frameBuffer[bufPos++] = (pps & 0xFF); - frameBuffer[bufPos++] = (pps >> 8); + frameBuffer[bufPos++] = (ppsActual & 0xFF); + frameBuffer[bufPos++] = (ppsActual >> 8); frameBuffer[bufPos++] = (numOfPointsActual & 0xFF); frameBuffer[bufPos++] = (numOfPointsActual >> 8); frameBuffer[bufPos++] = flags; @@ -348,7 +354,23 @@ int HeliosDac::HeliosDacDevice::SendFrame(unsigned int pps, std::uint8_t flags, } } +//sends frame to DAC +int HeliosDac::HeliosDacDevice::DoFrame() +{ + if (closed) + return HELIOS_ERROR; + + int actualLength = 0; + int transferResult = libusb_bulk_transfer(usbHandle, EP_BULK_OUT, frameBuffer, frameBufferSize, &actualLength, 8 + (frameBufferSize >> 5)); + + if (transferResult == LIBUSB_SUCCESS) + return HELIOS_SUCCESS; + else + return HELIOS_ERROR; +} + //continually running thread, when a frame is ready, it is sent to the DAC +//only used if HELIOS_FLAGS_DONT_BLOCK is used with writeframe void HeliosDac::HeliosDacDevice::FrameHandler() { while (!closed) @@ -366,20 +388,6 @@ void HeliosDac::HeliosDacDevice::FrameHandler() } } -//sends frame to DAC -int HeliosDac::HeliosDacDevice::DoFrame() -{ - if (closed) - return HELIOS_ERROR; - - int actualLength = 0; - int transferResult = libusb_bulk_transfer(usbHandle, EP_BULK_OUT, frameBuffer, frameBufferSize, &actualLength, 8 + (frameBufferSize >> 5)); - - if (transferResult == LIBUSB_SUCCESS) - return HELIOS_SUCCESS; - else - return HELIOS_ERROR; -} //Gets firmware version of DAC int HeliosDac::HeliosDacDevice::GetFirmwareVersion() diff --git a/sdk/examples/cpp/HeliosDac.h b/sdk/examples/cpp/HeliosDac.h index 3dc7c14..14e1a29 100644 --- a/sdk/examples/cpp/HeliosDac.h +++ b/sdk/examples/cpp/HeliosDac.h @@ -1,5 +1,5 @@ /* -Driver API for Helios Laser DAC class, HEADER +SDK for Helios Laser DAC class, HEADER By Gitle Mikkelsen gitlem@gmail.com @@ -11,11 +11,19 @@ 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 new frame, first call GetStatus(). If the function returns ready (1), +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 @@ -28,7 +36,6 @@ BASIC USAGE: #include #include #include -#include #define HELIOS_SDK_VERSION 6