/** Function writes string to USB, atm not more than MAX_SIZE is allowed if more is needed tranfser must be split up **/ byte UARTputs(char *buffer, byte length) { byte i=0; if (deviceState != CONFIGURED) return 0; if (!EP_IN_BD(UART_DATA_EP_NUM).Stat.UOWN) { //printf("IN: 0x%x ", &EP_IN_BD(0)); //printf("OUT: 0x%x \r\n", &EP_OUT_BD(0)); //printf("IN: 0x%x ", &EP_IN_BD(1)); //printf("OUT: 0x%x \r\n", &EP_OUT_BD(1)); //printf("IN: 0x%x ", &EP_IN_BD(2)); //printf("OUT: 0x%x \r\n", &EP_OUT_BD(2)); if (length > UART_BULK_IN_SIZE) length = UART_BULK_IN_SIZE; for (i=0; i < length; i++) { UARTTxBuffer[i] = buffer[i]; #ifdef DEBUG_PRINT printf("%c",UARTTxBuffer[i]); #endif } #ifdef DEBUG_PRINT printf("->"); #endif // printf("Stat 0x%x -> ", EP_IN_BD(UART_DATA_EP_NUM).Stat.uc); // Set counter to num bytes ready for send EP_IN_BD(UART_DATA_EP_NUM).Cnt = i; // clear BDT Stat bits beside DTS and then togle DTS EP_IN_BD(UART_DATA_EP_NUM).Stat.uc &= 0x40; EP_IN_BD(UART_DATA_EP_NUM).Stat.DTS = !EP_IN_BD(UART_DATA_EP_NUM).Stat.DTS; // reset Buffer to original state //BDS_UOWN | BDS_DTSEN | BDS_DTS; EP_IN_BD(UART_DATA_EP_NUM).Stat.uc |= BDS_UOWN | BDS_DTSEN; // printf("Stat 0x%x\r\n", EP_IN_BD(UART_DATA_EP_NUM).Stat.uc); } return i; }
u8 CDCputs(char *buffer, u8 length) { u8 i=0; if (deviceState != CONFIGURED) return 0; if (!CONTROL_LINE) return 0; if (!EP_IN_BD(CDC_DATA_EP_NUM).Stat.UOWN) { if (length > CDC_BULK_IN_SIZE) length = CDC_BULK_IN_SIZE; for (i=0; i < length; i++) { CDCTxBuffer[i] = buffer[i]; #ifdef DEBUG_PRINT_CDC printf("%c",CDCTxBuffer[i]); #endif } #ifdef DEBUG_PRINT_CDC printf("->"); #endif // Set counter to num bytes ready for send EP_IN_BD(CDC_DATA_EP_NUM).Cnt = i; // clear BDT Stat bits beside DTS and then togle DTS EP_IN_BD(CDC_DATA_EP_NUM).Stat.uc &= 0x40; EP_IN_BD(CDC_DATA_EP_NUM).Stat.DTS = !EP_IN_BD(CDC_DATA_EP_NUM).Stat.DTS; // reset Buffer to original state EP_IN_BD(CDC_DATA_EP_NUM).Stat.uc |= BDS_UOWN | BDS_DTSEN; } //return i; return i; }
/** Function writes string to USB, atm not more than MAX_SIZE is allowed if more is needed transfer must be split up **/ byte BULKputs(char *buffer, byte length) { byte i=0; if (deviceState != CONFIGURED) return 0; if (!EP_IN_BD(BULK_DATA_EP_NUM).Stat.UOWN) { if (length > BULK_BULK_IN_SIZE) length = BULK_BULK_IN_SIZE; for (i=0; i < length; i++) { BULKTxBuffer[i] = buffer[i]; } // Set counter to num bytes ready for send EP_IN_BD(BULK_DATA_EP_NUM).Cnt = i; // clear BDT Stat bits beside DTS and then togle DTS EP_IN_BD(BULK_DATA_EP_NUM).Stat.uc &= 0x40; EP_IN_BD(BULK_DATA_EP_NUM).Stat.DTS = !EP_IN_BD(BULK_DATA_EP_NUM).Stat.DTS; // reset Buffer to original state EP_IN_BD(BULK_DATA_EP_NUM).Stat.uc |= BDS_UOWN | BDS_DTSEN; } return i; }
void my_ep2_in(void) { if(UEIEbits.BTOEE && UEIRbits.BTOEF) { // Error during last transfert. Redoing it. UEIRbits.BTOEF = 0; if(EP_IN_BD(2).Stat.DTS == 0) { EP_IN_BD(2).Stat.uc = BDS_USIE | BDS_DAT0 | BDS_DTSEN; } else { EP_IN_BD(2).Stat.uc = BDS_USIE | BDS_DAT1 | BDS_DTSEN; } } else { if((ep2_num_bytes_to_send == 0) && last_send_was_null) { // There is nothing more to send, so keep // the EP2 buffer under the CPU responsability return; } last_send_was_null = (ep2_num_bytes_to_send < MY_EP2_BUFFER_SIZE); EP_IN_BD(2).Cnt = ep2_num_bytes_to_send; fill_in_buffer(2, &ep2_source_data, MY_EP2_BUFFER_SIZE, &ep2_num_bytes_to_send); if(EP_IN_BD(2).Stat.DTS == 0) { EP_IN_BD(2).Stat.uc = BDS_USIE | BDS_DAT1 | BDS_DTSEN; } else { EP_IN_BD(2).Stat.uc = BDS_USIE | BDS_DAT0 | BDS_DTSEN; } } }
void ep0_setup(void) { debug_usb("ep0_setup\n"); ep0_state = WAIT_SETUP; num_bytes_to_be_send = 0; if (ep0_usb_std_request()) { UCONbits.PKTDIS = 0; if (SetupBuffer.data_transfer_direction == DEVICE_TO_HOST) { ep0_state = WAIT_IN; EP_OUT_BD(0).Cnt = EP0_BUFFER_SIZE; EP_OUT_BD(0).ADR = (u8 __data *)&SetupBuffer; EP_OUT_BD(0).Stat.uc = BDS_USIE; EP_IN_BD(0).ADR = (u8 __data *)InBuffer; if (SetupBuffer.wLength < num_bytes_to_be_send) { num_bytes_to_be_send = SetupBuffer.wLength; } debug2_usb("bytes to send: %d\r\n", num_bytes_to_be_send); fill_in_buffer(0, &sourceData, EP0_BUFFER_SIZE, &num_bytes_to_be_send); EP_IN_BD(0).Stat.uc = BDS_USIE | BDS_DAT1 | BDS_DTSEN; } else // HOST_TO_DEVICE { ep0_state = WAIT_OUT; EP_OUT_BD(0).Cnt = EP0_BUFFER_SIZE; EP_OUT_BD(0).ADR = (u8 __data *)InBuffer; EP_OUT_BD(0).Stat.uc = BDS_USIE | BDS_DAT1 | BDS_DTSEN; EP_IN_BD(0).Cnt = 0; EP_IN_BD(0).Stat.uc = BDS_USIE | BDS_DAT1 | BDS_DTSEN; } } else if (ep0_dfu_request()) { UCONbits.PKTDIS = 0; if (SetupBuffer.data_transfer_direction == DEVICE_TO_HOST) { ep0_state = WAIT_DFU_IN; EP_OUT_BD(0).Cnt = EP0_BUFFER_SIZE; EP_OUT_BD(0).ADR = (u8 __data *)&SetupBuffer; EP_OUT_BD(0).Stat.uc = BDS_USIE; EP_IN_BD(0).ADR = (u8 __data *)InBuffer; if (SetupBuffer.wLength < num_bytes_to_be_send) { num_bytes_to_be_send = SetupBuffer.wLength; } debug2_usb("bytes to send: %d\n", num_bytes_to_be_send); // debug2("2: %x\n", sourceData[0]); fill_in_buffer(0, &sourceData, EP0_BUFFER_SIZE, &num_bytes_to_be_send); EP_IN_BD(0).Stat.uc = BDS_USIE | BDS_DAT1 | BDS_DTSEN; } else // HOST_TO_DEVICE { ep0_state = WAIT_DFU_OUT; EP_OUT_BD(0).Cnt = EP0_BUFFER_SIZE; EP_OUT_BD(0).ADR = (u8 __data *)InBuffer; EP_OUT_BD(0).Stat.uc = BDS_USIE | BDS_DAT1 | BDS_DTSEN; EP_IN_BD(0).Cnt = 0; EP_IN_BD(0).Stat.uc = BDS_USIE | BDS_DAT1 | BDS_DTSEN; } } else { debug_usb("unknown request\n"); UCONbits.PKTDIS = 0; EP_OUT_BD(0).Cnt = EP0_BUFFER_SIZE; EP_OUT_BD(0).ADR = (u8 __data *)&SetupBuffer; EP_OUT_BD(0).Stat.uc = BDS_USIE | BDS_BSTALL; EP_IN_BD(0).Stat.uc = BDS_USIE | BDS_BSTALL; } }
void ep0_in(void) { debug2_usb("ep0_in %d\n", (u16) num_bytes_to_be_send); if (GET_DEVICE_STATE() == ADDRESS_PENDING_STATE) { UADDR = SetupBuffer.bAddress; if (UADDR != 0) { SET_DEVICE_STATE(ADDRESS_STATE); } else { SET_DEVICE_STATE(DEFAULT_STATE); } } if (ep0_state == WAIT_IN) { fill_in_buffer(0, &sourceData, EP0_BUFFER_SIZE, &num_bytes_to_be_send); if (EP_IN_BD(0).Stat.DTS == 0) { EP_IN_BD(0).Stat.uc = BDS_USIE | BDS_DAT1 | BDS_DTSEN; } else { EP_IN_BD(0).Stat.uc = BDS_USIE | BDS_DAT0 | BDS_DTSEN; } } else if (ep0_state == WAIT_DFU_IN) { fill_in_buffer(0, &sourceData, EP0_BUFFER_SIZE, &num_bytes_to_be_send); if (EP_IN_BD(0).Stat.DTS == 0) { EP_IN_BD(0).Stat.uc = BDS_USIE | BDS_DAT1 | BDS_DTSEN; } else { EP_IN_BD(0).Stat.uc = BDS_USIE | BDS_DAT0 | BDS_DTSEN; } } else { ep0_state = WAIT_SETUP; EP_OUT_BD(0).Cnt = EP0_BUFFER_SIZE; EP_OUT_BD(0).ADR = (u8 __data *)&SetupBuffer; EP_OUT_BD(0).Stat.uc = BDS_USIE | BDS_DAT0 | BDS_DTSEN; EP_IN_BD(0).Stat.uc = BDS_UCPU; UEP0 = EPINEN_EN | EPOUTEN_EN | EPHSHK_EN; } if (GET_DEVICE_STATE() == CONFIGURATION_PENDING_STATE) { // First, disable all endpoints. // UEP0 is never disabled UEP1 = 0; UEP2 = 0; UEP3 = 0; UEP4 = 0; UEP5 = 0; UEP6 = 0; UEP7 = 0; UEP8 = 0; UEP9 = 0; UEP10 = 0; UEP11 = 0; UEP12 = 0; UEP13 = 0; UEP14 = 0; UEP15 = 0; // switch the functions vectors /* if(coming_cfg <= FLASH_CONFIGURATION) { // switch back to the bootloader vectors ep_init = boot_ep_init; ep_in = boot_ep_in; ep_out = boot_ep_out; ep_setup = boot_ep_setup; } else { // switch to the application vectors ep_init = application_data.ep_init; ep_in = application_data.ep_in; ep_out = application_data.ep_out; ep_setup = application_data.ep_setup; } */ ep_init = boot_ep_init; ep_in = boot_ep_in; ep_out = boot_ep_out; ep_setup = boot_ep_setup; SET_ACTIVE_CONFIGURATION(coming_cfg); if (coming_cfg == 0) { SET_DEVICE_STATE(ADDRESS_STATE); } else { static u8 i; // Switch to decrement loop because of a sdcc bug for (i = 15; i > 0; i--) // for(i = 1; i < 16; i++) { ep_init[coming_cfg][i](); } SET_DEVICE_STATE(CONFIGURED_STATE); } } }