void usb_RequestError(void) { usb_bdt[USB_CALC_BD(0, USB_DIR_OUT, USB_PP_EVEN)].BDCNT = USB_EP0_BUFFER_SIZE; //usb_bdt[USB_CALC_BD(0, USB_DIR_OUT, USB_PP_ODD)].BDCNT = USB_EP0_BUFFER_SIZE; usb_bdt[USB_CALC_BD(0, USB_DIR_IN, USB_PP_EVEN)].BDSTAT = UOWN + BSTALL; usb_bdt[USB_CALC_BD(0, USB_DIR_OUT, USB_PP_EVEN)].BDSTAT = UOWN + BSTALL; //usb_bdt[USB_CALC_BD(0, USB_DIR_IN, USB_PP_ODD)].BDSTAT = UOWN + BSTALL; //usb_bdt[USB_CALC_BD(0, USB_DIR_OUT, USB_PP_ODD)].BDSTAT = UOWN + BSTALL; // JTR TODO: Should also kill the IN and OUT handlers? }
void user_configured_init(void) { // JTR NEW FUNCTION // After the device is enumerated and configured then we set up non EP0 endpoints. // We only enable the endpoints we are using, not all of them. // Prior to this they are held in a disarmed state. // This function belongs to the current USB function and IS NOT generic. This is CLASS specific // and will vary from implementation to implementation. usb_unset_in_handler(1); usb_unset_in_handler(2); usb_unset_out_handler(2); USB_UEP1 = USB_EP_IN; USB_UEP2 = USB_EP_INOUT; /* Configure buffer descriptors */ #if USB_PP_BUF_MODE == 0 // JTR Setup CDC LINE_NOTICE EP (Interrupt IN) usb_bdt[USB_CALC_BD(1, USB_DIR_IN, USB_PP_EVEN)].BDCNT = 0; usb_bdt[USB_CALC_BD(1, USB_DIR_IN, USB_PP_EVEN)].BDADDR = cdc_acm_in_buffer; usb_bdt[USB_CALC_BD(1, USB_DIR_IN, USB_PP_EVEN)].BDSTAT = DTS + DTSEN; // Set DTS => First packet inverts, ie. is Data0 #else // TODO: Implement Ping-Pong buffering setup. #error "PP Mode not implemented yet" #endif usb_register_class_setup_handler(cdc_setup); cdc_trf_state = 0; CDC_Outbdp = &usb_bdt[USB_CALC_BD(2, USB_DIR_OUT, USB_PP_EVEN)]; CDC_Inbdp = &usb_bdt[USB_CALC_BD(2, USB_DIR_IN, USB_PP_EVEN)]; IsInBufferA = 0xFF; InPtr = cdc_In_bufferA; cdc_In_len = 0; CDC_Inbdp->BDADDR = &cdc_In_bufferA[0]; CDC_Inbdp->BDCNT = 0; CDC_Inbdp->BDSTAT = DTS + DTSEN; cdc_Out_len = 0; IsOutBufferA = 0xFF; OutPtr = cdc_Out_bufferA; CDC_Outbdp->BDCNT = CDC_BUFFER_SIZE; CDC_Outbdp->BDADDR = &cdc_Out_bufferA[0]; CDC_Outbdp->BDSTAT = UOWN + DTSEN; }
void ClearUSBtoDefault(void) { int i; sof_handler = NULL; class_setup_handler = NULL; vendor_setup_handler = NULL; SetUsbAddress(0); // After reset we don't have an address ResetPPbuffers(); ClearAllUsbErrorInterruptFlags(); for (i = 0; i < MAX_CHIP_EP; i++) { endpoints[i].out_handler = NULL; endpoints[i].in_handler = NULL; USB_UEP[i] = 0; } for (i = 0; i < (2 + 2 * MAX_EPNUM_USED); i++) { usb_bdt[i].BDSTAT = 0; } USB_UEP0 = USB_EP_CONTROL; // Configure Only ep0 At this point. //usbrequesterrorflag = 0; #ifdef USB_SELF_POWERED // JTR TODO this isn't actually 100% correct. "usb_device_status" is a runtime variable // In the case of a bus powered device it will always be 0x000 but in the case of // self powered with bus powered option it becames variable to the current powered // State. This is a minor thing and for now but it may need to be addressed if there is // any hardware that is dual powered. usb_device_status = 0x0001; #else usb_device_status = 0x0000; #endif usb_device_state = DETACHED_STATE; // JTR added flag byte for enumeration state usb_current_cfg = 0; // JTR formally usb_configured usb_addr_pending = 0x00; #if USB_PP_BUF_MODE == NO_PINGPONG usb_bdt[USB_CALC_BD(0, USB_DIR_OUT, USB_PP_EVEN)].BDCNT = USB_EP0_BUFFER_SIZE; // JTR endpoints[0].buffer_size; same thing done more obviously usb_bdt[USB_CALC_BD(0, USB_DIR_OUT, USB_PP_EVEN)].BDADDR = usb_ep0_out_buf; //endpoints[0].out_buffer; usb_bdt[USB_CALC_BD(0, USB_DIR_OUT, USB_PP_EVEN)].BDSTAT = UOWN + DTSEN; usb_bdt[USB_CALC_BD(0, USB_DIR_IN, USB_PP_EVEN)].BDCNT = 0; usb_bdt[USB_CALC_BD(0, USB_DIR_IN, USB_PP_EVEN)].BDADDR = usb_ep0_in_buf; //endpoints[0].in_buffer; usb_bdt[USB_CALC_BD(0, USB_DIR_IN, USB_PP_EVEN)].BDSTAT = DTS + DTSEN; // Set DTS => First packet inverts, ie. is Data0 #else #error "Invalid PING_PONG mode" #endif }
void usb_init(ROMPTR const unsigned char *device_descriptor, ROMPTR const unsigned char *config_descriptor, ROMPTR const unsigned char *string_descriptor, int num_string_descriptors) { int i; usb_device_descriptor = device_descriptor; usb_config_descriptor = config_descriptor; usb_string_descriptor = string_descriptor; usb_num_string_descriptors = num_string_descriptors; SetUsbAddress(0); // JTR added here. Probably not required though ResetPPbuffers(); DisableUsbInterrupts(); DisableAllUsbInterrupts(); ClearAllUsbErrorInterruptFlags(); ClearAllUsbInterruptFlags(); ConfigureUsbHardware(); sof_handler = NULL; class_setup_handler = NULL; vendor_setup_handler = NULL; for (i = 0; i < MAX_CHIP_EP; i++) { endpoints[i].out_handler = NULL; endpoints[i].in_handler = NULL; } // Register ep0 - no handlers usb_unset_in_handler(0); usb_unset_out_handler(0); // JTR All UEPx SPRs are hard coded. I cannot see much point of tables or indexing for these. // On the PIC16C765 such indexing was required for the STALL bit but now the STALL feature // is in the Buffer descriptor table not in the UEPx SPRs. // See changes to "USB_REQUEST_GET_STATUS" // USB_UEP[0] = endpoints[0].type; USB_UEP0 = USB_EP_CONTROL; /* Configure endpoints TODO: Only ep0 ? */ // JTR Right! code for other end points snipped...At this point we are only setting up EP0 #ifdef USB_SELF_POWERED usb_device_status = 0x0001; #else usb_device_status = 0x0000; #endif usb_device_state = 0x00; // JTR added flag byte for enumeration state usb_current_cfg = 0; // JTR formally usb_configured usb_addr_pending = 0x00; #if USB_PP_BUF_MODE == 0 usb_bdt[USB_CALC_BD(0, USB_DIR_OUT, USB_PP_EVEN)].BDCNT = USB_EP0_BUFFER_SIZE; // JTR endpoints[0].buffer_size; same thing done more obviously usb_bdt[USB_CALC_BD(0, USB_DIR_OUT, USB_PP_EVEN)].BDADDR = usb_ep0_out_buf; //endpoints[0].out_buffer; usb_bdt[USB_CALC_BD(0, USB_DIR_OUT, USB_PP_EVEN)].BDSTAT = UOWN + DTSEN; usb_bdt[USB_CALC_BD(0, USB_DIR_IN, USB_PP_EVEN)].BDCNT = 0; usb_bdt[USB_CALC_BD(0, USB_DIR_IN, USB_PP_EVEN)].BDADDR = usb_ep0_in_buf; //endpoints[0].in_buffer; usb_bdt[USB_CALC_BD(0, USB_DIR_IN, USB_PP_EVEN)].BDSTAT = DTS; // Set DTS => First packet inverts, ie. is Data0 #else // TODO: Implement Ping-Pong buffering setup. #error "PP Mode not implemented yet" #endif }
void usb_handle_StandardEndpointRequest(BDentry *bdp) { unsigned char *packet; unsigned char epnum; unsigned char dir; BDentry *epbd; packet = bdp->BDADDR; switch (packet[USB_bRequest]) { case USB_REQUEST_GET_STATUS: rbdp->BDADDR[0] = 0x00; // Assume no stall rbdp->BDADDR[1] = 0x00; // Same for stall or not epnum = packet[USB_wIndex] & 0x0F; dir = packet[USB_wIndex] >> 7; epbd = &usb_bdt[USB_CALC_BD(epnum, dir, USB_PP_EVEN)]; if (epbd->BDSTAT &= ~BSTALL) rbdp->BDADDR[0] = 0x01; // EVEN BD is stall flag set? epbd = &usb_bdt[USB_CALC_BD(epnum, dir, USB_PP_ODD)]; if (epbd->BDSTAT &= ~BSTALL) rbdp->BDADDR[0] = 0x01; // ODD BD is stall flag set? usb_ack_dat1(rbdp, 2); // JTR common addition for STD and CLASS ACK break; case USB_REQUEST_CLEAR_FEATURE: epnum = packet[USB_wIndex] & 0x0F; dir = packet[USB_wIndex] >> 7; epbd = &usb_bdt[USB_CALC_BD(epnum, dir, USB_PP_EVEN)]; epbd->BDSTAT &= ~BSTALL; if (dir) epbd->BDSTAT |= DTS; // JTR added IN EP set DTS as it will be toggled to zero next transfer if (0 == dir) epbd->BDSTAT &= ~DTS; // JTR added // JTR this pointless ATM. If ping-pong is enabled then you need to track PPBI // and set up ODD and EVEN BDs in respect to this. See complicated system in // microchip stack >= 2.8 // epbd = &usb_bdt[USB_CALC_BD(epnum, dir, USB_PP_ODD)]; // epbd->BDSTAT &= ~BSTALL; // if (dir) epbd->BDSTAT |= DTS; // JTR added // if (0 == dir) epbd->BDSTAT &= ~DTS; // JTR added usb_ack_dat1(rbdp, 0); // JTR common addition for STD and CLASS ACK // rbdp->BDCNT = 0; // rbdp->BDSTAT = UOWN + DTS + DTSEN; break; case USB_REQUEST_SET_FEATURE: epnum = packet[USB_wIndex] & 0x0F; dir = packet[USB_wIndex] >> 7; epbd = &usb_bdt[USB_CALC_BD(epnum, dir, USB_PP_EVEN)]; epbd->BDSTAT |= BSTALL; epbd = &usb_bdt[USB_CALC_BD(epnum, dir, USB_PP_ODD)]; epbd->BDSTAT |= BSTALL; usb_ack_dat1(rbdp, 0); // JTR common addition for STD and CLASS ACK // rbdp->BDCNT = 0; // rbdp->BDSTAT = UOWN + DTS + DTSEN; break; case USB_REQUEST_SYNCH_FRAME: default: usb_RequestError(); } }
void usb_handle_reset(void) { int i; mLedToggle(); #ifdef USB_SELF_POWERED // JTR see note about this in usb_init() usb_device_status = 0x0001; #else usb_device_status = 0x0000; #endif do { ClearUsbInterruptFlag(USB_TRN); // JTR corrected Must poll TRN Flag and clear, then wait 6 cycles. for next flag set. usb_current_cfg = 0; usb_device_state = 0x00; // This creates the requied 6 cycle delay for TRNF to reassert. usb_addr_pending = 0x00; } while (USB_TRANSACTION_FLAG); // for (i=0; i < MAX_CHIP_EP; i++ ) // JTR this loop seems to work proving that the USB_UEP ptr is now correct. // { // USB_UEP[i] = 0; // JTR Char on PIC18 and int ptr on PIC24 // } USB_UEP0 = 0; // Disable all endpoints USB_UEP1 = 0; USB_UEP2 = 0; USB_UEP3 = 0; USB_UEP4 = 0; USB_UEP5 = 0; USB_UEP6 = 0; USB_UEP7 = 0; #if MAX_CHIP_EP > 8 // JTR alteration USB_UEP8 = 0; USB_UEP9 = 0; USB_UEP10 = 0; USB_UEP11 = 0; USB_UEP12 = 0; USB_UEP13 = 0; USB_UEP14 = 0; USB_UEP15 = 0; #endif SetUsbAddress(0); // After reset we don't have an address ClearAllUsbInterruptFlags(); ClearAllUsbErrorInterruptFlags(); // JTR added. Clear all BD STAT registers so that they are owned by the CPU and it is safe to change them. for (i = 0; i < (2 + 2 * MAX_EPNUM_USED); i += 4) { usb_bdt[i].BDSTAT = 0; } // USB_UEP[0] = endpoints[0].type; // JTR removed all such indexing on UEPx USB_UEP0 = USB_EP_CONTROL; // JTR hard coded instead. /* Configure buffer descriptors */ #if USB_PP_BUF_MODE == 0 usb_bdt[USB_CALC_BD(0, USB_DIR_OUT, USB_PP_EVEN)].BDCNT = USB_EP0_BUFFER_SIZE; //endpoints[0].buffer_size; usb_bdt[USB_CALC_BD(0, USB_DIR_OUT, USB_PP_EVEN)].BDADDR = usb_ep0_out_buf; //endpoints[0].out_buffer; usb_bdt[USB_CALC_BD(0, USB_DIR_OUT, USB_PP_EVEN)].BDSTAT = UOWN + DTSEN; usb_bdt[USB_CALC_BD(0, USB_DIR_IN, USB_PP_EVEN)].BDCNT = 0; usb_bdt[USB_CALC_BD(0, USB_DIR_IN, USB_PP_EVEN)].BDADDR = usb_ep0_in_buf; //endpoints[0].in_buffer; usb_bdt[USB_CALC_BD(0, USB_DIR_IN, USB_PP_EVEN)].BDSTAT = DTS; // Set DTS => First packet inverts, ie. is Data0 #else // TODO: Implement Ping-Pong buffering setup. #error "PP Mode not implemented yet" #endif EnablePacketTransfer(); }
void usb_handle_StandardEndpointRequest(BDentry *bdp) { BYTE *packet; BYTE epnum; BYTE dir; BDentry *epbd; usb_uep_t *pUEP; packet = bdp->BDADDR; switch (packet[USB_bRequest]) { case USB_REQUEST_GET_STATUS: EP0_Inbdp->BDADDR[0] = 0x00; // Assume no stall EP0_Inbdp->BDADDR[1] = 0x00; // Same for stall or not epnum = packet[USB_wIndex] & 0x0F; dir = packet[USB_wIndex] >> 7; epbd = &usb_bdt[USB_CALC_BD(epnum, dir, USB_PP_EVEN)]; if (epbd->BDSTAT &= ~BSTALL) EP0_Inbdp->BDADDR[0] = 0x01; // EVEN BD is stall flag set? //epbd = &usb_bdt[USB_CALC_BD(epnum, dir, USB_PP_ODD)]; //if (epbd->BDSTAT &= ~BSTALL) // rbdp->BDADDR[0] = 0x01; // ODD BD is stall flag set? usb_ack_dat1(2); break; case USB_REQUEST_CLEAR_FEATURE: // As this is really is an application event and there // should be a call back and protocol for handling the // possible lost of a data packet. // TODO: ping-ping support. epnum = packet[USB_wIndex] & 0x0F; // JTR Added V0.2 after microchip stuff up with their documentation. pUEP = USB_UEP; pUEP += epnum; *pUEP &= ~USB_UEP_EPSTALL; dir = packet[USB_wIndex] >> 7; epbd = &usb_bdt[USB_CALC_BD(epnum, dir, USB_PP_EVEN)]; epbd->BDSTAT &= ~BSTALL; if (dir) epbd->BDSTAT |= DTS; // JTR added IN EP set DTS as it will be toggled to zero next transfer if (0 == dir) epbd->BDSTAT &= ~DTS; // JTR added // JTR this pointless ATM. If ping-pong is enabled then you need to track PPBI // and set up ODD and EVEN BDs in respect to this. See complicated system in // microchip stack >= 2.8 // epbd = &usb_bdt[USB_CALC_BD(epnum, dir, USB_PP_ODD)]; // epbd->BDSTAT &= ~BSTALL; // if (dir) epbd->BDSTAT |= DTS; // JTR added // if (0 == dir) epbd->BDSTAT &= ~DTS; // JTR added usb_ack_dat1(0); break; case USB_REQUEST_SET_FEATURE: epnum = packet[USB_wIndex] & 0x0F; dir = packet[USB_wIndex] >> 7; epbd = &usb_bdt[USB_CALC_BD(epnum, dir, USB_PP_EVEN)]; epbd->BDSTAT |= BSTALL; //epbd = &usb_bdt[USB_CALC_BD(epnum, dir, USB_PP_ODD)]; //epbd->BDSTAT |= BSTALL; usb_ack_dat1(0); break; case USB_REQUEST_SYNCH_FRAME: default: usb_RequestError(); } }
void user_configured_init(void) { // JTR NEW FUNCTION // After the device is enumerated and configured then we set up non EP0 endpoints. // We only enable the endpoints we are using, not all of them. // Prior to this they are held in a disarmed state. // This function belongs to the current USB function and IS NOT generic. This is CLASS specific // and will vary from implementation to implementation. usb_unset_in_handler(1); usb_unset_in_handler(2); usb_unset_out_handler(2); // JTR Macro has bug fix // JTR remove all USB_UEP[x] indexing from stack due to pointer bug (fixed?). // JTR experiment is the UEPx pointer system working? Lets try! // PASSED on PIC24 //USB_UEP[1] = USB_EP_IN; //USB_UEP[2] = USB_EP_INOUT; USB_UEP1 = USB_EP_IN; USB_UEP2 = USB_EP_INOUT; /* Configure buffer descriptors */ #if USB_PP_BUF_MODE == 0 // JTR Setup CDC LINE_NOTICE EP (Interrupt IN) usb_bdt[USB_CALC_BD(1, USB_DIR_IN, USB_PP_EVEN)].BDCNT = 0; usb_bdt[USB_CALC_BD(1, USB_DIR_IN, USB_PP_EVEN)].BDADDR = cdc_acm_in_buffer; usb_bdt[USB_CALC_BD(1, USB_DIR_IN, USB_PP_EVEN)].BDSTAT = DTS + DTSEN; // Set DTS => First packet inverts, ie. is Data0 usb_bdt[USB_CALC_BD(2, USB_DIR_OUT, USB_PP_EVEN)].BDCNT = CDC_BUFFER_SIZE; // JTR N/A endpoints[i].buffer_size; usb_bdt[USB_CALC_BD(2, USB_DIR_OUT, USB_PP_EVEN)].BDADDR = cdc_Out_buffer; usb_bdt[USB_CALC_BD(2, USB_DIR_OUT, USB_PP_EVEN)].BDSTAT = UOWN + DTSEN; usb_bdt[USB_CALC_BD(2, USB_DIR_IN, USB_PP_EVEN)].BDCNT = 0; usb_bdt[USB_CALC_BD(2, USB_DIR_IN, USB_PP_EVEN)].BDADDR = cdc_In_buffer; usb_bdt[USB_CALC_BD(2, USB_DIR_IN, USB_PP_EVEN)].BDSTAT = DTS + DTSEN; // Set DTS => First packet inverts, ie. is Data0 #else // TODO: Implement Ping-Pong buffering setup. #error "PP Mode not implemented yet" #endif usb_register_class_setup_handler(cdc_setup); Outbdp = &usb_bdt[USB_CALC_BD(2, USB_DIR_OUT, USB_PP_EVEN)]; Inbdp = &usb_bdt[USB_CALC_BD(2, USB_DIR_IN, USB_PP_EVEN)]; }