diff --git a/src/ZeDMD.cpp b/src/ZeDMD.cpp index 9773197..7228304 100644 --- a/src/ZeDMD.cpp +++ b/src/ZeDMD.cpp @@ -24,11 +24,8 @@ ZeDMD::ZeDMD() ZeDMD::~ZeDMD() { - m_pZeDMDComm->Disconnect(); - free(m_pZeDMDComm); - - m_pZeDMDWiFi->Disconnect(); - free(m_pZeDMDWiFi); + delete m_pZeDMDComm; + delete m_pZeDMDWiFi; if (m_pFrameBuffer) delete m_pFrameBuffer; diff --git a/src/ZeDMDComm.cpp b/src/ZeDMDComm.cpp index 69b125b..9641d4e 100644 --- a/src/ZeDMDComm.cpp +++ b/src/ZeDMDComm.cpp @@ -8,11 +8,14 @@ ZeDMDComm::ZeDMDComm() m_pThread = NULL; #if !((defined(__APPLE__) && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || (defined(TARGET_OS_TV) && TARGET_OS_TV))) || defined(__ANDROID__)) m_pSerialPort = NULL; + m_pSerialPortConfig = NULL; #endif } ZeDMDComm::~ZeDMDComm() { + Disconnect(); + if (m_pThread) { m_pThread->join(); @@ -260,36 +263,50 @@ void ZeDMDComm::IgnoreDevice(const char* ignore_device) void ZeDMDComm::SetDevice(const char* device) { if (sizeof(device) < 32) - strcpy(&m_device[0], device); + strcpy(m_device, device); } bool ZeDMDComm::Connect() { -#if !((defined(__APPLE__) && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || (defined(TARGET_OS_TV) && TARGET_OS_TV))) || defined(__ANDROID__)) - if (m_device[0] != 0) - return Connect(m_device); + bool success = false; - char szDevice[32]; +#if !((defined(__APPLE__) && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || (defined(TARGET_OS_TV) && TARGET_OS_TV))) || defined(__ANDROID__)) + if (*m_device != 0) { + LogMessage("Connecting to ZeDMD on %s...", m_device); - for (int i = 0; i < 7; i++) { -#ifdef __APPLE__ - sprintf(szDevice, "/dev/cu.usbserial-%04d", i); -#elif defined(_WIN32) || defined(_WIN64) - sprintf(szDevice, "\\\\.\\COM%d", i + 1); -#else - sprintf(szDevice, "/dev/ttyUSB%d", i); -#endif + success = Connect(m_device); - for (int j = 0; j < m_ignoredDevicesCounter; j++) { - if (strcmp(szDevice, m_ignoredDevices[j]) == 0) - continue; + if (!success) + LogMessage("Unable to connect to ZeDMD on %s", m_device); + } + else { + LogMessage("Searching for ZeDMD..."); + + struct sp_port** ppPorts; + enum sp_return result = sp_list_ports(&ppPorts); + if (result == SP_OK) { + for (int i = 0; ppPorts[i]; i++) { + char* pDevice = sp_get_port_name(ppPorts[i]); + bool ignored = false; + for (int j = 0; j < m_ignoredDevicesCounter; j++) { + ignored = (strcmp(pDevice, m_ignoredDevices[j]) == 0); + if (ignored) + break; + } + if (!ignored) + success = Connect(pDevice); + if (success) + break; + } + sp_free_port_list(ppPorts); } - if (Connect(szDevice)) - return true; + if (!success) + LogMessage("Unable to find ZeDMD"); } #endif - return false; + + return success; } void ZeDMDComm::Disconnect() @@ -300,7 +317,12 @@ void ZeDMDComm::Disconnect() Reset(); #if !((defined(__APPLE__) && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || (defined(TARGET_OS_TV) && TARGET_OS_TV))) || defined(__ANDROID__)) + sp_set_config(m_pSerialPort, m_pSerialPortConfig); + sp_free_config(m_pSerialPortConfig); + m_pSerialPortConfig = NULL; + sp_close(m_pSerialPort); + sp_free_port(m_pSerialPort); m_pSerialPort = NULL; #endif } @@ -308,11 +330,21 @@ void ZeDMDComm::Disconnect() bool ZeDMDComm::Connect(char *pDevice) { #if !((defined(__APPLE__) && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || (defined(TARGET_OS_TV) && TARGET_OS_TV))) || defined(__ANDROID__)) - if (sp_get_port_by_name(pDevice, &m_pSerialPort) != SP_OK) + enum sp_return result = sp_get_port_by_name(pDevice, &m_pSerialPort); + if (result != SP_OK) return false; - sp_open(m_pSerialPort, SP_MODE_READ_WRITE); - + result = sp_open(m_pSerialPort, SP_MODE_READ_WRITE); + if (result != SP_OK) { + sp_free_port(m_pSerialPort); + m_pSerialPort = NULL; + + return false; + } + + sp_new_config(&m_pSerialPortConfig); + sp_get_config(m_pSerialPort, m_pSerialPortConfig); + sp_set_baudrate(m_pSerialPort, ZEDMD_COMM_BAUD_RATE); sp_set_bits(m_pSerialPort, 8); sp_set_parity(m_pSerialPort, SP_PARITY_NONE); @@ -333,7 +365,7 @@ bool ZeDMDComm::Connect(char *pDevice) std::this_thread::sleep_for(std::chrono::milliseconds(200)); - if (sp_blocking_read(m_pSerialPort, data, 8, 0)) { + if (sp_blocking_read(m_pSerialPort, data, 8, ZEDMD_COMM_SERIAL_READ_TIMEOUT)) { if (!memcmp(data, CTRL_CHARS_HEADER, 4)) { m_width = data[4] + data[5] * 256; m_height = data[6] + data[7] * 256; diff --git a/src/ZeDMDComm.h b/src/ZeDMDComm.h index 785f5ca..02cdc54 100644 --- a/src/ZeDMDComm.h +++ b/src/ZeDMDComm.h @@ -67,11 +67,7 @@ struct ZeDMDFrame #define ZEDMD_COMM_BAUD_RATE 921600 -#if defined(__APPLE__) -#define ZEDMD_COMM_MAX_SERIAL_WRITE_AT_ONCE 512 -#define ZEDMD_COMM_SERIAL_READ_TIMEOUT 64 -#define ZEDMD_COMM_SERIAL_WRITE_TIMEOUT 16 -#elif defined(_WIN32) || defined(_WIN64) +#if defined(_WIN32) || defined(_WIN64) #define ZEDMD_COMM_MAX_SERIAL_WRITE_AT_ONCE 8192 #define ZEDMD_COMM_SERIAL_READ_TIMEOUT 16 #define ZEDMD_COMM_SERIAL_WRITE_TIMEOUT 16 @@ -142,6 +138,7 @@ class ZeDMDComm char m_device[32] = {0}; #if !((defined(__APPLE__) && ((defined(TARGET_OS_IOS) && TARGET_OS_IOS) || (defined(TARGET_OS_TV) && TARGET_OS_TV))) || defined(__ANDROID__)) struct sp_port *m_pSerialPort; + struct sp_port_config *m_pSerialPortConfig; #endif std::queue m_frames; std::thread *m_pThread; diff --git a/src/test.cpp b/src/test.cpp index 973e97c..c5784f6 100644 --- a/src/test.cpp +++ b/src/test.cpp @@ -1,11 +1,21 @@ #include "ZeDMD.h" +#include #include #include +void CALLBACK OnLogMessage(const char* format, va_list args, const void* pUserData) +{ + char buffer[1024]; + vsnprintf(buffer, sizeof(buffer), format, args); + + printf("%s\n", buffer); +} + int main(int argc, const char *argv[]) { - ZeDMD *pZEDMD = new ZeDMD(); + ZeDMD* pZEDMD = new ZeDMD(); + pZEDMD->SetLogMessageCallback(OnLogMessage, NULL); if (pZEDMD->Open()) {