STM32f407 网络接收 fpga 的 bin 文件并更新到 fpga series7(3)

news2024/11/26 2:42:31

STM32f407 网络接收 fpga 的 bin 文件并更新到 fpga series7(3)

简介

实验 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

引脚

在这里插入图片描述

时序

在这里插入图片描述

伪代码在手册里,自己看

stm32cube 配置

在这里插入图片描述

单片机代码

load_fpga.c

#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;
}

tcp_echo.c

#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 */

加载前

在这里插入图片描述
加载后
在这里插入图片描述

上位机在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2061185.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

快速了解矿用电源特性及其性能测试利器电源ate检测系统

在矿产资源开采的每一个环节&#xff0c;矿用电源都扮演着幕后英雄的角色&#xff0c;它的作用不可小觑。那么什么是矿用电源呢&#xff1f;电源ate检测系统如何助力矿用电源性能测试呢&#xff1f; 矿用电源模块介绍 矿用电源是专门用于矿井等地下作业场所的重要电源设备&…

阿里MAXCOMPUTE数据专辑信息读取并同步数据表

阿里MAXCOMPUTE数据专辑信息读取并同步数据表 在阿里云大数据体系中&#xff0c;我们可以使用数据地图的数据专辑&#xff0c;对数据的类别等进行一个管理 那么管理后的数据&#xff0c;我们想要落表进行相关的数据分析&#xff0c;如何做呢&#xff1f; 查看阿里云官方文档…

虚幻5|制作刀光粒子效果

一&#xff0c;创建一个粒子效果 1.Niagara系统 2.右键添加发射器&#xff0c;创建一个空白 3.点击空白的渲染&#xff0c;选择条带渲染器 4.右侧选择自定义侧面矢量 5.按顺序如下&#xff0c;编辑刀光的周期和方向 6.添加一个spawn per frame&#xff0c;使刀光每帧都在生成&…

Upload-Lab第13关:POST上传方式如何巧妙利用%00截断法绕过上传验证

第13关概述 在Upload-Lab第13关中&#xff0c;服务器会对上传的文件进行严格的扩展名检查。只有符合白名单的扩展名&#xff08;如.jpg、.png等&#xff09;才能成功上传。我们的目标是绕过这种检查&#xff0c;将恶意文件&#xff08;如.php&#xff09;上传到服务器。以下是…

图神经网络教程4-卷积图神经网络

介绍 卷积神经网络在涉及图像的预测任务上取得了最先进的性能。通过将权值学习核与输入图像卷积&#xff0c;CNN根据其视觉外观提取感兴趣的特征&#xff0c;无论它们在图像中的位置是哪里。虽然图像只是图的一个特殊情况(见图1 (a))&#xff0c;但是为图领域定义一个广义卷积…

了解同步带选择同步带

同步带和轮选型 同步带传动属于皮带传动&#xff0c;但是改进了传统皮带传动无法保持严格的传动比的打滑问题&#xff0c;传统皮带传动依靠皮带和皮带轮张紧时产生的摩擦力传输动力&#xff0c;但是从动轮遇到障碍或超载荷时&#xff0c;皮带会在皮带轮产生滑动。 解决打滑问题…

企业高性能web服务器【Nginx详解】

一.Web 服务基础介绍 1.1 互联网发展历程 1993年3月2日&#xff0c;中国科学院高能物理研究所租用AT&T公司的国际卫星信道建立的接入美国SLAC国家实 验室的64K专线正式开通&#xff0c;成为我国连入Internet的第一根专线。 1995年马云开始创业并推出了一个web网站 中国黄页…

【其它-高效处理小技巧】如何批量备份263企业邮箱邮件

如何批量备份263企业邮箱邮件 近期由于有人离职&#xff0c;邮箱要注销&#xff0c;之前邮箱内有5000多封沟通邮件&#xff0c;为避免将来找不到沟通过程&#xff0c;所以需要备份。 目的&#xff1a;一次性备份所有沟通邮件 方法一&#xff1a; 少于20封邮件&#xff0c;推荐…

基于vue框架的爱心公益网站532y9(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。

系统程序文件列表 项目功能&#xff1a;用户,志愿者,公益资讯,捐赠物资,公益项目,项目报名,公益类型 开题报告内容 基于Vue框架的爱心公益网站 开题报告 一、项目背景与意义 在快速发展的现代社会中&#xff0c;公益事业作为社会文明进步的重要标志&#xff0c;越来越受到…

创建GPTs,打造你的专属AI聊天机器人

在2023年11月的「OpenAI Devday」大会上&#xff0c;OpenAI再度带来了一系列令人瞩目的新功能&#xff0c;其中ChatGPT方面的突破尤为引人关注。而GPTs的亮相&#xff0c;不仅标志着个性化AI时代的到来&#xff0c;更为开发者和普通用户提供了前所未有的便利。接下来&#xff0…

WPS又崩了,在黑神话中挤出一条热搜!

吉祥知识星球http://mp.weixin.qq.com/s?__bizMzkwNjY1Mzc0Nw&mid2247485367&idx1&sn837891059c360ad60db7e9ac980a3321&chksmc0e47eebf793f7fdb8fcd7eed8ce29160cf79ba303b59858ba3a6660c6dac536774afb2a6330#rd 《网安面试指南》http://mp.weixin.qq.com/s?…

idea中如何不重启tomcat 即可看到修改内容变化

我 | 在这里 ⭐ 全栈开发攻城狮、全网10W粉丝、2022博客之星后端领域Top1、专家博主。 &#x1f393;擅长 指导毕设 | 论文指导 | 系统开发 | 毕业答辩 | 系统讲解等。已指导60位同学顺利毕业。持续接单中。。。 ✈️个人公众号&#xff1a;热爱技术的小郑。回复 Java全套视频教…

基于ElementPlus的分页表格组件ReTable

分页表格ReTable 组件实现基于 Vue3 Element Plus Typescript&#xff0c;同时引用 vueUse lodash-es tailwindCss (不影响功能&#xff0c;可忽略) 基于ElTable和ElPagination组件封装的分页表格&#xff0c;支持本地分页以及远程请求两种方式。本地数据分页自带全量数据的…

QT聊天室基于Tcp

server.cpp #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget),server(new QTcpServer(this)) // 给服务器指针对象实例化空间{ui->setupUi(this); }Widget::~Widget() {delete ui; }…

集团数字化转型方案(一)

集团数字化转型方案通过系统集成先进的物联网&#xff08;IoT&#xff09;、大数据分析、人工智能&#xff08;AI&#xff09;和云计算技术&#xff0c;构建一个全面智能化的运营生态系统&#xff0c;涵盖从数据驱动的决策支持、智能化业务流程优化、到全渠道客户体验提升的各个…

【算法基础实验】图论-最小生成树-Prim的即时实现

理论知识 Prim算法是一种用于计算加权无向图的最小生成树&#xff08;MST, Minimum Spanning Tree&#xff09;的贪心算法。最小生成树是一个连通的无向图的子图&#xff0c;它包含所有的顶点且总权重最小。Prim算法从一个起始顶点开始&#xff0c;不断将权重最小的边加入生成…

CTFHUB | web进阶 | JSON Web Token | 无签名

一些JWT库也支持none算法&#xff0c;即不使用签名算法。当alg字段为空时&#xff0c;后端将不执行签名验证 开启题目 账号密码随便输&#xff0c;登录之后显示只有 admin 可以获得 flag 在此页面抓包发到 repeater&#xff0c;这里我们需要用到一个 Burp 插件&#xff0c;按图…

科研绘图配色大全

目录 01 颜色网站 1.1 Material 1.1.1 tailwindcolor 1.2 Trending Color Palettes1.3 Material Palette 1.4 Graphs Colors 1.5 RGB颜色值与十六进制颜色码转换 1.6 colorbrewer 1.7 优设 1.8 Chinese Colors1.9 handpicked colors 02 科研绘图配色方案 2.1 常见科技…

干货:2024必备的四大PDF编辑器推荐!

面对PDF文件的编辑需求&#xff0c;你是否感到无从下手&#xff1f;那么&#xff0c;今天就为大家推荐几款实用的PDF编辑工具&#xff0c;让你轻松应对各种PDF编辑难题。 福昕PDF编辑器 链接&#xff1a;editor.foxitsoftware.cn 福昕PDF编辑器多功能专业级是我PDF编辑器。它…

【C++例题 / 训练】二分算法(模板 例题)

引言 二分也就是二分查找&#xff0c;又叫折半查找。这种算法正如其名&#xff0c;每一次都要分一半。 二分算法可以分为二分查找和二分答案。 以在一个升序数组中查找一个数为例&#xff0c;每次考察数组当前部分的中间元素&#xff0c;如果中间元素刚好是要找的&#xff0…