/* Send the next transaction containing data from the medium to the host. */ static int8_t send_next_data_transaction(struct msc_application_data *msc) { const uint8_t *cur = msc->tx_buf; const uint16_t len = msc->tx_len_remaining; if (!usb_is_configured() || usb_in_endpoint_busy(msc->in_endpoint)) return -1; if (len > 0) { /* There is data to send; send one packet worth. */ uint8_t *buf; uint16_t to_copy; buf = usb_get_in_buffer(msc->in_endpoint); to_copy = MIN(len, msc->in_endpoint_size); memcpy(buf, cur, to_copy); usb_send_in_buffer(msc->in_endpoint, to_copy); msc->transferred_bytes += to_copy; msc->tx_buf += to_copy; msc->tx_len_remaining -= to_copy; } else { /* Transfer of block has completed */ msc->operation_complete_callback(msc, true); msc->operation_complete_callback = NULL; msc->tx_buf = NULL; } return 0; }
int main(void) { OSCCONbits.IRCF = 0b1111; // 0b1111 = 16MHz HFINTOSC postscaler ANSELA = 0x00; // digital I/O on PORTA ANSELB = 0x00; // digital I/O on PORTB ANSELC = 0x00; // digital I/O on PORTC APFCON = 0x00; // a little bit of voodoo MODE_SW_TRIS = PIN_OUTPUT; MODE_SW = POTENTIOSTATIC; // initialize mode to potentiostatic CELL_ON_TRIS = PIN_OUTPUT; CELL_ON_PIN = CELL_OFF; // initialize cell to off position TRISC = 0x00; // all outputs on PORTC LATC = RANGE1; // initialize range to range 1 // Enable Active clock-tuning from the USB ACTCONbits.ACTSRC = 1; // 1=USB ACTCONbits.ACTEN = 1; // Configure interrupts INTCONbits.PEIE = 1; INTCONbits.GIE = 1; // Initialize USB usb_init(); while (1) { if (usb_is_configured() && usb_out_endpoint_has_data(1)) // wait for data received from host { if (!usb_in_endpoint_halted(1)) { while (usb_in_endpoint_busy(1)) // wait for EP1 IN to become free ; received_data_length = usb_get_out_buffer(1, &received_data); transmit_data = usb_get_in_buffer(1); interpret_command(); // this reads received_data and sets transmit_data and transmit_data_length usb_send_in_buffer(1, transmit_data_length); // send the data back } usb_arm_out_endpoint(1); } } return 0; }
USBSerial::operator bool() { return usb_is_connected(USBLIB) && usb_is_configured(USBLIB) && usb_cdcacm_get_dtr(); }
int main(void) { hardware_init(); luke_init(); #ifdef MULTI_CLASS_DEVICE hid_set_interface_list(hid_interfaces, sizeof (hid_interfaces)); #endif usb_init(); uint8_t regAddr = 0; while (1) { if (usb_is_configured() && usb_out_endpoint_has_data(1)) { // uint8_t len; const unsigned char *RxDataBuffer; unsigned char *TxDataBuffer = usb_get_in_buffer(1); /* Data received from host */ if (!usb_in_endpoint_halted(1)) { /* Wait for EP 1 IN to become free then send. This of * course only works using interrupts. */ while (usb_in_endpoint_busy(1)) ; usb_get_out_buffer(1, &RxDataBuffer); uint8_t pcktVer = RxDataBuffer[0] & 0xC0; uint8_t pcktLen = RxDataBuffer[0] & 0x2F; if (pcktVer == PROTOCOL_VERSION && pcktLen > 1) { uint8_t opcode = RxDataBuffer[1]; TxDataBuffer[1] = opcode; // echo back operation code ATTID id = (RxDataBuffer[2] << 8) + RxDataBuffer[3]; uint8_t len; switch (opcode) { case OP_ATT_VALUE_GET: TxDataBuffer[2] = RC_OK; // Return OK code TxDataBuffer[0] = PROTOCOL_VERSION; switch (id) { case ATT_PRODUCT_NAME: len = strlen(PRODUCT_NAME) + 1; // +1 for NULL TxDataBuffer[0] |= len + 3; // packet length memcpy(&TxDataBuffer[3], PRODUCT_NAME, len); break; case ATT_PRODUCT_REVISION: TxDataBuffer[0] |= 2 + 3; // packet length TxDataBuffer[3] = '0' + PORTCbits.RC2; TxDataBuffer[4] = NULL; break; case ATT_PRODUCT_SERIAL: /* TxDataBuffer[0] |= NVM_PRODUCT_SERIAL_SIZE + 3; // packet length for (uint8_t i=0; i<NVM_PRODUCT_SERIAL_SIZE; i++) { // Please note that 1 word of HEF is 14bits but lower 8bits is high-endurance TxDataBuffer[i+3] = (uint8_t) FLASH_ReadWord(NVM_PRODUCT_SERIAL_ADDR + i); } */ TxDataBuffer[0] |= NVM_PRODUCT_SERIAL_SIZE + 3; // packet length memcpy(&TxDataBuffer[3], NVM_PRODUCT_SERIAL_ADDR, NVM_PRODUCT_SERIAL_SIZE); break; case ATT_FIRM_VERSION: len = strlen(FIRM_VERSION) + 1; // +1 for NULL TxDataBuffer[0] |= len + 3; // packet length memcpy(&TxDataBuffer[3], FIRM_VERSION, len); break; case ATT_I2C0_RW_2BYTE: TxDataBuffer[0] |= 2 + 3; // packet length uint16_t dat = i2c_reg_read(regAddr); TxDataBuffer[4] = dat >> 8; TxDataBuffer[3] = dat; break; case ATT_VOLTAGE: TxDataBuffer[0] |= 4 + 3; // packet length float volt = get_voltage(); TxDataBuffer[3] = 0x00; memcpy(&TxDataBuffer[4], &volt, 3); break; case ATT_CURRENT: TxDataBuffer[0] |= 4 + 3; // packet length float curr = get_current(); TxDataBuffer[3] = 0x00; memcpy(&TxDataBuffer[4], &curr, 3); break; default: TxDataBuffer[0] |= 3; // packet length TxDataBuffer[2] = RC_FAIL; // Return error code break; } // end of switch (id) break; case OP_ATT_VALUE_SET: TxDataBuffer[0] = PROTOCOL_VERSION | 3; // packet length TxDataBuffer[2] = RC_OK; // Return OK code switch (id) { case ATT_I2C0_REG_ADDR: regAddr = RxDataBuffer[4]; break; case ATT_I2C0_RW_2BYTE: i2c_reg_write(regAddr, RxDataBuffer[5], RxDataBuffer[4]); break; default: TxDataBuffer[2] = RC_FAIL; // Return error code break; } // end of switch (id) break; default: TxDataBuffer[0] = PROTOCOL_VERSION | 3; // packet length TxDataBuffer[2] = RC_FAIL; // Return error code break; } // switch (opcode) // Send response memcpy(usb_get_in_buffer(1), TxDataBuffer, EP_1_IN_LEN); usb_send_in_buffer(1, EP_1_IN_LEN); } // end of if (pcktVer == PROTOCOL_VERSION && pcktLen > 1) } usb_arm_out_endpoint(1); } #ifndef USB_USE_INTERRUPTS usb_service(); #endif }
int main(void) { #if defined(__PIC24FJ64GB002__) || defined(__PIC24FJ256DA206__) unsigned int pll_startup_counter = 600; CLKDIVbits.PLLEN = 1; while(pll_startup_counter--); #elif _18F46J50 unsigned int pll_startup = 600; OSCTUNEbits.PLLEN = 1; while (pll_startup--) ; #elif _16F1459 || _16F1454 OSCCONbits.IRCF = 0b1111; /* 0b1111 = 16MHz HFINTOSC postscalar */ /* Enable Active clock-tuning from the USB */ ACTCONbits.ACTSRC = 1; /* 1=USB */ ACTCONbits.ACTEN = 1; #elif __32MX460F512L__ SYSTEMConfigPerformance(80000000); #endif /* Configure interrupts, per architecture */ #ifdef USB_USE_INTERRUPTS #if defined (_PIC18) || defined(_PIC14E) INTCONbits.PEIE = 1; INTCONbits.GIE = 1; #elif __PIC32MX__ INTCONbits.MVEC = 1; /* Multi-vector interrupts */ IPC11bits.USBIP = 4; /* Interrupt priority, must set to != 0. */ __asm volatile("ei"); #endif #endif #ifdef MULTI_CLASS_DEVICE hid_set_interface_list(hid_interfaces, sizeof(hid_interfaces)); #endif usb_init(); /* Setup mouse movement. This implementation sends back data for every * IN packet, but sends no movement for all but every delay-th frame. * Adjusting delay will slow down or speed up the movement, which is * also dependent upon the rate at which the host sends IN packets, * which varies between implementations. * * In real life, you wouldn't want to send back data that hadn't * changed, but since there's no real hardware to poll, and since this * example is about showing the HID class, and not about creative ways * to do timing, we send back data every frame. The interested reader * may want to modify it to use the start-of-frame callback for * timing. */ uint8_t x_delay = 14; uint8_t x_count = 100; int8_t x_direc = 1; uint8_t y_delay = 14; uint8_t y_count = 25; int8_t y_direc = 1; while (1) { if (usb_is_configured() && !usb_in_endpoint_halted(1) && !usb_in_endpoint_busy(1)) { /* Interface 1: Move mouse Left and Right. This * interface only has an X axis. */ unsigned char *buf = usb_get_in_buffer(1); buf[0] = 0x0; buf[1] = (--x_delay)? 0: x_direc; buf[2] = 0; /* Don't move Y */ usb_send_in_buffer(1, 3); if (x_delay == 0) { if (--x_count == 0) { x_count = 100; x_direc *= -1; } x_delay = 14; } } if (usb_is_configured() && !usb_in_endpoint_halted(2) && !usb_in_endpoint_busy(2)) { /* Interface 2: Move mouse up and Down. This * interface only has a Y axis. */ unsigned char *buf = usb_get_in_buffer(2); buf[0] = 0x0; buf[1] = 0; /* Don't move X */ buf[2] = (--y_delay)? 0: y_direc; buf[3] = 0; /* Don't move Z */ usb_send_in_buffer(2, 4); if (y_delay == 0) { if (--y_count == 0) { y_count = 25; y_direc *= -1; } y_delay = 14; } } #ifndef USB_USE_INTERRUPTS usb_service(); #endif } return 0; }
int main(void) { hardware_init(); #ifdef MULTI_CLASS_DEVICE hid_set_interface_list(hid_interfaces, sizeof(hid_interfaces)); #endif usb_init(); /* Setup mouse movement. This implementation sends back data for every * IN packet, but sends no movement for all but every delay-th frame. * Adjusting delay will slow down or speed up the movement, which is * also dependent upon the rate at which the host sends IN packets, * which varies between implementations. * * In real life, you wouldn't want to send back data that hadn't * changed, but since there's no real hardware to poll, and since this * example is about showing the HID class, and not about creative ways * to do timing, we send back data every frame. The interested reader * may want to modify it to use the start-of-frame callback for * timing. */ uint8_t x_delay = 14; uint8_t x_count = 100; int8_t x_direc = 1; uint8_t y_delay = 14; uint8_t y_count = 25; int8_t y_direc = 1; while (1) { if (usb_is_configured() && !usb_in_endpoint_halted(1) && !usb_in_endpoint_busy(1)) { /* Interface 1: Move mouse Left and Right. This * interface only has an X axis. */ unsigned char *buf = usb_get_in_buffer(1); buf[0] = 0x0; buf[1] = (--x_delay)? 0: x_direc; buf[2] = 0; /* Don't move Y */ usb_send_in_buffer(1, 3); if (x_delay == 0) { if (--x_count == 0) { x_count = 100; x_direc *= -1; } x_delay = 14; } } if (usb_is_configured() && !usb_in_endpoint_halted(2) && !usb_in_endpoint_busy(2)) { /* Interface 2: Move mouse up and Down. This * interface only has a Y axis. */ unsigned char *buf = usb_get_in_buffer(2); buf[0] = 0x0; buf[1] = 0; /* Don't move X */ buf[2] = (--y_delay)? 0: y_direc; buf[3] = 0; /* Don't move Z */ usb_send_in_buffer(2, 4); if (y_delay == 0) { if (--y_count == 0) { y_count = 25; y_direc *= -1; } y_delay = 14; } } #ifndef USB_USE_INTERRUPTS usb_service(); #endif } return 0; }
int main(void) { hardware_init(); #ifdef MULTI_CLASS_DEVICE cdc_set_interface_list(cdc_interfaces, sizeof(cdc_interfaces)); #endif usb_init(); uint8_t char_to_send = 'A'; bool send = true; bool loopback = false; while (1) { /* Send data to the PC */ if (usb_is_configured() && !usb_in_endpoint_halted(2) && !usb_in_endpoint_busy(2) && send) { int i; unsigned char *buf = usb_get_in_buffer(2); for (i = 0; i < 16; i++) { buf[i] = char_to_send++; if (char_to_send > 'Z') char_to_send = 'A'; } buf[i++] = '\r'; buf[i++] = '\n'; usb_send_in_buffer(2, i); } /* Handle data received from the host */ if (usb_is_configured() && !usb_out_endpoint_halted(2) && usb_out_endpoint_has_data(2)) { const unsigned char *out_buf; size_t out_buf_len; int i; /* Check for an empty transaction. */ out_buf_len = usb_get_out_buffer(2, &out_buf); if (out_buf_len <= 0) goto empty; if (send) { /* Stop sendng if a key was hit. */ send = false; send_string_sync(2, "Data send off ('h' for help)\r\n"); } else if (loopback) { /* Loop data back to the PC */ /* Wait until the IN endpoint can accept it */ while (usb_in_endpoint_busy(2)) ; /* Copy contents of OUT buffer to IN buffer * and send back to host. */ memcpy(usb_get_in_buffer(2), out_buf, out_buf_len); usb_send_in_buffer(2, out_buf_len); /* Send a zero-length packet if the transaction * length was the same as the endpoint * length. This is for demo purposes. In real * life, you only need to do this if the data * you're transferring ends on a multiple of * the endpoint length. */ if (out_buf_len == EP_2_LEN) { /* Wait until the IN endpoint can accept it */ while (usb_in_endpoint_busy(2)) ; usb_send_in_buffer(2, 0); } /* Scan for ~ character to end loopback mode */ for (i = 0; i < out_buf_len; i++) { if (out_buf[i] == '~') { loopback = false; send_string_sync(2, "\r\nLoopback off ('h' for help)\r\n"); break; } } } else { /* Scan for commands if not in loopback or * send mode. * * This is a hack. One should really scan the * entire string. In this case, since this * is a demo, assume that the user is using * a terminal program and typing the input, * all but ensuring the data will come in * single-character transactions. */ if (out_buf[0] == 'h' || out_buf[0] == '?') { /* Show help. * Make sure to not try to send more * than 63 bytes of data in one * transaction */ send_string_sync(2, "\r\nHelp:\r\n" "\ts: send data\r\n" "\tl: loopback\r\n"); send_string_sync(2, "\tn: send notification\r\n" "\th: help\r\n"); } else if (out_buf[0] == 's') send = true; else if (out_buf[0] == 'l') { loopback = true; send_string_sync(2, "loopback enabled; press ~ to disable\r\n"); } else if (out_buf[0] == 'n') { /* Send a Notification on Endpoint 1 */ struct cdc_serial_state_notification *n = (struct cdc_serial_state_notification *) usb_get_in_buffer(1); n->header.REQUEST.bmRequestType = 0xa1; n->header.bNotification = CDC_SERIAL_STATE; n->header.wValue = 0; n->header.wIndex = 1; /* Interface */ n->header.wLength = 2; n->data.serial_state = 0; /* Zero the whole bit mask */ n->data.bits.bRxCarrier = 1; n->data.bits.bTxCarrier = 1; n->data.bits.bBreak = 0; n->data.bits.bRingSignal = 0; n->data.bits.bFraming = 0; n->data.bits.bParity = 0; n->data.bits.bOverrun = 0; /* Wait for the endpoint to be free */ while (usb_in_endpoint_busy(1)) ; /* Send to to host */ usb_send_in_buffer(1, sizeof(*n)); send_string_sync(2, "Notification Sent\r\n"); } } empty: usb_arm_out_endpoint(2); } #ifndef USB_USE_INTERRUPTS usb_service(); #endif } return 0; }
int main(void) { #if defined(__PIC24FJ64GB002__) || defined(__PIC24FJ256DA206__) unsigned int pll_startup_counter = 600; CLKDIVbits.PLLEN = 1; while(pll_startup_counter--); #elif _18F46J50 unsigned int pll_startup = 600; OSCTUNEbits.PLLEN = 1; while (pll_startup--) ; #elif _16F1459 OSCCONbits.IRCF = 0b1111; /* 0b1111 = 16MHz HFINTOSC postscalar */ /* Enable Active clock-tuning from the USB */ ACTCONbits.ACTSRC = 1; /* 1=USB */ ACTCONbits.ACTEN = 1; #elif __32MX460F512L__ SYSTEMConfigPerformance(80000000); #endif /* Configure interrupts, per architecture */ #ifdef USB_USE_INTERRUPTS #if defined (_PIC18) || defined(_PIC14E) INTCONbits.PEIE = 1; INTCONbits.GIE = 1; #elif __PIC32MX__ INTCONbits.MVEC = 1; /* Multi-vector interrupts */ IPC11bits.USBIP = 4; /* Interrupt priority, must set to != 0. */ __asm volatile("ei"); #endif #endif usb_init(); unsigned char *buf = usb_get_in_buffer(1); memset(buf, 0xa0, EP_1_IN_LEN); while (1) { if (usb_is_configured() && usb_out_endpoint_has_data(1)) { uint8_t len; const unsigned char *data; /* Data received from host */ if (!usb_in_endpoint_halted(1)) { /* Wait for EP 1 IN to become free then send. This of * course only works using interrupts. */ while (usb_in_endpoint_busy(1)) ; len = usb_get_out_buffer(1, &data); memcpy(usb_get_in_buffer(1), data, EP_1_IN_LEN); usb_send_in_buffer(1, len); } usb_arm_out_endpoint(1); } #ifndef USB_USE_INTERRUPTS usb_service(); #endif } return 0; }
uint8 USBMidi::isConnected(void) { return usb_is_connected(USBLIB) && usb_is_configured(USBLIB); }