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