mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
Merge pull request #2423 from kwagyeman/kwabena/add_genx320x320_driver
sensors: Add genx320 driver.
This commit is contained in:
commit
69f49dfeca
@ -0,0 +1,32 @@
|
||||
# This work is licensed under the MIT license.
|
||||
# Copyright (c) 2013-2024 OpenMV LLC. All rights reserved.
|
||||
# https://github.com/openmv/openmv/blob/master/LICENSE
|
||||
#
|
||||
# This example shows off using the genx320 event camera from Prophesee.
|
||||
|
||||
import sensor
|
||||
import image
|
||||
import time
|
||||
|
||||
sensor.reset()
|
||||
sensor.set_pixformat(sensor.GRAYSCALE) # Must always be grayscale.
|
||||
sensor.set_framesize(sensor.B320X320) # Must always be 320x320.
|
||||
sensor.set_color_palette(image.PALETTE_EVT_DARK)
|
||||
|
||||
clock = time.clock()
|
||||
|
||||
while True:
|
||||
clock.tick()
|
||||
|
||||
img = sensor.snapshot()
|
||||
# img.median(1) # noise cleanup.
|
||||
|
||||
blobs = img.find_blobs(
|
||||
[(10, 20, -10, 10, -20, 0)], invert=True, pixels_threshold=10, area_threshold=100, merge=True
|
||||
)
|
||||
|
||||
for blob in blobs:
|
||||
img.draw_rectangle(blob.rect(), color=(255, 0, 0))
|
||||
img.draw_cross(blob.cx(), blob.cy(), color=(0, 255, 0))
|
||||
|
||||
print(clock.fps())
|
||||
@ -0,0 +1,24 @@
|
||||
# This work is licensed under the MIT license.
|
||||
# Copyright (c) 2013-2024 OpenMV LLC. All rights reserved.
|
||||
# https://github.com/openmv/openmv/blob/master/LICENSE
|
||||
#
|
||||
# This example shows off using the genx320 event camera from Prophesee.
|
||||
|
||||
import sensor
|
||||
import image
|
||||
import time
|
||||
|
||||
sensor.reset()
|
||||
sensor.set_pixformat(sensor.GRAYSCALE) # Must always be grayscale.
|
||||
sensor.set_framesize(sensor.B320X320) # Must always be 320x320.
|
||||
sensor.set_color_palette(image.PALETTE_EVT_DARK)
|
||||
|
||||
clock = time.clock()
|
||||
|
||||
while True:
|
||||
clock.tick()
|
||||
|
||||
img = sensor.snapshot()
|
||||
# img.median(1) # noise cleanup.
|
||||
|
||||
print(clock.fps())
|
||||
@ -0,0 +1,24 @@
|
||||
# This work is licensed under the MIT license.
|
||||
# Copyright (c) 2013-2024 OpenMV LLC. All rights reserved.
|
||||
# https://github.com/openmv/openmv/blob/master/LICENSE
|
||||
#
|
||||
# This example shows off using the genx320 event camera from Prophesee.
|
||||
|
||||
import sensor
|
||||
import image
|
||||
import time
|
||||
|
||||
sensor.reset()
|
||||
sensor.set_pixformat(sensor.GRAYSCALE) # Must always be grayscale.
|
||||
sensor.set_framesize(sensor.B320X320) # Must always be 320x320.
|
||||
sensor.set_color_palette(image.PALETTE_EVT_LIGHT)
|
||||
|
||||
clock = time.clock()
|
||||
|
||||
while True:
|
||||
clock.tick()
|
||||
|
||||
img = sensor.snapshot()
|
||||
# img.median(1) # noise cleanup.
|
||||
|
||||
print(clock.fps())
|
||||
@ -0,0 +1,32 @@
|
||||
# This work is licensed under the MIT license.
|
||||
# Copyright (c) 2013-2024 OpenMV LLC. All rights reserved.
|
||||
# https://github.com/openmv/openmv/blob/master/LICENSE
|
||||
#
|
||||
# This example shows off using the genx320 event camera from Prophesee.
|
||||
|
||||
import sensor
|
||||
import image
|
||||
import time
|
||||
|
||||
sensor.reset()
|
||||
sensor.set_pixformat(sensor.GRAYSCALE) # Must always be grayscale.
|
||||
sensor.set_framesize(sensor.B320X320) # Must always be 320x320.
|
||||
sensor.set_color_palette(image.PALETTE_EVT_LIGHT)
|
||||
|
||||
clock = time.clock()
|
||||
|
||||
while True:
|
||||
clock.tick()
|
||||
|
||||
img = sensor.snapshot()
|
||||
# img.median(1) # noise cleanup.
|
||||
|
||||
blobs = img.find_blobs(
|
||||
[(85, 95, -10, 10, -10, 10)], invert=True, pixels_threshold=10, area_threshold=100, merge=True
|
||||
)
|
||||
|
||||
for blob in blobs:
|
||||
img.draw_rectangle(blob.rect(), color=(255, 0, 0))
|
||||
img.draw_cross(blob.cx(), blob.cy(), color=(0, 255, 0))
|
||||
|
||||
print(clock.fps())
|
||||
@ -0,0 +1,22 @@
|
||||
# This work is licensed under the MIT license.
|
||||
# Copyright (c) 2013-2024 OpenMV LLC. All rights reserved.
|
||||
# https://github.com/openmv/openmv/blob/master/LICENSE
|
||||
#
|
||||
# This example shows off using the genx320 event camera from Prophesee.
|
||||
|
||||
import sensor
|
||||
import time
|
||||
|
||||
sensor.reset()
|
||||
sensor.set_pixformat(sensor.GRAYSCALE) # Must always be grayscale.
|
||||
sensor.set_framesize(sensor.B320X320) # Must always be 320x320.
|
||||
|
||||
clock = time.clock()
|
||||
|
||||
while True:
|
||||
clock.tick()
|
||||
|
||||
img = sensor.snapshot()
|
||||
# img.median(1) # noise cleanup.
|
||||
|
||||
print(clock.fps())
|
||||
@ -0,0 +1,30 @@
|
||||
# This work is licensed under the MIT license.
|
||||
# Copyright (c) 2013-2024 OpenMV LLC. All rights reserved.
|
||||
# https://github.com/openmv/openmv/blob/master/LICENSE
|
||||
#
|
||||
# This example shows off using the genx320 event camera from Prophesee.
|
||||
|
||||
import sensor
|
||||
import time
|
||||
|
||||
sensor.reset()
|
||||
sensor.set_pixformat(sensor.GRAYSCALE) # Must always be grayscale.
|
||||
sensor.set_framesize(sensor.B320X320) # Must always be 320x320.
|
||||
|
||||
clock = time.clock()
|
||||
|
||||
while True:
|
||||
clock.tick()
|
||||
|
||||
img = sensor.snapshot()
|
||||
# img.median(1) # noise cleanup.
|
||||
|
||||
blobs = img.find_blobs(
|
||||
[(120, 130)], invert=True, pixels_threshold=10, area_threshold=100, merge=True
|
||||
)
|
||||
|
||||
for blob in blobs:
|
||||
img.draw_rectangle(blob.rect(), color=(255, 255, 255))
|
||||
img.draw_cross(blob.cx(), blob.cy(), color=(0, 0, 0))
|
||||
|
||||
print(clock.fps())
|
||||
@ -54,6 +54,7 @@ OMV_DIR=omv
|
||||
CUBEAI_DIR=stm32cubeai
|
||||
CMSIS_DIR=hal/cmsis
|
||||
MICROPY_DIR=micropython
|
||||
GENX320_DIR=drivers/genx320
|
||||
LEPTON_DIR=drivers/lepton
|
||||
LSM6DS3_DIR=drivers/lsm6ds3
|
||||
LSM6DSOX_DIR=drivers/lsm6dsox
|
||||
|
||||
202
src/drivers/genx320/LICENSE
Normal file
202
src/drivers/genx320/LICENSE
Normal file
@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright Prophesee S.A.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
28
src/drivers/genx320/Makefile
Normal file
28
src/drivers/genx320/Makefile
Normal file
@ -0,0 +1,28 @@
|
||||
###
|
||||
# Copyright (c) Prophesee S.A.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
# on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and limitations under the License.
|
||||
###
|
||||
|
||||
SRCS = $(wildcard src/*.c)
|
||||
OBJS = $(addprefix $(BUILD)/, $(SRCS:.c=.o))
|
||||
OBJ_DIRS = $(sort $(dir $(OBJS)))
|
||||
|
||||
all: | $(OBJ_DIRS) $(OBJS)
|
||||
$(OBJ_DIRS):
|
||||
$(MKDIR) -p $@
|
||||
|
||||
$(BUILD)/%.o : %.c
|
||||
$(ECHO) "CC $<"
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
$(BUILD)/%.o : %.s
|
||||
$(ECHO) "AS $<"
|
||||
$(AS) $(AFLAGS) $< -o $@
|
||||
|
||||
-include $(OBJS:%.o=%.d)
|
||||
23
src/drivers/genx320/include/aer.h
Normal file
23
src/drivers/genx320/include/aer.h
Normal file
@ -0,0 +1,23 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @attention
|
||||
* Copyright (c) Prophesee S.A.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef INC_AER_H_
|
||||
#define INC_AER_H_
|
||||
|
||||
#define __AER_Y(__VAL__) ((__VAL__ ) & 0x1FFU)
|
||||
#define __AER_X(__VAL__) ((__VAL__ >> 9) & 0x1FFU)
|
||||
#define __AER_P(__VAL__) ((__VAL__ >> 18 ) & 0x1U)
|
||||
|
||||
#endif /* INC_AER_H_ */
|
||||
32
src/drivers/genx320/include/evt_2_0.h
Normal file
32
src/drivers/genx320/include/evt_2_0.h
Normal file
@ -0,0 +1,32 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @attention
|
||||
* Copyright (c) Prophesee S.A.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef INC_EVT_2_0_H_
|
||||
#define INC_EVT_2_0_H_
|
||||
|
||||
#define __EVT20_TYPE(__VAL__) ((__VAL__ >> 28)& 0xFU)
|
||||
#define __EVT20_TS(__VAL__) ((__VAL__ >> 22) & 0xF3U)
|
||||
#define __EVT20_X(__VAL__) ((__VAL__ >> 11) & 0x7FFU)
|
||||
#define __EVT20_Y(__VAL__) ((__VAL__ ) & 0x7FFU)
|
||||
#define __EVT20_TIME_HIGH(__VAL__) ((__VAL__ ) & 0xFFFFFFFU)
|
||||
|
||||
#define TD_LOW 0x0U /*!< EVT2.0 TD Event, Decrease in illumination */
|
||||
#define TD_HIGH 0x1U /*!< EVT2.0 TD Event, Increase in illumination */
|
||||
#define EV_TIME_HIGH 0x8U /*!< Timer High bits */
|
||||
#define EXT_TRIGGER 0xAU /*!< External triggers */
|
||||
#define OTHERS 0xEU /*!< To be used in extension in the event types */
|
||||
#define CONTINUED 0xFU /*!< Extra data to previous events */
|
||||
|
||||
#endif /* INC_EVT_2_0_H_ */
|
||||
45
src/drivers/genx320/include/firmware.h
Normal file
45
src/drivers/genx320/include/firmware.h
Normal file
@ -0,0 +1,45 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file firmware.h
|
||||
* @author PSEE Applications Team
|
||||
* @brief RISC-V Firmwares
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
* Copyright (c) Prophesee S.A.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
#ifndef APPLICATION_USER_FIRMWARE_H_
|
||||
#define APPLICATION_USER_FIRMWARE_H_
|
||||
|
||||
/* Standard Includes */
|
||||
#include <stdint.h>
|
||||
|
||||
/* User Includes */
|
||||
#include "psee_genx320.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Low power wakeup application Firmware */
|
||||
extern const size_t fw_esp_wakeup_size;
|
||||
extern const Firmware fw_esp_wakeup[];
|
||||
|
||||
/* Led tracking application Firmware */
|
||||
extern const size_t fw_led_tracking_size;
|
||||
extern const Firmware fw_led_tracking[];
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* APPLICATION_USER_FIRMWARE_H_ */
|
||||
8592
src/drivers/genx320/include/genx320_all_pub_registers.h
Normal file
8592
src/drivers/genx320/include/genx320_all_pub_registers.h
Normal file
File diff suppressed because it is too large
Load Diff
233
src/drivers/genx320/include/psee_genx320.h
Normal file
233
src/drivers/genx320/include/psee_genx320.h
Normal file
@ -0,0 +1,233 @@
|
||||
/**********************************************************************************************************************
|
||||
* Copyright (c) Prophesee S.A. *
|
||||
* *
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); *
|
||||
* you may not use this file except in compliance with the License. *
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 *
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed *
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
|
||||
* See the License for the specific language governing permissions and limitations under the License. *
|
||||
**********************************************************************************************************************/
|
||||
|
||||
#ifndef __GENX320_H
|
||||
#define __GENX320_H
|
||||
|
||||
/* Standard Includes */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
|
||||
/* User Includes*/
|
||||
#include "genx320_all_pub_registers.h"
|
||||
#include "psee_issd.h"
|
||||
|
||||
/* Sensor I2C Address */
|
||||
#define I2C_ADDRESS 0x3C
|
||||
|
||||
/* Sensor Chip ID */
|
||||
#define SAPHIR_CHIP_ID 0x0014
|
||||
#define SAPHIR_ES_ID 0x30501C01
|
||||
#define SAPHIR_MP_ID 0xB0602003
|
||||
|
||||
/* Memory Bank Defines */
|
||||
#define IMEM_START (0x00200000UL)
|
||||
#define DMEM_START (0x00300000UL)
|
||||
#define MEM_BANK_SELECT (0x0000F800UL)
|
||||
#define MEM_BANK_MEM0 (0x0000F900UL)
|
||||
|
||||
/* RISC-V Defines */
|
||||
#define RISC_BOOT_DONE 0x0ABCDEF
|
||||
|
||||
/**
|
||||
* @brief RISCV FW status structures definition
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
fw_OK = 0U,
|
||||
fw_Error_InvalidSize = 1U,
|
||||
fw_Error_InvalidPointer = 2U,
|
||||
fw_Flash_Error = 3U,
|
||||
fw_Start_Error = 4U,
|
||||
fw_Flashed_Already = 5U
|
||||
} FW_StatusTypeDef;
|
||||
|
||||
/**
|
||||
* @brief Shadow register status structures definition
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
shadow_valid = 0U,
|
||||
shadow_not_valid = 01
|
||||
} Shadow_StatusTypeDef;
|
||||
|
||||
/**
|
||||
* @brief Structure to hold the parameters for the bias
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t pr;
|
||||
uint8_t fo;
|
||||
uint8_t fes;
|
||||
uint8_t hpf;
|
||||
uint8_t diff_on;
|
||||
uint8_t diff;
|
||||
uint8_t diff_off;
|
||||
uint8_t inv;
|
||||
uint8_t refr;
|
||||
uint8_t invp;
|
||||
uint8_t req_pu;
|
||||
uint8_t sm_pdy;
|
||||
}BIAS_Params_t;
|
||||
|
||||
/**
|
||||
* @brief Structure to hold the border value for the Activity Map
|
||||
*/
|
||||
typedef struct {
|
||||
uint16_t x0;
|
||||
uint16_t x1;
|
||||
uint16_t x2;
|
||||
uint16_t x3;
|
||||
uint16_t x4;
|
||||
uint16_t y0;
|
||||
uint16_t y1;
|
||||
uint16_t y2;
|
||||
uint16_t y3;
|
||||
uint16_t y4;
|
||||
}AM_Borders_t;
|
||||
|
||||
/**
|
||||
* @brief Structure to hold the risc-v firmware
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t address;
|
||||
uint32_t value;
|
||||
} Firmware;
|
||||
|
||||
/**
|
||||
* @brief Structure to hold AFK Invalidation
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t df_wait_time;
|
||||
uint32_t df_timeout;
|
||||
} Invalidation;
|
||||
|
||||
/**
|
||||
* @brief Structure to hold the sensor clock frequencies
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t in_freq;
|
||||
uint32_t sys_freq;
|
||||
uint32_t evt_icn_freq;
|
||||
uint32_t cpu_ss_freq;
|
||||
uint32_t pll_in_freq;
|
||||
uint32_t pll_vco_freq;
|
||||
uint32_t phy_freq;
|
||||
uint32_t mipi_freq;
|
||||
uint32_t esc_freq;
|
||||
} clk_freq_dict;
|
||||
|
||||
/**
|
||||
* @brief Sensor Boot mode structure definition
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
ROM_BOOT = 0U,
|
||||
IMEM_BOOT = 1U
|
||||
} Boot_Mode;
|
||||
|
||||
/**
|
||||
* @brief Enum to hold the parameters for the bias
|
||||
*/
|
||||
typedef enum {
|
||||
PR,
|
||||
FO,
|
||||
FES,
|
||||
HPF,
|
||||
DIFF_ON,
|
||||
DIFF,
|
||||
DIFF_OFF,
|
||||
INV,
|
||||
REFR,
|
||||
INVP,
|
||||
REQ_PU,
|
||||
SM_PDY,
|
||||
} BIAS_Name_t;
|
||||
|
||||
/* Constants/Variables to hold default bias */
|
||||
extern const BIAS_Params_t genx320es_default_biases;
|
||||
extern const BIAS_Params_t genx320mp_default_biases;
|
||||
extern BIAS_Params_t genx320_default_biases;
|
||||
|
||||
/* Variable to hold default borders for Activity map */
|
||||
extern AM_Borders_t genx320mp_default_am_borders;
|
||||
|
||||
/* ISSD sequences. */
|
||||
extern const struct issd dcmi_evt;
|
||||
extern const struct issd dcmi_histo;
|
||||
extern const struct issd *current_issd;
|
||||
|
||||
/* Variable to hold the current boot mode */
|
||||
extern Boot_Mode genx320_boot_mode;
|
||||
|
||||
/* Sensor Register Manipulation Functions */
|
||||
extern void psee_sensor_read(uint16_t register_address, uint32_t *buf);
|
||||
extern void psee_sensor_write(uint16_t register_address, uint32_t register_data);
|
||||
|
||||
/* Sensor Bring Up Functions */
|
||||
extern void psee_sensor_init(const struct issd *);
|
||||
extern void psee_sensor_destroy(const struct issd *);
|
||||
extern void psee_sensor_start(const struct issd *);
|
||||
extern void psee_sensor_stop(const struct issd *);
|
||||
extern Boot_Mode psee_detect_boot_mode();
|
||||
extern const struct issd *psee_open_evt();
|
||||
extern void psee_sensor_set_bias(BIAS_Name_t bias, uint32_t val);
|
||||
extern void psee_sensor_set_biases(const BIAS_Params_t *bias);
|
||||
extern void psee_sensor_set_CPI_EVT20();
|
||||
extern void psee_sensor_set_CPI_HISTO();
|
||||
extern void psee_sensor_set_flip(uint32_t flip_x, uint32_t flip_y);
|
||||
extern void psee_sensor_powerdown();
|
||||
|
||||
/* Operating Mode Control Functions */
|
||||
extern void psee_PM3C_config();
|
||||
extern void psee_PM2_config();
|
||||
|
||||
/* Firmware flashing functions */
|
||||
extern FW_StatusTypeDef psee_write_firmware(const Firmware *firmwareArray, uint32_t n_bytes);
|
||||
extern FW_StatusTypeDef psee_start_firmware(Boot_Mode boot_mode);
|
||||
extern FW_StatusTypeDef psee_reset_firmware(Boot_Mode boot_mode);
|
||||
|
||||
/* Mailbox Communication Functions */
|
||||
extern uint32_t psee_get_mbx_cmd_ptr();
|
||||
extern uint32_t psee_get_mbx_misc();
|
||||
extern uint32_t psee_get_mbx_status_ptr();
|
||||
extern void psee_set_mbx_cmd_ptr(uint32_t val);
|
||||
extern void psee_set_mbx_misc(uint32_t val);
|
||||
extern void psee_set_mbx_status_ptr(uint32_t val);
|
||||
|
||||
/* ROI Access Functions */
|
||||
extern void psee_write_ROI_X(uint32_t offset, uint32_t val);
|
||||
extern void psee_write_ROI_Y(uint32_t offset, uint32_t val);
|
||||
extern void psee_write_ROI_CTRL(uint32_t val);
|
||||
|
||||
/* RISC-V Debugger Functions */
|
||||
extern uint32_t psee_mbx_read_uint32();
|
||||
extern void psee_decode_debugger();
|
||||
extern uint32_t psee_sensor_read_dmem(uint32_t address);
|
||||
extern uint32_t psee_sensor_read_imem(uint32_t address);
|
||||
|
||||
/* Statistics Register Read Functions */
|
||||
extern void psee_read_ro_lp_evt_cnt(uint32_t *p_data);
|
||||
extern uint32_t psee_read_ro_evt_cd_cnt();
|
||||
extern uint32_t psee_read_afk_flicker_evt_cnt();
|
||||
extern uint32_t psee_read_afk_total_evt_cnt();
|
||||
|
||||
/* Activity Map Configuration Functions */
|
||||
extern void psee_configure_activity_map();
|
||||
extern void psee_set_default_XY_borders(AM_Borders_t *border);
|
||||
|
||||
/* AFK Configuration Functions */
|
||||
extern void psee_enable_afk(uint16_t min_freq, uint16_t max_freq);
|
||||
extern void psee_disable_afk();
|
||||
|
||||
#endif
|
||||
63
src/drivers/genx320/include/psee_issd.h
Normal file
63
src/drivers/genx320/include/psee_issd.h
Normal file
@ -0,0 +1,63 @@
|
||||
/**********************************************************************************************************************
|
||||
* Copyright (c) Prophesee S.A. *
|
||||
* *
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); *
|
||||
* you may not use this file except in compliance with the License. *
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 *
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed *
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
|
||||
* See the License for the specific language governing permissions and limitations under the License. *
|
||||
**********************************************************************************************************************/
|
||||
|
||||
#ifndef __PSEE_ISSD_H
|
||||
#define __PSEE_ISSD_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifndef ARRAY_SIZE
|
||||
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||
#endif
|
||||
|
||||
enum op_id {
|
||||
READ,
|
||||
WRITE,
|
||||
DELAY
|
||||
};
|
||||
|
||||
struct read_op {
|
||||
uint16_t addr;
|
||||
uint32_t data;
|
||||
uint32_t mask;
|
||||
};
|
||||
|
||||
struct write_op {
|
||||
uint16_t addr;
|
||||
uint32_t data;
|
||||
};
|
||||
|
||||
struct delay_op {
|
||||
uint32_t us;
|
||||
};
|
||||
|
||||
struct reg_op {
|
||||
enum op_id op;
|
||||
union {
|
||||
struct read_op read;
|
||||
struct write_op write;
|
||||
struct delay_op delay;
|
||||
} args;
|
||||
};
|
||||
|
||||
struct sequence {
|
||||
const struct reg_op *ops;
|
||||
size_t len;
|
||||
};
|
||||
|
||||
struct issd {
|
||||
const struct sequence init;
|
||||
const struct sequence start;
|
||||
const struct sequence stop;
|
||||
const struct sequence destroy;
|
||||
};
|
||||
#endif
|
||||
9140
src/drivers/genx320/src/firmware.c
Normal file
9140
src/drivers/genx320/src/firmware.c
Normal file
File diff suppressed because it is too large
Load Diff
161
src/drivers/genx320/src/genx320_issd_cpi.c
Normal file
161
src/drivers/genx320/src/genx320_issd_cpi.c
Normal file
@ -0,0 +1,161 @@
|
||||
/**********************************************************************************************************************
|
||||
* Copyright (c) Prophesee S.A. *
|
||||
* *
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); *
|
||||
* you may not use this file except in compliance with the License. *
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 *
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed *
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
|
||||
* See the License for the specific language governing permissions and limitations under the License. *
|
||||
* *
|
||||
* This is an automatically generated file *
|
||||
**********************************************************************************************************************/
|
||||
|
||||
#ifndef __ISSD_CPI_H
|
||||
#define __ISSD_CPI_H
|
||||
|
||||
#include "psee_issd.h"
|
||||
|
||||
static const struct reg_op dcmi_init_seq[] = {
|
||||
{.op = WRITE, .args = {.write = {0x9008UL, 0x00000320}} }, // saphir/ro/time_base_ctrl Write fields: time_base_enable
|
||||
{.op = WRITE, .args = {.write = {0x9008UL, 0x00010320}} }, // saphir/ro/time_base_ctrl Write fields: time_base_srst
|
||||
{.op = WRITE, .args = {.write = {0x020CUL, 0x00000015}} }, // saphir/rtc_clk_ctrl Write fields: rtc_clk_en|rtc_clk_div
|
||||
{.op = WRITE, .args = {.write = {0x0204UL, 0x00004D6C}} }, // saphir/sys_clk_ctrl Write fields: sys_clk_auto_mode
|
||||
{.op = WRITE, .args = {.write = {0x0210UL, 0x00000C00}} }, // saphir/evt_icn_clk_ctrl Write fields: ro_clk_en|esp_clk_en
|
||||
{.op = WRITE, .args = {.write = {0x9008UL, 0x000000A0}} }, // saphir/ro/time_base_ctrl Write fields: us_counter_max
|
||||
{.op = WRITE, .args = {.write = {0x00B8UL, 0x00000040}} }, // saphir/sram_initn Write fields: cpi_initn
|
||||
{.op = WRITE, .args = {.write = {0x00C0UL, 0x00000078}} }, // saphir/sram_pd1 Write fields: cpi_pd
|
||||
{.op = WRITE, .args = {.write = {0x800CUL, 0x0001040A}} }, // saphir/cpi/packet_time_control Write fields: packet_period
|
||||
{.op = WRITE, .args = {.write = {0x8008UL, 0x00000400}} }, // saphir/cpi/packet_size_control Write fields: packet_size
|
||||
{.op = WRITE, .args = {.write = {0x8010UL, 0x00000140}} }, // saphir/cpi/frame_size_control Write fields: frame_size
|
||||
{.op = WRITE, .args = {.write = {0x8000UL, 0x0001EFA1}} }, // saphir/cpi/pipeline_control Write fields: enable|clk_out_en|clk_control_inversion|packet_fixed_size_enable|packet_fixed_rate_enable|frame_fixed_size_enable|output_if_mode|output_data_format|output_width|clk_out_gating_enable
|
||||
{.op = WRITE, .args = {.write = {0x8000UL, 0x0001FFA1}} }, // saphir/cpi/pipeline_control Write fields: clk_out_gating_enable
|
||||
{.op = WRITE, .args = {.write = {0xE000UL, 0x00000005}} }, // saphir/nfl/pipeline_control Write fields: enable|bypass
|
||||
{.op = WRITE, .args = {.write = {0xC000UL, 0x00000005}} }, // saphir/afk/pipeline_control Write fields: enable|bypass
|
||||
{.op = WRITE, .args = {.write = {0xD000UL, 0x00000005}} }, // saphir/stc/pipeline_control Write fields: enable|bypass
|
||||
{.op = WRITE, .args = {.write = {0x6000UL, 0x00000005}} }, // saphir/erc/pipeline_control Write fields: enable|bypass
|
||||
{.op = WRITE, .args = {.write = {0x60A0UL, 0x00000000}} }, // saphir/erc/delay_fifo_flush_and_bypass Write fields: en
|
||||
{.op = WRITE, .args = {.write = {0x704CUL, 0x000007D0}} }, // saphir/edf/output_interface_control
|
||||
{.op = WRITE, .args = {.write = {0x7100UL, 0x00010280}} }, // saphir/edf/external_output_adapter Write fields: qos_timeout|atomic_qos_mode
|
||||
{.op = WRITE, .args = {.write = {0x7044UL, 0x00000002}} }, // saphir/edf/control Write fields: format|endianness
|
||||
{.op = WRITE, .args = {.write = {0x7048UL, 0x00000000}} }, // saphir/edf/event_injection Write fields: sysmon_end_of_frame_en
|
||||
{.op = WRITE, .args = {.write = {0x7000UL, 0x00000001}} }, // saphir/edf/pipeline_control Write fields: enable|bypass
|
||||
{.op = WRITE, .args = {.write = {0x9008UL, 0x000000A4}} }, // saphir/ro/time_base_ctrl Write fields: time_base_mode|external_mode|external_mode_enable|us_counter_max
|
||||
{.op = WRITE, .args = {.write = {0x9000UL, 0x00000200}} }, // saphir/ro/readout_ctrl Write fields: ro_digital_pipe_en
|
||||
{.op = WRITE, .args = {.write = {0x001CUL, 0x00000004}} }, // saphir/dig_soft_reset Write fields: analog_rstn
|
||||
{.op = WRITE, .args = {.write = {0xA000UL, 0x00000406}} }, // saphir/ldo/bg Write fields: bg_en|bg_buf_en|bg_bypass|bg_chk|bg_adj
|
||||
{.op = WRITE, .args = {.write = {0xA01CUL, 0x0007641F}} }, // saphir/ldo/pmu Write fields: pmu_icgm_en|pmu_v2i_en|pmu_v2i_cal_en|mipi_v2i_en
|
||||
{.op = WRITE, .args = {.write = {0xB030UL, 0x00000010}} }, // saphir/mipi_csi/power Write fields: cur_en
|
||||
{.op = WRITE, .args = {.write = {0x004CUL, 0x00204E22}} }, // saphir/adc_control Write fields: adc_clk_en
|
||||
{.op = DELAY, .args = {.delay = {1000}} }, // us
|
||||
{.op = WRITE, .args = {.write = {0xA01CUL, 0x0007E41F}} }, // saphir/ldo/pmu Write fields: pmu_v2i_en|pmu_v2i_adj|pmu_v2i_cal_en
|
||||
{.op = DELAY, .args = {.delay = {1000}} }, // us
|
||||
{.op = READ, .args = {.read = {0xA01CUL, 0x0014E41F}} }, // saphir/ldo/pmu Read fields: pmu_v2i_cal_done_dyn
|
||||
{.op = WRITE, .args = {.write = {0x004CUL, 0x00204E20}} }, // saphir/adc_control Write fields: adc_clk_en
|
||||
{.op = WRITE, .args = {.write = {0x1218UL, 0x00000111}} }, // saphir/bias/bgen_cgm_sub Write fields: bias_cgm_sub_en
|
||||
{.op = WRITE, .args = {.write = {0x1218UL, 0x00000111}} }, // saphir/bias/bgen_cgm_sub Write fields: bias_cgm_sub_trim
|
||||
{.op = WRITE, .args = {.write = {0x1218UL, 0x00000111}} }, // saphir/bias/bgen_cgm_sub Write fields: bias_cgm_sub_slp_ctl
|
||||
{.op = DELAY, .args = {.delay = {1000}} }, // us
|
||||
{.op = WRITE, .args = {.write = {0x1220UL, 0x00000001}} }, // saphir/bias/bgen_cc_en Write fields: bias_cc_hv_en
|
||||
{.op = DELAY, .args = {.delay = {1000}} }, // us
|
||||
{.op = WRITE, .args = {.write = {0xA008UL, 0x00008085}} }, // saphir/ldo/ldo_lv Write fields: ldo_lv_en|ldo_lv_climit_en|ldo_lv_climit|ldo_lv_ind_en|ldo_lv_adj|ldo_lv_ind_vth_ok|ldo_lv_ind_vth_bo
|
||||
{.op = WRITE, .args = {.write = {0xA004UL, 0x00008025}} }, // saphir/ldo/ldo_hv Write fields: ldo_hv_en|ldo_hv_climit_en|ldo_hv_climit|ldo_hv_ind_en|ldo_hv_adj|ldo_hv_ind_vth_ok|ldo_hv_ind_vth_bo
|
||||
{.op = DELAY, .args = {.delay = {1000}} }, // us
|
||||
{.op = WRITE, .args = {.write = {0x0070UL, 0x0000055F}} }, // saphir/cp_ctrl Write fields: cp_en|cp_clk_en|cp_adj|cp_cfly|cp_mphase|cp_clk_divider
|
||||
{.op = DELAY, .args = {.delay = {1000}} }, // us
|
||||
{.op = WRITE, .args = {.write = {0x1220UL, 0x00000003}} }, // saphir/bias/bgen_cc_en Write fields: bias_cc_lv_en
|
||||
{.op = DELAY, .args = {.delay = {1000}} }, // us
|
||||
{.op = WRITE, .args = {.write = {0x1208UL, 0x00000030}} }, // saphir/bias/bgen_ctrl Write fields: bias_rstn_hv|bias_rstn_lv
|
||||
{.op = DELAY, .args = {.delay = {1000}} }, // us
|
||||
{.op = WRITE, .args = {.write = {0x0000UL, 0x00000420}} }, // saphir/roi_ctrl Write fields: roi_td_en|roi_td_shadow_trigger
|
||||
{.op = WRITE, .args = {.write = {0x0000UL, 0x00000400}} }, // saphir/roi_ctrl Write fields: roi_td_en|roi_td_shadow_trigger
|
||||
{.op = WRITE, .args = {.write = {0x0000UL, 0x00000802}} }, // saphir/roi_ctrl Write fields: roi_td_en|px_sw_rstn|px_roi_halt_programming
|
||||
{.op = WRITE, .args = {.write = {0x0000UL, 0x00000822}} }, // saphir/roi_ctrl Write fields: roi_td_en|roi_td_shadow_trigger
|
||||
{.op = WRITE, .args = {.write = {0x0000UL, 0x00000802}} }, // saphir/roi_ctrl Write fields: roi_td_en|roi_td_shadow_trigger
|
||||
{.op = WRITE, .args = {.write = {0x3000UL, 0x00000000}} }, // saphir/roi/td_roi_y00
|
||||
{.op = WRITE, .args = {.write = {0x3004UL, 0x00000000}} }, // saphir/roi/td_roi_y01
|
||||
{.op = WRITE, .args = {.write = {0x3008UL, 0x00000000}} }, // saphir/roi/td_roi_y02
|
||||
{.op = WRITE, .args = {.write = {0x300CUL, 0x00000000}} }, // saphir/roi/td_roi_y03
|
||||
{.op = WRITE, .args = {.write = {0x3010UL, 0x00000000}} }, // saphir/roi/td_roi_y04
|
||||
{.op = WRITE, .args = {.write = {0x3014UL, 0x00000000}} }, // saphir/roi/td_roi_y05
|
||||
{.op = WRITE, .args = {.write = {0x3018UL, 0x00000000}} }, // saphir/roi/td_roi_y06
|
||||
{.op = WRITE, .args = {.write = {0x301CUL, 0x00000000}} }, // saphir/roi/td_roi_y07
|
||||
{.op = WRITE, .args = {.write = {0x3020UL, 0x00000000}} }, // saphir/roi/td_roi_y08
|
||||
{.op = WRITE, .args = {.write = {0x3024UL, 0x00000000}} }, // saphir/roi/td_roi_y09
|
||||
{.op = WRITE, .args = {.write = {0x3028UL, 0x00000000}} }, // saphir/roi/td_roi_y10
|
||||
{.op = WRITE, .args = {.write = {0x0000UL, 0x00000822}} }, // saphir/roi_ctrl Write fields: roi_td_shadow_trigger
|
||||
{.op = WRITE, .args = {.write = {0x0000UL, 0x00000802}} }, // saphir/roi_ctrl Write fields: roi_td_shadow_trigger
|
||||
{.op = WRITE, .args = {.write = {0x2000UL, 0x00000000}} }, // saphir/roi/td_roi_x00 Write fields: effective
|
||||
{.op = WRITE, .args = {.write = {0x2004UL, 0x00000000}} }, // saphir/roi/td_roi_x01 Write fields: effective
|
||||
{.op = WRITE, .args = {.write = {0x2008UL, 0x00000000}} }, // saphir/roi/td_roi_x02 Write fields: effective
|
||||
{.op = WRITE, .args = {.write = {0x200CUL, 0x00000000}} }, // saphir/roi/td_roi_x03 Write fields: effective
|
||||
{.op = WRITE, .args = {.write = {0x2010UL, 0x00000000}} }, // saphir/roi/td_roi_x04 Write fields: effective
|
||||
{.op = WRITE, .args = {.write = {0x2014UL, 0x00000000}} }, // saphir/roi/td_roi_x05 Write fields: effective
|
||||
{.op = WRITE, .args = {.write = {0x2018UL, 0x00000000}} }, // saphir/roi/td_roi_x06 Write fields: effective
|
||||
{.op = WRITE, .args = {.write = {0x201CUL, 0x00000000}} }, // saphir/roi/td_roi_x07 Write fields: effective
|
||||
{.op = WRITE, .args = {.write = {0x2020UL, 0x00000000}} }, // saphir/roi/td_roi_x08 Write fields: effective
|
||||
{.op = WRITE, .args = {.write = {0x2024UL, 0x00000000}} }, // saphir/roi/td_roi_x09 Write fields: effective
|
||||
{.op = WRITE, .args = {.write = {0x3000UL, 0xFFFFFFFF}} }, // saphir/roi/td_roi_y00 Write fields: effective
|
||||
{.op = WRITE, .args = {.write = {0x3004UL, 0xFFFFFFFF}} }, // saphir/roi/td_roi_y01 Write fields: effective
|
||||
{.op = WRITE, .args = {.write = {0x3008UL, 0xFFFFFFFF}} }, // saphir/roi/td_roi_y02 Write fields: effective
|
||||
{.op = WRITE, .args = {.write = {0x300CUL, 0xFFFFFFFF}} }, // saphir/roi/td_roi_y03 Write fields: effective
|
||||
{.op = WRITE, .args = {.write = {0x3010UL, 0xFFFFFFFF}} }, // saphir/roi/td_roi_y04 Write fields: effective
|
||||
{.op = WRITE, .args = {.write = {0x3014UL, 0xFFFFFFFF}} }, // saphir/roi/td_roi_y05 Write fields: effective
|
||||
{.op = WRITE, .args = {.write = {0x3018UL, 0xFFFFFFFF}} }, // saphir/roi/td_roi_y06 Write fields: effective
|
||||
{.op = WRITE, .args = {.write = {0x301CUL, 0xFFFFFFFF}} }, // saphir/roi/td_roi_y07 Write fields: effective
|
||||
{.op = WRITE, .args = {.write = {0x3020UL, 0xFFFFFFFF}} }, // saphir/roi/td_roi_y08 Write fields: effective
|
||||
{.op = WRITE, .args = {.write = {0x3024UL, 0xFFFFFFFF}} }, // saphir/roi/td_roi_y09 Write fields: effective
|
||||
{.op = WRITE, .args = {.write = {0x0000UL, 0x00000822}} }, // saphir/roi_ctrl Write fields: roi_td_shadow_trigger
|
||||
{.op = WRITE, .args = {.write = {0x0000UL, 0x00000802}} }, // saphir/roi_ctrl Write fields: roi_td_shadow_trigger
|
||||
{.op = DELAY, .args = {.delay = {1000}} }, // us
|
||||
{.op = WRITE, .args = {.write = {0x1000UL, 0x0301003D}} }, // saphir/bias/bias_pr_hv0 Write fields: bias_en|bias_ctl
|
||||
{.op = WRITE, .args = {.write = {0x1004UL, 0x03010027}} }, // saphir/bias/bias_fo_hv0 Write fields: bias_en|bias_ctl
|
||||
{.op = WRITE, .args = {.write = {0x1008UL, 0x0101003F}} }, // saphir/bias/bias_fes_hv0 Write fields: bias_en|bias_ctl
|
||||
{.op = WRITE, .args = {.write = {0x1100UL, 0x03010000}} }, // saphir/bias/bias_hpf_lv0 Write fields: bias_en|bias_ctl
|
||||
{.op = WRITE, .args = {.write = {0x1104UL, 0x01090018}} }, // saphir/bias/bias_diff_on_lv0 Write fields: bias_en|bias_ctl
|
||||
{.op = WRITE, .args = {.write = {0x1108UL, 0x01010033}} }, // saphir/bias/bias_diff_lv0 Write fields: bias_en|bias_ctl
|
||||
{.op = WRITE, .args = {.write = {0x110CUL, 0x01090013}} }, // saphir/bias/bias_diff_off_lv0 Write fields: bias_en|bias_ctl
|
||||
{.op = WRITE, .args = {.write = {0x1110UL, 0x01010039}} }, // saphir/bias/bias_inv_lv0 Write fields: bias_en|bias_ctl
|
||||
{.op = WRITE, .args = {.write = {0x1114UL, 0x03010052}} }, // saphir/bias/bias_refr_lv0 Write fields: bias_en|bias_ctl
|
||||
{.op = WRITE, .args = {.write = {0x1118UL, 0x03010042}} }, // saphir/bias/bias_invp_lv0 Write fields: bias_en|bias_ctl
|
||||
{.op = WRITE, .args = {.write = {0x111CUL, 0x03000074}} }, // saphir/bias/bias_req_pu_lv0 Write fields: bias_en|bias_ctl
|
||||
{.op = WRITE, .args = {.write = {0x1120UL, 0x010000A4}} }, // saphir/bias/bias_sm_pdy_lv0 Write fields: bias_en|bias_ctl
|
||||
{.op = WRITE, .args = {.write = {0x1208UL, 0x00000035}} }, // saphir/bias/bgen_ctrl Write fields: burst_transfer_hv_bank_0|burst_transfer_lv_bank_0
|
||||
{.op = WRITE, .args = {.write = {0x0000UL, 0x00000802}} } // saphir/roi_ctrl Write fields: roi_td_en
|
||||
};
|
||||
static const struct reg_op dcmi_start_seq[] = {
|
||||
{.op = WRITE, .args = {.write = {0x9028UL, 0x00000000}} }, // saphir/ro/ro_lp_ctrl Write fields: lp_output_disable
|
||||
{.op = WRITE, .args = {.write = {0x9008UL, 0x000000A5}} }, // saphir/ro/time_base_ctrl Write fields: time_base_enable
|
||||
{.op = DELAY, .args = {.delay = {1000}} }, // us
|
||||
{.op = WRITE, .args = {.write = {0x002CUL, 0x0022C724}} }, // saphir/ro_td_ctrl Write fields: ro_td_ack_y_rstn|ro_td_arb_y_rstn|ro_td_addr_y_rstn|ro_td_sendreq_y_rstn
|
||||
{.op = WRITE, .args = {.write = {0x0000UL, 0x00000C02}} }, // saphir/roi_ctrl Write fields: roi_td_en|px_sw_rstn
|
||||
{.op = DELAY, .args = {.delay = {1000}} } // us
|
||||
};
|
||||
static const struct reg_op dcmi_stop_seq[] = {
|
||||
{.op = WRITE, .args = {.write = {0x0000UL, 0x00000802}} }, // saphir/roi_ctrl Write fields: roi_td_en|px_sw_rstn
|
||||
{.op = WRITE, .args = {.write = {0x002CUL, 0x00200624}} }, // saphir/ro_td_ctrl Write fields: ro_td_ack_y_rstn|ro_td_arb_y_rstn|ro_td_addr_y_rstn|ro_td_sendreq_y_rstn
|
||||
{.op = WRITE, .args = {.write = {0x9028UL, 0x00000002}} }, // saphir/ro/ro_lp_ctrl Write fields: lp_output_disable|lp_keep_th
|
||||
{.op = DELAY, .args = {.delay = {1000}} }, // us
|
||||
{.op = WRITE, .args = {.write = {0x9008UL, 0x000000A4}} }, // saphir/ro/time_base_ctrl Write fields: time_base_enable
|
||||
{.op = WRITE, .args = {.write = {0x8000UL, 0x0001FFA2}} }, // saphir/cpi/pipeline_control Write fields: enable|drop_nbackpressure|hot_disable_enable
|
||||
{.op = READ, .args = {.read = {0x8004UL, 0x00000002}} }, // saphir/cpi/pipeline_status Read fields: busy
|
||||
{.op = DELAY, .args = {.delay = {1000}} } // us
|
||||
};
|
||||
static const struct reg_op dcmi_destroy_seq[] = {
|
||||
};
|
||||
const struct issd dcmi_evt = {
|
||||
.init = {
|
||||
.ops = dcmi_init_seq,
|
||||
.len = ARRAY_SIZE(dcmi_init_seq)},
|
||||
.start = {
|
||||
.ops = dcmi_start_seq,
|
||||
.len = ARRAY_SIZE(dcmi_start_seq)},
|
||||
.stop = {
|
||||
.ops = dcmi_stop_seq,
|
||||
.len = ARRAY_SIZE(dcmi_stop_seq)},
|
||||
.destroy = {
|
||||
.ops = dcmi_destroy_seq,
|
||||
.len = ARRAY_SIZE(dcmi_destroy_seq)},
|
||||
};
|
||||
|
||||
#endif
|
||||
1469
src/drivers/genx320/src/psee_genx320.c
Normal file
1469
src/drivers/genx320/src/psee_genx320.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -44,6 +44,7 @@ SRCS += $(addprefix sensors/, \
|
||||
hm01b0.c \
|
||||
hm0360.c \
|
||||
gc2145.c \
|
||||
genx320.c \
|
||||
pag7920.c \
|
||||
paj6100.c \
|
||||
frogeye2020.c \
|
||||
|
||||
@ -48,6 +48,7 @@
|
||||
#define OMV_MT9M114_ENABLE (1)
|
||||
#define OMV_MT9V0XX_ENABLE (1)
|
||||
#define OMV_LEPTON_ENABLE (1)
|
||||
#define OMV_GENX320_ENABLE (1)
|
||||
#define OMV_PAG7920_ENABLE (1)
|
||||
#define OMV_PAJ6100_ENABLE (1)
|
||||
#define OMV_FROGEYE2020_ENABLE (1)
|
||||
|
||||
@ -42,6 +42,7 @@
|
||||
#define OMV_MT9M114_ENABLE (1)
|
||||
#define OMV_MT9V0XX_ENABLE (1)
|
||||
#define OMV_LEPTON_ENABLE (1)
|
||||
#define OMV_GENX320_ENABLE (1)
|
||||
#define OMV_PAG7920_ENABLE (1)
|
||||
#define OMV_PAJ6100_ENABLE (1)
|
||||
#define OMV_FROGEYE2020_ENABLE (1)
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
#define LEPTON_SLV_ADDR (0x54)
|
||||
#define HM0XX0_SLV_ADDR (0x48)
|
||||
#define GC2145_SLV_ADDR (0x78)
|
||||
#define GENX320_SLV_ADDR (0x78)
|
||||
#define FROGEYE2020_SLV_ADDR (0x6E)
|
||||
#define PAG7920_SLV_ADDR (0x80)
|
||||
|
||||
@ -31,6 +32,7 @@
|
||||
#define ON_CHIP_ID (0x00)
|
||||
#define HIMAX_CHIP_ID (0x0001)
|
||||
#define GC_CHIP_ID (0xF0)
|
||||
#define GENX320_CHIP_ID (0x0014)
|
||||
#define PIXART_CHIP_ID (0x00)
|
||||
|
||||
// Chip ID Values
|
||||
@ -57,6 +59,8 @@
|
||||
#define HM01B0_ID (0xB0)
|
||||
#define HM0360_ID (0x60)
|
||||
#define GC2145_ID (0x21)
|
||||
#define GENX320_ID_ES (0x30501C01)
|
||||
#define GENX320_ID_MP (0xB0602003)
|
||||
#define PAG7920_ID (0x7920)
|
||||
#define PAJ6100_ID (0x6100)
|
||||
#define FROGEYE2020_ID (0x2020)
|
||||
@ -211,10 +215,7 @@ typedef void (*frame_cb_t) ();
|
||||
|
||||
typedef struct _sensor sensor_t;
|
||||
typedef struct _sensor {
|
||||
union {
|
||||
uint8_t chip_id; // Sensor ID.
|
||||
uint16_t chip_id_w; // Sensor ID 16 bits.
|
||||
};
|
||||
uint32_t chip_id; // Sensor ID 32 bits.
|
||||
uint8_t slv_addr; // Sensor I2C slave address.
|
||||
|
||||
// Hardware flags (clock polarities, hw capabilities etc..)
|
||||
|
||||
@ -30,6 +30,7 @@
|
||||
#include "paj6100.h"
|
||||
#include "frogeye2020.h"
|
||||
#include "gc2145.h"
|
||||
#include "genx320.h"
|
||||
#include "framebuffer.h"
|
||||
#include "unaligned_memcpy.h"
|
||||
#include "omv_boardconfig.h"
|
||||
@ -190,37 +191,47 @@ static int sensor_detect() {
|
||||
switch (slv_addr) {
|
||||
#if (OMV_OV2640_ENABLE == 1)
|
||||
case OV2640_SLV_ADDR: // Or OV9650.
|
||||
omv_i2c_readb(&sensor.i2c_bus, slv_addr, OV_CHIP_ID, &sensor.chip_id);
|
||||
omv_i2c_readb(&sensor.i2c_bus, slv_addr, OV_CHIP_ID, (uint8_t *) &sensor.chip_id);
|
||||
return slv_addr;
|
||||
#endif // (OMV_OV2640_ENABLE == 1)
|
||||
|
||||
#if (OMV_OV5640_ENABLE == 1) || (OMV_GC2145_ENABLE == 1)
|
||||
// OV5640 and GC2145 share the same I2C address
|
||||
case OV5640_SLV_ADDR: // Or GC2145
|
||||
#if (OMV_OV5640_ENABLE == 1) || (OMV_GC2145_ENABLE == 1) || (OMV_GENX320_ENABLE == 1)
|
||||
// OV5640, GC2145, and GENX320 share the same I2C address
|
||||
case OV5640_SLV_ADDR: // Or GC2145, or GENX320.
|
||||
// Try to read GC2145 chip ID first
|
||||
omv_i2c_readb(&sensor.i2c_bus, slv_addr, GC_CHIP_ID, &sensor.chip_id);
|
||||
omv_i2c_readb(&sensor.i2c_bus, slv_addr, GC_CHIP_ID, (uint8_t *) &sensor.chip_id);
|
||||
if (sensor.chip_id != GC2145_ID) {
|
||||
// If it fails, try reading OV5640 chip ID.
|
||||
omv_i2c_readb2(&sensor.i2c_bus, slv_addr, OV5640_CHIP_ID, &sensor.chip_id);
|
||||
omv_i2c_readb2(&sensor.i2c_bus, slv_addr, OV5640_CHIP_ID, (uint8_t *) &sensor.chip_id);
|
||||
|
||||
#if (OMV_GENX320_ENABLE == 1)
|
||||
if (sensor.chip_id != OV5640_ID) {
|
||||
// If it fails, try reading GENX320 chip ID.
|
||||
uint8_t buf[] = {(GENX320_CHIP_ID >> 8), GENX320_CHIP_ID};
|
||||
omv_i2c_write_bytes(&sensor.i2c_bus, slv_addr, buf, 2, OMV_I2C_XFER_NO_STOP);
|
||||
omv_i2c_read_bytes(&sensor.i2c_bus, slv_addr, (uint8_t *) &sensor.chip_id, 4, OMV_I2C_XFER_NO_FLAGS);
|
||||
sensor.chip_id = __REV(sensor.chip_id);
|
||||
}
|
||||
#endif // (OMV_GENX320_ENABLE == 1)
|
||||
}
|
||||
return slv_addr;
|
||||
#endif // (OMV_OV5640_ENABLE == 1) || (OMV_GC2145_ENABLE == 1)
|
||||
#endif // (OMV_OV5640_ENABLE == 1) || (OMV_GC2145_ENABLE == 1) || (OMV_GENX320_ENABLE == 1)
|
||||
|
||||
#if (OMV_OV7725_ENABLE == 1) || (OMV_OV7670_ENABLE == 1) || (OMV_OV7690_ENABLE == 1)
|
||||
case OV7725_SLV_ADDR: // Or OV7690 or OV7670.
|
||||
omv_i2c_readb(&sensor.i2c_bus, slv_addr, OV_CHIP_ID, &sensor.chip_id);
|
||||
omv_i2c_readb(&sensor.i2c_bus, slv_addr, OV_CHIP_ID, (uint8_t *) &sensor.chip_id);
|
||||
return slv_addr;
|
||||
#endif //(OMV_OV7725_ENABLE == 1) || (OMV_OV7670_ENABLE == 1) || (OMV_OV7690_ENABLE == 1)
|
||||
|
||||
#if (OMV_MT9V0XX_ENABLE == 1)
|
||||
case MT9V0XX_SLV_ADDR:
|
||||
omv_i2c_readw(&sensor.i2c_bus, slv_addr, ON_CHIP_ID, &sensor.chip_id_w);
|
||||
omv_i2c_readw(&sensor.i2c_bus, slv_addr, ON_CHIP_ID, (uint16_t *) &sensor.chip_id);
|
||||
return slv_addr;
|
||||
#endif //(OMV_MT9V0XX_ENABLE == 1)
|
||||
|
||||
#if (OMV_MT9M114_ENABLE == 1)
|
||||
case MT9M114_SLV_ADDR:
|
||||
omv_i2c_readw2(&sensor.i2c_bus, slv_addr, ON_CHIP_ID, &sensor.chip_id_w);
|
||||
omv_i2c_readw2(&sensor.i2c_bus, slv_addr, ON_CHIP_ID, (uint16_t *) &sensor.chip_id);
|
||||
return slv_addr;
|
||||
#endif // (OMV_MT9M114_ENABLE == 1)
|
||||
|
||||
@ -232,20 +243,20 @@ static int sensor_detect() {
|
||||
|
||||
#if (OMV_HM01B0_ENABLE == 1) || (OMV_HM0360_ENABLE == 1)
|
||||
case HM0XX0_SLV_ADDR:
|
||||
omv_i2c_readb2(&sensor.i2c_bus, slv_addr, HIMAX_CHIP_ID, &sensor.chip_id);
|
||||
omv_i2c_readb2(&sensor.i2c_bus, slv_addr, HIMAX_CHIP_ID, (uint8_t *) &sensor.chip_id);
|
||||
return slv_addr;
|
||||
#endif // (OMV_HM01B0_ENABLE == 1) || (OMV_HM0360_ENABLE == 1)
|
||||
|
||||
#if (OMV_FROGEYE2020_ENABLE == 1)
|
||||
case FROGEYE2020_SLV_ADDR:
|
||||
sensor.chip_id_w = FROGEYE2020_ID;
|
||||
sensor.chip_id = FROGEYE2020_ID;
|
||||
return slv_addr;
|
||||
#endif // (OMV_FROGEYE2020_ENABLE == 1)
|
||||
|
||||
#if (OMV_PAG7920_ENABLE == 1)
|
||||
case PAG7920_SLV_ADDR:
|
||||
omv_i2c_readw(&sensor.i2c_bus, slv_addr, ON_CHIP_ID, &sensor.chip_id_w);
|
||||
sensor.chip_id_w = (sensor.chip_id_w << 8) | (sensor.chip_id_w >> 8);
|
||||
omv_i2c_readw(&sensor.i2c_bus, slv_addr, ON_CHIP_ID, (uint16_t *) &sensor.chip_id);
|
||||
sensor.chip_id = (sensor.chip_id << 8) | (sensor.chip_id >> 8);
|
||||
return slv_addr;
|
||||
#endif // (OMV_PAG7920_ENABLE == 1)
|
||||
}
|
||||
@ -315,7 +326,7 @@ int sensor_probe_init(uint32_t bus_id, uint32_t bus_speed) {
|
||||
#if (OMV_PAJ6100_ENABLE == 1)
|
||||
} else if (paj6100_detect(&sensor)) {
|
||||
// Found PixArt PAJ6100
|
||||
sensor.chip_id_w = PAJ6100_ID;
|
||||
sensor.chip_id = PAJ6100_ID;
|
||||
sensor.power_pol = ACTIVE_LOW;
|
||||
sensor.reset_pol = ACTIVE_LOW;
|
||||
#endif
|
||||
@ -326,7 +337,7 @@ int sensor_probe_init(uint32_t bus_id, uint32_t bus_speed) {
|
||||
}
|
||||
|
||||
// A supported sensor was detected, try to initialize it.
|
||||
switch (sensor.chip_id_w) {
|
||||
switch (sensor.chip_id) {
|
||||
#if (OMV_OV2640_ENABLE == 1)
|
||||
case OV2640_ID:
|
||||
if (sensor_set_xclk_frequency(OMV_OV2640_XCLK_FREQ) != 0) {
|
||||
@ -387,7 +398,7 @@ int sensor_probe_init(uint32_t bus_id, uint32_t bus_speed) {
|
||||
case MT9V0X2_ID_V_1:
|
||||
case MT9V0X2_ID_V_2:
|
||||
// Force old versions to the newest.
|
||||
sensor.chip_id_w = MT9V0X2_ID;
|
||||
sensor.chip_id = MT9V0X2_ID;
|
||||
case MT9V0X2_ID:
|
||||
case MT9V0X4_ID:
|
||||
if (sensor_set_xclk_frequency(OMV_MT9V0XX_XCLK_FREQ) != 0) {
|
||||
@ -442,6 +453,16 @@ int sensor_probe_init(uint32_t bus_id, uint32_t bus_speed) {
|
||||
break;
|
||||
#endif //(OMV_GC2145_ENABLE == 1)
|
||||
|
||||
#if (OMV_GENX320_ENABLE == 1)
|
||||
case GENX320_ID_ES:
|
||||
case GENX320_ID_MP:
|
||||
if (sensor_set_xclk_frequency(OMV_GENX320_XCLK_FREQ) != 0) {
|
||||
return SENSOR_ERROR_TIM_INIT_FAILED;
|
||||
}
|
||||
init_ret = genx320_init(&sensor);
|
||||
break;
|
||||
#endif // (OMV_GENX320_ENABLE == 1)
|
||||
|
||||
#if (OMV_PAG7920_ENABLE == 1)
|
||||
case PAG7920_ID:
|
||||
if (sensor_set_xclk_frequency(OMV_PAG7920_XCLK_FREQ) != 0) {
|
||||
@ -487,7 +508,7 @@ __weak int sensor_config(sensor_config_t config) {
|
||||
}
|
||||
|
||||
__weak int sensor_get_id() {
|
||||
return sensor.chip_id_w;
|
||||
return sensor.chip_id;
|
||||
}
|
||||
|
||||
__weak uint32_t sensor_get_xclk_frequency() {
|
||||
@ -1129,13 +1150,12 @@ __weak int sensor_set_framebuffers(int count) {
|
||||
return SENSOR_ERROR_INVALID_FRAMESIZE;
|
||||
}
|
||||
|
||||
uint32_t bpp = IM_MAX(sensor_get_src_bpp(), sensor_get_dst_bpp());
|
||||
#if OMV_CSI_HW_CROP_ENABLE
|
||||
// If hardware cropping is supported, use window size.
|
||||
MAIN_FB()->frame_size = MAIN_FB()->u * MAIN_FB()->v * bpp;
|
||||
MAIN_FB()->frame_size = MAIN_FB()->u * MAIN_FB()->v * 2;
|
||||
#else
|
||||
// Otherwise, use the real frame size.
|
||||
MAIN_FB()->frame_size = resolution[sensor.framesize][0] * resolution[sensor.framesize][1] * bpp;
|
||||
MAIN_FB()->frame_size = resolution[sensor.framesize][0] * resolution[sensor.framesize][1] * 2;
|
||||
#endif
|
||||
return framebuffer_set_buffers(count);
|
||||
}
|
||||
|
||||
@ -359,12 +359,16 @@ extern const int8_t lab_table[196608 / 2];
|
||||
|
||||
typedef enum {
|
||||
COLOR_PALETTE_RAINBOW,
|
||||
COLOR_PALETTE_IRONBOW
|
||||
COLOR_PALETTE_IRONBOW,
|
||||
COLOR_PALETTE_EVT_DARK,
|
||||
COLOR_PALETTE_EVT_LIGHT
|
||||
} color_palette_t;
|
||||
|
||||
// Color palette LUTs
|
||||
extern const uint16_t rainbow_table[256];
|
||||
extern const uint16_t ironbow_table[256];
|
||||
extern const uint16_t evt_dark_table[256];
|
||||
extern const uint16_t evt_light_table[256];
|
||||
|
||||
/////////////////
|
||||
// Image Stuff //
|
||||
|
||||
@ -67,3 +67,71 @@ const uint16_t ironbow_table[256] = {
|
||||
0xFF05, 0xFF26, 0xFF28, 0xFF4A, 0xFF4C, 0xFF4D, 0xFF6F, 0xFF71,
|
||||
0xFF92, 0xFF94, 0xFFB6, 0xFFB7, 0xFFD9, 0xFFDB, 0xFFFD, 0xFFE3
|
||||
};
|
||||
const uint16_t evt_dark_table[256] = {
|
||||
0xD6FD, 0xD6FC, 0xD6DC, 0xD6DC, 0xD6DC, 0xCEBC, 0xCEBC, 0xCE9B,
|
||||
0xCE9B, 0xCE9B, 0xC67B, 0xC67B, 0xC67B, 0xC65A, 0xC65A, 0xC65A,
|
||||
0xBE3A, 0xBE3A, 0xBE1A, 0xBE19, 0xBE19, 0xB5F9, 0xB5F9, 0xB5F9,
|
||||
0xB5D8, 0xB5D8, 0xB5D8, 0xADB8, 0xADB8, 0xAD98, 0xAD97, 0xAD97,
|
||||
0xAD77, 0xA577, 0xA577, 0xA556, 0xA556, 0xA556, 0x9D36, 0x9D36,
|
||||
0x9D36, 0x9D16, 0x9D15, 0x9D15, 0x94F5, 0x94F5, 0x94F5, 0x94D4,
|
||||
0x94D4, 0x94B4, 0x8CB4, 0x8CB4, 0x8C94, 0x8C93, 0x8C93, 0x8C73,
|
||||
0x8473, 0x8473, 0x8452, 0x8452, 0x8432, 0x7C32, 0x7C32, 0x7C12,
|
||||
0x7C12, 0x7C11, 0x7BF1, 0x73F1, 0x73F1, 0x73D1, 0x73D0, 0x73B0,
|
||||
0x6BB0, 0x6BB0, 0x6B90, 0x6B90, 0x6B8F, 0x6B6F, 0x636F, 0x636F,
|
||||
0x634F, 0x634E, 0x632E, 0x632E, 0x5B2E, 0x5B0E, 0x5B0E, 0x5B0D,
|
||||
0x5AED, 0x52ED, 0x52ED, 0x52CD, 0x52CD, 0x52AC, 0x52AC, 0x4AAC,
|
||||
0x4AAC, 0x4A8C, 0x4A8C, 0x4A8B, 0x4A6B, 0x426B, 0x424B, 0x424B,
|
||||
0x424A, 0x422A, 0x3A2A, 0x3A2A, 0x3A0A, 0x3A0A, 0x3A09, 0x39E9,
|
||||
0x31E9, 0x31C9, 0x31C9, 0x31C9, 0x31A8, 0x29A8, 0x29A8, 0x2988,
|
||||
0x2988, 0x2988, 0x2967, 0x2167, 0x2147, 0x2147, 0x2147, 0x2126,
|
||||
0x2126, 0x2126, 0x2127, 0x2147, 0x2147, 0x2147, 0x2147, 0x2147,
|
||||
0x2147, 0x2168, 0x2168, 0x2168, 0x2168, 0x2168, 0x2168, 0x2188,
|
||||
0x2189, 0x2189, 0x2189, 0x2189, 0x2189, 0x21A9, 0x21A9, 0x21A9,
|
||||
0x21AA, 0x21AA, 0x21CA, 0x21CA, 0x21CA, 0x21CA, 0x21CA, 0x29CB,
|
||||
0x29EB, 0x29EB, 0x29EB, 0x29EB, 0x29EB, 0x29EC, 0x2A0C, 0x2A0C,
|
||||
0x2A0C, 0x2A0C, 0x2A0C, 0x2A0C, 0x2A2D, 0x2A2D, 0x2A2D, 0x2A2D,
|
||||
0x2A2D, 0x2A4D, 0x2A4D, 0x2A4D, 0x2A4E, 0x2A4E, 0x2A4E, 0x2A6E,
|
||||
0x2A6E, 0x2A6E, 0x2A6E, 0x2A6F, 0x2A6F, 0x328F, 0x328F, 0x328F,
|
||||
0x328F, 0x328F, 0x3290, 0x32B0, 0x32B0, 0x32B0, 0x32B0, 0x32B0,
|
||||
0x32B0, 0x32B1, 0x32D1, 0x32D1, 0x32D1, 0x32D1, 0x32D1, 0x32D1,
|
||||
0x32F2, 0x32F2, 0x32F2, 0x32F2, 0x32F2, 0x3312, 0x3312, 0x3313,
|
||||
0x3313, 0x3313, 0x3313, 0x3B33, 0x3B33, 0x3B33, 0x3B34, 0x3B34,
|
||||
0x3B34, 0x3B54, 0x3B54, 0x3B54, 0x3B54, 0x3B55, 0x3B55, 0x3B75,
|
||||
0x3B75, 0x3B75, 0x3B75, 0x3B75, 0x3B96, 0x3B96, 0x3B96, 0x3B96,
|
||||
0x3B96, 0x3B96, 0x3BB6, 0x3BB6, 0x3BB7, 0x3BB7, 0x3BB7, 0x3BB7,
|
||||
0x3BD7, 0x43D7, 0x43D8, 0x43D8, 0x43D8, 0x43D8, 0x43F8, 0x43F8
|
||||
};
|
||||
const uint16_t evt_light_table[256] = {
|
||||
0x43F8, 0x43F8, 0x43F8, 0x4418, 0x4419, 0x4419, 0x4C19, 0x4C19,
|
||||
0x4C39, 0x4C39, 0x4C39, 0x4C39, 0x4C39, 0x5439, 0x5459, 0x5459,
|
||||
0x5459, 0x5459, 0x5459, 0x5479, 0x5C79, 0x5C79, 0x5C79, 0x5C79,
|
||||
0x5C99, 0x5C99, 0x5C99, 0x6499, 0x6499, 0x6499, 0x64B9, 0x64B9,
|
||||
0x64B9, 0x6CBA, 0x6CBA, 0x6CDA, 0x6CDA, 0x6CDA, 0x6CDA, 0x6CDA,
|
||||
0x6CFA, 0x74FA, 0x74FA, 0x74FA, 0x74FA, 0x751A, 0x751A, 0x751A,
|
||||
0x7D1A, 0x7D1A, 0x7D1A, 0x7D3A, 0x7D3A, 0x7D3A, 0x853A, 0x853A,
|
||||
0x855A, 0x855A, 0x855A, 0x855A, 0x855A, 0x8D5A, 0x8D5A, 0x8D7B,
|
||||
0x8D7B, 0x8D7B, 0x8D7B, 0x8D7B, 0x959B, 0x959B, 0x959B, 0x959B,
|
||||
0x959B, 0x95BB, 0x95BB, 0x9DBB, 0x9DBB, 0x9DBB, 0x9DDB, 0x9DDB,
|
||||
0x9DDB, 0x9DDB, 0xA5DB, 0xA5DB, 0xA5FB, 0xA5FB, 0xA5FB, 0xA5FB,
|
||||
0xA5FB, 0xAE1B, 0xAE1B, 0xAE1B, 0xAE1B, 0xAE1B, 0xAE3B, 0xAE3B,
|
||||
0xB63C, 0xB63C, 0xB63C, 0xB65C, 0xB65C, 0xB65C, 0xB65C, 0xBE5C,
|
||||
0xBE5C, 0xBE7C, 0xBE7C, 0xBE7C, 0xBE7C, 0xBE7C, 0xC69C, 0xC69C,
|
||||
0xC69C, 0xC69C, 0xC69C, 0xC6BC, 0xC6BC, 0xCEBC, 0xCEBC, 0xCEBC,
|
||||
0xCEBC, 0xCEDC, 0xCEDC, 0xD6DC, 0xD6DC, 0xD6DD, 0xD6FD, 0xD6FD,
|
||||
0xD6FD, 0xD6FC, 0xD6DC, 0xD6DC, 0xD6DC, 0xCEBC, 0xCEBC, 0xCE9B,
|
||||
0xCE9B, 0xCE9B, 0xC67B, 0xC67B, 0xC67B, 0xC65A, 0xC65A, 0xC65A,
|
||||
0xBE3A, 0xBE3A, 0xBE1A, 0xBE19, 0xBE19, 0xB5F9, 0xB5F9, 0xB5F9,
|
||||
0xB5D8, 0xB5D8, 0xB5D8, 0xADB8, 0xADB8, 0xAD98, 0xAD97, 0xAD97,
|
||||
0xAD77, 0xA577, 0xA577, 0xA556, 0xA556, 0xA556, 0x9D36, 0x9D36,
|
||||
0x9D36, 0x9D16, 0x9D15, 0x9D15, 0x94F5, 0x94F5, 0x94F5, 0x94D4,
|
||||
0x94D4, 0x94B4, 0x8CB4, 0x8CB4, 0x8C94, 0x8C93, 0x8C93, 0x8C73,
|
||||
0x8473, 0x8473, 0x8452, 0x8452, 0x8432, 0x7C32, 0x7C32, 0x7C12,
|
||||
0x7C12, 0x7C11, 0x7BF1, 0x73F1, 0x73F1, 0x73D1, 0x73D0, 0x73B0,
|
||||
0x6BB0, 0x6BB0, 0x6B90, 0x6B90, 0x6B8F, 0x6B6F, 0x636F, 0x636F,
|
||||
0x634F, 0x634E, 0x632E, 0x632E, 0x5B2E, 0x5B0E, 0x5B0E, 0x5B0D,
|
||||
0x5AED, 0x52ED, 0x52ED, 0x52CD, 0x52CD, 0x52AC, 0x52AC, 0x4AAC,
|
||||
0x4AAC, 0x4A8C, 0x4A8C, 0x4A8B, 0x4A6B, 0x426B, 0x424B, 0x424B,
|
||||
0x424A, 0x422A, 0x3A2A, 0x3A2A, 0x3A0A, 0x3A0A, 0x3A09, 0x39E9,
|
||||
0x31E9, 0x31C9, 0x31C9, 0x31C9, 0x31A8, 0x29A8, 0x29A8, 0x2988,
|
||||
0x2988, 0x2988, 0x2967, 0x2167, 0x2147, 0x2147, 0x2147, 0x2126
|
||||
};
|
||||
|
||||
@ -63,6 +63,12 @@ const void *py_helper_arg_to_palette(const mp_obj_t arg, uint32_t pixfmt) {
|
||||
palette = rainbow_table;
|
||||
} else if (type == COLOR_PALETTE_IRONBOW) {
|
||||
palette = ironbow_table;
|
||||
#if (OMV_GENX320_ENABLE == 1)
|
||||
} else if (type == COLOR_PALETTE_EVT_DARK) {
|
||||
palette = evt_dark_table;
|
||||
} else if (type == COLOR_PALETTE_EVT_LIGHT) {
|
||||
palette = evt_light_table;
|
||||
#endif // OMV_GENX320_ENABLE == 1
|
||||
} else {
|
||||
mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("Invalid color palette"));
|
||||
}
|
||||
@ -463,6 +469,12 @@ const uint16_t *py_helper_keyword_color_palette(uint n_args, const mp_obj_t *arg
|
||||
default_color_palette = rainbow_table;
|
||||
} else if (palette == COLOR_PALETTE_IRONBOW) {
|
||||
default_color_palette = ironbow_table;
|
||||
#if (OMV_GENX320_ENABLE == 1)
|
||||
} else if (palette == COLOR_PALETTE_EVT_DARK) {
|
||||
default_color_palette = evt_dark_table;
|
||||
} else if (palette == COLOR_PALETTE_EVT_LIGHT) {
|
||||
default_color_palette = evt_light_table;
|
||||
#endif // OMV_GENX320_ENABLE == 1
|
||||
} else {
|
||||
mp_raise_msg(&mp_type_ValueError,
|
||||
MP_ERROR_TEXT("Invalid pre-defined color palette!"));
|
||||
|
||||
@ -1195,6 +1195,18 @@ static mp_obj_t py_image_to_ironbow(uint n_args, const mp_obj_t *args, mp_map_t
|
||||
}
|
||||
static MP_DEFINE_CONST_FUN_OBJ_KW(py_image_to_ironbow_obj, 1, py_image_to_ironbow);
|
||||
|
||||
#if (OMV_GENX320_ENABLE == 1)
|
||||
static mp_obj_t py_image_to_evt_dark(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
return py_image_to(PIXFORMAT_RGB565, MP_ROM_INT(COLOR_PALETTE_EVT_DARK), false, n_args, args, kw_args);
|
||||
}
|
||||
static MP_DEFINE_CONST_FUN_OBJ_KW(py_image_to_evt_dark_obj, 1, py_image_to_evt_dark);
|
||||
|
||||
static mp_obj_t py_image_to_evt_light(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
return py_image_to(PIXFORMAT_RGB565, MP_ROM_INT(COLOR_PALETTE_EVT_LIGHT), false, n_args, args, kw_args);
|
||||
}
|
||||
static MP_DEFINE_CONST_FUN_OBJ_KW(py_image_to_evt_light_obj, 1, py_image_to_evt_light);
|
||||
#endif // OMV_GENX320_ENABLE == 1
|
||||
|
||||
static mp_obj_t py_image_to_jpeg(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
return py_image_to(PIXFORMAT_JPEG, MP_ROM_NONE, false, n_args, args, kw_args);
|
||||
}
|
||||
@ -6218,6 +6230,10 @@ static const mp_rom_map_elem_t locals_dict_table[] = {
|
||||
{MP_ROM_QSTR(MP_QSTR_to_rgb565), MP_ROM_PTR(&py_image_to_rgb565_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_to_rainbow), MP_ROM_PTR(&py_image_to_rainbow_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_to_ironbow), MP_ROM_PTR(&py_image_to_ironbow_obj)},
|
||||
#if (OMV_GENX320_ENABLE == 1)
|
||||
{MP_ROM_QSTR(MP_QSTR_to_evt_dark), MP_ROM_PTR(&py_image_to_evt_dark_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_to_evt_light), MP_ROM_PTR(&py_image_to_evt_light_obj)},
|
||||
#endif // OMV_GENX320_ENABLE == 1
|
||||
{MP_ROM_QSTR(MP_QSTR_to_jpeg), MP_ROM_PTR(&py_image_to_jpeg_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_to_png), MP_ROM_PTR(&py_image_to_png_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_compress), MP_ROM_PTR(&py_image_to_jpeg_obj)},
|
||||
@ -7027,6 +7043,10 @@ static const mp_rom_map_elem_t globals_dict_table[] = {
|
||||
{MP_ROM_QSTR(MP_QSTR_PNG), MP_ROM_INT(PIXFORMAT_PNG)}, /* PNG/COMPRESSED*/
|
||||
{MP_ROM_QSTR(MP_QSTR_PALETTE_RAINBOW), MP_ROM_INT(COLOR_PALETTE_RAINBOW)},
|
||||
{MP_ROM_QSTR(MP_QSTR_PALETTE_IRONBOW), MP_ROM_INT(COLOR_PALETTE_IRONBOW)},
|
||||
#if (OMV_GENX320_ENABLE == 1)
|
||||
{MP_ROM_QSTR(MP_QSTR_PALETTE_EVT_DARK), MP_ROM_INT(COLOR_PALETTE_EVT_DARK)},
|
||||
{MP_ROM_QSTR(MP_QSTR_PALETTE_EVT_LIGHT), MP_ROM_INT(COLOR_PALETTE_EVT_LIGHT)},
|
||||
#endif // OMV_GENX320_ENABLE == 1
|
||||
{MP_ROM_QSTR(MP_QSTR_AREA), MP_ROM_INT(IMAGE_HINT_AREA)},
|
||||
{MP_ROM_QSTR(MP_QSTR_BILINEAR), MP_ROM_INT(IMAGE_HINT_BILINEAR)},
|
||||
{MP_ROM_QSTR(MP_QSTR_BICUBIC), MP_ROM_INT(IMAGE_HINT_BICUBIC)},
|
||||
|
||||
@ -1004,6 +1004,14 @@ static mp_obj_t py_sensor_set_color_palette(mp_obj_t palette_obj) {
|
||||
case COLOR_PALETTE_IRONBOW:
|
||||
sensor_set_color_palette(ironbow_table);
|
||||
break;
|
||||
#if (OMV_GENX320_ENABLE == 1)
|
||||
case COLOR_PALETTE_EVT_DARK:
|
||||
sensor_set_color_palette(evt_dark_table);
|
||||
break;
|
||||
case COLOR_PALETTE_EVT_LIGHT:
|
||||
sensor_set_color_palette(evt_light_table);
|
||||
break;
|
||||
#endif // OMV_GENX320_ENABLE == 1
|
||||
default:
|
||||
sensor_raise_error(SENSOR_ERROR_INVALID_ARGUMENT);
|
||||
break;
|
||||
@ -1018,6 +1026,12 @@ static mp_obj_t py_sensor_get_color_palette() {
|
||||
return mp_obj_new_int(COLOR_PALETTE_RAINBOW);
|
||||
} else if (palette == ironbow_table) {
|
||||
return mp_obj_new_int(COLOR_PALETTE_IRONBOW);
|
||||
#if (OMV_GENX320_ENABLE == 1)
|
||||
} else if (palette == evt_dark_table) {
|
||||
return mp_obj_new_int(COLOR_PALETTE_EVT_DARK);
|
||||
} else if (palette == evt_light_table) {
|
||||
return mp_obj_new_int(COLOR_PALETTE_EVT_LIGHT);
|
||||
#endif // OMV_GENX320_ENABLE == 1
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
@ -96,6 +96,7 @@ OMV_CFLAGS += -I$(TOP_DIR)/$(OMV_DIR)/templates/
|
||||
OMV_CFLAGS += -I$(TOP_DIR)/$(OMV_DIR)/ports/$(PORT)/
|
||||
OMV_CFLAGS += -I$(TOP_DIR)/$(OMV_DIR)/ports/$(PORT)/modules/
|
||||
|
||||
OMV_CFLAGS += -I$(TOP_DIR)/$(GENX320_DIR)/include/
|
||||
OMV_CFLAGS += -I$(TOP_DIR)/$(LEPTON_DIR)/include/
|
||||
OMV_CFLAGS += -I$(TOP_DIR)/$(LSM6DS3_DIR)/include/
|
||||
OMV_CFLAGS += -I$(TOP_DIR)/$(LSM6DSOX_DIR)/include/
|
||||
@ -118,6 +119,7 @@ LIBS += $(TOP_DIR)/$(TENSORFLOW_DIR)/libtflm/lib/libtflm-$(CPU)+fp-release.a
|
||||
#------------- Firmware Objects ----------------#
|
||||
FIRM_OBJ += $(wildcard $(BUILD)/$(CMSIS_DIR)/src/dsp/*/*.o)
|
||||
FIRM_OBJ += $(wildcard $(BUILD)/$(HAL_DIR)/drivers/*.o)
|
||||
FIRM_OBJ += $(wildcard $(BUILD)/$(GENX320_DIR)/src/*.o)
|
||||
FIRM_OBJ += $(wildcard $(BUILD)/$(LEPTON_DIR)/src/*.o)
|
||||
ifeq ($(MICROPY_PY_IMU), 1)
|
||||
FIRM_OBJ += $(wildcard $(BUILD)/$(LSM6DS3_DIR)/src/*.o)
|
||||
@ -171,6 +173,7 @@ FIRM_OBJ += $(addprefix $(BUILD)/$(OMV_DIR)/sensors/, \
|
||||
hm01b0.o \
|
||||
hm0360.o \
|
||||
gc2145.o \
|
||||
genx320.o \
|
||||
pag7920.o \
|
||||
paj6100.o \
|
||||
frogeye2020.o \
|
||||
@ -525,6 +528,7 @@ FIRMWARE_OBJS: | $(BUILD) $(FW_DIR)
|
||||
$(MAKE) -C $(HAL_DIR) BUILD=$(BUILD)/$(HAL_DIR) CFLAGS="$(CFLAGS) -MMD"
|
||||
$(MAKE) -C $(TENSORFLOW_DIR) BUILD=$(BUILD)/$(TENSORFLOW_DIR) CFLAGS="$(CFLAGS) -MMD" headers
|
||||
$(MAKE) -C $(MICROPY_DIR)/ports/$(PORT) BUILD=$(BUILD)/$(MICROPY_DIR) $(MICROPY_ARGS)
|
||||
$(MAKE) -C $(GENX320_DIR) BUILD=$(BUILD)/$(GENX320_DIR) CFLAGS="$(CFLAGS) -MMD"
|
||||
$(MAKE) -C $(LEPTON_DIR) BUILD=$(BUILD)/$(LEPTON_DIR) CFLAGS="$(CFLAGS) -MMD"
|
||||
ifeq ($(MICROPY_PY_IMU), 1)
|
||||
$(MAKE) -C $(LSM6DS3_DIR) BUILD=$(BUILD)/$(LSM6DS3_DIR) CFLAGS="$(CFLAGS) -MMD"
|
||||
|
||||
@ -90,6 +90,7 @@ OMV_CFLAGS += -I$(TOP_DIR)/$(OMV_DIR)/templates/
|
||||
OMV_CFLAGS += -I$(TOP_DIR)/$(OMV_DIR)/ports/$(PORT)/
|
||||
OMV_CFLAGS += -I$(TOP_DIR)/$(OMV_DIR)/ports/$(PORT)/modules/
|
||||
|
||||
OMV_CFLAGS += -I$(TOP_DIR)/$(GENX320_DIR)/include/
|
||||
OMV_CFLAGS += -I$(TOP_DIR)/$(LEPTON_DIR)/include/
|
||||
OMV_CFLAGS += -I$(TOP_DIR)/$(LSM6DS3_DIR)/include/
|
||||
OMV_CFLAGS += -I$(TOP_DIR)/$(LSM6DSOX_DIR)/include/
|
||||
@ -145,6 +146,7 @@ LIBS += $(TOP_DIR)/$(TENSORFLOW_DIR)/libtflm/lib/libtflm-$(CPU)+fp-release.a
|
||||
FIRM_OBJ += $(wildcard $(BUILD)/$(CMSIS_DIR)/src/dsp/*/*.o)
|
||||
|
||||
FIRM_OBJ += $(wildcard $(BUILD)/$(HAL_DIR)/src/*.o)
|
||||
FIRM_OBJ += $(wildcard $(BUILD)/$(GENX320_DIR)/src/*.o)
|
||||
FIRM_OBJ += $(wildcard $(BUILD)/$(LEPTON_DIR)/src/*.o)
|
||||
ifeq ($(MICROPY_PY_IMU), 1)
|
||||
FIRM_OBJ += $(wildcard $(BUILD)/$(LSM6DS3_DIR)/src/*.o)
|
||||
@ -201,6 +203,7 @@ FIRM_OBJ += $(addprefix $(BUILD)/$(OMV_DIR)/sensors/, \
|
||||
hm01b0.o \
|
||||
hm0360.o \
|
||||
gc2145.o \
|
||||
genx320.o \
|
||||
pag7920.o \
|
||||
paj6100.o \
|
||||
frogeye2020.o \
|
||||
@ -607,6 +610,7 @@ UVC_OBJ += $(addprefix $(BUILD)/$(OMV_DIR)/sensors/, \
|
||||
hm01b0.o \
|
||||
hm0360.o \
|
||||
gc2145.o \
|
||||
genx320.o \
|
||||
pag7920.o \
|
||||
paj6100.o \
|
||||
frogeye2020.o \
|
||||
@ -637,6 +641,7 @@ UVC_OBJ += $(addprefix $(BUILD)/$(OMV_DIR)/ports/stm32/,\
|
||||
omv_spi.o \
|
||||
)
|
||||
|
||||
UVC_OBJ += $(wildcard $(BUILD)/$(GENX320_DIR)/src/*.o)
|
||||
UVC_OBJ += $(wildcard $(BUILD)/$(LEPTON_DIR)/src/*.o)
|
||||
ifeq ($(MICROPY_PY_IMU), 1)
|
||||
UVC_OBJ += $(wildcard $(BUILD)/$(LSM6DS3_DIR)/src/*.o)
|
||||
@ -663,6 +668,7 @@ FIRMWARE_OBJS: | $(BUILD) $(FW_DIR)
|
||||
$(MAKE) -C $(HAL_DIR) BUILD=$(BUILD)/$(HAL_DIR) CFLAGS="$(CFLAGS) -MMD"
|
||||
$(MAKE) -C $(TENSORFLOW_DIR) BUILD=$(BUILD)/$(TENSORFLOW_DIR) CFLAGS="$(CFLAGS) -MMD" headers
|
||||
$(MAKE) -C $(MICROPY_DIR)/ports/$(PORT) BUILD=$(BUILD)/$(MICROPY_DIR) $(MICROPY_ARGS)
|
||||
$(MAKE) -C $(GENX320_DIR) BUILD=$(BUILD)/$(GENX320_DIR) CFLAGS="$(CFLAGS) -MMD"
|
||||
$(MAKE) -C $(LEPTON_DIR) BUILD=$(BUILD)/$(LEPTON_DIR) CFLAGS="$(CFLAGS) -MMD"
|
||||
ifeq ($(MICROPY_PY_IMU), 1)
|
||||
$(MAKE) -C $(LSM6DS3_DIR) BUILD=$(BUILD)/$(LSM6DS3_DIR) CFLAGS="$(CFLAGS) -MMD"
|
||||
|
||||
427
src/omv/sensors/genx320.c
Normal file
427
src/omv/sensors/genx320.c
Normal file
@ -0,0 +1,427 @@
|
||||
/*
|
||||
* This file is part of the OpenMV project.
|
||||
*
|
||||
* Copyright (c) 2013-2024 Ibrahim Abdelkader <iabdalkader@openmv.io>
|
||||
* Copyright (c) 2013-2024 Kwabena W. Agyeman <kwagyeman@openmv.io>
|
||||
*
|
||||
* This work is licensed under the MIT license, see the file LICENSE for details.
|
||||
*
|
||||
* GENX320 driver.
|
||||
*/
|
||||
#include "omv_boardconfig.h"
|
||||
#if (OMV_GENX320_ENABLE == 1)
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "omv_i2c.h"
|
||||
#include "sensor.h"
|
||||
#include "framebuffer.h"
|
||||
#include "genx320.h"
|
||||
#include "py/mphal.h"
|
||||
#include "evt_2_0.h"
|
||||
#include "psee_genx320.h"
|
||||
|
||||
#define BLANK_LINES 4
|
||||
#define BLANK_COLUMNS 4
|
||||
|
||||
#define SENSOR_WIDTH 324
|
||||
#define SENSOR_HEIGHT 324
|
||||
|
||||
#define ACTIVE_SENSOR_WIDTH (SENSOR_WIDTH - BLANK_COLUMNS)
|
||||
#define ACTIVE_SENSOR_HEIGHT (SENSOR_HEIGHT - BLANK_LINES)
|
||||
#define ACTIVE_SENSOR_SIZE (ACTIVE_SENSOR_WIDTH * ACTIVE_SENSOR_HEIGHT)
|
||||
|
||||
#define HSYNC_CLOCK_CYCLES 32
|
||||
#define VSYNC_CLOCK_CYCLES 32
|
||||
|
||||
#define CONTRAST_DEFAULT 16
|
||||
#define BRIGHTNESS_DEFAULT 128
|
||||
|
||||
#define I2C_TIMEOUT 1000
|
||||
#define SRAM_INIT_TIMEOUT 100
|
||||
|
||||
#define INTEGRATION_DEF_PREIOD 10000 // 10ms (100 FPS)
|
||||
#define INTEGRATION_MIN_PREIOD 0x10 // 16us
|
||||
#define INTEGRATION_MAX_PREIOD 0x1FFF0 // 131056us
|
||||
|
||||
#define FPS_TO_US(fps) (1000000 / (fps))
|
||||
|
||||
#define EVENT_THRESHOLD_TO_CALIBRATE 100000
|
||||
#define EVENT_THRESHOLD_SIGMA 10
|
||||
|
||||
#if (OMV_GENX320_CAL_ENABLE == 1)
|
||||
static bool hot_pixels_disabled = false;
|
||||
#endif // (OMV_GENX320_CAL_ENABLE == 1)
|
||||
static int32_t contrast = CONTRAST_DEFAULT;
|
||||
static int32_t brightness = BRIGHTNESS_DEFAULT;
|
||||
|
||||
static int reset(sensor_t *sensor) {
|
||||
sensor->color_palette = NULL;
|
||||
|
||||
#if (OMV_GENX320_CAL_ENABLE == 1)
|
||||
hot_pixels_disabled = false;
|
||||
#endif // (OMV_GENX320_CAL_ENABLE == 1)
|
||||
contrast = CONTRAST_DEFAULT;
|
||||
brightness = BRIGHTNESS_DEFAULT;
|
||||
|
||||
BIAS_Params_t biases = (sensor->chip_id == SAPHIR_ES_ID) ? genx320es_default_biases : genx320mp_default_biases;
|
||||
|
||||
// Force CPI with chicken bits
|
||||
psee_sensor_write(TOP_CHICKEN, TOP_CHICKEN_OVERRIDE_MIPI_MODE_EN |
|
||||
TOP_CHICKEN_OVERRIDE_HISTO_MODE_EN |
|
||||
#if (OMV_GENX320_EHC_ENABLE == 1)
|
||||
1 << TOP_CHICKEN_OVERRIDE_HISTO_MODE_Pos |
|
||||
#else
|
||||
0 << TOP_CHICKEN_OVERRIDE_HISTO_MODE_Pos |
|
||||
#endif // (OMV_GENX320_EHC_ENABLE == 1)
|
||||
I2C_TIMEOUT << TOP_CHICKEN_I2C_TIMEOUT_Pos);
|
||||
|
||||
// Start the Init sequence
|
||||
psee_sensor_init(&dcmi_evt);
|
||||
|
||||
// Set EVT20 mode
|
||||
psee_sensor_write(EDF_CONTROL, 0);
|
||||
|
||||
// Configure Packet and Frame sizes
|
||||
psee_sensor_write(CPI_PACKET_SIZE_CONTROL, ACTIVE_SENSOR_WIDTH);
|
||||
psee_sensor_write(CPI_PACKET_TIME_CONTROL, ACTIVE_SENSOR_WIDTH << CPI_PACKET_TIME_CONTROL_PERIOD_Pos |
|
||||
HSYNC_CLOCK_CYCLES << CPI_PACKET_TIME_CONTROL_BLANKING_Pos);
|
||||
psee_sensor_write(CPI_FRAME_SIZE_CONTROL, ACTIVE_SENSOR_HEIGHT);
|
||||
psee_sensor_write(CPI_FRAME_TIME_CONTROL, VSYNC_CLOCK_CYCLES);
|
||||
|
||||
// Enable dropping
|
||||
psee_sensor_write(RO_READOUT_CTRL, RO_READOUT_CTRL_DIGITAL_PIPE_EN |
|
||||
RO_READOUT_CTRL_AVOID_BPRESS_TD |
|
||||
RO_READOUT_CTRL_DROP_EN |
|
||||
RO_READOUT_CTRL_DROP_ON_FULL_EN);
|
||||
|
||||
// Disable the Anti-FlicKering filter
|
||||
psee_disable_afk();
|
||||
|
||||
// Operation Mode Configuration
|
||||
psee_PM3C_config();
|
||||
|
||||
// Set the default border for the Activity map
|
||||
psee_set_default_XY_borders(&genx320mp_default_am_borders);
|
||||
|
||||
// Configure the activity map
|
||||
psee_configure_activity_map();
|
||||
|
||||
// Set Standard biases
|
||||
psee_sensor_set_biases(&biases);
|
||||
|
||||
// Start the sensor
|
||||
psee_sensor_start(&dcmi_evt);
|
||||
|
||||
#if (OMV_GENX320_EHC_ENABLE == 1)
|
||||
// Bypass Filter
|
||||
psee_sensor_write(EHC_PIPELINE_CONTROL, 0);
|
||||
|
||||
// Start sram init
|
||||
psee_sensor_write(SRAM_INITN, SRAM_INITN_EHC_STC);
|
||||
uint32_t reg;
|
||||
psee_sensor_read(SRAM_PD0, ®);
|
||||
psee_sensor_write(SRAM_PD0, reg & ~(SRAM_PD0_EHC_PD | SRAM_PD0_STC0_PD | SRAM_PD0_STC1_PD));
|
||||
psee_sensor_write(EHC_INITIALISATION, EHC_INITIALISATION_REQ_INIT);
|
||||
|
||||
// Configure the block
|
||||
psee_sensor_write(EHC_EHC_CONTROL, 0 << EHC_CONTROL_ALGO_SEL_Pos | // diff3
|
||||
1 << EHC_CONTROL_TRIG_SEL_Pos); // integration period
|
||||
psee_sensor_write(EHC_BITS_SPLITTING, INT8_T_BITS << EHC_BITS_SPLITTING_NEGATIVE_BIT_LENGTH_Pos |
|
||||
0 << EHC_BITS_SPLITTING_POSITIVE_BIT_LENGTH_Pos |
|
||||
0 << EHC_BITS_SPLITTING_OUT_16BITS_PADDING_MODE_Pos);
|
||||
psee_sensor_write(EHC_INTEGRATION_PERIOD, INTEGRATION_DEF_PREIOD);
|
||||
|
||||
// Check SRAM INIT done
|
||||
for (mp_uint_t start = mp_hal_ticks_ms();; mp_hal_delay_ms(1)) {
|
||||
uint32_t reg;
|
||||
psee_sensor_read(EHC_INITIALISATION, ®);
|
||||
|
||||
if (reg & EHC_INITIALISATION_FLAG_INIT_DONE) {
|
||||
psee_sensor_write(EHC_INITIALISATION, EHC_INITIALISATION_FLAG_INIT_DONE);
|
||||
break;
|
||||
}
|
||||
|
||||
if ((mp_hal_ticks_ms() - start) >= SRAM_INIT_TIMEOUT) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// Re-enable filter
|
||||
psee_sensor_write(EHC_PIPELINE_CONTROL, EHC_PIPELINE_CONTROL_ENABLE);
|
||||
#endif // (OMV_GENX320_EHC_ENABLE == 1)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sleep(sensor_t *sensor, int enable) {
|
||||
if (enable) {
|
||||
psee_PM2_config();
|
||||
} else {
|
||||
psee_PM3C_config();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int read_reg(sensor_t *sensor, uint16_t reg_addr) {
|
||||
uint32_t reg_data;
|
||||
uint8_t addr[] = {(reg_addr >> 8), reg_addr};
|
||||
if (omv_i2c_write_bytes(&sensor->i2c_bus, sensor->slv_addr, addr, 2, OMV_I2C_XFER_NO_STOP) != 0) {
|
||||
return -1;
|
||||
}
|
||||
if (omv_i2c_read_bytes(&sensor->i2c_bus, sensor->slv_addr, (uint8_t *) ®_data, 4, OMV_I2C_XFER_NO_FLAGS) != 0) {
|
||||
return -1;
|
||||
}
|
||||
reg_data = __REV(reg_data);
|
||||
return reg_data;
|
||||
}
|
||||
|
||||
static int write_reg(sensor_t *sensor, uint16_t reg_addr, uint16_t reg_data) {
|
||||
uint8_t buf[] = {(reg_addr >> 8), reg_addr, (reg_data >> 24), (reg_data >> 16), (reg_data >> 8), reg_data};
|
||||
return omv_i2c_write_bytes(&sensor->i2c_bus, sensor->slv_addr, buf, 6, OMV_I2C_XFER_NO_FLAGS);
|
||||
}
|
||||
|
||||
static int set_pixformat(sensor_t *sensor, pixformat_t pixformat) {
|
||||
return (pixformat == PIXFORMAT_GRAYSCALE) ? 0 : -1;
|
||||
}
|
||||
|
||||
static int set_framesize(sensor_t *sensor, framesize_t framesize) {
|
||||
return (framesize == FRAMESIZE_320X320) ? 0 : -1;
|
||||
}
|
||||
|
||||
static int set_framerate(sensor_t *sensor, int framerate) {
|
||||
#if (OMV_GENX320_EHC_ENABLE == 1)
|
||||
int us = FPS_TO_US(framerate);
|
||||
|
||||
if (us < INTEGRATION_MIN_PREIOD) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (us > INTEGRATION_MAX_PREIOD) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
psee_sensor_write(EHC_INTEGRATION_PERIOD, us);
|
||||
#endif // (OMV_GENX320_EHC_ENABLE == 1)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_contrast(sensor_t *sensor, int level) {
|
||||
contrast = __USAT(level, UINT8_T_BITS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_brightness(sensor_t *sensor, int level) {
|
||||
brightness = __USAT(level, UINT8_T_BITS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_colorbar(sensor_t *sensor, int enable) {
|
||||
uint32_t reg;
|
||||
psee_sensor_read(RO_READOUT_CTRL, ®);
|
||||
reg = (reg & ~RO_READOUT_CTRL_ERC_SELF_TEST_EN) | (enable ? RO_READOUT_CTRL_ERC_SELF_TEST_EN : 0);
|
||||
psee_sensor_write(RO_READOUT_CTRL, reg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_hmirror(sensor_t *sensor, int enable) {
|
||||
psee_sensor_set_flip(enable, sensor->vflip);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_vflip(sensor_t *sensor, int enable) {
|
||||
psee_sensor_set_flip(sensor->hmirror, enable);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if (OMV_GENX320_CAL_ENABLE == 1)
|
||||
static void disable_hot_pixels(uint8_t *histogram) {
|
||||
// Compute average
|
||||
int32_t avg = 0;
|
||||
|
||||
for (uint32_t i = 0; i < ACTIVE_SENSOR_SIZE; i++) {
|
||||
avg += histogram[i];
|
||||
}
|
||||
|
||||
avg /= ACTIVE_SENSOR_SIZE;
|
||||
|
||||
// Compute std
|
||||
int32_t std = 0;
|
||||
|
||||
for (uint32_t i = 0; i < ACTIVE_SENSOR_SIZE; i++) {
|
||||
int32_t diff = histogram[i] - avg;
|
||||
std += diff * diff;
|
||||
}
|
||||
|
||||
std = fast_sqrtf(std / ACTIVE_SENSOR_SIZE);
|
||||
|
||||
int32_t threshold = avg + (std * EVENT_THRESHOLD_SIGMA);
|
||||
|
||||
for (uint32_t y = 0; y < ACTIVE_SENSOR_HEIGHT; y++) {
|
||||
// Reset all blocks
|
||||
for (uint32_t i = 0; i < (ACTIVE_SENSOR_WIDTH / UINT32_T_BITS); i++) {
|
||||
psee_write_ROI_X(i * sizeof(uint32_t), 0);
|
||||
}
|
||||
|
||||
// Select line
|
||||
uint32_t offset = y / UINT32_T_BITS;
|
||||
psee_write_ROI_Y(offset * sizeof(uint32_t), 1 << (y % UINT32_T_BITS));
|
||||
|
||||
// Trigger shadow
|
||||
psee_write_ROI_CTRL(ROI_CTRL_PX_SW_RSTN | ROI_CTRL_TD_SHADOW_TRIGGER);
|
||||
|
||||
uint32_t tmp[ACTIVE_SENSOR_WIDTH / UINT32_T_BITS] = {};
|
||||
for (uint32_t x = 0; x < ACTIVE_SENSOR_WIDTH; x++) {
|
||||
if (histogram[(y * ACTIVE_SENSOR_WIDTH) + x] > threshold) {
|
||||
tmp[x / UINT32_T_BITS] |= 1 << (x % UINT32_T_BITS);
|
||||
}
|
||||
}
|
||||
|
||||
// Write x values to disable
|
||||
for (uint32_t i = 0; i < (ACTIVE_SENSOR_WIDTH / UINT32_T_BITS); i++) {
|
||||
psee_write_ROI_X(i * sizeof(uint32_t), tmp[i]);
|
||||
}
|
||||
|
||||
// Activate block
|
||||
psee_write_ROI_CTRL(ROI_CTRL_PX_SW_RSTN | ROI_CTRL_TD_SHADOW_TRIGGER | ROI_CTRL_TD_EN);
|
||||
|
||||
// Disable roi block
|
||||
psee_write_ROI_CTRL(ROI_CTRL_PX_SW_RSTN);
|
||||
psee_write_ROI_Y(offset * sizeof(uint32_t), 0);
|
||||
}
|
||||
}
|
||||
#endif // (OMV_GENX320_CAL_ENABLE == 1)
|
||||
|
||||
static void snapshot_post_process(image_t *image) {
|
||||
#if (OMV_GENX320_EHC_ENABLE == 1)
|
||||
for (uint32_t i = 0; i < ACTIVE_SENSOR_SIZE; i++) {
|
||||
image->data[i] = __USAT((((int8_t *) image->data)[i] * contrast) + brightness, UINT8_T_BITS);
|
||||
}
|
||||
#else
|
||||
uint8_t *out = fb_alloc(ACTIVE_SENSOR_SIZE, FB_ALLOC_NO_HINT);
|
||||
memset(out, brightness, ACTIVE_SENSOR_SIZE);
|
||||
|
||||
for (uint32_t i = 0; i < (ACTIVE_SENSOR_SIZE / sizeof(uint32_t)); i++) {
|
||||
uint32_t val = ((uint32_t *) image->data)[i];
|
||||
uint32_t x = __EVT20_X(val);
|
||||
uint32_t y = __EVT20_Y(val);
|
||||
switch (__EVT20_TYPE(val)) {
|
||||
case TD_LOW: {
|
||||
if ((x < ACTIVE_SENSOR_WIDTH) && (y < ACTIVE_SENSOR_HEIGHT)) {
|
||||
uint32_t index = (y * ACTIVE_SENSOR_WIDTH) + x;
|
||||
out[index] = __USAT(((int32_t) out[index]) - contrast, UINT8_T_BITS);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TD_HIGH: {
|
||||
if ((x < ACTIVE_SENSOR_WIDTH) && (y < ACTIVE_SENSOR_HEIGHT)) {
|
||||
uint32_t index = (y * ACTIVE_SENSOR_WIDTH) + x;
|
||||
out[index] = __USAT(((int32_t) out[index]) + contrast, UINT8_T_BITS);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(image->data, out, ACTIVE_SENSOR_SIZE);
|
||||
fb_free();
|
||||
#endif // (OMV_GENX320_EHC_ENABLE == 1)
|
||||
|
||||
if (sensor.color_palette && (framebuffer_get_buffer_size() >= (ACTIVE_SENSOR_SIZE * sizeof(uint16_t)))) {
|
||||
for (int32_t i = ACTIVE_SENSOR_SIZE - 1; i >= 0; i--) {
|
||||
((uint16_t *) image->data)[i] = sensor.color_palette[image->data[i]];
|
||||
}
|
||||
image->pixfmt = PIXFORMAT_RGB565;
|
||||
MAIN_FB()->pixfmt = PIXFORMAT_RGB565;
|
||||
}
|
||||
}
|
||||
|
||||
static int snapshot(sensor_t *sensor, image_t *image, uint32_t flags) {
|
||||
#if (OMV_GENX320_CAL_ENABLE == 1)
|
||||
if (!hot_pixels_disabled) {
|
||||
uint8_t *histogram = fb_alloc0(ACTIVE_SENSOR_SIZE, FB_ALLOC_NO_HINT);
|
||||
|
||||
// Collect events to calibrate hot pixels.
|
||||
for (uint32_t i = 0; i < EVENT_THRESHOLD_TO_CALIBRATE; ) {
|
||||
int ret = sensor_snapshot(sensor, image, flags);
|
||||
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Build histogram of events.
|
||||
#if (OMV_GENX320_EHC_ENABLE == 1)
|
||||
for (uint32_t j = 0; j < ACTIVE_SENSOR_SIZE; j++) {
|
||||
int32_t val = abs(((int8_t *) image->data)[j]);
|
||||
histogram[j] = val;
|
||||
i += val;
|
||||
}
|
||||
#else
|
||||
for (uint32_t j = 0; j < (ACTIVE_SENSOR_SIZE / sizeof(uint32_t)); j++) {
|
||||
uint32_t val = ((uint32_t *) image->data)[j];
|
||||
switch (__EVT20_TYPE(val)) {
|
||||
case TD_LOW:
|
||||
case TD_HIGH: {
|
||||
uint32_t x = __EVT20_X(val);
|
||||
uint32_t y = __EVT20_Y(val);
|
||||
if ((x < ACTIVE_SENSOR_WIDTH) && (y < ACTIVE_SENSOR_HEIGHT)) {
|
||||
uint32_t index = (y * ACTIVE_SENSOR_WIDTH) + x;
|
||||
histogram[index] = __USAT(histogram[index] + 1, UINT8_T_BITS);
|
||||
i++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // (OMV_GENX320_EHC_ENABLE == 1)
|
||||
|
||||
snapshot_post_process(image);
|
||||
}
|
||||
|
||||
disable_hot_pixels(histogram);
|
||||
|
||||
fb_free();
|
||||
hot_pixels_disabled = true;
|
||||
}
|
||||
#endif // (OMV_GENX320_CAL_ENABLE == 1)
|
||||
|
||||
int ret = sensor_snapshot(sensor, image, flags);
|
||||
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
snapshot_post_process(image);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int genx320_init(sensor_t *sensor) {
|
||||
// Initialize sensor structure
|
||||
sensor->reset = reset;
|
||||
sensor->sleep = sleep;
|
||||
sensor->read_reg = read_reg;
|
||||
sensor->write_reg = write_reg;
|
||||
sensor->set_pixformat = set_pixformat;
|
||||
sensor->set_framesize = set_framesize;
|
||||
sensor->set_framerate = set_framerate;
|
||||
sensor->set_contrast = set_contrast;
|
||||
sensor->set_brightness = set_brightness;
|
||||
sensor->set_colorbar = set_colorbar;
|
||||
sensor->set_hmirror = set_hmirror;
|
||||
sensor->set_vflip = set_vflip;
|
||||
sensor->snapshot = snapshot;
|
||||
|
||||
// Set sensor flags
|
||||
sensor->mono_bpp = sizeof(uint8_t);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif // (OMV_GENX320_ENABLE == 1)
|
||||
15
src/omv/sensors/genx320.h
Normal file
15
src/omv/sensors/genx320.h
Normal file
@ -0,0 +1,15 @@
|
||||
/*
|
||||
* This file is part of the OpenMV project.
|
||||
*
|
||||
* Copyright (c) 2013-2024 Ibrahim Abdelkader <iabdalkader@openmv.io>
|
||||
* Copyright (c) 2013-2024 Kwabena W. Agyeman <kwagyeman@openmv.io>
|
||||
*
|
||||
* This work is licensed under the MIT license, see the file LICENSE for details.
|
||||
*
|
||||
* GENX320 driver.
|
||||
*/
|
||||
#ifndef __GENX320_H__
|
||||
#define __GENX320_H__
|
||||
#define OMV_GENX320_XCLK_FREQ (24000000)
|
||||
int genx320_init(sensor_t *sensor);
|
||||
#endif // __GENX320_H__
|
||||
@ -522,17 +522,17 @@ int lepton_init(sensor_t *sensor) {
|
||||
// xxxx == Version
|
||||
// 01/00 == Shutter/NoShutter
|
||||
if (!strncmp(part.value, "500-0771", 8)) {
|
||||
sensor->chip_id_w = LEPTON_3_5;
|
||||
sensor->chip_id = LEPTON_3_5;
|
||||
} else if (!strncmp(part.value, "500-0726", 8)) {
|
||||
sensor->chip_id_w = LEPTON_3_0;
|
||||
sensor->chip_id = LEPTON_3_0;
|
||||
} else if (!strncmp(part.value, "500-0763", 8)) {
|
||||
sensor->chip_id_w = LEPTON_2_5;
|
||||
sensor->chip_id = LEPTON_2_5;
|
||||
} else if (!strncmp(part.value, "500-0659", 8)) {
|
||||
sensor->chip_id_w = LEPTON_2_0;
|
||||
sensor->chip_id = LEPTON_2_0;
|
||||
} else if (!strncmp(part.value, "500-0690", 8)) {
|
||||
sensor->chip_id_w = LEPTON_1_6;
|
||||
sensor->chip_id = LEPTON_1_6;
|
||||
} else if (!strncmp(part.value, "500-0643", 8)) {
|
||||
sensor->chip_id_w = LEPTON_1_5;
|
||||
sensor->chip_id = LEPTON_1_5;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -37,11 +37,11 @@ static enum {
|
||||
cfa_type = MONO_CFA;
|
||||
|
||||
static bool is_mt9v0x2(sensor_t *sensor) {
|
||||
return (sensor->chip_id_w == MT9V0X2_ID) || (sensor->chip_id_w == MT9V0X2_C_ID);
|
||||
return (sensor->chip_id == MT9V0X2_ID) || (sensor->chip_id == MT9V0X2_C_ID);
|
||||
}
|
||||
|
||||
static bool is_mt9v0x4(sensor_t *sensor) {
|
||||
return (sensor->chip_id_w == MT9V0X4_ID) || (sensor->chip_id_w == MT9V0X4_C_ID);
|
||||
return (sensor->chip_id == MT9V0X4_ID) || (sensor->chip_id == MT9V0X4_C_ID);
|
||||
}
|
||||
|
||||
static int reset(sensor_t *sensor) {
|
||||
@ -525,13 +525,13 @@ int mt9v0xx_init(sensor_t *sensor) {
|
||||
switch ((cfa_type_reg >> 9) & 0x7) {
|
||||
case BAYER_CFA_ID: {
|
||||
cfa_type = BAYER_CFA;
|
||||
switch (sensor->chip_id_w) {
|
||||
switch (sensor->chip_id) {
|
||||
case MT9V0X2_ID: {
|
||||
sensor->chip_id_w = MT9V0X2_C_ID;
|
||||
sensor->chip_id = MT9V0X2_C_ID;
|
||||
break;
|
||||
}
|
||||
case MT9V0X4_ID: {
|
||||
sensor->chip_id_w = MT9V0X4_C_ID;
|
||||
sensor->chip_id = MT9V0X4_C_ID;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
|
||||
@ -2,13 +2,39 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# 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>
|
||||
# Copyright (c) 2013-2024 Ibrahim Abdelkader <iabdalkader@openmv.io>
|
||||
# Copyright (c) 2013-2024 Kwabena W. Agyeman <kwagyeman@openmv.io>
|
||||
#
|
||||
# This work is licensed under the MIT license, see the file LICENSE for details.
|
||||
#
|
||||
# This script generates the rainbow lookup table.
|
||||
|
||||
def interpolate_color(color1, color2, factor):
|
||||
return (
|
||||
int(color1[0] + (color2[0] - color1[0]) * factor),
|
||||
int(color1[1] + (color2[1] - color1[1]) * factor),
|
||||
int(color1[2] + (color2[2] - color1[2]) * factor)
|
||||
)
|
||||
|
||||
def generate_lookup_table(lo_color, mid_color, hi_color):
|
||||
lookup_table = []
|
||||
|
||||
for i in range(256):
|
||||
if i < 128:
|
||||
factor = i / 128.0
|
||||
color = interpolate_color(lo_color, mid_color, factor)
|
||||
else:
|
||||
factor = (i - 128) / 128.0
|
||||
color = interpolate_color(mid_color, hi_color, factor)
|
||||
lookup_table.append(color)
|
||||
|
||||
return lookup_table
|
||||
|
||||
def rgb888_to_rgb565(tup):
|
||||
return [(int(((r * 31) + 127.5) / 255) & 0x1F) << 11 |
|
||||
(int(((g * 63) + 127.5) / 255) & 0x3F) << 5 |
|
||||
(int(((b * 31) + 127.5) / 255) & 0x1F) for r,g,b in tup]
|
||||
|
||||
NUM_COL=256
|
||||
SAT=1.0
|
||||
VAL=1.0
|
||||
@ -309,3 +335,37 @@ for i in range(NUM_COL):
|
||||
sys.stdout.write(",\n")
|
||||
else:
|
||||
sys.stdout.write("\n};\n")
|
||||
|
||||
on_event = (216, 223, 236)
|
||||
background = (30, 37, 52)
|
||||
off_event = (64, 126, 201)
|
||||
col = rgb888_to_rgb565(generate_lookup_table(on_event, background, off_event))
|
||||
|
||||
sys.stdout.write("const uint16_t evt_dark_table[%d] = {\n" % NUM_COL)
|
||||
for i in range(NUM_COL):
|
||||
if not (i % 8):
|
||||
sys.stdout.write(" ")
|
||||
sys.stdout.write("0x%04X" % col[i])
|
||||
if (i + 1) % 8:
|
||||
sys.stdout.write(", ")
|
||||
elif i != (NUM_COL-1):
|
||||
sys.stdout.write(",\n")
|
||||
else:
|
||||
sys.stdout.write("\n};\n")
|
||||
|
||||
on_event = (64, 126, 201)
|
||||
background = (216, 223, 236)
|
||||
off_event = (30, 37, 52)
|
||||
col = rgb888_to_rgb565(generate_lookup_table(on_event, background, off_event))
|
||||
|
||||
sys.stdout.write("const uint16_t evt_light_table[%d] = {\n" % NUM_COL)
|
||||
for i in range(NUM_COL):
|
||||
if not (i % 8):
|
||||
sys.stdout.write(" ")
|
||||
sys.stdout.write("0x%04X" % col[i])
|
||||
if (i + 1) % 8:
|
||||
sys.stdout.write(", ")
|
||||
elif i != (NUM_COL-1):
|
||||
sys.stdout.write(",\n")
|
||||
else:
|
||||
sys.stdout.write("\n};\n")
|
||||
|
||||
Loading…
Reference in New Issue
Block a user