00001
00015 #include "config.h"
00016
00017
00018 #include "pic_usb.h"
00019 #include "pic_usb_buffer_mgt.h"
00020
00021 #ifdef CDC_DEBUG
00022 #include "pic_serial.h"
00023 #endif
00024
00025
00026 #include "usb_cdc_class.h"
00027
00028
00029 #include "memory.h"
00030
00031
00032
00033 #define req_SEND_ENCAPSULATED_COMMAND 0x00
00034 #define req_GET_ENCAPSULATED_RESPONSE 0x01
00035 #define req_SET_COMM_FEATURE 0x02
00036 #define req_GET_COMM_FEATURE 0x03
00037 #define req_CLEAR_COMM_FEATURE 0x04
00038 #define req_SET_LINE_CODING 0x20
00039 #define req_GET_LINE_CODING 0x21
00040 #define req_SET_CONTROL_LINE_STATE 0x22
00041 #define req_SEND_BREAK 0x23
00042
00043 typedef union _long_union{
00044 long as_long;
00045 uns8 as_byte_array[4];
00046 } long_union;
00047
00051 typedef struct _line_coding {
00052 long_union dte_rate;
00053 uns8 stop_bits;
00054 uns8 parity;
00055 uns8 data_bits;
00056 } line_coding;
00057
00059 uns8 cdc_tx_buffer[USB_CDC_TX_BUFFER_SIZE];
00061 uns8 cdc_tx_start=0;
00063 uns8 cdc_tx_end=0;
00064
00066 uns8 cdc_rx_buffer[USB_CDC_RX_BUFFER_SIZE];
00068 uns8 cdc_rx_start = 0;
00070 uns8 cdc_rx_end = 0;
00071
00072
00073 uns8 class_data[8];
00074
00075
00076 void usb_handle_class_request_callback(setup_data_packet sdp) {
00077
00078 switch (sdp.bRequest) {
00079 case req_SET_LINE_CODING:
00080
00081
00082 #ifdef CDC_DEBUG
00083 serial_print_str("SET_LINE ");
00084 #endif
00085 control_mode = cm_CTRL_WRITE_DATA_STAGE_CLASS;
00086 break;
00087 case req_GET_LINE_CODING:
00088 #ifdef CDC_DEBUG
00089 serial_print_str("GET_LINE ");
00090 serial_print_str(" len=");
00091 serial_print_int(sdp.wLength);
00092 serial_putc(' ');
00093 #endif
00094
00095 control_mode = cm_CTRL_READ_DATA_STAGE_CLASS;
00096
00097 usb_send_data( 0, &class_data, 7, 1);
00098
00099 control_mode = cm_CTRL_READ_AWAITING_STATUS;
00100
00101 break;
00102 case req_SET_CONTROL_LINE_STATE:
00103 #ifdef CDC_DEBUG
00104 serial_print_str("scls=");
00105 serial_print_int_hex(sdp.wValue);
00106 #endif
00107
00108 control_mode = cm_CTRL_WRITE_SENDING_STATUS;
00109 usb_send_status_ack();
00110
00111 break;
00112 default:
00113 #ifdef CDC_DEBUG
00114 serial_print_str("??r=");
00115 serial_print_int(sdp.bRequest);
00116 #endif
00117 }
00118 }
00119
00120 void usb_handle_class_ctrl_write_callback(uns8 *data, uns16 count) {
00121
00122 switch (usb_sdp.bRequest) {
00123 case req_SET_LINE_CODING:
00124
00125 memcpy( (void *)&class_data, (void *)data, count);
00126
00127
00128 control_mode = cm_CTRL_WRITE_SENDING_STATUS;
00129 usb_send_status_ack();
00130 line_coding *my_lc;
00131 my_lc = (line_coding*) &class_data;
00132 #ifdef CDC_DEBUG
00133 serial_print_int_hex(my_lc->dte_rate.as_byte_array[0]);
00134 serial_print_int_hex(my_lc->dte_rate.as_byte_array[1]);
00135 serial_print_int_hex(my_lc->dte_rate.as_byte_array[2]);
00136 serial_print_int_hex(my_lc->dte_rate.as_byte_array[3]);
00137 serial_print_str(" st=");
00138 serial_print_int(my_lc->stop_bits);
00139 serial_print_str(" p=");
00140 serial_print_int(my_lc->parity);
00141 serial_print_str(" db=");
00142 serial_print_int(my_lc->data_bits);
00143 #endif
00144 break;
00145 default:
00146 #ifdef CDC_DEBUG
00147 serial_print_str(" ??ctrl write cb req=");
00148 serial_print_int_hex(usb_sdp.bRequest);
00149 serial_putc(' ');
00150 #endif
00151 break;
00152 }
00153 }
00154
00155 void usb_handle_class_ctrl_read_callback() {
00156 switch (usb_sdp.bRequest) {
00157 case req_GET_LINE_CODING:
00158
00159 control_mode = cm_CTRL_READ_AWAITING_STATUS;
00160 break;
00161 default:
00162 #ifdef CDC_DEBUG
00163 serial_print_str(" cl read ?? ");
00164 serial_print_int(usb_sdp.bRequest);
00165 #endif
00166 }
00167
00168 }
00169
00170 void usb_ep_data_out_callback(uns8 end_point, uns8 *buffer,
00171 uns16 byte_count) {
00172 uns8 cdc_rx_next;
00173 #ifdef CDC_DEBUG
00174 serial_print_str(" EP data out: ");
00175 serial_print_int(byte_count);
00176 serial_print_str(" bytes ");
00177 #endif
00178
00179 if (end_point == USB_CDC_DATA_ENDPOINT) {
00180 uns8 count;
00181 for (count = 0; count < byte_count; count++) {
00182 cdc_rx_next = cdc_rx_end + 1;
00183 if (cdc_rx_next == USB_CDC_RX_BUFFER_SIZE) {
00184 cdc_rx_next = 0;
00185 }
00186 if (cdc_rx_next != cdc_rx_start) {
00187 cdc_rx_buffer[cdc_rx_end] = buffer[count];
00188 cdc_rx_end = cdc_rx_next;
00189 }
00190 }
00191 } else {
00192 #ifdef CDC_DEBUG
00193 serial_print_str("data for ep ");
00194 serial_print_int(end_point);
00195 #endif
00196 }
00197 }
00198
00199
00200
00201 void usb_ep_data_in_callback(uns8 end_point, uns16 byte_count) {
00202 #ifdef CDC_DEBUG
00203 serial_print_str(" EP data in: ");
00204 serial_print_int(byte_count);
00205 serial_print_str(" bytes ");
00206 #endif
00207
00208 if (end_point == USB_CDC_DATA_ENDPOINT) {
00209 usb_cdc_handle_tx();
00210 }
00211 }
00212
00213
00214
00215 void usb_cdc_putc(uns8 c) {
00216 uns8 cdc_tx_next;
00217 bit my_store_gie;
00218 #ifdef CDC_IDE_DEBUG
00219 return;
00220 #endif
00221
00222 cdc_tx_next = cdc_tx_end + 1;
00223 if (cdc_tx_next == USB_CDC_TX_BUFFER_SIZE) {
00224 cdc_tx_next = 0;
00225 }
00226
00227 if ((!intcon.GIE) && (cdc_tx_next == cdc_tx_start)) {
00228 return;
00229 }
00230 while (cdc_tx_next == cdc_tx_start) {
00231 }
00232 my_store_gie = intcon.GIE;
00233 kill_interrupts();
00234
00235 cdc_tx_buffer[cdc_tx_end] = c;
00236 cdc_tx_end = cdc_tx_next;
00237
00238 intcon.GIE = my_store_gie;
00239
00240 }
00241
00242 uns8 usb_cdc_getc(void)
00243 {
00244 uns8 cdc_rx_char, cdc_rx_next;
00245
00246 while(cdc_rx_end == cdc_rx_start);
00247
00248 start_crit_sec();
00249
00250 cdc_rx_char = cdc_rx_buffer[cdc_rx_start];
00251 cdc_rx_start++;
00252 if (cdc_rx_start == USB_CDC_RX_BUFFER_SIZE) {
00253 cdc_rx_start = 0;
00254 }
00255
00256 end_crit_sec();
00257
00258 return (cdc_rx_char);
00259
00260 }
00261
00262
00263 void usb_cdc_handle_tx()
00264 {
00265 uns8 cdc_tx_next;
00266 uns8 count;
00267 uns16 buffer_size;
00268 uns8 *buffer;
00269 buffer_descriptor *bd;
00270
00271 bd = ep_in_bd_location[USB_CDC_DATA_ENDPOINT];
00272 if (test_bit(bd->stat, UOWN)) {
00273 return;
00274 }
00275
00276 buffer_size = ep_in_buffer_size[USB_CDC_DATA_ENDPOINT];
00277 buffer = ep_in_buffer_location[USB_CDC_DATA_ENDPOINT];
00278
00279 if (cdc_tx_end == cdc_tx_start) {
00280 return;
00281 }
00282 #ifdef CDC_DEBUG
00283 serial_putc('<');
00284 #endif
00285 start_crit_sec();
00286
00287 count = 0;
00288 while ((cdc_tx_end != cdc_tx_start) && (count < buffer_size)) {
00289
00290 cdc_tx_next = cdc_tx_start + 1;
00291 if (cdc_tx_next == USB_CDC_TX_BUFFER_SIZE) {
00292 cdc_tx_next = 0;
00293 }
00294 buffer[count] = cdc_tx_buffer[cdc_tx_start];
00295 #ifdef CDC_DEBUG
00296 serial_putc(buffer[count]);
00297 #endif
00298 count++;
00299 cdc_tx_start = cdc_tx_next;
00300 }
00301 if (count > 0) {
00302 bd->count = count;
00303 bd->addr = (uns16)buffer;
00304
00305 toggle_bit(bd->stat, DTS);
00306 clear_bit(bd->stat, KEN);
00307 clear_bit(bd->stat, INCDIS);
00308 set_bit (bd->stat, DTSEN);
00309 clear_bit(bd->stat, BSTALL);
00310 clear_bit(bd->stat, BC9);
00311 clear_bit(bd->stat, BC8);
00312
00313 set_bit (bd->stat, UOWN);
00314 }
00315 end_crit_sec();
00316 #ifdef CDC_DEBUG
00317 serial_putc('>');
00318 serial_print_str("send=");
00319 serial_print_int(count);
00320 serial_putc(' ');
00321 #endif
00322
00323 }
00324
00325 uns8 usb_cdc_rx_avail() { return cdc_rx_start != cdc_rx_end; }
00326 uns8 usb_cdc_tx_empty() { return cdc_tx_start == cdc_tx_end; }
00327
00328 void usb_cdc_print_str(char *str) {
00329
00330 uns8 count;
00331 buffer_descriptor *bd;
00332
00333 for(count = 0 ; str[count] != 0; count++)
00334 {
00335 usb_cdc_putc(str[count]);
00336 }
00337
00338
00339
00340
00341
00342
00343
00344
00345 }
00346
00347 void usb_SOF_callback(uns16 frame) {
00348
00349 usb_cdc_handle_tx();
00350 }
00351
00352 void usb_cdc_setup() {
00353 line_coding *my_lc;
00354 my_lc = (line_coding*) &class_data;
00355 my_lc->dte_rate.as_long = 0x80250000;
00356 my_lc->stop_bits = 0;
00357 my_lc->data_bits = 8;
00358 my_lc->parity = 0;
00359 }
00360
00361 void usb_cdc_print_int(uns16 i) {
00362
00363 char buffer[6];
00364 uns8 count = 5;
00365 buffer[5] = '\0';
00366 do {
00367 count--;
00368 buffer[count] = '0' + i % 10;
00369 i = i / 10;
00370 } while (i > 0);
00371 while (buffer[count]) {
00372 usb_cdc_putc(buffer[count]);
00373 count++;
00374 }
00375
00376
00377
00378
00379
00380 }