Trinity Devboard PCB V1.0 Firmware. FreeRTOS is setup and the MCU reads IMU data over SPI fand Magnetometer data over I2C, each with a seperate task. Sensordata is then run though MadgwickAHRS and send over USB as serial packet data to use in trinity visualizer. Bare minimum functionality works and is replicated from the first prototype.
This commit is contained in:
+44
@@ -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 >>> ---------------------------
|
||||
+242
@@ -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
|
||||
+56
@@ -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;
|
||||
}
|
||||
+262
@@ -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
|
||||
+68
@@ -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;
|
||||
}
|
||||
+262
@@ -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
|
||||
+83
@@ -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;
|
||||
}
|
||||
+295
@@ -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);
|
||||
}
|
||||
+262
@@ -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
|
||||
+85
@@ -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
+43
@@ -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
|
||||
+26
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;
|
||||
}
|
||||
+262
@@ -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
|
||||
+83
@@ -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;
|
||||
}
|
||||
+295
@@ -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);
|
||||
}
|
||||
+262
@@ -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
|
||||
+85
@@ -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.
|
||||
+196
@@ -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;
|
||||
}
|
||||
+6
File diff suppressed because one or more lines are too long
+43
@@ -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
|
||||
+26
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;
|
||||
}
|
||||
+23
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
|
||||
@@ -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 */
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+83
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+78
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+70
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+75
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+120
@@ -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--;
|
||||
}
|
||||
}
|
||||
+43
@@ -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);
|
||||
}
|
||||
}
|
||||
+119
@@ -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--;
|
||||
}
|
||||
}
|
||||
+43
@@ -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);
|
||||
}
|
||||
}
|
||||
+138
@@ -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--;
|
||||
}
|
||||
}
|
||||
+43
@@ -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;
|
||||
}
|
||||
}
|
||||
+7
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
|
||||
*/
|
||||
+235
@@ -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
|
||||
*/
|
||||
+411
@@ -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