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 cdc_rx_next = cdc_rx_end + 1;
00147 if (cdc_rx_next == CDC_RX_BUFFER_SIZE) {
00148 cdc_rx_next = 0;
00149 }
00150 if (cdc_rx_next != cdc_rx_start) {
00151 cdc_rx_buffer[cdc_rx_end] = buffer[count];
00152 cdc_rx_end = cdc_rx_next;
00153 }
00154 }
00155 } else {
00156 serial_print_str("data for ep ");
00157 serial_print_int(end_point);
00158 }
00159 }
00160
00161
00162
00163 void usb_ep_data_in_callback(uns8 end_point, uns16 byte_count) {
00164
00165 if (end_point == CDC_DATA_ENDPOINT) {
00166 usb_cdc_handle_tx();
00167 }
00168 }
00169
00170
00171
00172 void usb_cdc_putc(uns8 c) {
00173 uns8 cdc_tx_next;
00174 bit my_store_gie;
00175 #ifdef CDC_IDE_DEBUG
00176 return;
00177 #endif
00178
00179 cdc_tx_next = cdc_tx_end + 1;
00180 if (cdc_tx_next == CDC_TX_BUFFER_SIZE) {
00181 cdc_tx_next = 0;
00182 }
00183
00184 if ((!intcon.GIE) && (cdc_tx_next == cdc_tx_start)) {
00185 return;
00186 }
00187 while (cdc_tx_next == cdc_tx_start) {
00188 }
00189 my_store_gie = intcon.GIE;
00190 kill_interrupts();
00191
00192 cdc_tx_buffer[cdc_tx_end] = c;
00193 cdc_tx_end = cdc_tx_next;
00194
00195 intcon.GIE = my_store_gie;
00196
00197 }
00198
00199
00200 void usb_cdc_handle_tx()
00201 {
00202 uns8 cdc_tx_next;
00203 uns8 count;
00204 uns16 buffer_size;
00205 uns8 *buffer;
00206 buffer_descriptor *bd;
00207
00208 bd = ep_in_bd_location[CDC_DATA_ENDPOINT];
00209 if (test_bit(bd->stat, UOWN)) {
00210 return;
00211 }
00212
00213 buffer_size = ep_in_buffer_size[CDC_DATA_ENDPOINT];
00214 buffer = ep_in_buffer_location[CDC_DATA_ENDPOINT];
00215
00216 if (cdc_tx_end == cdc_tx_start) {
00217 return;
00218 }
00219
00220 start_crit_sec();
00221
00222 count = 0;
00223 while ((cdc_tx_end != cdc_tx_start) && (count < buffer_size)) {
00224
00225 cdc_tx_next = cdc_tx_start + 1;
00226 if (cdc_tx_next == CDC_TX_BUFFER_SIZE) {
00227 cdc_tx_next = 0;
00228 }
00229 buffer[count] = cdc_tx_buffer[cdc_tx_start];
00230 count++;
00231 cdc_tx_start = cdc_tx_next;
00232 }
00233 if (count > 0) {
00234 bd->count = count;
00235 bd->addr = (uns16)buffer;
00236
00237 toggle_bit(bd->stat, DTS);
00238 clear_bit(bd->stat, KEN);
00239 clear_bit(bd->stat, INCDIS);
00240 set_bit (bd->stat, DTSEN);
00241 clear_bit(bd->stat, BSTALL);
00242 clear_bit(bd->stat, BC9);
00243 clear_bit(bd->stat, BC8);
00244
00245 set_bit (bd->stat, UOWN);
00246 }
00247 end_crit_sec();
00248 }
00249
00250 uns8 usb_cdc_rx_avail() { return cdc_rx_start != cdc_rx_end; }
00251 uns8 usb_cdc_tx_empty() { return cdc_tx_start == cdc_tx_end; }
00252
00253 void usb_cdc_print_str(char *str) {
00254
00255 uns8 count;
00256 buffer_descriptor *bd;
00257
00258 for(count = 0 ; str[count] != 0; count++)
00259 {
00260 usb_cdc_putc(str[count]);
00261 }
00262
00263
00264
00265
00266
00267
00268
00269
00270 }
00271
00272 void usb_SOF_callback(uns16 frame) {
00273
00274 usb_cdc_handle_tx();
00275 }
00276
00277 void usb_cdc_setup() {
00278 line_coding *my_lc;
00279 my_lc = (line_coding*) &class_data;
00280 my_lc->dte_rate.as_long = 0x60090000;
00281 my_lc->stop_bits = 0;
00282 my_lc->data_bits = 8;
00283 my_lc->parity = 0;
00284 }