adding tinyusb support

This commit is contained in:
hathach 2018-04-02 13:11:21 +07:00
parent 191d88c76b
commit d362ad1c53
16 changed files with 560 additions and 637 deletions

View File

@ -64,7 +64,7 @@ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#if defined(_WIN32)
/* Do not include nrf specific files when building for PC host */
#elif defined(__unix)
//#elif defined(__unix)
/* Do not include nrf specific files when building for PC host */
#elif defined(__APPLE__)
/* Do not include nrf specific files when building for PC host */

View File

@ -1,192 +0,0 @@
/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved.
*
* The information contained herein is property of Nordic Semiconductor ASA.
* Terms and conditions of usage are described in detail in NORDIC
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
*
* Licensees are granted free, non-transferable use of the information. NO
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
* the file.
*
*/
#include "dfu_app_handler.h"
#include <string.h>
#include "bootloader_util.h"
#include "nrf.h"
#include "nrf_sdm.h"
#include "ble_gatt.h"
#include "ble_gatts.h"
#include "app_error.h"
#include "dfu_ble_svc.h"
#include "device_manager.h"
#include "nrf_delay.h"
#define IRQ_ENABLED 0x01 /**< Field that identifies if an interrupt is enabled. */
#define MAX_NUMBER_INTERRUPTS 32 /**< Maximum number of interrupts available. */
static void dfu_app_reset_prepare(void); /**< Forward declaration of default reset handler. */
static dfu_app_reset_prepare_t m_reset_prepare = dfu_app_reset_prepare; /**< Callback function to application to prepare for system reset. Allows application to clean up service and memory before reset. */
static dfu_ble_peer_data_t m_peer_data; /**< Peer data to be used for data exchange when resetting into DFU mode. */
static dm_handle_t m_dm_handle; /**< Device Manager handle with instance IDs of current BLE connection. */
/**@brief Function for reset_prepare handler if the application has not registered a handler.
*/
static void dfu_app_reset_prepare(void)
{
// Reset prepare should be handled by application.
// This function can be extended to include default handling if application does not implement
// own handler.
}
/**@brief Function for disabling all interrupts before jumping from bootloader to application.
*/
static void interrupts_disable(void)
{
uint32_t interrupt_setting_mask;
uint32_t irq;
// Fetch the current interrupt settings.
interrupt_setting_mask = NVIC->ISER[0];
// Loop from interrupt 0 for disabling of all interrupts.
for (irq = 0; irq < MAX_NUMBER_INTERRUPTS; irq++)
{
if (interrupt_setting_mask & (IRQ_ENABLED << irq))
{
// The interrupt was enabled, hence disable it.
NVIC_DisableIRQ((IRQn_Type)irq);
}
}
}
/**@brief Function for providing peer information to DFU for re-establishing a bonded connection in
* DFU mode.
*
* @param[in] conn_handle Connection handle for the connection requesting DFU mode.
*/
static void dfu_app_peer_data_set(uint16_t conn_handle)
{
uint32_t err_code;
dm_sec_keyset_t key_set;
uint32_t app_context_data = 0;
dm_application_context_t app_context;
/** [DFU bond sharing] */
err_code = dm_handle_get(conn_handle, &m_dm_handle);
if (err_code == NRF_SUCCESS)
{
err_code = dm_distributed_keys_get(&m_dm_handle, &key_set);
if (err_code == NRF_SUCCESS)
{
APP_ERROR_CHECK(err_code);
m_peer_data.addr = key_set.keys_central.p_id_key->id_addr_info;
m_peer_data.irk = key_set.keys_central.p_id_key->id_info;
m_peer_data.enc_key.enc_info = key_set.keys_periph.enc_key.p_enc_key->enc_info;
m_peer_data.enc_key.master_id = key_set.keys_periph.enc_key.p_enc_key->master_id;
err_code = dfu_ble_svc_peer_data_set(&m_peer_data);
APP_ERROR_CHECK(err_code);
app_context_data = (DFU_APP_ATT_TABLE_CHANGED << DFU_APP_ATT_TABLE_POS);
app_context.len = sizeof(app_context_data);
app_context.p_data = (uint8_t *)&app_context_data;
app_context.flags = 0;
err_code = dm_application_context_set(&m_dm_handle, &app_context);
APP_ERROR_CHECK(err_code);
}
else
{
// Keys were not available, thus we have a non-encrypted connection.
err_code = dm_peer_addr_get(&m_dm_handle, &m_peer_data.addr);
APP_ERROR_CHECK(err_code);
err_code = dfu_ble_svc_peer_data_set(&m_peer_data);
APP_ERROR_CHECK(err_code);
}
}
/** [DFU bond sharing] */
}
/**@brief Function for preparing the reset, disabling SoftDevice, and jumping to the bootloader.
*
* @param[in] conn_handle Connection handle for peer requesting to enter DFU mode.
*/
static void bootloader_start(uint16_t conn_handle)
{
uint32_t err_code;
uint16_t sys_serv_attr_len = sizeof(m_peer_data.sys_serv_attr);
err_code = sd_ble_gatts_sys_attr_get(conn_handle,
m_peer_data.sys_serv_attr,
&sys_serv_attr_len,
BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS);
if (err_code != NRF_SUCCESS)
{
// Any error at this stage means the system service attributes could not be fetched.
// This means the service changed indication cannot be sent in DFU mode, but connection
// is still possible to establish.
}
m_reset_prepare();
err_code = sd_power_gpregret_set(BOOTLOADER_DFU_START);
APP_ERROR_CHECK(err_code);
err_code = sd_softdevice_disable();
APP_ERROR_CHECK(err_code);
err_code = sd_softdevice_vector_table_base_set(NRF_UICR->NRFFW[0]);
APP_ERROR_CHECK(err_code);
dfu_app_peer_data_set(conn_handle);
NVIC_ClearPendingIRQ(SWI2_IRQn);
interrupts_disable();
bootloader_util_app_start(NRF_UICR->NRFFW[0]);
}
void dfu_app_on_dfu_evt(ble_dfu_t * p_dfu, ble_dfu_evt_t * p_evt)
{
switch (p_evt->ble_dfu_evt_type)
{
case BLE_DFU_START:
// Starting the bootloader - will cause reset.
bootloader_start(p_dfu->conn_handle);
break;
default:
{
// Unsupported event received from DFU Service.
// Send back BLE_DFU_RESP_VAL_NOT_SUPPORTED message to peer.
uint32_t err_code = ble_dfu_response_send(p_dfu,
BLE_DFU_START_PROCEDURE,
BLE_DFU_RESP_VAL_NOT_SUPPORTED);
APP_ERROR_CHECK(err_code);
}
break;
}
}
void dfu_app_reset_prepare_set(dfu_app_reset_prepare_t reset_prepare_func)
{
m_reset_prepare = reset_prepare_func;
}
void dfu_app_dm_appl_instance_set(dm_application_instance_t app_instance)
{
uint32_t err_code;
err_code = dm_application_instance_set(&app_instance, &m_dm_handle);
APP_ERROR_CHECK(err_code);
}

View File

@ -1,86 +0,0 @@
/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved.
*
* The information contained herein is property of Nordic Semiconductor ASA.
* Terms and conditions of usage are described in detail in NORDIC
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
*
* Licensees are granted free, non-transferable use of the information. NO
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
* the file.
*
*/
/** @file
*
* @defgroup nrf_dfu_app_handler DFU BLE packet handling in application
* @{
*
* @brief Handling of DFU BLE packets in the application.
*
* @details This module implements the handling of DFU packets for switching
* from an application to the bootloader and start DFU mode. The DFU
* packets are transmitted over BLE.
* This module handles only the StartDFU packet, which allows a BLE
* application to expose support for the DFU Service.
* The actual DFU Service runs in a dedicated environment after a BLE
* disconnect and reset of the \nRFXX device.
* The host must reconnect and continue the update procedure with
* access to the full DFU Service.
*
* @note The application must propagate DFU events to this module by calling
* @ref dfu_app_on_dfu_evt from the @ref ble_dfu_evt_handler_t callback.
*/
#ifndef DFU_APP_HANDLER_H__
#define DFU_APP_HANDLER_H__
#include "ble_dfu.h"
#include "nrf_svc.h"
#include "bootloader_types.h"
#include "device_manager.h"
#define DFU_APP_ATT_TABLE_POS 0 /**< Position for the ATT table changed setting. */
#define DFU_APP_ATT_TABLE_CHANGED 1 /**< Value indicating that the ATT table might have changed. This value will be set in the application-specific context in Device Manager when entering DFU mode. */
/**@brief DFU application reset_prepare function. This function is a callback that allows the
* application to prepare for an upcoming application reset.
*/
typedef void (*dfu_app_reset_prepare_t)(void);
/**@brief Function for handling events from the DFU Service.
*
* @details The application must inject this function into the DFU Service or propagate DFU events
* to the dfu_app_handler module by calling this function in the application-specific DFU event
* handler.
*
* @param[in] p_dfu Pointer to the DFU Service structure to which the include event relates.
* @param[in] p_evt Pointer to the DFU event.
*/
void dfu_app_on_dfu_evt(ble_dfu_t * p_dfu, ble_dfu_evt_t * p_evt);
/**@brief Function for registering a function to prepare a reset.
*
* @details The provided function is executed before resetting the system into bootloader/DFU
* mode. By registering this function, the caller is notified before the reset and can
* thus prepare the application for reset. For example, the application can gracefully
* disconnect any peers on BLE, turn of LEDS, ensure that all pending flash operations
* have completed, and so on.
*
* @param[in] reset_prepare_func Function to be executed before a reset.
*/
void dfu_app_reset_prepare_set(dfu_app_reset_prepare_t reset_prepare_func);
/**@brief Function for setting the Device Manager application instance.
*
* @details This function allows to set the @ref dm_application_instance_t value that is returned by the
* Device Manager when the application registers using @ref dm_register.
* If this function is not called, it is not be possible to share bonding information
* from the application to the bootloader/DFU when entering DFU mode.
*
* @param[in] app_instance Value for the application instance in use.
*/
void dfu_app_dm_appl_instance_set(dm_application_instance_t app_instance);
#endif // DFU_APP_HANDLER_H__
/** @} */

View File

@ -1,52 +0,0 @@
/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved.
*
* The information contained herein is property of Nordic Semiconductor ASA.
* Terms and conditions of usage are described in detail in NORDIC
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
*
* Licensees are granted free, non-transferable use of the information. NO
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
* the file.
*
*/
#include <stdint.h>
void HardFault_Handler(void) __attribute__(( naked ));
void HardFault_Handler(void)
{
__asm volatile(
" .syntax unified \n"
" ldr r0, =0xFFFFFFFD \n"
" cmp r0, lr \n"
" bne HardFault_Handler_ChooseMSP \n"
/* Reading PSP into R0 */
" mrs r0, PSP \n"
" b HardFault_Handler_Continue \n"
"HardFault_Handler_ChooseMSP: \n"
/* Reading MSP into R0 */
" mrs r0, MSP \n"
/* -----------------------------------------------------------------
* If we have selected MSP check if we may use stack safetly.
* If not - reset the stack to the initial value. */
" ldr r1, =__StackTop \n"
" ldr r2, =__StackLimit \n"
/* MSP is in the range of <__StackTop, __StackLimit) */
" cmp r0, r1 \n"
" bhi HardFault_MoveSP \n"
" cmp r0, r2 \n"
" bhi HardFault_Handler_Continue \n"
/* ----------------------------------------------------------------- */
"HardFault_MoveSP: \n"
" mov SP, r1 \n"
" movs r0, #0 \n"
"HardFault_Handler_Continue: \n"
" ldr r3, =HardFault_c_handler \n"
" bx r3 \n"
" .align \n"
);
}

View File

@ -1,65 +0,0 @@
/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved.
*
* The information contained herein is property of Nordic Semiconductor ASA.
* Terms and conditions of usage are described in detail in NORDIC
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
*
* Licensees are granted free, non-transferable use of the information. NO
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
* the file.
*
*/
#include <stdint.h>
#pragma section = "CSTACK"
extern void HardFault_c_handler( uint32_t * );
__stackless void HardFault_Handler(void);
__stackless void HardFault_Handler(void)
{
__asm volatile(
" ldr r0, 100f \n"
" cmp r0, lr \n"
" bne 1f \n"
/* Reading PSP into R0 */
" mrs r0, PSP \n"
" b 3f \n"
"1: \n"
/* Reading MSP into R0 */
" mrs r0, MSP \n"
/* -----------------------------------------------------------------
* If we have selected MSP check if we may use stack safetly.
* If not - reset the stack to the initial value. */
" ldr r1, 101f \n"
" ldr r2, 102f \n"
/* MSP is in the range of <__StackTop, __StackLimit) */
" cmp r0, r1 \n"
" bhi 2f \n"
" cmp r0, r2 \n"
" bhi 3f \n"
/* ----------------------------------------------------------------- */
"2: \n"
" mov SP, r1 \n"
" movs r0, #0 \n"
"3: \n"
" ldr r3, 103f \n"
" bx r3 \n"
"100: \n"
" DC32 0xFFFFFFFD \n"
"101: \n"
" DC32 %c0 \n"
"102: \n"
" DC32 %c1 \n"
"103: \n"
" DC32 %c2 \n"
: /* Outputs */
: /* Inputs */
"i"(__section_end("CSTACK")),
"i"(__section_begin("CSTACK")),
"i"(&HardFault_c_handler)
);
}

View File

@ -1,61 +0,0 @@
/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved.
*
* The information contained herein is property of Nordic Semiconductor ASA.
* Terms and conditions of usage are described in detail in NORDIC
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
*
* Licensees are granted free, non-transferable use of the information. NO
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
* the file.
*
*/
#include <stdint.h>
//lint -save -e27 -e10 -e19 -e40
extern char STACK$$Base;
/* This variable should be static but then it cannot be used in assembly code below.
* The problem here is that the address of the section can be archived by $$ operator
* that is not allowed in assembly code. */
char const * HardFault_Handler_stack_bottom = &STACK$$Base;
//lint -restore
__asm void HardFault_Handler(void)
{
PRESERVE8
EXTERN HardFault_c_handler
EXTERN __initial_sp
EXTERN HardFault_Handler_stack_bottom
ldr r0, =0xFFFFFFFD
cmp r0, lr
bne HardFault_Handler_ChooseMSP
/* Reading PSP into R0 */
mrs r0, PSP
b HardFault_Handler_Continue
HardFault_Handler_ChooseMSP
/* Reading MSP into R0 */
mrs r0, MSP
/* -----------------------------------------------------------------
* If we have selected MSP, check if we may use stack safely.
* If not - reset the stack to the initial value. */
ldr r1, =__initial_sp
ldr r2, =HardFault_Handler_stack_bottom
ldr r2, [r2]
/* MSP is in the range of <__StackTop, __StackLimit) */
cmp r0, r1
bhi HardFault_MoveSP
cmp r0, r2
bhi HardFault_Handler_Continue
/* ----------------------------------------------------------------- */
HardFault_MoveSP
mov SP, r1
movs r0, #0
HardFault_Handler_Continue
ldr r3, =HardFault_c_handler
bx r3
ALIGN
}

View File

@ -1,64 +0,0 @@
/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved.
*
* The information contained herein is property of Nordic Semiconductor ASA.
* Terms and conditions of usage are described in detail in NORDIC
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
*
* Licensees are granted free, non-transferable use of the information. NO
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
* the file.
*
*/
#include <stdint.h>
#pragma section = "CSTACK"
extern void HardFault_c_handler( uint32_t * );
__stackless void HardFault_Handler(void);
__stackless void HardFault_Handler(void)
{
__asm volatile(
" ldr.n r3, 103f \n"
" tst lr, #4 \n"
/* PSP is quite simple and does not require additional handler */
" itt ne \n"
" mrsne r0, psp \n"
/* Jump to the handler, do not store LR - returning from handler just exits exception */
" bxne r3 \n"
/* Processing MSP requires stack checking */
" mrs r0, msp \n"
" ldr.n r1, 101f \n"
" ldr.n r2, 102f \n"
/* MSP is in the range of <__StackTop, __StackLimit) */
" cmp r0, r1 \n"
" bhi.n 1f \n"
" cmp r0, r2 \n"
" bhi.n 2f \n"
"1: \n"
" mov sp, r1 \n"
" mov r0, #0 \n"
"2: \n"
" bx r3 \n"
/* Data alignment if required */
" nop \n"
"101: \n"
" DC32 %c0 \n"
"102: \n"
" DC32 %c1 \n"
"103: \n"
" DC32 %c2 \n"
: /* Outputs */
: /* Inputs */
"i"(__section_end("CSTACK")),
"i"(__section_begin("CSTACK")),
"i"(&HardFault_c_handler)
);
}

View File

@ -1,60 +0,0 @@
/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved.
*
* The information contained herein is property of Nordic Semiconductor ASA.
* Terms and conditions of usage are described in detail in NORDIC
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
*
* Licensees are granted free, non-transferable use of the information. NO
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
* the file.
*
*/
#include <stdint.h>
//lint -save -e27 -e10 -e19 -e40
extern char STACK$$Base;
/* This variable should be static but then it cannot be used in assembly code below.
* The problem here is that the address of the section can be archived by $$ operator
* that is not allowed in assembly code. */
char const * HardFault_Handler_stack_bottom = &STACK$$Base;
//lint -restore
__asm void HardFault_Handler(void)
{
PRESERVE8
EXTERN HardFault_c_handler
EXTERN __initial_sp
EXTERN HardFault_Handler_stack_bottom
ldr r3, =HardFault_c_handler
tst lr, #4
/* PSP is quite simple and does not require additional handler */
itt ne
mrsne r0, psp
/* Jump to the handler, do not store LR - returning from handler just exits exception */
bxne r3
/* Processing MSP requires stack checking */
mrs r0, msp
ldr r1, =__initial_sp
ldr r2, =HardFault_Handler_stack_bottom
ldr r2, [r2]
/* MSP is in the range of <__StackTop, __StackLimit) */
cmp r0, r1
bhi HardFault_MoveSP
cmp r0, r2
bhi HardFault_Handler_Continue
HardFault_MoveSP
mov sp, r1
mov r0, #0
HardFault_Handler_Continue
bx r3
ALIGN
}

View File

@ -1,53 +0,0 @@
/* Copyright (c) 2016 Nordic Semiconductor. All Rights Reserved.
*
* The information contained herein is property of Nordic Semiconductor ASA.
* Terms and conditions of usage are described in detail in NORDIC
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
*
* Licensees are granted free, non-transferable use of the information. NO
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
* the file.
*
*/
#include "app_error.h"
#ifdef DEBUG
#include "bsp.h"
#endif
/*lint -save -e14 */
/**
* Function is implemented as weak so that it can be overwritten by custom application error handler
* when needed.
*/
__WEAK void app_error_fault_handler(uint32_t id, uint32_t pc, uint32_t info)
{
// On assert, the system can only recover with a reset.
#ifndef DEBUG
NVIC_SystemReset();
#else
#ifdef BSP_DEFINES_ONLY
LEDS_ON(LEDS_MASK);
#else
UNUSED_VARIABLE(bsp_indication_set(BSP_INDICATE_FATAL_ERROR));
// This call can be used for debug purposes during application development.
// @note CAUTION: Activating this code will write the stack to flash on an error.
// This function should NOT be used in a final product.
// It is intended STRICTLY for development/debugging purposes.
// The flash write will happen EVEN if the radio is active, thus interrupting
// any communication.
// Use with care. Uncomment the line below to use.
//ble_debug_assert_handler(error_code, line_num, p_file_name);
#endif // BSP_DEFINES_ONLY
app_error_save_and_stop(id, pc, info);
#endif // DEBUG
}
/*lint -restore */

View File

@ -521,3 +521,32 @@ void adafruit_factory_reset(void)
blinky_fast_set(false);
led_off(LED_BLUE);
}
void app_error_fault_handler(uint32_t id, uint32_t pc, uint32_t info)
{
NVIC_SystemReset();
}
//--------------------------------------------------------------------+
// tinyusb callbacks
//--------------------------------------------------------------------+
void tud_mount_cb(uint8_t port)
{
}
void tud_umount_cb(uint8_t port)
{
}
void tud_cdc_rx_cb(uint8_t port)
{
}
uint32_t tusb_hal_millis(void)
{
return ( ( ((uint64_t)app_timer_cnt_get())*1000*(APP_TIMER_CONFIG_RTC_FREQUENCY+1)) / APP_TIMER_CLOCK_FREQ );
}

View File

@ -16,6 +16,7 @@ VERSION_REVISION = 0
SDK_PATH = ../../nRF5_SDK_11.0.0_89a8197/components
SRC_PATH = ..
TUSB_PATH = ../../tinyusb/tinyusb
SD_NAME = s140
SD_VERSION = 6.0.0
@ -94,7 +95,7 @@ C_SOURCE_FILES += $(SDK_PATH)/libraries/bootloader_dfu/dfu_transport_ble.c
C_SOURCE_FILES += $(SDK_PATH)/libraries/timer/app_timer.c
C_SOURCE_FILES += $(SDK_PATH)/libraries/scheduler/app_scheduler.c
C_SOURCE_FILES += $(SDK_PATH)/libraries/util/app_error.c
C_SOURCE_FILES += $(SDK_PATH)/libraries/util/app_error_weak.c
#C_SOURCE_FILES += $(SDK_PATH)/libraries/util/app_error_weak.c
C_SOURCE_FILES += $(SDK_PATH)/libraries/util/app_util_platform.c
C_SOURCE_FILES += $(SDK_PATH)/libraries/crc16/crc16.c
C_SOURCE_FILES += $(SDK_PATH)/libraries/hci/hci_mem_pool.c
@ -105,6 +106,7 @@ C_SOURCE_FILES += $(SDK_PATH)/libraries/uart/app_uart.c
C_SOURCE_FILES += $(SDK_PATH)/drivers_nrf/common/nrf_drv_common.c
C_SOURCE_FILES += $(SDK_PATH)/drivers_nrf/uart/nrf_drv_uart.c
C_SOURCE_FILES += $(SDK_PATH)/drivers_nrf/power/nrf_drv_power.c
C_SOURCE_FILES += $(SDK_PATH)/ble/common/ble_advdata.c
C_SOURCE_FILES += $(SDK_PATH)/ble/common/ble_conn_params.c
@ -118,7 +120,14 @@ C_SOURCE_FILES += $(SDK_PATH)/toolchain/system_nrf52840.c
C_SOURCE_FILES += ../../softdevice/common/softdevice_handler/softdevice_handler.c
C_SOURCE_FILES += ../../softdevice/common/softdevice_handler/softdevice_handler_appsh.c
C_SOURCE_FILES += $(SRC_PATH)/tusb_descriptors.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)/device/usbd.c
C_SOURCE_FILES += $(TUSB_PATH)/class/cdc/cdc_device.c
C_SOURCE_FILES += $(TUSB_PATH)/tusb.c
#******************************************************************************
# Assembly Files
@ -130,6 +139,7 @@ ASM_SOURCE_FILES = $(SDK_PATH)/toolchain/gcc/gcc_startup_nrf52840.S
#******************************************************************************
INC_PATHS += -I$(SRC_PATH)/
INC_PATHS += -I$(TUSB_PATH)/
INC_PATHS += -I$(SDK_PATH)/libraries/bootloader_dfu/hci_transport
INC_PATHS += -I$(SDK_PATH)/libraries/bootloader_dfu
@ -146,6 +156,8 @@ INC_PATHS += -I$(SDK_PATH)/drivers_nrf/hal
INC_PATHS += -I$(SDK_PATH)/drivers_nrf/config
INC_PATHS += -I$(SDK_PATH)/drivers_nrf/delay
INC_PATHS += -I$(SDK_PATH)/drivers_nrf/uart
INC_PATHS += -I$(SDK_PATH)/drivers_nrf/power
INC_PATHS += -I$(SDK_PATH)/drivers_nrf/usbd
INC_PATHS += -I../../softdevice/common
INC_PATHS += -I../../softdevice/common/softdevice_handler/

View File

@ -684,7 +684,7 @@
// <e> POWER_ENABLED - nrf_drv_power - POWER peripheral driver
//==========================================================
#ifndef POWER_ENABLED
#define POWER_ENABLED 0
#define POWER_ENABLED 1
#endif
// <o> POWER_CONFIG_IRQ_PRIORITY - Interrupt priority

95
src/tusb_config.h Normal file
View File

@ -0,0 +1,95 @@
/**************************************************************************/
/*!
@file tusb_config.h
@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.
*/
/**************************************************************************/
#ifndef _TUSB_TUSB_CONFIG_H_
#define _TUSB_TUSB_CONFIG_H_
#ifdef __cplusplus
extern "C" {
#endif
//--------------------------------------------------------------------+
// CONTROLLER CONFIGURATION
//--------------------------------------------------------------------+
//#define TUSB_CFG_MCU will be passed from IDE/command line for easy board/mcu switching
#define TUSB_CFG_CONTROLLER_0_MODE (TUSB_MODE_DEVICE)
//#define TUSB_CFG_CONTROLLER_1_MODE (TUSB_MODE_DEVICE)
//--------------------------------------------------------------------+
// DEVICE CONFIGURATION
//--------------------------------------------------------------------+
#define TUSB_CFG_DEVICE_CONTROL_ENDOINT_SIZE 64
//------------- CLASS -------------//
#define TUSB_CFG_DEVICE_HID_KEYBOARD 0
#define TUSB_CFG_DEVICE_HID_MOUSE 0
#define TUSB_CFG_DEVICE_HID_GENERIC 0 // not supported yet
#define TUSB_CFG_DEVICE_MSC 0
#define TUSB_CFG_DEVICE_CDC 1
//--------------------------------------------------------------------+
// COMMON CONFIGURATION
//--------------------------------------------------------------------+
#define TUSB_CFG_DEBUG 2
#define TUSB_CFG_OS TUSB_OS_NONE // be passed from IDE/command line for easy project switching
//#define TUSB_CFG_OS_TASK_PRIO 0 // be passed from IDE/command line for easy project switching
#define TUSB_CFG_TICKS_HZ 1000
//#define TUSB_CFG_OS TUSB_OS_NONE
//--------------------------------------------------------------------+
// USB RAM PLACEMENT
//--------------------------------------------------------------------+
#define TUSB_CFG_ATTR_USBRAM
// LPC11uxx and LPC13uxx requires each buffer has to be 64-byte alignment
#if TUSB_CFG_MCU == MCU_LPC11UXX || TUSB_CFG_MCU == MCU_LPC13UXX
#define ATTR_USB_MIN_ALIGNMENT ATTR_ALIGNED(64)
#elif defined NRF52840_XXAA
#define ATTR_USB_MIN_ALIGNMENT ATTR_ALIGNED(4)
#else
#define ATTR_USB_MIN_ALIGNMENT
#endif
#ifdef __cplusplus
}
#endif
#endif /* _TUSB_TUSB_CONFIG_H_ */

299
src/tusb_descriptors.c Normal file
View File

@ -0,0 +1,299 @@
/**************************************************************************/
/*!
@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_descriptors.h"
//--------------------------------------------------------------------+
// USB DEVICE DESCRIPTOR
//--------------------------------------------------------------------+
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 = TUSB_CFG_DEVICE_CONTROL_ENDOINT_SIZE,
.idVendor = CFG_VENDORID,
.idProduct = CFG_PRODUCTID,
.bcdDevice = 0x0100,
.iManufacturer = 0x01,
.iProduct = 0x02,
.iSerialNumber = 0x03,
.bNumConfigurations = 0x01
};
//--------------------------------------------------------------------+
// USB COFNIGURATION DESCRIPTOR
//--------------------------------------------------------------------+
app_descriptor_configuration_t const desc_configuration =
{
.configuration =
{
.bLength = sizeof(tusb_desc_configuration_t),
.bDescriptorType = TUSB_DESC_CONFIGURATION,
.wTotalLength = sizeof(app_descriptor_configuration_t),
.bNumInterfaces = ITF_TOTAL,
.bConfigurationValue = 1,
.iConfiguration = 0x00,
.bmAttributes = TUSB_DESC_CONFIG_ATT_BUS_POWER,
.bMaxPower = TUSB_DESC_CONFIG_POWER_MA(500)
},
#if TUSB_CFG_DEVICE_CDC
// 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 = 0x00
},
.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 = CDC_EDPT_NOTIF,
.bmAttributes = { .xfer = TUSB_XFER_INTERRUPT },
.wMaxPacketSize = { .size = CDC_EDPT_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 = CDC_EDPT_OUT,
.bmAttributes = { .xfer = TUSB_XFER_BULK },
.wMaxPacketSize = { .size = CDC_EDPT_SIZE },
.bInterval = 0
},
.ep_in =
{
.bLength = sizeof(tusb_desc_endpoint_t),
.bDescriptorType = TUSB_DESC_ENDPOINT,
.bEndpointAddress = CDC_EDPT_IN,
.bmAttributes = { .xfer = TUSB_XFER_BULK },
.wMaxPacketSize = { .size = CDC_EDPT_SIZE },
.bInterval = 0
},
},
#endif
#if TUSB_CFG_DEVICE_MSC
.msc =
{
.interface =
{
.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 = 0x07
},
.ep_out =
{
.bLength = sizeof(tusb_desc_endpoint_t),
.bDescriptorType = TUSB_DESC_ENDPOINT,
.bEndpointAddress = MSC_EDPT_OUT,
.bmAttributes = { .xfer = TUSB_XFER_BULK },
.wMaxPacketSize = { .size = MSC_EDPT_SIZE},
.bInterval = 1
},
.ep_in =
{
.bLength = sizeof(tusb_desc_endpoint_t),
.bDescriptorType = TUSB_DESC_ENDPOINT,
.bEndpointAddress = MSC_EDPT_IN,
.bmAttributes = { .xfer = TUSB_XFER_BULK },
.wMaxPacketSize = { .size = MSC_EDPT_SIZE},
.bInterval = 1
}
}
#endif
};
//--------------------------------------------------------------------+
// STRING DESCRIPTORS
//--------------------------------------------------------------------+
#define STRING_LEN_UNICODE(n) (2 + (2*(n))) // also includes 2 byte header
#define ENDIAN_BE16_FROM( high, low) ENDIAN_BE16(high << 8 | low)
// array of pointer to string descriptors
uint16_t const * const string_descriptor_arr [] =
{
[0] = (uint16_t []) { // supported language
ENDIAN_BE16_FROM( STRING_LEN_UNICODE(1), TUSB_DESC_STRING ),
0x0409 // English
},
[1] = (uint16_t []) { // manufacturer
ENDIAN_BE16_FROM( STRING_LEN_UNICODE(11), TUSB_DESC_STRING),
't', 'i', 'n', 'y', 'u', 's', 'b', '.', 'o', 'r', 'g' // len = 11
},
[2] = (uint16_t []) { // product
ENDIAN_BE16_FROM( STRING_LEN_UNICODE(14), TUSB_DESC_STRING),
't', 'i', 'n', 'y', 'u', 's', 'b', ' ', 'd', 'e', 'v', 'i', 'c', 'e' // len = 14
},
[3] = (uint16_t []) { // serials
ENDIAN_BE16_FROM( STRING_LEN_UNICODE(4), TUSB_DESC_STRING),
'1', '2', '3', '4' // len = 4
},
[4] = (uint16_t []) { // CDC Interface
ENDIAN_BE16_FROM( STRING_LEN_UNICODE(3), TUSB_DESC_STRING),
'c', 'd', 'c' // len = 3
},
[5] = (uint16_t []) { // Keyboard Interface
ENDIAN_BE16_FROM( STRING_LEN_UNICODE(5), TUSB_DESC_STRING),
'm', 'o', 'u', 's', 'e' // len = 5
},
[6] = (uint16_t []) { // Keyboard Interface
ENDIAN_BE16_FROM( STRING_LEN_UNICODE(8), TUSB_DESC_STRING),
'k', 'e', 'y', 'b', 'o', 'a', 'r', 'd' // len = 8
},
[7] = (uint16_t []) { // MSC Interface
ENDIAN_BE16_FROM( STRING_LEN_UNICODE(3), TUSB_DESC_STRING),
'm', 's', 'c' // len = 3
}
};
//--------------------------------------------------------------------+
// TINYUSB Descriptors Pointer (this variable is required by the stack)
//--------------------------------------------------------------------+
tusbd_descriptor_pointer_t tusbd_descriptor_pointers =
{
.p_device = (uint8_t const * ) &desc_device,
.p_configuration = (uint8_t const * ) &desc_configuration,
.p_string_arr = (uint8_t const **) string_descriptor_arr,
};

121
src/tusb_descriptors.h Normal file
View File

@ -0,0 +1,121 @@
/**************************************************************************/
/*!
@file tusb_descriptors.h
@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.
*/
/**************************************************************************/
#ifndef _TUSB_DESCRIPTORS_H_
#define _TUSB_DESCRIPTORS_H_
#include "tusb.h"
//--------------------------------------------------------------------+
// Descriptors Value (calculated by enabled Classes)
//--------------------------------------------------------------------+
#define CFG_VENDORID 0xCAFE
//#define CFG_PRODUCTID 0x4567 // use auto product id to prevent conflict with pc's driver
// each combination of interfaces need to have a unique productid, as windows will bind & remember device driver after the first plug.
// Auto ProductID layout's Bitmap: (MSB) MassStorage | Generic | Mouse | Key | CDC (LSB)
#ifndef CFG_PRODUCTID
#define PRODUCTID_BITMAP(interface, n) ( (TUSB_CFG_DEVICE_##interface) << (n) )
#define CFG_PRODUCTID (0x4000 | ( PRODUCTID_BITMAP(CDC, 0) | PRODUCTID_BITMAP(HID_KEYBOARD, 1) | \
PRODUCTID_BITMAP(HID_MOUSE, 2) | PRODUCTID_BITMAP(HID_GENERIC, 3) | \
PRODUCTID_BITMAP(MSC, 4) ) )
#endif
#define ITF_NUM_CDC 0
#define ITF_NUM_MSC 2
// total number of interfaces
#define ITF_TOTAL (TUSB_CFG_DEVICE_CDC*2 + TUSB_CFG_DEVICE_MSC)
//--------------------------------------------------------------------+
// Endpoints Address & Max Packet Size
//--------------------------------------------------------------------+
#define EDPT_IN(x) (0x80 | (x))
#define EDPT_OUT(x) (x)
#define CDC_EDPT_NOTIF EDPT_IN (1)
#define CDC_EDPT_NOTIF_SIZE 8
#define CDC_EDPT_OUT EDPT_OUT(2)
#define CDC_EDPT_IN EDPT_IN (2)
#define CDC_EDPT_SIZE 64
#define MSC_EDPT_OUT EDPT_OUT(3)
#define MSC_EDPT_IN EDPT_IN(3)
#define MSC_EDPT_SIZE 64
//--------------------------------------------------------------------+
// CONFIGURATION DESCRIPTOR
//--------------------------------------------------------------------+
typedef struct ATTR_PACKED
{
tusb_desc_configuration_t configuration;
#if TUSB_CFG_DEVICE_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;
#endif
#if TUSB_CFG_DEVICE_MSC
struct ATTR_PACKED
{
tusb_desc_interface_t interface;
tusb_desc_endpoint_t ep_out;
tusb_desc_endpoint_t ep_in;
}msc;
#endif
} app_descriptor_configuration_t;
#endif

@ -1 +1 @@
Subproject commit 68f5c004d836a6d15dfe651de3333c7ab0cc7e5f
Subproject commit 7a77aed8fa67cf6740943cf25a00485d4f288cfb