当前位置:   article > 正文

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

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

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

手册

搜索下载关键词: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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115

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 */
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106

加载前

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

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小舞很执着/article/detail/1016483
推荐阅读
相关标签
  

闽ICP备14008679号