2 * FnordlichtConnection.h: class to access a FnordlichtLight Hardware
3 * - the description could be found
4 * here: http://github.com/fd0/fnordlicht/raw/master/doc/PROTOCOL
6 * (C) Kai Lauterbach (klaute at gmail.com)
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27 #include "FnordlichtConnection.h"
29 #if !defined(_ATMO_VLC_PLUGIN_)
30 # include "FnordlichtConfigDialog.h"
41 CFnordlichtConnection::CFnordlichtConnection(CAtmoConfig *cfg)
42 : CAtmoConnection(cfg)
44 m_hComport = INVALID_HANDLE_VALUE;
47 CFnordlichtConnection::~CFnordlichtConnection()
51 ATMO_BOOL CFnordlichtConnection::OpenConnection()
53 #if defined(_ATMO_VLC_PLUGIN_)
54 char *serdevice = m_pAtmoConfig->getSerialDevice();
58 int portNummer = m_pAtmoConfig->getComport();
59 m_dwLastWin32Error = 0;
61 return ATMO_FALSE; // make no real sense;-)
66 #if !defined(_ATMO_VLC_PLUGIN_)
67 char serdevice[16]; // com4294967295
68 sprintf(serdevice,"com%d",portNummer);
73 m_hComport = CreateFile(serdevice,
74 GENERIC_WRITE, 0, NULL,
75 OPEN_EXISTING, 0, NULL);
76 if ( m_hComport == INVALID_HANDLE_VALUE )
78 // we have a problem here can't open com port...
79 // somebody else may use it?
80 // m_dwLastWin32Error = GetLastError();
83 /* change serial settings (Speed, stopbits etc.) */
84 DCB dcb; // für comport-parameter
85 dcb.DCBlength = sizeof(DCB);
86 GetCommState(m_hComport, &dcb); // ger current serialport settings
87 dcb.BaudRate = 19200; // set speed
88 dcb.ByteSize = 8; // set databits
89 dcb.Parity = NOPARITY; // set parity
90 dcb.StopBits = ONESTOPBIT; // set one stop bit
91 SetCommState(m_hComport, &dcb); // apply settings
96 m_hComport = open(serdevice,O_RDWR |O_NOCTTY);
101 memset(&tio,0,sizeof(tio));
102 tio.c_cflag = (CS8 | CREAD | HUPCL | CLOCAL);
103 tio.c_iflag = (INPCK | BRKINT);
104 cfsetispeed(&tio, bconst);
105 cfsetospeed(&tio, bconst);
106 if( ! tcsetattr(m_hComport, TCSANOW, &tio) )
107 tcflush(m_hComport, TCIOFLUSH);
109 // can't change parms
119 // stop fading on all devices
121 return true; // fnordlicht initialized...
123 return false; // something is going wrong...
126 void CFnordlichtConnection::CloseConnection()
128 if ( m_hComport != INVALID_HANDLE_VALUE )
133 CloseHandle(m_hComport);
137 m_hComport = INVALID_HANDLE_VALUE;
141 ATMO_BOOL CFnordlichtConnection::isOpen(void)
143 return (m_hComport != INVALID_HANDLE_VALUE);
146 ATMO_BOOL CFnordlichtConnection::HardwareWhiteAdjust(int global_gamma,
154 ATMO_BOOL storeToEeprom)
156 return ATMO_FALSE; //no hardware adjust required
160 def fade_rgb(addr, r, g, b, step, delay)
168 $dev.write "\x00\x00\x00\x00\x00"
169 $dev.write "\x00\x00\x00"
173 ATMO_BOOL CFnordlichtConnection::SendData(pColorPacket data)
175 if ( m_hComport == INVALID_HANDLE_VALUE )
178 int amount = getAmountFnordlichter();
179 unsigned char buffer[15];
180 memset(&buffer, 0, sizeof(buffer) ); // zero buffer
185 buffer[1] = 0x01; // fade to rgb color
186 buffer[2] = 0x80; // in two steps
187 buffer[3] = 0x01; // 1ms pause between steps
189 // send all packages to all fnordlicht's
190 for( unsigned char i=0; i < amount; i++ )
193 if ( m_ChannelAssignment && i < m_NumAssignedChannels )
194 idx = m_ChannelAssignment[i];
196 idx = -1; // no channel assigned to fnordlicht[i]
198 if( idx >= 0 && idx <= data->numColors )
200 // fnordlicht address equals to a MoMo Channel
201 buffer[0] = i; // fnordlicht address (0..254, 255 = broadcast)
202 buffer[4] = data->zone[idx].r;
203 buffer[5] = data->zone[idx].g;
204 buffer[6] = data->zone[idx].b;
209 WriteFile( m_hComport, buffer, sizeof(buffer),
210 (DWORD*)&iBytesWritten, NULL );
212 iBytesWritten = write(m_hComport, buffer, sizeof(buffer));
213 tcflush(m_hComport, TCIOFLUSH);
214 tcdrain(m_hComport); // flush buffer
217 if (iBytesWritten != sizeof(buffer))
220 return ATMO_FALSE; // shouldn't be...
231 ATMO_BOOL CFnordlichtConnection::CreateDefaultMapping(CAtmoChannelAssignment *ca)
235 ca->setSize( getAmountFnordlichter() ); // oder 4 ? depending on config!
236 ca->setZoneIndex(0, 0); // Zone 5
237 ca->setZoneIndex(1, 1);
238 ca->setZoneIndex(2, 2);
239 ca->setZoneIndex(3, 3);
243 int CFnordlichtConnection::getAmountFnordlichter()
245 return m_pAtmoConfig->getFnordlicht_Amount();
257 ATMO_BOOL CFnordlichtConnection::sync(void)
259 if ( m_hComport == INVALID_HANDLE_VALUE )
262 unsigned char buffer[16];
267 // fill buffer with 15 escape character
268 memset(&buffer, 0x1b, sizeof(buffer)-1);
270 buffer[sizeof(buffer)-1] = 0x00; // append one zero byte
274 WriteFile( m_hComport, buffer, sizeof(buffer),
275 (DWORD*)&iBytesWritten, NULL );
277 iBytesWritten = write(m_hComport, buffer, sizeof(buffer));
278 tcflush(m_hComport, TCIOFLUSH);
279 tcdrain(m_hComport); // flush buffer
284 return (iBytesWritten == sizeof(buffer)) ? ATMO_TRUE : ATMO_FALSE;
289 def stop(addr, fading = 1)
292 $dev.write fading.chr
293 $dev.write "\x00\x00\x00\x00"
294 $dev.write "\x00\x00\x00\x00\x00"
295 $dev.write "\x00\x00\x00"
299 ATMO_BOOL CFnordlichtConnection::stop(unsigned char addr)
301 if(m_hComport == INVALID_HANDLE_VALUE)
304 unsigned char buffer[15];
305 memset(&buffer, 0, sizeof(buffer)); // zero buffer
310 buffer[0] = addr; // fnordlicht address (255 = broadcast)
311 buffer[1] = 0x08; // stop command
312 buffer[2] = 1; // fading
316 WriteFile( m_hComport, buffer, sizeof(buffer),
317 (DWORD*)&iBytesWritten, NULL );
319 iBytesWritten = write(m_hComport, buffer, sizeof(buffer));
320 tcflush(m_hComport, TCIOFLUSH);
321 tcdrain(m_hComport); // flush buffer
326 return (iBytesWritten == sizeof(buffer)) ? ATMO_TRUE : ATMO_FALSE;
331 ATMO_BOOL CFnordlichtConnection::reset(unsigned char addr)
333 if(m_hComport == INVALID_HANDLE_VALUE)
338 if ( sync() && start_bootloader(addr) )
340 #if defined(_ATMO_VLC_PLUGIN_)
341 do_sleep(200000); // wait 200ms
343 do_sleep(200); // wait 200ms
345 if ( sync() && boot_enter_application(addr) )
353 def start_bootloader(addr)
356 $dev.write("\x6b\x56\x27\xfc")
357 $dev.write("\x00\x00\x00\x00\x00\x00\x00\x00\x00")
361 ATMO_BOOL CFnordlichtConnection::start_bootloader(unsigned char addr)
363 if(m_hComport == INVALID_HANDLE_VALUE)
366 unsigned char buffer[15];
367 memset(&buffer, 0, sizeof(buffer)); // zero buffer
372 buffer[0] = addr; // fnordlicht address (255 = broadcast)
373 buffer[1] = 0x80; // start_bootloader
381 WriteFile( m_hComport, buffer, sizeof(buffer),
382 (DWORD*)&iBytesWritten, NULL );
384 iBytesWritten = write(m_hComport, buffer, sizeof(buffer));
385 tcflush(m_hComport, TCIOFLUSH);
386 tcdrain(m_hComport); // flush buffer
391 return (iBytesWritten == sizeof(buffer)) ? ATMO_TRUE : ATMO_FALSE;
395 def boot_enter_application(addr)
398 $dev.write("\x00"*13)
402 ATMO_BOOL CFnordlichtConnection::boot_enter_application(unsigned char addr)
404 if(m_hComport == INVALID_HANDLE_VALUE)
407 unsigned char buffer[15];
408 memset(&buffer, 0, sizeof(buffer)); // zero buffer
413 buffer[0] = addr; // fnordlicht address (255 = broadcast)
414 buffer[1] = 0x87; // boot_ender_application command
418 WriteFile( m_hComport, buffer, sizeof(buffer),
419 (DWORD*)&iBytesWritten, NULL );
421 iBytesWritten = write(m_hComport, buffer, sizeof(buffer));
422 tcflush(m_hComport, TCIOFLUSH);
423 tcdrain(m_hComport); // flush buffer
428 return (iBytesWritten == sizeof(buffer)) ? ATMO_TRUE : ATMO_FALSE;
431 #if !defined(_ATMO_VLC_PLUGIN_)
433 char *CFnordlichtConnection::getChannelName(int ch)
436 if( ch < 0 ) return NULL;
437 if( ch >= getAmountFnordlichter() ) return NULL;
439 sprintf(buf,"Number [%d]",ch);
441 // sorry asprintf is not defined on Visual Studio :)
442 // return (asprintf(&ret, "Number [%d]", ch) != -1) ? ret : NULL;
446 ATMO_BOOL CFnordlichtConnection::ShowConfigDialog(HINSTANCE hInst, HWND parent,
449 CFnordlichtConfigDialog *dlg = new CFnordlichtConfigDialog(hInst,
453 INT_PTR result = dlg->ShowModal();