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
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 #include "enc28j60_spi_tx.h"
00046 #include "enc28j60_spi.h"
00047 #include "fspi.h"
00048
00049
00050 unsigned int tx_ptr;
00051 unsigned int tx_end_ptr;
00052 unsigned int TXST;
00053 unsigned int TXND;
00054
00055
00056 unsigned char act_tx;
00057
00058
00059 #define LOCKED 1
00060 #define UNLOCKED 0
00061 char tx1_lock = UNLOCKED;
00062 char tx2_lock = UNLOCKED;
00063 char tx3_lock = UNLOCKED;
00064
00065
00066 char tx1_protocol;
00067 char tx2_protocol;
00068 char tx3_protocol;
00069
00070
00071 unsigned int tx1_ptr;
00072 unsigned int tx2_ptr;
00073 unsigned int tx3_ptr;
00074
00075 unsigned int tx1_end_ptr;
00076 unsigned int tx2_end_ptr;
00077 unsigned int tx3_end_ptr;
00078
00079
00080 char tx_protocol(unsigned char protocol);
00081
00082
00083
00084
00085
00086
00090 char tx_init(unsigned char protocol){
00091
00092 int timer = TIMEOUT;
00093
00094
00095 while((read_reg8(ECON1,NO_DUMMY) & ECON1_TXRTS) && (timer-- > 0) );
00096
00097 if(timer == 0)
00098 return -1;
00099
00100
00101 if(protocol == UDP_PROTO){
00102
00103 if(tx1_lock == LOCKED){
00104 return -1;
00105 }
00106
00107 tx1_lock = LOCKED;
00108 tx_save(act_tx);
00109
00110 TXST = TX1ST;
00111 TXND = TX1ND;
00112 act_tx = TX1;
00113
00114 select_bank(0);
00115
00116 write_reg16(ETXST,TXST);
00117 write_reg16(ETXND,TXST);
00118
00119 tx_ptr = TX1ST;
00120 tx1_ptr = TX1ST;
00121 tx1_end_ptr = TX1ST;
00122 tx1_protocol = protocol;
00123
00124 return tx_protocol(protocol);
00125 }
00126
00127
00128 else if(protocol == TCP_PROTO){
00129
00130 if(tx3_lock == LOCKED){
00131 return -1;
00132 }
00133 tx3_lock = LOCKED;
00134
00135 tx_save(act_tx);
00136
00137 TXST = TX3ST;
00138 TXND = TX3ND;
00139 act_tx = TX3;
00140
00141 select_bank(0);
00142
00143 write_reg16(ETXST,TXST);
00144 write_reg16(ETXND,TXST);
00145
00146 tx_ptr = TX3ST;
00147 tx3_ptr = TX3ST;
00148 tx3_end_ptr = TX3ST;
00149 tx3_protocol = protocol;
00150
00151 return tx_protocol(protocol);
00152 }
00153
00154
00155 else if((protocol == ICMP_PROTO) | (protocol == TCP_PROTO_HEADER_ONLY)){
00156
00157 if(tx2_lock == LOCKED){
00158 return -1;
00159 }
00160
00161 tx2_lock = LOCKED;
00162 tx_save(act_tx);
00163
00164 TXST = TX2ST;
00165 TXND = TX2ND;
00166 act_tx = TX2;
00167
00168 select_bank(0);
00169
00170 write_reg16(ETXST,TXST);
00171 write_reg16(ETXND,TXST);
00172
00173 tx_ptr = TX2ST;
00174 tx2_ptr = TX2ST;
00175 tx2_end_ptr = TX2ST;
00176 tx2_protocol = protocol;
00177
00178 return tx_protocol(protocol);
00179 }
00180 else if((protocol == ARP_PROTO)){
00181
00182 tx_save(act_tx);
00183
00184 TXST = TX4ST;
00185 TXND = TX4ND;
00186 act_tx = TX4;
00187
00188 select_bank(0);
00189
00190 write_reg16(ETXST,TXST);
00191 write_reg16(ETXND,TXST);
00192
00193 tx_ptr = TX4ST;
00194
00195 return tx_protocol(protocol);
00196 }
00197
00198
00199 return -1;
00200 }
00201
00202
00203 char tx_protocol(unsigned char protocol){
00204
00205 switch(protocol){
00206 case TCP_PROTO_HEADER_ONLY:
00207 case TCP_PROTO:
00208 tx_ptr = TXST + CTRL_LEN + ETH_HEADER_LEN + IP_HEADER_LEN + TCP_HEADER_LEN;
00209 break;
00210 case UDP_PROTO:
00211 tx_ptr = TXST + CTRL_LEN + ETH_HEADER_LEN + IP_HEADER_LEN + UDP_HEADER_LEN;
00212 break;
00213 case ICMP_PROTO:
00214 tx_ptr = TXST + CTRL_LEN + ETH_HEADER_LEN + IP_HEADER_LEN + ICMP_HEADER_LEN;
00215 break;
00216 case ARP_PROTO:
00217 tx_ptr = TXST + CTRL_LEN + ETH_HEADER_LEN;
00218 break;
00219 default:
00220 return -1;
00221 }
00222
00223 select_bank(0);
00224 write_reg16(EWRPT,tx_ptr);
00225
00226 return 0;
00227 }
00228
00233 void tx_rewind(){
00234
00235 switch(act_tx){
00236 case TX1:
00237 tx_protocol(tx1_protocol);
00238 break;
00239 case TX2:
00240 tx_protocol(tx2_protocol);
00241 break;
00242 case TX3:
00243 tx_protocol(tx3_protocol);
00244 break;
00245 }
00246 }
00247
00248
00249
00253 void tx_seek(unsigned char header){
00254 switch(header){
00255 case CTRL:
00256 tx_ptr = TXST;
00257 break;
00258 case ETH_HEADER:
00259 tx_ptr = TXST + CTRL_LEN;
00260 break;
00261 case IP_HEADER:
00262 tx_ptr = TXST + CTRL_LEN + ETH_HEADER_LEN;
00263 break;
00264 case ICMP_HEADER:
00265 case TCP_HEADER:
00266 case UDP_HEADER:
00267 tx_ptr = TXST + CTRL_LEN + ETH_HEADER_LEN + IP_HEADER_LEN;
00268 break;
00269 }
00270
00271 select_bank(0);
00272 write_reg16(EWRPT,tx_ptr);
00273 return;
00274 }
00275
00281 inline void tx_close(){
00282 select_bank(0);
00283 tx_end_ptr = tx_ptr;
00284 write_reg16(ETXND,tx_end_ptr-1);
00285 }
00286
00287
00291 void tx_save(unsigned char buffer){
00292
00293
00294 switch(buffer){
00295 case TX1:
00296 tx1_ptr = tx_ptr;
00297 tx1_end_ptr = tx_end_ptr;
00298 break;
00299
00300 case TX2:
00301 tx2_ptr = tx_ptr;
00302 tx2_end_ptr = tx_end_ptr;
00303 break;
00304
00305 case TX3:
00306 tx3_ptr = tx_ptr;
00307 tx3_end_ptr = tx_end_ptr;
00308 break;
00309 }
00310 return;
00311 }
00312
00313
00317 void tx_load(unsigned char buffer){
00318
00319 switch(buffer){
00320 case TX1:
00321 TXST = TX1ST;
00322 TXND = TX1ND;
00323 tx_ptr = tx1_ptr;
00324 tx_end_ptr = tx1_end_ptr;
00325 act_tx = TX1;
00326 break;
00327
00328 case TX2:
00329 TXST = TX2ST;
00330 TXND = TX2ND;
00331 tx_ptr = tx2_ptr;
00332 tx_end_ptr = tx2_end_ptr;
00333 act_tx = TX2;
00334 break;
00335
00336 case TX3:
00337 TXST = TX3ST;
00338 TXND = TX3ND;
00339 tx_ptr = tx3_ptr;
00340 tx_end_ptr = tx3_end_ptr;
00341 act_tx = TX3;
00342 break;
00343 }
00344
00345 write_reg16(EWRPT,tx_ptr);
00346 write_reg16(ETXST,TXST);
00347 write_reg16(ETXND,tx_end_ptr-1);
00348
00349
00350 return;
00351 }
00352
00356 unsigned char tx_act(){
00357
00358 return act_tx;
00359 }
00360
00364 unsigned char tx_putc(char c){
00365
00366 if(tx_ptr > TXND)
00367 return 0;
00368 else{
00369 spi_putc(c);
00370 tx_ptr++;
00371 return 1;
00372 }
00373 }
00374
00378 unsigned int tx_write(void* ptr, unsigned int length){
00379
00380 int remaining = tx_left();
00381
00382 if(tx_ptr > TXND)
00383 return 0;
00384 else if(length >= remaining){
00385 spi_write(ptr, remaining);
00386 tx_ptr += remaining;
00387 return remaining;
00388 }
00389 else{
00390 spi_write(ptr, length);
00391 tx_ptr += length;
00392 return length;
00393 }
00394 return 0;
00395 }
00396
00400 unsigned int tx_fill(unsigned char value, unsigned int length){
00401
00402 int remaining = tx_left();
00403
00404 if(tx_ptr > TXND)
00405 return 0;
00406 else if(length >= remaining){
00407 spi_fill(value, remaining);
00408 tx_ptr += remaining;
00409 return remaining;
00410 }
00411 else{
00412 spi_fill(value, length);
00413 tx_ptr += length;
00414 return length;
00415 }
00416 return 0;
00417 }
00418
00423 unsigned int tx_skip(unsigned int length){
00424
00425 int remaining = tx_left();
00426
00427 if(tx_ptr > TXND)
00428 return 0;
00429 else if(length >= remaining){
00430 tx_ptr += remaining;
00431 write_reg16(EWRPT,tx_ptr);
00432 return remaining;
00433 }
00434 else{
00435 tx_ptr += length;
00436 write_reg16(EWRPT,tx_ptr);
00437 return length;
00438 }
00439 return 0;
00440 }
00441
00445 char tx_send(){
00446
00447 int timer = TIMEOUT;
00448
00449 while(( (read_reg8(ECON1,NO_DUMMY) & ECON1_TXRTS) > 0) & (timer-- > 0) );
00450
00451
00452 if(timer == 0){
00453 if(act_tx == TX1){
00454 tx_unlock(TX1);
00455 }
00456 else if(act_tx == TX2){
00457 tx_unlock(TX2);
00458 }
00459 return -1;
00460 }
00461
00462
00463
00464 select_bank(2);
00465 write_reg8(MACON3,MACON3_PADCFG0 | MACON3_TXCRCEN | MACON3_FULDPX);
00466
00467 bf_set(ECON1,ECON1_TXRTS);
00468
00469 if(act_tx == TX1){
00470 tx_unlock(TX1);
00471 }
00472 else if(act_tx == TX2){
00473 tx_unlock(TX2);
00474 }
00475 return 0;
00476 }
00477
00478
00482 inline unsigned int tx_left(){
00483
00484 return TXND - tx_ptr +1;
00485 }
00486
00490 inline unsigned int tx_data_len(){
00491
00492 return tx_end_ptr - tx_ptr;
00493 }
00494
00498 unsigned int tx_checksum(){
00499
00500
00501 select_bank(0);
00502 write_reg16(EDMAST,tx_ptr);
00503 write_reg16(EDMAND,tx_end_ptr -1);
00504 bf_clear(EIR,EIR_DMAIF);
00505
00506 bf_set(ECON1,ECON1_CSUMEN | ECON1_DMAST);
00507
00508 while((read_reg8(EIR,NO_DUMMY) & EIR_DMAIF ) == 0);
00509
00510 return read_reg16(EDMACS,NO_DUMMY);
00511
00512 }
00513
00514
00518 inline void tx_unlock(unsigned char buffer){
00519
00520 if(buffer == TX1)
00521 tx1_lock = UNLOCKED;
00522 else if(buffer == TX2)
00523 tx2_lock = UNLOCKED;
00524 else if(buffer == TX3)
00525 tx3_lock = UNLOCKED;
00526
00527 return;
00528 }