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