PlatformIO package of the Teensy core framework compatible with GCC 10 & C++20
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

560 lines
18KB

  1. #define HACKED //Limits number of times usbthread loops per second
  2. void usbthread() {
  3. uint32_t cc = 0;
  4. while(1) {
  5. myusb.Task();
  6. asix1.read();
  7. checkLink();
  8. if(fnet_netif_is_initialized(current_netif)){
  9. fnet_poll();
  10. fnet_service_poll();
  11. }
  12. #ifdef STATS
  13. LoopedUSB++;
  14. #endif
  15. #ifdef HACKED
  16. cc++;
  17. if ( cc > 20 ) {
  18. cc=0;
  19. threads.yield();
  20. }
  21. #endif
  22. }
  23. }
  24. void dhcp_cln_callback_updated(fnet_dhcp_cln_desc_t _dhcp_desc, fnet_netif_desc_t netif, void *p ) { //Called when DHCP updates
  25. struct fnet_dhcp_cln_options current_options;
  26. fnet_dhcp_cln_get_options(dhcp_desc, &current_options);
  27. uint8_t *ip = (uint8_t*)&current_options.ip_address.s_addr;
  28. Serial.print("IPAddress: ");
  29. Serial.print((uint8_t)*ip++);
  30. Serial.print(".");
  31. Serial.print((uint8_t)*ip++);
  32. Serial.print(".");
  33. Serial.print((uint8_t)*ip++);
  34. Serial.print(".");
  35. Serial.println((uint8_t)*ip);
  36. ip = (uint8_t*)&current_options.netmask.s_addr;
  37. Serial.print("SubnetMask: ");
  38. Serial.print((uint8_t)*ip++);
  39. Serial.print(".");
  40. Serial.print((uint8_t)*ip++);
  41. Serial.print(".");
  42. Serial.print((uint8_t)*ip++);
  43. Serial.print(".");
  44. Serial.println((uint8_t)*ip);
  45. ip = (uint8_t*)&current_options.gateway.s_addr;
  46. Serial.print("Gateway: ");
  47. Serial.print((uint8_t)*ip++);
  48. Serial.print(".");
  49. Serial.print((uint8_t)*ip++);
  50. Serial.print(".");
  51. Serial.print((uint8_t)*ip++);
  52. Serial.print(".");
  53. Serial.println((uint8_t)*ip);
  54. ip = (uint8_t*)&current_options.dhcp_server.s_addr;
  55. Serial.print("DHCPServer: ");
  56. Serial.print((uint8_t)*ip++);
  57. Serial.print(".");
  58. Serial.print((uint8_t)*ip++);
  59. Serial.print(".");
  60. Serial.print((uint8_t)*ip++);
  61. Serial.print(".");
  62. Serial.println((uint8_t)*ip);
  63. Serial.print("State: ");
  64. Serial.println(fnet_dhcp_cln_get_state(_dhcp_desc));
  65. Serial.println();
  66. Serial.println();
  67. }
  68. void checkLink(){
  69. // Serial.print("Link: ");
  70. // Serial.println(asix1.connected);
  71. if(asix1.connected && fnet_dhcp_cln_is_enabled(dhcp_desc)){
  72. // Serial.println("DHCP already running!");
  73. }
  74. else if(asix1.connected){
  75. struct fnet_init_params init_params;
  76. static const fnet_timer_api_t timer_api = { //Setup multi-thread timer
  77. .timer_get_ms = timer_get_ms,
  78. .timer_delay = 0,
  79. };
  80. /* Input parameters for FNET stack initialization */
  81. init_params.netheap_ptr = stack_heap;
  82. init_params.netheap_size = sizeof(stack_heap);
  83. init_params.mutex_api = &teensy_mutex_api;
  84. init_params.timer_api = &timer_api;
  85. /* FNET Initialization */
  86. if (fnet_init(&init_params) != FNET_ERR) {
  87. Serial.println("TCP/IP stack initialization is done.\n");
  88. /* You may use FNET stack API */
  89. /* Initialize networking interfaces using fnet_netif_init(). */
  90. // Get current net interface.
  91. if(fnet_netif_init(FNET_CPU_USB0_IF, MacAddress, 6) != FNET_ERR){
  92. Serial.println("netif Initialized");
  93. if((current_netif = fnet_netif_get_default()) == 0){
  94. Serial.println("ERROR: Network Interface is not configurated!");
  95. }
  96. else {
  97. Serial.println("Initializing DHCP");
  98. fnet_memset_zero(&dhcp_desc, sizeof(dhcp_desc));
  99. fnet_memset_zero(&dhcp_params, sizeof(dhcp_params));
  100. dhcp_params.netif = current_netif;
  101. // Enable DHCP client.
  102. if((dhcp_desc = fnet_dhcp_cln_init(&dhcp_params))){
  103. /*Register DHCP event handler callbacks.*/
  104. fnet_dhcp_cln_set_callback_updated(dhcp_desc, dhcp_cln_callback_updated, (void*)dhcp_desc);
  105. fnet_dhcp_cln_set_callback_discover(dhcp_desc, dhcp_cln_callback_updated, (void*)dhcp_desc);
  106. Serial.println("DHCP initialization done!");
  107. bench_srv_init();
  108. }
  109. else{
  110. Serial.println("ERROR: DHCP initialization failed!");
  111. }
  112. }
  113. }
  114. else {
  115. Serial.println("Error:netif initialization failed.\n");
  116. }
  117. }
  118. else {
  119. Serial.println("Error:TCP/IP stack initialization failed.\n");
  120. }
  121. }
  122. else if(!asix1.connected && fnet_dhcp_cln_is_enabled(dhcp_desc)){
  123. Serial.println("DHCP Released");
  124. fnet_dhcp_cln_release(dhcp_desc);
  125. fnet_memset_zero(dhcp_desc, sizeof(dhcp_desc));
  126. bench_srv_release();
  127. fnet_release();
  128. }
  129. else if(!asix1.connected){
  130. // Serial.println("DHCP already released!");
  131. }
  132. }
  133. void handleOutput(fnet_netif_t *netif, fnet_netbuf_t *nb) { //Called when a message is sent
  134. if(nb && (nb->total_length >= FNET_ETH_HDR_SIZE)){
  135. uint8_t* p = (uint8_t*)sbuf;
  136. _fnet_netbuf_to_buf(nb, 0u, FNET_NETBUF_COPYALL, p);
  137. if(nb->total_length >= 12){
  138. // Serial.print("Message Transmitted: ");
  139. // Serial.println(nb->total_length);
  140. // Serial.print("QueuedBefore: ");
  141. // Serial.println(asix1.txQueued());
  142. // const uint8_t* end = p + nb->total_length;
  143. // while(p < end){
  144. // if(*p <= 0x0F) Serial.print("0");
  145. // Serial.print(*p, HEX);
  146. // Serial.print(" ");
  147. // p++;
  148. // }
  149. // Serial.println();
  150. // p = (uint8_t*)sbuf;
  151. }
  152. myusb.Task();
  153. asix1.sendPacket(p, nb->total_length);
  154. // Serial.print("QueuedAfter: ");
  155. // Serial.println(asix1.txQueued());
  156. myusb.Task();
  157. }
  158. }
  159. void handleWait() {
  160. myusb.Task();
  161. }
  162. uint32_t _totalLength;
  163. int32_t _remainingLength = 0;
  164. uint8_t* _lastIndex;
  165. uint8_t* _rxEnd;
  166. uint8_t* _rxStart;
  167. void handleRecieve(const uint8_t* data, uint32_t length) { //Called when ASIX gets a message
  168. if(length == 0) return;
  169. RECIEVE:
  170. if(_remainingLength < 0){
  171. Serial.println("Remaining");
  172. while(_lastIndex < _rxEnd){
  173. *_lastIndex = *data;
  174. data++;
  175. _lastIndex++;
  176. }
  177. _fnet_eth_input(&fnet_usb0_if, (uint8_t*)rbuf, _totalLength);
  178. _remainingLength = abs(_remainingLength);
  179. data += _remainingLength;
  180. _remainingLength = length - ((_remainingLength + 3) & 0xFFFFFFFC);
  181. length -= _remainingLength;
  182. if(length) {
  183. goto RECIEVE;
  184. }
  185. }
  186. else if(((data[0] | data[2]) == 0xFF) && ((data[1] | data[3]) == 0xFF)) { //Check for header
  187. _lastIndex = (uint8_t*)rbuf;
  188. _totalLength = (data[1] << 8) | data[0];
  189. _remainingLength = length - ((_totalLength + 9) & 0xFFFFFFFC);
  190. if(_remainingLength < 0){
  191. // Serial.print("Remaining: ");
  192. // Serial.println(_remainingLength);
  193. const uint8_t* end = data + length;
  194. _rxEnd = (uint8_t*)rbuf + _totalLength;
  195. data += 6;
  196. while(data < end){
  197. *_lastIndex = *data;
  198. data++;
  199. _lastIndex++;
  200. }
  201. }
  202. else {
  203. data += 6;
  204. _fnet_eth_input(&fnet_usb0_if, (uint8_t*)data, _totalLength);
  205. if(_remainingLength) {
  206. // Serial.println("Remaining data");
  207. // Serial.print("length: ");
  208. // Serial.print(length);
  209. // Serial.print(" rlength: ");
  210. // Serial.println(_remainingLength);
  211. data -= 6;
  212. data += ((_totalLength + 9) & 0xFFFFFFFC);
  213. length -= ((_totalLength + 9) & 0xFFFFFFFC);
  214. // asix1.print_hexbytes((uint8_t*)data, ((_totalLength + 9) & 0xFFFFFFFC));
  215. goto RECIEVE;
  216. }
  217. }
  218. }
  219. else if(length == abs(_remainingLength)) return; //Technically an error and I don't know where it's happening, but this poses no problems so it's fine
  220. else{ //Error edgecase unknown cause
  221. Serial.println("Message Recieve Error, searching for next header");
  222. Serial.print("length: ");
  223. Serial.print(length);
  224. Serial.print(" rlength: ");
  225. Serial.println(_remainingLength);
  226. return;
  227. }
  228. }
  229. void handleSetMACAddress(uint8_t * hw_addr) { //Gets called on initialization
  230. Serial.print("SetMACAddress: ");
  231. for(uint8_t i = 0; i < 6; i++) {
  232. if(hw_addr[i] <= 0x0F) Serial.print("0");
  233. Serial.print(hw_addr[i], HEX);
  234. }
  235. Serial.println();
  236. }
  237. void handleGetMACAddress(fnet_mac_addr_t * hw_addr) { //Gets called everytime a message is sent
  238. (*hw_addr)[0] = asix1.nodeID[0];
  239. (*hw_addr)[1] = asix1.nodeID[1];
  240. (*hw_addr)[2] = asix1.nodeID[2];
  241. (*hw_addr)[3] = asix1.nodeID[3];
  242. (*hw_addr)[4] = asix1.nodeID[4];
  243. (*hw_addr)[5] = asix1.nodeID[5];
  244. MacAddress[0] = asix1.nodeID[0];
  245. MacAddress[1] = asix1.nodeID[1];
  246. MacAddress[2] = asix1.nodeID[2];
  247. MacAddress[3] = asix1.nodeID[3];
  248. MacAddress[4] = asix1.nodeID[4];
  249. MacAddress[5] = asix1.nodeID[5];
  250. // Serial.print("GetMACAddress: ");
  251. // for(uint8_t i = 0; i < 6; i++) {
  252. // if(hw_addr[i] <= 0x0F) Serial.print("0");
  253. // Serial.print(hw_addr[i], HEX);
  254. // }
  255. // Serial.println();
  256. }
  257. void handlePHYRead(fnet_uint32_t reg_addr, fnet_uint16_t *data) { //Could be called, don't think it works correctly
  258. asix1.readPHY(reg_addr, data);
  259. Serial.print("PHYRead: ");
  260. Serial.print(reg_addr, HEX);
  261. Serial.print(" ");
  262. Serial.println(*data, HEX);
  263. }
  264. void handlePHYWrite(fnet_uint32_t reg_addr, fnet_uint16_t data) { //Could be called, might work correctly
  265. asix1.writePHY(reg_addr, data);
  266. Serial.println("PHYWrite");
  267. }
  268. uint8_t mcHashTable[8] = {0,0,0,0,0,0,0,0}; //Whole table needs resent when one multicast address is changed
  269. void handleMulticastJoin(fnet_netif_t *netif, fnet_mac_addr_t multicast_addr) { //Called when joining multicast group
  270. //Not setup yet
  271. Serial.print("MulticastJoin: ");
  272. for(uint8_t i = 0; i < 6; i++) {
  273. if(multicast_addr[i] <= 0x0F) Serial.print("0");
  274. Serial.print(multicast_addr[i], HEX);
  275. }
  276. Serial.println();
  277. uint8_t crc = byteReverse((uint8_t)(fnet_usb_crc_hash(multicast_addr) & 0x000000FF)) >> 2;
  278. crc &= 0x3F;
  279. mcHashTable[crc >> 3] |= 1 << (crc & 7);
  280. asix1.setMulticast((uint8_t*)&mcHashTable);
  281. // Serial.println("MulticastTable: ");
  282. // for(uint8_t i = 0; i < 8; i++) {
  283. // Serial.println(mcHashTable[i],BIN);
  284. // }
  285. }
  286. void handleMulticastLeave(fnet_netif_t *netif, fnet_mac_addr_t multicast_addr) { //Called when leaving multicast group
  287. //Not setup yet
  288. Serial.println("MulticastLeave: ");
  289. for(uint8_t i = 0; i < 6; i++) {
  290. if(multicast_addr[i] <= 0x0F) Serial.print("0");
  291. Serial.print(multicast_addr[i], HEX);
  292. }
  293. Serial.println();
  294. uint8_t crc = byteReverse((uint8_t)(fnet_usb_crc_hash(multicast_addr) & 0x000000FF)) >> 2;
  295. crc &= 0x3F;
  296. mcHashTable[crc >> 3] ^= 1 << (crc & 7);
  297. asix1.setMulticast((uint8_t*)&mcHashTable);
  298. // Serial.println("MulticastTable: ");
  299. // for(uint8_t i = 0; i < 8; i++) {
  300. // Serial.println(mcHashTable[i],BIN);
  301. // }
  302. }
  303. uint8_t byteReverse(uint8_t x) {
  304. x = ((x >> 1) & 0x55) | ((x << 1) & 0xaa);
  305. x = ((x >> 2) & 0x33) | ((x << 2) & 0xcc);
  306. x = ((x >> 4) & 0x0f) | ((x << 4) & 0xf0);
  307. return x;
  308. }
  309. fnet_bool_t handleIsConnected() {
  310. return asix1.connected ? FNET_TRUE : FNET_FALSE;
  311. }
  312. fnet_bench_srv_params_t bench_srv_params;
  313. fnet_bench_srv_desc_t bench_srv_desc;
  314. void bench_srv_init(){
  315. /* Set Benchmark server parameters.*/
  316. fnet_memset_zero(&bench_srv_params, sizeof(bench_srv_params));
  317. bench_srv_params.type = SOCK_STREAM; /* TCP by default */
  318. if(current_netif){ /* Only on one interface */
  319. bench_srv_params.address.sa_scope_id = fnet_netif_get_scope_id(current_netif);
  320. }
  321. /* Start Benchmark server. */
  322. bench_srv_desc = fnet_bench_srv_init(&bench_srv_params);
  323. if(bench_srv_desc){
  324. /* Instal callbacks */
  325. // fnet_bench_srv_set_callback_session_begin (fapp_bench_srv_desc, fapp_bench_srv_callback_session_begin, shell_desc);
  326. fnet_bench_srv_set_callback_session_end (bench_srv_desc, bench_srv_callback_session_end, bench_srv_desc);
  327. }
  328. }
  329. void bench_srv_release(void){
  330. fnet_bench_srv_release(bench_srv_desc);
  331. bench_srv_desc = 0;
  332. }
  333. static void bench_srv_callback_session_end(fnet_bench_srv_desc_t desc, const struct fnet_bench_srv_result *bench_srv_result, void *cookie) {
  334. if(bench_srv_result){
  335. uint64_t totalBytes = (bench_srv_result->megabytes * 1000000) + bench_srv_result->bytes;
  336. // Serial.println("Benchmark results:");
  337. Serial.print("Megabytes: ");
  338. Serial.print(totalBytes / 1000000.0, 6);
  339. Serial.print(" Seconds: ");
  340. Serial.print(bench_srv_result->time_ms/1000.0, 4);
  341. // Serial.print("Bytes/Sec: ");
  342. // Serial.println(totalBytes/(bench_srv_result->time_ms/1000.0), 4);
  343. // Serial.print("KBytes/Sec: ");
  344. // Serial.println((totalBytes/(bench_srv_result->time_ms/1000.0))/1000.0, 4);
  345. Serial.print(" KBits/Sec: ");
  346. Serial.println((((totalBytes/(bench_srv_result->time_ms/1000.0))/1000.0)*8), 4);
  347. // Serial.println();
  348. }
  349. }
  350. fnet_bench_cln_desc_t teensy_bench_cln_desc;
  351. void bench_cln_cmd(uint8_t argc, char* argv){
  352. fnet_bench_cln_params_t bench_cln_params;
  353. fnet_netif_desc_t netif = current_netif;
  354. fnet_bench_cln_desc_t bench_cln_desc;
  355. fnet_char_t ip_str[FNET_IP_ADDR_STR_SIZE_MAX];
  356. uint8_t i;
  357. /* Set Benchmark client parameters.*/
  358. fnet_memset_zero(&bench_cln_params, sizeof(bench_cln_params));
  359. /* Default values */
  360. bench_cln_params.type = SOCK_STREAM; /* TCP by default */
  361. bench_cln_params.message_size = 1272; /* Default message size */
  362. bench_cln_params.message_number = 10000; /* Default number of messages */
  363. /* -a <remote ip> [tcp|udp] [-m <message size>] [-mn <number of messages>] */
  364. for(i = 0; i < (argc); i++){
  365. if (!fnet_strcmp(&argv[i], "-a")){ /*[-a <remote ip>] */
  366. i += 3;
  367. if(i < argc){
  368. if(fnet_inet_ptos(&argv[i], &bench_cln_params.address) == FNET_ERR){
  369. goto ERROR_PARAMETER;
  370. }
  371. while(argv[i] != '\0'){
  372. i++;
  373. }
  374. }
  375. else{
  376. goto ERROR_PARAMETER;
  377. }
  378. }
  379. else if (!fnet_strcmp(&argv[i], "tcp")){ /* TCP */
  380. bench_cln_params.type = SOCK_STREAM;
  381. while(argv[i] != '\0'){
  382. i++;
  383. }
  384. }
  385. else if (!fnet_strcmp(&argv[i], "udp")){ /* udp */
  386. bench_cln_params.type = SOCK_DGRAM;
  387. while(argv[i] != '\0'){
  388. i++;
  389. }
  390. }
  391. else if (!fnet_strcmp(&argv[i], "-m")){ /* [-m <message size>] */
  392. fnet_char_t *p = 0;
  393. i += 3;
  394. if(i < argc){
  395. bench_cln_params.message_size = fnet_strtoul(&argv[i], &p, 0);
  396. if (bench_cln_params.message_size == 0){
  397. goto ERROR_PARAMETER;
  398. }
  399. }
  400. else{
  401. goto ERROR_PARAMETER;
  402. }
  403. while(argv[i] != '\0'){
  404. i++;
  405. }
  406. }
  407. else if (!fnet_strcmp(&argv[i], "-mn")){ /* [-mn <number of messages>] */
  408. fnet_char_t *p = 0;
  409. i += 4;
  410. if(i < argc){
  411. bench_cln_params.message_number = fnet_strtoul(&argv[i], &p, 0);
  412. if (bench_cln_params.message_number == 0){
  413. goto ERROR_PARAMETER;
  414. }
  415. }
  416. else{
  417. goto ERROR_PARAMETER;
  418. }
  419. while(argv[i] != '\0'){
  420. i++;
  421. }
  422. }
  423. else if (argv[i] == '\0'){
  424. }
  425. else{/* Wrong parameter.*/
  426. goto ERROR_PARAMETER;
  427. }
  428. }
  429. if(fnet_socket_addr_is_unspecified(&bench_cln_params.address) == FNET_TRUE){ /* Address is not set. */
  430. Serial.println("Error: <remote ip> is not set");
  431. }
  432. else{
  433. if(netif){ /* Only on one interface */
  434. bench_cln_params.address.sa_scope_id = fnet_netif_get_scope_id(netif);
  435. }
  436. bench_cln_params.callback = bench_cln_callback_session_end; /* Callback function.*/
  437. /* Run Benchmark client. */
  438. bench_cln_desc = fnet_bench_cln_init(&bench_cln_params);
  439. if(bench_cln_desc){
  440. teensy_bench_cln_desc = bench_cln_desc;
  441. //
  442. Serial.println("Benchmark client started.");
  443. Serial.print("Protocol: ");
  444. Serial.println((bench_cln_params.type == SOCK_STREAM) ? "TCP" : "UDP");
  445. Serial.print("Remote IP Addr: ");
  446. Serial.println(fnet_inet_ntop(bench_cln_params.address.sa_family, bench_cln_params.address.sa_data, ip_str, sizeof(ip_str)));
  447. Serial.print("Remote Port: ");
  448. Serial.println(FNET_NTOHS(FNET_CFG_BENCH_CLN_PORT));
  449. Serial.print("Message Size: ");
  450. Serial.println(bench_cln_params.message_size);
  451. Serial.print("Num. of messages: ");
  452. Serial.println(bench_cln_params.message_number);
  453. Serial.println();
  454. }
  455. else{
  456. Serial.println("Benchmark client failed to start.");
  457. }
  458. }
  459. return;
  460. ERROR_PARAMETER:
  461. Serial.print("Bad parameter: ");
  462. Serial.println(&argv[i]);
  463. return;
  464. }
  465. static void bench_cln_callback_session_end(fnet_bench_cln_desc_t bench_cln_desc, const fnet_bench_cln_result_t *bench_cln_result, void *cookie){
  466. if(bench_cln_result){
  467. // fapp_bench_print_results (shell_desc, bench_cln_result->megabytes, bench_cln_result->bytes, bench_cln_result->time_ms);
  468. uint64_t totalBytes = (bench_cln_result->megabytes * 1000000) + bench_cln_result->bytes;
  469. // Serial.println("Benchmark results:");
  470. Serial.print("Megabytes: ");
  471. Serial.print(totalBytes / 1000000.0, 6);
  472. Serial.print(" Seconds: ");
  473. Serial.print(bench_cln_result->time_ms/1000.0, 4);
  474. Serial.print(" KBits/Sec: ");
  475. Serial.println((((totalBytes/(bench_cln_result->time_ms/1000.0))/1000.0)*8), 4);
  476. }
  477. }
  478. void serialParser(uint8_t argc, char* argv){
  479. for(uint8_t i = 0; i < (argc) /*avoid the last parameter.*/; i++){
  480. if (!fnet_strcmp(&argv[i], "benchtx")){ /*benchtx */
  481. i++;
  482. if(i < argc){
  483. argv += 8; //Advance length of command + 1
  484. argc -= 8; //Decrease length same amount
  485. Serial.println("Starting benchtx...");
  486. bench_cln_cmd(argc, argv);
  487. return;
  488. }
  489. else{
  490. goto ERROR_PARAMETER;
  491. }
  492. }
  493. else if (!fnet_strcmp(&argv[i], "benchrx")){ /*benchrx */
  494. i++;
  495. if(i < argc){
  496. argv += 8; //Advance length of command + 1
  497. argc -= 8; //Decrease length same amount
  498. // bench_cln_cmd(argc, argv);
  499. Serial.println("Starting benchrx...");
  500. return;
  501. }
  502. else{
  503. goto ERROR_PARAMETER;
  504. }
  505. }
  506. else{/* Wrong parameter.*/
  507. goto ERROR_PARAMETER;
  508. }
  509. }
  510. return;
  511. ERROR_PARAMETER:
  512. Serial.println("Invalid command");
  513. return;
  514. }