Contiki 2.6
|
00001 #include "cdc_eem.h" 00002 #include "contiki.h" 00003 #include "usb_drv.h" 00004 #include "usb_descriptors.h" 00005 #include "usb_specific_request.h" 00006 #include "rndis/rndis_task.h" 00007 #include "rndis/rndis_protocol.h" 00008 #include "uip.h" 00009 #include "sicslow_ethernet.h" 00010 #include <stdio.h> 00011 00012 #include <avr/pgmspace.h> 00013 #include <util/delay.h> 00014 00015 #define BUF ((struct uip_eth_hdr *)&uip_buf[0]) 00016 #define PRINTF printf 00017 #define PRINTF_P printf_P 00018 00019 extern uint8_t usb_eth_data_buffer[64]; 00020 00021 00022 //_____ M A C R O S ________________________________________________________ 00023 00024 00025 #define EEMCMD_ECHO 0x00 ///bmEEMCmd Echo 00026 #define EEMCMD_ECHO_RESPONSE 0x01 ///bmEEMCmd Echo Response 00027 #define EEMCMD_SUSPEND_HINT 0x02 ///bmEEMCmd Suspend Hint 00028 #define EEMCMD_RESPONSE_HINT 0x03 ///bmEEMCmd Response Hint 00029 #define EEMCMD_RESPONSE_COMPLETE_HINT 0x04 ///bmEEMCmd Response Complete Hint 00030 #define EEMCMD_TICKLE 0x05 ///bmEEMCmd Tickle 00031 00032 00033 void cdc_eem_configure_endpoints() { 00034 usb_configure_endpoint(TX_EP, \ 00035 TYPE_BULK, \ 00036 DIRECTION_IN, \ 00037 SIZE_64, \ 00038 TWO_BANKS, \ 00039 NYET_ENABLED); 00040 00041 usb_configure_endpoint(RX_EP, \ 00042 TYPE_BULK, \ 00043 DIRECTION_OUT, \ 00044 SIZE_64, \ 00045 TWO_BANKS, \ 00046 NYET_ENABLED); 00047 Usb_reset_endpoint(TX_EP); 00048 Usb_reset_endpoint(RX_EP); 00049 } 00050 00051 void cdc_eem_process(void) { 00052 uint16_t datalength; 00053 uint8_t bytecounter, headercounter; 00054 uint16_t i; 00055 00056 #ifdef USB_ETH_HOOK_INIT 00057 static uint8_t doInit = 1; 00058 if (doInit) { 00059 USB_ETH_HOOK_INIT(); 00060 doInit = 0; 00061 } 00062 #endif 00063 00064 //Connected! 00065 Led0_on(); 00066 00067 Usb_select_endpoint(RX_EP); 00068 00069 //If we have data and a free buffer 00070 if(Is_usb_receive_out() && (uip_len == 0)) { 00071 00072 //Read how much (endpoint only stores up to 64 bytes anyway) 00073 bytecounter = Usb_byte_counter_8(); 00074 00075 //EEM uses 2 bytes as a header 00076 headercounter = 2; 00077 00078 uint8_t fail = 0; 00079 00080 //Hmm.. what's going on here? 00081 if (bytecounter < headercounter) { 00082 Usb_ack_receive_out(); 00083 //TODO CO done = 1; 00084 } 00085 00086 //Read EEM Header 00087 i = 0; 00088 while (headercounter) { 00089 usb_eth_data_buffer[i] = Usb_read_byte(); 00090 bytecounter--; 00091 headercounter--; 00092 i++; 00093 } 00094 00095 //Order is LSB/MSB, so MSN is in usb_eth_data_buffer[1] 00096 //Bit 15 indicates command packet when set 00097 if (usb_eth_data_buffer[1] & 0x80) { 00098 //not a data payload 00099 datalength = 0; 00100 } else { 00101 //'0' indicates data packet 00102 //Length is lower 14 bits 00103 datalength = usb_eth_data_buffer[0] | ((usb_eth_data_buffer[1] & 0x3F) << 8); 00104 } 00105 00106 /* EEM Command Packet */ 00107 if ((datalength == 0) && (fail == 0)) 00108 { 00109 uint8_t command; 00110 uint16_t echoLength; 00111 00112 //Strip command off 00113 command = usb_eth_data_buffer[1] & 0x38; 00114 command = command >> 3; 00115 00116 //Decode command type 00117 switch (command) 00118 { 00119 /* Echo Request */ 00120 case EEMCMD_ECHO: 00121 00122 //Get echo length 00123 echoLength = (usb_eth_data_buffer[1] & 0x07) << 8; //MSB 00124 echoLength |= usb_eth_data_buffer[0]; //LSB 00125 00126 //TODO: everything. oops. 00127 00128 break; 00129 00130 /* Everything else: Whatever. */ 00131 case EEMCMD_ECHO_RESPONSE: 00132 case EEMCMD_SUSPEND_HINT: 00133 case EEMCMD_RESPONSE_HINT: 00134 case EEMCMD_RESPONSE_COMPLETE_HINT: 00135 case EEMCMD_TICKLE: 00136 break; 00137 00138 default: break; 00139 } 00140 } 00141 /* EEM Data Packet */ 00142 else if (datalength && (fail == 0)) 00143 { 00144 //Looks like we've got a live one 00145 #ifdef USB_ETH_HOOK_RX_START 00146 USB_ETH_HOOK_RX_START(); 00147 #endif 00148 00149 uint16_t bytes_received = 0; 00150 uint16_t dataleft = datalength; 00151 U8 * buffer = uip_buf; 00152 00153 while(dataleft) 00154 { 00155 *buffer++ = Usb_read_byte(); 00156 00157 dataleft--; 00158 bytecounter--; 00159 bytes_received++; 00160 00161 //Check if endpoint is done but we are expecting more data 00162 if ((bytecounter == 0) && (dataleft)) 00163 { 00164 //ACK previous data 00165 Usb_ack_receive_out(); 00166 00167 //Wait for new data 00168 while (!Is_usb_receive_out()); 00169 00170 //Get new data 00171 bytecounter = Usb_byte_counter_8(); 00172 00173 //ZLP? 00174 if (bytecounter == 0) 00175 { 00176 //Incomplete!! 00177 break; 00178 } 00179 } 00180 } 00181 00182 //Ack final data packet 00183 Usb_ack_receive_out(); 00184 00185 #ifdef USB_ETH_HOOK_RX_END 00186 USB_ETH_HOOK_RX_END(); 00187 #endif 00188 00189 //Packet has CRC, nobody wants that garbage 00190 datalength -= 4; 00191 00192 //Send data over RF or to local stack 00193 if(datalength <= USB_ETH_MTU) { 00194 USB_ETH_HOOK_HANDLE_INBOUND_PACKET(uip_buf,datalength); 00195 } else { 00196 USB_ETH_HOOK_RX_ERROR("Oversized packet"); 00197 } 00198 } //if (datalength) 00199 } //if(Is_usb_receive_out() && (uip_len == 0)) 00200 } 00201 00202 00203 /** 00204 \brief Send a single ethernet frame using EEM 00205 */ 00206 uint8_t eem_send(uint8_t * senddata, uint16_t sendlen, uint8_t led) 00207 { 00208 //Make a header 00209 uint8_t header[2]; 00210 00211 //Fake CRC! Add 4 to length for CRC 00212 sendlen += 4; 00213 header[0] = (sendlen >> 8) & 0x3f; 00214 header[1] = sendlen & 0xff; 00215 00216 //We send CRC seperatly.. 00217 sendlen -= 4; 00218 00219 //Send Data 00220 Usb_select_endpoint(TX_EP); 00221 //Usb_send_in(); 00222 00223 //Wait for ready 00224 if(usb_endpoint_wait_for_write_enabled()!=0) { 00225 USB_ETH_HOOK_TX_ERROR("Timeout: write enabled"); 00226 return 0; 00227 } 00228 00229 #ifdef USB_ETH_HOOK_TX_START 00230 USB_ETH_HOOK_TX_START(); 00231 #endif 00232 00233 //Send header (LSB then MSB) 00234 Usb_write_byte(header[1]); 00235 Usb_write_byte(header[0]); 00236 00237 //Send packet 00238 while(sendlen) { 00239 Usb_write_byte(*senddata); 00240 senddata++; 00241 sendlen--; 00242 00243 //If endpoint is full, send data in 00244 //And then wait for data to transfer 00245 if (!Is_usb_write_enabled()) { 00246 Usb_send_in(); 00247 00248 if(usb_endpoint_wait_for_write_enabled()!=0) { 00249 USB_ETH_HOOK_TX_ERROR("Timeout: write enabled"); 00250 return 0; 00251 } 00252 } 00253 00254 } 00255 00256 //CRC = 0xdeadbeef 00257 //Linux kernel 2.6.31 needs 0xdeadbeef in wrong order, 00258 //like this: uint8_t crc[4] = {0xef, 0xbe, 0xad, 0xde}; 00259 //This is fixed in 2.6.32 to the correct order (0xde, 0xad, 0xbe, 0xef) 00260 uint8_t crc[4] = {0xde, 0xad, 0xbe, 0xef}; 00261 00262 sendlen = 4; 00263 uint8_t i = 0; 00264 00265 //Send fake CRC 00266 while(sendlen) { 00267 Usb_write_byte(crc[i]); 00268 i++; 00269 sendlen--; 00270 00271 //If endpoint is full, send data in 00272 //And then wait for data to transfer 00273 if (!Is_usb_write_enabled()) { 00274 Usb_send_in(); 00275 if(usb_endpoint_wait_for_write_enabled()!=0) { 00276 USB_ETH_HOOK_TX_ERROR("Timeout: write enabled"); 00277 return 0; 00278 } 00279 } 00280 } 00281 00282 //Send last data in - also handles sending a ZLP if needed 00283 Usb_send_in(); 00284 00285 #ifdef USB_ETH_HOOK_TX_END 00286 USB_ETH_HOOK_TX_END(); 00287 #endif 00288 00289 //Wait for ready 00290 if(usb_endpoint_wait_for_IN_ready()!=0) { 00291 USB_ETH_HOOK_TX_ERROR("Timeout: IN ready"); 00292 return 0; 00293 } 00294 00295 return 1; 00296 }