diff --git a/ARM.AVH_FVP.pdsc b/ARM.AVH_FVP.pdsc
index b71fad6..a7426f6 100644
--- a/ARM.AVH_FVP.pdsc
+++ b/ARM.AVH_FVP.pdsc
@@ -30,6 +30,31 @@
+
+
+ Requirements for Corstone-310 FVP
+
+
+
+
+
+ Requirements for Corstone-310 FVP
+
+
+
+
+
+ Requirements for Corstone-315 FVP
+
+
+
+
+
+ Requirements for Corstone-320 FVP
+
+
+
+
@@ -110,4 +135,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/board/Corstone-300/Board-U55.clayer.yml b/board/Corstone-300/Board-U55.clayer.yml
new file mode 100644
index 0000000..cb372e0
--- /dev/null
+++ b/board/Corstone-300/Board-U55.clayer.yml
@@ -0,0 +1,65 @@
+layer:
+ type: Board
+ description: Board setup for AI/ML with Ethos U55
+ for-board: ARM::V2M-MPS3-SSE-300-FVP
+ for-device: ARM::SSE-300-MPS3
+
+ connections:
+ - connect: Corstone-300-U55
+ provides:
+ - CMSIS_USART
+ - CMSIS_VSTREAM_AUDIO_IN
+ - CMSIS_VSTREAM_AUDIO_OUT
+ - CMSIS_VSTREAM_VIDEO_IN
+ - CMSIS_VSTREAM_VIDEO_OUT
+ - STDOUT
+ - STDERR
+ - Heap: 786432
+
+ define:
+ - CMSIS_target_header: \"Corstone-300.h\"
+ - ETHOSU55
+ - CORSTONE300_FVP
+ - ARM_MODEL_USE_PMU_COUNTERS
+
+ packs:
+ - pack: ARM::CMSIS
+ - pack: ARM::CMSIS-Compiler@^2.1.0
+ - pack: ARM::ethos-u-core-driver@^1.25.2
+ - pack: ARM::AVH_FVP
+ - pack: ARM::V2M_MPS3_SSE_300_BSP@1.5.0
+
+ components:
+ - component: CMSIS:CORE
+
+ - component: CMSIS Driver:USART
+ - component: CMSIS Driver:vStream:AudioIn
+ - component: CMSIS Driver:vStream:AudioOut
+ - component: CMSIS Driver:vStream:VideoIn
+ - component: CMSIS Driver:vStream:VideoOut
+
+ - component: CMSIS-Compiler:CORE
+ - component: CMSIS-Compiler:STDERR:Custom
+ - component: CMSIS-Compiler:STDIN:Custom
+ - component: CMSIS-Compiler:STDOUT:Custom
+
+ - component: Device:Definition
+ - component: Device:Startup&C Startup
+
+ - component: Device:Native Driver:SysCounter
+ - component: Device:Native Driver:SysTimer
+ - component: Device:Native Driver:Timeout
+ - component: Device:Native Driver:UART
+
+ - component: Machine Learning:NPU Support:Ethos-U Driver&Generic U55
+
+ groups:
+ - group: Board
+ files:
+ - file: ./main.c
+ - file: ./main.h
+ - file: ./ethos_setup.c
+ - file: ./retarget_stdio.c
+
+ linker:
+ - regions: ./regions_SSE-300.h
diff --git a/board/Corstone-300/Board-U65.clayer.yml b/board/Corstone-300/Board-U65.clayer.yml
new file mode 100644
index 0000000..bd39b8d
--- /dev/null
+++ b/board/Corstone-300/Board-U65.clayer.yml
@@ -0,0 +1,65 @@
+layer:
+ type: Board
+ description: Board setup for AI/ML with Ethos U65
+ for-board: ARM::V2M-MPS3-SSE-300-FVP
+ for-device: ARM::SSE-300-MPS3
+
+ connections:
+ - connect: Corstone-300-U65
+ provides:
+ - CMSIS_USART
+ - CMSIS_VSTREAM_AUDIO_IN
+ - CMSIS_VSTREAM_AUDIO_OUT
+ - CMSIS_VSTREAM_VIDEO_IN
+ - CMSIS_VSTREAM_VIDEO_OUT
+ - STDOUT
+ - STDERR
+ - Heap: 786432
+
+ define:
+ - CMSIS_target_header: \"Corstone-300.h\"
+ - ETHOSU65
+ - CORSTONE300_FVP
+ - ARM_MODEL_USE_PMU_COUNTERS
+
+ packs:
+ - pack: ARM::CMSIS
+ - pack: ARM::CMSIS-Compiler@^2.1.0
+ - pack: ARM::ethos-u-core-driver@^1.25.2
+ - pack: ARM::AVH_FVP
+ - pack: ARM::V2M_MPS3_SSE_300_BSP@1.5.0
+
+ components:
+ - component: CMSIS:CORE
+
+ - component: CMSIS Driver:USART
+ - component: CMSIS Driver:vStream:AudioIn
+ - component: CMSIS Driver:vStream:AudioOut
+ - component: CMSIS Driver:vStream:VideoIn
+ - component: CMSIS Driver:vStream:VideoOut
+
+ - component: CMSIS-Compiler:CORE
+ - component: CMSIS-Compiler:STDERR:Custom
+ - component: CMSIS-Compiler:STDIN:Custom
+ - component: CMSIS-Compiler:STDOUT:Custom
+
+ - component: Device:Definition
+ - component: Device:Startup&C Startup
+
+ - component: Device:Native Driver:SysCounter
+ - component: Device:Native Driver:SysTimer
+ - component: Device:Native Driver:Timeout
+ - component: Device:Native Driver:UART
+
+ - component: Machine Learning:NPU Support:Ethos-U Driver&Generic U65
+
+ groups:
+ - group: Board
+ files:
+ - file: ./main.c
+ - file: ./main.h
+ - file: ./ethos_setup.c
+ - file: ./retarget_stdio.c
+
+ linker:
+ - regions: ./regions_SSE-300.h
diff --git a/board/Corstone-300/Board.clayer.yml b/board/Corstone-300/Board.clayer.yml
new file mode 100644
index 0000000..6046fc0
--- /dev/null
+++ b/board/Corstone-300/Board.clayer.yml
@@ -0,0 +1,60 @@
+layer:
+ type: Board
+ description: Board setup for AI/ML
+ for-board: ARM::V2M-MPS3-SSE-300-FVP
+ for-device: ARM::SSE-300-MPS3
+
+ connections:
+ - connect: Corstone-300
+ provides:
+ - CMSIS_USART
+ - CMSIS_VSTREAM_AUDIO_IN
+ - CMSIS_VSTREAM_AUDIO_OUT
+ - CMSIS_VSTREAM_VIDEO_IN
+ - CMSIS_VSTREAM_VIDEO_OUT
+ - STDOUT
+ - STDERR
+ - Heap: 786432
+
+ define:
+ - CMSIS_target_header: \"Corstone-300.h\"
+ - CORSTONE300_FVP
+ - ARM_MODEL_USE_PMU_COUNTERS
+
+ packs:
+ - pack: ARM::CMSIS
+ - pack: ARM::CMSIS-Compiler@^2.1.0
+ - pack: ARM::AVH_FVP
+ - pack: ARM::V2M_MPS3_SSE_300_BSP@1.5.0
+
+ components:
+ - component: CMSIS:CORE
+
+ - component: CMSIS Driver:USART
+ - component: CMSIS Driver:vStream:AudioIn
+ - component: CMSIS Driver:vStream:AudioOut
+ - component: CMSIS Driver:vStream:VideoIn
+ - component: CMSIS Driver:vStream:VideoOut
+
+ - component: CMSIS-Compiler:CORE
+ - component: CMSIS-Compiler:STDERR:Custom
+ - component: CMSIS-Compiler:STDIN:Custom
+ - component: CMSIS-Compiler:STDOUT:Custom
+
+ - component: Device:Definition
+ - component: Device:Startup&C Startup
+
+ - component: Device:Native Driver:SysCounter
+ - component: Device:Native Driver:SysTimer
+ - component: Device:Native Driver:Timeout
+ - component: Device:Native Driver:UART
+
+ groups:
+ - group: Board
+ files:
+ - file: ./main.c
+ - file: ./main.h
+ - file: ./retarget_stdio.c
+
+ linker:
+ - regions: ./regions_SSE-300.h
diff --git a/board/Corstone-300/Corstone-300.h b/board/Corstone-300/Corstone-300.h
new file mode 100644
index 0000000..3a5dde4
--- /dev/null
+++ b/board/Corstone-300/Corstone-300.h
@@ -0,0 +1,42 @@
+/*---------------------------------------------------------------------------
+ * Copyright (c) 2025 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 CORSTONE_300_H_
+#define CORSTONE_300_H_
+
+#include "Driver_USART.h"
+#include "cmsis_vstream.h"
+
+// CMSIS Driver instances of Board peripherals
+#define CMSIS_DRIVER_USART 0 // CMSIS Driver USART instance number
+
+// Retarget stdio to CMSIS UART
+#define RETARGET_STDIO_UART 0
+
+// CMSIS Drivers
+extern ARM_DRIVER_USART Driver_USART0; /* Serial */
+extern vStreamDriver_t Driver_vStreamAudioIn; /* Audio In Stream */
+extern vStreamDriver_t Driver_vStreamAudioOut; /* Audio Out Stream */
+extern vStreamDriver_t Driver_vStreamVideoIn; /* Video In Stream */
+extern vStreamDriver_t Driver_vStreamVideoOut; /* Video Out Stream */
+
+#ifdef CMSIS_shield_header
+#include CMSIS_shield_header
+#endif
+
+#endif /* CORSTONE_300_H_ */
diff --git a/board/Corstone-300/README.md b/board/Corstone-300/README.md
new file mode 100644
index 0000000..a47465c
--- /dev/null
+++ b/board/Corstone-300/README.md
@@ -0,0 +1,35 @@
+# Board: Arm V2M-MPS3-SSE-300-FVP
+
+## Board Layer for Corstone-300 FVP
+
+Device: SSE-300-MPS3
+
+### System Configuration
+
+| System Component | Setting
+|:------------------------|:----------------------------------
+| Heap | 768 kB (configured in linker file)
+| Stack (MSP) | 32 kB (configured in linker file)
+
+### STDIO mapping
+
+**STDIO** is routed to terminal via **UART0** peripheral
+
+### CMSIS-Driver mapping
+
+| CMSIS-Driver | Peripheral | Connection
+|:-----------------------|:-----------|:----------------------
+| Driver_USART0 | UART0 | STDOUT, STDERR
+| Driver_vStreamAudioIn | VSI0 | CMSIS_VSTREAM_AUDIO_IN
+| Driver_vStreamAudioOut | VSI1 | CMSIS_VSTREAM_AUDIO_OUT
+| Driver_vStreamVideoIn | VSI4 | CMSIS_VSTREAM_VIDEO_IN
+| Driver_vStreamVideoOut | VSI6 | CMSIS_VSTREAM_VIDEO_OUT
+
+### CMSIS-Driver vStream configuration
+
+| Driver | Stream Format Description
+|:-----------------------|:----------------------------------------------------
+| Driver_vStreamAudioIn | 16-bit PCM audio, 16000 samples/second
+| Driver_vStreamAudioOut | 16-bit PCM audio, 16000 samples/second
+| Driver_vStreamVideoIn | RGB888 video, resolution 1280 x 720 (W x H)
+| Driver_vStreamVideoOut | RGB888 video, resolution 480 x 800 (W x H)
diff --git a/board/Corstone-300/RTE/CMSIS_Driver/vstream_audio_in_config.h b/board/Corstone-300/RTE/CMSIS_Driver/vstream_audio_in_config.h
new file mode 100644
index 0000000..72953b0
--- /dev/null
+++ b/board/Corstone-300/RTE/CMSIS_Driver/vstream_audio_in_config.h
@@ -0,0 +1,60 @@
+/*---------------------------------------------------------------------------
+ * Copyright (c) 2025 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 VSTREAM_AUDIO_IN_CONFIG_H_
+#define VSTREAM_AUDIO_IN_CONFIG_H_
+
+//-------- <<< Use Configuration Wizard in Context Menu >>> --------------------
+//------ With VS Code: Open Preview for Configuration Wizard -------------------
+
+// Number of channels <1=>Mono <2=>Stereo
+// Defines the number of audio channels in stream.
+// Default: 2
+#ifndef AUDIO_IN_CHANNELS
+#define AUDIO_IN_CHANNELS 2
+#endif
+
+// Number of bits per sample <0=>8 <1=>16 <2=>24 <3=>32
+// Defines number of bits of information in each sample.
+// Default: 16
+#ifndef AUDIO_IN_SAMPLE_BITS
+#define AUDIO_IN_SAMPLE_BITS 16
+#endif
+
+// Sample rate <8000=>8 kHz <16000=>16 kHz <44100=>44.1 kHz <48000=>48 kHz
+// Defines the number of samples captured per second.
+// Default: 16000
+#ifndef AUDIO_IN_SAMPLE_RATE
+#define AUDIO_IN_SAMPLE_RATE 16000
+#endif
+
+// Streaming Device Index
+// Defines the system index of the audio streaming device.
+// Default: -1 (system default audio device)
+#ifndef AUDIO_IN_DEVICE
+#define AUDIO_IN_DEVICE -1
+#endif
+
+// Audio File Name
+// Defines the name of the audio file to be used for streaming.
+// Default: "" (use streaming device instead of file)
+#ifndef AUDIO_IN_FILENAME
+#define AUDIO_IN_FILENAME ""
+#endif
+
+#endif
diff --git a/board/Corstone-300/RTE/CMSIS_Driver/vstream_audio_in_config.h.base@1.0.0 b/board/Corstone-300/RTE/CMSIS_Driver/vstream_audio_in_config.h.base@1.0.0
new file mode 100644
index 0000000..72953b0
--- /dev/null
+++ b/board/Corstone-300/RTE/CMSIS_Driver/vstream_audio_in_config.h.base@1.0.0
@@ -0,0 +1,60 @@
+/*---------------------------------------------------------------------------
+ * Copyright (c) 2025 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 VSTREAM_AUDIO_IN_CONFIG_H_
+#define VSTREAM_AUDIO_IN_CONFIG_H_
+
+//-------- <<< Use Configuration Wizard in Context Menu >>> --------------------
+//------ With VS Code: Open Preview for Configuration Wizard -------------------
+
+// Number of channels <1=>Mono <2=>Stereo
+// Defines the number of audio channels in stream.
+// Default: 2
+#ifndef AUDIO_IN_CHANNELS
+#define AUDIO_IN_CHANNELS 2
+#endif
+
+// Number of bits per sample <0=>8 <1=>16 <2=>24 <3=>32
+// Defines number of bits of information in each sample.
+// Default: 16
+#ifndef AUDIO_IN_SAMPLE_BITS
+#define AUDIO_IN_SAMPLE_BITS 16
+#endif
+
+// Sample rate <8000=>8 kHz <16000=>16 kHz <44100=>44.1 kHz <48000=>48 kHz
+// Defines the number of samples captured per second.
+// Default: 16000
+#ifndef AUDIO_IN_SAMPLE_RATE
+#define AUDIO_IN_SAMPLE_RATE 16000
+#endif
+
+// Streaming Device Index
+// Defines the system index of the audio streaming device.
+// Default: -1 (system default audio device)
+#ifndef AUDIO_IN_DEVICE
+#define AUDIO_IN_DEVICE -1
+#endif
+
+// Audio File Name
+// Defines the name of the audio file to be used for streaming.
+// Default: "" (use streaming device instead of file)
+#ifndef AUDIO_IN_FILENAME
+#define AUDIO_IN_FILENAME ""
+#endif
+
+#endif
diff --git a/board/Corstone-300/RTE/CMSIS_Driver/vstream_audio_out_config.h b/board/Corstone-300/RTE/CMSIS_Driver/vstream_audio_out_config.h
new file mode 100644
index 0000000..a8b6859
--- /dev/null
+++ b/board/Corstone-300/RTE/CMSIS_Driver/vstream_audio_out_config.h
@@ -0,0 +1,60 @@
+/*---------------------------------------------------------------------------
+ * Copyright (c) 2025 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 VSTREAM_AUDIO_OUT_CONFIG_H_
+#define VSTREAM_AUDIO_OUT_CONFIG_H_
+
+//-------- <<< Use Configuration Wizard in Context Menu >>> --------------------
+//------ With VS Code: Open Preview for Configuration Wizard -------------------
+
+// Number of channels <1=>Mono <2=>Stereo
+// Defines the number of audio channels in stream.
+// Default: 2
+#ifndef AUDIO_OUT_CHANNELS
+#define AUDIO_OUT_CHANNELS 2
+#endif
+
+// Number of bits per sample <0=>8 <1=>16 <2=>24 <3=>32
+// Defines number of bits of information in each sample.
+// Default: 16
+#ifndef AUDIO_OUT_SAMPLE_BITS
+#define AUDIO_OUT_SAMPLE_BITS 16
+#endif
+
+// Sample rate <8000=>8 kHz <16000=>16 kHz <44100=>44.1 kHz <48000=>48 kHz
+// Defines the number of samples captured per second.
+// Default: 16000
+#ifndef AUDIO_OUT_SAMPLE_RATE
+#define AUDIO_OUT_SAMPLE_RATE 16000
+#endif
+
+// Streaming Device Index
+// Defines the system index of the audio streaming device.
+// Default: -1 (system default audio device)
+#ifndef AUDIO_OUT_DEVICE
+#define AUDIO_OUT_DEVICE -1
+#endif
+
+// Audio File Name
+// Defines the name of the audio file to be used for streaming.
+// Default: "" (use streaming device instead of file)
+#ifndef AUDIO_OUT_FILENAME
+#define AUDIO_OUT_FILENAME ""
+#endif
+
+#endif
diff --git a/board/Corstone-300/RTE/CMSIS_Driver/vstream_audio_out_config.h.base@1.0.0 b/board/Corstone-300/RTE/CMSIS_Driver/vstream_audio_out_config.h.base@1.0.0
new file mode 100644
index 0000000..a8b6859
--- /dev/null
+++ b/board/Corstone-300/RTE/CMSIS_Driver/vstream_audio_out_config.h.base@1.0.0
@@ -0,0 +1,60 @@
+/*---------------------------------------------------------------------------
+ * Copyright (c) 2025 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 VSTREAM_AUDIO_OUT_CONFIG_H_
+#define VSTREAM_AUDIO_OUT_CONFIG_H_
+
+//-------- <<< Use Configuration Wizard in Context Menu >>> --------------------
+//------ With VS Code: Open Preview for Configuration Wizard -------------------
+
+// Number of channels <1=>Mono <2=>Stereo
+// Defines the number of audio channels in stream.
+// Default: 2
+#ifndef AUDIO_OUT_CHANNELS
+#define AUDIO_OUT_CHANNELS 2
+#endif
+
+// Number of bits per sample <0=>8 <1=>16 <2=>24 <3=>32
+// Defines number of bits of information in each sample.
+// Default: 16
+#ifndef AUDIO_OUT_SAMPLE_BITS
+#define AUDIO_OUT_SAMPLE_BITS 16
+#endif
+
+// Sample rate <8000=>8 kHz <16000=>16 kHz <44100=>44.1 kHz <48000=>48 kHz
+// Defines the number of samples captured per second.
+// Default: 16000
+#ifndef AUDIO_OUT_SAMPLE_RATE
+#define AUDIO_OUT_SAMPLE_RATE 16000
+#endif
+
+// Streaming Device Index
+// Defines the system index of the audio streaming device.
+// Default: -1 (system default audio device)
+#ifndef AUDIO_OUT_DEVICE
+#define AUDIO_OUT_DEVICE -1
+#endif
+
+// Audio File Name
+// Defines the name of the audio file to be used for streaming.
+// Default: "" (use streaming device instead of file)
+#ifndef AUDIO_OUT_FILENAME
+#define AUDIO_OUT_FILENAME ""
+#endif
+
+#endif
diff --git a/board/Corstone-300/RTE/CMSIS_Driver/vstream_video_in_config.h b/board/Corstone-300/RTE/CMSIS_Driver/vstream_video_in_config.h
new file mode 100644
index 0000000..fd1d7d0
--- /dev/null
+++ b/board/Corstone-300/RTE/CMSIS_Driver/vstream_video_in_config.h
@@ -0,0 +1,70 @@
+/*---------------------------------------------------------------------------
+ * Copyright (c) 2025 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 VSTREAM_VIDEO_IN_CONFIG_H_
+#define VSTREAM_VIDEO_IN_CONFIG_H_
+
+//-------- <<< Use Configuration Wizard in Context Menu >>> --------------------
+//------ With VS Code: Open Preview for Configuration Wizard -------------------
+
+// Frame width
+// Defines the video stream frame width in pixels.
+// Common frame widths: 320, 640, 800, 1024.
+// Default: 640
+#ifndef VIDEO_IN_FRAME_WIDTH
+#define VIDEO_IN_FRAME_WIDTH 640
+#endif
+
+// Frame height
+// Defines the video stream frame height in pixels.
+// Common frame heights: 240, 480, 600, 768.
+// Default: 480
+#ifndef VIDEO_IN_FRAME_HEIGHT
+#define VIDEO_IN_FRAME_HEIGHT 480
+#endif
+
+// Frame rate
+// Defines the video stream frame rate in frames per second.
+// Common frame rates: 15, 25, 30, 60.
+// Default: 30
+#ifndef VIDEO_IN_FRAME_RATE
+#define VIDEO_IN_FRAME_RATE 30
+#endif
+
+// Color format <0=>Grayscale(8-bit) <1=>RGB888 <2=>BGR565 <3=>YUV420 <4=>NV12 <5=>NV21
+// Defines the video frame color space.
+// Default: 1
+#ifndef VIDEO_IN_FRAME_COLOR
+#define VIDEO_IN_FRAME_COLOR 1
+#endif
+
+// Streaming Device Index
+// Defines the system index of the video streaming device.
+// Default: -1 (system default video device)
+#ifndef VIDEO_IN_DEVICE
+#define VIDEO_IN_DEVICE -1
+#endif
+
+// Video File Name
+// Defines the name of the video file to be used for streaming.
+// Default: "" (use streaming device instead of file)
+#ifndef VIDEO_IN_FILENAME
+#define VIDEO_IN_FILENAME ""
+#endif
+
+#endif
diff --git a/board/Corstone-300/RTE/CMSIS_Driver/vstream_video_in_config.h.base@1.0.0 b/board/Corstone-300/RTE/CMSIS_Driver/vstream_video_in_config.h.base@1.0.0
new file mode 100644
index 0000000..a4e79fe
--- /dev/null
+++ b/board/Corstone-300/RTE/CMSIS_Driver/vstream_video_in_config.h.base@1.0.0
@@ -0,0 +1,70 @@
+/*---------------------------------------------------------------------------
+ * Copyright (c) 2025 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 VSTREAM_VIDEO_IN_CONFIG_H_
+#define VSTREAM_VIDEO_IN_CONFIG_H_
+
+//-------- <<< Use Configuration Wizard in Context Menu >>> --------------------
+//------ With VS Code: Open Preview for Configuration Wizard -------------------
+
+// Frame width
+// Defines the video stream frame width in pixels.
+// Common frame widths: 320, 640, 800, 1024.
+// Default: 640
+#ifndef VIDEO_IN_FRAME_WIDTH
+#define VIDEO_IN_FRAME_WIDTH 320
+#endif
+
+// Frame height
+// Defines the video stream frame height in pixels.
+// Common frame heights: 240, 480, 600, 768.
+// Default: 480
+#ifndef VIDEO_IN_FRAME_HEIGHT
+#define VIDEO_IN_FRAME_HEIGHT 240
+#endif
+
+// Frame rate
+// Defines the video stream frame rate in frames per second.
+// Common frame rates: 15, 25, 30, 60.
+// Default: 30
+#ifndef VIDEO_IN_FRAME_RATE
+#define VIDEO_IN_FRAME_RATE 30
+#endif
+
+// Color format <0=>Grayscale(8-bit) <1=>RGB888 <2=>BGR565 <3=>YUV420 <4=>NV12 <5=>NV21
+// Defines the video frame color space.
+// Default: 1
+#ifndef VIDEO_IN_FRAME_COLOR
+#define VIDEO_IN_FRAME_COLOR 1
+#endif
+
+// Streaming Device Index
+// Defines the system index of the video streaming device.
+// Default: -1 (system default video device)
+#ifndef VIDEO_IN_DEVICE
+#define VIDEO_IN_DEVICE -1
+#endif
+
+// Video File Name
+// Defines the name of the video file to be used for streaming.
+// Default: "" (use streaming device instead of file)
+#ifndef VIDEO_IN_FILENAME
+#define VIDEO_IN_FILENAME ""
+#endif
+
+#endif
diff --git a/board/Corstone-300/RTE/CMSIS_Driver/vstream_video_out_config.h b/board/Corstone-300/RTE/CMSIS_Driver/vstream_video_out_config.h
new file mode 100644
index 0000000..da9aa7e
--- /dev/null
+++ b/board/Corstone-300/RTE/CMSIS_Driver/vstream_video_out_config.h
@@ -0,0 +1,63 @@
+/*---------------------------------------------------------------------------
+ * Copyright (c) 2025 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 VSTREAM_VIDEO_OUT_CONFIG_H_
+#define VSTREAM_VIDEO_OUT_CONFIG_H_
+
+//-------- <<< Use Configuration Wizard in Context Menu >>> --------------------
+//------ With VS Code: Open Preview for Configuration Wizard -------------------
+
+// Frame width
+// Defines the video stream frame width in pixels.
+// Common frame widths: 320, 640, 800, 1024.
+// Default: 640
+#ifndef VIDEO_OUT_FRAME_WIDTH
+#define VIDEO_OUT_FRAME_WIDTH 640
+#endif
+
+// Frame height
+// Defines the video stream frame height in pixels.
+// Common frame heights: 240, 480, 600, 768.
+// Default: 480
+#ifndef VIDEO_OUT_FRAME_HEIGHT
+#define VIDEO_OUT_FRAME_HEIGHT 480
+#endif
+
+// Frame rate
+// Defines the video stream frame rate in frames per second.
+// Common frame rates: 15, 25, 30, 60.
+// Default: 30
+#ifndef VIDEO_OUT_FRAME_RATE
+#define VIDEO_OUT_FRAME_RATE 30
+#endif
+
+// Color format <0=>Grayscale(8-bit) <1=>RGB888 <2=>BGR565 <3=>YUV420 <4=>NV12 <5=>NV21
+// Defines the video frame color space.
+// Default: 1
+#ifndef VIDEO_OUT_FRAME_COLOR
+#define VIDEO_OUT_FRAME_COLOR 1
+#endif
+
+// Video File Name
+// Defines the name of the video file to be used for streaming.
+// Default: "" (use streaming device instead of file)
+#ifndef VIDEO_OUT_FILENAME
+#define VIDEO_OUT_FILENAME ""
+#endif
+
+#endif
diff --git a/board/Corstone-300/RTE/CMSIS_Driver/vstream_video_out_config.h.base@1.0.0 b/board/Corstone-300/RTE/CMSIS_Driver/vstream_video_out_config.h.base@1.0.0
new file mode 100644
index 0000000..b59bf69
--- /dev/null
+++ b/board/Corstone-300/RTE/CMSIS_Driver/vstream_video_out_config.h.base@1.0.0
@@ -0,0 +1,63 @@
+/*---------------------------------------------------------------------------
+ * Copyright (c) 2025 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 VSTREAM_VIDEO_OUT_CONFIG_H_
+#define VSTREAM_VIDEO_OUT_CONFIG_H_
+
+//-------- <<< Use Configuration Wizard in Context Menu >>> --------------------
+//------ With VS Code: Open Preview for Configuration Wizard -------------------
+
+// Frame width
+// Defines the video stream frame width in pixels.
+// Common frame widths: 320, 640, 800, 1024.
+// Default: 640
+#ifndef VIDEO_OUT_FRAME_WIDTH
+#define VIDEO_OUT_FRAME_WIDTH 320
+#endif
+
+// Frame height
+// Defines the video stream frame height in pixels.
+// Common frame heights: 240, 480, 600, 768.
+// Default: 480
+#ifndef VIDEO_OUT_FRAME_HEIGHT
+#define VIDEO_OUT_FRAME_HEIGHT 240
+#endif
+
+// Frame rate
+// Defines the video stream frame rate in frames per second.
+// Common frame rates: 15, 25, 30, 60.
+// Default: 30
+#ifndef VIDEO_OUT_FRAME_RATE
+#define VIDEO_OUT_FRAME_RATE 30
+#endif
+
+// Color format <0=>Grayscale(8-bit) <1=>RGB888 <2=>BGR565 <3=>YUV420 <4=>NV12 <5=>NV21
+// Defines the video frame color space.
+// Default: 1
+#ifndef VIDEO_OUT_FRAME_COLOR
+#define VIDEO_OUT_FRAME_COLOR 1
+#endif
+
+// Video File Name
+// Defines the name of the video file to be used for streaming.
+// Default: "" (use streaming device instead of file)
+#ifndef VIDEO_OUT_FILENAME
+#define VIDEO_OUT_FILENAME ""
+#endif
+
+#endif
diff --git a/board/Corstone-300/RTE/Device/SSE-300-MPS3/ac6_linker_script.sct.src b/board/Corstone-300/RTE/Device/SSE-300-MPS3/ac6_linker_script.sct.src
new file mode 100644
index 0000000..233a6de
--- /dev/null
+++ b/board/Corstone-300/RTE/Device/SSE-300-MPS3/ac6_linker_script.sct.src
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2023 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.
+ */
+
+/* ----------------------------------------------------------------------------
+ Stack seal size definition
+ *----------------------------------------------------------------------------*/
+#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
+#define __STACKSEAL_SIZE 8
+#else
+#define __STACKSEAL_SIZE 0
+#endif
+
+/*----------------------------------------------------------------------------
+ Scatter File Definitions definition
+ *----------------------------------------------------------------------------*/
+
+LR_ROM0 __ROM0_BASE __ROM0_SIZE {
+
+ ER_ROM0 __ROM0_BASE __ROM0_SIZE {
+ *.o (RESET, +First)
+ *(InRoot$$Sections)
+ }
+
+#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
+ ER_CMSE_VENEER AlignExpr(+0, 32) (__ROM0_SIZE - AlignExpr(ImageLength(ER_ROM0), 32)) {
+ *(Veneer$$CMSE)
+ }
+#endif
+}
+
+LR_ROM1 __ROM1_BASE __ROM1_SIZE {
+
+ ER_ROM1 __ROM1_BASE __ROM1_SIZE {
+ *(+RO +XO)
+ }
+
+ RW_NOINIT __RAM0_BASE UNINIT (__RAM0_SIZE - __HEAP_SIZE - __STACK_SIZE - __STACKSEAL_SIZE) {
+ *.o(.bss.noinit)
+ *.o(.bss.noinit.*)
+ }
+
+ RW_RAM0 AlignExpr(+0, 8) (__RAM0_SIZE - __HEAP_SIZE - __STACK_SIZE - __STACKSEAL_SIZE - AlignExpr(ImageLength(RW_NOINIT), 8)) {
+ *(+RW +ZI)
+ }
+
+#if __HEAP_SIZE > 0
+ ARM_LIB_HEAP (AlignExpr(+0, 8)) EMPTY __HEAP_SIZE { ; Reserve empty region for heap
+ }
+#endif
+
+ ARM_LIB_STACK (__RAM0_BASE + __RAM0_SIZE - __STACKSEAL_SIZE) EMPTY -__STACK_SIZE { ; Reserve empty region for stack
+ }
+
+#if __STACKSEAL_SIZE > 0
+ STACKSEAL +0 EMPTY __STACKSEAL_SIZE { ; Reserve empty region for stack seal immediately after stack
+ }
+#endif
+
+#if __RAM1_SIZE > 0
+ RW_RAM1 __RAM1_BASE __RAM1_SIZE {
+ ; Ethos-U Cache Area
+ *.o (*ethos_cache_buf)
+
+ ; NN Activation Tensor (activation buffer / tensor arena)
+ *.o (*activation_buf)
+
+ .ANY (+RW +ZI)
+ }
+#endif
+
+#if __RAM2_SIZE > 0
+ RW_RAM2 __RAM2_BASE __RAM2_SIZE {
+ .ANY (+RW +ZI)
+ }
+#endif
+
+#if __RAM3_SIZE > 0
+ RW_RAM3 __RAM3_BASE __RAM3_SIZE {
+ .ANY (+RW +ZI)
+ }
+#endif
+}
+
+#if __ROM2_SIZE > 0
+LR_ROM2 __ROM2_BASE __ROM2_SIZE {
+ ER_ROM2 +0 __ROM2_SIZE {
+ ; NN Model Binary Representation
+ *.o (nn_model)
+
+ .ANY (+RO +XO)
+ }
+}
+#endif
+
+#if __ROM3_SIZE > 0
+LR_ROM3 __ROM3_BASE __ROM3_SIZE {
+ ER_ROM3 +0 __ROM3_SIZE {
+ .ANY (+RO +XO)
+ }
+}
+#endif
diff --git a/board/Corstone-300/RTE/Device/SSE-300-MPS3/device_cfg.h b/board/Corstone-300/RTE/Device/SSE-300-MPS3/device_cfg.h
new file mode 100644
index 0000000..0e9746a
--- /dev/null
+++ b/board/Corstone-300/RTE/Device/SSE-300-MPS3/device_cfg.h
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2020-2024 Arm Limited. All rights reserved.
+ *
+ * Licensed under the Apache License Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing software
+ * distributed under the License is distributed on an "AS IS" BASIS
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __DEVICE_CFG_H__
+#define __DEVICE_CFG_H__
+
+/**
+ * \file device_cfg.h
+ * \brief Configuration file native driver re-targeting
+ *
+ * \details This file can be used to add native driver specific macro
+ * definitions to select which peripherals are available in the build.
+ *
+ * This is a default device configuration file with all peripherals enabled.
+ */
+
+/* Secure only peripheral configuration */
+
+/* ARM MPS3 IO SCC */
+#define MPS3_IO_S
+#define MPS3_IO_DEV MPS3_IO_DEV_S
+
+/* I2C_SBCon */
+#define I2C0_SBCON_S
+#define I2C0_SBCON_DEV I2C0_SBCON_DEV_S
+
+/* I2S */
+#define MPS3_I2S_S
+#define MPS3_I2S_DEV MPS3_I2S_DEV_S
+
+/* ARM UART Controller PL011 */
+#define UART0_CMSDK_S
+#define UART0_CMSDK_DEV UART0_CMSDK_DEV_S
+#define UART1_CMSDK_S
+#define UART1_CMSDK_DEV UART1_CMSDK_DEV_S
+
+#define DEFAULT_UART_BAUDRATE 115200U
+
+/* To be used as CODE and DATA sram */
+#define MPC_ISRAM0_S
+#define MPC_ISRAM0_DEV MPC_ISRAM0_DEV_S
+
+#define MPC_ISRAM1_S
+#define MPC_ISRAM1_DEV MPC_ISRAM0_DEV_S
+
+#define MPC_SRAM_S
+#define MPC_SRAM_DEV MPC_SRAM_DEV_S
+
+#define MPC_QSPI_S
+#define MPC_QSPI_DEV MPC_QSPI_DEV_S
+
+/** System Counter Armv8-M */
+#define SYSCOUNTER_CNTRL_ARMV8_M_S
+#define SYSCOUNTER_CNTRL_ARMV8_M_DEV SYSCOUNTER_CNTRL_ARMV8_M_DEV_S
+
+#define SYSCOUNTER_READ_ARMV8_M_S
+#define SYSCOUNTER_READ_ARMV8_M_DEV SYSCOUNTER_READ_ARMV8_M_DEV_S
+/**
+ * Arbitrary scaling values for test purposes
+ */
+#define SYSCOUNTER_ARMV8_M_DEFAULT_SCALE0_INT 1u
+#define SYSCOUNTER_ARMV8_M_DEFAULT_SCALE0_FRACT 0u
+#define SYSCOUNTER_ARMV8_M_DEFAULT_SCALE1_INT 1u
+#define SYSCOUNTER_ARMV8_M_DEFAULT_SCALE1_FRACT 0u
+
+/* System timer */
+#define SYSTIMER0_ARMV8_M_S
+#define SYSTIMER0_ARMV8_M_DEV SYSTIMER0_ARMV8_M_DEV_S
+#define SYSTIMER1_ARMV8_M_S
+#define SYSTIMER1_ARMV8_M_DEV SYSTIMER1_ARMV8_M_DEV_S
+#define SYSTIMER2_ARMV8_M_S
+#define SYSTIMER2_ARMV8_M_DEV SYSTIMER2_ARMV8_M_DEV_S
+#define SYSTIMER3_ARMV8_M_S
+#define SYSTIMER3_ARMV8_M_DEV SYSTIMER3_ARMV8_M_DEV_S
+
+#define SYSTIMER0_ARMV8M_DEFAULT_FREQ_HZ (25000000ul)
+#define SYSTIMER1_ARMV8M_DEFAULT_FREQ_HZ (25000000ul)
+#define SYSTIMER2_ARMV8M_DEFAULT_FREQ_HZ (25000000ul)
+#define SYSTIMER3_ARMV8M_DEFAULT_FREQ_HZ (25000000ul)
+
+/* CMSDK GPIO driver structures */
+#define GPIO0_CMSDK_S
+#define GPIO0_CMSDK_DEV GPIO0_CMSDK_DEV_S
+#define GPIO1_CMSDK_S
+#define GPIO1_CMSDK_DEV GPIO1_CMSDK_DEV_S
+#define GPIO2_CMSDK_S
+#define GPIO2_CMSDK_DEV GPIO2_CMSDK_DEV_S
+#define GPIO3_CMSDK_S
+#define GPIO3_CMSDK_DEV GPIO3_CMSDK_DEV_S
+
+/* System Watchdogs */
+#define SYSWDOG_ARMV8_M_S
+#define SYSWDOG_ARMV8_M_DEV SYSWDOG_ARMV8_M_DEV_S
+
+/* ARM MPC SIE 300 driver structures */
+#define MPC_VM0_S
+#define MPC_VM0_DEV MPC_VM0_DEV_S
+#define MPC_VM1_S
+#define MPC_VM1_DEV MPC_VM1_DEV_S
+#define MPC_SSRAM2_S
+#define MPC_SSRAM2_DEV MPC_SSRAM2_DEV_S
+#define MPC_SSRAM3_S
+#define MPC_SSRAM3_DEV MPC_SSRAM3_DEV_S
+
+/* ARM PPC driver structures */
+#define PPC_SSE300_MAIN0_S
+#define PPC_SSE300_MAIN0_DEV PPC_SSE300_MAIN0_DEV_S
+#define PPC_SSE300_MAIN_EXP0_S
+#define PPC_SSE300_MAIN_EXP0_DEV PPC_SSE300_MAIN_EXP0_DEV_S
+#define PPC_SSE300_MAIN_EXP1_S
+#define PPC_SSE300_MAIN_EXP1_DEV PPC_SSE300_MAIN_EXP1_DEV_S
+#define PPC_SSE300_MAIN_EXP2_S
+#define PPC_SSE300_MAIN_EXP2_DEV PPC_SSE300_MAIN_EXP2_DEV_S
+#define PPC_SSE300_MAIN_EXP3_S
+#define PPC_SSE300_MAIN_EXP3_DEV PPC_SSE300_MAIN_EXP3_DEV_S
+#define PPC_SSE300_PERIPH0_S
+#define PPC_SSE300_PERIPH0_DEV PPC_SSE300_PERIPH0_DEV_S
+#define PPC_SSE300_PERIPH1_S
+#define PPC_SSE300_PERIPH1_DEV PPC_SSE300_PERIPH1_DEV_S
+#define PPC_SSE300_PERIPH_EXP0_S
+#define PPC_SSE300_PERIPH_EXP0_DEV PPC_SSE300_PERIPH_EXP0_DEV_S
+#define PPC_SSE300_PERIPH_EXP1_S
+#define PPC_SSE300_PERIPH_EXP1_DEV PPC_SSE300_PERIPH_EXP1_DEV_S
+#define PPC_SSE300_PERIPH_EXP2_S
+#define PPC_SSE300_PERIPH_EXP2_DEV PPC_SSE300_PERIPH_EXP2_DEV_S
+#define PPC_SSE300_PERIPH_EXP3_S
+#define PPC_SSE300_PERIPH_EXP3_DEV PPC_SSE300_PERIPH_EXP3_DEV_S
+
+/* ARM SPI PL022 */
+/* Invalid device stubs are not defined */
+#define DEFAULT_SPI_SPEED_HZ 4000000U /* 4MHz */
+#define SPI1_PL022_S
+#define SPI1_PL022_DEV SPI1_PL022_DEV_S
+
+#endif /* __DEVICE_CFG_H__ */
diff --git a/board/Corstone-300/RTE/Device/SSE-300-MPS3/device_cfg.h.base@1.1.4 b/board/Corstone-300/RTE/Device/SSE-300-MPS3/device_cfg.h.base@1.1.4
new file mode 100644
index 0000000..0e9746a
--- /dev/null
+++ b/board/Corstone-300/RTE/Device/SSE-300-MPS3/device_cfg.h.base@1.1.4
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2020-2024 Arm Limited. All rights reserved.
+ *
+ * Licensed under the Apache License Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing software
+ * distributed under the License is distributed on an "AS IS" BASIS
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __DEVICE_CFG_H__
+#define __DEVICE_CFG_H__
+
+/**
+ * \file device_cfg.h
+ * \brief Configuration file native driver re-targeting
+ *
+ * \details This file can be used to add native driver specific macro
+ * definitions to select which peripherals are available in the build.
+ *
+ * This is a default device configuration file with all peripherals enabled.
+ */
+
+/* Secure only peripheral configuration */
+
+/* ARM MPS3 IO SCC */
+#define MPS3_IO_S
+#define MPS3_IO_DEV MPS3_IO_DEV_S
+
+/* I2C_SBCon */
+#define I2C0_SBCON_S
+#define I2C0_SBCON_DEV I2C0_SBCON_DEV_S
+
+/* I2S */
+#define MPS3_I2S_S
+#define MPS3_I2S_DEV MPS3_I2S_DEV_S
+
+/* ARM UART Controller PL011 */
+#define UART0_CMSDK_S
+#define UART0_CMSDK_DEV UART0_CMSDK_DEV_S
+#define UART1_CMSDK_S
+#define UART1_CMSDK_DEV UART1_CMSDK_DEV_S
+
+#define DEFAULT_UART_BAUDRATE 115200U
+
+/* To be used as CODE and DATA sram */
+#define MPC_ISRAM0_S
+#define MPC_ISRAM0_DEV MPC_ISRAM0_DEV_S
+
+#define MPC_ISRAM1_S
+#define MPC_ISRAM1_DEV MPC_ISRAM0_DEV_S
+
+#define MPC_SRAM_S
+#define MPC_SRAM_DEV MPC_SRAM_DEV_S
+
+#define MPC_QSPI_S
+#define MPC_QSPI_DEV MPC_QSPI_DEV_S
+
+/** System Counter Armv8-M */
+#define SYSCOUNTER_CNTRL_ARMV8_M_S
+#define SYSCOUNTER_CNTRL_ARMV8_M_DEV SYSCOUNTER_CNTRL_ARMV8_M_DEV_S
+
+#define SYSCOUNTER_READ_ARMV8_M_S
+#define SYSCOUNTER_READ_ARMV8_M_DEV SYSCOUNTER_READ_ARMV8_M_DEV_S
+/**
+ * Arbitrary scaling values for test purposes
+ */
+#define SYSCOUNTER_ARMV8_M_DEFAULT_SCALE0_INT 1u
+#define SYSCOUNTER_ARMV8_M_DEFAULT_SCALE0_FRACT 0u
+#define SYSCOUNTER_ARMV8_M_DEFAULT_SCALE1_INT 1u
+#define SYSCOUNTER_ARMV8_M_DEFAULT_SCALE1_FRACT 0u
+
+/* System timer */
+#define SYSTIMER0_ARMV8_M_S
+#define SYSTIMER0_ARMV8_M_DEV SYSTIMER0_ARMV8_M_DEV_S
+#define SYSTIMER1_ARMV8_M_S
+#define SYSTIMER1_ARMV8_M_DEV SYSTIMER1_ARMV8_M_DEV_S
+#define SYSTIMER2_ARMV8_M_S
+#define SYSTIMER2_ARMV8_M_DEV SYSTIMER2_ARMV8_M_DEV_S
+#define SYSTIMER3_ARMV8_M_S
+#define SYSTIMER3_ARMV8_M_DEV SYSTIMER3_ARMV8_M_DEV_S
+
+#define SYSTIMER0_ARMV8M_DEFAULT_FREQ_HZ (25000000ul)
+#define SYSTIMER1_ARMV8M_DEFAULT_FREQ_HZ (25000000ul)
+#define SYSTIMER2_ARMV8M_DEFAULT_FREQ_HZ (25000000ul)
+#define SYSTIMER3_ARMV8M_DEFAULT_FREQ_HZ (25000000ul)
+
+/* CMSDK GPIO driver structures */
+#define GPIO0_CMSDK_S
+#define GPIO0_CMSDK_DEV GPIO0_CMSDK_DEV_S
+#define GPIO1_CMSDK_S
+#define GPIO1_CMSDK_DEV GPIO1_CMSDK_DEV_S
+#define GPIO2_CMSDK_S
+#define GPIO2_CMSDK_DEV GPIO2_CMSDK_DEV_S
+#define GPIO3_CMSDK_S
+#define GPIO3_CMSDK_DEV GPIO3_CMSDK_DEV_S
+
+/* System Watchdogs */
+#define SYSWDOG_ARMV8_M_S
+#define SYSWDOG_ARMV8_M_DEV SYSWDOG_ARMV8_M_DEV_S
+
+/* ARM MPC SIE 300 driver structures */
+#define MPC_VM0_S
+#define MPC_VM0_DEV MPC_VM0_DEV_S
+#define MPC_VM1_S
+#define MPC_VM1_DEV MPC_VM1_DEV_S
+#define MPC_SSRAM2_S
+#define MPC_SSRAM2_DEV MPC_SSRAM2_DEV_S
+#define MPC_SSRAM3_S
+#define MPC_SSRAM3_DEV MPC_SSRAM3_DEV_S
+
+/* ARM PPC driver structures */
+#define PPC_SSE300_MAIN0_S
+#define PPC_SSE300_MAIN0_DEV PPC_SSE300_MAIN0_DEV_S
+#define PPC_SSE300_MAIN_EXP0_S
+#define PPC_SSE300_MAIN_EXP0_DEV PPC_SSE300_MAIN_EXP0_DEV_S
+#define PPC_SSE300_MAIN_EXP1_S
+#define PPC_SSE300_MAIN_EXP1_DEV PPC_SSE300_MAIN_EXP1_DEV_S
+#define PPC_SSE300_MAIN_EXP2_S
+#define PPC_SSE300_MAIN_EXP2_DEV PPC_SSE300_MAIN_EXP2_DEV_S
+#define PPC_SSE300_MAIN_EXP3_S
+#define PPC_SSE300_MAIN_EXP3_DEV PPC_SSE300_MAIN_EXP3_DEV_S
+#define PPC_SSE300_PERIPH0_S
+#define PPC_SSE300_PERIPH0_DEV PPC_SSE300_PERIPH0_DEV_S
+#define PPC_SSE300_PERIPH1_S
+#define PPC_SSE300_PERIPH1_DEV PPC_SSE300_PERIPH1_DEV_S
+#define PPC_SSE300_PERIPH_EXP0_S
+#define PPC_SSE300_PERIPH_EXP0_DEV PPC_SSE300_PERIPH_EXP0_DEV_S
+#define PPC_SSE300_PERIPH_EXP1_S
+#define PPC_SSE300_PERIPH_EXP1_DEV PPC_SSE300_PERIPH_EXP1_DEV_S
+#define PPC_SSE300_PERIPH_EXP2_S
+#define PPC_SSE300_PERIPH_EXP2_DEV PPC_SSE300_PERIPH_EXP2_DEV_S
+#define PPC_SSE300_PERIPH_EXP3_S
+#define PPC_SSE300_PERIPH_EXP3_DEV PPC_SSE300_PERIPH_EXP3_DEV_S
+
+/* ARM SPI PL022 */
+/* Invalid device stubs are not defined */
+#define DEFAULT_SPI_SPEED_HZ 4000000U /* 4MHz */
+#define SPI1_PL022_S
+#define SPI1_PL022_DEV SPI1_PL022_DEV_S
+
+#endif /* __DEVICE_CFG_H__ */
diff --git a/board/Corstone-300/RTE/Device/SSE-300-MPS3/gcc_linker_script.ld.src b/board/Corstone-300/RTE/Device/SSE-300-MPS3/gcc_linker_script.ld.src
new file mode 100644
index 0000000..2e2ef6f
--- /dev/null
+++ b/board/Corstone-300/RTE/Device/SSE-300-MPS3/gcc_linker_script.ld.src
@@ -0,0 +1,341 @@
+/*
+ * Copyright (c) 2023 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.
+ */
+
+/* ----------------------------------------------------------------------------
+ Stack seal size definition
+ *----------------------------------------------------------------------------*/
+#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
+#define __STACKSEAL_SIZE ( 8 )
+#else
+#define __STACKSEAL_SIZE ( 0 )
+#endif
+
+/* ----------------------------------------------------------------------------
+ Memory definition
+ *----------------------------------------------------------------------------*/
+MEMORY
+{
+ ROM0 (rx) : ORIGIN = __ROM0_BASE, LENGTH = __ROM0_SIZE
+#if __ROM1_SIZE > 0
+ ROM1 (rx) : ORIGIN = __ROM1_BASE, LENGTH = __ROM1_SIZE
+#endif
+#if __ROM2_SIZE > 0
+ ROM2 (rx) : ORIGIN = __ROM2_BASE, LENGTH = __ROM2_SIZE
+#endif
+#if __ROM3_SIZE > 0
+ ROM3 (rx) : ORIGIN = __ROM3_BASE, LENGTH = __ROM3_SIZE
+#endif
+
+ RAM0 (rwx) : ORIGIN = __RAM0_BASE, LENGTH = __RAM0_SIZE
+#if __RAM1_SIZE > 0
+ RAM1 (rwx) : ORIGIN = __RAM1_BASE, LENGTH = __RAM1_SIZE
+#endif
+#if __RAM2_SIZE > 0
+ RAM2 (rwx) : ORIGIN = __RAM2_BASE, LENGTH = __RAM2_SIZE
+#endif
+#if __RAM3_SIZE > 0
+ RAM3 (rwx) : ORIGIN = __RAM3_BASE, LENGTH = __RAM3_SIZE
+#endif
+}
+
+/* Linker script to place sections and symbol values. Should be used together
+ * with other linker script that defines memory regions FLASH and RAM.
+ * It references following symbols, which must be defined in code:
+ * Reset_Handler : Entry of reset handler
+ *
+ * It defines following symbols, which code can use without definition:
+ * __exidx_start
+ * __exidx_end
+ * __copy_table_start__
+ * __copy_table_end__
+ * __zero_table_start__
+ * __zero_table_end__
+ * __etext (deprecated)
+ * __data_start__
+ * __preinit_array_start
+ * __preinit_array_end
+ * __init_array_start
+ * __init_array_end
+ * __fini_array_start
+ * __fini_array_end
+ * __data_end__
+ * __bss_start__
+ * __bss_end__
+ * __noinit_start
+ * __noinit_end
+ * __end__
+ * end
+ * __HeapLimit
+ * __StackLimit
+ * __StackTop
+ * __stack
+ */
+ENTRY(Reset_Handler)
+
+SECTIONS
+{
+ .boot :
+ {
+ KEEP(*(.vectors))
+ } > ROM0
+
+#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
+ .gnu.sgstubs :
+ {
+ . = ALIGN(32);
+ } > ROM0
+#endif
+
+ .text :
+ {
+ *(.text*)
+
+ KEEP(*(.init))
+ KEEP(*(.fini))
+
+ /* .ctors */
+ *crtbegin.o(.ctors)
+ *crtbegin?.o(.ctors)
+ *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
+ *(SORT(.ctors.*))
+ *(.ctors)
+
+ /* .dtors */
+ *crtbegin.o(.dtors)
+ *crtbegin?.o(.dtors)
+ *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
+ *(SORT(.dtors.*))
+ *(.dtors)
+
+ *(.rodata*)
+
+ KEEP(*(.eh_frame*))
+ } > ROM1
+
+ .ARM.extab :
+ {
+ *(.ARM.extab* .gnu.linkonce.armextab.*)
+ } > ROM1
+
+ __exidx_start = .;
+ .ARM.exidx :
+ {
+ *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+ } > ROM1
+ __exidx_end = .;
+
+ .copy.table :
+ {
+ . = ALIGN(4);
+ __copy_table_start__ = .;
+
+ LONG (LOADADDR(.data))
+ LONG (ADDR(.data))
+ LONG (SIZEOF(.data) / 4)
+
+ LONG (LOADADDR(.init_buf))
+ LONG (ADDR(.init_buf))
+ LONG (SIZEOF(.init_buf) / 4)
+
+ /* Add each additional data section here */
+/*
+ LONG (LOADADDR(.data2))
+ LONG (ADDR(.data2))
+ LONG (SIZEOF(.data2) / 4)
+*/
+ __copy_table_end__ = .;
+ } > ROM1
+
+ .zero.table :
+ {
+ . = ALIGN(4);
+ __zero_table_start__ = .;
+
+/* .bss initialization to zero is already done during C Run-Time Startup.
+ LONG (ADDR(.bss))
+ LONG (SIZEOF(.bss) / 4)
+*/
+
+ /* Add each additional bss section here */
+/*
+ LONG (ADDR(.bss2))
+ LONG (SIZEOF(.bss2) / 4)
+*/
+ __zero_table_end__ = .;
+ } > ROM1
+
+ /*
+ * This __etext variable is kept for backward compatibility with older,
+ * ASM based startup files.
+ */
+ PROVIDE(__etext = LOADADDR(.data));
+
+ .data : ALIGN(4)
+ {
+ __data_start__ = .;
+ *(vtable)
+ *(.data)
+ *(.data.*)
+
+ . = ALIGN(4);
+ /* preinit data */
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP(*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+
+ . = ALIGN(4);
+ /* init data */
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP(*(SORT(.init_array.*)))
+ KEEP(*(.init_array))
+ PROVIDE_HIDDEN (__init_array_end = .);
+
+ . = ALIGN(4);
+ /* finit data */
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP(*(SORT(.fini_array.*)))
+ KEEP(*(.fini_array))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+
+ KEEP(*(.jcr*))
+ . = ALIGN(4);
+ /* All data end */
+ __data_end__ = .;
+
+ } > RAM0 AT > ROM1
+
+ /*
+ * Secondary data section, optional
+ *
+ * Remember to add each additional data section
+ * to the .copy.table above to assure proper
+ * initialization during startup.
+ */
+/*
+ .data2 : ALIGN(4)
+ {
+ . = ALIGN(4);
+ __data2_start__ = .;
+ *(.data2)
+ *(.data2.*)
+ . = ALIGN(4);
+ __data2_end__ = .;
+
+ } > RAM1 AT > ROM1
+*/
+
+ .bss :
+ {
+ . = ALIGN(4);
+ __bss_start__ = .;
+ *(.bss)
+ *(.bss.*)
+ *(COMMON)
+ . = ALIGN(4);
+ __bss_end__ = .;
+ } > RAM0 AT > RAM0
+
+ /*
+ * Secondary bss section, optional
+ *
+ * Remember to add each additional bss section
+ * to the .zero.table above to assure proper
+ * initialization during startup.
+ */
+/*
+ .bss2 :
+ {
+ . = ALIGN(4);
+ __bss2_start__ = .;
+ *(.bss2)
+ *(.bss2.*)
+ . = ALIGN(4);
+ __bss2_end__ = .;
+ } > RAM1 AT > RAM1
+*/
+
+ /* This section contains data that is not initialized during load,
+ or during the application's initialization sequence. */
+ .noinit (NOLOAD) :
+ {
+ . = ALIGN(4);
+ __noinit_start = .;
+ *(.noinit)
+ *(.noinit.*)
+ . = ALIGN(4);
+ __noinit_end = .;
+ } > RAM0
+
+ .heap (NOLOAD) :
+ {
+ . = ALIGN(8);
+ __end__ = .;
+ PROVIDE(end = .);
+ . = . + __HEAP_SIZE;
+ . = ALIGN(8);
+ __HeapLimit = .;
+ } > RAM0
+
+ .stack (ORIGIN(RAM0) + LENGTH(RAM0) - __STACK_SIZE - __STACKSEAL_SIZE) (NOLOAD) :
+ {
+ . = ALIGN(8);
+ __StackLimit = .;
+ . = . + __STACK_SIZE;
+ . = ALIGN(8);
+ __StackTop = .;
+ } > RAM0
+ PROVIDE(__stack = __StackTop);
+
+#if __STACKSEAL_SIZE > 0
+ .stackseal (ORIGIN(RAM0) + LENGTH(RAM0) - __STACKSEAL_SIZE) (NOLOAD) :
+ {
+ . = ALIGN(8);
+ __StackSeal = .;
+ . = . + 8;
+ . = ALIGN(8);
+ } > RAM0
+#endif
+
+ /* Check if data + heap + stack exceeds RAM limit */
+ ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
+
+ /* Non-initialized buffers in fast access RAM */
+ .cache (NOLOAD):
+ {
+ . = ALIGN(32);
+ *(*ethos_cache_buf) /* Ethos-U Cache Area */
+ *(*activation_buf) /* NN Activation Tensor (activation buffer / tensor arena) */
+ } > RAM1
+
+ /* Initialized buffers in fast access RAM */
+ /* Entry must exist in .copy.table */
+ .init_buf :
+ {
+ /* Add objects that go into RAM1 */
+ } > RAM1 AT > ROM1
+
+ .rom2 :
+ {
+ *(*nn_model) /* NN Model Binary Representation */
+ } > ROM2
+
+ .rom3 :
+ {
+ /* Add objects that go into ROM3 */
+ } > ROM3
+}
diff --git a/board/Corstone-300/RTE/Device/SSE-300-MPS3/iar_linker_script.icf.src b/board/Corstone-300/RTE/Device/SSE-300-MPS3/iar_linker_script.icf.src
new file mode 100644
index 0000000..ea02d53
--- /dev/null
+++ b/board/Corstone-300/RTE/Device/SSE-300-MPS3/iar_linker_script.icf.src
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2023-2024 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.
+ */
+
+define memory mem with size = 4G;
+
+#if __ROM0_SIZE > 0
+ define region ROM0_region = mem:[from __ROM0_BASE to (__ROM0_BASE+__ROM0_SIZE-1)];
+#else
+ define region ROM0_region = [];
+#endif
+
+#if __ROM1_SIZE > 0
+ define region ROM1_region = mem:[from __ROM1_BASE to (__ROM1_BASE+__ROM1_SIZE-1)];
+#else
+ define region ROM1_region = [];
+#endif
+
+#if __ROM2_SIZE > 0
+ define region ROM2_region = mem:[from __ROM2_BASE to (__ROM2_BASE+__ROM2_SIZE-1)];
+#else
+ define region ROM2_region = [];
+#endif
+
+#if __ROM3_SIZE > 0
+ define region ROM3_region = mem:[from __ROM3_BASE to (__ROM3_BASE+__ROM3_SIZE-1)];
+#else
+ define region ROM3_region = [];
+#endif
+
+define region ROM_region = ROM0_region | ROM1_region | ROM2_region | ROM3_region;
+
+#if __RAM0_SIZE > 0
+ define region RAM0_region = mem:[from __RAM0_BASE to (__RAM0_BASE+__RAM0_SIZE-1)];
+#else
+ define region RAM0_region = [];
+#endif
+
+#if __RAM1_SIZE > 0
+ define region RAM1_region = mem:[from __RAM1_BASE to (__RAM1_BASE+__RAM1_SIZE-1)];
+#else
+ define region RAM1_region = [];
+#endif
+
+#if __RAM2_SIZE > 0
+ define region RAM2_region = mem:[from __RAM2_BASE to (__RAM2_BASE+__RAM2_SIZE-1)];
+#else
+ define region RAM2_region = [];
+#endif
+
+#if __RAM3_SIZE > 0
+ define region RAM3_region = mem:[from __RAM3_BASE to (__RAM3_BASE+__RAM3_SIZE-1)];
+#else
+ define region RAM3_region = [];
+#endif
+
+define region RAM_region = RAM0_region | RAM1_region | RAM2_region | RAM3_region;
+
+do not initialize { section .noinit };
+initialize by copy { readwrite };
+if (isdefinedsymbol(__USE_DLIB_PERTHREAD))
+{
+ // Required in a multi-threaded application
+ initialize by copy with packing = none { section __DLIB_PERTHREAD };
+}
+
+place at address mem:__ROM0_BASE { readonly section .intvec };
+
+if (!isempty(ROM_region))
+{
+ place in ROM_region { readonly };
+}
+
+if (!isempty(RAM_region))
+{
+ define block CSTACK with alignment = 8, size = __STACK_SIZE { };
+ define block PROC_STACK with alignment = 8, size = 0 { };
+ define block HEAP with alignment = 8, size = __HEAP_SIZE { };
+ place in RAM_region { readwrite, block CSTACK, block PROC_STACK, block HEAP };
+}
diff --git a/board/Corstone-300/RTE/Device/SSE-300-MPS3/startup_SSE300MPS3.c b/board/Corstone-300/RTE/Device/SSE-300-MPS3/startup_SSE300MPS3.c
new file mode 100644
index 0000000..b29bff1
--- /dev/null
+++ b/board/Corstone-300/RTE/Device/SSE-300-MPS3/startup_SSE300MPS3.c
@@ -0,0 +1,487 @@
+/*
+ * Copyright (c) 2022-2023 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.
+ */
+
+/*
+ * This file is derivative of CMSIS V5.9.0 startup_ARMCM55.c
+ * Git SHA: 2b7495b8535bdcb306dac29b9ded4cfb679d7e5c
+ */
+
+#include "SSE300MPS3.h"
+
+/*----------------------------------------------------------------------------
+ External References
+ *----------------------------------------------------------------------------*/
+extern uint32_t __INITIAL_SP;
+extern uint32_t __STACK_LIMIT;
+#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
+extern uint64_t __STACK_SEAL;
+#endif
+
+extern __NO_RETURN void __PROGRAM_START(void);
+
+/*----------------------------------------------------------------------------
+ Internal References
+ *----------------------------------------------------------------------------*/
+void __NO_RETURN Reset_Handler (void);
+
+/*----------------------------------------------------------------------------
+ Exception / Interrupt Handler
+ *----------------------------------------------------------------------------*/
+#define DEFAULT_IRQ_HANDLER(handler_name) \
+void __NO_RETURN __WEAK handler_name(void); \
+void handler_name(void) { \
+ while(1); \
+}
+
+/* Exceptions */
+DEFAULT_IRQ_HANDLER(NMI_Handler)
+DEFAULT_IRQ_HANDLER(HardFault_Handler)
+DEFAULT_IRQ_HANDLER(MemManage_Handler)
+DEFAULT_IRQ_HANDLER(BusFault_Handler)
+DEFAULT_IRQ_HANDLER(UsageFault_Handler)
+DEFAULT_IRQ_HANDLER(SecureFault_Handler)
+DEFAULT_IRQ_HANDLER(SVC_Handler)
+DEFAULT_IRQ_HANDLER(DebugMon_Handler)
+DEFAULT_IRQ_HANDLER(PendSV_Handler)
+DEFAULT_IRQ_HANDLER(SysTick_Handler)
+
+DEFAULT_IRQ_HANDLER(NONSEC_WATCHDOG_RESET_REQ_Handler)
+DEFAULT_IRQ_HANDLER(NONSEC_WATCHDOG_Handler)
+DEFAULT_IRQ_HANDLER(SLOWCLK_Timer_Handler)
+DEFAULT_IRQ_HANDLER(TFM_TIMER0_IRQ_Handler)
+DEFAULT_IRQ_HANDLER(TIMER1_Handler)
+DEFAULT_IRQ_HANDLER(TIMER2_Handler)
+DEFAULT_IRQ_HANDLER(MPC_Handler)
+DEFAULT_IRQ_HANDLER(PPC_Handler)
+DEFAULT_IRQ_HANDLER(MSC_Handler)
+DEFAULT_IRQ_HANDLER(BRIDGE_ERROR_Handler)
+DEFAULT_IRQ_HANDLER(MGMT_PPU_Handler)
+DEFAULT_IRQ_HANDLER(SYS_PPU_Handler)
+DEFAULT_IRQ_HANDLER(CPU0_PPU_Handler)
+DEFAULT_IRQ_HANDLER(DEBUG_PPU_Handler)
+DEFAULT_IRQ_HANDLER(TIMER3_AON_Handler)
+DEFAULT_IRQ_HANDLER(CPU0_CTI_0_Handler)
+DEFAULT_IRQ_HANDLER(CPU0_CTI_1_Handler)
+
+DEFAULT_IRQ_HANDLER(System_Timestamp_Counter_Handler)
+DEFAULT_IRQ_HANDLER(UARTRX0_Handler)
+DEFAULT_IRQ_HANDLER(UARTTX0_Handler)
+DEFAULT_IRQ_HANDLER(UARTRX1_Handler)
+DEFAULT_IRQ_HANDLER(UARTTX1_Handler)
+DEFAULT_IRQ_HANDLER(UARTRX2_Handler)
+DEFAULT_IRQ_HANDLER(UARTTX2_Handler)
+DEFAULT_IRQ_HANDLER(UARTRX3_Handler)
+DEFAULT_IRQ_HANDLER(UARTTX3_Handler)
+DEFAULT_IRQ_HANDLER(UARTRX4_Handler)
+DEFAULT_IRQ_HANDLER(UARTTX4_Handler)
+DEFAULT_IRQ_HANDLER(UART0_Combined_Handler)
+DEFAULT_IRQ_HANDLER(UART1_Combined_Handler)
+DEFAULT_IRQ_HANDLER(UART2_Combined_Handler)
+DEFAULT_IRQ_HANDLER(UART3_Combined_Handler)
+DEFAULT_IRQ_HANDLER(UART4_Combined_Handler)
+DEFAULT_IRQ_HANDLER(UARTOVF_Handler)
+DEFAULT_IRQ_HANDLER(ETHERNET_Handler)
+DEFAULT_IRQ_HANDLER(I2S_Handler)
+DEFAULT_IRQ_HANDLER(TOUCH_SCREEN_Handler)
+DEFAULT_IRQ_HANDLER(USB_Handler)
+DEFAULT_IRQ_HANDLER(SPI_ADC_Handler)
+DEFAULT_IRQ_HANDLER(SPI_SHIELD0_Handler)
+DEFAULT_IRQ_HANDLER(SPI_SHIELD1_Handler)
+DEFAULT_IRQ_HANDLER(ETHOS_U55_Handler)
+#ifdef CORSTONE300_AN547
+DEFAULT_IRQ_HANDLER(DMA_Ch_1_Error_Handler)
+DEFAULT_IRQ_HANDLER(DMA_Ch_1_Terminal_Count_Handler)
+DEFAULT_IRQ_HANDLER(DMA_Ch_1_Combined_Handler)
+DEFAULT_IRQ_HANDLER(DMA_Ch_2_Error_Handler)
+DEFAULT_IRQ_HANDLER(DMA_Ch_2_Terminal_Count_Handler)
+DEFAULT_IRQ_HANDLER(DMA_Ch_2_Combined_Handler)
+DEFAULT_IRQ_HANDLER(DMA_Ch_3_Error_Handler)
+DEFAULT_IRQ_HANDLER(DMA_Ch_3_Terminal_Count_Handler)
+DEFAULT_IRQ_HANDLER(DMA_Ch_3_Combined_Handler)
+#endif
+DEFAULT_IRQ_HANDLER(GPIO0_Combined_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_Combined_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_Combined_Handler)
+DEFAULT_IRQ_HANDLER(GPIO3_Combined_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_0_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_1_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_2_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_3_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_4_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_5_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_6_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_7_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_8_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_9_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_10_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_11_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_12_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_13_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_14_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_15_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_0_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_1_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_2_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_3_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_4_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_5_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_6_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_7_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_8_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_9_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_10_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_11_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_12_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_13_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_14_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_15_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_0_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_1_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_2_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_3_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_4_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_5_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_6_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_7_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_8_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_9_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_10_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_11_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_12_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_13_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_14_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_15_Handler)
+DEFAULT_IRQ_HANDLER(GPIO3_0_Handler)
+DEFAULT_IRQ_HANDLER(GPIO3_1_Handler)
+DEFAULT_IRQ_HANDLER(GPIO3_2_Handler)
+DEFAULT_IRQ_HANDLER(GPIO3_3_Handler)
+DEFAULT_IRQ_HANDLER(UARTRX5_Handler)
+DEFAULT_IRQ_HANDLER(UARTTX5_Handler)
+DEFAULT_IRQ_HANDLER(UART5_Handler)
+#ifdef CORSTONE300_FVP
+DEFAULT_IRQ_HANDLER(ARM_VSI0_Handler)
+DEFAULT_IRQ_HANDLER(ARM_VSI1_Handler)
+DEFAULT_IRQ_HANDLER(ARM_VSI2_Handler)
+DEFAULT_IRQ_HANDLER(ARM_VSI3_Handler)
+DEFAULT_IRQ_HANDLER(ARM_VSI4_Handler)
+DEFAULT_IRQ_HANDLER(ARM_VSI5_Handler)
+DEFAULT_IRQ_HANDLER(ARM_VSI6_Handler)
+DEFAULT_IRQ_HANDLER(ARM_VSI7_Handler)
+#endif
+/*----------------------------------------------------------------------------
+ Exception / Interrupt Vector table
+ *----------------------------------------------------------------------------*/
+
+#if defined ( __GNUC__ )
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpedantic"
+#endif
+
+extern const VECTOR_TABLE_Type __VECTOR_TABLE[];
+ const VECTOR_TABLE_Type __VECTOR_TABLE[] __VECTOR_TABLE_ATTRIBUTE = {
+ (VECTOR_TABLE_Type)(&__INITIAL_SP), /* Initial Stack Pointer */
+ Reset_Handler, /* Reset Handler */
+ NMI_Handler, /* -14: NMI Handler */
+ HardFault_Handler, /* -13: Hard Fault Handler */
+ MemManage_Handler, /* -12: MPU Fault Handler */
+ BusFault_Handler, /* -11: Bus Fault Handler */
+ UsageFault_Handler, /* -10: Usage Fault Handler */
+ SecureFault_Handler, /* -9: Secure Fault Handler */
+ 0, /* Reserved */
+ 0, /* Reserved */
+ 0, /* Reserved */
+ SVC_Handler, /* -5: SVCall Handler */
+ DebugMon_Handler, /* -4: Debug Monitor Handler */
+ 0, /* Reserved */
+ PendSV_Handler, /* -2: PendSV Handler */
+ SysTick_Handler, /* -1: SysTick Handler */
+
+ NONSEC_WATCHDOG_RESET_REQ_Handler, /* 0: Non-Secure Watchdog Reset Request Handler */
+ NONSEC_WATCHDOG_Handler, /* 1: Non-Secure Watchdog Handler */
+ SLOWCLK_Timer_Handler, /* 2: SLOWCLK Timer Handler */
+ TFM_TIMER0_IRQ_Handler, /* 3: TIMER 0 Handler */
+ TIMER1_Handler, /* 4: TIMER 1 Handler */
+ TIMER2_Handler, /* 5: TIMER 2 Handler */
+ 0, /* 6: Reserved */
+ 0, /* 7: Reserved */
+ 0, /* 8: Reserved */
+ MPC_Handler, /* 9: MPC Combined (Secure) Handler */
+ PPC_Handler, /* 10: PPC Combined (Secure) Handler */
+ MSC_Handler, /* 11: MSC Combined (Secure) Handler */
+ BRIDGE_ERROR_Handler, /* 12: Bridge Error (Secure) Handler */
+ 0, /* 13: Reserved */
+ MGMT_PPU_Handler, /* 14: MGMT PPU Handler */
+ SYS_PPU_Handler, /* 15: SYS PPU Handler */
+ CPU0_PPU_Handler, /* 16: CPU0 PPU Handler */
+ 0, /* 17: Reserved */
+ 0, /* 18: Reserved */
+ 0, /* 19: Reserved */
+ 0, /* 20: Reserved */
+ 0, /* 21: Reserved */
+ 0, /* 22: Reserved */
+ 0, /* 23: Reserved */
+ 0, /* 24: Reserved */
+ 0, /* 25: Reserved */
+ DEBUG_PPU_Handler, /* 26: DEBUG PPU Handler */
+ TIMER3_AON_Handler, /* 27: TIMER 3 AON Handler */
+ CPU0_CTI_0_Handler, /* 28: CPU0 CTI IRQ 0 Handler */
+ CPU0_CTI_1_Handler, /* 29: CPU0 CTI IRQ 1 Handler */
+ 0, /* 30: Reserved */
+ 0, /* 31: Reserved */
+
+ /* External interrupts */
+ System_Timestamp_Counter_Handler, /* 32: System timestamp counter Handler */
+ UARTRX0_Handler, /* 33: UART 0 RX Handler */
+ UARTTX0_Handler, /* 34: UART 0 TX Handler */
+ UARTRX1_Handler, /* 35: UART 1 RX Handler */
+ UARTTX1_Handler, /* 36: UART 1 TX Handler */
+ UARTRX2_Handler, /* 37: UART 2 RX Handler */
+ UARTTX2_Handler, /* 38: UART 2 TX Handler */
+ UARTRX3_Handler, /* 39: UART 3 RX Handler */
+ UARTTX3_Handler, /* 40: UART 3 TX Handler */
+ UARTRX4_Handler, /* 41: UART 4 RX Handler */
+ UARTTX4_Handler, /* 42: UART 4 TX Handler */
+ UART0_Combined_Handler, /* 43: UART 0 Combined Handler */
+ UART1_Combined_Handler, /* 44: UART 1 Combined Handler */
+ UART2_Combined_Handler, /* 45: UART 2 Combined Handler */
+ UART3_Combined_Handler, /* 46: UART 3 Combined Handler */
+ UART4_Combined_Handler, /* 47: UART 4 Combined Handler */
+ UARTOVF_Handler, /* 48: UART 0, 1, 2, 3, 4 & 5 Overflow Handler */
+ ETHERNET_Handler, /* 49: Ethernet Handler */
+ I2S_Handler, /* 50: Audio I2S Handler */
+ TOUCH_SCREEN_Handler, /* 51: Touch Screen Handler */
+ USB_Handler, /* 52: USB Handler */
+ SPI_ADC_Handler, /* 53: SPI ADC Handler */
+ SPI_SHIELD0_Handler, /* 54: SPI (Shield 0) Handler */
+ SPI_SHIELD1_Handler, /* 55: SPI (Shield 0) Handler */
+ ETHOS_U55_Handler, /* 56: Ethos-U55 Handler */
+#ifdef CORSTONE300_AN547
+ 0, /* 57: Reserved */
+ 0, /* 58: Reserved */
+ 0, /* 59: Reserved */
+ DMA_Ch_1_Error_Handler, /* 60: DMA Ch1 Error Handler */
+ DMA_Ch_1_Terminal_Count_Handler, /* 61: DMA Ch1 Terminal Count Handler */
+ DMA_Ch_1_Combined_Handler, /* 62: DMA Ch1 Combined Handler */
+ DMA_Ch_2_Error_Handler, /* 63: DMA Ch2 Error Handler */
+ DMA_Ch_2_Terminal_Count_Handler, /* 64: DMA Ch2 Terminal Count Handler */
+ DMA_Ch_2_Combined_Handler, /* 65: DMA Ch2 Combined Handler */
+ DMA_Ch_3_Error_Handler, /* 66: DMA Ch3 Error Handler */
+ DMA_Ch_3_Terminal_Count_Handler, /* 67: DMA Ch3 Terminal Count Handler */
+ DMA_Ch_3_Combined_Handler, /* 68: DMA Ch3 Combined Handler */
+#else
+ 0, /* 57: Reserved */
+ 0, /* 58: Reserved */
+ 0, /* 59: Reserved */
+ 0, /* 60: Reserved */
+ 0, /* 61: Reserved */
+ 0, /* 62: Reserved */
+ 0, /* 63: Reserved */
+ 0, /* 64: Reserved */
+ 0, /* 65: Reserved */
+ 0, /* 66: Reserved */
+ 0, /* 67: Reserved */
+ 0, /* 68: Reserved */
+#endif
+ GPIO0_Combined_Handler, /* 69: GPIO 0 Combined Handler */
+ GPIO1_Combined_Handler, /* 70: GPIO 1 Combined Handler */
+ GPIO2_Combined_Handler, /* 71: GPIO 2 Combined Handler */
+ GPIO3_Combined_Handler, /* 72: GPIO 3 Combined Handler */
+ GPIO0_0_Handler, /* 73: GPIO0 Pin 0 Handler */
+ GPIO0_1_Handler, /* 74: GPIO0 Pin 1 Handler */
+ GPIO0_2_Handler, /* 75: GPIO0 Pin 2 Handler */
+ GPIO0_3_Handler, /* 76: GPIO0 Pin 3 Handler */
+ GPIO0_4_Handler, /* 77: GPIO0 Pin 4 Handler */
+ GPIO0_5_Handler, /* 78: GPIO0 Pin 5 Handler */
+ GPIO0_6_Handler, /* 79: GPIO0 Pin 6 Handler */
+ GPIO0_7_Handler, /* 80: GPIO0 Pin 7 Handler */
+ GPIO0_8_Handler, /* 81: GPIO0 Pin 8 Handler */
+ GPIO0_9_Handler, /* 82: GPIO0 Pin 9 Handler */
+ GPIO0_10_Handler, /* 83: GPIO0 Pin 10 Handler */
+ GPIO0_11_Handler, /* 84: GPIO0 Pin 11 Handler */
+ GPIO0_12_Handler, /* 85: GPIO0 Pin 12 Handler */
+ GPIO0_13_Handler, /* 86: GPIO0 Pin 13 Handler */
+ GPIO0_14_Handler, /* 87: GPIO0 Pin 14 Handler */
+ GPIO0_15_Handler, /* 88: GPIO0 Pin 15 Handler */
+ GPIO1_0_Handler, /* 89: GPIO1 Pin 0 Handler */
+ GPIO1_1_Handler, /* 90: GPIO1 Pin 1 Handler */
+ GPIO1_2_Handler, /* 91: GPIO1 Pin 2 Handler */
+ GPIO1_3_Handler, /* 92: GPIO1 Pin 3 Handler */
+ GPIO1_4_Handler, /* 93: GPIO1 Pin 4 Handler */
+ GPIO1_5_Handler, /* 94: GPIO1 Pin 5 Handler */
+ GPIO1_6_Handler, /* 95: GPIO1 Pin 6 Handler */
+ GPIO1_7_Handler, /* 96: GPIO1 Pin 7 Handler */
+ GPIO1_8_Handler, /* 97: GPIO1 Pin 8 Handler */
+ GPIO1_9_Handler, /* 98: GPIO1 Pin 9 Handler */
+ GPIO1_10_Handler, /* 99: GPIO1 Pin 10 Handler */
+ GPIO1_11_Handler, /* 100: GPIO1 Pin 11 Handler */
+ GPIO1_12_Handler, /* 101: GPIO1 Pin 12 Handler */
+ GPIO1_13_Handler, /* 102: GPIO1 Pin 13 Handler */
+ GPIO1_14_Handler, /* 103: GPIO1 Pin 14 Handler */
+ GPIO1_15_Handler, /* 104: GPIO1 Pin 15 Handler */
+ GPIO2_0_Handler, /* 105: GPIO2 Pin 0 Handler */
+ GPIO2_1_Handler, /* 106: GPIO2 Pin 1 Handler */
+ GPIO2_2_Handler, /* 107: GPIO2 Pin 2 Handler */
+ GPIO2_3_Handler, /* 108: GPIO2 Pin 3 Handler */
+ GPIO2_4_Handler, /* 109: GPIO2 Pin 4 Handler */
+ GPIO2_5_Handler, /* 110: GPIO2 Pin 5 Handler */
+ GPIO2_6_Handler, /* 111: GPIO2 Pin 6 Handler */
+ GPIO2_7_Handler, /* 112: GPIO2 Pin 7 Handler */
+ GPIO2_8_Handler, /* 113: GPIO2 Pin 8 Handler */
+ GPIO2_9_Handler, /* 114: GPIO2 Pin 9 Handler */
+ GPIO2_10_Handler, /* 115: GPIO2 Pin 10 Handler */
+ GPIO2_11_Handler, /* 116: GPIO2 Pin 11 Handler */
+ GPIO2_12_Handler, /* 117: GPIO2 Pin 12 Handler */
+ GPIO2_13_Handler, /* 118: GPIO2 Pin 13 Handler */
+ GPIO2_14_Handler, /* 119: GPIO2 Pin 14 Handler */
+ GPIO2_15_Handler, /* 120: GPIO2 Pin 15 Handler */
+ GPIO3_0_Handler, /* 121: GPIO3 Pin 0 Handler */
+ GPIO3_1_Handler, /* 122: GPIO3 Pin 1 Handler */
+ GPIO3_2_Handler, /* 123: GPIO3 Pin 2 Handler */
+ GPIO3_3_Handler, /* 124: GPIO3 Pin 3 Handler */
+ UARTRX5_Handler, /* 125: UART 5 RX Interrupt */
+ UARTTX5_Handler, /* 126: UART 5 TX Interrupt */
+ UART5_Handler, /* 127: UART 5 combined Interrupt */
+ 0, /* 128: Reserved */
+ 0, /* 129: Reserved */
+ 0, /* 130: Reserved */
+#ifdef CORSTONE300_FVP
+ 0, /* 131: Reserved */
+ 0, /* 132: Reserved */
+ 0, /* 133: Reserved */
+ 0, /* 134: Reserved */
+ 0, /* 135: Reserved */
+ 0, /* 136: Reserved */
+ 0, /* 137: Reserved */
+ 0, /* 138: Reserved */
+ 0, /* 139: Reserved */
+ 0, /* 140: Reserved */
+ 0, /* 141: Reserved */
+ 0, /* 142: Reserved */
+ 0, /* 143: Reserved */
+ 0, /* 144: Reserved */
+ 0, /* 145: Reserved */
+ 0, /* 146: Reserved */
+ 0, /* 147: Reserved */
+ 0, /* 148: Reserved */
+ 0, /* 149: Reserved */
+ 0, /* 150: Reserved */
+ 0, /* 151: Reserved */
+ 0, /* 152: Reserved */
+ 0, /* 153: Reserved */
+ 0, /* 154: Reserved */
+ 0, /* 155: Reserved */
+ 0, /* 156: Reserved */
+ 0, /* 157: Reserved */
+ 0, /* 158: Reserved */
+ 0, /* 159: Reserved */
+ 0, /* 160: Reserved */
+ 0, /* 161: Reserved */
+ 0, /* 162: Reserved */
+ 0, /* 163: Reserved */
+ 0, /* 164: Reserved */
+ 0, /* 165: Reserved */
+ 0, /* 166: Reserved */
+ 0, /* 167: Reserved */
+ 0, /* 168: Reserved */
+ 0, /* 169: Reserved */
+ 0, /* 170: Reserved */
+ 0, /* 171: Reserved */
+ 0, /* 172: Reserved */
+ 0, /* 173: Reserved */
+ 0, /* 174: Reserved */
+ 0, /* 175: Reserved */
+ 0, /* 176: Reserved */
+ 0, /* 177: Reserved */
+ 0, /* 178: Reserved */
+ 0, /* 179: Reserved */
+ 0, /* 180: Reserved */
+ 0, /* 181: Reserved */
+ 0, /* 182: Reserved */
+ 0, /* 183: Reserved */
+ 0, /* 184: Reserved */
+ 0, /* 185: Reserved */
+ 0, /* 186: Reserved */
+ 0, /* 187: Reserved */
+ 0, /* 188: Reserved */
+ 0, /* 189: Reserved */
+ 0, /* 190: Reserved */
+ 0, /* 191: Reserved */
+ 0, /* 192: Reserved */
+ 0, /* 193: Reserved */
+ 0, /* 194: Reserved */
+ 0, /* 195: Reserved */
+ 0, /* 196: Reserved */
+ 0, /* 197: Reserved */
+ 0, /* 198: Reserved */
+ 0, /* 199: Reserved */
+ 0, /* 200: Reserved */
+ 0, /* 201: Reserved */
+ 0, /* 202: Reserved */
+ 0, /* 203: Reserved */
+ 0, /* 204: Reserved */
+ 0, /* 205: Reserved */
+ 0, /* 206: Reserved */
+ 0, /* 207: Reserved */
+ 0, /* 208: Reserved */
+ 0, /* 209: Reserved */
+ 0, /* 210: Reserved */
+ 0, /* 211: Reserved */
+ 0, /* 212: Reserved */
+ 0, /* 213: Reserved */
+ 0, /* 214: Reserved */
+ 0, /* 215: Reserved */
+ 0, /* 216: Reserved */
+ 0, /* 217: Reserved */
+ 0, /* 218: Reserved */
+ 0, /* 219: Reserved */
+ 0, /* 220: Reserved */
+ 0, /* 221: Reserved */
+ 0, /* 222: Reserved */
+ 0, /* 223: Reserved */
+ ARM_VSI0_Handler, /* 224: VSI 0 Handler */
+ ARM_VSI1_Handler, /* 225: VSI 1 Handler */
+ ARM_VSI2_Handler, /* 226: VSI 2 Handler */
+ ARM_VSI3_Handler, /* 227: VSI 3 Handler */
+ ARM_VSI4_Handler, /* 228: VSI 4 Handler */
+ ARM_VSI5_Handler, /* 229: VSI 5 Handler */
+ ARM_VSI6_Handler, /* 230: VSI 6 Handler */
+ ARM_VSI7_Handler, /* 231: VSI 7 Handler */
+#endif
+};
+
+#if defined ( __GNUC__ )
+#pragma GCC diagnostic pop
+#endif
+
+/*----------------------------------------------------------------------------
+ Reset Handler called on controller reset
+ *----------------------------------------------------------------------------*/
+void Reset_Handler(void)
+{
+ __set_PSP((uint32_t)(&__INITIAL_SP));
+
+ __set_MSPLIM((uint32_t)(&__STACK_LIMIT));
+ __set_PSPLIM((uint32_t)(&__STACK_LIMIT));
+
+#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
+ __TZ_set_STACKSEAL_S((uint32_t *)(&__STACK_SEAL));
+#endif
+
+ SystemInit(); /* CMSIS System Initialization */
+ __PROGRAM_START(); /* Enter PreMain (C library entry point) */
+}
diff --git a/board/Corstone-300/RTE/Device/SSE-300-MPS3/startup_SSE300MPS3.c.base@1.1.1 b/board/Corstone-300/RTE/Device/SSE-300-MPS3/startup_SSE300MPS3.c.base@1.1.1
new file mode 100644
index 0000000..b29bff1
--- /dev/null
+++ b/board/Corstone-300/RTE/Device/SSE-300-MPS3/startup_SSE300MPS3.c.base@1.1.1
@@ -0,0 +1,487 @@
+/*
+ * Copyright (c) 2022-2023 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.
+ */
+
+/*
+ * This file is derivative of CMSIS V5.9.0 startup_ARMCM55.c
+ * Git SHA: 2b7495b8535bdcb306dac29b9ded4cfb679d7e5c
+ */
+
+#include "SSE300MPS3.h"
+
+/*----------------------------------------------------------------------------
+ External References
+ *----------------------------------------------------------------------------*/
+extern uint32_t __INITIAL_SP;
+extern uint32_t __STACK_LIMIT;
+#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
+extern uint64_t __STACK_SEAL;
+#endif
+
+extern __NO_RETURN void __PROGRAM_START(void);
+
+/*----------------------------------------------------------------------------
+ Internal References
+ *----------------------------------------------------------------------------*/
+void __NO_RETURN Reset_Handler (void);
+
+/*----------------------------------------------------------------------------
+ Exception / Interrupt Handler
+ *----------------------------------------------------------------------------*/
+#define DEFAULT_IRQ_HANDLER(handler_name) \
+void __NO_RETURN __WEAK handler_name(void); \
+void handler_name(void) { \
+ while(1); \
+}
+
+/* Exceptions */
+DEFAULT_IRQ_HANDLER(NMI_Handler)
+DEFAULT_IRQ_HANDLER(HardFault_Handler)
+DEFAULT_IRQ_HANDLER(MemManage_Handler)
+DEFAULT_IRQ_HANDLER(BusFault_Handler)
+DEFAULT_IRQ_HANDLER(UsageFault_Handler)
+DEFAULT_IRQ_HANDLER(SecureFault_Handler)
+DEFAULT_IRQ_HANDLER(SVC_Handler)
+DEFAULT_IRQ_HANDLER(DebugMon_Handler)
+DEFAULT_IRQ_HANDLER(PendSV_Handler)
+DEFAULT_IRQ_HANDLER(SysTick_Handler)
+
+DEFAULT_IRQ_HANDLER(NONSEC_WATCHDOG_RESET_REQ_Handler)
+DEFAULT_IRQ_HANDLER(NONSEC_WATCHDOG_Handler)
+DEFAULT_IRQ_HANDLER(SLOWCLK_Timer_Handler)
+DEFAULT_IRQ_HANDLER(TFM_TIMER0_IRQ_Handler)
+DEFAULT_IRQ_HANDLER(TIMER1_Handler)
+DEFAULT_IRQ_HANDLER(TIMER2_Handler)
+DEFAULT_IRQ_HANDLER(MPC_Handler)
+DEFAULT_IRQ_HANDLER(PPC_Handler)
+DEFAULT_IRQ_HANDLER(MSC_Handler)
+DEFAULT_IRQ_HANDLER(BRIDGE_ERROR_Handler)
+DEFAULT_IRQ_HANDLER(MGMT_PPU_Handler)
+DEFAULT_IRQ_HANDLER(SYS_PPU_Handler)
+DEFAULT_IRQ_HANDLER(CPU0_PPU_Handler)
+DEFAULT_IRQ_HANDLER(DEBUG_PPU_Handler)
+DEFAULT_IRQ_HANDLER(TIMER3_AON_Handler)
+DEFAULT_IRQ_HANDLER(CPU0_CTI_0_Handler)
+DEFAULT_IRQ_HANDLER(CPU0_CTI_1_Handler)
+
+DEFAULT_IRQ_HANDLER(System_Timestamp_Counter_Handler)
+DEFAULT_IRQ_HANDLER(UARTRX0_Handler)
+DEFAULT_IRQ_HANDLER(UARTTX0_Handler)
+DEFAULT_IRQ_HANDLER(UARTRX1_Handler)
+DEFAULT_IRQ_HANDLER(UARTTX1_Handler)
+DEFAULT_IRQ_HANDLER(UARTRX2_Handler)
+DEFAULT_IRQ_HANDLER(UARTTX2_Handler)
+DEFAULT_IRQ_HANDLER(UARTRX3_Handler)
+DEFAULT_IRQ_HANDLER(UARTTX3_Handler)
+DEFAULT_IRQ_HANDLER(UARTRX4_Handler)
+DEFAULT_IRQ_HANDLER(UARTTX4_Handler)
+DEFAULT_IRQ_HANDLER(UART0_Combined_Handler)
+DEFAULT_IRQ_HANDLER(UART1_Combined_Handler)
+DEFAULT_IRQ_HANDLER(UART2_Combined_Handler)
+DEFAULT_IRQ_HANDLER(UART3_Combined_Handler)
+DEFAULT_IRQ_HANDLER(UART4_Combined_Handler)
+DEFAULT_IRQ_HANDLER(UARTOVF_Handler)
+DEFAULT_IRQ_HANDLER(ETHERNET_Handler)
+DEFAULT_IRQ_HANDLER(I2S_Handler)
+DEFAULT_IRQ_HANDLER(TOUCH_SCREEN_Handler)
+DEFAULT_IRQ_HANDLER(USB_Handler)
+DEFAULT_IRQ_HANDLER(SPI_ADC_Handler)
+DEFAULT_IRQ_HANDLER(SPI_SHIELD0_Handler)
+DEFAULT_IRQ_HANDLER(SPI_SHIELD1_Handler)
+DEFAULT_IRQ_HANDLER(ETHOS_U55_Handler)
+#ifdef CORSTONE300_AN547
+DEFAULT_IRQ_HANDLER(DMA_Ch_1_Error_Handler)
+DEFAULT_IRQ_HANDLER(DMA_Ch_1_Terminal_Count_Handler)
+DEFAULT_IRQ_HANDLER(DMA_Ch_1_Combined_Handler)
+DEFAULT_IRQ_HANDLER(DMA_Ch_2_Error_Handler)
+DEFAULT_IRQ_HANDLER(DMA_Ch_2_Terminal_Count_Handler)
+DEFAULT_IRQ_HANDLER(DMA_Ch_2_Combined_Handler)
+DEFAULT_IRQ_HANDLER(DMA_Ch_3_Error_Handler)
+DEFAULT_IRQ_HANDLER(DMA_Ch_3_Terminal_Count_Handler)
+DEFAULT_IRQ_HANDLER(DMA_Ch_3_Combined_Handler)
+#endif
+DEFAULT_IRQ_HANDLER(GPIO0_Combined_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_Combined_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_Combined_Handler)
+DEFAULT_IRQ_HANDLER(GPIO3_Combined_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_0_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_1_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_2_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_3_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_4_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_5_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_6_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_7_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_8_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_9_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_10_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_11_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_12_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_13_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_14_Handler)
+DEFAULT_IRQ_HANDLER(GPIO0_15_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_0_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_1_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_2_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_3_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_4_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_5_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_6_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_7_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_8_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_9_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_10_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_11_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_12_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_13_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_14_Handler)
+DEFAULT_IRQ_HANDLER(GPIO1_15_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_0_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_1_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_2_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_3_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_4_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_5_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_6_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_7_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_8_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_9_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_10_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_11_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_12_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_13_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_14_Handler)
+DEFAULT_IRQ_HANDLER(GPIO2_15_Handler)
+DEFAULT_IRQ_HANDLER(GPIO3_0_Handler)
+DEFAULT_IRQ_HANDLER(GPIO3_1_Handler)
+DEFAULT_IRQ_HANDLER(GPIO3_2_Handler)
+DEFAULT_IRQ_HANDLER(GPIO3_3_Handler)
+DEFAULT_IRQ_HANDLER(UARTRX5_Handler)
+DEFAULT_IRQ_HANDLER(UARTTX5_Handler)
+DEFAULT_IRQ_HANDLER(UART5_Handler)
+#ifdef CORSTONE300_FVP
+DEFAULT_IRQ_HANDLER(ARM_VSI0_Handler)
+DEFAULT_IRQ_HANDLER(ARM_VSI1_Handler)
+DEFAULT_IRQ_HANDLER(ARM_VSI2_Handler)
+DEFAULT_IRQ_HANDLER(ARM_VSI3_Handler)
+DEFAULT_IRQ_HANDLER(ARM_VSI4_Handler)
+DEFAULT_IRQ_HANDLER(ARM_VSI5_Handler)
+DEFAULT_IRQ_HANDLER(ARM_VSI6_Handler)
+DEFAULT_IRQ_HANDLER(ARM_VSI7_Handler)
+#endif
+/*----------------------------------------------------------------------------
+ Exception / Interrupt Vector table
+ *----------------------------------------------------------------------------*/
+
+#if defined ( __GNUC__ )
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpedantic"
+#endif
+
+extern const VECTOR_TABLE_Type __VECTOR_TABLE[];
+ const VECTOR_TABLE_Type __VECTOR_TABLE[] __VECTOR_TABLE_ATTRIBUTE = {
+ (VECTOR_TABLE_Type)(&__INITIAL_SP), /* Initial Stack Pointer */
+ Reset_Handler, /* Reset Handler */
+ NMI_Handler, /* -14: NMI Handler */
+ HardFault_Handler, /* -13: Hard Fault Handler */
+ MemManage_Handler, /* -12: MPU Fault Handler */
+ BusFault_Handler, /* -11: Bus Fault Handler */
+ UsageFault_Handler, /* -10: Usage Fault Handler */
+ SecureFault_Handler, /* -9: Secure Fault Handler */
+ 0, /* Reserved */
+ 0, /* Reserved */
+ 0, /* Reserved */
+ SVC_Handler, /* -5: SVCall Handler */
+ DebugMon_Handler, /* -4: Debug Monitor Handler */
+ 0, /* Reserved */
+ PendSV_Handler, /* -2: PendSV Handler */
+ SysTick_Handler, /* -1: SysTick Handler */
+
+ NONSEC_WATCHDOG_RESET_REQ_Handler, /* 0: Non-Secure Watchdog Reset Request Handler */
+ NONSEC_WATCHDOG_Handler, /* 1: Non-Secure Watchdog Handler */
+ SLOWCLK_Timer_Handler, /* 2: SLOWCLK Timer Handler */
+ TFM_TIMER0_IRQ_Handler, /* 3: TIMER 0 Handler */
+ TIMER1_Handler, /* 4: TIMER 1 Handler */
+ TIMER2_Handler, /* 5: TIMER 2 Handler */
+ 0, /* 6: Reserved */
+ 0, /* 7: Reserved */
+ 0, /* 8: Reserved */
+ MPC_Handler, /* 9: MPC Combined (Secure) Handler */
+ PPC_Handler, /* 10: PPC Combined (Secure) Handler */
+ MSC_Handler, /* 11: MSC Combined (Secure) Handler */
+ BRIDGE_ERROR_Handler, /* 12: Bridge Error (Secure) Handler */
+ 0, /* 13: Reserved */
+ MGMT_PPU_Handler, /* 14: MGMT PPU Handler */
+ SYS_PPU_Handler, /* 15: SYS PPU Handler */
+ CPU0_PPU_Handler, /* 16: CPU0 PPU Handler */
+ 0, /* 17: Reserved */
+ 0, /* 18: Reserved */
+ 0, /* 19: Reserved */
+ 0, /* 20: Reserved */
+ 0, /* 21: Reserved */
+ 0, /* 22: Reserved */
+ 0, /* 23: Reserved */
+ 0, /* 24: Reserved */
+ 0, /* 25: Reserved */
+ DEBUG_PPU_Handler, /* 26: DEBUG PPU Handler */
+ TIMER3_AON_Handler, /* 27: TIMER 3 AON Handler */
+ CPU0_CTI_0_Handler, /* 28: CPU0 CTI IRQ 0 Handler */
+ CPU0_CTI_1_Handler, /* 29: CPU0 CTI IRQ 1 Handler */
+ 0, /* 30: Reserved */
+ 0, /* 31: Reserved */
+
+ /* External interrupts */
+ System_Timestamp_Counter_Handler, /* 32: System timestamp counter Handler */
+ UARTRX0_Handler, /* 33: UART 0 RX Handler */
+ UARTTX0_Handler, /* 34: UART 0 TX Handler */
+ UARTRX1_Handler, /* 35: UART 1 RX Handler */
+ UARTTX1_Handler, /* 36: UART 1 TX Handler */
+ UARTRX2_Handler, /* 37: UART 2 RX Handler */
+ UARTTX2_Handler, /* 38: UART 2 TX Handler */
+ UARTRX3_Handler, /* 39: UART 3 RX Handler */
+ UARTTX3_Handler, /* 40: UART 3 TX Handler */
+ UARTRX4_Handler, /* 41: UART 4 RX Handler */
+ UARTTX4_Handler, /* 42: UART 4 TX Handler */
+ UART0_Combined_Handler, /* 43: UART 0 Combined Handler */
+ UART1_Combined_Handler, /* 44: UART 1 Combined Handler */
+ UART2_Combined_Handler, /* 45: UART 2 Combined Handler */
+ UART3_Combined_Handler, /* 46: UART 3 Combined Handler */
+ UART4_Combined_Handler, /* 47: UART 4 Combined Handler */
+ UARTOVF_Handler, /* 48: UART 0, 1, 2, 3, 4 & 5 Overflow Handler */
+ ETHERNET_Handler, /* 49: Ethernet Handler */
+ I2S_Handler, /* 50: Audio I2S Handler */
+ TOUCH_SCREEN_Handler, /* 51: Touch Screen Handler */
+ USB_Handler, /* 52: USB Handler */
+ SPI_ADC_Handler, /* 53: SPI ADC Handler */
+ SPI_SHIELD0_Handler, /* 54: SPI (Shield 0) Handler */
+ SPI_SHIELD1_Handler, /* 55: SPI (Shield 0) Handler */
+ ETHOS_U55_Handler, /* 56: Ethos-U55 Handler */
+#ifdef CORSTONE300_AN547
+ 0, /* 57: Reserved */
+ 0, /* 58: Reserved */
+ 0, /* 59: Reserved */
+ DMA_Ch_1_Error_Handler, /* 60: DMA Ch1 Error Handler */
+ DMA_Ch_1_Terminal_Count_Handler, /* 61: DMA Ch1 Terminal Count Handler */
+ DMA_Ch_1_Combined_Handler, /* 62: DMA Ch1 Combined Handler */
+ DMA_Ch_2_Error_Handler, /* 63: DMA Ch2 Error Handler */
+ DMA_Ch_2_Terminal_Count_Handler, /* 64: DMA Ch2 Terminal Count Handler */
+ DMA_Ch_2_Combined_Handler, /* 65: DMA Ch2 Combined Handler */
+ DMA_Ch_3_Error_Handler, /* 66: DMA Ch3 Error Handler */
+ DMA_Ch_3_Terminal_Count_Handler, /* 67: DMA Ch3 Terminal Count Handler */
+ DMA_Ch_3_Combined_Handler, /* 68: DMA Ch3 Combined Handler */
+#else
+ 0, /* 57: Reserved */
+ 0, /* 58: Reserved */
+ 0, /* 59: Reserved */
+ 0, /* 60: Reserved */
+ 0, /* 61: Reserved */
+ 0, /* 62: Reserved */
+ 0, /* 63: Reserved */
+ 0, /* 64: Reserved */
+ 0, /* 65: Reserved */
+ 0, /* 66: Reserved */
+ 0, /* 67: Reserved */
+ 0, /* 68: Reserved */
+#endif
+ GPIO0_Combined_Handler, /* 69: GPIO 0 Combined Handler */
+ GPIO1_Combined_Handler, /* 70: GPIO 1 Combined Handler */
+ GPIO2_Combined_Handler, /* 71: GPIO 2 Combined Handler */
+ GPIO3_Combined_Handler, /* 72: GPIO 3 Combined Handler */
+ GPIO0_0_Handler, /* 73: GPIO0 Pin 0 Handler */
+ GPIO0_1_Handler, /* 74: GPIO0 Pin 1 Handler */
+ GPIO0_2_Handler, /* 75: GPIO0 Pin 2 Handler */
+ GPIO0_3_Handler, /* 76: GPIO0 Pin 3 Handler */
+ GPIO0_4_Handler, /* 77: GPIO0 Pin 4 Handler */
+ GPIO0_5_Handler, /* 78: GPIO0 Pin 5 Handler */
+ GPIO0_6_Handler, /* 79: GPIO0 Pin 6 Handler */
+ GPIO0_7_Handler, /* 80: GPIO0 Pin 7 Handler */
+ GPIO0_8_Handler, /* 81: GPIO0 Pin 8 Handler */
+ GPIO0_9_Handler, /* 82: GPIO0 Pin 9 Handler */
+ GPIO0_10_Handler, /* 83: GPIO0 Pin 10 Handler */
+ GPIO0_11_Handler, /* 84: GPIO0 Pin 11 Handler */
+ GPIO0_12_Handler, /* 85: GPIO0 Pin 12 Handler */
+ GPIO0_13_Handler, /* 86: GPIO0 Pin 13 Handler */
+ GPIO0_14_Handler, /* 87: GPIO0 Pin 14 Handler */
+ GPIO0_15_Handler, /* 88: GPIO0 Pin 15 Handler */
+ GPIO1_0_Handler, /* 89: GPIO1 Pin 0 Handler */
+ GPIO1_1_Handler, /* 90: GPIO1 Pin 1 Handler */
+ GPIO1_2_Handler, /* 91: GPIO1 Pin 2 Handler */
+ GPIO1_3_Handler, /* 92: GPIO1 Pin 3 Handler */
+ GPIO1_4_Handler, /* 93: GPIO1 Pin 4 Handler */
+ GPIO1_5_Handler, /* 94: GPIO1 Pin 5 Handler */
+ GPIO1_6_Handler, /* 95: GPIO1 Pin 6 Handler */
+ GPIO1_7_Handler, /* 96: GPIO1 Pin 7 Handler */
+ GPIO1_8_Handler, /* 97: GPIO1 Pin 8 Handler */
+ GPIO1_9_Handler, /* 98: GPIO1 Pin 9 Handler */
+ GPIO1_10_Handler, /* 99: GPIO1 Pin 10 Handler */
+ GPIO1_11_Handler, /* 100: GPIO1 Pin 11 Handler */
+ GPIO1_12_Handler, /* 101: GPIO1 Pin 12 Handler */
+ GPIO1_13_Handler, /* 102: GPIO1 Pin 13 Handler */
+ GPIO1_14_Handler, /* 103: GPIO1 Pin 14 Handler */
+ GPIO1_15_Handler, /* 104: GPIO1 Pin 15 Handler */
+ GPIO2_0_Handler, /* 105: GPIO2 Pin 0 Handler */
+ GPIO2_1_Handler, /* 106: GPIO2 Pin 1 Handler */
+ GPIO2_2_Handler, /* 107: GPIO2 Pin 2 Handler */
+ GPIO2_3_Handler, /* 108: GPIO2 Pin 3 Handler */
+ GPIO2_4_Handler, /* 109: GPIO2 Pin 4 Handler */
+ GPIO2_5_Handler, /* 110: GPIO2 Pin 5 Handler */
+ GPIO2_6_Handler, /* 111: GPIO2 Pin 6 Handler */
+ GPIO2_7_Handler, /* 112: GPIO2 Pin 7 Handler */
+ GPIO2_8_Handler, /* 113: GPIO2 Pin 8 Handler */
+ GPIO2_9_Handler, /* 114: GPIO2 Pin 9 Handler */
+ GPIO2_10_Handler, /* 115: GPIO2 Pin 10 Handler */
+ GPIO2_11_Handler, /* 116: GPIO2 Pin 11 Handler */
+ GPIO2_12_Handler, /* 117: GPIO2 Pin 12 Handler */
+ GPIO2_13_Handler, /* 118: GPIO2 Pin 13 Handler */
+ GPIO2_14_Handler, /* 119: GPIO2 Pin 14 Handler */
+ GPIO2_15_Handler, /* 120: GPIO2 Pin 15 Handler */
+ GPIO3_0_Handler, /* 121: GPIO3 Pin 0 Handler */
+ GPIO3_1_Handler, /* 122: GPIO3 Pin 1 Handler */
+ GPIO3_2_Handler, /* 123: GPIO3 Pin 2 Handler */
+ GPIO3_3_Handler, /* 124: GPIO3 Pin 3 Handler */
+ UARTRX5_Handler, /* 125: UART 5 RX Interrupt */
+ UARTTX5_Handler, /* 126: UART 5 TX Interrupt */
+ UART5_Handler, /* 127: UART 5 combined Interrupt */
+ 0, /* 128: Reserved */
+ 0, /* 129: Reserved */
+ 0, /* 130: Reserved */
+#ifdef CORSTONE300_FVP
+ 0, /* 131: Reserved */
+ 0, /* 132: Reserved */
+ 0, /* 133: Reserved */
+ 0, /* 134: Reserved */
+ 0, /* 135: Reserved */
+ 0, /* 136: Reserved */
+ 0, /* 137: Reserved */
+ 0, /* 138: Reserved */
+ 0, /* 139: Reserved */
+ 0, /* 140: Reserved */
+ 0, /* 141: Reserved */
+ 0, /* 142: Reserved */
+ 0, /* 143: Reserved */
+ 0, /* 144: Reserved */
+ 0, /* 145: Reserved */
+ 0, /* 146: Reserved */
+ 0, /* 147: Reserved */
+ 0, /* 148: Reserved */
+ 0, /* 149: Reserved */
+ 0, /* 150: Reserved */
+ 0, /* 151: Reserved */
+ 0, /* 152: Reserved */
+ 0, /* 153: Reserved */
+ 0, /* 154: Reserved */
+ 0, /* 155: Reserved */
+ 0, /* 156: Reserved */
+ 0, /* 157: Reserved */
+ 0, /* 158: Reserved */
+ 0, /* 159: Reserved */
+ 0, /* 160: Reserved */
+ 0, /* 161: Reserved */
+ 0, /* 162: Reserved */
+ 0, /* 163: Reserved */
+ 0, /* 164: Reserved */
+ 0, /* 165: Reserved */
+ 0, /* 166: Reserved */
+ 0, /* 167: Reserved */
+ 0, /* 168: Reserved */
+ 0, /* 169: Reserved */
+ 0, /* 170: Reserved */
+ 0, /* 171: Reserved */
+ 0, /* 172: Reserved */
+ 0, /* 173: Reserved */
+ 0, /* 174: Reserved */
+ 0, /* 175: Reserved */
+ 0, /* 176: Reserved */
+ 0, /* 177: Reserved */
+ 0, /* 178: Reserved */
+ 0, /* 179: Reserved */
+ 0, /* 180: Reserved */
+ 0, /* 181: Reserved */
+ 0, /* 182: Reserved */
+ 0, /* 183: Reserved */
+ 0, /* 184: Reserved */
+ 0, /* 185: Reserved */
+ 0, /* 186: Reserved */
+ 0, /* 187: Reserved */
+ 0, /* 188: Reserved */
+ 0, /* 189: Reserved */
+ 0, /* 190: Reserved */
+ 0, /* 191: Reserved */
+ 0, /* 192: Reserved */
+ 0, /* 193: Reserved */
+ 0, /* 194: Reserved */
+ 0, /* 195: Reserved */
+ 0, /* 196: Reserved */
+ 0, /* 197: Reserved */
+ 0, /* 198: Reserved */
+ 0, /* 199: Reserved */
+ 0, /* 200: Reserved */
+ 0, /* 201: Reserved */
+ 0, /* 202: Reserved */
+ 0, /* 203: Reserved */
+ 0, /* 204: Reserved */
+ 0, /* 205: Reserved */
+ 0, /* 206: Reserved */
+ 0, /* 207: Reserved */
+ 0, /* 208: Reserved */
+ 0, /* 209: Reserved */
+ 0, /* 210: Reserved */
+ 0, /* 211: Reserved */
+ 0, /* 212: Reserved */
+ 0, /* 213: Reserved */
+ 0, /* 214: Reserved */
+ 0, /* 215: Reserved */
+ 0, /* 216: Reserved */
+ 0, /* 217: Reserved */
+ 0, /* 218: Reserved */
+ 0, /* 219: Reserved */
+ 0, /* 220: Reserved */
+ 0, /* 221: Reserved */
+ 0, /* 222: Reserved */
+ 0, /* 223: Reserved */
+ ARM_VSI0_Handler, /* 224: VSI 0 Handler */
+ ARM_VSI1_Handler, /* 225: VSI 1 Handler */
+ ARM_VSI2_Handler, /* 226: VSI 2 Handler */
+ ARM_VSI3_Handler, /* 227: VSI 3 Handler */
+ ARM_VSI4_Handler, /* 228: VSI 4 Handler */
+ ARM_VSI5_Handler, /* 229: VSI 5 Handler */
+ ARM_VSI6_Handler, /* 230: VSI 6 Handler */
+ ARM_VSI7_Handler, /* 231: VSI 7 Handler */
+#endif
+};
+
+#if defined ( __GNUC__ )
+#pragma GCC diagnostic pop
+#endif
+
+/*----------------------------------------------------------------------------
+ Reset Handler called on controller reset
+ *----------------------------------------------------------------------------*/
+void Reset_Handler(void)
+{
+ __set_PSP((uint32_t)(&__INITIAL_SP));
+
+ __set_MSPLIM((uint32_t)(&__STACK_LIMIT));
+ __set_PSPLIM((uint32_t)(&__STACK_LIMIT));
+
+#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
+ __TZ_set_STACKSEAL_S((uint32_t *)(&__STACK_SEAL));
+#endif
+
+ SystemInit(); /* CMSIS System Initialization */
+ __PROGRAM_START(); /* Enter PreMain (C library entry point) */
+}
diff --git a/board/Corstone-300/RTE/Device/SSE-300-MPS3/system_SSE300MPS3.c b/board/Corstone-300/RTE/Device/SSE-300-MPS3/system_SSE300MPS3.c
new file mode 100644
index 0000000..20b624e
--- /dev/null
+++ b/board/Corstone-300/RTE/Device/SSE-300-MPS3/system_SSE300MPS3.c
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2009-2023 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.
+ */
+
+/*
+ * This file is derivative of CMSIS V5.9.0 system_ARMCM55.c
+ * Git SHA: 2b7495b8535bdcb306dac29b9ded4cfb679d7e5c
+ */
+
+#include "SSE300MPS3.h"
+
+/*----------------------------------------------------------------------------
+ Define clocks
+ *----------------------------------------------------------------------------*/
+ #define XTAL (32000000UL)
+ #define SYSTEM_CLOCK (XTAL)
+ #define PERIPHERAL_CLOCK (25000000UL)
+
+/*----------------------------------------------------------------------------
+ Exception / Interrupt Vector table
+ *----------------------------------------------------------------------------*/
+extern const VECTOR_TABLE_Type __VECTOR_TABLE[496];
+
+/*----------------------------------------------------------------------------
+ System Core Clock Variable
+ *----------------------------------------------------------------------------*/
+uint32_t SystemCoreClock = SYSTEM_CLOCK;
+uint32_t PeripheralClock = PERIPHERAL_CLOCK;
+
+/*----------------------------------------------------------------------------
+ System Core Clock update function
+ *----------------------------------------------------------------------------*/
+void SystemCoreClockUpdate (void)
+{
+ SystemCoreClock = SYSTEM_CLOCK;
+ PeripheralClock = PERIPHERAL_CLOCK;
+}
+
+/*----------------------------------------------------------------------------
+ System initialization function
+ *----------------------------------------------------------------------------*/
+void SystemInit (void)
+{
+#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U)
+ SCB->VTOR = (uint32_t)(&__VECTOR_TABLE[0]);
+#endif
+
+#if (defined (__FPU_USED) && (__FPU_USED == 1U)) || \
+ (defined (__ARM_FEATURE_MVE) && (__ARM_FEATURE_MVE > 0U))
+ SCB->CPACR |= ((3U << 10U*2U) | /* enable CP10 Full Access */
+ (3U << 11U*2U) ); /* enable CP11 Full Access */
+
+ /* Set low-power state for PDEPU */
+ /* 0b00 | ON, PDEPU is not in low-power state */
+ /* 0b01 | ON, but the clock is off */
+ /* 0b10 | RET(ention) */
+ /* 0b11 | OFF */
+
+ /* Clear ELPSTATE, value is 0b11 on Cold reset */
+ PWRMODCTL->CPDLPSTATE &= ~(PWRMODCTL_CPDLPSTATE_ELPSTATE_Msk);
+
+ /* Favor best FP/MVE performance by default, avoid EPU switch-ON delays */
+ /* PDEPU ON, Clock OFF */
+ PWRMODCTL->CPDLPSTATE |= 0x1 << PWRMODCTL_CPDLPSTATE_ELPSTATE_Pos;
+#endif
+
+#ifdef UNALIGNED_SUPPORT_DISABLE
+ SCB->CCR |= SCB_CCR_UNALIGN_TRP_Msk;
+#endif
+
+ /* Enable Loop and branch info cache */
+ SCB->CCR |= SCB_CCR_LOB_Msk;
+ __DSB();
+ __ISB();
+
+ /* Disable cache, because of BL2->Secure change.
+ If cache is enabled, then code decompression can fail or cause uncertain
+ behaviour after switching to main.
+ If cache needed to be Enabled before decompression, make sure to Clean
+ and Invalidate it at the begining of main(..)!
+
+ If so, use:
+ SCB_InvalidateICache(); // I cache cannot be cleaned
+ SCB_CleanInvalidateDCache();
+ */
+ SCB_DisableICache();
+ SCB_DisableDCache();
+
+ SystemCoreClock = SYSTEM_CLOCK;
+ PeripheralClock = PERIPHERAL_CLOCK;
+}
diff --git a/board/Corstone-300/RTE/Device/SSE-300-MPS3/system_SSE300MPS3.c.base@1.1.1 b/board/Corstone-300/RTE/Device/SSE-300-MPS3/system_SSE300MPS3.c.base@1.1.1
new file mode 100644
index 0000000..20b624e
--- /dev/null
+++ b/board/Corstone-300/RTE/Device/SSE-300-MPS3/system_SSE300MPS3.c.base@1.1.1
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2009-2023 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.
+ */
+
+/*
+ * This file is derivative of CMSIS V5.9.0 system_ARMCM55.c
+ * Git SHA: 2b7495b8535bdcb306dac29b9ded4cfb679d7e5c
+ */
+
+#include "SSE300MPS3.h"
+
+/*----------------------------------------------------------------------------
+ Define clocks
+ *----------------------------------------------------------------------------*/
+ #define XTAL (32000000UL)
+ #define SYSTEM_CLOCK (XTAL)
+ #define PERIPHERAL_CLOCK (25000000UL)
+
+/*----------------------------------------------------------------------------
+ Exception / Interrupt Vector table
+ *----------------------------------------------------------------------------*/
+extern const VECTOR_TABLE_Type __VECTOR_TABLE[496];
+
+/*----------------------------------------------------------------------------
+ System Core Clock Variable
+ *----------------------------------------------------------------------------*/
+uint32_t SystemCoreClock = SYSTEM_CLOCK;
+uint32_t PeripheralClock = PERIPHERAL_CLOCK;
+
+/*----------------------------------------------------------------------------
+ System Core Clock update function
+ *----------------------------------------------------------------------------*/
+void SystemCoreClockUpdate (void)
+{
+ SystemCoreClock = SYSTEM_CLOCK;
+ PeripheralClock = PERIPHERAL_CLOCK;
+}
+
+/*----------------------------------------------------------------------------
+ System initialization function
+ *----------------------------------------------------------------------------*/
+void SystemInit (void)
+{
+#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U)
+ SCB->VTOR = (uint32_t)(&__VECTOR_TABLE[0]);
+#endif
+
+#if (defined (__FPU_USED) && (__FPU_USED == 1U)) || \
+ (defined (__ARM_FEATURE_MVE) && (__ARM_FEATURE_MVE > 0U))
+ SCB->CPACR |= ((3U << 10U*2U) | /* enable CP10 Full Access */
+ (3U << 11U*2U) ); /* enable CP11 Full Access */
+
+ /* Set low-power state for PDEPU */
+ /* 0b00 | ON, PDEPU is not in low-power state */
+ /* 0b01 | ON, but the clock is off */
+ /* 0b10 | RET(ention) */
+ /* 0b11 | OFF */
+
+ /* Clear ELPSTATE, value is 0b11 on Cold reset */
+ PWRMODCTL->CPDLPSTATE &= ~(PWRMODCTL_CPDLPSTATE_ELPSTATE_Msk);
+
+ /* Favor best FP/MVE performance by default, avoid EPU switch-ON delays */
+ /* PDEPU ON, Clock OFF */
+ PWRMODCTL->CPDLPSTATE |= 0x1 << PWRMODCTL_CPDLPSTATE_ELPSTATE_Pos;
+#endif
+
+#ifdef UNALIGNED_SUPPORT_DISABLE
+ SCB->CCR |= SCB_CCR_UNALIGN_TRP_Msk;
+#endif
+
+ /* Enable Loop and branch info cache */
+ SCB->CCR |= SCB_CCR_LOB_Msk;
+ __DSB();
+ __ISB();
+
+ /* Disable cache, because of BL2->Secure change.
+ If cache is enabled, then code decompression can fail or cause uncertain
+ behaviour after switching to main.
+ If cache needed to be Enabled before decompression, make sure to Clean
+ and Invalidate it at the begining of main(..)!
+
+ If so, use:
+ SCB_InvalidateICache(); // I cache cannot be cleaned
+ SCB_CleanInvalidateDCache();
+ */
+ SCB_DisableICache();
+ SCB_DisableDCache();
+
+ SystemCoreClock = SYSTEM_CLOCK;
+ PeripheralClock = PERIPHERAL_CLOCK;
+}
diff --git a/board/Corstone-300/ethos_setup.c b/board/Corstone-300/ethos_setup.c
new file mode 100644
index 0000000..f154c77
--- /dev/null
+++ b/board/Corstone-300/ethos_setup.c
@@ -0,0 +1,103 @@
+/*---------------------------------------------------------------------------
+ * Copyright (c) 2025 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
+
+#include "RTE_Components.h"
+#include CMSIS_device_header
+
+#include "ethosu_driver.h"
+#include "main.h"
+
+#if defined(ETHOSU65) || defined(ETHOSU85)
+/* Define Ethos-U NPU cache buffer size */
+#ifndef ETHOS_CACHE_BUF_SIZE
+#define ETHOS_CACHE_BUF_SIZE 393216
+#endif
+
+/* Define Ethos-U cache buffer alignment */
+#ifndef ETHOS_CACHE_BUF_ALIGNMENT
+#define ETHOS_CACHE_BUF_ALIGNMENT 32
+#endif
+
+/* Define Ethos-U NPU cache buffer attributes */
+#ifndef ETHOS_CACHE_BUF_ATTRIBUTES
+#define ETHOS_CACHE_BUF_ATTRIBUTES __attribute__((section("ethos_cache_buf"), aligned(ETHOS_CACHE_BUF_ALIGNMENT)))
+#endif
+#endif
+
+/* Define Ethos-U NPU security mode */
+#ifndef ETHOS_SECURE_ENABLE
+#define ETHOS_SECURE_ENABLE 1
+#endif
+
+/* Define Ethos-U NPU privilege mode */
+#ifndef ETHOS_PRIVILEGE_ENABLE
+#define ETHOS_PRIVILEGE_ENABLE 1
+#endif
+
+/* Ethos NPU driver instance. */
+static struct ethosu_driver EthosDriver;
+
+#if defined(ETHOSU65) || defined(ETHOSU85)
+static uint8_t ethos_cache[ETHOS_CACHE_BUF_SIZE] ETHOS_CACHE_BUF_ATTRIBUTES;
+#endif
+
+/*
+ Ethos NPU interrupt handler.
+*/
+void ETHOS_U55_Handler (void) {
+ ethosu_irq_handler(&EthosDriver);
+}
+
+/*
+ Initialize the Ethos NPU driver.
+*/
+void ethos_setup (void) {
+ void * const ethos_base_addr = (void *)ETHOS_U55_APB_BASE_S;
+ struct ethosu_hw_info hw_info;
+ int rval;
+
+ /* Initialize Ethos-U NPU driver. */
+ rval = ethosu_init(&EthosDriver, /* Ethos-U device driver */
+ ethos_base_addr, /* Ethos-U base address */
+ #if defined(ETHOSU65) || defined(ETHOSU85)
+ ethos_cache, /* Cache memory pointer */
+ sizeof(ethos_cache), /* Cache memory size */
+ #else
+ 0, /* Cache memory pointer */
+ 0, /* Cache memory size */
+ #endif
+ ETHOS_SECURE_ENABLE, /* Secure enable */
+ ETHOS_PRIVILEGE_ENABLE); /* Privileged mode */
+ if (rval != 0) {
+ printf("Failed to initialize Arm Ethos-U driver\n");
+ }
+ else {
+ NVIC_EnableIRQ(ETHOS_U55_IRQn);
+
+ ethosu_get_hw_info(&EthosDriver, &hw_info);
+
+ printf("Ethos-U version info:\n");
+ printf("\tArch: v%u.%u.%u\n", hw_info.version.arch_major_rev,
+ hw_info.version.arch_minor_rev,
+ hw_info.version.arch_patch_rev);
+ printf("\tMACs/cc: %u\n", (uint32_t)(1 << hw_info.cfg.macs_per_cc));
+ printf("\tCmd stream: v%u\n", hw_info.cfg.cmd_stream_version);
+ }
+}
diff --git a/board/Corstone-300/fvp_config.txt b/board/Corstone-300/fvp_config.txt
new file mode 100644
index 0000000..364e9b7
--- /dev/null
+++ b/board/Corstone-300/fvp_config.txt
@@ -0,0 +1,7 @@
+# Parameters:
+# instance.parameter=value #(type, mode) default = 'def value' : description : [min..max]
+#------------------------------------------------------------------------------
+ethosu.num_macs=128 # (int , init-time) default = '0x80' : Number of 8x8 MACs performed per cycle (32, 64, 128, or 256). : [0x20:0x100]
+mps3_board.uart0.shutdown_on_eot=1 # (bool , init-time) default = '0' : Shutdown simulation when a EOT (ASCII 4) char is transmitted (useful for regression tests when semihosting is not available)
+mps3_board.visualisation.disable-visualisation=1 # (bool , init-time) default = '0' : Enable/disable visualisation
+#------------------------------------------------------------------------------
diff --git a/board/Corstone-300/main.c b/board/Corstone-300/main.c
new file mode 100644
index 0000000..69b3485
--- /dev/null
+++ b/board/Corstone-300/main.c
@@ -0,0 +1,35 @@
+/*---------------------------------------------------------------------------
+ * Copyright (c) 2024 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 "RTE_Components.h"
+#include CMSIS_device_header
+
+#include "main.h"
+
+int main (void) {
+
+ /* Initialize STDIO */
+ stdio_init();
+
+ #if defined(ETHOSU_ARCH)
+ /* Initialize Ethos NPU */
+ ethos_setup();
+ #endif
+
+ return (app_main());
+}
diff --git a/board/Corstone-300/main.h b/board/Corstone-300/main.h
new file mode 100644
index 0000000..6e2048e
--- /dev/null
+++ b/board/Corstone-300/main.h
@@ -0,0 +1,38 @@
+/*---------------------------------------------------------------------------
+ * Copyright (c) 2020-2025 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 MAIN_H__
+#define MAIN_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Prototypes */
+extern int app_main (void);
+extern int stdio_init (void);
+
+#if defined(ETHOSU_ARCH)
+extern void ethos_setup (void);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/board/Corstone-300/regions_SSE-300.h b/board/Corstone-300/regions_SSE-300.h
new file mode 100644
index 0000000..c55a6aa
--- /dev/null
+++ b/board/Corstone-300/regions_SSE-300.h
@@ -0,0 +1,115 @@
+#ifndef REGIONS_SSE_300_H
+#define REGIONS_SSE_300_H
+
+#include "sse300_memmap_s.h"
+#include "sse300_memmap_ns.h"
+
+
+//-------- <<< Use Configuration Wizard in Context Menu >>> --------------------
+//------ With VS Code: Open Preview for Configuration Wizard -------------------
+
+// ROM Configuration
+// =======================
+// __ROM0
+// Base address
+// Defines base address of memory region.
+// Contains Startup and Vector Table
+// Default: ITCM_S_BASE
+#define __ROM0_BASE ITCM_S_BASE
+// Region size [bytes]
+// Defines size of memory region.
+// Default: ITCM_S_SIZE
+#define __ROM0_SIZE ITCM_S_SIZE
+//
+
+// __ROM1
+// Base address
+// Defines base address of memory region.
+// Default: FPGA_SRAM_S_BASE
+#define __ROM1_BASE FPGA_SRAM_S_BASE
+// Region size [bytes]
+// Defines size of memory region.
+// Default: FPGA_SRAM_S_SIZE
+#define __ROM1_SIZE FPGA_SRAM_S_SIZE
+//
+
+// __ROM2
+// Base address
+// Defines base address of memory region.
+// Default: DDR4_3_S_BASE
+#define __ROM2_BASE DDR4_3_S_BASE
+// Region size [bytes]
+// Defines size of memory region.
+// Default: DDR4_3_S_SIZE
+#define __ROM2_SIZE DDR4_3_S_SIZE
+//
+
+// __ROM3
+// Base address
+// Defines base address of memory region.
+// Default: QSPI_FLASH_S_BASE
+#define __ROM3_BASE QSPI_FLASH_S_BASE
+// Region size [bytes]
+// Defines size of memory region.
+// Default: QSPI_FLASH_S_SIZE
+#define __ROM3_SIZE QSPI_FLASH_S_SIZE
+//
+
+//
+
+// RAM Configuration
+// =======================
+// __RAM0
+// Base address
+// Defines base address of memory region.
+// Default: DDR4_1_S_BASE
+#define __RAM0_BASE DDR4_1_S_BASE
+// Region size [bytes]
+// Defines size of memory region.
+// Default: DDR4_1_S_SIZE
+#define __RAM0_SIZE DDR4_1_S_SIZE
+//
+
+// __RAM1
+// Base address
+// Defines base address of memory region.
+// Default: SRAM_VM0_S_BASE
+#define __RAM1_BASE SRAM_VM0_S_BASE
+// Region size [bytes]
+// Defines size of memory region.
+// Default: SRAM_VM0_S_SIZE
+#define __RAM1_SIZE SRAM_VM0_S_SIZE
+//
+
+// __RAM2
+// Base address
+// Defines base address of memory region.
+// Default: SRAM_VM1_S_BASE
+#define __RAM2_BASE SRAM_VM1_S_BASE
+// Region size [bytes]
+// Defines size of memory region.
+// Default: SRAM_VM1_S_SIZE
+#define __RAM2_SIZE SRAM_VM1_S_SIZE
+//
+
+// __RAM3
+// Base address
+// Defines base address of memory region.
+// Default: DTCM_S_BASE
+#define __RAM3_BASE DTCM_S_BASE
+// Region size [bytes]
+// Defines size of memory region.
+// Default: DTCM_S_SIZE
+#define __RAM3_SIZE DTCM_S_SIZE
+//
+
+//
+
+// Stack / Heap Configuration
+// Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
+// Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
+#define __STACK_SIZE 0x00001000
+#define __HEAP_SIZE 0x00018000
+//
+
+#endif /* REGIONS_SSE_300_H */
diff --git a/board/Corstone-300/retarget_stdio.c b/board/Corstone-300/retarget_stdio.c
new file mode 100644
index 0000000..f553eed
--- /dev/null
+++ b/board/Corstone-300/retarget_stdio.c
@@ -0,0 +1,161 @@
+/*---------------------------------------------------------------------------
+ * Copyright (c) 2025 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.
+ *
+ * Name: retarget_stdio.c
+ * Purpose: Retarget stdio to CMSIS UART
+ *
+ *---------------------------------------------------------------------------*/
+
+#ifdef CMSIS_target_header
+#include CMSIS_target_header
+#else
+#include "Driver_USART.h"
+#endif
+
+#ifndef RETARGET_STDIO_UART
+#error "RETARGET_STDIO_UART not defined!"
+#endif
+
+/* Compile-time configuration */
+#ifndef UART_BAUDRATE
+#define UART_BAUDRATE 115200
+#endif
+
+/* References to the external retarget functions */
+extern int stdio_init (void);
+extern int stderr_putchar (int ch);
+extern int stdout_putchar (int ch);
+extern int stdin_getchar (void);
+
+/* Reference to the underlying USART driver */
+#ifndef CMSIS_target_header
+extern ARM_DRIVER_USART ARM_Driver_USART_(RETARGET_STDIO_UART);
+#endif
+#define ptrUSART (&ARM_Driver_USART_(RETARGET_STDIO_UART))
+
+/**
+ Initialize stdio
+
+ \return 0 on success, or -1 on error.
+*/
+int stdio_init (void) {
+
+ if (ptrUSART->Initialize(NULL) != ARM_DRIVER_OK) {
+ return -1;
+ }
+
+ if (ptrUSART->PowerControl(ARM_POWER_FULL) != ARM_DRIVER_OK) {
+ return -1;
+ }
+
+ if (ptrUSART->Control(ARM_USART_MODE_ASYNCHRONOUS |
+ ARM_USART_DATA_BITS_8 |
+ ARM_USART_PARITY_NONE |
+ ARM_USART_STOP_BITS_1 |
+ ARM_USART_FLOW_CONTROL_NONE,
+ UART_BAUDRATE) != ARM_DRIVER_OK) {
+ return -1;
+ }
+
+ if (ptrUSART->Control(ARM_USART_CONTROL_RX, 1U) != ARM_DRIVER_OK) {
+ return -1;
+ }
+
+ if (ptrUSART->Control(ARM_USART_CONTROL_TX, 1U) != ARM_DRIVER_OK) {
+ return -1;
+ }
+
+ return 0;
+}
+
+/**
+ Put a character to the stderr
+
+ \param[in] ch Character to output
+ \return The character written, or -1 on write error.
+*/
+int stderr_putchar (int ch) {
+ uint8_t buf[1];
+
+ if (ch == '\n') {
+ buf[0] = (uint8_t)'\r';
+
+ if (ptrUSART->Send(buf, 1U) != ARM_DRIVER_OK) {
+ return -1;
+ }
+
+ while (ptrUSART->GetStatus().tx_busy != 0U);
+ }
+
+ buf[0] = (uint8_t)ch;
+
+ if (ptrUSART->Send(buf, 1U) != ARM_DRIVER_OK) {
+ return -1;
+ }
+
+ while (ptrUSART->GetStatus().tx_busy != 0U);
+
+ return ch;
+}
+
+/**
+ Put a character to the stdout
+
+ \param[in] ch Character to output
+ \return The character written, or -1 on write error.
+*/
+int stdout_putchar (int ch) {
+ uint8_t buf[1];
+
+ if (ch == '\n') {
+ buf[0] = (uint8_t)'\r';
+
+ if (ptrUSART->Send(buf, 1U) != ARM_DRIVER_OK) {
+ return -1;
+ }
+
+ while (ptrUSART->GetStatus().tx_busy != 0U);
+ }
+
+ buf[0] = (uint8_t)ch;
+
+ if (ptrUSART->Send(buf, 1U) != ARM_DRIVER_OK) {
+ return -1;
+ }
+
+ while (ptrUSART->GetStatus().tx_busy != 0U);
+
+ return ch;
+}
+
+/**
+ Get a character from the stdio
+
+ \return The next character from the input, or -1 on read error.
+*/
+int stdin_getchar (void) {
+ uint8_t buf[1];
+
+ if (ptrUSART->Receive(buf, 1U) != ARM_DRIVER_OK) {
+ return -1;
+ }
+
+ while (ptrUSART->GetStatus().rx_busy != 0U);
+
+ return (int)buf[0];
+}
\ No newline at end of file
diff --git a/board/Corstone-300/sse300_memmap_ns.h b/board/Corstone-300/sse300_memmap_ns.h
new file mode 100644
index 0000000..d15a465
--- /dev/null
+++ b/board/Corstone-300/sse300_memmap_ns.h
@@ -0,0 +1,92 @@
+/*---------------------------------------------------------------------------
+ * Copyright (c) 2025 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 SSE300_MEMMAP_NS_H
+#define SSE300_MEMMAP_NS_H
+
+/*============================================================================*/
+/* NON-SECURE MEMORY REGIONS */
+/*============================================================================*/
+
+/*---------------------------------------------------------------------------*/
+/* Non-Secure Code Regions */
+/*---------------------------------------------------------------------------*/
+
+/* ITCM - Non-Secure */
+#define ITCM_NS_BASE 0x00000000
+#define ITCM_NS_SIZE 0x00080000 /* 512KB */
+#define ITCM_NS_LIMIT (ITCM_NS_BASE + ITCM_NS_SIZE - 1)
+
+/* FPGA SRAM - Non-Secure */
+#define FPGA_SRAM_NS_BASE 0x01000000
+#define FPGA_SRAM_NS_SIZE 0x00100000 /* 1MB */
+#define FPGA_SRAM_NS_LIMIT (FPGA_SRAM_NS_BASE + FPGA_SRAM_NS_SIZE - 1)
+
+/*---------------------------------------------------------------------------*/
+/* Non-Secure SRAM Regions */
+/*---------------------------------------------------------------------------*/
+
+/* DTCM - Non-Secure */
+#define DTCM_NS_BASE 0x20000000
+#define DTCM_NS_SIZE 0x00080000 /* 512KB */
+#define DTCM_NS_LIMIT (DTCM_NS_BASE + DTCM_NS_SIZE - 1)
+
+/* SRAM VM0 - Non-Secure */
+#define SRAM_VM0_NS_BASE 0x21000000
+#define SRAM_VM0_NS_SIZE 0x00100000 /* 1MB */
+#define SRAM_VM0_NS_LIMIT (SRAM_VM0_NS_BASE + SRAM_VM0_NS_SIZE - 1)
+
+/* SRAM VM1 - Non-Secure */
+#define SRAM_VM1_NS_BASE 0x21100000
+#define SRAM_VM1_NS_SIZE 0x00100000 /* 1MB */
+#define SRAM_VM1_NS_LIMIT (SRAM_VM1_NS_BASE + SRAM_VM1_NS_SIZE - 1)
+
+/*---------------------------------------------------------------------------*/
+/* Secure QSPI Flash Regions */
+/*---------------------------------------------------------------------------*/
+
+/* QSPI Flash - Secure */
+#define QSPI_FLASH_NS_BASE 0x28000000
+#define QSPI_FLASH_NS_SIZE 0x00800000 /* 8MB */
+#define QSPI_FLASH_NS_LIMIT (QSPI_FLASH_NS_BASE + QSPI_FLASH_NS_SIZE - 1)
+
+/*---------------------------------------------------------------------------*/
+/* Non-Secure DDR4 Regions */
+/*---------------------------------------------------------------------------*/
+
+/* DDR4 Region 0 - Non-Secure */
+#define DDR4_0_NS_BASE 0x60000000
+#define DDR4_0_NS_SIZE 0x10000000 /* 256MB */
+#define DDR4_0_NS_LIMIT (DDR4_0_NS_BASE + DDR4_0_NS_SIZE - 1)
+
+/* DDR4 Region 2 - Non-Secure */
+#define DDR4_2_NS_BASE 0x80000000
+#define DDR4_2_NS_SIZE 0x10000000 /* 256MB */
+#define DDR4_2_NS_LIMIT (DDR4_2_NS_BASE + DDR4_2_NS_SIZE - 1)
+
+/* DDR4 Region 4 - Non-Secure */
+#define DDR4_4_NS_BASE 0xA0000000
+#define DDR4_4_NS_SIZE 0x10000000 /* 256MB */
+#define DDR4_4_NS_LIMIT (DDR4_4_NS_BASE + DDR4_4_NS_SIZE - 1)
+
+/* DDR4 Region 6 - Non-Secure */
+#define DDR4_6_NS_BASE 0xC0000000
+#define DDR4_6_NS_SIZE 0x10000000 /* 256MB */
+#define DDR4_6_NS_LIMIT (DDR4_6_NS_BASE + DDR4_6_NS_SIZE - 1)
+
+#endif /* SSE300_MEMMAP_NS_H */
diff --git a/board/Corstone-300/sse300_memmap_s.h b/board/Corstone-300/sse300_memmap_s.h
new file mode 100644
index 0000000..3746461
--- /dev/null
+++ b/board/Corstone-300/sse300_memmap_s.h
@@ -0,0 +1,92 @@
+/*---------------------------------------------------------------------------
+ * Copyright (c) 2025 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 SSE300_MEMMAP_S_H
+#define SSE300_MEMMAP_S_H
+
+/*============================================================================*/
+/* SECURE MEMORY REGIONS */
+/*============================================================================*/
+
+/*---------------------------------------------------------------------------*/
+/* Secure Code Regions */
+/*---------------------------------------------------------------------------*/
+
+/* ITCM - Secure (Startup) */
+#define ITCM_S_BASE 0x10000000
+#define ITCM_S_SIZE 0x00080000 /* 512KB */
+#define ITCM_S_LIMIT (ITCM_S_BASE + ITCM_S_SIZE - 1)
+
+/* FPGA SRAM - Secure */
+#define FPGA_SRAM_S_BASE 0x11000000
+#define FPGA_SRAM_S_SIZE 0x00100000 /* 1MB */
+#define FPGA_SRAM_S_LIMIT (FPGA_SRAM_S_BASE + FPGA_SRAM_S_SIZE - 1)
+
+/*---------------------------------------------------------------------------*/
+/* Secure SRAM Regions */
+/*---------------------------------------------------------------------------*/
+
+/* DTCM - Secure */
+#define DTCM_S_BASE 0x30000000
+#define DTCM_S_SIZE 0x00080000 /* 512KB */
+#define DTCM_S_LIMIT (DTCM_S_BASE + DTCM_S_SIZE - 1)
+
+/* SRAM VM0 - Secure */
+#define SRAM_VM0_S_BASE 0x31000000
+#define SRAM_VM0_S_SIZE 0x00100000 /* 1MB */
+#define SRAM_VM0_S_LIMIT (SRAM_VM0_S_BASE + SRAM_VM0_S_SIZE - 1)
+
+/* SRAM VM1 - Secure */
+#define SRAM_VM1_S_BASE 0x31100000
+#define SRAM_VM1_S_SIZE 0x00100000 /* 1MB */
+#define SRAM_VM1_S_LIMIT (SRAM_VM1_S_BASE + SRAM_VM1_S_SIZE - 1)
+
+/*---------------------------------------------------------------------------*/
+/* Secure QSPI Flash Regions */
+/*---------------------------------------------------------------------------*/
+
+/* QSPI Flash - Secure */
+#define QSPI_FLASH_S_BASE 0x38000000
+#define QSPI_FLASH_S_SIZE 0x00800000 /* 8MB */
+#define QSPI_FLASH_S_LIMIT (QSPI_FLASH_S_BASE + QSPI_FLASH_S_SIZE - 1)
+
+/*---------------------------------------------------------------------------*/
+/* Secure DDR4 Regions */
+/*---------------------------------------------------------------------------*/
+
+/* DDR4 Region 1 - Secure */
+#define DDR4_1_S_BASE 0x70000000
+#define DDR4_1_S_SIZE 0x10000000 /* 256MB */
+#define DDR4_1_S_LIMIT (DDR4_1_S_BASE + DDR4_1_S_SIZE - 1)
+
+/* DDR4 Region 3 - Secure */
+#define DDR4_3_S_BASE 0x90000000
+#define DDR4_3_S_SIZE 0x10000000 /* 256MB */
+#define DDR4_3_S_LIMIT (DDR4_3_S_BASE + DDR4_3_S_SIZE - 1)
+
+/* DDR4 Region 5 - Secure */
+#define DDR4_5_S_BASE 0xB0000000
+#define DDR4_5_S_SIZE 0x10000000 /* 256MB */
+#define DDR4_5_S_LIMIT (DDR4_5_S_BASE + DDR4_5_S_SIZE - 1)
+
+/* DDR4 Region 7 - Secure */
+#define DDR4_7_S_BASE 0xD0000000
+#define DDR4_7_S_SIZE 0x10000000 /* 256MB */
+#define DDR4_7_S_LIMIT (DDR4_7_S_BASE + DDR4_7_S_SIZE - 1)
+
+#endif /* SSE300_MEMMAP_S_H */
diff --git a/board/Corstone-300/vsi/python/arm_vsi0.py b/board/Corstone-300/vsi/python/arm_vsi0.py
new file mode 100644
index 0000000..e1a7bfc
--- /dev/null
+++ b/board/Corstone-300/vsi/python/arm_vsi0.py
@@ -0,0 +1,217 @@
+# Copyright (c) 2021-2025 Arm Limited. All rights reserved.
+
+# Virtual Streaming Interface instance 0 Python script
+
+##@addtogroup arm_vsi_py_vstream_audio
+# @{
+#
+##@package arm_vsi0_vstream_audio
+#Documentation for VSI vStream Audio module.
+#
+#More details.
+
+import logging
+import vsi_audio
+
+logger = logging.getLogger(__name__)
+vsi_audio.logger = logger
+
+## Set verbosity level
+#verbosity = logging.DEBUG
+#verbosity = logging.INFO
+#verbosity = logging.WARNING
+verbosity = logging.ERROR
+
+# [debugging] Verbosity settings
+level = { 10: "DEBUG", 20: "INFO", 30: "WARNING", 40: "ERROR" }
+logging.basicConfig(format='Py: %(name)s : [%(levelname)s]\t%(message)s', level = verbosity)
+logger.info("Verbosity level is set to " + level[verbosity])
+
+
+# Audio Server configuration
+server_address = ('127.0.0.1', 6000)
+server_authkey = 'vsi_audio'
+
+
+# IRQ registers
+IRQ_Status = 0
+
+# Timer registers
+Timer_Control = 0
+Timer_Interval = 0
+
+# Timer Control register definitions
+Timer_Control_Run_Msk = 1<<0
+Timer_Control_Periodic_Msk = 1<<1
+Timer_Control_Trig_IRQ_Msk = 1<<2
+Timer_Control_Trig_DMA_Msk = 1<<3
+
+# DMA registers
+DMA_Control = 0
+
+# DMA Control register definitions
+DMA_Control_Enable_Msk = 1<<0
+DMA_Control_Direction_Msk = 1<<1
+DMA_Control_Direction_P2M = 0<<1
+DMA_Control_Direction_M2P = 1<<1
+
+# User registers
+Regs = [0] * 64
+
+# Data buffer
+Data = bytearray()
+
+# Streaming Server Connection Status
+Server_Connected = False
+
+
+
+## Initialize
+# @return None
+def init():
+ global Server_Connected
+ logger.info("init() called")
+
+ Server_Connected = vsi_audio.init(server_address, server_authkey)
+
+
+## Read interrupt request (the VSI IRQ Status Register)
+# @return value value read (32-bit)
+def rdIRQ():
+ global IRQ_Status
+ logger.info("rdIRQ() called")
+
+ value = IRQ_Status
+ logger.debug(f"Read IRQ_Status: 0x{value:08X}")
+
+ return value
+
+
+## Write interrupt request (the VSI IRQ Status Register)
+# @param value value to write (32-bit)
+# @return value value written (32-bit)
+def wrIRQ(value):
+ global IRQ_Status
+ logger.info(f"wrIRQ(value=0x{value:08X}) called")
+
+ IRQ_Status = value
+ logger.debug(f"wrIRQ: write IRQ_Status: 0x{value:08X}")
+
+ return value
+
+
+## Write Timer registers (the VSI Timer Registers)
+# @param index Timer register index (zero based)
+# @param value value to write (32-bit)
+# @return value value written (32-bit)
+def wrTimer(index, value):
+ global Timer_Control, Timer_Interval
+ logger.info(f"wrTimer(index={index}, value=0x{value:08X}) called")
+
+ if index == 0:
+ Timer_Control = value
+ logger.debug(f"wrTimer: write Timer_Control: 0x{value:08X}")
+ elif index == 1:
+ Timer_Interval = value
+ logger.debug(f"wrTimer: write Timer_Interval: 0x{value:08X}")
+
+ return value
+
+
+## Timer event (called at Timer Overflow)
+# @return None
+def timerEvent():
+ logger.info("timerEvent() called")
+
+ if Server_Connected:
+ vsi_audio.timerEvent()
+
+
+## Write DMA registers (the VSI DMA Registers)
+# @param index DMA register index (zero based)
+# @param value value to write (32-bit)
+# @return value value written (32-bit)
+def wrDMA(index, value):
+ global DMA_Control
+ logger.info(f"wrDMA(index={index}, value=0x{value:08X}) called")
+
+ if index == 0:
+ DMA_Control = value
+ logger.debug(f"wrDMA: write DMA_Control: 0x{value:08X}")
+
+ return value
+
+
+## Read data from peripheral for DMA P2M transfer (VSI DMA)
+# @param size size of data to read (in bytes, multiple of 4)
+# @return data data read (bytearray)
+def rdDataDMA(size):
+ global Data
+ logger.info(f"rdDataDMA(size={size}) called")
+
+ if Server_Connected:
+ Data = vsi_audio.rdDataDMA(size)
+
+ n = min(len(Data), size)
+ data = bytearray(size)
+ data[0:n] = Data[0:n]
+ logger.debug(f"rdDataDMA: read data ({size} bytes)")
+
+ return data
+
+
+## Write data to peripheral for DMA M2P transfer (VSI DMA)
+# @param data data to write (bytearray)
+# @param size size of data to write (in bytes, multiple of 4)
+# @return None
+def wrDataDMA(data, size):
+ global Data
+ logger.info(f"wrDataDMA(data={type(data).__name__}, size={size}) called")
+
+ Data = data
+ logger.debug(f"wrDataDMA: write data ({size} bytes)")
+
+ if Server_Connected:
+ vsi_audio.wrDataDMA(data, size)
+
+ return
+
+
+## Read user registers (the VSI User Registers)
+# @param index user register index (zero based)
+# @return value value read (32-bit)
+def rdRegs(index):
+ global Regs
+ logger.info(f"rdRegs(index={index}) called")
+
+ if Server_Connected:
+ Regs[index] = vsi_audio.rdRegs(index)
+
+ value = Regs[index]
+
+ # Log the value read from the register
+ logger.debug(f"rdRegs: read Regs[{index}]: 0x{value:08X}")
+
+ return value
+
+
+## Write user registers (the VSI User Registers)
+# @param index user register index (zero based)
+# @param value value to write (32-bit)
+# @return value value written (32-bit)
+def wrRegs(index, value):
+ global Regs
+ logger.info(f"wrRegs(index={index}, value=0x{value:08X}) called")
+
+ if Server_Connected:
+ value = vsi_audio.wrRegs(index, value)
+
+ Regs[index] = value
+
+ # Log the value written to the register
+ logger.debug(f"wrRegs: write Regs[{index}] = 0x{value:08X}")
+
+ return value
+
+
+## @}
diff --git a/board/Corstone-300/vsi/python/arm_vsi1.py b/board/Corstone-300/vsi/python/arm_vsi1.py
new file mode 100644
index 0000000..f1271b5
--- /dev/null
+++ b/board/Corstone-300/vsi/python/arm_vsi1.py
@@ -0,0 +1,217 @@
+# Copyright (c) 2021-2025 Arm Limited. All rights reserved.
+
+# Virtual Streaming Interface instance 1 Python script
+
+##@addtogroup arm_vsi_py_vstream_audio
+# @{
+#
+##@package arm_vsi1_vstream_audio
+#Documentation for VSI vStream Audio module.
+#
+#More details.
+
+import logging
+import vsi_audio
+
+logger = logging.getLogger(__name__)
+vsi_audio.logger = logger
+
+## Set verbosity level
+#verbosity = logging.DEBUG
+#verbosity = logging.INFO
+#verbosity = logging.WARNING
+verbosity = logging.ERROR
+
+# [debugging] Verbosity settings
+level = { 10: "DEBUG", 20: "INFO", 30: "WARNING", 40: "ERROR" }
+logging.basicConfig(format='Py: %(name)s : [%(levelname)s]\t%(message)s', level = verbosity)
+logger.info("Verbosity level is set to " + level[verbosity])
+
+
+# Audio Server configuration
+server_address = ('127.0.0.1', 6001)
+server_authkey = 'vsi_audio'
+
+
+# IRQ registers
+IRQ_Status = 0
+
+# Timer registers
+Timer_Control = 0
+Timer_Interval = 0
+
+# Timer Control register definitions
+Timer_Control_Run_Msk = 1<<0
+Timer_Control_Periodic_Msk = 1<<1
+Timer_Control_Trig_IRQ_Msk = 1<<2
+Timer_Control_Trig_DMA_Msk = 1<<3
+
+# DMA registers
+DMA_Control = 0
+
+# DMA Control register definitions
+DMA_Control_Enable_Msk = 1<<0
+DMA_Control_Direction_Msk = 1<<1
+DMA_Control_Direction_P2M = 0<<1
+DMA_Control_Direction_M2P = 1<<1
+
+# User registers
+Regs = [0] * 64
+
+# Data buffer
+Data = bytearray()
+
+# Streaming Server Connection Status
+Server_Connected = False
+
+
+
+## Initialize
+# @return None
+def init():
+ global Server_Connected
+ logger.info("init() called")
+
+ Server_Connected = vsi_audio.init(server_address, server_authkey)
+
+
+## Read interrupt request (the VSI IRQ Status Register)
+# @return value value read (32-bit)
+def rdIRQ():
+ global IRQ_Status
+ logger.info("rdIRQ() called")
+
+ value = IRQ_Status
+ logger.debug(f"Read IRQ_Status: 0x{value:08X}")
+
+ return value
+
+
+## Write interrupt request (the VSI IRQ Status Register)
+# @param value value to write (32-bit)
+# @return value value written (32-bit)
+def wrIRQ(value):
+ global IRQ_Status
+ logger.info(f"wrIRQ(value=0x{value:08X}) called")
+
+ IRQ_Status = value
+ logger.debug(f"wrIRQ: write IRQ_Status: 0x{value:08X}")
+
+ return value
+
+
+## Write Timer registers (the VSI Timer Registers)
+# @param index Timer register index (zero based)
+# @param value value to write (32-bit)
+# @return value value written (32-bit)
+def wrTimer(index, value):
+ global Timer_Control, Timer_Interval
+ logger.info(f"wrTimer(index={index}, value=0x{value:08X}) called")
+
+ if index == 0:
+ Timer_Control = value
+ logger.debug(f"wrTimer: write Timer_Control: 0x{value:08X}")
+ elif index == 1:
+ Timer_Interval = value
+ logger.debug(f"wrTimer: write Timer_Interval: 0x{value:08X}")
+
+ return value
+
+
+## Timer event (called at Timer Overflow)
+# @return None
+def timerEvent():
+ logger.info("timerEvent() called")
+
+ if Server_Connected:
+ vsi_audio.timerEvent()
+
+
+## Write DMA registers (the VSI DMA Registers)
+# @param index DMA register index (zero based)
+# @param value value to write (32-bit)
+# @return value value written (32-bit)
+def wrDMA(index, value):
+ global DMA_Control
+ logger.info(f"wrDMA(index={index}, value=0x{value:08X}) called")
+
+ if index == 0:
+ DMA_Control = value
+ logger.debug(f"wrDMA: write DMA_Control: 0x{value:08X}")
+
+ return value
+
+
+## Read data from peripheral for DMA P2M transfer (VSI DMA)
+# @param size size of data to read (in bytes, multiple of 4)
+# @return data data read (bytearray)
+def rdDataDMA(size):
+ global Data
+ logger.info(f"rdDataDMA(size={size}) called")
+
+ if Server_Connected:
+ Data = vsi_audio.rdDataDMA(size)
+
+ n = min(len(Data), size)
+ data = bytearray(size)
+ data[0:n] = Data[0:n]
+ logger.debug(f"rdDataDMA: read data ({size} bytes)")
+
+ return data
+
+
+## Write data to peripheral for DMA M2P transfer (VSI DMA)
+# @param data data to write (bytearray)
+# @param size size of data to write (in bytes, multiple of 4)
+# @return None
+def wrDataDMA(data, size):
+ global Data
+ logger.info(f"wrDataDMA(data={type(data).__name__}, size={size}) called")
+
+ Data = data
+ logger.debug(f"wrDataDMA: write data ({size} bytes)")
+
+ if Server_Connected:
+ vsi_audio.wrDataDMA(data, size)
+
+ return
+
+
+## Read user registers (the VSI User Registers)
+# @param index user register index (zero based)
+# @return value value read (32-bit)
+def rdRegs(index):
+ global Regs
+ logger.info(f"rdRegs(index={index}) called")
+
+ if Server_Connected:
+ Regs[index] = vsi_audio.rdRegs(index)
+
+ value = Regs[index]
+
+ # Log the value read from the register
+ logger.debug(f"rdRegs: read Regs[{index}]: 0x{value:08X}")
+
+ return value
+
+
+## Write user registers (the VSI User Registers)
+# @param index user register index (zero based)
+# @param value value to write (32-bit)
+# @return value value written (32-bit)
+def wrRegs(index, value):
+ global Regs
+ logger.info(f"wrRegs(index={index}, value=0x{value:08X}) called")
+
+ if Server_Connected:
+ value = vsi_audio.wrRegs(index, value)
+
+ Regs[index] = value
+
+ # Log the value written to the register
+ logger.debug(f"wrRegs: write Regs[{index}] = 0x{value:08X}")
+
+ return value
+
+
+## @}
diff --git a/board/Corstone-300/vsi/python/arm_vsi4.py b/board/Corstone-300/vsi/python/arm_vsi4.py
new file mode 100644
index 0000000..e15edf8
--- /dev/null
+++ b/board/Corstone-300/vsi/python/arm_vsi4.py
@@ -0,0 +1,217 @@
+# Copyright (c) 2021-2025 Arm Limited. All rights reserved.
+
+# Virtual Streaming Interface instance 4 Python script
+
+##@addtogroup arm_vsi_py_vstream_video
+# @{
+#
+##@package arm_vsi4_vstream_video
+#Documentation for VSI vStream Video module.
+#
+#More details.
+
+import logging
+import vsi_video
+
+logger = logging.getLogger(__name__)
+vsi_video.logger = logger
+
+## Set verbosity level
+#verbosity = logging.DEBUG
+#verbosity = logging.INFO
+#verbosity = logging.WARNING
+verbosity = logging.ERROR
+
+# [debugging] Verbosity settings
+level = { 10: "DEBUG", 20: "INFO", 30: "WARNING", 40: "ERROR" }
+logging.basicConfig(format='Py: %(name)s : [%(levelname)s]\t%(message)s', level = verbosity)
+logger.info("Verbosity level is set to " + level[verbosity])
+
+
+# Video Server configuration
+server_address = ('127.0.0.1', 6004)
+server_authkey = 'vsi_video'
+
+
+# IRQ registers
+IRQ_Status = 0
+
+# Timer registers
+Timer_Control = 0
+Timer_Interval = 0
+
+# Timer Control register definitions
+Timer_Control_Run_Msk = 1<<0
+Timer_Control_Periodic_Msk = 1<<1
+Timer_Control_Trig_IRQ_Msk = 1<<2
+Timer_Control_Trig_DMA_Msk = 1<<3
+
+# DMA registers
+DMA_Control = 0
+
+# DMA Control register definitions
+DMA_Control_Enable_Msk = 1<<0
+DMA_Control_Direction_Msk = 1<<1
+DMA_Control_Direction_P2M = 0<<1
+DMA_Control_Direction_M2P = 1<<1
+
+# User registers
+Regs = [0] * 64
+
+# Data buffer
+Data = bytearray()
+
+# Streaming Server Connection Status
+Server_Connected = False
+
+
+
+## Initialize
+# @return None
+def init():
+ global Server_Connected
+ logger.info("init() called")
+
+ Server_Connected = vsi_video.init(server_address, server_authkey)
+
+
+## Read interrupt request (the VSI IRQ Status Register)
+# @return value value read (32-bit)
+def rdIRQ():
+ global IRQ_Status
+ logger.info("rdIRQ() called")
+
+ value = IRQ_Status
+ logger.debug(f"Read IRQ_Status: 0x{value:08X}")
+
+ return value
+
+
+## Write interrupt request (the VSI IRQ Status Register)
+# @param value value to write (32-bit)
+# @return value value written (32-bit)
+def wrIRQ(value):
+ global IRQ_Status
+ logger.info(f"wrIRQ(value=0x{value:08X}) called")
+
+ IRQ_Status = value
+ logger.debug(f"wrIRQ: write IRQ_Status: 0x{value:08X}")
+
+ return value
+
+
+## Write Timer registers (the VSI Timer Registers)
+# @param index Timer register index (zero based)
+# @param value value to write (32-bit)
+# @return value value written (32-bit)
+def wrTimer(index, value):
+ global Timer_Control, Timer_Interval
+ logger.info(f"wrTimer(index={index}, value=0x{value:08X}) called")
+
+ if index == 0:
+ Timer_Control = value
+ logger.debug(f"wrTimer: write Timer_Control: 0x{value:08X}")
+ elif index == 1:
+ Timer_Interval = value
+ logger.debug(f"wrTimer: write Timer_Interval: 0x{value:08X}")
+
+ return value
+
+
+## Timer event (called at Timer Overflow)
+# @return None
+def timerEvent():
+ logger.info("timerEvent() called")
+
+ if Server_Connected:
+ vsi_video.timerEvent()
+
+
+## Write DMA registers (the VSI DMA Registers)
+# @param index DMA register index (zero based)
+# @param value value to write (32-bit)
+# @return value value written (32-bit)
+def wrDMA(index, value):
+ global DMA_Control
+ logger.info(f"wrDMA(index={index}, value=0x{value:08X}) called")
+
+ if index == 0:
+ DMA_Control = value
+ logger.debug(f"wrDMA: write DMA_Control: 0x{value:08X}")
+
+ return value
+
+
+## Read data from peripheral for DMA P2M transfer (VSI DMA)
+# @param size size of data to read (in bytes, multiple of 4)
+# @return data data read (bytearray)
+def rdDataDMA(size):
+ global Data
+ logger.info(f"rdDataDMA(size={size}) called")
+
+ if Server_Connected:
+ Data = vsi_video.rdDataDMA(size)
+
+ n = min(len(Data), size)
+ data = bytearray(size)
+ data[0:n] = Data[0:n]
+ logger.debug(f"rdDataDMA: read data ({size} bytes)")
+
+ return data
+
+
+## Write data to peripheral for DMA M2P transfer (VSI DMA)
+# @param data data to write (bytearray)
+# @param size size of data to write (in bytes, multiple of 4)
+# @return None
+def wrDataDMA(data, size):
+ global Data
+ logger.info(f"wrDataDMA(data={type(data).__name__}, size={size}) called")
+
+ Data = data
+ logger.debug(f"wrDataDMA: write data ({size} bytes)")
+
+ if Server_Connected:
+ vsi_video.wrDataDMA(data, size)
+
+ return
+
+
+## Read user registers (the VSI User Registers)
+# @param index user register index (zero based)
+# @return value value read (32-bit)
+def rdRegs(index):
+ global Regs
+ logger.info(f"rdRegs(index={index}) called")
+
+ if Server_Connected:
+ Regs[index] = vsi_video.rdRegs(index)
+
+ value = Regs[index]
+
+ # Log the value read from the register
+ logger.debug(f"rdRegs: read Regs[{index}]: 0x{value:08X}")
+
+ return value
+
+
+## Write user registers (the VSI User Registers)
+# @param index user register index (zero based)
+# @param value value to write (32-bit)
+# @return value value written (32-bit)
+def wrRegs(index, value):
+ global Regs
+ logger.info(f"wrRegs(index={index}, value=0x{value:08X}) called")
+
+ if Server_Connected:
+ value = vsi_video.wrRegs(index, value)
+
+ Regs[index] = value
+
+ # Log the value written to the register
+ logger.debug(f"wrRegs: write Regs[{index}] = 0x{value:08X}")
+
+ return value
+
+
+## @}
diff --git a/board/Corstone-300/vsi/python/arm_vsi5.py b/board/Corstone-300/vsi/python/arm_vsi5.py
new file mode 100644
index 0000000..631f74d
--- /dev/null
+++ b/board/Corstone-300/vsi/python/arm_vsi5.py
@@ -0,0 +1,217 @@
+# Copyright (c) 2021-2025 Arm Limited. All rights reserved.
+
+# Virtual Streaming Interface instance 5 Python script
+
+##@addtogroup arm_vsi_py_vstream_video
+# @{
+#
+##@package arm_vsi5_vstream_video
+#Documentation for VSI vStream Video module.
+#
+#More details.
+
+import logging
+import vsi_video
+
+logger = logging.getLogger(__name__)
+vsi_video.logger = logger
+
+## Set verbosity level
+#verbosity = logging.DEBUG
+#verbosity = logging.INFO
+#verbosity = logging.WARNING
+verbosity = logging.ERROR
+
+# [debugging] Verbosity settings
+level = { 10: "DEBUG", 20: "INFO", 30: "WARNING", 40: "ERROR" }
+logging.basicConfig(format='Py: %(name)s : [%(levelname)s]\t%(message)s', level = verbosity)
+logger.info("Verbosity level is set to " + level[verbosity])
+
+
+# Video Server configuration
+server_address = ('127.0.0.1', 6005)
+server_authkey = 'vsi_video'
+
+
+# IRQ registers
+IRQ_Status = 0
+
+# Timer registers
+Timer_Control = 0
+Timer_Interval = 0
+
+# Timer Control register definitions
+Timer_Control_Run_Msk = 1<<0
+Timer_Control_Periodic_Msk = 1<<1
+Timer_Control_Trig_IRQ_Msk = 1<<2
+Timer_Control_Trig_DMA_Msk = 1<<3
+
+# DMA registers
+DMA_Control = 0
+
+# DMA Control register definitions
+DMA_Control_Enable_Msk = 1<<0
+DMA_Control_Direction_Msk = 1<<1
+DMA_Control_Direction_P2M = 0<<1
+DMA_Control_Direction_M2P = 1<<1
+
+# User registers
+Regs = [0] * 64
+
+# Data buffer
+Data = bytearray()
+
+# Streaming Server Connection Status
+Server_Connected = False
+
+
+
+## Initialize
+# @return None
+def init():
+ global Server_Connected
+ logger.info("init() called")
+
+ Server_Connected = vsi_video.init(server_address, server_authkey)
+
+
+## Read interrupt request (the VSI IRQ Status Register)
+# @return value value read (32-bit)
+def rdIRQ():
+ global IRQ_Status
+ logger.info("rdIRQ() called")
+
+ value = IRQ_Status
+ logger.debug(f"Read IRQ_Status: 0x{value:08X}")
+
+ return value
+
+
+## Write interrupt request (the VSI IRQ Status Register)
+# @param value value to write (32-bit)
+# @return value value written (32-bit)
+def wrIRQ(value):
+ global IRQ_Status
+ logger.info(f"wrIRQ(value=0x{value:08X}) called")
+
+ IRQ_Status = value
+ logger.debug(f"wrIRQ: write IRQ_Status: 0x{value:08X}")
+
+ return value
+
+
+## Write Timer registers (the VSI Timer Registers)
+# @param index Timer register index (zero based)
+# @param value value to write (32-bit)
+# @return value value written (32-bit)
+def wrTimer(index, value):
+ global Timer_Control, Timer_Interval
+ logger.info(f"wrTimer(index={index}, value=0x{value:08X}) called")
+
+ if index == 0:
+ Timer_Control = value
+ logger.debug(f"wrTimer: write Timer_Control: 0x{value:08X}")
+ elif index == 1:
+ Timer_Interval = value
+ logger.debug(f"wrTimer: write Timer_Interval: 0x{value:08X}")
+
+ return value
+
+
+## Timer event (called at Timer Overflow)
+# @return None
+def timerEvent():
+ logger.info("timerEvent() called")
+
+ if Server_Connected:
+ vsi_video.timerEvent()
+
+
+## Write DMA registers (the VSI DMA Registers)
+# @param index DMA register index (zero based)
+# @param value value to write (32-bit)
+# @return value value written (32-bit)
+def wrDMA(index, value):
+ global DMA_Control
+ logger.info(f"wrDMA(index={index}, value=0x{value:08X}) called")
+
+ if index == 0:
+ DMA_Control = value
+ logger.debug(f"wrDMA: write DMA_Control: 0x{value:08X}")
+
+ return value
+
+
+## Read data from peripheral for DMA P2M transfer (VSI DMA)
+# @param size size of data to read (in bytes, multiple of 4)
+# @return data data read (bytearray)
+def rdDataDMA(size):
+ global Data
+ logger.info(f"rdDataDMA(size={size}) called")
+
+ if Server_Connected:
+ Data = vsi_video.rdDataDMA(size)
+
+ n = min(len(Data), size)
+ data = bytearray(size)
+ data[0:n] = Data[0:n]
+ logger.debug(f"rdDataDMA: read data ({size} bytes)")
+
+ return data
+
+
+## Write data to peripheral for DMA M2P transfer (VSI DMA)
+# @param data data to write (bytearray)
+# @param size size of data to write (in bytes, multiple of 4)
+# @return None
+def wrDataDMA(data, size):
+ global Data
+ logger.info(f"wrDataDMA(data={type(data).__name__}, size={size}) called")
+
+ Data = data
+ logger.debug(f"wrDataDMA: write data ({size} bytes)")
+
+ if Server_Connected:
+ vsi_video.wrDataDMA(data, size)
+
+ return
+
+
+## Read user registers (the VSI User Registers)
+# @param index user register index (zero based)
+# @return value value read (32-bit)
+def rdRegs(index):
+ global Regs
+ logger.info(f"rdRegs(index={index}) called")
+
+ if Server_Connected:
+ Regs[index] = vsi_video.rdRegs(index)
+
+ value = Regs[index]
+
+ # Log the value read from the register
+ logger.debug(f"rdRegs: read Regs[{index}]: 0x{value:08X}")
+
+ return value
+
+
+## Write user registers (the VSI User Registers)
+# @param index user register index (zero based)
+# @param value value to write (32-bit)
+# @return value value written (32-bit)
+def wrRegs(index, value):
+ global Regs
+ logger.info(f"wrRegs(index={index}, value=0x{value:08X}) called")
+
+ if Server_Connected:
+ value = vsi_video.wrRegs(index, value)
+
+ Regs[index] = value
+
+ # Log the value written to the register
+ logger.debug(f"wrRegs: write Regs[{index}] = 0x{value:08X}")
+
+ return value
+
+
+## @}
diff --git a/board/Corstone-300/vsi/python/arm_vsi6.py b/board/Corstone-300/vsi/python/arm_vsi6.py
new file mode 100644
index 0000000..58b1184
--- /dev/null
+++ b/board/Corstone-300/vsi/python/arm_vsi6.py
@@ -0,0 +1,217 @@
+# Copyright (c) 2021-2025 Arm Limited. All rights reserved.
+
+# Virtual Streaming Interface instance 6 Python script
+
+##@addtogroup arm_vsi_py_vstream_video
+# @{
+#
+##@package arm_vsi6_vstream_video
+#Documentation for VSI vStream Video module.
+#
+#More details.
+
+import logging
+import vsi_video
+
+logger = logging.getLogger(__name__)
+vsi_video.logger = logger
+
+## Set verbosity level
+#verbosity = logging.DEBUG
+#verbosity = logging.INFO
+#verbosity = logging.WARNING
+verbosity = logging.ERROR
+
+# [debugging] Verbosity settings
+level = { 10: "DEBUG", 20: "INFO", 30: "WARNING", 40: "ERROR" }
+logging.basicConfig(format='Py: %(name)s : [%(levelname)s]\t%(message)s', level = verbosity)
+logger.info("Verbosity level is set to " + level[verbosity])
+
+
+# Video Server configuration
+server_address = ('127.0.0.1', 6006)
+server_authkey = 'vsi_video'
+
+
+# IRQ registers
+IRQ_Status = 0
+
+# Timer registers
+Timer_Control = 0
+Timer_Interval = 0
+
+# Timer Control register definitions
+Timer_Control_Run_Msk = 1<<0
+Timer_Control_Periodic_Msk = 1<<1
+Timer_Control_Trig_IRQ_Msk = 1<<2
+Timer_Control_Trig_DMA_Msk = 1<<3
+
+# DMA registers
+DMA_Control = 0
+
+# DMA Control register definitions
+DMA_Control_Enable_Msk = 1<<0
+DMA_Control_Direction_Msk = 1<<1
+DMA_Control_Direction_P2M = 0<<1
+DMA_Control_Direction_M2P = 1<<1
+
+# User registers
+Regs = [0] * 64
+
+# Data buffer
+Data = bytearray()
+
+# Streaming Server Connection Status
+Server_Connected = False
+
+
+
+## Initialize
+# @return None
+def init():
+ global Server_Connected
+ logger.info("init() called")
+
+ Server_Connected = vsi_video.init(server_address, server_authkey)
+
+
+## Read interrupt request (the VSI IRQ Status Register)
+# @return value value read (32-bit)
+def rdIRQ():
+ global IRQ_Status
+ logger.info("rdIRQ() called")
+
+ value = IRQ_Status
+ logger.debug(f"Read IRQ_Status: 0x{value:08X}")
+
+ return value
+
+
+## Write interrupt request (the VSI IRQ Status Register)
+# @param value value to write (32-bit)
+# @return value value written (32-bit)
+def wrIRQ(value):
+ global IRQ_Status
+ logger.info(f"wrIRQ(value=0x{value:08X}) called")
+
+ IRQ_Status = value
+ logger.debug(f"wrIRQ: write IRQ_Status: 0x{value:08X}")
+
+ return value
+
+
+## Write Timer registers (the VSI Timer Registers)
+# @param index Timer register index (zero based)
+# @param value value to write (32-bit)
+# @return value value written (32-bit)
+def wrTimer(index, value):
+ global Timer_Control, Timer_Interval
+ logger.info(f"wrTimer(index={index}, value=0x{value:08X}) called")
+
+ if index == 0:
+ Timer_Control = value
+ logger.debug(f"wrTimer: write Timer_Control: 0x{value:08X}")
+ elif index == 1:
+ Timer_Interval = value
+ logger.debug(f"wrTimer: write Timer_Interval: 0x{value:08X}")
+
+ return value
+
+
+## Timer event (called at Timer Overflow)
+# @return None
+def timerEvent():
+ logger.info("timerEvent() called")
+
+ if Server_Connected:
+ vsi_video.timerEvent()
+
+
+## Write DMA registers (the VSI DMA Registers)
+# @param index DMA register index (zero based)
+# @param value value to write (32-bit)
+# @return value value written (32-bit)
+def wrDMA(index, value):
+ global DMA_Control
+ logger.info(f"wrDMA(index={index}, value=0x{value:08X}) called")
+
+ if index == 0:
+ DMA_Control = value
+ logger.debug(f"wrDMA: write DMA_Control: 0x{value:08X}")
+
+ return value
+
+
+## Read data from peripheral for DMA P2M transfer (VSI DMA)
+# @param size size of data to read (in bytes, multiple of 4)
+# @return data data read (bytearray)
+def rdDataDMA(size):
+ global Data
+ logger.info(f"rdDataDMA(size={size}) called")
+
+ if Server_Connected:
+ Data = vsi_video.rdDataDMA(size)
+
+ n = min(len(Data), size)
+ data = bytearray(size)
+ data[0:n] = Data[0:n]
+ logger.debug(f"rdDataDMA: read data ({size} bytes)")
+
+ return data
+
+
+## Write data to peripheral for DMA M2P transfer (VSI DMA)
+# @param data data to write (bytearray)
+# @param size size of data to write (in bytes, multiple of 4)
+# @return None
+def wrDataDMA(data, size):
+ global Data
+ logger.info(f"wrDataDMA(data={type(data).__name__}, size={size}) called")
+
+ Data = data
+ logger.debug(f"wrDataDMA: write data ({size} bytes)")
+
+ if Server_Connected:
+ vsi_video.wrDataDMA(data, size)
+
+ return
+
+
+## Read user registers (the VSI User Registers)
+# @param index user register index (zero based)
+# @return value value read (32-bit)
+def rdRegs(index):
+ global Regs
+ logger.info(f"rdRegs(index={index}) called")
+
+ if Server_Connected:
+ Regs[index] = vsi_video.rdRegs(index)
+
+ value = Regs[index]
+
+ # Log the value read from the register
+ logger.debug(f"rdRegs: read Regs[{index}]: 0x{value:08X}")
+
+ return value
+
+
+## Write user registers (the VSI User Registers)
+# @param index user register index (zero based)
+# @param value value to write (32-bit)
+# @return value value written (32-bit)
+def wrRegs(index, value):
+ global Regs
+ logger.info(f"wrRegs(index={index}, value=0x{value:08X}) called")
+
+ if Server_Connected:
+ value = vsi_video.wrRegs(index, value)
+
+ Regs[index] = value
+
+ # Log the value written to the register
+ logger.debug(f"wrRegs: write Regs[{index}] = 0x{value:08X}")
+
+ return value
+
+
+## @}
diff --git a/board/Corstone-300/vsi/python/arm_vsi7.py b/board/Corstone-300/vsi/python/arm_vsi7.py
new file mode 100644
index 0000000..cd32ab8
--- /dev/null
+++ b/board/Corstone-300/vsi/python/arm_vsi7.py
@@ -0,0 +1,217 @@
+# Copyright (c) 2021-2025 Arm Limited. All rights reserved.
+
+# Virtual Streaming Interface instance 7 Python script
+
+##@addtogroup arm_vsi_py_vstream_video
+# @{
+#
+##@package arm_vsi7_vstream_video
+#Documentation for VSI vStream Video module.
+#
+#More details.
+
+import logging
+import vsi_video
+
+logger = logging.getLogger(__name__)
+vsi_video.logger = logger
+
+## Set verbosity level
+#verbosity = logging.DEBUG
+#verbosity = logging.INFO
+#verbosity = logging.WARNING
+verbosity = logging.ERROR
+
+# [debugging] Verbosity settings
+level = { 10: "DEBUG", 20: "INFO", 30: "WARNING", 40: "ERROR" }
+logging.basicConfig(format='Py: %(name)s : [%(levelname)s]\t%(message)s', level = verbosity)
+logger.info("Verbosity level is set to " + level[verbosity])
+
+
+# Video Server configuration
+server_address = ('127.0.0.1', 6007)
+server_authkey = 'vsi_video'
+
+
+# IRQ registers
+IRQ_Status = 0
+
+# Timer registers
+Timer_Control = 0
+Timer_Interval = 0
+
+# Timer Control register definitions
+Timer_Control_Run_Msk = 1<<0
+Timer_Control_Periodic_Msk = 1<<1
+Timer_Control_Trig_IRQ_Msk = 1<<2
+Timer_Control_Trig_DMA_Msk = 1<<3
+
+# DMA registers
+DMA_Control = 0
+
+# DMA Control register definitions
+DMA_Control_Enable_Msk = 1<<0
+DMA_Control_Direction_Msk = 1<<1
+DMA_Control_Direction_P2M = 0<<1
+DMA_Control_Direction_M2P = 1<<1
+
+# User registers
+Regs = [0] * 64
+
+# Data buffer
+Data = bytearray()
+
+# Streaming Server Connection Status
+Server_Connected = False
+
+
+
+## Initialize
+# @return None
+def init():
+ global Server_Connected
+ logger.info("init() called")
+
+ Server_Connected = vsi_video.init(server_address, server_authkey)
+
+
+## Read interrupt request (the VSI IRQ Status Register)
+# @return value value read (32-bit)
+def rdIRQ():
+ global IRQ_Status
+ logger.info("rdIRQ() called")
+
+ value = IRQ_Status
+ logger.debug(f"Read IRQ_Status: 0x{value:08X}")
+
+ return value
+
+
+## Write interrupt request (the VSI IRQ Status Register)
+# @param value value to write (32-bit)
+# @return value value written (32-bit)
+def wrIRQ(value):
+ global IRQ_Status
+ logger.info(f"wrIRQ(value=0x{value:08X}) called")
+
+ IRQ_Status = value
+ logger.debug(f"wrIRQ: write IRQ_Status: 0x{value:08X}")
+
+ return value
+
+
+## Write Timer registers (the VSI Timer Registers)
+# @param index Timer register index (zero based)
+# @param value value to write (32-bit)
+# @return value value written (32-bit)
+def wrTimer(index, value):
+ global Timer_Control, Timer_Interval
+ logger.info(f"wrTimer(index={index}, value=0x{value:08X}) called")
+
+ if index == 0:
+ Timer_Control = value
+ logger.debug(f"wrTimer: write Timer_Control: 0x{value:08X}")
+ elif index == 1:
+ Timer_Interval = value
+ logger.debug(f"wrTimer: write Timer_Interval: 0x{value:08X}")
+
+ return value
+
+
+## Timer event (called at Timer Overflow)
+# @return None
+def timerEvent():
+ logger.info("timerEvent() called")
+
+ if Server_Connected:
+ vsi_video.timerEvent()
+
+
+## Write DMA registers (the VSI DMA Registers)
+# @param index DMA register index (zero based)
+# @param value value to write (32-bit)
+# @return value value written (32-bit)
+def wrDMA(index, value):
+ global DMA_Control
+ logger.info(f"wrDMA(index={index}, value=0x{value:08X}) called")
+
+ if index == 0:
+ DMA_Control = value
+ logger.debug(f"wrDMA: write DMA_Control: 0x{value:08X}")
+
+ return value
+
+
+## Read data from peripheral for DMA P2M transfer (VSI DMA)
+# @param size size of data to read (in bytes, multiple of 4)
+# @return data data read (bytearray)
+def rdDataDMA(size):
+ global Data
+ logger.info(f"rdDataDMA(size={size}) called")
+
+ if Server_Connected:
+ Data = vsi_video.rdDataDMA(size)
+
+ n = min(len(Data), size)
+ data = bytearray(size)
+ data[0:n] = Data[0:n]
+ logger.debug(f"rdDataDMA: read data ({size} bytes)")
+
+ return data
+
+
+## Write data to peripheral for DMA M2P transfer (VSI DMA)
+# @param data data to write (bytearray)
+# @param size size of data to write (in bytes, multiple of 4)
+# @return None
+def wrDataDMA(data, size):
+ global Data
+ logger.info(f"wrDataDMA(data={type(data).__name__}, size={size}) called")
+
+ Data = data
+ logger.debug(f"wrDataDMA: write data ({size} bytes)")
+
+ if Server_Connected:
+ vsi_video.wrDataDMA(data, size)
+
+ return
+
+
+## Read user registers (the VSI User Registers)
+# @param index user register index (zero based)
+# @return value value read (32-bit)
+def rdRegs(index):
+ global Regs
+ logger.info(f"rdRegs(index={index}) called")
+
+ if Server_Connected:
+ Regs[index] = vsi_video.rdRegs(index)
+
+ value = Regs[index]
+
+ # Log the value read from the register
+ logger.debug(f"rdRegs: read Regs[{index}]: 0x{value:08X}")
+
+ return value
+
+
+## Write user registers (the VSI User Registers)
+# @param index user register index (zero based)
+# @param value value to write (32-bit)
+# @return value value written (32-bit)
+def wrRegs(index, value):
+ global Regs
+ logger.info(f"wrRegs(index={index}, value=0x{value:08X}) called")
+
+ if Server_Connected:
+ value = vsi_video.wrRegs(index, value)
+
+ Regs[index] = value
+
+ # Log the value written to the register
+ logger.debug(f"wrRegs: write Regs[{index}] = 0x{value:08X}")
+
+ return value
+
+
+## @}
diff --git a/board/Corstone-300/vsi/python/vsi_audio.py b/board/Corstone-300/vsi/python/vsi_audio.py
new file mode 100644
index 0000000..a71574a
--- /dev/null
+++ b/board/Corstone-300/vsi/python/vsi_audio.py
@@ -0,0 +1,543 @@
+# Copyright (c) 2025 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.
+
+# Python VSI Audio Client module
+# This module provides a client interface for communicating with a VSI (Virtual Streaming Interface) audio server.
+# It allows configuration, streaming, and audio data transfer operations, typically used in hardware simulation or testing environments.
+
+try:
+ import time
+ import atexit
+ import logging
+ import subprocess
+ from multiprocessing.connection import Client, Connection
+ from os import path, getcwd
+ from os import name as os_name
+except ImportError as err:
+ print(f"VSI:Audio:ImportError: {err}")
+ raise
+except Exception as e:
+ print(f"VSI:Audio:Exception: {type(e).__name__}")
+ raise
+
+logger = logging.getLogger(__name__)
+
+
+class AudioClient:
+ """
+ Client for communicating with the VSI audio server using Python's multiprocessing connection.
+ Provides methods to configure the stream, send/receive audio data, and control the server.
+ """
+ def __init__(self):
+ # Server command codes
+ self.SET_MODE = 1
+ self.SET_DEVICE = 2
+ self.SET_FILENAME = 3
+ self.STREAM_CONFIGURE = 4
+ self.STREAM_ENABLE = 5
+ self.STREAM_DISABLE = 6
+ self.AUDIO_READ = 7
+ self.AUDIO_WRITE = 8
+ self.CLOSE_SERVER = 9
+
+ # Audio format codes
+ self.PCM_S8 = 0
+ self.PCM_S16LE = 1
+ self.PCM_S24LE = 2
+ self.PCM_S32LE = 3
+ self.PCM_F32LE = 4
+
+ # Connection object
+ self.conn = None
+
+ def connectToServer(self, address, authkey):
+ """
+ Attempt to connect to the VSI audio server at the given address with the provided authkey.
+
+ Args:
+ address: The (IP, port) tuple for the server to connect to.
+ authkey: The authorization key for server connection.
+ Returns:
+ None
+ """
+ for _ in range(50):
+ try:
+ self.conn = Client(address, authkey=authkey.encode('utf-8'))
+ if isinstance(self.conn, Connection):
+ break
+ else:
+ self.conn = None
+ except Exception:
+ self.conn = None
+ time.sleep(0.01)
+
+ def setMode(self, mode):
+ """
+ Set the mode of the audio stream (input/output).
+ Args:
+ mode: 1 for input, 2 for output.
+ Returns:
+ True if the mode is valid, False otherwise.
+ """
+ self.conn.send([self.SET_MODE, mode])
+ mode_valid = self.conn.recv()
+
+ return mode_valid
+
+ def setDevice(self, device):
+ """
+ Set the audio streaming device index (input/output).
+ Args:
+ device: The device index value to set on the server.
+ Returns:
+ Device index actually set.
+ """
+ self.conn.send([self.SET_DEVICE, device])
+ device_index = self.conn.recv()
+
+ return device_index
+
+ def setFilename(self, filename):
+ """
+ Set the filename for the audio stream on the server.
+ Args:
+ filename: The name of the file to set on the server.
+ Returns:
+ True if the filename is valid, False otherwise.
+ """
+ self.conn.send([self.SET_FILENAME, getcwd(), filename])
+ filename_valid = self.conn.recv()
+
+ return filename_valid
+
+ def configureStream(self, channels, sample_rate, sample_bits):
+ """
+ Configure the audio stream parameters on the server.
+ Args:
+ channels: Number of audio channels (1=mono, 2=stereo).
+ sample_rate: Sample rate in Hz (e.g., 44100, 48000).
+ sample_bits: Bit depth (8, 16, 24, 32).
+ Returns:
+ True if configuration is valid, False otherwise.
+ """
+ self.conn.send([self.STREAM_CONFIGURE, channels, sample_rate, sample_bits])
+ configuration_valid = self.conn.recv()
+
+ return configuration_valid
+
+ def enableStream(self):
+ """
+ Enable the audio stream on the server in the specified mode (input/output).
+ Returns:
+ `True` if the stream is active, `False` otherwise.
+ """
+ self.conn.send([self.STREAM_ENABLE])
+ stream_active = self.conn.recv()
+
+ return stream_active
+
+ def disableStream(self):
+ """
+ Disable the audio stream on the server.
+ Returns:
+ True if the stream is no longer active, False otherwise.
+ """
+ self.conn.send([self.STREAM_DISABLE])
+ stream_active = self.conn.recv()
+
+ return stream_active
+
+ def readAudio(self, size):
+ """
+ Request audio data from the server.
+ Args:
+ size: Number of bytes to read.
+ Returns:
+ tuple: (data, eos) where data is a Bytearray of audio data and eos is a Boolean indicating end-of-stream.
+ """
+ self.conn.send([self.AUDIO_READ, size])
+ data = self.conn.recv_bytes()
+ eos = self.conn.recv()
+
+ return data, eos
+
+ def writeAudio(self, data):
+ """
+ Send audio data to the server.
+ Args:
+ data: Bytearray of audio data to write.
+ Returns:
+ None
+ """
+ self.conn.send([self.AUDIO_WRITE])
+ self.conn.send_bytes(data)
+
+ def closeServer(self):
+ """
+ Close the connection to the server and request server shutdown.
+ Returns:
+ None
+ """
+ try:
+ if isinstance(self.conn, Connection):
+ self.conn.send([self.CLOSE_SERVER])
+ self.conn.close()
+ except Exception as e:
+ logger.error(f'Exception occurred on cleanup: {e}')
+
+
+
+# User register variables (simulate hardware registers for VSI peripheral)
+CONTROL = 0 # Regs[0] // Control: enable, mode, continuous
+STATUS = 0 # Regs[1] // Status: active, eos, file_name, file_valid
+DEVICE = -1 # Regs[2] // Streaming device
+FILENAME = "" # Regs[3] // Filename string array
+CHANNELS = 1 # Regs[4] // Number of audio channels
+SAMPLE_RATE = 16000 # Regs[5] // Sample rate
+SAMPLE_BITS = 16 # Regs[6] // Bits per sample
+
+
+# CONTROL register bit definitions
+CONTROL_ENABLE_Pos = 0
+CONTROL_ENABLE_Msk = 1<> CONTROL_MODE_Pos)
+ if mode_valid:
+ logger.info("wrCONTROL: CONTROL register updated: MODE changed")
+ else:
+ # Reset Mode
+ Audio.setMode(0)
+ value &= ~CONTROL_MODE_Msk
+ logger.error("wrCONTROL: CONTROL register updated: MODE cleared")
+
+ if ((value ^ CONTROL) & CONTROL_ENABLE_Msk) != 0:
+ # ENABLE bit changed
+ if (value & CONTROL_ENABLE_Msk) != 0:
+ logger.info("wrCONTROL: CONTROL register updated: ENABLE bit set")
+
+ # Configure stream
+ configuration_valid = Audio.configureStream(CHANNELS, SAMPLE_RATE, SAMPLE_BITS)
+ if configuration_valid:
+ # Configuration is valid, enable stream
+ server_active = Audio.enableStream()
+
+ if server_active:
+ STATUS |= STATUS_ACTIVE_Msk
+ STATUS &= ~STATUS_EOS_Msk
+ else:
+ logger.error("wrCONTROL: enable stream failed")
+ else:
+ logger.error("wrCONTROL: configure stream failed")
+ else:
+ logger.info("wrCONTROL: CONTROL register updated: ENABLE bit cleared")
+ Audio.disableStream()
+
+ STATUS &= ~STATUS_ACTIVE_Msk
+ logger.info("wrCONTROL: STATUS register updated: ACTIVE bit cleared")
+
+ CONTROL = value
+
+
+def rdSTATUS():
+ """
+ Read the STATUS register (user register).
+
+ Returns:
+ status: Current STATUS register value (32-bit)
+ """
+ global STATUS
+ logger.info(f"rdSTATUS: read STATUS: 0x{STATUS:08X}")
+ value = STATUS
+
+ # Clear DATA bit on read of STATUS register
+ STATUS &= ~STATUS_DATA_Msk
+ logger.debug("rdSTATUS: STATUS register updated: DATA bit cleared")
+
+ return value
+
+
+def wrDEVICE(value):
+ """
+ Write DEVICE register (user register).
+ Write is ignored if value to write equals to -1.
+
+ Args:
+ value: Device index to set.
+ Returns:
+ None
+ """
+ global DEVICE
+ DEVICE = Audio.setDevice(value)
+ logger.info(f"wrDEVICE: DEVICE register set to {DEVICE}")
+
+
+def rdFILENAME():
+ """
+ Read FILENAME register (user register).
+
+ Returns:
+ filename_len: Length of the filename string
+ """
+ global FILENAME
+ value = len(FILENAME)
+ logger.info(f"rdFILENAME: read FILENAME length: {value}")
+ return value
+
+
+def wrFILENAME(value):
+ """
+ Write FILENAME register (user register).
+
+ Append character represented by argument `value` to the filename string.
+ Write 0 to set a null terminator.
+ First character received after null terminator starts a new filename.
+ Args:
+ value: Character to append (as string or int)
+ Returns:
+ None
+ """
+ global FILENAME, STATUS
+
+ char = chr(value)
+
+ if STATUS & STATUS_FILE_NAME_Msk:
+ # Clear file related flags and reset filename
+ STATUS &= ~(STATUS_FILE_NAME_Msk | STATUS_FILE_VALID_Msk)
+ logger.debug("wrFILENAME: STATUS register updated: FILE_NAME and FILE_VALID bits cleared")
+
+ FILENAME = ""
+ logger.info("wrFILENAME: FILENAME register reset")
+
+ if char != '\0':
+ # Got character to append
+ logger.debug(f"wrFILENAME: append {char} to filename")
+ FILENAME += f"{char}"
+ else:
+ # Got null terminator
+ logger.info(f"wrFILENAME: filename: {FILENAME}")
+
+ STATUS |= STATUS_FILE_NAME_Msk
+ logger.debug("wrFILENAME: STATUS register updated: FILE_NAME bit set")
+
+ if Audio.setFilename(FILENAME) == True:
+ STATUS |= STATUS_FILE_VALID_Msk
+ logger.debug("wrFILENAME: STATUS register updated: FILE_VALID bit set")
+ else:
+ logger.error("wrFILENAME: Filename validation failed, file not found on server")
+
+
+def rdRegs(index):
+ """
+ Read user registers (the VSI User Registers).
+
+ Read the value of a user register by index.
+ Args:
+ index: User register index (zero based)
+ Returns:
+ value: Value read (32-bit)
+ """
+ global CONTROL, DEVICE, CHANNELS, SAMPLE_RATE, SAMPLE_BITS
+ value = 0
+
+ if index == 0:
+ value = CONTROL
+ elif index == 1:
+ value = rdSTATUS()
+ elif index == 2:
+ value = DEVICE
+ elif index == 3:
+ value = rdFILENAME()
+ elif index == 4:
+ value = CHANNELS
+ elif index == 5:
+ value = SAMPLE_RATE
+ elif index == 6:
+ value = SAMPLE_BITS
+
+ return value
+
+
+def wrRegs(index, value):
+ """
+ Write user registers (the VSI User Registers).
+
+ Write a value to a user register by index.
+ Args:
+ index: User register index (zero based)
+ value: Value to write (32-bit)
+ Returns:
+ value: Value written (32-bit)
+ """
+ global STATUS, CHANNELS, SAMPLE_RATE, SAMPLE_BITS
+
+ if index == 0:
+ wrCONTROL(value)
+ elif index == 1:
+ value = STATUS
+ elif index == 2:
+ wrDEVICE(value)
+ elif index == 3:
+ wrFILENAME(value)
+ elif index == 4:
+ CHANNELS = value
+ elif index == 5:
+ SAMPLE_RATE = value
+ elif index == 6:
+ SAMPLE_BITS = value
+
+ return value
diff --git a/board/Corstone-300/vsi/python/vsi_audio_server.py b/board/Corstone-300/vsi/python/vsi_audio_server.py
new file mode 100644
index 0000000..dafa594
--- /dev/null
+++ b/board/Corstone-300/vsi/python/vsi_audio_server.py
@@ -0,0 +1,691 @@
+# Copyright (c) 2025 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.
+
+# Python VSI Audio Server module
+
+try:
+ import argparse
+ import ipaddress
+ import logging
+ import time
+ import wave
+ from multiprocessing.connection import Listener
+ from pathlib import Path
+
+ import pyaudio
+ import numpy as np
+except ImportError as err:
+ print(f"VSI:Audio:Server:ImportError: {err}")
+except Exception as e:
+ print(f"VSI:Audio:Server:Exception: {type(e).__name__}")
+
+logger = logging.getLogger(__name__)
+
+## Set verbosity level
+#verbosity = logging.DEBUG
+#verbosity = logging.INFO
+#verbosity = logging.WARNING
+verbosity = logging.ERROR
+
+# [debugging] Verbosity settings
+level = { 10: "DEBUG", 20: "INFO", 30: "WARNING", 40: "ERROR" }
+logging.basicConfig(format='VSI Audio Server: [%(levelname)s]\t%(message)s', level = verbosity)
+logger.info("Verbosity level is set to " + level[verbosity])
+
+# Default Server configuration
+default_address = ('127.0.0.1', 6001)
+default_authkey = 'vsi_audio'
+
+# Supported file extensions
+supported_files = ['wav']
+
+# Mode Input/Output
+MODE_AUDIO_NONE = 0
+MODE_AUDIO_INPUT = 1
+MODE_AUDIO_OUTPUT = 2
+
+class AudioServer:
+ """Implements a TCP server for audio streaming and sample I/O.
+
+ Supports both audio files and microphone/speaker devices as input/output.
+ Listens for commands from a client (such as setting mode, filename, configuring stream,
+ enabling/disabling stream, reading/writing audio data), and performs the requested audio
+ operations using PyAudio and wave modules.
+ """
+ def __init__(self, address, authkey):
+ """
+ Initialize the AudioServer.
+
+ Sets up command codes, audio format constants, and initializes all state variables.
+ Creates a Listener object for incoming client connections.
+ Args:
+ address: The (IP, port) tuple for the server to listen on.
+ authkey: The authorization key for client connections.
+ Returns:
+ None
+ """
+ # Server commands
+ self.SET_MODE = 1
+ self.SET_DEVICE = 2
+ self.SET_FILENAME = 3
+ self.STREAM_CONFIGURE = 4
+ self.STREAM_ENABLE = 5
+ self.STREAM_DISABLE = 6
+ self.AUDIO_READ = 7
+ self.AUDIO_WRITE = 8
+ self.CLOSE_SERVER = 9
+
+ # Variables
+ self.listener = Listener(address, authkey=authkey.encode('utf-8'))
+ self.device = 0
+ self.filename = None
+ self.mode = None
+ self.active = False
+ self.eos = False
+ self.stream = None
+ self.wave_file = None
+ self.pyaudio_obj = pyaudio.PyAudio()
+ self.audio_buffer = bytearray()
+ self.chunk_size = 1024
+
+ # Stream configuration
+ self.channels = None
+ self.sample_rate = None
+ self.sample_bits = None
+
+ def _setMode(self, mode):
+ """
+ Set the stream mode to input (microphone/file) or output (speakers/file).
+
+ Args:
+ mode: The I/O mode (input or output).
+ """
+ mode_valid = False
+
+ if mode == MODE_AUDIO_INPUT:
+ self.mode = MODE_AUDIO_INPUT
+ logger.info("_setMode: set stream mode to Input")
+ mode_valid = True
+
+ elif mode == MODE_AUDIO_OUTPUT:
+ self.mode = MODE_AUDIO_OUTPUT
+ logger.info("_setMode: set stream mode to Output")
+ mode_valid = True
+
+ else:
+ self.mode = MODE_AUDIO_NONE
+ logger.error("_setMode: invalid mode")
+
+ return mode_valid
+
+ def _setDevice(self, device):
+ """
+ Set the streaming device index for input/output.
+
+ Sets the device index to the specified value, or
+ scans for the default device if -1 (0xFFFFFFFF) is given.
+
+ Args:
+ device: The device index to set.
+ Returns:
+ Device index actually set.
+ """
+ logger.debug(f"_setDevice: device={device}")
+
+ if (device == 4294967295): # -1 as unsigned 32-bit
+ # Set device index to point to default device for the selected mode
+ self.device = self._scan_audio_devices()
+ else:
+ # Set device index to the specified value
+ self.device = device
+
+ logger.info(f"_setDevice: streaming device set to {self.device}")
+
+ return self.device
+
+ def _setFilename(self, base_dir, filename):
+ """
+ Set the filename for input or output file.
+
+ Checks file extension to determine if file format is supported.
+ For input: verifies file exists and is supported.
+ For output: removes existing file if present.
+ Args:
+ base_dir: The base directory for the file.
+ filename: The name of the file (with extension).
+ Returns:
+ filename_valid: True if the filename is valid and set, False otherwise.
+ """
+ logger.debug(f"_setFilename: base_dir={base_dir}, filename={filename}")
+
+ filename_valid = False
+
+ self.filename = None
+
+ if filename == "":
+ # Empty filename is valid (use microphone/speakers)
+ return True
+
+ work_dir = Path(base_dir)
+ file_name = Path(filename)
+ file_path = Path("")
+
+ # Check if file extension is supported
+ ext = file_name.suffix.lstrip('.').lower()
+ if ext not in supported_files:
+ logger.error(f"_setFilename: unsupported file extension={ext}")
+ return filename_valid
+
+ # Check if filename is absolute path
+ if file_name.is_absolute():
+ # Absolute path provided
+ file_path = file_name
+ logger.debug(f"_setFilename: absolute path provided, file path={file_path}")
+ else:
+ # Relative path provided, create full path
+ file_path = work_dir / file_name
+ logger.debug(f"_setFilename: relative path provided, file path={file_path}")
+
+ # Normalize the file path
+ file_path = file_path.resolve()
+
+ if self.mode == MODE_AUDIO_INPUT:
+ # Check if the file exists
+ if Path(file_path).exists():
+ # File exists
+ filename_valid = True
+ else:
+ logger.error(f"_setFilename: file does not exist: {file_path}")
+
+ if self.mode == MODE_AUDIO_OUTPUT:
+ # Check if the file exists
+ if Path(file_path).exists():
+ # Remove existing file
+ Path(file_path).unlink(missing_ok=True)
+
+ filename_valid = True
+
+ if filename_valid:
+ # Set server side filename
+ self.filename = file_path
+ logger.info(f"_setFilename: filename set to {self.filename}")
+
+ return filename_valid
+
+ def _configureStream(self, channels, sample_rate, sample_bits):
+ """
+ Configure the audio stream parameters.
+
+ Args:
+ channels: The number of audio channels (1=mono, 2=stereo).
+ sample_rate: The sample rate in Hz (8000, 16000, 44100, 48000).
+ sample_bits: The bit depth (8, 16, 24, 32).
+ Returns:
+ configuration_valid: True if the configuration is valid and set, False otherwise.
+ """
+ logger.debug(f"_configureStream: channels={channels}, sample_rate={sample_rate}, sample_bits={sample_bits}")
+
+ if channels <= 0 or sample_rate <= 0 or sample_bits <= 0:
+ logger.error(f"_configureStream: invalid argument (channels={channels}, sample_rate={sample_rate}, sample_bits={sample_bits})")
+ return False
+
+ if sample_bits not in [8, 16, 24, 32]:
+ logger.error(f"_configureStream: unsupported sample_bits={sample_bits}")
+ return False
+
+ self.channels = channels
+ self.sample_rate = sample_rate
+ self.sample_bits = sample_bits
+
+ logger.info(f"_configureStream: stream configured to {self.channels} channels, {self.sample_rate}Hz, {self.sample_bits} bits")
+
+ return True
+
+ def _get_pyaudio_format(self):
+ """Get PyAudio format based on sample bits."""
+ if self.sample_bits == 8:
+ return pyaudio.paUInt8
+ elif self.sample_bits == 16:
+ return pyaudio.paInt16
+ elif self.sample_bits == 24:
+ return pyaudio.paInt24
+ elif self.sample_bits == 32:
+ return pyaudio.paInt32
+ else:
+ return pyaudio.paInt16 # default
+
+ def _scan_audio_devices(self):
+ """
+ Scan and log available audio devices, separating input and output devices.
+ Returns:
+ Default device index for the current mode.
+ """
+ if self.pyaudio_obj is None:
+ logger.error(" _scan_audio_devices: PyAudio object is not initialized")
+ return 0
+
+ logger.info("=== Available Audio Devices ===")
+ device_count = self.pyaudio_obj.get_device_count()
+
+ input_devices = []
+ output_devices = []
+
+ # Scan all devices
+ for i in range(device_count):
+ try:
+ info = self.pyaudio_obj.get_device_info_by_index(i)
+ host_api_info = self.pyaudio_obj.get_host_api_info_by_index(info['hostApi'])
+
+ device_info = {
+ 'index': i,
+ 'name': info['name'],
+ 'max_input_channels': info['maxInputChannels'],
+ 'max_output_channels': info['maxOutputChannels'],
+ 'default_sample_rate': info['defaultSampleRate'],
+ 'host_api': host_api_info['name']
+ }
+
+ # Categorize devices
+ if info['maxInputChannels'] > 0:
+ input_devices.append(device_info)
+ if info['maxOutputChannels'] > 0:
+ output_devices.append(device_info)
+
+ except Exception as e:
+ logger.warning(f"Device {i}: Error reading device info - {e}")
+
+ # Retrieve default devices
+ try:
+ default_input = self.pyaudio_obj.get_default_input_device_info()
+ default_output = self.pyaudio_obj.get_default_output_device_info()
+ except Exception as e:
+ logger.warning(f"Error getting default devices: {e}")
+
+ if (self.mode == MODE_AUDIO_INPUT):
+ # Log input devices
+ logger.info("--- INPUT DEVICES ---")
+ if input_devices:
+ for device in input_devices:
+ logger.debug(f"Device {device['index']}: {device['name']}")
+ logger.debug(f" - Input Channels: {device['max_input_channels']}")
+ logger.debug(f" - Sample Rate: {device['default_sample_rate']}")
+ else:
+ logger.info("No input devices found")
+
+ logger.info(f"Default Input Device: {default_input['index']} - {default_input['name']}")
+
+ rval = default_input['index']
+
+ if (self.mode == MODE_AUDIO_OUTPUT):
+ # Log output devices
+ logger.debug("--- OUTPUT DEVICES ---")
+ if output_devices:
+ for device in output_devices:
+ logger.debug(f"Device {device['index']}: {device['name']}")
+ logger.debug(f" - Output Channels: {device['max_output_channels']}")
+ logger.debug(f" - Sample Rate: {device['default_sample_rate']}")
+ else:
+ logger.info("No output devices found")
+
+ logger.info(f"Default Output Device: {default_output['index']} - {default_output['name']}")
+
+ rval = default_output['index']
+
+ return rval
+
+ def _audio_callback_input(self, in_data, frame_count, time_info, status):
+ """
+ Callback for PyAudio input stream.
+ """
+ logger.debug(f"_audio_callback_input: received {len(in_data)} bytes")
+
+ self.audio_buffer.extend(in_data)
+ return (None, pyaudio.paContinue)
+
+ def _audio_callback_output(self, in_data, frame_count, time_info, status):
+ """
+ Callback for PyAudio output stream.
+ """
+ logger.debug(f"_audio_callback_output: requested {frame_count} frames")
+
+ bytes_needed = frame_count * self.channels * (self.sample_bits // 8)
+ if len(self.audio_buffer) >= bytes_needed:
+ data = bytes(self.audio_buffer[:bytes_needed])
+ del self.audio_buffer[:bytes_needed]
+ else:
+ # Not enough data, return silence
+ data = b'\x00' * bytes_needed
+ return (data, pyaudio.paContinue)
+
+ def _enableStream(self):
+ """
+ Enable the audio stream for input (microphone/file) or output (file/speakers).
+
+ Initializes the PyAudio stream or wave file as needed.
+ Returns:
+ None
+ """
+ if self.mode != MODE_AUDIO_INPUT and self.mode != MODE_AUDIO_OUTPUT:
+ logger.error("_enableStream: invalid mode")
+ return
+
+ if self.active:
+ logger.info("_enableStream: stream already active")
+ return
+
+ self.eos = False
+ self.audio_buffer.clear()
+
+ try:
+ if self.filename == None:
+ # Use microphone/speakers
+ if self.pyaudio_obj is None:
+ logger.error("_enableStream: PyAudio object is not initialized")
+ return
+
+ audio_format = self._get_pyaudio_format()
+
+ if self.mode == MODE_AUDIO_INPUT:
+ logger.debug("_enableStream: use microphone for input streaming")
+ self.stream = self.pyaudio_obj.open(
+ format=audio_format,
+ channels=self.channels,
+ rate=self.sample_rate,
+ input=True,
+ input_device_index=self.device,
+ frames_per_buffer=self.chunk_size,
+ stream_callback=self._audio_callback_input
+ )
+ self.stream.start_stream()
+
+ elif self.mode == MODE_AUDIO_OUTPUT:
+ logger.debug("_enableStream: use speakers for output streaming")
+ self.stream = self.pyaudio_obj.open(
+ format=audio_format,
+ channels=self.channels,
+ rate=self.sample_rate,
+ output=True,
+ output_device_index=self.device,
+ frames_per_buffer=self.chunk_size,
+ stream_callback=self._audio_callback_output
+ )
+ self.stream.start_stream()
+
+ logger.info(f"_enableStream: audio device stream properties: channels={self.channels}, rate={self.sample_rate}, bits={self.sample_bits}")
+
+ else:
+ # Set file name string for audio file
+ file = str(self.filename.absolute())
+
+ logger.debug(f"_enableStream: use audio file: {file}")
+
+ if self.mode == MODE_AUDIO_INPUT:
+ self.wave_file = wave.open(file, 'rb')
+
+ # Verify file properties match configuration
+ file_channels = self.wave_file.getnchannels()
+ file_rate = self.wave_file.getframerate()
+ file_bits = self.wave_file.getsampwidth() * 8
+
+ if (file_channels != self.channels or file_rate != self.sample_rate or file_bits != self.sample_bits):
+ logger.warning(f"_enableStream: file properties ({file_channels}ch, {file_rate}Hz, {file_bits}bit) "
+ f"don't match configured ({self.channels}ch, {self.sample_rate}Hz, {self.sample_bits}bit)")
+
+ logger.info(f"_enableStream: input file properties: channels={file_channels}, rate={file_rate}, bits={file_bits}")
+
+ elif self.mode == MODE_AUDIO_OUTPUT:
+ self.wave_file = wave.open(file, 'wb')
+ self.wave_file.setnchannels(self.channels)
+ self.wave_file.setsampwidth(self.sample_bits // 8)
+ self.wave_file.setframerate(self.sample_rate)
+
+ logger.info(f"_enableStream: output file properties: channels={self.channels}, rate={self.sample_rate}, bits={self.sample_bits}")
+
+ self.active = True
+ logger.info("_enableStream: stream enabled")
+
+ except Exception as e:
+ logger.error(f"_enableStream: failed to enable stream: {e}")
+ self._disableStream()
+
+ def _disableStream(self):
+ """
+ Disable the audio stream and release resources.
+
+ Returns:
+ None
+ """
+ self.active = False
+
+ try:
+ if self.stream is not None:
+ if self.stream.is_active():
+ self.stream.stop_stream()
+ self.stream.close()
+ self.stream = None
+
+ if self.pyaudio_obj is not None:
+ self.pyaudio_obj.terminate()
+ self.pyaudio_obj = None
+
+ if self.wave_file is not None:
+ self.wave_file.close()
+ self.wave_file = None
+
+ except Exception as e:
+ logger.error(f"_disableStream: error during cleanup: {e}")
+
+ logger.info("_disableStream: stream disabled")
+
+ def _readAudio(self, size):
+ """
+ Read audio data from the current source.
+
+ Args:
+ size: Number of bytes to read.
+ Returns:
+ audio_data: The read audio data as a bytearray, or empty if no data is available.
+ """
+ logger.debug(f"_readAudio: size={size} bytes")
+
+ audio_data = bytearray()
+
+ if not self.active:
+ logger.error("_readAudio: stream not active")
+ return audio_data
+
+ if self.eos:
+ logger.debug("_readAudio: end of stream")
+ return audio_data
+
+ try:
+ if self.filename == None:
+ # Read from microphone buffer
+ while len(self.audio_buffer) < size:
+ # Wait for enough data
+ time.sleep(0.01) # Wait 10ms
+
+ # Now we have enough data
+ audio_data = bytearray(self.audio_buffer[:size])
+ del self.audio_buffer[:size]
+
+ logger.debug(f"_readAudio: read {len(audio_data)} bytes from microphone buffer")
+
+ else:
+ # Read from wave file
+ frames_to_read = size // (self.channels * (self.sample_bits // 8))
+ frames_data = self.wave_file.readframes(frames_to_read)
+
+ if len(frames_data) > 0:
+ audio_data = bytearray(frames_data)
+ logger.debug(f"_readAudio: read {len(audio_data)} bytes from file")
+ else:
+ self.eos = True
+ logger.debug("_readAudio: end of file reached")
+
+ except Exception as e:
+ logger.error(f"_readAudio: error reading audio data: {e}")
+
+ return audio_data
+
+ def _writeAudio(self, data):
+ """
+ Write audio data to the output destination (file or speakers).
+
+ Args:
+ data: The input audio data as a bytearray to be written.
+ Returns:
+ None
+ """
+ logger.debug(f"_writeAudio: audio data size={len(data)} bytes")
+
+ if not self.active:
+ logger.error("_writeAudio: stream not active")
+ return
+
+ try:
+ if self.filename == None:
+ # Write to speakers buffer
+ self.audio_buffer.extend(data)
+ logger.debug("_writeAudio: added data to speaker buffer")
+
+ else:
+ # Write to wave file
+ self.wave_file.writeframes(data)
+ logger.debug("_writeAudio: wrote data to file")
+
+ except Exception as e:
+ logger.error(f"_writeAudio: error writing audio data: {e}")
+
+ def run(self):
+ """
+ Main server loop.
+
+ Waits for a client connection, then processes commands in a loop.
+ Handles all supported commands: set filename, configure stream, enable/disable stream, read/write audio, close server.
+ Sends responses or audio data as appropriate.
+ """
+ logger.info("Audio server started")
+
+ try:
+ conn = self.listener.accept()
+ logger.info(f'Connection accepted {self.listener.address}')
+ except Exception:
+ logger.error("Connection not accepted")
+ return
+
+ while True:
+ try:
+ recv = conn.recv()
+ except EOFError:
+ return
+
+ cmd = recv[0] # Command
+ payload = recv[1:] # Payload
+
+ if cmd == self.SET_MODE:
+ mode_valid = self._setMode(payload[0])
+ conn.send(mode_valid)
+
+ elif cmd == self.SET_DEVICE:
+ device_valid = self._setDevice(payload[0])
+ conn.send(device_valid)
+
+ elif cmd == self.SET_FILENAME:
+ filename_valid = self._setFilename(payload[0], payload[1])
+ conn.send(filename_valid)
+
+ elif cmd == self.STREAM_CONFIGURE:
+ configuration_valid = self._configureStream(payload[0], payload[1], payload[2])
+ conn.send(configuration_valid)
+
+ elif cmd == self.STREAM_ENABLE:
+ self._enableStream()
+ conn.send(self.active)
+
+ elif cmd == self.STREAM_DISABLE:
+ self._disableStream()
+ conn.send(self.active)
+
+ elif cmd == self.AUDIO_READ:
+ size = payload[0]
+ audio_data = self._readAudio(size)
+ conn.send_bytes(audio_data)
+ conn.send(self.eos)
+
+ elif cmd == self.AUDIO_WRITE:
+ audio_data = conn.recv_bytes()
+ self._writeAudio(audio_data)
+
+ elif cmd == self.CLOSE_SERVER:
+ self.stop()
+
+ def stop(self):
+ """
+ Stop the audio server.
+
+ Releases all resources.
+ Returns:
+ None
+ """
+ self._disableStream()
+ self.listener.close()
+ logger.info("Audio server stopped")
+
+
+def ip(ip):
+ """
+ Validate that the input string is a valid IP address.
+ Args:
+ ip: The input IP address string to validate.
+ Returns:
+ ip: The validated IP address string. Raises an argparse.ArgumentTypeError if invalid.
+ """
+ try:
+ _ = ipaddress.ip_address(ip)
+ return ip
+ except:
+ raise argparse.ArgumentTypeError(f"Invalid IP address: {ip}!")
+
+def parse_arguments():
+ """
+ Parse command-line arguments for the audio server (IP, port, authkey).
+ Returns:
+ args: The parsed command-line arguments.
+ """
+ formatter = lambda prog: argparse.HelpFormatter(prog, max_help_position=41)
+ parser = argparse.ArgumentParser(formatter_class=formatter, description="VSI Audio Server")
+
+ parser_optional = parser.add_argument_group("optional")
+ parser_optional.add_argument("--ip", dest="ip", metavar="",
+ help=f"Server IP address (default: {default_address[0]})",
+ type=ip, default=default_address[0])
+ parser_optional.add_argument("--port", dest="port", metavar="",
+ help=f"TCP port (default: {default_address[1]})",
+ type=int, default=default_address[1])
+ parser_optional.add_argument("--authkey", dest="authkey", metavar="",
+ help=f"Authorization key (default: {default_authkey})",
+ type=str, default=default_authkey)
+
+ return parser.parse_args()
+
+if __name__ == '__main__':
+ args = parse_arguments()
+ Server = AudioServer((args.ip, args.port), args.authkey)
+ try:
+ Server.run()
+ except KeyboardInterrupt:
+ Server.stop()
diff --git a/board/Corstone-300/vsi/python/vsi_video.py b/board/Corstone-300/vsi/python/vsi_video.py
new file mode 100644
index 0000000..47a2af2
--- /dev/null
+++ b/board/Corstone-300/vsi/python/vsi_video.py
@@ -0,0 +1,547 @@
+# Copyright (c) 2023-2025 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.
+
+# Python VSI Video Client module
+# This module provides a client interface for communicating with a VSI (Virtual Streaming Interface) video server.
+# It allows configuration, streaming, and frame transfer operations for video data, typically used in hardware simulation or testing environments.
+
+try:
+ import time
+ import atexit
+ import logging
+ import subprocess
+ from multiprocessing.connection import Client, Connection
+ from os import path, getcwd
+ from os import name as os_name
+except ImportError as err:
+ print(f"VSI:Video:ImportError: {err}")
+ raise
+except Exception as e:
+ print(f"VSI:Video:Exception: {type(e).__name__}")
+ raise
+
+logger = logging.getLogger(__name__)
+
+
+class VideoClient:
+ """
+ Client for communicating with the VSI video server using Python's multiprocessing connection.
+ Provides methods to configure the stream, send/receive frames, and control the server.
+ """
+ def __init__(self):
+ # Server command codes
+ self.SET_MODE = 1
+ self.SET_DEVICE = 2
+ self.SET_FILENAME = 3
+ self.STREAM_CONFIGURE = 4
+ self.STREAM_ENABLE = 5
+ self.STREAM_DISABLE = 6
+ self.FRAME_READ = 7
+ self.FRAME_WRITE = 8
+ self.CLOSE_SERVER = 9
+ # Color space codes
+ self.GRAYSCALE8 = 0
+ self.RGB888 = 1
+ self.BGR565 = 2
+ self.YUV420 = 3
+ self.NV12 = 4
+ self.NV21 = 5
+ # Connection object
+ self.conn = None
+
+ def connectToServer(self, address, authkey):
+ """
+ Attempt to connect to the VSI video server at the given address with the provided authkey.
+
+ Args:
+ address: The (IP, port) tuple for the server to connect to.
+ authkey: The authorization key for server connection.
+ Returns:
+ None
+ """
+ for _ in range(50):
+ try:
+ self.conn = Client(address, authkey=authkey.encode('utf-8'))
+ if isinstance(self.conn, Connection):
+ break
+ else:
+ self.conn = None
+ except Exception:
+ self.conn = None
+ time.sleep(0.01)
+
+ def setMode(self, mode):
+ """
+ Set the mode of the video stream (input/output).
+ Args:
+ mode: 0 for input, 1 for output.
+ Returns:
+ True if the mode is valid, False otherwise.
+ """
+ self.conn.send([self.SET_MODE, mode])
+ mode_valid = self.conn.recv()
+
+ return mode_valid
+
+ def setDevice(self, device):
+ """
+ Set the video streaming device index (input/output).
+ Args:
+ device: The device index value to set on the server.
+ Returns:
+ Device index actually set.
+ """
+ self.conn.send([self.SET_DEVICE, device])
+ device_index = self.conn.recv()
+
+ return device_index
+
+ def setFilename(self, filename):
+ """
+ Set the filename for the video stream on the server.
+ Args:
+ filename: The name of the file to set on the server.
+ Returns:
+ True if the filename is valid, False otherwise.
+ """
+ self.conn.send([self.SET_FILENAME, getcwd(), filename])
+ filename_valid = self.conn.recv()
+
+ return filename_valid
+
+ def configureStream(self, frame_width, frame_height, frame_rate, color_format):
+ """
+ Configure the video stream parameters on the server.
+ Args:
+ frame_width: Width of the video frame.
+ frame_height: Height of the video frame.
+ frame_rate: Frame rate in frames per second.
+ color_format: Color format code.
+ Returns:
+ True if configuration is valid, False otherwise.
+ """
+ self.conn.send([self.STREAM_CONFIGURE, frame_width, frame_height, frame_rate, color_format])
+ configuration_valid = self.conn.recv()
+
+ return configuration_valid
+
+ def enableStream(self):
+ """
+ Enable the video stream on the server in the specified mode (input/output).
+ Returns:
+ `True` if the stream is active, `False` otherwise.
+ """
+ self.conn.send([self.STREAM_ENABLE])
+ stream_active = self.conn.recv()
+
+ return stream_active
+
+ def disableStream(self):
+ """
+ Disable the video stream on the server.
+ Returns:
+ True if the stream is no longer active, False otherwise.
+ """
+ self.conn.send([self.STREAM_DISABLE])
+ stream_active = self.conn.recv()
+
+ return stream_active
+
+ def readFrame(self):
+ """
+ Request a video frame from the server.
+ Returns:
+ tuple: (data, eos) where data is a Bytearray of frame data and eos is a Boolean indicating end-of-stream.
+ """
+ self.conn.send([self.FRAME_READ])
+ data = self.conn.recv_bytes()
+ eos = self.conn.recv()
+
+ return data, eos
+
+ def writeFrame(self, data):
+ """
+ Send a video frame to the server.
+ Args:
+ data: Bytearray of frame data to write.
+ Returns:
+ None
+ """
+ self.conn.send([self.FRAME_WRITE])
+ self.conn.send_bytes(data)
+
+ def closeServer(self):
+ """
+ Close the connection to the server and request server shutdown.
+ Returns:
+ None
+ """
+ try:
+ if isinstance(self.conn, Connection):
+ self.conn.send([self.CLOSE_SERVER])
+ self.conn.close()
+ except Exception as e:
+ logger.error(f'Exception occurred on cleanup: {e}')
+
+
+
+# User register variables (simulate hardware registers for VSI peripheral)
+CONTROL = 0 # Regs[0] // Control: enable, mode, continuous
+STATUS = 0 # Regs[1] // Status: active, eos, file_name, file_valid
+DEVICE = -1 # Regs[2] // Streaming device
+FILENAME = "" # Regs[3] // Filename string array
+FRAME_WIDTH = 300 # Regs[4] // Requested frame width
+FRAME_HEIGHT = 300 # Regs[5] // Requested frame height
+FRAME_RATE = 0 # Regs[6] // Frame rate
+FRAME_COLOR = 0 # Regs[7] // Frame color space
+
+
+# CONTROL register bit definitions
+CONTROL_ENABLE_Pos = 0
+CONTROL_ENABLE_Msk = 1<> CONTROL_MODE_Pos)
+ if mode_valid:
+ logger.info("wrCONTROL: CONTROL register updated: MODE changed")
+ else:
+ # Reset Mode
+ Video.setMode(0)
+ value &= ~CONTROL_MODE_Msk
+ logger.error("wrCONTROL: CONTROL register updated: MODE cleared")
+
+ if ((value ^ CONTROL) & CONTROL_ENABLE_Msk) != 0:
+ # ENABLE bit changed
+ if (value & CONTROL_ENABLE_Msk) != 0:
+ logger.info("wrCONTROL: CONTROL register updated: ENABLE bit set")
+
+ # Configure stream
+ configuration_valid = Video.configureStream(FRAME_WIDTH, FRAME_HEIGHT, FRAME_RATE, FRAME_COLOR)
+ if configuration_valid:
+ # Configuration is valid, enable stream
+ server_active = Video.enableStream()
+
+ if server_active:
+ STATUS |= STATUS_ACTIVE_Msk
+ STATUS &= ~STATUS_EOS_Msk
+ else:
+ logger.error("wrCONTROL: enable stream failed")
+ else:
+ logger.error("wrCONTROL: configure stream failed")
+ else:
+ logger.info("wrCONTROL: CONTROL register updated: ENABLE bit cleared")
+ Video.disableStream()
+
+ STATUS &= ~STATUS_ACTIVE_Msk
+ logger.info("wrCONTROL: STATUS register updated: ACTIVE bit cleared")
+
+ CONTROL = value
+
+
+def rdSTATUS():
+ """
+ Read the STATUS register (user register).
+
+ Returns:
+ status: Current STATUS register value (32-bit)
+ """
+ global STATUS
+ logger.info(f"rdSTATUS: read STATUS: 0x{STATUS:08X}")
+ value = STATUS
+
+ # Clear DATA bit on read of STATUS register
+ STATUS &= ~STATUS_DATA_Msk
+ logger.debug("rdSTATUS: STATUS register updated: DATA bit cleared")
+
+ return value
+
+
+def wrDEVICE(value):
+ """
+ Write DEVICE register (user register).
+ Write is ignored if value to write equals to -1.
+
+ Args:
+ value: Device index to set.
+ Returns:
+ None
+ """
+ global DEVICE
+ DEVICE = Video.setDevice(value)
+ logger.info(f"wrDEVICE: DEVICE register set to {DEVICE}")
+
+
+def rdFILENAME():
+ """
+ Read FILENAME register (user register).
+
+ Returns:
+ filename_len: Length of the filename string
+ """
+ global FILENAME
+ value = len(FILENAME)
+ logger.info(f"rdFILENAME: read FILENAME length: {value}")
+ return value
+
+
+def wrFILENAME(value):
+ """
+ Write FILENAME register (user register).
+
+ Append character represented by argument `value` to the filename string.
+ Write 0 to set a null terminator.
+ First character received after null terminator starts a new filename.
+ Args:
+ value: Character to append (as string or int)
+ Returns:
+ None
+ """
+ global FILENAME, STATUS
+
+ char = chr(value)
+
+ if STATUS & STATUS_FILE_NAME_Msk:
+ # Clear file related flags and reset filename
+ STATUS &= ~(STATUS_FILE_NAME_Msk | STATUS_FILE_VALID_Msk)
+ logger.debug("wrFILENAME: STATUS register updated: FILE_NAME and FILE_VALID bits cleared")
+
+ FILENAME = ""
+ logger.info("wrFILENAME: FILENAME register reset")
+
+ if char != '\0':
+ # Got character to append
+ logger.debug(f"wrFILENAME: append {char} to filename")
+ FILENAME += f"{char}"
+ else:
+ # Got null terminator
+ logger.info(f"wrFILENAME: filename: {FILENAME}")
+
+ STATUS |= STATUS_FILE_NAME_Msk
+ logger.debug("wrFILENAME: STATUS register updated: FILE_NAME bit set")
+
+ if Video.setFilename(FILENAME) == True:
+ STATUS |= STATUS_FILE_VALID_Msk
+ logger.debug("wrFILENAME: STATUS register updated: FILE_VALID bit set")
+ else:
+ logger.error("wrFILENAME: Filename validation failed, file not found on server")
+
+
+def rdRegs(index):
+ """
+ Read user registers (the VSI User Registers).
+
+ Read the value of a user register by index.
+ Args:
+ index: User register index (zero based)
+ Returns:
+ value: Value read (32-bit)
+ """
+ global CONTROL, DEVICE, FRAME_WIDTH, FRAME_HEIGHT, FRAME_RATE, FRAME_COLOR
+ value = 0
+
+ if index == 0:
+ value = CONTROL
+ elif index == 1:
+ value = rdSTATUS()
+ elif index == 2:
+ value = DEVICE
+ elif index == 3:
+ value = rdFILENAME()
+ elif index == 4:
+ value = FRAME_WIDTH
+ elif index == 5:
+ value = FRAME_HEIGHT
+ elif index == 6:
+ value = FRAME_RATE
+ elif index == 7:
+ value = FRAME_COLOR
+
+ return value
+
+
+def wrRegs(index, value):
+ """
+ Write user registers (the VSI User Registers).
+
+ Write a value to a user register by index.
+ Args:
+ index: User register index (zero based)
+ value: Value to write (32-bit)
+ Returns:
+ value: Value written (32-bit)
+ """
+ global STATUS, FRAME_WIDTH, FRAME_HEIGHT, FRAME_RATE, FRAME_COLOR
+
+ if index == 0:
+ wrCONTROL(value)
+ elif index == 1:
+ value = STATUS
+ elif index == 2:
+ wrDEVICE(value)
+ elif index == 3:
+ wrFILENAME(value)
+ elif index == 4:
+ FRAME_WIDTH = value
+ elif index == 5:
+ FRAME_HEIGHT = value
+ elif index == 6:
+ FRAME_RATE = value
+ elif index == 7:
+ FRAME_COLOR = value
+
+ return value
diff --git a/board/Corstone-300/vsi/python/vsi_video_server.py b/board/Corstone-300/vsi/python/vsi_video_server.py
new file mode 100644
index 0000000..3699eb3
--- /dev/null
+++ b/board/Corstone-300/vsi/python/vsi_video_server.py
@@ -0,0 +1,785 @@
+# Copyright (c) 2023-2025 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.
+
+# Python VSI Video Server module
+
+try:
+ import argparse
+ import ipaddress
+ import logging
+ from multiprocessing.connection import Listener
+ from pathlib import Path
+
+ import cv2
+ import numpy as np
+except ImportError as err:
+ print(f"VSI:Video:Server:ImportError: {err}")
+except Exception as e:
+ print(f"VSI:Video:Server:Exception: {type(e).__name__}")
+
+logger = logging.getLogger(__name__)
+
+## Set verbosity level
+#verbosity = logging.DEBUG
+#verbosity = logging.INFO
+#verbosity = logging.WARNING
+verbosity = logging.ERROR
+
+# [debugging] Verbosity settings
+level = { 10: "DEBUG", 20: "INFO", 30: "WARNING", 40: "ERROR" }
+logging.basicConfig(format='VSI Video Server: [%(levelname)s]\t%(message)s', level = verbosity)
+logger.info("Verbosity level is set to " + level[verbosity])
+
+# Default Server configuration
+default_address = ('127.0.0.1', 6000)
+default_authkey = 'vsi_video'
+
+# Supported file extensions
+video_file_extensions = ('wmv', 'avi', 'mp4')
+image_file_extensions = ('bmp', 'png', 'jpg')
+video_fourcc = {'wmv' : 'WMV1', 'avi' : 'MJPG', 'mp4' : 'mp4v'}
+
+# Mode Input/Output
+MODE_VIDEO_NONE = 0
+MODE_VIDEO_INPUT = 1
+MODE_VIDEO_OUTPUT = 2
+
+class VideoServer:
+ """Implements a TCP server for video streaming and frame I/O.
+
+ Supports both video and image files as input/output, and can interface with a camera device.
+ Listens for commands from a client (such as setting mode, filename, configuring stream,
+ enabling/disabling stream, reading/writing frames), and performs the requested video
+ operations using OpenCV.
+ """
+ def __init__(self, address, authkey):
+ """
+ Initialize the VideoServer.
+
+ Sets up command codes, color space constants, and initializes all state variables.
+ Creates a Listener object for incoming client connections.
+ Args:
+ address: The (IP, port) tuple for the server to listen on.
+ authkey: The authorization key for client connections.
+ Returns:
+ None
+ """
+ # Server commands
+ self.SET_MODE = 1
+ self.SET_DEVICE = 2
+ self.SET_FILENAME = 3
+ self.STREAM_CONFIGURE = 4
+ self.STREAM_ENABLE = 5
+ self.STREAM_DISABLE = 6
+ self.FRAME_READ = 7
+ self.FRAME_WRITE = 8
+ self.CLOSE_SERVER = 9
+ # Color space
+ self.GRAYSCALE8 = 0
+ self.RGB888 = 1
+ self.BGR565 = 2
+ self.YUV420 = 3
+ self.NV12 = 4
+ self.NV21 = 5
+ # Variables
+ self.listener = Listener(address, authkey=authkey.encode('utf-8'))
+ self.device = 0
+ self.filename = None
+ self.mode = None
+ self.active = False
+ self.video = True
+ self.stream = None
+ self.frame_ratio = 0
+ self.frame_drop = 0
+ self.eos = False
+ # Stream configuration
+ self.frame_width = None
+ self.frame_height = None
+ self.frame_color = None
+ self.frame_rate = None
+
+
+ def _setMode(self, mode):
+ """
+ Set the stream mode to input (camera/file) or output (display/file).
+
+ Args:
+ mode: The I/O mode (input or output).
+ """
+ mode_valid = False
+
+ if mode == MODE_VIDEO_INPUT:
+ self.mode = MODE_VIDEO_INPUT
+ logger.info("_setMode: set stream mode to Input")
+ mode_valid = True
+
+ elif mode == MODE_VIDEO_OUTPUT:
+ self.mode = MODE_VIDEO_OUTPUT
+ logger.info("_setMode: set stream mode to Output")
+ mode_valid = True
+
+ else:
+ self.mode = MODE_VIDEO_NONE
+ logger.error("_setMode: invalid mode")
+
+ return mode_valid
+
+ def _setDevice(self, device):
+ """
+ Set the streaming device index for input/output.
+
+ Sets the device index to the specified value, or
+ scans for the default device if -1 (0xFFFFFFFF) is given.
+
+ Args:
+ device: The device index to set.
+ Returns:
+ Device index actually set.
+ """
+ logger.debug(f"_setDevice: device={device}")
+
+ if (device == 4294967295): # -1 as unsigned 32-bit
+ # Set device index to point to default device for the selected mode
+ self.device = self._scan_video_devices()
+ else:
+ # Set device index to the specified value
+ self.device = device
+
+ logger.info(f"_setDevice: streaming device set to {self.device}")
+
+ return self.device
+
+ def _setFilename(self, base_dir, filename):
+ """
+ Set the filename for input or output file.
+
+ Checks file extension to determine if file format is supported.
+ For input: verifies file exists and is supported.
+ For output: removes existing file if present.
+ Args:
+ base_dir: The base directory for the file.
+ filename: The name of the file (with extension).
+ Returns:
+ filename_valid: True if the filename is valid and set, False otherwise.
+ """
+ logger.debug(f"_setFilename: base_dir={base_dir}, filename={filename}")
+
+ filename_valid = False
+
+ self.filename = None
+
+ if filename == "":
+ # Empty filename is valid (use microphone/speakers)
+ return True
+
+ work_dir = Path(base_dir)
+ file_name = Path(filename)
+ file_path = Path("")
+
+ # Check if file extension is supported
+ ext = file_name.suffix.lstrip('.').lower()
+ if ext not in video_file_extensions + image_file_extensions:
+ logger.error(f"_setFilename: unsupported file extension={ext}")
+ return filename_valid
+
+ # Check if filename is absolute path
+ if file_name.is_absolute():
+ # Absolute path provided
+ file_path = file_name
+ logger.debug(f"_setFilename: absolute path provided, file path={file_path}")
+ else:
+ # Relative path provided, create full path
+ file_path = work_dir / file_name
+ logger.debug(f"_setFilename: relative path provided, file path={file_path}")
+
+ # Normalize the file path
+ file_path = file_path.resolve()
+
+ if self.mode == MODE_VIDEO_INPUT:
+ # Check if the file exists
+ if Path(file_path).exists():
+ # File exists
+ filename_valid = True
+ else:
+ logger.error(f"_setFilename: file does not exist: {file_path}")
+
+ if self.mode == MODE_VIDEO_OUTPUT:
+ # Check if the file exists
+ if Path(file_path).exists():
+ # Remove existing file
+ Path(file_path).unlink(missing_ok=True)
+
+ filename_valid = True
+
+ if filename_valid:
+ # Set server side filename
+ self.filename = file_path
+ logger.info(f"_setFilename: filename set to {self.filename}")
+
+ return filename_valid
+
+ def _configureStream(self, frame_width, frame_height, frame_rate, frame_color):
+ """
+ Configure the video stream parameters.
+
+ Args:
+ frame_width: The desired frame width in pixels.
+ frame_height: The desired frame height in pixels.
+ frame_rate: The desired frame rate in frames per second.
+ frame_color: The desired frame color space (one of the defined constants).
+ Returns:
+ configuration_valid: True if the configuration is valid and set, False otherwise.
+ """
+ logger.debug(f"_configureStream: frame_width={frame_width}, frame_height={frame_height}, frame_rate={frame_rate}, frame_color={frame_color}")
+
+ if (frame_width == 0 or frame_height == 0 or frame_rate == 0):
+ logger.error(f"_configureStream: invalid argument (width={frame_width}, height={frame_height}, rate={frame_rate})")
+ return False
+ if frame_color not in (self.GRAYSCALE8, self.RGB888, self.BGR565, self.YUV420, self.NV12, self.NV21):
+ logger.error(f"_configureStream: invalid argument (color={frame_color})")
+ return False
+
+ self.frame_width = frame_width
+ self.frame_height = frame_height
+ self.frame_rate = frame_rate
+ self.frame_color = frame_color
+
+ logger.info(f"_configureStream: stream configured to {self.frame_width}x{self.frame_height}, fps={self.frame_rate}, color={self.frame_color}")
+
+ return True
+
+ def _scan_video_devices(self):
+ """
+ Scan and log available video input devices.
+ Returns:
+ Default device index for the current mode.
+ """
+ logger.info("=== Available Video Devices ===")
+
+ available_devices = []
+
+ # Test device indices 0-1 (covers built-in webcam + external camera)
+ for device_index in range(2):
+ try:
+ cap = cv2.VideoCapture(device_index)
+ if cap.isOpened():
+
+ # Get device properties
+ width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
+ height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
+ fps = cap.get(cv2.CAP_PROP_FPS)
+
+ device_info = {
+ 'index': device_index,
+ 'width': width,
+ 'height': height,
+ 'fps': fps,
+ }
+ available_devices.append(device_info)
+
+ logger.info(f"Device {device_index}: {width}x{height} @ {fps:.1f}fps")
+
+ cap.release()
+ except Exception as e:
+ logger.error(f"Error accessing device {device_index}: {e}")
+
+ if not available_devices:
+ logger.warning("No video devices found")
+ return -1
+ else:
+ logger.info(f"Found {len(available_devices)} input device(s)")
+ logger.info(f"Default Input Device: 0")
+
+ return 0
+
+ def _enableStream(self):
+ """
+ Enable the video stream for input (camera/file) or output (file/display).
+
+ Initializes the OpenCV VideoCapture or VideoWriter as needed.
+ Handles both new and existing files, and sets up frame dropping if input FPS > requested FPS.
+ Returns:
+ None
+ """
+
+ if self.mode != MODE_VIDEO_INPUT and self.mode != MODE_VIDEO_OUTPUT:
+ logger.error("_enableStream: invalid mode")
+ return
+
+ if self.active:
+ logger.info("_enableStream: stream already active")
+ return
+
+ self.eos = False
+ self.frame_ratio = 0
+ self.frame_drop = 0
+
+ if self.stream is not None:
+ self.stream.release()
+ self.stream = None
+
+ if self.filename == None:
+ self.video = True
+
+ if self.video:
+ if self.mode == MODE_VIDEO_INPUT:
+ # Input mode: read from camera or video file
+ if self.filename == None:
+ # No filename specified: use camera interface
+ logger.debug("_enableStream: use camera interface for input streaming")
+ self.stream = cv2.VideoCapture(self.device)
+
+ if not self.stream.isOpened():
+ logger.error("_enableStream: failed to open Camera interface")
+ return
+ else:
+ # Filename specified: use video file
+ logger.debug("_enableStream: use file interface for input streaming")
+ self.stream = cv2.VideoCapture(self.filename)
+
+ # Display stream properties
+ logger.info(f"_enableStream: source stream properties: width={self.stream.get(cv2.CAP_PROP_FRAME_WIDTH)}, height={self.stream.get(cv2.CAP_PROP_FRAME_HEIGHT)}, fps={self.stream.get(cv2.CAP_PROP_FPS)}")
+
+ # Get the video stream FPS
+ video_fps = self.stream.get(cv2.CAP_PROP_FPS)
+
+ if video_fps > self.frame_rate:
+ self.frame_ratio = video_fps / self.frame_rate
+ logger.debug(f"_enableStream: source/target frame ratio={self.frame_ratio}")
+
+ elif self.mode == MODE_VIDEO_OUTPUT:
+ # Output mode: write to video file or display window
+ if self.filename != None:
+ # Filename specified: output to file
+ logger.debug("_enableStream: output stream to a file")
+
+ extension = self.filename.suffix.lstrip('.').lower()
+ fourcc = cv2.VideoWriter_fourcc(*f'{video_fourcc[extension]}')
+
+ self.stream = cv2.VideoWriter(self.filename, fourcc, self.frame_rate, (self.frame_width, self.frame_height))
+ else:
+ logger.debug("_enableStream: output stream to display window")
+
+ self.active = True
+ logger.info("_enableStream: stream enabled")
+
+ def _disableStream(self):
+ """
+ Disable the video stream and release OpenCV resources.
+
+ For input streams, saves the current frame index for resuming later.
+ Returns:
+ None
+ """
+ self.active = False
+ if self.stream is not None:
+ # Clean-up stream resources and invalidate object
+ self.stream.release()
+ self.stream = None
+
+ logger.info("_disableStream: stream disabled")
+
+ def __cropFrame(self, frame, target_aspect_ratio):
+ """
+ Crop the input frame to match the specified aspect ratio.
+
+ Args:
+ frame: The input frame (as NumPy array) to be cropped.
+ aspect_ratio: The target aspect ratio (width/height).
+ Returns:
+ frame: The cropped frame.
+ """
+ logger.debug(f"__cropFrame: original_size=({frame.shape[1]}, {frame.shape[0]}), target_aspect_ratio={target_aspect_ratio}")
+
+ # NumPY array shape is (height, width, channels)
+ frame_h = frame.shape[0]
+ frame_w = frame.shape[1]
+
+ frame_aspect_ratio = frame_w / frame_h
+
+ if frame_aspect_ratio > target_aspect_ratio:
+ # Frame is wider than target -> crop left and right
+ new_w = int(frame_h * target_aspect_ratio)
+ left = (frame_w - new_w) // 2
+ right = left + new_w
+ cropped = frame[:, left:right]
+ else:
+ # Frame is taller than target -> crop top and bottom
+ new_h = int(frame_w / target_aspect_ratio)
+ top = (frame_h - new_h) // 2
+ bottom = top + new_h
+ cropped = frame[top:bottom, :]
+
+ logger.debug(f"__cropFrame: cropped_size=({cropped.shape[1]}, {cropped.shape[0]})")
+
+ return cropped
+
+ def __resizeFrame(self, frame, target_width, target_height):
+ """
+ Resize the input frame to the target width and height.
+
+ Args:
+ frame: The input frame (as NumPy array) to be resized.
+ target_width: The target width in pixels.
+ target_height: The target height in pixels.
+ Returns:
+ frame: The resized frame.
+ """
+ logger.debug(f"__resizeFrame: original_size=({frame.shape[1]}, {frame.shape[0]}), target_size=({target_width}, {target_height})")
+
+ try:
+ frame = cv2.resize(frame, (target_width, target_height))
+ except Exception as e:
+ logger.error(f"Error in resizeFrame(): {e}")
+
+ logger.debug(f"__resizeFrame: resized_size=({frame.shape[1]}, {frame.shape[0]})")
+
+ return frame
+
+ def __convertToBGR(self, frame):
+ """
+ Convert the input frame to BGR color space if needed.
+
+ Args:
+ frame: The input frame (as NumPy array) to be converted.
+ Returns:
+ frame: The converted frame in BGR color space.
+ """
+ if self.frame_color == self.RGB888:
+ # Convert RGB to BGR
+ logger.debug(f"__convertToBGR: converting frame from RGB to BGR")
+ frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
+ elif self.frame_color == self.GRAYSCALE8:
+ # Convert Grayscale to BGR
+ logger.debug(f"__convertToBGR: converting frame from Grayscale to BGR")
+ frame = cv2.cvtColor(frame, cv2.COLOR_GRAY2BGR)
+ elif self.frame_color == self.BGR565:
+ # Convert BGR565 to BGR
+ logger.debug(f"__convertToBGR: converting frame from BGR565 to BGR")
+ frame = cv2.cvtColor(frame, cv2.COLOR_BGR5652BGR)
+ elif self.frame_color == self.YUV420:
+ # Convert YUV420 to BGR
+ logger.debug(f"__convertToBGR: converting frame from YUV420 to BGR")
+ frame = cv2.cvtColor(frame, cv2.COLOR_YUV2BGR_I420)
+ elif self.frame_color == self.NV12:
+ # Convert NV12 to BGR
+ logger.debug(f"__convertToBGR: converting frame from NV12 to BGR")
+ frame = cv2.cvtColor(frame, cv2.COLOR_YUV2BGR_NV12)
+ elif self.frame_color == self.NV21:
+ # Convert NV21 to BGR
+ logger.debug(f"__convertToBGR: converting frame from NV21 to BGR")
+ frame = cv2.cvtColor(frame, cv2.COLOR_YUV2BGR_NV21)
+
+ return frame
+
+ def __convertFromBGR(self, frame):
+ """
+ Convert the input BGR frame to the specified color space if needed.
+
+ Args:
+ frame: The input frame (as NumPy array in BGR color space) to be converted.
+ Returns:
+ frame: The converted frame in the specified color space.
+ """
+ if self.frame_color == self.RGB888:
+ # Convert BGR to RGB
+ logger.debug(f"__convertFromBGR: converting frame from BGR to RGB")
+ frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
+ elif self.frame_color == self.GRAYSCALE8:
+ # Convert BGR to Grayscale
+ logger.debug(f"__convertFromBGR: converting frame from BGR to Grayscale")
+ frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
+ elif self.frame_color == self.BGR565:
+ # Convert BGR to BGR565
+ logger.debug(f"__convertFromBGR: converting frame from BGR to BGR565")
+ frame = cv2.cvtColor(frame, cv2.COLOR_BGR2BGR565)
+ elif self.frame_color == self.YUV420:
+ # Convert BGR to YUV420
+ logger.debug(f"__convertFromBGR: converting frame from BGR to YUV420")
+ frame = cv2.cvtColor(frame, cv2.COLOR_BGR2YUV_I420)
+ elif self.frame_color == self.NV12:
+ # Convert BGR to NV12
+ logger.debug(f"__convertFromBGR: converting frame from BGR to NV12")
+ frame = cv2.cvtColor(frame, cv2.COLOR_BGR2YUV_NV12)
+ elif self.frame_color == self.NV21:
+ # Convert BGR to NV21
+ logger.debug(f"__convertFromBGR: converting frame from BGR to NV21")
+ frame = cv2.cvtColor(frame, cv2.COLOR_BGR2YUV_NV21)
+
+ return frame
+
+ # Read frame from source
+ def _readFrame(self):
+ """Read a single frame from the current video or image source.
+
+ If the stream is not active or end-of-stream is reached, returns an empty bytearray.
+ For video sources, handles frame dropping to match requested frame rate.
+ For image sources, reads the image once and sets end-of-stream.
+ Resizes and converts color space as needed.
+ Returns:
+ frame: The read frame as a bytearray, or empty if no frame is available.
+ """
+ frame = bytearray()
+
+ # If the stream is not active, return empty frame
+ if not self.active:
+ logger.error("_readFrame: stream not active")
+ return frame
+
+ # If end-of-stream has been reached, return empty frame
+ if self.eos:
+ logger.debug("_readFrame: end of stream reached")
+ return frame
+
+ if self.video:
+ # Video source, read frame from the video stream
+ _, frame_in = self.stream.read() # Frame is numpy.ndarray, (height, width, channels), dtype=uint8
+
+ if frame_in is not None:
+ logger.debug(f"_readFrame: frame captured, size=({frame_in.shape[1]}, {frame_in.shape[0]})")
+
+ # Handle frame dropping if input FPS > requested FPS
+ if self.frame_ratio > 1:
+ # Accumulate fractional frames to drop
+ self.frame_drop += (self.frame_ratio - 1)
+
+ if self.frame_drop > 1:
+ logger.debug(f"_readFrame: frames to drop={self.frame_drop}")
+ drop = int(self.frame_drop // 1)
+
+ # Drop the required number of frames to match requested FPS
+ for i in range(drop):
+ _, _ = self.stream.read()
+ logger.debug(f"_readFrame: frames dropped={drop}")
+ self.frame_drop -= drop
+ logger.debug(f"_readFrame: frames left to drop={self.frame_drop}")
+ else:
+ # Frame not read, mark end-of-stream
+ self.eos = True
+ logger.debug("_readFrame: end of stream.")
+ else:
+ # For image sources, read the image once and set end-of-stream
+ frame_in = cv2.imread(self.filename)
+ self.eos = True
+ logger.debug("_readFrame: end of stream.")
+
+ if frame_in is not None:
+ target_width = self.frame_width
+ target_height = self.frame_height
+
+ frame_in_width = frame_in.shape[1]
+ frame_in_height = frame_in.shape[0]
+
+ # Check the target frame size aspect ratio
+ target_aspect_ratio = target_width / target_height
+ frame_aspect_ratio = frame_in_width / frame_in_height
+
+ if not np.isclose(frame_aspect_ratio, target_aspect_ratio, rtol=1e-3):
+ logger.debug(f"_readFrame: frame aspect ratio {frame_aspect_ratio:.2f} does not match target {target_aspect_ratio:.2f}, cropping frame")
+ frame_in = self.__cropFrame(frame_in, target_aspect_ratio)
+
+ # Update frame size after cropping
+ frame_in_width = frame_in.shape[1]
+ frame_in_height = frame_in.shape[0]
+
+ # Check the target frame size
+ if (frame_in_width != target_width) or (frame_in_height != target_height):
+ logger.debug(f"_readFrame: frame size ({frame_in_width}, {frame_in_height}) does not match target ({target_width}, {target_height}), resizing frame")
+ frame_in = self.__resizeFrame(frame_in, target_width, target_height)
+
+ # Convert frame color space to target color space
+ frame_in = self.__convertFromBGR(frame_in)
+
+ # Convert the frame to a bytearray for transmission
+ frame = bytearray(frame_in.tobytes())
+
+ return frame
+
+ def _writeFrame(self, frame):
+ """
+ Write a frame to the output destination (file or display window).
+
+ If filename is empty, displays the frame in a window.
+ If filename is set and video mode, writes frame to video file.
+ If filename is set and image mode, saves frame as image file.
+ Args:
+ frame: The input frame as a bytearray to be written.
+ Returns:
+ None
+ """
+ logger.debug(f"_writeFrame: frame size={len(frame)} bytes")
+
+ # If the stream is not active, do nothing
+ if not self.active:
+ logger.error("_writeFrame: stream not active")
+ return
+
+ try:
+ # Decode the frame from bytearray to a NumPy array
+ decoded_frame = np.frombuffer(frame, dtype=np.uint8)
+
+ # Reshape the decoded frame to match the target resolution
+ decoded_frame = decoded_frame.reshape((self.frame_height, self.frame_width, 3))
+ logger.debug(f"_writeFrame: decoded frame size=({decoded_frame.shape[1]}, {decoded_frame.shape[0]})")
+
+ # Convert color space to BGR
+ frame_out = self.__convertToBGR(decoded_frame)
+
+ if self.filename == None:
+ logger.debug("_writeFrame: display frame in window")
+ # If no filename, display the frame in a window
+ cv2.imshow(self.filename, frame_out)
+ cv2.waitKey(10)
+ else:
+ if self.video:
+ logger.debug("_writeFrame: write frame to video file")
+ # Write frame to video file
+ self.stream.write(np.uint8(frame_out))
+ else:
+ logger.debug("_writeFrame: write frame as image file")
+ # Write frame as image file
+ cv2.imwrite(self.filename, frame_out)
+
+ except Exception as e:
+ # Output exception debug information but continue
+ logger.error(f"Exception in _writeFrame: {type(e).__name__}: {e}", exc_info=True)
+ pass
+
+
+ def run(self):
+ """
+ Main server loop.
+
+ Waits for a client connection, then processes commands in a loop.
+ Handles all supported commands: set filename, configure stream, enable/disable stream, read/write frames, close server.
+ Sends responses or frame data as appropriate.
+ """
+ logger.info("Video server started")
+
+ try:
+ conn = self.listener.accept()
+ logger.info(f'Connection accepted {self.listener.address}')
+ except Exception:
+ logger.error("Connection not accepted")
+ return
+
+ while True:
+ try:
+ recv = conn.recv()
+ except EOFError:
+ return
+
+ cmd = recv[0] # Command
+ payload = recv[1:] # Payload
+
+ if cmd == self.SET_MODE:
+ mode_valid = self._setMode(payload[0])
+ conn.send(mode_valid)
+
+ elif cmd == self.SET_DEVICE:
+ device_valid = self._setDevice(payload[0])
+ conn.send(device_valid)
+
+ elif cmd == self.SET_FILENAME:
+ filename_valid = self._setFilename(payload[0], payload[1])
+ conn.send(filename_valid)
+
+ elif cmd == self.STREAM_CONFIGURE:
+ configuration_valid = self._configureStream(payload[0], payload[1], payload[2], payload[3])
+ conn.send(configuration_valid)
+
+ elif cmd == self.STREAM_ENABLE:
+ self._enableStream()
+ conn.send(self.active)
+
+ elif cmd == self.STREAM_DISABLE:
+ self._disableStream()
+ conn.send(self.active)
+
+ elif cmd == self.FRAME_READ:
+ frame = self._readFrame()
+ conn.send_bytes(frame)
+ conn.send(self.eos)
+
+ elif cmd == self.FRAME_WRITE:
+ frame = conn.recv_bytes()
+ self._writeFrame(frame)
+
+ elif cmd == self.CLOSE_SERVER:
+ self.stop()
+
+
+ def stop(self):
+ """
+ Stop the video server.
+
+ Releases all resources and closes any open windows.
+ Returns:
+ None
+ """
+ self._disableStream()
+ if (self.mode == MODE_VIDEO_OUTPUT) and (self.filename == None):
+ try:
+ cv2.destroyAllWindows()
+ except Exception:
+ pass
+ self.listener.close()
+ logger.info("Video server stopped")
+
+
+def ip(ip):
+ """
+ Validate that the input string is a valid IP address.
+ Args:
+ ip: The input IP address string to validate.
+ Returns:
+ ip: The validated IP address string. Raises an argparse.ArgumentTypeError if invalid.
+ """
+ try:
+ _ = ipaddress.ip_address(ip)
+ return ip
+ except:
+ raise argparse.ArgumentTypeError(f"Invalid IP address: {ip}!")
+
+def parse_arguments():
+ """
+ Parse command-line arguments for the video server (IP, port, authkey).
+ Returns:
+ args: The parsed command-line arguments.
+ """
+ formatter = lambda prog: argparse.HelpFormatter(prog, max_help_position=41)
+ parser = argparse.ArgumentParser(formatter_class=formatter, description="VSI Video Server")
+
+ parser_optional = parser.add_argument_group("optional")
+ parser_optional.add_argument("--ip", dest="ip", metavar="",
+ help=f"Server IP address (default: {default_address[0]})",
+ type=ip, default=default_address[0])
+ parser_optional.add_argument("--port", dest="port", metavar="",
+ help=f"TCP port (default: {default_address[1]})",
+ type=int, default=default_address[1])
+ parser_optional.add_argument("--authkey", dest="authkey", metavar="",
+ help=f"Authorization key (default: {default_authkey})",
+ type=str, default=default_authkey)
+
+ return parser.parse_args()
+
+if __name__ == '__main__':
+ args = parse_arguments()
+ Server = VideoServer((args.ip, args.port), args.authkey)
+ try:
+ Server.run()
+ except KeyboardInterrupt:
+ Server.stop()
diff --git a/board/Corstone-310/Board-U55.clayer.yml b/board/Corstone-310/Board-U55.clayer.yml
new file mode 100644
index 0000000..7445293
--- /dev/null
+++ b/board/Corstone-310/Board-U55.clayer.yml
@@ -0,0 +1,64 @@
+layer:
+ type: Board
+ description: Board setup for AI/ML with Ethos U55
+ for-board: ARM::V2M-MPS3-SSE-310
+ for-device: ARM::SSE-310-MPS3_FVP
+
+ connections:
+ - connect: Corstone-310
+ provides:
+ - CMSIS_USART
+ - CMSIS_VSTREAM_AUDIO_IN
+ - CMSIS_VSTREAM_AUDIO_OUT
+ - CMSIS_VSTREAM_VIDEO_IN
+ - CMSIS_VSTREAM_VIDEO_OUT
+ - STDOUT
+ - STDERR
+ - Heap: 786432
+
+ define:
+ - CMSIS_target_header: \"Corstone-310.h\"
+ - ETHOSU55
+ - ARM_MODEL_USE_PMU_COUNTERS
+
+ packs:
+ - pack: ARM::CMSIS
+ - pack: ARM::CMSIS-Compiler@^2.1.0
+ - pack: ARM::ethos-u-core-driver@^1.25.2
+ - pack: ARM::AVH_FVP
+ - pack: ARM::V2M_MPS3_SSE_310_BSP@1.4.0
+
+ components:
+ - component: CMSIS:CORE
+
+ - component: CMSIS Driver:USART
+ - component: CMSIS Driver:vStream:AudioIn
+ - component: CMSIS Driver:vStream:AudioOut
+ - component: CMSIS Driver:vStream:VideoIn
+ - component: CMSIS Driver:vStream:VideoOut
+
+ - component: CMSIS-Compiler:CORE
+ - component: CMSIS-Compiler:STDERR:Custom
+ - component: CMSIS-Compiler:STDIN:Custom
+ - component: CMSIS-Compiler:STDOUT:Custom
+
+ - component: Device:Definition
+ - component: Device:Startup&C Startup
+
+ - component: Device:Native Driver:SysCounter
+ - component: Device:Native Driver:SysTimer
+ - component: Device:Native Driver:Timeout
+ - component: Device:Native Driver:UART
+
+ - component: Machine Learning:NPU Support:Ethos-U Driver&Generic U55
+
+ groups:
+ - group: Board
+ files:
+ - file: ./main.c
+ - file: ./main.h
+ - file: ./ethos_setup.c
+ - file: ./retarget_stdio.c
+
+ linker:
+ - regions: ./regions_SSE-310.h
diff --git a/board/Corstone-310/Board-U65.clayer.yml b/board/Corstone-310/Board-U65.clayer.yml
new file mode 100644
index 0000000..ab2d117
--- /dev/null
+++ b/board/Corstone-310/Board-U65.clayer.yml
@@ -0,0 +1,64 @@
+layer:
+ type: Board
+ description: Board setup for AI/ML with Ethos U65
+ for-board: ARM::V2M-MPS3-SSE-310
+ for-device: ARM::SSE-310-MPS3_FVP
+
+ connections:
+ - connect: Corstone-310
+ provides:
+ - CMSIS_USART
+ - CMSIS_VSTREAM_AUDIO_IN
+ - CMSIS_VSTREAM_AUDIO_OUT
+ - CMSIS_VSTREAM_VIDEO_IN
+ - CMSIS_VSTREAM_VIDEO_OUT
+ - STDOUT
+ - STDERR
+ - Heap: 786432
+
+ define:
+ - CMSIS_target_header: \"Corstone-310.h\"
+ - ETHOSU65
+ - ARM_MODEL_USE_PMU_COUNTERS
+
+ packs:
+ - pack: ARM::CMSIS
+ - pack: ARM::CMSIS-Compiler@^2.1.0
+ - pack: ARM::ethos-u-core-driver@^1.25.2
+ - pack: ARM::AVH_FVP
+ - pack: ARM::V2M_MPS3_SSE_310_BSP@1.4.0
+
+ components:
+ - component: CMSIS:CORE
+
+ - component: CMSIS Driver:USART
+ - component: CMSIS Driver:vStream:AudioIn
+ - component: CMSIS Driver:vStream:AudioOut
+ - component: CMSIS Driver:vStream:VideoIn
+ - component: CMSIS Driver:vStream:VideoOut
+
+ - component: CMSIS-Compiler:CORE
+ - component: CMSIS-Compiler:STDERR:Custom
+ - component: CMSIS-Compiler:STDIN:Custom
+ - component: CMSIS-Compiler:STDOUT:Custom
+
+ - component: Device:Definition
+ - component: Device:Startup&C Startup
+
+ - component: Device:Native Driver:SysCounter
+ - component: Device:Native Driver:SysTimer
+ - component: Device:Native Driver:Timeout
+ - component: Device:Native Driver:UART
+
+ - component: Machine Learning:NPU Support:Ethos-U Driver&Generic U65
+
+ groups:
+ - group: Board
+ files:
+ - file: ./main.c
+ - file: ./main.h
+ - file: ./ethos_setup.c
+ - file: ./retarget_stdio.c
+
+ linker:
+ - regions: ./regions_SSE-310.h
diff --git a/board/Corstone-310/Board.clayer.yml b/board/Corstone-310/Board.clayer.yml
new file mode 100644
index 0000000..dd053ff
--- /dev/null
+++ b/board/Corstone-310/Board.clayer.yml
@@ -0,0 +1,59 @@
+layer:
+ type: Board
+ description: Board setup for AI/ML
+ for-board: ARM::V2M-MPS3-SSE-310
+ for-device: ARM::SSE-310-MPS3_FVP
+
+ connections:
+ - connect: Corstone-310
+ provides:
+ - CMSIS_USART
+ - CMSIS_VSTREAM_AUDIO_IN
+ - CMSIS_VSTREAM_AUDIO_OUT
+ - CMSIS_VSTREAM_VIDEO_IN
+ - CMSIS_VSTREAM_VIDEO_OUT
+ - STDOUT
+ - STDERR
+ - Heap: 786432
+
+ define:
+ - CMSIS_target_header: \"Corstone-310.h\"
+ - ARM_MODEL_USE_PMU_COUNTERS
+
+ packs:
+ - pack: ARM::CMSIS
+ - pack: ARM::CMSIS-Compiler@^2.1.0
+ - pack: ARM::AVH_FVP
+ - pack: ARM::V2M_MPS3_SSE_310_BSP@1.4.0
+
+ components:
+ - component: CMSIS:CORE
+
+ - component: CMSIS Driver:USART
+ - component: CMSIS Driver:vStream:AudioIn
+ - component: CMSIS Driver:vStream:AudioOut
+ - component: CMSIS Driver:vStream:VideoIn
+ - component: CMSIS Driver:vStream:VideoOut
+
+ - component: CMSIS-Compiler:CORE
+ - component: CMSIS-Compiler:STDERR:Custom
+ - component: CMSIS-Compiler:STDIN:Custom
+ - component: CMSIS-Compiler:STDOUT:Custom
+
+ - component: Device:Definition
+ - component: Device:Startup&C Startup
+
+ - component: Device:Native Driver:SysCounter
+ - component: Device:Native Driver:SysTimer
+ - component: Device:Native Driver:Timeout
+ - component: Device:Native Driver:UART
+
+ groups:
+ - group: Board
+ files:
+ - file: ./main.c
+ - file: ./main.h
+ - file: ./retarget_stdio.c
+
+ linker:
+ - regions: ./regions_SSE-310.h
diff --git a/board/Corstone-310/Corstone-310.h b/board/Corstone-310/Corstone-310.h
new file mode 100644
index 0000000..2047ff8
--- /dev/null
+++ b/board/Corstone-310/Corstone-310.h
@@ -0,0 +1,42 @@
+/*---------------------------------------------------------------------------
+ * Copyright (c) 2025 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 CORSTONE_310_H_
+#define CORSTONE_310_H_
+
+#include "Driver_USART.h"
+#include "cmsis_vstream.h"
+
+// CMSIS Driver instances of Board peripherals
+#define CMSIS_DRIVER_USART 0 // CMSIS Driver USART instance number
+
+// Retarget stdio to CMSIS UART
+#define RETARGET_STDIO_UART 0
+
+// CMSIS Drivers
+extern ARM_DRIVER_USART Driver_USART0; /* Serial */
+extern vStreamDriver_t Driver_vStreamAudioIn; /* Audio In Stream */
+extern vStreamDriver_t Driver_vStreamAudioOut; /* Audio Out Stream */
+extern vStreamDriver_t Driver_vStreamVideoIn; /* Video In Stream */
+extern vStreamDriver_t Driver_vStreamVideoOut; /* Video Out Stream */
+
+#ifdef CMSIS_shield_header
+#include CMSIS_shield_header
+#endif
+
+#endif /* CORSTONE_310_H_ */
diff --git a/board/Corstone-310/README.md b/board/Corstone-310/README.md
new file mode 100644
index 0000000..5470063
--- /dev/null
+++ b/board/Corstone-310/README.md
@@ -0,0 +1,35 @@
+# Board: Arm V2M-MPS3-SSE-310
+
+## Board Layer for Corstone-310 FVP
+
+Device: SSE-310-MPS3_FVP
+
+### System Configuration
+
+| System Component | Setting
+|:------------------------|:----------------------------------
+| Heap | 768 kB (configured in linker file)
+| Stack (MSP) | 32 kB (configured in linker file)
+
+### STDIO mapping
+
+**STDIO** is routed to terminal via **UART0** peripheral
+
+### CMSIS-Driver mapping
+
+| CMSIS-Driver | Peripheral | Connection
+|:-----------------------|:-----------|:----------------------
+| Driver_USART0 | UART0 | STDOUT, STDERR
+| Driver_vStreamAudioIn | VSI0 | CMSIS_VSTREAM_AUDIO_IN
+| Driver_vStreamAudioOut | VSI1 | CMSIS_VSTREAM_AUDIO_OUT
+| Driver_vStreamVideoIn | VSI4 | CMSIS_VSTREAM_VIDEO_IN
+| Driver_vStreamVideoOut | VSI6 | CMSIS_VSTREAM_VIDEO_OUT
+
+### CMSIS-Driver vStream configuration
+
+| Driver | Stream Format Description
+|:-----------------------|:----------------------------------------------------
+| Driver_vStreamAudioIn | 16-bit PCM audio, 16000 samples/second
+| Driver_vStreamAudioOut | 16-bit PCM audio, 16000 samples/second
+| Driver_vStreamVideoIn | RGB888 video, resolution 1280 x 720 (W x H)
+| Driver_vStreamVideoOut | RGB888 video, resolution 480 x 800 (W x H)
diff --git a/board/Corstone-310/RTE/CMSIS_Driver/vstream_audio_in_config.h b/board/Corstone-310/RTE/CMSIS_Driver/vstream_audio_in_config.h
new file mode 100644
index 0000000..72953b0
--- /dev/null
+++ b/board/Corstone-310/RTE/CMSIS_Driver/vstream_audio_in_config.h
@@ -0,0 +1,60 @@
+/*---------------------------------------------------------------------------
+ * Copyright (c) 2025 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 VSTREAM_AUDIO_IN_CONFIG_H_
+#define VSTREAM_AUDIO_IN_CONFIG_H_
+
+//-------- <<< Use Configuration Wizard in Context Menu >>> --------------------
+//------ With VS Code: Open Preview for Configuration Wizard -------------------
+
+// Number of channels <1=>Mono <2=>Stereo
+// Defines the number of audio channels in stream.
+// Default: 2
+#ifndef AUDIO_IN_CHANNELS
+#define AUDIO_IN_CHANNELS 2
+#endif
+
+// Number of bits per sample <0=>8 <1=>16 <2=>24 <3=>32
+// Defines number of bits of information in each sample.
+// Default: 16
+#ifndef AUDIO_IN_SAMPLE_BITS
+#define AUDIO_IN_SAMPLE_BITS 16
+#endif
+
+// Sample rate <8000=>8 kHz <16000=>16 kHz <44100=>44.1 kHz <48000=>48 kHz
+// Defines the number of samples captured per second.
+// Default: 16000
+#ifndef AUDIO_IN_SAMPLE_RATE
+#define AUDIO_IN_SAMPLE_RATE 16000
+#endif
+
+// Streaming Device Index
+// Defines the system index of the audio streaming device.
+// Default: -1 (system default audio device)
+#ifndef AUDIO_IN_DEVICE
+#define AUDIO_IN_DEVICE -1
+#endif
+
+// Audio File Name
+// Defines the name of the audio file to be used for streaming.
+// Default: "" (use streaming device instead of file)
+#ifndef AUDIO_IN_FILENAME
+#define AUDIO_IN_FILENAME ""
+#endif
+
+#endif
diff --git a/board/Corstone-310/RTE/CMSIS_Driver/vstream_audio_in_config.h.base@1.0.0 b/board/Corstone-310/RTE/CMSIS_Driver/vstream_audio_in_config.h.base@1.0.0
new file mode 100644
index 0000000..72953b0
--- /dev/null
+++ b/board/Corstone-310/RTE/CMSIS_Driver/vstream_audio_in_config.h.base@1.0.0
@@ -0,0 +1,60 @@
+/*---------------------------------------------------------------------------
+ * Copyright (c) 2025 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 VSTREAM_AUDIO_IN_CONFIG_H_
+#define VSTREAM_AUDIO_IN_CONFIG_H_
+
+//-------- <<< Use Configuration Wizard in Context Menu >>> --------------------
+//------ With VS Code: Open Preview for Configuration Wizard -------------------
+
+// Number of channels <1=>Mono <2=>Stereo
+// Defines the number of audio channels in stream.
+// Default: 2
+#ifndef AUDIO_IN_CHANNELS
+#define AUDIO_IN_CHANNELS 2
+#endif
+
+// Number of bits per sample <0=>8 <1=>16 <2=>24 <3=>32
+// Defines number of bits of information in each sample.
+// Default: 16
+#ifndef AUDIO_IN_SAMPLE_BITS
+#define AUDIO_IN_SAMPLE_BITS 16
+#endif
+
+// Sample rate <8000=>8 kHz <16000=>16 kHz <44100=>44.1 kHz <48000=>48 kHz
+// Defines the number of samples captured per second.
+// Default: 16000
+#ifndef AUDIO_IN_SAMPLE_RATE
+#define AUDIO_IN_SAMPLE_RATE 16000
+#endif
+
+// Streaming Device Index
+// Defines the system index of the audio streaming device.
+// Default: -1 (system default audio device)
+#ifndef AUDIO_IN_DEVICE
+#define AUDIO_IN_DEVICE -1
+#endif
+
+// Audio File Name
+// Defines the name of the audio file to be used for streaming.
+// Default: "" (use streaming device instead of file)
+#ifndef AUDIO_IN_FILENAME
+#define AUDIO_IN_FILENAME ""
+#endif
+
+#endif
diff --git a/board/Corstone-310/RTE/CMSIS_Driver/vstream_audio_out_config.h b/board/Corstone-310/RTE/CMSIS_Driver/vstream_audio_out_config.h
new file mode 100644
index 0000000..a8b6859
--- /dev/null
+++ b/board/Corstone-310/RTE/CMSIS_Driver/vstream_audio_out_config.h
@@ -0,0 +1,60 @@
+/*---------------------------------------------------------------------------
+ * Copyright (c) 2025 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 VSTREAM_AUDIO_OUT_CONFIG_H_
+#define VSTREAM_AUDIO_OUT_CONFIG_H_
+
+//-------- <<< Use Configuration Wizard in Context Menu >>> --------------------
+//------ With VS Code: Open Preview for Configuration Wizard -------------------
+
+// Number of channels <1=>Mono <2=>Stereo
+// Defines the number of audio channels in stream.
+// Default: 2
+#ifndef AUDIO_OUT_CHANNELS
+#define AUDIO_OUT_CHANNELS 2
+#endif
+
+// Number of bits per sample <0=>8 <1=>16 <2=>24 <3=>32
+// Defines number of bits of information in each sample.
+// Default: 16
+#ifndef AUDIO_OUT_SAMPLE_BITS
+#define AUDIO_OUT_SAMPLE_BITS 16
+#endif
+
+// Sample rate <8000=>8 kHz <16000=>16 kHz <44100=>44.1 kHz <48000=>48 kHz
+// Defines the number of samples captured per second.
+// Default: 16000
+#ifndef AUDIO_OUT_SAMPLE_RATE
+#define AUDIO_OUT_SAMPLE_RATE 16000
+#endif
+
+// Streaming Device Index
+// Defines the system index of the audio streaming device.
+// Default: -1 (system default audio device)
+#ifndef AUDIO_OUT_DEVICE
+#define AUDIO_OUT_DEVICE -1
+#endif
+
+// Audio File Name
+// Defines the name of the audio file to be used for streaming.
+// Default: "" (use streaming device instead of file)
+#ifndef AUDIO_OUT_FILENAME
+#define AUDIO_OUT_FILENAME ""
+#endif
+
+#endif
diff --git a/board/Corstone-310/RTE/CMSIS_Driver/vstream_audio_out_config.h.base@1.0.0 b/board/Corstone-310/RTE/CMSIS_Driver/vstream_audio_out_config.h.base@1.0.0
new file mode 100644
index 0000000..a8b6859
--- /dev/null
+++ b/board/Corstone-310/RTE/CMSIS_Driver/vstream_audio_out_config.h.base@1.0.0
@@ -0,0 +1,60 @@
+/*---------------------------------------------------------------------------
+ * Copyright (c) 2025 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 VSTREAM_AUDIO_OUT_CONFIG_H_
+#define VSTREAM_AUDIO_OUT_CONFIG_H_
+
+//-------- <<< Use Configuration Wizard in Context Menu >>> --------------------
+//------ With VS Code: Open Preview for Configuration Wizard -------------------
+
+// Number of channels <1=>Mono <2=>Stereo
+// Defines the number of audio channels in stream.
+// Default: 2
+#ifndef AUDIO_OUT_CHANNELS
+#define AUDIO_OUT_CHANNELS 2
+#endif
+
+// Number of bits per sample <0=>8 <1=>16 <2=>24 <3=>32
+// Defines number of bits of information in each sample.
+// Default: 16
+#ifndef AUDIO_OUT_SAMPLE_BITS
+#define AUDIO_OUT_SAMPLE_BITS 16
+#endif
+
+// Sample rate <8000=>8 kHz <16000=>16 kHz <44100=>44.1 kHz <48000=>48 kHz
+// Defines the number of samples captured per second.
+// Default: 16000
+#ifndef AUDIO_OUT_SAMPLE_RATE
+#define AUDIO_OUT_SAMPLE_RATE 16000
+#endif
+
+// Streaming Device Index
+// Defines the system index of the audio streaming device.
+// Default: -1 (system default audio device)
+#ifndef AUDIO_OUT_DEVICE
+#define AUDIO_OUT_DEVICE -1
+#endif
+
+// Audio File Name
+// Defines the name of the audio file to be used for streaming.
+// Default: "" (use streaming device instead of file)
+#ifndef AUDIO_OUT_FILENAME
+#define AUDIO_OUT_FILENAME ""
+#endif
+
+#endif
diff --git a/board/Corstone-310/RTE/CMSIS_Driver/vstream_video_in_config.h b/board/Corstone-310/RTE/CMSIS_Driver/vstream_video_in_config.h
new file mode 100644
index 0000000..fd1d7d0
--- /dev/null
+++ b/board/Corstone-310/RTE/CMSIS_Driver/vstream_video_in_config.h
@@ -0,0 +1,70 @@
+/*---------------------------------------------------------------------------
+ * Copyright (c) 2025 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 VSTREAM_VIDEO_IN_CONFIG_H_
+#define VSTREAM_VIDEO_IN_CONFIG_H_
+
+//-------- <<< Use Configuration Wizard in Context Menu >>> --------------------
+//------ With VS Code: Open Preview for Configuration Wizard -------------------
+
+// Frame width
+// Defines the video stream frame width in pixels.
+// Common frame widths: 320, 640, 800, 1024.
+// Default: 640
+#ifndef VIDEO_IN_FRAME_WIDTH
+#define VIDEO_IN_FRAME_WIDTH 640
+#endif
+
+// Frame height
+// Defines the video stream frame height in pixels.
+// Common frame heights: 240, 480, 600, 768.
+// Default: 480
+#ifndef VIDEO_IN_FRAME_HEIGHT
+#define VIDEO_IN_FRAME_HEIGHT 480
+#endif
+
+// Frame rate
+// Defines the video stream frame rate in frames per second.
+// Common frame rates: 15, 25, 30, 60.
+// Default: 30
+#ifndef VIDEO_IN_FRAME_RATE
+#define VIDEO_IN_FRAME_RATE 30
+#endif
+
+// Color format <0=>Grayscale(8-bit) <1=>RGB888 <2=>BGR565 <3=>YUV420 <4=>NV12 <5=>NV21
+// Defines the video frame color space.
+// Default: 1
+#ifndef VIDEO_IN_FRAME_COLOR
+#define VIDEO_IN_FRAME_COLOR 1
+#endif
+
+// Streaming Device Index
+// Defines the system index of the video streaming device.
+// Default: -1 (system default video device)
+#ifndef VIDEO_IN_DEVICE
+#define VIDEO_IN_DEVICE -1
+#endif
+
+// Video File Name
+// Defines the name of the video file to be used for streaming.
+// Default: "" (use streaming device instead of file)
+#ifndef VIDEO_IN_FILENAME
+#define VIDEO_IN_FILENAME ""
+#endif
+
+#endif
diff --git a/board/Corstone-310/RTE/CMSIS_Driver/vstream_video_in_config.h.base@1.0.0 b/board/Corstone-310/RTE/CMSIS_Driver/vstream_video_in_config.h.base@1.0.0
new file mode 100644
index 0000000..a4e79fe
--- /dev/null
+++ b/board/Corstone-310/RTE/CMSIS_Driver/vstream_video_in_config.h.base@1.0.0
@@ -0,0 +1,70 @@
+/*---------------------------------------------------------------------------
+ * Copyright (c) 2025 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 VSTREAM_VIDEO_IN_CONFIG_H_
+#define VSTREAM_VIDEO_IN_CONFIG_H_
+
+//-------- <<< Use Configuration Wizard in Context Menu >>> --------------------
+//------ With VS Code: Open Preview for Configuration Wizard -------------------
+
+// Frame width
+// Defines the video stream frame width in pixels.
+// Common frame widths: 320, 640, 800, 1024.
+// Default: 640
+#ifndef VIDEO_IN_FRAME_WIDTH
+#define VIDEO_IN_FRAME_WIDTH 320
+#endif
+
+// Frame height
+// Defines the video stream frame height in pixels.
+// Common frame heights: 240, 480, 600, 768.
+// Default: 480
+#ifndef VIDEO_IN_FRAME_HEIGHT
+#define VIDEO_IN_FRAME_HEIGHT 240
+#endif
+
+// Frame rate
+// Defines the video stream frame rate in frames per second.
+// Common frame rates: 15, 25, 30, 60.
+// Default: 30
+#ifndef VIDEO_IN_FRAME_RATE
+#define VIDEO_IN_FRAME_RATE 30
+#endif
+
+// Color format <0=>Grayscale(8-bit) <1=>RGB888 <2=>BGR565 <3=>YUV420 <4=>NV12 <5=>NV21
+// Defines the video frame color space.
+// Default: 1
+#ifndef VIDEO_IN_FRAME_COLOR
+#define VIDEO_IN_FRAME_COLOR 1
+#endif
+
+// Streaming Device Index
+// Defines the system index of the video streaming device.
+// Default: -1 (system default video device)
+#ifndef VIDEO_IN_DEVICE
+#define VIDEO_IN_DEVICE -1
+#endif
+
+// Video File Name
+// Defines the name of the video file to be used for streaming.
+// Default: "" (use streaming device instead of file)
+#ifndef VIDEO_IN_FILENAME
+#define VIDEO_IN_FILENAME ""
+#endif
+
+#endif
diff --git a/board/Corstone-310/RTE/CMSIS_Driver/vstream_video_out_config.h b/board/Corstone-310/RTE/CMSIS_Driver/vstream_video_out_config.h
new file mode 100644
index 0000000..da9aa7e
--- /dev/null
+++ b/board/Corstone-310/RTE/CMSIS_Driver/vstream_video_out_config.h
@@ -0,0 +1,63 @@
+/*---------------------------------------------------------------------------
+ * Copyright (c) 2025 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 VSTREAM_VIDEO_OUT_CONFIG_H_
+#define VSTREAM_VIDEO_OUT_CONFIG_H_
+
+//-------- <<< Use Configuration Wizard in Context Menu >>> --------------------
+//------ With VS Code: Open Preview for Configuration Wizard -------------------
+
+// Frame width
+// Defines the video stream frame width in pixels.
+// Common frame widths: 320, 640, 800, 1024.
+// Default: 640
+#ifndef VIDEO_OUT_FRAME_WIDTH
+#define VIDEO_OUT_FRAME_WIDTH 640
+#endif
+
+// Frame height
+//