/**************************************************************************** Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics Ltd. ALL RIGHTS RESERVED. This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics Ltd and MAY NOT be copied by any method or incorporated into another program without the express written consent of Aerospace C.Power. This Information or any portion thereof remains the property of Aerospace C.Power. The Information contained herein is believed to be accurate and Aerospace C.Power assumes no responsibility or liability for its use in any way and conveys no license or title under any patent or copyright and makes no representation or warranty that this Information is free from patent or copyright infringement. ****************************************************************************/ /* os shim includes */ #include "os_types.h" #include "os_task.h" #include "os_utils.h" /* common includes */ #include "iot_io.h" #include "iot_bitops.h" #include "iot_pkt.h" #include "iot_ipc.h" #include "iot_plc_lib.h" #include "iot_dbglog_api.h" #include "iot_config.h" /* driver includes */ #include "iot_clock.h" #include "iot_uart.h" #include "iot_led.h" /* cli includes */ #include "iot_cli.h" #include "iot_uart_h.h" /* debug includes*/ #include "dbg_io.h" #include "apb_dma.h" #include "dma_sw.h" #include "iot_gpio_api.h" #include "apb_glb_reg.h" #include "hw_reg_api.h" #include "gpio_mtx_reg.h" #include "pin_rf.h" #include "apb.h" #include "ahb_hw.h" #include "gpio_mtx.h" #include "iot_share_task.h" #include "gp_timer.h" #include "iot_pkt.h" #include "dwc_eth.h" #include "iot_img_hdr.h" #define K3D_RUN_MODE 3 // 1: binary mode 2: raw mode extern void ddr_module_cache_cfg(); extern void camera_module_init(); extern void ai_depth_auto_mode_cfg(); extern void ai_ref_pic_capture(); extern void ai_poll_done(); extern void ai_ram_auto_mode_cfg(); static const iot_pkt_config_t test_pkt_config = { { { 256, 50, PKT_OWNER_ALL, }, { 600, 50, PKT_OWNER_ALL, }, { 1100, 15, PKT_OWNER_ALL, }, { 2200, 6, PKT_OWNER_ALL, }, { 0, 0, PKT_OWNER_NONE, }, { 0, 0, PKT_OWNER_NONE, }, { 0, 0, PKT_OWNER_NONE, }, { 0, 0, PKT_OWNER_NONE, }, } }; /* dma config */ #define DMA_ETH_CHKSUM DMA_DEV_SW0 typedef struct _chksum_dma { uint8_t *src; uint16_t len; } chksum_dma_t; desc_sw_t out_descls[4]; desc_sw_t in_descls[4]; chksum_dma_t g_chksum_buf_t[4] = {0}; volatile uint8_t g_chksum_flag = 0; void IRAM_ATTR dma_handler(int vector, int status) { (void)vector; if (status & DMA_OUT_TOTAL_EOF_INT_ST_MASK) { //dma_pop_all_desc_list(DTEST_DMA_DEV, &desc1, &desc2); } if (status & 8) { g_chksum_flag = 1; } } void eth_chksum_get(chksum_dma_t *chksum_dma, uint8_t num, void *dest, uint16_t total_len, uint16_t *chksum) { chksum_dma_t *data = NULL; uint8_t *d = (uint8_t *) dest; uint8_t i = 0; if (num > 4) { return; } if (total_len > 2000) { return; } for (i = 0; i < num; i++) { data = chksum_dma+i; #if 0 DMA_MAKE_DESC(&out_descls[i], data->src, data->len, data->len, 0, 0, 0, DESC_OWNER_DMA); #else DMA_MAKE_SW_DESC(&out_descls[i], data->src, 0, data->len, 1, 0, 0, DESC_OWNER_DMA, 0); #endif //make out desc list out_descls[i].n_ptr = NULL; if (i) { out_descls[i].l_ptr = &out_descls[i-1]; out_descls[i - 1].n_ptr = &out_descls[i]; } else { out_descls[i].l_ptr = NULL; } } #if 0 DMA_MAKE_DESC(&in_descls[0], d, total_len, total_len, 0, 0, 0, DESC_OWNER_DMA); #else DMA_MAKE_SW_DESC(&in_descls[0], d, 0, total_len, 1, 0, 0, DESC_OWNER_DMA, 0); #endif g_chksum_flag = 0; dma_sw_start(DMA_ETH_CHKSUM, in_descls, out_descls); while(1) { if (g_chksum_flag) { *chksum = dma_sw_verify_value_get(DMA_ETH_CHKSUM); break; } } return; } t_dwc_ctrl *g_emac_ctrl = NULL; #define EMAC_TEST_UNIT 0 char dst_ip[] = {192, 168, 4, 163}; char src_ip[] = {192, 168, 4, 28}; os_task_h test_init_handle; os_task_h test_send_handle; extern int platform_init(); void signal_dump(int sig) { int data; if(sig < 57) { data = *(volatile int*)(0x44020000 + 0x4*sig); iot_printf("\r\nSIGN#%02d(CORE#%02d, DEFT#%02d) <- GPIO#%03d.", sig, (data&0x1000)?1:0, (data&0x300)>>8, data&0xFF); } else { iot_printf("\r\nSIGN#%02d INVALID!"); } } void gpio_dump(int g) { int data, data2, addr; if(g < 47) { if(g < 29){ addr = 0x44007000 + 0x24 + (g << 2); } else if(g < 37 ){ addr = 0x44007000 + 0x4 + ((g-29)<<2); } else if(g < 43){ addr = 0x44007000 + 0xa8 + ((g-37)<<2); } else if( g < 47){ addr =0x44007000 + 0x98 + ((g-43)<< 2); } data = *(volatile int*)addr; data2 = *(volatile int*)(0x44020400 + 0x4*g); iot_printf("\r\nGPIO#%02d(FUNC#%02d, PULL#%c%c) <- SIGN#%03d.", g, (data&0x30)>>4, (data&0x80)?'U':'-', (data&0x40)?'D':'-', data2&0xFF); } else { iot_printf("\r\nGPIO#%02d INVALID!"); } } void eth_gpio_dump(void) { int g; for(g = 8; g < 15; g++) { gpio_dump(g); } gpio_dump(18); gpio_dump(19); signal_dump(43); } #define IMG_LENGTH 1024 #define IMG_WIDTH 720 #define IMG_BIT 16 #define UDP_PROTOCOL 17 extern void dwc_gpio_bind(int unit); extern uint8_t g_print_enable; #define SWAP_L2B_SHORT(v) ((((v)&0xff) << 8) | (((v)&0xff00) >> 8)) #pragma pack(push) #pragma pack(1) typedef struct _eth_header { uint8_t dst_mac[6]; uint8_t src_mac[6]; uint16_t eth_type; } eth_header_t; typedef struct _ip_header { uint8_t hdr_len:4; uint8_t version:4; uint8_t tos; // type of service uint16_t tot_len; // total length uint16_t id; // identification uint16_t frag_off; // uint8_t ttl; // time to live uint8_t protocol; // protocol : 17:UDP uint16_t chk_sum; // check sum uint8_t srcaddr[4]; // src ip address uint8_t dstaddr[4]; // dest ip address } ip_header_t; typedef struct _udp_header { uint16_t src_port; uint16_t dst_port; uint16_t udp_len; uint16_t chk_sum; } udp_header_t; typedef struct _eth_udp_header { eth_header_t eth_hdr; ip_header_t ip_hdr; udp_header_t udp_hdr; } eth_udp_header_t; typedef struct _img_header { uint32_t frame_id; uint32_t pkt_id; uint32_t pkt_size; } img_header_t; typedef struct _pseudo_header { uint16_t len; uint8_t mbz; uint8_t protocol; uint8_t dst[4]; uint8_t src[4]; } pseudo_header_t; #pragma pack(pop) // global value set uint8_t dst_mac[6] = {0x00, 0x21, 0x85, 0xc5, 0x2b, 0x8f}; uint16_t g_eth_type = SWAP_L2B_SHORT(0x0800); uint16_t g_udp_src_port = SWAP_L2B_SHORT(1313); uint16_t g_udp_dst_port = SWAP_L2B_SHORT(46832); uint16_t chksum(void *data, uint16_t len) { //return 0; uint32_t acc; uint16_t src; uint8_t *octetptr; acc = 0; octetptr = (uint8_t*)data; while (len > 1) { src = (*octetptr) << 8; octetptr++; src |= (*octetptr); octetptr++; acc += src; len -= 2; } if (len > 0) { src = (*octetptr) << 8; acc += src; } acc = (acc >> 16) + (acc & 0x0000ffffUL); if ((acc & 0xffff0000UL) != 0) { acc = (acc >> 16) + (acc & 0x0000ffffUL); } src = (uint16_t)acc; return ~src; } void eth_test_send_udp(uint8_t *piece, uint32_t size, uint32_t frame_id, uint16_t pkt_id) { iot_pkt_ls lst; uint32_t udp_frame_size = size + sizeof(img_header_t) + sizeof(eth_udp_header_t); if (udp_frame_size > 1500) { IOT_ASSERT(0); } again: lst.pkt = iot_pkt_alloc(udp_frame_size, 0); if (lst.pkt == NULL) { //g_print_enable = 1; //IOT_ASSERT(0); //iot_printf("alloc failed\n"); //g_print_enable = 0; goto again; } lst.next = NULL; iot_pkt_set_data(lst.pkt, lst.pkt->head); iot_pkt_set_tail(lst.pkt, lst.pkt->data + udp_frame_size + 4); // udp header and payload uint32_t udp_len = udp_frame_size - sizeof(eth_header_t) - sizeof(ip_header_t); #if 0 /* udp packet and sw checksum */ udp_header_t *udp_hdr = (udp_header_t *)(lst.pkt->data + sizeof(eth_header_t) + sizeof(ip_header_t)); // fill udp header data udp_hdr->src_port = g_udp_src_port; udp_hdr->dst_port = g_udp_dst_port; udp_hdr->udp_len = SWAP_L2B_SHORT(udp_len); img_header_t *img_hdr = (img_header_t *)(lst.pkt->data + sizeof(eth_udp_header_t)); img_hdr->frame_id = frame_id; img_hdr->pkt_id = pkt_id; img_hdr->pkt_size = size; // fill img data from piece uint8_t *img_data = lst.pkt->data + sizeof(eth_udp_header_t) + sizeof(img_header_t); os_mem_cpy(img_data, piece, size); //os_mem_set(img_data, 0, size); pseudo_header_t *psd_hdr = (pseudo_header_t *)(lst.pkt->data + sizeof(eth_header_t) + sizeof(ip_header_t) - sizeof(pseudo_header_t)); os_mem_cpy(psd_hdr->src, src_ip, sizeof(src_ip)); os_mem_cpy(psd_hdr->dst, dst_ip, sizeof(dst_ip)); psd_hdr->len = udp_hdr->udp_len; psd_hdr->protocol = UDP_PROTOCOL; psd_hdr->mbz = 0; udp_hdr->chk_sum = 0; udp_hdr->chk_sum = chksum(psd_hdr, udp_len + sizeof(pseudo_header_t)); udp_hdr->chk_sum = SWAP_L2B_SHORT(udp_hdr->chk_sum); #else /* udp packet and hw checksum */ udp_header_t *udp_hdr = (udp_header_t *)(lst.pkt->data + sizeof(eth_header_t) + sizeof(ip_header_t)); pseudo_header_t *psd_hdr = (pseudo_header_t *)(lst.pkt->data + sizeof(eth_header_t) + sizeof(ip_header_t) - sizeof(pseudo_header_t)); uint16_t udp_chksum =0; udp_hdr->chk_sum = 0; udp_hdr->udp_len = SWAP_L2B_SHORT(udp_len); // fill udp header data udp_header_t tmp_uh = {0}; tmp_uh.src_port = g_udp_src_port; tmp_uh.dst_port = g_udp_dst_port; tmp_uh.udp_len = SWAP_L2B_SHORT(udp_len); // fill img header data img_header_t tmp_ih = {0}; tmp_ih.frame_id = frame_id; tmp_ih.pkt_id = pkt_id; tmp_ih.pkt_size = size; pseudo_header_t tmp_ph = {0}; os_mem_cpy(tmp_ph.src, src_ip, sizeof(src_ip)); os_mem_cpy(tmp_ph.dst, dst_ip, sizeof(dst_ip)); tmp_ph.len = udp_hdr->udp_len; tmp_ph.protocol = UDP_PROTOCOL; tmp_ph.mbz = 0; g_chksum_buf_t[0].src = (uint8_t *)&tmp_ph; g_chksum_buf_t[0].len = sizeof(pseudo_header_t); g_chksum_buf_t[1].src = (uint8_t *)&tmp_uh; g_chksum_buf_t[1].len = sizeof(udp_header_t); g_chksum_buf_t[2].src = (uint8_t *)&tmp_ih; g_chksum_buf_t[2].len = sizeof(img_header_t); g_chksum_buf_t[3].src = (uint8_t *)piece; g_chksum_buf_t[3].len = size; uint16_t total_len = sizeof(pseudo_header_t) + sizeof(udp_header_t) + sizeof(img_header_t) + size; eth_chksum_get(g_chksum_buf_t, 4, psd_hdr, total_len, &udp_chksum); udp_hdr->chk_sum = SWAP_L2B_SHORT(udp_chksum); #endif // ip header ip_header_t *ip_hdr = (ip_header_t *)(lst.pkt->data + sizeof(eth_header_t)); ip_hdr->version = 4; ip_hdr->hdr_len = 5; ip_hdr->tos = 0; ip_hdr->tot_len = SWAP_L2B_SHORT(udp_frame_size - sizeof(eth_header_t)); ip_hdr->id = SWAP_L2B_SHORT(8627); ip_hdr->frag_off = SWAP_L2B_SHORT(0); ip_hdr->ttl = 64; ip_hdr->protocol = 17; os_mem_cpy(ip_hdr->srcaddr, src_ip, sizeof(src_ip)); os_mem_cpy(ip_hdr->dstaddr, dst_ip, sizeof(dst_ip)); #if 0 // sw checksum ip_hdr->chk_sum = 0; ip_hdr->chk_sum = chksum(ip_hdr, sizeof(ip_header_t)); ip_hdr->chk_sum = SWAP_L2B_SHORT(ip_hdr->chk_sum); #else // hw checksum uint16_t chksum =0; ip_header_t test_ip_head = {0}; g_chksum_buf_t[0].src = (uint8_t *)ip_hdr; g_chksum_buf_t[0].len = sizeof(ip_header_t); ip_hdr->chk_sum = 0; eth_chksum_get(g_chksum_buf_t, 1, &test_ip_head, sizeof(ip_header_t), &chksum); ip_hdr->chk_sum = SWAP_L2B_SHORT(chksum); #endif // eth header eth_header_t *eth_hdr = (eth_header_t *)lst.pkt->data; dwc_mac_addr_get(g_emac_ctrl, (uint8_t *)eth_hdr->src_mac); os_mem_cpy(eth_hdr->dst_mac, dst_mac, sizeof(dst_mac)); eth_hdr->eth_type = g_eth_type; /* send udp packet */ dwc_eth_send_frame(g_emac_ctrl, &lst); } void eth_test_rcv(t_dwc_ctrl* p_ctrl, uint8_t * data, uint32_t len) { ///* int i; iot_printf("\r\nEth rcv (port=%d, pack_len=%d),packet dump :\r\n", p_ctrl->unit, len); for(i=0; i