Merge branch 'master' into pigrew-ZLP_Request2
This commit is contained in:
		
							
								
								
									
										12
									
								
								examples/device/dfu_rt/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								examples/device/dfu_rt/Makefile
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| include ../../../tools/top.mk | ||||
| include ../../make.mk | ||||
|  | ||||
| INC += \ | ||||
| 	src \ | ||||
| 	$(TOP)/hw \ | ||||
|  | ||||
| # Example source | ||||
| EXAMPLE_SOURCE += $(wildcard src/*.c) | ||||
| SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE)) | ||||
|  | ||||
| include ../../rules.mk | ||||
							
								
								
									
										151
									
								
								examples/device/dfu_rt/src/main.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										151
									
								
								examples/device/dfu_rt/src/main.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,151 @@ | ||||
| /*  | ||||
|  * The MIT License (MIT) | ||||
|  * | ||||
|  * Copyright (c) 2019 Ha Thach (tinyusb.org) | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|  * of this software and associated documentation files (the "Software"), to deal | ||||
|  * in the Software without restriction, including without limitation the rights | ||||
|  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|  * copies of the Software, and to permit persons to whom the Software is | ||||
|  * furnished to do so, subject to the following conditions: | ||||
|  * | ||||
|  * The above copyright notice and this permission notice shall be included in | ||||
|  * all copies or substantial portions of the Software. | ||||
|  * | ||||
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
|  * THE SOFTWARE. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #include <stdlib.h> | ||||
| #include <stdio.h> | ||||
| #include <string.h> | ||||
|  | ||||
| #include "bsp/board.h" | ||||
| #include "tusb.h" | ||||
|  | ||||
| //--------------------------------------------------------------------+ | ||||
| // MACRO CONSTANT TYPEDEF PROTYPES | ||||
| //--------------------------------------------------------------------+ | ||||
|  | ||||
| /* Blink pattern | ||||
|  * - 1000 ms : device should reboot | ||||
|  * - 250 ms  : device not mounted | ||||
|  * - 0 ms : device mounted | ||||
|  * - 2500 ms : device is suspended | ||||
|  */ | ||||
| enum  { | ||||
|   BLINK_DFU_MODE = 1000, | ||||
|   BLINK_NOT_MOUNTED = 250, | ||||
|   BLINK_MOUNTED = 0, | ||||
|   BLINK_SUSPENDED = 2500, | ||||
| }; | ||||
|  | ||||
| static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; | ||||
|  | ||||
| void led_blinking_task(void); | ||||
|  | ||||
| /*------------- MAIN -------------*/ | ||||
| int main(void) | ||||
| { | ||||
|   board_init(); | ||||
|  | ||||
|   tusb_init(); | ||||
|  | ||||
|   while (1) | ||||
|   { | ||||
|     tud_task(); // tinyusb device task | ||||
|     led_blinking_task(); | ||||
|   } | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| //--------------------------------------------------------------------+ | ||||
| // Device callbacks | ||||
| //--------------------------------------------------------------------+ | ||||
|  | ||||
| // Invoked when device is mounted | ||||
| void tud_mount_cb(void) | ||||
| { | ||||
|   blink_interval_ms = BLINK_MOUNTED; | ||||
| } | ||||
|  | ||||
| // Invoked when device is unmounted | ||||
| void tud_umount_cb(void) | ||||
| { | ||||
|   blink_interval_ms = BLINK_NOT_MOUNTED; | ||||
| } | ||||
|  | ||||
| // Invoked when usb bus is suspended | ||||
| // remote_wakeup_en : if host allow us  to perform remote wakeup | ||||
| // Within 7ms, device must draw an average of current less than 2.5 mA from bus | ||||
| void tud_suspend_cb(bool remote_wakeup_en) | ||||
| { | ||||
|   (void) remote_wakeup_en; | ||||
|   blink_interval_ms = BLINK_SUSPENDED; | ||||
| } | ||||
|  | ||||
| // Invoked when usb bus is resumed | ||||
| void tud_resume_cb(void) | ||||
| { | ||||
|   blink_interval_ms = BLINK_MOUNTED; | ||||
| } | ||||
|  | ||||
| // Invoked on DFU_DETACH request to reboot to the bootloader | ||||
| void tud_dfu_rt_reboot_to_dfu(void) | ||||
| { | ||||
|   blink_interval_ms = BLINK_DFU_MODE; | ||||
| } | ||||
|  | ||||
|  | ||||
| //--------------------------------------------------------------------+ | ||||
| // BLINKING TASK + Indicator pulse | ||||
| //--------------------------------------------------------------------+ | ||||
|  | ||||
|  | ||||
| volatile uint8_t doPulse = false; | ||||
| // called from USB context | ||||
| void led_indicator_pulse(void) { | ||||
| 	doPulse = true; | ||||
| } | ||||
|  | ||||
| void led_blinking_task(void) | ||||
| { | ||||
|   static uint32_t start_ms = 0; | ||||
|   static bool led_state = false; | ||||
|   if(blink_interval_ms == BLINK_MOUNTED) // Mounted | ||||
|   { | ||||
|     if(doPulse) | ||||
|     { | ||||
|       led_state = true; | ||||
|       board_led_write(true); | ||||
|       start_ms = board_millis(); | ||||
|       doPulse = false; | ||||
|     } | ||||
|     else if (led_state == true) | ||||
|     { | ||||
|       if ( board_millis() - start_ms < 750) //Spec says blink must be between 500 and 1000 ms. | ||||
|       { | ||||
|         return; // not enough time | ||||
|       } | ||||
|       led_state = false; | ||||
|       board_led_write(false); | ||||
|     } | ||||
|   } | ||||
|   else | ||||
|   { | ||||
|     // Blink every interval ms | ||||
|     if ( board_millis() - start_ms < blink_interval_ms) return; // not enough time | ||||
|     start_ms += blink_interval_ms; | ||||
|  | ||||
|     board_led_write(led_state); | ||||
|     led_state = 1 - led_state; // toggle | ||||
|   } | ||||
| } | ||||
							
								
								
									
										5
									
								
								examples/device/dfu_rt/src/main.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								examples/device/dfu_rt/src/main.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| #ifndef MAIN_H | ||||
| #define MAIN_H | ||||
| void led_indicator_pulse(void); | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										64
									
								
								examples/device/dfu_rt/src/tusb_config.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								examples/device/dfu_rt/src/tusb_config.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,64 @@ | ||||
| /* | ||||
|  * tusb_config.h | ||||
|  * | ||||
|  *  Created on: Oct 28, 2019 | ||||
|  *      Author: Sylvain Munaut | ||||
|  */ | ||||
|  | ||||
| #ifndef TUSB_CONFIG_H_ | ||||
| #define TUSB_CONFIG_H_ | ||||
|  | ||||
| #ifdef __cplusplus | ||||
|  extern "C" { | ||||
| #endif | ||||
|  | ||||
| //-------------------------------------------------------------------- | ||||
| // COMMON CONFIGURATION | ||||
| //-------------------------------------------------------------------- | ||||
|  | ||||
| // defined by compiler flags for flexibility | ||||
| #ifndef CFG_TUSB_MCU | ||||
|   #error CFG_TUSB_MCU must be defined | ||||
| #endif | ||||
|  | ||||
| #if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX | ||||
| #define CFG_TUSB_RHPORT0_MODE       (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED) | ||||
| #else | ||||
| #define CFG_TUSB_RHPORT0_MODE       OPT_MODE_DEVICE | ||||
| #endif | ||||
|  | ||||
| #define CFG_TUSB_OS                 OPT_OS_NONE | ||||
|  | ||||
| // CFG_TUSB_DEBUG is defined by compiler in DEBUG build | ||||
| // #define CFG_TUSB_DEBUG           0 | ||||
|  | ||||
| /* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. | ||||
|  * Tinyusb use follows macros to declare transferring memory so that they can be put | ||||
|  * into those specific section. | ||||
|  * e.g | ||||
|  * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) | ||||
|  * - CFG_TUSB_MEM_ALIGN   : __attribute__ ((aligned(4))) | ||||
|  */ | ||||
| #ifndef CFG_TUSB_MEM_SECTION | ||||
| #define CFG_TUSB_MEM_SECTION | ||||
| #endif | ||||
|  | ||||
| #ifndef CFG_TUSB_MEM_ALIGN | ||||
| #define CFG_TUSB_MEM_ALIGN          __attribute__ ((aligned(4))) | ||||
| #endif | ||||
|  | ||||
| //-------------------------------------------------------------------- | ||||
| // DEVICE CONFIGURATION | ||||
| //-------------------------------------------------------------------- | ||||
|  | ||||
| #define CFG_TUD_ENDPOINT0_SIZE    64 | ||||
|  | ||||
| //------------- CLASS -------------// | ||||
|  | ||||
| #define CFG_TUD_DFU_RT 1 | ||||
|  | ||||
| #ifdef __cplusplus | ||||
|  } | ||||
| #endif | ||||
|  | ||||
| #endif /* TUSB_CONFIG_H_ */ | ||||
							
								
								
									
										229
									
								
								examples/device/dfu_rt/src/usb_descriptors.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										229
									
								
								examples/device/dfu_rt/src/usb_descriptors.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,229 @@ | ||||
| /* | ||||
|  * The MIT License (MIT) | ||||
|  * | ||||
|  * Copyright (c) 2019 Ha Thach (tinyusb.org) | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|  * of this software and associated documentation files (the "Software"), to deal | ||||
|  * in the Software without restriction, including without limitation the rights | ||||
|  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|  * copies of the Software, and to permit persons to whom the Software is | ||||
|  * furnished to do so, subject to the following conditions: | ||||
|  * | ||||
|  * The above copyright notice and this permission notice shall be included in | ||||
|  * all copies or substantial portions of the Software. | ||||
|  * | ||||
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
|  * THE SOFTWARE. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #include "tusb.h" | ||||
| #include "class/dfu/dfu_rt_device.h" | ||||
|  | ||||
| /* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. | ||||
|  * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. | ||||
|  * | ||||
|  * Auto ProductID layout's Bitmap: | ||||
|  *   [MSB]         HID | MSC | CDC          [LSB] | ||||
|  */ | ||||
| #define _PID_MAP(itf, n)  ( (CFG_TUD_##itf) << (n) ) | ||||
| #define USB_PID           (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \ | ||||
|                            _PID_MAP(MIDI, 3) | _PID_MAP(VENDOR, 4) ) | ||||
|  | ||||
| //--------------------------------------------------------------------+ | ||||
| // Device Descriptors | ||||
| //--------------------------------------------------------------------+ | ||||
| tusb_desc_device_t const desc_device = | ||||
| { | ||||
|     .bLength            = sizeof(tusb_desc_device_t), | ||||
|     .bDescriptorType    = TUSB_DESC_DEVICE, | ||||
|     .bcdUSB             = 0x0200, | ||||
|  | ||||
|   #if CFG_TUD_CDC | ||||
|     // Use Interface Association Descriptor (IAD) for CDC | ||||
|     // As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1) | ||||
|     .bDeviceClass       = TUSB_CLASS_MISC, | ||||
|     .bDeviceSubClass    = MISC_SUBCLASS_COMMON, | ||||
|     .bDeviceProtocol    = MISC_PROTOCOL_IAD, | ||||
|   #else | ||||
|     .bDeviceClass       = 0x00, | ||||
|     .bDeviceSubClass    = 0x00, | ||||
|     .bDeviceProtocol    = 0x00, | ||||
|   #endif | ||||
|  | ||||
|     .bMaxPacketSize0    = CFG_TUD_ENDPOINT0_SIZE, | ||||
|  | ||||
|     .idVendor           = 0xCafe, | ||||
|     .idProduct          = USB_PID, | ||||
|     .bcdDevice          = 0x0100, | ||||
|  | ||||
|     .iManufacturer      = 0x01, | ||||
|     .iProduct           = 0x02, | ||||
|     .iSerialNumber      = 0x03, | ||||
|  | ||||
|     .bNumConfigurations = 0x01 | ||||
| }; | ||||
|  | ||||
| // Invoked when received GET DEVICE DESCRIPTOR | ||||
| // Application return pointer to descriptor | ||||
| uint8_t const * tud_descriptor_device_cb(void) | ||||
| { | ||||
|   return (uint8_t const *) &desc_device; | ||||
| } | ||||
|  | ||||
| //--------------------------------------------------------------------+ | ||||
| // HID Report Descriptor | ||||
| //--------------------------------------------------------------------+ | ||||
| #if CFG_TUD_HID | ||||
|  | ||||
| uint8_t const desc_hid_report[] = | ||||
| { | ||||
|   TUD_HID_REPORT_DESC_KEYBOARD( HID_REPORT_ID(REPORT_ID_KEYBOARD), ), | ||||
|   TUD_HID_REPORT_DESC_MOUSE   ( HID_REPORT_ID(REPORT_ID_MOUSE), ) | ||||
| }; | ||||
|  | ||||
| // Invoked when received GET HID REPORT DESCRIPTOR | ||||
| // Application return pointer to descriptor | ||||
| // Descriptor contents must exist long enough for transfer to complete | ||||
| uint8_t const * tud_hid_descriptor_report_cb(void) | ||||
| { | ||||
|   return desc_hid_report; | ||||
| } | ||||
|  | ||||
| #endif | ||||
|  | ||||
| //--------------------------------------------------------------------+ | ||||
| // Configuration Descriptor | ||||
| //--------------------------------------------------------------------+ | ||||
|  | ||||
| enum | ||||
| { | ||||
| #if CFG_TUD_CDC | ||||
|   ITF_NUM_CDC = 0, | ||||
|   ITF_NUM_CDC_DATA, | ||||
| #endif | ||||
|  | ||||
| #if CFG_TUD_MSC | ||||
|   ITF_NUM_MSC, | ||||
| #endif | ||||
|  | ||||
| #if CFG_TUD_HID | ||||
|   ITF_NUM_HID, | ||||
| #endif | ||||
|  | ||||
| #if CFG_TUD_DFU_RT | ||||
|   ITF_NUM_DFU_RT, | ||||
| #endif | ||||
|  | ||||
|   ITF_NUM_TOTAL | ||||
| }; | ||||
|  | ||||
|  | ||||
| #define CONFIG_TOTAL_LEN    (TUD_CONFIG_DESC_LEN + CFG_TUD_CDC*TUD_CDC_DESC_LEN + CFG_TUD_MSC*TUD_MSC_DESC_LEN +  \ | ||||
|     CFG_TUD_HID*TUD_HID_DESC_LEN  + (CFG_TUD_DFU_RT)*TUD_DFU_RT_DESC_LEN) | ||||
|  | ||||
| #if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX | ||||
|   // LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number | ||||
|   // 0 control, 1 In, 2 Bulk, 3 Iso, 4 In etc ... | ||||
|   // Note: since CDC EP ( 1 & 2), HID (4) are spot-on, thus we only need to force | ||||
|   // endpoint number for MSC to 5 | ||||
|   #define EPNUM_MSC   0x05 | ||||
| #else | ||||
|   #define EPNUM_MSC   0x03 | ||||
| #endif | ||||
|  | ||||
|  | ||||
| uint8_t const desc_configuration[] = | ||||
| { | ||||
|   // Interface count, string index, total length, attribute, power in mA | ||||
|   TUD_CONFIG_DESCRIPTOR(ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), | ||||
|  | ||||
| #if CFG_TUD_CDC | ||||
|   // Interface number, string index, EP notification address and size, EP data address (out, in) and size. | ||||
|   TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 1, 0x81, 8, 0x02, 0x82, 64), | ||||
| #endif | ||||
|  | ||||
| #if CFG_TUD_MSC | ||||
|   // Interface number, string index, EP Out & EP In address, EP size | ||||
|   TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 5, EPNUM_MSC, 0x80 | EPNUM_MSC, (CFG_TUSB_RHPORT0_MODE & OPT_MODE_HIGH_SPEED) ? 512 : 64), | ||||
| #endif | ||||
|  | ||||
| #if CFG_TUD_HID | ||||
|   // Interface number, string index, protocol, report descriptor len, EP In address, size & polling interval | ||||
|   TUD_HID_DESCRIPTOR(ITF_NUM_HID, 6, HID_PROTOCOL_NONE, sizeof(desc_hid_report), 0x84, 16, 10), | ||||
| #endif | ||||
|  | ||||
| #if CFG_TUD_DFU_RT | ||||
|   // Interface number, string index, attributes, detach timeout, transfer size */ | ||||
|   TUD_DFU_RT_DESCRIPTOR(ITF_NUM_DFU_RT, 7, 0x0d, 1000, 4096), | ||||
| #endif | ||||
| }; | ||||
|  | ||||
|  | ||||
| // Invoked when received GET CONFIGURATION DESCRIPTOR | ||||
| // Application return pointer to descriptor | ||||
| // Descriptor contents must exist long enough for transfer to complete | ||||
| uint8_t const * tud_descriptor_configuration_cb(uint8_t index) | ||||
| { | ||||
|   (void) index; // for multiple configurations | ||||
|   return desc_configuration; | ||||
| } | ||||
|  | ||||
| //--------------------------------------------------------------------+ | ||||
| // String Descriptors | ||||
| //--------------------------------------------------------------------+ | ||||
|  | ||||
| // array of pointer to string descriptors | ||||
| char const* string_desc_arr [] = | ||||
| { | ||||
|   (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409) | ||||
|   "TinyUSB",                     // 1: Manufacturer | ||||
|   "TinyUSB Device",              // 2: Product | ||||
|   "123456",                      // 3: Serials, should use chip ID | ||||
|   "TinyUSB DFU runtime",         // 4: DFU runtime | ||||
| }; | ||||
|  | ||||
| static uint16_t _desc_str[32]; | ||||
|  | ||||
| // Invoked when received GET STRING DESCRIPTOR request | ||||
| // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete | ||||
| uint16_t const* tud_descriptor_string_cb(uint8_t index) | ||||
| { | ||||
|   size_t chr_count; | ||||
|  | ||||
|   if ( index == 0) | ||||
|   { | ||||
|     memcpy(&_desc_str[1], string_desc_arr[0], 2); | ||||
|     chr_count = 1; | ||||
|   } | ||||
|   else | ||||
|   { | ||||
|     // Convert ASCII string into UTF-16 | ||||
|  | ||||
|     if ( !(index < sizeof(string_desc_arr)/sizeof(string_desc_arr[0])) ) return NULL; | ||||
|  | ||||
|     const char* str = string_desc_arr[index]; | ||||
|  | ||||
|     // Cap at max char | ||||
|     chr_count = strlen(str); | ||||
|     if ( chr_count > 31 ) { | ||||
|       chr_count = 31; | ||||
|     } | ||||
|  | ||||
|     for(uint8_t i=0; i<chr_count; i++) | ||||
|     { | ||||
|       _desc_str[1+i] = str[i]; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // first byte is length (including header), second byte is string type | ||||
|   _desc_str[0] = (uint16_t)((((uint16_t)TUSB_DESC_STRING) << 8 ) | (2u*chr_count + 2u)); | ||||
|  | ||||
|   return _desc_str; | ||||
| } | ||||
| @@ -17,6 +17,7 @@ SRC_C += \ | ||||
| 	src/device/usbd_control.c \ | ||||
| 	src/class/msc/msc_device.c \ | ||||
| 	src/class/cdc/cdc_device.c \ | ||||
| 	src/class/dfu/dfu_rt_device.c \ | ||||
| 	src/class/hid/hid_device.c \ | ||||
| 	src/class/midi/midi_device.c \ | ||||
| 	src/class/usbtmc/usbtmc_device.c \ | ||||
|   | ||||
							
								
								
									
										120
									
								
								src/class/dfu/dfu_rt_device.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								src/class/dfu/dfu_rt_device.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,120 @@ | ||||
| /* | ||||
|  * The MIT License (MIT) | ||||
|  * | ||||
|  * Copyright (c) 2019 Sylvain Munaut <tnt@246tNt.com> | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|  * of this software and associated documentation files (the "Software"), to deal | ||||
|  * in the Software without restriction, including without limitation the rights | ||||
|  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|  * copies of the Software, and to permit persons to whom the Software is | ||||
|  * furnished to do so, subject to the following conditions: | ||||
|  * | ||||
|  * The above copyright notice and this permission notice shall be included in | ||||
|  * all copies or substantial portions of the Software. | ||||
|  * | ||||
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
|  * THE SOFTWARE. | ||||
|  * | ||||
|  * This file is part of the TinyUSB stack. | ||||
|  */ | ||||
|  | ||||
| #include "tusb_option.h" | ||||
|  | ||||
| #if (TUSB_OPT_DEVICE_ENABLED && CFG_TUD_DFU_RT) | ||||
|  | ||||
| #include "dfu_rt_device.h" | ||||
| #include "device/usbd_pvt.h" | ||||
|  | ||||
| //--------------------------------------------------------------------+ | ||||
| // MACRO CONSTANT TYPEDEF | ||||
| //--------------------------------------------------------------------+ | ||||
| typedef enum { | ||||
|   DFU_REQUEST_DETACH      = 0, | ||||
|   DFU_REQUEST_DNLOAD      = 1, | ||||
|   DFU_REQUEST_UPLOAD      = 2, | ||||
|   DFU_REQUEST_GETSTATUS   = 3, | ||||
|   DFU_REQUEST_CLRSTATUS   = 4, | ||||
|   DFU_REQUEST_GETSTATE    = 5, | ||||
|   DFU_REQUEST_ABORT       = 6, | ||||
| } dfu_requests_t; | ||||
|  | ||||
| //--------------------------------------------------------------------+ | ||||
| // USBD Driver API | ||||
| //--------------------------------------------------------------------+ | ||||
| void dfu_rtd_init(void) | ||||
| { | ||||
| } | ||||
|  | ||||
| void dfu_rtd_reset(uint8_t rhport) | ||||
| { | ||||
|   (void) rhport; | ||||
| } | ||||
|  | ||||
| bool dfu_rtd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t *p_length) | ||||
| { | ||||
|   (void) rhport; | ||||
|  | ||||
|   // Ensure this is DFU Runtime | ||||
|   TU_ASSERT(itf_desc->bInterfaceSubClass == TUD_DFU_APP_SUBCLASS); | ||||
|   TU_ASSERT(itf_desc->bInterfaceProtocol == DFU_PROTOCOL_RT); | ||||
|  | ||||
|   uint8_t const * p_desc = tu_desc_next( itf_desc ); | ||||
|   (*p_length) = sizeof(tusb_desc_interface_t); | ||||
|  | ||||
|   if ( TUSB_DESC_FUNCTIONAL == tu_desc_type(p_desc) ) | ||||
|   { | ||||
|     (*p_length) += p_desc[DESC_OFFSET_LEN]; | ||||
|     p_desc = tu_desc_next(p_desc); | ||||
|   } | ||||
|  | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| bool dfu_rtd_control_complete(uint8_t rhport, tusb_control_request_t const * request) | ||||
| { | ||||
|   (void) rhport; | ||||
|  | ||||
|   //------------- Class Specific Request -------------// | ||||
|   TU_VERIFY(request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS); | ||||
|   TU_VERIFY(request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_INTERFACE); | ||||
|  | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| bool dfu_rtd_control_request(uint8_t rhport, tusb_control_request_t const * request) | ||||
| { | ||||
|   (void) rhport; | ||||
|  | ||||
|   //------------- Class Specific Request -------------// | ||||
|   TU_ASSERT(request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS); | ||||
|   TU_ASSERT(request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_INTERFACE); | ||||
|  | ||||
|   switch ( request->bRequest ) | ||||
|   { | ||||
|     case DFU_REQUEST_DETACH: | ||||
|       tud_control_status(rhport, request); | ||||
|       tud_dfu_rt_reboot_to_dfu(); | ||||
|     break; | ||||
|  | ||||
|     default: return false; // stall unsupported request | ||||
|   } | ||||
|  | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| bool dfu_rtd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) | ||||
| { | ||||
|   (void) rhport; | ||||
|   (void) ep_addr; | ||||
|   (void) result; | ||||
|   (void) xferred_bytes; | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										77
									
								
								src/class/dfu/dfu_rt_device.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								src/class/dfu/dfu_rt_device.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,77 @@ | ||||
| /* | ||||
|  * The MIT License (MIT) | ||||
|  * | ||||
|  * Copyright (c) 2019 Sylvain Munaut <tnt@246tNt.com> | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|  * of this software and associated documentation files (the "Software"), to deal | ||||
|  * in the Software without restriction, including without limitation the rights | ||||
|  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|  * copies of the Software, and to permit persons to whom the Software is | ||||
|  * furnished to do so, subject to the following conditions: | ||||
|  * | ||||
|  * The above copyright notice and this permission notice shall be included in | ||||
|  * all copies or substantial portions of the Software. | ||||
|  * | ||||
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
|  * THE SOFTWARE. | ||||
|  * | ||||
|  * This file is part of the TinyUSB stack. | ||||
|  */ | ||||
|  | ||||
| #ifndef _TUSB_DFU_RT_DEVICE_H_ | ||||
| #define _TUSB_DFU_RT_DEVICE_H_ | ||||
|  | ||||
| #include "common/tusb_common.h" | ||||
| #include "device/usbd.h" | ||||
|  | ||||
| #ifdef __cplusplus | ||||
|  extern "C" { | ||||
| #endif | ||||
|  | ||||
|  | ||||
| //--------------------------------------------------------------------+ | ||||
| // Common Definitions | ||||
| //--------------------------------------------------------------------+ | ||||
|  | ||||
| // DFU Protocol | ||||
| typedef enum | ||||
| { | ||||
|   DFU_PROTOCOL_RT  = 1, | ||||
|   DFU_PROTOCOL_DFU = 2, | ||||
| } dfu_protocol_type_t; | ||||
|  | ||||
| // DFU Descriptor Type | ||||
| typedef enum | ||||
| { | ||||
|   DFU_DESC_FUNCTIONAL = 0x21, | ||||
| } dfu_descriptor_type_t; | ||||
|  | ||||
|  | ||||
| //--------------------------------------------------------------------+ | ||||
| // Application Callback API (weak is optional) | ||||
| //--------------------------------------------------------------------+ | ||||
|  | ||||
| // Invoked when received new data | ||||
| TU_ATTR_WEAK void tud_dfu_rt_reboot_to_dfu(void); | ||||
|  | ||||
| //--------------------------------------------------------------------+ | ||||
| // Internal Class Driver API | ||||
| //--------------------------------------------------------------------+ | ||||
| void dfu_rtd_init(void); | ||||
| void dfu_rtd_reset(uint8_t rhport); | ||||
| bool dfu_rtd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t *p_length); | ||||
| bool dfu_rtd_control_request(uint8_t rhport, tusb_control_request_t const * request); | ||||
| bool dfu_rtd_control_complete(uint8_t rhport, tusb_control_request_t const * request); | ||||
| bool dfu_rtd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); | ||||
|  | ||||
| #ifdef __cplusplus | ||||
|  } | ||||
| #endif | ||||
|  | ||||
| #endif /* _TUSB_DFU_RT_DEVICE_H_ */ | ||||
| @@ -86,6 +86,8 @@ typedef enum | ||||
|   TUSB_DESC_BOS                   = 0x0F, | ||||
|   TUSB_DESC_DEVICE_CAPABILITY     = 0x10, | ||||
|  | ||||
|   TUSB_DESC_FUNCTIONAL            = 0x21, | ||||
|  | ||||
|   // Class Specific Descriptor | ||||
|   TUSB_DESC_CS_DEVICE             = 0x21, | ||||
|   TUSB_DESC_CS_CONFIGURATION      = 0x22, | ||||
|   | ||||
| @@ -79,7 +79,7 @@ typedef struct TU_ATTR_ALIGNED(4) | ||||
|   }; | ||||
| } dcd_event_t; | ||||
|  | ||||
| TU_VERIFY_STATIC(sizeof(dcd_event_t) <= 12, "size is not correct"); | ||||
| //TU_VERIFY_STATIC(sizeof(dcd_event_t) <= 12, "size is not correct"); | ||||
|  | ||||
| /*------------------------------------------------------------------*/ | ||||
| /* Device API | ||||
| @@ -119,20 +119,51 @@ void dcd_edpt_stall       (uint8_t rhport, uint8_t ep_addr); | ||||
| // clear stall, data toggle is also reset to DATA0 | ||||
| void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr); | ||||
|  | ||||
| /*------------------------------------------------------------------*/ | ||||
| /* Event Function | ||||
|  * Called by DCD to notify device stack | ||||
|  *------------------------------------------------------------------*/ | ||||
| void dcd_event_handler(dcd_event_t const * event, bool in_isr); | ||||
| //--------------------------------------------------------------------+ | ||||
| // Event API | ||||
| //--------------------------------------------------------------------+ | ||||
|  | ||||
| // Called by DCD to notify device stack | ||||
| extern void dcd_event_handler(dcd_event_t const * event, bool in_isr); | ||||
|  | ||||
| // helper to send bus signal event | ||||
| void dcd_event_bus_signal (uint8_t rhport, dcd_eventid_t eid, bool in_isr); | ||||
| static inline void dcd_event_bus_signal (uint8_t rhport, dcd_eventid_t eid, bool in_isr); | ||||
|  | ||||
| // helper to send setup received | ||||
| void dcd_event_setup_received(uint8_t rhport, uint8_t const * setup, bool in_isr); | ||||
| static inline void dcd_event_setup_received(uint8_t rhport, uint8_t const * setup, bool in_isr); | ||||
|  | ||||
| // helper to send transfer complete event | ||||
| void dcd_event_xfer_complete (uint8_t rhport, uint8_t ep_addr, uint32_t xferred_bytes, uint8_t result, bool in_isr); | ||||
| static inline void dcd_event_xfer_complete (uint8_t rhport, uint8_t ep_addr, uint32_t xferred_bytes, uint8_t result, bool in_isr); | ||||
|  | ||||
|  | ||||
| //--------------------------------------------------------------------+ | ||||
| // Inline helper | ||||
| //--------------------------------------------------------------------+ | ||||
|  | ||||
| static inline void dcd_event_bus_signal (uint8_t rhport, dcd_eventid_t eid, bool in_isr) | ||||
| { | ||||
|   dcd_event_t event = { .rhport = rhport, .event_id = eid, }; | ||||
|   dcd_event_handler(&event, in_isr); | ||||
| } | ||||
|  | ||||
| static inline void dcd_event_setup_received(uint8_t rhport, uint8_t const * setup, bool in_isr) | ||||
| { | ||||
|   dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_SETUP_RECEIVED }; | ||||
|   memcpy(&event.setup_received, setup, 8); | ||||
|  | ||||
|   dcd_event_handler(&event, in_isr); | ||||
| } | ||||
|  | ||||
| static inline void dcd_event_xfer_complete (uint8_t rhport, uint8_t ep_addr, uint32_t xferred_bytes, uint8_t result, bool in_isr) | ||||
| { | ||||
|   dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_XFER_COMPLETE }; | ||||
|  | ||||
|   event.xfer_complete.ep_addr = ep_addr; | ||||
|   event.xfer_complete.len     = xferred_bytes; | ||||
|   event.xfer_complete.result  = result; | ||||
|  | ||||
|   dcd_event_handler(&event, in_isr); | ||||
| } | ||||
|  | ||||
| #ifdef __cplusplus | ||||
|  } | ||||
|   | ||||
| @@ -167,6 +167,20 @@ static usbd_class_driver_t const usbd_class_drivers[] = | ||||
|       .sof              = NULL | ||||
|   }, | ||||
|   #endif | ||||
|  | ||||
|   #if CFG_TUD_DFU_RT | ||||
|   { | ||||
|       .class_code       = TUD_DFU_APP_CLASS, | ||||
|     //.subclass_code    = TUD_DFU_APP_SUBCLASS | ||||
|       .init             = dfu_rtd_init, | ||||
|       .reset            = dfu_rtd_reset, | ||||
|       .open             = dfu_rtd_open, | ||||
|       .control_request  = dfu_rtd_control_request, | ||||
|       .control_complete = dfu_rtd_control_complete, | ||||
|       .xfer_cb          = dfu_rtd_xfer_cb, | ||||
|       .sof              = NULL | ||||
|   }, | ||||
|   #endif | ||||
| }; | ||||
|  | ||||
| enum { USBD_CLASS_DRIVER_COUNT = TU_ARRAY_SIZE(usbd_class_drivers) }; | ||||
| @@ -276,7 +290,7 @@ bool tud_remote_wakeup(void) | ||||
| //--------------------------------------------------------------------+ | ||||
| // USBD Task | ||||
| //--------------------------------------------------------------------+ | ||||
| bool usbd_init (void) | ||||
| bool tud_init (void) | ||||
| { | ||||
|   TU_LOG2("USBD init\r\n"); | ||||
|  | ||||
| @@ -870,34 +884,6 @@ void dcd_event_handler(dcd_event_t const * event, bool in_isr) | ||||
|   } | ||||
| } | ||||
|  | ||||
| // helper to send bus signal event | ||||
| void dcd_event_bus_signal (uint8_t rhport, dcd_eventid_t eid, bool in_isr) | ||||
| { | ||||
|   dcd_event_t event = { .rhport = rhport, .event_id = eid, }; | ||||
|   dcd_event_handler(&event, in_isr); | ||||
| } | ||||
|  | ||||
| // helper to send setup received | ||||
| void dcd_event_setup_received(uint8_t rhport, uint8_t const * setup, bool in_isr) | ||||
| { | ||||
|   dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_SETUP_RECEIVED }; | ||||
|   memcpy(&event.setup_received, setup, 8); | ||||
|  | ||||
|   dcd_event_handler(&event, in_isr); | ||||
| } | ||||
|  | ||||
| // helper to send transfer complete event | ||||
| void dcd_event_xfer_complete (uint8_t rhport, uint8_t ep_addr, uint32_t xferred_bytes, uint8_t result, bool in_isr) | ||||
| { | ||||
|   dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_XFER_COMPLETE }; | ||||
|  | ||||
|   event.xfer_complete.ep_addr = ep_addr; | ||||
|   event.xfer_complete.len     = xferred_bytes; | ||||
|   event.xfer_complete.result  = result; | ||||
|  | ||||
|   dcd_event_handler(&event, in_isr); | ||||
| } | ||||
|  | ||||
| //--------------------------------------------------------------------+ | ||||
| // Helper | ||||
| //--------------------------------------------------------------------+ | ||||
|   | ||||
| @@ -41,6 +41,9 @@ | ||||
| // Application API | ||||
| //--------------------------------------------------------------------+ | ||||
|  | ||||
| // Init device stack | ||||
| bool tud_init (void); | ||||
|  | ||||
| // Task function should be called in main/rtos loop | ||||
| void tud_task (void); | ||||
|  | ||||
| @@ -304,6 +307,21 @@ TU_ATTR_WEAK bool tud_vendor_control_complete_cb(uint8_t rhport, tusb_control_re | ||||
|   /* Endpoint In */\ | ||||
|   7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0 | ||||
|  | ||||
| //------------- DFU Runtime -------------// | ||||
| #define TUD_DFU_APP_CLASS    (TUSB_CLASS_APPLICATION_SPECIFIC) | ||||
| #define TUD_DFU_APP_SUBCLASS 0x01u | ||||
|  | ||||
| // Length of template descriptr: 18 bytes | ||||
| #define TUD_DFU_RT_DESC_LEN (9 + 9) | ||||
|  | ||||
| // DFU runtime descriptor | ||||
| // Interface number, string index, attributes, detach timeout, transfer size | ||||
| #define TUD_DFU_RT_DESCRIPTOR(_itfnum, _stridx, _attr, _timeout, _xfer_size) \ | ||||
|   /* Interface */ \ | ||||
|   9, TUSB_DESC_INTERFACE, _itfnum, 0, 0, TUD_DFU_APP_CLASS, TUD_DFU_APP_SUBCLASS, DFU_PROTOCOL_RT, _stridx, \ | ||||
|   /* Function */ \ | ||||
|   9, DFU_DESC_FUNCTIONAL, _attr, U16_TO_U8S_LE(_timeout), U16_TO_U8S_LE(_xfer_size), U16_TO_U8S_LE(0x0101) | ||||
|  | ||||
|  | ||||
| #ifdef __cplusplus | ||||
|  } | ||||
|   | ||||
| @@ -33,8 +33,6 @@ | ||||
|  extern "C" { | ||||
| #endif | ||||
|  | ||||
| bool usbd_init (void); | ||||
|  | ||||
| //--------------------------------------------------------------------+ | ||||
| // USBD Endpoint API | ||||
| //--------------------------------------------------------------------+ | ||||
|   | ||||
| @@ -47,7 +47,7 @@ bool tusb_init(void) | ||||
| #endif | ||||
|  | ||||
| #if TUSB_OPT_DEVICE_ENABLED | ||||
|   TU_ASSERT ( usbd_init() ); // init device stack | ||||
|   TU_ASSERT ( tud_init() ); // init device stack | ||||
| #endif | ||||
|  | ||||
|   _initialized = true; | ||||
|   | ||||
| @@ -87,6 +87,10 @@ | ||||
|   #if CFG_TUD_USBTMC | ||||
|     #include "class/usbtmc/usbtmc_device.h" | ||||
|   #endif | ||||
|  | ||||
|   #if CFG_TUD_DFU_RT | ||||
|     #include "class/dfu/dfu_rt_device.h" | ||||
|   #endif | ||||
| #endif | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -188,6 +188,10 @@ | ||||
|   #define CFG_TUD_USBTMC          0 | ||||
| #endif | ||||
|  | ||||
| #ifndef CFG_TUD_DFU_RT | ||||
|   #define CFG_TUD_DFU_RT          0 | ||||
| #endif | ||||
|  | ||||
|  | ||||
| //-------------------------------------------------------------------- | ||||
| // HOST OPTIONS | ||||
|   | ||||
| @@ -9,6 +9,7 @@ | ||||
|   :use_exceptions: TRUE | ||||
|   :use_test_preprocessor: TRUE | ||||
|   :use_auxiliary_dependencies: TRUE | ||||
|   :use_deep_dependencies: TRUE | ||||
|   :build_root: _build | ||||
| #  :release_build: TRUE | ||||
|   :test_file_prefix: test_ | ||||
| @@ -41,10 +42,10 @@ | ||||
|   :commmon: &common_defines [] | ||||
|   :test: | ||||
|     - *common_defines | ||||
|     - TEST | ||||
|     - _TEST_ | ||||
|   :test_preprocess: | ||||
|     - *common_defines | ||||
|     - TEST | ||||
|     - _TEST_ | ||||
|  | ||||
| :cmock: | ||||
|   :mock_prefix: mock_ | ||||
| @@ -53,6 +54,7 @@ | ||||
|   :plugins: | ||||
|     - :ignore | ||||
|     - :callback | ||||
|     - :array | ||||
|   :treat_as: | ||||
|     uint8:    HEX8 | ||||
|     uint16:   HEX16 | ||||
|   | ||||
							
								
								
									
										138
									
								
								test/test/device/usbd/test_usbd.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										138
									
								
								test/test/device/usbd/test_usbd.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,138 @@ | ||||
| /*  | ||||
|  * The MIT License (MIT) | ||||
|  * | ||||
|  * Copyright (c) 2019 hathach for Adafruit Industries | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|  * of this software and associated documentation files (the "Software"), to deal | ||||
|  * in the Software without restriction, including without limitation the rights | ||||
|  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|  * copies of the Software, and to permit persons to whom the Software is | ||||
|  * furnished to do so, subject to the following conditions: | ||||
|  * | ||||
|  * The above copyright notice and this permission notice shall be included in | ||||
|  * all copies or substantial portions of the Software. | ||||
|  * | ||||
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||
|  * THE SOFTWARE. | ||||
|  */ | ||||
|  | ||||
| #include "unity.h" | ||||
|  | ||||
| // Files to test | ||||
| #include "tusb_fifo.h" | ||||
| #include "tusb.h" | ||||
| #include "usbd.h" | ||||
| TEST_FILE("usbd_control.c") | ||||
| //TEST_FILE("usb_descriptors.c") | ||||
|  | ||||
| // Mock File | ||||
| #include "mock_dcd.h" | ||||
|  | ||||
| //--------------------------------------------------------------------+ | ||||
| // MACRO TYPEDEF CONSTANT ENUM DECLARATION | ||||
| //--------------------------------------------------------------------+ | ||||
|  | ||||
| uint8_t const rhport = 0; | ||||
|  | ||||
| tusb_desc_device_t const desc_device = | ||||
| { | ||||
|     .bLength            = sizeof(tusb_desc_device_t), | ||||
|     .bDescriptorType    = TUSB_DESC_DEVICE, | ||||
|     .bcdUSB             = 0x0200, | ||||
|  | ||||
|     // Use Interface Association Descriptor (IAD) for CDC | ||||
|     // As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1) | ||||
|     .bDeviceClass       = TUSB_CLASS_MISC, | ||||
|     .bDeviceSubClass    = MISC_SUBCLASS_COMMON, | ||||
|     .bDeviceProtocol    = MISC_PROTOCOL_IAD, | ||||
|  | ||||
|     .bMaxPacketSize0    = CFG_TUD_ENDPOINT0_SIZE, | ||||
|  | ||||
|     .idVendor           = 0xCafe, | ||||
|     .idProduct          = 0xCafe, | ||||
|     .bcdDevice          = 0x0100, | ||||
|  | ||||
|     .iManufacturer      = 0x01, | ||||
|     .iProduct           = 0x02, | ||||
|     .iSerialNumber      = 0x03, | ||||
|  | ||||
|     .bNumConfigurations = 0x01 | ||||
| }; | ||||
|  | ||||
| tusb_control_request_t const req_get_desc_device = | ||||
| { | ||||
|   .bmRequestType = 0x80, | ||||
|   .bRequest = TUSB_REQ_GET_DESCRIPTOR, | ||||
|   .wValue = (TUSB_DESC_DEVICE << 8), | ||||
|   .wIndex = 0x0000, | ||||
|   .wLength = 64 | ||||
| }; | ||||
|  | ||||
| //--------------------------------------------------------------------+ | ||||
| // | ||||
| //--------------------------------------------------------------------+ | ||||
| uint8_t const * ptr_desc_device; | ||||
|  | ||||
| uint8_t const * tud_descriptor_device_cb(void) | ||||
| { | ||||
|   return ptr_desc_device; | ||||
| } | ||||
|  | ||||
| uint8_t const * tud_descriptor_configuration_cb(uint8_t index) | ||||
| { | ||||
|   TEST_FAIL(); | ||||
|   return NULL; | ||||
| } | ||||
|  | ||||
| uint16_t const* tud_descriptor_string_cb(uint8_t index) | ||||
| { | ||||
|   return NULL; | ||||
| } | ||||
|  | ||||
| void setUp(void) | ||||
| { | ||||
|   dcd_int_disable_Ignore(); | ||||
|   dcd_int_enable_Ignore(); | ||||
|  | ||||
|   if ( !tusb_inited() ) | ||||
|   { | ||||
|     dcd_init_Expect(rhport); | ||||
|     tusb_init(); | ||||
|   } | ||||
|  | ||||
|   ptr_desc_device = (uint8_t const *) &desc_device; | ||||
| } | ||||
|  | ||||
| void tearDown(void) | ||||
| { | ||||
| } | ||||
|  | ||||
| //--------------------------------------------------------------------+ | ||||
| // | ||||
| //--------------------------------------------------------------------+ | ||||
| void test_usbd_get_device_descriptor(void) | ||||
| { | ||||
|   dcd_event_setup_received(rhport, (uint8_t*) &req_get_desc_device, false); | ||||
|  | ||||
|   dcd_edpt_xfer_ExpectWithArrayAndReturn(rhport, 0x80, (uint8_t*)&desc_device, sizeof(tusb_desc_device_t), sizeof(tusb_desc_device_t), true); | ||||
|  | ||||
|   tud_task(); | ||||
| } | ||||
|  | ||||
| void test_usbd_get_device_descriptor_null(void) | ||||
| { | ||||
|   ptr_desc_device = NULL; | ||||
|  | ||||
|   dcd_event_setup_received(rhport, (uint8_t*) &req_get_desc_device, false); | ||||
|  | ||||
|   dcd_edpt_stall_Expect(rhport, 0); | ||||
|   dcd_edpt_stall_Expect(rhport, 0x80); | ||||
|  | ||||
|   tud_task(); | ||||
| } | ||||
| @@ -73,12 +73,11 @@ | ||||
| #define CFG_TUD_ENDOINT0_SIZE    64 | ||||
|  | ||||
| //------------- CLASS -------------// | ||||
| #define CFG_TUD_CDC              1 | ||||
| #define CFG_TUD_MSC              1 | ||||
| #define CFG_TUD_HID              1 | ||||
|  | ||||
| #define CFG_TUD_MIDI             1 | ||||
| #define CFG_TUD_VENDOR           1 | ||||
| #define CFG_TUD_CDC              0 | ||||
| #define CFG_TUD_MSC              0 | ||||
| #define CFG_TUD_HID              0 | ||||
| #define CFG_TUD_MIDI             0 | ||||
| #define CFG_TUD_VENDOR           0 | ||||
|  | ||||
| //------------- CDC -------------// | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 hathach
					hathach