Camera_driver: refactored version of camera driver
This commit is contained in:
@ -0,0 +1,44 @@
|
||||
/*------------------------------------------------------------------------------
|
||||
* MDK - Component ::Event Recorder
|
||||
* Copyright (c) 2016 ARM Germany GmbH. All rights reserved.
|
||||
*------------------------------------------------------------------------------
|
||||
* Name: EventRecorderConf.h
|
||||
* Purpose: Event Recorder Configuration
|
||||
* Rev.: V1.0.0
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
//-------- <<< Use Configuration Wizard in Context Menu >>> --------------------
|
||||
|
||||
// <h>Event Recorder
|
||||
|
||||
// <o>Number of Records
|
||||
// <8=>8 <16=>16 <32=>32 <64=>64 <128=>128 <256=>256 <512=>512 <1024=>1024
|
||||
// <2048=>2048 <4096=>4096 <8192=>8192 <16384=>16384 <32768=>32768
|
||||
// <65536=>65536 <131072=>131072 <262144=>262144 <524288=>524288
|
||||
// <1048576=>1048576
|
||||
// <i>Configure size of Event Record Buffer (each record is 16 bytes)
|
||||
// <i>Must be 2^n (min=8, max=1048576)
|
||||
#define EVENT_RECORD_COUNT 64U
|
||||
|
||||
// <o>Time Stamp Source
|
||||
// <0=> DWT Cycle Counter <1=> SysTick
|
||||
// <3=> User Timer (Normal Reset) <4=> User Timer (Power-On Reset)
|
||||
// <i>Selects source for 32-bit time stamp
|
||||
#define EVENT_TIMESTAMP_SOURCE 1
|
||||
|
||||
// <h>SysTick Configuration
|
||||
// <i>Configure values when Time Stamp Source is set to SysTick
|
||||
|
||||
// <o>SysTick Input Clock Frequency [Hz] <1-1000000000>
|
||||
// <i>Defines SysTick input clock (typical identical with processor clock)
|
||||
#define SYSTICK_CLOCK 100000000U
|
||||
|
||||
// <o>SysTick Interrupt Period [us] <1-1000000000>
|
||||
// <i>Defines time period of the SysTick timer interrupt
|
||||
#define SYSTICK_PERIOD_US 1000U
|
||||
|
||||
// </h>
|
||||
|
||||
// </h>
|
||||
|
||||
//------------- <<< end of configuration section >>> ---------------------------
|
@ -0,0 +1,242 @@
|
||||
;/**************************************************************************//**
|
||||
; * @file startup_ARMCM0.s
|
||||
; * @brief CMSIS Core Device Startup File for
|
||||
; * ARMCM0 Device Series
|
||||
; * @version V5.00
|
||||
; * @date 02. March 2016
|
||||
; ******************************************************************************/
|
||||
;/*
|
||||
; * Copyright (c) 2009-2016 ARM Limited. All rights reserved.
|
||||
; *
|
||||
; * 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
|
||||
; *
|
||||
; * 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.
|
||||
; */
|
||||
|
||||
;/*
|
||||
;//-------- <<< Use Configuration Wizard in Context Menu >>> ------------------
|
||||
;*/
|
||||
|
||||
|
||||
; <h> Stack Configuration
|
||||
; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
|
||||
; </h>
|
||||
|
||||
Stack_Size EQU 0x00000400
|
||||
|
||||
AREA STACK, NOINIT, READWRITE, ALIGN=3
|
||||
Stack_Mem SPACE Stack_Size
|
||||
__initial_sp
|
||||
|
||||
|
||||
; <h> Heap Configuration
|
||||
; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
|
||||
; </h>
|
||||
|
||||
Heap_Size EQU 0x00000C00
|
||||
|
||||
AREA HEAP, NOINIT, READWRITE, ALIGN=3
|
||||
__heap_base
|
||||
Heap_Mem SPACE Heap_Size
|
||||
__heap_limit
|
||||
|
||||
|
||||
PRESERVE8
|
||||
THUMB
|
||||
|
||||
|
||||
; Vector Table Mapped to Address 0 at Reset
|
||||
|
||||
AREA RESET, DATA, READONLY
|
||||
EXPORT __Vectors
|
||||
EXPORT __Vectors_End
|
||||
EXPORT __Vectors_Size
|
||||
|
||||
__Vectors DCD __initial_sp ; Top of Stack
|
||||
DCD Reset_Handler ; Reset Handler
|
||||
DCD NMI_Handler ; NMI Handler
|
||||
DCD HardFault_Handler ; Hard Fault Handler
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD SVC_Handler ; SVCall Handler
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD PendSV_Handler ; PendSV Handler
|
||||
DCD SysTick_Handler ; SysTick Handler
|
||||
|
||||
; External Interrupts
|
||||
DCD WDT_IRQHandler ; 0: Watchdog Timer
|
||||
DCD RTC_IRQHandler ; 1: Real Time Clock
|
||||
DCD TIM0_IRQHandler ; 2: Timer0 / Timer1
|
||||
DCD TIM2_IRQHandler ; 3: Timer2 / Timer3
|
||||
DCD MCIA_IRQHandler ; 4: MCIa
|
||||
DCD MCIB_IRQHandler ; 5: MCIb
|
||||
DCD UART0_IRQHandler ; 6: UART0 - DUT FPGA
|
||||
DCD UART1_IRQHandler ; 7: UART1 - DUT FPGA
|
||||
DCD UART2_IRQHandler ; 8: UART2 - DUT FPGA
|
||||
DCD UART4_IRQHandler ; 9: UART4 - not connected
|
||||
DCD AACI_IRQHandler ; 10: AACI / AC97
|
||||
DCD CLCD_IRQHandler ; 11: CLCD Combined Interrupt
|
||||
DCD ENET_IRQHandler ; 12: Ethernet
|
||||
DCD USBDC_IRQHandler ; 13: USB Device
|
||||
DCD USBHC_IRQHandler ; 14: USB Host Controller
|
||||
DCD CHLCD_IRQHandler ; 15: Character LCD
|
||||
DCD FLEXRAY_IRQHandler ; 16: Flexray
|
||||
DCD CAN_IRQHandler ; 17: CAN
|
||||
DCD LIN_IRQHandler ; 18: LIN
|
||||
DCD I2C_IRQHandler ; 19: I2C ADC/DAC
|
||||
DCD 0 ; 20: Reserved
|
||||
DCD 0 ; 21: Reserved
|
||||
DCD 0 ; 22: Reserved
|
||||
DCD 0 ; 23: Reserved
|
||||
DCD 0 ; 24: Reserved
|
||||
DCD 0 ; 25: Reserved
|
||||
DCD 0 ; 26: Reserved
|
||||
DCD 0 ; 27: Reserved
|
||||
DCD CPU_CLCD_IRQHandler ; 28: Reserved - CPU FPGA CLCD
|
||||
DCD 0 ; 29: Reserved - CPU FPGA
|
||||
DCD UART3_IRQHandler ; 30: UART3 - CPU FPGA
|
||||
DCD SPI_IRQHandler ; 31: SPI Touchscreen - CPU FPGA
|
||||
__Vectors_End
|
||||
|
||||
__Vectors_Size EQU __Vectors_End - __Vectors
|
||||
|
||||
AREA |.text|, CODE, READONLY
|
||||
|
||||
|
||||
; Reset Handler
|
||||
|
||||
Reset_Handler PROC
|
||||
EXPORT Reset_Handler [WEAK]
|
||||
IMPORT SystemInit
|
||||
IMPORT __main
|
||||
LDR R0, =SystemInit
|
||||
BLX R0
|
||||
LDR R0, =__main
|
||||
BX R0
|
||||
ENDP
|
||||
|
||||
|
||||
; Dummy Exception Handlers (infinite loops which can be modified)
|
||||
|
||||
NMI_Handler PROC
|
||||
EXPORT NMI_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
HardFault_Handler\
|
||||
PROC
|
||||
EXPORT HardFault_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
SVC_Handler PROC
|
||||
EXPORT SVC_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
PendSV_Handler PROC
|
||||
EXPORT PendSV_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
SysTick_Handler PROC
|
||||
EXPORT SysTick_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
|
||||
Default_Handler PROC
|
||||
|
||||
EXPORT WDT_IRQHandler [WEAK]
|
||||
EXPORT RTC_IRQHandler [WEAK]
|
||||
EXPORT TIM0_IRQHandler [WEAK]
|
||||
EXPORT TIM2_IRQHandler [WEAK]
|
||||
EXPORT MCIA_IRQHandler [WEAK]
|
||||
EXPORT MCIB_IRQHandler [WEAK]
|
||||
EXPORT UART0_IRQHandler [WEAK]
|
||||
EXPORT UART1_IRQHandler [WEAK]
|
||||
EXPORT UART2_IRQHandler [WEAK]
|
||||
EXPORT UART3_IRQHandler [WEAK]
|
||||
EXPORT UART4_IRQHandler [WEAK]
|
||||
EXPORT AACI_IRQHandler [WEAK]
|
||||
EXPORT CLCD_IRQHandler [WEAK]
|
||||
EXPORT ENET_IRQHandler [WEAK]
|
||||
EXPORT USBDC_IRQHandler [WEAK]
|
||||
EXPORT USBHC_IRQHandler [WEAK]
|
||||
EXPORT CHLCD_IRQHandler [WEAK]
|
||||
EXPORT FLEXRAY_IRQHandler [WEAK]
|
||||
EXPORT CAN_IRQHandler [WEAK]
|
||||
EXPORT LIN_IRQHandler [WEAK]
|
||||
EXPORT I2C_IRQHandler [WEAK]
|
||||
EXPORT CPU_CLCD_IRQHandler [WEAK]
|
||||
EXPORT SPI_IRQHandler [WEAK]
|
||||
|
||||
WDT_IRQHandler
|
||||
RTC_IRQHandler
|
||||
TIM0_IRQHandler
|
||||
TIM2_IRQHandler
|
||||
MCIA_IRQHandler
|
||||
MCIB_IRQHandler
|
||||
UART0_IRQHandler
|
||||
UART1_IRQHandler
|
||||
UART2_IRQHandler
|
||||
UART3_IRQHandler
|
||||
UART4_IRQHandler
|
||||
AACI_IRQHandler
|
||||
CLCD_IRQHandler
|
||||
ENET_IRQHandler
|
||||
USBDC_IRQHandler
|
||||
USBHC_IRQHandler
|
||||
CHLCD_IRQHandler
|
||||
FLEXRAY_IRQHandler
|
||||
CAN_IRQHandler
|
||||
LIN_IRQHandler
|
||||
I2C_IRQHandler
|
||||
CPU_CLCD_IRQHandler
|
||||
SPI_IRQHandler
|
||||
B .
|
||||
|
||||
ENDP
|
||||
|
||||
|
||||
ALIGN
|
||||
|
||||
|
||||
; User Initial Stack & Heap
|
||||
|
||||
IF :DEF:__MICROLIB
|
||||
|
||||
EXPORT __initial_sp
|
||||
EXPORT __heap_base
|
||||
EXPORT __heap_limit
|
||||
|
||||
ELSE
|
||||
|
||||
IMPORT __use_two_region_memory
|
||||
EXPORT __user_initial_stackheap
|
||||
|
||||
__user_initial_stackheap PROC
|
||||
LDR R0, = Heap_Mem
|
||||
LDR R1, =(Stack_Mem + Stack_Size)
|
||||
LDR R2, = (Heap_Mem + Heap_Size)
|
||||
LDR R3, = Stack_Mem
|
||||
BX LR
|
||||
ENDP
|
||||
|
||||
ALIGN
|
||||
|
||||
ENDIF
|
||||
|
||||
|
||||
END
|
@ -0,0 +1,56 @@
|
||||
/**************************************************************************//**
|
||||
* @file system_ARMCM0.c
|
||||
* @brief CMSIS Device System Source File for
|
||||
* ARMCM0 Device Series
|
||||
* @version V5.00
|
||||
* @date 08. April 2016
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2016 ARM Limited. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "ARMCM0.h"
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Define clocks
|
||||
*----------------------------------------------------------------------------*/
|
||||
#define XTAL ( 5000000U) /* Oscillator frequency */
|
||||
|
||||
#define SYSTEM_CLOCK (5 * XTAL)
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
System Core Clock Variable
|
||||
*----------------------------------------------------------------------------*/
|
||||
uint32_t SystemCoreClock = SYSTEM_CLOCK;
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
System Core Clock update function
|
||||
*----------------------------------------------------------------------------*/
|
||||
void SystemCoreClockUpdate (void)
|
||||
{
|
||||
SystemCoreClock = SYSTEM_CLOCK;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
System initialization function
|
||||
*----------------------------------------------------------------------------*/
|
||||
void SystemInit (void)
|
||||
{
|
||||
SystemCoreClock = SYSTEM_CLOCK;
|
||||
}
|
@ -0,0 +1,262 @@
|
||||
;/**************************************************************************//**
|
||||
; * @file startup_ARMCM3.s
|
||||
; * @brief CMSIS Core Device Startup File for
|
||||
; * ARMCM3 Device Series
|
||||
; * @version V5.00
|
||||
; * @date 02. March 2016
|
||||
; ******************************************************************************/
|
||||
;/*
|
||||
; * Copyright (c) 2009-2016 ARM Limited. All rights reserved.
|
||||
; *
|
||||
; * 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
|
||||
; *
|
||||
; * 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.
|
||||
; */
|
||||
|
||||
;/*
|
||||
;//-------- <<< Use Configuration Wizard in Context Menu >>> ------------------
|
||||
;*/
|
||||
|
||||
|
||||
; <h> Stack Configuration
|
||||
; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
|
||||
; </h>
|
||||
|
||||
Stack_Size EQU 0x00000400
|
||||
|
||||
AREA STACK, NOINIT, READWRITE, ALIGN=3
|
||||
Stack_Mem SPACE Stack_Size
|
||||
__initial_sp
|
||||
|
||||
|
||||
; <h> Heap Configuration
|
||||
; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
|
||||
; </h>
|
||||
|
||||
Heap_Size EQU 0x00000C00
|
||||
|
||||
AREA HEAP, NOINIT, READWRITE, ALIGN=3
|
||||
__heap_base
|
||||
Heap_Mem SPACE Heap_Size
|
||||
__heap_limit
|
||||
|
||||
|
||||
PRESERVE8
|
||||
THUMB
|
||||
|
||||
|
||||
; Vector Table Mapped to Address 0 at Reset
|
||||
|
||||
AREA RESET, DATA, READONLY
|
||||
EXPORT __Vectors
|
||||
EXPORT __Vectors_End
|
||||
EXPORT __Vectors_Size
|
||||
|
||||
__Vectors DCD __initial_sp ; Top of Stack
|
||||
DCD Reset_Handler ; Reset Handler
|
||||
DCD NMI_Handler ; NMI Handler
|
||||
DCD HardFault_Handler ; Hard Fault Handler
|
||||
DCD MemManage_Handler ; MPU Fault Handler
|
||||
DCD BusFault_Handler ; Bus Fault Handler
|
||||
DCD UsageFault_Handler ; Usage Fault Handler
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD SVC_Handler ; SVCall Handler
|
||||
DCD DebugMon_Handler ; Debug Monitor Handler
|
||||
DCD 0 ; Reserved
|
||||
DCD PendSV_Handler ; PendSV Handler
|
||||
DCD SysTick_Handler ; SysTick Handler
|
||||
|
||||
; External Interrupts
|
||||
DCD WDT_IRQHandler ; 0: Watchdog Timer
|
||||
DCD RTC_IRQHandler ; 1: Real Time Clock
|
||||
DCD TIM0_IRQHandler ; 2: Timer0 / Timer1
|
||||
DCD TIM2_IRQHandler ; 3: Timer2 / Timer3
|
||||
DCD MCIA_IRQHandler ; 4: MCIa
|
||||
DCD MCIB_IRQHandler ; 5: MCIb
|
||||
DCD UART0_IRQHandler ; 6: UART0 - DUT FPGA
|
||||
DCD UART1_IRQHandler ; 7: UART1 - DUT FPGA
|
||||
DCD UART2_IRQHandler ; 8: UART2 - DUT FPGA
|
||||
DCD UART4_IRQHandler ; 9: UART4 - not connected
|
||||
DCD AACI_IRQHandler ; 10: AACI / AC97
|
||||
DCD CLCD_IRQHandler ; 11: CLCD Combined Interrupt
|
||||
DCD ENET_IRQHandler ; 12: Ethernet
|
||||
DCD USBDC_IRQHandler ; 13: USB Device
|
||||
DCD USBHC_IRQHandler ; 14: USB Host Controller
|
||||
DCD CHLCD_IRQHandler ; 15: Character LCD
|
||||
DCD FLEXRAY_IRQHandler ; 16: Flexray
|
||||
DCD CAN_IRQHandler ; 17: CAN
|
||||
DCD LIN_IRQHandler ; 18: LIN
|
||||
DCD I2C_IRQHandler ; 19: I2C ADC/DAC
|
||||
DCD 0 ; 20: Reserved
|
||||
DCD 0 ; 21: Reserved
|
||||
DCD 0 ; 22: Reserved
|
||||
DCD 0 ; 23: Reserved
|
||||
DCD 0 ; 24: Reserved
|
||||
DCD 0 ; 25: Reserved
|
||||
DCD 0 ; 26: Reserved
|
||||
DCD 0 ; 27: Reserved
|
||||
DCD CPU_CLCD_IRQHandler ; 28: Reserved - CPU FPGA CLCD
|
||||
DCD 0 ; 29: Reserved - CPU FPGA
|
||||
DCD UART3_IRQHandler ; 30: UART3 - CPU FPGA
|
||||
DCD SPI_IRQHandler ; 31: SPI Touchscreen - CPU FPGA
|
||||
__Vectors_End
|
||||
|
||||
__Vectors_Size EQU __Vectors_End - __Vectors
|
||||
|
||||
AREA |.text|, CODE, READONLY
|
||||
|
||||
|
||||
; Reset Handler
|
||||
|
||||
Reset_Handler PROC
|
||||
EXPORT Reset_Handler [WEAK]
|
||||
IMPORT SystemInit
|
||||
IMPORT __main
|
||||
LDR R0, =SystemInit
|
||||
BLX R0
|
||||
LDR R0, =__main
|
||||
BX R0
|
||||
ENDP
|
||||
|
||||
|
||||
; Dummy Exception Handlers (infinite loops which can be modified)
|
||||
|
||||
NMI_Handler PROC
|
||||
EXPORT NMI_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
HardFault_Handler\
|
||||
PROC
|
||||
EXPORT HardFault_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
MemManage_Handler\
|
||||
PROC
|
||||
EXPORT MemManage_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
BusFault_Handler\
|
||||
PROC
|
||||
EXPORT BusFault_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
UsageFault_Handler\
|
||||
PROC
|
||||
EXPORT UsageFault_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
SVC_Handler PROC
|
||||
EXPORT SVC_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
DebugMon_Handler\
|
||||
PROC
|
||||
EXPORT DebugMon_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
PendSV_Handler PROC
|
||||
EXPORT PendSV_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
SysTick_Handler PROC
|
||||
EXPORT SysTick_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
|
||||
Default_Handler PROC
|
||||
|
||||
EXPORT WDT_IRQHandler [WEAK]
|
||||
EXPORT RTC_IRQHandler [WEAK]
|
||||
EXPORT TIM0_IRQHandler [WEAK]
|
||||
EXPORT TIM2_IRQHandler [WEAK]
|
||||
EXPORT MCIA_IRQHandler [WEAK]
|
||||
EXPORT MCIB_IRQHandler [WEAK]
|
||||
EXPORT UART0_IRQHandler [WEAK]
|
||||
EXPORT UART1_IRQHandler [WEAK]
|
||||
EXPORT UART2_IRQHandler [WEAK]
|
||||
EXPORT UART3_IRQHandler [WEAK]
|
||||
EXPORT UART4_IRQHandler [WEAK]
|
||||
EXPORT AACI_IRQHandler [WEAK]
|
||||
EXPORT CLCD_IRQHandler [WEAK]
|
||||
EXPORT ENET_IRQHandler [WEAK]
|
||||
EXPORT USBDC_IRQHandler [WEAK]
|
||||
EXPORT USBHC_IRQHandler [WEAK]
|
||||
EXPORT CHLCD_IRQHandler [WEAK]
|
||||
EXPORT FLEXRAY_IRQHandler [WEAK]
|
||||
EXPORT CAN_IRQHandler [WEAK]
|
||||
EXPORT LIN_IRQHandler [WEAK]
|
||||
EXPORT I2C_IRQHandler [WEAK]
|
||||
EXPORT CPU_CLCD_IRQHandler [WEAK]
|
||||
EXPORT SPI_IRQHandler [WEAK]
|
||||
|
||||
WDT_IRQHandler
|
||||
RTC_IRQHandler
|
||||
TIM0_IRQHandler
|
||||
TIM2_IRQHandler
|
||||
MCIA_IRQHandler
|
||||
MCIB_IRQHandler
|
||||
UART0_IRQHandler
|
||||
UART1_IRQHandler
|
||||
UART2_IRQHandler
|
||||
UART3_IRQHandler
|
||||
UART4_IRQHandler
|
||||
AACI_IRQHandler
|
||||
CLCD_IRQHandler
|
||||
ENET_IRQHandler
|
||||
USBDC_IRQHandler
|
||||
USBHC_IRQHandler
|
||||
CHLCD_IRQHandler
|
||||
FLEXRAY_IRQHandler
|
||||
CAN_IRQHandler
|
||||
LIN_IRQHandler
|
||||
I2C_IRQHandler
|
||||
CPU_CLCD_IRQHandler
|
||||
SPI_IRQHandler
|
||||
B .
|
||||
|
||||
ENDP
|
||||
|
||||
|
||||
ALIGN
|
||||
|
||||
|
||||
; User Initial Stack & Heap
|
||||
|
||||
IF :DEF:__MICROLIB
|
||||
|
||||
EXPORT __initial_sp
|
||||
EXPORT __heap_base
|
||||
EXPORT __heap_limit
|
||||
|
||||
ELSE
|
||||
|
||||
IMPORT __use_two_region_memory
|
||||
EXPORT __user_initial_stackheap
|
||||
|
||||
__user_initial_stackheap PROC
|
||||
LDR R0, = Heap_Mem
|
||||
LDR R1, =(Stack_Mem + Stack_Size)
|
||||
LDR R2, = (Heap_Mem + Heap_Size)
|
||||
LDR R3, = Stack_Mem
|
||||
BX LR
|
||||
ENDP
|
||||
|
||||
ALIGN
|
||||
|
||||
ENDIF
|
||||
|
||||
|
||||
END
|
@ -0,0 +1,68 @@
|
||||
/**************************************************************************//**
|
||||
* @file system_ARMCM3.c
|
||||
* @brief CMSIS Device System Source File for
|
||||
* ARMCM3 Device Series
|
||||
* @version V5.00
|
||||
* @date 08. April 2016
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2016 ARM Limited. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "ARMCM3.h"
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Define clocks
|
||||
*----------------------------------------------------------------------------*/
|
||||
#define XTAL ( 5000000U) /* Oscillator frequency */
|
||||
|
||||
#define SYSTEM_CLOCK (5 * XTAL)
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Externals
|
||||
*----------------------------------------------------------------------------*/
|
||||
#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1)
|
||||
extern uint32_t __Vectors;
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
System Core Clock Variable
|
||||
*----------------------------------------------------------------------------*/
|
||||
uint32_t SystemCoreClock = SYSTEM_CLOCK;
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
System Core Clock update function
|
||||
*----------------------------------------------------------------------------*/
|
||||
void SystemCoreClockUpdate (void)
|
||||
{
|
||||
SystemCoreClock = SYSTEM_CLOCK;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
System initialization function
|
||||
*----------------------------------------------------------------------------*/
|
||||
void SystemInit (void)
|
||||
{
|
||||
|
||||
#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1)
|
||||
SCB->VTOR = (uint32_t) &__Vectors;
|
||||
#endif
|
||||
|
||||
SystemCoreClock = SYSTEM_CLOCK;
|
||||
}
|
@ -0,0 +1,262 @@
|
||||
;/**************************************************************************//**
|
||||
; * @file startup_ARMCM4.s
|
||||
; * @brief CMSIS Core Device Startup File for
|
||||
; * ARMCM4 Device Series
|
||||
; * @version V5.00
|
||||
; * @date 02. March 2016
|
||||
; ******************************************************************************/
|
||||
;/*
|
||||
; * Copyright (c) 2009-2016 ARM Limited. All rights reserved.
|
||||
; *
|
||||
; * 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
|
||||
; *
|
||||
; * 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.
|
||||
; */
|
||||
|
||||
;/*
|
||||
;//-------- <<< Use Configuration Wizard in Context Menu >>> ------------------
|
||||
;*/
|
||||
|
||||
|
||||
; <h> Stack Configuration
|
||||
; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
|
||||
; </h>
|
||||
|
||||
Stack_Size EQU 0x00000400
|
||||
|
||||
AREA STACK, NOINIT, READWRITE, ALIGN=3
|
||||
Stack_Mem SPACE Stack_Size
|
||||
__initial_sp
|
||||
|
||||
|
||||
; <h> Heap Configuration
|
||||
; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
|
||||
; </h>
|
||||
|
||||
Heap_Size EQU 0x00000C00
|
||||
|
||||
AREA HEAP, NOINIT, READWRITE, ALIGN=3
|
||||
__heap_base
|
||||
Heap_Mem SPACE Heap_Size
|
||||
__heap_limit
|
||||
|
||||
|
||||
PRESERVE8
|
||||
THUMB
|
||||
|
||||
|
||||
; Vector Table Mapped to Address 0 at Reset
|
||||
|
||||
AREA RESET, DATA, READONLY
|
||||
EXPORT __Vectors
|
||||
EXPORT __Vectors_End
|
||||
EXPORT __Vectors_Size
|
||||
|
||||
__Vectors DCD __initial_sp ; Top of Stack
|
||||
DCD Reset_Handler ; Reset Handler
|
||||
DCD NMI_Handler ; NMI Handler
|
||||
DCD HardFault_Handler ; Hard Fault Handler
|
||||
DCD MemManage_Handler ; MPU Fault Handler
|
||||
DCD BusFault_Handler ; Bus Fault Handler
|
||||
DCD UsageFault_Handler ; Usage Fault Handler
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD SVC_Handler ; SVCall Handler
|
||||
DCD DebugMon_Handler ; Debug Monitor Handler
|
||||
DCD 0 ; Reserved
|
||||
DCD PendSV_Handler ; PendSV Handler
|
||||
DCD SysTick_Handler ; SysTick Handler
|
||||
|
||||
; External Interrupts
|
||||
DCD WDT_IRQHandler ; 0: Watchdog Timer
|
||||
DCD RTC_IRQHandler ; 1: Real Time Clock
|
||||
DCD TIM0_IRQHandler ; 2: Timer0 / Timer1
|
||||
DCD TIM2_IRQHandler ; 3: Timer2 / Timer3
|
||||
DCD MCIA_IRQHandler ; 4: MCIa
|
||||
DCD MCIB_IRQHandler ; 5: MCIb
|
||||
DCD UART0_IRQHandler ; 6: UART0 - DUT FPGA
|
||||
DCD UART1_IRQHandler ; 7: UART1 - DUT FPGA
|
||||
DCD UART2_IRQHandler ; 8: UART2 - DUT FPGA
|
||||
DCD UART4_IRQHandler ; 9: UART4 - not connected
|
||||
DCD AACI_IRQHandler ; 10: AACI / AC97
|
||||
DCD CLCD_IRQHandler ; 11: CLCD Combined Interrupt
|
||||
DCD ENET_IRQHandler ; 12: Ethernet
|
||||
DCD USBDC_IRQHandler ; 13: USB Device
|
||||
DCD USBHC_IRQHandler ; 14: USB Host Controller
|
||||
DCD CHLCD_IRQHandler ; 15: Character LCD
|
||||
DCD FLEXRAY_IRQHandler ; 16: Flexray
|
||||
DCD CAN_IRQHandler ; 17: CAN
|
||||
DCD LIN_IRQHandler ; 18: LIN
|
||||
DCD I2C_IRQHandler ; 19: I2C ADC/DAC
|
||||
DCD 0 ; 20: Reserved
|
||||
DCD 0 ; 21: Reserved
|
||||
DCD 0 ; 22: Reserved
|
||||
DCD 0 ; 23: Reserved
|
||||
DCD 0 ; 24: Reserved
|
||||
DCD 0 ; 25: Reserved
|
||||
DCD 0 ; 26: Reserved
|
||||
DCD 0 ; 27: Reserved
|
||||
DCD CPU_CLCD_IRQHandler ; 28: Reserved - CPU FPGA CLCD
|
||||
DCD 0 ; 29: Reserved - CPU FPGA
|
||||
DCD UART3_IRQHandler ; 30: UART3 - CPU FPGA
|
||||
DCD SPI_IRQHandler ; 31: SPI Touchscreen - CPU FPGA
|
||||
__Vectors_End
|
||||
|
||||
__Vectors_Size EQU __Vectors_End - __Vectors
|
||||
|
||||
AREA |.text|, CODE, READONLY
|
||||
|
||||
|
||||
; Reset Handler
|
||||
|
||||
Reset_Handler PROC
|
||||
EXPORT Reset_Handler [WEAK]
|
||||
IMPORT SystemInit
|
||||
IMPORT __main
|
||||
LDR R0, =SystemInit
|
||||
BLX R0
|
||||
LDR R0, =__main
|
||||
BX R0
|
||||
ENDP
|
||||
|
||||
|
||||
; Dummy Exception Handlers (infinite loops which can be modified)
|
||||
|
||||
NMI_Handler PROC
|
||||
EXPORT NMI_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
HardFault_Handler\
|
||||
PROC
|
||||
EXPORT HardFault_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
MemManage_Handler\
|
||||
PROC
|
||||
EXPORT MemManage_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
BusFault_Handler\
|
||||
PROC
|
||||
EXPORT BusFault_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
UsageFault_Handler\
|
||||
PROC
|
||||
EXPORT UsageFault_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
SVC_Handler PROC
|
||||
EXPORT SVC_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
DebugMon_Handler\
|
||||
PROC
|
||||
EXPORT DebugMon_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
PendSV_Handler PROC
|
||||
EXPORT PendSV_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
SysTick_Handler PROC
|
||||
EXPORT SysTick_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
|
||||
Default_Handler PROC
|
||||
|
||||
EXPORT WDT_IRQHandler [WEAK]
|
||||
EXPORT RTC_IRQHandler [WEAK]
|
||||
EXPORT TIM0_IRQHandler [WEAK]
|
||||
EXPORT TIM2_IRQHandler [WEAK]
|
||||
EXPORT MCIA_IRQHandler [WEAK]
|
||||
EXPORT MCIB_IRQHandler [WEAK]
|
||||
EXPORT UART0_IRQHandler [WEAK]
|
||||
EXPORT UART1_IRQHandler [WEAK]
|
||||
EXPORT UART2_IRQHandler [WEAK]
|
||||
EXPORT UART3_IRQHandler [WEAK]
|
||||
EXPORT UART4_IRQHandler [WEAK]
|
||||
EXPORT AACI_IRQHandler [WEAK]
|
||||
EXPORT CLCD_IRQHandler [WEAK]
|
||||
EXPORT ENET_IRQHandler [WEAK]
|
||||
EXPORT USBDC_IRQHandler [WEAK]
|
||||
EXPORT USBHC_IRQHandler [WEAK]
|
||||
EXPORT CHLCD_IRQHandler [WEAK]
|
||||
EXPORT FLEXRAY_IRQHandler [WEAK]
|
||||
EXPORT CAN_IRQHandler [WEAK]
|
||||
EXPORT LIN_IRQHandler [WEAK]
|
||||
EXPORT I2C_IRQHandler [WEAK]
|
||||
EXPORT CPU_CLCD_IRQHandler [WEAK]
|
||||
EXPORT SPI_IRQHandler [WEAK]
|
||||
|
||||
WDT_IRQHandler
|
||||
RTC_IRQHandler
|
||||
TIM0_IRQHandler
|
||||
TIM2_IRQHandler
|
||||
MCIA_IRQHandler
|
||||
MCIB_IRQHandler
|
||||
UART0_IRQHandler
|
||||
UART1_IRQHandler
|
||||
UART2_IRQHandler
|
||||
UART3_IRQHandler
|
||||
UART4_IRQHandler
|
||||
AACI_IRQHandler
|
||||
CLCD_IRQHandler
|
||||
ENET_IRQHandler
|
||||
USBDC_IRQHandler
|
||||
USBHC_IRQHandler
|
||||
CHLCD_IRQHandler
|
||||
FLEXRAY_IRQHandler
|
||||
CAN_IRQHandler
|
||||
LIN_IRQHandler
|
||||
I2C_IRQHandler
|
||||
CPU_CLCD_IRQHandler
|
||||
SPI_IRQHandler
|
||||
B .
|
||||
|
||||
ENDP
|
||||
|
||||
|
||||
ALIGN
|
||||
|
||||
|
||||
; User Initial Stack & Heap
|
||||
|
||||
IF :DEF:__MICROLIB
|
||||
|
||||
EXPORT __initial_sp
|
||||
EXPORT __heap_base
|
||||
EXPORT __heap_limit
|
||||
|
||||
ELSE
|
||||
|
||||
IMPORT __use_two_region_memory
|
||||
EXPORT __user_initial_stackheap
|
||||
|
||||
__user_initial_stackheap PROC
|
||||
LDR R0, = Heap_Mem
|
||||
LDR R1, =(Stack_Mem + Stack_Size)
|
||||
LDR R2, = (Heap_Mem + Heap_Size)
|
||||
LDR R3, = Stack_Mem
|
||||
BX LR
|
||||
ENDP
|
||||
|
||||
ALIGN
|
||||
|
||||
ENDIF
|
||||
|
||||
|
||||
END
|
@ -0,0 +1,83 @@
|
||||
/**************************************************************************//**
|
||||
* @file system_ARMCM4.c
|
||||
* @brief CMSIS Device System Source File for
|
||||
* ARMCM4 Device Series
|
||||
* @version V5.00
|
||||
* @date 08. April 2016
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2016 ARM Limited. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if defined (ARMCM4)
|
||||
#include "ARMCM4.h"
|
||||
#elif defined (ARMCM4_FP)
|
||||
#include "ARMCM4_FP.h"
|
||||
#else
|
||||
#error device not specified!
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Define clocks
|
||||
*----------------------------------------------------------------------------*/
|
||||
#define XTAL ( 5000000U) /* Oscillator frequency */
|
||||
|
||||
#define SYSTEM_CLOCK (5 * XTAL)
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Externals
|
||||
*----------------------------------------------------------------------------*/
|
||||
#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1)
|
||||
extern uint32_t __Vectors;
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
System Core Clock Variable
|
||||
*----------------------------------------------------------------------------*/
|
||||
uint32_t SystemCoreClock = SYSTEM_CLOCK;
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
System Core Clock update function
|
||||
*----------------------------------------------------------------------------*/
|
||||
void SystemCoreClockUpdate (void)
|
||||
{
|
||||
SystemCoreClock = SYSTEM_CLOCK;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
System initialization function
|
||||
*----------------------------------------------------------------------------*/
|
||||
void SystemInit (void)
|
||||
{
|
||||
|
||||
#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1)
|
||||
SCB->VTOR = (uint32_t) &__Vectors;
|
||||
#endif
|
||||
|
||||
#if defined (__FPU_USED) && (__FPU_USED == 1)
|
||||
SCB->CPACR |= ((3U << 10*2) | /* set CP10 Full Access */
|
||||
(3U << 11*2) ); /* set CP11 Full Access */
|
||||
#endif
|
||||
|
||||
#ifdef UNALIGNED_SUPPORT_DISABLE
|
||||
SCB->CCR |= SCB_CCR_UNALIGN_TRP_Msk;
|
||||
#endif
|
||||
|
||||
SystemCoreClock = SYSTEM_CLOCK;
|
||||
}
|
@ -0,0 +1,295 @@
|
||||
/**************************************************************************//**
|
||||
* @file startup_ARMCM7.s
|
||||
* @brief CMSIS Core Device Startup File for
|
||||
* ARMCM7 Device Series
|
||||
* @version V5.00
|
||||
* @date 26. April 2016
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2016 ARM Limited. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Linker generated Symbols
|
||||
*----------------------------------------------------------------------------*/
|
||||
extern uint32_t __etext;
|
||||
extern uint32_t __data_start__;
|
||||
extern uint32_t __data_end__;
|
||||
extern uint32_t __copy_table_start__;
|
||||
extern uint32_t __copy_table_end__;
|
||||
extern uint32_t __zero_table_start__;
|
||||
extern uint32_t __zero_table_end__;
|
||||
extern uint32_t __bss_start__;
|
||||
extern uint32_t __bss_end__;
|
||||
extern uint32_t __StackTop;
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Exception / Interrupt Handler Function Prototype
|
||||
*----------------------------------------------------------------------------*/
|
||||
typedef void( *pFunc )( void );
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
External References
|
||||
*----------------------------------------------------------------------------*/
|
||||
#ifndef __START
|
||||
extern void _start(void) __attribute__((noreturn)); /* PreeMain (C library entry point) */
|
||||
#else
|
||||
extern int __START(void) __attribute__((noreturn)); /* main entry point */
|
||||
#endif
|
||||
|
||||
#ifndef __NO_SYSTEM_INIT
|
||||
extern void SystemInit (void); /* CMSIS System Initialization */
|
||||
#endif
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Internal References
|
||||
*----------------------------------------------------------------------------*/
|
||||
void Default_Handler(void); /* Default empty handler */
|
||||
void Reset_Handler(void); /* Reset Handler */
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
User Initial Stack & Heap
|
||||
*----------------------------------------------------------------------------*/
|
||||
#ifndef __STACK_SIZE
|
||||
#define __STACK_SIZE 0x00000400
|
||||
#endif
|
||||
static uint8_t stack[__STACK_SIZE] __attribute__ ((aligned(8), used, section(".stack")));
|
||||
|
||||
#ifndef __HEAP_SIZE
|
||||
#define __HEAP_SIZE 0x00000C00
|
||||
#endif
|
||||
#if __HEAP_SIZE > 0
|
||||
static uint8_t heap[__HEAP_SIZE] __attribute__ ((aligned(8), used, section(".heap")));
|
||||
#endif
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Exception / Interrupt Handler
|
||||
*----------------------------------------------------------------------------*/
|
||||
/* Cortex-M7 Processor Exceptions */
|
||||
void NMI_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void HardFault_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void MemManage_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void BusFault_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void UsageFault_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void SVC_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void DebugMon_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void PendSV_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void SysTick_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
|
||||
/* ARMCM7 Specific Interrupts */
|
||||
void WDT_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void RTC_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void TIM0_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void TIM2_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void MCIA_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void MCIB_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void UART0_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void UART1_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void UART2_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void UART4_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void AACI_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void CLCD_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void ENET_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void USBDC_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void USBHC_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void CHLCD_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void FLEXRAY_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void CAN_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void LIN_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void I2C_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void CPU_CLCD_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void UART3_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void SPI_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Exception / Interrupt Vector table
|
||||
*----------------------------------------------------------------------------*/
|
||||
const pFunc __Vectors[] __attribute__ ((section(".vectors"))) = {
|
||||
/* Cortex-M7 Exceptions Handler */
|
||||
(pFunc)((uint32_t)&__StackTop), /* Initial Stack Pointer */
|
||||
Reset_Handler, /* Reset Handler */
|
||||
NMI_Handler, /* NMI Handler */
|
||||
HardFault_Handler, /* Hard Fault Handler */
|
||||
MemManage_Handler, /* MPU Fault Handler */
|
||||
BusFault_Handler, /* Bus Fault Handler */
|
||||
UsageFault_Handler, /* Usage Fault Handler */
|
||||
0, /* Reserved */
|
||||
0, /* Reserved */
|
||||
0, /* Reserved */
|
||||
0, /* Reserved */
|
||||
SVC_Handler, /* SVCall Handler */
|
||||
DebugMon_Handler, /* Debug Monitor Handler */
|
||||
0, /* Reserved */
|
||||
PendSV_Handler, /* PendSV Handler */
|
||||
SysTick_Handler, /* SysTick Handler */
|
||||
|
||||
/* External interrupts */
|
||||
WDT_IRQHandler, /* 0: Watchdog Timer */
|
||||
RTC_IRQHandler, /* 1: Real Time Clock */
|
||||
TIM0_IRQHandler, /* 2: Timer0 / Timer1 */
|
||||
TIM2_IRQHandler, /* 3: Timer2 / Timer3 */
|
||||
MCIA_IRQHandler, /* 4: MCIa */
|
||||
MCIB_IRQHandler, /* 5: MCIb */
|
||||
UART0_IRQHandler, /* 6: UART0 - DUT FPGA */
|
||||
UART1_IRQHandler, /* 7: UART1 - DUT FPGA */
|
||||
UART2_IRQHandler, /* 8: UART2 - DUT FPGA */
|
||||
UART4_IRQHandler, /* 9: UART4 - not connected */
|
||||
AACI_IRQHandler, /* 10: AACI / AC97 */
|
||||
CLCD_IRQHandler, /* 11: CLCD Combined Interrupt */
|
||||
ENET_IRQHandler, /* 12: Ethernet */
|
||||
USBDC_IRQHandler, /* 13: USB Device */
|
||||
USBHC_IRQHandler, /* 14: USB Host Controller */
|
||||
CHLCD_IRQHandler, /* 15: Character LCD */
|
||||
FLEXRAY_IRQHandler, /* 16: Flexray */
|
||||
CAN_IRQHandler, /* 17: CAN */
|
||||
LIN_IRQHandler, /* 18: LIN */
|
||||
I2C_IRQHandler, /* 19: I2C ADC/DAC */
|
||||
0, /* 20: Reserved */
|
||||
0, /* 21: Reserved */
|
||||
0, /* 22: Reserved */
|
||||
0, /* 23: Reserved */
|
||||
0, /* 24: Reserved */
|
||||
0, /* 25: Reserved */
|
||||
0, /* 26: Reserved */
|
||||
0, /* 27: Reserved */
|
||||
CPU_CLCD_IRQHandler, /* 28: Reserved - CPU FPGA CLCD */
|
||||
0, /* 29: Reserved - CPU FPGA */
|
||||
UART3_IRQHandler, /* 30: UART3 - CPU FPGA */
|
||||
SPI_IRQHandler /* 31: SPI Touchscreen - CPU FPGA */
|
||||
};
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Reset Handler called on controller reset
|
||||
*----------------------------------------------------------------------------*/
|
||||
void Reset_Handler(void) {
|
||||
uint32_t *pSrc, *pDest;
|
||||
uint32_t *pTable __attribute__((unused));
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
pTable = &__copy_table_start__;
|
||||
|
||||
for (; pTable < &__copy_table_end__; pTable = pTable + 3) {
|
||||
pSrc = (uint32_t*)*(pTable + 0);
|
||||
pDest = (uint32_t*)*(pTable + 1);
|
||||
for (; pDest < (uint32_t*)(*(pTable + 1) + *(pTable + 2)) ; ) {
|
||||
*pDest++ = *pSrc++;
|
||||
}
|
||||
}
|
||||
#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.
|
||||
*/
|
||||
pSrc = &__etext;
|
||||
pDest = &__data_start__;
|
||||
|
||||
for ( ; pDest < &__data_end__ ; ) {
|
||||
*pDest++ = *pSrc++;
|
||||
}
|
||||
#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 __copy_table_start__ and __copy_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
|
||||
*/
|
||||
pTable = &__zero_table_start__;
|
||||
|
||||
for (; pTable < &__zero_table_end__; pTable = pTable + 2) {
|
||||
pDest = (uint32_t*)*(pTable + 0);
|
||||
for (; pDest < (uint32_t*)(*(pTable + 0) + *(pTable + 1)) ; ) {
|
||||
*pDest++ = 0;
|
||||
}
|
||||
}
|
||||
#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.
|
||||
*/
|
||||
pDest = &__bss_start__;
|
||||
|
||||
for ( ; pDest < &__bss_end__ ; ) {
|
||||
*pDest++ = 0UL;
|
||||
}
|
||||
#endif /* __STARTUP_CLEAR_BSS_MULTIPLE || __STARTUP_CLEAR_BSS */
|
||||
|
||||
#ifndef __NO_SYSTEM_INIT
|
||||
SystemInit();
|
||||
#endif
|
||||
|
||||
#ifndef __START
|
||||
#define __START _start
|
||||
#endif
|
||||
__START();
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Default Handler for Exceptions / Interrupts
|
||||
*----------------------------------------------------------------------------*/
|
||||
void Default_Handler(void) {
|
||||
|
||||
while(1);
|
||||
}
|
@ -0,0 +1,262 @@
|
||||
;/**************************************************************************//**
|
||||
; * @file startup_ARMCM7.s
|
||||
; * @brief CMSIS Core Device Startup File for
|
||||
; * ARMCM7 Device Series
|
||||
; * @version V5.00
|
||||
; * @date 02. March 2016
|
||||
; ******************************************************************************/
|
||||
;/*
|
||||
; * Copyright (c) 2009-2016 ARM Limited. All rights reserved.
|
||||
; *
|
||||
; * 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
|
||||
; *
|
||||
; * 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.
|
||||
; */
|
||||
|
||||
;/*
|
||||
;//-------- <<< Use Configuration Wizard in Context Menu >>> ------------------
|
||||
;*/
|
||||
|
||||
|
||||
; <h> Stack Configuration
|
||||
; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
|
||||
; </h>
|
||||
|
||||
Stack_Size EQU 0x00000400
|
||||
|
||||
AREA STACK, NOINIT, READWRITE, ALIGN=3
|
||||
Stack_Mem SPACE Stack_Size
|
||||
__initial_sp
|
||||
|
||||
|
||||
; <h> Heap Configuration
|
||||
; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
|
||||
; </h>
|
||||
|
||||
Heap_Size EQU 0x00000C00
|
||||
|
||||
AREA HEAP, NOINIT, READWRITE, ALIGN=3
|
||||
__heap_base
|
||||
Heap_Mem SPACE Heap_Size
|
||||
__heap_limit
|
||||
|
||||
|
||||
PRESERVE8
|
||||
THUMB
|
||||
|
||||
|
||||
; Vector Table Mapped to Address 0 at Reset
|
||||
|
||||
AREA RESET, DATA, READONLY
|
||||
EXPORT __Vectors
|
||||
EXPORT __Vectors_End
|
||||
EXPORT __Vectors_Size
|
||||
|
||||
__Vectors DCD __initial_sp ; Top of Stack
|
||||
DCD Reset_Handler ; Reset Handler
|
||||
DCD NMI_Handler ; NMI Handler
|
||||
DCD HardFault_Handler ; Hard Fault Handler
|
||||
DCD MemManage_Handler ; MPU Fault Handler
|
||||
DCD BusFault_Handler ; Bus Fault Handler
|
||||
DCD UsageFault_Handler ; Usage Fault Handler
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD SVC_Handler ; SVCall Handler
|
||||
DCD DebugMon_Handler ; Debug Monitor Handler
|
||||
DCD 0 ; Reserved
|
||||
DCD PendSV_Handler ; PendSV Handler
|
||||
DCD SysTick_Handler ; SysTick Handler
|
||||
|
||||
; External Interrupts
|
||||
DCD WDT_IRQHandler ; 0: Watchdog Timer
|
||||
DCD RTC_IRQHandler ; 1: Real Time Clock
|
||||
DCD TIM0_IRQHandler ; 2: Timer0 / Timer1
|
||||
DCD TIM2_IRQHandler ; 3: Timer2 / Timer3
|
||||
DCD MCIA_IRQHandler ; 4: MCIa
|
||||
DCD MCIB_IRQHandler ; 5: MCIb
|
||||
DCD UART0_IRQHandler ; 6: UART0 - DUT FPGA
|
||||
DCD UART1_IRQHandler ; 7: UART1 - DUT FPGA
|
||||
DCD UART2_IRQHandler ; 8: UART2 - DUT FPGA
|
||||
DCD UART4_IRQHandler ; 9: UART4 - not connected
|
||||
DCD AACI_IRQHandler ; 10: AACI / AC97
|
||||
DCD CLCD_IRQHandler ; 11: CLCD Combined Interrupt
|
||||
DCD ENET_IRQHandler ; 12: Ethernet
|
||||
DCD USBDC_IRQHandler ; 13: USB Device
|
||||
DCD USBHC_IRQHandler ; 14: USB Host Controller
|
||||
DCD CHLCD_IRQHandler ; 15: Character LCD
|
||||
DCD FLEXRAY_IRQHandler ; 16: Flexray
|
||||
DCD CAN_IRQHandler ; 17: CAN
|
||||
DCD LIN_IRQHandler ; 18: LIN
|
||||
DCD I2C_IRQHandler ; 19: I2C ADC/DAC
|
||||
DCD 0 ; 20: Reserved
|
||||
DCD 0 ; 21: Reserved
|
||||
DCD 0 ; 22: Reserved
|
||||
DCD 0 ; 23: Reserved
|
||||
DCD 0 ; 24: Reserved
|
||||
DCD 0 ; 25: Reserved
|
||||
DCD 0 ; 26: Reserved
|
||||
DCD 0 ; 27: Reserved
|
||||
DCD CPU_CLCD_IRQHandler ; 28: Reserved - CPU FPGA CLCD
|
||||
DCD 0 ; 29: Reserved - CPU FPGA
|
||||
DCD UART3_IRQHandler ; 30: UART3 - CPU FPGA
|
||||
DCD SPI_IRQHandler ; 31: SPI Touchscreen - CPU FPGA
|
||||
__Vectors_End
|
||||
|
||||
__Vectors_Size EQU __Vectors_End - __Vectors
|
||||
|
||||
AREA |.text|, CODE, READONLY
|
||||
|
||||
|
||||
; Reset Handler
|
||||
|
||||
Reset_Handler PROC
|
||||
EXPORT Reset_Handler [WEAK]
|
||||
IMPORT SystemInit
|
||||
IMPORT __main
|
||||
LDR R0, =SystemInit
|
||||
BLX R0
|
||||
LDR R0, =__main
|
||||
BX R0
|
||||
ENDP
|
||||
|
||||
|
||||
; Dummy Exception Handlers (infinite loops which can be modified)
|
||||
|
||||
NMI_Handler PROC
|
||||
EXPORT NMI_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
HardFault_Handler\
|
||||
PROC
|
||||
EXPORT HardFault_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
MemManage_Handler\
|
||||
PROC
|
||||
EXPORT MemManage_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
BusFault_Handler\
|
||||
PROC
|
||||
EXPORT BusFault_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
UsageFault_Handler\
|
||||
PROC
|
||||
EXPORT UsageFault_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
SVC_Handler PROC
|
||||
EXPORT SVC_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
DebugMon_Handler\
|
||||
PROC
|
||||
EXPORT DebugMon_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
PendSV_Handler PROC
|
||||
EXPORT PendSV_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
SysTick_Handler PROC
|
||||
EXPORT SysTick_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
|
||||
Default_Handler PROC
|
||||
|
||||
EXPORT WDT_IRQHandler [WEAK]
|
||||
EXPORT RTC_IRQHandler [WEAK]
|
||||
EXPORT TIM0_IRQHandler [WEAK]
|
||||
EXPORT TIM2_IRQHandler [WEAK]
|
||||
EXPORT MCIA_IRQHandler [WEAK]
|
||||
EXPORT MCIB_IRQHandler [WEAK]
|
||||
EXPORT UART0_IRQHandler [WEAK]
|
||||
EXPORT UART1_IRQHandler [WEAK]
|
||||
EXPORT UART2_IRQHandler [WEAK]
|
||||
EXPORT UART3_IRQHandler [WEAK]
|
||||
EXPORT UART4_IRQHandler [WEAK]
|
||||
EXPORT AACI_IRQHandler [WEAK]
|
||||
EXPORT CLCD_IRQHandler [WEAK]
|
||||
EXPORT ENET_IRQHandler [WEAK]
|
||||
EXPORT USBDC_IRQHandler [WEAK]
|
||||
EXPORT USBHC_IRQHandler [WEAK]
|
||||
EXPORT CHLCD_IRQHandler [WEAK]
|
||||
EXPORT FLEXRAY_IRQHandler [WEAK]
|
||||
EXPORT CAN_IRQHandler [WEAK]
|
||||
EXPORT LIN_IRQHandler [WEAK]
|
||||
EXPORT I2C_IRQHandler [WEAK]
|
||||
EXPORT CPU_CLCD_IRQHandler [WEAK]
|
||||
EXPORT SPI_IRQHandler [WEAK]
|
||||
|
||||
WDT_IRQHandler
|
||||
RTC_IRQHandler
|
||||
TIM0_IRQHandler
|
||||
TIM2_IRQHandler
|
||||
MCIA_IRQHandler
|
||||
MCIB_IRQHandler
|
||||
UART0_IRQHandler
|
||||
UART1_IRQHandler
|
||||
UART2_IRQHandler
|
||||
UART3_IRQHandler
|
||||
UART4_IRQHandler
|
||||
AACI_IRQHandler
|
||||
CLCD_IRQHandler
|
||||
ENET_IRQHandler
|
||||
USBDC_IRQHandler
|
||||
USBHC_IRQHandler
|
||||
CHLCD_IRQHandler
|
||||
FLEXRAY_IRQHandler
|
||||
CAN_IRQHandler
|
||||
LIN_IRQHandler
|
||||
I2C_IRQHandler
|
||||
CPU_CLCD_IRQHandler
|
||||
SPI_IRQHandler
|
||||
B .
|
||||
|
||||
ENDP
|
||||
|
||||
|
||||
ALIGN
|
||||
|
||||
|
||||
; User Initial Stack & Heap
|
||||
|
||||
IF :DEF:__MICROLIB
|
||||
|
||||
EXPORT __initial_sp
|
||||
EXPORT __heap_base
|
||||
EXPORT __heap_limit
|
||||
|
||||
ELSE
|
||||
|
||||
IMPORT __use_two_region_memory
|
||||
EXPORT __user_initial_stackheap
|
||||
|
||||
__user_initial_stackheap PROC
|
||||
LDR R0, = Heap_Mem
|
||||
LDR R1, =(Stack_Mem + Stack_Size)
|
||||
LDR R2, = (Heap_Mem + Heap_Size)
|
||||
LDR R3, = Stack_Mem
|
||||
BX LR
|
||||
ENDP
|
||||
|
||||
ALIGN
|
||||
|
||||
ENDIF
|
||||
|
||||
|
||||
END
|
@ -0,0 +1,85 @@
|
||||
/**************************************************************************//**
|
||||
* @file system_ARMCM7.c
|
||||
* @brief CMSIS Device System Source File for
|
||||
* ARMCM7 Device Series
|
||||
* @version V5.00
|
||||
* @date 08. April 2016
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2016 ARM Limited. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if defined (ARMCM7)
|
||||
#include "ARMCM7.h"
|
||||
#elif defined (ARMCM7_SP)
|
||||
#include "ARMCM7_SP.h"
|
||||
#elif defined (ARMCM7_DP)
|
||||
#include "ARMCM7_DP.h"
|
||||
#else
|
||||
#error device not specified!
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Define clocks
|
||||
*----------------------------------------------------------------------------*/
|
||||
#define XTAL ( 5000000U) /* Oscillator frequency */
|
||||
|
||||
#define SYSTEM_CLOCK (5 * XTAL)
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Externals
|
||||
*----------------------------------------------------------------------------*/
|
||||
#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1)
|
||||
extern uint32_t __Vectors;
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
System Core Clock Variable
|
||||
*----------------------------------------------------------------------------*/
|
||||
uint32_t SystemCoreClock = SYSTEM_CLOCK;
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
System Core Clock update function
|
||||
*----------------------------------------------------------------------------*/
|
||||
void SystemCoreClockUpdate (void)
|
||||
{
|
||||
SystemCoreClock = SYSTEM_CLOCK;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
System initialization function
|
||||
*----------------------------------------------------------------------------*/
|
||||
void SystemInit (void)
|
||||
{
|
||||
|
||||
#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1)
|
||||
SCB->VTOR = (uint32_t) &__Vectors;
|
||||
#endif
|
||||
|
||||
#if defined (__FPU_USED) && (__FPU_USED == 1)
|
||||
SCB->CPACR |= ((3U << 10*2) | /* set CP10 Full Access */
|
||||
(3U << 11*2) ); /* set CP11 Full Access */
|
||||
#endif
|
||||
|
||||
#ifdef UNALIGNED_SUPPORT_DISABLE
|
||||
SCB->CCR |= SCB_CCR_UNALIGN_TRP_Msk;
|
||||
#endif
|
||||
|
||||
SystemCoreClock = SYSTEM_CLOCK;
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
|
||||
/*
|
||||
* Auto generated Run-Time-Environment Component Configuration File
|
||||
* *** Do not modify ! ***
|
||||
*
|
||||
* Project: 'arm_nnexamples_cifar10'
|
||||
* Target: 'ARMCM0'
|
||||
*/
|
||||
|
||||
#ifndef RTE_COMPONENTS_H
|
||||
#define RTE_COMPONENTS_H
|
||||
|
||||
|
||||
/*
|
||||
* Define the Device Header File:
|
||||
*/
|
||||
#define CMSIS_device_header "ARMCM0.h"
|
||||
|
||||
#define RTE_Compiler_EventRecorder
|
||||
#define RTE_Compiler_EventRecorder_DAP
|
||||
#define RTE_Compiler_IO_STDOUT /* Compiler I/O: STDOUT */
|
||||
#define RTE_Compiler_IO_STDOUT_EVR /* Compiler I/O: STDOUT EVR */
|
||||
|
||||
#endif /* RTE_COMPONENTS_H */
|
@ -0,0 +1,22 @@
|
||||
|
||||
/*
|
||||
* Auto generated Run-Time-Environment Component Configuration File
|
||||
* *** Do not modify ! ***
|
||||
*
|
||||
* Project: 'arm_nnexamples_cifar10'
|
||||
* Target: 'ARMCM3'
|
||||
*/
|
||||
|
||||
#ifndef RTE_COMPONENTS_H
|
||||
#define RTE_COMPONENTS_H
|
||||
|
||||
|
||||
/*
|
||||
* Define the Device Header File:
|
||||
*/
|
||||
#define CMSIS_device_header "ARMCM3.h"
|
||||
|
||||
#define RTE_Compiler_IO_STDOUT /* Compiler I/O: STDOUT */
|
||||
#define RTE_Compiler_IO_STDOUT_ITM /* Compiler I/O: STDOUT ITM */
|
||||
|
||||
#endif /* RTE_COMPONENTS_H */
|
@ -0,0 +1,22 @@
|
||||
|
||||
/*
|
||||
* Auto generated Run-Time-Environment Component Configuration File
|
||||
* *** Do not modify ! ***
|
||||
*
|
||||
* Project: 'arm_nnexamples_cifar10'
|
||||
* Target: 'ARMCM4_FP'
|
||||
*/
|
||||
|
||||
#ifndef RTE_COMPONENTS_H
|
||||
#define RTE_COMPONENTS_H
|
||||
|
||||
|
||||
/*
|
||||
* Define the Device Header File:
|
||||
*/
|
||||
#define CMSIS_device_header "ARMCM4_FP.h"
|
||||
|
||||
#define RTE_Compiler_IO_STDOUT /* Compiler I/O: STDOUT */
|
||||
#define RTE_Compiler_IO_STDOUT_ITM /* Compiler I/O: STDOUT ITM */
|
||||
|
||||
#endif /* RTE_COMPONENTS_H */
|
@ -0,0 +1,22 @@
|
||||
|
||||
/*
|
||||
* Auto generated Run-Time-Environment Component Configuration File
|
||||
* *** Do not modify ! ***
|
||||
*
|
||||
* Project: 'arm_nnexamples_cifar10'
|
||||
* Target: 'ARMCM7_SP'
|
||||
*/
|
||||
|
||||
#ifndef RTE_COMPONENTS_H
|
||||
#define RTE_COMPONENTS_H
|
||||
|
||||
|
||||
/*
|
||||
* Define the Device Header File:
|
||||
*/
|
||||
#define CMSIS_device_header "ARMCM7_SP.h"
|
||||
|
||||
#define RTE_Compiler_IO_STDOUT /* Compiler I/O: STDOUT */
|
||||
#define RTE_Compiler_IO_STDOUT_ITM /* Compiler I/O: STDOUT ITM */
|
||||
|
||||
#endif /* RTE_COMPONENTS_H */
|
@ -0,0 +1,196 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2018 Arm Limited. All rights reserved.
|
||||
*
|
||||
*
|
||||
* Project: CMSIS NN Library
|
||||
* Title: arm_nnexamples_cifar10.cpp
|
||||
*
|
||||
* Description: Convolutional Neural Network Example
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M7
|
||||
*
|
||||
* 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 LIMITED 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 THE
|
||||
* COPYRIGHT OWNER 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.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @ingroup groupExamples
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup CNNExample Convolutional Neural Network Example
|
||||
*
|
||||
* \par Description:
|
||||
* \par
|
||||
* Demonstrates a convolutional neural network (CNN) example with the use of convolution,
|
||||
* ReLU activation, pooling and fully-connected functions.
|
||||
*
|
||||
* \par Model definition:
|
||||
* \par
|
||||
* The CNN used in this example is based on CIFAR-10 example from Caffe [1].
|
||||
* The neural network consists
|
||||
* of 3 convolution layers interspersed by ReLU activation and max pooling layers, followed by a
|
||||
* fully-connected layer at the end. The input to the network is a 32x32 pixel color image, which will
|
||||
* be classified into one of the 10 output classes.
|
||||
* This example model implementation needs 32.3 KB to store weights, 40 KB for activations and
|
||||
* 3.1 KB for storing the \c im2col data.
|
||||
*
|
||||
* \image html CIFAR10_CNN.gif "Neural Network model definition"
|
||||
*
|
||||
* \par Variables Description:
|
||||
* \par
|
||||
* \li \c conv1_wt, \c conv2_wt, \c conv3_wt are convolution layer weight matrices
|
||||
* \li \c conv1_bias, \c conv2_bias, \c conv3_bias are convolution layer bias arrays
|
||||
* \li \c ip1_wt, ip1_bias point to fully-connected layer weights and biases
|
||||
* \li \c input_data points to the input image data
|
||||
* \li \c output_data points to the classification output
|
||||
* \li \c col_buffer is a buffer to store the \c im2col output
|
||||
* \li \c scratch_buffer is used to store the activation data (intermediate layer outputs)
|
||||
*
|
||||
* \par CMSIS DSP Software Library Functions Used:
|
||||
* \par
|
||||
* - arm_convolve_HWC_q7_RGB()
|
||||
* - arm_convolve_HWC_q7_fast()
|
||||
* - arm_relu_q7()
|
||||
* - arm_maxpool_q7_HWC()
|
||||
* - arm_avepool_q7_HWC()
|
||||
* - arm_fully_connected_q7_opt()
|
||||
* - arm_fully_connected_q7()
|
||||
*
|
||||
* <b> Refer </b>
|
||||
* \link arm_nnexamples_cifar10.cpp \endlink
|
||||
*
|
||||
* \par [1] https://github.com/BVLC/caffe
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include "arm_math.h"
|
||||
#include "arm_nnexamples_cifar10_parameter.h"
|
||||
#include "arm_nnexamples_cifar10_weights.h"
|
||||
|
||||
#include "arm_nnfunctions.h"
|
||||
#include "arm_nnexamples_cifar10_inputs.h"
|
||||
|
||||
#ifdef _RTE_
|
||||
#include "RTE_Components.h"
|
||||
#ifdef RTE_Compiler_EventRecorder
|
||||
#include "EventRecorder.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// include the input and weights
|
||||
|
||||
static q7_t conv1_wt[CONV1_IM_CH * CONV1_KER_DIM * CONV1_KER_DIM * CONV1_OUT_CH] = CONV1_WT;
|
||||
static q7_t conv1_bias[CONV1_OUT_CH] = CONV1_BIAS;
|
||||
|
||||
static q7_t conv2_wt[CONV2_IM_CH * CONV2_KER_DIM * CONV2_KER_DIM * CONV2_OUT_CH] = CONV2_WT;
|
||||
static q7_t conv2_bias[CONV2_OUT_CH] = CONV2_BIAS;
|
||||
|
||||
static q7_t conv3_wt[CONV3_IM_CH * CONV3_KER_DIM * CONV3_KER_DIM * CONV3_OUT_CH] = CONV3_WT;
|
||||
static q7_t conv3_bias[CONV3_OUT_CH] = CONV3_BIAS;
|
||||
|
||||
static q7_t ip1_wt[IP1_DIM * IP1_OUT] = IP1_WT;
|
||||
static q7_t ip1_bias[IP1_OUT] = IP1_BIAS;
|
||||
|
||||
/* Here the image_data should be the raw uint8 type RGB image in [RGB, RGB, RGB ... RGB] format */
|
||||
uint8_t image_data[CONV1_IM_CH * CONV1_IM_DIM * CONV1_IM_DIM] = IMG_DATA;
|
||||
q7_t output_data[IP1_OUT];
|
||||
|
||||
//vector buffer: max(im2col buffer,average pool buffer, fully connected buffer)
|
||||
q7_t col_buffer[2 * 5 * 5 * 32 * 2];
|
||||
|
||||
q7_t scratch_buffer[32 * 32 * 10 * 4];
|
||||
|
||||
int main()
|
||||
{
|
||||
#ifdef RTE_Compiler_EventRecorder
|
||||
EventRecorderInitialize (EventRecordAll, 1); // initialize and start Event Recorder
|
||||
#endif
|
||||
|
||||
printf("start execution\n");
|
||||
/* start the execution */
|
||||
|
||||
q7_t *img_buffer1 = scratch_buffer;
|
||||
q7_t *img_buffer2 = img_buffer1 + 32 * 32 * 32;
|
||||
|
||||
/* input pre-processing */
|
||||
int mean_data[3] = INPUT_MEAN_SHIFT;
|
||||
unsigned int scale_data[3] = INPUT_RIGHT_SHIFT;
|
||||
for (int i=0;i<32*32*3; i+=3) {
|
||||
img_buffer2[i] = (q7_t)__SSAT( ((((int)image_data[i] - mean_data[0])<<7) + (0x1<<(scale_data[0]-1)))
|
||||
>> scale_data[0], 8);
|
||||
img_buffer2[i+1] = (q7_t)__SSAT( ((((int)image_data[i+1] - mean_data[1])<<7) + (0x1<<(scale_data[1]-1)))
|
||||
>> scale_data[1], 8);
|
||||
img_buffer2[i+2] = (q7_t)__SSAT( ((((int)image_data[i+2] - mean_data[2])<<7) + (0x1<<(scale_data[2]-1)))
|
||||
>> scale_data[2], 8);
|
||||
}
|
||||
|
||||
// conv1 img_buffer2 -> img_buffer1
|
||||
arm_convolve_HWC_q7_RGB(img_buffer2, CONV1_IM_DIM, CONV1_IM_CH, conv1_wt, CONV1_OUT_CH, CONV1_KER_DIM, CONV1_PADDING,
|
||||
CONV1_STRIDE, conv1_bias, CONV1_BIAS_LSHIFT, CONV1_OUT_RSHIFT, img_buffer1, CONV1_OUT_DIM,
|
||||
(q15_t *) col_buffer, NULL);
|
||||
|
||||
arm_relu_q7(img_buffer1, CONV1_OUT_DIM * CONV1_OUT_DIM * CONV1_OUT_CH);
|
||||
|
||||
// pool1 img_buffer1 -> img_buffer2
|
||||
arm_maxpool_q7_HWC(img_buffer1, CONV1_OUT_DIM, CONV1_OUT_CH, POOL1_KER_DIM,
|
||||
POOL1_PADDING, POOL1_STRIDE, POOL1_OUT_DIM, NULL, img_buffer2);
|
||||
|
||||
// conv2 img_buffer2 -> img_buffer1
|
||||
arm_convolve_HWC_q7_fast(img_buffer2, CONV2_IM_DIM, CONV2_IM_CH, conv2_wt, CONV2_OUT_CH, CONV2_KER_DIM,
|
||||
CONV2_PADDING, CONV2_STRIDE, conv2_bias, CONV2_BIAS_LSHIFT, CONV2_OUT_RSHIFT, img_buffer1,
|
||||
CONV2_OUT_DIM, (q15_t *) col_buffer, NULL);
|
||||
|
||||
arm_relu_q7(img_buffer1, CONV2_OUT_DIM * CONV2_OUT_DIM * CONV2_OUT_CH);
|
||||
|
||||
// pool2 img_buffer1 -> img_buffer2
|
||||
arm_maxpool_q7_HWC(img_buffer1, CONV2_OUT_DIM, CONV2_OUT_CH, POOL2_KER_DIM,
|
||||
POOL2_PADDING, POOL2_STRIDE, POOL2_OUT_DIM, col_buffer, img_buffer2);
|
||||
|
||||
// conv3 img_buffer2 -> img_buffer1
|
||||
arm_convolve_HWC_q7_fast(img_buffer2, CONV3_IM_DIM, CONV3_IM_CH, conv3_wt, CONV3_OUT_CH, CONV3_KER_DIM,
|
||||
CONV3_PADDING, CONV3_STRIDE, conv3_bias, CONV3_BIAS_LSHIFT, CONV3_OUT_RSHIFT, img_buffer1,
|
||||
CONV3_OUT_DIM, (q15_t *) col_buffer, NULL);
|
||||
|
||||
arm_relu_q7(img_buffer1, CONV3_OUT_DIM * CONV3_OUT_DIM * CONV3_OUT_CH);
|
||||
|
||||
// pool3 img_buffer-> img_buffer2
|
||||
arm_maxpool_q7_HWC(img_buffer1, CONV3_OUT_DIM, CONV3_OUT_CH, POOL3_KER_DIM,
|
||||
POOL3_PADDING, POOL3_STRIDE, POOL3_OUT_DIM, col_buffer, img_buffer2);
|
||||
|
||||
arm_fully_connected_q7_opt(img_buffer2, ip1_wt, IP1_DIM, IP1_OUT, IP1_BIAS_LSHIFT, IP1_OUT_RSHIFT, ip1_bias,
|
||||
output_data, (q15_t *) img_buffer1);
|
||||
|
||||
arm_softmax_q7(output_data, 10, output_data);
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
printf("%d: %d\n", i, output_data[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
File diff suppressed because one or more lines are too long
@ -0,0 +1,43 @@
|
||||
#define CONV1_IM_DIM 32
|
||||
#define CONV1_IM_CH 3
|
||||
#define CONV1_KER_DIM 5
|
||||
#define CONV1_PADDING 2
|
||||
#define CONV1_STRIDE 1
|
||||
#define CONV1_OUT_CH 32
|
||||
#define CONV1_OUT_DIM 32
|
||||
|
||||
#define POOL1_KER_DIM 3
|
||||
#define POOL1_STRIDE 2
|
||||
#define POOL1_PADDING 0
|
||||
#define POOL1_OUT_DIM 16
|
||||
|
||||
#define CONV2_IM_DIM 16
|
||||
#define CONV2_IM_CH 32
|
||||
#define CONV2_KER_DIM 5
|
||||
#define CONV2_PADDING 2
|
||||
#define CONV2_STRIDE 1
|
||||
#define CONV2_OUT_CH 16
|
||||
#define CONV2_OUT_DIM 16
|
||||
|
||||
#define POOL2_KER_DIM 3
|
||||
#define POOL2_STRIDE 2
|
||||
#define POOL2_PADDING 0
|
||||
#define POOL2_OUT_DIM 8
|
||||
|
||||
#define CONV3_IM_DIM 8
|
||||
#define CONV3_IM_CH 16
|
||||
#define CONV3_KER_DIM 5
|
||||
#define CONV3_PADDING 2
|
||||
#define CONV3_STRIDE 1
|
||||
#define CONV3_OUT_CH 32
|
||||
#define CONV3_OUT_DIM 8
|
||||
|
||||
#define POOL3_KER_DIM 3
|
||||
#define POOL3_STRIDE 2
|
||||
#define POOL3_PADDING 0
|
||||
#define POOL3_OUT_DIM 4
|
||||
|
||||
#define IP1_DIM 4*4*32
|
||||
#define IP1_IM_DIM 4
|
||||
#define IP1_IM_CH 32
|
||||
#define IP1_OUT 10
|
File diff suppressed because one or more lines are too long
@ -0,0 +1,4 @@
|
||||
CMSIS NN Lib example arm_nnexample_cifar10 for
|
||||
Cortex-M4 and Cortex-M7.
|
||||
|
||||
The example is configured for uVision Simulator.
|
@ -0,0 +1,44 @@
|
||||
/*------------------------------------------------------------------------------
|
||||
* MDK - Component ::Event Recorder
|
||||
* Copyright (c) 2016 ARM Germany GmbH. All rights reserved.
|
||||
*------------------------------------------------------------------------------
|
||||
* Name: EventRecorderConf.h
|
||||
* Purpose: Event Recorder Configuration
|
||||
* Rev.: V1.0.0
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
//-------- <<< Use Configuration Wizard in Context Menu >>> --------------------
|
||||
|
||||
// <h>Event Recorder
|
||||
|
||||
// <o>Number of Records
|
||||
// <8=>8 <16=>16 <32=>32 <64=>64 <128=>128 <256=>256 <512=>512 <1024=>1024
|
||||
// <2048=>2048 <4096=>4096 <8192=>8192 <16384=>16384 <32768=>32768
|
||||
// <65536=>65536 <131072=>131072 <262144=>262144 <524288=>524288
|
||||
// <1048576=>1048576
|
||||
// <i>Configure size of Event Record Buffer (each record is 16 bytes)
|
||||
// <i>Must be 2^n (min=8, max=1048576)
|
||||
#define EVENT_RECORD_COUNT 64U
|
||||
|
||||
// <o>Time Stamp Source
|
||||
// <0=> DWT Cycle Counter <1=> SysTick
|
||||
// <3=> User Timer (Normal Reset) <4=> User Timer (Power-On Reset)
|
||||
// <i>Selects source for 32-bit time stamp
|
||||
#define EVENT_TIMESTAMP_SOURCE 1
|
||||
|
||||
// <h>SysTick Configuration
|
||||
// <i>Configure values when Time Stamp Source is set to SysTick
|
||||
|
||||
// <o>SysTick Input Clock Frequency [Hz] <1-1000000000>
|
||||
// <i>Defines SysTick input clock (typical identical with processor clock)
|
||||
#define SYSTICK_CLOCK 100000000U
|
||||
|
||||
// <o>SysTick Interrupt Period [us] <1-1000000000>
|
||||
// <i>Defines time period of the SysTick timer interrupt
|
||||
#define SYSTICK_PERIOD_US 1000U
|
||||
|
||||
// </h>
|
||||
|
||||
// </h>
|
||||
|
||||
//------------- <<< end of configuration section >>> ---------------------------
|
@ -0,0 +1,242 @@
|
||||
;/**************************************************************************//**
|
||||
; * @file startup_ARMCM0.s
|
||||
; * @brief CMSIS Core Device Startup File for
|
||||
; * ARMCM0 Device Series
|
||||
; * @version V5.00
|
||||
; * @date 02. March 2016
|
||||
; ******************************************************************************/
|
||||
;/*
|
||||
; * Copyright (c) 2009-2016 ARM Limited. All rights reserved.
|
||||
; *
|
||||
; * 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
|
||||
; *
|
||||
; * 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.
|
||||
; */
|
||||
|
||||
;/*
|
||||
;//-------- <<< Use Configuration Wizard in Context Menu >>> ------------------
|
||||
;*/
|
||||
|
||||
|
||||
; <h> Stack Configuration
|
||||
; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
|
||||
; </h>
|
||||
|
||||
Stack_Size EQU 0x00000400
|
||||
|
||||
AREA STACK, NOINIT, READWRITE, ALIGN=3
|
||||
Stack_Mem SPACE Stack_Size
|
||||
__initial_sp
|
||||
|
||||
|
||||
; <h> Heap Configuration
|
||||
; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
|
||||
; </h>
|
||||
|
||||
Heap_Size EQU 0x00000C00
|
||||
|
||||
AREA HEAP, NOINIT, READWRITE, ALIGN=3
|
||||
__heap_base
|
||||
Heap_Mem SPACE Heap_Size
|
||||
__heap_limit
|
||||
|
||||
|
||||
PRESERVE8
|
||||
THUMB
|
||||
|
||||
|
||||
; Vector Table Mapped to Address 0 at Reset
|
||||
|
||||
AREA RESET, DATA, READONLY
|
||||
EXPORT __Vectors
|
||||
EXPORT __Vectors_End
|
||||
EXPORT __Vectors_Size
|
||||
|
||||
__Vectors DCD __initial_sp ; Top of Stack
|
||||
DCD Reset_Handler ; Reset Handler
|
||||
DCD NMI_Handler ; NMI Handler
|
||||
DCD HardFault_Handler ; Hard Fault Handler
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD SVC_Handler ; SVCall Handler
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD PendSV_Handler ; PendSV Handler
|
||||
DCD SysTick_Handler ; SysTick Handler
|
||||
|
||||
; External Interrupts
|
||||
DCD WDT_IRQHandler ; 0: Watchdog Timer
|
||||
DCD RTC_IRQHandler ; 1: Real Time Clock
|
||||
DCD TIM0_IRQHandler ; 2: Timer0 / Timer1
|
||||
DCD TIM2_IRQHandler ; 3: Timer2 / Timer3
|
||||
DCD MCIA_IRQHandler ; 4: MCIa
|
||||
DCD MCIB_IRQHandler ; 5: MCIb
|
||||
DCD UART0_IRQHandler ; 6: UART0 - DUT FPGA
|
||||
DCD UART1_IRQHandler ; 7: UART1 - DUT FPGA
|
||||
DCD UART2_IRQHandler ; 8: UART2 - DUT FPGA
|
||||
DCD UART4_IRQHandler ; 9: UART4 - not connected
|
||||
DCD AACI_IRQHandler ; 10: AACI / AC97
|
||||
DCD CLCD_IRQHandler ; 11: CLCD Combined Interrupt
|
||||
DCD ENET_IRQHandler ; 12: Ethernet
|
||||
DCD USBDC_IRQHandler ; 13: USB Device
|
||||
DCD USBHC_IRQHandler ; 14: USB Host Controller
|
||||
DCD CHLCD_IRQHandler ; 15: Character LCD
|
||||
DCD FLEXRAY_IRQHandler ; 16: Flexray
|
||||
DCD CAN_IRQHandler ; 17: CAN
|
||||
DCD LIN_IRQHandler ; 18: LIN
|
||||
DCD I2C_IRQHandler ; 19: I2C ADC/DAC
|
||||
DCD 0 ; 20: Reserved
|
||||
DCD 0 ; 21: Reserved
|
||||
DCD 0 ; 22: Reserved
|
||||
DCD 0 ; 23: Reserved
|
||||
DCD 0 ; 24: Reserved
|
||||
DCD 0 ; 25: Reserved
|
||||
DCD 0 ; 26: Reserved
|
||||
DCD 0 ; 27: Reserved
|
||||
DCD CPU_CLCD_IRQHandler ; 28: Reserved - CPU FPGA CLCD
|
||||
DCD 0 ; 29: Reserved - CPU FPGA
|
||||
DCD UART3_IRQHandler ; 30: UART3 - CPU FPGA
|
||||
DCD SPI_IRQHandler ; 31: SPI Touchscreen - CPU FPGA
|
||||
__Vectors_End
|
||||
|
||||
__Vectors_Size EQU __Vectors_End - __Vectors
|
||||
|
||||
AREA |.text|, CODE, READONLY
|
||||
|
||||
|
||||
; Reset Handler
|
||||
|
||||
Reset_Handler PROC
|
||||
EXPORT Reset_Handler [WEAK]
|
||||
IMPORT SystemInit
|
||||
IMPORT __main
|
||||
LDR R0, =SystemInit
|
||||
BLX R0
|
||||
LDR R0, =__main
|
||||
BX R0
|
||||
ENDP
|
||||
|
||||
|
||||
; Dummy Exception Handlers (infinite loops which can be modified)
|
||||
|
||||
NMI_Handler PROC
|
||||
EXPORT NMI_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
HardFault_Handler\
|
||||
PROC
|
||||
EXPORT HardFault_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
SVC_Handler PROC
|
||||
EXPORT SVC_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
PendSV_Handler PROC
|
||||
EXPORT PendSV_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
SysTick_Handler PROC
|
||||
EXPORT SysTick_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
|
||||
Default_Handler PROC
|
||||
|
||||
EXPORT WDT_IRQHandler [WEAK]
|
||||
EXPORT RTC_IRQHandler [WEAK]
|
||||
EXPORT TIM0_IRQHandler [WEAK]
|
||||
EXPORT TIM2_IRQHandler [WEAK]
|
||||
EXPORT MCIA_IRQHandler [WEAK]
|
||||
EXPORT MCIB_IRQHandler [WEAK]
|
||||
EXPORT UART0_IRQHandler [WEAK]
|
||||
EXPORT UART1_IRQHandler [WEAK]
|
||||
EXPORT UART2_IRQHandler [WEAK]
|
||||
EXPORT UART3_IRQHandler [WEAK]
|
||||
EXPORT UART4_IRQHandler [WEAK]
|
||||
EXPORT AACI_IRQHandler [WEAK]
|
||||
EXPORT CLCD_IRQHandler [WEAK]
|
||||
EXPORT ENET_IRQHandler [WEAK]
|
||||
EXPORT USBDC_IRQHandler [WEAK]
|
||||
EXPORT USBHC_IRQHandler [WEAK]
|
||||
EXPORT CHLCD_IRQHandler [WEAK]
|
||||
EXPORT FLEXRAY_IRQHandler [WEAK]
|
||||
EXPORT CAN_IRQHandler [WEAK]
|
||||
EXPORT LIN_IRQHandler [WEAK]
|
||||
EXPORT I2C_IRQHandler [WEAK]
|
||||
EXPORT CPU_CLCD_IRQHandler [WEAK]
|
||||
EXPORT SPI_IRQHandler [WEAK]
|
||||
|
||||
WDT_IRQHandler
|
||||
RTC_IRQHandler
|
||||
TIM0_IRQHandler
|
||||
TIM2_IRQHandler
|
||||
MCIA_IRQHandler
|
||||
MCIB_IRQHandler
|
||||
UART0_IRQHandler
|
||||
UART1_IRQHandler
|
||||
UART2_IRQHandler
|
||||
UART3_IRQHandler
|
||||
UART4_IRQHandler
|
||||
AACI_IRQHandler
|
||||
CLCD_IRQHandler
|
||||
ENET_IRQHandler
|
||||
USBDC_IRQHandler
|
||||
USBHC_IRQHandler
|
||||
CHLCD_IRQHandler
|
||||
FLEXRAY_IRQHandler
|
||||
CAN_IRQHandler
|
||||
LIN_IRQHandler
|
||||
I2C_IRQHandler
|
||||
CPU_CLCD_IRQHandler
|
||||
SPI_IRQHandler
|
||||
B .
|
||||
|
||||
ENDP
|
||||
|
||||
|
||||
ALIGN
|
||||
|
||||
|
||||
; User Initial Stack & Heap
|
||||
|
||||
IF :DEF:__MICROLIB
|
||||
|
||||
EXPORT __initial_sp
|
||||
EXPORT __heap_base
|
||||
EXPORT __heap_limit
|
||||
|
||||
ELSE
|
||||
|
||||
IMPORT __use_two_region_memory
|
||||
EXPORT __user_initial_stackheap
|
||||
|
||||
__user_initial_stackheap PROC
|
||||
LDR R0, = Heap_Mem
|
||||
LDR R1, =(Stack_Mem + Stack_Size)
|
||||
LDR R2, = (Heap_Mem + Heap_Size)
|
||||
LDR R3, = Stack_Mem
|
||||
BX LR
|
||||
ENDP
|
||||
|
||||
ALIGN
|
||||
|
||||
ENDIF
|
||||
|
||||
|
||||
END
|
@ -0,0 +1,56 @@
|
||||
/**************************************************************************//**
|
||||
* @file system_ARMCM0.c
|
||||
* @brief CMSIS Device System Source File for
|
||||
* ARMCM0 Device Series
|
||||
* @version V5.00
|
||||
* @date 08. April 2016
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2016 ARM Limited. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "ARMCM0.h"
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Define clocks
|
||||
*----------------------------------------------------------------------------*/
|
||||
#define XTAL ( 5000000U) /* Oscillator frequency */
|
||||
|
||||
#define SYSTEM_CLOCK (5 * XTAL)
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
System Core Clock Variable
|
||||
*----------------------------------------------------------------------------*/
|
||||
uint32_t SystemCoreClock = SYSTEM_CLOCK;
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
System Core Clock update function
|
||||
*----------------------------------------------------------------------------*/
|
||||
void SystemCoreClockUpdate (void)
|
||||
{
|
||||
SystemCoreClock = SYSTEM_CLOCK;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
System initialization function
|
||||
*----------------------------------------------------------------------------*/
|
||||
void SystemInit (void)
|
||||
{
|
||||
SystemCoreClock = SYSTEM_CLOCK;
|
||||
}
|
@ -0,0 +1,262 @@
|
||||
;/**************************************************************************//**
|
||||
; * @file startup_ARMCM3.s
|
||||
; * @brief CMSIS Core Device Startup File for
|
||||
; * ARMCM3 Device Series
|
||||
; * @version V5.00
|
||||
; * @date 02. March 2016
|
||||
; ******************************************************************************/
|
||||
;/*
|
||||
; * Copyright (c) 2009-2016 ARM Limited. All rights reserved.
|
||||
; *
|
||||
; * 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
|
||||
; *
|
||||
; * 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.
|
||||
; */
|
||||
|
||||
;/*
|
||||
;//-------- <<< Use Configuration Wizard in Context Menu >>> ------------------
|
||||
;*/
|
||||
|
||||
|
||||
; <h> Stack Configuration
|
||||
; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
|
||||
; </h>
|
||||
|
||||
Stack_Size EQU 0x00000400
|
||||
|
||||
AREA STACK, NOINIT, READWRITE, ALIGN=3
|
||||
Stack_Mem SPACE Stack_Size
|
||||
__initial_sp
|
||||
|
||||
|
||||
; <h> Heap Configuration
|
||||
; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
|
||||
; </h>
|
||||
|
||||
Heap_Size EQU 0x00000C00
|
||||
|
||||
AREA HEAP, NOINIT, READWRITE, ALIGN=3
|
||||
__heap_base
|
||||
Heap_Mem SPACE Heap_Size
|
||||
__heap_limit
|
||||
|
||||
|
||||
PRESERVE8
|
||||
THUMB
|
||||
|
||||
|
||||
; Vector Table Mapped to Address 0 at Reset
|
||||
|
||||
AREA RESET, DATA, READONLY
|
||||
EXPORT __Vectors
|
||||
EXPORT __Vectors_End
|
||||
EXPORT __Vectors_Size
|
||||
|
||||
__Vectors DCD __initial_sp ; Top of Stack
|
||||
DCD Reset_Handler ; Reset Handler
|
||||
DCD NMI_Handler ; NMI Handler
|
||||
DCD HardFault_Handler ; Hard Fault Handler
|
||||
DCD MemManage_Handler ; MPU Fault Handler
|
||||
DCD BusFault_Handler ; Bus Fault Handler
|
||||
DCD UsageFault_Handler ; Usage Fault Handler
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD SVC_Handler ; SVCall Handler
|
||||
DCD DebugMon_Handler ; Debug Monitor Handler
|
||||
DCD 0 ; Reserved
|
||||
DCD PendSV_Handler ; PendSV Handler
|
||||
DCD SysTick_Handler ; SysTick Handler
|
||||
|
||||
; External Interrupts
|
||||
DCD WDT_IRQHandler ; 0: Watchdog Timer
|
||||
DCD RTC_IRQHandler ; 1: Real Time Clock
|
||||
DCD TIM0_IRQHandler ; 2: Timer0 / Timer1
|
||||
DCD TIM2_IRQHandler ; 3: Timer2 / Timer3
|
||||
DCD MCIA_IRQHandler ; 4: MCIa
|
||||
DCD MCIB_IRQHandler ; 5: MCIb
|
||||
DCD UART0_IRQHandler ; 6: UART0 - DUT FPGA
|
||||
DCD UART1_IRQHandler ; 7: UART1 - DUT FPGA
|
||||
DCD UART2_IRQHandler ; 8: UART2 - DUT FPGA
|
||||
DCD UART4_IRQHandler ; 9: UART4 - not connected
|
||||
DCD AACI_IRQHandler ; 10: AACI / AC97
|
||||
DCD CLCD_IRQHandler ; 11: CLCD Combined Interrupt
|
||||
DCD ENET_IRQHandler ; 12: Ethernet
|
||||
DCD USBDC_IRQHandler ; 13: USB Device
|
||||
DCD USBHC_IRQHandler ; 14: USB Host Controller
|
||||
DCD CHLCD_IRQHandler ; 15: Character LCD
|
||||
DCD FLEXRAY_IRQHandler ; 16: Flexray
|
||||
DCD CAN_IRQHandler ; 17: CAN
|
||||
DCD LIN_IRQHandler ; 18: LIN
|
||||
DCD I2C_IRQHandler ; 19: I2C ADC/DAC
|
||||
DCD 0 ; 20: Reserved
|
||||
DCD 0 ; 21: Reserved
|
||||
DCD 0 ; 22: Reserved
|
||||
DCD 0 ; 23: Reserved
|
||||
DCD 0 ; 24: Reserved
|
||||
DCD 0 ; 25: Reserved
|
||||
DCD 0 ; 26: Reserved
|
||||
DCD 0 ; 27: Reserved
|
||||
DCD CPU_CLCD_IRQHandler ; 28: Reserved - CPU FPGA CLCD
|
||||
DCD 0 ; 29: Reserved - CPU FPGA
|
||||
DCD UART3_IRQHandler ; 30: UART3 - CPU FPGA
|
||||
DCD SPI_IRQHandler ; 31: SPI Touchscreen - CPU FPGA
|
||||
__Vectors_End
|
||||
|
||||
__Vectors_Size EQU __Vectors_End - __Vectors
|
||||
|
||||
AREA |.text|, CODE, READONLY
|
||||
|
||||
|
||||
; Reset Handler
|
||||
|
||||
Reset_Handler PROC
|
||||
EXPORT Reset_Handler [WEAK]
|
||||
IMPORT SystemInit
|
||||
IMPORT __main
|
||||
LDR R0, =SystemInit
|
||||
BLX R0
|
||||
LDR R0, =__main
|
||||
BX R0
|
||||
ENDP
|
||||
|
||||
|
||||
; Dummy Exception Handlers (infinite loops which can be modified)
|
||||
|
||||
NMI_Handler PROC
|
||||
EXPORT NMI_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
HardFault_Handler\
|
||||
PROC
|
||||
EXPORT HardFault_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
MemManage_Handler\
|
||||
PROC
|
||||
EXPORT MemManage_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
BusFault_Handler\
|
||||
PROC
|
||||
EXPORT BusFault_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
UsageFault_Handler\
|
||||
PROC
|
||||
EXPORT UsageFault_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
SVC_Handler PROC
|
||||
EXPORT SVC_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
DebugMon_Handler\
|
||||
PROC
|
||||
EXPORT DebugMon_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
PendSV_Handler PROC
|
||||
EXPORT PendSV_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
SysTick_Handler PROC
|
||||
EXPORT SysTick_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
|
||||
Default_Handler PROC
|
||||
|
||||
EXPORT WDT_IRQHandler [WEAK]
|
||||
EXPORT RTC_IRQHandler [WEAK]
|
||||
EXPORT TIM0_IRQHandler [WEAK]
|
||||
EXPORT TIM2_IRQHandler [WEAK]
|
||||
EXPORT MCIA_IRQHandler [WEAK]
|
||||
EXPORT MCIB_IRQHandler [WEAK]
|
||||
EXPORT UART0_IRQHandler [WEAK]
|
||||
EXPORT UART1_IRQHandler [WEAK]
|
||||
EXPORT UART2_IRQHandler [WEAK]
|
||||
EXPORT UART3_IRQHandler [WEAK]
|
||||
EXPORT UART4_IRQHandler [WEAK]
|
||||
EXPORT AACI_IRQHandler [WEAK]
|
||||
EXPORT CLCD_IRQHandler [WEAK]
|
||||
EXPORT ENET_IRQHandler [WEAK]
|
||||
EXPORT USBDC_IRQHandler [WEAK]
|
||||
EXPORT USBHC_IRQHandler [WEAK]
|
||||
EXPORT CHLCD_IRQHandler [WEAK]
|
||||
EXPORT FLEXRAY_IRQHandler [WEAK]
|
||||
EXPORT CAN_IRQHandler [WEAK]
|
||||
EXPORT LIN_IRQHandler [WEAK]
|
||||
EXPORT I2C_IRQHandler [WEAK]
|
||||
EXPORT CPU_CLCD_IRQHandler [WEAK]
|
||||
EXPORT SPI_IRQHandler [WEAK]
|
||||
|
||||
WDT_IRQHandler
|
||||
RTC_IRQHandler
|
||||
TIM0_IRQHandler
|
||||
TIM2_IRQHandler
|
||||
MCIA_IRQHandler
|
||||
MCIB_IRQHandler
|
||||
UART0_IRQHandler
|
||||
UART1_IRQHandler
|
||||
UART2_IRQHandler
|
||||
UART3_IRQHandler
|
||||
UART4_IRQHandler
|
||||
AACI_IRQHandler
|
||||
CLCD_IRQHandler
|
||||
ENET_IRQHandler
|
||||
USBDC_IRQHandler
|
||||
USBHC_IRQHandler
|
||||
CHLCD_IRQHandler
|
||||
FLEXRAY_IRQHandler
|
||||
CAN_IRQHandler
|
||||
LIN_IRQHandler
|
||||
I2C_IRQHandler
|
||||
CPU_CLCD_IRQHandler
|
||||
SPI_IRQHandler
|
||||
B .
|
||||
|
||||
ENDP
|
||||
|
||||
|
||||
ALIGN
|
||||
|
||||
|
||||
; User Initial Stack & Heap
|
||||
|
||||
IF :DEF:__MICROLIB
|
||||
|
||||
EXPORT __initial_sp
|
||||
EXPORT __heap_base
|
||||
EXPORT __heap_limit
|
||||
|
||||
ELSE
|
||||
|
||||
IMPORT __use_two_region_memory
|
||||
EXPORT __user_initial_stackheap
|
||||
|
||||
__user_initial_stackheap PROC
|
||||
LDR R0, = Heap_Mem
|
||||
LDR R1, =(Stack_Mem + Stack_Size)
|
||||
LDR R2, = (Heap_Mem + Heap_Size)
|
||||
LDR R3, = Stack_Mem
|
||||
BX LR
|
||||
ENDP
|
||||
|
||||
ALIGN
|
||||
|
||||
ENDIF
|
||||
|
||||
|
||||
END
|
@ -0,0 +1,68 @@
|
||||
/**************************************************************************//**
|
||||
* @file system_ARMCM3.c
|
||||
* @brief CMSIS Device System Source File for
|
||||
* ARMCM3 Device Series
|
||||
* @version V5.00
|
||||
* @date 08. April 2016
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2016 ARM Limited. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "ARMCM3.h"
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Define clocks
|
||||
*----------------------------------------------------------------------------*/
|
||||
#define XTAL ( 5000000U) /* Oscillator frequency */
|
||||
|
||||
#define SYSTEM_CLOCK (5 * XTAL)
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Externals
|
||||
*----------------------------------------------------------------------------*/
|
||||
#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1)
|
||||
extern uint32_t __Vectors;
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
System Core Clock Variable
|
||||
*----------------------------------------------------------------------------*/
|
||||
uint32_t SystemCoreClock = SYSTEM_CLOCK;
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
System Core Clock update function
|
||||
*----------------------------------------------------------------------------*/
|
||||
void SystemCoreClockUpdate (void)
|
||||
{
|
||||
SystemCoreClock = SYSTEM_CLOCK;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
System initialization function
|
||||
*----------------------------------------------------------------------------*/
|
||||
void SystemInit (void)
|
||||
{
|
||||
|
||||
#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1)
|
||||
SCB->VTOR = (uint32_t) &__Vectors;
|
||||
#endif
|
||||
|
||||
SystemCoreClock = SYSTEM_CLOCK;
|
||||
}
|
@ -0,0 +1,262 @@
|
||||
;/**************************************************************************//**
|
||||
; * @file startup_ARMCM4.s
|
||||
; * @brief CMSIS Core Device Startup File for
|
||||
; * ARMCM4 Device Series
|
||||
; * @version V5.00
|
||||
; * @date 02. March 2016
|
||||
; ******************************************************************************/
|
||||
;/*
|
||||
; * Copyright (c) 2009-2016 ARM Limited. All rights reserved.
|
||||
; *
|
||||
; * 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
|
||||
; *
|
||||
; * 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.
|
||||
; */
|
||||
|
||||
;/*
|
||||
;//-------- <<< Use Configuration Wizard in Context Menu >>> ------------------
|
||||
;*/
|
||||
|
||||
|
||||
; <h> Stack Configuration
|
||||
; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
|
||||
; </h>
|
||||
|
||||
Stack_Size EQU 0x00000400
|
||||
|
||||
AREA STACK, NOINIT, READWRITE, ALIGN=3
|
||||
Stack_Mem SPACE Stack_Size
|
||||
__initial_sp
|
||||
|
||||
|
||||
; <h> Heap Configuration
|
||||
; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
|
||||
; </h>
|
||||
|
||||
Heap_Size EQU 0x00000C00
|
||||
|
||||
AREA HEAP, NOINIT, READWRITE, ALIGN=3
|
||||
__heap_base
|
||||
Heap_Mem SPACE Heap_Size
|
||||
__heap_limit
|
||||
|
||||
|
||||
PRESERVE8
|
||||
THUMB
|
||||
|
||||
|
||||
; Vector Table Mapped to Address 0 at Reset
|
||||
|
||||
AREA RESET, DATA, READONLY
|
||||
EXPORT __Vectors
|
||||
EXPORT __Vectors_End
|
||||
EXPORT __Vectors_Size
|
||||
|
||||
__Vectors DCD __initial_sp ; Top of Stack
|
||||
DCD Reset_Handler ; Reset Handler
|
||||
DCD NMI_Handler ; NMI Handler
|
||||
DCD HardFault_Handler ; Hard Fault Handler
|
||||
DCD MemManage_Handler ; MPU Fault Handler
|
||||
DCD BusFault_Handler ; Bus Fault Handler
|
||||
DCD UsageFault_Handler ; Usage Fault Handler
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD SVC_Handler ; SVCall Handler
|
||||
DCD DebugMon_Handler ; Debug Monitor Handler
|
||||
DCD 0 ; Reserved
|
||||
DCD PendSV_Handler ; PendSV Handler
|
||||
DCD SysTick_Handler ; SysTick Handler
|
||||
|
||||
; External Interrupts
|
||||
DCD WDT_IRQHandler ; 0: Watchdog Timer
|
||||
DCD RTC_IRQHandler ; 1: Real Time Clock
|
||||
DCD TIM0_IRQHandler ; 2: Timer0 / Timer1
|
||||
DCD TIM2_IRQHandler ; 3: Timer2 / Timer3
|
||||
DCD MCIA_IRQHandler ; 4: MCIa
|
||||
DCD MCIB_IRQHandler ; 5: MCIb
|
||||
DCD UART0_IRQHandler ; 6: UART0 - DUT FPGA
|
||||
DCD UART1_IRQHandler ; 7: UART1 - DUT FPGA
|
||||
DCD UART2_IRQHandler ; 8: UART2 - DUT FPGA
|
||||
DCD UART4_IRQHandler ; 9: UART4 - not connected
|
||||
DCD AACI_IRQHandler ; 10: AACI / AC97
|
||||
DCD CLCD_IRQHandler ; 11: CLCD Combined Interrupt
|
||||
DCD ENET_IRQHandler ; 12: Ethernet
|
||||
DCD USBDC_IRQHandler ; 13: USB Device
|
||||
DCD USBHC_IRQHandler ; 14: USB Host Controller
|
||||
DCD CHLCD_IRQHandler ; 15: Character LCD
|
||||
DCD FLEXRAY_IRQHandler ; 16: Flexray
|
||||
DCD CAN_IRQHandler ; 17: CAN
|
||||
DCD LIN_IRQHandler ; 18: LIN
|
||||
DCD I2C_IRQHandler ; 19: I2C ADC/DAC
|
||||
DCD 0 ; 20: Reserved
|
||||
DCD 0 ; 21: Reserved
|
||||
DCD 0 ; 22: Reserved
|
||||
DCD 0 ; 23: Reserved
|
||||
DCD 0 ; 24: Reserved
|
||||
DCD 0 ; 25: Reserved
|
||||
DCD 0 ; 26: Reserved
|
||||
DCD 0 ; 27: Reserved
|
||||
DCD CPU_CLCD_IRQHandler ; 28: Reserved - CPU FPGA CLCD
|
||||
DCD 0 ; 29: Reserved - CPU FPGA
|
||||
DCD UART3_IRQHandler ; 30: UART3 - CPU FPGA
|
||||
DCD SPI_IRQHandler ; 31: SPI Touchscreen - CPU FPGA
|
||||
__Vectors_End
|
||||
|
||||
__Vectors_Size EQU __Vectors_End - __Vectors
|
||||
|
||||
AREA |.text|, CODE, READONLY
|
||||
|
||||
|
||||
; Reset Handler
|
||||
|
||||
Reset_Handler PROC
|
||||
EXPORT Reset_Handler [WEAK]
|
||||
IMPORT SystemInit
|
||||
IMPORT __main
|
||||
LDR R0, =SystemInit
|
||||
BLX R0
|
||||
LDR R0, =__main
|
||||
BX R0
|
||||
ENDP
|
||||
|
||||
|
||||
; Dummy Exception Handlers (infinite loops which can be modified)
|
||||
|
||||
NMI_Handler PROC
|
||||
EXPORT NMI_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
HardFault_Handler\
|
||||
PROC
|
||||
EXPORT HardFault_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
MemManage_Handler\
|
||||
PROC
|
||||
EXPORT MemManage_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
BusFault_Handler\
|
||||
PROC
|
||||
EXPORT BusFault_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
UsageFault_Handler\
|
||||
PROC
|
||||
EXPORT UsageFault_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
SVC_Handler PROC
|
||||
EXPORT SVC_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
DebugMon_Handler\
|
||||
PROC
|
||||
EXPORT DebugMon_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
PendSV_Handler PROC
|
||||
EXPORT PendSV_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
SysTick_Handler PROC
|
||||
EXPORT SysTick_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
|
||||
Default_Handler PROC
|
||||
|
||||
EXPORT WDT_IRQHandler [WEAK]
|
||||
EXPORT RTC_IRQHandler [WEAK]
|
||||
EXPORT TIM0_IRQHandler [WEAK]
|
||||
EXPORT TIM2_IRQHandler [WEAK]
|
||||
EXPORT MCIA_IRQHandler [WEAK]
|
||||
EXPORT MCIB_IRQHandler [WEAK]
|
||||
EXPORT UART0_IRQHandler [WEAK]
|
||||
EXPORT UART1_IRQHandler [WEAK]
|
||||
EXPORT UART2_IRQHandler [WEAK]
|
||||
EXPORT UART3_IRQHandler [WEAK]
|
||||
EXPORT UART4_IRQHandler [WEAK]
|
||||
EXPORT AACI_IRQHandler [WEAK]
|
||||
EXPORT CLCD_IRQHandler [WEAK]
|
||||
EXPORT ENET_IRQHandler [WEAK]
|
||||
EXPORT USBDC_IRQHandler [WEAK]
|
||||
EXPORT USBHC_IRQHandler [WEAK]
|
||||
EXPORT CHLCD_IRQHandler [WEAK]
|
||||
EXPORT FLEXRAY_IRQHandler [WEAK]
|
||||
EXPORT CAN_IRQHandler [WEAK]
|
||||
EXPORT LIN_IRQHandler [WEAK]
|
||||
EXPORT I2C_IRQHandler [WEAK]
|
||||
EXPORT CPU_CLCD_IRQHandler [WEAK]
|
||||
EXPORT SPI_IRQHandler [WEAK]
|
||||
|
||||
WDT_IRQHandler
|
||||
RTC_IRQHandler
|
||||
TIM0_IRQHandler
|
||||
TIM2_IRQHandler
|
||||
MCIA_IRQHandler
|
||||
MCIB_IRQHandler
|
||||
UART0_IRQHandler
|
||||
UART1_IRQHandler
|
||||
UART2_IRQHandler
|
||||
UART3_IRQHandler
|
||||
UART4_IRQHandler
|
||||
AACI_IRQHandler
|
||||
CLCD_IRQHandler
|
||||
ENET_IRQHandler
|
||||
USBDC_IRQHandler
|
||||
USBHC_IRQHandler
|
||||
CHLCD_IRQHandler
|
||||
FLEXRAY_IRQHandler
|
||||
CAN_IRQHandler
|
||||
LIN_IRQHandler
|
||||
I2C_IRQHandler
|
||||
CPU_CLCD_IRQHandler
|
||||
SPI_IRQHandler
|
||||
B .
|
||||
|
||||
ENDP
|
||||
|
||||
|
||||
ALIGN
|
||||
|
||||
|
||||
; User Initial Stack & Heap
|
||||
|
||||
IF :DEF:__MICROLIB
|
||||
|
||||
EXPORT __initial_sp
|
||||
EXPORT __heap_base
|
||||
EXPORT __heap_limit
|
||||
|
||||
ELSE
|
||||
|
||||
IMPORT __use_two_region_memory
|
||||
EXPORT __user_initial_stackheap
|
||||
|
||||
__user_initial_stackheap PROC
|
||||
LDR R0, = Heap_Mem
|
||||
LDR R1, =(Stack_Mem + Stack_Size)
|
||||
LDR R2, = (Heap_Mem + Heap_Size)
|
||||
LDR R3, = Stack_Mem
|
||||
BX LR
|
||||
ENDP
|
||||
|
||||
ALIGN
|
||||
|
||||
ENDIF
|
||||
|
||||
|
||||
END
|
@ -0,0 +1,83 @@
|
||||
/**************************************************************************//**
|
||||
* @file system_ARMCM4.c
|
||||
* @brief CMSIS Device System Source File for
|
||||
* ARMCM4 Device Series
|
||||
* @version V5.00
|
||||
* @date 08. April 2016
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2016 ARM Limited. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if defined (ARMCM4)
|
||||
#include "ARMCM4.h"
|
||||
#elif defined (ARMCM4_FP)
|
||||
#include "ARMCM4_FP.h"
|
||||
#else
|
||||
#error device not specified!
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Define clocks
|
||||
*----------------------------------------------------------------------------*/
|
||||
#define XTAL ( 5000000U) /* Oscillator frequency */
|
||||
|
||||
#define SYSTEM_CLOCK (5 * XTAL)
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Externals
|
||||
*----------------------------------------------------------------------------*/
|
||||
#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1)
|
||||
extern uint32_t __Vectors;
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
System Core Clock Variable
|
||||
*----------------------------------------------------------------------------*/
|
||||
uint32_t SystemCoreClock = SYSTEM_CLOCK;
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
System Core Clock update function
|
||||
*----------------------------------------------------------------------------*/
|
||||
void SystemCoreClockUpdate (void)
|
||||
{
|
||||
SystemCoreClock = SYSTEM_CLOCK;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
System initialization function
|
||||
*----------------------------------------------------------------------------*/
|
||||
void SystemInit (void)
|
||||
{
|
||||
|
||||
#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1)
|
||||
SCB->VTOR = (uint32_t) &__Vectors;
|
||||
#endif
|
||||
|
||||
#if defined (__FPU_USED) && (__FPU_USED == 1)
|
||||
SCB->CPACR |= ((3U << 10*2) | /* set CP10 Full Access */
|
||||
(3U << 11*2) ); /* set CP11 Full Access */
|
||||
#endif
|
||||
|
||||
#ifdef UNALIGNED_SUPPORT_DISABLE
|
||||
SCB->CCR |= SCB_CCR_UNALIGN_TRP_Msk;
|
||||
#endif
|
||||
|
||||
SystemCoreClock = SYSTEM_CLOCK;
|
||||
}
|
@ -0,0 +1,295 @@
|
||||
/**************************************************************************//**
|
||||
* @file startup_ARMCM7.s
|
||||
* @brief CMSIS Core Device Startup File for
|
||||
* ARMCM7 Device Series
|
||||
* @version V5.00
|
||||
* @date 26. April 2016
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2016 ARM Limited. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Linker generated Symbols
|
||||
*----------------------------------------------------------------------------*/
|
||||
extern uint32_t __etext;
|
||||
extern uint32_t __data_start__;
|
||||
extern uint32_t __data_end__;
|
||||
extern uint32_t __copy_table_start__;
|
||||
extern uint32_t __copy_table_end__;
|
||||
extern uint32_t __zero_table_start__;
|
||||
extern uint32_t __zero_table_end__;
|
||||
extern uint32_t __bss_start__;
|
||||
extern uint32_t __bss_end__;
|
||||
extern uint32_t __StackTop;
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Exception / Interrupt Handler Function Prototype
|
||||
*----------------------------------------------------------------------------*/
|
||||
typedef void( *pFunc )( void );
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
External References
|
||||
*----------------------------------------------------------------------------*/
|
||||
#ifndef __START
|
||||
extern void _start(void) __attribute__((noreturn)); /* PreeMain (C library entry point) */
|
||||
#else
|
||||
extern int __START(void) __attribute__((noreturn)); /* main entry point */
|
||||
#endif
|
||||
|
||||
#ifndef __NO_SYSTEM_INIT
|
||||
extern void SystemInit (void); /* CMSIS System Initialization */
|
||||
#endif
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Internal References
|
||||
*----------------------------------------------------------------------------*/
|
||||
void Default_Handler(void); /* Default empty handler */
|
||||
void Reset_Handler(void); /* Reset Handler */
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
User Initial Stack & Heap
|
||||
*----------------------------------------------------------------------------*/
|
||||
#ifndef __STACK_SIZE
|
||||
#define __STACK_SIZE 0x00000400
|
||||
#endif
|
||||
static uint8_t stack[__STACK_SIZE] __attribute__ ((aligned(8), used, section(".stack")));
|
||||
|
||||
#ifndef __HEAP_SIZE
|
||||
#define __HEAP_SIZE 0x00000C00
|
||||
#endif
|
||||
#if __HEAP_SIZE > 0
|
||||
static uint8_t heap[__HEAP_SIZE] __attribute__ ((aligned(8), used, section(".heap")));
|
||||
#endif
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Exception / Interrupt Handler
|
||||
*----------------------------------------------------------------------------*/
|
||||
/* Cortex-M7 Processor Exceptions */
|
||||
void NMI_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void HardFault_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void MemManage_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void BusFault_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void UsageFault_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void SVC_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void DebugMon_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void PendSV_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void SysTick_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
|
||||
/* ARMCM7 Specific Interrupts */
|
||||
void WDT_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void RTC_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void TIM0_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void TIM2_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void MCIA_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void MCIB_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void UART0_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void UART1_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void UART2_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void UART4_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void AACI_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void CLCD_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void ENET_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void USBDC_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void USBHC_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void CHLCD_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void FLEXRAY_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void CAN_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void LIN_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void I2C_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void CPU_CLCD_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void UART3_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void SPI_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Exception / Interrupt Vector table
|
||||
*----------------------------------------------------------------------------*/
|
||||
const pFunc __Vectors[] __attribute__ ((section(".vectors"))) = {
|
||||
/* Cortex-M7 Exceptions Handler */
|
||||
(pFunc)((uint32_t)&__StackTop), /* Initial Stack Pointer */
|
||||
Reset_Handler, /* Reset Handler */
|
||||
NMI_Handler, /* NMI Handler */
|
||||
HardFault_Handler, /* Hard Fault Handler */
|
||||
MemManage_Handler, /* MPU Fault Handler */
|
||||
BusFault_Handler, /* Bus Fault Handler */
|
||||
UsageFault_Handler, /* Usage Fault Handler */
|
||||
0, /* Reserved */
|
||||
0, /* Reserved */
|
||||
0, /* Reserved */
|
||||
0, /* Reserved */
|
||||
SVC_Handler, /* SVCall Handler */
|
||||
DebugMon_Handler, /* Debug Monitor Handler */
|
||||
0, /* Reserved */
|
||||
PendSV_Handler, /* PendSV Handler */
|
||||
SysTick_Handler, /* SysTick Handler */
|
||||
|
||||
/* External interrupts */
|
||||
WDT_IRQHandler, /* 0: Watchdog Timer */
|
||||
RTC_IRQHandler, /* 1: Real Time Clock */
|
||||
TIM0_IRQHandler, /* 2: Timer0 / Timer1 */
|
||||
TIM2_IRQHandler, /* 3: Timer2 / Timer3 */
|
||||
MCIA_IRQHandler, /* 4: MCIa */
|
||||
MCIB_IRQHandler, /* 5: MCIb */
|
||||
UART0_IRQHandler, /* 6: UART0 - DUT FPGA */
|
||||
UART1_IRQHandler, /* 7: UART1 - DUT FPGA */
|
||||
UART2_IRQHandler, /* 8: UART2 - DUT FPGA */
|
||||
UART4_IRQHandler, /* 9: UART4 - not connected */
|
||||
AACI_IRQHandler, /* 10: AACI / AC97 */
|
||||
CLCD_IRQHandler, /* 11: CLCD Combined Interrupt */
|
||||
ENET_IRQHandler, /* 12: Ethernet */
|
||||
USBDC_IRQHandler, /* 13: USB Device */
|
||||
USBHC_IRQHandler, /* 14: USB Host Controller */
|
||||
CHLCD_IRQHandler, /* 15: Character LCD */
|
||||
FLEXRAY_IRQHandler, /* 16: Flexray */
|
||||
CAN_IRQHandler, /* 17: CAN */
|
||||
LIN_IRQHandler, /* 18: LIN */
|
||||
I2C_IRQHandler, /* 19: I2C ADC/DAC */
|
||||
0, /* 20: Reserved */
|
||||
0, /* 21: Reserved */
|
||||
0, /* 22: Reserved */
|
||||
0, /* 23: Reserved */
|
||||
0, /* 24: Reserved */
|
||||
0, /* 25: Reserved */
|
||||
0, /* 26: Reserved */
|
||||
0, /* 27: Reserved */
|
||||
CPU_CLCD_IRQHandler, /* 28: Reserved - CPU FPGA CLCD */
|
||||
0, /* 29: Reserved - CPU FPGA */
|
||||
UART3_IRQHandler, /* 30: UART3 - CPU FPGA */
|
||||
SPI_IRQHandler /* 31: SPI Touchscreen - CPU FPGA */
|
||||
};
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Reset Handler called on controller reset
|
||||
*----------------------------------------------------------------------------*/
|
||||
void Reset_Handler(void) {
|
||||
uint32_t *pSrc, *pDest;
|
||||
uint32_t *pTable __attribute__((unused));
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
pTable = &__copy_table_start__;
|
||||
|
||||
for (; pTable < &__copy_table_end__; pTable = pTable + 3) {
|
||||
pSrc = (uint32_t*)*(pTable + 0);
|
||||
pDest = (uint32_t*)*(pTable + 1);
|
||||
for (; pDest < (uint32_t*)(*(pTable + 1) + *(pTable + 2)) ; ) {
|
||||
*pDest++ = *pSrc++;
|
||||
}
|
||||
}
|
||||
#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.
|
||||
*/
|
||||
pSrc = &__etext;
|
||||
pDest = &__data_start__;
|
||||
|
||||
for ( ; pDest < &__data_end__ ; ) {
|
||||
*pDest++ = *pSrc++;
|
||||
}
|
||||
#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 __copy_table_start__ and __copy_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
|
||||
*/
|
||||
pTable = &__zero_table_start__;
|
||||
|
||||
for (; pTable < &__zero_table_end__; pTable = pTable + 2) {
|
||||
pDest = (uint32_t*)*(pTable + 0);
|
||||
for (; pDest < (uint32_t*)(*(pTable + 0) + *(pTable + 1)) ; ) {
|
||||
*pDest++ = 0;
|
||||
}
|
||||
}
|
||||
#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.
|
||||
*/
|
||||
pDest = &__bss_start__;
|
||||
|
||||
for ( ; pDest < &__bss_end__ ; ) {
|
||||
*pDest++ = 0UL;
|
||||
}
|
||||
#endif /* __STARTUP_CLEAR_BSS_MULTIPLE || __STARTUP_CLEAR_BSS */
|
||||
|
||||
#ifndef __NO_SYSTEM_INIT
|
||||
SystemInit();
|
||||
#endif
|
||||
|
||||
#ifndef __START
|
||||
#define __START _start
|
||||
#endif
|
||||
__START();
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Default Handler for Exceptions / Interrupts
|
||||
*----------------------------------------------------------------------------*/
|
||||
void Default_Handler(void) {
|
||||
|
||||
while(1);
|
||||
}
|
@ -0,0 +1,262 @@
|
||||
;/**************************************************************************//**
|
||||
; * @file startup_ARMCM7.s
|
||||
; * @brief CMSIS Core Device Startup File for
|
||||
; * ARMCM7 Device Series
|
||||
; * @version V5.00
|
||||
; * @date 02. March 2016
|
||||
; ******************************************************************************/
|
||||
;/*
|
||||
; * Copyright (c) 2009-2016 ARM Limited. All rights reserved.
|
||||
; *
|
||||
; * 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
|
||||
; *
|
||||
; * 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.
|
||||
; */
|
||||
|
||||
;/*
|
||||
;//-------- <<< Use Configuration Wizard in Context Menu >>> ------------------
|
||||
;*/
|
||||
|
||||
|
||||
; <h> Stack Configuration
|
||||
; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
|
||||
; </h>
|
||||
|
||||
Stack_Size EQU 0x00000400
|
||||
|
||||
AREA STACK, NOINIT, READWRITE, ALIGN=3
|
||||
Stack_Mem SPACE Stack_Size
|
||||
__initial_sp
|
||||
|
||||
|
||||
; <h> Heap Configuration
|
||||
; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
|
||||
; </h>
|
||||
|
||||
Heap_Size EQU 0x00000C00
|
||||
|
||||
AREA HEAP, NOINIT, READWRITE, ALIGN=3
|
||||
__heap_base
|
||||
Heap_Mem SPACE Heap_Size
|
||||
__heap_limit
|
||||
|
||||
|
||||
PRESERVE8
|
||||
THUMB
|
||||
|
||||
|
||||
; Vector Table Mapped to Address 0 at Reset
|
||||
|
||||
AREA RESET, DATA, READONLY
|
||||
EXPORT __Vectors
|
||||
EXPORT __Vectors_End
|
||||
EXPORT __Vectors_Size
|
||||
|
||||
__Vectors DCD __initial_sp ; Top of Stack
|
||||
DCD Reset_Handler ; Reset Handler
|
||||
DCD NMI_Handler ; NMI Handler
|
||||
DCD HardFault_Handler ; Hard Fault Handler
|
||||
DCD MemManage_Handler ; MPU Fault Handler
|
||||
DCD BusFault_Handler ; Bus Fault Handler
|
||||
DCD UsageFault_Handler ; Usage Fault Handler
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD SVC_Handler ; SVCall Handler
|
||||
DCD DebugMon_Handler ; Debug Monitor Handler
|
||||
DCD 0 ; Reserved
|
||||
DCD PendSV_Handler ; PendSV Handler
|
||||
DCD SysTick_Handler ; SysTick Handler
|
||||
|
||||
; External Interrupts
|
||||
DCD WDT_IRQHandler ; 0: Watchdog Timer
|
||||
DCD RTC_IRQHandler ; 1: Real Time Clock
|
||||
DCD TIM0_IRQHandler ; 2: Timer0 / Timer1
|
||||
DCD TIM2_IRQHandler ; 3: Timer2 / Timer3
|
||||
DCD MCIA_IRQHandler ; 4: MCIa
|
||||
DCD MCIB_IRQHandler ; 5: MCIb
|
||||
DCD UART0_IRQHandler ; 6: UART0 - DUT FPGA
|
||||
DCD UART1_IRQHandler ; 7: UART1 - DUT FPGA
|
||||
DCD UART2_IRQHandler ; 8: UART2 - DUT FPGA
|
||||
DCD UART4_IRQHandler ; 9: UART4 - not connected
|
||||
DCD AACI_IRQHandler ; 10: AACI / AC97
|
||||
DCD CLCD_IRQHandler ; 11: CLCD Combined Interrupt
|
||||
DCD ENET_IRQHandler ; 12: Ethernet
|
||||
DCD USBDC_IRQHandler ; 13: USB Device
|
||||
DCD USBHC_IRQHandler ; 14: USB Host Controller
|
||||
DCD CHLCD_IRQHandler ; 15: Character LCD
|
||||
DCD FLEXRAY_IRQHandler ; 16: Flexray
|
||||
DCD CAN_IRQHandler ; 17: CAN
|
||||
DCD LIN_IRQHandler ; 18: LIN
|
||||
DCD I2C_IRQHandler ; 19: I2C ADC/DAC
|
||||
DCD 0 ; 20: Reserved
|
||||
DCD 0 ; 21: Reserved
|
||||
DCD 0 ; 22: Reserved
|
||||
DCD 0 ; 23: Reserved
|
||||
DCD 0 ; 24: Reserved
|
||||
DCD 0 ; 25: Reserved
|
||||
DCD 0 ; 26: Reserved
|
||||
DCD 0 ; 27: Reserved
|
||||
DCD CPU_CLCD_IRQHandler ; 28: Reserved - CPU FPGA CLCD
|
||||
DCD 0 ; 29: Reserved - CPU FPGA
|
||||
DCD UART3_IRQHandler ; 30: UART3 - CPU FPGA
|
||||
DCD SPI_IRQHandler ; 31: SPI Touchscreen - CPU FPGA
|
||||
__Vectors_End
|
||||
|
||||
__Vectors_Size EQU __Vectors_End - __Vectors
|
||||
|
||||
AREA |.text|, CODE, READONLY
|
||||
|
||||
|
||||
; Reset Handler
|
||||
|
||||
Reset_Handler PROC
|
||||
EXPORT Reset_Handler [WEAK]
|
||||
IMPORT SystemInit
|
||||
IMPORT __main
|
||||
LDR R0, =SystemInit
|
||||
BLX R0
|
||||
LDR R0, =__main
|
||||
BX R0
|
||||
ENDP
|
||||
|
||||
|
||||
; Dummy Exception Handlers (infinite loops which can be modified)
|
||||
|
||||
NMI_Handler PROC
|
||||
EXPORT NMI_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
HardFault_Handler\
|
||||
PROC
|
||||
EXPORT HardFault_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
MemManage_Handler\
|
||||
PROC
|
||||
EXPORT MemManage_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
BusFault_Handler\
|
||||
PROC
|
||||
EXPORT BusFault_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
UsageFault_Handler\
|
||||
PROC
|
||||
EXPORT UsageFault_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
SVC_Handler PROC
|
||||
EXPORT SVC_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
DebugMon_Handler\
|
||||
PROC
|
||||
EXPORT DebugMon_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
PendSV_Handler PROC
|
||||
EXPORT PendSV_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
SysTick_Handler PROC
|
||||
EXPORT SysTick_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
|
||||
Default_Handler PROC
|
||||
|
||||
EXPORT WDT_IRQHandler [WEAK]
|
||||
EXPORT RTC_IRQHandler [WEAK]
|
||||
EXPORT TIM0_IRQHandler [WEAK]
|
||||
EXPORT TIM2_IRQHandler [WEAK]
|
||||
EXPORT MCIA_IRQHandler [WEAK]
|
||||
EXPORT MCIB_IRQHandler [WEAK]
|
||||
EXPORT UART0_IRQHandler [WEAK]
|
||||
EXPORT UART1_IRQHandler [WEAK]
|
||||
EXPORT UART2_IRQHandler [WEAK]
|
||||
EXPORT UART3_IRQHandler [WEAK]
|
||||
EXPORT UART4_IRQHandler [WEAK]
|
||||
EXPORT AACI_IRQHandler [WEAK]
|
||||
EXPORT CLCD_IRQHandler [WEAK]
|
||||
EXPORT ENET_IRQHandler [WEAK]
|
||||
EXPORT USBDC_IRQHandler [WEAK]
|
||||
EXPORT USBHC_IRQHandler [WEAK]
|
||||
EXPORT CHLCD_IRQHandler [WEAK]
|
||||
EXPORT FLEXRAY_IRQHandler [WEAK]
|
||||
EXPORT CAN_IRQHandler [WEAK]
|
||||
EXPORT LIN_IRQHandler [WEAK]
|
||||
EXPORT I2C_IRQHandler [WEAK]
|
||||
EXPORT CPU_CLCD_IRQHandler [WEAK]
|
||||
EXPORT SPI_IRQHandler [WEAK]
|
||||
|
||||
WDT_IRQHandler
|
||||
RTC_IRQHandler
|
||||
TIM0_IRQHandler
|
||||
TIM2_IRQHandler
|
||||
MCIA_IRQHandler
|
||||
MCIB_IRQHandler
|
||||
UART0_IRQHandler
|
||||
UART1_IRQHandler
|
||||
UART2_IRQHandler
|
||||
UART3_IRQHandler
|
||||
UART4_IRQHandler
|
||||
AACI_IRQHandler
|
||||
CLCD_IRQHandler
|
||||
ENET_IRQHandler
|
||||
USBDC_IRQHandler
|
||||
USBHC_IRQHandler
|
||||
CHLCD_IRQHandler
|
||||
FLEXRAY_IRQHandler
|
||||
CAN_IRQHandler
|
||||
LIN_IRQHandler
|
||||
I2C_IRQHandler
|
||||
CPU_CLCD_IRQHandler
|
||||
SPI_IRQHandler
|
||||
B .
|
||||
|
||||
ENDP
|
||||
|
||||
|
||||
ALIGN
|
||||
|
||||
|
||||
; User Initial Stack & Heap
|
||||
|
||||
IF :DEF:__MICROLIB
|
||||
|
||||
EXPORT __initial_sp
|
||||
EXPORT __heap_base
|
||||
EXPORT __heap_limit
|
||||
|
||||
ELSE
|
||||
|
||||
IMPORT __use_two_region_memory
|
||||
EXPORT __user_initial_stackheap
|
||||
|
||||
__user_initial_stackheap PROC
|
||||
LDR R0, = Heap_Mem
|
||||
LDR R1, =(Stack_Mem + Stack_Size)
|
||||
LDR R2, = (Heap_Mem + Heap_Size)
|
||||
LDR R3, = Stack_Mem
|
||||
BX LR
|
||||
ENDP
|
||||
|
||||
ALIGN
|
||||
|
||||
ENDIF
|
||||
|
||||
|
||||
END
|
@ -0,0 +1,85 @@
|
||||
/**************************************************************************//**
|
||||
* @file system_ARMCM7.c
|
||||
* @brief CMSIS Device System Source File for
|
||||
* ARMCM7 Device Series
|
||||
* @version V5.00
|
||||
* @date 08. April 2016
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2016 ARM Limited. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if defined (ARMCM7)
|
||||
#include "ARMCM7.h"
|
||||
#elif defined (ARMCM7_SP)
|
||||
#include "ARMCM7_SP.h"
|
||||
#elif defined (ARMCM7_DP)
|
||||
#include "ARMCM7_DP.h"
|
||||
#else
|
||||
#error device not specified!
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Define clocks
|
||||
*----------------------------------------------------------------------------*/
|
||||
#define XTAL ( 5000000U) /* Oscillator frequency */
|
||||
|
||||
#define SYSTEM_CLOCK (5 * XTAL)
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Externals
|
||||
*----------------------------------------------------------------------------*/
|
||||
#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1)
|
||||
extern uint32_t __Vectors;
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
System Core Clock Variable
|
||||
*----------------------------------------------------------------------------*/
|
||||
uint32_t SystemCoreClock = SYSTEM_CLOCK;
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
System Core Clock update function
|
||||
*----------------------------------------------------------------------------*/
|
||||
void SystemCoreClockUpdate (void)
|
||||
{
|
||||
SystemCoreClock = SYSTEM_CLOCK;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
System initialization function
|
||||
*----------------------------------------------------------------------------*/
|
||||
void SystemInit (void)
|
||||
{
|
||||
|
||||
#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1)
|
||||
SCB->VTOR = (uint32_t) &__Vectors;
|
||||
#endif
|
||||
|
||||
#if defined (__FPU_USED) && (__FPU_USED == 1)
|
||||
SCB->CPACR |= ((3U << 10*2) | /* set CP10 Full Access */
|
||||
(3U << 11*2) ); /* set CP11 Full Access */
|
||||
#endif
|
||||
|
||||
#ifdef UNALIGNED_SUPPORT_DISABLE
|
||||
SCB->CCR |= SCB_CCR_UNALIGN_TRP_Msk;
|
||||
#endif
|
||||
|
||||
SystemCoreClock = SYSTEM_CLOCK;
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
|
||||
/*
|
||||
* Auto generated Run-Time-Environment Component Configuration File
|
||||
* *** Do not modify ! ***
|
||||
*
|
||||
* Project: 'arm_nnexamples_gru'
|
||||
* Target: 'ARMCM0'
|
||||
*/
|
||||
|
||||
#ifndef RTE_COMPONENTS_H
|
||||
#define RTE_COMPONENTS_H
|
||||
|
||||
|
||||
/*
|
||||
* Define the Device Header File:
|
||||
*/
|
||||
#define CMSIS_device_header "ARMCM0.h"
|
||||
|
||||
#define RTE_Compiler_EventRecorder
|
||||
#define RTE_Compiler_EventRecorder_DAP
|
||||
#define RTE_Compiler_IO_STDOUT /* Compiler I/O: STDOUT */
|
||||
#define RTE_Compiler_IO_STDOUT_EVR /* Compiler I/O: STDOUT EVR */
|
||||
|
||||
#endif /* RTE_COMPONENTS_H */
|
@ -0,0 +1,22 @@
|
||||
|
||||
/*
|
||||
* Auto generated Run-Time-Environment Component Configuration File
|
||||
* *** Do not modify ! ***
|
||||
*
|
||||
* Project: 'arm_nnexamples_gru'
|
||||
* Target: 'ARMCM3'
|
||||
*/
|
||||
|
||||
#ifndef RTE_COMPONENTS_H
|
||||
#define RTE_COMPONENTS_H
|
||||
|
||||
|
||||
/*
|
||||
* Define the Device Header File:
|
||||
*/
|
||||
#define CMSIS_device_header "ARMCM3.h"
|
||||
|
||||
#define RTE_Compiler_IO_STDOUT /* Compiler I/O: STDOUT */
|
||||
#define RTE_Compiler_IO_STDOUT_ITM /* Compiler I/O: STDOUT ITM */
|
||||
|
||||
#endif /* RTE_COMPONENTS_H */
|
@ -0,0 +1,22 @@
|
||||
|
||||
/*
|
||||
* Auto generated Run-Time-Environment Component Configuration File
|
||||
* *** Do not modify ! ***
|
||||
*
|
||||
* Project: 'arm_nnexamples_gru'
|
||||
* Target: 'ARMCM4_FP'
|
||||
*/
|
||||
|
||||
#ifndef RTE_COMPONENTS_H
|
||||
#define RTE_COMPONENTS_H
|
||||
|
||||
|
||||
/*
|
||||
* Define the Device Header File:
|
||||
*/
|
||||
#define CMSIS_device_header "ARMCM4_FP.h"
|
||||
|
||||
#define RTE_Compiler_IO_STDOUT /* Compiler I/O: STDOUT */
|
||||
#define RTE_Compiler_IO_STDOUT_ITM /* Compiler I/O: STDOUT ITM */
|
||||
|
||||
#endif /* RTE_COMPONENTS_H */
|
@ -0,0 +1,22 @@
|
||||
|
||||
/*
|
||||
* Auto generated Run-Time-Environment Component Configuration File
|
||||
* *** Do not modify ! ***
|
||||
*
|
||||
* Project: 'arm_nnexamples_gru'
|
||||
* Target: 'ARMCM7_SP'
|
||||
*/
|
||||
|
||||
#ifndef RTE_COMPONENTS_H
|
||||
#define RTE_COMPONENTS_H
|
||||
|
||||
|
||||
/*
|
||||
* Define the Device Header File:
|
||||
*/
|
||||
#define CMSIS_device_header "ARMCM7_SP.h"
|
||||
|
||||
#define RTE_Compiler_IO_STDOUT /* Compiler I/O: STDOUT */
|
||||
#define RTE_Compiler_IO_STDOUT_ITM /* Compiler I/O: STDOUT ITM */
|
||||
|
||||
#endif /* RTE_COMPONENTS_H */
|
@ -0,0 +1,221 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2018 Arm Limited. All rights reserved.
|
||||
*
|
||||
*
|
||||
* Project: CMSIS NN Library
|
||||
* Title: arm_nnexamples_gru.cpp
|
||||
*
|
||||
* Description: Gated Recurrent Unit Example
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M7
|
||||
*
|
||||
* 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 LIMITED 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 THE
|
||||
* COPYRIGHT OWNER 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.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @ingroup groupExamples
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup GRUExample Gated Recurrent Unit Example
|
||||
*
|
||||
* \par Description:
|
||||
* \par
|
||||
* Demonstrates a gated recurrent unit (GRU) example with the use of fully-connected,
|
||||
* Tanh/Sigmoid activation functions.
|
||||
*
|
||||
* \par Model definition:
|
||||
* \par
|
||||
* GRU is a type of recurrent neural network (RNN). It contains two sigmoid gates and one hidden
|
||||
* state.
|
||||
* \par
|
||||
* The computation can be summarized as:
|
||||
* <pre>z[t] = sigmoid( W_z ⋅ {h[t-1],x[t]} )
|
||||
* r[t] = sigmoid( W_r ⋅ {h[t-1],x[t]} )
|
||||
* n[t] = tanh( W_n ⋅ [r[t] × {h[t-1], x[t]} )
|
||||
* h[t] = (1 - z[t]) × h[t-1] + z[t] × n[t] </pre>
|
||||
* \image html GRU.gif "Gate Recurrent Unit Diagram"
|
||||
*
|
||||
* \par Variables Description:
|
||||
* \par
|
||||
* \li \c update_gate_weights, \c reset_gate_weights, \c hidden_state_weights are weights corresponding to update gate (W_z), reset gate (W_r), and hidden state (W_n).
|
||||
* \li \c update_gate_bias, \c reset_gate_bias, \c hidden_state_bias are layer bias arrays
|
||||
* \li \c test_input1, \c test_input2, \c test_history are the inputs and initial history
|
||||
*
|
||||
* \par
|
||||
* The buffer is allocated as:
|
||||
* \par
|
||||
* | reset | input | history | update | hidden_state |
|
||||
* \par
|
||||
* In this way, the concatination is automatically done since (reset, input) and (input, history)
|
||||
* are physically concatinated in memory.
|
||||
* \par
|
||||
* The ordering of the weight matrix should be adjusted accordingly.
|
||||
*
|
||||
*
|
||||
*
|
||||
* \par CMSIS DSP Software Library Functions Used:
|
||||
* \par
|
||||
* - arm_fully_connected_mat_q7_vec_q15_opt()
|
||||
* - arm_nn_activations_direct_q15()
|
||||
* - arm_mult_q15()
|
||||
* - arm_offset_q15()
|
||||
* - arm_sub_q15()
|
||||
* - arm_copy_q15()
|
||||
*
|
||||
* <b> Refer </b>
|
||||
* \link arm_nnexamples_gru.cpp \endlink
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include "arm_nnexamples_gru_test_data.h"
|
||||
#include "arm_math.h"
|
||||
#include "arm_nnfunctions.h"
|
||||
|
||||
#ifdef _RTE_
|
||||
#include "RTE_Components.h"
|
||||
#ifdef RTE_Compiler_EventRecorder
|
||||
#include "EventRecorder.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define DIM_HISTORY 32
|
||||
#define DIM_INPUT 32
|
||||
#define DIM_VEC 64
|
||||
|
||||
#define USE_X4
|
||||
|
||||
#ifndef USE_X4
|
||||
static q7_t update_gate_weights[DIM_VEC * DIM_HISTORY] = UPDATE_GATE_WEIGHT_X2;
|
||||
static q7_t reset_gate_weights[DIM_VEC * DIM_HISTORY] = RESET_GATE_WEIGHT_X2;
|
||||
static q7_t hidden_state_weights[DIM_VEC * DIM_HISTORY] = HIDDEN_STATE_WEIGHT_X2;
|
||||
#else
|
||||
static q7_t update_gate_weights[DIM_VEC * DIM_HISTORY] = UPDATE_GATE_WEIGHT_X4;
|
||||
static q7_t reset_gate_weights[DIM_VEC * DIM_HISTORY] = RESET_GATE_WEIGHT_X4;
|
||||
static q7_t hidden_state_weights[DIM_VEC * DIM_HISTORY] = HIDDEN_STATE_WEIGHT_X4;
|
||||
#endif
|
||||
|
||||
static q7_t update_gate_bias[DIM_HISTORY] = UPDATE_GATE_BIAS;
|
||||
static q7_t reset_gate_bias[DIM_HISTORY] = RESET_GATE_BIAS;
|
||||
static q7_t hidden_state_bias[DIM_HISTORY] = HIDDEN_STATE_BIAS;
|
||||
|
||||
static q15_t test_input1[DIM_INPUT] = INPUT_DATA1;
|
||||
static q15_t test_input2[DIM_INPUT] = INPUT_DATA2;
|
||||
static q15_t test_history[DIM_HISTORY] = HISTORY_DATA;
|
||||
|
||||
q15_t scratch_buffer[DIM_HISTORY * 4 + DIM_INPUT];
|
||||
|
||||
void gru_example(q15_t * scratch_input, uint16_t input_size, uint16_t history_size,
|
||||
q7_t * weights_update, q7_t * weights_reset, q7_t * weights_hidden_state,
|
||||
q7_t * bias_update, q7_t * bias_reset, q7_t * bias_hidden_state)
|
||||
{
|
||||
q15_t *reset = scratch_input;
|
||||
q15_t *input = scratch_input + history_size;
|
||||
q15_t *history = scratch_input + history_size + input_size;
|
||||
q15_t *update = scratch_input + 2 * history_size + input_size;
|
||||
q15_t *hidden_state = scratch_input + 3 * history_size + input_size;
|
||||
|
||||
// reset gate calculation
|
||||
// the range of the output can be adjusted with bias_shift and output_shift
|
||||
#ifndef USE_X4
|
||||
arm_fully_connected_mat_q7_vec_q15(input, weights_reset, input_size + history_size, history_size, 0, 15, bias_reset,
|
||||
reset, NULL);
|
||||
#else
|
||||
arm_fully_connected_mat_q7_vec_q15_opt(input, weights_reset, input_size + history_size, history_size, 0, 15,
|
||||
bias_reset, reset, NULL);
|
||||
#endif
|
||||
// sigmoid function, the size of the integer bit-width should be consistent with out_shift
|
||||
arm_nn_activations_direct_q15(reset, history_size, 0, ARM_SIGMOID);
|
||||
arm_mult_q15(history, reset, reset, history_size);
|
||||
|
||||
// update gate calculation
|
||||
// the range of the output can be adjusted with bias_shift and output_shift
|
||||
#ifndef USE_X4
|
||||
arm_fully_connected_mat_q7_vec_q15(input, weights_update, input_size + history_size, history_size, 0, 15,
|
||||
bias_update, update, NULL);
|
||||
#else
|
||||
arm_fully_connected_mat_q7_vec_q15_opt(input, weights_update, input_size + history_size, history_size, 0, 15,
|
||||
bias_update, update, NULL);
|
||||
#endif
|
||||
|
||||
// sigmoid function, the size of the integer bit-width should be consistent with out_shift
|
||||
arm_nn_activations_direct_q15(update, history_size, 0, ARM_SIGMOID);
|
||||
|
||||
// hidden state calculation
|
||||
#ifndef USE_X4
|
||||
arm_fully_connected_mat_q7_vec_q15(reset, weights_hidden_state, input_size + history_size, history_size, 0, 15,
|
||||
bias_hidden_state, hidden_state, NULL);
|
||||
#else
|
||||
arm_fully_connected_mat_q7_vec_q15_opt(reset, weights_hidden_state, input_size + history_size, history_size, 0, 15,
|
||||
bias_hidden_state, hidden_state, NULL);
|
||||
#endif
|
||||
|
||||
// tanh function, the size of the integer bit-width should be consistent with out_shift
|
||||
arm_nn_activations_direct_q15(hidden_state, history_size, 0, ARM_TANH);
|
||||
arm_mult_q15(update, hidden_state, hidden_state, history_size);
|
||||
|
||||
// we calculate z - 1 here
|
||||
// so final addition becomes substraction
|
||||
arm_offset_q15(update, 0x8000, update, history_size);
|
||||
// multiply history
|
||||
arm_mult_q15(history, update, update, history_size);
|
||||
// calculate history_out
|
||||
arm_sub_q15(hidden_state, update, history, history_size);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
#ifdef RTE_Compiler_EventRecorder
|
||||
EventRecorderInitialize (EventRecordAll, 1); // initialize and start Event Recorder
|
||||
#endif
|
||||
|
||||
printf("Start GRU execution\n");
|
||||
int input_size = DIM_INPUT;
|
||||
int history_size = DIM_HISTORY;
|
||||
|
||||
// copy over the input data
|
||||
arm_copy_q15(test_input1, scratch_buffer + history_size, input_size);
|
||||
arm_copy_q15(test_history, scratch_buffer + history_size + input_size, history_size);
|
||||
|
||||
gru_example(scratch_buffer, input_size, history_size,
|
||||
update_gate_weights, reset_gate_weights, hidden_state_weights,
|
||||
update_gate_bias, reset_gate_bias, hidden_state_bias);
|
||||
printf("Complete first iteration on GRU\n");
|
||||
|
||||
arm_copy_q15(test_input2, scratch_buffer + history_size, input_size);
|
||||
gru_example(scratch_buffer, input_size, history_size,
|
||||
update_gate_weights, reset_gate_weights, hidden_state_weights,
|
||||
update_gate_bias, reset_gate_bias, hidden_state_bias);
|
||||
printf("Complete second iteration on GRU\n");
|
||||
|
||||
return 0;
|
||||
}
|
File diff suppressed because one or more lines are too long
@ -0,0 +1,4 @@
|
||||
CMSIS NN Lib example arm_nnexample_gru0 for
|
||||
Cortex-M4 and Cortex-M7.
|
||||
|
||||
The example is configured for uVision Simulator.
|
@ -0,0 +1,196 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2018 Arm Limited. All rights reserved.
|
||||
*
|
||||
*
|
||||
* Project: CMSIS NN Library
|
||||
* Title: arm_nnexamples_cifar10.cpp
|
||||
*
|
||||
* Description: Convolutional Neural Network Example
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M7
|
||||
*
|
||||
* 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 LIMITED 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 THE
|
||||
* COPYRIGHT OWNER 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.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @ingroup groupExamples
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup CNNExample Convolutional Neural Network Example
|
||||
*
|
||||
* \par Description:
|
||||
* \par
|
||||
* Demonstrates a convolutional neural network (CNN) example with the use of convolution,
|
||||
* ReLU activation, pooling and fully-connected functions.
|
||||
*
|
||||
* \par Model definition:
|
||||
* \par
|
||||
* The CNN used in this example is based on CIFAR-10 example from Caffe [1].
|
||||
* The neural network consists
|
||||
* of 3 convolution layers interspersed by ReLU activation and max pooling layers, followed by a
|
||||
* fully-connected layer at the end. The input to the network is a 32x32 pixel color image, which will
|
||||
* be classified into one of the 10 output classes.
|
||||
* This example model implementation needs 32.3 KB to store weights, 40 KB for activations and
|
||||
* 3.1 KB for storing the \c im2col data.
|
||||
*
|
||||
* \image html CIFAR10_CNN.gif "Neural Network model definition"
|
||||
*
|
||||
* \par Variables Description:
|
||||
* \par
|
||||
* \li \c conv1_wt, \c conv2_wt, \c conv3_wt are convolution layer weight matrices
|
||||
* \li \c conv1_bias, \c conv2_bias, \c conv3_bias are convolution layer bias arrays
|
||||
* \li \c ip1_wt, ip1_bias point to fully-connected layer weights and biases
|
||||
* \li \c input_data points to the input image data
|
||||
* \li \c output_data points to the classification output
|
||||
* \li \c col_buffer is a buffer to store the \c im2col output
|
||||
* \li \c scratch_buffer is used to store the activation data (intermediate layer outputs)
|
||||
*
|
||||
* \par CMSIS DSP Software Library Functions Used:
|
||||
* \par
|
||||
* - arm_convolve_HWC_q7_RGB()
|
||||
* - arm_convolve_HWC_q7_fast()
|
||||
* - arm_relu_q7()
|
||||
* - arm_maxpool_q7_HWC()
|
||||
* - arm_avepool_q7_HWC()
|
||||
* - arm_fully_connected_q7_opt()
|
||||
* - arm_fully_connected_q7()
|
||||
*
|
||||
* <b> Refer </b>
|
||||
* \link arm_nnexamples_cifar10.cpp \endlink
|
||||
*
|
||||
* \par [1] https://github.com/BVLC/caffe
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include "arm_math.h"
|
||||
#include "arm_nnexamples_cifar10_parameter.h"
|
||||
#include "arm_nnexamples_cifar10_weights.h"
|
||||
|
||||
#include "arm_nnfunctions.h"
|
||||
#include "arm_nnexamples_cifar10_inputs.h"
|
||||
|
||||
#ifdef _RTE_
|
||||
#include "RTE_Components.h"
|
||||
#ifdef RTE_Compiler_EventRecorder
|
||||
#include "EventRecorder.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// include the input and weights
|
||||
|
||||
static q7_t conv1_wt[CONV1_IM_CH * CONV1_KER_DIM * CONV1_KER_DIM * CONV1_OUT_CH] = CONV1_WT;
|
||||
static q7_t conv1_bias[CONV1_OUT_CH] = CONV1_BIAS;
|
||||
|
||||
static q7_t conv2_wt[CONV2_IM_CH * CONV2_KER_DIM * CONV2_KER_DIM * CONV2_OUT_CH] = CONV2_WT;
|
||||
static q7_t conv2_bias[CONV2_OUT_CH] = CONV2_BIAS;
|
||||
|
||||
static q7_t conv3_wt[CONV3_IM_CH * CONV3_KER_DIM * CONV3_KER_DIM * CONV3_OUT_CH] = CONV3_WT;
|
||||
static q7_t conv3_bias[CONV3_OUT_CH] = CONV3_BIAS;
|
||||
|
||||
static q7_t ip1_wt[IP1_DIM * IP1_OUT] = IP1_WT;
|
||||
static q7_t ip1_bias[IP1_OUT] = IP1_BIAS;
|
||||
|
||||
/* Here the image_data should be the raw uint8 type RGB image in [RGB, RGB, RGB ... RGB] format */
|
||||
uint8_t image_data[CONV1_IM_CH * CONV1_IM_DIM * CONV1_IM_DIM] = IMG_DATA;
|
||||
q7_t output_data[IP1_OUT];
|
||||
|
||||
//vector buffer: max(im2col buffer,average pool buffer, fully connected buffer)
|
||||
q7_t col_buffer[2 * 5 * 5 * 32 * 2];
|
||||
|
||||
q7_t scratch_buffer[32 * 32 * 10 * 4];
|
||||
|
||||
int main()
|
||||
{
|
||||
#ifdef RTE_Compiler_EventRecorder
|
||||
EventRecorderInitialize (EventRecordAll, 1); // initialize and start Event Recorder
|
||||
#endif
|
||||
|
||||
printf("start execution\n");
|
||||
/* start the execution */
|
||||
|
||||
q7_t *img_buffer1 = scratch_buffer;
|
||||
q7_t *img_buffer2 = img_buffer1 + 32 * 32 * 32;
|
||||
|
||||
/* input pre-processing */
|
||||
int mean_data[3] = INPUT_MEAN_SHIFT;
|
||||
unsigned int scale_data[3] = INPUT_RIGHT_SHIFT;
|
||||
for (int i=0;i<32*32*3; i+=3) {
|
||||
img_buffer2[i] = (q7_t)__SSAT( ((((int)image_data[i] - mean_data[0])<<7) + (0x1<<(scale_data[0]-1)))
|
||||
>> scale_data[0], 8);
|
||||
img_buffer2[i+1] = (q7_t)__SSAT( ((((int)image_data[i+1] - mean_data[1])<<7) + (0x1<<(scale_data[1]-1)))
|
||||
>> scale_data[1], 8);
|
||||
img_buffer2[i+2] = (q7_t)__SSAT( ((((int)image_data[i+2] - mean_data[2])<<7) + (0x1<<(scale_data[2]-1)))
|
||||
>> scale_data[2], 8);
|
||||
}
|
||||
|
||||
// conv1 img_buffer2 -> img_buffer1
|
||||
arm_convolve_HWC_q7_RGB(img_buffer2, CONV1_IM_DIM, CONV1_IM_CH, conv1_wt, CONV1_OUT_CH, CONV1_KER_DIM, CONV1_PADDING,
|
||||
CONV1_STRIDE, conv1_bias, CONV1_BIAS_LSHIFT, CONV1_OUT_RSHIFT, img_buffer1, CONV1_OUT_DIM,
|
||||
(q15_t *) col_buffer, NULL);
|
||||
|
||||
arm_relu_q7(img_buffer1, CONV1_OUT_DIM * CONV1_OUT_DIM * CONV1_OUT_CH);
|
||||
|
||||
// pool1 img_buffer1 -> img_buffer2
|
||||
arm_maxpool_q7_HWC(img_buffer1, CONV1_OUT_DIM, CONV1_OUT_CH, POOL1_KER_DIM,
|
||||
POOL1_PADDING, POOL1_STRIDE, POOL1_OUT_DIM, NULL, img_buffer2);
|
||||
|
||||
// conv2 img_buffer2 -> img_buffer1
|
||||
arm_convolve_HWC_q7_fast(img_buffer2, CONV2_IM_DIM, CONV2_IM_CH, conv2_wt, CONV2_OUT_CH, CONV2_KER_DIM,
|
||||
CONV2_PADDING, CONV2_STRIDE, conv2_bias, CONV2_BIAS_LSHIFT, CONV2_OUT_RSHIFT, img_buffer1,
|
||||
CONV2_OUT_DIM, (q15_t *) col_buffer, NULL);
|
||||
|
||||
arm_relu_q7(img_buffer1, CONV2_OUT_DIM * CONV2_OUT_DIM * CONV2_OUT_CH);
|
||||
|
||||
// pool2 img_buffer1 -> img_buffer2
|
||||
arm_maxpool_q7_HWC(img_buffer1, CONV2_OUT_DIM, CONV2_OUT_CH, POOL2_KER_DIM,
|
||||
POOL2_PADDING, POOL2_STRIDE, POOL2_OUT_DIM, col_buffer, img_buffer2);
|
||||
|
||||
// conv3 img_buffer2 -> img_buffer1
|
||||
arm_convolve_HWC_q7_fast(img_buffer2, CONV3_IM_DIM, CONV3_IM_CH, conv3_wt, CONV3_OUT_CH, CONV3_KER_DIM,
|
||||
CONV3_PADDING, CONV3_STRIDE, conv3_bias, CONV3_BIAS_LSHIFT, CONV3_OUT_RSHIFT, img_buffer1,
|
||||
CONV3_OUT_DIM, (q15_t *) col_buffer, NULL);
|
||||
|
||||
arm_relu_q7(img_buffer1, CONV3_OUT_DIM * CONV3_OUT_DIM * CONV3_OUT_CH);
|
||||
|
||||
// pool3 img_buffer-> img_buffer2
|
||||
arm_maxpool_q7_HWC(img_buffer1, CONV3_OUT_DIM, CONV3_OUT_CH, POOL3_KER_DIM,
|
||||
POOL3_PADDING, POOL3_STRIDE, POOL3_OUT_DIM, col_buffer, img_buffer2);
|
||||
|
||||
arm_fully_connected_q7_opt(img_buffer2, ip1_wt, IP1_DIM, IP1_OUT, IP1_BIAS_LSHIFT, IP1_OUT_RSHIFT, ip1_bias,
|
||||
output_data, (q15_t *) img_buffer1);
|
||||
|
||||
arm_softmax_q7(output_data, 10, output_data);
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
printf("%d: %d\n", i, output_data[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
File diff suppressed because one or more lines are too long
@ -0,0 +1,43 @@
|
||||
#define CONV1_IM_DIM 32
|
||||
#define CONV1_IM_CH 3
|
||||
#define CONV1_KER_DIM 5
|
||||
#define CONV1_PADDING 2
|
||||
#define CONV1_STRIDE 1
|
||||
#define CONV1_OUT_CH 32
|
||||
#define CONV1_OUT_DIM 32
|
||||
|
||||
#define POOL1_KER_DIM 3
|
||||
#define POOL1_STRIDE 2
|
||||
#define POOL1_PADDING 0
|
||||
#define POOL1_OUT_DIM 16
|
||||
|
||||
#define CONV2_IM_DIM 16
|
||||
#define CONV2_IM_CH 32
|
||||
#define CONV2_KER_DIM 5
|
||||
#define CONV2_PADDING 2
|
||||
#define CONV2_STRIDE 1
|
||||
#define CONV2_OUT_CH 16
|
||||
#define CONV2_OUT_DIM 16
|
||||
|
||||
#define POOL2_KER_DIM 3
|
||||
#define POOL2_STRIDE 2
|
||||
#define POOL2_PADDING 0
|
||||
#define POOL2_OUT_DIM 8
|
||||
|
||||
#define CONV3_IM_DIM 8
|
||||
#define CONV3_IM_CH 16
|
||||
#define CONV3_KER_DIM 5
|
||||
#define CONV3_PADDING 2
|
||||
#define CONV3_STRIDE 1
|
||||
#define CONV3_OUT_CH 32
|
||||
#define CONV3_OUT_DIM 8
|
||||
|
||||
#define POOL3_KER_DIM 3
|
||||
#define POOL3_STRIDE 2
|
||||
#define POOL3_PADDING 0
|
||||
#define POOL3_OUT_DIM 4
|
||||
|
||||
#define IP1_DIM 4*4*32
|
||||
#define IP1_IM_DIM 4
|
||||
#define IP1_IM_CH 32
|
||||
#define IP1_OUT 10
|
File diff suppressed because one or more lines are too long
@ -0,0 +1,7 @@
|
||||
CMSIS NN Lib example arm_nnexample_cifar10 for
|
||||
Cortex-M0, Cortex-M3, Cortex-M4 and Cortex-M7.
|
||||
|
||||
The example is configured for IAR Embedded Workbench for ARM Simulator.
|
||||
|
||||
When changing target, remember to change the ARM_MATH_CMx and __FPU_PRESENT
|
||||
Preprocessor defines for C/C++ Compiler
|
@ -0,0 +1,221 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2018 Arm Limited. All rights reserved.
|
||||
*
|
||||
*
|
||||
* Project: CMSIS NN Library
|
||||
* Title: arm_nnexamples_gru.cpp
|
||||
*
|
||||
* Description: Gated Recurrent Unit Example
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M7
|
||||
*
|
||||
* 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 LIMITED 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 THE
|
||||
* COPYRIGHT OWNER 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.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @ingroup groupExamples
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup GRUExample Gated Recurrent Unit Example
|
||||
*
|
||||
* \par Description:
|
||||
* \par
|
||||
* Demonstrates a gated recurrent unit (GRU) example with the use of fully-connected,
|
||||
* Tanh/Sigmoid activation functions.
|
||||
*
|
||||
* \par Model definition:
|
||||
* \par
|
||||
* GRU is a type of recurrent neural network (RNN). It contains two sigmoid gates and one hidden
|
||||
* state.
|
||||
* \par
|
||||
* The computation can be summarized as:
|
||||
* <pre>z[t] = sigmoid( W_z ⋅ {h[t-1],x[t]} )
|
||||
* r[t] = sigmoid( W_r ⋅ {h[t-1],x[t]} )
|
||||
* n[t] = tanh( W_n ⋅ [r[t] × {h[t-1], x[t]} )
|
||||
* h[t] = (1 - z[t]) × h[t-1] + z[t] × n[t] </pre>
|
||||
* \image html GRU.gif "Gate Recurrent Unit Diagram"
|
||||
*
|
||||
* \par Variables Description:
|
||||
* \par
|
||||
* \li \c update_gate_weights, \c reset_gate_weights, \c hidden_state_weights are weights corresponding to update gate (W_z), reset gate (W_r), and hidden state (W_n).
|
||||
* \li \c update_gate_bias, \c reset_gate_bias, \c hidden_state_bias are layer bias arrays
|
||||
* \li \c test_input1, \c test_input2, \c test_history are the inputs and initial history
|
||||
*
|
||||
* \par
|
||||
* The buffer is allocated as:
|
||||
* \par
|
||||
* | reset | input | history | update | hidden_state |
|
||||
* \par
|
||||
* In this way, the concatination is automatically done since (reset, input) and (input, history)
|
||||
* are physically concatinated in memory.
|
||||
* \par
|
||||
* The ordering of the weight matrix should be adjusted accordingly.
|
||||
*
|
||||
*
|
||||
*
|
||||
* \par CMSIS DSP Software Library Functions Used:
|
||||
* \par
|
||||
* - arm_fully_connected_mat_q7_vec_q15_opt()
|
||||
* - arm_nn_activations_direct_q15()
|
||||
* - arm_mult_q15()
|
||||
* - arm_offset_q15()
|
||||
* - arm_sub_q15()
|
||||
* - arm_copy_q15()
|
||||
*
|
||||
* <b> Refer </b>
|
||||
* \link arm_nnexamples_gru.cpp \endlink
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include "arm_nnexamples_gru_test_data.h"
|
||||
#include "arm_math.h"
|
||||
#include "arm_nnfunctions.h"
|
||||
|
||||
#ifdef _RTE_
|
||||
#include "RTE_Components.h"
|
||||
#ifdef RTE_Compiler_EventRecorder
|
||||
#include "EventRecorder.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define DIM_HISTORY 32
|
||||
#define DIM_INPUT 32
|
||||
#define DIM_VEC 64
|
||||
|
||||
#define USE_X4
|
||||
|
||||
#ifndef USE_X4
|
||||
static q7_t update_gate_weights[DIM_VEC * DIM_HISTORY] = UPDATE_GATE_WEIGHT_X2;
|
||||
static q7_t reset_gate_weights[DIM_VEC * DIM_HISTORY] = RESET_GATE_WEIGHT_X2;
|
||||
static q7_t hidden_state_weights[DIM_VEC * DIM_HISTORY] = HIDDEN_STATE_WEIGHT_X2;
|
||||
#else
|
||||
static q7_t update_gate_weights[DIM_VEC * DIM_HISTORY] = UPDATE_GATE_WEIGHT_X4;
|
||||
static q7_t reset_gate_weights[DIM_VEC * DIM_HISTORY] = RESET_GATE_WEIGHT_X4;
|
||||
static q7_t hidden_state_weights[DIM_VEC * DIM_HISTORY] = HIDDEN_STATE_WEIGHT_X4;
|
||||
#endif
|
||||
|
||||
static q7_t update_gate_bias[DIM_HISTORY] = UPDATE_GATE_BIAS;
|
||||
static q7_t reset_gate_bias[DIM_HISTORY] = RESET_GATE_BIAS;
|
||||
static q7_t hidden_state_bias[DIM_HISTORY] = HIDDEN_STATE_BIAS;
|
||||
|
||||
static q15_t test_input1[DIM_INPUT] = INPUT_DATA1;
|
||||
static q15_t test_input2[DIM_INPUT] = INPUT_DATA2;
|
||||
static q15_t test_history[DIM_HISTORY] = HISTORY_DATA;
|
||||
|
||||
q15_t scratch_buffer[DIM_HISTORY * 4 + DIM_INPUT];
|
||||
|
||||
void gru_example(q15_t * scratch_input, uint16_t input_size, uint16_t history_size,
|
||||
q7_t * weights_update, q7_t * weights_reset, q7_t * weights_hidden_state,
|
||||
q7_t * bias_update, q7_t * bias_reset, q7_t * bias_hidden_state)
|
||||
{
|
||||
q15_t *reset = scratch_input;
|
||||
q15_t *input = scratch_input + history_size;
|
||||
q15_t *history = scratch_input + history_size + input_size;
|
||||
q15_t *update = scratch_input + 2 * history_size + input_size;
|
||||
q15_t *hidden_state = scratch_input + 3 * history_size + input_size;
|
||||
|
||||
// reset gate calculation
|
||||
// the range of the output can be adjusted with bias_shift and output_shift
|
||||
#ifndef USE_X4
|
||||
arm_fully_connected_mat_q7_vec_q15(input, weights_reset, input_size + history_size, history_size, 0, 15, bias_reset,
|
||||
reset, NULL);
|
||||
#else
|
||||
arm_fully_connected_mat_q7_vec_q15_opt(input, weights_reset, input_size + history_size, history_size, 0, 15,
|
||||
bias_reset, reset, NULL);
|
||||
#endif
|
||||
// sigmoid function, the size of the integer bit-width should be consistent with out_shift
|
||||
arm_nn_activations_direct_q15(reset, history_size, 0, ARM_SIGMOID);
|
||||
arm_mult_q15(history, reset, reset, history_size);
|
||||
|
||||
// update gate calculation
|
||||
// the range of the output can be adjusted with bias_shift and output_shift
|
||||
#ifndef USE_X4
|
||||
arm_fully_connected_mat_q7_vec_q15(input, weights_update, input_size + history_size, history_size, 0, 15,
|
||||
bias_update, update, NULL);
|
||||
#else
|
||||
arm_fully_connected_mat_q7_vec_q15_opt(input, weights_update, input_size + history_size, history_size, 0, 15,
|
||||
bias_update, update, NULL);
|
||||
#endif
|
||||
|
||||
// sigmoid function, the size of the integer bit-width should be consistent with out_shift
|
||||
arm_nn_activations_direct_q15(update, history_size, 0, ARM_SIGMOID);
|
||||
|
||||
// hidden state calculation
|
||||
#ifndef USE_X4
|
||||
arm_fully_connected_mat_q7_vec_q15(reset, weights_hidden_state, input_size + history_size, history_size, 0, 15,
|
||||
bias_hidden_state, hidden_state, NULL);
|
||||
#else
|
||||
arm_fully_connected_mat_q7_vec_q15_opt(reset, weights_hidden_state, input_size + history_size, history_size, 0, 15,
|
||||
bias_hidden_state, hidden_state, NULL);
|
||||
#endif
|
||||
|
||||
// tanh function, the size of the integer bit-width should be consistent with out_shift
|
||||
arm_nn_activations_direct_q15(hidden_state, history_size, 0, ARM_TANH);
|
||||
arm_mult_q15(update, hidden_state, hidden_state, history_size);
|
||||
|
||||
// we calculate z - 1 here
|
||||
// so final addition becomes substraction
|
||||
arm_offset_q15(update, 0x8000, update, history_size);
|
||||
// multiply history
|
||||
arm_mult_q15(history, update, update, history_size);
|
||||
// calculate history_out
|
||||
arm_sub_q15(hidden_state, update, history, history_size);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
#ifdef RTE_Compiler_EventRecorder
|
||||
EventRecorderInitialize (EventRecordAll, 1); // initialize and start Event Recorder
|
||||
#endif
|
||||
|
||||
printf("Start GRU execution\n");
|
||||
int input_size = DIM_INPUT;
|
||||
int history_size = DIM_HISTORY;
|
||||
|
||||
// copy over the input data
|
||||
arm_copy_q15(test_input1, scratch_buffer + history_size, input_size);
|
||||
arm_copy_q15(test_history, scratch_buffer + history_size + input_size, history_size);
|
||||
|
||||
gru_example(scratch_buffer, input_size, history_size,
|
||||
update_gate_weights, reset_gate_weights, hidden_state_weights,
|
||||
update_gate_bias, reset_gate_bias, hidden_state_bias);
|
||||
printf("Complete first iteration on GRU\n");
|
||||
|
||||
arm_copy_q15(test_input2, scratch_buffer + history_size, input_size);
|
||||
gru_example(scratch_buffer, input_size, history_size,
|
||||
update_gate_weights, reset_gate_weights, hidden_state_weights,
|
||||
update_gate_bias, reset_gate_bias, hidden_state_bias);
|
||||
printf("Complete second iteration on GRU\n");
|
||||
|
||||
return 0;
|
||||
}
|
File diff suppressed because one or more lines are too long
@ -0,0 +1,7 @@
|
||||
CMSIS NN Lib example arm_nnexample_gru0 for
|
||||
Cortex-M0, Cortex-M3, Cortex-M4 and Cortex-M7.
|
||||
|
||||
The example is configured for IAR Embedded Workbench for ARM Simulator.
|
||||
|
||||
When changing target, remember to change the ARM_MATH_CMx and __FPU_PRESENT
|
||||
Preprocessor defines for C/C++ Compiler
|
56
resources/FC_camera/Drivers/CMSIS/NN/Include/arm_nn_tables.h
Normal file
56
resources/FC_camera/Drivers/CMSIS/NN/Include/arm_nn_tables.h
Normal file
@ -0,0 +1,56 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Project: CMSIS NN Library
|
||||
* Title: arm_nn_tables.h
|
||||
* Description: Extern declaration for NN tables
|
||||
*
|
||||
* $Date: 17. January 2018
|
||||
* $Revision: V.1.0.0
|
||||
*
|
||||
* Target Processor: Cortex-M cores
|
||||
* -------------------------------------------------------------------- */
|
||||
/*
|
||||
* Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _ARM_NN_TABLES_H
|
||||
#define _ARM_NN_TABLES_H
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/**
|
||||
* @brief tables for various activation functions
|
||||
*
|
||||
*/
|
||||
|
||||
extern const q15_t sigmoidTable_q15[256];
|
||||
extern const q7_t sigmoidTable_q7[256];
|
||||
|
||||
extern const q7_t tanhTable_q7[256];
|
||||
extern const q15_t tanhTable_q15[256];
|
||||
|
||||
/**
|
||||
* @brief 2-way tables for various activation functions
|
||||
*
|
||||
* 2-way table, H table for value larger than 1/4
|
||||
* L table for value smaller than 1/4, H table for remaining
|
||||
* We have this only for the q15_t version. It does not make
|
||||
* sense to have it for q7_t type
|
||||
*/
|
||||
extern const q15_t sigmoidHTable_q15[192];
|
||||
extern const q15_t sigmoidLTable_q15[128];
|
||||
|
||||
#endif /* ARM_NN_TABLES_H */
|
1075
resources/FC_camera/Drivers/CMSIS/NN/Include/arm_nnfunctions.h
Normal file
1075
resources/FC_camera/Drivers/CMSIS/NN/Include/arm_nnfunctions.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,269 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Project: CMSIS NN Library
|
||||
* Title: arm_nnsupportfunctions.h
|
||||
* Description: Public header file of support functions for CMSIS NN Library
|
||||
*
|
||||
* $Date: 13. July 2018
|
||||
* $Revision: V.1.0.0
|
||||
*
|
||||
* Target Processor: Cortex-M cores
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#ifndef _ARM_NNSUPPORTFUNCTIONS_H_
|
||||
#define _ARM_NNSUPPORTFUNCTIONS_H_
|
||||
|
||||
#include "arm_math.h"
|
||||
#include "arm_common_tables.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#define LEFT_SHIFT(_shift) (_shift > 0 ? _shift : 0)
|
||||
#define RIGHT_SHIFT(_shift) (_shift > 0 ? 0 : -_shift)
|
||||
#define Q31_MIN (0x80000000L)
|
||||
#define Q31_MAX (0x7FFFFFFFL)
|
||||
|
||||
/**
|
||||
* @brief Union for SIMD access of Q31/Q15/Q7 types
|
||||
*/
|
||||
union arm_nnword
|
||||
{
|
||||
q31_t word;
|
||||
/**< Q31 type */
|
||||
q15_t half_words[2];
|
||||
/**< Q15 type */
|
||||
q7_t bytes[4];
|
||||
/**< Q7 type */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Struct for specifying activation function types
|
||||
*
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
ARM_SIGMOID = 0,
|
||||
/**< Sigmoid activation function */
|
||||
ARM_TANH = 1,
|
||||
/**< Tanh activation function */
|
||||
} arm_nn_activation_type;
|
||||
|
||||
/**
|
||||
* @defgroup nndata_convert Neural Network Data Conversion Functions
|
||||
*
|
||||
* Perform data type conversion in-between neural network operations
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Converts the elements of the Q7 vector to Q15 vector without left-shift
|
||||
* @param[in] *pSrc points to the Q7 input vector
|
||||
* @param[out] *pDst points to the Q15 output vector
|
||||
* @param[in] blockSize length of the input vector
|
||||
* @return none.
|
||||
*
|
||||
*/
|
||||
|
||||
void arm_q7_to_q15_no_shift(const q7_t * pSrc, q15_t * pDst, uint32_t blockSize);
|
||||
|
||||
/**
|
||||
* @brief Converts the elements of the Q7 vector to reordered Q15 vector without left-shift
|
||||
* @param[in] *pSrc points to the Q7 input vector
|
||||
* @param[out] *pDst points to the Q15 output vector
|
||||
* @param[in] blockSize length of the input vector
|
||||
* @return none.
|
||||
*
|
||||
*/
|
||||
|
||||
void arm_q7_to_q15_reordered_no_shift(const q7_t * pSrc, q15_t * pDst, uint32_t blockSize);
|
||||
|
||||
#if defined (ARM_MATH_DSP)
|
||||
|
||||
/**
|
||||
* @brief read and expand one Q7 word into two Q15 words
|
||||
*/
|
||||
|
||||
__STATIC_FORCEINLINE void *read_and_pad(void *source, q31_t * out1, q31_t * out2)
|
||||
{
|
||||
q31_t inA = *__SIMD32(source)++;
|
||||
q31_t inAbuf1 = __SXTB16(__ROR(inA, 8));
|
||||
q31_t inAbuf2 = __SXTB16(inA);
|
||||
|
||||
#ifndef ARM_MATH_BIG_ENDIAN
|
||||
*out2 = __PKHTB(inAbuf1, inAbuf2, 16);
|
||||
*out1 = __PKHBT(inAbuf2, inAbuf1, 16);
|
||||
#else
|
||||
*out1 = __PKHTB(inAbuf1, inAbuf2, 16);
|
||||
*out2 = __PKHBT(inAbuf2, inAbuf1, 16);
|
||||
#endif
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief read and expand one Q7 word into two Q15 words with reordering
|
||||
*/
|
||||
|
||||
__STATIC_FORCEINLINE void *read_and_pad_reordered(void *source, q31_t * out1, q31_t * out2)
|
||||
{
|
||||
q31_t inA = *__SIMD32(source)++;
|
||||
#ifndef ARM_MATH_BIG_ENDIAN
|
||||
*out2 = __SXTB16(__ROR(inA, 8));
|
||||
*out1 = __SXTB16(inA);
|
||||
#else
|
||||
*out1 = __SXTB16(__ROR(inA, 8));
|
||||
*out2 = __SXTB16(inA);
|
||||
#endif
|
||||
|
||||
return source;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @defgroup NNBasicMath Basic Math Functions for Neural Network Computation
|
||||
*
|
||||
* Basic Math Functions for Neural Network Computation
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Q7 vector multiplication with variable output shifts
|
||||
* @param[in] *pSrcA pointer to the first input vector
|
||||
* @param[in] *pSrcB pointer to the second input vector
|
||||
* @param[out] *pDst pointer to the output vector
|
||||
* @param[in] out_shift amount of right-shift for output
|
||||
* @param[in] blockSize number of samples in each vector
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function uses saturating arithmetic.
|
||||
* Results outside of the allowable Q15 range [0x8000 0x7FFF] will be saturated.
|
||||
*/
|
||||
|
||||
void arm_nn_mult_q15(
|
||||
q15_t * pSrcA,
|
||||
q15_t * pSrcB,
|
||||
q15_t * pDst,
|
||||
const uint16_t out_shift,
|
||||
uint32_t blockSize);
|
||||
|
||||
/**
|
||||
* @brief Q7 vector multiplication with variable output shifts
|
||||
* @param[in] *pSrcA pointer to the first input vector
|
||||
* @param[in] *pSrcB pointer to the second input vector
|
||||
* @param[out] *pDst pointer to the output vector
|
||||
* @param[in] out_shift amount of right-shift for output
|
||||
* @param[in] blockSize number of samples in each vector
|
||||
* @return none.
|
||||
*
|
||||
* <b>Scaling and Overflow Behavior:</b>
|
||||
* \par
|
||||
* The function uses saturating arithmetic.
|
||||
* Results outside of the allowable Q7 range [0x80 0x7F] will be saturated.
|
||||
*/
|
||||
|
||||
void arm_nn_mult_q7(
|
||||
q7_t * pSrcA,
|
||||
q7_t * pSrcB,
|
||||
q7_t * pDst,
|
||||
const uint16_t out_shift,
|
||||
uint32_t blockSize);
|
||||
|
||||
/**
|
||||
* @brief macro for adding rounding offset
|
||||
*/
|
||||
#ifndef ARM_NN_TRUNCATE
|
||||
#define NN_ROUND(out_shift) ( (0x1u << out_shift) >> 1 )
|
||||
#else
|
||||
#define NN_ROUND(out_shift) 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Saturating doubling high multiply. Result matches
|
||||
* NEON instruction VQRDMULH.
|
||||
* @param[in] m1 Multiplicand
|
||||
* @param[in] m2 Multiplier
|
||||
* @return Result of multiplication.
|
||||
*
|
||||
*/
|
||||
__STATIC_FORCEINLINE q31_t arm_nn_sat_doubling_high_mult(const q31_t m1, const q31_t m2)
|
||||
{
|
||||
q31_t result = 0;
|
||||
// Rounding offset to add for a right shift of 31
|
||||
q63_t mult = 1 << 30;
|
||||
|
||||
if ((m1 < 0) ^ (m2 < 0))
|
||||
{
|
||||
mult = 1 - mult;
|
||||
}
|
||||
// Gets resolved as a SMLAL instruction
|
||||
mult = mult + (q63_t)m1 * m2;
|
||||
|
||||
// Utilize all of the upper 32 bits. This is the doubling step
|
||||
// as well.
|
||||
result = mult / (1UL << 31);
|
||||
|
||||
if ((m1 == m2) && (m1 == Q31_MIN))
|
||||
{
|
||||
result = Q31_MAX;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Rounding divide by power of two.
|
||||
* @param[in] dividend - Dividend
|
||||
* @param[in] exponent - Divisor = power(2, exponent)
|
||||
* Range: [0, 31]
|
||||
* @return Rounded result of division. Midpoint is rounded away from zero.
|
||||
*
|
||||
*/
|
||||
__STATIC_FORCEINLINE q31_t arm_nn_divide_by_power_of_two(const q31_t dividend, const q31_t exponent)
|
||||
{
|
||||
q31_t result = 0;
|
||||
const q31_t remainder_mask = (1l << exponent) - 1;
|
||||
int32_t remainder = remainder_mask & dividend;
|
||||
|
||||
// Basic division
|
||||
result = dividend >> exponent;
|
||||
|
||||
// Adjust 'result' for rounding (mid point away from zero)
|
||||
q31_t threshold = remainder_mask >> 1;
|
||||
if (result < 0)
|
||||
{
|
||||
threshold++;
|
||||
}
|
||||
if (remainder > threshold)
|
||||
{
|
||||
result++;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -0,0 +1,242 @@
|
||||
;/**************************************************************************//**
|
||||
; * @file startup_ARMCM0.s
|
||||
; * @brief CMSIS Core Device Startup File for
|
||||
; * ARMCM0 Device Series
|
||||
; * @version V5.00
|
||||
; * @date 02. March 2016
|
||||
; ******************************************************************************/
|
||||
;/*
|
||||
; * Copyright (c) 2009-2016 ARM Limited. All rights reserved.
|
||||
; *
|
||||
; * 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
|
||||
; *
|
||||
; * 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.
|
||||
; */
|
||||
|
||||
;/*
|
||||
;//-------- <<< Use Configuration Wizard in Context Menu >>> ------------------
|
||||
;*/
|
||||
|
||||
|
||||
; <h> Stack Configuration
|
||||
; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
|
||||
; </h>
|
||||
|
||||
Stack_Size EQU 0x00000400
|
||||
|
||||
AREA STACK, NOINIT, READWRITE, ALIGN=3
|
||||
Stack_Mem SPACE Stack_Size
|
||||
__initial_sp
|
||||
|
||||
|
||||
; <h> Heap Configuration
|
||||
; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
|
||||
; </h>
|
||||
|
||||
Heap_Size EQU 0x00000C00
|
||||
|
||||
AREA HEAP, NOINIT, READWRITE, ALIGN=3
|
||||
__heap_base
|
||||
Heap_Mem SPACE Heap_Size
|
||||
__heap_limit
|
||||
|
||||
|
||||
PRESERVE8
|
||||
THUMB
|
||||
|
||||
|
||||
; Vector Table Mapped to Address 0 at Reset
|
||||
|
||||
AREA RESET, DATA, READONLY
|
||||
EXPORT __Vectors
|
||||
EXPORT __Vectors_End
|
||||
EXPORT __Vectors_Size
|
||||
|
||||
__Vectors DCD __initial_sp ; Top of Stack
|
||||
DCD Reset_Handler ; Reset Handler
|
||||
DCD NMI_Handler ; NMI Handler
|
||||
DCD HardFault_Handler ; Hard Fault Handler
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD SVC_Handler ; SVCall Handler
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD PendSV_Handler ; PendSV Handler
|
||||
DCD SysTick_Handler ; SysTick Handler
|
||||
|
||||
; External Interrupts
|
||||
DCD WDT_IRQHandler ; 0: Watchdog Timer
|
||||
DCD RTC_IRQHandler ; 1: Real Time Clock
|
||||
DCD TIM0_IRQHandler ; 2: Timer0 / Timer1
|
||||
DCD TIM2_IRQHandler ; 3: Timer2 / Timer3
|
||||
DCD MCIA_IRQHandler ; 4: MCIa
|
||||
DCD MCIB_IRQHandler ; 5: MCIb
|
||||
DCD UART0_IRQHandler ; 6: UART0 - DUT FPGA
|
||||
DCD UART1_IRQHandler ; 7: UART1 - DUT FPGA
|
||||
DCD UART2_IRQHandler ; 8: UART2 - DUT FPGA
|
||||
DCD UART4_IRQHandler ; 9: UART4 - not connected
|
||||
DCD AACI_IRQHandler ; 10: AACI / AC97
|
||||
DCD CLCD_IRQHandler ; 11: CLCD Combined Interrupt
|
||||
DCD ENET_IRQHandler ; 12: Ethernet
|
||||
DCD USBDC_IRQHandler ; 13: USB Device
|
||||
DCD USBHC_IRQHandler ; 14: USB Host Controller
|
||||
DCD CHLCD_IRQHandler ; 15: Character LCD
|
||||
DCD FLEXRAY_IRQHandler ; 16: Flexray
|
||||
DCD CAN_IRQHandler ; 17: CAN
|
||||
DCD LIN_IRQHandler ; 18: LIN
|
||||
DCD I2C_IRQHandler ; 19: I2C ADC/DAC
|
||||
DCD 0 ; 20: Reserved
|
||||
DCD 0 ; 21: Reserved
|
||||
DCD 0 ; 22: Reserved
|
||||
DCD 0 ; 23: Reserved
|
||||
DCD 0 ; 24: Reserved
|
||||
DCD 0 ; 25: Reserved
|
||||
DCD 0 ; 26: Reserved
|
||||
DCD 0 ; 27: Reserved
|
||||
DCD CPU_CLCD_IRQHandler ; 28: Reserved - CPU FPGA CLCD
|
||||
DCD 0 ; 29: Reserved - CPU FPGA
|
||||
DCD UART3_IRQHandler ; 30: UART3 - CPU FPGA
|
||||
DCD SPI_IRQHandler ; 31: SPI Touchscreen - CPU FPGA
|
||||
__Vectors_End
|
||||
|
||||
__Vectors_Size EQU __Vectors_End - __Vectors
|
||||
|
||||
AREA |.text|, CODE, READONLY
|
||||
|
||||
|
||||
; Reset Handler
|
||||
|
||||
Reset_Handler PROC
|
||||
EXPORT Reset_Handler [WEAK]
|
||||
IMPORT SystemInit
|
||||
IMPORT __main
|
||||
LDR R0, =SystemInit
|
||||
BLX R0
|
||||
LDR R0, =__main
|
||||
BX R0
|
||||
ENDP
|
||||
|
||||
|
||||
; Dummy Exception Handlers (infinite loops which can be modified)
|
||||
|
||||
NMI_Handler PROC
|
||||
EXPORT NMI_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
HardFault_Handler\
|
||||
PROC
|
||||
EXPORT HardFault_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
SVC_Handler PROC
|
||||
EXPORT SVC_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
PendSV_Handler PROC
|
||||
EXPORT PendSV_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
SysTick_Handler PROC
|
||||
EXPORT SysTick_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
|
||||
Default_Handler PROC
|
||||
|
||||
EXPORT WDT_IRQHandler [WEAK]
|
||||
EXPORT RTC_IRQHandler [WEAK]
|
||||
EXPORT TIM0_IRQHandler [WEAK]
|
||||
EXPORT TIM2_IRQHandler [WEAK]
|
||||
EXPORT MCIA_IRQHandler [WEAK]
|
||||
EXPORT MCIB_IRQHandler [WEAK]
|
||||
EXPORT UART0_IRQHandler [WEAK]
|
||||
EXPORT UART1_IRQHandler [WEAK]
|
||||
EXPORT UART2_IRQHandler [WEAK]
|
||||
EXPORT UART3_IRQHandler [WEAK]
|
||||
EXPORT UART4_IRQHandler [WEAK]
|
||||
EXPORT AACI_IRQHandler [WEAK]
|
||||
EXPORT CLCD_IRQHandler [WEAK]
|
||||
EXPORT ENET_IRQHandler [WEAK]
|
||||
EXPORT USBDC_IRQHandler [WEAK]
|
||||
EXPORT USBHC_IRQHandler [WEAK]
|
||||
EXPORT CHLCD_IRQHandler [WEAK]
|
||||
EXPORT FLEXRAY_IRQHandler [WEAK]
|
||||
EXPORT CAN_IRQHandler [WEAK]
|
||||
EXPORT LIN_IRQHandler [WEAK]
|
||||
EXPORT I2C_IRQHandler [WEAK]
|
||||
EXPORT CPU_CLCD_IRQHandler [WEAK]
|
||||
EXPORT SPI_IRQHandler [WEAK]
|
||||
|
||||
WDT_IRQHandler
|
||||
RTC_IRQHandler
|
||||
TIM0_IRQHandler
|
||||
TIM2_IRQHandler
|
||||
MCIA_IRQHandler
|
||||
MCIB_IRQHandler
|
||||
UART0_IRQHandler
|
||||
UART1_IRQHandler
|
||||
UART2_IRQHandler
|
||||
UART3_IRQHandler
|
||||
UART4_IRQHandler
|
||||
AACI_IRQHandler
|
||||
CLCD_IRQHandler
|
||||
ENET_IRQHandler
|
||||
USBDC_IRQHandler
|
||||
USBHC_IRQHandler
|
||||
CHLCD_IRQHandler
|
||||
FLEXRAY_IRQHandler
|
||||
CAN_IRQHandler
|
||||
LIN_IRQHandler
|
||||
I2C_IRQHandler
|
||||
CPU_CLCD_IRQHandler
|
||||
SPI_IRQHandler
|
||||
B .
|
||||
|
||||
ENDP
|
||||
|
||||
|
||||
ALIGN
|
||||
|
||||
|
||||
; User Initial Stack & Heap
|
||||
|
||||
IF :DEF:__MICROLIB
|
||||
|
||||
EXPORT __initial_sp
|
||||
EXPORT __heap_base
|
||||
EXPORT __heap_limit
|
||||
|
||||
ELSE
|
||||
|
||||
IMPORT __use_two_region_memory
|
||||
EXPORT __user_initial_stackheap
|
||||
|
||||
__user_initial_stackheap PROC
|
||||
LDR R0, = Heap_Mem
|
||||
LDR R1, =(Stack_Mem + Stack_Size)
|
||||
LDR R2, = (Heap_Mem + Heap_Size)
|
||||
LDR R3, = Stack_Mem
|
||||
BX LR
|
||||
ENDP
|
||||
|
||||
ALIGN
|
||||
|
||||
ENDIF
|
||||
|
||||
|
||||
END
|
@ -0,0 +1,56 @@
|
||||
/**************************************************************************//**
|
||||
* @file system_ARMCM0.c
|
||||
* @brief CMSIS Device System Source File for
|
||||
* ARMCM0 Device Series
|
||||
* @version V5.00
|
||||
* @date 08. April 2016
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2016 ARM Limited. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "ARMCM0.h"
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Define clocks
|
||||
*----------------------------------------------------------------------------*/
|
||||
#define XTAL ( 5000000U) /* Oscillator frequency */
|
||||
|
||||
#define SYSTEM_CLOCK (5 * XTAL)
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
System Core Clock Variable
|
||||
*----------------------------------------------------------------------------*/
|
||||
uint32_t SystemCoreClock = SYSTEM_CLOCK;
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
System Core Clock update function
|
||||
*----------------------------------------------------------------------------*/
|
||||
void SystemCoreClockUpdate (void)
|
||||
{
|
||||
SystemCoreClock = SYSTEM_CLOCK;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
System initialization function
|
||||
*----------------------------------------------------------------------------*/
|
||||
void SystemInit (void)
|
||||
{
|
||||
SystemCoreClock = SYSTEM_CLOCK;
|
||||
}
|
@ -0,0 +1,262 @@
|
||||
;/**************************************************************************//**
|
||||
; * @file startup_ARMCM3.s
|
||||
; * @brief CMSIS Core Device Startup File for
|
||||
; * ARMCM3 Device Series
|
||||
; * @version V5.00
|
||||
; * @date 02. March 2016
|
||||
; ******************************************************************************/
|
||||
;/*
|
||||
; * Copyright (c) 2009-2016 ARM Limited. All rights reserved.
|
||||
; *
|
||||
; * 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
|
||||
; *
|
||||
; * 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.
|
||||
; */
|
||||
|
||||
;/*
|
||||
;//-------- <<< Use Configuration Wizard in Context Menu >>> ------------------
|
||||
;*/
|
||||
|
||||
|
||||
; <h> Stack Configuration
|
||||
; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
|
||||
; </h>
|
||||
|
||||
Stack_Size EQU 0x00000400
|
||||
|
||||
AREA STACK, NOINIT, READWRITE, ALIGN=3
|
||||
Stack_Mem SPACE Stack_Size
|
||||
__initial_sp
|
||||
|
||||
|
||||
; <h> Heap Configuration
|
||||
; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
|
||||
; </h>
|
||||
|
||||
Heap_Size EQU 0x00080000
|
||||
|
||||
AREA HEAP, NOINIT, READWRITE, ALIGN=3
|
||||
__heap_base
|
||||
Heap_Mem SPACE Heap_Size
|
||||
__heap_limit
|
||||
|
||||
|
||||
PRESERVE8
|
||||
THUMB
|
||||
|
||||
|
||||
; Vector Table Mapped to Address 0 at Reset
|
||||
|
||||
AREA RESET, DATA, READONLY
|
||||
EXPORT __Vectors
|
||||
EXPORT __Vectors_End
|
||||
EXPORT __Vectors_Size
|
||||
|
||||
__Vectors DCD __initial_sp ; Top of Stack
|
||||
DCD Reset_Handler ; Reset Handler
|
||||
DCD NMI_Handler ; NMI Handler
|
||||
DCD HardFault_Handler ; Hard Fault Handler
|
||||
DCD MemManage_Handler ; MPU Fault Handler
|
||||
DCD BusFault_Handler ; Bus Fault Handler
|
||||
DCD UsageFault_Handler ; Usage Fault Handler
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD SVC_Handler ; SVCall Handler
|
||||
DCD DebugMon_Handler ; Debug Monitor Handler
|
||||
DCD 0 ; Reserved
|
||||
DCD PendSV_Handler ; PendSV Handler
|
||||
DCD SysTick_Handler ; SysTick Handler
|
||||
|
||||
; External Interrupts
|
||||
DCD WDT_IRQHandler ; 0: Watchdog Timer
|
||||
DCD RTC_IRQHandler ; 1: Real Time Clock
|
||||
DCD TIM0_IRQHandler ; 2: Timer0 / Timer1
|
||||
DCD TIM2_IRQHandler ; 3: Timer2 / Timer3
|
||||
DCD MCIA_IRQHandler ; 4: MCIa
|
||||
DCD MCIB_IRQHandler ; 5: MCIb
|
||||
DCD UART0_IRQHandler ; 6: UART0 - DUT FPGA
|
||||
DCD UART1_IRQHandler ; 7: UART1 - DUT FPGA
|
||||
DCD UART2_IRQHandler ; 8: UART2 - DUT FPGA
|
||||
DCD UART4_IRQHandler ; 9: UART4 - not connected
|
||||
DCD AACI_IRQHandler ; 10: AACI / AC97
|
||||
DCD CLCD_IRQHandler ; 11: CLCD Combined Interrupt
|
||||
DCD ENET_IRQHandler ; 12: Ethernet
|
||||
DCD USBDC_IRQHandler ; 13: USB Device
|
||||
DCD USBHC_IRQHandler ; 14: USB Host Controller
|
||||
DCD CHLCD_IRQHandler ; 15: Character LCD
|
||||
DCD FLEXRAY_IRQHandler ; 16: Flexray
|
||||
DCD CAN_IRQHandler ; 17: CAN
|
||||
DCD LIN_IRQHandler ; 18: LIN
|
||||
DCD I2C_IRQHandler ; 19: I2C ADC/DAC
|
||||
DCD 0 ; 20: Reserved
|
||||
DCD 0 ; 21: Reserved
|
||||
DCD 0 ; 22: Reserved
|
||||
DCD 0 ; 23: Reserved
|
||||
DCD 0 ; 24: Reserved
|
||||
DCD 0 ; 25: Reserved
|
||||
DCD 0 ; 26: Reserved
|
||||
DCD 0 ; 27: Reserved
|
||||
DCD CPU_CLCD_IRQHandler ; 28: Reserved - CPU FPGA CLCD
|
||||
DCD 0 ; 29: Reserved - CPU FPGA
|
||||
DCD UART3_IRQHandler ; 30: UART3 - CPU FPGA
|
||||
DCD SPI_IRQHandler ; 31: SPI Touchscreen - CPU FPGA
|
||||
__Vectors_End
|
||||
|
||||
__Vectors_Size EQU __Vectors_End - __Vectors
|
||||
|
||||
AREA |.text|, CODE, READONLY
|
||||
|
||||
|
||||
; Reset Handler
|
||||
|
||||
Reset_Handler PROC
|
||||
EXPORT Reset_Handler [WEAK]
|
||||
IMPORT SystemInit
|
||||
IMPORT __main
|
||||
LDR R0, =SystemInit
|
||||
BLX R0
|
||||
LDR R0, =__main
|
||||
BX R0
|
||||
ENDP
|
||||
|
||||
|
||||
; Dummy Exception Handlers (infinite loops which can be modified)
|
||||
|
||||
NMI_Handler PROC
|
||||
EXPORT NMI_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
HardFault_Handler\
|
||||
PROC
|
||||
EXPORT HardFault_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
MemManage_Handler\
|
||||
PROC
|
||||
EXPORT MemManage_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
BusFault_Handler\
|
||||
PROC
|
||||
EXPORT BusFault_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
UsageFault_Handler\
|
||||
PROC
|
||||
EXPORT UsageFault_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
SVC_Handler PROC
|
||||
EXPORT SVC_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
DebugMon_Handler\
|
||||
PROC
|
||||
EXPORT DebugMon_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
PendSV_Handler PROC
|
||||
EXPORT PendSV_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
SysTick_Handler PROC
|
||||
EXPORT SysTick_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
|
||||
Default_Handler PROC
|
||||
|
||||
EXPORT WDT_IRQHandler [WEAK]
|
||||
EXPORT RTC_IRQHandler [WEAK]
|
||||
EXPORT TIM0_IRQHandler [WEAK]
|
||||
EXPORT TIM2_IRQHandler [WEAK]
|
||||
EXPORT MCIA_IRQHandler [WEAK]
|
||||
EXPORT MCIB_IRQHandler [WEAK]
|
||||
EXPORT UART0_IRQHandler [WEAK]
|
||||
EXPORT UART1_IRQHandler [WEAK]
|
||||
EXPORT UART2_IRQHandler [WEAK]
|
||||
EXPORT UART3_IRQHandler [WEAK]
|
||||
EXPORT UART4_IRQHandler [WEAK]
|
||||
EXPORT AACI_IRQHandler [WEAK]
|
||||
EXPORT CLCD_IRQHandler [WEAK]
|
||||
EXPORT ENET_IRQHandler [WEAK]
|
||||
EXPORT USBDC_IRQHandler [WEAK]
|
||||
EXPORT USBHC_IRQHandler [WEAK]
|
||||
EXPORT CHLCD_IRQHandler [WEAK]
|
||||
EXPORT FLEXRAY_IRQHandler [WEAK]
|
||||
EXPORT CAN_IRQHandler [WEAK]
|
||||
EXPORT LIN_IRQHandler [WEAK]
|
||||
EXPORT I2C_IRQHandler [WEAK]
|
||||
EXPORT CPU_CLCD_IRQHandler [WEAK]
|
||||
EXPORT SPI_IRQHandler [WEAK]
|
||||
|
||||
WDT_IRQHandler
|
||||
RTC_IRQHandler
|
||||
TIM0_IRQHandler
|
||||
TIM2_IRQHandler
|
||||
MCIA_IRQHandler
|
||||
MCIB_IRQHandler
|
||||
UART0_IRQHandler
|
||||
UART1_IRQHandler
|
||||
UART2_IRQHandler
|
||||
UART3_IRQHandler
|
||||
UART4_IRQHandler
|
||||
AACI_IRQHandler
|
||||
CLCD_IRQHandler
|
||||
ENET_IRQHandler
|
||||
USBDC_IRQHandler
|
||||
USBHC_IRQHandler
|
||||
CHLCD_IRQHandler
|
||||
FLEXRAY_IRQHandler
|
||||
CAN_IRQHandler
|
||||
LIN_IRQHandler
|
||||
I2C_IRQHandler
|
||||
CPU_CLCD_IRQHandler
|
||||
SPI_IRQHandler
|
||||
B .
|
||||
|
||||
ENDP
|
||||
|
||||
|
||||
ALIGN
|
||||
|
||||
|
||||
; User Initial Stack & Heap
|
||||
|
||||
IF :DEF:__MICROLIB
|
||||
|
||||
EXPORT __initial_sp
|
||||
EXPORT __heap_base
|
||||
EXPORT __heap_limit
|
||||
|
||||
ELSE
|
||||
|
||||
IMPORT __use_two_region_memory
|
||||
EXPORT __user_initial_stackheap
|
||||
|
||||
__user_initial_stackheap PROC
|
||||
LDR R0, = Heap_Mem
|
||||
LDR R1, =(Stack_Mem + Stack_Size)
|
||||
LDR R2, = (Heap_Mem + Heap_Size)
|
||||
LDR R3, = Stack_Mem
|
||||
BX LR
|
||||
ENDP
|
||||
|
||||
ALIGN
|
||||
|
||||
ENDIF
|
||||
|
||||
|
||||
END
|
@ -0,0 +1,68 @@
|
||||
/**************************************************************************//**
|
||||
* @file system_ARMCM3.c
|
||||
* @brief CMSIS Device System Source File for
|
||||
* ARMCM3 Device Series
|
||||
* @version V5.00
|
||||
* @date 08. April 2016
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2016 ARM Limited. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "ARMCM3.h"
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Define clocks
|
||||
*----------------------------------------------------------------------------*/
|
||||
#define XTAL ( 5000000U) /* Oscillator frequency */
|
||||
|
||||
#define SYSTEM_CLOCK (5 * XTAL)
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Externals
|
||||
*----------------------------------------------------------------------------*/
|
||||
#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1)
|
||||
extern uint32_t __Vectors;
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
System Core Clock Variable
|
||||
*----------------------------------------------------------------------------*/
|
||||
uint32_t SystemCoreClock = SYSTEM_CLOCK;
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
System Core Clock update function
|
||||
*----------------------------------------------------------------------------*/
|
||||
void SystemCoreClockUpdate (void)
|
||||
{
|
||||
SystemCoreClock = SYSTEM_CLOCK;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
System initialization function
|
||||
*----------------------------------------------------------------------------*/
|
||||
void SystemInit (void)
|
||||
{
|
||||
|
||||
#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1)
|
||||
SCB->VTOR = (uint32_t) &__Vectors;
|
||||
#endif
|
||||
|
||||
SystemCoreClock = SYSTEM_CLOCK;
|
||||
}
|
@ -0,0 +1,262 @@
|
||||
;/**************************************************************************//**
|
||||
; * @file startup_ARMCM4.s
|
||||
; * @brief CMSIS Core Device Startup File for
|
||||
; * ARMCM4 Device Series
|
||||
; * @version V5.00
|
||||
; * @date 02. March 2016
|
||||
; ******************************************************************************/
|
||||
;/*
|
||||
; * Copyright (c) 2009-2016 ARM Limited. All rights reserved.
|
||||
; *
|
||||
; * 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
|
||||
; *
|
||||
; * 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.
|
||||
; */
|
||||
|
||||
;/*
|
||||
;//-------- <<< Use Configuration Wizard in Context Menu >>> ------------------
|
||||
;*/
|
||||
|
||||
|
||||
; <h> Stack Configuration
|
||||
; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
|
||||
; </h>
|
||||
|
||||
Stack_Size EQU 0x00000400
|
||||
|
||||
AREA STACK, NOINIT, READWRITE, ALIGN=3
|
||||
Stack_Mem SPACE Stack_Size
|
||||
__initial_sp
|
||||
|
||||
|
||||
; <h> Heap Configuration
|
||||
; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
|
||||
; </h>
|
||||
|
||||
Heap_Size EQU 0x00000C00
|
||||
|
||||
AREA HEAP, NOINIT, READWRITE, ALIGN=3
|
||||
__heap_base
|
||||
Heap_Mem SPACE Heap_Size
|
||||
__heap_limit
|
||||
|
||||
|
||||
PRESERVE8
|
||||
THUMB
|
||||
|
||||
|
||||
; Vector Table Mapped to Address 0 at Reset
|
||||
|
||||
AREA RESET, DATA, READONLY
|
||||
EXPORT __Vectors
|
||||
EXPORT __Vectors_End
|
||||
EXPORT __Vectors_Size
|
||||
|
||||
__Vectors DCD __initial_sp ; Top of Stack
|
||||
DCD Reset_Handler ; Reset Handler
|
||||
DCD NMI_Handler ; NMI Handler
|
||||
DCD HardFault_Handler ; Hard Fault Handler
|
||||
DCD MemManage_Handler ; MPU Fault Handler
|
||||
DCD BusFault_Handler ; Bus Fault Handler
|
||||
DCD UsageFault_Handler ; Usage Fault Handler
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD SVC_Handler ; SVCall Handler
|
||||
DCD DebugMon_Handler ; Debug Monitor Handler
|
||||
DCD 0 ; Reserved
|
||||
DCD PendSV_Handler ; PendSV Handler
|
||||
DCD SysTick_Handler ; SysTick Handler
|
||||
|
||||
; External Interrupts
|
||||
DCD WDT_IRQHandler ; 0: Watchdog Timer
|
||||
DCD RTC_IRQHandler ; 1: Real Time Clock
|
||||
DCD TIM0_IRQHandler ; 2: Timer0 / Timer1
|
||||
DCD TIM2_IRQHandler ; 3: Timer2 / Timer3
|
||||
DCD MCIA_IRQHandler ; 4: MCIa
|
||||
DCD MCIB_IRQHandler ; 5: MCIb
|
||||
DCD UART0_IRQHandler ; 6: UART0 - DUT FPGA
|
||||
DCD UART1_IRQHandler ; 7: UART1 - DUT FPGA
|
||||
DCD UART2_IRQHandler ; 8: UART2 - DUT FPGA
|
||||
DCD UART4_IRQHandler ; 9: UART4 - not connected
|
||||
DCD AACI_IRQHandler ; 10: AACI / AC97
|
||||
DCD CLCD_IRQHandler ; 11: CLCD Combined Interrupt
|
||||
DCD ENET_IRQHandler ; 12: Ethernet
|
||||
DCD USBDC_IRQHandler ; 13: USB Device
|
||||
DCD USBHC_IRQHandler ; 14: USB Host Controller
|
||||
DCD CHLCD_IRQHandler ; 15: Character LCD
|
||||
DCD FLEXRAY_IRQHandler ; 16: Flexray
|
||||
DCD CAN_IRQHandler ; 17: CAN
|
||||
DCD LIN_IRQHandler ; 18: LIN
|
||||
DCD I2C_IRQHandler ; 19: I2C ADC/DAC
|
||||
DCD 0 ; 20: Reserved
|
||||
DCD 0 ; 21: Reserved
|
||||
DCD 0 ; 22: Reserved
|
||||
DCD 0 ; 23: Reserved
|
||||
DCD 0 ; 24: Reserved
|
||||
DCD 0 ; 25: Reserved
|
||||
DCD 0 ; 26: Reserved
|
||||
DCD 0 ; 27: Reserved
|
||||
DCD CPU_CLCD_IRQHandler ; 28: Reserved - CPU FPGA CLCD
|
||||
DCD 0 ; 29: Reserved - CPU FPGA
|
||||
DCD UART3_IRQHandler ; 30: UART3 - CPU FPGA
|
||||
DCD SPI_IRQHandler ; 31: SPI Touchscreen - CPU FPGA
|
||||
__Vectors_End
|
||||
|
||||
__Vectors_Size EQU __Vectors_End - __Vectors
|
||||
|
||||
AREA |.text|, CODE, READONLY
|
||||
|
||||
|
||||
; Reset Handler
|
||||
|
||||
Reset_Handler PROC
|
||||
EXPORT Reset_Handler [WEAK]
|
||||
IMPORT SystemInit
|
||||
IMPORT __main
|
||||
LDR R0, =SystemInit
|
||||
BLX R0
|
||||
LDR R0, =__main
|
||||
BX R0
|
||||
ENDP
|
||||
|
||||
|
||||
; Dummy Exception Handlers (infinite loops which can be modified)
|
||||
|
||||
NMI_Handler PROC
|
||||
EXPORT NMI_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
HardFault_Handler\
|
||||
PROC
|
||||
EXPORT HardFault_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
MemManage_Handler\
|
||||
PROC
|
||||
EXPORT MemManage_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
BusFault_Handler\
|
||||
PROC
|
||||
EXPORT BusFault_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
UsageFault_Handler\
|
||||
PROC
|
||||
EXPORT UsageFault_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
SVC_Handler PROC
|
||||
EXPORT SVC_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
DebugMon_Handler\
|
||||
PROC
|
||||
EXPORT DebugMon_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
PendSV_Handler PROC
|
||||
EXPORT PendSV_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
SysTick_Handler PROC
|
||||
EXPORT SysTick_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
|
||||
Default_Handler PROC
|
||||
|
||||
EXPORT WDT_IRQHandler [WEAK]
|
||||
EXPORT RTC_IRQHandler [WEAK]
|
||||
EXPORT TIM0_IRQHandler [WEAK]
|
||||
EXPORT TIM2_IRQHandler [WEAK]
|
||||
EXPORT MCIA_IRQHandler [WEAK]
|
||||
EXPORT MCIB_IRQHandler [WEAK]
|
||||
EXPORT UART0_IRQHandler [WEAK]
|
||||
EXPORT UART1_IRQHandler [WEAK]
|
||||
EXPORT UART2_IRQHandler [WEAK]
|
||||
EXPORT UART3_IRQHandler [WEAK]
|
||||
EXPORT UART4_IRQHandler [WEAK]
|
||||
EXPORT AACI_IRQHandler [WEAK]
|
||||
EXPORT CLCD_IRQHandler [WEAK]
|
||||
EXPORT ENET_IRQHandler [WEAK]
|
||||
EXPORT USBDC_IRQHandler [WEAK]
|
||||
EXPORT USBHC_IRQHandler [WEAK]
|
||||
EXPORT CHLCD_IRQHandler [WEAK]
|
||||
EXPORT FLEXRAY_IRQHandler [WEAK]
|
||||
EXPORT CAN_IRQHandler [WEAK]
|
||||
EXPORT LIN_IRQHandler [WEAK]
|
||||
EXPORT I2C_IRQHandler [WEAK]
|
||||
EXPORT CPU_CLCD_IRQHandler [WEAK]
|
||||
EXPORT SPI_IRQHandler [WEAK]
|
||||
|
||||
WDT_IRQHandler
|
||||
RTC_IRQHandler
|
||||
TIM0_IRQHandler
|
||||
TIM2_IRQHandler
|
||||
MCIA_IRQHandler
|
||||
MCIB_IRQHandler
|
||||
UART0_IRQHandler
|
||||
UART1_IRQHandler
|
||||
UART2_IRQHandler
|
||||
UART3_IRQHandler
|
||||
UART4_IRQHandler
|
||||
AACI_IRQHandler
|
||||
CLCD_IRQHandler
|
||||
ENET_IRQHandler
|
||||
USBDC_IRQHandler
|
||||
USBHC_IRQHandler
|
||||
CHLCD_IRQHandler
|
||||
FLEXRAY_IRQHandler
|
||||
CAN_IRQHandler
|
||||
LIN_IRQHandler
|
||||
I2C_IRQHandler
|
||||
CPU_CLCD_IRQHandler
|
||||
SPI_IRQHandler
|
||||
B .
|
||||
|
||||
ENDP
|
||||
|
||||
|
||||
ALIGN
|
||||
|
||||
|
||||
; User Initial Stack & Heap
|
||||
|
||||
IF :DEF:__MICROLIB
|
||||
|
||||
EXPORT __initial_sp
|
||||
EXPORT __heap_base
|
||||
EXPORT __heap_limit
|
||||
|
||||
ELSE
|
||||
|
||||
IMPORT __use_two_region_memory
|
||||
EXPORT __user_initial_stackheap
|
||||
|
||||
__user_initial_stackheap PROC
|
||||
LDR R0, = Heap_Mem
|
||||
LDR R1, =(Stack_Mem + Stack_Size)
|
||||
LDR R2, = (Heap_Mem + Heap_Size)
|
||||
LDR R3, = Stack_Mem
|
||||
BX LR
|
||||
ENDP
|
||||
|
||||
ALIGN
|
||||
|
||||
ENDIF
|
||||
|
||||
|
||||
END
|
@ -0,0 +1,83 @@
|
||||
/**************************************************************************//**
|
||||
* @file system_ARMCM4.c
|
||||
* @brief CMSIS Device System Source File for
|
||||
* ARMCM4 Device Series
|
||||
* @version V5.00
|
||||
* @date 07. September 2016
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2016 ARM Limited. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if defined (ARMCM4)
|
||||
#include "ARMCM4.h"
|
||||
#elif defined (ARMCM4_FP)
|
||||
#include "ARMCM4_FP.h"
|
||||
#else
|
||||
#error device not specified!
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Define clocks
|
||||
*----------------------------------------------------------------------------*/
|
||||
#define XTAL ( 5000000UL) /* Oscillator frequency */
|
||||
|
||||
#define SYSTEM_CLOCK (5U * XTAL)
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Externals
|
||||
*----------------------------------------------------------------------------*/
|
||||
#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U)
|
||||
extern uint32_t __Vectors;
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
System Core Clock Variable
|
||||
*----------------------------------------------------------------------------*/
|
||||
uint32_t SystemCoreClock = SYSTEM_CLOCK;
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
System Core Clock update function
|
||||
*----------------------------------------------------------------------------*/
|
||||
void SystemCoreClockUpdate (void)
|
||||
{
|
||||
SystemCoreClock = SYSTEM_CLOCK;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
System initialization function
|
||||
*----------------------------------------------------------------------------*/
|
||||
void SystemInit (void)
|
||||
{
|
||||
|
||||
#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U)
|
||||
SCB->VTOR = (uint32_t) &__Vectors;
|
||||
#endif
|
||||
|
||||
#if defined (__FPU_USED) && (__FPU_USED == 1U)
|
||||
SCB->CPACR |= ((3U << 10U*2U) | /* set CP10 Full Access */
|
||||
(3U << 11U*2U) ); /* set CP11 Full Access */
|
||||
#endif
|
||||
|
||||
#ifdef UNALIGNED_SUPPORT_DISABLE
|
||||
SCB->CCR |= SCB_CCR_UNALIGN_TRP_Msk;
|
||||
#endif
|
||||
|
||||
SystemCoreClock = SYSTEM_CLOCK;
|
||||
}
|
@ -0,0 +1,262 @@
|
||||
;/**************************************************************************//**
|
||||
; * @file startup_ARMCM4.s
|
||||
; * @brief CMSIS Core Device Startup File for
|
||||
; * ARMCM4 Device Series
|
||||
; * @version V5.00
|
||||
; * @date 02. March 2016
|
||||
; ******************************************************************************/
|
||||
;/*
|
||||
; * Copyright (c) 2009-2016 ARM Limited. All rights reserved.
|
||||
; *
|
||||
; * 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
|
||||
; *
|
||||
; * 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.
|
||||
; */
|
||||
|
||||
;/*
|
||||
;//-------- <<< Use Configuration Wizard in Context Menu >>> ------------------
|
||||
;*/
|
||||
|
||||
|
||||
; <h> Stack Configuration
|
||||
; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
|
||||
; </h>
|
||||
|
||||
Stack_Size EQU 0x00004000
|
||||
|
||||
AREA STACK, NOINIT, READWRITE, ALIGN=3
|
||||
Stack_Mem SPACE Stack_Size
|
||||
__initial_sp
|
||||
|
||||
|
||||
; <h> Heap Configuration
|
||||
; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
|
||||
; </h>
|
||||
|
||||
Heap_Size EQU 0x00100000
|
||||
|
||||
AREA HEAP, NOINIT, READWRITE, ALIGN=3
|
||||
__heap_base
|
||||
Heap_Mem SPACE Heap_Size
|
||||
__heap_limit
|
||||
|
||||
|
||||
PRESERVE8
|
||||
THUMB
|
||||
|
||||
|
||||
; Vector Table Mapped to Address 0 at Reset
|
||||
|
||||
AREA RESET, DATA, READONLY
|
||||
EXPORT __Vectors
|
||||
EXPORT __Vectors_End
|
||||
EXPORT __Vectors_Size
|
||||
|
||||
__Vectors DCD __initial_sp ; Top of Stack
|
||||
DCD Reset_Handler ; Reset Handler
|
||||
DCD NMI_Handler ; NMI Handler
|
||||
DCD HardFault_Handler ; Hard Fault Handler
|
||||
DCD MemManage_Handler ; MPU Fault Handler
|
||||
DCD BusFault_Handler ; Bus Fault Handler
|
||||
DCD UsageFault_Handler ; Usage Fault Handler
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD SVC_Handler ; SVCall Handler
|
||||
DCD DebugMon_Handler ; Debug Monitor Handler
|
||||
DCD 0 ; Reserved
|
||||
DCD PendSV_Handler ; PendSV Handler
|
||||
DCD SysTick_Handler ; SysTick Handler
|
||||
|
||||
; External Interrupts
|
||||
DCD WDT_IRQHandler ; 0: Watchdog Timer
|
||||
DCD RTC_IRQHandler ; 1: Real Time Clock
|
||||
DCD TIM0_IRQHandler ; 2: Timer0 / Timer1
|
||||
DCD TIM2_IRQHandler ; 3: Timer2 / Timer3
|
||||
DCD MCIA_IRQHandler ; 4: MCIa
|
||||
DCD MCIB_IRQHandler ; 5: MCIb
|
||||
DCD UART0_IRQHandler ; 6: UART0 - DUT FPGA
|
||||
DCD UART1_IRQHandler ; 7: UART1 - DUT FPGA
|
||||
DCD UART2_IRQHandler ; 8: UART2 - DUT FPGA
|
||||
DCD UART4_IRQHandler ; 9: UART4 - not connected
|
||||
DCD AACI_IRQHandler ; 10: AACI / AC97
|
||||
DCD CLCD_IRQHandler ; 11: CLCD Combined Interrupt
|
||||
DCD ENET_IRQHandler ; 12: Ethernet
|
||||
DCD USBDC_IRQHandler ; 13: USB Device
|
||||
DCD USBHC_IRQHandler ; 14: USB Host Controller
|
||||
DCD CHLCD_IRQHandler ; 15: Character LCD
|
||||
DCD FLEXRAY_IRQHandler ; 16: Flexray
|
||||
DCD CAN_IRQHandler ; 17: CAN
|
||||
DCD LIN_IRQHandler ; 18: LIN
|
||||
DCD I2C_IRQHandler ; 19: I2C ADC/DAC
|
||||
DCD 0 ; 20: Reserved
|
||||
DCD 0 ; 21: Reserved
|
||||
DCD 0 ; 22: Reserved
|
||||
DCD 0 ; 23: Reserved
|
||||
DCD 0 ; 24: Reserved
|
||||
DCD 0 ; 25: Reserved
|
||||
DCD 0 ; 26: Reserved
|
||||
DCD 0 ; 27: Reserved
|
||||
DCD CPU_CLCD_IRQHandler ; 28: Reserved - CPU FPGA CLCD
|
||||
DCD 0 ; 29: Reserved - CPU FPGA
|
||||
DCD UART3_IRQHandler ; 30: UART3 - CPU FPGA
|
||||
DCD SPI_IRQHandler ; 31: SPI Touchscreen - CPU FPGA
|
||||
__Vectors_End
|
||||
|
||||
__Vectors_Size EQU __Vectors_End - __Vectors
|
||||
|
||||
AREA |.text|, CODE, READONLY
|
||||
|
||||
|
||||
; Reset Handler
|
||||
|
||||
Reset_Handler PROC
|
||||
EXPORT Reset_Handler [WEAK]
|
||||
IMPORT SystemInit
|
||||
IMPORT __main
|
||||
LDR R0, =SystemInit
|
||||
BLX R0
|
||||
LDR R0, =__main
|
||||
BX R0
|
||||
ENDP
|
||||
|
||||
|
||||
; Dummy Exception Handlers (infinite loops which can be modified)
|
||||
|
||||
NMI_Handler PROC
|
||||
EXPORT NMI_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
HardFault_Handler\
|
||||
PROC
|
||||
EXPORT HardFault_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
MemManage_Handler\
|
||||
PROC
|
||||
EXPORT MemManage_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
BusFault_Handler\
|
||||
PROC
|
||||
EXPORT BusFault_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
UsageFault_Handler\
|
||||
PROC
|
||||
EXPORT UsageFault_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
SVC_Handler PROC
|
||||
EXPORT SVC_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
DebugMon_Handler\
|
||||
PROC
|
||||
EXPORT DebugMon_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
PendSV_Handler PROC
|
||||
EXPORT PendSV_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
SysTick_Handler PROC
|
||||
EXPORT SysTick_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
|
||||
Default_Handler PROC
|
||||
|
||||
EXPORT WDT_IRQHandler [WEAK]
|
||||
EXPORT RTC_IRQHandler [WEAK]
|
||||
EXPORT TIM0_IRQHandler [WEAK]
|
||||
EXPORT TIM2_IRQHandler [WEAK]
|
||||
EXPORT MCIA_IRQHandler [WEAK]
|
||||
EXPORT MCIB_IRQHandler [WEAK]
|
||||
EXPORT UART0_IRQHandler [WEAK]
|
||||
EXPORT UART1_IRQHandler [WEAK]
|
||||
EXPORT UART2_IRQHandler [WEAK]
|
||||
EXPORT UART3_IRQHandler [WEAK]
|
||||
EXPORT UART4_IRQHandler [WEAK]
|
||||
EXPORT AACI_IRQHandler [WEAK]
|
||||
EXPORT CLCD_IRQHandler [WEAK]
|
||||
EXPORT ENET_IRQHandler [WEAK]
|
||||
EXPORT USBDC_IRQHandler [WEAK]
|
||||
EXPORT USBHC_IRQHandler [WEAK]
|
||||
EXPORT CHLCD_IRQHandler [WEAK]
|
||||
EXPORT FLEXRAY_IRQHandler [WEAK]
|
||||
EXPORT CAN_IRQHandler [WEAK]
|
||||
EXPORT LIN_IRQHandler [WEAK]
|
||||
EXPORT I2C_IRQHandler [WEAK]
|
||||
EXPORT CPU_CLCD_IRQHandler [WEAK]
|
||||
EXPORT SPI_IRQHandler [WEAK]
|
||||
|
||||
WDT_IRQHandler
|
||||
RTC_IRQHandler
|
||||
TIM0_IRQHandler
|
||||
TIM2_IRQHandler
|
||||
MCIA_IRQHandler
|
||||
MCIB_IRQHandler
|
||||
UART0_IRQHandler
|
||||
UART1_IRQHandler
|
||||
UART2_IRQHandler
|
||||
UART3_IRQHandler
|
||||
UART4_IRQHandler
|
||||
AACI_IRQHandler
|
||||
CLCD_IRQHandler
|
||||
ENET_IRQHandler
|
||||
USBDC_IRQHandler
|
||||
USBHC_IRQHandler
|
||||
CHLCD_IRQHandler
|
||||
FLEXRAY_IRQHandler
|
||||
CAN_IRQHandler
|
||||
LIN_IRQHandler
|
||||
I2C_IRQHandler
|
||||
CPU_CLCD_IRQHandler
|
||||
SPI_IRQHandler
|
||||
B .
|
||||
|
||||
ENDP
|
||||
|
||||
|
||||
ALIGN
|
||||
|
||||
|
||||
; User Initial Stack & Heap
|
||||
|
||||
IF :DEF:__MICROLIB
|
||||
|
||||
EXPORT __initial_sp
|
||||
EXPORT __heap_base
|
||||
EXPORT __heap_limit
|
||||
|
||||
ELSE
|
||||
|
||||
IMPORT __use_two_region_memory
|
||||
EXPORT __user_initial_stackheap
|
||||
|
||||
__user_initial_stackheap PROC
|
||||
LDR R0, = Heap_Mem
|
||||
LDR R1, =(Stack_Mem + Stack_Size)
|
||||
LDR R2, = (Heap_Mem + Heap_Size)
|
||||
LDR R3, = Stack_Mem
|
||||
BX LR
|
||||
ENDP
|
||||
|
||||
ALIGN
|
||||
|
||||
ENDIF
|
||||
|
||||
|
||||
END
|
@ -0,0 +1,83 @@
|
||||
/**************************************************************************//**
|
||||
* @file system_ARMCM4.c
|
||||
* @brief CMSIS Device System Source File for
|
||||
* ARMCM4 Device Series
|
||||
* @version V5.00
|
||||
* @date 08. April 2016
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2016 ARM Limited. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if defined (ARMCM4)
|
||||
#include "ARMCM4.h"
|
||||
#elif defined (ARMCM4_FP)
|
||||
#include "ARMCM4_FP.h"
|
||||
#else
|
||||
#error device not specified!
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Define clocks
|
||||
*----------------------------------------------------------------------------*/
|
||||
#define XTAL ( 5000000U) /* Oscillator frequency */
|
||||
|
||||
#define SYSTEM_CLOCK (5 * XTAL)
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Externals
|
||||
*----------------------------------------------------------------------------*/
|
||||
#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1)
|
||||
extern uint32_t __Vectors;
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
System Core Clock Variable
|
||||
*----------------------------------------------------------------------------*/
|
||||
uint32_t SystemCoreClock = SYSTEM_CLOCK;
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
System Core Clock update function
|
||||
*----------------------------------------------------------------------------*/
|
||||
void SystemCoreClockUpdate (void)
|
||||
{
|
||||
SystemCoreClock = SYSTEM_CLOCK;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
System initialization function
|
||||
*----------------------------------------------------------------------------*/
|
||||
void SystemInit (void)
|
||||
{
|
||||
|
||||
#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1)
|
||||
SCB->VTOR = (uint32_t) &__Vectors;
|
||||
#endif
|
||||
|
||||
#if defined (__FPU_USED) && (__FPU_USED == 1)
|
||||
SCB->CPACR |= ((3U << 10*2) | /* set CP10 Full Access */
|
||||
(3U << 11*2) ); /* set CP11 Full Access */
|
||||
#endif
|
||||
|
||||
#ifdef UNALIGNED_SUPPORT_DISABLE
|
||||
SCB->CCR |= SCB_CCR_UNALIGN_TRP_Msk;
|
||||
#endif
|
||||
|
||||
SystemCoreClock = SYSTEM_CLOCK;
|
||||
}
|
@ -0,0 +1,295 @@
|
||||
/**************************************************************************//**
|
||||
* @file startup_ARMCM7.s
|
||||
* @brief CMSIS Core Device Startup File for
|
||||
* ARMCM7 Device Series
|
||||
* @version V5.00
|
||||
* @date 26. April 2016
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2016 ARM Limited. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Linker generated Symbols
|
||||
*----------------------------------------------------------------------------*/
|
||||
extern uint32_t __etext;
|
||||
extern uint32_t __data_start__;
|
||||
extern uint32_t __data_end__;
|
||||
extern uint32_t __copy_table_start__;
|
||||
extern uint32_t __copy_table_end__;
|
||||
extern uint32_t __zero_table_start__;
|
||||
extern uint32_t __zero_table_end__;
|
||||
extern uint32_t __bss_start__;
|
||||
extern uint32_t __bss_end__;
|
||||
extern uint32_t __StackTop;
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Exception / Interrupt Handler Function Prototype
|
||||
*----------------------------------------------------------------------------*/
|
||||
typedef void( *pFunc )( void );
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
External References
|
||||
*----------------------------------------------------------------------------*/
|
||||
#ifndef __START
|
||||
extern void _start(void) __attribute__((noreturn)); /* PreeMain (C library entry point) */
|
||||
#else
|
||||
extern int __START(void) __attribute__((noreturn)); /* main entry point */
|
||||
#endif
|
||||
|
||||
#ifndef __NO_SYSTEM_INIT
|
||||
extern void SystemInit (void); /* CMSIS System Initialization */
|
||||
#endif
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Internal References
|
||||
*----------------------------------------------------------------------------*/
|
||||
void Default_Handler(void); /* Default empty handler */
|
||||
void Reset_Handler(void); /* Reset Handler */
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
User Initial Stack & Heap
|
||||
*----------------------------------------------------------------------------*/
|
||||
#ifndef __STACK_SIZE
|
||||
#define __STACK_SIZE 0x00000400
|
||||
#endif
|
||||
static uint8_t stack[__STACK_SIZE] __attribute__ ((aligned(8), used, section(".stack")));
|
||||
|
||||
#ifndef __HEAP_SIZE
|
||||
#define __HEAP_SIZE 0x00000C00
|
||||
#endif
|
||||
#if __HEAP_SIZE > 0
|
||||
static uint8_t heap[__HEAP_SIZE] __attribute__ ((aligned(8), used, section(".heap")));
|
||||
#endif
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Exception / Interrupt Handler
|
||||
*----------------------------------------------------------------------------*/
|
||||
/* Cortex-M7 Processor Exceptions */
|
||||
void NMI_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void HardFault_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void MemManage_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void BusFault_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void UsageFault_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void SVC_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void DebugMon_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void PendSV_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void SysTick_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
|
||||
/* ARMCM7 Specific Interrupts */
|
||||
void WDT_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void RTC_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void TIM0_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void TIM2_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void MCIA_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void MCIB_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void UART0_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void UART1_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void UART2_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void UART4_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void AACI_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void CLCD_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void ENET_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void USBDC_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void USBHC_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void CHLCD_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void FLEXRAY_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void CAN_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void LIN_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void I2C_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void CPU_CLCD_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void UART3_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
void SPI_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Exception / Interrupt Vector table
|
||||
*----------------------------------------------------------------------------*/
|
||||
const pFunc __Vectors[] __attribute__ ((section(".vectors"))) = {
|
||||
/* Cortex-M7 Exceptions Handler */
|
||||
(pFunc)((uint32_t)&__StackTop), /* Initial Stack Pointer */
|
||||
Reset_Handler, /* Reset Handler */
|
||||
NMI_Handler, /* NMI Handler */
|
||||
HardFault_Handler, /* Hard Fault Handler */
|
||||
MemManage_Handler, /* MPU Fault Handler */
|
||||
BusFault_Handler, /* Bus Fault Handler */
|
||||
UsageFault_Handler, /* Usage Fault Handler */
|
||||
0, /* Reserved */
|
||||
0, /* Reserved */
|
||||
0, /* Reserved */
|
||||
0, /* Reserved */
|
||||
SVC_Handler, /* SVCall Handler */
|
||||
DebugMon_Handler, /* Debug Monitor Handler */
|
||||
0, /* Reserved */
|
||||
PendSV_Handler, /* PendSV Handler */
|
||||
SysTick_Handler, /* SysTick Handler */
|
||||
|
||||
/* External interrupts */
|
||||
WDT_IRQHandler, /* 0: Watchdog Timer */
|
||||
RTC_IRQHandler, /* 1: Real Time Clock */
|
||||
TIM0_IRQHandler, /* 2: Timer0 / Timer1 */
|
||||
TIM2_IRQHandler, /* 3: Timer2 / Timer3 */
|
||||
MCIA_IRQHandler, /* 4: MCIa */
|
||||
MCIB_IRQHandler, /* 5: MCIb */
|
||||
UART0_IRQHandler, /* 6: UART0 - DUT FPGA */
|
||||
UART1_IRQHandler, /* 7: UART1 - DUT FPGA */
|
||||
UART2_IRQHandler, /* 8: UART2 - DUT FPGA */
|
||||
UART4_IRQHandler, /* 9: UART4 - not connected */
|
||||
AACI_IRQHandler, /* 10: AACI / AC97 */
|
||||
CLCD_IRQHandler, /* 11: CLCD Combined Interrupt */
|
||||
ENET_IRQHandler, /* 12: Ethernet */
|
||||
USBDC_IRQHandler, /* 13: USB Device */
|
||||
USBHC_IRQHandler, /* 14: USB Host Controller */
|
||||
CHLCD_IRQHandler, /* 15: Character LCD */
|
||||
FLEXRAY_IRQHandler, /* 16: Flexray */
|
||||
CAN_IRQHandler, /* 17: CAN */
|
||||
LIN_IRQHandler, /* 18: LIN */
|
||||
I2C_IRQHandler, /* 19: I2C ADC/DAC */
|
||||
0, /* 20: Reserved */
|
||||
0, /* 21: Reserved */
|
||||
0, /* 22: Reserved */
|
||||
0, /* 23: Reserved */
|
||||
0, /* 24: Reserved */
|
||||
0, /* 25: Reserved */
|
||||
0, /* 26: Reserved */
|
||||
0, /* 27: Reserved */
|
||||
CPU_CLCD_IRQHandler, /* 28: Reserved - CPU FPGA CLCD */
|
||||
0, /* 29: Reserved - CPU FPGA */
|
||||
UART3_IRQHandler, /* 30: UART3 - CPU FPGA */
|
||||
SPI_IRQHandler /* 31: SPI Touchscreen - CPU FPGA */
|
||||
};
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Reset Handler called on controller reset
|
||||
*----------------------------------------------------------------------------*/
|
||||
void Reset_Handler(void) {
|
||||
uint32_t *pSrc, *pDest;
|
||||
uint32_t *pTable __attribute__((unused));
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
pTable = &__copy_table_start__;
|
||||
|
||||
for (; pTable < &__copy_table_end__; pTable = pTable + 3) {
|
||||
pSrc = (uint32_t*)*(pTable + 0);
|
||||
pDest = (uint32_t*)*(pTable + 1);
|
||||
for (; pDest < (uint32_t*)(*(pTable + 1) + *(pTable + 2)) ; ) {
|
||||
*pDest++ = *pSrc++;
|
||||
}
|
||||
}
|
||||
#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.
|
||||
*/
|
||||
pSrc = &__etext;
|
||||
pDest = &__data_start__;
|
||||
|
||||
for ( ; pDest < &__data_end__ ; ) {
|
||||
*pDest++ = *pSrc++;
|
||||
}
|
||||
#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 __copy_table_start__ and __copy_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
|
||||
*/
|
||||
pTable = &__zero_table_start__;
|
||||
|
||||
for (; pTable < &__zero_table_end__; pTable = pTable + 2) {
|
||||
pDest = (uint32_t*)*(pTable + 0);
|
||||
for (; pDest < (uint32_t*)(*(pTable + 0) + *(pTable + 1)) ; ) {
|
||||
*pDest++ = 0;
|
||||
}
|
||||
}
|
||||
#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.
|
||||
*/
|
||||
pDest = &__bss_start__;
|
||||
|
||||
for ( ; pDest < &__bss_end__ ; ) {
|
||||
*pDest++ = 0UL;
|
||||
}
|
||||
#endif /* __STARTUP_CLEAR_BSS_MULTIPLE || __STARTUP_CLEAR_BSS */
|
||||
|
||||
#ifndef __NO_SYSTEM_INIT
|
||||
SystemInit();
|
||||
#endif
|
||||
|
||||
#ifndef __START
|
||||
#define __START _start
|
||||
#endif
|
||||
__START();
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Default Handler for Exceptions / Interrupts
|
||||
*----------------------------------------------------------------------------*/
|
||||
void Default_Handler(void) {
|
||||
|
||||
while(1);
|
||||
}
|
@ -0,0 +1,262 @@
|
||||
;/**************************************************************************//**
|
||||
; * @file startup_ARMCM7.s
|
||||
; * @brief CMSIS Core Device Startup File for
|
||||
; * ARMCM7 Device Series
|
||||
; * @version V5.00
|
||||
; * @date 02. March 2016
|
||||
; ******************************************************************************/
|
||||
;/*
|
||||
; * Copyright (c) 2009-2016 ARM Limited. All rights reserved.
|
||||
; *
|
||||
; * 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
|
||||
; *
|
||||
; * 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.
|
||||
; */
|
||||
|
||||
;/*
|
||||
;//-------- <<< Use Configuration Wizard in Context Menu >>> ------------------
|
||||
;*/
|
||||
|
||||
|
||||
; <h> Stack Configuration
|
||||
; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
|
||||
; </h>
|
||||
|
||||
Stack_Size EQU 0x00000400
|
||||
|
||||
AREA STACK, NOINIT, READWRITE, ALIGN=3
|
||||
Stack_Mem SPACE Stack_Size
|
||||
__initial_sp
|
||||
|
||||
|
||||
; <h> Heap Configuration
|
||||
; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
|
||||
; </h>
|
||||
|
||||
Heap_Size EQU 0x00080000
|
||||
|
||||
AREA HEAP, NOINIT, READWRITE, ALIGN=3
|
||||
__heap_base
|
||||
Heap_Mem SPACE Heap_Size
|
||||
__heap_limit
|
||||
|
||||
|
||||
PRESERVE8
|
||||
THUMB
|
||||
|
||||
|
||||
; Vector Table Mapped to Address 0 at Reset
|
||||
|
||||
AREA RESET, DATA, READONLY
|
||||
EXPORT __Vectors
|
||||
EXPORT __Vectors_End
|
||||
EXPORT __Vectors_Size
|
||||
|
||||
__Vectors DCD __initial_sp ; Top of Stack
|
||||
DCD Reset_Handler ; Reset Handler
|
||||
DCD NMI_Handler ; NMI Handler
|
||||
DCD HardFault_Handler ; Hard Fault Handler
|
||||
DCD MemManage_Handler ; MPU Fault Handler
|
||||
DCD BusFault_Handler ; Bus Fault Handler
|
||||
DCD UsageFault_Handler ; Usage Fault Handler
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD SVC_Handler ; SVCall Handler
|
||||
DCD DebugMon_Handler ; Debug Monitor Handler
|
||||
DCD 0 ; Reserved
|
||||
DCD PendSV_Handler ; PendSV Handler
|
||||
DCD SysTick_Handler ; SysTick Handler
|
||||
|
||||
; External Interrupts
|
||||
DCD WDT_IRQHandler ; 0: Watchdog Timer
|
||||
DCD RTC_IRQHandler ; 1: Real Time Clock
|
||||
DCD TIM0_IRQHandler ; 2: Timer0 / Timer1
|
||||
DCD TIM2_IRQHandler ; 3: Timer2 / Timer3
|
||||
DCD MCIA_IRQHandler ; 4: MCIa
|
||||
DCD MCIB_IRQHandler ; 5: MCIb
|
||||
DCD UART0_IRQHandler ; 6: UART0 - DUT FPGA
|
||||
DCD UART1_IRQHandler ; 7: UART1 - DUT FPGA
|
||||
DCD UART2_IRQHandler ; 8: UART2 - DUT FPGA
|
||||
DCD UART4_IRQHandler ; 9: UART4 - not connected
|
||||
DCD AACI_IRQHandler ; 10: AACI / AC97
|
||||
DCD CLCD_IRQHandler ; 11: CLCD Combined Interrupt
|
||||
DCD ENET_IRQHandler ; 12: Ethernet
|
||||
DCD USBDC_IRQHandler ; 13: USB Device
|
||||
DCD USBHC_IRQHandler ; 14: USB Host Controller
|
||||
DCD CHLCD_IRQHandler ; 15: Character LCD
|
||||
DCD FLEXRAY_IRQHandler ; 16: Flexray
|
||||
DCD CAN_IRQHandler ; 17: CAN
|
||||
DCD LIN_IRQHandler ; 18: LIN
|
||||
DCD I2C_IRQHandler ; 19: I2C ADC/DAC
|
||||
DCD 0 ; 20: Reserved
|
||||
DCD 0 ; 21: Reserved
|
||||
DCD 0 ; 22: Reserved
|
||||
DCD 0 ; 23: Reserved
|
||||
DCD 0 ; 24: Reserved
|
||||
DCD 0 ; 25: Reserved
|
||||
DCD 0 ; 26: Reserved
|
||||
DCD 0 ; 27: Reserved
|
||||
DCD CPU_CLCD_IRQHandler ; 28: Reserved - CPU FPGA CLCD
|
||||
DCD 0 ; 29: Reserved - CPU FPGA
|
||||
DCD UART3_IRQHandler ; 30: UART3 - CPU FPGA
|
||||
DCD SPI_IRQHandler ; 31: SPI Touchscreen - CPU FPGA
|
||||
__Vectors_End
|
||||
|
||||
__Vectors_Size EQU __Vectors_End - __Vectors
|
||||
|
||||
AREA |.text|, CODE, READONLY
|
||||
|
||||
|
||||
; Reset Handler
|
||||
|
||||
Reset_Handler PROC
|
||||
EXPORT Reset_Handler [WEAK]
|
||||
IMPORT SystemInit
|
||||
IMPORT __main
|
||||
LDR R0, =SystemInit
|
||||
BLX R0
|
||||
LDR R0, =__main
|
||||
BX R0
|
||||
ENDP
|
||||
|
||||
|
||||
; Dummy Exception Handlers (infinite loops which can be modified)
|
||||
|
||||
NMI_Handler PROC
|
||||
EXPORT NMI_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
HardFault_Handler\
|
||||
PROC
|
||||
EXPORT HardFault_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
MemManage_Handler\
|
||||
PROC
|
||||
EXPORT MemManage_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
BusFault_Handler\
|
||||
PROC
|
||||
EXPORT BusFault_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
UsageFault_Handler\
|
||||
PROC
|
||||
EXPORT UsageFault_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
SVC_Handler PROC
|
||||
EXPORT SVC_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
DebugMon_Handler\
|
||||
PROC
|
||||
EXPORT DebugMon_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
PendSV_Handler PROC
|
||||
EXPORT PendSV_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
SysTick_Handler PROC
|
||||
EXPORT SysTick_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
|
||||
Default_Handler PROC
|
||||
|
||||
EXPORT WDT_IRQHandler [WEAK]
|
||||
EXPORT RTC_IRQHandler [WEAK]
|
||||
EXPORT TIM0_IRQHandler [WEAK]
|
||||
EXPORT TIM2_IRQHandler [WEAK]
|
||||
EXPORT MCIA_IRQHandler [WEAK]
|
||||
EXPORT MCIB_IRQHandler [WEAK]
|
||||
EXPORT UART0_IRQHandler [WEAK]
|
||||
EXPORT UART1_IRQHandler [WEAK]
|
||||
EXPORT UART2_IRQHandler [WEAK]
|
||||
EXPORT UART3_IRQHandler [WEAK]
|
||||
EXPORT UART4_IRQHandler [WEAK]
|
||||
EXPORT AACI_IRQHandler [WEAK]
|
||||
EXPORT CLCD_IRQHandler [WEAK]
|
||||
EXPORT ENET_IRQHandler [WEAK]
|
||||
EXPORT USBDC_IRQHandler [WEAK]
|
||||
EXPORT USBHC_IRQHandler [WEAK]
|
||||
EXPORT CHLCD_IRQHandler [WEAK]
|
||||
EXPORT FLEXRAY_IRQHandler [WEAK]
|
||||
EXPORT CAN_IRQHandler [WEAK]
|
||||
EXPORT LIN_IRQHandler [WEAK]
|
||||
EXPORT I2C_IRQHandler [WEAK]
|
||||
EXPORT CPU_CLCD_IRQHandler [WEAK]
|
||||
EXPORT SPI_IRQHandler [WEAK]
|
||||
|
||||
WDT_IRQHandler
|
||||
RTC_IRQHandler
|
||||
TIM0_IRQHandler
|
||||
TIM2_IRQHandler
|
||||
MCIA_IRQHandler
|
||||
MCIB_IRQHandler
|
||||
UART0_IRQHandler
|
||||
UART1_IRQHandler
|
||||
UART2_IRQHandler
|
||||
UART3_IRQHandler
|
||||
UART4_IRQHandler
|
||||
AACI_IRQHandler
|
||||
CLCD_IRQHandler
|
||||
ENET_IRQHandler
|
||||
USBDC_IRQHandler
|
||||
USBHC_IRQHandler
|
||||
CHLCD_IRQHandler
|
||||
FLEXRAY_IRQHandler
|
||||
CAN_IRQHandler
|
||||
LIN_IRQHandler
|
||||
I2C_IRQHandler
|
||||
CPU_CLCD_IRQHandler
|
||||
SPI_IRQHandler
|
||||
B .
|
||||
|
||||
ENDP
|
||||
|
||||
|
||||
ALIGN
|
||||
|
||||
|
||||
; User Initial Stack & Heap
|
||||
|
||||
IF :DEF:__MICROLIB
|
||||
|
||||
EXPORT __initial_sp
|
||||
EXPORT __heap_base
|
||||
EXPORT __heap_limit
|
||||
|
||||
ELSE
|
||||
|
||||
IMPORT __use_two_region_memory
|
||||
EXPORT __user_initial_stackheap
|
||||
|
||||
__user_initial_stackheap PROC
|
||||
LDR R0, = Heap_Mem
|
||||
LDR R1, =(Stack_Mem + Stack_Size)
|
||||
LDR R2, = (Heap_Mem + Heap_Size)
|
||||
LDR R3, = Stack_Mem
|
||||
BX LR
|
||||
ENDP
|
||||
|
||||
ALIGN
|
||||
|
||||
ENDIF
|
||||
|
||||
|
||||
END
|
@ -0,0 +1,85 @@
|
||||
/**************************************************************************//**
|
||||
* @file system_ARMCM7.c
|
||||
* @brief CMSIS Device System Source File for
|
||||
* ARMCM7 Device Series
|
||||
* @version V5.00
|
||||
* @date 08. April 2016
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2016 ARM Limited. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if defined (ARMCM7)
|
||||
#include "ARMCM7.h"
|
||||
#elif defined (ARMCM7_SP)
|
||||
#include "ARMCM7_SP.h"
|
||||
#elif defined (ARMCM7_DP)
|
||||
#include "ARMCM7_DP.h"
|
||||
#else
|
||||
#error device not specified!
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Define clocks
|
||||
*----------------------------------------------------------------------------*/
|
||||
#define XTAL ( 5000000U) /* Oscillator frequency */
|
||||
|
||||
#define SYSTEM_CLOCK (5 * XTAL)
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
Externals
|
||||
*----------------------------------------------------------------------------*/
|
||||
#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1)
|
||||
extern uint32_t __Vectors;
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
System Core Clock Variable
|
||||
*----------------------------------------------------------------------------*/
|
||||
uint32_t SystemCoreClock = SYSTEM_CLOCK;
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
System Core Clock update function
|
||||
*----------------------------------------------------------------------------*/
|
||||
void SystemCoreClockUpdate (void)
|
||||
{
|
||||
SystemCoreClock = SYSTEM_CLOCK;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
System initialization function
|
||||
*----------------------------------------------------------------------------*/
|
||||
void SystemInit (void)
|
||||
{
|
||||
|
||||
#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1)
|
||||
SCB->VTOR = (uint32_t) &__Vectors;
|
||||
#endif
|
||||
|
||||
#if defined (__FPU_USED) && (__FPU_USED == 1)
|
||||
SCB->CPACR |= ((3U << 10*2) | /* set CP10 Full Access */
|
||||
(3U << 11*2) ); /* set CP11 Full Access */
|
||||
#endif
|
||||
|
||||
#ifdef UNALIGNED_SUPPORT_DISABLE
|
||||
SCB->CCR |= SCB_CCR_UNALIGN_TRP_Msk;
|
||||
#endif
|
||||
|
||||
SystemCoreClock = SYSTEM_CLOCK;
|
||||
}
|
@ -0,0 +1,395 @@
|
||||
;******************** (C) COPYRIGHT 2016 STMicroelectronics ********************
|
||||
;* File Name : startup_stm32f411xe.s
|
||||
;* Author : MCD Application Team
|
||||
;* Version : V2.6.0
|
||||
;* Date : 04-November-2016
|
||||
;* Description : STM32F411xExx devices vector table for MDK-ARM toolchain.
|
||||
;* This module performs:
|
||||
;* - Set the initial SP
|
||||
;* - Set the initial PC == Reset_Handler
|
||||
;* - Set the vector table entries with the exceptions ISR address
|
||||
;* - Branches to __main in the C library (which eventually
|
||||
;* calls main()).
|
||||
;* After Reset the CortexM4 processor is in Thread mode,
|
||||
;* priority is Privileged, and the Stack is set to Main.
|
||||
;* <<< Use Configuration Wizard in Context Menu >>>
|
||||
;*******************************************************************************
|
||||
;
|
||||
;* Redistribution and use in source and binary forms, with or without modification,
|
||||
;* are permitted provided that the following conditions are met:
|
||||
;* 1. Redistributions of source code must retain the above copyright notice,
|
||||
;* this list of conditions and the following disclaimer.
|
||||
;* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
;* this list of conditions and the following disclaimer in the documentation
|
||||
;* and/or other materials provided with the distribution.
|
||||
;* 3. Neither the name of STMicroelectronics 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 THE COPYRIGHT HOLDER 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.
|
||||
;
|
||||
;*******************************************************************************
|
||||
|
||||
; Amount of memory (in bytes) allocated for Stack
|
||||
; Tailor this value to your application needs
|
||||
; <h> Stack Configuration
|
||||
; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
|
||||
; </h>
|
||||
|
||||
Stack_Size EQU 0x00000400
|
||||
|
||||
AREA STACK, NOINIT, READWRITE, ALIGN=3
|
||||
Stack_Mem SPACE Stack_Size
|
||||
__initial_sp
|
||||
|
||||
|
||||
; <h> Heap Configuration
|
||||
; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
|
||||
; </h>
|
||||
|
||||
Heap_Size EQU 0x00000200
|
||||
|
||||
AREA HEAP, NOINIT, READWRITE, ALIGN=3
|
||||
__heap_base
|
||||
Heap_Mem SPACE Heap_Size
|
||||
__heap_limit
|
||||
|
||||
PRESERVE8
|
||||
THUMB
|
||||
|
||||
|
||||
; Vector Table Mapped to Address 0 at Reset
|
||||
AREA RESET, DATA, READONLY
|
||||
EXPORT __Vectors
|
||||
EXPORT __Vectors_End
|
||||
EXPORT __Vectors_Size
|
||||
|
||||
__Vectors DCD __initial_sp ; Top of Stack
|
||||
DCD Reset_Handler ; Reset Handler
|
||||
DCD NMI_Handler ; NMI Handler
|
||||
DCD HardFault_Handler ; Hard Fault Handler
|
||||
DCD MemManage_Handler ; MPU Fault Handler
|
||||
DCD BusFault_Handler ; Bus Fault Handler
|
||||
DCD UsageFault_Handler ; Usage Fault Handler
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD SVC_Handler ; SVCall Handler
|
||||
DCD DebugMon_Handler ; Debug Monitor Handler
|
||||
DCD 0 ; Reserved
|
||||
DCD PendSV_Handler ; PendSV Handler
|
||||
DCD SysTick_Handler ; SysTick Handler
|
||||
|
||||
; External Interrupts
|
||||
DCD WWDG_IRQHandler ; Window WatchDog
|
||||
DCD PVD_IRQHandler ; PVD through EXTI Line detection
|
||||
DCD TAMP_STAMP_IRQHandler ; Tamper and TimeStamps through the EXTI line
|
||||
DCD RTC_WKUP_IRQHandler ; RTC Wakeup through the EXTI line
|
||||
DCD FLASH_IRQHandler ; FLASH
|
||||
DCD RCC_IRQHandler ; RCC
|
||||
DCD EXTI0_IRQHandler ; EXTI Line0
|
||||
DCD EXTI1_IRQHandler ; EXTI Line1
|
||||
DCD EXTI2_IRQHandler ; EXTI Line2
|
||||
DCD EXTI3_IRQHandler ; EXTI Line3
|
||||
DCD EXTI4_IRQHandler ; EXTI Line4
|
||||
DCD DMA1_Stream0_IRQHandler ; DMA1 Stream 0
|
||||
DCD DMA1_Stream1_IRQHandler ; DMA1 Stream 1
|
||||
DCD DMA1_Stream2_IRQHandler ; DMA1 Stream 2
|
||||
DCD DMA1_Stream3_IRQHandler ; DMA1 Stream 3
|
||||
DCD DMA1_Stream4_IRQHandler ; DMA1 Stream 4
|
||||
DCD DMA1_Stream5_IRQHandler ; DMA1 Stream 5
|
||||
DCD DMA1_Stream6_IRQHandler ; DMA1 Stream 6
|
||||
DCD ADC_IRQHandler ; ADC1, ADC2 and ADC3s
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD EXTI9_5_IRQHandler ; External Line[9:5]s
|
||||
DCD TIM1_BRK_TIM9_IRQHandler ; TIM1 Break and TIM9
|
||||
DCD TIM1_UP_TIM10_IRQHandler ; TIM1 Update and TIM10
|
||||
DCD TIM1_TRG_COM_TIM11_IRQHandler ; TIM1 Trigger and Commutation and TIM11
|
||||
DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare
|
||||
DCD TIM2_IRQHandler ; TIM2
|
||||
DCD TIM3_IRQHandler ; TIM3
|
||||
DCD TIM4_IRQHandler ; TIM4
|
||||
DCD I2C1_EV_IRQHandler ; I2C1 Event
|
||||
DCD I2C1_ER_IRQHandler ; I2C1 Error
|
||||
DCD I2C2_EV_IRQHandler ; I2C2 Event
|
||||
DCD I2C2_ER_IRQHandler ; I2C2 Error
|
||||
DCD SPI1_IRQHandler ; SPI1
|
||||
DCD SPI2_IRQHandler ; SPI2
|
||||
DCD USART1_IRQHandler ; USART1
|
||||
DCD USART2_IRQHandler ; USART2
|
||||
DCD 0 ; Reserved
|
||||
DCD EXTI15_10_IRQHandler ; External Line[15:10]s
|
||||
DCD RTC_Alarm_IRQHandler ; RTC Alarm (A and B) through EXTI Line
|
||||
DCD OTG_FS_WKUP_IRQHandler ; USB OTG FS Wakeup through EXTI line
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD DMA1_Stream7_IRQHandler ; DMA1 Stream7
|
||||
DCD 0 ; Reserved
|
||||
DCD SDIO_IRQHandler ; SDIO
|
||||
DCD TIM5_IRQHandler ; TIM5
|
||||
DCD SPI3_IRQHandler ; SPI3
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD DMA2_Stream0_IRQHandler ; DMA2 Stream 0
|
||||
DCD DMA2_Stream1_IRQHandler ; DMA2 Stream 1
|
||||
DCD DMA2_Stream2_IRQHandler ; DMA2 Stream 2
|
||||
DCD DMA2_Stream3_IRQHandler ; DMA2 Stream 3
|
||||
DCD DMA2_Stream4_IRQHandler ; DMA2 Stream 4
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD OTG_FS_IRQHandler ; USB OTG FS
|
||||
DCD DMA2_Stream5_IRQHandler ; DMA2 Stream 5
|
||||
DCD DMA2_Stream6_IRQHandler ; DMA2 Stream 6
|
||||
DCD DMA2_Stream7_IRQHandler ; DMA2 Stream 7
|
||||
DCD USART6_IRQHandler ; USART6
|
||||
DCD I2C3_EV_IRQHandler ; I2C3 event
|
||||
DCD I2C3_ER_IRQHandler ; I2C3 error
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD FPU_IRQHandler ; FPU
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD SPI4_IRQHandler ; SPI4
|
||||
DCD SPI5_IRQHandler ; SPI5
|
||||
|
||||
__Vectors_End
|
||||
|
||||
__Vectors_Size EQU __Vectors_End - __Vectors
|
||||
|
||||
AREA |.text|, CODE, READONLY
|
||||
|
||||
; Reset handler
|
||||
Reset_Handler PROC
|
||||
EXPORT Reset_Handler [WEAK]
|
||||
IMPORT SystemInit
|
||||
IMPORT __main
|
||||
|
||||
LDR R0, =SystemInit
|
||||
BLX R0
|
||||
LDR R0, =__main
|
||||
BX R0
|
||||
ENDP
|
||||
|
||||
; Dummy Exception Handlers (infinite loops which can be modified)
|
||||
|
||||
NMI_Handler PROC
|
||||
EXPORT NMI_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
HardFault_Handler\
|
||||
PROC
|
||||
EXPORT HardFault_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
MemManage_Handler\
|
||||
PROC
|
||||
EXPORT MemManage_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
BusFault_Handler\
|
||||
PROC
|
||||
EXPORT BusFault_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
UsageFault_Handler\
|
||||
PROC
|
||||
EXPORT UsageFault_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
SVC_Handler PROC
|
||||
EXPORT SVC_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
DebugMon_Handler\
|
||||
PROC
|
||||
EXPORT DebugMon_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
PendSV_Handler PROC
|
||||
EXPORT PendSV_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
SysTick_Handler PROC
|
||||
EXPORT SysTick_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
|
||||
Default_Handler PROC
|
||||
|
||||
EXPORT WWDG_IRQHandler [WEAK]
|
||||
EXPORT PVD_IRQHandler [WEAK]
|
||||
EXPORT TAMP_STAMP_IRQHandler [WEAK]
|
||||
EXPORT RTC_WKUP_IRQHandler [WEAK]
|
||||
EXPORT FLASH_IRQHandler [WEAK]
|
||||
EXPORT RCC_IRQHandler [WEAK]
|
||||
EXPORT EXTI0_IRQHandler [WEAK]
|
||||
EXPORT EXTI1_IRQHandler [WEAK]
|
||||
EXPORT EXTI2_IRQHandler [WEAK]
|
||||
EXPORT EXTI3_IRQHandler [WEAK]
|
||||
EXPORT EXTI4_IRQHandler [WEAK]
|
||||
EXPORT DMA1_Stream0_IRQHandler [WEAK]
|
||||
EXPORT DMA1_Stream1_IRQHandler [WEAK]
|
||||
EXPORT DMA1_Stream2_IRQHandler [WEAK]
|
||||
EXPORT DMA1_Stream3_IRQHandler [WEAK]
|
||||
EXPORT DMA1_Stream4_IRQHandler [WEAK]
|
||||
EXPORT DMA1_Stream5_IRQHandler [WEAK]
|
||||
EXPORT DMA1_Stream6_IRQHandler [WEAK]
|
||||
EXPORT ADC_IRQHandler [WEAK]
|
||||
EXPORT EXTI9_5_IRQHandler [WEAK]
|
||||
EXPORT TIM1_BRK_TIM9_IRQHandler [WEAK]
|
||||
EXPORT TIM1_UP_TIM10_IRQHandler [WEAK]
|
||||
EXPORT TIM1_TRG_COM_TIM11_IRQHandler [WEAK]
|
||||
EXPORT TIM1_CC_IRQHandler [WEAK]
|
||||
EXPORT TIM2_IRQHandler [WEAK]
|
||||
EXPORT TIM3_IRQHandler [WEAK]
|
||||
EXPORT TIM4_IRQHandler [WEAK]
|
||||
EXPORT I2C1_EV_IRQHandler [WEAK]
|
||||
EXPORT I2C1_ER_IRQHandler [WEAK]
|
||||
EXPORT I2C2_EV_IRQHandler [WEAK]
|
||||
EXPORT I2C2_ER_IRQHandler [WEAK]
|
||||
EXPORT SPI1_IRQHandler [WEAK]
|
||||
EXPORT SPI2_IRQHandler [WEAK]
|
||||
EXPORT USART1_IRQHandler [WEAK]
|
||||
EXPORT USART2_IRQHandler [WEAK]
|
||||
EXPORT EXTI15_10_IRQHandler [WEAK]
|
||||
EXPORT RTC_Alarm_IRQHandler [WEAK]
|
||||
EXPORT OTG_FS_WKUP_IRQHandler [WEAK]
|
||||
EXPORT DMA1_Stream7_IRQHandler [WEAK]
|
||||
EXPORT SDIO_IRQHandler [WEAK]
|
||||
EXPORT TIM5_IRQHandler [WEAK]
|
||||
EXPORT SPI3_IRQHandler [WEAK]
|
||||
EXPORT DMA2_Stream0_IRQHandler [WEAK]
|
||||
EXPORT DMA2_Stream1_IRQHandler [WEAK]
|
||||
EXPORT DMA2_Stream2_IRQHandler [WEAK]
|
||||
EXPORT DMA2_Stream3_IRQHandler [WEAK]
|
||||
EXPORT DMA2_Stream4_IRQHandler [WEAK]
|
||||
EXPORT OTG_FS_IRQHandler [WEAK]
|
||||
EXPORT DMA2_Stream5_IRQHandler [WEAK]
|
||||
EXPORT DMA2_Stream6_IRQHandler [WEAK]
|
||||
EXPORT DMA2_Stream7_IRQHandler [WEAK]
|
||||
EXPORT USART6_IRQHandler [WEAK]
|
||||
EXPORT I2C3_EV_IRQHandler [WEAK]
|
||||
EXPORT I2C3_ER_IRQHandler [WEAK]
|
||||
EXPORT FPU_IRQHandler [WEAK]
|
||||
EXPORT SPI4_IRQHandler [WEAK]
|
||||
EXPORT SPI5_IRQHandler [WEAK]
|
||||
|
||||
WWDG_IRQHandler
|
||||
PVD_IRQHandler
|
||||
TAMP_STAMP_IRQHandler
|
||||
RTC_WKUP_IRQHandler
|
||||
FLASH_IRQHandler
|
||||
RCC_IRQHandler
|
||||
EXTI0_IRQHandler
|
||||
EXTI1_IRQHandler
|
||||
EXTI2_IRQHandler
|
||||
EXTI3_IRQHandler
|
||||
EXTI4_IRQHandler
|
||||
DMA1_Stream0_IRQHandler
|
||||
DMA1_Stream1_IRQHandler
|
||||
DMA1_Stream2_IRQHandler
|
||||
DMA1_Stream3_IRQHandler
|
||||
DMA1_Stream4_IRQHandler
|
||||
DMA1_Stream5_IRQHandler
|
||||
DMA1_Stream6_IRQHandler
|
||||
ADC_IRQHandler
|
||||
EXTI9_5_IRQHandler
|
||||
TIM1_BRK_TIM9_IRQHandler
|
||||
TIM1_UP_TIM10_IRQHandler
|
||||
TIM1_TRG_COM_TIM11_IRQHandler
|
||||
TIM1_CC_IRQHandler
|
||||
TIM2_IRQHandler
|
||||
TIM3_IRQHandler
|
||||
TIM4_IRQHandler
|
||||
I2C1_EV_IRQHandler
|
||||
I2C1_ER_IRQHandler
|
||||
I2C2_EV_IRQHandler
|
||||
I2C2_ER_IRQHandler
|
||||
SPI1_IRQHandler
|
||||
SPI2_IRQHandler
|
||||
USART1_IRQHandler
|
||||
USART2_IRQHandler
|
||||
EXTI15_10_IRQHandler
|
||||
RTC_Alarm_IRQHandler
|
||||
OTG_FS_WKUP_IRQHandler
|
||||
DMA1_Stream7_IRQHandler
|
||||
SDIO_IRQHandler
|
||||
TIM5_IRQHandler
|
||||
SPI3_IRQHandler
|
||||
DMA2_Stream0_IRQHandler
|
||||
DMA2_Stream1_IRQHandler
|
||||
DMA2_Stream2_IRQHandler
|
||||
DMA2_Stream3_IRQHandler
|
||||
DMA2_Stream4_IRQHandler
|
||||
OTG_FS_IRQHandler
|
||||
DMA2_Stream5_IRQHandler
|
||||
DMA2_Stream6_IRQHandler
|
||||
DMA2_Stream7_IRQHandler
|
||||
USART6_IRQHandler
|
||||
I2C3_EV_IRQHandler
|
||||
I2C3_ER_IRQHandler
|
||||
FPU_IRQHandler
|
||||
SPI4_IRQHandler
|
||||
SPI5_IRQHandler
|
||||
|
||||
B .
|
||||
|
||||
ENDP
|
||||
|
||||
ALIGN
|
||||
|
||||
;*******************************************************************************
|
||||
; User Stack and Heap initialization
|
||||
;*******************************************************************************
|
||||
IF :DEF:__MICROLIB
|
||||
|
||||
EXPORT __initial_sp
|
||||
EXPORT __heap_base
|
||||
EXPORT __heap_limit
|
||||
|
||||
ELSE
|
||||
|
||||
IMPORT __use_two_region_memory
|
||||
EXPORT __user_initial_stackheap
|
||||
|
||||
__user_initial_stackheap
|
||||
|
||||
LDR R0, = Heap_Mem
|
||||
LDR R1, =(Stack_Mem + Stack_Size)
|
||||
LDR R2, = (Heap_Mem + Heap_Size)
|
||||
LDR R3, = Stack_Mem
|
||||
BX LR
|
||||
|
||||
ALIGN
|
||||
|
||||
ENDIF
|
||||
|
||||
END
|
||||
|
||||
;************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE*****
|
@ -0,0 +1,763 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file system_stm32f4xx.c
|
||||
* @author MCD Application Team
|
||||
* @version V2.6.0
|
||||
* @date 04-November-2016
|
||||
* @brief CMSIS Cortex-M4 Device Peripheral Access Layer System Source File.
|
||||
*
|
||||
* This file provides two functions and one global variable to be called from
|
||||
* user application:
|
||||
* - SystemInit(): This function is called at startup just after reset and
|
||||
* before branch to main program. This call is made inside
|
||||
* the "startup_stm32f4xx.s" file.
|
||||
*
|
||||
* - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
|
||||
* by the user application to setup the SysTick
|
||||
* timer or configure other parameters.
|
||||
*
|
||||
* - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
|
||||
* be called whenever the core clock is changed
|
||||
* during program execution.
|
||||
*
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2016 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of STMicroelectronics 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 THE COPYRIGHT HOLDER 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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/** @addtogroup CMSIS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup stm32f4xx_system
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F4xx_System_Private_Includes
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
#include "stm32f4xx.h"
|
||||
|
||||
#if !defined (HSE_VALUE)
|
||||
#define HSE_VALUE ((uint32_t)25000000) /*!< Default value of the External oscillator in Hz */
|
||||
#endif /* HSE_VALUE */
|
||||
|
||||
#if !defined (HSI_VALUE)
|
||||
#define HSI_VALUE ((uint32_t)16000000) /*!< Value of the Internal oscillator in Hz*/
|
||||
#endif /* HSI_VALUE */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F4xx_System_Private_TypesDefinitions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F4xx_System_Private_Defines
|
||||
* @{
|
||||
*/
|
||||
|
||||
/************************* Miscellaneous Configuration ************************/
|
||||
/*!< Uncomment the following line if you need to use external SRAM or SDRAM as data memory */
|
||||
#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx)\
|
||||
|| defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\
|
||||
|| defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx)
|
||||
/* #define DATA_IN_ExtSRAM */
|
||||
#endif /* STM32F40xxx || STM32F41xxx || STM32F42xxx || STM32F43xxx || STM32F469xx || STM32F479xx ||\
|
||||
STM32F412Zx || STM32F412Vx */
|
||||
|
||||
#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\
|
||||
|| defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx)
|
||||
/* #define DATA_IN_ExtSDRAM */
|
||||
#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx || STM32F469xx ||\
|
||||
STM32F479xx */
|
||||
|
||||
/*!< Uncomment the following line if you need to relocate your vector Table in
|
||||
Internal SRAM. */
|
||||
/* #define VECT_TAB_SRAM */
|
||||
#define VECT_TAB_OFFSET 0x00 /*!< Vector Table base offset field.
|
||||
This value must be a multiple of 0x200. */
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F4xx_System_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F4xx_System_Private_Variables
|
||||
* @{
|
||||
*/
|
||||
/* This variable is updated in three ways:
|
||||
1) by calling CMSIS function SystemCoreClockUpdate()
|
||||
2) by calling HAL API function HAL_RCC_GetHCLKFreq()
|
||||
3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
|
||||
Note: If you use this function to configure the system clock; then there
|
||||
is no need to call the 2 first functions listed above, since SystemCoreClock
|
||||
variable is updated automatically.
|
||||
*/
|
||||
uint32_t SystemCoreClock = 16000000;
|
||||
const uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
|
||||
const uint8_t APBPrescTable[8] = {0, 0, 0, 0, 1, 2, 3, 4};
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F4xx_System_Private_FunctionPrototypes
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM)
|
||||
static void SystemInit_ExtMemCtl(void);
|
||||
#endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F4xx_System_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Setup the microcontroller system
|
||||
* Initialize the FPU setting, vector table location and External memory
|
||||
* configuration.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void SystemInit(void)
|
||||
{
|
||||
/* FPU settings ------------------------------------------------------------*/
|
||||
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
|
||||
SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */
|
||||
#endif
|
||||
/* Reset the RCC clock configuration to the default reset state ------------*/
|
||||
/* Set HSION bit */
|
||||
RCC->CR |= (uint32_t)0x00000001;
|
||||
|
||||
/* Reset CFGR register */
|
||||
RCC->CFGR = 0x00000000;
|
||||
|
||||
/* Reset HSEON, CSSON and PLLON bits */
|
||||
RCC->CR &= (uint32_t)0xFEF6FFFF;
|
||||
|
||||
/* Reset PLLCFGR register */
|
||||
RCC->PLLCFGR = 0x24003010;
|
||||
|
||||
/* Reset HSEBYP bit */
|
||||
RCC->CR &= (uint32_t)0xFFFBFFFF;
|
||||
|
||||
/* Disable all interrupts */
|
||||
RCC->CIR = 0x00000000;
|
||||
|
||||
#if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM)
|
||||
SystemInit_ExtMemCtl();
|
||||
#endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */
|
||||
|
||||
/* Configure the Vector Table location add offset address ------------------*/
|
||||
#ifdef VECT_TAB_SRAM
|
||||
SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
|
||||
#else
|
||||
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Update SystemCoreClock variable according to Clock Register Values.
|
||||
* The SystemCoreClock variable contains the core clock (HCLK), it can
|
||||
* be used by the user application to setup the SysTick timer or configure
|
||||
* other parameters.
|
||||
*
|
||||
* @note Each time the core clock (HCLK) changes, this function must be called
|
||||
* to update SystemCoreClock variable value. Otherwise, any configuration
|
||||
* based on this variable will be incorrect.
|
||||
*
|
||||
* @note - The system frequency computed by this function is not the real
|
||||
* frequency in the chip. It is calculated based on the predefined
|
||||
* constant and the selected clock source:
|
||||
*
|
||||
* - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*)
|
||||
*
|
||||
* - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**)
|
||||
*
|
||||
* - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**)
|
||||
* or HSI_VALUE(*) multiplied/divided by the PLL factors.
|
||||
*
|
||||
* (*) HSI_VALUE is a constant defined in stm32f4xx_hal_conf.h file (default value
|
||||
* 16 MHz) but the real value may vary depending on the variations
|
||||
* in voltage and temperature.
|
||||
*
|
||||
* (**) HSE_VALUE is a constant defined in stm32f4xx_hal_conf.h file (its value
|
||||
* depends on the application requirements), user has to ensure that HSE_VALUE
|
||||
* is same as the real frequency of the crystal used. Otherwise, this function
|
||||
* may have wrong result.
|
||||
*
|
||||
* - The result of this function could be not correct when using fractional
|
||||
* value for HSE crystal.
|
||||
*
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void SystemCoreClockUpdate(void)
|
||||
{
|
||||
uint32_t tmp = 0, pllvco = 0, pllp = 2, pllsource = 0, pllm = 2;
|
||||
|
||||
/* Get SYSCLK source -------------------------------------------------------*/
|
||||
tmp = RCC->CFGR & RCC_CFGR_SWS;
|
||||
|
||||
switch (tmp)
|
||||
{
|
||||
case 0x00: /* HSI used as system clock source */
|
||||
SystemCoreClock = HSI_VALUE;
|
||||
break;
|
||||
case 0x04: /* HSE used as system clock source */
|
||||
SystemCoreClock = HSE_VALUE;
|
||||
break;
|
||||
case 0x08: /* PLL used as system clock source */
|
||||
|
||||
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N
|
||||
SYSCLK = PLL_VCO / PLL_P
|
||||
*/
|
||||
pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) >> 22;
|
||||
pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM;
|
||||
|
||||
if (pllsource != 0)
|
||||
{
|
||||
/* HSE used as PLL clock source */
|
||||
pllvco = (HSE_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* HSI used as PLL clock source */
|
||||
pllvco = (HSI_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6);
|
||||
}
|
||||
|
||||
pllp = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) >>16) + 1 ) *2;
|
||||
SystemCoreClock = pllvco/pllp;
|
||||
break;
|
||||
default:
|
||||
SystemCoreClock = HSI_VALUE;
|
||||
break;
|
||||
}
|
||||
/* Compute HCLK frequency --------------------------------------------------*/
|
||||
/* Get HCLK prescaler */
|
||||
tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)];
|
||||
/* HCLK frequency */
|
||||
SystemCoreClock >>= tmp;
|
||||
}
|
||||
|
||||
#if defined (DATA_IN_ExtSRAM) && defined (DATA_IN_ExtSDRAM)
|
||||
#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\
|
||||
|| defined(STM32F469xx) || defined(STM32F479xx)
|
||||
/**
|
||||
* @brief Setup the external memory controller.
|
||||
* Called in startup_stm32f4xx.s before jump to main.
|
||||
* This function configures the external memories (SRAM/SDRAM)
|
||||
* This SRAM/SDRAM will be used as program data memory (including heap and stack).
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void SystemInit_ExtMemCtl(void)
|
||||
{
|
||||
__IO uint32_t tmp = 0x00;
|
||||
|
||||
register uint32_t tmpreg = 0, timeout = 0xFFFF;
|
||||
register __IO uint32_t index;
|
||||
|
||||
/* Enable GPIOC, GPIOD, GPIOE, GPIOF, GPIOG, GPIOH and GPIOI interface clock */
|
||||
RCC->AHB1ENR |= 0x000001F8;
|
||||
|
||||
/* Delay after an RCC peripheral clock enabling */
|
||||
tmp = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOCEN);
|
||||
|
||||
/* Connect PDx pins to FMC Alternate function */
|
||||
GPIOD->AFR[0] = 0x00CCC0CC;
|
||||
GPIOD->AFR[1] = 0xCCCCCCCC;
|
||||
/* Configure PDx pins in Alternate function mode */
|
||||
GPIOD->MODER = 0xAAAA0A8A;
|
||||
/* Configure PDx pins speed to 100 MHz */
|
||||
GPIOD->OSPEEDR = 0xFFFF0FCF;
|
||||
/* Configure PDx pins Output type to push-pull */
|
||||
GPIOD->OTYPER = 0x00000000;
|
||||
/* No pull-up, pull-down for PDx pins */
|
||||
GPIOD->PUPDR = 0x00000000;
|
||||
|
||||
/* Connect PEx pins to FMC Alternate function */
|
||||
GPIOE->AFR[0] = 0xC00CC0CC;
|
||||
GPIOE->AFR[1] = 0xCCCCCCCC;
|
||||
/* Configure PEx pins in Alternate function mode */
|
||||
GPIOE->MODER = 0xAAAA828A;
|
||||
/* Configure PEx pins speed to 100 MHz */
|
||||
GPIOE->OSPEEDR = 0xFFFFC3CF;
|
||||
/* Configure PEx pins Output type to push-pull */
|
||||
GPIOE->OTYPER = 0x00000000;
|
||||
/* No pull-up, pull-down for PEx pins */
|
||||
GPIOE->PUPDR = 0x00000000;
|
||||
|
||||
/* Connect PFx pins to FMC Alternate function */
|
||||
GPIOF->AFR[0] = 0xCCCCCCCC;
|
||||
GPIOF->AFR[1] = 0xCCCCCCCC;
|
||||
/* Configure PFx pins in Alternate function mode */
|
||||
GPIOF->MODER = 0xAA800AAA;
|
||||
/* Configure PFx pins speed to 50 MHz */
|
||||
GPIOF->OSPEEDR = 0xAA800AAA;
|
||||
/* Configure PFx pins Output type to push-pull */
|
||||
GPIOF->OTYPER = 0x00000000;
|
||||
/* No pull-up, pull-down for PFx pins */
|
||||
GPIOF->PUPDR = 0x00000000;
|
||||
|
||||
/* Connect PGx pins to FMC Alternate function */
|
||||
GPIOG->AFR[0] = 0xCCCCCCCC;
|
||||
GPIOG->AFR[1] = 0xCCCCCCCC;
|
||||
/* Configure PGx pins in Alternate function mode */
|
||||
GPIOG->MODER = 0xAAAAAAAA;
|
||||
/* Configure PGx pins speed to 50 MHz */
|
||||
GPIOG->OSPEEDR = 0xAAAAAAAA;
|
||||
/* Configure PGx pins Output type to push-pull */
|
||||
GPIOG->OTYPER = 0x00000000;
|
||||
/* No pull-up, pull-down for PGx pins */
|
||||
GPIOG->PUPDR = 0x00000000;
|
||||
|
||||
/* Connect PHx pins to FMC Alternate function */
|
||||
GPIOH->AFR[0] = 0x00C0CC00;
|
||||
GPIOH->AFR[1] = 0xCCCCCCCC;
|
||||
/* Configure PHx pins in Alternate function mode */
|
||||
GPIOH->MODER = 0xAAAA08A0;
|
||||
/* Configure PHx pins speed to 50 MHz */
|
||||
GPIOH->OSPEEDR = 0xAAAA08A0;
|
||||
/* Configure PHx pins Output type to push-pull */
|
||||
GPIOH->OTYPER = 0x00000000;
|
||||
/* No pull-up, pull-down for PHx pins */
|
||||
GPIOH->PUPDR = 0x00000000;
|
||||
|
||||
/* Connect PIx pins to FMC Alternate function */
|
||||
GPIOI->AFR[0] = 0xCCCCCCCC;
|
||||
GPIOI->AFR[1] = 0x00000CC0;
|
||||
/* Configure PIx pins in Alternate function mode */
|
||||
GPIOI->MODER = 0x0028AAAA;
|
||||
/* Configure PIx pins speed to 50 MHz */
|
||||
GPIOI->OSPEEDR = 0x0028AAAA;
|
||||
/* Configure PIx pins Output type to push-pull */
|
||||
GPIOI->OTYPER = 0x00000000;
|
||||
/* No pull-up, pull-down for PIx pins */
|
||||
GPIOI->PUPDR = 0x00000000;
|
||||
|
||||
/*-- FMC Configuration -------------------------------------------------------*/
|
||||
/* Enable the FMC interface clock */
|
||||
RCC->AHB3ENR |= 0x00000001;
|
||||
/* Delay after an RCC peripheral clock enabling */
|
||||
tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN);
|
||||
|
||||
FMC_Bank5_6->SDCR[0] = 0x000019E4;
|
||||
FMC_Bank5_6->SDTR[0] = 0x01115351;
|
||||
|
||||
/* SDRAM initialization sequence */
|
||||
/* Clock enable command */
|
||||
FMC_Bank5_6->SDCMR = 0x00000011;
|
||||
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
|
||||
while((tmpreg != 0) && (timeout-- > 0))
|
||||
{
|
||||
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
|
||||
}
|
||||
|
||||
/* Delay */
|
||||
for (index = 0; index<1000; index++);
|
||||
|
||||
/* PALL command */
|
||||
FMC_Bank5_6->SDCMR = 0x00000012;
|
||||
timeout = 0xFFFF;
|
||||
while((tmpreg != 0) && (timeout-- > 0))
|
||||
{
|
||||
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
|
||||
}
|
||||
|
||||
/* Auto refresh command */
|
||||
FMC_Bank5_6->SDCMR = 0x00000073;
|
||||
timeout = 0xFFFF;
|
||||
while((tmpreg != 0) && (timeout-- > 0))
|
||||
{
|
||||
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
|
||||
}
|
||||
|
||||
/* MRD register program */
|
||||
FMC_Bank5_6->SDCMR = 0x00046014;
|
||||
timeout = 0xFFFF;
|
||||
while((tmpreg != 0) && (timeout-- > 0))
|
||||
{
|
||||
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
|
||||
}
|
||||
|
||||
/* Set refresh count */
|
||||
tmpreg = FMC_Bank5_6->SDRTR;
|
||||
FMC_Bank5_6->SDRTR = (tmpreg | (0x0000027C<<1));
|
||||
|
||||
/* Disable write protection */
|
||||
tmpreg = FMC_Bank5_6->SDCR[0];
|
||||
FMC_Bank5_6->SDCR[0] = (tmpreg & 0xFFFFFDFF);
|
||||
|
||||
#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)
|
||||
/* Configure and enable Bank1_SRAM2 */
|
||||
FMC_Bank1->BTCR[2] = 0x00001011;
|
||||
FMC_Bank1->BTCR[3] = 0x00000201;
|
||||
FMC_Bank1E->BWTR[2] = 0x0fffffff;
|
||||
#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */
|
||||
#if defined(STM32F469xx) || defined(STM32F479xx)
|
||||
/* Configure and enable Bank1_SRAM2 */
|
||||
FMC_Bank1->BTCR[2] = 0x00001091;
|
||||
FMC_Bank1->BTCR[3] = 0x00110212;
|
||||
FMC_Bank1E->BWTR[2] = 0x0fffffff;
|
||||
#endif /* STM32F469xx || STM32F479xx */
|
||||
|
||||
(void)(tmp);
|
||||
}
|
||||
#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F469xx || STM32F479xx */
|
||||
#elif defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM)
|
||||
/**
|
||||
* @brief Setup the external memory controller.
|
||||
* Called in startup_stm32f4xx.s before jump to main.
|
||||
* This function configures the external memories (SRAM/SDRAM)
|
||||
* This SRAM/SDRAM will be used as program data memory (including heap and stack).
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void SystemInit_ExtMemCtl(void)
|
||||
{
|
||||
__IO uint32_t tmp = 0x00;
|
||||
#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\
|
||||
|| defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx)
|
||||
#if defined (DATA_IN_ExtSDRAM)
|
||||
register uint32_t tmpreg = 0, timeout = 0xFFFF;
|
||||
register __IO uint32_t index;
|
||||
|
||||
#if defined(STM32F446xx)
|
||||
/* Enable GPIOA, GPIOC, GPIOD, GPIOE, GPIOF, GPIOG interface
|
||||
clock */
|
||||
RCC->AHB1ENR |= 0x0000007D;
|
||||
#else
|
||||
/* Enable GPIOC, GPIOD, GPIOE, GPIOF, GPIOG, GPIOH and GPIOI interface
|
||||
clock */
|
||||
RCC->AHB1ENR |= 0x000001F8;
|
||||
#endif /* STM32F446xx */
|
||||
/* Delay after an RCC peripheral clock enabling */
|
||||
tmp = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOCEN);
|
||||
|
||||
#if defined(STM32F446xx)
|
||||
/* Connect PAx pins to FMC Alternate function */
|
||||
GPIOA->AFR[0] |= 0xC0000000;
|
||||
GPIOA->AFR[1] |= 0x00000000;
|
||||
/* Configure PDx pins in Alternate function mode */
|
||||
GPIOA->MODER |= 0x00008000;
|
||||
/* Configure PDx pins speed to 50 MHz */
|
||||
GPIOA->OSPEEDR |= 0x00008000;
|
||||
/* Configure PDx pins Output type to push-pull */
|
||||
GPIOA->OTYPER |= 0x00000000;
|
||||
/* No pull-up, pull-down for PDx pins */
|
||||
GPIOA->PUPDR |= 0x00000000;
|
||||
|
||||
/* Connect PCx pins to FMC Alternate function */
|
||||
GPIOC->AFR[0] |= 0x00CC0000;
|
||||
GPIOC->AFR[1] |= 0x00000000;
|
||||
/* Configure PDx pins in Alternate function mode */
|
||||
GPIOC->MODER |= 0x00000A00;
|
||||
/* Configure PDx pins speed to 50 MHz */
|
||||
GPIOC->OSPEEDR |= 0x00000A00;
|
||||
/* Configure PDx pins Output type to push-pull */
|
||||
GPIOC->OTYPER |= 0x00000000;
|
||||
/* No pull-up, pull-down for PDx pins */
|
||||
GPIOC->PUPDR |= 0x00000000;
|
||||
#endif /* STM32F446xx */
|
||||
|
||||
/* Connect PDx pins to FMC Alternate function */
|
||||
GPIOD->AFR[0] = 0x000000CC;
|
||||
GPIOD->AFR[1] = 0xCC000CCC;
|
||||
/* Configure PDx pins in Alternate function mode */
|
||||
GPIOD->MODER = 0xA02A000A;
|
||||
/* Configure PDx pins speed to 50 MHz */
|
||||
GPIOD->OSPEEDR = 0xA02A000A;
|
||||
/* Configure PDx pins Output type to push-pull */
|
||||
GPIOD->OTYPER = 0x00000000;
|
||||
/* No pull-up, pull-down for PDx pins */
|
||||
GPIOD->PUPDR = 0x00000000;
|
||||
|
||||
/* Connect PEx pins to FMC Alternate function */
|
||||
GPIOE->AFR[0] = 0xC00000CC;
|
||||
GPIOE->AFR[1] = 0xCCCCCCCC;
|
||||
/* Configure PEx pins in Alternate function mode */
|
||||
GPIOE->MODER = 0xAAAA800A;
|
||||
/* Configure PEx pins speed to 50 MHz */
|
||||
GPIOE->OSPEEDR = 0xAAAA800A;
|
||||
/* Configure PEx pins Output type to push-pull */
|
||||
GPIOE->OTYPER = 0x00000000;
|
||||
/* No pull-up, pull-down for PEx pins */
|
||||
GPIOE->PUPDR = 0x00000000;
|
||||
|
||||
/* Connect PFx pins to FMC Alternate function */
|
||||
GPIOF->AFR[0] = 0xCCCCCCCC;
|
||||
GPIOF->AFR[1] = 0xCCCCCCCC;
|
||||
/* Configure PFx pins in Alternate function mode */
|
||||
GPIOF->MODER = 0xAA800AAA;
|
||||
/* Configure PFx pins speed to 50 MHz */
|
||||
GPIOF->OSPEEDR = 0xAA800AAA;
|
||||
/* Configure PFx pins Output type to push-pull */
|
||||
GPIOF->OTYPER = 0x00000000;
|
||||
/* No pull-up, pull-down for PFx pins */
|
||||
GPIOF->PUPDR = 0x00000000;
|
||||
|
||||
/* Connect PGx pins to FMC Alternate function */
|
||||
GPIOG->AFR[0] = 0xCCCCCCCC;
|
||||
GPIOG->AFR[1] = 0xCCCCCCCC;
|
||||
/* Configure PGx pins in Alternate function mode */
|
||||
GPIOG->MODER = 0xAAAAAAAA;
|
||||
/* Configure PGx pins speed to 50 MHz */
|
||||
GPIOG->OSPEEDR = 0xAAAAAAAA;
|
||||
/* Configure PGx pins Output type to push-pull */
|
||||
GPIOG->OTYPER = 0x00000000;
|
||||
/* No pull-up, pull-down for PGx pins */
|
||||
GPIOG->PUPDR = 0x00000000;
|
||||
|
||||
#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\
|
||||
|| defined(STM32F469xx) || defined(STM32F479xx)
|
||||
/* Connect PHx pins to FMC Alternate function */
|
||||
GPIOH->AFR[0] = 0x00C0CC00;
|
||||
GPIOH->AFR[1] = 0xCCCCCCCC;
|
||||
/* Configure PHx pins in Alternate function mode */
|
||||
GPIOH->MODER = 0xAAAA08A0;
|
||||
/* Configure PHx pins speed to 50 MHz */
|
||||
GPIOH->OSPEEDR = 0xAAAA08A0;
|
||||
/* Configure PHx pins Output type to push-pull */
|
||||
GPIOH->OTYPER = 0x00000000;
|
||||
/* No pull-up, pull-down for PHx pins */
|
||||
GPIOH->PUPDR = 0x00000000;
|
||||
|
||||
/* Connect PIx pins to FMC Alternate function */
|
||||
GPIOI->AFR[0] = 0xCCCCCCCC;
|
||||
GPIOI->AFR[1] = 0x00000CC0;
|
||||
/* Configure PIx pins in Alternate function mode */
|
||||
GPIOI->MODER = 0x0028AAAA;
|
||||
/* Configure PIx pins speed to 50 MHz */
|
||||
GPIOI->OSPEEDR = 0x0028AAAA;
|
||||
/* Configure PIx pins Output type to push-pull */
|
||||
GPIOI->OTYPER = 0x00000000;
|
||||
/* No pull-up, pull-down for PIx pins */
|
||||
GPIOI->PUPDR = 0x00000000;
|
||||
#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F469xx || STM32F479xx */
|
||||
|
||||
/*-- FMC Configuration -------------------------------------------------------*/
|
||||
/* Enable the FMC interface clock */
|
||||
RCC->AHB3ENR |= 0x00000001;
|
||||
/* Delay after an RCC peripheral clock enabling */
|
||||
tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN);
|
||||
|
||||
/* Configure and enable SDRAM bank1 */
|
||||
#if defined(STM32F446xx)
|
||||
FMC_Bank5_6->SDCR[0] = 0x00001954;
|
||||
#else
|
||||
FMC_Bank5_6->SDCR[0] = 0x000019E4;
|
||||
#endif /* STM32F446xx */
|
||||
FMC_Bank5_6->SDTR[0] = 0x01115351;
|
||||
|
||||
/* SDRAM initialization sequence */
|
||||
/* Clock enable command */
|
||||
FMC_Bank5_6->SDCMR = 0x00000011;
|
||||
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
|
||||
while((tmpreg != 0) && (timeout-- > 0))
|
||||
{
|
||||
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
|
||||
}
|
||||
|
||||
/* Delay */
|
||||
for (index = 0; index<1000; index++);
|
||||
|
||||
/* PALL command */
|
||||
FMC_Bank5_6->SDCMR = 0x00000012;
|
||||
timeout = 0xFFFF;
|
||||
while((tmpreg != 0) && (timeout-- > 0))
|
||||
{
|
||||
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
|
||||
}
|
||||
|
||||
/* Auto refresh command */
|
||||
#if defined(STM32F446xx)
|
||||
FMC_Bank5_6->SDCMR = 0x000000F3;
|
||||
#else
|
||||
FMC_Bank5_6->SDCMR = 0x00000073;
|
||||
#endif /* STM32F446xx */
|
||||
timeout = 0xFFFF;
|
||||
while((tmpreg != 0) && (timeout-- > 0))
|
||||
{
|
||||
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
|
||||
}
|
||||
|
||||
/* MRD register program */
|
||||
#if defined(STM32F446xx)
|
||||
FMC_Bank5_6->SDCMR = 0x00044014;
|
||||
#else
|
||||
FMC_Bank5_6->SDCMR = 0x00046014;
|
||||
#endif /* STM32F446xx */
|
||||
timeout = 0xFFFF;
|
||||
while((tmpreg != 0) && (timeout-- > 0))
|
||||
{
|
||||
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
|
||||
}
|
||||
|
||||
/* Set refresh count */
|
||||
tmpreg = FMC_Bank5_6->SDRTR;
|
||||
#if defined(STM32F446xx)
|
||||
FMC_Bank5_6->SDRTR = (tmpreg | (0x0000050C<<1));
|
||||
#else
|
||||
FMC_Bank5_6->SDRTR = (tmpreg | (0x0000027C<<1));
|
||||
#endif /* STM32F446xx */
|
||||
|
||||
/* Disable write protection */
|
||||
tmpreg = FMC_Bank5_6->SDCR[0];
|
||||
FMC_Bank5_6->SDCR[0] = (tmpreg & 0xFFFFFDFF);
|
||||
#endif /* DATA_IN_ExtSDRAM */
|
||||
#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx || STM32F469xx || STM32F479xx */
|
||||
|
||||
#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx)\
|
||||
|| defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\
|
||||
|| defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx)
|
||||
|
||||
#if defined(DATA_IN_ExtSRAM)
|
||||
/*-- GPIOs Configuration -----------------------------------------------------*/
|
||||
/* Enable GPIOD, GPIOE, GPIOF and GPIOG interface clock */
|
||||
RCC->AHB1ENR |= 0x00000078;
|
||||
/* Delay after an RCC peripheral clock enabling */
|
||||
tmp = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIODEN);
|
||||
|
||||
/* Connect PDx pins to FMC Alternate function */
|
||||
GPIOD->AFR[0] = 0x00CCC0CC;
|
||||
GPIOD->AFR[1] = 0xCCCCCCCC;
|
||||
/* Configure PDx pins in Alternate function mode */
|
||||
GPIOD->MODER = 0xAAAA0A8A;
|
||||
/* Configure PDx pins speed to 100 MHz */
|
||||
GPIOD->OSPEEDR = 0xFFFF0FCF;
|
||||
/* Configure PDx pins Output type to push-pull */
|
||||
GPIOD->OTYPER = 0x00000000;
|
||||
/* No pull-up, pull-down for PDx pins */
|
||||
GPIOD->PUPDR = 0x00000000;
|
||||
|
||||
/* Connect PEx pins to FMC Alternate function */
|
||||
GPIOE->AFR[0] = 0xC00CC0CC;
|
||||
GPIOE->AFR[1] = 0xCCCCCCCC;
|
||||
/* Configure PEx pins in Alternate function mode */
|
||||
GPIOE->MODER = 0xAAAA828A;
|
||||
/* Configure PEx pins speed to 100 MHz */
|
||||
GPIOE->OSPEEDR = 0xFFFFC3CF;
|
||||
/* Configure PEx pins Output type to push-pull */
|
||||
GPIOE->OTYPER = 0x00000000;
|
||||
/* No pull-up, pull-down for PEx pins */
|
||||
GPIOE->PUPDR = 0x00000000;
|
||||
|
||||
/* Connect PFx pins to FMC Alternate function */
|
||||
GPIOF->AFR[0] = 0x00CCCCCC;
|
||||
GPIOF->AFR[1] = 0xCCCC0000;
|
||||
/* Configure PFx pins in Alternate function mode */
|
||||
GPIOF->MODER = 0xAA000AAA;
|
||||
/* Configure PFx pins speed to 100 MHz */
|
||||
GPIOF->OSPEEDR = 0xFF000FFF;
|
||||
/* Configure PFx pins Output type to push-pull */
|
||||
GPIOF->OTYPER = 0x00000000;
|
||||
/* No pull-up, pull-down for PFx pins */
|
||||
GPIOF->PUPDR = 0x00000000;
|
||||
|
||||
/* Connect PGx pins to FMC Alternate function */
|
||||
GPIOG->AFR[0] = 0x00CCCCCC;
|
||||
GPIOG->AFR[1] = 0x000000C0;
|
||||
/* Configure PGx pins in Alternate function mode */
|
||||
GPIOG->MODER = 0x00085AAA;
|
||||
/* Configure PGx pins speed to 100 MHz */
|
||||
GPIOG->OSPEEDR = 0x000CAFFF;
|
||||
/* Configure PGx pins Output type to push-pull */
|
||||
GPIOG->OTYPER = 0x00000000;
|
||||
/* No pull-up, pull-down for PGx pins */
|
||||
GPIOG->PUPDR = 0x00000000;
|
||||
|
||||
/*-- FMC/FSMC Configuration --------------------------------------------------*/
|
||||
/* Enable the FMC/FSMC interface clock */
|
||||
RCC->AHB3ENR |= 0x00000001;
|
||||
|
||||
#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)
|
||||
/* Delay after an RCC peripheral clock enabling */
|
||||
tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN);
|
||||
/* Configure and enable Bank1_SRAM2 */
|
||||
FMC_Bank1->BTCR[2] = 0x00001011;
|
||||
FMC_Bank1->BTCR[3] = 0x00000201;
|
||||
FMC_Bank1E->BWTR[2] = 0x0fffffff;
|
||||
#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */
|
||||
#if defined(STM32F469xx) || defined(STM32F479xx)
|
||||
/* Delay after an RCC peripheral clock enabling */
|
||||
tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN);
|
||||
/* Configure and enable Bank1_SRAM2 */
|
||||
FMC_Bank1->BTCR[2] = 0x00001091;
|
||||
FMC_Bank1->BTCR[3] = 0x00110212;
|
||||
FMC_Bank1E->BWTR[2] = 0x0fffffff;
|
||||
#endif /* STM32F469xx || STM32F479xx */
|
||||
#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx)|| defined(STM32F417xx)\
|
||||
|| defined(STM32F412Zx) || defined(STM32F412Vx)
|
||||
/* Delay after an RCC peripheral clock enabling */
|
||||
tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FSMCEN);
|
||||
/* Configure and enable Bank1_SRAM2 */
|
||||
FSMC_Bank1->BTCR[2] = 0x00001011;
|
||||
FSMC_Bank1->BTCR[3] = 0x00000201;
|
||||
FSMC_Bank1E->BWTR[2] = 0x0FFFFFFF;
|
||||
#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F412Zx || STM32F412Vx */
|
||||
|
||||
#endif /* DATA_IN_ExtSRAM */
|
||||
#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F427xx || STM32F437xx ||\
|
||||
STM32F429xx || STM32F439xx || STM32F469xx || STM32F479xx || STM32F412Zx || STM32F412Vx */
|
||||
(void)(tmp);
|
||||
}
|
||||
#endif /* DATA_IN_ExtSRAM && DATA_IN_ExtSDRAM */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
@ -0,0 +1,20 @@
|
||||
|
||||
/*
|
||||
* Auto generated Run-Time-Environment Component Configuration File
|
||||
* *** Do not modify ! ***
|
||||
*
|
||||
* Project: 'arm_nnexamples_cifar10'
|
||||
* Target: 'ARMCM0'
|
||||
*/
|
||||
|
||||
#ifndef RTE_COMPONENTS_H
|
||||
#define RTE_COMPONENTS_H
|
||||
|
||||
|
||||
/*
|
||||
* Define the Device Header File:
|
||||
*/
|
||||
#define CMSIS_device_header "ARMCM0.h"
|
||||
|
||||
|
||||
#endif /* RTE_COMPONENTS_H */
|
@ -0,0 +1,26 @@
|
||||
|
||||
/*
|
||||
* Auto generated Run-Time-Environment Component Configuration File
|
||||
* *** Do not modify ! ***
|
||||
*
|
||||
* Project: 'arm_nnexamples_nn_test'
|
||||
* Target: 'ARMCM3'
|
||||
*/
|
||||
|
||||
#ifndef RTE_COMPONENTS_H
|
||||
#define RTE_COMPONENTS_H
|
||||
|
||||
|
||||
/*
|
||||
* Define the Device Header File:
|
||||
*/
|
||||
#define CMSIS_device_header "ARMCM3.h"
|
||||
|
||||
#define RTE_Compiler_IO_STDERR /* Compiler I/O: STDERR */
|
||||
#define RTE_Compiler_IO_STDERR_ITM /* Compiler I/O: STDERR ITM */
|
||||
#define RTE_Compiler_IO_STDOUT /* Compiler I/O: STDOUT */
|
||||
#define RTE_Compiler_IO_STDOUT_ITM /* Compiler I/O: STDOUT ITM */
|
||||
#define RTE_Compiler_IO_TTY /* Compiler I/O: TTY */
|
||||
#define RTE_Compiler_IO_TTY_ITM /* Compiler I/O: TTY ITM */
|
||||
|
||||
#endif /* RTE_COMPONENTS_H */
|
@ -0,0 +1,26 @@
|
||||
|
||||
/*
|
||||
* Auto generated Run-Time-Environment Component Configuration File
|
||||
* *** Do not modify ! ***
|
||||
*
|
||||
* Project: 'arm_nnexamples_nn_test'
|
||||
* Target: 'ARMCM4_FP'
|
||||
*/
|
||||
|
||||
#ifndef RTE_COMPONENTS_H
|
||||
#define RTE_COMPONENTS_H
|
||||
|
||||
|
||||
/*
|
||||
* Define the Device Header File:
|
||||
*/
|
||||
#define CMSIS_device_header "ARMCM4_FP.h"
|
||||
|
||||
#define RTE_Compiler_IO_STDERR /* Compiler I/O: STDERR */
|
||||
#define RTE_Compiler_IO_STDERR_ITM /* Compiler I/O: STDERR ITM */
|
||||
#define RTE_Compiler_IO_STDOUT /* Compiler I/O: STDOUT */
|
||||
#define RTE_Compiler_IO_STDOUT_ITM /* Compiler I/O: STDOUT ITM */
|
||||
#define RTE_Compiler_IO_TTY /* Compiler I/O: TTY */
|
||||
#define RTE_Compiler_IO_TTY_ITM /* Compiler I/O: TTY ITM */
|
||||
|
||||
#endif /* RTE_COMPONENTS_H */
|
@ -0,0 +1,26 @@
|
||||
|
||||
/*
|
||||
* Auto generated Run-Time-Environment Component Configuration File
|
||||
* *** Do not modify ! ***
|
||||
*
|
||||
* Project: 'arm_nnexamples_nn_test'
|
||||
* Target: 'ARMCM7_SP'
|
||||
*/
|
||||
|
||||
#ifndef RTE_COMPONENTS_H
|
||||
#define RTE_COMPONENTS_H
|
||||
|
||||
|
||||
/*
|
||||
* Define the Device Header File:
|
||||
*/
|
||||
#define CMSIS_device_header "ARMCM7_SP.h"
|
||||
|
||||
#define RTE_Compiler_IO_STDERR /* Compiler I/O: STDERR */
|
||||
#define RTE_Compiler_IO_STDERR_ITM /* Compiler I/O: STDERR ITM */
|
||||
#define RTE_Compiler_IO_STDOUT /* Compiler I/O: STDOUT */
|
||||
#define RTE_Compiler_IO_STDOUT_ITM /* Compiler I/O: STDOUT ITM */
|
||||
#define RTE_Compiler_IO_TTY /* Compiler I/O: TTY */
|
||||
#define RTE_Compiler_IO_TTY_ITM /* Compiler I/O: TTY ITM */
|
||||
|
||||
#endif /* RTE_COMPONENTS_H */
|
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "ref_functions.h"
|
||||
|
||||
void arm_convolve_HWC_q15_ref(const q15_t * Im_in, // input image
|
||||
const uint16_t dim_im_in, // input image dimention
|
||||
const uint16_t ch_im_in, // number of input image channels
|
||||
const q15_t * wt, // kernel weights
|
||||
const uint16_t ch_im_out, // number of filters, i.e., output image channels
|
||||
const uint16_t dim_kernel, // filter kernel size
|
||||
const uint16_t padding, // padding sizes
|
||||
const uint16_t stride, // stride
|
||||
const q15_t * bias, // bias
|
||||
const uint16_t bias_shift, const uint16_t out_shift, q15_t * Im_out, // output image
|
||||
const uint16_t dim_im_out, // output image dimension
|
||||
q15_t * bufferA, //buffer space for input
|
||||
q7_t * bufferB //buffer space for output
|
||||
)
|
||||
{
|
||||
int i, j, k, l, m, n;
|
||||
int conv_out;
|
||||
int in_row, in_col;
|
||||
|
||||
for (i = 0; i < ch_im_out; i++)
|
||||
{
|
||||
for (j = 0; j < dim_im_out; j++)
|
||||
{
|
||||
for (k = 0; k < dim_im_out; k++)
|
||||
{
|
||||
#ifndef ARM_NN_TRUNCATE
|
||||
conv_out = (bias[i] << bias_shift) + (0x1 << (out_shift - 1));
|
||||
#else
|
||||
conv_out = bias[i] << bias_shift;
|
||||
#endif
|
||||
for (m = 0; m < dim_kernel; m++)
|
||||
{
|
||||
for (n = 0; n < dim_kernel; n++)
|
||||
{
|
||||
in_row = stride * j + m - padding;
|
||||
in_col = stride * k + n - padding;
|
||||
if (in_row >= 0 && in_col >= 0 && in_row < dim_im_in && in_col < dim_im_in)
|
||||
{
|
||||
for (l = 0; l < ch_im_in; l++)
|
||||
{
|
||||
conv_out += Im_in[(in_row * dim_im_in + in_col) * ch_im_in + l] *
|
||||
wt[i * ch_im_in * dim_kernel * dim_kernel + (m * dim_kernel + n) * ch_im_in + l];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Im_out[i + (j * dim_im_out + k) * ch_im_out] = (q15_t) __SSAT((conv_out >> out_shift), 16);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "ref_functions.h"
|
||||
|
||||
void
|
||||
arm_convolve_HWC_q15_nonsquare_ref(const q15_t * Im_in,
|
||||
const uint16_t dim_im_in_x,
|
||||
const uint16_t dim_im_in_y,
|
||||
const uint16_t ch_im_in,
|
||||
const q15_t * wt,
|
||||
const uint16_t ch_im_out,
|
||||
const uint16_t dim_kernel_x,
|
||||
const uint16_t dim_kernel_y,
|
||||
const uint16_t padding_x,
|
||||
const uint16_t padding_y,
|
||||
const uint16_t stride_x,
|
||||
const uint16_t stride_y,
|
||||
const q15_t * bias,
|
||||
const uint16_t bias_shift,
|
||||
const uint16_t out_shift,
|
||||
q15_t * Im_out,
|
||||
const uint16_t dim_im_out_x,
|
||||
const uint16_t dim_im_out_y,
|
||||
q15_t * bufferA,
|
||||
q7_t * bufferB)
|
||||
|
||||
{
|
||||
uint16_t i, j, k, l, m, n;
|
||||
int conv_out;
|
||||
signed char in_row, in_col;
|
||||
|
||||
for (i = 0; i < ch_im_out; i++)
|
||||
{
|
||||
for (j = 0; j < dim_im_out_y; j++)
|
||||
{
|
||||
for (k = 0; k < dim_im_out_x; k++)
|
||||
{
|
||||
#ifndef ARM_NN_TRUNCATE
|
||||
conv_out = (bias[i] << bias_shift) + (0x1 << (out_shift - 1));
|
||||
#else
|
||||
conv_out = bias[i] << bias_shift;
|
||||
#endif
|
||||
for (m = 0; m < dim_kernel_y; m++)
|
||||
{
|
||||
for (n = 0; n < dim_kernel_x; n++)
|
||||
{
|
||||
in_row = stride_y * j + m - padding_y;
|
||||
in_col = stride_x * k + n - padding_x;
|
||||
if (in_row >= 0 && in_col >= 0 && in_row < dim_im_in_y && in_col < dim_im_in_x)
|
||||
{
|
||||
for (l = 0; l < ch_im_in; l++)
|
||||
{
|
||||
conv_out +=
|
||||
Im_in[(in_row * dim_im_in_x + in_col) * ch_im_in +
|
||||
l] * wt[i * ch_im_in * dim_kernel_x * dim_kernel_y + (m * dim_kernel_x +
|
||||
n) * ch_im_in + l];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Im_out[i + (j * dim_im_out_x + k) * ch_im_out] = (q15_t) __SSAT((conv_out >> out_shift), 16);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "ref_functions.h"
|
||||
|
||||
void arm_convolve_HWC_q7_ref(const q7_t * Im_in, // input image
|
||||
const uint16_t dim_im_in, // input image dimention
|
||||
const uint16_t ch_im_in, // number of input image channels
|
||||
const q7_t * wt, // kernel weights
|
||||
const uint16_t ch_im_out, // number of filters, i.e., output image channels
|
||||
const uint16_t dim_kernel, // filter kernel size
|
||||
const uint16_t padding, // padding sizes
|
||||
const uint16_t stride, // stride
|
||||
const q7_t * bias, // bias
|
||||
const uint16_t bias_shift, const uint16_t out_shift, q7_t * Im_out, // output image
|
||||
const uint16_t dim_im_out, // output image dimension
|
||||
q15_t * bufferA, //buffer space for input
|
||||
q7_t * bufferB //buffer space for output
|
||||
)
|
||||
{
|
||||
int i, j, k, l, m, n;
|
||||
int conv_out;
|
||||
int in_row, in_col;
|
||||
|
||||
for (i = 0; i < ch_im_out; i++)
|
||||
{
|
||||
for (j = 0; j < dim_im_out; j++)
|
||||
{
|
||||
for (k = 0; k < dim_im_out; k++)
|
||||
{
|
||||
#ifndef ARM_NN_TRUNCATE
|
||||
conv_out = ((q31_t) (bias[i]) << bias_shift) + (0x1 << (out_shift - 1));
|
||||
#else
|
||||
conv_out = bias[i] << bias_shift;
|
||||
#endif
|
||||
for (m = 0; m < dim_kernel; m++)
|
||||
{
|
||||
for (n = 0; n < dim_kernel; n++)
|
||||
{
|
||||
// if-for implementation
|
||||
in_row = stride * j + m - padding;
|
||||
in_col = stride * k + n - padding;
|
||||
if (in_row >= 0 && in_col >= 0 && in_row < dim_im_in && in_col < dim_im_in)
|
||||
{
|
||||
for (l = 0; l < ch_im_in; l++)
|
||||
{
|
||||
conv_out += Im_in[(in_row * dim_im_in + in_col) * ch_im_in + l] *
|
||||
wt[i * ch_im_in * dim_kernel * dim_kernel + (m * dim_kernel + n) * ch_im_in + l];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Im_out[i + (j * dim_im_out + k) * ch_im_out] = (q7_t) __SSAT((conv_out >> out_shift), 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "ref_functions.h"
|
||||
|
||||
void arm_convolve_HWC_q7_ref_nonsquare(const q7_t * Im_in, // input image
|
||||
const uint16_t dim_im_in_x, // input image dimention x
|
||||
const uint16_t dim_im_in_y, // input image dimention y
|
||||
const uint16_t ch_im_in, // number of input image channels
|
||||
const q7_t * wt, // kernel weights
|
||||
const uint16_t ch_im_out, // number of filters, i.e., output image channels
|
||||
const uint16_t dim_kernel_x, // filter kernel size x
|
||||
const uint16_t dim_kernel_y, // filter kernel size y
|
||||
const uint16_t padding_x, // padding sizes x
|
||||
const uint16_t padding_y, // padding sizes y
|
||||
const uint16_t stride_x, // stride x
|
||||
const uint16_t stride_y, // stride y
|
||||
const q7_t * bias, // bias
|
||||
const uint16_t bias_shift, const uint16_t out_shift, q7_t * Im_out, // output image
|
||||
const uint16_t dim_im_out_x, // output image dimension x
|
||||
const uint16_t dim_im_out_y, // output image dimension y
|
||||
q15_t * bufferA, //buffer space for input
|
||||
q7_t * bufferB //buffer space for output
|
||||
)
|
||||
{
|
||||
int i, j, k, l, m, n;
|
||||
int conv_out;
|
||||
int in_row, in_col;
|
||||
|
||||
for (i = 0; i < ch_im_out; i++)
|
||||
{
|
||||
for (j = 0; j < dim_im_out_y; j++)
|
||||
{
|
||||
for (k = 0; k < dim_im_out_x; k++)
|
||||
{
|
||||
#ifndef ARM_NN_TRUNCATE
|
||||
conv_out = ((q31_t) (bias[i]) << bias_shift) + (0x1 << (out_shift - 1));
|
||||
#else
|
||||
conv_out = bias[i] << bias_shift;
|
||||
#endif
|
||||
for (m = 0; m < dim_kernel_y; m++)
|
||||
{
|
||||
for (n = 0; n < dim_kernel_x; n++)
|
||||
{
|
||||
// if-for implementation
|
||||
in_row = stride_y * j + m - padding_y;
|
||||
in_col = stride_x * k + n - padding_x;
|
||||
if (in_row >= 0 && in_col >= 0 && in_row < dim_im_in_y && in_col < dim_im_in_x)
|
||||
{
|
||||
for (l = 0; l < ch_im_in; l++)
|
||||
{
|
||||
conv_out += Im_in[(in_row * dim_im_in_x + in_col) * ch_im_in + l] *
|
||||
wt[i * ch_im_in * dim_kernel_y * dim_kernel_x + (m * dim_kernel_x + n) * ch_im_in +
|
||||
l];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Im_out[i + (j * dim_im_out_x + k) * ch_im_out] = (q7_t) __SSAT((conv_out >> out_shift), 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "ref_functions.h"
|
||||
|
||||
void arm_depthwise_separable_conv_HWC_q7_ref(const q7_t * Im_in, // input image
|
||||
const uint16_t dim_im_in, // input image dimention
|
||||
const uint16_t ch_im_in, // number of input image channels
|
||||
const q7_t * wt, // kernel weights
|
||||
const uint16_t ch_im_out, // number of filters, i.e., output image channels
|
||||
const uint16_t dim_kernel, // filter kernel size
|
||||
const uint16_t padding, // padding sizes
|
||||
const uint16_t stride, // stride
|
||||
const q7_t * bias, // bias
|
||||
const uint16_t bias_shift, // amount of left-shift for bias
|
||||
const uint16_t out_shift, // amount of right-shift for output
|
||||
q7_t * Im_out, // output image
|
||||
const uint16_t dim_im_out, // output image dimension
|
||||
q15_t * bufferA, //buffer space for input
|
||||
q7_t * bufferB //buffer space for output
|
||||
)
|
||||
{
|
||||
int i_out_y, i_out_x, i_ch_out;
|
||||
int i_ker_y, i_ker_x;
|
||||
for (i_out_y = 0; i_out_y < dim_im_out; i_out_y++)
|
||||
{
|
||||
for (i_out_x = 0; i_out_x < dim_im_out; i_out_x++)
|
||||
{
|
||||
for (i_ch_out = 0; i_ch_out < ch_im_out; i_ch_out++)
|
||||
{
|
||||
// for each output
|
||||
#ifndef ARM_NN_TRUNCATE
|
||||
int conv_out = (bias[i_ch_out] << bias_shift) + (0x1 << (out_shift - 1));
|
||||
#else
|
||||
int conv_out = bias[i_ch_out] << bias_shift;
|
||||
#endif
|
||||
for (i_ker_y = 0; i_ker_y < dim_kernel; i_ker_y++)
|
||||
{
|
||||
for (i_ker_x = 0; i_ker_x < dim_kernel; i_ker_x++)
|
||||
{
|
||||
int in_row = stride * i_out_y + i_ker_y - padding;
|
||||
int in_col = stride * i_out_x + i_ker_x - padding;
|
||||
if (in_row >= 0 && in_col >= 0 && in_row < dim_im_in && in_col < dim_im_in)
|
||||
{
|
||||
conv_out += Im_in[(in_row * dim_im_in + in_col) * ch_im_in + i_ch_out] *
|
||||
wt[(i_ker_y * dim_kernel + i_ker_x) * ch_im_out + i_ch_out];
|
||||
}
|
||||
}
|
||||
}
|
||||
Im_out[(i_out_y * dim_im_out + i_out_x) * ch_im_out + i_ch_out] =
|
||||
(q7_t) __SSAT((conv_out >> out_shift), 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "ref_functions.h"
|
||||
|
||||
void arm_depthwise_separable_conv_HWC_q7_ref_nonsquare(const q7_t * Im_in, // input image
|
||||
const uint16_t dim_im_in_x, // input image dimention x
|
||||
const uint16_t dim_im_in_y, // input image dimention y
|
||||
const uint16_t ch_im_in, // number of input image channels
|
||||
const q7_t * wt, // kernel weights
|
||||
const uint16_t ch_im_out, // number of filters, i.e., output image channels
|
||||
const uint16_t dim_kernel_x, // filter kernel size x
|
||||
const uint16_t dim_kernel_y, // filter kernel size y
|
||||
const uint16_t padding_x, // padding sizes x
|
||||
const uint16_t padding_y, // padding sizes y
|
||||
const uint16_t stride_x, // stride x
|
||||
const uint16_t stride_y, // stride y
|
||||
const q7_t * bias, // bias
|
||||
const uint16_t bias_shift, // amount of left-shift for bias
|
||||
const uint16_t out_shift, // amount of right-shift for output
|
||||
q7_t * Im_out, // output image
|
||||
const uint16_t dim_im_out_x, // output image dimension x
|
||||
const uint16_t dim_im_out_y, // output image dimension y
|
||||
q15_t * bufferA, //buffer space for input
|
||||
q7_t * bufferB //buffer space for output
|
||||
)
|
||||
{
|
||||
int i_out_y, i_out_x, i_ch_out;
|
||||
int i_ker_y, i_ker_x;
|
||||
for (i_out_y = 0; i_out_y < dim_im_out_y; i_out_y++)
|
||||
{
|
||||
for (i_out_x = 0; i_out_x < dim_im_out_x; i_out_x++)
|
||||
{
|
||||
for (i_ch_out = 0; i_ch_out < ch_im_out; i_ch_out++)
|
||||
{
|
||||
// for each output
|
||||
#ifndef ARM_NN_TRUNCATE
|
||||
int conv_out = (bias[i_ch_out] << bias_shift) + (0x1 << (out_shift - 1));
|
||||
#else
|
||||
int conv_out = bias[i_ch_out] << bias_shift;
|
||||
#endif
|
||||
for (i_ker_y = 0; i_ker_y < dim_kernel_y; i_ker_y++)
|
||||
{
|
||||
for (i_ker_x = 0; i_ker_x < dim_kernel_x; i_ker_x++)
|
||||
{
|
||||
int in_row = stride_y * i_out_y + i_ker_y - padding_y;
|
||||
int in_col = stride_x * i_out_x + i_ker_x - padding_x;
|
||||
if (in_row >= 0 && in_col >= 0 && in_row < dim_im_in_y && in_col < dim_im_in_x)
|
||||
{
|
||||
conv_out += Im_in[(in_row * dim_im_in_x + in_col) * ch_im_in + i_ch_out] *
|
||||
wt[(i_ker_y * dim_kernel_x + i_ker_x) * ch_im_out + i_ch_out];
|
||||
}
|
||||
}
|
||||
}
|
||||
Im_out[(i_out_y * dim_im_out_x + i_out_x) * ch_im_out + i_ch_out] =
|
||||
(q7_t) __SSAT((conv_out >> out_shift), 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "ref_functions.h"
|
||||
|
||||
void arm_fully_connected_mat_q7_vec_q15_opt_ref(const q15_t * pV, // pointer to vector
|
||||
const q7_t * pM, // pointer to matrix
|
||||
const uint16_t dim_vec, // length of the vector
|
||||
const uint16_t num_of_rows, // numCol of A
|
||||
const uint16_t bias_shift, // amount of left-shift for bias
|
||||
const uint16_t out_shift, // amount of right-shift for output
|
||||
const q7_t * bias, q15_t * pOut, // output operand
|
||||
q15_t * vec_buffer)
|
||||
{
|
||||
|
||||
uint16_t rowCnt = num_of_rows >> 2;
|
||||
const q7_t *pB = pM;
|
||||
const q15_t *pA;
|
||||
q15_t *pO = pOut;
|
||||
const q7_t *pBias = bias;
|
||||
|
||||
while (rowCnt)
|
||||
{
|
||||
pA = pV;
|
||||
#ifndef ARM_NN_TRUNCATE
|
||||
q31_t sum = (*pBias++ << bias_shift) + (0x1 << (out_shift - 1));
|
||||
q31_t sum2 = (*pBias++ << bias_shift) + (0x1 << (out_shift - 1));
|
||||
q31_t sum3 = (*pBias++ << bias_shift) + (0x1 << (out_shift - 1));
|
||||
q31_t sum4 = (*pBias++ << bias_shift) + (0x1 << (out_shift - 1));
|
||||
#else
|
||||
q31_t sum = *pBias++ << bias_shift;
|
||||
q31_t sum2 = *pBias++ << bias_shift;
|
||||
q31_t sum3 = *pBias++ << bias_shift;
|
||||
q31_t sum4 = *pBias++ << bias_shift;
|
||||
#endif
|
||||
|
||||
uint16_t colCnt = dim_vec >> 1;
|
||||
|
||||
while (colCnt)
|
||||
{
|
||||
q15_t inA1 = *pA++;
|
||||
q15_t inA2 = *pA++;
|
||||
|
||||
q7_t inB1 = *pB++;
|
||||
q7_t inB3 = *pB++;
|
||||
q7_t inB2 = *pB++;
|
||||
q7_t inB4 = *pB++;
|
||||
|
||||
sum += inA1 * inB1 + inA2 * inB2;
|
||||
sum2 += inA1 * inB3 + inA2 * inB4;
|
||||
|
||||
inB1 = *pB++;
|
||||
inB3 = *pB++;
|
||||
inB2 = *pB++;
|
||||
inB4 = *pB++;
|
||||
|
||||
sum3 += inA1 * inB1 + inA2 * inB2;
|
||||
sum4 += inA1 * inB3 + inA2 * inB4;
|
||||
|
||||
colCnt--;
|
||||
}
|
||||
colCnt = dim_vec & 0x1;
|
||||
while (colCnt)
|
||||
{
|
||||
q15_t inA = *pA++;
|
||||
q7_t inB = *pB++;
|
||||
sum += inA * inB;
|
||||
inB = *pB++;
|
||||
sum2 += inA * inB;
|
||||
inB = *pB++;
|
||||
sum3 += inA * inB;
|
||||
inB = *pB++;
|
||||
sum4 += inA * inB;
|
||||
|
||||
colCnt--;
|
||||
}
|
||||
*pO++ = (q15_t) __SSAT((sum >> out_shift), 16);
|
||||
*pO++ = (q15_t) __SSAT((sum2 >> out_shift), 16);
|
||||
*pO++ = (q15_t) __SSAT((sum3 >> out_shift), 16);
|
||||
*pO++ = (q15_t) __SSAT((sum4 >> out_shift), 16);
|
||||
|
||||
rowCnt--;
|
||||
}
|
||||
|
||||
rowCnt = num_of_rows & 0x3;
|
||||
|
||||
while (rowCnt)
|
||||
{
|
||||
pA = pV;
|
||||
#ifndef ARM_NN_TRUNCATE
|
||||
int ip_out = (*pBias++ << bias_shift) + (0x1 << (out_shift - 1));
|
||||
#else
|
||||
int ip_out = *pBias++ << bias_shift;
|
||||
#endif
|
||||
for (int j = 0; j < dim_vec; j++)
|
||||
{
|
||||
q15_t inA = *pA++;
|
||||
q7_t inB = *pB++;
|
||||
ip_out += inA * inB;
|
||||
}
|
||||
*pO++ = (q15_t) __SSAT((ip_out >> out_shift), 16);
|
||||
|
||||
rowCnt--;
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "ref_functions.h"
|
||||
|
||||
void arm_fully_connected_mat_q7_vec_q15_ref(const q15_t * pV, // pointer to vector
|
||||
const q7_t * pM, // pointer to matrix
|
||||
const uint16_t dim_vec, // length of the vector
|
||||
const uint16_t num_of_rows, // numCol of A
|
||||
const uint16_t bias_shift, // amount of left-shift for bias
|
||||
const uint16_t out_shift, // amount of right-shift for output
|
||||
const q7_t * bias, q15_t * pOut, // output operand
|
||||
q15_t * vec_buffer)
|
||||
{
|
||||
for (int i = 0; i < num_of_rows; i++)
|
||||
{
|
||||
#ifndef ARM_NN_TRUNCATE
|
||||
int ip_out = (bias[i] << bias_shift) + (0x1 << (out_shift - 1));
|
||||
#else
|
||||
int ip_out = bias[i] << bias_shift;
|
||||
#endif
|
||||
for (int j = 0; j < dim_vec; j++)
|
||||
{
|
||||
ip_out += pV[j] * pM[i * dim_vec + j];
|
||||
}
|
||||
pOut[i] = (q15_t) __SSAT((ip_out >> out_shift), 16);
|
||||
}
|
||||
}
|
@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "ref_functions.h"
|
||||
|
||||
void arm_fully_connected_q15_opt_ref(const q15_t * pV, // pointer to vector
|
||||
const q15_t * pM, // pointer to matrix
|
||||
const uint16_t dim_vec, // length of the vector
|
||||
const uint16_t num_of_rows, // numCol of A
|
||||
const uint16_t bias_shift, // amount of left-shift for bias
|
||||
const uint16_t out_shift, // amount of right-shift for output
|
||||
const q15_t * bias, q15_t * pOut, // output operand
|
||||
q15_t * vec_buffer)
|
||||
{
|
||||
|
||||
uint16_t rowCnt = num_of_rows >> 2;
|
||||
const q15_t *pB = pM;
|
||||
const q15_t *pA;
|
||||
q15_t *pO = pOut;
|
||||
const q15_t *pBias = bias;
|
||||
|
||||
while (rowCnt)
|
||||
{
|
||||
pA = pV;
|
||||
#ifndef ARM_NN_TRUNCATE
|
||||
q31_t sum = (*pBias++ << bias_shift) + (0x1 << (out_shift - 1));
|
||||
q31_t sum2 = (*pBias++ << bias_shift) + (0x1 << (out_shift - 1));
|
||||
q31_t sum3 = (*pBias++ << bias_shift) + (0x1 << (out_shift - 1));
|
||||
q31_t sum4 = (*pBias++ << bias_shift) + (0x1 << (out_shift - 1));
|
||||
#else
|
||||
q31_t sum = *pBias++ << bias_shift;
|
||||
q31_t sum2 = *pBias++ << bias_shift;
|
||||
q31_t sum3 = *pBias++ << bias_shift;
|
||||
q31_t sum4 = *pBias++ << bias_shift;
|
||||
#endif
|
||||
|
||||
uint16_t colCnt = dim_vec >> 1;
|
||||
|
||||
while (colCnt)
|
||||
{
|
||||
q15_t inA1 = *pA++;
|
||||
q15_t inA2 = *pA++;
|
||||
|
||||
q15_t inB1 = *pB++;
|
||||
q15_t inB2 = *pB++;
|
||||
sum += inA1 * inB1 + inA2 * inB2;
|
||||
|
||||
inB1 = *pB++;
|
||||
inB2 = *pB++;
|
||||
sum2 += inA1 * inB1 + inA2 * inB2;
|
||||
|
||||
inB1 = *pB++;
|
||||
inB2 = *pB++;
|
||||
sum3 += inA1 * inB1 + inA2 * inB2;
|
||||
|
||||
inB1 = *pB++;
|
||||
inB2 = *pB++;
|
||||
sum4 += inA1 * inB1 + inA2 * inB2;
|
||||
|
||||
colCnt--;
|
||||
}
|
||||
colCnt = dim_vec & 0x1;
|
||||
while (colCnt)
|
||||
{
|
||||
q15_t inA = *pA++;
|
||||
q15_t inB = *pB++;
|
||||
sum += inA * inB;
|
||||
inB = *pB++;
|
||||
sum2 += inA * inB;
|
||||
inB = *pB++;
|
||||
sum3 += inA * inB;
|
||||
inB = *pB++;
|
||||
sum4 += inA * inB;
|
||||
colCnt--;
|
||||
}
|
||||
*pO++ = (q15_t) __SSAT((sum >> out_shift), 16);
|
||||
*pO++ = (q15_t) __SSAT((sum2 >> out_shift), 16);
|
||||
*pO++ = (q15_t) __SSAT((sum3 >> out_shift), 16);
|
||||
*pO++ = (q15_t) __SSAT((sum4 >> out_shift), 16);
|
||||
|
||||
rowCnt--;
|
||||
}
|
||||
|
||||
rowCnt = num_of_rows & 0x3;
|
||||
|
||||
while (rowCnt)
|
||||
{
|
||||
pA = pV;
|
||||
#ifndef ARM_NN_TRUNCATE
|
||||
int ip_out = (*pBias++ << bias_shift) + (0x1 << (out_shift - 1));
|
||||
#else
|
||||
int ip_out = *pBias++ << bias_shift;
|
||||
#endif
|
||||
for (int j = 0; j < dim_vec; j++)
|
||||
{
|
||||
q15_t inA = *pA++;
|
||||
q15_t inB = *pB++;
|
||||
ip_out += inA * inB;
|
||||
}
|
||||
*pO++ = (q15_t) __SSAT((ip_out >> out_shift), 16);
|
||||
|
||||
rowCnt--;
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "ref_functions.h"
|
||||
|
||||
void arm_fully_connected_q15_ref(const q15_t * pV, // pointer to vector
|
||||
const q15_t * pM, // pointer to matrix
|
||||
const uint16_t dim_vec, // length of the vector
|
||||
const uint16_t num_of_rows, // numCol of A
|
||||
const uint16_t bias_shift, // amount of left-shift for bias
|
||||
const uint16_t out_shift, // amount of right-shift for output
|
||||
const q15_t * bias, q15_t * pOut, // output operand
|
||||
q15_t * vec_buffer)
|
||||
{
|
||||
for (int i = 0; i < num_of_rows; i++)
|
||||
{
|
||||
#ifndef ARM_NN_TRUNCATE
|
||||
int ip_out = (bias[i] << bias_shift) + (0x1 << (out_shift - 1));
|
||||
#else
|
||||
int ip_out = bias[i] << bias_shift;
|
||||
#endif
|
||||
for (int j = 0; j < dim_vec; j++)
|
||||
{
|
||||
ip_out += pV[j] * pM[i * dim_vec + j];
|
||||
}
|
||||
pOut[i] = (q15_t) __SSAT((ip_out >> out_shift), 16);
|
||||
}
|
||||
}
|
@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "ref_functions.h"
|
||||
|
||||
void arm_fully_connected_q7_opt_ref(const q7_t * pV, // pointer to vector
|
||||
const q7_t * pM, // pointer to matrix
|
||||
const uint16_t dim_vec, // length of the vector
|
||||
const uint16_t num_of_rows, // numCol of A
|
||||
const uint16_t bias_shift, // amount of left-shift for bias
|
||||
const uint16_t out_shift, // amount of right-shift for output
|
||||
const q7_t * bias, q7_t * pOut, // output operand
|
||||
q15_t * vec_buffer)
|
||||
{
|
||||
|
||||
uint16_t rowCnt = num_of_rows >> 2;
|
||||
const q7_t *pB = pM;
|
||||
const q7_t *pA;
|
||||
q7_t *pO = pOut;
|
||||
const q7_t *pBias = bias;
|
||||
|
||||
while (rowCnt)
|
||||
{
|
||||
pA = pV;
|
||||
#ifndef ARM_NN_TRUNCATE
|
||||
q31_t sum = (*pBias++ << bias_shift) + (0x1 << (out_shift - 1));
|
||||
q31_t sum2 = (*pBias++ << bias_shift) + (0x1 << (out_shift - 1));
|
||||
q31_t sum3 = (*pBias++ << bias_shift) + (0x1 << (out_shift - 1));
|
||||
q31_t sum4 = (*pBias++ << bias_shift) + (0x1 << (out_shift - 1));
|
||||
#else
|
||||
q31_t sum = *pBias++ << bias_shift;
|
||||
q31_t sum2 = *pBias++ << bias_shift;
|
||||
q31_t sum3 = *pBias++ << bias_shift;
|
||||
q31_t sum4 = *pBias++ << bias_shift;
|
||||
#endif
|
||||
|
||||
uint16_t colCnt = dim_vec >> 2;
|
||||
|
||||
while (colCnt)
|
||||
{
|
||||
q7_t inA1 = *pA++;
|
||||
q7_t inA3 = *pA++;
|
||||
q7_t inA2 = *pA++;
|
||||
q7_t inA4 = *pA++;
|
||||
|
||||
q7_t inB1 = *pB++;
|
||||
q7_t inB3 = *pB++;
|
||||
q7_t inB2 = *pB++;
|
||||
q7_t inB4 = *pB++;
|
||||
|
||||
sum += inA1 * inB1 + inA2 * inB2;
|
||||
sum2 += inA1 * inB3 + inA2 * inB4;
|
||||
|
||||
inB1 = *pB++;
|
||||
inB3 = *pB++;
|
||||
inB2 = *pB++;
|
||||
inB4 = *pB++;
|
||||
|
||||
sum3 += inA1 * inB1 + inA2 * inB2;
|
||||
sum4 += inA1 * inB3 + inA2 * inB4;
|
||||
|
||||
inB1 = *pB++;
|
||||
inB3 = *pB++;
|
||||
inB2 = *pB++;
|
||||
inB4 = *pB++;
|
||||
|
||||
sum += inA3 * inB1 + inA4 * inB2;
|
||||
sum2 += inA3 * inB3 + inA4 * inB4;
|
||||
|
||||
inB1 = *pB++;
|
||||
inB3 = *pB++;
|
||||
inB2 = *pB++;
|
||||
inB4 = *pB++;
|
||||
|
||||
sum3 += inA3 * inB1 + inA4 * inB2;
|
||||
sum4 += inA3 * inB3 + inA4 * inB4;
|
||||
|
||||
colCnt--;
|
||||
}
|
||||
colCnt = dim_vec & 0x3;
|
||||
while (colCnt)
|
||||
{
|
||||
q7_t inA = *pA++;
|
||||
q7_t inB = *pB++;
|
||||
sum += inA * inB;
|
||||
inB = *pB++;
|
||||
sum2 += inA * inB;
|
||||
inB = *pB++;
|
||||
sum3 += inA * inB;
|
||||
inB = *pB++;
|
||||
sum4 += inA * inB;
|
||||
|
||||
colCnt--;
|
||||
}
|
||||
*pO++ = (q7_t) __SSAT((sum >> out_shift), 8);
|
||||
*pO++ = (q7_t) __SSAT((sum2 >> out_shift), 8);
|
||||
*pO++ = (q7_t) __SSAT((sum3 >> out_shift), 8);
|
||||
*pO++ = (q7_t) __SSAT((sum4 >> out_shift), 8);
|
||||
|
||||
rowCnt--;
|
||||
}
|
||||
|
||||
rowCnt = num_of_rows & 0x3;
|
||||
|
||||
while (rowCnt)
|
||||
{
|
||||
pA = pV;
|
||||
#ifndef ARM_NN_TRUNCATE
|
||||
int ip_out = (*pBias++ << bias_shift) + (0x1 << (out_shift - 1));
|
||||
#else
|
||||
int ip_out = *pBias++ << bias_shift;
|
||||
#endif
|
||||
for (int j = 0; j < dim_vec; j++)
|
||||
{
|
||||
q7_t inA = *pA++;
|
||||
q7_t inB = *pB++;
|
||||
ip_out += inA * inB;
|
||||
}
|
||||
*pO++ = (q7_t) __SSAT((ip_out >> out_shift), 8);
|
||||
|
||||
rowCnt--;
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "ref_functions.h"
|
||||
|
||||
void arm_fully_connected_q7_ref(const q7_t * pV, // pointer to vector
|
||||
const q7_t * pM, // pointer to matrix
|
||||
const uint16_t dim_vec, // length of the vector
|
||||
const uint16_t num_of_rows, // numCol of A
|
||||
const uint16_t bias_shift, // amount of left-shift for bias
|
||||
const uint16_t out_shift, // amount of right-shift for output
|
||||
const q7_t * bias, q7_t * pOut, // output operand
|
||||
q15_t * vec_buffer)
|
||||
{
|
||||
for (int i = 0; i < num_of_rows; i++)
|
||||
{
|
||||
#ifndef ARM_NN_TRUNCATE
|
||||
int ip_out = (bias[i] << bias_shift) + (0x1 << (out_shift - 1));
|
||||
#else
|
||||
int ip_out = bias[i] << bias_shift;
|
||||
#endif
|
||||
for (int j = 0; j < dim_vec; j++)
|
||||
{
|
||||
ip_out += pV[j] * pM[i * dim_vec + j];
|
||||
}
|
||||
pOut[i] = (q7_t) __SSAT((ip_out >> out_shift), 8);
|
||||
}
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "arm_math.h"
|
||||
#include "arm_nnfunctions.h"
|
||||
|
||||
void arm_nn_mult_q7_ref(q7_t * pSrcA,
|
||||
q7_t * pSrcB,
|
||||
q7_t * pDst,
|
||||
const uint16_t out_shift,
|
||||
uint32_t blockSize) {
|
||||
uint16_t i;
|
||||
|
||||
for (i = 0; i < blockSize; i++)
|
||||
{
|
||||
q31_t product = pSrcA[i] * pSrcB[i];
|
||||
#ifndef ARM_NN_TRUNCATE
|
||||
pDst[i] = (q7_t)__SSAT((product + (0x1 << (out_shift - 1)))>>out_shift, 8);
|
||||
#else
|
||||
pDst[i] = (q7_t)__SSAT(product >> out_shift, 8);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void arm_nn_mult_q15_ref(q15_t * pSrcA,
|
||||
q15_t * pSrcB,
|
||||
q15_t * pDst,
|
||||
const uint16_t out_shift,
|
||||
uint32_t blockSize) {
|
||||
uint16_t i;
|
||||
|
||||
for (i = 0; i < blockSize; i++)
|
||||
{
|
||||
q31_t product = pSrcA[i] * pSrcB[i];
|
||||
#ifndef ARM_NN_TRUNCATE
|
||||
pDst[i] = (q15_t)__SSAT((product + (0x1 << (out_shift - 1)))>>out_shift, 16);
|
||||
#else
|
||||
pDst[i] = (q15_t)__SSAT(product >> out_shift, 16);
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "ref_functions.h"
|
||||
|
||||
void arm_avepool_q7_HWC_ref(const q7_t * Im_in, // input image
|
||||
const uint16_t dim_im_in, // input image dimension
|
||||
const uint16_t ch_im_in, // number of input image channels
|
||||
const uint16_t dim_kernel, // window kernel size
|
||||
const uint16_t padding, // padding sizes
|
||||
const uint16_t stride, // stride
|
||||
const uint16_t dim_im_out, // output image dimension
|
||||
q7_t * bufferA, // a buffer for local storage
|
||||
q7_t * Im_out)
|
||||
{
|
||||
int16_t i_ch_in, i_x, i_y;
|
||||
int16_t k_x, k_y;
|
||||
|
||||
for (i_ch_in = 0; i_ch_in < ch_im_in; i_ch_in++)
|
||||
{
|
||||
for (i_y = 0; i_y < dim_im_out; i_y++)
|
||||
{
|
||||
for (i_x = 0; i_x < dim_im_out; i_x++)
|
||||
{
|
||||
int sum = 0;
|
||||
int count = 0;
|
||||
for (k_y = i_y * stride - padding; k_y < i_y * stride - padding + dim_kernel; k_y++)
|
||||
{
|
||||
for (k_x = i_x * stride - padding; k_x < i_x * stride - padding + dim_kernel; k_x++)
|
||||
{
|
||||
if (k_y >= 0 && k_x >= 0 && k_y < dim_im_in && k_x < dim_im_in)
|
||||
{
|
||||
sum += Im_in[i_ch_in + ch_im_in * (k_x + k_y * dim_im_in)];
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
Im_out[i_ch_in + ch_im_in * (i_x + i_y * dim_im_out)] = sum / count;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void arm_maxpool_q7_HWC_ref(const q7_t * Im_in, // input image
|
||||
const uint16_t dim_im_in, // input image dimension
|
||||
const uint16_t ch_im_in, // number of input image channels
|
||||
const uint16_t dim_kernel, // window kernel size
|
||||
const uint16_t padding, // padding sizes
|
||||
const uint16_t stride, // stride
|
||||
const uint16_t dim_im_out, // output image dimension
|
||||
q7_t * bufferA, // a buffer for local storage
|
||||
q7_t * Im_out)
|
||||
{
|
||||
int16_t i_ch_in, i_x, i_y;
|
||||
int16_t k_x, k_y;
|
||||
|
||||
for (i_ch_in = 0; i_ch_in < ch_im_in; i_ch_in++)
|
||||
{
|
||||
for (i_y = 0; i_y < dim_im_out; i_y++)
|
||||
{
|
||||
for (i_x = 0; i_x < dim_im_out; i_x++)
|
||||
{
|
||||
int max = -129;
|
||||
for (k_y = i_y * stride - padding; k_y < i_y * stride - padding + dim_kernel; k_y++)
|
||||
{
|
||||
for (k_x = i_x * stride - padding; k_x < i_x * stride - padding + dim_kernel; k_x++)
|
||||
{
|
||||
if (k_y >= 0 && k_x >= 0 && k_y < dim_im_in && k_x < dim_im_in)
|
||||
{
|
||||
if (Im_in[i_ch_in + ch_im_in * (k_x + k_y * dim_im_in)] > max)
|
||||
{
|
||||
max = Im_in[i_ch_in + ch_im_in * (k_x + k_y * dim_im_in)];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Im_out[i_ch_in + ch_im_in * (i_x + i_y * dim_im_out)] = max;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "arm_math.h"
|
||||
#include "arm_nnfunctions.h"
|
||||
|
||||
void arm_relu_q7_ref(q7_t * data, uint16_t size)
|
||||
{
|
||||
uint16_t i;
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
if (data[i] < 0)
|
||||
data[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void arm_relu_q15_ref(q15_t * data, uint16_t size)
|
||||
{
|
||||
uint16_t i;
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
if (data[i] < 0)
|
||||
data[i] = 0;
|
||||
}
|
||||
}
|
File diff suppressed because one or more lines are too long
@ -0,0 +1,250 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _REF_FUNCTIONS_H_
|
||||
#define _REF_FUNCTIONS_H_
|
||||
|
||||
#include "arm_math.h"
|
||||
#include "arm_nnfunctions.h"
|
||||
//#include "arm_nnsupportfunctions.h"
|
||||
#include "fully_connected_testing_weights.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/*
|
||||
*
|
||||
* Convolution reference implemenation
|
||||
*
|
||||
*/
|
||||
|
||||
void arm_convolve_HWC_q7_ref(const q7_t * Im_in, // input image
|
||||
const uint16_t dim_im_in, // input image dimention
|
||||
const uint16_t ch_im_in, // number of input image channels
|
||||
const q7_t * wt, // kernel weights
|
||||
const uint16_t ch_im_out, // number of filters, i.e., output image channels
|
||||
const uint16_t dim_kernel, // filter kernel size
|
||||
const uint16_t padding, // padding sizes
|
||||
const uint16_t stride, // stride
|
||||
const q7_t * bias, // bias
|
||||
const uint16_t bias_shift, const uint16_t out_shift, q7_t * Im_out, // output image
|
||||
const uint16_t dim_im_out, // output image dimension
|
||||
q15_t * bufferA, //buffer space for input
|
||||
q7_t * bufferB //buffer space for output
|
||||
);
|
||||
|
||||
void arm_convolve_HWC_q7_ref_nonsquare(const q7_t * Im_in, // input image
|
||||
const uint16_t dim_im_in_x, // input image dimention x
|
||||
const uint16_t dim_im_in_y, // input image dimention y
|
||||
const uint16_t ch_im_in, // number of input image channels
|
||||
const q7_t * wt, // kernel weights
|
||||
const uint16_t ch_im_out, // number of filters, i.e., output image channels
|
||||
const uint16_t dim_kernel_x, // filter kernel size x
|
||||
const uint16_t dim_kernel_y, // filter kernel size y
|
||||
const uint16_t padding_x, // padding sizes x
|
||||
const uint16_t padding_y, // padding sizes y
|
||||
const uint16_t stride_x, // stride x
|
||||
const uint16_t stride_y, // stride y
|
||||
const q7_t * bias, // bias
|
||||
const uint16_t bias_shift, const uint16_t out_shift, q7_t * Im_out, // output image
|
||||
const uint16_t dim_im_out_x, // output image dimension x
|
||||
const uint16_t dim_im_out_y, // output image dimension y
|
||||
q15_t * bufferA, //buffer space for input
|
||||
q7_t * bufferB //buffer space for output
|
||||
);
|
||||
|
||||
void arm_convolve_HWC_q15_ref(const q15_t * Im_in, // input image
|
||||
const uint16_t dim_im_in, // input image dimention
|
||||
const uint16_t ch_im_in, // number of input image channels
|
||||
const q15_t * wt, // kernel weights
|
||||
const uint16_t ch_im_out, // number of filters, i.e., output image channels
|
||||
const uint16_t dim_kernel, // filter kernel size
|
||||
const uint16_t padding, // padding sizes
|
||||
const uint16_t stride, // stride
|
||||
const q15_t * bias, // bias
|
||||
const uint16_t bias_shift, const uint16_t out_shift, q15_t * Im_out, // output image
|
||||
const uint16_t dim_im_out, // output image dimension
|
||||
q15_t * bufferA, //buffer space for input
|
||||
q7_t * bufferB //buffer space for output
|
||||
);
|
||||
void arm_convolve_HWC_q15_nonsquare_ref(const q15_t * Im_in,
|
||||
const uint16_t dim_im_in_x,
|
||||
const uint16_t dim_im_in_y,
|
||||
const uint16_t ch_im_in,
|
||||
const q15_t * wt,
|
||||
const uint16_t ch_im_out,
|
||||
const uint16_t dim_kernel_x,
|
||||
const uint16_t dim_kernel_y,
|
||||
const uint16_t padding_x,
|
||||
const uint16_t padding_y,
|
||||
const uint16_t stride_x,
|
||||
const uint16_t stride_y,
|
||||
const q15_t * bias,
|
||||
const uint16_t bias_shift,
|
||||
const uint16_t out_shift,
|
||||
q15_t * Im_out,
|
||||
const uint16_t dim_im_out_x,
|
||||
const uint16_t dim_im_out_y,
|
||||
q15_t * bufferA,
|
||||
q7_t * bufferB);
|
||||
|
||||
void arm_depthwise_separable_conv_HWC_q7_ref(const q7_t * Im_in, // input image
|
||||
const uint16_t dim_im_in, // input image dimention
|
||||
const uint16_t ch_im_in, // number of input image channels
|
||||
const q7_t * wt, // kernel weights
|
||||
const uint16_t ch_im_out, // number of filters, i.e., output image channels
|
||||
const uint16_t dim_kernel, // filter kernel size
|
||||
const uint16_t padding, // padding sizes
|
||||
const uint16_t stride, // stride
|
||||
const q7_t * bias, // bias
|
||||
const uint16_t bias_shift, // amount of left-shift for bias
|
||||
const uint16_t out_shift, // amount of right-shift for output
|
||||
q7_t * Im_out, // output image
|
||||
const uint16_t dim_im_out, // output image dimension
|
||||
q15_t * bufferA, //buffer space for input
|
||||
q7_t * bufferB //buffer space for output
|
||||
);
|
||||
void arm_depthwise_separable_conv_HWC_q7_ref_nonsquare(const q7_t * Im_in, // input image
|
||||
const uint16_t dim_im_in_x, // input image dimention x
|
||||
const uint16_t dim_im_in_y, // input image dimention y
|
||||
const uint16_t ch_im_in, // number of input image channels
|
||||
const q7_t * wt, // kernel weights
|
||||
const uint16_t ch_im_out, // number of filters, i.e., output image channels
|
||||
const uint16_t dim_kernel_x, // filter kernel size x
|
||||
const uint16_t dim_kernel_y, // filter kernel size y
|
||||
const uint16_t padding_x, // padding sizes x
|
||||
const uint16_t padding_y, // padding sizes y
|
||||
const uint16_t stride_x, // stride x
|
||||
const uint16_t stride_y, // stride y
|
||||
const q7_t * bias, // bias
|
||||
const uint16_t bias_shift, // amount of left-shift for bias
|
||||
const uint16_t out_shift, // amount of right-shift for output
|
||||
q7_t * Im_out, // output image
|
||||
const uint16_t dim_im_out_x, // output image dimension x
|
||||
const uint16_t dim_im_out_y, // output image dimension y
|
||||
q15_t * bufferA, //buffer space for input
|
||||
q7_t * bufferB //buffer space for output
|
||||
);
|
||||
|
||||
/*
|
||||
*
|
||||
* Fully-connected reference implemenation
|
||||
*
|
||||
*/
|
||||
|
||||
void arm_fully_connected_q7_ref(const q7_t * pV, // pointer to vector
|
||||
const q7_t * pM, // pointer to matrix
|
||||
const uint16_t dim_vec, // length of the vector
|
||||
const uint16_t num_of_rows, // numCol of A
|
||||
const uint16_t bias_shift, // amount of left-shift for bias
|
||||
const uint16_t out_shift, // amount of right-shift for output
|
||||
const q7_t * bias, q7_t * pOut, // output operand
|
||||
q15_t * vec_buffer);
|
||||
|
||||
void arm_fully_connected_q15_ref(const q15_t * pV, // pointer to vector
|
||||
const q15_t * pM, // pointer to matrix
|
||||
const uint16_t dim_vec, // length of the vector
|
||||
const uint16_t num_of_rows, // numCol of A
|
||||
const uint16_t bias_shift, // amount of left-shift for bias
|
||||
const uint16_t out_shift, // amount of right-shift for output
|
||||
const q15_t * bias, q15_t * pOut, // output operand
|
||||
q15_t * vec_buffer);
|
||||
|
||||
void arm_fully_connected_mat_q7_vec_q15_ref(const q15_t * pV, // pointer to vector
|
||||
const q7_t * pM, // pointer to matrix
|
||||
const uint16_t dim_vec, // length of the vector
|
||||
const uint16_t num_of_rows, // numCol of A
|
||||
const uint16_t bias_shift, // amount of left-shift for bias
|
||||
const uint16_t out_shift, // amount of right-shift for output
|
||||
const q7_t * bias, q15_t * pOut, // output operand
|
||||
q15_t * vec_buffer);
|
||||
|
||||
void arm_fully_connected_q7_opt_ref(const q7_t * pV, // pointer to vector
|
||||
const q7_t * pM, // pointer to matrix
|
||||
const uint16_t dim_vec, // length of the vector
|
||||
const uint16_t num_of_rows, // numCol of A
|
||||
const uint16_t bias_shift, // amount of left-shift for bias
|
||||
const uint16_t out_shift, // amount of right-shift for output
|
||||
const q7_t * bias, q7_t * pOut, // output operand
|
||||
q15_t * vec_buffer);
|
||||
|
||||
void arm_fully_connected_q15_opt_ref(const q15_t * pV, // pointer to vector
|
||||
const q15_t * pM, // pointer to matrix
|
||||
const uint16_t dim_vec, // length of the vector
|
||||
const uint16_t num_of_rows, // numCol of A
|
||||
const uint16_t bias_shift, // amount of left-shift for bias
|
||||
const uint16_t out_shift, // amount of right-shift for output
|
||||
const q15_t * bias, q15_t * pOut, // output operand
|
||||
q15_t * vec_buffer);
|
||||
|
||||
void arm_fully_connected_mat_q7_vec_q15_opt_ref(const q15_t * pV, // pointer to vector
|
||||
const q7_t * pM, // pointer to matrix
|
||||
const uint16_t dim_vec, // length of the vector
|
||||
const uint16_t num_of_rows, // numCol of A
|
||||
const uint16_t bias_shift, // amount of left-shift for bias
|
||||
const uint16_t out_shift, // amount of right-shift for output
|
||||
const q7_t * bias, q15_t * pOut, // output operand
|
||||
q15_t * vec_buffer);
|
||||
|
||||
/*
|
||||
*
|
||||
* Pooling reference implemenation
|
||||
*
|
||||
*/
|
||||
|
||||
void arm_avepool_q7_HWC_ref(const q7_t * Im_in, // input image
|
||||
const uint16_t dim_im_in, // input image dimension
|
||||
const uint16_t ch_im_in, // number of input image channels
|
||||
const uint16_t dim_kernel, // window kernel size
|
||||
const uint16_t padding, // padding sizes
|
||||
const uint16_t stride, // stride
|
||||
const uint16_t dim_im_out, // output image dimension
|
||||
q7_t * bufferA, // a buffer for local storage
|
||||
q7_t * Im_out);
|
||||
|
||||
void arm_maxpool_q7_HWC_ref(const q7_t * Im_in, // input image
|
||||
const uint16_t dim_im_in, // input image dimension
|
||||
const uint16_t ch_im_in, // number of input image channels
|
||||
const uint16_t dim_kernel, // window kernel size
|
||||
const uint16_t padding, // padding sizes
|
||||
const uint16_t stride, // stride
|
||||
const uint16_t dim_im_out, // output image dimension
|
||||
q7_t * bufferA, // a buffer for local storage
|
||||
q7_t * Im_out);
|
||||
|
||||
/*
|
||||
*
|
||||
* Other reference implemenation
|
||||
*
|
||||
*/
|
||||
|
||||
void arm_relu_q7_ref(q7_t * data, uint16_t size);
|
||||
|
||||
void arm_relu_q15_ref(q15_t * data, uint16_t size);
|
||||
|
||||
void arm_nn_mult_q7_ref(q7_t * pSrcA, q7_t * pSrcB, q7_t * pDst, const uint16_t out_shift, uint32_t blockSize);
|
||||
|
||||
void arm_nn_mult_q15_ref(q15_t * pSrcA, q15_t * pSrcB, q15_t * pDst, const uint16_t out_shift, uint32_t blockSize);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -0,0 +1,801 @@
|
||||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010-2018 Arm Limited. All rights reserved.
|
||||
*
|
||||
*
|
||||
* Project: CMSIS NN Library
|
||||
* Title: arm_nnexamples_nn_test.cpp
|
||||
*
|
||||
* Description: Example code for NN kernel testing.
|
||||
*
|
||||
* Target Processor: Cortex-M cores
|
||||
*
|
||||
* 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 LIMITED 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 THE
|
||||
* COPYRIGHT OWNER 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.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_nnexamples_nn_test.h"
|
||||
|
||||
//#define TEST_SIGMOID
|
||||
//#define TEST_TANH
|
||||
#define TEST_POOL
|
||||
#define TEST_RELU
|
||||
#define TEST_IP
|
||||
#define TEST_CONV
|
||||
#define TEST_NONSQUARE
|
||||
#define TEST_NNMULT
|
||||
|
||||
int test_index = 0;
|
||||
q7_t test_flags[50];
|
||||
bool test_pass;
|
||||
|
||||
int main()
|
||||
{
|
||||
printf("start tests\n");
|
||||
|
||||
srand(1);
|
||||
|
||||
// common pointers for testing data
|
||||
q7_t *test1;
|
||||
q15_t *test2;
|
||||
q7_t *test3;
|
||||
q15_t *test4;
|
||||
|
||||
for (test_index = 0; test_index<50; test_index++) {
|
||||
test_flags[test_index] = -1;
|
||||
}
|
||||
test_index = 0;
|
||||
|
||||
#ifdef TEST_NNMULT
|
||||
#define NNMULT_DIM 128
|
||||
test1 = new q7_t[NNMULT_DIM*2];
|
||||
test2 = new q15_t[NNMULT_DIM*2];
|
||||
test3 = new q7_t[NNMULT_DIM*2];
|
||||
test4 = new q15_t[NNMULT_DIM*2];
|
||||
|
||||
q7_t * mult_out_q7 = test3;
|
||||
q7_t * mult_ref_q7 = test3 + NNMULT_DIM;
|
||||
q15_t * mult_out_q15 = test4;
|
||||
q15_t * mult_ref_q15 = test4 + NNMULT_DIM;
|
||||
|
||||
for (int i=0;i<NNMULT_DIM*2;i++) {
|
||||
test1[i] = (rand() % 256 - 128);
|
||||
test2[i] = (rand() % 65536 - 32768);
|
||||
}
|
||||
|
||||
// Test q7
|
||||
arm_nn_mult_q7(test1, test1+NNMULT_DIM, mult_out_q7, 5, NNMULT_DIM);
|
||||
|
||||
arm_nn_mult_q7_ref(test1, test1+NNMULT_DIM, mult_ref_q7, 5, NNMULT_DIM);
|
||||
|
||||
verify_results_q7(mult_out_q7, mult_ref_q7, NNMULT_DIM);
|
||||
|
||||
arm_nn_mult_q7(test1, test1+NNMULT_DIM, mult_out_q7, 9, NNMULT_DIM);
|
||||
|
||||
arm_nn_mult_q7_ref(test1, test1+NNMULT_DIM, mult_ref_q7, 9, NNMULT_DIM);
|
||||
|
||||
verify_results_q7(mult_out_q7, mult_ref_q7, NNMULT_DIM);
|
||||
|
||||
// Test q15
|
||||
arm_nn_mult_q15(test2, test2+NNMULT_DIM, mult_out_q15, 13, NNMULT_DIM);
|
||||
|
||||
arm_nn_mult_q15_ref(test2, test2+NNMULT_DIM, mult_ref_q15, 13, NNMULT_DIM);
|
||||
|
||||
verify_results_q15(mult_out_q15, mult_ref_q15, NNMULT_DIM);
|
||||
|
||||
arm_nn_mult_q15(test2, test2+NNMULT_DIM, mult_out_q15, 18, NNMULT_DIM);
|
||||
|
||||
arm_nn_mult_q15_ref(test2, test2+NNMULT_DIM, mult_ref_q15, 18, NNMULT_DIM);
|
||||
|
||||
verify_results_q15(mult_out_q15, mult_ref_q15, NNMULT_DIM);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TEST_SIGMOID
|
||||
|
||||
#define SIGMOID_DIM 128
|
||||
|
||||
/* This part tests the running of sigmoid functions */
|
||||
|
||||
test1 = new q7_t[SIGMOID_DIM];
|
||||
test2 = new q15_t[SIGMOID_DIM];
|
||||
test3 = new q7_t[SIGMOID_DIM];
|
||||
test4 = new q15_t[SIGMOID_DIM];
|
||||
|
||||
srand(1);
|
||||
|
||||
for (int i = 0; i < SIGMOID_DIM; i++)
|
||||
{
|
||||
test1[i] = (rand() % 256 - 128);
|
||||
test2[i] = (rand() % 65536 - 32768);
|
||||
test3[i] = test1[i];
|
||||
test4[i] = test2[i];
|
||||
}
|
||||
|
||||
arm_nn_activations_direct_q7(test3, SIGMOID_DIM, 3, ARM_SIGMOID);
|
||||
|
||||
for (int i = 0; i < SIGMOID_DIM; i++)
|
||||
{
|
||||
printf("in: %d out: %d\n", test1[i], test3[i]);
|
||||
}
|
||||
|
||||
printf("start testing q15_t sigmoid\n\n");
|
||||
|
||||
arm_nn_activations_direct_q15(test4, SIGMOID_DIM, 3, ARM_SIGMOID);
|
||||
|
||||
for (int i = 0; i < SIGMOID_DIM; i++)
|
||||
{
|
||||
printf("in: %d out: %d\n", test2[i], test4[i]);
|
||||
}
|
||||
|
||||
delete[]test1;
|
||||
delete[]test2;
|
||||
delete[]test3;
|
||||
delete[]test4;
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TEST_TANH
|
||||
|
||||
#define TANH_DIM 128
|
||||
|
||||
/* This part tests the running of sigmoid functions */
|
||||
|
||||
test1 = new q7_t[TANH_DIM];
|
||||
test2 = new q15_t[TANH_DIM];
|
||||
test3 = new q7_t[TANH_DIM];
|
||||
test4 = new q15_t[TANH_DIM];
|
||||
|
||||
srand(1);
|
||||
|
||||
for (int i = 0; i < TANH_DIM; i++)
|
||||
{
|
||||
test1[i] = (rand() % 256 - 128);
|
||||
test2[i] = (rand() % 65536 - 32768);
|
||||
test3[i] = test1[i];
|
||||
test4[i] = test2[i];
|
||||
}
|
||||
|
||||
arm_nn_activations_direct_q7(test3, TANH_DIM, 3, ARM_TANH);
|
||||
|
||||
printf("start testing q7_t tanh\n\n");
|
||||
|
||||
for (int i = 0; i < TANH_DIM; i++)
|
||||
{
|
||||
printf("in: %d out: %d\n", test1[i], test3[i]);
|
||||
}
|
||||
|
||||
printf("start testing q15_t tanh\n\n");
|
||||
|
||||
arm_nn_activations_direct_q15(test4, TANH_DIM, 3, ARM_TANH);
|
||||
|
||||
for (int i = 0; i < TANH_DIM; i++)
|
||||
{
|
||||
printf("in: %d out: %d\n", test2[i], test4[i]);
|
||||
}
|
||||
|
||||
delete[]test1;
|
||||
delete[]test2;
|
||||
delete[]test3;
|
||||
delete[]test4;
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TEST_POOL
|
||||
|
||||
#define POOL_IM_DIM 32
|
||||
#define POOL_IM_CH 8
|
||||
|
||||
test1 = new q7_t[POOL_IM_DIM * POOL_IM_DIM * POOL_IM_CH * 2];
|
||||
test2 = new q15_t[POOL_IM_DIM * POOL_IM_CH];
|
||||
test3 = new q7_t[POOL_IM_DIM * POOL_IM_DIM * POOL_IM_CH];
|
||||
|
||||
for (int i = 0; i < POOL_IM_DIM * POOL_IM_DIM * POOL_IM_CH; i++)
|
||||
{
|
||||
test1[i] = (rand() % 256 - 128);
|
||||
}
|
||||
|
||||
q7_t *img_in = test1 + POOL_IM_DIM * POOL_IM_DIM * POOL_IM_CH;
|
||||
q7_t *pool_out_ref = test3;
|
||||
q7_t *pool_out_opt = test3 + POOL_IM_DIM * POOL_IM_DIM * POOL_IM_CH / 2;
|
||||
|
||||
for (int i = 0; i < POOL_IM_DIM * POOL_IM_DIM * POOL_IM_CH; i++)
|
||||
{
|
||||
test3[i] = 0;
|
||||
}
|
||||
|
||||
// copy over the img input
|
||||
for (int i = 0; i < POOL_IM_DIM * POOL_IM_DIM * POOL_IM_CH; i++)
|
||||
{
|
||||
img_in[i] = test1[i];
|
||||
}
|
||||
|
||||
initialize_results_q7(pool_out_ref, pool_out_opt, POOL_IM_DIM / 2 * POOL_IM_DIM / 2 * POOL_IM_CH);
|
||||
|
||||
printf("Start maxpool reference implementation\n");
|
||||
|
||||
arm_maxpool_q7_HWC_ref(img_in, POOL_IM_DIM, POOL_IM_CH, 3, 0, 2, POOL_IM_DIM / 2, (q7_t *) test2, pool_out_ref);
|
||||
|
||||
// copy over the img input
|
||||
for (int i = 0; i < POOL_IM_DIM * POOL_IM_DIM * POOL_IM_CH; i++)
|
||||
{
|
||||
img_in[i] = test1[i];
|
||||
}
|
||||
|
||||
printf("Start maxpool opt implementation\n");
|
||||
|
||||
arm_maxpool_q7_HWC(img_in, POOL_IM_DIM, POOL_IM_CH, 3, 0, 2, POOL_IM_DIM / 2, (q7_t *) test2, pool_out_opt);
|
||||
|
||||
verify_results_q7(pool_out_ref, pool_out_opt, POOL_IM_DIM / 2 * POOL_IM_DIM / 2 * POOL_IM_CH);
|
||||
|
||||
// copy over the img input
|
||||
for (int i = 0; i < POOL_IM_DIM * POOL_IM_DIM * POOL_IM_CH; i++)
|
||||
{
|
||||
img_in[i] = test1[i];
|
||||
}
|
||||
|
||||
// copy over the img input
|
||||
for (int i = 0; i < POOL_IM_DIM * POOL_IM_DIM * POOL_IM_CH; i++)
|
||||
{
|
||||
img_in[i] = test1[i];
|
||||
}
|
||||
|
||||
printf("Start avepool ref implementation\n");
|
||||
|
||||
arm_avepool_q7_HWC_ref(img_in, POOL_IM_DIM, POOL_IM_CH, 3, 0, 2, POOL_IM_DIM / 2, (q7_t *) test2, pool_out_ref);
|
||||
|
||||
// copy over the img input
|
||||
for (int i = 0; i < POOL_IM_DIM * POOL_IM_DIM * POOL_IM_CH; i++)
|
||||
{
|
||||
img_in[i] = test1[i];
|
||||
}
|
||||
|
||||
printf("Start avepool opt implementation\n");
|
||||
|
||||
arm_avepool_q7_HWC(img_in, POOL_IM_DIM, POOL_IM_CH, 3, 0, 2, POOL_IM_DIM / 2, (q7_t *) test2, pool_out_opt);
|
||||
|
||||
// special check here
|
||||
bool if_ave_pool_match = true;
|
||||
for (int i = 0; i < POOL_IM_DIM / 2 * POOL_IM_DIM / 2 * POOL_IM_CH; i++)
|
||||
{
|
||||
// we tolerate at most difference of 1 here because of rounding errors
|
||||
if (pool_out_ref[i] - pool_out_opt[i] >= 2 || pool_out_opt[i] - pool_out_ref[i] >= 2)
|
||||
{
|
||||
printf("Output mismatch at %d, expected %d, actual %d\n", i, pool_out_ref[i], pool_out_opt[i]);
|
||||
if_ave_pool_match = false;
|
||||
}
|
||||
}
|
||||
if (if_ave_pool_match == true)
|
||||
{
|
||||
printf("Outputs match.\n");
|
||||
}
|
||||
|
||||
delete[]test1;
|
||||
delete[]test2;
|
||||
delete[]test3;
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TEST_RELU
|
||||
|
||||
#define RELU_DIM 127
|
||||
|
||||
test1 = new q7_t[RELU_DIM];
|
||||
test2 = new q15_t[RELU_DIM];
|
||||
test3 = new q7_t[RELU_DIM];
|
||||
test4 = new q15_t[RELU_DIM];
|
||||
|
||||
for (int i = 0; i < RELU_DIM; i++)
|
||||
{
|
||||
test1[i] = (rand() % 256 - 128);
|
||||
test2[i] = (rand() % 65536 - 32768);
|
||||
test3[i] = test1[i];
|
||||
test4[i] = test2[i];
|
||||
}
|
||||
|
||||
q7_t *relu_ref_data_q7 = test1;
|
||||
q7_t *relu_opt_data_q7 = test3;
|
||||
q15_t *relu_ref_data_q15 = test2;
|
||||
q15_t *relu_opt_data_q15 = test4;
|
||||
|
||||
printf("Start ref relu q7 implementation\n");
|
||||
|
||||
arm_relu_q7_ref(relu_ref_data_q7, RELU_DIM);
|
||||
|
||||
printf("Start opt relu q7 implementation\n");
|
||||
|
||||
arm_relu_q7(relu_opt_data_q7, RELU_DIM);
|
||||
|
||||
verify_results_q7(relu_ref_data_q7, relu_opt_data_q7, RELU_DIM);
|
||||
|
||||
printf("Start ref relu q15 implementation\n");
|
||||
|
||||
arm_relu_q15_ref(relu_ref_data_q15, RELU_DIM);
|
||||
|
||||
printf("Start opt relu q15 implementation\n");
|
||||
|
||||
arm_relu_q15(relu_opt_data_q15, RELU_DIM);
|
||||
|
||||
verify_results_q15(relu_ref_data_q15, relu_opt_data_q15, RELU_DIM);
|
||||
|
||||
delete[]test1;
|
||||
delete[]test2;
|
||||
delete[]test3;
|
||||
delete[]test4;
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TEST_IP
|
||||
|
||||
#define IP_ROW_DIM 127
|
||||
#define IP_COL_DIM 127
|
||||
|
||||
q7_t ip_weights[IP_ROW_DIM * IP_COL_DIM] = IP2_WEIGHT;
|
||||
q7_t ip_q7_opt_weights[IP_ROW_DIM * IP_COL_DIM] = IP4_WEIGHT;
|
||||
q7_t ip_q7_q15_opt_weights[IP_ROW_DIM * IP_COL_DIM] = IP4_q7_q15_WEIGHT;
|
||||
q15_t ip_q15_weights[IP_ROW_DIM * IP_COL_DIM] = IP2_WEIGHT;
|
||||
q15_t ip_q15_opt_weights[IP_ROW_DIM * IP_COL_DIM] = IP4_WEIGHT_Q15;
|
||||
|
||||
test1 = new q7_t[IP_COL_DIM + IP_ROW_DIM];
|
||||
test2 = new q15_t[IP_COL_DIM];
|
||||
test3 = new q7_t[IP_ROW_DIM * 3];
|
||||
test4 = new q15_t[IP_COL_DIM + IP_ROW_DIM * 2];
|
||||
|
||||
for (int i = 0; i < IP_ROW_DIM + IP_COL_DIM; i++)
|
||||
{
|
||||
test1[i] = rand() % 256 - 100;
|
||||
}
|
||||
for (int i = 0; i < IP_ROW_DIM * 3; i++)
|
||||
{
|
||||
test3[i] = 0;
|
||||
}
|
||||
|
||||
q7_t *ip_bias_q7 = test1 + IP_COL_DIM;
|
||||
|
||||
q7_t *ip_out_q7_ref = test3;
|
||||
q7_t *ip_out_q7_opt = test3 + IP_ROW_DIM;
|
||||
q7_t *ip_out_q7_opt_fast = test3 + 2 * IP_ROW_DIM;
|
||||
q15_t *ip_out_q15_ref = test4 + IP_COL_DIM;
|
||||
q15_t *ip_out_q15_opt = test4 + IP_COL_DIM + IP_ROW_DIM;
|
||||
|
||||
initialize_results_q7(ip_out_q7_ref, ip_out_q7_opt, IP_ROW_DIM);
|
||||
initialize_results_q7(ip_out_q7_ref, ip_out_q7_opt_fast, IP_ROW_DIM);
|
||||
initialize_results_q7(ip_out_q7_ref, ip_out_q7_opt_fast, IP_ROW_DIM);
|
||||
|
||||
printf("Start ref q7 implementation\n");
|
||||
|
||||
arm_fully_connected_q7_ref(test1, ip_weights, IP_COL_DIM, IP_ROW_DIM, 1, 7, ip_bias_q7, ip_out_q7_ref, test2);
|
||||
|
||||
printf("Start q7 implementation\n");
|
||||
|
||||
arm_fully_connected_q7(test1, ip_weights, IP_COL_DIM, IP_ROW_DIM, 1, 7, ip_bias_q7, ip_out_q7_opt, test2);
|
||||
|
||||
verify_results_q7(ip_out_q7_ref, ip_out_q7_opt, IP_ROW_DIM);
|
||||
|
||||
printf("Start q7 ref opt implementation\n");
|
||||
|
||||
arm_fully_connected_q7_opt_ref(test1, ip_q7_opt_weights, IP_COL_DIM, IP_ROW_DIM, 1, 7, ip_bias_q7,
|
||||
ip_out_q7_opt_fast, test2);
|
||||
|
||||
verify_results_q7(ip_out_q7_ref, ip_out_q7_opt_fast, IP_ROW_DIM);
|
||||
|
||||
printf("Start q7 opt implementation\n");
|
||||
|
||||
arm_fully_connected_q7_opt(test1, ip_q7_opt_weights, IP_COL_DIM, IP_ROW_DIM, 1, 7, ip_bias_q7, ip_out_q7_opt_fast,
|
||||
test2);
|
||||
|
||||
verify_results_q7(ip_out_q7_ref, ip_out_q7_opt_fast, IP_ROW_DIM);
|
||||
|
||||
for (int i = 0; i < IP_ROW_DIM + IP_COL_DIM; i++)
|
||||
{
|
||||
test4[i] = (rand() % 65536 - 32768);
|
||||
}
|
||||
|
||||
initialize_results_q15(ip_out_q15_ref, ip_out_q15_opt, IP_ROW_DIM);
|
||||
|
||||
printf("Start ref q15 implementation\n");
|
||||
|
||||
arm_fully_connected_q15_ref(test4, ip_q15_weights, IP_COL_DIM, IP_ROW_DIM, 1, 7, test2, ip_out_q15_ref, NULL);
|
||||
|
||||
printf("Start q15 implementation\n");
|
||||
|
||||
arm_fully_connected_q15(test4, ip_q15_weights, IP_COL_DIM, IP_ROW_DIM, 1, 7, test2, ip_out_q15_opt, NULL);
|
||||
|
||||
verify_results_q15(ip_out_q15_ref, ip_out_q15_opt, IP_ROW_DIM);
|
||||
|
||||
printf("Start ref opt q15 implementation\n");
|
||||
|
||||
arm_fully_connected_q15_opt_ref(test4, ip_q15_opt_weights, IP_COL_DIM, IP_ROW_DIM, 1, 7, test2, ip_out_q15_opt,
|
||||
NULL);
|
||||
|
||||
verify_results_q15(ip_out_q15_ref, ip_out_q15_opt, IP_ROW_DIM);
|
||||
|
||||
printf("Start opt q15 implementation\n");
|
||||
|
||||
arm_fully_connected_q15_opt(test4, ip_q15_opt_weights, IP_COL_DIM, IP_ROW_DIM, 1, 7, test2, ip_out_q15_opt, NULL);
|
||||
|
||||
verify_results_q15(ip_out_q15_ref, ip_out_q15_opt, IP_ROW_DIM);
|
||||
|
||||
initialize_results_q15(ip_out_q15_ref, ip_out_q15_opt, IP_ROW_DIM);
|
||||
|
||||
printf("Start ref q7_q15 implementation\n");
|
||||
|
||||
arm_fully_connected_mat_q7_vec_q15_ref(test4, ip_weights, IP_COL_DIM, IP_ROW_DIM, 1, 7, ip_bias_q7, ip_out_q15_ref,
|
||||
test2);
|
||||
|
||||
printf("Start q7_q15 implementation\n");
|
||||
|
||||
arm_fully_connected_mat_q7_vec_q15(test4, ip_weights, IP_COL_DIM, IP_ROW_DIM, 1, 7, ip_bias_q7, ip_out_q15_opt,
|
||||
test2);
|
||||
|
||||
verify_results_q15(ip_out_q15_ref, ip_out_q15_opt, IP_ROW_DIM);
|
||||
|
||||
printf("Start ref opt q7_q15 implementation\n");
|
||||
|
||||
arm_fully_connected_mat_q7_vec_q15_opt_ref(test4, ip_q7_q15_opt_weights, IP_COL_DIM, IP_ROW_DIM, 1, 7, ip_bias_q7,
|
||||
ip_out_q15_opt, test2);
|
||||
|
||||
verify_results_q15(ip_out_q15_ref, ip_out_q15_opt, IP_ROW_DIM);
|
||||
|
||||
printf("Start opt q7_q15 implementation\n");
|
||||
|
||||
arm_fully_connected_mat_q7_vec_q15_opt(test4, ip_q7_q15_opt_weights, IP_COL_DIM, IP_ROW_DIM, 1, 7, ip_bias_q7,
|
||||
ip_out_q15_opt, test2);
|
||||
|
||||
verify_results_q15(ip_out_q15_ref, ip_out_q15_opt, IP_ROW_DIM);
|
||||
|
||||
delete[]test1;
|
||||
delete[]test2;
|
||||
delete[]test3;
|
||||
delete[]test4;
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TEST_NONSQUARE
|
||||
|
||||
/* Use RCONV to differential with square CONV */
|
||||
|
||||
#define RCONV_IM_DIM_X 10
|
||||
#define RCONV_IM_DIM_Y 8
|
||||
#define RCONV_IM_CH 4
|
||||
#define RCONV_KER_DIM_X 5
|
||||
#define RCONV_KER_DIM_Y 3
|
||||
#define RCONV_STRIDE_X 1
|
||||
#define RCONV_STRIDE_Y 1
|
||||
#define RCONV_PADDING_X 2
|
||||
#define RCONV_PADDING_Y 1
|
||||
#define RCONV_OUT_CH 4
|
||||
#define RCONV_OUT_DIM_X 10
|
||||
#define RCONV_OUT_DIM_Y 8
|
||||
|
||||
test1 = new q7_t[RCONV_KER_DIM_Y * RCONV_KER_DIM_X * RCONV_IM_CH * RCONV_OUT_CH + RCONV_OUT_CH];
|
||||
test2 = new q15_t[2 * RCONV_KER_DIM_Y * RCONV_KER_DIM_X * RCONV_IM_CH];
|
||||
test3 =
|
||||
new q7_t[RCONV_IM_DIM_Y * RCONV_IM_DIM_X * RCONV_IM_CH + 2 * RCONV_OUT_DIM_Y * RCONV_OUT_DIM_X * RCONV_OUT_CH];
|
||||
|
||||
for (int i = 0; i < RCONV_KER_DIM_Y * RCONV_KER_DIM_X * RCONV_IM_CH * RCONV_OUT_CH + RCONV_OUT_CH; i++)
|
||||
{
|
||||
test1[i] = rand() % 256 - 100;
|
||||
}
|
||||
|
||||
for (int i = 0;
|
||||
i < RCONV_IM_DIM_Y * RCONV_IM_DIM_X * RCONV_IM_CH + 2 * RCONV_OUT_DIM_Y * RCONV_OUT_DIM_X * RCONV_OUT_CH; i++)
|
||||
{
|
||||
test3[i] = rand() % 256 - 100;
|
||||
}
|
||||
|
||||
q7_t *rconv_weight_q7 = test1;
|
||||
q7_t *rconv_bias_q7 = test1 + RCONV_KER_DIM_Y * RCONV_KER_DIM_X * RCONV_IM_CH * RCONV_OUT_CH;
|
||||
|
||||
q15_t *rconv_buf = test2;
|
||||
|
||||
q7_t *rconv_im_in_q7 = test3;
|
||||
q7_t *rconv_im_out_ref_q7 = test3 + RCONV_IM_DIM_Y * RCONV_IM_DIM_X * RCONV_IM_CH;
|
||||
q7_t *rconv_im_out_opt_q7 =
|
||||
test3 + RCONV_IM_DIM_Y * RCONV_IM_DIM_X * RCONV_IM_CH + RCONV_OUT_DIM_Y * RCONV_OUT_DIM_X * RCONV_OUT_CH;
|
||||
|
||||
initialize_results_q7(rconv_im_out_ref_q7, rconv_im_out_opt_q7, RCONV_OUT_DIM_Y * RCONV_OUT_DIM_X * RCONV_OUT_CH);
|
||||
|
||||
printf("start conv q7 nonsquare ref implementation\n");
|
||||
arm_convolve_HWC_q7_ref_nonsquare(rconv_im_in_q7, RCONV_IM_DIM_X, RCONV_IM_DIM_Y, RCONV_IM_CH, rconv_weight_q7,
|
||||
RCONV_OUT_CH, RCONV_KER_DIM_X, RCONV_KER_DIM_Y, RCONV_PADDING_X, RCONV_PADDING_Y,
|
||||
RCONV_STRIDE_X, RCONV_STRIDE_Y, rconv_bias_q7, 1, 7, rconv_im_out_ref_q7,
|
||||
RCONV_OUT_DIM_X, RCONV_OUT_DIM_Y, rconv_buf, NULL);
|
||||
|
||||
printf("start conv q7 nonsquare opt implementation\n");
|
||||
arm_convolve_HWC_q7_fast_nonsquare(rconv_im_in_q7, RCONV_IM_DIM_X, RCONV_IM_DIM_Y, RCONV_IM_CH, rconv_weight_q7,
|
||||
RCONV_OUT_CH, RCONV_KER_DIM_X, RCONV_KER_DIM_Y, RCONV_PADDING_X, RCONV_PADDING_Y,
|
||||
RCONV_STRIDE_X, RCONV_STRIDE_Y, rconv_bias_q7, 1, 7, rconv_im_out_opt_q7,
|
||||
RCONV_OUT_DIM_X, RCONV_OUT_DIM_Y, rconv_buf, NULL);
|
||||
|
||||
verify_results_q7(rconv_im_out_ref_q7, rconv_im_out_opt_q7, RCONV_OUT_DIM_Y * RCONV_OUT_DIM_X * RCONV_OUT_CH);
|
||||
|
||||
initialize_results_q7(rconv_im_out_ref_q7, rconv_im_out_opt_q7, RCONV_OUT_DIM_Y * RCONV_OUT_DIM_X * RCONV_OUT_CH);
|
||||
|
||||
printf("start conv q7 nonsquare ref implementation\n");
|
||||
arm_convolve_HWC_q7_ref_nonsquare(rconv_im_in_q7, RCONV_IM_DIM_X, RCONV_IM_DIM_Y, RCONV_IM_CH, rconv_weight_q7,
|
||||
RCONV_OUT_CH, RCONV_KER_DIM_X, RCONV_KER_DIM_Y, RCONV_PADDING_X, RCONV_PADDING_Y,
|
||||
RCONV_STRIDE_X, RCONV_STRIDE_Y, rconv_bias_q7, 1, 7, rconv_im_out_ref_q7,
|
||||
RCONV_OUT_DIM_X, RCONV_OUT_DIM_Y, rconv_buf, NULL);
|
||||
|
||||
printf("start conv q7 nonsquare basic implementation\n");
|
||||
arm_convolve_HWC_q7_basic_nonsquare(rconv_im_in_q7, RCONV_IM_DIM_X, RCONV_IM_DIM_Y, RCONV_IM_CH, rconv_weight_q7,
|
||||
RCONV_OUT_CH, RCONV_KER_DIM_X, RCONV_KER_DIM_Y, RCONV_PADDING_X, RCONV_PADDING_Y,
|
||||
RCONV_STRIDE_X, RCONV_STRIDE_Y, rconv_bias_q7, 1, 7, rconv_im_out_opt_q7,
|
||||
RCONV_OUT_DIM_X, RCONV_OUT_DIM_Y, rconv_buf, NULL);
|
||||
|
||||
verify_results_q7(rconv_im_out_ref_q7, rconv_im_out_opt_q7, RCONV_OUT_DIM_Y * RCONV_OUT_DIM_X * RCONV_OUT_CH);
|
||||
|
||||
initialize_results_q7(rconv_im_out_ref_q7, rconv_im_out_opt_q7, RCONV_OUT_DIM_Y * RCONV_OUT_DIM_X * RCONV_OUT_CH);
|
||||
|
||||
printf("start 1x1 conv q7 nonsquare fast implementation\n");
|
||||
arm_convolve_HWC_q7_fast_nonsquare(rconv_im_in_q7, RCONV_IM_DIM_X, RCONV_IM_DIM_Y, RCONV_IM_CH, rconv_weight_q7,
|
||||
RCONV_OUT_CH, 1, 1, 0, 0, RCONV_STRIDE_X,
|
||||
RCONV_STRIDE_Y, rconv_bias_q7, 1, 7, rconv_im_out_ref_q7, RCONV_OUT_DIM_X,
|
||||
RCONV_OUT_DIM_Y, rconv_buf, NULL);
|
||||
|
||||
printf("start 1x1 conv q7 nonsquare dedicated function implementation\n");
|
||||
arm_convolve_1x1_HWC_q7_fast_nonsquare(rconv_im_in_q7, RCONV_IM_DIM_X, RCONV_IM_DIM_Y, RCONV_IM_CH, rconv_weight_q7,
|
||||
RCONV_OUT_CH, 1, 1, 0, 0, RCONV_STRIDE_X,
|
||||
RCONV_STRIDE_Y, rconv_bias_q7, 1, 7, rconv_im_out_opt_q7, RCONV_OUT_DIM_X,
|
||||
RCONV_OUT_DIM_Y, rconv_buf, NULL);
|
||||
|
||||
verify_results_q7(rconv_im_out_ref_q7, rconv_im_out_opt_q7, RCONV_OUT_DIM_Y * RCONV_OUT_DIM_X * RCONV_OUT_CH);
|
||||
|
||||
printf("start depthwise separable conv q7 nonsquare ref implementation\n");
|
||||
arm_depthwise_separable_conv_HWC_q7_ref_nonsquare(rconv_im_in_q7, RCONV_IM_DIM_X, RCONV_IM_DIM_Y, RCONV_IM_CH,
|
||||
rconv_weight_q7, RCONV_OUT_CH, RCONV_KER_DIM_X, RCONV_KER_DIM_Y,
|
||||
RCONV_PADDING_X, RCONV_PADDING_Y, RCONV_STRIDE_X, RCONV_STRIDE_Y,
|
||||
rconv_bias_q7, 1, 7, rconv_im_out_ref_q7, RCONV_OUT_DIM_X,
|
||||
RCONV_OUT_DIM_Y, rconv_buf, NULL);
|
||||
|
||||
printf("start depthwise separable conv q7 nonsquare opt implementation\n");
|
||||
arm_depthwise_separable_conv_HWC_q7_nonsquare(rconv_im_in_q7, RCONV_IM_DIM_X, RCONV_IM_DIM_Y, RCONV_IM_CH,
|
||||
rconv_weight_q7, RCONV_OUT_CH, RCONV_KER_DIM_X, RCONV_KER_DIM_Y,
|
||||
RCONV_PADDING_X, RCONV_PADDING_Y, RCONV_STRIDE_X, RCONV_STRIDE_Y,
|
||||
rconv_bias_q7, 1, 7, rconv_im_out_opt_q7, RCONV_OUT_DIM_X,
|
||||
RCONV_OUT_DIM_Y, rconv_buf, NULL);
|
||||
|
||||
verify_results_q7(rconv_im_out_ref_q7, rconv_im_out_opt_q7, RCONV_OUT_DIM_Y * RCONV_OUT_DIM_X * RCONV_OUT_CH);
|
||||
|
||||
delete[]test1;
|
||||
delete[]test2;
|
||||
delete[]test3;
|
||||
|
||||
test2 = new q15_t[RCONV_KER_DIM_Y * RCONV_KER_DIM_X * RCONV_IM_CH * RCONV_OUT_CH + RCONV_OUT_CH]; // weights + bias
|
||||
test4 = new q15_t[2 * RCONV_KER_DIM_Y * RCONV_KER_DIM_X * RCONV_IM_CH //buffer
|
||||
+ RCONV_IM_DIM_Y * RCONV_IM_DIM_X * RCONV_IM_CH + 2 * RCONV_OUT_DIM_Y * RCONV_OUT_DIM_X * RCONV_OUT_CH]; // i/o
|
||||
|
||||
for (int i = 0; i < RCONV_KER_DIM_Y * RCONV_KER_DIM_X * RCONV_IM_CH * RCONV_OUT_CH + RCONV_OUT_CH; i++)
|
||||
{
|
||||
test2[i] = rand() % 256 - 100;
|
||||
}
|
||||
|
||||
for (int i = 0;
|
||||
i < 2 * RCONV_KER_DIM_Y * RCONV_KER_DIM_X * RCONV_IM_CH
|
||||
+ RCONV_IM_DIM_Y * RCONV_IM_DIM_X * RCONV_IM_CH + 2 * RCONV_OUT_DIM_Y * RCONV_OUT_DIM_X * RCONV_OUT_CH;
|
||||
i++)
|
||||
{
|
||||
test4[i] = rand() % 256 - 100;
|
||||
}
|
||||
|
||||
q15_t *rconv_weight_q15 = test2;
|
||||
q15_t *rconv_bias_q15 = test2 + RCONV_KER_DIM_Y * RCONV_KER_DIM_X * RCONV_IM_CH * RCONV_OUT_CH;
|
||||
|
||||
rconv_buf = test4;
|
||||
|
||||
q15_t *rconv_im_in_q15 = test4 + 2 * RCONV_KER_DIM_Y * RCONV_KER_DIM_X * RCONV_IM_CH;
|
||||
q15_t *rconv_im_out_ref_q15 = rconv_im_in_q15 + RCONV_IM_DIM_Y * RCONV_IM_DIM_X * RCONV_IM_CH;
|
||||
q15_t *rconv_im_out_opt_q15 = rconv_im_out_ref_q15 + RCONV_OUT_DIM_Y * RCONV_OUT_DIM_X * RCONV_OUT_CH;
|
||||
|
||||
initialize_results_q15(rconv_im_out_ref_q15, rconv_im_out_opt_q15, RCONV_OUT_DIM_Y * RCONV_OUT_DIM_X * RCONV_OUT_CH);
|
||||
|
||||
printf("start conv q15 nonsquare ref implementation\n");
|
||||
arm_convolve_HWC_q15_nonsquare_ref(rconv_im_in_q15, RCONV_IM_DIM_X, RCONV_IM_DIM_Y, RCONV_IM_CH, rconv_weight_q15,
|
||||
RCONV_OUT_CH, RCONV_KER_DIM_X, RCONV_KER_DIM_Y, RCONV_PADDING_X, RCONV_PADDING_Y,
|
||||
RCONV_STRIDE_X, RCONV_STRIDE_Y, rconv_bias_q15, 1, 7, rconv_im_out_ref_q15,
|
||||
RCONV_OUT_DIM_X, RCONV_OUT_DIM_Y, rconv_buf, NULL);
|
||||
|
||||
printf("start conv q5 nonsquare opt implementation\n");
|
||||
arm_convolve_HWC_q15_fast_nonsquare(rconv_im_in_q15, RCONV_IM_DIM_X, RCONV_IM_DIM_Y, RCONV_IM_CH, rconv_weight_q15,
|
||||
RCONV_OUT_CH, RCONV_KER_DIM_X, RCONV_KER_DIM_Y, RCONV_PADDING_X, RCONV_PADDING_Y,
|
||||
RCONV_STRIDE_X, RCONV_STRIDE_Y, rconv_bias_q15, 1, 7, rconv_im_out_opt_q15,
|
||||
RCONV_OUT_DIM_X, RCONV_OUT_DIM_Y, rconv_buf, NULL);
|
||||
|
||||
verify_results_q15(rconv_im_out_ref_q15, rconv_im_out_opt_q15, RCONV_OUT_DIM_Y * RCONV_OUT_DIM_X * RCONV_OUT_CH);
|
||||
|
||||
delete [] test2;
|
||||
delete [] test4;
|
||||
#endif
|
||||
|
||||
#ifdef TEST_CONV
|
||||
|
||||
#define CONV_IM_DIM 16
|
||||
#define CONV_IM_CH 16
|
||||
#define CONV_KER_DIM 5
|
||||
#define CONV_OUT_CH 16
|
||||
#define CONV_OUT_DIM 16
|
||||
|
||||
test1 = new q7_t[CONV_KER_DIM * CONV_KER_DIM * CONV_IM_CH * CONV_OUT_CH + CONV_OUT_CH];
|
||||
test2 =
|
||||
new q15_t[CONV_KER_DIM * CONV_KER_DIM * CONV_IM_CH * CONV_OUT_CH +
|
||||
2 * CONV_KER_DIM * CONV_KER_DIM * CONV_IM_CH * CONV_OUT_CH + CONV_OUT_CH];
|
||||
test3 = new q7_t[CONV_IM_DIM * CONV_IM_DIM * CONV_IM_CH + 2 * CONV_OUT_DIM * CONV_OUT_DIM * CONV_OUT_CH];
|
||||
test4 = new q15_t[CONV_IM_DIM * CONV_IM_DIM * CONV_IM_CH + 2 * CONV_OUT_DIM * CONV_OUT_DIM * CONV_OUT_CH];
|
||||
|
||||
for (int i = 0; i < CONV_KER_DIM * CONV_KER_DIM * CONV_IM_CH * CONV_OUT_CH + CONV_OUT_CH; i++)
|
||||
{
|
||||
test1[i] = rand() % 256 - 100;
|
||||
}
|
||||
|
||||
for (int i = 0;
|
||||
i <
|
||||
CONV_KER_DIM * CONV_KER_DIM * CONV_IM_CH * CONV_OUT_CH +
|
||||
2 * CONV_KER_DIM * CONV_KER_DIM * CONV_IM_CH * CONV_OUT_CH + CONV_OUT_CH; i++)
|
||||
{
|
||||
test2[i] = (rand() % 65536 - 32768);
|
||||
}
|
||||
|
||||
for (int i = 0; i < CONV_IM_DIM * CONV_IM_DIM * CONV_IM_CH + 2 * CONV_OUT_DIM * CONV_OUT_DIM * CONV_OUT_CH; i++)
|
||||
{
|
||||
test3[i] = rand() % 256 - 100;
|
||||
}
|
||||
|
||||
for (int i = 0; i < CONV_IM_DIM * CONV_IM_DIM * CONV_IM_CH + 2 * CONV_OUT_DIM * CONV_OUT_DIM * CONV_OUT_CH; i++)
|
||||
{
|
||||
test4[i] = (rand() % 65536 - 32768);
|
||||
}
|
||||
|
||||
q7_t *conv_weight_q7 = test1;
|
||||
q7_t *conv_bias_q7 = test1 + CONV_KER_DIM * CONV_KER_DIM * CONV_IM_CH * CONV_OUT_CH;
|
||||
|
||||
q15_t *conv_weight_q15 = test2;
|
||||
q15_t *conv_buf = test2 + CONV_KER_DIM * CONV_KER_DIM * CONV_IM_CH * CONV_OUT_CH;
|
||||
q15_t *conv_bias_q15 =
|
||||
test2 + CONV_KER_DIM * CONV_KER_DIM * CONV_IM_CH * CONV_OUT_CH +
|
||||
2 * CONV_KER_DIM * CONV_KER_DIM * CONV_IM_CH * CONV_OUT_CH;
|
||||
|
||||
q7_t *conv_im_in_q7 = test3;
|
||||
q7_t *conv_im_out_ref_q7 = test3 + CONV_IM_DIM * CONV_IM_DIM * CONV_IM_CH;
|
||||
q7_t *conv_im_out_opt_q7 =
|
||||
test3 + CONV_IM_DIM * CONV_IM_DIM * CONV_IM_CH + CONV_OUT_DIM * CONV_OUT_DIM * CONV_OUT_CH;
|
||||
|
||||
q15_t *conv_im_in_q15 = test4;
|
||||
q15_t *conv_im_out_ref_q15 = test4 + CONV_IM_DIM * CONV_IM_DIM * CONV_IM_CH;
|
||||
q15_t *conv_im_out_opt_q15 =
|
||||
test4 + CONV_IM_DIM * CONV_IM_DIM * CONV_IM_CH + CONV_OUT_DIM * CONV_OUT_DIM * CONV_OUT_CH;
|
||||
|
||||
initialize_results_q7(conv_im_out_ref_q7, conv_im_out_opt_q7, CONV_OUT_DIM * CONV_OUT_DIM * CONV_OUT_CH);
|
||||
|
||||
printf("start q7 ref implementation\n");
|
||||
|
||||
arm_convolve_HWC_q7_ref(conv_im_in_q7, CONV_IM_DIM, CONV_IM_CH, conv_weight_q7,
|
||||
CONV_OUT_CH, CONV_KER_DIM, 2, 1, conv_bias_q7, 1, 7, conv_im_out_ref_q7,
|
||||
CONV_OUT_DIM, conv_buf, NULL);
|
||||
|
||||
printf("start q7 basic implementation\n");
|
||||
|
||||
arm_convolve_HWC_q7_basic(conv_im_in_q7, CONV_IM_DIM, CONV_IM_CH, conv_weight_q7,
|
||||
CONV_OUT_CH, CONV_KER_DIM, 2, 1, conv_bias_q7, 1, 7, conv_im_out_opt_q7,
|
||||
CONV_OUT_DIM, conv_buf, NULL);
|
||||
|
||||
verify_results_q7(conv_im_out_ref_q7, conv_im_out_opt_q7, CONV_OUT_DIM * CONV_OUT_DIM * CONV_OUT_CH);
|
||||
|
||||
printf("start q7 fast implementation\n");
|
||||
|
||||
arm_convolve_HWC_q7_fast(conv_im_in_q7, CONV_IM_DIM, CONV_IM_CH, conv_weight_q7,
|
||||
CONV_OUT_CH, CONV_KER_DIM, 2, 1, conv_bias_q7, 1, 7, conv_im_out_opt_q7,
|
||||
CONV_OUT_DIM, conv_buf, NULL);
|
||||
|
||||
verify_results_q7(conv_im_out_ref_q7, conv_im_out_opt_q7, CONV_OUT_DIM * CONV_OUT_DIM * CONV_OUT_CH);
|
||||
|
||||
// testing with RGB
|
||||
printf("start q7 ref implementation for RGB\n");
|
||||
|
||||
arm_convolve_HWC_q7_ref(conv_im_in_q7, CONV_IM_DIM, 3, conv_weight_q7,
|
||||
CONV_OUT_CH, CONV_KER_DIM, 2, 1, conv_bias_q7, 1, 7, conv_im_out_ref_q7,
|
||||
CONV_OUT_DIM, conv_buf, NULL);
|
||||
|
||||
printf("start q7 basic implementation for RGB\n");
|
||||
|
||||
arm_convolve_HWC_q7_basic(conv_im_in_q7, CONV_IM_DIM, 3, conv_weight_q7,
|
||||
CONV_OUT_CH, CONV_KER_DIM, 2, 1, conv_bias_q7, 1, 7, conv_im_out_opt_q7,
|
||||
CONV_OUT_DIM, conv_buf, NULL);
|
||||
|
||||
verify_results_q7(conv_im_out_ref_q7, conv_im_out_opt_q7, CONV_OUT_DIM * CONV_OUT_DIM * CONV_OUT_CH);
|
||||
|
||||
printf("start q7 RGB implementation for RGB\n");
|
||||
|
||||
arm_convolve_HWC_q7_RGB(conv_im_in_q7, CONV_IM_DIM, 3, conv_weight_q7,
|
||||
CONV_OUT_CH, CONV_KER_DIM, 2, 1, conv_bias_q7, 1, 7, conv_im_out_opt_q7,
|
||||
CONV_OUT_DIM, conv_buf, NULL);
|
||||
|
||||
verify_results_q7(conv_im_out_ref_q7, conv_im_out_opt_q7, CONV_OUT_DIM * CONV_OUT_DIM * CONV_OUT_CH);
|
||||
|
||||
// testing q15
|
||||
initialize_results_q15(conv_im_out_ref_q15, conv_im_out_opt_q15, CONV_OUT_DIM * CONV_OUT_DIM * CONV_OUT_CH);
|
||||
|
||||
printf("start q15 ref implementation\n");
|
||||
|
||||
arm_convolve_HWC_q15_ref(conv_im_in_q15, CONV_IM_DIM, CONV_IM_CH, conv_weight_q15,
|
||||
CONV_OUT_CH, CONV_KER_DIM, 2, 1, conv_bias_q15, 0, 15, conv_im_out_ref_q15,
|
||||
CONV_OUT_DIM, conv_buf, NULL);
|
||||
|
||||
printf("start q15 basic implementation\n");
|
||||
|
||||
arm_convolve_HWC_q15_basic(conv_im_in_q15, CONV_IM_DIM, CONV_IM_CH, conv_weight_q15,
|
||||
CONV_OUT_CH, CONV_KER_DIM, 2, 1, conv_bias_q15, 0, 15, conv_im_out_opt_q15,
|
||||
CONV_OUT_DIM, conv_buf, NULL);
|
||||
|
||||
verify_results_q15(conv_im_out_ref_q15, conv_im_out_opt_q15, CONV_OUT_DIM * CONV_OUT_DIM * CONV_OUT_CH);
|
||||
|
||||
printf("start q15 fast implementation\n");
|
||||
|
||||
arm_convolve_HWC_q15_fast(conv_im_in_q15, CONV_IM_DIM, CONV_IM_CH, conv_weight_q15,
|
||||
CONV_OUT_CH, CONV_KER_DIM, 2, 1, conv_bias_q15, 0, 15, conv_im_out_opt_q15,
|
||||
CONV_OUT_DIM, conv_buf, NULL);
|
||||
|
||||
verify_results_q15(conv_im_out_ref_q15, conv_im_out_opt_q15, CONV_OUT_DIM * CONV_OUT_DIM * CONV_OUT_CH);
|
||||
|
||||
// depthwise separable conv
|
||||
initialize_results_q7(conv_im_out_ref_q7, conv_im_out_opt_q7, CONV_OUT_DIM * CONV_OUT_DIM * CONV_OUT_CH);
|
||||
|
||||
printf("start q7 depthwise_separable_conv ref implementation\n");
|
||||
|
||||
arm_depthwise_separable_conv_HWC_q7_ref(conv_im_in_q7, CONV_IM_DIM, CONV_IM_CH, conv_weight_q7,
|
||||
CONV_OUT_CH, CONV_KER_DIM, 2, 1, conv_bias_q7, 1, 7, conv_im_out_ref_q7,
|
||||
CONV_OUT_DIM, conv_buf, NULL);
|
||||
|
||||
printf("start q7 depthwise_separable_conv implementation\n");
|
||||
|
||||
arm_depthwise_separable_conv_HWC_q7(conv_im_in_q7, CONV_IM_DIM, CONV_IM_CH, conv_weight_q7,
|
||||
CONV_OUT_CH, CONV_KER_DIM, 2, 1, conv_bias_q7, 1, 7, conv_im_out_opt_q7,
|
||||
CONV_OUT_DIM, conv_buf, NULL);
|
||||
|
||||
verify_results_q7(conv_im_out_ref_q7, conv_im_out_opt_q7, CONV_OUT_DIM * CONV_OUT_DIM * CONV_OUT_CH);
|
||||
|
||||
delete[]test1;
|
||||
delete[]test2;
|
||||
delete[]test3;
|
||||
delete[]test4;
|
||||
|
||||
#endif
|
||||
|
||||
test_pass = true;
|
||||
test_index = 0;
|
||||
while (test_flags[test_index] != -1) {
|
||||
if (test_flags[test_index]) {
|
||||
test_pass = false;
|
||||
}
|
||||
test_index ++;
|
||||
}
|
||||
if (test_pass) {
|
||||
printf("All tests passed\n");
|
||||
} else {
|
||||
printf("Test failed passed\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
#ifndef _MAIN_H_
|
||||
#define _MAIN_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
#include "arm_nnfunctions.h"
|
||||
#include "ref_functions.h"
|
||||
|
||||
extern int test_index;
|
||||
extern q7_t test_flags[50];
|
||||
|
||||
void initialize_results_q7(q7_t * ref, q7_t * opt, int length)
|
||||
{
|
||||
arm_fill_q7(0, ref, length);
|
||||
arm_fill_q7(37, opt, length);
|
||||
}
|
||||
|
||||
void initialize_results_q15(q15_t * ref, q15_t * opt, int length)
|
||||
{
|
||||
arm_fill_q15(0, ref, length);
|
||||
arm_fill_q15(0x5F5, opt, length);
|
||||
}
|
||||
|
||||
void verify_results_q7(q7_t * ref, q7_t * opt, int length)
|
||||
{
|
||||
|
||||
bool if_match = true;
|
||||
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
if (ref[i] != opt[i])
|
||||
{
|
||||
printf("Output mismatch at %d, expected %d, actual %d\r\n", i, ref[i], opt[i]);
|
||||
|
||||
if_match = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (if_match == true)
|
||||
{
|
||||
printf("Outputs match.\r\n\r\n");
|
||||
test_flags[test_index++] = 0;
|
||||
} else {
|
||||
test_flags[test_index++] = 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void verify_results_q15(q15_t * ref, q15_t * opt, int length)
|
||||
{
|
||||
|
||||
bool if_match = true;
|
||||
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
if (ref[i] != opt[i])
|
||||
{
|
||||
printf("Output mismatch at %d, expected %d, actual %d\r\n", i, ref[i], opt[i]);
|
||||
|
||||
if_match = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (if_match == true)
|
||||
{
|
||||
printf("Outputs match.\r\n\r\n");
|
||||
test_flags[test_index++] = 0;
|
||||
} else {
|
||||
test_flags[test_index++] = 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,4 @@
|
||||
CMSIS DSP_Lib example arm_nnexample_nn_test for
|
||||
Cortex-M3, Cortex-M4 and Cortex-M7.
|
||||
|
||||
The example is configured for uVision Simulator.
|
@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Project: CMSIS NN Library
|
||||
* Title: arm_nn_activations_q15.c
|
||||
* Description: Q15 neural network activation function using direct table look-up
|
||||
*
|
||||
* $Date: 17. January 2018
|
||||
* $Revision: V.1.0.0
|
||||
*
|
||||
* Target Processor: Cortex-M cores
|
||||
*
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
#include "arm_common_tables.h"
|
||||
#include "arm_nnfunctions.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupNN
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup Acti
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Q15 neural network activation function using direct table look-up
|
||||
* @param[in,out] data pointer to input
|
||||
* @param[in] size number of elements
|
||||
* @param[in] int_width bit-width of the integer part, assume to be smaller than 3
|
||||
* @param[in] type type of activation functions
|
||||
* @return none.
|
||||
*
|
||||
* @details
|
||||
*
|
||||
* This is the direct table look-up approach.
|
||||
*
|
||||
* Assume here the integer part of the fixed-point is <= 3.
|
||||
* More than 3 just not making much sense, makes no difference with
|
||||
* saturation followed by any of these activation functions.
|
||||
*/
|
||||
|
||||
void arm_nn_activations_direct_q15(q15_t * data, uint16_t size, uint16_t int_width, arm_nn_activation_type type)
|
||||
{
|
||||
uint16_t i = size;
|
||||
q15_t *pIn = data;
|
||||
q15_t *pOut = data;
|
||||
uint16_t shift_size = 8 + 3 - int_width;
|
||||
uint32_t bit_mask = 0x7FF >> int_width;
|
||||
uint32_t full_frac = bit_mask + 1;
|
||||
const q15_t *lookup_table;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case ARM_SIGMOID:
|
||||
lookup_table = sigmoidTable_q15;
|
||||
break;
|
||||
case ARM_TANH:
|
||||
default:
|
||||
lookup_table = tanhTable_q15;
|
||||
break;
|
||||
}
|
||||
|
||||
while (i)
|
||||
{
|
||||
q15_t out;
|
||||
q15_t in = *pIn++;
|
||||
q15_t frac = (uint32_t) in & bit_mask;
|
||||
q15_t value = lookup_table[__USAT(in >> shift_size, 8)];
|
||||
q15_t value2 = lookup_table[__USAT(1 + (in >> shift_size), 8)];
|
||||
|
||||
/* doing the interpolation here for better accuracy */
|
||||
out = ((q31_t) (full_frac - frac) * value + (q31_t) value2 * frac) >> shift_size;
|
||||
|
||||
*pOut++ = out;
|
||||
i--;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of Acti group
|
||||
*/
|
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Project: CMSIS NN Library
|
||||
* Title: arm_nn_activations_q7.c
|
||||
* Description: Q7 neural network activation function using direct table look-up
|
||||
*
|
||||
* $Date: 17. January 2018
|
||||
* $Revision: V.1.0.0
|
||||
*
|
||||
* Target Processor: Cortex-M cores
|
||||
*
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
#include "arm_common_tables.h"
|
||||
#include "arm_nnfunctions.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupNN
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup Acti
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Q7 neural network activation function using direct table look-up
|
||||
* @param[in,out] data pointer to input
|
||||
* @param[in] size number of elements
|
||||
* @param[in] int_width bit-width of the integer part, assume to be smaller than 3
|
||||
* @param[in] type type of activation functions
|
||||
* @return none.
|
||||
*
|
||||
* @details
|
||||
*
|
||||
* This is the direct table look-up approach.
|
||||
*
|
||||
* Assume here the integer part of the fixed-point is <= 3.
|
||||
* More than 3 just not making much sense, makes no difference with
|
||||
* saturation followed by any of these activation functions.
|
||||
*/
|
||||
|
||||
void arm_nn_activations_direct_q7(q7_t * data, uint16_t size, uint16_t int_width, arm_nn_activation_type type)
|
||||
{
|
||||
uint16_t i = size;
|
||||
q7_t *pIn = data;
|
||||
q7_t *pOut = data;
|
||||
q7_t in;
|
||||
q7_t out;
|
||||
uint16_t shift_size = 3 - int_width;
|
||||
const q7_t *lookup_table;
|
||||
switch (type)
|
||||
{
|
||||
case ARM_SIGMOID:
|
||||
lookup_table = sigmoidTable_q7;
|
||||
break;
|
||||
case ARM_TANH:
|
||||
default:
|
||||
lookup_table = tanhTable_q7;
|
||||
break;
|
||||
}
|
||||
while (i)
|
||||
{
|
||||
in = *pIn++;
|
||||
out = lookup_table[(uint8_t) (in >> shift_size)];
|
||||
*pOut++ = out;
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of Acti group
|
||||
*/
|
@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Project: CMSIS NN Library
|
||||
* Title: arm_relu_q15.c
|
||||
* Description: Q15 version of ReLU
|
||||
*
|
||||
* $Date: 17. January 2018
|
||||
* $Revision: V.1.0.0
|
||||
*
|
||||
* Target Processor: Cortex-M cores
|
||||
*
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
#include "arm_nnfunctions.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupNN
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup Acti
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Q15 RELU function
|
||||
* @param[in,out] data pointer to input
|
||||
* @param[in] size number of elements
|
||||
* @return none.
|
||||
*
|
||||
* @details
|
||||
*
|
||||
* Optimized relu with QSUB instructions.
|
||||
*
|
||||
*/
|
||||
|
||||
void arm_relu_q15(q15_t * data, uint16_t size)
|
||||
{
|
||||
|
||||
#if defined (ARM_MATH_DSP)
|
||||
/* Run the following code for Cortex-M4 and Cortex-M7 */
|
||||
|
||||
uint16_t i = size >> 1;
|
||||
q15_t *pIn = data;
|
||||
q15_t *pOut = data;
|
||||
q31_t in;
|
||||
q31_t buf;
|
||||
q31_t mask;
|
||||
|
||||
while (i)
|
||||
{
|
||||
in = *__SIMD32(pIn)++;
|
||||
|
||||
/* extract the first bit */
|
||||
buf = __ROR(in & 0x80008000, 15);
|
||||
|
||||
/* if MSB=1, mask will be 0xFF, 0x0 otherwise */
|
||||
mask = __QSUB16(0x00000000, buf);
|
||||
|
||||
*__SIMD32(pOut)++ = in & (~mask);
|
||||
i--;
|
||||
}
|
||||
|
||||
if (size & 0x1)
|
||||
{
|
||||
if (*pIn < 0)
|
||||
{
|
||||
*pIn = 0;
|
||||
}
|
||||
pIn++;
|
||||
}
|
||||
#else
|
||||
/* Run the following code as reference implementation for Cortex-M0 and Cortex-M3 */
|
||||
uint16_t i;
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
if (data[i] < 0)
|
||||
data[i] = 0;
|
||||
}
|
||||
|
||||
#endif /* ARM_MATH_DSP */
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of Acti group
|
||||
*/
|
@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Project: CMSIS NN Library
|
||||
* Title: arm_relu_q7.c
|
||||
* Description: Q7 version of ReLU
|
||||
*
|
||||
* $Date: 17. January 2018
|
||||
* $Revision: V.1.0.0
|
||||
*
|
||||
* Target Processor: Cortex-M cores
|
||||
*
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
#include "arm_nnfunctions.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupNN
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup Acti
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Q7 RELU function
|
||||
* @param[in,out] data pointer to input
|
||||
* @param[in] size number of elements
|
||||
* @return none.
|
||||
*
|
||||
* @details
|
||||
*
|
||||
* Optimized relu with QSUB instructions.
|
||||
*
|
||||
*/
|
||||
|
||||
void arm_relu_q7(q7_t * data, uint16_t size)
|
||||
{
|
||||
|
||||
#if defined (ARM_MATH_DSP)
|
||||
/* Run the following code for Cortex-M4 and Cortex-M7 */
|
||||
|
||||
uint16_t i = size >> 2;
|
||||
q7_t *pIn = data;
|
||||
q7_t *pOut = data;
|
||||
q31_t in;
|
||||
q31_t buf;
|
||||
q31_t mask;
|
||||
|
||||
while (i)
|
||||
{
|
||||
in = *__SIMD32(pIn)++;
|
||||
|
||||
/* extract the first bit */
|
||||
buf = __ROR(in & 0x80808080, 7);
|
||||
|
||||
/* if MSB=1, mask will be 0xFF, 0x0 otherwise */
|
||||
mask = __QSUB8(0x00000000, buf);
|
||||
|
||||
*__SIMD32(pOut)++ = in & (~mask);
|
||||
i--;
|
||||
}
|
||||
|
||||
i = size & 0x3;
|
||||
while (i)
|
||||
{
|
||||
if (*pIn < 0)
|
||||
{
|
||||
*pIn = 0;
|
||||
}
|
||||
pIn++;
|
||||
i--;
|
||||
}
|
||||
|
||||
#else
|
||||
/* Run the following code as reference implementation for Cortex-M0 and Cortex-M3 */
|
||||
|
||||
uint16_t i;
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
if (data[i] < 0)
|
||||
data[i] = 0;
|
||||
}
|
||||
|
||||
#endif /* ARM_MATH_DSP */
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of Acti group
|
||||
*/
|
@ -0,0 +1,235 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Project: CMSIS NN Library
|
||||
* Title: arm_convolve_1x1_HWC_q7_fast_nonsquare.c
|
||||
* Description: Fast Q7 version of 1x1 convolution (non-square shape)
|
||||
*
|
||||
* $Date: 17. January 2018
|
||||
* $Revision: V.1.0.0
|
||||
*
|
||||
* Target Processor: Cortex-M cores
|
||||
*
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
#include "arm_nnfunctions.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupNN
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup NNConv
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Fast Q7 version of 1x1 convolution (non-sqaure shape)
|
||||
* @param[in] Im_in pointer to input tensor
|
||||
* @param[in] dim_im_in_x input tensor dimention x
|
||||
* @param[in] dim_im_in_y input tensor dimention y
|
||||
* @param[in] ch_im_in number of input tensor channels
|
||||
* @param[in] wt pointer to kernel weights
|
||||
* @param[in] ch_im_out number of filters, i.e., output tensor channels
|
||||
* @param[in] dim_kernel_x filter kernel size x
|
||||
* @param[in] dim_kernel_y filter kernel size y
|
||||
* @param[in] padding_x padding size x
|
||||
* @param[in] padding_y padding size y
|
||||
* @param[in] stride_x convolution stride x
|
||||
* @param[in] stride_y convolution stride y
|
||||
* @param[in] bias pointer to bias
|
||||
* @param[in] bias_shift amount of left-shift for bias
|
||||
* @param[in] out_shift amount of right-shift for output
|
||||
* @param[in,out] Im_out pointer to output tensor
|
||||
* @param[in] dim_im_out_x output tensor dimension x
|
||||
* @param[in] dim_im_out_y output tensor dimension y
|
||||
* @param[in,out] bufferA pointer to buffer space for input
|
||||
* @param[in,out] bufferB pointer to buffer space for output
|
||||
* @return The function returns either
|
||||
* <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
|
||||
*
|
||||
* This function is optimized for convolution with 1x1 kernel size (i.e., dim_kernel_x=1
|
||||
* and dim_kernel_y=1). It can be used for the second half of MobileNets [1] after depthwise
|
||||
* separable convolution.
|
||||
*
|
||||
* This function is the version with full list of optimization tricks, but with
|
||||
* some contraints:
|
||||
* ch_im_in is multiple of 4
|
||||
* ch_im_out is multiple of 2
|
||||
*
|
||||
* [1] MobileNets: Efficient Convolutional Neural Networks for Mobile Vision Applications
|
||||
* https://arxiv.org/abs/1704.04861
|
||||
*/
|
||||
|
||||
arm_status arm_convolve_1x1_HWC_q7_fast_nonsquare(const q7_t * Im_in,
|
||||
const uint16_t dim_im_in_x,
|
||||
const uint16_t dim_im_in_y,
|
||||
const uint16_t ch_im_in,
|
||||
const q7_t * wt,
|
||||
const uint16_t ch_im_out,
|
||||
const uint16_t dim_kernel_x,
|
||||
const uint16_t dim_kernel_y,
|
||||
const uint16_t padding_x,
|
||||
const uint16_t padding_y,
|
||||
const uint16_t stride_x,
|
||||
const uint16_t stride_y,
|
||||
const q7_t * bias,
|
||||
const uint16_t bias_shift,
|
||||
const uint16_t out_shift,
|
||||
q7_t * Im_out,
|
||||
const uint16_t dim_im_out_x,
|
||||
const uint16_t dim_im_out_y,
|
||||
q15_t * bufferA,
|
||||
q7_t * bufferB)
|
||||
{
|
||||
|
||||
#if defined (ARM_MATH_DSP)
|
||||
/* Run the following code for Cortex-M4 and Cortex-M7 */
|
||||
|
||||
int16_t i_out_y, i_out_x;
|
||||
int16_t i_ch_out;
|
||||
|
||||
/* -----------------------
|
||||
* Here we use bufferA as q15_t internally as computation are done with q15_t level
|
||||
* im2col are done to output in q15_t format from q7_t input
|
||||
*/
|
||||
|
||||
q15_t *pBuffer = bufferA;
|
||||
q7_t *pOut = Im_out;
|
||||
|
||||
if (ch_im_in % 4 != 0 || ch_im_out % 2 != 0 || dim_kernel_x != 1 || dim_kernel_y != 1
|
||||
|| padding_x != 0 || padding_y != 0 || stride_x != 1 || stride_y != 1)
|
||||
{
|
||||
/* check if the input dimension meets the constraints */
|
||||
return ARM_MATH_SIZE_MISMATCH;
|
||||
}
|
||||
|
||||
for (i_out_y = 0; i_out_y < dim_im_out_y; i_out_y++)
|
||||
{
|
||||
for (i_out_x = 0; i_out_x < dim_im_out_x; i_out_x++)
|
||||
{
|
||||
/* This part implements the im2col function */
|
||||
arm_q7_to_q15_reordered_no_shift((q7_t *) Im_in + (i_out_y * dim_im_in_x + i_out_x) * ch_im_in, pBuffer,
|
||||
ch_im_in);
|
||||
pBuffer += ch_im_in;
|
||||
|
||||
if (pBuffer == bufferA + 2 * ch_im_in * dim_kernel_x * dim_kernel_y)
|
||||
{
|
||||
pOut =
|
||||
arm_nn_mat_mult_kernel_q7_q15_reordered(wt, bufferA, ch_im_out, ch_im_in, bias_shift, out_shift, bias, pOut);
|
||||
/* counter reset */
|
||||
pBuffer = bufferA;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* check if there is left-over for compute */
|
||||
if (pBuffer != bufferA)
|
||||
{
|
||||
const q7_t *pA = wt;
|
||||
for (i_ch_out = 0; i_ch_out < ch_im_out; i_ch_out++)
|
||||
{
|
||||
q31_t sum = ((q31_t)(bias[i_ch_out]) << bias_shift) + NN_ROUND(out_shift);
|
||||
q15_t *pB = bufferA;
|
||||
/* basically each time it process 4 entries */
|
||||
uint16_t colCnt = ch_im_in * dim_kernel_x * dim_kernel_y >> 2;
|
||||
|
||||
while (colCnt)
|
||||
{
|
||||
|
||||
q31_t inA1, inA2;
|
||||
q31_t inB1, inB2;
|
||||
|
||||
pA = (const q7_t *)read_and_pad_reordered((void *)pA, &inA1, &inA2);
|
||||
|
||||
inB1 = *__SIMD32(pB)++;
|
||||
sum = __SMLAD(inA1, inB1, sum);
|
||||
inB2 = *__SIMD32(pB)++;
|
||||
sum = __SMLAD(inA2, inB2, sum);
|
||||
|
||||
colCnt--;
|
||||
}
|
||||
colCnt = ch_im_in * dim_kernel_y * dim_kernel_x & 0x3;
|
||||
while (colCnt)
|
||||
{
|
||||
q7_t inA1 = *pA++;
|
||||
q15_t inB1 = *pB++;
|
||||
sum += inA1 * inB1;
|
||||
colCnt--;
|
||||
}
|
||||
*pOut = (q7_t) __SSAT((sum >> out_shift), 8);
|
||||
pOut++;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#else
|
||||
/* Run the following code as reference implementation for Cortex-M0 and Cortex-M3 */
|
||||
|
||||
int i, j, k, l, m, n;
|
||||
int conv_out;
|
||||
int in_row, in_col;
|
||||
|
||||
if (ch_im_in % 4 != 0 || ch_im_out % 2 != 0 || dim_kernel_x != 1 || dim_kernel_y != 1
|
||||
|| padding_x != 0 || padding_y != 0 || stride_x != 1 || stride_y != 1)
|
||||
{
|
||||
/* check if the input dimension meets the constraints */
|
||||
return ARM_MATH_SIZE_MISMATCH;
|
||||
}
|
||||
|
||||
for (i = 0; i < ch_im_out; i++)
|
||||
{
|
||||
for (j = 0; j < dim_im_out_y; j++)
|
||||
{
|
||||
for (k = 0; k < dim_im_out_x; k++)
|
||||
{
|
||||
conv_out = ((q31_t)(bias[i]) << bias_shift) + NN_ROUND(out_shift);
|
||||
for (m = 0; m < dim_kernel_y; m++)
|
||||
{
|
||||
for (n = 0; n < dim_kernel_x; n++)
|
||||
{
|
||||
// if-for implementation
|
||||
in_row = stride_y * j + m - padding_y;
|
||||
in_col = stride_x * k + n - padding_x;
|
||||
if (in_row >= 0 && in_col >= 0 && in_row < dim_im_in_y && in_col < dim_im_in_x)
|
||||
{
|
||||
for (l = 0; l < ch_im_in; l++)
|
||||
{
|
||||
conv_out += Im_in[(in_row * dim_im_in_x + in_col) * ch_im_in + l] *
|
||||
wt[i * ch_im_in * dim_kernel_y * dim_kernel_x + (m * dim_kernel_y + n) * ch_im_in + l];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Im_out[i + (j * dim_im_out_x + k) * ch_im_out] = (q7_t) __SSAT((conv_out >> out_shift), 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* ARM_MATH_DSP */
|
||||
|
||||
/* Return to application */
|
||||
return ARM_MATH_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of NNConv group
|
||||
*/
|
@ -0,0 +1,207 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Project: CMSIS NN Library
|
||||
* Title: arm_convolve_HWC_q15_basic.c
|
||||
* Description: Q15 version of convolution
|
||||
*
|
||||
* $Date: 17. January 2018
|
||||
* $Revision: V.1.0.0
|
||||
*
|
||||
* Target Processor: Cortex-M cores
|
||||
*
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
#include "arm_nnfunctions.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupNN
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup NNConv
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Basic Q15 convolution function
|
||||
* @param[in] Im_in pointer to input tensor
|
||||
* @param[in] dim_im_in input tensor dimention
|
||||
* @param[in] ch_im_in number of input tensor channels
|
||||
* @param[in] wt pointer to kernel weights
|
||||
* @param[in] ch_im_out number of filters, i.e., output tensor channels
|
||||
* @param[in] dim_kernel filter kernel size
|
||||
* @param[in] padding padding sizes
|
||||
* @param[in] stride convolution stride
|
||||
* @param[in] bias pointer to bias
|
||||
* @param[in] bias_shift amount of left-shift for bias
|
||||
* @param[in] out_shift amount of right-shift for output
|
||||
* @param[in,out] Im_out pointer to output tensor
|
||||
* @param[in] dim_im_out output tensor dimension
|
||||
* @param[in,out] bufferA pointer to buffer space for input
|
||||
* @param[in,out] bufferB pointer to buffer space for output
|
||||
* @return The function returns <code>ARM_MATH_SUCCESS</code>
|
||||
*
|
||||
* @details
|
||||
*
|
||||
* <b>Buffer size:</b>
|
||||
*
|
||||
* bufferA size: ch_im_in*dim_kernel*dim_kernel
|
||||
*
|
||||
* bufferB size: 0
|
||||
*
|
||||
* This basic version is designed to work for any input tensor and weight
|
||||
* dimension.
|
||||
*/
|
||||
|
||||
arm_status
|
||||
arm_convolve_HWC_q15_basic(const q15_t * Im_in,
|
||||
const uint16_t dim_im_in,
|
||||
const uint16_t ch_im_in,
|
||||
const q15_t * wt,
|
||||
const uint16_t ch_im_out,
|
||||
const uint16_t dim_kernel,
|
||||
const uint16_t padding,
|
||||
const uint16_t stride,
|
||||
const q15_t * bias,
|
||||
const uint16_t bias_shift,
|
||||
const uint16_t out_shift,
|
||||
q15_t * Im_out,
|
||||
const uint16_t dim_im_out,
|
||||
q15_t * bufferA,
|
||||
q7_t * bufferB)
|
||||
{
|
||||
|
||||
#if defined (ARM_MATH_DSP)
|
||||
/* Run the following code for Cortex-M4 and Cortex-M7 */
|
||||
|
||||
int16_t i_out_y, i_out_x, i_ker_y, i_ker_x;
|
||||
|
||||
uint16_t im2col_out_pixel_index = 0;
|
||||
q15_t *pBuffer = bufferA;
|
||||
q15_t *pOut = Im_out;
|
||||
q15_t *im_buffer = bufferA;
|
||||
const q15_t *pA;
|
||||
int i;
|
||||
|
||||
/* This part implements the im2col function */
|
||||
for (i_out_y = 0; i_out_y < dim_im_out; i_out_y++)
|
||||
{
|
||||
for (i_out_x = 0; i_out_x < dim_im_out; i_out_x++)
|
||||
{
|
||||
for (i_ker_y = i_out_y * stride - padding; i_ker_y < i_out_y * stride - padding + dim_kernel; i_ker_y++)
|
||||
{
|
||||
for (i_ker_x = i_out_x * stride - padding; i_ker_x < i_out_x * stride - padding + dim_kernel; i_ker_x++)
|
||||
{
|
||||
if (i_ker_y < 0 || i_ker_y >= dim_im_in || i_ker_x < 0 || i_ker_x >= dim_im_in)
|
||||
{
|
||||
/* Filling 0 for out-of-bound paddings */
|
||||
/* arm_fill_q15(0, pBuffer, ch_im_in); */
|
||||
memset(pBuffer, 0, sizeof(q15_t)*ch_im_in);
|
||||
} else
|
||||
{
|
||||
/* arm_copy_q15((q15_t *) Im_in + (i_ker_y * dim_im_in + i_ker_x) * ch_im_in, pBuffer, ch_im_in); */
|
||||
memcpy(pBuffer, (q15_t *) Im_in + (i_ker_y * dim_im_in + i_ker_x) * ch_im_in, sizeof(q15_t)*ch_im_in);
|
||||
}
|
||||
pBuffer += ch_im_in;
|
||||
}
|
||||
}
|
||||
|
||||
pA = wt;
|
||||
for (i = 0; i < ch_im_out; i++)
|
||||
{
|
||||
q31_t sum = ((q31_t)bias[i] << bias_shift) + NN_ROUND(out_shift);
|
||||
q15_t *pB = im_buffer;
|
||||
uint16_t colCnt = ch_im_in * dim_kernel * dim_kernel >> 2;
|
||||
while (colCnt)
|
||||
{
|
||||
q31_t inA1 = *__SIMD32(pA)++;
|
||||
q31_t inB1 = *__SIMD32(pB)++;
|
||||
q31_t inA2 = *__SIMD32(pA)++;
|
||||
q31_t inB2 = *__SIMD32(pB)++;
|
||||
|
||||
sum = __SMLAD(inA1, inB1, sum);
|
||||
sum = __SMLAD(inA2, inB2, sum);
|
||||
|
||||
colCnt--;
|
||||
}
|
||||
colCnt = ch_im_in * dim_kernel * dim_kernel & 0x3;
|
||||
while (colCnt)
|
||||
{
|
||||
q15_t inA1 = *pA++;
|
||||
q15_t inB1 = *pB++;
|
||||
sum += inA1 * inB1;
|
||||
colCnt--;
|
||||
}
|
||||
*pOut = (q15_t) __SSAT((sum >> out_shift), 16);
|
||||
pOut++;
|
||||
}
|
||||
|
||||
/* counter reset */
|
||||
pBuffer = im_buffer;
|
||||
im2col_out_pixel_index++;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
/* Run the following code as reference implementation for Cortex-M0 and Cortex-M3 */
|
||||
uint16_t i, j, k, l, m, n;
|
||||
int conv_out;
|
||||
signed char in_row, in_col;
|
||||
|
||||
for (i = 0; i < ch_im_out; i++)
|
||||
{
|
||||
for (j = 0; j < dim_im_out; j++)
|
||||
{
|
||||
for (k = 0; k < dim_im_out; k++)
|
||||
{
|
||||
conv_out = ((q31_t)bias[i] << bias_shift) + NN_ROUND(out_shift);
|
||||
for (m = 0; m < dim_kernel; m++)
|
||||
{
|
||||
for (n = 0; n < dim_kernel; n++)
|
||||
{
|
||||
in_row = stride * j + m - padding;
|
||||
in_col = stride * k + n - padding;
|
||||
if (in_row >= 0 && in_col >= 0 && in_row < dim_im_in && in_col < dim_im_in)
|
||||
{
|
||||
for (l = 0; l < ch_im_in; l++)
|
||||
{
|
||||
conv_out +=
|
||||
Im_in[(in_row * dim_im_in + in_col) * ch_im_in +
|
||||
l] * wt[i * ch_im_in * dim_kernel * dim_kernel + (m * dim_kernel +
|
||||
n) * ch_im_in + l];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Im_out[i + (j * dim_im_out + k) * ch_im_out] = (q15_t) __SSAT((conv_out >> out_shift), 16);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* ARM_MATH_DSP */
|
||||
|
||||
/* Return to application */
|
||||
return ARM_MATH_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of NNConv group
|
||||
*/
|
@ -0,0 +1,255 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Project: CMSIS NN Library
|
||||
* Title: arm_convolve_HWC_q15_fast.c
|
||||
* Description: Fast Q15 version of convolution
|
||||
*
|
||||
* $Date: 17. January 2018
|
||||
* $Revision: V.1.0.0
|
||||
*
|
||||
* Target Processor: Cortex-M cores
|
||||
*
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
#include "arm_nnfunctions.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupNN
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup NNConv
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Fast Q15 convolution function
|
||||
* @param[in] Im_in pointer to input tensor
|
||||
* @param[in] dim_im_in input tensor dimention
|
||||
* @param[in] ch_im_in number of input tensor channels
|
||||
* @param[in] wt pointer to kernel weights
|
||||
* @param[in] ch_im_out number of filters, i.e., output tensor channels
|
||||
* @param[in] dim_kernel filter kernel size
|
||||
* @param[in] padding padding sizes
|
||||
* @param[in] stride convolution stride
|
||||
* @param[in] bias pointer to bias
|
||||
* @param[in] bias_shift amount of left-shift for bias
|
||||
* @param[in] out_shift amount of right-shift for output
|
||||
* @param[in,out] Im_out pointer to output tensor
|
||||
* @param[in] dim_im_out output tensor dimension
|
||||
* @param[in,out] bufferA pointer to buffer space for input
|
||||
* @param[in,out] bufferB pointer to buffer space for output
|
||||
* @return The function returns either
|
||||
* <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
|
||||
*
|
||||
* @details
|
||||
*
|
||||
* <b>Buffer size:</b>
|
||||
*
|
||||
* bufferA size: 2*ch_im_in*dim_kernel*dim_kernel
|
||||
*
|
||||
* bufferB size: 0
|
||||
*
|
||||
* <b>Input dimension constraints:</b>
|
||||
*
|
||||
* ch_im_in is multiple of 2
|
||||
*
|
||||
* ch_im_out is multipe of 2
|
||||
*
|
||||
*/
|
||||
|
||||
arm_status
|
||||
arm_convolve_HWC_q15_fast(const q15_t * Im_in,
|
||||
const uint16_t dim_im_in,
|
||||
const uint16_t ch_im_in,
|
||||
const q15_t * wt,
|
||||
const uint16_t ch_im_out,
|
||||
const uint16_t dim_kernel,
|
||||
const uint16_t padding,
|
||||
const uint16_t stride,
|
||||
const q15_t * bias,
|
||||
const uint16_t bias_shift,
|
||||
const uint16_t out_shift,
|
||||
q15_t * Im_out,
|
||||
const uint16_t dim_im_out,
|
||||
q15_t * bufferA,
|
||||
q7_t * bufferB)
|
||||
{
|
||||
|
||||
#if defined (ARM_MATH_DSP)
|
||||
int16_t i_out_y, i_out_x, i_ker_y, i_ker_x;
|
||||
|
||||
q15_t *pBuffer = bufferA;
|
||||
q15_t *im_buffer = bufferA;
|
||||
q15_t *pOut = Im_out;
|
||||
|
||||
if (ch_im_in % 2 != 0 || ch_im_out % 2 != 0)
|
||||
{
|
||||
/* check if the input dimension meets the constraints */
|
||||
return ARM_MATH_SIZE_MISMATCH;
|
||||
}
|
||||
|
||||
/* Run the following code for Cortex-M4 and Cortex-M7 */
|
||||
|
||||
/* This part implements the im2col function */
|
||||
for (i_out_y = 0; i_out_y < dim_im_out; i_out_y++)
|
||||
{
|
||||
for (i_out_x = 0; i_out_x < dim_im_out; i_out_x++)
|
||||
{
|
||||
for (i_ker_y = i_out_y * stride - padding; i_ker_y < i_out_y * stride - padding + dim_kernel; i_ker_y++)
|
||||
{
|
||||
for (i_ker_x = i_out_x * stride - padding; i_ker_x < i_out_x * stride - padding + dim_kernel; i_ker_x++)
|
||||
{
|
||||
if (i_ker_y < 0 || i_ker_y >= dim_im_in || i_ker_x < 0 || i_ker_x >= dim_im_in)
|
||||
{
|
||||
/* arm_fill_q15(0, pBuffer, ch_im_in); */
|
||||
memset(pBuffer, 0, sizeof(q15_t)*ch_im_in);
|
||||
} else
|
||||
{
|
||||
/* arm_copy_q15((q15_t *) Im_in + (i_ker_y * dim_im_in + i_ker_x) * ch_im_in, pBuffer, ch_im_in); */
|
||||
memcpy(pBuffer, (q15_t *) Im_in + (i_ker_y * dim_im_in + i_ker_x) * ch_im_in, sizeof(q15_t)*ch_im_in);
|
||||
}
|
||||
pBuffer += ch_im_in;
|
||||
}
|
||||
}
|
||||
|
||||
if (i_out_x & 0x1)
|
||||
{
|
||||
int i;
|
||||
/* initialize the matrix pointers for A */
|
||||
const q15_t *pA = wt;
|
||||
|
||||
/* set up the second output pointers */
|
||||
q15_t *pOut2 = pOut + ch_im_out;
|
||||
|
||||
/* this loop over rows in A */
|
||||
for (i = 0; i < ch_im_out; i += 2)
|
||||
{
|
||||
/* setup pointers for B */
|
||||
q15_t *pB = im_buffer;
|
||||
const q15_t *pB2 = pB + ch_im_in * dim_kernel * dim_kernel;
|
||||
|
||||
/* aling the second pointer for A */
|
||||
const q15_t *pA2 = pA + ch_im_in * dim_kernel * dim_kernel;
|
||||
|
||||
/* init the sum with bias */
|
||||
q31_t sum = ((q31_t)bias[i] << bias_shift) + NN_ROUND(out_shift);
|
||||
q31_t sum2 = ((q31_t)bias[i] << bias_shift) + NN_ROUND(out_shift);
|
||||
q31_t sum3 = ((q31_t)bias[i + 1] << bias_shift) + NN_ROUND(out_shift);
|
||||
q31_t sum4 = ((q31_t)bias[i + 1] << bias_shift) + NN_ROUND(out_shift);
|
||||
|
||||
uint16_t colCnt = ch_im_in * dim_kernel * dim_kernel >> 1;
|
||||
/* accumulate over the vector */
|
||||
while (colCnt)
|
||||
{
|
||||
q31_t inA1 = *__SIMD32(pA)++;
|
||||
q31_t inB1 = *__SIMD32(pB)++;
|
||||
q31_t inA2 = *__SIMD32(pA2)++;
|
||||
q31_t inB2 = *__SIMD32(pB2)++;
|
||||
|
||||
sum = __SMLAD(inA1, inB1, sum);
|
||||
sum2 = __SMLAD(inA1, inB2, sum2);
|
||||
sum3 = __SMLAD(inA2, inB1, sum3);
|
||||
sum4 = __SMLAD(inA2, inB2, sum4);
|
||||
|
||||
colCnt--;
|
||||
} /* while over colCnt */
|
||||
colCnt = ch_im_in * dim_kernel * dim_kernel & 0x1;
|
||||
while (colCnt)
|
||||
{
|
||||
q15_t inA1 = *pA++;
|
||||
q15_t inB1 = *pB++;
|
||||
q15_t inA2 = *pA2++;
|
||||
q15_t inB2 = *pB2++;
|
||||
|
||||
sum += inA1 * inB1;
|
||||
sum2 += inA1 * inB2;
|
||||
sum3 += inA2 * inB1;
|
||||
sum4 += inA2 * inB2;
|
||||
colCnt--;
|
||||
} /* while over colCnt */
|
||||
*pOut++ = (q15_t) __SSAT(sum >> out_shift, 16);
|
||||
*pOut++ = (q15_t) __SSAT(sum3 >> out_shift, 16);
|
||||
*pOut2++ = (q15_t) __SSAT(sum2 >> out_shift, 16);
|
||||
*pOut2++ = (q15_t) __SSAT(sum4 >> out_shift, 16);
|
||||
|
||||
/* skip the row computed with A2 */
|
||||
pA += ch_im_in * dim_kernel * dim_kernel;
|
||||
} /* for over ch_im_out */
|
||||
|
||||
pOut += ch_im_out;
|
||||
/* counter reset */
|
||||
pBuffer = im_buffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
/* Run the following code as reference implementation for Cortex-M0 and Cortex-M3 */
|
||||
uint16_t i, j, k, l, m, n;
|
||||
int conv_out;
|
||||
signed char in_row, in_col;
|
||||
|
||||
if (ch_im_in % 2 != 0 || ch_im_out % 2 != 0)
|
||||
{
|
||||
/* check if the input dimension meets the constraints */
|
||||
return ARM_MATH_SIZE_MISMATCH;
|
||||
}
|
||||
|
||||
for (i = 0; i < ch_im_out; i++)
|
||||
{
|
||||
for (j = 0; j < dim_im_out; j++)
|
||||
{
|
||||
for (k = 0; k < dim_im_out; k++)
|
||||
{
|
||||
conv_out = ((q31_t)bias[i] << bias_shift) + NN_ROUND(out_shift);
|
||||
for (m = 0; m < dim_kernel; m++)
|
||||
{
|
||||
for (n = 0; n < dim_kernel; n++)
|
||||
{
|
||||
in_row = stride * j + m - padding;
|
||||
in_col = stride * k + n - padding;
|
||||
if (in_row >= 0 && in_col >= 0 && in_row < dim_im_in && in_col < dim_im_in)
|
||||
{
|
||||
for (l = 0; l < ch_im_in; l++)
|
||||
{
|
||||
conv_out +=
|
||||
Im_in[(in_row * dim_im_in + in_col) * ch_im_in +
|
||||
l] * wt[i * ch_im_in * dim_kernel * dim_kernel + (m * dim_kernel +
|
||||
n) * ch_im_in + l];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Im_out[i + (j * dim_im_out + k) * ch_im_out] = (q15_t) __SSAT((conv_out >> out_shift), 16);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* ARM_MATH_DSP */
|
||||
|
||||
/* Return to application */
|
||||
return ARM_MATH_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of NNConv group
|
||||
*/
|
@ -0,0 +1,265 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Project: CMSIS NN Library
|
||||
* Title: arm_convolve_HWC_q15_fast.c
|
||||
* Description: Fast Q15 version of convolution
|
||||
*
|
||||
* $Date: 24. May 2018
|
||||
* $Revision: V.1.0.0
|
||||
*
|
||||
* Target Processor: Cortex-M cores
|
||||
*
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
#include "arm_nnfunctions.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupNN
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup NNConv
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Fast Q15 convolution function (non-sqaure shape)
|
||||
* @param[in] Im_in pointer to input tensor
|
||||
* @param[in] dim_im_in_x input tensor dimention x
|
||||
* @param[in] dim_im_in_y input tensor dimention y
|
||||
* @param[in] ch_im_in number of input tensor channels
|
||||
* @param[in] wt pointer to kernel weights
|
||||
* @param[in] ch_im_out number of filters, i.e., output tensor channels
|
||||
* @param[in] dim_kernel_x filter kernel size x
|
||||
* @param[in] dim_kernel_y filter kernel size y
|
||||
* @param[in] padding_x padding size x
|
||||
* @param[in] padding_y padding size y
|
||||
* @param[in] stride_x convolution stride x
|
||||
* @param[in] stride_y convolution stride y
|
||||
* @param[in] bias pointer to bias
|
||||
* @param[in] bias_shift amount of left-shift for bias
|
||||
* @param[in] out_shift amount of right-shift for output
|
||||
* @param[in,out] Im_out pointer to output tensor
|
||||
* @param[in] dim_im_out_x output tensor dimension x
|
||||
* @param[in] dim_im_out_y output tensor dimension y
|
||||
* @param[in,out] bufferA pointer to buffer space for input
|
||||
* @param[in,out] bufferB pointer to buffer space for output
|
||||
* @return The function returns either
|
||||
* <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
|
||||
*
|
||||
* @details
|
||||
*
|
||||
* <b>Buffer size:</b>
|
||||
*
|
||||
* bufferA size: 2*ch_im_in*dim_kernel*dim_kernel
|
||||
*
|
||||
* bufferB size: 0
|
||||
*
|
||||
* <b>Input dimension constraints:</b>
|
||||
*
|
||||
* ch_im_in is multiple of 2
|
||||
*
|
||||
* ch_im_out is multipe of 2
|
||||
*
|
||||
*/
|
||||
|
||||
arm_status
|
||||
arm_convolve_HWC_q15_fast_nonsquare(const q15_t * Im_in,
|
||||
const uint16_t dim_im_in_x,
|
||||
const uint16_t dim_im_in_y,
|
||||
const uint16_t ch_im_in,
|
||||
const q15_t * wt,
|
||||
const uint16_t ch_im_out,
|
||||
const uint16_t dim_kernel_x,
|
||||
const uint16_t dim_kernel_y,
|
||||
const uint16_t padding_x,
|
||||
const uint16_t padding_y,
|
||||
const uint16_t stride_x,
|
||||
const uint16_t stride_y,
|
||||
const q15_t * bias,
|
||||
const uint16_t bias_shift,
|
||||
const uint16_t out_shift,
|
||||
q15_t * Im_out,
|
||||
const uint16_t dim_im_out_x,
|
||||
const uint16_t dim_im_out_y,
|
||||
q15_t * bufferA,
|
||||
q7_t * bufferB)
|
||||
{
|
||||
|
||||
#if defined (ARM_MATH_DSP)
|
||||
int16_t i_out_y, i_out_x, i_ker_y, i_ker_x;
|
||||
|
||||
q15_t *pBuffer = bufferA;
|
||||
q15_t *im_buffer = bufferA;
|
||||
q15_t *pOut = Im_out;
|
||||
|
||||
if (ch_im_in % 2 != 0 || ch_im_out % 2 != 0)
|
||||
{
|
||||
/* check if the input dimension meets the constraints */
|
||||
return ARM_MATH_SIZE_MISMATCH;
|
||||
}
|
||||
|
||||
/* Run the following code for Cortex-M4 and Cortex-M7 */
|
||||
|
||||
/* This part implements the im2col function */
|
||||
for (i_out_y = 0; i_out_y < dim_im_out_y; i_out_y++)
|
||||
{
|
||||
for (i_out_x = 0; i_out_x < dim_im_out_x; i_out_x++)
|
||||
{
|
||||
for (i_ker_y = i_out_y * stride_y - padding_y; i_ker_y < i_out_y * stride_y - padding_y + dim_kernel_y; i_ker_y++)
|
||||
{
|
||||
for (i_ker_x = i_out_x * stride_x - padding_x; i_ker_x < i_out_x * stride_x - padding_x + dim_kernel_x; i_ker_x++)
|
||||
{
|
||||
if (i_ker_y < 0 || i_ker_y >= dim_im_in_y || i_ker_x < 0 || i_ker_x >= dim_im_in_x)
|
||||
{
|
||||
/* arm_fill_q15(0, pBuffer, ch_im_in); */
|
||||
memset(pBuffer, 0, sizeof(q15_t)*ch_im_in);
|
||||
} else
|
||||
{
|
||||
/* arm_copy_q15((q15_t *) Im_in + (i_ker_y * dim_im_in_x + i_ker_x) * ch_im_in, pBuffer, ch_im_in); */
|
||||
memcpy(pBuffer, (q15_t *) Im_in + (i_ker_y * dim_im_in_x + i_ker_x) * ch_im_in, sizeof(q15_t)*ch_im_in);
|
||||
}
|
||||
pBuffer += ch_im_in;
|
||||
}
|
||||
}
|
||||
|
||||
if (i_out_x & 0x1)
|
||||
{
|
||||
int i;
|
||||
/* initialize the matrix pointers for A */
|
||||
const q15_t *pA = wt;
|
||||
|
||||
/* set up the second output pointers */
|
||||
q15_t *pOut2 = pOut + ch_im_out;
|
||||
|
||||
/* this loop over rows in A */
|
||||
for (i = 0; i < ch_im_out; i += 2)
|
||||
{
|
||||
/* setup pointers for B */
|
||||
q15_t *pB = im_buffer;
|
||||
const q15_t *pB2 = pB + ch_im_in * dim_kernel_y * dim_kernel_x;
|
||||
|
||||
/* aling the second pointer for A */
|
||||
const q15_t *pA2 = pA + ch_im_in * dim_kernel_y * dim_kernel_x;
|
||||
|
||||
/* init the sum with bias */
|
||||
q31_t sum = ((q31_t)bias[i] << bias_shift) + NN_ROUND(out_shift);
|
||||
q31_t sum2 = ((q31_t)bias[i] << bias_shift) + NN_ROUND(out_shift);
|
||||
q31_t sum3 = ((q31_t)bias[i + 1] << bias_shift) + NN_ROUND(out_shift);
|
||||
q31_t sum4 = ((q31_t)bias[i + 1] << bias_shift) + NN_ROUND(out_shift);
|
||||
|
||||
uint16_t colCnt = ch_im_in * dim_kernel_y * dim_kernel_x >> 1;
|
||||
/* accumulate over the vector */
|
||||
while (colCnt)
|
||||
{
|
||||
q31_t inA1 = *__SIMD32(pA)++;
|
||||
q31_t inB1 = *__SIMD32(pB)++;
|
||||
q31_t inA2 = *__SIMD32(pA2)++;
|
||||
q31_t inB2 = *__SIMD32(pB2)++;
|
||||
|
||||
sum = __SMLAD(inA1, inB1, sum);
|
||||
sum2 = __SMLAD(inA1, inB2, sum2);
|
||||
sum3 = __SMLAD(inA2, inB1, sum3);
|
||||
sum4 = __SMLAD(inA2, inB2, sum4);
|
||||
|
||||
colCnt--;
|
||||
} /* while over colCnt */
|
||||
colCnt = ch_im_in * dim_kernel_y * dim_kernel_x & 0x1;
|
||||
while (colCnt)
|
||||
{
|
||||
q15_t inA1 = *pA++;
|
||||
q15_t inB1 = *pB++;
|
||||
q15_t inA2 = *pA2++;
|
||||
q15_t inB2 = *pB2++;
|
||||
|
||||
sum += inA1 * inB1;
|
||||
sum2 += inA1 * inB2;
|
||||
sum3 += inA2 * inB1;
|
||||
sum4 += inA2 * inB2;
|
||||
colCnt--;
|
||||
} /* while over colCnt */
|
||||
*pOut++ = (q15_t) __SSAT(sum >> out_shift, 16);
|
||||
*pOut++ = (q15_t) __SSAT(sum3 >> out_shift, 16);
|
||||
*pOut2++ = (q15_t) __SSAT(sum2 >> out_shift, 16);
|
||||
*pOut2++ = (q15_t) __SSAT(sum4 >> out_shift, 16);
|
||||
|
||||
/* skip the row computed with A2 */
|
||||
pA += ch_im_in * dim_kernel_y * dim_kernel_x;
|
||||
} /* for over ch_im_out */
|
||||
|
||||
pOut += ch_im_out;
|
||||
/* counter reset */
|
||||
pBuffer = im_buffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
/* Run the following code as reference implementation for Cortex-M0 and Cortex-M3 */
|
||||
uint16_t i, j, k, l, m, n;
|
||||
int conv_out;
|
||||
signed char in_row, in_col;
|
||||
|
||||
if (ch_im_in % 2 != 0 || ch_im_out % 2 != 0)
|
||||
{
|
||||
/* check if the input dimension meets the constraints */
|
||||
return ARM_MATH_SIZE_MISMATCH;
|
||||
}
|
||||
|
||||
for (i = 0; i < ch_im_out; i++)
|
||||
{
|
||||
for (j = 0; j < dim_im_out_y; j++)
|
||||
{
|
||||
for (k = 0; k < dim_im_out_x; k++)
|
||||
{
|
||||
conv_out = ((q31_t)bias[i] << bias_shift) + NN_ROUND(out_shift);
|
||||
for (m = 0; m < dim_kernel_y; m++)
|
||||
{
|
||||
for (n = 0; n < dim_kernel_x; n++)
|
||||
{
|
||||
in_row = stride_y * j + m - padding_y;
|
||||
in_col = stride_x * k + n - padding_x;
|
||||
if (in_row >= 0 && in_col >= 0 && in_row < dim_im_in_y && in_col < dim_im_in_x)
|
||||
{
|
||||
for (l = 0; l < ch_im_in; l++)
|
||||
{
|
||||
conv_out +=
|
||||
Im_in[(in_row * dim_im_in_x + in_col) * ch_im_in +
|
||||
l] * wt[i * ch_im_in * dim_kernel_x * dim_kernel_y + (m * dim_kernel_x +
|
||||
n) * ch_im_in + l];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Im_out[i + (j * dim_im_out_x + k) * ch_im_out] = (q15_t) __SSAT((conv_out >> out_shift), 16);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* ARM_MATH_DSP */
|
||||
|
||||
/* Return to application */
|
||||
return ARM_MATH_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of NNConv group
|
||||
*/
|
@ -0,0 +1,279 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Project: CMSIS NN Library
|
||||
* Title: arm_convolve_HWC_q7_RGB.c
|
||||
* Description: Q7 version of convolution for RGB image
|
||||
*
|
||||
* $Date: 17. January 2018
|
||||
* $Revision: V.1.0.0
|
||||
*
|
||||
* Target Processor: Cortex-M cores
|
||||
*
|
||||
* -------------------------------------------------------------------- */
|
||||
#include "arm_math.h"
|
||||
#include "arm_nnfunctions.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupNN
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup NNConv
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Q7 convolution function for RGB image
|
||||
* @param[in] Im_in pointer to input tensor
|
||||
* @param[in] dim_im_in input tensor dimention
|
||||
* @param[in] ch_im_in number of input tensor channels
|
||||
* @param[in] wt pointer to kernel weights
|
||||
* @param[in] ch_im_out number of filters, i.e., output tensor channels
|
||||
* @param[in] dim_kernel filter kernel size
|
||||
* @param[in] padding padding sizes
|
||||
* @param[in] stride convolution stride
|
||||
* @param[in] bias pointer to bias
|
||||
* @param[in] bias_shift amount of left-shift for bias
|
||||
* @param[in] out_shift amount of right-shift for output
|
||||
* @param[in,out] Im_out pointer to output tensor
|
||||
* @param[in] dim_im_out output tensor dimension
|
||||
* @param[in,out] bufferA pointer to buffer space for input
|
||||
* @param[in,out] bufferB pointer to buffer space for output
|
||||
* @return The function returns either
|
||||
* <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
|
||||
*
|
||||
* @details
|
||||
*
|
||||
* <b>Buffer size:</b>
|
||||
*
|
||||
* bufferA size: 2*ch_im_in*dim_kernel*dim_kernel
|
||||
*
|
||||
* bufferB size: 0
|
||||
*
|
||||
* <b>Input dimension constraints:</b>
|
||||
*
|
||||
* ch_im_in equals 3
|
||||
*
|
||||
* This kernel is written exclusively for convolution with ch_im_in
|
||||
* equals 3. This applies on the first layer of CNNs which has input
|
||||
* image with RGB format.
|
||||
*/
|
||||
|
||||
arm_status
|
||||
arm_convolve_HWC_q7_RGB(const q7_t * Im_in,
|
||||
const uint16_t dim_im_in,
|
||||
const uint16_t ch_im_in,
|
||||
const q7_t * wt,
|
||||
const uint16_t ch_im_out,
|
||||
const uint16_t dim_kernel,
|
||||
const uint16_t padding,
|
||||
const uint16_t stride,
|
||||
const q7_t * bias,
|
||||
const uint16_t bias_shift,
|
||||
const uint16_t out_shift,
|
||||
q7_t * Im_out, const uint16_t dim_im_out, q15_t * bufferA, q7_t * bufferB)
|
||||
{
|
||||
|
||||
#if defined (ARM_MATH_DSP)
|
||||
/* Run the following code for Cortex-M4 and Cortex-M7 */
|
||||
int16_t i_out_y, i_out_x, i_ker_y, i_ker_x;
|
||||
|
||||
/*
|
||||
* Here we use bufferA as q15_t internally as computation are done with q15_t level
|
||||
* im2col are done to output in q15_t format from q7_t input
|
||||
*/
|
||||
q15_t *pBuffer = bufferA;
|
||||
q7_t *pOut = Im_out;
|
||||
|
||||
// check if number of input channels is 3
|
||||
if (ch_im_in != 3)
|
||||
{
|
||||
return ARM_MATH_SIZE_MISMATCH;
|
||||
}
|
||||
// This part implements the im2col function
|
||||
for (i_out_y = 0; i_out_y < dim_im_out; i_out_y++)
|
||||
{
|
||||
for (i_out_x = 0; i_out_x < dim_im_out; i_out_x++)
|
||||
{
|
||||
for (i_ker_y = i_out_y * stride - padding; i_ker_y < i_out_y * stride - padding + dim_kernel; i_ker_y++)
|
||||
{
|
||||
for (i_ker_x = i_out_x * stride - padding; i_ker_x < i_out_x * stride - padding + dim_kernel; i_ker_x++)
|
||||
{
|
||||
if (i_ker_y < 0 || i_ker_y >= dim_im_in || i_ker_x < 0 || i_ker_x >= dim_im_in)
|
||||
{
|
||||
/* Equivalent to arm_fill_q15(0, pBuffer, ch_im_in) with assumption: ch_im_in = 3 */
|
||||
*__SIMD32(pBuffer) = 0x0;
|
||||
*(pBuffer + 2) = 0;
|
||||
pBuffer += 3;
|
||||
} else
|
||||
{
|
||||
/*
|
||||
* Equivalent to:
|
||||
* arm_q7_to_q15_no_shift( (q7_t*)Im_in+(i_ker_y*dim_im_in+i_ker_x)*3, pBuffer, 3);
|
||||
*/
|
||||
|
||||
const q7_t *pPixel = Im_in + (i_ker_y * dim_im_in + i_ker_x) * 3;
|
||||
q31_t buf = *__SIMD32(pPixel);
|
||||
|
||||
union arm_nnword top;
|
||||
union arm_nnword bottom;
|
||||
|
||||
top.word = __SXTB16(buf);
|
||||
bottom.word = __SXTB16(__ROR(buf, 8));
|
||||
|
||||
#ifndef ARM_MATH_BIG_ENDIAN
|
||||
/*
|
||||
* little-endian, | omit | 3rd | 2nd | 1st |
|
||||
* MSB LSB
|
||||
* top | 3rd | 1st |; bottom | omit | 2nd |
|
||||
*
|
||||
* version 1, need to swap 2nd and 3rd weight
|
||||
* *__SIMD32(pBuffer) = top.word;
|
||||
* *(pBuffer+2) = bottom.half_words[0];
|
||||
*
|
||||
* version 2, no weight shuffling required
|
||||
*/
|
||||
*pBuffer++ = top.half_words[0];
|
||||
*__SIMD32(pBuffer) = __PKHBT(bottom.word, top.word, 0);
|
||||
#else
|
||||
/*
|
||||
* big-endian, | 1st | 2nd | 3rd | omit |
|
||||
* MSB LSB
|
||||
* top | 2nd | omit |; bottom | 1st | 3rd |
|
||||
*
|
||||
* version 1, need to swap 2nd and 3rd weight
|
||||
* *__SIMD32(pBuffer) = bottom.word;
|
||||
* *(pBuffer+2) = top.half_words[1];
|
||||
*
|
||||
* version 2, no weight shuffling required
|
||||
*/
|
||||
*pBuffer++ = bottom.half_words[0];
|
||||
*__SIMD32(pBuffer) = __PKHTB(top.word, bottom.word, 0);
|
||||
#endif
|
||||
pBuffer += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pBuffer == bufferA + 2 * 3 * dim_kernel * dim_kernel)
|
||||
{
|
||||
pOut =
|
||||
arm_nn_mat_mult_kernel_q7_q15(wt, bufferA,
|
||||
ch_im_out,
|
||||
3 * dim_kernel * dim_kernel, bias_shift, out_shift, bias, pOut);
|
||||
|
||||
/* counter reset */
|
||||
pBuffer = bufferA;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* left-over because odd number of output pixels */
|
||||
if (pBuffer != bufferA)
|
||||
{
|
||||
const q7_t *pA = wt;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ch_im_out; i++)
|
||||
{
|
||||
q31_t sum = ((q31_t)bias[i] << bias_shift) + NN_ROUND(out_shift);
|
||||
q15_t *pB = bufferA;
|
||||
/* basically each time it process 4 entries */
|
||||
uint16_t colCnt = 3 * dim_kernel * dim_kernel >> 2;
|
||||
|
||||
while (colCnt)
|
||||
{
|
||||
|
||||
q31_t inA1, inA2;
|
||||
q31_t inB1, inB2;
|
||||
|
||||
pA = (q7_t *) read_and_pad((void *)pA, &inA1, &inA2);
|
||||
|
||||
inB1 = *__SIMD32(pB)++;
|
||||
sum = __SMLAD(inA1, inB1, sum);
|
||||
inB2 = *__SIMD32(pB)++;
|
||||
sum = __SMLAD(inA2, inB2, sum);
|
||||
|
||||
colCnt--;
|
||||
}
|
||||
colCnt = 3 * dim_kernel * dim_kernel & 0x3;
|
||||
while (colCnt)
|
||||
{
|
||||
q7_t inA1 = *pA++;
|
||||
q15_t inB1 = *pB++;
|
||||
sum += inA1 * inB1;
|
||||
colCnt--;
|
||||
}
|
||||
*pOut++ = (q7_t) __SSAT((sum >> out_shift), 8);
|
||||
}
|
||||
}
|
||||
#else
|
||||
/* Run the following code as reference implementation for Cortex-M0 and Cortex-M3 */
|
||||
|
||||
uint16_t i, j, k, l, m, n;
|
||||
int conv_out;
|
||||
signed char in_row, in_col;
|
||||
|
||||
// check if number of input channels is 3
|
||||
if (ch_im_in != 3)
|
||||
{
|
||||
return ARM_MATH_SIZE_MISMATCH;
|
||||
}
|
||||
|
||||
for (i = 0; i < ch_im_out; i++)
|
||||
{
|
||||
for (j = 0; j < dim_im_out; j++)
|
||||
{
|
||||
for (k = 0; k < dim_im_out; k++)
|
||||
{
|
||||
conv_out = (bias[i] << bias_shift) + NN_ROUND(out_shift);
|
||||
for (m = 0; m < dim_kernel; m++)
|
||||
{
|
||||
for (n = 0; n < dim_kernel; n++)
|
||||
{
|
||||
/* if-for implementation */
|
||||
in_row = stride * j + m - padding;
|
||||
in_col = stride * k + n - padding;
|
||||
if (in_row >= 0 && in_col >= 0 && in_row < dim_im_in && in_col < dim_im_in)
|
||||
{
|
||||
for (l = 0; l < ch_im_in; l++)
|
||||
{
|
||||
conv_out +=
|
||||
Im_in[(in_row * dim_im_in + in_col) * ch_im_in +
|
||||
l] * wt[i * ch_im_in * dim_kernel * dim_kernel + (m * dim_kernel +
|
||||
n) * ch_im_in + l];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Im_out[i + (j * dim_im_out + k) * ch_im_out] = (q7_t) __SSAT((conv_out >> out_shift), 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* ARM_MATH_DSP */
|
||||
|
||||
/* Return to application */
|
||||
return (ARM_MATH_SUCCESS);
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of NNConv group
|
||||
*/
|
@ -0,0 +1,230 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Project: CMSIS NN Library
|
||||
* Title: arm_convolve_HWC_q7_basic.c
|
||||
* Description: Q7 version of convolution
|
||||
*
|
||||
* $Date: 17. January 2018
|
||||
* $Revision: V.1.0.0
|
||||
*
|
||||
* Target Processor: Cortex-M cores
|
||||
*
|
||||
* -------------------------------------------------------------------- */
|
||||
#include "arm_math.h"
|
||||
#include "arm_nnfunctions.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupNN
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup NNConv
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Basic Q7 convolution function
|
||||
* @param[in] Im_in pointer to input tensor
|
||||
* @param[in] dim_im_in input tensor dimention
|
||||
* @param[in] ch_im_in number of input tensor channels
|
||||
* @param[in] wt pointer to kernel weights
|
||||
* @param[in] ch_im_out number of filters, i.e., output tensor channels
|
||||
* @param[in] dim_kernel filter kernel size
|
||||
* @param[in] padding padding sizes
|
||||
* @param[in] stride convolution stride
|
||||
* @param[in] bias pointer to bias
|
||||
* @param[in] bias_shift amount of left-shift for bias
|
||||
* @param[in] out_shift amount of right-shift for output
|
||||
* @param[in,out] Im_out pointer to output tensor
|
||||
* @param[in] dim_im_out output tensor dimension
|
||||
* @param[in,out] bufferA pointer to buffer space for input
|
||||
* @param[in,out] bufferB pointer to buffer space for output
|
||||
* @return The function returns <code>ARM_MATH_SUCCESS</code>
|
||||
*
|
||||
* @details
|
||||
*
|
||||
* <b>Buffer size:</b>
|
||||
*
|
||||
* bufferA size: 2*ch_im_in*dim_kernel*dim_kernel
|
||||
*
|
||||
* bufferB size: 0
|
||||
*
|
||||
* This basic version is designed to work for any input tensor and weight
|
||||
* dimension.
|
||||
*/
|
||||
|
||||
arm_status
|
||||
arm_convolve_HWC_q7_basic(const q7_t * Im_in,
|
||||
const uint16_t dim_im_in,
|
||||
const uint16_t ch_im_in,
|
||||
const q7_t * wt,
|
||||
const uint16_t ch_im_out,
|
||||
const uint16_t dim_kernel,
|
||||
const uint16_t padding,
|
||||
const uint16_t stride,
|
||||
const q7_t * bias,
|
||||
const uint16_t bias_shift,
|
||||
const uint16_t out_shift,
|
||||
q7_t * Im_out,
|
||||
const uint16_t dim_im_out,
|
||||
q15_t * bufferA,
|
||||
q7_t * bufferB)
|
||||
{
|
||||
|
||||
#if defined (ARM_MATH_DSP)
|
||||
/* Run the following code for Cortex-M4 and Cortex-M7 */
|
||||
|
||||
int16_t i_out_y, i_out_x, i_ker_y, i_ker_x;
|
||||
|
||||
/*
|
||||
* Here we use bufferA as q15_t internally as computation are done with q15_t level
|
||||
* im2col are done to output in q15_t format from q7_t input
|
||||
*/
|
||||
q15_t *pBuffer = bufferA;
|
||||
q7_t *pOut = Im_out;
|
||||
|
||||
/* This part implements the im2col function */
|
||||
for (i_out_y = 0; i_out_y < dim_im_out; i_out_y++)
|
||||
{
|
||||
for (i_out_x = 0; i_out_x < dim_im_out; i_out_x++)
|
||||
{
|
||||
for (i_ker_y = i_out_y * stride - padding; i_ker_y < i_out_y * stride - padding + dim_kernel; i_ker_y++)
|
||||
{
|
||||
for (i_ker_x = i_out_x * stride - padding; i_ker_x < i_out_x * stride - padding + dim_kernel; i_ker_x++)
|
||||
{
|
||||
if (i_ker_y < 0 || i_ker_y >= dim_im_in || i_ker_x < 0 || i_ker_x >= dim_im_in)
|
||||
{
|
||||
/* Filling 0 for out-of-bound paddings */
|
||||
/* arm_fill_q15(0, pBuffer, ch_im_in); */
|
||||
memset(pBuffer, 0, sizeof(q15_t)*ch_im_in);
|
||||
} else
|
||||
{
|
||||
/* Copying the pixel data to column */
|
||||
arm_q7_to_q15_no_shift((q7_t *)
|
||||
Im_in + (i_ker_y * dim_im_in + i_ker_x) * ch_im_in, pBuffer, ch_im_in);
|
||||
}
|
||||
pBuffer += ch_im_in;
|
||||
}
|
||||
}
|
||||
|
||||
/* Computation is filed for every 2 columns */
|
||||
if (pBuffer == bufferA + 2 * ch_im_in * dim_kernel * dim_kernel)
|
||||
{
|
||||
pOut =
|
||||
arm_nn_mat_mult_kernel_q7_q15(wt, bufferA,
|
||||
ch_im_out,
|
||||
ch_im_in *
|
||||
dim_kernel * dim_kernel, bias_shift, out_shift, bias, pOut);
|
||||
|
||||
/* counter reset */
|
||||
pBuffer = bufferA;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* left-over because odd number of output pixels */
|
||||
if (pBuffer != bufferA)
|
||||
{
|
||||
const q7_t *pA = wt;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ch_im_out; i++)
|
||||
{
|
||||
/* Load the accumulator with bias first */
|
||||
q31_t sum = ((q31_t)bias[i] << bias_shift) + NN_ROUND(out_shift);
|
||||
|
||||
/* Point to the beging of the im2col buffer */
|
||||
q15_t *pB = bufferA;
|
||||
|
||||
/* Each time it process 4 entries */
|
||||
uint16_t colCnt = ch_im_in * dim_kernel * dim_kernel >> 2;
|
||||
|
||||
while (colCnt)
|
||||
{
|
||||
q31_t inA1, inA2;
|
||||
q31_t inB1, inB2;
|
||||
|
||||
pA = (q7_t *) read_and_pad((void *)pA, &inA1, &inA2);
|
||||
|
||||
inB1 = *__SIMD32(pB)++;
|
||||
sum = __SMLAD(inA1, inB1, sum);
|
||||
inB2 = *__SIMD32(pB)++;
|
||||
sum = __SMLAD(inA2, inB2, sum);
|
||||
|
||||
colCnt--;
|
||||
}
|
||||
colCnt = ch_im_in * dim_kernel * dim_kernel & 0x3;
|
||||
while (colCnt)
|
||||
{
|
||||
q7_t inA1 = *pA++;
|
||||
q15_t inB1 = *pB++;
|
||||
sum += inA1 * inB1;
|
||||
colCnt--;
|
||||
}
|
||||
*pOut++ = (q7_t) __SSAT((sum >> out_shift), 8);
|
||||
}
|
||||
}
|
||||
#else
|
||||
/* Run the following code as reference implementation for Cortex-M0 and Cortex-M3 */
|
||||
|
||||
uint16_t i, j, k, l, m, n;
|
||||
int conv_out;
|
||||
signed char in_row, in_col;
|
||||
|
||||
for (i = 0; i < ch_im_out; i++)
|
||||
{
|
||||
for (j = 0; j < dim_im_out; j++)
|
||||
{
|
||||
for (k = 0; k < dim_im_out; k++)
|
||||
{
|
||||
conv_out = ((q31_t)bias[i] << bias_shift) + NN_ROUND(out_shift);
|
||||
for (m = 0; m < dim_kernel; m++)
|
||||
{
|
||||
for (n = 0; n < dim_kernel; n++)
|
||||
{
|
||||
// if-for implementation
|
||||
in_row = stride * j + m - padding;
|
||||
in_col = stride * k + n - padding;
|
||||
if (in_row >= 0 && in_col >= 0 && in_row < dim_im_in && in_col < dim_im_in)
|
||||
{
|
||||
for (l = 0; l < ch_im_in; l++)
|
||||
{
|
||||
conv_out +=
|
||||
Im_in[(in_row * dim_im_in + in_col) * ch_im_in +
|
||||
l] * wt[i * ch_im_in * dim_kernel * dim_kernel + (m * dim_kernel +
|
||||
n) * ch_im_in + l];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Im_out[i + (j * dim_im_out + k) * ch_im_out] = (q7_t) __SSAT((conv_out >> out_shift), 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* ARM_MATH_DSP */
|
||||
|
||||
/* Return to application */
|
||||
return ARM_MATH_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of NNConv group
|
||||
*/
|
@ -0,0 +1,228 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Project: CMSIS NN Library
|
||||
* Title: arm_convolve_HWC_q7_basic.c
|
||||
* Description: Q7 version of convolution
|
||||
*
|
||||
* $Date: 13. July 2018
|
||||
* $Revision: V.1.0.0
|
||||
*
|
||||
* Target Processor: Cortex-M cores
|
||||
*
|
||||
* -------------------------------------------------------------------- */
|
||||
#include "arm_math.h"
|
||||
#include "arm_nnfunctions.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupNN
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup NNConv
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Basic Q7 convolution function (non-sqaure shape)
|
||||
* @param[in] Im_in pointer to input tensor
|
||||
* @param[in] dim_im_in_x input tensor dimention x
|
||||
* @param[in] dim_im_in_y input tensor dimention y
|
||||
* @param[in] ch_im_in number of input tensor channels
|
||||
* @param[in] wt pointer to kernel weights
|
||||
* @param[in] ch_im_out number of filters, i.e., output tensor channels
|
||||
* @param[in] dim_kernel_x filter kernel size x
|
||||
* @param[in] dim_kernel_y filter kernel size y
|
||||
* @param[in] padding_x padding size x
|
||||
* @param[in] padding_y padding size y
|
||||
* @param[in] stride_x convolution stride x
|
||||
* @param[in] stride_y convolution stride y
|
||||
* @param[in] bias pointer to bias
|
||||
* @param[in] bias_shift amount of left-shift for bias
|
||||
* @param[in] out_shift amount of right-shift for output
|
||||
* @param[in,out] Im_out pointer to output tensor
|
||||
* @param[in] dim_im_out_x output tensor dimension x
|
||||
* @param[in] dim_im_out_y output tensor dimension y
|
||||
* @param[in,out] bufferA pointer to buffer space for input
|
||||
* @param[in,out] bufferB pointer to buffer space for output
|
||||
* @return The function returns <code>ARM_MATH_SUCCESS</code>
|
||||
*/
|
||||
|
||||
arm_status arm_convolve_HWC_q7_basic_nonsquare(const q7_t * Im_in,
|
||||
const uint16_t dim_im_in_x,
|
||||
const uint16_t dim_im_in_y,
|
||||
const uint16_t ch_im_in,
|
||||
const q7_t * wt,
|
||||
const uint16_t ch_im_out,
|
||||
const uint16_t dim_kernel_x,
|
||||
const uint16_t dim_kernel_y,
|
||||
const uint16_t padding_x,
|
||||
const uint16_t padding_y,
|
||||
const uint16_t stride_x,
|
||||
const uint16_t stride_y,
|
||||
const q7_t * bias,
|
||||
const uint16_t bias_shift,
|
||||
const uint16_t out_shift,
|
||||
q7_t * Im_out,
|
||||
const uint16_t dim_im_out_x,
|
||||
const uint16_t dim_im_out_y,
|
||||
q15_t * bufferA,
|
||||
q7_t * bufferB)
|
||||
{
|
||||
|
||||
#if defined (ARM_MATH_DSP)
|
||||
/* Run the following code for Cortex-M4 and Cortex-M7 */
|
||||
|
||||
int16_t i_out_y, i_out_x, i_ker_y, i_ker_x;
|
||||
|
||||
/*
|
||||
* Here we use bufferA as q15_t internally as computation are done with q15_t level
|
||||
* im2col are done to output in q15_t format from q7_t input
|
||||
*/
|
||||
q15_t *pBuffer = bufferA;
|
||||
q7_t *pOut = Im_out;
|
||||
|
||||
/* This part implements the im2col function */
|
||||
for (i_out_y = 0; i_out_y < dim_im_out_y; i_out_y++)
|
||||
{
|
||||
for (i_out_x = 0; i_out_x < dim_im_out_x; i_out_x++)
|
||||
{
|
||||
for (i_ker_y = i_out_y * stride_y - padding_y; i_ker_y < i_out_y * stride_y - padding_y + dim_kernel_y; i_ker_y++)
|
||||
{
|
||||
for (i_ker_x = i_out_x * stride_x - padding_x; i_ker_x < i_out_x * stride_x - padding_x + dim_kernel_x; i_ker_x++)
|
||||
{
|
||||
if (i_ker_y < 0 || i_ker_y >= dim_im_in_y || i_ker_x < 0 || i_ker_x >= dim_im_in_x)
|
||||
{
|
||||
/* Filling 0 for out-of-bound paddings */
|
||||
/* arm_fill_q15(0, pBuffer, ch_im_in); */
|
||||
memset(pBuffer, 0, sizeof(q15_t)*ch_im_in);
|
||||
} else
|
||||
{
|
||||
/* Copying the pixel data to column */
|
||||
arm_q7_to_q15_no_shift((q7_t *)
|
||||
Im_in + (i_ker_y * dim_im_in_x + i_ker_x) * ch_im_in, pBuffer, ch_im_in);
|
||||
}
|
||||
pBuffer += ch_im_in;
|
||||
}
|
||||
}
|
||||
|
||||
/* Computation is filed for every 2 columns */
|
||||
if (pBuffer == bufferA + 2 * ch_im_in * dim_kernel_y * dim_kernel_x)
|
||||
{
|
||||
pOut =
|
||||
arm_nn_mat_mult_kernel_q7_q15(wt, bufferA,
|
||||
ch_im_out,
|
||||
ch_im_in *
|
||||
dim_kernel_y * dim_kernel_x, bias_shift, out_shift, bias, pOut);
|
||||
|
||||
/* counter reset */
|
||||
pBuffer = bufferA;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* left-over because odd number of output pixels */
|
||||
if (pBuffer != bufferA)
|
||||
{
|
||||
const q7_t *pA = wt;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ch_im_out; i++)
|
||||
{
|
||||
/* Load the accumulator with bias first */
|
||||
q31_t sum = ((q31_t)bias[i] << bias_shift) + NN_ROUND(out_shift);
|
||||
|
||||
/* Point to the beging of the im2col buffer */
|
||||
q15_t *pB = bufferA;
|
||||
|
||||
/* Each time it process 4 entries */
|
||||
uint16_t colCnt = ch_im_in * dim_kernel_y * dim_kernel_x >> 2;
|
||||
|
||||
while (colCnt)
|
||||
{
|
||||
q31_t inA1, inA2;
|
||||
q31_t inB1, inB2;
|
||||
|
||||
pA = (q7_t *) read_and_pad((void *)pA, &inA1, &inA2);
|
||||
|
||||
inB1 = *__SIMD32(pB)++;
|
||||
sum = __SMLAD(inA1, inB1, sum);
|
||||
inB2 = *__SIMD32(pB)++;
|
||||
sum = __SMLAD(inA2, inB2, sum);
|
||||
|
||||
colCnt--;
|
||||
}
|
||||
colCnt = ch_im_in * dim_kernel_y * dim_kernel_x & 0x3;
|
||||
while (colCnt)
|
||||
{
|
||||
q7_t inA1 = *pA++;
|
||||
q15_t inB1 = *pB++;
|
||||
sum += inA1 * inB1;
|
||||
colCnt--;
|
||||
}
|
||||
*pOut++ = (q7_t) __SSAT((sum >> out_shift), 8);
|
||||
}
|
||||
}
|
||||
#else
|
||||
/* Run the following code as reference implementation for Cortex-M0 and Cortex-M3 */
|
||||
|
||||
uint16_t i, j, k, l, m, n;
|
||||
int conv_out;
|
||||
signed char in_row, in_col;
|
||||
|
||||
for (i = 0; i < ch_im_out; i++)
|
||||
{
|
||||
for (j = 0; j < dim_im_out_y; j++)
|
||||
{
|
||||
for (k = 0; k < dim_im_out_x; k++)
|
||||
{
|
||||
conv_out = ((q31_t)bias[i] << bias_shift) + NN_ROUND(out_shift);
|
||||
for (m = 0; m < dim_kernel_y; m++)
|
||||
{
|
||||
for (n = 0; n < dim_kernel_x; n++)
|
||||
{
|
||||
// if-for implementation
|
||||
in_row = stride_y * j + m - padding_y;
|
||||
in_col = stride_x * k + n - padding_x;
|
||||
if (in_row >= 0 && in_col >= 0 && in_row < dim_im_in_y && in_col < dim_im_in_x)
|
||||
{
|
||||
for (l = 0; l < ch_im_in; l++)
|
||||
{
|
||||
conv_out +=
|
||||
Im_in[(in_row * dim_im_in_x + in_col) * ch_im_in + l] *
|
||||
wt[i * ch_im_in * dim_kernel_y * dim_kernel_x +
|
||||
(m * dim_kernel_x + n) * ch_im_in + l];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Im_out[i + (j * dim_im_out_x + k) * ch_im_out] = (q7_t) __SSAT((conv_out >> out_shift), 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* ARM_MATH_DSP */
|
||||
|
||||
/* Return to application */
|
||||
return ARM_MATH_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of NNConv group
|
||||
*/
|
@ -0,0 +1,408 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Project: CMSIS NN Library
|
||||
* Title: arm_convolve_HWC_q7_fast.c
|
||||
* Description: Fast Q7 version of convolution
|
||||
*
|
||||
* $Date: 17. January 2018
|
||||
* $Revision: V.1.0.0
|
||||
*
|
||||
* Target Processor: Cortex-M cores
|
||||
*
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
#include "arm_nnfunctions.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupNN
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup NNConv
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Fast Q7 convolution function
|
||||
* @param[in] Im_in pointer to input tensor
|
||||
* @param[in] dim_im_in input tensor dimention
|
||||
* @param[in] ch_im_in number of input tensor channels
|
||||
* @param[in] wt pointer to kernel weights
|
||||
* @param[in] ch_im_out number of filters, i.e., output tensor channels
|
||||
* @param[in] dim_kernel filter kernel size
|
||||
* @param[in] padding padding sizes
|
||||
* @param[in] stride convolution stride
|
||||
* @param[in] bias pointer to bias
|
||||
* @param[in] bias_shift amount of left-shift for bias
|
||||
* @param[in] out_shift amount of right-shift for output
|
||||
* @param[in,out] Im_out pointer to output tensor
|
||||
* @param[in] dim_im_out output tensor dimension
|
||||
* @param[in,out] bufferA pointer to buffer space for input
|
||||
* @param[in,out] bufferB pointer to buffer space for output
|
||||
* @return The function returns either
|
||||
* <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
|
||||
*
|
||||
* @details
|
||||
*
|
||||
* <b>Buffer size:</b>
|
||||
*
|
||||
* bufferA size: 2*ch_im_in*dim_kernel*dim_kernel
|
||||
*
|
||||
* bufferB size: 0
|
||||
*
|
||||
* <b>Input dimension constraints:</b>
|
||||
*
|
||||
* ch_im_in is multiple of 4 ( because of the SIMD32 read and swap )
|
||||
*
|
||||
* ch_im_out is multipe of 2 ( bacause 2x2 mat_mult kernel )
|
||||
*
|
||||
* The im2col converts the Q7 tensor input into Q15 column, which is stored in
|
||||
* bufferA. There is reordering happenning during this im2col process with
|
||||
* arm_q7_to_q15_reordered_no_shift. For every four elements, the second and
|
||||
* third elements are swapped.
|
||||
*
|
||||
* The computation kernel arm_nn_mat_mult_kernel_q7_q15_reordered does the
|
||||
* GEMM computation with the reordered columns.
|
||||
*
|
||||
* To speed-up the determination of the padding condition, we split the
|
||||
* computation into 3x3 parts, i.e., {top, mid, bottom} X {left, mid, right}.
|
||||
* This reduces the total number of boundary condition checks and improves
|
||||
* the data copying performance.
|
||||
*/
|
||||
|
||||
arm_status
|
||||
arm_convolve_HWC_q7_fast(const q7_t * Im_in,
|
||||
const uint16_t dim_im_in,
|
||||
const uint16_t ch_im_in,
|
||||
const q7_t * wt,
|
||||
const uint16_t ch_im_out,
|
||||
const uint16_t dim_kernel,
|
||||
const uint16_t padding,
|
||||
const uint16_t stride,
|
||||
const q7_t * bias,
|
||||
const uint16_t bias_shift,
|
||||
const uint16_t out_shift,
|
||||
q7_t * Im_out,
|
||||
const uint16_t dim_im_out,
|
||||
q15_t * bufferA,
|
||||
q7_t * bufferB)
|
||||
{
|
||||
|
||||
#if defined (ARM_MATH_DSP)
|
||||
/* Run the following code for Cortex-M4 and Cortex-M7 */
|
||||
|
||||
int16_t i_out_y, i_out_x, i_ker_y, i_ker_x;
|
||||
|
||||
/*
|
||||
* Here we use bufferA as q15_t internally as computation are done with q15_t level
|
||||
* im2col are done to output in q15_t format from q7_t input
|
||||
*/
|
||||
|
||||
q15_t *pBuffer = bufferA;
|
||||
q7_t *pOut = Im_out;
|
||||
|
||||
if (ch_im_in % 4 != 0 || ch_im_out % 2 != 0)
|
||||
{
|
||||
/* check if the input dimension meets the constraints */
|
||||
return ARM_MATH_SIZE_MISMATCH;
|
||||
}
|
||||
|
||||
/*
|
||||
* Here we split the entire matrix into three regions depending on the padding situation
|
||||
* Top: i_out_y from 0 to padding - 1
|
||||
* Middle: i_out_y from padding to dim_im_out-padding-1
|
||||
* Bottom: i_out_y from dim_im_out-padding to dim_im_out-1
|
||||
*/
|
||||
|
||||
/* top part */
|
||||
for (i_out_y = 0; i_out_y < padding; i_out_y++)
|
||||
{
|
||||
for (i_out_x = 0; i_out_x < dim_im_out; i_out_x++)
|
||||
{
|
||||
/* This part implements the im2col function */
|
||||
for (i_ker_y = i_out_y * stride - padding; i_ker_y < i_out_y * stride - padding + dim_kernel; i_ker_y++)
|
||||
{
|
||||
for (i_ker_x = i_out_x * stride - padding; i_ker_x < i_out_x * stride - padding + dim_kernel; i_ker_x++)
|
||||
{
|
||||
if (i_ker_y < 0 || i_ker_y >= dim_im_in || i_ker_x < 0 || i_ker_x >= dim_im_in)
|
||||
{
|
||||
/* arm_fill_q15(0, pBuffer, ch_im_in); */
|
||||
memset(pBuffer, 0, sizeof(q15_t)*ch_im_in);
|
||||
} else
|
||||
{
|
||||
arm_q7_to_q15_reordered_no_shift
|
||||
((q7_t *) Im_in + (i_ker_y * dim_im_in + i_ker_x) * ch_im_in, pBuffer, ch_im_in);
|
||||
}
|
||||
pBuffer += ch_im_in;
|
||||
}
|
||||
}
|
||||
|
||||
if (pBuffer == bufferA + 2 * ch_im_in * dim_kernel * dim_kernel)
|
||||
{
|
||||
pOut =
|
||||
arm_nn_mat_mult_kernel_q7_q15_reordered(wt,
|
||||
bufferA,
|
||||
ch_im_out,
|
||||
ch_im_in
|
||||
*
|
||||
dim_kernel * dim_kernel, bias_shift, out_shift, bias, pOut);
|
||||
/* counter reset */
|
||||
pBuffer = bufferA;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* middle part, here we also divide the x into left, mid and right */
|
||||
for (; i_out_y < dim_im_out - padding; i_out_y++)
|
||||
{
|
||||
|
||||
/* left part */
|
||||
for (i_out_x = 0; i_out_x < padding; i_out_x++)
|
||||
{
|
||||
/* This part implements the im2col function */
|
||||
for (i_ker_y = i_out_y * stride - padding; i_ker_y < i_out_y * stride - padding + dim_kernel; i_ker_y++)
|
||||
{
|
||||
for (i_ker_x = i_out_x * stride - padding; i_ker_x < i_out_x * stride - padding + dim_kernel; i_ker_x++)
|
||||
{
|
||||
if (i_ker_x < 0 || i_ker_x >= dim_im_in)
|
||||
{
|
||||
/* arm_fill_q15(0, pBuffer, ch_im_in); */
|
||||
memset(pBuffer, 0, sizeof(q15_t)*ch_im_in);
|
||||
} else
|
||||
{
|
||||
arm_q7_to_q15_reordered_no_shift
|
||||
((q7_t *) Im_in + (i_ker_y * dim_im_in + i_ker_x) * ch_im_in, pBuffer, ch_im_in);
|
||||
}
|
||||
pBuffer += ch_im_in;
|
||||
}
|
||||
}
|
||||
|
||||
if (pBuffer == bufferA + 2 * ch_im_in * dim_kernel * dim_kernel)
|
||||
{
|
||||
pOut =
|
||||
arm_nn_mat_mult_kernel_q7_q15_reordered(wt,
|
||||
bufferA,
|
||||
ch_im_out,
|
||||
ch_im_in
|
||||
*
|
||||
dim_kernel * dim_kernel, bias_shift, out_shift, bias, pOut);
|
||||
/* counter reset */
|
||||
pBuffer = bufferA;
|
||||
}
|
||||
}
|
||||
|
||||
/* mid part */
|
||||
for (; i_out_x < dim_im_out - padding; i_out_x++)
|
||||
{
|
||||
/* This part implements the im2col function */
|
||||
for (i_ker_y = i_out_y * stride - padding; i_ker_y < i_out_y * stride - padding + dim_kernel; i_ker_y++)
|
||||
{
|
||||
arm_q7_to_q15_reordered_no_shift((q7_t *) Im_in
|
||||
+
|
||||
(i_ker_y *
|
||||
dim_im_in +
|
||||
i_out_x *
|
||||
stride - padding) * ch_im_in, pBuffer, ch_im_in * dim_kernel);
|
||||
pBuffer += ch_im_in * dim_kernel;
|
||||
}
|
||||
|
||||
if (pBuffer == bufferA + 2 * ch_im_in * dim_kernel * dim_kernel)
|
||||
{
|
||||
pOut =
|
||||
arm_nn_mat_mult_kernel_q7_q15_reordered(wt,
|
||||
bufferA,
|
||||
ch_im_out,
|
||||
ch_im_in
|
||||
*
|
||||
dim_kernel * dim_kernel, bias_shift, out_shift, bias, pOut);
|
||||
/* counter reset */
|
||||
pBuffer = bufferA;
|
||||
}
|
||||
}
|
||||
|
||||
/* right part */
|
||||
for (; i_out_x < dim_im_out; i_out_x++)
|
||||
{
|
||||
/* This part implements the im2col function */
|
||||
for (i_ker_y = i_out_y * stride - padding; i_ker_y < i_out_y * stride - padding + dim_kernel; i_ker_y++)
|
||||
{
|
||||
for (i_ker_x = i_out_x * stride - padding; i_ker_x < i_out_x * stride - padding + dim_kernel; i_ker_x++)
|
||||
{
|
||||
if (i_ker_x < 0 || i_ker_x >= dim_im_in)
|
||||
{
|
||||
/* arm_fill_q15(0, pBuffer, ch_im_in); */
|
||||
memset(pBuffer, 0, sizeof(q15_t)*ch_im_in);
|
||||
} else
|
||||
{
|
||||
arm_q7_to_q15_reordered_no_shift
|
||||
((q7_t *) Im_in + (i_ker_y * dim_im_in + i_ker_x) * ch_im_in, pBuffer, ch_im_in);
|
||||
}
|
||||
pBuffer += ch_im_in;
|
||||
}
|
||||
}
|
||||
|
||||
if (pBuffer == bufferA + 2 * ch_im_in * dim_kernel * dim_kernel)
|
||||
{
|
||||
pOut =
|
||||
arm_nn_mat_mult_kernel_q7_q15_reordered(wt,
|
||||
bufferA,
|
||||
ch_im_out,
|
||||
ch_im_in
|
||||
*
|
||||
dim_kernel * dim_kernel, bias_shift, out_shift, bias, pOut);
|
||||
/* counter reset */
|
||||
pBuffer = bufferA;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (; i_out_y < dim_im_out; i_out_y++)
|
||||
{
|
||||
for (i_out_x = 0; i_out_x < dim_im_out; i_out_x++)
|
||||
{
|
||||
/* This part implements the im2col function */
|
||||
for (i_ker_y = i_out_y * stride - padding; i_ker_y < i_out_y * stride - padding + dim_kernel; i_ker_y++)
|
||||
{
|
||||
for (i_ker_x = i_out_x * stride - padding; i_ker_x < i_out_x * stride - padding + dim_kernel; i_ker_x++)
|
||||
{
|
||||
if (i_ker_y < 0 || i_ker_y >= dim_im_in || i_ker_x < 0 || i_ker_x >= dim_im_in)
|
||||
{
|
||||
/* arm_fill_q15(0, pBuffer, ch_im_in); */
|
||||
memset(pBuffer, 0, sizeof(q15_t)*ch_im_in);
|
||||
} else
|
||||
{
|
||||
arm_q7_to_q15_reordered_no_shift
|
||||
((q7_t *) Im_in + (i_ker_y * dim_im_in + i_ker_x) * ch_im_in, pBuffer, ch_im_in);
|
||||
}
|
||||
pBuffer += ch_im_in;
|
||||
}
|
||||
}
|
||||
|
||||
if (pBuffer == bufferA + 2 * ch_im_in * dim_kernel * dim_kernel)
|
||||
{
|
||||
pOut =
|
||||
arm_nn_mat_mult_kernel_q7_q15_reordered(wt,
|
||||
bufferA,
|
||||
ch_im_out,
|
||||
ch_im_in
|
||||
*
|
||||
dim_kernel * dim_kernel, bias_shift, out_shift, bias, pOut);
|
||||
/* counter reset */
|
||||
pBuffer = bufferA;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* check if there is left-over for compute */
|
||||
if (pBuffer != bufferA)
|
||||
{
|
||||
const q7_t *pA = wt;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ch_im_out; i++)
|
||||
{
|
||||
q31_t sum = ((q31_t)bias[i] << bias_shift) + NN_ROUND(out_shift);
|
||||
q15_t *pB = bufferA;
|
||||
/* each time it process 4 entries */
|
||||
uint16_t colCnt = ch_im_in * dim_kernel * dim_kernel >> 2;
|
||||
|
||||
while (colCnt)
|
||||
{
|
||||
|
||||
q31_t inA1, inA2;
|
||||
q31_t inB1, inB2;
|
||||
|
||||
pA = (q7_t *) read_and_pad_reordered((void *)pA, &inA1, &inA2);
|
||||
|
||||
inB1 = *__SIMD32(pB)++;
|
||||
sum = __SMLAD(inA1, inB1, sum);
|
||||
inB2 = *__SIMD32(pB)++;
|
||||
sum = __SMLAD(inA2, inB2, sum);
|
||||
|
||||
colCnt--;
|
||||
}
|
||||
colCnt = ch_im_in * dim_kernel * dim_kernel & 0x3;
|
||||
while (colCnt)
|
||||
{
|
||||
q7_t inA1 = *pA++;
|
||||
q15_t inB1 = *pB++;
|
||||
sum += inA1 * inB1;
|
||||
colCnt--;
|
||||
}
|
||||
*pOut = (q7_t) __SSAT((sum >> out_shift), 8);
|
||||
pOut++;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
#else
|
||||
/* Run the following code as reference implementation for Cortex-M0 and Cortex-M3 */
|
||||
|
||||
uint16_t i, j, k, l, m, n;
|
||||
int conv_out;
|
||||
signed char in_row, in_col;
|
||||
|
||||
if (ch_im_in % 4 != 0 || ch_im_out % 2 != 0)
|
||||
{
|
||||
/* check if the input dimension meets the constraints */
|
||||
return ARM_MATH_SIZE_MISMATCH;
|
||||
}
|
||||
|
||||
for (i = 0; i < ch_im_out; i++)
|
||||
{
|
||||
for (j = 0; j < dim_im_out; j++)
|
||||
{
|
||||
for (k = 0; k < dim_im_out; k++)
|
||||
{
|
||||
conv_out = (bias[i] << bias_shift) + NN_ROUND(out_shift);
|
||||
for (m = 0; m < dim_kernel; m++)
|
||||
{
|
||||
for (n = 0; n < dim_kernel; n++)
|
||||
{
|
||||
// if-for implementation
|
||||
in_row = stride * j + m - padding;
|
||||
in_col = stride * k + n - padding;
|
||||
if (in_row >= 0 && in_col >= 0 && in_row < dim_im_in && in_col < dim_im_in)
|
||||
{
|
||||
for (l = 0; l < ch_im_in; l++)
|
||||
{
|
||||
conv_out +=
|
||||
Im_in[(in_row * dim_im_in + in_col) * ch_im_in +
|
||||
l] * wt[i * ch_im_in * dim_kernel * dim_kernel + (m * dim_kernel +
|
||||
n) * ch_im_in + l];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Im_out[i + (j * dim_im_out + k) * ch_im_out] = (q7_t) __SSAT((conv_out >> out_shift), 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* ARM_MATH_DSP */
|
||||
|
||||
/* Return to application */
|
||||
return ARM_MATH_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of NNConv group
|
||||
*/
|
@ -0,0 +1,379 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Project: CMSIS NN Library
|
||||
* Title: arm_convolve_HWC_q7_fast_nonsquare.c
|
||||
* Description: Fast Q7 version of convolution (non-sqaure shape)
|
||||
*
|
||||
* $Date: 17. January 2018
|
||||
* $Revision: V.1.0.0
|
||||
*
|
||||
* Target Processor: Cortex-M cores
|
||||
*
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
#include "arm_nnfunctions.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupNN
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup NNConv
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Fast Q7 convolution function (non-sqaure shape)
|
||||
* @param[in] Im_in pointer to input tensor
|
||||
* @param[in] dim_im_in_x input tensor dimention x
|
||||
* @param[in] dim_im_in_y input tensor dimention y
|
||||
* @param[in] ch_im_in number of input tensor channels
|
||||
* @param[in] wt pointer to kernel weights
|
||||
* @param[in] ch_im_out number of filters, i.e., output tensor channels
|
||||
* @param[in] dim_kernel_x filter kernel size x
|
||||
* @param[in] dim_kernel_y filter kernel size y
|
||||
* @param[in] padding_x padding size x
|
||||
* @param[in] padding_y padding size y
|
||||
* @param[in] stride_x convolution stride x
|
||||
* @param[in] stride_y convolution stride y
|
||||
* @param[in] bias pointer to bias
|
||||
* @param[in] bias_shift amount of left-shift for bias
|
||||
* @param[in] out_shift amount of right-shift for output
|
||||
* @param[in,out] Im_out pointer to output tensor
|
||||
* @param[in] dim_im_out_x output tensor dimension x
|
||||
* @param[in] dim_im_out_y output tensor dimension y
|
||||
* @param[in,out] bufferA pointer to buffer space for input
|
||||
* @param[in,out] bufferB pointer to buffer space for output
|
||||
* @return The function returns either
|
||||
* <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
|
||||
*
|
||||
* This function is the version with full list of optimization tricks, but with
|
||||
* some contraints:
|
||||
* ch_im_in is multiple of 4
|
||||
* ch_im_out is multiple of 2
|
||||
*/
|
||||
|
||||
arm_status arm_convolve_HWC_q7_fast_nonsquare(const q7_t * Im_in,
|
||||
const uint16_t dim_im_in_x,
|
||||
const uint16_t dim_im_in_y,
|
||||
const uint16_t ch_im_in,
|
||||
const q7_t * wt,
|
||||
const uint16_t ch_im_out,
|
||||
const uint16_t dim_kernel_x,
|
||||
const uint16_t dim_kernel_y,
|
||||
const uint16_t padding_x,
|
||||
const uint16_t padding_y,
|
||||
const uint16_t stride_x,
|
||||
const uint16_t stride_y,
|
||||
const q7_t * bias,
|
||||
const uint16_t bias_shift,
|
||||
const uint16_t out_shift,
|
||||
q7_t * Im_out,
|
||||
const uint16_t dim_im_out_x,
|
||||
const uint16_t dim_im_out_y,
|
||||
q15_t * bufferA,
|
||||
q7_t * bufferB)
|
||||
{
|
||||
|
||||
#if defined (ARM_MATH_DSP)
|
||||
/* Run the following code for Cortex-M4 and Cortex-M7 */
|
||||
|
||||
int16_t i_out_y, i_out_x, i_ker_y, i_ker_x;
|
||||
|
||||
/* -----------------------
|
||||
* Here we use bufferA as q15_t internally as computation are done with q15_t level
|
||||
* im2col are done to output in q15_t format from q7_t input
|
||||
*/
|
||||
|
||||
q15_t *pBuffer = bufferA;
|
||||
q7_t *pOut = Im_out;
|
||||
|
||||
if (ch_im_in % 4 != 0 || ch_im_out % 2 != 0)
|
||||
{
|
||||
/* check if the input dimension meets the constraints */
|
||||
return ARM_MATH_SIZE_MISMATCH;
|
||||
}
|
||||
|
||||
/*
|
||||
* Here we split the entire matrix into three regions depending on the padding situation
|
||||
* Top: i_out_y from 0 to padding - 1
|
||||
* Middle: i_out_y from padding to dim_im_out-padding-1
|
||||
* Bottom: i_out_y from dim_im_out-padding to dim_im_out-1
|
||||
*/
|
||||
|
||||
/* top part */
|
||||
for (i_out_y = 0; i_out_y < padding_y; i_out_y++)
|
||||
{
|
||||
for (i_out_x = 0; i_out_x < dim_im_out_x; i_out_x++)
|
||||
{
|
||||
/* This part implements the im2col function */
|
||||
for (i_ker_y = i_out_y * stride_y - padding_y; i_ker_y < i_out_y * stride_y - padding_y + dim_kernel_y;
|
||||
i_ker_y++)
|
||||
{
|
||||
for (i_ker_x = i_out_x * stride_x - padding_x; i_ker_x < i_out_x * stride_x - padding_x + dim_kernel_x;
|
||||
i_ker_x++)
|
||||
{
|
||||
if (i_ker_y < 0 || i_ker_y >= dim_im_in_y || i_ker_x < 0 || i_ker_x >= dim_im_in_x)
|
||||
{
|
||||
/* arm_fill_q15(0, pBuffer, ch_im_in); */
|
||||
memset(pBuffer, 0, sizeof(q15_t)*ch_im_in);
|
||||
} else
|
||||
{
|
||||
arm_q7_to_q15_reordered_no_shift((q7_t *) Im_in + (i_ker_y * dim_im_in_x + i_ker_x) * ch_im_in,
|
||||
pBuffer, ch_im_in);
|
||||
}
|
||||
pBuffer += ch_im_in;
|
||||
}
|
||||
}
|
||||
|
||||
if (pBuffer == bufferA + 2 * ch_im_in * dim_kernel_x * dim_kernel_y)
|
||||
{
|
||||
pOut =
|
||||
arm_nn_mat_mult_kernel_q7_q15_reordered(wt, bufferA, ch_im_out, ch_im_in * dim_kernel_x * dim_kernel_y,
|
||||
bias_shift, out_shift, bias, pOut);
|
||||
/* counter reset */
|
||||
pBuffer = bufferA;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* middle part, here we also divide the x into left, mid and right */
|
||||
for (; i_out_y < dim_im_out_y - padding_y; i_out_y++)
|
||||
{
|
||||
|
||||
/* left part */
|
||||
for (i_out_x = 0; i_out_x < padding_x; i_out_x++)
|
||||
{
|
||||
/* This part implements the im2col function */
|
||||
for (i_ker_y = i_out_y * stride_y - padding_y; i_ker_y < i_out_y * stride_y - padding_y + dim_kernel_y;
|
||||
i_ker_y++)
|
||||
{
|
||||
for (i_ker_x = i_out_x * stride_x - padding_x; i_ker_x < i_out_x * stride_x - padding_x + dim_kernel_x;
|
||||
i_ker_x++)
|
||||
{
|
||||
if (i_ker_x < 0 || i_ker_x >= dim_im_in_x)
|
||||
{
|
||||
/* arm_fill_q15(0, pBuffer, ch_im_in); */
|
||||
memset(pBuffer, 0, sizeof(q15_t)*ch_im_in);
|
||||
} else
|
||||
{
|
||||
arm_q7_to_q15_reordered_no_shift((q7_t *) Im_in + (i_ker_y * dim_im_in_x + i_ker_x) * ch_im_in,
|
||||
pBuffer, ch_im_in);
|
||||
}
|
||||
pBuffer += ch_im_in;
|
||||
}
|
||||
}
|
||||
|
||||
if (pBuffer == bufferA + 2 * ch_im_in * dim_kernel_x * dim_kernel_y)
|
||||
{
|
||||
pOut =
|
||||
arm_nn_mat_mult_kernel_q7_q15_reordered(wt, bufferA, ch_im_out, ch_im_in * dim_kernel_x * dim_kernel_y,
|
||||
bias_shift, out_shift, bias, pOut);
|
||||
/* counter reset */
|
||||
pBuffer = bufferA;
|
||||
}
|
||||
}
|
||||
|
||||
/* mid part */
|
||||
for (; i_out_x < dim_im_out_x - padding_x; i_out_x++)
|
||||
{
|
||||
/* This part implements the im2col function */
|
||||
for (i_ker_y = i_out_y * stride_y - padding_y; i_ker_y < i_out_y * stride_y - padding_y + dim_kernel_y;
|
||||
i_ker_y++)
|
||||
{
|
||||
arm_q7_to_q15_reordered_no_shift((q7_t *) Im_in +
|
||||
(i_ker_y * dim_im_in_x + i_out_x * stride_x - padding_x) * ch_im_in,
|
||||
pBuffer, ch_im_in * dim_kernel_x);
|
||||
pBuffer += ch_im_in * dim_kernel_x;
|
||||
}
|
||||
|
||||
if (pBuffer == bufferA + 2 * ch_im_in * dim_kernel_x * dim_kernel_y)
|
||||
{
|
||||
pOut =
|
||||
arm_nn_mat_mult_kernel_q7_q15_reordered(wt, bufferA, ch_im_out, ch_im_in * dim_kernel_x * dim_kernel_y,
|
||||
bias_shift, out_shift, bias, pOut);
|
||||
/* counter reset */
|
||||
pBuffer = bufferA;
|
||||
}
|
||||
}
|
||||
|
||||
/* right part */
|
||||
for (; i_out_x < dim_im_out_x; i_out_x++)
|
||||
{
|
||||
/* This part implements the im2col function */
|
||||
for (i_ker_y = i_out_y * stride_y - padding_y; i_ker_y < i_out_y * stride_y - padding_y + dim_kernel_y;
|
||||
i_ker_y++)
|
||||
{
|
||||
for (i_ker_x = i_out_x * stride_x - padding_x; i_ker_x < i_out_x * stride_x - padding_x + dim_kernel_x;
|
||||
i_ker_x++)
|
||||
{
|
||||
if (i_ker_x < 0 || i_ker_x >= dim_im_in_x)
|
||||
{
|
||||
/* arm_fill_q15(0, pBuffer, ch_im_in); */
|
||||
memset(pBuffer, 0, sizeof(q15_t)*ch_im_in);
|
||||
} else
|
||||
{
|
||||
arm_q7_to_q15_reordered_no_shift((q7_t *) Im_in + (i_ker_y * dim_im_in_x + i_ker_x) * ch_im_in,
|
||||
pBuffer, ch_im_in);
|
||||
}
|
||||
pBuffer += ch_im_in;
|
||||
}
|
||||
}
|
||||
|
||||
if (pBuffer == bufferA + 2 * ch_im_in * dim_kernel_x * dim_kernel_y)
|
||||
{
|
||||
pOut =
|
||||
arm_nn_mat_mult_kernel_q7_q15_reordered(wt, bufferA, ch_im_out, ch_im_in * dim_kernel_x * dim_kernel_y,
|
||||
bias_shift, out_shift, bias, pOut);
|
||||
/* counter reset */
|
||||
pBuffer = bufferA;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (; i_out_y < dim_im_out_y; i_out_y++)
|
||||
{
|
||||
for (i_out_x = 0; i_out_x < dim_im_out_x; i_out_x++)
|
||||
{
|
||||
/* This part implements the im2col function */
|
||||
for (i_ker_y = i_out_y * stride_y - padding_y; i_ker_y < i_out_y * stride_y - padding_y + dim_kernel_y;
|
||||
i_ker_y++)
|
||||
{
|
||||
for (i_ker_x = i_out_x * stride_x - padding_x; i_ker_x < i_out_x * stride_x - padding_x + dim_kernel_x;
|
||||
i_ker_x++)
|
||||
{
|
||||
if (i_ker_y < 0 || i_ker_y >= dim_im_in_y || i_ker_x < 0 || i_ker_x >= dim_im_in_x)
|
||||
{
|
||||
/* arm_fill_q15(0, pBuffer, ch_im_in); */
|
||||
memset(pBuffer, 0, sizeof(q15_t)*ch_im_in);
|
||||
} else
|
||||
{
|
||||
arm_q7_to_q15_reordered_no_shift((q7_t *) Im_in + (i_ker_y * dim_im_in_x + i_ker_x) * ch_im_in,
|
||||
pBuffer, ch_im_in);
|
||||
}
|
||||
pBuffer += ch_im_in;
|
||||
}
|
||||
}
|
||||
|
||||
if (pBuffer == bufferA + 2 * ch_im_in * dim_kernel_x * dim_kernel_y)
|
||||
{
|
||||
pOut =
|
||||
arm_nn_mat_mult_kernel_q7_q15_reordered(wt, bufferA, ch_im_out, ch_im_in * dim_kernel_x * dim_kernel_y,
|
||||
bias_shift, out_shift, bias, pOut);
|
||||
/* counter reset */
|
||||
pBuffer = bufferA;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* check if there is left-over for compute */
|
||||
if (pBuffer != bufferA)
|
||||
{
|
||||
const q7_t *pA = wt;
|
||||
int i;
|
||||
for (i = 0; i < ch_im_out; i++)
|
||||
{
|
||||
q31_t sum = ((q31_t)(bias[i]) << bias_shift) + NN_ROUND(out_shift);
|
||||
q15_t *pB = bufferA;
|
||||
/* basically each time it process 4 entries */
|
||||
uint16_t colCnt = ch_im_in * dim_kernel_x * dim_kernel_y >> 2;
|
||||
|
||||
while (colCnt)
|
||||
{
|
||||
|
||||
q31_t inA1, inA2;
|
||||
q31_t inB1, inB2;
|
||||
|
||||
pA = (const q7_t *)read_and_pad_reordered((void *)pA, &inA1, &inA2);
|
||||
|
||||
inB1 = *__SIMD32(pB)++;
|
||||
sum = __SMLAD(inA1, inB1, sum);
|
||||
inB2 = *__SIMD32(pB)++;
|
||||
sum = __SMLAD(inA2, inB2, sum);
|
||||
|
||||
colCnt--;
|
||||
}
|
||||
colCnt = (ch_im_in * dim_kernel_y * dim_kernel_x) & 0x3;
|
||||
while (colCnt)
|
||||
{
|
||||
q7_t inA1 = *pA++;
|
||||
q15_t inB1 = *pB++;
|
||||
sum += inA1 * inB1;
|
||||
colCnt--;
|
||||
}
|
||||
*pOut = (q7_t) __SSAT((sum >> out_shift), 8);
|
||||
pOut++;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#else
|
||||
/* Run the following code as reference implementation for Cortex-M0 and Cortex-M3 */
|
||||
int i, j, k, l, m, n;
|
||||
int conv_out;
|
||||
int in_row, in_col;
|
||||
|
||||
if (ch_im_in % 4 != 0 || ch_im_out % 2 != 0)
|
||||
{
|
||||
/* check if the input dimension meets the constraints */
|
||||
return ARM_MATH_SIZE_MISMATCH;
|
||||
}
|
||||
|
||||
for (i = 0; i < ch_im_out; i++)
|
||||
{
|
||||
for (j = 0; j < dim_im_out_y; j++)
|
||||
{
|
||||
for (k = 0; k < dim_im_out_x; k++)
|
||||
{
|
||||
conv_out = ((q31_t)(bias[i]) << bias_shift) + NN_ROUND(out_shift);
|
||||
for (m = 0; m < dim_kernel_y; m++)
|
||||
{
|
||||
for (n = 0; n < dim_kernel_x; n++)
|
||||
{
|
||||
/* if-for implementation */
|
||||
in_row = stride_y * j + m - padding_y;
|
||||
in_col = stride_x * k + n - padding_x;
|
||||
if (in_row >= 0 && in_col >= 0 && in_row < dim_im_in_y && in_col < dim_im_in_x)
|
||||
{
|
||||
for (l = 0; l < ch_im_in; l++)
|
||||
{
|
||||
conv_out += Im_in[(in_row * dim_im_in_x + in_col) * ch_im_in + l] *
|
||||
wt[i * ch_im_in * dim_kernel_y * dim_kernel_x + (m * dim_kernel_x + n) * ch_im_in + l];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Im_out[i + (j * dim_im_out_x + k) * ch_im_out] = (q7_t) __SSAT((conv_out >> out_shift), 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif /* ARM_MATH_DSP */
|
||||
|
||||
/* Return to application */
|
||||
return ARM_MATH_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of NNConv group
|
||||
*/
|
@ -0,0 +1,239 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2019 Arm Limited or its affiliates. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Project: CMSIS NN Library
|
||||
* Title: arm_depthwise_conv_u8_basic_ver1.c
|
||||
* Description: u8 depthwise convolution function
|
||||
*
|
||||
* $Date: June, 2019
|
||||
* $Revision: V.0.8.0
|
||||
*
|
||||
* Target : Cortex-M cores with DSP extension
|
||||
*
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
#include "arm_nnfunctions.h"
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define DILATION_X (1)
|
||||
#define DILATION_Y (1)
|
||||
|
||||
/**
|
||||
* @ingroup groupNN
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup NNConv
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief uint8 depthwise convolution function with asymmetric quantization for even number of channel multiplier
|
||||
* and input channels. Unless specified otherwise, arguments are mandatory. Both square and non-square inputs
|
||||
* are accepted.
|
||||
*
|
||||
* @param[in] input Pointer to input tensor
|
||||
* @param[in] input_x Width of input tensor
|
||||
* @param[in] input_y Height of input tensor
|
||||
* @param[in] input_ch Channels in input tensor
|
||||
* @param[in] kernel Pointer to kernel weights
|
||||
* @param[in] kernel_x Width of kernel
|
||||
* @param[in] kernel_y Height of kernel
|
||||
* @param[in] ch_mult Number of channel multiplier
|
||||
* @param[in] pad_x Padding sizes x
|
||||
* @param[in] pad_y Padding sizes y
|
||||
* @param[in] stride_x Convolution stride along the width
|
||||
* @param[in] stride_y Convolution stride along the height
|
||||
* @param[in] dilation_x Dilation along width. Not used and intended for future enhancement.
|
||||
* @param[in] dilation_y Dilation along height. Not used and intended for future enhancement.
|
||||
* @param[in] bias Pointer to optional bias values. If no bias is
|
||||
* availble, NULL is expected
|
||||
* @param[in] input_offset Input tensor zero offset
|
||||
* @param[in] filter_offset Kernel tensor zero offset
|
||||
* @param[in] output_offset Output tensor zero offset
|
||||
* @param[in,out] output Pointer to output tensor
|
||||
* @param[in] output_x Width of output tensor
|
||||
* @param[in] output_y Height of output tensor
|
||||
* @param[in] output_activation_min Minimum value to clamp the output to. Range : {0, 255}
|
||||
* @param[in] output_activation_max Minimum value to clamp the output to. Range : {0, 255}
|
||||
* @param[in] out_shift Amount of right-shift for output
|
||||
* @param[in] out_mult Output multiplier for requantization
|
||||
* @return The function returns one of the following
|
||||
* <code>ARM_MATH_SIZE_MISMATCH</code> - Not supported dimension of tensors
|
||||
* <code>ARM_MATH_SUCCESS</code> - Successful operation
|
||||
* <code>ARM_MATH_ARGUMENT_ERROR</code> - Implementation not available
|
||||
*
|
||||
* <b> Input constraints</b>
|
||||
* ch_mult is multiple of 2
|
||||
* kernel_x is multiple of 2
|
||||
*
|
||||
*/
|
||||
|
||||
arm_status arm_depthwise_conv_u8_basic_ver1(const uint8_t *input,
|
||||
const uint16_t input_x,
|
||||
const uint16_t input_y,
|
||||
const uint16_t input_ch,
|
||||
const uint8_t *kernel,
|
||||
const uint16_t kernel_x,
|
||||
const uint16_t kernel_y,
|
||||
const int16_t ch_mult,
|
||||
const int16_t pad_x,
|
||||
const int16_t pad_y,
|
||||
const int16_t stride_x,
|
||||
const int16_t stride_y,
|
||||
const int16_t dilation_x,
|
||||
const int16_t dilation_y,
|
||||
const int32_t *bias,
|
||||
const int32_t input_offset,
|
||||
const int32_t filter_offset,
|
||||
const int32_t output_offset,
|
||||
uint8_t *output,
|
||||
const uint16_t output_x,
|
||||
const uint16_t output_y,
|
||||
const int32_t output_activation_min,
|
||||
const int32_t output_activation_max,
|
||||
const int32_t out_shift,
|
||||
const int32_t out_mult)
|
||||
{
|
||||
arm_status status = ARM_MATH_SUCCESS;
|
||||
#if defined (ARM_MATH_DSP)
|
||||
int i_out = 0;
|
||||
(void)dilation_x;
|
||||
(void)dilation_y;
|
||||
|
||||
const int32_t input_offset_pkd = (input_offset & 0xFFFF) | (input_offset & 0xFFFF) << 16;
|
||||
const int32_t kernel_offset_pkd = (filter_offset & 0xFFFF) | (filter_offset & 0xFFFF) << 16;
|
||||
|
||||
if (0 != ch_mult % 2 || 0 != kernel_x % 2)
|
||||
{
|
||||
return ARM_MATH_SIZE_MISMATCH;
|
||||
}
|
||||
|
||||
for (int i_out_y = 0; i_out_y < output_y; i_out_y++)
|
||||
{
|
||||
const int16_t base_idx_y = (i_out_y * stride_y) - pad_y;
|
||||
for (int i_out_x = 0; i_out_x < output_x; i_out_x++)
|
||||
{
|
||||
const int16_t base_idx_x = (i_out_x * stride_x) - pad_x;
|
||||
for (int i_input_ch = 0; i_input_ch < input_ch; i_input_ch++)
|
||||
{
|
||||
for (int i_ch_mult = 0; i_ch_mult < ch_mult; i_ch_mult += 2)
|
||||
{
|
||||
const int idx_out_ch = i_ch_mult + i_input_ch * ch_mult;
|
||||
|
||||
int32_t acc_0 = 0;
|
||||
int32_t acc_1 = 0;
|
||||
if (NULL != bias)
|
||||
{
|
||||
acc_0 = bias[idx_out_ch];
|
||||
acc_1 = bias[idx_out_ch + 1];
|
||||
}
|
||||
|
||||
for (int i_ker_y = 0; i_ker_y < kernel_y; i_ker_y++)
|
||||
{
|
||||
const int32_t idx_y = base_idx_y + DILATION_Y * i_ker_y;
|
||||
const int32_t y_in_range = (idx_y >= 0) && (idx_y < input_y);
|
||||
|
||||
for (int i_ker_x = 0; i_ker_x < kernel_x; i_ker_x += 2)
|
||||
{
|
||||
if (1 == y_in_range)
|
||||
{
|
||||
const int32_t idx_x = base_idx_x + DILATION_X * i_ker_x;
|
||||
const int32_t idx_x1 = base_idx_x + DILATION_X * (i_ker_x + 1);
|
||||
/* Range check for first input */
|
||||
if (idx_x >= 0 && idx_x < input_x)
|
||||
{
|
||||
const int32_t idx_0 = (idx_y * input_x + idx_x) * input_ch + i_input_ch;
|
||||
|
||||
const int32_t ker_idx_0 =
|
||||
(i_ker_y * kernel_x + i_ker_x) * (input_ch * ch_mult) + idx_out_ch;
|
||||
const int32_t ker_idx_1 = ker_idx_0 + input_ch * ch_mult;
|
||||
|
||||
int32_t input_pkd = input[idx_0] | (input[idx_0 + input_ch] << 16);
|
||||
int32_t kernel_pkd = kernel[ker_idx_0] | (kernel[ker_idx_1] << 16);
|
||||
|
||||
input_pkd = __SADD16(input_pkd, input_offset_pkd);
|
||||
kernel_pkd = __SADD16(kernel_pkd, kernel_offset_pkd);
|
||||
/* Range check for second input */
|
||||
if (idx_x1 >= input_x)
|
||||
{
|
||||
input_pkd &= 0xFFFF;
|
||||
}
|
||||
acc_0 = __SMLAD(input_pkd, kernel_pkd, acc_0);
|
||||
|
||||
kernel_pkd = kernel[ker_idx_0 + 1] | (kernel[ker_idx_1 + 1] << 16);
|
||||
kernel_pkd = __SADD16(kernel_pkd, kernel_offset_pkd);
|
||||
acc_1 = __SMLAD(input_pkd, kernel_pkd, acc_1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Requantize and clamp output to provided range */
|
||||
acc_0 = arm_nn_divide_by_power_of_two(arm_nn_sat_doubling_high_mult(
|
||||
acc_0 * (1 << LEFT_SHIFT(out_shift)), out_mult),
|
||||
RIGHT_SHIFT(out_shift));
|
||||
|
||||
acc_0 += output_offset;
|
||||
|
||||
if (output_activation_min > acc_0)
|
||||
{
|
||||
acc_0 = output_activation_min;
|
||||
}
|
||||
|
||||
if (acc_0 > output_activation_max)
|
||||
{
|
||||
acc_0 = output_activation_max;
|
||||
}
|
||||
output[i_out++] = acc_0;
|
||||
|
||||
/* Requantize and clamp output to provided range */
|
||||
acc_1 = arm_nn_divide_by_power_of_two(arm_nn_sat_doubling_high_mult(
|
||||
acc_1 * (1 << LEFT_SHIFT(out_shift)), out_mult),
|
||||
RIGHT_SHIFT(out_shift));
|
||||
acc_1 += output_offset;
|
||||
|
||||
if (output_activation_min > acc_1)
|
||||
{
|
||||
acc_1 = output_activation_min;
|
||||
}
|
||||
|
||||
if (acc_1 > output_activation_max)
|
||||
{
|
||||
acc_1 = output_activation_max;
|
||||
}
|
||||
output[i_out++] = acc_1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
/* No available implementation. */
|
||||
status = ARM_MATH_ARGUMENT_ERROR;
|
||||
#endif
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of NNConv group
|
||||
*/
|
||||
|
||||
|
@ -0,0 +1,418 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Project: CMSIS NN Library
|
||||
* Title: arm_depthwise_separable_conv_HWC_q7.c
|
||||
* Description: Q7 depthwise separable convolution function
|
||||
*
|
||||
* $Date: 17. January 2018
|
||||
* $Revision: V.1.0.0
|
||||
*
|
||||
* Target Processor: Cortex-M cores
|
||||
*
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
#include "arm_nnfunctions.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupNN
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup NNConv
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Q7 depthwise separable convolution function
|
||||
* @param[in] Im_in pointer to input tensor
|
||||
* @param[in] dim_im_in input tensor dimention
|
||||
* @param[in] ch_im_in number of input tensor channels
|
||||
* @param[in] wt pointer to kernel weights
|
||||
* @param[in] ch_im_out number of filters, i.e., output tensor channels
|
||||
* @param[in] dim_kernel filter kernel size
|
||||
* @param[in] padding padding sizes
|
||||
* @param[in] stride convolution stride
|
||||
* @param[in] bias pointer to bias
|
||||
* @param[in] bias_shift amount of left-shift for bias
|
||||
* @param[in] out_shift amount of right-shift for output
|
||||
* @param[in,out] Im_out pointer to output tensor
|
||||
* @param[in] dim_im_out output tensor dimension
|
||||
* @param[in,out] bufferA pointer to buffer space for input
|
||||
* @param[in,out] bufferB pointer to buffer space for output
|
||||
* @return The function returns either
|
||||
* <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
|
||||
*
|
||||
* @details
|
||||
*
|
||||
* <b>Buffer size:</b>
|
||||
*
|
||||
* bufferA size: 2*ch_im_in*dim_kernel*dim_kernel
|
||||
*
|
||||
* bufferB size: 0
|
||||
*
|
||||
* <b>Input dimension constraints:</b>
|
||||
*
|
||||
* ch_im_in equals ch_im_out
|
||||
*
|
||||
* Implementation:
|
||||
* There are 3 nested loop here:
|
||||
* Inner loop: calculate each output value with MAC instruction over an accumulator
|
||||
* Mid loop: loop over different output channel
|
||||
* Outer loop: loop over different output (x, y)
|
||||
*/
|
||||
|
||||
arm_status arm_depthwise_separable_conv_HWC_q7(const q7_t * Im_in,
|
||||
const uint16_t dim_im_in,
|
||||
const uint16_t ch_im_in,
|
||||
const q7_t * wt,
|
||||
const uint16_t ch_im_out,
|
||||
const uint16_t dim_kernel,
|
||||
const uint16_t padding,
|
||||
const uint16_t stride,
|
||||
const q7_t * bias,
|
||||
const uint16_t bias_shift,
|
||||
const uint16_t out_shift,
|
||||
q7_t * Im_out,
|
||||
const uint16_t dim_im_out,
|
||||
q15_t * bufferA,
|
||||
q7_t * bufferB)
|
||||
{
|
||||
|
||||
#if defined (ARM_MATH_DSP)
|
||||
/* Run the following code for Cortex-M4 and Cortex-M7 */
|
||||
|
||||
int16_t i_out_y, i_out_x;
|
||||
int16_t i_ker_y, i_ker_x;
|
||||
q7_t *colBuffer = (q7_t *) bufferA;
|
||||
q7_t *pBuffer = colBuffer;
|
||||
const q7_t *pBias = bias;
|
||||
q7_t *pOut = Im_out;
|
||||
uint16_t rowCnt;
|
||||
uint16_t row_shift;
|
||||
|
||||
/* do some checking here, basically ch_im_in == ch_im_out */
|
||||
if (ch_im_in != ch_im_out)
|
||||
{
|
||||
return ARM_MATH_SIZE_MISMATCH;
|
||||
}
|
||||
|
||||
for (i_out_y = 0; i_out_y < dim_im_out; i_out_y++)
|
||||
{
|
||||
for (i_out_x = 0; i_out_x < dim_im_out; i_out_x++)
|
||||
{
|
||||
/* we first do im2col here */
|
||||
for (i_ker_y = i_out_y * stride - padding; i_ker_y < i_out_y * stride - padding + dim_kernel; i_ker_y++)
|
||||
{
|
||||
for (i_ker_x = i_out_x * stride - padding; i_ker_x < i_out_x * stride - padding + dim_kernel; i_ker_x++)
|
||||
{
|
||||
if (i_ker_y < 0 || i_ker_y >= dim_im_in || i_ker_x < 0 || i_ker_x >= dim_im_in)
|
||||
{
|
||||
/* arm_fill_q7(0, pBuffer, ch_im_in); */
|
||||
memset(pBuffer, 0, ch_im_in);
|
||||
} else
|
||||
{
|
||||
/* arm_copy_q7((q7_t *) Im_in + (i_ker_y * dim_im_in + i_ker_x) * ch_im_in, pBuffer, ch_im_in); */
|
||||
memcpy(pBuffer, (q7_t *) Im_in + (i_ker_y * dim_im_in + i_ker_x) * ch_im_in, ch_im_in);
|
||||
}
|
||||
pBuffer += ch_im_in;
|
||||
}
|
||||
}
|
||||
|
||||
/* we will do the computation here for each channel */
|
||||
rowCnt = ch_im_out >> 2;
|
||||
row_shift = 0;
|
||||
pBias = bias;
|
||||
|
||||
while (rowCnt)
|
||||
{
|
||||
q31_t sum = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift);
|
||||
q31_t sum2 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift);
|
||||
q31_t sum3 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift);
|
||||
q31_t sum4 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift);
|
||||
|
||||
uint16_t colCnt = (dim_kernel * dim_kernel) >> 1;
|
||||
q7_t *pB = colBuffer + row_shift;
|
||||
const q7_t *pA = wt + row_shift;
|
||||
row_shift += 4;
|
||||
|
||||
#ifdef USE_INTRINSIC
|
||||
|
||||
#ifndef ARM_MATH_BIG_ENDIAN
|
||||
|
||||
while (colCnt)
|
||||
{
|
||||
q31_t inA1, inA2, inB1, inB2, opA, opB;
|
||||
|
||||
inB1 = *__SIMD32(pB);
|
||||
pB += ch_im_in;
|
||||
opB = *__SIMD32(pB);
|
||||
pB += ch_im_in;
|
||||
inB2 = __PKHTB(opB, inB1, 16);
|
||||
inB1 = __PKHBT(inB1, opB, 16);
|
||||
inA1 = *__SIMD32(pA);
|
||||
pA += ch_im_in;
|
||||
opB = *__SIMD32(pA);
|
||||
pA += ch_im_in;
|
||||
inA2 = __PKHTB(opB, inA1, 16);
|
||||
inA1 = __PKHBT(inA1, opB, 16);
|
||||
opA = __SXTB16(inA1);
|
||||
opB = __SXTB16(inB1);
|
||||
sum = __SMLAD(opA, opB, sum);
|
||||
opA = __SXTB16(__ROR(inA1, 8));
|
||||
opB = __SXTB16(__ROR(inB1, 8));
|
||||
sum2 = __SMLAD(opA, opB, sum2);
|
||||
opA = __SXTB16(inA2);
|
||||
opB = __SXTB16(inB2);
|
||||
sum3 = __SMLAD(opA, opB, sum3);
|
||||
opA = __SXTB16(__ROR(inA2, 8));
|
||||
opB = __SXTB16(__ROR(inB2, 8));
|
||||
sum4 = __SMLAD(opA, opB, sum4);
|
||||
colCnt--;
|
||||
}
|
||||
#else
|
||||
|
||||
while (colCnt)
|
||||
{
|
||||
q31_t inA1, inA2, inB1, inB2, opA, opB;
|
||||
|
||||
inB1 = *__SIMD32(pB);
|
||||
pB += ch_im_in;
|
||||
opB = *__SIMD32(pB);
|
||||
pB += ch_im_in;
|
||||
inB2 = __PKHBT(opB, inB1, 16);
|
||||
inB1 = __PKHTB(inB1, opB, 16);
|
||||
inA1 = *__SIMD32(pA);
|
||||
pA += ch_im_in;
|
||||
opB = *__SIMD32(pA);
|
||||
pA += ch_im_in;
|
||||
inA2 = __PKHBT(opB, inA1, 16);
|
||||
inA1 = __PKHTB(inA1, opB, 16);
|
||||
opA = __SXTB16(inA1);
|
||||
opB = __SXTB16(inB1);
|
||||
sum2 = __SMLAD(opA, opB, sum2);
|
||||
opA = __SXTB16(__ROR(inA1, 8));
|
||||
opB = __SXTB16(__ROR(inB1, 8));
|
||||
sum = __SMLAD(opA, opB, sum);
|
||||
opA = __SXTB16(inA2);
|
||||
opB = __SXTB16(inB2);
|
||||
sum4 = __SMLAD(opA, opB, sum4);
|
||||
opA = __SXTB16(__ROR(inA2, 8));
|
||||
opB = __SXTB16(__ROR(inB2, 8));
|
||||
sum3 = __SMLAD(opA, opB, sum3);
|
||||
colCnt--;
|
||||
}
|
||||
|
||||
#endif /* ARM_MATH_BIG_ENDIAN */
|
||||
|
||||
#else
|
||||
|
||||
#ifndef ARM_MATH_BIG_ENDIAN
|
||||
/*
|
||||
* r0 r1 r2 r3 r4 r5
|
||||
* inA1, inA2, inB1, inB2, opA, opB
|
||||
*/
|
||||
|
||||
asm volatile ("COL_LOOP_%=:\n"
|
||||
"ldr.w r2, [%[pB], #0]\n"
|
||||
"add.w %[pB], %[pB], %[ch_im_in]\n"
|
||||
"ldr.w r5, [%[pB], #0]\n"
|
||||
"add.w %[pB], %[pB], %[ch_im_in]\n"
|
||||
"pkhtb r3, r5, r2, ASR #16\n"
|
||||
"pkhbt r2, r2, r5, LSL #16\n"
|
||||
"ldr.w r0, [%[pA], #0]\n"
|
||||
"add.w %[pA], %[pA], %[ch_im_in]\n"
|
||||
"ldr.w r5, [%[pA], #0]\n"
|
||||
"add.w %[pA], %[pA], %[ch_im_in]\n"
|
||||
"pkhtb r1, r5, r0, ASR #16\n"
|
||||
"pkhbt r0, r0, r5, LSL #16\n"
|
||||
"sxtb16 r4, r0\n"
|
||||
"sxtb16 r5, r2\n"
|
||||
"smlad %[sum], r4, r5, %[sum]\n"
|
||||
"mov.w r4, r0, ror #8\n"
|
||||
"mov.w r5, r2, ror #8\n"
|
||||
"sxtb16 r4, r4\n"
|
||||
"sxtb16 r5, r5\n"
|
||||
"smlad %[sum2], r4, r5, %[sum2]\n"
|
||||
"sxtb16 r4, r1\n"
|
||||
"sxtb16 r5, r3\n"
|
||||
"smlad %[sum3], r4, r5, %[sum3]\n"
|
||||
"mov.w r4, r1, ror #8\n"
|
||||
"mov.w r5, r3, ror #8\n"
|
||||
"sxtb16 r4, r4\n"
|
||||
"sxtb16 r5, r5\n"
|
||||
"smlad %[sum4], r4, r5, %[sum4]\n"
|
||||
"subs %[colCnt], #1\n"
|
||||
"bne COL_LOOP_%=\n":[sum]
|
||||
"+r"(sum),[sum2] "+r"(sum2),
|
||||
[sum3] "+r"(sum3),
|
||||
[sum4] "+r"(sum4),[pB] "+r"(pB),
|
||||
[pA] "+r"(pA):[colCnt]
|
||||
"r"(colCnt),[ch_im_in] "r"(ch_im_in):"r0", "r1", "r2", "r3", "r4", "r5");
|
||||
#else
|
||||
/*
|
||||
* r0 r1 r2 r3 r4 r5
|
||||
* inA1, inA2, inB1, inB2, opA, opB
|
||||
*/
|
||||
asm volatile ("COL_LOOP_%=:\n"
|
||||
"ldr.w r2, [%[pB], #0]\n"
|
||||
"add.w %[pB], %[pB], %[ch_im_in]\n"
|
||||
"ldr.w r5, [%[pB], #0]\n"
|
||||
"add.w %[pB], %[pB], %[ch_im_in]\n"
|
||||
"pkhbt r3, r5, r2, LSL #16\n"
|
||||
"pkhtb r2, r2, r5, ASR #16\n"
|
||||
"ldr.w r0, [%[pA], #0]\n"
|
||||
"add.w %[pA], %[pA], %[ch_im_in]\n"
|
||||
"ldr.w r5, [%[pA], #0]\n"
|
||||
"add.w %[pA], %[pA], %[ch_im_in]\n"
|
||||
"pkhbt r1, r5, r0, LSL #16\n"
|
||||
"pkhtb r0, r0, r5, ASR #16\n"
|
||||
"sxtb16 r4, r0\n"
|
||||
"sxtb16 r5, r2\n"
|
||||
"smlad %[sum2], r4, r5, %[sum2]\n"
|
||||
"mov.w r4, r0, ror #8\n"
|
||||
"mov.w r5, r2, ror #8\n"
|
||||
"sxtb16 r4, r4\n"
|
||||
"sxtb16 r5, r5\n"
|
||||
"smlad %[sum], r4, r5, %[sum]\n"
|
||||
"sxtb16 r4, r1\n"
|
||||
"sxtb16 r5, r3\n"
|
||||
"smlad %[sum4], r4, r5, %[sum4]\n"
|
||||
"mov.w r4, r1, ror #8\n"
|
||||
"mov.w r5, r3, ror #8\n"
|
||||
"sxtb16 r4, r4\n"
|
||||
"sxtb16 r5, r5\n"
|
||||
"smlad %[sum3], r4, r5, %[sum3]\n"
|
||||
"subs %[colCnt], #1\n"
|
||||
"bne COL_LOOP_%=\n":[sum]
|
||||
"+r"(sum),[sum2] "+r"(sum2),
|
||||
[sum3] "+r"(sum3),
|
||||
[sum4] "+r"(sum4),[pB] "+r"(pB),
|
||||
[pA] "+r"(pA):[colCnt]
|
||||
"r"(colCnt),[ch_im_in] "r"(ch_im_in):"r0", "r1", "r2", "r3", "r4", "r5");
|
||||
|
||||
#endif /* ARM_MATH_BIG_ENDIAN */
|
||||
|
||||
#endif /* USE_INTRINSIC */
|
||||
|
||||
colCnt = (dim_kernel * dim_kernel) & 0x1;
|
||||
while (colCnt)
|
||||
{
|
||||
union arm_nnword inA, inB;
|
||||
inA.word = *__SIMD32(pA);
|
||||
pA += ch_im_in;
|
||||
inB.word = *__SIMD32(pB);
|
||||
pB += ch_im_in;
|
||||
sum += inA.bytes[0] * inB.bytes[0];
|
||||
sum2 += inA.bytes[1] * inB.bytes[1];
|
||||
sum3 += inA.bytes[2] * inB.bytes[2];
|
||||
sum4 += inA.bytes[3] * inB.bytes[3];
|
||||
colCnt--;
|
||||
}
|
||||
|
||||
*pOut++ = (q7_t) __SSAT((sum >> out_shift), 8);
|
||||
*pOut++ = (q7_t) __SSAT((sum2 >> out_shift), 8);
|
||||
*pOut++ = (q7_t) __SSAT((sum3 >> out_shift), 8);
|
||||
*pOut++ = (q7_t) __SSAT((sum4 >> out_shift), 8);
|
||||
|
||||
rowCnt--;
|
||||
}
|
||||
|
||||
rowCnt = ch_im_out & 0x3;
|
||||
while (rowCnt)
|
||||
{
|
||||
q7_t *pB = colBuffer + row_shift;
|
||||
const q7_t *pA = wt + row_shift;
|
||||
q31_t sum = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift);
|
||||
uint16_t colCnt = (dim_kernel * dim_kernel);
|
||||
|
||||
row_shift += 1;
|
||||
|
||||
while (colCnt)
|
||||
{
|
||||
q7_t A1 = *pA;
|
||||
q7_t B1 = *pB;
|
||||
pA += ch_im_in;
|
||||
pB += ch_im_in;
|
||||
sum += A1 * B1;
|
||||
|
||||
colCnt--;
|
||||
}
|
||||
*pOut++ = (q7_t) __SSAT((sum >> out_shift), 8);
|
||||
rowCnt--;
|
||||
}
|
||||
|
||||
/* clear counter and pointers */
|
||||
pBuffer = colBuffer;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
/* Run the following code as reference implementation for Cortex-M0 and Cortex-M3 */
|
||||
int i_out_y, i_out_x, i_ch_out, i_ker_x, i_ker_y;
|
||||
int conv_out;
|
||||
|
||||
/* do some checking here, basically ch_im_in == ch_im_out */
|
||||
if (ch_im_in != ch_im_out)
|
||||
{
|
||||
return ARM_MATH_SIZE_MISMATCH;
|
||||
}
|
||||
|
||||
for (i_out_y = 0; i_out_y < dim_im_out; i_out_y++)
|
||||
{
|
||||
for (i_out_x = 0; i_out_x < dim_im_out; i_out_x++)
|
||||
{
|
||||
for (i_ch_out = 0; i_ch_out < ch_im_out; i_ch_out++)
|
||||
{
|
||||
// for each output
|
||||
conv_out = ((q31_t)(bias[i_ch_out]) << bias_shift) + NN_ROUND(out_shift);
|
||||
for (i_ker_y = 0; i_ker_y < dim_kernel; i_ker_y++)
|
||||
{
|
||||
for (i_ker_x = 0; i_ker_x < dim_kernel; i_ker_x++)
|
||||
{
|
||||
int in_row = stride * i_out_y + i_ker_y - padding;
|
||||
int in_col = stride * i_out_x + i_ker_x - padding;
|
||||
if (in_row >= 0 && in_col >= 0 && in_row < dim_im_in && in_col < dim_im_in)
|
||||
{
|
||||
conv_out +=
|
||||
Im_in[(in_row *
|
||||
dim_im_in +
|
||||
in_col) *
|
||||
ch_im_in +
|
||||
i_ch_out] * wt[(i_ker_y * dim_kernel + i_ker_x) * ch_im_out + i_ch_out];
|
||||
}
|
||||
}
|
||||
}
|
||||
Im_out[(i_out_y * dim_im_out +
|
||||
i_out_x) * ch_im_out + i_ch_out] = (q7_t) __SSAT((conv_out >> out_shift), 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* ARM_MATH_DSP */
|
||||
|
||||
/* Return to application */
|
||||
return ARM_MATH_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of NNConv group
|
||||
*/
|
@ -0,0 +1,411 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Project: CMSIS NN Library
|
||||
* Title: arm_depthwise_separable_conv_HWC_q7_nonsquare.c
|
||||
* Description: Q7 depthwise separable convolution function (non-square shape)
|
||||
*
|
||||
* $Date: 17. January 2018
|
||||
* $Revision: V.1.0.0
|
||||
*
|
||||
* Target Processor: Cortex-M cores
|
||||
*
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#include "arm_math.h"
|
||||
#include "arm_nnfunctions.h"
|
||||
|
||||
/**
|
||||
* @ingroup groupNN
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup NNConv
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Q7 depthwise separable convolution function (non-square shape)
|
||||
* @param[in] Im_in pointer to input tensor
|
||||
* @param[in] dim_im_in_x input tensor dimention x
|
||||
* @param[in] dim_im_in_y input tensor dimention y
|
||||
* @param[in] ch_im_in number of input tensor channels
|
||||
* @param[in] wt pointer to kernel weights
|
||||
* @param[in] ch_im_out number of filters, i.e., output tensor channels
|
||||
* @param[in] dim_kernel_x filter kernel size x
|
||||
* @param[in] dim_kernel_y filter kernel size y
|
||||
* @param[in] padding_x padding sizes x
|
||||
* @param[in] padding_y padding sizes y
|
||||
* @param[in] stride_x convolution stride x
|
||||
* @param[in] stride_y convolution stride y
|
||||
* @param[in] bias pointer to bias
|
||||
* @param[in] bias_shift amount of left-shift for bias
|
||||
* @param[in] out_shift amount of right-shift for output
|
||||
* @param[in,out] Im_out pointer to output tensor
|
||||
* @param[in] dim_im_out_x output tensor dimension x
|
||||
* @param[in] dim_im_out_y output tensor dimension y
|
||||
* @param[in,out] bufferA pointer to buffer space for input
|
||||
* @param[in,out] bufferB pointer to buffer space for output
|
||||
* @return The function returns either
|
||||
* <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
|
||||
*
|
||||
* This function is the version with full list of optimization tricks, but with
|
||||
* some contraints:
|
||||
* ch_im_in is multiple of 2
|
||||
* ch_im_out is multiple of 2
|
||||
*/
|
||||
|
||||
arm_status arm_depthwise_separable_conv_HWC_q7_nonsquare(const q7_t * Im_in,
|
||||
const uint16_t dim_im_in_x,
|
||||
const uint16_t dim_im_in_y,
|
||||
const uint16_t ch_im_in,
|
||||
const q7_t * wt,
|
||||
const uint16_t ch_im_out,
|
||||
const uint16_t dim_kernel_x,
|
||||
const uint16_t dim_kernel_y,
|
||||
const uint16_t padding_x,
|
||||
const uint16_t padding_y,
|
||||
const uint16_t stride_x,
|
||||
const uint16_t stride_y,
|
||||
const q7_t * bias,
|
||||
const uint16_t bias_shift,
|
||||
const uint16_t out_shift,
|
||||
q7_t * Im_out,
|
||||
const uint16_t dim_im_out_x,
|
||||
const uint16_t dim_im_out_y,
|
||||
q15_t * bufferA,
|
||||
q7_t * bufferB)
|
||||
{
|
||||
|
||||
#if defined (ARM_MATH_DSP)
|
||||
/* Run the following code for Cortex-M4 and Cortex-M7 */
|
||||
|
||||
/*
|
||||
* Implementation:
|
||||
* There are 3 nested loop here:
|
||||
* Inner loop: calculate each output value with MAC instruction over an accumulator
|
||||
* Mid loop: loop over different output channel
|
||||
* Outer loop: loop over different output (x, y)
|
||||
*
|
||||
*/
|
||||
|
||||
int16_t i_out_y, i_out_x;
|
||||
int16_t i_ker_y, i_ker_x;
|
||||
q7_t *colBuffer = (q7_t *) bufferA;
|
||||
q7_t *pBuffer = colBuffer;
|
||||
const q7_t *pBias = bias;
|
||||
q7_t *pOut = Im_out;
|
||||
uint16_t rowCnt;
|
||||
uint16_t row_shift;
|
||||
|
||||
/* do some checking here, basically ch_im_in == ch_im_out */
|
||||
if (ch_im_in != ch_im_out)
|
||||
{
|
||||
return ARM_MATH_SIZE_MISMATCH;
|
||||
}
|
||||
|
||||
for (i_out_y = 0; i_out_y < dim_im_out_y; i_out_y++)
|
||||
{
|
||||
for (i_out_x = 0; i_out_x < dim_im_out_x; i_out_x++)
|
||||
{
|
||||
/* we first do im2col here */
|
||||
for (i_ker_y = i_out_y * stride_y - padding_y; i_ker_y < i_out_y * stride_y - padding_y + dim_kernel_y;
|
||||
i_ker_y++)
|
||||
{
|
||||
for (i_ker_x = i_out_x * stride_x - padding_x; i_ker_x < i_out_x * stride_x - padding_x + dim_kernel_x;
|
||||
i_ker_x++)
|
||||
{
|
||||
if (i_ker_y < 0 || i_ker_y >= dim_im_in_y || i_ker_x < 0 || i_ker_x >= dim_im_in_x)
|
||||
{
|
||||
/* arm_fill_q7(0, pBuffer, ch_im_in); */
|
||||
memset(pBuffer, 0, ch_im_in);
|
||||
} else
|
||||
{
|
||||
/* arm_copy_q7((q7_t *) Im_in + (i_ker_y * dim_im_in_x + i_ker_x) * ch_im_in, pBuffer, ch_im_in); */
|
||||
memcpy(pBuffer, (q7_t *) Im_in + (i_ker_y * dim_im_in_x + i_ker_x) * ch_im_in, ch_im_in);
|
||||
}
|
||||
pBuffer += ch_im_in;
|
||||
}
|
||||
}
|
||||
|
||||
/* we will do the computation here for each channel */
|
||||
rowCnt = ch_im_out >> 2;
|
||||
row_shift = 0;
|
||||
pBias = bias;
|
||||
|
||||
while (rowCnt)
|
||||
{
|
||||
q31_t sum = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift);
|
||||
q31_t sum2 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift);
|
||||
q31_t sum3 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift);
|
||||
q31_t sum4 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift);
|
||||
|
||||
uint16_t colCnt = (dim_kernel_x * dim_kernel_y) >> 1;
|
||||
q7_t *pB = colBuffer + row_shift;
|
||||
const q7_t *pA = wt + row_shift;
|
||||
row_shift += 4;
|
||||
|
||||
#ifdef USE_INTRINSIC
|
||||
|
||||
#ifndef ARM_MATH_BIG_ENDIAN
|
||||
|
||||
while (colCnt)
|
||||
{
|
||||
q31_t inA1, inA2, inB1, inB2, opA, opB;
|
||||
|
||||
inB1 = *__SIMD32(pB);
|
||||
pB += ch_im_in;
|
||||
opB = *__SIMD32(pB);
|
||||
pB += ch_im_in;
|
||||
inB2 = __PKHTB(opB, inB1, 16);
|
||||
inB1 = __PKHBT(inB1, opB, 16);
|
||||
inA1 = *__SIMD32(pA);
|
||||
pA += ch_im_in;
|
||||
opB = *__SIMD32(pA);
|
||||
pA += ch_im_in;
|
||||
inA2 = __PKHTB(opB, inA1, 16);
|
||||
inA1 = __PKHBT(inA1, opB, 16);
|
||||
opA = __SXTB16(inA1);
|
||||
opB = __SXTB16(inB1);
|
||||
sum = __SMLAD(opA, opB, sum);
|
||||
opA = __SXTB16(__ROR(inA1, 8));
|
||||
opB = __SXTB16(__ROR(inB1, 8));
|
||||
sum2 = __SMLAD(opA, opB, sum2);
|
||||
opA = __SXTB16(inA2);
|
||||
opB = __SXTB16(inB2);
|
||||
sum3 = __SMLAD(opA, opB, sum3);
|
||||
opA = __SXTB16(__ROR(inA2, 8));
|
||||
opB = __SXTB16(__ROR(inB2, 8));
|
||||
sum4 = __SMLAD(opA, opB, sum4);
|
||||
colCnt--;
|
||||
}
|
||||
#else
|
||||
|
||||
while (colCnt)
|
||||
{
|
||||
q31_t inA1, inA2, inB1, inB2, opA, opB;
|
||||
|
||||
inB1 = *__SIMD32(pB);
|
||||
pB += ch_im_in;
|
||||
opB = *__SIMD32(pB);
|
||||
pB += ch_im_in;
|
||||
inB2 = __PKHBT(opB, inB1, 16);
|
||||
inB1 = __PKHTB(inB1, opB, 16);
|
||||
inA1 = *__SIMD32(pA);
|
||||
pA += ch_im_in;
|
||||
opB = *__SIMD32(pA);
|
||||
pA += ch_im_in;
|
||||
inA2 = __PKHBT(opB, inA1, 16);
|
||||
inA1 = __PKHTB(inA1, opB, 16);
|
||||
opA = __SXTB16(inA1);
|
||||
opB = __SXTB16(inB1);
|
||||
sum2 = __SMLAD(opA, opB, sum2);
|
||||
opA = __SXTB16(__ROR(inA1, 8));
|
||||
opB = __SXTB16(__ROR(inB1, 8));
|
||||
sum = __SMLAD(opA, opB, sum);
|
||||
opA = __SXTB16(inA2);
|
||||
opB = __SXTB16(inB2);
|
||||
sum4 = __SMLAD(opA, opB, sum4);
|
||||
opA = __SXTB16(__ROR(inA2, 8));
|
||||
opB = __SXTB16(__ROR(inB2, 8));
|
||||
sum3 = __SMLAD(opA, opB, sum3);
|
||||
colCnt--;
|
||||
}
|
||||
|
||||
#endif /* ARM_MATH_BIG_ENDIAN */
|
||||
|
||||
#else
|
||||
|
||||
#ifndef ARM_MATH_BIG_ENDIAN
|
||||
// r0 r1 r2 r3 r4 r5
|
||||
// inA1, inA2, inB1, inB2, opA, opB
|
||||
asm volatile ("COL_LOOP:\n"
|
||||
"ldr.w r2, [%[pB], #0]\n"
|
||||
"add.w %[pB], %[pB], %[ch_im_in]\n"
|
||||
"ldr.w r5, [%[pB], #0]\n"
|
||||
"add.w %[pB], %[pB], %[ch_im_in]\n"
|
||||
"pkhtb r3, r5, r2, ASR #16\n"
|
||||
"pkhbt r2, r2, r5, LSL #16\n"
|
||||
"ldr.w r0, [%[pA], #0]\n"
|
||||
"add.w %[pA], %[pA], %[ch_im_in]\n"
|
||||
"ldr.w r5, [%[pA], #0]\n"
|
||||
"add.w %[pA], %[pA], %[ch_im_in]\n"
|
||||
"pkhtb r1, r5, r0, ASR #16\n"
|
||||
"pkhbt r0, r0, r5, LSL #16\n"
|
||||
"sxtb16 r4, r0\n"
|
||||
"sxtb16 r5, r2\n"
|
||||
"smlad %[sum], r4, r5, %[sum]\n"
|
||||
"mov.w r4, r0, ror #8\n"
|
||||
"mov.w r5, r2, ror #8\n"
|
||||
"sxtb16 r4, r4\n"
|
||||
"sxtb16 r5, r5\n"
|
||||
"smlad %[sum2], r4, r5, %[sum2]\n"
|
||||
"sxtb16 r4, r1\n"
|
||||
"sxtb16 r5, r3\n"
|
||||
"smlad %[sum3], r4, r5, %[sum3]\n"
|
||||
"mov.w r4, r1, ror #8\n"
|
||||
"mov.w r5, r3, ror #8\n"
|
||||
"sxtb16 r4, r4\n"
|
||||
"sxtb16 r5, r5\n"
|
||||
"smlad %[sum4], r4, r5, %[sum4]\n"
|
||||
"subs %[colCnt], #1\n"
|
||||
"bne COL_LOOP\n":[sum] "+r"(sum),[sum2] "+r"(sum2),[sum3] "+r"(sum3),
|
||||
[sum4] "+r"(sum4),[pB] "+r"(pB),[pA] "+r"(pA):[colCnt] "r"(colCnt),
|
||||
[ch_im_in] "r"(ch_im_in):"r0", "r1", "r2", "r3", "r4", "r5");
|
||||
#else
|
||||
// r0 r1 r2 r3 r4 r5
|
||||
// inA1, inA2, inB1, inB2, opA, opB
|
||||
asm volatile ("COL_LOOP:\n"
|
||||
"ldr.w r2, [%[pB], #0]\n"
|
||||
"add.w %[pB], %[pB], %[ch_im_in]\n"
|
||||
"ldr.w r5, [%[pB], #0]\n"
|
||||
"add.w %[pB], %[pB], %[ch_im_in]\n"
|
||||
"pkhbt r3, r5, r2, LSL #16\n"
|
||||
"pkhtb r2, r2, r5, ASR #16\n"
|
||||
"ldr.w r0, [%[pA], #0]\n"
|
||||
"add.w %[pA], %[pA], %[ch_im_in]\n"
|
||||
"ldr.w r5, [%[pA], #0]\n"
|
||||
"add.w %[pA], %[pA], %[ch_im_in]\n"
|
||||
"pkhbt r1, r5, r0, LSL #16\n"
|
||||
"pkhtb r0, r0, r5, ASR #16\n"
|
||||
"sxtb16 r4, r0\n"
|
||||
"sxtb16 r5, r2\n"
|
||||
"smlad %[sum2], r4, r5, %[sum2]\n"
|
||||
"mov.w r4, r0, ror #8\n"
|
||||
"mov.w r5, r2, ror #8\n"
|
||||
"sxtb16 r4, r4\n"
|
||||
"sxtb16 r5, r5\n"
|
||||
"smlad %[sum], r4, r5, %[sum]\n"
|
||||
"sxtb16 r4, r1\n"
|
||||
"sxtb16 r5, r3\n"
|
||||
"smlad %[sum4], r4, r5, %[sum4]\n"
|
||||
"mov.w r4, r1, ror #8\n"
|
||||
"mov.w r5, r3, ror #8\n"
|
||||
"sxtb16 r4, r4\n"
|
||||
"sxtb16 r5, r5\n"
|
||||
"smlad %[sum3], r4, r5, %[sum3]\n"
|
||||
"subs %[colCnt], #1\n"
|
||||
"bne COL_LOOP\n":[sum] "+r"(sum),[sum2] "+r"(sum2),[sum3] "+r"(sum3),
|
||||
[sum4] "+r"(sum4),[pB] "+r"(pB),[pA] "+r"(pA):[colCnt] "r"(colCnt),
|
||||
[ch_im_in] "r"(ch_im_in):"r0", "r1", "r2", "r3", "r4", "r5");
|
||||
#endif /*ARM_MATH_BIG_ENDIAN */
|
||||
|
||||
#endif /* USE_INTRINSIC */
|
||||
|
||||
colCnt = (dim_kernel_x * dim_kernel_y) & 0x1;
|
||||
while (colCnt)
|
||||
{
|
||||
union arm_nnword inA, inB;
|
||||
inA.word = *__SIMD32(pA);
|
||||
pA += ch_im_in;
|
||||
inB.word = *__SIMD32(pB);
|
||||
pB += ch_im_in;
|
||||
sum += inA.bytes[0] * inB.bytes[0];
|
||||
sum2 += inA.bytes[1] * inB.bytes[1];
|
||||
sum3 += inA.bytes[2] * inB.bytes[2];
|
||||
sum4 += inA.bytes[3] * inB.bytes[3];
|
||||
colCnt--;
|
||||
}
|
||||
|
||||
*pOut++ = (q7_t) __SSAT((sum >> out_shift), 8);
|
||||
*pOut++ = (q7_t) __SSAT((sum2 >> out_shift), 8);
|
||||
*pOut++ = (q7_t) __SSAT((sum3 >> out_shift), 8);
|
||||
*pOut++ = (q7_t) __SSAT((sum4 >> out_shift), 8);
|
||||
|
||||
rowCnt--;
|
||||
}
|
||||
|
||||
rowCnt = ch_im_out & 0x3;
|
||||
while (rowCnt)
|
||||
{
|
||||
q7_t *pB = colBuffer + row_shift;
|
||||
const q7_t *pA = wt + row_shift;
|
||||
q31_t sum = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift);
|
||||
uint16_t colCnt = (dim_kernel_x * dim_kernel_y);
|
||||
|
||||
row_shift += 1;
|
||||
|
||||
while (colCnt)
|
||||
{
|
||||
q7_t A1 = *pA;
|
||||
q7_t B1 = *pB;
|
||||
pA += ch_im_in;
|
||||
pB += ch_im_in;
|
||||
sum += A1 * B1;
|
||||
|
||||
colCnt--;
|
||||
}
|
||||
*pOut++ = (q7_t) __SSAT((sum >> out_shift), 8);
|
||||
rowCnt--;
|
||||
}
|
||||
|
||||
// clear counter and pointers
|
||||
pBuffer = colBuffer;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
/* Run the following code as reference implementation for Cortex-M0 and Cortex-M3 */
|
||||
int i_out_y, i_out_x, i_ch_out;
|
||||
int i_ker_y, i_ker_x;
|
||||
|
||||
/* do some checking here, basically ch_im_in == ch_im_out */
|
||||
if (ch_im_in != ch_im_out)
|
||||
{
|
||||
return ARM_MATH_SIZE_MISMATCH;
|
||||
}
|
||||
|
||||
for (i_out_y = 0; i_out_y < dim_im_out_y; i_out_y++)
|
||||
{
|
||||
for (i_out_x = 0; i_out_x < dim_im_out_x; i_out_x++)
|
||||
{
|
||||
for (i_ch_out = 0; i_ch_out < ch_im_out; i_ch_out++)
|
||||
{
|
||||
// for each output
|
||||
int conv_out = ((q31_t)(bias[i_ch_out]) << bias_shift) + NN_ROUND(out_shift);
|
||||
for (i_ker_y = 0; i_ker_y < dim_kernel_y; i_ker_y++)
|
||||
{
|
||||
for (i_ker_x = 0; i_ker_x < dim_kernel_x; i_ker_x++)
|
||||
{
|
||||
int in_row = stride_y * i_out_y + i_ker_y - padding_y;
|
||||
int in_col = stride_x * i_out_x + i_ker_x - padding_x;
|
||||
if (in_row >= 0 && in_col >= 0 && in_row < dim_im_in_y && in_col < dim_im_in_x)
|
||||
{
|
||||
conv_out += Im_in[(in_row * dim_im_in_x + in_col) * ch_im_in + i_ch_out] *
|
||||
wt[(i_ker_y * dim_kernel_x + i_ker_x) * ch_im_out + i_ch_out];
|
||||
}
|
||||
}
|
||||
}
|
||||
Im_out[(i_out_y * dim_im_out_x + i_out_x) * ch_im_out + i_ch_out] =
|
||||
(q7_t) __SSAT((conv_out >> out_shift), 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* ARM_MATH_DSP */
|
||||
|
||||
|
||||
/* Return to application */
|
||||
return ARM_MATH_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @} end of NNConv group
|
||||
*/
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user