前言
本片分享USB开发环境搭建,以CDC为例。
创建工程
打开e2studio
菜单栏点击
文件->新建->瑞萨C/C++项目->Renesas RA
选择C/C++ -> Renesas RA C/C++ Project下一步
指定工程名字,下一步
指定board,芯片,工具链,下一步
指定开发模式flat,下一步
指定生成可执行项目,选择freertos,下一步
指定led模板,完成
配置
双击xml配置文件
添加heap
按照如下选择stacks->点击Thread->New Stack->RTOS->FreeRTOS Heap4
此时提示有错误,使用heap需要将线程创建改为动态方式
如下配置,点击Thread->属性->设置相关参数
设置Total Heap Size
设置Support Dynamic Allocation使能
设置USB
配置引脚
配置FS引脚P814和P815
HD的VBUS PB01
Stacks-.Thread->New Stack->Connectivity->USB PCDC
添加USB CDC驱动
设置其属性
按照如下设置PCDC的属性 实例民鼻子g_pcdc,
Bulk in bulk out interrupt的pipe为1 2 6
配置USB时钟使用24MHz,这里很重要,默认的20M不能工作。
使能DMA,使用HS的地址。
设置以下属性实例名字 g_basic
使用IP1高速
设置描述符
设置cdc回调函数
DMA配置
添加2个传输
设置传输0的属性
设置传输1的属性
配置信号量等对象
创建信号量属性如下
再创建三个消息队列
属性分别如下
更新配置
先保存,再更新配置
添加描述符
添加文件r_usb_pcdc_descriptor.c到src目录下
r_usb_pcdc_descriptor.c文件内容如下
/*
* Copyright (c) 2020 - 2024 Renesas Electronics Corporation and/or its affiliates
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/******************************************************************************
Includes <System Includes> , "Project Includes"
******************************************************************************/
#include "r_usb_basic.h"
#include "r_usb_basic_api.h"
#include "r_usb_basic_cfg.h"
/******************************************************************************
Macro definitions
******************************************************************************/
/* bcdUSB */
#define USB_BCDNUM (0x0200U)
/* Release Number */
#define USB_RELEASE (0x0200U)
/* DCP max packet size */
#define USB_DCPMAXP (64U)
/* Configuration number */
#define USB_CONFIGNUM (1U)
/* Vendor ID */
#define USB_VENDORID (0x0000U)
/* Product ID */
#define USB_PRODUCTID (0x0002U)
/* Class-Specific Configuration Descriptors */
#define USB_PCDC_CS_INTERFACE (0x24U)
/* bDescriptor SubType in Communications Class Functional Descriptors */
/* Header Functional Descriptor */
#define USB_PCDC_DT_SUBTYPE_HEADER_FUNC (0x00U)
/* Call Management Functional Descriptor. */
#define USB_PCDC_DT_SUBTYPE_CALL_MANAGE_FUNC (0x01U)
/* Abstract Control Management Functional Descriptor. */
#define USB_PCDC_DT_SUBTYPE_ABSTRACT_CTR_MANAGE_FUNC (0x02U)
/* Union Functional Descriptor */
#define USB_PCDC_DT_SUBTYPE_UNION_FUNC (0x06U)
/* Communications Class Subclass Codes */
#define USB_PCDC_CLASS_SUBCLASS_CODE_ABS_CTR_MDL (0x02U)
/* USB Class Definitions for Communications Devices Specification
release number in binary-coded decimal. */
#define USB_PCDC_BCD_CDC (0x0110U)
/* Descriptor length */
#define USB_PCDC_QD_LEN (10U)
#define USB_PCDC_CD1_LEN (67U)
#define STRING_DESCRIPTOR0_LEN (4U)
#define STRING_DESCRIPTOR1_LEN (16U)
#define STRING_DESCRIPTOR2_LEN (44U)
#define STRING_DESCRIPTOR3_LEN (46U)
#define STRING_DESCRIPTOR4_LEN (22U)
#define STRING_DESCRIPTOR5_LEN (18U)
#define STRING_DESCRIPTOR6_LEN (28U)
#define NUM_STRING_DESCRIPTOR (7U)
/* Descriptor data Mask */
#define USB_UCHAR_MAX (0xffU)
#define USB_W_TOTAL_LENGTH_MASK (256U)
#define USB_W_MAX_PACKET_SIZE_MASK (64U)
#define USB_PCDC_BCD_CDC_MASK (256U)
/******************************************************************************
Private global variables and functions
******************************************************************************/
/******************************************************************************
Exported global variables
******************************************************************************/
/******************************************************************************
Exported global functions (to be accessed by other files)
******************************************************************************/
/* Standard Device Descriptor */
uint8_t g_apl_device[USB_DD_BLENGTH + ( USB_DD_BLENGTH % 2)] =
{
USB_DD_BLENGTH, /* 0:bLength */
USB_DT_DEVICE, /* 1:bDescriptorType */
(USB_BCDNUM & (uint8_t) USB_UCHAR_MAX), /* 2:bcdUSB_lo */
((uint8_t) (USB_BCDNUM >> 8) & (uint8_t) USB_UCHAR_MAX), /* 3:bcdUSB_hi */
USB_IFCLS_CDCC, /* 4:bDeviceClass */
0, /* 5:bDeviceSubClass */
0, /* 6:bDeviceProtocol */
(uint8_t) USB_DCPMAXP, /* 7:bMAXPacketSize(for DCP) */
(USB_VENDORID & (uint8_t) USB_UCHAR_MAX), /* 8:idVendor_lo */
((uint8_t) (USB_VENDORID >> 8) & (uint8_t) USB_UCHAR_MAX), /* 9:idVendor_hi */
((uint16_t) USB_PRODUCTID & (uint8_t) USB_UCHAR_MAX), /* 10:idProduct_lo */
((uint8_t) (USB_PRODUCTID >> 8) & (uint8_t) USB_UCHAR_MAX), /* 11:idProduct_hi */
(USB_RELEASE & (uint8_t) USB_UCHAR_MAX), /* 12:bcdDevice_lo */
((uint8_t) (USB_RELEASE >> 8) & (uint8_t) USB_UCHAR_MAX), /* 13:bcdDevice_hi */
1, /* 14:iManufacturer */
2, /* 15:iProduct */
6, /* 16:iSerialNumber */
USB_CONFIGNUM /* 17:bNumConfigurations */
};
/************************************************************
* Device Qualifier Descriptor *
************************************************************/
uint8_t g_apl_qualifier_descriptor[USB_PCDC_QD_LEN + ( USB_PCDC_QD_LEN % 2)] =
{
USB_PCDC_QD_LEN, /* 0:bLength */
USB_DT_DEVICE_QUALIFIER, /* 1:bDescriptorType */
(USB_BCDNUM & (uint8_t) USB_UCHAR_MAX), /* 2:bcdUSB_lo */
((uint8_t) (USB_BCDNUM >> 8) & (uint8_t) USB_UCHAR_MAX), /* 3:bcdUSB_hi */
0, /* 4:bDeviceClass */
0, /* 5:bDeviceSubClass */
0, /* 6:bDeviceProtocol */
(uint8_t) USB_DCPMAXP, /* 7:bMAXPacketSize(for DCP) */
USB_CONFIGNUM, /* 8:bNumConfigurations */
0 /* 9:bReserved */
};
/************************************************************
* Configuration Or Other_Speed_Configuration Descriptor *
************************************************************/
/* For Full-Speed */
uint8_t g_apl_configuration[USB_PCDC_CD1_LEN + ( USB_PCDC_CD1_LEN % 2)] =
{
USB_CD_BLENGTH, /* 0:bLength */
USB_SOFT_CHANGE, /* 1:bDescriptorType */
USB_PCDC_CD1_LEN % USB_W_TOTAL_LENGTH_MASK, /* 2:wTotalLength(L) */
USB_PCDC_CD1_LEN / USB_W_TOTAL_LENGTH_MASK, /* 3:wTotalLength(H) */
2, /* 4:bNumInterfaces */
1, /* 5:bConfigurationValue */
0, /* 6:iConfiguration */
USB_CF_RESERVED | USB_CF_SELFP, /* 7:bmAttributes */
(10 / 2), /* 8:MAXPower (2mA unit) */
/* Interface Descriptor */
USB_ID_BLENGTH, /* 0:bLength */
USB_DT_INTERFACE, /* 1:bDescriptor */
0, /* 2:bInterfaceNumber */
0, /* 3:bAlternateSetting */
1, /* 4:bNumEndpoints */
USB_IFCLS_CDCC, /* 5:bInterfaceClass */
USB_PCDC_CLASS_SUBCLASS_CODE_ABS_CTR_MDL, /* 6:bInterfaceSubClass */
1, /* 7:bInterfaceProtocol */
0, /* 8:iInterface */
/* Communications Class Functional Descriptorss */
5, /* 0:bLength */
USB_PCDC_CS_INTERFACE, /* 1:bDescriptorType */
USB_PCDC_DT_SUBTYPE_HEADER_FUNC, /* 2:bDescriptorSubtype */
USB_PCDC_BCD_CDC % USB_W_TOTAL_LENGTH_MASK, /* 3:bcdCDC_lo */
USB_PCDC_BCD_CDC / USB_W_TOTAL_LENGTH_MASK, /* 4:bcdCDC_hi */
/* Communications Class Functional Descriptorss */
4, /* 0:bLength */
USB_PCDC_CS_INTERFACE, /* 1:bDescriptorType */
USB_PCDC_DT_SUBTYPE_ABSTRACT_CTR_MANAGE_FUNC, /* 2:bDescriptorSubtype */
2, /* 3:bmCapabilities */
/* Communications Class Functional Descriptorss */
5, /* 0:bLength */
USB_PCDC_CS_INTERFACE, /* 1:bDescriptorType */
USB_PCDC_DT_SUBTYPE_UNION_FUNC, /* 2:bDescriptorSubtype */
0, /* 3:bMasterInterface */
1, /* 4:bSlaveInterface0 */
/* Communications Class Functional Descriptorss */
5, /* 0:bLength */
USB_PCDC_CS_INTERFACE, /* 1:bDescriptorType */
USB_PCDC_DT_SUBTYPE_CALL_MANAGE_FUNC, /* 2:bDescriptorSubtype */
/* D1:1-Device can send/receive call management
information over a Data Class interface. */
/* D0:1-Device handles call management itself. */
3, /* 3:bmCapabilities */
1, /* 4:bDataInterface */
/* Endpoint Descriptor 0 */
7, /* 0:bLength */
USB_DT_ENDPOINT, /* 1:bDescriptorType */
USB_EP_IN | USB_EP3, /* 2:bEndpointAddress */
USB_EP_INT, /* 3:bmAttribute */
16, /* 4:wMAXPacketSize_lo */
0, /* 5:wMAXPacketSize_hi */
0x10, /* 6:bInterval */
/* Interface Descriptor */
USB_ID_BLENGTH, /* 0:bLength */
USB_DT_INTERFACE, /* 1:bDescriptor */
1, /* 2:bInterfaceNumber */
0, /* 3:bAlternateSetting */
2, /* 4:bNumEndpoints */
USB_IFCLS_CDCD, /* 5:bInterfaceClass */
0, /* 6:bInterfaceSubClass */
0, /* 7:bInterfaceProtocol */
0, /* 8:iInterface */
/* Endpoint Descriptor 0 */
USB_ED_BLENGTH, /* 0:bLength */
USB_DT_ENDPOINT, /* 1:bDescriptorType */
USB_EP_IN | USB_EP1, /* 2:bEndpointAddress */
USB_EP_BULK, /* 3:bmAttribute */
USB_W_MAX_PACKET_SIZE_MASK, /* 4:wMAXPacketSize_lo */
0, /* 5:wMAXPacketSize_hi */
0, /* 6:bInterval */
/* Endpoint Descriptor 1 */
USB_ED_BLENGTH, /* 0:bLength */
USB_DT_ENDPOINT, /* 1:bDescriptorType */
USB_EP_OUT | USB_EP2, /* 2:bEndpointAddress */
USB_EP_BULK, /* 3:bmAttribute */
USB_W_MAX_PACKET_SIZE_MASK, /* 4:wMAXPacketSize_lo */
0, /* 5:wMAXPacketSize_hi */
0, /* 6:bInterval */
};
/* For High-Speed */
uint8_t g_apl_hs_configuration[USB_PCDC_CD1_LEN + ( USB_PCDC_CD1_LEN % 2)] =
{
9, /* 0:bLength */
USB_SOFT_CHANGE, /* 1:bDescriptorType */
USB_PCDC_CD1_LEN % USB_W_TOTAL_LENGTH_MASK, /* 2:wTotalLength(L) */
USB_PCDC_CD1_LEN / USB_W_TOTAL_LENGTH_MASK, /* 3:wTotalLength(H) */
2, /* 4:bNumInterfaces */
1, /* 5:bConfigurationValue */
0, /* 6:iConfiguration */
USB_CF_RESERVED | USB_CF_SELFP, /* 7:bmAttributes */
(10 / 2), /* 8:MAXPower (2mA unit) */
/* Interface Descriptor */
9, /* 0:bLength */
USB_DT_INTERFACE, /* 1:bDescriptor */
0, /* 2:bInterfaceNumber */
0, /* 3:bAlternateSetting */
1, /* 4:bNumEndpoints */
USB_IFCLS_CDCC, /* 5:bInterfaceClass */
USB_PCDC_CLASS_SUBCLASS_CODE_ABS_CTR_MDL, /* 6:bInterfaceSubClass */
1, /* 7:bInterfaceProtocol */
0, /* 8:iInterface */
/* Communications Class Functional Descriptorss */
5, /* 0:bLength */
USB_PCDC_CS_INTERFACE, /* 1:bDescriptorType */
USB_PCDC_DT_SUBTYPE_HEADER_FUNC, /* 2:bDescriptorSubtype */
USB_PCDC_BCD_CDC % USB_PCDC_BCD_CDC_MASK, /* 3:bcdCDC_lo */
USB_PCDC_BCD_CDC / USB_PCDC_BCD_CDC_MASK, /* 4:bcdCDC_hi */
/* Communications Class Functional Descriptorss */
4, /* 0:bLength */
USB_PCDC_CS_INTERFACE, /* 1:bDescriptorType */
USB_PCDC_DT_SUBTYPE_ABSTRACT_CTR_MANAGE_FUNC, /* 2:bDescriptorSubtype */
2, /* 3:bmCapabilities */
/* Communications Class Functional Descriptorss */
5, /* 0:bLength */
USB_PCDC_CS_INTERFACE, /* 1:bDescriptorType */
USB_PCDC_DT_SUBTYPE_UNION_FUNC, /* 2:bDescriptorSubtype */
0, /* 3:bMasterInterface */
1, /* 4:bSlaveInterface0 */
/* Communications Class Functional Descriptorss */
5, /* 0:bLength */
USB_PCDC_CS_INTERFACE, /* 1:bDescriptorType */
USB_PCDC_DT_SUBTYPE_CALL_MANAGE_FUNC, /* 2:bDescriptorSubtype */
/* D1:1-Device can send/receive call management
information over a Data Class interface. */
/* D0:1-Device handles call management itself. */
3, /* 3:bmCapabilities */
1, /* 4:bDataInterface */
/* Endpoint Descriptor 0 */
7, /* 0:bLength */
USB_DT_ENDPOINT, /* 1:bDescriptorType */
USB_EP_IN | USB_EP3, /* 2:bEndpointAddress */
USB_EP_INT, /* 3:bmAttribute */
16, /* 4:wMAXPacketSize_lo */
0, /* 5:wMAXPacketSize_hi */
0x10, /* 6:bInterval */
/* Interface Descriptor */
9, /* 0:bLength */
USB_DT_INTERFACE, /* 1:bDescriptor */
1, /* 2:bInterfaceNumber */
0, /* 3:bAlternateSetting */
2, /* 4:bNumEndpoints */
USB_IFCLS_CDCD, /* 5:bInterfaceClass */
0, /* 6:bInterfaceSubClass */
0, /* 7:bInterfaceProtocol */
0, /* 8:iInterface */
/* Endpoint Descriptor 0 */
7, /* 0:bLength */
USB_DT_ENDPOINT, /* 1:bDescriptorType */
USB_EP_IN | USB_EP1, /* 2:bEndpointAddress */
USB_EP_BULK, /* 3:bmAttribute */
0, /* 4:wMAXPacketSize_lo */
2, /* 5:wMAXPacketSize_hi */
0, /* 6:bInterval */
/* Endpoint Descriptor 1 */
7, /* 0:bLength */
USB_DT_ENDPOINT, /* 1:bDescriptorType */
USB_EP_OUT | USB_EP2, /* 2:bEndpointAddress */
USB_EP_BULK, /* 3:bmAttribute */
0, /* 4:wMAXPacketSize_lo */
2, /* 5:wMAXPacketSize_hi */
0, /* 6:bInterval */
};
/*************************************
* String Descriptor *
*************************************/
/* UNICODE 0x0409 English (United States) */
uint8_t g_cdc_string_descriptor0[STRING_DESCRIPTOR0_LEN + ( STRING_DESCRIPTOR0_LEN % 2)] =
{
STRING_DESCRIPTOR0_LEN, /* 0:bLength */
USB_DT_STRING, /* 1:bDescriptorType */
0x09, 0x04 /* 2:wLANGID[0] */
};
/* iManufacturer */
uint8_t g_cdc_string_descriptor1[STRING_DESCRIPTOR1_LEN + ( STRING_DESCRIPTOR1_LEN % 2)] =
{
STRING_DESCRIPTOR1_LEN, /* 0:bLength */
USB_DT_STRING, /* 1:bDescriptorType */
'R', 0x00, /* 2:wLANGID[0] */
'E', 0x00,
'N', 0x00,
'E', 0x00,
'S', 0x00,
'A', 0x00,
'S', 0x00,
};
/* iProduct */
uint8_t g_cdc_string_descriptor2[STRING_DESCRIPTOR2_LEN + ( STRING_DESCRIPTOR2_LEN % 2)] =
{
STRING_DESCRIPTOR2_LEN, /* 0:bLength */
USB_DT_STRING, /* 1:bDescriptorType */
'C', 0x00,
'D', 0x00,
'C', 0x00,
' ', 0x00,
'U', 0x00,
'S', 0x00,
'B', 0x00,
' ', 0x00,
'D', 0x00,
'e', 0x00,
'm', 0x00,
'o', 0x00,
'n', 0x00,
's', 0x00,
't', 0x00,
'r', 0x00,
'a', 0x00,
't', 0x00,
'i', 0x00,
'o', 0x00,
'n', 0x00,
};
/* iInterface */
uint8_t g_cdc_string_descriptor3[STRING_DESCRIPTOR3_LEN + ( STRING_DESCRIPTOR3_LEN % 2)] =
{
STRING_DESCRIPTOR3_LEN, /* 0:bLength */
USB_DT_STRING, /* 1:bDescriptorType */
'C', 0x00,
'o', 0x00,
'm', 0x00,
'm', 0x00,
'u', 0x00,
'n', 0x00,
'i', 0x00,
'c', 0x00,
'a', 0x00,
't', 0x00,
'i', 0x00,
'o', 0x00,
'n', 0x00,
's', 0x00,
' ', 0x00,
'D', 0x00,
'e', 0x00,
'v', 0x00,
'i', 0x00,
'c', 0x00,
'e', 0x00,
's', 0x00
};
/* iConfiguration */
uint8_t g_cdc_string_descriptor4[STRING_DESCRIPTOR4_LEN + ( STRING_DESCRIPTOR4_LEN % 2)] =
{
STRING_DESCRIPTOR4_LEN, /* 0:bLength */
USB_DT_STRING, /* 1:bDescriptorType */
'F', 0x00, /* 2:wLANGID[0] */
'u', 0x00,
'l', 0x00,
'l', 0x00,
'-', 0x00,
'S', 0x00,
'p', 0x00,
'e', 0x00,
'e', 0x00,
'd', 0x00
};
/* iConfiguration */
uint8_t g_cdc_string_descriptor5[STRING_DESCRIPTOR5_LEN + ( STRING_DESCRIPTOR5_LEN % 2)] =
{
STRING_DESCRIPTOR5_LEN, /* 0:bLength */
USB_DT_STRING, /* 1:bDescriptorType */
'H', 0x00, /* 2:wLANGID[0] */
'i', 0x00,
'-', 0x00,
'S', 0x00,
'p', 0x00,
'e', 0x00,
'e', 0x00,
'd', 0x00
};
/* iSerialNumber */
uint8_t g_cdc_string_descriptor6[STRING_DESCRIPTOR6_LEN + ( STRING_DESCRIPTOR6_LEN % 2)] =
{
STRING_DESCRIPTOR6_LEN, /* 0:bLength */
USB_DT_STRING, /* 1:bDescriptorType */
'0', 0x00, /* 2:wLANGID[0] */
'0', 0x00,
'0', 0x00,
'0', 0x00,
'0', 0x00,
'0', 0x00,
'0', 0x00,
'0', 0x00,
'0', 0x00,
'0', 0x00,
'0', 0x00,
'0', 0x00,
'1', 0x00,
};
uint8_t *gp_apl_string_table[] =
{
g_cdc_string_descriptor0,
g_cdc_string_descriptor1,
g_cdc_string_descriptor2,
g_cdc_string_descriptor3,
g_cdc_string_descriptor4,
g_cdc_string_descriptor5,
g_cdc_string_descriptor6
};
const usb_descriptor_t g_usb_descriptor =
{
g_apl_device, /* Pointer to the device descriptor */
g_apl_configuration, /* Pointer to the configuration descriptor for Full-speed */
g_apl_hs_configuration, /* Pointer to the configuration descriptor for Hi-speed */
g_apl_qualifier_descriptor, /* Pointer to the qualifier descriptor */
gp_apl_string_table, /* Pointer to the string descriptor table */
NUM_STRING_DESCRIPTOR
};
/******************************************************************************
Renesas Abstracted Peripheral Communications Devices Class Driver API functions
******************************************************************************/
/******************************************************************************
End Of File
******************************************************************************/
CDC操作
blinky_thread_entry.c中实现
usb_pcdc_callback
任务循环中
打开USB
< class="p" style="">/* Open USB instance */
< class="p" style="">{
< class="p" style="">err = R_USB_Open (&g_basic_ctrl, &g_basic_cfg);
< class="p" style="">if (FSP_SUCCESS != err)
< class="p" style="">{
< class="p" style="">//APP_ERR_PRINT("\r\nR_USB_Open failed.\r\n");
< class="p" style="">//APP_ERR_TRAP(err);
< class="p" style="">}
< class="p" style="">//APP_PRINT("\r\nUSB Opened successfully.\n\r");
< class="p" style="">}
然后不断处理队列消息
< class="p" style="">/* Check if USB event is received */
< class="p" style="">err_queue = xQueueReceive(g_event_queue, (void * const)&q_instance, (portMAX_DELAY));
< class="p" style="">if(pdTRUE != err_queue)
< class="p" style="">{
< class="p" style="">//APP_ERR_PRINT("\r\nNo USB Event received. Please check USB connection \r\n");
< class="p" style="">}
完整的代码如下
blinky_thread_entry.c
/*
* Copyright (c) 2020 - 2024 Renesas Electronics Corporation and/or its affiliates
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "blinky_thread.h"
typedef struct
{
uint32_t peripheral;
union
{
uint32_t data_size;
}u;
}queue_evt_t;
typedef enum
{
PERIPHERAL_NONE = 0,
PERIPHERAL_USB,
PERIPHERAL_UART,
}peripheral_t;
#define RESET_VALUE (0x00)
#define DATA_LEN (512U) // Data Length
#define LINE_CODING_LENGTH (0x07U) // Line coding length
/* Variable to capture USB event. */
volatile bool g_tx_complete = true;
volatile usb_event_info_t g_usb_pcdc_event;
/* Flag to indicate USB resume/suspend status */
static bool b_usb_attach = false;
/* Variable to store UART settings */
volatile usb_pcdc_linecoding_t g_line_coding;
usb_pcdc_ctrllinestate_t g_control_line_state =
{
.bdtr = 0,
.brts = 0,
};
/* Error status flag */
static volatile bool g_err_flag = false;
/* Variable to store baud rate */
uint32_t g_baud_rate = RESET_VALUE ;
/* Buffer to store user data */
uint8_t g_user_data_buf[DATA_LEN] = {RESET_VALUE};
/* Variable to store size of data received from tera term */
volatile uint32_t g_terminal_data_size = RESET_VALUE ;
uint8_t g_usb_tx_buffer[512]="hello";
extern bsp_leds_t g_bsp_leds;
/*******************************************************************************************************************//**
* [url=home.php?mod=space&uid=159083]@brief[/url] Deinitialize initialized USB instance
* @param[in] None
* @retval None
**********************************************************************************************************************/
static void deinit_usb(void)
{
fsp_err_t err = FSP_SUCCESS;
/* Close module */
err = R_USB_Close (&g_basic_ctrl);
if (FSP_SUCCESS != err)
{
//APP_ERR_PRINT ("\r\n** USB close API failed ** \r\n");
}
}
/* Blinky Thread entry function */
void blinky_thread_entry (void * pvParameters)
{
FSP_PARAMETER_NOT_USED(pvParameters);
fsp_err_t err = FSP_SUCCESS;
BaseType_t err_queue = pdFALSE;
queue_evt_t q_instance;
/* LED type structure */
bsp_leds_t leds = g_bsp_leds;
/* If this board has no LEDs then trap here */
if (0 == leds.led_count)
{
while (1)
{
; // There are no LEDs on this board
}
}
/* Holds level to set for pins */
//bsp_io_level_t pin_level = BSP_IO_LEVEL_LOW;
/* Open USB instance */
{
err = R_USB_Open (&g_basic_ctrl, &g_basic_cfg);
if (FSP_SUCCESS != err)
{
//APP_ERR_PRINT("\r\nR_USB_Open failed.\r\n");
//APP_ERR_TRAP(err);
}
//APP_PRINT("\r\nUSB Opened successfully.\n\r");
}
xSemaphoreGive(g_usb_tx_semaphore);
while (1)
{
/* Check if USB event is received */
err_queue = xQueueReceive(g_event_queue, (void * const)&q_instance, (portMAX_DELAY));
if(pdTRUE != err_queue)
{
//APP_ERR_PRINT("\r\nNo USB Event received. Please check USB connection \r\n");
}
/* Check for usb event */
if (PERIPHERAL_USB == q_instance.peripheral)
{
/* Send received data out to the UART */
if ((true == b_usb_attach))
{
if(0U < q_instance.u.data_size)
{
/* Wait for previous USB transfer to complete */
BaseType_t err_semaphore = xSemaphoreTake (g_usb_tx_semaphore, portMAX_DELAY);
if (pdTRUE == err_semaphore)
{
/* Write data to host machine */
err = R_USB_Write (&g_basic_ctrl, &g_usb_tx_buffer[0], sizeof(g_usb_tx_buffer), USB_CLASS_PCDC);
if (FSP_SUCCESS != err)
{
//APP_ERR_PRINT("\r\nR_USB_Write API failed.\r\n");
deinit_usb();
//deinit_uart();
//APP_ERR_TRAP(err);
}
}
#if 0
/* Wait till previously queued data is out completely */
{
BaseType_t err_semaphore = xSemaphoreTake( g_uart_tx_mutex, portMAX_DELAY );
if(pdTRUE != err_semaphore)
{
APP_ERR_PRINT("\r\nxSemaphoreTake on g_uart_tx_mutex Failed \r\n");
APP_ERR_TRAP(err_semaphore);
}
}
/* Write data to UART Tx pin */
#if (BSP_FEATURE_SCI_VERSION == 2U)
err = R_SCI_B_UART_Write(&g_uart_ctrl, g_user_data_buf, q_instance.u.data_size);
#else
err = R_SCI_UART_Write(&g_uart_ctrl, g_user_data_buf, q_instance.u.data_size);
#endif
if(FSP_SUCCESS != err)
{
APP_ERR_PRINT ("\r\n** R_SCI_UART_Write API failed **\r\n");
deinit_usb();
deinit_uart();
APP_ERR_TRAP(err);
}
#endif
}
else
{
/* Buffer is physically transmitted since UART_EVENT_TX_COMPLETE was generated. */
/* Continue to read data from USB. */
/* The amount of data received will be known when USB_STATUS_READ_COMPLETE event occurs*/
err = R_USB_Read(&g_basic_ctrl, g_user_data_buf, DATA_LEN, USB_CLASS_PCDC);
if (FSP_SUCCESS != err)
{
//APP_ERR_PRINT("\r\nR_USB_Read API failed.\r\n");
deinit_usb();
//deinit_uart();
//APP_ERR_TRAP(err);
}
}
}
continue;
}
if(PERIPHERAL_NONE == q_instance.peripheral)
{
;
}
#if 0
/* Enable access to the PFS registers. If using r_ioport module then register protection is automatically
* handled. This code uses BSP IO functions to show how it is used.
*/
R_BSP_PinAccessEnable();
/* Update all board LEDs */
for (uint32_t i = 0; i < leds.led_count; i++)
{
/* Get pin to toggle */
uint32_t pin = leds.p_leds[i];
/* Write to this pin */
R_BSP_PinWrite((bsp_io_port_pin_t) pin, pin_level);
}
/* Protect PFS registers */
R_BSP_PinAccessDisable();
/* Toggle level for next write */
if (BSP_IO_LEVEL_LOW == pin_level)
{
pin_level = BSP_IO_LEVEL_HIGH;
}
else
{
pin_level = BSP_IO_LEVEL_LOW;
}
#endif
//vTaskDelay(configTICK_RATE_HZ);
}
}
/*******************************************************************************************************************//**
* @brief USB PCDC with freertos callback
* @param[IN] usb_event_info_t usb event
* @param[IN] usb_hdl_t task
* @param[IN] usb_onoff_t state
* @retval None
**********************************************************************************************************************/
void usb_pcdc_callback(usb_event_info_t * p_pcdc_event , usb_hdl_t task, usb_onoff_t state)
{
FSP_PARAMETER_NOT_USED (task);
FSP_PARAMETER_NOT_USED (state);
queue_evt_t instance;
fsp_err_t err;
switch (p_pcdc_event->event)
{
/* USB Read complete Class Request */
case USB_STATUS_READ_COMPLETE:
{
//APP_PRINT("\nUSB STATUS : USB_STATUS_READ_COMPLETE \n");
instance.peripheral = PERIPHERAL_USB;
instance.u.data_size = p_pcdc_event->data_size;
/* Send the event from queue */
if (pdTRUE != (xQueueSend(g_event_queue, (const void *)&instance, (TickType_t)(RESET_VALUE))))
{
g_err_flag = true;
//APP_ERR_PRINT("\r\n xQueueSend on g_event_queue Failed \r\n");
//APP_ERR_TRAP(pdTRUE);
}
}
break;
/* Write Complete Class Request */
case USB_STATUS_WRITE_COMPLETE:
{
//APP_PRINT("\nUSB STATUS : USB_STATUS_WRITE_COMPLETE \n");
BaseType_t err_semaphore = xSemaphoreGive(g_usb_tx_semaphore);
if(pdTRUE != err_semaphore)
{
//APP_ERR_PRINT("\r\n xSemaphoreGive on g_usb_tx_semaphore Failed \r\n");
//APP_ERR_TRAP(err_semaphore);
}
err = R_USB_Read (&g_basic_ctrl, g_user_data_buf, DATA_LEN, USB_CLASS_PCDC);
if (FSP_SUCCESS != err)
{
//APP_ERR_PRINT("\r\nR_USB_Read API failed.\r\n");
deinit_usb();
//APP_ERR_TRAP(err);
}
return;
}
break;
/* Configured state class request */
case USB_STATUS_CONFIGURED:
{
b_usb_attach = true;
//APP_PRINT("\r\nUSB Status Configured Successful\r\n");
/* Read data from tera term */
err = R_USB_Read (&g_basic_ctrl, g_user_data_buf, DATA_LEN, USB_CLASS_PCDC);
if (FSP_SUCCESS != err)
{
//APP_ERR_PRINT("\r\nR_USB_Read API failed.\r\n");
deinit_usb();
//APP_ERR_TRAP(err);
}
return;
}
break;
/* Receive Class Request */
case USB_STATUS_REQUEST:
{
/* Check for the specific CDC class request IDs */
if (USB_PCDC_SET_LINE_CODING == (p_pcdc_event->setup.request_type & USB_BREQUEST))
{
//APP_PRINT("\nUSB STATUS : USB_STATUS_REQUEST \nRequest_Type: USB_PCDC_SET_LINE_CODING \n");
/* Get the class request.*/
err = R_USB_PeriControlDataGet (&g_basic_ctrl, (uint8_t*) &g_line_coding, LINE_CODING_LENGTH);
if(FSP_SUCCESS == err)
{
#if 0
/* Line Coding information read from the control pipe */
APP_PRINT ("\n*********SET***********\nbitrate = %d\nChar_Format = %d\nParity_Type = %d\ndata_Bit = %d\n***********************\n",\
g_line_coding.dw_dte_rate,
g_line_coding.b_char_format,
g_line_coding.b_parity_type,
g_line_coding.b_data_bits);
g_sci_extend_cfg.p_baud_setting = &g_baud_setting;
g_uart_test_cfg.p_extend = &g_sci_extend_cfg;
/* Calculate the baud rate*/
g_baud_rate = g_line_coding.dw_dte_rate;
if(INVALID_SIZE < g_baud_rate)
{
/* Calculate baud rate setting registers */
#if (BSP_FEATURE_SCI_VERSION == 2U)
err = R_SCI_B_UART_BaudCalculate(g_baud_rate, g_enable_bitrate_modulation, g_error_rate_x_1000, &g_baud_setting);
#else
err = R_SCI_UART_BaudCalculate(g_baud_rate, g_enable_bitrate_modulation, g_error_rate_x_1000, &g_baud_setting);
#endif
if(FSP_SUCCESS != err)
{
APP_ERR_PRINT ("\r\n** R_SCI_UART_BaudCalculate API failed **\r\n");
deinit_usb();
deinit_uart();
APP_ERR_TRAP(err);
}
}
/* Set number of parity bits */
set_uart_line_coding_cfg (&g_uart_test_cfg, &g_line_coding);
/* Close module */
#if (BSP_FEATURE_SCI_VERSION == 2U)
err = R_SCI_B_UART_Close (&g_uart_ctrl);
#else
err = R_SCI_UART_Close (&g_uart_ctrl);
#endif
if (FSP_SUCCESS != err)
{
APP_ERR_PRINT ("\r\n** R_SCI_UART_Close API failed ** \r\n");
}
/* Open UART with changed UART settings */
#if (BSP_FEATURE_SCI_VERSION == 2U)
err = R_SCI_B_UART_Open(&g_uart_ctrl, &g_uart_test_cfg);
#else
err = R_SCI_UART_Open(&g_uart_ctrl, &g_uart_test_cfg);
#endif
if(FSP_SUCCESS != err)
{
APP_ERR_PRINT ("\r\n** R_SCI_UART_Open API failed **\r\n");
deinit_usb();
APP_ERR_TRAP(err);
}
#endif
}
}
else if (USB_PCDC_GET_LINE_CODING == (p_pcdc_event->setup.request_type & USB_BREQUEST))
{
//APP_PRINT("\nUSB STATUS : USB_STATUS_REQUEST \nRequest_Type: USB_PCDC_GET_LINE_CODING \n");
/* Set the class request.*/
err = R_USB_PeriControlDataSet (&g_basic_ctrl, (uint8_t*) &g_line_coding, LINE_CODING_LENGTH);
if (FSP_SUCCESS == err)
{
//APP_PRINT ("\n*********GET***********\nbitrate = %d\nChar_Format = %d\nParity_Type = %d\ndata_Bit = %d\n***********************\n",
// g_line_coding.dw_dte_rate,
// g_line_coding.b_char_format,
// g_line_coding.b_parity_type,
// g_line_coding.b_data_bits);
}
else
{
//APP_ERR_PRINT("\r\nR_USB_PeriControlDataSet failed.\r\n");
deinit_usb();
//deinit_uart();
//APP_ERR_TRAP(err);
}
}
else if (USB_PCDC_SET_CONTROL_LINE_STATE == (p_pcdc_event->setup.request_type & USB_BREQUEST))
{
//APP_PRINT("\nUSB STATUS : USB_STATUS_REQUEST \nRequest_Type: USB_PCDC_SET_CONTROL_LINE_STATE \n");
/* Get the status of the control signals */
err = R_USB_PeriControlDataGet(&g_basic_ctrl,
(uint8_t*) &g_control_line_state,
sizeof(usb_pcdc_ctrllinestate_t));
if (FSP_SUCCESS == err)
{
if (FSP_SUCCESS == err)
{
#if 0
g_control_line_state.bdtr = (unsigned char)((p_pcdc_event->setup.request_value >> 0) & 0x01);
g_control_line_state.brts = (unsigned char)((p_pcdc_event->setup.request_value >> 1) & 0x01);
/* Toggle the line state if the flow control pin is set to a value (other than SCI_UART_INVALID_16BIT_PARAM) */
if (SCI_UART_INVALID_16BIT_PARAM != g_uart_ctrl.flow_pin)
{
R_BSP_PinAccessEnable();
R_BSP_PinWrite(g_uart_ctrl.flow_pin,
(g_control_line_state.brts == 0) ? BSP_IO_LEVEL_LOW : BSP_IO_LEVEL_HIGH);
R_BSP_PinAccessDisable();
}
APP_PRINT("\n******Line State*******\nbdtr = %d\nbrts = %d\n***********************\n",
g_control_line_state.bdtr,
g_control_line_state.brts);
#endif
}
}
/* Set the usb status as ACK response.*/
err = R_USB_PeriControlStatusSet (&g_basic_ctrl, USB_SETUP_STATUS_ACK);
if (FSP_SUCCESS != err)
{
//APP_ERR_PRINT("\r\nR_USB_PeriControlStatusSet failed.\r\n");
deinit_usb();
//deinit_uart();
//APP_ERR_TRAP(err);
}
}
else
{
;
}
return;
}
break;
/* Complete Class Request */
case USB_STATUS_REQUEST_COMPLETE:
{
if(USB_PCDC_SET_LINE_CODING == (p_pcdc_event->setup.request_type & USB_BREQUEST))
{
//APP_PRINT("\nUSB STATUS : USB_STATUS_REQUEST_COMPLETE \nRequest_Type: USB_PCDC_SET_LINE_CODING \n");
}
else if (USB_PCDC_GET_LINE_CODING == (p_pcdc_event->setup.request_type & USB_BREQUEST))
{
//APP_PRINT("\nUSB STATUS : USB_STATUS_REQUEST_COMPLETE \nRequest_Type: USB_PCDC_GET_LINE_CODING \n");
}
else
{
;
}
return;
}
break;
/* Detach, Suspend State Class requests */
case USB_STATUS_DETACH:
/* Stop all read/write transactions using R_USB_Stop */
case USB_STATUS_SUSPEND:
{
//APP_PRINT("\nUSB STATUS : USB_STATUS_DETACH or USB_STATUS_SUSPEND\r\n");
/* Reset the usb attached flag indicating usb is removed.*/
b_usb_attach = false;
memset (g_user_data_buf, RESET_VALUE, sizeof(g_user_data_buf));
return;
}
/* Resume state */
case USB_STATUS_RESUME:
{
//APP_PRINT("\nUSB STATUS : USB_STATUS_RESUME\r\n");
/* set the usb attached flag*/
b_usb_attach = true;
}
break;
default:
return;
break;
}
}
编译运行
右键点击工程名->构建项目
点击甲壳虫图标
点击运行
可以看到枚举出来的串口
上位机发送一个字节,开发板返回hello
总结
使用配置工具可以比较方便的配置相关的驱动,能够比较快速的搭建USB开发环境。
注意USB PLL频率要配置为24MHz。