initial commit
This commit is contained in:
+404
@@ -0,0 +1,404 @@
|
||||
#******************************************************************************
|
||||
#
|
||||
# Makefile - Rules for building the libraries, examples and docs.
|
||||
#
|
||||
# Copyright (c) 2019, Ambiq Micro
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
# 3. Neither the name of the copyright holder nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from this
|
||||
# software without specific prior written permission.
|
||||
#
|
||||
# Third party software included in this distribution is subject to the
|
||||
# additional license terms as defined in the /docs/licenses directory.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
# This is part of revision 2.1.0 of the AmbiqSuite Development Package.
|
||||
#
|
||||
#******************************************************************************
|
||||
|
||||
#******************************************************************************
|
||||
#
|
||||
# This is an example makefile for SparkFun Apollo3 boards as used in the
|
||||
# AmbiqSuite SDK.
|
||||
#
|
||||
# Recommended usage
|
||||
# make
|
||||
# make bootload_svl (uses the SparkFun Variable Loader to upload code)
|
||||
# make bootload_asb (uses the Ambiq Secure Bootlaoder to upload code)
|
||||
# make clean
|
||||
#
|
||||
# Filepaths
|
||||
# You can relocate this makefile easily by providing the path to the root of
|
||||
# the AmbiqSuite SDK. If that path is not specified then this file will
|
||||
# assume that it is located in
|
||||
# <AmbiqSDKRoot>/boards/<your_board>/examples/<your_example>/gcc
|
||||
# and use relative paths
|
||||
#
|
||||
# User Configuration
|
||||
# You must also specify which COM_PORT to use if you want to use the
|
||||
# 'bootlaoder' targets.
|
||||
# Windows example: COM_PORT=COM4
|
||||
# *nix example: COM_PORT=/dev/usbserialxxxx
|
||||
#
|
||||
# Python vs. Executable
|
||||
# For simplicity the upload tools are called as Python scripts by default.
|
||||
# Make sure PYTHON is set to the appropriate command to run Python3 from the
|
||||
# command line.
|
||||
#
|
||||
#******************************************************************************
|
||||
|
||||
|
||||
#******************************************************************************
|
||||
#
|
||||
# User Options
|
||||
#
|
||||
#******************************************************************************
|
||||
|
||||
# You can override these values on the command line e.g. make bootload COM_PORT=/dev/cu***
|
||||
# COM_PORT is the serial port to use for uploading. For example COM#### on Windows or /dev/cu.usbserial-#### on *nix
|
||||
COM_PORT ?=
|
||||
# ASB_UPLOAD_BAUD is the baud rate setting of the Ambiq Secue Bootloader (ASB) as it is configured on the Apollo3. Defautls to 115200 if unset
|
||||
ASB_UPLOAD_BAUD ?=
|
||||
# SVL_UPLOAD_BAUD is the baud rate setting of the SparkFun Variable Loader (SVL). Defaults to 921600 if unset
|
||||
SVL_UPLOAD_BAUD ?=
|
||||
# PYTHON3 should evaluate to a call to the Python3 executable on your machine
|
||||
PYTHON3 ?=
|
||||
|
||||
# *Optionally* specify absolute paths to the SDK and the BSP
|
||||
# You can do this on the command line - e.g. make bootload SDKPATH=~/$AMBIQ_SDK_ROOT_PATH
|
||||
# Make sure to use / instead of \ when on Windows
|
||||
SDKPATH ?=# Set as the path to the SDK root if not located at ../../../../..
|
||||
COMMONPATH ?=# Set as the path to the BSP common folder if not located at ../../../../common
|
||||
BOARDPATH ?=# Set as the path to the board if not located at ../../..
|
||||
PROJECTPATH ?=# Set as the path to the project if not located at ..
|
||||
BOARD ?=# If using a SparkFun board you can simply provide the name e.g. redboard_artemis_atp
|
||||
|
||||
### Project Settings
|
||||
TARGET := hm01b0_camera_uart
|
||||
COMPILERNAME := gcc
|
||||
PROJECT := $(TARGET)_gcc
|
||||
|
||||
|
||||
#******************************************************************************
|
||||
#
|
||||
# Warning Messages
|
||||
#
|
||||
#******************************************************************************
|
||||
ifeq ($(BOARD),)
|
||||
$(warning warning: no BOARD specified, will fall back to BOARDPATH for arbitrary bsp locations)
|
||||
else
|
||||
BOARDPATH=../../../../$(BOARD)
|
||||
$(warning Using BOARD=$(BOARD) at $(BOARDPATH))
|
||||
endif
|
||||
|
||||
ifeq ($(COM_PORT),)
|
||||
COM_PORT=COM4
|
||||
$(warning warning: you have not defined COM_PORT. Assuming it is COM4)
|
||||
endif
|
||||
ifeq ($(PYTHON3),)
|
||||
PYTHON3=python3
|
||||
$(warning warning: you have not defined PYTHON3. assuming it is accessible by 'python3')
|
||||
endif
|
||||
ifeq ($(ASB_UPLOAD_BAUD),)
|
||||
ASB_UPLOAD_BAUD=115200
|
||||
$(warning defaulting to 115200 baud for ASB)
|
||||
endif
|
||||
ifeq ($(SVL_UPLOAD_BAUD),)
|
||||
SVL_UPLOAD_BAUD=921600
|
||||
$(warning defaulting to 921600 baud for SVL)
|
||||
endif
|
||||
|
||||
ifeq ($(SDKPATH),)
|
||||
SDKPATH =../../../../..
|
||||
$(warning warning: you have not defined SDKPATH so will continue assuming that the SDK root is at $(SDKPATH))
|
||||
else
|
||||
# When the SDKPATH is given export it
|
||||
export SDKPATH
|
||||
endif
|
||||
|
||||
ifeq ($(COMMONPATH),)
|
||||
COMMONPATH =../../../../common
|
||||
$(warning warning: you have not defined COMMONPATH so will continue assuming that the COMMON root is at $(COMMONPATH))
|
||||
else
|
||||
# When the COMMONPATH is given export it
|
||||
export COMMONPATH
|
||||
endif
|
||||
|
||||
ifeq ($(BOARDPATH),)
|
||||
$(error Error: BOARDPATH must be provided)
|
||||
else
|
||||
# Ensure that boardpath does not include a trailing '/'
|
||||
ifeq ($(notdir $(BOARDPATH)),)
|
||||
override BOARDPATH:=$(patsubst %/, %,$(BOARDPATH))
|
||||
$(warning BOARDPATH had a trivial 'notdir' so we tried changing it to: $(BOARDPATH))
|
||||
endif
|
||||
BOARD=$(notdir $(BOARDPATH))
|
||||
# When the BOARDPATH is given export it
|
||||
export BOARDPATH
|
||||
endif
|
||||
|
||||
ifeq ($(PROJECTPATH),)
|
||||
PROJECTPATH =..
|
||||
$(warning warning: you have not defined PROJECTPATH so will continue assuming that the PROJECT root is at $(PROJECTPATH))
|
||||
else
|
||||
# When the PROJECTPATH is given export it
|
||||
export PROJECTPATH
|
||||
endif
|
||||
|
||||
CONFIG := $(PROJECTPATH)/gcc/$(BOARD)/bin
|
||||
$(warning CONFIG=$(CONFIG))
|
||||
|
||||
#******************************************************************************
|
||||
#
|
||||
# User Defines / Includes / Sources / Libraries
|
||||
#
|
||||
#******************************************************************************
|
||||
|
||||
# Global Defines
|
||||
DEFINES= -DPART_$(PART)
|
||||
DEFINES+= -DAM_CUSTOM_BDADDR
|
||||
DEFINES+= -DAM_PACKAGE_BGA
|
||||
DEFINES+= -DWSF_TRACE_ENABLED
|
||||
DEFINES+= -DAM_DEBUG_PRINTF
|
||||
DEFINES+= -DAM_PART_APOLLO3
|
||||
DEFINES+=
|
||||
|
||||
# Includes (Add paths to where example header files are located)
|
||||
INCLUDES=
|
||||
INCLUDES+= -I$(PROJECTPATH)/src
|
||||
INCLUDES+= -I$(BOARDPATH)/bsp
|
||||
INCLUDES+= -I$(SDKPATH)
|
||||
INCLUDES+= -I$(SDKPATH)/utils
|
||||
INCLUDES+= -I$(SDKPATH)/devices
|
||||
INCLUDES+= -I$(SDKPATH)/mcu/apollo3
|
||||
INCLUDES+= -I$(SDKPATH)/CMSIS/AmbiqMicro/Include
|
||||
INCLUDES+= -I$(SDKPATH)/CMSIS/ARM/Include
|
||||
INCLUDES+= -I$(COMMONPATH)/third_party/hm01b0
|
||||
INCLUDES+=
|
||||
|
||||
# Compilation Units (Add all the .c files you need to compile)
|
||||
SRC=
|
||||
SRC+= main.cpp
|
||||
SRC+= startup_gcc.c
|
||||
SRC+= am_util_delay.c
|
||||
SRC+= am_util_faultisr.c
|
||||
SRC+= am_util_id.c
|
||||
SRC+= am_util_stdio.c
|
||||
SRC+= HM01B0.c
|
||||
SRC+=
|
||||
|
||||
# VPATH (Add paths to where your source files are located)
|
||||
VPATH=
|
||||
VPATH+= $(PROJECTPATH)/src
|
||||
VPATH+= $(SDKPATH)/utils
|
||||
VPATH+= $(COMMONPATH)/examples/hm01b0_camera_uart
|
||||
VPATH+= $(COMMONPATH)/tools_sfe/templates
|
||||
VPATH+= $(COMMONPATH)/third_party/hm01b0
|
||||
VPATH+=
|
||||
|
||||
# LIBS (Precompiled libraries to include in the linker step)
|
||||
LIBS=
|
||||
LIBS+= $(BOARDPATH)/bsp/gcc/bin/libam_bsp.a
|
||||
LIBS+= $(SDKPATH)/mcu/apollo3/hal/gcc/bin/libam_hal.a
|
||||
LIBS+=
|
||||
|
||||
|
||||
|
||||
#******************************************************************************
|
||||
#
|
||||
# Warning Messages
|
||||
#
|
||||
#******************************************************************************
|
||||
### Bootloader Tools
|
||||
ASB_UPLOADER=$(PYTHON3) $(COMMONPATH)/tools_sfe/asb/asb.py
|
||||
SVL_UPLOADER=$(PYTHON3) $(COMMONPATH)/tools_sfe/svl/svl.py
|
||||
|
||||
|
||||
SHELL:=/bin/bash
|
||||
#### Setup ####
|
||||
|
||||
TOOLCHAIN ?= arm-none-eabi
|
||||
PART = apollo3
|
||||
CPU = cortex-m4
|
||||
FPU = fpv4-sp-d16
|
||||
# Default to FPU hardware calling convention. However, some customers and/or
|
||||
# applications may need the software calling convention.
|
||||
#FABI = softfp
|
||||
FABI = hard
|
||||
|
||||
STARTUP_FILE := ./startup_$(COMPILERNAME).c
|
||||
|
||||
#### Required Executables ####
|
||||
CC = $(TOOLCHAIN)-gcc
|
||||
GCC = $(TOOLCHAIN)-gcc
|
||||
CPP = $(TOOLCHAIN)-cpp
|
||||
CXX = $(TOOLCHAIN)-g++
|
||||
LD = $(TOOLCHAIN)-ld
|
||||
CP = $(TOOLCHAIN)-objcopy
|
||||
OD = $(TOOLCHAIN)-objdump
|
||||
RD = $(TOOLCHAIN)-readelf
|
||||
AR = $(TOOLCHAIN)-ar
|
||||
SIZE = $(TOOLCHAIN)-size
|
||||
RM = $(shell which rm 2>/dev/null)
|
||||
|
||||
EXECUTABLES = CC LD CP OD AR RD SIZE GCC CXX
|
||||
K := $(foreach exec,$(EXECUTABLES),\
|
||||
$(if $(shell which $($(exec)) 2>/dev/null),,\
|
||||
$(info $(exec) not found on PATH ($($(exec))).)$(exec)))
|
||||
$(if $(strip $(value K)),$(info Required Program(s) $(strip $(value K)) not found))
|
||||
|
||||
ifneq ($(strip $(value K)),)
|
||||
all clean:
|
||||
$(info Tools $(TOOLCHAIN)-$(COMPILERNAME) not installed.)
|
||||
$(RM) -rf bin
|
||||
else
|
||||
|
||||
|
||||
|
||||
#******************************************************************************
|
||||
#
|
||||
# Machinery
|
||||
#
|
||||
#******************************************************************************
|
||||
|
||||
XSRC = $(filter %.cpp,$(SRC))
|
||||
ZSRC = $(filter %.cc,$(SRC))
|
||||
CSRC = $(filter %.c,$(SRC))
|
||||
ASRC = $(filter %.s,$(SRC))
|
||||
|
||||
OBJS = $(XSRC:%.cpp=$(CONFIG)/%.o)
|
||||
OBJS+= $(ZSRC:%.cc=$(CONFIG)/%.o)
|
||||
OBJS+= $(CSRC:%.c=$(CONFIG)/%.o)
|
||||
OBJS+= $(ASRC:%.s=$(CONFIG)/%.o)
|
||||
|
||||
DEPS = $(XSRC:%.cpp=$(CONFIG)/%.d)
|
||||
DEPS+= $(ZSRC:%.cc=$(CONFIG)/%.d)
|
||||
DEPS+= $(CSRC:%.c=$(CONFIG)/%.d)
|
||||
DEPS+= $(ASRC:%.s=$(CONFIG)/%.d)
|
||||
|
||||
CSTD = -std=c99
|
||||
|
||||
CFLAGS = -mthumb -mcpu=$(CPU) -mfpu=$(FPU) -mfloat-abi=$(FABI)
|
||||
CFLAGS+= -ffunction-sections -fdata-sections
|
||||
CFLAGS+= -MMD -MP $(CSTD) -Wall -g
|
||||
CFLAGS+= -O0
|
||||
CFLAGS+= $(DEFINES)
|
||||
CFLAGS+= $(INCLUDES)
|
||||
CFLAGS+=
|
||||
|
||||
XSTD = -std=gnu++11
|
||||
|
||||
XFLAGS = $(CFLAGS)
|
||||
XFLAGS+= -fno-exceptions
|
||||
|
||||
LFLAGS = -mthumb -mcpu=$(CPU) -mfpu=$(FPU) -mfloat-abi=$(FABI)
|
||||
LFLAGS+= -nostartfiles -static
|
||||
LFLAGS+= -Wl,--gc-sections,--entry,Reset_Handler,-Map,$(CONFIG)/$(TARGET).map
|
||||
LFLAGS+= -Wl,--start-group -lm -lc -lgcc $(LIBS) -Wl,--end-group
|
||||
LFLAGS+=
|
||||
|
||||
# Additional user specified CFLAGS
|
||||
CFLAGS+=$(EXTRA_CFLAGS)
|
||||
|
||||
CPFLAGS = -Obinary
|
||||
|
||||
ODFLAGS = -S
|
||||
|
||||
#******************************************************************************
|
||||
#
|
||||
# Targets / Rules
|
||||
#
|
||||
#******************************************************************************
|
||||
all: asb
|
||||
asb: directories $(CONFIG)/$(TARGET)_asb.bin
|
||||
svl: directories $(CONFIG)/$(TARGET)_svl.bin
|
||||
|
||||
directories:
|
||||
@mkdir -p $(CONFIG)
|
||||
|
||||
$(CONFIG)/%.o: %.cpp $(CONFIG)/%.d
|
||||
@echo " Compiling $(COMPILERNAME) $<" ;\
|
||||
$(CXX) -c $(XSTD) $(XFLAGS) $< -o $@
|
||||
|
||||
$(CONFIG)/%.o: %.cc $(CONFIG)/%.d
|
||||
@echo " Compiling $(COMPILERNAME) $<" ;\
|
||||
$(CXX) -c $(XSTD) $(XFLAGS) $< -o $@
|
||||
|
||||
$(CONFIG)/%.o: %.c $(CONFIG)/%.d
|
||||
@echo " Compiling $(COMPILERNAME) $<" ;\
|
||||
$(CC) -c $(CFLAGS) $< -o $@
|
||||
|
||||
$(CONFIG)/%.o: %.s $(CONFIG)/%.d
|
||||
@echo " Assembling $(COMPILERNAME) $<" ;\
|
||||
$(CC) -c $(CFLAGS) $< -o $@
|
||||
|
||||
$(CONFIG)/$(TARGET)_asb.axf: LINKER_FILE = $(COMMONPATH)/tools_sfe/templates/asb_linker.ld
|
||||
$(CONFIG)/$(TARGET)_asb.axf: $(OBJS) $(LIBS)
|
||||
@echo " Linking $(COMPILERNAME) $@ with script $(LINKER_FILE)";\
|
||||
$(CC) -Wl,-T,$(LINKER_FILE) -o $@ $(OBJS) $(LFLAGS)
|
||||
|
||||
$(CONFIG)/$(TARGET)_svl.axf: LINKER_FILE = $(COMMONPATH)/tools_sfe/templates/asb_svl_linker.ld
|
||||
$(CONFIG)/$(TARGET)_svl.axf: $(OBJS) $(LIBS)
|
||||
@echo " Linking $(COMPILERNAME) $@ with script $(LINKER_FILE)";\
|
||||
$(CC) -Wl,-T,$(LINKER_FILE) -o $@ $(OBJS) $(LFLAGS)
|
||||
|
||||
$(CONFIG)/$(TARGET)_%.bin: $(CONFIG)/$(TARGET)_%.axf
|
||||
@echo " Copying $(COMPILERNAME) $@..." ;\
|
||||
$(CP) $(CPFLAGS) $< $@ ;\
|
||||
$(OD) $(ODFLAGS) $< > $(CONFIG)/$(TARGET).lst
|
||||
|
||||
bootload_asb: directories $(CONFIG)/$(TARGET)_asb.bin
|
||||
$(ASB_UPLOADER) --bin $(CONFIG)/$(TARGET)_asb.bin --load-address-blob 0x20000 --magic-num 0xCB -o $(CONFIG)/$(TARGET) --version 0x0 --load-address-wired 0xC000 -i 6 --options 0x1 -b $(ASB_UPLOAD_BAUD) -port $(COM_PORT) -r 2 -v
|
||||
|
||||
bootload_svl: directories $(CONFIG)/$(TARGET)_svl.bin
|
||||
$(SVL_UPLOADER) $(COM_PORT) -f $(CONFIG)/$(TARGET)_svl.bin -b $(SVL_UPLOAD_BAUD) -v
|
||||
|
||||
bootload: bootload_svl
|
||||
|
||||
clean:
|
||||
@echo "Cleaning..." ;\
|
||||
$(RM) -f $(OBJS) $(DEPS) \
|
||||
$(CONFIG)/$(TARGET).bin $(CONFIG)/$(TARGET).axf \
|
||||
$(CONFIG)/$(TARGET).lst $(CONFIG)/$(TARGET).map \
|
||||
$(CONFIG)/$(TARGET)_svl.bin $(CONFIG)/$(TARGET)_svl.axf \
|
||||
$(CONFIG)/$(TARGET)_svl.lst $(CONFIG)/$(TARGET)_svl.map \
|
||||
$(CONFIG)/$(TARGET)_asb.bin $(CONFIG)/$(TARGET)_asb.axf \
|
||||
$(CONFIG)/$(TARGET)_asb.lst $(CONFIG)/$(TARGET)_asb.map
|
||||
|
||||
$(CONFIG)/%.d: ;
|
||||
|
||||
$(SDKPATH)/mcu/apollo3/hal/gcc/bin/libam_hal.a:
|
||||
$(MAKE) -C $(SDKPATH)/mcu/apollo3/hal/gcc
|
||||
|
||||
$(SDKPATH)/third_party/uecc/gcc/bin/lib_uecc.a:
|
||||
$(MAKE) -C $(SDKPATH)/third_party/uecc
|
||||
|
||||
$(BOARDPATH)/bsp/gcc/bin/libam_bsp.a:
|
||||
$(MAKE) -C $(BOARDPATH)/bsp/gcc
|
||||
|
||||
# Automatically include any generated dependencies
|
||||
-include $(DEPS)
|
||||
endif
|
||||
.PHONY: all clean directories bootload bootload_asb bootload_svl
|
||||
+356
@@ -0,0 +1,356 @@
|
||||
// based on demo from Himax
|
||||
|
||||
/*
|
||||
Copyright (c) 2019 SparkFun Electronics
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "am_mcu_apollo.h"
|
||||
#include "am_bsp.h"
|
||||
#include "am_util.h"
|
||||
#include "HM01B0.h"
|
||||
#include "HM01B0_RAW8_QVGA_8bits_lsb_5fps.h"
|
||||
#include "platform.h"
|
||||
|
||||
|
||||
//#define DEMO_HM01B0_TEST_MODE_ENABLE
|
||||
#define DEMO_HM01B0_FRAMEBUFFER_DUMP_ENABLE
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// HM01B0 Configuration
|
||||
//
|
||||
//*****************************************************************************
|
||||
static hm01b0_cfg_t s_HM01B0Cfg =
|
||||
{
|
||||
// i2c settings
|
||||
.ui16SlvAddr = HM01B0_DEFAULT_ADDRESS,
|
||||
.eIOMMode = HM01B0_IOM_MODE,
|
||||
.ui32IOMModule = HM01B0_IOM_MODULE,
|
||||
.sIOMCfg =
|
||||
{
|
||||
.eInterfaceMode = HM01B0_IOM_MODE,
|
||||
.ui32ClockFreq = HM01B0_I2C_CLOCK_FREQ,
|
||||
},
|
||||
.pIOMHandle = NULL,
|
||||
.ui8PinSCL = HM01B0_PIN_SCL,
|
||||
.ui8PinSDA = HM01B0_PIN_SDA,
|
||||
|
||||
// MCLK settings
|
||||
.ui32CTimerModule = HM01B0_MCLK_GENERATOR_MOD,
|
||||
.ui32CTimerSegment = HM01B0_MCLK_GENERATOR_SEG,
|
||||
.ui32CTimerOutputPin = HM01B0_PIN_MCLK,
|
||||
|
||||
// data interface
|
||||
.ui8PinD0 = HM01B0_PIN_D0,
|
||||
.ui8PinD1 = HM01B0_PIN_D1,
|
||||
.ui8PinD2 = HM01B0_PIN_D2,
|
||||
.ui8PinD3 = HM01B0_PIN_D3,
|
||||
.ui8PinD4 = HM01B0_PIN_D4,
|
||||
.ui8PinD5 = HM01B0_PIN_D5,
|
||||
.ui8PinD6 = HM01B0_PIN_D6,
|
||||
.ui8PinD7 = HM01B0_PIN_D7,
|
||||
.ui8PinVSYNC = HM01B0_PIN_VSYNC,
|
||||
.ui8PinHSYNC = HM01B0_PIN_HSYNC,
|
||||
.ui8PinPCLK = HM01B0_PIN_PCLK,
|
||||
|
||||
#ifdef HM01B0_PIN_TRIG
|
||||
.ui8PinTrig = HM01B0_PIN_TRIG,
|
||||
#endif // HM01B0_PIN_TRIG
|
||||
|
||||
#ifdef HM01B0_PIN_INT
|
||||
.ui8PinInt = HM01B0_PIN_INT,
|
||||
#endif // HM01B0_PIN_INT
|
||||
|
||||
.pfnGpioIsr = NULL,
|
||||
};
|
||||
|
||||
static uint8_t s_ui8FrameBuffer[HM01B0_PIXEL_X_NUM * HM01B0_PIXEL_Y_NUM];
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Forward declarations
|
||||
//
|
||||
//*****************************************************************************
|
||||
void boost_mode_enable(bool bEnable);
|
||||
void am_gpio_isr(void);
|
||||
void framebuffer_dump(uint8_t *pui8Buffer, uint32_t ui32BufferLen);
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// High Speed UART Configuration
|
||||
//
|
||||
//*****************************************************************************
|
||||
static const am_hal_uart_config_t g_sBspUartConfigHS =
|
||||
{
|
||||
//
|
||||
// Standard UART settings: 115200-8-N-1
|
||||
//
|
||||
.ui32BaudRate = 115200,
|
||||
.ui32DataBits = AM_HAL_UART_DATA_BITS_8,
|
||||
.ui32Parity = AM_HAL_UART_PARITY_NONE,
|
||||
.ui32StopBits = AM_HAL_UART_ONE_STOP_BIT,
|
||||
.ui32FlowControl = AM_HAL_UART_FLOW_CTRL_NONE,
|
||||
|
||||
//
|
||||
// Set TX and RX FIFOs to interrupt at half-full.
|
||||
//
|
||||
.ui32FifoLevels = (AM_HAL_UART_TX_FIFO_1_2 |
|
||||
AM_HAL_UART_RX_FIFO_1_2),
|
||||
|
||||
//
|
||||
// The default interface will just use polling instead of buffers.
|
||||
//
|
||||
.pui8TxBuffer = 0,
|
||||
.ui32TxBufferSize = 0,
|
||||
.pui8RxBuffer = 0,
|
||||
.ui32RxBufferSize = 0,
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Main function.
|
||||
//
|
||||
//*****************************************************************************
|
||||
int main(void)
|
||||
{
|
||||
|
||||
uint32_t ui32Err = HM01B0_ERR_OK;
|
||||
uint16_t ui16ModelId = 0x0000;
|
||||
uint8_t ui8Mode = 0xFF;
|
||||
|
||||
am_hal_clkgen_control(AM_HAL_CLKGEN_CONTROL_SYSCLK_MAX, 0);
|
||||
|
||||
//
|
||||
// Set the default cache configuration
|
||||
//
|
||||
am_hal_cachectrl_config(&am_hal_cachectrl_defaults);
|
||||
am_hal_cachectrl_enable();
|
||||
|
||||
//
|
||||
// Configure the board for low power operation.
|
||||
//
|
||||
am_bsp_low_power_init();
|
||||
|
||||
#ifdef AM_BSP_GPIO_CAMERA_HM01B0_DVDDEN
|
||||
//
|
||||
// Turn on the camera regulator
|
||||
//
|
||||
am_hal_gpio_pinconfig(AM_BSP_GPIO_CAMERA_HM01B0_DVDDEN, g_AM_HAL_GPIO_OUTPUT_12);
|
||||
am_hal_gpio_output_set(AM_BSP_GPIO_CAMERA_HM01B0_DVDDEN);
|
||||
#endif // AM_BSP_GPIO_CAMERA_HM01B0_DVDDEN
|
||||
|
||||
//
|
||||
// Enable the UART print interface at high speed
|
||||
//
|
||||
am_bsp_uart_printf_enable_custom(&g_sBspUartConfigHS);
|
||||
|
||||
//
|
||||
// Clear the terminal and print the banner.
|
||||
//
|
||||
am_util_stdio_terminal_clear();
|
||||
am_util_stdio_printf("HM01B0 Demo\n");
|
||||
am_util_stdio_printf(" SCL:\tPin %d\n", s_HM01B0Cfg.ui8PinSCL);
|
||||
am_util_stdio_printf(" SDA:\tPin %d\n", s_HM01B0Cfg.ui8PinSDA);
|
||||
am_util_stdio_printf(" MCLK:\tPin %d\n", s_HM01B0Cfg.ui32CTimerOutputPin);
|
||||
am_util_stdio_printf(" VSYNC:\tPin %d\n", s_HM01B0Cfg.ui8PinVSYNC);
|
||||
am_util_stdio_printf(" HSYNC\tPin %d\n", s_HM01B0Cfg.ui8PinHSYNC);
|
||||
am_util_stdio_printf(" PCLK:\tPin %d\n", s_HM01B0Cfg.ui8PinPCLK);
|
||||
am_util_stdio_printf(" D0:\tPin %d\n", s_HM01B0Cfg.ui8PinD0);
|
||||
am_util_stdio_printf(" D1:\tPin %d\n", s_HM01B0Cfg.ui8PinD1);
|
||||
am_util_stdio_printf(" D2:\tPin %d\n", s_HM01B0Cfg.ui8PinD2);
|
||||
am_util_stdio_printf(" D3:\tPin %d\n", s_HM01B0Cfg.ui8PinD3);
|
||||
am_util_stdio_printf(" D4:\tPin %d\n", s_HM01B0Cfg.ui8PinD4);
|
||||
am_util_stdio_printf(" D5:\tPin %d\n", s_HM01B0Cfg.ui8PinD5);
|
||||
am_util_stdio_printf(" D6:\tPin %d\n", s_HM01B0Cfg.ui8PinD6);
|
||||
am_util_stdio_printf(" D7:\tPin %d\n", s_HM01B0Cfg.ui8PinD7);
|
||||
|
||||
//
|
||||
// Enable interrupts so we can receive messages from the boot host.
|
||||
//
|
||||
am_hal_interrupt_master_enable();
|
||||
|
||||
boost_mode_enable(true);
|
||||
|
||||
hm01b0_power_up(&s_HM01B0Cfg);
|
||||
|
||||
// todo: check the delay time to just fit the spec.
|
||||
am_util_delay_ms(1);
|
||||
|
||||
hm01b0_mclk_enable(&s_HM01B0Cfg);
|
||||
|
||||
// todo: check the delay time to just fit the spec.
|
||||
am_util_delay_ms(1);
|
||||
|
||||
hm01b0_init_if(&s_HM01B0Cfg);
|
||||
|
||||
hm01b0_get_modelid(&s_HM01B0Cfg, &ui16ModelId);
|
||||
|
||||
am_util_stdio_printf("HM01B0 Model ID 0x%04X\n", ui16ModelId);
|
||||
|
||||
hm01b0_init_system(&s_HM01B0Cfg, (hm_script_t *)sHM01B0InitScript, sizeof(sHM01B0InitScript)/sizeof(hm_script_t));
|
||||
|
||||
#ifdef DEMO_HM01B0_TEST_MODE_ENABLE
|
||||
am_util_stdio_printf("HM01B0 Enable walking 1s test mode\n");
|
||||
hm01b0_test_walking1s(&s_HM01B0Cfg);
|
||||
#else
|
||||
hm01b0_cal_ae(&s_HM01B0Cfg, 10, s_ui8FrameBuffer, sizeof(s_ui8FrameBuffer));
|
||||
#endif
|
||||
|
||||
while(1)
|
||||
{
|
||||
hm01b0_ae_cfg_t sAECfg;
|
||||
|
||||
hm01b0_get_mode(&s_HM01B0Cfg, &ui8Mode);
|
||||
|
||||
am_util_stdio_printf("HM01B0 current mode %d\n", ui8Mode);
|
||||
|
||||
ui32Err = hm01b0_get_ae(&s_HM01B0Cfg, &sAECfg);
|
||||
am_util_stdio_printf("AE convergance(0x%02X) TargetMean 0x%02X, ConvergeInTh 0x%02X, AEMean 0x%02X\n", ui32Err, sAECfg.ui8AETargetMean, sAECfg.ui8ConvergeInTh, sAECfg.ui8AEMean);
|
||||
|
||||
hm01b0_cmd_update(&s_HM01B0Cfg);
|
||||
|
||||
hm01b0_set_mode(&s_HM01B0Cfg, HM01B0_REG_MODE_SELECT_STREAMING_NFRAMES, 1);
|
||||
|
||||
hm01b0_blocking_read_oneframe(&s_HM01B0Cfg, s_ui8FrameBuffer, sizeof(s_ui8FrameBuffer));
|
||||
|
||||
#ifdef DEMO_HM01B0_TEST_MODE_ENABLE
|
||||
hm01b0_test_walking1s_check_data_sanity(s_ui8FrameBuffer, sizeof(s_ui8FrameBuffer), 10);
|
||||
am_util_delay_ms(3000);
|
||||
#endif
|
||||
|
||||
#ifdef DEMO_HM01B0_FRAMEBUFFER_DUMP_ENABLE
|
||||
framebuffer_dump(s_ui8FrameBuffer, sizeof(s_ui8FrameBuffer));
|
||||
#endif
|
||||
memset(s_ui8FrameBuffer, 0x00, sizeof(s_ui8FrameBuffer));
|
||||
|
||||
// give some time for user to stop the external itm logging.
|
||||
am_util_delay_ms(5000);
|
||||
|
||||
}
|
||||
|
||||
hm01b0_deinit_if(&s_HM01B0Cfg);
|
||||
|
||||
hm01b0_mclk_disable(&s_HM01B0Cfg);
|
||||
|
||||
hm01b0_power_down(&s_HM01B0Cfg);
|
||||
|
||||
boost_mode_enable(false);
|
||||
|
||||
//
|
||||
// Loop forever.
|
||||
//
|
||||
while (1)
|
||||
{
|
||||
//
|
||||
// Go to Deep Sleep.
|
||||
//
|
||||
am_hal_sysctrl_sleep(AM_HAL_SYSCTRL_SLEEP_DEEP);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Helper Functions
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
// GPIO ISR
|
||||
void
|
||||
am_gpio_isr(void)
|
||||
{
|
||||
if (s_HM01B0Cfg.pfnGpioIsr)
|
||||
s_HM01B0Cfg.pfnGpioIsr();
|
||||
}
|
||||
|
||||
// frame buffer dump
|
||||
void framebuffer_dump(uint8_t *pui8Buffer, uint32_t ui32BufferLen)
|
||||
{
|
||||
am_util_stdio_printf("+++ frame +++");
|
||||
|
||||
for (uint32_t ui32Idx = 0; ui32Idx < ui32BufferLen; ui32Idx++)
|
||||
{
|
||||
if ((ui32Idx & 0xF) == 0x00)
|
||||
{
|
||||
am_util_stdio_printf("\n0x%08X ", ui32Idx);
|
||||
// this delay is to let itm have time to flush out data.
|
||||
am_util_delay_ms(1);
|
||||
}
|
||||
|
||||
am_util_stdio_printf("%02X ", *(pui8Buffer + ui32Idx));
|
||||
}
|
||||
|
||||
am_util_stdio_printf("\n--- frame ---\n");
|
||||
am_util_delay_ms(1);
|
||||
}
|
||||
|
||||
// burst mode enable
|
||||
void boost_mode_enable(bool bEnable){
|
||||
am_hal_burst_avail_e eBurstModeAvailable;
|
||||
am_hal_burst_mode_e eBurstMode;
|
||||
|
||||
// Check that the Burst Feature is available.
|
||||
if (AM_HAL_STATUS_SUCCESS == am_hal_burst_mode_initialize(&eBurstModeAvailable)){
|
||||
if (AM_HAL_BURST_AVAIL == eBurstModeAvailable){
|
||||
am_util_stdio_printf("Apollo3 Burst Mode is Available\n");
|
||||
}
|
||||
else{
|
||||
am_util_stdio_printf("Apollo3 Burst Mode is Not Available\n");
|
||||
while(1){};
|
||||
}
|
||||
}
|
||||
else{
|
||||
am_util_stdio_printf("Failed to Initialize for Burst Mode operation\n");
|
||||
}
|
||||
|
||||
// Make sure we are in "Normal" mode.
|
||||
if (AM_HAL_STATUS_SUCCESS == am_hal_burst_mode_disable(&eBurstMode)){
|
||||
if (AM_HAL_NORMAL_MODE == eBurstMode){
|
||||
am_util_stdio_printf("Apollo3 operating in Normal Mode (48MHz)\n");
|
||||
}
|
||||
}
|
||||
else{
|
||||
am_util_stdio_printf("Failed to Disable Burst Mode operation\n");
|
||||
}
|
||||
|
||||
// Put the MCU into "Burst" mode.
|
||||
if (bEnable)
|
||||
{
|
||||
if (AM_HAL_STATUS_SUCCESS == am_hal_burst_mode_enable(&eBurstMode)){
|
||||
if (AM_HAL_BURST_MODE == eBurstMode){
|
||||
am_util_stdio_printf("Apollo3 operating in Burst Mode (96MHz)\n");
|
||||
}
|
||||
}
|
||||
else{
|
||||
am_util_stdio_printf("Failed to Enable Burst Mode operation\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import os
|
||||
import sys
|
||||
import argparse
|
||||
import os.path
|
||||
from array import *
|
||||
|
||||
VERSION = 0
|
||||
SUBVERSION = 1
|
||||
|
||||
HIMAX_CMD_OFFSET_OP = 0
|
||||
HIMAX_CMD_OFFSET_ADDR = 1
|
||||
HIMAX_CMD_OFFSET_REGADDR = 2
|
||||
HIMAX_CMD_OFFSET_REGVALUE = 3
|
||||
|
||||
dict_DeviceDefaultAddress = {
|
||||
'HM01B0': '24',
|
||||
}
|
||||
|
||||
def check_file_existence(x):
|
||||
if not os.path.isfile(x):
|
||||
# Argparse uses the ArgumentTypeError to give a rejection message like:
|
||||
# error: argument input: x does not exist
|
||||
raise argparse.ArgumentTypeError("{0} does not exist".format(x))
|
||||
return x
|
||||
|
||||
def create_outputfile(args):
|
||||
|
||||
path = os.path.dirname(os.path.abspath(args.ifile))
|
||||
basename = os.path.split(os.path.splitext(args.ifile)[0])[-1]
|
||||
outputfile = os.path.join(path, basename + '.h')
|
||||
|
||||
return outputfile
|
||||
|
||||
def do_convert(args, ofilename):
|
||||
ofile = open(ofilename, 'w')
|
||||
ofile.write("\n")
|
||||
ofile.write("#include \"%s.h\"\n" % args.model)
|
||||
ofile.write("\n")
|
||||
ofile.write("const hm_script_t s%sInitScript[] =\n" % args.model)
|
||||
ofile.write("{\n")
|
||||
|
||||
with open(args.ifile, 'r') as ifile:
|
||||
for line in ifile:
|
||||
items = line.split()
|
||||
ofile.write("// %s\n" % (' '.join(items)))
|
||||
print("// %s" % (' '.join(items)))
|
||||
if len(items) > 1:
|
||||
if items[HIMAX_CMD_OFFSET_OP] == 'W' and items[HIMAX_CMD_OFFSET_ADDR] == dict_DeviceDefaultAddress.get(args.model):
|
||||
print(" {0x%s, 0x%s,}," % (items[HIMAX_CMD_OFFSET_REGADDR], items[HIMAX_CMD_OFFSET_REGVALUE]))
|
||||
ofile.write(" {0x%s, 0x%s,},\n" % (items[HIMAX_CMD_OFFSET_REGADDR], items[HIMAX_CMD_OFFSET_REGVALUE]))
|
||||
|
||||
ofile.write("};\n")
|
||||
ofile.close()
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description = 'This program converts a given Himax Script into a c header file.')
|
||||
|
||||
parser.add_argument('-i', '--input',
|
||||
dest = 'ifile',
|
||||
required = True,
|
||||
help = 'input file',
|
||||
metavar = 'FILE',
|
||||
type = check_file_existence)
|
||||
|
||||
parser.add_argument('-m', '--model',
|
||||
dest = 'model',
|
||||
required = True,
|
||||
help = 'Himax Sensor Model',
|
||||
choices = ['HM01B0'],
|
||||
default = 'HM01B0',
|
||||
)
|
||||
|
||||
|
||||
parser.add_argument('-v', '--version',
|
||||
help = 'show the program version',
|
||||
action = 'version',
|
||||
version = '%(prog)s {ver}'.format(ver = 'v%d.%d' %\
|
||||
(VERSION, SUBVERSION)))
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
ofilename = create_outputfile(args)
|
||||
|
||||
# print('%s' % ofile)
|
||||
|
||||
do_convert(args, ofilename)
|
||||
|
||||
print "done!"
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
+177
@@ -0,0 +1,177 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import os
|
||||
import sys
|
||||
import argparse
|
||||
import os.path
|
||||
from array import *
|
||||
|
||||
from PIL import Image
|
||||
import numpy as np
|
||||
import re
|
||||
|
||||
dict_Resolutions = {
|
||||
'QVGA': (324, 244),
|
||||
}
|
||||
|
||||
# height = 244
|
||||
# width = 324
|
||||
|
||||
VERSION = 0
|
||||
SUBVERSION = 1
|
||||
|
||||
class RawData:
|
||||
ui8Array = None
|
||||
|
||||
def __init__(self):
|
||||
self.ui8Array = array('B')
|
||||
|
||||
|
||||
def check_file_existence(x):
|
||||
if not os.path.isfile(x):
|
||||
# Argparse uses the ArgumentTypeError to give a rejection message like:
|
||||
# error: argument input: x does not exist
|
||||
raise argparse.ArgumentTypeError("{0} does not exist".format(x))
|
||||
return x
|
||||
|
||||
def create_bmp(args, framelist):
|
||||
|
||||
(width, height) = dict_Resolutions.get(args.resolution, ("Resolution not supported", 0, 0))
|
||||
|
||||
for idx, frame in enumerate(framelist):
|
||||
bitmap = np.zeros((height, width), dtype=np.uint8)
|
||||
|
||||
h_idx = height - 1
|
||||
w_idx = 0
|
||||
|
||||
# fill up bitmap array
|
||||
for pixel in frame.ui8Array:
|
||||
bitmap[h_idx, w_idx] = pixel
|
||||
if w_idx == width - 1:
|
||||
w_idx = 0
|
||||
h_idx -= 1
|
||||
else:
|
||||
w_idx += 1
|
||||
|
||||
|
||||
|
||||
# h_idx = height - 1
|
||||
# w_idx = width - 1
|
||||
|
||||
# # fill up bitmap array
|
||||
# for pixel in frame.ui8Array:
|
||||
# bitmap[h_idx, w_idx] = pixel
|
||||
# if w_idx == 0:
|
||||
# w_idx = width - 1
|
||||
# h_idx -= 1
|
||||
# else:
|
||||
# w_idx -= 1
|
||||
|
||||
|
||||
|
||||
# h_idx = 0
|
||||
# w_idx = 0
|
||||
|
||||
# # fill up bitmap array
|
||||
# for pixel in frame.ui8Array:
|
||||
# bitmap[h_idx, w_idx] = pixel
|
||||
# if w_idx == width - 1:
|
||||
# w_idx = 0
|
||||
# h_idx += 1
|
||||
# else:
|
||||
# w_idx += 1
|
||||
|
||||
|
||||
|
||||
path = os.path.dirname(os.path.abspath(args.inputfile))
|
||||
basename = os.path.split(os.path.splitext(args.inputfile)[0])[-1]
|
||||
outputfile = os.path.join(path, basename + '_' + str(idx) + '.bmp')
|
||||
|
||||
# print (bitmap)
|
||||
img = Image.fromarray(bitmap, 'L')
|
||||
img.save(outputfile)
|
||||
img.show()
|
||||
|
||||
print ("%s created" % (basename + '_' + str(idx) + '.bmp'))
|
||||
|
||||
def do_convert(args):
|
||||
|
||||
(width, height) = dict_Resolutions.get(args.resolution, ("Resolution not supported", 0, 0))
|
||||
|
||||
with open(args.inputfile) as f:
|
||||
h_idx = 0
|
||||
w_idx = 0
|
||||
rawdata = None
|
||||
framestart = False
|
||||
framestop = False
|
||||
framelist = list()
|
||||
|
||||
# collect all pixel data into an int array
|
||||
for line in f:
|
||||
if line == "+++ frame +++\n":
|
||||
framestart = True
|
||||
rawdata = RawData()
|
||||
continue
|
||||
elif line == '--- frame ---\n':
|
||||
framestop = True
|
||||
|
||||
if framestart == True and framestop == False:
|
||||
linelist = re.findall(r"[\w']+", line)
|
||||
|
||||
if len(linelist) != 17:
|
||||
# drop this frame
|
||||
framestart = False
|
||||
continue
|
||||
|
||||
for item in linelist[1 : ]:
|
||||
rawdata.ui8Array.append(int(item, base=16))
|
||||
|
||||
elif framestart == True and framestop == True:
|
||||
|
||||
(address, length) = rawdata.ui8Array.buffer_info()
|
||||
|
||||
if (length * rawdata.ui8Array.itemsize) != (height * width):
|
||||
print ("Incorrect total data length %d" % length * rawdata.ui8Array.itemsize)
|
||||
else:
|
||||
framelist.append(rawdata)
|
||||
framestart = False
|
||||
framestop = False
|
||||
|
||||
create_bmp(args, framelist)
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description = 'This program converts raw data from HM01B0 to a bmp file.')
|
||||
|
||||
parser.add_argument('-i', '--input',
|
||||
dest = 'inputfile',
|
||||
required = True,
|
||||
help = 'input file',
|
||||
metavar = 'FILE',
|
||||
type = check_file_existence
|
||||
)
|
||||
|
||||
parser.add_argument('-r', '--resolution',
|
||||
dest = 'resolution',
|
||||
required = False,
|
||||
help = 'Resolution',
|
||||
choices = ['QVGA'],
|
||||
default = 'QVGA',
|
||||
)
|
||||
|
||||
parser.add_argument('-v', '--version',
|
||||
help = 'Program version',
|
||||
action = 'version',
|
||||
version = '%(prog)s {ver}'.format(ver = 'v%d.%d' %\
|
||||
(VERSION, SUBVERSION))
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
do_convert(args)
|
||||
|
||||
print ("done!")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user