123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599 |
- #include "../dp_usb/usb_stack_globals.h"
- #if USB_EP0_BUFFER_SIZE == 8u
- #elif USB_EP0_BUFFER_SIZE == 16u
- #elif USB_EP0_BUFFER_SIZE == 32u
- #elif USB_EP0_BUFFER_SIZE == 64u
- #else
- #error "USB_EP0_BUFFER_SIZE needs to be 8, 16, 32 or 64 bytes"
- #endif
- ROMPTR const BYTE *usb_device_descriptor;
- ROMPTR const BYTE *usb_config_descriptor;
- ROMPTR const BYTE *usb_string_descriptor;
- int usb_num_string_descriptors;
- usb_handler_t sof_handler;
- usb_handler_t class_setup_handler, vendor_setup_handler;
- usb_ep_t endpoints[MAX_CHIP_EP];
- #if defined(PIC_18F)
- #pragma udata usb_bdt
- BDentry usb_bdt[2 + 2 * MAX_EPNUM_USED];
- #pragma udata usb_data
- #if USB_PP_BUF_MODE == 0
- BYTE usb_ep0_out_buf[USB_EP0_BUFFER_SIZE];
- BYTE usb_ep0_in_buf[USB_EP0_BUFFER_SIZE];
- #else
- #error "Ping pong buffer not implemented yet!"
- #endif
- #elif defined(PIC_24F)
- #pragma udata usb_bdt
- BDentry usb_bdt[2 + 2 * MAX_EPNUM_USED] __attribute__((aligned(512)));
- #if USB_PP_BUF_MODE == 0
- BYTE usb_ep0_out_buf[USB_EP0_BUFFER_SIZE];
- BYTE usb_ep0_in_buf[USB_EP0_BUFFER_SIZE];
- #else
- #error "Ping pong buffer not implemented yet!"
- #endif
- #endif
- #pragma udata
- unsigned int usb_device_status;
- unsigned int usb_current_cfg;
- volatile BYTE usb_device_state;
- BYTE usb_addr_pending;
- BYTE trn_status;
- BDentry *EP0_Outbdp, *EP0_Inbdp;
- BYTE IsSuspended = 0;
- ROMPTR const BYTE *usb_rom_ptr;
- size_t usb_rom_len;
- volatile BYTE usbrequesterrorflag;
- void usb_init(ROMPTR const BYTE *device_descriptor,
- ROMPTR const BYTE *config_descriptor,
- ROMPTR const BYTE *string_descriptor,
- int num_string_descriptors) {
- usb_device_descriptor = device_descriptor;
- usb_config_descriptor = config_descriptor;
- usb_string_descriptor = string_descriptor;
- usb_num_string_descriptors = num_string_descriptors;
- sof_handler = NULL;
- class_setup_handler = NULL;
- vendor_setup_handler = NULL;
- usb_unset_in_handler(0);
- usb_unset_out_handler(0);
- ClearUSBtoDefault();
- ConfigureUsbHardware();
- EnablePacketTransfer();
- }
- void usb_start(void) {
- EnableUsb();
- usb_device_state = ATTACHED_STATE;
- while (SingleEndedZeroIsSet());
- usb_device_state = DEFAULT_STATE;
- }
- void usb_handle_error(void) {
-
- ClearAllUsbErrorInterruptFlags();
- }
- void usb_handle_reset(void) {
- do {
- ClearUsbInterruptFlag(USB_TRN);
- usb_current_cfg = 0;
- usb_device_state = DEFAULT_STATE;
- usb_addr_pending = 0x00;
- } while (USB_TRANSACTION_FLAG);
- ClearUSBtoDefault();
- EnablePacketTransfer();
- }
- void ClearUSBtoDefault(void) {
- int i;
- sof_handler = NULL;
- class_setup_handler = NULL;
- vendor_setup_handler = NULL;
- SetUsbAddress(0);
- 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;
-
- #ifdef USB_SELF_POWERED
-
-
-
-
-
- usb_device_status = 0x0001;
- #else
- usb_device_status = 0x0000;
- #endif
- usb_device_state = DETACHED_STATE;
- usb_current_cfg = 0;
- 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;
- usb_bdt[USB_CALC_BD(0, USB_DIR_OUT, USB_PP_EVEN)].BDADDR = usb_ep0_out_buf;
- 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;
- usb_bdt[USB_CALC_BD(0, USB_DIR_IN, USB_PP_EVEN)].BDSTAT = DTS + DTSEN;
- #else
- #error "Invalid PING_PONG mode"
- #endif
- }
- void usb_handler(void) {
- if (USB_IDLE_FLAG) {
-
- USBSuspend();
- ClearUsbInterruptFlag(USB_IDLE);
- }
- if (USB_RESET_FLAG) {
- usb_handle_reset();
- ClearUsbInterruptFlag(USB_URST);
- }
- if (USB_ERROR_FLAG) {
-
- ClearAllUsbErrorInterruptFlags();
- ClearUsbInterruptFlag(USB_UERR);
- }
- if (USB_STALL_FLAG) {
- ClearUsbInterruptFlag(USB_STALL);
- }
- if (USB_SOF_FLAG) {
-
- if (sof_handler) sof_handler();
- ClearUsbInterruptFlag(USB_SOF);
- }
- if (USB_TRANSACTION_FLAG) {
- if (!USB_STAT2EP(GetUsbTransaction()))
- usb_handle_transaction();
- ClearUsbInterruptFlag(USB_TRN);
- }
- }
- void usb_handle_transaction(void) {
- usbrequesterrorflag = 0;
- trn_status = GetUsbTransaction();
- EP0_Outbdp = &usb_bdt[USB_USTAT2BD(trn_status)];
- EP0_Inbdp = &usb_bdt[USB_USTAT2BD(trn_status | DIRBIT)];
- switch (EP0_Outbdp->BDSTAT & USB_TOKEN_Mask) {
- case USB_TOKEN_SETUP:
- usb_handle_setup();
- break;
- case USB_TOKEN_OUT:
- usb_handle_out();
- break;
- case USB_TOKEN_IN:
- usb_handle_in();
- break;
-
-
- }
- }
- void usb_handle_setup(void) {
- EP0_Inbdp->BDSTAT = DTSEN;
- EnablePacketTransfer();
- switch (EP0_Outbdp->BDADDR[USB_bmRequestType] & USB_bmRequestType_TypeMask) {
- case USB_bmRequestType_Standard:
- switch (EP0_Outbdp->BDADDR[USB_bmRequestType] & USB_bmRequestType_RecipientMask) {
- case USB_bmRequestType_Device:
- usb_handle_StandardDeviceRequest(EP0_Outbdp);
- break;
- case USB_bmRequestType_Interface:
- usb_handle_StandardInterfaceRequest(EP0_Outbdp);
- break;
- case USB_bmRequestType_Endpoint:
- usb_handle_StandardEndpointRequest(EP0_Outbdp);
- break;
- default:
- usb_RequestError();
- }
- break;
- case USB_bmRequestType_Class:
- if (class_setup_handler) class_setup_handler();
- break;
- case USB_bmRequestType_Vendor:
-
-
- if (vendor_setup_handler) vendor_setup_handler();
- break;
- default:
- usb_RequestError();
- }
-
- EP0_Outbdp->BDCNT = USB_EP0_BUFFER_SIZE;
-
-
-
-
-
- EP0_Outbdp->BDSTAT = (!(EP0_Outbdp->BDADDR[USB_bmRequestType] & USB_bmRequestType_PhaseMask) &&
- (EP0_Outbdp->BDADDR[USB_wLength] || EP0_Outbdp->BDADDR[USB_wLengthHigh])) ? UOWN + DTS + DTSEN : UOWN + DTSEN;
- }
- void usb_handle_StandardDeviceRequest(BDentry *bdp) {
- BYTE *packet = bdp->BDADDR;
- int i;
- switch (packet[USB_bRequest]) {
- case USB_REQUEST_GET_STATUS:
- EP0_Inbdp->BDADDR[0] = usb_device_status & 0xFF;
- EP0_Inbdp->BDADDR[1] = usb_device_status >> 8;
- usb_ack_dat1(2);
- break;
- case USB_REQUEST_CLEAR_FEATURE:
- if (0x01u == packet[USB_wValue]) {
- usb_device_status &= ~0x0002;
- usb_ack_dat1(0);
- } else
- usb_RequestError();
- break;
- case USB_REQUEST_SET_FEATURE:
- if (0x01u == packet[USB_wValue]) {
- usb_device_status |= 0x0002;
- usb_ack_dat1(0);
- } else
- usb_RequestError();
- break;
- case USB_REQUEST_SET_ADDRESS:
- if (0x00u == packet[USB_wValueHigh] && 0x7Fu >= packet[USB_wValue]) {
- usb_addr_pending = packet[USB_wValue];
- usb_set_in_handler(0, usb_set_address);
- usb_ack_dat1(0);
- } else
- usb_RequestError();
- break;
- case USB_REQUEST_GET_DESCRIPTOR:
- switch (packet[USB_bDescriptorType]) {
- case USB_DEVICE_DESCRIPTOR_TYPE:
- usb_rom_ptr = usb_device_descriptor;
- usb_rom_len = usb_device_descriptor[0];
- if ((0 == packet[USB_wLengthHigh] && packet[USB_wLength] < usb_rom_ptr[0]))
- usb_rom_len = packet[USB_wLength];
- break;
- case USB_CONFIGURATION_DESCRIPTOR_TYPE:
- if (packet[USB_bDescriptorIndex] >= usb_device_descriptor[17]) {
- flag_usb_RequestError();
- break;
- }
- usb_rom_ptr = usb_config_descriptor;
- usb_rom_len = usb_rom_ptr[2] + usb_rom_ptr[3] * 256;
- for (i = 0; i < packet[USB_bDescriptorIndex]; i++) {
- usb_rom_ptr += usb_rom_len;
- usb_rom_len = usb_rom_ptr[2] + usb_rom_ptr[3] * 256;
- }
- if ((packet[USB_wLengthHigh] < usb_rom_ptr[3]) ||
- (packet[USB_wLengthHigh] == usb_rom_ptr[3] && packet[USB_wLength] < usb_rom_ptr[2]))
- usb_rom_len = packet[USB_wLength] + packet[USB_wLengthHigh] * 256;
- break;
- case USB_STRING_DESCRIPTOR_TYPE:
-
- if (packet[USB_bDescriptorIndex] >= usb_num_string_descriptors) {
- flag_usb_RequestError();
- break;
- }
- usb_rom_ptr = usb_string_descriptor;
- usb_rom_len = usb_rom_ptr[0];
- for (i = 0; i < packet[USB_bDescriptorIndex]; i++) {
- usb_rom_ptr += usb_rom_len;
- usb_rom_len = usb_rom_ptr[0];
- }
- if ((0 == packet[USB_wLengthHigh] && packet[USB_wLength] < usb_rom_ptr[0]))
- usb_rom_len = packet[USB_wLength];
- break;
- case USB_INTERFACE_DESCRIPTOR_TYPE:
- case USB_ENDPOINT_DESCRIPTOR_TYPE:
- default:
- flag_usb_RequestError();
- }
- if (0 == usbrequesterrorflag) {
- usb_send_rom();
- usb_set_in_handler(0, usb_send_rom);
- } else {
- usb_RequestError();
- }
- break;
- case USB_REQUEST_GET_CONFIGURATION:
- EP0_Inbdp->BDADDR[0] = usb_current_cfg;
- usb_ack_dat1(1);
- break;
- case USB_REQUEST_SET_CONFIGURATION:
- if (USB_NUM_CONFIGURATIONS >= packet[USB_wValue]) {
-
-
- usb_current_cfg = packet[USB_wValue];
- if (usb_current_cfg != 0) {
-
-
-
- usb_device_state = CONFIGURED_STATE;
- user_configured_init();
- } else {
- usb_device_state = ADDRESS_STATE;
- }
- usb_ack_dat1(0);
- } else
- usb_RequestError();
- break;
- case USB_REQUEST_SET_DESCRIPTOR:
- default:
- usb_RequestError();
- }
- }
- void usb_handle_StandardInterfaceRequest(BDentry *bdp) {
- BYTE *packet = bdp->BDADDR;
- switch (packet[USB_bRequest]) {
- case USB_REQUEST_GET_STATUS:
- EP0_Inbdp->BDADDR[0] = 0x00;
- EP0_Inbdp->BDADDR[1] = 0x00;
- usb_ack_dat1(2);
- break;
- case USB_REQUEST_GET_INTERFACE:
- if (USB_NUM_INTERFACES > packet[USB_bInterface]) {
-
- EP0_Inbdp->BDADDR[0] = 0;
- usb_ack_dat1(1);
- } else
- usb_RequestError();
- break;
- case USB_REQUEST_SET_INTERFACE:
- if (USB_NUM_INTERFACES > packet[USB_bInterface] && 0u == packet[USB_wValue]) {
-
- usb_ack_dat1(0);
- } else
- usb_RequestError();
- break;
- case USB_REQUEST_CLEAR_FEATURE:
- case USB_REQUEST_SET_FEATURE:
- default:
- usb_RequestError();
- }
- }
- 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;
- EP0_Inbdp->BDADDR[1] = 0x00;
- 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;
-
-
-
- usb_ack_dat1(2);
- break;
- case USB_REQUEST_CLEAR_FEATURE:
-
-
-
-
- epnum = packet[USB_wIndex] & 0x0F;
- 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;
- if (0 == dir) epbd->BDSTAT &= ~DTS;
-
-
-
-
-
-
-
- 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;
-
-
- usb_ack_dat1(0);
- break;
- case USB_REQUEST_SYNCH_FRAME:
- default:
- usb_RequestError();
- }
- }
- void usb_handle_in(void) {
- if (endpoints[USB_STAT2EP(trn_status)].in_handler) {
- endpoints[USB_STAT2EP(trn_status)].in_handler();
- }
- }
- void usb_handle_out(void) {
- if (endpoints[USB_STAT2EP(trn_status)].out_handler) {
- endpoints[USB_STAT2EP(trn_status)].out_handler();
- }
- }
- void usb_register_sof_handler(usb_handler_t handler) {
- sof_handler = handler;
- }
- void usb_register_class_setup_handler(usb_handler_t handler) {
- class_setup_handler = handler;
- }
- void usb_register_vendor_setup_handler(usb_handler_t handler) {
- vendor_setup_handler = handler;
- }
- void usb_set_in_handler(int ep, usb_handler_t in_handler) {
- endpoints[ep].in_handler = in_handler;
- }
- void usb_set_out_handler(int ep, usb_handler_t out_handler) {
- endpoints[ep].out_handler = out_handler;
- }
- void usb_ack_dat1(int bdcnt) {
- EP0_Inbdp->BDCNT = (bdcnt & 0xFF);
- EP0_Inbdp->BDSTAT = (DTS | UOWN | DTSEN);
- }
- 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_IN, USB_PP_EVEN)].BDSTAT = UOWN + BSTALL;
- usb_bdt[USB_CALC_BD(0, USB_DIR_OUT, USB_PP_EVEN)].BDSTAT = UOWN + BSTALL;
-
-
-
- }
- void usb_set_address(void) {
- if (0x00u == usb_addr_pending) {
- usb_device_state = DEFAULT_STATE;
- } else {
- usb_device_state = ADDRESS_STATE;
- }
- SetUsbAddress(usb_addr_pending);
- usb_addr_pending = 0xFF;
- usb_unset_in_handler(0);
- }
- void usb_send_rom(void) {
- unsigned int i;
- size_t packet_len;
- if (usb_rom_len) {
- packet_len = (usb_rom_len < USB_EP0_BUFFER_SIZE) ? usb_rom_len : USB_EP0_BUFFER_SIZE;
- for (i = 0; i < packet_len; i++) {
- EP0_Inbdp->BDADDR[i] = usb_rom_ptr[i];
- }
- } else {
- packet_len = 0;
- usb_unset_in_handler(0);
- }
- EP0_Inbdp->BDCNT = (BYTE) packet_len;
- EP0_Inbdp->BDSTAT = ((EP0_Inbdp->BDSTAT ^ DTS) & DTS) | UOWN | DTSEN;
- usb_rom_ptr += packet_len;
- usb_rom_len -= packet_len;
- }
|