summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/application/main/include/UseCaseCommonUtils.hpp17
-rw-r--r--source/hal/source/components/vsi/CMakeLists.txt79
-rw-r--r--source/hal/source/components/vsi/include/arm_vsi.h121
-rw-r--r--source/hal/source/components/vsi/include/video_drv.h142
-rw-r--r--source/hal/source/components/vsi/source/video_drv.c600
-rw-r--r--source/hal/source/platform/mps3/CMakeLists.txt14
-rw-r--r--source/hal/source/platform/mps3/include/sse-300/peripheral_irqs.h10
-rw-r--r--source/hal/source/platform/mps3/include/sse-310/peripheral_irqs.h10
-rw-r--r--source/hal/source/platform/mps3/include/vsi_mps3.h115
-rw-r--r--source/hal/source/platform/mps3/source/platform_drivers.c12
-rw-r--r--source/hal/source/platform/mps3/source/vsi_mps3.c62
-rw-r--r--source/use_case/img_class/usecase.cmake12
-rw-r--r--source/use_case/object_detection/include/UseCaseHandler.hpp30
-rw-r--r--source/use_case/object_detection/src/MainLoop.cc14
-rw-r--r--source/use_case/object_detection/src/UseCaseHandler.cc231
-rw-r--r--source/use_case/object_detection/usecase.cmake24
-rw-r--r--source/use_case/vww/usecase.cmake12
17 files changed, 1475 insertions, 30 deletions
diff --git a/source/application/main/include/UseCaseCommonUtils.hpp b/source/application/main/include/UseCaseCommonUtils.hpp
index 68ffe42..182aea6 100644
--- a/source/application/main/include/UseCaseCommonUtils.hpp
+++ b/source/application/main/include/UseCaseCommonUtils.hpp
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: Copyright 2021-2022 Arm Limited and/or its affiliates <open-source-office@arm.com>
+ * SPDX-FileCopyrightText: Copyright 2021-2022, 2024 Arm Limited and/or its affiliates <open-source-office@arm.com>
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -56,12 +56,15 @@ bool SetAppCtxIfmIdx(arm::app::ApplicationContext& ctx, uint32_t idx, const std:
namespace common {
- enum OPCODES {
- MENU_OPT_RUN_INF_NEXT = 1, /* Run on next vector. */
- MENU_OPT_RUN_INF_CHOSEN, /* Run on a user provided vector index. */
- MENU_OPT_RUN_INF_ALL, /* Run inference on all. */
- MENU_OPT_SHOW_MODEL_INFO, /* Show model info. */
- MENU_OPT_LIST_IFM /* List the current IFM. */
+ enum OPCODES {
+ MENU_OPT_RUN_INF_NEXT = 1, /* Run on next vector. */
+ MENU_OPT_RUN_INF_CHOSEN, /* Run on a user provided vector index. */
+ MENU_OPT_RUN_INF_ALL, /* Run inference on all. */
+ MENU_OPT_SHOW_MODEL_INFO, /* Show model info. */
+ MENU_OPT_LIST_IFM, /* List the current IFM. */
+#if VSI_ENABLED
+ MENU_OPT_RUN_INF_VSI /* Run on input from VSI. */
+#endif
};
}
diff --git a/source/hal/source/components/vsi/CMakeLists.txt b/source/hal/source/components/vsi/CMakeLists.txt
new file mode 100644
index 0000000..8d07459
--- /dev/null
+++ b/source/hal/source/components/vsi/CMakeLists.txt
@@ -0,0 +1,79 @@
+#----------------------------------------------------------------------------
+# SPDX-FileCopyrightText: Copyright 2024 Arm Limited and/or its affiliates <open-source-office@arm.com>
+# SPDX-License-Identifier: Apache-2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#----------------------------------------------------------------------------
+
+##########################################################
+# Arm Virtual Streaming Interface initialization library #
+##########################################################
+
+# Arm Virtual Streaming Interface is only available on
+# certain supported platforms.
+
+cmake_minimum_required(VERSION 3.21.0)
+set(ARM_VSI_COMPONENT arm_vsi)
+project(${ARM_VSI_COMPONENT}
+ DESCRIPTION "Arm Virtual Streaming Interface initialization library"
+ LANGUAGES C CXX ASM)
+
+## Logging utilities:
+if (NOT TARGET log)
+ if (NOT DEFINED LOG_PROJECT_DIR)
+ message(FATAL_ERROR "LOG_PROJECT_DIR needs to be defined.")
+ endif()
+ add_subdirectory(${LOG_PROJECT_DIR} ${CMAKE_BINARY_DIR}/log)
+endif()
+
+# Create static library
+add_library(${ARM_VSI_COMPONENT} STATIC)
+
+## Include directories - public
+target_include_directories(${ARM_VSI_COMPONENT}
+ PUBLIC
+ include)
+
+## Component sources
+target_sources(${ARM_VSI_COMPONENT}
+ PUBLIC
+ source/video_drv.c)
+
+## If the rte_components target has been defined, include it as a dependency here. This component
+## gives access to certain CPU related functions and definitions that should come from the CMSIS
+## or custom system setup and boot implementation files.
+## If the component is not defined as a target, a dependency for this target should be added by
+## the project importing this one.
+if (TARGET rte_components)
+ target_link_libraries(${ARM_VSI_COMPONENT} PUBLIC
+ rte_components)
+else()
+ message(WARNING
+ "rte_components target not defined."
+ "${ARM_VSI_COMPONENT} will need to be provided access to"
+ "RTE_Components.h header to include CPU specific definitions.")
+endif()
+## Compile definitions
+target_compile_definitions(${ARM_VSI_COMPONENT}
+ PUBLIC
+ VSI_ENABLED)
+
+## Add dependencies
+target_link_libraries(${ARM_VSI_COMPONENT} PUBLIC
+ log)
+
+# Display status
+message(STATUS "CMAKE_CURRENT_SOURCE_DIR: " ${CMAKE_CURRENT_SOURCE_DIR})
+message(STATUS "*******************************************************")
+message(STATUS "Library : " ${ARM_VSI_COMPONENT})
+message(STATUS "*******************************************************")
diff --git a/source/hal/source/components/vsi/include/arm_vsi.h b/source/hal/source/components/vsi/include/arm_vsi.h
new file mode 100644
index 0000000..1d307d1
--- /dev/null
+++ b/source/hal/source/components/vsi/include/arm_vsi.h
@@ -0,0 +1,121 @@
+/*
+* SPDX-FileCopyrightText: Copyright 2024 Arm Limited and/or its affiliates <open-source-office@arm.com>
+* SPDX-License-Identifier: Apache-2.0
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/*
+ * Virtual Streaming Interface (VSI)
+ */
+
+#ifndef __ARM_VSI_H
+#define __ARM_VSI_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef __IM
+#define __IM volatile const /*! Defines 'read only' structure member permissions */
+#endif
+#ifndef __OM
+#define __OM volatile /*! Defines 'write only' structure member permissions */
+#endif
+#ifndef __IOM
+#define __IOM volatile /*! Defines 'read/write' structure member permissions */
+#endif
+
+#include <stdint.h>
+
+/* IRQ number assignment (should be moved to device header) */
+#define ARM_VSI0_IRQn 224
+#define ARM_VSI1_IRQn 225
+#define ARM_VSI2_IRQn 226
+#define ARM_VSI3_IRQn 227
+#define ARM_VSI4_IRQn 228
+#define ARM_VSI5_IRQn 229
+#define ARM_VSI6_IRQn 230
+#define ARM_VSI7_IRQn 231
+
+/// Structure type to access the virtual streaming interface
+typedef struct
+{
+ /// Interrupt Request (IRQ)
+ struct {
+ __IOM uint32_t Enable; /*!< (R/W) IRQ Enable */
+ __OM uint32_t Set; /*!< (-/W) IRQ Set */
+ __OM uint32_t Clear; /*!< (-/W) IRQ Clear */
+ __IM uint32_t Status; /*!< (R/-) IRQ Status */
+ } IRQ;
+ uint32_t reserved1[60];
+ /// Time counter with 1MHz input frequency
+ struct {
+ __IOM uint32_t Control; /*!< (R/W) Timer Control */
+ __IOM uint32_t Interval; /*!< (R/W) Timer Interval Value (in microseconds) */
+ __IM uint32_t Count; /*!< (R/-) Timer Overflow Count */
+ } Timer;
+ uint32_t reserved2[61];
+ /// Direct Memory Access (DMA) Controller
+ struct {
+ __IOM uint32_t Control; /*!< (R/W) DMA Control */
+ __IOM uint32_t Address; /*!< (R/W) DMA Memory Start Address */
+ __IOM uint32_t BlockSize; /*!< (R/W) DMA Block Size (in bytes, multiple of 4) */
+ __IOM uint32_t BlockNum; /*!< (R/W) DMA Number of Blocks (must be 2^n) */
+ __IM uint32_t BlockIndex; /*!< (R/-) DMA Block Index */
+ } DMA;
+ uint32_t reserved3[59];
+ __IOM uint32_t Regs[64]; /*!< (R/W) User Registers */
+} ARM_VSI_Type;
+
+/* VSI Timer Control Definitions for Timer.Control register */
+#define ARM_VSI_Timer_Run_Pos 0U /*!< Timer Control: Run Position */
+#define ARM_VSI_Timer_Run_Msk (1UL << ARM_VSI_Timer_Run_Pos) /*!< Timer Control: Run Mask */
+#define ARM_VSI_Timer_Periodic_Pos 1U /*!< Timer Control: Periodic Position */
+#define ARM_VSI_Timer_Periodic_Msk (1UL << ARM_VSI_Timer_Periodic_Pos) /*!< Timer Control: Periodic Mask */
+#define ARM_VSI_Timer_Trig_IRQ_Pos 2U /*!< Timer Control: Trig_IRQ Position */
+#define ARM_VSI_Timer_Trig_IRQ_Msk (1UL << ARM_VSI_Timer_Trig_IRQ_Pos) /*!< Timer Control: Trig_IRQ Mask */
+#define ARM_VSI_Timer_Trig_DMA_Pos 3U /*!< Timer Control: Trig_DAM Position */
+#define ARM_VSI_Timer_Trig_DMA_Msk (1UL << ARM_VSI_Timer_Trig_DMA_Pos) /*!< Timer Control: Trig_DMA Mask */
+
+/* VSI DMA Control Definitions for DMA.Control register */
+#define ARM_VSI_DMA_Enable_Pos 0U /*!< DMA Control: Enable Position */
+#define ARM_VSI_DMA_Enable_Msk (1UL << ARM_VSI_DMA_Enable_Pos) /*!< DMA Control: Enable Mask */
+#define ARM_VSI_DMA_Direction_Pos 1U /*!< DMA Control: Direction Position */
+#define ARM_VSI_DMA_Direction_Msk (1UL << ARM_VSI_DMA_Direction_Pos) /*!< DMA Control: Direction Mask */
+#define ARM_VSI_DMA_Direction_P2M (0UL*ARM_VSI_DMA_Direction_Msk) /*!< DMA Control: Direction P2M */
+#define ARM_VSI_DMA_Direction_M2P (1UL*ARM_VSI_DMA_Direction_Msk) /*!< DMA Control: Direction M2P */
+
+/* Memory mapping of 8 VSI peripherals */
+#define ARM_VSI0_BASE (0x4FF00000UL) /*!< VSI 0 Base Address */
+#define ARM_VSI1_BASE (0x4FF10000UL) /*!< VSI 1 Base Address */
+#define ARM_VSI2_BASE (0x4FF20000UL) /*!< VSI 2 Base Address */
+#define ARM_VSI3_BASE (0x4FF30000UL) /*!< VSI 3 Base Address */
+#define ARM_VSI4_BASE (0x4FF40000UL) /*!< VSI 4 Base Address */
+#define ARM_VSI5_BASE (0x4FF50000UL) /*!< VSI 5 Base Address */
+#define ARM_VSI6_BASE (0x4FF60000UL) /*!< VSI 6 Base Address */
+#define ARM_VSI7_BASE (0x4FF70000UL) /*!< VSI 7 Base Address */
+#define ARM_VSI0 ((ARM_VSI_Type *)ARM_VSI0_BASE) /*!< VSI 0 struct */
+#define ARM_VSI1 ((ARM_VSI_Type *)ARM_VSI1_BASE) /*!< VSI 1 struct */
+#define ARM_VSI2 ((ARM_VSI_Type *)ARM_VSI2_BASE) /*!< VSI 2 struct */
+#define ARM_VSI3 ((ARM_VSI_Type *)ARM_VSI3_BASE) /*!< VSI 3 struct */
+#define ARM_VSI4 ((ARM_VSI_Type *)ARM_VSI4_BASE) /*!< VSI 4 struct */
+#define ARM_VSI5 ((ARM_VSI_Type *)ARM_VSI5_BASE) /*!< VSI 5 struct */
+#define ARM_VSI6 ((ARM_VSI_Type *)ARM_VSI6_BASE) /*!< VSI 6 struct */
+#define ARM_VSI7 ((ARM_VSI_Type *)ARM_VSI7_BASE) /*!< VSI 7 struct */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ARM_VSI_H */
diff --git a/source/hal/source/components/vsi/include/video_drv.h b/source/hal/source/components/vsi/include/video_drv.h
new file mode 100644
index 0000000..73a6ef7
--- /dev/null
+++ b/source/hal/source/components/vsi/include/video_drv.h
@@ -0,0 +1,142 @@
+/*
+* SPDX-FileCopyrightText: Copyright 2024 Arm Limited and/or its affiliates <open-source-office@arm.com>
+* SPDX-License-Identifier: Apache-2.0
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef VIDEO_DRV_H
+#define VIDEO_DRV_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdint.h>
+
+/* Video Channel */
+#define VIDEO_DRV_IN0 (0UL) ///< Video Input channel 0
+#define VIDEO_DRV_OUT0 (1UL) ///< Video Output channel 0
+#define VIDEO_DRV_IN1 (2UL) ///< Video Input channel 1
+#define VIDEO_DRV_OUT1 (3UL) ///< Video Output channel 1
+
+/* Video Event */
+#define VIDEO_DRV_EVENT_FRAME (1UL << 0) ///< Video frame received
+#define VIDEO_DRV_EVENT_OVERFLOW (1UL << 1) ///< Video buffer overflow
+#define VIDEO_DRV_EVENT_UNDERFLOW (1UL << 2) ///< Video buffer underflow
+#define VIDEO_DRV_EVENT_EOS (1UL << 3) ///< Video end of stream
+
+/* Video Mode */
+#define VIDEO_DRV_MODE_SINGLE (0UL) ///< Single frame
+#define VIDEO_DRV_MODE_CONTINUOS (1UL) ///< Continuos stream
+
+/* Return code */
+#define VIDEO_DRV_OK (0) ///< Operation succeeded
+#define VIDEO_DRV_ERROR (-1) ///< Unspecified error
+#define VIDEO_DRV_ERROR_PARAMETER (-2) ///< Parameter error
+
+/// Video Color Format
+#define COLOR_FORMAT_BEGIN (0UL)
+#define COLOR_GRAYSCALE8 (1UL)
+#define COLOR_RGB888 (2UL)
+#define COLOR_BGR565 (3UL)
+#define COLOR_YUV420 (4UL)
+#define COLOR_NV12 (5UL)
+#define COLOR_NV21 (6UL)
+#define COLOR_FORMAT_END (7UL)
+
+/// Video Status
+typedef struct {
+ uint32_t active : 1; ///< Video stream active
+ uint32_t buf_empty : 1; ///< Video stream buffer empty
+ uint32_t buf_full : 1; ///< Video stream buffer full
+ uint32_t overflow : 1; ///< Video buffer overflow (cleared on GetStatus)
+ uint32_t underflow : 1; ///< Video buffer underflow (cleared on GetStatus)
+ uint32_t eos : 1; ///< Video end of stream (cleared on GetStatus)
+ uint32_t reserved : 26;
+} VideoDrv_Status_t;
+
+/// \brief Video Events callback function type.
+/// \param[in] channel channel number
+/// \param[in] event events notification mask
+/// \return none
+typedef void (*VideoDrv_Event_t) (uint32_t channel, uint32_t event);
+
+/// \brief Initialize Video Interface.
+/// \param[in] cb_event pointer to \ref VideoDrv_Event_t
+/// \return return code
+int32_t VideoDrv_Initialize (VideoDrv_Event_t cb_event);
+
+/// \brief De-initialize Video Interface.
+/// \return return code
+int32_t VideoDrv_Uninitialize (void);
+
+/// \brief Set Video Interface file.
+/// \param[in] channel channel number
+/// \param[in] name video filename (pointer to NULL terminated string)
+/// \return return code
+int32_t VideoDrv_SetFile (uint32_t channel, const char *name);
+
+/// \brief Configure Video Interface.
+/// \param[in] channel channel number
+/// \param[in] frame_width frame width in pixels
+/// \param[in] frame_height frame height in pixels
+/// \param[in] color_format pixel color format
+/// \param[in] frame_rate frame rate (frames per second)
+/// \return return code
+int32_t VideoDrv_Configure (uint32_t channel, uint32_t frame_width, uint32_t frame_height, uint32_t color_format, uint32_t frame_rate);
+
+/// \brief Set Video Interface buffer.
+/// \param[in] channel channel number
+/// \param[in] buf pointer to buffer for video stream
+/// \param[in] buf_size video stream buffer size in bytes
+/// \return return code
+int32_t VideoDrv_SetBuf (uint32_t channel, void *buf, uint32_t buf_size);
+
+/// \brief Flush Video Interface buffer.
+/// \param[in] channel channel number
+/// \return return code
+int32_t VideoDrv_FlushBuf (uint32_t channel);
+
+/// \brief Start Stream on Video Interface.
+/// \param[in] channel channel number
+/// \param[in] mode stream mode
+/// \return return code
+int32_t VideoDrv_StreamStart (uint32_t channel, uint32_t mode);
+
+/// \brief Stop Stream on Video Interface.
+/// \param[in] channel channel number
+/// \return return code
+int32_t VideoDrv_StreamStop (uint32_t channel);
+
+/// \brief Get Video Frame buffer.
+/// \param[in] channel channel number
+/// \return pointer to frame buffer
+void *VideoDrv_GetFrameBuf (uint32_t channel);
+
+/// \brief Release Video Frame.
+/// \param[in] channel channel number
+/// \return return code
+int32_t VideoDrv_ReleaseFrame (uint32_t channel);
+
+/// \brief Get Video Interface status.
+/// \param[in] channel channel number
+/// \return \ref VideoDrv_Status_t
+VideoDrv_Status_t VideoDrv_GetStatus (uint32_t channel);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* VIDEO_DRV_H */
diff --git a/source/hal/source/components/vsi/source/video_drv.c b/source/hal/source/components/vsi/source/video_drv.c
new file mode 100644
index 0000000..ab4e2e5
--- /dev/null
+++ b/source/hal/source/components/vsi/source/video_drv.c
@@ -0,0 +1,600 @@
+/*
+* SPDX-FileCopyrightText: Copyright 2024 Arm Limited and/or its affiliates <open-source-office@arm.com>
+* SPDX-License-Identifier: Apache-2.0
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include <stdint.h>
+#include <string.h>
+#include "video_drv.h"
+
+#include "RTE_Components.h"
+#include "arm_vsi.h"
+
+// Video channel definitions
+#ifndef VIDEO_INPUT_CHANNELS
+#define VIDEO_INPUT_CHANNELS 1
+#endif
+#if (VIDEO_INPUT_CHANNELS > 2)
+#error "Maximum 2 Video Input channels are supported!"
+#endif
+#ifndef VIDEO_OUTPUT_CHANNELS
+#define VIDEO_OUTPUT_CHANNELS 1
+#endif
+#if (VIDEO_OUTPUT_CHANNELS > 2)
+#error "Maximum 2 Video Output channels are supported!"
+#endif
+
+
+// Video peripheral definitions
+#define VideoI0 ARM_VSI4 // Video Input channel 0 access struct
+#define VideoI0_IRQn ARM_VSI4_IRQn // Video Input channel 0 Interrupt number
+#define VideoI0_Handler ARM_VSI4_Handler // Video Input channel 0 Interrupt handler
+#define VideoI1 ARM_VSI5 // Video Input channel 1 access struct
+#define VideoI1_IRQn ARM_VSI5_IRQn // Video Input channel 1 Interrupt number
+#define VideoI1_Handler ARM_VSI5_Handler // Video Input channel 1 Interrupt handler
+#define VideoO0 ARM_VSI6 // Video Output channel 0 access struct
+#define VideoO0_IRQn ARM_VSI6_IRQn // Video Output channel 0 Interrupt number
+#define VideoO0_Handler ARM_VSI6_Handler // Video Output channel 0 Interrupt handler
+#define VideoO1 ARM_VSI7 // Video Output channel 1 access struct
+#define VideoO1_IRQn ARM_VSI7_IRQn // Video Output channel 1 Interrupt number
+#define VideoO1_Handler ARM_VSI7_Handler // Video Output channel 1 Interrupt handler
+
+// Video Peripheral registers
+#define Reg_MODE Regs[0] // Mode: 0=Input, 1=Output
+#define Reg_CONTROL Regs[1] // Control: enable, continuos, flush
+#define Reg_STATUS Regs[2] // Status: active, buf_empty, buf_full, overflow, underflow, eos
+#define Reg_FILENAME_LEN Regs[3] // Filename length
+#define Reg_FILENAME_CHAR Regs[4] // Filename character
+#define Reg_FILENAME_VALID Regs[5] // Filename valid flag
+#define Reg_FRAME_WIDTH Regs[6] // Requested frame width
+#define Reg_FRAME_HEIGHT Regs[7] // Requested frame height
+#define Reg_COLOR_FORMAT Regs[8] // Color format
+#define Reg_FRAME_RATE Regs[9] // Frame rate
+#define Reg_FRAME_INDEX Regs[10] // Frame index
+#define Reg_FRAME_COUNT Regs[11] // Frame count
+#define Reg_FRAME_COUNT_MAX Regs[12] // Frame count maximum
+
+// Video MODE register defintions
+#define Reg_MODE_IO_Pos 0U
+#define Reg_MODE_IO_Msk (1UL << Reg_MODE_IO_Pos)
+#define Reg_MODE_Input (0UL << Reg_MODE_IO_Pos)
+#define Reg_MODE_Output (1UL << Reg_MODE_IO_Pos)
+
+// Video CONTROL register definitions
+#define Reg_CONTROL_ENABLE_Pos 0U
+#define Reg_CONTROL_ENABLE_Msk (1UL << Reg_CONTROL_ENABLE_Pos)
+#define Reg_CONTROL_CONTINUOS_Pos 1U
+#define Reg_CONTROL_CONTINUOS_Msk (1UL << Reg_CONTROL_CONTINUOS_Pos)
+#define Reg_CONTROL_BUF_FLUSH_Pos 2U
+#define Reg_CONTROL_BUF_FLUSH_Msk (1UL << Reg_CONTROL_BUF_FLUSH_Pos)
+
+// Video STATUS register definitions
+#define Reg_STATUS_ACTIVE_Pos 0U
+#define Reg_STATUS_ACTIVE_Msk (1UL << Reg_STATUS_ACTIVE_Pos)
+#define Reg_STATUS_BUF_EMPTY_Pos 1U
+#define Reg_STATUS_BUF_EMPTY_Msk (1UL << Reg_STATUS_BUF_EMPTY_Pos)
+#define Reg_STATUS_BUF_FULL_Pos 2U
+#define Reg_STATUS_BUF_FULL_Msk (1UL << Reg_STATUS_BUF_FULL_Pos)
+#define Reg_STATUS_OVERFLOW_Pos 3U
+#define Reg_STATUS_OVERFLOW_Msk (1UL << Reg_STATUS_OVERFLOW_Pos)
+#define Reg_STATUS_UNDERFLOW_Pos 4U
+#define Reg_STATUS_UNDERFLOW_Msk (1UL << Reg_STATUS_UNDERFLOW_Pos)
+#define Reg_STATUS_EOS_Pos 5U
+#define Reg_STATUS_EOS_Msk (1UL << Reg_STATUS_EOS_Pos)
+
+// IRQ Status register definitions
+#define Reg_IRQ_Status_FRAME_Pos 0U
+#define Reg_IRQ_Status_FRAME_Msk (1UL << Reg_IRQ_Status_FRAME_Pos)
+#define Reg_IRQ_Status_OVERFLOW_Pos 1U
+#define Reg_IRQ_Status_OVERFLOW_Msk (1UL << Reg_IRQ_Status_OVERFLOW_Pos)
+#define Reg_IRQ_Status_UNDERFLOW_Pos 2U
+#define Reg_IRQ_Status_UNDERFLOW_Msk (1UL << Reg_IRQ_Status_UNDERFLOW_Pos)
+#define Reg_IRQ_Status_EOS_Pos 3U
+#define Reg_IRQ_Status_EOS_Msk (1UL << Reg_IRQ_Status_EOS_Pos)
+
+#define Reg_IRQ_Status_Msk Reg_IRQ_Status_FRAME_Msk | \
+ Reg_IRQ_Status_OVERFLOW_Msk | \
+ Reg_IRQ_Status_UNDERFLOW_Msk | \
+ Reg_IRQ_Status_EOS_Msk
+
+// Video peripheral access structure
+static ARM_VSI_Type * const pVideo[4] = { VideoI0, VideoO0, VideoI1, VideoO1 };
+
+// Driver State
+static uint8_t Initialized = 0U;
+static uint8_t Configured[4] = { 0U, 0U, 0U, 0U };
+
+// Event Callback
+static VideoDrv_Event_t CB_Event = NULL;
+
+// Video Interrupt Handler
+static void Video_Handler (uint32_t channel) {
+ uint32_t irq_status;
+ uint32_t event;
+
+ irq_status = pVideo[channel]->IRQ.Status;
+ pVideo[channel]->IRQ.Clear = irq_status;
+ __DSB();
+ __ISB();
+
+ event = 0U;
+ if (irq_status & Reg_IRQ_Status_FRAME_Msk) {
+ event |= VIDEO_DRV_EVENT_FRAME;
+ }
+ if (irq_status & Reg_IRQ_Status_OVERFLOW_Msk) {
+ event |= VIDEO_DRV_EVENT_OVERFLOW;
+ }
+ if (irq_status & Reg_IRQ_Status_UNDERFLOW_Msk) {
+ event |= VIDEO_DRV_EVENT_UNDERFLOW;
+ }
+ if (irq_status & Reg_IRQ_Status_EOS_Msk) {
+ event |= VIDEO_DRV_EVENT_EOS;
+ }
+
+ if (CB_Event != NULL) {
+ CB_Event(channel, event);
+ }
+}
+
+// Video channel 0 Interrupt Handler
+#if (VIDEO_INPUT_CHANNELS >= 1)
+void VideoI0_Handler (void);
+void VideoI0_Handler (void) {
+ Video_Handler(0U);
+}
+#endif
+
+// Video channel 1 Interrupt Handler
+#if (VIDEO_OUTPUT_CHANNELS >= 1)
+void VideoO0_Handler (void);
+void VideoO0_Handler (void) {
+ Video_Handler(1U);
+}
+#endif
+
+// Video channel 2 Interrupt Handler
+#if (VIDEO_INPUT_CHANNELS >= 2)
+void VideoI1_Handler (void);
+void VideoI1_Handler (void) {
+ Video_Handler(2U);
+}
+#endif
+
+// Video channel 3 Interrupt Handler
+#if (VIDEO_OUTPUT_CHANNELS >= 2)
+void VideoO1_Handler (void);
+void VideoO1_Handler (void) {
+ Video_Handler(3U);
+}
+#endif
+
+// Initialize Video Interface
+int32_t VideoDrv_Initialize (VideoDrv_Event_t cb_event) {
+
+ CB_Event = cb_event;
+
+ // Initialize Video Input channel 0
+ #if (VIDEO_INPUT_CHANNELS >= 1)
+ VideoI0->Timer.Control = 0U;
+ VideoI0->DMA.Control = 0U;
+ VideoI0->IRQ.Clear = Reg_IRQ_Status_Msk;
+ VideoI0->IRQ.Enable = Reg_IRQ_Status_Msk;
+ VideoI0->Reg_MODE = Reg_MODE_Input;
+ VideoI0->Reg_CONTROL = 0U;
+// NVIC_EnableIRQ(VideoI0_IRQn);
+ NVIC->ISER[(((uint32_t)VideoI0_IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)VideoI0_IRQn) & 0x1FUL));
+ #endif
+ Configured[0] = 0U;
+
+ // Initialize Video Output channel 0
+ #if (VIDEO_OUTPUT_CHANNELS >= 1)
+ VideoO0->Timer.Control = 0U;
+ VideoO0->DMA.Control = 0U;
+ VideoO0->IRQ.Clear = Reg_IRQ_Status_Msk;
+ VideoO0->IRQ.Enable = Reg_IRQ_Status_Msk;
+ VideoO0->Reg_MODE = Reg_MODE_Output;
+ VideoO0->Reg_CONTROL = 0U;
+// NVIC_EnableIRQ(VideoO0_IRQn);
+ NVIC->ISER[(((uint32_t)VideoO0_IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)VideoO0_IRQn) & 0x1FUL));
+ #endif
+ Configured[1] = 0U;
+
+ // Initialize Video Input channel 1
+ #if (VIDEO_INPUT_CHANNELS >= 2)
+ VideoI1->Timer.Control = 0U;
+ VideoI1->DMA.Control = 0U;
+ VideoI1->IRQ.Clear = Reg_IRQ_Status_Msk;
+ VideoI1->IRQ.Enable = Reg_IRQ_Status_Msk;
+ VideoI1->Reg_MODE = Reg_MODE_Input;
+ VideoI1->Reg_CONTROL = 0U;
+// NVIC_EnableIRQ(VideoI1_IRQn);
+ NVIC->ISER[(((uint32_t)VideoI1_IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)VideoI1_IRQn) & 0x1FUL));
+ #endif
+ Configured[2] = 0U;
+
+ // Initialize Video Output channel 1
+ #if (VIDEO_OUTPUT_CHANNELS >= 2)
+ VideoO1->Timer.Control = 0U;
+ VideoO1->DMA.Control = 0U;
+ VideoO1->IRQ.Clear = Reg_IRQ_Status_Msk;
+ VideoO1->IRQ.Enable = Reg_IRQ_Status_Msk;
+ VideoO1->Reg_MODE = Reg_MODE_Output;
+ VideoO1->Reg_CONTROL = 0U;
+// NVIC_EnableIRQ(VideoO1_IRQn);
+ NVIC->ISER[(((uint32_t)VideoO1_IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)VideoO1_IRQn) & 0x1FUL));
+ #endif
+ Configured[3] = 0U;
+
+ __DSB();
+ __ISB();
+
+ Initialized = 1U;
+
+ return VIDEO_DRV_OK;
+}
+
+// De-initialize Video Interface
+int32_t VideoDrv_Uninitialize (void) {
+
+ // De-initialize Video Input channel 0
+ #if (VIDEO_INPUT_CHANNELS >= 1)
+// NVIC_DisableIRQ(VideoI0_IRQn);
+ NVIC->ICER[(((uint32_t)VideoI0_IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)VideoI0_IRQn) & 0x1FUL));
+ VideoI0->Timer.Control = 0U;
+ VideoI0->DMA.Control = 0U;
+ VideoI0->IRQ.Clear = Reg_IRQ_Status_Msk;
+ VideoI0->IRQ.Enable = 0U;
+ VideoI0->Reg_CONTROL = 0U;
+ #endif
+
+ // De-initialize Video Output channel 0
+ #if (VIDEO_OUTPUT_CHANNELS >= 1)
+// NVIC_DisableIRQ(VideoO0_IRQn);
+ NVIC->ICER[(((uint32_t)VideoO0_IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)VideoO0_IRQn) & 0x1FUL));
+ VideoO0->Timer.Control = 0U;
+ VideoO0->DMA.Control = 0U;
+ VideoO0->IRQ.Clear = Reg_IRQ_Status_Msk;
+ VideoO0->IRQ.Enable = 0U;
+ VideoO0->Reg_CONTROL = 0U;
+ #endif
+
+ // De-initialize Video Input channel 1
+ #if (VIDEO_INPUT_CHANNELS >= 2)
+// NVIC_DisableIRQ(VideoI1_IRQn);
+ NVIC->ICER[(((uint32_t)VideoI1_IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)VideoI1_IRQn) & 0x1FUL));
+ VideoI1->Timer.Control = 0U;
+ VideoI1->DMA.Control = 0U;
+ VideoI1->IRQ.Clear = Reg_IRQ_Status_Msk;
+ VideoI1->IRQ.Enable = 0U;
+ VideoI1->Reg_CONTROL = 0U;
+ #endif
+
+ // De-initialize Video Output channel 1
+ #if (VIDEO_OUTPUT_CHANNELS >= 2)
+// NVIC_DisableIRQ(VideoO1_IRQn);
+ NVIC->ICER[(((uint32_t)VideoO1_IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)VideoO1_IRQn) & 0x1FUL));
+ VideoO1->Timer.Control = 0U;
+ VideoO1->DMA.Control = 0U;
+ VideoO1->IRQ.Clear = Reg_IRQ_Status_Msk;
+ VideoO1->IRQ.Enable = 0U;
+ VideoO1->Reg_CONTROL = 0U;
+ #endif
+
+ __DSB();
+ __ISB();
+
+ Initialized = 0U;
+
+ return VIDEO_DRV_OK;
+}
+
+// Set Video Interface file
+int32_t VideoDrv_SetFile (uint32_t channel, const char *name) {
+ const char *p;
+ uint32_t n;
+
+ if ((((channel & 1U) == 0U) && ((channel >> 1) >= VIDEO_INPUT_CHANNELS)) ||
+ (((channel & 1U) != 0U) && ((channel >> 1) >= VIDEO_OUTPUT_CHANNELS)) ||
+ (name == NULL)) {
+ return VIDEO_DRV_ERROR_PARAMETER;
+ }
+
+ if (Initialized == 0U) {
+ return VIDEO_DRV_ERROR;
+ }
+
+ if ((pVideo[channel]->Reg_STATUS & Reg_STATUS_ACTIVE_Msk) != 0U) {
+ return VIDEO_DRV_ERROR;
+ }
+
+ // Register Video filename
+ n = strlen(name);
+ pVideo[channel]->Reg_FILENAME_LEN = n;
+ for (p = name; n != 0U; n--) {
+ pVideo[channel]->Reg_FILENAME_CHAR = *p++;
+ }
+ if (pVideo[channel]->Reg_FILENAME_VALID == 0U) {
+ return VIDEO_DRV_ERROR;
+ }
+
+ return VIDEO_DRV_OK;
+}
+
+// Configure Video Interface
+int32_t VideoDrv_Configure (uint32_t channel, uint32_t frame_width, uint32_t frame_height, uint32_t color_format, uint32_t frame_rate) {
+ uint32_t pixel_size;
+ uint32_t block_size;
+
+ if ((((channel & 1U) == 0U) && ((channel >> 1) >= VIDEO_INPUT_CHANNELS)) ||
+ (((channel & 1U) != 0U) && ((channel >> 1) >= VIDEO_OUTPUT_CHANNELS)) ||
+ (frame_width == 0U) ||
+ (frame_height == 0U) ||
+ (frame_rate == 0U) ||
+ (color_format <= COLOR_FORMAT_BEGIN) ||
+ (color_format >= COLOR_FORMAT_END)) {
+ return VIDEO_DRV_ERROR_PARAMETER;
+ }
+
+ switch (color_format) {
+ case COLOR_GRAYSCALE8:
+ pixel_size = 8U;
+ break;
+ case COLOR_YUV420:
+ pixel_size = 12U;
+ break;
+ case COLOR_BGR565:
+ pixel_size = 16U;
+ break;
+ case COLOR_RGB888:
+ case COLOR_NV12:
+ case COLOR_NV21:
+ pixel_size = 24U;
+ break;
+ default:
+ return VIDEO_DRV_ERROR_PARAMETER;
+ }
+
+ block_size = (((frame_width * frame_height) * pixel_size) + 7U) / 8U;
+ block_size = (block_size + 3U) & ~3U;
+
+ if (Initialized == 0U) {
+ return VIDEO_DRV_ERROR;
+ }
+
+ if ((pVideo[channel]->Reg_STATUS & Reg_STATUS_ACTIVE_Msk) != 0U) {
+ return VIDEO_DRV_ERROR;
+ }
+
+ pVideo[channel]->Reg_FRAME_WIDTH = frame_width;
+ pVideo[channel]->Reg_FRAME_HEIGHT = frame_height;
+ pVideo[channel]->Reg_COLOR_FORMAT = color_format;
+ pVideo[channel]->Reg_FRAME_RATE = frame_rate;
+ pVideo[channel]->Timer.Interval = 1000000U / frame_rate;
+ pVideo[channel]->DMA.BlockSize = block_size;
+
+ Configured[channel] = 1U;
+
+ return VIDEO_DRV_OK;
+}
+
+// Set Video Interface buffer
+int32_t VideoDrv_SetBuf (uint32_t channel, void *buf, uint32_t buf_size) {
+ uint32_t block_num;
+
+ if ((((channel & 1U) == 0U) && ((channel >> 1) >= VIDEO_INPUT_CHANNELS)) ||
+ (((channel & 1U) != 0U) && ((channel >> 1) >= VIDEO_OUTPUT_CHANNELS)) ||
+ (buf == NULL) ||
+ (buf_size == 0U)) {
+ return VIDEO_DRV_ERROR_PARAMETER;
+ }
+
+ if ((Initialized == 0U) ||
+ (Configured[channel] == 0U)) {
+ return VIDEO_DRV_ERROR;
+ }
+
+ if ((pVideo[channel]->Reg_STATUS & Reg_STATUS_ACTIVE_Msk) != 0U) {
+ return VIDEO_DRV_ERROR;
+ }
+
+ block_num = buf_size / pVideo[channel]->DMA.BlockSize;
+ if (block_num == 0U) {
+ return VIDEO_DRV_ERROR;
+ }
+
+ pVideo[channel]->Reg_FRAME_COUNT_MAX = block_num;
+ pVideo[channel]->DMA.BlockNum = block_num;
+
+ pVideo[channel]->DMA.Address = (uint32_t)buf;
+
+ Configured[channel] = 2U;
+
+ return VIDEO_DRV_OK;
+}
+
+// Flush Video Interface buffer
+int32_t VideoDrv_FlushBuf (uint32_t channel) {
+
+ if ((((channel & 1U) == 0U) && ((channel >> 1) >= VIDEO_INPUT_CHANNELS)) ||
+ (((channel & 1U) != 0U) && ((channel >> 1) >= VIDEO_OUTPUT_CHANNELS))) {
+ return VIDEO_DRV_ERROR_PARAMETER;
+ }
+
+ if (Initialized == 0U) {
+ return VIDEO_DRV_ERROR;
+ }
+
+ if ((pVideo[channel]->Reg_STATUS & Reg_STATUS_ACTIVE_Msk) != 0U) {
+ return VIDEO_DRV_ERROR;
+ }
+
+ pVideo[channel]->Reg_CONTROL = Reg_CONTROL_BUF_FLUSH_Msk;
+
+ return VIDEO_DRV_OK;
+}
+
+// Start Stream on Video Interface
+int32_t VideoDrv_StreamStart (uint32_t channel, uint32_t mode) {
+ uint32_t control;
+
+ if ((((channel & 1U) == 0U) && ((channel >> 1) >= VIDEO_INPUT_CHANNELS)) ||
+ (((channel & 1U) != 0U) && ((channel >> 1) >= VIDEO_OUTPUT_CHANNELS)) ||
+ (mode > VIDEO_DRV_MODE_CONTINUOS)) {
+ return VIDEO_DRV_ERROR_PARAMETER;
+ }
+
+ if ((Initialized == 0U) ||
+ (Configured[channel] < 2U)) {
+ return VIDEO_DRV_ERROR;
+ }
+
+ if ((pVideo[channel]->Reg_STATUS & Reg_STATUS_ACTIVE_Msk) != 0U) {
+ return VIDEO_DRV_OK;
+ }
+
+ control = Reg_CONTROL_ENABLE_Msk;
+ if (mode == VIDEO_DRV_MODE_CONTINUOS) {
+ control |= Reg_CONTROL_CONTINUOS_Msk;
+ }
+ pVideo[channel]->Reg_CONTROL = control;
+
+
+ if ((pVideo[channel]->Reg_STATUS & Reg_STATUS_ACTIVE_Msk) == 0U) {
+ return VIDEO_DRV_ERROR;
+ }
+
+ control = ARM_VSI_DMA_Enable_Msk;
+ if ((channel & 1U) == 0U) {
+ control |= ARM_VSI_DMA_Direction_P2M;
+ } else {
+ control |= ARM_VSI_DMA_Direction_M2P;
+ }
+ pVideo[channel]->DMA.Control = control;
+
+ control = ARM_VSI_Timer_Run_Msk |
+ ARM_VSI_Timer_Trig_DMA_Msk |
+ ARM_VSI_Timer_Trig_IRQ_Msk;
+ if (mode == VIDEO_DRV_MODE_CONTINUOS) {
+ control |= ARM_VSI_Timer_Periodic_Msk;
+ }
+ pVideo[channel]->Timer.Control = control;
+
+ return VIDEO_DRV_OK;
+}
+
+// Stop Stream on Video Interface
+int32_t VideoDrv_StreamStop (uint32_t channel) {
+
+ if ((((channel & 1U) == 0U) && ((channel >> 1) >= VIDEO_INPUT_CHANNELS)) ||
+ (((channel & 1U) != 0U) && ((channel >> 1) >= VIDEO_OUTPUT_CHANNELS))) {
+ return VIDEO_DRV_ERROR_PARAMETER;
+ }
+
+ if ((Initialized == 0U) ||
+ (Configured[channel] < 2U)) {
+ return VIDEO_DRV_ERROR;
+ }
+
+ if ((pVideo[channel]->Reg_STATUS & Reg_STATUS_ACTIVE_Msk) == 0U) {
+ return VIDEO_DRV_OK;
+ }
+
+ pVideo[channel]->Timer.Control = 0U;
+ pVideo[channel]->DMA.Control = 0U;
+ pVideo[channel]->Reg_CONTROL = 0U;
+
+ return VIDEO_DRV_OK;
+}
+
+// Get Video Frame buffer
+void *VideoDrv_GetFrameBuf (uint32_t channel) {
+ void *frame = NULL;
+
+ if ((((channel & 1U) == 0U) && ((channel >> 1) >= VIDEO_INPUT_CHANNELS)) ||
+ (((channel & 1U) != 0U) && ((channel >> 1) >= VIDEO_OUTPUT_CHANNELS))) {
+ return NULL;
+ }
+
+ if ((Initialized == 0U) ||
+ (Configured[channel] < 2U)) {
+ return NULL;
+ }
+
+ if ((pVideo[channel]->Reg_MODE & Reg_MODE_IO_Msk) == Reg_MODE_Input) {
+ // Input
+ if ((pVideo[channel]->Reg_STATUS & Reg_STATUS_BUF_EMPTY_Msk) != 0U) {
+ return NULL;
+ }
+ } else {
+ // Output
+ if ((pVideo[channel]->Reg_STATUS & Reg_STATUS_BUF_FULL_Msk) != 0U) {
+ return NULL;
+ }
+ }
+
+ frame = (void *)(pVideo[channel]->DMA.Address + (pVideo[channel]->Reg_FRAME_INDEX * pVideo[channel]->DMA.BlockSize));
+
+ return frame;
+}
+
+// Release Video Frame
+int32_t VideoDrv_ReleaseFrame (uint32_t channel) {
+
+ if ((((channel & 1U) == 0U) && ((channel >> 1) >= VIDEO_INPUT_CHANNELS)) ||
+ (((channel & 1U) != 0U) && ((channel >> 1) >= VIDEO_OUTPUT_CHANNELS))) {
+ return VIDEO_DRV_ERROR_PARAMETER;
+ }
+
+ if ((Initialized == 0U) ||
+ (Configured[channel] < 2U)) {
+ return VIDEO_DRV_ERROR;
+ }
+
+ if ((pVideo[channel]->Reg_MODE & Reg_MODE_IO_Msk) == Reg_MODE_Input) {
+ // Input
+ if ((pVideo[channel]->Reg_STATUS & Reg_STATUS_BUF_EMPTY_Msk) != 0U) {
+ return VIDEO_DRV_ERROR;
+ }
+ } else {
+ // Output
+ if ((pVideo[channel]->Reg_STATUS & Reg_STATUS_BUF_FULL_Msk) != 0U) {
+ return VIDEO_DRV_ERROR;
+ }
+ }
+
+ pVideo[channel]->Reg_FRAME_INDEX = 0U;
+
+ return VIDEO_DRV_OK;
+}
+
+
+// Get Video Interface status
+VideoDrv_Status_t VideoDrv_GetStatus (uint32_t channel) {
+ VideoDrv_Status_t status = { 0U, 0U, 0U, 0U, 0U, 0U, 0U };
+ uint32_t status_reg;
+
+ if ((((channel & 1U) == 0U) && ((channel >> 1) < VIDEO_INPUT_CHANNELS)) ||
+ (((channel & 1U) != 0U) && ((channel >> 1) < VIDEO_OUTPUT_CHANNELS))) {
+ status_reg = pVideo[channel]->Reg_STATUS;
+ status.active = (status_reg & Reg_STATUS_ACTIVE_Msk) >> Reg_STATUS_ACTIVE_Pos;
+ status.buf_empty = (status_reg & Reg_STATUS_BUF_EMPTY_Msk) >> Reg_STATUS_BUF_EMPTY_Pos;
+ status.buf_full = (status_reg & Reg_STATUS_BUF_FULL_Msk) >> Reg_STATUS_BUF_FULL_Pos;
+ status.overflow = (status_reg & Reg_STATUS_OVERFLOW_Msk) >> Reg_STATUS_OVERFLOW_Pos;
+ status.underflow = (status_reg & Reg_STATUS_UNDERFLOW_Msk) >> Reg_STATUS_UNDERFLOW_Pos;
+ status.eos = (status_reg & Reg_STATUS_EOS_Msk) >> Reg_STATUS_EOS_Pos;
+ }
+
+ return status;
+}
diff --git a/source/hal/source/platform/mps3/CMakeLists.txt b/source/hal/source/platform/mps3/CMakeLists.txt
index 5008f0b..2791150 100644
--- a/source/hal/source/platform/mps3/CMakeLists.txt
+++ b/source/hal/source/platform/mps3/CMakeLists.txt
@@ -1,5 +1,5 @@
#----------------------------------------------------------------------------
-# SPDX-FileCopyrightText: Copyright 2022 Arm Limited and/or its affiliates <open-source-office@arm.com>
+# SPDX-FileCopyrightText: Copyright 2022, 2024 Arm Limited and/or its affiliates <open-source-office@arm.com>
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -133,6 +133,18 @@ if (CPU_PROFILE_ENABLED)
target_compile_definitions(${PLATFORM_DRIVERS_TARGET} PUBLIC CPU_PROFILE_ENABLED)
endif()
+# If Virtual Streaming Interface is enabled, we need to link the vsi driver
+if (VSI_ENABLED)
+ target_sources(${PLATFORM_DRIVERS_TARGET}
+ PRIVATE
+ source/vsi_mps3.c)
+ add_subdirectory(${COMPONENTS_DIR}/vsi ${CMAKE_BINARY_DIR}/vsi)
+
+ target_link_libraries(${PLATFORM_DRIVERS_TARGET}
+ PUBLIC
+ arm_vsi)
+endif ()
+
# If Ethos-U is enabled, we need the driver library too
if (ETHOS_U_NPU_ENABLED)
diff --git a/source/hal/source/platform/mps3/include/sse-300/peripheral_irqs.h b/source/hal/source/platform/mps3/include/sse-300/peripheral_irqs.h
index 2085c6a..9fb7b9e 100644
--- a/source/hal/source/platform/mps3/include/sse-300/peripheral_irqs.h
+++ b/source/hal/source/platform/mps3/include/sse-300/peripheral_irqs.h
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: Copyright 2022 Arm Limited and/or its affiliates <open-source-office@arm.com>
+ * SPDX-FileCopyrightText: Copyright 2022, 2024 Arm Limited and/or its affiliates <open-source-office@arm.com>
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -131,6 +131,14 @@
#define UARTRX5_IRQn (125) /* UART 5 RX Interrupt */
#define UARTTX5_IRQn (126) /* UART 5 TX Interrupt */
#define UART5_IRQn (127) /* UART 5 combined Interrupt */
+#define ARM_VSI0_IRQn (224) /* 224: VSI 0 */
+#define ARM_VSI1_IRQn (225) /* 225: VSI 1 */
+#define ARM_VSI2_IRQn (226) /* 226: VSI 2 */
+#define ARM_VSI3_IRQn (227) /* 227: VSI 3 */
+#define ARM_VSI4_IRQn (228) /* 228: VSI 4 */
+#define ARM_VSI5_IRQn (229) /* 229: VSI 5 */
+#define ARM_VSI6_IRQn (230) /* 230: VSI 6 */
+#define ARM_VSI7_IRQn (231) /* 231: VSI 7 */
/* #undef HDCLCD_IRQn */
#endif /* PERIPHERAL_IRQS_H */
diff --git a/source/hal/source/platform/mps3/include/sse-310/peripheral_irqs.h b/source/hal/source/platform/mps3/include/sse-310/peripheral_irqs.h
index 95b62c7..0414f63 100644
--- a/source/hal/source/platform/mps3/include/sse-310/peripheral_irqs.h
+++ b/source/hal/source/platform/mps3/include/sse-310/peripheral_irqs.h
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: Copyright 2022 Arm Limited and/or its affiliates <open-source-office@arm.com>
+ * SPDX-FileCopyrightText: Copyright 2022, 2024 Arm Limited and/or its affiliates <open-source-office@arm.com>
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -129,6 +129,14 @@
#define UARTRX5_IRQn (125) /* UART 5 RX Interrupt */
#define UARTTX5_IRQn (126) /* UART 5 TX Interrupt */
#define UART5_IRQn (127) /* UART 5 combined Interrupt */
+#define ARM_VSI0_IRQn (224) /* 224: VSI 0 */
+#define ARM_VSI1_IRQn (225) /* 225: VSI 1 */
+#define ARM_VSI2_IRQn (226) /* 226: VSI 2 */
+#define ARM_VSI3_IRQn (227) /* 227: VSI 3 */
+#define ARM_VSI4_IRQn (228) /* 228: VSI 4 */
+#define ARM_VSI5_IRQn (229) /* 229: VSI 5 */
+#define ARM_VSI6_IRQn (230) /* 230: VSI 6 */
+#define ARM_VSI7_IRQn (231) /* 231: VSI 7 */
/* #undef HDCLCD_IRQn */
#endif /* PERIPHERAL_IRQS_H */
diff --git a/source/hal/source/platform/mps3/include/vsi_mps3.h b/source/hal/source/platform/mps3/include/vsi_mps3.h
new file mode 100644
index 0000000..a8895ea
--- /dev/null
+++ b/source/hal/source/platform/mps3/include/vsi_mps3.h
@@ -0,0 +1,115 @@
+/*
+ * SPDX-FileCopyrightText: Copyright 2024 Arm Limited and/or its affiliates <open-source-office@arm.com>
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef VSI_MPS3_H
+#define VSI_MPS3_H
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "peripheral_irqs.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef __IM
+#define __IM volatile const /*! Defines 'read only' structure member permissions */
+#endif
+#ifndef __OM
+#define __OM volatile /*! Defines 'write only' structure member permissions */
+#endif
+#ifndef __IOM
+#define __IOM volatile /*! Defines 'read/write' structure member permissions */
+#endif
+
+/// Structure type to access the virtual streaming interface
+typedef struct
+{
+ /// Interrupt Request (IRQ)
+ struct {
+ __IOM uint32_t Enable; /*!< (R/W) IRQ Enable */
+ __OM uint32_t Set; /*!< (-/W) IRQ Set */
+ __OM uint32_t Clear; /*!< (-/W) IRQ Clear */
+ __IM uint32_t Status; /*!< (R/-) IRQ Status */
+ } IRQ;
+ uint32_t reserved1[60];
+ /// Time counter with 1MHz input frequency
+ struct {
+ __IOM uint32_t Control; /*!< (R/W) Timer Control */
+ __IOM uint32_t Interval; /*!< (R/W) Timer Interval Value (in microseconds) */
+ __IM uint32_t Count; /*!< (R/-) Timer Overflow Count */
+ } Timer;
+ uint32_t reserved2[61];
+ /// Direct Memory Access (DMA) Controller
+ struct {
+ __IOM uint32_t Control; /*!< (R/W) DMA Control */
+ __IOM uint32_t Address; /*!< (R/W) DMA Memory Start Address */
+ __IOM uint32_t BlockSize; /*!< (R/W) DMA Block Size (in bytes, multiple of 4) */
+ __IOM uint32_t BlockNum; /*!< (R/W) DMA Number of Blocks (must be 2^n) */
+ __IM uint32_t BlockIndex; /*!< (R/-) DMA Block Index */
+ } DMA;
+ uint32_t reserved3[59];
+ __IOM uint32_t Regs[64]; /*!< (R/W) User Registers */
+} ARM_VSI_Type;
+
+/* VSI Timer Control Definitions for Timer.Control register */
+#define ARM_VSI_Timer_Run_Pos 0U /*!< Timer Control: Run Position */
+#define ARM_VSI_Timer_Run_Msk (1UL << ARM_VSI_Timer_Run_Pos) /*!< Timer Control: Run Mask */
+#define ARM_VSI_Timer_Periodic_Pos 1U /*!< Timer Control: Periodic Position */
+#define ARM_VSI_Timer_Periodic_Msk (1UL << ARM_VSI_Timer_Periodic_Pos) /*!< Timer Control: Periodic Mask */
+#define ARM_VSI_Timer_Trig_IRQ_Pos 2U /*!< Timer Control: Trig_IRQ Position */
+#define ARM_VSI_Timer_Trig_IRQ_Msk (1UL << ARM_VSI_Timer_Trig_IRQ_Pos) /*!< Timer Control: Trig_IRQ Mask */
+#define ARM_VSI_Timer_Trig_DMA_Pos 3U /*!< Timer Control: Trig_DAM Position */
+#define ARM_VSI_Timer_Trig_DMA_Msk (1UL << ARM_VSI_Timer_Trig_DMA_Pos) /*!< Timer Control: Trig_DMA Mask */
+
+/* VSI DMA Control Definitions for DMA.Control register */
+#define ARM_VSI_DMA_Enable_Pos 0U /*!< DMA Control: Enable Position */
+#define ARM_VSI_DMA_Enable_Msk (1UL << ARM_VSI_DMA_Enable_Pos) /*!< DMA Control: Enable Mask */
+#define ARM_VSI_DMA_Direction_Pos 1U /*!< DMA Control: Direction Position */
+#define ARM_VSI_DMA_Direction_Msk (1UL << ARM_VSI_DMA_Direction_Pos) /*!< DMA Control: Direction Mask */
+#define ARM_VSI_DMA_Direction_P2M (0UL*ARM_VSI_DMA_Direction_Msk) /*!< DMA Control: Direction P2M */
+#define ARM_VSI_DMA_Direction_M2P (1UL*ARM_VSI_DMA_Direction_Msk) /*!< DMA Control: Direction M2P */
+
+/* Memory mapping of 8 VSI peripherals */
+#define ARM_VSI0_BASE (0x4FF00000UL) /*!< VSI 0 Base Address */
+#define ARM_VSI1_BASE (0x4FF10000UL) /*!< VSI 1 Base Address */
+#define ARM_VSI2_BASE (0x4FF20000UL) /*!< VSI 2 Base Address */
+#define ARM_VSI3_BASE (0x4FF30000UL) /*!< VSI 3 Base Address */
+#define ARM_VSI4_BASE (0x4FF40000UL) /*!< VSI 4 Base Address */
+#define ARM_VSI5_BASE (0x4FF50000UL) /*!< VSI 5 Base Address */
+#define ARM_VSI6_BASE (0x4FF60000UL) /*!< VSI 6 Base Address */
+#define ARM_VSI7_BASE (0x4FF70000UL) /*!< VSI 7 Base Address */
+#define ARM_VSI0 ((ARM_VSI_Type *)ARM_VSI0_BASE) /*!< VSI 0 struct */
+#define ARM_VSI1 ((ARM_VSI_Type *)ARM_VSI1_BASE) /*!< VSI 1 struct */
+#define ARM_VSI2 ((ARM_VSI_Type *)ARM_VSI2_BASE) /*!< VSI 2 struct */
+#define ARM_VSI3 ((ARM_VSI_Type *)ARM_VSI3_BASE) /*!< VSI 3 struct */
+#define ARM_VSI4 ((ARM_VSI_Type *)ARM_VSI4_BASE) /*!< VSI 4 struct */
+#define ARM_VSI5 ((ARM_VSI_Type *)ARM_VSI5_BASE) /*!< VSI 5 struct */
+#define ARM_VSI6 ((ARM_VSI_Type *)ARM_VSI6_BASE) /*!< VSI 6 struct */
+#define ARM_VSI7 ((ARM_VSI_Type *)ARM_VSI7_BASE) /*!< VSI 7 struct */
+
+/**
+ * @brief Initialises the VSI
+ * @return 0 if successful, error code otherwise
+ **/
+int vsi_init(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* VSI_MPS3_H */
diff --git a/source/hal/source/platform/mps3/source/platform_drivers.c b/source/hal/source/platform/mps3/source/platform_drivers.c
index 73b388b..1f55bb9 100644
--- a/source/hal/source/platform/mps3/source/platform_drivers.c
+++ b/source/hal/source/platform/mps3/source/platform_drivers.c
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: Copyright 2022-2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
+ * SPDX-FileCopyrightText: Copyright 2022-2024 Arm Limited and/or its affiliates <open-source-office@arm.com>
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -40,6 +40,10 @@
#endif /* ARM_NPU */
+#if VSI_ENABLED
+#include "vsi_mps3.h"
+#endif /* VSI_ENABLED */
+
/**
* @brief Checks if the platform is valid by checking
* the CPU ID for the FPGA implementation against
@@ -94,6 +98,12 @@ int platform_init(void)
#endif /* ARM_NPU */
+#if VSI_ENABLED
+ if (0 != (err = vsi_init())) {
+ return err;
+ }
+#endif /* VSI_ENABLED */
+
/* Print target design info */
info("Target system design: %s\n", s_platform_name);
return 0;
diff --git a/source/hal/source/platform/mps3/source/vsi_mps3.c b/source/hal/source/platform/mps3/source/vsi_mps3.c
new file mode 100644
index 0000000..8516c1c
--- /dev/null
+++ b/source/hal/source/platform/mps3/source/vsi_mps3.c
@@ -0,0 +1,62 @@
+/*
+ * SPDX-FileCopyrightText: Copyright 2024 Arm Limited and/or its affiliates <open-source-office@arm.com>
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "vsi_mps3.h"
+
+#include "log_macros.h"
+#include "RTE_Components.h"
+#include "peripheral_irqs.h"
+
+#include "video_drv.h"
+
+/* Exception / Interrupt Handler */
+#define DEFAULT_IRQ_HANDLER(handler_name) \
+void __WEAK __NO_RETURN handler_name(void); \
+void handler_name(void) { \
+ while(1); \
+}
+
+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)
+
+int vsi_init(void)
+{
+ /* Register the VSI handlers in our vector table. */
+ NVIC_SetVector(ARM_VSI0_IRQn, (uint32_t)ARM_VSI0_Handler);
+ NVIC_SetVector(ARM_VSI1_IRQn, (uint32_t)ARM_VSI1_Handler);
+ NVIC_SetVector(ARM_VSI2_IRQn, (uint32_t)ARM_VSI2_Handler);
+ NVIC_SetVector(ARM_VSI3_IRQn, (uint32_t)ARM_VSI3_Handler);
+ NVIC_SetVector(ARM_VSI4_IRQn, (uint32_t)ARM_VSI4_Handler);
+ NVIC_SetVector(ARM_VSI5_IRQn, (uint32_t)ARM_VSI5_Handler);
+ NVIC_SetVector(ARM_VSI6_IRQn, (uint32_t)ARM_VSI6_Handler);
+ NVIC_SetVector(ARM_VSI7_IRQn, (uint32_t)ARM_VSI7_Handler);
+
+ /* Initialize Video VSI. */
+ if (VideoDrv_Initialize(NULL) != VIDEO_DRV_OK) {
+ printf_err("Failed to initialise video driver\n");
+ return 1;
+ }
+
+ info("VSI device initialised\n");
+
+ return 0;
+}
diff --git a/source/use_case/img_class/usecase.cmake b/source/use_case/img_class/usecase.cmake
index 4c25989..f18522c 100644
--- a/source/use_case/img_class/usecase.cmake
+++ b/source/use_case/img_class/usecase.cmake
@@ -1,5 +1,5 @@
#----------------------------------------------------------------------------
-# SPDX-FileCopyrightText: Copyright 2021 Arm Limited and/or its affiliates <open-source-office@arm.com>
+# SPDX-FileCopyrightText: Copyright 2021, 2024 Arm Limited and/or its affiliates <open-source-office@arm.com>
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -28,10 +28,12 @@ USER_OPTION(${use_case}_LABELS_TXT_FILE "Labels' txt file for the chosen model"
FILEPATH)
# Generate input files
-generate_images_code("${${use_case}_FILE_PATH}"
- ${SRC_GEN_DIR}
- ${INC_GEN_DIR}
- "${${use_case}_IMAGE_SIZE}")
+generate_images_code(
+ INPUT_DIR "${${use_case}_FILE_PATH}"
+ SRC_OUT ${SRC_GEN_DIR}
+ HDR_OUT ${INC_GEN_DIR}
+ IMG_SIZE "${${use_case}_IMAGE_SIZE}"
+)
# Generate labels file
set(${use_case}_LABELS_CPP_FILE Labels)
diff --git a/source/use_case/object_detection/include/UseCaseHandler.hpp b/source/use_case/object_detection/include/UseCaseHandler.hpp
index 9fe716f..43fb6bf 100644
--- a/source/use_case/object_detection/include/UseCaseHandler.hpp
+++ b/source/use_case/object_detection/include/UseCaseHandler.hpp
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: Copyright 2022 Arm Limited and/or its affiliates <open-source-office@arm.com>
+ * SPDX-FileCopyrightText: Copyright 2022, 2024 Arm Limited and/or its affiliates <open-source-office@arm.com>
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,11 +17,39 @@
#ifndef OBJ_DET_HANDLER_HPP
#define OBJ_DET_HANDLER_HPP
+#if VSI_ENABLED
+#include "DetectionResult.hpp"
+#include <vector>
+#endif
+
+#include <cstdint>
#include "AppContext.hpp"
namespace arm {
namespace app {
+#if VSI_ENABLED
+ typedef object_detection::DetectionResult OdResults;
+
+ /**
+ * @brief Draw boxe(s) detected by the model.
+ * @param[in] image Pointer to the image.
+ * @param[in] imageWidth Image width.
+ * @param[in] imageHeight Image height.
+ * @param[in] results A vector of detection results.
+ **/
+ void DrawDetectionBoxesVsi(uint8_t* image,
+ const uint32_t imageWidth,
+ const uint32_t imageHeight,
+ const std::vector<OdResults>& results);
+ /**
+ * @brief Handles the inference event when using VSI.
+ * @param[in] ctx Pointer to the application context.
+ * @return true or false based on execution success.
+ **/
+ bool ObjectDetectionHandlerVsi(ApplicationContext& ctx);
+#endif
+
/**
* @brief Handles the inference event.
* @param[in] ctx Pointer to the application context.
diff --git a/source/use_case/object_detection/src/MainLoop.cc b/source/use_case/object_detection/src/MainLoop.cc
index 4735bcb..fe21de6 100644
--- a/source/use_case/object_detection/src/MainLoop.cc
+++ b/source/use_case/object_detection/src/MainLoop.cc
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: Copyright 2022 Arm Limited and/or its affiliates <open-source-office@arm.com>
+ * SPDX-FileCopyrightText: Copyright 2022, 2024 Arm Limited and/or its affiliates <open-source-office@arm.com>
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -41,7 +41,12 @@ static void DisplayDetectionMenu()
printf(" %u. Run detection ifm at chosen index\n", common::MENU_OPT_RUN_INF_CHOSEN);
printf(" %u. Run detection on all ifm\n", common::MENU_OPT_RUN_INF_ALL);
printf(" %u. Show NN model info\n", common::MENU_OPT_SHOW_MODEL_INFO);
- printf(" %u. List ifm\n\n", common::MENU_OPT_LIST_IFM);
+ printf(" %u. List ifm\n", common::MENU_OPT_LIST_IFM);
+#if VSI_ENABLED
+ fflush(stdout);
+ printf(" %u. Run detection using VSI as input\n", common::MENU_OPT_RUN_INF_VSI);
+#endif
+ printf("\n");
printf(" Choice: ");
fflush(stdout);
}
@@ -99,6 +104,11 @@ void main_loop()
case common::MENU_OPT_LIST_IFM:
executionSuccessful = ListFilesHandler(caseContext);
break;
+#if VSI_ENABLED
+ case common::MENU_OPT_RUN_INF_VSI:
+ executionSuccessful = ObjectDetectionHandlerVsi(caseContext);
+ break;
+#endif
default:
printf("Incorrect choice, try again.");
break;
diff --git a/source/use_case/object_detection/src/UseCaseHandler.cc b/source/use_case/object_detection/src/UseCaseHandler.cc
index 9330187..1a20db5 100644
--- a/source/use_case/object_detection/src/UseCaseHandler.cc
+++ b/source/use_case/object_detection/src/UseCaseHandler.cc
@@ -1,5 +1,5 @@
/*
- * SPDX-FileCopyrightText: Copyright 2022 Arm Limited and/or its affiliates
+ * SPDX-FileCopyrightText: Copyright 2022, 2024 Arm Limited and/or its affiliates
* <open-source-office@arm.com> SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -28,6 +28,235 @@
namespace arm {
namespace app {
+#if VSI_ENABLED
+#include "video_drv.h" /* Video Driver API. */
+
+ /**
+ * @brief Draws a box in the image using the object detection result object.
+ *
+ * @param[out] imageData Pointer to the start of the image.
+ * @param[in] width Image width.
+ * @param[in] height Image height.
+ * @param[in] result Object detection result.
+ */
+ static void DrawBox(uint8_t* imageData,
+ const uint32_t width,
+ const uint32_t height,
+ const OdResults& result)
+ {
+ UNUSED(height);
+ const auto x = result.m_x0;
+ const auto y = result.m_y0;
+ const auto w = result.m_w;
+ const auto h = result.m_h;
+
+ const uint32_t step = width * 3;
+ uint8_t* const imStart = imageData + (y * step) + (x * 3);
+
+ uint8_t* dst_0 = imStart;
+ uint8_t* dst_1 = imStart + (h * step);
+
+ for (uint32_t i = 0; i < static_cast<uint32_t>(w); ++i) {
+ *dst_0 = 255;
+ *dst_1 = 255;
+
+ dst_0 += 3;
+ dst_1 += 3;
+ }
+
+ dst_0 = imStart;
+ dst_1 = imStart + (w * 3);
+
+ for (uint32_t j = 0; j < static_cast<uint32_t>(h); ++j) {
+ *dst_0 = 255;
+ *dst_1 = 255;
+
+ dst_0 += step;
+ dst_1 += step;
+ }
+ }
+
+ void DrawDetectionBoxesVsi(uint8_t* image,
+ const uint32_t imageWidth,
+ const uint32_t imageHeight,
+ const std::vector<OdResults>& results)
+ {
+ for (const auto& result : results) {
+ DrawBox(image, imageWidth, imageHeight, result);
+ printf("Detection :: [%d" ", %d"
+ ", %d" ", %d" "]\n",
+ result.m_x0,
+ result.m_y0,
+ result.m_w,
+ result.m_h);
+ }
+ }
+
+ /* Object detection VSI inference handler. */
+ bool ObjectDetectionHandlerVsi(ApplicationContext& ctx)
+ {
+ /* Image buffer. */
+ static uint8_t ImageBuf[IMAGE_DATA_SIZE];
+ static uint8_t ImageOut[IMAGE_DATA_SIZE];
+
+ /* Model object creation and initialisation. */
+ auto& model = ctx.Get<Model&>("model");
+
+ TfLiteTensor* inputTensor = model.GetInputTensor(0);
+ TfLiteTensor* outputTensor0 = model.GetOutputTensor(0);
+ TfLiteTensor* outputTensor1 = model.GetOutputTensor(1);
+
+ if (!inputTensor->dims) {
+ printf_err("Invalid input tensor dims\n");
+ return false;
+ } else if (inputTensor->dims->size < 3) {
+ printf_err("Input tensor dimension should be >= 3\n");
+ return false;
+ }
+
+ TfLiteIntArray* inputShape = model.GetInputShape(0);
+ const int inputImgCols = inputShape->data[arm::app::YoloFastestModel::ms_inputColsIdx];
+ const int inputImgRows = inputShape->data[arm::app::YoloFastestModel::ms_inputRowsIdx];
+
+ /* Set up pre- and post-processing. */
+ arm::app::DetectorPreProcess preProcess =
+ arm::app::DetectorPreProcess(inputTensor, true, model.IsDataSigned());
+
+ std::vector<arm::app::OdResults> results;
+ const arm::app::object_detection::PostProcessParams postProcessParams{
+ inputImgRows,
+ inputImgCols,
+ arm::app::object_detection::originalImageSize,
+ arm::app::object_detection::anchor1,
+ arm::app::object_detection::anchor2};
+ arm::app::DetectorPostProcess postProcess =
+ arm::app::DetectorPostProcess(outputTensor0, outputTensor1, results, postProcessParams);
+
+ const size_t imgSz = inputTensor->bytes < IMAGE_DATA_SIZE ?
+ inputTensor->bytes : IMAGE_DATA_SIZE;
+
+ if (sizeof(ImageBuf) < imgSz) {
+ printf_err("Image buffer is insufficient\n");
+ return false;
+ }
+
+ /* Configure Input Video. */
+ if (VideoDrv_Configure(VIDEO_DRV_IN0,
+ arm::app::object_detection::originalImageSize,
+ arm::app::object_detection::originalImageSize,
+ COLOR_RGB888, 24U) != VIDEO_DRV_OK) {
+ printf_err("Failed to configure video input\n");
+ return false;
+ }
+
+ /* Set Input Video buffer. */
+ if (VideoDrv_SetBuf(VIDEO_DRV_IN0, ImageBuf, IMAGE_DATA_SIZE) != VIDEO_DRV_OK) {
+ printf_err("Failed to set buffer for video input\n");
+ return false;
+ }
+
+ /* Set Output Video file (only when using AVH - default: Display) */
+ // if (VideoDrv_SetFile(VIDEO_DRV_OUT0, "output_image.png") != VIDEO_DRV_OK) {
+ // printf_err("Failed to set filename for video output\n");
+ // return 1;
+ // }
+ /* Configure Output Video. */
+ if (VideoDrv_Configure(VIDEO_DRV_OUT0,
+ arm::app::object_detection::originalImageSize,
+ arm::app::object_detection::originalImageSize,
+ COLOR_RGB888, 24U) != VIDEO_DRV_OK) {
+ printf_err("Failed to configure video output\n");
+ return false;
+ }
+
+ /* Set Output Video buffer. */
+ if (VideoDrv_SetBuf(VIDEO_DRV_OUT0, ImageOut, IMAGE_DATA_SIZE) != VIDEO_DRV_OK) {
+ printf_err("Failed to set buffer for video output\n");
+ return false;
+ }
+
+ auto imgCount = ctx.Get<uint32_t>("imgIndex");
+ void* imgFrame = nullptr;
+ void* outFrame = nullptr;
+
+ while (true) {
+#if VSI_IMAGE_INPUT
+ if (VideoDrv_SetFile(VIDEO_DRV_IN0, GetFilePath(imgCount)) != VIDEO_DRV_OK) {
+ printf_err("Failed to set filename for video input\n");
+ return false;
+ }
+#endif
+
+ VideoDrv_Status_t status;
+
+ results.clear();
+
+ /* Start video capture (single frame). */
+ if (VideoDrv_StreamStart(VIDEO_DRV_IN0, VIDEO_DRV_MODE_SINGLE) != VIDEO_DRV_OK) {
+ printf_err("Failed to start video capture\n");
+ return false;
+ }
+
+ /* Wait for video input frame. */
+ do {
+ status = VideoDrv_GetStatus(VIDEO_DRV_IN0);
+ } while (status.buf_empty != 0U);
+
+ /* Get input video frame buffer. */
+ imgFrame = VideoDrv_GetFrameBuf(VIDEO_DRV_IN0);
+
+ /* Run the pre-processing, inference and post-processing. */
+ if (!preProcess.DoPreProcess(imgFrame, imgSz)) {
+ printf_err("Pre-processing failed.\n");
+ return false;
+ }
+
+ /* Run inference over this image. */
+ printf("\rImage %" PRIu32 "; ", ++imgCount);
+
+ if (!model.RunInference()) {
+ printf_err("Inference failed.\n");
+ return false;
+ }
+
+ if (!postProcess.DoPostProcess()) {
+ printf_err("Post-processing failed.\n");
+ return false;
+ }
+
+ /* Release input frame. */
+ VideoDrv_ReleaseFrame(VIDEO_DRV_IN0);
+
+ arm::app::DrawDetectionBoxesVsi(static_cast<uint8_t*>(imgFrame), inputImgCols, inputImgRows, results);
+
+ /* Get output video frame buffer. */
+ outFrame = VideoDrv_GetFrameBuf(VIDEO_DRV_OUT0);
+
+ /* Copy image frame with detection boxes to output frame buffer. */
+ memcpy(outFrame, imgFrame, IMAGE_DATA_SIZE);
+
+ /* Release output frame. */
+ VideoDrv_ReleaseFrame(VIDEO_DRV_OUT0);
+
+ /* Start video output (single frame). */
+ VideoDrv_StreamStart(VIDEO_DRV_OUT0, VIDEO_DRV_MODE_SINGLE);
+
+ /* Check for end of stream (when using AVH with file as Video input). */
+ if (status.eos != 0U) {
+ while (VideoDrv_GetStatus(VIDEO_DRV_OUT0).buf_empty == 0U);
+ break;
+ }
+ }
+
+ IncrementAppCtxIfmIdx(ctx, "imgIndex");
+
+ /* De-initialize Video Interface. */
+ //VideoDrv_Uninitialize();
+ return true;
+ }
+
+#endif
+
/**
* @brief Presents inference results along using the data presentation
* object.
diff --git a/source/use_case/object_detection/usecase.cmake b/source/use_case/object_detection/usecase.cmake
index a36d3e0..cb0236b 100644
--- a/source/use_case/object_detection/usecase.cmake
+++ b/source/use_case/object_detection/usecase.cmake
@@ -1,5 +1,5 @@
#----------------------------------------------------------------------------
-# SPDX-FileCopyrightText: Copyright 2022 Arm Limited and/or its affiliates <open-source-office@arm.com>
+# SPDX-FileCopyrightText: Copyright 2022, 2024 Arm Limited and/or its affiliates <open-source-office@arm.com>
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -36,10 +36,24 @@ USER_OPTION(${use_case}_CHANNELS_IMAGE_DISPLAYED "Channels' image displayed on t
BOOL)
# Generate input files
-generate_images_code("${${use_case}_FILE_PATH}"
- ${SRC_GEN_DIR}
- ${INC_GEN_DIR}
- "${${use_case}_IMAGE_SIZE}")
+if (VSI_IMAGE_INPUT)
+ set(${use_case}_COMPILE_DEFS "VSI_IMAGE_INPUT")
+
+ generate_images_code(
+ INPUT_DIR "${${use_case}_FILE_PATH}"
+ SRC_OUT ${SRC_GEN_DIR}
+ HDR_OUT ${INC_GEN_DIR}
+ IMG_SIZE "${${use_case}_IMAGE_SIZE}"
+ GENERATE_FILE_PATHS
+ )
+else ()
+ generate_images_code(
+ INPUT_DIR "${${use_case}_FILE_PATH}"
+ SRC_OUT ${SRC_GEN_DIR}
+ HDR_OUT ${INC_GEN_DIR}
+ IMG_SIZE "${${use_case}_IMAGE_SIZE}"
+ )
+endif ()
USER_OPTION(${use_case}_ACTIVATION_BUF_SZ "Activation buffer size for the chosen model"
0x00082000
diff --git a/source/use_case/vww/usecase.cmake b/source/use_case/vww/usecase.cmake
index 7a4d876..99580cc 100644
--- a/source/use_case/vww/usecase.cmake
+++ b/source/use_case/vww/usecase.cmake
@@ -1,5 +1,5 @@
#----------------------------------------------------------------------------
-# SPDX-FileCopyrightText: Copyright 2021 Arm Limited and/or its affiliates <open-source-office@arm.com>
+# SPDX-FileCopyrightText: Copyright 2021, 2024 Arm Limited and/or its affiliates <open-source-office@arm.com>
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -58,7 +58,9 @@ generate_labels_code(
)
# Generate input files
-generate_images_code("${${use_case}_FILE_PATH}"
- ${SRC_GEN_DIR}
- ${INC_GEN_DIR}
- "${${use_case}_IMAGE_SIZE}")
+generate_images_code(
+ INPUT_DIR "${${use_case}_FILE_PATH}"
+ SRC_OUT ${SRC_GEN_DIR}
+ HDR_OUT ${INC_GEN_DIR}
+ IMG_SIZE "${${use_case}_IMAGE_SIZE}"
+)