当前位置: 首页 > news >正文

hpm使用笔记————使用usb作为从机接收来自上位机的数据然后通过spi主机发送给spi从机

历程整合

    • 环境
    • 要求
    • 任务需求
    • 任务实现
    • 代码实现
    • 任务测试
      • 功能测试
    • 结束

环境

  • hpm_sdk v 1.7.0
  • ses v8.10

要求

例程demo USB-CDC 作为从机接收,然后把接收到的数据转发给SPI,SPI传输出去

任务需求

  • USB使用cherry协议栈进行开发

  • 作为device设备(从机

  • CDC–> 虚拟串口 然后通过spi 协议 去发送

  • spi 主机\从机—>进行发送

任务实现

  • cherryusb CDC 虚拟串口

  • 确定使用cherryusb协议栈进行开发(轻量化)

    从sdk中构建usb cdc 虚拟串口历程

    串口13接收数据然后发送给spi spi 主机转发,从机接收

  • SPI \主机\从机

  • 使用历程中的spi协议进行测试

    发送/接收

代码实现

main.c

/** Copyright (c) 2022 HPMicro** SPDX-License-Identifier: BSD-3-Clause**/#include <stdio.h>
#include "board.h"
#include "hpm_debug_console.h"
#include "usb_config.h"#include "hpm_spi_drv.h"
#include "hpm_clock_drv.h"#define LED_FLASH_PERIOD_IN_MS 300extern volatile bool dtr_enable;
extern void cdc_acm_init(uint8_t busid, uint32_t reg_base);
extern void cdc_acm_data_send_with_dtr_test(uint8_t busid);extern uint8_t read_buffer[512];   /* vcom接收的数组 *//**************************************************************/spi_timing_config_t timing_config = {0};spi_format_config_t format_config = {0};spi_control_config_t control_config = {0};hpm_stat_t stat;
uint8_t wbuff[10] ;//= {0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9};
uint8_t rbuff[10] = {0};void spi_init(void){uint32_t spi_clcok;spi_clcok = board_init_spi_clock(BOARD_APP_SPI_BASE);board_init_spi_pins(BOARD_APP_SPI_BASE);printf("SPI-Master Polling Transfer Example\n");/* set SPI sclk frequency for master */spi_master_get_default_timing_config(&timing_config);timing_config.master_config.clk_src_freq_in_hz = spi_clcok;timing_config.master_config.sclk_freq_in_hz = BOARD_APP_SPI_SCLK_FREQ;if (status_success != spi_master_timing_init(BOARD_APP_SPI_BASE, &timing_config)) {printf("SPI master timming init failed\n");while (1) {}}/* set SPI format config for master */spi_master_get_default_format_config(&format_config);format_config.common_config.data_len_in_bits = BOARD_APP_SPI_DATA_LEN_IN_BITS;format_config.common_config.mode = spi_master_mode;format_config.common_config.cpol = spi_sclk_high_idle;format_config.common_config.cpha = spi_sclk_sampling_even_clk_edges;spi_format_init(BOARD_APP_SPI_BASE, &format_config);printf("SPI-Master transfer format is configured.\n");/* set SPI control config for master */spi_master_get_default_control_config(&control_config);control_config.master_config.cmd_enable = false;  /* cmd phase control for master */control_config.master_config.addr_enable = false; /* address phase control for master */control_config.common_config.trans_mode = spi_trans_write_read_together;
}
extern uint8_t read_buffer[512];
void func_spi_write_data(uint8_t *data_Array,uint32_t bytes){
#if 1stat = spi_transfer(BOARD_APP_SPI_BASE,&control_config,NULL, NULL,(uint8_t *)read_buffer, 10, (uint8_t *)rbuff, ARRAY_SIZE(rbuff));
#elsestat = spi_transfer(BOARD_APP_SPI_BASE,&control_config,NULL, NULL,(uint8_t * )data_Array, bytes, NULL,NULL);for(int i = 0 ;i< sizeof(data_Array); i++){printf("%d\n",data_Array[i]);}
#endif /* 0 */}int main(void)
{board_init();spi_init();board_init_led_pins();board_init_usb_pins();intc_set_irq_priority(CONFIG_HPM_USBD_IRQn, 2);board_timer_create(LED_FLASH_PERIOD_IN_MS, board_led_toggle);printf("cherry usb cdc_acm device sample.\n");cdc_acm_init(0, CONFIG_HPM_USBD_BASE);while(1) {}return 0;
}
/**************************************************************/

cherryusb_cdc.c

/** Copyright (c) 2022-2023 HPMicro** SPDX-License-Identifier: BSD-3-Clause**/#include "usbd_core.h"
#include "usbd_cdc.h"/*!< endpoint address */
#define CDC_IN_EP  0x81
#define CDC_OUT_EP 0x01
#define CDC_INT_EP 0x83/*!< config descriptor size */
#define USB_CONFIG_SIZE (9 + CDC_ACM_DESCRIPTOR_LEN)static const uint8_t device_descriptor[] = {USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01)
};static const uint8_t config_descriptor_hs[] = {USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),CDC_ACM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, USB_BULK_EP_MPS_HS, 0x02),
};static const uint8_t config_descriptor_fs[] = {USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),CDC_ACM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, USB_BULK_EP_MPS_FS, 0x02),
};static const uint8_t device_quality_descriptor[] = {USB_DEVICE_QUALIFIER_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, 0x01),
};static const uint8_t other_speed_config_descriptor_hs[] = {USB_OTHER_SPEED_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),CDC_ACM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, USB_BULK_EP_MPS_FS, 0x02),
};static const uint8_t other_speed_config_descriptor_fs[] = {USB_OTHER_SPEED_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),CDC_ACM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, USB_BULK_EP_MPS_HS, 0x02),
};static const char *string_descriptors[] = {(const char[]){ 0x09, 0x04 }, /* Langid */"HPMicro",                    /* Manufacturer */"HPMicro CDC DEMO",           /* Product */"2024051702",                 /* Serial Number */
};static const uint8_t *device_descriptor_callback(uint8_t speed)
{(void)speed;return device_descriptor;
}static const uint8_t *config_descriptor_callback(uint8_t speed)
{if (speed == USB_SPEED_HIGH) {return config_descriptor_hs;} else if (speed == USB_SPEED_FULL) {return config_descriptor_fs;} else {return NULL;}
}
static const uint8_t *device_quality_descriptor_callback(uint8_t speed)
{(void)speed;return device_quality_descriptor;
}static const uint8_t *other_speed_config_descriptor_callback(uint8_t speed)
{if (speed == USB_SPEED_HIGH) {return other_speed_config_descriptor_hs;} else if (speed == USB_SPEED_FULL) {return other_speed_config_descriptor_fs;} else {return NULL;}
}static const char *string_descriptor_callback(uint8_t speed, uint8_t index)
{(void)speed;if (index >= (sizeof(string_descriptors) / sizeof(char *))) {return NULL;}return string_descriptors[index];
}const struct usb_descriptor cdc_descriptor = {.device_descriptor_callback = device_descriptor_callback,.config_descriptor_callback = config_descriptor_callback,.device_quality_descriptor_callback = device_quality_descriptor_callback,.other_speed_descriptor_callback = other_speed_config_descriptor_callback,.string_descriptor_callback = string_descriptor_callback,
};USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[512];
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[2048];
volatile bool dtr_enable;
volatile bool ep_tx_busy_flag;static void usbd_event_handler(uint8_t busid, uint8_t event)
{switch (event) {case USBD_EVENT_RESET:break;case USBD_EVENT_CONNECTED:break;case USBD_EVENT_DISCONNECTED:break;case USBD_EVENT_RESUME:break;case USBD_EVENT_SUSPEND:break;case USBD_EVENT_CONFIGURED:/* setup first out ep read transfer */usbd_ep_start_read(busid, CDC_OUT_EP, &read_buffer[0], usbd_get_ep_mps(busid, CDC_OUT_EP));break;case USBD_EVENT_SET_REMOTE_WAKEUP:break;case USBD_EVENT_CLR_REMOTE_WAKEUP:break;default:break;}
}extern void func_spi_write_data(uint8_t *data_Array, uint32_t bytes);
void usbd_cdc_acm_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes)
{USB_LOG_RAW("actual out len:%d\r\n", nbytes);usbd_ep_start_read(busid, ep, &read_buffer[0], usbd_get_ep_mps(busid, ep));func_spi_write_data(read_buffer, nbytes);usbd_ep_start_write(busid, CDC_IN_EP, &read_buffer[0], nbytes);
}void usbd_cdc_acm_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
{USB_LOG_RAW("actual in len:%d\r\n", nbytes);if ((nbytes % usbd_get_ep_mps(busid, ep)) == 0 && nbytes) {/* send zlp */usbd_ep_start_write(busid, ep, NULL, 0);} else {ep_tx_busy_flag = false;}
}/*!< endpoint call back */
struct usbd_endpoint cdc_out_ep = {.ep_addr = CDC_OUT_EP,.ep_cb = usbd_cdc_acm_bulk_out
};struct usbd_endpoint cdc_in_ep = {.ep_addr = CDC_IN_EP,.ep_cb = usbd_cdc_acm_bulk_in
};static struct usbd_interface intf0;
static struct usbd_interface intf1;/* function ------------------------------------------------------------------*/void cdc_acm_init(uint8_t busid, uint32_t reg_base)
{usbd_desc_register(busid, &cdc_descriptor);usbd_add_interface(busid, usbd_cdc_acm_init_intf(busid, &intf0));usbd_add_interface(busid, usbd_cdc_acm_init_intf(busid, &intf1));usbd_add_endpoint(busid, &cdc_out_ep);usbd_add_endpoint(busid, &cdc_in_ep);usbd_initialize(busid, reg_base, usbd_event_handler);
}void usbd_cdc_acm_set_dtr(uint8_t busid, uint8_t intf, bool dtr)
{(void)busid;(void)intf;if (dtr) {dtr_enable = 1;}
}
void cdc_acm_data_send_with_dtr_test(uint8_t busid)
{ep_tx_busy_flag = true;write_buffer[0] = 'h';write_buffer[1] = 'p';write_buffer[2] = 'm';write_buffer[3] = 'i';write_buffer[4] = 'c';write_buffer[5] = 'r';write_buffer[6] = 'o';write_buffer[7] = 0x0D;write_buffer[8] = 0x0A;memset(&write_buffer[9], 'a', 2037);write_buffer[2046] = 0x0D;write_buffer[2047] = 0x0A;usbd_ep_start_write(busid, CDC_IN_EP, &write_buffer[0], 2048);while (ep_tx_busy_flag) {}
}

任务测试

功能测试

  • cherryusb 虚拟串口测试

    • 虚拟串口收发数据
  • hpm_spi主机从机收发测试

    • 主机给从机发送数据,从机可以接收到数据
  • 整合工程,通过usb虚拟的串口接收来自上位机的数据,然后通过spi主机发送给spi从机

    • 测试🆗

结束

相关文章:

hpm使用笔记————使用usb作为从机接收来自上位机的数据然后通过spi主机发送给spi从机

历程整合 环境要求任务需求任务实现代码实现任务测试功能测试 结束 环境 hpm_sdk v 1.7.0ses v8.10 要求 例程demo USB-CDC 作为从机接收&#xff0c;然后把接收到的数据转发给SPI&#xff0c;SPI传输出去 任务需求 USB使用cherry协议栈进行开发 作为device设备&#xff08;…...

数据结构(查找算法)

1. 查找的概念 在一堆数据中&#xff0c;找到我们想要的那个数据&#xff0c;就是查找&#xff0c;也称为搜索&#xff0c;很容易想到&#xff0c;查找算法的优劣&#xff0c;取决于两个因素&#xff1a; 数据本身存储的特点查找算法本身的特点 比如&#xff0c;如果数据存储…...

private前端常见算法

1.数组 合并两个有序数组&#xff08;简单-5&#xff09; https://leetcode.cn/problems/merge-sorted-array/description/?envTypestudy-plan-v2&envIdtop-interview-150 移除元素&#xff08;简单-4&#xff09; https://leetcode.cn/problems/remove-element/descr…...

Go语言之十条命令(The Ten Commands of Go Language)

Go语言之十条命令 Go语言简介 Go语言&#xff08;又称Golang&#xff09;‌是由Google开发的一种开源编程语言&#xff0c;首次公开发布于2009年。Go语言旨在提供简洁、高效、可靠的软件开发解决方案&#xff0c;特别强调并发编程和系统编程‌。 Go语言的基本特征 ‌静态强类…...

Residency 与 Internship 的区别及用法解析

Residency 与 Internship 的区别及用法解析 在英文中&#xff0c;“residency” 和 “internship” 都与职业培训相关&#xff0c;但它们的使用场景和具体含义存在显著差异。本文将详细解析这两个词的区别&#xff0c;以及它们在不同语境下的应用。 Residency 的定义及使用场景…...

成品电池综合测试仪:电子设备性能与安全的守护者|鑫达能

在现代科技和工业领域&#xff0c;电池作为能量储存和转换的关键组件&#xff0c;其性能的稳定性和可靠性至关重要。为了确保电池在各种应用场景中都能发挥最佳性能&#xff0c;成品电池综合测试仪应运而生。这一设备不仅能够对电池的各项性能指标进行全面、准确的检测&#xf…...

Taro地图组件和小程序定位

在 Taro 中使用腾讯地图 1.首先在项目配置文件 project.config.json 中添加权限&#xff1a; {"permission": {"scope.userLocation": {"desc": "你的位置信息将用于小程序位置接口的效果展示"}} }2.在 app.config.ts 中配置&#x…...

深入了解 SSL/TLS 协议及其工作原理

深入了解 SSL/TLS 协议及其工作原理 一. 什么是 SSL/TLS?二. SSL/TLS 握手过程三. SSL/TLS 数据加密与传输四. 总结 点个免费的赞和关注&#xff0c;有错误的地方请指出&#xff0c;看个人主页有惊喜。 作者&#xff1a;神的孩子都在歌唱 一. 什么是 SSL/TLS? 安全套接层&am…...

【计算机操作系统:二、操作系统的结构和硬件支持】

第2章 操作系统的结构和硬件支持 2.1 操作系统虚拟机 操作系统虚拟机是一种通过软件技术对硬件资源进行抽象和虚拟化的机制&#xff0c;使用户能够以逻辑方式访问和使用计算机资源。 定义与概念&#xff1a; 虚拟机是操作系统虚拟化技术的核心产物&#xff0c;通过模拟硬件资…...

51单片机——步进电机模块

直流电机没有正负之分&#xff0c;在两端加上直流电就能工作 P1.0-P1.3都可以控制电机&#xff0c;例如&#xff1a;使用P1.0&#xff0c;则需要把线接在J47的1&#xff08;VCC&#xff09;和2&#xff08;OUT1&#xff09;上 1、直流电机实验 要实现的功能是&#xff1a;直…...

当算法遇到线性代数(四):奇异值分解(SVD)

SVD分解的理论与应用 线性代数系列相关文章&#xff08;置顶&#xff09; 1.当算法遇到线性代数&#xff08;一&#xff09;&#xff1a;二次型和矩阵正定的意义 2.当算法遇到线性代数&#xff08;二&#xff09;&#xff1a;矩阵特征值的意义 3.当算法遇到线性代数&#xff0…...

SASS 简化代码开发的基本方法

概要 本文以一个按钮开发的实例&#xff0c;介绍如何使用SASS来简化CSS代码开发的。 代码和实现 我们希望通过CSS开发下面的代码样式&#xff0c;从样式来看&#xff0c;每个按钮的基本样式相同&#xff0c;就是颜色不同。 如果按照传统的方式开发&#xff0c;需要开发btn &…...

40.TryParse尝试转化为int类型 C#例子

也许这个时候学有点晚&#xff0c;但是不管怎样都学了 尝试转化&#xff0c;不能转化就返回bool类型的假 它会直接给括号里面的int类型赋值 代码&#xff1a; using System; using System.Timers; public class Program {static void Main(){int a;bool i;while (true){Get…...

【微服务】2、网关

Spring Cloud微服务网关技术介绍 单体项目拆分微服务后的问题 服务地址问题&#xff1a;单体项目端口固定&#xff08;如黑马商城为8080&#xff09;&#xff0c;拆分微服务后端口各异&#xff08;如购物车808、商品8081、支付8086等&#xff09;且可能变化&#xff0c;前端难…...

红队-shell编程篇(上)

声明 通过学习 泷羽sec的个人空间-泷羽sec个人主页-哔哩哔哩视频,做出的文章如涉及侵权马上删除文章 笔记的只是方便各位师傅学习知识,以下网站只涉及学习内容,其他的都与本人无关,切莫逾越法律红线,否则后果自负 一、建立Shell文件 1. Shell简介 Shell是一种命令行界面&am…...

电子价签会是零售界的下一个主流?【新立电子】

电子价签&#xff0c;作为一种能够替代传统纸质标签的数字显示屏&#xff0c;已经在零售行业中展现出其巨大的潜力。它具有实时更新、集中管理、高效节能的特点&#xff0c;实现价格的实时更新&#xff0c;大大减少更新价格的工作量和时间。为消费者带来更加便捷、准确的购物体…...

5 分布式ID

这里讲一个比较常用的分布式防重复的ID生成策略&#xff0c;雪花算法 一个用户体量比较大的分布式系统必然伴随着分表分库&#xff0c;分机房部署&#xff0c;单体的部署方式肯定是承载不了这么大的体量。 雪花算法的结构说明 如下图所示: 雪花算法组成 从上图我们可以看…...

SpringBoot | @Autowired 和 @Resource 的区别及原理分析

关注&#xff1a;CodingTechWork 引言 在Spring框架中&#xff0c;Autowired 和 Resource 是两种常用的依赖注入注解&#xff0c;它们都用于自动装配Bean&#xff0c;简化了开发者手动创建和管理Bean的繁琐工作。然而&#xff0c;它们的实现机制和使用方式有所不同。理解这两者…...

『SQLite』解释执行(Explain)

摘要&#xff1a;本节主要讲解SQL的解释执行&#xff1a;Explain。 在 sqlite 语句之前&#xff0c;可以使用 “EXPLAIN” 关键字或 “EXPLAIN QUERY PLAN” 短语&#xff0c;用于描述表查询的细节。 基本语法 EXPLAIN 语法&#xff1a; EXPLAIN [SQLite Query]EXPLAIN QUER…...

0基础学前端-----CSS DAY12

视频参考&#xff1a;B站Pink老师 今天是CSS学习的第十二天&#xff0c;今天开始的笔记对应Pink老师课程中的CSS第七天的内容。 本节重点&#xff1a;CSS高级技巧 本章目录 本节目标1. 精灵图1.1 为什么需要精灵图1.2 精灵图使用案例&#xff1a;拼出自己的名字 2. 字体图标2.…...

【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15

缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下&#xff1a; struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...

工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配

AI3D视觉的工业赋能者 迁移科技成立于2017年&#xff0c;作为行业领先的3D工业相机及视觉系统供应商&#xff0c;累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成&#xff0c;通过稳定、易用、高回报的AI3D视觉系统&#xff0c;为汽车、新能源、金属制造等行…...

ArcGIS Pro制作水平横向图例+多级标注

今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作&#xff1a;ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等&#xff08;ArcGIS出图图例8大技巧&#xff09;&#xff0c;那这次我们看看ArcGIS Pro如何更加快捷的操作。…...

关键领域软件测试的突围之路:如何破解安全与效率的平衡难题

在数字化浪潮席卷全球的今天&#xff0c;软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件&#xff0c;这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下&#xff0c;实现高效测试与快速迭代&#xff1f;这一命题正考验着…...

Xen Server服务器释放磁盘空间

disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...

#Uniapp篇:chrome调试unapp适配

chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器&#xff1a;Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...

uniapp手机号一键登录保姆级教程(包含前端和后端)

目录 前置条件创建uniapp项目并关联uniClound云空间开启一键登录模块并开通一键登录服务编写云函数并上传部署获取手机号流程(第一种) 前端直接调用云函数获取手机号&#xff08;第三种&#xff09;后台调用云函数获取手机号 错误码常见问题 前置条件 手机安装有sim卡手机开启…...

Python 实现 Web 静态服务器(HTTP 协议)

目录 一、在本地启动 HTTP 服务器1. Windows 下安装 node.js1&#xff09;下载安装包2&#xff09;配置环境变量3&#xff09;安装镜像4&#xff09;node.js 的常用命令 2. 安装 http-server 服务3. 使用 http-server 开启服务1&#xff09;使用 http-server2&#xff09;详解 …...

Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、Spring MVC与MyBatis技术解析 一、第一轮基础概念问题 1. Spring框架的核心容器是什么&#xff1f;它的作用是什么&#xff1f; Spring框架的核心容器是IoC&#xff08;控制反转&#xff09;容器。它的主要作用是管理对…...

ZYNQ学习记录FPGA(一)ZYNQ简介

一、知识准备 1.一些术语,缩写和概念&#xff1a; 1&#xff09;ZYNQ全称&#xff1a;ZYNQ7000 All Pgrammable SoC 2&#xff09;SoC:system on chips(片上系统)&#xff0c;对比集成电路的SoB&#xff08;system on board&#xff09; 3&#xff09;ARM&#xff1a;处理器…...