00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00043 #include "config.h"
00044
00045
00046 #include "pic_usb.h"
00047 #include "pic_usb_buffer_mgt.h"
00048 #ifdef USB_CDC_USE_LEDS
00049 #include "platform_leds.h"
00050 #endif
00051
00052
00053 #include "pic_serial.h"
00054
00055
00056
00057 #include "usb_cdc_class.h"
00058
00059
00060 #include "memory.h"
00061
00062
00063
00064 #define req_SEND_ENCAPSULATED_COMMAND 0x00
00065 #define req_GET_ENCAPSULATED_RESPONSE 0x01
00066 #define req_SET_COMM_FEATURE 0x02
00067 #define req_GET_COMM_FEATURE 0x03
00068 #define req_CLEAR_COMM_FEATURE 0x04
00069 #define req_SET_LINE_CODING 0x20
00070 #define req_GET_LINE_CODING 0x21
00071 #define req_SET_CONTROL_LINE_STATE 0x22
00072 #define req_SEND_BREAK 0x23
00073
00074 #define not_SERIAL_STATE 0xa1
00075
00076 typedef union _long_union{
00077 long as_long;
00078 uns8 as_byte_array[4];
00079 } long_union;
00080
00084 typedef struct _line_coding {
00085 long_union dte_rate;
00086 uns8 stop_bits;
00087 uns8 parity;
00088 uns8 data_bits;
00089 } line_coding;
00090
00091 uns16 current_bit_rate;
00092 long_union dte_rate;
00093
00095 uns8 cdc_tx_buffer[USB_CDC_TX_BUFFER_SIZE];
00097 uns8 cdc_tx_start=0;
00099 uns8 cdc_tx_end=0;
00100
00102 uns8 cdc_rx_buffer[USB_CDC_RX_BUFFER_SIZE];
00104 uns8 cdc_rx_start = 0;
00106 uns8 cdc_rx_end = 0;
00107
00108
00109 uns8 class_data[8];
00110
00111
00112 void usb_handle_class_request_callback(setup_data_packet sdp) {
00113
00114 switch (sdp.bRequest) {
00115 case req_SET_LINE_CODING:
00116
00117
00118 #ifdef CDC_DEBUG
00119 serial_print_str("SET_LINE ");
00120 #endif
00121 control_mode = cm_CTRL_WRITE_DATA_STAGE_CLASS;
00122 break;
00123 case req_GET_LINE_CODING:
00124 #ifdef CDC_DEBUG
00125 serial_print_str("GET_LINE ");
00126 serial_print_str(" len=");
00127 serial_print_int(sdp.wLength);
00128 serial_putc(' ');
00129 #endif
00130
00131 control_mode = cm_CTRL_READ_DATA_STAGE_CLASS;
00132
00133 line_coding my_line_coding;
00134
00135
00136 my_line_coding.dte_rate.as_byte_array[0] = dte_rate.as_byte_array[3];
00137 my_line_coding.dte_rate.as_byte_array[1] = dte_rate.as_byte_array[2];
00138 my_line_coding.dte_rate.as_byte_array[2] = dte_rate.as_byte_array[1];
00139 my_line_coding.dte_rate.as_byte_array[3] = dte_rate.as_byte_array[0];
00140 my_line_coding.stop_bits = 0;
00141 my_line_coding.data_bits = 8;
00142 my_line_coding.parity = 0;
00143
00144 usb_send_data( 0, (uns8 *)&my_line_coding, sizeof(my_line_coding), 1);
00145
00146 control_mode = cm_CTRL_READ_AWAITING_STATUS;
00147
00148 break;
00149 case req_SET_CONTROL_LINE_STATE:
00150 #ifdef CDC_DEBUG
00151 serial_print_str("scls=");
00152 serial_print_int_hex(sdp.wValue);
00153 #endif
00154
00155
00156 usb_send_status_ack();
00157 control_mode = cm_CTRL_WRITE_SENDING_STATUS;
00158
00159 break;
00160 default:
00161 #ifdef CDC_DEBUG
00162 serial_print_str("??r=");
00163 serial_print_int(sdp.bRequest);
00164 #endif
00165 }
00166 }
00167
00168 void usb_handle_class_ctrl_write_callback(uns8 *data, uns16 count) {
00169
00170 switch (usb_sdp.bRequest) {
00171 case req_SET_LINE_CODING:
00172
00173 memcpy( (void *)&class_data, (void *)data, count);
00174
00175
00176
00177 usb_send_status_ack();
00178 control_mode = cm_CTRL_WRITE_SENDING_STATUS;
00179
00180 line_coding *my_lc;
00181 my_lc = (line_coding*) &class_data;
00182 #ifdef CDC_DEBUG
00183 serial_print_int_hex(my_lc->dte_rate.as_byte_array[0]);
00184 serial_print_int_hex(my_lc->dte_rate.as_byte_array[1]);
00185 serial_print_int_hex(my_lc->dte_rate.as_byte_array[2]);
00186 serial_print_int_hex(my_lc->dte_rate.as_byte_array[3]);
00187 serial_print_str(" st=");
00188 serial_print_int(my_lc->stop_bits);
00189 serial_print_str(" p=");
00190 serial_print_int(my_lc->parity);
00191 serial_print_str(" db=");
00192 serial_print_int(my_lc->data_bits);
00193 serial_print_str(" bit rate: ");
00194 #endif
00195
00196 dte_rate.as_byte_array[0] = my_lc->dte_rate.as_byte_array[3];
00197 dte_rate.as_byte_array[1] = my_lc->dte_rate.as_byte_array[2];
00198 dte_rate.as_byte_array[2] = my_lc->dte_rate.as_byte_array[1];
00199 dte_rate.as_byte_array[3] = my_lc->dte_rate.as_byte_array[0];
00200
00201 switch (my_lc->dte_rate.as_long) {
00202 case 2400:
00203 current_bit_rate = SPBRG_2400;
00204 #ifdef CDC_DEBUG
00205 serial_print_str("2400 ");
00206 #endif
00207 break;
00208 case 4800:
00209 current_bit_rate = SPBRG_4800;
00210 #ifdef CDC_DEBUG
00211 serial_print_str("4800 ");
00212 #endif
00213 break;
00214 case 9600:
00215 current_bit_rate = SPBRG_9600;
00216 #ifdef CDC_DEBUG
00217 serial_print_str("9600 ");
00218 #endif
00219 break;
00220 case 19200:
00221 current_bit_rate = SPBRG_19200;
00222 #ifdef CDC_DEBUG
00223 serial_print_str("19200 ");
00224 #endif
00225 break;
00226 case 38400:
00227 current_bit_rate = SPBRG_38400;
00228 #ifdef CDC_DEBUG
00229 serial_print_str("38400 ");
00230 #endif
00231 break;
00232 case 115200:
00233 current_bit_rate = SPBRG_115200;
00234 #ifdef CDC_DEBUG
00235 serial_print_str("115200 ");
00236 #endif
00237 break;
00238 default:
00239 #ifdef CDC_DEBUG
00240 serial_print_str("Don't handle this bit rate");
00241 #endif
00242 }
00243
00244 clear_bit(rcsta, SPEN);
00245 clear_bit(txsta, TXEN);
00246 clear_bit(rcsta, CREN);
00247
00248
00249 serial_setup(current_bit_rate);
00250 if (!serial_tx_empty()) {
00251 #ifdef USB_CDC_USE_LEDS
00252 platform_leds_flash(1);
00253 #endif
00254 set_bit(pie1, TXIE);
00255 serial_tx_isr();
00256 }
00257 break;
00258 default:
00259 #ifdef CDC_DEBUG
00260 serial_print_str(" ??cw req=");
00261 serial_print_int_hex(usb_sdp.bRequest);
00262 serial_putc(' ');
00263 #endif
00264 break;
00265 }
00266 }
00267
00268 void usb_handle_class_ctrl_read_callback() {
00269 switch (usb_sdp.bRequest) {
00270 case req_GET_LINE_CODING:
00271
00272 control_mode = cm_CTRL_READ_AWAITING_STATUS;
00273 break;
00274 default:
00275 #ifdef CDC_DEBUG
00276 serial_print_str(" cl read ?? ");
00277 serial_print_int(usb_sdp.bRequest);
00278 #endif
00279 }
00280
00281 }
00282
00283 void usb_ep_data_out_callback(uns8 end_point, uns8 *buffer,
00284 uns16 byte_count) {
00285 uns8 cdc_rx_next;
00286 #ifdef CDC_DEBUG
00287 serial_print_str(" EP data out: ");
00288 serial_print_int(byte_count);
00289 serial_print_str(" bytes ");
00290 #endif
00291
00292
00293
00294 if (end_point == USB_CDC_DATA_ENDPOINT) {
00295 uns8 count;
00296 for (count = 0; count < byte_count; count++) {
00297 cdc_rx_next = cdc_rx_end + 1;
00298 if (cdc_rx_next == USB_CDC_RX_BUFFER_SIZE) {
00299 cdc_rx_next = 0;
00300 }
00301 if (cdc_rx_next != cdc_rx_start) {
00302 cdc_rx_buffer[cdc_rx_end] = buffer[count];
00303 cdc_rx_end = cdc_rx_next;
00304 } else {
00305
00306 break;
00307 }
00308 }
00309 } else {
00310 #ifdef CDC_DEBUG
00311 serial_print_str("data for ep ");
00312 serial_print_int(end_point);
00313 #endif
00314 }
00315
00316 #ifdef USB_CDC_USE_LEDS
00317 platform_leds_flash(3);
00318 #endif
00319 }
00320
00321
00322
00323 void usb_ep_data_in_callback(uns8 end_point, uns16 byte_count) {
00324 #ifdef CDC_DEBUG
00325 serial_print_str(" EP data in: ");
00326 serial_print_int(byte_count);
00327 serial_print_str(" bytes ");
00328 #endif
00329
00330 if (end_point == USB_CDC_DATA_ENDPOINT) {
00331 usb_cdc_handle_tx();
00332 }
00333 }
00334
00335 void usb_cdc_set_dcd() {
00336 }
00337
00338 void usb_cdc_set_dsr() {
00339 }
00340
00341
00342
00343 void usb_cdc_putc(uns8 c) {
00344 uns8 cdc_tx_next;
00345 bit my_store_gie;
00346 #ifdef CDC_IDE_DEBUG
00347 return;
00348 #endif
00349
00350 cdc_tx_next = cdc_tx_end + 1;
00351 if (cdc_tx_next == USB_CDC_TX_BUFFER_SIZE) {
00352 cdc_tx_next = 0;
00353 }
00354
00355 if ((!intcon.GIE) && (cdc_tx_next == cdc_tx_start)) {
00356 return;
00357 }
00358 while (cdc_tx_next == cdc_tx_start) {
00359
00360 }
00361
00362 start_crit_sec();
00363
00364 cdc_tx_buffer[cdc_tx_end] = c;
00365 cdc_tx_end = cdc_tx_next;
00366
00367 end_crit_sec();
00368
00369 }
00370
00371 uns8 usb_cdc_getc(void)
00372 {
00373 uns8 cdc_rx_char, cdc_rx_next;
00374
00375 while(cdc_rx_end == cdc_rx_start);
00376
00377 start_crit_sec();
00378
00379 cdc_rx_char = cdc_rx_buffer[cdc_rx_start];
00380 cdc_rx_start++;
00381 if (cdc_rx_start == USB_CDC_RX_BUFFER_SIZE) {
00382 cdc_rx_start = 0;
00383 }
00384
00385 end_crit_sec();
00386
00387 return (cdc_rx_char);
00388
00389 }
00390
00391
00392 void usb_cdc_handle_tx()
00393 {
00394 uns8 cdc_tx_next;
00395 uns8 count;
00396 uns16 buffer_size;
00397 uns8 *buffer;
00398 buffer_descriptor *bd;
00399
00400 bd = ep_in_bd_location[USB_CDC_DATA_ENDPOINT];
00401 if (test_bit(bd->stat, UOWN)) {
00402 return;
00403 }
00404
00405 buffer_size = ep_in_buffer_size[USB_CDC_DATA_ENDPOINT];
00406 buffer = ep_in_buffer_location[USB_CDC_DATA_ENDPOINT];
00407
00408 if (cdc_tx_end == cdc_tx_start) {
00409 return;
00410 }
00411 #ifdef CDC_DEBUG
00412 serial_putc('<');
00413 #endif
00414 start_crit_sec();
00415
00416 count = 0;
00417 while ((cdc_tx_end != cdc_tx_start) && (count < buffer_size)) {
00418
00419 cdc_tx_next = cdc_tx_start + 1;
00420 if (cdc_tx_next == USB_CDC_TX_BUFFER_SIZE) {
00421 cdc_tx_next = 0;
00422 }
00423 buffer[count] = cdc_tx_buffer[cdc_tx_start];
00424 #ifdef CDC_DEBUG
00425 serial_putc(buffer[count]);
00426 #endif
00427 count++;
00428 cdc_tx_start = cdc_tx_next;
00429 }
00430 if (count > 0) {
00431 bd->count = count;
00432 bd->addr = (uns16)buffer;
00433
00434 toggle_bit(bd->stat, DTS);
00435 clear_bit(bd->stat, KEN);
00436 clear_bit(bd->stat, INCDIS);
00437 set_bit (bd->stat, DTSEN);
00438 clear_bit(bd->stat, BSTALL);
00439 clear_bit(bd->stat, BC9);
00440 clear_bit(bd->stat, BC8);
00441
00442 set_bit (bd->stat, UOWN);
00443 }
00444 end_crit_sec();
00445 #ifdef CDC_DEBUG
00446 serial_putc('>');
00447 serial_print_str("send=");
00448 serial_print_int(count);
00449 serial_putc(' ');
00450 #endif
00451 #ifdef USB_CDC_USE_LEDS
00452 platform_leds_flash(2);
00453 #endif
00454 }
00455
00456 uns8 usb_cdc_rx_avail() { return cdc_rx_start != cdc_rx_end; }
00457 uns8 usb_cdc_tx_empty() { return cdc_tx_start == cdc_tx_end; }
00458
00459 void usb_cdc_print_str(char *str) {
00460
00461 uns8 count;
00462 buffer_descriptor *bd;
00463
00464 for(count = 0 ; str[count] != 0; count++)
00465 {
00466 usb_cdc_putc(str[count]);
00467 }
00468
00469
00470
00471
00472
00473
00474
00475
00476 }
00477
00478 void usb_SOF_callback(uns16 frame) {
00479
00480 usb_cdc_handle_tx();
00481 }
00482
00483 void usb_cdc_setup() {
00484
00485 current_bit_rate = SPBRG_9600;
00486
00487 dte_rate.as_long = 9600;
00488
00489 }
00490
00491 void usb_cdc_print_int(uns16 i) {
00492
00493 char buffer[6];
00494 uns8 count = 5;
00495 buffer[5] = '\0';
00496 do {
00497 count--;
00498 buffer[count] = '0' + i % 10;
00499 i = i / 10;
00500 } while (i > 0);
00501 while (buffer[count]) {
00502 usb_cdc_putc(buffer[count]);
00503 count++;
00504 }
00505
00506
00507
00508
00509
00510 }