Add RP2040 port and Pico and Nano board files.

This commit is contained in:
iabdalkader 2021-05-27 20:07:49 +02:00
parent 559d375b1d
commit f72c4d75de
28 changed files with 4512 additions and 1 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,109 @@
/*************************************************************************//**
* @file RP2040.h
* @brief CMSIS-Core(M) Device Peripheral Access Layer Header File for
* Device RP2040
* @version V1.0.0
* @date 5. May 2021
*****************************************************************************/
/*
* Copyright (c) 2009-2021 Arm Limited. All rights reserved.
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _CMSIS_RP2040_H_
#define _CMSIS_RP2040_H_
#ifdef __cplusplus
extern "C" {
#endif
/* =========================================================================================================================== */
/* ================ Interrupt Number Definition ================ */
/* =========================================================================================================================== */
typedef enum
{
/* ======================================= ARM Cortex-M0+ Specific Interrupt Numbers ======================================= */
Reset_IRQn = -15, /*!< -15 Reset Vector, invoked on Power up and warm reset */
NonMaskableInt_IRQn = -14, /*!< -14 Non maskable Interrupt, cannot be stopped or preempted */
HardFault_IRQn = -13, /*!< -13 Hard Fault, all classes of Fault */
SVCall_IRQn = -5, /*!< -5 System Service Call via SVC instruction */
PendSV_IRQn = -2, /*!< -2 Pendable request for system service */
SysTick_IRQn = -1, /*!< -1 System Tick Timer */
/* =========================================== RP2040 Specific Interrupt Numbers =========================================== */
TIMER_IRQ_0_IRQn = 0, /*!< 0 TIMER_IRQ_0 */
TIMER_IRQ_1_IRQn = 1, /*!< 1 TIMER_IRQ_1 */
TIMER_IRQ_2_IRQn = 2, /*!< 2 TIMER_IRQ_2 */
TIMER_IRQ_3_IRQn = 3, /*!< 3 TIMER_IRQ_3 */
PWM_IRQ_WRAP_IRQn = 4, /*!< 4 PWM_IRQ_WRAP */
USBCTRL_IRQ_IRQn = 5, /*!< 5 USBCTRL_IRQ */
XIP_IRQ_IRQn = 6, /*!< 6 XIP_IRQ */
PIO0_IRQ_0_IRQn = 7, /*!< 7 PIO0_IRQ_0 */
PIO0_IRQ_1_IRQn = 8, /*!< 8 PIO0_IRQ_1 */
PIO1_IRQ_0_IRQn = 9, /*!< 9 PIO1_IRQ_0 */
PIO1_IRQ_1_IRQn = 10, /*!< 10 PIO1_IRQ_1 */
DMA_IRQ_0_IRQn = 11, /*!< 11 DMA_IRQ_0 */
DMA_IRQ_1_IRQn = 12, /*!< 12 DMA_IRQ_1 */
IO_IRQ_BANK0_IRQn = 13, /*!< 13 IO_IRQ_BANK0 */
IO_IRQ_QSPI_IRQn = 14, /*!< 14 IO_IRQ_QSPI */
SIO_IRQ_PROC0_IRQn = 15, /*!< 15 SIO_IRQ_PROC0 */
SIO_IRQ_PROC1_IRQn = 16, /*!< 16 SIO_IRQ_PROC1 */
CLOCKS_IRQ_IRQn = 17, /*!< 17 CLOCKS_IRQ */
SPI0_IRQ_IRQn = 18, /*!< 18 SPI0_IRQ */
SPI1_IRQ_IRQn = 19, /*!< 19 SPI1_IRQ */
UART0_IRQ_IRQn = 20, /*!< 20 UART0_IRQ */
UART1_IRQ_IRQn = 21, /*!< 21 UART1_IRQ */
ADC_IRQ_FIFO_IRQn = 22, /*!< 22 ADC_IRQ_FIFO */
I2C0_IRQ_IRQn = 23, /*!< 23 I2C0_IRQ */
I2C1_IRQ_IRQn = 24, /*!< 24 I2C1_IRQ */
RTC_IRQ_IRQn = 25 /*!< 25 RTC_IRQ */
} IRQn_Type;
/* =========================================================================================================================== */
/* ================ Processor and Core Peripheral Section ================ */
/* =========================================================================================================================== */
/* ========================== Configuration of the ARM Cortex-M0+ Processor and Core Peripherals =========================== */
#define __CM0PLUS_REV 0x0001U /*!< CM0PLUS Core Revision */
#define __NVIC_PRIO_BITS 2 /*!< Number of Bits used for Priority Levels */
#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */
#define __VTOR_PRESENT 1 /*!< Set to 1 if CPU supports Vector Table Offset Register */
#define __MPU_PRESENT 1 /*!< MPU present */
#define __FPU_PRESENT 0 /*!< FPU present */
/** @} */ /* End of group Configuration_of_CMSIS */
#include "core_cm0plus.h" /*!< ARM Cortex-M0+ processor and core peripherals */
#include "system_RP2040.h" /*!< RP2040 System */
#ifndef __IM /*!< Fallback for older CMSIS versions */
#define __IM __I
#endif
#ifndef __OM /*!< Fallback for older CMSIS versions */
#define __OM __O
#endif
#ifndef __IOM /*!< Fallback for older CMSIS versions */
#define __IOM __IO
#endif
#ifdef __cplusplus
}
#endif
#endif /* _CMSIS_RP2040_H */

View File

@ -0,0 +1,65 @@
/*************************************************************************//**
* @file system_RP2040.h
* @brief CMSIS-Core(M) Device Peripheral Access Layer Header File for
* Device RP2040
* @version V1.0.0
* @date 5. May 2021
*****************************************************************************/
/*
* Copyright (c) 2009-2021 Arm Limited. All rights reserved.
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _CMSIS_SYSTEM_RP2040_H
#define _CMSIS_SYSTEM_RP2040_H
#ifdef __cplusplus
extern "C" {
#endif
/**
\brief Exception / Interrupt Handler Function Prototype
*/
typedef void(*VECTOR_TABLE_Type)(void);
/**
\brief System Clock Frequency (Core Clock)
*/
extern uint32_t SystemCoreClock;
/**
\brief Setup the microcontroller system.
Initialize the System and update the SystemCoreClock variable.
*/
extern void SystemInit (void);
/**
\brief Update SystemCoreClock variable.
Updates the SystemCoreClock with current core Clock retrieved from cpu registers.
*/
extern void SystemCoreClockUpdate (void);
#ifdef __cplusplus
}
#endif
#endif /* _CMSIS_SYSTEM_RP2040_H */

View File

@ -0,0 +1,52 @@
/*************************************************************************//**
* @file system_RP2040.c
* @brief CMSIS-Core(M) Device Peripheral Access Layer Header File for
* Device RP2040
* @version V1.0.0
* @date 5. May 2021
*****************************************************************************/
/*
* Copyright (c) 2009-2021 Arm Limited. All rights reserved.
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdint.h>
#include "RP2040.h"
#include "hardware/clocks.h"
/*---------------------------------------------------------------------------
System Core Clock Variable
*---------------------------------------------------------------------------*/
uint32_t SystemCoreClock; /* System Clock Frequency (Core Clock)*/
/*---------------------------------------------------------------------------
System Core Clock function
*---------------------------------------------------------------------------*/
void SystemCoreClockUpdate (void)
{
SystemCoreClock = clock_get_hz(clk_sys);
}
/*---------------------------------------------------------------------------
System initialization function
*---------------------------------------------------------------------------*/
void __attribute__((constructor)) SystemInit (void)
{
SystemCoreClockUpdate();
}

@ -1 +1 @@
Subproject commit b814ad51d6b51b94fb7dab01dc111d5053d98a82
Subproject commit 750d095c0d0790e988a0047e992a54a43bf45d2c

View File

@ -0,0 +1,153 @@
/*
* This file is part of the OpenMV project.
*
* Copyright (c) 2013-2021 Ibrahim Abdelkader <iabdalkader@openmv.io>
* Copyright (c) 2013-2021 Kwabena W. Agyeman <kwagyeman@openmv.io>
*
* This work is licensed under the MIT license, see the file LICENSE for details.
*
* 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
// Not filesystem yet
//#define IMLIB_ENABLE_IMAGE_FILE_IO
// Enable LAB LUT
//#define IMLIB_ENABLE_LAB_LUT
// Enable YUV LUT
//#define IMLIB_ENABLE_YUV_LUT
// Enable mean pooling
//#define IMLIB_ENABLE_MEAN_POOLING
// Enable midpoint pooling
//#define IMLIB_ENABLE_MIDPOINT_POOLING
// 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 cartoon()
// #define IMLIB_ENABLE_CARTOON
// 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
// 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 CMSIS NN
// #if !defined(CUBEAI)
// #define IMLIB_ENABLE_CNN
// #endif
// Enable Tensor Flow
#if !defined(CUBEAI)
//#define IMLIB_ENABLE_TF
#endif
// Enable FAST (20+ KBs).
// #define IMLIB_ENABLE_FAST
// Enable find_template()
//#define IMLIB_FIND_TEMPLATE
// Enable find_lbp()
//#define IMLIB_ENABLE_FIND_LBP
// Enable find_keypoints()
//#define IMLIB_ENABLE_FIND_KEYPOINTS
// 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 STM32 DMA2D
//#define IMLIB_ENABLE_DMA2D
#endif //__IMLIB_CONFIG_H__

View File

@ -0,0 +1,3 @@
freeze ("$(PORT_DIR)/modules")
include("$(MPY_DIR)/extmod/uasyncio/manifest.py")
freeze ("$(MPY_LIB_DIR)/", "lsm6dsox.py")

View File

@ -0,0 +1,12 @@
set(MICROPY_PY_SENSOR 0)
set(MICROPY_PY_ULAB 1)
set(MICROPY_PY_WINC1500 0)
set(MICROPY_PY_LWIP 0)
set(MICROPY_PY_NETWORK_CYW43 0)
set(MICROPY_PY_BLUETOOTH 0)
set(MICROPY_BLUETOOTH_NIMBLE 0)
set(MICROPY_PY_AUDIO 1)
set(MICROPY_PY_MICRO_SPEECH 0)
set(MICROPY_PY_LCD 0)
set(MICROPY_PY_TV 0)
set(MICROPY_PY_BUZZER 0)

View File

@ -0,0 +1,191 @@
/*
* This file is part of the OpenMV project.
*
* Copyright (c) 2013-2021 Ibrahim Abdelkader <iabdalkader@openmv.io>
* Copyright (c) 2013-2021 Kwabena W. Agyeman <kwagyeman@openmv.io>
*
* This work is licensed under the MIT license, see the file LICENSE for details.
*
* Board configuration and pin definitions.
*/
#ifndef __OMV_BOARDCONFIG_H__
#define __OMV_BOARDCONFIG_H__
// Architecture info
#define OMV_ARCH_STR "PICO M0" // 33 chars max
#define OMV_BOARD_TYPE "PICO"
#ifndef LINKER_SCRIPT
extern unsigned char *OMV_UNIQUE_ID_ADDR;
#endif
#define OMV_UNIQUE_ID_SIZE 2 // 2 words
#define OMV_XCLK_MCO (0U)
#define OMV_XCLK_TIM (1U)
// Sensor external clock source.
#define OMV_XCLK_SOURCE (OMV_XCLK_TIM)
// Sensor external clock timer frequency.
// TODO Not actually used right now, frequency is hardcoded.
#define OMV_XCLK_FREQUENCY (12500000)
// RAW buffer size
#define OMV_RAW_BUF_SIZE (151*1024)
// Enable hardware JPEG
#define OMV_HARDWARE_JPEG (0)
// Enable sensor drivers
#define OMV_ENABLE_OV2640 (0)
#define OMV_ENABLE_OV5640 (0)
#define OMV_ENABLE_OV7670 (1)
#define OMV_ENABLE_OV7690 (0)
#define OMV_ENABLE_OV7725 (0)
#define OMV_ENABLE_OV9650 (0)
#define OMV_ENABLE_MT9V034 (0)
#define OMV_ENABLE_LEPTON (0)
#define OMV_ENABLE_HM01B0 (0)
// Set which OV767x sensor is used
#define OMV_OV7670_VERSION (70)
// OV7670 clock divider
#define OMV_OV7670_CLKRC (0x00)
// FIR Module
#define OMV_ENABLE_FIR_MLX90621 (0)
#define OMV_ENABLE_FIR_MLX90640 (0)
#define OMV_ENABLE_FIR_MLX90641 (0)
#define OMV_ENABLE_FIR_AMG8833 (1)
#define OMV_ENABLE_FIR_LEPTON (0)
// Enable sensor features
#define OMV_ENABLE_OV5640_AF (0)
// Enable WiFi debug
#define OMV_ENABLE_WIFIDBG (0)
// Enable self-tests on first boot
#define OMV_ENABLE_SELFTEST (0)
// If buffer size is bigger than this threshold, the quality is reduced.
// This is only used for JPEG images sent to the IDE not normal compression.
#define JPEG_QUALITY_THRESH (160*120)
// Low and high JPEG QS.
#define JPEG_QUALITY_LOW 35
#define JPEG_QUALITY_HIGH 60
// FB Heap Block Size
#define OMV_UMM_BLOCK_SIZE 16
// Core VBAT for selftests
#define OMV_CORE_VBAT "3.3"
// USB IRQn.
#define OMV_USB_IRQN (USBCTRL_IRQ_IRQn)
// Linker script constants (see the linker script template port/x.ld.S).
#define OMV_FB_MEMORY RAM // Framebuffer, fb_alloc
#define OMV_MAIN_MEMORY RAM // data, bss and heap memory
#define OMV_STACK_MEMORY RAM // stack memory
#define OMV_FB_SIZE (151K) // FB memory: header + QVGA/GS image
#define OMV_FB_ALLOC_SIZE (12K) // minimum fb alloc size
#define OMV_STACK_SIZE (8K)
#define OMV_HEAP_SIZE (32 * 1024) // MicroPython's heap
#define OMV_JPEG_BUF_SIZE (20 * 1024) // IDE JPEG buffer (header + data).
// GP LED
#define LED_PIN (6)
// FIR I2C
#define FIR_I2C_ID (0)
#define FIR_I2C_SCL_PIN (27)
#define FIR_I2C_SDA_PIN (26)
#define FIR_I2C_SPEED (CAMBUS_SPEED_FULL)
// ISC I2C
#define ISC_I2C_ID (0)
#define ISC_I2C_SCL_PIN (27)
#define ISC_I2C_SDA_PIN (26)
#define ISC_I2C_SPEED (CAMBUS_SPEED_STANDARD)
// I2C0
#define I2C0_ID (0)
#define I2C0_SCL_PIN (27)
#define I2C0_SDA_PIN (26)
#define I2C0_SPEED (CAMBUS_SPEED_FULL)
// I2C1
#define I2C1_ID (1)
#define I2C1_SCL_PIN (7)
#define I2C1_SDA_PIN (6)
#define I2C1_SPEED (CAMBUS_SPEED_FULL)
#define LCD_SPI (spi0)
#define LCD_MOSI_PIN (7)
#define LCD_SCLK_PIN (6)
#define LCD_RST_PIN (4)
#define LCD_RST_PIN_WRITE(bit) gpio_put(LCD_RST_PIN, bit);
#define LCD_RS_PIN (25)
#define LCD_RS_PIN_WRITE(bit) gpio_put(LCD_RS_PIN, bit);
#define LCD_CS_PIN (5)
#define LCD_CS_PIN_WRITE(bit) gpio_put(LCD_CS_PIN, bit);
// AUDIO config.
#define PDM_PIO (pio1)
#define PDM_SM (0)
#define PDM_DMA (1)
#define PDM_DMA_IRQ (DMA_IRQ_1)
#define PDM_DMA_CHANNEL (0)
#define PDM_CLK_PIN (23)
#define PDM_DIN_PIN (22)
// DCMI config.
#define DCMI_PIO (pio0)
#define DCMI_SM (0)
#define DCMI_DMA (0)
#define DCMI_DMA_IRQ (DMA_IRQ_0)
#define DCMI_DMA_CHANNEL (0)
#define DCMI_PWDN_PIN (0)
#define DCMI_RESET_PIN (1)
#define DCMI_D0_PIN (15)
#define DCMI_D1_PIN (16)
#define DCMI_D2_PIN (17)
#define DCMI_D3_PIN (18)
#define DCMI_D4_PIN (19)
#define DCMI_D5_PIN (20)
#define DCMI_D6_PIN (21)
#define DCMI_D7_PIN (22) // This pin is missing
#define DCMI_XCLK_PIN (28)
#define DCMI_PXCLK_PIN (29)
#define DCMI_HSYNC_PIN (12)
#define DCMI_VSYNC_PIN (13)
#if defined(DCMI_RESET_PIN)
#define DCMI_RESET_LOW() gpio_put(DCMI_RESET_PIN, 0)
#define DCMI_RESET_HIGH() gpio_put(DCMI_RESET_PIN, 1)
#else
#define DCMI_RESET_LOW()
#define DCMI_RESET_HIGH()
#endif
#if defined(DCMI_PWDN_PIN)
#define DCMI_PWDN_LOW() gpio_put(DCMI_PWDN_PIN, 0)
#define DCMI_PWDN_HIGH() gpio_put(DCMI_PWDN_PIN, 1)
#else
#define DCMI_PWDN_LOW()
#define DCMI_PWDN_HIGH()
#endif
#endif //__OMV_BOARDCONFIG_H__

View File

@ -0,0 +1 @@
PORT=rp2

View File

@ -0,0 +1,12 @@
/*
* This file is part of the OpenMV project.
* Copyright (c) 2013-2016 Kwabena W. Agyeman <kwagyeman@openmv.io>
* 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.
#endif //__ULAB_CONFIG_H__

View File

@ -0,0 +1,153 @@
/*
* This file is part of the OpenMV project.
*
* Copyright (c) 2013-2021 Ibrahim Abdelkader <iabdalkader@openmv.io>
* Copyright (c) 2013-2021 Kwabena W. Agyeman <kwagyeman@openmv.io>
*
* This work is licensed under the MIT license, see the file LICENSE for details.
*
* 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
// Not filesystem yet
//#define IMLIB_ENABLE_IMAGE_FILE_IO
// Enable LAB LUT
//#define IMLIB_ENABLE_LAB_LUT
// Enable YUV LUT
//#define IMLIB_ENABLE_YUV_LUT
// Enable mean pooling
//#define IMLIB_ENABLE_MEAN_POOLING
// Enable midpoint pooling
//#define IMLIB_ENABLE_MIDPOINT_POOLING
// 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 cartoon()
// #define IMLIB_ENABLE_CARTOON
// 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
// 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 CMSIS NN
// #if !defined(CUBEAI)
// #define IMLIB_ENABLE_CNN
// #endif
// Enable Tensor Flow
#if !defined(CUBEAI)
//#define IMLIB_ENABLE_TF
#endif
// Enable FAST (20+ KBs).
// #define IMLIB_ENABLE_FAST
// Enable find_template()
//#define IMLIB_FIND_TEMPLATE
// Enable find_lbp()
//#define IMLIB_ENABLE_FIND_LBP
// Enable find_keypoints()
//#define IMLIB_ENABLE_FIND_KEYPOINTS
// 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 STM32 DMA2D
//#define IMLIB_ENABLE_DMA2D
#endif //__IMLIB_CONFIG_H__

View File

@ -0,0 +1,2 @@
freeze ("$(PORT_DIR)/modules")
include("$(MPY_DIR)/extmod/uasyncio/manifest.py")

View File

@ -0,0 +1,12 @@
set(MICROPY_PY_SENSOR 1)
set(MICROPY_PY_ULAB 1)
set(MICROPY_PY_WINC1500 0)
set(MICROPY_PY_LWIP 0)
set(MICROPY_PY_NETWORK_CYW43 0)
set(MICROPY_PY_BLUETOOTH 0)
set(MICROPY_BLUETOOTH_NIMBLE 0)
set(MICROPY_PY_AUDIO 0)
set(MICROPY_PY_MICRO_SPEECH 0)
set(MICROPY_PY_LCD 0)
set(MICROPY_PY_TV 0)
set(MICROPY_PY_BUZZER 0)

View File

@ -0,0 +1,192 @@
/*
* This file is part of the OpenMV project.
*
* Copyright (c) 2013-2021 Ibrahim Abdelkader <iabdalkader@openmv.io>
* Copyright (c) 2013-2021 Kwabena W. Agyeman <kwagyeman@openmv.io>
*
* This work is licensed under the MIT license, see the file LICENSE for details.
*
* Board configuration and pin definitions.
*/
#ifndef __OMV_BOARDCONFIG_H__
#define __OMV_BOARDCONFIG_H__
// Architecture info
#define OMV_ARCH_STR "PICO M0" // 33 chars max
#define OMV_BOARD_TYPE "PICO"
#ifndef LINKER_SCRIPT
extern unsigned char *OMV_UNIQUE_ID_ADDR;
#endif
#define OMV_UNIQUE_ID_SIZE 2 // 2 words
#define OMV_XCLK_MCO (0U)
#define OMV_XCLK_TIM (1U)
// Sensor external clock source.
#define OMV_XCLK_SOURCE (OMV_XCLK_TIM)
// Sensor external clock timer frequency.
// TODO Not actually used right now, frequency is hardcoded.
#define OMV_XCLK_FREQUENCY (12500000)
// RAW buffer size
#define OMV_RAW_BUF_SIZE (151*1024)
// Enable hardware JPEG
#define OMV_HARDWARE_JPEG (0)
// Enable sensor drivers
#define OMV_ENABLE_OV2640 (0)
#define OMV_ENABLE_OV5640 (0)
#define OMV_ENABLE_OV7670 (1)
#define OMV_ENABLE_OV7690 (0)
#define OMV_ENABLE_OV7725 (0)
#define OMV_ENABLE_OV9650 (0)
#define OMV_ENABLE_MT9V034 (0)
#define OMV_ENABLE_LEPTON (0)
#define OMV_ENABLE_HM01B0 (0)
// Set which OV767x sensor is used
#define OMV_OV7670_VERSION (70)
// OV7670 clock divider
#define OMV_OV7670_CLKRC (0x00)
// FIR Module
#define OMV_ENABLE_FIR_MLX90621 (0)
#define OMV_ENABLE_FIR_MLX90640 (0)
#define OMV_ENABLE_FIR_MLX90641 (0)
#define OMV_ENABLE_FIR_AMG8833 (1)
#define OMV_ENABLE_FIR_LEPTON (0)
// Enable sensor features
#define OMV_ENABLE_OV5640_AF (0)
// Enable WiFi debug
#define OMV_ENABLE_WIFIDBG (0)
// Enable self-tests on first boot
#define OMV_ENABLE_SELFTEST (0)
// If buffer size is bigger than this threshold, the quality is reduced.
// This is only used for JPEG images sent to the IDE not normal compression.
#define JPEG_QUALITY_THRESH (160*120)
// Low and high JPEG QS.
#define JPEG_QUALITY_LOW 35
#define JPEG_QUALITY_HIGH 60
// FB Heap Block Size
#define OMV_UMM_BLOCK_SIZE 16
// Core VBAT for selftests
#define OMV_CORE_VBAT "3.3"
// USB IRQn.
#define OMV_USB_IRQN (USBCTRL_IRQ_IRQn)
// Linker script constants (see the linker script template port/x.ld.S).
#define OMV_FB_MEMORY RAM // Framebuffer, fb_alloc
#define OMV_MAIN_MEMORY RAM // data, bss and heap memory
#define OMV_STACK_MEMORY RAM // stack memory
#define OMV_FB_SIZE (151K) // FB memory: header + QVGA/GS image
#define OMV_FB_ALLOC_SIZE (12K) // minimum fb alloc size
#define OMV_STACK_SIZE (8K)
#define OMV_HEAP_SIZE (32 * 1024) // MicroPython's heap
#define OMV_JPEG_BUF_SIZE (20 * 1024) // IDE JPEG buffer (header + data).
// GP LED
#define LED_PIN (25)
// FIR I2C
#define FIR_I2C_ID (0)
#define FIR_I2C_SCL_PIN (27)
#define FIR_I2C_SDA_PIN (26)
#define FIR_I2C_SPEED (CAMBUS_SPEED_FULL)
// ISC I2C
#define ISC_I2C_ID (1)
#define ISC_I2C_SCL_PIN (15)
#define ISC_I2C_SDA_PIN (14)
#define ISC_I2C_SPEED (CAMBUS_SPEED_STANDARD)
// I2C0
#define I2C0_ID (0)
#define I2C0_SCL_PIN (27)
#define I2C0_SDA_PIN (26)
#define I2C0_SPEED (CAMBUS_SPEED_FULL)
// I2C1
#define I2C1_ID (1)
#define I2C1_SCL_PIN (15)
#define I2C1_SDA_PIN (14)
#define I2C1_SPEED (CAMBUS_SPEED_FULL)
#define LCD_SPI (spi0)
#define LCD_MOSI_PIN (19)
#define LCD_SCLK_PIN (18)
#define LCD_RST_PIN (20)
#define LCD_RST_PIN_WRITE(bit) gpio_put(LCD_RST_PIN, bit);
#define LCD_RS_PIN (21)
#define LCD_RS_PIN_WRITE(bit) gpio_put(LCD_RS_PIN, bit);
#define LCD_CS_PIN (17)
#define LCD_CS_PIN_WRITE(bit) gpio_put(LCD_CS_PIN, bit);
// AUDIO config.
//#define PDM_PIO (pio1)
//#define PDM_SM (0)
//#define PDM_DMA (1)
//#define PDM_DMA_IRQ (DMA_IRQ_1)
//#define PDM_DMA_CHANNEL (0)
//
//#define PDM_CLK_PIN (23)
//#define PDM_DIN_PIN (22)
// DCMI config.
#define DCMI_PIO (pio0)
#define DCMI_SM (0)
#define DCMI_DMA (0)
#define DCMI_DMA_IRQ (DMA_IRQ_0)
#define DCMI_DMA_CHANNEL (0)
#define DCMI_PWDN_PIN (0)
#define DCMI_RESET_PIN (1)
#define DCMI_D0_PIN (2)
#define DCMI_D1_PIN (3)
#define DCMI_D2_PIN (4)
#define DCMI_D3_PIN (5)
#define DCMI_D4_PIN (6)
#define DCMI_D5_PIN (7)
#define DCMI_D6_PIN (8)
#define DCMI_D7_PIN (9)
// TODO: These are hard-coded in dcmi.pio need to fix.
#define DCMI_PXCLK_PIN (11)
#define DCMI_HSYNC_PIN (12)
#define DCMI_VSYNC_PIN (13)
#define DCMI_XCLK_PIN (10)
#if defined(DCMI_RESET_PIN)
#define DCMI_RESET_LOW() gpio_put(DCMI_RESET_PIN, 0)
#define DCMI_RESET_HIGH() gpio_put(DCMI_RESET_PIN, 1)
#else
#define DCMI_RESET_LOW()
#define DCMI_RESET_HIGH()
#endif
#if defined(DCMI_PWDN_PIN)
#define DCMI_PWDN_LOW() gpio_put(DCMI_PWDN_PIN, 0)
#define DCMI_PWDN_HIGH() gpio_put(DCMI_PWDN_PIN, 1)
#else
#define DCMI_PWDN_LOW()
#define DCMI_PWDN_HIGH()
#endif
#endif //__OMV_BOARDCONFIG_H__

View File

@ -0,0 +1 @@
PORT=rp2

View File

@ -0,0 +1,12 @@
/*
* This file is part of the OpenMV project.
* Copyright (c) 2013-2016 Kwabena W. Agyeman <kwagyeman@openmv.io>
* 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.
#endif //__ULAB_CONFIG_H__

145
src/omv/ports/rp2/cambus.c Normal file
View File

@ -0,0 +1,145 @@
#include <stdio.h>
#include <stdbool.h>
#include "py/mphal.h"
#include "pico/time.h"
#include "pico/stdlib.h"
#include "hardware/i2c.h"
#include "omv_boardconfig.h"
#include "cambus.h"
#define I2C_TIMEOUT (100*1000)
#define I2C_SCAN_TIMEOUT (10*1000)
int cambus_init(cambus_t *bus, uint32_t bus_id, uint32_t speed)
{
bus->id = bus_id;
bus->initialized = false;
switch (speed) {
case CAMBUS_SPEED_STANDARD:
bus->speed = 100 * 1000; ///< 100 kbps
break;
case CAMBUS_SPEED_FULL:
bus->speed = 250 * 1000; ///< 250 kbps
break;
case CAMBUS_SPEED_FAST:
bus->speed = 400 * 1000; ///< 400 kbps
break;
default:
return -1;
}
switch (bus_id) {
case 0: {
bus->i2c = i2c0;
bus->scl_pin = I2C0_SCL_PIN;
bus->sda_pin = I2C0_SDA_PIN;
break;
}
case 1: {
bus->i2c = i2c1;
bus->scl_pin = I2C1_SCL_PIN;
bus->sda_pin = I2C1_SDA_PIN;
break;
}
default:
return -1;
}
i2c_init(bus->i2c, bus->speed);
gpio_set_function(bus->scl_pin, GPIO_FUNC_I2C);
gpio_set_function(bus->sda_pin, GPIO_FUNC_I2C);
bus->initialized = true;
return 0;
}
int cambus_deinit(cambus_t *bus)
{
if (bus->initialized) {
i2c_deinit(bus->i2c);
bus->initialized = false;
}
return 0;
}
int cambus_scan(cambus_t *bus)
{
for (uint8_t addr=0x09, rxdata; addr<=0x77; addr++) {
if (i2c_read_timeout_us(bus->i2c, addr, &rxdata, 1, false, I2C_SCAN_TIMEOUT) >= 0) {
return (addr << 1);
}
}
return 0;
}
int cambus_readb(cambus_t *bus, uint8_t slv_addr, uint8_t reg_addr, uint8_t *reg_data)
{
int bytes = 0;
slv_addr = slv_addr >> 1;
bytes += i2c_write_timeout_us(bus->i2c, slv_addr, &reg_addr, 1, false, I2C_TIMEOUT);
bytes += i2c_read_timeout_us(bus->i2c, slv_addr, reg_data, 1, false, I2C_TIMEOUT);
return (bytes == 2) ? 0 : -1;
}
int cambus_writeb(cambus_t *bus, uint8_t slv_addr, uint8_t reg_addr, uint8_t reg_data)
{
int bytes = 0;
slv_addr = slv_addr >> 1;
uint8_t buf[] = {reg_addr, reg_data};
bytes = i2c_write_timeout_us(bus->i2c, slv_addr, buf, 2, false, I2C_TIMEOUT);
return (bytes == 2) ? 0 : -1;
}
int cambus_read_bytes(cambus_t *bus, uint8_t slv_addr, uint8_t *buf, int len, uint32_t flags)
{
int bytes = 0;
slv_addr = slv_addr >> 1;
bool nostop = false;
if (flags & CAMBUS_XFER_NO_STOP) {
nostop = true;
}
bytes = i2c_read_timeout_us(bus->i2c, slv_addr, buf, len, nostop, I2C_TIMEOUT);
return (bytes == len) ? 0 : -1;
}
int cambus_write_bytes(cambus_t *bus, uint8_t slv_addr, uint8_t *buf, int len, uint32_t flags)
{
int bytes = 0;
slv_addr = slv_addr >> 1;
bool nostop = false;
if (flags & CAMBUS_XFER_NO_STOP) {
nostop = true;
}
bytes = i2c_write_timeout_us(bus->i2c, slv_addr, buf, len, nostop, I2C_TIMEOUT);
return (bytes == len) ? 0 : -1;
}
int cambus_pulse_scl(cambus_t *bus)
{
cambus_deinit(bus);
// Configure SCL as GPIO
gpio_init(bus->scl_pin);
gpio_set_dir(bus->scl_pin, GPIO_OUT);
// Pulse SCL to recover stuck device.
for (int i=0; i<10000; i++) {
gpio_put(bus->scl_pin, 1);
mp_hal_delay_us(10);
gpio_put(bus->scl_pin, 0);
mp_hal_delay_us(10);
}
return 0;
}

View File

@ -0,0 +1,57 @@
; This file is part of the OpenMV project.
;
; Copyright (c) 2013-2021 Ibrahim Abdelkader <iabdalkader@openmv.io>
; Copyright (c) 2013-2021 Kwabena W. Agyeman <kwagyeman@openmv.io>
;
; This work is licensed under the MIT license, see the file LICENSE for details.
; Image Sensor PIO program.
.define public PXCLK 11
.define public HSYNC 12
.define public VSYNC 13
.program dcmi_default
.wrap_target
pull block ; Read number of lines in OSR
mov y, osr ; Copy OSR to Y
pull block ; Read line width in bytes in OSR
wait 1 gpio VSYNC ; Wait for VSYNC to go low
wait 0 gpio VSYNC
line_loop:
mov x, osr ; Copy line width from OSR to X
wait 0 gpio HSYNC ; Wait for HSYNC to go high
wait 1 gpio HSYNC
pixels_loop:
wait 0 gpio PXCLK
wait 1 gpio PXCLK
in pins 8
jmp x-- pixels_loop ; Keep reading pixels while x != 0
jmp y-- line_loop ; Keep reading lines while y != 0
.wrap
.program dcmi_odd_byte
.wrap_target
pull block ; Read number of lines in OSR
mov y, osr ; Copy OSR to Y
pull block ; Read line width in bytes in OSR
wait 1 gpio VSYNC ; Wait for VSYNC to go low
wait 0 gpio VSYNC
line_loop:
mov x, osr ; Copy line width from OSR to X
wait 0 gpio HSYNC ; Wait for HSYNC to go high
wait 1 gpio HSYNC
pixels_loop:
wait 0 gpio PXCLK
wait 1 gpio PXCLK
in pins 8
wait 0 gpio PXCLK
wait 1 gpio PXCLK
jmp x-- pixels_loop ; Keep reading pixels while x != 0
jmp y-- line_loop ; Keep reading lines while y != 0
.wrap

326
src/omv/ports/rp2/main.c Normal file
View File

@ -0,0 +1,326 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2020-2021 Damien P. George
*
* 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.
*/
#include <stdio.h>
#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 "lib/mp-readline/readline.h"
#include "lib/utils/gchelper.h"
#include "lib/utils/pyexec.h"
#include "tusb.h"
#include "uart.h"
#include "modmachine.h"
#include "modrp2.h"
#include "genhdr/mpversion.h"
#include "pendsv.h"
#include "pico/stdlib.h"
#include "pico/binary_info.h"
#include "hardware/rtc.h"
#include "hardware/structs/rosc.h"
#include "pico/unique_id.h"
#include "omv_boardconfig.h"
#include "framebuffer.h"
#include "cambus.h"
#include "sensor.h"
#include "usbdbg.h"
#include "py_fir.h"
#if MICROPY_PY_AUDIO
#include "py_audio.h"
#endif
extern uint8_t __StackTop, __StackBottom;
static char OMV_ATTR_SECTION(OMV_ATTR_ALIGNED(gc_heap[OMV_HEAP_SIZE], 4), ".heap");
uint8_t *OMV_UNIQUE_ID_ADDR;
static pico_unique_board_id_t OMV_ATTR_ALIGNED(pico_unique_id, 4);
// Embed version info in the binary in machine readable form
bi_decl(bi_program_version_string(MICROPY_GIT_TAG));
// Add a section to the picotool output similar to program features, but for frozen modules
// (it will aggregate BINARY_INFO_ID_MP_FROZEN binary info)
bi_decl(bi_program_feature_group_with_flags(BINARY_INFO_TAG_MICROPYTHON,
BINARY_INFO_ID_MP_FROZEN, "frozen modules",
BI_NAMED_GROUP_SEPARATE_COMMAS | BI_NAMED_GROUP_SORT_ALPHA));
void __fatal_error()
{
gpio_init(LED_PIN);
gpio_set_dir(LED_PIN, GPIO_OUT);
while (true) {
gpio_put(LED_PIN, 1);
sleep_ms(100);
gpio_put(LED_PIN, 0);
sleep_ms(100);
}
}
void exec_boot_script(const char *path, bool interruptible)
{
nlr_buf_t nlr;
bool interrupted = false;
if (nlr_push(&nlr) == 0) {
// Enable IDE interrupts if allowed.
if (interruptible) {
usbdbg_set_irq_enabled(true);
usbdbg_set_script_running(true);
}
// Parse, compile and execute the script.
pyexec_file_if_exists(path);
nlr_pop();
} else {
interrupted = true;
}
// Disable IDE interrupts
usbdbg_set_irq_enabled(false);
usbdbg_set_script_running(false);
if (interrupted) {
mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val);
}
}
int main(int argc, char **argv) {
bool first_soft_reset = true;
#if MICROPY_HW_ENABLE_UART_REPL
bi_decl(bi_program_feature("UART REPL"))
setup_default_uart();
mp_uart_init();
#endif
#if MICROPY_HW_ENABLE_USBDEV
bi_decl(bi_program_feature("USB REPL"))
#endif
#if MICROPY_PY_THREAD
bi_decl(bi_program_feature("thread support"))
mp_thread_init();
#endif
// Start and initialise the RTC
datetime_t t = {
.year = 2021,
.month = 1,
.day = 1,
.dotw = 5, // 0 is Sunday, so 5 is Friday
.hour = 0,
.min = 0,
.sec = 0,
};
rtc_init();
rtc_set_datetime(&t);
// Set board unique ID from flash for USB debugging.
OMV_UNIQUE_ID_ADDR = pico_unique_id.id;
pico_get_unique_board_id(&pico_unique_id);
soft_reset:
// Initialise stack extents and GC heap.
mp_stack_set_top(&__StackTop);
mp_stack_set_limit(&__StackTop - &__StackBottom - 256);
gc_init(&gc_heap[0], &gc_heap[MP_ARRAY_SIZE(gc_heap)]);
// Initialise MicroPython runtime.
mp_init();
mp_obj_list_init(MP_OBJ_TO_PTR(mp_sys_path), 0);
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_));
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_lib));
mp_obj_list_init(MP_OBJ_TO_PTR(mp_sys_argv), 0);
// Initialise sub-systems.
mp_hal_init();
readline_init0();
machine_pin_init();
rp2_pio_init();
pendsv_init();
usbdbg_init();
fb_alloc_init0();
framebuffer_init0();
py_fir_init0();
#if MICROPY_PY_SENSOR
if (sensor_init() != 0) {
printf("sensor init failed!\n");
}
#endif
// Execute _boot.py to set up the filesystem.
pyexec_frozen_module("_boot.py");
// Execute user scripts.
exec_boot_script("boot.py", false);
if (first_soft_reset) {
exec_boot_script("main.py", true);
}
// If there's no script ready, just re-exec REPL
while (!usbdbg_script_ready()) {
nlr_buf_t nlr;
if (nlr_push(&nlr) == 0) {
// enable IDE interrupt
usbdbg_set_irq_enabled(true);
// run REPL
if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) {
if (pyexec_raw_repl() != 0) {
break;
}
} else {
if (pyexec_friendly_repl() != 0) {
break;
}
}
nlr_pop();
}
}
if (usbdbg_script_ready()) {
nlr_buf_t nlr;
if (nlr_push(&nlr) == 0) {
// Enable IDE interrupt
usbdbg_set_irq_enabled(true);
// Execute the script.
pyexec_str(usbdbg_get_script());
nlr_pop();
} else {
mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val);
}
}
usbdbg_wait_for_command(1000);
usbdbg_set_irq_enabled(false);
#if MICROPY_PY_AUDIO
py_audio_deinit();
#endif
rp2_pio_deinit();
machine_pin_deinit();
gc_sweep_all();
mp_deinit();
first_soft_reset = false;
goto soft_reset;
return 0;
}
void gc_collect(void) {
gc_collect_start();
gc_helper_collect_regs_and_stack();
#if MICROPY_PY_THREAD
mp_thread_gc_others();
#endif
gc_collect_end();
}
void nlr_jump_fail(void *val) {
printf("FATAL: uncaught exception %p\n", val);
mp_obj_print_exception(&mp_plat_print, MP_OBJ_FROM_PTR(val));
for (;;) {
__breakpoint();
}
}
#ifndef NDEBUG
void MP_WEAK __assert_func(const char *file, int line, const char *func, const char *expr) {
printf("Assertion '%s' failed, at file %s:%d\n", expr, file, line);
panic("Assertion failed");
}
#endif
#define POLY (0xD5)
uint8_t rosc_random_u8(size_t cycles) {
static uint8_t r;
for (size_t i = 0; i < cycles; ++i) {
r = ((r << 1) | rosc_hw->randombit) ^ (r & 0x80 ? POLY : 0);
mp_hal_delay_us_fast(1);
}
return r;
}
uint32_t rosc_random_u32(void) {
uint32_t value = 0;
for (size_t i = 0; i < 4; ++i) {
value = value << 8 | rosc_random_u8(32);
}
return value;
}
const char rp2_help_text[] =
"Welcome to MicroPython!\n"
"\n"
"For online help please visit https://micropython.org/help/.\n"
"\n"
"For access to the hardware use the 'machine' module. RP2 specific commands\n"
"are in the 'rp2' module.\n"
"\n"
"Quick overview of some objects:\n"
" machine.Pin(pin) -- get a pin, eg machine.Pin(0)\n"
" machine.Pin(pin, m, [p]) -- get a pin and configure it for IO mode m, pull mode p\n"
" methods: init(..), value([v]), high(), low(), irq(handler)\n"
" machine.ADC(pin) -- make an analog object from a pin\n"
" methods: read_u16()\n"
" machine.PWM(pin) -- make a PWM object from a pin\n"
" methods: deinit(), freq([f]), duty_u16([d]), duty_ns([d])\n"
" machine.I2C(id) -- create an I2C object (id=0,1)\n"
" methods: readfrom(addr, buf, stop=True), writeto(addr, buf, stop=True)\n"
" readfrom_mem(addr, memaddr, arg), writeto_mem(addr, memaddr, arg)\n"
" machine.SPI(id, baudrate=1000000) -- create an SPI object (id=0,1)\n"
" methods: read(nbytes, write=0x00), write(buf), write_readinto(wr_buf, rd_buf)\n"
" machine.Timer(freq, callback) -- create a software timer object\n"
" eg: machine.Timer(freq=1, callback=lambda t:print(t))\n"
"\n"
"Pins are numbered 0-29, and 26-29 have ADC capabilities\n"
"Pin IO modes are: Pin.IN, Pin.OUT, Pin.ALT\n"
"Pin pull modes are: Pin.PULL_UP, Pin.PULL_DOWN\n"
"\n"
"Useful control commands:\n"
" CTRL-C -- interrupt a running program\n"
" CTRL-D -- on a blank line, do a soft reset of the board\n"
" CTRL-E -- on a blank line, enter paste mode\n"
"\n"
"For further help on a specific object, type help(obj)\n"
"For a list of available modules, type help('modules')\n"
;

View File

@ -0,0 +1,207 @@
/*
* This file is part of the OpenMV project.
*
* Copyright (c) 2013-2021 Ibrahim Abdelkader <iabdalkader@openmv.io>
* Copyright (c) 2013-2021 Kwabena W. Agyeman <kwagyeman@openmv.io>
*
* This work is licensed under the MIT license, see the file LICENSE for details.
*
* Audio Python module.
*/
#include <stdio.h>
#include <stdint.h>
#include "py/obj.h"
#include "py/objarray.h"
#include "py/nlr.h"
#include "py/mphal.h"
#include "py/binary.h"
#include "pendsv.h"
#include "runtime.h"
#include "omv_boardconfig.h"
#if MICROPY_PY_AUDIO
#include "py_audio.h"
#include "py_assert.h"
#include "py_helper.h"
#include "hardware/pio.h"
#include "hardware/dma.h"
#include "hardware/irq.h"
#include "hardware/clocks.h"
#include "pdm.pio.h"
#include "OpenPDMFilter.h"
#define PDM_DEFAULT_GAIN (16)
#define PDM_BUFFER_SIZE (512)
#define RAISE_OS_EXCEPTION(msg) mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT(msg))
static mp_obj_array_t *g_pcmbuf = NULL;
static mp_obj_t g_audio_callback = mp_const_none;
static uint32_t g_buf_index = 0;
static uint32_t g_decimation = 64;
static uint8_t PDM_BUFFERS[2][PDM_BUFFER_SIZE];
// OpenPDM filter used to convert PDM into PCM
static TPDMFilter_InitStruct pdm_filter;
// Pendsv dispatch callback.
static void audio_pendsv_callback(void)
{
// Call user callback
mp_call_function_1(g_audio_callback, MP_OBJ_FROM_PTR(g_pcmbuf));
}
static void dma_irq_handler()
{
// Clear the interrupt request.
dma_irqn_acknowledge_channel(PDM_DMA, PDM_DMA_CHANNEL);
// Set next buffer and retrigger the DMA channel.
dma_channel_set_write_addr(PDM_DMA_CHANNEL, PDM_BUFFERS[g_buf_index ^ 1], true);
// Convert PDM to PCM samples.
// TODO: should run this in PendSV context instead.
if (g_decimation == 64) {
Open_PDM_Filter_64(PDM_BUFFERS[g_buf_index], g_pcmbuf->items, 1, &pdm_filter);
} else {
Open_PDM_Filter_128(PDM_BUFFERS[g_buf_index], g_pcmbuf->items, 1, &pdm_filter);
}
// Schedule audio callback.
pendsv_schedule_dispatch(PENDSV_DISPATCH_AUDIO, audio_pendsv_callback);
// Swap buffers
g_buf_index ^= 1;
}
static mp_obj_t py_audio_init(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
{
// Read Args.
uint32_t channels = py_helper_keyword_int(n_args, args, 0, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_channels), 1);
uint32_t frequency = py_helper_keyword_int(n_args, args, 1, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_frequency), 16000);
int gain = py_helper_keyword_int(n_args, args, 2, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_gain_db), PDM_DEFAULT_GAIN);
// Sanity checks
if (channels != 1) {
RAISE_OS_EXCEPTION("Invalid number of channels! Expected 1.");
}
if (!(frequency == 16000 || frequency == 32000 || frequency == 48000)) {
RAISE_OS_EXCEPTION("Invalid number of channels! Expected 16K, 32K or 48K.");
}
uint32_t g_decimation = (frequency == 16000) ? 128 : 64;
uint32_t n_samples = (PDM_BUFFER_SIZE * 8) / g_decimation;
// Initialize OpenPDM filter.
pdm_filter.Fs = frequency;
pdm_filter.nSamples = n_samples;
pdm_filter.LP_HZ = frequency / 2;
pdm_filter.HP_HZ = 10;
pdm_filter.In_MicChannels = channels;
pdm_filter.Out_MicChannels = channels;
pdm_filter.Decimation = g_decimation;
pdm_filter.filterGain = gain;
Open_PDM_Filter_Init(&pdm_filter);
// Configure PIO state machine
float clkDiv = (float) clock_get_hz(clk_sys) / frequency / g_decimation / 2;
uint offset = pio_add_program(PDM_PIO, &pdm_pio_program);
pdm_pio_program_init(PDM_PIO, PDM_SM, offset, PDM_CLK_PIN, PDM_DIN_PIN, clkDiv);
// Wait for microphone
mp_hal_delay_ms(100);
// Configure DMA for transferring PIO rx buffer to raw buffers
dma_channel_config c = dma_channel_get_default_config(PDM_DMA_CHANNEL);
channel_config_set_read_increment(&c, false);
channel_config_set_write_increment(&c, true);
channel_config_set_dreq(&c, pio_get_dreq(PDM_PIO, PDM_SM, false));
channel_config_set_transfer_data_size(&c, DMA_SIZE_8);
// Configure DMA channel without starting.
dma_channel_configure(PDM_DMA_CHANNEL, &c,
PDM_BUFFERS[0], // Destinatinon pointer
&PDM_PIO->rxf[PDM_SM], // Source pointer
sizeof(PDM_BUFFERS[0]), // Number of transfers
false // Don't start immediately
);
// Set new DMA IRQ handler.
// Disable IRQs.
irq_set_enabled(PDM_DMA_IRQ, false);
// Clear DMA interrupts.
dma_irqn_acknowledge_channel(PDM_DMA, PDM_DMA_CHANNEL);
// Remove current handler if any.
irq_handler_t irq_handler = irq_get_exclusive_handler(PDM_DMA_IRQ);
if (irq_handler != NULL) {
irq_remove_handler(PDM_DMA_IRQ, irq_handler);
}
// Set new exclusive IRQ handler.
irq_set_exclusive_handler(PDM_DMA_IRQ, dma_irq_handler);
// Or set shared IRQ handler, but this needs to be called once.
// irq_add_shared_handler(PDM_DMA_IRQ, dma_irq_handler, PICO_DEFAULT_IRQ_PRIORITY);
// Re-enable IRQs.
irq_set_enabled(PDM_DMA_IRQ, true);
dma_irqn_set_channel_enabled(PDM_DMA, PDM_DMA_CHANNEL, true);
// Allocate global PCM buffer.
g_pcmbuf = mp_obj_new_bytearray_by_ref(n_samples * sizeof(int16_t), m_new(int16_t, n_samples));
return mp_const_none;
}
void py_audio_deinit()
{
// Disable PDM and IRQ
dma_channel_abort(PDM_DMA_CHANNEL);
dma_irqn_set_channel_enabled(PDM_DMA, PDM_DMA_CHANNEL, false);
g_pcmbuf = NULL;
g_buf_index = 0;
g_audio_callback = mp_const_none;
}
static mp_obj_t py_audio_start_streaming(mp_obj_t callback_obj)
{
g_audio_callback = callback_obj;
if (!mp_obj_is_callable(g_audio_callback)) {
g_audio_callback = mp_const_none;
RAISE_OS_EXCEPTION("Invalid callback object!");
}
dma_channel_start(PDM_DMA_CHANNEL);
return mp_const_none;
}
static mp_obj_t py_audio_stop_streaming()
{
py_audio_deinit();
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_audio_init_obj, 0, py_audio_init);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_audio_start_streaming_obj, py_audio_start_streaming);
STATIC MP_DEFINE_CONST_FUN_OBJ_0(py_audio_stop_streaming_obj, py_audio_stop_streaming);
static const mp_rom_map_elem_t globals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_audio) },
{ MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&py_audio_init_obj) },
{ MP_ROM_QSTR(MP_QSTR_start_streaming), MP_ROM_PTR(&py_audio_start_streaming_obj)},
{ MP_ROM_QSTR(MP_QSTR_stop_streaming), MP_ROM_PTR(&py_audio_stop_streaming_obj) },
};
STATIC MP_DEFINE_CONST_DICT(globals_dict, globals_dict_table);
const mp_obj_module_t audio_module = {
.base = { &mp_type_module },
.globals = (mp_obj_t)&globals_dict,
};
#endif //MICROPY_PY_AUDIO

View File

@ -0,0 +1,14 @@
/*
* This file is part of the OpenMV project.
*
* Copyright (c) 2013-2021 Ibrahim Abdelkader <iabdalkader@openmv.io>
* Copyright (c) 2013-2021 Kwabena W. Agyeman <kwagyeman@openmv.io>
*
* This work is licensed under the MIT license, see the file LICENSE for details.
*
* Audio Python module.
*/
#ifndef __PY_AUDIO_H__
#define __PY_AUDIO_H__
void py_audio_deinit();
#endif // __PY_AUDIO_H__

View File

@ -0,0 +1,253 @@
# Need to redefine these variables here.
set(TOP_DIR $ENV{TOP_DIR})
set(TARGET $ENV{TARGET})
set(PORT rp2)
set(BUILD ${TOP_DIR}/build)
set(FW_DIR ${BUILD}/bin)
set(OMV_DIR omv)
set(UVC_DIR uvc)
set(CM4_DIR cm4)
set(BOOTLDR_DIR bootloader)
set(CUBEAI_DIR stm32cubeai)
set(CMSIS_DIR hal/cmsis)
#set(MICROPY_DIR micropython)
set(LEPTON_DIR drivers/lepton)
set(LSM6DS3_DIR drivers/lsm6ds3)
set(WINC1500_DIR drivers/winc1500)
set(MLX90621_DIR drivers/mlx90621)
set(MLX90640_DIR drivers/mlx90640)
set(MLX90641_DIR drivers/mlx90641)
set(OPENPDM_DIR ${TOP_DIR}/lib/openpdm)
set(TENSORFLOW_DIR ${TOP_DIR}/lib/libtf)
set(OMV_BOARD_CONFIG_DIR ${TOP_DIR}/${OMV_DIR}/boards/${TARGET}/)
#set(MP_BOARD_CONFIG_DIR ${TOP_DIR}/${MICROPY_DIR}/ports/${PORT}/boards/${TARGET}/
set(MPY_LIB_DIR ${TOP_DIR}/../scripts/libraries)
set(FROZEN_MANIFEST ${OMV_BOARD_CONFIG_DIR}/manifest.py)
set(OMV_COMMON_DIR ${TOP_DIR}/${OMV_DIR}/common)
set(PORT_DIR ${TOP_DIR}/${OMV_DIR}/ports/${PORT})
# Include board cmake fragment
include(${OMV_BOARD_CONFIG_DIR}/omv_boardconfig.cmake)
target_compile_definitions(${MICROPY_TARGET} PRIVATE
ARM_MATH_CM0PLUS
${OMV_BOARD_MODULES_DEFINITIONS}
)
#target_compile_options(${MICROPY_TARGET} PRIVATE
#)
# Generate DCMI PIO header
pico_generate_pio_header(${MICROPY_TARGET}
${TOP_DIR}/${OMV_DIR}/ports/${PORT}/dcmi.pio
)
# Linker script
add_custom_command(
OUTPUT ${FW_DIR}/rp2.ld
COMMENT "Preprocessing linker script"
COMMAND "${CMAKE_C_COMPILER}" -P -E -I ${OMV_BOARD_CONFIG_DIR} -DLINKER_SCRIPT ${PORT_DIR}/rp2.ld.S > ${FW_DIR}/rp2.ld
DEPENDS ${OMV_BOARD_CONFIG_DIR}/omv_boardconfig.h ${PORT_DIR}/rp2.ld.S
VERBATIM
)
add_custom_target(
LinkerScript
ALL DEPENDS ${FW_DIR}/rp2.ld
VERBATIM
)
pico_set_linker_script(${MICROPY_TARGET} ${FW_DIR}/rp2.ld)
# Add OMV qstr sources
file(GLOB OMV_SRC_QSTR1 ${TOP_DIR}/${OMV_DIR}/modules/*.c)
file(GLOB OMV_SRC_QSTR2 ${TOP_DIR}/${OMV_DIR}/ports/${PORT}/modules/*.c)
list(APPEND MICROPY_SOURCE_QSTR ${OMV_SRC_QSTR1} ${OMV_SRC_QSTR2})
# Override manifest file
set(MICROPY_FROZEN_MANIFEST ${FROZEN_MANIFEST})
target_include_directories(${MICROPY_TARGET} PRIVATE
${TOP_DIR}/${CMSIS_DIR}/include/
${TOP_DIR}/${CMSIS_DIR}/include/rpi/
${MICROPY_DIR}/py/
${MICROPY_DIR}/lib/oofatfs/
${MICROPY_DIR}/lib/tinyusb/src/
${TOP_DIR}/${OMV_DIR}/
${TOP_DIR}/${OMV_DIR}/alloc/
${TOP_DIR}/${OMV_DIR}/common/
${TOP_DIR}/${OMV_DIR}/imlib/
${TOP_DIR}/${OMV_DIR}/modules/
${TOP_DIR}/${OMV_DIR}/sensors/
${TOP_DIR}/${OMV_DIR}/ports/${PORT}/
${TOP_DIR}/${OMV_DIR}/ports/${PORT}/modules/
${TOP_DIR}/${LEPTON_DIR}/include/
${TOP_DIR}/${LSM6DS3_DIR}/include/
${TOP_DIR}/${WINC1500_DIR}/include/
${TOP_DIR}/${MLX90621_DIR}/include/
${TOP_DIR}/${MLX90640_DIR}/include/
${TOP_DIR}/${MLX90641_DIR}/include/
${OMV_BOARD_CONFIG_DIR}
)
target_sources(${MICROPY_TARGET} PRIVATE
${TOP_DIR}/${OMV_DIR}/alloc/xalloc.c
${TOP_DIR}/${OMV_DIR}/alloc/fb_alloc.c
${TOP_DIR}/${OMV_DIR}/alloc/umm_malloc.c
${TOP_DIR}/${OMV_DIR}/alloc/dma_alloc.c
${TOP_DIR}/${OMV_DIR}/alloc/unaligned_memcpy.c
${TOP_DIR}/${OMV_DIR}/common/array.c
${TOP_DIR}/${OMV_DIR}/common/ff_wrapper.c
${TOP_DIR}/${OMV_DIR}/common/ini.c
${TOP_DIR}/${OMV_DIR}/common/ringbuf.c
${TOP_DIR}/${OMV_DIR}/common/trace.c
${TOP_DIR}/${OMV_DIR}/common/mutex.c
${TOP_DIR}/${OMV_DIR}/common/usbdbg.c
${TOP_DIR}/${OMV_DIR}/sensors/ov2640.c
${TOP_DIR}/${OMV_DIR}/sensors/ov5640.c
${TOP_DIR}/${OMV_DIR}/sensors/ov7670.c
${TOP_DIR}/${OMV_DIR}/sensors/ov7690.c
${TOP_DIR}/${OMV_DIR}/sensors/ov7725.c
${TOP_DIR}/${OMV_DIR}/sensors/ov9650.c
${TOP_DIR}/${OMV_DIR}/sensors/mt9v034.c
${TOP_DIR}/${OMV_DIR}/sensors/mt9m114.c
${TOP_DIR}/${OMV_DIR}/sensors/lepton.c
${TOP_DIR}/${OMV_DIR}/sensors/hm01b0.c
${TOP_DIR}/${OMV_DIR}/sensors/gc2145.c
${TOP_DIR}/${OMV_DIR}/modules/py_clock.c
${TOP_DIR}/${OMV_DIR}/modules/py_gif.c
${TOP_DIR}/${OMV_DIR}/modules/py_helper.c
${TOP_DIR}/${OMV_DIR}/modules/py_image.c
${TOP_DIR}/${OMV_DIR}/modules/py_imageio.c
${TOP_DIR}/${OMV_DIR}/modules/py_mjpeg.c
${TOP_DIR}/${OMV_DIR}/modules/py_omv.c
${TOP_DIR}/${OMV_DIR}/modules/py_sensor.c
${TOP_DIR}/${OMV_DIR}/modules/py_tf.c
${TOP_DIR}/${OMV_DIR}/modules/py_fir.c
${TOP_DIR}/${OMV_DIR}/imlib/agast.c
${TOP_DIR}/${OMV_DIR}/imlib/apriltag.c
${TOP_DIR}/${OMV_DIR}/imlib/bayer.c
${TOP_DIR}/${OMV_DIR}/imlib/binary.c
${TOP_DIR}/${OMV_DIR}/imlib/blob.c
${TOP_DIR}/${OMV_DIR}/imlib/bmp.c
${TOP_DIR}/${OMV_DIR}/imlib/clahe.c
${TOP_DIR}/${OMV_DIR}/imlib/collections.c
${TOP_DIR}/${OMV_DIR}/imlib/dmtx.c
${TOP_DIR}/${OMV_DIR}/imlib/draw.c
${TOP_DIR}/${OMV_DIR}/imlib/edge.c
${TOP_DIR}/${OMV_DIR}/imlib/eye.c
${TOP_DIR}/${OMV_DIR}/imlib/fast.c
${TOP_DIR}/${OMV_DIR}/imlib/fft.c
${TOP_DIR}/${OMV_DIR}/imlib/filter.c
${TOP_DIR}/${OMV_DIR}/imlib/fmath.c
${TOP_DIR}/${OMV_DIR}/imlib/font.c
${TOP_DIR}/${OMV_DIR}/imlib/framebuffer.c
${TOP_DIR}/${OMV_DIR}/imlib/fsort.c
${TOP_DIR}/${OMV_DIR}/imlib/gif.c
${TOP_DIR}/${OMV_DIR}/imlib/haar.c
${TOP_DIR}/${OMV_DIR}/imlib/hog.c
${TOP_DIR}/${OMV_DIR}/imlib/hough.c
${TOP_DIR}/${OMV_DIR}/imlib/imlib.c
${TOP_DIR}/${OMV_DIR}/imlib/integral.c
${TOP_DIR}/${OMV_DIR}/imlib/integral_mw.c
${TOP_DIR}/${OMV_DIR}/imlib/jpeg.c
${TOP_DIR}/${OMV_DIR}/imlib/kmeans.c
${TOP_DIR}/${OMV_DIR}/imlib/lab_tab.c
${TOP_DIR}/${OMV_DIR}/imlib/lbp.c
${TOP_DIR}/${OMV_DIR}/imlib/line.c
${TOP_DIR}/${OMV_DIR}/imlib/lsd.c
${TOP_DIR}/${OMV_DIR}/imlib/mathop.c
${TOP_DIR}/${OMV_DIR}/imlib/mjpeg.c
${TOP_DIR}/${OMV_DIR}/imlib/orb.c
${TOP_DIR}/${OMV_DIR}/imlib/phasecorrelation.c
${TOP_DIR}/${OMV_DIR}/imlib/point.c
${TOP_DIR}/${OMV_DIR}/imlib/pool.c
${TOP_DIR}/${OMV_DIR}/imlib/ppm.c
${TOP_DIR}/${OMV_DIR}/imlib/qrcode.c
${TOP_DIR}/${OMV_DIR}/imlib/qsort.c
${TOP_DIR}/${OMV_DIR}/imlib/rainbow_tab.c
${TOP_DIR}/${OMV_DIR}/imlib/rectangle.c
${TOP_DIR}/${OMV_DIR}/imlib/selective_search.c
${TOP_DIR}/${OMV_DIR}/imlib/sincos_tab.c
${TOP_DIR}/${OMV_DIR}/imlib/stats.c
${TOP_DIR}/${OMV_DIR}/imlib/template.c
${TOP_DIR}/${OMV_DIR}/imlib/xyz_tab.c
${TOP_DIR}/${OMV_DIR}/imlib/zbar.c
${TOP_DIR}/${OMV_DIR}/ports/${PORT}/main.c
${TOP_DIR}/${OMV_DIR}/ports/${PORT}/cambus.c
${TOP_DIR}/${OMV_DIR}/ports/${PORT}/sensor.c
)
if(MICROPY_PY_SENSOR)
target_compile_definitions(${MICROPY_TARGET} PRIVATE
MICROPY_PY_SENSOR=1
)
endif()
if(MICROPY_PY_AUDIO)
target_include_directories(${MICROPY_TARGET} PRIVATE
${OPENPDM_DIR}/
)
set(AUDIO_SOURCES
${OPENPDM_DIR}/OpenPDMFilter.c
${TOP_DIR}/${OMV_DIR}/ports/${PORT}/modules/py_audio.c
)
target_sources(${MICROPY_TARGET} PRIVATE ${AUDIO_SOURCES})
target_compile_definitions(${MICROPY_TARGET} PRIVATE
MICROPY_PY_AUDIO=1
#USE_LUT
)
pico_generate_pio_header(${MICROPY_TARGET}
${TOP_DIR}/${OMV_DIR}/ports/${PORT}/pdm.pio
)
endif()
if(MICROPY_PY_ULAB)
set(MICROPY_ULAB_DIR "${MICROPY_DIR}/extmod/ulab")
target_include_directories(${MICROPY_TARGET} PRIVATE
${MICROPY_ULAB_DIR}/code/
)
set(ULAB_SOURCES
${MICROPY_ULAB_DIR}/code/scipy/optimize/optimize.c
${MICROPY_ULAB_DIR}/code/scipy/signal/signal.c
${MICROPY_ULAB_DIR}/code/scipy/special/special.c
${MICROPY_ULAB_DIR}/code/ndarray_operators.c
${MICROPY_ULAB_DIR}/code/ulab_tools.c
${MICROPY_ULAB_DIR}/code/ndarray.c
${MICROPY_ULAB_DIR}/code/numpy/approx/approx.c
${MICROPY_ULAB_DIR}/code/numpy/compare/compare.c
${MICROPY_ULAB_DIR}/code/ulab_create.c
${MICROPY_ULAB_DIR}/code/numpy/fft/fft.c
${MICROPY_ULAB_DIR}/code/numpy/fft/fft_tools.c
${MICROPY_ULAB_DIR}/code/numpy/filter/filter.c
${MICROPY_ULAB_DIR}/code/numpy/linalg/linalg.c
${MICROPY_ULAB_DIR}/code/numpy/linalg/linalg_tools.c
${MICROPY_ULAB_DIR}/code/numpy/numerical/numerical.c
${MICROPY_ULAB_DIR}/code/numpy/poly/poly.c
${MICROPY_ULAB_DIR}/code/numpy/vector/vector.c
${MICROPY_ULAB_DIR}/code/user/user.c
${MICROPY_ULAB_DIR}/code/numpy/numpy.c
${MICROPY_ULAB_DIR}/code/scipy/scipy.c
${MICROPY_ULAB_DIR}/code/ulab.c
)
target_sources(${MICROPY_TARGET} PRIVATE ${ULAB_SOURCES})
list(APPEND MICROPY_SOURCE_QSTR ${ULAB_SOURCES})
target_compile_definitions(${MICROPY_TARGET} PRIVATE
MICROPY_PY_ULAB=1
ULAB_CONFIG_FILE="${OMV_BOARD_CONFIG_DIR}/ulab_config.h"
)
endif()

View File

@ -0,0 +1,23 @@
/*
* This file is part of the OpenMV project.
*
* Copyright (c) 2013-2021 Ibrahim Abdelkader <iabdalkader@openmv.io>
* Copyright (c) 2013-2021 Kwabena W. Agyeman <kwagyeman@openmv.io>
*
* This work is licensed under the MIT license, see the file LICENSE for details.
*
* OpenMV RP2 port abstraction layer.
*/
#ifndef __OMV_PORTCONFIG_H__
#define __OMV_PORTCONFIG_H__
#include "pico/stdlib.h"
#include "hardware/i2c.h"
// omv_gpio_t definition
typedef uint32_t omv_gpio_t;
// cambus/i2c definition
typedef i2c_inst_t *omv_cambus_t;
#endif // __OMV_PORTCONFIG_H__

View File

@ -0,0 +1,31 @@
# This file is part of the OpenMV project.
#
# Copyright (c) 2013-2019 Ibrahim Abdelkader <iabdalkader@openmv.io>
# Copyright (c) 2013-2019 Kwabena W. Agyeman <kwagyeman@openmv.io>
#
# This work is licensed under the MIT license, see the file LICENSE for details.
#
# RP2 Makefile.
# This just invokes make in MicroPython RP2 port with OpenMV's cmake arg.
export PORT
export TARGET
export TOP_DIR
MICROPY_ARGS += BOARD=$(TARGET) BUILD=$(FW_DIR) OMV_CMAKE=$(TOP_DIR)/$(OMV_DIR)/ports/$(PORT)/omv_portconfig.cmake
###################################################
all: $(OPENMV)
$(BUILD):
$(MKDIR) -p $@
$(FIRMWARE): | $(BUILD)
$(MAKE) -C $(MICROPY_DIR)/ports/$(PORT) $(MICROPY_ARGS)
# This target generates the firmware image.
$(OPENMV): $(FIRMWARE)
$(SIZE) $(FW_DIR)/$(FIRMWARE).elf
size:
$(SIZE) --format=SysV $(FW_DIR)/$(FIRMWARE).elf

56
src/omv/ports/rp2/pdm.pio Normal file
View File

@ -0,0 +1,56 @@
; Copyright (c) 2019 Arduino LLC. All right reserved.
;
; This library is free software; you can redistribute it and/or
; modify it under the terms of the GNU Lesser General Public
; License as published by the Free Software Foundation; either
; version 2.1 of the License, or (at your option) any later version.
;
; This library is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
; See the GNU Lesser General Public License for more details.
;
; You should have received a copy of the GNU Lesser General Public
; License along with this library; if not, write to the Free Software
; Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
.program pdm_pio
.side_set 1
.wrap_target
; prova a cambiare edge
;sample on falling edge
push iffull noblock side 1
;nop side 1
;nop side 0
in pins, 1 side 0
;nop side 0
.wrap
% c-sdk {
#include "hardware/gpio.h"
static inline void pdm_pio_program_init(PIO pio, uint sm, uint offset, uint clkPin, uint dataPin, float clkDiv) {
pio_sm_config c = pdm_pio_program_get_default_config(offset);
sm_config_set_sideset(&c, 1, false, false);
//sm_config_set_in_shift(&c, false, true, 8);
sm_config_set_in_shift(&c, false, false, 8);
sm_config_set_in_pins(&c, dataPin);
sm_config_set_sideset_pins(&c, clkPin);
sm_config_set_clkdiv(&c, clkDiv);
pio_sm_set_consecutive_pindirs(pio, sm, dataPin, 1, false);
pio_sm_set_consecutive_pindirs(pio, sm, clkPin, 1, true);
pio_sm_set_pins_with_mask(pio, sm, 0, (1u << clkPin) );
//pio_gpio_init(pio, dataPin);
pio_gpio_init(pio, clkPin);
pio_sm_init(pio, sm, offset, &c);
pio_sm_set_enabled(pio, sm, true);
}
%}

265
src/omv/ports/rp2/rp2.ld.S Normal file
View File

@ -0,0 +1,265 @@
/*
* This file is part of the OpenMV project.
*
* Copyright (c) 2013-2021 Ibrahim Abdelkader <iabdalkader@openmv.io>
* Copyright (c) 2013-2021 Kwabena W. Agyeman <kwagyeman@openmv.io>
*
* This work is licensed under the MIT license, see the file LICENSE for details.
*
* Linker script for RP2040 Devices.
*/
/* Entry Point */
ENTRY(_entry_point)
#include "omv_boardconfig.h"
MEMORY
{
FLASH(rx) : ORIGIN = 0x10000000, LENGTH = 2048k
RAM(rwx) : ORIGIN = 0x20000000, LENGTH = 256k
SCRATCH_X(rwx) : ORIGIN = 0x20040000, LENGTH = 4k
SCRATCH_Y(rwx) : ORIGIN = 0x20041000, LENGTH = 4k
}
SECTIONS
{
/* Second stage bootloader is prepended to the image. It must be 256 bytes big
and checksummed. It is usually built by the boot_stage2 target
in the Raspberry Pi Pico SDK
*/
.flash_begin : {
__flash_binary_start = .;
} > FLASH
.boot2 : {
__boot2_start__ = .;
KEEP (*(.boot2))
__boot2_end__ = .;
} > FLASH
ASSERT(__boot2_end__ - __boot2_start__ == 256,
"ERROR: Pico second stage bootloader must be 256 bytes in size")
/* The second stage will always enter the image at the start of .text.
The debugger will use the ELF entry point, which is the _entry_point
symbol if present, otherwise defaults to start of .text.
This can be used to transfer control back to the bootrom on debugger
launches only, to perform proper flash setup.
*/
.text : {
__logical_binary_start = .;
KEEP (*(.vectors))
KEEP (*(.binary_info_header))
__binary_info_header_end = .;
KEEP (*(.reset))
/* TODO revisit this now memset/memcpy/float in ROM */
/* bit of a hack right now to exclude all floating point and time critical (e.g. memset, memcpy) code from
* FLASH ... we will include any thing excluded here in .data below by default */
*(.init)
/* Change for MicroPython... excluse gc.c, parse.c, vm.c from flash */
*(EXCLUDE_FILE(*libgcc.a: *libc.a: *lib_a-mem*.o *libm.a: *gc.c.obj *vm.c.obj *parse.c.obj) .text*)
*(.fini)
/* Pull all c'tors into .text */
*crtbegin.o(.ctors)
*crtbegin?.o(.ctors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
*(SORT(.ctors.*))
*(.ctors)
/* Followed by destructors */
*crtbegin.o(.dtors)
*crtbegin?.o(.dtors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
*(SORT(.dtors.*))
*(.dtors)
*(.eh_frame*)
. = ALIGN(4);
} > FLASH
.rodata : {
*(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a:) .rodata*)
. = ALIGN(4);
*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.flashdata*)))
. = ALIGN(4);
} > FLASH
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > FLASH
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > FLASH
__exidx_end = .;
/* Machine inspectable binary information */
. = ALIGN(4);
__binary_info_start = .;
.binary_info :
{
KEEP(*(.binary_info.keep.*))
*(.binary_info.*)
} > FLASH
__binary_info_end = .;
. = ALIGN(4);
/* End of .text-like segments */
__etext = .;
.ram_vector_table (COPY): {
*(.ram_vector_table)
} > RAM
.data : {
__data_start__ = .;
*(vtable)
*(.time_critical*)
/* remaining .text and .rodata; i.e. stuff we exclude above because we want it in RAM */
*(.text*)
. = ALIGN(4);
*(.rodata*)
. = ALIGN(4);
_ram_start = .;
*(.data*)
. = ALIGN(4);
*(.after_data.*)
. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__mutex_array_start = .);
KEEP(*(SORT(.mutex_array.*)))
KEEP(*(.mutex_array))
PROVIDE_HIDDEN (__mutex_array_end = .);
. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP(*(SORT(.preinit_array.*)))
KEEP(*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
/* init data */
PROVIDE_HIDDEN (__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
/* finit data */
PROVIDE_HIDDEN (__fini_array_start = .);
*(SORT(.fini_array.*))
*(.fini_array)
PROVIDE_HIDDEN (__fini_array_end = .);
*(.jcr)
. = ALIGN(4);
/* All data end */
__data_end__ = .;
} > RAM AT> FLASH
.uninitialized_data (COPY): {
. = ALIGN(4);
*(.uninitialized_data*)
} > RAM
.bss : {
. = ALIGN(4);
__bss_start__ = .;
*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.bss*)))
*(COMMON)
. = ALIGN(4);
__bss_end__ = .;
_ebss = .;
} > RAM
/* Main framebuffer memory */
.fb_memory (NOLOAD) :
{
. = ALIGN(4);
_fb_base = .;
. = . + OMV_FB_SIZE + OMV_FB_ALLOC_SIZE;
. = ALIGN(4);
_fballoc = .;
. = ALIGN(4);
#if !defined(OMV_JPEG_MEMORY)
_jpeg_buf = .; // IDE JPEG buffer
. = . + OMV_JPEG_BUF_SIZE;
. = ALIGN(4);
#endif
} >OMV_FB_MEMORY
.heap (COPY):
{
__end__ = .;
end = __end__;
*(.heap*)
__HeapLimit = .;
} > RAM
/* Start and end symbols must be word-aligned */
.scratch_x : {
__scratch_x_start__ = .;
*(.scratch_x.*)
. = ALIGN(4);
__scratch_x_end__ = .;
} > SCRATCH_X AT > FLASH
__scratch_x_source__ = LOADADDR(.scratch_x);
.scratch_y : {
__scratch_y_start__ = .;
*(.scratch_y.*)
. = ALIGN(4);
__scratch_y_end__ = .;
} > SCRATCH_Y AT > FLASH
__scratch_y_source__ = LOADADDR(.scratch_y);
/* .stack*_dummy section doesn't contains any symbols. It is only
* used for linker to calculate size of stack sections, and assign
* values to stack symbols later
*
* stack1 section may be empty/missing if platform_launch_core1 is not used */
/* by default we put core 0 stack at the end of scratch Y, so that if core 1
* stack is not used then all of SCRATCH_X is free.
*/
.stack1_dummy (COPY):
{
*(.stack1*)
} > SCRATCH_X
.stack_dummy (COPY):
{
*(.stack*)
} > SCRATCH_Y
.flash_end : {
__flash_binary_end = .;
} > FLASH
/* stack limit is poorly named, but historically is maximum heap ptr */
__StackLimit = ORIGIN(RAM) + LENGTH(RAM);
__StackOneTop = ORIGIN(SCRATCH_X) + LENGTH(SCRATCH_X);
__StackTop = ORIGIN(SCRATCH_Y) + LENGTH(SCRATCH_Y);
__StackOneBottom = __StackOneTop - SIZEOF(.stack1_dummy);
__StackBottom = __StackTop - SIZEOF(.stack_dummy);
PROVIDE(__stack = __StackTop);
/* Check if data + heap + stack exceeds RAM limit */
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed")
ASSERT( __binary_info_header_end - __logical_binary_start <= 256, "Binary info must be in first 256 bytes of the binary")
/* todo assert on extra code */
}

1077
src/omv/ports/rp2/sensor.c Normal file

File diff suppressed because it is too large Load Diff