LMS 2012
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
c_daisy.c
Go to the documentation of this file.
1 /*
2  * LEGO® MINDSTORMS EV3
3  *
4  * Copyright (C) 2010-2013 The LEGO Group
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  */
20 
39 /***** Daisy var_s *****/
40 #include "c_input.h"
41 #include "c_daisy.h"
42 #include "c_output.h"
43 
44 
45 /*#if (HARDWARE != SIMULATION)
46 */
47 #include <stdio.h>
48 #include <string.h>
49 #include <fcntl.h>
50 #include <stdlib.h>
51 #include <unistd.h>
52 #include <sys/mman.h>
53 
54 // Device vars etc.
55 
57 int TimeOutMs = 10;
59 
60 // READ / WRITE stuff HOST (downstream side i.e the HOST side)
61 
64 int WriteState; // NON-blocking states of WRITE to the downstream
65 int ReadState; // NON-blocking states of READ from the downstream side
66 int LastWriteResult; // Result from last WRITE
67 int BytesWritten; // Bytes actually written
68 int ReadLength; // Length of READ
69 
70 // Layer versus Table pointers and limits
71 
75 
79 
83 
88 
89 // Layer 0 (self) , Sensor No , Data bytes 0 - n
90 // -
91 // -
92 // Layer 3 ~ max , Sensor No , Data bytes 0 - n
93 
95 RESULT IsDaisyChained = FAIL;
97 
98 DATA8 DaisyTempTypeLayer; // Normalised number used for direct indexing in array
101 
102 USB_SPEED *pUsbSpeed;
104 
107 
110 RESULT DaisyReadyState = OK;
111 uint DaisyPushCounter = 55; // Start with some DaisyStuff - HARD CODED :-)
113 
115 int DaisyUpstreamDataReady = TRUE; // Used to flag (conduct) the dual use of the UpStream channel. Return, errors contra Daisy data
116 
117 UBYTE cDaisyOwnLayer = 0; // Handy to know ;-)
118 
119 UBYTE cDaisyMasterCookieArray[16]; // Hands out a Cookie
120 UBYTE DaisyBusyFlags[BUSYFLAGS]; // Daisy BUSY flags always in a sensor transmission from downstream
121 
122  // --- --- --- --- --- --- --- --- --- --- --- --- ---
123  // |3,3|3,2|3,1|3,0|2,3|2,2---1,2|1,1|1,0|0,3|0,2|0,1|0,0|
124  // --- --- --- --- --- --- --- --- --- --- --- --- ---
125  //
126  // Each byte:
127  //
128  // S(tatus): BUSY = 1
129  // READY = 0
130  //
131  // M(agic)C(ookie):
132  //
133  // Together with the Layer, it forms a "sequence counter"
134  // Always incremented by 3 (due to position and if Layer included)
135  // The reset of a given BUSY state is also done by
136  // looking at this "sequence number" i.e. Magic Cookie.
137  // A BUSY state can only be reset by the SET-cookie or a newer one!
138  //
139  // L(ayer) Used by the SLAVE to know the position and where to RESET
140  // the busy-flag (position in the row of 16 bytes) - also known by
141  // array position
142  //
143  // - -- -- -- -- -- - -
144  // |S|MC|MC|MC|MC|MC|L|L|
145  // - -- -- -- -- -- - -
146 
147 struct timeval TV = { 0 , 0};
148 
149 void SetUnlocked(int Status)
150 {
151  Unlocked = Status;
152 }
153 
154 int GetUnlocked(void)
155 {
156  return Unlocked;
157 }
158 
159 void SetSlaveUnlocked(int Status)
160 {
161  SlaveUnlocked = Status;
162 }
163 
165 {
166  return SlaveUnlocked;
167 }
168 
170 {
171  return WriteState;
172 }
173 
175 {
176  return LastWriteResult;
177 }
178 
179 void cDaisyFlagFail(DATA8 Layer, DATA8 Sensor)
180 {
181  DaisyBuffers[Layer][Sensor][0] = FAIL;
182 }
183 
184 void cDaisyFlagBusy(DATA8 Layer, DATA8 Sensor)
185 {
186  DaisyBuffers[Layer][Sensor][0] = BUSY;
187 }
188 
190 {
191  int Layer;
192  int Sensor;
193 
194  // Set all sensor status to FAIL
195  for (Layer = StartLayer; Layer < DAISY_MAX_LAYER_DEPT; Layer++)
196  {
197  for(Sensor = 0; Sensor < DAISY_MAX_SENSORS_PER_LAYER; Sensor++)
198  {
199  cDaisyFlagFail(Layer, Sensor);
200  }
201  }
202 }
203 
205 {
206  cDaisyOwnLayer = Layer;
207 
208  //#define DEBUG
209  #undef DEBUG
210  #ifdef DEBUG
211  printf("SetOwnLayer = %d\n\r", cDaisyOwnLayer);
212  #endif
213 }
214 
216 {
217  return cDaisyOwnLayer;
218 }
219 
221 {
222  BusyTimer = BUSYTIME; // re-shoot timer
223  PushPriorityCounter = DAISY_PRIORITY_COUNT; // init priority of BUS use
224  DaisyReadyState = OK;
225 }
226 
227 RESULT cDaisyTxDownStream(void)
228 {
229  RESULT RetRes = FAIL;
230 
231  // ESCAPE FROM down connection errors
233 
234  RetRes = cDaisyWrite();
235 
236  switch(RetRes)
237  {
239 
240  //#define DEBUG
241  #undef DEBUG
242  #ifdef DEBUG
243  printf("cDaisyDownTxStreamCmd - DAISY_WR_DISCONNECTED\n\r");
244  #endif
245 
248  RetRes = FAIL;
249  DaisyReadyState = FAIL;
250  break; // Leave unhappy :-(
251 
252  case DAISY_WR_NOT_FINISHED: // Started OK, but not finished. Set wait for
253  // write completion and flag busy
254  //#define DEBUG
255  #undef DEBUG
256  #ifdef DEBUG
257  printf("cDaisyDownTxStreamCmd - DAISY_WR_NOT_FINISHED\n\r");
258  #endif
259 
261  RetRes = OK;
262  DaisyReadyState = OK;
263  break;
264 
265  case DAISY_WR_ERROR:
266 
267  //#define DEBUG
268  #undef DEBUG
269  #ifdef DEBUG
270  printf("cDaisyDownStreamCmd - DAISY_WR_ERROR\n\r");
271  #endif
272  // Fall through
273  // break;
274 
276 
277  // Connected but current
278  // operation went wrong!
279  // If ERROR in starting the write -
280  // flag error
281 
282  //#define DEBUG
283  #undef DEBUG
284  #ifdef DEBUG
285  printf("cDaisyDownStreamCmd - DAISY_WR_ERROR\n\r");
286  #endif
287 
288  DaisyReadyState = FAIL;
289  RetRes = FAIL;
290  break;
291  }
292  return RetRes;
293 }
294 
295 //********** MOTOR DAISY STUFF ******************************************************************
296 
297 void cDaisySetMasterCookie(uint Index, UBYTE CookieValue)
298 {
299  cDaisyMasterCookieArray[Index] = CookieValue;
300 }
301 
302 void cDaisyClearMasterCookie(uint Index)
303 {
304  cDaisyMasterCookieArray[Index] = 0x00;
305 }
306 
308 {
309  if((cDaisyMasterCookieArray[Index]) < 0x1F)
310  cDaisyMasterCookieArray[Index]++;
311  else
312  cDaisyMasterCookieArray[Index] = 0; // "Overrun"
313 }
314 
316 {
317  return (uint)(Port + (Layer * 4));
318 }
319 
320 void cDaisySetupMagicCookies(uint StoreFrom, UBYTE Layer, UBYTE PortField)
321 {
322  UBYTE MagicCookie = 0;
323  UBYTE BitFieldPointer = 0x01; // Pointing at Port 0 (1) okay 0000 0001 :-)
324  uint i;
325  uint LargePointer;
326  uint StorePointer = StoreFrom;
327 
328  for(i = 0; i < 4; i++)
329  {
330  if(PortField & BitFieldPointer) // BitField set?
331  {
332  LargePointer = (uint)(i + (Layer * 4)); // Byte pointer within the Layer
333  cDaisyIncrementMasterCookie(LargePointer); // Adjust Cookie (newest)
334  MagicCookie = (UBYTE)((cDaisyMasterCookieArray[LargePointer] << 2) & 0x7C); // Place Cookie Magic Number
335  MagicCookie |= 0x80; // Set BUSY
336  MagicCookie |= Layer; // Place Layer
337  DataOut[StorePointer] = MagicCookie;
338  DaisyBusyFlags[LargePointer] = MagicCookie; // Store also in Masters own array
339  }
340  else
341  {
342  DataOut[StorePointer] = 0x00;
343  }
344 
345  StorePointer++; // Next Port
346  BitFieldPointer = (UBYTE)(BitFieldPointer << 1);
347  }
348 }
349 
350 RESULT cDaisyCheckBusyIndex(UBYTE Layer, UBYTE Port)
351 {
352  RESULT RetVal = OK;
353 
354  if(DaisyBusyFlags[cDaisyGetPosFromLayerAndPort(Layer, Port)] & 0x80)
355  RetVal = BUSY;
356 
357  return RetVal;
358 }
359 
361 {
362  UBYTE Port; // Iterator for checking - "flying bit"
363  UBYTE RetVal = 0;
364  uint StartPort;
365  UBYTE CheckBit = 0x01;
366 
367  StartPort = (4 * Layer);
368 
369  for(Port = StartPort ; Port < (StartPort + 4); Port++)
370  {
371  if((DaisyBusyFlags[Port] & 0x80) && (PortBits & CheckBit))
372  RetVal |= CheckBit;
373  CheckBit <<= 1;
374  }
375 
376  //#define DEBUG
377  #undef DEBUG
378  #ifdef DEBUG
379  printf("cDaisyCheckBusyBit = %X\n\r", RetVal);
380  #endif
381 
382  return RetVal;
383 }
384 
386 {
387  // Used to keep the "repeating" slaves downstream up to date
388  // Check if newer !!
389 }
390 
391 void cDaisySetBusyFlags(UBYTE Layer, UBYTE Port, UBYTE MagicCookie) // Called from cCom
392 {
393  uint CookieIndex;
394 
395  CookieIndex = (uint)((Layer * 4) + Port);
396  DaisyBusyFlags[CookieIndex] = MagicCookie;
397 }
398 
399 RESULT cDaisyMotorDownStream(DATA8 *pData, DATA8 Length, DATA8 Layer, DATA8 PortField)
400 {
401  RESULT Result = FAIL;
402  DATA8 Len;
403  DATA8 Msg1 = 0; // Not used at the moment :-(
404  DATA8 Msg2 = 0; // -
405 
406  //#define DEBUG
407  #undef DEBUG
408  #ifdef DEBUG
409  printf("cDaisyMotorDownStream called\n\r");
410  #endif
411 
413 
414  // DaisyChained Motor commands using BUSY flags
415  // pData points to the raw Direct Motor Command e.g.
416  // len1, len2, msg1, msg2, cmdtype, global, local, bytecode"1", layer, sensor,....bytecode"n"
417  // Length = total payload
418  // Layer = delivery level: If 1 then the DaisyDecoration is removed and the "raw" payload is
419  // tx'ed via the USB as a normal Direct Command
420  // MAGIC Cookie added after the PAYLOAD
421 
422  DaisyTempDownLayer = Layer - 1; // Point into local table (Layer 1 at index 0, 2 @ 1 etc.
423 
424  cDaisyResetBusyTiming(); // Make new prioritized access to channel
425 
426  if(Layer > 1) // Tx as Daisy
427  {
428  // Setup Daisy prolog
429  Len = Length + 5 + 4; // Payload + the prolog portion + MAGIC COOKIES
430  DataOut[0] = Len; // The length only 1 (one) byte in Daisy
431  DataOut[1] = 0; // -
432  DataOut[2] = Msg1; // TODO Real MSG no
433  DataOut[3] = Msg2;
435  DataOut[5] = DAISY_CHAIN_DOWNSTREAM_WITH_BUSY; // Downstream special handling
436  DataOut[6] = DaisyTempDownLayer; // Layer (destination?);
437 
438  // Byte 7 = PayLoad Start
439  memcpy(&(DataOut[7]), pData, Length);
440  cDaisySetupMagicCookies(7 + Length, Layer, PortField);
441 
442  //#define DEBUG
443  #undef DEBUG
444  #ifdef DEBUG
445  printf("cDaisyMotorDownStream sent as DAISY_COMMAND_NO_REPLY + DAISY_CHAIN_DOWNSTREAM_WITH_BUSY\n\r");
446 
447  int ii;
448  printf("DataOut =\n\r");
449  for(ii = 0; ii < (Len+2); ii++)
450  printf("%X, ", DataOut[ii]);
451 
452  printf("DaisyBusyFlags =\n\r");
453  for(ii = 0; ii < 16; ii++)
454  printf("%X, ",DaisyBusyFlags[ii]);
455  printf("\r\n");
456  #endif
457 
458  }
459  else
460  {
461  // We send the payload only as a Direct Command
462  // Setup "NORMAL" prolog
463 
464  Len = Length + 3 + 4; // Payload + the prolog portion + 4 MAGIC COOKIES
465  DataOut[0] = Len; // The length only 1 (one) byte in Daisy
466  DataOut[1] = 0; // -
467  DataOut[2] = Msg1; // TODO Real MSG no
468  DataOut[3] = Msg2;
470  // Byte 5 = PayLoad Start
471  memcpy(&(DataOut[5]), pData, Length);
472 
473  // cDaisySetupMagicCookie(DataOutPos, Layer, Port);
474  cDaisySetupMagicCookies(5 + Length, Layer, PortField);
475 
476  //#define DEBUG
477  #undef DEBUG
478  #ifdef DEBUG
479  printf("cDaisyMotorDownStream sent as a normal DIR_CMD_NO_REPLY_WITH_BUSY\n\r");
480  printf("After cDaisySetupMagicCookies\n\r");
481  int help2;
482  for(help2 = 0; help2 < (Len + 2); help2++)
483  {
484  printf("%X, ", DataOut[help2]);
485  }
486  printf("\n\r");
487  #endif
488  }
489 
490  Result = cDaisyTxDownStream();
491 
492  return Result;
493 }
494 
496 {
498 }
499 
501 {
502  UWORD RetVal = 0;
503 
504  *pData = DaisyUpstreamDataBuffer; // Specific Daisy Data Buffer (NOT the answer/error one!!)
505  RetVal = DAISY_UPSTREAM_DATA_LENGTH; // As it says - We have some data
506 
507  return RetVal;
508 }
509 
511 {
512  return DaisyPushCounter;
513 }
514 
515 void SetDaisyPushCounter(int Count)
516 {
517  DaisyPushCounter = Count;
518 }
519 
521 {
523 }
524 
526 {
527  if (DaisyPushCounter > 0)
529 }
530 
531 RESULT cDaisyReady(void)
532 {
533  RESULT Result = FAIL;
534 
535  if ((BusyTimer) && (PushPriorityCounter))
536  {
537  Result = BUSY;
538  }
539  else
540  {
541  Result = DaisyReadyState;
542  }
543 
544  return (Result);
545 }
546 
547 void DaisyAsyncReadCallBack(struct libusb_transfer *ReadUsbTransfer)
548 {
549  // Callback -> Asyncronous Read-job done
550 
551  //#define DEBUG
552  #undef DEBUG
553  #ifdef DEBUG
554  printf("Did we reach here??\n\r");
555  #endif
556 
557  switch(ReadUsbTransfer->status)
558  {
559  case LIBUSB_TRANSFER_COMPLETED: // An normal completion
560  ReadLength = ReadUsbTransfer->actual_length;
562 
563  //#define DEBUG
564  #undef DEBUG
565  #ifdef DEBUG
566  printf("\n\rcDaisyAsyncReadCallBack - LIBUSB_TRANSFER_COMPLETED\n\r");
567  #endif
568 
569  break;
570 
571  case LIBUSB_TRANSFER_TIMED_OUT: // The asynchronous transfer ended up in a timeout
573 
574  //#define DEBUG
575  #undef DEBUG
576  #ifdef DEBUG
577  printf("\n\rcDaisyAsyncReadCallBack - LIBUSB_TRANSFER_TIMED_OUT\n\r");
578  #endif
579 
580  break;
581 
582  case LIBUSB_TRANSFER_NO_DEVICE: // The device (slave) has gone...
585 
586  //#define DEBUG
587  #undef DEBUG
588  #ifdef DEBUG
589  printf("\n\rcDaisyAsyncReadCallBack - LIBUSB_TRANSFER_NO_DEVICE\n\r");
590  #endif
591 
592  break;
593 
594  default: // Fall through
595  case LIBUSB_TRANSFER_CANCELLED: // Fall through Could be more detailed - but all are unhappy states ;-)
596  case LIBUSB_TRANSFER_STALL: // Fall through
597  case LIBUSB_TRANSFER_OVERFLOW: // Fall through
598 
600 
601  //#define DEBUG
602  #ifdef DEBUG
603  printf("\n\rcDaisyAsyncReadCallBack - LIBUSB_ALL_ERROR\n\r");
604  #endif
605 
606  break;
607  }
608 }
609 
611 {
612  // Startup of a read from downstream - are we ready (UNLOCKED)?
613  int ReadResult = DAISY_RD_OK;
614 
615  libusb_fill_interrupt_transfer( ReadTransfer,
616  DeviceHandle,
618  DataIn,
621  NO_USER_DATA, // No user data
622  TimeOutMs);
623 
624  ReadResult = libusb_submit_transfer(ReadTransfer);
625 
626  switch(ReadResult)
627  {
628  case LIBUSB_SUCCESS: ReadResult = DAISY_RD_OK; // Read initiated OK
629  ReadState = DAISY_RD_REQUESTED; // Ready for the callback to be called
630  ReadLength = 0; // Nothing read yet
631 
632  //#define DEBUG
633  #undef DEBUG
634  #ifdef DEBUG
635  printf("\n\rcDaisyStartReadUnlockAnswer - LIBUSB_SUCCESS\n\r");
636  #endif
637 
638  break;
639 
640  case LIBUSB_ERROR_NO_DEVICE: ReadResult = DAISY_RD_DISCONNECTED; // Device gone, but can be requested later
641  ReadState = DAISY_RD_IDLE; // No active job - Device is disconnected
643 
644  //#define DEBUG
645  #undef DEBUG
646  #ifdef DEBUG
647  printf("\n\rDaisyStartReadUnlockAnswer - LIBUSB_ERROR_NO_DEVICE\n\r");
648  #endif
649 
650  break; // Try again later....
651 
652  default: ReadResult = DAISY_RD_ERROR; // Some ERROR should not happen at start
653  ReadState = DAISY_RD_IDLE; // if device present - No active job
654 
655  //#define DEBUG
656  #undef DEBUG
657  #ifdef DEBUG
658  printf("\n\rDaisyStartReadUnlockAnswer - LIBUSB_DEFAULT\n\r");
659  #endif
660 
661  break; // Try again later....
662  }
663 }
664 
665 RESULT cDaisyDownStreamCmd(DATA8 *pData, DATA8 Length, DATA8 Layer)
666 {
667  RESULT RetRes = FAIL;
668  DATA8 Len;
669  DATA8 Msg1 = 0; // Not used at the moment :-(
670  DATA8 Msg2 = 0; // -
671 
672  // The HOSTing brick command to the downstream friends
673  // DaisyChained commands e.g. Motor cmd's
674  // pData points to the raw Direct Command e.g.
675  // len1, len2, msg1, msg2, cmdtype, global, local, bytecode"1", layer, sensor,....bytecode"n"
676  // Length = total payload
677  // Layer = delivery level: If 1 then the DaisyDecoration is removed and the "raw" payload is
678  // tx'ed via the USB as a normal Direct Command
679 
680  // ESCAPE FROM down connection errors
682 
683  DaisyTempDownLayer = Layer - 1; // Point into local table (Layer 1 at index 0, 2 @ 1 etc.
684 
685  cDaisyResetBusyTiming(); // Make new prioritized access to channel
686 
687  if(Layer > 1) // Tx as Daisy
688  {
689  // Setup Daisy prolog
690  Len = Length + 5; // Payload + the prolog portion
691  DataOut[0] = Len; // The length only 1 (one) byte in Daisy
692  DataOut[1] = 0; // -
693  DataOut[2] = Msg1; // TODO Real MSG no
694  DataOut[3] = Msg2;
697  DataOut[6] = DaisyTempDownLayer; // Layer - Where to deliver
698  // Byte 7 = PayLoad Start
699  memcpy(&(DataOut[7]), pData, Length);
700  }
701  else
702  {
703  // We send the payload only as a Direct Command
704  // Setup "NORMAL" prolog
705 
706  Len = Length + 3; // Payload + the prolog portion
707  DataOut[0] = Len; // The length only 1 (one) byte in Daisy
708  DataOut[1] = 0; // -
709  DataOut[2] = Msg1; // TODO Real MSG no
710  DataOut[3] = Msg2;
711  DataOut[4] = DIRECT_COMMAND_NO_REPLY;
712  // Byte 5 = PayLoad Start
713  memcpy(&(DataOut[5]), pData, Length);
714  }
715 
716  RetRes = cDaisyTxDownStream();
717 
718  return RetRes;
719 }
720 
721 
722 void cDaisyCmd(RXBUF *pRxBuf, TXBUF *pTxBuf)
723 {
724  COMCMD *pComCmd;
725  DAISY_UNLOCK_REPLY *pDaisyUnlockReply;
726  DAISYCMD *pDaisyCmd;
727  DAISY_READ *pDaisyRead;
728  uint PortIndex;
729  int CommandPointer;
730  UBYTE ThisMagicCookie;
731 
732  // Here the commands come from an upstream friend or if Layer 1 from the HOSTing Brick
733 
734  //#define DEBUG
735  #undef DEBUG
736  #ifdef DEBUG
737  printf("Here is the call from the HOST to cDaisyCmd\n\r");
738  #endif
739 
740  pComCmd = (COMCMD*)(ComInstance.RxBuf[USBDEV].Buf); // Overall pointer to Rec. Command stuff
741  pDaisyCmd = (DAISYCMD*)(*pComCmd).PayLoad;
742  pDaisyRead = (DAISY_READ*)(ComInstance.RxBuf[USBDEV].Buf);
743  pDaisyUnlockReply = (DAISY_UNLOCK_REPLY*)(ComInstance.TxBuf[USBDEV].Buf); // Overall pointer to Reply stuff
744  UBYTE LayerByte;
745 
746  switch((*pDaisyCmd).DaisyCmd)
747  {
748  case DAISY_UNLOCK_SLAVE: // Decorate the reply
749  pDaisyUnlockReply->CmdSize = SIZEOF_UNLOCK_REPLY - sizeof(CMDSIZE);
750  pDaisyUnlockReply->MsgCount = pDaisyRead->MsgCount;
751  pDaisyUnlockReply->CmdType = DAISY_REPLY;
752  pDaisyUnlockReply->Cmd = DAISY_UNLOCK_SLAVE;
753  pDaisyUnlockReply->Status = OK;
754 
755  //#define DEBUG
756  #undef DEBUG
757  #ifdef DEBUG
758  printf("CmdSize1 = %d\n\r", ComInstance.TxBuf[USBDEV].Buf[0]);
759  printf("CmdSize2 = %d\n\r", ComInstance.TxBuf[USBDEV].Buf[1]);
760  printf("MSG1 = %d\n\r", ComInstance.TxBuf[USBDEV].Buf[2]);
761  printf("MSG2 = %d\n\r", ComInstance.TxBuf[USBDEV].Buf[3]);
762  printf("CmdTyp = %x\n\r", ComInstance.TxBuf[USBDEV].Buf[4]);
763  printf("Cmd = %x\n\r", ComInstance.TxBuf[USBDEV].Buf[5]);
764  printf("Stat = %x\n\r", ComInstance.TxBuf[USBDEV].Buf[6]);
765  #endif
766 
767  // Fill the control stuff
768  ComInstance.TxBuf[USBDEV].BlockLen = DAISY_DATA_PACKET;
770  ComInstance.TxBuf[USBDEV].Writing = 1;
771  SetDaisyPushCounter(DAISY_PUSH_NOT_UNLOCKED); // Flag special handling to cCom
772  PushState = DAISY_PUSH_CONNECTED; // We should push all we're able to!!
773 
774  SetUnlocked(TRUE);
775  cInputStartTypeDataUpload(); // Force type table from SLAVE devices
776  usleep(1500);
777  cDaisyPushUpStream(); // Flood upward
778  cDaisyPrepareNext(); // Ready for the next sensor in the array
779  usleep(1500);
780  break;
781 
782  case DAISY_SET_TYPE: // Set type exception
783 
784  //#define DEBUG
785  #undef DEBUG
786  #ifdef DEBUG
787  printf("DAISY_SET_TYPE\n\r");
788  #endif
789 
790 
791  if((*pDaisyCmd).Layer < 1)
792  {
793  // Destination layer reached
794 
795 
796  //#define DEBUG
797  #undef DEBUG
798  #ifdef DEBUG
799  printf("DAISY_SET_TYPE layer < 1 : ");
800  #endif
801 
802  cInputSetChainedDeviceType(0, (*pDaisyCmd).SensorNo, (*pDaisyCmd).PayLoad[0], (*pDaisyCmd).PayLoad[1]);
803  }
804  else // Further down
805  {
806  #undef DEBUG
807  //#define DEBUG
808  #ifdef DEBUG
809  printf("DAISY_SET_TYPE Further DOWN\n\r");
810  #endif
811 
812  (*pDaisyCmd).Layer = ((*pDaisyCmd).Layer - 1);
813 
814  // TX as is...
815  memcpy(&(DataOut[0]), pComCmd, ((*pComCmd).CmdSize + 2));
817  }
818 
819  break;
820 
821  case DAISY_CHAIN_DOWNSTREAM: // If Layer == 1 we should tx downstream as a "normal" DIRECT CMD
822  // if Layer > 1 we should decrement Layer and send downstream as
823  // a DaisyChain payload
824 
825  //#define DEBUG
826  #undef DEBUG
827  #ifdef DEBUG
828  printf("Here is the call from the HOST to cDaisyCmd DAISY_CHAIN_DOWNSTREAM - Daisy Layer set to %d\n\r", (*pDaisyCmd).Layer);
829  #endif
830 
831  if((*pDaisyCmd).Layer == 1)
832  {
833  // Convert the message to a DIRECT COMMAND (i.e. replace the Daisy stuff)
834  // TODO check for reply or not
835  (*pComCmd).Cmd = DIRECT_COMMAND_NO_REPLY; // Setup as "normal" Direct Command;
836 
837  // Adjust the size (i.e. remove the SubCmd
838  (*pComCmd).CmdSize = (*pComCmd).CmdSize - 2;
839  // Copy first portion of command (all before SubCmd
840  memcpy(&(DataOut[0]), &((*pComCmd).CmdSize), 5);
841 
842  // Move Payload to "normal" position
843  memcpy(&(DataOut[5]), &((*pComCmd).PayLoad[2]), ((*pComCmd).CmdSize - 3));
844 
845  //#define DEBUG
846  #undef DEBUG
847  #ifdef DEBUG
848  printf("DAISY_CHAIN_DOWNSTREAM sent as a DIRECT command\n\r");
849  #endif
850  }
851  else
852  {
853  (*pDaisyCmd).Layer = ((*pDaisyCmd).Layer - 1);
854  // TX as is...
855  memcpy(&(DataOut[0]), pComCmd, ((*pComCmd).CmdSize + 2));
856 
857  //#define DEBUG
858  #undef DEBUG
859  #ifdef DEBUG
860  printf("DAISY_CHAIN_DOWNSTREAM sent as a further down command\n\r");
861  #endif
862  }
863 
865 
866  break;
867 
869 
870  //#define DEBUG
871  #undef DEBUG
872  #ifdef DEBUG
873  printf(" case DAISY_CHAIN_DOWNSTREAM_WITH_BUSY - (*pDaisyCmd).Layer == %d\n\r", (*pDaisyCmd).Layer );
874  #endif
875 
876  // If Layer == 1 we should tx downstream as a "normal" DIRECT CMD
877  // if Layer > 1 we should decrement Layer and send downstream as
878  // a DaisyChain payload
879 
880  // Here we set the new and updated BUSY flags
881  // Only the LAYER, ports is affected. 4 of the total 16
882 
883  LayerByte = 0;
884 
885  PortIndex = 0;
886  for(CommandPointer = 3; CommandPointer >= 0; CommandPointer--)
887  {
888  // PAYLOAD_OFFSET = 4
889  ThisMagicCookie = (*pComCmd).PayLoad[((*pComCmd).CmdSize) - CommandPointer - PAYLOAD_OFFSET];
890 
891  // Set Cookies in array E.g. layer 3(2) xxxx xxxx CCCC xxxx
892 
893  LayerByte |= (UBYTE)(ThisMagicCookie & 0x03);
894 
895  cDaisySetBusyFlags((UBYTE)(ThisMagicCookie & 0x03), PortIndex++, ThisMagicCookie);
896  }
897 
898  cDaisySetOwnLayer((UBYTE)(LayerByte - (*pDaisyCmd).Layer));
899 
900  //#define DEBUG
901  #undef DEBUG
902  #ifdef DEBUG
903 
904  int DebugP;
905 
906  printf("DaisyBusyFlags DOWN:\r\n");
907 
908  for(DebugP = 0; DebugP < 16; DebugP++)
909  printf("%X, ", DaisyBusyFlags[DebugP]);
910 
911  printf("\r\nCookie setting done..(*pDaisyCmd).Layer == %d OwnLayer == %d\r\n", (*pDaisyCmd).Layer, cDaisyOwnLayer);
912  printf("\r\n");
913  #endif
914 
915  if((*pDaisyCmd).Layer == 1)
916  {
917  // Convert the message to a DIRECT COMMAND (i.e. replace the Daisy stuff)
918  // TODO check for reply or not
919  (*pComCmd).Cmd = DIR_CMD_NO_REPLY_WITH_BUSY; // Setup as "normal" Direct Command;
920 
921  // Adjust the size (i.e. remove the SubCmd and Layer
922  (*pComCmd).CmdSize = (*pComCmd).CmdSize - 2;
923 
924  // Copy first portion of command (all before SubCmd
925  memcpy(&(DataOut[0]), &((*pComCmd).CmdSize), 5);
926 
927  // Move Payload to "normal" position
928  memcpy(&(DataOut[5]), &((*pComCmd).PayLoad[2]), ((*pComCmd).CmdSize - 4));
929  }
930  else
931  {
932  (*pDaisyCmd).Layer = ((*pDaisyCmd).Layer - 1);
933 
934  // TX as is...
935  memcpy(&(DataOut[0]), pComCmd, ((*pComCmd).CmdSize + 2));
936  }
937 
939 
940  // Fall through
941  // break;
942 
943  default: // ERROR
944  break;
945  }
946 }
947 
949 {
950  // What's the smallest packet size for the HOSTed daisychained slave?
951  int InSize = 0;
952  int OutSize = 0;
953 
956 
957  return (InSize <= OutSize) ? InSize : OutSize; // Return the smallest size
958 }
959 
961 {
962  // Get the GADGET side speed (PC or DAISY host?)
963  // I.e. HIGH speed = PC, FULL speed = DAISY stuff (or old PC/cheap HUB ;-))
964 
965  DATA8 SpeedResult = FULL_SPEED;
966 
967  // Check for UPSTREAM connection
968  if((*pUsbSpeed).Speed == FULL_SPEED)
969  {
970 
971  #undef DEBUG
972  //#define DEBUG
973  #ifdef DEBUG
974  printf("Connected to FULL_SPEED on Gadget side - DAISY chained\n\r");
975  #endif
976 
977  IsDaisyChained = OK;
978  //SpeedResult already set
979  }
980  else
981  {
982  SpeedResult = HIGH_SPEED;
983  IsDaisyChained = FAIL;
984 
985  //#define DEBUG
986  #undef DEBUG
987  #ifdef DEBUG
988  printf("Connected to HIGH_SPEED on Gadget side\n\r");
989  #endif
990  }
991  return SpeedResult;
992 }
993 
995 {
996  return ReadLayerPointer; // Returns the layer we just points to (index)
997 }
998 
1000 {
1001  return ReadSensorPointer; // Returns the sensor we just points to (index)
1002 }
1003 
1004 RESULT cDaisyChained(void)
1005 {
1006  return IsDaisyChained; // Are we daisychained or not?
1007 }
1008 
1010 {
1011  TimeOutMs = TimeOut; // Set the Daisy HOST timeout time
1012 }
1013 
1015 {
1016  return MaxInterruptPacketSize; // Returns the packet size (is the smallest of the IN/OUT endpoint)
1017 }
1018 
1020 {
1021  // Makes the connection (shared mem) between Gadget driver
1022  // kernel layer and the Userspace layer
1023 
1024  RESULT Result = FAIL;
1025  int UsbFile;
1026  USB_SPEED *pUsbSpeedTemp;
1027 
1028  // Create a Shared Memory entry for signaling the driver state FULL- or HIGHSPEED
1029 
1030  UsbFile = open(USBDEV_DEVICE_NAME,O_RDWR | O_SYNC);
1031 
1032  #undef DEBUG
1033  //#define DEBUG
1034  #ifdef DEBUG
1035  printf("UsbFile = %d\r\n", UsbFile);
1036  #endif
1037 
1038  if(UsbFile >= 0)
1039  {
1040  pUsbSpeedTemp = (USB_SPEED*)mmap(0, sizeof(UWORD), PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, UsbFile, 0);
1041 
1042  if(pUsbSpeedTemp == MAP_FAILED)
1043  {
1044  #undef DEBUG
1045  //#define DEBUG
1046  #ifdef DEBUG
1047  printf("MAP_FAILED\n\r");
1048  #endif
1049 
1051  }
1052  else
1053  {
1054  pUsbSpeed = pUsbSpeedTemp;
1055  Result = OK;
1056 
1057  #undef DEBUG
1058  //#define DEBUG
1059  #ifdef DEBUG
1060  printf("OK pUsbSpeed in c_Daisy\n\r");
1061  #endif
1062  }
1063  close(UsbFile);
1064  }
1065 
1066  return Result;
1067 }
1068 
1069 RESULT cDaisyWriteTypeDownstream(DATA8 Layer,DATA8 Port,DATA8 Type,DATA8 Mode)
1070 {
1071  RESULT RetRes = BUSY;
1072  int ReturnValue = DAISY_WR_ERROR;
1073 
1074  //#define DEBUG
1075  #undef DEBUG
1076  #ifdef DEBUG
1077  printf("Writing TYPE/MODE to SLAVE - Layer = %d, Port = %d, Type = %d, Mode = %d\r\n", Layer, Port, Type, Mode);
1078  #endif
1079 
1080  cDaisyResetBusyTiming(); // Make new prioritized access to channel
1081 
1082  DataOut[LEN1] = 8;
1083  DataOut[LEN2] = 0;
1084  DataOut[MSG1] = 1; // TODO Real MSG no
1085  DataOut[MSG2] = 0;
1088  DataOut[LAYER_POS_TO_SLAVE] = Layer; // The TO_SLAVE added/changed for "FENCE_ERROR" protection!!
1089  DataOut[SENSOR_POS_TO_SLAVE] = Port;
1090  DataOut[TYPE_POS_TO_SLAVE] = Type;
1091  DataOut[MODE_POS_TO_SLAVE] = Mode;
1092 
1093  ReturnValue = cDaisyWrite();
1094 
1095  switch(ReturnValue)
1096  {
1097  case DAISY_WR_DISCONNECTED:
1098 
1099  //#define DEBUG
1100  #undef DEBUG
1101  #ifdef DEBUG
1102  printf("cDaisyWriteTypeDownstream - DAISY_WR_DISCONNECTED\n\r");
1103  #endif
1104 
1107  RetRes = FAIL;
1108  DaisyReadyState = FAIL;
1109 
1110  break; // Leave unhappy :-(
1111 
1112  case DAISY_WR_NOT_FINISHED: // Started OK, but not finished. Set wait for
1113  // write completion and flag busy
1114 
1115  //#define DEBUG
1116  #undef DEBUG
1117  #ifdef DEBUG
1118  printf("cDaisyWriteTypeDownstream - DAISY_WR_NOT_FINISHED\n\r");
1119  #endif
1120 
1123  RetRes = OK;
1124  DaisyReadyState = OK;
1125 
1126  break; // Leave and wait polite ;-)
1127 
1128  case DAISY_WR_ERROR:
1129 
1130  //#define DEBUG
1131  #undef DEBUG
1132  #ifdef DEBUG
1133  printf("cDaisyWriteTypeDownstream - DAISY_WR_ERROR\n\r");
1134  #endif
1135 
1136  // Fall through
1137  // break;
1138 
1139  default: DownConnectionState = DAISY_DOWN_UNLOCKED; // Connected but current
1140  // operation went wrong!
1141  // If ERROR in starting the write -
1142  // flag BUSY, so user can decide
1143  // what to do - hopefully a new try ;-)
1144  // (normalised layer/sensor number)
1145 
1147  RetRes = FAIL;
1148  DaisyReadyState = FAIL;
1149 
1150  break;
1151  }
1152 
1153  return RetRes;
1154 }
1155 
1156 RESULT cDaisySetDeviceType(DATA8 Layer,DATA8 Port,DATA8 Type,DATA8 Mode)
1157 {
1158  DATA8 NormSensor;
1159  RESULT RetVal = FAIL;
1160 
1161  //#define DEBUG
1162  #ifdef DEBUG
1163  printf("cDaisySetDeviceType in cDaisy\n\r");
1164  #endif
1165  #undef DEBUG
1166 
1167  if(Layer >= 1) // Layer > self
1168  {
1169  DaisyTempTypeLayer = Layer - 1; // Preserve for later use
1170 
1171  // Set BUSY in table
1172  if(Port > DAISY_MAX_INPUT_SENSOR_INDEX)
1173  NormSensor = Port - DAISY_SENSOR_OUTPUT_OFFSET;
1174  else
1175  NormSensor = Port;
1176 
1177  DaisyTempTypeSensor = NormSensor;
1179 
1180  RetVal = cDaisyWriteTypeDownstream(DaisyTempTypeLayer, Port, Type, Mode);
1181  }
1182  return RetVal;
1183 }
1184 
1185 void DaisyResetTheBuffers( int FromLayer)
1186 {
1187  int i;
1188  int j;
1189 
1190  // As it says - Zero set the Daisy Array
1191  for(i = FromLayer; i < DAISY_MAX_LAYER_DEPT; i++)
1192  {
1193  for(j = 0; j < DAISY_MAX_SENSORS_PER_LAYER; j++)
1194  {
1195  memset((&(DaisyBuffers[i][j])), 0, DAISY_MAX_DATASIZE);
1196  DaisyBuffers[i][j][0] = FAIL; // No activity should equal INVALID, NO_SENSOR and
1197  // "----" in display on Master ;-)
1198  }
1199  }
1200 }
1201 
1203 {
1204  DaisyResetTheBuffers( 0 ); // All including MySelf
1205 }
1206 
1208 {
1209  DaisyResetTheBuffers( 1 ); // All below MySelf
1210 }
1211 
1212 RESULT cDaisyInit(void)
1213 {
1214  RESULT Result = FAIL;
1215  int Temp;
1216 
1217  //#define DEBUG
1218  #undef DEBUG
1219  #ifdef DEBUG
1220  printf("\n\rDaisy Init called\n\r");
1221  #endif
1222 
1226 
1227  DaisyMsgCounter = 0; // Used by the Daisy, not in sync with the HOST PC app. message counter
1228 
1229  // Layer, Table-pointers and size limit initialisation
1230  ReadLayerPointer = 0;
1231  ReadSensorPointer = 0;
1232  MaxLowerLayer = 0;
1233  DaisyInfo = EMPTY; // No info
1234 
1236  DaisyPushCounter = 0x55;
1237  OldDaisyCounter = 0;
1238 
1239  DaisyZeroTheBuffers(); // Start @ a known stage of data
1240 
1241  // Make a handle to the kernel USB speed
1242  Result = cDaisyCreateSpeedInfo();
1243 
1244  if(Result == OK)
1245  {
1246  // Check for UPSTREAM connection
1247  if((*pUsbSpeed).Speed == HIGH_SPEED)
1248  {
1249  UpStreamConnection.Speed = HIGH_SPEED;
1250 
1251  #undef DEBUG
1252  #ifdef DEBUG
1253  printf("Connected to HIGH_SPEED on Gadget side\n\r");
1254  #endif
1255  }
1256  else
1257  {
1258  UpStreamConnection.Speed = FULL_SPEED;
1259 
1260  //#define DEBUG
1261  #undef DEBUG
1262  #ifdef DEBUG
1263  printf("Connected to FULL_SPEED on Gadget side\n\r");
1264  #endif
1265  }
1266 
1267  // Start initializing the UsbLib stuff
1268  Temp = libusb_init(NULL);
1269 
1270  if(Temp < 0)
1271  {
1272  Result = FAIL;
1273  }
1274  else
1275  {
1276  //#define DEBUG
1277  #undef DEBUG
1278  #ifdef DEBUG
1279  printf("\n\rDaisy Temp >= 0 \n\r");
1280  #endif
1281 
1283  if(DeviceHandle != NULL)
1284  {
1285  // We've found our HID and want to use it
1286  // Detach the hidusb from our HID to let us
1287  // and the libusb use it :-)
1288 
1289  libusb_detach_kernel_driver(DeviceHandle, INTERFACE_NUMBER); // No simple ERROR check
1290  // an ERROR will be catched
1291  if(libusb_claim_interface(DeviceHandle, INTERFACE_NUMBER) >= 0) // from here.....
1292  {
1293  // We have an valid Interface
1294 
1295  //#define DEBUG
1296  #undef DEBUG
1297  #ifdef DEBUG
1298  printf("\n\rDaisy valid InterFace??? We have if this is seen...;-)\n\r");
1299  #endif
1300 
1301  Result = OK;
1302  MaxInterruptPacketSize = cDaisyGetMaxPacketSize(DeviceHandle); // Be sure we have the right size
1303 
1304  //#define DEBUG
1305  #undef DEBUG
1306  #ifdef DEBUG
1307  printf("\n\rDaisy MaxInterruptPacketSize: %d\n\r", MaxInterruptPacketSize);
1308  #endif
1309 
1312  WriteState = DAISY_WR_IDLE; // We have a connection, but no communication yet
1314  ReadTransfer = libusb_alloc_transfer(0);
1315  WriteTransfer = libusb_alloc_transfer(0);
1316  BytesWritten = 0;
1317  ReadLength = 0;
1318  }
1319  else
1320  Result = FAIL; // Could not claim the interface to the HID device
1321  }
1322  }
1323  }
1324  //#define DEBUG
1325  #undef DEBUG
1326  #ifdef DEBUG
1327  printf("\n\rDaisy Init ended (HOST)\n\r");
1328  #endif
1329 
1330  return Result;
1331 }
1332 
1334 {
1335  //#define DEBUG
1336  #undef DEBUG
1337  #ifdef DEBUG
1338  printf("Writing UNLOCK to SLAVE\r\n");
1339  #endif
1340 
1341  DataOut[LEN1] = 4;
1342  DataOut[LEN2] = 0;
1343  DataOut[MSG1] = 1; // TODO real no
1344  DataOut[MSG2] = 0;
1347 
1348  return cDaisyWrite();
1349 }
1350 
1352 {
1353  return DataIn[LAYER_POS]; // Get the LAYER from the in the message embedded layer
1354 }
1355 
1357 {
1358  return DataIn[SENSOR_POS]; // Get the Sensor-position from the in the message embedded sensor-"address"
1359 }
1360 
1362 {
1363  if(ReplyNumber < 10000)
1364  ReplyNumber++;
1365  else
1366  ReplyNumber = 0;
1367  return ReplyNumber;
1368 }
1369 
1370 RESULT cDaisyGetDeviceInfo(DATA8 Length,UBYTE *pInfo)
1371 {
1372  RESULT RetVal = FAIL;
1373 
1374  // Polled by cInput module
1376  { // Last device I.e. the MASTER
1377  // OK to get'n'delete the INFO
1378  // else TX it upwards
1379 
1380  if(Length > MAX_DEVICE_INFOLENGTH) Length = MAX_DEVICE_INFOLENGTH;
1381 
1382  #undef DEBUG
1383  //#define DEBUG
1384  #ifdef DEBUG
1385  printf("%s\r\n", &(DaisyInfoBuffer[0]));
1386  #endif
1387 
1388  memcpy(pInfo, DaisyInfoBuffer, Length);
1389  DaisyInfo = EMPTY;
1390  RetVal = OK;
1391  }
1392 
1393  return RetVal;
1394 }
1395 
1396 RESULT cDaisySetDeviceInfo(DATA8 Length,UBYTE *pInfo)
1397 {
1398  // UpStream command from Input module from slave via DaisyChain
1399  RESULT RetResult = BUSY;
1400 
1402  {
1403  //#define DEBUG
1404  #undef DEBUG
1405  #ifdef DEBUG
1406  printf("cDaisySetDeviceInfo, PushState == DAISY_PUSH_CONNECTED\n\r");
1407  #endif
1408 
1409  if(DaisyInfo == EMPTY) // Ready for new info stuff
1410  {
1411  //#define DEBUG
1412  #undef DEBUG
1413  #ifdef DEBUG
1414  printf("cDaisySetDeviceInfo, DaisyInfo == EMPTY\n\r");
1415  #endif
1416 
1417  if(Length > MAX_DEVICE_INFOLENGTH) Length = MAX_DEVICE_INFOLENGTH;
1418  memcpy(DaisyInfoBuffer, pInfo, Length);
1419 
1420  //#define DEBUG
1421  #undef DEBUG
1422  #ifdef DEBUG
1423  int loop;
1424  for(loop = 0; loop < Length; loop++)
1425  {
1426  printf("DaisyInfoBuffer[%d] = 0x%x\r\n", loop, DaisyInfoBuffer[loop]);
1427  }
1428  #endif
1429 
1431  DaisyInfo = VALID;
1432  RetResult = OK;
1433  }
1434  }
1435  else
1436  {
1437  RetResult = FAIL;
1438  }
1439  return RetResult;
1440 }
1441 
1443 {
1444  // PUSH data like a mouse-device upwards in the (daisy-) chain
1445  // NOT as a master-slave but as a slave who is "forcing" data
1446  // upstream as fast as possible - still scheduled voluntary from
1447  // the VM/Application thread
1448 
1449  DAISY_DEVICE_DATA *pDaisyReply;
1450  DAISY_INFO *pDaisyInfo;
1451  DATA8 DeviceNo; // The normalized number used in the request
1452  // (I.e. 0-3 left as.. 4-7 changed to 16-19)
1453  RESULT SensorResult = FAIL;
1454  UBYTE MotorFlags;
1455 
1456  //#define DEBUG
1457  #undef DEBUG
1458  #ifdef DEBUG
1459  printf("Her we call c_daisy cDaisyPushUpStream\n\r");
1460  #endif
1461 
1462  pDaisyReply = (DAISY_DEVICE_DATA*)(DaisyUpstreamDataBuffer); // Overall pointer to Reply stuff
1463 
1464  pDaisyReply->CmdType = DAISY_REPLY;
1465  pDaisyReply->MsgCount = cDaisyReplyNumber();
1466 
1467  // If information about sensors is available,
1468  // and we're "man in the middle" - I.e. not
1469  // at top-level (MASTER-level) the content
1470  // of the INFO buffer shall be pushed upwards
1471  // in the chain
1472 
1474  {
1475  // We have some "VALID" info
1476  pDaisyReply->CmdSize = SIZEOF_REPLY_DAISY_READ; // If we get the length in the future
1477  // it should be set here
1478  // Fill in the INFO in the reply
1479  pDaisyReply->Cmd = DAISY_CHAIN_INFO;
1480 
1481  pDaisyInfo = (DAISY_INFO*)(DaisyUpstreamDataBuffer);
1482 
1483  memcpy(pDaisyInfo->Info, DaisyInfoBuffer, SIZEOF_DAISY_INFO_READ);
1484  DaisyInfo = EMPTY; // We've used the stuff
1485 
1486  #undef DEBUG
1487  //#define DEBUG
1488  #ifdef DEBUG
1489  printf("cDaisyPushUpStream INFO done!!!!\n\r");
1490  #endif
1491  }
1492  else // NO info, so do the DATA job
1493  {
1494  pDaisyReply->CmdSize = DAISY_SENSOR_DATA_SIZE + BUSYFLAGS;
1495  pDaisyReply->Cmd = DAISY_CHAIN_UPSTREAM;
1496  pDaisyReply->Layer = ReadLayerPointer;
1497 
1498  if(ReadSensorPointer > 3)
1500  else
1501  DeviceNo = ReadSensorPointer;
1502 
1503  pDaisyReply->SensorNo = DeviceNo; // The normalized number :-)
1504 
1505  if(ReadLayerPointer == 0) // I.e. if we want to read our own layer
1506  { // we read directly @ the in-/output device
1507  // else we read in the table (array) indexed
1508  // 0-3 and 16-19 (in and "output" sensors)
1509 
1510  SensorResult = cInputGetDeviceData(ReadLayerPointer, DeviceNo, DEVICE_MAX_DATA, &(pDaisyReply->Type), &(pDaisyReply->Mode), (DATA8*)(&(pDaisyReply->DeviceData[0])));
1511 
1512  pDaisyReply->Status = SensorResult; // Status from device;
1513 
1514  //#define DEBUG
1515  #undef DEBUG
1516  #ifdef DEBUG
1517  if(DeviceNo == 1)
1518  printf("Self DATA (PUSH) collected here: ReadLayerP: %d, ReadSensorP: %d, DeviceNo: %d, Status %d\r\n", ReadLayerPointer, ReadSensorPointer, DeviceNo, SensorResult);
1519  #endif
1520 
1521  }
1522  else
1523  {
1524  // We should read from the array we uses the real ReadSensorPointer
1525  // Remember layer is 1 offset (i.e. 0 == Layer 1, 1 == 2, so Read Array Layer 1 == read[1 - 1]
1526 
1527  //#define DEBUG
1528  #undef DEBUG
1529  #ifdef DEBUG
1530  printf("Array Data (PUSH) are collected here: ReadLayerPointer > 0: %d, ReadSensorPointer: %d, DeviceNo: %d - STATUS = %d\r\n", ReadLayerPointer, ReadSensorPointer, DeviceNo, DaisyBuffers[ReadLayerPointer - 1][ReadSensorPointer][0]);
1531  #endif
1532 
1534  }
1535 
1536  //#define DEBUG
1537  #undef DEBUG
1538  #ifdef DEBUG
1539 
1540  int w;
1541 
1542  printf("Before own in PUSH:");
1543 
1544  for(w = 0; w < 16; w++)
1545  if(DaisyBusyFlags[w] != 0x00)
1546  printf("[%d]=%X ", w, DaisyBusyFlags[w]);
1547  printf("\n\r");
1548  #endif
1549 
1550  // refresh the motor status
1551  MotorFlags = cMotorGetBusyFlags();
1552 
1553  //#define DEBUG
1554  #undef DEBUG
1555  #ifdef DEBUG
1556  printf("Push MotorFlags from cMotorGetBusyFlags() = %X\n\r", MotorFlags);
1557  #endif
1558 
1559  // Pack (reset) the stuff
1560 
1561  uint j;
1562  UBYTE p = 0x01;
1563  uint StartIndex;
1564 
1565  StartIndex = 4 * cDaisyGetOwnLayer();
1566 
1567  //#define DEBUG
1568  #undef DEBUG
1569  #ifdef DEBUG
1570  printf("StartIndex Getting cMotorGetBusyFlags() = %d\n\r", StartIndex);
1571  #endif
1572 
1573  for(j = StartIndex; j < (StartIndex + 4); j++)
1574  {
1575  // Remember it's only the BUSY flag - the Cookie number isn't changed
1576 
1577  if(p & MotorFlags)
1578  DaisyBusyFlags[j] |= 0x80;
1579  else
1580  DaisyBusyFlags[j] &= 0x7F;
1581 
1582  p <<= 1;
1583 
1584  //#define DEBUG
1585  #undef DEBUG
1586  #ifdef DEBUG
1587  printf("DaisyBusyFlags[%d] = %X, ", j, DaisyBusyFlags[j]);
1588  #endif
1589 
1590  }
1591 
1592  //#define DEBUG
1593  #undef DEBUG
1594  #ifdef DEBUG
1595  printf("\n\r");
1596  #endif
1597 
1598  //We add the Motor BUSY stuff
1599  memcpy(&(pDaisyReply->FirstCookie), DaisyBusyFlags, 16);
1600 
1601  //#define DEBUG
1602  #undef DEBUG
1603  #ifdef DEBUG
1604 
1605  int z;
1606 
1607  printf("PUSHed:");
1608 
1609  for(z = 0; z < 16; z++)
1610  if(DaisyBusyFlags[z] != 0x00)
1611  printf("[%d]=%X @ StartIndex:%d", z, DaisyBusyFlags[z], StartIndex);
1612  printf("\n\r");
1613  #endif
1614 
1615  }
1616 
1617  // Common portion
1618 
1619  //#define DEBUG
1620  #undef DEBUG
1621  #ifdef DEBUG
1622  printf("StreamDataReady set TRUE\n\r");
1623  #endif
1624 
1626 
1627  //#define DEBUG
1628  #undef DEBUG
1629  #ifdef DEBUG
1630 
1631  int nn;
1632 
1633  for(nn = 2; nn < 4; nn++)
1634  {
1635  printf("[%d]=%d, ", nn, DaisyUpstreamDataBuffer[nn]);
1636  }
1637 
1638  printf("\n\r");
1639  #endif
1640 
1641 }
1642 
1644 {
1645  // Adjust for next poll
1648  {
1649 
1650  //#define DEBUG
1651  #undef DEBUG
1652  #ifdef DEBUG
1653  printf("ReadSensorPointer %d at PrepareNext lige foer reset\n\r", ReadSensorPointer);
1654  #endif
1655 
1656  ReadSensorPointer = 0; // Reset position
1657  ReadLayerPointer++;
1658  if(ReadLayerPointer > 3) // >= MaxLowerLayer)
1659  ReadLayerPointer = 0; // Start at the very beginning of table once more
1660  }
1661 
1662  //#define DEBUG
1663  #undef DEBUG
1664  #ifdef DEBUG
1665  printf("ReadSensorPointer %d at PrepareNext\n\r", ReadSensorPointer);
1666  #endif
1667 
1668 }
1669 
1670 RESULT cDaisyGetDownstreamData(DATA8 Layer,DATA8 Sensor,DATA8 Length,DATA8 *pType,DATA8 *pMode,DATA8 *pData)
1671 {
1672  //Normalized Sensor I.e. 16,17 to 4,5 etc.
1673 
1674  DATA8 NormSensor;
1675  RESULT Result = FAIL;
1676 
1677  //#define DEBUG
1678  #undef DEBUG
1679  #ifdef DEBUG
1680  printf("Layer (+1): %d, Port: %d", Layer, Sensor);
1681  #endif
1682 
1683  if(Layer > 0) // Self should not be called here, but directly from the I/P's
1684  {
1685  Layer--; // Normalize Layer Index into storage ( Layer 1 is positioned @ index 0, 2 @ index 1 etc.
1686 
1688  NormSensor = (Sensor - DAISY_SENSOR_OUTPUT_OFFSET);
1689  else
1690  NormSensor = Sensor;
1691 
1692  Result = DaisyBuffers[Layer][NormSensor][STATUS_POS];
1693 
1694  //#define DEBUG
1695  #undef DEBUG
1696  #ifdef DEBUG
1697 
1698  if((Layer == 0) && (NormSensor == 1))
1699  {
1700  switch(Result)
1701  {
1702  case OK: printf("Layer 0, Sensor 1, OK\n\r");
1703  break;
1704 
1705  case BUSY: printf("Layer 0, Sensor 1, BUSY\n\r");
1706  break;
1707 
1708  case FAIL: printf("Layer 0, Sensor 1, FAIL\n\r");
1709  break;
1710 
1711  case STOP: printf("Layer 0, Sensor 1, STOP\n\r");
1712  break;
1713  }
1714  }
1715  #endif
1716 
1717 
1718  *pMode = DaisyBuffers[Layer][NormSensor][MODE_POS];
1719  *pType = DaisyBuffers[Layer][NormSensor][TYPE_POS];
1720 
1721  // Nanny the length
1722  if(!(Length <= DEVICE_MAX_DATA)) Length = DEVICE_MAX_DATA;
1723  memcpy(pData, &(DaisyBuffers[Layer][NormSensor][DEVICE_DATA_POS]), Length);
1724 
1725  //#define DEBUG
1726  #undef DEBUG
1727  #ifdef DEBUG
1728  printf("L=%d, S=%d, T=%d\n\r", Layer, NormSensor, DaisyBuffers[Layer][NormSensor][TYPE_POS]);
1729  #endif
1730  }
1731  return Result;
1732 
1733 }
1734 
1735 void DaisyAsyncWriteCallBack(struct libusb_transfer *WriteUsbTransfer)
1736 {
1737  BytesWritten = 0; // Reset - only set if data written
1738 
1739  // Callback -> Asyncronous Write-job done
1740 
1741  if( WriteUsbTransfer->status == LIBUSB_TRANSFER_COMPLETED )
1742  {
1743  //#define DEBUG
1744  #undef DEBUG
1745  #ifdef DEBUG
1746  printf("Did I reach callback?? 01\r\n");
1747  #endif
1748 
1749  LastWriteResult = DAISY_WR_COMPLETED; // Done with Success
1750  BytesWritten = WriteUsbTransfer->actual_length;
1751  DaisyReadyState = OK;
1752  }
1753  else // Some thing went wrong....
1754  {
1755  switch( WriteUsbTransfer->status)
1756  {
1757 
1758 
1760  //#define DEBUG
1761  #undef DEBUG
1762  #ifdef DEBUG
1763  printf("Did I reach callback?? 02\r\n");
1764  #endif
1765 
1767  DaisyReadyState = FAIL;
1768 
1769  break;
1770 
1772  //#define DEBUG
1773  #undef DEBUG
1774  #ifdef DEBUG
1775  printf("Did I reach callback?? 03\r\n");
1776  #endif
1777 
1780  DaisyReadyState = FAIL;
1781 
1782  break;
1783 
1784  default: // Fall through
1785  case LIBUSB_TRANSFER_CANCELLED: // Fall through Could be more detailed
1786  case LIBUSB_TRANSFER_STALL: // Fall through
1787  case LIBUSB_TRANSFER_OVERFLOW: // Fall through
1788 
1790  DaisyReadyState = FAIL;
1791 
1792  //#define DEBUG
1793  #undef DEBUG
1794  #ifdef DEBUG
1795  printf("Did I reach callback?? 04\r\n");
1796  #endif
1797 
1798  break;
1799  }
1800  }
1801 
1803 
1804 }
1805 
1806 int cDaisyWriteDone(void) // Called for an asyncronous check on the actual write
1807 {
1808  int ReturnValue = DAISY_WR_NOT_FINISHED;
1809  int EventResult = 0;
1810 
1811  EventResult = libusb_handle_events_timeout(0, &TV); // Let the CPU get some job done - but don't let it
1812  // use too much time.......
1813  switch(LastWriteResult)
1814  {
1815  case DAISY_WR_NOT_FINISHED: // Return Write in progress
1816  // ReturnValue already set...
1817  DaisyReadyState = OK; // Until something else proved
1818 
1819  break;
1820 
1821  case DAISY_WR_IDLE: // Hmmm We're idle
1822  DaisyReadyState = OK;
1823  ReturnValue = DAISY_WR_IDLE;
1824 
1825  break;
1826 
1827  case DAISY_WR_COMPLETED: ReturnValue = BytesWritten; // Return a positive value i.e. NO error
1829  DaisyReadyState = OK;
1830  WriteState = DAISY_WR_IDLE; // Ready again
1831 
1832  break;
1833 
1834  case DAISY_WR_DISCONNECTED: ReturnValue = DAISY_WR_DISCONNECTED; // Device gone, but can be requested later
1835  WriteState = DAISY_WR_IDLE; // But ready again if reconnected
1836  DaisyReadyState = FAIL;
1837 
1838  break;
1839 
1840  default: // FALL THROUGH
1841  case DAISY_WR_TIMED_OUT: // FALL THROUGH Could be more detailed
1842 
1843  case DAISY_WR_ERROR: ReturnValue = DAISY_WR_ERROR;
1845  DaisyReadyState = FAIL;
1846 
1847  break;
1848  }
1849  return ReturnValue;
1850 }
1851 
1852 void cDaisyPollFromDownStream(void) // Autonomous put into array etc. :-)
1853 {
1854  int ReadResult = 0;
1855  int EventResult = 0;
1856  int InfoLength = 0;
1857  int TempStorePointer = 0; // Used for the offset of O/P sensors
1858  // (i.e. 16 = 4, 17 = 5 index in array)
1859 
1860  EventResult = libusb_handle_events_timeout(0, &TV); // Let the CPU get some job done - but don't let it
1861  // use too much time.......
1862 
1863  if(ReadState != DAISY_RD_IDLE)
1864  {
1865  // Some job in progress - wait for CallBack to give the async result
1866 
1867  switch(ReadState)
1868  {
1869  case DAISY_RD_DONE: // We have a valid READ
1870 
1871  //#define DEBUG
1872  #undef DEBUG
1873  #ifdef DEBUG
1874  printf("\n\rcDaisyPollFromDownstream - DAISY_RD_DONE - length = %d\n\r", ReadLength);
1875  #endif
1876 
1877  // #define DEBUG
1878  #undef DEBUG
1879  #ifdef DEBUG
1880 
1881  int x;
1882  printf("--DATAIN---\n\r");
1883  for (x = 0; x < 16; x++)
1884  printf("%d, ", DataIn[x]);
1885 
1886  for (x = 16; x < 32; x++)
1887  printf("%d, ", DataIn[x]);
1888  printf("\n\r");
1889 
1890  // Smaller print for verify :-)
1891  //printf("Data rec\n\r");
1892 
1893  #endif
1894 
1895  // If we're the MASTER we keep the INFO in the buffer
1896  // and flags it's ready
1897  // else the INFO is pushed upwards in the cDaisyPushUpStream()
1898 
1899  // Switch on data type
1900  // DAISY_CHAIN_INFO == 0xA2
1901  // DAISY_CHAIN_UPSTREAM == 0xA1
1902 
1903  ReadResult = ReadLength;
1904 
1905  switch(DataIn[SUBCMD]) // Type of DAISY packet
1906  {
1907  case DAISY_CHAIN_INFO:
1908  #undef DEBUG
1909  //#define DEBUG
1910  #ifdef DEBUG
1911  printf("DaisyInfo from DownStream\n\r");
1912  #endif
1913 
1914  // Ready for update
1915  if(DaisyInfo == EMPTY) // Ready for new info stuff
1916  {
1918  InfoLength = MAX_DEVICE_INFOLENGTH;
1919  else
1920  InfoLength = ReadLength;
1921 
1922  // Store the INFO
1923  memcpy(DaisyInfoBuffer, &(DataIn[INFO_INFO]), InfoLength);
1924  DaisyInfo = VALID;
1925  ReadState = DAISY_RD_IDLE; // Ready for next job
1926  }
1927 
1928  // else wait for INFO polled and cleared by input
1929  if(PushPriorityCounter > 0)
1930  {
1932 
1933  //#define DEBUG
1934  #undef DEBUG
1935  #ifdef DEBUG
1936  printf("PushPriorityCounter, Time = %d , %d\n\r", PushPriorityCounter, BusyTimer);
1937  #endif
1938  }
1939 
1940  break;
1941 
1942  case DAISY_CHAIN_UPSTREAM:
1943 
1944  //#define DEBUG
1945  #undef DEBUG
1946  #ifdef DEBUG
1947  printf("DaisyData polled from DownStream\n\r");
1948  #endif
1949 
1950  if(ReadLength < DAISY_MAX_EP_IN_SIZE) // Add trailing zeroes
1951  {
1952  memset((&(DataIn[ReadLength])), 0, DAISY_MAX_EP_IN_SIZE - ReadLength);
1953  }
1954 
1955  // Adjust the BUSY stuff
1956  // If polled Cookies newer/same age as what's in the local array
1957  // and the BUSY flag in the polled version is cleared - all the
1958  // cookie is reset to 0
1959 
1960  int k;
1961  int l;
1962 
1963  l = 0;
1964 
1965  for(k = BUSYFLAGS_START_POS; k < (BUSYFLAGS_START_POS + 16); k++)
1966  {
1967  if((DataIn[k] & 0x7C) >= (DaisyBusyFlags[l] & 0x7C)) // Cookie upstream newer or same age
1968  {
1969  if((DataIn[k] & 0x80) == 0x00)
1970  {
1971  // Busy reset here but "age" and "from where" preserved for use upstream
1972  DataIn[k] &= 0x7F;
1973  DaisyBusyFlags[l] &= 0x7F; //0x00; // local RESET too
1974  }
1975  }
1976 
1977  l++;
1978  }
1979 
1980  // Remember layer is 1 offset (i.e. Layer "One down" stored at index 0, "Two down" as 1 etc.
1981  // So a Read Array Layer "One down" == read[1 - 1] - remember layer 0 (self) is read directly
1982 
1983  TempStorePointer = GetSensorStorePointer();
1984 
1985  if(TempStorePointer > 15)
1986  TempStorePointer = (TempStorePointer - DAISY_SENSOR_OUTPUT_OFFSET);
1987 
1988  memcpy((&(DaisyBuffers[GetLayerStorePointer()][TempStorePointer])), &(DataIn[8/*0*/]), DAISY_DEVICE_PAYLOAD_SIZE/*DAISY_MAX_EP_IN_SIZE*/);
1989 
1990  //#define DEBUG
1991  #undef DEBUG
1992  #ifdef DEBUG
1993 
1994  int i;
1995  int j;
1996  int z;
1997 
1998  printf("-----\n\r");
1999  for (j = 0; j < 4; j++)
2000  {
2001  for (i = 0; i < 8; i++)
2002  {
2003  for (z = 0; z < 32; z++)
2004  {
2005  printf("%d, ",(UBYTE)(DaisyBuffers[j][i][z]));
2006  }
2007  printf("\n\r");
2008  }
2009  }
2010 
2011  // Smaller print for verify :-)
2012  //printf("Data rec\n\r");
2013  #endif
2014 
2015  if(PushPriorityCounter > 0)
2016  {
2018  }
2019 
2020  ReadState = DAISY_RD_IDLE; // Ready for next job
2021 
2022  break;
2023 
2024  default: ReadState = DAISY_RD_IDLE; // Ready for next job
2025 
2026  break;
2027  }
2028 
2029 
2030  break;
2031 
2032  case DAISY_RD_REQUESTED: // We still have a valid READ request
2033  // ReadState already set OK
2034 
2035  //#define DEBUG
2036  #undef DEBUG
2037  #ifdef DEBUG
2038  printf("\n\rcDaisyPollFromDownstream - DAISY_RD_REQUESTED\n\r");
2039  #endif
2040 
2041  break;
2042 
2043  case DAISY_RD_DISCONNECTED: // Device gone, but can be requested later
2044  // Ready again if reconnected
2045 
2047 
2048  //#define DEBUG
2049  #undef DEBUG
2050  #ifdef DEBUG
2051  printf("\n\rcDaisyPollFromDownstream - DAISY_RD_DISCONNECTED\n\r");
2052  #endif
2053  // FALL THROUGH
2054 
2055  case DAISY_RD_TIMEDOUT: // Too lazy...
2056 
2057  //#define DEBUG
2058  #undef DEBUG
2059  #ifdef DEBUG
2060  printf("\n\rcDaisyPollFromDownstream - DAISY_RD_TIMEDOUT\n\r");
2061  #endif
2062 
2063  ReadState = DAISY_RD_IDLE; // Ready again if it becomes more "energy"...
2064 
2065  break;
2066 
2067  default: // FALL THROUGH
2068 
2069  case DAISY_RD_ERROR:
2070  //#define DEBUG
2071  #undef DEBUG
2072  #ifdef DEBUG
2073  printf("\n\rcDaisyPollFromDownstream - DAISY_RD_ERROR\n\r");
2074  #endif
2075 
2076  ReadResult = DAISY_RD_ERROR;
2077  ReadState = DAISY_RD_IDLE; // Ready for next job
2078 
2079  break;
2080  }
2081  }
2082  else
2083  {
2084  // We have to start the READ job
2085  if(DeviceHandle == NULL)
2086  {
2087  #undef DEBUG
2088  //#define DEBUG
2089  #ifdef DEBUG
2090  printf("\n\rcDaisyPollFromDownstream - Device_handle = NULL\n\r");
2091  #endif
2092  }
2093  else
2094  {
2095  if(ReadTransfer == NULL)
2096  {
2097  #undef DEBUG
2098  //#define DEBUG
2099  #ifdef DEBUG
2100  printf("\n\rcDaisyPollFromDownstream - ReadTransfer = NULL\n\r");
2101  #endif
2102  }
2103  else
2104  {
2105  // Populate the transfer
2106  libusb_fill_interrupt_transfer( ReadTransfer,
2107  DeviceHandle,
2109  DataIn,
2112  NO_USER_DATA, // No user data
2113  TimeOutMs);
2114 
2115  ReadResult = libusb_submit_transfer(ReadTransfer);
2116  switch(ReadResult)
2117  {
2118  case LIBUSB_SUCCESS: // Read initiated OK
2119  ReadState = DAISY_RD_REQUESTED; // Ready for the callback to be called
2120  ReadLength = 0; // Nothing read yet
2121 
2122  //#define DEBUG
2123  #undef DEBUG
2124  #ifdef DEBUG
2125  printf("\n\rcDaisyPollFromDownstream REQ - LIBUSB_SUCCESS\n\r");
2126  #endif
2127 
2128  break;
2129 
2130  case LIBUSB_ERROR_NO_DEVICE: // Device gone, but can be requested later
2131  ReadState = DAISY_RD_IDLE; // No active job - Device is disconnected
2134 
2135  //#define DEBUG
2136  #undef DEBUG
2137  #ifdef DEBUG
2138  printf("\n\rcDaisyPollFromDownstream - LIBUSB_ERROR_NO_DEVICE\n\r");
2139  #endif
2140 
2141  break; // Try again later....
2142 
2143  default: // Some ERROR should not happen at start
2144  ReadState = DAISY_RD_IDLE; // if device present - No active job
2145 
2146  //#define DEBUG
2147  #undef DEBUG
2148  #ifdef DEBUG
2149  printf("\n\rcDaisyPollFromDownstream - LIBUSB_DEFAULT\n\r");
2150  #endif
2151 
2152  break; // Try again later....
2153  }
2154  }
2155  }
2156  }
2157 }
2158 
2159 int cDaisyWrite() // Write DOWNSTREAM
2160 {
2161  int ResValue;
2162  int ReturnValue = DAISY_WR_ERROR;
2163 
2164  if(WriteState == DAISY_WR_IDLE) // We're ready for a (new) write
2165  {
2166 
2167  //#define DEBUG
2168  #undef DEBUG
2169  #ifdef DEBUG
2170  printf("DAISY WriteState and IDLE\r\n");
2171  #endif
2172 
2173  // Do a start write
2174  libusb_fill_interrupt_transfer( WriteTransfer,
2175  DeviceHandle,
2177  DataOut,
2180  NO_USER_DATA, // No user data
2181  TimeOutMs);
2182 
2183  ResValue = libusb_submit_transfer(WriteTransfer);
2184 
2185  //#define DEBUG
2186  #undef DEBUG
2187  #ifdef DEBUG
2188  printf("ResValue from write submit = %d\n\r", ResValue);
2189  #endif
2190 
2191  switch(ResValue) // Could be returned as is,
2192  { // but if some should be rearranged,
2193  // renamed or grouped in another way
2194 
2195  case LIBUSB_SUCCESS:
2196  //#define DEBUG
2197  #undef DEBUG
2198  #ifdef DEBUG
2199  printf("Write submit LIBUSB_SUCCESS\n\r");
2200  #endif
2201 
2202  ReturnValue = DAISY_WR_NOT_FINISHED; // Write started OK
2203  LastWriteResult = DAISY_WR_NOT_FINISHED; // and NOT finished
2204  WriteState = DAISY_WR_REQUESTED; // Ready for for the callback to signal Write Done
2205 
2206  break;
2207 
2209 
2210  //#define DEBUG
2211  #undef DEBUG
2212  #ifdef DEBUG
2213  printf("Write submit LIBUSB_ERROR_NO_DEVICE\n\r");
2214  #endif
2215 
2216  ReturnValue = DAISY_WR_DISCONNECTED; // Device gone, but can be requested later
2217  LastWriteResult = DAISY_WR_DISCONNECTED; // signal it
2219  WriteState = DAISY_WR_IDLE; // We can be used if a device is connected
2220 
2221  break;
2222 
2223  case LIBUSB_ERROR_BUSY:
2224  //#define DEBUG
2225  #undef DEBUG
2226  #ifdef DEBUG
2227  printf("Write submit LIBUSB_ERROR_BUSY\n\r");
2228  #endif
2229 
2230  ReturnValue = DAISY_WR_NOT_FINISHED; // Previous write NOT finished
2232  WriteState = DAISY_WR_REQUESTED; // Still.... must be
2233 
2234  break;
2235 
2236  default:
2237  //#define DEBUG
2238  #undef DEBUG
2239  #ifdef DEBUG
2240  printf("Write submit DEFAULT in switch\n\r"); // ERROR
2241  #endif
2242 
2243  break;
2244  }
2245  }
2246  return ReturnValue;
2247 }
2248 
2249 RESULT cDaisyUnlockOk(void)
2250 {
2251  RESULT Result = FAIL;
2252 
2253  //#define DEBUG
2254  #undef DEBUG
2255  #ifdef DEBUG
2256  printf("cDaisyUnlockOk\n\r");
2257  #endif
2258 
2259  switch(ReadState)
2260  {
2261  case DAISY_RD_DONE: // We have to check the answer
2262 
2263  //#define DEBUG
2264  #undef DEBUG
2265  #ifdef DEBUG
2266  printf("Did we reach RD_DONE in UnLockOk?\n\r");
2267  #endif
2268 
2269  if((DataIn[SUBCMD] == DAISY_UNLOCK_SLAVE ) && (DataIn[STAT] == OK ))
2270  {
2271  Result = OK;
2272  //#define DEBUG
2273  #undef DEBUG
2274  #ifdef DEBUG
2275  printf("cDaisyUnlockOk -> OK\n\r");
2276  #endif
2277  }
2278  else
2279  {
2280  // else FAIL already set
2281 
2282  //#define DEBUG
2283  #undef DEBUG
2284  #ifdef DEBUG
2285  printf("cDaisyUnlockOk -> FAIL\n\r");
2286  #endif
2287  }
2288 
2289  break;
2290 
2291  case DAISY_RD_REQUESTED: // Still busy
2292 
2293  Result = BUSY;
2294 
2295  break;
2296 
2297  case DAISY_RD_DISCONNECTED: // ALREADY set: Result = FAIL;
2298  case DAISY_RD_TIMEDOUT: // Fall through
2299  case DAISY_RD_ERROR: // Fall through
2300 
2301  default: break;
2302  }
2303 
2304  return Result;
2305 }
2306 
2308 {
2309  FILE *pIdVendor = NULL;
2310  FILE *pIdProduct = NULL;
2311  char VendorBuffer[64];
2312  char ProductBuffer[64];
2313  RESULT Result = FAIL;
2314 
2315  pIdVendor = fopen("/sys/bus/usb/devices/1-1/idVendor", "r");
2316 
2317  pIdProduct = fopen("/sys/bus/usb/devices/1-1/idProduct", "r");
2318 
2319  if((pIdVendor != NULL) && (pIdProduct != NULL))
2320  {
2321  if(fgets(VendorBuffer, sizeof (VendorBuffer), pIdVendor) != NULL)
2322  {
2323  if(fgets(ProductBuffer, sizeof (ProductBuffer), pIdProduct) != NULL)
2324  {
2325  if((strstr(ProductBuffer, SLAVE_PROD_ID) > 0) && (strstr(VendorBuffer, SLAVE_VENDOR_ID) > 0))
2326  Result = OK;
2327  }
2328  }
2329  }
2330 
2331  if(pIdVendor != NULL)
2332  fclose(pIdVendor);
2333 
2334  if(pIdProduct != NULL)
2335  fclose(pIdProduct);
2336 
2337  return Result;
2338 }
2339 
2340 void cDaisyControl(void)
2341 {
2342  static ULONG TimeOld = 0;
2343  ULONG TimeNew;
2344  ULONG TimeDiff;
2345 
2346  int WriteRes = 0;
2347 
2348  // Update busy timeout
2349  TimeNew = GetTimeUS();
2350 
2351  if (TimeOld == 0)
2352  {
2353  TimeOld = TimeNew;
2354  }
2355 
2356  TimeDiff = TimeNew - TimeOld;
2357 
2358  if (BusyTimer > TimeDiff)
2359  {
2360  BusyTimer -= TimeDiff;
2361  }
2362  else
2363  {
2364  BusyTimer = 0;
2365  }
2366 
2367  TimeOld = TimeNew;
2368 
2369  // Do we have an interface at all?
2370 
2371  int EventResult = 0;
2372 
2373  EventResult = libusb_handle_events_timeout(0, &TV); // Let the CPU get some job done - but don't let it
2374  // use too much time.......
2375 
2376  switch(DownConnectionState) // What is downstream and what should we do---
2377  {
2378  case DAISY_DOWN_DISCONNECTED: // The "try and connect" is simple timed
2379 
2380  //#define DEBUG
2381  #undef DEBUG
2382  #ifdef DEBUG
2383  printf("DAISY_DOWN_DISCONNECTED\r\n");
2384  #endif
2385 
2386  PlugAndPlay--; // one more "loop"
2387 
2388  if(PlugAndPlay <= 0)
2389  {
2390  if(cDaisyCheckForAttachedSlave() == OK)
2391  {
2392  cDaisyOpen(); // Try to make a connection
2393  }
2394  else
2395  {
2396  PlugAndPlay = TIME_TO_CHECK_FOR_DAISY_DOWNSTREAM; // Another period
2398  //#define DEBUG
2399  #undef DEBUG
2400  #ifdef DEBUG
2401  printf("DAISY disconnected DOWNSTREAM - No slave bricks!! \r\n");
2402  #endif
2403  }
2404  }
2405  break;
2406 
2407  case DAISY_DOWN_CONNECTED: // Slave connected but still locked
2408 
2409  //#define DEBUG
2410  #undef DEBUG
2411  #ifdef DEBUG
2412  printf("DAISY_DOWN_CONNECTED\r\n");
2413  #endif
2414 
2416  {
2417  // Write request started OK
2419  }
2420  break;
2421 
2422  case DAISY_DOWN_UNLOCKING: // Write Request in progress
2423 
2424  //#define DEBUG
2425  #undef DEBUG
2426  #ifdef DEBUG
2427  printf("DAISY_DOWN_UNLOCKING\r\n");
2428  #endif
2429 
2431  {
2433  }
2434  else
2435  {
2436  //#define DEBUG
2437  #undef DEBUG
2438  #ifdef DEBUG
2439  printf("Before cDaisyStartReadUnlockAnswer()\r\n");
2440  #endif
2441 
2444  }
2445  break;
2446 
2447  case DAISY_CHECK_UNLOCK: // Check for a valid answer (DAISY_DOWN_UNLOCKED)
2448 
2449  //#define DEBUG
2450  #undef DEBUG
2451  #ifdef DEBUG
2452  printf("DAISY_CHECK_UNLOCK ReadState = %d\r\n", ReadState);
2453  #endif
2454 
2455  if(ReadState == DAISY_RD_DONE)
2456  {
2457  //#define DEBUG
2458  #undef DEBUG
2459  #ifdef DEBUG
2460  printf("DAISY_RD_DONE\n\r");
2461  #endif
2462 
2463  if(cDaisyUnlockOk() == OK)
2464  {
2465  //#define DEBUG
2466  #undef DEBUG
2467  #ifdef DEBUG
2468  printf("cDaisyUnlockOk() returned OK\n\r");
2469  #endif
2470 
2473  }
2474  else
2475  {
2476  //#define DEBUG
2477  #undef DEBUG
2478  #ifdef DEBUG
2479  printf("cDaisyUnlockOk() failed :-( \n\r");
2480  #endif
2481 
2483  }
2484  }
2485  else
2486  {
2487  if(ReadState == DAISY_RD_ERROR)
2488  {
2490  }
2491  }
2492  break;
2493 
2494  case DAISY_DOWN_UNLOCKED: // Initialized i.e. UNLOCKed and ready for Transfer of INFO & DATA
2495 
2496  //#define DEBUG
2497  #undef DEBUG
2498  #ifdef DEBUG
2499  printf("DAISY_DOWN_UNLOCKED\r\n");
2500  #endif
2501 
2502  // Poll as fast as possible and even faster.....
2503 
2505 
2506  break;
2507 
2508  case DAISY_DOWN_SET_DEVICETYPE: // Write mode in progress
2509 
2510  WriteRes = cDaisyWriteDone();
2511  switch(WriteRes)
2512  {
2513 
2514  case DAISY_WR_NOT_FINISHED: // Wait polite...
2515  break;
2516 
2517  case DAISY_WR_IDLE: // Success :-)
2519 
2520  // Do the Polling Job again
2521  if(GetUnlocked() == TRUE) cDaisyPollFromDownStream(); // We have control :-)
2522  break;
2523 
2524  case DAISY_WR_DISCONNECTED: // Blame the user for falling in the wire
2527  break;
2528 
2529  case DAISY_WR_ERROR: // Unhappy - error while setting the MODE
2531  // FALL through! break;
2532  default:
2533 
2534  break;
2535  }
2536 
2537  break;
2538 
2539  case DAISY_DOWNSTREAM_CHECK_WRITE_DONE: // Generic Write in progress
2540  WriteRes = cDaisyWriteDone();
2541 
2542  switch(WriteRes)
2543  {
2544  case DAISY_WR_NOT_FINISHED: // Wait polite...
2545  break;
2546 
2547  case DAISY_WR_IDLE: // Success :-)
2549  // Do the Polling Job again
2550  if(GetUnlocked() == TRUE) cDaisyPollFromDownStream(); // We have control :-)
2551  break;
2552 
2553  case DAISY_WR_DISCONNECTED: // Blame the user for falling in the wire
2556  break;
2557 
2558  case DAISY_WR_ERROR: // Unhappy - error while writing
2559  // FALL through! break;
2560  default:
2561 
2562  break;
2563  }
2564 
2565  break;
2566 
2567 
2568  default: break;
2569  }
2570 }
2571 
2572 RESULT cDaisyOpen(void)
2573 {
2574  if(DeviceHandle != NULL)
2575  {
2576  libusb_close(DeviceHandle); // Close for safe open (again)
2577  DeviceHandle = NULL; // NO false pointer
2578  }
2579  return (cDaisyInit());
2580 }
2581 
2582 RESULT cDaisyClose(void)
2583 {
2584  return (cDaisyExit());
2585 }
2586 
2587 RESULT cDaisyExit(void)
2588 {
2589  RESULT Result = OK;
2590 
2591  if(ReadTransfer)
2592  libusb_free_transfer(ReadTransfer); // Cleanup
2593  if(WriteTransfer)
2594  libusb_free_transfer(WriteTransfer); // Cleanup
2595 
2598  libusb_exit(NULL);
2599 
2600  DeviceHandle = NULL;
2601  return (Result);
2602 }
void cDaisyResetBusyTiming(void)
Definition: c_daisy.c:220
#define DAISY_INTERRUPT_EP_IN
Definition: c_daisy.h:123
#define DAISY_CHAIN_DOWNSTREAM_WITH_BUSY
Definition: c_daisy.h:72
int ReadLength
Definition: c_daisy.c:68
RESULT cDaisyDownStreamCmd(DATA8 *pData, DATA8 Length, DATA8 Layer)
Definition: c_daisy.c:665
RESULT cInputGetDeviceData(DATA8 Layer, DATA8 Port, DATA8 Length, DATA8 *pType, DATA8 *pMode, DATA8 *pData)
Definition: c_input.c:1935
UBYTE cDaisyCheckBusyBit(UBYTE Layer, UBYTE PortBits)
Definition: c_daisy.c:360
DATA8 ReadSensorPointer
Definition: c_daisy.c:73
void cDaisyStartReadUnlockAnswer(void)
Definition: c_daisy.c:610
#define SLAVE_PROD_ID
Definition: c_daisy.h:141
int GetSensorPointer(void)
Definition: c_daisy.c:999
#define DAISY_SENSOR_DATA_SIZE
Definition: c_daisy.h:212
RESULT cDaisyOpen(void)
Definition: c_daisy.c:2572
void cDaisySetupMagicCookies(uint StoreFrom, UBYTE Layer, UBYTE PortField)
Definition: c_daisy.c:320
MSGCNT cDaisyReplyNumber(void)
Definition: c_daisy.c:1361
Definition: lms2012.h:558
RESULT cDaisyCheckForAttachedSlave(void)
Definition: c_daisy.c:2307
#define DAISY_MAX_SENSORS_PER_LAYER
Definition: c_daisy.h:134
Definition: c_daisy.h:372
void cDaisyFlagDisconnected(DATA8 StartLayer)
Definition: c_daisy.c:189
void DaisyZeroAllExceptMySelf(void)
Definition: c_daisy.c:1207
void cDaisyFlagFail(DATA8 Layer, DATA8 Sensor)
Definition: c_daisy.c:179
int cDaisyWrite()
Definition: c_daisy.c:2159
void cDaisySetMasterCookie(uint Index, UBYTE CookieValue)
Definition: c_daisy.c:297
ULONG BusyTimer
Definition: c_daisy.c:108
void cDaisySetTimeout(int TimeOut)
Definition: c_daisy.c:1009
uint GetDaisyPushCounter(void)
Definition: c_daisy.c:510
void cDaisySetOwnLayer(UBYTE Layer)
Definition: c_daisy.c:204
uint PushPriorityCounter
Definition: c_daisy.c:109
ULONG GetTimeUS(void)
Definition: lms2012.c:327
int DaisyControlState
Definition: c_daisy.c:77
struct libusb_device_handle libusb_device_handle
Definition: libusb.h:591
#define SENSOR_POS_TO_SLAVE
Definition: c_daisy.h:399
void LogErrorNumber(ERR Err)
Definition: lms2012.c:445
struct timeval TV
Definition: c_daisy.c:147
CMDSIZE CmdSize
Definition: c_daisy.h:157
#define DAISY_MAX_LAYER_DEPT
Definition: c_daisy.h:135
int libusb_detach_kernel_driver(libusb_device_handle *dev, int interface)
RESULT cInputStartTypeDataUpload(void)
Definition: c_input.c:3243
#define DAISY_DEVICE_PAYLOAD_SIZE
Definition: c_daisy.h:208
UBYTE DaisyBusyFlags[BUSYFLAGS]
Definition: c_daisy.c:120
CMDSIZE CmdSize
Definition: c_daisy.h:192
int cDaisyGetLastWriteState(void)
Definition: c_daisy.c:169
void DaisyResetTheBuffers(int FromLayer)
Definition: c_daisy.c:1185
void DaisyAsyncReadCallBack(struct libusb_transfer *ReadUsbTransfer)
Definition: c_daisy.c:547
unsigned int TimeOut
Definition: c_wifi.c:100
DATA8 PayLoad[]
Definition: c_daisy.h:240
#define BUSYFLAGS_START_POS
Definition: c_daisy.h:213
int libusb_release_interface(libusb_device_handle *dev, int iface)
RESULT cDaisyCreateSpeedInfo(void)
Definition: c_daisy.c:1019
int actual_length
Definition: libusb.h:748
libusb_device * libusb_get_device(libusb_device_handle *dev_handle)
Definition: c_com.h:964
void ResetDaisyPushCounter(void)
Definition: c_daisy.c:520
RESULT cDaisyCheckBusyIndex(UBYTE Layer, UBYTE Port)
Definition: c_daisy.c:350
Definition: lms2012.h:557
#define DAISY_COMMAND_REPLY
Definition: c_daisy.h:60
RESULT cDaisyClose(void)
Definition: c_daisy.c:2582
UBYTE DaisyInfo
Definition: c_daisy.c:78
Definition: c_daisy.h:377
Definition: c_daisy.h:406
int PlugAndPlay
Definition: c_daisy.c:82
#define DAISY_SET_TYPE
Definition: c_daisy.h:71
int SlaveUnlocked
Definition: c_daisy.c:106
#define TIME_TO_CHECK_FOR_DAISY_DOWNSTREAM
Definition: c_daisy.h:426
#define DAISY_PRIORITY_COUNT
Definition: c_daisy.h:413
int GetUnlocked(void)
Definition: c_daisy.c:154
DATA8 cDaisyGetUsbUpStreamSpeed(void)
Definition: c_daisy.c:960
#define DAISY_COMMAND_NO_REPLY
Definition: c_daisy.h:61
UBYTE DaisyUpstreamDataBuffer[DAISY_DEFAULT_MAX_EP_SIZE]
Definition: c_daisy.c:86
uint cDaisyGetPosFromLayerAndPort(UBYTE Layer, UBYTE Port)
Definition: c_daisy.c:315
DATA8 DaisyTempTypeSensor
Definition: c_daisy.c:99
int DaisyUpstreamDataReady
Definition: c_daisy.c:115
MSGCNT MsgCount
Definition: c_daisy.h:193
RESULT cDaisyInit(void)
Definition: c_daisy.c:1212
struct libusb_device_handle * DeviceHandle
Definition: c_daisy.c:58
RESULT cDaisyGetDeviceInfo(DATA8 Length, UBYTE *pInfo)
Definition: c_daisy.c:1370
enum libusb_transfer_status status
Definition: libusb.h:740
int cDaisyWriteDone(void)
Definition: c_daisy.c:1806
int cDaisyWriteUnlockToSlave()
Definition: c_daisy.c:1333
USB_SPEED UpStreamConnection
Definition: c_daisy.c:103
int GetSensorStorePointer(void)
Definition: c_daisy.c:1356
int GetLayerStorePointer(void)
Definition: c_daisy.c:1351
#define SLAVE_VENDOR_ID
Definition: c_daisy.h:142
#define DAISY_SENSOR_OUTPUT_OFFSET
Definition: c_daisy.h:211
void cDaisySetBusyFlags(UBYTE Layer, UBYTE Port, UBYTE MagicCookie)
Definition: c_daisy.c:391
unsigned int ULONG
Basic Type used to symbolise 32 bit unsigned values.
Definition: lmstypes.h:31
void cDaisyPrepareNext(void)
Definition: c_daisy.c:1643
#define DAISY_CHAIN_DOWNSTREAM
Definition: c_daisy.h:67
#define DAISY_INTERRUPT_EP_OUT
Definition: c_daisy.h:124
int DaisyMsgCounter
Definition: c_daisy.c:76
UBYTE DeviceData[DEVICE_MAX_DATA]
Definition: c_daisy.h:201
DATA8 DaisyBuffers[DAISY_MAX_LAYER_DEPT][DAISY_MAX_SENSORS_PER_LAYER][DAISY_MAX_DATASIZE]
Definition: c_daisy.c:87
DATA8 DaisyTempDownLayer
Definition: c_daisy.c:100
UBYTE cDaisyOwnLayer
Definition: c_daisy.c:117
#define DAISY_CHAIN_INFO
Definition: c_daisy.h:69
#define MAX_DEVICE_INFOLENGTH
Number of bytes in the structure above (can not be changed)
Definition: lms2012.h:800
#define SIZEOF_REPLY_DAISY_READ
Definition: c_daisy.h:207
#define SENSOR_POS
Definition: c_daisy.h:227
int libusb_get_max_packet_size(libusb_device *dev, unsigned char endpoint)
#define NO_USER_DATA
Definition: c_daisy.h:131
void cDaisyPollFromDownStream(void)
Definition: c_daisy.c:1852
void cDaisyStuffRefill(void)
Definition: c_daisy.c:495
UBYTE cDaisyGetOwnLayer(void)
Definition: c_daisy.c:215
struct libusb_transfer * WriteTransfer
Definition: c_daisy.c:63
struct libusb_transfer * libusb_alloc_transfer(int iso_packets)
RESULT IsDaisyChained
Definition: c_daisy.c:95
void libusb_close(libusb_device_handle *dev_handle)
UBYTE DataOut[DAISY_DEFAULT_MAX_EP_SIZE]
Definition: c_daisy.c:85
#define DAISY_REPLY
Definition: c_daisy.h:98
#define ComInstance
Definition: c_com.h:1591
Definition: c_com.h:939
int DownConnectionState
Definition: c_daisy.c:80
int Unlocked
Definition: c_daisy.c:105
RESULT cDaisyUnlockOk(void)
Definition: c_daisy.c:2249
Definition: c_daisy.h:373
int GetLayerPointer(void)
Definition: c_daisy.c:994
UWORD CMDSIZE
Definition: c_com.h:960
int WriteState
Definition: c_daisy.c:64
RESULT cDaisyMotorDownStream(DATA8 *pData, DATA8 Length, DATA8 Layer, DATA8 PortField)
Definition: c_daisy.c:399
#define DIR_CMD_NO_REPLY_WITH_BUSY
Definition: c_com.h:933
RESULT cDaisyWriteTypeDownstream(DATA8 Layer, DATA8 Port, DATA8 Type, DATA8 Mode)
Definition: c_daisy.c:1069
#define PAYLOAD_OFFSET
Definition: c_daisy.h:233
#define DAISY_MAX_DATASIZE
Definition: c_daisy.h:230
void libusb_free_transfer(struct libusb_transfer *transfer)
void cDaisyUpdateLocalBusyFlags(UBYTE Layer)
Definition: c_daisy.c:385
uint DaisyPushCounter
Definition: c_daisy.c:111
void cDaisyControl(void)
Definition: c_daisy.c:2340
DATA8 ReadLayerPointer
Definition: c_daisy.c:72
int BytesWritten
Definition: c_daisy.c:67
#define INTERFACE_NUMBER
Definition: c_daisy.h:117
unsigned char UBYTE
Basic Type used to symbolise 8 bit unsigned values.
Definition: lmstypes.h:29
RESULT cDaisyGetDownstreamData(DATA8 Layer, DATA8 Sensor, DATA8 Length, DATA8 *pType, DATA8 *pMode, DATA8 *pData)
Definition: c_daisy.c:1670
UWORD MSGCNT
Definition: c_com.h:961
void cDaisyIncrementMasterCookie(uint Index)
Definition: c_daisy.c:307
#define MODE_POS_TO_SLAVE
Definition: c_daisy.h:401
Definition: c_daisy.h:405
void DaisyZeroTheBuffers(void)
Definition: c_daisy.c:1202
int ReadState
Definition: c_daisy.c:65
int libusb_handle_events_timeout(libusb_context *ctx, struct timeval *tv)
RESULT cDaisyChained(void)
Definition: c_daisy.c:1004
DATA8 DaisyTempTypeLayer
Definition: c_daisy.c:98
Definition: c_com.h:1516
Definition: c_com.h:1534
#define DAISY_MAX_EP_IN_SIZE
Definition: c_daisy.h:126
int cDaisyGetMaxPacketSize(libusb_device_handle *DeviceHandle)
Definition: c_daisy.c:948
#define DAISY_UPSTREAM_DATA_LENGTH
Definition: c_daisy.h:129
UBYTE cDaisyMasterCookieArray[16]
Definition: c_daisy.c:119
unsigned short UWORD
Basic Type used to symbolise 16 bit unsigned values.
Definition: lmstypes.h:30
int LastWriteResult
Definition: c_daisy.c:66
libusb_device_handle * libusb_open_device_with_vid_pid(libusb_context *ctx, uint16_t vendor_id, uint16_t product_id)
UBYTE FirstCookie
Definition: c_daisy.h:203
Definition: c_daisy.h:371
#define LAYER_POS
Definition: c_daisy.h:226
RESULT cDaisyTxDownStream(void)
Definition: c_daisy.c:227
RESULT cDaisySetDeviceType(DATA8 Layer, DATA8 Port, DATA8 Type, DATA8 Mode)
Definition: c_daisy.c:1156
int libusb_submit_transfer(struct libusb_transfer *transfer)
void cDaisyFlagBusy(DATA8 Layer, DATA8 Sensor)
Definition: c_daisy.c:184
void cDaisyCmd(RXBUF *pRxBuf, TXBUF *pTxBuf)
Definition: c_daisy.c:722
#define DAISY_VENDOR_ID
Definition: c_daisy.h:115
#define DAISY_MAX_INPUT_SENSOR_INDEX
Definition: c_daisy.h:210
MSGCNT ReplyNumber
Definition: c_daisy.c:96
Definition: c_daisy.h:374
#define LAYER_POS_TO_SLAVE
Definition: c_daisy.h:398
#define SIZEOF_UNLOCK_REPLY
Definition: c_daisy.h:164
MSGCNT MsgCount
Definition: c_daisy.h:169
int cDaisyGetLastWriteResult(void)
Definition: c_daisy.c:174
#define TYPE_POS_TO_SLAVE
Definition: c_daisy.h:400
int cDaisyGetInterruptPacketSize(void)
Definition: c_daisy.c:1014
#define DAISY_PUSH_NOT_UNLOCKED
Definition: c_daisy.h:414
int PushState
Definition: c_daisy.c:81
RESULT cDaisyExit(void)
Definition: c_daisy.c:2587
void DaisyAsyncWriteCallBack(struct libusb_transfer *WriteUsbTransfer)
Definition: c_daisy.c:1735
#define DAISY_PRODUCT_ID
Definition: c_daisy.h:116
void cDaisyPushUpStream(void)
Definition: c_daisy.c:1442
#define BUSYFLAGS
Definition: c_daisy.h:138
int GetSlaveUnlocked(void)
Definition: c_daisy.c:164
RESULT cDaisyReady(void)
Definition: c_daisy.c:531
SBYTE DATA8
VM Type for 1 byte signed value.
Definition: lmstypes.h:61
#define BUSYTIME
Definition: c_daisy.h:412
uint OldDaisyCounter
Definition: c_daisy.c:112
UWORD cDaisyData(UBYTE **pData)
Definition: c_daisy.c:500
int DaisyStuffRefill
Definition: c_daisy.c:114
UBYTE cMotorGetBusyFlags(void)
Definition: c_output.c:382
RESULT cDaisySetDeviceInfo(DATA8 Length, UBYTE *pInfo)
Definition: c_daisy.c:1396
#define DEVICE_MAX_DATA
Definition: c_daisy.h:137
void DecrementDaisyPushCounter(void)
Definition: c_daisy.c:525
int libusb_init(libusb_context **ctx)
void cDaisyClearMasterCookie(uint Index)
Definition: c_daisy.c:302
void SetUnlocked(int Status)
Definition: c_daisy.c:149
RESULT DaisyReadyState
Definition: c_daisy.c:110
#define DAISY_UNLOCK_SLAVE
Definition: c_daisy.h:70
int libusb_claim_interface(libusb_device_handle *dev, int iface)
UBYTE DaisyInfoBuffer[DAISY_DEFAULT_MAX_EP_SIZE]
Definition: c_daisy.c:94
#define SIZEOF_DAISY_INFO_READ
Definition: c_daisy.h:224
int TimeOutMs
Definition: c_daisy.c:57
struct libusb_transfer * ReadTransfer
Definition: c_daisy.c:62
int MaxLowerLayer
Definition: c_daisy.c:74
#define DAISY_DEFAULT_MAX_EP_SIZE
Definition: c_daisy.h:128
USB_SPEED * pUsbSpeed
Definition: c_daisy.c:102
void libusb_exit(libusb_context *ctx)
void SetDaisyPushCounter(int Count)
Definition: c_daisy.c:515
int MaxInterruptPacketSize
Definition: c_daisy.c:56
#define DAISY_CHAIN_UPSTREAM
Definition: c_daisy.h:68
#define DAISY_DATA_PACKET
Definition: c_daisy.h:231
UBYTE Info[]
Definition: c_daisy.h:220
void SetSlaveUnlocked(int Status)
Definition: c_daisy.c:159
UBYTE DataIn[DAISY_DEFAULT_MAX_EP_SIZE]
Definition: c_daisy.c:84
RESULT cInputSetChainedDeviceType(DATA8 Layer, DATA8 Port, DATA8 Type, DATA8 Mode)
Definition: c_input.c:1752
#define NULL
#define DAISY_DEFAULT_TIMEOUT
Definition: c_daisy.h:130