diff --git a/src/omv/boards/NANO33/omv_boardconfig.h b/src/omv/boards/NANO33/omv_boardconfig.h index 525d49384..74e1ccfd3 100644 --- a/src/omv/boards/NANO33/omv_boardconfig.h +++ b/src/omv/boards/NANO33/omv_boardconfig.h @@ -67,6 +67,10 @@ #define JPEG_QUALITY_LOW 50 #define JPEG_QUALITY_HIGH 90 +// Low and high JPEG QS. +#define JPEG_QUALITY_LOW 50 +#define JPEG_QUALITY_HIGH 90 + // FB Heap Block Size #define OMV_UMM_BLOCK_SIZE 16 @@ -91,4 +95,11 @@ #define OMV_TEXT_LENGTH 808K // FLASH_SIZE - SD_SIZE - FS_SIZE #define OMV_SRAM_ORIGIN 0x20004000 // Reserve 16K for SD memory. #define OMV_SRAM_LENGTH 240K // RAM_SIZE - SD_RAM_SIZE + +// FIR I2C +#define FIR_I2C_ID (0) +#define FIR_I2C_SCL_PIN (2) +#define FIR_I2C_SDA_PIN (31) +#define FIR_I2C_SPEED (CAMBUS_SPEED_FULL) + #endif //__OMV_BOARDCONFIG_H__ diff --git a/src/omv/ports/nrf/cambus.c b/src/omv/ports/nrf/cambus.c new file mode 100644 index 000000000..a19beffdf --- /dev/null +++ b/src/omv/ports/nrf/cambus.c @@ -0,0 +1,167 @@ +/* + * This file is part of the OpenMV project. + * + * Copyright (c) 2013-2019 Ibrahim Abdelkader + * Copyright (c) 2013-2019 Kwabena W. Agyeman + * + * This work is licensed under the MIT license, see the file LICENSE for details. + * + * Cambus driver nRF port. + */ +#include +#include +#include "py/mphal.h" + +#include "omv_boardconfig.h" +#include "cambus.h" +#include "common.h" + +#define I2C_TIMEOUT (1000) +#define I2C_SCAN_TIMEOUT (100) + +int cambus_init(cambus_t *bus, uint32_t bus_id, uint32_t speed) +{ + bus->id = bus_id; + bus->speed = speed; + bus->scl_pin = FIR_I2C_SCL_PIN; + bus->sda_pin = FIR_I2C_SDA_PIN; + bus->initialized = false; + + switch (bus_id) { + case 0: { + nrfx_twi_t _twi = NRFX_TWI_INSTANCE(0); + memcpy(&bus->twi, &_twi, sizeof(nrfx_twi_t)); + break; + } + case 1: { + nrfx_twi_t _twi = NRFX_TWI_INSTANCE(1); + memcpy(&bus->twi, &_twi, sizeof(nrfx_twi_t)); + break; + } + default: + return -1; + } + + nrfx_twi_config_t config = { + .scl = FIR_I2C_SCL_PIN, + .sda = FIR_I2C_SDA_PIN, + .frequency = speed, + .interrupt_priority = 4, + .hold_bus_uninit = false + }; + + if (nrfx_twi_init(&bus->twi, &config, NULL, NULL) != NRFX_SUCCESS) { + return -1; + } + + bus->initialized = true; + return 0; +} + +int cambus_deinit(cambus_t *bus) +{ + if (bus->initialized) { + nrfx_twi_uninit(&bus->twi); + bus->initialized = false; + } + return 0; +} + +int cambus_scan(cambus_t *bus) +{ + return 0; +} + +int cambus_gencall(cambus_t *bus, uint8_t cmd) +{ + return 0; +} + +int cambus_read_bytes(cambus_t *bus, uint8_t slv_addr, uint8_t reg_addr, uint8_t *buf, int len) +{ + int ret = 0; + slv_addr = slv_addr >> 1; + + nrfx_twi_enable(&bus->twi); + nrfx_twi_xfer_desc_t desc1 = NRFX_TWI_XFER_DESC_TX(slv_addr, ®_addr, 1); + if (nrfx_twi_xfer(&bus->twi, &desc1, NRFX_TWI_FLAG_TX_NO_STOP) != NRFX_SUCCESS) { + ret = -1; + goto i2c_error; + } + + nrfx_twi_xfer_desc_t desc2 = NRFX_TWI_XFER_DESC_RX(slv_addr, buf, len); + if (nrfx_twi_xfer(&bus->twi, &desc2, 0) != NRFX_SUCCESS) { + ret = -1; + } + +i2c_error: + nrfx_twi_disable(&bus->twi); + return ret; +} + +int cambus_write_bytes(cambus_t *bus, uint8_t slv_addr, uint8_t reg_addr, uint8_t *buf, int len) +{ + int ret = 0; + slv_addr = slv_addr >> 1; + + nrfx_twi_enable(&bus->twi); + nrfx_twi_xfer_desc_t desc1 = NRFX_TWI_XFER_DESC_TX(slv_addr, ®_addr, 1); + if (nrfx_twi_xfer(&bus->twi, &desc1, NRFX_TWI_FLAG_SUSPEND) != NRFX_SUCCESS) { + ret = -1; + goto i2c_error; + } + + nrfx_twi_xfer_desc_t desc2 = NRFX_TWI_XFER_DESC_TX(slv_addr, buf, len); + if (nrfx_twi_xfer(&bus->twi, &desc2, 0) != NRFX_SUCCESS) { + ret = -1; + } + +i2c_error: + nrfx_twi_disable(&bus->twi); + return ret; +} + +int cambus_readw_bytes(cambus_t *bus, uint8_t slv_addr, uint16_t reg_addr, uint8_t *buf, int len) +{ + return 0; +} + +int cambus_writew_bytes(cambus_t *bus, uint8_t slv_addr, uint16_t reg_addr, uint8_t *buf, int len) +{ + return 0; +} + +int cambus_read_bytes_seq(cambus_t *bus, uint8_t slv_addr, uint8_t *buf, int len, bool nostop) +{ + int ret = 0; + slv_addr = slv_addr >> 1; + nrfx_twi_enable(&bus->twi); + nrfx_twi_xfer_desc_t desc = NRFX_TWI_XFER_DESC_RX(slv_addr, buf, len); + if (nrfx_twi_xfer(&bus->twi, &desc, 0) != NRFX_SUCCESS) { + ret = -1; + } + nrfx_twi_disable(&bus->twi); + return ret; +} + +int cambus_write_bytes_seq(cambus_t *bus, uint8_t slv_addr, uint8_t *buf, int len, bool nostop) +{ + int ret = 0; + slv_addr = slv_addr >> 1; + nrfx_twi_enable(&bus->twi); + nrfx_twi_xfer_desc_t desc = NRFX_TWI_XFER_DESC_TX(slv_addr, buf, len); + if (nrfx_twi_xfer(&bus->twi, &desc, (nostop == true) ? NRFX_TWI_FLAG_TX_NO_STOP:0) != NRFX_SUCCESS) { + ret = -1; + } + nrfx_twi_disable(&bus->twi); + return ret; +} + +int cambus_pulse_scl(cambus_t *bus) +{ + for (int i=0; i<10000; i++) { + cambus_deinit(bus); + nrfx_twi_bus_recover(bus->scl_pin, bus->sda_pin); + } + return 0; +} diff --git a/src/omv/ports/nrf/cambus_struct.h b/src/omv/ports/nrf/cambus_struct.h new file mode 100644 index 000000000..a192b775f --- /dev/null +++ b/src/omv/ports/nrf/cambus_struct.h @@ -0,0 +1,30 @@ +/* + * This file is part of the OpenMV project. + * + * Copyright (c) 2013-2019 Ibrahim Abdelkader + * Copyright (c) 2013-2019 Kwabena W. Agyeman + * + * This work is licensed under the MIT license, see the file LICENSE for details. + * + * NRF port camera bus struct definition. + */ +#ifndef __CAMBUS_STRUCT_H__ +#define __CAMBUS_STRUCT_H__ + +#include "nrfx_twi.h" + +typedef enum _cambus_speed { + CAMBUS_SPEED_STANDARD = TWI_FREQUENCY_FREQUENCY_K100, ///< 100 kbps + CAMBUS_SPEED_FULL = TWI_FREQUENCY_FREQUENCY_K250, ///< 250 kbps + CAMBUS_SPEED_FAST = TWI_FREQUENCY_FREQUENCY_K400 ///< 400 kbps +} cambus_speed_t; + +typedef struct _cambus { + uint32_t id; + uint32_t speed; + uint32_t scl_pin; + uint32_t sda_pin; + uint32_t initialized; + nrfx_twi_t twi; +} cambus_t; +#endif // __CAMBUS_STRUCT_H__ diff --git a/src/omv/ports/nrf/omv_portconfig.mk b/src/omv/ports/nrf/omv_portconfig.mk index e22830327..3c9aeae2f 100644 --- a/src/omv/ports/nrf/omv_portconfig.mk +++ b/src/omv/ports/nrf/omv_portconfig.mk @@ -48,10 +48,11 @@ OMV_CFLAGS += -I$(TOP_DIR)/$(OMV_DIR)/ports/$(PORT)/ OMV_CFLAGS += -I$(TOP_DIR)/$(OMV_DIR)/ports/$(PORT)/modules/ OMV_CFLAGS += -I$(TOP_DIR)/$(LEPTON_DIR)/include/ -OMV_CFLAGS += -I$(TOP_DIR)/$(MLX_DIR)/include/ OMV_CFLAGS += -I$(TOP_DIR)/$(LSM6DS3_DIR)/include/ -OMV_CFLAGS += -I$(TOP_DIR)/$(TENSORFLOW_DIR)/$(CPU)/ OMV_CFLAGS += -I$(TOP_DIR)/$(WINC1500_DIR)/include/ +OMV_CFLAGS += -I$(TOP_DIR)/$(MLX90621_DIR)/include/ +OMV_CFLAGS += -I$(TOP_DIR)/$(MLX90640_DIR)/include/ +OMV_CFLAGS += -I$(TOP_DIR)/$(TENSORFLOW_DIR)/$(CPU)/ OMV_CFLAGS += -I$(TOP_DIR)/$(LIBPDM_DIR)/ CFLAGS += $(HAL_CFLAGS) $(MPY_CFLAGS) $(OMV_CFLAGS) @@ -76,13 +77,14 @@ FIRM_OBJ += $(wildcard $(BUILD)/$(CMSIS_DIR)/src/nn/ConvolutionFunctions/*.o) FIRM_OBJ += $(wildcard $(BUILD)/$(HAL_DIR)/src/*.o) FIRM_OBJ += $(wildcard $(BUILD)/$(LEPTON_DIR)/src/*.o) -FIRM_OBJ += $(wildcard $(BUILD)/$(MLX_DIR)/src/*.o) ifeq ($(MICROPY_PY_IMU), 1) FIRM_OBJ += $(wildcard $(BUILD)/$(LSM6DS3_DIR)/src/*.o) endif ifeq ($(MICROPY_PY_WINC1500), 1) FIRM_OBJ += $(wildcard $(BUILD)/$(WINC1500_DIR)/src/*.o) endif +FIRM_OBJ += $(wildcard $(BUILD)/$(MLX90621_DIR)/src/*.o) +FIRM_OBJ += $(wildcard $(BUILD)/$(MLX90640_DIR)/src/*.o) #------------- OpenMV Objects ----------------# FIRM_OBJ += $(addprefix $(BUILD)/$(CMSIS_DIR)/src/, \ @@ -127,6 +129,7 @@ FIRM_OBJ += $(addprefix $(BUILD)/$(OMV_DIR)/modules/, \ py_omv.o \ py_sensor.o \ py_tf.o \ + py_fir.o \ ) FIRM_OBJ += $(addprefix $(BUILD)/$(OMV_DIR)/imlib/, \ @@ -335,6 +338,8 @@ FIRMWARE_OBJS: | $(BUILD) $(FW_DIR) $(MAKE) -C $(CMSIS_DIR) BUILD=$(BUILD)/$(CMSIS_DIR) CFLAGS="$(CFLAGS) -fno-strict-aliasing -MMD" $(MAKE) -C $(MICROPY_DIR)/ports/$(PORT) BUILD=$(BUILD)/$(MICROPY_DIR) $(MICROPY_ARGS) $(MAKE) -C $(HAL_DIR) BUILD=$(BUILD)/$(HAL_DIR) CFLAGS="$(CFLAGS) -MMD" + $(MAKE) -C $(MLX90621_DIR) BUILD=$(BUILD)/$(MLX90621_DIR) CFLAGS="$(CFLAGS) -MMD" + $(MAKE) -C $(MLX90640_DIR) BUILD=$(BUILD)/$(MLX90640_DIR) CFLAGS="$(CFLAGS) -MMD" $(MAKE) -C $(OMV_DIR) BUILD=$(BUILD)/$(OMV_DIR) CFLAGS="$(CFLAGS) -MMD" $(FIRMWARE): FIRMWARE_OBJS