赞
踩
实验 3:在搭建好 tcp 服务器,并拟定好协议的前提下,接收每一个 bin 文件的块,配置到 fpga。
fpga
fpga1
stm32
// fpga引脚 stm32引脚
// 用不到D_OUT
#define PROGRAM_B PB0
#define INT_B PB1
#define CCLK PC10
#define D01_DIN PC12
#define DONE PD3
搜索下载关键词:Xilinx XAPP583 Using a Microprocessor to Configure Xilinx 7 Series FPGAs
#include "load_fpga.h" #include <stdio.h> #include "main.h" #define WRITE_PROGRAM_B(x) HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, x) #define WRITE_CCLK(x) HAL_GPIO_WritePin(GPIOC, GPIO_PIN_10, x) #define WRITE_D01_DIN(x) HAL_GPIO_WritePin(GPIOC, GPIO_PIN_12, x) #define READ_INT_B() HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) #define READ_DONE() HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_3) /// @brief 交换4字节顺序 /// eg: 0xaabbccdd -> 0xddccbbaas /// @param data /// @return unsigned int swap_uint32(unsigned int data) { unsigned int swapped; swapped = ((data << 24) & 0xFF000000) | ((data << 8) & 0x00FF0000) | ((data >> 8) & 0x0000FF00) | ((data >> 24) & 0x000000FF); return swapped; } /// @brief 产生count个时钟上升沿 /// @param drvdata /// @param count void shift_cclk(unsigned int count) { int i; // WRITE_CCLK(0); // 感觉有点多余,影响接收速度了 for (i = 0; i < count; ++i) { WRITE_CCLK(1); WRITE_CCLK(0); } } /// @brief 写入每一位,从高位开始 /// @param data32 void shift_word_out(unsigned int data32) { int i; unsigned int data; for (i = 31; i >= 0; i--) { data = (data32 & 1 << i) ? 1 : 0; WRITE_D01_DIN(data); shift_cclk(1); } } /// @brief 准备写入 /// 配置准备下入状态 /// @param /// @return 成功返回0 int program_init(void) { int i = 0; /* Configuration Reset */ WRITE_PROGRAM_B(0); HAL_Delay(1); // 1us WRITE_PROGRAM_B(1); /* Wait for Device Initialization */ while (READ_INT_B() == 0) { ++i; if (i > 0x00010000) { printf("INIT_B has not gone high\n"); return -1; } } return 0; } /// @brief 写入fpga /// @param buf /// @param len /// @return 成功返回0 int program_data(char *buf, int len) { int i; for (i = 0; i < len; i += 4) { shift_word_out(swap_uint32(*(uint32_t *)(buf + i))); if (READ_INT_B() == 0) { printf("INIT_B error\n"); return -1; } } return 0; } /// @brief 写入完成 /// @param /// @return 成功返回0 int program_done(void) { /* Check INIT_B */ if (READ_INT_B() == 0) { printf("INIT_B error\n"); return -1; } /* Wait for DONE to assert */ int i = 0; while (READ_DONE() == 0) { shift_cclk(1); // 不加会导致又概率失败 ++i; if (i > 0x00010000) { printf("DONE has not gone high\n"); return -1; } } /* Compensate for Special Startup Conditions */ shift_cclk(8); return 0; }
#include "tcp_echo.h" #include "lwip/opt.h" #include "lwip/tcp.h" #include "load_fpga.h" #if LWIP_NETCONN #include "lwip/sys.h" #include "lwip/api.h" #define TCPECHO_THREAD_PRIO (tskIDLE_PRIORITY + 4) #define kbuffer_len 1024 #define kheader_size 24 #define kdata_len 1000 #define kmagic 0xaa5555aa char buffer[kbuffer_len]; struct tcp_package_header { uint32_t magic; uint32_t type; uint32_t data_offset; uint32_t data_len; uint32_t order; uint32_t magic1; }; /// @brief TCP服务函数 /// @param arg static void tcpecho_thread(void *arg) { struct netconn *conn, *newconn; err_t err, accept_err; struct netbuf *buf; void *data; u16_t len; int ret = 0; LWIP_UNUSED_ARG(arg); #if 1 /* Create a new connection identifier. */ conn = netconn_new(NETCONN_TCP); if (conn != NULL) { /* Bind connection to well known port number 7. */ err = netconn_bind(conn, NULL, 7); if (err == ERR_OK) { /* Tell connection to go into listening mode. */ netconn_listen(conn); while (1) { /* Grab new connection. */ accept_err = netconn_accept(conn, &newconn); /* Process the new connection. */ if (accept_err == ERR_OK) { while (netconn_recv(newconn, &buf) == ERR_OK) { netbuf_data(buf, &data, &len); do { // 1 拿到帧头 struct tcp_package_header *head; head = (struct tcp_package_header *)data; // 2 判断type switch (head->type) { case 0xA: ret = program_init(); break; case 0xB: ret = program_data( (char *)data + sizeof(struct tcp_package_header), head->data_len); break; case 0xC: ret = program_done(); break; default: break; } // 3 回发给tcp_client if (ret < 0) { head->data_offset = 1; } else { head->data_offset = 0; } netconn_write(newconn, head, sizeof(struct tcp_package_header), NETCONN_COPY); } while (netbuf_next(buf) >= 0); netbuf_delete(buf); } /* Close connection and discard connection identifier. */ netconn_close(newconn); netconn_delete(newconn); } } } else { netconn_delete(newconn); } } #endif } // 创建tcp服务函数任务 void tcpecho_init(void) { sys_thread_new("tcpecho_thread", tcpecho_thread, NULL, DEFAULT_THREAD_STACKSIZE, TCPECHO_THREAD_PRIO); } #endif /* LWIP_NETCONN */
加载前
加载后
上位机
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。