Spectrometer library  2.1
Simplified version of the thread-safe core
libspectr.c
1 #include "libspectr.h"
2 #include "internal.h"
3 
4 #include <windows.h>
5 
6 
7 #ifndef AS_CORE_LIBRARY
8  #ifdef WIN32
9  BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
10  {
11  switch(fdwReason) {
12  case DLL_PROCESS_ATTACH:
13  //g_Device = NULL;
14  //g_numOfPixelsInFrame = 0;
15  break;
16  case DLL_PROCESS_DETACH:
17  //if (g_Device) {
18  // hid_close(g_Device);
19  // g_Device = NULL;
20  //}
21 
22  //if (g_savedSerial) {
23  // free(g_savedSerial);
24  // g_savedSerial = NULL;
25  //}
26  break;
27  }
28  return TRUE;
29  }
30  #endif
31 #endif
32 
33 int disconnectDeviceContext(uintptr_t* deviceContextPtr)
34 {
35  DeviceContext_t *deviceContext = NULL;
36 
37  if (!deviceContextPtr) {
38  return OK;
39  }
40 
41  deviceContext = (DeviceContext_t*)(*deviceContextPtr);
42 
43  hid_close(deviceContext->handle);
44  free(deviceContext->serial);
45 
46  free(deviceContext);
47  *deviceContextPtr = 0;
48 
49  return 0;
50 }
51 
52 
53 int connectToDeviceBySerial(const char * const serialNumber, uintptr_t* deviceContextPtr)
54 {
55  wchar_t *serialWChar = NULL;
56  int cLen = serialNumber? strlen(serialNumber) : 0;
57 
58  DeviceContext_t *deviceContext = NULL;
59 
60  if (!deviceContextPtr) {
61  return NO_DEVICE_CONTEXT_ERROR;
62  }
63 
64  deviceContext = (DeviceContext_t*)(*deviceContextPtr);
65  free(deviceContext);
66 
67  deviceContext = malloc(sizeof(DeviceContext_t));
68  *deviceContext = NULL_DEVICE_CONTEXT;
69 
70  if (cLen) {
71  ++cLen; //for \0
72  serialWChar = calloc(sizeof(wchar_t) * cLen, sizeof(wchar_t));
73  mbstowcs(serialWChar, serialNumber, cLen);
74  }
75 
76  if (deviceContext->handle) {
77  hid_close(deviceContext->handle);
78  deviceContext->handle = NULL;
79  }
80 
81  deviceContext->handle = hid_open(USBD_VID, USBD_PID, (const wchar_t *)serialWChar);
82  if (deviceContext->handle == NULL) {
83  free(serialWChar);
84  return CONNECT_ERROR_FAILED;
85  }
86 
87  if (serialWChar) {
88  if (serialNumber != deviceContext->serial) {
89  free(deviceContext->serial);
90  deviceContext->serial = calloc(sizeof(char) * cLen, sizeof(char));
91  strcpy(deviceContext->serial, serialNumber);
92  }
93 
94  free(serialWChar);
95  }
96 
97  return OK;
98 }
99 
100 int connectToDeviceByIndex(unsigned int index, uintptr_t* deviceContextPtr) //0..n-1
101 {
102  int cBytesCount = 0, wcLen = 0;
103  int count = 0;
104  struct hid_device_info *devices = hid_enumerate(USBD_VID, USBD_PID),
105  *deviceIterator = devices;
106 
107  wchar_t *serialWChar = NULL;
108 
109  DeviceContext_t *deviceContext = NULL;
110 
111  if (!deviceContextPtr) {
112  return NO_DEVICE_CONTEXT_ERROR;
113  }
114 
115  deviceContext = (DeviceContext_t*)(*deviceContextPtr);
116  free(deviceContext);
117  *deviceContextPtr = 0;
118 
119  deviceContext = malloc(sizeof(DeviceContext_t));
120  *deviceContext = NULL_DEVICE_CONTEXT;
121 
122  while (deviceIterator) {
123  ++count;
124 
125  if (index == count - 1) {
126  serialWChar = deviceIterator->serial_number;
127  break;
128  } else {
129  deviceIterator = deviceIterator->next;
130  }
131  }
132 
133  if (!serialWChar) {
134  hid_free_enumeration(devices);
135  return CONNECT_ERROR_NOT_FOUND;
136  }
137 
138  if (deviceContext->handle) {
139  hid_close(deviceContext->handle);
140  deviceContext->handle = NULL;
141  }
142  deviceContext->handle = hid_open(USBD_VID, USBD_PID, (const wchar_t *)serialWChar);
143 
144  if (deviceContext->handle == NULL) {
145  hid_free_enumeration(devices);
146  return CONNECT_ERROR_FAILED;
147  }
148 
149  wcLen = wcslen(serialWChar);
150  cBytesCount = wcstombs(NULL, serialWChar, wcLen);
151 
152  free(deviceContext->serial);
153  deviceContext->serial = calloc(cBytesCount + 1, sizeof(char));
154  wcstombs(deviceContext->serial, serialWChar, wcLen);
155 
156  hid_free_enumeration(devices);
157 
158  *deviceContextPtr = (uintptr_t)deviceContext;
159 
160  return OK;
161 }
162 
163 uint32_t getDevicesCount()
164 {
165  int count = 0;
166  struct hid_device_info *devices = hid_enumerate(USBD_VID, USBD_PID),
167  *device = devices;
168 
169  while (device != NULL) {
170  ++count;
171  device = device->next;
172  }
173 
174  hid_free_enumeration(devices);
175  return count;
176 }
177 
179 {
180  DeviceInfo_t *resultList = NULL,
181  *current = NULL,
182  *parent = NULL;
183 
184  int cBytesCount = 0, wcLen = 0;
185 
186  struct hid_device_info *devices = hid_enumerate(USBD_VID, USBD_PID),
187  *device = devices;
188 
189  wchar_t *serialWChar = NULL;
190 
191  while (device) {
192  current = malloc(sizeof(DeviceInfo_t));
193 
194  serialWChar = device->serial_number;
195  wcLen = wcslen(serialWChar);
196  cBytesCount = wcstombs(NULL, serialWChar, wcLen);
197 
198  current->serialNumber = calloc(cBytesCount + 1, sizeof(char));
199  wcstombs(current->serialNumber, serialWChar, wcLen);
200  current->next = NULL;
201 
202  if (resultList == NULL) {
203  resultList = current;
204  }
205 
206  if (parent != NULL) {
207  parent->next = current;
208  }
209 
210  parent = current;
211  device = device->next;
212  }
213 
214  hid_free_enumeration(devices);
215  return resultList;
216 }
217 
218 void clearDevicesInfo(struct DeviceInfo_t *devices)
219 {
220  _recursiveClearing(devices);
221  free(devices);
222 }
223 
224 int setFrameFormat(uint16_t numOfStartElement, uint16_t numOfEndElement, uint8_t reductionMode, uint16_t *numOfPixelsInFrame, uintptr_t* deviceContextPtr)
225 {
226  unsigned char report[EXTENDED_PACKET_SIZE];
227  int result = -1;
228  int errorCode = -1;
229  DeviceContext_t *deviceContext = NULL;
230 
231  result = _verifyDeviceContextByPtr(deviceContextPtr);
232  if (result != OK)
233  return result;
234 
235  deviceContext = (DeviceContext_t*)(*deviceContextPtr);
236 
237  report[0] = ZERO_REPORT_ID;
238  report[1] = SET_FRAME_FORMAT_REQUEST;
239  report[2] = LOW_BYTE(numOfStartElement);
240  report[3] = HIGH_BYTE(numOfStartElement);
241  report[4] = LOW_BYTE(numOfEndElement);
242  report[5] = HIGH_BYTE(numOfEndElement);
243  report[6] = reductionMode;
244 
245  result = _writeReadFunction(report, CORRECT_SET_FRAME_FORMAT_REPLY, STANDARD_TIMEOUT_MILLISECONDS, deviceContextPtr);
246  if (result != OK) {
247  return result;
248  }
249 
250  errorCode = report[1];
251  if (!errorCode) {
252  deviceContext->numOfPixelsInFrame = (report[3] << 8) | report[2];
253 
254  if (numOfPixelsInFrame) {
255  *numOfPixelsInFrame = deviceContext->numOfPixelsInFrame;
256  }
257  }
258 
259  return errorCode;
260 }
261 
262 int setExposure(uint32_t timeOfExposure, uint8_t force, uintptr_t* deviceContextPtr)
263 {
264  unsigned char report[EXTENDED_PACKET_SIZE];
265  int result = -1;
266  int errorCode = -1;
267 
268  result = _verifyDeviceContextByPtr(deviceContextPtr);
269  if (result != OK)
270  return result;
271 
272  report[0] = ZERO_REPORT_ID;
273  report[1] = SET_EXPOSURE_REQUEST;
274  report[2] = LOW_BYTE(LOW_WORD(timeOfExposure)); //(exposure >> 24) & 0xFF;
275  report[3] = HIGH_BYTE(LOW_WORD(timeOfExposure)); //(exposure >> 16) & 0xFF;
276  report[4] = LOW_BYTE(HIGH_WORD(timeOfExposure)); //(exposure >> 8) & 0xFF;
277  report[5] = HIGH_BYTE(HIGH_WORD(timeOfExposure)); //exposure & 0xFF;
278  report[6] = force;
279 
280  result = _writeReadFunction(report, CORRECT_SET_EXPOSURE_REPLY, STANDARD_TIMEOUT_MILLISECONDS, deviceContextPtr);
281  if (result != OK) {
282  return result;
283  }
284 
285  errorCode = report[1];
286  return errorCode;
287 }
288 
289 int setAcquisitionParameters(uint16_t numOfScans, uint16_t numOfBlankScans, uint8_t/*ScanMode_t*/ scanMode, uint32_t timeOfExposure, uintptr_t* deviceContextPtr)
290 {
291  uint8_t report[EXTENDED_PACKET_SIZE];
292  int result = -1;
293  int errorCode = -1;
294 
295  result = _verifyDeviceContextByPtr(deviceContextPtr);
296  if (result != OK)
297  return result;
298 
299  report[0] = ZERO_REPORT_ID;
300  report[1] = SET_ACQUISITION_PARAMETERS_REQUEST;
301  report[2] = LOW_BYTE(numOfScans);
302  report[3] = HIGH_BYTE(numOfScans);
303  report[4] = LOW_BYTE(numOfBlankScans);
304  report[5] = HIGH_BYTE(numOfBlankScans);
305  report[6] = scanMode;
306  report[7] = LOW_BYTE(LOW_WORD(timeOfExposure));
307  report[8] = HIGH_BYTE(LOW_WORD(timeOfExposure));
308  report[9] = LOW_BYTE(HIGH_WORD(timeOfExposure));
309  report[10] = HIGH_BYTE(HIGH_WORD(timeOfExposure));
310 
311  result = _writeReadFunction(report, CORRECT_SET_ACQUISITION_PARAMETERS_REPLY, STANDARD_TIMEOUT_MILLISECONDS, deviceContextPtr);
312  if (result != OK) {
313  return result;
314  }
315 
316  errorCode = report[1];
317  return errorCode;
318 }
319 
320 int setMultipleParameters(uint16_t numOfScans, uint16_t numOfBlankScans, uint8_t /*ScanMode_t*/ scanMode, uint32_t timeOfExposure, uint8_t/*EnableMode_t*/ enableMode, uint8_t/*TriggerFront_t*/ signalFrontMode, uintptr_t* deviceContextPtr)
321 {
322  unsigned char report[EXTENDED_PACKET_SIZE];
323  int result = -1;
324  int errorCode = -1;
325 
326  result = _verifyDeviceContextByPtr(deviceContextPtr);
327  if (result != OK)
328  return result;
329 
330  report[0] = ZERO_REPORT_ID;
331  report[1] = SET_ALL_PARAMETERS_REQUEST;
332  report[2] = LOW_BYTE(numOfScans);
333  report[3] = HIGH_BYTE(numOfScans);
334  report[4] = LOW_BYTE(numOfBlankScans);
335  report[5] = HIGH_BYTE(numOfBlankScans);
336  report[6] = scanMode;
337  report[7] = LOW_BYTE(LOW_WORD(timeOfExposure));
338  report[8] = HIGH_BYTE(LOW_WORD(timeOfExposure));
339  report[9] = LOW_BYTE(HIGH_WORD(timeOfExposure));
340  report[10] = HIGH_BYTE(HIGH_WORD(timeOfExposure));
341  report[11] = enableMode;
342  report[12] = signalFrontMode;
343 
344  result = _writeReadFunction(report, CORRECT_GET_ACQUISITION_PARAMETERS_REPLY, STANDARD_TIMEOUT_MILLISECONDS, deviceContextPtr);
345  if (result != OK) {
346  return result;
347  }
348 
349  errorCode = report[1];
350  return errorCode;
351 }
352 
353 int setExternalTrigger(uint8_t /*EnableMode_t*/ enableMode, uint8_t /*TriggerFront_t*/ signalFrontMode, uintptr_t* deviceContextPtr)
354 {
355  unsigned char report[EXTENDED_PACKET_SIZE];
356  int result = -1;
357  int errorCode = -1;
358 
359  result = _verifyDeviceContextByPtr(deviceContextPtr);
360  if (result != OK)
361  return result;
362 
363  report[0] = ZERO_REPORT_ID;
364  report[1] = SET_EXTERNAL_TRIGGER_REQUEST;
365  report[2] = enableMode;
366  report[3] = signalFrontMode;
367 
368  result = _writeReadFunction(report, CORRECT_SET_EXTERNAL_TRIGGER_REPLY, STANDARD_TIMEOUT_MILLISECONDS, deviceContextPtr);
369  if (result != OK) {
370  return result;
371  }
372 
373  errorCode = report[1];
374  return errorCode;
375 }
376 
377 int setOpticalTrigger(uint8_t /*OpticalTriggerMode_t*/ enableMode, uint16_t pixel, uint16_t threshold, uintptr_t* deviceContextPtr)
378 {
379  uint8_t report[EXTENDED_PACKET_SIZE];
380  int result = -1;
381  int errorCode = -1;
382 
383  result = _verifyDeviceContextByPtr(deviceContextPtr);
384  if (result != OK)
385  return result;
386 
387  report[0] = ZERO_REPORT_ID;
388  report[1] = SET_OPTICAl_TRIGGER_REQUEST;
389  report[2] = enableMode;
390  report[3] = LOW_BYTE(pixel);
391  report[4] = HIGH_BYTE(pixel);
392  report[5] = LOW_BYTE(threshold);
393  report[6] = HIGH_BYTE(threshold);
394 
395  result = _writeReadFunction(report, CORRECT_SET_OPTICAL_TRIGGER_REPLY, STANDARD_TIMEOUT_MILLISECONDS, deviceContextPtr);
396  if (result != OK) {
397  return result;
398  }
399 
400  errorCode = report[1];
401  return errorCode;
402 }
403 
404 int triggerAcquisition(uintptr_t* deviceContextPtr)
405 {
406  unsigned char report[EXTENDED_PACKET_SIZE];
407  int result = -1;
408 
409  result = _verifyDeviceContextByPtr(deviceContextPtr);
410  if (result != OK)
411  return result;
412 
413  report[0] = ZERO_REPORT_ID;
414  report[1] = SET_SOFTWARE_TRIGGER_REQUEST;
415 
416  result = _writeOnlyFunction(report, deviceContextPtr);
417  return result;
418 }
419 
420 int getStatus(uint8_t *statusFlags, uint16_t *framesInMemory, uintptr_t* deviceContextPtr)
421 {
422  unsigned char report[EXTENDED_PACKET_SIZE];
423  int result = -1;
424 
425  result = _verifyDeviceContextByPtr(deviceContextPtr);
426  if (result != OK)
427  return result;
428 
429  report[0] = ZERO_REPORT_ID;
430  report[1] = STATUS_REQUEST;
431 
432  result = _writeReadFunction(report, CORRECT_STATUS_REPLY, STANDARD_TIMEOUT_MILLISECONDS, deviceContextPtr);
433  if (result != OK) {
434  return result;
435  }
436 
437  if (statusFlags) {
438  *statusFlags = report[1];
439  }
440 
441  if (framesInMemory) {
442  *framesInMemory = (report[3] << 8) | (report[2]);
443  }
444 
445  return OK;
446 }
447 
448 int getAcquisitionParameters(uint16_t* numOfScans, uint16_t* numOfBlankScans, uint8_t *scanMode, uint32_t* timeOfExposure, uintptr_t* deviceContextPtr)
449 {
450  uint8_t report[EXTENDED_PACKET_SIZE];
451  int result = -1;
452 
453  result = _verifyDeviceContextByPtr(deviceContextPtr);
454  if (result != OK)
455  return result;
456 
457  report[0] = ZERO_REPORT_ID;
458  report[1] = GET_ACQUISITION_PARAMETERS_REQUEST;
459 
460  result = _writeReadFunction(report, CORRECT_GET_ACQUISITION_PARAMETERS_REPLY, STANDARD_TIMEOUT_MILLISECONDS, deviceContextPtr);
461  if (result != OK) {
462  return result;
463  }
464 
465  if (numOfScans) {
466  *numOfScans = (report[2] << 8) | report[1];
467  }
468 
469  if (numOfBlankScans) {
470  *numOfBlankScans = (report[4] << 8) | report[3];
471  }
472 
473  if (scanMode) {
474  *scanMode = report[5];
475  }
476 
477  if (timeOfExposure) {
478  *timeOfExposure = (report[9] << 24) | (report[8] << 16) | (report[7] << 8) | report[6];
479  }
480 
481  return OK;
482 }
483 
484 int getFrameFormat(uint16_t *numOfStartElement, uint16_t *numOfEndElement, uint8_t *reductionMode, uint16_t *numOfPixelsInFrame, uintptr_t* deviceContextPtr)
485 {
486  unsigned char report[EXTENDED_PACKET_SIZE];
487  int result = -1;
488  DeviceContext_t *deviceContext = NULL;
489 
490  result = _verifyDeviceContextByPtr(deviceContextPtr);
491  if (result != OK)
492  return result;
493 
494  deviceContext = (DeviceContext_t*)(*deviceContextPtr);
495 
496  report[0] = ZERO_REPORT_ID;
497  report[1] = GET_FRAME_FORMAT_REQUEST;
498 
499  result = _writeReadFunction(report, CORRECT_GET_FRAME_FORMAT_REPLY, STANDARD_TIMEOUT_MILLISECONDS, deviceContextPtr);
500  if (result != OK) {
501  return result;
502  }
503 
504  if (numOfStartElement) {
505  *numOfStartElement = (report[2] << 8) | report[1];
506  }
507 
508  if (numOfEndElement) {
509  *numOfEndElement = (report[4] << 8) | report[3];
510  }
511 
512  if (reductionMode) {
513  *reductionMode = report[5];
514  }
515 
516  deviceContext->numOfPixelsInFrame = (report[7] << 8) | report[6];
517 
518  if (numOfPixelsInFrame) {
519  *numOfPixelsInFrame = deviceContext->numOfPixelsInFrame;
520  }
521 
522  return OK;
523 }
524 
525 int getFrame(uint16_t *framePixelsBuffer, uint16_t numOfFrame, uintptr_t* deviceContextPtr)
526 {
527  uint8_t report[EXTENDED_PACKET_SIZE];
528  int result = -1;
529 
530  /* Total frame request parameters: */
531  uint16_t pixelOffset = 0;
532  uint8_t numOfPacketsToGet = 0, numOfPacketsLeft = 0, numOfPacketsReceived = 0;
533 
534  bool continueGetInReport = true;
535  uint16_t totalNumOfReceivedPixels = 0;
536 
537  uint8_t indexOfPixelInPacket = 0;
538  int indexInPacket = 0;
539 
540  DeviceContext_t *deviceContext = NULL;
541 
542  result = _verifyDeviceContextByPtr(deviceContextPtr);
543  if (result != OK)
544  return result;
545 
546  deviceContext = (DeviceContext_t*)(*deviceContextPtr);
547 
548  if (!deviceContext->handle) {
549  result = _reconnect(deviceContextPtr);
550  if (result != OK) {
551  return result;
552  }
553  }
554 
555  if (!framePixelsBuffer) {
556  return INPUT_PARAMETER_NOT_INITIALIZED;
557  }
558 
559  if (!deviceContext->numOfPixelsInFrame) {
560  result = getFrameFormat(NULL, NULL, NULL, NULL, deviceContextPtr);
561  if (result != OK)
562  return result;
563  }
564 
565  numOfPacketsToGet = (deviceContext->numOfPixelsInFrame) / NUM_OF_PIXELS_IN_PACKET;
566  numOfPacketsToGet += (deviceContext->numOfPixelsInFrame % NUM_OF_PIXELS_IN_PACKET)? 1 : 0;
567 
568  if (numOfPacketsToGet > MAX_PACKETS_IN_FRAME) {
569  return NUM_OF_PACKETS_IN_FRAME_ERROR;
570  }
571 
572  report[0] = ZERO_REPORT_ID;
573  report[1] = GET_FRAME_REQUEST;
574  report[2] = LOW_BYTE(pixelOffset);
575  report[3] = HIGH_BYTE(pixelOffset);
576  report[4] = LOW_BYTE(numOfFrame);
577  report[5] = HIGH_BYTE(numOfFrame);
578  report[6] = numOfPacketsToGet;
579 
580  result = _tryWrite(report, deviceContextPtr);
581  if (result != OK) {
582  return result;
583  }
584  continueGetInReport = true;
585  while (continueGetInReport) {
586  result = hid_read_timeout(deviceContext->handle, report, EXTENDED_PACKET_SIZE, STANDARD_TIMEOUT_MILLISECONDS);
587  if (result != HID_OPERATION_READ_SUCCESS){
588  return READING_PROCESS_FAILED;
589  }
590 
591  if (report[0] != CORRECT_GET_FRAME_REPLY) {
592  return WRONG_ANSWER;
593  }
594 
595  ++numOfPacketsReceived;
596 
597  numOfPacketsLeft = report[3];
598  if (numOfPacketsLeft >= REMAINING_PACKETS_ERROR ||
599  (numOfPacketsLeft != numOfPacketsToGet - numOfPacketsReceived)) {
600  return GET_FRAME_REMAINING_PACKETS_ERROR;
601  }
602 
603  if (numOfPacketsLeft != numOfPacketsToGet - numOfPacketsReceived) {
604  return GET_FRAME_REMAINING_PACKETS_ERROR;
605  }
606 
607  continueGetInReport = (numOfPacketsLeft > 0)? true : false;
608 
609  pixelOffset = (report[2] << 8) | report[1];
610 
611  indexInPacket = 4;
612  indexOfPixelInPacket = 0;
613 
614  while ((totalNumOfReceivedPixels < deviceContext->numOfPixelsInFrame) && (indexOfPixelInPacket < NUM_OF_PIXELS_IN_PACKET)) {
615  uint16_t pixel = (report[indexInPacket + 1] << 8) | report[indexInPacket];
616  framePixelsBuffer[pixelOffset + indexOfPixelInPacket] = pixel;
617 
618  indexInPacket += 2;
619  ++indexOfPixelInPacket;
620  ++totalNumOfReceivedPixels;
621  }
622  }
623 
624  return OK;
625 }
626 
627 int clearMemory(uintptr_t* deviceContextPtr)
628 {
629  unsigned char report[EXTENDED_PACKET_SIZE];
630  int result = -1;
631  int errorCode = -1;
632 
633  result = _verifyDeviceContextByPtr(deviceContextPtr);
634  if (result != OK)
635  return result;
636 
637  report[0] = ZERO_REPORT_ID;
638  report[1] = CLEAR_MEMORY_REQUEST;
639 
640  result = _writeReadFunction(report, CORRECT_CLEAR_MEMORY_REPLY, STANDARD_TIMEOUT_MILLISECONDS, deviceContextPtr);
641  if (result != OK) {
642  return result;
643  }
644 
645  errorCode = report[1];
646  return errorCode;
647 }
648 
649 int eraseFlash(uintptr_t* deviceContextPtr)
650 {
651  int result = -1;
652  int errorCode = -1;
653  uint8_t report[EXTENDED_PACKET_SIZE];
654 
655  result = _verifyDeviceContextByPtr(deviceContextPtr);
656  if (result != OK)
657  return result;
658 
659  report[0] = ZERO_REPORT_ID;
660  report[1] = ERASE_FLASH_REQUEST;
661 
662  result = _writeReadFunction(report, CORRECT_ERASE_FLASH_REPLY, ERASE_FLASH_TIMEOUT_MILLISECONDS, deviceContextPtr);
663  if (result != OK) {
664  return result;
665  }
666 
667  errorCode = report[1];
668  return errorCode;
669 }
670 
671 int readFlash(uint8_t *buffer, uint32_t absoluteOffset, uint32_t bytesToRead, uintptr_t* deviceContextPtr)
672 {
673  int result = -1;
674  uint8_t report[EXTENDED_PACKET_SIZE];
675 
676  uint32_t numOfPacketsToGet = 0;
677  uint8_t numOfPacketsToGetCurrent = 0, numOfPacketsReceivedCurrent = 0, numOfPacketsLeftCurrent = 0;
678 
679  bool continueGetInReport = true;
680  uint16_t localOffset = 0;
681  uint32_t totalNumOfReceivedBytes = 0;
682 
683  uint8_t indexOfByteInPacket;
684  int indexInPacket;
685 
686  uint32_t offsetIncrement = 0;
687  uint8_t payloadSize = PACKET_SIZE - 4;
688 
689  DeviceContext_t *deviceContext = NULL;
690 
691  result = _verifyDeviceContextByPtr(deviceContextPtr);
692  if (result != OK)
693  return result;
694 
695  if (!buffer) {
696  return INPUT_PARAMETER_NOT_INITIALIZED;
697  }
698 
699  deviceContext = (DeviceContext_t*)(*deviceContextPtr);
700 
701  if (!deviceContext->handle) {
702  result = _reconnect(deviceContextPtr);
703  if (result != OK) {
704  return result;
705  }
706  }
707 
708  numOfPacketsToGet = bytesToRead / payloadSize;
709  numOfPacketsToGet += (bytesToRead % payloadSize)? 1 : 0;
710 
711  while(numOfPacketsToGet) {
712  numOfPacketsToGetCurrent = (numOfPacketsToGet > MAX_READ_FLASH_PACKETS)? MAX_READ_FLASH_PACKETS : numOfPacketsToGet;
713 
714  report[0] = ZERO_REPORT_ID;
715  report[1] = READ_FLASH_REQUEST;
716  report[2] = LOW_BYTE(LOW_WORD(absoluteOffset + offsetIncrement));
717  report[3] = HIGH_BYTE(LOW_WORD(absoluteOffset + offsetIncrement));
718  report[4] = LOW_BYTE(HIGH_WORD(absoluteOffset + offsetIncrement));
719  report[5] = HIGH_BYTE(HIGH_WORD(absoluteOffset + offsetIncrement));
720  report[6] = numOfPacketsToGetCurrent;
721 
722  result = hid_write(deviceContext->handle, (const unsigned char*)report, EXTENDED_PACKET_SIZE);
723  if (result != HID_OPERATION_WRITE_SUCCESS) {
724  return WRITING_PROCESS_FAILED;
725  }
726 
727  numOfPacketsReceivedCurrent = 0;
728  continueGetInReport = true;
729  while (continueGetInReport) {
730  result = hid_read_timeout(deviceContext->handle, report, EXTENDED_PACKET_SIZE, STANDARD_TIMEOUT_MILLISECONDS);
731  if (result != HID_OPERATION_READ_SUCCESS){
732  return READING_PROCESS_FAILED;
733  }
734 
735  ++numOfPacketsReceivedCurrent;
736 
737  if (report[0] != CORRECT_READ_FLASH_REPLY) {
738  return WRONG_ANSWER;
739  }
740 
741  numOfPacketsLeftCurrent = report[3];
742 
743  if (numOfPacketsLeftCurrent >= REMAINING_PACKETS_ERROR || (numOfPacketsLeftCurrent != numOfPacketsToGetCurrent - numOfPacketsReceivedCurrent)) {
744  return READ_FLASH_REMAINING_PACKETS_ERROR;
745  }
746  continueGetInReport = (numOfPacketsLeftCurrent > 0)? true : false;
747 
748  localOffset = (report[2] << 8) | report[1];
749 
750  indexInPacket = 4;
751  indexOfByteInPacket = 0;
752 
753  while ((totalNumOfReceivedBytes < bytesToRead) && (indexOfByteInPacket < payloadSize)) {
754  buffer[offsetIncrement + localOffset + indexOfByteInPacket++] = report[indexInPacket++];
755  ++totalNumOfReceivedBytes;
756  }
757  }
758 
759  if (numOfPacketsToGet > MAX_READ_FLASH_PACKETS) {
760  numOfPacketsToGet -= MAX_READ_FLASH_PACKETS;
761  offsetIncrement += MAX_READ_FLASH_PACKETS * payloadSize;
762  } else {
763  numOfPacketsToGet = 0;
764  }
765  }
766 
767  return OK;
768 }
769 
770 
771 int writeFlash(uint8_t *buffer, uint32_t absoluteOffset, uint32_t bytesToWrite, uintptr_t* deviceContextPtr)
772 {
773  int result = -1;
774  uint8_t report[EXTENDED_PACKET_SIZE];
775  uint8_t errorCode = -1;
776 
777  uint32_t index, byteIndex = 0;
778  uint32_t bytesLeftToWrite = bytesToWrite;
779 
780  DeviceContext_t *deviceContext = NULL;
781 
782  result = _verifyDeviceContextByPtr(deviceContextPtr);
783  if (result != OK)
784  return result;
785 
786  if (!buffer) {
787  return INPUT_PARAMETER_NOT_INITIALIZED;
788  }
789 
790  deviceContext = (DeviceContext_t*)(*deviceContextPtr);
791 
792  if (deviceContext->handle == NULL) {
793  result = _reconnect(deviceContextPtr);
794  if (result != OK) {
795  return result;
796  }
797  }
798 
799  while (bytesLeftToWrite) {
800  report[0] = ZERO_REPORT_ID;
801  report[1] = WRITE_FLASH_REQUEST;
802  report[2] = LOW_BYTE(LOW_WORD(absoluteOffset));
803  report[3] = HIGH_BYTE(LOW_WORD(absoluteOffset));
804  report[4] = LOW_BYTE(HIGH_WORD(absoluteOffset));
805  report[5] = HIGH_BYTE(HIGH_WORD(absoluteOffset));
806  report[6] = (bytesLeftToWrite > MAX_FLASH_WRITE_PAYLOAD) ? MAX_FLASH_WRITE_PAYLOAD : bytesLeftToWrite;
807 
808  index = 7;
809  while ((byteIndex < bytesToWrite) && (index < EXTENDED_PACKET_SIZE)) {
810  report[index++] = buffer[byteIndex++];
811  }
812 
813  result = hid_write(deviceContext->handle, (const unsigned char*)report, EXTENDED_PACKET_SIZE);
814  if (result != HID_OPERATION_WRITE_SUCCESS) {
815  return WRITING_PROCESS_FAILED;
816  }
817 
818  result = hid_read_timeout(deviceContext->handle, report, EXTENDED_PACKET_SIZE, STANDARD_TIMEOUT_MILLISECONDS);
819  if (result != HID_OPERATION_READ_SUCCESS){
820  return READING_PROCESS_FAILED;
821  }
822 
823  if (report[0] != CORRECT_WRITE_FLASH_REPLY) {
824  return WRONG_ANSWER;
825  }
826 
827  errorCode = report[1];
828  if (errorCode != OK) {
829  return errorCode;
830  }
831 
832  if (bytesLeftToWrite > MAX_FLASH_WRITE_PAYLOAD) {
833  bytesLeftToWrite -= MAX_FLASH_WRITE_PAYLOAD;
834  absoluteOffset += MAX_FLASH_WRITE_PAYLOAD;
835  } else
836  bytesLeftToWrite = 0;
837  }
838 
839  return errorCode;
840 }
841 
842 int resetDevice(uintptr_t* deviceContextPtr)
843 {
844  unsigned char report[EXTENDED_PACKET_SIZE];
845  int result = -1;
846 
847  result = _verifyDeviceContextByPtr(deviceContextPtr);
848  if (result != OK)
849  return result;
850 
851  report[0] = ZERO_REPORT_ID;
852  report[1] = RESET_REQUEST;
853 
854  result = _writeOnlyFunction(report, deviceContextPtr);
855  return result;
856 }
857 
858 int detachDevice(uintptr_t* deviceContextPtr)
859 {
860  unsigned char report[EXTENDED_PACKET_SIZE];
861  int result;
862 
863  result = _verifyDeviceContextByPtr(deviceContextPtr);
864  if (result != OK)
865  return result;
866 
867  report[0] = ZERO_REPORT_ID;
868  report[1] = DETACH_REQUEST;
869 
870  result = _writeOnlyFunction(report, deviceContextPtr);
871  return result;
872 }
int disconnectDeviceContext(uintptr_t *deviceContextPtr)
Free a device handle.
Definition: libspectr.c:33
LIBSHARED_AND_STATIC_EXPORT uint32_t getDevicesCount()
Returns the number of the connected devices.
Definition: libspectr.c:163
int getFrame(uint16_t *framePixelsBuffer, uint16_t numOfFrame, uintptr_t *deviceContextPtr)
Gets frame.
Definition: libspectr.c:525
int eraseFlash(uintptr_t *deviceContextPtr)
Erases user flash memory.
Definition: libspectr.c:649
int getAcquisitionParameters(uint16_t *numOfScans, uint16_t *numOfBlankScans, uint8_t *scanMode, uint32_t *timeOfExposure, uintptr_t *deviceContextPtr)
Returns the same values as set by setAcquisitionParameters.
Definition: libspectr.c:448
int setFrameFormat(uint16_t numOfStartElement, uint16_t numOfEndElement, uint8_t reductionMode, uint16_t *numOfPixelsInFrame, uintptr_t *deviceContextPtr)
Sets frame parameters Note: this function clears the memory and stops the current acquisition...
Definition: libspectr.c:224
int setExposure(uint32_t timeOfExposure, uint8_t force, uintptr_t *deviceContextPtr)
Sets exposure parameter.
Definition: libspectr.c:262
int triggerAcquisition(uintptr_t *deviceContextPtr)
Start acquisition by software.
Definition: libspectr.c:404
int clearMemory(uintptr_t *deviceContextPtr)
Clears memory.
Definition: libspectr.c:627
int connectToDeviceByIndex(unsigned int index, uintptr_t *deviceContextPtr)
Connects to the required device by index This function or its analog connectToSingleDeviceBySerial sh...
Definition: libspectr.c:100
int connectToDeviceBySerial(const char *const serialNumber, uintptr_t *deviceContextPtr)
Finds the requested device by the provided serial number and connects to it. This function or its ana...
Definition: libspectr.c:53
int setExternalTrigger(uint8_t enableMode, uint8_t signalFrontMode, uintptr_t *deviceContextPtr)
Sets the external acquisition trigger.
Definition: libspectr.c:353
int getFrameFormat(uint16_t *numOfStartElement, uint16_t *numOfEndElement, uint8_t *reductionMode, uint16_t *numOfPixelsInFrame, uintptr_t *deviceContextPtr)
Returns the same values as set by setFrameFormat.
Definition: libspectr.c:484
int setMultipleParameters(uint16_t numOfScans, uint16_t numOfBlankScans, uint8_t scanMode, uint32_t timeOfExposure, uint8_t enableMode, uint8_t signalFrontMode, uintptr_t *deviceContextPtr)
Sets multiple parameters - combination of setAcquisitionParametersOnSingleDevice and setExternalTrigg...
Definition: libspectr.c:320
int readFlash(uint8_t *buffer, uint32_t absoluteOffset, uint32_t bytesToRead, uintptr_t *deviceContextPtr)
Reads from user flash memory Reads bytesToRead from user flash memory starting at offset and copies t...
Definition: libspectr.c:671
int getStatus(uint8_t *statusFlags, uint16_t *framesInMemory, uintptr_t *deviceContextPtr)
Gets the device status.
Definition: libspectr.c:420
int detachDevice(uintptr_t *deviceContextPtr)
Disconnects the device The device will be disconnected from USB, and any interaction with it will not...
Definition: libspectr.c:858
int resetDevice(uintptr_t *deviceContextPtr)
Resets all the device parameters to their default values and clears the memory.
Definition: libspectr.c:842
LIBSHARED_AND_STATIC_EXPORT DeviceInfo_t * getDevicesInfo()
Obtains the list of all connected devices. Run clearDevicesInfo() with the result of this function to...
Definition: libspectr.c:178
LIBSHARED_AND_STATIC_EXPORT void clearDevicesInfo(DeviceInfo_t *devices)
Clears the list of all connected devices obtained by getDevicesInfo() function.
Definition: libspectr.c:218
int setOpticalTrigger(uint8_t enableMode, uint16_t pixel, uint16_t threshold, uintptr_t *deviceContextPtr)
Sets the optical atrigger.
Definition: libspectr.c:377
int setAcquisitionParameters(uint16_t numOfScans, uint16_t numOfBlankScans, uint8_t scanMode, uint32_t timeOfExposure, uintptr_t *deviceContextPtr)
Sets acquisition parameters.
Definition: libspectr.c:289
int writeFlash(uint8_t *buffer, uint32_t absoluteOffset, uint32_t bytesToWrite, uintptr_t *deviceContextPtr)
Writes bytesToWrite bytes from the buffer to the user flash memory starting at offset.
Definition: libspectr.c:771