merge with current master

This commit is contained in:
Peter Lawrence 2020-03-15 18:28:13 -05:00
commit e7efcb6fd5
251 changed files with 19656 additions and 41596 deletions

25
.gitattributes vendored Normal file
View File

@ -0,0 +1,25 @@
# Set the default behavior, in case people don't have core.autocrlf set.
* text=auto
*.c text
*.cpp text
*.h text
*.icf text
*.js text
*.json text
*.ld text
*.md text
*.mk text
*.py text
*.rst text
*.s text
*.txt text
*.xml text
*.yml text
Makefile text
# Windows-only Visual Studio things
*.sln text eol=crlf
*.csproj text eol=crlf

View File

@ -24,8 +24,9 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
example: ['board_test', 'cdc_dual_ports', 'cdc_msc', 'dfu_rt', 'hid_composite', example: ['board_test', 'cdc_dual_ports', 'cdc_msc', 'cdc_msc_freertos', 'dfu_rt',
'hid_generic_inout', 'midi_test', 'msc_dual_lun', 'usbtmc', 'webusb_serial'] 'hid_composite', 'hid_generic_inout', 'midi_test', 'msc_dual_lun', 'net_lwip_webserver',
'usbtmc', 'webusb_serial']
steps: steps:
- name: Setup Python - name: Setup Python
uses: actions/setup-python@v1 uses: actions/setup-python@v1

8
.gitmodules vendored
View File

@ -21,4 +21,10 @@
url = https://github.com/hathach/microchip_driver.git url = https://github.com/hathach/microchip_driver.git
[submodule "hw/mcu/nuvoton"] [submodule "hw/mcu/nuvoton"]
path = hw/mcu/nuvoton path = hw/mcu/nuvoton
url = https://github.com/majbthrd/nuc_driver.git url = https://github.com/majbthrd/nuc_driver.git
[submodule "lib/lwip"]
path = lib/lwip
url = https://git.savannah.nongnu.org/git/lwip.git
[submodule "lib/FreeRTOS"]
path = lib/FreeRTOS
url = https://github.com/FreeRTOS/FreeRTOS.git

View File

@ -25,9 +25,11 @@
* Board support for STM32F070RB Nucleo, STM32F303 Discovery * Board support for STM32F070RB Nucleo, STM32F303 Discovery
* **[Peter Lawrence](https://github.com/majbthrd)** * **[Peter Lawrence](https://github.com/majbthrd)**
* Nuvoton NUC 121, 125, 126 device driver port * Nuvoton NUC 120, 121, 125, 126, 505 device driver port
* Board support for NuTiny NUC121s, NUC125s, NUC126V * USBNET RNDIS, CDC-ECM, CDC-EEM class driver
* Complete multiple class interfaces & add cdc_dual_ports example * Added `net_lwip_webserver` example for demonstration of usbnet with lwip
* Board support for NuTiny NUC120, NUC121s, NUC125s, NUC126V, NUC505
* Complete multiple class interfaces & add cdc_dual_ports example
* **[Scott Shawcroft](https://github.com/tannewt)** * **[Scott Shawcroft](https://github.com/tannewt)**
* SAMD21 and SAMD51 device driver port * SAMD21 and SAMD51 device driver port

View File

@ -38,7 +38,7 @@ The stack supports the following MCUs:
- **Sony:** CXD56 - **Sony:** CXD56
- **ST:** STM32 series: L0, F0, F1, F2, F3, F4, F7, H7 (device only) - **ST:** STM32 series: L0, F0, F1, F2, F3, F4, F7, H7 (device only)
- **[ValentyUSB](https://github.com/im-tomu/valentyusb)** eptri - **[ValentyUSB](https://github.com/im-tomu/valentyusb)** eptri
- **Nuvoton:** NUC121/NUC125, NUC126 - **Nuvoton:** NUC120, NUC121/NUC125, NUC126, NUC505
[Here is the list of supported Boards](docs/boards.md) that can be used with provided examples. [Here is the list of supported Boards](docs/boards.md) that can be used with provided examples.
@ -50,6 +50,7 @@ Supports multiple device configurations by dynamically changing usb descriptors.
- Human Interface Device (HID): Generic (In & Out), Keyboard, Mouse, Gamepad etc ... - Human Interface Device (HID): Generic (In & Out), Keyboard, Mouse, Gamepad etc ...
- Mass Storage Class (MSC): with multiple LUNs - Mass Storage Class (MSC): with multiple LUNs
- Musical Instrument Digital Interface (MIDI) - Musical Instrument Digital Interface (MIDI)
- Network with RNDIS, CDC-ECM, CDC-EEM (work in progress)
- Vendor-specific class support with generic In & Out endpoints. Can be used with MS OS 2.0 compatible descriptor to load winUSB driver without INF file. - Vendor-specific class support with generic In & Out endpoints. Can be used with MS OS 2.0 compatible descriptor to load winUSB driver without INF file.
- [WebUSB](https://github.com/WICG/webusb) with vendor-specific class - [WebUSB](https://github.com/WICG/webusb) with vendor-specific class

View File

@ -13,14 +13,18 @@ This code base already had supported for a handful of following boards (sorted a
- [Adafruit Circuit Playground Express](https://www.adafruit.com/product/3333) - [Adafruit Circuit Playground Express](https://www.adafruit.com/product/3333)
- [Adafruit Feather M0 Express](https://www.adafruit.com/product/3403) - [Adafruit Feather M0 Express](https://www.adafruit.com/product/3403)
- [Adafruit Metro M0 Express](https://www.adafruit.com/product/3505)
- [Adafruit Feather M4 Express](https://www.adafruit.com/product/3857) - [Adafruit Feather M4 Express](https://www.adafruit.com/product/3857)
- [Adafruit ItsyBitsy M0 Express](https://www.adafruit.com/product/3727)
- [Adafruit ItsyBitsy M4 Express](https://www.adafruit.com/product/3800)
- [Adafruit Metro M0 Express](https://www.adafruit.com/product/3505)
- [Adafruit Metro M4 Express](https://www.adafruit.com/product/3382) - [Adafruit Metro M4 Express](https://www.adafruit.com/product/3382)
### Nordic nRF5x ### Nordic nRF5x
- [Adafruit Feather nRF52840 Express](https://www.adafruit.com/product/4062)
- [Adafruit Circuit Playground Bluefruit](https://www.adafruit.com/product/4333) - [Adafruit Circuit Playground Bluefruit](https://www.adafruit.com/product/4333)
- [Adafruit CLUE](https://www.adafruit.com/product/4500)
- [Adafruit Feather nRF52840 Express](https://www.adafruit.com/product/4062)
- [Adafruit Feather nRF52840 Sense](https://www.adafruit.com/product/4516)
- [Maker Diary nRF52840 MDK Dongle](https://wiki.makerdiary.com/nrf52840-mdk-usb-dongle) - [Maker Diary nRF52840 MDK Dongle](https://wiki.makerdiary.com/nrf52840-mdk-usb-dongle)
- [Nordic nRF52840 Development Kit (aka pca10056)](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-DK) - [Nordic nRF52840 Development Kit (aka pca10056)](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-DK)
- [Nordic nRF52840 Dongle (aka pca10059)](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-Dongle) - [Nordic nRF52840 Dongle (aka pca10059)](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-Dongle)
@ -29,9 +33,11 @@ This code base already had supported for a handful of following boards (sorted a
### Nuvoton ### Nuvoton
- NuTiny SDK NUC120
- [NuTiny NUC121S](https://direct.nuvoton.com/en/nutiny-nuc121s) - [NuTiny NUC121S](https://direct.nuvoton.com/en/nutiny-nuc121s)
- [NuTiny NUC125S](https://direct.nuvoton.com/en/nutiny-nuc125s) - [NuTiny NUC125S](https://direct.nuvoton.com/en/nutiny-nuc125s)
- [NuTiny NUC126V](https://direct.nuvoton.com/en/nutiny-nuc126v) - [NuTiny NUC126V](https://direct.nuvoton.com/en/nutiny-nuc126v)
- [NuTiny SDK NUC505Y](https://direct.nuvoton.com/en/nutiny-nuc505y)
### NXP iMX RT ### NXP iMX RT

View File

@ -39,7 +39,7 @@
#error CFG_TUSB_MCU must be defined #error CFG_TUSB_MCU must be defined
#endif #endif
#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX #if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || CFG_TUSB_MCU == OPT_MCU_NUC505
#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED) #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED)
#else #else
#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE #define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE

View File

@ -130,8 +130,10 @@ static uint16_t _desc_str[32];
// Invoked when received GET STRING DESCRIPTOR request // Invoked when received GET STRING DESCRIPTOR request
// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete // 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) uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid)
{ {
(void) langid;
uint8_t chr_count; uint8_t chr_count;
if ( index == 0) if ( index == 0)

View File

@ -39,7 +39,7 @@
#error CFG_TUSB_MCU must be defined #error CFG_TUSB_MCU must be defined
#endif #endif
#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX #if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || CFG_TUSB_MCU == OPT_MCU_NUC505
#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED) #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED)
#else #else
#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE #define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE
@ -68,6 +68,7 @@
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// DEVICE CONFIGURATION // DEVICE CONFIGURATION
//-------------------------------------------------------------------- //--------------------------------------------------------------------
#ifndef CFG_TUD_ENDPOINT0_SIZE #ifndef CFG_TUD_ENDPOINT0_SIZE
#define CFG_TUD_ENDPOINT0_SIZE 64 #define CFG_TUD_ENDPOINT0_SIZE 64
#endif #endif

View File

@ -95,7 +95,7 @@ enum
#define EPNUM_MSC_IN 0x85 #define EPNUM_MSC_IN 0x85
#elif CFG_TUSB_MCU == OPT_MCU_SAMG #elif CFG_TUSB_MCU == OPT_MCU_SAMG
// SAMG doesn't support a same endpoint number with IN and OUT // SAMG doesn't support a same endpoint number with different direction IN and OUT
// e.g EP1 OUT & EP1 IN cannot exist together // e.g EP1 OUT & EP1 IN cannot exist together
#define EPNUM_CDC_NOTIF 0x81 #define EPNUM_CDC_NOTIF 0x81
#define EPNUM_CDC_OUT 0x02 #define EPNUM_CDC_OUT 0x02
@ -155,8 +155,10 @@ static uint16_t _desc_str[32];
// Invoked when received GET STRING DESCRIPTOR request // Invoked when received GET STRING DESCRIPTOR request
// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete // 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) uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid)
{ {
(void) langid;
uint8_t chr_count; uint8_t chr_count;
if ( index == 0) if ( index == 0)

View File

@ -0,0 +1,27 @@
include ../../../tools/top.mk
include ../../make.mk
FREERTOS_SRC = lib/FreeRTOS/FreeRTOS/Source
INC += \
src \
$(TOP)/hw \
$(TOP)/$(FREERTOS_SRC)/include \
$(TOP)/$(FREERTOS_SRC)/portable/GCC/$(FREERTOS_PORT)
# Example source
EXAMPLE_SOURCE += $(wildcard src/*.c)
SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE))
# FreeRTOS source, all files in port folder
SRC_C += \
$(FREERTOS_SRC)/list.c \
$(FREERTOS_SRC)/queue.c \
$(FREERTOS_SRC)/tasks.c \
$(FREERTOS_SRC)/timers.c \
$(subst ../../../,,$(wildcard ../../../$(FREERTOS_SRC)/portable/GCC/$(FREERTOS_PORT)/*.c))
# FreeRTOS (lto + Os) linker issue
LDFLAGS += -Wl,--undefined=vTaskSwitchContext
include ../../rules.mk

View File

@ -41,8 +41,84 @@
* *
* See http://www.freertos.org/a00110.html. * See http://www.freertos.org/a00110.html.
*----------------------------------------------------------*/ *----------------------------------------------------------*/
#include "nrf.h"
// for OPT_MCU_
#include "tusb_option.h"
#if CFG_TUSB_MCU == OPT_MCU_LPC11UXX || CFG_TUSB_MCU == OPT_MCU_LPC13XX || \
CFG_TUSB_MCU == OPT_MCU_LPC15XX || CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || \
CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC18XX || \
CFG_TUSB_MCU == OPT_MCU_LPC40XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX
#include "chip.h"
#elif CFG_TUSB_MCU == OPT_MCU_LPC51UXX || CFG_TUSB_MCU == OPT_MCU_LPC54XXX || \
CFG_TUSB_MCU == OPT_MCU_LPC55XX
#include "fsl_device_registers.h"
#elif CFG_TUSB_MCU == OPT_MCU_NRF5X
#include "nrf.h"
#elif CFG_TUSB_MCU == OPT_MCU_SAMD21 || CFG_TUSB_MCU == OPT_MCU_SAMD51
#include "sam.h"
#elif CFG_TUSB_MCU == OPT_MCU_SAMG
#undef LITTLE_ENDIAN // hack to suppress "LITTLE_ENDIAN" redefined
#include "sam.h"
#elif CFG_TUSB_MCU == OPT_MCU_STM32F0
#include "stm32f0xx.h"
#elif CFG_TUSB_MCU == OPT_MCU_STM32F1
#include "stm32f1xx.h"
#elif CFG_TUSB_MCU == OPT_MCU_STM32F2
#include "stm32f2xx.h"
#elif CFG_TUSB_MCU == OPT_MCU_STM32F3
#include "stm32f3xx.h"
#elif CFG_TUSB_MCU == OPT_MCU_STM32F4
#include "stm32f4xx.h"
#elif CFG_TUSB_MCU == OPT_MCU_STM32F7
#include "stm32f7xx.h"
#elif CFG_TUSB_MCU == OPT_MCU_STM32H7
#include "stm32h7xx.h"
#elif CFG_TUSB_MCU == OPT_MCU_STM32L0
#include "stm32l0xx.h"
#elif CFG_TUSB_MCU == OPT_MCU_STM32L1
#include "stm32l1xx.h"
#elif CFG_TUSB_MCU == OPT_MCU_STM32L4
#include "stm32l4xx.h"
#elif CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX
#include "fsl_device_registers.h"
#elif CFG_TUSB_MCU == OPT_MCU_NUC120
#include "NUC100Series.h"
#elif CFG_TUSB_MCU == OPT_MCU_NUC121 || CFG_TUSB_MCU == OPT_MCU_NUC126
#include "NuMicro.h"
#elif CFG_TUSB_MCU == OPT_MCU_NUC505
#include "NUC505Series.h"
#else
#error "FreeRTOSConfig.h need to include low level mcu header for configuration"
#endif
extern uint32_t SystemCoreClock;
/* Cortex M23/M33 port configuration. */
#define configENABLE_MPU 0
#define configENABLE_FPU 1
#define configENABLE_TRUSTZONE 0
#define configMINIMAL_SECURE_STACK_SIZE ( 1024 )
#define configUSE_PREEMPTION 1 #define configUSE_PREEMPTION 1
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
@ -50,7 +126,7 @@
#define configTICK_RATE_HZ ( 1000 ) #define configTICK_RATE_HZ ( 1000 )
#define configMAX_PRIORITIES ( 5 ) #define configMAX_PRIORITIES ( 5 )
#define configMINIMAL_STACK_SIZE ( 128 ) #define configMINIMAL_STACK_SIZE ( 128 )
#define configTOTAL_HEAP_SIZE ( 16*1024 ) #define configTOTAL_HEAP_SIZE ( 0*1024 ) // dynamic is not used
#define configMAX_TASK_NAME_LEN 16 #define configMAX_TASK_NAME_LEN 16
#define configUSE_16_BIT_TICKS 0 #define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 1 #define configIDLE_SHOULD_YIELD 1
@ -64,7 +140,7 @@
#define configENABLE_BACKWARD_COMPATIBILITY 1 #define configENABLE_BACKWARD_COMPATIBILITY 1
#define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_STATIC_ALLOCATION 1
#define configSUPPORT_DYNAMIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 0
/* Hook function related definitions. */ /* Hook function related definitions. */
#define configUSE_IDLE_HOOK 0 #define configUSE_IDLE_HOOK 0
@ -108,18 +184,18 @@
/* Define to trap errors during development. */ /* Define to trap errors during development. */
// Halt CPU (breakpoint) when hitting error, only apply for Cortex M3, M4, M7 // Halt CPU (breakpoint) when hitting error, only apply for Cortex M3, M4, M7
#if defined(__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__) #if defined(__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__)
#define configASSERT(_exp) \ #define configASSERT(_exp) \
do {\ do {\
if ( !(_exp) ) { \ if ( !(_exp) ) { \
volatile uint32_t* ARM_CM_DHCSR = ((volatile uint32_t*) 0xE000EDF0UL); /* Cortex M CoreDebug->DHCSR */ \ volatile uint32_t* ARM_CM_DHCSR = ((volatile uint32_t*) 0xE000EDF0UL); /* Cortex M CoreDebug->DHCSR */ \
if ( (*ARM_CM_DHCSR) & 1UL ) { /* Only halt mcu if debugger is attached */ \ if ( (*ARM_CM_DHCSR) & 1UL ) { /* Only halt mcu if debugger is attached */ \
taskDISABLE_INTERRUPTS(); \ taskDISABLE_INTERRUPTS(); \
__asm("BKPT #0\n"); \ __asm("BKPT #0\n"); \
}\
}\ }\
}\ } while(0)
} while(0)
#else #else
#define configASSERT( x ) #define configASSERT( x )
#endif #endif
/* FreeRTOS hooks to NVIC vectors */ /* FreeRTOS hooks to NVIC vectors */
@ -144,15 +220,6 @@
routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL
INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
PRIORITY THAN THIS! (higher priorities are lower numeric values. */ PRIORITY THAN THIS! (higher priorities are lower numeric values. */
/* SD priority
* 0: SD timing critical
* 1: SD memory protection
* 2: App Highest
* 3: App High
* 4: SD non-time-critical
* 5+ Remaining Application
*/
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 2 #define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 2
/* Interrupt priorities used by the kernel port layer itself. These are generic /* Interrupt priorities used by the kernel port layer itself. These are generic

View File

@ -36,8 +36,6 @@
#include "bsp/board.h" #include "bsp/board.h"
#include "tusb.h" #include "tusb.h"
#include "usb_descriptors.h"
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// MACRO CONSTANT TYPEDEF PROTYPES // MACRO CONSTANT TYPEDEF PROTYPES
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
@ -53,12 +51,24 @@ enum {
BLINK_SUSPENDED = 2500, BLINK_SUSPENDED = 2500,
}; };
// static timer
StaticTimer_t static_blink;
TimerHandle_t blink_tm; TimerHandle_t blink_tm;
// static task for usbd
#define USBD_STACK_SIZE 150
StackType_t stack_usbd[USBD_STACK_SIZE];
StaticTask_t static_task_usbd;
// static task for cdc
#define CDC_STACK_SZIE 128
StackType_t stack_cdc[CDC_STACK_SZIE];
StaticTask_t static_task_cdc;
void led_blinky_cb(TimerHandle_t xTimer); void led_blinky_cb(TimerHandle_t xTimer);
void usb_device_task(void* param); void usb_device_task(void* param);
void cdc_task(void* params); void cdc_task(void* params);
void hid_task(void* params);
/*------------- MAIN -------------*/ /*------------- MAIN -------------*/
int main(void) int main(void)
@ -66,21 +76,17 @@ int main(void)
board_init(); board_init();
// soft timer for blinky // soft timer for blinky
blink_tm = xTimerCreate(NULL, pdMS_TO_TICKS(BLINK_NOT_MOUNTED), true, NULL, led_blinky_cb); blink_tm = xTimerCreateStatic(NULL, pdMS_TO_TICKS(BLINK_NOT_MOUNTED), true, NULL, led_blinky_cb, &static_blink);
xTimerStart(blink_tm, 0); xTimerStart(blink_tm, 0);
tusb_init(); tusb_init();
// Create a task for tinyusb device stack // Create a task for tinyusb device stack
xTaskCreate( usb_device_task, "usbd", 150, NULL, configMAX_PRIORITIES-1, NULL); (void) xTaskCreateStatic( usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES-1, stack_usbd, &static_task_usbd);
// Create task // Create task
#if CFG_TUD_CDC #if CFG_TUD_CDC
xTaskCreate( cdc_task, "cdc", 128, NULL, configMAX_PRIORITIES-2, NULL); (void) xTaskCreateStatic( cdc_task, "cdc", CDC_STACK_SZIE, NULL, configMAX_PRIORITIES-2, stack_cdc, &static_task_cdc);
#endif
#if CFG_TUD_HID
xTaskCreate( hid_task, "hid", 128, NULL, configMAX_PRIORITIES-2, NULL);
#endif #endif
vTaskStartScheduler(); vTaskStartScheduler();
@ -134,6 +140,7 @@ void tud_resume_cb(void)
xTimerChangePeriod(blink_tm, pdMS_TO_TICKS(BLINK_MOUNTED), 0); xTimerChangePeriod(blink_tm, pdMS_TO_TICKS(BLINK_MOUNTED), 0);
} }
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// USB CDC // USB CDC
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
@ -189,97 +196,7 @@ void tud_cdc_rx_cb(uint8_t itf)
(void) itf; (void) itf;
} }
#endif #endif // CFG_TUD_CDC
//--------------------------------------------------------------------+
// USB HID
//--------------------------------------------------------------------+
#if CFG_TUD_HID
void hid_task(void* params)
{
(void) params;
while (1)
{
// Poll every 10ms
vTaskDelay(pdMS_TO_TICKS(10));
uint32_t const btn = board_button_read();
// Remote wakeup
if ( tud_suspended() && btn )
{
// Wake up host if we are in suspend mode
// and REMOTE_WAKEUP feature is enabled by host
tud_remote_wakeup();
}
/*------------- Mouse -------------*/
if ( tud_hid_ready() )
{
if ( btn )
{
int8_t const delta = 5;
// no button, right + down, no scroll pan
tud_hid_mouse_report(REPORT_ID_MOUSE, 0x00, delta, delta, 0, 0);
// delay a bit before attempt to send keyboard report
vTaskDelay(pdMS_TO_TICKS(2));
}
}
/*------------- Keyboard -------------*/
if ( tud_hid_ready() )
{
// use to avoid send multiple consecutive zero report for keyboard
static bool has_key = false;
if ( btn )
{
uint8_t keycode[6] = { 0 };
keycode[0] = HID_KEY_A;
tud_hid_keyboard_report(REPORT_ID_KEYBOARD, 0, keycode);
has_key = true;
}else
{
// send empty key report if previously has key pressed
if (has_key) tud_hid_keyboard_report(REPORT_ID_KEYBOARD, 0, NULL);
has_key = false;
}
}
}
}
// Invoked when received GET_REPORT control request
// Application must fill buffer report's content and return its length.
// Return zero will cause the stack to STALL request
uint16_t tud_hid_get_report_cb(uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen)
{
// TODO not Implemented
(void) report_id;
(void) report_type;
(void) buffer;
(void) reqlen;
return 0;
}
// Invoked when received SET_REPORT control request or
// received data on OUT endpoint ( Report ID = 0, Type = 0 )
void tud_hid_set_report_cb(uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize)
{
// TODO not Implemented
(void) report_id;
(void) report_type;
(void) buffer;
(void) bufsize;
}
#endif
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// BLINKING TASK // BLINKING TASK

View File

@ -220,18 +220,6 @@ int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer,
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);

View File

@ -39,7 +39,7 @@
#error CFG_TUSB_MCU must be defined #error CFG_TUSB_MCU must be defined
#endif #endif
#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX #if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || CFG_TUSB_MCU == OPT_MCU_NUC505
#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED) #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED)
#else #else
#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE #define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE
@ -76,7 +76,7 @@
//------------- CLASS -------------// //------------- CLASS -------------//
#define CFG_TUD_CDC 1 #define CFG_TUD_CDC 1
#define CFG_TUD_MSC 1 #define CFG_TUD_MSC 1
#define CFG_TUD_HID 1 #define CFG_TUD_HID 0
#define CFG_TUD_MIDI 0 #define CFG_TUD_MIDI 0
#define CFG_TUD_VENDOR 0 #define CFG_TUD_VENDOR 0

View File

@ -24,7 +24,6 @@
*/ */
#include "tusb.h" #include "tusb.h"
#include "usb_descriptors.h"
/* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. /* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug.
* Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC.
@ -45,17 +44,11 @@ tusb_desc_device_t const desc_device =
.bDescriptorType = TUSB_DESC_DEVICE, .bDescriptorType = TUSB_DESC_DEVICE,
.bcdUSB = 0x0200, .bcdUSB = 0x0200,
#if CFG_TUD_CDC
// Use Interface Association Descriptor (IAD) for CDC // Use Interface Association Descriptor (IAD) for CDC
// As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1) // As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1)
.bDeviceClass = TUSB_CLASS_MISC, .bDeviceClass = TUSB_CLASS_MISC,
.bDeviceSubClass = MISC_SUBCLASS_COMMON, .bDeviceSubClass = MISC_SUBCLASS_COMMON,
.bDeviceProtocol = MISC_PROTOCOL_IAD, .bDeviceProtocol = MISC_PROTOCOL_IAD,
#else
.bDeviceClass = 0x00,
.bDeviceSubClass = 0x00,
.bDeviceProtocol = 0x00,
#endif
.bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
@ -77,84 +70,63 @@ uint8_t const * tud_descriptor_device_cb(void)
return (uint8_t const *) &desc_device; return (uint8_t const *) &desc_device;
} }
//--------------------------------------------------------------------+
// HID Report Descriptor
//--------------------------------------------------------------------+
#if CFG_TUD_HID
uint8_t const desc_hid_report[] =
{
TUD_HID_REPORT_DESC_KEYBOARD( HID_REPORT_ID(REPORT_ID_KEYBOARD), ),
TUD_HID_REPORT_DESC_MOUSE ( HID_REPORT_ID(REPORT_ID_MOUSE), )
};
// Invoked when received GET HID REPORT DESCRIPTOR
// Application return pointer to descriptor
// Descriptor contents must exist long enough for transfer to complete
uint8_t const * tud_hid_descriptor_report_cb(void)
{
return desc_hid_report;
}
#endif
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// Configuration Descriptor // Configuration Descriptor
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
enum enum
{ {
#if CFG_TUD_CDC
ITF_NUM_CDC = 0, ITF_NUM_CDC = 0,
ITF_NUM_CDC_DATA, ITF_NUM_CDC_DATA,
#endif
#if CFG_TUD_MSC
ITF_NUM_MSC, ITF_NUM_MSC,
#endif
#if CFG_TUD_HID
ITF_NUM_HID,
#endif
ITF_NUM_TOTAL ITF_NUM_TOTAL
}; };
#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + CFG_TUD_CDC*TUD_CDC_DESC_LEN + CFG_TUD_MSC*TUD_MSC_DESC_LEN + CFG_TUD_HID*TUD_HID_DESC_LEN) #define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_DESC_LEN + TUD_MSC_DESC_LEN)
#if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX #if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX
// LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number // LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number
// 0 control, 1 In, 2 Bulk, 3 Iso, 4 In etc ... // 0 control, 1 In, 2 Bulk, 3 Iso, 4 In, 5 Bulk etc ...
// Note: since CDC EP ( 1 & 2), HID (4) are spot-on, thus we only need to force #define EPNUM_CDC_NOTIF 0x81
// endpoint number for MSC to 5 #define EPNUM_CDC_OUT 0x02
#define EPNUM_MSC 0x05 #define EPNUM_CDC_IN 0x82
#define EPNUM_MSC_OUT 0x05
#define EPNUM_MSC_IN 0x85
#elif CFG_TUSB_MCU == OPT_MCU_SAMG
// SAMG doesn't support a same endpoint number with different direction IN and OUT
// e.g EP1 OUT & EP1 IN cannot exist together
#define EPNUM_CDC_NOTIF 0x81
#define EPNUM_CDC_OUT 0x02
#define EPNUM_CDC_IN 0x83
#define EPNUM_MSC_OUT 0x04
#define EPNUM_MSC_IN 0x85
#else #else
#define EPNUM_MSC 0x03 #define EPNUM_CDC_NOTIF 0x81
#define EPNUM_CDC_OUT 0x02
#define EPNUM_CDC_IN 0x82
#define EPNUM_MSC_OUT 0x03
#define EPNUM_MSC_IN 0x83
#endif #endif
uint8_t const desc_configuration[] = uint8_t const desc_configuration[] =
{ {
// interface count, string index, total length, attribute, power in mA // Interface count, string index, total length, attribute, power in mA
TUD_CONFIG_DESCRIPTOR(ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), TUD_CONFIG_DESCRIPTOR(ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
#if CFG_TUD_CDC
// Interface number, string index, EP notification address and size, EP data address (out, in) and size. // Interface number, string index, EP notification address and size, EP data address (out, in) and size.
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, 0x81, 8, 0x02, 0x82, 64), TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 8, EPNUM_CDC_OUT, EPNUM_CDC_IN, 64),
#endif
#if CFG_TUD_MSC
// Interface number, string index, EP Out & EP In address, EP size // Interface number, string index, EP Out & EP In address, EP size
TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 5, EPNUM_MSC, 0x80 | EPNUM_MSC, 64), // highspeed 512 TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 5, EPNUM_MSC_OUT, EPNUM_MSC_IN, (CFG_TUSB_RHPORT0_MODE & OPT_MODE_HIGH_SPEED) ? 512 : 64),
#endif
#if CFG_TUD_HID
// Interface number, string index, protocol, report descriptor len, EP In address, size & polling interval
TUD_HID_DESCRIPTOR(ITF_NUM_HID, 6, HID_PROTOCOL_NONE, sizeof(desc_hid_report), 0x84, 16, 10)
#endif
}; };
// Invoked when received GET CONFIGURATION DESCRIPTOR // Invoked when received GET CONFIGURATION DESCRIPTOR
// Application return pointer to descriptor // Application return pointer to descriptor
// Descriptor contents must exist long enough for transfer to complete // Descriptor contents must exist long enough for transfer to complete
@ -177,15 +149,16 @@ char const* string_desc_arr [] =
"123456", // 3: Serials, should use chip ID "123456", // 3: Serials, should use chip ID
"TinyUSB CDC", // 4: CDC Interface "TinyUSB CDC", // 4: CDC Interface
"TinyUSB MSC", // 5: MSC Interface "TinyUSB MSC", // 5: MSC Interface
"TinyUSB HID" // 6: HID
}; };
static uint16_t _desc_str[32]; static uint16_t _desc_str[32];
// Invoked when received GET STRING DESCRIPTOR request // Invoked when received GET STRING DESCRIPTOR request
// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete // 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) uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid)
{ {
(void) langid;
uint8_t chr_count; uint8_t chr_count;
if ( index == 0) if ( index == 0)

View File

@ -1,26 +0,0 @@
include ../../../tools/top.mk
include ../../make.mk
INC += \
src \
$(TOP)/hw \
$(TOP)/lib/FreeRTOS/Source/include \
$(TOP)/lib/FreeRTOS/Source/portable/GCC/$(FREERTOS_PORT)
# Example source
EXAMPLE_SOURCE += $(wildcard src/*.c)
SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE))
# FreeRTOS source
SRC_C += \
lib/FreeRTOS/Source/list.c \
lib/FreeRTOS/Source/queue.c \
lib/FreeRTOS/Source/tasks.c \
lib/FreeRTOS/Source/timers.c \
lib/FreeRTOS/Source/portable/MemMang/heap_4.c \
lib/FreeRTOS/Source/portable/GCC/$(FREERTOS_PORT)/port.c \
# FreeRTOS (lto + Os) linker issue
LDFLAGS += -Wl,--undefined=vTaskSwitchContext
include ../../rules.mk

View File

@ -21,7 +21,7 @@
#error CFG_TUSB_MCU must be defined #error CFG_TUSB_MCU must be defined
#endif #endif
#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX #if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || CFG_TUSB_MCU == OPT_MCU_NUC505
#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED) #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED)
#else #else
#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE #define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE

View File

@ -193,8 +193,10 @@ static uint16_t _desc_str[32];
// Invoked when received GET STRING DESCRIPTOR request // Invoked when received GET STRING DESCRIPTOR request
// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete // 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) uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid)
{ {
(void) langid;
size_t chr_count; size_t chr_count;
if ( index == 0) if ( index == 0)

View File

@ -39,7 +39,7 @@
#error CFG_TUSB_MCU must be defined #error CFG_TUSB_MCU must be defined
#endif #endif
#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX #if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || CFG_TUSB_MCU == OPT_MCU_NUC505
#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED) #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED)
#else #else
#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE #define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE

View File

@ -134,8 +134,10 @@ static uint16_t _desc_str[32];
// Invoked when received GET STRING DESCRIPTOR request // Invoked when received GET STRING DESCRIPTOR request
// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete // 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) uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid)
{ {
(void) langid;
uint8_t chr_count; uint8_t chr_count;
if ( index == 0) if ( index == 0)

View File

@ -39,7 +39,7 @@
#error CFG_TUSB_MCU must be defined #error CFG_TUSB_MCU must be defined
#endif #endif
#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX #if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || CFG_TUSB_MCU == OPT_MCU_NUC505
#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED) #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED)
#else #else
#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE #define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE

View File

@ -132,8 +132,10 @@ static uint16_t _desc_str[32];
// Invoked when received GET STRING DESCRIPTOR request // Invoked when received GET STRING DESCRIPTOR request
// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete // 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) uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid)
{ {
(void) langid;
uint8_t chr_count; uint8_t chr_count;
if ( index == 0) if ( index == 0)

View File

@ -39,7 +39,7 @@
#error CFG_TUSB_MCU must be defined #error CFG_TUSB_MCU must be defined
#endif #endif
#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX #if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || CFG_TUSB_MCU == OPT_MCU_NUC505
#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED) #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED)
#else #else
#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE #define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE

View File

@ -123,8 +123,10 @@ static uint16_t _desc_str[32];
// Invoked when received GET STRING DESCRIPTOR request // Invoked when received GET STRING DESCRIPTOR request
// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete // 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) uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid)
{ {
(void) langid;
uint8_t chr_count; uint8_t chr_count;
if ( index == 0) if ( index == 0)

View File

@ -39,7 +39,7 @@
#error CFG_TUSB_MCU must be defined #error CFG_TUSB_MCU must be defined
#endif #endif
#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX #if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || CFG_TUSB_MCU == OPT_MCU_NUC505
#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED) #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED)
#else #else
#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE #define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE

View File

@ -80,10 +80,20 @@ enum
#if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX #if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX
// LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number // LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number
// 0 control, 1 In, 2 Bulk, 3 Iso, 4 In etc ... // 0 control, 1 In, 2 Bulk, 3 Iso, 4 In, 5 Bulk etc ...
#define EPNUM_MSC 0x02 #define EPNUM_MSC_OUT 0x02
#define EPNUM_MSC_IN 0x82
#elif CFG_TUSB_MCU == OPT_MCU_SAMG
// SAMG doesn't support a same endpoint number with different direction IN and OUT
// e.g EP1 OUT & EP1 IN cannot exist together
#define EPNUM_MSC_OUT 0x01
#define EPNUM_MSC_IN 0x82
#else #else
#define EPNUM_MSC 0x01 #define EPNUM_MSC_OUT 0x01
#define EPNUM_MSC_IN 0x81
#endif #endif
uint8_t const desc_configuration[] = uint8_t const desc_configuration[] =
@ -92,7 +102,7 @@ uint8_t const desc_configuration[] =
TUD_CONFIG_DESCRIPTOR(ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), TUD_CONFIG_DESCRIPTOR(ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
// Interface number, string index, EP Out & EP In address, EP size // Interface number, string index, EP Out & EP In address, EP size
TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 0, EPNUM_MSC, 0x80 | EPNUM_MSC, (CFG_TUSB_RHPORT0_MODE & OPT_MODE_HIGH_SPEED) ? 512 : 64), TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 0, EPNUM_MSC_OUT, EPNUM_MSC_IN, (CFG_TUSB_RHPORT0_MODE & OPT_MODE_HIGH_SPEED) ? 512 : 64),
}; };
// Invoked when received GET CONFIGURATION DESCRIPTOR // Invoked when received GET CONFIGURATION DESCRIPTOR
@ -121,8 +131,10 @@ static uint16_t _desc_str[32];
// Invoked when received GET STRING DESCRIPTOR request // Invoked when received GET STRING DESCRIPTOR request
// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete // 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) uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid)
{ {
(void) langid;
uint8_t chr_count; uint8_t chr_count;
if ( index == 0) if ( index == 0)

View File

@ -0,0 +1,57 @@
include ../../../tools/top.mk
include ../../make.mk
CFLAGS += \
-DPBUF_POOL_SIZE=2 \
-DTCP_WND=2*TCP_MSS \
-DHTTPD_USE_CUSTOM_FSDATA=0
INC += \
src \
$(TOP)/hw \
$(TOP)/lib/lwip/src/include \
$(TOP)/lib/lwip/src/include/ipv4 \
$(TOP)/lib/lwip/src/include/lwip/apps \
$(TOP)/lib/networking
# Example source
EXAMPLE_SOURCE += $(wildcard src/*.c)
SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE))
SRC_C += \
lib/lwip/src/core/altcp.c \
lib/lwip/src/core/altcp_alloc.c \
lib/lwip/src/core/altcp_tcp.c \
lib/lwip/src/core/def.c \
lib/lwip/src/core/dns.c \
lib/lwip/src/core/inet_chksum.c \
lib/lwip/src/core/init.c \
lib/lwip/src/core/ip.c \
lib/lwip/src/core/mem.c \
lib/lwip/src/core/memp.c \
lib/lwip/src/core/netif.c \
lib/lwip/src/core/pbuf.c \
lib/lwip/src/core/raw.c \
lib/lwip/src/core/stats.c \
lib/lwip/src/core/sys.c \
lib/lwip/src/core/tcp.c \
lib/lwip/src/core/tcp_in.c \
lib/lwip/src/core/tcp_out.c \
lib/lwip/src/core/timeouts.c \
lib/lwip/src/core/udp.c \
lib/lwip/src/core/ipv4/autoip.c \
lib/lwip/src/core/ipv4/dhcp.c \
lib/lwip/src/core/ipv4/etharp.c \
lib/lwip/src/core/ipv4/icmp.c \
lib/lwip/src/core/ipv4/igmp.c \
lib/lwip/src/core/ipv4/ip4.c \
lib/lwip/src/core/ipv4/ip4_addr.c \
lib/lwip/src/core/ipv4/ip4_frag.c \
lib/lwip/src/netif/ethernet.c \
lib/lwip/src/netif/slipif.c \
lib/lwip/src/apps/http/httpd.c \
lib/lwip/src/apps/http/fs.c \
lib/networking/dhserver.c \
lib/networking/dnserver.c \
lib/networking/rndis_reports.c
include ../../rules.mk

View File

@ -0,0 +1,75 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* 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. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __CC_H__
#define __CC_H__
//#include "cpu.h"
typedef int sys_prot_t;
/* define compiler specific symbols */
#if defined (__ICCARM__)
#define PACK_STRUCT_BEGIN
#define PACK_STRUCT_STRUCT
#define PACK_STRUCT_END
#define PACK_STRUCT_FIELD(x) x
#define PACK_STRUCT_USE_INCLUDES
#elif defined (__CC_ARM)
#define PACK_STRUCT_BEGIN __packed
#define PACK_STRUCT_STRUCT
#define PACK_STRUCT_END
#define PACK_STRUCT_FIELD(x) x
#elif defined (__GNUC__)
#define PACK_STRUCT_BEGIN
#define PACK_STRUCT_STRUCT __attribute__ ((__packed__))
#define PACK_STRUCT_END
#define PACK_STRUCT_FIELD(x) x
#elif defined (__TASKING__)
#define PACK_STRUCT_BEGIN
#define PACK_STRUCT_STRUCT
#define PACK_STRUCT_END
#define PACK_STRUCT_FIELD(x) x
#endif
#define LWIP_PLATFORM_ASSERT(x) do { if(!(x)) while(1); } while(0)
#endif /* __CC_H__ */

View File

@ -0,0 +1,57 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* 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. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 lwIP TCP/IP stack.
*
* Author: Simon Goldschmidt
*
*/
#ifndef __LWIPOPTS_H__
#define __LWIPOPTS_H__
/* Prevent having to link sys_arch.c (we don't test the API layers in unit tests) */
#define NO_SYS 1
#define MEM_ALIGNMENT 4
#define LWIP_RAW 1
#define LWIP_NETCONN 0
#define LWIP_SOCKET 0
#define LWIP_DHCP 0
#define LWIP_ICMP 1
#define LWIP_UDP 1
#define LWIP_TCP 1
#define ETH_PAD_SIZE 0
#define LWIP_IP_ACCEPT_UDP_PORT(p) ((p) == PP_NTOHS(67))
#define TCP_MSS (1500 /*mtu*/ - 20 /*iphdr*/ - 20 /*tcphhr*/)
#define TCP_SND_BUF (2 * TCP_MSS)
#define ETHARP_SUPPORT_STATIC_ENTRIES 1
#define LWIP_HTTPD_CGI 0
#define LWIP_HTTPD_SSI 0
#define LWIP_HTTPD_SSI_INCLUDE_TAG 0
#endif /* __LWIPOPTS_H__ */

View File

@ -0,0 +1,214 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2020 Peter Lawrence
*
* influenced by lrndis https://github.com/fetisov/lrndis
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
/*
depending on the value of CFG_TUD_NET (tusb_config.h), this can be a CDC-ECM, RNDIS, or CDC-EEM USB virtual network adapter
CDC-ECM should be valid on Linux and MacOS hosts
RNDIS should be valid on Linux and Windows hosts
CDC-EEM should be valid on Linux hosts
You *must* customize tusb_config.h to set the CFG_TUD_NET definition to the type of these network adapters to emulate.
The MCU appears to the host as IP address 192.168.7.1, and provides a DHCP server, DNS server, and web server.
*/
#include "bsp/board.h"
#include "tusb.h"
#include "dhserver.h"
#include "dnserver.h"
#include "lwip/init.h"
#include "httpd.h"
/* lwip context */
static struct netif netif_data;
/* shared between tud_network_recv_cb() and service_traffic() */
static struct pbuf *received_frame;
/* this is used by this code, ./class/net/net_driver.c, and usb_descriptors.c */
/* ideally speaking, this should be generated from the hardware's unique ID (if available) */
const uint8_t tud_network_mac_address[6] = {0x20,0x89,0x84,0x6A,0x96,0x00};
/* network parameters of this MCU */
static const ip_addr_t ipaddr = IPADDR4_INIT_BYTES(192, 168, 7, 1);
static const ip_addr_t netmask = IPADDR4_INIT_BYTES(255, 255, 255, 0);
static const ip_addr_t gateway = IPADDR4_INIT_BYTES(0, 0, 0, 0);
/* database IP addresses that can be offered to the host; this must be in RAM to store assigned MAC addresses */
static dhcp_entry_t entries[] =
{
/* mac ip address subnet mask lease time */
{ {0}, {192, 168, 7, 2}, {255, 255, 255, 0}, 24 * 60 * 60 },
{ {0}, {192, 168, 7, 3}, {255, 255, 255, 0}, 24 * 60 * 60 },
{ {0}, {192, 168, 7, 4}, {255, 255, 255, 0}, 24 * 60 * 60 }
};
/* DHCP configuration parameters, leveraging "entries" above */
static const dhcp_config_t dhcp_config =
{
{192, 168, 7, 1}, 67, /* server address (self), port */
{192, 168, 7, 1}, /* dns server (self) */
"usb", /* dns suffix */
TU_ARRAY_SIZE(entries), /* number of entries */
entries /* pointer to entries */
};
static err_t linkoutput_fn(struct netif *netif, struct pbuf *p)
{
(void)netif;
for (;;)
{
/* if TinyUSB isn't ready, we must signal back to lwip that there is nothing we can do */
if (!tud_ready())
return ERR_USE;
/* if the network driver can accept another packet, we make it happen */
if (tud_network_can_xmit())
{
tud_network_xmit(p);
return ERR_OK;
}
/* transfer execution to TinyUSB in the hopes that it will finish transmitting the prior packet */
tud_task();
}
}
static err_t output_fn(struct netif *netif, struct pbuf *p, const ip_addr_t *addr)
{
return etharp_output(netif, p, addr);
}
static err_t netif_init_cb(struct netif *netif)
{
LWIP_ASSERT("netif != NULL", (netif != NULL));
netif->mtu = CFG_TUD_NET_MTU;
netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP | NETIF_FLAG_UP;
netif->state = NULL;
netif->name[0] = 'E';
netif->name[1] = 'X';
netif->linkoutput = linkoutput_fn;
netif->output = output_fn;
return ERR_OK;
}
static void init_lwip(void)
{
struct netif *netif = &netif_data;
lwip_init();
netif->hwaddr_len = sizeof(tud_network_mac_address);
memcpy(netif->hwaddr, tud_network_mac_address, sizeof(tud_network_mac_address));
netif = netif_add(netif, &ipaddr, &netmask, &gateway, NULL, netif_init_cb, ip_input);
netif_set_default(netif);
}
/* handle any DNS requests from dns-server */
bool dns_query_proc(const char *name, ip_addr_t *addr)
{
if (0 == strcmp(name, "tiny.usb"))
{
*addr = ipaddr;
return true;
}
return false;
}
bool tud_network_recv_cb(struct pbuf *p)
{
/* this shouldn't happen, but if we get another packet before
parsing the previous, we must signal our inability to accept it */
if (received_frame) return false;
/* store away the pointer for service_traffic() to later handle */
received_frame = p;
return true;
}
static void service_traffic(void)
{
/* handle any packet received by tud_network_recv_cb() */
if (received_frame)
{
ethernet_input(received_frame, &netif_data);
pbuf_free(received_frame);
received_frame = NULL;
tud_network_recv_renew();
}
}
void tud_network_init_cb(void)
{
/* if the network is re-initializing and we have a leftover packet, we must do a cleanup */
if (received_frame)
{
pbuf_free(received_frame);
received_frame = NULL;
}
}
int main(void)
{
/* initialize TinyUSB */
board_init();
tusb_init();
/* initialize lwip, dhcp-server, dns-server, and http */
init_lwip();
while (!netif_is_up(&netif_data));
while (dhserv_init(&dhcp_config) != ERR_OK);
while (dnserv_init(&ipaddr, 53, dns_query_proc) != ERR_OK);
httpd_init();
while (1)
{
tud_task();
service_traffic();
}
return 0;
}
/* lwip has provision for using a mutex, when applicable */
sys_prot_t sys_arch_protect(void)
{
return 0;
}
void sys_arch_unprotect(sys_prot_t pval)
{
(void)pval;
}
/* lwip needs a millisecond time source, and the TinyUSB board support code has one available */
uint32_t sys_now(void)
{
return board_millis();
}

View File

@ -0,0 +1,90 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
#ifndef _TUSB_CONFIG_H_
#define _TUSB_CONFIG_H_
#ifdef __cplusplus
extern "C" {
#endif
//--------------------------------------------------------------------
// COMMON CONFIGURATION
//--------------------------------------------------------------------
// defined by compiler flags for flexibility
#ifndef CFG_TUSB_MCU
#error CFG_TUSB_MCU must be defined
#endif
#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX
#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED)
#else
#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE
#endif
#define CFG_TUSB_OS OPT_OS_NONE
// CFG_TUSB_DEBUG is defined by compiler in DEBUG build
// #define CFG_TUSB_DEBUG 0
/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment.
* Tinyusb use follows macros to declare transferring memory so that they can be put
* into those specific section.
* e.g
* - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") ))
* - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4)))
*/
#ifndef CFG_TUSB_MEM_SECTION
#define CFG_TUSB_MEM_SECTION
#endif
#ifndef CFG_TUSB_MEM_ALIGN
#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4)))
#endif
//--------------------------------------------------------------------
// DEVICE CONFIGURATION
//--------------------------------------------------------------------
#ifndef CFG_TUD_ENDPOINT0_SIZE
#define CFG_TUD_ENDPOINT0_SIZE 64
#endif
//------------- CLASS -------------//
#define CFG_TUD_CDC 0
#define CFG_TUD_MSC 0
#define CFG_TUD_HID 0
#define CFG_TUD_MIDI 0
#define CFG_TUD_VENDOR 0
//#define CFG_TUD_NET OPT_NET_ECM
#define CFG_TUD_NET OPT_NET_RNDIS
//#define CFG_TUD_NET OPT_NET_EEM
#ifdef __cplusplus
}
#endif
#endif /* _TUSB_CONFIG_H_ */

View File

@ -0,0 +1,199 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
#include "tusb.h"
#include "usb_descriptors.h"
/* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug.
* Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC.
*
* Auto ProductID layout's Bitmap:
* [MSB] NET1:NET0 | VENDOR | MIDI | HID | MSC | CDC [LSB]
*/
#define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) )
#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \
_PID_MAP(MIDI, 3) | _PID_MAP(VENDOR, 4) | _PID_MAP(NET, 5) )
//--------------------------------------------------------------------+
// Device Descriptors
//--------------------------------------------------------------------+
tusb_desc_device_t const desc_device =
{
.bLength = sizeof(tusb_desc_device_t),
.bDescriptorType = TUSB_DESC_DEVICE,
.bcdUSB = 0x0200,
.bDeviceClass = TUSB_CLASS_UNSPECIFIED,
.bDeviceSubClass = 0,
.bDeviceProtocol = 0,
.bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
.idVendor = 0xCafe,
.idProduct = USB_PID,
.bcdDevice = 0x0100,
.iManufacturer = 0x01,
.iProduct = 0x02,
.iSerialNumber = 0x03,
.bNumConfigurations = 0x01
};
// Invoked when received GET DEVICE DESCRIPTOR
// Application return pointer to descriptor
uint8_t const * tud_descriptor_device_cb(void)
{
return (uint8_t const *) &desc_device;
}
//--------------------------------------------------------------------+
// Configuration Descriptor
//--------------------------------------------------------------------+
enum
{
ITF_NUM_CDC = 0,
ITF_NUM_CDC_DATA,
ITF_NUM_TOTAL
};
enum
{
STR_LANGID = 0,
STR_MANUFACTURER,
STR_PRODUCT,
STR_ITFNAME,
STR_MAC,
};
#if CFG_TUD_NET == OPT_NET_ECM
#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_ECM_DESC_LEN)
#elif CFG_TUD_NET == OPT_NET_RNDIS
#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_RNDIS_DESC_LEN)
#elif CFG_TUD_NET == OPT_NET_EEM
#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_EEM_DESC_LEN)
#endif
#if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX
// LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number
// 0 control, 1 In, 2 Bulk, 3 Iso, 4 In etc ...
#define EPNUM_CDC 2
#else
#define EPNUM_CDC 2
#endif
uint8_t const desc_configuration[] =
{
// Interface count, string index, total length, attribute, power in mA
TUD_CONFIG_DESCRIPTOR(ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0, 100),
#if CFG_TUD_NET == OPT_NET_ECM
// Interface number, description string index, MAC address string index, EP notification address and size, EP data address (out, in), and size, max segment size.
TUD_CDC_ECM_DESCRIPTOR(ITF_NUM_CDC, STR_ITFNAME, STR_MAC, 0x81, 8, EPNUM_CDC, 0x80 | EPNUM_CDC, CFG_TUD_NET_ENDPOINT_SIZE, CFG_TUD_NET_MTU),
#elif CFG_TUD_NET == OPT_NET_RNDIS
// Interface number, string index, EP notification address and size, EP data address (out, in) and size.
TUD_RNDIS_DESCRIPTOR(ITF_NUM_CDC, STR_ITFNAME, 0x81, 8, EPNUM_CDC, 0x80 | EPNUM_CDC, CFG_TUD_NET_ENDPOINT_SIZE),
#elif CFG_TUD_NET == OPT_NET_EEM
// Interface number, description string index, EP data address (out, in) and size.
TUD_CDC_EEM_DESCRIPTOR(ITF_NUM_CDC, STR_ITFNAME, EPNUM_CDC, 0x80 | EPNUM_CDC, CFG_TUD_NET_ENDPOINT_SIZE),
#endif
};
// Invoked when received GET CONFIGURATION DESCRIPTOR
// Application return pointer to descriptor
// Descriptor contents must exist long enough for transfer to complete
uint8_t const * tud_descriptor_configuration_cb(uint8_t index)
{
(void) index; // for multiple configurations
return desc_configuration;
}
//--------------------------------------------------------------------+
// String Descriptors
//--------------------------------------------------------------------+
// array of pointer to string descriptors
char const* string_desc_arr [] =
{
[STR_LANGID] = (const char[]) { 0x09, 0x04 }, // supported language is English (0x0409)
[STR_MANUFACTURER] = "TinyUSB", // Manufacturer
[STR_PRODUCT] = "TinyUSB Device", // Product
[STR_ITFNAME] = // CDC-ECM Interface
#if CFG_TUD_NET == OPT_NET_ECM
"TinyUSB CDC-ECM",
#elif CFG_TUD_NET == OPT_NET_RNDIS
"TinyUSB RNDIS",
#elif CFG_TUD_NET == OPT_NET_EEM
"TinyUSB CDC-EEM",
#endif
};
static uint16_t _desc_str[32];
// Invoked when received GET STRING DESCRIPTOR request
// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete
uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid)
{
(void)langid;
unsigned chr_count = 0;
if (STR_LANGID == index)
{
memcpy(&_desc_str[1], string_desc_arr[0], 2);
chr_count = 1;
}
else if (STR_MAC == index)
{
// Convert MAC address into UTF-16
for (unsigned i=0; i<sizeof(tud_network_mac_address); i++)
{
_desc_str[1+chr_count++] = "0123456789ABCDEF"[(tud_network_mac_address[i] >> 4) & 0xf];
_desc_str[1+chr_count++] = "0123456789ABCDEF"[(tud_network_mac_address[i] >> 0) & 0xf];
}
}
else
{
// Convert ASCII string into UTF-16
if ( !(index < sizeof(string_desc_arr)/sizeof(string_desc_arr[0])) ) return NULL;
const char* str = string_desc_arr[index];
// Cap at max char
chr_count = strlen(str);
if ( chr_count > (TU_ARRAY_SIZE(_desc_str) - 1)) chr_count = TU_ARRAY_SIZE(_desc_str) - 1;
for (unsigned i=0; i<chr_count; i++)
{
_desc_str[1+i] = str[i];
}
}
// first byte is length (including header), second byte is string type
_desc_str[0] = (TUSB_DESC_STRING << 8 ) | (2*chr_count + 2);
return _desc_str;
}

View File

@ -0,0 +1,28 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef USB_DESCRIPTORS_H_
#define USB_DESCRIPTORS_H_
#endif /* USB_DESCRIPTORS_H_ */

View File

@ -21,7 +21,7 @@
#error CFG_TUSB_MCU must be defined #error CFG_TUSB_MCU must be defined
#endif #endif
#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX #if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || CFG_TUSB_MCU == OPT_MCU_NUC505
#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED) #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED)
#else #else
#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE #define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE

View File

@ -216,8 +216,10 @@ static uint16_t _desc_str[32];
// Invoked when received GET STRING DESCRIPTOR request // Invoked when received GET STRING DESCRIPTOR request
// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete // 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) uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid)
{ {
(void) langid;
size_t chr_count; size_t chr_count;
if ( index == 0) if ( index == 0)

View File

@ -39,7 +39,7 @@
#error CFG_TUSB_MCU must be defined #error CFG_TUSB_MCU must be defined
#endif #endif
#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX #if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || CFG_TUSB_MCU == OPT_MCU_NUC505
#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED) #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED)
#else #else
#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE #define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE

View File

@ -204,8 +204,10 @@ static uint16_t _desc_str[32];
// Invoked when received GET STRING DESCRIPTOR request // Invoked when received GET STRING DESCRIPTOR request
// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete // 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) uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid)
{ {
(void) langid;
uint8_t chr_count; uint8_t chr_count;
if ( index == 0) if ( index == 0)

View File

@ -22,6 +22,7 @@ SRC_C += \
src/class/midi/midi_device.c \ src/class/midi/midi_device.c \
src/class/usbtmc/usbtmc_device.c \ src/class/usbtmc/usbtmc_device.c \
src/class/vendor/vendor_device.c \ src/class/vendor/vendor_device.c \
src/class/net/net_device.c \
src/portable/$(VENDOR)/$(CHIP_FAMILY)/dcd_$(CHIP_FAMILY).c src/portable/$(VENDOR)/$(CHIP_FAMILY)/dcd_$(CHIP_FAMILY).c
# TinyUSB stack include # TinyUSB stack include
@ -120,6 +121,7 @@ endif
# Flash using jlink # Flash using jlink
flash-jlink: $(BUILD)/$(BOARD)-firmware.hex flash-jlink: $(BUILD)/$(BOARD)-firmware.hex
@echo halt > $(BUILD)/$(BOARD).jlink @echo halt > $(BUILD)/$(BOARD).jlink
@echo r > $(BUILD)/$(BOARD).jlink
@echo loadfile $^ >> $(BUILD)/$(BOARD).jlink @echo loadfile $^ >> $(BUILD)/$(BOARD).jlink
@echo r >> $(BUILD)/$(BOARD).jlink @echo r >> $(BUILD)/$(BOARD).jlink
@echo go >> $(BUILD)/$(BOARD).jlink @echo go >> $(BUILD)/$(BOARD).jlink

View File

@ -0,0 +1,192 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
#include "bsp/board.h"
#include "nrfx.h"
#include "nrfx/hal/nrf_gpio.h"
#include "nrfx/drivers/include/nrfx_power.h"
#ifdef SOFTDEVICE_PRESENT
#include "nrf_sdm.h"
#include "nrf_soc.h"
#endif
/*------------------------------------------------------------------*/
/* MACRO TYPEDEF CONSTANT ENUM
*------------------------------------------------------------------*/
#define _PINNUM(port, pin) ((port)*32 + (pin))
#define LED_PIN _PINNUM(1, 1)
#define LED_STATE_ON 1
#define BUTTON_PIN _PINNUM(1, 02)
// 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.
extern void tusb_hal_nrf_power_event(uint32_t event);
void board_init(void)
{
// Config clock source: XTAL or RC in sdk_config.h
NRF_CLOCK->LFCLKSRC = (uint32_t)((CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos) & CLOCK_LFCLKSRC_SRC_Msk);
NRF_CLOCK->TASKS_LFCLKSTART = 1UL;
// LED
nrf_gpio_cfg_output(LED_PIN);
board_led_write(false);
// Button
nrf_gpio_cfg_input(BUTTON_PIN, NRF_GPIO_PIN_PULLUP);
#if CFG_TUSB_OS == OPT_OS_NONE
// 1ms tick timer
SysTick_Config(SystemCoreClock/1000);
#endif
#if TUSB_OPT_DEVICE_ENABLED
// Priorities 0, 1, 4 (nRF52) are reserved for SoftDevice
// 2 is highest for application
NVIC_SetPriority(USBD_IRQn, 2);
// USB power may already be ready at this time -> no event generated
// We need to invoke the handler based on the status initially
uint32_t usb_reg;
#ifdef SOFTDEVICE_PRESENT
uint8_t sd_en = false;
sd_softdevice_is_enabled(&sd_en);
if ( sd_en ) {
sd_power_usbdetected_enable(true);
sd_power_usbpwrrdy_enable(true);
sd_power_usbremoved_enable(true);
sd_power_usbregstatus_get(&usb_reg);
}else
#endif
{
// Power module init
const nrfx_power_config_t pwr_cfg = { 0 };
nrfx_power_init(&pwr_cfg);
// Register tusb function as USB power handler
const nrfx_power_usbevt_config_t config = { .handler = (nrfx_power_usb_event_handler_t) tusb_hal_nrf_power_event };
nrfx_power_usbevt_init(&config);
nrfx_power_usbevt_enable();
usb_reg = NRF_POWER->USBREGSTATUS;
}
if ( usb_reg & POWER_USBREGSTATUS_VBUSDETECT_Msk ) tusb_hal_nrf_power_event(NRFX_POWER_USB_EVT_DETECTED);
if ( usb_reg & POWER_USBREGSTATUS_OUTPUTRDY_Msk ) tusb_hal_nrf_power_event(NRFX_POWER_USB_EVT_READY);
#endif
}
//--------------------------------------------------------------------+
// Board porting API
//--------------------------------------------------------------------+
void board_led_write(bool state)
{
nrf_gpio_pin_write(LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON));
}
uint32_t board_button_read(void)
{
// button is active LOW
return (nrf_gpio_pin_read(BUTTON_PIN) ? 0 : 1);
}
int board_uart_read(uint8_t* buf, int len)
{
(void) buf; (void) len;
return 0;
}
int board_uart_write(void const * buf, int len)
{
(void) buf; (void) len;
return 0;
}
#if CFG_TUSB_OS == OPT_OS_NONE
volatile uint32_t system_ticks = 0;
void SysTick_Handler (void)
{
system_ticks++;
}
uint32_t board_millis(void)
{
return system_ticks;
}
#endif
#ifdef SOFTDEVICE_PRESENT
// process SOC event from SD
uint32_t proc_soc(void)
{
uint32_t soc_evt;
uint32_t err = sd_evt_get(&soc_evt);
if (NRF_SUCCESS == err)
{
/*------------- usb power event handler -------------*/
int32_t usbevt = (soc_evt == NRF_EVT_POWER_USB_DETECTED ) ? NRFX_POWER_USB_EVT_DETECTED:
(soc_evt == NRF_EVT_POWER_USB_POWER_READY) ? NRFX_POWER_USB_EVT_READY :
(soc_evt == NRF_EVT_POWER_USB_REMOVED ) ? NRFX_POWER_USB_EVT_REMOVED : -1;
if ( usbevt >= 0) tusb_hal_nrf_power_event(usbevt);
}
return err;
}
uint32_t proc_ble(void)
{
// do nothing with ble
return NRF_ERROR_NOT_FOUND;
}
void SD_EVT_IRQHandler(void)
{
// process BLE and SOC until there is no more events
while( (NRF_ERROR_NOT_FOUND != proc_ble()) || (NRF_ERROR_NOT_FOUND != proc_soc()) )
{
}
}
void nrf_error_cb(uint32_t id, uint32_t pc, uint32_t info)
{
(void) id;
(void) pc;
(void) info;
}
#endif

View File

@ -0,0 +1,63 @@
CFLAGS += \
-flto \
-mthumb \
-mabi=aapcs \
-mcpu=cortex-m4 \
-mfloat-abi=hard \
-mfpu=fpv4-sp-d16 \
-DCFG_TUSB_MCU=OPT_MCU_NRF5X \
-DNRF52840_XXAA \
-DCONFIG_GPIO_AS_PINRESET
# nrfx issue undef _ARMCC_VERSION usage https://github.com/NordicSemiconductor/nrfx/issues/49
CFLAGS += -Wno-error=undef -Wno-error=unused-parameter
# due to tusb_hal_nrf_power_event
GCCVERSION = $(firstword $(subst ., ,$(shell arm-none-eabi-gcc -dumpversion)))
ifeq ($(shell expr $(GCCVERSION) \>= 8), 1)
CFLAGS += -Wno-error=cast-function-type
endif
# All source paths should be relative to the top level.
LD_FILE = hw/bsp/$(BOARD)/nrf52840_s140_v6.ld
LDFLAGS += -L$(TOP)/hw/mcu/nordic/nrfx/mdk
SRC_C += \
hw/mcu/nordic/nrfx/drivers/src/nrfx_power.c \
hw/mcu/nordic/nrfx/mdk/system_nrf52840.c \
INC += \
$(TOP)/hw/mcu/nordic/cmsis/Include \
$(TOP)/hw/mcu/nordic \
$(TOP)/hw/mcu/nordic/nrfx \
$(TOP)/hw/mcu/nordic/nrfx/mdk \
$(TOP)/hw/mcu/nordic/nrfx/hal \
$(TOP)/hw/mcu/nordic/nrfx/drivers/include \
$(TOP)/hw/mcu/nordic/nrfx/drivers/src \
SRC_S += hw/mcu/nordic/nrfx/mdk/gcc_startup_nrf52840.S
ASFLAGS += -D__HEAP_SIZE=0
# For TinyUSB port source
VENDOR = nordic
CHIP_FAMILY = nrf5x
# For freeRTOS port source
FREERTOS_PORT = ARM_CM4F
# For flash-jlink target
JLINK_DEVICE = nRF52840_xxAA
JLINK_IF = swd
# For uf2 conversion
UF2_FAMILY = 0xADA52840
$(BUILD)/$(BOARD)-firmware.zip: $(BUILD)/$(BOARD)-firmware.hex
adafruit-nrfutil dfu genpkg --dev-type 0x0052 --sd-req 0xFFFE --application $^ $@
# flash using adafruit-nrfutil dfu
flash: $(BUILD)/$(BOARD)-firmware.zip
@:$(call check_defined, SERIAL, example: SERIAL=/dev/ttyACM0)
adafruit-nrfutil --verbose dfu serial --package $^ -p $(SERIAL) -b 115200 --singlebank --touch 1200

View File

@ -0,0 +1,38 @@
/* Linker script to configure memory regions. */
SEARCH_DIR(.)
GROUP(-lgcc -lc -lnosys)
MEMORY
{
FLASH (rx) : ORIGIN = 0x26000, LENGTH = 0xED000 - 0x26000
/* SRAM required by S132 depend on
* - Attribute Table Size
* - Vendor UUID count
* - Max ATT MTU
* - Concurrent connection peripheral + central + secure links
* - Event Len, HVN queue, Write CMD queue
*/
RAM (rwx) : ORIGIN = 0x20003400, LENGTH = 0x20040000 - 0x20003400
}
SECTIONS
{
. = ALIGN(4);
.svc_data :
{
PROVIDE(__start_svc_data = .);
KEEP(*(.svc_data))
PROVIDE(__stop_svc_data = .);
} > RAM
.fs_data :
{
PROVIDE(__start_fs_data = .);
KEEP(*(.fs_data))
PROVIDE(__stop_fs_data = .);
} > RAM
} INSERT AFTER .data;
INCLUDE "nrf52_common.ld"

View File

@ -39,7 +39,6 @@
#include <stdbool.h> #include <stdbool.h>
#include "ansi_escape.h" #include "ansi_escape.h"
#include "tusb.h" #include "tusb.h"
#define CFG_BOARD_UART_BAUDRATE 115200 #define CFG_BOARD_UART_BAUDRATE 115200
@ -68,18 +67,21 @@ int board_uart_write(void const * buf, int len);
#if CFG_TUSB_OS == OPT_OS_NONE #if CFG_TUSB_OS == OPT_OS_NONE
// Get current milliseconds, must be implemented when no RTOS is used // Get current milliseconds, must be implemented when no RTOS is used
uint32_t board_millis(void); uint32_t board_millis(void);
#elif CFG_TUSB_OS == OPT_OS_FREERTOS #elif CFG_TUSB_OS == OPT_OS_FREERTOS
static inline uint32_t board_millis(void) static inline uint32_t board_millis(void)
{ {
return ( ( ((uint64_t) xTaskGetTickCount()) * 1000) / configTICK_RATE_HZ ); return ( ( ((uint64_t) xTaskGetTickCount()) * 1000) / configTICK_RATE_HZ );
} }
#elif CFG_TUSB_OS == OPT_OS_MYNEWT #elif CFG_TUSB_OS == OPT_OS_MYNEWT
static inline uint32_t board_millis(void) static inline uint32_t board_millis(void)
{ {
return os_time_ticks_to_ms32( os_time_get() ); return os_time_ticks_to_ms32( os_time_get() );
} }
#else #else
#error "Need to implement board_millis() for this OS" #error "board_millis() is not implemented for this OS"
#endif #endif
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
@ -95,6 +97,7 @@ static inline void board_led_off(void)
board_led_write(false); board_led_write(false);
} }
// TODO remove
static inline void board_delay(uint32_t ms) static inline void board_delay(uint32_t ms)
{ {
uint32_t start_ms = board_millis(); uint32_t start_ms = board_millis();

View File

@ -19,7 +19,7 @@ CFLAGS += -Wno-error=cast-function-type
endif endif
# All source paths should be relative to the top level. # All source paths should be relative to the top level.
LD_FILE = hw/bsp/circuitplayground_bluefruit/nrf52840_s140_v6.ld LD_FILE = hw/bsp/$(BOARD)/nrf52840_s140_v6.ld
LDFLAGS += -L$(TOP)/hw/mcu/nordic/nrfx/mdk LDFLAGS += -L$(TOP)/hw/mcu/nordic/nrfx/mdk

View File

@ -8,7 +8,7 @@ CFLAGS += \
-DCFG_TUSB_MCU=OPT_MCU_SAMD21 -DCFG_TUSB_MCU=OPT_MCU_SAMD21
# All source paths should be relative to the top level. # All source paths should be relative to the top level.
LD_FILE = hw/bsp/circuitplayground_express/samd21g18a_flash.ld LD_FILE = hw/bsp/$(BOARD)/samd21g18a_flash.ld
SRC_C += \ SRC_C += \
hw/mcu/microchip/samd/asf4/samd21/gcc/gcc/startup_samd21.c \ hw/mcu/microchip/samd/asf4/samd21/gcc/gcc/startup_samd21.c \
@ -41,4 +41,5 @@ JLINK_DEVICE = ATSAMD21G18
JLINK_IF = swd JLINK_IF = swd
# flash using jlink # flash using jlink
flash: flash-jlink flash: $(BUILD)/$(BOARD)-firmware.uf2
cp $< /media/$(USER)/CPLAYBOOT/

View File

@ -60,6 +60,11 @@ void board_init(void)
_sysctrl_init_referenced_generators(); _sysctrl_init_referenced_generators();
_gclk_init_generators_by_fref(_GCLK_INIT_LAST); _gclk_init_generators_by_fref(_GCLK_INIT_LAST);
// Update SystemCoreClock since it is hard coded with asf4 and not correct
// Init 1ms tick timer (samd SystemCoreClock may not correct)
SystemCoreClock = CONF_CPU_FREQUENCY;
SysTick_Config(CONF_CPU_FREQUENCY / 1000);
// Led init // Led init
gpio_set_pin_direction(LED_PIN, GPIO_DIRECTION_OUT); gpio_set_pin_direction(LED_PIN, GPIO_DIRECTION_OUT);
gpio_set_pin_level(LED_PIN, 0); gpio_set_pin_level(LED_PIN, 0);
@ -68,9 +73,9 @@ void board_init(void)
gpio_set_pin_direction(BUTTON_PIN, GPIO_DIRECTION_IN); gpio_set_pin_direction(BUTTON_PIN, GPIO_DIRECTION_IN);
gpio_set_pin_pull_mode(BUTTON_PIN, GPIO_PULL_DOWN); gpio_set_pin_pull_mode(BUTTON_PIN, GPIO_PULL_DOWN);
#if CFG_TUSB_OS == OPT_OS_NONE #if CFG_TUSB_OS == OPT_OS_FREERTOS
// 1ms tick timer (samd SystemCoreClock may not correct) // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher )
SysTick_Config(CONF_CPU_FREQUENCY / 1000); NVIC_SetPriority(USB_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY);
#endif #endif
/* USB Clock init /* USB Clock init

View File

@ -15,7 +15,7 @@ CFLAGS += -Wno-error=strict-prototypes -Wno-error=unused-parameter
MCU_DIR = hw/mcu/nxp/lpcopen/lpc40xx/lpc_chip_40xx MCU_DIR = hw/mcu/nxp/lpcopen/lpc40xx/lpc_chip_40xx
# All source paths should be relative to the top level. # All source paths should be relative to the top level.
LD_FILE = hw/bsp/ea4088qs/lpc4088.ld LD_FILE = hw/bsp/$(BOARD)/lpc4088.ld
SRC_C += \ SRC_C += \
$(MCU_DIR)/../gcc/cr_startup_lpc40xx.c \ $(MCU_DIR)/../gcc/cr_startup_lpc40xx.c \

View File

@ -3,6 +3,8 @@ CFLAGS += \
-mthumb \ -mthumb \
-mabi=aapcs \ -mabi=aapcs \
-mcpu=cortex-m4 \ -mcpu=cortex-m4 \
-mfloat-abi=hard \
-mfpu=fpv4-sp-d16 \
-nostdlib \ -nostdlib \
-DCORE_M4 \ -DCORE_M4 \
-DCFG_TUSB_MCU=OPT_MCU_LPC43XX \ -DCFG_TUSB_MCU=OPT_MCU_LPC43XX \
@ -14,7 +16,7 @@ CFLAGS += -Wno-error=unused-parameter -Wno-error=strict-prototypes
MCU_DIR = hw/mcu/nxp/lpcopen/lpc43xx/lpc_chip_43xx MCU_DIR = hw/mcu/nxp/lpcopen/lpc43xx/lpc_chip_43xx
# All source paths should be relative to the top level. # All source paths should be relative to the top level.
LD_FILE = hw/bsp/ea4357/lpc4357.ld LD_FILE = hw/bsp/$(BOARD)/lpc4357.ld
SRC_C += \ SRC_C += \
$(MCU_DIR)/../gcc/cr_startup_lpc43xx.c \ $(MCU_DIR)/../gcc/cr_startup_lpc43xx.c \
@ -35,7 +37,7 @@ VENDOR = nxp
CHIP_FAMILY = transdimension CHIP_FAMILY = transdimension
# For freeRTOS port source # For freeRTOS port source
FREERTOS_PORT = ARM_CM4 FREERTOS_PORT = ARM_CM4F
# For flash-jlink target # For flash-jlink target
JLINK_DEVICE = LPC4357 JLINK_DEVICE = LPC4357

View File

@ -9,7 +9,7 @@ CFLAGS += \
-DCFG_TUSB_MCU=OPT_MCU_SAMD21 -DCFG_TUSB_MCU=OPT_MCU_SAMD21
# All source paths should be relative to the top level. # All source paths should be relative to the top level.
LD_FILE = hw/bsp/feather_m0_express/samd21g18a_flash.ld LD_FILE = hw/bsp/$(BOARD)/samd21g18a_flash.ld
SRC_C += \ SRC_C += \
hw/mcu/microchip/samd/asf4/samd21/gcc/gcc/startup_samd21.c \ hw/mcu/microchip/samd/asf4/samd21/gcc/gcc/startup_samd21.c \
@ -25,7 +25,7 @@ INC += \
$(TOP)/hw/mcu/microchip/samd/asf4/samd21/include \ $(TOP)/hw/mcu/microchip/samd/asf4/samd21/include \
$(TOP)/hw/mcu/microchip/samd/asf4/samd21/hal/include \ $(TOP)/hw/mcu/microchip/samd/asf4/samd21/hal/include \
$(TOP)/hw/mcu/microchip/samd/asf4/samd21/hal/utils/include \ $(TOP)/hw/mcu/microchip/samd/asf4/samd21/hal/utils/include \
$(TOP)/hw/mcu/microchip/samd/asf4/samd51/hpl/pm/ \ $(TOP)/hw/mcu/microchip/samd/asf4/samd21/hpl/pm/ \
$(TOP)/hw/mcu/microchip/samd/asf4/samd21/hpl/port \ $(TOP)/hw/mcu/microchip/samd/asf4/samd21/hpl/port \
$(TOP)/hw/mcu/microchip/samd/asf4/samd21/hri \ $(TOP)/hw/mcu/microchip/samd/asf4/samd21/hri \
$(TOP)/hw/mcu/microchip/samd/asf4/samd21/CMSIS/Include $(TOP)/hw/mcu/microchip/samd/asf4/samd21/CMSIS/Include

View File

@ -60,6 +60,11 @@ void board_init(void)
_sysctrl_init_referenced_generators(); _sysctrl_init_referenced_generators();
_gclk_init_generators_by_fref(_GCLK_INIT_LAST); _gclk_init_generators_by_fref(_GCLK_INIT_LAST);
// Update SystemCoreClock since it is hard coded with asf4 and not correct
// Init 1ms tick timer (samd SystemCoreClock may not correct)
SystemCoreClock = CONF_CPU_FREQUENCY;
SysTick_Config(CONF_CPU_FREQUENCY / 1000);
// Led init // Led init
gpio_set_pin_direction(LED_PIN, GPIO_DIRECTION_OUT); gpio_set_pin_direction(LED_PIN, GPIO_DIRECTION_OUT);
gpio_set_pin_level(LED_PIN, 0); gpio_set_pin_level(LED_PIN, 0);
@ -68,9 +73,9 @@ void board_init(void)
gpio_set_pin_direction(BUTTON_PIN, GPIO_DIRECTION_IN); gpio_set_pin_direction(BUTTON_PIN, GPIO_DIRECTION_IN);
gpio_set_pin_pull_mode(BUTTON_PIN, GPIO_PULL_UP); gpio_set_pin_pull_mode(BUTTON_PIN, GPIO_PULL_UP);
#if CFG_TUSB_OS == OPT_OS_NONE #if CFG_TUSB_OS == OPT_OS_FREERTOS
// 1ms tick timer (samd SystemCoreClock may not correct) // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher )
SysTick_Config(CONF_CPU_FREQUENCY / 1000); NVIC_SetPriority(USB_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY);
#endif #endif
/* USB Clock init /* USB Clock init

View File

@ -12,7 +12,7 @@ CFLAGS += \
CFLAGS += -Wno-error=undef CFLAGS += -Wno-error=undef
# All source paths should be relative to the top level. # All source paths should be relative to the top level.
LD_FILE = hw/bsp/metro_m4_express/samd51g19a_flash.ld LD_FILE = hw/bsp/$(BOARD)/samd51g19a_flash.ld
SRC_C += \ SRC_C += \
hw/mcu/microchip/samd/asf4/samd51/gcc/gcc/startup_samd51.c \ hw/mcu/microchip/samd/asf4/samd51/gcc/gcc/startup_samd51.c \

View File

@ -58,6 +58,11 @@ void board_init(void)
_oscctrl_init_referenced_generators(); _oscctrl_init_referenced_generators();
_gclk_init_generators_by_fref(_GCLK_INIT_LAST); _gclk_init_generators_by_fref(_GCLK_INIT_LAST);
// Update SystemCoreClock since it is hard coded with asf4 and not correct
// Init 1ms tick timer (samd SystemCoreClock may not correct)
SystemCoreClock = CONF_CPU_FREQUENCY;
SysTick_Config(CONF_CPU_FREQUENCY / 1000);
// Led init // Led init
gpio_set_pin_direction(LED_PIN, GPIO_DIRECTION_OUT); gpio_set_pin_direction(LED_PIN, GPIO_DIRECTION_OUT);
gpio_set_pin_level(LED_PIN, 0); gpio_set_pin_level(LED_PIN, 0);
@ -66,9 +71,12 @@ void board_init(void)
gpio_set_pin_direction(BUTTON_PIN, GPIO_DIRECTION_IN); gpio_set_pin_direction(BUTTON_PIN, GPIO_DIRECTION_IN);
gpio_set_pin_pull_mode(BUTTON_PIN, GPIO_PULL_UP); gpio_set_pin_pull_mode(BUTTON_PIN, GPIO_PULL_UP);
#if CFG_TUSB_OS == OPT_OS_NONE #if CFG_TUSB_OS == OPT_OS_FREERTOS
// 1ms tick timer (samd SystemCoreClock may not correct) // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher )
SysTick_Config(CONF_CPU_FREQUENCY / 1000); NVIC_SetPriority(USB_0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY);
NVIC_SetPriority(USB_1_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY);
NVIC_SetPriority(USB_2_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY);
NVIC_SetPriority(USB_3_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY);
#endif #endif
/* USB Clock init /* USB Clock init

View File

@ -19,13 +19,14 @@ CFLAGS += -Wno-error=cast-function-type
endif endif
# All source paths should be relative to the top level. # All source paths should be relative to the top level.
LD_FILE = hw/bsp/feather_nrf52840_express/nrf52840_s140_v6.ld LD_FILE = hw/bsp/$(BOARD)/nrf52840_s140_v6.ld
LDFLAGS += -L$(TOP)/hw/mcu/nordic/nrfx/mdk LDFLAGS += -L$(TOP)/hw/mcu/nordic/nrfx/mdk
SRC_C += \ SRC_C += \
hw/mcu/nordic/nrfx/drivers/src/nrfx_power.c \ hw/mcu/nordic/nrfx/drivers/src/nrfx_power.c \
hw/mcu/nordic/nrfx/mdk/system_nrf52840.c \ hw/mcu/nordic/nrfx/drivers/src/nrfx_uarte.c \
hw/mcu/nordic/nrfx/mdk/system_nrf52840.c
INC += \ INC += \
$(TOP)/hw/mcu/nordic/cmsis/Include \ $(TOP)/hw/mcu/nordic/cmsis/Include \

View File

@ -29,6 +29,7 @@
#include "nrfx.h" #include "nrfx.h"
#include "nrfx/hal/nrf_gpio.h" #include "nrfx/hal/nrf_gpio.h"
#include "nrfx/drivers/include/nrfx_power.h" #include "nrfx/drivers/include/nrfx_power.h"
#include "nrfx/drivers/include/nrfx_uarte.h"
#ifdef SOFTDEVICE_PRESENT #ifdef SOFTDEVICE_PRESENT
#include "nrf_sdm.h" #include "nrf_sdm.h"
@ -45,12 +46,20 @@
#define BUTTON_PIN _PINNUM(1, 02) #define BUTTON_PIN _PINNUM(1, 02)
#define UART_RX_PIN 24
#define UART_TX_PIN 25
static nrfx_uarte_t _uart_id = NRFX_UARTE_INSTANCE(0);
// 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.
extern void tusb_hal_nrf_power_event(uint32_t event); extern void tusb_hal_nrf_power_event(uint32_t event);
void board_init(void) void board_init(void)
{ {
// stop LF clock just in case we jump from application without reset
NRF_CLOCK->TASKS_LFCLKSTOP = 1UL;
// Config clock source: XTAL or RC in sdk_config.h // Config clock source: XTAL or RC in sdk_config.h
NRF_CLOCK->LFCLKSRC = (uint32_t)((CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos) & CLOCK_LFCLKSRC_SRC_Msk); NRF_CLOCK->LFCLKSRC = (uint32_t)((CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos) & CLOCK_LFCLKSRC_SRC_Msk);
NRF_CLOCK->TASKS_LFCLKSTART = 1UL; NRF_CLOCK->TASKS_LFCLKSTART = 1UL;
@ -62,17 +71,32 @@ void board_init(void)
// Button // Button
nrf_gpio_cfg_input(BUTTON_PIN, NRF_GPIO_PIN_PULLUP); nrf_gpio_cfg_input(BUTTON_PIN, NRF_GPIO_PIN_PULLUP);
#if CFG_TUSB_OS == OPT_OS_NONE
// 1ms tick timer // 1ms tick timer
SysTick_Config(SystemCoreClock/1000); SysTick_Config(SystemCoreClock/1000);
#endif
// UART
nrfx_uarte_config_t uart_cfg =
{
.pseltxd = UART_TX_PIN,
.pselrxd = UART_RX_PIN,
.pselcts = NRF_UARTE_PSEL_DISCONNECTED,
.pselrts = NRF_UARTE_PSEL_DISCONNECTED,
.p_context = NULL,
.baudrate = NRF_UARTE_BAUDRATE_115200, // CFG_BOARD_UART_BAUDRATE
.interrupt_priority = 7,
.hal_cfg = {
.hwfc = NRF_UARTE_HWFC_DISABLED,
.parity = NRF_UARTE_PARITY_EXCLUDED,
}
};
nrfx_uarte_init(&_uart_id, &uart_cfg, NULL); //uart_handler);
#if TUSB_OPT_DEVICE_ENABLED #if TUSB_OPT_DEVICE_ENABLED
// Priorities 0, 1, 4 (nRF52) are reserved for SoftDevice // Priorities 0, 1, 4 (nRF52) are reserved for SoftDevice
// 2 is highest for application // 2 is highest for application
NVIC_SetPriority(USBD_IRQn, 2); NVIC_SetPriority(USBD_IRQn, 2);
// USB power may already be ready at this time -> no event generated // USB power may already be ready at this time -> no event generated
// We need to invoke the handler based on the status initially // We need to invoke the handler based on the status initially
uint32_t usb_reg; uint32_t usb_reg;
@ -127,12 +151,12 @@ int board_uart_read(uint8_t* buf, int len)
{ {
(void) buf; (void) len; (void) buf; (void) len;
return 0; return 0;
// return NRFX_SUCCESS == nrfx_uart_rx(&_uart_id, buf, (size_t) len) ? len : 0;
} }
int board_uart_write(void const * buf, int len) int board_uart_write(void const * buf, int len)
{ {
(void) buf; (void) len; return (NRFX_SUCCESS == nrfx_uarte_tx(&_uart_id, (uint8_t const*) buf, (size_t) len)) ? len : 0;
return 0;
} }
#if CFG_TUSB_OS == OPT_OS_NONE #if CFG_TUSB_OS == OPT_OS_NONE

View File

@ -0,0 +1,63 @@
CFLAGS += \
-flto \
-mthumb \
-mabi=aapcs \
-mcpu=cortex-m4 \
-mfloat-abi=hard \
-mfpu=fpv4-sp-d16 \
-DCFG_TUSB_MCU=OPT_MCU_NRF5X \
-DNRF52840_XXAA \
-DCONFIG_GPIO_AS_PINRESET
# nrfx issue undef _ARMCC_VERSION usage https://github.com/NordicSemiconductor/nrfx/issues/49
CFLAGS += -Wno-error=undef -Wno-error=unused-parameter
# due to tusb_hal_nrf_power_event
GCCVERSION = $(firstword $(subst ., ,$(shell arm-none-eabi-gcc -dumpversion)))
ifeq ($(shell expr $(GCCVERSION) \>= 8), 1)
CFLAGS += -Wno-error=cast-function-type
endif
# All source paths should be relative to the top level.
LD_FILE = hw/bsp/$(BOARD)/nrf52840_s140_v6.ld
LDFLAGS += -L$(TOP)/hw/mcu/nordic/nrfx/mdk
SRC_C += \
hw/mcu/nordic/nrfx/drivers/src/nrfx_power.c \
hw/mcu/nordic/nrfx/mdk/system_nrf52840.c \
INC += \
$(TOP)/hw/mcu/nordic/cmsis/Include \
$(TOP)/hw/mcu/nordic \
$(TOP)/hw/mcu/nordic/nrfx \
$(TOP)/hw/mcu/nordic/nrfx/mdk \
$(TOP)/hw/mcu/nordic/nrfx/hal \
$(TOP)/hw/mcu/nordic/nrfx/drivers/include \
$(TOP)/hw/mcu/nordic/nrfx/drivers/src \
SRC_S += hw/mcu/nordic/nrfx/mdk/gcc_startup_nrf52840.S
ASFLAGS += -D__HEAP_SIZE=0
# For TinyUSB port source
VENDOR = nordic
CHIP_FAMILY = nrf5x
# For freeRTOS port source
FREERTOS_PORT = ARM_CM4F
# For flash-jlink target
JLINK_DEVICE = nRF52840_xxAA
JLINK_IF = swd
# For uf2 conversion
UF2_FAMILY = 0xADA52840
$(BUILD)/$(BOARD)-firmware.zip: $(BUILD)/$(BOARD)-firmware.hex
adafruit-nrfutil dfu genpkg --dev-type 0x0052 --sd-req 0xFFFE --application $^ $@
# flash using adafruit-nrfutil dfu
flash: $(BUILD)/$(BOARD)-firmware.zip
@:$(call check_defined, SERIAL, example: SERIAL=/dev/ttyACM0)
adafruit-nrfutil --verbose dfu serial --package $^ -p $(SERIAL) -b 115200 --singlebank --touch 1200

View File

@ -0,0 +1,189 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
#include "bsp/board.h"
#include "nrfx.h"
#include "nrfx/hal/nrf_gpio.h"
#include "nrfx/drivers/include/nrfx_power.h"
#ifdef SOFTDEVICE_PRESENT
#include "nrf_sdm.h"
#include "nrf_soc.h"
#endif
/*------------------------------------------------------------------*/
/* MACRO TYPEDEF CONSTANT ENUM
*------------------------------------------------------------------*/
#define _PINNUM(port, pin) ((port)*32 + (pin))
#define LED_PIN _PINNUM(1, 9)
#define LED_STATE_ON 1
#define BUTTON_PIN _PINNUM(1, 02)
// 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.
extern void tusb_hal_nrf_power_event(uint32_t event);
void board_init(void)
{
// Config clock source: XTAL or RC in sdk_config.h
NRF_CLOCK->LFCLKSRC = (uint32_t)((CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos) & CLOCK_LFCLKSRC_SRC_Msk);
NRF_CLOCK->TASKS_LFCLKSTART = 1UL;
// LED
nrf_gpio_cfg_output(LED_PIN);
board_led_write(false);
// Button
nrf_gpio_cfg_input(BUTTON_PIN, NRF_GPIO_PIN_PULLUP);
// 1ms tick timer
SysTick_Config(SystemCoreClock/1000);
#if TUSB_OPT_DEVICE_ENABLED
// Priorities 0, 1, 4 (nRF52) are reserved for SoftDevice
// 2 is highest for application
NVIC_SetPriority(USBD_IRQn, 2);
// USB power may already be ready at this time -> no event generated
// We need to invoke the handler based on the status initially
uint32_t usb_reg;
#ifdef SOFTDEVICE_PRESENT
uint8_t sd_en = false;
sd_softdevice_is_enabled(&sd_en);
if ( sd_en ) {
sd_power_usbdetected_enable(true);
sd_power_usbpwrrdy_enable(true);
sd_power_usbremoved_enable(true);
sd_power_usbregstatus_get(&usb_reg);
}else
#endif
{
// Power module init
const nrfx_power_config_t pwr_cfg = { 0 };
nrfx_power_init(&pwr_cfg);
// Register tusb function as USB power handler
const nrfx_power_usbevt_config_t config = { .handler = (nrfx_power_usb_event_handler_t) tusb_hal_nrf_power_event };
nrfx_power_usbevt_init(&config);
nrfx_power_usbevt_enable();
usb_reg = NRF_POWER->USBREGSTATUS;
}
if ( usb_reg & POWER_USBREGSTATUS_VBUSDETECT_Msk ) tusb_hal_nrf_power_event(NRFX_POWER_USB_EVT_DETECTED);
if ( usb_reg & POWER_USBREGSTATUS_OUTPUTRDY_Msk ) tusb_hal_nrf_power_event(NRFX_POWER_USB_EVT_READY);
#endif
}
//--------------------------------------------------------------------+
// Board porting API
//--------------------------------------------------------------------+
void board_led_write(bool state)
{
nrf_gpio_pin_write(LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON));
}
uint32_t board_button_read(void)
{
// button is active LOW
return (nrf_gpio_pin_read(BUTTON_PIN) ? 0 : 1);
}
int board_uart_read(uint8_t* buf, int len)
{
(void) buf; (void) len;
return 0;
}
int board_uart_write(void const * buf, int len)
{
(void) buf; (void) len;
return 0;
}
#if CFG_TUSB_OS == OPT_OS_NONE
volatile uint32_t system_ticks = 0;
void SysTick_Handler (void)
{
system_ticks++;
}
uint32_t board_millis(void)
{
return system_ticks;
}
#endif
#ifdef SOFTDEVICE_PRESENT
// process SOC event from SD
uint32_t proc_soc(void)
{
uint32_t soc_evt;
uint32_t err = sd_evt_get(&soc_evt);
if (NRF_SUCCESS == err)
{
/*------------- usb power event handler -------------*/
int32_t usbevt = (soc_evt == NRF_EVT_POWER_USB_DETECTED ) ? NRFX_POWER_USB_EVT_DETECTED:
(soc_evt == NRF_EVT_POWER_USB_POWER_READY) ? NRFX_POWER_USB_EVT_READY :
(soc_evt == NRF_EVT_POWER_USB_REMOVED ) ? NRFX_POWER_USB_EVT_REMOVED : -1;
if ( usbevt >= 0) tusb_hal_nrf_power_event(usbevt);
}
return err;
}
uint32_t proc_ble(void)
{
// do nothing with ble
return NRF_ERROR_NOT_FOUND;
}
void SD_EVT_IRQHandler(void)
{
// process BLE and SOC until there is no more events
while( (NRF_ERROR_NOT_FOUND != proc_ble()) || (NRF_ERROR_NOT_FOUND != proc_soc()) )
{
}
}
void nrf_error_cb(uint32_t id, uint32_t pc, uint32_t info)
{
(void) id;
(void) pc;
(void) info;
}
#endif

View File

@ -0,0 +1,38 @@
/* Linker script to configure memory regions. */
SEARCH_DIR(.)
GROUP(-lgcc -lc -lnosys)
MEMORY
{
FLASH (rx) : ORIGIN = 0x26000, LENGTH = 0xED000 - 0x26000
/* SRAM required by S132 depend on
* - Attribute Table Size
* - Vendor UUID count
* - Max ATT MTU
* - Concurrent connection peripheral + central + secure links
* - Event Len, HVN queue, Write CMD queue
*/
RAM (rwx) : ORIGIN = 0x20003400, LENGTH = 0x20040000 - 0x20003400
}
SECTIONS
{
. = ALIGN(4);
.svc_data :
{
PROVIDE(__start_svc_data = .);
KEEP(*(.svc_data))
PROVIDE(__stop_svc_data = .);
} > RAM
.fs_data :
{
PROVIDE(__start_fs_data = .);
KEEP(*(.fs_data))
PROVIDE(__stop_fs_data = .);
} > RAM
} INSERT AFTER .data;
INCLUDE "nrf52_common.ld"

View File

@ -13,7 +13,7 @@ ST_HAL_DRIVER = hw/mcu/st/st_driver/STM32F4xx_HAL_Driver
ST_CMSIS = hw/mcu/st/st_driver/CMSIS/Device/ST/STM32F4xx ST_CMSIS = hw/mcu/st/st_driver/CMSIS/Device/ST/STM32F4xx
# All source paths should be relative to the top level. # All source paths should be relative to the top level.
LD_FILE = hw/bsp/pyboardv11/STM32F405RGTx_FLASH.ld LD_FILE = hw/bsp/$(BOARD)/STM32F405RGTx_FLASH.ld
SRC_C += \ SRC_C += \
$(ST_CMSIS)/Source/Templates/system_stm32f4xx.c \ $(ST_CMSIS)/Source/Templates/system_stm32f4xx.c \

View File

@ -9,7 +9,7 @@ MCU_DIR = hw/mcu/fomu
BSP_DIR = hw/bsp/fomu BSP_DIR = hw/bsp/fomu
# All source paths should be relative to the top level. # All source paths should be relative to the top level.
LD_FILE = hw/bsp/fomu/fomu.ld LD_FILE = hw/bsp/$(BOARD)/fomu.ld
# TODO remove later # TODO remove later
SRC_C += src/portable/$(VENDOR)/$(CHIP_FAMILY)/hal_$(CHIP_FAMILY).c SRC_C += src/portable/$(VENDOR)/$(CHIP_FAMILY)/hal_$(CHIP_FAMILY).c
@ -25,6 +25,9 @@ INC += \
VENDOR = valentyusb VENDOR = valentyusb
CHIP_FAMILY = eptri CHIP_FAMILY = eptri
# For freeRTOS port source
FREERTOS_PORT = RISC-V
# flash using dfu-util # flash using dfu-util
flash: $(BUILD)/$(BOARD)-firmware.dfu flash: $(BUILD)/$(BOARD)-firmware.dfu
dfu-util -D $^ dfu-util -D $^

View File

@ -0,0 +1,45 @@
CFLAGS += \
-flto \
-mthumb \
-mabi=aapcs-linux \
-mcpu=cortex-m0plus \
-nostdlib -nostartfiles \
-D__SAMD21G18A__ \
-DCONF_DFLL_OVERWRITE_CALIBRATION=0 \
-DCFG_TUSB_MCU=OPT_MCU_SAMD21
# All source paths should be relative to the top level.
LD_FILE = hw/bsp/$(BOARD)/samd21g18a_flash.ld
SRC_C += \
hw/mcu/microchip/samd/asf4/samd21/gcc/gcc/startup_samd21.c \
hw/mcu/microchip/samd/asf4/samd21/gcc/system_samd21.c \
hw/mcu/microchip/samd/asf4/samd21/hpl/gclk/hpl_gclk.c \
hw/mcu/microchip/samd/asf4/samd21/hpl/pm/hpl_pm.c \
hw/mcu/microchip/samd/asf4/samd21/hpl/sysctrl/hpl_sysctrl.c \
hw/mcu/microchip/samd/asf4/samd21/hal/src/hal_atomic.c
INC += \
$(TOP)/hw/mcu/microchip/samd/asf4/samd21/ \
$(TOP)/hw/mcu/microchip/samd/asf4/samd21/config \
$(TOP)/hw/mcu/microchip/samd/asf4/samd21/include \
$(TOP)/hw/mcu/microchip/samd/asf4/samd21/hal/include \
$(TOP)/hw/mcu/microchip/samd/asf4/samd21/hal/utils/include \
$(TOP)/hw/mcu/microchip/samd/asf4/samd21/hpl/pm/ \
$(TOP)/hw/mcu/microchip/samd/asf4/samd21/hpl/port \
$(TOP)/hw/mcu/microchip/samd/asf4/samd21/hri \
$(TOP)/hw/mcu/microchip/samd/asf4/samd21/CMSIS/Include
# For TinyUSB port source
VENDOR = microchip
CHIP_FAMILY = samd
# For freeRTOS port source
FREERTOS_PORT = ARM_CM0
# For flash-jlink target
JLINK_DEVICE = ATSAMD21G18
JLINK_IF = swd
# flash using jlink
flash: flash-jlink

Some files were not shown because too many files have changed in this diff Show More