Add M7 support

This commit is contained in:
iabdalkader 2016-08-12 22:43:50 +02:00
parent 21c693f968
commit 1cbcb7e434
40 changed files with 726 additions and 445 deletions

View File

@ -33,7 +33,6 @@ FIRMWARE = firmware
TOP_DIR=$(shell pwd)
BUILD=$(TOP_DIR)/build
CMSIS_DIR=cmsis
STHAL_DIR=sthal
STUSB_DIR=stusb
FATFS_DIR=fatfs
MICROPY_DIR=micropython
@ -56,16 +55,11 @@ CFLAGS += -O2 -ggdb3 -DNDEBUG
endif
# Compiler Flags
CFLAGS += -std=gnu99 -Wall -Werror -mlittle-endian -mthumb -nostartfiles -mabi=aapcs-linux -fdata-sections -ffunction-sections
CFLAGS += -fsingle-precision-constant -Wdouble-promotion -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard
CFLAGS += -DARM_MATH_CM4 -D__FPU_PRESENT=1 -D__FPU_USED=1 -DUSE_USB_FS -DUSE_DEVICE_MODE -DUSE_USB_OTG_ID=0 -DHSE_VALUE=12000000\
-D$(TARGET) -DSTM32_HAL_H='<stm32f4xx_hal.h>'
ifeq ($(TARGET), OPENMV1)
CFLAGS += -DSTM32F407xx
else
CFLAGS += -DSTM32F427xx
endif
include $(TOP_DIR)/$(OMV_DIR)/boards/$(TARGET)/omv_boardconfig.mk
CFLAGS += -std=gnu99 -Wall -Werror -Warray-bounds -mthumb -nostartfiles -mabi=aapcs-linux -fdata-sections -ffunction-sections
CFLAGS += -D$(MCU) -D$(ARM_MATH) -fsingle-precision-constant -Wdouble-promotion -mcpu=$(CPU) -mtune=$(CPU) -mfpu=$(FPU) -mfloat-abi=hard
CFLAGS += -D__FPU_PRESENT=1 -D__VFP_FP__ -DUSE_USB_FS -DUSE_DEVICE_MODE -DUSE_USB_OTG_ID=0 -DHSE_VALUE=12000000 -D$(TARGET)\
-DSTM32_HAL_H=$(HAL_INC) -DVECT_TAB_OFFSET=$(VECT_TAB_OFFSET) -DMAIN_APP_ADDR=$(MAIN_APP_ADDR)
CFLAGS += -I. -Iinclude
CFLAGS += -I$(TOP_DIR)/$(BOOT_DIR)/include/
@ -90,12 +84,12 @@ CFLAGS += -I$(TOP_DIR)/$(OMV_DIR)/boards/$(TARGET)/
CFLAGS += -I$(TOP_DIR)/$(WINC1500_DIR)/include/
# Linker Flags
LDFLAGS = -mcpu=cortex-m4 -mabi=aapcs-linux -mthumb -mlittle-endian -mfloat-abi=hard\
-mfpu=fpv4-sp-d16 -nostdlib -Wl,--gc-sections -Wl,-T$(BUILD)/stm32f4xx.lds
LDFLAGS = -mcpu=$(CPU) -mabi=aapcs-linux -mthumb -mfpu=$(FPU) -mfloat-abi=hard\
-nostdlib -Wl,--gc-sections -Wl,-T$(BUILD)/stm32fxxx.lds
# Linker Flags
BOOT_LDFLAGS = -mcpu=cortex-m4 -mabi=aapcs-linux -mthumb -mlittle-endian -mfloat-abi=hard\
-mfpu=fpv4-sp-d16 -nostdlib -Wl,--gc-sections -Wl,-T$(BUILD)/$(BOOT_DIR)/stm32f4xx.lds
BOOT_LDFLAGS = -mcpu=$(CPU) -mabi=aapcs-linux -mthumb -mfpu=$(FPU) -mfloat-abi=hard\
-nostdlib -Wl,--gc-sections -Wl,-T$(BUILD)/$(BOOT_DIR)/stm32fxxx.lds
#------------- Libraries ----------------#
#FIRM_OBJ += $(wildcard $(BUILD)/$(CMSIS_DIR)/src/st/*.o)
@ -126,7 +120,7 @@ FIRM_OBJ += $(addprefix $(BUILD)/$(OMV_DIR)/, \
ov2640.o \
ov7725.o \
sensor.o \
stm32f4xx_hal_msp.o \
stm32fxxx_hal_msp.o \
soft_i2c.o \
mutex.o \
)
@ -182,17 +176,11 @@ FIRM_OBJ += $(addprefix $(BUILD)/$(OMV_DIR)/py/, \
py_tof.o \
)
ifeq ($(TARGET), OPENMV1)
FIRM_OBJ += $(addprefix $(BUILD)/$(CMSIS_DIR)/src/st/,\
system_stm32f4xx.o \
startup_stm32f407xx.o \
$(STARTUP).o \
system_stm32fxxx.o \
)
else
FIRM_OBJ += $(addprefix $(BUILD)/$(CMSIS_DIR)/src/st/,\
system_stm32f4xx.o \
startup_stm32f427xx.o \
)
endif
#------------- MicroPy Core -------------------#
FIRM_OBJ += $(wildcard $(BUILD)/$(MICROPY_DIR)/py/*.o)
@ -318,17 +306,10 @@ FIRM_OBJ += $(addprefix $(BUILD)/$(MICROPY_DIR)/extmod/,\
BOOT_OBJ += $(wildcard $(BUILD)/$(BOOT_DIR)/src/*.o)
BOOT_OBJ += $(wildcard $(BUILD)/$(STHAL_DIR)/src/*.o)
ifeq ($(TARGET), OPENMV1)
BOOT_OBJ += $(addprefix $(BUILD)/$(CMSIS_DIR)/src/st/,\
system_stm32f4xx.o \
startup_stm32f407xx.o \
$(STARTUP).o \
system_stm32fxxx.o \
)
else
BOOT_OBJ += $(addprefix $(BUILD)/$(CMSIS_DIR)/src/st/,\
system_stm32f4xx.o \
startup_stm32f427xx.o \
)
endif
BOOT_OBJ += $(addprefix $(BUILD)/$(MICROPY_DIR)/usbdev/, \
core/src/usbd_core.o \
@ -353,6 +334,7 @@ export LDFLAGS
export TOP_DIR
export BUILD
export TARGET
export STARTUP
###################################################
all: $(OPENMV)
@ -372,31 +354,31 @@ FIRMWARE_OBJS:
# This target generates the main/app firmware image located at 0x08010000
$(FIRMWARE): FIRMWARE_OBJS
$(CPP) -P -E -D$(TARGET) $(OMV_DIR)/stm32f4xx.ld.S > $(BUILD)/stm32f4xx.lds
$(CPP) -P -E -D$(TARGET) $(OMV_DIR)/stm32fxxx.ld.S > $(BUILD)/stm32fxxx.lds
$(CC) $(LDFLAGS) $(FIRM_OBJ) -o $(FW_DIR)/$(FIRMWARE).elf
$(OBJCOPY) -Obinary $(FW_DIR)/$(FIRMWARE).elf $(FW_DIR)/$(FIRMWARE).bin
$(PYTHON) $(MKDFU) -b 0x08010000:$(FW_DIR)/$(FIRMWARE).bin $(FW_DIR)/$(FIRMWARE).dfu
$(PYTHON) $(MKDFU) -b $(MAIN_APP_ADDR):$(FW_DIR)/$(FIRMWARE).bin $(FW_DIR)/$(FIRMWARE).dfu
# This target generates the bootloader. The bootloader binary is generated twice,
# once without padding, to generate the bootloader.dfu file, and once with padding
# up to the main fw image (0x08010000), to generate a contiguous firmware.bin image.
# up to the main fw image (MAIN_APP_ADDR), to generate a contiguous firmware.bin image.
$(BOOTLOADER): FIRMWARE_OBJS BOOTLOADER_OBJS
$(CPP) -P -E -D$(TARGET) $(BOOT_DIR)/stm32f4xx.ld.S > $(BUILD)/$(BOOT_DIR)/stm32f4xx.lds
$(CPP) -P -E -D$(TARGET) $(BOOT_DIR)/stm32fxxx.ld.S > $(BUILD)/$(BOOT_DIR)/stm32fxxx.lds
$(CC) $(BOOT_LDFLAGS) $(BOOT_OBJ) -o $(FW_DIR)/$(BOOTLOADER).elf
$(OBJCOPY) -Obinary $(FW_DIR)/$(BOOTLOADER).elf $(FW_DIR)/$(BOOTLOADER).bin
$(PYTHON) $(MKDFU) -b 0x08000000:$(FW_DIR)/$(BOOTLOADER).bin $(FW_DIR)/$(BOOTLOADER).dfu
$(OBJCOPY) -Obinary --pad-to=0x08010000 $(FW_DIR)/$(BOOTLOADER).elf $(FW_DIR)/$(BOOTLOADER).bin
$(OBJCOPY) -Obinary --pad-to=$(MAIN_APP_ADDR) $(FW_DIR)/$(BOOTLOADER).elf $(FW_DIR)/$(BOOTLOADER).bin
# This target generates a combined bootloader+main firmware image.
$(OPENMV): $(BOOTLOADER) $(FIRMWARE) | $(BUILD)
$(CAT) $(FW_DIR)/$(BOOTLOADER).bin $(FW_DIR)/$(FIRMWARE).bin > $(FW_DIR)/$(OPENMV).bin
$(PYTHON) $(MKDFU) -b 0x08000000:$(FW_DIR)/$(BOOTLOADER).bin -b 0x08010000:$(FW_DIR)/$(FIRMWARE).bin $(FW_DIR)/$(OPENMV).dfu
$(PYTHON) $(MKDFU) -b 0x08000000:$(FW_DIR)/$(BOOTLOADER).bin -b $(MAIN_APP_ADDR):$(FW_DIR)/$(FIRMWARE).bin $(FW_DIR)/$(OPENMV).dfu
$(SIZE) $(FW_DIR)/$(BOOTLOADER).elf
$(SIZE) $(FW_DIR)/$(FIRMWARE).elf
size:
$(SIZE) $(FW_DIR)/$(BOOTLOADER).elf
$(SIZE) $(FW_DIR)/$(FIRMWARE).elf
$(SIZE) --format=SysV $(FW_DIR)/$(BOOTLOADER).elf
$(SIZE) --format=SysV $(FW_DIR)/$(FIRMWARE).elf
clean:
$(RM) -fr $(BUILD)

View File

@ -1,11 +1,7 @@
# Sources
ifeq ($(TARGET), OPENMV1)
SRC_S = src/st/startup_stm32f407xx.s
else
SRC_S = src/st/startup_stm32f427xx.s
endif
SRC_S = src/st/$(STARTUP).s
SRC_C = src/st/system_stm32fxxx.c
SRC_C = src/st/system_stm32f4xx.c
SRC_C += $(wildcard src/dsp/CommonTables/*.c)
SRC_C += $(wildcard src/dsp/FastMathFunctions/*.c)
SRC_C += $(wildcard src/dsp/MatrixFunctions/*.c)

View File

@ -64,6 +64,7 @@
*/
#include STM32_HAL_H
#include "omv_boardconfig.h"
/**
* @}
@ -99,8 +100,10 @@
/*!< Uncomment the following line if you need to relocate your vector Table in
Internal SRAM. */
/* #define VECT_TAB_SRAM */
#define VECT_TAB_OFFSET 0x20000 /*!< Vector Table base offset field.
This value must be a multiple of 0x200. */
// Defined in board config files
//#define VECT_TAB_OFFSET 0x10000 /*!< Vector Table base offset field.
// This value must be a multiple of 0x200. */
/******************************************************************************/
/**

View File

@ -11,7 +11,7 @@ SRCS += $(addprefix , \
ov2640.c \
ov7725.c \
sensor.c \
stm32f4xx_hal_msp.c \
stm32fxxx_hal_msp.c \
soft_i2c.c \
mutex.c \
)

View File

@ -21,6 +21,10 @@
#define OMV_MAX_BLOB_FRAME FRAMESIZE_QCIF
#define OMV_MAX_BLOB_FRAME_STR "QCIF"
// Bootloader LED GPIO port/pin
#define OMV_BOOTLDR_LED_PIN (GPIO_PIN_2)
#define OMV_BOOTLDR_LED_PORT (GPIOC)
/* SCCB/I2C */
#define SCCB_I2C (I2C1)
#define SCCB_AF (GPIO_AF4_I2C1)

View File

@ -0,0 +1,9 @@
MCU=STM32F407xx
CPU=cortex-m4
FPU=fpv4-sp-d16
STHAL_DIR=sthal/f4
ARM_MATH=ARM_MATH_CM4
HAL_INC='<stm32f4xx_hal.h>'
STARTUP=startup_stm32f407xx
VECT_TAB_OFFSET=0x10000
MAIN_APP_ADDR=0x08010000

View File

@ -23,6 +23,13 @@
#define OMV_MAX_BLOB_FRAME FRAMESIZE_VGA
#define OMV_MAX_BLOB_FRAME_STR "VGA"
// Bootloader LED GPIO port/pin
#define OMV_BOOTLDR_LED_PIN (GPIO_PIN_2)
#define OMV_BOOTLDR_LED_PORT (GPIOC)
// JPEG buffer size, almost 8000 bytes + headers (~8KBs)
#define OMV_JPEG_BUF_SIZE (8000)
/* SCCB/I2C */
#define SCCB_I2C (I2C1)
#define SCCB_AF (GPIO_AF4_I2C1)
@ -40,6 +47,7 @@
#define DCMI_TIM_CHANNEL (TIM_CHANNEL_1)
#define DCMI_TIM_CLK_ENABLE() __TIM1_CLK_ENABLE()
#define DCMI_TIM_CLK_DISABLE() __TIM1_CLK_DISABLE()
#define DCMI_TIM_PCLK_FREQ() HAL_RCC_GetPCLK2Freq()
#define DCMI_RESET_PIN (GPIO_PIN_10)
#define DCMI_RESET_PORT (GPIOA)

View File

@ -0,0 +1,9 @@
MCU=STM32F427xx
CPU=cortex-m4
FPU=fpv4-sp-d16
STHAL_DIR=sthal/f4
ARM_MATH=ARM_MATH_CM4
HAL_INC='<stm32f4xx_hal.h>'
STARTUP=startup_stm32f427xx
VECT_TAB_OFFSET=0x10000
MAIN_APP_ADDR=0x08010000

View File

@ -0,0 +1,95 @@
/*
* This file is part of the OpenMV project.
* Copyright (c) 2013/2014 Ibrahim Abdelkader <i.abdalkader@gmail.com>
* 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__
// Sensor external clock frequency.
#define OMV_XCLK_FREQUENCY (12000000)
// Have built-in RGB->LAB table.
#define OMV_HAVE_LAB_TABLE
// Max integral image.
#define OMV_MAX_INT_FRAME FRAMESIZE_VGA
#define OMV_MAX_INT_FRAME_STR "VGA"
// Max GS/RGB565/YUV422/Binary image.
#define OMV_MAX_RAW_FRAME FRAMESIZE_VGA
#define OMV_MAX_RAW_FRAME_STR "VGA"
// Max raw (RGB565/YUV422) image for blob detection.
#define OMV_MAX_BLOB_FRAME FRAMESIZE_VGA
#define OMV_MAX_BLOB_FRAME_STR "VGA"
// Bootloader LED GPIO port/pin
#define OMV_BOOTLDR_LED_PIN (GPIO_PIN_5)
#define OMV_BOOTLDR_LED_PORT (GPIOK)
// JPEG buffer size
#define OMV_JPEG_BUF_SIZE (64*1024)
/* SCCB/I2C */
#define SCCB_I2C (I2C1)
#define SCCB_AF (GPIO_AF4_I2C1)
#define SCCB_CLK_ENABLE() __I2C1_CLK_ENABLE()
#define SCCB_CLK_DISABLE() __I2C1_CLK_DISABLE()
#define SCCB_PORT (GPIOB)
#define SCCB_SCL_PIN (GPIO_PIN_6)
#define SCCB_SDA_PIN (GPIO_PIN_7)
/* DCMI */
#define DCMI_TIM (TIM3)
#define DCMI_TIM_PIN (GPIO_PIN_4)
#define DCMI_TIM_PORT (GPIOB)
#define DCMI_TIM_AF (GPIO_AF2_TIM3)
#define DCMI_TIM_CHANNEL (TIM_CHANNEL_1)
#define DCMI_TIM_CLK_ENABLE() __TIM3_CLK_ENABLE()
#define DCMI_TIM_CLK_DISABLE() __TIM3_CLK_DISABLE()
#define DCMI_TIM_PCLK_FREQ() HAL_RCC_GetPCLK1Freq()
#define DCMI_RESET_PIN (GPIO_PIN_3)
#define DCMI_RESET_PORT (GPIOB)
#define DCMI_PWDN_PIN (GPIO_PIN_1)
#define DCMI_PWDN_PORT (GPIOE)
#define DCMI_FSIN_PIN (GPIO_PIN_5)
#define DCMI_FSIN_PORT (GPIOB)
#define DCMI_D0_PIN (GPIO_PIN_6)
#define DCMI_D1_PIN (GPIO_PIN_7)
#define DCMI_D2_PIN (GPIO_PIN_10)
#define DCMI_D3_PIN (GPIO_PIN_11)
#define DCMI_D4_PIN (GPIO_PIN_4)
#define DCMI_D5_PIN (GPIO_PIN_3)
#define DCMI_D6_PIN (GPIO_PIN_5)
#define DCMI_D7_PIN (GPIO_PIN_9)
#define DCMI_D0_PORT (GPIOC)
#define DCMI_D1_PORT (GPIOC)
#define DCMI_D2_PORT (GPIOG)
#define DCMI_D3_PORT (GPIOG)
#define DCMI_D4_PORT (GPIOE)
#define DCMI_D5_PORT (GPIOD)
#define DCMI_D6_PORT (GPIOE)
#define DCMI_D7_PORT (GPIOB)
#define DCMI_HSYNC_PIN (GPIO_PIN_4)
#define DCMI_VSYNC_PIN (GPIO_PIN_5)
#define DCMI_PXCLK_PIN (GPIO_PIN_6)
#define DCMI_HSYNC_PORT (GPIOA)
#define DCMI_VSYNC_PORT (GPIOI)
#define DCMI_PXCLK_PORT (GPIOA)
#define DCMI_RESET_LOW() HAL_GPIO_WritePin(DCMI_RESET_PORT, DCMI_RESET_PIN, GPIO_PIN_RESET)
#define DCMI_RESET_HIGH() HAL_GPIO_WritePin(DCMI_RESET_PORT, DCMI_RESET_PIN, GPIO_PIN_SET)
#define DCMI_PWDN_LOW() HAL_GPIO_WritePin(DCMI_PWDN_PORT, DCMI_PWDN_PIN, GPIO_PIN_RESET)
#define DCMI_PWDN_HIGH() HAL_GPIO_WritePin(DCMI_PWDN_PORT, DCMI_PWDN_PIN, GPIO_PIN_SET)
#define DCMI_FSIN_LOW() HAL_GPIO_WritePin(DCMI_FSIN_PORT, DCMI_FSIN_PIN, GPIO_PIN_RESET)
#define DCMI_FSIN_HIGH() HAL_GPIO_WritePin(DCMI_FSIN_PORT, DCMI_FSIN_PIN, GPIO_PIN_SET)
#endif //__OMV_BOARDCONFIG_H__

View File

@ -0,0 +1,9 @@
MCU=STM32F769xx
CPU=cortex-m7
FPU=fpv5-sp-d16
STHAL_DIR=sthal/f7
ARM_MATH=ARM_MATH_CM7
HAL_INC='<stm32f7xx_hal.h>'
STARTUP=startup_stm32f769xx
VECT_TAB_OFFSET=0x20000
MAIN_APP_ADDR=0x08020000

View File

@ -8,22 +8,39 @@
*/
#ifndef __FRAMEBUFFER_H__
#define __FRAMEBUFFER_H__
#include "mutex.h"
extern char _fb_base;
static struct framebuffer {
int w,h;
int bpp;
int ready;
int request;
uint8_t pixels[];
// Note all instances of fb point to the same memory address.
}*fb = (struct framebuffer *) &_fb_base;
}*__attribute__ ((__unused__)) fb = (struct framebuffer *) &_fb_base;
extern char _jpeg_buf;
static struct jpegbuffer {
int w,h;
int size;
int enabled;
int quality;
mutex_t lock;
uint8_t pixels[];
// Note all instances of jepg_fb point to the same memory address.
}*__attribute__ ((__unused__)) jpeg_fb = (struct jpegbuffer *) &_jpeg_buf;
// Use these macros to get a pointer to main or JPEG framebuffer.
#define MAIN_FB() (fb)
#define JPEG_FB() (jpeg_fb)
// Returns MAIN FB size
#define MAIN_FB_SIZE() (MAIN_FB()->w*MAIN_FB()->h*MAIN_FB()->bpp)
// The JPEG offset allows JPEG compression of the framebuffer without overwriting the pixels.
// The offset size may need to be adjusted depending on the quality, otherwise JPEG data may
// overwrite image pixels before they are compressed (see framebuffer.h)
#define FB_JPEG_OFFS_SIZE (1*1024)
// overwrite image pixels before they are compressed.
#define FB_JPEG_OFFS_SIZE (1024)
// Use this macro to get a pointer to the free SRAM area located after the framebuffer.
// If JPEG is enabled, this macro returns pixels + the JPEG image size (usually stored in bpp).
#define FB_PIXELS() ((fb->bpp > 2)? (fb->pixels+fb->bpp) : (fb->pixels+fb->w*fb->h*fb->bpp+FB_JPEG_OFFS_SIZE))
// TODO: FIX this, is main FB still used for JPEG ?
#define FB_PIXELS() ((MAIN_FB()->bpp > 2)? (MAIN_FB()->pixels+MAIN_FB()->bpp) : (MAIN_FB()->pixels+MAIN_FB_SIZE()))
#endif /* __FRAMEBUFFER_H__ */

View File

@ -11,16 +11,16 @@
*
*/
#include <arm_math.h>
#include <stdio.h>
#include <stm32f4xx_hal.h>
#include STM32_HAL_H
#include <arm_math.h>
#include "xalloc.h"
#include "fb_alloc.h"
#include "ff_wrapper.h"
#include "imlib.h"
#define TIME_JPEG (0)
#define FIX_0_382683433 ((int32_t) 98)
#define FIX_0_541196100 ((int32_t) 139)
#define FIX_0_707106781 ((int32_t) 181)
@ -504,6 +504,11 @@ static void jpeg_write_headers(jpeg_buf_t *jpeg_buf, int w, int h, int bpp, jpeg
jpeg_put_bytes(jpeg_buf, (uint8_t [3]){0x00, 0x3F, 0x0}, 3);
}
void jpeg_init0()
{
}
void jpeg_compress(image_t *src, image_t *dst, int quality)
{
int DCY=0, DCU=0, DCV=0;

View File

@ -9,7 +9,7 @@
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <stm32f4xx_hal.h>
#include STM32_HAL_H
#include "mpconfig.h"
#include "systick.h"
#include "pendsv.h"
@ -283,19 +283,18 @@ int main(void)
int sensor_init_ret = 0;
bool first_soft_reset = true;
// Stack limit should be less than real stack size, so we
// had chance to recover from limit hit.
// STM32F4xx HAL library initialization:
// - Set NVIC Group Priority to 4
// - Configure the Flash prefetch, instruction and Data caches
// - Configure the Systick to generate an interrupt each 1 msec
// Note: The bootloader enables the CCM/DTCM memory.
HAL_Init();
// Stack limit should be less than real stack size, so we have a chance
// to recover from limit hit. (Limit is measured in bytes.)
mp_stack_ctrl_init();
mp_stack_set_limit((char*)&_ram_end - (char*)&_heap_end - 1024);
/* STM32F4xx HAL library initialization:
- Configure the Flash prefetch, instruction and Data caches
- Configure the Systick to generate an interrupt each 1 msec
- Set NVIC Group Priority to 4
- Global MSP (MCU Support Package) initialization
*/
HAL_Init();
// basic sub-system init
led_init();
pendsv_init();

View File

@ -6,7 +6,7 @@
* Mutex.
*
*/
#include <stm32f4xx.h>
#include STM32_HAL_H
#include "mutex.h"
// This is a standard implementation of mutexs on ARM processors following the ARM guide.
@ -14,40 +14,58 @@
void mutex_init(mutex_t *mutex)
{
mutex_unlock(mutex);
__DMB();
mutex->tid = 0;
mutex->lock = 0;
}
void mutex_lock(mutex_t *mutex)
void mutex_lock(mutex_t *mutex, uint32_t tid)
{
volatile int locked = 0;
// Wait for mutex to be unlocked
do {
// Attempt exclusive read
while (__LDREXW(mutex) != 0);
while (__LDREXW(&mutex->lock) != 0);
// Attempt to lock mutex
locked = __STREXW(1, mutex);
locked = __STREXW(1, &mutex->lock);
// Set TID if mutex is locked
if (locked == 0) {
mutex->tid = tid;
}
} while (locked != 0);
__DMB();
}
int mutex_try_lock(mutex_t *mutex)
int mutex_try_lock(mutex_t *mutex, uint32_t tid)
{
volatile int locked = 1;
if (__LDREXW(mutex) != 0) {
return 0;
}
// If mutex is already locked by the current thread then
// release the Kraken err.. the mutex, else attempt to lock it.
if (mutex->tid == tid) {
mutex_unlock(mutex, tid);
} else if (__LDREXW(&mutex->lock) == 0) {
// Attempt to lock the mutex
locked = __STREXW(1, &mutex->lock);
__DMB();
// Attempt to lock mutex
locked = __STREXW(1, mutex);
__DMB();
// Set TID if mutex is locked
if (locked == 0) {
mutex->tid = tid;
}
}
return (locked == 0);
}
void mutex_unlock(mutex_t *mutex)
void mutex_unlock(mutex_t *mutex, uint32_t tid)
{
__DMB();
*mutex = 0;
if (mutex->tid == tid) {
__DMB();
mutex->tid = 0;
mutex->lock = 0;
}
}

View File

@ -9,9 +9,15 @@
#ifndef __MUTEX_H__
#define __MUTEX_H__
#include <stdint.h>
typedef volatile uint32_t mutex_t;
#define MUTEX_TID_IDE (1<<0)
#define MUTEX_TID_OMV (1<<1)
typedef volatile struct {
uint32_t tid;
uint32_t lock;
} mutex_t;
void mutex_init(mutex_t *mutex);
void mutex_lock(mutex_t *mutex);
int mutex_try_lock(mutex_t *mutex);
void mutex_unlock(mutex_t *mutex);
void mutex_lock(mutex_t *mutex, uint32_t tid);
int mutex_try_lock(mutex_t *mutex, uint32_t tid);
void mutex_unlock(mutex_t *mutex, uint32_t tid);
#endif /* __MUTEX_H__ */

View File

@ -9,7 +9,7 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "stm32f4xx_hal.h"
#include STM32_HAL_H
#include "sccb.h"
#include "ov2640.h"
#include "systick.h"

View File

@ -9,7 +9,7 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "stm32f4xx_hal.h"
#include STM32_HAL_H
#include "sccb.h"
#include "ov7725.h"
#include "systick.h"
@ -19,8 +19,8 @@ static const uint8_t default_regs[][2] = {
{COM3, COM3_SWAP_YUV},
{COM7, COM7_RES_VGA | COM7_FMT_RGB565 | COM7_FMT_RGB},
{COM4, 0xC1}, /* PLL */
{CLKRC, 0x00},
{COM4, 0x41}, /* PLL x4 */
{CLKRC, 0x40}, /* Bypass pre-scalar */
// VGA Window Size
{HSTART, 0x23},

View File

@ -9,7 +9,7 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "stm32f4xx_hal.h"
#include STM32_HAL_H
#include "sccb.h"
#include "ov9650.h"
#include "systick.h"

View File

@ -10,7 +10,6 @@
#define __MP_H__
#include <stdio.h>
#include <string.h>
#include <stm32f4xx_hal.h>
#include "mpconfig.h"
#include "misc.h"
#include "systick.h"

View File

@ -228,18 +228,17 @@ static mp_obj_t py_image_save(uint n_args, const mp_obj_t *args, mp_map_t *kw_ar
static mp_obj_t py_image_compress(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
{
image_t *arg_img = py_image_cobj(args[0]);
PY_ASSERT_FALSE_MSG(IM_IS_JPEG(arg_img),
"Operation not supported on JPEG");
PY_ASSERT_FALSE_MSG(IM_IS_JPEG(arg_img), "Operation not supported on JPEG");
int arg_q = py_helper_lookup_int(kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_quality), 50);
arg_q = IM_MIN(IM_MAX(arg_q, 1), 100);
// Check if this image is the one in the frame buffer...
if ((fb->pixels+FB_JPEG_OFFS_SIZE) == arg_img->pixels) {
if (fb->pixels == arg_img->pixels) {
// We do not allow shallow copies so this is okay...
image_t src = {.w=fb->w, .h=fb->h, .bpp=fb->bpp, .pixels=fb->pixels+FB_JPEG_OFFS_SIZE};
image_t dst = {.w=fb->w, .h=fb->h, .bpp=128*1024, .pixels=fb->pixels};
jpeg_compress(&src, &dst, arg_q);
image_t src = {.w=fb->w, .h=fb->h, .bpp=fb->bpp, .pixels=fb->pixels};
image_t dst = {.w=fb->w, .h=fb->h, .bpp=128*1024, .pixels=fb->pixels+FB_JPEG_OFFS_SIZE};
jpeg_compress(&src, &dst, arg_q, false);
fb->bpp = dst.bpp;
arg_img->bpp = dst.bpp;
arg_img->pixels = dst.pixels;
@ -251,7 +250,7 @@ static mp_obj_t py_image_compress(uint n_args, const mp_obj_t *args, mp_map_t *k
// When jpeg_compress needs more memory than in currently allocated it
// will try to realloc. MP will detect that the pointer is outside of
// the heap and return NULL which will cause an out of memory error.
jpeg_compress(arg_img, &out, arg_q);
jpeg_compress(arg_img, &out, arg_q, true);
if (out.bpp <= (arg_img->w * arg_img->h * arg_img->bpp)) {
memcpy(arg_img->pixels, out.pixels, out.bpp);
arg_img->bpp = out.bpp;
@ -272,8 +271,7 @@ static mp_obj_t py_image_compress(uint n_args, const mp_obj_t *args, mp_map_t *k
static mp_obj_t py_image_compressed(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
{
image_t *arg_img = py_image_cobj(args[0]);
PY_ASSERT_FALSE_MSG(IM_IS_JPEG(arg_img),
"Operation not supported on JPEG");
PY_ASSERT_FALSE_MSG(IM_IS_JPEG(arg_img), "Operation not supported on JPEG");
int arg_q = py_helper_lookup_int(kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_quality), 50);
arg_q = IM_MIN(IM_MAX(arg_q, 1), 100);
@ -288,7 +286,7 @@ static mp_obj_t py_image_compressed(uint n_args, const mp_obj_t *args, mp_map_t
// When jpeg_compress needs more memory than in currently allocated it
// will try to realloc. MP will detect that the pointer is outside of
// the heap and return NULL which will cause an out of memory error.
jpeg_compress(arg_img, &out, arg_q);
jpeg_compress(arg_img, &out, arg_q, false);
uint8_t *temp = xalloc(out.bpp);
memcpy(temp, out.pixels, out.bpp);
out.pixels = temp;
@ -1111,8 +1109,7 @@ static mp_obj_t py_image_mean_pool(mp_obj_t img_obj, mp_obj_t x_div_obj, mp_obj_
arg_img->w = out_img.w;
arg_img->h = out_img.h;
// Check if this image is the one in the frame buffer...
if (((fb->pixels+FB_JPEG_OFFS_SIZE) == arg_img->pixels)
|| (fb->pixels == arg_img->pixels)) {
if ((fb->pixels == arg_img->pixels) || (fb->pixels == arg_img->pixels)) {
fb->w = out_img.w;
fb->h = out_img.h;
}

View File

@ -16,6 +16,7 @@
#include "py_sensor.h"
#include "omv_boardconfig.h"
#include "py_helper.h"
#include "framebuffer.h"
extern sensor_t sensor;
@ -84,12 +85,20 @@ static mp_obj_t py_sensor_skip_frames(uint n_args, const mp_obj_t *args) {
return mp_const_none;
}
static mp_obj_t py_sensor_get_fb() {
mp_obj_t image = py_image(0, 0, 0, 0);
if (sensor_get_fb(py_image_cobj(image))) {
static mp_obj_t py_sensor_get_fb()
{
if (MAIN_FB()->bpp == 0) {
return mp_const_none;
}
return image;
image_t image = {
.w = MAIN_FB()->w,
.h = MAIN_FB()->h,
.bpp = MAIN_FB()->bpp,
.pixels = MAIN_FB()->pixels
};
return py_image_from_struct(&image);
}
static mp_obj_t py_sensor_get_id() {

View File

@ -9,10 +9,9 @@
#include <stdlib.h>
#include <string.h>
#include <stm32f4xx_hal.h>
#include <mp.h>
#include <math.h>
#include STM32_HAL_H
#include <float.h>
#include "fb_alloc.h"
#include "xalloc.h"
@ -104,9 +103,13 @@ static void i2c_init()
// I2C configuration
I2CHandle.Instance = I2C2;
I2CHandle.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
#if defined(STM32F769xx)
I2CHandle.Init.Timing = 0x20404768; // 10KHz
#else
I2CHandle.Init.ClockSpeed = 10000;
I2CHandle.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;
I2CHandle.Init.DutyCycle = I2C_DUTYCYCLE_2;
#endif
I2CHandle.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;
I2CHandle.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;
I2CHandle.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;
I2CHandle.Init.OwnAddress1 = 0xFE;

View File

@ -7,7 +7,7 @@
*
*/
#include <stdbool.h>
#include <stm32f4xx_hal.h>
#include STM32_HAL_H
#include <systick.h>
#include "omv_boardconfig.h"
#include "sccb.h"
@ -21,9 +21,13 @@ int SCCB_Init()
/* Configure I2C */
I2CHandle.Instance = SCCB_I2C;
I2CHandle.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
#if defined(STM32F769xx)
I2CHandle.Init.Timing = 0x20404768; // 10KHz
#else
I2CHandle.Init.ClockSpeed = SCCB_FREQ;
I2CHandle.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;
I2CHandle.Init.DutyCycle = I2C_DUTYCYCLE_2;
#endif
I2CHandle.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;
I2CHandle.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;
I2CHandle.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;
I2CHandle.Init.OwnAddress1 = 0xFE;

View File

@ -7,7 +7,7 @@
*
*/
#include <stdbool.h>
#include <stm32f4xx_hal.h>
#include STM32_HAL_H
#include <core_cmInstr.h>
#include "mp.h"

View File

@ -26,8 +26,7 @@
#include "mp.h"
#include <stdbool.h>
#include <stm32f4xx_hal.h>
#include "mdefs.h"
#include STM32_HAL_H
#include "ffconf.h"
#include "diskio.h"
#include "pincfg.h"

View File

@ -8,8 +8,6 @@
*/
#include <stdlib.h>
#include <string.h>
#include <stm32f4xx_hal.h>
#include "mp.h"
#include "irq.h"
#include "sccb.h"
@ -28,6 +26,9 @@
#define REG_MIDL 0x1D
#define MAX_XFER_SIZE (0xFFFC)
// 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*1)
sensor_t sensor;
TIM_HandleTypeDef TIMHandle;
@ -56,19 +57,19 @@ const int resolution[][2] = {
static int extclk_config(int frequency)
{
/* TCLK (PCLK2 * 2) */
int tclk = HAL_RCC_GetPCLK2Freq() * 2;
// Doubles PCLK
//__HAL_RCC_TIMCLKPRESCALER(RCC_TIMPRES_ACTIVATED);
/* SYSCLK/TCLK = No prescaler */
int prescaler = (uint16_t) (HAL_RCC_GetSysClockFreq()/ tclk) - 1;
/* TCLK (PCLK * 2) */
int tclk = DCMI_TIM_PCLK_FREQ() * 2;
/* Period should be even */
int period = (tclk / frequency)-1;
int period = (tclk / frequency) - 1;
/* Timer base configuration */
TIMHandle.Instance = DCMI_TIM;
TIMHandle.Init.Period = period;
TIMHandle.Init.Prescaler = prescaler;
TIMHandle.Init.Prescaler = 0;
TIMHandle.Init.ClockDivision = 0;
TIMHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
@ -158,8 +159,21 @@ static int dma_config()
void sensor_init0()
{
// Clear framebuffer
memset(fb, 0, sizeof(*fb));
// Init FB mutex
mutex_init(&JPEG_FB()->lock);
// Save fb_enabled flag state
int fb_enabled = JPEG_FB()->enabled;
// Clear framebuffers
memset(MAIN_FB(), 0, sizeof(*MAIN_FB()));
memset(JPEG_FB(), 0, sizeof(*JPEG_FB()));
// Set default quality
JPEG_FB()->quality = 50;
// Set fb_enabled
JPEG_FB()->enabled = fb_enabled;
}
int sensor_init()
@ -175,21 +189,34 @@ int sensor_init()
SCCB_Init();
systick_sleep(10);
/* Configure the sensor external clock (XCLK) to XCLK_FREQ.
Note: The sensor's internal PLL (when CLKRC=0x80) doubles the XCLK_FREQ
(XCLK=XCLK_FREQ*2), and the unscaled PIXCLK output is XCLK_FREQ*4 */
// Configure the sensor external clock (XCLK) to XCLK_FREQ.
//
// Max pixclk is 2.5 * HCLK:
// STM32F427@180MHz PCLK = 71.9999MHz
// STM32F769@216MHz PCLK = 86.4000MHz
//
// OV7725 PCLK when prescalar is enabled (CLKRC[6]=0):
// Internal clock = Input clock × PLL multiplier / [(CLKRC[5:0] + 1) × 2]
//
// OV7725 PCLK when prescalar is disabled (CLKRC[6]=1):
// Internal clock = Input clock × PLL multiplier
//
// OV2640:
// The sensor's internal PLL (when CLKRC=0x80) doubles the XCLK_FREQ
// (XCLK=XCLK_FREQ*2), and the unscaled PIXCLK output is XCLK_FREQ*4
if (extclk_config(OMV_XCLK_FREQUENCY) != 0) {
// Timer problem
return -1;
}
/* Uncomment this to pass through the MCO1 clock (HSI=16MHz) this results in a
64MHz PIXCLK output from the sensor.
Note: The maximum pixel clock input on the STM32F4xx is 54MHz,
the STM32F7 can probably handle higher input pixel clock.
*/
//(void) extclk_config;
64MHz PIXCLK output from the sensor. */
#if defined OPENMV2
// Note: MCO is multiplexed on OPENMV2 TIM1 only.
//(void) extclk_config; // to avoid warnings
//HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_HSI, RCC_MCODIV_1);
#endif
/* Reset the sesnor state */
memset(&sensor, 0, sizeof(sensor_t));
@ -368,6 +395,9 @@ int sensor_set_framesize(framesize_t framesize)
fb->h = resolution[framesize][1];
HAL_DCMI_DisableCROP(&DCMIHandle);
}
// Set initial JPEG buffer quality.
JPEG_FB()->quality = (MAIN_FB_SIZE() > JPEG_QUALITY_THRESH) ? 50:75;
return 0;
}
@ -554,10 +584,6 @@ void DCMI_DMAConvCpltUser(uint32_t addr)
uint8_t *src = (uint8_t*) addr;
uint8_t *dst = fb->pixels;
if (SENSOR_HW_FLAGS_GET(&sensor, SENSOR_HW_FLAGS_SW_JPEG)) {
dst += FB_JPEG_OFFS_SIZE;
}
if (sensor.line_filter_func && sensor.line_filter_args) {
int bpp = ((sensor.pixformat == PIXFORMAT_GRAYSCALE) ? 1:2);
dst += line++ * fb->w * bpp;
@ -589,44 +615,45 @@ int sensor_snapshot(image_t *image, line_filter_t line_filter_func, void *line_f
{
volatile uint32_t addr;
volatile uint16_t length;
uint32_t snapshot_start;
uint32_t tick_start;
// Set line filter
sensor_set_line_filter(line_filter_func, line_filter_args);
// Compress the framebuffer for the IDE only for non-JPEG images and
// only if the IDE has requested a framebuffer and it's not the first frame.
// Note: This doesn't run unless the camera is connected to PC.
if (fb->bpp && fb->request && sensor.pixformat != PIXFORMAT_JPEG &&
SENSOR_HW_FLAGS_GET(&sensor, SENSOR_HW_FLAGS_SW_JPEG) &&
(!IM_IS_JPEG(fb))) {
// The framebuffer is compressed in place.
// Assuming we have at least 128KBs of SRAM.
image_t src = {.w=fb->w, .h=fb->h, .bpp=fb->bpp, .pixels=fb->pixels+FB_JPEG_OFFS_SIZE};
image_t dst = {.w=fb->w, .h=fb->h, .bpp=128*1024, .pixels=fb->pixels};
// Compress the framebuffer for the IDE preview, only if it's not the first frame,
// the framebuffer is enabled and the image sensor does not support JPEG encoding.
// Note: This doesn't run unless the IDE is connected and the framebuffer is enabled.
if ((fb->bpp == 1 || fb->bpp == 2) && JPEG_FB()->enabled && sensor.pixformat
!= PIXFORMAT_JPEG && SENSOR_HW_FLAGS_GET(&sensor, SENSOR_HW_FLAGS_SW_JPEG)) {
// Lock FB
if (mutex_try_lock(&JPEG_FB()->lock, MUTEX_TID_OMV)) {
// Set JPEG src and dst images.
image_t src = {.w=fb->w, .h=fb->h, .bpp=fb->bpp, .pixels=fb->pixels};
image_t dst = {.w=fb->w, .h=fb->h, .bpp=OMV_JPEG_BUF_SIZE, .pixels=JPEG_FB()->pixels};
// Note: lower quality results in a faster IDE
// framerates, since it saves on USB bandwidth.
int qs = (sensor.framesize <= FRAMESIZE_QVGA) ? 75:50;
jpeg_compress(&src, &dst, qs);
fb->bpp = dst.bpp;
// Note: lower quality saves USB bandwidth and results in a faster IDE FPS.
bool overflow = jpeg_compress(&src, &dst, JPEG_FB()->quality, false);
if (overflow == true) {
// JPEG buffer overflowed, reduce JPEG quality for the next frame
// and skip the current frame. The IDE doesn't receive this frame.
if (JPEG_FB()->quality > 0) {
JPEG_FB()->quality = IM_MAX(1, ((JPEG_FB()->quality) - 10));
}
JPEG_FB()->w = 0; JPEG_FB()->h = 0; JPEG_FB()->size = 0;
} else {
// No buffer overflow, increase quality up to max quality based on frame size
if (JPEG_FB()->quality < ((MAIN_FB_SIZE() > JPEG_QUALITY_THRESH) ? 50:75)) {
JPEG_FB()->quality++;
}
// Set FB from JPEG image
JPEG_FB()->w = dst.w; JPEG_FB()->h = dst.h; JPEG_FB()->size = dst.bpp;
}
// Unlock the framebuffer mutex
mutex_unlock(&JPEG_FB()->lock, MUTEX_TID_OMV);
}
}
// fb->bpp is set to zero for the first frame after changing the resolution/format.
// Note: If fb->bpp is not zero, then we have a valid frame (compressed or raw).
fb->ready = (fb->bpp > 0);
// Wait for the IDE to read the framebuffer before it gets overwritten with a new frame, and
// after all the image processing code has run (which possibily draws over the framebuffer).
//
// This fakes double buffering without having to allocate a second buffer and allows us to
// re-use the framebuffer for software JPEG compression.
// Note: This loop is executed only if the USB debug is active and we have a valid frame.
while (fb->ready && fb->request) {
systick_sleep(2);
}
fb->ready = 0;
// Setup the size and address of the transfer
if (sensor.pixformat == PIXFORMAT_JPEG) {
// Sensor has hardware JPEG set max frame size.
@ -642,7 +669,7 @@ int sensor_snapshot(image_t *image, line_filter_t line_filter_func, void *line_f
line = 0;
// Snapshot start tick
snapshot_start = HAL_GetTick();
tick_start = HAL_GetTick();
// Enable DMA IRQ
HAL_NVIC_EnableIRQ(DMA2_Stream1_IRQn);
@ -659,7 +686,7 @@ int sensor_snapshot(image_t *image, line_filter_t line_filter_func, void *line_f
// Wait for frame
while ((DCMI->CR & DCMI_CR_CAPTURE) != 0) {
if ((HAL_GetTick() - snapshot_start) >= 3000) {
if ((HAL_GetTick() - tick_start) >= 3000) {
// Sensor timeout, most likely a HW issue.
// Abort the DMA request.
HAL_DMA_Abort(&DMAHandle);
@ -675,6 +702,11 @@ int sensor_snapshot(image_t *image, line_filter_t line_filter_func, void *line_f
// Disable DMA IRQ
HAL_NVIC_DisableIRQ(DMA2_Stream1_IRQn);
// TODO on M4 we get an extra call
//if (line != fb->h) {
// printf("lines %d\n", line);
//}
// Fix the BPP
switch (sensor.pixformat) {
case PIXFORMAT_GRAYSCALE:
@ -696,30 +728,6 @@ int sensor_snapshot(image_t *image, line_filter_t line_filter_func, void *line_f
image->h = fb->h;
image->bpp = fb->bpp;
image->pixels = fb->pixels;
if (sensor.pixformat != PIXFORMAT_JPEG &&
SENSOR_HW_FLAGS_GET(&sensor, SENSOR_HW_FLAGS_SW_JPEG)) {
image->pixels += FB_JPEG_OFFS_SIZE;
}
}
return 0;
}
int sensor_get_fb(image_t *img)
{
if (!fb->bpp) {
return -1;
}
if (img != NULL) {
img->w = fb->w;
img->h = fb->h;
img->bpp = fb->bpp;
img->pixels = fb->pixels;
if (sensor.pixformat != PIXFORMAT_JPEG &&
SENSOR_HW_FLAGS_GET(&sensor, SENSOR_HW_FLAGS_SW_JPEG)) {
img->pixels += FB_JPEG_OFFS_SIZE;
}
}
return 0;

View File

@ -156,12 +156,6 @@ int sensor_write_reg(uint8_t reg, uint8_t val);
// Note: Has nothing to do with HW JPEG.
int sensor_enable_jpeg(bool enable);
// Capture a Snapshot.
int sensor_snapshot(image_t *image, line_filter_t line_filter_func, void *line_filter_args);
// Capture the frame buffer.
int sensor_get_fb(image_t *img);
// Set the sensor pixel format.
int sensor_set_pixformat(pixformat_t pixformat);
@ -213,4 +207,7 @@ int sensor_set_special_effect(sde_t sde);
// Set filter function.
int sensor_set_line_filter(line_filter_t line_filter_func, void *line_filter_args);
// Capture a Snapshot.
int sensor_snapshot(image_t *image, line_filter_t line_filter_func, void *line_filter_args);
#endif /* __SENSOR_H__ */

View File

@ -1,152 +0,0 @@
/*
* This file is part of the OpenMV project.
* Copyright (c) 2013/2014 Ibrahim Abdelkader <i.abdalkader@gmail.com>
* This work is licensed under the MIT license, see the file LICENSE for details.
*
* Linker script for STM32F4xx Devices.
*
*/
/* Entry Point */
ENTRY(Reset_Handler)
#ifdef OPENMV1
#define HEAP_MEMORY CCM
#define FLASH_ORIGIN 0x08000000
#define FLASH_LENGTH 512K
#define ISR_ORIGIN 0x08000000
#define ISR_LENGTH 16K
#define TEXT_ORIGIN 0x08010000
#define TEXT_LENGTH 448K
#define RAM_ORIGIN 0x20000000
#define RAM_LENGTH 128K
#define CCM_ORIGIN 0x10000000
#define CCM_LENGTH 64K
#else
#define HEAP_MEMORY CCM
#define FLASH_ORIGIN 0x08000000
#define FLASH_LENGTH 1024K
#define ISR_ORIGIN 0x08000000
#define ISR_LENGTH 16K
#define TEXT_ORIGIN 0x08010000
#define TEXT_LENGTH 960K
#define RAM_ORIGIN 0x20000000
#define RAM_LENGTH 192K
#define CCM_ORIGIN 0x10000000
#define CCM_LENGTH 64K
#endif //OPENMV1
/* Specify the memory areas */
MEMORY
{
FLASH (rx) : ORIGIN = FLASH_ORIGIN, LENGTH = FLASH_LENGTH
FLASH_ISR (rx) : ORIGIN = ISR_ORIGIN, LENGTH = ISR_LENGTH
FLASH_TEXT (rx) : ORIGIN = TEXT_ORIGIN, LENGTH = TEXT_LENGTH
RAM (xrw) : ORIGIN = RAM_ORIGIN, LENGTH = RAM_LENGTH
CCM (xrw) : ORIGIN = CCM_ORIGIN, LENGTH = CCM_LENGTH
}
_estack = 0x10010000; /* Stack is allocated on CCM block */
_ram_end = 0x10010000; /* 64KB CCM */
_fb_base = 0x20000000;
_stack_size = 0xC00; /* minimum amount of stack */
_heap_size = 0xD800; /* required amount of heap */
// Flash filesystem cache
_fs_cache = 0x20030000-(16*1024);
// VFS sturct + FATFS file buffer
// VFS struct size is 624 bytes
_vfs_buf = _fs_cache - (1024);
// USB MSC bot data
_msc_buf = _vfs_buf - (2048);
// Image line buffer.
// Maximum line * 2BPP * 2 (for double buffering).
_line_buf = _msc_buf - (640*4);
// _line_buf is only used when reading frames and when reading
// frames fb_alloc is not used so we can overwrite _line_buf.
_fballoc = _line_buf + (640*4);
/* Define output sections */
SECTIONS
{
/* The program code and other data goes into FLASH */
.text :
{
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
. = ALIGN(4);
_etext = .; /* define a global symbols at end of code */
_exit = .;
} >FLASH_TEXT
/* used by the startup to initialize data */
_sidata = .;
/* Initialized data sections goes into RAM, load LMA copy after code */
.data : AT ( _sidata )
{
. = ALIGN(4);
_sdata = .; /* create a global symbol at data start */
_ram_start = .;
*(.data) /* .data sections */
*(.data*) /* .data* sections */
. = ALIGN(4);
_edata = .; /* define a global symbol at data end */
} >CCM
/* Uninitialized data section */
. = ALIGN(4);
.bss :
{
/* This is used by the startup in order to initialize the .bss secion */
_sbss = .; /* define a global symbol at bss start */
__bss_start__ = _sbss;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .; /* define a global symbol at bss end */
__bss_end__ = _ebss;
_bss_end = _ebss; /* for gccollect */
} >CCM
._heap :
{
. = ALIGN(4);
_heap_start = .;
. = . + _heap_size;
. = ALIGN(4);
_heap_end = .;
} >HEAP_MEMORY
/* Make sure there is enough RAM the stack and FS cache */
._user_heap_stack :
{
. = ALIGN(4);
. = . + _stack_size;
. = ALIGN(4);
} >CCM
.ARM.attributes 0 : { *(.ARM.attributes) }
}

219
src/omv/stm32fxxx.ld.S Executable file
View File

@ -0,0 +1,219 @@
/*
* This file is part of the OpenMV project.
* Copyright (c) 2013/2014 Ibrahim Abdelkader <i.abdalkader@gmail.com>
* This work is licensed under the MIT license, see the file LICENSE for details.
*
* Linker script for STM32F4xx Devices.
*
*/
/* Entry Point */
ENTRY(Reset_Handler)
#if defined(OPENMV1)
#define FLASH_ORIGIN 0x08000000
#define FLASH_LENGTH 512K
#define TEXT_ORIGIN 0x08010000
#define TEXT_LENGTH 448K
#define SRAM1_ORIGIN 0x20000000
#define SRAM1_LENGTH 128K
#define CCM_ORIGIN 0x10000000
#define CCM_LENGTH 64K
#elif defined(OPENMV2)
#define FB_MEMORY SRAM1 // Framebuffer, fb_alloc
#define MAIN_MEMORY CCM // data, bss, stack and heap
#define DMA_MEMORY SRAM2 // Misc DMA buffers
// Located in main memory region
#define STACK_SIZE (3K)
#define HEAP_SIZE (54K)
// Located in FB memory
#define FB_SIZE (151K) // FB memory: header + QVGA/GS image
// fb alloc memory is dynamic = FB_ALLOC_SIZE + FB_SIZE - (w*h*bpp)
// Note this overwrites the 2KBs line buf when not reading a frame.
#define FB_ALLOC_SIZE (14K) // minimum fb alloc size
// Located in DMA memory
#define LINE_BUF_SIZE (2K) // Image line buffer round(320 * 2BPP * 2 buffers).
#define MSC_BUF_SIZE (2K) // USB MSC bot data
#define VFS_BUF_SIZE (1K) // VFS sturct + FATFS file buffer (624 bytes)
#define FS_BUF_SIZE (16K) // Flash filesystem cache
#define JPEG_BUF_SIZE (8K) // IDE JPEG buffer
#define FLASH_ORIGIN 0x08000000
#define FLASH_LENGTH 1024K
#define TEXT_ORIGIN 0x08010000
#define TEXT_LENGTH 960K
#define CCM_ORIGIN 0x10000000
#define CCM_LENGTH 64K
#define SRAM1_ORIGIN 0x20000000
#define SRAM1_LENGTH 163K
#define SRAM2_ORIGIN 0x20028C00
#define SRAM2_LENGTH 29K
#elif defined(OPENMV7)
#define FB_MEMORY SRAM1 // Framebuffer, fb_alloc
#define MAIN_MEMORY SRAM2 // data, bss, stack and heap
#define DMA_MEMORY CCM // Misc DMA buffers
#define FB_SIZE (301K) // FB memory: header + VGA/GS image
#define FB_ALLOC_SIZE (14K) // minimum fb alloc size
#define STACK_SIZE (4K)
#define HEAP_SIZE (58K)
#define LINE_BUF_SIZE (3K) // Image line buffer round(640 * 2BPP * 2 buffers).
#define MSC_BUF_SIZE (2K) // USB MSC bot data
#define VFS_BUF_SIZE (1K) // VFS sturct + FATFS file buffer (624 bytes)
#define FS_BUF_SIZE (32K) // Flash filesystem cache
#define JPEG_BUF_SIZE (64K) // IDE JPEG buffer
#define FLASH_ORIGIN 0x08000000
#define FLASH_LENGTH 2048K
#define TEXT_ORIGIN 0x08020000
#define TEXT_LENGTH 1920K
// Note DTCM/ITCM memory is not cacheable on M7
#define CCM_ORIGIN 0x20000000
#define CCM_LENGTH 128K
#define SRAM1_ORIGIN 0x20020000
#define SRAM1_LENGTH 315K
#define SRAM2_ORIGIN 0x2006EC00
#define SRAM2_LENGTH 69K
#endif
/* Specify the memory areas */
MEMORY
{
CCM (xrw) : ORIGIN = CCM_ORIGIN, LENGTH = CCM_LENGTH
SRAM1 (xrw) : ORIGIN = SRAM1_ORIGIN, LENGTH = SRAM1_LENGTH
SRAM2 (xrw) : ORIGIN = SRAM2_ORIGIN, LENGTH = SRAM2_LENGTH
FLASH_TEXT (rx) : ORIGIN = TEXT_ORIGIN, LENGTH = TEXT_LENGTH
}
_fb_base = ORIGIN(FB_MEMORY);
_fballoc = ORIGIN(FB_MEMORY) + FB_SIZE + FB_ALLOC_SIZE;
_estack = ORIGIN(MAIN_MEMORY) + LENGTH(MAIN_MEMORY);
_ram_end = ORIGIN(MAIN_MEMORY) + LENGTH(MAIN_MEMORY);
_heap_size = HEAP_SIZE; /* required amount of heap */
_stack_size = STACK_SIZE; /* minimum amount of stack */
// _line_buf is only used when reading frames and when reading
// frames fb_alloc is not used so we can overwrite _line_buf.
//_fballoc = _line_buf + (640*4);
/* Define output sections */
SECTIONS
{
/* The program code and other data goes into FLASH */
.text :
{
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
*(.text) /* .text sections (code) */
. = ALIGN(4);
*(.text*) /* .text* sections (code) */
. = ALIGN(4);
*(.rodata) /* .rodata sections (constants, strings, etc.) */
. = ALIGN(4);
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
. = ALIGN(4);
_etext = .; /* define a global symbols at end of code */
} >FLASH_TEXT
/* used by the startup to initialize data */
_sidata = .;
/* Initialized data sections goes into ram, load LMA copy after code */
.data : AT ( _sidata )
{
. = ALIGN(4);
_sdata = .; /* create a global symbol at data start */
_ram_start = .;
*(.data) /* .data sections */
. = ALIGN(4);
*(.data*) /* .data* sections */
. = ALIGN(4);
_edata = .; /* define a global symbol at data end */
} >MAIN_MEMORY
/* Uninitialized data section */
. = ALIGN(4);
.bss (NOLOAD) :
{
/* This is used by the startup in order to initialize the .bss secion */
_sbss = .; /* define a global symbol at bss start */
__bss_start__ = _sbss;
*(.bss)
. = ALIGN(4);
*(.bss*)
. = ALIGN(4);
*(COMMON)
. = ALIGN(4);
_ebss = .; /* define a global symbol at bss end */
__bss_end__ = _ebss;
_bss_end = _ebss; /* for gccollect */
} >MAIN_MEMORY
._heap (NOLOAD) :
{
. = ALIGN(4);
_heap_start = .;
. = . + _heap_size;
. = ALIGN(4);
_heap_end = .;
} >MAIN_MEMORY
/* Make sure there is enough ram for the stack */
._stack (NOLOAD) :
{
. = ALIGN(4);
. = . + _stack_size;
. = ALIGN(4);
} >MAIN_MEMORY
/* Non-cacheable DMA buffers */
.dma_buffers (NOLOAD) :
{
. = ALIGN(4);
_line_buf = .; // Image line buffer.
. = . + LINE_BUF_SIZE;
. = ALIGN(4);
_msc_buf = .; // USB MSC bot data (2K)
. = . + MSC_BUF_SIZE;
. = ALIGN(4);
_vfs_buf = .; // VFS sturct + FATFS file buffer (around 624 bytes)
. = . + VFS_BUF_SIZE;
. = ALIGN(4);
_fs_cache = .; // Flash filesystem cache
. = . + FS_BUF_SIZE;
. = ALIGN(4);
_jpeg_buf = .; // IDE JPEG buffer
. = . + JPEG_BUF_SIZE;
. = ALIGN(4);
*(.dma_buffer)
} >DMA_MEMORY
.ARM.attributes 0 : { *(.ARM.attributes) }
}

View File

@ -6,7 +6,7 @@
* HAL MSP.
*
*/
#include <stm32f4xx_hal.h>
#include STM32_HAL_H
#include "omv_boardconfig.h"
/* GPIO struct */
@ -36,6 +36,16 @@ void SystemClock_Config(void);
void HAL_MspInit(void)
{
#if defined(STM32F769xx)
// Invalidate each cache before enabling it
SCB_InvalidateICache();
SCB_InvalidateDCache();
/* Enable the CPU Cache */
SCB_EnableICache();
SCB_EnableDCache();
#endif
/* Set the system clock */
SystemClock_Config();
@ -48,14 +58,25 @@ void HAL_MspInit(void)
__GPIOC_CLK_ENABLE();
__GPIOD_CLK_ENABLE();
__GPIOE_CLK_ENABLE();
#ifdef OPENMV2
#if defined (STM32F769xx)
__GPIOF_CLK_ENABLE();
__GPIOG_CLK_ENABLE();
__GPIOH_CLK_ENABLE();
__GPIOI_CLK_ENABLE();
__GPIOJ_CLK_ENABLE();
__GPIOK_CLK_ENABLE();
#endif
/* Enable DMA clocks */
__DMA1_CLK_ENABLE();
__DMA2_CLK_ENABLE();
#if defined (STM32F769xx)
/* Enable JPEG clock */
__HAL_RCC_JPEG_CLK_ENABLE();
#endif
/* Configure DCMI GPIO */
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.Pull = GPIO_PULLDOWN;

View File

@ -11,7 +11,6 @@
#include "sensor.h"
#include "framebuffer.h"
#include "ff.h"
#include "core_cm4.h"
#include "usbdbg.h"
#include "nlr.h"
#include "lexer.h"
@ -92,26 +91,29 @@ void usbdbg_data_in(void *buffer, int length)
}
case USBDBG_FRAME_SIZE:
if (!fb->ready) {
// Frame not ready return 0
((uint32_t*)buffer)[0] = 0;
} else {
// Frame ready return header
((uint32_t*)buffer)[0] = fb->w;
((uint32_t*)buffer)[1] = fb->h;
((uint32_t*)buffer)[2] = fb->bpp;
((uint32_t*)buffer)[0] = 0;
// Try to lock FB
if (mutex_try_lock(&JPEG_FB()->lock, MUTEX_TID_IDE)) {
// Return header w, h and size/bpp
((uint32_t*)buffer)[0] = JPEG_FB()->w;
((uint32_t*)buffer)[1] = JPEG_FB()->h;
((uint32_t*)buffer)[2] = JPEG_FB()->size;
// If header size == 0 frame is not ready
if (JPEG_FB()->size == 0) {
// unlock FB
mutex_unlock(&JPEG_FB()->lock, MUTEX_TID_IDE);
}
}
fb->request = 1;
cmd = USBDBG_NONE;
break;
case USBDBG_FRAME_DUMP:
if (xfer_bytes < xfer_length) {
memcpy(buffer, fb->pixels+xfer_bytes, length);
memcpy(buffer, JPEG_FB()->pixels+xfer_bytes, length);
xfer_bytes += length;
if (xfer_bytes == xfer_length) {
fb->request = 0;
cmd = USBDBG_NONE;
mutex_unlock(&JPEG_FB()->lock, MUTEX_TID_IDE);
}
}
break;
@ -288,8 +290,20 @@ void usbdbg_control(void *buffer, uint8_t request, uint32_t length)
NVIC_SystemReset();
break;
case USBDBG_FB_ENABLE: {
int16_t enable = *((int16_t*)buffer);
JPEG_FB()->enabled = enable;
if (enable == 0) {
// When disabling framebuffer, the IDE might still be holding FB lock.
// If the IDE is not the current lock owner, this operation is ignored.
mutex_unlock(&JPEG_FB()->lock, MUTEX_TID_IDE);
}
cmd = USBDBG_NONE;
break;
}
case USBDBG_JPEG_ENABLE: {
int16_t enable= *((int16_t*)buffer);
int16_t enable = *((int16_t*)buffer);
sensor_enable_jpeg(enable);
cmd = USBDBG_NONE;
break;

View File

@ -43,6 +43,7 @@ enum usbdbg_cmd {
USBDBG_ATTR_READ =0x8A,
USBDBG_ATTR_WRITE =0x0B,
USBDBG_SYS_RESET =0x0C,
USBDBG_FB_ENABLE =0x0D,
USBDBG_JPEG_ENABLE =0x0E,
USBDBG_TX_BUF_LEN =0x8E,
USBDBG_TX_BUF =0x8F

View File

@ -33,6 +33,7 @@ stm32f7xx_hal_tim.c\
stm32f7xx_hal_tim_ex.c\
stm32f7xx_hal_uart.c\
stm32f7xx_hal_usart.c\
stm32f7xx_hal_jpeg.c\
stm32f7xx_ll_usb.c\
stm32f7xx_ll_sdmmc.c\
stm32f7xx_ll_fmc.c\

View File

@ -411,8 +411,8 @@ typedef struct
* @retval The state of FLAG.
*/
#define __HAL_DCMI_GET_FLAG(__HANDLE__, __FLAG__)\
((((__FLAG__) & (DCMI_SR_INDEX|DCMI_MIS_INDEX)) == 0x0)? ((__HANDLE__)->Instance->RIS & (__FLAG__)) :\
(((__FLAG__) & DCMI_SR_INDEX) == 0x0)? ((__HANDLE__)->Instance->MIS & (__FLAG__)) : ((__HANDLE__)->Instance->SR & (__FLAG__)))
((((__FLAG__) & (DCMI_SR_INDEX|DCMI_MIS_INDEX)) == 0x0)? ((__HANDLE__)->Instance->RISR & (__FLAG__)) :\
(((__FLAG__) & DCMI_SR_INDEX) == 0x0)? ((__HANDLE__)->Instance->MISR & (__FLAG__)) : ((__HANDLE__)->Instance->SR & (__FLAG__)))
/**
* @brief Clear the DCMI pending flags.

82
src/sthal/f7/src/stm32f7xx_hal_dcmi.c Normal file → Executable file
View File

@ -390,8 +390,8 @@ HAL_StatusTypeDef HAL_DCMI_Start_DMA_MB(DCMI_HandleTypeDef* hdcmi, uint32_t DCMI
/* Lock the DCMI peripheral state */
hdcmi->State = HAL_DCMI_STATE_BUSY;
/* Check the parameters */
assert_param(IS_DCMI_CAPTURE_MODE(DCMI_Mode));
/* Enable DCMI by setting DCMIEN bit */
__HAL_DCMI_ENABLE(hdcmi);
/* Configure the DCMI Mode */
hdcmi->Instance->CR &= ~(DCMI_CR_CM);
@ -403,28 +403,29 @@ HAL_StatusTypeDef HAL_DCMI_Start_DMA_MB(DCMI_HandleTypeDef* hdcmi, uint32_t DCMI
/* Set the DMA error callback */
hdcmi->DMA_Handle->XferErrorCallback = DCMI_DMAError;
/* Set the dma abort callback */
hdcmi->DMA_Handle->XferAbortCallback = NULL;
/* DCMI_DOUBLE_BUFFER Mode */
/* Set the DMA memory1 conversion complete callback */
hdcmi->DMA_Handle->XferM1CpltCallback = DCMI_DMAXferCplt;
/* Initialise transfer parameters */
hdcmi->XferCount = Count;
hdcmi->XferCount = Count-2;
hdcmi->XferSize = Length/Count;
hdcmi->pBuffPtr = pData;
/* Update DCMI counter and transfer number*/
hdcmi->XferCount = (hdcmi->XferCount - 2);
hdcmi->XferTransferNumber = hdcmi->XferCount;
/* Update second memory address */
SecondMemAddress = (uint32_t)(pData + (4*hdcmi->XferSize));
/* Start DMA multi buffer transfer */
HAL_DMAEx_MultiBufferStart_IT(hdcmi->DMA_Handle, (uint32_t)&hdcmi->Instance->DR, (uint32_t)pData, SecondMemAddress, hdcmi->XferSize);
/* Enable Capture */
DCMI->CR |= DCMI_CR_CAPTURE;
hdcmi->Instance->CR |= DCMI_CR_CAPTURE;
/* Release Lock */
__HAL_UNLOCK(hdcmi);
/* Return function status */
return HAL_OK;
@ -701,6 +702,10 @@ __weak void HAL_DCMI_FrameEventCallback(DCMI_HandleTypeDef *hdcmi)
*/
}
__weak void DCMI_DMAConvCpltUser(uint32_t addr)
{
}
/**
* @}
*/
@ -867,52 +872,27 @@ uint32_t HAL_DCMI_GetError(DCMI_HandleTypeDef *hdcmi)
*/
static void DCMI_DMAXferCplt(DMA_HandleTypeDef *hdma)
{
uint32_t tmp = 0;
DCMI_HandleTypeDef* hdcmi;
hdcmi = (DCMI_HandleTypeDef*) ((DMA_HandleTypeDef*)hdma)->Parent;
//hdcmi->State= HAL_DCMI_STATE_READY;
DCMI_HandleTypeDef* hdcmi = ( DCMI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
if(hdcmi->XferCount != 0)
{
/* Update memory 0 address location */
tmp = ((hdcmi->DMA_Handle->Instance->CR) & DMA_SxCR_CT);
if(((hdcmi->XferCount % 2) == 0) && (tmp != 0))
{
tmp = hdcmi->DMA_Handle->Instance->M0AR;
HAL_DMAEx_ChangeMemory(hdcmi->DMA_Handle, (tmp + (8*hdcmi->XferSize)), MEMORY0);
hdcmi->XferCount--;
}
/* Update memory 1 address location */
else if((hdcmi->DMA_Handle->Instance->CR & DMA_SxCR_CT) == 0)
{
tmp = hdcmi->DMA_Handle->Instance->M1AR;
HAL_DMAEx_ChangeMemory(hdcmi->DMA_Handle, (tmp + (8*hdcmi->XferSize)), MEMORY1);
hdcmi->XferCount--;
}
}
/* Update memory 0 address location */
else if((hdcmi->DMA_Handle->Instance->CR & DMA_SxCR_CT) != 0)
{
hdcmi->DMA_Handle->Instance->M0AR = hdcmi->pBuffPtr;
}
/* Update memory 1 address location */
else if((hdcmi->DMA_Handle->Instance->CR & DMA_SxCR_CT) == 0)
{
tmp = hdcmi->pBuffPtr;
hdcmi->DMA_Handle->Instance->M1AR = (tmp + (4*hdcmi->XferSize));
hdcmi->XferCount = hdcmi->XferTransferNumber;
// Note: we don't need to adjust memory addresses because they stay the same.
if (hdcmi->XferCount != 0) {
hdcmi->XferCount--;
}
/* Check if the frame is transferred */
if(hdcmi->XferCount == hdcmi->XferTransferNumber)
{
/* Enable the Frame interrupt */
if ((hdcmi->DMA_Handle->Instance->CR & DMA_SxCR_CT) == 0) {
// Current traget is M0 call user callback with M1
DCMI_DMAConvCpltUser(hdcmi->DMA_Handle->Instance->M1AR);
} else {
// Current traget is M1 call user callback with M0
DCMI_DMAConvCpltUser(hdcmi->DMA_Handle->Instance->M0AR);
}
if (__HAL_DCMI_GET_FLAG(hdcmi, DCMI_FLAG_FRAMERI) != RESET) {
/* Re-enable frame interrupt */
__HAL_DCMI_ENABLE_IT(hdcmi, DCMI_IT_FRAME);
/* When snapshot mode, set dcmi state to ready */
if((hdcmi->Instance->CR & DCMI_CR_CM) == DCMI_MODE_SNAPSHOT)
{
hdcmi->State= HAL_DCMI_STATE_READY;
}
hdcmi->State= HAL_DCMI_STATE_READY;
}
}

View File

@ -103,12 +103,12 @@
#include "bsp/include/nm_bsp_arduino_uno.h"
#endif
#ifdef OPENMV1
#if defined(OPENMV1)
#include "nm_bsp_openmv1.h"
#endif
#ifdef OPENMV2
#elif defined(OPENMV2)
#include "nm_bsp_openmv2.h"
#elif defined(OPENMV7)
#include "nm_bsp_openmv7.h"
#endif
#endif //_NM_BSP_INTERNAL_H_

View File

@ -3,9 +3,14 @@
#include "conf_winc.h"
#define NM_EDGE_INTERRUPT (1)
#define NM_EDGE_INTERRUPT (1)
#define NM_DEBUG CONF_WINC_DEBUG
#define NM_BSP_PRINTF CONF_WINC_PRINTF
#define NM_DEBUG CONF_WINC_DEBUG
#define NM_BSP_PRINTF CONF_WINC_PRINTF
#define WINC_PIN_CS (pin_B12)
#define WINC_PIN_EN (pin_A5)
#define WINC_PIN_RST (pin_D12)
#define WINC_PIN_IRQ (pin_D13)
#endif /* _NM_BSP_OPENMV2_H_ */

View File

@ -0,0 +1,16 @@
#ifndef _NM_BSP_OPENMV7_H_
#define _NM_BSP_OPENMV7_H_
#include "conf_winc.h"
#define NM_EDGE_INTERRUPT (1)
#define NM_DEBUG CONF_WINC_DEBUG
#define NM_BSP_PRINTF CONF_WINC_PRINTF
#define WINC_PIN_CS (pin_I0)
#define WINC_PIN_EN (pin_D5)
#define WINC_PIN_RST (pin_G9)
#define WINC_PIN_IRQ (pin_H15)
#endif /* _NM_BSP_OPENMV7_H_ */

View File

@ -1,4 +1,4 @@
#include <stm32f4xx_hal.h>
#include STM32_HAL_H
#include "conf_winc.h"
#include "bsp/include/nm_bsp.h"
#include "common/include/nm_common.h"
@ -10,10 +10,10 @@
#include "systick.h"
static tpfNmBspIsr gpfIsr;
static const pin_obj_t *PIN_CS = &pin_B12;
static const pin_obj_t *PIN_EN = &pin_A5;
static const pin_obj_t *PIN_RST = &pin_D12;
static const pin_obj_t *PIN_IRQ = &pin_D13;
static const pin_obj_t *PIN_CS = &(WINC_PIN_CS);
static const pin_obj_t *PIN_EN = &(WINC_PIN_EN);
static const pin_obj_t *PIN_RST = &(WINC_PIN_RST);
static const pin_obj_t *PIN_IRQ = &(WINC_PIN_IRQ);
static const mp_obj_fun_builtin_t irq_callback_obj;
/*

View File

@ -40,6 +40,8 @@
*/
#include <stdio.h>
#include <string.h>
#include STM32_HAL_H
#include "bsp/include/nm_bsp.h"
#include "common/include/nm_common.h"
#include "bus_wrapper/include/nm_bus_wrapper.h"
@ -49,7 +51,6 @@
#include "pin.h"
#include "genhdr/pins.h"
#include "extint.h"
#include <stm32f4xx_hal.h>
#include "spi.h"
static SPI_HandleTypeDef SPI_HANDLE;
@ -90,11 +91,10 @@ static sint8 nm_i2c_write_special(uint8 *wb1, uint16 sz1, uint8 *wb2, uint16 sz2
#ifdef CONF_WINC_USE_SPI
/** PIO instance used by CS. */
static const pin_obj_t *PIN_CS = &pin_B12;
#define SPI_ASSERT_CS() do {HAL_GPIO_WritePin(PIN_CS->gpio, PIN_CS->pin_mask, GPIO_PIN_RESET);} while(0)
#define SPI_DEASSERT_CS() do {HAL_GPIO_WritePin(PIN_CS->gpio, PIN_CS->pin_mask, GPIO_PIN_SET);} while(0)
static const pin_obj_t *PIN_CS = &WINC_PIN_CS;
#define SPI_TIMEOUT (10000) /* in ms */
#include <string.h>
#define SPI_ASSERT_CS() do {HAL_GPIO_WritePin(PIN_CS->gpio, PIN_CS->pin_mask, GPIO_PIN_RESET);} while(0)
#define SPI_DEASSERT_CS() do {HAL_GPIO_WritePin(PIN_CS->gpio, PIN_CS->pin_mask, GPIO_PIN_SET);} while(0)
static sint8 spi_rw(uint8 *tx_buf, uint8 *rx_buf, uint16 u16Sz)
{