delete non-supported platforms

This commit is contained in:
Conor Patrick 2019-02-12 17:18:44 -05:00
parent ed676151f1
commit 45eaef2663
94 changed files with 0 additions and 57864 deletions

File diff suppressed because one or more lines are too long

View File

@ -1,49 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>EFM32</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<triggers>clean,full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>com.silabs.ss.framework.ide.project.sls.core.SLSProjectNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
</natures>
<linkedResources>
<link>
<name>crypto</name>
<type>2</type>
<locationURI>$%7BPARENT-2-PROJECT_LOC%7D/crypto</locationURI>
</link>
<link>
<name>fido2</name>
<type>2</type>
<locationURI>$%7BPARENT-2-PROJECT_LOC%7D/fido2</locationURI>
</link>
<link>
<name>CMSIS/EFM32JG1B/startup_gcc_efm32jg1b.s</name>
<type>1</type>
<locationURI>STUDIO_SDK_LOC/platform/Device/SiliconLabs/EFM32JG1B/Source/GCC/startup_efm32jg1b.S</locationURI>
</link>
<link>
<name>CMSIS/EFM32JG1B/system_efm32jg1b.c</name>
<type>1</type>
<locationURI>STUDIO_SDK_LOC/platform/Device/SiliconLabs/EFM32JG1B/Source/system_efm32jg1b.c</locationURI>
</link>
</linkedResources>
</projectDescription>

View File

@ -1,2 +0,0 @@
copiedFilesOriginState={}
eclipse.preferences.version=1

View File

@ -1,70 +0,0 @@
eclipse.preferences.version=1
org.eclipse.cdt.codan.checkers.errnoreturn=Warning
org.eclipse.cdt.codan.checkers.errnoreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},implicit\=>false}
org.eclipse.cdt.codan.checkers.errreturnvalue=Error
org.eclipse.cdt.codan.checkers.errreturnvalue.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.checkers.nocommentinside=-Error
org.eclipse.cdt.codan.checkers.nocommentinside.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.checkers.nolinecomment=-Error
org.eclipse.cdt.codan.checkers.nolinecomment.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.checkers.noreturn=Error
org.eclipse.cdt.codan.checkers.noreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},implicit\=>false}
org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation=Error
org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem=Error
org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem=Warning
org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem=Warning
org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},no_break_comment\=>"no break",last_case_param\=>false,empty_case_param\=>false}
org.eclipse.cdt.codan.internal.checkers.CatchByReference=Warning
org.eclipse.cdt.codan.internal.checkers.CatchByReference.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},unknown\=>false,exceptions\=>()}
org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem=Error
org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization=Warning
org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},skip\=>true}
org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem=Error
org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem=Error
org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.InvalidArguments=Error
org.eclipse.cdt.codan.internal.checkers.InvalidArguments.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem=Error
org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem=Error
org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem=Error
org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem=Error
org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker=-Info
org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},pattern\=>"^[a-z]",macro\=>true,exceptions\=>()}
org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem=Warning
org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.OverloadProblem=Error
org.eclipse.cdt.codan.internal.checkers.OverloadProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem=Error
org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem=Error
org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem=-Warning
org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem=-Warning
org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem=Warning
org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true,exceptions\=>()}
org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem=Warning
org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},paramNot\=>false}
org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem=Warning
org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},else\=>false,afterelse\=>false}
org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem=Error
org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem=Warning
org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true}
org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem=Warning
org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true}
org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem=Warning
org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true,exceptions\=>("@(\#)","$Id")}
org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem=Error
org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}

View File

@ -1,317 +0,0 @@
/* @file startup_efm32pg1b.S
* @brief startup file for Silicon Labs EFM32PG1B devices.
* For use with GCC for ARM Embedded Processors
* @version 5.2.2
* Date: 12 June 2014
*
*/
/* Copyright (c) 2011 - 2014 ARM LIMITED
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.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of ARM 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 COPYRIGHT HOLDERS AND CONTRIBUTORS 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.
---------------------------------------------------------------------------*/
.syntax unified
.arch armv7-m
.section .stack
.align 3
#ifdef __STACK_SIZE
.equ Stack_Size, __STACK_SIZE
#else
.equ Stack_Size, 0x00000400
#endif
.globl __StackTop
.globl __StackLimit
__StackLimit:
.space Stack_Size
.size __StackLimit, . - __StackLimit
__StackTop:
.size __StackTop, . - __StackTop
.section .heap
.align 3
#ifdef __HEAP_SIZE
.equ Heap_Size, __HEAP_SIZE
#else
.equ Heap_Size, 0x00000C00
#endif
.globl __HeapBase
.globl __HeapLimit
__HeapBase:
.if Heap_Size
.space Heap_Size
.endif
.size __HeapBase, . - __HeapBase
__HeapLimit:
.size __HeapLimit, . - __HeapLimit
.section .vectors
.align 2
.globl __Vectors
__Vectors:
.long __StackTop /* Top of Stack */
.long Reset_Handler /* Reset Handler */
.long NMI_Handler /* NMI Handler */
.long HardFault_Handler /* Hard Fault Handler */
.long MemManage_Handler /* MPU Fault Handler */
.long BusFault_Handler /* Bus Fault Handler */
.long UsageFault_Handler /* Usage Fault Handler */
.long Default_Handler /* Reserved */
.long Default_Handler /* Reserved */
.long Default_Handler /* Reserved */
.long Default_Handler /* Reserved */
.long SVC_Handler /* SVCall Handler */
.long DebugMon_Handler /* Debug Monitor Handler */
.long Default_Handler /* Reserved */
.long PendSV_Handler /* PendSV Handler */
.long SysTick_Handler /* SysTick Handler */
/* External interrupts */
.long EMU_IRQHandler /* 0 - EMU */
.long Default_Handler /* 1 - Reserved */
.long WDOG0_IRQHandler /* 2 - WDOG0 */
.long Default_Handler /* 3 - Reserved */
.long Default_Handler /* 4 - Reserved */
.long Default_Handler /* 5 - Reserved */
.long Default_Handler /* 6 - Reserved */
.long Default_Handler /* 7 - Reserved */
.long LDMA_IRQHandler /* 8 - LDMA */
.long GPIO_EVEN_IRQHandler /* 9 - GPIO_EVEN */
.long TIMER0_IRQHandler /* 10 - TIMER0 */
.long USART0_RX_IRQHandler /* 11 - USART0_RX */
.long USART0_TX_IRQHandler /* 12 - USART0_TX */
.long ACMP0_IRQHandler /* 13 - ACMP0 */
.long ADC0_IRQHandler /* 14 - ADC0 */
.long IDAC0_IRQHandler /* 15 - IDAC0 */
.long I2C0_IRQHandler /* 16 - I2C0 */
.long GPIO_ODD_IRQHandler /* 17 - GPIO_ODD */
.long TIMER1_IRQHandler /* 18 - TIMER1 */
.long USART1_RX_IRQHandler /* 19 - USART1_RX */
.long USART1_TX_IRQHandler /* 20 - USART1_TX */
.long LEUART0_IRQHandler /* 21 - LEUART0 */
.long PCNT0_IRQHandler /* 22 - PCNT0 */
.long CMU_IRQHandler /* 23 - CMU */
.long MSC_IRQHandler /* 24 - MSC */
.long CRYPTO_IRQHandler /* 25 - CRYPTO */
.long LETIMER0_IRQHandler /* 26 - LETIMER0 */
.long Default_Handler /* 27 - Reserved */
.long Default_Handler /* 28 - Reserved */
.long RTCC_IRQHandler /* 29 - RTCC */
.long Default_Handler /* 30 - Reserved */
.long CRYOTIMER_IRQHandler /* 31 - CRYOTIMER */
.long Default_Handler /* 32 - Reserved */
.long FPUEH_IRQHandler /* 33 - FPUEH */
.size __Vectors, . - __Vectors
.text
.thumb
.thumb_func
.align 2
.globl Reset_Handler
.type Reset_Handler, %function
Reset_Handler:
#ifndef __NO_SYSTEM_INIT
ldr r0, =SystemInit
blx r0
#endif
/* Firstly it copies data from read only memory to RAM. There are two schemes
* to copy. One can copy more than one sections. Another can only copy
* one section. The former scheme needs more instructions and read-only
* data to implement than the latter.
* Macro __STARTUP_COPY_MULTIPLE is used to choose between two schemes. */
#ifdef __STARTUP_COPY_MULTIPLE
/* Multiple sections scheme.
*
* Between symbol address __copy_table_start__ and __copy_table_end__,
* there are array of triplets, each of which specify:
* offset 0: LMA of start of a section to copy from
* offset 4: VMA of start of a section to copy to
* offset 8: size of the section to copy. Must be multiply of 4
*
* All addresses must be aligned to 4 bytes boundary.
*/
ldr r4, =__copy_table_start__
ldr r5, =__copy_table_end__
.L_loop0:
cmp r4, r5
bge .L_loop0_done
ldr r1, [r4]
ldr r2, [r4, #4]
ldr r3, [r4, #8]
.L_loop0_0:
subs r3, #4
ittt ge
ldrge r0, [r1, r3]
strge r0, [r2, r3]
bge .L_loop0_0
adds r4, #12
b .L_loop0
.L_loop0_done:
#else
/* Single section scheme.
*
* The ranges of copy from/to are specified by following symbols
* __etext: LMA of start of the section to copy from. Usually end of text
* __data_start__: VMA of start of the section to copy to
* __data_end__: VMA of end of the section to copy to
*
* All addresses must be aligned to 4 bytes boundary.
*/
ldr r1, =__etext
ldr r2, =__data_start__
ldr r3, =__data_end__
.L_loop1:
cmp r2, r3
ittt lt
ldrlt r0, [r1], #4
strlt r0, [r2], #4
blt .L_loop1
#endif /*__STARTUP_COPY_MULTIPLE */
/* This part of work usually is done in C library startup code. Otherwise,
* define this macro to enable it in this startup.
*
* There are two schemes too. One can clear multiple BSS sections. Another
* can only clear one section. The former is more size expensive than the
* latter.
*
* Define macro __STARTUP_CLEAR_BSS_MULTIPLE to choose the former.
* Otherwise efine macro __STARTUP_CLEAR_BSS to choose the later.
*/
#ifdef __STARTUP_CLEAR_BSS_MULTIPLE
/* Multiple sections scheme.
*
* Between symbol address __zero_table_start__ and __zero_table_end__,
* there are array of tuples specifying:
* offset 0: Start of a BSS section
* offset 4: Size of this BSS section. Must be multiply of 4
*/
ldr r3, =__zero_table_start__
ldr r4, =__zero_table_end__
.L_loop2:
cmp r3, r4
bge .L_loop2_done
ldr r1, [r3]
ldr r2, [r3, #4]
movs r0, 0
.L_loop2_0:
subs r2, #4
itt ge
strge r0, [r1, r2]
bge .L_loop2_0
adds r3, #8
b .L_loop2
.L_loop2_done:
#elif defined (__STARTUP_CLEAR_BSS)
/* Single BSS section scheme.
*
* The BSS section is specified by following symbols
* __bss_start__: start of the BSS section.
* __bss_end__: end of the BSS section.
*
* Both addresses must be aligned to 4 bytes boundary.
*/
ldr r1, =__bss_start__
ldr r2, =__bss_end__
movs r0, 0
.L_loop3:
cmp r1, r2
itt lt
strlt r0, [r1], #4
blt .L_loop3
#endif /* __STARTUP_CLEAR_BSS_MULTIPLE || __STARTUP_CLEAR_BSS */
#ifndef __START
#define __START _start
#endif
bl __START
.pool
.size Reset_Handler, . - Reset_Handler
.align 1
.thumb_func
.weak Default_Handler
.type Default_Handler, %function
Default_Handler:
b .
.size Default_Handler, . - Default_Handler
/* Macro to define default handlers. Default handler
* will be weak symbol and just dead loops. They can be
* overwritten by other handlers */
.macro def_irq_handler handler_name
.weak \handler_name
.set \handler_name, Default_Handler
.endm
def_irq_handler NMI_Handler
def_irq_handler HardFault_Handler
def_irq_handler MemManage_Handler
def_irq_handler BusFault_Handler
def_irq_handler UsageFault_Handler
def_irq_handler SVC_Handler
def_irq_handler DebugMon_Handler
def_irq_handler PendSV_Handler
def_irq_handler SysTick_Handler
def_irq_handler EMU_IRQHandler
def_irq_handler WDOG0_IRQHandler
def_irq_handler LDMA_IRQHandler
def_irq_handler GPIO_EVEN_IRQHandler
def_irq_handler TIMER0_IRQHandler
def_irq_handler USART0_RX_IRQHandler
def_irq_handler USART0_TX_IRQHandler
def_irq_handler ACMP0_IRQHandler
def_irq_handler ADC0_IRQHandler
def_irq_handler IDAC0_IRQHandler
def_irq_handler I2C0_IRQHandler
def_irq_handler GPIO_ODD_IRQHandler
def_irq_handler TIMER1_IRQHandler
def_irq_handler USART1_RX_IRQHandler
def_irq_handler USART1_TX_IRQHandler
def_irq_handler LEUART0_IRQHandler
def_irq_handler PCNT0_IRQHandler
def_irq_handler CMU_IRQHandler
def_irq_handler MSC_IRQHandler
def_irq_handler CRYPTO_IRQHandler
def_irq_handler LETIMER0_IRQHandler
def_irq_handler RTCC_IRQHandler
def_irq_handler CRYOTIMER_IRQHandler
def_irq_handler FPUEH_IRQHandler
.end

View File

@ -1,389 +0,0 @@
/***************************************************************************//**
* @file system_efm32pg1b.c
* @brief CMSIS Cortex-M3/M4 System Layer for EFM32 devices.
* @version 5.2.2
******************************************************************************
* # License
* <b>Copyright 2017 Silicon Laboratories, Inc. http://www.silabs.com</b>
******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.@n
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.@n
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Laboratories, Inc.
* has no obligation to support this Software. Silicon Laboratories, Inc. is
* providing the Software "AS IS", with no express or implied warranties of any
* kind, including, but not limited to, any implied warranties of
* merchantability or fitness for any particular purpose or warranties against
* infringement of any proprietary rights of a third party.
*
* Silicon Laboratories, Inc. will not be liable for any consequential,
* incidental, or special damages, or any other relief, or for any claim by
* any third party, arising from your use of this Software.
*
*****************************************************************************/
#include <stdint.h>
#include "em_device.h"
/*******************************************************************************
****************************** DEFINES ************************************
******************************************************************************/
/** LFRCO frequency, tuned to below frequency during manufacturing. */
#define EFM32_LFRCO_FREQ (32768UL)
/** ULFRCO frequency */
#define EFM32_ULFRCO_FREQ (1000UL)
/*******************************************************************************
************************** LOCAL VARIABLES ********************************
******************************************************************************/
/* System oscillator frequencies. These frequencies are normally constant */
/* for a target, but they are made configurable in order to allow run-time */
/* handling of different boards. The crystal oscillator clocks can be set */
/* compile time to a non-default value by defining respective EFM_nFXO_FREQ */
/* values according to board design. By defining the EFM_nFXO_FREQ to 0, */
/* one indicates that the oscillator is not present, in order to save some */
/* SW footprint. */
#ifndef EFM32_HFRCO_MAX_FREQ
/** Maximum HFRCO frequency */
#define EFM32_HFRCO_MAX_FREQ (38000000UL)
#endif
#ifndef EFM32_HFXO_FREQ
/** HFXO frequency */
#define EFM32_HFXO_FREQ (40000000UL)
#endif
#ifndef EFM32_HFRCO_STARTUP_FREQ
/** HFRCO startup frequency */
#define EFM32_HFRCO_STARTUP_FREQ (19000000UL)
#endif
/* Do not define variable if HF crystal oscillator not present */
#if (EFM32_HFXO_FREQ > 0UL)
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/** System HFXO clock. */
static uint32_t SystemHFXOClock = EFM32_HFXO_FREQ;
/** @endcond (DO_NOT_INCLUDE_WITH_DOXYGEN) */
#endif
#ifndef EFM32_LFXO_FREQ
/** LFXO frequency */
#define EFM32_LFXO_FREQ (EFM32_LFRCO_FREQ)
#endif
/* Do not define variable if LF crystal oscillator not present */
#if (EFM32_LFXO_FREQ > 0UL)
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/** System LFXO clock. */
static uint32_t SystemLFXOClock = 32768UL;
/** @endcond (DO_NOT_INCLUDE_WITH_DOXYGEN) */
#endif
/*******************************************************************************
************************** GLOBAL VARIABLES *******************************
******************************************************************************/
/**
* @brief
* System System Clock Frequency (Core Clock).
*
* @details
* Required CMSIS global variable that must be kept up-to-date.
*/
uint32_t SystemCoreClock = EFM32_HFRCO_STARTUP_FREQ;
/**
* @brief
* System HFRCO frequency
*
* @note
* This is an EFM32 proprietary variable, not part of the CMSIS definition.
*
* @details
* Frequency of the system HFRCO oscillator
*/
uint32_t SystemHfrcoFreq = EFM32_HFRCO_STARTUP_FREQ;
/*******************************************************************************
************************** GLOBAL FUNCTIONS *******************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Get the current core clock frequency.
*
* @details
* Calculate and get the current core clock frequency based on the current
* configuration. Assuming that the SystemCoreClock global variable is
* maintained, the core clock frequency is stored in that variable as well.
* This function will however calculate the core clock based on actual HW
* configuration. It will also update the SystemCoreClock global variable.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @return
* The current core clock frequency in Hz.
******************************************************************************/
uint32_t SystemCoreClockGet(void)
{
uint32_t ret;
uint32_t presc;
ret = SystemHFClockGet();
presc = (CMU->HFCOREPRESC & _CMU_HFCOREPRESC_PRESC_MASK) >>
_CMU_HFCOREPRESC_PRESC_SHIFT;
ret /= (presc + 1);
/* Keep CMSIS system clock variable up-to-date */
SystemCoreClock = ret;
return ret;
}
/***************************************************************************//**
* @brief
* Get the maximum core clock frequency.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @return
* The maximum core clock frequency in Hz.
******************************************************************************/
uint32_t SystemMaxCoreClockGet(void)
{
return (EFM32_HFRCO_MAX_FREQ > EFM32_HFXO_FREQ ? \
EFM32_HFRCO_MAX_FREQ : EFM32_HFXO_FREQ);
}
/***************************************************************************//**
* @brief
* Get the current HFCLK frequency.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @return
* The current HFCLK frequency in Hz.
******************************************************************************/
uint32_t SystemHFClockGet(void)
{
uint32_t ret;
switch (CMU->HFCLKSTATUS & _CMU_HFCLKSTATUS_SELECTED_MASK)
{
case CMU_HFCLKSTATUS_SELECTED_LFXO:
#if (EFM32_LFXO_FREQ > 0)
ret = SystemLFXOClock;
#else
/* We should not get here, since core should not be clocked. May */
/* be caused by a misconfiguration though. */
ret = 0;
#endif
break;
case CMU_HFCLKSTATUS_SELECTED_LFRCO:
ret = EFM32_LFRCO_FREQ;
break;
case CMU_HFCLKSTATUS_SELECTED_HFXO:
#if (EFM32_HFXO_FREQ > 0)
ret = SystemHFXOClock;
#else
/* We should not get here, since core should not be clocked. May */
/* be caused by a misconfiguration though. */
ret = 0;
#endif
break;
default: /* CMU_HFCLKSTATUS_SELECTED_HFRCO */
ret = SystemHfrcoFreq;
break;
}
return ret / (1U + ((CMU->HFPRESC & _CMU_HFPRESC_PRESC_MASK)
>> _CMU_HFPRESC_PRESC_SHIFT));
}
/**************************************************************************//**
* @brief
* Get high frequency crystal oscillator clock frequency for target system.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @return
* HFXO frequency in Hz.
*****************************************************************************/
uint32_t SystemHFXOClockGet(void)
{
/* External crystal oscillator present? */
#if (EFM32_HFXO_FREQ > 0)
return SystemHFXOClock;
#else
return 0;
#endif
}
/**************************************************************************//**
* @brief
* Set high frequency crystal oscillator clock frequency for target system.
*
* @note
* This function is mainly provided for being able to handle target systems
* with different HF crystal oscillator frequencies run-time. If used, it
* should probably only be used once during system startup.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @param[in] freq
* HFXO frequency in Hz used for target.
*****************************************************************************/
void SystemHFXOClockSet(uint32_t freq)
{
/* External crystal oscillator present? */
#if (EFM32_HFXO_FREQ > 0)
SystemHFXOClock = freq;
/* Update core clock frequency if HFXO is used to clock core */
if ((CMU->HFCLKSTATUS & _CMU_HFCLKSTATUS_SELECTED_MASK) == CMU_HFCLKSTATUS_SELECTED_HFXO)
{
/* The function will update the global variable */
SystemCoreClockGet();
}
#else
(void)freq; /* Unused parameter */
#endif
}
/**************************************************************************//**
* @brief
* Initialize the system.
*
* @details
* Do required generic HW system init.
*
* @note
* This function is invoked during system init, before the main() routine
* and any data has been initialized. For this reason, it cannot do any
* initialization of variables etc.
*****************************************************************************/
void SystemInit(void)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
/* Set floating point coprosessor access mode. */
SCB->CPACR |= ((3UL << 10*2) | /* set CP10 Full Access */
(3UL << 11*2) ); /* set CP11 Full Access */
#endif
}
/**************************************************************************//**
* @brief
* Get low frequency RC oscillator clock frequency for target system.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @return
* LFRCO frequency in Hz.
*****************************************************************************/
uint32_t SystemLFRCOClockGet(void)
{
/* Currently we assume that this frequency is properly tuned during */
/* manufacturing and is not changed after reset. If future requirements */
/* for re-tuning by user, we can add support for that. */
return EFM32_LFRCO_FREQ;
}
/**************************************************************************//**
* @brief
* Get ultra low frequency RC oscillator clock frequency for target system.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @return
* ULFRCO frequency in Hz.
*****************************************************************************/
uint32_t SystemULFRCOClockGet(void)
{
/* The ULFRCO frequency is not tuned, and can be very inaccurate */
return EFM32_ULFRCO_FREQ;
}
/**************************************************************************//**
* @brief
* Get low frequency crystal oscillator clock frequency for target system.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @return
* LFXO frequency in Hz.
*****************************************************************************/
uint32_t SystemLFXOClockGet(void)
{
/* External crystal oscillator present? */
#if (EFM32_LFXO_FREQ > 0)
return SystemLFXOClock;
#else
return 0;
#endif
}
/**************************************************************************//**
* @brief
* Set low frequency crystal oscillator clock frequency for target system.
*
* @note
* This function is mainly provided for being able to handle target systems
* with different HF crystal oscillator frequencies run-time. If used, it
* should probably only be used once during system startup.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @param[in] freq
* LFXO frequency in Hz used for target.
*****************************************************************************/
void SystemLFXOClockSet(uint32_t freq)
{
/* External crystal oscillator present? */
#if (EFM32_LFXO_FREQ > 0)
SystemLFXOClock = freq;
/* Update core clock frequency if LFXO is used to clock core */
if ((CMU->HFCLKSTATUS & _CMU_HFCLKSTATUS_SELECTED_MASK) == CMU_HFCLKSTATUS_SELECTED_LFXO)
{
/* The function will update the global variable */
SystemCoreClockGet();
}
#else
(void)freq; /* Unused parameter */
#endif
}

View File

@ -1,116 +0,0 @@
<?xml version="1.0" encoding="ASCII"?>
<device:XMLDevice xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:device="http://www.silabs.com/ss/hwconfig/document/device.ecore" name="EFM32PG1B200F256GM48" partId="mcu.arm.efm32.pg1.efm32pg1b200f256gm48" contextId="%DEFAULT%">
<mode name="DefaultMode">
<property object="ADC0" propertyId="ABPeripheral.included" value="true"/>
<property object="CMU" propertyId="ABPeripheral.included" value="true"/>
<property object="CMU" propertyId="clocksettings.hfrcosettings.hfrcofrequency" value="38 MHz"/>
<property object="CMU" propertyId="clocksettings.lfclocksettings.ulfrcorequired" value="Yes"/>
<property object="CRYOTIMER" propertyId="ABPeripheral.included" value="true"/>
<property object="CRYOTIMER" propertyId="cryotimer.clocking.clocksourceforcryotimer" value="ULFRCO"/>
<property object="CRYOTIMER" propertyId="cryotimer.clocking.eventafterevery" value="1 cycle"/>
<property object="CRYPTO" propertyId="ABPeripheral.included" value="true"/>
<property object="DefaultMode" propertyId="mode.diagramLocation" value="100, 100"/>
<property object="EMU" propertyId="ABPeripheral.included" value="true"/>
<property object="GPIO" propertyId="ABPeripheral.included" value="true"/>
<property object="PA0" propertyId="ports.settings.pinmode" value="Push-pull"/>
<property object="PA1" propertyId="ports.settings.dout" value="1"/>
<property object="PA1" propertyId="ports.settings.filter" value="Enabled"/>
<property object="PA1" propertyId="ports.settings.pinmode" value="Input pull"/>
<property object="PA1" propertyId="ports.settings.pulldirection" value="Pullup"/>
<property object="PA1" propertyId="ports.settings.pullup" value="Enabled"/>
<property object="PA3" propertyId="ports.settings.pinmode" value="Push-pull"/>
<property object="PA4" propertyId="ports.settings.dout" value="1"/>
<property object="PA4" propertyId="ports.settings.filter" value="Enabled"/>
<property object="PA4" propertyId="ports.settings.pinmode" value="Wired-and pullup filter"/>
<property object="PA4" propertyId="ports.settings.pulldirection" value="Pullup"/>
<property object="PA4" propertyId="ports.settings.pullup" value="Enabled"/>
<property object="PA5" propertyId="ports.settings.dout" value="1"/>
<property object="PA5" propertyId="ports.settings.filter" value="Enabled"/>
<property object="PA5" propertyId="ports.settings.pinmode" value="Push-pull"/>
<property object="PA5" propertyId="ports.settings.pulldirection" value="Pullup"/>
<property object="PA5" propertyId="ports.settings.pullup" value="Enabled"/>
<property object="PB13" propertyId="ports.settings.dout" value="1"/>
<property object="PB13" propertyId="ports.settings.filter" value="Enabled"/>
<property object="PB13" propertyId="ports.settings.pinmode" value="Push-pull"/>
<property object="PB13" propertyId="ports.settings.pulldirection" value="Pullup"/>
<property object="PB13" propertyId="ports.settings.pullup" value="Enabled"/>
<property object="PC10" propertyId="ports.settings.dout" value="1"/>
<property object="PC10" propertyId="ports.settings.filter" value="Enabled"/>
<property object="PC10" propertyId="ports.settings.pinmode" value="Push-pull"/>
<property object="PC10" propertyId="ports.settings.pulldirection" value="Pullup"/>
<property object="PC10" propertyId="ports.settings.pullup" value="Enabled"/>
<property object="PC6" propertyId="ports.settings.dout" value="1"/>
<property object="PC6" propertyId="ports.settings.filter" value="Enabled"/>
<property object="PC6" propertyId="ports.settings.pinmode" value="Push-pull"/>
<property object="PC6" propertyId="ports.settings.pulldirection" value="Pullup"/>
<property object="PC6" propertyId="ports.settings.pullup" value="Enabled"/>
<property object="PC7" propertyId="ports.settings.dout" value="1"/>
<property object="PC7" propertyId="ports.settings.filter" value="Enabled"/>
<property object="PC7" propertyId="ports.settings.pinmode" value="Input pull"/>
<property object="PC7" propertyId="ports.settings.pulldirection" value="Pullup"/>
<property object="PC7" propertyId="ports.settings.pullup" value="Enabled"/>
<property object="PC8" propertyId="ports.settings.dout" value="1"/>
<property object="PC8" propertyId="ports.settings.filter" value="Enabled"/>
<property object="PC8" propertyId="ports.settings.pinmode" value="Push-pull"/>
<property object="PC8" propertyId="ports.settings.pulldirection" value="Pullup"/>
<property object="PC8" propertyId="ports.settings.pullup" value="Enabled"/>
<property object="PC9" propertyId="ports.settings.dout" value="1"/>
<property object="PC9" propertyId="ports.settings.filter" value="Enabled"/>
<property object="PC9" propertyId="ports.settings.pinmode" value="Input pull"/>
<property object="PC9" propertyId="ports.settings.pulldirection" value="Pullup"/>
<property object="PC9" propertyId="ports.settings.pullup" value="Enabled"/>
<property object="PD10" propertyId="ports.settings.dout" value="1"/>
<property object="PD10" propertyId="ports.settings.filter" value="Enabled"/>
<property object="PD10" propertyId="ports.settings.pinmode" value="Push-pull"/>
<property object="PD10" propertyId="ports.settings.pulldirection" value="Pullup"/>
<property object="PD10" propertyId="ports.settings.pullup" value="Enabled"/>
<property object="PD15" propertyId="ports.settings.dout" value="1"/>
<property object="PD15" propertyId="ports.settings.filter" value="Enabled"/>
<property object="PD15" propertyId="ports.settings.pinmode" value="Push-pull"/>
<property object="PD15" propertyId="ports.settings.pulldirection" value="Pullup"/>
<property object="PD15" propertyId="ports.settings.pullup" value="Enabled"/>
<property object="PF2" propertyId="ports.settings.dout" value="1"/>
<property object="PF2" propertyId="ports.settings.filter" value="Enabled"/>
<property object="PF2" propertyId="ports.settings.pinmode" value="Push-pull"/>
<property object="PF2" propertyId="ports.settings.pulldirection" value="Pullup"/>
<property object="PF2" propertyId="ports.settings.pullup" value="Enabled"/>
<property object="PF3" propertyId="ports.settings.dout" value="1"/>
<property object="PF3" propertyId="ports.settings.filter" value="Enabled"/>
<property object="PF3" propertyId="ports.settings.pinmode" value="Wired-and pullup filter"/>
<property object="PF3" propertyId="ports.settings.pulldirection" value="Pullup"/>
<property object="PF3" propertyId="ports.settings.pullup" value="Enabled"/>
<property object="PF4" propertyId="ports.settings.pinmode" value="Push-pull"/>
<property object="PF5" propertyId="ports.settings.pinmode" value="Push-pull"/>
<property object="PF6" propertyId="ports.settings.dout" value="1"/>
<property object="PF6" propertyId="ports.settings.filter" value="Enabled"/>
<property object="PF6" propertyId="ports.settings.pinmode" value="Input pull"/>
<property object="PF6" propertyId="ports.settings.pulldirection" value="Pullup"/>
<property object="PF6" propertyId="ports.settings.pullup" value="Enabled"/>
<property object="PORTIO" propertyId="portio.i2c0.location.i2c0_sclloc" value="3"/>
<property object="PORTIO" propertyId="portio.i2c0.location.i2c0_sdaloc" value="27"/>
<property object="PORTIO" propertyId="portio.usart0.enable.cts" value="Enabled"/>
<property object="PORTIO" propertyId="portio.usart0.enable.rts" value="Enabled"/>
<property object="PORTIO" propertyId="portio.usart0.enable.rx" value="Enabled"/>
<property object="PORTIO" propertyId="portio.usart0.enable.tx" value="Enabled"/>
<property object="PORTIO" propertyId="portio.usart0.location.usart0_ctsloc" value="30"/>
<property object="PORTIO" propertyId="portio.usart0.location.usart0_rtsloc" value="30"/>
<property object="PORTIO" propertyId="portio.usart1.enable.clk" value="Enabled"/>
<property object="PORTIO" propertyId="portio.usart1.enable.rx" value="Enabled"/>
<property object="PORTIO" propertyId="portio.usart1.enable.tx" value="Enabled"/>
<property object="PORTIO" propertyId="portio.usart1.location.usart1_clkloc" value="11"/>
<property object="PORTIO" propertyId="portio.usart1.location.usart1_rxloc" value="11"/>
<property object="PORTIO" propertyId="portio.usart1.location.usart1_txloc" value="11"/>
<property object="TIMER0" propertyId="timer.clocksettings.clockselection" value="TIM0_CC1 input"/>
<property object="USART0" propertyId="ABPeripheral.included" value="true"/>
<property object="USART0" propertyId="usart.outputsettings.clockselect" value="Disabled"/>
<property object="USART1" propertyId="ABPeripheral.included" value="true"/>
<property object="USART1" propertyId="usart.mode.usartmode" value="Synchronous Mode (SPI / I2S)"/>
<property object="USART1" propertyId="usart.outputsettings.clockselect" value="Disabled"/>
<property object="USART1" propertyId="usart.synchronoussettings.baudrate" value="130000"/>
<property object="USART1" propertyId="usart.synchronoussettings.clockpolarityphasemode" value="Clock idle low, sample on falling edge"/>
</mode>
<modeTransition>
<property object="RESET &#x2192; DefaultMode" propertyId="modeTransition.source" value="RESET"/>
<property object="RESET &#x2192; DefaultMode" propertyId="modeTransition.target" value="DefaultMode"/>
</modeTransition>
</device:XMLDevice>

View File

@ -1,107 +0,0 @@
<?xml version="1.0" encoding="ASCII"?>
<device:XMLDevice xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:device="http://www.silabs.com/ss/hwconfig/document/device.ecore" name="EFM32JG1B200F128GM32" partId="mcu.arm.efm32.jg1.efm32jg1b200f128gm32" contextId="%DEFAULT%">
<mode name="DefaultMode">
<property object="ADC0" propertyId="ABPeripheral.included" value="true"/>
<property object="CMU" propertyId="ABPeripheral.included" value="true"/>
<property object="CMU" propertyId="clocksettings.hfrcosettings.hfrcofrequency" value="38 MHz"/>
<property object="CMU" propertyId="clocksettings.lfclocksettings.ulfrcorequired" value="Yes"/>
<property object="CRYOTIMER" propertyId="ABPeripheral.included" value="true"/>
<property object="CRYOTIMER" propertyId="cryotimer.clocking.clocksourceforcryotimer" value="ULFRCO"/>
<property object="CRYOTIMER" propertyId="cryotimer.clocking.eventafterevery" value="1 cycle"/>
<property object="CRYPTO" propertyId="ABPeripheral.included" value="true"/>
<property object="DefaultMode" propertyId="mode.diagramLocation" value="100, 100"/>
<property object="EMU" propertyId="ABPeripheral.included" value="true"/>
<property object="EMU" propertyId="emu.powerconfiguration.externalpowercircuitwiring" value="Not wired for DCDC"/>
<property object="GPIO" propertyId="ABPeripheral.included" value="true"/>
<property object="PA0" propertyId="ports.settings.pinmode" value="Input"/>
<property object="PA1" propertyId="ports.settings.pinmode" value="Input"/>
<property object="PB11" propertyId="ports.settings.dout" value="1"/>
<property object="PB11" propertyId="ports.settings.filter" value="Enabled"/>
<property object="PB11" propertyId="ports.settings.pinmode" value="Push-pull"/>
<property object="PB11" propertyId="ports.settings.pulldirection" value="Pullup"/>
<property object="PB11" propertyId="ports.settings.pullup" value="Enabled"/>
<property object="PB12" propertyId="ports.settings.dout" value="1"/>
<property object="PB12" propertyId="ports.settings.filter" value="Enabled"/>
<property object="PB12" propertyId="ports.settings.pinmode" value="Input pull"/>
<property object="PB12" propertyId="ports.settings.pulldirection" value="Pullup"/>
<property object="PB12" propertyId="ports.settings.pullup" value="Enabled"/>
<property object="PB13" propertyId="ports.settings.dout" value="1"/>
<property object="PB13" propertyId="ports.settings.filter" value="Enabled"/>
<property object="PB13" propertyId="ports.settings.pinmode" value="Push-pull"/>
<property object="PB13" propertyId="ports.settings.pulldirection" value="Pullup"/>
<property object="PB13" propertyId="ports.settings.pullup" value="Enabled"/>
<property object="PB15" propertyId="ports.settings.dout" value="1"/>
<property object="PB15" propertyId="ports.settings.filter" value="Enabled"/>
<property object="PB15" propertyId="ports.settings.pinmode" value="Push-pull"/>
<property object="PB15" propertyId="ports.settings.pulldirection" value="Pullup"/>
<property object="PB15" propertyId="ports.settings.pullup" value="Enabled"/>
<property object="PD10" propertyId="ports.settings.dout" value="1"/>
<property object="PD10" propertyId="ports.settings.filter" value="Enabled"/>
<property object="PD10" propertyId="ports.settings.pinmode" value="Push-pull"/>
<property object="PD10" propertyId="ports.settings.pulldirection" value="Pullup"/>
<property object="PD10" propertyId="ports.settings.pullup" value="Enabled"/>
<property object="PD11" propertyId="ports.settings.dout" value="1"/>
<property object="PD11" propertyId="ports.settings.filter" value="Enabled"/>
<property object="PD11" propertyId="ports.settings.pinmode" value="Input pull"/>
<property object="PD11" propertyId="ports.settings.pulldirection" value="Pullup"/>
<property object="PD11" propertyId="ports.settings.pullup" value="Enabled"/>
<property object="PD12" propertyId="ports.settings.dout" value="1"/>
<property object="PD12" propertyId="ports.settings.filter" value="Enabled"/>
<property object="PD12" propertyId="ports.settings.pinmode" value="Push-pull"/>
<property object="PD12" propertyId="ports.settings.pulldirection" value="Pullup"/>
<property object="PD12" propertyId="ports.settings.pullup" value="Enabled"/>
<property object="PD13" propertyId="ports.settings.dout" value="1"/>
<property object="PD13" propertyId="ports.settings.filter" value="Enabled"/>
<property object="PD13" propertyId="ports.settings.pinmode" value="Input pull"/>
<property object="PD13" propertyId="ports.settings.pulldirection" value="Pullup"/>
<property object="PD13" propertyId="ports.settings.pullup" value="Enabled"/>
<property object="PD14" propertyId="ports.settings.dout" value="1"/>
<property object="PD14" propertyId="ports.settings.filter" value="Enabled"/>
<property object="PD14" propertyId="ports.settings.pinmode" value="Push-pull"/>
<property object="PD14" propertyId="ports.settings.pulldirection" value="Pullup"/>
<property object="PD14" propertyId="ports.settings.pullup" value="Enabled"/>
<property object="PD15" propertyId="ports.settings.dout" value="1"/>
<property object="PD15" propertyId="ports.settings.filter" value="Enabled"/>
<property object="PD15" propertyId="ports.settings.pinmode" value="Push-pull"/>
<property object="PD15" propertyId="ports.settings.pulldirection" value="Pullup"/>
<property object="PD15" propertyId="ports.settings.pullup" value="Enabled"/>
<property object="PD9" propertyId="ports.settings.dout" value="1"/>
<property object="PD9" propertyId="ports.settings.filter" value="Enabled"/>
<property object="PD9" propertyId="ports.settings.pinmode" value="Push-pull"/>
<property object="PD9" propertyId="ports.settings.pulldirection" value="Pullup"/>
<property object="PD9" propertyId="ports.settings.pullup" value="Enabled"/>
<property object="PORTIO" propertyId="portio.timer0.enable.cc0" value="Enabled"/>
<property object="PORTIO" propertyId="portio.timer0.enable.cc1" value="Enabled"/>
<property object="PORTIO" propertyId="portio.timer0.enable.cc2" value="Enabled"/>
<property object="PORTIO" propertyId="portio.timer0.location.timer0_cc0loc" value="18"/>
<property object="PORTIO" propertyId="portio.timer0.location.timer0_cc1loc" value="16"/>
<property object="PORTIO" propertyId="portio.timer0.location.timer0_cc2loc" value="20"/>
<property object="PORTIO" propertyId="portio.usart0.enable.rx" value="Enabled"/>
<property object="PORTIO" propertyId="portio.usart0.enable.tx" value="Enabled"/>
<property object="PORTIO" propertyId="portio.usart0.location.usart0_txloc" value="20"/>
<property object="PORTIO" propertyId="portio.usart1.enable.clk" value="Enabled"/>
<property object="PORTIO" propertyId="portio.usart1.enable.rx" value="Enabled"/>
<property object="PORTIO" propertyId="portio.usart1.enable.tx" value="Enabled"/>
<property object="PORTIO" propertyId="portio.usart1.location.usart1_rxloc" value="6"/>
<property object="PORTIO" propertyId="portio.usart1.location.usart1_txloc" value="8"/>
<property object="TIMER0" propertyId="ABPeripheral.included" value="true"/>
<property object="TIMER0" propertyId="timer.capturecomparech0.ccmode" value="PWM"/>
<property object="TIMER0" propertyId="timer.capturecomparech0.countermatchoutputaction" value="Toggle on event"/>
<property object="TIMER0" propertyId="timer.capturecomparech1.ccmode" value="PWM"/>
<property object="TIMER0" propertyId="timer.capturecomparech1.countermatchoutputaction" value="Toggle on event"/>
<property object="TIMER0" propertyId="timer.capturecomparech2.ccmode" value="PWM"/>
<property object="TIMER0" propertyId="timer.capturecomparech2.countermatchoutputaction" value="Toggle on event"/>
<property object="TIMER0" propertyId="timer.clocksettings.hfperprescaler" value="Divide by 512"/>
<property object="USART0" propertyId="ABPeripheral.included" value="true"/>
<property object="USART0" propertyId="usart.outputsettings.clockselect" value="Disabled"/>
<property object="USART1" propertyId="ABPeripheral.included" value="true"/>
<property object="USART1" propertyId="usart.asynchronoussettings.baudrate" value="130000"/>
<property object="USART1" propertyId="usart.mode.usartmode" value="Synchronous Mode (SPI / I2S)"/>
<property object="USART1" propertyId="usart.outputsettings.clockselect" value="Disabled"/>
<property object="USART1" propertyId="usart.synchronoussettings.baudrate" value="130000"/>
</mode>
<modeTransition>
<property object="RESET &#x2192; DefaultMode" propertyId="modeTransition.source" value="RESET"/>
<property object="RESET &#x2192; DefaultMode" propertyId="modeTransition.target" value="DefaultMode"/>
</modeTransition>
</device:XMLDevice>

View File

@ -1,23 +0,0 @@
CC=arm-none-eabi-gcc
all:
cd 'GNU ARM v7.2.1 - Debug' && make all
#arm-none-eabi-gcc -g -gdwarf-2 -mcpu=cortex-m4 -mthumb -std=c99 '-DDEBUG=1' '-DEFM32PG1B200F256GM48=1' -IC:/Users/conor/Desktop/u2f-one/crypto/sha256 -IC:/Users/conor/Desktop/u2f-one/crypto/micro-ecc -IC:/Users/conor/Desktop/u2f-one/crypto/tiny-AES-c -I"C:\Users\conor\Desktop\u2f-one\efm32\inc" -IC:/Users/conor/Desktop/u2f-one/fido2 -IC:/Users/conor/Desktop/u2f-one/tinycbor/src -I"C:/SiliconLabs/SimplicityStudio/v4/developer/sdks/gecko_sdk_suite/v1.1//platform/CMSIS/Include" -I"C:/SiliconLabs/SimplicityStudio/v4/developer/sdks/gecko_sdk_suite/v1.1//hardware/kit/common/drivers" -I"C:/SiliconLabs/SimplicityStudio/v4/developer/sdks/gecko_sdk_suite/v1.1//hardware/kit/SLSTK3401A_EFM32PG/config" -I"C:/SiliconLabs/SimplicityStudio/v4/developer/sdks/gecko_sdk_suite/v1.1//platform/Device/SiliconLabs/EFM32PG1B/Include" -I"C:/SiliconLabs/SimplicityStudio/v4/developer/sdks/gecko_sdk_suite/v1.1//platform/emlib/inc" -I"C:/SiliconLabs/SimplicityStudio/v4/developer/sdks/gecko_sdk_suite/v1.1//hardware/kit/common/bsp" -O0 -Wall -c -fmessage-length=0 -mno-sched-prolog -fno-builtin -ffunction-sections -fdata-sections -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -MMD -MP -MF"src/device.d" -MT"src/device.o" -o "src/device.o" "../src/device.c"
#arm-none-eabi-gcc -g -gdwarf-2 -mcpu=cortex-m4 -mthumb -T "EFM32.ld" -Xlinker --gc-sections -Xlinker -Map="EFM32.map" -mfpu=fpv4-sp-d16 -mfloat-abi=softfp --specs=nano.specs -o EFM32.axf "./CMSIS/EFM32PG1B/startup_gcc_efm32pg1b.o" "./CMSIS/EFM32PG1B/system_efm32pg1b.o" "./crypto/micro-ecc/uECC.o" "./crypto/sha256/sha256.o" "./crypto/tiny-AES-c/aes.o" "./emlib/em_assert.o" "./emlib/em_cmu.o" "./emlib/em_emu.o" "./emlib/em_gpio.o" "./emlib/em_system.o" "./emlib/em_usart.o" "./fido2/crypto.o" "./fido2/ctap.o" "./fido2/ctap_parse.o" "./fido2/ctaphid.o" "./fido2/log.o" "./fido2/main.o" "./fido2/stubs.o" "./fido2/test_power.o" "./fido2/u2f.o" "./fido2/util.o" "./src/InitDevice.o" "./src/device.o" "./src/main.o" "./src/printing.o" "./src/retargetio.o" -Wl,--start-group -lgcc -lc -lnosys -Wl,--end-group
cbor:
cd ../tinycbor/ && make clean
cd ../tinycbor/ && make CC="$(CC)" \
LDFLAGS="-lgcc -lc -lnosys --specs=nosys.specs -mcpu=cortex-m4 -mfloat-abi=softfp -mfpu=fpv4-sp-d16 -mthumb " \
CFLAGS="-g -gdwarf-2 -mcpu=cortex-m4 -mthumb -std=c99 -DEFM32PG1B200F256GM48=1 -O3 -Wall -c -fmessage-length=0 -mno-sched-prolog -fno-builtin -ffunction-sections -fdata-sections -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -MMD -MP "
clean:
cd 'GNU ARM v7.2.1 - Debug' && make clean

File diff suppressed because it is too large Load Diff

View File

@ -1,81 +0,0 @@
/***************************************************************************//**
* @file em_assert.c
* @brief Assert API
* @version 5.2.2
*******************************************************************************
* # License
* <b>Copyright 2016 Silicon Laboratories, Inc. http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "em_assert.h"
#include <stdbool.h>
/***************************************************************************//**
* @addtogroup emlib
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup ASSERT
* @{
******************************************************************************/
#if defined(DEBUG_EFM)
/***************************************************************************//**
* @brief
* EFM internal assert handling.
*
* This function is invoked through EFM_ASSERT() macro usage only, it should
* not be used explicitly.
*
* This implementation simply enters an indefinite loop, allowing
* the use of a debugger to determine cause of failure. By defining
* DEBUG_EFM_USER to the preprocessor for all files, a user defined version
* of this function must be defined and will be invoked instead, possibly
* providing output of assertion location.
*
* @note
* This function is not used unless @ref DEBUG_EFM is defined
* during preprocessing of EFM_ASSERT() usage.
*
* @param[in] file
* Name of source file where assertion failed.
*
* @param[in] line
* Line number in source file where assertion failed.
******************************************************************************/
void assertEFM(const char *file, int line)
{
(void)file; /* Unused parameter */
(void)line; /* Unused parameter */
while (true) {
}
}
#endif /* DEBUG_EFM */
/** @} (end addtogroup ASSERT) */
/** @} (end addtogroup emlib) */

File diff suppressed because it is too large Load Diff

View File

@ -1,61 +0,0 @@
/***************************************************************************//**
* @file em_cryotimer.c
* @brief Ultra Low Energy Timer/Counter (CRYOTIMER) peripheral API
* @version 5.2.2
*******************************************************************************
* # License
* <b>Copyright 2016 Silicon Laboratories, Inc. http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.@n
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.@n
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "em_cryotimer.h"
#include "em_bus.h"
#if defined(CRYOTIMER_PRESENT) && (CRYOTIMER_COUNT == 1)
/***************************************************************************//**
* @brief
* Initialize the CRYOTIMER.
*
* @details
* Use this function to initialize the CRYOTIMER.
* Select prescaler setting and select low frequency oscillator.
* Refer to the configuration structure @ref CRYOTIMER_Init_TypeDef for more
* details.
*
* @param[in] init
* Pointer to initialization structure.
******************************************************************************/
void CRYOTIMER_Init(const CRYOTIMER_Init_TypeDef *init)
{
CRYOTIMER->PERIODSEL = (uint32_t)init->period & _CRYOTIMER_PERIODSEL_MASK;
CRYOTIMER->CTRL = ((uint32_t)init->enable << _CRYOTIMER_CTRL_EN_SHIFT)
| ((uint32_t)init->debugRun << _CRYOTIMER_CTRL_DEBUGRUN_SHIFT)
| ((uint32_t)init->osc << _CRYOTIMER_CTRL_OSCSEL_SHIFT)
| ((uint32_t)init->presc << _CRYOTIMER_CTRL_PRESC_SHIFT);
CRYOTIMER_EM4WakeupEnable(init->em4Wakeup);
}
#endif /* defined(CRYOTIMER_PRESENT) && (CRYOTIMER_COUNT > 0) */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,367 +0,0 @@
/***************************************************************************//**
* @file em_gpio.c
* @brief General Purpose IO (GPIO) peripheral API
* devices.
* @version 5.2.2
*******************************************************************************
* # License
* <b>Copyright 2016 Silicon Laboratories, Inc. http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "em_gpio.h"
#if defined(GPIO_COUNT) && (GPIO_COUNT > 0)
/***************************************************************************//**
* @addtogroup emlib
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup GPIO
* @brief General Purpose Input/Output (GPIO) API
* @details
* This module contains functions to control the GPIO peripheral of Silicon
* Labs 32-bit MCUs and SoCs. The GPIO peripheral is used for pin configuration
* and direct pin manipulation and sensing as well as routing for peripheral
* pin connections.
* @{
******************************************************************************/
/*******************************************************************************
******************************* DEFINES ***********************************
******************************************************************************/
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/** Validation of pin typically usable in assert statements. */
#define GPIO_DRIVEMODE_VALID(mode) ((mode) <= 3)
#define GPIO_STRENGHT_VALID(strenght) (!((strenght) \
& ~(_GPIO_P_CTRL_DRIVESTRENGTH_MASK \
| _GPIO_P_CTRL_DRIVESTRENGTHALT_MASK)))
/** @endcond */
/*******************************************************************************
************************** GLOBAL FUNCTIONS *******************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Sets the pin location of the debug pins (Serial Wire interface).
*
* @note
* Changing the pins used for debugging uncontrolled, may result in a lockout.
*
* @param[in] location
* The debug pin location to use (0-3).
******************************************************************************/
void GPIO_DbgLocationSet(unsigned int location)
{
#if defined (_GPIO_ROUTE_SWLOCATION_MASK)
EFM_ASSERT(location < AFCHANLOC_MAX);
GPIO->ROUTE = (GPIO->ROUTE & ~_GPIO_ROUTE_SWLOCATION_MASK)
| (location << _GPIO_ROUTE_SWLOCATION_SHIFT);
#else
(void)location;
#endif
}
#if defined (_GPIO_P_CTRL_DRIVEMODE_MASK)
/***************************************************************************//**
* @brief
* Sets the drive mode for a GPIO port.
*
* @param[in] port
* The GPIO port to access.
*
* @param[in] mode
* Drive mode to use for port.
******************************************************************************/
void GPIO_DriveModeSet(GPIO_Port_TypeDef port, GPIO_DriveMode_TypeDef mode)
{
EFM_ASSERT(GPIO_PORT_VALID(port) && GPIO_DRIVEMODE_VALID(mode));
GPIO->P[port].CTRL = (GPIO->P[port].CTRL & ~(_GPIO_P_CTRL_DRIVEMODE_MASK))
| (mode << _GPIO_P_CTRL_DRIVEMODE_SHIFT);
}
#endif
#if defined (_GPIO_P_CTRL_DRIVESTRENGTH_MASK)
/***************************************************************************//**
* @brief
* Sets the drive strength for a GPIO port.
*
* @param[in] port
* The GPIO port to access.
*
* @param[in] strength
* Drive strength to use for port.
******************************************************************************/
void GPIO_DriveStrengthSet(GPIO_Port_TypeDef port,
GPIO_DriveStrength_TypeDef strength)
{
EFM_ASSERT(GPIO_PORT_VALID(port) && GPIO_STRENGHT_VALID(strength));
BUS_RegMaskedWrite(&GPIO->P[port].CTRL,
_GPIO_P_CTRL_DRIVESTRENGTH_MASK | _GPIO_P_CTRL_DRIVESTRENGTHALT_MASK,
strength);
}
#endif
/***************************************************************************//**
* @brief
* Configure GPIO external pin interrupt.
*
* @details
* If reconfiguring a GPIO interrupt that is already enabled, it is generally
* recommended to disable it first, see GPIO_Disable().
*
* The actual GPIO interrupt handler must be in place before enabling the
* interrupt.
*
* Notice that any pending interrupt for the selected interrupt is cleared
* by this function.
*
* @note
* On series 0 devices the pin number parameter is not used. The
* pin number used on these devices is hardwired to the interrupt with the
* same number. @n
* On series 1 devices, pin number can be selected freely within a group.
* Interrupt numbers are divided into 4 groups (intNo / 4) and valid pin
* number within the interrupt groups are:
* 0: pins 0-3
* 1: pins 4-7
* 2: pins 8-11
* 3: pins 12-15
*
* @param[in] port
* The port to associate with @p pin.
*
* @param[in] pin
* The pin number on the port.
*
* @param[in] intNo
* The interrupt number to trigger.
*
* @param[in] risingEdge
* Set to true if interrupts shall be enabled on rising edge, otherwise false.
*
* @param[in] fallingEdge
* Set to true if interrupts shall be enabled on falling edge, otherwise false.
*
* @param[in] enable
* Set to true if interrupt shall be enabled after configuration completed,
* false to leave disabled. See GPIO_IntDisable() and GPIO_IntEnable().
******************************************************************************/
void GPIO_ExtIntConfig(GPIO_Port_TypeDef port,
unsigned int pin,
unsigned int intNo,
bool risingEdge,
bool fallingEdge,
bool enable)
{
uint32_t tmp = 0;
#if !defined(_GPIO_EXTIPINSELL_MASK)
(void)pin;
#endif
EFM_ASSERT(GPIO_PORT_PIN_VALID(port, pin));
#if defined(_GPIO_EXTIPINSELL_MASK)
EFM_ASSERT(GPIO_INTNO_PIN_VALID(intNo, pin));
#endif
/* There are two registers controlling the interrupt configuration:
* The EXTIPSELL register controls pins 0-7 and EXTIPSELH controls
* pins 8-15. */
if (intNo < 8) {
BUS_RegMaskedWrite(&GPIO->EXTIPSELL,
_GPIO_EXTIPSELL_EXTIPSEL0_MASK
<< (_GPIO_EXTIPSELL_EXTIPSEL1_SHIFT * intNo),
port << (_GPIO_EXTIPSELL_EXTIPSEL1_SHIFT * intNo));
} else {
tmp = intNo - 8;
BUS_RegMaskedWrite(&GPIO->EXTIPSELH,
_GPIO_EXTIPSELH_EXTIPSEL8_MASK
<< (_GPIO_EXTIPSELH_EXTIPSEL9_SHIFT * tmp),
port << (_GPIO_EXTIPSELH_EXTIPSEL9_SHIFT * tmp));
}
#if defined(_GPIO_EXTIPINSELL_MASK)
/* There are two registers controlling the interrupt/pin number mapping:
* The EXTIPINSELL register controls interrupt 0-7 and EXTIPINSELH controls
* interrupt 8-15. */
if (intNo < 8) {
BUS_RegMaskedWrite(&GPIO->EXTIPINSELL,
_GPIO_EXTIPINSELL_EXTIPINSEL0_MASK
<< (_GPIO_EXTIPINSELL_EXTIPINSEL1_SHIFT * intNo),
((pin % 4) & _GPIO_EXTIPINSELL_EXTIPINSEL0_MASK)
<< (_GPIO_EXTIPINSELL_EXTIPINSEL1_SHIFT * intNo));
} else {
BUS_RegMaskedWrite(&GPIO->EXTIPINSELH,
_GPIO_EXTIPINSELH_EXTIPINSEL8_MASK
<< (_GPIO_EXTIPINSELH_EXTIPINSEL9_SHIFT * tmp),
((pin % 4) & _GPIO_EXTIPINSELH_EXTIPINSEL8_MASK)
<< (_GPIO_EXTIPSELH_EXTIPSEL9_SHIFT * tmp));
}
#endif
/* Enable/disable rising edge */
BUS_RegBitWrite(&(GPIO->EXTIRISE), intNo, risingEdge);
/* Enable/disable falling edge */
BUS_RegBitWrite(&(GPIO->EXTIFALL), intNo, fallingEdge);
/* Clear any pending interrupt */
GPIO->IFC = 1 << intNo;
/* Finally enable/disable interrupt */
BUS_RegBitWrite(&(GPIO->IEN), intNo, enable);
}
/***************************************************************************//**
* @brief
* Set the mode for a GPIO pin.
*
* @param[in] port
* The GPIO port to access.
*
* @param[in] pin
* The pin number in the port.
*
* @param[in] mode
* The desired pin mode.
*
* @param[in] out
* Value to set for pin in DOUT register. The DOUT setting is important for
* even some input mode configurations, determining pull-up/down direction.
******************************************************************************/
void GPIO_PinModeSet(GPIO_Port_TypeDef port,
unsigned int pin,
GPIO_Mode_TypeDef mode,
unsigned int out)
{
EFM_ASSERT(GPIO_PORT_PIN_VALID(port, pin));
/* If disabling pin, do not modify DOUT in order to reduce chance for */
/* glitch/spike (may not be sufficient precaution in all use cases) */
if (mode != gpioModeDisabled) {
if (out) {
GPIO_PinOutSet(port, pin);
} else {
GPIO_PinOutClear(port, pin);
}
}
/* There are two registers controlling the pins for each port. The MODEL
* register controls pins 0-7 and MODEH controls pins 8-15. */
if (pin < 8) {
GPIO->P[port].MODEL = (GPIO->P[port].MODEL & ~(0xFu << (pin * 4)))
| (mode << (pin * 4));
} else {
GPIO->P[port].MODEH = (GPIO->P[port].MODEH & ~(0xFu << ((pin - 8) * 4)))
| (mode << ((pin - 8) * 4));
}
if (mode == gpioModeDisabled) {
if (out) {
GPIO_PinOutSet(port, pin);
} else {
GPIO_PinOutClear(port, pin);
}
}
}
/***************************************************************************//**
* @brief
* Get the mode for a GPIO pin.
*
* @param[in] port
* The GPIO port to access.
*
* @param[in] pin
* The pin number in the port.
*
* @return
* The pin mode.
******************************************************************************/
GPIO_Mode_TypeDef GPIO_PinModeGet(GPIO_Port_TypeDef port,
unsigned int pin)
{
EFM_ASSERT(GPIO_PORT_PIN_VALID(port, pin));
if (pin < 8) {
return (GPIO_Mode_TypeDef) ((GPIO->P[port].MODEL >> (pin * 4)) & 0xF);
} else {
return (GPIO_Mode_TypeDef) ((GPIO->P[port].MODEH >> ((pin - 8) * 4)) & 0xF);
}
}
#if defined(_GPIO_EM4WUEN_MASK)
/**************************************************************************//**
* @brief
* Enable GPIO pin wake-up from EM4. When the function exits,
* EM4 mode can be safely entered.
*
* @note
* It is assumed that the GPIO pin modes are set correctly.
* Valid modes are @ref gpioModeInput and @ref gpioModeInputPull.
*
* @param[in] pinmask
* Bitmask containing the bitwise logic OR of which GPIO pin(s) to enable.
* Refer to Reference Manuals for pinmask to GPIO port/pin mapping.
* @param[in] polaritymask
* Bitmask containing the bitwise logic OR of GPIO pin(s) wake-up polarity.
* Refer to Reference Manuals for pinmask to GPIO port/pin mapping.
*****************************************************************************/
void GPIO_EM4EnablePinWakeup(uint32_t pinmask, uint32_t polaritymask)
{
EFM_ASSERT((pinmask & ~_GPIO_EM4WUEN_MASK) == 0);
#if defined(_GPIO_EM4WUPOL_MASK)
EFM_ASSERT((polaritymask & ~_GPIO_EM4WUPOL_MASK) == 0);
GPIO->EM4WUPOL &= ~pinmask; /* Set wakeup polarity */
GPIO->EM4WUPOL |= pinmask & polaritymask;
#elif defined(_GPIO_EXTILEVEL_MASK)
EFM_ASSERT((polaritymask & ~_GPIO_EXTILEVEL_MASK) == 0);
GPIO->EXTILEVEL &= ~pinmask;
GPIO->EXTILEVEL |= pinmask & polaritymask;
#endif
GPIO->EM4WUEN |= pinmask; /* Enable wakeup */
GPIO_EM4SetPinRetention(true); /* Enable pin retention */
#if defined(_GPIO_CMD_EM4WUCLR_MASK)
GPIO->CMD = GPIO_CMD_EM4WUCLR; /* Clear wake-up logic */
#elif defined(_GPIO_IFC_EM4WU_MASK)
GPIO_IntClear(pinmask);
#endif
}
#endif
/** @} (end addtogroup GPIO) */
/** @} (end addtogroup emlib) */
#endif /* defined(GPIO_COUNT) && (GPIO_COUNT > 0) */

View File

@ -1,811 +0,0 @@
/***************************************************************************//**
* @file em_i2c.c
* @brief Inter-integrated Circuit (I2C) Peripheral API
* @version 5.2.2
*******************************************************************************
* # License
* <b>Copyright 2016 Silicon Laboratories, Inc. http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "em_i2c.h"
#if defined(I2C_COUNT) && (I2C_COUNT > 0)
#include "em_cmu.h"
#include "em_bus.h"
#include "em_assert.h"
#include <limits.h>
/***************************************************************************//**
* @addtogroup emlib
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup I2C
* @brief Inter-integrated Circuit (I2C) Peripheral API
* @details
* This module contains functions to control the I2C peripheral of Silicon
* Labs 32-bit MCUs and SoCs. The I2C interface allows communication on I2C
* buses with the lowest energy consumption possible.
* @{
******************************************************************************/
/*******************************************************************************
******************************* DEFINES ***********************************
******************************************************************************/
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/** Validation of I2C register block pointer reference for assert statements. */
#if (I2C_COUNT == 1)
#define I2C_REF_VALID(ref) ((ref) == I2C0)
#elif (I2C_COUNT == 2)
#define I2C_REF_VALID(ref) ((ref == I2C0) || (ref == I2C1))
#elif (I2C_COUNT == 3)
#define I2C_REF_VALID(ref) ((ref == I2C0) || (ref == I2C1) || (ref == I2C2))
#endif
/** Error flags indicating I2C transfer has failed somehow. */
/* Notice that I2C_IF_TXOF (transmit overflow) is not really possible with */
/* this SW supporting master mode. Likewise for I2C_IF_RXUF (receive underflow) */
/* RXUF is only likely to occur with this SW if using a debugger peeking into */
/* RXDATA register. Thus, we ignore those types of fault. */
#define I2C_IF_ERRORS (I2C_IF_BUSERR | I2C_IF_ARBLOST)
/* Max I2C transmission rate constant */
#if defined(_SILICON_LABS_32B_SERIES_0)
#define I2C_CR_MAX 4
#elif defined(_SILICON_LABS_32B_SERIES_1)
#define I2C_CR_MAX 8
#else
#warning "Max I2C transmission rate constant is not defined"
#endif
/** @endcond */
/*******************************************************************************
******************************** ENUMS ************************************
******************************************************************************/
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/** Master mode transfer states. */
typedef enum {
i2cStateStartAddrSend, /**< Send start + (first part of) address. */
i2cStateAddrWFAckNack, /**< Wait for ACK/NACK on (first part of) address. */
i2cStateAddrWF2ndAckNack, /**< Wait for ACK/NACK on second part of 10 bit address. */
i2cStateRStartAddrSend, /**< Send repeated start + (first part of) address. */
i2cStateRAddrWFAckNack, /**< Wait for ACK/NACK on address sent after repeated start. */
i2cStateDataSend, /**< Send data. */
i2cStateDataWFAckNack, /**< Wait for ACK/NACK on data sent. */
i2cStateWFData, /**< Wait for data. */
i2cStateWFStopSent, /**< Wait for STOP to have been transmitted. */
i2cStateDone /**< Transfer completed successfully. */
} I2C_TransferState_TypeDef;
/** @endcond */
/*******************************************************************************
******************************* STRUCTS ***********************************
******************************************************************************/
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/** Structure used to store state information on an ongoing master mode transfer. */
typedef struct {
/** Current state. */
I2C_TransferState_TypeDef state;
/** Result return code. */
I2C_TransferReturn_TypeDef result;
/** Offset in current sequence buffer. */
uint16_t offset;
/* Index to current sequence buffer in use. */
uint8_t bufIndx;
/** Reference to I2C transfer sequence definition provided by user. */
I2C_TransferSeq_TypeDef *seq;
} I2C_Transfer_TypeDef;
/** @endcond */
/*******************************************************************************
***************************** LOCAL DATA *******^**************************
******************************************************************************/
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/**
* Lookup table for Nlow + Nhigh setting defined by CLHR. Set undefined
* index (0x3) to reflect default setting just in case.
*/
static const uint8_t i2cNSum[] = { 4 + 4, 6 + 3, 11 + 6, 4 + 4 };
/** Transfer state info for ongoing master mode transfer */
static I2C_Transfer_TypeDef i2cTransfer[I2C_COUNT];
/** @endcond */
/*******************************************************************************
************************** GLOBAL FUNCTIONS *******************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Get current configured I2C bus frequency.
*
* @details
* This frequency is only of relevance when acting as master.
*
* @param[in] i2c
* Pointer to I2C peripheral register block.
*
* @return
* Current I2C frequency in Hz.
******************************************************************************/
uint32_t I2C_BusFreqGet(I2C_TypeDef *i2c)
{
uint32_t freqHfper;
uint32_t n;
/* Max frequency is given by freqScl = freqHfper/((Nlow + Nhigh)(DIV + 1) + I2C_CR_MAX)
* More details can be found in the reference manual,
* I2C Clock Generation chapter. */
freqHfper = CMU_ClockFreqGet(cmuClock_HFPER);
/* n = Nlow + Nhigh */
n = (uint32_t)(i2cNSum[(i2c->CTRL & _I2C_CTRL_CLHR_MASK) >> _I2C_CTRL_CLHR_SHIFT]);
return (freqHfper / ((n * (i2c->CLKDIV + 1)) + I2C_CR_MAX));
}
/***************************************************************************//**
* @brief
* Set I2C bus frequency.
*
* @details
* The bus frequency is only of relevance when acting as a master. The bus
* frequency should not be set higher than the max frequency accepted by the
* slowest device on the bus.
*
* Notice that due to asymmetric requirements on low and high I2C clock
* cycles by the I2C specification, the actual max frequency allowed in order
* to comply with the specification may be somewhat lower than expected.
*
* Please refer to the reference manual, details on I2C clock generation,
* for max allowed theoretical frequencies for different modes.
*
* @param[in] i2c
* Pointer to I2C peripheral register block.
*
* @param[in] freqRef
* I2C reference clock frequency in Hz that will be used. If set to 0,
* then HFPER clock is used. Setting it to a higher than actual configured
* value only has the consequence of reducing the real I2C frequency.
*
* @param[in] freqScl
* Bus frequency to set (actual bus speed may be lower due to integer
* prescaling). Safe (according to I2C specification) max frequencies for
* standard, fast and fast+ modes are available using I2C_FREQ_ defines.
* (Using I2C_FREQ_ defines requires corresponding setting of @p type.)
* Slowest slave device on bus must always be considered.
*
* @param[in] i2cMode
* Clock low to high ratio type to use. If not using i2cClockHLRStandard,
* make sure all devices on the bus support the specified mode. Using a
* non-standard ratio is useful to achieve higher bus clock in fast and
* fast+ modes.
******************************************************************************/
void I2C_BusFreqSet(I2C_TypeDef *i2c,
uint32_t freqRef,
uint32_t freqScl,
I2C_ClockHLR_TypeDef i2cMode)
{
uint32_t n, minFreq;
int32_t div;
/* Avoid divide by 0 */
EFM_ASSERT(freqScl);
if (!freqScl) {
return;
}
/* Set the CLHR (clock low to high ratio). */
i2c->CTRL &= ~_I2C_CTRL_CLHR_MASK;
BUS_RegMaskedWrite(&i2c->CTRL,
_I2C_CTRL_CLHR_MASK,
i2cMode << _I2C_CTRL_CLHR_SHIFT);
if (!freqRef) {
freqRef = CMU_ClockFreqGet(cmuClock_HFPER);
}
/* Check minumum HF peripheral clock */
minFreq = UINT_MAX;
if (i2c->CTRL & I2C_CTRL_SLAVE) {
switch (i2cMode) {
case i2cClockHLRStandard:
#if defined(_SILICON_LABS_32B_SERIES_0)
minFreq = 4200000; break;
#elif defined(_SILICON_LABS_32B_SERIES_1)
minFreq = 2000000; break;
#endif
case i2cClockHLRAsymetric:
#if defined(_SILICON_LABS_32B_SERIES_0)
minFreq = 11000000; break;
#elif defined(_SILICON_LABS_32B_SERIES_1)
minFreq = 5000000; break;
#endif
case i2cClockHLRFast:
#if defined(_SILICON_LABS_32B_SERIES_0)
minFreq = 24400000; break;
#elif defined(_SILICON_LABS_32B_SERIES_1)
minFreq = 14000000; break;
#endif
}
} else {
/* For master mode, platform 1 and 2 share the same
min frequencies */
switch (i2cMode) {
case i2cClockHLRStandard:
minFreq = 2000000; break;
case i2cClockHLRAsymetric:
minFreq = 9000000; break;
case i2cClockHLRFast:
minFreq = 20000000; break;
}
}
/* Frequency most be larger-than */
EFM_ASSERT(freqRef > minFreq);
/* SCL frequency is given by
* freqScl = freqRef/((Nlow + Nhigh) * (DIV + 1) + I2C_CR_MAX)
*
* Thus
* DIV = ((freqRef - (I2C_CR_MAX * freqScl))/((Nlow + Nhigh) * freqScl)) - 1
*
* More details can be found in the reference manual,
* I2C Clock Generation chapter. */
/* n = Nlow + Nhigh */
n = (uint32_t)(i2cNSum[i2cMode]);
div = ((freqRef - (I2C_CR_MAX * freqScl)) / (n * freqScl)) - 1;
EFM_ASSERT(div >= 0);
EFM_ASSERT((uint32_t)div <= _I2C_CLKDIV_DIV_MASK);
/* Clock divisor must be at least 1 in slave mode according to reference */
/* manual (in which case there is normally no need to set bus frequency). */
if ((i2c->CTRL & I2C_CTRL_SLAVE) && !div) {
div = 1;
}
i2c->CLKDIV = (uint32_t)div;
}
/***************************************************************************//**
* @brief
* Enable/disable I2C.
*
* @note
* After enabling the I2C (from being disabled), the I2C is in BUSY state.
*
* @param[in] i2c
* Pointer to I2C peripheral register block.
*
* @param[in] enable
* true to enable counting, false to disable.
******************************************************************************/
void I2C_Enable(I2C_TypeDef *i2c, bool enable)
{
EFM_ASSERT(I2C_REF_VALID(i2c));
BUS_RegBitWrite(&(i2c->CTRL), _I2C_CTRL_EN_SHIFT, enable);
}
/***************************************************************************//**
* @brief
* Initialize I2C.
*
* @param[in] i2c
* Pointer to I2C peripheral register block.
*
* @param[in] init
* Pointer to I2C initialization structure.
******************************************************************************/
void I2C_Init(I2C_TypeDef *i2c, const I2C_Init_TypeDef *init)
{
EFM_ASSERT(I2C_REF_VALID(i2c));
i2c->IEN = 0;
i2c->IFC = _I2C_IFC_MASK;
/* Set SLAVE select mode */
BUS_RegBitWrite(&(i2c->CTRL), _I2C_CTRL_SLAVE_SHIFT, init->master ? 0 : 1);
I2C_BusFreqSet(i2c, init->refFreq, init->freq, init->clhr);
BUS_RegBitWrite(&(i2c->CTRL), _I2C_CTRL_EN_SHIFT, init->enable);
}
/***************************************************************************//**
* @brief
* Reset I2C to same state as after a HW reset.
*
* @note
* The ROUTE register is NOT reset by this function, in order to allow for
* centralized setup of this feature.
*
* @param[in] i2c
* Pointer to I2C peripheral register block.
******************************************************************************/
void I2C_Reset(I2C_TypeDef *i2c)
{
i2c->CTRL = _I2C_CTRL_RESETVALUE;
i2c->CLKDIV = _I2C_CLKDIV_RESETVALUE;
i2c->SADDR = _I2C_SADDR_RESETVALUE;
i2c->SADDRMASK = _I2C_SADDRMASK_RESETVALUE;
i2c->IEN = _I2C_IEN_RESETVALUE;
i2c->IFC = _I2C_IFC_MASK;
/* Do not reset route register, setting should be done independently */
}
/***************************************************************************//**
* @brief
* Continue an initiated I2C transfer (single master mode only).
*
* @details
* This function is used repeatedly after a I2C_TransferInit() in order to
* complete a transfer. It may be used in polled mode as the below example
* shows:
* @verbatim
* I2C_TransferReturn_TypeDef ret;
*
* // Do a polled transfer
* ret = I2C_TransferInit(I2C0, seq);
* while (ret == i2cTransferInProgress)
* {
* ret = I2C_Transfer(I2C0);
* }
* @endverbatim
* It may also be used in interrupt driven mode, where this function is invoked
* from the interrupt handler. Notice that if used in interrupt mode, NVIC
* interrupts must be configured and enabled for the I2C bus used. I2C
* peripheral specific interrupts are managed by this SW.
*
* @note
* Only single master mode is supported.
*
* @param[in] i2c
* Pointer to I2C peripheral register block.
*
* @return
* Returns status for ongoing transfer.
* @li #i2cTransferInProgress - indicates that transfer not finished.
* @li #i2cTransferDone - transfer completed successfully.
* @li otherwise some sort of error has occurred.
*
******************************************************************************/
I2C_TransferReturn_TypeDef I2C_Transfer(I2C_TypeDef *i2c)
{
uint32_t tmp;
uint32_t pending;
I2C_Transfer_TypeDef *transfer;
I2C_TransferSeq_TypeDef *seq;
EFM_ASSERT(I2C_REF_VALID(i2c));
/* Support up to 2 I2C buses */
if (i2c == I2C0) {
transfer = i2cTransfer;
}
#if (I2C_COUNT > 1)
else if (i2c == I2C1) {
transfer = i2cTransfer + 1;
}
#endif
#if (I2C_COUNT > 2)
else if (i2c == I2C2) {
transfer = i2cTransfer + 2;
}
#endif
else {
return i2cTransferUsageFault;
}
seq = transfer->seq;
for (;; ) {
pending = i2c->IF;
/* If some sort of fault, abort transfer. */
if (pending & I2C_IF_ERRORS) {
if (pending & I2C_IF_ARBLOST) {
/* If arbitration fault, it indicates either a slave device */
/* not responding as expected, or other master which is not */
/* supported by this SW. */
transfer->result = i2cTransferArbLost;
} else if (pending & I2C_IF_BUSERR) {
/* A bus error indicates a misplaced start or stop, which should */
/* not occur in master mode controlled by this SW. */
transfer->result = i2cTransferBusErr;
}
/* If error situation occurred, it is difficult to know */
/* exact cause and how to resolve. It will be up to a wrapper */
/* to determine how to handle a fault/recovery if possible. */
transfer->state = i2cStateDone;
goto done;
}
switch (transfer->state) {
/***************************************************/
/* Send first start+address (first byte if 10 bit) */
/***************************************************/
case i2cStateStartAddrSend:
if (seq->flags & I2C_FLAG_10BIT_ADDR) {
tmp = (((uint32_t)(seq->addr) >> 8) & 0x06) | 0xf0;
/* In 10 bit address mode, the address following the first */
/* start always indicate write. */
} else {
tmp = (uint32_t)(seq->addr) & 0xfe;
if (seq->flags & I2C_FLAG_READ) {
/* Indicate read request */
tmp |= 1;
}
}
transfer->state = i2cStateAddrWFAckNack;
i2c->TXDATA = tmp;/* Data not transmitted until START sent */
i2c->CMD = I2C_CMD_START;
goto done;
/*******************************************************/
/* Wait for ACK/NACK on address (first byte if 10 bit) */
/*******************************************************/
case i2cStateAddrWFAckNack:
if (pending & I2C_IF_NACK) {
i2c->IFC = I2C_IFC_NACK;
transfer->result = i2cTransferNack;
transfer->state = i2cStateWFStopSent;
i2c->CMD = I2C_CMD_STOP;
} else if (pending & I2C_IF_ACK) {
i2c->IFC = I2C_IFC_ACK;
/* If 10 bit address, send 2nd byte of address. */
if (seq->flags & I2C_FLAG_10BIT_ADDR) {
transfer->state = i2cStateAddrWF2ndAckNack;
i2c->TXDATA = (uint32_t)(seq->addr) & 0xff;
} else {
/* Determine whether receiving or sending data */
if (seq->flags & I2C_FLAG_READ) {
transfer->state = i2cStateWFData;
if (seq->buf[transfer->bufIndx].len == 1) {
i2c->CMD = I2C_CMD_NACK;
}
} else {
transfer->state = i2cStateDataSend;
continue;
}
}
}
goto done;
/******************************************************/
/* Wait for ACK/NACK on second byte of 10 bit address */
/******************************************************/
case i2cStateAddrWF2ndAckNack:
if (pending & I2C_IF_NACK) {
i2c->IFC = I2C_IFC_NACK;
transfer->result = i2cTransferNack;
transfer->state = i2cStateWFStopSent;
i2c->CMD = I2C_CMD_STOP;
} else if (pending & I2C_IF_ACK) {
i2c->IFC = I2C_IFC_ACK;
/* If using plain read sequence with 10 bit address, switch to send */
/* repeated start. */
if (seq->flags & I2C_FLAG_READ) {
transfer->state = i2cStateRStartAddrSend;
}
/* Otherwise expected to write 0 or more bytes */
else {
transfer->state = i2cStateDataSend;
}
continue;
}
goto done;
/*******************************/
/* Send repeated start+address */
/*******************************/
case i2cStateRStartAddrSend:
if (seq->flags & I2C_FLAG_10BIT_ADDR) {
tmp = ((seq->addr >> 8) & 0x06) | 0xf0;
} else {
tmp = seq->addr & 0xfe;
}
/* If this is a write+read combined sequence, then read is about to start */
if (seq->flags & I2C_FLAG_WRITE_READ) {
/* Indicate read request */
tmp |= 1;
}
transfer->state = i2cStateRAddrWFAckNack;
/* We have to write START cmd first since repeated start, otherwise */
/* data would be sent first. */
i2c->CMD = I2C_CMD_START;
i2c->TXDATA = tmp;
goto done;
/**********************************************************************/
/* Wait for ACK/NACK on repeated start+address (first byte if 10 bit) */
/**********************************************************************/
case i2cStateRAddrWFAckNack:
if (pending & I2C_IF_NACK) {
i2c->IFC = I2C_IFC_NACK;
transfer->result = i2cTransferNack;
transfer->state = i2cStateWFStopSent;
i2c->CMD = I2C_CMD_STOP;
} else if (pending & I2C_IF_ACK) {
i2c->IFC = I2C_IFC_ACK;
/* Determine whether receiving or sending data */
if (seq->flags & I2C_FLAG_WRITE_READ) {
transfer->state = i2cStateWFData;
} else {
transfer->state = i2cStateDataSend;
continue;
}
}
goto done;
/*****************************/
/* Send a data byte to slave */
/*****************************/
case i2cStateDataSend:
/* Reached end of data buffer? */
if (transfer->offset >= seq->buf[transfer->bufIndx].len) {
/* Move to next message part */
transfer->offset = 0;
transfer->bufIndx++;
/* Send repeated start when switching to read mode on 2nd buffer */
if (seq->flags & I2C_FLAG_WRITE_READ) {
transfer->state = i2cStateRStartAddrSend;
continue;
}
/* Only writing from one buffer, or finished both buffers */
if ((seq->flags & I2C_FLAG_WRITE) || (transfer->bufIndx > 1)) {
transfer->state = i2cStateWFStopSent;
i2c->CMD = I2C_CMD_STOP;
goto done;
}
/* Reprocess in case next buffer is empty */
continue;
}
/* Send byte */
i2c->TXDATA = (uint32_t)(seq->buf[transfer->bufIndx].data[transfer->offset++]);
transfer->state = i2cStateDataWFAckNack;
goto done;
/*********************************************************/
/* Wait for ACK/NACK from slave after sending data to it */
/*********************************************************/
case i2cStateDataWFAckNack:
if (pending & I2C_IF_NACK) {
i2c->IFC = I2C_IFC_NACK;
transfer->result = i2cTransferNack;
transfer->state = i2cStateWFStopSent;
i2c->CMD = I2C_CMD_STOP;
} else if (pending & I2C_IF_ACK) {
i2c->IFC = I2C_IFC_ACK;
transfer->state = i2cStateDataSend;
continue;
}
goto done;
/****************************/
/* Wait for data from slave */
/****************************/
case i2cStateWFData:
if (pending & I2C_IF_RXDATAV) {
uint8_t data;
unsigned int rxLen = seq->buf[transfer->bufIndx].len;
/* Must read out data in order to not block further progress */
data = (uint8_t)(i2c->RXDATA);
/* Make sure not storing beyond end of buffer just in case */
if (transfer->offset < rxLen) {
seq->buf[transfer->bufIndx].data[transfer->offset++] = data;
}
/* If we have read all requested data, then the sequence should end */
if (transfer->offset >= rxLen) {
/* If there is only one byte to receive we need to transmit the
NACK now, before the stop. */
if (1 == rxLen) {
i2c->CMD = I2C_CMD_NACK;
}
transfer->state = i2cStateWFStopSent;
i2c->CMD = I2C_CMD_STOP;
} else {
/* Send ACK and wait for next byte */
i2c->CMD = I2C_CMD_ACK;
if ( (1 < rxLen) && (transfer->offset == (rxLen - 1)) ) {
/* If there is more than one byte to receive and this is the next
to last byte we need to transmit the NACK now, before receiving
the last byte. */
i2c->CMD = I2C_CMD_NACK;
}
}
}
goto done;
/***********************************/
/* Wait for STOP to have been sent */
/***********************************/
case i2cStateWFStopSent:
if (pending & I2C_IF_MSTOP) {
i2c->IFC = I2C_IFC_MSTOP;
transfer->state = i2cStateDone;
}
goto done;
/******************************/
/* Unexpected state, SW fault */
/******************************/
default:
transfer->result = i2cTransferSwFault;
transfer->state = i2cStateDone;
goto done;
}
}
done:
if (transfer->state == i2cStateDone) {
/* Disable interrupt sources when done */
i2c->IEN = 0;
/* Update result unless some fault already occurred */
if (transfer->result == i2cTransferInProgress) {
transfer->result = i2cTransferDone;
}
}
/* Until transfer is done keep returning i2cTransferInProgress */
else {
return i2cTransferInProgress;
}
return transfer->result;
}
/***************************************************************************//**
* @brief
* Prepare and start an I2C transfer (single master mode only).
*
* @details
* This function must be invoked in order to start an I2C transfer
* sequence. In order to actually complete the transfer, I2C_Transfer() must
* be used either in polled mode or by adding a small driver wrapper utilizing
* interrupts.
*
* @note
* Only single master mode is supported.
*
* @param[in] i2c
* Pointer to I2C peripheral register block.
*
* @param[in] seq
* Pointer to sequence structure defining the I2C transfer to take place. The
* referenced structure must exist until the transfer has fully completed.
*
* @return
* Returns status for ongoing transfer:
* @li #i2cTransferInProgress - indicates that transfer not finished.
* @li otherwise some sort of error has occurred.
******************************************************************************/
I2C_TransferReturn_TypeDef I2C_TransferInit(I2C_TypeDef *i2c,
I2C_TransferSeq_TypeDef *seq)
{
I2C_Transfer_TypeDef *transfer;
EFM_ASSERT(I2C_REF_VALID(i2c));
EFM_ASSERT(seq);
/* Support up to 2 I2C buses */
if (i2c == I2C0) {
transfer = i2cTransfer;
}
#if (I2C_COUNT > 1)
else if (i2c == I2C1) {
transfer = i2cTransfer + 1;
}
#endif
#if (I2C_COUNT > 2)
else if (i2c == I2C2) {
transfer = i2cTransfer + 2;
}
#endif
else {
return i2cTransferUsageFault;
}
/* Check if in busy state. Since this SW assumes single master, we can */
/* just issue an abort. The BUSY state is normal after a reset. */
if (i2c->STATE & I2C_STATE_BUSY) {
i2c->CMD = I2C_CMD_ABORT;
}
/* Make sure user is not trying to read 0 bytes, it is not */
/* possible according to I2C spec, since slave will always start */
/* sending first byte ACK on address. The read operation can */
/* only be stopped by NACKing a received byte, ie minimum 1 byte. */
if (((seq->flags & I2C_FLAG_READ) && !(seq->buf[0].len))
|| ((seq->flags & I2C_FLAG_WRITE_READ) && !(seq->buf[1].len))
) {
return i2cTransferUsageFault;
}
/* Prepare for a transfer */
transfer->state = i2cStateStartAddrSend;
transfer->result = i2cTransferInProgress;
transfer->offset = 0;
transfer->bufIndx = 0;
transfer->seq = seq;
/* Ensure buffers are empty */
i2c->CMD = I2C_CMD_CLEARPC | I2C_CMD_CLEARTX;
if (i2c->IF & I2C_IF_RXDATAV) {
(void)i2c->RXDATA;
}
/* Clear all pending interrupts prior to starting transfer. */
i2c->IFC = _I2C_IFC_MASK;
/* Enable those interrupts we are interested in throughout transfer. */
/* Notice that the I2C interrupt must also be enabled in the NVIC, but */
/* that is left for an additional driver wrapper. */
i2c->IEN |= I2C_IF_NACK | I2C_IF_ACK | I2C_IF_MSTOP
| I2C_IF_RXDATAV | I2C_IF_ERRORS;
/* Start transfer */
return I2C_Transfer(i2c);
}
/** @} (end addtogroup I2C) */
/** @} (end addtogroup emlib) */
#endif /* defined(I2C_COUNT) && (I2C_COUNT > 0) */

View File

@ -1,355 +0,0 @@
/***************************************************************************//**
* @file em_ldma.c
* @brief Direct memory access (LDMA) module peripheral API
* @version 5.2.2
*******************************************************************************
* # License
* <b>Copyright 2016 Silicon Laboratories, Inc. http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.@n
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.@n
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "em_ldma.h"
#if defined(LDMA_PRESENT) && (LDMA_COUNT == 1)
#include <stddef.h>
#include "em_assert.h"
#include "em_bus.h"
#include "em_cmu.h"
#include "em_core.h"
/***************************************************************************//**
* @addtogroup emlib
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup LDMA
* @{
******************************************************************************/
#if defined(LDMA_IRQ_HANDLER_TEMPLATE)
/***************************************************************************//**
* @brief
* Template for an LDMA IRQ handler.
******************************************************************************/
void LDMA_IRQHandler(void)
{
uint32_t ch;
/* Get all pending and enabled interrupts. */
uint32_t pending = LDMA_IntGetEnabled();
/* Loop here on an LDMA error to enable debugging. */
while (pending & LDMA_IF_ERROR) {
}
/* Iterate over all LDMA channels. */
for (ch = 0; ch < DMA_CHAN_COUNT; ch++) {
uint32_t mask = 0x1 << ch;
if (pending & mask) {
/* Clear interrupt flag. */
LDMA->IFC = mask;
/* Do more stuff here, execute callbacks etc. */
}
}
}
#endif
/***************************************************************************//**
* @brief
* De-initialize the LDMA controller.
*
* LDMA interrupts are disabled and the LDMA clock is stopped.
******************************************************************************/
void LDMA_DeInit(void)
{
NVIC_DisableIRQ(LDMA_IRQn);
LDMA->IEN = 0;
LDMA->CHEN = 0;
CMU_ClockEnable(cmuClock_LDMA, false);
}
/***************************************************************************//**
* @brief
* Enable or disable a LDMA channel request.
*
* @details
* Use this function to enable or disable a LDMA channel request. This will
* prevent the LDMA from proceeding after its current transaction if disabled.
*
* @param[in] channel
* LDMA channel to enable or disable requests on.
*
* @param[in] enable
* If 'true' request will be enabled. If 'false' request will be disabled.
******************************************************************************/
void LDMA_EnableChannelRequest(int ch, bool enable)
{
EFM_ASSERT(ch < DMA_CHAN_COUNT);
BUS_RegBitWrite(&LDMA->REQDIS, ch, !enable);
}
/***************************************************************************//**
* @brief
* Initialize the LDMA controller.
*
* @details
* This function will disable all the LDMA channels and enable the LDMA bus
* clock in the CMU. This function will also enable the LDMA IRQ in the NVIC
* and set the LDMA IRQ priority to a user configurable priority. The LDMA
* interrupt priority is configured using the @ref LDMA_Init_t structure.
*
* @note
* Since this function enables the LDMA IRQ you should always add a custom
* LDMA_IRQHandler to the application in order to handle any interrupts
* from LDMA.
*
* @param[in] init
* Pointer to initialization structure used to configure the LDMA.
******************************************************************************/
void LDMA_Init(const LDMA_Init_t *init)
{
EFM_ASSERT(init != NULL);
EFM_ASSERT(!((init->ldmaInitCtrlNumFixed << _LDMA_CTRL_NUMFIXED_SHIFT)
& ~_LDMA_CTRL_NUMFIXED_MASK));
EFM_ASSERT(!((init->ldmaInitCtrlSyncPrsClrEn << _LDMA_CTRL_SYNCPRSCLREN_SHIFT)
& ~_LDMA_CTRL_SYNCPRSCLREN_MASK));
EFM_ASSERT(!((init->ldmaInitCtrlSyncPrsSetEn << _LDMA_CTRL_SYNCPRSSETEN_SHIFT)
& ~_LDMA_CTRL_SYNCPRSSETEN_MASK));
EFM_ASSERT(init->ldmaInitIrqPriority < (1 << __NVIC_PRIO_BITS));
CMU_ClockEnable(cmuClock_LDMA, true);
LDMA->CTRL = (init->ldmaInitCtrlNumFixed << _LDMA_CTRL_NUMFIXED_SHIFT)
| (init->ldmaInitCtrlSyncPrsClrEn << _LDMA_CTRL_SYNCPRSCLREN_SHIFT)
| (init->ldmaInitCtrlSyncPrsSetEn << _LDMA_CTRL_SYNCPRSSETEN_SHIFT);
LDMA->CHEN = 0;
LDMA->DBGHALT = 0;
LDMA->REQDIS = 0;
/* Enable LDMA error interrupt. */
LDMA->IEN = LDMA_IEN_ERROR;
LDMA->IFC = 0xFFFFFFFF;
NVIC_ClearPendingIRQ(LDMA_IRQn);
/* Range is 0..7, 0 is highest priority. */
NVIC_SetPriority(LDMA_IRQn, init->ldmaInitIrqPriority);
NVIC_EnableIRQ(LDMA_IRQn);
}
/***************************************************************************//**
* @brief
* Start a DMA transfer.
*
* @param[in] ch
* DMA channel.
*
* @param[in] transfer
* Initialization structure used to configure the transfer.
*
* @param[in] descriptor
* Transfer descriptor, can be an array of descriptors linked together.
******************************************************************************/
void LDMA_StartTransfer(int ch,
const LDMA_TransferCfg_t *transfer,
const LDMA_Descriptor_t *descriptor)
{
uint32_t tmp;
CORE_DECLARE_IRQ_STATE;
uint32_t chMask = 1 << ch;
EFM_ASSERT(ch < DMA_CHAN_COUNT);
EFM_ASSERT(transfer != NULL);
EFM_ASSERT(!(transfer->ldmaReqSel & ~_LDMA_CH_REQSEL_MASK));
EFM_ASSERT(!((transfer->ldmaCtrlSyncPrsClrOff << _LDMA_CTRL_SYNCPRSCLREN_SHIFT)
& ~_LDMA_CTRL_SYNCPRSCLREN_MASK));
EFM_ASSERT(!((transfer->ldmaCtrlSyncPrsClrOn << _LDMA_CTRL_SYNCPRSCLREN_SHIFT)
& ~_LDMA_CTRL_SYNCPRSCLREN_MASK));
EFM_ASSERT(!((transfer->ldmaCtrlSyncPrsSetOff << _LDMA_CTRL_SYNCPRSSETEN_SHIFT)
& ~_LDMA_CTRL_SYNCPRSSETEN_MASK));
EFM_ASSERT(!((transfer->ldmaCtrlSyncPrsSetOn << _LDMA_CTRL_SYNCPRSSETEN_SHIFT)
& ~_LDMA_CTRL_SYNCPRSSETEN_MASK));
EFM_ASSERT(!((transfer->ldmaCfgArbSlots << _LDMA_CH_CFG_ARBSLOTS_SHIFT)
& ~_LDMA_CH_CFG_ARBSLOTS_MASK));
EFM_ASSERT(!((transfer->ldmaCfgSrcIncSign << _LDMA_CH_CFG_SRCINCSIGN_SHIFT)
& ~_LDMA_CH_CFG_SRCINCSIGN_MASK) );
EFM_ASSERT(!((transfer->ldmaCfgDstIncSign << _LDMA_CH_CFG_DSTINCSIGN_SHIFT)
& ~_LDMA_CH_CFG_DSTINCSIGN_MASK));
EFM_ASSERT(!((transfer->ldmaLoopCnt << _LDMA_CH_LOOP_LOOPCNT_SHIFT)
& ~_LDMA_CH_LOOP_LOOPCNT_MASK));
LDMA->CH[ch].REQSEL = transfer->ldmaReqSel;
LDMA->CH[ch].LOOP = (transfer->ldmaLoopCnt << _LDMA_CH_LOOP_LOOPCNT_SHIFT);
LDMA->CH[ch].CFG = (transfer->ldmaCfgArbSlots << _LDMA_CH_CFG_ARBSLOTS_SHIFT)
| (transfer->ldmaCfgSrcIncSign << _LDMA_CH_CFG_SRCINCSIGN_SHIFT)
| (transfer->ldmaCfgDstIncSign << _LDMA_CH_CFG_DSTINCSIGN_SHIFT);
/* Set descriptor address. */
LDMA->CH[ch].LINK = (uint32_t)descriptor & _LDMA_CH_LINK_LINKADDR_MASK;
/* Clear pending channel interrupt. */
LDMA->IFC = chMask;
/* Critical region. */
CORE_ENTER_ATOMIC();
/* Enable channel interrupt. */
LDMA->IEN |= chMask;
if (transfer->ldmaReqDis) {
LDMA->REQDIS |= chMask;
}
if (transfer->ldmaDbgHalt) {
LDMA->DBGHALT |= chMask;
}
tmp = LDMA->CTRL;
if (transfer->ldmaCtrlSyncPrsClrOff) {
tmp &= ~_LDMA_CTRL_SYNCPRSCLREN_MASK
| (~transfer->ldmaCtrlSyncPrsClrOff << _LDMA_CTRL_SYNCPRSCLREN_SHIFT);
}
if (transfer->ldmaCtrlSyncPrsClrOn) {
tmp |= transfer->ldmaCtrlSyncPrsClrOn << _LDMA_CTRL_SYNCPRSCLREN_SHIFT;
}
if (transfer->ldmaCtrlSyncPrsSetOff) {
tmp &= ~_LDMA_CTRL_SYNCPRSSETEN_MASK
| (~transfer->ldmaCtrlSyncPrsSetOff << _LDMA_CTRL_SYNCPRSSETEN_SHIFT);
}
if (transfer->ldmaCtrlSyncPrsSetOn) {
tmp |= transfer->ldmaCtrlSyncPrsSetOn << _LDMA_CTRL_SYNCPRSSETEN_SHIFT;
}
LDMA->CTRL = tmp;
BUS_RegMaskedClear(&LDMA->CHDONE, chMask); /* Clear the done flag. */
LDMA->LINKLOAD = chMask; /* Start transfer by loading descriptor. */
/* Critical region end. */
CORE_EXIT_ATOMIC();
}
/***************************************************************************//**
* @brief
* Stop a DMA transfer.
*
* @note
* The DMA will complete the current AHB burst transfer before stopping.
*
* @param[in] ch
* DMA channel to stop.
******************************************************************************/
void LDMA_StopTransfer(int ch)
{
uint32_t chMask = 1 << ch;
EFM_ASSERT(ch < DMA_CHAN_COUNT);
CORE_ATOMIC_SECTION(
LDMA->IEN &= ~chMask;
BUS_RegMaskedClear(&LDMA->CHEN, chMask);
)
}
/***************************************************************************//**
* @brief
* Check if a DMA transfer has completed.
*
* @param[in] ch
* DMA channel to check.
*
* @return
* True if transfer has completed, false if not.
******************************************************************************/
bool LDMA_TransferDone(int ch)
{
bool retVal = false;
uint32_t chMask = 1 << ch;
EFM_ASSERT(ch < DMA_CHAN_COUNT);
CORE_ATOMIC_SECTION(
if (((LDMA->CHEN & chMask) == 0)
&& ((LDMA->CHDONE & chMask) == chMask)) {
retVal = true;
}
)
return retVal;
}
/***************************************************************************//**
* @brief
* Get number of items remaining in a transfer.
*
* @note
* This function is does not take into account that a DMA transfers with
* a chain of linked transfers might be ongoing. It will only check the
* count for the current transfer.
*
* @param[in] ch
* The channel number of the transfer to check.
*
* @return
* Number of items remaining in the transfer.
******************************************************************************/
uint32_t LDMA_TransferRemainingCount(int ch)
{
uint32_t remaining, done, iflag;
uint32_t chMask = 1 << ch;
EFM_ASSERT(ch < DMA_CHAN_COUNT);
CORE_ATOMIC_SECTION(
iflag = LDMA->IF;
done = LDMA->CHDONE;
remaining = LDMA->CH[ch].CTRL;
)
iflag &= chMask;
done &= chMask;
remaining = (remaining & _LDMA_CH_CTRL_XFERCNT_MASK)
>> _LDMA_CH_CTRL_XFERCNT_SHIFT;
if (done || ((remaining == 0) && iflag)) {
return 0;
}
return remaining + 1;
}
/** @} (end addtogroup LDMA) */
/** @} (end addtogroup emlib) */
#endif /* defined( LDMA_PRESENT ) && ( LDMA_COUNT == 1 ) */

File diff suppressed because it is too large Load Diff

View File

@ -1,114 +0,0 @@
/***************************************************************************//**
* @file em_system.c
* @brief System Peripheral API
* @version 5.2.2
*******************************************************************************
* # License
* <b>Copyright 2016 Silicon Laboratories, Inc. http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "em_system.h"
#include "em_assert.h"
#include <stddef.h>
/***************************************************************************//**
* @addtogroup emlib
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup SYSTEM
* @{
******************************************************************************/
/*******************************************************************************
************************** GLOBAL FUNCTIONS *******************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Get chip major/minor revision.
*
* @param[out] rev
* Location to place chip revision info.
******************************************************************************/
void SYSTEM_ChipRevisionGet(SYSTEM_ChipRevision_TypeDef *rev)
{
uint8_t tmp;
EFM_ASSERT(rev);
/* CHIP FAMILY bit [5:2] */
tmp = (((ROMTABLE->PID1 & _ROMTABLE_PID1_FAMILYMSB_MASK) >> _ROMTABLE_PID1_FAMILYMSB_SHIFT) << 2);
/* CHIP FAMILY bit [1:0] */
tmp |= ((ROMTABLE->PID0 & _ROMTABLE_PID0_FAMILYLSB_MASK) >> _ROMTABLE_PID0_FAMILYLSB_SHIFT);
rev->family = tmp;
/* CHIP MAJOR bit [3:0] */
rev->major = (ROMTABLE->PID0 & _ROMTABLE_PID0_REVMAJOR_MASK) >> _ROMTABLE_PID0_REVMAJOR_SHIFT;
/* CHIP MINOR bit [7:4] */
tmp = (((ROMTABLE->PID2 & _ROMTABLE_PID2_REVMINORMSB_MASK) >> _ROMTABLE_PID2_REVMINORMSB_SHIFT) << 4);
/* CHIP MINOR bit [3:0] */
tmp |= ((ROMTABLE->PID3 & _ROMTABLE_PID3_REVMINORLSB_MASK) >> _ROMTABLE_PID3_REVMINORLSB_SHIFT);
rev->minor = tmp;
}
/***************************************************************************//**
* @brief
* Get factory calibration value for a given peripheral register.
*
* @param[in] regAddress
* Peripheral calibration register address to get calibration value for. If
* a calibration value is found then this register is updated with the
* calibration value.
*
* @return
* True if a calibration value exists, false otherwise.
******************************************************************************/
bool SYSTEM_GetCalibrationValue(volatile uint32_t *regAddress)
{
SYSTEM_CalAddrVal_TypeDef * p, * end;
p = (SYSTEM_CalAddrVal_TypeDef *)(DEVINFO_BASE & 0xFFFFF000);
end = (SYSTEM_CalAddrVal_TypeDef *)DEVINFO_BASE;
for (; p < end; p++) {
if (p->address == 0xFFFFFFFF) {
/* Found table terminator */
return false;
}
if (p->address == (uint32_t)regAddress) {
*regAddress = p->calValue;
return true;
}
}
/* Nothing found for regAddress */
return false;
}
/** @} (end addtogroup SYSTEM) */
/** @} (end addtogroup emlib) */

View File

@ -1,253 +0,0 @@
/***************************************************************************//**
* @file em_timer.c
* @brief Timer/counter (TIMER) Peripheral API
* @version 5.2.2
*******************************************************************************
* # License
* <b>Copyright 2016 Silicon Laboratories, Inc. http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "em_timer.h"
#if defined(TIMER_COUNT) && (TIMER_COUNT > 0)
#include "em_assert.h"
/***************************************************************************//**
* @addtogroup emlib
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup TIMER
* @brief Timer/Counter (TIMER) Peripheral API
* @details
* The timer module consists of three main parts:
* @li General timer config and enable control.
* @li Compare/capture control.
* @li Dead time insertion control (may not be available for all timers).
* @{
******************************************************************************/
/*******************************************************************************
************************** GLOBAL FUNCTIONS *******************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Initialize TIMER.
*
* @details
* Notice that counter top must be configured separately with for instance
* TIMER_TopSet(). In addition, compare/capture and dead-time insertion
* init must be initialized separately if used. That should probably
* be done prior to the use of this function if configuring the TIMER to
* start when initialization is completed.
*
* @param[in] timer
* Pointer to TIMER peripheral register block.
*
* @param[in] init
* Pointer to TIMER initialization structure.
******************************************************************************/
void TIMER_Init(TIMER_TypeDef *timer, const TIMER_Init_TypeDef *init)
{
EFM_ASSERT(TIMER_REF_VALID(timer));
/* Stop timer if specified to be disabled (dosn't hurt if already stopped) */
if (!(init->enable)) {
timer->CMD = TIMER_CMD_STOP;
}
/* Reset counter */
timer->CNT = _TIMER_CNT_RESETVALUE;
timer->CTRL = ((uint32_t)(init->prescale) << _TIMER_CTRL_PRESC_SHIFT)
| ((uint32_t)(init->clkSel) << _TIMER_CTRL_CLKSEL_SHIFT)
| ((uint32_t)(init->fallAction) << _TIMER_CTRL_FALLA_SHIFT)
| ((uint32_t)(init->riseAction) << _TIMER_CTRL_RISEA_SHIFT)
| ((uint32_t)(init->mode) << _TIMER_CTRL_MODE_SHIFT)
| (init->debugRun ? TIMER_CTRL_DEBUGRUN : 0)
| (init->dmaClrAct ? TIMER_CTRL_DMACLRACT : 0)
| (init->quadModeX4 ? TIMER_CTRL_QDM_X4 : 0)
| (init->oneShot ? TIMER_CTRL_OSMEN : 0)
#if defined(TIMER_CTRL_X2CNT) && defined(TIMER_CTRL_ATI)
| (init->count2x ? TIMER_CTRL_X2CNT : 0)
| (init->ati ? TIMER_CTRL_ATI : 0)
#endif
| (init->sync ? TIMER_CTRL_SYNC : 0);
/* Start timer if specified to be enabled (dosn't hurt if already started) */
if (init->enable) {
timer->CMD = TIMER_CMD_START;
}
}
/***************************************************************************//**
* @brief
* Initialize TIMER compare/capture channel.
*
* @details
* Notice that if operating channel in compare mode, the CCV and CCVB register
* must be set separately as required.
*
* @param[in] timer
* Pointer to TIMER peripheral register block.
*
* @param[in] ch
* Compare/capture channel to init for.
*
* @param[in] init
* Pointer to TIMER initialization structure.
******************************************************************************/
void TIMER_InitCC(TIMER_TypeDef *timer,
unsigned int ch,
const TIMER_InitCC_TypeDef *init)
{
EFM_ASSERT(TIMER_REF_VALID(timer));
EFM_ASSERT(TIMER_CH_VALID(ch));
timer->CC[ch].CTRL =
((uint32_t)(init->eventCtrl) << _TIMER_CC_CTRL_ICEVCTRL_SHIFT)
| ((uint32_t)(init->edge) << _TIMER_CC_CTRL_ICEDGE_SHIFT)
| ((uint32_t)(init->prsSel) << _TIMER_CC_CTRL_PRSSEL_SHIFT)
| ((uint32_t)(init->cufoa) << _TIMER_CC_CTRL_CUFOA_SHIFT)
| ((uint32_t)(init->cofoa) << _TIMER_CC_CTRL_COFOA_SHIFT)
| ((uint32_t)(init->cmoa) << _TIMER_CC_CTRL_CMOA_SHIFT)
| ((uint32_t)(init->mode) << _TIMER_CC_CTRL_MODE_SHIFT)
| (init->filter ? TIMER_CC_CTRL_FILT_ENABLE : 0)
| (init->prsInput ? TIMER_CC_CTRL_INSEL_PRS : 0)
| (init->coist ? TIMER_CC_CTRL_COIST : 0)
| (init->outInvert ? TIMER_CC_CTRL_OUTINV : 0);
}
#if defined(_TIMER_DTCTRL_MASK)
/***************************************************************************//**
* @brief
* Initialize the TIMER DTI unit.
*
* @param[in] timer
* Pointer to TIMER peripheral register block.
*
* @param[in] init
* Pointer to TIMER DTI initialization structure.
******************************************************************************/
void TIMER_InitDTI(TIMER_TypeDef *timer, const TIMER_InitDTI_TypeDef *init)
{
EFM_ASSERT(TIMER0 == timer);
/* Make sure the DTI unit is disabled while initializing. */
TIMER_EnableDTI(timer, false);
/* Setup the DTCTRL register.
The enable bit will be set at the end of the function if specified. */
timer->DTCTRL =
(init->autoRestart ? TIMER_DTCTRL_DTDAS : 0)
| (init->activeLowOut ? TIMER_DTCTRL_DTIPOL : 0)
| (init->invertComplementaryOut ? TIMER_DTCTRL_DTCINV : 0)
| (init->enablePrsSource ? TIMER_DTCTRL_DTPRSEN : 0)
| ((uint32_t)(init->prsSel) << _TIMER_DTCTRL_DTPRSSEL_SHIFT);
/* Setup the DTTIME register. */
timer->DTTIME =
((uint32_t)(init->prescale) << _TIMER_DTTIME_DTPRESC_SHIFT)
| ((uint32_t)(init->riseTime) << _TIMER_DTTIME_DTRISET_SHIFT)
| ((uint32_t)(init->fallTime) << _TIMER_DTTIME_DTFALLT_SHIFT);
/* Setup the DTFC register. */
timer->DTFC =
(init->enableFaultSourceCoreLockup ? TIMER_DTFC_DTLOCKUPFEN : 0)
| (init->enableFaultSourceDebugger ? TIMER_DTFC_DTDBGFEN : 0)
| (init->enableFaultSourcePrsSel0 ? TIMER_DTFC_DTPRS0FEN : 0)
| (init->enableFaultSourcePrsSel1 ? TIMER_DTFC_DTPRS1FEN : 0)
| ((uint32_t)(init->faultAction) << _TIMER_DTFC_DTFA_SHIFT)
| ((uint32_t)(init->faultSourcePrsSel0) << _TIMER_DTFC_DTPRS0FSEL_SHIFT)
| ((uint32_t)(init->faultSourcePrsSel1) << _TIMER_DTFC_DTPRS1FSEL_SHIFT);
/* Setup the DTOGEN register. */
timer->DTOGEN = init->outputsEnableMask;
/* Clear any previous DTI faults. */
TIMER_ClearDTIFault(timer, TIMER_GetDTIFault(timer));
/* Enable/disable before returning. */
TIMER_EnableDTI(timer, init->enable);
}
#endif
/***************************************************************************//**
* @brief
* Reset TIMER to same state as after a HW reset.
*
* @note
* The ROUTE register is NOT reset by this function, in order to allow for
* centralized setup of this feature.
*
* @param[in] timer
* Pointer to TIMER peripheral register block.
******************************************************************************/
void TIMER_Reset(TIMER_TypeDef *timer)
{
int i;
EFM_ASSERT(TIMER_REF_VALID(timer));
/* Make sure disabled first, before resetting other registers */
timer->CMD = TIMER_CMD_STOP;
timer->CTRL = _TIMER_CTRL_RESETVALUE;
timer->IEN = _TIMER_IEN_RESETVALUE;
timer->IFC = _TIMER_IFC_MASK;
timer->TOPB = _TIMER_TOPB_RESETVALUE;
/* Write TOP after TOPB to invalidate TOPB (clear TIMER_STATUS_TOPBV) */
timer->TOP = _TIMER_TOP_RESETVALUE;
timer->CNT = _TIMER_CNT_RESETVALUE;
/* Do not reset route register, setting should be done independently */
/* (Note: ROUTE register may be locked by DTLOCK register.) */
for (i = 0; TIMER_CH_VALID(i); i++) {
timer->CC[i].CTRL = _TIMER_CC_CTRL_RESETVALUE;
timer->CC[i].CCV = _TIMER_CC_CCV_RESETVALUE;
timer->CC[i].CCVB = _TIMER_CC_CCVB_RESETVALUE;
}
/* Reset dead time insertion module, no effect on timers without DTI */
#if defined(TIMER_DTLOCK_LOCKKEY_UNLOCK)
/* Unlock DTI registers first in case locked */
timer->DTLOCK = TIMER_DTLOCK_LOCKKEY_UNLOCK;
timer->DTCTRL = _TIMER_DTCTRL_RESETVALUE;
timer->DTTIME = _TIMER_DTTIME_RESETVALUE;
timer->DTFC = _TIMER_DTFC_RESETVALUE;
timer->DTOGEN = _TIMER_DTOGEN_RESETVALUE;
timer->DTFAULTC = _TIMER_DTFAULTC_MASK;
#endif
}
/** @} (end addtogroup TIMER) */
/** @} (end addtogroup emlib) */
#endif /* defined(TIMER_COUNT) && (TIMER_COUNT > 0) */

File diff suppressed because it is too large Load Diff

View File

@ -1,48 +0,0 @@
//=========================================================
// inc/InitDevice.h: generated by Hardware Configurator
//
// This file will be regenerated when saving a document.
// leave the sections inside the "$[...]" comment tags alone
// or they will be overwritten!
//=========================================================
#ifndef __INIT_DEVICE_H__
#define __INIT_DEVICE_H__
// USER CONSTANTS
// USER PROTOTYPES
// $[Mode Transition Prototypes]
extern void enter_DefaultMode_from_RESET(void);
// [Mode Transition Prototypes]$
// $[Config(Per-Module Mode)Transition Prototypes]
extern void EMU_enter_DefaultMode_from_RESET(void);
extern void LFXO_enter_DefaultMode_from_RESET(void);
extern void CMU_enter_DefaultMode_from_RESET(void);
extern void ADC0_enter_DefaultMode_from_RESET(void);
extern void ACMP0_enter_DefaultMode_from_RESET(void);
extern void ACMP1_enter_DefaultMode_from_RESET(void);
extern void IDAC0_enter_DefaultMode_from_RESET(void);
extern void RTCC_enter_DefaultMode_from_RESET(void);
extern void USART0_enter_DefaultMode_from_RESET(void);
extern void USART1_enter_DefaultMode_from_RESET(void);
extern void LEUART0_enter_DefaultMode_from_RESET(void);
extern void WDOG0_enter_DefaultMode_from_RESET(void);
extern void I2C0_enter_DefaultMode_from_RESET(void);
extern void GPCRC_enter_DefaultMode_from_RESET(void);
extern void LDMA_enter_DefaultMode_from_RESET(void);
extern void TIMER0_enter_DefaultMode_from_RESET(void);
extern void TIMER1_enter_DefaultMode_from_RESET(void);
extern void LETIMER0_enter_DefaultMode_from_RESET(void);
extern void CRYOTIMER_enter_DefaultMode_from_RESET(void);
extern void PCNT0_enter_DefaultMode_from_RESET(void);
extern void PRS_enter_DefaultMode_from_RESET(void);
extern void PORTIO_enter_DefaultMode_from_RESET(void);
// [Config(Per-Module Mode)Transition Prototypes]$
// $[User-defined pin name abstraction]
// [User-defined pin name abstraction]$
#endif

View File

@ -1,56 +0,0 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Solo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
/*
* app.h
*
* Created on: Jun 26, 2018
* Author: conor
*/
#ifndef SRC_APP_H_
#define SRC_APP_H_
#define DEBUG_LEVEL 1
//#define PRINTING_USE_VCOM
//#define USING_DEV_BOARD
//#define ENABLE_U2F_EXTENSIONS
#define ENABLE_U2F
//#define DISABLE_CTAPHID_PING
//#define DISABLE_CTAPHID_WINK
//#define DISABLE_CTAPHID_CBOR
void printing_init();
//#define TEST
//#define TEST_POWER
// GPIO assignments
#define NFC_DEV_SS gpioPortF,2
#define LED_INIT_VALUE 0x001000
#endif /* SRC_APP_H_ */

View File

@ -1,278 +0,0 @@
/*
* Configuration for enabling CRYPTO hardware acceleration in all mbedtls
* modules when running on SiliconLabs devices.
*
* Copyright (C) 2016, Silicon Labs, http://www.silabs.com
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @defgroup sl_crypto_config Silicon Labs CRYPTO Hardware Acceleration Configuration
* @addtogroup sl_crypto_config
*
* @brief
* mbed TLS configuration for Silicon Labs CRYPTO hardware acceleration
*
* @details
* mbed TLS configuration is composed of settings in this Silicon Labs specific CRYPTO hardware acceleration file located in mbedtls/configs and the mbed TLS configuration file in mbedtls/include/mbedtls/config.h.
* This configuration can be used as a starting point to evaluate hardware acceleration available on Silicon Labs devices.
*
* @{
*/
#ifndef MBEDTLS_CONFIG_SL_CRYPTO_ALL_ACCELERATION_H
#define MBEDTLS_CONFIG_SL_CRYPTO_ALL_ACCELERATION_H
#include "em_device.h"
#if !defined(NO_CRYPTO_ACCELERATION)
/**
* @name SECTION: Silicon Labs Acceleration settings
*
* This section sets Silicon Labs Acceleration settings.
* @{
*/
/**
* \def MBEDTLS_AES_ALT
*
* Enable hardware acceleration for the AES block cipher
*
* Module: sl_crypto/src/crypto_aes.c for devices with CRYPTO
* sl_crypto/src/aes_aes.c for devices with AES
*
* See MBEDTLS_AES_C for more information.
*/
#define MBEDTLS_AES_ALT
#define MBEDTLS_ECP_ALT
/**
* \def MBEDTLS_ECP_INTERNAL_ALT
* \def ECP_SHORTWEIERSTRASS
* \def MBEDTLS_ECP_ADD_MIXED_ALT
* \def MBEDTLS_ECP_DOUBLE_JAC_ALT
* \def MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT
* \def MBEDTLS_ECP_NORMALIZE_JAC_ALT
*
* Enable hardware acceleration for the elliptic curve over GF(p) library.
*
* Module: sl_crypto/src/crypto_ecp.c
* Caller: library/ecp.c
*
* Requires: MBEDTLS_BIGNUM_C, MBEDTLS_ECP_C and at least one
* MBEDTLS_ECP_DP_XXX_ENABLED and (CRYPTO_COUNT > 0)
*/
#if defined(CRYPTO_COUNT) && (CRYPTO_COUNT > 0)
#define MBEDTLS_ECP_INTERNAL_ALT
#define ECP_SHORTWEIERSTRASS
#define MBEDTLS_ECP_ADD_MIXED_ALT
#define MBEDTLS_ECP_DOUBLE_JAC_ALT
#define MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT
#define MBEDTLS_ECP_NORMALIZE_JAC_ALT
#define MBEDTLS_ECP_RANDOMIZE_JAC_ALT
#endif
/**
* \def MBEDTLS_SHA1_ALT
*
* Enable hardware acceleration for the SHA1 cryptographic hash algorithm.
*
* Module: sl_crypto/src/crypto_sha.c
* Caller: library/mbedtls_md.c
* library/ssl_cli.c
* library/ssl_srv.c
* library/ssl_tls.c
* library/x509write_crt.c
*
* Requires: MBEDTLS_SHA1_C and (CRYPTO_COUNT > 0)
* See MBEDTLS_SHA1_C for more information.
*/
#if defined(CRYPTO_COUNT) && (CRYPTO_COUNT > 0)
#define MBEDTLS_SHA1_ALT
#endif
/**
* \def MBEDTLS_SHA256_ALT
*
* Enable hardware acceleration for the SHA-224 and SHA-256 cryptographic
* hash algorithms.
*
* Module: sl_crypto/src/crypto_sha.c
* Caller: library/entropy.c
* library/mbedtls_md.c
* library/ssl_cli.c
* library/ssl_srv.c
* library/ssl_tls.c
*
* Requires: MBEDTLS_SHA256_C and (CRYPTO_COUNT > 0)
* See MBEDTLS_SHA256_C for more information.
*/
#if defined(CRYPTO_COUNT) && (CRYPTO_COUNT > 0)
#define MBEDTLS_SHA256_ALT
#endif
#endif /* #if !defined(NO_CRYPTO_ACCELERATION) */
/**
* \def MBEDTLS_TRNG_C
*
* Enable software support for the True Random Number Generator (TRNG)
* incorporated from Series 1 Configuration 2 devices (EFR32MG12, etc.)
* from Silicon Labs.
*
* TRNG is not supported by software for EFR32XG13 (SDID_89) and
* EFR32XG14 (SDID_95).
*
* Requires TRNG_PRESENT &&
* !(_SILICON_LABS_GECKO_INTERNAL_SDID_89 ||
* _SILICON_LABS_GECKO_INTERNAL_SDID_95)
*/
#if defined(TRNG_PRESENT) && \
!(defined(_SILICON_LABS_GECKO_INTERNAL_SDID_89) || \
defined(_SILICON_LABS_GECKO_INTERNAL_SDID_95))
#define MBEDTLS_TRNG_C
#endif
/**
* \def MBEDTLS_ENTROPY_ADC_C
*
* Enable software support for the retrieving entropy data from the ADC
* incorporated on devices from Silicon Labs.
*
* Requires ADC_PRESENT && _ADC_SINGLECTRLX_VREFSEL_VENTROPY
*/
#if defined(ADC_PRESENT) && defined(_ADC_SINGLECTRLX_VREFSEL_VENTROPY)
#define MBEDTLS_ENTROPY_ADC_C
#endif
/**
* \def MBEDTLS_ENTROPY_ADC_INSTANCE
*
* Specify which ADC instance shall be used as entropy source.
*
* Requires MBEDTLS_ENTROPY_ADC_C
*/
#if defined(MBEDTLS_ENTROPY_ADC_C)
#define MBEDTLS_ENTROPY_ADC_INSTANCE (0)
#endif
/**
* \def MBEDTLS_ENTROPY_RAIL_C
*
* Enable software support for the retrieving entropy data from the RAIL
* incorporated on devices from Silicon Labs.
*
* Requires _EFR_DEVICE
*/
#if defined(_EFR_DEVICE)
#define MBEDTLS_ENTROPY_RAIL_C
#endif
/**
* \def MBEDTLS_ENTROPY_HARDWARE_ALT_RAIL
*
* Use the radio (RAIL) as default hardware entropy source.
*
* Requires MBEDTLS_ENTROPY_RAIL_C && _EFR_DEVICE && !MBEDTLS_TRNG_C
*/
#if defined(MBEDTLS_ENTROPY_RAIL_C) && \
defined(_EFR_DEVICE) && !defined(MBEDTLS_TRNG_C)
#define MBEDTLS_ENTROPY_HARDWARE_ALT_RAIL
#endif
/**
* \def MBEDTLS_ENTROPY_HARDWARE_ALT
*
* Integrate the provided default entropy source into the mbed
* TLS entropy infrastructure.
*
* Requires MBEDTLS_TRNG_C || MBEDTLS_ENTROPY_HARDWARE_ALT_RAIL
*/
#if defined(MBEDTLS_TRNG_C) || defined(MBEDTLS_ENTROPY_HARDWARE_ALT_RAIL)
#define MBEDTLS_ENTROPY_HARDWARE_ALT
#endif
/* Default ECC configuration for Silicon Labs devices: */
/* ECC curves supported by CRYPTO hardware module: */
#define MBEDTLS_ECP_DP_SECP192R1_ENABLED
#define MBEDTLS_ECP_DP_SECP224R1_ENABLED
#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
/* Save RAM by adjusting to our exact needs */
#define MBEDTLS_ECP_MAX_BITS 256
#ifndef MBEDTLS_MPI_MAX_SIZE
#define MBEDTLS_MPI_MAX_SIZE 32 // 384 bits is 48 bytes
#endif
/*
Set MBEDTLS_ECP_WINDOW_SIZE to configure
ECC point multiplication window size, see ecp.h:
2 = Save RAM at the expense of speed
3 = Improve speed at the expense of RAM
4 = Optimize speed at the expense of RAM
*/
#define MBEDTLS_ECP_WINDOW_SIZE 3
#define MBEDTLS_ECP_FIXED_POINT_OPTIM 0
/* Significant speed benefit at the expense of some ROM */
#define MBEDTLS_ECP_NIST_OPTIM
/* Include the default mbed TLS config file */
#include "mbedtls/config.h"
#undef MBEDTLS_TIMING_C
#undef MBEDTLS_FS_IO
#undef MBEDTLS_SHA512_C
#undef MBEDTLS_ENTROPY_SHA512_ACCUMULATOR
#undef MBEDTLS_NET_C
#define MBEDTLS_ECP_NORMALIZE_JAC_ALT
#define MBEDTLS_ECP_DEVICE_ALT
#define MBEDTLS_MPI_MODULAR_DIVISION_ALT
#define MBEDTLS_ECP_INTERNAL_ALT
#define ECP_SHORTWEIERSTRASS
#define MBEDTLS_ECP_ADD_MIXED_ALT
#define MBEDTLS_ECP_DOUBLE_JAC_ALT
#define MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT
#define MBEDTLS_ECP_NORMALIZE_JAC_ALT
#define MBEDTLS_ECP_RANDOMIZE_JAC_ALT
#define MBEDTLS_ECP_DEVICE_ADD_MIXED_ALT
//#define MBEDTLS_ENTROPY_ALT
//#define MBEDTLS_MPI_MUL_MPI_ALT // doesnt seem to be implemented
//#define MBEDTLS_MPI_MUL_INT_ALT // makes no difference or slightly slower
#define MBEDTLS_NO_PLATFORM_ENTROPY
/* Hardware entropy source is not yet supported. Uncomment this macro to
provide your own implementation of an entropy collector. */
//#define MBEDTLS_ENTROPY_HARDWARE_ALT
/* Exclude and/or change default config here. E.g.: */
//#undef MBEDTLS_ECP_DP_SECP384R1_ENABLED
//#undef MBEDTLS_ECP_DP_SECP521R1_ENABLED
//#undef MBEDTLS_ECP_DP_BP384R1_ENABLED
//#undef MBEDTLS_ECP_DP_BP512R1_ENABLED
//#undef MBEDTLS_SHA512_C
#include "mbedtls/check_config.h"
/** @} (end section sl_crypto_config) */
/** @} (end addtogroup sl_crypto_config) */
#endif /* MBEDTLS_CONFIG_SL_CRYPTO_ALL_ACCELERATION_H */

View File

@ -1,34 +0,0 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Solo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
/*
* nfc.h
*
* Created on: Jul 22, 2018
* Author: conor
*/
#ifndef INC_NFC_H_
#define INC_NFC_H_
void nfc_test();
#endif /* INC_NFC_H_ */

View File

@ -1,752 +0,0 @@
//=========================================================
// src/InitDevice.c: generated by Hardware Configurator
//
// This file will be regenerated when saving a document.
// leave the sections inside the "$[...]" comment tags alone
// or they will be overwritten!
//=========================================================
// USER INCLUDES
#include "InitDevice.h"
// USER PROTOTYPES
// USER FUNCTIONS
// $[Library includes]
#include "em_system.h"
#include "em_emu.h"
#include "em_cmu.h"
#include "em_device.h"
#include "em_chip.h"
#include "em_assert.h"
#include "em_adc.h"
#include "em_cryotimer.h"
#include "em_crypto.h"
#include "em_gpio.h"
#include "em_timer.h"
#include "em_usart.h"
// [Library includes]$
//==============================================================================
// enter_DefaultMode_from_RESET
//==============================================================================
extern void enter_DefaultMode_from_RESET(void) {
// $[Config Calls]
CHIP_Init();
EMU_enter_DefaultMode_from_RESET();
CMU_enter_DefaultMode_from_RESET();
ADC0_enter_DefaultMode_from_RESET();
USART0_enter_DefaultMode_from_RESET();
USART1_enter_DefaultMode_from_RESET();
TIMER0_enter_DefaultMode_from_RESET();
CRYOTIMER_enter_DefaultMode_from_RESET();
PORTIO_enter_DefaultMode_from_RESET();
// [Config Calls]$
}
//================================================================================
// EMU_enter_DefaultMode_from_RESET
//================================================================================
extern void EMU_enter_DefaultMode_from_RESET(void) {
// $[EMU Initialization]
/* External power circuit not wired for DCDC; shut down regulator */
EMU_DCDCPowerOff();
/* Initialize EM2/EM3 mode */
EMU_EM23Init_TypeDef em23Init = EMU_EM23INIT_DEFAULT;
em23Init.em23VregFullEn = 0;
EMU_EM23Init(&em23Init);
/* Initialize EM4H/S mode */
EMU_EM4Init_TypeDef em4Init = EMU_EM4INIT_DEFAULT;
em4Init.retainLfrco = 0;
em4Init.retainLfxo = 0;
em4Init.retainUlfrco = 0;
em4Init.em4State = emuEM4Shutoff;
em4Init.pinRetentionMode = emuPinRetentionDisable;
EMU_EM4Init(&em4Init);
// [EMU Initialization]$
}
//================================================================================
// LFXO_enter_DefaultMode_from_RESET
//================================================================================
extern void LFXO_enter_DefaultMode_from_RESET(void) {
}
//================================================================================
// CMU_enter_DefaultMode_from_RESET
//================================================================================
extern void CMU_enter_DefaultMode_from_RESET(void) {
// $[High Frequency Clock Setup]
/* Initializing HFXO */
CMU_HFXOInit_TypeDef hfxoInit = CMU_HFXOINIT_DEFAULT;
CMU_HFXOInit(&hfxoInit);
/* Setting system HFRCO frequency */
CMU_HFRCOFreqSet (cmuHFRCOFreq_38M0Hz);
/* Using HFRCO as high frequency clock, HFCLK */
CMU_ClockSelectSet(cmuClock_HF, cmuSelect_HFRCO);
// [High Frequency Clock Setup]$
// $[LE clocks enable]
/* Enable ULFRCO oscillator, and wait for it to be stable */
CMU_OscillatorEnable(cmuOsc_ULFRCO, true, true);
// [LE clocks enable]$
// $[LFACLK Setup]
/* LFACLK is disabled */
// [LFACLK Setup]$
// $[LFBCLK Setup]
/* LFBCLK is disabled */
// [LFBCLK Setup]$
// $[LFECLK Setup]
/* LFECLK is disabled */
// [LFECLK Setup]$
// $[Peripheral Clock enables]
/* Enable clock for HF peripherals */
CMU_ClockEnable(cmuClock_HFPER, true);
/* Enable clock for ADC0 */
CMU_ClockEnable(cmuClock_ADC0, true);
/* Enable clock for CRYOTIMER */
CMU_ClockEnable(cmuClock_CRYOTIMER, true);
/* Enable clock for TIMER0 */
CMU_ClockEnable(cmuClock_TIMER0, true);
/* Enable clock for USART0 */
CMU_ClockEnable(cmuClock_USART0, true);
/* Enable clock for USART1 */
CMU_ClockEnable(cmuClock_USART1, true);
/* Enable clock for GPIO by default */
CMU_ClockEnable(cmuClock_GPIO, true);
// [Peripheral Clock enables]$
// $[Clock output]
/* Disable CLKOUT0 output */
CMU->CTRL = (CMU->CTRL & ~_CMU_CTRL_CLKOUTSEL0_MASK)
| CMU_CTRL_CLKOUTSEL0_DISABLED;
/* Disable CLKOUT1 output */
CMU->CTRL = (CMU->CTRL & ~_CMU_CTRL_CLKOUTSEL1_MASK)
| CMU_CTRL_CLKOUTSEL1_DISABLED;
// [Clock output]$
// $[CMU_IO]
/* Disable CLKOUT0 pin */
CMU->ROUTEPEN &= ~CMU_ROUTEPEN_CLKOUT0PEN;
/* Disable CLKOUT1 pin */
CMU->ROUTEPEN &= ~CMU_ROUTEPEN_CLKOUT1PEN;
// [CMU_IO]$
}
//================================================================================
// ADC0_enter_DefaultMode_from_RESET
//================================================================================
extern void ADC0_enter_DefaultMode_from_RESET(void) {
// $[ADC0_Init]
ADC_Init_TypeDef ADC0_init = ADC_INIT_DEFAULT;
ADC0_init.ovsRateSel = adcOvsRateSel2;
ADC0_init.warmUpMode = adcWarmupNormal;
ADC0_init.timebase = ADC_TimebaseCalc(0);
ADC0_init.prescale = ADC_PrescaleCalc(7000000, 0);
ADC0_init.tailgate = 0;
ADC0_init.em2ClockConfig = adcEm2Disabled;
ADC_Init(ADC0, &ADC0_init);
// [ADC0_Init]$
// $[ADC0_InputConfiguration]
// [ADC0_InputConfiguration]$
}
//================================================================================
// ACMP0_enter_DefaultMode_from_RESET
//================================================================================
extern void ACMP0_enter_DefaultMode_from_RESET(void) {
// $[ACMP0_Init]
// [ACMP0_Init]$
// $[ACMP0_IO]
// [ACMP0_IO]$
}
//================================================================================
// ACMP1_enter_DefaultMode_from_RESET
//================================================================================
extern void ACMP1_enter_DefaultMode_from_RESET(void) {
// $[ACMP1_Init]
// [ACMP1_Init]$
// $[ACMP1_IO]
// [ACMP1_IO]$
}
//================================================================================
// IDAC0_enter_DefaultMode_from_RESET
//================================================================================
extern void IDAC0_enter_DefaultMode_from_RESET(void) {
}
//================================================================================
// RTCC_enter_DefaultMode_from_RESET
//================================================================================
extern void RTCC_enter_DefaultMode_from_RESET(void) {
// $[Compare/Capture Channel 0 init]
// [Compare/Capture Channel 0 init]$
// $[Compare/Capture Channel 1 init]
// [Compare/Capture Channel 1 init]$
// $[Compare/Capture Channel 2 init]
// [Compare/Capture Channel 2 init]$
// $[RTCC init]
// [RTCC init]$
}
//================================================================================
// USART0_enter_DefaultMode_from_RESET
//================================================================================
extern void USART0_enter_DefaultMode_from_RESET(void) {
// $[USART_InitAsync]
USART_InitAsync_TypeDef initasync = USART_INITASYNC_DEFAULT;
initasync.enable = usartDisable;
initasync.baudrate = 115200;
initasync.databits = usartDatabits8;
initasync.parity = usartNoParity;
initasync.stopbits = usartStopbits1;
initasync.oversampling = usartOVS16;
#if defined( USART_INPUT_RXPRS ) && defined( USART_CTRL_MVDIS )
initasync.mvdis = 0;
initasync.prsRxEnable = 0;
initasync.prsRxCh = 0;
#endif
USART_InitAsync(USART0, &initasync);
// [USART_InitAsync]$
// $[USART_InitSync]
// [USART_InitSync]$
// $[USART_InitPrsTrigger]
USART_PrsTriggerInit_TypeDef initprs = USART_INITPRSTRIGGER_DEFAULT;
initprs.rxTriggerEnable = 0;
initprs.txTriggerEnable = 0;
initprs.prsTriggerChannel = usartPrsTriggerCh0;
USART_InitPrsTrigger(USART0, &initprs);
// [USART_InitPrsTrigger]$
// $[USART_InitIO]
/* Disable CLK pin */
USART0->ROUTELOC0 = (USART0->ROUTELOC0 & (~_USART_ROUTELOC0_CLKLOC_MASK))
| USART_ROUTELOC0_CLKLOC_LOC4;
USART0->ROUTEPEN = USART0->ROUTEPEN & (~USART_ROUTEPEN_CLKPEN);
/* Disable CS pin */
USART0->ROUTELOC0 = (USART0->ROUTELOC0 & (~_USART_ROUTELOC0_CSLOC_MASK))
| USART_ROUTELOC0_CSLOC_LOC3;
USART0->ROUTEPEN = USART0->ROUTEPEN & (~USART_ROUTEPEN_CSPEN);
/* Disable CTS pin */
USART0->ROUTELOC1 = (USART0->ROUTELOC1 & (~_USART_ROUTELOC1_CTSLOC_MASK))
| USART_ROUTELOC1_CTSLOC_LOC2;
USART0->ROUTEPEN = USART0->ROUTEPEN & (~USART_ROUTEPEN_CTSPEN);
/* Disable RTS pin */
USART0->ROUTELOC1 = (USART0->ROUTELOC1 & (~_USART_ROUTELOC1_RTSLOC_MASK))
| USART_ROUTELOC1_RTSLOC_LOC1;
USART0->ROUTEPEN = USART0->ROUTEPEN & (~USART_ROUTEPEN_RTSPEN);
/* Set up RX pin */
USART0->ROUTELOC0 = (USART0->ROUTELOC0 & (~_USART_ROUTELOC0_RXLOC_MASK))
| USART_ROUTELOC0_RXLOC_LOC0;
USART0->ROUTEPEN = USART0->ROUTEPEN | USART_ROUTEPEN_RXPEN;
/* Set up TX pin */
USART0->ROUTELOC0 = (USART0->ROUTELOC0 & (~_USART_ROUTELOC0_TXLOC_MASK))
| USART_ROUTELOC0_TXLOC_LOC20;
USART0->ROUTEPEN = USART0->ROUTEPEN | USART_ROUTEPEN_TXPEN;
// [USART_InitIO]$
// $[USART_Misc]
/* Disable CTS */
USART0->CTRLX = USART0->CTRLX & (~USART_CTRLX_CTSEN);
/* Set CTS active low */
USART0->CTRLX = USART0->CTRLX & (~USART_CTRLX_CTSINV);
/* Set RTS active low */
USART0->CTRLX = USART0->CTRLX & (~USART_CTRLX_RTSINV);
/* Set CS active low */
USART0->CTRL = USART0->CTRL & (~USART_CTRL_CSINV);
/* Set TX active high */
USART0->CTRL = USART0->CTRL & (~USART_CTRL_TXINV);
/* Set RX active high */
USART0->CTRL = USART0->CTRL & (~USART_CTRL_RXINV);
// [USART_Misc]$
// $[USART_Enable]
/* Enable USART if opted by user */
USART_Enable(USART0, usartEnable);
// [USART_Enable]$
}
//================================================================================
// USART1_enter_DefaultMode_from_RESET
//================================================================================
extern void USART1_enter_DefaultMode_from_RESET(void) {
// $[USART_InitAsync]
// [USART_InitAsync]$
// $[USART_InitSync]
USART_InitSync_TypeDef initsync = USART_INITSYNC_DEFAULT;
initsync.enable = usartDisable;
initsync.baudrate = 130000;
initsync.databits = usartDatabits8;
initsync.master = 1;
initsync.msbf = 1;
initsync.clockMode = usartClockMode0;
#if defined( USART_INPUT_RXPRS ) && defined( USART_TRIGCTRL_AUTOTXTEN )
initsync.prsRxEnable = 0;
initsync.prsRxCh = 0;
initsync.autoTx = 0;
#endif
USART_InitSync(USART1, &initsync);
// [USART_InitSync]$
// $[USART_InitPrsTrigger]
USART_PrsTriggerInit_TypeDef initprs = USART_INITPRSTRIGGER_DEFAULT;
initprs.rxTriggerEnable = 0;
initprs.txTriggerEnable = 0;
initprs.prsTriggerChannel = usartPrsTriggerCh0;
USART_InitPrsTrigger(USART1, &initprs);
// [USART_InitPrsTrigger]$
// $[USART_InitIO]
/* Set up CLK pin */
USART1->ROUTELOC0 = (USART1->ROUTELOC0 & (~_USART_ROUTELOC0_CLKLOC_MASK))
| USART_ROUTELOC0_CLKLOC_LOC4;
USART1->ROUTEPEN = USART1->ROUTEPEN | USART_ROUTEPEN_CLKPEN;
/* Disable CS pin */
USART1->ROUTELOC0 = (USART1->ROUTELOC0 & (~_USART_ROUTELOC0_CSLOC_MASK))
| USART_ROUTELOC0_CSLOC_LOC3;
USART1->ROUTEPEN = USART1->ROUTEPEN & (~USART_ROUTEPEN_CSPEN);
/* Disable CTS pin */
USART1->ROUTELOC1 = (USART1->ROUTELOC1 & (~_USART_ROUTELOC1_CTSLOC_MASK))
| USART_ROUTELOC1_CTSLOC_LOC2;
USART1->ROUTEPEN = USART1->ROUTEPEN & (~USART_ROUTEPEN_CTSPEN);
/* Disable RTS pin */
USART1->ROUTELOC1 = (USART1->ROUTELOC1 & (~_USART_ROUTELOC1_RTSLOC_MASK))
| USART_ROUTELOC1_RTSLOC_LOC1;
USART1->ROUTEPEN = USART1->ROUTEPEN & (~USART_ROUTEPEN_RTSPEN);
/* Set up RX pin */
USART1->ROUTELOC0 = (USART1->ROUTELOC0 & (~_USART_ROUTELOC0_RXLOC_MASK))
| USART_ROUTELOC0_RXLOC_LOC6;
USART1->ROUTEPEN = USART1->ROUTEPEN | USART_ROUTEPEN_RXPEN;
/* Set up TX pin */
USART1->ROUTELOC0 = (USART1->ROUTELOC0 & (~_USART_ROUTELOC0_TXLOC_MASK))
| USART_ROUTELOC0_TXLOC_LOC8;
USART1->ROUTEPEN = USART1->ROUTEPEN | USART_ROUTEPEN_TXPEN;
// [USART_InitIO]$
// $[USART_Misc]
/* Disable CTS */
USART1->CTRLX = USART1->CTRLX & (~USART_CTRLX_CTSEN);
/* Set CTS active low */
USART1->CTRLX = USART1->CTRLX & (~USART_CTRLX_CTSINV);
/* Set RTS active low */
USART1->CTRLX = USART1->CTRLX & (~USART_CTRLX_RTSINV);
/* Set CS active low */
USART1->CTRL = USART1->CTRL & (~USART_CTRL_CSINV);
/* Set TX active high */
USART1->CTRL = USART1->CTRL & (~USART_CTRL_TXINV);
/* Set RX active high */
USART1->CTRL = USART1->CTRL & (~USART_CTRL_RXINV);
// [USART_Misc]$
// $[USART_Enable]
/* Enable USART if opted by user */
USART_Enable(USART1, usartEnable);
// [USART_Enable]$
}
//================================================================================
// LEUART0_enter_DefaultMode_from_RESET
//================================================================================
extern void LEUART0_enter_DefaultMode_from_RESET(void) {
// $[LEUART0 initialization]
// [LEUART0 initialization]$
}
//================================================================================
// WDOG0_enter_DefaultMode_from_RESET
//================================================================================
extern void WDOG0_enter_DefaultMode_from_RESET(void) {
// $[WDOG Initialization]
// [WDOG Initialization]$
}
//================================================================================
// I2C0_enter_DefaultMode_from_RESET
//================================================================================
extern void I2C0_enter_DefaultMode_from_RESET(void) {
// $[I2C0 I/O setup]
// [I2C0 I/O setup]$
// $[I2C0 initialization]
// [I2C0 initialization]$
}
//================================================================================
// GPCRC_enter_DefaultMode_from_RESET
//================================================================================
extern void GPCRC_enter_DefaultMode_from_RESET(void) {
}
//================================================================================
// LDMA_enter_DefaultMode_from_RESET
//================================================================================
extern void LDMA_enter_DefaultMode_from_RESET(void) {
}
//================================================================================
// TIMER0_enter_DefaultMode_from_RESET
//================================================================================
extern void TIMER0_enter_DefaultMode_from_RESET(void) {
// $[TIMER0 I/O setup]
/* Set up CC0 */
TIMER0->ROUTELOC0 = (TIMER0->ROUTELOC0 & (~_TIMER_ROUTELOC0_CC0LOC_MASK))
| TIMER_ROUTELOC0_CC0LOC_LOC18;
TIMER0->ROUTEPEN = TIMER0->ROUTEPEN | TIMER_ROUTEPEN_CC0PEN;
/* Set up CC1 */
TIMER0->ROUTELOC0 = (TIMER0->ROUTELOC0 & (~_TIMER_ROUTELOC0_CC1LOC_MASK))
| TIMER_ROUTELOC0_CC1LOC_LOC16;
TIMER0->ROUTEPEN = TIMER0->ROUTEPEN | TIMER_ROUTEPEN_CC1PEN;
/* Set up CC2 */
TIMER0->ROUTELOC0 = (TIMER0->ROUTELOC0 & (~_TIMER_ROUTELOC0_CC2LOC_MASK))
| TIMER_ROUTELOC0_CC2LOC_LOC20;
TIMER0->ROUTEPEN = TIMER0->ROUTEPEN | TIMER_ROUTEPEN_CC2PEN;
/* Set up CDTI0 */
TIMER0->ROUTELOC2 = (TIMER0->ROUTELOC2 & (~_TIMER_ROUTELOC2_CDTI0LOC_MASK))
| TIMER_ROUTELOC2_CDTI0LOC_LOC3;
TIMER0->ROUTEPEN = TIMER0->ROUTEPEN & (~TIMER_ROUTEPEN_CDTI0PEN);
/* Set up CDTI1 */
TIMER0->ROUTELOC2 = (TIMER0->ROUTELOC2 & (~_TIMER_ROUTELOC2_CDTI1LOC_MASK))
| TIMER_ROUTELOC2_CDTI1LOC_LOC2;
TIMER0->ROUTEPEN = TIMER0->ROUTEPEN & (~TIMER_ROUTEPEN_CDTI1PEN);
/* Set up CDTI2 */
TIMER0->ROUTELOC2 = (TIMER0->ROUTELOC2 & (~_TIMER_ROUTELOC2_CDTI2LOC_MASK))
| TIMER_ROUTELOC2_CDTI2LOC_LOC1;
TIMER0->ROUTEPEN = TIMER0->ROUTEPEN & (~TIMER_ROUTEPEN_CDTI2PEN);
// [TIMER0 I/O setup]$
// $[TIMER0 initialization]
TIMER_Init_TypeDef init = TIMER_INIT_DEFAULT;
init.enable = 1;
init.debugRun = 0;
init.dmaClrAct = 0;
init.sync = 0;
init.clkSel = timerClkSelHFPerClk;
init.prescale = timerPrescale512;
init.fallAction = timerInputActionNone;
init.riseAction = timerInputActionNone;
init.mode = timerModeUp;
init.quadModeX4 = 0;
init.oneShot = 0;
init.count2x = 0;
init.ati = 0;
TIMER_Init(TIMER0, &init);
// [TIMER0 initialization]$
// $[TIMER0 CC0 init]
TIMER_InitCC_TypeDef initCC0 = TIMER_INITCC_DEFAULT;
initCC0.prsInput = false;
initCC0.prsSel = timerPRSSELCh0;
initCC0.edge = timerEdgeRising;
initCC0.mode = timerCCModePWM;
initCC0.eventCtrl = timerEventEveryEdge;
initCC0.filter = 0;
initCC0.cofoa = timerOutputActionNone;
initCC0.cufoa = timerOutputActionNone;
initCC0.cmoa = timerOutputActionToggle;
initCC0.coist = 0;
initCC0.outInvert = 0;
TIMER_InitCC(TIMER0, 0, &initCC0);
// [TIMER0 CC0 init]$
// $[TIMER0 CC1 init]
TIMER_InitCC_TypeDef initCC1 = TIMER_INITCC_DEFAULT;
initCC1.prsInput = false;
initCC1.prsSel = timerPRSSELCh0;
initCC1.edge = timerEdgeRising;
initCC1.mode = timerCCModePWM;
initCC1.eventCtrl = timerEventEveryEdge;
initCC1.filter = 0;
initCC1.cofoa = timerOutputActionNone;
initCC1.cufoa = timerOutputActionNone;
initCC1.cmoa = timerOutputActionToggle;
initCC1.coist = 0;
initCC1.outInvert = 0;
TIMER_InitCC(TIMER0, 1, &initCC1);
// [TIMER0 CC1 init]$
// $[TIMER0 CC2 init]
TIMER_InitCC_TypeDef initCC2 = TIMER_INITCC_DEFAULT;
initCC2.prsInput = false;
initCC2.prsSel = timerPRSSELCh0;
initCC2.edge = timerEdgeRising;
initCC2.mode = timerCCModePWM;
initCC2.eventCtrl = timerEventEveryEdge;
initCC2.filter = 0;
initCC2.cofoa = timerOutputActionNone;
initCC2.cufoa = timerOutputActionNone;
initCC2.cmoa = timerOutputActionToggle;
initCC2.coist = 0;
initCC2.outInvert = 0;
TIMER_InitCC(TIMER0, 2, &initCC2);
// [TIMER0 CC2 init]$
// $[TIMER0 DTI init]
TIMER_InitDTI_TypeDef initDTI = TIMER_INITDTI_DEFAULT;
initDTI.enable = 0;
initDTI.activeLowOut = 0;
initDTI.invertComplementaryOut = 0;
initDTI.autoRestart = 0;
initDTI.enablePrsSource = 0;
initDTI.prsSel = timerPRSSELCh0;
initDTI.prescale = timerPrescale1;
initDTI.riseTime = 1;
initDTI.fallTime = 1;
initDTI.enableFaultSourceCoreLockup = 1;
initDTI.enableFaultSourceDebugger = 1;
initDTI.faultSourcePrsSel0 = 0;
initDTI.faultSourcePrsSel0 = timerPRSSELCh0;
initDTI.faultSourcePrsSel1 = 0;
initDTI.faultSourcePrsSel1 = timerPRSSELCh0;
initDTI.faultAction = timerDtiFaultActionInactive;
initDTI.outputsEnableMask = 0 | TIMER_DTOGEN_DTOGCC0EN
| TIMER_DTOGEN_DTOGCC1EN | TIMER_DTOGEN_DTOGCC2EN;
TIMER_InitDTI(TIMER0, &initDTI);
// [TIMER0 DTI init]$
}
//================================================================================
// TIMER1_enter_DefaultMode_from_RESET
//================================================================================
extern void TIMER1_enter_DefaultMode_from_RESET(void) {
// $[TIMER1 I/O setup]
// [TIMER1 I/O setup]$
// $[TIMER1 initialization]
// [TIMER1 initialization]$
// $[TIMER1 CC0 init]
// [TIMER1 CC0 init]$
// $[TIMER1 CC1 init]
// [TIMER1 CC1 init]$
// $[TIMER1 CC2 init]
// [TIMER1 CC2 init]$
// $[TIMER1 CC3 init]
// [TIMER1 CC3 init]$
}
//================================================================================
// LETIMER0_enter_DefaultMode_from_RESET
//================================================================================
extern void LETIMER0_enter_DefaultMode_from_RESET(void) {
// $[LETIMER0 Compare Values]
// [LETIMER0 Compare Values]$
// $[LETIMER0 Repeat Values]
// [LETIMER0 Repeat Values]$
// $[LETIMER0 Initialization]
// [LETIMER0 Initialization]$
// $[LETIMER0 PRS Input Triggers]
// [LETIMER0 PRS Input Triggers]$
// $[LETIMER0 I/O setup]
// [LETIMER0 I/O setup]$
}
//================================================================================
// CRYOTIMER_enter_DefaultMode_from_RESET
//================================================================================
extern void CRYOTIMER_enter_DefaultMode_from_RESET(void) {
// $[CRYOTIMER_Init]
CRYOTIMER_Init_TypeDef cryoInit = CRYOTIMER_INIT_DEFAULT;
/* General settings */
cryoInit.enable = 1;
cryoInit.debugRun = 0;
cryoInit.em4Wakeup = 0;
/* Clocking settings */
/* With a frequency of 1000Hz on ULFRCO, this will result in a 1.00 ms timeout */
cryoInit.osc = cryotimerOscULFRCO;
cryoInit.presc = cryotimerPresc_1;
cryoInit.period = cryotimerPeriod_1;
CRYOTIMER_Init(&cryoInit);
// [CRYOTIMER_Init]$
}
//================================================================================
// PCNT0_enter_DefaultMode_from_RESET
//================================================================================
extern void PCNT0_enter_DefaultMode_from_RESET(void) {
// $[PCNT0 I/O setup]
// [PCNT0 I/O setup]$
// $[PCNT0 initialization]
// [PCNT0 initialization]$
}
//================================================================================
// PRS_enter_DefaultMode_from_RESET
//================================================================================
extern void PRS_enter_DefaultMode_from_RESET(void) {
// $[PRS initialization]
// [PRS initialization]$
}
//================================================================================
// PORTIO_enter_DefaultMode_from_RESET
//================================================================================
extern void PORTIO_enter_DefaultMode_from_RESET(void) {
// $[Port A Configuration]
/* Pin PA0 is configured to Input enabled */
GPIO_PinModeSet(gpioPortA, 0, gpioModeInput, 0);
/* Pin PA1 is configured to Input enabled */
GPIO_PinModeSet(gpioPortA, 1, gpioModeInput, 0);
// [Port A Configuration]$
// $[Port B Configuration]
/* Pin PB11 is configured to Push-pull */
GPIO_PinModeSet(gpioPortB, 11, gpioModePushPull, 1);
/* Pin PB12 is configured to Input enabled with pull-up */
GPIO_PinModeSet(gpioPortB, 12, gpioModeInputPull, 1);
/* Pin PB13 is configured to Push-pull */
GPIO_PinModeSet(gpioPortB, 13, gpioModePushPull, 1);
/* Pin PB15 is configured to Push-pull */
GPIO_PinModeSet(gpioPortB, 15, gpioModePushPull, 1);
// [Port B Configuration]$
// $[Port C Configuration]
// [Port C Configuration]$
// $[Port D Configuration]
/* Pin PD9 is configured to Push-pull */
GPIO_PinModeSet(gpioPortD, 9, gpioModePushPull, 1);
/* Pin PD10 is configured to Push-pull */
GPIO_PinModeSet(gpioPortD, 10, gpioModePushPull, 1);
/* Pin PD11 is configured to Input enabled with pull-up */
GPIO_PinModeSet(gpioPortD, 11, gpioModeInputPull, 1);
/* Pin PD12 is configured to Push-pull */
GPIO_PinModeSet(gpioPortD, 12, gpioModePushPull, 1);
/* Pin PD13 is configured to Input enabled with pull-up */
GPIO_PinModeSet(gpioPortD, 13, gpioModeInputPull, 1);
/* Pin PD14 is configured to Push-pull */
GPIO_PinModeSet(gpioPortD, 14, gpioModePushPull, 1);
/* Pin PD15 is configured to Push-pull */
GPIO_PinModeSet(gpioPortD, 15, gpioModePushPull, 1);
// [Port D Configuration]$
// $[Port E Configuration]
// [Port E Configuration]$
// $[Port F Configuration]
// [Port F Configuration]$
}

View File

@ -1,689 +0,0 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Solo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
/*
* Wrapper for crypto implementation on device
*
* */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "em_adc.h"
#include "util.h"
#include "crypto.h"
#include "device.h"
#include "sha256.h"
#include "uECC.h"
#include "aes.h"
#include "ctap.h"
#include "log.h"
#include MBEDTLS_CONFIG_FILE
#include "sha256_alt.h"
#include "mbedtls/ctr_drbg.h"
#include "mbedtls/ecdsa.h"
const uint8_t attestation_cert_der[];
const uint16_t attestation_cert_der_size;
const uint8_t attestation_key[];
const uint16_t attestation_key_size;
static mbedtls_sha256_context embed_sha256_ctx;
static mbedtls_ctr_drbg_context ctr_drbg;
static const struct uECC_Curve_t * _es256_curve = NULL;
static const uint8_t * _signing_key = NULL;
static int _key_len = 0;
// Secrets for testing only
static uint8_t master_secret[32] = "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff"
"\xff\xee\xdd\xcc\xbb\xaa\x99\x88\x77\x66\x55\x44\x33\x22\x11\x00";
static uint8_t transport_secret[32] = "\x10\x01\x22\x33\x44\x55\x66\x77\x87\x90\x0a\xbb\x3c\xd8\xee\xff"
"\xff\xee\x8d\x1c\x3b\xfa\x99\x88\x77\x86\x55\x44\xd3\xff\x33\x00";
void crypto_sha256_init()
{
mbedtls_sha256_init( &embed_sha256_ctx );
mbedtls_sha256_starts(&embed_sha256_ctx,0);
// sha256_init(&sha256_ctx);
}
void crypto_reset_master_secret()
{
ctap_generate_rng(master_secret, 32);
}
void crypto_sha256_update(uint8_t * data, size_t len)
{
mbedtls_sha256_update(&embed_sha256_ctx,data,len);
// sha256_update(&sha256_ctx, data, len);
}
void crypto_sha256_update_secret()
{
mbedtls_sha256_update(&embed_sha256_ctx,master_secret,32);
// sha256_update(&sha256_ctx, master_secret, 32);
}
void crypto_sha256_final(uint8_t * hash)
{
mbedtls_sha256_finish( &embed_sha256_ctx, hash );
// sha256_final(&sha256_ctx, hash);
}
void crypto_sha256_hmac_init(uint8_t * key, uint32_t klen, uint8_t * hmac)
{
uint8_t buf[64];
int i;
memset(buf, 0, sizeof(buf));
if (key == CRYPTO_MASTER_KEY)
{
key = master_secret;
klen = sizeof(master_secret);
}
if(klen > 64)
{
printf2(TAG_ERR,"Error, key size must be <= 64\n");
exit(1);
}
memmove(buf, key, klen);
for (i = 0; i < sizeof(buf); i++)
{
buf[i] = buf[i] ^ 0x36;
}
crypto_sha256_init();
crypto_sha256_update(buf, 64);
}
void crypto_sha256_hmac_final(uint8_t * key, uint32_t klen, uint8_t * hmac)
{
uint8_t buf[64];
int i;
crypto_sha256_final(hmac);
memset(buf, 0, sizeof(buf));
if (key == CRYPTO_MASTER_KEY)
{
key = master_secret;
klen = sizeof(master_secret);
}
if(klen > 64)
{
printf2(TAG_ERR,"Error, key size must be <= 64\n");
exit(1);
}
memmove(buf, key, klen);
for (i = 0; i < sizeof(buf); i++)
{
buf[i] = buf[i] ^ 0x5c;
}
crypto_sha256_init();
crypto_sha256_update(buf, 64);
crypto_sha256_update(hmac, 32);
crypto_sha256_final(hmac);
}
uint8_t adc_rng(void)
{
int i;
uint8_t random = 0;
/* Random number generation */
for (i=0; i<3; i++)
{
ADC_Start(ADC0, adcStartSingle);
while ((ADC0->IF & ADC_IF_SINGLE) == 0);
random |= ((ADC_DataSingleGet(ADC0) & 0x07) << (i * 3));
}
return random;
}
// Generate @num bytes of random numbers to @dest
// return 1 if success, error otherwise
int ctap_generate_rng(uint8_t * dst, size_t num)
{
return mbedtls_ctr_drbg_random(&ctr_drbg,dst,num) == 0;
}
int adc_entropy_func( void *data, unsigned char *output, size_t len )
{
while(len--)
*output++ = adc_rng();
return 0;
}
void crypto_ecc256_init()
{
uECC_set_rng((uECC_RNG_Function)ctap_generate_rng);
_es256_curve = uECC_secp256r1();
mbedtls_ctr_drbg_init(&ctr_drbg);
if ( mbedtls_ctr_drbg_seed(&ctr_drbg, adc_entropy_func, NULL,
master_secret,32 ) != 0 ) {
printf2(TAG_ERR, "mbedtls_ctr_drbg_seed failed\n");
exit(1);
}
}
void crypto_load_external_key(uint8_t * key, int len)
{
_signing_key = key;
_key_len = len;
}
void crypto_ecc256_load_attestation_key()
{
_signing_key = attestation_key;
_key_len = 32;
}
/**
* \brief Import a point from unsigned binary data
*
* \param grp Group to which the point should belong
* \param P Point to import
* \param buf Input buffer
* \param ilen Actual length of input
*
* \return 0 if successful,
* MBEDTLS_ERR_ECP_BAD_INPUT_DATA if input is invalid,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed,
* MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the point format
* is not implemented.
*
* \note This function does NOT check that the point actually
* belongs to the given group, see mbedtls_ecp_check_pubkey() for
* that.
*/
//int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp, mbedtls_ecp_point *P,
// const unsigned char *buf, size_t ilen );
/**
* \brief Import X from unsigned binary data, big endian
*
* \param X Destination MPI
* \param buf Input buffer
* \param buflen Input buffer size
*
* \return 0 if successful,
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
*/
//int mbedtls_mpi_read_binary( mbedtls_mpi *X, const unsigned char *buf, size_t buflen );
/*
* Set context from an mbedtls_ecp_keypair
*/
//int mbedtls_ecdsa_from_keypair( mbedtls_ecdsa_context *ctx, const mbedtls_ecp_keypair *key );
void crypto_ecc256_sign(uint8_t * data, int len, uint8_t * sig)
{
mbedtls_ecp_group grp; /*!< Elliptic curve and base point */
mbedtls_mpi d; /*!< our secret value */
//#define CRYPTO_ENABLE CMU->HFBUSCLKEN0 |= CMU_HFBUSCLKEN0_CRYPTO; \
// CRYPTO->IFC = _CRYPTO_IFC_MASK; \
// CRYPTO->CMD = CRYPTO_CMD_SEQSTOP; \
// CRYPTO->CTRL = CRYPTO_CTRL_DMA0RSEL_DDATA0; \
// CRYPTO->SEQCTRL = 0; \
// CRYPTO->SEQCTRLB = 0
//
//#define CRYPTO_DISABLE \
// CRYPTO->IEN = 0; \
// CMU->HFBUSCLKEN0 &= ~CMU_HFBUSCLKEN0_CRYPTO;
// CRYPTO_DISABLE;
// CRYPTO_ENABLE;
// mbedtls_ecp_group_init( &grp );
// mbedtls_mpi_init( &d );
// mbedtls_ecp_group_load(&grp, MBEDTLS_ECP_DP_SECP256R1);
// mbedtls_mpi_read_binary(&d, _signing_key, 32);
//
// mbedtls_mpi r,s;
// mbedtls_mpi_init(&r);
// mbedtls_mpi_init(&s);
//
// printf("signing..\n");
// dump_hex(data,len);
// mbedtls_ecdsa_sign_det( &grp, &r, &s, &d,
// data, 32, MBEDTLS_MD_SHA256 );// Issue: this will freeze on 13th iteration..
// printf("signed\n");
//
// mbedtls_mpi_write_binary(&r,sig,32);
// mbedtls_mpi_write_binary(&s,sig+32,32);
if ( uECC_sign(_signing_key, data, len, sig, _es256_curve) == 0)
{
printf2(TAG_ERR,"error, uECC failed\n");
exit(1);
}
}
#if 1
void crypto_ecdsa_sign(uint8_t * data, int len, uint8_t * sig, int MBEDTLS_ECP_ID)
{
const struct uECC_Curve_t * curve = NULL;
switch(MBEDTLS_ECP_ID)
{
case MBEDTLS_ECP_DP_SECP192R1:
curve = uECC_secp192r1();
if (_key_len != 24) goto fail;
break;
case MBEDTLS_ECP_DP_SECP224R1:
curve = uECC_secp224r1();
if (_key_len != 28) goto fail;
break;
case MBEDTLS_ECP_DP_SECP256R1:
curve = uECC_secp256r1();
if (_key_len != 32) goto fail;
break;
case MBEDTLS_ECP_DP_SECP256K1:
curve = uECC_secp256k1();
if (_key_len != 32) goto fail;
break;
default:
printf2(TAG_ERR,"error, invalid ECDSA alg specifier\n");
exit(1);
}
if ( uECC_sign(_signing_key, data, len, sig, curve) == 0)
{
printf2(TAG_ERR,"error, uECC failed\n");
exit(1);
}
return;
fail:
printf2(TAG_ERR,"error, invalid key length: %d\n", _key_len);
exit(1);
}
#else
void crypto_ecdsa_sign(uint8_t * data, int len, uint8_t * sig, int MBEDTLS_ECP_ID)
{
mbedtls_ecp_group grp; /*!< Elliptic curve and base point */
mbedtls_mpi d; /*!< our secret value */
mbedtls_ecp_group_init( &grp );
mbedtls_mpi_init( &d );
mbedtls_ecp_group_load(&grp, MBEDTLS_ECP_ID);
mbedtls_mpi_read_binary(&d, _signing_key, 32);
mbedtls_mpi r,s;
mbedtls_mpi_init(&r);
mbedtls_mpi_init(&s);
printf("signing..\n");
dump_hex(data,len);
mbedtls_ecdsa_sign_det( &grp, &r, &s, &d,
data, 32, MBEDTLS_MD_SHA256 );// Issue: this will freeze on 13th iteration..
printf("signed\n");
mbedtls_mpi_write_binary(&r,sig,32);
mbedtls_mpi_write_binary(&s,sig+32,32);
}
#endif
/*
* Generate a keypair with configurable base point
*/
// mbedtls_ecp_gen_keypair( &ctx->grp, &ctx->d, &ctx->Q, f_rng, p_rng )
// mbedtls_ecp_gen_keypair_base( grp, &grp->G, d, Q, f_rng, p_rng )
/*
* Curve types: internal for now, might be exposed later
*/
typedef enum
{
ECP_TYPE_NONE = 0,
ECP_TYPE_SHORT_WEIERSTRASS, /* y^2 = x^3 + a x + b */
ECP_TYPE_MONTGOMERY, /* y^2 = x^3 + a x^2 + x */
} ecp_curve_type;
/*
* Get the type of a curve
*/
static inline ecp_curve_type ecp_get_type( const mbedtls_ecp_group *grp )
{
if( grp->G.X.p == NULL )
return( ECP_TYPE_NONE );
if( grp->G.Y.p == NULL )
return( ECP_TYPE_MONTGOMERY );
else
return( ECP_TYPE_SHORT_WEIERSTRASS );
}
static int mbedtls_ecp_gen_privkey( mbedtls_ecp_group *grp,
const mbedtls_ecp_point *G,
mbedtls_mpi *d, mbedtls_ecp_point *Q,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
int ret;
size_t n_size = ( grp->nbits + 7 ) / 8;
#if defined(ECP_MONTGOMERY)
if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY )
{
/* [M225] page 5 */
size_t b;
MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( d, n_size, f_rng, p_rng ) );
/* Make sure the most significant bit is nbits */
b = mbedtls_mpi_bitlen( d ) - 1; /* mbedtls_mpi_bitlen is one-based */
if( b > grp->nbits )
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( d, b - grp->nbits ) );
else
MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, grp->nbits, 1 ) );
/* Make sure the last three bits are unset */
MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 0, 0 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 1, 0 ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 2, 0 ) );
}
else
#endif /* ECP_MONTGOMERY */
#if defined(ECP_SHORTWEIERSTRASS)
if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS )
{
/* SEC1 3.2.1: Generate d such that 1 <= n < N */
int count = 0;
unsigned char rnd[MBEDTLS_ECP_MAX_BYTES];
/*
* Match the procedure given in RFC 6979 (deterministic ECDSA):
* - use the same byte ordering;
* - keep the leftmost nbits bits of the generated octet string;
* - try until result is in the desired range.
* This also avoids any biais, which is especially important for ECDSA.
*/
do
{
MBEDTLS_MPI_CHK( f_rng( p_rng, rnd, n_size ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( d, rnd, n_size ) );
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( d, 8 * n_size - grp->nbits ) );
/*
* Each try has at worst a probability 1/2 of failing (the msb has
* a probability 1/2 of being 0, and then the result will be < N),
* so after 30 tries failure probability is a most 2**(-30).
*
* For most curves, 1 try is enough with overwhelming probability,
* since N starts with a lot of 1s in binary, but some curves
* such as secp224k1 are actually very close to the worst case.
*/
if( ++count > 30 )
return( MBEDTLS_ERR_ECP_RANDOM_FAILED );
}
while( mbedtls_mpi_cmp_int( d, 1 ) < 0 ||
mbedtls_mpi_cmp_mpi( d, &grp->N ) >= 0 );
}
else
#endif /* ECP_SHORTWEIERSTRASS */
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
cleanup:
if( ret != 0 )
return( ret );
return 0;
}
static int mbedtls_ecp_derive_pubkey( mbedtls_ecp_group *grp,
const mbedtls_ecp_point *G,
mbedtls_mpi *d, mbedtls_ecp_point *Q,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng )
{
return( mbedtls_ecp_mul( grp, Q, d, G, f_rng, p_rng ) );
}
static int hmac_vector_func(uint8_t * hmac, uint8_t * dst, int len)
{
static int hmac_ptr = 0;
if (hmac==NULL)
{
hmac_ptr = 0;
return 0;
}
int i;
while(len--)
{
*dst++ = hmac[hmac_ptr++ % 32];
}
return 0;
}
void generate_private_key(uint8_t * data, int len, uint8_t * data2, int len2, uint8_t * privkey)
{
crypto_sha256_hmac_init(CRYPTO_MASTER_KEY, 0, privkey);
crypto_sha256_update(data, len);
crypto_sha256_update(data2, len2);
crypto_sha256_update(master_secret, 32);
crypto_sha256_hmac_final(CRYPTO_MASTER_KEY, 0, privkey);
// mbedtls_ecp_group grp; /*!< Elliptic curve and base point */
// mbedtls_mpi d; /*!< our secret value */
// mbedtls_ecp_point Q;
//
// mbedtls_ecp_group_init( &grp );
// mbedtls_mpi_init( &d );
// mbedtls_ecp_point_init(&Q);
//
// mbedtls_ecp_group_load(&grp, MBEDTLS_ECP_DP_SECP256R1);
//
//// mbedtls_mpi_read_binary(&d, _signing_key, 32);
// hmac_vector_func(NULL, NULL, 0);
// mbedtls_ecp_gen_privkey(&grp, &grp.G, &d, &Q, hmac_vector_func, privkey);
// mbedtls_mpi_write_binary(&d,privkey,32);
}
/*int uECC_compute_public_key(const uint8_t *private_key, uint8_t *public_key, uECC_Curve curve);*/
void crypto_ecc256_derive_public_key(uint8_t * data, int len, uint8_t * x, uint8_t * y)
{
int ret;
uint8_t privkey[32];
uint8_t pubkey[64];
// generate_private_key(data,len,NULL,0,privkey);
crypto_sha256_hmac_init(CRYPTO_MASTER_KEY, 0, privkey);
crypto_sha256_update(data, len);
crypto_sha256_update(NULL, 0);
crypto_sha256_update(master_secret, 32);
crypto_sha256_hmac_final(CRYPTO_MASTER_KEY, 0, privkey);
// mbedtls_ecp_group grp; /*!< Elliptic curve and base point */
// mbedtls_mpi d; /*!< our secret value */
// mbedtls_ecp_point Q;
//
// mbedtls_ecp_group_init( &grp );
// mbedtls_mpi_init( &d );
// mbedtls_ecp_point_init(&Q);
//
// mbedtls_ecp_group_load(&grp, MBEDTLS_ECP_DP_SECP256R1);
//
//// mbedtls_mpi_read_binary(&d, _signing_key, 32);
// hmac_vector_func(NULL, NULL, 0);
// ret= mbedtls_ecp_gen_privkey(&grp, &grp.G, &d, &Q, hmac_vector_func, privkey);
// if (ret != 0)
// {
// printf("error with priv key -0x04%x\n", -ret);
// }
//// mbedtls_mpi_write_binary(&d,privkey,32);
//
// memset(pubkey,0,sizeof(pubkey));
//
// ret = mbedtls_ecp_derive_pubkey( &grp, &grp.G,
// &d, &Q, hmac_vector_func, privkey);
//
// if (ret != 0)
// {
// printf("error with public key\n");
// }
//
// mbedtls_mpi_write_binary(&Q.X,x,32);
// mbedtls_mpi_write_binary(&Q.Y,y,32);
uECC_compute_public_key(privkey, pubkey, _es256_curve);
memmove(x,pubkey,32);
memmove(y,pubkey+32,32);
}
void crypto_ecc256_load_key(uint8_t * data, int len, uint8_t * data2, int len2)
{
static uint8_t privkey[32];
generate_private_key(data,len,data2,len2,privkey);
_signing_key = privkey;
_key_len = 32;
}
void crypto_ecc256_make_key_pair(uint8_t * pubkey, uint8_t * privkey)
{
if (uECC_make_key(pubkey, privkey, _es256_curve) != 1)
{
printf2(TAG_ERR,"Error, uECC_make_key failed\n");
exit(1);
}
}
void crypto_ecc256_shared_secret(const uint8_t * pubkey, const uint8_t * privkey, uint8_t * shared_secret)
{
if (uECC_shared_secret(pubkey, privkey, shared_secret, _es256_curve) != 1)
{
printf2(TAG_ERR,"Error, uECC_shared_secret failed\n");
exit(1);
}
}
struct AES_ctx aes_ctx;
void crypto_aes256_init(uint8_t * key, uint8_t * nonce)
{
if (key == CRYPTO_TRANSPORT_KEY)
{
AES_init_ctx(&aes_ctx, transport_secret);
}
else
{
AES_init_ctx(&aes_ctx, key);
}
if (nonce == NULL)
{
memset(aes_ctx.Iv, 0, 16);
}
else
{
memmove(aes_ctx.Iv, nonce, 16);
}
}
// prevent round key recomputation
void crypto_aes256_reset_iv(uint8_t * nonce)
{
if (nonce == NULL)
{
memset(aes_ctx.Iv, 0, 16);
}
else
{
memmove(aes_ctx.Iv, nonce, 16);
}
}
void crypto_aes256_decrypt(uint8_t * buf, int length)
{
AES_CBC_decrypt_buffer(&aes_ctx, buf, length);
}
void crypto_aes256_encrypt(uint8_t * buf, int length)
{
AES_CBC_encrypt_buffer(&aes_ctx, buf, length);
}
const uint8_t attestation_cert_der[] =
"\x30\x82\x01\xfb\x30\x82\x01\xa1\xa0\x03\x02\x01\x02\x02\x01\x00\x30\x0a\x06\x08"
"\x2a\x86\x48\xce\x3d\x04\x03\x02\x30\x2c\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13"
"\x02\x55\x53\x31\x0b\x30\x09\x06\x03\x55\x04\x08\x0c\x02\x4d\x44\x31\x10\x30\x0e"
"\x06\x03\x55\x04\x0a\x0c\x07\x54\x45\x53\x54\x20\x43\x41\x30\x20\x17\x0d\x31\x38"
"\x30\x35\x31\x30\x30\x33\x30\x36\x32\x30\x5a\x18\x0f\x32\x30\x36\x38\x30\x34\x32"
"\x37\x30\x33\x30\x36\x32\x30\x5a\x30\x7c\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13"
"\x02\x55\x53\x31\x0b\x30\x09\x06\x03\x55\x04\x08\x0c\x02\x4d\x44\x31\x0f\x30\x0d"
"\x06\x03\x55\x04\x07\x0c\x06\x4c\x61\x75\x72\x65\x6c\x31\x15\x30\x13\x06\x03\x55"
"\x04\x0a\x0c\x0c\x54\x45\x53\x54\x20\x43\x4f\x4d\x50\x41\x4e\x59\x31\x22\x30\x20"
"\x06\x03\x55\x04\x0b\x0c\x19\x41\x75\x74\x68\x65\x6e\x74\x69\x63\x61\x74\x6f\x72"
"\x20\x41\x74\x74\x65\x73\x74\x61\x74\x69\x6f\x6e\x31\x14\x30\x12\x06\x03\x55\x04"
"\x03\x0c\x0b\x63\x6f\x6e\x6f\x72\x70\x70\x2e\x63\x6f\x6d\x30\x59\x30\x13\x06\x07"
"\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00"
"\x04\x45\xa9\x02\xc1\x2e\x9c\x0a\x33\xfa\x3e\x84\x50\x4a\xb8\x02\xdc\x4d\xb9\xaf"
"\x15\xb1\xb6\x3a\xea\x8d\x3f\x03\x03\x55\x65\x7d\x70\x3f\xb4\x02\xa4\x97\xf4\x83"
"\xb8\xa6\xf9\x3c\xd0\x18\xad\x92\x0c\xb7\x8a\x5a\x3e\x14\x48\x92\xef\x08\xf8\xca"
"\xea\xfb\x32\xab\x20\xa3\x62\x30\x60\x30\x46\x06\x03\x55\x1d\x23\x04\x3f\x30\x3d"
"\xa1\x30\xa4\x2e\x30\x2c\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x53\x31"
"\x0b\x30\x09\x06\x03\x55\x04\x08\x0c\x02\x4d\x44\x31\x10\x30\x0e\x06\x03\x55\x04"
"\x0a\x0c\x07\x54\x45\x53\x54\x20\x43\x41\x82\x09\x00\xf7\xc9\xec\x89\xf2\x63\x94"
"\xd9\x30\x09\x06\x03\x55\x1d\x13\x04\x02\x30\x00\x30\x0b\x06\x03\x55\x1d\x0f\x04"
"\x04\x03\x02\x04\xf0\x30\x0a\x06\x08\x2a\x86\x48\xce\x3d\x04\x03\x02\x03\x48\x00"
"\x30\x45\x02\x20\x18\x38\xb0\x45\x03\x69\xaa\xa7\xb7\x38\x62\x01\xaf\x24\x97\x5e"
"\x7e\x74\x64\x1b\xa3\x7b\xf7\xe6\xd3\xaf\x79\x28\xdb\xdc\xa5\x88\x02\x21\x00\xcd"
"\x06\xf1\xe3\xab\x16\x21\x8e\xd8\xc0\x14\xaf\x09\x4f\x5b\x73\xef\x5e\x9e\x4b\xe7"
"\x35\xeb\xdd\x9b\x6d\x8f\x7d\xf3\xc4\x3a\xd7";
const uint16_t attestation_cert_der_size = sizeof(attestation_cert_der)-1;
const uint8_t attestation_key[] = "\xcd\x67\xaa\x31\x0d\x09\x1e\xd1\x6e\x7e\x98\x92\xaa\x07\x0e\x19\x94\xfc\xd7\x14\xae\x7c\x40\x8f\xb9\x46\xb7\x2e\x5f\xe7\x5d\x30";
const uint16_t attestation_key_size = sizeof(attestation_key)-1;

View File

@ -1,713 +0,0 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Solo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
/*
* device.c
*
* Created on: Jun 27, 2018
* Author: conor
*/
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include "em_chip.h"
#include "em_gpio.h"
#include "em_usart.h"
#include "em_adc.h"
#include "em_cmu.h"
#include "em_msc.h"
#include "em_i2c.h"
#include "em_timer.h"
#include "InitDevice.h"
#include "cbor.h"
#include "log.h"
#include "ctaphid.h"
#include "util.h"
#include "app.h"
#include "uECC.h"
#include "crypto.h"
#include "nfc.h"
#ifdef USING_DEV_BOARD
#define MSG_AVAIL_PIN gpioPortC,9
#define RDY_PIN gpioPortC,10
#define RW_PIN gpioPortD,11
#define RESET_PIN gpioPortB,13
#define LED_RED_PIN gpioPortF,4
#define LED_GREEN_PIN gpioPortF,5
#else
#define MSG_AVAIL_PIN gpioPortA,1
#define RDY_PIN gpioPortA,0
#define RW_PIN gpioPortD,15
#define RESET_PIN gpioPortB,15
#define LED_RED_PIN gpioPortD,10
#define LED_GREEN_PIN gpioPortD,14
#define LED_BLUE_PIN gpioPortD,9
#define BUTTON_PIN gpioPortD,13
#define RED_CHANNEL 0
#define GREEN_CHANNEL 2
#define BLUE_CHANNEL 1
#endif
#define PAGE_SIZE 2048
#define PAGES 64
#define COUNTER_PAGE (PAGES - 3)
#define STATE1_PAGE (PAGES - 2)
#define STATE2_PAGE (PAGES - 1)
#define APPLICATION_START_ADDR 0x4000
#define APPLICATION_START_PAGE (0x4000/PAGE_SIZE)
#define APPLICATION_END_ADDR (PAGE_SIZE*(PAGES - 3)-4) // NOT included in application
#define APPLICATION_END_PAGE ((PAGES - 3)) // 125 is NOT included in application
#define AUTH_WORD_ADDR (PAGE_SIZE*(PAGES - 3)-4)
static void init_atomic_counter()
{
int offset = 0;
uint32_t count;
uint32_t one = 1;
uint32_t * ptr = PAGE_SIZE * COUNTER_PAGE;
for (offset = 0; offset < PAGE_SIZE/4; offset += 1)
{
count = *(ptr+offset);
if (count != 0xffffffff)
{
return;
}
}
MSC_WriteWordFast(ptr,&one,4);
}
uint32_t ctap_atomic_count(int sel)
{
int offset = 0;
uint32_t count;
uint32_t zero = 0;
uint32_t * ptr = PAGE_SIZE * COUNTER_PAGE;
if (sel != 0)
{
printf2(TAG_ERR,"counter2 not imple\n");
exit(1);
}
for (offset = 0; offset < PAGE_SIZE/4; offset += 1) // wear-level the flash
{
count = *(ptr+offset);
if (count != 0)
{
count++;
offset++;
if (offset == PAGE_SIZE/4)
{
offset = 0;
MSC_ErasePage(ptr);
/*printf("RESET page counter\n");*/
}
else
{
MSC_WriteWordFast(ptr+offset-1,&zero,4);
}
MSC_WriteWordFast(ptr+offset,&count,4);
break;
}
}
return count;
}
static uint32_t _color;
uint32_t get_RBG()
{
return _color;
}
void RGB(uint32_t hex)
{
uint16_t r = 256 - ((hex & 0xff0000) >> 16);
uint16_t g = 256 - ((hex & 0xff00) >> 8);
uint16_t b = 256 - ((hex & 0xff) >> 0);
TIMER_CompareBufSet(TIMER0, GREEN_CHANNEL, g); // green
TIMER_CompareBufSet(TIMER0, RED_CHANNEL, r); // red
TIMER_CompareBufSet(TIMER0, BLUE_CHANNEL, b); // blue
_color = hex;
}
#define IS_BUTTON_PRESSED() (GPIO_PinInGet(BUTTON_PIN) == 0)
// Verify the user
// return 1 if user is verified, 0 if not
int ctap_user_verification(uint8_t arg)
{
return 1;
}
// Test for user presence
// Return 1 for user is present, 0 user not present
int ctap_user_presence_test()
{
#ifdef SKIP_BUTTON_CHECK
return 1;
#endif
uint32_t t1 = millis();
RGB(0x304010);
#ifdef USE_BUTTON_DELAY
delay(3000);
RGB(0x001040);
delay(50);
return 1;
#endif
while (IS_BUTTON_PRESSED())
{
if (t1 + 5000 < millis())
{
printf1(TAG_GEN,"Button not pressed\n");
return 0;
}
}
t1 = millis();
do
{
if (t1 + 5000 < millis())
{
return 0;
}
if (! IS_BUTTON_PRESSED())
continue;
delay(1);
}
while (! IS_BUTTON_PRESSED());
RGB(0x001040);
delay(50);
return 1;
}
// Must be implemented by application
// data is HID_MESSAGE_SIZE long in bytes
#ifndef TEST_POWER
void ctaphid_write_block(uint8_t * data)
{
printf1(TAG_DUMP,"<< "); dump_hex1(TAG_DUMP, data, HID_MESSAGE_SIZE);
usbhid_send(data);
}
#endif
#ifdef IS_BOOTLOADER // two different colors between bootloader and app
void heartbeat()
{
static int state = 0;
static uint32_t val = (LED_INIT_VALUE >> 8) & 0xff;
int but = IS_BUTTON_PRESSED();
if (state)
{
val--;
}
else
{
val++;
}
if (val > 30 || val < 1)
{
state = !state;
}
// if (but) RGB(val * 2);
// else
RGB((val << 16) | (val*2 << 8));
}
#else
void heartbeat()
{
static int state = 0;
static uint32_t val = (LED_INIT_VALUE >> 8) & 0xff;
int but = IS_BUTTON_PRESSED();
#if 0
RGB(0x100000); // bright ass light
return;
#endif
if (state)
{
val--;
}
else
{
val++;
}
if (val >120/3 || val < 1)
{
state = !state;
}
if (but) RGB(val * 2);
else RGB(val*3 | ((val*3) << 8) | (val << 16) );
// else RGB((val*3) << 8);
}
#endif
uint32_t millis()
{
return CRYOTIMER->CNT;
}
void usbhid_init()
{
}
static int msgs_to_recv = 0;
static void wait_for_efm8_ready()
{
// Wait for efm8 to be ready
while (GPIO_PinInGet(RDY_PIN) == 0)
;
}
static void wait_for_efm8_busy()
{
// Wait for efm8 to be ready
while (GPIO_PinInGet(RDY_PIN) != 0)
;
}
#ifndef TEST_POWER
int usbhid_recv(uint8_t * msg)
{
int i;
if (GPIO_PinInGet(MSG_AVAIL_PIN) == 0)
{
GPIO_PinOutClear(RW_PIN); // Drive low to indicate READ
wait_for_efm8_ready();
for (i = 0; i < 64; i++)
{
msg[i] = USART_SpiTransfer(USART1, 'A');
// delay(1);
}
GPIO_PinOutSet(RW_PIN);
wait_for_efm8_busy();
// // msgs_to_recv--;
// printf(">> ");
// dump_hex(msg,64);
return 64;
}
return 0;
}
#endif
void usbhid_send(uint8_t * msg)
{
int i;
// uint32_t t1 = millis();
USART_SpiTransfer(USART1, *msg++); // Send 1 byte
wait_for_efm8_ready();
for (i = 1; i < HID_MESSAGE_SIZE; i++)
{
USART_SpiTransfer(USART1, *msg++);
}
wait_for_efm8_busy();
delay(10);
// uint32_t t2 = millis();
// printf("wait time: %u\n", (uint32_t)(t2-t1));
}
void usbhid_close()
{
}
void main_loop_delay()
{
}
void delay(int ms)
{
int t1 = millis();
while(millis() - t1 < ms)
;
}
void GPIO_ODD_IRQHandler()
{
uint32_t flag = GPIO->IF;
GPIO->IFC = flag;
if (flag & (1<<9))
{
// printf("pin 9 interrupt\r\n");
msgs_to_recv++;
}
else
{
printf1(TAG_ERR,"wrong pin int %x\r\n",flag);
}
}
void init_adc()
{
/* Enable ADC Clock */
CMU_ClockEnable(cmuClock_ADC0, true);
ADC_Init_TypeDef init = ADC_INIT_DEFAULT;
ADC_InitSingle_TypeDef singleInit = ADC_INITSINGLE_DEFAULT;
/* Initialize the ADC with the required values */
init.timebase = ADC_TimebaseCalc(0);
init.prescale = ADC_PrescaleCalc(7000000, 0);
ADC_Init(ADC0, &init);
/* Initialize for single conversion specific to RNG */
singleInit.reference = adcRefVEntropy;
singleInit.diff = true;
singleInit.posSel = adcPosSelVSS;
singleInit.negSel = adcNegSelVSS;
ADC_InitSingle(ADC0, &singleInit);
/* Set VINATT to maximum value and clear FIFO */
ADC0->SINGLECTRLX |= _ADC_SINGLECTRLX_VINATT_MASK;
ADC0->SINGLEFIFOCLEAR = ADC_SINGLEFIFOCLEAR_SINGLEFIFOCLEAR;
}
void authenticator_read_state(AuthenticatorState * state)
{
uint32_t * ptr = PAGE_SIZE*STATE1_PAGE;
memmove(state,ptr,sizeof(AuthenticatorState));
}
void authenticator_read_backup_state(AuthenticatorState * state )
{
uint32_t * ptr = PAGE_SIZE*STATE2_PAGE;
memmove(state,ptr,sizeof(AuthenticatorState));
}
void authenticator_write_state(AuthenticatorState * state, int backup)
{
uint32_t * ptr;
if (! backup)
{
ptr = PAGE_SIZE*STATE1_PAGE;
MSC_ErasePage(ptr);
// for (i = 0; i < sizeof(AuthenticatorState)/4; i++ )
MSC_WriteWordFast(ptr,state,sizeof(AuthenticatorState) + (sizeof(AuthenticatorState)%4));
}
else
{
ptr = PAGE_SIZE*STATE2_PAGE;
MSC_ErasePage(ptr);
// for (i = 0; i < sizeof(AuthenticatorState)/4; i++ )
MSC_WriteWordFast(ptr,state,sizeof(AuthenticatorState) + (sizeof(AuthenticatorState)%4));
}
}
// Return 1 yes backup is init'd, else 0
int authenticator_is_backup_initialized()
{
uint8_t header[16];
uint32_t * ptr = PAGE_SIZE*STATE2_PAGE;
memmove(header,ptr,16);
AuthenticatorState * state = (AuthenticatorState*)header;
return state->is_initialized == INITIALIZED_MARKER;
}
uint8_t adc_rng(void);
void reset_efm8()
{
// Reset EFM8
GPIO_PinOutClear(RESET_PIN);
delay(2);
GPIO_PinOutSet(RESET_PIN);
}
void bootloader_init(void)
{
/* Chip errata */
// Reset EFM8
GPIO_PinModeSet(RESET_PIN, gpioModePushPull, 1);
// status LEDS
GPIO_PinModeSet(LED_RED_PIN,
gpioModePushPull,
1); // red
GPIO_PinModeSet(LED_GREEN_PIN,
gpioModePushPull,
1); // green
GPIO_PinModeSet(LED_BLUE_PIN,
gpioModePushPull,
1); // blue
// EFM8 RDY/BUSY
GPIO_PinModeSet(RDY_PIN, gpioModeInput, 0);
// EFM8 MSG Available
GPIO_PinModeSet(MSG_AVAIL_PIN, gpioModeInput, 0);
// SPI R/w Indicator
GPIO_PinModeSet(RW_PIN, gpioModePushPull, 1);
printing_init();
MSC_Init();
}
void device_init(void)
{
/* Chip errata */
CHIP_Init();
enter_DefaultMode_from_RESET();
// status LEDS
GPIO_PinModeSet(LED_RED_PIN,
gpioModePushPull,
1); // red
GPIO_PinModeSet(LED_GREEN_PIN,
gpioModePushPull,
1); // green
GPIO_PinModeSet(LED_BLUE_PIN,
gpioModePushPull,
1); // blue
// EFM8 RDY/BUSY
GPIO_PinModeSet(RDY_PIN, gpioModeInput, 0);
// EFM8 MSG Available
GPIO_PinModeSet(MSG_AVAIL_PIN, gpioModeInput, 0);
// SPI R/w Indicator
GPIO_PinModeSet(RW_PIN, gpioModePushPull, 1);
// Reset EFM8
GPIO_PinModeSet(RESET_PIN, gpioModePushPull, 1);
TIMER_TopSet(TIMER0, 255);
RGB(LED_INIT_VALUE);
printing_init();
init_adc();
MSC_Init();
init_atomic_counter();
if (sizeof(AuthenticatorState) > PAGE_SIZE)
{
printf2(TAG_ERR, "not enough room in page\n");
exit(1);
}
CborEncoder test;
uint8_t buf[64];
cbor_encoder_init(&test, buf, 20, 0);
reset_efm8();
printf1(TAG_GEN,"Device init\r\n");
int i=0;
for (i = 0; i < sizeof(buf); i++)
{
buf[i] = adc_rng();
}
}
#ifdef IS_BOOTLOADER
typedef enum
{
BootWrite = 0x40,
BootDone = 0x41,
BootCheck = 0x42,
BootErase = 0x43,
} WalletOperation;
typedef struct {
uint8_t op;
uint8_t addr[3];
uint8_t tag[4];
uint8_t len;
uint8_t payload[255 - 9];
} __attribute__((packed)) BootloaderReq;
//#define APPLICATION_START_ADDR 0x8000
//#define APPLICATION_START_PAGE (0x8000/PAGE_SIZE)
//#define APPLICATION_END_ADDR (PAGE_SIZE*125-4) // NOT included in application
static void erase_application()
{
int page;
uint32_t * ptrpage;
for(page = APPLICATION_START_PAGE; page < APPLICATION_END_PAGE; page++)
{
ptrpage = page * PAGE_SIZE;
MSC_ErasePage(ptrpage);
}
}
static void authorize_application()
{
uint32_t zero = 0;
uint32_t * ptr;
ptr = AUTH_WORD_ADDR;
MSC_WriteWordFast(ptr,&zero, 4);
}
int bootloader_bridge(uint8_t klen, uint8_t * keyh)
{
static int has_erased = 0;
BootloaderReq * req = (BootloaderReq * )keyh;
uint8_t payload[256];
uint8_t hash[32];
uint8_t * pubkey = (uint8_t*)"\x57\xe6\x80\x39\x56\x46\x2f\x0c\x95\xac\x72\x71\xf0\xbc\xe8\x2d\x67\xd0\x59\x29\x2e\x15\x22\x89\x6a\xbd\x3f\x7f\x27\xf3\xc0\xc6\xe2\xd7\x7d\x8a\x9f\xcc\x53\xc5\x91\xb2\x0c\x9c\x3b\x4e\xa4\x87\x31\x67\xb4\xa9\x4b\x0e\x8d\x06\x67\xd8\xc5\xef\x2c\x50\x4a\x55";
const struct uECC_Curve_t * curve = NULL;
/*printf("bootloader_bridge\n");*/
if (req->len > 255-9)
{
return CTAP1_ERR_INVALID_LENGTH;
}
memset(payload, 0xff, sizeof(payload));
memmove(payload, req->payload, req->len);
uint32_t addr = (*((uint32_t*)req->addr)) & 0xffffff;
uint32_t * ptr = addr;
switch(req->op){
case BootWrite:
/*printf("BootWrite 0x%08x\n", addr);*/
if (ptr < APPLICATION_START_ADDR || ptr >= APPLICATION_END_ADDR)
{
return CTAP2_ERR_NOT_ALLOWED;
}
if (!has_erased)
{
erase_application();
has_erased = 1;
}
if (is_authorized_to_boot())
{
printf2(TAG_ERR, "Error, boot check bypassed\n");
exit(1);
}
MSC_WriteWordFast(ptr,payload, req->len + (req->len%4));
break;
case BootDone:
// printf("BootDone\n");
ptr = APPLICATION_START_ADDR;
crypto_sha256_init();
crypto_sha256_update(ptr, APPLICATION_END_ADDR-APPLICATION_START_ADDR);
crypto_sha256_final(hash);
// printf("hash: "); dump_hex(hash, 32);
// printf("sig: "); dump_hex(payload, 64);
curve = uECC_secp256r1();
if (! uECC_verify(pubkey,
hash,
32,
payload,
curve))
{
return CTAP2_ERR_OPERATION_DENIED;
}
authorize_application();
REBOOT_FLAG = 1;
break;
case BootCheck:
/*printf("BootCheck\n");*/
return 0;
break;
case BootErase:
/*printf("BootErase\n");*/
erase_application();
return 0;
break;
default:
return CTAP1_ERR_INVALID_COMMAND;
}
return 0;
}
int is_authorized_to_boot()
{
uint32_t * auth = AUTH_WORD_ADDR;
return *auth == 0;
}
#endif

View File

@ -1,34 +0,0 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Solo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
#include <stdio.h>
#include <string.h>
#include "em_chip.h"
#include "em_cmu.h"
#include "em_emu.h"
#include "em_core.h"
#include "em_gpio.h"
#include "InitDevice.h"
#include "app.h"
#include "cbor.h"

View File

@ -1,382 +0,0 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Solo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
/*
* nfc.c
*
* Created on: Jul 22, 2018
* Author: conor
*/
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include "em_chip.h"
#include "em_gpio.h"
#include "em_i2c.h"
#include "log.h"
#include "util.h"
#include "nfc.h"
#include "app.h"
#define NFC_DEV_ADDR (0xa0|(0x0<<1))
#define NFC_DEV_USART USART1
#ifndef IS_BOOTLOADER
I2C_TransferReturn_TypeDef I2CSPM_Transfer(I2C_TypeDef *i2c, I2C_TransferSeq_TypeDef *seq)
{
I2C_TransferReturn_TypeDef ret;
uint32_t timeout = 10000;
/* Do a polled transfer */
ret = I2C_TransferInit(i2c, seq);
while (ret == i2cTransferInProgress && timeout--)
{
ret = I2C_Transfer(i2c);
}
return ret;
}
// data must be 16 bytes
void read_block(uint8_t block, uint8_t * data)
{
uint8_t addr = NFC_DEV_ADDR;
I2C_TransferSeq_TypeDef seq;
I2C_TransferReturn_TypeDef ret;
uint8_t i2c_read_data[16];
uint8_t i2c_write_data[1];
seq.addr = addr;
seq.flags = I2C_FLAG_WRITE_READ;
/* Select command to issue */
i2c_write_data[0] = block;
seq.buf[0].data = i2c_write_data;
seq.buf[0].len = 1;
/* Select location/length of data to be read */
seq.buf[1].data = i2c_read_data;
seq.buf[1].len = 16;
ret = I2CSPM_Transfer(I2C0, &seq);
if (ret != i2cTransferDone) {
printf("I2C fail %04x\r\n",ret);
exit(1);
}
memmove(data, i2c_read_data, 16);
}
// data must be 16 bytes
void write_block(uint8_t block, uint8_t * data)
{
uint8_t addr = NFC_DEV_ADDR;
I2C_TransferSeq_TypeDef seq;
I2C_TransferReturn_TypeDef ret;
uint8_t i2c_write_data[1 + 16];
seq.addr = addr;
seq.flags = I2C_FLAG_WRITE;
/* Select command to issue */
i2c_write_data[0] = block;
memmove(i2c_write_data + 1, data, 16);
seq.buf[0].data = i2c_write_data;
seq.buf[0].len = 17;
/* Select location/length of data to be read */
seq.buf[1].data = NULL;
seq.buf[1].len = 0;
ret = I2CSPM_Transfer(I2C0, &seq);
if (ret != i2cTransferDone) {
printf("I2C fail %04x\r\n",ret);
exit(1);
}
}
void write_reg_flash(uint8_t reg_addr, uint8_t mask,uint8_t data)
{
uint8_t addr = NFC_DEV_ADDR;
I2C_TransferSeq_TypeDef seq;
I2C_TransferReturn_TypeDef ret;
uint8_t i2c_write_data[4];
seq.addr = addr;
seq.flags = I2C_FLAG_WRITE;
i2c_write_data[0] = 0x3a;
i2c_write_data[1] = reg_addr;
i2c_write_data[2] = mask;
i2c_write_data[3] = data;
seq.buf[0].data = i2c_write_data;
seq.buf[0].len = 4;
seq.buf[1].data = NULL;
seq.buf[1].len = 0;
ret = I2CSPM_Transfer(I2C0, &seq);
if (ret != i2cTransferDone) {
printf("I2C fail %04x\r\n",ret);
exit(1);
}
}
void write_reg(uint8_t reg_addr, uint8_t data)
{
uint8_t mode = 0x00 | (reg_addr & 0x1f);
// delay(10);
// delay(10);
GPIO_PinOutClear(NFC_DEV_SS);
delay(1);
USART_SpiTransfer(NFC_DEV_USART, mode);
mode = USART_SpiTransfer(NFC_DEV_USART, data);
GPIO_PinOutSet(NFC_DEV_SS);
}
void write_command(uint8_t cmd)
{
uint8_t mode = cmd;
// delay(10);
// delay(10);
GPIO_PinOutClear(NFC_DEV_SS);
delay(1);
USART_SpiTransfer(NFC_DEV_USART, mode);
GPIO_PinOutSet(NFC_DEV_SS);
GPIO_PinOutClear(NFC_DEV_SS);
}
void write_eeprom(uint8_t block, uint8_t * data)
{
uint8_t mode = 0x40;
// delay(10);
// delay(10);
GPIO_PinOutClear(NFC_DEV_SS);
delay(1);
USART_SpiTransfer(NFC_DEV_USART, mode);
mode = block << 1;
USART_SpiTransfer(NFC_DEV_USART, mode);
USART_SpiTransfer(NFC_DEV_USART, *data++);
USART_SpiTransfer(NFC_DEV_USART, *data++);
USART_SpiTransfer(NFC_DEV_USART, *data++);
USART_SpiTransfer(NFC_DEV_USART, *data++);
GPIO_PinOutSet(NFC_DEV_SS);
GPIO_PinOutClear(NFC_DEV_SS);
}
void read_eeprom(uint8_t block, uint8_t * data)
{
uint8_t mode = 0x7f;
// delay(10);
// delay(10);
GPIO_PinOutClear(NFC_DEV_SS);
delay(1);
USART_SpiTransfer(NFC_DEV_USART, mode);
mode = block << 1;
USART_SpiTransfer(NFC_DEV_USART, mode);
*data++ = USART_SpiTransfer(NFC_DEV_USART, 0);
*data++ = USART_SpiTransfer(NFC_DEV_USART, 0);
*data++ = USART_SpiTransfer(NFC_DEV_USART, 0);
*data++ = USART_SpiTransfer(NFC_DEV_USART, 0);
GPIO_PinOutSet(NFC_DEV_SS);
GPIO_PinOutClear(NFC_DEV_SS);
}
uint8_t read_reg(uint8_t reg_addr)
{
uint8_t mode = 0x20 | (reg_addr & 0x1f);
// delay(10);
// delay(10);
GPIO_PinOutClear(NFC_DEV_SS);
delay(1);
USART_SpiTransfer(NFC_DEV_USART, mode);
mode = USART_SpiTransfer(NFC_DEV_USART, 0);
GPIO_PinOutSet(NFC_DEV_SS);
GPIO_PinOutClear(NFC_DEV_SS);
// printf("%02x: %x\n",(reg_addr),(int)mode);
return mode;
}
void read_buffer(uint8_t * data, int len)
{
uint8_t mode = 0xC0;
int i;
if (len > 32)
{
printf("warning, max len is 32\n");
len = 32;
}
GPIO_PinOutClear(NFC_DEV_SS);
delay(1);
USART_SpiTransfer(NFC_DEV_USART, mode);
for(i = 0; i < len; i++)
{
*data++ = USART_SpiTransfer(NFC_DEV_USART, 0);
}
GPIO_PinOutSet(NFC_DEV_SS);
GPIO_PinOutClear(NFC_DEV_SS);
}
// data must be 14 bytes long
void read_reg_block(uint8_t * data)
{
int i;
uint8_t mode = 0x20 | (0 & 0x1f);
GPIO_PinOutClear(NFC_DEV_SS);
delay(1);
USART_SpiTransfer(NFC_DEV_USART, mode);
for (i = 0; i < 0x20; i++)
{
mode = USART_SpiTransfer(NFC_DEV_USART, 0);
if (i < 6 || (i >=8 && i < 0x0f) || (i >= 0x1e))
{
*data = mode;
data++;
}
}
GPIO_PinOutSet(NFC_DEV_SS);
GPIO_PinOutClear(NFC_DEV_SS);
}
typedef struct {
uint8_t header;
uint8_t tlen;
uint8_t plen;
uint8_t ilen;
uint8_t rtype;
} NDEF;
typedef struct {
uint8_t io;
uint8_t conf0;
uint8_t conf1;
uint8_t conf2;
uint8_t rfid_status;
uint8_t ic_status;
uint8_t mask0;
uint8_t mask1;
uint8_t int0;
uint8_t int1;
uint8_t buf_status2;
uint8_t buf_status1;
uint8_t last_nfc_address;
uint8_t maj;
uint8_t minor;
} __attribute__((packed)) AMS_REGS;
void nfc_test()
{
uint8_t data[32];
uint8_t ns_reg;
uint8_t last_ns_reg;
// magic-number,
uint8_t cc[] = {0xE1,0x10,0x08, 0x00};
uint8_t ndef[32] = "\x03\x11\xD1\x01\x0D\x55\x01adafruit.com";
AMS_REGS * regs;
return ;
delay(10);
GPIO_PinOutSet(NFC_DEV_SS);
delay(10);
GPIO_PinOutClear(NFC_DEV_SS);
delay(10);
// uint8_t reg = read_reg(0);
write_command(0xC2); // Set to default state
write_command(0xC4); // Clear buffer
write_reg(0x3, 0x80 | 0x40); // enable tunneling mode and RF configuration
read_reg_block(data);
printf("regs: "); dump_hex(data,15);
delay(100);
read_reg_block(data);
printf("regs: "); dump_hex(data,15);
if (0)
{
read_eeprom(0x7F, data);
printf("initial config: "); dump_hex(data,4);
data[0] = (1<<2) | 0x03; // save cfg1 setting for energy harvesting
data[1] = 0x80 | 0x40; // save cfg2 setting for tunneling
write_eeprom(0x7F, data);
printf("updated config: "); dump_hex(data,4);
}
while (1)
{
// delay(100);
// read_reg_block(data);
// regs = (AMS_REGS *)data;
//
// if ((regs->buf_status2 & 0x3f) && !(regs->buf_status2 & 0x80))
// {
// read_buffer(data, regs->buf_status2 & 0x3f);
// printf("data: ");
//
// dump_hex(data, regs->buf_status2 & 0x3f);
// }
// dump_hex(data,15);
}
}
#endif

View File

@ -1,105 +0,0 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Solo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
#include "em_chip.h"
#include "em_cmu.h"
#include "em_emu.h"
#include "em_core.h"
#include "em_usart.h"
#include "em_gpio.h"
#include <stdio.h>
#include <string.h>
#include "app.h"
#ifndef PRINTING_USE_VCOM
int RETARGET_WriteChar(char c)
{
return ITM_SendChar(c);
}
int RETARGET_ReadChar(void)
{
return 0;
}
void setupSWOForPrint(void)
{
/* Enable GPIO clock. */
CMU_ClockEnable(cmuClock_GPIO, true);
/* Enable Serial wire output pin */
GPIO->ROUTEPEN |= GPIO_ROUTEPEN_SWVPEN;
/* Set location 0 */
GPIO->ROUTELOC0 = GPIO_ROUTELOC0_SWVLOC_LOC0;
/* Enable output on pin - GPIO Port F, Pin 2 */
GPIO->P[5].MODEL &= ~(_GPIO_P_MODEL_MODE2_MASK);
GPIO->P[5].MODEL |= GPIO_P_MODEL_MODE2_PUSHPULL;
/* Enable debug clock AUXHFRCO */
CMU_OscillatorEnable(cmuOsc_AUXHFRCO, true, true);
CMU->OSCENCMD = CMU_OSCENCMD_AUXHFRCOEN;
/* Wait until clock is ready */
while (!(CMU->STATUS & CMU_STATUS_AUXHFRCORDY));
/* Enable trace in core debug */
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
ITM->LAR = 0xC5ACCE55;
ITM->TER = 0x0;
ITM->TCR = 0x0;
TPI->SPPR = 2;
TPI->ACPR = 0x15; // changed from 0x0F on Giant, etc. to account for 19 MHz default AUXHFRCO frequency
ITM->TPR = 0x0;
DWT->CTRL = 0x400003FE;
ITM->TCR = 0x0001000D;
TPI->FFCR = 0x00000100;
ITM->TER = 0x1;
}
void printing_init()
{
setupSWOForPrint();
}
#else
int RETARGET_WriteChar(char c)
{
USART_Tx(USART0,c);
return 0;
}
int RETARGET_ReadChar(void)
{
return 0;
}
void printing_init()
{
#ifdef USING_DEV_BOARD
// GPIO_PinModeSet(gpioPortA,5,gpioModePushPull,1); // VCOM enable
#endif
}
#endif

View File

@ -1,475 +0,0 @@
/***************************************************************************//**
* @file
* @brief Provide stdio retargeting for all supported toolchains.
* @version 5.5.0
*******************************************************************************
* # License
* <b>Copyright 2015 Silicon Labs, Inc. http://www.silabs.com</b>
*******************************************************************************
*
* This file is licensed under the Silabs License Agreement. See the file
* "Silabs_License_Agreement.txt" for details. Before using this software for
* any purpose, you must agree to the terms of that agreement.
*
******************************************************************************/
/***************************************************************************//**
* @addtogroup RetargetIo
* @{ This module provide low-level stubs for retargetting stdio for all
* supported toolchains.
* The stubs are minimal yet sufficient implementations.
* Refer to chapter 12 in the reference manual for newlib 1.17.0
* for details on implementing newlib stubs.
******************************************************************************/
extern int RETARGET_ReadChar(void);
extern int RETARGET_WriteChar(char c);
#if !defined(__CROSSWORKS_ARM) && defined(__GNUC__)
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "em_device.h"
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
int fileno(FILE *);
/** @endcond */
int _close(int file);
int _fstat(int file, struct stat *st);
int _isatty(int file);
int _lseek(int file, int ptr, int dir);
int _read(int file, char *ptr, int len);
caddr_t _sbrk(int incr);
int _write(int file, const char *ptr, int len);
extern char _end; /**< Defined by the linker */
/**************************************************************************//**
* @brief
* Close a file.
*
* @param[in] file
* File you want to close.
*
* @return
* Returns 0 when the file is closed.
*****************************************************************************/
int _close(int file)
{
(void) file;
return 0;
}
/**************************************************************************//**
* @brief Exit the program.
* @param[in] status The value to return to the parent process as the
* exit status (not used).
*****************************************************************************/
void _exit(int status)
{
(void) status;
while (1) {
} /* Hang here forever... */
}
/**************************************************************************//**
* @brief
* Status of an open file.
*
* @param[in] file
* Check status for this file.
*
* @param[in] st
* Status information.
*
* @return
* Returns 0 when st_mode is set to character special.
*****************************************************************************/
int _fstat(int file, struct stat *st)
{
(void) file;
st->st_mode = S_IFCHR;
return 0;
}
/**************************************************************************//**
* @brief Get process ID.
*****************************************************************************/
int _getpid(void)
{
return 1;
}
/**************************************************************************//**
* @brief
* Query whether output stream is a terminal.
*
* @param[in] file
* Descriptor for the file.
*
* @return
* Returns 1 when query is done.
*****************************************************************************/
int _isatty(int file)
{
(void) file;
return 1;
}
/**************************************************************************//**
* @brief Send signal to process.
* @param[in] pid Process id (not used).
* @param[in] sig Signal to send (not used).
*****************************************************************************/
int _kill(int pid, int sig)
{
(void)pid;
(void)sig;
return -1;
}
/**************************************************************************//**
* @brief
* Set position in a file.
*
* @param[in] file
* Descriptor for the file.
*
* @param[in] ptr
* Poiter to the argument offset.
*
* @param[in] dir
* Directory whence.
*
* @return
* Returns 0 when position is set.
*****************************************************************************/
int _lseek(int file, int ptr, int dir)
{
(void) file;
(void) ptr;
(void) dir;
return 0;
}
/**************************************************************************//**
* @brief
* Read from a file.
*
* @param[in] file
* Descriptor for the file you want to read from.
*
* @param[in] ptr
* Pointer to the chacaters that are beeing read.
*
* @param[in] len
* Number of characters to be read.
*
* @return
* Number of characters that have been read.
*****************************************************************************/
int _read(int file, char *ptr, int len)
{
int c, rxCount = 0;
(void) file;
while (len--) {
if ((c = RETARGET_ReadChar()) != -1) {
*ptr++ = c;
rxCount++;
} else {
break;
}
}
if (rxCount <= 0) {
return -1; /* Error exit */
}
return rxCount;
}
/**************************************************************************//**
* @brief
* Increase heap.
*
* @param[in] incr
* Number of bytes you want increment the program's data space.
*
* @return
* Rsturns a pointer to the start of the new area.
*****************************************************************************/
caddr_t _sbrk(int incr)
{
static char *heap_end;
char *prev_heap_end;
if (heap_end == 0) {
heap_end = &_end;
}
prev_heap_end = heap_end;
heap_end += incr;
return (caddr_t) prev_heap_end;
}
/**************************************************************************//**
* @brief
* Write to a file.
*
* @param[in] file
* Descriptor for the file you want to write to.
*
* @param[in] ptr
* Pointer to the text you want to write
*
* @param[in] len
* Number of characters to be written.
*
* @return
* Number of characters that have been written.
*****************************************************************************/
int _write(int file, const char *ptr, int len)
{
int txCount;
(void) file;
for (txCount = 0; txCount < len; txCount++) {
RETARGET_WriteChar(*ptr++);
}
return len;
}
#endif /* !defined( __CROSSWORKS_ARM ) && defined( __GNUC__ ) */
#if defined(__ICCARM__)
/*******************
*
* Copyright 1998-2003 IAR Systems. All rights reserved.
*
* $Revision: 38614 $
*
* This is a template implementation of the "__write" function used by
* the standard library. Replace it with a system-specific
* implementation.
*
* The "__write" function should output "size" number of bytes from
* "buffer" in some application-specific way. It should return the
* number of characters written, or _LLIO_ERROR on failure.
*
* If "buffer" is zero then __write should perform flushing of
* internal buffers, if any. In this case "handle" can be -1 to
* indicate that all handles should be flushed.
*
* The template implementation below assumes that the application
* provides the function "MyLowLevelPutchar". It should return the
* character written, or -1 on failure.
*
********************/
#include <yfuns.h>
#include <stdint.h>
#include "em_common.h"
_STD_BEGIN
/**************************************************************************//**
* @brief Transmit buffer to USART1
* @param buffer Array of characters to send
* @param nbytes Number of bytes to transmit
* @return Number of bytes sent
*****************************************************************************/
static int TxBuf(uint8_t *buffer, int nbytes)
{
int i;
for (i = 0; i < nbytes; i++) {
RETARGET_WriteChar(*buffer++);
}
return nbytes;
}
/*
* If the __write implementation uses internal buffering, uncomment
* the following line to ensure that we are called with "buffer" as 0
* (i.e. flush) when the application terminates.
*/
size_t __write(int handle, const unsigned char * buffer, size_t size)
{
/* Remove the #if #endif pair to enable the implementation */
size_t nChars = 0;
if (buffer == 0) {
/*
* This means that we should flush internal buffers. Since we
* don't we just return. (Remember, "handle" == -1 means that all
* handles should be flushed.)
*/
return 0;
}
/* This template only writes to "standard out" and "standard err",
* for all other file handles it returns failure. */
if (handle != _LLIO_STDOUT && handle != _LLIO_STDERR) {
return _LLIO_ERROR;
}
/* Hook into USART1 transmit function here */
if (TxBuf((uint8_t *) buffer, size) != size) {
return _LLIO_ERROR;
} else {
nChars = size;
}
return nChars;
}
size_t __read(int handle, unsigned char * buffer, size_t size)
{
/* Remove the #if #endif pair to enable the implementation */
int nChars = 0;
/* This template only reads from "standard in", for all other file
* handles it returns failure. */
if (handle != _LLIO_STDIN) {
return _LLIO_ERROR;
}
for (/* Empty */; size > 0; --size) {
int c = RETARGET_ReadChar();
if (c < 0) {
break;
}
*buffer++ = c;
++nChars;
}
return nChars;
}
_STD_END
#endif /* defined( __ICCARM__ ) */
#if defined(__CROSSWORKS_ARM)
/* Pass each of these function straight to the USART */
int __putchar(int ch)
{
return(RETARGET_WriteChar(ch));
}
int __getchar(void)
{
return(RETARGET_ReadChar());
}
#endif /* defined( __CROSSWORKS_ARM ) */
#if defined(__CC_ARM)
/******************************************************************************/
/* RETARGET.C: 'Retarget' layer for target-dependent low level functions */
/******************************************************************************/
/* This file is part of the uVision/ARM development tools. */
/* Copyright (c) 2005-2006 Keil Software. All rights reserved. */
/* This software may only be used under the terms of a valid, current, */
/* end user licence from KEIL for a compatible version of KEIL software */
/* development tools. Nothing else gives you the right to use this software. */
/******************************************************************************/
#include <stdio.h>
/* #pragma import(__use_no_semihosting_swi) */
struct __FILE{
int handle;
};
/**Standard output stream*/
FILE __stdout;
/**************************************************************************//**
* @brief
* Writes character to file
*
* @param[in] f
* File
*
* @param[in] ch
* Character
*
* @return
* Written character
*****************************************************************************/
int fputc(int ch, FILE *f)
{
return(RETARGET_WriteChar(ch));
}
/**************************************************************************//**
* @brief
* Reads character from file
*
* @param[in] f
* File
*
* @return
* Character
*****************************************************************************/
int fgetc(FILE *f)
{
return(RETARGET_ReadChar());
}
/**************************************************************************//**
* @brief
* Tests the error indicator for the stream pointed
* to by file
*
* @param[in] f
* File
*
* @return
* Returns non-zero if it is set
*****************************************************************************/
int ferror(FILE *f)
{
/* Your implementation of ferror */
return EOF;
}
/**************************************************************************//**
* @brief
* Writes a character to the console
*
* @param[in] ch
* Character
*****************************************************************************/
void _ttywrch(int ch)
{
RETARGET_WriteChar(ch);
}
/**************************************************************************//**
* @brief
* Library exit function. This function is called if stack
* overflow occurs.
*
* @param[in] return_code
* Return code
*****************************************************************************/
void _sys_exit(int return_code)
{
label: goto label;/* endless loop */
}
#endif /* defined( __CC_ARM ) */
/** @} (end group RetargetIo) */

View File

@ -1,210 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
<storageModule moduleId="org.eclipse.cdt.core.settings">
<cconfiguration id="com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt.debug#com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt:7.2.1.20170904">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt.debug#com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt:7.2.1.20170904" moduleId="org.eclipse.cdt.core.settings" name="GNU ARM v7.2.1 - Debug">
<macros>
<stringMacro name="StudioSdkPath" type="VALUE_PATH_DIR" value="${StudioSdkPathFromID:com.silabs.sdk.stack.super:1.1.1._310456152}"/>
<stringMacro name="StudioToolchainPath" type="VALUE_PATH_DIR" value="${StudioToolchainPathFromID:com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt:7.2.1.20170904}"/>
</macros>
<externalSettings/>
<extensions>
<extension id="com.silabs.ss.framework.debugger.core.HEX" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="com.silabs.ss.framework.debugger.core.EBL" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="com.silabs.ss.framework.debugger.core.GBL" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="com.silabs.ss.framework.debugger.core.BIN" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="com.silabs.ss.framework.debugger.core.S37" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions>
</storageModule>
<storageModule buildConfig.stockConfigId="com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt.debug#com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt:7.2.1.20170904" cppBuildConfig.builtinIncludes="studio:/sdk/hardware/kit/common/bsp/ studio:/sdk/hardware/kit/common/drivers/ studio:/sdk/platform/Device/SiliconLabs/EFM32JG1B/Include/ studio:/sdk/platform/CMSIS/Include/ studio:/sdk/platform/emlib/inc/ studio:/sdk/hardware/kit/common/bsp/ studio:/sdk/hardware/kit/common/drivers/ studio:/sdk/platform/Device/SiliconLabs/EFM32JG1B/Include/ studio:/sdk/platform/CMSIS/Include/ studio:/sdk/platform/emlib/inc/" cppBuildConfig.builtinLibraryFiles="" cppBuildConfig.builtinLibraryNames="" cppBuildConfig.builtinLibraryObjects="" cppBuildConfig.builtinLibraryPaths="" cppBuildConfig.builtinMacros="EFM32JG1B200F128GM32 EFM32JG1B200F128GM32" moduleId="com.silabs.ss.framework.ide.project.core.cpp" projectCommon.boardIds="com.silabs.board.none:0.0.0" projectCommon.partId="mcu.arm.efm32.jg1.efm32jg1b200f128gm32" projectCommon.referencedModules="[{&quot;builtinExcludes&quot;:[],&quot;builtinSources&quot;:[],&quot;builtin&quot;:true,&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/ss/Project.ecore\&quot; builtin=\&quot;true\&quot; id=\&quot;com.silabs.sdk.exx32.common.drivers\&quot;&gt;\r\n &lt;exclusions pattern=\&quot;.*\&quot;/&gt;\r\n&lt;/project:MModule&gt;&quot;},{&quot;builtinExcludes&quot;:[],&quot;builtinSources&quot;:[],&quot;builtin&quot;:true,&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/ss/Project.ecore\&quot; builtin=\&quot;true\&quot; id=\&quot;com.silabs.sdk.exx32.common.bsp\&quot;&gt;\r\n &lt;exclusions pattern=\&quot;.*\&quot;/&gt;\r\n&lt;/project:MModule&gt;&quot;},{&quot;builtinExcludes&quot;:[],&quot;builtinSources&quot;:[&quot;CMSIS/EFM32JG1B/startup_gcc_efm32jg1b.s&quot;,&quot;CMSIS/EFM32JG1B/system_efm32jg1b.c&quot;],&quot;builtin&quot;:true,&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/ss/Project.ecore\&quot; builtin=\&quot;true\&quot; id=\&quot;com.silabs.sdk.exx32.part\&quot;/&gt;&quot;},{&quot;builtinExcludes&quot;:[],&quot;builtinSources&quot;:[],&quot;builtin&quot;:true,&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/ss/Project.ecore\&quot; builtin=\&quot;true\&quot; id=\&quot;com.silabs.sdk.exx32.common.CMSIS\&quot;&gt;\r\n &lt;exclusions pattern=\&quot;.*\&quot;/&gt;\r\n&lt;/project:MModule&gt;&quot;},{&quot;builtinExcludes&quot;:[],&quot;builtinSources&quot;:[&quot;emlib/em_gpio.c&quot;,&quot;emlib/em_system.c&quot;,&quot;emlib/em_cmu.c&quot;,&quot;emlib/em_assert.c&quot;,&quot;emlib/em_emu.c&quot;],&quot;builtin&quot;:true,&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/ss/Project.ecore\&quot; builtin=\&quot;true\&quot; id=\&quot;com.silabs.sdk.exx32.common.emlib\&quot;&gt;\r\n &lt;inclusions pattern=\&quot;emlib/em_system.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;emlib/em_emu.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;emlib/em_cmu.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;emlib/em_device.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;emlib/em_chip.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;emlib/em_assert.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;emlib/em_gpio.c\&quot;/&gt;\r\n&lt;/project:MModule&gt;&quot;},{&quot;builtinExcludes&quot;:[],&quot;builtinSources&quot;:[],&quot;builtin&quot;:true,&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/ss/Project.ecore\&quot; builtin=\&quot;true\&quot; id=\&quot;com.silabs.sdk.exx32.board\&quot;/&gt;&quot;}]" projectCommon.sdkId="com.silabs.sdk.stack.super:1.1.1._310456152" projectCommon.toolchainId="com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt:7.2.1.20170904"/>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" description="" id="com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt.debug#com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt:7.2.1.20170904" name="GNU ARM v7.2.1 - Debug" parent="com.silabs.ide.si32.gcc.cdt.managedbuild.config.gnu.exe">
<folderInfo id="com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt.debug#com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt:7.2.1.20170904." name="/" resourcePath="">
<toolChain id="com.silabs.ide.si32.gcc.cdt.managedbuild.toolchain.exe.930698941" name="Si32 GNU ARM" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.toolchain.exe">
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.toolchain.debug.level.2037798819" name="Debug Level" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.toolchain.debug.level" value="com.silabs.ide.si32.gcc.cdt.managedbuild.toolchain.debug.level.default" valueType="enumerated"/>
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.overrideflash.495029551" name="Override default flash options" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.overrideflash" value="true" valueType="boolean"/>
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.flashlength.2021030475" name="LENGTH" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.flashlength" value="0x4000" valueType="string"/>
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.overrideram.2020332041" name="Override default RAM options" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.overrideram" value="true" valueType="boolean"/>
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.ramorigin.2081162957" name="ORIGIN" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.ramorigin" value="0x20000000" valueType="string"/>
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.ramlength.1981650487" name="LENGTH" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.ramlength" value="0x8000" valueType="string"/>
<targetPlatform binaryParser="org.eclipse.cdt.core.ELF;org.eclipse.cdt.core.GNU_ELF;com.silabs.ss.framework.debugger.core.BIN;com.silabs.ss.framework.debugger.core.HEX;com.silabs.ss.framework.debugger.core.S37;com.silabs.ss.framework.debugger.core.EBL;com.silabs.ss.framework.debugger.core.GBL" id="com.silabs.ide.si32.gcc.cdt.managedbuild.target.gnu.platform.base.613101530" isAbstract="false" name="Debug Platform" osList="win32,linux,macosx" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.target.gnu.platform.base"/>
<builder buildPath="${workspace_loc:/efm32boot}/GNU ARM v7.2.1 - Debug" id="com.silabs.ide.si32.gcc.cdt.managedbuild.target.gnu.builder.base.2113865201" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Si32 GNU ARM Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.target.gnu.builder.base"/>
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.base.981192541" name="GNU ARM C Compiler" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.base">
<option id="gnu.c.compiler.option.optimization.level.1400029735" name="Optimization Level" superClass="gnu.c.compiler.option.optimization.level" value="gnu.c.optimization.level.size" valueType="enumerated"/>
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.def.symbols.115820704" name="Defined symbols (-D)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.def.symbols" valueType="definedSymbols">
<listOptionValue builtIn="false" value="DEBUG=1"/>
<listOptionValue builtIn="false" value="EFM32JG1B200F128GM32=1"/>
</option>
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.debug.builtin.422869633" name="Always branch to builtin functions (-fno-builtin)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.debug.builtin" value="true" valueType="boolean"/>
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.debug.prolog.384018529" name="Generate debugger-friendly prologs (-mno-sched-prolog)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.debug.prolog" value="true" valueType="boolean"/>
<option id="gnu.c.compiler.option.include.paths.749408413" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/inc}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${ProjDirPath}/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${ProjDirPath}/../efm32/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${ProjDirPath}/../../fido2&quot;"/>
<listOptionValue builtIn="false" value="&quot;${ProjDirPath}/../../fido2/extensions&quot;"/>
<listOptionValue builtIn="false" value="&quot;${ProjDirPath}/../../tinycbor/src&quot;"/>
<listOptionValue builtIn="false" value="&quot;${ProjDirPath}/../../crypto/sha256&quot;"/>
<listOptionValue builtIn="false" value="&quot;${ProjDirPath}/../../crypto/micro-ecc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${ProjDirPath}/../../crypto/tiny-AES-c&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/hardware/kit/common/bsp&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/hardware/kit/common/drivers&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/platform/Device/SiliconLabs/EFM32JG1B/Include&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/platform/CMSIS/Include&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/platform/emlib/inc&quot;"/>
</option>
<inputType id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.input.486237326" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.input"/>
</tool>
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.base.856016047" name="GNU ARM C++ Compiler" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.base">
<option id="gnu.cpp.compiler.option.optimization.level.1012646883" name="Optimization Level" superClass="gnu.cpp.compiler.option.optimization.level" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/>
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.debug.builtin.1020668095" name="Always branch to builtin functions (-fno-builtin)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.debug.builtin" value="true" valueType="boolean"/>
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.debug.prolog.304697844" name="Generate debugger-friendly prologs (-mno-sched-prolog)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.debug.prolog" value="true" valueType="boolean"/>
</tool>
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.assembler.base.718152493" name="GNU ARM Assembler" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.assembler.base">
<option id="gnu.both.asm.option.include.paths.998368574" name="Include paths (-I)" superClass="gnu.both.asm.option.include.paths" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/inc}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${ProjDirPath}/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/hardware/kit/common/bsp&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/hardware/kit/common/drivers&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/platform/Device/SiliconLabs/EFM32JG1B/Include&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/platform/CMSIS/Include&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/platform/emlib/inc&quot;"/>
</option>
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.as.def.symbols.604334894" name="Defined symbols (-D)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.as.def.symbols" valueType="definedSymbols">
<listOptionValue builtIn="false" value="EFM32JG1B200F128GM32=1"/>
</option>
<inputType id="org.eclipse.cdt.core.asmSource.695503458" superClass="org.eclipse.cdt.core.asmSource"/>
</tool>
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.base.1884456996" name="GNU ARM C Linker" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.base">
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.nostdlibs.1998445955" name="No startup or default libs (-nostdlib)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.nostdlibs" value="false" valueType="boolean"/>
<inputType id="cdt.managedbuild.tool.gnu.c.linker.input.185802893" superClass="cdt.managedbuild.tool.gnu.c.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
</tool>
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.linker.base.1862357894" name="GNU ARM C++ Linker" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.linker.base"/>
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.archiver.base.1275127827" name="GNU ARM Archiver" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.archiver.base"/>
</toolChain>
</folderInfo>
<sourceEntries>
<entry excluding="CMSIS/EFM32PG1B|crypto|efm32|fido2" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
<entry excluding="aes-gcm|micro-ecc/examples|micro-ecc/scripts|micro-ecc/test|tiny-AES-c" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="crypto"/>
<entry excluding=".settings|CMSIS|docs|emlib|GNU ARM v7.2.1 - Debug|hw|inc|mbedtls|sl_crypto|src/crypto.c|src/main.c|.cproject|.project|EFM32.hwconf|Makefile|src/.crypto.c.swp|src/.device.c.swp|src/app.h" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="efm32"/>
<entry excluding=".main.c.swp|crypto.c|ctap_parse.c|main.c|.ctap_errors.h.swp|.ctap.c.swp|.ctap.h.swp|.storage.h.swp|.wallet.c.swp|.wallet.h.swp" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="fido2"/>
</sourceEntries>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
<cconfiguration id="com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt.release#com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt:7.2.1.20170904">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt.release#com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt:7.2.1.20170904" moduleId="org.eclipse.cdt.core.settings" name="GNU ARM v7.2.1 - Release">
<macros>
<stringMacro name="StudioSdkPath" type="VALUE_PATH_DIR" value="${StudioSdkPathFromID:com.silabs.sdk.stack.super:1.1.1._310456152}"/>
<stringMacro name="StudioToolchainPath" type="VALUE_PATH_DIR" value="${StudioToolchainPathFromID:com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt:7.2.1.20170904}"/>
</macros>
<externalSettings/>
<extensions>
<extension id="com.silabs.ss.framework.debugger.core.HEX" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="com.silabs.ss.framework.debugger.core.EBL" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="com.silabs.ss.framework.debugger.core.GBL" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="com.silabs.ss.framework.debugger.core.BIN" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="com.silabs.ss.framework.debugger.core.S37" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions>
</storageModule>
<storageModule buildConfig.stockConfigId="com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt.release#com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt:7.2.1.20170904" cppBuildConfig.builtinIncludes="studio:/sdk/hardware/kit/common/bsp/ studio:/sdk/hardware/kit/SLSTK3401A_EFM32PG/config/ studio:/sdk/hardware/kit/common/drivers/ studio:/sdk/platform/Device/SiliconLabs/EFM32PG1B/Include/ studio:/sdk/platform/CMSIS/Include/ studio:/sdk/platform/emlib/inc/ studio:/sdk/hardware/kit/common/bsp/ studio:/sdk/hardware/kit/SLSTK3401A_EFM32PG/config/ studio:/sdk/hardware/kit/common/drivers/ studio:/sdk/platform/Device/SiliconLabs/EFM32PG1B/Include/ studio:/sdk/platform/CMSIS/Include/ studio:/sdk/platform/emlib/inc/" cppBuildConfig.builtinLibraryFiles="" cppBuildConfig.builtinLibraryNames="" cppBuildConfig.builtinLibraryObjects="" cppBuildConfig.builtinLibraryPaths="" cppBuildConfig.builtinMacros="EFM32PG1B200F256GM48 EFM32PG1B200F256GM48" moduleId="com.silabs.ss.framework.ide.project.core.cpp" projectCommon.referencedModules="[{&quot;builtinExcludes&quot;:[],&quot;builtinSources&quot;:[&quot;emlib/em_gpio.c&quot;,&quot;emlib/em_system.c&quot;,&quot;emlib/em_cmu.c&quot;,&quot;emlib/em_assert.c&quot;,&quot;emlib/em_emu.c&quot;],&quot;builtin&quot;:true,&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/ss/Project.ecore\&quot; builtin=\&quot;true\&quot; id=\&quot;com.silabs.sdk.exx32.common.emlib\&quot;&gt;\r\n &lt;inclusions pattern=\&quot;emlib/em_system.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;emlib/em_emu.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;emlib/em_cmu.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;emlib/em_device.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;emlib/em_chip.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;emlib/em_assert.c\&quot;/&gt;\r\n &lt;inclusions pattern=\&quot;emlib/em_gpio.c\&quot;/&gt;\r\n&lt;/project:MModule&gt;&quot;},{&quot;builtinExcludes&quot;:[],&quot;builtinSources&quot;:[],&quot;builtin&quot;:true,&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/ss/Project.ecore\&quot; builtin=\&quot;true\&quot; id=\&quot;com.silabs.sdk.exx32.board\&quot;/&gt;&quot;},{&quot;builtinExcludes&quot;:[],&quot;builtinSources&quot;:[&quot;CMSIS/EFM32PG1B/startup_gcc_efm32pg1b.s&quot;,&quot;CMSIS/EFM32PG1B/system_efm32pg1b.c&quot;],&quot;builtin&quot;:true,&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/ss/Project.ecore\&quot; builtin=\&quot;true\&quot; id=\&quot;com.silabs.sdk.exx32.part\&quot;/&gt;&quot;},{&quot;builtinExcludes&quot;:[],&quot;builtinSources&quot;:[],&quot;builtin&quot;:true,&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/ss/Project.ecore\&quot; builtin=\&quot;true\&quot; id=\&quot;com.silabs.sdk.exx32.common.bsp\&quot;&gt;\r\n &lt;exclusions pattern=\&quot;.*\&quot;/&gt;\r\n&lt;/project:MModule&gt;&quot;},{&quot;builtinExcludes&quot;:[],&quot;builtinSources&quot;:[],&quot;builtin&quot;:true,&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/ss/Project.ecore\&quot; builtin=\&quot;true\&quot; id=\&quot;com.silabs.sdk.exx32.common.drivers\&quot;&gt;\r\n &lt;exclusions pattern=\&quot;.*\&quot;/&gt;\r\n&lt;/project:MModule&gt;&quot;},{&quot;builtinExcludes&quot;:[],&quot;builtinSources&quot;:[],&quot;builtin&quot;:true,&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/ss/Project.ecore\&quot; builtin=\&quot;true\&quot; id=\&quot;com.silabs.sdk.exx32.common.CMSIS\&quot;&gt;\r\n &lt;exclusions pattern=\&quot;.*\&quot;/&gt;\r\n&lt;/project:MModule&gt;&quot;}]" projectCommon.toolchainId="com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt:7.2.1.20170904"/>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" description="" id="com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt.release#com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt:7.2.1.20170904" name="GNU ARM v7.2.1 - Release" parent="com.silabs.ide.si32.gcc.cdt.managedbuild.config.gnu.exe">
<folderInfo id="com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt.release#com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt:7.2.1.20170904." name="/" resourcePath="">
<toolChain id="com.silabs.ide.si32.gcc.cdt.managedbuild.toolchain.exe.1542058136" name="Si32 GNU ARM" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.toolchain.exe">
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.toolchain.debug.level.704282697" name="Debug Level" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.toolchain.debug.level" value="com.silabs.ide.si32.gcc.cdt.managedbuild.toolchain.debug.level.default" valueType="enumerated"/>
<targetPlatform binaryParser="org.eclipse.cdt.core.ELF;org.eclipse.cdt.core.GNU_ELF;com.silabs.ss.framework.debugger.core.BIN;com.silabs.ss.framework.debugger.core.HEX;com.silabs.ss.framework.debugger.core.S37;com.silabs.ss.framework.debugger.core.EBL;com.silabs.ss.framework.debugger.core.GBL" id="com.silabs.ide.si32.gcc.cdt.managedbuild.target.gnu.platform.base.67671565" isAbstract="false" name="Debug Platform" osList="win32,linux,macosx" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.target.gnu.platform.base"/>
<builder buildPath="${workspace_loc:/efm32boot}/GNU ARM v7.2.1 - Release" id="com.silabs.ide.si32.gcc.cdt.managedbuild.target.gnu.builder.base.805468153" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Si32 GNU ARM Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.target.gnu.builder.base"/>
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.base.1301757596" name="GNU ARM C Compiler" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.base">
<option id="gnu.c.compiler.option.optimization.level.992246362" name="Optimization Level" superClass="gnu.c.compiler.option.optimization.level" value="gnu.c.optimization.level.most" valueType="enumerated"/>
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.def.symbols.1037480919" name="Defined symbols (-D)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.def.symbols" valueType="definedSymbols">
<listOptionValue builtIn="false" value="NDEBUG=1"/>
<listOptionValue builtIn="false" value="EFM32PG1B200F256GM48=1"/>
</option>
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.debug.builtin.951908916" name="Always branch to builtin functions (-fno-builtin)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.debug.builtin" value="false" valueType="boolean"/>
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.debug.prolog.1884913917" name="Generate debugger-friendly prologs (-mno-sched-prolog)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.debug.prolog" value="false" valueType="boolean"/>
<option id="gnu.c.compiler.option.include.paths.1968865334" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/inc}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${ProjDirPath}/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/hardware/kit/common/bsp&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/hardware/kit/SLSTK3401A_EFM32PG/config&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/hardware/kit/common/drivers&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/platform/Device/SiliconLabs/EFM32PG1B/Include&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/platform/CMSIS/Include&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/platform/emlib/inc&quot;"/>
</option>
<inputType id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.input.2075078357" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.input"/>
</tool>
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.base.1495369104" name="GNU ARM C++ Compiler" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.base">
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.debug.builtin.1435596684" name="Always branch to builtin functions (-fno-builtin)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.debug.builtin" value="false" valueType="boolean"/>
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.debug.prolog.258094144" name="Generate debugger-friendly prologs (-mno-sched-prolog)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.debug.prolog" value="false" valueType="boolean"/>
</tool>
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.assembler.base.947557425" name="GNU ARM Assembler" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.assembler.base">
<option id="gnu.both.asm.option.include.paths.220914305" name="Include paths (-I)" superClass="gnu.both.asm.option.include.paths" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/inc}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${ProjDirPath}/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/hardware/kit/common/bsp&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/hardware/kit/SLSTK3401A_EFM32PG/config&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/hardware/kit/common/drivers&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/platform/Device/SiliconLabs/EFM32PG1B/Include&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/platform/CMSIS/Include&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/platform/emlib/inc&quot;"/>
</option>
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.as.def.symbols.1679775183" name="Defined symbols (-D)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.as.def.symbols" valueType="definedSymbols">
<listOptionValue builtIn="false" value="EFM32PG1B200F256GM48=1"/>
</option>
<inputType id="org.eclipse.cdt.core.asmSource.1025131309" superClass="org.eclipse.cdt.core.asmSource"/>
</tool>
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.base.158700898" name="GNU ARM C Linker" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.base">
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.nostdlibs.1339758179" name="No startup or default libs (-nostdlib)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.nostdlibs" value="false" valueType="boolean"/>
<inputType id="cdt.managedbuild.tool.gnu.c.linker.input.1667537250" superClass="cdt.managedbuild.tool.gnu.c.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
</tool>
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.linker.base.305372504" name="GNU ARM C++ Linker" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.linker.base"/>
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.archiver.base.29462529" name="GNU ARM Archiver" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.archiver.base"/>
</toolChain>
</folderInfo>
<sourceEntries>
<entry excluding="efm32/CMSIS/EFM32JG1B|CMSIS/EFM32JG1B" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
</sourceEntries>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
</storageModule>
<storageModule moduleId="com.silabs.ss.framework.ide.project.core.cpp" project.generation="92" projectCommon.boardIds="brd2500a:0.0.0" projectCommon.buildArtifactType="EXE" projectCommon.importModeId="COPY" projectCommon.partId="mcu.arm.efm32.pg1.efm32pg1b200f256gm48" projectCommon.sdkId="com.silabs.sdk.stack.super:1.1.1._310456152"/>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="efm32boot.com.silabs.ss.framework.ide.project.core.cdt.cdtMbsProjectType.501778116" name="SLS CDT Project" projectType="com.silabs.ss.framework.ide.project.core.cdt.cdtMbsProjectType"/>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
<scannerConfigBuildInfo instanceId="com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt.release#com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt:7.2.1.20170904;com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt.release#com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt:7.2.1.20170904.;com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.base.1301757596;com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.input.2075078357">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt.debug#com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt:7.2.1.20170904;com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt.debug#com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt:7.2.1.20170904.;com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.base.981192541;com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.input.486237326">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
</storageModule>
<storageModule moduleId="refreshScope"/>
</cproject>

View File

@ -1,47 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>efm32boot</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<triggers>clean,full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>com.silabs.ss.framework.ide.project.sls.core.SLSProjectNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
</natures>
<linkedResources>
<link>
<name>crypto</name>
<type>2</type>
<locationURI>PARENT-2-PROJECT_LOC/crypto</locationURI>
</link>
<link>
<name>efm32</name>
<type>2</type>
<locationURI>$%7BPARENT-1-PROJECT_LOC%7D/efm32</locationURI>
</link>
<link>
<name>fido2</name>
<type>2</type>
<locationURI>PARENT-2-PROJECT_LOC/fido2</locationURI>
</link>
<link>
<name>CMSIS/EFM32JG1B/startup_gcc_efm32jg1b.s</name>
<type>1</type>
<locationURI>STUDIO_SDK_LOC/platform/Device/SiliconLabs/EFM32JG1B/Source/GCC/startup_efm32jg1b.S</locationURI>
</link>
<link>
<name>CMSIS/EFM32JG1B/system_efm32jg1b.c</name>
<type>1</type>
<locationURI>STUDIO_SDK_LOC/platform/Device/SiliconLabs/EFM32JG1B/Source/system_efm32jg1b.c</locationURI>
</link>
</linkedResources>
</projectDescription>

View File

@ -1,2 +0,0 @@
copiedFilesOriginState={}
eclipse.preferences.version=1

View File

@ -1,317 +0,0 @@
/* @file startup_efm32pg1b.S
* @brief startup file for Silicon Labs EFM32PG1B devices.
* For use with GCC for ARM Embedded Processors
* @version 5.2.2
* Date: 12 June 2014
*
*/
/* Copyright (c) 2011 - 2014 ARM LIMITED
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.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of ARM 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 COPYRIGHT HOLDERS AND CONTRIBUTORS 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.
---------------------------------------------------------------------------*/
.syntax unified
.arch armv7-m
.section .stack
.align 3
#ifdef __STACK_SIZE
.equ Stack_Size, __STACK_SIZE
#else
.equ Stack_Size, 0x00000400
#endif
.globl __StackTop
.globl __StackLimit
__StackLimit:
.space Stack_Size
.size __StackLimit, . - __StackLimit
__StackTop:
.size __StackTop, . - __StackTop
.section .heap
.align 3
#ifdef __HEAP_SIZE
.equ Heap_Size, __HEAP_SIZE
#else
.equ Heap_Size, 0x00000C00
#endif
.globl __HeapBase
.globl __HeapLimit
__HeapBase:
.if Heap_Size
.space Heap_Size
.endif
.size __HeapBase, . - __HeapBase
__HeapLimit:
.size __HeapLimit, . - __HeapLimit
.section .vectors
.align 2
.globl __Vectors
__Vectors:
.long __StackTop /* Top of Stack */
.long Reset_Handler /* Reset Handler */
.long NMI_Handler /* NMI Handler */
.long HardFault_Handler /* Hard Fault Handler */
.long MemManage_Handler /* MPU Fault Handler */
.long BusFault_Handler /* Bus Fault Handler */
.long UsageFault_Handler /* Usage Fault Handler */
.long Default_Handler /* Reserved */
.long Default_Handler /* Reserved */
.long Default_Handler /* Reserved */
.long Default_Handler /* Reserved */
.long SVC_Handler /* SVCall Handler */
.long DebugMon_Handler /* Debug Monitor Handler */
.long Default_Handler /* Reserved */
.long PendSV_Handler /* PendSV Handler */
.long SysTick_Handler /* SysTick Handler */
/* External interrupts */
.long EMU_IRQHandler /* 0 - EMU */
.long Default_Handler /* 1 - Reserved */
.long WDOG0_IRQHandler /* 2 - WDOG0 */
.long Default_Handler /* 3 - Reserved */
.long Default_Handler /* 4 - Reserved */
.long Default_Handler /* 5 - Reserved */
.long Default_Handler /* 6 - Reserved */
.long Default_Handler /* 7 - Reserved */
.long LDMA_IRQHandler /* 8 - LDMA */
.long GPIO_EVEN_IRQHandler /* 9 - GPIO_EVEN */
.long TIMER0_IRQHandler /* 10 - TIMER0 */
.long USART0_RX_IRQHandler /* 11 - USART0_RX */
.long USART0_TX_IRQHandler /* 12 - USART0_TX */
.long ACMP0_IRQHandler /* 13 - ACMP0 */
.long ADC0_IRQHandler /* 14 - ADC0 */
.long IDAC0_IRQHandler /* 15 - IDAC0 */
.long I2C0_IRQHandler /* 16 - I2C0 */
.long GPIO_ODD_IRQHandler /* 17 - GPIO_ODD */
.long TIMER1_IRQHandler /* 18 - TIMER1 */
.long USART1_RX_IRQHandler /* 19 - USART1_RX */
.long USART1_TX_IRQHandler /* 20 - USART1_TX */
.long LEUART0_IRQHandler /* 21 - LEUART0 */
.long PCNT0_IRQHandler /* 22 - PCNT0 */
.long CMU_IRQHandler /* 23 - CMU */
.long MSC_IRQHandler /* 24 - MSC */
.long CRYPTO_IRQHandler /* 25 - CRYPTO */
.long LETIMER0_IRQHandler /* 26 - LETIMER0 */
.long Default_Handler /* 27 - Reserved */
.long Default_Handler /* 28 - Reserved */
.long RTCC_IRQHandler /* 29 - RTCC */
.long Default_Handler /* 30 - Reserved */
.long CRYOTIMER_IRQHandler /* 31 - CRYOTIMER */
.long Default_Handler /* 32 - Reserved */
.long FPUEH_IRQHandler /* 33 - FPUEH */
.size __Vectors, . - __Vectors
.text
.thumb
.thumb_func
.align 2
.globl Reset_Handler
.type Reset_Handler, %function
Reset_Handler:
#ifndef __NO_SYSTEM_INIT
ldr r0, =SystemInit
blx r0
#endif
/* Firstly it copies data from read only memory to RAM. There are two schemes
* to copy. One can copy more than one sections. Another can only copy
* one section. The former scheme needs more instructions and read-only
* data to implement than the latter.
* Macro __STARTUP_COPY_MULTIPLE is used to choose between two schemes. */
#ifdef __STARTUP_COPY_MULTIPLE
/* Multiple sections scheme.
*
* Between symbol address __copy_table_start__ and __copy_table_end__,
* there are array of triplets, each of which specify:
* offset 0: LMA of start of a section to copy from
* offset 4: VMA of start of a section to copy to
* offset 8: size of the section to copy. Must be multiply of 4
*
* All addresses must be aligned to 4 bytes boundary.
*/
ldr r4, =__copy_table_start__
ldr r5, =__copy_table_end__
.L_loop0:
cmp r4, r5
bge .L_loop0_done
ldr r1, [r4]
ldr r2, [r4, #4]
ldr r3, [r4, #8]
.L_loop0_0:
subs r3, #4
ittt ge
ldrge r0, [r1, r3]
strge r0, [r2, r3]
bge .L_loop0_0
adds r4, #12
b .L_loop0
.L_loop0_done:
#else
/* Single section scheme.
*
* The ranges of copy from/to are specified by following symbols
* __etext: LMA of start of the section to copy from. Usually end of text
* __data_start__: VMA of start of the section to copy to
* __data_end__: VMA of end of the section to copy to
*
* All addresses must be aligned to 4 bytes boundary.
*/
ldr r1, =__etext
ldr r2, =__data_start__
ldr r3, =__data_end__
.L_loop1:
cmp r2, r3
ittt lt
ldrlt r0, [r1], #4
strlt r0, [r2], #4
blt .L_loop1
#endif /*__STARTUP_COPY_MULTIPLE */
/* This part of work usually is done in C library startup code. Otherwise,
* define this macro to enable it in this startup.
*
* There are two schemes too. One can clear multiple BSS sections. Another
* can only clear one section. The former is more size expensive than the
* latter.
*
* Define macro __STARTUP_CLEAR_BSS_MULTIPLE to choose the former.
* Otherwise efine macro __STARTUP_CLEAR_BSS to choose the later.
*/
#ifdef __STARTUP_CLEAR_BSS_MULTIPLE
/* Multiple sections scheme.
*
* Between symbol address __zero_table_start__ and __zero_table_end__,
* there are array of tuples specifying:
* offset 0: Start of a BSS section
* offset 4: Size of this BSS section. Must be multiply of 4
*/
ldr r3, =__zero_table_start__
ldr r4, =__zero_table_end__
.L_loop2:
cmp r3, r4
bge .L_loop2_done
ldr r1, [r3]
ldr r2, [r3, #4]
movs r0, 0
.L_loop2_0:
subs r2, #4
itt ge
strge r0, [r1, r2]
bge .L_loop2_0
adds r3, #8
b .L_loop2
.L_loop2_done:
#elif defined (__STARTUP_CLEAR_BSS)
/* Single BSS section scheme.
*
* The BSS section is specified by following symbols
* __bss_start__: start of the BSS section.
* __bss_end__: end of the BSS section.
*
* Both addresses must be aligned to 4 bytes boundary.
*/
ldr r1, =__bss_start__
ldr r2, =__bss_end__
movs r0, 0
.L_loop3:
cmp r1, r2
itt lt
strlt r0, [r1], #4
blt .L_loop3
#endif /* __STARTUP_CLEAR_BSS_MULTIPLE || __STARTUP_CLEAR_BSS */
#ifndef __START
#define __START _start
#endif
bl __START
.pool
.size Reset_Handler, . - Reset_Handler
.align 1
.thumb_func
.weak Default_Handler
.type Default_Handler, %function
Default_Handler:
b .
.size Default_Handler, . - Default_Handler
/* Macro to define default handlers. Default handler
* will be weak symbol and just dead loops. They can be
* overwritten by other handlers */
.macro def_irq_handler handler_name
.weak \handler_name
.set \handler_name, Default_Handler
.endm
def_irq_handler NMI_Handler
def_irq_handler HardFault_Handler
def_irq_handler MemManage_Handler
def_irq_handler BusFault_Handler
def_irq_handler UsageFault_Handler
def_irq_handler SVC_Handler
def_irq_handler DebugMon_Handler
def_irq_handler PendSV_Handler
def_irq_handler SysTick_Handler
def_irq_handler EMU_IRQHandler
def_irq_handler WDOG0_IRQHandler
def_irq_handler LDMA_IRQHandler
def_irq_handler GPIO_EVEN_IRQHandler
def_irq_handler TIMER0_IRQHandler
def_irq_handler USART0_RX_IRQHandler
def_irq_handler USART0_TX_IRQHandler
def_irq_handler ACMP0_IRQHandler
def_irq_handler ADC0_IRQHandler
def_irq_handler IDAC0_IRQHandler
def_irq_handler I2C0_IRQHandler
def_irq_handler GPIO_ODD_IRQHandler
def_irq_handler TIMER1_IRQHandler
def_irq_handler USART1_RX_IRQHandler
def_irq_handler USART1_TX_IRQHandler
def_irq_handler LEUART0_IRQHandler
def_irq_handler PCNT0_IRQHandler
def_irq_handler CMU_IRQHandler
def_irq_handler MSC_IRQHandler
def_irq_handler CRYPTO_IRQHandler
def_irq_handler LETIMER0_IRQHandler
def_irq_handler RTCC_IRQHandler
def_irq_handler CRYOTIMER_IRQHandler
def_irq_handler FPUEH_IRQHandler
.end

View File

@ -1,389 +0,0 @@
/***************************************************************************//**
* @file system_efm32pg1b.c
* @brief CMSIS Cortex-M3/M4 System Layer for EFM32 devices.
* @version 5.2.2
******************************************************************************
* # License
* <b>Copyright 2017 Silicon Laboratories, Inc. http://www.silabs.com</b>
******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.@n
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.@n
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Laboratories, Inc.
* has no obligation to support this Software. Silicon Laboratories, Inc. is
* providing the Software "AS IS", with no express or implied warranties of any
* kind, including, but not limited to, any implied warranties of
* merchantability or fitness for any particular purpose or warranties against
* infringement of any proprietary rights of a third party.
*
* Silicon Laboratories, Inc. will not be liable for any consequential,
* incidental, or special damages, or any other relief, or for any claim by
* any third party, arising from your use of this Software.
*
*****************************************************************************/
#include <stdint.h>
#include "em_device.h"
/*******************************************************************************
****************************** DEFINES ************************************
******************************************************************************/
/** LFRCO frequency, tuned to below frequency during manufacturing. */
#define EFM32_LFRCO_FREQ (32768UL)
/** ULFRCO frequency */
#define EFM32_ULFRCO_FREQ (1000UL)
/*******************************************************************************
************************** LOCAL VARIABLES ********************************
******************************************************************************/
/* System oscillator frequencies. These frequencies are normally constant */
/* for a target, but they are made configurable in order to allow run-time */
/* handling of different boards. The crystal oscillator clocks can be set */
/* compile time to a non-default value by defining respective EFM_nFXO_FREQ */
/* values according to board design. By defining the EFM_nFXO_FREQ to 0, */
/* one indicates that the oscillator is not present, in order to save some */
/* SW footprint. */
#ifndef EFM32_HFRCO_MAX_FREQ
/** Maximum HFRCO frequency */
#define EFM32_HFRCO_MAX_FREQ (38000000UL)
#endif
#ifndef EFM32_HFXO_FREQ
/** HFXO frequency */
#define EFM32_HFXO_FREQ (40000000UL)
#endif
#ifndef EFM32_HFRCO_STARTUP_FREQ
/** HFRCO startup frequency */
#define EFM32_HFRCO_STARTUP_FREQ (19000000UL)
#endif
/* Do not define variable if HF crystal oscillator not present */
#if (EFM32_HFXO_FREQ > 0UL)
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/** System HFXO clock. */
static uint32_t SystemHFXOClock = EFM32_HFXO_FREQ;
/** @endcond (DO_NOT_INCLUDE_WITH_DOXYGEN) */
#endif
#ifndef EFM32_LFXO_FREQ
/** LFXO frequency */
#define EFM32_LFXO_FREQ (EFM32_LFRCO_FREQ)
#endif
/* Do not define variable if LF crystal oscillator not present */
#if (EFM32_LFXO_FREQ > 0UL)
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/** System LFXO clock. */
static uint32_t SystemLFXOClock = 32768UL;
/** @endcond (DO_NOT_INCLUDE_WITH_DOXYGEN) */
#endif
/*******************************************************************************
************************** GLOBAL VARIABLES *******************************
******************************************************************************/
/**
* @brief
* System System Clock Frequency (Core Clock).
*
* @details
* Required CMSIS global variable that must be kept up-to-date.
*/
uint32_t SystemCoreClock = EFM32_HFRCO_STARTUP_FREQ;
/**
* @brief
* System HFRCO frequency
*
* @note
* This is an EFM32 proprietary variable, not part of the CMSIS definition.
*
* @details
* Frequency of the system HFRCO oscillator
*/
uint32_t SystemHfrcoFreq = EFM32_HFRCO_STARTUP_FREQ;
/*******************************************************************************
************************** GLOBAL FUNCTIONS *******************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Get the current core clock frequency.
*
* @details
* Calculate and get the current core clock frequency based on the current
* configuration. Assuming that the SystemCoreClock global variable is
* maintained, the core clock frequency is stored in that variable as well.
* This function will however calculate the core clock based on actual HW
* configuration. It will also update the SystemCoreClock global variable.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @return
* The current core clock frequency in Hz.
******************************************************************************/
uint32_t SystemCoreClockGet(void)
{
uint32_t ret;
uint32_t presc;
ret = SystemHFClockGet();
presc = (CMU->HFCOREPRESC & _CMU_HFCOREPRESC_PRESC_MASK) >>
_CMU_HFCOREPRESC_PRESC_SHIFT;
ret /= (presc + 1);
/* Keep CMSIS system clock variable up-to-date */
SystemCoreClock = ret;
return ret;
}
/***************************************************************************//**
* @brief
* Get the maximum core clock frequency.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @return
* The maximum core clock frequency in Hz.
******************************************************************************/
uint32_t SystemMaxCoreClockGet(void)
{
return (EFM32_HFRCO_MAX_FREQ > EFM32_HFXO_FREQ ? \
EFM32_HFRCO_MAX_FREQ : EFM32_HFXO_FREQ);
}
/***************************************************************************//**
* @brief
* Get the current HFCLK frequency.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @return
* The current HFCLK frequency in Hz.
******************************************************************************/
uint32_t SystemHFClockGet(void)
{
uint32_t ret;
switch (CMU->HFCLKSTATUS & _CMU_HFCLKSTATUS_SELECTED_MASK)
{
case CMU_HFCLKSTATUS_SELECTED_LFXO:
#if (EFM32_LFXO_FREQ > 0)
ret = SystemLFXOClock;
#else
/* We should not get here, since core should not be clocked. May */
/* be caused by a misconfiguration though. */
ret = 0;
#endif
break;
case CMU_HFCLKSTATUS_SELECTED_LFRCO:
ret = EFM32_LFRCO_FREQ;
break;
case CMU_HFCLKSTATUS_SELECTED_HFXO:
#if (EFM32_HFXO_FREQ > 0)
ret = SystemHFXOClock;
#else
/* We should not get here, since core should not be clocked. May */
/* be caused by a misconfiguration though. */
ret = 0;
#endif
break;
default: /* CMU_HFCLKSTATUS_SELECTED_HFRCO */
ret = SystemHfrcoFreq;
break;
}
return ret / (1U + ((CMU->HFPRESC & _CMU_HFPRESC_PRESC_MASK)
>> _CMU_HFPRESC_PRESC_SHIFT));
}
/**************************************************************************//**
* @brief
* Get high frequency crystal oscillator clock frequency for target system.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @return
* HFXO frequency in Hz.
*****************************************************************************/
uint32_t SystemHFXOClockGet(void)
{
/* External crystal oscillator present? */
#if (EFM32_HFXO_FREQ > 0)
return SystemHFXOClock;
#else
return 0;
#endif
}
/**************************************************************************//**
* @brief
* Set high frequency crystal oscillator clock frequency for target system.
*
* @note
* This function is mainly provided for being able to handle target systems
* with different HF crystal oscillator frequencies run-time. If used, it
* should probably only be used once during system startup.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @param[in] freq
* HFXO frequency in Hz used for target.
*****************************************************************************/
void SystemHFXOClockSet(uint32_t freq)
{
/* External crystal oscillator present? */
#if (EFM32_HFXO_FREQ > 0)
SystemHFXOClock = freq;
/* Update core clock frequency if HFXO is used to clock core */
if ((CMU->HFCLKSTATUS & _CMU_HFCLKSTATUS_SELECTED_MASK) == CMU_HFCLKSTATUS_SELECTED_HFXO)
{
/* The function will update the global variable */
SystemCoreClockGet();
}
#else
(void)freq; /* Unused parameter */
#endif
}
/**************************************************************************//**
* @brief
* Initialize the system.
*
* @details
* Do required generic HW system init.
*
* @note
* This function is invoked during system init, before the main() routine
* and any data has been initialized. For this reason, it cannot do any
* initialization of variables etc.
*****************************************************************************/
void SystemInit(void)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
/* Set floating point coprosessor access mode. */
SCB->CPACR |= ((3UL << 10*2) | /* set CP10 Full Access */
(3UL << 11*2) ); /* set CP11 Full Access */
#endif
}
/**************************************************************************//**
* @brief
* Get low frequency RC oscillator clock frequency for target system.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @return
* LFRCO frequency in Hz.
*****************************************************************************/
uint32_t SystemLFRCOClockGet(void)
{
/* Currently we assume that this frequency is properly tuned during */
/* manufacturing and is not changed after reset. If future requirements */
/* for re-tuning by user, we can add support for that. */
return EFM32_LFRCO_FREQ;
}
/**************************************************************************//**
* @brief
* Get ultra low frequency RC oscillator clock frequency for target system.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @return
* ULFRCO frequency in Hz.
*****************************************************************************/
uint32_t SystemULFRCOClockGet(void)
{
/* The ULFRCO frequency is not tuned, and can be very inaccurate */
return EFM32_ULFRCO_FREQ;
}
/**************************************************************************//**
* @brief
* Get low frequency crystal oscillator clock frequency for target system.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @return
* LFXO frequency in Hz.
*****************************************************************************/
uint32_t SystemLFXOClockGet(void)
{
/* External crystal oscillator present? */
#if (EFM32_LFXO_FREQ > 0)
return SystemLFXOClock;
#else
return 0;
#endif
}
/**************************************************************************//**
* @brief
* Set low frequency crystal oscillator clock frequency for target system.
*
* @note
* This function is mainly provided for being able to handle target systems
* with different HF crystal oscillator frequencies run-time. If used, it
* should probably only be used once during system startup.
*
* @note
* This is an EFM32 proprietary function, not part of the CMSIS definition.
*
* @param[in] freq
* LFXO frequency in Hz used for target.
*****************************************************************************/
void SystemLFXOClockSet(uint32_t freq)
{
/* External crystal oscillator present? */
#if (EFM32_LFXO_FREQ > 0)
SystemLFXOClock = freq;
/* Update core clock frequency if LFXO is used to clock core */
if ((CMU->HFCLKSTATUS & _CMU_HFCLKSTATUS_SELECTED_MASK) == CMU_HFCLKSTATUS_SELECTED_LFXO)
{
/* The function will update the global variable */
SystemCoreClockGet();
}
#else
(void)freq; /* Unused parameter */
#endif
}

View File

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="ASCII"?>
<device:XMLDevice xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:device="http://www.silabs.com/ss/hwconfig/document/device.ecore" name="EFM32PG1B200F256GM48" partId="mcu.arm.efm32.pg1.efm32pg1b200f256gm48" contextId="%DEFAULT%">
<mode name="DefaultMode">
<property object="DefaultMode" propertyId="mode.diagramLocation" value="100, 100"/>
</mode>
<modeTransition>
<property object="RESET &#x2192; DefaultMode" propertyId="modeTransition.source" value="RESET"/>
<property object="RESET &#x2192; DefaultMode" propertyId="modeTransition.target" value="DefaultMode"/>
</modeTransition>
</device:XMLDevice>

View File

@ -1,81 +0,0 @@
/***************************************************************************//**
* @file em_assert.c
* @brief Assert API
* @version 5.2.2
*******************************************************************************
* # License
* <b>Copyright 2016 Silicon Laboratories, Inc. http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "em_assert.h"
#include <stdbool.h>
/***************************************************************************//**
* @addtogroup emlib
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup ASSERT
* @{
******************************************************************************/
#if defined(DEBUG_EFM)
/***************************************************************************//**
* @brief
* EFM internal assert handling.
*
* This function is invoked through EFM_ASSERT() macro usage only, it should
* not be used explicitly.
*
* This implementation simply enters an indefinite loop, allowing
* the use of a debugger to determine cause of failure. By defining
* DEBUG_EFM_USER to the preprocessor for all files, a user defined version
* of this function must be defined and will be invoked instead, possibly
* providing output of assertion location.
*
* @note
* This function is not used unless @ref DEBUG_EFM is defined
* during preprocessing of EFM_ASSERT() usage.
*
* @param[in] file
* Name of source file where assertion failed.
*
* @param[in] line
* Line number in source file where assertion failed.
******************************************************************************/
void assertEFM(const char *file, int line)
{
(void)file; /* Unused parameter */
(void)line; /* Unused parameter */
while (true) {
}
}
#endif /* DEBUG_EFM */
/** @} (end addtogroup ASSERT) */
/** @} (end addtogroup emlib) */

File diff suppressed because it is too large Load Diff

View File

@ -1,61 +0,0 @@
/***************************************************************************//**
* @file em_cryotimer.c
* @brief Ultra Low Energy Timer/Counter (CRYOTIMER) peripheral API
* @version 5.2.2
*******************************************************************************
* # License
* <b>Copyright 2016 Silicon Laboratories, Inc. http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.@n
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.@n
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "em_cryotimer.h"
#include "em_bus.h"
#if defined(CRYOTIMER_PRESENT) && (CRYOTIMER_COUNT == 1)
/***************************************************************************//**
* @brief
* Initialize the CRYOTIMER.
*
* @details
* Use this function to initialize the CRYOTIMER.
* Select prescaler setting and select low frequency oscillator.
* Refer to the configuration structure @ref CRYOTIMER_Init_TypeDef for more
* details.
*
* @param[in] init
* Pointer to initialization structure.
******************************************************************************/
void CRYOTIMER_Init(const CRYOTIMER_Init_TypeDef *init)
{
CRYOTIMER->PERIODSEL = (uint32_t)init->period & _CRYOTIMER_PERIODSEL_MASK;
CRYOTIMER->CTRL = ((uint32_t)init->enable << _CRYOTIMER_CTRL_EN_SHIFT)
| ((uint32_t)init->debugRun << _CRYOTIMER_CTRL_DEBUGRUN_SHIFT)
| ((uint32_t)init->osc << _CRYOTIMER_CTRL_OSCSEL_SHIFT)
| ((uint32_t)init->presc << _CRYOTIMER_CTRL_PRESC_SHIFT);
CRYOTIMER_EM4WakeupEnable(init->em4Wakeup);
}
#endif /* defined(CRYOTIMER_PRESENT) && (CRYOTIMER_COUNT > 0) */

File diff suppressed because it is too large Load Diff

View File

@ -1,367 +0,0 @@
/***************************************************************************//**
* @file em_gpio.c
* @brief General Purpose IO (GPIO) peripheral API
* devices.
* @version 5.2.2
*******************************************************************************
* # License
* <b>Copyright 2016 Silicon Laboratories, Inc. http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "em_gpio.h"
#if defined(GPIO_COUNT) && (GPIO_COUNT > 0)
/***************************************************************************//**
* @addtogroup emlib
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup GPIO
* @brief General Purpose Input/Output (GPIO) API
* @details
* This module contains functions to control the GPIO peripheral of Silicon
* Labs 32-bit MCUs and SoCs. The GPIO peripheral is used for pin configuration
* and direct pin manipulation and sensing as well as routing for peripheral
* pin connections.
* @{
******************************************************************************/
/*******************************************************************************
******************************* DEFINES ***********************************
******************************************************************************/
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
/** Validation of pin typically usable in assert statements. */
#define GPIO_DRIVEMODE_VALID(mode) ((mode) <= 3)
#define GPIO_STRENGHT_VALID(strenght) (!((strenght) \
& ~(_GPIO_P_CTRL_DRIVESTRENGTH_MASK \
| _GPIO_P_CTRL_DRIVESTRENGTHALT_MASK)))
/** @endcond */
/*******************************************************************************
************************** GLOBAL FUNCTIONS *******************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Sets the pin location of the debug pins (Serial Wire interface).
*
* @note
* Changing the pins used for debugging uncontrolled, may result in a lockout.
*
* @param[in] location
* The debug pin location to use (0-3).
******************************************************************************/
void GPIO_DbgLocationSet(unsigned int location)
{
#if defined (_GPIO_ROUTE_SWLOCATION_MASK)
EFM_ASSERT(location < AFCHANLOC_MAX);
GPIO->ROUTE = (GPIO->ROUTE & ~_GPIO_ROUTE_SWLOCATION_MASK)
| (location << _GPIO_ROUTE_SWLOCATION_SHIFT);
#else
(void)location;
#endif
}
#if defined (_GPIO_P_CTRL_DRIVEMODE_MASK)
/***************************************************************************//**
* @brief
* Sets the drive mode for a GPIO port.
*
* @param[in] port
* The GPIO port to access.
*
* @param[in] mode
* Drive mode to use for port.
******************************************************************************/
void GPIO_DriveModeSet(GPIO_Port_TypeDef port, GPIO_DriveMode_TypeDef mode)
{
EFM_ASSERT(GPIO_PORT_VALID(port) && GPIO_DRIVEMODE_VALID(mode));
GPIO->P[port].CTRL = (GPIO->P[port].CTRL & ~(_GPIO_P_CTRL_DRIVEMODE_MASK))
| (mode << _GPIO_P_CTRL_DRIVEMODE_SHIFT);
}
#endif
#if defined (_GPIO_P_CTRL_DRIVESTRENGTH_MASK)
/***************************************************************************//**
* @brief
* Sets the drive strength for a GPIO port.
*
* @param[in] port
* The GPIO port to access.
*
* @param[in] strength
* Drive strength to use for port.
******************************************************************************/
void GPIO_DriveStrengthSet(GPIO_Port_TypeDef port,
GPIO_DriveStrength_TypeDef strength)
{
EFM_ASSERT(GPIO_PORT_VALID(port) && GPIO_STRENGHT_VALID(strength));
BUS_RegMaskedWrite(&GPIO->P[port].CTRL,
_GPIO_P_CTRL_DRIVESTRENGTH_MASK | _GPIO_P_CTRL_DRIVESTRENGTHALT_MASK,
strength);
}
#endif
/***************************************************************************//**
* @brief
* Configure GPIO external pin interrupt.
*
* @details
* If reconfiguring a GPIO interrupt that is already enabled, it is generally
* recommended to disable it first, see GPIO_Disable().
*
* The actual GPIO interrupt handler must be in place before enabling the
* interrupt.
*
* Notice that any pending interrupt for the selected interrupt is cleared
* by this function.
*
* @note
* On series 0 devices the pin number parameter is not used. The
* pin number used on these devices is hardwired to the interrupt with the
* same number. @n
* On series 1 devices, pin number can be selected freely within a group.
* Interrupt numbers are divided into 4 groups (intNo / 4) and valid pin
* number within the interrupt groups are:
* 0: pins 0-3
* 1: pins 4-7
* 2: pins 8-11
* 3: pins 12-15
*
* @param[in] port
* The port to associate with @p pin.
*
* @param[in] pin
* The pin number on the port.
*
* @param[in] intNo
* The interrupt number to trigger.
*
* @param[in] risingEdge
* Set to true if interrupts shall be enabled on rising edge, otherwise false.
*
* @param[in] fallingEdge
* Set to true if interrupts shall be enabled on falling edge, otherwise false.
*
* @param[in] enable
* Set to true if interrupt shall be enabled after configuration completed,
* false to leave disabled. See GPIO_IntDisable() and GPIO_IntEnable().
******************************************************************************/
void GPIO_ExtIntConfig(GPIO_Port_TypeDef port,
unsigned int pin,
unsigned int intNo,
bool risingEdge,
bool fallingEdge,
bool enable)
{
uint32_t tmp = 0;
#if !defined(_GPIO_EXTIPINSELL_MASK)
(void)pin;
#endif
EFM_ASSERT(GPIO_PORT_PIN_VALID(port, pin));
#if defined(_GPIO_EXTIPINSELL_MASK)
EFM_ASSERT(GPIO_INTNO_PIN_VALID(intNo, pin));
#endif
/* There are two registers controlling the interrupt configuration:
* The EXTIPSELL register controls pins 0-7 and EXTIPSELH controls
* pins 8-15. */
if (intNo < 8) {
BUS_RegMaskedWrite(&GPIO->EXTIPSELL,
_GPIO_EXTIPSELL_EXTIPSEL0_MASK
<< (_GPIO_EXTIPSELL_EXTIPSEL1_SHIFT * intNo),
port << (_GPIO_EXTIPSELL_EXTIPSEL1_SHIFT * intNo));
} else {
tmp = intNo - 8;
BUS_RegMaskedWrite(&GPIO->EXTIPSELH,
_GPIO_EXTIPSELH_EXTIPSEL8_MASK
<< (_GPIO_EXTIPSELH_EXTIPSEL9_SHIFT * tmp),
port << (_GPIO_EXTIPSELH_EXTIPSEL9_SHIFT * tmp));
}
#if defined(_GPIO_EXTIPINSELL_MASK)
/* There are two registers controlling the interrupt/pin number mapping:
* The EXTIPINSELL register controls interrupt 0-7 and EXTIPINSELH controls
* interrupt 8-15. */
if (intNo < 8) {
BUS_RegMaskedWrite(&GPIO->EXTIPINSELL,
_GPIO_EXTIPINSELL_EXTIPINSEL0_MASK
<< (_GPIO_EXTIPINSELL_EXTIPINSEL1_SHIFT * intNo),
((pin % 4) & _GPIO_EXTIPINSELL_EXTIPINSEL0_MASK)
<< (_GPIO_EXTIPINSELL_EXTIPINSEL1_SHIFT * intNo));
} else {
BUS_RegMaskedWrite(&GPIO->EXTIPINSELH,
_GPIO_EXTIPINSELH_EXTIPINSEL8_MASK
<< (_GPIO_EXTIPINSELH_EXTIPINSEL9_SHIFT * tmp),
((pin % 4) & _GPIO_EXTIPINSELH_EXTIPINSEL8_MASK)
<< (_GPIO_EXTIPSELH_EXTIPSEL9_SHIFT * tmp));
}
#endif
/* Enable/disable rising edge */
BUS_RegBitWrite(&(GPIO->EXTIRISE), intNo, risingEdge);
/* Enable/disable falling edge */
BUS_RegBitWrite(&(GPIO->EXTIFALL), intNo, fallingEdge);
/* Clear any pending interrupt */
GPIO->IFC = 1 << intNo;
/* Finally enable/disable interrupt */
BUS_RegBitWrite(&(GPIO->IEN), intNo, enable);
}
/***************************************************************************//**
* @brief
* Set the mode for a GPIO pin.
*
* @param[in] port
* The GPIO port to access.
*
* @param[in] pin
* The pin number in the port.
*
* @param[in] mode
* The desired pin mode.
*
* @param[in] out
* Value to set for pin in DOUT register. The DOUT setting is important for
* even some input mode configurations, determining pull-up/down direction.
******************************************************************************/
void GPIO_PinModeSet(GPIO_Port_TypeDef port,
unsigned int pin,
GPIO_Mode_TypeDef mode,
unsigned int out)
{
EFM_ASSERT(GPIO_PORT_PIN_VALID(port, pin));
/* If disabling pin, do not modify DOUT in order to reduce chance for */
/* glitch/spike (may not be sufficient precaution in all use cases) */
if (mode != gpioModeDisabled) {
if (out) {
GPIO_PinOutSet(port, pin);
} else {
GPIO_PinOutClear(port, pin);
}
}
/* There are two registers controlling the pins for each port. The MODEL
* register controls pins 0-7 and MODEH controls pins 8-15. */
if (pin < 8) {
GPIO->P[port].MODEL = (GPIO->P[port].MODEL & ~(0xFu << (pin * 4)))
| (mode << (pin * 4));
} else {
GPIO->P[port].MODEH = (GPIO->P[port].MODEH & ~(0xFu << ((pin - 8) * 4)))
| (mode << ((pin - 8) * 4));
}
if (mode == gpioModeDisabled) {
if (out) {
GPIO_PinOutSet(port, pin);
} else {
GPIO_PinOutClear(port, pin);
}
}
}
/***************************************************************************//**
* @brief
* Get the mode for a GPIO pin.
*
* @param[in] port
* The GPIO port to access.
*
* @param[in] pin
* The pin number in the port.
*
* @return
* The pin mode.
******************************************************************************/
GPIO_Mode_TypeDef GPIO_PinModeGet(GPIO_Port_TypeDef port,
unsigned int pin)
{
EFM_ASSERT(GPIO_PORT_PIN_VALID(port, pin));
if (pin < 8) {
return (GPIO_Mode_TypeDef) ((GPIO->P[port].MODEL >> (pin * 4)) & 0xF);
} else {
return (GPIO_Mode_TypeDef) ((GPIO->P[port].MODEH >> ((pin - 8) * 4)) & 0xF);
}
}
#if defined(_GPIO_EM4WUEN_MASK)
/**************************************************************************//**
* @brief
* Enable GPIO pin wake-up from EM4. When the function exits,
* EM4 mode can be safely entered.
*
* @note
* It is assumed that the GPIO pin modes are set correctly.
* Valid modes are @ref gpioModeInput and @ref gpioModeInputPull.
*
* @param[in] pinmask
* Bitmask containing the bitwise logic OR of which GPIO pin(s) to enable.
* Refer to Reference Manuals for pinmask to GPIO port/pin mapping.
* @param[in] polaritymask
* Bitmask containing the bitwise logic OR of GPIO pin(s) wake-up polarity.
* Refer to Reference Manuals for pinmask to GPIO port/pin mapping.
*****************************************************************************/
void GPIO_EM4EnablePinWakeup(uint32_t pinmask, uint32_t polaritymask)
{
EFM_ASSERT((pinmask & ~_GPIO_EM4WUEN_MASK) == 0);
#if defined(_GPIO_EM4WUPOL_MASK)
EFM_ASSERT((polaritymask & ~_GPIO_EM4WUPOL_MASK) == 0);
GPIO->EM4WUPOL &= ~pinmask; /* Set wakeup polarity */
GPIO->EM4WUPOL |= pinmask & polaritymask;
#elif defined(_GPIO_EXTILEVEL_MASK)
EFM_ASSERT((polaritymask & ~_GPIO_EXTILEVEL_MASK) == 0);
GPIO->EXTILEVEL &= ~pinmask;
GPIO->EXTILEVEL |= pinmask & polaritymask;
#endif
GPIO->EM4WUEN |= pinmask; /* Enable wakeup */
GPIO_EM4SetPinRetention(true); /* Enable pin retention */
#if defined(_GPIO_CMD_EM4WUCLR_MASK)
GPIO->CMD = GPIO_CMD_EM4WUCLR; /* Clear wake-up logic */
#elif defined(_GPIO_IFC_EM4WU_MASK)
GPIO_IntClear(pinmask);
#endif
}
#endif
/** @} (end addtogroup GPIO) */
/** @} (end addtogroup emlib) */
#endif /* defined(GPIO_COUNT) && (GPIO_COUNT > 0) */

File diff suppressed because it is too large Load Diff

View File

@ -1,114 +0,0 @@
/***************************************************************************//**
* @file em_system.c
* @brief System Peripheral API
* @version 5.2.2
*******************************************************************************
* # License
* <b>Copyright 2016 Silicon Laboratories, Inc. http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "em_system.h"
#include "em_assert.h"
#include <stddef.h>
/***************************************************************************//**
* @addtogroup emlib
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup SYSTEM
* @{
******************************************************************************/
/*******************************************************************************
************************** GLOBAL FUNCTIONS *******************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Get chip major/minor revision.
*
* @param[out] rev
* Location to place chip revision info.
******************************************************************************/
void SYSTEM_ChipRevisionGet(SYSTEM_ChipRevision_TypeDef *rev)
{
uint8_t tmp;
EFM_ASSERT(rev);
/* CHIP FAMILY bit [5:2] */
tmp = (((ROMTABLE->PID1 & _ROMTABLE_PID1_FAMILYMSB_MASK) >> _ROMTABLE_PID1_FAMILYMSB_SHIFT) << 2);
/* CHIP FAMILY bit [1:0] */
tmp |= ((ROMTABLE->PID0 & _ROMTABLE_PID0_FAMILYLSB_MASK) >> _ROMTABLE_PID0_FAMILYLSB_SHIFT);
rev->family = tmp;
/* CHIP MAJOR bit [3:0] */
rev->major = (ROMTABLE->PID0 & _ROMTABLE_PID0_REVMAJOR_MASK) >> _ROMTABLE_PID0_REVMAJOR_SHIFT;
/* CHIP MINOR bit [7:4] */
tmp = (((ROMTABLE->PID2 & _ROMTABLE_PID2_REVMINORMSB_MASK) >> _ROMTABLE_PID2_REVMINORMSB_SHIFT) << 4);
/* CHIP MINOR bit [3:0] */
tmp |= ((ROMTABLE->PID3 & _ROMTABLE_PID3_REVMINORLSB_MASK) >> _ROMTABLE_PID3_REVMINORLSB_SHIFT);
rev->minor = tmp;
}
/***************************************************************************//**
* @brief
* Get factory calibration value for a given peripheral register.
*
* @param[in] regAddress
* Peripheral calibration register address to get calibration value for. If
* a calibration value is found then this register is updated with the
* calibration value.
*
* @return
* True if a calibration value exists, false otherwise.
******************************************************************************/
bool SYSTEM_GetCalibrationValue(volatile uint32_t *regAddress)
{
SYSTEM_CalAddrVal_TypeDef * p, * end;
p = (SYSTEM_CalAddrVal_TypeDef *)(DEVINFO_BASE & 0xFFFFF000);
end = (SYSTEM_CalAddrVal_TypeDef *)DEVINFO_BASE;
for (; p < end; p++) {
if (p->address == 0xFFFFFFFF) {
/* Found table terminator */
return false;
}
if (p->address == (uint32_t)regAddress) {
*regAddress = p->calValue;
return true;
}
}
/* Nothing found for regAddress */
return false;
}
/** @} (end addtogroup SYSTEM) */
/** @} (end addtogroup emlib) */

View File

@ -1,253 +0,0 @@
/***************************************************************************//**
* @file em_timer.c
* @brief Timer/counter (TIMER) Peripheral API
* @version 5.2.2
*******************************************************************************
* # License
* <b>Copyright 2016 Silicon Laboratories, Inc. http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "em_timer.h"
#if defined(TIMER_COUNT) && (TIMER_COUNT > 0)
#include "em_assert.h"
/***************************************************************************//**
* @addtogroup emlib
* @{
******************************************************************************/
/***************************************************************************//**
* @addtogroup TIMER
* @brief Timer/Counter (TIMER) Peripheral API
* @details
* The timer module consists of three main parts:
* @li General timer config and enable control.
* @li Compare/capture control.
* @li Dead time insertion control (may not be available for all timers).
* @{
******************************************************************************/
/*******************************************************************************
************************** GLOBAL FUNCTIONS *******************************
******************************************************************************/
/***************************************************************************//**
* @brief
* Initialize TIMER.
*
* @details
* Notice that counter top must be configured separately with for instance
* TIMER_TopSet(). In addition, compare/capture and dead-time insertion
* init must be initialized separately if used. That should probably
* be done prior to the use of this function if configuring the TIMER to
* start when initialization is completed.
*
* @param[in] timer
* Pointer to TIMER peripheral register block.
*
* @param[in] init
* Pointer to TIMER initialization structure.
******************************************************************************/
void TIMER_Init(TIMER_TypeDef *timer, const TIMER_Init_TypeDef *init)
{
EFM_ASSERT(TIMER_REF_VALID(timer));
/* Stop timer if specified to be disabled (dosn't hurt if already stopped) */
if (!(init->enable)) {
timer->CMD = TIMER_CMD_STOP;
}
/* Reset counter */
timer->CNT = _TIMER_CNT_RESETVALUE;
timer->CTRL = ((uint32_t)(init->prescale) << _TIMER_CTRL_PRESC_SHIFT)
| ((uint32_t)(init->clkSel) << _TIMER_CTRL_CLKSEL_SHIFT)
| ((uint32_t)(init->fallAction) << _TIMER_CTRL_FALLA_SHIFT)
| ((uint32_t)(init->riseAction) << _TIMER_CTRL_RISEA_SHIFT)
| ((uint32_t)(init->mode) << _TIMER_CTRL_MODE_SHIFT)
| (init->debugRun ? TIMER_CTRL_DEBUGRUN : 0)
| (init->dmaClrAct ? TIMER_CTRL_DMACLRACT : 0)
| (init->quadModeX4 ? TIMER_CTRL_QDM_X4 : 0)
| (init->oneShot ? TIMER_CTRL_OSMEN : 0)
#if defined(TIMER_CTRL_X2CNT) && defined(TIMER_CTRL_ATI)
| (init->count2x ? TIMER_CTRL_X2CNT : 0)
| (init->ati ? TIMER_CTRL_ATI : 0)
#endif
| (init->sync ? TIMER_CTRL_SYNC : 0);
/* Start timer if specified to be enabled (dosn't hurt if already started) */
if (init->enable) {
timer->CMD = TIMER_CMD_START;
}
}
/***************************************************************************//**
* @brief
* Initialize TIMER compare/capture channel.
*
* @details
* Notice that if operating channel in compare mode, the CCV and CCVB register
* must be set separately as required.
*
* @param[in] timer
* Pointer to TIMER peripheral register block.
*
* @param[in] ch
* Compare/capture channel to init for.
*
* @param[in] init
* Pointer to TIMER initialization structure.
******************************************************************************/
void TIMER_InitCC(TIMER_TypeDef *timer,
unsigned int ch,
const TIMER_InitCC_TypeDef *init)
{
EFM_ASSERT(TIMER_REF_VALID(timer));
EFM_ASSERT(TIMER_CH_VALID(ch));
timer->CC[ch].CTRL =
((uint32_t)(init->eventCtrl) << _TIMER_CC_CTRL_ICEVCTRL_SHIFT)
| ((uint32_t)(init->edge) << _TIMER_CC_CTRL_ICEDGE_SHIFT)
| ((uint32_t)(init->prsSel) << _TIMER_CC_CTRL_PRSSEL_SHIFT)
| ((uint32_t)(init->cufoa) << _TIMER_CC_CTRL_CUFOA_SHIFT)
| ((uint32_t)(init->cofoa) << _TIMER_CC_CTRL_COFOA_SHIFT)
| ((uint32_t)(init->cmoa) << _TIMER_CC_CTRL_CMOA_SHIFT)
| ((uint32_t)(init->mode) << _TIMER_CC_CTRL_MODE_SHIFT)
| (init->filter ? TIMER_CC_CTRL_FILT_ENABLE : 0)
| (init->prsInput ? TIMER_CC_CTRL_INSEL_PRS : 0)
| (init->coist ? TIMER_CC_CTRL_COIST : 0)
| (init->outInvert ? TIMER_CC_CTRL_OUTINV : 0);
}
#if defined(_TIMER_DTCTRL_MASK)
/***************************************************************************//**
* @brief
* Initialize the TIMER DTI unit.
*
* @param[in] timer
* Pointer to TIMER peripheral register block.
*
* @param[in] init
* Pointer to TIMER DTI initialization structure.
******************************************************************************/
void TIMER_InitDTI(TIMER_TypeDef *timer, const TIMER_InitDTI_TypeDef *init)
{
EFM_ASSERT(TIMER0 == timer);
/* Make sure the DTI unit is disabled while initializing. */
TIMER_EnableDTI(timer, false);
/* Setup the DTCTRL register.
The enable bit will be set at the end of the function if specified. */
timer->DTCTRL =
(init->autoRestart ? TIMER_DTCTRL_DTDAS : 0)
| (init->activeLowOut ? TIMER_DTCTRL_DTIPOL : 0)
| (init->invertComplementaryOut ? TIMER_DTCTRL_DTCINV : 0)
| (init->enablePrsSource ? TIMER_DTCTRL_DTPRSEN : 0)
| ((uint32_t)(init->prsSel) << _TIMER_DTCTRL_DTPRSSEL_SHIFT);
/* Setup the DTTIME register. */
timer->DTTIME =
((uint32_t)(init->prescale) << _TIMER_DTTIME_DTPRESC_SHIFT)
| ((uint32_t)(init->riseTime) << _TIMER_DTTIME_DTRISET_SHIFT)
| ((uint32_t)(init->fallTime) << _TIMER_DTTIME_DTFALLT_SHIFT);
/* Setup the DTFC register. */
timer->DTFC =
(init->enableFaultSourceCoreLockup ? TIMER_DTFC_DTLOCKUPFEN : 0)
| (init->enableFaultSourceDebugger ? TIMER_DTFC_DTDBGFEN : 0)
| (init->enableFaultSourcePrsSel0 ? TIMER_DTFC_DTPRS0FEN : 0)
| (init->enableFaultSourcePrsSel1 ? TIMER_DTFC_DTPRS1FEN : 0)
| ((uint32_t)(init->faultAction) << _TIMER_DTFC_DTFA_SHIFT)
| ((uint32_t)(init->faultSourcePrsSel0) << _TIMER_DTFC_DTPRS0FSEL_SHIFT)
| ((uint32_t)(init->faultSourcePrsSel1) << _TIMER_DTFC_DTPRS1FSEL_SHIFT);
/* Setup the DTOGEN register. */
timer->DTOGEN = init->outputsEnableMask;
/* Clear any previous DTI faults. */
TIMER_ClearDTIFault(timer, TIMER_GetDTIFault(timer));
/* Enable/disable before returning. */
TIMER_EnableDTI(timer, init->enable);
}
#endif
/***************************************************************************//**
* @brief
* Reset TIMER to same state as after a HW reset.
*
* @note
* The ROUTE register is NOT reset by this function, in order to allow for
* centralized setup of this feature.
*
* @param[in] timer
* Pointer to TIMER peripheral register block.
******************************************************************************/
void TIMER_Reset(TIMER_TypeDef *timer)
{
int i;
EFM_ASSERT(TIMER_REF_VALID(timer));
/* Make sure disabled first, before resetting other registers */
timer->CMD = TIMER_CMD_STOP;
timer->CTRL = _TIMER_CTRL_RESETVALUE;
timer->IEN = _TIMER_IEN_RESETVALUE;
timer->IFC = _TIMER_IFC_MASK;
timer->TOPB = _TIMER_TOPB_RESETVALUE;
/* Write TOP after TOPB to invalidate TOPB (clear TIMER_STATUS_TOPBV) */
timer->TOP = _TIMER_TOP_RESETVALUE;
timer->CNT = _TIMER_CNT_RESETVALUE;
/* Do not reset route register, setting should be done independently */
/* (Note: ROUTE register may be locked by DTLOCK register.) */
for (i = 0; TIMER_CH_VALID(i); i++) {
timer->CC[i].CTRL = _TIMER_CC_CTRL_RESETVALUE;
timer->CC[i].CCV = _TIMER_CC_CCV_RESETVALUE;
timer->CC[i].CCVB = _TIMER_CC_CCVB_RESETVALUE;
}
/* Reset dead time insertion module, no effect on timers without DTI */
#if defined(TIMER_DTLOCK_LOCKKEY_UNLOCK)
/* Unlock DTI registers first in case locked */
timer->DTLOCK = TIMER_DTLOCK_LOCKKEY_UNLOCK;
timer->DTCTRL = _TIMER_DTCTRL_RESETVALUE;
timer->DTTIME = _TIMER_DTTIME_RESETVALUE;
timer->DTFC = _TIMER_DTFC_RESETVALUE;
timer->DTOGEN = _TIMER_DTOGEN_RESETVALUE;
timer->DTFAULTC = _TIMER_DTFAULTC_MASK;
#endif
}
/** @} (end addtogroup TIMER) */
/** @} (end addtogroup emlib) */
#endif /* defined(TIMER_COUNT) && (TIMER_COUNT > 0) */

File diff suppressed because it is too large Load Diff

View File

@ -1,66 +0,0 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Solo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
/*
* app.h
*
* Created on: Jun 26, 2018
* Author: conor
*/
#ifndef SRC_APP_H_
#define SRC_APP_H_
#include <stdint.h>
#define IS_BOOTLOADER
#define DEBUG_LEVEL 0
//#define PRINTING_USE_VCOM
//#define USING_DEV_BOARD
#define BRIDGE_TO_WALLET
#define JUMP_LOC 0x4000
#ifdef USING_DEV_BOARD
#define PUSH_BUTTON gpioPortF,6
#else
#define PUSH_BUTTON gpioPortD,13
#endif
//#define DISABLE_CTAPHID_PING
#define DISABLE_CTAPHID_WINK
#define DISABLE_CTAPHID_CBOR
void printing_init();
int bootloader_bridge(uint8_t klen, uint8_t * keyh);
int is_authorized_to_boot();
#define LED_INIT_VALUE 0x101000
extern uint8_t REBOOT_FLAG;
#endif /* SRC_APP_H_ */

View File

@ -1,98 +0,0 @@
/**************************************************************************//**
* @file boot.c
* @brief Functions for booting another application
* @author Silicon Labs
* @version 1.03
******************************************************************************
* @section License
* <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
*******************************************************************************
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
* obligation to support this Software. Silicon Labs is providing the
* Software "AS IS", with no express or implied warranties of any kind,
* including, but not limited to, any implied warranties of merchantability
* or fitness for any particular purpose or warranties against infringement
* of any proprietary rights of a third party.
*
* Silicon Labs will not be liable for any consequential, incidental, or
* special damages, or any other relief, or for any claim by any third party,
* arising from your use of this Software.
*
******************************************************************************/
#include "em_device.h"
#include "em_gpio.h"
#include "em_cmu.h"
#include "app.h"
/******************************************************************************
* This function sets up the Cortex-M3 with a new SP and PC.
*****************************************************************************/
#if defined ( __CC_ARM )
__asm void BOOT_jump(uint32_t sp, uint32_t pc)
{
/* Set new MSP, PSP based on SP (r0)*/
msr msp, r0
msr psp, r0
/* Jump to PC (r1)*/
bx r1
}
#else
void __attribute__((optimize("O0"))) BOOT_jump(uint32_t sp, uint32_t pc)
{
(void) sp;
(void) pc;
/* Set new MSP, PSP based on SP (r0)*/
__asm("msr msp, r0");
__asm("msr psp, r0");
/* Jump to PC (r1)*/
__asm("mov pc, r1");
}
#endif
/* Resets any peripherals that have been in use by
* the bootloader before booting the appliation */
static void resetPeripherals(void)
{
}
/******************************************************************************
* Boots the firmware. This function will activate the vector table
* of the firmware application and set the PC and SP from this table.
*****************************************************************************/
void __attribute__((optimize("O0"))) BOOT_boot(void)
{
uint32_t pc, sp;
uint32_t *bootAddress = (uint32_t *)(JUMP_LOC);
resetPeripherals();
/* Set new vector table */
SCB->VTOR = (uint32_t)bootAddress;
/* Read new SP and PC from vector table */
sp = bootAddress[0];
pc = bootAddress[1];
/* Do a jump by loading the PC and SP into the CPU registers */
BOOT_jump(sp, pc);
}

View File

@ -1,367 +0,0 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Solo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
/*
* Wrapper for crypto implementation on device
*
* */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "util.h"
#include "crypto.h"
#ifdef USE_SOFTWARE_IMPLEMENTATION
#include "sha256.h"
#include "uECC.h"
#include "aes.h"
#include "ctap.h"
#include "device.h"
#include "app.h"
#include "log.h"
#if defined(USING_PC) || defined(IS_BOOTLOADER)
typedef enum
{
MBEDTLS_ECP_DP_NONE = 0,
MBEDTLS_ECP_DP_SECP192R1, /*!< 192-bits NIST curve */
MBEDTLS_ECP_DP_SECP224R1, /*!< 224-bits NIST curve */
MBEDTLS_ECP_DP_SECP256R1, /*!< 256-bits NIST curve */
MBEDTLS_ECP_DP_SECP384R1, /*!< 384-bits NIST curve */
MBEDTLS_ECP_DP_SECP521R1, /*!< 521-bits NIST curve */
MBEDTLS_ECP_DP_BP256R1, /*!< 256-bits Brainpool curve */
MBEDTLS_ECP_DP_BP384R1, /*!< 384-bits Brainpool curve */
MBEDTLS_ECP_DP_BP512R1, /*!< 512-bits Brainpool curve */
MBEDTLS_ECP_DP_CURVE25519, /*!< Curve25519 */
MBEDTLS_ECP_DP_SECP192K1, /*!< 192-bits "Koblitz" curve */
MBEDTLS_ECP_DP_SECP224K1, /*!< 224-bits "Koblitz" curve */
MBEDTLS_ECP_DP_SECP256K1, /*!< 256-bits "Koblitz" curve */
} mbedtls_ecp_group_id;
#endif
const uint8_t attestation_cert_der[];
const uint16_t attestation_cert_der_size;
const uint8_t attestation_key[];
const uint16_t attestation_key_size;
static SHA256_CTX sha256_ctx;
static const struct uECC_Curve_t * _es256_curve = NULL;
static const uint8_t * _signing_key = NULL;
static int _key_len = 0;
// Secrets for testing only
static uint8_t master_secret[32] = "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff"
"\xff\xee\xdd\xcc\xbb\xaa\x99\x88\x77\x66\x55\x44\x33\x22\x11\x00";
static uint8_t transport_secret[32] = "\x10\x01\x22\x33\x44\x55\x66\x77\x87\x90\x0a\xbb\x3c\xd8\xee\xff"
"\xff\xee\x8d\x1c\x3b\xfa\x99\x88\x77\x86\x55\x44\xd3\xff\x33\x00";
void crypto_sha256_init()
{
sha256_init(&sha256_ctx);
}
void crypto_reset_master_secret()
{
ctap_generate_rng(master_secret, 32);
}
void crypto_sha256_update(uint8_t * data, size_t len)
{
sha256_update(&sha256_ctx, data, len);
}
void crypto_sha256_update_secret()
{
sha256_update(&sha256_ctx, master_secret, 32);
}
void crypto_sha256_final(uint8_t * hash)
{
sha256_final(&sha256_ctx, hash);
}
void crypto_sha256_hmac_init(uint8_t * key, uint32_t klen, uint8_t * hmac)
{
uint8_t buf[64];
int i;
memset(buf, 0, sizeof(buf));
if (key == CRYPTO_MASTER_KEY)
{
key = master_secret;
klen = sizeof(master_secret);
}
if(klen > 64)
{
printf2(TAG_ERR,"Error, key size must be <= 64\n");
exit(1);
}
memmove(buf, key, klen);
for (i = 0; i < sizeof(buf); i++)
{
buf[i] = buf[i] ^ 0x36;
}
crypto_sha256_init();
crypto_sha256_update(buf, 64);
}
void crypto_sha256_hmac_final(uint8_t * key, uint32_t klen, uint8_t * hmac)
{
uint8_t buf[64];
int i;
crypto_sha256_final(hmac);
memset(buf, 0, sizeof(buf));
if (key == CRYPTO_MASTER_KEY)
{
key = master_secret;
klen = sizeof(master_secret);
}
if(klen > 64)
{
printf2(TAG_ERR,"Error, key size must be <= 64\n");
exit(1);
}
memmove(buf, key, klen);
for (i = 0; i < sizeof(buf); i++)
{
buf[i] = buf[i] ^ 0x5c;
}
crypto_sha256_init();
crypto_sha256_update(buf, 64);
crypto_sha256_update(hmac, 32);
crypto_sha256_final(hmac);
}
void crypto_ecc256_init()
{
uECC_set_rng((uECC_RNG_Function)ctap_generate_rng);
_es256_curve = uECC_secp256r1();
}
void crypto_ecc256_load_attestation_key()
{
_signing_key = attestation_key;
_key_len = 32;
}
void crypto_ecc256_sign(uint8_t * data, int len, uint8_t * sig)
{
if ( uECC_sign(_signing_key, data, len, sig, _es256_curve) == 0)
{
printf2(TAG_ERR,"error, uECC failed\n");
exit(1);
}
}
void crypto_ecc256_load_key(uint8_t * data, int len, uint8_t * data2, int len2)
{
static uint8_t privkey[32];
generate_private_key(data,len,data2,len2,privkey);
_signing_key = privkey;
_key_len = 32;
}
void crypto_ecdsa_sign(uint8_t * data, int len, uint8_t * sig, int MBEDTLS_ECP_ID)
{
const struct uECC_Curve_t * curve = NULL;
switch(MBEDTLS_ECP_ID)
{
case MBEDTLS_ECP_DP_SECP256R1:
curve = uECC_secp256r1();
if (_key_len != 32) goto fail;
break;
default:
printf2(TAG_ERR,"error, invalid ECDSA alg specifier\n");
exit(1);
}
if ( uECC_sign(_signing_key, data, len, sig, curve) == 0)
{
printf2(TAG_ERR,"error, uECC failed\n");
exit(1);
}
return;
fail:
printf2(TAG_ERR,"error, invalid key length\n");
exit(1);
}
void generate_private_key(uint8_t * data, int len, uint8_t * data2, int len2, uint8_t * privkey)
{
crypto_sha256_hmac_init(CRYPTO_MASTER_KEY, 0, privkey);
crypto_sha256_update(data, len);
crypto_sha256_update(data2, len2);
crypto_sha256_update(master_secret, 32);
crypto_sha256_hmac_final(CRYPTO_MASTER_KEY, 0, privkey);
}
/*int uECC_compute_public_key(const uint8_t *private_key, uint8_t *public_key, uECC_Curve curve);*/
void crypto_ecc256_derive_public_key(uint8_t * data, int len, uint8_t * x, uint8_t * y)
{
uint8_t privkey[32];
uint8_t pubkey[64];
generate_private_key(data,len,NULL,0,privkey);
memset(pubkey,0,sizeof(pubkey));
uECC_compute_public_key(privkey, pubkey, _es256_curve);
memmove(x,pubkey,32);
memmove(y,pubkey+32,32);
}
void crypto_load_external_key(uint8_t * key, int len)
{
_signing_key = key;
_key_len = len;
}
void crypto_ecc256_make_key_pair(uint8_t * pubkey, uint8_t * privkey)
{
if (uECC_make_key(pubkey, privkey, _es256_curve) != 1)
{
printf2(TAG_ERR,"Error, uECC_make_key failed\n");
exit(1);
}
}
void crypto_ecc256_shared_secret(const uint8_t * pubkey, const uint8_t * privkey, uint8_t * shared_secret)
{
if (uECC_shared_secret(pubkey, privkey, shared_secret, _es256_curve) != 1)
{
printf2(TAG_ERR,"Error, uECC_shared_secret failed\n");
exit(1);
}
}
struct AES_ctx aes_ctx;
void crypto_aes256_init(uint8_t * key, uint8_t * nonce)
{
if (key == CRYPTO_TRANSPORT_KEY)
{
AES_init_ctx(&aes_ctx, transport_secret);
}
else
{
AES_init_ctx(&aes_ctx, key);
}
if (nonce == NULL)
{
memset(aes_ctx.Iv, 0, 16);
}
else
{
memmove(aes_ctx.Iv, nonce, 16);
}
}
// prevent round key recomputation
void crypto_aes256_reset_iv(uint8_t * nonce)
{
if (nonce == NULL)
{
memset(aes_ctx.Iv, 0, 16);
}
else
{
memmove(aes_ctx.Iv, nonce, 16);
}
}
void crypto_aes256_decrypt(uint8_t * buf, int length)
{
AES_CBC_decrypt_buffer(&aes_ctx, buf, length);
}
void crypto_aes256_encrypt(uint8_t * buf, int length)
{
AES_CBC_encrypt_buffer(&aes_ctx, buf, length);
}
const uint8_t attestation_cert_der[] =
"\x30\x82\x01\xfb\x30\x82\x01\xa1\xa0\x03\x02\x01\x02\x02\x01\x00\x30\x0a\x06\x08"
"\x2a\x86\x48\xce\x3d\x04\x03\x02\x30\x2c\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13"
"\x02\x55\x53\x31\x0b\x30\x09\x06\x03\x55\x04\x08\x0c\x02\x4d\x44\x31\x10\x30\x0e"
"\x06\x03\x55\x04\x0a\x0c\x07\x54\x45\x53\x54\x20\x43\x41\x30\x20\x17\x0d\x31\x38"
"\x30\x35\x31\x30\x30\x33\x30\x36\x32\x30\x5a\x18\x0f\x32\x30\x36\x38\x30\x34\x32"
"\x37\x30\x33\x30\x36\x32\x30\x5a\x30\x7c\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13"
"\x02\x55\x53\x31\x0b\x30\x09\x06\x03\x55\x04\x08\x0c\x02\x4d\x44\x31\x0f\x30\x0d"
"\x06\x03\x55\x04\x07\x0c\x06\x4c\x61\x75\x72\x65\x6c\x31\x15\x30\x13\x06\x03\x55"
"\x04\x0a\x0c\x0c\x54\x45\x53\x54\x20\x43\x4f\x4d\x50\x41\x4e\x59\x31\x22\x30\x20"
"\x06\x03\x55\x04\x0b\x0c\x19\x41\x75\x74\x68\x65\x6e\x74\x69\x63\x61\x74\x6f\x72"
"\x20\x41\x74\x74\x65\x73\x74\x61\x74\x69\x6f\x6e\x31\x14\x30\x12\x06\x03\x55\x04"
"\x03\x0c\x0b\x63\x6f\x6e\x6f\x72\x70\x70\x2e\x63\x6f\x6d\x30\x59\x30\x13\x06\x07"
"\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00"
"\x04\x45\xa9\x02\xc1\x2e\x9c\x0a\x33\xfa\x3e\x84\x50\x4a\xb8\x02\xdc\x4d\xb9\xaf"
"\x15\xb1\xb6\x3a\xea\x8d\x3f\x03\x03\x55\x65\x7d\x70\x3f\xb4\x02\xa4\x97\xf4\x83"
"\xb8\xa6\xf9\x3c\xd0\x18\xad\x92\x0c\xb7\x8a\x5a\x3e\x14\x48\x92\xef\x08\xf8\xca"
"\xea\xfb\x32\xab\x20\xa3\x62\x30\x60\x30\x46\x06\x03\x55\x1d\x23\x04\x3f\x30\x3d"
"\xa1\x30\xa4\x2e\x30\x2c\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x53\x31"
"\x0b\x30\x09\x06\x03\x55\x04\x08\x0c\x02\x4d\x44\x31\x10\x30\x0e\x06\x03\x55\x04"
"\x0a\x0c\x07\x54\x45\x53\x54\x20\x43\x41\x82\x09\x00\xf7\xc9\xec\x89\xf2\x63\x94"
"\xd9\x30\x09\x06\x03\x55\x1d\x13\x04\x02\x30\x00\x30\x0b\x06\x03\x55\x1d\x0f\x04"
"\x04\x03\x02\x04\xf0\x30\x0a\x06\x08\x2a\x86\x48\xce\x3d\x04\x03\x02\x03\x48\x00"
"\x30\x45\x02\x20\x18\x38\xb0\x45\x03\x69\xaa\xa7\xb7\x38\x62\x01\xaf\x24\x97\x5e"
"\x7e\x74\x64\x1b\xa3\x7b\xf7\xe6\xd3\xaf\x79\x28\xdb\xdc\xa5\x88\x02\x21\x00\xcd"
"\x06\xf1\xe3\xab\x16\x21\x8e\xd8\xc0\x14\xaf\x09\x4f\x5b\x73\xef\x5e\x9e\x4b\xe7"
"\x35\xeb\xdd\x9b\x6d\x8f\x7d\xf3\xc4\x3a\xd7";
const uint16_t attestation_cert_der_size = sizeof(attestation_cert_der)-1;
const uint8_t attestation_key[] = "\xcd\x67\xaa\x31\x0d\x09\x1e\xd1\x6e\x7e\x98\x92\xaa\x07\x0e\x19\x94\xfc\xd7\x14\xae\x7c\x40\x8f\xb9\x46\xb7\x2e\x5f\xe7\x5d\x30";
const uint16_t attestation_key_size = sizeof(attestation_key)-1;
#else
#error "No crypto implementation defined"
#endif

View File

@ -1,138 +0,0 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Solo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
#include "em_device.h"
#include "em_chip.h"
#include "em_timer.h"
#include "device.h"
#include "app.h"
#include "u2f.h"
#include "log.h"
#include "InitDevice.h"
void bootloader_init(void);
uint8_t REBOOT_FLAG;
int main(void)
{
int count = 0;
uint32_t t1 = 0;
uint32_t t2 = 0;
uint32_t accum = 0;
uint32_t dt = 0;
uint8_t hidmsg[64];
/* Chip errata */
CHIP_Init();
EMU_enter_DefaultMode_from_RESET();
CMU_enter_DefaultMode_from_RESET();
// ADC0_enter_DefaultMode_from_RESET();
USART0_enter_DefaultMode_from_RESET();
USART1_enter_DefaultMode_from_RESET();
// LDMA_enter_DefaultMode_from_RESET();
CRYOTIMER_enter_DefaultMode_from_RESET();
PORTIO_enter_DefaultMode_from_RESET();
bootloader_init();
set_logging_mask(
/*0*/
TAG_GEN|
/*TAG_MC |*/
/*TAG_GA |*/
/*TAG_WALLET |*/
TAG_STOR |
/*TAG_CP |*/
// TAG_CTAP|
/*TAG_HID|*/
/*TAG_U2F|*/
/*TAG_PARSE |*/
// TAG_TIME|
/*TAG_DUMP|*/
/*TAG_GREEN|*/
/*TAG_RED|*/
TAG_ERR
);
printf1(TAG_GEN,"Bootloader init\r\n");
if (GPIO_PinInGet(PUSH_BUTTON) == 0)
{
t1 = millis();
while(GPIO_PinInGet(PUSH_BUTTON) == 0 && (millis() - t1) < 2000)
;
if (GPIO_PinInGet(PUSH_BUTTON) == 0) {
bootmode:
printf1(TAG_GEN,"Reflash condition detected\n");
ctaphid_init();
reset_efm8();
TIMER0_enter_DefaultMode_from_RESET();
TIMER_TopSet(TIMER0, 255);
RGB(LED_INIT_VALUE);
/* Infinite loop */
int count = 0;
while (1) {
if (millis() - t1 > 10)
{
/*printf("heartbeat %ld\n", beat++);*/
heartbeat();
t1 = millis();
}
if (usbhid_recv(hidmsg) > 0)
{
/*printf("%d>> ",count++); dump_hex1(TAG_DUMP, hidmsg,sizeof(hidmsg));*/
// t2 = millis();
ctaphid_handle_packet(hidmsg);
// accum += millis() - t2;
// printf("accum: %d\n", (uint32_t)accum);
// printf("dt: %d\n", t2 - dt);
// dt = t2;
// memset(hidmsg, 0, sizeof(hidmsg));
}
else
{
/*main_loop_delay();*/
}
ctaphid_check_timeouts();
if (REBOOT_FLAG) break;
}
// delay(100);
}
}
printf1(TAG_GEN,"Normal boot\n");
if (is_authorized_to_boot() )
{
BOOT_boot();
} else {
printf1(TAG_GEN,"Warning: not authorized to boot\n");
goto bootmode;
}
}

View File

@ -1,195 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
<storageModule moduleId="org.eclipse.cdt.core.settings">
<cconfiguration id="com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt.debug#com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt:9.53.0">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt.debug#com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt:9.53.0" moduleId="org.eclipse.cdt.core.settings" name="Keil 8051 v9.53 - Debug">
<macros>
<stringMacro name="StudioSdkPath" type="VALUE_PATH_DIR" value="${StudioSdkPathFromID:com.silabs.sdk.8051:4.1.1._-963069327}"/>
<stringMacro name="StudioToolchainPath" type="VALUE_PATH_DIR" value="${StudioToolchainPathFromID:com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt:9.53.0}"/>
</macros>
<externalSettings/>
<extensions>
<extension id="com.silabs.ss.framework.debugger.core.HEX" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="com.silabs.ss.tool.ide.c8051.debug.OMF2" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="com.silabs.ss.framework.debugger.core.EBL" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="com.silabs.ss.framework.debugger.core.GBL" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="com.silabs.ss.tool.ide.c8051.debug.OMF" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="com.silabs.ss.framework.debugger.core.BIN" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="com.silabs.ss.framework.debugger.core.S37" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt.KeilErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions>
</storageModule>
<storageModule buildConfig.stockConfigId="com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt.debug#com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt:9.53.0" cppBuildConfig.builtinIncludes="studio:/sdk/Lib/efm8_usb/inc/ studio:/sdk/Lib/efm8_assert/ studio:/sdk/Device/EFM8UB1/peripheral_driver/inc/ studio:/sdk/Device/shared/si8051base/ studio:/sdk/Device/EFM8UB1/inc/ studio:/sdk/Lib/efm8_usbc/lib_kernel/inc/ studio:/sdk/Lib/efm8_usbc/lib_usbc_pd/inc/ studio:/sdk/Lib/efm8_usb/inc/ studio:/sdk/Lib/efm8_assert/ studio:/sdk/Device/EFM8UB1/peripheral_driver/inc/ studio:/sdk/Device/shared/si8051base/ studio:/sdk/Device/EFM8UB1/inc/ studio:/sdk/Lib/efm8_usbc/lib_kernel/inc/ studio:/sdk/Lib/efm8_usbc/lib_usbc_pd/inc/" cppBuildConfig.builtinLibraryFiles="" cppBuildConfig.builtinLibraryNames="" cppBuildConfig.builtinLibraryObjects="" cppBuildConfig.builtinLibraryPaths="" cppBuildConfig.builtinMacros="" moduleId="com.silabs.ss.framework.ide.project.core.cpp" projectCommon.boardIds="brd5000a:0.0.0.A02" projectCommon.partId="mcu.8051.efm8.ub1.efm8ub10f16g-b-qfn28" projectCommon.referencedModules="[{&quot;builtinExcludes&quot;:[],&quot;builtinSources&quot;:[&quot;lib/efm8ub1/peripheralDrivers/src/usb_0.c&quot;,&quot;lib/efm8ub1/peripheralDrivers/inc/usb_0.h&quot;],&quot;builtin&quot;:true,&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/ss/Project.ecore\&quot; builtin=\&quot;true\&quot; id=\&quot;com.silabs.sdk.si8051.external.efm8PeripheralDriver.usb0\&quot;/&gt;&quot;},{&quot;builtinExcludes&quot;:[],&quot;builtinSources&quot;:[&quot;lib/efm8_assert/assert.c&quot;,&quot;lib/efm8_assert/assert.h&quot;],&quot;builtin&quot;:true,&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/ss/Project.ecore\&quot; builtin=\&quot;true\&quot; id=\&quot;com.silabs.sdk.si8051.external.efm8Library.assert\&quot;/&gt;&quot;},{&quot;builtinExcludes&quot;:[],&quot;builtinSources&quot;:[&quot;lib/efm8_usb/inc/efm8_usb.h&quot;,&quot;lib/efm8_usb/src/efm8_usbd.c&quot;,&quot;lib/efm8_usb/src/efm8_usbdch9.c&quot;,&quot;lib/efm8_usb/src/efm8_usbdep.c&quot;,&quot;lib/efm8_usb/src/efm8_usbdint.c&quot;,&quot;lib/efm8_usb/Readme.txt&quot;],&quot;builtin&quot;:true,&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/ss/Project.ecore\&quot; builtin=\&quot;true\&quot; id=\&quot;com.silabs.sdk.si8051.external.efm8Library.usb\&quot;/&gt;&quot;},{&quot;builtinExcludes&quot;:[],&quot;builtinSources&quot;:[&quot;src/SILABS_STARTUP.A51&quot;],&quot;builtin&quot;:true,&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/ss/Project.ecore\&quot; builtin=\&quot;true\&quot; id=\&quot;com.silabs.sdk.si8051.shared\&quot;/&gt;&quot;},{&quot;builtinExcludes&quot;:[],&quot;builtinSources&quot;:[],&quot;builtin&quot;:true,&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/ss/Project.ecore\&quot; builtin=\&quot;true\&quot; id=\&quot;com.silabs.sdk.si8051.external.efm8Library.usbc\&quot;/&gt;&quot;}]" projectCommon.sdkId="com.silabs.sdk.8051:4.1.1._-963069327" projectCommon.toolchainId="com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt:9.53.0"/>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactExtension="omf" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" cleanCommand="rm -rf" description="" id="com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt.debug#com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt:9.53.0" name="Keil 8051 v9.53 - Debug" parent="com.silabs.ide.si8051.keil.exe.default">
<folderInfo id="com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt.debug#com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt:9.53.0." name="/" resourcePath="">
<toolChain id="com.silabs.ide.si8051.keil.toolchain.exe.default.803196567" name="Keil 8051" superClass="com.silabs.ide.si8051.keil.toolchain.exe.default">
<option id="com.silabs.ide.si8051.keil.toolchain.category.general.debug.1285835962" name="Generate debug information" superClass="com.silabs.ide.si8051.keil.toolchain.category.general.debug" value="true" valueType="boolean"/>
<option id="com.silabs.ide.si8051.keil.toolchain.category.general.extended_assembler.1124669083" name="Use Extended Assembler (AX51) instead of A51" superClass="com.silabs.ide.si8051.keil.toolchain.category.general.extended_assembler" value="true" valueType="boolean"/>
<option id="com.silabs.ide.si8051.keil.toolchain.category.general.extended_linker.1220060828" name="Use Extended Linker (LX51) instead of BL51" superClass="com.silabs.ide.si8051.keil.toolchain.category.general.extended_linker" value="true" valueType="boolean"/>
<option id="com.silabs.ide.si8051.keil.toolchain.category.general.memory_model.923432818" name="Memory model" superClass="com.silabs.ide.si8051.keil.toolchain.category.general.memory_model" value="com.silabs.ide.si8051.keil.toolchain.category.general.memory_model.large" valueType="enumerated"/>
<targetPlatform binaryParser="com.silabs.ss.tool.ide.c8051.debug.OMF;com.silabs.ss.tool.ide.c8051.debug.OMF2;com.silabs.ss.framework.debugger.core.BIN;com.silabs.ss.framework.debugger.core.HEX;com.silabs.ss.framework.debugger.core.S37;com.silabs.ss.framework.debugger.core.EBL;com.silabs.ss.framework.debugger.core.GBL" id="com.silabs.ide.si8051.keil.targetplatform.1736873507" isAbstract="false" superClass="com.silabs.ide.si8051.keil.targetplatform"/>
<builder buildPath="${workspace_loc:/efm8}/Keil 8051 v9.53 - Debug" id="com.silabs.ide.si8051.keil.builder.699981897" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Keil Builder" parallelBuildOn="false" superClass="com.silabs.ide.si8051.keil.builder"/>
<tool id="com.silabs.ide.si8051.keil.toolchain.compiler.161237451" name="Keil 8051 Compiler" superClass="com.silabs.ide.si8051.keil.toolchain.compiler">
<option id="com.silabs.ide.si8051.keil.compiler.category.symbols.def.1394396371" name="Defined symbols (DEFINE(...))" superClass="com.silabs.ide.si8051.keil.compiler.category.symbols.def" valueType="definedSymbols">
<listOptionValue builtIn="false" value="DEBUG=1"/>
</option>
<option id="com.silabs.ide.si8051.keil.compiler.category.optimization.level.816863969" name="Level" superClass="com.silabs.ide.si8051.keil.compiler.category.optimization.level" value="com.silabs.ide.si8051.keil.compiler.category.optimization.level.9" valueType="enumerated"/>
<option id="com.silabs.ide.si8051.keil.compiler.category.optimization.emphasis.628030751" name="Emphasis" superClass="com.silabs.ide.si8051.keil.compiler.category.optimization.emphasis" value="com.silabs.ide.si8051.keil.compiler.category.optimization.emphasis.speed" valueType="enumerated"/>
<option id="com.silabs.ide.si8051.keil.compiler.category.includes.paths.1243816580" name="Include paths (INCDIR(...))" superClass="com.silabs.ide.si8051.keil.compiler.category.includes.paths" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/inc}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/inc/config}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Lib/efm8_usb/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Lib/efm8_assert&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Device/EFM8UB1/peripheral_driver/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Device/shared/si8051base&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Device/EFM8UB1/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Lib/efm8_usbc/lib_kernel/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Lib/efm8_usbc/lib_usbc_pd/inc&quot;"/>
</option>
<option id="com.silabs.ide.si8051.keil.compiler.category.misc.extraflags.1584403236" name="Additional Flags" superClass="com.silabs.ide.si8051.keil.compiler.category.misc.extraflags" value="OA" valueType="string"/>
<option id="com.silabs.ide.si8051.keil.compiler.category.general.code.1474638890" name="Code size" superClass="com.silabs.ide.si8051.keil.compiler.category.general.code" value="com.silabs.ide.si8051.keil.compiler.category.general.code.large" valueType="enumerated"/>
<inputType id="com.silabs.ide.si8051.keil.compiler.inputType.1048026013" superClass="com.silabs.ide.si8051.keil.compiler.inputType"/>
</tool>
<tool command="AX51" id="com.silabs.ide.si8051.keil.toolchain.assembler.683449334" name="Keil 8051 Assembler" superClass="com.silabs.ide.si8051.keil.toolchain.assembler">
<option id="com.silabs.ide.si8051.keil.assembler.category.symbols.def.677208820" name="Defined symbols (SET(...))" superClass="com.silabs.ide.si8051.keil.assembler.category.symbols.def"/>
<option id="com.silabs.ide.si8051.keil.assembler.category.includes.paths.1772111840" name="Include paths (INCDIR(...))" superClass="com.silabs.ide.si8051.keil.assembler.category.includes.paths" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/inc}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/inc/config}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Lib/efm8_usb/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Lib/efm8_assert&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Device/EFM8UB1/peripheral_driver/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Device/shared/si8051base&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Device/EFM8UB1/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Lib/efm8_usbc/lib_kernel/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Lib/efm8_usbc/lib_usbc_pd/inc&quot;"/>
</option>
<inputType id="com.silabs.ide.si8051.keil.assembler.inputType.1712887970" superClass="com.silabs.ide.si8051.keil.assembler.inputType"/>
</tool>
<tool command="LX51" id="com.silabs.ide.si8051.keil.toolchain.linker.367126547" name="Keil 8051 Linker" superClass="com.silabs.ide.si8051.keil.toolchain.linker">
<option id="com.silabs.ide.si8051.keil.linker.category.general.use_control_file.117123054" name="Use linker control file" superClass="com.silabs.ide.si8051.keil.linker.category.general.use_control_file" value="false" valueType="boolean"/>
<option id="com.silabs.ide.si8051.keil.linker.category.ordering.selection.1520457668" name="Linker input ordering" superClass="com.silabs.ide.si8051.keil.linker.category.ordering.selection" value="./src/InitDevice.OBJ;./src/SILABS_STARTUP.OBJ;./src/callback.OBJ;./src/descriptors.OBJ;./src/main.OBJ;./src/printing.OBJ;./lib/efm8ub1/peripheralDrivers/src/usb_0.OBJ;./lib/efm8_usb/src/efm8_usbd.OBJ;./lib/efm8_usb/src/efm8_usbdch9.OBJ;./lib/efm8_usb/src/efm8_usbdep.OBJ;./lib/efm8_usb/src/efm8_usbdint.OBJ;./lib/efm8_assert/assert.OBJ" valueType="string"/>
<inputType id="com.silabs.ide.si8051.keil.linker.inputType.320881486" superClass="com.silabs.ide.si8051.keil.linker.inputType"/>
</tool>
<tool id="com.silabs.ide.si8051.keil.toolchain.librarian.1238681544" name="Keil 8051 Library Manager" superClass="com.silabs.ide.si8051.keil.toolchain.librarian"/>
</toolChain>
</folderInfo>
<sourceEntries>
<entry excluding="docs|lib/c8051f320|lib/c8051f326|lib/c8051f340|lib/c8051f380|lib/efm8ub2|lib/efm8ub3|lib/efm8ub4|.git/objects/info|.git/objects/pack|.git/refs/tags|src" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/>
</sourceEntries>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
<cconfiguration id="com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt.release#com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt:9.53.0">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt.release#com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt:9.53.0" moduleId="org.eclipse.cdt.core.settings" name="Keil 8051 v9.53 - Release">
<macros>
<stringMacro name="StudioSdkPath" type="VALUE_PATH_DIR" value="${StudioSdkPathFromID:com.silabs.sdk.8051:4.1.1._-963069327}"/>
<stringMacro name="StudioToolchainPath" type="VALUE_PATH_DIR" value="${StudioToolchainPathFromID:com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt:9.53.0}"/>
</macros>
<externalSettings/>
<extensions>
<extension id="com.silabs.ss.framework.debugger.core.HEX" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="com.silabs.ss.tool.ide.c8051.debug.OMF2" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="com.silabs.ss.framework.debugger.core.EBL" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="com.silabs.ss.framework.debugger.core.GBL" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="com.silabs.ss.tool.ide.c8051.debug.OMF" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="com.silabs.ss.framework.debugger.core.BIN" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="com.silabs.ss.framework.debugger.core.S37" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt.KeilErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions>
</storageModule>
<storageModule buildConfig.stockConfigId="com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt.release#com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt:9.53.0" cppBuildConfig.builtinIncludes="studio:/sdk/Lib/efm8_usb/inc/ studio:/sdk/Lib/efm8_assert/ studio:/sdk/Device/EFM8UB1/peripheral_driver/inc/ studio:/sdk/Device/shared/si8051base/ studio:/sdk/Device/EFM8UB1/inc/ studio:/sdk/Lib/efm8_usbc/lib_kernel/inc/ studio:/sdk/Lib/efm8_usbc/lib_usbc_pd/inc/ studio:/sdk/Lib/efm8_usb/inc/ studio:/sdk/Lib/efm8_assert/ studio:/sdk/Device/EFM8UB1/peripheral_driver/inc/ studio:/sdk/Device/shared/si8051base/ studio:/sdk/Device/EFM8UB1/inc/ studio:/sdk/Lib/efm8_usbc/lib_kernel/inc/ studio:/sdk/Lib/efm8_usbc/lib_usbc_pd/inc/" cppBuildConfig.builtinLibraryFiles="" cppBuildConfig.builtinLibraryNames="" cppBuildConfig.builtinLibraryObjects="" cppBuildConfig.builtinLibraryPaths="" cppBuildConfig.builtinMacros="" moduleId="com.silabs.ss.framework.ide.project.core.cpp" projectCommon.referencedModules="[{&quot;builtinExcludes&quot;:[],&quot;builtinSources&quot;:[],&quot;builtin&quot;:true,&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/ss/Project.ecore\&quot; builtin=\&quot;true\&quot; id=\&quot;com.silabs.sdk.si8051.external.efm8Library.usbc\&quot;/&gt;&quot;},{&quot;builtinExcludes&quot;:[],&quot;builtinSources&quot;:[&quot;lib/efm8ub1/peripheralDrivers/src/usb_0.c&quot;,&quot;lib/efm8ub1/peripheralDrivers/inc/usb_0.h&quot;],&quot;builtin&quot;:true,&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/ss/Project.ecore\&quot; builtin=\&quot;true\&quot; id=\&quot;com.silabs.sdk.si8051.external.efm8PeripheralDriver.usb0\&quot;/&gt;&quot;},{&quot;builtinExcludes&quot;:[],&quot;builtinSources&quot;:[&quot;lib/efm8_usb/inc/efm8_usb.h&quot;,&quot;lib/efm8_usb/src/efm8_usbd.c&quot;,&quot;lib/efm8_usb/src/efm8_usbdch9.c&quot;,&quot;lib/efm8_usb/src/efm8_usbdep.c&quot;,&quot;lib/efm8_usb/src/efm8_usbdint.c&quot;,&quot;lib/efm8_usb/Readme.txt&quot;],&quot;builtin&quot;:true,&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/ss/Project.ecore\&quot; builtin=\&quot;true\&quot; id=\&quot;com.silabs.sdk.si8051.external.efm8Library.usb\&quot;/&gt;&quot;},{&quot;builtinExcludes&quot;:[],&quot;builtinSources&quot;:[&quot;lib/efm8_assert/assert.c&quot;,&quot;lib/efm8_assert/assert.h&quot;],&quot;builtin&quot;:true,&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/ss/Project.ecore\&quot; builtin=\&quot;true\&quot; id=\&quot;com.silabs.sdk.si8051.external.efm8Library.assert\&quot;/&gt;&quot;},{&quot;builtinExcludes&quot;:[],&quot;builtinSources&quot;:[&quot;src/SILABS_STARTUP.A51&quot;],&quot;builtin&quot;:true,&quot;module&quot;:&quot;&lt;project:MModule xmlns:project=\&quot;http://www.silabs.com/ss/Project.ecore\&quot; builtin=\&quot;true\&quot; id=\&quot;com.silabs.sdk.si8051.shared\&quot;/&gt;&quot;}]" projectCommon.toolchainId="com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt:9.53.0"/>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactExtension="omf" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" cleanCommand="rm -rf" description="" id="com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt.release#com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt:9.53.0" name="Keil 8051 v9.53 - Release" parent="com.silabs.ide.si8051.keil.exe.default">
<folderInfo id="com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt.release#com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt:9.53.0." name="/" resourcePath="">
<toolChain id="com.silabs.ide.si8051.keil.toolchain.exe.default.2049529147" name="Keil 8051" superClass="com.silabs.ide.si8051.keil.toolchain.exe.default">
<option id="com.silabs.ide.si8051.keil.toolchain.category.general.debug.498309818" name="Generate debug information" superClass="com.silabs.ide.si8051.keil.toolchain.category.general.debug" value="true" valueType="boolean"/>
<option id="com.silabs.ide.si8051.keil.toolchain.category.general.extended_assembler.1283846940" name="Use Extended Assembler (AX51) instead of A51" superClass="com.silabs.ide.si8051.keil.toolchain.category.general.extended_assembler" value="true" valueType="boolean"/>
<option id="com.silabs.ide.si8051.keil.toolchain.category.general.extended_linker.146017776" name="Use Extended Linker (LX51) instead of BL51" superClass="com.silabs.ide.si8051.keil.toolchain.category.general.extended_linker" value="true" valueType="boolean"/>
<option id="com.silabs.ide.si8051.keil.toolchain.category.general.memory_model.640114993" name="Memory model" superClass="com.silabs.ide.si8051.keil.toolchain.category.general.memory_model" value="com.silabs.ide.si8051.keil.toolchain.category.general.memory_model.small" valueType="enumerated"/>
<targetPlatform binaryParser="com.silabs.ss.tool.ide.c8051.debug.OMF;com.silabs.ss.tool.ide.c8051.debug.OMF2;com.silabs.ss.framework.debugger.core.BIN;com.silabs.ss.framework.debugger.core.HEX;com.silabs.ss.framework.debugger.core.S37;com.silabs.ss.framework.debugger.core.EBL;com.silabs.ss.framework.debugger.core.GBL" id="com.silabs.ide.si8051.keil.targetplatform.690223176" isAbstract="false" superClass="com.silabs.ide.si8051.keil.targetplatform"/>
<builder buildPath="${workspace_loc:/efm8}/Keil 8051 v9.53 - Release" id="com.silabs.ide.si8051.keil.builder.1329230955" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Keil Builder" parallelBuildOn="false" superClass="com.silabs.ide.si8051.keil.builder"/>
<tool id="com.silabs.ide.si8051.keil.toolchain.compiler.1966285955" name="Keil 8051 Compiler" superClass="com.silabs.ide.si8051.keil.toolchain.compiler">
<option id="com.silabs.ide.si8051.keil.compiler.category.optimization.level.851586321" name="Level" superClass="com.silabs.ide.si8051.keil.compiler.category.optimization.level" value="com.silabs.ide.si8051.keil.compiler.category.optimization.level.9" valueType="enumerated"/>
<option id="com.silabs.ide.si8051.keil.compiler.category.symbols.def.497293805" name="Defined symbols (DEFINE(...))" superClass="com.silabs.ide.si8051.keil.compiler.category.symbols.def" valueType="definedSymbols">
<listOptionValue builtIn="false" value="NDEBUG=1"/>
</option>
<option id="com.silabs.ide.si8051.keil.compiler.category.optimization.coloring.2036986310" name="Global register coloring" superClass="com.silabs.ide.si8051.keil.compiler.category.optimization.coloring" value="true" valueType="boolean"/>
<option id="com.silabs.ide.si8051.keil.compiler.category.optimization.emphasis.777114717" name="Emphasis" superClass="com.silabs.ide.si8051.keil.compiler.category.optimization.emphasis" value="com.silabs.ide.si8051.keil.compiler.category.optimization.emphasis.speed" valueType="enumerated"/>
<option id="com.silabs.ide.si8051.keil.compiler.category.includes.paths.882106026" name="Include paths (INCDIR(...))" superClass="com.silabs.ide.si8051.keil.compiler.category.includes.paths" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/inc}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/inc/config}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Lib/efm8_usb/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Lib/efm8_assert&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Device/EFM8UB1/peripheral_driver/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Device/shared/si8051base&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Device/EFM8UB1/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Lib/efm8_usbc/lib_kernel/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Lib/efm8_usbc/lib_usbc_pd/inc&quot;"/>
</option>
<option id="com.silabs.ide.si8051.keil.compiler.category.misc.extraflags.1520964257" name="Additional Flags" superClass="com.silabs.ide.si8051.keil.compiler.category.misc.extraflags" value="OA" valueType="string"/>
<option id="com.silabs.ide.si8051.keil.compiler.category.general.code.1101784529" name="Code size" superClass="com.silabs.ide.si8051.keil.compiler.category.general.code" value="com.silabs.ide.si8051.keil.compiler.category.general.code.large" valueType="enumerated"/>
<inputType id="com.silabs.ide.si8051.keil.compiler.inputType.1366062481" superClass="com.silabs.ide.si8051.keil.compiler.inputType"/>
</tool>
<tool command="AX51" id="com.silabs.ide.si8051.keil.toolchain.assembler.862226894" name="Keil 8051 Assembler" superClass="com.silabs.ide.si8051.keil.toolchain.assembler">
<option id="com.silabs.ide.si8051.keil.assembler.category.symbols.def.1379136974" name="Defined symbols (SET(...))" superClass="com.silabs.ide.si8051.keil.assembler.category.symbols.def" valueType="stringList">
<listOptionValue builtIn="false" value="SILABS_STARTUP=1"/>
</option>
<option id="com.silabs.ide.si8051.keil.assembler.category.includes.paths.2327129" name="Include paths (INCDIR(...))" superClass="com.silabs.ide.si8051.keil.assembler.category.includes.paths" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/inc}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/inc/config}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Lib/efm8_usb/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Lib/efm8_assert&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Device/EFM8UB1/peripheral_driver/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Device/shared/si8051base&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Device/EFM8UB1/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Lib/efm8_usbc/lib_kernel/inc&quot;"/>
<listOptionValue builtIn="false" value="&quot;${StudioSdkPath}/Lib/efm8_usbc/lib_usbc_pd/inc&quot;"/>
</option>
<inputType id="com.silabs.ide.si8051.keil.assembler.inputType.1906467347" superClass="com.silabs.ide.si8051.keil.assembler.inputType"/>
</tool>
<tool command="LX51" id="com.silabs.ide.si8051.keil.toolchain.linker.1259644704" name="Keil 8051 Linker" superClass="com.silabs.ide.si8051.keil.toolchain.linker">
<option id="com.silabs.ide.si8051.keil.linker.category.general.use_control_file.1886409616" name="Use linker control file" superClass="com.silabs.ide.si8051.keil.linker.category.general.use_control_file" value="true" valueType="boolean"/>
<inputType id="com.silabs.ide.si8051.keil.linker.inputType.1526176751" superClass="com.silabs.ide.si8051.keil.linker.inputType"/>
</tool>
<tool id="com.silabs.ide.si8051.keil.toolchain.librarian.1609353969" name="Keil 8051 Library Manager" superClass="com.silabs.ide.si8051.keil.toolchain.librarian"/>
</toolChain>
</folderInfo>
<sourceEntries>
<entry excluding="docs|lib/c8051f320|lib/c8051f326|lib/c8051f340|lib/c8051f380|lib/efm8ub2|lib/efm8ub3|lib/efm8ub4|.git/objects/info|.git/objects/pack|.git/refs/tags|src" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/>
</sourceEntries>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
</storageModule>
<storageModule moduleId="com.silabs.ss.framework.ide.project.core.cpp" project.generation="5" projectCommon.boardIds="brd5000a:0.0.0.A02" projectCommon.buildArtifactType="EXE" projectCommon.importModeId="COPY" projectCommon.partId="mcu.8051.efm8.ub1.efm8ub10f16g-b-qfn28" projectCommon.sdkId="com.silabs.sdk.8051:4.1.1._-963069327"/>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="efm8.com.silabs.ss.framework.ide.project.core.cdt.cdtMbsProjectType.972220390" name="SLS CDT Project" projectType="com.silabs.ss.framework.ide.project.core.cdt.cdtMbsProjectType"/>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
<scannerConfigBuildInfo instanceId="com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt.debug#com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt:9.53.0;com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt.debug#com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt:9.53.0.">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.silabs.ide.si8051.keil.KeilScannerInfoCollector"/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt.release#com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt:9.53.0;com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt.release#com.silabs.ss.tool.ide.c8051.toolchain.keil.cdt:9.53.0.">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="com.silabs.ide.si8051.keil.KeilScannerInfoCollector"/>
</scannerConfigBuildInfo>
</storageModule>
<storageModule moduleId="refreshScope" versionNumber="2">
<configuration configurationName="Keil 8051 v9.53 - Debug">
<resource resourceType="PROJECT" workspacePath="/efm8"/>
</configuration>
<configuration configurationName="Keil 8051 v9.53 - Release">
<resource resourceType="PROJECT" workspacePath="/efm8"/>
</configuration>
</storageModule>
</cproject>

View File

@ -1,27 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>efm8</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<triggers>clean,full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>com.silabs.ss.framework.ide.project.sls.core.SLSProjectNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
</natures>
</projectDescription>

View File

@ -1,2 +0,0 @@
copiedFilesOriginState={}
eclipse.preferences.version=1

View File

@ -1,71 +0,0 @@
eclipse.preferences.version=1
org.eclipse.cdt.codan.checkers.errnoreturn=Warning
org.eclipse.cdt.codan.checkers.errnoreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},implicit\=>false}
org.eclipse.cdt.codan.checkers.errreturnvalue=Error
org.eclipse.cdt.codan.checkers.errreturnvalue.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.checkers.nocommentinside=-Error
org.eclipse.cdt.codan.checkers.nocommentinside.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.checkers.nolinecomment=-Error
org.eclipse.cdt.codan.checkers.nolinecomment.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.checkers.noreturn=Error
org.eclipse.cdt.codan.checkers.noreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},implicit\=>false}
org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation=Error
org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem=Error
org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem=Warning
org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem=Warning
org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},no_break_comment\=>"no break",last_case_param\=>false,empty_case_param\=>false}
org.eclipse.cdt.codan.internal.checkers.CatchByReference=Warning
org.eclipse.cdt.codan.internal.checkers.CatchByReference.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},unknown\=>false,exceptions\=>()}
org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem=Error
org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization=Warning
org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},skip\=>true}
org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem=Error
org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem=Error
org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.InvalidArguments=Error
org.eclipse.cdt.codan.internal.checkers.InvalidArguments.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem=Error
org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem=Error
org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem=Error
org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem=Error
org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker=-Info
org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},pattern\=>"^[a-z]",macro\=>true,exceptions\=>()}
org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem=Warning
org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.OverloadProblem=Error
org.eclipse.cdt.codan.internal.checkers.OverloadProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem=Error
org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem=Error
org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem=-Warning
org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem=-Warning
org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem=Warning
org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true,exceptions\=>()}
org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem=Warning
org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},paramNot\=>false}
org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem=Warning
org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},else\=>false,afterelse\=>false}
org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem=Error
org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem=Warning
org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true}
org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem=Warning
org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true}
org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem=Warning
org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true,exceptions\=>("@(\#)","$Id")}
org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem=Error
org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
useParentScope=false

View File

@ -1,2 +0,0 @@
eclipse.preferences.version=1
org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false

View File

@ -1,117 +0,0 @@
<?xml version="1.0" encoding="ASCII"?>
<device:XMLDevice xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:device="http://www.silabs.com/ss/hwconfig/document/device.ecore" name="EFM8UB10F16G-B-QFN28" partId="mcu.8051.efm8.ub1.efm8ub10f16g-b-qfn28" version="4.0.1" contextId="%DEFAULT%">
<mode name="DefaultMode">
<property object="CIP51_0" propertyId="ABPeripheral.included" value="true"/>
<property object="CIP51_0" propertyId="cip51.prefetchenginecontrol.enableprefetch" value="Enabled"/>
<property object="CIP51_0" propertyId="cip51.prefetchenginecontrol.flashreadtiming" value="SYSCLK is below 50 MHz"/>
<property object="CLOCK_0" propertyId="ABPeripheral.included" value="true"/>
<property object="CLOCK_0" propertyId="clock.clockselect.clocksourcedivider" value="SYSCLK / 1"/>
<property object="CLOCK_0" propertyId="clock.clockselect.selectclocksource" value="Internal High Frequency Oscillator 1"/>
<property object="CROSSBAR0" propertyId="xbar0.spi0.clockdata" value="Enabled"/>
<property object="CROSSBAR0" propertyId="xbar0.uart0.data" value="Enabled"/>
<property object="DefaultMode" propertyId="mode.diagramLocation" value="100, 100"/>
<property object="INTERRUPT_0" propertyId="ABPeripheral.included" value="true"/>
<property object="INTERRUPT_0" propertyId="interrupt.interruptenable.enableallinterrupts" value="Enabled"/>
<property object="LFOSC_0" propertyId="ABPeripheral.included" value="true"/>
<property object="LFOSC_0" propertyId="lfosc.lowfrequencyoscillatorcontrol.enableinternallfoscillator" value="Enabled"/>
<property object="LFOSC_0" propertyId="lfosc.lowfrequencyoscillatorcontrol.selectinternallfoscillatordivider" value="Divide by 8"/>
<property object="P0.0" propertyId="ports.settings.skip" value="Skipped"/>
<property object="P0.1" propertyId="ports.settings.skip" value="Skipped"/>
<property object="P0.2" propertyId="ports.settings.skip" value="Skipped"/>
<property object="P0.3" propertyId="ports.settings.skip" value="Skipped"/>
<property object="P0.4" propertyId="ports.settings.iomode" value="Digital Push-Pull Output"/>
<property object="P0.4" propertyId="ports.settings.outputmode" value="Push-pull"/>
<property object="P0.7" propertyId="ports.settings.iomode" value="Digital Push-Pull Output"/>
<property object="P0.7" propertyId="ports.settings.outputmode" value="Push-pull"/>
<property object="P1.1" propertyId="ports.settings.iomode" value="Digital Push-Pull Output"/>
<property object="P1.1" propertyId="ports.settings.outputmode" value="Push-pull"/>
<property object="P1.2" propertyId="ports.settings.latch" value="Low"/>
<property object="P1.4" propertyId="ports.settings.iomode" value="Digital Push-Pull Output"/>
<property object="P1.4" propertyId="ports.settings.outputmode" value="Push-pull"/>
<property object="P1.5" propertyId="ports.settings.iomode" value="Digital Push-Pull Output"/>
<property object="P1.5" propertyId="ports.settings.outputmode" value="Push-pull"/>
<property object="P1.6" propertyId="ports.settings.iomode" value="Digital Push-Pull Output"/>
<property object="P1.6" propertyId="ports.settings.outputmode" value="Push-pull"/>
<property object="PBCFG_0" propertyId="pbcfg.settings.enablecrossbar" value="Enabled"/>
<property object="PMU_0" propertyId="ABPeripheral.included" value="true"/>
<property object="SPI_0" propertyId="ABPeripheral.included" value="true"/>
<property object="SPI_0" propertyId="spi.clockrate.spiclockfrequencyactual" value="2.000 MHz"/>
<property object="SPI_0" propertyId="spi.clockrate.spiclockfrequencytarget" value="2000000"/>
<property object="SPI_0" propertyId="spi.clockrate.sysclk" value="48.000 MHz"/>
<property object="SPI_0" propertyId="spi.clockrate.sysclkdividercoefficientspi0ckr" value="11"/>
<property object="SPI_0" propertyId="spi.control.slaveselectmode" value="Slave or master 3-wire mode"/>
<property object="SPI_0" propertyId="spi.control.spienable" value="Enabled"/>
<property object="TIMER01_0" propertyId="ABPeripheral.included" value="true"/>
<property object="TIMER01_0" propertyId="timer01.timer1highbyte.timer1highbyte" value="48"/>
<property object="TIMER01_0" propertyId="timer01.timer1mode2:8bitcountertimerwithautoreload.targetoverflowfrequency" value="230400"/>
<property object="TIMER01_0" propertyId="timer01.timer1mode2:8bitcountertimerwithautoreload.timerreloadvalue" value="48"/>
<property object="TIMER16_2" propertyId="ABPeripheral.included" value="true"/>
<property object="TIMER16_2" propertyId="timer16.initandreloadvalue.targetoverflowfrequency" value="100"/>
<property object="TIMER16_2" propertyId="timer16.initandreloadvalue.timerreloadvalue" value="25536"/>
<property object="TIMER16_2" propertyId="timer16.reloadhighbyte.reloadhighbyte" value="99"/>
<property object="TIMER16_2" propertyId="timer16.reloadlowbyte.reloadlowbyte" value="192"/>
<property object="TIMER16_3" propertyId="ABPeripheral.included" value="true"/>
<property object="TIMER16_3" propertyId="timer16.control.clocksource" value="LFOSC/8"/>
<property object="TIMER16_3" propertyId="timer16.control.runcontrol" value="Start"/>
<property object="TIMER16_3" propertyId="timer16.control.selectexternalclock" value="LFOSC / 8"/>
<property object="TIMER16_3" propertyId="timer16.control.timerrunningstate" value="Timer is Running"/>
<property object="TIMER16_4" propertyId="ABPeripheral.included" value="true"/>
<property object="TIMER_SETUP_0" propertyId="ABPeripheral.included" value="true"/>
<property object="TIMER_SETUP_0" propertyId="timer_setup.clockcontrol0.timer01prescale" value="SYSCLK / 4"/>
<property object="TIMER_SETUP_0" propertyId="timer_setup.timer01control.timer1runcontrol" value="Start"/>
<property object="TIMER_SETUP_0" propertyId="timer_setup.timer1.clocksource" value="Use SYSCLK"/>
<property object="TIMER_SETUP_0" propertyId="timer_setup.timer1.mode" value="Mode 2, 8-bit Counter/Timer with Auto-Reload"/>
<property object="TIMER_SETUP_0" propertyId="timer_setup.timer1.timerrunningstate" value="Timer is Running"/>
<property object="TIMER_SETUP_0" propertyId="timer_setup.timer1.timerswitch1:runcontrol" value="Start"/>
<property object="UARTE_1" propertyId="uarte.baudrategeneratorcontrol.actualbaudrate" value="115384"/>
<property object="UARTE_1" propertyId="uarte.baudrategeneratorcontrol.baudrateprescaler" value="Divide by 8"/>
<property object="UARTE_1" propertyId="uarte.baudrategeneratorcontrol.baudratereloadhigh" value="255"/>
<property object="UARTE_1" propertyId="uarte.baudrategeneratorcontrol.baudratereloadlow" value="230"/>
<property object="UARTE_1" propertyId="uarte.baudrategeneratorcontrol.enablebaudrategenerator" value="Enabled"/>
<property object="UARTE_1" propertyId="uarte.baudrategeneratorcontrol.expectedbaudrate" value="115200"/>
<property object="UARTE_1" propertyId="uarte.serialportcontrol.enablereceive" value="Enabled"/>
<property object="UART_0" propertyId="ABPeripheral.included" value="true"/>
<property object="UART_0" propertyId="uart.serialportcontrol.actualbaudrate" value="115384 Baud"/>
<property object="UART_0" propertyId="uart.serialportcontrol.enablereceive" value="Enabled"/>
<property object="UART_0" propertyId="uart.serialportcontrol.timer1overflowfrequency" value="230.769 kHz"/>
<property object="USBLIB_0" propertyId="ABPeripheral.included" value="true"/>
<property object="USBLIB_0" propertyId="configuration.configurationparameters.configurationstring" value=""/>
<property object="USBLIB_0" propertyId="configuration.configurationparameters.devicepower" value="Bus-Powered"/>
<property object="USBLIB_0" propertyId="device.deviceproperties.bmaxpacketsize" value="64"/>
<property object="USBLIB_0" propertyId="device.deviceproperties.productidpid" value="35535"/>
<property object="USBLIB_0" propertyId="device.deviceproperties.productstring" value="EOS Bridge"/>
<property object="USBLIB_0" propertyId="endpoints.endpoint1in.bulkmaxpacketsizebytes" value="64"/>
<property object="USBLIB_0" propertyId="endpoints.endpoint1in.maxpacketsizebytes" value="64"/>
<property object="USBLIB_0" propertyId="endpoints.endpoint1in.pollingintervalms" value="5"/>
<property object="USBLIB_0" propertyId="endpoints.endpoint1in.transfertype" value="Interrupt"/>
<property object="USBLIB_0" propertyId="endpoints.endpoint1out.maxpacketsizebytes" value="64"/>
<property object="USBLIB_0" propertyId="endpoints.endpoint1out.pollingintervalms" value="5"/>
<property object="USBLIB_0" propertyId="endpoints.endpoint1out.transfertype" value="Interrupt"/>
<property object="USBLIB_0" propertyId="endpoints.endpoint2in.bulkmaxpacketsizebytes" value="64"/>
<property object="USBLIB_0" propertyId="endpoints.endpoint2in.maxpacketsizebytes" value="64"/>
<property object="USBLIB_0" propertyId="endpoints.endpoint2in.pollingintervalms" value="5"/>
<property object="USBLIB_0" propertyId="endpoints.endpoint2in.transfertype" value="Interrupt"/>
<property object="USBLIB_0" propertyId="endpoints.endpoint2out.bulkmaxpacketsizebytes" value="64"/>
<property object="USBLIB_0" propertyId="endpoints.endpoint2out.endpoint2out" value="Enabled"/>
<property object="USBLIB_0" propertyId="endpoints.endpoint2out.maxpacketsizebytes" value="64"/>
<property object="USBLIB_0" propertyId="endpoints.endpoint2out.pollingintervalms" value="5"/>
<property object="USBLIB_0" propertyId="endpoints.endpoint2out.transfertype" value="Interrupt"/>
<property object="USBLIB_0" propertyId="endpoints.endpoint3in.endpoint3in" value="Enabled"/>
<property object="USBLIB_0" propertyId="endpoints.endpoint3in.maxpacketsizebytes" value="64"/>
<property object="USBLIB_0" propertyId="endpoints.endpoint3in.pollingintervalms" value="5"/>
<property object="USBLIB_0" propertyId="endpoints.endpoint3in.transfertype" value="Interrupt"/>
<property object="USBLIB_0" propertyId="interfaces.interface0.interfaceclass" value="HID (Human Interface Device)"/>
<property object="USBLIB_0" propertyId="library.callbackfunctions.resetcallback" value="Enabled"/>
<property object="USBLIB_0" propertyId="library.callbackfunctions.selfpoweredcallback" value="Enabled"/>
<property object="USBLIB_0" propertyId="library.callbackfunctions.setupcommandcallback" value="Enabled"/>
<property object="USBLIB_0" propertyId="library.callbackfunctions.statechangecallback" value="Enabled"/>
<property object="USBLIB_0" propertyId="library.libraryconfiguration.clockrecovery" value="Enabled"/>
<property object="VREG_0" propertyId="ABPeripheral.included" value="true"/>
<property object="WDT_0" propertyId="ABPeripheral.included" value="true"/>
<property object="WDT_0" propertyId="wdt.watchdogcontrol.wdtenable" value="Disable"/>
</mode>
<modeTransition>
<property object="RESET &#x2192; DefaultMode" propertyId="modeTransition.source" value="RESET"/>
<property object="RESET &#x2192; DefaultMode" propertyId="modeTransition.target" value="DefaultMode"/>
</modeTransition>
</device:XMLDevice>

View File

@ -1,37 +0,0 @@
//=========================================================
// inc/InitDevice.h: generated by Hardware Configurator
//
// This file will be regenerated when saving a document.
// leave the sections inside the "$[...]" comment tags alone
// or they will be overwritten!
//=========================================================
#ifndef __INIT_DEVICE_H__
#define __INIT_DEVICE_H__
// USER CONSTANTS
// USER PROTOTYPES
// $[Mode Transition Prototypes]
extern void enter_DefaultMode_from_RESET(void);
// [Mode Transition Prototypes]$
// $[Config(Per-Module Mode)Transition Prototypes]
extern void WDT_0_enter_DefaultMode_from_RESET(void);
extern void PORTS_0_enter_DefaultMode_from_RESET(void);
extern void PORTS_1_enter_DefaultMode_from_RESET(void);
extern void PBCFG_0_enter_DefaultMode_from_RESET(void);
extern void LFOSC_0_enter_DefaultMode_from_RESET(void);
extern void CIP51_0_enter_DefaultMode_from_RESET(void);
extern void CLOCK_0_enter_DefaultMode_from_RESET(void);
extern void TIMER01_0_enter_DefaultMode_from_RESET(void);
extern void TIMER16_2_enter_DefaultMode_from_RESET(void);
extern void TIMER16_3_enter_DefaultMode_from_RESET(void);
extern void TIMER_SETUP_0_enter_DefaultMode_from_RESET(void);
extern void SPI_0_enter_DefaultMode_from_RESET(void);
extern void UART_0_enter_DefaultMode_from_RESET(void);
extern void INTERRUPT_0_enter_DefaultMode_from_RESET(void);
extern void USBLIB_0_enter_DefaultMode_from_RESET(void);
// [Config(Per-Module Mode)Transition Prototypes]$
#endif

View File

@ -1,54 +0,0 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Solo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
/*
* app.h
*
* Created on: Jun 25, 2018
* Author: conor
*/
#ifndef INC_APP_H_
#define INC_APP_H_
#define USE_PRINTING
void usb_transfer_complete();
void spi_transfer_complete();
#define INPUT_ENDPOINT EP2OUT
#define OUTPUT_ENDPOINT EP3IN
#define INPUT_ENDPOINT_NUM 0x83
#define OUTPUT_ENDPOINT_NUM 0x02
//#define INPUT_ENDPOINT EP1OUT
//#define OUTPUT_ENDPOINT EP1IN
//
//#define INPUT_ENDPOINT_NUM 0x81
//#define OUTPUT_ENDPOINT_NUM 0x01
void delay(int ms);
#endif /* INC_APP_H_ */

View File

@ -1,157 +0,0 @@
/*******************************************************************************
* @file usbconfig.h
* @brief USB protocol stack library, application supplied configuration options.
*******************************************************************************/
//=============================================================================
// inc/config/usbconfig.h: generated by Hardware Configurator
//
// This file will be regenerated when saving a document. leave the sections
// inside the "$[...]" comment tags alone or they will be overwritten!
//=============================================================================
#ifndef __SILICON_LABS_USBCONFIG_H
#define __SILICON_LABS_USBCONFIG_H
// -----------------------------------------------------------------------------
// Specify bus- or self-powered
// -----------------------------------------------------------------------------
// $[Device Power]
#define SLAB_USB_BUS_POWERED 1
// [Device Power]$
// -----------------------------------------------------------------------------
// Specify USB speed
// -----------------------------------------------------------------------------
// $[USB Speed]
#define SLAB_USB_FULL_SPEED 1
// [USB Speed]$
// -----------------------------------------------------------------------------
// Enable or disable the clock recovery
// -----------------------------------------------------------------------------
// $[Clock Recovery]
#define SLAB_USB_CLOCK_RECOVERY_ENABLED 1
// [Clock Recovery]$
// -----------------------------------------------------------------------------
// Enable or disable remote wakeup
// -----------------------------------------------------------------------------
// $[Remote Wake-up]
#define SLAB_USB_REMOTE_WAKEUP_ENABLED 0
// [Remote Wake-up]$
// -----------------------------------------------------------------------------
// Specify number of interfaces and whether any interfaces support alternate
// settings
// -----------------------------------------------------------------------------
// $[Number of Interfaces]
#define SLAB_USB_NUM_INTERFACES 1
#define SLAB_USB_SUPPORT_ALT_INTERFACES 0
// [Number of Interfaces]$
// -----------------------------------------------------------------------------
// Enable or disable each endpoint
// -----------------------------------------------------------------------------
// $[Endpoints Used]
#define SLAB_USB_EP1IN_USED 0
#define SLAB_USB_EP1OUT_USED 0
#define SLAB_USB_EP2IN_USED 0
#define SLAB_USB_EP2OUT_USED 1
#define SLAB_USB_EP3IN_USED 1
#define SLAB_USB_EP3OUT_USED 0
// [Endpoints Used]$
// -----------------------------------------------------------------------------
// Specify maximum packet size for each endpoint
// -----------------------------------------------------------------------------
// $[Endpoint Max Packet Size]
#define SLAB_USB_EP1IN_MAX_PACKET_SIZE 64
#define SLAB_USB_EP1OUT_MAX_PACKET_SIZE 64
#define SLAB_USB_EP2IN_MAX_PACKET_SIZE 64
#define SLAB_USB_EP2OUT_MAX_PACKET_SIZE 64
#define SLAB_USB_EP3IN_MAX_PACKET_SIZE 64
#define SLAB_USB_EP3OUT_MAX_PACKET_SIZE 1
// [Endpoint Max Packet Size]$
// -----------------------------------------------------------------------------
// Specify transfer type of each endpoint
// -----------------------------------------------------------------------------
// $[Endpoint Transfer Type]
#define SLAB_USB_EP1IN_TRANSFER_TYPE USB_EPTYPE_INTR
#define SLAB_USB_EP1OUT_TRANSFER_TYPE USB_EPTYPE_INTR
#define SLAB_USB_EP2IN_TRANSFER_TYPE USB_EPTYPE_INTR
#define SLAB_USB_EP2OUT_TRANSFER_TYPE USB_EPTYPE_INTR
#define SLAB_USB_EP3IN_TRANSFER_TYPE USB_EPTYPE_INTR
#define SLAB_USB_EP3OUT_TRANSFER_TYPE USB_EPTYPE_ISOC
// [Endpoint Transfer Type]$
// -----------------------------------------------------------------------------
// Enable or disable callback functions
// -----------------------------------------------------------------------------
// $[Callback Functions]
#define SLAB_USB_HANDLER_CB 0
#define SLAB_USB_IS_SELF_POWERED_CB 1
#define SLAB_USB_RESET_CB 1
#define SLAB_USB_SETUP_CMD_CB 1
#define SLAB_USB_SOF_CB 0
#define SLAB_USB_STATE_CHANGE_CB 1
// [Callback Functions]$
// -----------------------------------------------------------------------------
// Specify number of languages supported by string descriptors.
// -----------------------------------------------------------------------------
// $[Number of Languages]
#define SLAB_USB_NUM_LANGUAGES 1
// [Number of Languages]$
// -----------------------------------------------------------------------------
// If only one descriptor language is supported, specify that language here.
// If multiple descriptor languages are supported, this value is ignored and
// the supported languages must listed in the
// myUsbStringTableLanguageIDsDescriptor structure.
// -----------------------------------------------------------------------------
// $[USB Language]
#define SLAB_USB_LANGUAGE USB_LANGID_ENUS
// [USB Language]$
// -----------------------------------------------------------------------------
//
// Set the power saving mode
//
// SLAB_USB_PWRSAVE_MODE configures when the device will automatically enter
// the USB power-save mode. It is a bitmask constant with bit values:
// USB_PWRSAVE_MODE_OFF - No energy saving mode selected
// USB_PWRSAVE_MODE_ONSUSPEND - Enter USB power-save mode on USB suspend
// USB_PWRSAVE_MODE_ONVBUSOFF - Enter USB power-save mode when not attached
// to the USB host.
// USB_PWRSAVE_MODE_FASTWAKE - Exit USB power-save mode more quickly, but
// consume more power while in USB power-save
// mode.
// While the device is in USB power-save mode
// (typically during USB suspend), the
// internal voltage regulator stays in normal
// power mode instead of entering suspend
// power mode.
// This is an advanced feature that may be
// useful in certain applications that support
// remote wakeup.
//
// -----------------------------------------------------------------------------
// $[Power Save Mode]
#define SLAB_USB_PWRSAVE_MODE USB_PWRSAVE_MODE_OFF
// [Power Save Mode]$
// -----------------------------------------------------------------------------
// Enable or disable polled mode
//
// When enabled, the application must call USBD_Run() periodically to process
// USB events.
// When disabled, USB events will be handled automatically by an interrupt
// handler.
// -----------------------------------------------------------------------------
// $[Polled Mode]
#define SLAB_USB_POLLED_MODE 0
// [Polled Mode]$
#endif // __SILICON_LABS_USBCONFIG_H

View File

@ -1,65 +0,0 @@
/*******************************************************************************
* @file descriptors.h
* @brief USB descriptors header file.
*******************************************************************************/
//=============================================================================
// inc/descriptors.h: generated by Hardware Configurator
//
// This file will be regenerated when saving a document. leave the sections
// inside the "$[...]" comment tags alone or they will be overwritten!
//=============================================================================
#ifndef __SILICON_LABS_DESCRIPTORS_H
#define __SILICON_LABS_DESCRIPTORS_H
//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include <si_toolchain.h>
#include <endian.h>
#include <stdlib.h>
#include <string.h>
#include <efm8_usb.h>
#ifdef __cplusplus
extern "C" {
#endif
// -------------------- USB Identification ------------------------------------
//
// **********
// NOTE: YOU MUST PROVIDE YOUR OWN USB VID/PID (below)
// **********
//
// Following are the definition of the USB VID and PID. These are, by default,
// values that are assigned to Silicon Labs. These values are provided merely
// as an example. You may not use the Silicon Labs VID/PID values in your
// product. You must provide your own assigned VID and PID values.
//-----------------------------------------------------------------------------
// $[Vendor ID]
#define USB_VENDOR_ID htole16(0x10c4)
// [Vendor ID]$
// $[Product ID]
#define USB_PRODUCT_ID htole16(0x8acf)
// [Product ID]$
extern SI_SEGMENT_VARIABLE(ReportDescriptor0[34], const uint8_t, SI_SEG_CODE);
extern SI_SEGMENT_VARIABLE(deviceDesc[], const USB_DeviceDescriptor_TypeDef, SI_SEG_CODE);
extern SI_SEGMENT_VARIABLE(configDesc[], const uint8_t, SI_SEG_CODE);
extern SI_SEGMENT_VARIABLE(initstruct, const USBD_Init_TypeDef, SI_SEG_CODE);
#define HID_PACKET_SIZE 64
#ifdef __cplusplus
}
#endif
#endif // __SILICON_LABS_DESCRIPTORS_H
#if 0
// $[HID Report Descriptors]
extern SI_SEGMENT_VARIABLE(ReportDescriptor0[0], const uint8_t, SI_SEG_CODE);
// [HID Report Descriptors]$
#endif

View File

@ -1,40 +0,0 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Solo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
#ifndef EEPROM_H_
#define EEPROM_H_
#include "app.h"
void eeprom_init();
void eeprom_read(uint16_t addr, uint8_t * buf, uint8_t len);
void _eeprom_write(uint16_t addr, uint8_t * buf, uint8_t len, uint8_t flags);
extern char __erase_mem[3];
#define eeprom_write(a,b,l) _eeprom_write(a,b,l,0x1)
#define eeprom_erase(a) _eeprom_write(a,__erase_mem,1,0x3)
#define EEPROM_DATA_START 0xF800
#endif /* EEPROM_H_ */

View File

@ -1,82 +0,0 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Solo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
#ifndef PRINTING_H_
#define PRINTING_H_
#include <SI_EFM8UB1_Register_Enums.h>
#include <efm8_usb.h>
#include <stdint.h>
#include "app.h"
#define watchdog() (WDTCN = 0xA5)
#define reboot() (RSTSRC = 1 << 4)
#define millis() ((uint16_t)(TMR3L | (TMR3H << 8)))
void u2f_delay(uint32_t ms);
void usb_write();
#ifdef USE_PRINTING
void dump_hex(uint8_t* hex, uint8_t len);
void cputd(uint32_t i);
void cputx(uint32_t i);
#define cputb(x) cputx((uint8_t) (x))
#define cputl(x) cputd((uint32_t) (x))
#define cputlx(x) cputx((uint32_t) (x))
void cprints(const char * str);
void cprintb(const char * tag, uint8_t c, ...);
void cprintd(const char * tag, uint8_t c, ...);
void cprintx(const char * tag, uint8_t c, ...);
void cprintl(const char * tag, uint8_t c, ...);
void cprintlx(const char * tag, uint8_t c, ...);
#else
#define cprintx(x)
#define cprintb(x)
#define cprintlx(x)
#define cprintl(x)
#define cprintd(x)
#define cprints(x)
#define cputx(x)
#define cputb(x)
#define cputl(x)
#define cputlx(x)
#define putf(x)
#define dump_hex(x)
#endif
#endif /* BSP_H_ */

View File

@ -1,15 +0,0 @@
/**************************************************************************//**
* Copyright (c) 2015 by Silicon Laboratories Inc. All rights reserved.
*
* http://developer.silabs.com/legal/version/v11/Silicon_Labs_Software_License_Agreement.txt
*****************************************************************************/
#ifndef NDEBUG
void slab_Assert( const char * file, int line )
{
file = file;
line = line;
while ( 1 );
}
#endif

View File

@ -1,60 +0,0 @@
/******************************************************************************
* Copyright (c) 2014 by Silicon Laboratories Inc. All rights reserved.
*
* http://developer.silabs.com/legal/version/v11/Silicon_Labs_Software_License_Agreement.txt
*****************************************************************************/
#ifndef __ASSERT_H__
#include "efm8_config.h"
/**************************************************************************//**
* @addtogroup efm8_assert
* @{
*
* @brief Runtime assert for EFM8
*
* This module contains a runtime assert macro. It can be compiled out by setting
* the NDEBUG flag.
*
*****************************************************************************/
/**************************************************************************//**
* @def NDEBUG
* @brief Controls if the asserts are present.
*
* Asserts are removed if this symbol is defined
*
*****************************************************************************/
/**************************************************************************//**
* @def USER_ASSERT
* @brief User implemented assert function.
*
* When asserts are enabled the default handler can be be replaced with a user defined
* function of the form 'void userAssertName( const char * file, int line )' by setting
* the value of USER_ASSERT to the userAssertName.
*
*****************************************************************************/
/**************************************************************************//**
* @def SLAB_ASSERT(expr)
* @brief default implementation of assert_failed.
*
* This function can be replaced by a user defined assert function by setting the USER_ASSERT flag
*****************************************************************************/
#ifdef NDEBUG
#define SLAB_ASSERT(expr)
#else
#ifdef USER_ASSERT
#define SLAB_ASSERT(expr) ((expr) ? ((void)0) : USER_ASSERT( __FILE__, __LINE__ ))
#else
void slab_Assert( const char * file, int line );
//Yes this is smaller than if(!expr){assert}
#define SLAB_ASSERT(expr) if(expr){}else{slab_Assert( __FILE__, __LINE__ );}
#endif
#endif
#endif //!__ASSERT_H__

View File

@ -1,56 +0,0 @@
-------------------------------------------------------------------------------
Readme.txt
-------------------------------------------------------------------------------
Copyright 2014 Silicon Laboratories, Inc.
http://developer.silabs.com/legal/version/v11/Silicon_Labs_Software_License_Agreement.txt
Program Description:
-------------------
This is the generic EFM8 USB Firmware Library. Please see the EFM8 Libraries
Documentation for more information (/doc/EFM8/software/Lib/index.html).
Known Issues and Limitations:
----------------------------
1) The library does not reset its Data Toggle after receiving a SET_INTERFACE
request.
Target and Tool Chain Information:
---------------------------------
Target: EFM8UB1, EFM8UB2, C8051F320/1, C8051F326/7, C8051F34x, C8051F38x
Tool chain: Keil
File List:
---------
/inc/efm8_usb.h
/src/efm8_usbd.c
/src/efm8_usbdch9.c
/src/efm8_usbdep.c
/src/efm8_usbdint.c
Release Information:
-------------------
Version 1.0.0
- Initial release.
Version 1.0.1
- Fixed bug in logic of remote wakeup feature where the device would
attempt to wake the host before enabling its USB transceiver.
- Fixed bug where the device would stall the Data Phase instead of the
Setup Phase when sending a procedural stall on Endpoint 0.
- Fixed bug where a bus-powered device would look at VBUS after a USB Reset
to determine if it should enter the Default or Attached State. VBUS is
always present on a bus-powered device, so it should automatically enter
the Default State.
- Removed code that generated a compiler warning when
USB_PWRSAVE_MODE_FASTWAKE was enabled.
- Improved documentation of USB_PWRSAVE_MODE_FASTWAKE feature.
-------------------------------------------------------------------------------
End Of File
-------------------------------------------------------------------------------

File diff suppressed because it is too large Load Diff

View File

@ -1,755 +0,0 @@
/**************************************************************************//**
* Copyright (c) 2015 by Silicon Laboratories Inc. All rights reserved.
*
* http://developer.silabs.com/legal/version/v11/Silicon_Labs_Software_License_Agreement.txt
*****************************************************************************/
#include "si_toolchain.h"
#include "efm8_usb.h"
//#include "assert.h"
#include <stdint.h>
#define SLAB_ASSERT(x)
// -----------------------------------------------------------------------------
// Global Variables
/// Tracks the state of the USB device and endpoints and contains pointers
/// to all descriptors.
SI_SEGMENT_VARIABLE(myUsbDevice, USBD_Device_TypeDef, MEM_MODEL_SEG);
// -----------------------------------------------------------------------------
// Macros
/// Returns the requested endpoint object of type USBD_Ep_TypeDef
/// This macro does not check that epAddr is valid, so the calling function
/// should verify epAddr before using the macro.
#define GetEp(epAddr) (&myUsbDevice.ep0 + epAddr)
#if SLAB_USB_POLLED_MODE
#define DISABLE_USB_INTS {}
#define ENABLE_USB_INTS {}
#else
/// Saves the current state of the USB Interrupt Enable to a variable called
/// usbIntsEnabled, then disables USB interrupts.
#define DISABLE_USB_INTS { usbIntsEnabled = USB_GetIntsEnabled(); USB_DisableInts(); }
/// Sets the USB Interrupt Enable bit to the value of usbIntsEnabled.
/// @ref DISABLE_USB_INTS must be used before this macro is used.
#define ENABLE_USB_INTS { if (usbIntsEnabled) {USB_EnableInts(); } }
#endif // SLAB_USB_POLLED_MODE
// Function in efm8_usbdint.c to force load the module for libraries
extern void forceModuleLoad_usbint(void);
// -----------------------------------------------------------------------------
// USB API Functions
void USBD_AbortAllTransfers(void)
{
uint8_t i;
bool usbIntsEnabled;
USB_SaveSfrPage();
DISABLE_USB_INTS;
// Call USBD_AbortTransfer() for each endpoint
for (i = 1; i < SLAB_USB_NUM_EPS_USED; i++)
{
USBD_AbortTransfer(i);
}
ENABLE_USB_INTS;
USB_RestoreSfrPage();
}
int8_t USBD_AbortTransfer(uint8_t epAddr)
{
USBD_Ep_TypeDef MEM_MODEL_SEG *ep;
uint8_t retVal = USB_STATUS_OK;
bool usbIntsEnabled;
USB_SaveSfrPage();
// Verify this is a valid endpoint address and is not Endpoint 0.
if ((epAddr == EP0) || (epAddr >= SLAB_USB_NUM_EPS_USED))
{
SLAB_ASSERT(false);
retVal = USB_STATUS_ILLEGAL;
}
else
{
DISABLE_USB_INTS;
ep = GetEp(epAddr);
// If the state of the endpoint is already idle, there is not need to abort
// a transfer
if (ep->state != D_EP_IDLE)
{
switch (epAddr)
{
#if SLAB_USB_EP1IN_USED
case EP1IN:
USB_AbortInEp(1);
break;
#endif
#if SLAB_USB_EP2IN_USED
case EP2IN:
USB_AbortInEp(2);
break;
#endif
#if SLAB_USB_EP3IN_USED
case EP3IN:
USB_AbortInEp(3);
break;
#endif
#if SLAB_USB_EP1OUT_USED
case EP1OUT:
USB_AbortOutEp(1);
break;
#endif
#if SLAB_USB_EP2OUT_USED
case EP2OUT:
USB_AbortOutEp(2);
break;
#endif
#if SLAB_USB_EP3OUT_USED
case EP3OUT:
USB_AbortOutEp(3);
break;
#endif
}
// Set the endpoint state to idle and clear out endpoint state variables
ep->state = D_EP_IDLE;
ep->misc.c = 0;
}
}
ENABLE_USB_INTS;
USB_RestoreSfrPage();
return retVal;
}
void USBD_Connect(void)
{
USB_SaveSfrPage();
myUsbDevice.ep0.state = D_EP_IDLE;
USB_EnablePullUpResistor();
USB_EnableTransceiver();
USB_RestoreSfrPage();
}
void USBD_Disconnect(void)
{
USB_SaveSfrPage();
USB_DisablePullUpResistor();
USB_RestoreSfrPage();
}
bool USBD_EpIsBusy(uint8_t epAddr)
{
USBD_Ep_TypeDef MEM_MODEL_SEG *ep;
// Verify this is a valid endpoint address
if (epAddr >= SLAB_USB_NUM_EPS_USED)
{
SLAB_ASSERT(false);
return true;
}
ep = GetEp(epAddr);
if (ep->state == D_EP_IDLE)
{
return false;
}
return true;
}
USBD_State_TypeDef USBD_GetUsbState(void)
{
return myUsbDevice.state;
}
int8_t USBD_Init(const USBD_Init_TypeDef *p)
{
uint8_t i;
USB_SaveSfrPage();
USB_DisableInts();
// This forces the liner to bring in the contents efm8_usbdint
// It is place here since all users MUST call this function
// for the library to work properly
forceModuleLoad_usbint();
// Zero out the myUsbDevice struct, then initialize all non-zero members
for (i = 0; i < sizeof(myUsbDevice); i++)
{
*((uint8_t MEM_MODEL_SEG *)&myUsbDevice + i) = 0;
}
// Get the USB descriptors from p
myUsbDevice.deviceDescriptor = p->deviceDescriptor;
myUsbDevice.configDescriptor = (USB_ConfigurationDescriptor_TypeDef *)p->configDescriptor;
myUsbDevice.stringDescriptors = p->stringDescriptors;
myUsbDevice.numberOfStrings = p->numberOfStrings;
// Enable USB clock
#if SLAB_USB_FULL_SPEED
USB_SetClockIntOsc();
USB_SelectFullSpeed();
#else
USB_SetClockIntOscDiv8();
USB_SelectLowSpeed();
#endif // SLAB_USB_FULL_SPEED
// Enable or disable VBUS detection
#if SLAB_USB_BUS_POWERED
USB_VbusDetectDisable();
#else
USB_VbusDetectEnable();
#endif
USB_ForceReset();
USB_EnableDeviceInts();
USBD_Connect();
// If VBUS is present, the state should be Default.
// Otherwise, it is Attached.
#if SLAB_USB_BUS_POWERED
myUsbDevice.state = USBD_STATE_DEFAULT;
#else
if (USB_IsVbusOn())
{
myUsbDevice.state = USBD_STATE_DEFAULT;
}
else
{
myUsbDevice.state = USBD_STATE_ATTACHED;
}
#endif
// Only enable USB interrupts when not in polled mode
#if (SLAB_USB_POLLED_MODE == 0)
USB_EnableInts();
#endif
USB_RestoreSfrPage();
USB_DisableInhibit();
return USB_STATUS_OK;
}
int8_t USBD_Read(uint8_t epAddr,
uint8_t *dat,
uint16_t byteCount,
bool callback)
{
bool usbIntsEnabled;
USBD_Ep_TypeDef MEM_MODEL_SEG *ep;
USB_SaveSfrPage();
// Verify the endpoint address is valid.
switch (epAddr)
{
case EP0:
#if SLAB_USB_EP1OUT_USED
case EP1OUT:
#endif
#if SLAB_USB_EP2OUT_USED
case EP2OUT:
#endif
#if SLAB_USB_EP3OUT_USED
case EP3OUT:
#endif
break;
#if SLAB_USB_EP1IN_USED
case EP1IN:
#endif
#if SLAB_USB_EP2IN_USED
case EP2IN:
#endif
#if SLAB_USB_EP3IN_USED
case EP3IN:
#endif
default:
SLAB_ASSERT(false);
return USB_STATUS_ILLEGAL;
}
// If the device has not been configured, we cannot start a transfer.
if ((epAddr != EP0) && (myUsbDevice.state != USBD_STATE_CONFIGURED))
{
return USB_STATUS_DEVICE_UNCONFIGURED;
}
ep = GetEp(epAddr);
// If the endpoint is not idle, we cannot start a new transfer.
// Return the appropriate error code.
if (ep->state != D_EP_IDLE)
{
if (ep->state == D_EP_STALL)
{
return USB_STATUS_EP_STALLED;
}
else
{
return USB_STATUS_EP_BUSY;
}
}
DISABLE_USB_INTS;
ep->buf = dat;
ep->remaining = byteCount;
ep->state = D_EP_RECEIVING;
ep->misc.bits.callback = callback;
ep->misc.bits.waitForRead = false;
// If isochronous, set the buffer index to 0
#if ((SLAB_USB_EP3OUT_USED) && (SLAB_USB_EP3OUT_TRANSFER_TYPE == USB_EPTYPE_ISOC))
if (epAddr == EP3OUT)
{
myUsbDevice.ep3outIsoIdx = 0;
}
#endif
ENABLE_USB_INTS;
USB_RestoreSfrPage();
return USB_STATUS_OK;
}
#if SLAB_USB_REMOTE_WAKEUP_ENABLED
int8_t USBD_RemoteWakeup(void)
{
// The device must be suspended and Remote Wakeup must have been previously
// configured with a SET_FEATURE (Remote Wakeup) command.
if ((myUsbDevice.state != USBD_STATE_SUSPENDED) ||
(myUsbDevice.remoteWakeupEnabled == false))
{
return USB_STATUS_ILLEGAL;
}
USB_ForceResume();
USBD_RemoteWakeupDelay(); // Application will provide the delay between
// starting and stopping the resume signal.
USB_ClearResume();
return USB_STATUS_OK;
}
#endif // SLAB_USB_REMOTE_WAKEUP_ENABLED
#if SLAB_USB_POLLED_MODE
void USBD_Run(void)
{
usbIrqHandler();
}
#endif // SLAB_USB_POLLED_MODE
int8_t USBD_StallEp(uint8_t epAddr)
{
bool usbIntsEnabled;
USB_SaveSfrPage();
// Verify the endpoint address is valid and not Endpoint 0.
if ((epAddr == EP0) || (epAddr >= SLAB_USB_NUM_EPS_USED))
{
SLAB_ASSERT(false);
return USB_STATUS_ILLEGAL;
}
DISABLE_USB_INTS;
// Halt the appropriate endpoint by sending a stall and setting the endpoint
// state to Halted (D_EP_HALT).
switch (epAddr)
{
#if SLAB_USB_EP1IN_USED
case (EP1IN):
myUsbDevice.ep1in.state = D_EP_HALT;
USB_SetIndex(1);
USB_EpnInStall();
break;
#endif
#if SLAB_USB_EP2IN_USED
case (EP2IN):
myUsbDevice.ep2in.state = D_EP_HALT;
USB_SetIndex(2);
USB_EpnInStall();
break;
#endif
#if SLAB_USB_EP3IN_USED
case (EP3IN):
myUsbDevice.ep3in.state = D_EP_HALT;
USB_SetIndex(3);
USB_EpnInStall();
break;
#endif
#if SLAB_USB_EP1OUT_USED
case (EP1OUT):
myUsbDevice.ep1out.state = D_EP_HALT;
USB_SetIndex(1);
USB_EpnOutStall();
break;
#endif
#if SLAB_USB_EP2OUT_USED
case (EP2OUT):
myUsbDevice.ep2out.state = D_EP_HALT;
USB_SetIndex(2);
USB_EpnOutStall();
break;
#endif
#if SLAB_USB_EP3OUT_USED
case (EP3OUT):
myUsbDevice.ep3out.state = D_EP_HALT;
USB_SetIndex(3);
USB_EpnOutStall();
break;
#endif
}
ENABLE_USB_INTS;
USB_RestoreSfrPage();
return USB_STATUS_OK;
}
void USBD_Stop(void)
{
USB_DisableInts();
USBD_Disconnect();
USBD_SetUsbState(USBD_STATE_NONE);
}
void USBD_Suspend(void)
{
uint8_t i;
bool regulatorEnabled, prefetchEnabled;
USB_SaveSfrPage();
// If the USB_PWRSAVE_MODE_ONVBUSOFF is enabled, we can enter suspend if VBUS
// is not present even if the USB has not detected a suspend event.
#if ((!(SLAB_USB_PWRSAVE_MODE & USB_PWRSAVE_MODE_ONVBUSOFF)) || \
(SLAB_USB_BUS_POWERED))
if (USB_IsSuspended() == true)
#else
if ((USB_IsSuspended() == true) || (USB_IsVbusOn() == false))
#endif
{
USB_SuspendTransceiver();
#if SLAB_USB_FULL_SPEED
USB_SetSuspendClock();
#endif
// Get the state of the prefetch engine enable bit and disable the prefetch
// engine
prefetchEnabled = USB_IsPrefetchEnabled();
USB_DisablePrefetch();
// Get the state of the internal regulator before suspending it.
if (USB_IsRegulatorEnabled() == true)
{
regulatorEnabled = true;
#if (SLAB_USB_PWRSAVE_MODE & USB_PWRSAVE_MODE_FASTWAKE)
USB_SuspendRegulatorFastWake();
#else
USB_SuspendRegulator();
// Wait at least 12 clock instructions before halting the internal oscillator
for (i = 0; i < 3; i++)
{
}
#endif
}
else
{
regulatorEnabled = false;
}
do
{
USB_SuspendOscillator();
// When we arrive here, the device has waked from suspend mode.
#if SLAB_USB_REMOTE_WAKEUP_ENABLED
// If remote wakeup is enabled, query the application if the remote
// wakeup event occurred. If so, exit USBD_Suspend().
if (USB_IsSuspended() == true)
{
if (USBD_RemoteWakeupCb() == true)
{
break;
}
}
#endif
#if ((!(SLAB_USB_PWRSAVE_MODE & USB_PWRSAVE_MODE_ONVBUSOFF)) && \
(SLAB_USB_BUS_POWERED == 0))
// If the USB_PWRSAVE_MODE_ONVBUSOFF mode is disabled, VBUS has been
// removed, so exit USBD_Suspend().
if (USB_IsVbusOn() == false)
{
break;
}
#endif
} while (USB_IsSuspended() == true);
// Restore the internal regulator
if (regulatorEnabled == true)
{
USB_UnsuspendRegulator();
}
// Restore the prefetch engine
if (prefetchEnabled == true)
{
USB_EnablePrefetch();
}
#if SLAB_USB_FULL_SPEED
// Restore the clock
USB_SetNormalClock();
#endif
USB_EnableTransceiver();
}
USB_RestoreSfrPage();
}
int8_t USBD_UnStallEp(uint8_t epAddr)
{
bool usbIntsEnabled;
USB_SaveSfrPage();
// Verify the endpoint address is valid and not Endpoint 0.
if ((epAddr == EP0) || (epAddr >= SLAB_USB_NUM_EPS_USED))
{
SLAB_ASSERT(false);
return USB_STATUS_ILLEGAL;
}
else
{
DISABLE_USB_INTS;
// End the stall condition and set the endpoint state to idle.
switch (epAddr)
{
#if SLAB_USB_EP1IN_USED
case (EP1IN):
myUsbDevice.ep1in.state = D_EP_IDLE;
USB_SetIndex(1);
USB_EpnInEndStall();
break;
#endif
#if SLAB_USB_EP2IN_USED
case (EP2IN):
myUsbDevice.ep2in.state = D_EP_IDLE;
USB_SetIndex(2);
USB_EpnInEndStall();
break;
#endif
#if SLAB_USB_EP3IN_USED
case (EP3IN):
myUsbDevice.ep3in.state = D_EP_IDLE;
USB_SetIndex(3);
USB_EpnInEndStall();
break;
#endif
#if SLAB_USB_EP1OUT_USED
case (EP1OUT):
myUsbDevice.ep1out.state = D_EP_IDLE;
USB_SetIndex(1);
USB_EpnOutEndStall();
break;
#endif
#if SLAB_USB_EP2OUT_USED
case (EP2OUT):
myUsbDevice.ep2out.state = D_EP_IDLE;
USB_SetIndex(2);
USB_EpnOutEndStall();
break;
#endif
#if SLAB_USB_EP3OUT_USED
case (EP3OUT):
myUsbDevice.ep3out.state = D_EP_IDLE;
USB_SetIndex(3);
USB_EpnOutEndStall();
break;
#endif
}
ENABLE_USB_INTS;
USB_RestoreSfrPage();
}
return USB_STATUS_OK;
}
int8_t USBD_Write(uint8_t epAddr,
uint8_t *dat,
uint16_t byteCount,
bool callback)
{
bool usbIntsEnabled;
USBD_Ep_TypeDef MEM_MODEL_SEG *ep;
USB_SaveSfrPage();
// Verify the endpoint address is valid.
switch (epAddr)
{
case EP0:
#if SLAB_USB_EP1IN_USED
case EP1IN:
#endif
#if SLAB_USB_EP2IN_USED
case EP2IN:
#endif
#if SLAB_USB_EP3IN_USED
case EP3IN:
#endif
break;
#if SLAB_USB_EP1OUT_USED
case EP1OUT:
#endif
#if SLAB_USB_EP2OUT_USED
case EP2OUT:
#endif
#if SLAB_USB_EP3OUT_USED
case EP3OUT:
#endif
default:
SLAB_ASSERT(false);
return USB_STATUS_ILLEGAL;
}
// If the device is not configured and it is not Endpoint 0, we cannot begin
// a transfer.
if ((epAddr != EP0) && (myUsbDevice.state != USBD_STATE_CONFIGURED))
{
return USB_STATUS_DEVICE_UNCONFIGURED;
}
ep = GetEp(epAddr);
// If the endpoint is not idle, we cannot start a new transfer.
// Return the appropriate error code.
if (ep->state != D_EP_IDLE)
{
if (ep->state == D_EP_STALL)
{
return USB_STATUS_EP_STALLED;
}
else
{
return USB_STATUS_EP_BUSY;
}
}
DISABLE_USB_INTS;
ep->buf = dat;
ep->remaining = byteCount;
ep->state = D_EP_TRANSMITTING;
ep->misc.bits.callback = callback;
switch (epAddr)
{
// For Endpoint 0, set the inPacketPending flag to true. The USB handler
// will see this on the next SOF and begin the transfer.
case (EP0):
myUsbDevice.ep0.misc.bits.inPacketPending = true;
break;
// For data endpoints, we will call USB_WriteFIFO here to reduce latency
// between the call to USBD_Write() and the first packet being sent.
#if SLAB_USB_EP1IN_USED
case (EP1IN):
USB_WriteFIFO(1,
(byteCount > SLAB_USB_EP1IN_MAX_PACKET_SIZE) ? SLAB_USB_EP1IN_MAX_PACKET_SIZE : byteCount,
myUsbDevice.ep1in.buf,
true);
break;
#endif // SLAB_USB_EP1IN_USED
#if SLAB_USB_EP2IN_USED
case (EP2IN):
USB_WriteFIFO(2,
(byteCount > SLAB_USB_EP2IN_MAX_PACKET_SIZE) ? SLAB_USB_EP2IN_MAX_PACKET_SIZE : byteCount,
myUsbDevice.ep2in.buf,
true);
break;
#endif // SLAB_USB_EP2IN_USED
#if SLAB_USB_EP3IN_USED
case (EP3IN):
#if ((SLAB_USB_EP3IN_TRANSFER_TYPE == USB_EPTYPE_BULK) || (SLAB_USB_EP3IN_TRANSFER_TYPE == USB_EPTYPE_INTR))
USB_WriteFIFO(3,
(byteCount > SLAB_USB_EP3IN_MAX_PACKET_SIZE) ? SLAB_USB_EP3IN_MAX_PACKET_SIZE : byteCount,
myUsbDevice.ep3in.buf,
true);
#elif (SLAB_USB_EP3IN_TRANSFER_TYPE == USB_EPTYPE_ISOC)
myUsbDevice.ep3in.misc.bits.inPacketPending = true;
myUsbDevice.ep3inIsoIdx = 0;
#endif
break;
#endif // SLAB_USB_EP3IN_USED
}
ENABLE_USB_INTS;
USB_RestoreSfrPage();
return USB_STATUS_OK;
}
// -----------------------------------------------------------------------------
// UtilityFunctions
void USBD_SetUsbState(USBD_State_TypeDef newState)
{
#if (SLAB_USB_SUPPORT_ALT_INTERFACES)
uint8_t i;
#endif
USBD_State_TypeDef currentState;
currentState = myUsbDevice.state;
// If the device is un-configuring, disable the data endpoints and clear out
// alternate interface settings
if ((currentState >= USBD_STATE_SUSPENDED)
&& (newState < USBD_STATE_SUSPENDED))
{
USBD_AbortAllTransfers();
#if (SLAB_USB_SUPPORT_ALT_INTERFACES)
for (i = 0; i < SLAB_USB_NUM_INTERFACES; i++)
{
myUsbDevice.interfaceAltSetting[i] = 0;
}
#endif
}
if (newState == USBD_STATE_SUSPENDED)
{
myUsbDevice.savedState = currentState;
}
myUsbDevice.state = newState;
#if SLAB_USB_STATE_CHANGE_CB
if (currentState != newState)
{
USBD_DeviceStateChangeCb(currentState, newState);
}
#endif
}

View File

@ -1,880 +0,0 @@
/**************************************************************************//**
* Copyright (c) 2015 by Silicon Laboratories Inc. All rights reserved.
*
* http://developer.silabs.com/legal/version/v11/Silicon_Labs_Software_License_Agreement.txt
*****************************************************************************/
#include "si_toolchain.h"
#include "efm8_usb.h"
#include <stdint.h>
#include <endian.h>
// -----------------------------------------------------------------------------
// Function Prototypes
static USB_Status_TypeDef ClearFeature(void);
static USB_Status_TypeDef GetConfiguration(void);
static USB_Status_TypeDef GetDescriptor(void);
static USB_Status_TypeDef GetInterface(void);
static USB_Status_TypeDef GetStatus(void);
static USB_Status_TypeDef SetAddress(void);
static USB_Status_TypeDef SetConfiguration(void);
static USB_Status_TypeDef SetFeature(void);
static USB_Status_TypeDef SetInterface(void);
static void USBD_ActivateAllEps(bool forceIdle);
static void EP0_Write(uint8_t *dat, uint16_t numBytes);
void SendEp0Stall(void);
// -----------------------------------------------------------------------------
// Global Variables
extern SI_SEGMENT_VARIABLE(myUsbDevice, USBD_Device_TypeDef, MEM_MODEL_SEG);
SI_SEGMENT_VARIABLE(txZero[2], uint8_t, SI_SEG_CODE);
// -----------------------------------------------------------------------------
// Static Global Variables
static uint16_t pStatus;
// -----------------------------------------------------------------------------
// Chapter 9 Functions
/***************************************************************************//**
* @brief Processes Standard Request (Chapter 9 Command)
* @return Status of request (type @ref USB_Status_TypeDef)
* @note This function takes no parameters, but it uses the setup command
* stored in @ref myUsbDevice.setup.
******************************************************************************/
USB_Status_TypeDef USBDCH9_SetupCmd(void)
{
USB_Status_TypeDef status = USB_STATUS_OK;
switch (myUsbDevice.setup.bRequest)
{
case GET_STATUS:
status = GetStatus();
break;
case CLEAR_FEATURE:
status = ClearFeature();
break;
case SET_FEATURE:
status = SetFeature();
break;
case SET_ADDRESS:
status = SetAddress();
break;
case GET_DESCRIPTOR:
status = GetDescriptor();
break;
case GET_CONFIGURATION:
status = GetConfiguration();
break;
case SET_CONFIGURATION:
status = SetConfiguration();
break;
case GET_INTERFACE:
status = GetInterface();
break;
case SET_INTERFACE:
status = SetInterface();
break;
default:
status = USB_STATUS_REQ_ERR;
break;
}
// Reset index to 0 in case one of the above commands modified it
USB_SetIndex(0);
// If the command resulted in an error, send a procedural stall
if (status == USB_STATUS_REQ_ERR)
{
SendEp0Stall();
}
return status;
}
/***************************************************************************//**
* @brief Clears the requested feature
* @details Supports CLEAR_FEATURE for Remote Wakeup and Endpoint Halt
* @return Status of request (type @ref USB_Status_TypeDef)
* @note This function takes no parameters, but it uses the setup command
* stored in @ref myUsbDevice.setup.
******************************************************************************/
static USB_Status_TypeDef ClearFeature(void)
{
USB_Status_TypeDef retVal = USB_STATUS_REQ_ERR;
if (myUsbDevice.setup.wLength == 0)
{
switch (myUsbDevice.setup.bmRequestType.Recipient)
{
#if SLAB_USB_REMOTE_WAKEUP_ENABLED
case USB_SETUP_RECIPIENT_DEVICE:
if ((myUsbDevice.setup.wIndex == 0)
&& (myUsbDevice.setup.wValue == USB_FEATURE_DEVICE_REMOTE_WAKEUP)
&& (myUsbDevice.state >= USBD_STATE_ADDRESSED))
{
// Remote wakeup feature clear
myUsbDevice.remoteWakeupEnabled = false;
retVal = USB_STATUS_OK;
}
break;
#endif // SLAB_USB_REMOTE_WAKEUP_ENABLED
case USB_SETUP_RECIPIENT_ENDPOINT:
if (myUsbDevice.setup.wValue == USB_FEATURE_ENDPOINT_HALT)
{
// Device does not support halting endpoint 0, but do not return
// an error as this is a valid request
if (((myUsbDevice.setup.wIndex & ~USB_EP_DIR_IN) == 0)
&& (myUsbDevice.state >= USBD_STATE_ADDRESSED))
{
retVal = USB_STATUS_OK;
}
else if (((myUsbDevice.setup.wIndex & ~USB_SETUP_DIR_D2H) < SLAB_USB_NUM_EPS_USED)
&& (myUsbDevice.state == USBD_STATE_CONFIGURED))
{
retVal = USB_STATUS_OK;
USB_SetIndex((myUsbDevice.setup.wIndex & 0xFF) & ~USB_SETUP_DIR_D2H);
#if (SLAB_USB_EP1IN_USED || SLAB_USB_EP2IN_USED || SLAB_USB_EP3IN_USED)
if ((myUsbDevice.setup.wIndex & 0xFF) & USB_EP_DIR_IN)
{
USB_EpnInEndStallAndClearDataToggle();
}
#endif
#if (SLAB_USB_EP1OUT_USED || SLAB_USB_EP2OUT_USED || SLAB_USB_EP3OUT_USED)
if (((myUsbDevice.setup.wIndex & 0xFF) & USB_EP_DIR_IN) == 0)
{
USB_EpnOutEndStallAndClearDataToggle();
}
#endif
switch (myUsbDevice.setup.wIndex & 0xFF)
{
#if SLAB_USB_EP1OUT_USED
case (USB_EP_DIR_OUT | 1):
if (myUsbDevice.ep1out.state != D_EP_RECEIVING)
{
myUsbDevice.ep1out.state = D_EP_IDLE;
}
break;
#endif
#if SLAB_USB_EP2OUT_USED
case (USB_EP_DIR_OUT | 2):
if (myUsbDevice.ep2out.state != D_EP_RECEIVING)
{
myUsbDevice.ep2out.state = D_EP_IDLE;
}
break;
#endif
#if SLAB_USB_EP3OUT_USED
case (USB_EP_DIR_OUT | 3):
if (myUsbDevice.ep3out.state != D_EP_RECEIVING)
{
myUsbDevice.ep3out.state = D_EP_IDLE;
}
break;
#endif
#if SLAB_USB_EP1IN_USED
case (USB_EP_DIR_IN | 1):
if (myUsbDevice.ep1in.state != D_EP_TRANSMITTING)
{
myUsbDevice.ep1in.state = D_EP_IDLE;
}
break;
#endif
#if SLAB_USB_EP2IN_USED
case (USB_EP_DIR_IN | 2):
if (myUsbDevice.ep2in.state != D_EP_TRANSMITTING)
{
myUsbDevice.ep2in.state = D_EP_IDLE;
}
break;
#endif
#if SLAB_USB_EP3IN_USED
case (USB_EP_DIR_IN | 3):
if (myUsbDevice.ep3in.state != D_EP_TRANSMITTING)
{
myUsbDevice.ep3in.state = D_EP_IDLE;
}
break;
#endif
}
}
}
}
}
return retVal;
}
/***************************************************************************//**
* @brief Gets the current configuration value
* @details Zero means the device is not configured, a non-zero value
* is the configuration value of the configured device.
* @return Status of request (type @ref USB_Status_TypeDef)
* @note This function takes no parameters, but it uses the setup command
* stored in @ref myUsbDevice.setup.
******************************************************************************/
static USB_Status_TypeDef GetConfiguration(void)
{
USB_Status_TypeDef retVal = USB_STATUS_REQ_ERR;
if ((myUsbDevice.setup.wIndex == 0)
&& (myUsbDevice.setup.wValue == 0)
&& (myUsbDevice.setup.wLength == 1)
&& (myUsbDevice.setup.bmRequestType.Direction == USB_SETUP_DIR_IN)
&& (myUsbDevice.setup.bmRequestType.Recipient == USB_SETUP_RECIPIENT_DEVICE))
{
if (myUsbDevice.state == USBD_STATE_ADDRESSED)
{
EP0_Write(txZero, 1);
retVal = USB_STATUS_OK;
}
else if (myUsbDevice.state == USBD_STATE_CONFIGURED)
{
EP0_Write(&myUsbDevice.configurationValue, 1);
retVal = USB_STATUS_OK;
}
}
return retVal;
}
/***************************************************************************//**
* @brief Sends the requested USB Descriptor
* @details Supports single or multiple languages (configured by
* @ref SLAB_USB_NUM_LANGUAGES).
* @return Status of request (type @ref USB_Status_TypeDef)
* @note This function takes no parameters, but it uses the setup command
* stored in @ref myUsbDevice.setup.
******************************************************************************/
static USB_Status_TypeDef GetDescriptor(void)
{
#if (SLAB_USB_NUM_LANGUAGES > 1)
bool langSupported;
uint8_t lang;
#endif
uint8_t index;
uint16_t length = 0;
uint8_t *dat;
USB_Status_TypeDef retVal = USB_STATUS_REQ_ERR;
if (*((uint8_t *)&myUsbDevice.setup.bmRequestType) ==
(USB_SETUP_DIR_D2H | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_DEVICE))
{
index = myUsbDevice.setup.wValue & 0xFF;
switch (myUsbDevice.setup.wValue >> 8)
{
case USB_DEVICE_DESCRIPTOR:
if (index != 0)
{
break;
}
dat = (uint8_t *)myUsbDevice.deviceDescriptor;
length = myUsbDevice.deviceDescriptor->bLength;
break;
case USB_CONFIG_DESCRIPTOR:
if (index != 0)
{
break;
}
dat = (uint8_t *)myUsbDevice.configDescriptor;
length = le16toh(myUsbDevice.configDescriptor->wTotalLength);
break;
case USB_STRING_DESCRIPTOR:
#if (SLAB_USB_NUM_LANGUAGES == 1)
dat = (uint8_t *)myUsbDevice.stringDescriptors[index];
// Index 0 is the language string. If SLAB_USB_NUM_LANGUAGES == 1, we
// know the length will be 4 and the format will be UTF16LE.
if (index == 0)
{
length = 4;
myUsbDevice.ep0String.encoding.type = USB_STRING_DESCRIPTOR_UTF16LE;
}
// Otherwise, verify the language is correct (either the value set as
// SLAB_USB_LANGUAGE in usbconfig.h, or 0).
else if ((myUsbDevice.setup.wIndex == 0) || (myUsbDevice.setup.wIndex == SLAB_USB_LANGUAGE))
{
// Verify the index is valid
if (index < myUsbDevice.numberOfStrings)
{
length = *(dat + USB_STRING_DESCRIPTOR_LENGTH);
myUsbDevice.ep0String.encoding.type = *(dat + USB_STRING_DESCRIPTOR_ENCODING);
dat += USB_STRING_DESCRIPTOR_LENGTH;
myUsbDevice.ep0String.encoding.init = true;
}
}
#elif (SLAB_USB_NUM_LANGUAGES > 1)
langSupported = false;
// Index 0 is the language.
if (index == 0)
{
dat = ((uint8_t *)myUsbDevice.stringDescriptors->languageArray[0][index]);
length = *((uint8_t *)dat);
myUsbDevice.ep0String.encoding.type = USB_STRING_DESCRIPTOR_UTF16LE;
}
else
{
// Otherwise, verify the language is one of the supported languages or 0.
for (lang = 0; lang < SLAB_USB_NUM_LANGUAGES; lang++)
{
if ((myUsbDevice.stringDescriptors->languageIDs[lang] == myUsbDevice.setup.wIndex)
|| (myUsbDevice.stringDescriptors->languageIDs[lang] == 0))
{
langSupported = true;
break;
}
}
if ((langSupported == true) && (index < myUsbDevice.numberOfStrings))
{
dat = ((uint8_t *)myUsbDevice.stringDescriptors->languageArray[lang][index]);
length = *(dat + USB_STRING_DESCRIPTOR_LENGTH);
myUsbDevice.ep0String.encoding.type = *(dat + USB_STRING_DESCRIPTOR_ENCODING);
dat += USB_STRING_DESCRIPTOR_LENGTH;
if (myUsbDevice.ep0String.encoding.type == USB_STRING_DESCRIPTOR_UTF16LE_PACKED)
{
myUsbDevice.ep0String.encoding.init = true;
}
else
{
myUsbDevice.ep0String.encoding.init = false;
}
}
}
#endif // ( SLAB_USB_NUM_LANGUAGES == 1 )
}
// If there is a descriptor to send, get the proper length, then call
// EP0_Write() to send.
if (length)
{
if (length > myUsbDevice.setup.wLength)
{
length = myUsbDevice.setup.wLength;
}
EP0_Write(dat, length);
retVal = USB_STATUS_OK;
}
}
return retVal;
}
/***************************************************************************//**
* @brief Sends the current interface alternate setting
* @details Sends 0x0000 if alternate interfaces are not supported.
* @return Status of request (type @ref USB_Status_TypeDef)
* @note This function takes no parameters, but it uses the setup command
* stored in @ref myUsbDevice.setup.
******************************************************************************/
static USB_Status_TypeDef GetInterface(void)
{
uint16_t interface = myUsbDevice.setup.wIndex;
USB_Status_TypeDef retVal = USB_STATUS_REQ_ERR;
if ((interface < SLAB_USB_NUM_INTERFACES)
&& (myUsbDevice.setup.wLength == 1)
&& (myUsbDevice.setup.wValue == 0)
&& (*((uint8_t *)&myUsbDevice.setup.bmRequestType) ==
(USB_SETUP_DIR_D2H | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_INTERFACE)))
{
if (myUsbDevice.state == USBD_STATE_CONFIGURED)
{
#if (SLAB_USB_SUPPORT_ALT_INTERFACES)
// Return the alternate setting for the specified interface
EP0_Write(&myUsbDevice.interfaceAltSetting[interface], 1);
#else
// Alternate interfaces are not supported, so return 0x0000.
EP0_Write(&txZero, 1);
#endif
retVal = USB_STATUS_OK;
}
}
return retVal;
}
/***************************************************************************//**
* @brief Sends the requested Remote Wakeup, Self-Powered, or
* Endpoint Status
* @return Status of request (type @ref USB_Status_TypeDef)
* @note This function takes no parameters, but it uses the setup command
* stored in @ref myUsbDevice.setup.
******************************************************************************/
static USB_Status_TypeDef GetStatus(void)
{
USB_Status_TypeDef retVal = USB_STATUS_REQ_ERR;
if ((myUsbDevice.setup.wLength == 2)
&& (myUsbDevice.setup.wValue == 0)
&& (myUsbDevice.setup.bmRequestType.Direction == USB_SETUP_DIR_IN)
&& (myUsbDevice.state >= USBD_STATE_ADDRESSED))
{
pStatus = htole16(0); // Default return value is 0x0000
switch (myUsbDevice.setup.bmRequestType.Recipient)
{
case USB_SETUP_RECIPIENT_DEVICE:
if (myUsbDevice.setup.wIndex == 0)
{
#if SLAB_USB_REMOTE_WAKEUP_ENABLED
// Remote wakeup feature status
if (myUsbDevice.remoteWakeupEnabled)
{
pStatus |= htole16(REMOTE_WAKEUP_ENABLED);
}
#endif // SLAB_USB_REMOTE_WAKEUP_ENABLED
#if SLAB_USB_IS_SELF_POWERED_CB
// Current self/bus power status
if (USBD_IsSelfPoweredCb())
{
pStatus |= htole16(DEVICE_IS_SELFPOWERED);
}
#elif (SLAB_USB_BUS_POWERED == 0)
pStatus |= htole16(DEVICE_IS_SELFPOWERED);
#endif // SLAB_USB_IS_SELF_POWERED_CB
retVal = USB_STATUS_OK;
}
break;
case USB_SETUP_RECIPIENT_INTERFACE:
if (myUsbDevice.setup.wIndex < SLAB_USB_NUM_INTERFACES)
{
retVal = USB_STATUS_OK;
}
break;
case USB_SETUP_RECIPIENT_ENDPOINT:
// Device does not support halting endpoint 0, but do not give
// an error as this is a valid request
if (((myUsbDevice.setup.wIndex & ~USB_EP_DIR_IN) == 0)
&& (myUsbDevice.state == USBD_STATE_ADDRESSED))
{
retVal = USB_STATUS_OK;
}
else if (myUsbDevice.state == USBD_STATE_CONFIGURED)
{
switch (myUsbDevice.setup.wIndex & 0xFF)
{
#if SLAB_USB_EP1OUT_USED
case (USB_EP_DIR_OUT | 1):
if (myUsbDevice.ep1out.state == D_EP_HALT)
{
pStatus = htole16(1);
}
retVal = USB_STATUS_OK;
break;
#endif
#if SLAB_USB_EP2OUT_USED
case (USB_EP_DIR_OUT | 2):
if (myUsbDevice.ep2out.state == D_EP_HALT)
{
pStatus = htole16(1);
}
retVal = USB_STATUS_OK;
break;
#endif
#if SLAB_USB_EP3OUT_USED
case (USB_EP_DIR_OUT | 3):
if (myUsbDevice.ep3out.state == D_EP_HALT)
{
pStatus = htole16(1);
}
retVal = USB_STATUS_OK;
break;
#endif
#if SLAB_USB_EP1IN_USED
case (USB_EP_DIR_IN | 1):
if (myUsbDevice.ep1in.state == D_EP_HALT)
{
pStatus = htole16(1);
}
retVal = USB_STATUS_OK;
break;
#endif
#if SLAB_USB_EP2IN_USED
case (USB_EP_DIR_IN | 2):
if (myUsbDevice.ep2in.state == D_EP_HALT)
{
pStatus = htole16(1);
}
retVal = USB_STATUS_OK;
break;
#endif
#if SLAB_USB_EP3IN_USED
case (USB_EP_DIR_IN | 3):
if (myUsbDevice.ep3in.state == D_EP_HALT)
{
pStatus = htole16(1);
}
retVal = USB_STATUS_OK;
break;
#endif
}
}
break;
}
// If the command was valid, send the requested status.
if (retVal == USB_STATUS_OK)
{
EP0_Write((uint8_t *)&pStatus, 2);
}
}
return retVal;
}
/***************************************************************************//**
* @brief Sets the Address
* @return Status of request (type @ref USB_Status_TypeDef)
* @note This function takes no parameters, but it uses the setup command
* stored in @ref myUsbDevice.setup.
******************************************************************************/
static USB_Status_TypeDef SetAddress(void)
{
USB_Status_TypeDef retVal = USB_STATUS_REQ_ERR;
if ((myUsbDevice.setup.wValue < 128)
&& (myUsbDevice.setup.wLength == 0)
&& (myUsbDevice.setup.bmRequestType.Recipient == USB_SETUP_RECIPIENT_DEVICE)
&& (myUsbDevice.setup.wIndex == 0))
{
// If the device is in the Default state and the address is non-zero, put
// the device in the Addressed state.
if (myUsbDevice.state == USBD_STATE_DEFAULT)
{
if (myUsbDevice.setup.wValue != 0)
{
USBD_SetUsbState(USBD_STATE_ADDRESSED);
}
retVal = USB_STATUS_OK;
}
// If the device is already addressed and the address is zero, put the
// device in the Default state.
else if (myUsbDevice.state == USBD_STATE_ADDRESSED)
{
if (myUsbDevice.setup.wValue == 0)
{
USBD_SetUsbState(USBD_STATE_DEFAULT);
}
retVal = USB_STATUS_OK;
}
// Set the new address if the request was valid.
if (retVal == USB_STATUS_OK)
{
USB_SetAddress(myUsbDevice.setup.wValue);
}
}
return retVal;
}
/***************************************************************************//**
* @brief Sets the Configuration
* @return Status of request (type @ref USB_Status_TypeDef)
* @note This function takes no parameters, but it uses the setup command
* stored in @ref myUsbDevice.setup.
******************************************************************************/
static USB_Status_TypeDef SetConfiguration(void)
{
USB_Status_TypeDef retVal = USB_STATUS_REQ_ERR;
if (((myUsbDevice.setup.wValue >> 8) == 0)
&& (myUsbDevice.setup.bmRequestType.Recipient == USB_SETUP_RECIPIENT_DEVICE)
&& (myUsbDevice.setup.wLength == 0)
&& (myUsbDevice.setup.wIndex == 0))
{
// If the device is in the Addressed state and a valid Configuration value
// was sent, enter the Configured state.
if (myUsbDevice.state == USBD_STATE_ADDRESSED)
{
if ((myUsbDevice.setup.wValue == 0)
|| (myUsbDevice.setup.wValue == myUsbDevice.configDescriptor->bConfigurationValue))
{
myUsbDevice.configurationValue = myUsbDevice.setup.wValue;
if (myUsbDevice.setup.wValue == myUsbDevice.configDescriptor->bConfigurationValue)
{
USBD_ActivateAllEps(true);
USBD_SetUsbState(USBD_STATE_CONFIGURED);
}
retVal = USB_STATUS_OK;
}
}
// If the device is in the Configured state and Configuration zero is sent,
// abort all transfer and enter the Addressed state.
else if (myUsbDevice.state == USBD_STATE_CONFIGURED)
{
if ((myUsbDevice.setup.wValue == 0)
|| (myUsbDevice.setup.wValue == myUsbDevice.configDescriptor->bConfigurationValue))
{
myUsbDevice.configurationValue = myUsbDevice.setup.wValue;
if (myUsbDevice.setup.wValue == 0)
{
USBD_SetUsbState(USBD_STATE_ADDRESSED);
USBD_AbortAllTransfers();
}
else
{
// Reenable device endpoints, will reset data toggles
USBD_ActivateAllEps(false);
}
retVal = USB_STATUS_OK;
}
}
}
return retVal;
}
/***************************************************************************//**
* @brief Sets the Remote Wakeup or Endpoint Halt Feature
* @return Status of request (type @ref USB_Status_TypeDef)
* @note This function takes no parameters, but it uses the setup command
* stored in @ref myUsbDevice.setup.
******************************************************************************/
static USB_Status_TypeDef SetFeature(void)
{
USB_Status_TypeDef retVal = USB_STATUS_REQ_ERR;
if (myUsbDevice.setup.wLength == 0)
{
switch (myUsbDevice.setup.bmRequestType.Recipient)
{
#if SLAB_USB_REMOTE_WAKEUP_ENABLED
case USB_SETUP_RECIPIENT_DEVICE:
if ((myUsbDevice.setup.wIndex == 0) // ITF no. 0
&& (myUsbDevice.setup.wValue == USB_FEATURE_DEVICE_REMOTE_WAKEUP)
&& (myUsbDevice.state == USBD_STATE_CONFIGURED))
{
myUsbDevice.remoteWakeupEnabled = true;
retVal = USB_STATUS_OK;
}
break;
#endif // SLAB_USB_REMOTE_WAKEUP_ENABLED
case USB_SETUP_RECIPIENT_ENDPOINT:
// Device does not support halting endpoint 0, but do not return
// an error as this is a valid request
if (((myUsbDevice.setup.wIndex & ~USB_EP_DIR_IN) == 0)
&& (myUsbDevice.state >= USBD_STATE_ADDRESSED))
{
retVal = USB_STATUS_OK;
}
else if ((((myUsbDevice.setup.wIndex) & ~USB_SETUP_DIR_D2H) < SLAB_USB_NUM_EPS_USED)
&& (myUsbDevice.setup.wValue == USB_FEATURE_ENDPOINT_HALT)
&& (myUsbDevice.state == USBD_STATE_CONFIGURED))
{
retVal = USB_STATUS_OK;
USB_SetIndex((myUsbDevice.setup.wIndex & 0xFF) & ~USB_SETUP_DIR_D2H);
// Enable Stalls on the specified endpoint.
#if (SLAB_USB_EP1IN_USED || SLAB_USB_EP2IN_USED || SLAB_USB_EP3IN_USED)
if ((myUsbDevice.setup.wIndex & 0xFF) & USB_EP_DIR_IN)
{
USB_EpnInStall();
}
#endif
#if (SLAB_USB_EP1OUT_USED || SLAB_USB_EP2OUT_USED || SLAB_USB_EP3OUT_USED)
if (((myUsbDevice.setup.wIndex & 0xFF) & USB_EP_DIR_IN) == 0)
{
USB_EpnOutStall();
}
#endif
// Put the specified endpoint in the Halted state.
switch (myUsbDevice.setup.wIndex & 0xFF)
{
#if SLAB_USB_EP1OUT_USED
case (USB_EP_DIR_OUT | 1):
myUsbDevice.ep1out.state = D_EP_HALT;
break;
#endif
#if SLAB_USB_EP2OUT_USED
case (USB_EP_DIR_OUT | 2):
myUsbDevice.ep2out.state = D_EP_HALT;
break;
#endif
#if SLAB_USB_EP3OUT_USED
case (USB_EP_DIR_OUT | 3):
myUsbDevice.ep3out.state = D_EP_HALT;
break;
#endif
#if SLAB_USB_EP1IN_USED
case (USB_EP_DIR_IN | 1):
myUsbDevice.ep1in.state = D_EP_HALT;
break;
#endif
#if SLAB_USB_EP2IN_USED
case (USB_EP_DIR_IN | 2):
myUsbDevice.ep2in.state = D_EP_HALT;
break;
#endif
#if SLAB_USB_EP3IN_USED
case (USB_EP_DIR_IN | 3):
myUsbDevice.ep3in.state = D_EP_HALT;
break;
#endif
}
}
}
}
return retVal;
}
/***************************************************************************//**
* @brief Sets the Interface and Alternate Interface (if supported)
* @return Status of request (type @ref USB_Status_TypeDef)
* @note This function takes no parameters, but it uses the setup command
* stored in @ref myUsbDevice.setup.
******************************************************************************/
static USB_Status_TypeDef SetInterface(void)
{
USB_Status_TypeDef retVal = USB_STATUS_REQ_ERR;
uint8_t interface = (uint8_t)myUsbDevice.setup.wIndex;
uint8_t altSetting = (uint8_t)myUsbDevice.setup.wValue;
if ((interface < SLAB_USB_NUM_INTERFACES)
&& (myUsbDevice.state == USBD_STATE_CONFIGURED)
&& (myUsbDevice.setup.wLength == 0)
#if (SLAB_USB_SUPPORT_ALT_INTERFACES == 0)
&& (altSetting == 0)
#endif
&& (myUsbDevice.setup.bmRequestType.Recipient == USB_SETUP_RECIPIENT_INTERFACE))
{
#if (SLAB_USB_SUPPORT_ALT_INTERFACES)
if (USBD_SetInterfaceCb(interface, altSetting) == USB_STATUS_OK)
{
myUsbDevice.interfaceAltSetting[interface] = altSetting;
retVal = USB_STATUS_OK;
}
#else
#if (SLAB_USB_NUM_INTERFACES == 1)
// Reset data toggles on EP's
USBD_ActivateAllEps(false);
#endif // ( SLAB_USB_NUM_INTERFACES == 1 )
retVal = USB_STATUS_OK;
#endif // ( SLAB_USB_SUPPORT_ALT_INTERFACES )
}
return retVal;
}
// -----------------------------------------------------------------------------
// Utility Functions
/***************************************************************************//**
* @brief Enables all endpoints for data transfers
* @return Status of request (type @ref USB_Status_TypeDef)
* @note This function takes no parameters, but it uses the setup command
* stored in @ref myUsbDevice.setup.
******************************************************************************/
static void USBD_ActivateAllEps(bool forceIdle)
{
if (forceIdle == true)
{
#if SLAB_USB_EP1IN_USED
myUsbDevice.ep1in.state = D_EP_IDLE;
#endif
#if SLAB_USB_EP2IN_USED
myUsbDevice.ep2in.state = D_EP_IDLE;
#endif
#if SLAB_USB_EP3IN_USED
myUsbDevice.ep3in.state = D_EP_IDLE;
#endif
#if SLAB_USB_EP1OUT_USED
myUsbDevice.ep1out.state = D_EP_IDLE;
#endif
#if SLAB_USB_EP2OUT_USED
myUsbDevice.ep2out.state = D_EP_IDLE;
#endif
#if SLAB_USB_EP3OUT_USED
myUsbDevice.ep3out.state = D_EP_IDLE;
#endif
}
#if SLAB_USB_EP1IN_USED
USB_ActivateEp(1, // ep
SLAB_USB_EP1IN_MAX_PACKET_SIZE, // packetSize
1, // inDir
SLAB_USB_EP1OUT_USED, // splitMode
0); // isoMod
#endif // SLAB_USB_EP1IN_USED
#if SLAB_USB_EP2IN_USED
USB_ActivateEp(2, // ep
SLAB_USB_EP2IN_MAX_PACKET_SIZE, // packetSize
1, // inDir
SLAB_USB_EP2OUT_USED, // splitMode
0); // isoMod
#endif // SLAB_USB_EP2IN_USED
#if SLAB_USB_EP3IN_USED
USB_ActivateEp(3, // ep
SLAB_USB_EP3IN_MAX_PACKET_SIZE, // packetSize
1, // inDir
SLAB_USB_EP3OUT_USED, // splitMode
(SLAB_USB_EP3IN_TRANSFER_TYPE == USB_EPTYPE_ISOC)); // isoMod
#endif // SLAB_USB_EP3IN_USED
#if SLAB_USB_EP1OUT_USED
USB_ActivateEp(1, // ep
SLAB_USB_EP1OUT_MAX_PACKET_SIZE, // packetSize
0, // inDir
SLAB_USB_EP1IN_USED, // splitMode
0); // isoMod
#endif // SLAB_USB_EP1OUT_USED
#if SLAB_USB_EP2OUT_USED
USB_ActivateEp(2, // ep
SLAB_USB_EP2OUT_MAX_PACKET_SIZE, // packetSize
0, // inDir
SLAB_USB_EP2IN_USED, // splitMode
0); // isoMod
#endif // SLAB_USB_EP2OUT_USED
#if SLAB_USB_EP3OUT_USED
USB_ActivateEp(3, // ep
SLAB_USB_EP3OUT_MAX_PACKET_SIZE, // packetSize
0, // inDir
SLAB_USB_EP3IN_USED, // splitMode
(SLAB_USB_EP3OUT_TRANSFER_TYPE == USB_EPTYPE_ISOC)); // isoMod
#endif // SLAB_USB_EP1OUT_USED
}
/***************************************************************************//**
* @brief Sets up an Endpoint 0 Write
* @param dat
* Data to transmit on Endpoint 0
* @param numBytes
* Number of bytes to transmit on Endpoint 0
******************************************************************************/
static void EP0_Write(uint8_t *dat, uint16_t numBytes)
{
if (myUsbDevice.ep0.state == D_EP_IDLE)
{
myUsbDevice.ep0.buf = (uint8_t *)dat;
myUsbDevice.ep0.remaining = numBytes;
myUsbDevice.ep0.state = D_EP_TRANSMITTING;
myUsbDevice.ep0.misc.c = 0;
}
}

View File

@ -1,896 +0,0 @@
/**************************************************************************//**
* Copyright (c) 2015 by Silicon Laboratories Inc. All rights reserved.
*
* http://developer.silabs.com/legal/version/v11/Silicon_Labs_Software_License_Agreement.txt
*****************************************************************************/
#include "si_toolchain.h"
#include "efm8_usb.h"
#include <stdint.h>
#include <endian.h>
extern SI_SEGMENT_VARIABLE(myUsbDevice, USBD_Device_TypeDef, MEM_MODEL_SEG);
// -----------------------------------------------------------------------------
// Function Prototypes
// -------------------------------
// Memory-specific FIFO access functions
#ifdef SI_GPTR
static void USB_ReadFIFO_Idata(uint8_t numBytes, SI_VARIABLE_SEGMENT_POINTER(dat, uint8_t, SI_SEG_IDATA), uint8_t fifoNum);
static void USB_WriteFIFO_Idata(uint8_t numBytes, SI_VARIABLE_SEGMENT_POINTER(dat, uint8_t, SI_SEG_IDATA));
static void USB_ReadFIFO_Xdata(uint8_t numBytes, SI_VARIABLE_SEGMENT_POINTER(dat, uint8_t, SI_SEG_XDATA), uint8_t fifoNum);
static void USB_WriteFIFO_Xdata(uint8_t numBytes, SI_VARIABLE_SEGMENT_POINTER(dat, uint8_t, SI_SEG_XDATA));
#if SI_GPTR_MTYPE_PDATA != SI_GPTR_MTYPE_XDATA
static void USB_ReadFIFO_Pdata(uint8_t numBytes, SI_VARIABLE_SEGMENT_POINTER(dat, uint8_t, SI_SEG_PDATA), uint8_t fifoNum);
static void USB_WriteFIFO_Pdata(uint8_t numBytes, SI_VARIABLE_SEGMENT_POINTER(dat, uint8_t, SI_SEG_PDATA));
#endif
#if SI_GPTR_MTYPE_DATA != SI_GPTR_MTYPE_IDATA
static void USB_ReadFIFO_Data(uint8_t numBytes, SI_VARIABLE_SEGMENT_POINTER(dat, uint8_t, SI_SEG_DATA), uint8_t fifoNum);
static void USB_WriteFIFO_Data(uint8_t numBytes, uint8_t SI_VARIABLE_SEGMENT_POINTER(dat, uint8_t, SI_SEG_DATA));
#endif
static void USB_WriteFIFO_Code(uint8_t numBytes, SI_VARIABLE_SEGMENT_POINTER(dat, uint8_t, SI_SEG_CODE));
#else
// -------------------------------
// Generic FIFO access functions
static void USB_ReadFIFO_Generic(uint8_t numBytes, uint8_t *dat, uint8_t fifoNum);
static void USB_WriteFIFO_Generic(uint8_t numBytes, uint8_t *dat);
#endif // #ifdef SI_GPTR
// -----------------------------------------------------------------------------
// Functions
/***************************************************************************//**
* @brief Reads Isochronous data from the Endpoint FIFO
* @param fifoNum
* USB Endpoint FIFO to read
* @param numBytes
* Number of bytes to read from the FIFO
* @param dat
* Pointer to buffer to hold data read from the FIFO
******************************************************************************/
#if (SLAB_USB_EP3OUT_USED && (SLAB_USB_EP3OUT_TRANSFER_TYPE == USB_EPTYPE_ISOC) && (SLAB_USB_EP3OUT_MAX_PACKET_SIZE > 255))
// ----------------------------------------------------------------------------
// If Isochronous mode is enabled and the max packet size is greater than 255,
// break the FIFO reads up into multiple reads of 255 or less bytes.
// ----------------------------------------------------------------------------
void USB_ReadFIFOIso(uint8_t fifoNum, uint16_t numBytes, uint8_t *dat)
{
uint8_t numBytesRead;
// USB_ReadFIFO() accepts a maximum of 255 bytes. If the number of bytes to
// send is greated than 255, call USB_ReadFIFO() multiple times.
while (numBytes > 0)
{
numBytesRead = (numBytes > 255) ? 255 : numBytes;
USB_ReadFIFO(fifoNum, numBytesRead, dat);
numBytes -= numBytesRead;
dat += numBytesRead;
}
}
#else
#define USB_ReadFIFOIso(a, b, c) USB_ReadFIFO(a, b, c)
#endif
/***************************************************************************//**
* @brief Writes Isochronous data to the Endpoint FIFO
* @param fifoNum
* USB Endpoint FIFO to write
* @param numBytes
* Number of bytes to write to the FIFO
* @param dat
* Pointer to buffer hoding data to write to the FIFO
******************************************************************************/
#if (SLAB_USB_EP3IN_USED && (SLAB_USB_EP3IN_TRANSFER_TYPE == USB_EPTYPE_ISOC) && (SLAB_USB_EP3IN_MAX_PACKET_SIZE > 255))
// ----------------------------------------------------------------------------
// If Isochronous mode is enabled and the max packet size is greater than 255,
// break the FIFO writes up into multiple writes of 255 or less bytes.
// ----------------------------------------------------------------------------
void USB_WriteFIFOIso(uint8_t fifoNum, uint16_t numBytes, uint8_t *dat)
{
uint8_t numBytesWrite;
// USB_WriteFIFO() accepts a maximum of 255 bytes. If the number of bytes to
// send is greated than 255, call USB_WriteFIFO() multiple times.
while (numBytes > 0)
{
numBytesWrite = (numBytes > 255) ? 255 : numBytes;
numBytes -= numBytesWrite;
USB_WriteFIFO(fifoNum, numBytesWrite, dat, (numBytes == 0));
dat += numBytesWrite;
}
}
#else
#define USB_WriteFIFOIso(a, b, c) USB_WriteFIFO(a, b, c, true)
#endif
#if SLAB_USB_EP1IN_USED
/***************************************************************************//**
* @brief Handle Endpoint 1 IN transfer interrupt
* @note This function takes no parameters, but it uses the EP1IN status
* variables stored in @ref myUsbDevice.ep1in.
******************************************************************************/
void handleUsbIn1Int(void)
{
uint8_t xferred;
bool callback;
USB_SetIndex(1);
if (USB_EpnInGetSentStall())
{
USB_EpnInClearSentStall();
}
else if (myUsbDevice.ep1in.state == D_EP_TRANSMITTING)
{
xferred = (myUsbDevice.ep1in.remaining > SLAB_USB_EP1IN_MAX_PACKET_SIZE)
? SLAB_USB_EP1IN_MAX_PACKET_SIZE : myUsbDevice.ep1in.remaining;
myUsbDevice.ep1in.remaining -= xferred;
myUsbDevice.ep1in.buf += xferred;
callback = myUsbDevice.ep1in.misc.bits.callback;
// Load more data
if (myUsbDevice.ep1in.remaining > 0)
{
USB_WriteFIFO(1,
(myUsbDevice.ep1in.remaining > SLAB_USB_EP1IN_MAX_PACKET_SIZE)
? SLAB_USB_EP1IN_MAX_PACKET_SIZE
: myUsbDevice.ep1in.remaining,
myUsbDevice.ep1in.buf,
true);
}
else
{
myUsbDevice.ep1in.misc.bits.callback = false;
myUsbDevice.ep1in.state = D_EP_IDLE;
}
if (callback == true)
{
USBD_XferCompleteCb(EP1IN, USB_STATUS_OK, xferred, myUsbDevice.ep1in.remaining);
}
}
}
#endif // SLAB_USB_EP1IN_USED
#if SLAB_USB_EP2IN_USED
/***************************************************************************//**
* @brief Handle Endpoint 2 IN transfer interrupt
* @note This function takes no parameters, but it uses the EP2IN status
* variables stored in @ref myUsbDevice.ep2in.
******************************************************************************/
void handleUsbIn2Int(void)
{
uint8_t xferred;
bool callback;
USB_SetIndex(2);
if (USB_EpnInGetSentStall())
{
USB_EpnInClearSentStall();
}
else if (myUsbDevice.ep2in.state == D_EP_TRANSMITTING)
{
xferred = (myUsbDevice.ep2in.remaining > SLAB_USB_EP2IN_MAX_PACKET_SIZE)
? SLAB_USB_EP2IN_MAX_PACKET_SIZE : myUsbDevice.ep2in.remaining;
myUsbDevice.ep2in.remaining -= xferred;
myUsbDevice.ep2in.buf += xferred;
callback = myUsbDevice.ep2in.misc.bits.callback;
// Load more data
if (myUsbDevice.ep2in.remaining > 0)
{
USB_WriteFIFO(2,
(myUsbDevice.ep2in.remaining > SLAB_USB_EP2IN_MAX_PACKET_SIZE)
? SLAB_USB_EP2IN_MAX_PACKET_SIZE
: myUsbDevice.ep2in.remaining,
myUsbDevice.ep2in.buf,
true);
}
else
{
myUsbDevice.ep2in.misc.bits.callback = false;
myUsbDevice.ep2in.state = D_EP_IDLE;
}
if (callback == true)
{
USBD_XferCompleteCb(EP2IN, USB_STATUS_OK, xferred, myUsbDevice.ep2in.remaining);
}
}
}
#endif // SLAB_USB_EP2IN_USED
#if SLAB_USB_EP3IN_USED
/***************************************************************************//**
* @brief Handle Endpoint 3 IN transfer interrupt
* @details Endpoint 3 IN is the only IN endpoint that supports isochronous
* transfers.
* @note This function takes no parameters, but it uses the EP3IN status
* variables stored in @ref myUsbDevice.ep3in.
******************************************************************************/
void handleUsbIn3Int(void)
{
#if SLAB_USB_EP3IN_TRANSFER_TYPE == USB_EPTYPE_ISOC
uint16_t xferred, nextIdx;
#else
uint8_t xferred;
bool callback;
#endif
USB_SetIndex(3);
if (USB_EpnInGetSentStall())
{
USB_EpnInClearSentStall();
}
else if (myUsbDevice.ep3in.state == D_EP_TRANSMITTING)
{
#if ((SLAB_USB_EP3IN_TRANSFER_TYPE == USB_EPTYPE_BULK) || (SLAB_USB_EP3IN_TRANSFER_TYPE == USB_EPTYPE_INTR))
xferred = (myUsbDevice.ep3in.remaining > SLAB_USB_EP3IN_MAX_PACKET_SIZE)
? SLAB_USB_EP3IN_MAX_PACKET_SIZE : myUsbDevice.ep3in.remaining;
myUsbDevice.ep3in.remaining -= xferred;
myUsbDevice.ep3in.buf += xferred;
#endif
#if ((SLAB_USB_EP3IN_TRANSFER_TYPE == USB_EPTYPE_BULK) || (SLAB_USB_EP3IN_TRANSFER_TYPE == USB_EPTYPE_INTR))
callback = myUsbDevice.ep3in.misc.bits.callback;
#elif (SLAB_USB_EP3IN_TRANSFER_TYPE == USB_EPTYPE_ISOC)
if (myUsbDevice.ep3in.misc.bits.callback == true)
{
// In Isochronous mode, the meaning of the USBD_XferCompleteCb parameters changes:
// xferred is ignored
// remaining is the current index into the circular buffer
// the return value is the number of bytes to transmit in the next packet
xferred = USBD_XferCompleteCb(EP3IN, USB_STATUS_OK, 0, myUsbDevice.ep3inIsoIdx);
if (xferred == 0)
{
myUsbDevice.ep3in.misc.bits.inPacketPending = true;
return;
}
}
#endif
// Load more data
#if ((SLAB_USB_EP3IN_TRANSFER_TYPE == USB_EPTYPE_BULK) || (SLAB_USB_EP3IN_TRANSFER_TYPE == USB_EPTYPE_INTR))
if (myUsbDevice.ep3in.remaining > 0)
{
USB_WriteFIFO(3,
(myUsbDevice.ep3in.remaining > SLAB_USB_EP3IN_MAX_PACKET_SIZE)
? SLAB_USB_EP3IN_MAX_PACKET_SIZE
: myUsbDevice.ep3in.remaining,
myUsbDevice.ep3in.buf,
true);
}
else
{
myUsbDevice.ep3in.misc.bits.callback = false;
myUsbDevice.ep3in.state = D_EP_IDLE;
}
if (callback == true)
{
USBD_XferCompleteCb(EP3IN, USB_STATUS_OK, xferred, myUsbDevice.ep3in.remaining);
}
#elif (SLAB_USB_EP3IN_TRANSFER_TYPE == USB_EPTYPE_ISOC)
nextIdx = xferred + myUsbDevice.ep3inIsoIdx;
myUsbDevice.ep3in.misc.bits.inPacketPending = false;
// Check if the next index is past the end of the circular buffer.
// If so, break the write up into two calls to USB_WriteFIFOIso()
if (nextIdx > myUsbDevice.ep3in.remaining)
{
USB_WriteFIFOIso(3, myUsbDevice.ep3in.remaining - myUsbDevice.ep3inIsoIdx, &myUsbDevice.ep3in.buf[myUsbDevice.ep3inIsoIdx]);
myUsbDevice.ep3inIsoIdx = nextIdx - myUsbDevice.ep3in.remaining;
USB_WriteFIFOIso(3, myUsbDevice.ep3inIsoIdx, myUsbDevice.ep3in.buf);
}
else
{
USB_WriteFIFOIso(3, xferred, &myUsbDevice.ep3in.buf[myUsbDevice.ep3inIsoIdx]);
myUsbDevice.ep3inIsoIdx = nextIdx;
}
#endif // ( ( SLAB_USB_EP3IN_TRANSFER_TYPE == USB_EPTYPE_BULK ) || ( SLAB_USB_EP3IN_TRANSFER_TYPE == USB_EPTYPE_INTR ) )
}
}
#endif // SLAB_USB_EP3IN_USED
#if SLAB_USB_EP1OUT_USED
/***************************************************************************//**
* @brief Handle Endpoint 1 OUT transfer interrupt
* @note This function takes no parameters, but it uses the EP1OUT status
* variables stored in @ref myUsbDevice.ep1out.
******************************************************************************/
void handleUsbOut1Int(void)
{
uint8_t count;
USB_Status_TypeDef status;
bool xferComplete = false;
USB_SetIndex(1);
if (USB_EpnOutGetSentStall())
{
USB_EpnOutClearSentStall();
}
else if (USB_EpnGetOutPacketReady())
{
count = USB_EpOutGetCount();
// If USBD_Read() has not been called, return an error
if (myUsbDevice.ep1out.state != D_EP_RECEIVING)
{
myUsbDevice.ep1out.misc.bits.outPacketPending = true;
status = USB_STATUS_EP_ERROR;
}
// Check for overrun of user buffer
else if (myUsbDevice.ep1out.remaining < count)
{
myUsbDevice.ep1out.state = D_EP_IDLE;
myUsbDevice.ep1out.misc.bits.outPacketPending = true;
status = USB_STATUS_EP_RX_BUFFER_OVERRUN;
}
else
{
USB_ReadFIFO(1, count, myUsbDevice.ep1out.buf);
myUsbDevice.ep1out.misc.bits.outPacketPending = false;
myUsbDevice.ep1out.remaining -= count;
myUsbDevice.ep1out.buf += count;
if ((myUsbDevice.ep1out.remaining == 0) || (count != SLAB_USB_EP1OUT_MAX_PACKET_SIZE))
{
myUsbDevice.ep1out.state = D_EP_IDLE;
xferComplete = true;
}
status = USB_STATUS_OK;
USB_EpnClearOutPacketReady();
}
if (myUsbDevice.ep1out.misc.bits.callback == true)
{
if (xferComplete == true)
{
myUsbDevice.ep1out.misc.bits.callback = false;
}
USBD_XferCompleteCb(EP1OUT, status, count, myUsbDevice.ep1out.remaining);
}
}
}
#endif // EP1OUT_USED
#if SLAB_USB_EP2OUT_USED
/***************************************************************************//**
* @brief Handle Endpoint 2 OUT transfer interrupt
* @note This function takes no parameters, but it uses the EP2OUT status
* variables stored in @ref myUsbDevice.ep2out.
******************************************************************************/
void handleUsbOut2Int(void)
{
uint8_t count;
USB_Status_TypeDef status;
bool xferComplete = false;
USB_SetIndex(2);
if (USB_EpnOutGetSentStall())
{
USB_EpnOutClearSentStall();
}
else if (USB_EpnGetOutPacketReady())
{
count = USB_EpOutGetCount();
// If USBD_Read() has not been called, return an error
if (myUsbDevice.ep2out.state != D_EP_RECEIVING)
{
myUsbDevice.ep2out.misc.bits.outPacketPending = true;
status = USB_STATUS_EP_ERROR;
}
// Check for overrun of user buffer
else if (myUsbDevice.ep2out.remaining < count)
{
myUsbDevice.ep2out.state = D_EP_IDLE;
myUsbDevice.ep2out.misc.bits.outPacketPending = true;
status = USB_STATUS_EP_RX_BUFFER_OVERRUN;
}
else
{
USB_ReadFIFO(2, count, myUsbDevice.ep2out.buf);
myUsbDevice.ep2out.misc.bits.outPacketPending = false;
myUsbDevice.ep2out.remaining -= count;
myUsbDevice.ep2out.buf += count;
if ((myUsbDevice.ep2out.remaining == 0) || (count != SLAB_USB_EP2OUT_MAX_PACKET_SIZE))
{
myUsbDevice.ep2out.state = D_EP_IDLE;
xferComplete = true;
}
status = USB_STATUS_OK;
USB_EpnClearOutPacketReady();
}
if (myUsbDevice.ep2out.misc.bits.callback == true)
{
if (xferComplete == true)
{
myUsbDevice.ep2out.misc.bits.callback = false;
}
USBD_XferCompleteCb(EP2OUT, status, count, myUsbDevice.ep2out.remaining);
}
}
}
#endif // EP2OUT_USED
#if SLAB_USB_EP3OUT_USED
/***************************************************************************//**
* @brief Handle Endpoint 3 OUT transfer interrupt
* @details Endpoint 3 OUT is the only OUT endpoint that supports
* isochronous transfers.
* @note This function takes no parameters, but it uses the EP3OUT status
* variables stored in @ref myUsbDevice.ep3out.
******************************************************************************/
void handleUsbOut3Int(void)
{
#if (SLAB_USB_EP3OUT_TRANSFER_TYPE == USB_EPTYPE_ISOC)
uint16_t nextIdx;
#if (SLAB_USB_EP3OUT_MAX_PACKET_SIZE > 255)
uint16_t count;
#else
uint8_t count;
#endif // ( SLAB_USB_EP3OUT_MAX_PACKET_SIZE > 255 )
#else
uint8_t count;
#endif // ( SLAB_USB_EP3OUT_TRANSFER_TYPE == USB_EPTYPE_ISOC )
USB_Status_TypeDef status;
bool xferComplete = false;
USB_SetIndex(3);
if (USB_EpnOutGetSentStall())
{
USB_EpnOutClearSentStall();
}
else if (USB_EpnGetOutPacketReady())
{
count = USB_EpOutGetCount();
// If USBD_Read() has not been called, return an error
if (myUsbDevice.ep3out.state != D_EP_RECEIVING)
{
myUsbDevice.ep3out.misc.bits.outPacketPending = true;
status = USB_STATUS_EP_ERROR;
}
#if ((SLAB_USB_EP3OUT_TRANSFER_TYPE == USB_EPTYPE_BULK) || (SLAB_USB_EP3OUT_TRANSFER_TYPE == USB_EPTYPE_INTR))
// Check for overrun of user buffer
else if (myUsbDevice.ep3out.remaining < count)
{
myUsbDevice.ep3out.state = D_EP_IDLE;
myUsbDevice.ep3out.misc.bits.outPacketPending = true;
status = USB_STATUS_EP_RX_BUFFER_OVERRUN;
}
#endif
else
{
#if ((SLAB_USB_EP3OUT_TRANSFER_TYPE == USB_EPTYPE_BULK) || (SLAB_USB_EP3OUT_TRANSFER_TYPE == USB_EPTYPE_INTR))
USB_ReadFIFO(3, count, myUsbDevice.ep3out.buf);
myUsbDevice.ep3out.remaining -= count;
myUsbDevice.ep3out.buf += count;
if ((myUsbDevice.ep3out.remaining == 0) || (count != SLAB_USB_EP3OUT_MAX_PACKET_SIZE))
{
myUsbDevice.ep3out.state = D_EP_IDLE;
xferComplete = true;
}
#elif (SLAB_USB_EP3OUT_TRANSFER_TYPE == USB_EPTYPE_ISOC)
nextIdx = count + myUsbDevice.ep3outIsoIdx;
// In isochronous mode, a circular buffer is used to hold the data
// If the next index into the circular buffer passes the end of the
// buffer, make two calls to USB_ReadFIFOIso()
if (nextIdx > myUsbDevice.ep3out.remaining)
{
USB_ReadFIFOIso(3, myUsbDevice.ep3out.remaining - myUsbDevice.ep3outIsoIdx, &myUsbDevice.ep3out.buf[myUsbDevice.ep3outIsoIdx]);
myUsbDevice.ep3outIsoIdx = nextIdx - myUsbDevice.ep3out.remaining;
USB_ReadFIFOIso(3, myUsbDevice.ep3outIsoIdx, myUsbDevice.ep3out.buf);
}
else
{
USB_ReadFIFOIso(3, count, &myUsbDevice.ep3out.buf[myUsbDevice.ep3outIsoIdx]);
myUsbDevice.ep3outIsoIdx = nextIdx;
}
#endif // ( ( SLAB_USB_EP3OUT_TRANSFER_TYPE == USB_EPTYPE_BULK ) || ( SLAB_USB_EP3OUT_TRANSFER_TYPE == USB_EPTYPE_INTR ) )
myUsbDevice.ep3out.misc.bits.outPacketPending = false;
status = USB_STATUS_OK;
USB_EpnClearOutPacketReady();
}
if (myUsbDevice.ep3out.misc.bits.callback == true)
{
if (xferComplete == true)
{
myUsbDevice.ep3out.misc.bits.callback = false;
}
#if ((SLAB_USB_EP3OUT_TRANSFER_TYPE == USB_EPTYPE_BULK) || (SLAB_USB_EP3OUT_TRANSFER_TYPE == USB_EPTYPE_INTR))
USBD_XferCompleteCb(EP3OUT, status, count, myUsbDevice.ep3out.remaining);
#elif (SLAB_USB_EP3OUT_TRANSFER_TYPE == USB_EPTYPE_ISOC)
// In Isochronous mode, the meaning of the USBD_XferCompleteCb parameters changes:
// xferred is the number of bytes received in the last packet
// remaining is the current index into the circular buffer
USBD_XferCompleteCb(EP3OUT, status, count, myUsbDevice.ep3outIsoIdx);
#endif
}
}
}
#endif // EP3OUT_USED
/***************************************************************************//**
* @brief Reads data from the USB FIFO
* @param fifoNum
* USB Endpoint FIFO to read
* @param numBytes
* Number of bytes to read from the FIFO
* @param dat
* Pointer to buffer to hold data read from the FIFO
******************************************************************************/
void USB_ReadFIFO(uint8_t fifoNum, uint8_t numBytes, uint8_t *dat)
{
if (numBytes > 0)
{
USB_EnableReadFIFO(fifoNum);
// Convert generic pointer to memory-specific pointer and call the
// the corresponding memory-specific function, if possible.
// The memory-specific functions are much faster than the generic functions.
#ifdef SI_GPTR
switch (((SI_GEN_PTR_t *)&dat)->gptr.memtype)
{
case SI_GPTR_MTYPE_IDATA:
USB_ReadFIFO_Idata(numBytes, dat, fifoNum);
break;
// For some compilers, IDATA and DATA are treated the same.
// Only call the USB_ReadFIFO_Data() if the compiler differentiates
// between DATA and IDATA.
#if (SI_GPTR_MTYPE_DATA != SI_GPTR_MTYPE_IDATA)
case SI_GPTR_MTYPE_DATA:
USB_ReadFIFO_Data(numBytes, dat, fifoNum);
break;
#endif
case SI_GPTR_MTYPE_XDATA:
USB_ReadFIFO_Xdata(numBytes, dat, fifoNum);
break;
// For some compilers, XDATA and PDATA are treated the same.
// Only call the USB_ReadFIFO_Pdata() if the compiler differentiates
// between XDATA and PDATA.
#if (SI_GPTR_MTYPE_PDATA != SI_GPTR_MTYPE_XDATA)
case SI_GPTR_MTYPE_PDATA:
USB_ReadFIFO_Pdata(numBytes, dat, fifoNum);
break;
#endif
default:
break;
}
#else
USB_ReadFIFO_Generic(numBytes, dat, fifoNum);
#endif // #ifdef SI_GPTR
USB_DisableReadFIFO(fifoNum);
}
}
/***************************************************************************//**
* @brief Writes data to the USB FIFO
* @param fifoNum
* USB Endpoint FIFO to write
* @param numBytes
* Number of bytes to write to the FIFO
* @param dat
* Pointer to buffer hoding data to write to the FIFO
* @param txPacket
* If TRUE, the packet will be sent immediately after loading the
* FIFO
* If FALSE, the packet will be stored in the FIFO and the
* transmission must be started at a later time
******************************************************************************/
void USB_WriteFIFO(uint8_t fifoNum, uint8_t numBytes, uint8_t *dat, bool txPacket)
{
USB_EnableWriteFIFO(fifoNum);
// Convert generic pointer to memory-specific pointer and call the
// the corresponding memory-specific function, if possible.
// The memory-specific functions are much faster than the generic functions.
#ifdef SI_GPTR
switch (((SI_GEN_PTR_t *)&dat)->gptr.memtype)
{
case SI_GPTR_MTYPE_IDATA:
USB_WriteFIFO_Idata(numBytes, dat);
break;
// For some compilers, IDATA and DATA are treated the same.
// Only call the USB_WriteFIFO_Data() if the compiler differentiates between
// DATA and IDATA.
#if (SI_GPTR_MTYPE_DATA != SI_GPTR_MTYPE_IDATA)
case SI_GPTR_MTYPE_DATA:
USB_WriteFIFO_Data(numBytes, dat);
break;
#endif
case SI_GPTR_MTYPE_XDATA:
USB_WriteFIFO_Xdata(numBytes, dat);
break;
// For some compilers, XDATA and PDATA are treated the same.
// Only call the USB_WriteFIFO_Pdata() if the compiler differentiates
// between XDATA and PDATA.
#if (SI_GPTR_MTYPE_PDATA != SI_GPTR_MTYPE_XDATA)
case SI_GPTR_MTYPE_PDATA:
USB_WriteFIFO_Pdata(numBytes, dat);
break;
#endif
case SI_GPTR_MTYPE_CODE:
USB_WriteFIFO_Code(numBytes, dat);
break;
default:
break;
}
#else
USB_WriteFIFO_Generic(numBytes, dat);
#endif // #ifdef SI_GPTR
USB_DisableWriteFIFO(fifoNum);
if ((txPacket == true) && (fifoNum > 0))
{
USB_SetIndex(fifoNum);
USB_EpnSetInPacketReady();
}
}
// -----------------------------------------------------------------------------
// Memory-Specific FIFO Access Functions
//
// Memory-specific functions are much faster (more than 2x) than generic
// generic functions, so we will use memory-specific functions if possible.
// -----------------------------------------------------------------------------
#ifdef SI_GPTR
/***************************************************************************//**
* @brief Reads data from the USB FIFO to a buffer in IRAM
* @param numBytes
* Number of bytes to read from the FIFO
* @param dat
* Pointer to IDATA buffer to hold data read from the FIFO
* @param fifoNum
* USB FIFO to read
******************************************************************************/
static void USB_ReadFIFO_Idata(uint8_t numBytes, SI_VARIABLE_SEGMENT_POINTER(dat, uint8_t, SI_SEG_IDATA), uint8_t fifoNum)
{
while (--numBytes)
{
USB_GetFIFOByte(dat);
dat++;
}
USB_GetLastFIFOByte(dat, fifoNum);
}
/***************************************************************************//**
* @brief Writes data held in IRAM to the USB FIFO
* @details The FIFO to write must be set before calling the function with
* @ref USB_EnableWriteFIFO().
* @param numBytes
* Number of bytes to write to the FIFO
* @param dat
* Pointer to IDATA buffer holding data to write to the FIFO
******************************************************************************/
static void USB_WriteFIFO_Idata(uint8_t numBytes, SI_VARIABLE_SEGMENT_POINTER(dat, uint8_t, SI_SEG_IDATA))
{
while (numBytes--)
{
USB_SetFIFOByte(*dat);
dat++;
}
}
/***************************************************************************//**
* @brief Reads data from the USB FIFO to a buffer in XRAM
* @param numBytes
* Number of bytes to read from the FIFO
* @param dat
* Pointer to XDATA buffer to hold data read from the FIFO
* @param fifoNum
* USB FIFO to read
******************************************************************************/
static void USB_ReadFIFO_Xdata(uint8_t numBytes, SI_VARIABLE_SEGMENT_POINTER(dat, uint8_t, SI_SEG_XDATA), uint8_t fifoNum)
{
while (--numBytes)
{
USB_GetFIFOByte(dat);
dat++;
}
USB_GetLastFIFOByte(dat, fifoNum);
}
/***************************************************************************//**
* @brief Writes data held in XRAM to the USB FIFO
* @details The FIFO to write must be set before calling the function with
* @ref USB_EnableWriteFIFO().
* @param numBytes
* Number of bytes to write to the FIFO
* @param dat
* Pointer to XDATA buffer holding data to write to the FIFO
******************************************************************************/
static void USB_WriteFIFO_Xdata(uint8_t numBytes, SI_VARIABLE_SEGMENT_POINTER(dat, uint8_t, SI_SEG_XDATA))
{
while (numBytes--)
{
USB_SetFIFOByte(*dat);
dat++;
}
}
#if SI_GPTR_MTYPE_PDATA != SI_GPTR_MTYPE_XDATA
/***************************************************************************//**
* @brief Reads data from the USB FIFO to a buffer in paged XRAM
* @param numBytes
* Number of bytes to read from the FIFO
* @param dat
* Pointer to PDATA buffer to hold data read from the FIFO
* @param fifoNum
* USB FIFO to read
******************************************************************************/
static void USB_ReadFIFO_Pdata(uint8_t numBytes, SI_VARIABLE_SEGMENT_POINTER(dat, uint8_t, SI_SEG_PDATA), uint8_t fifoNum)
{
while (--numBytes)
{
USB_GetFIFOByte(dat);
dat++;
}
USB_GetLastFIFOByte(dat, fifoNum);
}
/***************************************************************************//**
* @brief Writes data held in paged XRAM to the USB FIFO
* @details The FIFO to write must be set before calling the function with
* @ref USB_EnableWriteFIFO().
* @param numBytes
* Number of bytes to write to the FIFO
* @param dat
* Pointer to PDATA buffer holding data to write to the FIFO
******************************************************************************/
static void USB_WriteFIFO_Pdata(uint8_t numBytes, SI_VARIABLE_SEGMENT_POINTER(dat, uint8_t, SI_SEG_PDATA))
{
while (numBytes--)
{
USB_SetFIFOByte(*dat);
dat++;
}
}
#endif
#if SI_GPTR_MTYPE_DATA != SI_GPTR_MTYPE_IDATA
/***************************************************************************//**
* @brief Reads data from the USB FIFO to a buffer in DRAM
* @param numBytes
* Number of bytes to read from the FIFO
* @param dat
* Pointer to DATA buffer to hold data read from the FIFO
* @param fifoNum
* USB FIFO to read
******************************************************************************/
static void USB_ReadFIFO_Data(uint8_t numBytes, SI_VARIABLE_SEGMENT_POINTER(dat, uint8_t, SI_SEG_DATA), uint8_t fifoNum)
{
while (--numBytes)
{
USB_GetFIFOByte(*dat);
dat++;
}
USB_GetLastFIFOByte(*dat, fifoNum);
}
/***************************************************************************//**
* @brief Writes data held in DRAM to the USB FIFO
* @details The FIFO to write must be set before calling the function with
* @ref USB_EnableWriteFIFO().
* @param numBytes
* Number of bytes to write to the FIFO
* @param dat
* Pointer to DATA buffer to hold data read from the FIFO
******************************************************************************/
static void USB_WriteFIFO_Data(uint8_t numBytes, SI_VARIABLE_SEGMENT_POINTER(dat, uint8_t, SI_SEG_DATA))
{
while (numBytes--)
{
USB_SetFIFOByte(*dat);
dat++;
}
}
#endif
/***************************************************************************//**
* @brief Writes data held in code space to the USB FIFO
* @details The FIFO to write must be set before calling the function with
* @ref USB_EnableWriteFIFO().
* @param numBytes
* Number of bytes to write to the FIFO
* @param dat
* Pointer to CODE buffer holding data to write to the FIFO
******************************************************************************/
static void USB_WriteFIFO_Code(uint8_t numBytes, SI_VARIABLE_SEGMENT_POINTER(dat, uint8_t, SI_SEG_CODE))
{
while (numBytes--)
{
USB_SetFIFOByte(*dat);
dat++;
}
}
#else
/***************************************************************************//**
* @brief Reads data from the USB FIFO to a buffer in generic memory space
* @param numBytes
* Number of bytes to read from the FIFO
* @param dat
* Pointer to generic buffer to hold data read from the FIFO
* @param fifoNum
* USB FIFO to read
******************************************************************************/
static void USB_ReadFIFO_Generic(uint8_t numBytes, uint8_t *dat, uint8_t fifoNum)
{
while (--numBytes)
{
USB_GetFIFOByte(*dat);
dat++;
}
USB_GetLastFIFOByte(*dat, fifoNum);
}
/***************************************************************************//**
* @brief Writes data held in generic memory space to the USB FIFO
* @details The FIFO to write must be set before calling the function with
* @ref USB_EnableWriteFIFO().
* @param numBytes
* Number of bytes to write to the FIFO
* @param dat
* Pointer to generic buffer holding data to write to the FIFO
******************************************************************************/
static void USB_WriteFIFO_Generic(uint8_t numBytes, uint8_t *dat)
{
while (numBytes--)
{
USB_SetFIFOByte(*dat);
dat++;
}
}
#endif // #ifdef SI_GPTR

View File

@ -1,533 +0,0 @@
/**************************************************************************//**
* Copyright (c) 2015 by Silicon Laboratories Inc. All rights reserved.
*
* http://developer.silabs.com/legal/version/v11/Silicon_Labs_Software_License_Agreement.txt
*****************************************************************************/
#include "si_toolchain.h"
#include "efm8_usb.h"
#include <stdint.h>
#include <endian.h>
// -----------------------------------------------------------------------------
// Global variables
extern SI_SEGMENT_VARIABLE(myUsbDevice, USBD_Device_TypeDef, MEM_MODEL_SEG);
extern SI_SEGMENT_VARIABLE(txZero[2], uint8_t, SI_SEG_CODE);
// -----------------------------------------------------------------------------
// Function prototypes
static void handleUsbEp0Int(void);
static void handleUsbResetInt(void);
static void handleUsbSuspendInt(void);
static void handleUsbResumeInt(void);
static void handleUsbEp0Tx(void);
static void handleUsbEp0Rx(void);
static void USB_ReadFIFOSetup(void);
#if (SLAB_USB_EP1IN_USED)
void handleUsbIn1Int(void);
#endif // SLAB_USB_EP1IN_USED
#if (SLAB_USB_EP2IN_USED)
void handleUsbIn2Int(void);
#endif // SLAB_USB_EP2IN_USED
#if (SLAB_USB_EP3IN_USED)
void handleUsbIn3Int(void);
#endif // SLAB_USB_EP3IN_USED
#if (SLAB_USB_EP1OUT_USED)
void handleUsbOut1Int(void);
#endif // SLAB_USB_EP1OUT_USED
#if (SLAB_USB_EP2OUT_USED)
void handleUsbOut2Int(void);
#endif // SLAB_USB_EP2OUT_USED
#if (SLAB_USB_EP3OUT_USED)
void handleUsbOut3Int(void);
#endif // SLAB_USB_EP3OUT_USED
void SendEp0Stall(void);
// -----------------------------------------------------------------------------
// Functions
/***************************************************************************//**
* @brief First-level handler for USB peripheral interrupt
* @details If @ref SLAB_USB_POLLED_MODE is 1, this becomes a regular
* function instead of an ISR and must be called by the application
* periodically.
******************************************************************************/
#if (SLAB_USB_POLLED_MODE == 0)
SI_INTERRUPT(usbIrqHandler, USB0_IRQn)
#else
void usbIrqHandler(void)
#endif
{
uint8_t statusCommon, statusIn, statusOut, indexSave;
#if SLAB_USB_HANDLER_CB
// Callback to user before processing
USBD_EnterHandler();
#endif
// Get the interrupt sources
statusCommon = USB_GetCommonInts();
statusIn = USB_GetInInts();
statusOut = USB_GetOutInts();
#if SLAB_USB_POLLED_MODE
if ((statusCommon == 0) && (statusIn == 0) && (statusOut == 0))
{
return;
}
#endif
// Save the current index
indexSave = USB_GetIndex();
// Check Common USB Interrupts
if (USB_IsSofIntActive(statusCommon))
{
#if SLAB_USB_SOF_CB
USBD_SofCb(USB_GetSofNumber());
#endif // SLAB_USB_SOF_CB
// Check for unhandled USB packets on EP0 and set the corresponding IN or
// OUT interrupt active flag if necessary.
if (((myUsbDevice.ep0.misc.bits.outPacketPending == true) && (myUsbDevice.ep0.state == D_EP_RECEIVING)) ||
((myUsbDevice.ep0.misc.bits.inPacketPending == true) && (myUsbDevice.ep0.state == D_EP_TRANSMITTING)))
{
USB_SetEp0IntActive(statusIn);
}
// Check for unhandled USB OUT packets and set the corresponding OUT
// interrupt active flag if necessary.
#if SLAB_USB_EP1OUT_USED
if ((myUsbDevice.ep1out.misc.bits.outPacketPending == true) && (myUsbDevice.ep1out.state == D_EP_RECEIVING))
{
USB_SetOut1IntActive(statusOut);
}
#endif
#if SLAB_USB_EP2OUT_USED
if ((myUsbDevice.ep2out.misc.bits.outPacketPending == true) && (myUsbDevice.ep2out.state == D_EP_RECEIVING))
{
USB_SetOut2IntActive(statusOut);
}
#endif
#if SLAB_USB_EP3OUT_USED
if ((myUsbDevice.ep3out.misc.bits.outPacketPending == true) && (myUsbDevice.ep3out.state == D_EP_RECEIVING))
{
USB_SetOut3IntActive(statusOut);
}
#endif
#if (SLAB_USB_EP3IN_USED && (SLAB_USB_EP3IN_TRANSFER_TYPE == USB_EPTYPE_ISOC))
if ((myUsbDevice.ep3in.misc.bits.inPacketPending == true) && (myUsbDevice.ep3in.state == D_EP_TRANSMITTING))
{
USB_SetIn3IntActive(statusIn);
}
#endif
}
if (USB_IsResetIntActive(statusCommon))
{
handleUsbResetInt();
// If VBUS is not present on detection of a USB reset, enter suspend mode.
#if (SLAB_USB_PWRSAVE_MODE & USB_PWRSAVE_MODE_ONVBUSOFF)
if (USB_IsVbusOn() == false)
{
USB_SetSuspendIntActive(statusCommon);
}
#endif
}
if (USB_IsResumeIntActive(statusCommon))
{
handleUsbResumeInt();
}
if (USB_IsSuspendIntActive(statusCommon))
{
handleUsbSuspendInt();
}
#if SLAB_USB_EP3IN_USED
if (USB_IsIn3IntActive(statusIn))
{
handleUsbIn3Int();
}
#endif // EP3IN_USED
#if SLAB_USB_EP3OUT_USED
if (USB_IsOut3IntActive(statusOut))
{
handleUsbOut3Int();
}
#endif // EP3OUT_USED
#if SLAB_USB_EP2IN_USED
if (USB_IsIn2IntActive(statusIn))
{
handleUsbIn2Int();
}
#endif // EP2IN_USED
#if SLAB_USB_EP1IN_USED
if (USB_IsIn1IntActive(statusIn))
{
handleUsbIn1Int();
}
#endif // EP1IN_USED
#if SLAB_USB_EP2OUT_USED
if (USB_IsOut2IntActive(statusOut))
{
handleUsbOut2Int();
}
#endif // EP2OUT_USED
#if SLAB_USB_EP1OUT_USED
if (USB_IsOut1IntActive(statusOut))
{
handleUsbOut1Int();
}
#endif // EP1OUT_USED
// Check USB Endpoint 0 Interrupt
if (USB_IsEp0IntActive(statusIn))
{
handleUsbEp0Int();
}
// Restore index
USB_SetIndex(indexSave);
#if SLAB_USB_HANDLER_CB
// Callback to user before exiting
USBD_ExitHandler();
#endif
}
/***************************************************************************//**
* @brief Handles Endpoint 0 transfer interrupt
******************************************************************************/
static void handleUsbEp0Int(void)
{
USB_SetIndex(0);
if (USB_Ep0SentStall() || USB_GetSetupEnd())
{
USB_Ep0ClearSentStall();
USB_ServicedSetupEnd();
myUsbDevice.ep0.state = D_EP_IDLE;
myUsbDevice.ep0.misc.c = 0;
}
if (USB_Ep0OutPacketReady())
{
if (myUsbDevice.ep0.misc.bits.waitForRead == true)
{
myUsbDevice.ep0.misc.bits.outPacketPending = true;
}
else if (myUsbDevice.ep0.state == D_EP_IDLE)
{
myUsbDevice.ep0String.c = USB_STRING_DESCRIPTOR_UTF16LE;
USB_ReadFIFOSetup();
// Vendor unique, Class or Standard setup commands override?
#if SLAB_USB_SETUP_CMD_CB
if (USBD_SetupCmdCb(&myUsbDevice.setup) == USB_STATUS_REQ_UNHANDLED)
{
#endif
if (myUsbDevice.setup.bmRequestType.Type == USB_SETUP_TYPE_STANDARD)
{
USBDCH9_SetupCmd();
}
else
{
SendEp0Stall();
}
#if SLAB_USB_SETUP_CMD_CB
}
else
{
// If in-packet but callback didn't setup a USBD_Read and we are expecting a data byte then
// we need to wait for the read to be setup and nack packets till USBD_Read is called.
if ((myUsbDevice.setup.bmRequestType.Direction == USB_SETUP_DIR_OUT)
&& (myUsbDevice.ep0.state != D_EP_RECEIVING)
&& (myUsbDevice.setup.wLength)
)
{
myUsbDevice.ep0.misc.bits.waitForRead = true;
}
}
#endif
}
else if (myUsbDevice.ep0.state == D_EP_RECEIVING)
{
handleUsbEp0Rx();
}
else
{
myUsbDevice.ep0.misc.bits.outPacketPending = true;
}
}
if ((myUsbDevice.ep0.state == D_EP_TRANSMITTING) && (USB_Ep0InPacketReady() == 0))
{
handleUsbEp0Tx();
}
}
/***************************************************************************//**
* @brief Reads and formats a setup packet
******************************************************************************/
static void USB_ReadFIFOSetup(void)
{
uint16_t MEM_MODEL_SEG *ptr = &myUsbDevice.setup;
USB_ReadFIFO(0, 8, (uint8_t *)ptr);
USB_Ep0ServicedOutPacketReady();
// Modify for Endian-ness of the compiler
ptr[1] = le16toh(ptr[1]);
ptr[2] = le16toh(ptr[2]);
ptr[3] = le16toh(ptr[3]);
}
/***************************************************************************//**
* @brief Handles USB port reset interrupt
* @details After receiving a USB reset, halt all endpoints except for
* Endpoint 0, set the device state, and configure USB hardware.
******************************************************************************/
static void handleUsbResetInt(void)
{
// Setup EP0 to receive SETUP packets
myUsbDevice.ep0.state = D_EP_IDLE;
// Halt all other endpoints
#if SLAB_USB_EP1IN_USED
myUsbDevice.ep1in.state = D_EP_HALT;
#endif
#if SLAB_USB_EP2IN_USED
myUsbDevice.ep2in.state = D_EP_HALT;
#endif
#if SLAB_USB_EP3IN_USED
myUsbDevice.ep3in.state = D_EP_HALT;
#endif
#if SLAB_USB_EP1OUT_USED
myUsbDevice.ep1out.state = D_EP_HALT;
#endif
#if SLAB_USB_EP2OUT_USED
myUsbDevice.ep2out.state = D_EP_HALT;
#endif
#if SLAB_USB_EP3OUT_USED
myUsbDevice.ep3out.state = D_EP_HALT;
#endif
// After a USB reset, some USB hardware configurations will be reset and must
// be reconfigured.
// Re-enable clock recovery
#if SLAB_USB_CLOCK_RECOVERY_ENABLED
#if SLAB_USB_FULL_SPEED
USB_EnableFullSpeedClockRecovery();
#else
USB_EnableLowSpeedClockRecovery();
#endif
#endif
// Re-enable USB interrupts
USB_EnableSuspendDetection();
USB_EnableDeviceInts();
// If VBUS is preset, put the device in the Default state.
// Otherwise, put it in the Attached state.
#if (!(SLAB_USB_PWRSAVE_MODE & USB_PWRSAVE_MODE_ONVBUSOFF))
if (USB_IsVbusOn())
{
USBD_SetUsbState(USBD_STATE_DEFAULT);
}
else
{
USBD_SetUsbState(USBD_STATE_ATTACHED);
}
#else
USBD_SetUsbState(USBD_STATE_DEFAULT);
#endif // (!(SLAB_USB_PWRSAVE_MODE & USB_PWRSAVE_MODE_ONVBUSOFF))
#if SLAB_USB_RESET_CB
// Make the USB Reset Callback
USBD_ResetCb();
#endif
}
/***************************************************************************//**
* @brief Handle USB port suspend interrupt
* @details After receiving a USB reset, set the device state and
* call @ref USBD_Suspend() if configured to do so in
* @ref SLAB_USB_PWRSAVE_MODE
******************************************************************************/
static void handleUsbSuspendInt(void)
{
if (myUsbDevice.state >= USBD_STATE_POWERED)
{
USBD_SetUsbState(USBD_STATE_SUSPENDED);
#if (SLAB_USB_PWRSAVE_MODE & USB_PWRSAVE_MODE_ONSUSPEND)
USBD_Suspend();
#endif
}
}
/***************************************************************************//**
* @brief Handles USB port resume interrupt
* @details Restore the device state to its previous value.
******************************************************************************/
static void handleUsbResumeInt(void)
{
USBD_SetUsbState(myUsbDevice.savedState);
}
/***************************************************************************//**
* @brief Handles transmit data phase on Endpoint 0
******************************************************************************/
static void handleUsbEp0Tx(void)
{
uint8_t count, count_snapshot, i;
bool callback = myUsbDevice.ep0.misc.bits.callback;
// The number of bytes to send in the next packet must be less than or equal
// to the maximum EP0 packet size.
count = (myUsbDevice.ep0.remaining >= USB_EP0_SIZE) ?
USB_EP0_SIZE : myUsbDevice.ep0.remaining;
// Save the packet size for future use.
count_snapshot = count;
// Strings can use the USB_STRING_DESCRIPTOR_UTF16LE_PACKED type to pack
// UTF16LE data without the zero's between each character.
// If the current string is of type USB_STRING_DESCRIPTOR_UTF16LE_PACKED,
// unpacket it by inserting a zero between each character in the string.
if (myUsbDevice.ep0String.encoding.type == USB_STRING_DESCRIPTOR_UTF16LE_PACKED)
{
// If ep0String.encoding.init is true, this is the beginning of the string.
// The first two bytes of the string are the bLength and bDescriptorType
// fields. These are no packed like the reset of the string, so write them
// to the FIFO and set ep0String.encoding.init to false.
if (myUsbDevice.ep0String.encoding.init == true)
{
USB_WriteFIFO(0, 2, myUsbDevice.ep0.buf, false);
myUsbDevice.ep0.buf += 2;
count -= 2;
myUsbDevice.ep0String.encoding.init = false;
}
// Insert a 0x00 between each character of the string.
for (i = 0; i < count / 2; i++)
{
USB_WriteFIFO(0, 1, myUsbDevice.ep0.buf, false);
myUsbDevice.ep0.buf++;
USB_WriteFIFO(0, 1, &txZero, false);
}
}
// For any data other than USB_STRING_DESCRIPTOR_UTF16LE_PACKED, just send the
// data normally.
else
{
USB_WriteFIFO(0, count, myUsbDevice.ep0.buf, false);
myUsbDevice.ep0.buf += count;
}
myUsbDevice.ep0.misc.bits.inPacketPending = false;
myUsbDevice.ep0.remaining -= count_snapshot;
// If the last packet of the transfer is exactly the maximum EP0 packet size,
// we will have to send a ZLP (zero-length packet) after the last data packet
// to signal to the host that the transfer is complete.
// Check for the ZLP packet case here.
if ((myUsbDevice.ep0.remaining == 0) && (count_snapshot != USB_EP0_SIZE))
{
USB_Ep0SetLastInPacketReady();
myUsbDevice.ep0.state = D_EP_IDLE;
myUsbDevice.ep0String.c = USB_STRING_DESCRIPTOR_UTF16LE;
myUsbDevice.ep0.misc.c = 0;
}
else
{
// Do not call USB_Ep0SetLastInPacketReady() because we still need to send
// the ZLP.
USB_Ep0SetInPacketReady();
}
// Make callback if requested
if (callback == true)
{
USBD_XferCompleteCb(EP0, USB_STATUS_OK, count_snapshot, myUsbDevice.ep0.remaining);
}
}
/***************************************************************************//**
* @brief Handles receive data phase on Endpoint 0
******************************************************************************/
void handleUsbEp0Rx(void)
{
uint8_t count;
USB_Status_TypeDef status;
bool callback = myUsbDevice.ep0.misc.bits.callback;
// Get the number of bytes received
count = USB_Ep0GetCount();
// If the call to USBD_Read() did not give a large enough buffer to hold this
// data, set the outPacketPending flag and signal an RX overrun.
if (myUsbDevice.ep0.remaining < count)
{
myUsbDevice.ep0.state = D_EP_IDLE;
myUsbDevice.ep0.misc.bits.outPacketPending = true;
status = USB_STATUS_EP_RX_BUFFER_OVERRUN;
}
else
{
USB_ReadFIFO(0, count, myUsbDevice.ep0.buf);
myUsbDevice.ep0.buf += count;
myUsbDevice.ep0.remaining -= count;
status = USB_STATUS_OK;
// If the last packet of the transfer is exactly the maximum EP0 packet
// size, we will must wait to receive a ZLP (zero-length packet) after the
// last data packet. This signals that the host has completed the transfer.
// Check for the ZLP packet case here.
if ((myUsbDevice.ep0.remaining == 0) && (count != USB_EP0_SIZE))
{
USB_Ep0SetLastOutPacketReady();
myUsbDevice.ep0.state = D_EP_IDLE;
myUsbDevice.ep0.misc.bits.callback = false;
}
else
{
// Do not call USB_Ep0SetLastOutPacketReady() until we get the ZLP.
USB_Ep0ServicedOutPacketReady();
}
}
// Make callback if requested
if (callback == true)
{
USBD_XferCompleteCb(EP0, status, count, myUsbDevice.ep0.remaining);
}
}
/***************************************************************************//**
* @brief Send a procedural stall on Endpoint 0
******************************************************************************/
void SendEp0Stall(void)
{
USB_SetIndex(0);
myUsbDevice.ep0.state = D_EP_STALL;
USB_Ep0SendStall();
}
// This function is called from USBD_Init(). It forces the user project to pull
// this module from the library so that the declared ISR can be seen and
// included. If this is not done then this entire module by never be included
// and the ISR will not be present.
void forceModuleLoad_usbint(void){}

File diff suppressed because it is too large Load Diff

View File

@ -1,232 +0,0 @@
/**************************************************************************//**
* Copyright (c) 2015 by Silicon Laboratories Inc. All rights reserved.
*
* http://developer.silabs.com/legal/version/v11/Silicon_Labs_Software_License_Agreement.txt
*****************************************************************************/
#include "usb_0.h"
#include <stdbool.h>
#include <stdint.h>
/** @addtogroup usb_0_runtime USB0 Runtime API */
// -----------------------------------------------------------------------------
// Functions
// -------------------------------
// Utility Functions
/**************************************************************************//**
* @brief Reads a 16-bit indirect USB register value
* @param regAddr
* Address of high byte of 16-bit USB indirect register to read
* @return 16-bit register value
*****************************************************************************/
static uint16_t USB_GetShortRegister(uint8_t regAddr)
{
uint16_t retVal;
USB_READ_BYTE(regAddr);
retVal = (USB0DAT << 8);
USB_READ_BYTE((regAddr - 1));
retVal |= USB0DAT;
return retVal;
}
// -------------------------------
// USB0 Peripheral Driver Functions
void USB_SetIndex(uint8_t epsel)
{
USB_WRITE_BYTE(INDEX, epsel);
}
uint8_t USB_GetCommonInts(void)
{
USB_READ_BYTE(CMINT);
return USB0DAT;
}
uint8_t USB_GetInInts(void)
{
USB_READ_BYTE(IN1INT);
return USB0DAT;
}
uint8_t USB_GetOutInts(void)
{
USB_READ_BYTE(OUT1INT);
return USB0DAT;
}
uint8_t USB_GetIndex(void)
{
USB_READ_BYTE(INDEX);
return USB0DAT;
}
bool USB_IsSuspended(void)
{
USB_READ_BYTE(POWER);
return USB0DAT & POWER_SUSMD__SUSPENDED;
}
bool USB_GetSetupEnd(void)
{
USB_READ_BYTE(E0CSR);
return USB0DAT & E0CSR_SUEND__SET;
}
bool USB_Ep0SentStall(void)
{
USB_READ_BYTE(E0CSR);
return USB0DAT & E0CSR_STSTL__SET;
}
bool USB_Ep0OutPacketReady(void)
{
USB_READ_BYTE(E0CSR);
return USB0DAT & E0CSR_OPRDY__SET;
}
bool USB_Ep0InPacketReady(void)
{
USB_READ_BYTE(E0CSR);
return USB0DAT & E0CSR_INPRDY__SET;
}
uint8_t USB_Ep0GetCount(void)
{
USB_READ_BYTE(E0CNT);
return USB0DAT;
}
bool USB_EpnInGetSentStall(void)
{
USB_READ_BYTE(EINCSRL);
return (bool)(USB0DAT & EINCSRL_STSTL__SET);
}
void USB_AbortInEp(uint8_t fifoNum)
{
USB_SetIndex(fifoNum);
USB_EpnInFlush();
USB_EpnInFlush();
}
bool USB_EpnOutGetSentStall(void)
{
USB_READ_BYTE(EOUTCSRL);
return (bool)(USB0DAT & EOUTCSRL_STSTL__SET);
}
bool USB_EpnGetOutPacketReady(void)
{
USB_READ_BYTE(EOUTCSRL);
return (bool)(USB0DAT & EOUTCSRL_OPRDY__SET);
}
uint16_t USB_EpOutGetCount(void)
{
return USB_GetShortRegister(EOUTCNTH);
}
void USB_AbortOutEp(uint8_t fifoNum)
{
USB_SetIndex(fifoNum);
USB_EpnOutFlush();
USB_EpnOutFlush();
}
void USB_ActivateEp(uint8_t ep,
uint16_t packetSize,
bool inDir,
bool splitMode,
bool isoMode)
{
uint8_t CSRH_mask = 0;
uint16_t fifoSize;
USB_SetIndex(ep);
// Determine the available fifoSize for a given endpoint based on the
// splitMode setting
fifoSize = (splitMode == true) ? (16 << ep) : (32 << ep);
if (packetSize <= fifoSize)
{
CSRH_mask |= EINCSRH_DBIEN__ENABLED;
}
if (isoMode == true)
{
CSRH_mask |= EINCSRH_ISO__ENABLED;
}
if (inDir == true)
{
CSRH_mask |= EINCSRH_DIRSEL__IN;
if (splitMode == true)
{
CSRH_mask |= EINCSRH_SPLIT__ENABLED;
}
USB_WRITE_BYTE(EINCSRL, EINCSRL_CLRDT__BMASK);
USB_WRITE_BYTE(EINCSRH, CSRH_mask);
}
else // OUT
{
USB_WRITE_BYTE(EOUTCSRL, EOUTCSRL_CLRDT__BMASK);
USB_WRITE_BYTE(EOUTCSRH, CSRH_mask);
if (splitMode == false)
{
USB_WRITE_BYTE(EINCSRH, 0);
}
}
}
uint16_t USB_GetSofNumber(void)
{
return USB_GetShortRegister(FRAMEH);
}
bool USB_GetIntsEnabled(void)
{
SFRPAGE = PG2_PAGE;
return (bool)(EIE2 & EIE2_EUSB0__ENABLED);
}
bool USB_IsPrefetchEnabled(void)
{
SFRPAGE = PG2_PAGE;
return (bool)(PFE0CN & PFE0CN_PFEN__ENABLED);
}
bool USB_IsRegulatorEnabled(void)
{
SFRPAGE = PG3_PAGE;
return !(REG1CN & REG1CN_REG1ENB__DISABLED);
}
void USB_SuspendOscillator(void)
{
uint8_t clkSelSave = CLKSEL & 0x7F;
CLKSEL = (CLKSEL_CLKDIV__SYSCLK_DIV_8 | CLKSEL_CLKSL__HFOSC0);
SFRPAGE = LEGACY_PAGE;
PCON1 |= PCON1_SUSPEND__SUSPEND;
CLKSEL = clkSelSave;
// If the target frequency is over 24MHz, our write to CLKSEL will be ignored.
// If this is the case we need to do two writes: one to 24 MHz followed by the
// actual value.
if ((CLKSEL & 0x7F) != clkSelSave)
{
CLKSEL = (CLKSEL_CLKDIV__SYSCLK_DIV_1 | CLKSEL_CLKSL__HFOSC0);
CLKSEL = clkSelSave;
}
}
/** @} (end addtogroup usb_0_runtime USB0 Runtime API) */

View File

@ -1,580 +0,0 @@
//=========================================================
// src/InitDevice.c: generated by Hardware Configurator
//
// This file will be regenerated when saving a document.
// leave the sections inside the "$[...]" comment tags alone
// or they will be overwritten!
//=========================================================
// USER INCLUDES
#include <SI_EFM8UB1_Register_Enums.h>
#include "InitDevice.h"
// USER PROTOTYPES
// USER FUNCTIONS
// $[Library Includes]
#include "efm8_usb.h"
#include "descriptors.h"
#include "usb_0.h"
// [Library Includes]$
//==============================================================================
// enter_DefaultMode_from_RESET
//==============================================================================
extern void enter_DefaultMode_from_RESET(void) {
// $[Config Calls]
// Save the SFRPAGE
uint8_t SFRPAGE_save = SFRPAGE;
WDT_0_enter_DefaultMode_from_RESET();
PORTS_0_enter_DefaultMode_from_RESET();
PORTS_1_enter_DefaultMode_from_RESET();
PBCFG_0_enter_DefaultMode_from_RESET();
LFOSC_0_enter_DefaultMode_from_RESET();
CIP51_0_enter_DefaultMode_from_RESET();
CLOCK_0_enter_DefaultMode_from_RESET();
TIMER01_0_enter_DefaultMode_from_RESET();
TIMER16_2_enter_DefaultMode_from_RESET();
TIMER16_3_enter_DefaultMode_from_RESET();
TIMER_SETUP_0_enter_DefaultMode_from_RESET();
SPI_0_enter_DefaultMode_from_RESET();
UART_0_enter_DefaultMode_from_RESET();
INTERRUPT_0_enter_DefaultMode_from_RESET();
USBLIB_0_enter_DefaultMode_from_RESET();
// Restore the SFRPAGE
SFRPAGE = SFRPAGE_save;
// [Config Calls]$
}
extern void INTERRUPT_0_enter_DefaultMode_from_RESET(void) {
// $[EIE1 - Extended Interrupt Enable 1]
// [EIE1 - Extended Interrupt Enable 1]$
// $[EIE2 - Extended Interrupt Enable 2]
// [EIE2 - Extended Interrupt Enable 2]$
// $[EIP1H - Extended Interrupt Priority 1 High]
// [EIP1H - Extended Interrupt Priority 1 High]$
// $[EIP1 - Extended Interrupt Priority 1 Low]
// [EIP1 - Extended Interrupt Priority 1 Low]$
// $[EIP2 - Extended Interrupt Priority 2]
// [EIP2 - Extended Interrupt Priority 2]$
// $[EIP2H - Extended Interrupt Priority 2 High]
// [EIP2H - Extended Interrupt Priority 2 High]$
// $[IE - Interrupt Enable]
/***********************************************************************
- Enable each interrupt according to its individual mask setting
- Disable external interrupt 0
- Disable external interrupt 1
- Disable all SPI0 interrupts
- Disable all Timer 0 interrupt
- Disable all Timer 1 interrupt
- Disable Timer 2 interrupt
- Disable UART0 interrupt
***********************************************************************/
IE = IE_EA__ENABLED | IE_EX0__DISABLED | IE_EX1__DISABLED
| IE_ESPI0__DISABLED | IE_ET0__DISABLED | IE_ET1__DISABLED
| IE_ET2__DISABLED | IE_ES0__DISABLED;
// [IE - Interrupt Enable]$
// $[IP - Interrupt Priority]
// [IP - Interrupt Priority]$
// $[IPH - Interrupt Priority High]
// [IPH - Interrupt Priority High]$
}
extern void USBLIB_0_enter_DefaultMode_from_RESET(void) {
// $[USBD Init]
USBD_Init (&initstruct);
// [USBD Init]$
}
extern void CLOCK_0_enter_DefaultMode_from_RESET(void) {
// $[HFOSC1 Setup]
// Ensure SYSCLK is > 24 MHz before switching to HFOSC1
SFRPAGE = 0x00;
CLKSEL = CLKSEL_CLKSL__HFOSC0 | CLKSEL_CLKDIV__SYSCLK_DIV_1;
while ((CLKSEL & CLKSEL_DIVRDY__BMASK) == CLKSEL_DIVRDY__NOT_READY)
;
// [HFOSC1 Setup]$
// $[CLKSEL - Clock Select]
/***********************************************************************
- Clock derived from the Internal High Frequency Oscillator 1
- SYSCLK is equal to selected clock source divided by 1
***********************************************************************/
CLKSEL = CLKSEL_CLKSL__HFOSC1 | CLKSEL_CLKDIV__SYSCLK_DIV_1;
while ((CLKSEL & CLKSEL_DIVRDY__BMASK) == CLKSEL_DIVRDY__NOT_READY)
;
// [CLKSEL - Clock Select]$
}
extern void WDT_0_enter_DefaultMode_from_RESET(void) {
// $[WDTCN - Watchdog Timer Control]
SFRPAGE = 0x00;
//Disable Watchdog with key sequence
WDTCN = 0xDE; //First key
WDTCN = 0xAD; //Second key
// [WDTCN - Watchdog Timer Control]$
}
extern void CIP51_0_enter_DefaultMode_from_RESET(void) {
// $[PFE0CN - Prefetch Engine Control]
/***********************************************************************
- Enable the prefetch engine
- SYSCLK < 50 MHz
***********************************************************************/
SFRPAGE = 0x10;
PFE0CN = PFE0CN_PFEN__ENABLED | PFE0CN_FLRT__SYSCLK_BELOW_50_MHZ;
// [PFE0CN - Prefetch Engine Control]$
}
extern void PBCFG_0_enter_DefaultMode_from_RESET(void) {
// $[XBR2 - Port I/O Crossbar 2]
/***********************************************************************
- Weak Pullups enabled
- Crossbar enabled
- UART1 I/O unavailable at Port pin
- UART1 RTS1 unavailable at Port pin
- UART1 CTS1 unavailable at Port pin
***********************************************************************/
XBR2 = XBR2_WEAKPUD__PULL_UPS_ENABLED | XBR2_XBARE__ENABLED
| XBR2_URT1E__DISABLED | XBR2_URT1RTSE__DISABLED
| XBR2_URT1CTSE__DISABLED;
// [XBR2 - Port I/O Crossbar 2]$
// $[PRTDRV - Port Drive Strength]
// [PRTDRV - Port Drive Strength]$
// $[XBR0 - Port I/O Crossbar 0]
/***********************************************************************
- UART0 TX0, RX0 routed to Port pins P0.4 and P0.5
- SPI I/O routed to Port pins
- SMBus 0 I/O unavailable at Port pins
- CP0 unavailable at Port pin
- Asynchronous CP0 unavailable at Port pin
- CP1 unavailable at Port pin
- Asynchronous CP1 unavailable at Port pin
- SYSCLK unavailable at Port pin
***********************************************************************/
XBR0 = XBR0_URT0E__ENABLED | XBR0_SPI0E__ENABLED | XBR0_SMB0E__DISABLED
| XBR0_CP0E__DISABLED | XBR0_CP0AE__DISABLED | XBR0_CP1E__DISABLED
| XBR0_CP1AE__DISABLED | XBR0_SYSCKE__DISABLED;
// [XBR0 - Port I/O Crossbar 0]$
// $[XBR1 - Port I/O Crossbar 1]
// [XBR1 - Port I/O Crossbar 1]$
}
extern void TIMER_SETUP_0_enter_DefaultMode_from_RESET(void) {
// $[CKCON0 - Clock Control 0]
/***********************************************************************
- System clock divided by 4
- Counter/Timer 0 uses the clock defined by the prescale field, SCA
- Timer 2 high byte uses the clock defined by T2XCLK in TMR2CN0
- Timer 2 low byte uses the clock defined by T2XCLK in TMR2CN0
- Timer 3 high byte uses the clock defined by T3XCLK in TMR3CN0
- Timer 3 low byte uses the clock defined by T3XCLK in TMR3CN0
- Timer 1 uses the system clock
***********************************************************************/
CKCON0 = CKCON0_SCA__SYSCLK_DIV_4 | CKCON0_T0M__PRESCALE
| CKCON0_T2MH__EXTERNAL_CLOCK | CKCON0_T2ML__EXTERNAL_CLOCK
| CKCON0_T3MH__EXTERNAL_CLOCK | CKCON0_T3ML__EXTERNAL_CLOCK
| CKCON0_T1M__SYSCLK;
// [CKCON0 - Clock Control 0]$
// $[CKCON1 - Clock Control 1]
// [CKCON1 - Clock Control 1]$
// $[TMOD - Timer 0/1 Mode]
/***********************************************************************
- Mode 0, 13-bit Counter/Timer
- Mode 2, 8-bit Counter/Timer with Auto-Reload
- Timer Mode
- Timer 0 enabled when TR0 = 1 irrespective of INT0 logic level
- Timer Mode
- Timer 1 enabled when TR1 = 1 irrespective of INT1 logic level
***********************************************************************/
TMOD = TMOD_T0M__MODE0 | TMOD_T1M__MODE2 | TMOD_CT0__TIMER
| TMOD_GATE0__DISABLED | TMOD_CT1__TIMER | TMOD_GATE1__DISABLED;
// [TMOD - Timer 0/1 Mode]$
// $[TCON - Timer 0/1 Control]
/***********************************************************************
- Start Timer 1 running
***********************************************************************/
TCON |= TCON_TR1__RUN;
// [TCON - Timer 0/1 Control]$
}
extern void UARTE_1_enter_DefaultMode_from_RESET(void) {
// $[SBCON1 - UART1 Baud Rate Generator Control]
/***********************************************************************
- Enable the baud rate generator
- Prescaler = 8
***********************************************************************/
SFRPAGE = 0x20;
SBCON1 = SBCON1_BREN__ENABLED | SBCON1_BPS__DIV_BY_8;
// [SBCON1 - UART1 Baud Rate Generator Control]$
// $[SMOD1 - UART1 Mode]
// [SMOD1 - UART1 Mode]$
// $[UART1FCN0 - UART1 FIFO Control 0]
// [UART1FCN0 - UART1 FIFO Control 0]$
// $[SBRLH1 - UART1 Baud Rate Generator High Byte]
/***********************************************************************
- UART1 Baud Rate Reload High = 0xFF
***********************************************************************/
SBRLH1 = (0xFF << SBRLH1_BRH__SHIFT);
// [SBRLH1 - UART1 Baud Rate Generator High Byte]$
// $[SBRLL1 - UART1 Baud Rate Generator Low Byte]
/***********************************************************************
- UART1 Baud Rate Reload Low = 0xE6
***********************************************************************/
SBRLL1 = (0xE6 << SBRLL1_BRL__SHIFT);
// [SBRLL1 - UART1 Baud Rate Generator Low Byte]$
// $[UART1LIN - UART1 LIN Configuration]
// [UART1LIN - UART1 LIN Configuration]$
// $[SCON1 - UART1 Serial Port Control]
/***********************************************************************
- UART1 reception enabled
***********************************************************************/
SCON1 |= SCON1_REN__RECEIVE_ENABLED;
// [SCON1 - UART1 Serial Port Control]$
// $[UART1FCN1 - UART1 FIFO Control 1]
// [UART1FCN1 - UART1 FIFO Control 1]$
}
extern void TIMER16_2_enter_DefaultMode_from_RESET(void) {
// $[Timer Initialization]
// Save Timer Configuration
uint8_t TMR2CN0_TR2_save;
TMR2CN0_TR2_save = TMR2CN0 & TMR2CN0_TR2__BMASK;
// Stop Timer
TMR2CN0 &= ~(TMR2CN0_TR2__BMASK);
// [Timer Initialization]$
// $[TMR2CN1 - Timer 2 Control 1]
// [TMR2CN1 - Timer 2 Control 1]$
// $[TMR2CN0 - Timer 2 Control]
// [TMR2CN0 - Timer 2 Control]$
// $[TMR2H - Timer 2 High Byte]
// [TMR2H - Timer 2 High Byte]$
// $[TMR2L - Timer 2 Low Byte]
// [TMR2L - Timer 2 Low Byte]$
// $[TMR2RLH - Timer 2 Reload High Byte]
/***********************************************************************
- Timer 2 Reload High Byte = 0x63
***********************************************************************/
TMR2RLH = (0x63 << TMR2RLH_TMR2RLH__SHIFT);
// [TMR2RLH - Timer 2 Reload High Byte]$
// $[TMR2RLL - Timer 2 Reload Low Byte]
/***********************************************************************
- Timer 2 Reload Low Byte = 0xC0
***********************************************************************/
TMR2RLL = (0xC0 << TMR2RLL_TMR2RLL__SHIFT);
// [TMR2RLL - Timer 2 Reload Low Byte]$
// $[TMR2CN0]
// [TMR2CN0]$
// $[Timer Restoration]
// Restore Timer Configuration
TMR2CN0 |= TMR2CN0_TR2_save;
// [Timer Restoration]$
}
extern void TIMER16_3_enter_DefaultMode_from_RESET(void) {
// $[Timer Initialization]
// Save Timer Configuration
uint8_t TMR3CN0_TR3_save;
TMR3CN0_TR3_save = TMR3CN0 & TMR3CN0_TR3__BMASK;
// Stop Timer
TMR3CN0 &= ~(TMR3CN0_TR3__BMASK);
// [Timer Initialization]$
// $[TMR3CN1 - Timer 3 Control 1]
// [TMR3CN1 - Timer 3 Control 1]$
// $[TMR3CN0 - Timer 3 Control]
/***********************************************************************
- Timer 3 clock is the low-frequency oscillator divided by 8
***********************************************************************/
TMR3CN0 |= TMR3CN0_T3XCLK__LFOSC_DIV_8;
// [TMR3CN0 - Timer 3 Control]$
// $[TMR3H - Timer 3 High Byte]
// [TMR3H - Timer 3 High Byte]$
// $[TMR3L - Timer 3 Low Byte]
// [TMR3L - Timer 3 Low Byte]$
// $[TMR3RLH - Timer 3 Reload High Byte]
// [TMR3RLH - Timer 3 Reload High Byte]$
// $[TMR3RLL - Timer 3 Reload Low Byte]
// [TMR3RLL - Timer 3 Reload Low Byte]$
// $[TMR3CN0]
/***********************************************************************
- Start Timer 3 running
***********************************************************************/
TMR3CN0 |= TMR3CN0_TR3__RUN;
// [TMR3CN0]$
// $[Timer Restoration]
// Restore Timer Configuration
TMR3CN0 |= TMR3CN0_TR3_save;
// [Timer Restoration]$
}
extern void PORTS_0_enter_DefaultMode_from_RESET(void) {
// $[P0 - Port 0 Pin Latch]
// [P0 - Port 0 Pin Latch]$
// $[P0MDOUT - Port 0 Output Mode]
/***********************************************************************
- P0.0 output is open-drain
- P0.1 output is open-drain
- P0.2 output is open-drain
- P0.3 output is open-drain
- P0.4 output is push-pull
- P0.5 output is open-drain
- P0.6 output is open-drain
- P0.7 output is push-pull
***********************************************************************/
P0MDOUT = P0MDOUT_B0__OPEN_DRAIN | P0MDOUT_B1__OPEN_DRAIN
| P0MDOUT_B2__OPEN_DRAIN | P0MDOUT_B3__OPEN_DRAIN
| P0MDOUT_B4__PUSH_PULL | P0MDOUT_B5__OPEN_DRAIN
| P0MDOUT_B6__OPEN_DRAIN | P0MDOUT_B7__PUSH_PULL;
// [P0MDOUT - Port 0 Output Mode]$
// $[P0MDIN - Port 0 Input Mode]
// [P0MDIN - Port 0 Input Mode]$
// $[P0SKIP - Port 0 Skip]
/***********************************************************************
- P0.0 pin is skipped by the crossbar
- P0.1 pin is skipped by the crossbar
- P0.2 pin is skipped by the crossbar
- P0.3 pin is skipped by the crossbar
- P0.4 pin is not skipped by the crossbar
- P0.5 pin is not skipped by the crossbar
- P0.6 pin is not skipped by the crossbar
- P0.7 pin is not skipped by the crossbar
***********************************************************************/
P0SKIP = P0SKIP_B0__SKIPPED | P0SKIP_B1__SKIPPED | P0SKIP_B2__SKIPPED
| P0SKIP_B3__SKIPPED | P0SKIP_B4__NOT_SKIPPED
| P0SKIP_B5__NOT_SKIPPED | P0SKIP_B6__NOT_SKIPPED
| P0SKIP_B7__NOT_SKIPPED;
// [P0SKIP - Port 0 Skip]$
// $[P0MASK - Port 0 Mask]
// [P0MASK - Port 0 Mask]$
// $[P0MAT - Port 0 Match]
// [P0MAT - Port 0 Match]$
}
extern void PORTS_1_enter_DefaultMode_from_RESET(void) {
// $[P1 - Port 1 Pin Latch]
/***********************************************************************
- P1.0 is high. Set P1.0 to drive or float high
- P1.1 is high. Set P1.1 to drive or float high
- P1.2 is low. Set P1.2 to drive low
- P1.3 is high. Set P1.3 to drive or float high
- P1.4 is high. Set P1.4 to drive or float high
- P1.5 is high. Set P1.5 to drive or float high
- P1.6 is high. Set P1.6 to drive or float high
- P1.7 is high. Set P1.7 to drive or float high
***********************************************************************/
P1 = P1_B0__HIGH | P1_B1__HIGH | P1_B2__LOW | P1_B3__HIGH | P1_B4__HIGH
| P1_B5__HIGH | P1_B6__HIGH | P1_B7__HIGH;
// [P1 - Port 1 Pin Latch]$
// $[P1MDOUT - Port 1 Output Mode]
/***********************************************************************
- P1.0 output is open-drain
- P1.1 output is push-pull
- P1.2 output is open-drain
- P1.3 output is open-drain
- P1.4 output is push-pull
- P1.5 output is push-pull
- P1.6 output is push-pull
- P1.7 output is open-drain
***********************************************************************/
P1MDOUT = P1MDOUT_B0__OPEN_DRAIN | P1MDOUT_B1__PUSH_PULL
| P1MDOUT_B2__OPEN_DRAIN | P1MDOUT_B3__OPEN_DRAIN
| P1MDOUT_B4__PUSH_PULL | P1MDOUT_B5__PUSH_PULL
| P1MDOUT_B6__PUSH_PULL | P1MDOUT_B7__OPEN_DRAIN;
// [P1MDOUT - Port 1 Output Mode]$
// $[P1MDIN - Port 1 Input Mode]
// [P1MDIN - Port 1 Input Mode]$
// $[P1SKIP - Port 1 Skip]
// [P1SKIP - Port 1 Skip]$
// $[P1MASK - Port 1 Mask]
// [P1MASK - Port 1 Mask]$
// $[P1MAT - Port 1 Match]
// [P1MAT - Port 1 Match]$
}
extern void PORTS_2_enter_DefaultMode_from_RESET(void) {
// $[P2 - Port 2 Pin Latch]
/***********************************************************************
- P2.0 is low. Set P2.0 to drive low
- P2.1 is high. Set P2.1 to drive or float high
- P2.2 is high. Set P2.2 to drive or float high
- P2.3 is high. Set P2.3 to drive or float high
***********************************************************************/
P2 = P2_B0__LOW | P2_B1__HIGH | P2_B2__HIGH | P2_B3__HIGH;
// [P2 - Port 2 Pin Latch]$
// $[P2MDOUT - Port 2 Output Mode]
/***********************************************************************
- P2.0 output is push-pull
- P2.1 output is open-drain
- P2.2 output is open-drain
- P2.3 output is open-drain
***********************************************************************/
P2MDOUT = P2MDOUT_B0__PUSH_PULL | P2MDOUT_B1__OPEN_DRAIN
| P2MDOUT_B2__OPEN_DRAIN | P2MDOUT_B3__OPEN_DRAIN;
// [P2MDOUT - Port 2 Output Mode]$
// $[P2MDIN - Port 2 Input Mode]
// [P2MDIN - Port 2 Input Mode]$
// $[P2SKIP - Port 2 Skip]
// [P2SKIP - Port 2 Skip]$
// $[P2MASK - Port 2 Mask]
// [P2MASK - Port 2 Mask]$
// $[P2MAT - Port 2 Match]
// [P2MAT - Port 2 Match]$
}
extern void TIMER01_0_enter_DefaultMode_from_RESET(void) {
// $[Timer Initialization]
//Save Timer Configuration
uint8_t TCON_save;
TCON_save = TCON;
//Stop Timers
TCON &= ~TCON_TR0__BMASK & ~TCON_TR1__BMASK;
// [Timer Initialization]$
// $[TH0 - Timer 0 High Byte]
// [TH0 - Timer 0 High Byte]$
// $[TL0 - Timer 0 Low Byte]
// [TL0 - Timer 0 Low Byte]$
// $[TH1 - Timer 1 High Byte]
/***********************************************************************
- Timer 1 High Byte = 0x30
***********************************************************************/
TH1 = (0x30 << TH1_TH1__SHIFT);
// [TH1 - Timer 1 High Byte]$
// $[TL1 - Timer 1 Low Byte]
// [TL1 - Timer 1 Low Byte]$
// $[Timer Restoration]
//Restore Timer Configuration
TCON |= (TCON_save & TCON_TR0__BMASK) | (TCON_save & TCON_TR1__BMASK);
// [Timer Restoration]$
}
extern void UART_0_enter_DefaultMode_from_RESET(void) {
// $[SCON0 - UART0 Serial Port Control]
/***********************************************************************
- UART0 reception enabled
***********************************************************************/
SCON0 |= SCON0_REN__RECEIVE_ENABLED;
// [SCON0 - UART0 Serial Port Control]$
}
extern void SPI_0_enter_DefaultMode_from_RESET(void) {
// $[SPI0CKR - SPI0 Clock Rate]
/***********************************************************************
- SPI0 Clock Rate = 0x0B
***********************************************************************/
SPI0CKR = (0x0B << SPI0CKR_SPI0CKR__SHIFT);
// [SPI0CKR - SPI0 Clock Rate]$
// $[SPI0FCN0 - SPI0 FIFO Control 0]
// [SPI0FCN0 - SPI0 FIFO Control 0]$
// $[SPI0FCN1 - SPI0 FIFO Control 1]
// [SPI0FCN1 - SPI0 FIFO Control 1]$
// $[SPI0CFG - SPI0 Configuration]
// [SPI0CFG - SPI0 Configuration]$
// $[SPI0CN0 - SPI0 Control]
/***********************************************************************
- Enable the SPI module
- 3-Wire Slave or 3-Wire Master Mode
***********************************************************************/
SPI0CN0 &= ~SPI0CN0_NSSMD__FMASK;
SPI0CN0 |= SPI0CN0_SPIEN__ENABLED;
// [SPI0CN0 - SPI0 Control]$
}
extern void LFOSC_0_enter_DefaultMode_from_RESET(void) {
// $[LFO0CN - Low Frequency Oscillator Control]
/***********************************************************************
- Internal L-F Oscillator Enabled
- Divide by 8 selected
***********************************************************************/
LFO0CN &= ~LFO0CN_OSCLD__FMASK;
LFO0CN |= LFO0CN_OSCLEN__ENABLED;
// [LFO0CN - Low Frequency Oscillator Control]$
// $[Wait for LFOSC Ready]
while ((LFO0CN & LFO0CN_OSCLRDY__BMASK) != LFO0CN_OSCLRDY__SET)
;
// [Wait for LFOSC Ready]$
}

View File

@ -1,203 +0,0 @@
$NOMOD51
;------------------------------------------------------------------------------
; This file is part of the C51 Compiler package
; Copyright (c) 1988-2005 Keil Elektronik GmbH and Keil Software, Inc.
; Version 8.01
;
; *** <<< Use Configuration Wizard in Context Menu >>> ***
;------------------------------------------------------------------------------
; STARTUP.A51: This code is executed after processor reset.
;
; To translate this file use A51 with the following invocation:
;
; A51 STARTUP.A51
;
; To link the modified STARTUP.OBJ file to your application use the following
; Lx51 invocation:
;
; Lx51 your object file list, STARTUP.OBJ controls
;
;------------------------------------------------------------------------------
;
; User-defined <h> Power-On Initialization of Memory
;
; With the following EQU statements the initialization of memory
; at processor reset can be defined:
;
; <o> IDATALEN: IDATA memory size <0x0-0x100>
; <i> Note: The absolute start-address of IDATA memory is always 0
; <i> The IDATA space overlaps physically the DATA and BIT areas.
IDATALEN EQU 80H
;
; <o> XDATASTART: XDATA memory start address <0x0-0xFFFF>
; <i> The absolute start address of XDATA memory
XDATASTART EQU 0
;
; <o> XDATALEN: XDATA memory size <0x0-0xFFFF>
; <i> The length of XDATA memory in bytes.
XDATALEN EQU 0
;
; <o> PDATASTART: PDATA memory start address <0x0-0xFFFF>
; <i> The absolute start address of PDATA memory
PDATASTART EQU 0H
;
; <o> PDATALEN: PDATA memory size <0x0-0xFF>
; <i> The length of PDATA memory in bytes.
PDATALEN EQU 0H
;
;</h>
;------------------------------------------------------------------------------
;
;<h> Reentrant Stack Initialization
;
; The following EQU statements define the stack pointer for reentrant
; functions and initialized it:
;
; <h> Stack Space for reentrant functions in the SMALL model.
; <q> IBPSTACK: Enable SMALL model reentrant stack
; <i> Stack space for reentrant functions in the SMALL model.
IBPSTACK EQU 0 ; set to 1 if small reentrant is used.
; <o> IBPSTACKTOP: End address of SMALL model stack <0x0-0xFF>
; <i> Set the top of the stack to the highest location.
IBPSTACKTOP EQU 0xFF +1 ; default 0FFH+1
; </h>
;
; <h> Stack Space for reentrant functions in the LARGE model.
; <q> XBPSTACK: Enable LARGE model reentrant stack
; <i> Stack space for reentrant functions in the LARGE model.
XBPSTACK EQU 0 ; set to 1 if large reentrant is used.
; <o> XBPSTACKTOP: End address of LARGE model stack <0x0-0xFFFF>
; <i> Set the top of the stack to the highest location.
XBPSTACKTOP EQU 0xFFFF +1 ; default 0FFFFH+1
; </h>
;
; <h> Stack Space for reentrant functions in the COMPACT model.
; <q> PBPSTACK: Enable COMPACT model reentrant stack
; <i> Stack space for reentrant functions in the COMPACT model.
PBPSTACK EQU 0 ; set to 1 if compact reentrant is used.
;
; <o> PBPSTACKTOP: End address of COMPACT model stack <0x0-0xFFFF>
; <i> Set the top of the stack to the highest location.
PBPSTACKTOP EQU 0xFF +1 ; default 0FFH+1
; </h>
;</h>
;------------------------------------------------------------------------------
;
; Memory Page for Using the Compact Model with 64 KByte xdata RAM
; <e>Compact Model Page Definition
;
; <i>Define the XDATA page used for PDATA variables.
; <i>PPAGE must conform with the PPAGE set in the linker invocation.
;
; Enable pdata memory page initalization
PPAGEENABLE EQU 0 ; set to 1 if pdata object are used.
;
; <o> PPAGE number <0x0-0xFF>
; <i> uppermost 256-byte address of the page used for PDATA variables.
PPAGE EQU 0
;
; <o> SFR address which supplies uppermost address byte <0x0-0xFF>
; <i> most 8051 variants use P2 as uppermost address byte
PPAGE_SFR DATA 0A0H
;
; </e>
;------------------------------------------------------------------------------
; Standard SFR Symbols
ACC DATA 0E0H
B DATA 0F0H
SP DATA 81H
DPL DATA 82H
DPH DATA 83H
NAME ?C_STARTUP
?C_C51STARTUP SEGMENT CODE
?STACK SEGMENT IDATA
RSEG ?STACK
DS 1
EXTRN CODE (?C_START)
PUBLIC ?C_STARTUP
CSEG AT 0
?C_STARTUP: LJMP STARTUP1
RSEG ?C_C51STARTUP
STARTUP1:
$IF (SILABS_STARTUP = 1)
EXTRN CODE (SiLabs_Startup)
LCALL SiLabs_Startup
$ENDIF
IF IDATALEN <> 0
MOV R0,#IDATALEN - 1
CLR A
IDATALOOP: MOV @R0,A
DJNZ R0,IDATALOOP
ENDIF
IF XDATALEN <> 0
MOV DPTR,#XDATASTART
MOV R7,#LOW (XDATALEN)
IF (LOW (XDATALEN)) <> 0
MOV R6,#(HIGH (XDATALEN)) +1
ELSE
MOV R6,#HIGH (XDATALEN)
ENDIF
CLR A
XDATALOOP: MOVX @DPTR,A
INC DPTR
DJNZ R7,XDATALOOP
DJNZ R6,XDATALOOP
ENDIF
IF PPAGEENABLE <> 0
MOV PPAGE_SFR,#PPAGE
ENDIF
IF PDATALEN <> 0
MOV R0,#LOW (PDATASTART)
MOV R7,#LOW (PDATALEN)
CLR A
PDATALOOP: MOVX @R0,A
INC R0
DJNZ R7,PDATALOOP
ENDIF
IF IBPSTACK <> 0
EXTRN DATA (?C_IBP)
MOV ?C_IBP,#LOW IBPSTACKTOP
ENDIF
IF XBPSTACK <> 0
EXTRN DATA (?C_XBP)
MOV ?C_XBP,#HIGH XBPSTACKTOP
MOV ?C_XBP+1,#LOW XBPSTACKTOP
ENDIF
IF PBPSTACK <> 0
EXTRN DATA (?C_PBP)
MOV ?C_PBP,#LOW PBPSTACKTOP
ENDIF
MOV SP,#?STACK-1
; This code is required if you use L51_BANK.A51 with Banking Mode 4
;<h> Code Banking
; <q> Select Bank 0 for L51_BANK.A51 Mode 4
$IF (USE_BANKING = 1)
; <i> Initialize bank mechanism to code bank 0 when using L51_BANK.A51 with Banking Mode 4.
EXTRN CODE (?B_SWITCH0)
CALL ?B_SWITCH0 ; init bank mechanism to code bank 0
$ENDIF
;</h>
LJMP ?C_START
END

View File

@ -1,148 +0,0 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Solo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
#include <SI_EFM8UB1_Register_Enums.h>
#include <efm8_usb.h>
#include <stdio.h>
#include "printing.h"
#include "descriptors.h"
#include "app.h"
#define UNUSED(expr) do { (void)(expr); } while (0)
#define HID_INTERFACE_INDEX 0
uint8_t tmpBuffer;
void USBD_ResetCb(void) {
// cprints("USBD_ResetCb\r\n");
// u2f_print_ev("USBD_ResetCb\r\n");
}
void USBD_DeviceStateChangeCb(USBD_State_TypeDef oldState,
USBD_State_TypeDef newState) {
// cprints("USBD_DeviceStateChangeCb\r\n");
UNUSED(oldState);
UNUSED(newState);
// u2f_print_ev("USBD_DeviceStateChangeCb\r\n");
}
bool USBD_IsSelfPoweredCb(void) {
// cprints("USBD_IsSelfPoweredCb\r\n");
return false;
}
// Necessary routine for USB HID
USB_Status_TypeDef USBD_SetupCmdCb(
SI_VARIABLE_SEGMENT_POINTER(setup, USB_Setup_TypeDef, MEM_MODEL_SEG)) {
USB_Status_TypeDef retVal = USB_STATUS_REQ_UNHANDLED;
if ((setup->bmRequestType.Type == USB_SETUP_TYPE_STANDARD)
&& (setup->bmRequestType.Direction == USB_SETUP_DIR_IN)
&& (setup->bmRequestType.Recipient == USB_SETUP_RECIPIENT_INTERFACE)) {
// A HID device must extend the standard GET_DESCRIPTOR command
// with support for HID descriptors.
switch (setup->bRequest) {
case GET_DESCRIPTOR:
if (setup->wIndex == 0)
{
if ((setup->wValue >> 8) == USB_HID_REPORT_DESCRIPTOR) {
USBD_Write(EP0, ReportDescriptor0,
EFM8_MIN(sizeof(ReportDescriptor0), setup->wLength),
false);
retVal = USB_STATUS_OK;
} else if ((setup->wValue >> 8) == USB_HID_DESCRIPTOR) {
USBD_Write(EP0, (&configDesc[18]),
EFM8_MIN(USB_HID_DESCSIZE, setup->wLength), false);
retVal = USB_STATUS_OK;
}
}
break;
}
}
else if ((setup->bmRequestType.Type == USB_SETUP_TYPE_CLASS)
&& (setup->bmRequestType.Recipient == USB_SETUP_RECIPIENT_INTERFACE)
&& (setup->wIndex == HID_INTERFACE_INDEX))
{
// Implement the necessary HID class specific commands.
switch (setup->bRequest)
{
case USB_HID_SET_IDLE:
if (((setup->wValue & 0xFF) == 0) // Report ID
&& (setup->wLength == 0)
&& (setup->bmRequestType.Direction != USB_SETUP_DIR_IN))
{
retVal = USB_STATUS_OK;
}
break;
case USB_HID_GET_IDLE:
if ((setup->wValue == 0) // Report ID
&& (setup->wLength == 1)
&& (setup->bmRequestType.Direction == USB_SETUP_DIR_IN))
{
tmpBuffer = 24;
USBD_Write(EP0, &tmpBuffer, 1, false);
retVal = USB_STATUS_OK;
}
break;
default:
break;
}
}
return retVal;
}
uint16_t USBD_XferCompleteCb(uint8_t epAddr, USB_Status_TypeDef status,
uint16_t xferred, uint16_t remaining ) {
UNUSED(status);
UNUSED(xferred);
UNUSED(remaining);
if (epAddr == INPUT_ENDPOINT)
{
usb_transfer_complete();
}
else if (epAddr == OUTPUT_ENDPOINT)
{
usb_writeback_complete();
}
return 0;
}

View File

@ -1,183 +0,0 @@
//=============================================================================
// src/descriptors.c: generated by Hardware Configurator
//
// This file is only generated if it does not exist. Modifications in this file
// will persist even if Configurator generates code. To refresh this file,
// you must first delete it and then regenerate code.
//=============================================================================
//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include <si_toolchain.h>
#include <endian.h>
#include <stdlib.h>
#include <string.h>
#include <efm8_usb.h>
#include "descriptors.h"
#include "app.h"
#ifdef __cplusplus
extern "C" {
#endif
// HID Report Descriptor for Interface 0
SI_SEGMENT_VARIABLE(ReportDescriptor0[34],
const uint8_t,
SI_SEG_CODE) =
{
0x06, 0xd0, 0xf1,// USAGE_PAGE (FIDO Alliance)
0x09, 0x01,// USAGE (Keyboard)
0xa1, 0x01,// COLLECTION (Application)
0x09, 0x20, // USAGE (Input Report Data)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
0x75, 0x08, // REPORT_SIZE (8)
0x95, HID_PACKET_SIZE, // REPORT_COUNT (64)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x09, 0x21, // USAGE(Output Report Data)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x26, 0xff, 0x00, // LOGICAL_MAXIMUM (255)
0x75, 0x08, // REPORT_SIZE (8)
0x95, HID_PACKET_SIZE, // REPORT_COUNT (64)
0x91, 0x02, // OUTPUT (Data,Var,Abs)
0xc0,// END_COLLECTION
};
SI_SEGMENT_VARIABLE(deviceDesc[],
const USB_DeviceDescriptor_TypeDef,
SI_SEG_CODE) =
{
USB_DEVICE_DESCSIZE, // bLength
USB_DEVICE_DESCRIPTOR,// bLength
htole16(0x0200),// bcdUSB
0,// bDeviceClass
0,// bDeviceSubClass
0,// bDeviceProtocol
64,// bMaxPacketSize
USB_VENDOR_ID,// idVendor
USB_PRODUCT_ID,// idProduct
htole16(0x0100),// bcdDevice
1,// iManufacturer
2,// iProduct
3,// iSerialNumber
1,// bNumConfigurations
};
SI_SEGMENT_VARIABLE(configDesc[],
const uint8_t,
SI_SEG_CODE) =
{
USB_CONFIG_DESCSIZE, // bLength
USB_CONFIG_DESCRIPTOR,// bLength
0x29,// wTotalLength(LSB)
0x00,// wTotalLength(MSB)
1,// bNumInterfaces
1,// bConfigurationValue
0,// iConfiguration
CONFIG_DESC_BM_RESERVED_D7,// bmAttrib: Bus powered
CONFIG_DESC_MAXPOWER_mA(100),// bMaxPower: 100 mA
//Interface 0 Descriptor
USB_INTERFACE_DESCSIZE,// bLength
USB_INTERFACE_DESCRIPTOR,// bDescriptorType
0,// bInterfaceNumber
0,// bAlternateSetting
2,// bNumEndpoints
3,// bInterfaceClass: HID (Human Interface Device)
0,// bInterfaceSubClass
0,// bInterfaceProtocol
4,// iInterface
//HID Descriptor
USB_HID_DESCSIZE,// bLength
USB_HID_DESCRIPTOR,// bLength
0x11,// bcdHID (LSB)
0x01,// bcdHID (MSB)
0,// bCountryCode
1,// bNumDescriptors
USB_HID_REPORT_DESCRIPTOR,// bDescriptorType
sizeof( ReportDescriptor0 ),// wDescriptorLength(LSB)
sizeof( ReportDescriptor0 )>>8,// wDescriptorLength(MSB)
//Endpoint 2 IN Descriptor
USB_ENDPOINT_DESCSIZE,// bLength
USB_ENDPOINT_DESCRIPTOR,// bDescriptorType
OUTPUT_ENDPOINT_NUM,// bEndpointAddress
USB_EPTYPE_INTR,// bAttrib
HID_PACKET_SIZE,// wMaxPacketSize (LSB)
0x00,// wMaxPacketSize (MSB)
5,// bInterval
//Endpoint 3 OUT Descriptor
USB_ENDPOINT_DESCSIZE,// bLength
USB_ENDPOINT_DESCRIPTOR,// bDescriptorType
INPUT_ENDPOINT_NUM,// bEndpointAddress
USB_EPTYPE_INTR,// bAttrib
HID_PACKET_SIZE,// wMaxPacketSize (LSB)
0x00,// wMaxPacketSize (MSB)
5,// bInterval
};
#define LANG_STRING htole16( SLAB_USB_LANGUAGE )
#define MFR_STRING 'S','i','l','i','c','o','n',' ','L','a','b','s','\0'
#define MFR_SIZE 13
#define SER_STRING '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','\0'
#define SER_SIZE 17
#define CFG_STRING 'C','o','n','f','i','g',' ','#','1','\0'
#define CFG_SIZE 10
#ifdef BRIDGE_TO_WALLET
#define INT0_STRING 'E','O','S',' ','W','a','l','l','e','t','\0'
#define INT0_SIZE 11
#define PROD_STRING 'E','O','S',' ','W','a','l','l','e','t','\0'
#define PROD_SIZE 11
#else
#define INT0_STRING 'S','o','l','o',' ','K','e','y','\0'
#define INT0_SIZE 9
#define PROD_STRING 'S','o','l','o',' ','K','e','y','\0'
#define PROD_SIZE 9
#endif
LANGID_STATIC_CONST_STRING_DESC( langDesc[], LANG_STRING );
UTF16LE_PACKED_STATIC_CONST_STRING_DESC( mfrDesc[], MFR_STRING, MFR_SIZE);
UTF16LE_PACKED_STATIC_CONST_STRING_DESC( prodDesc[], PROD_STRING, PROD_SIZE);
UTF16LE_PACKED_STATIC_CONST_STRING_DESC( serDesc[], SER_STRING, SER_SIZE);
//UTF16LE_PACKED_STATIC_CONST_STRING_DESC( cfgDesc[], CFG_STRING, CFG_SIZE);
UTF16LE_PACKED_STATIC_CONST_STRING_DESC( int0Desc[], INT0_STRING, INT0_SIZE);
//-----------------------------------------------------------------------------
SI_SEGMENT_POINTER(myUsbStringTable_USEnglish[],
static const USB_StringDescriptor_TypeDef,
const SI_SEG_CODE) =
{
langDesc,
mfrDesc,
prodDesc,
serDesc,
int0Desc,
};
//-----------------------------------------------------------------------------
SI_SEGMENT_VARIABLE(initstruct,
const USBD_Init_TypeDef,
SI_SEG_CODE) =
{
deviceDesc, // deviceDescriptor
configDesc,// configDescriptor
myUsbStringTable_USEnglish,// stringDescriptors
5// numberOfStrings
};
#ifdef __cplusplus
}
#endif

View File

@ -1,100 +0,0 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Solo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
#include <SI_EFM8UB1_Register_Enums.h>
#include <stdint.h>
#include "eeprom.h"
#include "printing.h"
char __erase_mem[3];
static void erase_ram()
{
data uint16_t i;
data uint8_t xdata * clear = 0;
for (i=0; i<0x400;i++)
{
*(clear++) = 0x0;
}
}
void eeprom_init()
{
uint8_t secbyte;
eeprom_read(0xFBFF,&secbyte,1);
if (secbyte == 0xff)
{
eeprom_erase(0xFBC0);
secbyte = -32;
eeprom_write(0xFBFF, &secbyte, 1);
erase_ram();
// Reboot
cprints("rebooting\r\n");
RSTSRC = (1<<4);
}
else
{
// cprints("no reboot\r\n");
}
}
void eeprom_read(uint16_t addr, uint8_t * buf, uint8_t len)
{
uint8_t code * eepaddr = (uint8_t code *) addr;
bit old_int;
while(len--)
{
old_int = IE_EA;
IE_EA = 0;
*buf++ = *eepaddr++;
IE_EA = old_int;
}
}
void _eeprom_write(uint16_t addr, uint8_t * buf, uint8_t len, uint8_t flags)
{
uint8_t xdata * data eepaddr = (uint8_t xdata *) addr;
bit old_int;
while(len--)
{
old_int = IE_EA;
IE_EA = 0;
// Enable VDD monitor
VDM0CN = 0x80;
RSTSRC = 0x02;
// unlock key
FLKEY = 0xA5;
FLKEY = 0xF1;
PSCTL |= flags;
*eepaddr = *buf;
PSCTL &= ~flags;
IE_EA = old_int;
eepaddr++;
buf++;
}
}

View File

@ -1,282 +0,0 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Solo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
#include <SI_EFM8UB1_Register_Enums.h>
#include "InitDevice.h"
#include "efm8_usb.h"
#include "uart_1.h"
#include "printing.h"
#include "eeprom.h"
#define BUFFER_SIZE 12
#ifdef USING_DEVELOPMENT_BOARD
#define RW_PIN P2_B3
#define BUSY_PIN P1_B2
#define MSG_RDY_PIN P1_B1
#else
#define RW_PIN P0_B1
#define BUSY_PIN P0_B2
#define MSG_RDY_PIN P0_B3
#endif
#define SIGNAL_WRITE_BSY() BUSY_PIN = 0 // Set P1 low
#define SIGNAL_WRITE_RDY() BUSY_PIN = 1 // Set P1 high
data uint8_t write_ptr = 0;
data uint8_t read_ptr = 0;
data uint8_t i_ptr = 0;
data uint8_t count = 0;
data uint8_t writebackbuf_count = 0;
uint8_t hidmsgbuf[64*BUFFER_SIZE];
//uint8_t debugR[64];
//uint8_t debugRi;
//uint8_t debugW[64];
//uint8_t debugW2[64];
//uint8_t debugWi;
data uint8_t writebackbuf[64];
void usb_transfer_complete()
{
count++;
// memmove(debugR, hidmsgbuf + write_ptr*64, 64);
// debugRi = write_ptr;
write_ptr++;
if (write_ptr == BUFFER_SIZE)
{
write_ptr = 0;
}
// MSG_RDY_INT_PIN = 0;
// MSG_RDY_INT_PIN = 1;
}
uint16_t USB_TX_COUNT = 0;
void usb_writeback_complete()
{
// if (USB_TX_COUNT >= 511/2)
// {
// USB_TX_COUNT -= 64;
// if (USB_TX_COUNT < 511)
// {
// SIGNAL_WRITE_RDY();
// }
// }
// else
// {
// USB_TX_COUNT -= 64;
// }
USB_TX_COUNT -= 64;
}
void spi_transfer_complete()
{
if (count > 0) count--;
i_ptr = 0;
read_ptr++;
if (read_ptr == BUFFER_SIZE)
{
read_ptr = 0;
}
}
void usb_write()
{
data uint8_t errors = 0;
USB_TX_COUNT += 64;
while (USB_STATUS_OK != (USBD_Write(OUTPUT_ENDPOINT, writebackbuf, 64, true)))
{
delay(2);
if (errors++ > 30)
{
cprints("ERROR USB WRITE\r\n");
break;
}
}
}
extern USBD_Device_TypeDef myUsbDevice;
int main(void) {
data uint8_t k;
data uint16_t last_efm32_pin = 0;
uint16_t t1 = 0;
uint8_t lastcount = count;
int reset;
data int lastwritecount = writebackbuf_count;
enter_DefaultMode_from_RESET();
eeprom_init();
SCON0_TI = 1;
// P2_B0 = 1;
MSG_RDY_PIN = 1;
// enable SPI interrupts
// SPI0FCN1 = SPI0FCN1 | (1<<4);
IE_EA = 1;
// IE_ESPI0 = 1;
SPI0FCN0 = SPI0FCN0 | (1<<2); // flush RX fifo
SPI0FCN0 = SPI0FCN0 | (1<<6); // flush TX fifo
// SPI0FCN0 &= ~3; // FIFO threshold 0x0
SPI0FCN1 |= (1); // Enable RX fifo
// cprints("hello,world\r\n");
reset = RSTSRC;
cprintx("reset source: ", 1, reset);
if (reset != 0x10)
{
RSTSRC = (1<<4);
}
MSG_RDY_PIN = 1;
SIGNAL_WRITE_BSY();
while (1) {
if (RW_PIN == 0)
{
i_ptr = 0;
SPI0FCN0 |= (1<<6); // Flush TX fifo buffer
while (SPI0CN0 & (1 << 1)) // While TX FIFO has room
SPI0DAT = (hidmsgbuf+read_ptr*64)[i_ptr++];
SIGNAL_WRITE_RDY();
while (i_ptr<64)
{
while(! (SPI0CN0 & (1 << 1)))
;
SPI0DAT = (hidmsgbuf+read_ptr*64)[i_ptr++];
}
while(RW_PIN == 0)
{
}
// cprints(">> ");
// dump_hex(hidmsgbuf+read_ptr*64,64);
spi_transfer_complete();
if (count == 0)
{
MSG_RDY_PIN = 1;
}
SPI0FCN0 = SPI0FCN0 | (1<<2); // flush RX fifo
while ((SPI0CFG & (0x1)) == 0)
{
k = SPI0DAT;
}
SIGNAL_WRITE_BSY();
}
else
{
// Did we RX data and have room?
if ((SPI0CFG & (0x1)) == 0 && USB_TX_COUNT < 511/2)
{
writebackbuf[writebackbuf_count++] = SPI0DAT;
SIGNAL_WRITE_RDY();
while(writebackbuf_count < 64)
{
while((SPI0CFG & (0x1)) == 1)
;
writebackbuf[writebackbuf_count++] = SPI0DAT;
}
// cprints("<< ");
// dump_hex(writebackbuf,64);
usb_write();
writebackbuf_count = 0;
SPI0FCN0 = SPI0FCN0 | (1<<2); // flush RX fifo
SIGNAL_WRITE_BSY();
}
}
if (millis() - t1 > 1500)
{
#ifdef USING_DEVELOPMENT_BOARD
P1_B5 = k++&1;
#endif
t1 = millis();
}
// if (!USBD_EpIsBusy(EP2OUT) && !USBD_EpIsBusy(EP3IN) && lastcount==count)
if (!USBD_EpIsBusy(INPUT_ENDPOINT) && lastcount==count)
// if (lastcount==count)
{
// cprintd("sched read to ",1,(int)(hidmsgbuf + write_ptr*64));
if (count == BUFFER_SIZE)
{
// cprints("Warning, USB buffer full\r\n");
}
else
{
// cprints("sched read\r\n");
USBD_Read(INPUT_ENDPOINT, hidmsgbuf + write_ptr*64, 64, true);
}
}
// cprints("it\r\n");
if (lastcount != count)
{
if (count > lastcount)
{
// cputd(debugRi); cprints(">> ");
// dump_hex(debugR,64);
MSG_RDY_PIN = 0;
}
else
{
// cputd(debugWi); cprints(">>>> ");
// dump_hex(debugW,64);
// dump_hex(debugW2,64);
}
lastcount = count;
}
}
}

View File

@ -1,207 +0,0 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Solo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
/*
* printing.c
*
* Created on: Jun 25, 2018
* Author: conor
*/
#include <SI_EFM8UB1_Register_Enums.h>
#include <efm8_usb.h>
#include <stdarg.h>
#include <stdio.h>
#include "printing.h"
void delay(uint16_t ms)
{
uint16_t m1 = millis();
while (millis() - m1 < ms)
;
}
#ifdef USE_PRINTING
void putf(char c)
{
uint8_t i;
SBUF0 = c;
// Blocking delay that works for 115200 baud on this device (<1ms)
for (i=0; i<200; i++){}
for (i=0; i<200; i++){}
for (i=0; i<190; i++){}
}
void dump_hex(uint8_t* hex, uint8_t len)
{
uint8_t i;
uint8_t b;
const char lut[] = "0123456789abcdef";
for (i=0 ; i < len ; i++)
{
b = ((*hex) & 0xf0)>>4;
putf(lut[b]);
b = ((*hex) & 0x0f);
putf(lut[b]);
putf(' ');
hex++;
}
cprints("\r\n");
}
void cprints(char* d)
{
while(*d)
{
// UART0 output queue
putf(*d++);
}
}
static void int2str_reduce_n(char ** snum, uint32_t copy, uint8_t n)
{
do
{
copy /= n;
++*snum;
}while(copy);
}
static const char * __digits = "0123456789abcdef";
static char xdata __int2str_buf[9];
static void int2str_map_n(char ** snum, uint32_t i, uint8_t n)
{
int c = 0;
do
{
if (*snum <__int2str_buf) break;
*--*snum = __digits[i % n];
i /= n;
}while(i);
}
#define dint2str(i) __int2strn(i,10)
#define xint2str(i) __int2strn(i,16)
char * __int2strn(int32_t i, uint8_t n)
{
char * snum = __int2str_buf;
if (i<0) *snum++ = '-';
int2str_reduce_n(&snum, i, n);
*snum = '\0';
int2str_map_n(&snum, i, n);
return snum;
}
void cputd(int32_t i)
{
cprints(dint2str((int32_t)i));
}
void cputx(int32_t i)
{
cprints(xint2str(i));
}
static void put_space()
{
cprints(" ");
}
static void put_line()
{
cprints("\r\n");
}
void cprintd(const char * tag, uint8_t c, ...)
{
va_list args;
cprints(tag);
va_start(args,c);
while(c--)
{
cputd((int32_t)va_arg(args, int16_t));
}
put_line();
va_end(args);
}
void cprintl(const char * tag, uint8_t c, ...)
{
va_list args;
cprints(tag);
va_start(args,c);
while(c--)
{
cputl(va_arg(args, int32_t));
cprints(" ");
}
put_line();
va_end(args);
}
void cprintx(const char * tag, uint8_t c, ...)
{
va_list args;
cprints(tag);
va_start(args,c);
while(c--)
{
cputx((int32_t)va_arg(args, uint16_t));
cprints(" ");
}
put_line();
va_end(args);
}
void cprintb(const char * tag, uint8_t c, ...)
{
va_list args;
cprints(tag);
va_start(args,c);
while(c--)
{
cputb(va_arg(args, uint8_t));
put_space();
}
put_line();
va_end(args);
}
void cprintlx(const char * tag, uint8_t c, ...)
{
va_list args;
cprints(tag);
va_start(args,c);
while(c--)
{
cputlx(va_arg(args, int32_t));
put_space();
}
put_line();
va_end(args);
}
#endif

View File

@ -1,308 +0,0 @@
PROJECT_NAME := blinky_pca10056
TARGETS := nrf52840_xxaa
OUTPUT_DIRECTORY := _build
SDK_ROOT := ./sdk_15.0.0
PROJ_DIR := .
$(OUTPUT_DIRECTORY)/nrf52840_xxaa.out: \
LINKER_SCRIPT := blinky_gcc_nrf52.ld
# Source files common to all targets
SRC_FILES += \
$(SDK_ROOT)/modules/nrfx/mdk/gcc_startup_nrf52840.S \
$(PROJ_DIR)/../main.c \
$(PROJ_DIR)/usb.c \
$(PROJ_DIR)/retarget.c \
$(PROJ_DIR)/device.c \
$(PROJ_DIR)/../util.c \
$(PROJ_DIR)/../log.c \
$(PROJ_DIR)/../stubs.c \
$(PROJ_DIR)/../ctaphid.c \
$(PROJ_DIR)/../ctap.c \
$(PROJ_DIR)/../ctap_parse.c \
$(PROJ_DIR)/../u2f.c \
$(PROJ_DIR)/../test_power.c \
\
$(PROJ_DIR)/crypto.c \
$(PROJ_DIR)/../crypto/sha256.c \
$(PROJ_DIR)/../crypto/tiny-AES-c/aes.c \
$(PROJ_DIR)/../crypto/micro-ecc/uECC.c \
\
$(SDK_ROOT)/components/boards/boards.c \
$(SDK_ROOT)/components/libraries/util/app_error.c \
$(SDK_ROOT)/components/libraries/util/app_error_handler_gcc.c \
$(SDK_ROOT)/components/libraries/util/app_error_weak.c \
$(SDK_ROOT)/components/libraries/util/app_util_platform.c \
$(SDK_ROOT)/components/libraries/util/nrf_assert.c \
$(SDK_ROOT)/components/libraries/strerror/nrf_strerror.c \
$(SDK_ROOT)/modules/nrfx/mdk/system_nrf52840.c \
$(SDK_ROOT)/external/segger_rtt/SEGGER_RTT.c \
$(SDK_ROOT)/external/segger_rtt/SEGGER_RTT_printf.c \
$(SDK_ROOT)/integration/nrfx/legacy/nrf_drv_clock.c \
$(SDK_ROOT)/modules/nrfx/drivers/src/nrfx_rtc.c \
$(SDK_ROOT)/modules/nrfx/drivers/src/nrfx_clock.c \
\
$(SDK_ROOT)/components/libraries/button/app_button.c \
$(SDK_ROOT)/components/libraries/fifo/app_fifo.c \
$(SDK_ROOT)/components/libraries/scheduler/app_scheduler.c \
$(SDK_ROOT)/components/libraries/timer/app_timer.c \
$(SDK_ROOT)/components/libraries/uart/app_uart_fifo.c \
$(SDK_ROOT)/components/libraries/usbd/app_usbd.c \
$(SDK_ROOT)/components/libraries/usbd/app_usbd_core.c \
$(SDK_ROOT)/components/libraries/usbd/class/hid/app_usbd_hid.c \
$(SDK_ROOT)/components/libraries/usbd/class/hid/generic/app_usbd_hid_generic.c \
$(SDK_ROOT)/components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd.c \
$(SDK_ROOT)/components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse.c \
$(SDK_ROOT)/components/libraries/usbd/app_usbd_string_desc.c \
$(SDK_ROOT)/external/fnmatch/fnmatch.c \
$(SDK_ROOT)/components/libraries/hardfault/nrf52/handler/hardfault_handler_gcc.c \
$(SDK_ROOT)/components/libraries/hardfault/hardfault_implementation.c \
$(SDK_ROOT)/components/libraries/atomic_fifo/nrf_atfifo.c \
$(SDK_ROOT)/components/libraries/atomic/nrf_atomic.c \
$(SDK_ROOT)/components/libraries/balloc/nrf_balloc.c \
$(SDK_ROOT)/components/libraries/experimental_memobj/nrf_memobj.c \
$(SDK_ROOT)/components/libraries/pwr_mgmt/nrf_pwr_mgmt.c \
$(SDK_ROOT)/components/libraries/queue/nrf_queue.c \
$(SDK_ROOT)/components/libraries/experimental_ringbuf/nrf_ringbuf.c \
$(SDK_ROOT)/components/libraries/experimental_section_vars/nrf_section_iter.c \
$(SDK_ROOT)/integration/nrfx/legacy/nrf_drv_power.c \
$(SDK_ROOT)/components/drivers_nrf/usbd/nrf_drv_usbd.c \
$(SDK_ROOT)/components/drivers_nrf/nrf_soc_nosd/nrf_nvic.c \
$(SDK_ROOT)/components/drivers_nrf/nrf_soc_nosd/nrf_soc.c \
$(SDK_ROOT)/modules/nrfx/drivers/src/nrfx_gpiote.c \
$(SDK_ROOT)/modules/nrfx/drivers/src/nrfx_power.c \
$(SDK_ROOT)/modules/nrfx/drivers/src/nrfx_power_clock.c \
$(SDK_ROOT)/modules/nrfx/drivers/src/prs/nrfx_prs.c \
$(SDK_ROOT)/components/libraries/bsp/bsp.c \
$(SDK_ROOT)/components/libraries/bsp/bsp_cli.c \
\
$(SDK_ROOT)/external/cifra_AES128-EAX/blockwise.c \
$(SDK_ROOT)/external/cifra_AES128-EAX/cifra_cmac.c \
$(SDK_ROOT)/external/cifra_AES128-EAX/cifra_eax_aes.c \
$(SDK_ROOT)/external/cifra_AES128-EAX/eax.c \
$(SDK_ROOT)/external/cifra_AES128-EAX/gf128.c \
$(SDK_ROOT)/components/libraries/mem_manager/mem_manager.c \
$(SDK_ROOT)/external/cifra_AES128-EAX/modes.c \
$(SDK_ROOT)/external/fprintf/nrf_fprintf.c \
$(SDK_ROOT)/external/fprintf/nrf_fprintf_format.c \
$(SDK_ROOT)/integration/nrfx/legacy/nrf_drv_rng.c \
$(SDK_ROOT)/modules/nrfx/drivers/src/prs/nrfx_prs.c \
$(SDK_ROOT)/modules/nrfx/drivers/src/nrfx_rng.c \
# Include folders common to all targets
INC_FOLDERS += \
$(SDK_ROOT)/components \
$(SDK_ROOT)/components/libraries/experimental_memobj \
$(SDK_ROOT)/components/libraries/experimental_section_vars \
$(SDK_ROOT)/modules/nrfx/mdk \
$(SDK_ROOT)/modules/nrfx/hal \
$(SDK_ROOT)/components/libraries/balloc \
$(SDK_ROOT)/components/libraries/experimental_log \
$(SDK_ROOT)/components/libraries/experimental_log/src \
$(SDK_ROOT)/components/libraries/delay \
$(SDK_ROOT)/integration/nrfx \
$(SDK_ROOT)/components/libraries/bsp \
$(SDK_ROOT)/components/drivers_nrf/nrf_soc_nosd \
$(SDK_ROOT)/components/libraries/strerror \
$(SDK_ROOT)/components/boards \
$(SDK_ROOT)/components/toolchain/cmsis/include \
$(SDK_ROOT)/modules/nrfx \
$(SDK_ROOT)/external/segger_rtt \
$(PROJ_DIR) \
$(PROJ_DIR)/.. \
$(PROJ_DIR)/../tinycbor/src \
\
$(PROJ_DIR)/../crypto/ \
$(PROJ_DIR)/../crypto/micro-ecc \
$(PROJ_DIR)/../crypto/tiny-AES-c \
\
$(SDK_ROOT)/components/libraries/util \
$(SDK_ROOT)/integration/nrfx/legacy \
$(SDK_ROOT)/modules/nrfx/drivers/include \
$(SDK_ROOT)/components/libraries/cli \
$(SDK_ROOT)/components/libraries/scheduler \
$(SDK_ROOT)/components/libraries/experimental_log \
$(SDK_ROOT)/components/libraries/queue \
$(SDK_ROOT)/components/libraries/pwr_mgmt \
$(SDK_ROOT)/components/libraries/fifo \
$(SDK_ROOT)/components/toolchain/cmsis/include \
$(SDK_ROOT)/components/libraries/timer \
$(SDK_ROOT)/components/libraries/bsp \
$(SDK_ROOT)/components/libraries/usbd/class/hid/generic \
$(SDK_ROOT)/components/libraries/usbd/class/hid/kbd \
$(SDK_ROOT)/components/libraries/balloc \
$(SDK_ROOT)/components/drivers_nrf/usbd \
$(SDK_ROOT)/components/libraries/usbd/class/hid \
$(SDK_ROOT)/components/libraries/hardfault/nrf52 \
$(SDK_ROOT)/components/libraries/hardfault \
$(SDK_ROOT)/components/libraries/uart \
$(SDK_ROOT)/external/fnmatch \
$(SDK_ROOT)/components/libraries/button \
$(SDK_ROOT)/components/libraries/experimental_section_vars \
$(SDK_ROOT)/integration/nrfx/legacy \
$(SDK_ROOT)/components/libraries/usbd \
$(SDK_ROOT)/components/libraries/mutex \
$(PROJ_DIR) \
$(SDK_ROOT)/components/libraries/experimental_log/src \
$(SDK_ROOT)/components/libraries/delay \
$(SDK_ROOT)/external/segger_rtt \
$(SDK_ROOT)/components/libraries/atomic_fifo \
$(SDK_ROOT)/components/libraries/experimental_ringbuf \
$(SDK_ROOT)/components/libraries/atomic \
$(SDK_ROOT)/components/boards \
$(SDK_ROOT)/components/libraries/experimental_memobj \
$(SDK_ROOT)/components/libraries/usbd/config \
$(SDK_ROOT)/integration/nrfx \
$(SDK_ROOT)/components/drivers_nrf/nrf_soc_nosd \
$(SDK_ROOT)/components/libraries/usbd/class/hid/mouse \
$(SDK_ROOT)/modules/nrfx/drivers/include \
$(SDK_ROOT)/modules/nrfx/hal \
$(SDK_ROOT)/external/fprintf \
\
$(SDK_ROOT)/external/fprintf \
$(PROJ_DIR) \
$(SDK_ROOT)/components/libraries/experimental_section_vars \
$(SDK_ROOT)/components/libraries/experimental_log \
$(SDK_ROOT)/components/libraries/experimental_memobj \
$(SDK_ROOT)/components/libraries/stack_info \
$(SDK_ROOT)/components/libraries/delay \
$(SDK_ROOT)/external/nrf_oberon/include \
$(SDK_ROOT)/components/libraries/crypto \
$(SDK_ROOT)/components/toolchain/cmsis/include \
$(SDK_ROOT)/components/libraries/balloc \
$(SDK_ROOT)/components/libraries/mem_manager \
$(SDK_ROOT)/external/nrf_oberon \
$(SDK_ROOT)/components/libraries/atomic \
$(SDK_ROOT)/components/libraries/strerror \
$(SDK_ROOT)/integration/nrfx \
$(SDK_ROOT)/modules/nrfx/drivers/include \
$(SDK_ROOT)/external/mbedtls/include \
$(SDK_ROOT)/components/libraries/experimental_log/src \
$(SDK_ROOT)/components/libraries/util \
$(SDK_ROOT)/modules/nrfx \
$(SDK_ROOT)/components/drivers_nrf/nrf_soc_nosd \
$(SDK_ROOT)/external/segger_rtt \
$(SDK_ROOT)/modules/nrfx/mdk \
$(SDK_ROOT)/modules/nrfx/hal \
$(SDK_ROOT)/components/libraries/mutex \
$(SDK_ROOT)/components/libraries/queue \
$(SDK_ROOT)/integration/nrfx/legacy \
$(SDK_ROOT)/external/cifra_AES128-EAX \
$(SDK_ROOT)/components/boards \
$(SDK_ROOT)/external/nrf_cc310/include \
# Libraries common to all targets
LIB_FILES += $(SDK_ROOT)/external/nrf_cc310/lib/libnrf_cc310_0.9.9.a \
$(PROJ_DIR)/../tinycbor/lib/libtinycbor.a
# Optimization flags
OPT = -O3 -g3
# Uncomment the line below to enable link time optimization
#OPT += -flto
# C flags common to all targets
CFLAGS += $(OPT)
CFLAGS += -DBOARD_PCA10056
CFLAGS += -DNRF52
#CFLAGS += -DBSP_DEFINES_ONLY
CFLAGS += -DCONFIG_GPIO_AS_PINRESET
CFLAGS += -DFLOAT_ABI_HARD
CFLAGS += -DNRF52840_XXAA
#CFLAGS += -DSTUB_CTAPHID
#CFLAGS += -DSTUB_CTAP
CFLAGS += -DuECC_PLATFORM=5
#CFLAGS += -DTEST_POWER -DTEST
CFLAGS += -std=gnu11
CFLAGS += -mcpu=cortex-m4
CFLAGS += -mthumb -mabi=aapcs
CFLAGS += -Wall -Wno-format
CFLAGS += -mfloat-abi=hard -mfpu=fpv4-sp-d16
# keep every function in a separate section, this allows linker to discard unused ones
CFLAGS += -ffunction-sections -fdata-sections -fno-strict-aliasing
CFLAGS += -fno-builtin -fshort-enums
CFLAGS += -DNRF_CRYPTO_MAX_INSTANCE_COUNT=1
# C++ flags common to all targets
CXXFLAGS += $(OPT)
# Assembler flags common to all targets
ASMFLAGS += -g3
ASMFLAGS += -mcpu=cortex-m4
ASMFLAGS += -mthumb -mabi=aapcs
ASMFLAGS += -mfloat-abi=hard -mfpu=fpv4-sp-d16
ASMFLAGS += -DBOARD_PCA10056
ASMFLAGS += -DBSP_DEFINES_ONLY
ASMFLAGS += -DCONFIG_GPIO_AS_PINRESET
ASMFLAGS += -DFLOAT_ABI_HARD
ASMFLAGS += -DNRF52840_XXAA
# Linker flags
LDFLAGS += $(OPT)
LDFLAGS += -mthumb -mabi=aapcs -L$(SDK_ROOT)/modules/nrfx/mdk -T$(LINKER_SCRIPT)
LDFLAGS += -mcpu=cortex-m4
LDFLAGS += -mfloat-abi=hard -mfpu=fpv4-sp-d16
# let linker dump unused sections
LDFLAGS += -Wl,--gc-sections
# use newlib in nano version
LDFLAGS += --specs=nano.specs
nrf52840_xxaa: CFLAGS += -D__HEAP_SIZE=8192
nrf52840_xxaa: CFLAGS += -D__STACK_SIZE=8192
nrf52840_xxaa: ASMFLAGS += -D__HEAP_SIZE=8192
nrf52840_xxaa: ASMFLAGS += -D__STACK_SIZE=8192
# Add standard libraries at the very end of the linker input, after all objects
# that may need symbols provided by these libraries.
LIB_FILES += -lc -lnosys -lm
.PHONY: default help
# Default target - first one defined
default: nrf52840_xxaa
# Print all targets that can be built
help:
@echo following targets are available:
@echo nrf52840_xxaa
@echo sdk_config - starting external tool for editing sdk_config.h
@echo flash - flashing binary
TEMPLATE_PATH := $(SDK_ROOT)/components/toolchain/gcc
include $(TEMPLATE_PATH)/Makefile.common
#include $(PROJ_DIR)/../tinycbor/Makefile
#$(shell echo )
#$(shell )
$(foreach target, $(TARGETS), $(call define_target, $(target)))
.PHONY: flash erase
cbor:
cd $(PROJ_DIR)/../tinycbor/ && make clean
cd $(PROJ_DIR)/../tinycbor/ && make CC="$(CC)" \
LDFLAGS="-lc -lnosys --specs=nosys.specs -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -mthumb -mabi=aapcs " \
CFLAGS=" -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -mthumb -mabi=aapcs -DFLOAT_ABI_HARD -std=gnu11"
# Flash the program
flash: $(OUTPUT_DIRECTORY)/nrf52840_xxaa.hex
@echo Flashing: $<
nrfjprog -f nrf52 --program $< --sectorerase
nrfjprog -f nrf52 --reset
erase:
nrfjprog -f nrf52 --eraseall
SDK_CONFIG_FILE := ../config/sdk_config.h
CMSIS_CONFIG_TOOL := $(SDK_ROOT)/external_tools/cmsisconfig/CMSIS_Configuration_Wizard.jar
sdk_config:
java -jar $(CMSIS_CONFIG_TOOL) $(SDK_CONFIG_FILE)

View File

@ -1,45 +0,0 @@
// <h> segger_rtt - SEGGER RTT
//==========================================================
// <o> SEGGER_RTT_CONFIG_BUFFER_SIZE_UP - Size of upstream buffer.
// <i> Note that either @ref NRF_LOG_BACKEND_RTT_OUTPUT_BUFFER_SIZE
// <i> or this value is actually used. It depends on which one is bigger.
#ifndef SEGGER_RTT_CONFIG_BUFFER_SIZE_UP
#define SEGGER_RTT_CONFIG_BUFFER_SIZE_UP 4096
#endif
// <o> SEGGER_RTT_CONFIG_MAX_NUM_UP_BUFFERS - Size of upstream buffer.
#ifndef SEGGER_RTT_CONFIG_MAX_NUM_UP_BUFFERS
#define SEGGER_RTT_CONFIG_MAX_NUM_UP_BUFFERS 16
#endif
// <o> SEGGER_RTT_CONFIG_BUFFER_SIZE_DOWN - Size of upstream buffer.
#ifndef SEGGER_RTT_CONFIG_BUFFER_SIZE_DOWN
#define SEGGER_RTT_CONFIG_BUFFER_SIZE_DOWN 8
#endif
// <o> SEGGER_RTT_CONFIG_MAX_NUM_DOWN_BUFFERS - Size of upstream buffer.
#ifndef SEGGER_RTT_CONFIG_MAX_NUM_DOWN_BUFFERS
#define SEGGER_RTT_CONFIG_MAX_NUM_DOWN_BUFFERS 2
#endif
// <o> SEGGER_RTT_CONFIG_DEFAULT_MODE - RTT behavior if the buffer is full.
// <i> The following modes are supported:
// <i> - SKIP - Do not block, output nothing.
// <i> - TRIM - Do not block, output as much as fits.
// <i> - BLOCK - Wait until there is space in the buffer.
// <0=> SKIP
// <1=> TRIM
// <2=> BLOCK_IF_FIFO_FULL
#ifndef SEGGER_RTT_CONFIG_DEFAULT_MODE
#define SEGGER_RTT_CONFIG_DEFAULT_MODE 1
#define APP_FIFO_ENABLED 2
#endif

View File

@ -1,57 +0,0 @@
/* Linker script to configure memory regions. */
SEARCH_DIR(.)
GROUP(-lgcc -lc -lnosys)
MEMORY
{
FLASH (rx) : ORIGIN = 0x0, LENGTH = 0x100000
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x40000
}
SECTIONS
{
}
SECTIONS
{
. = ALIGN(4);
.mem_section_dummy_ram :
{
}
.log_dynamic_data :
{
PROVIDE(__start_log_dynamic_data = .);
KEEP(*(SORT(.log_dynamic_data*)))
PROVIDE(__stop_log_dynamic_data = .);
} > RAM
} INSERT AFTER .data;
SECTIONS
{
.mem_section_dummy_rom :
{
}
.crypto_data :
{
PROVIDE(__start_crypto_data = .);
KEEP(*(SORT(.crypto_data*)))
PROVIDE(__stop_crypto_data = .);
} > FLASH
.log_const_data :
{
PROVIDE(__start_log_const_data = .);
KEEP(*(SORT(.log_const_data*)))
PROVIDE(__stop_log_const_data = .);
} > FLASH
.nrf_balloc :
{
PROVIDE(__start_nrf_balloc = .);
KEEP(*(.nrf_balloc))
PROVIDE(__stop_nrf_balloc = .);
} > FLASH
} INSERT AFTER .text
INCLUDE "nrf_common.ld"

View File

@ -1,489 +0,0 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Solo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
/*
* Wrapper for crypto implementation on device
*
* */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "util.h"
#include "crypto.h"
#include "sha256.h"
#include "uECC.h"
#include "aes.h"
#include "ctap.h"
#include "ssi_pal_types.h"
#include "ssi_pal_mem.h"
#include "sns_silib.h"
#include "crys_ecpki_build.h"
#include "crys_ecpki_ecdsa.h"
#include "crys_ecpki_dh.h"
#include "crys_ecpki_kg.h"
#include "crys_ecpki_domain.h"
#include "crys_rnd.h"
#include "nrf52840.h"
const uint8_t attestation_cert_der[];
const uint16_t attestation_cert_der_size;
const uint8_t attestation_key[];
const uint16_t attestation_key_size;
/*static SHA256_CTX sha256_ctx;*/
struct CRYS_HASHUserContext_t sha256_ctx;
const CRYS_ECPKI_Domain_t* _es256_curve;
CRYS_RND_State_t rndState_ptr;
CRYS_RND_WorkBuff_t rndWorkBuff_ptr;
static const uint8_t * _signing_key = NULL;
// Secrets for testing only
static uint8_t master_secret[32] = "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff"
"\xff\xee\xdd\xcc\xbb\xaa\x99\x88\x77\x66\x55\x44\x33\x22\x11\x00";
static uint8_t transport_secret[32] = "\x10\x01\x22\x33\x44\x55\x66\x77\x87\x90\x0a\xbb\x3c\xd8\xee\xff"
"\xff\xee\x8d\x1c\x3b\xfa\x99\x88\x77\x86\x55\x44\xd3\xff\x33\x00";
void crypto_sha256_init()
{
/*sha256_init(&sha256_ctx);*/
int ret = CRYS_HASH_Init(&sha256_ctx, CRYS_HASH_SHA256_mode);
if (ret != CRYS_OK )
{
printf("sha init fail\n");
exit(1);
}
}
void crypto_reset_master_secret()
{
ctap_generate_rng(master_secret, 32);
}
void crypto_sha256_update(uint8_t * data, size_t len)
{
/*sha256_update(&sha256_ctx, data, len);*/
int ret = CRYS_HASH_Update(&sha256_ctx, data, len);
if (ret != CRYS_OK )
{
printf("sha update fail\n");
exit(1);
}
}
void crypto_sha256_update_secret()
{
/*sha256_update(&sha256_ctx, master_secret, 32);*/
int ret = CRYS_HASH_Update(&sha256_ctx, master_secret, 32);
if (ret != CRYS_OK )
{
printf("sha update secret fail\n");
exit(1);
}
}
void crypto_sha256_final(uint8_t * hash)
{
/*sha256_final(&sha256_ctx, hash);*/
int ret = CRYS_HASH_Finish(&sha256_ctx, (uint32_t*)hash);
if (ret != CRYS_OK )
{
printf("sha finish fail\n");
exit(1);
}
}
void crypto_sha256_hmac_init(uint8_t * key, uint32_t klen, uint8_t * hmac)
{
uint8_t buf[64];
int i;
memset(buf, 0, sizeof(buf));
if (key == CRYPTO_MASTER_KEY)
{
key = master_secret;
klen = sizeof(master_secret);
}
if(klen > 64)
{
printf("Error, key size must be <= 64\n");
exit(1);
}
memmove(buf, key, klen);
for (i = 0; i < sizeof(buf); i++)
{
buf[i] = buf[i] ^ 0x36;
}
crypto_sha256_init();
crypto_sha256_update(buf, 64);
}
void crypto_sha256_hmac_final(uint8_t * key, uint32_t klen, uint8_t * hmac)
{
uint8_t buf[64];
int i;
crypto_sha256_final(hmac);
memset(buf, 0, sizeof(buf));
if (key == CRYPTO_MASTER_KEY)
{
key = master_secret;
klen = sizeof(master_secret);
}
if(klen > 64)
{
printf("Error, key size must be <= 64\n");
exit(1);
}
memmove(buf, key, klen);
for (i = 0; i < sizeof(buf); i++)
{
buf[i] = buf[i] ^ 0x5c;
}
crypto_sha256_init();
crypto_sha256_update(buf, 64);
crypto_sha256_update(hmac, 32);
crypto_sha256_final(hmac);
}
void crypto_ecc256_init()
{
int ret;
NVIC_EnableIRQ(CRYPTOCELL_IRQn);
NRF_CRYPTOCELL->ENABLE = 1;
ret = SaSi_LibInit();
if (ret != SA_SILIB_RET_OK) {
printf("Failed SaSi_LibInit - ret = 0x%x\n", ret);
exit(1);
}
memset(&rndState_ptr, 0, sizeof(CRYS_RND_State_t));
memset(&rndWorkBuff_ptr, 0, sizeof(CRYS_RND_WorkBuff_t));
ret = CRYS_RndInit(&rndState_ptr, &rndWorkBuff_ptr);
if (ret != SA_SILIB_RET_OK) {
printf("Failed CRYS_RndInit - ret = 0x%x\n", ret);
exit(1);
}
_es256_curve = CRYS_ECPKI_GetEcDomain(CRYS_ECPKI_DomainID_secp256r1);
//
uECC_set_rng((uECC_RNG_Function)ctap_generate_rng);
//
}
void crypto_ecc256_load_attestation_key()
{
_signing_key = attestation_key;
}
void crypto_ecc256_sign(uint8_t * data, int len, uint8_t * sig)
{
CRYS_ECPKI_UserPrivKey_t UserPrivKey;
CRYS_ECDSA_SignUserContext_t SignUserContext;
uint32_t sigsz = 64;
int ret = CRYS_ECPKI_BuildPrivKey(_es256_curve,
_signing_key,
32,
&UserPrivKey);
if (ret != SA_SILIB_RET_OK){
printf(" CRYS_ECPKI_BuildPrivKey failed with 0x%x \n",ret);
exit(1);
}
ret = CRYS_ECDSA_Sign(&rndState_ptr,
CRYS_RND_GenerateVector,
&SignUserContext,
&UserPrivKey,
CRYS_ECPKI_AFTER_HASH_SHA256_mode,
data,
len,
sig,
&sigsz);
if (ret != SA_SILIB_RET_OK){
printf(" CRYS_ECDSA_Sign failed with 0x%x \n",ret);
exit(1);
}
}
/*int uECC_compute_public_key(const uint8_t *private_key, uint8_t *public_key, uECC_Curve curve);*/
void derive_private_key_pair(uint8_t * data, int len, uint8_t * data2, int len2, uint8_t * privkey, uint8_t * pubkey);
void crypto_ecc256_derive_public_key(uint8_t * data, int len, uint8_t * x, uint8_t * y)
{
uint8_t privkey[32];
uint8_t pubkey[64];
derive_private_key_pair(data,len,NULL,0,privkey,pubkey);
/*memset(pubkey,0,sizeof(pubkey));*/
/*uECC_compute_public_key(privkey, pubkey, uECC_secp256r1());*/
memmove(x,pubkey,32);
memmove(y,pubkey+32,32);
}
void crypto_ecc256_load_key(uint8_t * data, int len, uint8_t * data2, int len2)
{
static uint8_t privkey[32];
generate_private_key(data,len,data2,len2,privkey);
_signing_key = privkey;
}
void crypto_ecc256_make_key_pair(uint8_t * pubkey, uint8_t * privkey)
{
CRYS_ECPKI_UserPrivKey_t nrfpriv;
CRYS_ECPKI_UserPublKey_t nrfpub;
CRYS_ECPKI_KG_TempData_t tmp;
uint8_t pubkey1[65];
int ret;
uint32_t sz;
ret = CRYS_ECPKI_GenKeyPair(&rndState_ptr,
CRYS_RND_GenerateVector,
_es256_curve,
&nrfpriv, &nrfpub, &tmp, NULL);
if (ret != SA_SILIB_RET_OK){
printf(" gen key failed with 0x%x \n",ret);
exit(1);
}
sz = 32;
CRYS_ECPKI_ExportPrivKey(&nrfpriv, privkey, &sz);
sz = 65;
CRYS_ECPKI_ExportPublKey(&nrfpub,CRYS_EC_PointUncompressed, pubkey1, &sz);
memmove(pubkey, pubkey1+1, 64);
}
void crypto_ecc256_shared_secret(const uint8_t * pubkey, const uint8_t * privkey, uint8_t * shared_secret)
{
if (uECC_shared_secret(pubkey, privkey, shared_secret, uECC_secp256r1()) != 1)
{
printf("Error, uECC_shared_secret failed\n");
exit(1);
}
}
uint8_t fixed_vector_hmac[32];
int fixed_vector_iter = 31;
uint32_t fixed_vector(void * rng, uint16_t sz, uint8_t * out)
{
while(sz--)
{
*out++ = fixed_vector_hmac[fixed_vector_iter--];
if (fixed_vector_iter == -1)
{
fixed_vector_iter = 31;
}
}
return 0;
}
void derive_private_key_pair(uint8_t * data, int len, uint8_t * data2, int len2, uint8_t * privkey, uint8_t * pubkey)
{
CRYS_ECPKI_UserPrivKey_t nrfpriv;
CRYS_ECPKI_UserPublKey_t nrfpub;
CRYS_ECPKI_KG_TempData_t tmp;
uint32_t ret;
uint32_t sz;
int i;
uint8_t pubkey1[65];
crypto_sha256_hmac_init(CRYPTO_MASTER_KEY, 0, privkey);
crypto_sha256_update(data, len);
crypto_sha256_update(data2, len2);
crypto_sha256_update(master_secret, 32);
crypto_sha256_hmac_final(CRYPTO_MASTER_KEY, 0, privkey);
memmove(fixed_vector_hmac, privkey, 32);
fixed_vector_iter=31;
/*privkey[31] += 1;*/
for (i = 31; i > -1; i++)
{
privkey[i] += 1;
if (privkey[i] != 0)
break;
}
// There isn't a CC310 function for calculating a public key from a private,
// so to get around it, we can "fix" the RNG input to GenKeyPair
if(pubkey != NULL)
{
ret = CRYS_ECPKI_GenKeyPair(&rndState_ptr,
fixed_vector,
/*CRYS_RND_GenerateVector,*/
_es256_curve,
&nrfpriv, &nrfpub, &tmp, NULL);
if (ret != SA_SILIB_RET_OK){
printf(" gen key failed with 0x%x \n",ret);
exit(1);
}
/*sz = 32;*/
/*ret = CRYS_ECPKI_ExportPrivKey(&nrfpriv, privkey, &sz);*/
/*if (ret != 0)*/
/*{*/
/*printf("privkey export fail\n");*/
/*exit(1);*/
/*}*/
sz = 65;
ret = CRYS_ECPKI_ExportPublKey(&nrfpub,CRYS_EC_PointUncompressed , pubkey1, &sz);
if (ret != 0 || sz != 65)
{
printf("pubkey export fail 0x%04x\n",ret);
exit(1);
}
if (pubkey1[0] != 0x04)
{
printf("pubkey uncompressed export fail 0x%02x\n",(int)pubkey1[0]);
exit(1);
}
memmove(pubkey, pubkey1+1 , 64);
}
}
void generate_private_key(uint8_t * data, int len, uint8_t * data2, int len2, uint8_t * privkey)
{
derive_private_key_pair(data,len,data2,len2,privkey,NULL);
}
struct AES_ctx aes_ctx;
void crypto_aes256_init(uint8_t * key, uint8_t * nonce)
{
if (key == CRYPTO_TRANSPORT_KEY)
{
AES_init_ctx(&aes_ctx, transport_secret);
}
else
{
AES_init_ctx(&aes_ctx, key);
}
if (nonce == NULL)
{
memset(aes_ctx.Iv, 0, 16);
}
else
{
memmove(aes_ctx.Iv, nonce, 16);
}
}
// prevent round key recomputation
void crypto_aes256_reset_iv(uint8_t * nonce)
{
if (nonce == NULL)
{
memset(aes_ctx.Iv, 0, 16);
}
else
{
memmove(aes_ctx.Iv, nonce, 16);
}
}
void crypto_aes256_decrypt(uint8_t * buf, int length)
{
AES_CBC_decrypt_buffer(&aes_ctx, buf, length);
}
void crypto_aes256_encrypt(uint8_t * buf, int length)
{
AES_CBC_encrypt_buffer(&aes_ctx, buf, length);
}
const uint8_t attestation_cert_der[] =
"\x30\x82\x01\xfb\x30\x82\x01\xa1\xa0\x03\x02\x01\x02\x02\x01\x00\x30\x0a\x06\x08"
"\x2a\x86\x48\xce\x3d\x04\x03\x02\x30\x2c\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13"
"\x02\x55\x53\x31\x0b\x30\x09\x06\x03\x55\x04\x08\x0c\x02\x4d\x44\x31\x10\x30\x0e"
"\x06\x03\x55\x04\x0a\x0c\x07\x54\x45\x53\x54\x20\x43\x41\x30\x20\x17\x0d\x31\x38"
"\x30\x35\x31\x30\x30\x33\x30\x36\x32\x30\x5a\x18\x0f\x32\x30\x36\x38\x30\x34\x32"
"\x37\x30\x33\x30\x36\x32\x30\x5a\x30\x7c\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13"
"\x02\x55\x53\x31\x0b\x30\x09\x06\x03\x55\x04\x08\x0c\x02\x4d\x44\x31\x0f\x30\x0d"
"\x06\x03\x55\x04\x07\x0c\x06\x4c\x61\x75\x72\x65\x6c\x31\x15\x30\x13\x06\x03\x55"
"\x04\x0a\x0c\x0c\x54\x45\x53\x54\x20\x43\x4f\x4d\x50\x41\x4e\x59\x31\x22\x30\x20"
"\x06\x03\x55\x04\x0b\x0c\x19\x41\x75\x74\x68\x65\x6e\x74\x69\x63\x61\x74\x6f\x72"
"\x20\x41\x74\x74\x65\x73\x74\x61\x74\x69\x6f\x6e\x31\x14\x30\x12\x06\x03\x55\x04"
"\x03\x0c\x0b\x63\x6f\x6e\x6f\x72\x70\x70\x2e\x63\x6f\x6d\x30\x59\x30\x13\x06\x07"
"\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00"
"\x04\x45\xa9\x02\xc1\x2e\x9c\x0a\x33\xfa\x3e\x84\x50\x4a\xb8\x02\xdc\x4d\xb9\xaf"
"\x15\xb1\xb6\x3a\xea\x8d\x3f\x03\x03\x55\x65\x7d\x70\x3f\xb4\x02\xa4\x97\xf4\x83"
"\xb8\xa6\xf9\x3c\xd0\x18\xad\x92\x0c\xb7\x8a\x5a\x3e\x14\x48\x92\xef\x08\xf8\xca"
"\xea\xfb\x32\xab\x20\xa3\x62\x30\x60\x30\x46\x06\x03\x55\x1d\x23\x04\x3f\x30\x3d"
"\xa1\x30\xa4\x2e\x30\x2c\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x53\x31"
"\x0b\x30\x09\x06\x03\x55\x04\x08\x0c\x02\x4d\x44\x31\x10\x30\x0e\x06\x03\x55\x04"
"\x0a\x0c\x07\x54\x45\x53\x54\x20\x43\x41\x82\x09\x00\xf7\xc9\xec\x89\xf2\x63\x94"
"\xd9\x30\x09\x06\x03\x55\x1d\x13\x04\x02\x30\x00\x30\x0b\x06\x03\x55\x1d\x0f\x04"
"\x04\x03\x02\x04\xf0\x30\x0a\x06\x08\x2a\x86\x48\xce\x3d\x04\x03\x02\x03\x48\x00"
"\x30\x45\x02\x20\x18\x38\xb0\x45\x03\x69\xaa\xa7\xb7\x38\x62\x01\xaf\x24\x97\x5e"
"\x7e\x74\x64\x1b\xa3\x7b\xf7\xe6\xd3\xaf\x79\x28\xdb\xdc\xa5\x88\x02\x21\x00\xcd"
"\x06\xf1\xe3\xab\x16\x21\x8e\xd8\xc0\x14\xaf\x09\x4f\x5b\x73\xef\x5e\x9e\x4b\xe7"
"\x35\xeb\xdd\x9b\x6d\x8f\x7d\xf3\xc4\x3a\xd7";
const uint16_t attestation_cert_der_size = sizeof(attestation_cert_der)-1;
const uint8_t attestation_key[] = "\xcd\x67\xaa\x31\x0d\x09\x1e\xd1\x6e\x7e\x98\x92\xaa\x07\x0e\x19\x94\xfc\xd7\x14\xae\x7c\x40\x8f\xb9\x46\xb7\x2e\x5f\xe7\x5d\x30";
const uint16_t attestation_key_size = sizeof(attestation_key)-1;

View File

@ -1,286 +0,0 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Solo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
/*
* Device specific functionality here
* */
#define DEBUG
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include "nrf.h"
#include "nrf_error.h"
#include "nrf_drv_power.h"
#include "nrf_strerror.h"
#include "nrf_drv_rtc.h"
#include "nrf_drv_clock.h"
#include "nrf_drv_usbd.h"
#include "nrf_gpio.h"
#include "bsp.h"
#include "app_error.h"
#include "app_fifo.h"
#include "util.h"
#include "usb.h"
#include "device.h"
#include "cbor.h"
#include "log.h"
extern int _SEGGER_TERM;
void set_output_terminal(uint32_t term)
{
_SEGGER_TERM = term;
}
void app_error_fault_handler(uint32_t id, uint32_t pc, uint32_t info)
{
error_info_t * e = (error_info_t *)info;
printf("Error: %d: %s at %d:%s\n",e->err_code, nrf_strerror_get(e->err_code), e->line_num, e->p_file_name);
while(1)
;
}
void log_resetreason(void)
{
/* Reset reason */
uint32_t rr = nrf_power_resetreas_get();
printf("Reset reasons:\n");
if (0 == rr)
{
printf("- NONE\n");
}
if (0 != (rr & NRF_POWER_RESETREAS_RESETPIN_MASK))
{
printf("- RESETPIN\n");
}
if (0 != (rr & NRF_POWER_RESETREAS_DOG_MASK ))
{
printf("- DOG\n");
}
if (0 != (rr & NRF_POWER_RESETREAS_SREQ_MASK ))
{
printf("- SREQ\n");
}
if (0 != (rr & NRF_POWER_RESETREAS_LOCKUP_MASK ))
{
printf("- LOCKUP\n");
}
if (0 != (rr & NRF_POWER_RESETREAS_OFF_MASK ))
{
printf("- OFF\n");
}
if (0 != (rr & NRF_POWER_RESETREAS_LPCOMP_MASK ))
{
printf("- LPCOMP\n");
}
if (0 != (rr & NRF_POWER_RESETREAS_DIF_MASK ))
{
printf("- DIF\n");
}
if (0 != (rr & NRF_POWER_RESETREAS_NFC_MASK ))
{
printf("- NFC\n");
}
if (0 != (rr & NRF_POWER_RESETREAS_VBUS_MASK ))
{
printf("- VBUS\n");
}
}
static const nrf_drv_rtc_t rtc = NRF_DRV_RTC_INSTANCE(0); /**< Declaring an instance of nrf_drv_rtc for RTC0. */
uint64_t millis()
{
return (uint64_t)nrf_drv_rtc_counter_get(&rtc);
}
static void rtc_config(void)
{
uint32_t err_code;
//Initialize RTC instance
nrf_drv_rtc_config_t config = NRF_DRV_RTC_DEFAULT_CONFIG;
config.prescaler = 32;
err_code = nrf_drv_rtc_init(&rtc, &config, NULL);
APP_ERROR_CHECK(err_code);
//Power on RTC instance
nrf_drv_rtc_enable(&rtc);
}
static void init_power_clock(void)
{
ret_code_t ret;
/* Initializing power and clock */
ret = nrf_drv_clock_init();
APP_ERROR_CHECK(ret);
ret = nrf_drv_power_init(NULL);
APP_ERROR_CHECK(ret);
nrf_drv_clock_hfclk_request(NULL);
nrf_drv_clock_lfclk_request(NULL);
while (!(nrf_drv_clock_hfclk_is_running() &&
nrf_drv_clock_lfclk_is_running()))
{
/* Just waiting */
}
}
void device_init()
{
if ((nrf_power_resetreas_get() & NRF_POWER_RESETREAS_RESETPIN_MASK) == 0)
{
// Hard reset. this is for engineering A sample to work for USB ...
nrf_power_resetreas_clear(nrf_power_resetreas_get());
nrf_gpio_cfg_output(NRF_GPIO_PIN_MAP(0,31));
nrf_gpio_pin_clear(NRF_GPIO_PIN_MAP(0,31));
while (1)
;
}
nrf_power_resetreas_clear(nrf_power_resetreas_get());
set_output_terminal(0);
init_power_clock();
rtc_config();
usbhid_init();
srand(millis());
nrf_gpio_cfg_output(LED_1);
nrf_gpio_cfg_output(LED_2);
nrf_gpio_cfg_output(LED_3);
nrf_gpio_cfg_output(LED_4);
nrf_gpio_pin_toggle(LED_2);
nrf_gpio_pin_toggle(LED_3);
}
static uint8_t fifo_buf[1024];
app_fifo_t USBHID_RECV_FIFO;
void usbhid_init()
{
#ifndef TEST_POWER
app_fifo_init(&USBHID_RECV_FIFO, fifo_buf, sizeof(fifo_buf));
usb_init();
#endif
}
// Receive 64 byte USB HID message, don't block, return size of packet, return 0 if nothing
#ifndef TEST_POWER
int usbhid_recv(uint8_t * msg)
{
uint32_t size = 64;
app_fifo_read(&USBHID_RECV_FIFO, msg, &size);
return size;
}
#endif
// Send 64 byte USB HID message
void usbhid_send(uint8_t * msg)
{
static nrf_drv_usbd_transfer_t transfer;
transfer.p_data.tx = msg;
transfer.size = 64;
while (nrf_drv_usbd_ep_is_busy(NRF_DRV_USBD_EPIN1))
;
nrf_drv_usbd_ep_transfer(
NRF_DRV_USBD_EPIN1,
&transfer);
}
void usbhid_close()
{
}
void main_loop_delay()
{
// no delay on embedded system
}
void heartbeat()
{
nrf_gpio_pin_toggle(LED_1);
nrf_gpio_pin_toggle(LED_2);
nrf_gpio_pin_toggle(LED_3);
nrf_gpio_pin_toggle(LED_4);
}
#ifndef TEST_POWER
void ctaphid_write_block(uint8_t * data)
{
printf1(TAG_DUMP,"<< "); dump_hex1(TAG_DUMP,data, 64);
usbhid_send(data);
}
#endif
int ctap_user_presence_test()
{
return 1;
}
int ctap_user_verification(uint8_t arg)
{
return 1;
}
uint32_t ctap_atomic_count(int sel)
{
static uint32_t counter1 = 25;
static uint32_t counter2 = 25;
/*return 713;*/
if (sel == 0)
{
printf1(TAG_RED,"counter1: %d\n", counter1);
return counter1++;
}
else
{
return counter2++;
}
}
int ctap_generate_rng(uint8_t * dst, size_t num)
{
int i;
for (i = 0; i < num; i++)
{
*dst++ = (uint8_t)rand();
}
return 1;
}

View File

@ -1,42 +0,0 @@
#
# Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
#
# This file is part of Solo.
#
# Solo is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Solo is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Solo. If not, see <https://www.gnu.org/licenses/>
#
# This code is available under licenses for commercial use.
# Please contact SoloKeys for more information.
#
from fido2.hid import CtapHidDevice
from fido2.client import Fido2Client
from fido2.pyu2f import hidtransport
import sys
from random import randint
import array
# Locate a device
for d in CtapHidDevice.list_devices():
print(d)
#selector = hidtransport.HidUsageSelector
#for d in hidtransport.hid.Enumerate():
#print('1',d)
#if selector(d):
#try:
#dev = hidtransport.hid.Open(d['path'])
#print('2',dev)
#except OSError:
## Insufficient permissions to access device
#pass

View File

@ -1,101 +0,0 @@
/**
* Copyright (c) 2014 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS 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.
*
*/
/** @file
*
* @defgroup blinky_example_main main.c
* @{
* @ingroup blinky_example
* @brief Blinky Example Application main file.
*
* This file contains the source code for a sample application to blink LEDs.
*
*/
#define DEBUG
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include "nrf.h"
#include "nrf_delay.h"
#include "boards.h"
#include "device.h"
#include "time.h"
#include "util.h"
int main(void)
{
/* Configure board. */
uint8_t hidmsg[64];
uint32_t count = 0;
uint32_t beat = 0;
uint32_t t1 = 0;
printf("hello FIDO2\r\n");
device_init();
while(1)
{
if (millis() - t1 > 1000)
{
printf("heartbeat %ld\n", beat++);
t1 = millis();
}
if (usbhid_recv(hidmsg) > 0)
{
printf("%d>> ",count++); dump_hex(hidmsg,sizeof(hidmsg));
/*ctaphid_handle_packet(hidmsg);*/
memset(hidmsg, 0, sizeof(hidmsg));
}
/*u2f_hid_check_timeouts();*/
main_loop_delay();
}
}

View File

@ -1,39 +0,0 @@
#!/usr/bin/python
#
# Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
#
# This file is part of Solo.
#
# Solo is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Solo is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Solo. If not, see <https://www.gnu.org/licenses/>
#
# This code is available under licenses for commercial use.
# Please contact SoloKeys for more information.
#
import serial, sys
from sys import argv
if len(argv) not in [2,3]:
print('usage: %s <com-port> [baud-rate]' % argv[0])
sys.exit(1)
baud = 115200
if len(argv) > 2:
baud = int(argv[2])
ser = serial.Serial(argv[1],baud)
print('reading..')
sys.stdout.flush()
while True:
sys.stdout.write(ser.read())

View File

@ -1,102 +0,0 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Solo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
#include "nrf.h"
#include "SEGGER_RTT.h"
int _SEGGER_TERM = 0;
void set_logging_tag(uint32_t tag)
{
int term = 0;
while (tag)
{
if (tag & 1)
break;
term++;
tag = tag >> 1;
}
_SEGGER_TERM = term;
}
#if defined(__CC_ARM)
int fgetc(FILE * p_file)
{
return '0';
}
int fputc(int ch, FILE * p_file)
{
SEGGER_RTT_PutChar(_SEGGER_TERM, ch);
return ch;
}
#elif defined(__GNUC__) && defined(__SES_ARM)
int __getchar(FILE * p_file)
{
return '0';
}
int __putchar(int ch, FILE * p_file)
{
SEGGER_RTT_PutChar(_SEGGER_TERM, ch);
return ch;
}
#elif defined(__GNUC__) && !defined(__SES_ARM)
int _write(int file, const char * p_char, int len)
{
int i;
static int lastterm = -1;
/*char buf[2];*/
/*buf[1] = 0;*/
UNUSED_PARAMETER(file);
if (_SEGGER_TERM != lastterm)
{
SEGGER_RTT_SetTerminal(_SEGGER_TERM);
lastterm = _SEGGER_TERM;
}
for (i = 0; i < len; i++)
{
/*buf[0] = *p_char++;*/
SEGGER_RTT_PutChar(0, *p_char++);
/*SEGGER_RTT_TerminalOut(_SEGGER_TERM, buf);*/
}
return len;
}
int _read(int file, char * p_char, int len)
{
*p_char = '0';
return 1;
}
#else
/*#elif defined(__ICCARM__)*/
#error "No read/write for printing implemented for compiler"
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,31 +0,0 @@
/*
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
*
* This file is part of Solo.
*
* Solo is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Solo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Solo. If not, see <https://www.gnu.org/licenses/>
*
* This code is available under licenses for commercial use.
* Please contact SoloKeys for more information.
*/
#ifndef _USB_H
#define _USB_H
#include "app_fifo.h"
void usb_init(void);
extern app_fifo_t USBHID_RECV_FIFO;
#endif

View File

@ -1 +0,0 @@