123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720 |
- #include "pic18f2550.h"
- #include "usbcdc.h"
- #include "usbpic_defs.h"
- #include "usbcdc_defs.h"
- #include "usb_defs.h"
- typedef __code unsigned char* codePtr;
- typedef __data unsigned char* dataPtr;
- typedef struct {
- USB_CFG_DSC cd01;
- USB_INTF_DSC i01a00;
- USB_CDC_HEADER_FN_DSC cdc_header_fn_i01a00;
- USB_CDC_CALL_MGT_FN_DSC cdc_call_mgt_fn_i01a00;
- USB_CDC_ACM_FN_DSC cdc_acm_fn_i01a00;
- USB_CDC_UNION_FN_DSC cdc_union_fn_i01a00;
- USB_EP_DSC ep02i_i01a00;
- USB_INTF_DSC i02a00;
- USB_EP_DSC ep03o_i02a00;
- USB_EP_DSC ep03i_i02a00;
- } config_struct;
- unsigned char usbcdc_device_state;
- static unsigned char device_address;
- static unsigned char current_configuration;
- static unsigned char idx;
- static unsigned char control_stage;
- static unsigned char request_handled;
- static dataPtr data_ptr;
- static codePtr code_ptr;
- static dataPtr in_ptr;
- static unsigned char dlen;
- #define SETUP_STAGE 0
- #define DATA_OUT_STAGE 1
- #define DATA_IN_STAGE 2
- #define STATUS_STAGE 3
- __code unsigned char device_descriptor[] = {
- 0x12, 0x01,
- 0x00, 0x02,
- 0x02, 0x00,
- 0x00, E0SZ,
- 0x08, 0x04,
- 0x0A, 0x00,
- 0x00, 0x01,
- 0x01, 0x00,
- 0x00, 0x01
-
- };
- __code unsigned char device_qualifier_descriptor[] = {
- 0x0A, 0x06,
- 0x00, 0x02,
- 0x02, 0x00,
- 0x00, E0SZ,
- 0x01, 0x00
- };
- static __code char const_values_0x00_0x00[] = { 0, 0 };
- static __code char const_values_0x00_0x01[] = { 0, 1 };
- static __code char const_values_0x01_0x00[] = { 1, 0 };
- static __code char const_values_status[] = { (USBCDC_SELF_POWERED<<0), 0 };
- __code config_struct
- config_descriptor = {
- {
-
- sizeof(USB_CFG_DSC), DSC_CFG,
- sizeof(config_struct),
- 0x02, 0x01,
- 0x00, 0x80 | (USBCDC_SELF_POWERED<<6),
- USBCDC_MAXPOWER / 2,
- },
-
- { sizeof(USB_INTF_DSC),
- DSC_INTF,
- 0,
- 0,
- 1,
- COMM_INTF,
- ABSTRACT_CONTROL_MODEL,
- V25TER,
- 0
- },
-
- { sizeof(USB_CDC_HEADER_FN_DSC), CS_INTERFACE,DSC_FN_HEADER,
- 0x0110 },
- { sizeof(USB_CDC_CALL_MGT_FN_DSC), CS_INTERFACE,
- DSC_FN_CALL_MGT, 0x01, CDC_DATA_INTF_ID},
- { sizeof(USB_CDC_ACM_FN_DSC), CS_INTERFACE,
- DSC_FN_ACM, 0x02 },
- { sizeof(USB_CDC_UNION_FN_DSC), CS_INTERFACE,
- DSC_FN_UNION, CDC_COMM_INTF_ID, CDC_DATA_INTF_ID },
-
- {
- sizeof(USB_EP_DSC), DSC_EP,_EP01_IN, _INT,CDC_INT_EP_SIZE, 0x0A, },
-
- { sizeof(USB_INTF_DSC),
- DSC_INTF,
- 1,
- 0,
- 2,
- DATA_INTF,
- 0,
- NO_PROTOCOL,
- 2,
- },
-
- { sizeof(USB_EP_DSC), DSC_EP,_EP02_OUT,
- _BULK,USBCDC_BUFFER_LEN, 0x00, },
- { sizeof(USB_EP_DSC), DSC_EP,_EP02_IN, _BULK,USBCDC_BUFFER_LEN,
- 0x00 },
- };
- __code unsigned char string_descriptor0[] = {
- 0x04, STRING_DESCRIPTOR,
- 0x09, 0x04,
- };
- __code unsigned char string_descriptor1[] = {
- 0x0E, STRING_DESCRIPTOR,
- 'T', 0x00,
- 'e', 0x00,
- 's', 0x00,
- 't', 0x00,
- 'i', 0x00,
- '!', 0x00,
- };
- __code unsigned char string_descriptor2[] = {
- 0x20, STRING_DESCRIPTOR,
- 'U', 0x00,
- 'S', 0x00,
- 'B', 0x00,
- ' ', 0x00,
- 'G', 0x00,
- 'e', 0x00,
- 'n', 0x00,
- 'e', 0x00,
- 'r', 0x00,
- 'i', 0x00,
- 'c', 0x00,
- ' ', 0x00,
- 'C', 0x00,
- 'D', 0x00,
- 'C', 0x00,
- };
- static volatile setup_packet_struct setup_packet;
- static volatile unsigned char control_transfer_buffer[E0SZ];
- static unsigned char tx_len = 0;
- static unsigned char rx_idx = 0;
- volatile unsigned char cdc_rx_buffer[USBCDC_BUFFER_LEN];
- volatile unsigned char cdc_tx_buffer[USBCDC_BUFFER_LEN];
- static volatile unsigned char cdcint_buffer[USBCDC_BUFFER_LEN];
- static __code char cdc_line_coding[7] = {9600&0xFF,9600>>8,0,0,0,0,8};
- void usbcdc_putchar(char c)__wparam
- {
- while (usbcdc_wr_busy());
- cdc_tx_buffer[tx_len++]=c;
- if (tx_len>=sizeof(cdc_tx_buffer)) {
- usbcdc_flush();
- }
- }
- char usbcdc_wr_busy() {
- return (ep2_i.STAT & UOWN)!=0;
- }
- unsigned char usbcdc_rd_ready() {
- if (ep2_o.STAT & UOWN)
- return 0;
- if (rx_idx >= ep2_o.CNT) {
- usbcdc_read();
- return 0;
- }
- return 1;
- }
- void usbcdc_write(unsigned char len)__wparam
- {
- if (len> 0) {
- ep2_i.CNT = len;
- if (ep2_i.STAT & DTS)
- ep2_i.STAT = UOWN | DTSEN;
- else
- ep2_i.STAT = UOWN | DTS | DTSEN;
- }
- }
- void usbcdc_flush() {
- usbcdc_write(tx_len);
- tx_len = 0;
-
- }
- void usbcdc_read() {
- rx_idx=0;
- ep2_o.CNT = sizeof(cdc_rx_buffer);
- if (ep2_o.STAT & DTS)
- ep2_o.STAT = UOWN | DTSEN;
- else
- ep2_o.STAT = UOWN | DTS | DTSEN;
- }
- char usbcdc_getchar() {
- char c;
- while (!usbcdc_rd_ready());
-
- c = cdc_rx_buffer[rx_idx++];
- if (rx_idx>=ep2_o.CNT) {
- usbcdc_read();
- }
- return c;
- }
- static void get_descriptor(void) {
- if (setup_packet.bmrequesttype == 0x80) {
- unsigned char descriptorType = setup_packet.wvalue1;
- unsigned char descriptorIndex = setup_packet.wvalue0;
-
- if (descriptorType == DEVICE_DESCRIPTOR) {
- request_handled = 1;
- code_ptr = (codePtr) &device_descriptor;
- dlen = *code_ptr;
- } else if (descriptorType == QUALIFIER_DESCRIPTOR) {
- request_handled = 1;
- code_ptr = (codePtr) &device_qualifier_descriptor;
- dlen = sizeof(device_qualifier_descriptor);
- } else if (descriptorType == CONFIGURATION_DESCRIPTOR) {
- request_handled = 1;
-
- code_ptr = (codePtr) &config_descriptor;
- dlen = *(code_ptr + 2);
-
- } else if (descriptorType == STRING_DESCRIPTOR) {
- request_handled = 1;
- if (descriptorIndex == 0) {
- code_ptr = (codePtr) &string_descriptor0;
- } else if (descriptorIndex == 1) {
- code_ptr = (codePtr) &string_descriptor1;
- } else {
- code_ptr = (codePtr) &string_descriptor2;
- }
- dlen = *code_ptr;
- }
- }
- }
- static void get_status(void) {
-
- unsigned char recipient = setup_packet.bmrequesttype & 0x1F;
-
-
- if (recipient == 0x00) {
-
- request_handled = 1;
- code_ptr = (codePtr) &const_values_status;
-
- } else if (recipient == 0x01) {
-
- code_ptr = (codePtr) &const_values_0x00_0x00;
- request_handled = 1;
- } else if (recipient == 0x02) {
-
- unsigned char endpointNum = setup_packet.windex0 & 0x0F;
- unsigned char endpointDir = setup_packet.windex0 & 0x80;
- request_handled = 1;
-
-
- in_ptr = (dataPtr) &ep0_o + (endpointNum * 8);
- if (endpointDir)
- in_ptr += 4;
- if (*in_ptr & BSTALL)
- code_ptr = (codePtr) &const_values_0x01_0x00;
- }
- if (request_handled) {
- dlen = 2;
- }
- }
- static void set_feature(void) {
- unsigned char recipient = setup_packet.bmrequesttype & 0x1F;
- unsigned char feature = setup_packet.wvalue0;
-
- if (recipient == 0x02) {
-
- unsigned char endpointNum = setup_packet.windex0 & 0x0F;
- unsigned char endpointDir = setup_packet.windex0 & 0x80;
- if ((feature == ENDPOINT_HALT) && (endpointNum != 0)) {
- char temp;
-
-
- request_handled = 1;
-
-
- in_ptr = (dataPtr) &ep0_o + (endpointNum * 8);
- if (endpointDir)
- in_ptr += 4;
-
- if (setup_packet.brequest == SET_FEATURE)
- temp = 0x84;
- else {
- if (endpointDir == 1)
- temp = 0x00;
- else
- temp = 0x88;
- }
- *in_ptr = temp;
-
- }
- }
- }
- void in_data_stage(void) {
-
- unsigned char bufferSize;
-
- if (dlen < E0SZ)
- bufferSize = dlen;
- else
- bufferSize = E0SZ;
-
-
- ep0_i.STAT &= ~(BC8| BC9);
-
-
- ep0_i.CNT = bufferSize;
- ep0_i.ADDR = (int) &control_transfer_buffer;
-
-
-
- dlen = dlen - bufferSize;
-
- in_ptr = (dataPtr) &control_transfer_buffer;
-
-
- for (idx = bufferSize; idx--;)
- *in_ptr++ = *code_ptr++;
-
- }
- void prepare_for_setup_stage(void) {
- control_stage = SETUP_STAGE;
- ep0_o.CNT = E0SZ;
- ep0_o.ADDR = (int) &setup_packet;
- ep0_o.STAT = UOWN | DTSEN;
- ep0_i.STAT = 0x00;
- UCONbits.PKTDIS = 0;
- }
- char debug=0;
- void process_control_transfer(void) {
- if (USTAT == USTAT_OUT) {
- unsigned char PID = (ep0_o.STAT & 0x3C) >> 2;
- if (PID == 0x0D) {
-
-
-
- ep0_i.STAT &= ~UOWN;
- ep0_o.STAT &= ~UOWN;
-
-
- control_stage = SETUP_STAGE;
- request_handled = 0;
-
- dlen = 0;
-
-
- debug=setup_packet.bmrequesttype;
- if (1 ) {
- unsigned char request = setup_packet.brequest;
- debug = request;
-
-
- if (request == SET_ADDRESS) {
-
-
-
-
-
- request_handled = 1;
- usbcdc_device_state = ADDRESS;
- device_address = setup_packet.wvalue0;
- } else if (request == GET_DESCRIPTOR) {
- get_descriptor();
- } else if (request == SET_CONFIGURATION) {
-
- request_handled = 1;
- current_configuration = setup_packet.wvalue0;
-
-
- if (current_configuration == 0) {
-
-
- usbcdc_device_state = ADDRESS;
- } else {
-
- usbcdc_device_state = CONFIGURED;
-
-
- {
- UEP1 = 0x1E;
-
- ep1_i.ADDR = (int) &cdcint_buffer;
- ep1_i.STAT = DTS;
-
- UEP2 = 0x1E;
-
- ep2_o.CNT = sizeof(cdc_rx_buffer);
- ep2_o.ADDR = (int) &cdc_rx_buffer;
- ep2_o.STAT = UOWN | DTSEN;
-
- ep2_i.ADDR = (int) &cdc_tx_buffer;
- ep2_i.STAT = DTS;
- }
- }
- } else if (request == GET_CONFIGURATION) {
- request_handled = 1;
- code_ptr = (codePtr) &const_values_0x00_0x01[current_configuration];
- dlen = 1;
- } else if (request == GET_STATUS) {
- get_status();
- } else if ((request == CLEAR_FEATURE) || (request
- == SET_FEATURE)) {
- set_feature();
- } else if (request == GET_INTERFACE) {
-
-
-
- request_handled = 1;
- code_ptr = (codePtr) (&const_values_0x00_0x00);
- dlen = 1;
- } else if ((request == SET_INTERFACE) || (request == SET_LINE_CODING) || (request == SET_CONTROL_LINE_STATE)) {
-
-
-
- request_handled = 1;
- } else if (request == GET_LINE_CODING) {
- code_ptr = (codePtr) (&cdc_line_coding);
- dlen = sizeof(cdc_line_coding);
- request_handled = 1;
- }
-
-
-
-
-
-
-
-
-
-
- }
-
-
- if (!request_handled) {
-
- ep0_o.CNT = E0SZ;
- ep0_o.ADDR = (int) &setup_packet;
- ep0_o.STAT = UOWN | BSTALL;
- ep0_i.STAT = UOWN | BSTALL;
- } else if (setup_packet.bmrequesttype & 0x80) {
-
- if (setup_packet.wlength < dlen)
- dlen = setup_packet.wlength;
-
- in_data_stage();
- control_stage = DATA_IN_STAGE;
-
- ep0_o.CNT = E0SZ;
- ep0_o.ADDR = (int) &setup_packet;
- ep0_o.STAT = UOWN;
-
-
-
- ep0_i.STAT = UOWN | DTS | DTSEN;
- } else {
-
-
- control_stage = DATA_OUT_STAGE;
-
- ep0_i.CNT = 0;
- ep0_i.STAT = UOWN | DTS | DTSEN;
-
- ep0_o.CNT = E0SZ;
- ep0_o.ADDR = (int) &control_transfer_buffer;
-
- ep0_o.STAT = UOWN | DTS | DTSEN;
- }
-
- UCONbits.PKTDIS = 0;
-
- } else if (control_stage == DATA_OUT_STAGE) {
-
-
-
- {
-
- unsigned char bufferSize;
-
- bufferSize = ep0_o.CNT;
-
-
- dlen = dlen + bufferSize;
- data_ptr = (dataPtr) &control_transfer_buffer;
- for (idx = bufferSize; idx--;)
- *in_ptr++ = *data_ptr++;
-
- }
-
-
- if (ep0_o.STAT & DTS)
- ep0_o.STAT = UOWN | DTSEN;
- else
- ep0_o.STAT = UOWN | DTS | DTSEN;
- } else {
-
- prepare_for_setup_stage();
- }
- } else if (USTAT == USTAT_IN) {
-
-
-
- if ((UADDR == 0) && (usbcdc_device_state == ADDRESS)) {
-
-
- UADDR = setup_packet.wvalue0;
- if (UADDR == 0) {
-
-
- usbcdc_device_state = DEFAULT;
- }
- }
-
- if (control_stage == DATA_IN_STAGE) {
-
- in_data_stage();
-
- if (ep0_i.STAT & DTS)
- ep0_i.STAT = UOWN | DTSEN;
- else
- ep0_i.STAT = UOWN | DTS | DTSEN;
- } else {
-
- prepare_for_setup_stage();
- }
- }
- }
- void usbcdc_init() {
- UCFG = 0x14;
-
- usbcdc_device_state = DETACHED;
-
- current_configuration = 0x00;
-
-
- if (UCONbits.USBEN == 0) {
- UCON = 0;
- UIE = 0;
- UCONbits.USBEN = 1;
- usbcdc_device_state = ATTACHED;
-
- }
-
- {
- UIR = 0;
- UIE = 0;
- UIEbits.URSTIE = 1;
- usbcdc_device_state = POWERED;
- }
-
- PIE2bits.USBIE = 1;
- }
- void usbcdc_handler(void) {
- if ((UCFGbits.UTEYE == 1) ||
- (usbcdc_device_state == DETACHED) ||
- (UCONbits.SUSPND == 1))
- return;
-
-
- if (UIRbits.URSTIF && UIEbits.URSTIE) {
- {
-
- UEIR = 0x00;
- UIR = 0x00;
- UEIE = 0x9f;
- UIE = 0x2b;
- UADDR = 0x00;
-
-
- UEP0 = 0x16;
-
-
- while (UIRbits.TRNIF == 1)
- UIRbits.TRNIF = 0;
-
-
- UCONbits.PKTDIS = 0;
-
-
- prepare_for_setup_stage();
-
- current_configuration = 0;
- usbcdc_device_state = DEFAULT;
-
- }
- UIRbits.URSTIF = 0;
- }
-
- if (UIRbits.SOFIF && UIEbits.SOFIE) {
- UIRbits.SOFIF = 0;
- }
-
-
- if (UIRbits.STALLIF && UIEbits.STALLIE) {
- if (UEP0bits.EPSTALL == 1) {
-
- prepare_for_setup_stage();
- UEP0bits.EPSTALL = 0;
- }
- UIRbits.STALLIF = 0;
- }
- if (UIRbits.UERRIF && UIEbits.UERRIE) {
-
- UIRbits.UERRIF = 0;
- }
-
- if (UIRbits.TRNIF && UIEbits.TRNIE) {
- process_control_transfer();
-
- UIRbits.TRNIF = 0;
- }
- }
|