Little-Wire
 All Classes Functions Groups Pages
littleWire.c
1 /*
2  Cross platform computer interface library for Little Wire project
3 
4  http://littlewire.github.io
5 
6  Copyright (C) <2013> ihsan Kehribar <ihsan@kehribar.me>
7  Copyright (C) <2013> Omer Kilic <omerkilic@gmail.com>
8 
9  Permission is hereby granted, free of charge, to any person obtaining a copy of
10  this software and associated documentation files (the "Software"), to deal in
11  the Software without restriction, including without limitation the rights to
12  use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
13  of the Software, and to permit persons to whom the Software is furnished to do
14  so, subject to the following conditions:
15 
16  The above copyright notice and this permission notice shall be included in all
17  copies or substantial portions of the Software.
18 
19  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25  SOFTWARE.
26 */
27 
28 /******************************************************************************
29 * See the littleWire.h for the function descriptions/comments
30 /*****************************************************************************/
31 #include "littleWire.h"
32 
33 unsigned char crc8;
34 int LastDiscrepancy;
35 int LastFamilyDiscrepancy;
36 int LastDeviceFlag;
37 
38 /******************************************************************************
39 / Taken from: http://www.maxim-ic.com/appnotes.cfm/appnote_number/187
40 /*****************************************************************************/
41 static unsigned char dscrc_table[] = {
42  0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65,
43  157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220,
44  35,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98,
45  190,224, 2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255,
46  70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89, 7,
47  219,133,103, 57,186,228, 6, 88, 25, 71,165,251,120, 38,196,154,
48  101, 59,217,135, 4, 90,184,230,167,249, 27, 69,198,152,122, 36,
49  248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91, 5,231,185,
50  140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205,
51  17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80,
52  175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238,
53  50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115,
54  202,148,118, 40,171,245, 23, 73, 8, 86,180,234,105, 55,213,139,
55  87, 9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22,
56  233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168,
57  116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53};
58 /*****************************************************************************/
59 
61 {
62  struct usb_bus *bus;
63  struct usb_device *dev;
64 
65  usb_init();
66  usb_find_busses();
67  usb_find_devices();
68 
69  lw_totalDevices = 0;
70 
71  for (bus = usb_busses; bus; bus = bus->next)
72  {
73  for (dev = bus->devices; dev; dev = dev->next)
74  {
75  usb_dev_handle *udev;
76  char description[256];
77  char string[256];
78  int ret, i;
79 
80  if((dev->descriptor.idVendor == VENDOR_ID) && (dev->descriptor.idProduct == PRODUCT_ID))
81  {
82  udev = usb_open(dev);
83  if (udev)
84  {
85  if (dev->descriptor.iSerialNumber)
86  {
87  ret = usb_get_string_simple(udev, dev->descriptor.iSerialNumber, string, sizeof(string));
88  if (ret > 0)
89  {
90  lwResults[lw_totalDevices].serialNumber = atoi(string);
91  lwResults[lw_totalDevices].lw_device = dev;
92  }
93  }
94  usb_close(udev);
95  lw_totalDevices++;
96  }
97  }
98  }
99  }
100 
101  return lw_totalDevices;
102 }
103 
104 littleWire* littlewire_connect_byID(int desiredID)
105 {
106  littleWire *tempHandle = NULL;
107 
108  if(desiredID > (lw_totalDevices-1))
109  {
110  return tempHandle;
111  }
112 
113  tempHandle = usb_open(lwResults[desiredID].lw_device);
114 
115  return tempHandle;
116 }
117 
118 littleWire* littlewire_connect_bySerialNum(int mySerial)
119 {
120  littleWire *tempHandle = NULL;
121  int temp_id = 0xDEAF;
122  int i;
123 
124  for(i=0;i<lw_totalDevices;i++)
125  {
126  if(lwResults[i].serialNumber == mySerial)
127  {
128  temp_id = i;
129  }
130  }
131 
132  tempHandle = littlewire_connect_byID(temp_id);
133  return tempHandle;
134 }
135 
136 littleWire* littleWire_connect()
137 {
138  littleWire *tempHandle = NULL;
139 
140  usb_init();
141  usbOpenDevice(&tempHandle, VENDOR_ID, "*", PRODUCT_ID, "*", "*", NULL, NULL );
142 
143  return tempHandle;
144 }
145 
146 unsigned char readFirmwareVersion(littleWire* lwHandle)
147 {
148  lwStatus=usb_control_msg(lwHandle, 0xC0, 34, 0, 0, rxBuffer, 8, USB_TIMEOUT);
149 
150  return rxBuffer[0];
151 }
152 
153 void changeSerialNumber(littleWire* lwHandle,int serialNumber)
154 {
155  char serBuf[4];
156 
157  if(serialNumber > 999)
158  {
159  serialNumber = 999;
160  }
161  else if(serialNumber < 100)
162  {
163  serialNumber = 100;
164  }
165 
166  sprintf(serBuf,"%d",serialNumber);
167 
168  lwStatus=usb_control_msg(lwHandle, 0xC0, 55, (serBuf[1]<<8)|serBuf[0],serBuf[2], rxBuffer, 8, USB_TIMEOUT);
169 }
170 
171 void digitalWrite(littleWire* lwHandle, unsigned char pin, unsigned char state)
172 {
173  if(state){
174  lwStatus=usb_control_msg(lwHandle, 0xC0, 18, pin, 0, rxBuffer, 8, USB_TIMEOUT);
175  } else{
176  lwStatus=usb_control_msg(lwHandle, 0xC0, 19, pin, 0, rxBuffer, 8, USB_TIMEOUT);
177  }
178 }
179 
180 void pinMode(littleWire* lwHandle, unsigned char pin, unsigned char mode)
181 {
182  if(mode){
183  lwStatus=usb_control_msg(lwHandle, 0xC0, 13, pin, 0, rxBuffer, 8, USB_TIMEOUT);
184  } else {
185  lwStatus=usb_control_msg(lwHandle, 0xC0, 14, pin, 0, rxBuffer, 8, USB_TIMEOUT);
186  }
187 }
188 
189 unsigned char digitalRead(littleWire* lwHandle, unsigned char pin)
190 {
191  lwStatus=usb_control_msg(lwHandle, 0xC0, 20, pin, 0, rxBuffer, 8, USB_TIMEOUT);
192 
193  return rxBuffer[0];
194 }
195 
196 void internalPullup(littleWire* lwHandle, unsigned char pin, unsigned char state)
197 {
198  if(state){
199  lwStatus=usb_control_msg(lwHandle, 0xC0, 18, pin, 0, rxBuffer, 8, USB_TIMEOUT);
200  } else{
201  lwStatus=usb_control_msg(lwHandle, 0xC0, 19, pin, 0, rxBuffer, 8, USB_TIMEOUT);
202  }
203 }
204 
205 void analog_init(littleWire* lwHandle, unsigned char voltageRef)
206 {
207  lwStatus=usb_control_msg(lwHandle, 0xC0, 35, (voltageRef<<8) | 0x07, 0, rxBuffer, 8, USB_TIMEOUT);
208 }
209 
210 unsigned int analogRead(littleWire* lwHandle, unsigned char channel)
211 {
212  lwStatus=usb_control_msg(lwHandle, 0xC0, 15, channel, 0, rxBuffer, 8, USB_TIMEOUT);
213 
214  return ((rxBuffer[1] *256) + (rxBuffer[0]));
215 }
216 
217 void pwm_init(littleWire* lwHandle)
218 {
219  lwStatus=usb_control_msg(lwHandle, 0xC0, 16, 0, 0, rxBuffer, 8, USB_TIMEOUT);
220 }
221 
222 void pwm_stop(littleWire* lwHandle)
223 {
224  lwStatus=usb_control_msg(lwHandle, 0xC0, 32, 0, 0, rxBuffer, 8, USB_TIMEOUT);
225 }
226 
227 void pwm_updateCompare(littleWire* lwHandle, unsigned char channelA, unsigned char channelB)
228 {
229  lwStatus=usb_control_msg(lwHandle, 0xC0, 17, channelA, channelB, rxBuffer, 8, USB_TIMEOUT);
230 }
231 
232 void pwm_updatePrescaler(littleWire* lwHandle, unsigned int value)
233 {
234  switch(value)
235  {
236  case 1024:
237  lwStatus=usb_control_msg(lwHandle, 0xC0, 22, 4, 0, rxBuffer, 8, USB_TIMEOUT);
238  break;
239  case 256:
240  lwStatus=usb_control_msg(lwHandle, 0xC0, 22, 3, 0, rxBuffer, 8, USB_TIMEOUT);
241  break;
242  case 64:
243  lwStatus=usb_control_msg(lwHandle, 0xC0, 22, 2, 0, rxBuffer, 8, USB_TIMEOUT);
244  break;
245  case 8:
246  lwStatus=usb_control_msg(lwHandle, 0xC0, 22, 1, 0, rxBuffer, 8, USB_TIMEOUT);
247  break;
248  case 1:
249  lwStatus=usb_control_msg(lwHandle, 0xC0, 22, 0, 0, rxBuffer, 8, USB_TIMEOUT);
250  break;
251  }
252 }
253 
254 void spi_init(littleWire* lwHandle)
255 {
256  lwStatus=usb_control_msg(lwHandle, 0xC0, 23, 0, 0, rxBuffer, 8, USB_TIMEOUT);
257 }
258 
259 void spi_sendMessage(littleWire* lwHandle, unsigned char * sendBuffer, unsigned char * inputBuffer, unsigned char length ,unsigned char mode)
260 {
261  int i=0;
262  if(length>4)
263  length=4;
264  lwStatus=usb_control_msg(lwHandle, 0xC0, (0xF0 + length + (mode<<3) ), (sendBuffer[1]<<8) + sendBuffer[0] , (sendBuffer[3]<<8) + sendBuffer[2], rxBuffer, 8, USB_TIMEOUT);
265  lwStatus=usb_control_msg(lwHandle, 0xC0, 40, 0, 0, rxBuffer, 8, USB_TIMEOUT);
266  for(i=0;i<length;i++)
267  inputBuffer[i]=rxBuffer[i];
268 }
269 
270 unsigned char debugSpi(littleWire* lwHandle, unsigned char message)
271 {
272  lwStatus=usb_control_msg(lwHandle, 0xC0, 33, 0, 0, rxBuffer, 8, USB_TIMEOUT);
273  lwStatus=usb_control_msg(lwHandle, 0xC0, 40, 0, 0, rxBuffer, 8, USB_TIMEOUT);
274  return rxBuffer[0];
275 }
276 
277 void spi_updateDelay(littleWire* lwHandle, unsigned int duration)
278 {
279  lwStatus=usb_control_msg(lwHandle, 0xC0, 31, duration, 0, rxBuffer, 8, USB_TIMEOUT);
280 }
281 
282 void i2c_init(littleWire* lwHandle)
283 {
284  lwStatus=usb_control_msg(lwHandle, 0xC0, 44, 0, 0, rxBuffer, 8, USB_TIMEOUT);
285 }
286 
287 unsigned char i2c_start(littleWire* lwHandle, unsigned char address7bit, unsigned char direction)
288 {
289  unsigned char temp;
290 
291  temp = (address7bit << 1) | direction;
292 
293  lwStatus=usb_control_msg(lwHandle, 0xC0, 45, temp, 0, rxBuffer, 8, USB_TIMEOUT);
294  lwStatus=usb_control_msg(lwHandle, 0xC0, 40, 0, 0, rxBuffer, 8, USB_TIMEOUT);
295  return !rxBuffer[0];
296 }
297 
298 void i2c_write(littleWire* lwHandle, unsigned char* sendBuffer, unsigned char length, unsigned char endWithStop)
299 {
300  lwStatus=usb_control_msg(lwHandle, 0xC0, (0xE0 + length + (endWithStop<<3) ), (sendBuffer[1]<<8) + sendBuffer[0] , (sendBuffer[3]<<8) + sendBuffer[2], rxBuffer, 8, USB_TIMEOUT);
301 }
302 
303 void i2c_read(littleWire* lwHandle, unsigned char* readBuffer, unsigned char length, unsigned char endWithStop)
304 {
305  int i=0;
306 
307  if(endWithStop)
308  lwStatus=usb_control_msg(lwHandle, 0xC0, 46, (length<<8) + 1, 1, rxBuffer, 8, USB_TIMEOUT);
309  else
310  lwStatus=usb_control_msg(lwHandle, 0xC0, 46, (length<<8) + 0, 0, rxBuffer, 8, USB_TIMEOUT);
311 
312  delay(3);
313 
314  lwStatus=usb_control_msg(lwHandle, 0xC0, 40, 0, 0, rxBuffer, 8, USB_TIMEOUT);
315 
316  for(i=0;i<length;i++)
317  readBuffer[i]=rxBuffer[i];
318 }
319 
320 void i2c_updateDelay(littleWire* lwHandle, unsigned int duration)
321 {
322  lwStatus=usb_control_msg(lwHandle, 0xC0, 49, duration, 0, rxBuffer, 8, USB_TIMEOUT);
323 }
324 
325 void onewire_sendBit(littleWire* lwHandle, unsigned char bitValue)
326 {
327  lwStatus=usb_control_msg(lwHandle, 0xC0, 51, bitValue, 0, rxBuffer, 8, USB_TIMEOUT);
328 }
329 
330 void onewire_writeByte(littleWire* lwHandle, unsigned char messageToSend)
331 {
332  lwStatus=usb_control_msg(lwHandle, 0xC0, 42, messageToSend, 0, rxBuffer, 8, USB_TIMEOUT);
333  delay(3);
334 }
335 
336 unsigned char onewire_readByte(littleWire* lwHandle)
337 {
338  lwStatus=usb_control_msg(lwHandle, 0xC0, 43, 0, 0, rxBuffer, 8, USB_TIMEOUT);
339  delay(3);
340  lwStatus=usb_control_msg(lwHandle, 0xC0, 40, 0, 0, rxBuffer, 8, USB_TIMEOUT);
341  return rxBuffer[0];
342 }
343 
344 unsigned char onewire_readBit(littleWire* lwHandle)
345 {
346  lwStatus=usb_control_msg(lwHandle, 0xC0, 50, 0, 0, rxBuffer, 8, USB_TIMEOUT);
347  lwStatus=usb_control_msg(lwHandle, 0xC0, 40, 0, 0, rxBuffer, 8, USB_TIMEOUT);
348  return rxBuffer[0];
349 }
350 
351 unsigned char onewire_resetPulse(littleWire* lwHandle)
352 {
353  lwStatus=usb_control_msg(lwHandle, 0xC0, 41, 0, 0, rxBuffer, 8, USB_TIMEOUT);
354  delay(3);
355  lwStatus=usb_control_msg(lwHandle, 0xC0, 40, 0, 0, rxBuffer, 8, USB_TIMEOUT);
356  return rxBuffer[0];
357 }
358 
359 void softPWM_state(littleWire* lwHandle,unsigned char state)
360 {
361  lwStatus=usb_control_msg(lwHandle, 0xC0, 47, state, 0, rxBuffer, 8, USB_TIMEOUT);
362 }
363 
364 void softPWM_write(littleWire* lwHandle,unsigned char ch1,unsigned char ch2,unsigned char ch3)
365 {
366  lwStatus=usb_control_msg(lwHandle, 0xC0, 48, (ch2<<8) | ch1, ch3, rxBuffer, 8, USB_TIMEOUT);
367 }
368 
369 void ws2812_write(littleWire* lwHandle, unsigned char pin, unsigned char r,unsigned char g,unsigned char b)
370 {
371  lwStatus=usb_control_msg(lwHandle, 0xC0, 54, (g<<8) | pin | 0x30, (b<<8) | r, rxBuffer, 8, USB_TIMEOUT);
372 }
373 
374 void ws2812_flush(littleWire* lwHandle, unsigned char pin)
375 {
376  lwStatus=usb_control_msg(lwHandle, 0xC0, 54, pin | 0x10, 0, rxBuffer, 8, USB_TIMEOUT);
377 }
378 
379 void ws2812_preload(littleWire* lwHandle, unsigned char r,unsigned char g,unsigned char b)
380 {
381  lwStatus=usb_control_msg(lwHandle, 0xC0, 54, (g<<8) | 0x20, (b<<8) | r, rxBuffer, 8, USB_TIMEOUT);
382 }
383 
384 int customMessage(littleWire* lwHandle,unsigned char* receiveBuffer,unsigned char command,unsigned char d1,unsigned char d2, unsigned char d3, unsigned char d4)
385 {
386  int i;
387  int rc;
388  rc = lwStatus=usb_control_msg(lwHandle, 0xC0, command, (d2<<8)|d1, (d4<<8)|d3, rxBuffer, 8, USB_TIMEOUT);
389  for(i=0;i<8;i++)
390  receiveBuffer[i]=rxBuffer[i];
391  return rc;
392 }
393 
394 /******************************************************************************
395 * Do the crc8 calculation
396 * Taken from: http://www.maxim-ic.com/appnotes.cfm/appnote_number/187
397 /*****************************************************************************/
398 unsigned char docrc8(unsigned char value)
399 {
400  // See Maxim Application Note 27
401 
402  crc8 = dscrc_table[crc8 ^ value];
403 
404  return crc8;
405 }
406 
407 int onewire_nextAddress(littleWire* lwHandle)
408 {
409  int id_bit_number;
410  int last_zero, rom_byte_number, search_result;
411  int id_bit, cmp_id_bit;
412  unsigned char rom_byte_mask, search_direction;
413 
414  // initialize for search
415  id_bit_number = 1;
416  last_zero = 0;
417  rom_byte_number = 0;
418  rom_byte_mask = 1;
419  search_result = 0;
420  crc8 = 0;
421 
422  // if the last call was not the last one
423  if (!LastDeviceFlag)
424  {
425  // 1-Wire reset
426  if (!onewire_resetPulse(lwHandle))
427  {
428  // reset the search
429  LastDiscrepancy = 0;
430  LastDeviceFlag = 0;
431  LastFamilyDiscrepancy = 0;
432  return 0;
433  }
434 
435  // issue the search command
436  onewire_writeByte(lwHandle,0xF0);
437 
438  // loop to do the search
439  do
440  {
441  // read a bit and its complement
442  id_bit = onewire_readBit(lwHandle);
443  cmp_id_bit = onewire_readBit(lwHandle);
444 
445  // check for no devices on 1-wire
446  if ((id_bit == 1) && (cmp_id_bit == 1))
447  break;
448  else
449  {
450  // all devices coupled have 0 or 1
451  if (id_bit != cmp_id_bit)
452  search_direction = id_bit; // bit write value for search
453  else
454  {
455  // if this discrepancy if before the Last Discrepancy
456  // on a previous next then pick the same as last time
457  if (id_bit_number < LastDiscrepancy)
458  search_direction = ((ROM_NO[rom_byte_number] & rom_byte_mask) > 0);
459  else
460  // if equal to last pick 1, if not then pick 0
461  search_direction = (id_bit_number == LastDiscrepancy);
462 
463  // if 0 was picked then record its position in LastZero
464  if (search_direction == 0)
465  {
466  last_zero = id_bit_number;
467 
468  // check for Last discrepancy in family
469  if (last_zero < 9)
470  LastFamilyDiscrepancy = last_zero;
471  }
472  }
473 
474  // set or clear the bit in the ROM byte rom_byte_number
475  // with mask rom_byte_mask
476  if (search_direction == 1)
477  ROM_NO[rom_byte_number] |= rom_byte_mask;
478  else
479  ROM_NO[rom_byte_number] &= ~rom_byte_mask;
480 
481  // serial number search direction write bit
482  onewire_sendBit(lwHandle,search_direction);
483 
484  // increment the byte counter id_bit_number
485  // and shift the mask rom_byte_mask
486  id_bit_number++;
487  rom_byte_mask <<= 1;
488 
489  // if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask
490  if (rom_byte_mask == 0)
491  {
492  docrc8(ROM_NO[rom_byte_number]); // accumulate the CRC
493  rom_byte_number++;
494  rom_byte_mask = 1;
495  }
496  }
497  }
498  while(rom_byte_number < 8); // loop until through all ROM bytes 0-7
499 
500  // if the search was successful then
501  if (!((id_bit_number < 65) || (crc8 != 0)))
502  {
503  // search successful so set LastDiscrepancy,LastDeviceFlag,search_result
504  LastDiscrepancy = last_zero;
505 
506  // check for last device
507  if (LastDiscrepancy == 0)
508  LastDeviceFlag = 1;
509 
510  search_result = 1;
511  }
512  }
513 
514  // if no device found then reset counters so next 'search' will be like a first
515  if (!search_result || !ROM_NO[0])
516  {
517  LastDiscrepancy = 0;
518  LastDeviceFlag = 0;
519  LastFamilyDiscrepancy = 0;
520  search_result = 0;
521  }
522 
523  return search_result;
524 }
525 
526 int onewire_firstAddress(littleWire* lwHandle)
527 {
528  littleWire* temp = lwHandle;
529 
530  // reset the search state
531  LastDiscrepancy = 0;
532  LastDeviceFlag = 0;
533  LastFamilyDiscrepancy = 0;
534 
535  return onewire_nextAddress(temp);
536 }
537 
539  if (lwStatus<0) return lwStatus;
540  else return 0;
541 }
542 
544  if (lwStatus<0) switch (lwStatus) {
545  case -1: return "I/O Error"; break;
546  case -2: return "Invalid paramenter"; break;
547  case -3: return "Access error"; break;
548  case -4: return "No device"; break;
549  case -5: return "Not found"; break;
550  case -6: return "Busy"; break;
551  case -7: return "Timeout"; break;
552  case -8: return "Overflow"; break;
553  case -9: return "Pipe"; break;
554  case -10: return "Interrupted"; break;
555  case -11: return "No memory"; break;
556  case -12: return "Not supported"; break;
557  case -99: return "Other"; break;
558  default: return "unknown";
559  }
560  else return 0;
561 }