Merge pull request #17 from hathach/devlocal

dcd lpc17xx update
This commit is contained in:
hathach 2018-11-29 22:24:09 +07:00 committed by GitHub
commit 861e7e6a79
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
48 changed files with 25323 additions and 556 deletions

View File

@ -3,4 +3,6 @@
<import file_name="nrf5x/nrf5x.emProject" /> <import file_name="nrf5x/nrf5x.emProject" />
<import file_name="samd21/samd21.emProject" /> <import file_name="samd21/samd21.emProject" />
<import file_name="samd51/samd51.emProject" /> <import file_name="samd51/samd51.emProject" />
<import file_name="lpc43xx/lpc43xx.emProject" />
<import file_name="lpc175x_6x/lpc175x_6x.emProject" />
</solution> </solution>

View File

@ -0,0 +1,109 @@
/*****************************************************************************
* SEGGER Microcontroller GmbH & Co. KG *
* Solutions for real time microcontroller applications *
*****************************************************************************
* *
* (c) 2015 SEGGER Microcontroller GmbH & Co. KG *
* *
* Internet: www.segger.com Support: support@segger.com *
* *
*****************************************************************************/
/*****************************************************************************
* Preprocessor Definitions *
* ------------------------ *
* NO_STACK_INIT *
* *
* If defined, the stack pointer will not be initialised. *
* *
* NO_SYSTEM_INIT *
* *
* If defined, the SystemInit() function will not be called. By default *
* SystemInit() is called after reset to enable the clocks and memories to *
* be initialised prior to any C startup initialisation. *
* *
* NO_VTOR_CONFIG *
* *
* If defined, the vector table offset register will not be configured. *
* *
* MEMORY_INIT *
* *
* If defined, the MemoryInit() function will be called. By default *
* MemoryInit() is called after SystemInit() to enable an external memory *
* controller. *
* *
* STACK_INIT_VAL *
* *
* If defined, specifies the initial stack pointer value. If undefined, *
* the stack pointer will be initialised to point to the end of the *
* RAM segment. *
* *
* VECTORS_IN_RAM *
* *
* If defined, the exception vectors will be copied from Flash to RAM. *
* *
*****************************************************************************/
.syntax unified
.global Reset_Handler
.extern _vectors
.section .init, "ax"
.thumb_func
.equ VTOR_REG, 0xE000ED08
#ifndef STACK_INIT_VAL
#define STACK_INIT_VAL __RAM_segment_end__
#endif
Reset_Handler:
#ifndef NO_STACK_INIT
/* Initialise main stack */
ldr r0, =STACK_INIT_VAL
bic r0, #0x7
mov sp, r0
#endif
#ifndef NO_SYSTEM_INIT
/* Initialise system */
ldr r0, =SystemInit
blx r0
#endif
#ifdef MEMORY_INIT
ldr r0, =MemoryInit
blx r0
#endif
#ifdef VECTORS_IN_RAM
/* Copy exception vectors into RAM */
ldr r0, =__vectors_start__
ldr r1, =__vectors_end__
ldr r2, =__vectors_ram_start__
1:
cmp r0, r1
beq 2f
ldr r3, [r0]
str r3, [r2]
adds r0, r0, #4
adds r2, r2, #4
b 1b
2:
#endif
#ifndef NO_VTOR_CONFIG
/* Configure vector table offset register */
ldr r0, =VTOR_REG
#ifdef VECTORS_IN_RAM
ldr r1, =_vectors_ram
#else
ldr r1, =_vectors
#endif
str r1, [r0]
#endif
/* Jump to program start */
b _start

View File

@ -0,0 +1,19 @@
/*****************************************************************************
* SEGGER Microcontroller GmbH & Co. KG *
* Solutions for real time microcontroller applications *
*****************************************************************************
* *
* (c) 2015 SEGGER Microcontroller GmbH & Co. KG *
* *
* Internet: www.segger.com Support: support@segger.com *
* *
*****************************************************************************/
function Reset() {
TargetInterface.resetAndStop();
}
function EnableTrace(traceInterfaceType) {
// TODO: Enable trace
}

View File

@ -0,0 +1,6 @@
<!DOCTYPE Board_Memory_Definition_File>
<root name="LPC1769">
<MemorySegment name="FLASH" start="0x00000000" size="0x00080000" access="ReadOnly" />
<MemorySegment name="RAM" start="0x10000000" size="0x00008000" access="Read/Write" />
<MemorySegment name="RAM2" start="0x2007C000" size="0x00008000" access="Read/Write" />
</root>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,418 @@
/*****************************************************************************
* SEGGER Microcontroller GmbH & Co. KG *
* Solutions for real time microcontroller applications *
*****************************************************************************
* *
* (c) 2015 SEGGER Microcontroller GmbH & Co. KG *
* *
* Internet: www.segger.com Support: support@segger.com *
* *
*****************************************************************************/
/*****************************************************************************
* Preprocessor Definitions *
* ------------------------ *
* VECTORS_IN_RAM *
* *
* If defined, an area of RAM will large enough to store the vector table *
* will be reserved. *
* *
*****************************************************************************/
.syntax unified
.code 16
.section .init, "ax"
.align 0
/*****************************************************************************
* Default Exception Handlers *
*****************************************************************************/
.thumb_func
.weak NMI_Handler
NMI_Handler:
b .
.thumb_func
.weak HardFault_Handler
HardFault_Handler:
b .
.thumb_func
.weak SVC_Handler
SVC_Handler:
b .
.thumb_func
.weak PendSV_Handler
PendSV_Handler:
b .
.thumb_func
.weak SysTick_Handler
SysTick_Handler:
b .
.thumb_func
Dummy_Handler:
b .
#if defined(__OPTIMIZATION_SMALL)
.weak WDT_IRQHandler
.thumb_set WDT_IRQHandler,Dummy_Handler
.weak TIMER0_IRQHandler
.thumb_set TIMER0_IRQHandler,Dummy_Handler
.weak TIMER1_IRQHandler
.thumb_set TIMER1_IRQHandler,Dummy_Handler
.weak TIMER2_IRQHandler
.thumb_set TIMER2_IRQHandler,Dummy_Handler
.weak TIMER3_IRQHandler
.thumb_set TIMER3_IRQHandler,Dummy_Handler
.weak UART0_IRQHandler
.thumb_set UART0_IRQHandler,Dummy_Handler
.weak UART1_IRQHandler
.thumb_set UART1_IRQHandler,Dummy_Handler
.weak UART2_IRQHandler
.thumb_set UART2_IRQHandler,Dummy_Handler
.weak UART3_IRQHandler
.thumb_set UART3_IRQHandler,Dummy_Handler
.weak PWM1_IRQHandler
.thumb_set PWM1_IRQHandler,Dummy_Handler
.weak I2C0_IRQHandler
.thumb_set I2C0_IRQHandler,Dummy_Handler
.weak I2C1_IRQHandler
.thumb_set I2C1_IRQHandler,Dummy_Handler
.weak I2C2_IRQHandler
.thumb_set I2C2_IRQHandler,Dummy_Handler
.weak SPI_IRQHandler
.thumb_set SPI_IRQHandler,Dummy_Handler
.weak SSP0_IRQHandler
.thumb_set SSP0_IRQHandler,Dummy_Handler
.weak SSP1_IRQHandler
.thumb_set SSP1_IRQHandler,Dummy_Handler
.weak PLL0_IRQHandler
.thumb_set PLL0_IRQHandler,Dummy_Handler
.weak RTC_IRQHandler
.thumb_set RTC_IRQHandler,Dummy_Handler
.weak EINT0_IRQHandler
.thumb_set EINT0_IRQHandler,Dummy_Handler
.weak EINT1_IRQHandler
.thumb_set EINT1_IRQHandler,Dummy_Handler
.weak EINT2_IRQHandler
.thumb_set EINT2_IRQHandler,Dummy_Handler
.weak EINT3_IRQHandler
.thumb_set EINT3_IRQHandler,Dummy_Handler
.weak ADC_IRQHandler
.thumb_set ADC_IRQHandler,Dummy_Handler
.weak BOD_IRQHandler
.thumb_set BOD_IRQHandler,Dummy_Handler
.weak USB_IRQHandler
.thumb_set USB_IRQHandler,Dummy_Handler
.weak CAN_IRQHandler
.thumb_set CAN_IRQHandler,Dummy_Handler
.weak DMA_IRQHandler
.thumb_set DMA_IRQHandler,Dummy_Handler
.weak I2S_IRQHandler
.thumb_set I2S_IRQHandler,Dummy_Handler
.weak ENET_IRQHandler
.thumb_set ENET_IRQHandler,Dummy_Handler
.weak RIT_IRQHandler
.thumb_set RIT_IRQHandler,Dummy_Handler
.weak MCPWM_IRQHandler
.thumb_set MCPWM_IRQHandler,Dummy_Handler
.weak QEI_IRQHandler
.thumb_set QEI_IRQHandler,Dummy_Handler
.weak PLL1_IRQHandler
.thumb_set PLL1_IRQHandler,Dummy_Handler
.weak USBActivity_IRQHandler
.thumb_set USBActivity_IRQHandler,Dummy_Handler
.weak CANActivity_IRQHandler
.thumb_set CANActivity_IRQHandler,Dummy_Handler
#else
.thumb_func
.weak WDT_IRQHandler
WDT_IRQHandler:
b .
.thumb_func
.weak TIMER0_IRQHandler
TIMER0_IRQHandler:
b .
.thumb_func
.weak TIMER1_IRQHandler
TIMER1_IRQHandler:
b .
.thumb_func
.weak TIMER2_IRQHandler
TIMER2_IRQHandler:
b .
.thumb_func
.weak TIMER3_IRQHandler
TIMER3_IRQHandler:
b .
.thumb_func
.weak UART0_IRQHandler
UART0_IRQHandler:
b .
.thumb_func
.weak UART1_IRQHandler
UART1_IRQHandler:
b .
.thumb_func
.weak UART2_IRQHandler
UART2_IRQHandler:
b .
.thumb_func
.weak UART3_IRQHandler
UART3_IRQHandler:
b .
.thumb_func
.weak PWM1_IRQHandler
PWM1_IRQHandler:
b .
.thumb_func
.weak I2C0_IRQHandler
I2C0_IRQHandler:
b .
.thumb_func
.weak I2C1_IRQHandler
I2C1_IRQHandler:
b .
.thumb_func
.weak I2C2_IRQHandler
I2C2_IRQHandler:
b .
.thumb_func
.weak SPI_IRQHandler
SPI_IRQHandler:
b .
.thumb_func
.weak SSP0_IRQHandler
SSP0_IRQHandler:
b .
.thumb_func
.weak SSP1_IRQHandler
SSP1_IRQHandler:
b .
.thumb_func
.weak PLL0_IRQHandler
PLL0_IRQHandler:
b .
.thumb_func
.weak RTC_IRQHandler
RTC_IRQHandler:
b .
.thumb_func
.weak EINT0_IRQHandler
EINT0_IRQHandler:
b .
.thumb_func
.weak EINT1_IRQHandler
EINT1_IRQHandler:
b .
.thumb_func
.weak EINT2_IRQHandler
EINT2_IRQHandler:
b .
.thumb_func
.weak EINT3_IRQHandler
EINT3_IRQHandler:
b .
.thumb_func
.weak ADC_IRQHandler
ADC_IRQHandler:
b .
.thumb_func
.weak BOD_IRQHandler
BOD_IRQHandler:
b .
.thumb_func
.weak USB_IRQHandler
USB_IRQHandler:
b .
.thumb_func
.weak CAN_IRQHandler
CAN_IRQHandler:
b .
.thumb_func
.weak DMA_IRQHandler
DMA_IRQHandler:
b .
.thumb_func
.weak I2S_IRQHandler
I2S_IRQHandler:
b .
.thumb_func
.weak ENET_IRQHandler
ENET_IRQHandler:
b .
.thumb_func
.weak RIT_IRQHandler
RIT_IRQHandler:
b .
.thumb_func
.weak MCPWM_IRQHandler
MCPWM_IRQHandler:
b .
.thumb_func
.weak QEI_IRQHandler
QEI_IRQHandler:
b .
.thumb_func
.weak PLL1_IRQHandler
PLL1_IRQHandler:
b .
.thumb_func
.weak USBActivity_IRQHandler
USBActivity_IRQHandler:
b .
.thumb_func
.weak CANActivity_IRQHandler
CANActivity_IRQHandler:
b .
#endif
/*****************************************************************************
* Vector Table *
*****************************************************************************/
.section .vectors, "ax"
.align 0
.global _vectors
.extern __stack_end__
.extern Reset_Handler
_vectors:
.word __stack_end__
.word Reset_Handler
.word NMI_Handler
.word HardFault_Handler
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word SVC_Handler
.word 0 /* Reserved */
.word 0 /* Reserved */
.word PendSV_Handler
.word SysTick_Handler
.word WDT_IRQHandler
.word TIMER0_IRQHandler
.word TIMER1_IRQHandler
.word TIMER2_IRQHandler
.word TIMER3_IRQHandler
.word UART0_IRQHandler
.word UART1_IRQHandler
.word UART2_IRQHandler
.word UART3_IRQHandler
.word PWM1_IRQHandler
.word I2C0_IRQHandler
.word I2C1_IRQHandler
.word I2C2_IRQHandler
.word SPI_IRQHandler
.word SSP0_IRQHandler
.word SSP1_IRQHandler
.word PLL0_IRQHandler
.word RTC_IRQHandler
.word EINT0_IRQHandler
.word EINT1_IRQHandler
.word EINT2_IRQHandler
.word EINT3_IRQHandler
.word ADC_IRQHandler
.word BOD_IRQHandler
.word USB_IRQHandler
.word CAN_IRQHandler
.word DMA_IRQHandler
.word I2S_IRQHandler
.word ENET_IRQHandler
.word RIT_IRQHandler
.word MCPWM_IRQHandler
.word QEI_IRQHandler
.word PLL1_IRQHandler
.word USBActivity_IRQHandler
.word CANActivity_IRQHandler
_vectors_end:
#ifdef VECTORS_IN_RAM
.section .vectors_ram, "ax"
.align 0
.global _vectors_ram
_vectors_ram:
.space _vectors_end - _vectors, 0
#endif

View File

@ -0,0 +1,37 @@
<!DOCTYPE Linker_Placement_File>
<Root name="Flash Section Placement">
<MemorySegment name="$(FLASH_NAME:FLASH)">
<ProgramSection alignment="0x100" load="Yes" name=".vectors" start="$(FLASH_START:)" />
<ProgramSection alignment="4" load="Yes" name=".init" />
<ProgramSection alignment="4" load="Yes" name=".init_rodata" />
<ProgramSection alignment="4" load="Yes" name=".text" />
<ProgramSection alignment="4" load="Yes" name=".dtors" />
<ProgramSection alignment="4" load="Yes" name=".ctors" />
<ProgramSection alignment="4" load="Yes" name=".rodata" />
<ProgramSection alignment="4" load="Yes" name=".ARM.exidx" address_symbol="__exidx_start" end_symbol="__exidx_end" />
<ProgramSection alignment="4" load="Yes" runin=".fast_run" name=".fast" />
<ProgramSection alignment="4" load="Yes" runin=".data_run" name=".data" />
<ProgramSection alignment="4" load="Yes" runin=".tdata_run" name=".tdata" />
</MemorySegment>
<MemorySegment name="$(RAM_NAME:RAM);SRAM">
<ProgramSection alignment="0x100" load="No" name=".vectors_ram" start="$(RAM_START:$(SRAM_START:))" />
<ProgramSection alignment="4" load="No" name=".fast_run" />
<ProgramSection alignment="4" load="No" name=".data_run" />
<ProgramSection alignment="4" load="No" name=".bss" />
<ProgramSection alignment="4" load="No" name=".tbss" />
<ProgramSection alignment="4" load="No" name=".tdata_run" />
<ProgramSection alignment="4" load="No" name=".non_init" />
<ProgramSection alignment="4" size="__HEAPSIZE__" load="No" name=".heap" />
<ProgramSection alignment="8" size="__STACKSIZE__" load="No" place_from_segment_end="Yes" name=".stack" />
<ProgramSection alignment="8" size="__STACKSIZE_PROCESS__" load="No" name=".stack_process" />
</MemorySegment>
<MemorySegment name="$(FLASH2_NAME:FLASH2)">
<ProgramSection alignment="4" load="Yes" name=".text2" />
<ProgramSection alignment="4" load="Yes" name=".rodata2" />
<ProgramSection alignment="4" load="Yes" runin=".data2_run" name=".data2" />
</MemorySegment>
<MemorySegment name="$(RAM2_NAME:RAM2)">
<ProgramSection alignment="4" load="No" name=".data2_run" />
<ProgramSection alignment="4" load="No" name=".bss2" />
</MemorySegment>
</Root>

View File

@ -0,0 +1,100 @@
<!DOCTYPE CrossStudio_Project_File>
<solution Name="lpc175x_6x" target="8" version="2">
<project Name="lpc175x_6x">
<configuration
Name="Common"
Placement="Flash"
Target="LPC4357 Cortex-M4"
arm_architecture="v7M"
arm_core_type="Cortex-M3"
arm_endian="Little"
arm_fp_abi="Soft"
arm_fpu_type="None"
arm_interwork="No"
arm_linker_heap_size="1024"
arm_linker_process_stack_size="0"
arm_linker_stack_size="1024"
arm_simulator_memory_simulation_parameter="RX 00000000,00080000,FFFFFFFF;RWX 10000000,00008000,CDCDCDCD"
arm_target_debug_interface_type="ADIv5"
arm_target_device_name="LPC1769"
arm_target_interface_type="SWD"
build_treat_warnings_as_errors="No"
c_preprocessor_definitions="LPC175x_6x;__LPC1700_FAMILY;__LPC176x_SUBFAMILY;ARM_MATH_CM3;FLASH_PLACEMENT=1;BOARD_LPCXPRESSO1769;CFG_TUSB_MCU=OPT_MCU_LPC175X_6X"
c_user_include_directories="../../src;$(rootDir)/hw/cmsis/Include;$(rootDir)/hw;$(rootDir)/src;$(lpcDir)/CMSIS_CORE_LPC17xx/inc;$(lpcDir)/LPC17xx_DriverLib/include"
debug_register_definition_file="LPC176x5x_Registers.xml"
debug_target_connection="J-Link"
gcc_enable_all_warnings="Yes"
gcc_entry_point="Reset_Handler"
link_use_linker_script_file="No"
linker_memory_map_file="LPC1769_MemoryMap.xml"
linker_section_placement_file="flash_placement.xml"
linker_section_placements_segments="FLASH RX 0x00000000 0x00080000;RAM RWX 0x10000000 0x00008000"
macros="DeviceFamily=LPC1700;DeviceSubFamily=LPC176x;Target=LPC1769;Placement=Flash;rootDir=../../../../..;lpcDir=../../../../../hw/mcu/nxp/lpc175x_6x"
project_directory=""
project_type="Executable"
target_reset_script="Reset();"
target_script_file="$(ProjectDir)/LPC1700_Target.js"
target_trace_initialize_script="EnableTrace(&quot;$(TraceInterfaceType)&quot;)" />
<folder
Name="tinyusb"
exclude=""
filter="*.c;*.h"
path="../../../../../src"
recurse="Yes" />
<folder Name="hw">
<folder Name="bsp">
<file file_name="../../../../../hw/bsp/ansi_escape.h" />
<file file_name="../../../../../hw/bsp/board.h" />
<folder Name="lpcxpresso1769">
<file file_name="../../../../../hw/bsp/lpcxpresso1769/board_lpcxpresso1769.c" />
<file file_name="../../../../../hw/bsp/lpcxpresso1769/board_lpcxpresso1769.h" />
</folder>
</folder>
<folder Name="mcu">
<folder Name="nxp">
<folder Name="lpc175x_6x">
<folder Name="CMSIS_CORE_LPC17xx">
<folder Name="inc">
<file file_name="../../../../../hw/mcu/nxp/lpc175x_6x/CMSIS_CORE_LPC17xx/inc/LPC17xx.h" />
<file file_name="../../../../../hw/mcu/nxp/lpc175x_6x/CMSIS_CORE_LPC17xx/inc/system_LPC17xx.h" />
</folder>
<folder Name="src">
<file file_name="../../../../../hw/mcu/nxp/lpc175x_6x/CMSIS_CORE_LPC17xx/src/system_LPC17xx.c" />
</folder>
</folder>
<folder Name="LPC17xx_DriverLib">
<folder Name="include" />
<folder Name="source">
<file file_name="../../../../../hw/mcu/nxp/lpc175x_6x/LPC17xx_DriverLib/source/lpc17xx_gpio.c" />
<file file_name="../../../../../hw/mcu/nxp/lpc175x_6x/LPC17xx_DriverLib/source/lpc17xx_pinsel.c" />
</folder>
</folder>
</folder>
</folder>
</folder>
</folder>
<configuration Name="Debug" build_treat_warnings_as_errors="Yes" />
<folder
Name="src"
exclude=""
filter="*.c;*.h"
path="../../src"
recurse="Yes" />
<folder Name="System Files">
<file file_name="flash_placement.xml" />
<file file_name="LPC1700_Startup.s" />
<file file_name="LPC1700_Target.js" />
<file file_name="LPC1769_MemoryMap.xml" />
<file file_name="LPC176x5x_Registers.xml" />
<file file_name="LPC176x5x_Vectors.s" />
<file file_name="thumb_crt0.s" />
</folder>
<folder
Name="segger_rtt"
exclude=""
filter="*.c;*.h"
path="../../../../../lib/segger_rtt"
recurse="No" />
</project>
<configuration Name="LPCXpresso 1769" />
</solution>

View File

@ -0,0 +1,415 @@
// **********************************************************************
// * SEGGER Microcontroller GmbH *
// * The Embedded Experts *
// **********************************************************************
// * *
// * (c) 2014 - 2018 SEGGER Microcontroller GmbH *
// * (c) 2001 - 2018 Rowley Associates Limited *
// * *
// * www.segger.com Support: support@segger.com *
// * *
// **********************************************************************
// * *
// * All rights reserved. *
// * *
// * Redistribution and use in source and binary forms, with or *
// * without modification, are permitted provided that the following *
// * conditions are met: *
// * *
// * - Redistributions of source code must retain the above copyright *
// * notice, this list of conditions and the following disclaimer. *
// * *
// * - Neither the name of SEGGER Microcontroller GmbH *
// * nor the names of its contributors may be used to endorse or *
// * promote products derived from this software without specific *
// * prior written permission. *
// * *
// * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
// * CONTRIBUTORS "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 SEGGER Microcontroller GmbH 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. *
// * *
// **********************************************************************
//
//
// Preprocessor Definitions
// ------------------------
// APP_ENTRY_POINT
//
// Defines the application entry point function, if undefined this setting
// defaults to "main".
//
// INITIALIZE_STACK
//
// If defined, the contents of the stack will be initialized to a the
// value 0xCC.
//
// INITIALIZE_SECONDARY_SECTIONS
//
// If defined, the .data2, .text2, .rodata2 and .bss2 sections will be initialized.
//
// INITIALIZE_TCM_SECTIONS
//
// If defined, the .data_tcm, .text_tcm, .rodata_tcm and .bss_tcm sections
// will be initialized.
//
// INITIALIZE_USER_SECTIONS
//
// If defined, the function InitializeUserMemorySections will be called prior
// to entering main in order to allow the user to initialize any user defined
// memory sections.
//
// FULL_LIBRARY
//
// If defined then
// - argc, argv are setup by the debug_getargs.
// - the exit symbol is defined and executes on return from main.
// - the exit symbol calls destructors, atexit functions and then debug_exit.
//
// If not defined then
// - argc and argv are zero.
// - the exit symbol is defined, executes on return from main and loops
//
#ifndef APP_ENTRY_POINT
#define APP_ENTRY_POINT main
#endif
#ifndef ARGSSPACE
#define ARGSSPACE 128
#endif
.syntax unified
.global _start
.extern APP_ENTRY_POINT
.global exit
.weak exit
#ifdef INITIALIZE_USER_SECTIONS
.extern InitializeUserMemorySections
#endif
.section .init, "ax"
.code 16
.balign 2
.thumb_func
_start:
/* Set up main stack if size > 0 */
ldr r1, =__stack_end__
ldr r0, =__stack_start__
subs r2, r1, r0
beq 1f
#ifdef __ARM_EABI__
movs r2, #0x7
bics r1, r2
#endif
mov sp, r1
#ifdef INITIALIZE_STACK
movs r2, #0xCC
ldr r0, =__stack_start__
bl memory_set
#endif
1:
/* Set up process stack if size > 0 */
ldr r1, =__stack_process_end__
ldr r0, =__stack_process_start__
subs r2, r1, r0
beq 1f
#ifdef __ARM_EABI__
movs r2, #0x7
bics r1, r2
#endif
msr psp, r1
movs r2, #2
msr control, r2
#ifdef INITIALIZE_STACK
movs r2, #0xCC
bl memory_set
#endif
1:
/* Copy initialized memory sections into RAM (if necessary). */
ldr r0, =__data_load_start__
ldr r1, =__data_start__
ldr r2, =__data_end__
bl memory_copy
ldr r0, =__text_load_start__
ldr r1, =__text_start__
ldr r2, =__text_end__
bl memory_copy
ldr r0, =__fast_load_start__
ldr r1, =__fast_start__
ldr r2, =__fast_end__
bl memory_copy
ldr r0, =__ctors_load_start__
ldr r1, =__ctors_start__
ldr r2, =__ctors_end__
bl memory_copy
ldr r0, =__dtors_load_start__
ldr r1, =__dtors_start__
ldr r2, =__dtors_end__
bl memory_copy
ldr r0, =__rodata_load_start__
ldr r1, =__rodata_start__
ldr r2, =__rodata_end__
bl memory_copy
ldr r0, =__tdata_load_start__
ldr r1, =__tdata_start__
ldr r2, =__tdata_end__
bl memory_copy
#ifdef INITIALIZE_SECONDARY_SECTIONS
ldr r0, =__data2_load_start__
ldr r1, =__data2_start__
ldr r2, =__data2_end__
bl memory_copy
ldr r0, =__text2_load_start__
ldr r1, =__text2_start__
ldr r2, =__text2_end__
bl memory_copy
ldr r0, =__rodata2_load_start__
ldr r1, =__rodata2_start__
ldr r2, =__rodata2_end__
bl memory_copy
#endif /* #ifdef INITIALIZE_SECONDARY_SECTIONS */
#ifdef INITIALIZE_TCM_SECTIONS
ldr r0, =__data_tcm_load_start__
ldr r1, =__data_tcm_start__
ldr r2, =__data_tcm_end__
bl memory_copy
ldr r0, =__text_tcm_load_start__
ldr r1, =__text_tcm_start__
ldr r2, =__text_tcm_end__
bl memory_copy
ldr r0, =__rodata_tcm_load_start__
ldr r1, =__rodata_tcm_start__
ldr r2, =__rodata_tcm_end__
bl memory_copy
#endif /* #ifdef INITIALIZE_TCM_SECTIONS */
/* Zero the bss. */
ldr r0, =__bss_start__
ldr r1, =__bss_end__
movs r2, #0
bl memory_set
ldr r0, =__tbss_start__
ldr r1, =__tbss_end__
movs r2, #0
bl memory_set
#ifdef INITIALIZE_SECONDARY_SECTIONS
ldr r0, =__bss2_start__
ldr r1, =__bss2_end__
mov r2, #0
bl memory_set
#endif /* #ifdef INITIALIZE_SECONDARY_SECTIONS */
#ifdef INITIALIZE_TCM_SECTIONS
ldr r0, =__bss_tcm_start__
ldr r1, =__bss_tcm_end__
mov r2, #0
bl memory_set
#endif /* #ifdef INITIALIZE_TCM_SECTIONS */
/* Initialize the heap */
ldr r0, = __heap_start__
ldr r1, = __heap_end__
subs r1, r1, r0
cmp r1, #8
blt 1f
movs r2, #0
str r2, [r0]
adds r0, r0, #4
str r1, [r0]
1:
#ifdef INITIALIZE_USER_SECTIONS
ldr r2, =InitializeUserMemorySections
blx r2
#endif
/* Call constructors */
ldr r0, =__ctors_start__
ldr r1, =__ctors_end__
ctor_loop:
cmp r0, r1
beq ctor_end
ldr r2, [r0]
adds r0, #4
push {r0-r1}
blx r2
pop {r0-r1}
b ctor_loop
ctor_end:
/* Setup initial call frame */
movs r0, #0
mov lr, r0
mov r12, sp
.type start, function
start:
/* Jump to application entry point */
#ifdef FULL_LIBRARY
movs r0, #ARGSSPACE
ldr r1, =args
ldr r2, =debug_getargs
blx r2
ldr r1, =args
#else
movs r0, #0
movs r1, #0
#endif
ldr r2, =APP_ENTRY_POINT
blx r2
.thumb_func
exit:
#ifdef FULL_LIBRARY
mov r5, r0 // save the exit parameter/return result
/* Call destructors */
ldr r0, =__dtors_start__
ldr r1, =__dtors_end__
dtor_loop:
cmp r0, r1
beq dtor_end
ldr r2, [r0]
add r0, #4
push {r0-r1}
blx r2
pop {r0-r1}
b dtor_loop
dtor_end:
/* Call atexit functions */
ldr r2, =_execute_at_exit_fns
blx r2
/* Call debug_exit with return result/exit parameter */
mov r0, r5
ldr r2, =debug_exit
blx r2
#endif
/* Returned from application entry point, loop forever. */
exit_loop:
b exit_loop
.thumb_func
memory_copy:
cmp r0, r1
beq 2f
subs r2, r2, r1
beq 2f
1:
ldrb r3, [r0]
adds r0, r0, #1
strb r3, [r1]
adds r1, r1, #1
subs r2, r2, #1
bne 1b
2:
bx lr
.thumb_func
memory_set:
cmp r0, r1
beq 1f
strb r2, [r0]
adds r0, r0, #1
b memory_set
1:
bx lr
// default C/C++ library helpers
.macro HELPER helper_name
.section .text.\helper_name, "ax", %progbits
.balign 2
.global \helper_name
.weak \helper_name
\helper_name:
.thumb_func
.endm
.macro JUMPTO name
#if defined(__thumb__) && !defined(__thumb2__)
mov r12, r0
ldr r0, =\name
push {r0}
mov r0, r12
pop {pc}
#else
b \name
#endif
.endm
HELPER __aeabi_read_tp
ldr r0, =__tbss_start__-8
bx lr
HELPER abort
b .
HELPER __assert
b .
HELPER __aeabi_assert
b .
HELPER __sync_synchronize
bx lr
HELPER __getchar
JUMPTO debug_getchar
HELPER __putchar
JUMPTO debug_putchar
HELPER __open
JUMPTO debug_fopen
HELPER __close
JUMPTO debug_fclose
HELPER __write
mov r3, r0
mov r0, r1
movs r1, #1
JUMPTO debug_fwrite
HELPER __read
mov r3, r0
mov r0, r1
movs r1, #1
JUMPTO debug_fread
HELPER __seek
push {r4, lr}
mov r4, r0
bl debug_fseek
cmp r0, #0
bne 1f
mov r0, r4
bl debug_ftell
pop {r4, pc}
1:
ldr r0, =-1
pop {r4, pc}
// char __user_locale_name_buffer[];
.section .bss.__user_locale_name_buffer, "aw", %nobits
.global __user_locale_name_buffer
.weak __user_locale_name_buffer
__user_locale_name_buffer:
.word 0x0
#ifdef FULL_LIBRARY
.bss
args:
.space ARGSSPACE
#endif
/* Setup attibutes of stack and heap sections so they don't take up room in the elf file */
.section .stack, "wa", %nobits
.section .stack_process, "wa", %nobits
.section .heap, "wa", %nobits

View File

@ -18,11 +18,12 @@
arm_target_debug_interface_type="ADIv5" arm_target_debug_interface_type="ADIv5"
arm_target_device_name="nRF52840_xxAA" arm_target_device_name="nRF52840_xxAA"
arm_target_interface_type="SWD" arm_target_interface_type="SWD"
build_treat_warnings_as_errors="Yes" build_treat_warnings_as_errors="No"
c_preprocessor_definitions="NRF52840_XXAA;__nRF_FAMILY;ARM_MATH_CM4;FLASH_PLACEMENT=1;BOARD_PCA10056;CFG_TUSB_MCU=OPT_MCU_NRF5X" c_preprocessor_definitions="NRF52840_XXAA;__nRF_FAMILY;ARM_MATH_CM4;FLASH_PLACEMENT=1;BOARD_PCA10056;CFG_TUSB_MCU=OPT_MCU_NRF5X"
c_user_include_directories="../../src;$(rootDir)/hw/cmsis/Include;$(rootDir)/hw;$(rootDir)/src;$(nrfxDir)/..;$(nrfxDir);$(nrfxDir)/mdk;$(nrfxDir)/hal;$(nrfxDir)/drivers/include" c_user_include_directories="../../src;$(rootDir)/hw/cmsis/Include;$(rootDir)/hw;$(rootDir)/src;$(nrfxDir)/..;$(nrfxDir);$(nrfxDir)/mdk;$(nrfxDir)/hal;$(nrfxDir)/drivers/include"
debug_register_definition_file="nrf52840_Registers.xml" debug_register_definition_file="nrf52840_Registers.xml"
debug_target_connection="J-Link" debug_target_connection="J-Link"
gcc_enable_all_warnings="Yes"
gcc_entry_point="Reset_Handler" gcc_entry_point="Reset_Handler"
link_use_linker_script_file="No" link_use_linker_script_file="No"
linker_memory_map_file="nRF52840_xxAA_MemoryMap.xml" linker_memory_map_file="nRF52840_xxAA_MemoryMap.xml"

View File

@ -57,9 +57,6 @@
<file file_name="../../../../../hw/mcu/microchip/samd/asf4/samd21/gcc/system_samd21.c" /> <file file_name="../../../../../hw/mcu/microchip/samd/asf4/samd21/gcc/system_samd21.c" />
</folder> </folder>
<folder Name="hpl"> <folder Name="hpl">
<folder Name="core">
<file file_name="../../../../../hw/mcu/microchip/samd/asf4/samd21/hpl/core/hpl_init.c" />
</folder>
<folder Name="gclk"> <folder Name="gclk">
<file file_name="../../../../../hw/mcu/microchip/samd/asf4/samd21/hpl/gclk/hpl_gclk.c" /> <file file_name="../../../../../hw/mcu/microchip/samd/asf4/samd21/hpl/gclk/hpl_gclk.c" />
</folder> </folder>

View File

@ -23,6 +23,7 @@
c_user_include_directories="../../src;$(rootDir)/hw/cmsis/Include;$(rootDir)/hw;$(rootDir)/src;$(asf4Dir);$(asf4Dir)/include;$(asf4Dir)/config;$(asf4Dir)/hri;$(asf4Dir)/hal/include;$(asf4Dir)/hal/utils/include;$(asf4Dir)/hpl/port;$(asf4Dir)/hpl/gclk" c_user_include_directories="../../src;$(rootDir)/hw/cmsis/Include;$(rootDir)/hw;$(rootDir)/src;$(asf4Dir);$(asf4Dir)/include;$(asf4Dir)/config;$(asf4Dir)/hri;$(asf4Dir)/hal/include;$(asf4Dir)/hal/utils/include;$(asf4Dir)/hpl/port;$(asf4Dir)/hpl/gclk"
debug_register_definition_file="ATSAMD51J19A_Registers.xml" debug_register_definition_file="ATSAMD51J19A_Registers.xml"
debug_target_connection="J-Link" debug_target_connection="J-Link"
gcc_enable_all_warnings="Yes"
gcc_entry_point="Reset_Handler" gcc_entry_point="Reset_Handler"
link_use_linker_script_file="No" link_use_linker_script_file="No"
linker_memory_map_file="ATSAMD51J19A_MemoryMap.xml" linker_memory_map_file="ATSAMD51J19A_MemoryMap.xml"
@ -58,9 +59,6 @@
<file file_name="../../../../../hw/mcu/microchip/samd/asf4/samd51/gcc/system_samd51.c" /> <file file_name="../../../../../hw/mcu/microchip/samd/asf4/samd51/gcc/system_samd51.c" />
</folder> </folder>
<folder Name="hpl"> <folder Name="hpl">
<folder Name="core">
<file file_name="../../../../../hw/mcu/microchip/samd/asf4/samd51/hpl/core/hpl_init.c" />
</folder>
<folder Name="osc32kctrl"> <folder Name="osc32kctrl">
<file file_name="../../../../../hw/mcu/microchip/samd/asf4/samd51/hpl/osc32kctrl/hpl_osc32kctrl.c" /> <file file_name="../../../../../hw/mcu/microchip/samd/asf4/samd51/hpl/osc32kctrl/hpl_osc32kctrl.c" />
</folder> </folder>

View File

@ -187,6 +187,7 @@ void tud_umount_cb(void)
void tud_cdc_rx_cb(uint8_t itf) void tud_cdc_rx_cb(uint8_t itf)
{ {
(void) itf;
} }
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+

View File

@ -52,10 +52,15 @@
// defined by compiler flags for flexibility // defined by compiler flags for flexibility
#ifndef CFG_TUSB_MCU #ifndef CFG_TUSB_MCU
#error CFG_TUSB_MCU should be defined using compiler flags #error CFG_TUSB_MCU must be defined
#endif #endif
#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX
#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED)
#else
#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE #define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE
#endif
#define CFG_TUSB_DEBUG 2 #define CFG_TUSB_DEBUG 2
#define CFG_TUSB_OS OPT_OS_NONE #define CFG_TUSB_OS OPT_OS_NONE
@ -88,12 +93,22 @@
*/ */
#define CFG_TUD_DESC_AUTO 1 #define CFG_TUD_DESC_AUTO 1
/* USB VID/PID if not defined, tinyusb to use default value /* If USB VID/PID is not defined, tinyusb will use default value
* Note: different class combination e.g CDC and (CDC + MSC) should have different * Note: different class combination e.g CDC and (CDC + MSC) should have different
* PID since Host OS will "remembered" device driver after the first plug */ * PID since Host OS will "remembered" device driver after the first plug */
// #define CFG_TUD_DESC_VID 0xCAFE // #define CFG_TUD_DESC_VID 0xCAFE
// #define CFG_TUD_DESC_PID 0x0001 // #define CFG_TUD_DESC_PID 0x0001
// LPC175x_6x's endpoint type (bulk/interrupt/iso) are fixed by its number
// Therefor we need to force endpoint number to correct type on lpc17xx
#if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X
#define CFG_TUD_DESC_CDC_EPNUM_NOTIF 1
#define CFG_TUD_DESC_CDC_EPNUM 2
#define CFG_TUD_DESC_MSC_EPNUM 5
#define CFG_TUD_DESC_HID_KEYBOARD_EPNUM 4
#define CFG_TUD_DESC_HID_MOUSE_EPNUM 7
#endif
//------------- CLASS -------------// //------------- CLASS -------------//
#define CFG_TUD_CDC 1 #define CFG_TUD_CDC 1
#define CFG_TUD_MSC 1 #define CFG_TUD_MSC 1
@ -109,7 +124,6 @@
#define CFG_TUD_HID_KEYBOARD_BOOT 1 #define CFG_TUD_HID_KEYBOARD_BOOT 1
#define CFG_TUD_HID_MOUSE_BOOT 1 #define CFG_TUD_HID_MOUSE_BOOT 1
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// CDC // CDC
//-------------------------------------------------------------------- //--------------------------------------------------------------------
@ -121,7 +135,6 @@
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// MSC // MSC
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// Number of supported Logical Unit Number (At least 1) // Number of supported Logical Unit Number (At least 1)
#define CFG_TUD_MSC_MAXLUN 1 #define CFG_TUD_MSC_MAXLUN 1

View File

@ -3,4 +3,5 @@
<import file_name="nrf5x/nrf5x.emProject" /> <import file_name="nrf5x/nrf5x.emProject" />
<import file_name="samd21/samd21.emProject" /> <import file_name="samd21/samd21.emProject" />
<import file_name="samd51/samd51.emProject" /> <import file_name="samd51/samd51.emProject" />
<import file_name="lpc175x_6x/lpc175x_6x.emProject" />
</solution> </solution>

View File

@ -4,8 +4,9 @@
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// See http://www.freertos.org/a00110.html. // See http://www.freertos.org/a00110.html.
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
//#include "bsp/board.h" #include "LPC17xx.h"
#include "nrf.h"
#define configCPU_CLOCK_HZ SystemCoreClock
#if 0 #if 0
#if CFG_TUSB_MCU == OPT_MCU_LPC43XX #if CFG_TUSB_MCU == OPT_MCU_LPC43XX
@ -15,12 +16,10 @@
#endif #endif
#endif #endif
#define configCPU_CLOCK_HZ SystemCoreClock
#define configUSE_PREEMPTION 1 #define configUSE_PREEMPTION 1
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
#define configTICK_RATE_HZ ( 1000 ) #define configTICK_RATE_HZ ( 1000 )
#define configMAX_PRIORITIES (5) #define configMAX_PRIORITIES (8)
#define configMINIMAL_STACK_SIZE (128 ) #define configMINIMAL_STACK_SIZE (128 )
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 16*1024 ) ) #define configTOTAL_HEAP_SIZE ( ( size_t ) ( 16*1024 ) )
#define configMAX_TASK_NAME_LEN 32 #define configMAX_TASK_NAME_LEN 32
@ -106,13 +105,14 @@ static inline void configASSERT_breakpoint(void)
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// Interrupt nesting behaviour configuration. // Interrupt nesting behaviour configuration.
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
/* Cortex-M specific definitions. __NVIC_PRIO_BITS is defined in core_cmx.h */ /* Cortex-M specific definitions. __NVIC_PRIO_BITS is defined in mcu_variant.h */
#ifdef __NVIC_PRIO_BITS #ifdef __NVIC_PRIO_BITS
#define configPRIO_BITS __NVIC_PRIO_BITS #define configPRIO_BITS __NVIC_PRIO_BITS
#else #else
#define configPRIO_BITS 5 // 32 priority levels #error "This port requires __NVIC_PRIO_BITS to be defined"
#endif #endif
/* The lowest interrupt priority that can be used in a call to a "set priority" /* The lowest interrupt priority that can be used in a call to a "set priority"
function. */ function. */
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 0x1f #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 0x1f
@ -121,14 +121,14 @@ function. */
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. */
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5 #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
to all Cortex-M ports, and do not rely on any particular library functions. */ to all Cortex-M ports, and do not rely on any particular library functions. */
#define configKERNEL_INTERRUPT_PRIORITY configLIBRARY_LOWEST_INTERRUPT_PRIORITY // ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) #define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! /* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY //( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) #define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
#endif /* __FREERTOS_CONFIG__H */ #endif /* __FREERTOS_CONFIG__H */

View File

@ -0,0 +1,109 @@
/*****************************************************************************
* SEGGER Microcontroller GmbH & Co. KG *
* Solutions for real time microcontroller applications *
*****************************************************************************
* *
* (c) 2015 SEGGER Microcontroller GmbH & Co. KG *
* *
* Internet: www.segger.com Support: support@segger.com *
* *
*****************************************************************************/
/*****************************************************************************
* Preprocessor Definitions *
* ------------------------ *
* NO_STACK_INIT *
* *
* If defined, the stack pointer will not be initialised. *
* *
* NO_SYSTEM_INIT *
* *
* If defined, the SystemInit() function will not be called. By default *
* SystemInit() is called after reset to enable the clocks and memories to *
* be initialised prior to any C startup initialisation. *
* *
* NO_VTOR_CONFIG *
* *
* If defined, the vector table offset register will not be configured. *
* *
* MEMORY_INIT *
* *
* If defined, the MemoryInit() function will be called. By default *
* MemoryInit() is called after SystemInit() to enable an external memory *
* controller. *
* *
* STACK_INIT_VAL *
* *
* If defined, specifies the initial stack pointer value. If undefined, *
* the stack pointer will be initialised to point to the end of the *
* RAM segment. *
* *
* VECTORS_IN_RAM *
* *
* If defined, the exception vectors will be copied from Flash to RAM. *
* *
*****************************************************************************/
.syntax unified
.global Reset_Handler
.extern _vectors
.section .init, "ax"
.thumb_func
.equ VTOR_REG, 0xE000ED08
#ifndef STACK_INIT_VAL
#define STACK_INIT_VAL __RAM_segment_end__
#endif
Reset_Handler:
#ifndef NO_STACK_INIT
/* Initialise main stack */
ldr r0, =STACK_INIT_VAL
bic r0, #0x7
mov sp, r0
#endif
#ifndef NO_SYSTEM_INIT
/* Initialise system */
ldr r0, =SystemInit
blx r0
#endif
#ifdef MEMORY_INIT
ldr r0, =MemoryInit
blx r0
#endif
#ifdef VECTORS_IN_RAM
/* Copy exception vectors into RAM */
ldr r0, =__vectors_start__
ldr r1, =__vectors_end__
ldr r2, =__vectors_ram_start__
1:
cmp r0, r1
beq 2f
ldr r3, [r0]
str r3, [r2]
adds r0, r0, #4
adds r2, r2, #4
b 1b
2:
#endif
#ifndef NO_VTOR_CONFIG
/* Configure vector table offset register */
ldr r0, =VTOR_REG
#ifdef VECTORS_IN_RAM
ldr r1, =_vectors_ram
#else
ldr r1, =_vectors
#endif
str r1, [r0]
#endif
/* Jump to program start */
b _start

View File

@ -0,0 +1,19 @@
/*****************************************************************************
* SEGGER Microcontroller GmbH & Co. KG *
* Solutions for real time microcontroller applications *
*****************************************************************************
* *
* (c) 2015 SEGGER Microcontroller GmbH & Co. KG *
* *
* Internet: www.segger.com Support: support@segger.com *
* *
*****************************************************************************/
function Reset() {
TargetInterface.resetAndStop();
}
function EnableTrace(traceInterfaceType) {
// TODO: Enable trace
}

View File

@ -0,0 +1,6 @@
<!DOCTYPE Board_Memory_Definition_File>
<root name="LPC1769">
<MemorySegment name="FLASH" start="0x00000000" size="0x00080000" access="ReadOnly" />
<MemorySegment name="RAM" start="0x10000000" size="0x00008000" access="Read/Write" />
<MemorySegment name="RAM2" start="0x2007C000" size="0x00008000" access="Read/Write" />
</root>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,418 @@
/*****************************************************************************
* SEGGER Microcontroller GmbH & Co. KG *
* Solutions for real time microcontroller applications *
*****************************************************************************
* *
* (c) 2015 SEGGER Microcontroller GmbH & Co. KG *
* *
* Internet: www.segger.com Support: support@segger.com *
* *
*****************************************************************************/
/*****************************************************************************
* Preprocessor Definitions *
* ------------------------ *
* VECTORS_IN_RAM *
* *
* If defined, an area of RAM will large enough to store the vector table *
* will be reserved. *
* *
*****************************************************************************/
.syntax unified
.code 16
.section .init, "ax"
.align 0
/*****************************************************************************
* Default Exception Handlers *
*****************************************************************************/
.thumb_func
.weak NMI_Handler
NMI_Handler:
b .
.thumb_func
.weak HardFault_Handler
HardFault_Handler:
b .
.thumb_func
.weak SVC_Handler
SVC_Handler:
b .
.thumb_func
.weak PendSV_Handler
PendSV_Handler:
b .
.thumb_func
.weak SysTick_Handler
SysTick_Handler:
b .
.thumb_func
Dummy_Handler:
b .
#if defined(__OPTIMIZATION_SMALL)
.weak WDT_IRQHandler
.thumb_set WDT_IRQHandler,Dummy_Handler
.weak TIMER0_IRQHandler
.thumb_set TIMER0_IRQHandler,Dummy_Handler
.weak TIMER1_IRQHandler
.thumb_set TIMER1_IRQHandler,Dummy_Handler
.weak TIMER2_IRQHandler
.thumb_set TIMER2_IRQHandler,Dummy_Handler
.weak TIMER3_IRQHandler
.thumb_set TIMER3_IRQHandler,Dummy_Handler
.weak UART0_IRQHandler
.thumb_set UART0_IRQHandler,Dummy_Handler
.weak UART1_IRQHandler
.thumb_set UART1_IRQHandler,Dummy_Handler
.weak UART2_IRQHandler
.thumb_set UART2_IRQHandler,Dummy_Handler
.weak UART3_IRQHandler
.thumb_set UART3_IRQHandler,Dummy_Handler
.weak PWM1_IRQHandler
.thumb_set PWM1_IRQHandler,Dummy_Handler
.weak I2C0_IRQHandler
.thumb_set I2C0_IRQHandler,Dummy_Handler
.weak I2C1_IRQHandler
.thumb_set I2C1_IRQHandler,Dummy_Handler
.weak I2C2_IRQHandler
.thumb_set I2C2_IRQHandler,Dummy_Handler
.weak SPI_IRQHandler
.thumb_set SPI_IRQHandler,Dummy_Handler
.weak SSP0_IRQHandler
.thumb_set SSP0_IRQHandler,Dummy_Handler
.weak SSP1_IRQHandler
.thumb_set SSP1_IRQHandler,Dummy_Handler
.weak PLL0_IRQHandler
.thumb_set PLL0_IRQHandler,Dummy_Handler
.weak RTC_IRQHandler
.thumb_set RTC_IRQHandler,Dummy_Handler
.weak EINT0_IRQHandler
.thumb_set EINT0_IRQHandler,Dummy_Handler
.weak EINT1_IRQHandler
.thumb_set EINT1_IRQHandler,Dummy_Handler
.weak EINT2_IRQHandler
.thumb_set EINT2_IRQHandler,Dummy_Handler
.weak EINT3_IRQHandler
.thumb_set EINT3_IRQHandler,Dummy_Handler
.weak ADC_IRQHandler
.thumb_set ADC_IRQHandler,Dummy_Handler
.weak BOD_IRQHandler
.thumb_set BOD_IRQHandler,Dummy_Handler
.weak USB_IRQHandler
.thumb_set USB_IRQHandler,Dummy_Handler
.weak CAN_IRQHandler
.thumb_set CAN_IRQHandler,Dummy_Handler
.weak DMA_IRQHandler
.thumb_set DMA_IRQHandler,Dummy_Handler
.weak I2S_IRQHandler
.thumb_set I2S_IRQHandler,Dummy_Handler
.weak ENET_IRQHandler
.thumb_set ENET_IRQHandler,Dummy_Handler
.weak RIT_IRQHandler
.thumb_set RIT_IRQHandler,Dummy_Handler
.weak MCPWM_IRQHandler
.thumb_set MCPWM_IRQHandler,Dummy_Handler
.weak QEI_IRQHandler
.thumb_set QEI_IRQHandler,Dummy_Handler
.weak PLL1_IRQHandler
.thumb_set PLL1_IRQHandler,Dummy_Handler
.weak USBActivity_IRQHandler
.thumb_set USBActivity_IRQHandler,Dummy_Handler
.weak CANActivity_IRQHandler
.thumb_set CANActivity_IRQHandler,Dummy_Handler
#else
.thumb_func
.weak WDT_IRQHandler
WDT_IRQHandler:
b .
.thumb_func
.weak TIMER0_IRQHandler
TIMER0_IRQHandler:
b .
.thumb_func
.weak TIMER1_IRQHandler
TIMER1_IRQHandler:
b .
.thumb_func
.weak TIMER2_IRQHandler
TIMER2_IRQHandler:
b .
.thumb_func
.weak TIMER3_IRQHandler
TIMER3_IRQHandler:
b .
.thumb_func
.weak UART0_IRQHandler
UART0_IRQHandler:
b .
.thumb_func
.weak UART1_IRQHandler
UART1_IRQHandler:
b .
.thumb_func
.weak UART2_IRQHandler
UART2_IRQHandler:
b .
.thumb_func
.weak UART3_IRQHandler
UART3_IRQHandler:
b .
.thumb_func
.weak PWM1_IRQHandler
PWM1_IRQHandler:
b .
.thumb_func
.weak I2C0_IRQHandler
I2C0_IRQHandler:
b .
.thumb_func
.weak I2C1_IRQHandler
I2C1_IRQHandler:
b .
.thumb_func
.weak I2C2_IRQHandler
I2C2_IRQHandler:
b .
.thumb_func
.weak SPI_IRQHandler
SPI_IRQHandler:
b .
.thumb_func
.weak SSP0_IRQHandler
SSP0_IRQHandler:
b .
.thumb_func
.weak SSP1_IRQHandler
SSP1_IRQHandler:
b .
.thumb_func
.weak PLL0_IRQHandler
PLL0_IRQHandler:
b .
.thumb_func
.weak RTC_IRQHandler
RTC_IRQHandler:
b .
.thumb_func
.weak EINT0_IRQHandler
EINT0_IRQHandler:
b .
.thumb_func
.weak EINT1_IRQHandler
EINT1_IRQHandler:
b .
.thumb_func
.weak EINT2_IRQHandler
EINT2_IRQHandler:
b .
.thumb_func
.weak EINT3_IRQHandler
EINT3_IRQHandler:
b .
.thumb_func
.weak ADC_IRQHandler
ADC_IRQHandler:
b .
.thumb_func
.weak BOD_IRQHandler
BOD_IRQHandler:
b .
.thumb_func
.weak USB_IRQHandler
USB_IRQHandler:
b .
.thumb_func
.weak CAN_IRQHandler
CAN_IRQHandler:
b .
.thumb_func
.weak DMA_IRQHandler
DMA_IRQHandler:
b .
.thumb_func
.weak I2S_IRQHandler
I2S_IRQHandler:
b .
.thumb_func
.weak ENET_IRQHandler
ENET_IRQHandler:
b .
.thumb_func
.weak RIT_IRQHandler
RIT_IRQHandler:
b .
.thumb_func
.weak MCPWM_IRQHandler
MCPWM_IRQHandler:
b .
.thumb_func
.weak QEI_IRQHandler
QEI_IRQHandler:
b .
.thumb_func
.weak PLL1_IRQHandler
PLL1_IRQHandler:
b .
.thumb_func
.weak USBActivity_IRQHandler
USBActivity_IRQHandler:
b .
.thumb_func
.weak CANActivity_IRQHandler
CANActivity_IRQHandler:
b .
#endif
/*****************************************************************************
* Vector Table *
*****************************************************************************/
.section .vectors, "ax"
.align 0
.global _vectors
.extern __stack_end__
.extern Reset_Handler
_vectors:
.word __stack_end__
.word Reset_Handler
.word NMI_Handler
.word HardFault_Handler
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word SVC_Handler
.word 0 /* Reserved */
.word 0 /* Reserved */
.word PendSV_Handler
.word SysTick_Handler
.word WDT_IRQHandler
.word TIMER0_IRQHandler
.word TIMER1_IRQHandler
.word TIMER2_IRQHandler
.word TIMER3_IRQHandler
.word UART0_IRQHandler
.word UART1_IRQHandler
.word UART2_IRQHandler
.word UART3_IRQHandler
.word PWM1_IRQHandler
.word I2C0_IRQHandler
.word I2C1_IRQHandler
.word I2C2_IRQHandler
.word SPI_IRQHandler
.word SSP0_IRQHandler
.word SSP1_IRQHandler
.word PLL0_IRQHandler
.word RTC_IRQHandler
.word EINT0_IRQHandler
.word EINT1_IRQHandler
.word EINT2_IRQHandler
.word EINT3_IRQHandler
.word ADC_IRQHandler
.word BOD_IRQHandler
.word USB_IRQHandler
.word CAN_IRQHandler
.word DMA_IRQHandler
.word I2S_IRQHandler
.word ENET_IRQHandler
.word RIT_IRQHandler
.word MCPWM_IRQHandler
.word QEI_IRQHandler
.word PLL1_IRQHandler
.word USBActivity_IRQHandler
.word CANActivity_IRQHandler
_vectors_end:
#ifdef VECTORS_IN_RAM
.section .vectors_ram, "ax"
.align 0
.global _vectors_ram
_vectors_ram:
.space _vectors_end - _vectors, 0
#endif

View File

@ -0,0 +1,314 @@
MEMORY
{
UNPLACED_SECTIONS (wx) : ORIGIN = 0x100000000, LENGTH = 0
RAM2 (wx) : ORIGIN = 0x2007c000, LENGTH = 0x00008000
RAM (wx) : ORIGIN = 0x10000000, LENGTH = 0x00008000
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00080000
}
SECTIONS
{
__RAM2_segment_start__ = 0x2007c000;
__RAM2_segment_end__ = 0x20084000;
__RAM2_segment_size__ = 0x00008000;
__RAM_segment_start__ = 0x10000000;
__RAM_segment_end__ = 0x10008000;
__RAM_segment_size__ = 0x00008000;
__FLASH_segment_start__ = 0x00000000;
__FLASH_segment_end__ = 0x00080000;
__FLASH_segment_size__ = 0x00080000;
__HEAPSIZE__ = 1024;
__STACKSIZE_PROCESS__ = 0;
__STACKSIZE__ = 1024;
__data2_run_load_start__ = ALIGN(__RAM2_segment_start__ , 4);
.data2_run ALIGN(__RAM2_segment_start__ , 4) (NOLOAD) : AT(ALIGN(__RAM2_segment_start__ , 4))
{
__data2_run_start__ = .;
*(.data2_run .data2_run.*)
}
__data2_run_end__ = __data2_run_start__ + SIZEOF(.data2_run);
__data2_run_size__ = SIZEOF(.data2_run);
__data2_run_load_end__ = __data2_run_end__;
. = ASSERT(__data2_run_start__ == __data2_run_end__ || (__data2_run_end__ >= __RAM2_segment_start__ && __data2_run_end__ <= __RAM2_segment_end__) , "error: .data2_run is too large to fit in RAM2 memory segment");
__bss2_load_start__ = ALIGN(__data2_run_end__ , 4);
.bss2 ALIGN(__data2_run_end__ , 4) (NOLOAD) : AT(ALIGN(__data2_run_end__ , 4))
{
__bss2_start__ = .;
*(.bss2 .bss2.*)
}
__bss2_end__ = __bss2_start__ + SIZEOF(.bss2);
__bss2_size__ = SIZEOF(.bss2);
__bss2_load_end__ = __bss2_end__;
__RAM2_segment_used_end__ = ALIGN(__data2_run_end__ , 4) + SIZEOF(.bss2);
__RAM2_segment_used_size__ = __RAM2_segment_used_end__ - __RAM2_segment_start__;
. = ASSERT(__bss2_start__ == __bss2_end__ || (__bss2_end__ >= __RAM2_segment_start__ && __bss2_end__ <= __RAM2_segment_end__) , "error: .bss2 is too large to fit in RAM2 memory segment");
__vectors_ram_load_start__ = ALIGN(__RAM_segment_start__ , 256);
.vectors_ram ALIGN(__RAM_segment_start__ , 256) (NOLOAD) : AT(ALIGN(__RAM_segment_start__ , 256))
{
__vectors_ram_start__ = .;
*(.vectors_ram .vectors_ram.*)
}
__vectors_ram_end__ = __vectors_ram_start__ + SIZEOF(.vectors_ram);
__vectors_ram_size__ = SIZEOF(.vectors_ram);
__vectors_ram_load_end__ = __vectors_ram_end__;
. = ASSERT(__vectors_ram_start__ == __vectors_ram_end__ || (__vectors_ram_end__ >= __RAM_segment_start__ && __vectors_ram_end__ <= __RAM_segment_end__) , "error: .vectors_ram is too large to fit in RAM memory segment");
__vectors_load_start__ = ALIGN(__FLASH_segment_start__ , 256);
.vectors ALIGN(__FLASH_segment_start__ , 256) : AT(ALIGN(__FLASH_segment_start__ , 256))
{
__vectors_start__ = .;
*(.vectors .vectors.*)
}
__vectors_end__ = __vectors_start__ + SIZEOF(.vectors);
__vectors_size__ = SIZEOF(.vectors);
__vectors_load_end__ = __vectors_end__;
. = ASSERT(__vectors_start__ == __vectors_end__ || (__vectors_end__ >= __FLASH_segment_start__ && __vectors_end__ <= __FLASH_segment_end__) , "error: .vectors is too large to fit in FLASH memory segment");
__init_load_start__ = ALIGN(__vectors_end__ , 4);
.init ALIGN(__vectors_end__ , 4) : AT(ALIGN(__vectors_end__ , 4))
{
__init_start__ = .;
*(.init .init.*)
}
__init_end__ = __init_start__ + SIZEOF(.init);
__init_size__ = SIZEOF(.init);
__init_load_end__ = __init_end__;
. = ASSERT(__init_start__ == __init_end__ || (__init_end__ >= __FLASH_segment_start__ && __init_end__ <= __FLASH_segment_end__) , "error: .init is too large to fit in FLASH memory segment");
__init_rodata_load_start__ = ALIGN(__init_end__ , 4);
.init_rodata ALIGN(__init_end__ , 4) : AT(ALIGN(__init_end__ , 4))
{
__init_rodata_start__ = .;
*(.init_rodata .init_rodata.*)
}
__init_rodata_end__ = __init_rodata_start__ + SIZEOF(.init_rodata);
__init_rodata_size__ = SIZEOF(.init_rodata);
__init_rodata_load_end__ = __init_rodata_end__;
. = ASSERT(__init_rodata_start__ == __init_rodata_end__ || (__init_rodata_end__ >= __FLASH_segment_start__ && __init_rodata_end__ <= __FLASH_segment_end__) , "error: .init_rodata is too large to fit in FLASH memory segment");
__text_load_start__ = ALIGN(__init_rodata_end__ , 4);
.text ALIGN(__init_rodata_end__ , 4) : AT(ALIGN(__init_rodata_end__ , 4))
{
__text_start__ = .;
*(.text .text.* .glue_7t .glue_7 .gnu.linkonce.t.* .gcc_except_table .ARM.extab* .gnu.linkonce.armextab.*)
}
__text_end__ = __text_start__ + SIZEOF(.text);
__text_size__ = SIZEOF(.text);
__text_load_end__ = __text_end__;
. = ASSERT(__text_start__ == __text_end__ || (__text_end__ >= __FLASH_segment_start__ && __text_end__ <= __FLASH_segment_end__) , "error: .text is too large to fit in FLASH memory segment");
__dtors_load_start__ = ALIGN(__text_end__ , 4);
.dtors ALIGN(__text_end__ , 4) : AT(ALIGN(__text_end__ , 4))
{
__dtors_start__ = .;
KEEP (*(SORT(.dtors.*))) KEEP (*(.dtors)) KEEP (*(.fini_array)) KEEP (*(SORT(.fini_array.*)))
}
__dtors_end__ = __dtors_start__ + SIZEOF(.dtors);
__dtors_size__ = SIZEOF(.dtors);
__dtors_load_end__ = __dtors_end__;
. = ASSERT(__dtors_start__ == __dtors_end__ || (__dtors_end__ >= __FLASH_segment_start__ && __dtors_end__ <= __FLASH_segment_end__) , "error: .dtors is too large to fit in FLASH memory segment");
__ctors_load_start__ = ALIGN(__dtors_end__ , 4);
.ctors ALIGN(__dtors_end__ , 4) : AT(ALIGN(__dtors_end__ , 4))
{
__ctors_start__ = .;
KEEP (*(SORT(.ctors.*))) KEEP (*(.ctors)) KEEP (*(.init_array)) KEEP (*(SORT(.init_array.*)))
}
__ctors_end__ = __ctors_start__ + SIZEOF(.ctors);
__ctors_size__ = SIZEOF(.ctors);
__ctors_load_end__ = __ctors_end__;
. = ASSERT(__ctors_start__ == __ctors_end__ || (__ctors_end__ >= __FLASH_segment_start__ && __ctors_end__ <= __FLASH_segment_end__) , "error: .ctors is too large to fit in FLASH memory segment");
__rodata_load_start__ = ALIGN(__ctors_end__ , 4);
.rodata ALIGN(__ctors_end__ , 4) : AT(ALIGN(__ctors_end__ , 4))
{
__rodata_start__ = .;
*(.rodata .rodata.* .gnu.linkonce.r.*)
}
__rodata_end__ = __rodata_start__ + SIZEOF(.rodata);
__rodata_size__ = SIZEOF(.rodata);
__rodata_load_end__ = __rodata_end__;
. = ASSERT(__rodata_start__ == __rodata_end__ || (__rodata_end__ >= __FLASH_segment_start__ && __rodata_end__ <= __FLASH_segment_end__) , "error: .rodata is too large to fit in FLASH memory segment");
__ARM.exidx_load_start__ = ALIGN(__rodata_end__ , 4);
.ARM.exidx ALIGN(__rodata_end__ , 4) : AT(ALIGN(__rodata_end__ , 4))
{
__ARM.exidx_start__ = .;
__exidx_start = __ARM.exidx_start__;
*(.ARM.exidx .ARM.exidx.*)
}
__ARM.exidx_end__ = __ARM.exidx_start__ + SIZEOF(.ARM.exidx);
__ARM.exidx_size__ = SIZEOF(.ARM.exidx);
__exidx_end = __ARM.exidx_end__;
__ARM.exidx_load_end__ = __ARM.exidx_end__;
. = ASSERT(__ARM.exidx_start__ == __ARM.exidx_end__ || (__ARM.exidx_end__ >= __FLASH_segment_start__ && __ARM.exidx_end__ <= __FLASH_segment_end__) , "error: .ARM.exidx is too large to fit in FLASH memory segment");
__fast_load_start__ = ALIGN(__ARM.exidx_end__ , 4);
.fast ALIGN(__vectors_ram_end__ , 4) : AT(ALIGN(__ARM.exidx_end__ , 4))
{
__fast_start__ = .;
*(.fast .fast.*)
}
__fast_end__ = __fast_start__ + SIZEOF(.fast);
__fast_size__ = SIZEOF(.fast);
__fast_load_end__ = __fast_load_start__ + SIZEOF(.fast);
. = ASSERT(__fast_load_start__ == __fast_load_end__ || (__fast_load_end__ >= __FLASH_segment_start__ && __fast_load_end__ <= __FLASH_segment_end__) , "error: .fast is too large to fit in FLASH memory segment");
.fast_run ALIGN(__vectors_ram_end__ , 4) (NOLOAD) :
{
__fast_run_start__ = .;
. = MAX(__fast_run_start__ + SIZEOF(.fast), .);
}
__fast_run_end__ = __fast_run_start__ + SIZEOF(.fast_run);
__fast_run_size__ = SIZEOF(.fast_run);
__fast_run_load_end__ = __fast_run_end__;
. = ASSERT(__fast_run_start__ == __fast_run_end__ || (__fast_run_end__ >= __RAM_segment_start__ && __fast_run_end__ <= __RAM_segment_end__) , "error: .fast_run is too large to fit in RAM memory segment");
__data_load_start__ = ALIGN(__fast_load_start__ + SIZEOF(.fast) , 4);
.data ALIGN(__fast_run_end__ , 4) : AT(ALIGN(__fast_load_start__ + SIZEOF(.fast) , 4))
{
__data_start__ = .;
*(.data .data.* .gnu.linkonce.d.*)
}
__data_end__ = __data_start__ + SIZEOF(.data);
__data_size__ = SIZEOF(.data);
__data_load_end__ = __data_load_start__ + SIZEOF(.data);
. = ASSERT(__data_load_start__ == __data_load_end__ || (__data_load_end__ >= __FLASH_segment_start__ && __data_load_end__ <= __FLASH_segment_end__) , "error: .data is too large to fit in FLASH memory segment");
.data_run ALIGN(__fast_run_end__ , 4) (NOLOAD) :
{
__data_run_start__ = .;
. = MAX(__data_run_start__ + SIZEOF(.data), .);
}
__data_run_end__ = __data_run_start__ + SIZEOF(.data_run);
__data_run_size__ = SIZEOF(.data_run);
__data_run_load_end__ = __data_run_end__;
. = ASSERT(__data_run_start__ == __data_run_end__ || (__data_run_end__ >= __RAM_segment_start__ && __data_run_end__ <= __RAM_segment_end__) , "error: .data_run is too large to fit in RAM memory segment");
__bss_load_start__ = ALIGN(__data_run_end__ , 4);
.bss ALIGN(__data_run_end__ , 4) (NOLOAD) : AT(ALIGN(__data_run_end__ , 4))
{
__bss_start__ = .;
*(.bss .bss.* .gnu.linkonce.b.*) *(COMMON)
}
__bss_end__ = __bss_start__ + SIZEOF(.bss);
__bss_size__ = SIZEOF(.bss);
__bss_load_end__ = __bss_end__;
. = ASSERT(__bss_start__ == __bss_end__ || (__bss_end__ >= __RAM_segment_start__ && __bss_end__ <= __RAM_segment_end__) , "error: .bss is too large to fit in RAM memory segment");
__tbss_load_start__ = ALIGN(__bss_end__ , 4);
.tbss ALIGN(__bss_end__ , 4) (NOLOAD) : AT(ALIGN(__bss_end__ , 4))
{
__tbss_start__ = .;
*(.tbss .tbss.*)
}
__tbss_end__ = __tbss_start__ + SIZEOF(.tbss);
__tbss_size__ = SIZEOF(.tbss);
__tbss_load_end__ = __tbss_end__;
. = ASSERT(__tbss_start__ == __tbss_end__ || (__tbss_end__ >= __RAM_segment_start__ && __tbss_end__ <= __RAM_segment_end__) , "error: .tbss is too large to fit in RAM memory segment");
__tdata_load_start__ = ALIGN(__data_load_start__ + SIZEOF(.data) , 4);
.tdata ALIGN(__tbss_end__ , 4) : AT(ALIGN(__data_load_start__ + SIZEOF(.data) , 4))
{
__tdata_start__ = .;
*(.tdata .tdata.*)
}
__tdata_end__ = __tdata_start__ + SIZEOF(.tdata);
__tdata_size__ = SIZEOF(.tdata);
__tdata_load_end__ = __tdata_load_start__ + SIZEOF(.tdata);
__FLASH_segment_used_end__ = ALIGN(__data_load_start__ + SIZEOF(.data) , 4) + SIZEOF(.tdata);
__FLASH_segment_used_size__ = __FLASH_segment_used_end__ - __FLASH_segment_start__;
. = ASSERT(__tdata_load_start__ == __tdata_load_end__ || (__tdata_load_end__ >= __FLASH_segment_start__ && __tdata_load_end__ <= __FLASH_segment_end__) , "error: .tdata is too large to fit in FLASH memory segment");
.tdata_run ALIGN(__tbss_end__ , 4) (NOLOAD) :
{
__tdata_run_start__ = .;
. = MAX(__tdata_run_start__ + SIZEOF(.tdata), .);
}
__tdata_run_end__ = __tdata_run_start__ + SIZEOF(.tdata_run);
__tdata_run_size__ = SIZEOF(.tdata_run);
__tdata_run_load_end__ = __tdata_run_end__;
. = ASSERT(__tdata_run_start__ == __tdata_run_end__ || (__tdata_run_end__ >= __RAM_segment_start__ && __tdata_run_end__ <= __RAM_segment_end__) , "error: .tdata_run is too large to fit in RAM memory segment");
__non_init_load_start__ = ALIGN(__tdata_run_end__ , 4);
.non_init ALIGN(__tdata_run_end__ , 4) (NOLOAD) : AT(ALIGN(__tdata_run_end__ , 4))
{
__non_init_start__ = .;
*(.non_init .non_init.*)
}
__non_init_end__ = __non_init_start__ + SIZEOF(.non_init);
__non_init_size__ = SIZEOF(.non_init);
__non_init_load_end__ = __non_init_end__;
. = ASSERT(__non_init_start__ == __non_init_end__ || (__non_init_end__ >= __RAM_segment_start__ && __non_init_end__ <= __RAM_segment_end__) , "error: .non_init is too large to fit in RAM memory segment");
__heap_load_start__ = ALIGN(__non_init_end__ , 4);
.heap ALIGN(__non_init_end__ , 4) (NOLOAD) : AT(ALIGN(__non_init_end__ , 4))
{
__heap_start__ = .;
*(.heap .heap.*)
. = ALIGN(MAX(__heap_start__ + __HEAPSIZE__ , .), 4);
}
__heap_end__ = __heap_start__ + SIZEOF(.heap);
__heap_size__ = SIZEOF(.heap);
__heap_load_end__ = __heap_end__;
. = ASSERT(__heap_start__ == __heap_end__ || (__heap_end__ >= __RAM_segment_start__ && __heap_end__ <= __RAM_segment_end__) , "error: .heap is too large to fit in RAM memory segment");
__stack_load_start__ = __RAM_segment_end__ - 1024;
.stack __RAM_segment_end__ - 1024 (NOLOAD) : AT(__RAM_segment_end__ - 1024)
{
__stack_start__ = .;
*(.stack .stack.*)
. = ALIGN(MAX(__stack_start__ + __STACKSIZE__ , .), 8);
}
__stack_end__ = __stack_start__ + SIZEOF(.stack);
__stack_size__ = SIZEOF(.stack);
__stack_load_end__ = __stack_end__;
. = ASSERT(__stack_start__ == __stack_end__ || (__stack_end__ >= __RAM_segment_start__ && __stack_end__ <= __RAM_segment_end__) , "error: .stack is too large to fit in RAM memory segment");
. = ASSERT(__heap_end__ <= __stack_start__ , "error: section .heap overlaps absolute placed section .stack");
__stack_process_load_start__ = ALIGN(__stack_end__ , 8);
.stack_process ALIGN(__stack_end__ , 8) (NOLOAD) : AT(ALIGN(__stack_end__ , 8))
{
__stack_process_start__ = .;
*(.stack_process .stack_process.*)
. = ALIGN(MAX(__stack_process_start__ + __STACKSIZE_PROCESS__ , .), 8);
}
__stack_process_end__ = __stack_process_start__ + SIZEOF(.stack_process);
__stack_process_size__ = SIZEOF(.stack_process);
__stack_process_load_end__ = __stack_process_end__;
__RAM_segment_used_end__ = ALIGN(__stack_end__ , 8) + SIZEOF(.stack_process);
__RAM_segment_used_size__ = __RAM_segment_used_end__ - __RAM_segment_start__;
. = ASSERT(__stack_process_start__ == __stack_process_end__ || (__stack_process_end__ >= __RAM_segment_start__ && __stack_process_end__ <= __RAM_segment_end__) , "error: .stack_process is too large to fit in RAM memory segment");
}

View File

@ -0,0 +1,37 @@
<!DOCTYPE Linker_Placement_File>
<Root name="Flash Section Placement">
<MemorySegment name="$(FLASH_NAME:FLASH)">
<ProgramSection alignment="0x100" load="Yes" name=".vectors" start="$(FLASH_START:)" />
<ProgramSection alignment="4" load="Yes" name=".init" />
<ProgramSection alignment="4" load="Yes" name=".init_rodata" />
<ProgramSection alignment="4" load="Yes" name=".text" />
<ProgramSection alignment="4" load="Yes" name=".dtors" />
<ProgramSection alignment="4" load="Yes" name=".ctors" />
<ProgramSection alignment="4" load="Yes" name=".rodata" />
<ProgramSection alignment="4" load="Yes" name=".ARM.exidx" address_symbol="__exidx_start" end_symbol="__exidx_end" />
<ProgramSection alignment="4" load="Yes" runin=".fast_run" name=".fast" />
<ProgramSection alignment="4" load="Yes" runin=".data_run" name=".data" />
<ProgramSection alignment="4" load="Yes" runin=".tdata_run" name=".tdata" />
</MemorySegment>
<MemorySegment name="$(RAM_NAME:RAM);SRAM">
<ProgramSection alignment="0x100" load="No" name=".vectors_ram" start="$(RAM_START:$(SRAM_START:))" />
<ProgramSection alignment="4" load="No" name=".fast_run" />
<ProgramSection alignment="4" load="No" name=".data_run" />
<ProgramSection alignment="4" load="No" name=".bss" />
<ProgramSection alignment="4" load="No" name=".tbss" />
<ProgramSection alignment="4" load="No" name=".tdata_run" />
<ProgramSection alignment="4" load="No" name=".non_init" />
<ProgramSection alignment="4" size="__HEAPSIZE__" load="No" name=".heap" />
<ProgramSection alignment="8" size="__STACKSIZE__" load="No" place_from_segment_end="Yes" name=".stack" />
<ProgramSection alignment="8" size="__STACKSIZE_PROCESS__" load="No" name=".stack_process" />
</MemorySegment>
<MemorySegment name="$(FLASH2_NAME:FLASH2)">
<ProgramSection alignment="4" load="Yes" name=".text2" />
<ProgramSection alignment="4" load="Yes" name=".rodata2" />
<ProgramSection alignment="4" load="Yes" runin=".data2_run" name=".data2" />
</MemorySegment>
<MemorySegment name="$(RAM2_NAME:RAM2)">
<ProgramSection alignment="4" load="No" name=".data2_run" />
<ProgramSection alignment="4" load="No" name=".bss2" />
</MemorySegment>
</Root>

View File

@ -0,0 +1,141 @@
<!DOCTYPE CrossStudio_Project_File>
<solution Name="lpc175x_6x" target="8" version="2">
<project Name="lpc175x_6x">
<configuration
Name="Common"
Placement="Flash"
Target="LPC4357 Cortex-M4"
arm_architecture="v7M"
arm_core_type="Cortex-M3"
arm_endian="Little"
arm_fp_abi="Soft"
arm_fpu_type="None"
arm_interwork="No"
arm_linker_heap_size="1024"
arm_linker_process_stack_size="0"
arm_linker_stack_size="1024"
arm_simulator_memory_simulation_parameter="RX 00000000,00080000,FFFFFFFF;RWX 10000000,00008000,CDCDCDCD"
arm_target_debug_interface_type="ADIv5"
arm_target_device_name="LPC1769"
arm_target_interface_type="SWD"
build_treat_warnings_as_errors="No"
c_preprocessor_definitions="LPC175x_6x;__LPC1700_FAMILY;__LPC176x_SUBFAMILY;ARM_MATH_CM3;FLASH_PLACEMENT=1;BOARD_LPCXPRESSO1769;CFG_TUSB_MCU=OPT_MCU_LPC175X_6X"
c_user_include_directories=".;../../src;$(rootDir)/hw/cmsis/Include;$(rootDir)/hw;$(rootDir)/src;$(lpcDir)/CMSIS_CORE_LPC17xx/inc;$(lpcDir)/LPC17xx_DriverLib/include;$(freertosDir)/Source/include;$(freertosDir)/Source/portable/GCC/ARM_CM3"
debug_register_definition_file="LPC176x5x_Registers.xml"
debug_target_connection="J-Link"
gcc_enable_all_warnings="Yes"
gcc_entry_point="Reset_Handler"
link_use_linker_script_file="No"
linker_memory_map_file="LPC1769_MemoryMap.xml"
linker_section_placement_file="flash_placement.xml"
linker_section_placements_segments="FLASH RX 0x00000000 0x00080000;RAM RWX 0x10000000 0x00008000"
macros="DeviceFamily=LPC1700;DeviceSubFamily=LPC176x;Target=LPC1769;Placement=Flash;rootDir=../../../../..;lpcDir=../../../../../hw/mcu/nxp/lpc175x_6x;freertosDir=../../../../../lib/FreeRTOS"
project_directory=""
project_type="Executable"
target_reset_script="Reset();"
target_script_file="$(ProjectDir)/LPC1700_Target.js"
target_trace_initialize_script="EnableTrace(&quot;$(TraceInterfaceType)&quot;)" />
<folder
Name="tinyusb"
exclude=""
filter="*.c;*.h"
path="../../../../../src"
recurse="Yes" />
<folder Name="hw">
<folder Name="bsp">
<file file_name="../../../../../hw/bsp/ansi_escape.h" />
<file file_name="../../../../../hw/bsp/board.h" />
<folder Name="lpcxpresso1769">
<file file_name="../../../../../hw/bsp/lpcxpresso1769/board_lpcxpresso1769.c" />
<file file_name="../../../../../hw/bsp/lpcxpresso1769/board_lpcxpresso1769.h" />
</folder>
</folder>
<folder Name="mcu">
<folder Name="nxp">
<folder Name="lpc175x_6x">
<folder Name="CMSIS_CORE_LPC17xx">
<folder Name="inc">
<file file_name="../../../../../hw/mcu/nxp/lpc175x_6x/CMSIS_CORE_LPC17xx/inc/LPC17xx.h" />
<file file_name="../../../../../hw/mcu/nxp/lpc175x_6x/CMSIS_CORE_LPC17xx/inc/system_LPC17xx.h" />
</folder>
<folder Name="src">
<file file_name="../../../../../hw/mcu/nxp/lpc175x_6x/CMSIS_CORE_LPC17xx/src/system_LPC17xx.c" />
</folder>
</folder>
<folder Name="LPC17xx_DriverLib">
<folder Name="include" />
<folder Name="source">
<file file_name="../../../../../hw/mcu/nxp/lpc175x_6x/LPC17xx_DriverLib/source/lpc17xx_gpio.c" />
<file file_name="../../../../../hw/mcu/nxp/lpc175x_6x/LPC17xx_DriverLib/source/lpc17xx_pinsel.c" />
</folder>
</folder>
</folder>
</folder>
</folder>
</folder>
<configuration Name="Debug" build_treat_warnings_as_errors="Yes" />
<folder
Name="src"
exclude=""
filter="*.c;*.h"
path="../../src"
recurse="Yes" />
<folder Name="System Files">
<file file_name="flash_placement.xml" />
<file file_name="LPC1700_Startup.s" />
<file file_name="LPC1700_Target.js" />
<file file_name="LPC1769_MemoryMap.xml" />
<file file_name="LPC176x5x_Registers.xml" />
<file file_name="LPC176x5x_Vectors.s" />
<file file_name="thumb_crt0.s" />
</folder>
<folder
Name="segger_rtt"
exclude=""
filter="*.c;*.h"
path="../../../../../lib/segger_rtt"
recurse="No" />
<folder Name="lib">
<folder Name="FreeRTOS">
<folder Name="Source">
<folder Name="include">
<file file_name="../../../../../lib/FreeRTOS/Source/include/croutine.h" />
<file file_name="../../../../../lib/FreeRTOS/Source/include/deprecated_definitions.h" />
<file file_name="../../../../../lib/FreeRTOS/Source/include/event_groups.h" />
<file file_name="../../../../../lib/FreeRTOS/Source/include/FreeRTOS.h" />
<file file_name="../../../../../lib/FreeRTOS/Source/include/list.h" />
<file file_name="../../../../../lib/FreeRTOS/Source/include/message_buffer.h" />
<file file_name="../../../../../lib/FreeRTOS/Source/include/mpu_prototypes.h" />
<file file_name="../../../../../lib/FreeRTOS/Source/include/mpu_wrappers.h" />
<file file_name="../../../../../lib/FreeRTOS/Source/include/portable.h" />
<file file_name="../../../../../lib/FreeRTOS/Source/include/projdefs.h" />
<file file_name="../../../../../lib/FreeRTOS/Source/include/queue.h" />
<file file_name="../../../../../lib/FreeRTOS/Source/include/semphr.h" />
<file file_name="../../../../../lib/FreeRTOS/Source/include/stack_macros.h" />
<file file_name="../../../../../lib/FreeRTOS/Source/include/StackMacros.h" />
<file file_name="../../../../../lib/FreeRTOS/Source/include/stream_buffer.h" />
<file file_name="../../../../../lib/FreeRTOS/Source/include/task.h" />
<file file_name="../../../../../lib/FreeRTOS/Source/include/timers.h" />
</folder>
<folder Name="portable">
<folder Name="GCC">
<folder Name="ARM_CM3">
<file file_name="../../../../../lib/FreeRTOS/Source/portable/GCC/ARM_CM3/port.c" />
<file file_name="../../../../../lib/FreeRTOS/Source/portable/GCC/ARM_CM3/portmacro.h" />
</folder>
</folder>
<folder Name="MemMang">
<file file_name="../../../../../lib/FreeRTOS/Source/portable/MemMang/heap_4.c" />
</folder>
</folder>
<file file_name="../../../../../lib/FreeRTOS/Source/list.c" />
<file file_name="../../../../../lib/FreeRTOS/Source/queue.c" />
<file file_name="../../../../../lib/FreeRTOS/Source/tasks.c" />
<file file_name="../../../../../lib/FreeRTOS/Source/timers.c" />
</folder>
<file file_name="../../../../../lib/FreeRTOS/freertos_hook.c" />
</folder>
</folder>
</project>
<configuration Name="LPCXpresso 1769" />
</solution>

View File

@ -0,0 +1,415 @@
// **********************************************************************
// * SEGGER Microcontroller GmbH *
// * The Embedded Experts *
// **********************************************************************
// * *
// * (c) 2014 - 2018 SEGGER Microcontroller GmbH *
// * (c) 2001 - 2018 Rowley Associates Limited *
// * *
// * www.segger.com Support: support@segger.com *
// * *
// **********************************************************************
// * *
// * All rights reserved. *
// * *
// * Redistribution and use in source and binary forms, with or *
// * without modification, are permitted provided that the following *
// * conditions are met: *
// * *
// * - Redistributions of source code must retain the above copyright *
// * notice, this list of conditions and the following disclaimer. *
// * *
// * - Neither the name of SEGGER Microcontroller GmbH *
// * nor the names of its contributors may be used to endorse or *
// * promote products derived from this software without specific *
// * prior written permission. *
// * *
// * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
// * CONTRIBUTORS "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 SEGGER Microcontroller GmbH 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. *
// * *
// **********************************************************************
//
//
// Preprocessor Definitions
// ------------------------
// APP_ENTRY_POINT
//
// Defines the application entry point function, if undefined this setting
// defaults to "main".
//
// INITIALIZE_STACK
//
// If defined, the contents of the stack will be initialized to a the
// value 0xCC.
//
// INITIALIZE_SECONDARY_SECTIONS
//
// If defined, the .data2, .text2, .rodata2 and .bss2 sections will be initialized.
//
// INITIALIZE_TCM_SECTIONS
//
// If defined, the .data_tcm, .text_tcm, .rodata_tcm and .bss_tcm sections
// will be initialized.
//
// INITIALIZE_USER_SECTIONS
//
// If defined, the function InitializeUserMemorySections will be called prior
// to entering main in order to allow the user to initialize any user defined
// memory sections.
//
// FULL_LIBRARY
//
// If defined then
// - argc, argv are setup by the debug_getargs.
// - the exit symbol is defined and executes on return from main.
// - the exit symbol calls destructors, atexit functions and then debug_exit.
//
// If not defined then
// - argc and argv are zero.
// - the exit symbol is defined, executes on return from main and loops
//
#ifndef APP_ENTRY_POINT
#define APP_ENTRY_POINT main
#endif
#ifndef ARGSSPACE
#define ARGSSPACE 128
#endif
.syntax unified
.global _start
.extern APP_ENTRY_POINT
.global exit
.weak exit
#ifdef INITIALIZE_USER_SECTIONS
.extern InitializeUserMemorySections
#endif
.section .init, "ax"
.code 16
.balign 2
.thumb_func
_start:
/* Set up main stack if size > 0 */
ldr r1, =__stack_end__
ldr r0, =__stack_start__
subs r2, r1, r0
beq 1f
#ifdef __ARM_EABI__
movs r2, #0x7
bics r1, r2
#endif
mov sp, r1
#ifdef INITIALIZE_STACK
movs r2, #0xCC
ldr r0, =__stack_start__
bl memory_set
#endif
1:
/* Set up process stack if size > 0 */
ldr r1, =__stack_process_end__
ldr r0, =__stack_process_start__
subs r2, r1, r0
beq 1f
#ifdef __ARM_EABI__
movs r2, #0x7
bics r1, r2
#endif
msr psp, r1
movs r2, #2
msr control, r2
#ifdef INITIALIZE_STACK
movs r2, #0xCC
bl memory_set
#endif
1:
/* Copy initialized memory sections into RAM (if necessary). */
ldr r0, =__data_load_start__
ldr r1, =__data_start__
ldr r2, =__data_end__
bl memory_copy
ldr r0, =__text_load_start__
ldr r1, =__text_start__
ldr r2, =__text_end__
bl memory_copy
ldr r0, =__fast_load_start__
ldr r1, =__fast_start__
ldr r2, =__fast_end__
bl memory_copy
ldr r0, =__ctors_load_start__
ldr r1, =__ctors_start__
ldr r2, =__ctors_end__
bl memory_copy
ldr r0, =__dtors_load_start__
ldr r1, =__dtors_start__
ldr r2, =__dtors_end__
bl memory_copy
ldr r0, =__rodata_load_start__
ldr r1, =__rodata_start__
ldr r2, =__rodata_end__
bl memory_copy
ldr r0, =__tdata_load_start__
ldr r1, =__tdata_start__
ldr r2, =__tdata_end__
bl memory_copy
#ifdef INITIALIZE_SECONDARY_SECTIONS
ldr r0, =__data2_load_start__
ldr r1, =__data2_start__
ldr r2, =__data2_end__
bl memory_copy
ldr r0, =__text2_load_start__
ldr r1, =__text2_start__
ldr r2, =__text2_end__
bl memory_copy
ldr r0, =__rodata2_load_start__
ldr r1, =__rodata2_start__
ldr r2, =__rodata2_end__
bl memory_copy
#endif /* #ifdef INITIALIZE_SECONDARY_SECTIONS */
#ifdef INITIALIZE_TCM_SECTIONS
ldr r0, =__data_tcm_load_start__
ldr r1, =__data_tcm_start__
ldr r2, =__data_tcm_end__
bl memory_copy
ldr r0, =__text_tcm_load_start__
ldr r1, =__text_tcm_start__
ldr r2, =__text_tcm_end__
bl memory_copy
ldr r0, =__rodata_tcm_load_start__
ldr r1, =__rodata_tcm_start__
ldr r2, =__rodata_tcm_end__
bl memory_copy
#endif /* #ifdef INITIALIZE_TCM_SECTIONS */
/* Zero the bss. */
ldr r0, =__bss_start__
ldr r1, =__bss_end__
movs r2, #0
bl memory_set
ldr r0, =__tbss_start__
ldr r1, =__tbss_end__
movs r2, #0
bl memory_set
#ifdef INITIALIZE_SECONDARY_SECTIONS
ldr r0, =__bss2_start__
ldr r1, =__bss2_end__
mov r2, #0
bl memory_set
#endif /* #ifdef INITIALIZE_SECONDARY_SECTIONS */
#ifdef INITIALIZE_TCM_SECTIONS
ldr r0, =__bss_tcm_start__
ldr r1, =__bss_tcm_end__
mov r2, #0
bl memory_set
#endif /* #ifdef INITIALIZE_TCM_SECTIONS */
/* Initialize the heap */
ldr r0, = __heap_start__
ldr r1, = __heap_end__
subs r1, r1, r0
cmp r1, #8
blt 1f
movs r2, #0
str r2, [r0]
adds r0, r0, #4
str r1, [r0]
1:
#ifdef INITIALIZE_USER_SECTIONS
ldr r2, =InitializeUserMemorySections
blx r2
#endif
/* Call constructors */
ldr r0, =__ctors_start__
ldr r1, =__ctors_end__
ctor_loop:
cmp r0, r1
beq ctor_end
ldr r2, [r0]
adds r0, #4
push {r0-r1}
blx r2
pop {r0-r1}
b ctor_loop
ctor_end:
/* Setup initial call frame */
movs r0, #0
mov lr, r0
mov r12, sp
.type start, function
start:
/* Jump to application entry point */
#ifdef FULL_LIBRARY
movs r0, #ARGSSPACE
ldr r1, =args
ldr r2, =debug_getargs
blx r2
ldr r1, =args
#else
movs r0, #0
movs r1, #0
#endif
ldr r2, =APP_ENTRY_POINT
blx r2
.thumb_func
exit:
#ifdef FULL_LIBRARY
mov r5, r0 // save the exit parameter/return result
/* Call destructors */
ldr r0, =__dtors_start__
ldr r1, =__dtors_end__
dtor_loop:
cmp r0, r1
beq dtor_end
ldr r2, [r0]
add r0, #4
push {r0-r1}
blx r2
pop {r0-r1}
b dtor_loop
dtor_end:
/* Call atexit functions */
ldr r2, =_execute_at_exit_fns
blx r2
/* Call debug_exit with return result/exit parameter */
mov r0, r5
ldr r2, =debug_exit
blx r2
#endif
/* Returned from application entry point, loop forever. */
exit_loop:
b exit_loop
.thumb_func
memory_copy:
cmp r0, r1
beq 2f
subs r2, r2, r1
beq 2f
1:
ldrb r3, [r0]
adds r0, r0, #1
strb r3, [r1]
adds r1, r1, #1
subs r2, r2, #1
bne 1b
2:
bx lr
.thumb_func
memory_set:
cmp r0, r1
beq 1f
strb r2, [r0]
adds r0, r0, #1
b memory_set
1:
bx lr
// default C/C++ library helpers
.macro HELPER helper_name
.section .text.\helper_name, "ax", %progbits
.balign 2
.global \helper_name
.weak \helper_name
\helper_name:
.thumb_func
.endm
.macro JUMPTO name
#if defined(__thumb__) && !defined(__thumb2__)
mov r12, r0
ldr r0, =\name
push {r0}
mov r0, r12
pop {pc}
#else
b \name
#endif
.endm
HELPER __aeabi_read_tp
ldr r0, =__tbss_start__-8
bx lr
HELPER abort
b .
HELPER __assert
b .
HELPER __aeabi_assert
b .
HELPER __sync_synchronize
bx lr
HELPER __getchar
JUMPTO debug_getchar
HELPER __putchar
JUMPTO debug_putchar
HELPER __open
JUMPTO debug_fopen
HELPER __close
JUMPTO debug_fclose
HELPER __write
mov r3, r0
mov r0, r1
movs r1, #1
JUMPTO debug_fwrite
HELPER __read
mov r3, r0
mov r0, r1
movs r1, #1
JUMPTO debug_fread
HELPER __seek
push {r4, lr}
mov r4, r0
bl debug_fseek
cmp r0, #0
bne 1f
mov r0, r4
bl debug_ftell
pop {r4, pc}
1:
ldr r0, =-1
pop {r4, pc}
// char __user_locale_name_buffer[];
.section .bss.__user_locale_name_buffer, "aw", %nobits
.global __user_locale_name_buffer
.weak __user_locale_name_buffer
__user_locale_name_buffer:
.word 0x0
#ifdef FULL_LIBRARY
.bss
args:
.space ARGSSPACE
#endif
/* Setup attibutes of stack and heap sections so they don't take up room in the elf file */
.section .stack, "wa", %nobits
.section .stack_process, "wa", %nobits
.section .heap, "wa", %nobits

View File

@ -137,8 +137,7 @@
#error "This port requires __NVIC_PRIO_BITS to be defined" #error "This port requires __NVIC_PRIO_BITS to be defined"
#endif #endif
/* The lowest interrupt priority that can be used in a call to a "set priority" /* The lowest interrupt priority that can be used in a call to a "set priority" function. */
function. */
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<<configPRIO_BITS) - 1) #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<<configPRIO_BITS) - 1)
/* The highest interrupt priority that can be used by any interrupt service /* The highest interrupt priority that can be used by any interrupt service

View File

@ -127,7 +127,6 @@
<file file_name="../../../../../lib/FreeRTOS/Source/include/timers.h" /> <file file_name="../../../../../lib/FreeRTOS/Source/include/timers.h" />
</folder> </folder>
<folder Name="portable"> <folder Name="portable">
<folder Name="Common" />
<folder Name="GCC"> <folder Name="GCC">
<folder Name="ARM_CM4F"> <folder Name="ARM_CM4F">
<file file_name="../../../../../lib/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c" /> <file file_name="../../../../../lib/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c" />

View File

@ -121,7 +121,6 @@
<file file_name="../../../../../lib/FreeRTOS/Source/include/timers.h" /> <file file_name="../../../../../lib/FreeRTOS/Source/include/timers.h" />
</folder> </folder>
<folder Name="portable"> <folder Name="portable">
<folder Name="Common" />
<folder Name="GCC"> <folder Name="GCC">
<folder Name="ARM_CM0"> <folder Name="ARM_CM0">
<file file_name="../../../../../lib/FreeRTOS/Source/portable/GCC/ARM_CM0/port.c" /> <file file_name="../../../../../lib/FreeRTOS/Source/portable/GCC/ARM_CM0/port.c" />
@ -137,7 +136,6 @@
<file file_name="../../../../../lib/FreeRTOS/Source/tasks.c" /> <file file_name="../../../../../lib/FreeRTOS/Source/tasks.c" />
<file file_name="../../../../../lib/FreeRTOS/Source/timers.c" /> <file file_name="../../../../../lib/FreeRTOS/Source/timers.c" />
</folder> </folder>
<file file_name="../../../../../lib/FreeRTOS/FreeRTOSConfig.h" />
<file file_name="../../../../../lib/FreeRTOS/freertos_hook.c" /> <file file_name="../../../../../lib/FreeRTOS/freertos_hook.c" />
</folder> </folder>
</folder> </folder>

View File

@ -125,7 +125,6 @@
<file file_name="../../../../../lib/FreeRTOS/Source/include/timers.h" /> <file file_name="../../../../../lib/FreeRTOS/Source/include/timers.h" />
</folder> </folder>
<folder Name="portable"> <folder Name="portable">
<folder Name="Common" />
<folder Name="GCC"> <folder Name="GCC">
<folder Name="ARM_CM4F"> <folder Name="ARM_CM4F">
<file file_name="../../../../../lib/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c" /> <file file_name="../../../../../lib/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c" />
@ -141,7 +140,6 @@
<file file_name="../../../../../lib/FreeRTOS/Source/tasks.c" /> <file file_name="../../../../../lib/FreeRTOS/Source/tasks.c" />
<file file_name="../../../../../lib/FreeRTOS/Source/timers.c" /> <file file_name="../../../../../lib/FreeRTOS/Source/timers.c" />
</folder> </folder>
<file file_name="../../../../../lib/FreeRTOS/FreeRTOSConfig.h" />
<file file_name="../../../../../lib/FreeRTOS/freertos_hook.c" /> <file file_name="../../../../../lib/FreeRTOS/freertos_hook.c" />
</folder> </folder>
</folder> </folder>

View File

@ -39,8 +39,6 @@
#ifndef _TUSB_CONFIG_H_ #ifndef _TUSB_CONFIG_H_
#define _TUSB_CONFIG_H_ #define _TUSB_CONFIG_H_
#include "bsp/board.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -48,9 +46,10 @@
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// COMMON CONFIGURATION // COMMON CONFIGURATION
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// defined by compiler flags for flexibility // defined by compiler flags for flexibility
#ifndef CFG_TUSB_MCU #ifndef CFG_TUSB_MCU
#error CFG_TUSB_MCU should be defined using compiler flags #error CFG_TUSB_MCU must be defined
#endif #endif
#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE #define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE
@ -63,6 +62,21 @@
//#define CFG_TUD_TASK_QUEUE_SZ 16 //#define CFG_TUD_TASK_QUEUE_SZ 16
//#define CFG_TUD_TASK_STACK_SZ 150 //#define CFG_TUD_TASK_STACK_SZ 150
/* 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 ATTR_ALIGNED(4)
#endif
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// DEVICE CONFIGURATION // DEVICE CONFIGURATION
//-------------------------------------------------------------------- //--------------------------------------------------------------------
@ -78,12 +92,23 @@
*/ */
#define CFG_TUD_DESC_AUTO 1 #define CFG_TUD_DESC_AUTO 1
/* USB VID/PID if not defined, tinyusb to use default value /* If USB VID/PID is not defined, tinyusb will use default value
* Note: different class combination e.g CDC and (CDC + MSC) should have different * Note: different class combination e.g CDC and (CDC + MSC) should have different
* PID since Host OS will "remembered" device driver after the first plug */ * PID since Host OS will "remembered" device driver after the first plug */
// #define CFG_TUD_DESC_VID 0xCAFE // #define CFG_TUD_DESC_VID 0xCAFE
// #define CFG_TUD_DESC_PID 0x0001 // #define CFG_TUD_DESC_PID 0x0001
// LPC175x_6x's endpoint type (bulk/interrupt/iso) are fixed by its number
// Therefor we need to force endpoint number to correct type on lpc17xx
#if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X
#define CFG_TUD_DESC_CDC_EPNUM_NOTIF 1
#define CFG_TUD_DESC_CDC_EPNUM 2
#define CFG_TUD_DESC_MSC_EPNUM 5
#define CFG_TUD_DESC_HID_KEYBOARD_EPNUM 4
#define CFG_TUD_DESC_HID_MOUSE_EPNUM 7
#endif
//------------- CLASS -------------// //------------- CLASS -------------//
#define CFG_TUD_CDC 1 #define CFG_TUD_CDC 1
#define CFG_TUD_MSC 1 #define CFG_TUD_MSC 1
@ -137,13 +162,6 @@
*/ */
#define CFG_TUD_HID_ASCII_TO_KEYCODE_LOOKUP 1 #define CFG_TUD_HID_ASCII_TO_KEYCODE_LOOKUP 1
//--------------------------------------------------------------------
// USB RAM PLACEMENT
//--------------------------------------------------------------------
#define CFG_TUSB_MEM_SECTION
#define CFG_TUSB_MEM_ALIGN ATTR_ALIGNED(4)
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -36,14 +36,18 @@
*/ */
/**************************************************************************/ /**************************************************************************/
#include "../board.h" #include "bsp/board.h"
#include "tusb.h"
#ifdef BOARD_LPCXPRESSO1769 #ifdef BOARD_LPCXPRESSO1769
#include "LPC17xx.h"
#include "lpc17xx_pinsel.h"
#define BOARD_LED_PORT (0) #define BOARD_LED_PORT (0)
#define BOARD_LED_PIN (22) #define BOARD_LED_PIN (22)
const static struct { static const struct {
uint8_t port; uint8_t port;
uint8_t pin; uint8_t pin;
} buttons[] = } buttons[] =
@ -89,6 +93,7 @@ void board_init(void)
//P0_21 instead of P2_9 as USB connect //P0_21 instead of P2_9 as USB connect
#endif #endif
#if 0
//------------- UART -------------// //------------- UART -------------//
PINSEL_CFG_Type PinCfg = PINSEL_CFG_Type PinCfg =
{ {
@ -110,20 +115,43 @@ void board_init(void)
UART_Init(BOARD_UART_PORT, &UARTConfigStruct); UART_Init(BOARD_UART_PORT, &UARTConfigStruct);
UART_TxCmd(BOARD_UART_PORT, ENABLE); // Enable UART Transmit UART_TxCmd(BOARD_UART_PORT, ENABLE); // Enable UART Transmit
#endif
} }
/*------------------------------------------------------------------*/
/* TUSB HAL MILLISECOND
*------------------------------------------------------------------*/
#if CFG_TUSB_OS == OPT_OS_NONE
volatile uint32_t system_ticks = 0;
void SysTick_Handler (void)
{
system_ticks++;
}
uint32_t tusb_hal_millis(void)
{
return board_tick2ms(system_ticks);
}
#endif
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// LEDS // LEDS
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
void board_leds(uint32_t on_mask, uint32_t off_mask) void board_led_control(uint32_t id, bool state)
{ {
if (on_mask & BIT_(0)) (void) id;
if (state)
{ {
GPIO_SetValue(BOARD_LED_PORT, BIT_(BOARD_LED_PIN)); GPIO_SetValue(BOARD_LED_PORT, BIT_(BOARD_LED_PIN));
}else if (off_mask & BIT_(0)) }else
{ {
GPIO_ClearValue(BOARD_LED_PORT, BIT_(BOARD_LED_PIN)); GPIO_ClearValue(BOARD_LED_PORT, BIT_(BOARD_LED_PIN));
} }
} }
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
@ -148,12 +176,12 @@ uint32_t board_buttons(void)
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
void board_uart_putchar(uint8_t c) void board_uart_putchar(uint8_t c)
{ {
UART_Send(BOARD_UART_PORT, &c, 1, BLOCKING); // UART_Send(BOARD_UART_PORT, &c, 1, BLOCKING);
} }
uint8_t board_uart_getchar(void) uint8_t board_uart_getchar(void)
{ {
return UART_ReceiveByte(BOARD_UART_PORT); // return UART_ReceiveByte(BOARD_UART_PORT);
} }
#endif #endif

View File

@ -42,7 +42,6 @@
#include "LPC17xx.h" #include "LPC17xx.h"
#include "lpc17xx_clkpwr.h" #include "lpc17xx_clkpwr.h"
#include "lpc17xx_pinsel.h"
#include "lpc17xx_gpio.h" #include "lpc17xx_gpio.h"
#include "lpc17xx_uart.h" #include "lpc17xx_uart.h"
@ -53,6 +52,9 @@
#define CFG_PRINTF_TARGET PRINTF_TARGET_UART #define CFG_PRINTF_TARGET PRINTF_TARGET_UART
//#define CFG_PRINTF_TARGET PRINTF_TARGET_SWO //#define CFG_PRINTF_TARGET PRINTF_TARGET_SWO
#define BOARD_LED_NUM 1
#define BOARD_LED0 0
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -248,7 +248,6 @@ uint8_t board_uart_getchar(void)
void board_uart_putchar(uint8_t c) void board_uart_putchar(uint8_t c)
{ {
} }
#endif #endif

View File

@ -302,6 +302,8 @@ tusb_error_t cdcd_open(uint8_t rhport, tusb_desc_interface_t const * p_interface
// return false to stall control endpoint (e.g Host send non-sense DATA) // return false to stall control endpoint (e.g Host send non-sense DATA)
bool cdcd_control_request_complete(uint8_t rhport, tusb_control_request_t const * request) bool cdcd_control_request_complete(uint8_t rhport, tusb_control_request_t const * request)
{ {
(void) rhport;
//------------- Class Specific Request -------------// //------------- Class Specific Request -------------//
TU_VERIFY (request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS); TU_VERIFY (request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS);
@ -358,8 +360,10 @@ bool cdcd_control_request(uint8_t rhport, tusb_control_request_t const * request
return true; return true;
} }
tusb_error_t cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes) tusb_error_t cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes)
{ {
(void) result;
// TODO Support multiple interfaces // TODO Support multiple interfaces
uint8_t const itf = 0; uint8_t const itf = 0;
cdcd_interface_t* p_cdc = &_cdcd_itf[itf]; cdcd_interface_t* p_cdc = &_cdcd_itf[itf];
@ -367,16 +371,14 @@ tusb_error_t cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event,
// receive new data // receive new data
if ( ep_addr == p_cdc->ep_out ) if ( ep_addr == p_cdc->ep_out )
{ {
char const wanted = p_cdc->wanted_char;
for(uint32_t i=0; i<xferred_bytes; i++) for(uint32_t i=0; i<xferred_bytes; i++)
{ {
tu_fifo_write(&p_cdc->rx_ff, &p_cdc->epout_buf[i]); tu_fifo_write(&p_cdc->rx_ff, &p_cdc->epout_buf[i]);
// Check for wanted char and invoke callback if needed // Check for wanted char and invoke callback if needed
if ( tud_cdc_rx_wanted_cb && ( wanted != -1 ) && ( wanted == p_cdc->epout_buf[i] ) ) if ( tud_cdc_rx_wanted_cb && ( ((signed char) p_cdc->wanted_char) != -1 ) && ( p_cdc->wanted_char == p_cdc->epout_buf[i] ) )
{ {
tud_cdc_rx_wanted_cb(itf, wanted); tud_cdc_rx_wanted_cb(itf, p_cdc->wanted_char);
} }
} }

View File

@ -116,7 +116,7 @@ void cdcd_init (void);
tusb_error_t cdcd_open (uint8_t rhport, tusb_desc_interface_t const * p_interface_desc, uint16_t *p_length); tusb_error_t cdcd_open (uint8_t rhport, tusb_desc_interface_t const * p_interface_desc, uint16_t *p_length);
bool cdcd_control_request (uint8_t rhport, tusb_control_request_t const * p_request); bool cdcd_control_request (uint8_t rhport, tusb_control_request_t const * p_request);
bool cdcd_control_request_complete (uint8_t rhport, tusb_control_request_t const * p_request); bool cdcd_control_request_complete (uint8_t rhport, tusb_control_request_t const * p_request);
tusb_error_t cdcd_xfer_cb (uint8_t rhport, uint8_t edpt_addr, xfer_result_t event, uint32_t xferred_bytes); tusb_error_t cdcd_xfer_cb (uint8_t rhport, uint8_t edpt_addr, xfer_result_t result, uint32_t xferred_bytes);
void cdcd_reset (uint8_t rhport); void cdcd_reset (uint8_t rhport);
#endif #endif

View File

@ -418,7 +418,6 @@ bool hidd_control_request(uint8_t rhport, tusb_control_request_t const * p_reque
if (p_request->bRequest == TUSB_REQ_GET_DESCRIPTOR && desc_type == HID_DESC_TYPE_REPORT) if (p_request->bRequest == TUSB_REQ_GET_DESCRIPTOR && desc_type == HID_DESC_TYPE_REPORT)
{ {
// Cast away the const on p_hid->desc_report because we know it won't be modified.
usbd_control_xfer(rhport, p_request, (void *)p_hid->desc_report, p_hid->desc_len); usbd_control_xfer(rhport, p_request, (void *)p_hid->desc_report, p_hid->desc_len);
}else }else
{ {

View File

@ -146,6 +146,7 @@ void mscd_init(void)
void mscd_reset(uint8_t rhport) void mscd_reset(uint8_t rhport)
{ {
(void) rhport;
tu_memclr(&_mscd_itf, sizeof(mscd_interface_t)); tu_memclr(&_mscd_itf, sizeof(mscd_interface_t));
} }
@ -201,6 +202,9 @@ bool mscd_control_request(uint8_t rhport, tusb_control_request_t const * p_reque
// return false to stall control endpoint (e.g Host send non-sense DATA) // return false to stall control endpoint (e.g Host send non-sense DATA)
bool mscd_control_request_complete(uint8_t rhport, tusb_control_request_t const * p_request) bool mscd_control_request_complete(uint8_t rhport, tusb_control_request_t const * p_request)
{ {
(void) rhport;
(void) p_request;
// nothing to do // nothing to do
return true; return true;
} }
@ -208,6 +212,7 @@ bool mscd_control_request_complete(uint8_t rhport, tusb_control_request_t const
// return length of response (copied to buffer), -1 if it is not an built-in commands // return length of response (copied to buffer), -1 if it is not an built-in commands
int32_t proc_builtin_scsi(msc_cbw_t const * p_cbw, uint8_t* buffer, uint32_t bufsize) int32_t proc_builtin_scsi(msc_cbw_t const * p_cbw, uint8_t* buffer, uint32_t bufsize)
{ {
(void) bufsize; // TODO refractor later
int32_t ret; int32_t ret;
switch ( p_cbw->command[0] ) switch ( p_cbw->command[0] )

View File

@ -71,12 +71,6 @@ TU_VERIFY_STATIC(CFG_TUD_MSC_BUFSIZE < UINT16_MAX, "Size is not correct");
#error CFG_TUD_MSC_PRODUCT_REV 4-byte string must be defined #error CFG_TUD_MSC_PRODUCT_REV 4-byte string must be defined
#endif #endif
// TODO highspeed device is 512
#ifndef CFG_TUD_MSC_EPSIZE
#define CFG_TUD_MSC_EPSIZE 64
#endif
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif

View File

@ -170,7 +170,7 @@ static osal_queue_t _usbd_q;
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
static void mark_interface_endpoint(uint8_t const* p_desc, uint16_t desc_len, uint8_t driver_id); static void mark_interface_endpoint(uint8_t const* p_desc, uint16_t desc_len, uint8_t driver_id);
static bool process_control_request(uint8_t rhport, tusb_control_request_t const * p_request); static bool process_control_request(uint8_t rhport, tusb_control_request_t const * p_request);
static bool process_set_config(uint8_t rhport, uint8_t config_number); static bool process_set_config(uint8_t rhport);
static void const* get_descriptor(tusb_control_request_t const * p_request, uint16_t* desc_len); static void const* get_descriptor(tusb_control_request_t const * p_request, uint16_t* desc_len);
void usbd_control_reset (uint8_t rhport); void usbd_control_reset (uint8_t rhport);
@ -356,7 +356,7 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const
dcd_set_config(rhport, config); dcd_set_config(rhport, config);
_usbd_dev.config_num = config; _usbd_dev.config_num = config;
TU_ASSERT( TUSB_ERROR_NONE == process_set_config(rhport, config) ); TU_ASSERT( TUSB_ERROR_NONE == process_set_config(rhport) );
} }
break; break;
@ -427,7 +427,7 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const
// Process Set Configure Request // Process Set Configure Request
// This function parse configuration descriptor & open drivers accordingly // This function parse configuration descriptor & open drivers accordingly
static bool process_set_config(uint8_t rhport, uint8_t config_number) static bool process_set_config(uint8_t rhport)
{ {
uint8_t const * desc_cfg = (uint8_t const *) usbd_desc_set->config; uint8_t const * desc_cfg = (uint8_t const *) usbd_desc_set->config;
TU_ASSERT(desc_cfg != NULL); TU_ASSERT(desc_cfg != NULL);
@ -591,23 +591,23 @@ void dcd_event_handler(dcd_event_t const * event, bool in_isr)
// helper to send bus signal event // helper to send bus signal event
void dcd_event_bus_signal (uint8_t rhport, dcd_eventid_t eid, bool in_isr) void dcd_event_bus_signal (uint8_t rhport, dcd_eventid_t eid, bool in_isr)
{ {
dcd_event_t event = { .rhport = 0, .event_id = eid, }; dcd_event_t event = { .rhport = rhport, .event_id = eid, };
dcd_event_handler(&event, in_isr); dcd_event_handler(&event, in_isr);
} }
// helper to send setup received // helper to send setup received
void dcd_event_setup_received(uint8_t rhport, uint8_t const * setup, bool in_isr) void dcd_event_setup_received(uint8_t rhport, uint8_t const * setup, bool in_isr)
{ {
dcd_event_t event = { .rhport = 0, .event_id = DCD_EVENT_SETUP_RECEIVED }; dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_SETUP_RECEIVED };
memcpy(&event.setup_received, setup, 8); memcpy(&event.setup_received, setup, 8);
dcd_event_handler(&event, true); dcd_event_handler(&event, in_isr);
} }
// helper to send transfer complete event // helper to send transfer complete event
void dcd_event_xfer_complete (uint8_t rhport, uint8_t ep_addr, uint32_t xferred_bytes, uint8_t result, bool in_isr) void dcd_event_xfer_complete (uint8_t rhport, uint8_t ep_addr, uint32_t xferred_bytes, uint8_t result, bool in_isr)
{ {
dcd_event_t event = { .rhport = 0, .event_id = DCD_EVENT_XFER_COMPLETE }; dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_XFER_COMPLETE };
event.xfer_complete.ep_addr = ep_addr; event.xfer_complete.ep_addr = ep_addr;
event.xfer_complete.len = xferred_bytes; event.xfer_complete.len = xferred_bytes;

View File

@ -101,18 +101,19 @@ enum
ITF_NUM_TOTAL ITF_NUM_TOTAL
}; };
enum { enum
ITF_STR_LANGUAGE = 0 , {
ITF_STR_MANUFACTURER , ITF_STR_LANGUAGE = 0 ,
ITF_STR_PRODUCT , ITF_STR_MANUFACTURER ,
ITF_STR_SERIAL , ITF_STR_PRODUCT ,
ITF_STR_SERIAL ,
#if CFG_TUD_CDC #if CFG_TUD_CDC
ITF_STR_CDC , ITF_STR_CDC ,
#endif #endif
#if CFG_TUD_MSC #if CFG_TUD_MSC
ITF_STR_MSC , ITF_STR_MSC ,
#endif #endif
#if CFG_TUD_HID_KEYBOARD && CFG_TUD_HID_KEYBOARD_BOOT #if CFG_TUD_HID_KEYBOARD && CFG_TUD_HID_KEYBOARD_BOOT
@ -133,23 +134,51 @@ enum {
#define _EP_OUT(x) (x) #define _EP_OUT(x) (x)
// CDC // CDC
#define EP_CDC_NOTIF _EP_IN ( ITF_NUM_CDC+1 ) #ifdef CFG_TUD_DESC_CDC_EPNUM_NOTIF
#define EP_CDC_NOTIF _EP_IN (CFG_TUD_DESC_CDC_EPNUM_NOTIF)
#else
#define EP_CDC_NOTIF _EP_IN ( ITF_NUM_CDC+1 )
#endif
#define EP_CDC_NOTIF_SIZE 8 #define EP_CDC_NOTIF_SIZE 8
#define EP_CDC_OUT _EP_OUT( ITF_NUM_CDC+2 ) #ifdef CFG_TUD_DESC_CDC_EPNUM
#define EP_CDC_IN _EP_IN ( ITF_NUM_CDC+2 ) #define EP_CDC_OUT _EP_OUT( CFG_TUD_DESC_CDC_EPNUM )
#define EP_CDC_IN _EP_IN ( CFG_TUD_DESC_CDC_EPNUM )
#else
#define EP_CDC_OUT _EP_OUT( ITF_NUM_CDC+2 )
#define EP_CDC_IN _EP_IN ( ITF_NUM_CDC+2 )
#endif
// Mass Storage // Mass Storage
#define EP_MSC_OUT _EP_OUT( ITF_NUM_MSC+1 ) #ifdef CFG_TUD_DESC_MSC_EPNUM
#define EP_MSC_IN _EP_IN ( ITF_NUM_MSC+1 ) #define EP_MSC_OUT _EP_OUT( CFG_TUD_DESC_MSC_EPNUM )
#define EP_MSC_IN _EP_IN ( CFG_TUD_DESC_MSC_EPNUM )
#else
#define EP_MSC_OUT _EP_OUT( ITF_NUM_MSC+1 )
#define EP_MSC_IN _EP_IN ( ITF_NUM_MSC+1 )
#endif
#if TUD_OPT_HIGH_SPEED
#define EP_MSC_SIZE 512
#else
#define EP_MSC_SIZE 64
#endif
// HID Keyboard with boot protocol // HID Keyboard with boot protocol
#define EP_HID_KBD_BOOT _EP_IN ( ITF_NUM_HID_BOOT_KBD+1 ) #ifdef CFG_TUD_DESC_HID_KEYBOARD_EPNUM
#define EP_HID_KBD_BOOT _EP_IN ( CFG_TUD_DESC_HID_KEYBOARD_EPNUM )
#else
#define EP_HID_KBD_BOOT _EP_IN ( ITF_NUM_HID_BOOT_KBD+1 )
#endif
#define EP_HID_KBD_BOOT_SZ 8 #define EP_HID_KBD_BOOT_SZ 8
// HID Mouse with boot protocol // HID Mouse with boot protocol
#define EP_HID_MSE_BOOT _EP_IN ( ITF_NUM_HID_BOOT_MSE+1 ) #ifdef CFG_TUD_DESC_HID_MOUSE_EPNUM
#define EP_HID_MSE_BOOT _EP_IN ( CFG_TUD_DESC_HID_MOUSE_EPNUM )
#else
#define EP_HID_MSE_BOOT _EP_IN ( ITF_NUM_HID_BOOT_MSE+1 )
#endif
#define EP_HID_MSE_BOOT_SZ 8 #define EP_HID_MSE_BOOT_SZ 8
// HID composite = keyboard + mouse + gamepad + etc ... // HID composite = keyboard + mouse + gamepad + etc ...
@ -466,7 +495,7 @@ desc_auto_cfg_t const _desc_auto_config_struct =
.bDescriptorType = TUSB_DESC_ENDPOINT, .bDescriptorType = TUSB_DESC_ENDPOINT,
.bEndpointAddress = EP_MSC_OUT, .bEndpointAddress = EP_MSC_OUT,
.bmAttributes = { .xfer = TUSB_XFER_BULK }, .bmAttributes = { .xfer = TUSB_XFER_BULK },
.wMaxPacketSize = { .size = CFG_TUD_MSC_EPSIZE}, .wMaxPacketSize = { .size = EP_MSC_SIZE},
.bInterval = 1 .bInterval = 1
}, },
@ -476,7 +505,7 @@ desc_auto_cfg_t const _desc_auto_config_struct =
.bDescriptorType = TUSB_DESC_ENDPOINT, .bDescriptorType = TUSB_DESC_ENDPOINT,
.bEndpointAddress = EP_MSC_IN, .bEndpointAddress = EP_MSC_IN,
.bmAttributes = { .xfer = TUSB_XFER_BULK }, .bmAttributes = { .xfer = TUSB_XFER_BULK },
.wMaxPacketSize = { .size = CFG_TUD_MSC_EPSIZE}, .wMaxPacketSize = { .size = EP_MSC_SIZE},
.bInterval = 1 .bInterval = 1
} }
}, },
@ -563,7 +592,6 @@ desc_auto_cfg_t const _desc_auto_config_struct =
#endif // boot mouse #endif // boot mouse
#if AUTO_DESC_HID_GENERIC #if AUTO_DESC_HID_GENERIC
//------------- HID Generic Multiple report -------------// //------------- HID Generic Multiple report -------------//
.hid_generic = .hid_generic =
{ {
@ -601,7 +629,6 @@ desc_auto_cfg_t const _desc_auto_config_struct =
.bInterval = 0x0A .bInterval = 0x0A
} }
} }
#endif // hid generic #endif // hid generic
}; };

View File

@ -68,6 +68,7 @@ CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t _usbd_ctrl_buf[CFG_TUD_ENDOINT0_
void usbd_control_reset (uint8_t rhport) void usbd_control_reset (uint8_t rhport)
{ {
(void) rhport;
tu_varclr(&_control_state); tu_varclr(&_control_state);
} }
@ -126,8 +127,11 @@ bool usbd_control_xfer(uint8_t rhport, tusb_control_request_t const * request, v
} }
// callback when a transaction complete on DATA stage of control endpoint // callback when a transaction complete on DATA stage of control endpoint
bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes) bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes)
{ {
(void) result;
(void) ep_addr;
if ( _control_state.request.bmRequestType_bit.direction == TUSB_DIR_OUT ) if ( _control_state.request.bmRequestType_bit.direction == TUSB_DIR_OUT )
{ {
memcpy(_control_state.buffer, _usbd_ctrl_buf, xferred_bytes); memcpy(_control_state.buffer, _usbd_ctrl_buf, xferred_bytes);

View File

@ -84,11 +84,11 @@ bool dcd_init (uint8_t rhport)
void dcd_connect (uint8_t rhport) void dcd_connect (uint8_t rhport)
{ {
(void) rhport;
} }
void dcd_disconnect (uint8_t rhport) void dcd_disconnect (uint8_t rhport)
{ {
(void) rhport;
} }
void dcd_set_address (uint8_t rhport, uint8_t dev_addr) void dcd_set_address (uint8_t rhport, uint8_t dev_addr)

View File

@ -197,16 +197,17 @@ bool dcd_init (uint8_t rhport)
void dcd_connect (uint8_t rhport) void dcd_connect (uint8_t rhport)
{ {
(void) rhport;
} }
void dcd_disconnect (uint8_t rhport) void dcd_disconnect (uint8_t rhport)
{ {
(void) rhport;
} }
void dcd_set_address (uint8_t rhport, uint8_t dev_addr) void dcd_set_address (uint8_t rhport, uint8_t dev_addr)
{ {
(void) rhport; (void) rhport;
(void) dev_addr;
// Set Address is automatically update by hw controller // Set Address is automatically update by hw controller
} }
@ -362,7 +363,7 @@ void USBD_IRQHandler(void)
volatile uint32_t* regevt = &NRF_USBD->EVENTS_USBRESET; volatile uint32_t* regevt = &NRF_USBD->EVENTS_USBRESET;
for(int i=0; i<USBD_INTEN_EPDATA_Pos+1; i++) for(uint8_t i=0; i<USBD_INTEN_EPDATA_Pos+1; i++)
{ {
if ( BIT_TEST_(inten, i) && regevt[i] ) if ( BIT_TEST_(inten, i) && regevt[i] )
{ {

View File

@ -40,86 +40,145 @@
#if TUSB_OPT_DEVICE_ENABLED && (CFG_TUSB_MCU == OPT_MCU_LPC175X_6X) #if TUSB_OPT_DEVICE_ENABLED && (CFG_TUSB_MCU == OPT_MCU_LPC175X_6X)
#define _TINY_USB_SOURCE_FILE_
//--------------------------------------------------------------------+
// INCLUDE
//--------------------------------------------------------------------+
#include "device/dcd.h" #include "device/dcd.h"
#include "dcd_lpc175x_6x.h" #include "dcd_lpc175x_6x.h"
#include "usbd_dcd.h" #include "LPC17xx.h"
#include "osal/osal.h"
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// MACRO CONSTANT TYPEDEF // MACRO CONSTANT TYPEDEF
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
#define DCD_QHD_MAX 32 #define DCD_ENDPOINT_MAX 32
#define DCD_QTD_MAX 32 // TODO scale with configure
typedef struct { typedef struct ATTR_ALIGNED(4)
volatile dcd_dma_descriptor_t* udca[DCD_QHD_MAX]; // must be 128 byte aligned {
dcd_dma_descriptor_t dd[DCD_QTD_MAX][2]; // each endpoints can have up to 2 DD queued at a time TODO 0-1 are not used, offset to reduce memory //------------- Word 0 -------------//
uint32_t next;
uint8_t class_code[DCD_QHD_MAX]; //------------- Word 1 -------------//
uint16_t atle_mode : 2; // 00: normal, 01: ATLE (auto length extraction)
uint16_t next_valid : 1;
uint16_t : 1; ///< reserved
uint16_t isochronous : 1; // is an iso endpoint
uint16_t max_packet_size : 11;
struct { volatile uint16_t buflen; // bytes for non-iso, number of packets for iso endpoint
uint8_t* p_data;
uint16_t remaining_bytes;
uint8_t int_on_complete;
}control_dma;
}dcd_data_t; //------------- Word 2 -------------//
volatile uint32_t buffer;
//------------- Word 3 -------------//
volatile uint16_t retired : 1; // initialized to zero
volatile uint16_t status : 4;
volatile uint16_t iso_last_packet_valid : 1;
volatile uint16_t atle_lsb_extracted : 1; // used in ATLE mode
volatile uint16_t atle_msb_extracted : 1; // used in ATLE mode
volatile uint16_t atle_mess_len_position : 6; // used in ATLE mode
uint16_t : 2;
volatile uint16_t present_count; // For non-iso : The number of bytes transferred by the DMA engine
// For iso : number of packets
//------------- Word 4 -------------//
// uint32_t iso_packet_size_addr; // iso only, can be omitted for non-iso
}dma_desc_t;
TU_VERIFY_STATIC( sizeof(dma_desc_t) == 16, "size is not correct"); // TODO not support ISO for now
typedef struct
{
// must be 128 byte aligned
volatile dma_desc_t* udca[DCD_ENDPOINT_MAX];
// TODO DMA does not support control transfer (0-1 are not used, offset to reduce memory)
dma_desc_t dd[DCD_ENDPOINT_MAX];
struct
{
uint8_t* out_buffer;
uint8_t out_bytes;
volatile bool out_received; // indicate if data is already received in endpoint
uint8_t in_bytes;
} control;
} dcd_data_t;
ATTR_ALIGNED(128) static dcd_data_t _dcd;
CFG_TUSB_MEM_SECTION ATTR_ALIGNED(128) STATIC_VAR dcd_data_t dcd_data;
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// INTERNAL OBJECT & FUNCTION DECLARATION // SIE Command
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
static void bus_reset(void); static void sie_cmd_code (sie_cmdphase_t phase, uint8_t code_data)
static tusb_error_t pipe_control_read(void * buffer, uint16_t length); {
static tusb_error_t pipe_control_write(void const * buffer, uint16_t length); LPC_USB->USBDevIntClr = (DEV_INT_COMMAND_CODE_EMPTY_MASK | DEV_INT_COMMAND_DATA_FULL_MASK);
static tusb_error_t pipe_control_xfer(uint8_t ep_id, uint8_t* p_buffer, uint16_t length); LPC_USB->USBCmdCode = (phase << 8) | (code_data << 16);
uint32_t const wait_flag = (phase == SIE_CMDPHASE_READ) ? DEV_INT_COMMAND_DATA_FULL_MASK : DEV_INT_COMMAND_CODE_EMPTY_MASK;
while ((LPC_USB->USBDevIntSt & wait_flag) == 0) {}
LPC_USB->USBDevIntClr = wait_flag;
}
static void sie_write (uint8_t cmd_code, uint8_t data_len, uint8_t data)
{
sie_cmd_code(SIE_CMDPHASE_COMMAND, cmd_code);
if (data_len)
{
sie_cmd_code(SIE_CMDPHASE_WRITE, data);
}
}
static uint32_t sie_read (uint8_t cmd_code, uint8_t data_len)
{
// TODO multiple read
sie_cmd_code(SIE_CMDPHASE_COMMAND , cmd_code);
sie_cmd_code(SIE_CMDPHASE_READ , cmd_code);
return LPC_USB->USBCmdData;
}
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// PIPE HELPER // PIPE HELPER
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
static inline uint8_t edpt_addr2phy(uint8_t endpoint_addr) ATTR_CONST ATTR_ALWAYS_INLINE; static inline uint8_t ep_addr2idx(uint8_t ep_addr)
static inline uint8_t edpt_addr2phy(uint8_t endpoint_addr)
{ {
return 2*(endpoint_addr & 0x0F) + ((endpoint_addr & TUSB_DIR_IN_MASK) ? 1 : 0); return 2*(ep_addr & 0x0F) + ((ep_addr & TUSB_DIR_IN_MASK) ? 1 : 0);
} }
static inline void edpt_set_max_packet_size(uint8_t ep_id, uint16_t max_packet_size) ATTR_ALWAYS_INLINE; static void set_ep_size(uint8_t ep_id, uint16_t max_packet_size)
static inline void edpt_set_max_packet_size(uint8_t ep_id, uint16_t max_packet_size) {
{ // follows example in 11.10.4.2 // follows example in 11.10.4.2
LPC_USB->USBReEp |= BIT_(ep_id); LPC_USB->USBReEp |= BIT_(ep_id);
LPC_USB->USBEpInd = ep_id; // select index before setting packet size LPC_USB->USBEpInd = ep_id; // select index before setting packet size
LPC_USB->USBMaxPSize = max_packet_size; LPC_USB->USBMaxPSize = max_packet_size;
#ifndef _TEST_ while ((LPC_USB->USBDevIntSt & DEV_INT_ENDPOINT_REALIZED_MASK) == 0) {}
while ((LPC_USB->USBDevIntSt & DEV_INT_ENDPOINT_REALIZED_MASK) == 0) {} // TODO can be omitted
LPC_USB->USBDevIntClr = DEV_INT_ENDPOINT_REALIZED_MASK; LPC_USB->USBDevIntClr = DEV_INT_ENDPOINT_REALIZED_MASK;
#endif
} }
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// USBD-DCD API // CONTROLLER API
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
static void bus_reset(void) static void bus_reset(void)
{ {
// step 7 : slave mode set up // step 7 : slave mode set up
LPC_USB->USBEpIntClr = 0xFFFFFFFF; // clear all pending interrupt LPC_USB->USBEpIntClr = 0xFFFFFFFF; // clear all pending interrupt
LPC_USB->USBDevIntClr = 0xFFFFFFFF; // clear all pending interrupt LPC_USB->USBDevIntClr = 0xFFFFFFFF; // clear all pending interrupt
LPC_USB->USBEpIntEn = (uint32_t) BIN8(11); // control endpoint cannot use DMA, non-control all use DMA LPC_USB->USBEpIntEn = 0x03UL; // control endpoint cannot use DMA, non-control all use DMA
LPC_USB->USBEpIntPri = 0; // same priority for all endpoint LPC_USB->USBEpIntPri = 0x03UL; // fast for control endpoint
// step 8 : DMA set up // step 8 : DMA set up
LPC_USB->USBEpDMADis = 0xFFFFFFFF; // firstly disable all dma LPC_USB->USBEpDMADis = 0xFFFFFFFF; // firstly disable all dma
LPC_USB->USBDMARClr = 0xFFFFFFFF; // clear all pending interrupt LPC_USB->USBDMARClr = 0xFFFFFFFF; // clear all pending interrupt
LPC_USB->USBEoTIntClr = 0xFFFFFFFF; LPC_USB->USBEoTIntClr = 0xFFFFFFFF;
LPC_USB->USBNDDRIntClr = 0xFFFFFFFF; LPC_USB->USBNDDRIntClr = 0xFFFFFFFF;
LPC_USB->USBSysErrIntClr = 0xFFFFFFFF; LPC_USB->USBSysErrIntClr = 0xFFFFFFFF;
tu_memclr(&dcd_data, sizeof(dcd_data_t)); tu_memclr(&_dcd, sizeof(dcd_data_t));
} }
bool dcd_init(uint8_t rhport) bool dcd_init(uint8_t rhport)
@ -128,171 +187,32 @@ bool dcd_init(uint8_t rhport)
//------------- user manual 11.13 usb device controller initialization -------------// LPC_USB->USBEpInd = 0; //------------- user manual 11.13 usb device controller initialization -------------// LPC_USB->USBEpInd = 0;
// step 6 : set up control endpoint // step 6 : set up control endpoint
edpt_set_max_packet_size(0, CFG_TUD_ENDOINT0_SIZE); set_ep_size(0, CFG_TUD_ENDOINT0_SIZE);
edpt_set_max_packet_size(1, CFG_TUD_ENDOINT0_SIZE); set_ep_size(1, CFG_TUD_ENDOINT0_SIZE);
bus_reset(); bus_reset();
LPC_USB->USBDevIntEn = (DEV_INT_DEVICE_STATUS_MASK | DEV_INT_ENDPOINT_SLOW_MASK | DEV_INT_ERROR_MASK); LPC_USB->USBDevIntEn = (DEV_INT_DEVICE_STATUS_MASK | DEV_INT_ENDPOINT_FAST_MASK | DEV_INT_ENDPOINT_SLOW_MASK | DEV_INT_ERROR_MASK);
LPC_USB->USBUDCAH = (uint32_t) dcd_data.udca; LPC_USB->USBUDCAH = (uint32_t) _dcd.udca;
LPC_USB->USBDMAIntEn = (DMA_INT_END_OF_XFER_MASK | DMA_INT_ERROR_MASK ); LPC_USB->USBDMAIntEn = (DMA_INT_END_OF_XFER_MASK /*| DMA_INT_NEW_DD_REQUEST_MASK*/ | DMA_INT_ERROR_MASK);
sie_write(SIE_CMDCODE_DEVICE_STATUS, 1, 1); // connect sie_write(SIE_CMDCODE_DEVICE_STATUS, 1, 1); // connect
NVIC_EnableIRQ(USB_IRQn); // USB IRQ priority should be set by application previously
// If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher )
#if CFG_TUSB_OS == OPT_OS_FREERTOS
if ( NVIC_GetPriority(USB_IRQn) < configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY )
{
NVIC_SetPriority(USB_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY );
}
#endif
NVIC_ClearPendingIRQ(USB_IRQn);
NVIC_EnableIRQ(USB_IRQn);
return TUSB_ERROR_NONE; return TUSB_ERROR_NONE;
} }
static void endpoint_non_control_isr(uint32_t eot_int)
{
for(uint8_t ep_id = 2; ep_id < DCD_QHD_MAX; ep_id++ )
{
if ( BIT_TEST_(eot_int, ep_id) )
{
dcd_dma_descriptor_t* const p_first_dd = &dcd_data.dd[ep_id][0];
dcd_dma_descriptor_t* const p_last_dd = dcd_data.dd[ep_id] + (p_first_dd->is_next_valid ? 1 : 0); // Maximum is 2 QTD are queued in an endpoint
// only handle when Controller already finished the last DD
if ( dcd_data.udca[ep_id] == p_last_dd )
{
dcd_data.udca[ep_id] = p_first_dd; // UDCA currently points to the last DD, change to the fixed DD
p_first_dd->buffer_length = 0; // buffer length is used to determined if first dd is queued in pipe xfer function
if ( p_last_dd->int_on_complete )
{
edpt_hdl_t edpt_hdl =
{
.rhport = 0,
.index = ep_id,
.class_code = dcd_data.class_code[ep_id]
};
bool succeeded = (p_last_dd->status == DD_STATUS_NORMAL || p_last_dd->status == DD_STATUS_DATA_UNDERUN) ? true : false;
dcd_xfer_complete(edpt_hdl, p_last_dd->present_count, succeeded); // report only xferred bytes in the IOC qtd
}
}
}
}
}
static void endpoint_control_isr(void)
{
uint32_t const interrupt_enable = LPC_USB->USBEpIntEn;
uint32_t const endpoint_int_status = LPC_USB->USBEpIntSt & interrupt_enable;
// LPC_USB->USBEpIntClr = endpoint_int_status; // acknowledge interrupt TODO cannot immediately acknowledge setup packet
dcd_event_t event = { .rhport = 0 };
//------------- Setup Recieved-------------//
if ( (endpoint_int_status & BIT_(0)) &&
(sie_read(SIE_CMDCODE_ENDPOINT_SELECT+0, 1) & SIE_SELECT_ENDPOINT_SETUP_RECEIVED_MASK) )
{
(void) sie_read(SIE_CMDCODE_ENDPOINT_SELECT_CLEAR_INTERRUPT+0, 1); // clear setup bit
event.event_id = DCD_EVENT_SETUP_RECEIVED;
pipe_control_read(&event.setup_received, 8); // TODO read before clear setup above
dcd_event_handler(&event, true);
}
else if (endpoint_int_status & 0x03)
{
uint8_t const ep_id = ( endpoint_int_status & BIT_(0) ) ? 0 : 1;
if ( dcd_data.control_dma.remaining_bytes > 0 )
{ // there are still data to transfer
pipe_control_xfer(ep_id, dcd_data.control_dma.p_data, dcd_data.control_dma.remaining_bytes);
}
else
{
dcd_data.control_dma.remaining_bytes = 0;
if ( BIT_TEST_(dcd_data.control_dma.int_on_complete, ep_id) )
{
edpt_hdl_t edpt_hdl = { .rhport = 0, .class_code = 0 };
dcd_data.control_dma.int_on_complete = 0;
// FIXME xferred_byte for control xfer is not needed now !!!
dcd_xfer_complete(edpt_hdl, 0, true);
}
}
}
LPC_USB->USBEpIntClr = endpoint_int_status; // acknowledge interrupt TODO cannot immediately acknowledge setup packet
}
void hal_dcd_isr(uint8_t rhport)
{
(void) rhport;
uint32_t const device_int_enable = LPC_USB->USBDevIntEn;
uint32_t const device_int_status = LPC_USB->USBDevIntSt & device_int_enable;
LPC_USB->USBDevIntClr = device_int_status;// Acknowledge handled interrupt
dcd_event_t event = { .rhport = rhport };
//------------- usb bus event -------------//
if (device_int_status & DEV_INT_DEVICE_STATUS_MASK)
{
uint8_t const dev_status_reg = sie_read(SIE_CMDCODE_DEVICE_STATUS, 1);
if (dev_status_reg & SIE_DEV_STATUS_RESET_MASK)
{
bus_reset();
event.event_id = DCD_EVENT_BUS_RESET;
dcd_event_handler(&event, true);
}
if (dev_status_reg & SIE_DEV_STATUS_CONNECT_CHANGE_MASK)
{ // device is disconnected, require using VBUS (P1_30)
event.event_id = DCD_EVENT_UNPLUGGED;
dcd_event_handler(&event, true);
}
if (dev_status_reg & SIE_DEV_STATUS_SUSPEND_CHANGE_MASK)
{
if (dev_status_reg & SIE_DEV_STATUS_SUSPEND_MASK)
{
event.event_id = DCD_EVENT_SUSPENDED;
dcd_event_handler(&event, true);
}
// else
// { // resume signal
// event.event_id = DCD_EVENT_RESUME;
// dcd_event_handler(&event, true);
// }
// }
}
}
//------------- Control Endpoint (Slave Mode) -------------//
if (device_int_status & DEV_INT_ENDPOINT_SLOW_MASK)
{
endpoint_control_isr();
}
//------------- Non-Control Endpoint (DMA Mode) -------------//
uint32_t const dma_int_enable = LPC_USB->USBDMAIntEn;
uint32_t const dma_int_status = LPC_USB->USBDMAIntSt & dma_int_enable;
if (dma_int_status & DMA_INT_END_OF_XFER_MASK)
{
uint32_t eot_int = LPC_USB->USBEoTIntSt;
LPC_USB->USBEoTIntClr = eot_int; // acknowledge interrupt source
endpoint_non_control_isr(eot_int);
}
if (device_int_status & DEV_INT_ERROR_MASK || dma_int_status & DMA_INT_ERROR_MASK)
{
uint32_t error_status = sie_read(SIE_CMDCODE_READ_ERROR_STATUS, 1);
(void) error_status;
// TU_ASSERT(false, (void) 0);
}
}
//--------------------------------------------------------------------+
// USBD API - CONTROLLER
//--------------------------------------------------------------------+
void dcd_connect(uint8_t rhport) void dcd_connect(uint8_t rhport)
{ {
(void) rhport; (void) rhport;
@ -313,65 +233,45 @@ void dcd_set_config(uint8_t rhport, uint8_t config_num)
} }
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// PIPE CONTROL HELPER // CONTROL HELPER
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
static inline uint16_t length_byte2dword(uint16_t length_in_bytes) ATTR_ALWAYS_INLINE ATTR_CONST; static inline uint8_t byte2dword(uint8_t bytes)
static inline uint16_t length_byte2dword(uint16_t length_in_bytes)
{ {
return (length_in_bytes + 3) / 4; // length_in_dword return (bytes + 3) / 4; // length in dwords
} }
static tusb_error_t pipe_control_xfer(uint8_t ep_id, uint8_t* p_buffer, uint16_t length) static void control_ep_write(void const * buffer, uint8_t len)
{ {
uint16_t const packet_len = tu_min16(length, CFG_TUD_ENDOINT0_SIZE); uint32_t const * buf32 = (uint32_t const *) buffer;
if (ep_id)
{
TU_ASSERT_ERR ( pipe_control_write(p_buffer, packet_len) );
}else
{
TU_ASSERT_ERR ( pipe_control_read(p_buffer, packet_len) );
}
dcd_data.control_dma.remaining_bytes -= packet_len;
dcd_data.control_dma.p_data += packet_len;
return TUSB_ERROR_NONE;
}
static tusb_error_t pipe_control_write(void const * buffer, uint16_t length)
{
uint32_t const * p_write_data = (uint32_t const *) buffer;
LPC_USB->USBCtrl = USBCTRL_WRITE_ENABLE_MASK; // logical endpoint = 0 LPC_USB->USBCtrl = USBCTRL_WRITE_ENABLE_MASK; // logical endpoint = 0
LPC_USB->USBTxPLen = length; LPC_USB->USBTxPLen = (uint32_t) len;
for (uint16_t count = 0; count < length_byte2dword(length); count++) for (uint8_t count = 0; count < byte2dword(len); count++)
{ {
LPC_USB->USBTxData = *p_write_data; // NOTE: cortex M3 have no problem with alignment LPC_USB->USBTxData = *buf32; // NOTE: cortex M3 have no problem with alignment
p_write_data++; buf32++;
} }
LPC_USB->USBCtrl = 0; LPC_USB->USBCtrl = 0;
// select control IN & validate the endpoint // select control IN & validate the endpoint
sie_write(SIE_CMDCODE_ENDPOINT_SELECT+1, 0, 0); sie_write(SIE_CMDCODE_ENDPOINT_SELECT+1, 0, 0);
sie_write(SIE_CMDCODE_BUFFER_VALIDATE , 0, 0); sie_write(SIE_CMDCODE_BUFFER_VALIDATE , 0, 0);
return TUSB_ERROR_NONE;
} }
static tusb_error_t pipe_control_read(void * buffer, uint16_t length) static uint8_t control_ep_read(void * buffer, uint8_t len)
{ {
LPC_USB->USBCtrl = USBCTRL_READ_ENABLE_MASK; // logical endpoint = 0 LPC_USB->USBCtrl = USBCTRL_READ_ENABLE_MASK; // logical endpoint = 0
while ((LPC_USB->USBRxPLen & USBRXPLEN_PACKET_READY_MASK) == 0) {} // TODO blocking, should have timeout while ((LPC_USB->USBRxPLen & USBRXPLEN_PACKET_READY_MASK) == 0) {} // TODO blocking, should have timeout
uint16_t actual_length = tu_min16(length, (uint16_t) (LPC_USB->USBRxPLen & USBRXPLEN_PACKET_LENGTH_MASK) ); len = tu_min8(len, (uint8_t) (LPC_USB->USBRxPLen & USBRXPLEN_PACKET_LENGTH_MASK) );
uint32_t *p_read_data = (uint32_t*) buffer; uint32_t *buf32 = (uint32_t*) buffer;
for( uint16_t count=0; count < length_byte2dword(actual_length); count++)
for (uint8_t count=0; count < byte2dword(len); count++)
{ {
*p_read_data = LPC_USB->USBRxData; *buf32 = LPC_USB->USBRxData;
p_read_data++; // increase by 4 ( sizeof(uint32_t) ) buf32++;
} }
LPC_USB->USBCtrl = 0; LPC_USB->USBCtrl = 0;
@ -380,164 +280,323 @@ static tusb_error_t pipe_control_read(void * buffer, uint16_t length)
sie_write(SIE_CMDCODE_ENDPOINT_SELECT+0, 0, 0); sie_write(SIE_CMDCODE_ENDPOINT_SELECT+0, 0, 0);
sie_write(SIE_CMDCODE_BUFFER_CLEAR , 0, 0); sie_write(SIE_CMDCODE_BUFFER_CLEAR , 0, 0);
return TUSB_ERROR_NONE; return len;
} }
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// CONTROL PIPE API // DCD Endpoint Port
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
void dcd_control_stall(uint8_t rhport) bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc)
{
sie_write(SIE_CMDCODE_ENDPOINT_SET_STATUS+0, 1, SIE_SET_ENDPOINT_STALLED_MASK | SIE_SET_ENDPOINT_CONDITION_STALLED_MASK);
}
bool dcd_control_xfer(uint8_t rhport, uint8_t dir, uint8_t * p_buffer, uint16_t length, bool int_on_complete)
{ {
(void) rhport; (void) rhport;
TU_VERIFY( !(length != 0 && p_buffer == NULL) ); uint8_t const epnum = edpt_number(p_endpoint_desc->bEndpointAddress);
uint8_t const ep_id = ep_addr2idx(p_endpoint_desc->bEndpointAddress);
// determine Endpoint where Data & Status phase occurred (IN or OUT) // Endpoint type is fixed to endpoint number
uint8_t const ep_data = (dir == TUSB_DIR_IN) ? 1 : 0; // 1: interrupt, 2: Bulk, 3: Iso and so on
uint8_t const ep_status = 1 - ep_data; switch ( p_endpoint_desc->bmAttributes.xfer )
dcd_data.control_dma.int_on_complete = int_on_complete ? BIT_(ep_status) : 0;
//------------- Data Phase -------------//
if ( length )
{ {
dcd_data.control_dma.p_data = (uint8_t*) p_buffer; case TUSB_XFER_INTERRUPT:
dcd_data.control_dma.remaining_bytes = length; TU_ASSERT((epnum % 3) == 1);
break;
// lpc17xx already received the first DATA OUT packet by now case TUSB_XFER_BULK:
TU_VERIFY_ERR ( pipe_control_xfer(ep_data, p_buffer, length), false ); TU_ASSERT((epnum % 3) == 2 || (epnum == 15));
break;
case TUSB_XFER_ISOCHRONOUS:
TU_ASSERT((epnum % 3) == 3 && (epnum != 15));
break;
default:
break;
} }
//------------- Status Phase (opposite direct to Data) -------------// //------------- Realize Endpoint with Max Packet Size -------------//
if (dir == TUSB_DIR_OUT) set_ep_size(ep_id, p_endpoint_desc->wMaxPacketSize.size);
{ // only write for CONTROL OUT, CONTROL IN data will be retrieved in hal_dcd_isr // TODO ????
TU_VERIFY_ERR ( pipe_control_write(NULL, 0), false ); //------------- first DD prepare -------------//
dma_desc_t* const dd = &_dcd.dd[ep_id];
tu_memclr(dd, sizeof(dma_desc_t));
dd->isochronous = (p_endpoint_desc->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS) ? 1 : 0;
dd->max_packet_size = p_endpoint_desc->wMaxPacketSize.size;
dd->retired = 1; // invalid at first
sie_write(SIE_CMDCODE_ENDPOINT_SET_STATUS + ep_id, 1, 0); // clear all endpoint status
return true;
}
bool dcd_edpt_busy(uint8_t rhport, uint8_t ep_addr)
{
(void) rhport;
uint8_t ep_id = ep_addr2idx( ep_addr );
return (_dcd.udca[ep_id] != NULL && !_dcd.udca[ep_id]->retired);
}
void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr)
{
(void) rhport;
if ( edpt_number(ep_addr) == 0 )
{
sie_write(SIE_CMDCODE_ENDPOINT_SET_STATUS+0, 1, SIE_SET_ENDPOINT_STALLED_MASK | SIE_SET_ENDPOINT_CONDITION_STALLED_MASK);
}else
{
uint8_t ep_id = ep_addr2idx( ep_addr );
sie_write(SIE_CMDCODE_ENDPOINT_SET_STATUS+ep_id, 1, SIE_SET_ENDPOINT_STALLED_MASK);
}
}
void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
{
(void) rhport;
uint8_t ep_id = ep_addr2idx(ep_addr);
sie_write(SIE_CMDCODE_ENDPOINT_SET_STATUS+ep_id, 1, 0);
}
bool dcd_edpt_stalled (uint8_t rhport, uint8_t ep_addr)
{
(void) rhport;
uint32_t const ep_state = sie_read(SIE_CMDCODE_ENDPOINT_SELECT + ep_addr2idx(ep_addr), 1);
return (ep_state & SIE_SELECT_ENDPOINT_STALL_MASK) ? true : false;
}
static bool control_xact(uint8_t rhport, uint8_t dir, uint8_t * buffer, uint8_t len)
{
(void) rhport;
if ( dir )
{
_dcd.control.in_bytes = len;
control_ep_write(buffer, len);
}else
{
if ( _dcd.control.out_received )
{
// Already received the DATA OUT packet
_dcd.control.out_received = false;
_dcd.control.out_buffer = NULL;
_dcd.control.out_bytes = 0;
uint8_t received = control_ep_read(buffer, len);
dcd_event_xfer_complete(0, 0, received, XFER_RESULT_SUCCESS, true);
}else
{
_dcd.control.out_buffer = buffer;
_dcd.control.out_bytes = len;
}
} }
return true; return true;
} }
//--------------------------------------------------------------------+ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes)
// BULK/INTERRUPT/ISO PIPE API
//--------------------------------------------------------------------+
edpt_hdl_t dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc, uint8_t class_code)
{ {
(void) rhport; // Control transfer is not DMA support, and must be done in slave mode
if ( edpt_number(ep_addr) == 0 )
edpt_hdl_t const null_handle = { 0 };
// TODO refractor to universal pipe open validation function
if (p_endpoint_desc->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS) return null_handle; // TODO not support ISO yet
TU_ASSERT (p_endpoint_desc->wMaxPacketSize.size <= 64, null_handle); // TODO ISO can be 1023, but ISO not supported now
uint8_t ep_id = edpt_addr2phy( p_endpoint_desc->bEndpointAddress );
//------------- Realize Endpoint with Max Packet Size -------------//
edpt_set_max_packet_size(ep_id, p_endpoint_desc->wMaxPacketSize.size);
dcd_data.class_code[ep_id] = class_code;
//------------- first DD prepare -------------//
dcd_dma_descriptor_t* const p_dd = &dcd_data.dd[ep_id][0];
tu_memclr(p_dd, sizeof(dcd_dma_descriptor_t));
p_dd->is_isochronous = (p_endpoint_desc->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS) ? 1 : 0;
p_dd->max_packet_size = p_endpoint_desc->wMaxPacketSize.size;
p_dd->is_retired = 1; // inactive at first
dcd_data.udca[ ep_id ] = p_dd; // hook to UDCA
sie_write(SIE_CMDCODE_ENDPOINT_SET_STATUS+ep_id, 1, 0); // clear all endpoint status
return (edpt_hdl_t)
{
.rhport = 0,
.index = ep_id,
.class_code = class_code
};
}
bool dcd_edpt_busy(edpt_hdl_t edpt_hdl)
{
return (dcd_data.udca[edpt_hdl.index] != NULL && !dcd_data.udca[edpt_hdl.index]->is_retired);
}
void dcd_edpt_stall(edpt_hdl_t edpt_hdl)
{
sie_write(SIE_CMDCODE_ENDPOINT_SET_STATUS+edpt_hdl.index, 1, SIE_SET_ENDPOINT_STALLED_MASK);
}
void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
{
uint8_t ep_id = ep_addr2phy(ep_addr);
sie_write(SIE_CMDCODE_ENDPOINT_SET_STATUS+ep_id, 1, 0);
}
void dd_xfer_init(dcd_dma_descriptor_t* p_dd, void* buffer, uint16_t total_bytes)
{
p_dd->next = 0;
p_dd->is_next_valid = 0;
p_dd->buffer_addr = (uint32_t) buffer;
p_dd->buffer_length = total_bytes;
p_dd->status = DD_STATUS_NOT_SERVICED;
p_dd->iso_last_packet_valid = 0;
p_dd->present_count = 0;
}
tusb_error_t dcd_edpt_queue_xfer(edpt_hdl_t edpt_hdl, uint8_t * buffer, uint16_t total_bytes)
{ // NOTE for sure the qhd has no dds
dcd_dma_descriptor_t* const p_fixed_dd = &dcd_data.dd[edpt_hdl.index][0]; // always queue with the fixed DD
dd_xfer_init(p_fixed_dd, buffer, total_bytes);
p_fixed_dd->is_retired = 1;
p_fixed_dd->int_on_complete = 0;
return TUSB_ERROR_NONE;
}
tusb_error_t dcd_edpt_xfer(edpt_hdl_t edpt_hdl, uint8_t* buffer, uint16_t total_bytes, bool int_on_complete)
{
dcd_dma_descriptor_t* const p_first_dd = &dcd_data.dd[edpt_hdl.index][0];
//------------- fixed DD is already queued a xfer -------------//
if ( p_first_dd->buffer_length )
{ {
// setup new dd return control_xact(rhport, edpt_dir(ep_addr), buffer, (uint8_t) total_bytes);
dcd_dma_descriptor_t* const p_dd = &dcd_data.dd[ edpt_hdl.index ][1];
tu_memclr(p_dd, sizeof(dcd_dma_descriptor_t));
dd_xfer_init(p_dd, buffer, total_bytes);
p_dd->max_packet_size = p_first_dd->max_packet_size;
p_dd->is_isochronous = p_first_dd->is_isochronous;
p_dd->int_on_complete = int_on_complete;
// hook to fixed dd
p_first_dd->next = (uint32_t) p_dd;
p_first_dd->is_next_valid = 1;
} }
//------------- fixed DD is free -------------//
else else
{ {
dd_xfer_init(p_first_dd, buffer, total_bytes); uint8_t ep_id = ep_addr2idx(ep_addr);
p_first_dd->int_on_complete = int_on_complete; dma_desc_t* dd = &_dcd.dd[ep_id];
// Prepare DMA descriptor
// Isochronous & max packet size must be preserved, Other fields of dd should be clear
uint16_t const ep_size = dd->max_packet_size;
uint8_t is_iso = dd->isochronous;
tu_memclr(dd, sizeof(dma_desc_t));
dd->isochronous = is_iso;
dd->max_packet_size = ep_size;
dd->buffer = buffer;
dd->buflen = total_bytes;
_dcd.udca[ep_id] = dd;
if ( ep_id % 2 )
{
// Clear EP interrupt before Enable DMA
LPC_USB->USBEpIntEn &= ~BIT_(ep_id);
LPC_USB->USBEpDMAEn = BIT_(ep_id);
// endpoint IN need to actively raise DMA request
LPC_USB->USBDMARSet = BIT_(ep_id);
}else
{
// Enable DMA
LPC_USB->USBEpDMAEn = BIT_(ep_id);
}
return true;
}
}
//--------------------------------------------------------------------+
// ISR
//--------------------------------------------------------------------+
// handle control xfer (slave mode)
static void control_xfer_isr(uint8_t rhport, uint32_t ep_int_status)
{
// Control out complete
if ( ep_int_status & BIT_(0) )
{
bool is_setup = sie_read(SIE_CMDCODE_ENDPOINT_SELECT+0, 1) & SIE_SELECT_ENDPOINT_SETUP_RECEIVED_MASK;
LPC_USB->USBEpIntClr = BIT_(0);
if (is_setup)
{
uint8_t setup_packet[8];
control_ep_read(setup_packet, 8); // TODO read before clear setup above
dcd_event_setup_received(rhport, setup_packet, true);
}
else if ( _dcd.control.out_buffer )
{
// software queued transfer previously
uint8_t received = control_ep_read(_dcd.control.out_buffer, _dcd.control.out_bytes);
_dcd.control.out_buffer = NULL;
_dcd.control.out_bytes = 0;
dcd_event_xfer_complete(rhport, 0, received, XFER_RESULT_SUCCESS, true);
}else
{
// hardware auto ack packet -> mark as received
_dcd.control.out_received = true;
}
} }
p_first_dd->is_retired = 0; // activate xfer // Control In complete
dcd_data.udca[edpt_hdl.index] = p_first_dd; if ( ep_int_status & BIT_(1) )
LPC_USB->USBEpDMAEn = BIT_(edpt_hdl.index); {
LPC_USB->USBEpIntClr = BIT_(1);
dcd_event_xfer_complete(rhport, TUSB_DIR_IN_MASK, _dcd.control.in_bytes, XFER_RESULT_SUCCESS, true);
}
}
if ( edpt_hdl.index % 2 ) // handle bus event signal
{ // endpoint IN need to actively raise DMA request static void bus_event_isr(uint8_t rhport)
LPC_USB->USBDMARSet = BIT_(edpt_hdl.index); {
uint8_t const dev_status = sie_read(SIE_CMDCODE_DEVICE_STATUS, 1);
if (dev_status & SIE_DEV_STATUS_RESET_MASK)
{
bus_reset();
dcd_event_bus_signal(rhport, DCD_EVENT_BUS_RESET, true);
} }
return TUSB_ERROR_NONE; if (dev_status & SIE_DEV_STATUS_CONNECT_CHANGE_MASK)
{
// device is disconnected, require using VBUS (P1_30)
dcd_event_bus_signal(rhport, DCD_EVENT_UNPLUGGED, true);
}
if (dev_status & SIE_DEV_STATUS_SUSPEND_CHANGE_MASK)
{
if (dev_status & SIE_DEV_STATUS_SUSPEND_MASK)
{
dcd_event_bus_signal(rhport, DCD_EVENT_SUSPENDED, true);
}
else
{
dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true);
}
}
}
// Helper to complete a DMA descriptor for non-control transfer
static void dd_complete_isr(uint8_t rhport, uint8_t ep_id)
{
dma_desc_t* const dd = &_dcd.dd[ep_id];
uint8_t result = (dd->status == DD_STATUS_NORMAL || dd->status == DD_STATUS_DATA_UNDERUN) ? XFER_RESULT_SUCCESS : XFER_RESULT_FAILED;
uint8_t const ep_addr = (ep_id / 2) | ((ep_id & 0x01) ? TUSB_DIR_IN_MASK : 0);
dcd_event_xfer_complete(rhport, ep_addr, dd->present_count, result, true);
}
// main USB IRQ handler
void hal_dcd_isr(uint8_t rhport)
{
uint32_t const dev_int_status = LPC_USB->USBDevIntSt & LPC_USB->USBDevIntEn;
LPC_USB->USBDevIntClr = dev_int_status;// Acknowledge handled interrupt
// Bus event
if (dev_int_status & DEV_INT_DEVICE_STATUS_MASK)
{
bus_event_isr(rhport);
}
// Endpoint interrupt
uint32_t const ep_int_status = LPC_USB->USBEpIntSt & LPC_USB->USBEpIntEn;
// Control Endpoint are fast
if (dev_int_status & DEV_INT_ENDPOINT_FAST_MASK)
{
// Note clear USBEpIntClr will also clear the setup received bit --> clear after handle setup packet
// Only clear USBEpIntClr 1 endpoint each, and should wait for CDFULL bit set
control_xfer_isr(rhport, ep_int_status);
}
// non-control IN are slow
if (dev_int_status & DEV_INT_ENDPOINT_SLOW_MASK)
{
for ( uint8_t ep_id = 3; ep_id < DCD_ENDPOINT_MAX; ep_id += 2 )
{
if ( BIT_TEST_(ep_int_status, ep_id) )
{
LPC_USB->USBEpIntClr = BIT_(ep_id);
// Clear Ep interrupt for next DMA
LPC_USB->USBEpIntEn &= ~BIT_(ep_id);
dd_complete_isr(rhport, ep_id);
}
}
}
// DMA transfer complete (RAM <-> EP) for Non-Control
// OUT: USB transfer is fully complete
// IN : UBS transfer is still on-going -> enable EpIntEn to know when it is complete
uint32_t const dma_int_status = LPC_USB->USBDMAIntSt & LPC_USB->USBDMAIntEn;
if (dma_int_status & DMA_INT_END_OF_XFER_MASK)
{
uint32_t const eot = LPC_USB->USBEoTIntSt;
LPC_USB->USBEoTIntClr = eot; // acknowledge interrupt source
for ( uint8_t ep_id = 2; ep_id < DCD_ENDPOINT_MAX; ep_id++ )
{
if ( BIT_TEST_(eot, ep_id) )
{
if ( ep_id & 0x01 )
{
// IN enable EpInt for end of usb transfer
LPC_USB->USBEpIntEn |= BIT_(ep_id);
}else
{
// OUT
dd_complete_isr(rhport, ep_id);
}
}
}
}
// Errors
if ( (dev_int_status & DEV_INT_ERROR_MASK) || (dma_int_status & DMA_INT_ERROR_MASK) )
{
uint32_t error_status = sie_read(SIE_CMDCODE_READ_ERROR_STATUS, 1);
(void) error_status;
TU_BREAKPOINT();
}
} }
#endif #endif

View File

@ -36,53 +36,15 @@
*/ */
/**************************************************************************/ /**************************************************************************/
/** \ingroup group_dcd
* \defgroup group_dcd_lpc175x_6x LPC175x_6x
* @{ */
#ifndef _TUSB_DCD_LPC175X_6X_H_ #ifndef _TUSB_DCD_LPC175X_6X_H_
#define _TUSB_DCD_LPC175X_6X_H_ #define _TUSB_DCD_LPC175X_6X_H_
#include <common/tusb_common.h> #include "common/tusb_common.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
typedef struct ATTR_ALIGNED(4)
{
//------------- Word 0 -------------//
uint32_t next;
//------------- Word 1 -------------//
uint16_t mode : 2; // either 00 normal or 01 ATLE(auto length extraction)
uint16_t is_next_valid : 1;
uint16_t int_on_complete : 1; ///< make use of reserved bit
uint16_t is_isochronous : 1; // is an iso endpoint
uint16_t max_packet_size : 11;
volatile uint16_t buffer_length;
//------------- Word 2 -------------//
volatile uint32_t buffer_addr;
//------------- Word 3 -------------//
volatile uint16_t is_retired : 1; // initialized to zero
volatile uint16_t status : 4;
volatile uint16_t iso_last_packet_valid : 1;
volatile uint16_t atle_is_lsb_extracted : 1; // used in ATLE mode
volatile uint16_t atle_is_msb_extracted : 1; // used in ATLE mode
volatile uint16_t atle_message_length_position : 6; // used in ATLE mode
uint16_t : 2;
volatile uint16_t present_count; // The number of bytes transferred by the DMA engine. The DMA engine updates this field after completing each packet transfer.
//------------- Word 4 -------------//
// uint32_t iso_packet_size_addr; // iso only, can be omitted for non-iso
}dcd_dma_descriptor_t;
TU_VERIFY_STATIC( sizeof(dcd_dma_descriptor_t) == 16, "size is not correct"); // TODO not support ISO for now
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// Register Interface // Register Interface
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
@ -195,46 +157,8 @@ enum {
DD_STATUS_SYSTEM_ERROR DD_STATUS_SYSTEM_ERROR
}; };
//--------------------------------------------------------------------+
// SIE Command
//--------------------------------------------------------------------+
static inline void sie_cmd_code (sie_cmdphase_t phase, uint8_t code_data) ATTR_ALWAYS_INLINE;
static inline void sie_cmd_code (sie_cmdphase_t phase, uint8_t code_data)
{
LPC_USB->USBDevIntClr = (DEV_INT_COMMAND_CODE_EMPTY_MASK | DEV_INT_COMMAND_DATA_FULL_MASK);
LPC_USB->USBCmdCode = (phase << 8) | (code_data << 16);
uint32_t const wait_flag = (phase == SIE_CMDPHASE_READ) ? DEV_INT_COMMAND_DATA_FULL_MASK : DEV_INT_COMMAND_CODE_EMPTY_MASK;
#ifndef _TEST_
while ((LPC_USB->USBDevIntSt & wait_flag) == 0); // TODO blocking forever potential
#endif
LPC_USB->USBDevIntClr = wait_flag;
}
static inline void sie_write (uint8_t cmd_code, uint8_t data_len, uint8_t data) ATTR_ALWAYS_INLINE;
static inline void sie_write (uint8_t cmd_code, uint8_t data_len, uint8_t data)
{
sie_cmd_code(SIE_CMDPHASE_COMMAND, cmd_code);
if (data_len)
{
sie_cmd_code(SIE_CMDPHASE_WRITE, data);
}
}
static inline uint32_t sie_read (uint8_t cmd_code, uint8_t data_len) ATTR_ALWAYS_INLINE;
static inline uint32_t sie_read (uint8_t cmd_code, uint8_t data_len)
{
// TODO multiple read
sie_cmd_code(SIE_CMDPHASE_COMMAND , cmd_code);
sie_cmd_code(SIE_CMDPHASE_READ , cmd_code);
return LPC_USB->USBCmdData;
}
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif /* _TUSB_DCD_LPC175X_6X_H_ */ #endif /* _TUSB_DCD_LPC175X_6X_H_ */
/** @} */

View File

@ -37,9 +37,11 @@
/**************************************************************************/ /**************************************************************************/
#include "common/tusb_common.h" #include "common/tusb_common.h"
#if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X
#include "hal_usb.h"
#if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X
#include "LPC17xx.h"
#include "lpc17xx_pinsel.h"
void tusb_hal_int_enable(uint8_t rhport) void tusb_hal_int_enable(uint8_t rhport)
{ {
@ -102,6 +104,8 @@ bool tusb_hal_init(void)
void USB_IRQHandler(void) void USB_IRQHandler(void)
{ {
extern void hal_dcd_isr(uint8_t rhport);
#if MODE_HOST_SUPPORTED #if MODE_HOST_SUPPORTED
hal_hcd_isr(0); hal_hcd_isr(0);
#endif #endif

View File

@ -288,7 +288,7 @@ bool dcd_edpt_busy(uint8_t rhport, uint8_t ep_addr)
// return !p_qhd->qtd_overlay.halted && p_qhd->qtd_overlay.active; // return !p_qhd->qtd_overlay.halted && p_qhd->qtd_overlay.active;
} }
bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes)
{ {
uint8_t const epnum = edpt_number(ep_addr); uint8_t const epnum = edpt_number(ep_addr);
uint8_t const dir = edpt_dir(ep_addr); uint8_t const dir = edpt_dir(ep_addr);
@ -301,9 +301,8 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t
while(LPC_USB[rhport]->ENDPTSETUPSTAT & BIT_(0)) {} while(LPC_USB[rhport]->ENDPTSETUPSTAT & BIT_(0)) {}
} }
dcd_data_t* p_dcd = dcd_data_ptr[rhport]; dcd_qhd_t * p_qhd = &dcd_data_ptr[rhport]->qhd[ep_idx];
dcd_qhd_t * p_qhd = &p_dcd->qhd[ep_idx]; dcd_qtd_t * p_qtd = &dcd_data_ptr[rhport]->qtd[ep_idx];
dcd_qtd_t * p_qtd = &p_dcd->qtd[ep_idx];
//------------- Prepare qtd -------------// //------------- Prepare qtd -------------//
qtd_init(p_qtd, buffer, total_bytes); qtd_init(p_qtd, buffer, total_bytes);
@ -393,7 +392,7 @@ void hal_dcd_isr(uint8_t rhport)
uint8_t result = p_qtd->halted ? XFER_RESULT_STALLED : uint8_t result = p_qtd->halted ? XFER_RESULT_STALLED :
( p_qtd->xact_err ||p_qtd->buffer_err ) ? XFER_RESULT_FAILED : XFER_RESULT_SUCCESS; ( p_qtd->xact_err ||p_qtd->buffer_err ) ? XFER_RESULT_FAILED : XFER_RESULT_SUCCESS;
uint8_t ep_addr = (ep_idx/2) | ( (ep_idx & 0x01) ? TUSB_DIR_IN_MASK : 0 ); uint8_t const ep_addr = (ep_idx/2) | ( (ep_idx & 0x01) ? TUSB_DIR_IN_MASK : 0 );
dcd_event_xfer_complete(rhport, ep_addr, p_qtd->expected_bytes - p_qtd->total_bytes, result, true); // only number of bytes in the IOC qtd dcd_event_xfer_complete(rhport, ep_addr, p_qtd->expected_bytes - p_qtd->total_bytes, result, true); // only number of bytes in the IOC qtd
} }
} }

View File

@ -83,13 +83,16 @@
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// CONTROLLER // CONTROLLER
// Only 1 roothub port can be configured to be device and/or host.
// tinyusb does not support dual devices or dual host configuration
//-------------------------------------------------------------------- //--------------------------------------------------------------------
/** \defgroup group_mode Controller Mode Selection /** \defgroup group_mode Controller Mode Selection
* \brief CFG_TUSB_CONTROLLER_N_MODE must be defined with these * \brief CFG_TUSB_CONTROLLER_N_MODE must be defined with these
* @{ */ * @{ */
#define OPT_MODE_HOST 0x02 ///< Host Mode #define OPT_MODE_NONE 0x00 ///< Disabled
#define OPT_MODE_DEVICE 0x01 ///< Device Mode #define OPT_MODE_DEVICE 0x01 ///< Device Mode
#define OPT_MODE_NONE 0x00 ///< Disabled #define OPT_MODE_HOST 0x02 ///< Host Mode
#define OPT_MODE_HIGH_SPEED 0x10 ///< Highspeed
/** @} */ /** @} */
#ifndef CFG_TUSB_RHPORT0_MODE #ifndef CFG_TUSB_RHPORT0_MODE
@ -100,21 +103,34 @@
#define CFG_TUSB_RHPORT1_MODE OPT_MODE_NONE #define CFG_TUSB_RHPORT1_MODE OPT_MODE_NONE
#endif #endif
#if ((CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST) && (CFG_TUSB_RHPORT1_MODE & OPT_MODE_HOST)) || \
((CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE) && (CFG_TUSB_RHPORT1_MODE & OPT_MODE_DEVICE))
#error "tinyusb does not support same modes on more than 1 roothub port"
#endif
// TODO remove
#define CONTROLLER_HOST_NUMBER (\ #define CONTROLLER_HOST_NUMBER (\
((CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST) ? 1 : 0) + \ ((CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST) ? 1 : 0) + \
((CFG_TUSB_RHPORT1_MODE & OPT_MODE_HOST) ? 1 : 0)) ((CFG_TUSB_RHPORT1_MODE & OPT_MODE_HOST) ? 1 : 0))
#define MODE_HOST_SUPPORTED (CONTROLLER_HOST_NUMBER > 0) #define MODE_HOST_SUPPORTED (CONTROLLER_HOST_NUMBER > 0)
// Which roothub port is configured as host
#define TUH_OPT_RHPORT ( (CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST) ? 0 : ((CFG_TUSB_RHPORT1_MODE & OPT_MODE_HOST) ? 1 : -1) ) #define TUH_OPT_RHPORT ( (CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST) ? 0 : ((CFG_TUSB_RHPORT1_MODE & OPT_MODE_HOST) ? 1 : -1) )
#define TUSB_OPT_HOST_ENABLED ( TUH_OPT_RHPORT >= 0 ) #define TUSB_OPT_HOST_ENABLED ( TUH_OPT_RHPORT >= 0 )
// Which roothub port is configured as device
#define TUD_OPT_RHPORT ( (CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE) ? 0 : ((CFG_TUSB_RHPORT1_MODE & OPT_MODE_DEVICE) ? 1 : -1) ) #define TUD_OPT_RHPORT ( (CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE) ? 0 : ((CFG_TUSB_RHPORT1_MODE & OPT_MODE_DEVICE) ? 1 : -1) )
#if TUD_OPT_RHPORT == 0
#define TUD_OPT_HIGH_SPEED ( CFG_TUSB_RHPORT0_MODE & OPT_MODE_HIGH_SPEED )
#else
#define TUD_OPT_HIGH_SPEED ( CFG_TUSB_RHPORT1_MODE & OPT_MODE_HIGH_SPEED )
#endif
#define TUSB_OPT_DEVICE_ENABLED ( TUD_OPT_RHPORT >= 0 ) #define TUSB_OPT_DEVICE_ENABLED ( TUD_OPT_RHPORT >= 0 )
#if ((CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST) && (CFG_TUSB_RHPORT1_MODE & OPT_MODE_HOST)) || ((CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE) && (CFG_TUSB_RHPORT1_MODE & OPT_MODE_DEVICE))
#error "tinyusb does not support same modes on more than 1 roothub port"
#endif
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// COMMON OPTIONS // COMMON OPTIONS