惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

雷峰网
雷峰网
Recorded Future
Recorded Future
B
Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 聂微东
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
量子位
GbyAI
GbyAI
IT之家
IT之家
Microsoft Azure Blog
Microsoft Azure Blog
I
InfoQ
S
SegmentFault 最新的问题
T
Tailwind CSS Blog
有赞技术团队
有赞技术团队
M
MIT News - Artificial intelligence
罗磊的独立博客
MongoDB | Blog
MongoDB | Blog
The Cloudflare Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
腾讯CDC
小众软件
小众软件
博客园 - 三生石上(FineUI控件)
aimingoo的专栏
aimingoo的专栏
博客园 - Franky
Martin Fowler
Martin Fowler
P
Proofpoint News Feed
月光博客
月光博客
博客园_首页
C
Check Point Blog
宝玉的分享
宝玉的分享
Security Archives - TechRepublic
Security Archives - TechRepublic
T
Tenable Blog
Vercel News
Vercel News
SecWiki News
SecWiki News
Security Latest
Security Latest
Microsoft Security Blog
Microsoft Security Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
阮一峰的网络日志
阮一峰的网络日志
Hacker News - Newest:
Hacker News - Newest: "LLM"
Google Online Security Blog
Google Online Security Blog
N
News and Events Feed by Topic
Y
Y Combinator Blog
U
Unit 42
The Register - Security
The Register - Security
云风的 BLOG
云风的 BLOG
K
Kaspersky official blog
WordPress大学
WordPress大学
Blog — PlanetScale
Blog — PlanetScale
N
Netflix TechBlog - Medium
Jina AI
Jina AI

博客园 - 所长

频谱仪 N9020A 操作步骤记录 FPGA-CAN MAC 层 IP 核测试(二) 源码阅读 libero reg 编译时 占用 RAM 资源 而不是 LUT 资源 加扰和解扰 FPGA-CAN MAC 层 IP 核测试(一) 上板实测 Microchip SoftConsole v2022.2-RISC-V-747 polarfire soc 裸机例程中 链接文件 mpfs-envm-lma-scratchpad-vma.ld 分析 FlashPro5 导致 window11 蓝屏 libero verilog 模块例化时,信号不存在 默认是 不连接 A3P250 在线 debug 抓取信号 Identify 在线逻辑分析仪 MPFS250T MSS 引脚 上下拉配置 如何在 libero 中 写一个 axi4 slave 总线的 IP核 可以 和 CoreAXI4Interconnect 连接 (五) 官方参考 verilog 按键消抖模块 如何在 libero 中 写一个 axi4 slave 总线的 IP核 可以 和 CoreAXI4Interconnect 连接 (四) axi-lite 信号抓取 libero Active Probes 如何在 libero 中 写一个 axi4 slave 总线的 IP核 可以 和 CoreAXI4Interconnect 连接 (三) C代码测试 访问卡死 如何在 libero 中 写一个 axi4 slave 总线的 IP核 可以 和 CoreAXI4Interconnect 连接 (二) axi-lite 如何在 libero 中 写一个 axi4 slave 总线的 IP核 可以 和 CoreAXI4Interconnect 连接(一)libero 设置把模块信号变总线方式 libero 2025.2 Macro Library User Guide for SmartFusion 2 and IGLOO 2 FPGAs 如何在 libero 中 写一个 axi4 slave 总线的 IP核 可以 和 CoreAXI4Interconnect 连接 (零) MSS CFG MPFS250T FLASH 只有 128KB 调整代码优化 AD9361 SPI no-os 文件移植 SoftConsole MPFS250T 初学(七) 初始化日志记录 AD9361 SPI no-os 文件移植 SoftConsole MPFS250T 初学(六) 开启 日志打印 Calibration TIMEOUT (0x247, 0x2) AD9361 SPI no-os 文件移植 SoftConsole MPFS250T 初学(五) ad9361_check_cal_done 卡死 AD9361 SPI no-os 文件移植 SoftConsole MPFS250T 初学(四) ad9361_init 编译报错 和 读取 AD9361 ID AD9361 SPI no-os 文件移植 SoftConsole MPFS250T 初学(二) AD9361 初始化流程 熟悉 AD9361 SPI no-os 文件移植 SoftConsole MPFS250T 初学(一) 驱动代码移植 RS422 差分 逻辑分析仪 抓包 libero Simulate - ModelSim ME 仿真 串口数据处理模块 vivado axi PS-PL 封装IP 创造自定义 外设 libero Simulate - ModelSim ME (三) 实战测试 双端口 RAM 读写 libero Simulate - ModelSim ME (二) 语法分析 libero Simulate - ModelSim ME (一) 新建工程 libero smartdebug Libero SoC CMP402 PolarFire SOC MSS 时钟源选择 polarfire Temperature and Voltage Sensor 温度和电压传感器 log2 PolarFire SoC Clock Conditioning Circuitry - CCC (PLL/DLL) 时钟源介绍(二) PolarFire SoC Clock Conditioning Circuitry - CCC (PLL/DLL) 初始化(三) PolarFire SoC Clock Conditioning Circuitry - CCC (PLL/DLL) 简单介绍(一) libero export flashpro express Job Libero MPFS250T PFSoC MSS Configurator 2025.2 DDR3 ECC 配置 Libero MPFS250T 如何使用 FPExpress 2025.2 烧录 MPFS250TS Direct C 编程后,使用 JTAG 读取的 DEVICE_INFO LOG Xilinx SDK 2019.1 使用 JTAG 将 10MB 文件 复制到 ZYNQ 的 DDR中 大约 20 秒 libero PolarFire soc SPI-DirectC 实战 dp_G5M_check_cycle_count libero PolarFire soc SPI-DirectC 实战 dp_G5M_do_program libero PolarFire soc SPI-DirectC 实战 dp_G5M_erase_action libero PolarFire soc SPI-DirectC 实战 dp_G5M_verify_digest_action
AD9361 SPI no-os 文件移植 SoftConsole MPFS250T 初学(三) 接口适配到自己的板子
所长 · 2026-05-04 · via 博客园 - 所长

AD9361 SPI no-os 文件移植 SoftConsole MPFS250T 初学(一) 驱动代码移植 - 所长 - 博客园

AD9361 SPI no-os 文件移植 SoftConsole MPFS250T 初学(二) AD9361 初始化流程 熟悉 - 所长 - 博客园

AD9361 SPI no-os 文件移植 SoftConsole MPFS250T 初学(三) 接口适配到自己的板子 - 所长 - 博客园

AD9361 SPI no-os 文件移植 SoftConsole MPFS250T 初学(四) ad9361_init 编译报错 和 读取 AD9361 ID - 所长 - 博客园

AD9361 SPI no-os 文件移植 SoftConsole MPFS250T 初学(五) ad9361_check_cal_done 卡死 - 所长 - 博客园

AD9361 SPI no-os 文件移植 SoftConsole MPFS250T 初学(六) 开启 日志打印 Calibration TIMEOUT (0x247, 0x2) - 所长 - 博客园

AD9361 SPI no-os 文件移植 SoftConsole MPFS250T 初学(七) 初始化日志记录 - 所长 - 博客园

上面一章  讲了 初始化  ad9361 基本流程,官方给出的接口是 xilinx ,  没有 MPFS250T ,因此 , spi 接口 , gpio 控制接口(复位和使能和同步)需要自己实现

 要实现的接口函数 GPIO 和 SPI 接口 ,: 官方 对这两个接口 实现的比较复杂  ,主要参考 xilinx 接口实现

#define GPIO_OPS    &xil_gpio_ops

#define SPI_OPS     &xil_spi_ops

/**
 * @brief Xilinx platform specific GPIO platform ops structure
 */
const struct no_os_gpio_platform_ops xil_gpio_ops = {
    .gpio_ops_get = &xil_gpio_get,
    .gpio_ops_get_optional = &xil_gpio_get_optional,
    .gpio_ops_remove = &xil_gpio_remove,
    .gpio_ops_direction_input = &xil_gpio_direction_input,
    .gpio_ops_direction_output = &xil_gpio_direction_output,
    .gpio_ops_get_direction = &xil_gpio_get_direction,
    .gpio_ops_set_value = &xil_gpio_set_value,
    .gpio_ops_get_value = &xil_gpio_get_value,
};
/**
 * @brief Xilinx platform specific SPI platform ops structure
 */
const struct no_os_spi_platform_ops xil_spi_ops = {
    .init = &xil_spi_init,
    .write_and_read = &xil_spi_write_and_read,
    .remove = &xil_spi_remove
};

image

看下  复位引脚 控制 调用  顺序:

ad9361_init → 

ad9361_reset(phy)  → 

no_os_gpio_set_value(phy->gpio_desc_resetb, 0); → // 控制引脚 拉低

desc->platform_ops->gpio_ops_set_value(desc, value); → // 调用接口 设置引脚电平

no_os_mdelay(1)  → // 延迟 1ms 

no_os_gpio_set_value(phy->gpio_desc_resetb, 1); → // 控制引脚 拉高

// SPI 接口 和 GPIO   MPFS250T  接口实现 

// SPI 收发数据 注意, AD9361 的 库 不会 给出 发送字节数和接收字节数, 需要 修改  AD9361的库

/**
 * @brief Set the value of the specified GPIO.
 * @param desc - The GPIO descriptor.
 * @param value - The value.
 *                Example: NO_OS_GPIO_HIGH
 *                         NO_OS_GPIO_LOW
 * @return 0 in case of success, -1 otherwise.
 */
int32_t mpfs_gpio_set_value(struct no_os_gpio_desc *desc,
               uint8_t value)
{
    if(desc)
    {
        xprintf( "mpfs_gpio_set_value number:%d,value=%d.\n", desc->number, value );
        if( desc->number == AD9361_RESET_GPIO )
        {
            bsp_ad9361_gpio_set(AD9361_RESET_GPIO,value);
        }

    }

    return 0;
}
/**
 * @brief Write and read data to/from SPI.
 * @param desc - The SPI descriptor.
 * @param data - The buffer with the transmitted/received data.
 * @param bytes_number - Number of bytes to write/read.
 * @return 0 in case of success, -1 otherwise.
 */
int32_t mpfs_spi_write_and_read(struct no_os_spi_desc *desc,
                   uint8_t *data,
                   uint16_t tx_len,
                   uint16_t rx_len)
{

    MSS_SPI_set_slave_select(&g_mss_spi0_lo, MSS_SPI_SLAVE_1);

    MSS_SPI_transfer_block(&g_mss_spi0_lo, data, tx_len, &data[tx_len], rx_len);

    MSS_SPI_clear_slave_select(&g_mss_spi0_lo, MSS_SPI_SLAVE_1);

    // xprintf_hex( "mpfs_spi_tx_rx", data, tx_len+rx_len );

    return 0;
}

 延迟接口,最小延迟 1ms , 因此 us 延迟 用 ms 延迟替代, 不足 1ms 用 1ms  替代

/* Kernel includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"

/**
 * @brief Generate microseconds delay.
 * @param usecs - Delay in microseconds.
 */
void no_os_udelay(uint32_t usecs)
{
    if(usecs<1000)
        vTaskDelay(1);
    else
        vTaskDelay((usecs/1000)+1);
}

/**
 * @brief Generate miliseconds delay.
 * @param msecs - Delay in miliseconds.
 */
void no_os_mdelay(uint32_t msecs)
{
    vTaskDelay(msecs);
}

内存分配和释放接口

/*****************************************/
/***************MALLOC/FREE***********************/
/*****************************************/

/**
 * @brief Allocate memory and return a pointer to it.
 * @param size - Size of the memory block, in bytes.
 * @return Pointer to the allocated memory, or NULL if the request fails.
 */
void *no_os_malloc(size_t size)
{
    return pvPortMalloc(size);
}

/**
 * @brief Allocate memory and return a pointer to it, set memory to 0.
 * @param nitems - Number of elements to be allocated.
 * @param size - Size of elements.
 * @return Pointer to the allocated memory, or NULL if the request fails.
 */
void *no_os_calloc(size_t nitems, size_t size)
{
    return pvPortCalloc(nitems, size);
}

/**
 * @brief Deallocate memory previously allocated by a call to no_os_calloc
 *        or no_os_malloc.
 * @param ptr - Pointer to a memory block previously allocated by a call
 *        to no_os_calloc or no_os_malloc.
 * @return None.
 */
void no_os_free(void *ptr)
{
    vPortFree(ptr);
}