From 9d0e012b1ccdb7a05e989039bfda5ba7183f58a7 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Fri, 10 Oct 2025 20:15:05 +0200 Subject: [PATCH] ports/qemu: Add qemu port. Signed-off-by: iabdalkader --- boards/MPS2_AN500/imlib_config.h | 164 ++++++++++++++++++++++++++ boards/MPS2_AN500/manifest.py | 5 + boards/MPS2_AN500/omv_boardconfig.h | 71 +++++++++++ boards/MPS2_AN500/omv_boardconfig.mk | 24 ++++ boards/MPS2_AN500/romfs.json | 6 + boards/MPS2_AN500/ulab_config.h | 17 +++ boards/MPS3_AN547/imlib_config.h | 164 ++++++++++++++++++++++++++ boards/MPS3_AN547/manifest.py | 5 + boards/MPS3_AN547/omv_boardconfig.h | 75 ++++++++++++ boards/MPS3_AN547/omv_boardconfig.mk | 25 ++++ boards/MPS3_AN547/romfs.json | 6 + boards/MPS3_AN547/ulab_config.h | 17 +++ common/pendsv.c | 3 +- common/usbdbg.c | 2 + modules/py_omv.c | 4 +- ports/qemu/main.c | 118 +++++++++++++++++++ ports/qemu/omv_csi.c | 85 ++++++++++++++ ports/qemu/omv_i2c.c | 68 +++++++++++ ports/qemu/omv_mpconfigport.h | 50 ++++++++ ports/qemu/omv_portconfig.h | 59 ++++++++++ ports/qemu/omv_portconfig.mk | 170 +++++++++++++++++++++++++++ ports/qemu/qemu.ld.S | 73 ++++++++++++ 22 files changed, 1209 insertions(+), 2 deletions(-) create mode 100644 boards/MPS2_AN500/imlib_config.h create mode 100644 boards/MPS2_AN500/manifest.py create mode 100644 boards/MPS2_AN500/omv_boardconfig.h create mode 100755 boards/MPS2_AN500/omv_boardconfig.mk create mode 100644 boards/MPS2_AN500/romfs.json create mode 100644 boards/MPS2_AN500/ulab_config.h create mode 100644 boards/MPS3_AN547/imlib_config.h create mode 100644 boards/MPS3_AN547/manifest.py create mode 100644 boards/MPS3_AN547/omv_boardconfig.h create mode 100644 boards/MPS3_AN547/omv_boardconfig.mk create mode 100644 boards/MPS3_AN547/romfs.json create mode 100644 boards/MPS3_AN547/ulab_config.h create mode 100644 ports/qemu/main.c create mode 100644 ports/qemu/omv_csi.c create mode 100644 ports/qemu/omv_i2c.c create mode 100644 ports/qemu/omv_mpconfigport.h create mode 100644 ports/qemu/omv_portconfig.h create mode 100644 ports/qemu/omv_portconfig.mk create mode 100644 ports/qemu/qemu.ld.S diff --git a/boards/MPS2_AN500/imlib_config.h b/boards/MPS2_AN500/imlib_config.h new file mode 100644 index 000000000..1e3cabf84 --- /dev/null +++ b/boards/MPS2_AN500/imlib_config.h @@ -0,0 +1,164 @@ +/* + * SPDX-License-Identifier: MIT + * + * Copyright (C) 2025 OpenMV, LLC. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Image library configuration. + */ +#ifndef __IMLIB_CONFIG_H__ +#define __IMLIB_CONFIG_H__ + +// Enable Image I/O +#define IMLIB_ENABLE_IMAGE_IO + +// Enable Image File I/O +#define IMLIB_ENABLE_IMAGE_FILE_IO + +// Enable LAB LUT +#define IMLIB_ENABLE_LAB_LUT + +// Enable YUV LUT +//#define IMLIB_ENABLE_YUV_LUT + +// Enable ISP ops +#define IMLIB_ENABLE_ISP_OPS + +// Enable binary ops +#define IMLIB_ENABLE_BINARY_OPS + +// Enable math ops +#define IMLIB_ENABLE_MATH_OPS + +// Enable flood_fill() +#define IMLIB_ENABLE_FLOOD_FILL + +// Enable mean() +#define IMLIB_ENABLE_MEAN + +// Enable median() +#define IMLIB_ENABLE_MEDIAN + +// Enable mode() +#define IMLIB_ENABLE_MODE + +// Enable midpoint() +#define IMLIB_ENABLE_MIDPOINT + +// Enable morph() +#define IMLIB_ENABLE_MORPH + +// Enable Gaussian +#define IMLIB_ENABLE_GAUSSIAN + +// Enable Laplacian +#define IMLIB_ENABLE_LAPLACIAN + +// Enable bilateral() +#define IMLIB_ENABLE_BILATERAL + +// Enable linpolar() +#define IMLIB_ENABLE_LINPOLAR + +// Enable logpolar() +#define IMLIB_ENABLE_LOGPOLAR + +// Enable lens_corr() +#define IMLIB_ENABLE_LENS_CORR + +// Enable rotation_corr() +#define IMLIB_ENABLE_ROTATION_CORR + +// Enable phasecorrelate() +#if defined(IMLIB_ENABLE_ROTATION_CORR) +#define IMLIB_ENABLE_FIND_DISPLACEMENT +#endif + +// Enable get_similarity() +#define IMLIB_ENABLE_GET_SIMILARITY + +// Enable find_lines() +#define IMLIB_ENABLE_FIND_LINES + +// Enable find_line_segments() +#define IMLIB_ENABLE_FIND_LINE_SEGMENTS + +// Enable find_circles() +#define IMLIB_ENABLE_FIND_CIRCLES + +// Enable find_rects() +#define IMLIB_ENABLE_FIND_RECTS + +// Enable find_qrcodes() (14 KB) +#define IMLIB_ENABLE_QRCODES + +// Enable find_apriltags() (64 KB) +#define IMLIB_ENABLE_APRILTAGS +#define IMLIB_ENABLE_APRILTAGS_TAG36H11 + +// Enable fine find_apriltags() - (8-way connectivity versus 4-way connectivity) +// #define IMLIB_ENABLE_FINE_APRILTAGS + +// Enable high res find_apriltags() - uses more RAM +// #define IMLIB_ENABLE_HIGH_RES_APRILTAGS + +// Enable find_datamatrices() (26 KB) +#define IMLIB_ENABLE_DATAMATRICES + +// Enable find_barcodes() (42 KB) +#define IMLIB_ENABLE_BARCODES + +// Enable find_features() and Haar cascades. +#define IMLIB_ENABLE_FEATURES + +// Enable Tensor Flow +#define IMLIB_ENABLE_STAI + +// Enable AGAST. +#define IMLIB_ENABLE_AGAST + +// Enable find_template() +#define IMLIB_FIND_TEMPLATE + +// Enable find_lbp() +#define IMLIB_ENABLE_FIND_LBP + +// Enable find_keypoints() +#if defined(IMLIB_ENABLE_FAST) || defined(IMLIB_ENABLE_AGAST) +#define IMLIB_ENABLE_FIND_KEYPOINTS +#endif + +// Enable load, save and match descriptor +#define IMLIB_ENABLE_DESCRIPTOR + +// Enable find_hog() +#define IMLIB_ENABLE_HOG + +// Enable selective_search() +#define IMLIB_ENABLE_SELECTIVE_SEARCH + +// Enable PNG encoder/decoder +#define IMLIB_ENABLE_PNG_ENCODER +#define IMLIB_ENABLE_PNG_DECODER + +// Stereo Imaging +#define IMLIB_ENABLE_STEREO_DISPARITY + +#endif //__IMLIB_CONFIG_H__ diff --git a/boards/MPS2_AN500/manifest.py b/boards/MPS2_AN500/manifest.py new file mode 100644 index 000000000..828c076f5 --- /dev/null +++ b/boards/MPS2_AN500/manifest.py @@ -0,0 +1,5 @@ +# OpenMV library +add_library("openmv-lib", "$(OMV_LIB_DIR)") + +# Libraries +require("ml", library="openmv-lib") diff --git a/boards/MPS2_AN500/omv_boardconfig.h b/boards/MPS2_AN500/omv_boardconfig.h new file mode 100644 index 000000000..86a926ee5 --- /dev/null +++ b/boards/MPS2_AN500/omv_boardconfig.h @@ -0,0 +1,71 @@ +/* + * SPDX-License-Identifier: MIT + * + * Copyright (C) 2025 OpenMV, LLC. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Board configuration and pin definitions. + */ +#ifndef __OMV_BOARDCONFIG_H__ +#define __OMV_BOARDCONFIG_H__ + +// Architecture info +#define OMV_BOARD_ARCH "MPS2 AN500" // 33 chars max +#define OMV_BOARD_TYPE "M7" + +// JPEG configuration. +#define OMV_JPEG_CODEC_ENABLE (0) +#define OMV_JPEG_QUALITY_LOW (35) +#define OMV_JPEG_QUALITY_HIGH (60) +#define OMV_JPEG_QUALITY_THRESHOLD (160 * 120 * 2) + +// UMM heap block size +#define OMV_UMM_BLOCK_SIZE 16 + +#define OMV_MAIN_MEMORY SRAM1 // Data/BSS memory +#define OMV_STACK_MEMORY SRAM1 // stack memory +#define OMV_STACK_SIZE (64K) +#define OMV_FB_MEMORY SRAM1 // Framebuffer, fb_alloc +#define OMV_FB_SIZE (1M) // FB memory: header + QVGA/GS image +#define OMV_FB_ALLOC_SIZE (1850K) // minimum fb alloc size +#define OMV_GC_BLOCK0_MEMORY SRAM1 // Main GC block +#define OMV_GC_BLOCK0_SIZE (1M) +#define OMV_SB_SIZE (128K) // IDE JPEG buffer size (header + data). + +// Memory map. +#define OMV_SRAM1_ORIGIN 0x20000000 +#define OMV_SRAM1_LENGTH 4M + +#define OMV_FLASH_ISR_ORIGIN 0x00000000 +#define OMV_FLASH_ISR_LENGTH 4K + +#define OMV_FLASH_TXT_ORIGIN 0x00001000 +#define OMV_FLASH_TXT_LENGTH 4092M + +// CSI configuration. +#define OMV_CSI_I2C_ID (0) +#define OMV_CSI_I2C_SPEED (OMV_I2C_SPEED_STANDARD) +#define OMV_CSI_CLK_SOURCE (OMV_CSI_CLK_SOURCE_TIM) +#define OMV_CSI_CLK_FREQUENCY (24000000) +#define OMV_CSI_HW_CROP_ENABLE (0) +#define OMV_CSI_MAX_DEVICES (3) + +#define OMV_SOFTCSI_ENABLE (1) +#endif //__OMV_BOARDCONFIG_H__ diff --git a/boards/MPS2_AN500/omv_boardconfig.mk b/boards/MPS2_AN500/omv_boardconfig.mk new file mode 100755 index 000000000..e0161f300 --- /dev/null +++ b/boards/MPS2_AN500/omv_boardconfig.mk @@ -0,0 +1,24 @@ +CPU=cortex-m7 +FPU=fpv5-d16 +PORT=qemu +QEMU_MACHINE=mps2-an500 +OMV_ENABLE_BL=0 +OMV_LEPTON_SDK_ENABLE=0 +OMV_BOARD_CFLAGS= -DQEMU_SOC_MPS2 \ + -DCPU_FREQ_HZ=25000000 +MICROPY_PY_CSI = 1 +MICROPY_PY_CSI_NG = 1 +MICROPY_PY_FIR = 0 +MICROPY_PY_ULAB = 1 +MICROPY_PY_WINC1500 = 0 +MICROPY_PY_DISPLAY = 0 +MICROPY_PY_TV = 0 +MICROPY_PY_ML = 1 +MICROPY_PY_ML_TFLM = 1 +MICROPY_PY_LWIP = 0 +MICROPY_PY_SSL = 0 +MICROPY_PY_SSL_ECDSA_SIGN_ALT = 0 +MICROPY_SSL_MBEDTLS = 0 +MICROPY_PY_NETWORK_CYW43 = 0 +MICROPY_PY_BLUETOOTH = 0 +MICROPY_BLUETOOTH_NIMBLE = 0 diff --git a/boards/MPS2_AN500/romfs.json b/boards/MPS2_AN500/romfs.json new file mode 100644 index 000000000..29e22514b --- /dev/null +++ b/boards/MPS2_AN500/romfs.json @@ -0,0 +1,6 @@ +{ + "0": { + "size": "0x20000", + "entries": [ ] + } +} diff --git a/boards/MPS2_AN500/ulab_config.h b/boards/MPS2_AN500/ulab_config.h new file mode 100644 index 000000000..6205c6745 --- /dev/null +++ b/boards/MPS2_AN500/ulab_config.h @@ -0,0 +1,17 @@ +/* + * This file is part of the OpenMV project. + * Copyright (c) 2013-2016 Kwabena W. Agyeman + * This work is licensed under the MIT license, see the file LICENSE for details. + * + * Ulab config file. + * + */ +#ifndef __ULAB_CONFIG_H__ +#define __ULAB_CONFIG_H__ +// Override ulab defaults here. +#define ULAB_MAX_DIMS (4) +#define ULAB_SUPPORTS_COMPLEX (0) +#define ULAB_SCIPY_HAS_OPTIMIZE_MODULE (0) +#define ULAB_SCIPY_HAS_SPECIAL_MODULE (0) +#define ULAB_FFT_IS_NUMPY_COMPATIBLE (0) +#endif //__ULAB_CONFIG_H__ diff --git a/boards/MPS3_AN547/imlib_config.h b/boards/MPS3_AN547/imlib_config.h new file mode 100644 index 000000000..1e3cabf84 --- /dev/null +++ b/boards/MPS3_AN547/imlib_config.h @@ -0,0 +1,164 @@ +/* + * SPDX-License-Identifier: MIT + * + * Copyright (C) 2025 OpenMV, LLC. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Image library configuration. + */ +#ifndef __IMLIB_CONFIG_H__ +#define __IMLIB_CONFIG_H__ + +// Enable Image I/O +#define IMLIB_ENABLE_IMAGE_IO + +// Enable Image File I/O +#define IMLIB_ENABLE_IMAGE_FILE_IO + +// Enable LAB LUT +#define IMLIB_ENABLE_LAB_LUT + +// Enable YUV LUT +//#define IMLIB_ENABLE_YUV_LUT + +// Enable ISP ops +#define IMLIB_ENABLE_ISP_OPS + +// Enable binary ops +#define IMLIB_ENABLE_BINARY_OPS + +// Enable math ops +#define IMLIB_ENABLE_MATH_OPS + +// Enable flood_fill() +#define IMLIB_ENABLE_FLOOD_FILL + +// Enable mean() +#define IMLIB_ENABLE_MEAN + +// Enable median() +#define IMLIB_ENABLE_MEDIAN + +// Enable mode() +#define IMLIB_ENABLE_MODE + +// Enable midpoint() +#define IMLIB_ENABLE_MIDPOINT + +// Enable morph() +#define IMLIB_ENABLE_MORPH + +// Enable Gaussian +#define IMLIB_ENABLE_GAUSSIAN + +// Enable Laplacian +#define IMLIB_ENABLE_LAPLACIAN + +// Enable bilateral() +#define IMLIB_ENABLE_BILATERAL + +// Enable linpolar() +#define IMLIB_ENABLE_LINPOLAR + +// Enable logpolar() +#define IMLIB_ENABLE_LOGPOLAR + +// Enable lens_corr() +#define IMLIB_ENABLE_LENS_CORR + +// Enable rotation_corr() +#define IMLIB_ENABLE_ROTATION_CORR + +// Enable phasecorrelate() +#if defined(IMLIB_ENABLE_ROTATION_CORR) +#define IMLIB_ENABLE_FIND_DISPLACEMENT +#endif + +// Enable get_similarity() +#define IMLIB_ENABLE_GET_SIMILARITY + +// Enable find_lines() +#define IMLIB_ENABLE_FIND_LINES + +// Enable find_line_segments() +#define IMLIB_ENABLE_FIND_LINE_SEGMENTS + +// Enable find_circles() +#define IMLIB_ENABLE_FIND_CIRCLES + +// Enable find_rects() +#define IMLIB_ENABLE_FIND_RECTS + +// Enable find_qrcodes() (14 KB) +#define IMLIB_ENABLE_QRCODES + +// Enable find_apriltags() (64 KB) +#define IMLIB_ENABLE_APRILTAGS +#define IMLIB_ENABLE_APRILTAGS_TAG36H11 + +// Enable fine find_apriltags() - (8-way connectivity versus 4-way connectivity) +// #define IMLIB_ENABLE_FINE_APRILTAGS + +// Enable high res find_apriltags() - uses more RAM +// #define IMLIB_ENABLE_HIGH_RES_APRILTAGS + +// Enable find_datamatrices() (26 KB) +#define IMLIB_ENABLE_DATAMATRICES + +// Enable find_barcodes() (42 KB) +#define IMLIB_ENABLE_BARCODES + +// Enable find_features() and Haar cascades. +#define IMLIB_ENABLE_FEATURES + +// Enable Tensor Flow +#define IMLIB_ENABLE_STAI + +// Enable AGAST. +#define IMLIB_ENABLE_AGAST + +// Enable find_template() +#define IMLIB_FIND_TEMPLATE + +// Enable find_lbp() +#define IMLIB_ENABLE_FIND_LBP + +// Enable find_keypoints() +#if defined(IMLIB_ENABLE_FAST) || defined(IMLIB_ENABLE_AGAST) +#define IMLIB_ENABLE_FIND_KEYPOINTS +#endif + +// Enable load, save and match descriptor +#define IMLIB_ENABLE_DESCRIPTOR + +// Enable find_hog() +#define IMLIB_ENABLE_HOG + +// Enable selective_search() +#define IMLIB_ENABLE_SELECTIVE_SEARCH + +// Enable PNG encoder/decoder +#define IMLIB_ENABLE_PNG_ENCODER +#define IMLIB_ENABLE_PNG_DECODER + +// Stereo Imaging +#define IMLIB_ENABLE_STEREO_DISPARITY + +#endif //__IMLIB_CONFIG_H__ diff --git a/boards/MPS3_AN547/manifest.py b/boards/MPS3_AN547/manifest.py new file mode 100644 index 000000000..828c076f5 --- /dev/null +++ b/boards/MPS3_AN547/manifest.py @@ -0,0 +1,5 @@ +# OpenMV library +add_library("openmv-lib", "$(OMV_LIB_DIR)") + +# Libraries +require("ml", library="openmv-lib") diff --git a/boards/MPS3_AN547/omv_boardconfig.h b/boards/MPS3_AN547/omv_boardconfig.h new file mode 100644 index 000000000..1389a5483 --- /dev/null +++ b/boards/MPS3_AN547/omv_boardconfig.h @@ -0,0 +1,75 @@ +/* + * SPDX-License-Identifier: MIT + * + * Copyright (C) 2025 OpenMV, LLC. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Board configuration and pin definitions. + */ +#ifndef __OMV_BOARDCONFIG_H__ +#define __OMV_BOARDCONFIG_H__ + +// Architecture info +#define OMV_BOARD_ARCH "MPS3 AN547" // 33 chars max +#define OMV_BOARD_TYPE "M55" + +// JPEG configuration. +#define OMV_JPEG_CODEC_ENABLE (0) +#define OMV_JPEG_QUALITY_LOW (35) +#define OMV_JPEG_QUALITY_HIGH (60) +#define OMV_JPEG_QUALITY_THRESHOLD (160 * 120 * 2) + +// UMM heap block size +#define OMV_UMM_BLOCK_SIZE 16 + +#define OMV_MAIN_MEMORY SRAM1 // Data/BSS memory +#define OMV_STACK_MEMORY SRAM1 // stack memory +#define OMV_STACK_SIZE (64K) +#define OMV_FB_MEMORY SRAM1 // Framebuffer, fb_alloc +#define OMV_FB_SIZE (1M) // FB memory: header + QVGA/GS image +#define OMV_FB_ALLOC_SIZE (1850K) // minimum fb alloc size +#define OMV_GC_BLOCK0_MEMORY SRAM1 // Main GC block +#define OMV_GC_BLOCK0_SIZE (1M) +#define OMV_SB_SIZE (128K) // IDE JPEG buffer size (header + data). + +// Memory map. +#define OMV_ITCM_ORIGIN 0x00000000 +#define OMV_ITCM_LENGTH 512K + +#define OMV_SRAM1_ORIGIN 0x21000000 +#define OMV_SRAM1_LENGTH 4M + +#define OMV_FLASH_ISR_ORIGIN 0x00000000 +#define OMV_FLASH_ISR_LENGTH 4K + +#define OMV_FLASH_TXT_ORIGIN 0x01000000 +#define OMV_FLASH_TXT_LENGTH 2M + +// CSI configuration. +#define OMV_CSI_I2C_ID (0) +#define OMV_CSI_I2C_SPEED (OMV_I2C_SPEED_STANDARD) +#define OMV_CSI_CLK_SOURCE (OMV_CSI_CLK_SOURCE_TIM) +#define OMV_CSI_CLK_FREQUENCY (24000000) +#define OMV_CSI_HW_CROP_ENABLE (0) +#define OMV_CSI_MAX_DEVICES (3) + +#define OMV_SOFTCSI_ENABLE (1) + +#endif //__OMV_BOARDCONFIG_H__ diff --git a/boards/MPS3_AN547/omv_boardconfig.mk b/boards/MPS3_AN547/omv_boardconfig.mk new file mode 100644 index 000000000..a09f70528 --- /dev/null +++ b/boards/MPS3_AN547/omv_boardconfig.mk @@ -0,0 +1,25 @@ +CPU=cortex-m55 +FPU=auto +PORT=qemu +QEMU_MACHINE=mps3-an547 +OMV_ENABLE_BL=0 +OMV_LEPTON_SDK_ENABLE=0 +OMV_BOARD_CFLAGS= -mcmse \ + -DQEMU_SOC_MPS3 \ + -DCPU_FREQ_HZ=32000000 +MICROPY_PY_CSI = 1 +MICROPY_PY_CSI_NG = 1 +MICROPY_PY_FIR = 0 +MICROPY_PY_ULAB = 1 +MICROPY_PY_WINC1500 = 0 +MICROPY_PY_DISPLAY = 0 +MICROPY_PY_TV = 0 +MICROPY_PY_ML = 1 +MICROPY_PY_ML_TFLM = 1 +MICROPY_PY_LWIP = 0 +MICROPY_PY_SSL = 0 +MICROPY_PY_SSL_ECDSA_SIGN_ALT = 0 +MICROPY_SSL_MBEDTLS = 0 +MICROPY_PY_NETWORK_CYW43 = 0 +MICROPY_PY_BLUETOOTH = 0 +MICROPY_BLUETOOTH_NIMBLE = 0 diff --git a/boards/MPS3_AN547/romfs.json b/boards/MPS3_AN547/romfs.json new file mode 100644 index 000000000..29e22514b --- /dev/null +++ b/boards/MPS3_AN547/romfs.json @@ -0,0 +1,6 @@ +{ + "0": { + "size": "0x20000", + "entries": [ ] + } +} diff --git a/boards/MPS3_AN547/ulab_config.h b/boards/MPS3_AN547/ulab_config.h new file mode 100644 index 000000000..6205c6745 --- /dev/null +++ b/boards/MPS3_AN547/ulab_config.h @@ -0,0 +1,17 @@ +/* + * This file is part of the OpenMV project. + * Copyright (c) 2013-2016 Kwabena W. Agyeman + * This work is licensed under the MIT license, see the file LICENSE for details. + * + * Ulab config file. + * + */ +#ifndef __ULAB_CONFIG_H__ +#define __ULAB_CONFIG_H__ +// Override ulab defaults here. +#define ULAB_MAX_DIMS (4) +#define ULAB_SUPPORTS_COMPLEX (0) +#define ULAB_SCIPY_HAS_OPTIMIZE_MODULE (0) +#define ULAB_SCIPY_HAS_SPECIAL_MODULE (0) +#define ULAB_FFT_IS_NUMPY_COMPATIBLE (0) +#endif //__ULAB_CONFIG_H__ diff --git a/common/pendsv.c b/common/pendsv.c index 38e7a0429..0508f34bf 100644 --- a/common/pendsv.c +++ b/common/pendsv.c @@ -23,7 +23,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ - +#ifndef QEMU_BUILD #include #include "py/mphal.h" #include "py/runtime.h" @@ -192,3 +192,4 @@ __attribute__((naked)) void PendSV_Handler(void) { "nlr_jump_ptr: .word nlr_jump\n" ); } +#endif // QEMU_BUILD diff --git a/common/usbdbg.c b/common/usbdbg.c index a9d4eb4d0..4563ceac5 100644 --- a/common/usbdbg.c +++ b/common/usbdbg.c @@ -23,6 +23,7 @@ * * USB debugger. */ +#ifndef QEMU_BUILD #include #include #include "py/nlr.h" @@ -452,3 +453,4 @@ void usbdbg_control(void *buffer, uint8_t request, uint32_t size) { break; } } +#endif // QEMU_BUILD diff --git a/modules/py_omv.c b/modules/py_omv.c index baef18d2d..c16e0b0dc 100644 --- a/modules/py_omv.c +++ b/modules/py_omv.c @@ -55,7 +55,8 @@ static mp_obj_t py_omv_board_type() { static MP_DEFINE_CONST_FUN_OBJ_0(py_omv_board_type_obj, py_omv_board_type); static mp_obj_t py_omv_board_id() { - char str[25]; + char str[25] = {0}; + #ifdef OMV_BOARD_UID_ADDR snprintf(str, 25, "%08X%08X%08X", #if (OMV_BOARD_UID_SIZE == 2) 0U, @@ -64,6 +65,7 @@ static mp_obj_t py_omv_board_id() { #endif *((unsigned int *) (OMV_BOARD_UID_ADDR + OMV_BOARD_UID_OFFSET * 1)), *((unsigned int *) (OMV_BOARD_UID_ADDR + OMV_BOARD_UID_OFFSET * 0))); + #endif return mp_obj_new_str(str, strlen(str)); } static MP_DEFINE_CONST_FUN_OBJ_0(py_omv_board_id_obj, py_omv_board_id); diff --git a/ports/qemu/main.c b/ports/qemu/main.c new file mode 100644 index 000000000..43cfa0a13 --- /dev/null +++ b/ports/qemu/main.c @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2023-2024 OpenMV, LLC. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Any redistribution, use, or modification in source or binary form + * is done solely for personal benefit and not for any commercial + * purpose or for monetary gain. For commercial licensing options, + * please contact openmv@openmv.io + * + * THIS SOFTWARE IS PROVIDED BY THE LICENSOR AND COPYRIGHT OWNER "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR OR COPYRIGHT + * OWNER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "py/compile.h" +#include "py/runtime.h" +#include "py/gc.h" +#include "py/mperrno.h" +#include "py/mphal.h" +#include "py/stackctrl.h" +#include "shared/readline/readline.h" +#include "shared/runtime/gchelper.h" +#include "shared/runtime/pyexec.h" + +#include "omv_boardconfig.h" +#include "mp_utils.h" +#include "file_utils.h" +#include "fb_alloc.h" +#include "framebuffer.h" +#include "omv_csi.h" + +int main(int argc, char **argv) { + bool first_soft_reset = true; + +soft_reset: + // Initialise stack extents and GC heap. + extern uint8_t _estack, _sstack, _heap_start, _heap_end; + mp_init_gc_stack(&_sstack, &_estack, &_heap_start, &_heap_end, 1024); + + mp_init(); + + fb_alloc_init0(); + framebuffer_init0(); + + #ifdef IMLIB_ENABLE_IMAGE_FILE_IO + file_buffer_init0(); + #endif + + imlib_init_all(); + + #if MICROPY_PY_CSI + omv_csi_init0(); + + if (first_soft_reset) { + omv_csi_init(); + } + #endif + + for (;;) { + if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) { + if (pyexec_raw_repl() != 0) { + break; + } + } else { + if (pyexec_friendly_repl() != 0) { + break; + } + } + } + + mp_printf(&mp_plat_print, "MPY: soft reboot\n"); + gc_sweep_all(); + mp_deinit(); + first_soft_reset = false; + goto soft_reset; +} + +void gc_collect(void) { + gc_collect_start(); + gc_helper_collect_regs_and_stack(); + gc_collect_end(); +} + +void nlr_jump_fail(void *val) { + mp_printf(&mp_plat_print, "FATAL: uncaught exception %p\n", val); + mp_obj_print_exception(&mp_plat_print, MP_OBJ_FROM_PTR(val)); + exit(1); +} + +void __fatal_error(const char *msg) { + mp_hal_stdout_tx_strn("\nFATAL ERROR:\n", 14); + mp_hal_stdout_tx_strn(msg, strlen(msg)); + for (;;) { + *(volatile uint32_t *) 0x4900C000 ^= 9; + for (volatile uint delay = 0; delay < 10000000; delay++) { + } + } +} + +void usbdbg_set_irq_enabled(bool enabled) { + +} diff --git a/ports/qemu/omv_csi.c b/ports/qemu/omv_csi.c new file mode 100644 index 000000000..baf80f61f --- /dev/null +++ b/ports/qemu/omv_csi.c @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2023-2025 OpenMV, LLC. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Any redistribution, use, or modification in source or binary form + * is done solely for personal benefit and not for any commercial + * purpose or for monetary gain. For commercial licensing options, + * please contact openmv@openmv.io + * + * THIS SOFTWARE IS PROVIDED BY THE LICENSOR AND COPYRIGHT OWNER "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR OR COPYRIGHT + * OWNER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * QEMU dummy CSI driver. + */ +#if MICROPY_PY_CSI +#include +#include +#include +#include + +#include "py/mphal.h" +#include "py/runtime.h" + +#include "omv_boardconfig.h" +#include "omv_i2c.h" +#include "omv_csi.h" + +static int qemu_csi_config(omv_csi_t *csi, omv_csi_config_t config) { + // Dummy implementation - accept all configurations + return 0; +} + +static int qemu_csi_abort(omv_csi_t *csi, bool fifo_flush, bool in_irq) { + // Dummy implementation + return 0; +} + +static uint32_t qemu_clk_get_frequency(omv_clk_t *clk) { + // Dummy implementation - return nominal frequency + return clk->freq; +} + +static int qemu_clk_set_frequency(omv_clk_t *clk, uint32_t frequency) { + // Dummy implementation - accept any frequency + clk->freq = frequency; + return 0; +} + +static int qemu_csi_snapshot(omv_csi_t *csi, image_t *dst_image, uint32_t flags) { + // Dummy implementation - return timeout error since there's no camera + return OMV_CSI_ERROR_CAPTURE_TIMEOUT; +} + +int omv_csi_ops_init(omv_csi_t *csi) { + // Set CSI ops to dummy implementations + csi->abort = qemu_csi_abort; + csi->config = qemu_csi_config; + csi->snapshot = qemu_csi_snapshot; + + // Set CSI clock ops + csi->clk->freq = OMV_CSI_CLK_FREQUENCY; + csi->clk->set_freq = qemu_clk_set_frequency; + csi->clk->get_freq = qemu_clk_get_frequency; + + return 0; +} +#endif // MICROPY_PY_CSI diff --git a/ports/qemu/omv_i2c.c b/ports/qemu/omv_i2c.c new file mode 100644 index 000000000..b59f60c03 --- /dev/null +++ b/ports/qemu/omv_i2c.c @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2023-2025 OpenMV, LLC. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Any redistribution, use, or modification in source or binary form + * is done solely for personal benefit and not for any commercial + * purpose or for monetary gain. For commercial licensing options, + * please contact openmv@openmv.io + * + * THIS SOFTWARE IS PROVIDED BY THE LICENSOR AND COPYRIGHT OWNER "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR OR COPYRIGHT + * OWNER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * QEMU dummy I2C driver. + */ +#include +#include +#include + +#include "py/mphal.h" +#include "py/runtime.h" + +#include "omv_portconfig.h" +#include "omv_i2c.h" + +int omv_i2c_init(omv_i2c_t *i2c, uint32_t bus_id, uint32_t speed) { + i2c->id = bus_id; + i2c->speed = speed; + i2c->initialized = true; + i2c->scl_pin = NULL; + i2c->sda_pin = NULL; + i2c->inst = NULL; + return 0; +} + +int omv_i2c_deinit(omv_i2c_t *i2c) { + if (i2c->initialized) { + i2c->initialized = false; + } + return 0; +} + +int omv_i2c_scan(omv_i2c_t *i2c, uint8_t *list, uint8_t size) { + // Dummy implementation - no devices found + return 0; +} + +int omv_i2c_enable(omv_i2c_t *i2c, bool enable) { + // Dummy implementation + return 0; +} diff --git a/ports/qemu/omv_mpconfigport.h b/ports/qemu/omv_mpconfigport.h new file mode 100644 index 000000000..7b474a4d7 --- /dev/null +++ b/ports/qemu/omv_mpconfigport.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2023-2024 OpenMV, LLC. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Any redistribution, use, or modification in source or binary form + * is done solely for personal benefit and not for any commercial + * purpose or for monetary gain. For commercial licensing options, + * please contact openmv@openmv.io + * + * THIS SOFTWARE IS PROVIDED BY THE LICENSOR AND COPYRIGHT OWNER "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR OR COPYRIGHT + * OWNER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * MicroPython port configuration. + */ +#define MICROPY_NLR_RAISE_HOOK \ + do { \ + extern void fb_alloc_free_till_mark(); \ + fb_alloc_free_till_mark(); \ + } while (0); + +#define MICROPY_OBJ_REPR (MICROPY_OBJ_REPR_C) +typedef int mp_int_t; // must be pointer size +typedef unsigned int mp_uint_t; // must be pointer size + +#define MICROPY_PY_TIME (1) +#define MICROPY_GC_SPLIT_HEAP (1) +#define MICROPY_BANNER_NAME_AND_VERSION "OpenMV " OPENMV_GIT_TAG "; MicroPython " MICROPY_GIT_TAG + +#include + +#undef MICROPY_MEM_STATS +#undef MICROPY_MALLOC_USES_ALLOCATED_SIZE diff --git a/ports/qemu/omv_portconfig.h b/ports/qemu/omv_portconfig.h new file mode 100644 index 000000000..e5a0f4fce --- /dev/null +++ b/ports/qemu/omv_portconfig.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2023-2025 OpenMV, LLC. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Any redistribution, use, or modification in source or binary form + * is done solely for personal benefit and not for any commercial + * purpose or for monetary gain. For commercial licensing options, + * please contact openmv@openmv.io + * + * THIS SOFTWARE IS PROVIDED BY THE LICENSOR AND COPYRIGHT OWNER "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR OR COPYRIGHT + * OWNER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * OpenMV QEMU port abstraction layer. + */ +#ifndef __OMV_PORTCONFIG_H__ +#define __OMV_PORTCONFIG_H__ +#include + +// omv_gpio_t definitions +typedef void *omv_gpio_t; + +// GPIO modes, speeds, and pull configurations (dummy values for QEMU) +#define OMV_GPIO_MODE_INPUT (0) +#define OMV_GPIO_MODE_OUTPUT (1) +#define OMV_GPIO_MODE_OUTPUT_OD (2) +#define OMV_GPIO_MODE_ALT (3) +#define OMV_GPIO_MODE_ALT_OD (4) + +#define OMV_GPIO_PULL_NONE (0) +#define OMV_GPIO_PULL_UP (1) +#define OMV_GPIO_PULL_DOWN (2) + +#define OMV_GPIO_SPEED_LOW (0) +#define OMV_GPIO_SPEED_MED (1) +#define OMV_GPIO_SPEED_HIGH (2) +#define OMV_GPIO_SPEED_MAX (3) + +// omv_i2c_t definitions +typedef void *omv_i2c_dev_t; + +#endif // __OMV_PORTCONFIG_H__ diff --git a/ports/qemu/omv_portconfig.mk b/ports/qemu/omv_portconfig.mk new file mode 100644 index 000000000..b5d3073f0 --- /dev/null +++ b/ports/qemu/omv_portconfig.mk @@ -0,0 +1,170 @@ +# SPDX-License-Identifier: MIT +# +# Copyright (C) 2025 OpenMV, LLC. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +# Set startup and system files for CMSIS Makefile. +LDSCRIPT ?= qemu +ROMFS_IMAGE := $(FW_DIR)/romfs.stamp +ROMFS_CONFIG := $(OMV_BOARD_CONFIG_DIR)/romfs.json + +# Compiler Flags +CFLAGS += -std=gnu11 \ + -Wall \ + -Werror \ + -Warray-bounds \ + -nostartfiles \ + -fdata-sections \ + -ffunction-sections \ + -fno-inline-small-functions \ + -mthumb \ + -mcpu=$(CPU) \ + -mfpu=$(FPU) \ + -mfloat-abi=hard + +CFLAGS += -D$(TARGET) \ + -DQEMU_BUILD \ + -D__FPU_PRESENT=1 \ + -D__FPU_USED=1 \ + -D__VFP_FP__ \ + -DARM_NN_TRUNCATE=1 \ + -DCMSIS_MCU_H='' \ + $(OMV_BOARD_CFLAGS) + +# Linker Flags +LDFLAGS = -mthumb \ + -nostartfiles \ + -mcpu=$(CPU) \ + -mfpu=$(FPU) \ + -mfloat-abi=hard \ + -mabi=aapcs-linux \ + -Wl,--print-memory-usage \ + -Wl,--gc-sections \ + -Wl,-T$(BUILD)/$(LDSCRIPT).lds \ + -Wl,-Map=$(BUILD)/$(FIRMWARE).map + +OMV_CFLAGS += -I$(TOP_DIR) +OMV_CFLAGS += -I$(TOP_DIR)/$(COMMON_DIR) +OMV_CFLAGS += -I$(TOP_DIR)/modules +OMV_CFLAGS += -I$(TOP_DIR)/ports/$(PORT) +OMV_CFLAGS += -I$(TOP_DIR)/ports/$(PORT)/modules +OMV_CFLAGS += -I$(OMV_BOARD_CONFIG_DIR) + +MPY_CFLAGS += -I$(MP_BOARD_CONFIG_DIR) +MPY_CFLAGS += -I$(BUILD)/$(MICROPY_DIR) +MPY_CFLAGS += -I$(TOP_DIR)/$(MICROPY_DIR) +MPY_CFLAGS += -I$(TOP_DIR)/$(MICROPY_DIR)/py +MPY_CFLAGS += -I$(TOP_DIR)/$(MICROPY_DIR)/lib/oofatfs +MPY_CFLAGS += -I$(TOP_DIR)/$(MICROPY_DIR)/lib/tinyusb/src +MPY_CFLAGS += -I$(TOP_DIR)/$(MICROPY_DIR)/lib/lwip/src/include +MPY_CFLAGS += -I$(TOP_DIR)/$(MICROPY_DIR)/shared/tinyusb +MPY_CFLAGS += -I$(TOP_DIR)/$(MICROPY_DIR)/ports/qemu +MPY_CFLAGS += -I$(TOP_DIR)/$(MICROPY_DIR)/ports/qemu/lwip_inc +MPY_CFLAGS += -I$(TOP_DIR)/$(MICROPY_DIR)/shared/runtime + +MPY_CFLAGS += -DMICROPY_PY_LWIP=$(MICROPY_PY_LWIP) +MPY_CFLAGS += -DMICROPY_PY_SSL=$(MICROPY_PY_SSL) +MPY_CFLAGS += -DMICROPY_PY_SSL_ECDSA_SIGN_ALT=$(MICROPY_PY_SSL_ECDSA_SIGN_ALT) +MPY_CFLAGS += -DMICROPY_SSL_MBEDTLS=$(MICROPY_SSL_MBEDTLS) +MPY_CFLAGS += -DMICROPY_PY_NETWORK_CYW43=$(MICROPY_PY_NETWORK_CYW43) +MPY_CFLAGS += -DMICROPY_PY_BLUETOOTH=$(MICROPY_PY_BLUETOOTH) +MPY_CFLAGS += -DMICROPY_BLUETOOTH_NIMBLE=$(MICROPY_BLUETOOTH_NIMBLE) +MPY_CFLAGS += -DMICROPY_PY_BLUETOOTH_USE_SYNC_EVENTS=1 +MPY_CFLAGS += -DMICROPY_FLOAT_IMPL=MICROPY_FLOAT_IMPL_FLOAT + +MPY_MKARGS += CMSIS_DIR=$(TOP_DIR)/$(CMSIS_DIR) +MPY_MKARGS += MICROPY_VFS_LFS2=0 +MPY_MKARGS += CFLAGS_EXTRA="-std=gnu11" +MPY_MKARGS += MICROPY_PY_LWIP=$(MICROPY_PY_LWIP) +MPY_MKARGS += MICROPY_PY_SSL=$(MICROPY_PY_SSL) +MPY_MKARGS += MICROPY_PY_SSL_ECDSA_SIGN_ALT=$(MICROPY_PY_SSL_ECDSA_SIGN_ALT) +MPY_MKARGS += MICROPY_SSL_MBEDTLS=$(MICROPY_SSL_MBEDTLS) +MPY_MKARGS += MICROPY_PY_NETWORK_CYW43=$(MICROPY_PY_NETWORK_CYW43) +MPY_MKARGS += MICROPY_PY_BLUETOOTH=$(MICROPY_PY_BLUETOOTH) +MPY_MKARGS += MICROPY_BLUETOOTH_NIMBLE=$(MICROPY_BLUETOOTH_NIMBLE) +MPY_MKARGS += MICROPY_FLOAT_IMPL=float +MPY_MKARGS += SUPPORTS_HARDWARE_FP_SINGLE=1 + +CFLAGS += $(HAL_CFLAGS) $(MPY_CFLAGS) $(OMV_CFLAGS) + +# Firmware objects from .mk files. +include lib/cmsis/cmsis.mk +include common/common.mk +include drivers/drivers.mk +include lib/imlib/imlib.mk +include lib/tflm/tflm.mk +include ports/ports.mk +include common/micropy.mk + +# Firmware objects from port. +MPY_FIRM_OBJ += $(addprefix $(BUILD)/$(MICROPY_DIR)/,\ + uart.o \ + mphalport.o \ + frozen_content.o \ + mcu/arm/errorhandler.o \ + mcu/arm/startup.o \ + mcu/arm/systick.o \ +) + +ifeq ($(MICROPY_PY_ML_TFLM), 1) +ifeq ($(CPU),cortex-m55) +LIBS += $(TOP_DIR)/$(TENSORFLOW_DIR)/libtflm/lib/libtflm-cortex-m55-release.a +else +LIBS += $(TOP_DIR)/$(TENSORFLOW_DIR)/libtflm/lib/libtflm-$(CPU)+fp-release.a +endif +endif + +################################################### +all: $(ROMFS_IMAGE) + $(SIZE) $(FW_DIR)/$(FIRMWARE).elf + +# This target builds MicroPython. +MICROPYTHON: | FIRM_DIRS + $(MAKE) -C $(MICROPY_DIR)/ports/$(PORT) BUILD=$(BUILD)/$(MICROPY_DIR) $(MPY_MKARGS) + +$(OMV_FIRM_OBJ): | MICROPYTHON + +# This target builds the firmware. +$(FIRMWARE): $(OMV_FIRM_OBJ) + $(CPP) -P -E -DLINKER_SCRIPT -I$(COMMON_DIR) -I$(OMV_BOARD_CONFIG_DIR) \ + ports/$(PORT)/$(LDSCRIPT).ld.S > $(BUILD)/$(LDSCRIPT).lds + $(CC) $(LDFLAGS) $(OMV_FIRM_OBJ) $(MPY_FIRM_OBJ) -o $(FW_DIR)/$(FIRMWARE).elf $(LIBS) -lm + $(OBJCOPY) -Obinary $(FW_DIR)/$(FIRMWARE).elf $(FW_DIR)/$(FIRMWARE).bin + +$(ROMFS_IMAGE): $(ROMFS_CONFIG) | $(FIRMWARE) + $(ECHO) "GEN romfs image" + $(PYTHON) $(TOOLS_DIR)/$(MKROMFS) \ + --top-dir $(TOP_DIR) \ + --out-dir $(FW_DIR) \ + --build-dir $(BUILD)/lib/models \ + $(STEDGE_ARGS) --config $(ROMFS_CONFIG) + touch $@ + +QEMU_SYSTEM = qemu-system-arm +QEMU_ARGS += -machine $(QEMU_MACHINE) -nographic -monitor null -semihosting + +ifeq ($(DEBUG), 1) +QEMU_ARGS += -s -S +endif + +run: $(ROMFS_IMAGE) + $(QEMU_SYSTEM) $(QEMU_ARGS) -serial pty -kernel $(FW_DIR)/$(FIRMWARE).elf + +include common/mkrules.mk diff --git a/ports/qemu/qemu.ld.S b/ports/qemu/qemu.ld.S new file mode 100644 index 000000000..76cc58e39 --- /dev/null +++ b/ports/qemu/qemu.ld.S @@ -0,0 +1,73 @@ +/* This file is part of the MicroPython project, http://micropython.org/ + * The MIT License (MIT) + * Copyright (c) 2018 Damien P. George + */ + +#include "omv_boardconfig.h" + +MEMORY +{ + #if defined(OMV_ITCM_ORIGIN) + ITCM (xrw) : ORIGIN = OMV_ITCM_ORIGIN, LENGTH = OMV_ITCM_LENGTH + #endif + #if defined(OMV_SRAM1_ORIGIN) + SRAM1 (xrw) : ORIGIN = OMV_SRAM1_ORIGIN, LENGTH = OMV_SRAM1_LENGTH + #endif + #if defined(OMV_SRAM2_ORIGIN) + SRAM2 (xrw) : ORIGIN = OMV_SRAM2_ORIGIN, LENGTH = OMV_SRAM2_LENGTH + #endif + FLASH_ISR (rx) : ORIGIN = OMV_FLASH_ISR_ORIGIN, LENGTH = OMV_FLASH_ISR_LENGTH + FLASH_TEXT (rx) : ORIGIN = OMV_FLASH_TXT_ORIGIN, LENGTH = OMV_FLASH_TXT_LENGTH +} + +/* Define output sections */ +SECTIONS +{ + .isr_vector : ALIGN(4) + { + KEEP(*(.isr_vector)) + . = ALIGN(4); + } >FLASH_ISR + + /* The program code and other data goes into FLASH */ + .text : ALIGN(4) + { + *(.text*) // .text* sections (code) + . = ALIGN(4); + *(.rodata*) // .rodata* sections (constants, strings, etc.) + . = ALIGN(4); + *(.ARM.exidx*) + . = ALIGN(4); + _etext = .; + } >FLASH_TEXT + + /* The address used as the source for copying the initialized data section. */ + _sidata = LOADADDR(.data); + + /* Initialized data sections */ + .data : ALIGN(4) + { + _sdata = .; // Used by the startup to initialize the data section + *(.data) // .data sections + . = ALIGN(4); + *(.data*) // .data* sections + . = ALIGN(4); + _edata = .; // Define a global symbol at data end + } >OMV_MAIN_MEMORY AT> FLASH_TEXT + + /* Uninitialized data section */ + .bss (NOLOAD) : ALIGN(4) + { + _sbss = .; // Used by the startup to initialize the .bss section + __bss_start__ = .; + . = ALIGN(4); + *(.bss*) + . = ALIGN(4); + *(COMMON) + . = ALIGN(4); + _ebss = .; // Define a global symbol at bss end + __bss_end__ = .; + } >OMV_MAIN_MEMORY + + #include "common.ld.S" +}