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

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 300

extern 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 1
    
    stat = spi_transfer(BOARD_APP_SPI_BASE,
                &control_config,
                NULL, NULL,
                (uint8_t *)read_buffer, 10, (uint8_t *)rbuff, ARRAY_SIZE(rbuff));
#else
    stat = 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从机

    • 测试🆗

结束


http://www.kler.cn/a/471661.html

相关文章:

  • 使用 PyTorch 自定义数据集并划分训练、验证与测试集
  • Mysql--基础篇--数据类型(整数,浮点数,日期,枚举,二进制,空间类型等)
  • Jupyter Markdown样式说明
  • HTML静态网页成品作业(HTML+CSS)——婚礼婚纱网页设计制作(6个页面)
  • OSPF使能配置
  • 攻防靶场(32):两个爆破技巧 Funbox 7 EasyEnum
  • 5. 多线程(3) --- synchronized
  • 力扣经典题目之2283. 判断一个数的数字计数是否等于数位的值
  • [网络安全]DVWA之File Upload—AntSword(蚁剑)攻击姿势及解题详析合集
  • windows蓝屏以及windows补丁回滚
  • Solaris操作系统
  • JavaScript系列(12)-- 高阶函数应用
  • Spring5框架之SpringMVC
  • 记录一下Coding一直不能clone
  • 7_TypeScript Number --[深入浅出 TypeScript 测试]
  • Ae:合成设置 - 3D 渲染器
  • 除了RAII和智能指针,还有哪些资源管理机制?
  • Java设计模式 —— 【行为型模式】命令模式(Command Pattern) 详解
  • doris 2.1 Data Queries Common Table Expression UDF 学习笔记
  • 【LeetCode】4. 去重的效率提升