00001
00015 #include "config.h"
00016
00017
00018 #include "pic_usb.h"
00019 #include "pic_usb_buffer_mgt.h"
00020 #include "pic_serial.h"
00021
00022
00023 #include "usb_cdc_class.h"
00024
00025
00026 #include "memory.h"
00027
00028
00029
00030 #define req_SEND_ENCAPSULATED_COMMAND 0x00
00031 #define req_GET_ENCAPSULATED_RESPONSE 0x01
00032 #define req_SET_COMM_FEATURE 0x02
00033 #define req_GET_COMM_FEATURE 0x03
00034 #define req_CLEAR_COMM_FEATURE 0x04
00035 #define req_SET_LINE_CODING 0x20
00036 #define req_GET_LINE_CODING 0x21
00037 #define req_SET_CONTROL_LINE_STATE 0x22
00038 #define req_SEND_BREAK 0x23
00039
00040 typedef union _long_union{
00041 long as_long;
00042 uns8 as_byte_array[4];
00043 } long_union;
00044
00045
00046 typedef struct _line_coding {
00047 long_union dte_rate;
00048 uns8 stop_bits;
00049 uns8 parity;
00050 uns8 data_bits;
00051 } line_coding;
00052
00054 uns8 cdc_tx_buffer[CDC_TX_BUFFER_SIZE];
00056 uns8 cdc_tx_start=0;
00058 uns8 cdc_tx_end=0;
00059
00061 uns8 cdc_rx_buffer[CDC_RX_BUFFER_SIZE];
00063 uns8 cdc_rx_start = 0;
00065 uns8 cdc_rx_end = 0;
00066
00067
00068 uns8 class_data[8];
00069
00070 void usb_handle_class_request(setup_data_packet sdp) {
00071
00072 switch (sdp.bRequest) {
00073 case req_SET_LINE_CODING:
00074
00075 serial_print_str("SET_LINE ");
00076 control_mode = cm_CTRL_WRITE_DATA_STAGE_CLASS;
00077 break;
00078 case req_GET_LINE_CODING:
00079 serial_print_str("GET_LINE ");
00080 control_mode = cm_CTRL_READ_DATA_STAGE_CLASS;
00081
00082 usb_send_data( 0, &class_data, 8, 1);
00083
00084 break;
00085 case req_SET_CONTROL_LINE_STATE:
00086 serial_print_str("scls=");
00087 serial_print_int_hex(sdp.wValue);
00088
00089 control_mode = cm_CTRL_WRITE_SENDING_STATUS;
00090 usb_send_status_ack();
00091 break;
00092 default:
00093 serial_print_str("??r=");
00094 serial_print_int(sdp.bRequest);
00095 }
00096 }
00097
00098 void usb_handle_ctrl_write_class(uns8 *data, uns16 count) {
00099
00100 switch (usb_sdp.bRequest) {
00101 case req_SET_LINE_CODING:
00102
00103 memcpy( (void *)&class_data, (void *)data, count);
00104
00105
00106 control_mode = cm_CTRL_WRITE_SENDING_STATUS;
00107 usb_send_status_ack();
00108 line_coding *my_lc;
00109 my_lc = (line_coding*) &class_data;
00110 serial_print_int_hex(my_lc->dte_rate.as_byte_array[0]);
00111 serial_print_int_hex(my_lc->dte_rate.as_byte_array[1]);
00112 serial_print_int_hex(my_lc->dte_rate.as_byte_array[2]);
00113 serial_print_int_hex(my_lc->dte_rate.as_byte_array[3]);
00114 serial_print_str(" st=");
00115 serial_print_int(my_lc->stop_bits);
00116 serial_print_str(" p=");
00117 serial_print_int(my_lc->parity);
00118 serial_print_str(" db=");
00119 serial_print_int(my_lc->data_bits);
00120
00121 break;
00122 }
00123 }
00124
00125 void usb_handle_ctrl_read_class() {
00126 switch (usb_sdp.bRequest) {
00127 case req_GET_LINE_CODING:
00128
00129 control_mode = cm_CTRL_READ_AWAITING_STATUS;
00130 break;
00131 default:
00132 serial_print_str(" cl read ?? ");
00133 serial_print_int(usb_sdp.bRequest);
00134 }
00135
00136 }
00137
00138 void usb_ep_data_out_callback(uns8 end_point, uns8 *buffer,
00139 uns16 byte_count) {
00140 uns8 cdc_rx_next;
00141
00142
00143 if (end_point == CDC_DATA_ENDPOINT) {
00144 uns8 count;
00145 for (count = 0; count < byte_count; count++) {
00146
00147 cdc_rx_next = cdc_rx_end + 1;
00148 if (cdc_rx_next == CDC_RX_BUFFER_SIZE) {
00149 cdc_rx_next = 0;
00150 }
00151 if (cdc_rx_next != cdc_rx_start) {
00152 cdc_rx_buffer[cdc_rx_end] = buffer[count];
00153 cdc_rx_end = cdc_rx_next;
00154 }
00155 }
00156 } else {
00157 serial_print_str("data for ep ");
00158 serial_print_int(end_point);
00159 }
00160 }
00161
00162 void usb_ep_data_in_callback(uns8 end_point, uns16 byte_count) {
00163
00164 usb_cdc_handle_tx();
00165 }
00166
00167
00168
00169 void usb_cdc_putc(uns8 c) {
00170 uns8 cdc_tx_next;
00171 bit my_store_gie;
00172 #ifdef CDC_IDE_DEBUG
00173 return;
00174 #endif
00175
00176 cdc_tx_next = cdc_tx_end + 1;
00177 if (cdc_tx_next == CDC_TX_BUFFER_SIZE) {
00178 cdc_tx_next = 0;
00179 }
00180
00181 if ((!intcon.GIE) && (cdc_tx_next == cdc_tx_start)) {
00182 return;
00183 }
00184 while (cdc_tx_next == cdc_tx_start) {
00185 }
00186 my_store_gie = intcon.GIE;
00187 kill_interrupts();
00188
00189 cdc_tx_buffer[cdc_tx_end] = c;
00190 cdc_tx_end = cdc_tx_next;
00191
00192 intcon.GIE = my_store_gie;
00193
00194 }
00195
00196
00197 void usb_cdc_handle_tx()
00198 {
00199 uns8 cdc_tx_next;
00200 uns8 count;
00201 uns16 buffer_size;
00202 uns8 *buffer;
00203 buffer_descriptor *bd;
00204
00205 bd = ep_in_bd_location[CDC_DATA_ENDPOINT];
00206 if (test_bit(bd->stat, UOWN)) {
00207 return;
00208 }
00209
00210 buffer_size = ep_in_buffer_size[CDC_DATA_ENDPOINT];
00211 buffer = ep_in_buffer_location[CDC_DATA_ENDPOINT];
00212
00213 if (cdc_tx_end == cdc_tx_start) {
00214 return;
00215 }
00216
00217 start_crit_sec();
00218
00219 count = 0;
00220 while ((cdc_tx_end != cdc_tx_start) && (count < buffer_size)) {
00221
00222 cdc_tx_next = cdc_tx_start + 1;
00223 if (cdc_tx_next == CDC_TX_BUFFER_SIZE) {
00224 cdc_tx_next = 0;
00225 }
00226 buffer[count] = cdc_tx_buffer[cdc_tx_start];
00227 count++;
00228 cdc_tx_start = cdc_tx_next;
00229 }
00230 if (count > 0) {
00231 bd->count = count;
00232 bd->addr = (uns16)buffer;
00233
00234 toggle_bit(bd->stat, DTS);
00235 clear_bit(bd->stat, KEN);
00236 clear_bit(bd->stat, INCDIS);
00237 set_bit (bd->stat, DTSEN);
00238 clear_bit(bd->stat, BSTALL);
00239 clear_bit(bd->stat, BC9);
00240 clear_bit(bd->stat, BC8);
00241
00242 set_bit (bd->stat, UOWN);
00243 }
00244 end_crit_sec();
00245 }
00246
00247 uns8 usb_cdc_rx_avail() { return cdc_rx_start != cdc_rx_end; }
00248 uns8 usb_cdc_tx_empty() { return cdc_tx_start == cdc_tx_end; }
00249
00250 void usb_cdc_print_str(char *str) {
00251
00252 uns8 count;
00253 buffer_descriptor *bd;
00254
00255 for(count = 0 ; str[count] != 0; count++)
00256 {
00257 usb_cdc_putc(str[count]);
00258 }
00259
00260
00261
00262
00263
00264
00265
00266
00267 }
00268
00269 void usb_SOF_callback(uns16 frame) {
00270
00271 usb_cdc_handle_tx();
00272 }
00273
00274 void usb_cdc_setup() {
00275 line_coding *my_lc;
00276 my_lc = (line_coding*) &class_data;
00277 my_lc->dte_rate.as_long = 0x60090000;
00278 my_lc->stop_bits = 0;
00279 my_lc->data_bits = 8;
00280 my_lc->parity = 0;
00281 }
00282