bluepill: add usbcdc example
This commit is contained in:
		
							parent
							
								
									3d193b0275
								
							
						
					
					
						commit
						5b7110fd24
					
				| 
						 | 
					@ -0,0 +1,39 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This directory is intended for project header files.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					A header file is a file containing C declarations and macro definitions
 | 
				
			||||||
 | 
					to be shared between several project source files. You request the use of a
 | 
				
			||||||
 | 
					header file in your project source file (C, C++, etc) located in `src` folder
 | 
				
			||||||
 | 
					by including it, with the C preprocessing directive `#include'.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```src/main.c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "header.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main (void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					 ...
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Including a header file produces the same results as copying the header file
 | 
				
			||||||
 | 
					into each source file that needs it. Such copying would be time-consuming
 | 
				
			||||||
 | 
					and error-prone. With a header file, the related declarations appear
 | 
				
			||||||
 | 
					in only one place. If they need to be changed, they can be changed in one
 | 
				
			||||||
 | 
					place, and programs that include the header file will automatically use the
 | 
				
			||||||
 | 
					new version when next recompiled. The header file eliminates the labor of
 | 
				
			||||||
 | 
					finding and changing all the copies as well as the risk that a failure to
 | 
				
			||||||
 | 
					find one copy will result in inconsistencies within a program.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					In C, the usual convention is to give header files names that end with `.h'.
 | 
				
			||||||
 | 
					It is most portable to use only letters, digits, dashes, and underscores in
 | 
				
			||||||
 | 
					header file names, and at most one dot.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Read more about using header files in official GCC documentation:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* Include Syntax
 | 
				
			||||||
 | 
					* Include Operation
 | 
				
			||||||
 | 
					* Once-Only Headers
 | 
				
			||||||
 | 
					* Computed Includes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,46 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This directory is intended for project specific (private) libraries.
 | 
				
			||||||
 | 
					PlatformIO will compile them to static libraries and link into executable file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The source code of each library should be placed in a an own separate directory
 | 
				
			||||||
 | 
					("lib/your_library_name/[here are source files]").
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For example, see a structure of the following two libraries `Foo` and `Bar`:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					|--lib
 | 
				
			||||||
 | 
					|  |
 | 
				
			||||||
 | 
					|  |--Bar
 | 
				
			||||||
 | 
					|  |  |--docs
 | 
				
			||||||
 | 
					|  |  |--examples
 | 
				
			||||||
 | 
					|  |  |--src
 | 
				
			||||||
 | 
					|  |     |- Bar.c
 | 
				
			||||||
 | 
					|  |     |- Bar.h
 | 
				
			||||||
 | 
					|  |  |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
 | 
				
			||||||
 | 
					|  |
 | 
				
			||||||
 | 
					|  |--Foo
 | 
				
			||||||
 | 
					|  |  |- Foo.c
 | 
				
			||||||
 | 
					|  |  |- Foo.h
 | 
				
			||||||
 | 
					|  |
 | 
				
			||||||
 | 
					|  |- README --> THIS FILE
 | 
				
			||||||
 | 
					|
 | 
				
			||||||
 | 
					|- platformio.ini
 | 
				
			||||||
 | 
					|--src
 | 
				
			||||||
 | 
					   |- main.c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					and a contents of `src/main.c`:
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					#include <Foo.h>
 | 
				
			||||||
 | 
					#include <Bar.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main (void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  ...
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PlatformIO Library Dependency Finder will find automatically dependent
 | 
				
			||||||
 | 
					libraries scanning project source files.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					More information about PlatformIO Library Dependency Finder
 | 
				
			||||||
 | 
					- https://docs.platformio.org/page/librarymanager/ldf.html
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,14 @@
 | 
				
			||||||
 | 
					; PlatformIO Project Configuration File
 | 
				
			||||||
 | 
					;
 | 
				
			||||||
 | 
					;   Build options: build flags, source filter
 | 
				
			||||||
 | 
					;   Upload options: custom upload port, speed and extra flags
 | 
				
			||||||
 | 
					;   Library options: dependencies, extra library storages
 | 
				
			||||||
 | 
					;   Advanced options: extra scripting
 | 
				
			||||||
 | 
					;
 | 
				
			||||||
 | 
					; Please visit documentation for the other options and examples
 | 
				
			||||||
 | 
					; https://docs.platformio.org/page/projectconf.html
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[env:bluepill_f103c8]
 | 
				
			||||||
 | 
					platform = ststm32
 | 
				
			||||||
 | 
					board = bluepill_f103c8
 | 
				
			||||||
 | 
					framework = libopencm3
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,277 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * This file is part of the libopencm3 project.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Copyright (C) 2010 Gareth McMullin <gareth@blacksphere.co.nz>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This library is free software: you can redistribute it and/or modify
 | 
				
			||||||
 | 
					 * it under the terms of the GNU Lesser General Public License as published by
 | 
				
			||||||
 | 
					 * the Free Software Foundation, either version 3 of the License, or
 | 
				
			||||||
 | 
					 * (at your option) any later version.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This library is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 * GNU Lesser General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU Lesser General Public License
 | 
				
			||||||
 | 
					 * along with this library.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <libopencm3/stm32/rcc.h>
 | 
				
			||||||
 | 
					#include <libopencm3/stm32/gpio.h>
 | 
				
			||||||
 | 
					#include <libopencm3/usb/usbd.h>
 | 
				
			||||||
 | 
					#include <libopencm3/usb/cdc.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct usb_device_descriptor dev = {
 | 
				
			||||||
 | 
						.bLength = USB_DT_DEVICE_SIZE,
 | 
				
			||||||
 | 
						.bDescriptorType = USB_DT_DEVICE,
 | 
				
			||||||
 | 
						.bcdUSB = 0x0200,
 | 
				
			||||||
 | 
						.bDeviceClass = USB_CLASS_CDC,
 | 
				
			||||||
 | 
						.bDeviceSubClass = 0,
 | 
				
			||||||
 | 
						.bDeviceProtocol = 0,
 | 
				
			||||||
 | 
						.bMaxPacketSize0 = 64,
 | 
				
			||||||
 | 
						.idVendor = 0x0483,
 | 
				
			||||||
 | 
						.idProduct = 0x5740,
 | 
				
			||||||
 | 
						.bcdDevice = 0x0200,
 | 
				
			||||||
 | 
						.iManufacturer = 1,
 | 
				
			||||||
 | 
						.iProduct = 2,
 | 
				
			||||||
 | 
						.iSerialNumber = 3,
 | 
				
			||||||
 | 
						.bNumConfigurations = 1,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * This notification endpoint isn't implemented. According to CDC spec its
 | 
				
			||||||
 | 
					 * optional, but its absence causes a NULL pointer dereference in Linux
 | 
				
			||||||
 | 
					 * cdc_acm driver.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static const struct usb_endpoint_descriptor comm_endp[] = {{
 | 
				
			||||||
 | 
						.bLength = USB_DT_ENDPOINT_SIZE,
 | 
				
			||||||
 | 
							.bDescriptorType = USB_DT_ENDPOINT,
 | 
				
			||||||
 | 
							.bEndpointAddress = 0x83,
 | 
				
			||||||
 | 
							.bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT,
 | 
				
			||||||
 | 
							.wMaxPacketSize = 16,
 | 
				
			||||||
 | 
							.bInterval = 255,
 | 
				
			||||||
 | 
					}};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct usb_endpoint_descriptor data_endp[] = {{
 | 
				
			||||||
 | 
						.bLength = USB_DT_ENDPOINT_SIZE,
 | 
				
			||||||
 | 
							.bDescriptorType = USB_DT_ENDPOINT,
 | 
				
			||||||
 | 
							.bEndpointAddress = 0x01,
 | 
				
			||||||
 | 
							.bmAttributes = USB_ENDPOINT_ATTR_BULK,
 | 
				
			||||||
 | 
							.wMaxPacketSize = 64,
 | 
				
			||||||
 | 
							.bInterval = 1,
 | 
				
			||||||
 | 
					}, {
 | 
				
			||||||
 | 
						.bLength = USB_DT_ENDPOINT_SIZE,
 | 
				
			||||||
 | 
							.bDescriptorType = USB_DT_ENDPOINT,
 | 
				
			||||||
 | 
							.bEndpointAddress = 0x82,
 | 
				
			||||||
 | 
							.bmAttributes = USB_ENDPOINT_ATTR_BULK,
 | 
				
			||||||
 | 
							.wMaxPacketSize = 64,
 | 
				
			||||||
 | 
							.bInterval = 1,
 | 
				
			||||||
 | 
					}};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct {
 | 
				
			||||||
 | 
						struct usb_cdc_header_descriptor header;
 | 
				
			||||||
 | 
						struct usb_cdc_call_management_descriptor call_mgmt;
 | 
				
			||||||
 | 
						struct usb_cdc_acm_descriptor acm;
 | 
				
			||||||
 | 
						struct usb_cdc_union_descriptor cdc_union;
 | 
				
			||||||
 | 
					} __attribute__((packed)) cdcacm_functional_descriptors = {
 | 
				
			||||||
 | 
						.header = {
 | 
				
			||||||
 | 
							.bFunctionLength = sizeof(struct usb_cdc_header_descriptor),
 | 
				
			||||||
 | 
							.bDescriptorType = CS_INTERFACE,
 | 
				
			||||||
 | 
							.bDescriptorSubtype = USB_CDC_TYPE_HEADER,
 | 
				
			||||||
 | 
							.bcdCDC = 0x0110,
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						.call_mgmt = {
 | 
				
			||||||
 | 
							.bFunctionLength =
 | 
				
			||||||
 | 
								sizeof(struct usb_cdc_call_management_descriptor),
 | 
				
			||||||
 | 
							.bDescriptorType = CS_INTERFACE,
 | 
				
			||||||
 | 
							.bDescriptorSubtype = USB_CDC_TYPE_CALL_MANAGEMENT,
 | 
				
			||||||
 | 
							.bmCapabilities = 0,
 | 
				
			||||||
 | 
							.bDataInterface = 1,
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						.acm = {
 | 
				
			||||||
 | 
							.bFunctionLength = sizeof(struct usb_cdc_acm_descriptor),
 | 
				
			||||||
 | 
							.bDescriptorType = CS_INTERFACE,
 | 
				
			||||||
 | 
							.bDescriptorSubtype = USB_CDC_TYPE_ACM,
 | 
				
			||||||
 | 
							.bmCapabilities = 0,
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						.cdc_union = {
 | 
				
			||||||
 | 
							.bFunctionLength = sizeof(struct usb_cdc_union_descriptor),
 | 
				
			||||||
 | 
							.bDescriptorType = CS_INTERFACE,
 | 
				
			||||||
 | 
							.bDescriptorSubtype = USB_CDC_TYPE_UNION,
 | 
				
			||||||
 | 
							.bControlInterface = 0,
 | 
				
			||||||
 | 
							.bSubordinateInterface0 = 1,
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct usb_interface_descriptor comm_iface[] = {{
 | 
				
			||||||
 | 
						.bLength = USB_DT_INTERFACE_SIZE,
 | 
				
			||||||
 | 
							.bDescriptorType = USB_DT_INTERFACE,
 | 
				
			||||||
 | 
							.bInterfaceNumber = 0,
 | 
				
			||||||
 | 
							.bAlternateSetting = 0,
 | 
				
			||||||
 | 
							.bNumEndpoints = 1,
 | 
				
			||||||
 | 
							.bInterfaceClass = USB_CLASS_CDC,
 | 
				
			||||||
 | 
							.bInterfaceSubClass = USB_CDC_SUBCLASS_ACM,
 | 
				
			||||||
 | 
							.bInterfaceProtocol = USB_CDC_PROTOCOL_AT,
 | 
				
			||||||
 | 
							.iInterface = 0,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							.endpoint = comm_endp,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							.extra = &cdcacm_functional_descriptors,
 | 
				
			||||||
 | 
							.extralen = sizeof(cdcacm_functional_descriptors),
 | 
				
			||||||
 | 
					}};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct usb_interface_descriptor data_iface[] = {{
 | 
				
			||||||
 | 
						.bLength = USB_DT_INTERFACE_SIZE,
 | 
				
			||||||
 | 
							.bDescriptorType = USB_DT_INTERFACE,
 | 
				
			||||||
 | 
							.bInterfaceNumber = 1,
 | 
				
			||||||
 | 
							.bAlternateSetting = 0,
 | 
				
			||||||
 | 
							.bNumEndpoints = 2,
 | 
				
			||||||
 | 
							.bInterfaceClass = USB_CLASS_DATA,
 | 
				
			||||||
 | 
							.bInterfaceSubClass = 0,
 | 
				
			||||||
 | 
							.bInterfaceProtocol = 0,
 | 
				
			||||||
 | 
							.iInterface = 0,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							.endpoint = data_endp,
 | 
				
			||||||
 | 
					}};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct usb_interface ifaces[] = {{
 | 
				
			||||||
 | 
						.num_altsetting = 1,
 | 
				
			||||||
 | 
							.altsetting = comm_iface,
 | 
				
			||||||
 | 
					}, {
 | 
				
			||||||
 | 
						.num_altsetting = 1,
 | 
				
			||||||
 | 
							.altsetting = data_iface,
 | 
				
			||||||
 | 
					}};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct usb_config_descriptor config = {
 | 
				
			||||||
 | 
						.bLength = USB_DT_CONFIGURATION_SIZE,
 | 
				
			||||||
 | 
						.bDescriptorType = USB_DT_CONFIGURATION,
 | 
				
			||||||
 | 
						.wTotalLength = 0,
 | 
				
			||||||
 | 
						.bNumInterfaces = 2,
 | 
				
			||||||
 | 
						.bConfigurationValue = 1,
 | 
				
			||||||
 | 
						.iConfiguration = 0,
 | 
				
			||||||
 | 
						.bmAttributes = 0x80,
 | 
				
			||||||
 | 
						.bMaxPower = 0x32,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						.interface = ifaces,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const char *usb_strings[] = {
 | 
				
			||||||
 | 
						"Black Sphere Technologies",
 | 
				
			||||||
 | 
						"CDC-ACM Demo",
 | 
				
			||||||
 | 
						"DEMO",
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Buffer to be used for control requests. */
 | 
				
			||||||
 | 
					uint8_t usbd_control_buffer[128];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static enum usbd_request_return_codes
 | 
				
			||||||
 | 
					cdcacm_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, uint8_t **buf,
 | 
				
			||||||
 | 
							       uint16_t *len, void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req))
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						(void)complete;
 | 
				
			||||||
 | 
						(void)buf;
 | 
				
			||||||
 | 
						(void)usbd_dev;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (req->bRequest) {
 | 
				
			||||||
 | 
							case USB_CDC_REQ_SET_CONTROL_LINE_STATE: {
 | 
				
			||||||
 | 
													 /*
 | 
				
			||||||
 | 
													  * This Linux cdc_acm driver requires this to be implemented
 | 
				
			||||||
 | 
													  * even though it's optional in the CDC spec, and we don't
 | 
				
			||||||
 | 
													  * advertise it in the ACM functional descriptor.
 | 
				
			||||||
 | 
													  */
 | 
				
			||||||
 | 
													 char local_buf[10];
 | 
				
			||||||
 | 
													 struct usb_cdc_notification *notif = (void *)local_buf;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
													 /* We echo signals back to host as notification. */
 | 
				
			||||||
 | 
													 notif->bmRequestType = 0xA1;
 | 
				
			||||||
 | 
													 notif->bNotification = USB_CDC_NOTIFY_SERIAL_STATE;
 | 
				
			||||||
 | 
													 notif->wValue = 0;
 | 
				
			||||||
 | 
													 notif->wIndex = 0;
 | 
				
			||||||
 | 
													 notif->wLength = 2;
 | 
				
			||||||
 | 
													 local_buf[8] = req->wValue & 3;
 | 
				
			||||||
 | 
													 local_buf[9] = 0;
 | 
				
			||||||
 | 
													 // usbd_ep_write_packet(0x83, buf, 10);
 | 
				
			||||||
 | 
													 return USBD_REQ_HANDLED;
 | 
				
			||||||
 | 
												 }
 | 
				
			||||||
 | 
							case USB_CDC_REQ_SET_LINE_CODING:
 | 
				
			||||||
 | 
												 if (*len < sizeof(struct usb_cdc_line_coding))
 | 
				
			||||||
 | 
													 return USBD_REQ_NOTSUPP;
 | 
				
			||||||
 | 
												 return USBD_REQ_HANDLED;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return USBD_REQ_NOTSUPP;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					cdcacm_data_rx_cb(usbd_device *usbd_dev, uint8_t ep)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						(void)ep;
 | 
				
			||||||
 | 
						(void)usbd_dev;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						char buf[64];
 | 
				
			||||||
 | 
						int len = usbd_ep_read_packet(usbd_dev, 0x01, buf, 64);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (len) {
 | 
				
			||||||
 | 
							usbd_ep_write_packet(usbd_dev, 0x82, buf, len);
 | 
				
			||||||
 | 
							buf[len] = 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					cdcacm_set_config(usbd_device *usbd_dev, uint16_t wValue)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						(void)wValue;
 | 
				
			||||||
 | 
						(void)usbd_dev;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						usbd_ep_setup(usbd_dev, 0x01, USB_ENDPOINT_ATTR_BULK, 64, cdcacm_data_rx_cb);
 | 
				
			||||||
 | 
						usbd_ep_setup(usbd_dev, 0x82, USB_ENDPOINT_ATTR_BULK, 64, NULL);
 | 
				
			||||||
 | 
						usbd_ep_setup(usbd_dev, 0x83, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						usbd_register_control_callback(
 | 
				
			||||||
 | 
								usbd_dev,
 | 
				
			||||||
 | 
								USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE,
 | 
				
			||||||
 | 
								USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT,
 | 
				
			||||||
 | 
								cdcacm_control_request);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					main(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						usbd_device *usbd_dev;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rcc_clock_setup_in_hsi_out_48mhz();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rcc_periph_clock_enable(RCC_GPIOC);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						gpio_set(GPIOC, GPIO11);
 | 
				
			||||||
 | 
						gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ,
 | 
				
			||||||
 | 
								GPIO_CNF_OUTPUT_PUSHPULL, GPIO11);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						usbd_dev = usbd_init(&st_usbfs_v1_usb_driver, &dev, &config, usb_strings, 3, usbd_control_buffer, sizeof(usbd_control_buffer));
 | 
				
			||||||
 | 
						usbd_register_set_config_callback(usbd_dev, cdcacm_set_config);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < 0x800000; i++)
 | 
				
			||||||
 | 
							__asm__("nop");
 | 
				
			||||||
 | 
						gpio_clear(GPIOC, GPIO11);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while (1)
 | 
				
			||||||
 | 
							usbd_poll(usbd_dev);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,11 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This directory is intended for PIO Unit Testing and project tests.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Unit Testing is a software testing method by which individual units of
 | 
				
			||||||
 | 
					source code, sets of one or more MCU program modules together with associated
 | 
				
			||||||
 | 
					control data, usage procedures, and operating procedures, are tested to
 | 
				
			||||||
 | 
					determine whether they are fit for use. Unit testing finds problems early
 | 
				
			||||||
 | 
					in the development cycle.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					More information about PIO Unit Testing:
 | 
				
			||||||
 | 
					- https://docs.platformio.org/page/plus/unit-testing.html
 | 
				
			||||||
		Loading…
	
		Reference in New Issue