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 作为从机接收,然后把接收到的数据转发给SPI,SPI传输出去 任务需求 USB使用cherry协议栈进行开发 作为device设备(…...

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

private前端常见算法
1.数组 合并两个有序数组(简单-5) https://leetcode.cn/problems/merge-sorted-array/description/?envTypestudy-plan-v2&envIdtop-interview-150 移除元素(简单-4) https://leetcode.cn/problems/remove-element/descr…...
Go语言之十条命令(The Ten Commands of Go Language)
Go语言之十条命令 Go语言简介 Go语言(又称Golang)是由Google开发的一种开源编程语言,首次公开发布于2009年。Go语言旨在提供简洁、高效、可靠的软件开发解决方案,特别强调并发编程和系统编程。 Go语言的基本特征 静态强类…...
Residency 与 Internship 的区别及用法解析
Residency 与 Internship 的区别及用法解析 在英文中,“residency” 和 “internship” 都与职业培训相关,但它们的使用场景和具体含义存在显著差异。本文将详细解析这两个词的区别,以及它们在不同语境下的应用。 Residency 的定义及使用场景…...

成品电池综合测试仪:电子设备性能与安全的守护者|鑫达能
在现代科技和工业领域,电池作为能量储存和转换的关键组件,其性能的稳定性和可靠性至关重要。为了确保电池在各种应用场景中都能发挥最佳性能,成品电池综合测试仪应运而生。这一设备不仅能够对电池的各项性能指标进行全面、准确的检测…...
Taro地图组件和小程序定位
在 Taro 中使用腾讯地图 1.首先在项目配置文件 project.config.json 中添加权限: {"permission": {"scope.userLocation": {"desc": "你的位置信息将用于小程序位置接口的效果展示"}} }2.在 app.config.ts 中配置&#x…...

深入了解 SSL/TLS 协议及其工作原理
深入了解 SSL/TLS 协议及其工作原理 一. 什么是 SSL/TLS?二. SSL/TLS 握手过程三. SSL/TLS 数据加密与传输四. 总结 点个免费的赞和关注,有错误的地方请指出,看个人主页有惊喜。 作者:神的孩子都在歌唱 一. 什么是 SSL/TLS? 安全套接层&am…...
【计算机操作系统:二、操作系统的结构和硬件支持】
第2章 操作系统的结构和硬件支持 2.1 操作系统虚拟机 操作系统虚拟机是一种通过软件技术对硬件资源进行抽象和虚拟化的机制,使用户能够以逻辑方式访问和使用计算机资源。 定义与概念: 虚拟机是操作系统虚拟化技术的核心产物,通过模拟硬件资…...

51单片机——步进电机模块
直流电机没有正负之分,在两端加上直流电就能工作 P1.0-P1.3都可以控制电机,例如:使用P1.0,则需要把线接在J47的1(VCC)和2(OUT1)上 1、直流电机实验 要实现的功能是:直…...

当算法遇到线性代数(四):奇异值分解(SVD)
SVD分解的理论与应用 线性代数系列相关文章(置顶) 1.当算法遇到线性代数(一):二次型和矩阵正定的意义 2.当算法遇到线性代数(二):矩阵特征值的意义 3.当算法遇到线性代数࿰…...

SASS 简化代码开发的基本方法
概要 本文以一个按钮开发的实例,介绍如何使用SASS来简化CSS代码开发的。 代码和实现 我们希望通过CSS开发下面的代码样式,从样式来看,每个按钮的基本样式相同,就是颜色不同。 如果按照传统的方式开发,需要开发btn &…...
40.TryParse尝试转化为int类型 C#例子
也许这个时候学有点晚,但是不管怎样都学了 尝试转化,不能转化就返回bool类型的假 它会直接给括号里面的int类型赋值 代码: using System; using System.Timers; public class Program {static void Main(){int a;bool i;while (true){Get…...

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

红队-shell编程篇(上)
声明 通过学习 泷羽sec的个人空间-泷羽sec个人主页-哔哩哔哩视频,做出的文章如涉及侵权马上删除文章 笔记的只是方便各位师傅学习知识,以下网站只涉及学习内容,其他的都与本人无关,切莫逾越法律红线,否则后果自负 一、建立Shell文件 1. Shell简介 Shell是一种命令行界面&am…...
电子价签会是零售界的下一个主流?【新立电子】
电子价签,作为一种能够替代传统纸质标签的数字显示屏,已经在零售行业中展现出其巨大的潜力。它具有实时更新、集中管理、高效节能的特点,实现价格的实时更新,大大减少更新价格的工作量和时间。为消费者带来更加便捷、准确的购物体…...

5 分布式ID
这里讲一个比较常用的分布式防重复的ID生成策略,雪花算法 一个用户体量比较大的分布式系统必然伴随着分表分库,分机房部署,单体的部署方式肯定是承载不了这么大的体量。 雪花算法的结构说明 如下图所示: 雪花算法组成 从上图我们可以看…...
SpringBoot | @Autowired 和 @Resource 的区别及原理分析
关注:CodingTechWork 引言 在Spring框架中,Autowired 和 Resource 是两种常用的依赖注入注解,它们都用于自动装配Bean,简化了开发者手动创建和管理Bean的繁琐工作。然而,它们的实现机制和使用方式有所不同。理解这两者…...
『SQLite』解释执行(Explain)
摘要:本节主要讲解SQL的解释执行:Explain。 在 sqlite 语句之前,可以使用 “EXPLAIN” 关键字或 “EXPLAIN QUERY PLAN” 短语,用于描述表查询的细节。 基本语法 EXPLAIN 语法: EXPLAIN [SQLite Query]EXPLAIN QUER…...

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

(概率论)无偏估计
参考文章:(15 封私信 / 51 条消息) 什么是无偏估计? - 知乎 (zhihu.com) 首先,第一个回答中,马同学图解数学讲解得很形象, 我的概括是:“注意,有一个总体的均值u。然后,如果抽样n个&…...

Minio-Linux-安装
文章目录 1.Linux安装1.下载源码包2.上传到/usr/local/minio1.进入目录2.上传 3.开放执行权限4.创建minio文件存储目录及日志目录5.编写启动的shell脚本1.脚本编写2.赋予执行权限 6.启动!1.执行run脚本2.查看日志3.开放9001和9000端口1.服务器2.安全组3.访问&#x…...
利用Java爬取1688商品详情API接口:技术与应用指南
引言 1688作为中国领先的B2B电子商务平台,拥有海量的商品信息。对于商家和市场研究人员来说,能够从1688获取商品详情信息,对于市场分析、竞品研究等具有重要价值。本文将详细介绍如何使用Java编写爬虫程序,以合法、高效的方式获取…...
基于MATLAB的汽车热管理模型构建
一、引言 汽车热管理系统对汽车性能、部件寿命及驾乘体验至关重要。它能确保发动机、电池等关键部件在适宜温度工作。MATLAB 功能强大,为构建高精度热管理模型提供有效途径,助力优化系统设计与控制策略。 二、汽车热管理系统构成 2.1 发动机冷却系统&…...
LRU(1)
LRU是"Least Recently Used"(最近最少使用)的缩写,它是一种常用的页面置换算法和缓存淘汰策略。当计算机系统的内存或缓存资源有限时,LRU算法根据的历史访问记录来决定哪些数据应该被保留在内存或缓存中,哪些被淘汰。其核心思想是“…...

VSCode 使用鼠标滚轮控制字体
一、 文件 | 首选项 | 设置 二、单击在 settings.json中编辑 "editor.mouseWheelZoom": true 注注注意:保存哦!ctrlS 三、测试 按住ctrl鼠标滚轮,控制字体大小...

数据库(3)--针对列的CRUD操作
1.Create 新增 语法: insert into 表名 (列名)values (列)... 创建一个学生表用于演示: create table if not exists student( id bigint comment 编号, name varchar(20) comment 姓名 ); 1.1直接增加…...

【Linux】记录一下考RHCE的学习过程(七)
年底了,公司接的北京地铁轨道交通的项目做不完了,一百多列地铁的设备都得调,派我出差了几周,这几天才回来,出差累死了实在是没办法更新。(YOASOBI的二开票还没抢到ToT,哭死,看看回滚…...

【顶刊TPAMI 2025】多头编码(MHE)之极限分类 Part 1:背景动机
目录 1 简单概括2 几个重要发现3 主要贡献4 背景知识5 方法简介 论文:Multi-Head Encoding for Extreme Label Classification 作者:Daojun Liang, Haixia Zhang, Dongfeng Yuan and Minggao Zhang 单位:山东大学 代码:https://gi…...

使用hardhat进行合约测试
演示源码:hardhat-demo: 演示基于hardhat的HelloWord合约测试案例。 环境 NodeJs 创建工程 1.创建一个hardhat工程根目录(hardhat-demo),然后进入该目录执行。 npx hardhat执行该命令,会进行hardhat工程初始化。 提示我们是否安装该版本h…...