change to dynamic descriptor for serial only mode
This commit is contained in:
		
							
								
								
									
										254
									
								
								src/main.c
									
									
									
									
									
								
							
							
						
						
									
										254
									
								
								src/main.c
									
									
									
									
									
								
							| @@ -66,7 +66,7 @@ | ||||
| #include "nrf_usbd.h" | ||||
| #include "tusb.h" | ||||
|  | ||||
| void usb_init(void); | ||||
| void usb_init(bool cdc_only); | ||||
| void usb_teardown(void); | ||||
|  | ||||
| #else | ||||
| @@ -96,7 +96,7 @@ void usb_teardown(void); | ||||
| #define DFU_MAGIC_OTA_APPJUM            BOOTLOADER_DFU_START             // 0xB1 | ||||
| #define DFU_MAGIC_OTA_RESET             0xA8 | ||||
| #define DFU_MAGIC_SERIAL_ONLY_RESET     0x4e | ||||
| #define DFU_MAGIC_UF2_SERIAL_RESET      0x57 | ||||
| #define DFU_MAGIC_UF2_RESET             0x57 | ||||
|  | ||||
| #define BOOTLOADER_VERSION_REGISTER     NRF_TIMER2->CC[0] | ||||
| #define DFU_SERIAL_STARTUP_INTERVAL     1000 | ||||
| @@ -124,6 +124,7 @@ STATIC_ASSERT( APPDATA_ADDR_START == 0x6D000); | ||||
|  | ||||
|  | ||||
| void adafruit_factory_reset(void); | ||||
| static uint32_t softdev_init(bool init_softdevice); | ||||
|  | ||||
| // true if ble, false if serial | ||||
| bool _ota_dfu = false; | ||||
| @@ -140,6 +141,131 @@ void softdev_mbr_init(void) | ||||
|   sd_mbr_command(&com); | ||||
| } | ||||
|  | ||||
| int main(void) | ||||
| { | ||||
|   // SD is already Initialized in case of BOOTLOADER_DFU_OTA_MAGIC | ||||
|   bool sd_inited = (NRF_POWER->GPREGRET == DFU_MAGIC_OTA_APPJUM); | ||||
|  | ||||
|   // Start Bootloader in BLE OTA mode | ||||
|   _ota_dfu = (NRF_POWER->GPREGRET == DFU_MAGIC_OTA_APPJUM) || (NRF_POWER->GPREGRET == DFU_MAGIC_OTA_RESET); | ||||
|  | ||||
|   // Serial only mode | ||||
|   bool serial_only_dfu = (NRF_POWER->GPREGRET == DFU_MAGIC_SERIAL_ONLY_RESET); | ||||
|  | ||||
|   // start either serial, uf2 or ble | ||||
|   bool dfu_start = _ota_dfu || serial_only_dfu || (NRF_POWER->GPREGRET == DFU_MAGIC_UF2_RESET); | ||||
|  | ||||
|   // Clear GPREGRET if it is our values | ||||
|   if (dfu_start) NRF_POWER->GPREGRET = 0; | ||||
|  | ||||
|   // Save bootloader version to pre-defined register, retrieved by application | ||||
|   BOOTLOADER_VERSION_REGISTER = (MK_BOOTLOADER_VERSION); | ||||
|  | ||||
|   // This check ensures that the defined fields in the bootloader corresponds with actual setting in the chip. | ||||
|   APP_ERROR_CHECK_BOOL(*((uint32_t *)NRF_UICR_BOOT_START_ADDRESS) == BOOTLOADER_REGION_START); | ||||
|  | ||||
|   board_init(); | ||||
|   bootloader_init(); | ||||
|  | ||||
|   // When updating SoftDevice, bootloader will reset before swapping SD | ||||
|   if (bootloader_dfu_sd_in_progress()) | ||||
|   { | ||||
|     APP_ERROR_CHECK( bootloader_dfu_sd_update_continue() ); | ||||
|     APP_ERROR_CHECK( bootloader_dfu_sd_update_finalize() ); | ||||
|   } | ||||
|  | ||||
|   /*------------- Determine DFU mode (Serial, OTA, FRESET or normal) -------------*/ | ||||
|   // DFU button pressed | ||||
|   dfu_start  = dfu_start || button_pressed(BUTTON_DFU); | ||||
|  | ||||
|   // DFU + FRESET are pressed --> OTA | ||||
|   _ota_dfu = _ota_dfu  || ( button_pressed(BUTTON_DFU) && button_pressed(BUTTON_FRESET) ) ; | ||||
|  | ||||
|   if ( dfu_start || !bootloader_app_is_valid(DFU_BANK_0_REGION_START) ) | ||||
|   { | ||||
|     if ( _ota_dfu ) | ||||
|     { | ||||
|       // Enable BLE if in OTA | ||||
|       led_pwm_init(NRF_PWM1, LED_BLUE); | ||||
|  | ||||
|       softdev_init(!sd_inited); | ||||
|       sd_inited = true; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|       // otherwise USB for Serial & UF2 | ||||
|       usb_init(serial_only_dfu); | ||||
|     } | ||||
|  | ||||
|     // Initiate an update of the firmware. | ||||
|     APP_ERROR_CHECK( bootloader_dfu_start(_ota_dfu, 0) ); | ||||
|  | ||||
|     if ( _ota_dfu ) | ||||
|     { | ||||
|       led_pwm_teardown(NRF_PWM1); | ||||
|       led_off(LED_BLUE); | ||||
|  | ||||
|       sd_softdevice_disable(); | ||||
|     }else | ||||
|     { | ||||
|       usb_teardown(); | ||||
|     } | ||||
|   } | ||||
| #ifdef NRF52832_XXAA | ||||
|   else | ||||
|   { | ||||
|     /* Adafruit Modification | ||||
|      * Even DFU is not active, we still force an 1000 ms dfu serial mode when startup | ||||
|      * to support auto programming from Arduino IDE */ | ||||
|     bootloader_dfu_start(false, DFU_SERIAL_STARTUP_INTERVAL); | ||||
|   } | ||||
| #endif | ||||
|  | ||||
|   // Adafruit Factory reset | ||||
|   if ( !button_pressed(BUTTON_DFU) && button_pressed(BUTTON_FRESET) ) | ||||
|   { | ||||
|     adafruit_factory_reset(); | ||||
|   } | ||||
|  | ||||
|   // Reset Board | ||||
|   board_teardown(); | ||||
|  | ||||
|   // Jump to application if valid | ||||
|   if (bootloader_app_is_valid(DFU_BANK_0_REGION_START) && !bootloader_dfu_sd_in_progress()) | ||||
|   { | ||||
|     // MBR must be init before start application | ||||
|     if ( !sd_inited ) softdev_mbr_init(); | ||||
|  | ||||
|     // Select a bank region to use as application region. | ||||
|     // @note: Only applications running from DFU_BANK_0_REGION_START is supported. | ||||
|     bootloader_app_start(DFU_BANK_0_REGION_START); | ||||
|   } | ||||
|  | ||||
|   NVIC_SystemReset(); | ||||
| } | ||||
|  | ||||
|  | ||||
| // Perform factory reset to erase Application + Data | ||||
| void adafruit_factory_reset(void) | ||||
| { | ||||
|   // Blink fast RED and turn on BLUE when erasing | ||||
|   led_blink_fast(true); | ||||
|   led_on(LED_BLUE); | ||||
|  | ||||
|   // clear all App Data if any | ||||
|   if ( DFU_APP_DATA_RESERVED ) | ||||
|   { | ||||
|     nrf_nvmc_page_erase(APPDATA_ADDR_START); | ||||
|   } | ||||
|  | ||||
|   // Only need to erase the 1st page of Application code to make it invalid | ||||
|   nrf_nvmc_page_erase(DFU_BANK_0_REGION_START); | ||||
|  | ||||
|   // back to normal | ||||
|   led_blink_fast(false); | ||||
|   led_off(LED_BLUE); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Initializes the SoftDevice and the BLE event interrupt. | ||||
|  * @param[in] init_softdevice  true if SoftDevice should be initialized. The SoftDevice must only | ||||
| @@ -218,130 +344,6 @@ static uint32_t softdev_init(bool init_softdevice) | ||||
|   return NRF_SUCCESS; | ||||
| } | ||||
|  | ||||
| int main(void) | ||||
| { | ||||
|   // SD is already Initialized in case of BOOTLOADER_DFU_OTA_MAGIC | ||||
|   bool sd_inited = (NRF_POWER->GPREGRET == DFU_MAGIC_OTA_APPJUM); | ||||
|  | ||||
|   // Start Bootloader in BLE OTA mode | ||||
|   _ota_dfu = (NRF_POWER->GPREGRET == DFU_MAGIC_OTA_APPJUM) || | ||||
|              (NRF_POWER->GPREGRET == DFU_MAGIC_OTA_RESET); | ||||
|  | ||||
|   // | ||||
|  | ||||
|   // start bootloader either serial or ble | ||||
|   bool dfu_start = _ota_dfu || (NRF_POWER->GPREGRET == DFU_MAGIC_SERIAL_ONLY_RESET); | ||||
|  | ||||
|   // Clear GPREGRET if it is our values | ||||
|   if (dfu_start) NRF_POWER->GPREGRET = 0; | ||||
|  | ||||
|   // Save bootloader version to pre-defined register, retrieved by application | ||||
|   BOOTLOADER_VERSION_REGISTER = (MK_BOOTLOADER_VERSION); | ||||
|  | ||||
|   // This check ensures that the defined fields in the bootloader corresponds with actual setting in the chip. | ||||
|   APP_ERROR_CHECK_BOOL(*((uint32_t *)NRF_UICR_BOOT_START_ADDRESS) == BOOTLOADER_REGION_START); | ||||
|  | ||||
|   board_init(); | ||||
|   bootloader_init(); | ||||
|  | ||||
|   // When updating SoftDevice, bootloader will reset before swapping SD | ||||
|   if (bootloader_dfu_sd_in_progress()) | ||||
|   { | ||||
|     APP_ERROR_CHECK( bootloader_dfu_sd_update_continue() ); | ||||
|     APP_ERROR_CHECK( bootloader_dfu_sd_update_finalize() ); | ||||
|   } | ||||
|  | ||||
|   /*------------- Determine DFU mode (Serial, OTA, FRESET or normal) -------------*/ | ||||
|   // DFU button pressed | ||||
|   dfu_start  = dfu_start || button_pressed(BUTTON_DFU); | ||||
|  | ||||
|   // DFU + FRESET are pressed --> OTA | ||||
|   _ota_dfu = _ota_dfu  || ( button_pressed(BUTTON_DFU) && button_pressed(BUTTON_FRESET) ) ; | ||||
|  | ||||
|   if ( dfu_start || !bootloader_app_is_valid(DFU_BANK_0_REGION_START) ) | ||||
|   { | ||||
|     if ( _ota_dfu ) | ||||
|     { | ||||
|       // Enable BLE if in OTA | ||||
|       led_pwm_init(NRF_PWM1, LED_BLUE); | ||||
|  | ||||
|       softdev_init(!sd_inited); | ||||
|       sd_inited = true; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|       // otherwise USB for Serial & UF2 | ||||
|       usb_init(); | ||||
|     } | ||||
|  | ||||
|     // Initiate an update of the firmware. | ||||
|     APP_ERROR_CHECK( bootloader_dfu_start(_ota_dfu, 0) ); | ||||
|  | ||||
|     if ( _ota_dfu ) | ||||
|     { | ||||
|       led_pwm_teardown(NRF_PWM1); | ||||
|       led_off(LED_BLUE); | ||||
|  | ||||
|       sd_softdevice_disable(); | ||||
|     }else | ||||
|     { | ||||
|       usb_teardown(); | ||||
|     } | ||||
|   } | ||||
| #ifdef NRF52832_XXAA | ||||
|   else | ||||
|   { | ||||
|     /* Adafruit Modification | ||||
|      * Even DFU is not active, we still force an 1000 ms dfu serial mode when startup | ||||
|      * to support auto programming from Arduino IDE */ | ||||
|     bootloader_dfu_start(false, DFU_SERIAL_STARTUP_INTERVAL); | ||||
|   } | ||||
| #endif | ||||
|  | ||||
|   // Adafruit Factory reset | ||||
|   if ( !button_pressed(BUTTON_DFU) && button_pressed(BUTTON_FRESET) ) | ||||
|   { | ||||
|     adafruit_factory_reset(); | ||||
|   } | ||||
|  | ||||
|   // Reset Board | ||||
|   board_teardown(); | ||||
|  | ||||
|   // Jump to application if valid | ||||
|   if (bootloader_app_is_valid(DFU_BANK_0_REGION_START) && !bootloader_dfu_sd_in_progress()) | ||||
|   { | ||||
|     // MBR must be init before start application | ||||
|     if ( !sd_inited ) softdev_mbr_init(); | ||||
|  | ||||
|     // Select a bank region to use as application region. | ||||
|     // @note: Only applications running from DFU_BANK_0_REGION_START is supported. | ||||
|     bootloader_app_start(DFU_BANK_0_REGION_START); | ||||
|   } | ||||
|  | ||||
|   NVIC_SystemReset(); | ||||
| } | ||||
|  | ||||
|  | ||||
| // Perform factory reset to erase Application + Data | ||||
| void adafruit_factory_reset(void) | ||||
| { | ||||
|   // Blink fast RED and turn on BLUE when erasing | ||||
|   led_blink_fast(true); | ||||
|   led_on(LED_BLUE); | ||||
|  | ||||
|   // clear all App Data if any | ||||
|   if ( DFU_APP_DATA_RESERVED ) | ||||
|   { | ||||
|     nrf_nvmc_page_erase(APPDATA_ADDR_START); | ||||
|   } | ||||
|  | ||||
|   // Only need to erase the 1st page of Application code to make it invalid | ||||
|   nrf_nvmc_page_erase(DFU_BANK_0_REGION_START); | ||||
|  | ||||
|   // back to normal | ||||
|   led_blink_fast(false); | ||||
|   led_off(LED_BLUE); | ||||
| } | ||||
|  | ||||
| //--------------------------------------------------------------------+ | ||||
| // Error Handler | ||||
|   | ||||
| @@ -68,10 +68,7 @@ | ||||
| //--------------------------------------------------------------------+ | ||||
|  | ||||
| /*------------- Core -------------*/ | ||||
| #define CFG_TUD_DESC_AUTO           1 | ||||
| #define CFG_TUD_DESC_VID            0x239A | ||||
| #define CFG_TUD_DESC_PID            0x0029 | ||||
|  | ||||
| #define CFG_TUD_DESC_AUTO           0 | ||||
| #define CFG_TUD_ENDOINT0_SIZE       64 | ||||
|  | ||||
| //------------- Class enabled -------------// | ||||
|   | ||||
| @@ -1,84 +0,0 @@ | ||||
| /**************************************************************************/ | ||||
| /*! | ||||
|     @file     tusb_descriptors.c | ||||
|     @author   hathach (tinyusb.org) | ||||
|  | ||||
|     @section LICENSE | ||||
|  | ||||
|     Software License Agreement (BSD License) | ||||
|  | ||||
|     Copyright (c) 2013, hathach (tinyusb.org) | ||||
|     All rights reserved. | ||||
|  | ||||
|     Redistribution and use in source and binary forms, with or without | ||||
|     modification, are permitted provided that the following conditions are met: | ||||
|     1. Redistributions of source code must retain the above copyright | ||||
|     notice, this list of conditions and the following disclaimer. | ||||
|     2. Redistributions in binary form must reproduce the above copyright | ||||
|     notice, this list of conditions and the following disclaimer in the | ||||
|     documentation and/or other materials provided with the distribution. | ||||
|     3. Neither the name of the copyright holders nor the | ||||
|     names of its contributors may be used to endorse or promote products | ||||
|     derived from this software without specific prior written permission. | ||||
|  | ||||
|     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY | ||||
|     EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||||
|     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||||
|     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY | ||||
|     DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||||
|     INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||||
|     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION HOWEVER CAUSED AND | ||||
|     ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||
|     INCLUDING NEGLIGENCE OR OTHERWISE ARISING IN ANY WAY OUT OF THE USE OF THIS | ||||
|     SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
|  | ||||
|     This file is part of the tinyusb stack. | ||||
| */ | ||||
| /**************************************************************************/ | ||||
|  | ||||
| #include "tusb.h" | ||||
|  | ||||
| //--------------------------------------------------------------------+ | ||||
| // STRING DESCRIPTORS | ||||
| //--------------------------------------------------------------------+ | ||||
|  | ||||
| // array of pointer to string descriptors | ||||
| uint16_t const * const string_desc_arr [] = | ||||
| { | ||||
|     // 0: is supported language = English | ||||
|     TUD_DESC_STRCONV(0x0409), | ||||
|  | ||||
|     // 1: Manufacturer | ||||
|     TUD_DESC_STRCONV('A','d','a','f','r','u','i','t',' ','I','n','d','u','s','t','r','i','e','s'), | ||||
|  | ||||
|     // 2: Product | ||||
|     TUD_DESC_STRCONV('B','l','u','e','f','r','u','i','t',' ','n','R','F','5','2','8','4','0'), | ||||
|  | ||||
|     // 3: Serials TODO use chip ID | ||||
|     TUD_DESC_STRCONV('1', '2', '3', '4'), | ||||
|  | ||||
|     // 4: CDC Interface | ||||
|     TUD_DESC_STRCONV('B','l','u','e','f','r','u','i','t',' ','S','e','r','i','a','l'), | ||||
|  | ||||
|     // 5: MSC Interface | ||||
|     TUD_DESC_STRCONV('B','l','u','e','f','r','u','i','t',' ','S','t','o','r','a','g','e'), | ||||
|  | ||||
|     // 6: Custom Interface | ||||
|     TUD_DESC_STRCONV('B','l','u','e','f','r','u','i','t',' ','C','u','s','t','o','m') | ||||
| }; | ||||
|  | ||||
|  | ||||
| // tud_desc_set is required by tinyusb stack | ||||
| // since CFG_TUD_DESC_AUTO is enabled, we only need to set string_arr  | ||||
| tud_desc_set_t tud_desc_set = | ||||
| { | ||||
|     .device     = NULL, | ||||
|     .config     = NULL, | ||||
|     .string_arr = (uint8_t const **) string_desc_arr, | ||||
|     .hid_report = | ||||
|     { | ||||
|         .generic       = NULL, | ||||
|         .boot_keyboard = NULL, | ||||
|         .boot_mouse    = NULL | ||||
|     } | ||||
| }; | ||||
| @@ -55,7 +55,7 @@ extern void tusb_hal_nrf_power_event(uint32_t event); | ||||
|  | ||||
|  | ||||
| //------------- IMPLEMENTATION -------------// | ||||
| void usb_init(void) | ||||
| void usb_init(bool cdc_only) | ||||
| { | ||||
|   // USB power may already be ready at this time -> no event generated | ||||
|   // We need to invoke the handler based on the status initially | ||||
|   | ||||
							
								
								
									
										312
									
								
								src/usb/usb_desc.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										312
									
								
								src/usb/usb_desc.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,312 @@ | ||||
| /**************************************************************************/ | ||||
| /*! | ||||
|     @file     usb_desc.c | ||||
|     @author   hathach (tinyusb.org) | ||||
|  | ||||
|     @section LICENSE | ||||
|  | ||||
|     Software License Agreement (BSD License) | ||||
|  | ||||
|     Copyright (c) 2013, hathach (tinyusb.org) | ||||
|     Copyright (c) 2018, Adafruit Industries (adafruit.com) | ||||
|  | ||||
|     All rights reserved. | ||||
|  | ||||
|     Redistribution and use in source and binary forms, with or without | ||||
|     modification, are permitted provided that the following conditions are met: | ||||
|     1. Redistributions of source code must retain the above copyright | ||||
|     notice, this list of conditions and the following disclaimer. | ||||
|     2. Redistributions in binary form must reproduce the above copyright | ||||
|     notice, this list of conditions and the following disclaimer in the | ||||
|     documentation and/or other materials provided with the distribution. | ||||
|     3. Neither the name of the copyright holders nor the | ||||
|     names of its contributors may be used to endorse or promote products | ||||
|     derived from this software without specific prior written permission. | ||||
|  | ||||
|     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY | ||||
|     EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||||
|     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||||
|     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY | ||||
|     DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||||
|     INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||||
|     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION HOWEVER CAUSED AND | ||||
|     ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||
|     INCLUDING NEGLIGENCE OR OTHERWISE ARISING IN ANY WAY OUT OF THE USE OF THIS | ||||
|     SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
|  | ||||
|     This file is part of the tinyusb stack. | ||||
| */ | ||||
| /**************************************************************************/ | ||||
|  | ||||
| #include "usb_desc.h" | ||||
|  | ||||
|  | ||||
| /*------------- Interface Numbering -------------*/ | ||||
| enum { | ||||
|     ITF_NUM_CDC = 0  , | ||||
|     ITF_NUM_CDC_DATA , | ||||
|     ITF_NUM_MSC      , | ||||
|     ITF_NUM_TOTAL | ||||
| }; | ||||
|  | ||||
| enum { | ||||
|     ITF_STR_LANGUAGE = 0 , | ||||
|     ITF_STR_MANUFACTURER , | ||||
|     ITF_STR_PRODUCT      , | ||||
|     ITF_STR_SERIAL       , | ||||
|     ITF_STR_CDC          , | ||||
|     ITF_STR_MSC | ||||
| }; | ||||
|  | ||||
| /*------------- Endpoint Numbering & Size -------------*/ | ||||
| #define _EP_IN(x)               (0x80 | (x)) | ||||
| #define _EP_OUT(x)              (x) | ||||
|  | ||||
| // CDC | ||||
| #define EP_CDC_NOTIF            _EP_IN ( ITF_NUM_CDC+1 ) | ||||
| #define EP_CDC_NOTIF_SIZE       8 | ||||
|  | ||||
| #define EP_CDC_OUT              _EP_OUT( ITF_NUM_CDC+2 ) | ||||
| #define EP_CDC_IN               _EP_IN ( ITF_NUM_CDC+2 ) | ||||
|  | ||||
| // Mass Storage | ||||
| #define EP_MSC_OUT              _EP_OUT( ITF_NUM_MSC+1 ) | ||||
| #define EP_MSC_IN               _EP_IN ( ITF_NUM_MSC+1 ) | ||||
|  | ||||
| //--------------------------------------------------------------------+ | ||||
| // STRING DESCRIPTORS | ||||
| //--------------------------------------------------------------------+ | ||||
|  | ||||
| // array of pointer to string descriptors | ||||
| uint16_t const * const string_desc_arr [] = | ||||
| { | ||||
|     // 0: is supported language = English | ||||
|     TUD_DESC_STRCONV(0x0409), | ||||
|  | ||||
|     // 1: Manufacturer | ||||
|     TUD_DESC_STRCONV('A','d','a','f','r','u','i','t',' ','I','n','d','u','s','t','r','i','e','s'), | ||||
|  | ||||
|     // 2: Product | ||||
|     TUD_DESC_STRCONV('B','l','u','e','f','r','u','i','t',' ','n','R','F','5','2','8','4','0', ' ', 'D','F','U'), | ||||
|  | ||||
|     // 3: Serials TODO use chip ID | ||||
|     TUD_DESC_STRCONV('1', '2', '3', '4'), | ||||
|  | ||||
|     // 4: CDC Interface | ||||
|     TUD_DESC_STRCONV('B','l','u','e','f','r','u','i','t',' ','S','e','r','i','a','l'), | ||||
|  | ||||
|     // 5: MSC Interface | ||||
|     TUD_DESC_STRCONV('B','l','u','e','f','r','u','i','t',' ','U','F','2'), | ||||
| }; | ||||
|  | ||||
| //--------------------------------------------------------------------+ | ||||
| // Device Descriptor | ||||
| //--------------------------------------------------------------------+ | ||||
| tusb_desc_device_t usb_desc_dev = | ||||
| { | ||||
|     .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_ENDOINT0_SIZE, | ||||
|  | ||||
|     .idVendor           = USB_DESC_VID, | ||||
|     .idProduct          = USB_DESC_UF2_PID, | ||||
|     .bcdDevice          = 0x0100, | ||||
|  | ||||
|     .iManufacturer      = 0x01, | ||||
|     .iProduct           = 0x02, | ||||
|     .iSerialNumber      = 0x03, | ||||
|  | ||||
|     .bNumConfigurations = 0x01 | ||||
| }; | ||||
|  | ||||
| //--------------------------------------------------------------------+ | ||||
| // Configuration Descriptor | ||||
| //--------------------------------------------------------------------+ | ||||
| usb_desc_cfg_t usb_desc_cfg = | ||||
| { | ||||
|     .config = | ||||
|     { | ||||
|         .bLength             = sizeof(tusb_desc_configuration_t), | ||||
|         .bDescriptorType     = TUSB_DESC_CONFIGURATION, | ||||
|         .wTotalLength        = sizeof(usb_desc_cfg_t), | ||||
|         .bNumInterfaces      = ITF_NUM_TOTAL, | ||||
|         .bConfigurationValue = 1, | ||||
|         .iConfiguration      = 0x00, | ||||
|         .bmAttributes        = TUSB_DESC_CONFIG_ATT_BUS_POWER, | ||||
|         .bMaxPower           = TUSB_DESC_CONFIG_POWER_MA(100) | ||||
|     }, | ||||
|  | ||||
|     // IAD points to CDC Interfaces | ||||
|     .cdc = | ||||
|     { | ||||
|       .iad = | ||||
|       { | ||||
|           .bLength           = sizeof(tusb_desc_interface_assoc_t), | ||||
|           .bDescriptorType   = TUSB_DESC_INTERFACE_ASSOCIATION, | ||||
|  | ||||
|           .bFirstInterface   = ITF_NUM_CDC, | ||||
|           .bInterfaceCount   = 2, | ||||
|  | ||||
|           .bFunctionClass    = TUSB_CLASS_CDC, | ||||
|           .bFunctionSubClass = CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL, | ||||
|           .bFunctionProtocol = CDC_COMM_PROTOCOL_ATCOMMAND, | ||||
|           .iFunction         = 0 | ||||
|       }, | ||||
|  | ||||
|       //------------- CDC Communication Interface -------------// | ||||
|       .comm_itf = | ||||
|       { | ||||
|           .bLength            = sizeof(tusb_desc_interface_t), | ||||
|           .bDescriptorType    = TUSB_DESC_INTERFACE, | ||||
|           .bInterfaceNumber   = ITF_NUM_CDC, | ||||
|           .bAlternateSetting  = 0, | ||||
|           .bNumEndpoints      = 1, | ||||
|           .bInterfaceClass    = TUSB_CLASS_CDC, | ||||
|           .bInterfaceSubClass = CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL, | ||||
|           .bInterfaceProtocol = CDC_COMM_PROTOCOL_ATCOMMAND, | ||||
|           .iInterface         = ITF_STR_CDC | ||||
|       }, | ||||
|  | ||||
|       .header = | ||||
|       { | ||||
|           .bLength            = sizeof(cdc_desc_func_header_t), | ||||
|           .bDescriptorType    = TUSB_DESC_CLASS_SPECIFIC, | ||||
|           .bDescriptorSubType = CDC_FUNC_DESC_HEADER, | ||||
|           .bcdCDC             = 0x0120 | ||||
|       }, | ||||
|  | ||||
|       .call = | ||||
|       { | ||||
|           .bLength            = sizeof(cdc_desc_func_call_management_t), | ||||
|           .bDescriptorType    = TUSB_DESC_CLASS_SPECIFIC, | ||||
|           .bDescriptorSubType = CDC_FUNC_DESC_CALL_MANAGEMENT, | ||||
|           .bmCapabilities     = { 0 }, | ||||
|           .bDataInterface     = ITF_NUM_CDC+1, | ||||
|       }, | ||||
|  | ||||
|       .acm = | ||||
|       { | ||||
|           .bLength            = sizeof(cdc_desc_func_acm_t), | ||||
|           .bDescriptorType    = TUSB_DESC_CLASS_SPECIFIC, | ||||
|           .bDescriptorSubType = CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT, | ||||
|           .bmCapabilities     = { // 0x02 | ||||
|               .support_line_request = 1, | ||||
|           } | ||||
|       }, | ||||
|  | ||||
|       .union_func = | ||||
|       { | ||||
|           .bLength                  = sizeof(cdc_desc_func_union_t), // plus number of | ||||
|           .bDescriptorType          = TUSB_DESC_CLASS_SPECIFIC, | ||||
|           .bDescriptorSubType       = CDC_FUNC_DESC_UNION, | ||||
|           .bControlInterface        = ITF_NUM_CDC, | ||||
|           .bSubordinateInterface    = ITF_NUM_CDC+1, | ||||
|       }, | ||||
|  | ||||
|       .ep_notif = | ||||
|       { | ||||
|           .bLength          = sizeof(tusb_desc_endpoint_t), | ||||
|           .bDescriptorType  = TUSB_DESC_ENDPOINT, | ||||
|           .bEndpointAddress = EP_CDC_NOTIF, | ||||
|           .bmAttributes     = { .xfer = TUSB_XFER_INTERRUPT }, | ||||
|           .wMaxPacketSize   = { .size = EP_CDC_NOTIF_SIZE }, | ||||
|           .bInterval        = 0x10 | ||||
|       }, | ||||
|  | ||||
|       //------------- CDC Data Interface -------------// | ||||
|       .data_itf = | ||||
|       { | ||||
|           .bLength            = sizeof(tusb_desc_interface_t), | ||||
|           .bDescriptorType    = TUSB_DESC_INTERFACE, | ||||
|           .bInterfaceNumber   = ITF_NUM_CDC+1, | ||||
|           .bAlternateSetting  = 0x00, | ||||
|           .bNumEndpoints      = 2, | ||||
|           .bInterfaceClass    = TUSB_CLASS_CDC_DATA, | ||||
|           .bInterfaceSubClass = 0, | ||||
|           .bInterfaceProtocol = 0, | ||||
|           .iInterface         = 0x00 | ||||
|       }, | ||||
|  | ||||
|       .ep_out = | ||||
|       { | ||||
|           .bLength          = sizeof(tusb_desc_endpoint_t), | ||||
|           .bDescriptorType  = TUSB_DESC_ENDPOINT, | ||||
|           .bEndpointAddress = EP_CDC_OUT, | ||||
|           .bmAttributes     = { .xfer = TUSB_XFER_BULK }, | ||||
|           .wMaxPacketSize   = { .size = CFG_TUD_CDC_EPSIZE }, | ||||
|           .bInterval        = 0 | ||||
|       }, | ||||
|  | ||||
|       .ep_in = | ||||
|       { | ||||
|           .bLength          = sizeof(tusb_desc_endpoint_t), | ||||
|           .bDescriptorType  = TUSB_DESC_ENDPOINT, | ||||
|           .bEndpointAddress = EP_CDC_IN, | ||||
|           .bmAttributes     = { .xfer = TUSB_XFER_BULK }, | ||||
|           .wMaxPacketSize   = { .size = CFG_TUD_CDC_EPSIZE }, | ||||
|           .bInterval        = 0 | ||||
|       }, | ||||
|     }, | ||||
|  | ||||
|     //------------- Mass Storage-------------// | ||||
|     .msc = | ||||
|     { | ||||
|       .itf = | ||||
|       { | ||||
|           .bLength            = sizeof(tusb_desc_interface_t), | ||||
|           .bDescriptorType    = TUSB_DESC_INTERFACE, | ||||
|           .bInterfaceNumber   = ITF_NUM_MSC, | ||||
|           .bAlternateSetting  = 0x00, | ||||
|           .bNumEndpoints      = 2, | ||||
|           .bInterfaceClass    = TUSB_CLASS_MSC, | ||||
|           .bInterfaceSubClass = MSC_SUBCLASS_SCSI, | ||||
|           .bInterfaceProtocol = MSC_PROTOCOL_BOT, | ||||
|           .iInterface         = ITF_STR_MSC | ||||
|       }, | ||||
|  | ||||
|       .ep_out = | ||||
|       { | ||||
|           .bLength          = sizeof(tusb_desc_endpoint_t), | ||||
|           .bDescriptorType  = TUSB_DESC_ENDPOINT, | ||||
|           .bEndpointAddress = EP_MSC_OUT, | ||||
|           .bmAttributes     = { .xfer = TUSB_XFER_BULK }, | ||||
|           .wMaxPacketSize   = { .size = CFG_TUD_MSC_EPSIZE}, | ||||
|           .bInterval        = 1 | ||||
|       }, | ||||
|  | ||||
|       .ep_in = | ||||
|       { | ||||
|           .bLength          = sizeof(tusb_desc_endpoint_t), | ||||
|           .bDescriptorType  = TUSB_DESC_ENDPOINT, | ||||
|           .bEndpointAddress = EP_MSC_IN, | ||||
|           .bmAttributes     = { .xfer = TUSB_XFER_BULK }, | ||||
|           .wMaxPacketSize   = { .size = CFG_TUD_MSC_EPSIZE}, | ||||
|           .bInterval        = 1 | ||||
|       } | ||||
|     } | ||||
| }; | ||||
|  | ||||
|  | ||||
| // tud_desc_set is required by tinyusb stack | ||||
| // since CFG_TUD_DESC_AUTO is enabled, we only need to set string_arr  | ||||
| tud_desc_set_t tud_desc_set = | ||||
| { | ||||
|     .device       = &usb_desc_dev, | ||||
|     .config       = &usb_desc_cfg, | ||||
|     .string_arr   = (uint8_t const **) string_desc_arr, | ||||
|     .string_count = sizeof(string_desc_arr)/sizeof(string_desc_arr[0]), | ||||
|  | ||||
|     .hid_report = | ||||
|     { | ||||
|         .generic       = NULL, | ||||
|         .boot_keyboard = NULL, | ||||
|         .boot_mouse    = NULL | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										95
									
								
								src/usb/usb_desc.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								src/usb/usb_desc.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,95 @@ | ||||
| /**************************************************************************/ | ||||
| /*! | ||||
|     @file     usb_desc.h | ||||
|     @author   hathach (tinyusb.org) | ||||
|  | ||||
|     @section LICENSE | ||||
|  | ||||
|     Software License Agreement (BSD License) | ||||
|  | ||||
|     Copyright (c) 2013, hathach (tinyusb.org) | ||||
|     Copyright (c) 2018, Adafruit Industries (adafruit.com) | ||||
|  | ||||
|     All rights reserved. | ||||
|  | ||||
|     Redistribution and use in source and binary forms, with or without | ||||
|     modification, are permitted provided that the following conditions are met: | ||||
|     1. Redistributions of source code must retain the above copyright | ||||
|     notice, this list of conditions and the following disclaimer. | ||||
|     2. Redistributions in binary form must reproduce the above copyright | ||||
|     notice, this list of conditions and the following disclaimer in the | ||||
|     documentation and/or other materials provided with the distribution. | ||||
|     3. Neither the name of the copyright holders nor the | ||||
|     names of its contributors may be used to endorse or promote products | ||||
|     derived from this software without specific prior written permission. | ||||
|  | ||||
|     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY | ||||
|     EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||||
|     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||||
|     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY | ||||
|     DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||||
|     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||||
|     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||||
|     ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||
|     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||||
|     SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
| */ | ||||
| /**************************************************************************/ | ||||
|  | ||||
| #ifndef USB_DESC_H_ | ||||
| #define USB_DESC_H_ | ||||
|  | ||||
| #include "tusb.h" | ||||
|  | ||||
| #ifdef __cplusplus | ||||
|  extern "C" { | ||||
| #endif | ||||
|  | ||||
| #define USB_DESC_VID                0x239A | ||||
|  | ||||
| #define USB_DESC_UF2_PID            0x0029 | ||||
| #define USB_DESC_SERIAL_ONLY_PID    0x002A | ||||
|  | ||||
|  | ||||
| /*------------- Configuration Descriptor -------------*/ | ||||
| typedef struct ATTR_PACKED | ||||
| { | ||||
|   tusb_desc_configuration_t           config; | ||||
|  | ||||
|   //------------- CDC -------------// | ||||
|   struct ATTR_PACKED | ||||
|   { | ||||
|     tusb_desc_interface_assoc_t       iad; | ||||
|  | ||||
|     //CDC Control Interface | ||||
|     tusb_desc_interface_t             comm_itf; | ||||
|     cdc_desc_func_header_t            header; | ||||
|     cdc_desc_func_call_management_t   call; | ||||
|     cdc_desc_func_acm_t               acm; | ||||
|     cdc_desc_func_union_t             union_func; | ||||
|     tusb_desc_endpoint_t              ep_notif; | ||||
|  | ||||
|     //CDC Data Interface | ||||
|     tusb_desc_interface_t             data_itf; | ||||
|     tusb_desc_endpoint_t              ep_out; | ||||
|     tusb_desc_endpoint_t              ep_in; | ||||
|   }cdc; | ||||
|  | ||||
|   //------------- Mass Storage -------------// | ||||
|   struct ATTR_PACKED | ||||
|   { | ||||
|     tusb_desc_interface_t             itf; | ||||
|     tusb_desc_endpoint_t              ep_out; | ||||
|     tusb_desc_endpoint_t              ep_in; | ||||
|   } msc; | ||||
| } usb_desc_cfg_t; | ||||
|  | ||||
|  | ||||
| extern tusb_desc_device_t usb_desc_dev; | ||||
| extern usb_desc_cfg_t     usb_desc_cfg; | ||||
|  | ||||
| #ifdef __cplusplus | ||||
|  } | ||||
| #endif | ||||
|  | ||||
| #endif /* USB_DESC_H_ */ | ||||
		Reference in New Issue
	
	Block a user