update repo to work with latest tinyusb and nrfx module
This commit is contained in:
		
							
								
								
									
										5
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								Makefile
									
									
									
									
									
								
							@@ -108,7 +108,7 @@ C_SOURCE_FILES += $(SRC_PATH)/dfu_init.c
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
# nrfx
 | 
					# nrfx
 | 
				
			||||||
C_SOURCE_FILES += $(NRFX_PATH)/drivers/src/nrfx_power.c
 | 
					C_SOURCE_FILES += $(NRFX_PATH)/drivers/src/nrfx_power.c
 | 
				
			||||||
C_SOURCE_FILES += $(NRFX_PATH)/hal/nrf_nvmc.c
 | 
					C_SOURCE_FILES += $(NRFX_PATH)/drivers/src/nrfx_nvmc.c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# SDK 11 files
 | 
					# SDK 11 files
 | 
				
			||||||
C_SOURCE_FILES += $(SDK11_PATH)/libraries/bootloader_dfu/bootloader.c
 | 
					C_SOURCE_FILES += $(SDK11_PATH)/libraries/bootloader_dfu/bootloader.c
 | 
				
			||||||
@@ -159,13 +159,11 @@ C_SOURCE_FILES += $(NRFX_PATH)/mdk/system_nrf52840.c
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
# Tinyusb stack
 | 
					# Tinyusb stack
 | 
				
			||||||
C_SOURCE_FILES += $(TUSB_PATH)/portable/nordic/nrf5x/dcd_nrf5x.c
 | 
					C_SOURCE_FILES += $(TUSB_PATH)/portable/nordic/nrf5x/dcd_nrf5x.c
 | 
				
			||||||
C_SOURCE_FILES += $(TUSB_PATH)/portable/nordic/nrf5x/hal_nrf5x.c
 | 
					 | 
				
			||||||
C_SOURCE_FILES += $(TUSB_PATH)/common/tusb_fifo.c
 | 
					C_SOURCE_FILES += $(TUSB_PATH)/common/tusb_fifo.c
 | 
				
			||||||
C_SOURCE_FILES += $(TUSB_PATH)/device/usbd.c
 | 
					C_SOURCE_FILES += $(TUSB_PATH)/device/usbd.c
 | 
				
			||||||
C_SOURCE_FILES += $(TUSB_PATH)/device/usbd_control.c
 | 
					C_SOURCE_FILES += $(TUSB_PATH)/device/usbd_control.c
 | 
				
			||||||
C_SOURCE_FILES += $(TUSB_PATH)/class/cdc/cdc_device.c
 | 
					C_SOURCE_FILES += $(TUSB_PATH)/class/cdc/cdc_device.c
 | 
				
			||||||
C_SOURCE_FILES += $(TUSB_PATH)/class/msc/msc_device.c
 | 
					C_SOURCE_FILES += $(TUSB_PATH)/class/msc/msc_device.c
 | 
				
			||||||
C_SOURCE_FILES += $(TUSB_PATH)/class/custom/custom_device.c
 | 
					 | 
				
			||||||
C_SOURCE_FILES += $(TUSB_PATH)/tusb.c
 | 
					C_SOURCE_FILES += $(TUSB_PATH)/tusb.c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
@@ -198,6 +196,7 @@ IPATH += $(NRFX_PATH)
 | 
				
			|||||||
IPATH += $(NRFX_PATH)/mdk
 | 
					IPATH += $(NRFX_PATH)/mdk
 | 
				
			||||||
IPATH += $(NRFX_PATH)/hal
 | 
					IPATH += $(NRFX_PATH)/hal
 | 
				
			||||||
IPATH += $(NRFX_PATH)/drivers/include
 | 
					IPATH += $(NRFX_PATH)/drivers/include
 | 
				
			||||||
 | 
					IPATH += $(NRFX_PATH)/drivers/src
 | 
				
			||||||
 | 
					
 | 
				
			||||||
IPATH += $(SDK11_PATH)/libraries/bootloader_dfu/hci_transport
 | 
					IPATH += $(SDK11_PATH)/libraries/bootloader_dfu/hci_transport
 | 
				
			||||||
IPATH += $(SDK11_PATH)/libraries/bootloader_dfu
 | 
					IPATH += $(SDK11_PATH)/libraries/bootloader_dfu
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -119,9 +119,9 @@ static void wait_for_events(void)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    // Feed all Watchdog just in case application enable it
 | 
					    // Feed all Watchdog just in case application enable it
 | 
				
			||||||
    // WDT cannot be disabled once started. It even last through soft reset (NVIC Reset)
 | 
					    // WDT cannot be disabled once started. It even last through soft reset (NVIC Reset)
 | 
				
			||||||
    if ( nrf_wdt_started() )
 | 
					    if ( nrf_wdt_started(NRF_WDT) )
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      for (uint8_t i=0; i<8; i++) nrf_wdt_reload_request_set(i);
 | 
					      for (uint8_t i=0; i<8; i++) nrf_wdt_reload_request_set(NRF_WDT, i);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Event received. Process it from the scheduler.
 | 
					    // Event received. Process it from the scheduler.
 | 
				
			||||||
@@ -194,8 +194,8 @@ static void bootloader_settings_save(bootloader_settings_t * p_settings)
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
  else
 | 
					  else
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    nrf_nvmc_page_erase(BOOTLOADER_SETTINGS_ADDRESS);
 | 
					    nrfx_nvmc_page_erase(BOOTLOADER_SETTINGS_ADDRESS);
 | 
				
			||||||
    nrf_nvmc_write_words(BOOTLOADER_SETTINGS_ADDRESS, (uint32_t *) p_settings, sizeof(bootloader_settings_t) / 4);
 | 
					    nrfx_nvmc_words_write(BOOTLOADER_SETTINGS_ADDRESS, (uint32_t *) p_settings, sizeof(bootloader_settings_t) / 4);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pstorage_callback_handler(&m_bootsettings_handle, PSTORAGE_STORE_OP_CODE, NRF_SUCCESS, (uint8_t *) p_settings, sizeof(bootloader_settings_t));
 | 
					    pstorage_callback_handler(&m_bootsettings_handle, PSTORAGE_STORE_OP_CODE, NRF_SUCCESS, (uint8_t *) p_settings, sizeof(bootloader_settings_t));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -151,7 +151,7 @@ static void dfu_prepare_func_app_erase(uint32_t image_size)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    for ( uint32_t i = 0; i < page_count; i++ )
 | 
					    for ( uint32_t i = 0; i < page_count; i++ )
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      nrf_nvmc_page_erase(DFU_BANK_0_REGION_START + i * CODE_PAGE_SIZE);
 | 
					      nrfx_nvmc_page_erase(DFU_BANK_0_REGION_START + i * CODE_PAGE_SIZE);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // invoke complete callback
 | 
					    // invoke complete callback
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -44,9 +44,9 @@ void flash_nrf5x_flush (bool need_erase)
 | 
				
			|||||||
    // - nRF52840 dfu serial/uf2 are USB-based which are DMA and should have no problems.
 | 
					    // - nRF52840 dfu serial/uf2 are USB-based which are DMA and should have no problems.
 | 
				
			||||||
    //
 | 
					    //
 | 
				
			||||||
    // Note: MSC uf2 does not erase page in advance like dfu serial
 | 
					    // Note: MSC uf2 does not erase page in advance like dfu serial
 | 
				
			||||||
    if ( need_erase ) nrf_nvmc_page_erase(_fl_addr);
 | 
					    if ( need_erase ) nrfx_nvmc_page_erase(_fl_addr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    nrf_nvmc_write_words(_fl_addr, (uint32_t *) _fl_buf, FLASH_PAGE_SIZE / 4);
 | 
					    nrfx_nvmc_words_write(_fl_addr, (uint32_t *) _fl_buf, FLASH_PAGE_SIZE / 4);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  _fl_addr = FLASH_CACHE_INVALID_ADDR;
 | 
					  _fl_addr = FLASH_CACHE_INVALID_ADDR;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,7 +28,7 @@
 | 
				
			|||||||
#include <stdint.h>
 | 
					#include <stdint.h>
 | 
				
			||||||
#include <stdbool.h>
 | 
					#include <stdbool.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "nrf_nvmc.h"
 | 
					#include "nrfx_nvmc.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __cplusplus
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 extern "C" {
 | 
					 extern "C" {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -65,8 +65,8 @@
 | 
				
			|||||||
#include "pstorage_platform.h"
 | 
					#include "pstorage_platform.h"
 | 
				
			||||||
#include "nrf_mbr.h"
 | 
					#include "nrf_mbr.h"
 | 
				
			||||||
#include "pstorage.h"
 | 
					#include "pstorage.h"
 | 
				
			||||||
 | 
					#include "nrfx_nvmc.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "nrf_nvmc.h"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef NRF52840_XXAA
 | 
					#ifdef NRF52840_XXAA
 | 
				
			||||||
#include "nrf_usbd.h"
 | 
					#include "nrf_usbd.h"
 | 
				
			||||||
@@ -275,11 +275,11 @@ void adafruit_factory_reset(void)
 | 
				
			|||||||
  // clear all App Data if any
 | 
					  // clear all App Data if any
 | 
				
			||||||
  if ( DFU_APP_DATA_RESERVED )
 | 
					  if ( DFU_APP_DATA_RESERVED )
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    nrf_nvmc_page_erase(APPDATA_ADDR_START);
 | 
					    nrfx_nvmc_page_erase(APPDATA_ADDR_START);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Only need to erase the 1st page of Application code to make it invalid
 | 
					  // Only need to erase the 1st page of Application code to make it invalid
 | 
				
			||||||
  nrf_nvmc_page_erase(DFU_BANK_0_REGION_START);
 | 
					  nrfx_nvmc_page_erase(DFU_BANK_0_REGION_START);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // back to normal
 | 
					  // back to normal
 | 
				
			||||||
  led_state(STATE_FACTORY_RESET_FINISHED);
 | 
					  led_state(STATE_FACTORY_RESET_FINISHED);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,11 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// Power
 | 
					// Power
 | 
				
			||||||
#define NRFX_POWER_ENABLED  1
 | 
					#define NRFX_POWER_ENABLED  1
 | 
				
			||||||
#define NRFX_POWER_CONFIG_IRQ_PRIORITY 7
 | 
					#define NRFX_POWER_DEFAULT_CONFIG_IRQ_PRIORITY  7
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define NRFX_CLOCK_ENABLED  0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define NRFX_NVMC_ENABLED   1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// UART
 | 
					// UART
 | 
				
			||||||
#ifdef NRF52832_XXAA
 | 
					#ifdef NRF52832_XXAA
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -45,38 +45,47 @@ int write_block(uint32_t block_no, uint8_t *data, bool quiet, WriteState *state)
 | 
				
			|||||||
// tinyusb callbacks
 | 
					// tinyusb callbacks
 | 
				
			||||||
//--------------------------------------------------------------------+
 | 
					//--------------------------------------------------------------------+
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Invoked when received SCSI_CMD_INQUIRY
 | 
				
			||||||
 | 
					// Application fill vendor id, product id and revision with string up to 8, 16, 4 characters respectively
 | 
				
			||||||
 | 
					void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t product_id[16], uint8_t product_rev[4])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  (void) lun;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const char vid[] = "Adafruit";
 | 
				
			||||||
 | 
					  const char pid[] = "Bluefruit UF2";
 | 
				
			||||||
 | 
					  const char rev[] = "1.0";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  memcpy(vendor_id  , vid, strlen(vid));
 | 
				
			||||||
 | 
					  memcpy(product_id , pid, strlen(pid));
 | 
				
			||||||
 | 
					  memcpy(product_rev, rev, strlen(rev));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Invoked when received Test Unit Ready command.
 | 
				
			||||||
 | 
					// return true allowing host to read/write this LUN e.g SD card inserted
 | 
				
			||||||
 | 
					bool tud_msc_test_unit_ready_cb(uint8_t lun)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  (void) lun;
 | 
				
			||||||
 | 
					  return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Callback invoked when received an SCSI command not in built-in list below
 | 
					// Callback invoked when received an SCSI command not in built-in list below
 | 
				
			||||||
// - READ_CAPACITY10, READ_FORMAT_CAPACITY, INQUIRY, MODE_SENSE6, REQUEST_SENSE
 | 
					// - READ_CAPACITY10, READ_FORMAT_CAPACITY, INQUIRY, MODE_SENSE6, REQUEST_SENSE
 | 
				
			||||||
// - READ10 and WRITE10 has their own callbacks
 | 
					// - READ10 and WRITE10 has their own callbacks
 | 
				
			||||||
int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer, uint16_t bufsize)
 | 
					int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer, uint16_t bufsize)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  void const* response = NULL;
 | 
					  void const* response = NULL;
 | 
				
			||||||
  int32_t resplen = 0;
 | 
					  uint16_t resplen = 0;
 | 
				
			||||||
  memset(buffer, 0, bufsize);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  switch ( scsi_cmd[0] )
 | 
					  // most scsi handled is input
 | 
				
			||||||
 | 
					  bool in_xfer = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  switch (scsi_cmd[0])
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    case SCSI_CMD_TEST_UNIT_READY:
 | 
					 | 
				
			||||||
      // Command that host uses to check our readiness before sending other commands
 | 
					 | 
				
			||||||
      resplen = 0;
 | 
					 | 
				
			||||||
    break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
 | 
					    case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
 | 
				
			||||||
      // Host is about to read/write etc ... better not to disconnect disk
 | 
					      // Host is about to read/write etc ... better not to disconnect disk
 | 
				
			||||||
      resplen = 0;
 | 
					      resplen = 0;
 | 
				
			||||||
    break;
 | 
					    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    case SCSI_CMD_START_STOP_UNIT:
 | 
					 | 
				
			||||||
      // Host try to eject/safe remove/poweroff us. We could safely disconnect with disk storage, or go into lower power
 | 
					 | 
				
			||||||
      /* scsi_start_stop_unit_t const * start_stop = (scsi_start_stop_unit_t const *) scsi_cmd;
 | 
					 | 
				
			||||||
       // Start bit = 0 : low power mode, if load_eject = 1 : unmount disk storage as well
 | 
					 | 
				
			||||||
       // Start bit = 1 : Ready mode, if load_eject = 1 : mount disk storage
 | 
					 | 
				
			||||||
       start_stop->start;
 | 
					 | 
				
			||||||
       start_stop->load_eject;
 | 
					 | 
				
			||||||
       */
 | 
					 | 
				
			||||||
      resplen = 0;
 | 
					 | 
				
			||||||
    break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    default:
 | 
					    default:
 | 
				
			||||||
      // Set Sense = Invalid Command Operation
 | 
					      // Set Sense = Invalid Command Operation
 | 
				
			||||||
      tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00);
 | 
					      tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00);
 | 
				
			||||||
@@ -86,13 +95,18 @@ int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer,
 | 
				
			|||||||
    break;
 | 
					    break;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // return len must not larger than bufsize
 | 
					  // return resplen must not larger than bufsize
 | 
				
			||||||
  if ( resplen > (int32_t)bufsize ) resplen = bufsize;
 | 
					  if ( resplen > bufsize ) resplen = bufsize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // copy response to stack's buffer if any
 | 
					  if ( response && (resplen > 0) )
 | 
				
			||||||
  if ( response && resplen )
 | 
					  {
 | 
				
			||||||
 | 
					    if(in_xfer)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      memcpy(buffer, response, resplen);
 | 
					      memcpy(buffer, response, resplen);
 | 
				
			||||||
 | 
					    }else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      // SCSI output
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return resplen;
 | 
					  return resplen;
 | 
				
			||||||
@@ -161,6 +175,8 @@ void tud_msc_write10_complete_cb(uint8_t lun)
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Invoked when received SCSI_CMD_READ_CAPACITY_10 and SCSI_CMD_READ_FORMAT_CAPACITY to determine the disk size
 | 
				
			||||||
 | 
					// Application update block count and block size
 | 
				
			||||||
void tud_msc_capacity_cb(uint8_t lun, uint32_t* block_count, uint16_t* block_size)
 | 
					void tud_msc_capacity_cb(uint8_t lun, uint32_t* block_count, uint16_t* block_size)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  (void) lun;
 | 
					  (void) lun;
 | 
				
			||||||
@@ -169,4 +185,26 @@ void tud_msc_capacity_cb(uint8_t lun, uint32_t* block_count, uint16_t* block_siz
 | 
				
			|||||||
  *block_size  = 512;
 | 
					  *block_size  = 512;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Invoked when received Start Stop Unit command
 | 
				
			||||||
 | 
					// - Start = 0 : stopped power mode, if load_eject = 1 : unload disk storage
 | 
				
			||||||
 | 
					// - Start = 1 : active mode, if load_eject = 1 : load disk storage
 | 
				
			||||||
 | 
					bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, bool load_eject)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  (void) lun;
 | 
				
			||||||
 | 
					  (void) power_condition;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if ( load_eject )
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    if (start)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      // load disk storage
 | 
				
			||||||
 | 
					    }else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      // unload disk storage
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -58,11 +58,6 @@
 | 
				
			|||||||
//------------- Class enabled -------------//
 | 
					//------------- Class enabled -------------//
 | 
				
			||||||
#define CFG_TUD_CDC                 1
 | 
					#define CFG_TUD_CDC                 1
 | 
				
			||||||
#define CFG_TUD_MSC                 1
 | 
					#define CFG_TUD_MSC                 1
 | 
				
			||||||
#define CFG_TUD_HID_KEYBOARD        0
 | 
					 | 
				
			||||||
#define CFG_TUD_HID_MOUSE           0
 | 
					 | 
				
			||||||
#define CFG_TUD_HID_GENERIC         0 // not supported yet
 | 
					 | 
				
			||||||
#define CFG_TUD_CUSTOM_CLASS        0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*------------------------------------------------------------------*/
 | 
					/*------------------------------------------------------------------*/
 | 
				
			||||||
/* CLASS DRIVER
 | 
					/* CLASS DRIVER
 | 
				
			||||||
@@ -72,34 +67,15 @@
 | 
				
			|||||||
#define CFG_TUD_CDC_RX_BUFSIZE      1024
 | 
					#define CFG_TUD_CDC_RX_BUFSIZE      1024
 | 
				
			||||||
#define CFG_TUD_CDC_TX_BUFSIZE      1024
 | 
					#define CFG_TUD_CDC_TX_BUFSIZE      1024
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* TX is sent automatically on every Start of Frame event ~ 1ms.
 | 
					 | 
				
			||||||
 * If not enabled, application must call tud_cdc_flush() periodically
 | 
					 | 
				
			||||||
 * Note: Enabled this could overflow device task, if it does, define
 | 
					 | 
				
			||||||
 * CFG_TUD_TASK_QUEUE_SZ with large value
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#define CFG_TUD_CDC_FLUSH_ON_SOF    0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Number of supported Logical Unit Number
 | 
					 | 
				
			||||||
#define CFG_TUD_MSC_MAXLUN          1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Buffer size for each read/write transfer, the more the better
 | 
					// Buffer size for each read/write transfer, the more the better
 | 
				
			||||||
#define CFG_TUD_MSC_BUFSIZE         (4*1024)
 | 
					#define CFG_TUD_MSC_BUFSIZE         (4*1024)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Vendor name included in Inquiry response, max 8 bytes
 | 
					 | 
				
			||||||
#define CFG_TUD_MSC_VENDOR          "Adafruit"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Product name included in Inquiry response, max 16 bytes
 | 
					 | 
				
			||||||
#define CFG_TUD_MSC_PRODUCT         "Feather nRF52840"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Product revision string included in Inquiry response, max 4 bytes
 | 
					 | 
				
			||||||
#define CFG_TUD_MSC_PRODUCT_REV     "1.0"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
//--------------------------------------------------------------------+
 | 
					//--------------------------------------------------------------------+
 | 
				
			||||||
// USB RAM PLACEMENT
 | 
					// USB RAM PLACEMENT
 | 
				
			||||||
//--------------------------------------------------------------------+
 | 
					//--------------------------------------------------------------------+
 | 
				
			||||||
#define CFG_TUSB_ATTR_USBRAM
 | 
					#define CFG_TUSB_ATTR_USBRAM
 | 
				
			||||||
#define CFG_TUSB_MEM_ALIGN          ATTR_ALIGNED(4)
 | 
					#define CFG_TUSB_MEM_ALIGN          __attribute__ ((aligned(4)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define BREAKPOINT_IGNORE_COUNT(n) \
 | 
					#define BREAKPOINT_IGNORE_COUNT(n) \
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -40,12 +40,8 @@
 | 
				
			|||||||
// MACRO TYPEDEF CONSTANT ENUM DECLARATION
 | 
					// MACRO TYPEDEF CONSTANT ENUM DECLARATION
 | 
				
			||||||
//--------------------------------------------------------------------+
 | 
					//--------------------------------------------------------------------+
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// from usb_desc.c for dynamic descriptor
 | 
					 | 
				
			||||||
extern tusb_desc_device_t usb_desc_dev;
 | 
					 | 
				
			||||||
extern usb_desc_cfg_t     usb_desc_cfg;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Serial string using unique Device ID
 | 
					// Serial string using unique Device ID
 | 
				
			||||||
extern uint16_t           usb_desc_str_serial[1+16];
 | 
					extern char               usb_desc_str_serial[1+16];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* tinyusb function that handles power event (detected, ready, removed)
 | 
					/* tinyusb function that handles power event (detected, ready, removed)
 | 
				
			||||||
 * We must call it within SD's SOC event handler, or set it as power event handler if SD is not enabled. */
 | 
					 * We must call it within SD's SOC event handler, or set it as power event handler if SD is not enabled. */
 | 
				
			||||||
@@ -94,24 +90,10 @@ void usb_init(bool cdc_only)
 | 
				
			|||||||
    tusb_hal_nrf_power_event(NRFX_POWER_USB_EVT_READY);
 | 
					    tusb_hal_nrf_power_event(NRFX_POWER_USB_EVT_READY);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if ( cdc_only )
 | 
					  usb_desc_set_mode(cdc_only);
 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    // Change PID to CDC only
 | 
					 | 
				
			||||||
    usb_desc_dev.idProduct = USB_DESC_CDC_ONLY_PID;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Remove MSC interface = reduce total interface + adjust config desc length
 | 
					 | 
				
			||||||
    usb_desc_cfg.config.bNumInterfaces--;
 | 
					 | 
				
			||||||
    usb_desc_cfg.config.wTotalLength -= sizeof(usb_desc_cfg.msc);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Create Serial string descriptor
 | 
					  // Create Serial string descriptor
 | 
				
			||||||
  char tmp_serial[17];
 | 
					  sprintf(usb_desc_str_serial, "%08lX%08lX", NRF_FICR->DEVICEID[1], NRF_FICR->DEVICEID[0]);
 | 
				
			||||||
  sprintf(tmp_serial, "%08lX%08lX", NRF_FICR->DEVICEID[1], NRF_FICR->DEVICEID[0]);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  for(uint8_t i=0; i<16; i++)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    usb_desc_str_serial[1+i] = tmp_serial[i];
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Init tusb stack
 | 
					  // Init tusb stack
 | 
				
			||||||
  tusb_init();
 | 
					  tusb_init();
 | 
				
			||||||
@@ -124,7 +106,7 @@ void usb_teardown(void)
 | 
				
			|||||||
    // Abort all transfers
 | 
					    // Abort all transfers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Disable pull up
 | 
					    // Disable pull up
 | 
				
			||||||
    nrf_usbd_pullup_disable();
 | 
					    nrf_usbd_pullup_disable(NRF_USBD);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Disable Interrupt
 | 
					    // Disable Interrupt
 | 
				
			||||||
    NVIC_DisableIRQ(USBD_IRQn);
 | 
					    NVIC_DisableIRQ(USBD_IRQn);
 | 
				
			||||||
@@ -132,7 +114,7 @@ void usb_teardown(void)
 | 
				
			|||||||
    // disable all interrupt
 | 
					    // disable all interrupt
 | 
				
			||||||
    NRF_USBD->INTENCLR = NRF_USBD->INTEN;
 | 
					    NRF_USBD->INTENCLR = NRF_USBD->INTEN;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    nrf_usbd_disable();
 | 
					    nrf_usbd_disable(NRF_USBD);
 | 
				
			||||||
    sd_clock_hfclk_release();
 | 
					    sd_clock_hfclk_release();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    sd_power_usbdetected_enable(false);
 | 
					    sd_power_usbdetected_enable(false);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,15 +24,6 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "usb_desc.h"
 | 
					#include "usb_desc.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
/*------------- Interface Numbering -------------*/
 | 
					 | 
				
			||||||
enum {
 | 
					 | 
				
			||||||
    ITF_NUM_CDC = 0  ,
 | 
					 | 
				
			||||||
    ITF_NUM_CDC_DATA ,
 | 
					 | 
				
			||||||
    ITF_NUM_MSC      ,
 | 
					 | 
				
			||||||
    ITF_NUM_TOTAL
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum {
 | 
					enum {
 | 
				
			||||||
    ITF_STR_LANGUAGE = 0 ,
 | 
					    ITF_STR_LANGUAGE = 0 ,
 | 
				
			||||||
    ITF_STR_MANUFACTURER ,
 | 
					    ITF_STR_MANUFACTURER ,
 | 
				
			||||||
@@ -42,22 +33,95 @@ enum {
 | 
				
			|||||||
    ITF_STR_MSC
 | 
					    ITF_STR_MSC
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*------------- Endpoint Numbering & Size -------------*/
 | 
					static bool _cdc_only = false;
 | 
				
			||||||
#define _EP_IN(x)          (0x80 | (x))
 | 
					 | 
				
			||||||
#define _EP_OUT(x)         (x)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
// CDC
 | 
					//--------------------------------------------------------------------+
 | 
				
			||||||
#define EP_CDC_NOTIF       _EP_IN ( ITF_NUM_CDC+1 )
 | 
					// Device Descriptor
 | 
				
			||||||
#define EP_CDC_NOTIF_SIZE  8
 | 
					//--------------------------------------------------------------------+
 | 
				
			||||||
 | 
					tusb_desc_device_t desc_device =
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    .bLength            = sizeof(tusb_desc_device_t),
 | 
				
			||||||
 | 
					    .bDescriptorType    = TUSB_DESC_DEVICE,
 | 
				
			||||||
 | 
					    .bcdUSB             = 0x0200,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define EP_CDC_OUT         _EP_OUT( ITF_NUM_CDC+2 )
 | 
					    // Use Interface Association Descriptor (IAD) for CDC
 | 
				
			||||||
#define EP_CDC_IN          _EP_IN ( ITF_NUM_CDC+2 )
 | 
					    // 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,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Mass Storage
 | 
					    .idVendor           = USB_DESC_VID,
 | 
				
			||||||
#define EP_MSC_OUT         _EP_OUT( ITF_NUM_MSC+1 )
 | 
					    .idProduct          = USB_DESC_UF2_PID,
 | 
				
			||||||
#define EP_MSC_IN          _EP_IN ( ITF_NUM_MSC+1 )
 | 
					    .bcdDevice          = 0x0100,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define EP_MSC_SIZE        64
 | 
					    .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;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//--------------------------------------------------------------------+
 | 
				
			||||||
 | 
					// Configuration Descriptor
 | 
				
			||||||
 | 
					//--------------------------------------------------------------------+
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum {
 | 
				
			||||||
 | 
					    ITF_NUM_CDC = 0  ,
 | 
				
			||||||
 | 
					    ITF_NUM_CDC_DATA ,
 | 
				
			||||||
 | 
					    ITF_NUM_MSC      ,
 | 
				
			||||||
 | 
					    ITF_NUM_TOTAL
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint8_t const desc_configuration_cdc_msc[] =
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  // Interface count, string index, total length, attribute, power in mA
 | 
				
			||||||
 | 
					  TUD_CONFIG_DESCRIPTOR(ITF_NUM_TOTAL, 0, TUD_CONFIG_DESC_LEN + TUD_CDC_DESC_LEN + TUD_MSC_DESC_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Interface number, string index, EP notification address and size, EP data address (out, in) and size.
 | 
				
			||||||
 | 
					  TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, ITF_STR_CDC, 0x81, 8, 0x02, 0x82, 64),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Interface number, string index, EP Out & EP In address, EP size
 | 
				
			||||||
 | 
					  TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, ITF_STR_MSC, 0x03, 0x83, 64),
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint8_t const desc_configuration_cdc_only[] =
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  // Interface count, string index, total length, attribute, power in mA
 | 
				
			||||||
 | 
					  TUD_CONFIG_DESCRIPTOR(ITF_NUM_TOTAL-1, 0, TUD_CONFIG_DESC_LEN + TUD_CDC_DESC_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Interface number, string index, EP notification address and size, EP data address (out, in) and size.
 | 
				
			||||||
 | 
					  TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, ITF_STR_CDC, 0x81, 8, 0x02, 0x82, 64),
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 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 _cdc_only ? desc_configuration_cdc_only : desc_configuration_cdc_msc;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Enumerate as CDC + MSC or CDC only
 | 
				
			||||||
 | 
					void usb_desc_set_mode(bool cdc_only)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  _cdc_only = cdc_only;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if ( cdc_only )
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    // Change PID to CDC only
 | 
				
			||||||
 | 
					    desc_device.idProduct = USB_DESC_CDC_ONLY_PID;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//--------------------------------------------------------------------+
 | 
					//--------------------------------------------------------------------+
 | 
				
			||||||
// STRING DESCRIPTORS
 | 
					// STRING DESCRIPTORS
 | 
				
			||||||
@@ -86,219 +150,51 @@ enum {
 | 
				
			|||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Serial is 64-bit DeviceID -> 16 chars len
 | 
					// Serial is 64-bit DeviceID -> 16 chars len
 | 
				
			||||||
uint16_t usb_desc_str_serial[1+16] = { TUD_DESC_STR_HEADER(16) };
 | 
					char usb_desc_str_serial[1+16];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// array of pointer to string descriptors
 | 
					// array of pointer to string descriptors
 | 
				
			||||||
uint16_t const * const string_desc_arr [] = USB_STRING_DESCRIPTORS;
 | 
					char const* string_desc_arr [] =
 | 
				
			||||||
 | 
					 | 
				
			||||||
//--------------------------------------------------------------------+
 | 
					 | 
				
			||||||
// Device Descriptor
 | 
					 | 
				
			||||||
//--------------------------------------------------------------------+
 | 
					 | 
				
			||||||
tusb_desc_device_t usb_desc_dev =
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    .bLength            = sizeof(tusb_desc_device_t),
 | 
					  (const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409)
 | 
				
			||||||
    .bDescriptorType    = TUSB_DESC_DEVICE,
 | 
					  "Adafruit Industries",         // 1: Manufacturer
 | 
				
			||||||
    .bcdUSB             = 0x0200,
 | 
					  "Bluefruit DFU",               // 2: Product
 | 
				
			||||||
 | 
					  usb_desc_str_serial,           // 3: Serials, should use chip ID
 | 
				
			||||||
    // Use Interface Association Descriptor (IAD) for CDC
 | 
					  "Bluefruit Serial",            // 4: CDC Interface
 | 
				
			||||||
    // As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1)
 | 
					  "Bluefruit UF2",               // 5: MSC Interface
 | 
				
			||||||
    .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
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//--------------------------------------------------------------------+
 | 
					// up to 32 unicode characters (header make it 33)
 | 
				
			||||||
// Configuration Descriptor
 | 
					static uint16_t _desc_str[33];
 | 
				
			||||||
//--------------------------------------------------------------------+
 | 
					
 | 
				
			||||||
usb_desc_cfg_t usb_desc_cfg =
 | 
					// 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)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    .config =
 | 
					  uint8_t chr_count;
 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        .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
 | 
					  if ( index == 0)
 | 
				
			||||||
    .cdc =
 | 
					 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
      .iad =
 | 
					    memcpy(&_desc_str[1], string_desc_arr[0], 2);
 | 
				
			||||||
 | 
					    chr_count = 1;
 | 
				
			||||||
 | 
					  }else
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
          .bLength           = sizeof(tusb_desc_interface_assoc_t),
 | 
					    if ( !(index < sizeof(string_desc_arr)/sizeof(string_desc_arr[0])) ) return NULL;
 | 
				
			||||||
          .bDescriptorType   = TUSB_DESC_INTERFACE_ASSOCIATION,
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
          .bFirstInterface   = ITF_NUM_CDC,
 | 
					    // Convert ASCII string into UTF-16
 | 
				
			||||||
          .bInterfaceCount   = 2,
 | 
					    const char* str = string_desc_arr[index];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          .bFunctionClass    = TUSB_CLASS_CDC,
 | 
					    // Cap at max char
 | 
				
			||||||
          .bFunctionSubClass = CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL,
 | 
					    chr_count = strlen(str);
 | 
				
			||||||
          .bFunctionProtocol = CDC_COMM_PROTOCOL_ATCOMMAND,
 | 
					    if ( chr_count > 31 ) chr_count = 31;
 | 
				
			||||||
          .iFunction         = 0
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      //------------- CDC Communication Interface -------------//
 | 
					    for(uint8_t i=0; i<chr_count; i++)
 | 
				
			||||||
      .comm_itf =
 | 
					 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
          .bLength            = sizeof(tusb_desc_interface_t),
 | 
					      _desc_str[1+i] = str[i];
 | 
				
			||||||
          .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 = EP_MSC_SIZE},
 | 
					 | 
				
			||||||
          .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 = EP_MSC_SIZE },
 | 
					 | 
				
			||||||
          .bInterval        = 1
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // first byte is length (including header), second byte is string type
 | 
				
			||||||
 | 
					  _desc_str[0] = (TUSB_DESC_STRING << 8 ) | (2*chr_count + 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// tud_desc_set is required by tinyusb stack
 | 
					  return _desc_str;
 | 
				
			||||||
// 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
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,9 +28,7 @@
 | 
				
			|||||||
#include "tusb.h"
 | 
					#include "tusb.h"
 | 
				
			||||||
#include "boards.h"
 | 
					#include "boards.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __cplusplus
 | 
					void usb_desc_set_mode(bool cdc_only);
 | 
				
			||||||
 extern "C" {
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifndef USB_DESC_VID
 | 
					#ifndef USB_DESC_VID
 | 
				
			||||||
#define USB_DESC_VID             0x239A
 | 
					#define USB_DESC_VID             0x239A
 | 
				
			||||||
@@ -44,43 +42,4 @@
 | 
				
			|||||||
#define USB_DESC_CDC_ONLY_PID    0x002A
 | 
					#define USB_DESC_CDC_ONLY_PID    0x002A
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
/*------------- 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;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef __cplusplus
 | 
					 | 
				
			||||||
 }
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif /* USB_DESC_H_ */
 | 
					#endif /* USB_DESC_H_ */
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user