delete non-supported platforms
This commit is contained in:
parent
ed676151f1
commit
45eaef2663
File diff suppressed because one or more lines are too long
@ -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>
|
|
@ -1,2 +0,0 @@
|
|||||||
copiedFilesOriginState={}
|
|
||||||
eclipse.preferences.version=1
|
|
@ -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}}
|
|
@ -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
|
|
@ -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
|
|
||||||
}
|
|
@ -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 → DefaultMode" propertyId="modeTransition.source" value="RESET"/>
|
|
||||||
<property object="RESET → DefaultMode" propertyId="modeTransition.target" value="DefaultMode"/>
|
|
||||||
</modeTransition>
|
|
||||||
</device:XMLDevice>
|
|
@ -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 → DefaultMode" propertyId="modeTransition.source" value="RESET"/>
|
|
||||||
<property object="RESET → DefaultMode" propertyId="modeTransition.target" value="DefaultMode"/>
|
|
||||||
</modeTransition>
|
|
||||||
</device:XMLDevice>
|
|
@ -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
@ -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
@ -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
@ -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) */
|
|
@ -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) */
|
|
@ -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
@ -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) */
|
|
@ -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
@ -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
|
|
||||||
|
|
@ -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_ */
|
|
@ -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 */
|
|
@ -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_ */
|
|
@ -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]$
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -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;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -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
|
|
@ -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"
|
|
@ -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
|
|
@ -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
|
|
@ -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) */
|
|
@ -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="[{"builtinExcludes":[],"builtinSources":[],"builtin":true,"module":"<project:MModule xmlns:project=\"http://www.silabs.com/ss/Project.ecore\" builtin=\"true\" id=\"com.silabs.sdk.exx32.common.drivers\">\r\n <exclusions pattern=\".*\"/>\r\n</project:MModule>"},{"builtinExcludes":[],"builtinSources":[],"builtin":true,"module":"<project:MModule xmlns:project=\"http://www.silabs.com/ss/Project.ecore\" builtin=\"true\" id=\"com.silabs.sdk.exx32.common.bsp\">\r\n <exclusions pattern=\".*\"/>\r\n</project:MModule>"},{"builtinExcludes":[],"builtinSources":["CMSIS/EFM32JG1B/startup_gcc_efm32jg1b.s","CMSIS/EFM32JG1B/system_efm32jg1b.c"],"builtin":true,"module":"<project:MModule xmlns:project=\"http://www.silabs.com/ss/Project.ecore\" builtin=\"true\" id=\"com.silabs.sdk.exx32.part\"/>"},{"builtinExcludes":[],"builtinSources":[],"builtin":true,"module":"<project:MModule xmlns:project=\"http://www.silabs.com/ss/Project.ecore\" builtin=\"true\" id=\"com.silabs.sdk.exx32.common.CMSIS\">\r\n <exclusions pattern=\".*\"/>\r\n</project:MModule>"},{"builtinExcludes":[],"builtinSources":["emlib/em_gpio.c","emlib/em_system.c","emlib/em_cmu.c","emlib/em_assert.c","emlib/em_emu.c"],"builtin":true,"module":"<project:MModule xmlns:project=\"http://www.silabs.com/ss/Project.ecore\" builtin=\"true\" id=\"com.silabs.sdk.exx32.common.emlib\">\r\n <inclusions pattern=\"emlib/em_system.c\"/>\r\n <inclusions pattern=\"emlib/em_emu.c\"/>\r\n <inclusions pattern=\"emlib/em_cmu.c\"/>\r\n <inclusions pattern=\"emlib/em_device.c\"/>\r\n <inclusions pattern=\"emlib/em_chip.c\"/>\r\n <inclusions pattern=\"emlib/em_assert.c\"/>\r\n <inclusions pattern=\"emlib/em_gpio.c\"/>\r\n</project:MModule>"},{"builtinExcludes":[],"builtinSources":[],"builtin":true,"module":"<project:MModule xmlns:project=\"http://www.silabs.com/ss/Project.ecore\" builtin=\"true\" id=\"com.silabs.sdk.exx32.board\"/>"}]" 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=""${workspace_loc:/${ProjName}/inc}""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${ProjDirPath}/inc""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${ProjDirPath}/../efm32/inc""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${ProjDirPath}/../../fido2""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${ProjDirPath}/../../fido2/extensions""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${ProjDirPath}/../../tinycbor/src""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${ProjDirPath}/../../crypto/sha256""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${ProjDirPath}/../../crypto/micro-ecc""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${ProjDirPath}/../../crypto/tiny-AES-c""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/hardware/kit/common/bsp""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/hardware/kit/common/drivers""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/platform/Device/SiliconLabs/EFM32JG1B/Include""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/platform/CMSIS/Include""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/platform/emlib/inc""/>
|
|
||||||
</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=""${workspace_loc:/${ProjName}/inc}""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${ProjDirPath}/inc""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/hardware/kit/common/bsp""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/hardware/kit/common/drivers""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/platform/Device/SiliconLabs/EFM32JG1B/Include""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/platform/CMSIS/Include""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/platform/emlib/inc""/>
|
|
||||||
</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="[{"builtinExcludes":[],"builtinSources":["emlib/em_gpio.c","emlib/em_system.c","emlib/em_cmu.c","emlib/em_assert.c","emlib/em_emu.c"],"builtin":true,"module":"<project:MModule xmlns:project=\"http://www.silabs.com/ss/Project.ecore\" builtin=\"true\" id=\"com.silabs.sdk.exx32.common.emlib\">\r\n <inclusions pattern=\"emlib/em_system.c\"/>\r\n <inclusions pattern=\"emlib/em_emu.c\"/>\r\n <inclusions pattern=\"emlib/em_cmu.c\"/>\r\n <inclusions pattern=\"emlib/em_device.c\"/>\r\n <inclusions pattern=\"emlib/em_chip.c\"/>\r\n <inclusions pattern=\"emlib/em_assert.c\"/>\r\n <inclusions pattern=\"emlib/em_gpio.c\"/>\r\n</project:MModule>"},{"builtinExcludes":[],"builtinSources":[],"builtin":true,"module":"<project:MModule xmlns:project=\"http://www.silabs.com/ss/Project.ecore\" builtin=\"true\" id=\"com.silabs.sdk.exx32.board\"/>"},{"builtinExcludes":[],"builtinSources":["CMSIS/EFM32PG1B/startup_gcc_efm32pg1b.s","CMSIS/EFM32PG1B/system_efm32pg1b.c"],"builtin":true,"module":"<project:MModule xmlns:project=\"http://www.silabs.com/ss/Project.ecore\" builtin=\"true\" id=\"com.silabs.sdk.exx32.part\"/>"},{"builtinExcludes":[],"builtinSources":[],"builtin":true,"module":"<project:MModule xmlns:project=\"http://www.silabs.com/ss/Project.ecore\" builtin=\"true\" id=\"com.silabs.sdk.exx32.common.bsp\">\r\n <exclusions pattern=\".*\"/>\r\n</project:MModule>"},{"builtinExcludes":[],"builtinSources":[],"builtin":true,"module":"<project:MModule xmlns:project=\"http://www.silabs.com/ss/Project.ecore\" builtin=\"true\" id=\"com.silabs.sdk.exx32.common.drivers\">\r\n <exclusions pattern=\".*\"/>\r\n</project:MModule>"},{"builtinExcludes":[],"builtinSources":[],"builtin":true,"module":"<project:MModule xmlns:project=\"http://www.silabs.com/ss/Project.ecore\" builtin=\"true\" id=\"com.silabs.sdk.exx32.common.CMSIS\">\r\n <exclusions pattern=\".*\"/>\r\n</project:MModule>"}]" 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=""${workspace_loc:/${ProjName}/inc}""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${ProjDirPath}/inc""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/hardware/kit/common/bsp""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/hardware/kit/SLSTK3401A_EFM32PG/config""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/hardware/kit/common/drivers""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/platform/Device/SiliconLabs/EFM32PG1B/Include""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/platform/CMSIS/Include""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/platform/emlib/inc""/>
|
|
||||||
</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=""${workspace_loc:/${ProjName}/inc}""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${ProjDirPath}/inc""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/hardware/kit/common/bsp""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/hardware/kit/SLSTK3401A_EFM32PG/config""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/hardware/kit/common/drivers""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/platform/Device/SiliconLabs/EFM32PG1B/Include""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/platform/CMSIS/Include""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/platform/emlib/inc""/>
|
|
||||||
</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>
|
|
@ -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>
|
|
@ -1,2 +0,0 @@
|
|||||||
copiedFilesOriginState={}
|
|
||||||
eclipse.preferences.version=1
|
|
@ -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
|
|
@ -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
|
|
||||||
}
|
|
@ -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 → DefaultMode" propertyId="modeTransition.source" value="RESET"/>
|
|
||||||
<property object="RESET → DefaultMode" propertyId="modeTransition.target" value="DefaultMode"/>
|
|
||||||
</modeTransition>
|
|
||||||
</device:XMLDevice>
|
|
@ -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
@ -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
@ -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
@ -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) */
|
|
@ -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
@ -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_ */
|
|
@ -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);
|
|
||||||
}
|
|
@ -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
|
|
||||||
|
|
||||||
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -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="[{"builtinExcludes":[],"builtinSources":["lib/efm8ub1/peripheralDrivers/src/usb_0.c","lib/efm8ub1/peripheralDrivers/inc/usb_0.h"],"builtin":true,"module":"<project:MModule xmlns:project=\"http://www.silabs.com/ss/Project.ecore\" builtin=\"true\" id=\"com.silabs.sdk.si8051.external.efm8PeripheralDriver.usb0\"/>"},{"builtinExcludes":[],"builtinSources":["lib/efm8_assert/assert.c","lib/efm8_assert/assert.h"],"builtin":true,"module":"<project:MModule xmlns:project=\"http://www.silabs.com/ss/Project.ecore\" builtin=\"true\" id=\"com.silabs.sdk.si8051.external.efm8Library.assert\"/>"},{"builtinExcludes":[],"builtinSources":["lib/efm8_usb/inc/efm8_usb.h","lib/efm8_usb/src/efm8_usbd.c","lib/efm8_usb/src/efm8_usbdch9.c","lib/efm8_usb/src/efm8_usbdep.c","lib/efm8_usb/src/efm8_usbdint.c","lib/efm8_usb/Readme.txt"],"builtin":true,"module":"<project:MModule xmlns:project=\"http://www.silabs.com/ss/Project.ecore\" builtin=\"true\" id=\"com.silabs.sdk.si8051.external.efm8Library.usb\"/>"},{"builtinExcludes":[],"builtinSources":["src/SILABS_STARTUP.A51"],"builtin":true,"module":"<project:MModule xmlns:project=\"http://www.silabs.com/ss/Project.ecore\" builtin=\"true\" id=\"com.silabs.sdk.si8051.shared\"/>"},{"builtinExcludes":[],"builtinSources":[],"builtin":true,"module":"<project:MModule xmlns:project=\"http://www.silabs.com/ss/Project.ecore\" builtin=\"true\" id=\"com.silabs.sdk.si8051.external.efm8Library.usbc\"/>"}]" 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=""${workspace_loc:/${ProjName}/inc}""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/inc/config}""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/Lib/efm8_usb/inc""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/Lib/efm8_assert""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/Device/EFM8UB1/peripheral_driver/inc""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/Device/shared/si8051base""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/Device/EFM8UB1/inc""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/Lib/efm8_usbc/lib_kernel/inc""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/Lib/efm8_usbc/lib_usbc_pd/inc""/>
|
|
||||||
</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=""${workspace_loc:/${ProjName}/inc}""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/inc/config}""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/Lib/efm8_usb/inc""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/Lib/efm8_assert""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/Device/EFM8UB1/peripheral_driver/inc""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/Device/shared/si8051base""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/Device/EFM8UB1/inc""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/Lib/efm8_usbc/lib_kernel/inc""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/Lib/efm8_usbc/lib_usbc_pd/inc""/>
|
|
||||||
</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="[{"builtinExcludes":[],"builtinSources":[],"builtin":true,"module":"<project:MModule xmlns:project=\"http://www.silabs.com/ss/Project.ecore\" builtin=\"true\" id=\"com.silabs.sdk.si8051.external.efm8Library.usbc\"/>"},{"builtinExcludes":[],"builtinSources":["lib/efm8ub1/peripheralDrivers/src/usb_0.c","lib/efm8ub1/peripheralDrivers/inc/usb_0.h"],"builtin":true,"module":"<project:MModule xmlns:project=\"http://www.silabs.com/ss/Project.ecore\" builtin=\"true\" id=\"com.silabs.sdk.si8051.external.efm8PeripheralDriver.usb0\"/>"},{"builtinExcludes":[],"builtinSources":["lib/efm8_usb/inc/efm8_usb.h","lib/efm8_usb/src/efm8_usbd.c","lib/efm8_usb/src/efm8_usbdch9.c","lib/efm8_usb/src/efm8_usbdep.c","lib/efm8_usb/src/efm8_usbdint.c","lib/efm8_usb/Readme.txt"],"builtin":true,"module":"<project:MModule xmlns:project=\"http://www.silabs.com/ss/Project.ecore\" builtin=\"true\" id=\"com.silabs.sdk.si8051.external.efm8Library.usb\"/>"},{"builtinExcludes":[],"builtinSources":["lib/efm8_assert/assert.c","lib/efm8_assert/assert.h"],"builtin":true,"module":"<project:MModule xmlns:project=\"http://www.silabs.com/ss/Project.ecore\" builtin=\"true\" id=\"com.silabs.sdk.si8051.external.efm8Library.assert\"/>"},{"builtinExcludes":[],"builtinSources":["src/SILABS_STARTUP.A51"],"builtin":true,"module":"<project:MModule xmlns:project=\"http://www.silabs.com/ss/Project.ecore\" builtin=\"true\" id=\"com.silabs.sdk.si8051.shared\"/>"}]" 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=""${workspace_loc:/${ProjName}/inc}""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/inc/config}""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/Lib/efm8_usb/inc""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/Lib/efm8_assert""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/Device/EFM8UB1/peripheral_driver/inc""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/Device/shared/si8051base""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/Device/EFM8UB1/inc""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/Lib/efm8_usbc/lib_kernel/inc""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/Lib/efm8_usbc/lib_usbc_pd/inc""/>
|
|
||||||
</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=""${workspace_loc:/${ProjName}/inc}""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/inc/config}""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/Lib/efm8_usb/inc""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/Lib/efm8_assert""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/Device/EFM8UB1/peripheral_driver/inc""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/Device/shared/si8051base""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/Device/EFM8UB1/inc""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/Lib/efm8_usbc/lib_kernel/inc""/>
|
|
||||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/Lib/efm8_usbc/lib_usbc_pd/inc""/>
|
|
||||||
</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>
|
|
@ -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>
|
|
@ -1,2 +0,0 @@
|
|||||||
copiedFilesOriginState={}
|
|
||||||
eclipse.preferences.version=1
|
|
@ -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
|
|
@ -1,2 +0,0 @@
|
|||||||
eclipse.preferences.version=1
|
|
||||||
org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
|
|
@ -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 → DefaultMode" propertyId="modeTransition.source" value="RESET"/>
|
|
||||||
<property object="RESET → DefaultMode" propertyId="modeTransition.target" value="DefaultMode"/>
|
|
||||||
</modeTransition>
|
|
||||||
</device:XMLDevice>
|
|
@ -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
|
|
||||||
|
|
@ -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_ */
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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
|
|
@ -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__
|
|
@ -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
@ -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
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -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
|
|
@ -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
@ -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) */
|
|
@ -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]$
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -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
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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++;
|
|
||||||
}
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -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
|
|
@ -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)
|
|
@ -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
|
|
||||||
|
|
||||||
|
|
@ -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"
|
|
@ -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;
|
|
||||||
|
|
||||||
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -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
|
|
@ -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();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -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())
|
|
@ -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
@ -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
|
|
@ -1 +0,0 @@
|
|||||||
|
|
Loading…
x
Reference in New Issue
Block a user