1 /* 2 * Ben NanoNote and Arduino USB Host shield communication. 3 * 4 * Copyright 2013 Paul Boddie 5 * 6 * SPI functions derived from those in lib/atben.c by Werner Almesberger: 7 * 8 * Copyright 2010-2011 Werner Almesberger 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; either version 2 of the License, or 13 * (at your option) any later version. 14 */ 15 16 #include <ubb/ubb.h> 17 #include <stdio.h> 18 #include <signal.h> 19 #include <stdlib.h> 20 #include <usb.h> 21 #include <unistd.h> 22 23 /* Found in Python's asdl.h. */ 24 25 #ifndef __cplusplus 26 typedef enum {false, true} bool; 27 #endif 28 29 /* Initialisation states. */ 30 31 typedef enum 32 { 33 MAX_DEVSTATE_INIT = 0, 34 MAX_DEVSTATE_CONNECTED = 1, 35 MAX_DEVSTATE_RESET = 2, 36 MAX_DEVSTATE_READY = 3 37 } max_devstate; 38 39 /* Pin assignments: 40 * 41 * Sniffer UBB Shield 42 * ------- ---- ------ 43 * DAT2 DAT2 9 (INT) 44 * CD DAT3 10 (SS) 45 * CMD CMD 7 (RESET) 46 * VCC VDD VIN 47 * CLK CLK 13 (SCLK) 48 * GND GND GND 49 * DAT0 DAT0 11 (MOSI) 50 * DAT1 DAT1 12 (MISO) 51 * 8 (GPX) (not assigned) 52 */ 53 54 #define MAX_RESET UBB_CMD 55 #define MAX_SCLK UBB_CLK 56 #define MAX_MOSI UBB_DAT0 57 #define MAX_MISO UBB_DAT1 58 #define MAX_INT UBB_DAT2 59 #define MAX_SS UBB_DAT3 60 61 /* MAX3421E definitions. */ 62 63 #define MAX_REG_READ 0x00 64 #define MAX_REG_WRITE 0x02 65 66 #define MAX_REG_RCVFIFO 1 67 #define MAX_REG_SNDFIFO 2 68 #define MAX_REG_SUDFIFO 4 69 #define MAX_REG_RCVBC 6 70 #define MAX_REG_SNDBC 7 71 #define MAX_REG_USBIRQ 13 72 #define MAX_REG_USBIEN 14 73 #define MAX_REG_USBCTL 15 74 #define MAX_REG_CPUCTL 16 75 #define MAX_REG_PINCTL 17 76 #define MAX_REG_REVISION 18 77 #define MAX_REG_HIRQ 25 78 #define MAX_REG_HIEN 26 79 #define MAX_REG_MODE 27 80 #define MAX_REG_PERADDR 28 81 #define MAX_REG_HCTL 29 82 #define MAX_REG_HXFR 30 83 #define MAX_REG_HRSL 31 84 85 #define MAX_USBIRQ_OSCOKIRQ 1 86 #define MAX_USBIRQ_NOVBUSIRQ 32 87 #define MAX_USBIRQ_VBUSIRQ 64 88 89 #define MAX_USBCTL_PWRDOWN 16 90 #define MAX_USBCTL_CHIPRES 32 91 92 #define MAX_CPUCTL_IE 1 93 94 #define MAX_PINCTL_POSINT_LOW 0 95 #define MAX_PINCTL_POSINT_HIGH 4 96 #define MAX_PINCTL_INTLEVEL_EDGE 0 97 #define MAX_PINCTL_INTLEVEL_LEVEL 8 98 #define MAX_PINCTL_FDUPSPI_HALF 0 99 #define MAX_PINCTL_FDUPSPI_FULL 16 100 101 #define MAX_HIRQ_BUSEVENTIRQ 1 102 #define MAX_HIRQ_RWUIRQ 2 103 #define MAX_HIRQ_RCVDAVIRQ 4 104 #define MAX_HIRQ_SNDBAVIRQ 8 105 #define MAX_HIRQ_SUSDNIRQ 16 106 #define MAX_HIRQ_CONDETIRQ 32 107 #define MAX_HIRQ_FRAMEIRQ 64 108 #define MAX_HIRQ_HXFRDNIRQ 128 109 110 #define MAX_HIEN_BUSEVENTIE 1 111 #define MAX_HIEN_CONDETIE 32 112 #define MAX_HIEN_FRAMEIE 64 113 114 #define MAX_MODE_PERIPHERAL 0 115 #define MAX_MODE_HOST 1 116 #define MAX_MODE_LOWSPEED 2 117 #define MAX_MODE_SOFKAENAB 8 118 #define MAX_MODE_SEPIRQ_OFF 0 119 #define MAX_MODE_SEPIRQ_ON 16 120 #define MAX_MODE_DMPULLDN 64 121 #define MAX_MODE_DPPULLDN 128 122 123 #define MAX_MODE_HOST_ENABLED MAX_MODE_HOST | MAX_MODE_SEPIRQ_OFF | MAX_MODE_DMPULLDN | MAX_MODE_DPPULLDN 124 #define MAX_MODE_HOST_FULLSPEED MAX_MODE_HOST_ENABLED 125 #define MAX_MODE_HOST_LOWSPEED MAX_MODE_HOST_ENABLED | MAX_MODE_LOWSPEED 126 127 #define MAX_HCTL_BUSRST 1 128 #define MAX_HCTL_SAMPLEBUS 4 129 #define MAX_HCTL_RCVTOG0 16 130 #define MAX_HCTL_RCVTOG1 32 131 #define MAX_HCTL_SNDTOG0 64 132 #define MAX_HCTL_SNDTOG1 128 133 134 #define MAX_HXFR_SETUP 16 135 #define MAX_HXFR_OUTNIN 32 136 #define MAX_HXFR_HS 128 137 138 #define MAX_HRSL_JSTATUS 128 139 #define MAX_HRSL_KSTATUS 64 140 #define MAX_HRSL_SNDTOGRD 32 141 #define MAX_HRSL_RCVTOGRD 16 142 #define MAX_HRSL_HRSLT 15 143 144 #define max_reg(n) ((uint8_t) (n << 3)) 145 #define max_reg_read(n) (max_reg(n) | MAX_REG_READ) 146 #define max_reg_write(n) (max_reg(n) | MAX_REG_WRITE) 147 148 void spi_begin() 149 { 150 CLR(MAX_SS); 151 } 152 153 void spi_end() 154 { 155 SET(MAX_SS); 156 } 157 158 /** 159 * Send the given value via MOSI while receiving a value via MISO. 160 * This requires full-duplex SPI and will produce a status value for the first 161 * value sent (the command). 162 */ 163 uint8_t spi_sendrecv(uint8_t v) 164 { 165 uint8_t result = 0; 166 uint8_t mask; 167 168 for (mask = 0x80; mask; mask >>= 1) 169 { 170 if (v & mask) 171 { 172 #ifdef DEBUG 173 printf("1"); 174 #endif 175 SET(MAX_MOSI); 176 } 177 else 178 { 179 #ifdef DEBUG 180 printf("0"); 181 #endif 182 CLR(MAX_MOSI); 183 } 184 185 /* Wait for stable output signal. */ 186 187 SET(MAX_SCLK); 188 189 if (PIN(MAX_MISO)) 190 result |= mask; 191 192 CLR(MAX_SCLK); 193 } 194 195 #ifdef DEBUG 196 printf("\n"); 197 #endif 198 return result; 199 } 200 201 uint8_t max_read(uint8_t reg, uint8_t *status) 202 { 203 uint8_t result = 0, tmpstatus = 0; 204 205 tmpstatus = 0; 206 207 spi_begin(); 208 tmpstatus = spi_sendrecv(max_reg_read(reg)); 209 result = spi_sendrecv(0); 210 spi_end(); 211 212 if (status != NULL) 213 *status = tmpstatus; 214 215 return result; 216 } 217 218 uint8_t max_write(uint8_t reg, uint8_t value) 219 { 220 uint8_t status = 0; 221 222 spi_begin(); 223 status = spi_sendrecv(max_reg_write(reg)); 224 spi_sendrecv(value); 225 spi_end(); 226 227 return status; 228 } 229 230 /** 231 * Return whether data can be sent. 232 */ 233 bool max_can_send(uint8_t *status) 234 { 235 if (status == NULL) 236 return max_read(MAX_REG_HIRQ, NULL) & MAX_HIRQ_SNDBAVIRQ; 237 else 238 return *status & MAX_HIRQ_SNDBAVIRQ; 239 } 240 241 /** 242 * Set the sending data toggle. 243 */ 244 void max_set_send_toggle(bool toggle) 245 { 246 max_write(MAX_REG_HCTL, toggle ? MAX_HCTL_SNDTOG1 : MAX_HCTL_SNDTOG0); 247 } 248 249 /** 250 * Return the sending data toggle. 251 */ 252 bool max_get_send_toggle() 253 { 254 return (max_read(MAX_REG_HRSL, NULL) & MAX_HRSL_SNDTOGRD) != 0; 255 } 256 257 /** 258 * Set the receiving data toggle. 259 */ 260 void max_set_recv_toggle(bool toggle) 261 { 262 max_write(MAX_REG_HCTL, toggle ? MAX_HCTL_RCVTOG1 : MAX_HCTL_RCVTOG0); 263 } 264 265 /** 266 * Return the receiving data toggle. 267 */ 268 bool max_get_recv_toggle() 269 { 270 return (max_read(MAX_REG_HRSL, NULL) & MAX_HRSL_RCVTOGRD) != 0; 271 } 272 273 /** 274 * Wait for handshake/timeout after a transfer. 275 */ 276 uint8_t max_wait_transfer(uint8_t status) 277 { 278 while (!(status & MAX_HIRQ_HXFRDNIRQ)) 279 { 280 status = max_read(MAX_REG_HIRQ, NULL); 281 } 282 283 return status; 284 } 285 286 /** 287 * Write the given data to the FIFO. 288 */ 289 void max_write_fifo(uint8_t endpoint, uint8_t *data, uint8_t len) 290 { 291 uint8_t count; 292 293 for (count = 0; count < len; count++) 294 { 295 max_write(endpoint ? MAX_REG_SNDFIFO : MAX_REG_SUDFIFO, data[count]); 296 } 297 298 if (endpoint) 299 max_write(MAX_REG_SNDBC, len); 300 } 301 302 /** 303 * Read the data from the FIFO. 304 */ 305 void max_read_fifo(uint8_t *data, uint8_t *len, uint8_t *datalimit) 306 { 307 uint8_t count, received = max_read(MAX_REG_RCVBC, NULL); 308 309 *len += received; 310 311 for (count = 0; (count < received) && (data < datalimit); count++) 312 { 313 *data++ = max_read(MAX_REG_RCVFIFO, NULL); 314 } 315 } 316 317 /** 318 * Send a control request to the given address consisting of the given setup 319 * data. 320 */ 321 uint8_t max_control(uint8_t address, uint8_t *setup) 322 { 323 uint8_t status, hrsl; 324 325 max_write_fifo(0, setup, 8); 326 327 /* Set the address. */ 328 329 max_write(MAX_REG_PERADDR, address); 330 331 /* Initiate the transfer. */ 332 333 do 334 { 335 status = max_write(MAX_REG_HXFR, MAX_HXFR_SETUP); 336 status = max_wait_transfer(status); 337 hrsl = max_read(MAX_REG_HRSL, &status); 338 } 339 while (hrsl & MAX_HRSL_HRSLT); 340 341 return status; 342 } 343 344 /** 345 * Perform a status transaction as part of a larger control transaction. 346 * The out parameter is used to indicate the kind of status transfer to be 347 * performed and should be the inverse of the control transfer direction. 348 */ 349 uint8_t max_control_status(bool out) 350 { 351 uint8_t status, hrsl; 352 353 do 354 { 355 status = max_write(MAX_REG_HXFR, MAX_HXFR_HS | (out ? MAX_HXFR_OUTNIN : 0)); 356 status = max_wait_transfer(status); 357 hrsl = max_read(MAX_REG_HRSL, &status); 358 } 359 while (hrsl & MAX_HRSL_HRSLT); 360 361 return status; 362 } 363 364 /** 365 * Send a request to the given address and endpoint, using the supplied data 366 * payload with the given length, indicating the preserved toggle state of the 367 * endpoint (which will be updated). 368 */ 369 uint8_t max_send(uint8_t address, uint8_t endpoint, uint8_t *data, uint8_t len, bool *toggle) 370 { 371 uint8_t status, hrsl = 0; 372 373 max_write_fifo(endpoint, data, len); 374 375 if (endpoint) 376 max_set_send_toggle(*toggle); 377 378 /* Set the address. */ 379 380 max_write(MAX_REG_PERADDR, address); 381 382 /* Initiate the transfer. */ 383 384 do 385 { 386 status = max_write(MAX_REG_HXFR, endpoint | MAX_HXFR_OUTNIN); 387 status = max_wait_transfer(status); 388 389 /* Test for usable data. */ 390 391 if (!(status & MAX_HIRQ_SNDBAVIRQ)) 392 continue; 393 394 hrsl = max_read(MAX_REG_HRSL, &status); 395 } 396 while (hrsl & MAX_HRSL_HRSLT); 397 398 if (endpoint) 399 *toggle = max_get_send_toggle(); 400 401 return status; 402 } 403 404 /** 405 * Make a request for data from the given address and endpoint, collecting it in 406 * the supplied buffer with the given length, indicating the preserved toggle 407 * state of the endpoint (which will be updated) The length will be updated to 408 * indicate the total length of the received data. 409 */ 410 uint8_t max_recv(uint8_t address, uint8_t endpoint, uint8_t *data, uint8_t *len, bool *toggle) 411 { 412 uint8_t *datalimit = data + *len; 413 uint8_t status, hrsl = 0; 414 415 if (endpoint) 416 max_set_send_toggle(*toggle); 417 418 /* Set the address. */ 419 420 max_write(MAX_REG_PERADDR, address); 421 422 /* Initiate the transfer. */ 423 424 do 425 { 426 status = max_write(MAX_REG_HXFR, endpoint); 427 status = max_wait_transfer(status); 428 429 /* Test for usable data. */ 430 431 if (!(status & MAX_HIRQ_RCVDAVIRQ)) 432 continue; 433 434 hrsl = max_read(MAX_REG_HRSL, &status); 435 } 436 while (hrsl & MAX_HRSL_HRSLT); 437 438 do 439 { 440 max_read_fifo(data, len, datalimit); 441 442 /* Indicate that all data has been read. */ 443 444 status = max_write(MAX_REG_HIRQ, MAX_HIRQ_RCVDAVIRQ); 445 } 446 while (status & MAX_HIRQ_RCVDAVIRQ); 447 448 if (endpoint) 449 *toggle = max_get_send_toggle(); 450 451 return status; 452 } 453 454 void chipreset() 455 { 456 printf("Resetting...\n"); 457 max_write(MAX_REG_USBCTL, MAX_USBCTL_CHIPRES); 458 459 printf("Clearing the reset...\n"); 460 max_write(MAX_REG_USBCTL, 0); 461 } 462 463 uint8_t check() 464 { 465 uint8_t oscillator; 466 467 oscillator = max_read(MAX_REG_USBIRQ, NULL); 468 469 return (oscillator & ~(MAX_USBIRQ_NOVBUSIRQ | MAX_USBIRQ_VBUSIRQ)) == MAX_USBIRQ_OSCOKIRQ; 470 } 471 472 uint8_t wait() 473 { 474 uint16_t timeout = 1024; 475 476 /* Wait for the oscillator before performing USB activity. */ 477 478 printf("Waiting...\n"); 479 480 while ((timeout > 0) && (!check())) 481 { 482 timeout--; 483 } 484 485 printf("Iterations remaining: %d\n", timeout); 486 487 return timeout; 488 } 489 490 /** 491 * Return whether the bus is ready to be sampled. The application note claims 492 * that the SAMPLEBUS bit is cleared, but this does not seem to be the case. 493 */ 494 uint8_t samplebusready() 495 { 496 uint8_t result; 497 498 result = max_read(MAX_REG_HCTL, NULL); 499 return result & MAX_HCTL_SAMPLEBUS; 500 } 501 502 void samplebus() 503 { 504 max_write(MAX_REG_HCTL, MAX_HCTL_SAMPLEBUS); 505 while (!samplebusready()); 506 } 507 508 /** 509 * Handle the connection or disconnection of a device, returning true if the 510 * device is now connected or false otherwise. 511 */ 512 bool devicechanged() 513 { 514 uint8_t hrsl, mode; 515 516 hrsl = max_read(MAX_REG_HRSL, NULL); 517 mode = max_read(MAX_REG_MODE, NULL); 518 519 if ((hrsl & MAX_HRSL_JSTATUS) && (hrsl & MAX_HRSL_KSTATUS)) 520 { 521 printf("Bad device status.\n"); 522 } 523 else if (!(hrsl & MAX_HRSL_JSTATUS) && !(hrsl & MAX_HRSL_KSTATUS)) 524 { 525 printf("Device disconnected.\n"); 526 } 527 else 528 { 529 printf("Device connected.\n"); 530 531 /* Low speed device when J and lowspeed have the same level. 532 Since J and K should have opposing levels, K can be tested when 533 lowspeed is low. */ 534 535 if (((hrsl & MAX_HRSL_JSTATUS) && (mode & MAX_MODE_LOWSPEED)) || 536 ((hrsl & MAX_HRSL_KSTATUS) && !(mode & MAX_MODE_LOWSPEED))) 537 { 538 printf("Device is low speed.\n"); 539 max_write(MAX_REG_MODE, MAX_MODE_HOST_LOWSPEED); 540 } 541 else 542 { 543 printf("Device is full speed.\n"); 544 max_write(MAX_REG_MODE, MAX_MODE_HOST_FULLSPEED); 545 } 546 547 /* Reset the device. */ 548 549 max_write(MAX_REG_HCTL, MAX_HCTL_BUSRST); 550 return true; 551 } 552 553 return false; 554 } 555 556 void setup_packet(uint8_t *setup, uint8_t request_type, uint8_t request, uint16_t value, uint16_t index, uint16_t length) 557 { 558 setup[0] = request_type; 559 setup[1] = request; 560 setup[2] = value & 0xff; 561 setup[3] = value >> 8; 562 setup[4] = index & 0xff; 563 setup[5] = index >> 8; 564 setup[6] = length & 0xff; 565 setup[7] = length >> 8; 566 } 567 568 bool max_init_device(bool *in_toggle) 569 { 570 uint8_t data[64], len = 64, setup[8]; 571 struct usb_device_descriptor *desc; 572 573 printf("Sending control request to address 0, endpoint 0...\n"); 574 setup_packet(setup, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR, USB_DT_DEVICE, 0, USB_DT_DEVICE_SIZE); 575 max_control(0, setup); 576 max_recv(0, 0, data, &len, in_toggle); 577 max_control_status(true); 578 579 if (len >= sizeof(struct usb_device_descriptor)) 580 { 581 desc = (struct usb_device_descriptor *) data; 582 printf("bLength: %d\n", desc->bLength); 583 printf("bDescriptorType: %d\n", desc->bDescriptorType); 584 printf("bcdUSB: %d\n", desc->bcdUSB); 585 printf("bDeviceClass: %d\n", desc->bDeviceClass); 586 printf("bDeviceSubClass: %d\n", desc->bDeviceSubClass); 587 printf("bDeviceProtocol: %d\n", desc->bDeviceProtocol); 588 printf("bMaxPacketSize0: %d\n", desc->bMaxPacketSize0); 589 printf("idVendor: %x\n", desc->idVendor); 590 printf("idProduct: %x\n", desc->idProduct); 591 printf("bcdDevice: %d\n", desc->bcdDevice); 592 printf("iManufacturer: %d\n", desc->iManufacturer); 593 printf("iProduct: %d\n", desc->iProduct); 594 printf("iSerialNumber: %d\n", desc->iSerialNumber); 595 printf("bNumConfigurations: %d\n", desc->bNumConfigurations); 596 return true; 597 } 598 599 return false; 600 } 601 602 void shutdown(int signum) 603 { 604 printf("Closing...\n"); 605 ubb_close(0); 606 exit(1); 607 } 608 609 int main(int argc, char *argv[]) 610 { 611 uint8_t status = 0, revision = 0; 612 uint16_t count; 613 bool in_toggle = 0, bus_event, data_event, suspended_event, connection_event, frame_event; 614 max_devstate devstate = MAX_DEVSTATE_INIT; 615 616 signal(SIGINT, &shutdown); 617 618 if (ubb_open(0) < 0) { 619 perror("ubb_open"); 620 return 1; 621 } 622 623 ubb_power(1); 624 printf("Power on.\n"); 625 626 OUT(MAX_SS); 627 OUT(MAX_MOSI); 628 OUT(MAX_SCLK); 629 OUT(MAX_RESET); 630 IN(MAX_INT); 631 IN(MAX_MISO); 632 633 /* Initialise SPI. */ 634 /* Set SS# to 1. */ 635 636 SET(MAX_SS); 637 CLR(MAX_MOSI); 638 CLR(MAX_SCLK); 639 SET(MAX_RESET); 640 641 /* Initialise the MAX3421E. */ 642 643 /* Set full-duplex, interrupt signalling. */ 644 645 printf("Setting pin control...\n"); 646 max_write(MAX_REG_PINCTL, MAX_PINCTL_INTLEVEL_LEVEL | MAX_PINCTL_FDUPSPI_FULL); 647 648 chipreset(); 649 printf("Ready? %d\n", wait()); 650 651 /* Check various registers. */ 652 653 printf("Mode: %x\n", max_read(MAX_REG_MODE, &status)); 654 printf("IRQ: %x\n", max_read(MAX_REG_HIRQ, &status)); 655 656 /* Set host mode. */ 657 658 printf("Setting mode...\n"); 659 status = max_write(MAX_REG_MODE, MAX_MODE_HOST_ENABLED); 660 661 printf("Setting INT signalling...\n"); 662 status = max_write(MAX_REG_CPUCTL, MAX_CPUCTL_IE); 663 664 printf("Setting event signalling...\n"); 665 status = max_write(MAX_REG_HIEN, MAX_HIEN_CONDETIE | MAX_HIEN_FRAMEIE | MAX_HIEN_BUSEVENTIE); 666 667 /* Check various registers. */ 668 669 printf("Mode: %x\n", max_read(MAX_REG_MODE, &status)); 670 printf("IRQ: %x\n", max_read(MAX_REG_HIRQ, &status)); 671 printf("IE: %x\n", max_read(MAX_REG_HIEN, &status)); 672 printf("CPU: %x\n", max_read(MAX_REG_CPUCTL, &status)); 673 printf("Pin: %x\n", max_read(MAX_REG_PINCTL, &status)); 674 printf("USBIRQ: %x\n", max_read(MAX_REG_USBIRQ, &status)); 675 printf("USBIE: %x\n", max_read(MAX_REG_USBIEN, &status)); 676 677 /* Read from the REVISION register. */ 678 679 printf("Reading...\n"); 680 revision = max_read(MAX_REG_REVISION, &status); 681 printf("Revision = %x\n", revision); 682 683 /* Sample the bus for any devices that are already connected. */ 684 685 samplebus(); 686 687 if (devicechanged()) 688 { 689 devstate = MAX_DEVSTATE_CONNECTED; 690 } 691 692 /* Enter the main processing loop. */ 693 694 for (count = 0; count <= 65535; count++) 695 { 696 if (!PIN(MAX_INT)) 697 { 698 status = max_read(MAX_REG_HIRQ, NULL); 699 700 if ((bus_event = status & MAX_HIRQ_BUSEVENTIRQ)) 701 printf("Bus "); 702 if ((data_event = status & MAX_HIRQ_RCVDAVIRQ)) 703 printf("Data "); 704 if ((suspended_event = status & MAX_HIRQ_SUSDNIRQ)) 705 printf("Suspended "); 706 if ((connection_event = status & MAX_HIRQ_CONDETIRQ)) 707 printf("Connection "); 708 frame_event = status & MAX_HIRQ_FRAMEIRQ; 709 printf("\n"); 710 711 max_write(MAX_REG_HIRQ, status); 712 713 /* Detect device connection/disconnection. */ 714 715 if ((devstate == MAX_DEVSTATE_INIT) && connection_event && devicechanged()) 716 { 717 devstate = MAX_DEVSTATE_CONNECTED; 718 } 719 720 /* Handle device reset initiation. */ 721 722 else if ((devstate == MAX_DEVSTATE_CONNECTED) && bus_event) 723 { 724 max_write(MAX_REG_MODE, max_read(MAX_REG_MODE, NULL) | MAX_MODE_SOFKAENAB); 725 devstate = MAX_DEVSTATE_RESET; 726 } 727 728 /* Handle device reset completion, initiating communications. */ 729 730 else if ((devstate == MAX_DEVSTATE_RESET) && frame_event && max_can_send(&status)) 731 { 732 max_init_device(&in_toggle); 733 devstate = MAX_DEVSTATE_READY; 734 max_write(MAX_REG_MODE, max_read(MAX_REG_MODE, NULL) & ~MAX_MODE_SOFKAENAB); 735 } 736 737 /* Handle device disconnection. */ 738 739 else if ((devstate != MAX_DEVSTATE_INIT) && connection_event) 740 { 741 devstate = MAX_DEVSTATE_INIT; 742 } 743 } 744 } 745 746 printf("Closing...\n"); 747 ubb_close(0); 748 749 return 0; 750 }