1 /*
2 * Copyright (C) 2020-2022 Alibaba Group Holding Limited
3 */
4
5
6 #include <stdio.h>
7 #include <string.h>
8 #include <assert.h>
9 #include <stdlib.h>
10
11 #include "aos/kernel.h"
12 #include "sys/socket.h"
13 #include <uservice/uservice.h>
14 #include <uservice/eventid.h>
15 #include "ulog/ulog.h"
16
17 #include "ch395_spi.h"
18 #include "ch395_cmd.h"
19
20 #define TAG "ch395_sal_module"
21
22 #define SPI_TIME_OUT 1000
23
24 #define TCP_MSS_MAX_VALUE 1460
25 #define TCP_MSS_MIN_VALUE 60
26 #define TCP_TTL_MAX_VALUE 128
27 #define MAX_BUF_NUM 48
28 #define IPV4_ADDR_STR_LEN 15
29
30 static int8_t guc_module_initflag = 0;
31 static spi_dev_t g_st_spi_info = {0};
32 static aos_mutex_t gst_spi_op_mutex = {0};
33
34 #define TAG "ch395_cmd"
35
ch395_str_to_ip4addr(int8_t * str,uint8_t * paddr)36 int32_t ch395_str_to_ip4addr(int8_t *str, uint8_t *paddr)
37 {
38 uint32_t i = 0;
39 uint32_t len = 0;
40 uint32_t ipaddr = 0;
41
42 if (NULL == str || NULL == paddr) {
43 LOGE(TAG, "%s %d Invalid input", __func__, __LINE__);
44 return -1;
45 }
46
47 len = strlen(str);
48 if (len > IPV4_ADDR_STR_LEN) {
49 LOGE(TAG, "%s %d Invalid input %s ", __func__, __LINE__, str);
50 return -1;
51 }
52
53 ipaddr = ipaddr_addr(str);
54 if (ipaddr == -1) {
55 LOGE(TAG, "%s %d Invalid ip str %s", __func__, __LINE__, str);
56 return -1;
57 }
58
59 ipaddr = ntohl(ipaddr);
60 paddr[0] = (uint8_t)((ipaddr & 0xFF000000) >> 24);
61 paddr[1] = (uint8_t)((ipaddr & 0x00FF0000) >> 16);
62 paddr[2] = (uint8_t)((ipaddr & 0x0000FF00) >> 8);
63 paddr[3] = (uint8_t)(ipaddr & 0x000000FF);
64
65 return 0;
66 }
67
ch395_module_init(spi_dev_t * pstspiinfo)68 int32_t ch395_module_init(spi_dev_t *pstspiinfo)
69 {
70 int32_t ret = 0;
71
72 if (NULL == pstspiinfo) {
73 LOGE(TAG, "%s %d invalid input \r\n", __FILE__, __LINE__);
74 return -1;
75 }
76
77 if (guc_module_initflag) {
78 return 0;
79 }
80
81 ret = hal_ch395_spi_init(pstspiinfo);
82 if (ret) {
83 LOGE(TAG, "spi init fail 0x%x, port %d, spi role %d, firstbit %d, work_mode %d, freq %d",
84 ret, pstspiinfo->port, pstspiinfo->config.role, pstspiinfo->config.firstbit,
85 pstspiinfo->config.mode, pstspiinfo->config.freq);
86 return -1;
87 }
88
89 ret = aos_mutex_new(&gst_spi_op_mutex);
90 if (ret) {
91 LOGE(TAG, "Failed to new a mutex 0x%x", ret);
92 return -1;
93 }
94
95 memset(&g_st_spi_info, 0, sizeof(g_st_spi_info));
96 memcpy(&g_st_spi_info, pstspiinfo, sizeof(g_st_spi_info));
97
98 guc_module_initflag = 1;
99 return 0;
100 }
101
ch395_spi_data_write(uint8_t * pdata,uint32_t len)102 static int32_t ch395_spi_data_write(uint8_t *pdata, uint32_t len)
103 {
104 int32_t ret = 0;
105
106 if (NULL == pdata || 0 == len) {
107 LOGE(TAG, "invalid input");
108 return -1;
109 }
110
111 if (guc_module_initflag == 0) {
112 LOGE(TAG, "ch395 spi bus haven't init yet");
113 return -1;
114 }
115
116 aos_mutex_lock(&gst_spi_op_mutex, AOS_WAIT_FOREVER);
117 ret = hal_spi_send_ch395(&g_st_spi_info, pdata, len, SPI_TIME_OUT);
118 aos_mutex_unlock(&gst_spi_op_mutex);
119 if (ret) {
120 LOGE(TAG, "spi cmd write fail %d", ret);
121 return -1;
122 }
123
124 return 0;
125 }
126
ch395_spi_send_and_recv(uint8_t * txdata,uint32_t txlen,uint8_t * rxdata,uint32_t rxlen)127 static int32_t ch395_spi_send_and_recv(uint8_t *txdata, uint32_t txlen, uint8_t *rxdata, uint32_t rxlen)
128 {
129 int32_t ret = 0;
130 uint32_t i = 0;
131
132 if (NULL == txdata || 0 == txlen || NULL == rxdata || 0 == rxlen) {
133 LOGE(TAG, "invalid input");
134 return -1;
135 }
136
137 if (guc_module_initflag == 0) {
138 LOGE(TAG, "ch395 spi bus haven't init yet");
139 return -1;
140 }
141
142 aos_mutex_lock(&gst_spi_op_mutex, AOS_WAIT_FOREVER);
143 ret = hal_spi_send_and_recv_ch395_normal(&g_st_spi_info, txdata, txlen, rxdata, rxlen, SPI_TIME_OUT);
144 aos_mutex_unlock(&gst_spi_op_mutex);
145 if (ret) {
146 LOGE(TAG, "===hal spi send and recv 0x%x len %d fail ret 0x%x==\r\n", txdata[0], txlen, ret);
147 return -1;
148 }
149
150 return 0;
151 }
152
ch395_spi_cmd_query(uint8_t cmd,uint8_t * pvalue)153 static int32_t ch395_spi_cmd_query(uint8_t cmd, uint8_t *pvalue)
154 {
155 int32_t ret = 0;
156 uint8_t data = 0;
157
158 if (NULL == pvalue) {
159 LOGE(TAG, "Invalid input");
160 return -1;
161 }
162
163 ret = ch395_spi_send_and_recv(&cmd, sizeof(cmd), &data, sizeof(data));
164 if (ret) {
165 LOGE(TAG, "spi send and recv fail %d, cmd %d", ret, cmd);
166 return -1;
167 }
168
169 *pvalue = data;
170 return 0;
171 }
172
ch395_get_cmd_status(uint8_t * pstatus)173 static int32_t ch395_get_cmd_status(uint8_t *pstatus)
174 {
175 int32_t ret = 0;
176 uint8_t cmd = CMD01_GET_CMD_STATUS;
177 uint8_t value = 0;
178
179 if (NULL == pstatus) {
180 LOGE(TAG, "Invalid input");
181 return -1;
182 }
183
184 ret = ch395_spi_cmd_query(cmd, &value);
185 if (ret) {
186 LOGE(TAG, "get cmd status fail %d ret", cmd);
187 return -1;
188 }
189
190 *pstatus = value;
191
192 return 0;
193 }
194
ch395_chip_exist_check(void)195 int32_t ch395_chip_exist_check(void)
196 {
197 uint8_t cmd[2] = {CMD11_CHECK_EXIST, 0x5A};
198 uint8_t readdata = 0;
199 int32_t ret = 0;
200
201 if (guc_module_initflag == 0) {
202 LOGE(TAG, "ch395 spi bus haven't init yet");
203 return -1;
204 }
205
206 aos_mutex_lock(&gst_spi_op_mutex, AOS_WAIT_FOREVER);
207 ret = hal_spi_send_and_recv_ch395_exist(&g_st_spi_info, cmd, sizeof(cmd), &readdata, sizeof(readdata), SPI_TIME_OUT);
208 aos_mutex_unlock(&gst_spi_op_mutex);
209 if (ret) {
210 LOGE(TAG, "===hal spi send and recv 0x%x len %d fail ret 0x%x==\r\n", cmd[0], sizeof(cmd), ret);
211 return -1;
212 }
213
214 if (readdata != ~cmd[1]) {
215 LOGE(TAG, "testdata 0x%x, readdata 0x%x ,chip not exist", cmd[1], readdata);
216 return -1;
217 }
218
219 return 0;
220 }
221
ch395_chip_reset(void)222 int32_t ch395_chip_reset(void)
223 {
224 int32_t ret = 0;
225 uint8_t cmd = CMD00_RESET_ALL;
226
227 ret = ch395_spi_data_write(&cmd, sizeof(cmd));
228 if (ret) {
229 LOGE(TAG, "send chip reset cmd fail ");
230 return -1;
231 }
232 /*wait 50ms ,make sure reset operation can finish*/
233 aos_msleep(50);
234
235 return 0;
236 }
237
ch395_enter_sleep(void)238 int32_t ch395_enter_sleep(void)
239 {
240 int32_t ret = 0;
241 uint8_t cmd = CMD00_ENTER_SLEEP;
242
243 ret = ch395_spi_data_write(&cmd, sizeof(cmd));
244 if (ret) {
245 LOGE(TAG, "send chip reset cmd fail ");
246 return -1;
247 }
248
249 /*when exite sleep mode should cost several ms (less than 10ms)*/
250 return 0;
251 }
252
ch395_get_version(uint8_t * pchip_ver,uint8_t * pfirm_ver)253 int32_t ch395_get_version(uint8_t *pchip_ver, uint8_t *pfirm_ver)
254 {
255 int32_t ret = 0;
256 uint8_t ver = 0;
257
258 if (NULL == pchip_ver || NULL == pfirm_ver) {
259 LOGE(TAG, "Invalid input");
260 return -1;
261 }
262
263 ret = ch395_spi_cmd_query(CMD01_GET_IC_VER, &ver);
264 if (ret) {
265 LOGE(TAG, "Fail to get version cmd 0x%x ret %d", CMD01_GET_IC_VER, ret);
266 return -1;
267 }
268
269 *pfirm_ver = ver & 0x0F;
270 *pchip_ver = (ver & 0xF0) >> 4;
271
272 return 0;
273 }
274
ch395_set_phy_state(uint8_t state)275 int32_t ch395_set_phy_state(uint8_t state)
276 {
277 int32_t ret = 0;
278 uint8_t data[2] = {0};
279
280 if (state != PHY_DISCONN && state != PHY_10M_FLL && state != PHY_10M_HALF
281 && state != PHY_100M_FLL && state != PHY_100M_HALF && state != PHY_AUTO) {
282 LOGE(TAG, "Invalid input 0x%x ", state);
283 return -1;
284 }
285
286 data[0] = CMD10_SET_PHY;
287 data[1] = state;
288
289 ret = ch395_spi_data_write(data, sizeof(data));
290 if (ret) {
291 LOGE(TAG, "send phy state fail cmd 0x%x state 0x%x", data[0], data[1]);
292 return -1;
293 }
294
295 return 0;
296 }
297
ch395_get_phy_status(uint8_t * pstate)298 int32_t ch395_get_phy_status(uint8_t *pstate)
299 {
300 int32_t ret = 0;
301
302 if (NULL == pstate) {
303 LOGE(TAG, "Invalid input");
304 return -1;
305 }
306
307 ret = ch395_spi_cmd_query(CMD01_GET_PHY_STATUS, pstate);
308 if (ret) {
309 LOGE(TAG, "Fail to get phy status %d", ret);
310 return -1;
311 }
312
313 return 0;
314 }
315
ch395_set_mac_addr(uint8_t mac[6])316 int32_t ch395_set_mac_addr(uint8_t mac[6])
317 {
318 int32_t ret = 0;
319 uint8_t data[7] = {0};
320
321 data[0] = CMD60_SET_MAC_ADDR;
322 memcpy(&data[1], mac, 6);
323
324 ret = ch395_spi_data_write(data, sizeof(data));
325 if (ret) {
326 LOGE(TAG, "Fail to write cmd 0x%x and mac fail ,ret %d", CMD60_SET_MAC_ADDR, ret);
327 return -1;
328 }
329
330 /*it will save mac info at eerpom , it will take 100 ms*/
331 aos_msleep(100);
332
333 return 0;
334 }
335
ch395_get_mac_addr(uint8_t mac[6])336 int32_t ch395_get_mac_addr(uint8_t mac[6])
337 {
338 int32_t ret = 0;
339 uint8_t cmd = CMD06_GET_MAC_ADDR;
340
341 ret = ch395_spi_send_and_recv(&cmd, sizeof(cmd), mac, 6);
342 if (ret) {
343 LOGE(TAG, "spi send and recv fail %d, recv data len %d", ret, 6);
344 return -1;
345 }
346
347 return 0;
348 }
349
ch395_set_mac_filt(uint8_t filt_type,uint32_t hash0,uint32_t hash1)350 int32_t ch395_set_mac_filt(uint8_t filt_type, uint32_t hash0, uint32_t hash1)
351 {
352 int32_t ret = 0;
353 uint8_t data[10] = {0};
354
355 data[0] = CMD90_SET_MAC_FILT;
356 data[1] = filt_type;
357 data[2] = (uint8_t)hash0;
358 data[3] = (uint8_t)(hash0 >> 8);
359 data[4] = (uint8_t)(hash0 >> 16);
360 data[5] = (uint8_t)(hash0 >> 24);
361 data[6] = (uint8_t)hash1;
362 data[7] = (uint8_t)(hash1 >> 8);
363 data[8] = (uint8_t)(hash1 >> 16);
364 data[9] = (uint8_t)(hash1 >> 24);
365
366 ret = ch395_spi_data_write(data, sizeof(data));
367 if (ret) {
368 LOGE(TAG, "fail to send mac filt data");
369 return -1;
370 }
371
372 return 0;
373 }
374
ch395_set_ip_addr(uint8_t ip[4])375 int32_t ch395_set_ip_addr(uint8_t ip[4])
376 {
377 int32_t ret = 0;
378 uint8_t data[5] = {0};
379
380 data[0] = CMD40_SET_IP_ADDR;
381 memcpy(&data[1], ip, 4);
382
383 ret = ch395_spi_data_write(data, sizeof(data));
384 if (ret) {
385 LOGE(TAG, "Fail to write ip addr ret %d", ret);
386 return -1;
387 }
388
389 return 0;
390 }
391
ch395_set_gw_ip_addr(uint8_t ip[4])392 int32_t ch395_set_gw_ip_addr(uint8_t ip[4])
393 {
394 int32_t ret = 0;
395 uint8_t data[5] = {0};
396
397 data[0] = CMD40_SET_GWIP_ADDR;
398 memcpy(&data[1], ip, 4);
399
400 ret = ch395_spi_data_write(data, sizeof(data));
401 if (ret) {
402 LOGE(TAG, "Fail to write gateway ip addr ret %d", ret);
403 return -1;
404 }
405
406 return 0;
407 }
408
ch395_set_ip_mask_addr(uint8_t ip[4])409 int32_t ch395_set_ip_mask_addr(uint8_t ip[4])
410 {
411 int32_t ret = 0;
412 uint8_t data[5] = {0};
413
414 data[0] = CMD40_SET_MASK_ADDR;
415 memcpy(&data[1], ip, 4);
416
417 ret = ch395_spi_data_write(data, sizeof(data));
418 if (ret) {
419 LOGE(TAG, "Fail to write mask ip addr ret %d", ret);
420 return -1;
421 }
422
423 return 0;
424 }
425
ch395_get_global_int_status(uint8_t * pstatus)426 int32_t ch395_get_global_int_status(uint8_t *pstatus)
427 {
428 int32_t ret = 0;
429
430 if (NULL == pstatus) {
431 LOGE(TAG, "Invalid input");
432 return -1;
433 }
434
435 ret = ch395_spi_cmd_query(CMD01_GET_GLOB_INT_STATUS, pstatus);
436 if (ret) {
437 LOGE(TAG, "Fail to get interrup status");
438 return -1;
439 }
440
441 return 0;
442 }
443
ch395_get_global_all_int_status(uint16_t * pstatus)444 int32_t ch395_get_global_all_int_status(uint16_t *pstatus)
445 {
446 int32_t ret = 0;
447 uint8_t recvdata[2] = {0};
448 uint8_t cmd = CMD02_GET_GLOB_INT_STATUS_ALL;
449
450 if (NULL == pstatus) {
451 LOGE(TAG, "Invalid input");
452 return -1;
453 }
454
455 ret = ch395_spi_send_and_recv(&cmd, sizeof(cmd), (uint8_t *)recvdata, sizeof(recvdata));
456 if (ret) {
457 LOGE(TAG, "spi send and recv fail %d", ret);
458 return -1;
459 }
460
461 *pstatus = (uint16_t)(recvdata[1] << 8) + recvdata[0];
462
463 return 0;
464 }
465
466 /*only works in tcp mode, biggest value is 20 */
ch395_tcp_retran_count_set(uint8_t count)467 int32_t ch395_tcp_retran_count_set(uint8_t count)
468 {
469 int32_t ret = 0;
470 uint8_t data[2] = {0};
471
472 data[1] = count;
473 if (data[1] > 20) {
474 LOGE(TAG, "Invalid input %d , set it to 20", data[1]);
475 data[1] = 20;
476 }
477
478 data[0] = CMD10_SET_RETRAN_COUNT;
479
480 ret = ch395_spi_data_write(data, sizeof(data));
481 if (ret) {
482 LOGE(TAG, "Fail to set retran data");
483 return -1;
484 }
485
486 return 0;
487
488 }
489
490 /*period time is ms */
ch395_tcp_retry_period_set(uint16_t time)491 int32_t ch395_tcp_retry_period_set(uint16_t time)
492 {
493 int32_t ret = 0;
494 uint8_t data[3] = {0};
495
496 if (time > 1000) {
497 LOGE(TAG, "Invalid input %d ", time);
498 return -1;
499 }
500
501 data[0] = CMD20_SET_RETRAN_PERIOD;
502 data[1] = (uint8_t)time;
503 data[2] = (uint8_t)(time >> 8);
504
505 ret = ch395_spi_data_write(data, sizeof(data));
506 if (ret) {
507 LOGE(TAG, "Fail to set retran data");
508 return -1;
509 }
510
511 return 0;
512
513 }
514
ch395_get_remote_ip_port(uint8_t sock,uint8_t ip[4],uint16_t * pport)515 int32_t ch395_get_remote_ip_port(uint8_t sock, uint8_t ip[4], uint16_t *pport)
516 {
517 int32_t ret = 0;
518 uint8_t send_data[2] = {0};
519 uint8_t recv_data[6] = {0};
520
521 if (sock >= MAX_SURPPORT_SOCK_NUM || NULL == pport) {
522 LOGE(TAG, "Invalid input sock %d pport %p ", sock, pport);
523 return -1;
524 }
525
526 send_data[0] = CMD06_GET_REMOT_IPP_SN;
527 send_data[1] = sock;
528
529 ret = ch395_spi_send_and_recv(send_data, sizeof(send_data), recv_data, sizeof(recv_data));
530 if (ret) {
531 LOGE(TAG, "Fail to get sock %d remote port and ip", sock);
532 return -1;
533 }
534
535 memcpy(ip, recv_data, 4);
536
537 *pport = recv_data[4] + (uint16_t)(recv_data[5] << 8);
538
539 return 0;
540 }
541
ch395_clear_sock_recv_buff(uint8_t sock)542 int32_t ch395_clear_sock_recv_buff(uint8_t sock)
543 {
544 int32_t ret = 0;
545 uint8_t data[2] = {0};
546
547 if (sock >= MAX_SURPPORT_SOCK_NUM) {
548 LOGE(TAG, "Invalid input %d", sock);
549 return -1;
550 }
551
552 data[0] = CMD10_CLEAR_RECV_BUF_SN;
553 data[1] = sock;
554
555 ret = ch395_spi_data_write(data, sizeof(data));
556 if (ret) {
557 LOGE(TAG, "Fail to send data 0x%x", sock);
558 return -1;
559 }
560
561 return 0;
562 }
563
ch395_get_sock_tcp_status(uint8_t sock,uint8_t * psock_status,uint8_t * ptcp_status)564 int32_t ch395_get_sock_tcp_status(uint8_t sock, uint8_t *psock_status, uint8_t *ptcp_status)
565 {
566 int32_t ret = 0;
567 uint8_t data[2] = {0};
568 uint8_t recv_data[2] = {0};
569
570 if (sock >= MAX_SURPPORT_SOCK_NUM || NULL == psock_status || NULL == ptcp_status) {
571 LOGE(TAG, "Invalid input %d", sock);
572 return -1;
573 }
574
575 data[0] = CMD12_GET_SOCKET_STATUS_SN;
576 data[1] = sock;
577
578 ret = ch395_spi_send_and_recv(data, sizeof(data), recv_data, sizeof(recv_data));
579 if (ret) {
580 LOGE(TAG, "Fail to get sock %d tcp status", sock);
581 return -1;
582 }
583
584 *psock_status = recv_data[0];
585 *ptcp_status = recv_data[1];
586
587 return 0;
588 }
589
ch395_get_sock_int_status(uint8_t sock,uint8_t * pinterrupt)590 int32_t ch395_get_sock_int_status(uint8_t sock, uint8_t *pinterrupt)
591 {
592 int32_t ret = 0;
593 uint8_t send_data[2] = {0};
594 uint8_t data = 0;
595
596 if (sock >= MAX_SURPPORT_SOCK_NUM || NULL == pinterrupt) {
597 LOGE(TAG, "Invalid input %d", sock);
598 return -1;
599 }
600
601 send_data[0] = CMD11_GET_INT_STATUS_SN;
602 send_data[1] = sock;
603
604 ret = ch395_spi_send_and_recv(send_data, sizeof(send_data), &data, sizeof(data));
605 if (ret) {
606 LOGE(TAG, "Fail to get sock %d interupt status", sock);
607 return -1;
608 }
609
610 *pinterrupt = data;
611
612 return 0;
613 }
614
ch395_set_sock_dest_ip(uint8_t sock,uint8_t * pdst_ip)615 int32_t ch395_set_sock_dest_ip(uint8_t sock, uint8_t *pdst_ip)
616 {
617 int32_t ret = 0;
618 uint8_t data[6] = {0};
619
620 if (sock >= MAX_SURPPORT_SOCK_NUM || NULL == pdst_ip) {
621 LOGE(TAG, "Invalid input %d", sock);
622 return -1;
623 }
624
625 data[0] = CMD50_SET_IP_ADDR_SN;
626 data[1] = sock;
627 memcpy(&data[2], pdst_ip, 4);
628
629 ret = ch395_spi_data_write(data, sizeof(data));
630 if (ret) {
631 LOGE(TAG, "Fail to send data 0x%x", sock);
632 return -1;
633 }
634
635 return 0;
636 }
637
ch395_set_sock_dest_port(uint8_t sock,uint16_t dest_port)638 int32_t ch395_set_sock_dest_port(uint8_t sock, uint16_t dest_port)
639 {
640 int32_t ret = 0;
641 uint8_t data[4] = {0};
642
643 if (sock >= MAX_SURPPORT_SOCK_NUM) {
644 LOGE(TAG, "Invalid input %d", sock);
645 return -1;
646 }
647
648 data[0] = CMD30_SET_DES_PORT_SN;
649 data[1] = sock;
650 data[2] = (uint8_t)dest_port;
651 data[3] = (uint8_t)(dest_port >> 8);
652
653 ret = ch395_spi_data_write(data, sizeof(data));
654 if (ret) {
655 LOGE(TAG, "Fail to send data 0x%x", sock);
656 return -1;
657 }
658
659 return 0;
660 }
661
ch395_set_sock_src_port(uint8_t sock,uint16_t src_port)662 int32_t ch395_set_sock_src_port(uint8_t sock, uint16_t src_port)
663 {
664 int32_t ret = 0;
665 uint8_t data[4] = {0};
666
667 if (sock >= MAX_SURPPORT_SOCK_NUM) {
668 LOGE(TAG, "Invalid input %d", sock);
669 return -1;
670 }
671
672 data[0] = CMD30_SET_SOUR_PORT_SN;
673 data[1] = sock;
674 data[2] = (uint8_t)src_port;
675 data[3] = (uint8_t)(src_port >> 8);
676
677 ret = ch395_spi_data_write(data, sizeof(data));
678 if (ret) {
679 LOGE(TAG, "Fail to send data 0x%x", sock);
680 return -1;
681 }
682
683 return 0;
684 }
685
ch395_set_sock_proto_type(uint8_t sock,uint8_t proto_type)686 int32_t ch395_set_sock_proto_type(uint8_t sock, uint8_t proto_type)
687 {
688 int32_t ret = 0;
689 uint8_t data[3] = {0};
690
691 if (sock >= MAX_SURPPORT_SOCK_NUM || proto_type > PROTO_TYPE_TCP) {
692 LOGE(TAG, "Invalid input %d", sock);
693 return -1;
694 }
695
696 data[0] = CMD20_SET_PROTO_TYPE_SN;
697 data[1] = sock;
698 data[2] = proto_type;
699
700 ret = ch395_spi_data_write(data, sizeof(data));
701 if (ret) {
702 LOGE(TAG, "Fail to send data 0x%x", sock);
703 return -1;
704 }
705
706 return 0;
707 }
708
ch395_socket_open(uint8_t sock)709 int32_t ch395_socket_open(uint8_t sock)
710 {
711 int32_t ret = 0;
712 int32_t retry = 0;
713 uint8_t status = 0;
714 uint8_t data[2] = {0};
715
716 if (sock >= MAX_SURPPORT_SOCK_NUM) {
717 LOGE(TAG, "Invalid input %d", sock);
718 return -1;
719 }
720
721 data[0] = CMD1W_OPEN_SOCKET_SN;
722 data[1] = sock;
723
724 ret = ch395_spi_data_write(data, sizeof(data));
725 if (ret) {
726 LOGE(TAG, "Fail to send data 0x%x", sock);
727 return -1;
728 }
729
730 /*check cmd status GET_CMD_STATUS, CMD_ERR_SUCCESS means successed*/
731 do {
732 retry++;
733 status = 0;
734 /*need to wait data free interrupt*/
735 ret = ch395_get_cmd_status(&status);
736 if (ret == 0 && (status != CH395_ERR_BUSY)) {
737 break;
738 }
739 aos_msleep(2);
740 } while (retry < 20);
741
742 if (retry <= 20) {
743 return 0;
744 }
745
746 return -1;
747 }
748
ch395_socket_close(uint8_t sock)749 int32_t ch395_socket_close(uint8_t sock)
750 {
751 int32_t ret = 0;
752 int32_t retry = 0;
753 uint8_t status = 0;
754 uint8_t data[2] = {0};
755
756 if (sock >= MAX_SURPPORT_SOCK_NUM) {
757 LOGE(TAG, "Invalid input %d", sock);
758 return -1;
759 }
760
761 data[0] = CMD1W_CLOSE_SOCKET_SN;
762 data[1] = sock;
763
764 ret = ch395_spi_data_write(data, sizeof(data));
765 if (ret) {
766 LOGE(TAG, "Fail to send data 0x%x", sock);
767 return -1;
768 }
769
770 /*need to check cmd status*/
771 do {
772 retry++;
773 status = 0;
774 /*need to wait data free interrupt*/
775 ret = ch395_get_cmd_status(&status);
776 if (ret == 0 && (status != CH395_ERR_BUSY)) {
777 break;
778 }
779 aos_msleep(2);
780 } while (retry < 20);
781
782 if (retry <= 20) {
783 return 0;
784 }
785
786 return -1;
787 }
788
ch395_socket_tcp_connect(uint8_t sock)789 int32_t ch395_socket_tcp_connect(uint8_t sock)
790 {
791 int32_t ret = 0;
792 int32_t retry = 0;
793 uint8_t status = 0;
794 uint8_t data[2] = {0};
795
796 if (sock >= MAX_SURPPORT_SOCK_NUM) {
797 LOGE(TAG, "Invalid input %d", sock);
798 return -1;
799 }
800
801 data[0] = CMD1W_TCP_CONNECT_SN;
802 data[1] = sock;
803
804 ret = ch395_spi_data_write(data, sizeof(data));
805 if (ret) {
806 LOGE(TAG, "Fail to send data 0x%x", sock);
807 return -1;
808 }
809
810 /*need to check cmd status*/
811 do {
812 retry++;
813 status = 0;
814 /*need to wait data free interrupt*/
815 ret = ch395_get_cmd_status(&status);
816 if (ret == 0 && (status != CMD_ERR_SUCCESS)) {
817 break;
818 }
819 aos_msleep(2);
820 } while (retry < 20);
821
822 if (retry >= 20) {
823 LOGE(TAG, "Fail to execute cmd tcp connect");
824 return -1;
825 }
826
827 return 0;
828 }
829
ch395_socket_tcp_disconnect(uint8_t sock)830 int32_t ch395_socket_tcp_disconnect(uint8_t sock)
831 {
832 int32_t ret = 0;
833 uint32_t retry = 0;
834 uint8_t status = 0;
835 uint8_t data[2] = {0};
836
837 if (sock >= MAX_SURPPORT_SOCK_NUM) {
838 LOGE(TAG, "Invalid input %d", sock);
839 return -1;
840 }
841
842 data[0] = CMD1W_TCP_CONNECT_SN;
843 data[1] = sock;
844
845 ret = ch395_spi_data_write(data, sizeof(data));
846 if (ret) {
847 LOGE(TAG, "Fail to send data 0x%x", sock);
848 return -1;
849 }
850
851 /*need to check cmd status*/
852 do {
853 retry++;
854 status = 0;
855 /*need to wait data free interrupt*/
856 ret = ch395_get_cmd_status(&status);
857 if (ret == 0 && (status != CH395_ERR_BUSY)) {
858 break;
859 }
860 aos_msleep(2);
861 } while (retry < 20);
862
863 if (retry >= 20) {
864 LOGE(TAG, "Fail to execute cmd tcp disconnect");
865 return -1;
866 }
867
868 return 0;
869 }
870
ch395_socket_data_send(uint8_t sock,uint16_t datalen,uint8_t * pdata)871 int32_t ch395_socket_data_send(uint8_t sock, uint16_t datalen, uint8_t *pdata)
872 {
873 int32_t ret = 0;
874 uint8_t *psend_data = NULL;
875 uint32_t sendlen = 0;
876 int32_t retry = 0;
877
878 if (sock >= MAX_SURPPORT_SOCK_NUM || NULL == pdata) {
879 LOGE(TAG, "Invalid input %d", sock);
880 return -1;
881 }
882
883 sendlen = datalen + 4;
884 psend_data = malloc(sendlen);
885 if (NULL == psend_data) {
886 LOGE(TAG, "%s %d fail to malloc %d data", __FILE__, __LINE__, sendlen);
887 return -1;
888 }
889 memset(psend_data, 0, sendlen);
890
891 psend_data[0] = CMD30_WRITE_SEND_BUF_SN;
892 psend_data[1] = sock;
893 psend_data[2] = (uint8_t) (datalen);
894 psend_data[3] = (uint8_t) (datalen >> 8);
895 memcpy(&psend_data[4], pdata, datalen);
896
897 aos_mutex_lock(&gst_spi_op_mutex, AOS_WAIT_FOREVER);
898 ret = hal_spi_send_ch395_sockdata(&g_st_spi_info, psend_data, sendlen, SPI_TIME_OUT);
899 aos_mutex_unlock(&gst_spi_op_mutex);
900 free(psend_data);
901 if (ret) {
902 LOGE(TAG, "Fail to send data 0x%x", sendlen);
903 return -1;
904 }
905
906 return 0;
907 }
908
ch395_socket_recv_data_len(uint8_t sock,uint16_t * pdatalen)909 int32_t ch395_socket_recv_data_len(uint8_t sock, uint16_t *pdatalen)
910 {
911 int32_t ret = 0;
912 uint8_t send_data[2] = {0};
913
914 if (sock >= MAX_SURPPORT_SOCK_NUM || NULL == pdatalen) {
915 LOGE(TAG, "Invalid input %d", sock);
916 return -1;
917 }
918
919 send_data[0] = CMD12_GET_RECV_LEN_SN;
920 send_data[1] = sock;
921
922 ret = ch395_spi_send_and_recv(send_data, sizeof(send_data), pdatalen, sizeof(uint16_t));
923 if (ret) {
924 LOGE(TAG, "Fail to send data 0x%x", sock);
925 return -1;
926 }
927
928 return 0;
929 }
930
ch395_socket_recv_data(uint8_t sock,uint16_t datalen,uint8_t * pdata)931 int32_t ch395_socket_recv_data(uint8_t sock, uint16_t datalen, uint8_t *pdata)
932 {
933 int32_t ret = 0;
934 uint8_t send_data[4] = {0};
935
936 if (sock >= MAX_SURPPORT_SOCK_NUM || NULL == pdata || datalen == 0) {
937 LOGE(TAG, "Invalid input %d datalen %d", sock, datalen);
938 return -1;
939 }
940
941 send_data[0] = CMD30_READ_RECV_BUF_SN;
942 send_data[1] = sock;
943 send_data[2] = (uint8_t)datalen;
944 send_data[3] = (uint8_t)(datalen >> 8);
945
946 ret = ch395_spi_send_and_recv(send_data, sizeof(send_data), pdata, datalen);
947 if (ret) {
948 LOGE(TAG, "Fail to send data 0x%x", sock);
949 return -1;
950 }
951
952 return 0;
953 }
954
955 /*
956 * Input : enable : 1 enable PING
957 : 0 disable PING
958 */
ch395_ping_enable(uint8_t enable)959 int32_t ch395_ping_enable(uint8_t enable)
960 {
961 int32_t ret = 0;
962 uint8_t cmd_data[2] = {0};
963
964 if (enable != 0 && enable != 1) {
965 LOGE(TAG, "Invalid inpute %d", enable);
966 return -1;
967 }
968
969 cmd_data[0] = CMD01_PING_ENABLE;
970 cmd_data[1] = enable;
971
972 ret = ch395_spi_data_write(cmd_data, sizeof(cmd_data));
973 if (ret) {
974 LOGE(TAG, "Fail to send data 0x%x", enable);
975 return -1;
976 }
977
978 return 0;
979 }
980
981 /*
982 * Input : enable : 1 enable dhcp
983 : 0 disable dhcp
984 */
ch395_dhcp_enable(uint8_t enable)985 int32_t ch395_dhcp_enable(uint8_t enable)
986 {
987 int32_t ret = 0;
988 uint8_t status = 0;
989 uint8_t i = 0;
990 uint8_t cmd_data[2] = {0};
991 /*should do it after chip is enabled*/
992
993 if (enable != 0 && enable != 1) {
994 LOGE(TAG, "Invalid inpute %d", enable);
995 return -1;
996 }
997
998 cmd_data[0] = CMD10_DHCP_ENABLE;
999 cmd_data[1] = enable;
1000
1001 ret = ch395_spi_data_write(cmd_data, sizeof(cmd_data));
1002 if (ret) {
1003 LOGE(TAG, "Fail to send data 0x%x", enable);
1004 return -1;
1005 }
1006 aos_msleep(20);
1007 /*check cmd status*/
1008 while (1) {
1009 ret = ch395_get_cmd_status(&status);
1010 if (ret == 0 && (status != CH395_ERR_BUSY)) {
1011 break;
1012 }
1013 if (i++ > 200) {
1014 return -1;
1015 }
1016 /* we should wait more than 2 ms to get cmd status*/
1017 }
1018 LOGI(TAG, "dhcp enable %d execute successed ", enable);
1019
1020 return 0;
1021 }
1022
ch395_dhcp_get_status(uint8_t * pstatus)1023 int32_t ch395_dhcp_get_status(uint8_t *pstatus)
1024 {
1025 int32_t ret = 0;
1026
1027 if (NULL == pstatus) {
1028 LOGE(TAG, "Invalid inpute ");
1029 return -1;
1030 }
1031
1032 ret = ch395_spi_cmd_query(CMD01_GET_DHCP_STATUS, pstatus);
1033 if (ret) {
1034 LOGE(TAG, "Fail to get dhcp status ret %d", ret);
1035 return -1;
1036 }
1037
1038 return 0;
1039 }
1040
ch395_get_ip_interface(ch395_int_t * pst_inf)1041 int32_t ch395_get_ip_interface(ch395_int_t *pst_inf)
1042 {
1043 int32_t ret = 0;
1044 uint8_t cmd = CMD014_GET_IP_INF;
1045
1046 if (NULL == pst_inf) {
1047 LOGE(TAG, "Invalid input");
1048 return -1;
1049 }
1050
1051 ret = ch395_spi_send_and_recv(&cmd, sizeof(cmd), pst_inf, sizeof(ch395_int_t));
1052 if (ret) {
1053 LOGE(TAG, "Fail to read interface info data");
1054 return -1;
1055 }
1056
1057 return 0;
1058 }
1059
1060 /*should be set before ch395 init*/
ch395_set_tcp_mss(uint16_t mss)1061 int32_t ch395_set_tcp_mss(uint16_t mss)
1062 {
1063 int32_t ret = 0;
1064 uint8_t data[3] = {0};
1065
1066 if (mss > TCP_MSS_MAX_VALUE || mss < TCP_MSS_MIN_VALUE) {
1067 LOGE(TAG, "Invalid Input %d", mss);
1068 return -1;
1069 }
1070
1071 data[0] = CMD20_SET_TCP_MSS;
1072 data[1] = (uint8_t)mss;
1073 data[2] = (uint8_t)(mss >> 8);
1074
1075 ret = ch395_spi_data_write(data, sizeof(data));
1076 if (ret) {
1077 LOGE(TAG, "Fail to write mss value %d", mss);
1078 return -1;
1079 }
1080
1081 return 0;
1082 }
1083
ch395_set_func_param(uint32_t param)1084 int32_t ch395_set_func_param(uint32_t param)
1085 {
1086 int32_t ret = 0;
1087 uint8_t data[5] = {0};
1088
1089 data[0] = CMD40_SET_FUN_PARA;
1090 data[1] = (uint8_t)param;
1091 data[2] = (uint8_t)(param >> 8);
1092 data[3] = (uint8_t)(param >> 16);
1093 data[4] = (uint8_t)(param >> 24);
1094
1095 ret = ch395_spi_data_write(data, sizeof(data));
1096 if (ret) {
1097 LOGE(TAG, "Fail to set func param value %d", param);
1098 return -1;
1099 }
1100
1101 return 0;
1102
1103 }
1104
ch395_set_sock_ttl(uint8_t sock,uint8_t ttl)1105 int32_t ch395_set_sock_ttl(uint8_t sock, uint8_t ttl)
1106 {
1107 int32_t ret = 0;
1108 uint8_t data[3] = {0};
1109
1110 /*should be called after sock is opened*/
1111 if (ttl > TCP_TTL_MAX_VALUE || sock >= MAX_SURPPORT_SOCK_NUM) {
1112 LOGE(TAG, "Invalid Input ttl %d, sock %d", ttl, sock);
1113 return -1;
1114 }
1115
1116 data[0] = CMD20_SET_TTL;
1117 data[1] = sock;
1118 data[2] = ttl;
1119
1120 ret = ch395_spi_data_write(data, sizeof(data));
1121 if (ret) {
1122 LOGE(TAG, "Fail to write sock %d ttl %d", sock, ttl);
1123 return -1;
1124 }
1125
1126 return 0;
1127 }
1128
1129 /* There is 48 blocks in ch395. Each Block size is 512 bytes.
1130 * The default config is :
1131 * sock 0 recv buf 0 8
1132 * send buf 8 4
1133 * sock 1 recv buf 12 8
1134 * send buf 20 4
1135 * sock 2 recv buf 24 8
1136 * send buf 32 4
1137 * sock 3 recv buf 36 8
1138 * send buf 44 4
1139 * other recv buf NULL 0
1140 * send buf NULL 0
1141 */
ch395_sock_set_recv_buf(uint8_t sock,uint8_t startblk,uint8_t blknum)1142 int32_t ch395_sock_set_recv_buf(uint8_t sock, uint8_t startblk, uint8_t blknum)
1143 {
1144 int32_t ret = 0;
1145 uint8_t data[4] = {0};
1146
1147 if (sock >= MAX_SURPPORT_SOCK_NUM || startblk >= MAX_BUF_NUM || blknum >= MAX_BUF_NUM) {
1148 LOGE(TAG, "Invalid input sock %d, startblk %d, blknum %d", sock, startblk, blknum);
1149 return -1;
1150 }
1151
1152 data[0] = CMD30_SET_RECV_BUF;
1153 data[1] = sock;
1154 data[2] = startblk;
1155 data[3] = blknum;
1156
1157 ret = ch395_spi_data_write(data, sizeof(data));
1158 if (ret) {
1159 LOGE(TAG, "Fail to write sock %d startblk %d blknum %d", sock, startblk, blknum);
1160 return -1;
1161 }
1162
1163 return 0;
1164 }
1165
ch395_sock_set_send_buf(uint8_t sock,uint8_t startblk,uint8_t blknum)1166 int32_t ch395_sock_set_send_buf(uint8_t sock, uint8_t startblk, uint8_t blknum)
1167 {
1168 int32_t ret = 0;
1169 uint8_t data[4] = {0};
1170
1171 if (sock >= MAX_SURPPORT_SOCK_NUM || startblk >= MAX_BUF_NUM || blknum >= MAX_BUF_NUM) {
1172 LOGE(TAG, "Invalid input sock %d, startblk %d, blknum %d", sock, startblk, blknum);
1173 return -1;
1174 }
1175
1176 data[0] = CMD30_SET_SEND_BUF;
1177 data[1] = sock;
1178 data[2] = startblk;
1179 data[3] = blknum;
1180
1181 ret = ch395_spi_data_write(data, sizeof(data));
1182 if (ret) {
1183 LOGE(TAG, "Fail to write sock %d startblk %d blknum %d", sock, startblk, blknum);
1184 return -1;
1185 }
1186
1187 return 0;
1188
1189 }
1190
ch395_dev_init(void)1191 int32_t ch395_dev_init(void)
1192 {
1193 int32_t ret = 0;
1194 uint8_t status = CH395_ERR_UNKNOW;
1195 uint8_t cmd = CMD0W_INIT_CH395;
1196 uint8_t i = 0;
1197
1198 ret = ch395_spi_data_write(&cmd, 1);
1199 if (ret) {
1200 LOGE(TAG, "write init cmd fail %d ", ret);
1201 return -1;
1202 }
1203 /*should wait 350ms after init cmd*/
1204 aos_msleep(200);
1205 /*check cmd excute status*/
1206 while (1) {
1207 ret = ch395_get_cmd_status(&status);
1208 if (ret == 0 && status != CH395_ERR_BUSY) {
1209 break;
1210 }
1211 if (i++ > 200) {
1212 return -1;
1213 }
1214 /* we should wait more than 2 ms to get cmd status*/
1215 aos_msleep(2);
1216 }
1217
1218 return 0;
1219 }
1220
1221