├── .gitignore ├── .gitmodules ├── Kconfig ├── LICENSE ├── README.md ├── components ├── drivers │ ├── CMakeLists.txt │ ├── camera │ │ ├── Kconfig │ │ ├── gc0328 │ │ │ ├── include │ │ │ │ ├── cambus.h │ │ │ │ ├── gc0328.h │ │ │ │ └── sipeed_i2c.h │ │ │ └── src │ │ │ │ ├── cambus.c │ │ │ │ ├── gc0328.c │ │ │ │ └── sipeed_i2c.c │ │ ├── include │ │ │ └── camera.h │ │ ├── ov2640 │ │ │ ├── include │ │ │ │ └── ov2640.h │ │ │ └── src │ │ │ │ └── ov2640.c │ │ ├── ov5640 │ │ │ ├── include │ │ │ │ ├── ov5640.c │ │ │ │ ├── ov5640.h │ │ │ │ ├── ov5640af.h │ │ │ │ └── ov5640cfg.h │ │ │ └── src │ │ │ │ └── ov5640.c │ │ └── src │ │ │ └── camera.c │ ├── lcd │ │ ├── Kconfig │ │ ├── include │ │ │ ├── font.h │ │ │ ├── lcd.h │ │ │ └── nt35310.h │ │ └── src │ │ │ ├── lcd.c │ │ │ └── nt35310.c │ ├── sd_card │ │ ├── Kconfig │ │ ├── include │ │ │ ├── diskio.h │ │ │ ├── ff.h │ │ │ ├── ffconf.h │ │ │ ├── integer.h │ │ │ └── sdcard.h │ │ └── src │ │ │ ├── ccsbcs.c │ │ │ ├── diskio.c │ │ │ ├── ff.c │ │ │ └── sdcard.c │ └── w25q_flash │ │ ├── Kconfig │ │ ├── include │ │ └── w25qxx.h │ │ └── src │ │ └── w25qxx.c ├── kendryte_sdk │ ├── CMakeLists.txt │ └── Kconfig └── utils │ ├── CMakeLists.txt │ ├── Kconfig │ ├── base64 │ ├── include │ │ └── base64.h │ └── src │ │ └── base64.c │ ├── bmp │ ├── include │ │ └── rgb2bmp.h │ └── src │ │ └── rgb2bmp.c │ ├── cJSON │ ├── include │ │ ├── cJSON.h │ │ └── cJSON_Utils.h │ └── src │ │ ├── cJSON.c │ │ └── cJSON_Utils.c │ ├── jpeg_decode │ ├── include │ │ ├── picojpeg.h │ │ └── picojpeg_util.h │ └── src │ │ ├── picojpeg.c │ │ └── picojpeg_util.c │ ├── jpeg_encode │ ├── include │ │ └── jpeg_encode.h │ └── src │ │ └── jpeg_encode.c │ └── yuv_tab │ ├── include │ └── yuv_tab.h │ └── src │ └── yuv_tab.c ├── projects ├── dvp2lcd │ ├── .gitignore │ ├── CMakeLists.txt │ ├── compile │ │ ├── compile_flags.cmake │ │ ├── gen_binary.cmake │ │ ├── kendryte.ld │ │ └── priority.conf │ ├── config_defaults.mk │ ├── download2board.sh │ ├── main │ │ ├── CMakeLists.txt │ │ ├── Kconfig │ │ └── src │ │ │ └── main.c │ └── project.py ├── dvp2sdcard │ ├── .gitignore │ ├── CMakeLists.txt │ ├── compile │ │ ├── compile_flags.cmake │ │ ├── gen_binary.cmake │ │ ├── kendryte.ld │ │ └── priority.conf │ ├── config_defaults.mk │ ├── download2board.sh │ ├── main │ │ ├── CMakeLists.txt │ │ ├── Kconfig │ │ ├── include │ │ │ ├── image_process.h │ │ │ └── sd_image.h │ │ └── src │ │ │ ├── image_process.c │ │ │ ├── main.c │ │ │ └── sd_image.c │ └── project.py └── testproject │ ├── .gitignore │ ├── CMakeLists.txt │ ├── compile │ ├── compile_flags.cmake │ ├── gen_binary.cmake │ ├── kendryte.ld │ └── priority.conf │ ├── config_defaults.mk │ ├── download2board.sh │ ├── main │ ├── CMakeLists.txt │ ├── Kconfig │ └── src │ │ └── main.c │ └── project.py ├── requirements.txt └── tools ├── cmake ├── compile.cmake ├── compile_flags.cmake ├── gen_binary.cmake ├── project.py ├── sort_components.py └── tools.cmake ├── flash ├── flash.py └── kfpkg.py └── kconfig ├── genconfig.py └── update_build_info.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Object files 5 | *.o 6 | *.ko 7 | *.obj 8 | *.elf 9 | 10 | # Linker output 11 | *.ilk 12 | *.map 13 | *.exp 14 | 15 | # Precompiled Headers 16 | *.gch 17 | *.pch 18 | 19 | # Libraries 20 | *.lib 21 | *.a 22 | *.la 23 | *.lo 24 | 25 | # Shared objects (inc. Windows DLLs) 26 | *.dll 27 | *.so 28 | *.so.* 29 | *.dylib 30 | 31 | # Executables 32 | *.exe 33 | *.out 34 | *.app 35 | *.i*86 36 | *.x86_64 37 | *.hex 38 | 39 | # Debug files 40 | *.dSYM/ 41 | *.su 42 | *.idb 43 | *.pdb 44 | 45 | # Kernel Module Compile Results 46 | *.mod* 47 | *.cmd 48 | .tmp_versions/ 49 | modules.order 50 | Module.symvers 51 | Mkfile.old 52 | dkms.conf 53 | 54 | build 55 | .vscode 56 | .config 57 | .config.old 58 | 59 | 60 | # python 61 | *.pyc 62 | __pycache__ 63 | projects/espwifi/* -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "components/kendryte_sdk/kendryte-standalone-sdk"] 2 | path = components/kendryte_sdk/kendryte-standalone-sdk 3 | url = https://github.com/kendryte/kendryte-standalone-sdk 4 | [submodule "tools/flash/kflash_py"] 5 | path = tools/flash/kflash_py 6 | url = https://github.com/sipeed/kflash.py.git 7 | [submodule "tools/kconfig/Kconfiglib"] 8 | path = tools/kconfig/Kconfiglib 9 | url = https://github.com/ulfalizer/Kconfiglib.git 10 | -------------------------------------------------------------------------------- /Kconfig: -------------------------------------------------------------------------------- 1 | 2 | mainmenu "C/CPP CMake project framework Kconfig configuration" 3 | 4 | menu "Toolchain configuration" 5 | config TOOLCHAIN_PATH 6 | string "toolchain path" 7 | default "/opt/kendryte-toolchain/bin" 8 | 9 | config TOOLCHAIN_PREFIX 10 | string "toolchain prefix" 11 | default "riscv64-unknown-elf-" 12 | endmenu 13 | 14 | menu "Components configuration" 15 | osource "${SDK_PATH}/components/*/Kconfig" 16 | endmenu 17 | 18 | osource "${PROJECT_PATH}/*/Kconfig" -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | k210-camera-project 2 | ========== 3 | 4 | This is a simple project for k210 with drivers of different camera type,support save image to sd-card by jpeg or bmp. 5 | 6 | ## Get source code 7 | 8 | * Clone by https link 9 | 10 | ``` 11 | git clone https://github.com/PureHing/k210-camera-project.git 12 | ``` 13 | 14 | * Then get submodules 15 | 16 | ``` 17 | git submodule update --recursive --init 18 | ``` 19 | 20 | It will regiter and clone all submodules, if you don't want to register all submodules, cause some modules is unnecessary, just execute 21 | ``` 22 | git submodule update --init 23 | # or 24 | git submodule update --init path_to_submodule 25 | # or 26 | git submodule update --init --recursive path_to_submodule 27 | ``` 28 | 29 | ## Install dependencies 30 | 31 | Ubuntu for example: 32 | 33 | ``` 34 | sudo apt update 35 | sudo apt install python3 python3-pip build-essential cmake 36 | sudo pip3 install -r requirements.txt 37 | 38 | ``` 39 | > recommend `python3` instead of python2 40 | 41 | Check `CMake` version by 42 | 43 | ``` 44 | cmake --version 45 | ``` 46 | 47 | The `cmake` version should be at least `v3.9`, if not, please install latest `cmake` manually from [cmake website](https://cmake.org/download/) 48 | 49 | 50 | 51 | 52 | ## Download toolchain 53 | 54 | Download the latest toolchain from [here](https://github.com/kendryte/kendryte-gnu-toolchain/releases), or [kendryte-toolchain-ubuntu-amd64-8.2.0-20190409.tar.xz(CDN)](http://dl.cdn.sipeed.com/kendryte-toolchain-ubuntu-amd64-8.2.0-20190409.tar.xz) 55 | 56 | And extract to `/opt/kendryte-toolchain/` 57 | 58 | For example: 59 | 60 | ``` 61 | wget http://dl.cdn.sipeed.com/kendryte-toolchain-ubuntu-amd64-8.2.0-20190409.tar.xz 62 | sudo tar -Jxvf kendryte-toolchain-ubuntu-amd64-8.2.0-20190409.tar.xz -C /opt 63 | ls /opt/kendryte-toolchain/bin 64 | ``` 65 | 66 | ## Configure project 67 | 68 | * Switch path to `testproject` project director 69 | 70 | ``` 71 | cd projects/testproject 72 | ``` 73 | 74 | or 75 | 76 | ``` 77 | cd projects/dvp2lcd 78 | ``` 79 | 80 | * Configure toolchain path 81 | 82 | The default toolchain path is `/opt/kendryte-toolchain/bin`, 83 | and default toolchain pfrefix is `riscv64-unknown-elf-`. 84 | 85 | If you have copied toolchain to `/opt`, just use default. 86 | 87 | Or you can customsize your toolchain path by 88 | 89 | ``` 90 | python project.py --toolchain /opt/kendryte-toolchain/bin --toolchain-prefix riscv64-unknown-elf- config 91 | ``` 92 | 93 | And clean config to default by command 94 | 95 | ``` 96 | python project.py clean_conf 97 | ``` 98 | 99 | * Configure project 100 | 101 | Usually, just use the default configuration. 102 | 103 | If you want to customsize project modules, execute command: 104 | 105 | ``` 106 | python3 project.py menuconfig 107 | ``` 108 | 109 | This command will display a configure panel with GUI, 110 | then change settings and save configuration. 111 | 112 | ## Build 113 | 114 | ``` 115 | python3 project.py build 116 | ``` 117 | 118 | And clean project by: 119 | 120 | ``` 121 | python3 project.py clean 122 | ``` 123 | 124 | Clean all build files by: 125 | 126 | ``` 127 | python3 project.py distclean 128 | ``` 129 | 130 | The make system is generated from `cmake`, 131 | you **MUST** run 132 | 133 | ``` 134 | python3 project.py rebuild 135 | ``` 136 | 137 | to rebuild make system after you **add/delete** source files or edit kconfig files 138 | 139 | 140 | 141 | 142 | ## Flash (Burn) to board 143 | 144 | 145 | For example 146 | 147 | ``` 148 | python3 project.py -B dan -p /dev/ttyUSB0 -b 1500000 -S flash 149 | or 150 | ./download2board.sh 151 | ``` 152 | 153 | `-B` means board, `-p` means board serial device port, `-b` means baudrate, `-S` or `--Slow` means download at low speed but more stable mode. 154 | 155 | the configuration saved in `.flash_conf.json` except args: `--sram`(`-s`)、`--terminal`(`-t`)、`--Slow`(`-S`) 156 | You don't need to confiure again the next time you burn firmware, just use: 157 | ``` 158 | python3 project.py flash 159 | ``` 160 | or 161 | ``` 162 | python3 project.py -S flash 163 | ``` 164 | 165 | 166 | More parameters help by : 167 | 168 | ``` 169 | python3 project.py --help 170 | ``` 171 | 172 | 173 | ## Others 174 | 175 | Build system: refer to [c_cpp_project_framework](https://github.com/Neutree/c_cpp_project_framework) and [MF1-SDK](https://github.com/sipeed/MF1_SDK) 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | -------------------------------------------------------------------------------- /components/drivers/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | list(APPEND ADD_INCLUDE 2 | #camera 3 | "camera/include" 4 | "camera/ov2640/include" 5 | "camera/ov5640/include" 6 | "camera/gc0328/include" 7 | #lcd 8 | "lcd/include" 9 | #w25q_flash 10 | "w25q_flash/include" 11 | #sd card 12 | "sd_card/include" 13 | ) 14 | 15 | if(CONFIG_ENABLE_CAMERA) 16 | append_srcs_dir(ADD_SRCS "camera/src") 17 | 18 | if(CONFIG_CAMERA_GC0328) 19 | append_srcs_dir(ADD_SRCS "camera/gc0328/src") 20 | endif() 21 | if(CONFIG_CAMERA_OV5640) 22 | append_srcs_dir(ADD_SRCS "camera/ov5640/src") 23 | endif() 24 | if(CONFIG_CAMERA_OV2640) 25 | append_srcs_dir(ADD_SRCS "camera/ov2640/src") 26 | endif() 27 | endif() 28 | 29 | if(CONFIG_ENABLE_LCD) 30 | append_srcs_dir(ADD_SRCS "lcd/src") 31 | endif() 32 | 33 | if(CONFIG_ENABLE_FLASH) 34 | append_srcs_dir(ADD_SRCS "w25q_flash/src") 35 | endif() 36 | append_srcs_dir(ADD_SRCS "w25q_flash/src") 37 | if(CONFIG_ENABLE_SD_CARD) 38 | append_srcs_dir(ADD_SRCS "sd_card/src") 39 | endif() 40 | list(APPEND ADD_REQUIREMENTS kendryte_sdk) 41 | register_component() 42 | -------------------------------------------------------------------------------- /components/drivers/camera/Kconfig: -------------------------------------------------------------------------------- 1 | 2 | menu "Camera( Sensor ) configuration" 3 | 4 | comment "SELECT CAMERA TYPE" 5 | 6 | config ENABLE_CAMERA 7 | bool "enable camera" 8 | default y 9 | 10 | choice CAMERA_TYPE 11 | depends on ENABLE_CAMERA 12 | bool "Camera type" 13 | default CAMERA_OV2640 14 | 15 | config CAMERA_OV2640 16 | bool "single ov2640" 17 | config CAMERA_GC0328 18 | bool "single gc0328" 19 | config CAMERA_OV5640 20 | bool "single ov5640" 21 | endchoice 22 | 23 | menu "DVP pin configuration" 24 | depends on ENABLE_CAMERA 25 | config PIN_CMOS_RST 26 | int "Pin CMOS_RST" 27 | default 42 28 | config PIN_CMOS_PWDN 29 | int "Pin CMOS_PWDN" 30 | default 44 31 | config PIN_CMOS_XCLK 32 | int "Pin CMOS_XCLK" 33 | default 46 34 | config PIN_CMOS_VSYNC 35 | int "Pin CMOS_VSYNC" 36 | default 43 37 | 38 | config PIN_CMOS_HREF 39 | int "Pin CMOS_HREF" 40 | default 45 41 | config PIN_CMOS_PCLK 42 | int "Pin CMOS_PCLK" 43 | default 47 44 | config PIN_SCCB_SCLK 45 | int "Pin SCCB_SCLK" 46 | default 41 47 | config PIN_SCCB_SDA 48 | int "Pin SCCB_SDA" 49 | default 40 50 | endmenu 51 | 52 | config CAMERA_RESOLUTION_WIDTH 53 | depends on ENABLE_CAMERA 54 | int "Camera resolution width" 55 | default 320 56 | config CAMERA_RESOLUTION_HEIGHT 57 | depends on ENABLE_CAMERA 58 | int "Camera resolution height" 59 | default 240 60 | endmenu 61 | -------------------------------------------------------------------------------- /components/drivers/camera/gc0328/include/cambus.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the OpenMV project. 3 | * Copyright (c) 2013/2014 Ibrahim Abdelkader 4 | * This work is licensed under the MIT license, see the file LICENSE for details. 5 | * 6 | * Camera bus driver. 7 | * 8 | */ 9 | #ifndef __CAMBUS_H__ 10 | #define __CAMBUS_H__ 11 | #include 12 | int cambus_init(uint8_t reg_wid, int8_t i2c, int8_t pin_clk, int8_t pin_sda, uint8_t gpio_clk, uint8_t gpio_sda); 13 | int cambus_scan(); 14 | int cambus_scan_gc0328(void); 15 | int cambus_readb(uint8_t slv_addr, uint16_t reg_addr, uint8_t *reg_data); 16 | void cambus_set_writeb_delay(uint32_t delay); 17 | int cambus_writeb(uint8_t slv_addr, uint16_t reg_addr, uint8_t reg_data); 18 | int cambus_readw(uint8_t slv_addr, uint16_t reg_addr, uint16_t *reg_data); 19 | int cambus_writew(uint8_t slv_addr, uint16_t reg_addr, uint16_t reg_data); 20 | int cambus_readw2(uint8_t slv_addr, uint16_t reg_addr, uint16_t *reg_data); 21 | int cambus_writew2(uint8_t slv_addr, uint16_t reg_addr, uint16_t reg_data); 22 | uint8_t cambus_reg_width(); 23 | #endif // __CAMBUS_H__ 24 | -------------------------------------------------------------------------------- /components/drivers/camera/gc0328/include/gc0328.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2018 Canaan Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | #ifndef __GC0328_H 16 | #define __GC0328_H 17 | 18 | #include 19 | 20 | #define GC0328_ID (0x9d) 21 | #define GC0328_ADDR (0x21) 22 | 23 | typedef enum { 24 | FRAMESIZE_INVALID = 0, 25 | // C/SIF Resolutions 26 | FRAMESIZE_QQCIF, // 88x72 27 | FRAMESIZE_QCIF, // 176x144 28 | FRAMESIZE_CIF, // 352x288 29 | FRAMESIZE_QQSIF, // 88x60 30 | FRAMESIZE_QSIF, // 176x120 31 | FRAMESIZE_SIF, // 352x240 32 | // VGA Resolutions 33 | FRAMESIZE_QQQQVGA, // 40x30 34 | FRAMESIZE_QQQVGA, // 80x60 35 | FRAMESIZE_QQVGA, // 160x120 36 | FRAMESIZE_QVGA, // 320x240 37 | FRAMESIZE_VGA, // 640x480 38 | FRAMESIZE_HQQQVGA, // 60x40 39 | FRAMESIZE_HQQVGA, // 120x80 40 | FRAMESIZE_HQVGA, // 240x160 41 | // FFT Resolutions 42 | FRAMESIZE_64X32, // 64x32 43 | FRAMESIZE_64X64, // 64x64 44 | FRAMESIZE_128X64, // 128x64 45 | FRAMESIZE_128X128, // 128x128 46 | FRAMESIZE_240X240, // 240x240 47 | // Other 48 | FRAMESIZE_LCD, // 128x160 49 | FRAMESIZE_QQVGA2, // 128x160 50 | FRAMESIZE_WVGA, // 720x480 51 | FRAMESIZE_WVGA2, // 752x480 52 | FRAMESIZE_SVGA, // 800x600 53 | FRAMESIZE_SXGA, // 1280x1024 54 | FRAMESIZE_UXGA, // 1600x1200 55 | } framesize_t; 56 | 57 | 58 | //int gc0328_reset(sensor_t*); 59 | //uint8_t gc0328_scan(void); 60 | int gc0328_init(void); 61 | int gc0328_reset(void); 62 | int gc0328_set_framesize(framesize_t framesize); 63 | 64 | #endif /* __GC0328_H */ 65 | -------------------------------------------------------------------------------- /components/drivers/camera/gc0328/include/sipeed_i2c.h: -------------------------------------------------------------------------------- 1 | #ifndef __MAIX_I2C_H__ 2 | #define __MAIX_I2C_H__ 3 | 4 | #include "i2c.h" 5 | 6 | #define I2C_CON_SPEED_STANDARD 1 // <=100Kbit/s 7 | #define I2C_CON_SPEED_FAST 2 // <=400Kbit/s or <=1000Kbit/s 8 | #define I2C_CON_SPEED_HIGH 3 // <=3.4Mbit/s 9 | 10 | void maix_i2c_init(i2c_device_number_t i2c_num, uint32_t address_width, 11 | uint32_t i2c_clk); 12 | int maix_i2c_send_data(i2c_device_number_t i2c_num, uint32_t slave_address, const uint8_t *send_buf, size_t send_buf_len, uint16_t timeout_ms); 13 | int maix_i2c_recv_data(i2c_device_number_t i2c_num, uint32_t slave_address, const uint8_t *send_buf, size_t send_buf_len, uint8_t *receive_buf, 14 | size_t receive_buf_len, uint16_t timeout_ms); 15 | void maix_i2c_deinit(i2c_device_number_t i2c_num); 16 | #endif //__MAIX_I2C_H__ 17 | -------------------------------------------------------------------------------- /components/drivers/camera/gc0328/src/cambus.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the OpenMV project. 3 | * Copyright (c) 2013/2014 Ibrahim Abdelkader 4 | * This work is licensed under the MIT license, see the file LICENSE for details. 5 | * 6 | * SCCB (I2C like) driver. 7 | * 8 | */ 9 | #include 10 | //#include "omv_boardconfig.h" 11 | #include "cambus.h" 12 | #include "dvp.h" 13 | #include "gc0328.h" 14 | //#include "py/mpprint.h" 15 | #include "sysctl.h" 16 | #include "fpioa.h" 17 | #include "sipeed_i2c.h" 18 | #include "printf.h" 19 | #include "sleep.h" 20 | //#include "mphalport.h" 21 | 22 | static uint32_t write_bus_delay = 10; //ms 23 | 24 | void cambus_set_writeb_delay(uint32_t delay) 25 | { 26 | write_bus_delay = delay; 27 | } 28 | 29 | /** 30 | * @i2c -2: hardware sccb i2c, -1: soft, [0,2]: hardware i2c 31 | */ 32 | int sccb_i2c_init(int8_t i2c, uint8_t pin_clk, uint8_t pin_sda, uint8_t gpio_clk, uint8_t gpio_sda, uint32_t freq) 33 | { 34 | if(i2c == -2) 35 | { 36 | // dvp_sccb_set_clk_rate(1000000); 37 | fpioa_set_function(pin_clk, FUNC_SCCB_SCLK); 38 | fpioa_set_function(pin_sda, FUNC_SCCB_SDA); 39 | } 40 | else if(i2c == -1) 41 | { 42 | } 43 | else 44 | { 45 | if(i2c>2 || i2c<0) 46 | return -1; 47 | printf("init i2c%d\r\n", i2c); 48 | fpioa_set_function(pin_clk, FUNC_I2C0_SCLK + i2c * 2); 49 | fpioa_set_function(pin_sda, FUNC_I2C0_SDA + i2c * 2); 50 | maix_i2c_init((i2c_device_number_t)i2c, 7, freq); 51 | } 52 | return 0; 53 | } 54 | 55 | int sccb_i2c_write_byte(int8_t i2c, uint8_t addr, uint16_t reg, uint8_t reg_len, uint8_t data, uint16_t timeout_ms) 56 | { 57 | if(i2c == -2) 58 | { 59 | dvp_sccb_send_data(addr, reg, data); 60 | } 61 | else if(i2c == -1) 62 | { 63 | } 64 | else 65 | { 66 | if(i2c>2 || i2c<0) 67 | return -1; 68 | uint8_t tmp[3]; 69 | if(reg_len == 8) 70 | { 71 | tmp[0] = reg & 0xFF; 72 | tmp[1] = data; 73 | return maix_i2c_send_data((i2c_device_number_t)i2c, addr, tmp, 2, 10); 74 | } 75 | else 76 | { 77 | tmp[0] = (reg>>8) & 0xFF; 78 | tmp[1] = reg&0xFF; 79 | tmp[2] = data; 80 | return maix_i2c_send_data((i2c_device_number_t)i2c, addr, tmp, 3, 10); 81 | } 82 | } 83 | return 0; 84 | } 85 | 86 | int sccb_i2c_read_byte(int8_t i2c, uint8_t addr, uint16_t reg, uint8_t reg_len, uint8_t* data, uint16_t timeout_ms) 87 | { 88 | *data = 0; 89 | if(i2c == -2) 90 | { 91 | *data = dvp_sccb_receive_data(addr, reg); 92 | } 93 | else if(i2c == -1) 94 | { 95 | } 96 | else 97 | { 98 | if(i2c>2 || i2c<0) 99 | return -1; 100 | uint8_t tmp[2]; 101 | if(reg_len == 8) 102 | { 103 | tmp[0] = reg & 0xFF; 104 | maix_i2c_send_data((i2c_device_number_t)i2c, addr, tmp, 1, 10); 105 | int ret = maix_i2c_recv_data((i2c_device_number_t)i2c, addr, NULL, 0, data, 1, 10); 106 | return ret; 107 | } 108 | else 109 | { 110 | tmp[0] = (reg>>8) & 0xFF; 111 | tmp[1] = reg&0xFF; 112 | int ret = maix_i2c_send_data((i2c_device_number_t)i2c, addr, tmp, 2, 10); 113 | if(ret != 0) 114 | return ret; 115 | ret = maix_i2c_recv_data((i2c_device_number_t)i2c, addr, NULL, 0, data, 1, 10); 116 | return ret; 117 | } 118 | } 119 | return 0; 120 | } 121 | 122 | int sccb_i2c_recieve_byte(int8_t i2c, uint8_t addr, uint8_t* data, uint16_t timeout_ms) 123 | { 124 | if(i2c == -2) 125 | { 126 | *data = dvp_sccb_receive_data(addr, 0x00); 127 | return *data; 128 | } 129 | else if(i2c == -1) 130 | { 131 | } 132 | else 133 | { 134 | if(i2c>2 || i2c<0) 135 | return -1; 136 | int ret = maix_i2c_recv_data((i2c_device_number_t)i2c, addr, NULL, 0, data, 1, 10); 137 | return ret; 138 | } 139 | return 0; 140 | } 141 | 142 | static uint8_t sccb_reg_width = 8; 143 | static int8_t i2c_device = -2; 144 | 145 | /** 146 | * 147 | * @i2c_type 0: sccb, 1:hardware i2c, 2:software i2c 148 | * 149 | */ 150 | int cambus_init(uint8_t reg_wid, int8_t i2c, int8_t pin_clk, int8_t pin_sda, uint8_t gpio_clk, uint8_t gpio_sda) 151 | { 152 | // dvp_init(reg_wid); 153 | sccb_reg_width = reg_wid; 154 | if(pin_clk<0 || pin_sda<0) 155 | return -1; 156 | i2c_device = i2c; 157 | sccb_i2c_init(i2c_device, pin_clk, pin_sda, gpio_clk, gpio_sda,100000 ); 158 | return 0; 159 | } 160 | int cambus_read_id(uint8_t addr,uint16_t *manuf_id, uint16_t *device_id) 161 | { 162 | *manuf_id = 0; 163 | *device_id = 0; 164 | uint8_t tmp = 0; 165 | int ret = 0; 166 | 167 | // sccb_i2c_write_byte(i2c_device, addr, 0xFF, sccb_reg_width, 0x01, 10); 168 | ret |= sccb_i2c_read_byte(i2c_device, addr, 0x1C, sccb_reg_width, &tmp, 100); 169 | *manuf_id = tmp << 8; 170 | ret |= sccb_i2c_read_byte(i2c_device, addr, 0x1D, sccb_reg_width, &tmp, 100); 171 | *manuf_id |= tmp; 172 | ret |= sccb_i2c_read_byte(i2c_device, addr, 0x0A, sccb_reg_width, &tmp, 100); 173 | *device_id = tmp << 8; 174 | ret |= sccb_i2c_read_byte(i2c_device, addr, 0x0B, sccb_reg_width, &tmp, 100); 175 | *device_id |= tmp; 176 | // printk("ret:%d %04x %04x\r\n",ret, *manuf_id, *device_id); 177 | return ret; 178 | } 179 | 180 | int cambus_read16_id(uint8_t addr,uint16_t *manuf_id, uint16_t *device_id) 181 | { 182 | *manuf_id = 0; 183 | *device_id = 0; 184 | uint8_t tmp = 0; 185 | int ret = 0; 186 | //TODO: 0x300A 0x300B maybe just for OV3660 187 | // sccb_i2c_write_byte(i2c_device, addr, 0xFF, sccb_reg_width, 0x01, 10); 188 | ret |= sccb_i2c_read_byte(i2c_device, addr, 0x300A, sccb_reg_width, &tmp, 100); 189 | if(ret != 0) 190 | return ret; 191 | *device_id = tmp << 8; 192 | ret |= sccb_i2c_read_byte(i2c_device, addr, 0x300B, sccb_reg_width, &tmp, 100); 193 | *device_id |= tmp; 194 | // printk("ret:%d %04x %04x\r\n",ret, *manuf_id, *device_id); 195 | return ret; 196 | } 197 | 198 | int cambus_scan() 199 | { 200 | 201 | uint16_t manuf_id = 0; 202 | uint16_t device_id = 0; 203 | sccb_reg_width = 8; 204 | for (uint8_t addr=0x08; addr<=0x77; addr++) { 205 | if( cambus_read_id(addr ,&manuf_id,&device_id) != 0) 206 | continue; 207 | if(device_id!=0 && device_id!=0xffff) 208 | { 209 | return addr; 210 | } 211 | } 212 | sccb_reg_width = 16; 213 | for (uint8_t addr=0x08; addr<=0x77; addr++) { 214 | if( cambus_read16_id(addr ,&manuf_id,&device_id) != 0) 215 | continue; 216 | if(device_id!=0 && device_id!=0xffff) 217 | { 218 | return addr; 219 | } 220 | } 221 | return 0; 222 | } 223 | int cambus_scan_gc0328(void) 224 | { 225 | uint8_t id; 226 | sccb_reg_width = 8; 227 | sccb_i2c_write_byte(i2c_device, GC0328_ADDR, 0xFE, sccb_reg_width, 0x00, 10); 228 | sccb_i2c_read_byte(i2c_device, GC0328_ADDR, 0xF0, sccb_reg_width, &id, 10); 229 | if (id != 0x9d) 230 | { 231 | printf("error gc0328 detect, ret id is 0x%x\r\n", id); 232 | return 0; 233 | } 234 | printf("===== id: %x =====,gc0328 detect\r\n", id); 235 | return id; 236 | } 237 | int cambus_readb(uint8_t slv_addr, uint16_t reg_addr, uint8_t *reg_data) 238 | { 239 | 240 | int ret = 0; 241 | sccb_i2c_read_byte(i2c_device, slv_addr, reg_addr, sccb_reg_width, reg_data, 10); 242 | if(0xff == *reg_data) 243 | ret = -1; 244 | 245 | return ret; 246 | 247 | } 248 | 249 | int cambus_writeb(uint8_t slv_addr, uint16_t reg_addr, uint8_t reg_data) 250 | { 251 | sccb_i2c_write_byte(i2c_device, slv_addr, reg_addr, sccb_reg_width, reg_data, 10); 252 | msleep(write_bus_delay); 253 | return 0; 254 | } 255 | 256 | int cambus_readw(uint8_t slv_addr, uint16_t reg_addr, uint16_t *reg_data) 257 | { 258 | return 0; 259 | } 260 | 261 | int cambus_writew(uint8_t slv_addr, uint16_t reg_addr, uint16_t reg_data) 262 | { 263 | return 0; 264 | } 265 | 266 | int cambus_readw2(uint8_t slv_addr, uint16_t reg_addr, uint16_t *reg_data) 267 | { 268 | return 0; 269 | } 270 | 271 | int cambus_writew2(uint8_t slv_addr, uint16_t reg_addr, uint16_t reg_data) 272 | { 273 | return 0; 274 | } 275 | 276 | uint8_t cambus_reg_width() 277 | { 278 | return sccb_reg_width; 279 | } 280 | 281 | -------------------------------------------------------------------------------- /components/drivers/camera/include/camera.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef __cplusplus 4 | extern "C" { 5 | #endif 6 | 7 | void camera_init(); 8 | 9 | #ifdef __cplusplus 10 | } // extern "C" { 11 | #endif -------------------------------------------------------------------------------- /components/drivers/camera/ov2640/include/ov2640.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2018 Canaan Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | #ifndef _OV2640_H 16 | #define _OV2640_H 17 | 18 | #include 19 | 20 | #define OV2640_ADDR 0x60 21 | 22 | int ov2640_init(void); 23 | int ov2640_read_id(uint16_t *manuf_id, uint16_t *device_id); 24 | 25 | #endif /* _OV2640_H */ 26 | 27 | -------------------------------------------------------------------------------- /components/drivers/camera/ov2640/src/ov2640.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2018 Canaan Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | #include 16 | #include "ov2640.h" 17 | #include "dvp.h" 18 | #include "plic.h" 19 | #include "global_config.h" 20 | #include "syslog.h" 21 | static const char *TAG = "ov2640"; 22 | const uint8_t ov2640_config[][2]= 23 | { 24 | {0xff, 0x01}, 25 | {0x12, 0x80}, 26 | {0xff, 0x00}, 27 | {0x2c, 0xff}, 28 | {0x2e, 0xdf}, 29 | {0xff, 0x01}, 30 | {0x3c, 0x32}, 31 | {0x11, 0x00}, 32 | {0x09, 0x02}, 33 | #if CONFIG_MAIX_DOCK 34 | {0x04, 0x88},//0xd8,0x08 35 | #else 36 | {0x04, 0x58}, 37 | #endif 38 | {0x13, 0xe5}, 39 | {0x14, 0x48}, 40 | {0x2c, 0x0c}, 41 | {0x33, 0x78}, 42 | {0x3a, 0x33}, 43 | {0x3b, 0xfb}, 44 | {0x3e, 0x00}, 45 | {0x43, 0x11}, 46 | {0x16, 0x10}, 47 | {0x39, 0x92}, 48 | {0x35, 0xda}, 49 | {0x22, 0x1a}, 50 | {0x37, 0xc3}, 51 | {0x23, 0x00}, 52 | {0x34, 0xc0}, 53 | {0x36, 0x1a}, 54 | {0x06, 0x88}, 55 | {0x07, 0xc0}, 56 | {0x0d, 0x87}, 57 | {0x0e, 0x41}, 58 | {0x4c, 0x00}, 59 | {0x48, 0x00}, 60 | {0x5b, 0x00}, 61 | {0x42, 0x03}, 62 | {0x4a, 0x81}, 63 | {0x21, 0x99}, 64 | {0x24, 0x40}, 65 | {0x25, 0x38}, 66 | {0x26, 0x82}, 67 | {0x5c, 0x00}, 68 | {0x63, 0x00}, 69 | {0x46, 0x22}, 70 | {0x0c, 0x3c}, 71 | {0x61, 0x70}, 72 | {0x62, 0x80}, 73 | {0x7c, 0x05}, 74 | {0x20, 0x80}, 75 | {0x28, 0x30}, 76 | {0x6c, 0x00}, 77 | {0x6d, 0x80}, 78 | {0x6e, 0x00}, 79 | {0x70, 0x02}, 80 | {0x71, 0x94}, 81 | {0x73, 0xc1}, 82 | {0x3d, 0x34}, 83 | {0x5a, 0x57}, 84 | {0x12, 0x40}, 85 | {0x17, 0x11}, 86 | {0x18, 0x43}, 87 | {0x19, 0x00}, 88 | {0x1a, 0x4b}, 89 | {0x32, 0x09}, 90 | {0x37, 0xc0}, 91 | {0x4f, 0xca}, 92 | {0x50, 0xa8}, 93 | {0x5a, 0x23}, 94 | {0x6d, 0x00}, 95 | {0x3d, 0x38}, 96 | {0xff, 0x00}, 97 | {0xe5, 0x7f}, 98 | {0xf9, 0xc0}, 99 | {0x41, 0x24}, 100 | {0xe0, 0x14}, 101 | {0x76, 0xff}, 102 | {0x33, 0xa0}, 103 | {0x42, 0x20}, 104 | {0x43, 0x18}, 105 | {0x4c, 0x00}, 106 | {0x87, 0xd5}, 107 | {0x88, 0x3f}, 108 | {0xd7, 0x03}, 109 | {0xd9, 0x10}, 110 | {0xd3, 0x82}, 111 | {0xc8, 0x08}, 112 | {0xc9, 0x80}, 113 | {0x7c, 0x00}, 114 | {0x7d, 0x00}, 115 | {0x7c, 0x03}, 116 | {0x7d, 0x48}, 117 | {0x7d, 0x48}, 118 | {0x7c, 0x08}, 119 | {0x7d, 0x20}, 120 | {0x7d, 0x10}, 121 | {0x7d, 0x0e}, 122 | {0x90, 0x00}, 123 | {0x91, 0x0e}, 124 | {0x91, 0x1a}, 125 | {0x91, 0x31}, 126 | {0x91, 0x5a}, 127 | {0x91, 0x69}, 128 | {0x91, 0x75}, 129 | {0x91, 0x7e}, 130 | {0x91, 0x88}, 131 | {0x91, 0x8f}, 132 | {0x91, 0x96}, 133 | {0x91, 0xa3}, 134 | {0x91, 0xaf}, 135 | {0x91, 0xc4}, 136 | {0x91, 0xd7}, 137 | {0x91, 0xe8}, 138 | {0x91, 0x20}, 139 | {0x92, 0x00}, 140 | {0x93, 0x06}, 141 | {0x93, 0xe3}, 142 | {0x93, 0x05}, 143 | {0x93, 0x05}, 144 | {0x93, 0x00}, 145 | {0x93, 0x04}, 146 | {0x93, 0x00}, 147 | {0x93, 0x00}, 148 | {0x93, 0x00}, 149 | {0x93, 0x00}, 150 | {0x93, 0x00}, 151 | {0x93, 0x00}, 152 | {0x93, 0x00}, 153 | {0x96, 0x00}, 154 | {0x97, 0x08}, 155 | {0x97, 0x19}, 156 | {0x97, 0x02}, 157 | {0x97, 0x0c}, 158 | {0x97, 0x24}, 159 | {0x97, 0x30}, 160 | {0x97, 0x28}, 161 | {0x97, 0x26}, 162 | {0x97, 0x02}, 163 | {0x97, 0x98}, 164 | {0x97, 0x80}, 165 | {0x97, 0x00}, 166 | {0x97, 0x00}, 167 | {0xc3, 0xed}, 168 | {0xa4, 0x00}, 169 | {0xa8, 0x00}, 170 | {0xc5, 0x11}, 171 | {0xc6, 0x51}, 172 | {0xbf, 0x80}, 173 | {0xc7, 0x10}, 174 | {0xb6, 0x66}, 175 | {0xb8, 0xa5}, 176 | {0xb7, 0x64}, 177 | {0xb9, 0x7c}, 178 | {0xb3, 0xaf}, 179 | {0xb4, 0x97}, 180 | {0xb5, 0xff}, 181 | {0xb0, 0xc5}, 182 | {0xb1, 0x94}, 183 | {0xb2, 0x0f}, 184 | {0xc4, 0x5c}, 185 | {0xc0, 0x64}, 186 | {0xc1, 0x4b}, 187 | {0x8c, 0x00}, 188 | {0x86, 0x3d}, 189 | {0x50, 0x00}, 190 | {0x51, 0xc8}, 191 | {0x52, 0x96}, 192 | {0x53, 0x00}, 193 | {0x54, 0x00}, 194 | {0x55, 0x00}, 195 | {0x5a, 0xc8}, 196 | {0x5b, 0x96}, 197 | {0x5c, 0x00}, 198 | {0xd3, 0x02}, 199 | {0xc3, 0xed}, 200 | {0x7f, 0x00}, 201 | {0xda, 0x08}, 202 | {0xe5, 0x1f}, 203 | {0xe1, 0x67}, 204 | {0xe0, 0x00}, 205 | {0xdd, 0x7f}, 206 | {0x05, 0x00}, 207 | {0xff, 0x00}, 208 | {0xe0, 0x04}, 209 | {0x5a, 0x50}, 210 | {0x5b, 0x3c}, 211 | {0x5c, 0x00}, 212 | {0xe0, 0x00}, 213 | {0x00, 0x00} 214 | }; 215 | 216 | int ov2640_init(void) 217 | { 218 | uint16_t v_manuf_id; 219 | uint16_t v_device_id; 220 | ov2640_read_id(&v_manuf_id, &v_device_id); 221 | LOGI(TAG,"manuf_id:0x%04x,device_id:0x%04x,ov2640 detect", v_manuf_id, v_device_id); 222 | uint16_t index = 0; 223 | for (index = 0; ov2640_config[index][0]; index++) 224 | dvp_sccb_send_data(OV2640_ADDR, ov2640_config[index][0], ov2640_config[index][1]); 225 | return 0; 226 | } 227 | 228 | int ov2640_read_id(uint16_t *manuf_id, uint16_t *device_id) 229 | { 230 | dvp_sccb_send_data(OV2640_ADDR, 0xFF, 0x01); 231 | *manuf_id = (dvp_sccb_receive_data(OV2640_ADDR, 0x1C) << 8) | dvp_sccb_receive_data(OV2640_ADDR, 0x1D); 232 | *device_id = (dvp_sccb_receive_data(OV2640_ADDR, 0x0A) << 8) | dvp_sccb_receive_data(OV2640_ADDR, 0x0B); 233 | return 0; 234 | } 235 | 236 | -------------------------------------------------------------------------------- /components/drivers/camera/ov5640/include/ov5640.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2018 Canaan Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | #ifndef _OV5640_H 16 | #define _OV5640_H 17 | 18 | #include 19 | 20 | #define OV5640_ID 0X5640 21 | #define OV5640_ADDR 0X78 22 | #define OV5640_CHIPIDH 0X300A 23 | #define OV5640_CHIPIDL 0X300B 24 | 25 | #define XSIZE 320 26 | #define YSIZE 240 27 | #define LCD_GRAM_ADDRESS 0x60020000 28 | 29 | #define QQVGA_160_120 0 30 | #define QCIF_176_144 1 31 | #define QVGA_320_240 2 32 | #define WQVGA_400_240 3 33 | #define CIF_352_288 4 34 | 35 | 36 | 37 | uint8_t ov5640_init(void); 38 | void ov5640_flash_lamp(uint8_t sw); 39 | void OV5640_Brightness(uint8_t bright); 40 | void OV5640_Exposure(uint8_t exposure); 41 | void OV5640_Light_Mode(uint8_t mode); 42 | void OV5640_Color_Saturation(uint8_t sat); 43 | void OV5640_Brightness(uint8_t bright); 44 | void OV5640_Contrast(uint8_t contrast); 45 | void OV5640_Sharpness(uint8_t sharp); 46 | void OV5640_Special_Effects(uint8_t eft); 47 | uint8_t OV5640_Focus_Init(void); 48 | uint8_t OV5640_Auto_Focus(void); 49 | 50 | #endif 51 | 52 | -------------------------------------------------------------------------------- /components/drivers/camera/ov5640/src/ov5640.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2018 Canaan Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | #include 16 | #include 17 | #include "ov5640.h" 18 | #include "ov5640cfg.h" 19 | #include "ov5640af.h" 20 | #include "dvp.h" 21 | 22 | static void hal_delay(uint32_t delay) 23 | { 24 | usleep(delay * 1000); 25 | } 26 | 27 | static void ov5640_wr_reg(uint16_t reg,uint8_t data) 28 | { 29 | dvp_sccb_send_data(OV5640_ADDR, reg, data); 30 | } 31 | 32 | static uint8_t ov5640_rd_reg(uint16_t reg) 33 | { 34 | return dvp_sccb_receive_data(OV5640_ADDR, reg); 35 | } 36 | 37 | uint8_t ov5640_init(void) 38 | { 39 | uint16_t i = 0; 40 | uint16_t reg = 0; 41 | 42 | reg = ov5640_rd_reg(OV5640_CHIPIDH); 43 | reg <<= 8; 44 | reg |= ov5640_rd_reg(OV5640_CHIPIDL); 45 | printf("ID: %X \r\n", reg); 46 | if(reg != OV5640_ID) 47 | { 48 | printf("ID: %d \r\n", reg); 49 | return 1; 50 | } 51 | 52 | ov5640_wr_reg(0x3103,0X11); /*system clock from pad, bit[1]*/ 53 | ov5640_wr_reg(0X3008,0X82); 54 | hal_delay(10); 55 | 56 | for(i = 0; i1000)return 1; 281 | }while(state!=0x70); 282 | return 0; 283 | } 284 | 285 | uint8_t OV5640_Auto_Focus(void) 286 | { 287 | uint8_t temp=0; 288 | uint16_t retry=0; 289 | ov5640_wr_reg(0x3023,0x01); 290 | ov5640_wr_reg(0x3022,0x08); 291 | do 292 | { 293 | temp=ov5640_rd_reg(0x3023); 294 | retry++; 295 | if(retry>1000)return 2; 296 | hal_delay(5); 297 | } while(temp!=0x00); 298 | ov5640_wr_reg(0x3023,0x01); 299 | ov5640_wr_reg(0x3022,0x04); 300 | retry=0; 301 | do 302 | { 303 | temp=ov5640_rd_reg(0x3023); 304 | retry++; 305 | if(retry>1000)return 2; 306 | hal_delay(5); 307 | }while(temp!=0x00); 308 | return 0; 309 | } 310 | 311 | -------------------------------------------------------------------------------- /components/drivers/camera/src/camera.c: -------------------------------------------------------------------------------- 1 | #include "global_config.h" 2 | #include "fpioa.h" 3 | #include "sysctl.h" 4 | #include "dvp.h" 5 | #include "ov5640.h" 6 | #include "ov2640.h" 7 | #include "gc0328.h" 8 | #include "cambus.h" 9 | #include "syslog.h" 10 | static const char *TAG = "camera_init"; 11 | 12 | 13 | static void io_mux_init(void) 14 | { 15 | 16 | #if CONFIG_MAIX_DOCK 17 | /* Init DVP IO map and function settings */ 18 | fpioa_set_function(CONFIG_PIN_CMOS_RST, FUNC_CMOS_RST); 19 | fpioa_set_function(CONFIG_PIN_CMOS_PWDN, FUNC_CMOS_PWDN); 20 | fpioa_set_function(CONFIG_PIN_CMOS_XCLK, FUNC_CMOS_XCLK); 21 | fpioa_set_function(CONFIG_PIN_CMOS_VSYNC, FUNC_CMOS_VSYNC); 22 | fpioa_set_function(CONFIG_PIN_CMOS_HREF, FUNC_CMOS_HREF); 23 | fpioa_set_function(CONFIG_PIN_CMOS_PCLK, FUNC_CMOS_PCLK); 24 | fpioa_set_function(CONFIG_PIN_SCCB_SCLK, FUNC_SCCB_SCLK); 25 | fpioa_set_function(CONFIG_PIN_SCCB_SDA, FUNC_SCCB_SDA); 26 | #if CONFIG_ENABLE_LCD 27 | /* Init SPI IO map and function settings */ 28 | fpioa_set_function(CONFIG_PIN_NUM_LCD_DCX, FUNC_GPIOHS0 + CONFIG_GPIOHS_NUM_LCD_DCX); 29 | fpioa_set_function(CONFIG_PIN_NUM_LCD_WRX, FUNC_SPI0_SS3); 30 | fpioa_set_function(CONFIG_PIN_NUM_LCD_SCK, FUNC_SPI0_SCLK); 31 | fpioa_set_function(CONFIG_PIN_NUM_LCD_RST, FUNC_GPIOHS0 + CONFIG_GPIOHS_NUM_LCD_RST); 32 | #endif 33 | sysctl_set_spi0_dvp_data(1); 34 | #if CONFIG_KEY_SAVE 35 | fpioa_set_function(CONFIG_KEY_BTN_NUM, FUNC_GPIOHS0 + CONFIG_KEY_BTN_NUM_GPIOHS); 36 | #endif 37 | #else 38 | 39 | #endif 40 | } 41 | 42 | static void io_set_power(void) 43 | { 44 | 45 | 46 | #if CONFIG_MAIX_DOCK 47 | /* Set dvp and spi pin to 1.8V */ 48 | sysctl_set_power_mode(SYSCTL_POWER_BANK6, SYSCTL_POWER_V18); 49 | sysctl_set_power_mode(SYSCTL_POWER_BANK7, SYSCTL_POWER_V18); 50 | 51 | #else 52 | /* Set dvp and spi pin to 1.8V */ 53 | sysctl_set_power_mode(SYSCTL_POWER_BANK1, SYSCTL_POWER_V18); 54 | sysctl_set_power_mode(SYSCTL_POWER_BANK2, SYSCTL_POWER_V18); 55 | #endif 56 | } 57 | 58 | 59 | 60 | void camera_init() 61 | { 62 | io_mux_init(); 63 | io_set_power(); 64 | 65 | #if CONFIG_CAMERA_OV5640 66 | dvp_init(16); 67 | dvp_set_xclk_rate(24000000); 68 | dvp_enable_burst(); 69 | dvp_set_output_enable(0, 1); 70 | dvp_set_output_enable(1, 1); 71 | dvp_set_image_format(DVP_CFG_RGB_FORMAT); 72 | dvp_set_image_size(CONFIG_CAMERA_RESOLUTION_WIDTH, CONFIG_CAMERA_RESOLUTION_HEIGHT); 73 | 74 | ov5640_init(); 75 | 76 | #if 0 77 | // OV5640_Focus_Init(); 78 | OV5640_Light_Mode(2); //set auto 79 | OV5640_Color_Saturation(6); //default 80 | OV5640_Brightness(8); //default 81 | OV5640_Contrast(3); //default 82 | // OV5640_Sharpness(33); //set auto 83 | // OV5640_Auto_Focus(); 84 | #endif 85 | 86 | #elif CONFIG_CAMERA_OV2640 87 | dvp_init(8); 88 | dvp_set_xclk_rate(24000000); 89 | dvp_enable_burst(); 90 | dvp_set_output_enable(0, 1); 91 | dvp_set_output_enable(1, 1); 92 | dvp_set_image_format(DVP_CFG_RGB_FORMAT); 93 | 94 | dvp_set_image_size(CONFIG_CAMERA_RESOLUTION_WIDTH, CONFIG_CAMERA_RESOLUTION_HEIGHT); 95 | ov2640_init(); 96 | #elif CONFIG_CAMERA_GC0328 97 | dvp_init(8); 98 | dvp_set_xclk_rate(24000000); 99 | dvp_enable_burst(); 100 | dvp_set_output_enable(0, 1); 101 | dvp_set_output_enable(1, 1); 102 | dvp_set_image_format(DVP_CFG_YUV_FORMAT); 103 | dvp_set_image_size(320, 240); 104 | cambus_init(8, 2, 41, 40, 0, 0); //DVP SCL(41) SDA(40) pin ->software i2c 105 | 106 | gc0328_reset(); 107 | gc0328_init(); 108 | #else 109 | LOGE(TAG,"not support camera type"); 110 | #endif 111 | } -------------------------------------------------------------------------------- /components/drivers/lcd/Kconfig: -------------------------------------------------------------------------------- 1 | 2 | menu "LCD configuration" 3 | 4 | config ENABLE_LCD 5 | bool "enable lcd" 6 | default y 7 | 8 | menu "Lcd ( Display ) configuration" 9 | depends on ENABLE_LCD 10 | 11 | config LCD_WIDTH 12 | depends on ENABLE_LCD 13 | int "Lcd display size width" 14 | default 320 15 | config LCD_HEIGHT 16 | depends on ENABLE_LCD 17 | int "Lcd display size height" 18 | default 240 19 | 20 | config LCD_CLK_FREQ_MHZ 21 | depends on ENABLE_LCD 22 | int "lcd clk frequency MHZ" 23 | default 20 24 | endmenu 25 | 26 | menu "LCD Pin configuration" 27 | depends on ENABLE_LCD 28 | 29 | config PIN_NUM_LCD_RST 30 | int "LCD Pin RST" 31 | default 37 32 | config PIN_NUM_LCD_DCX 33 | int "LCD Pin DCX" 34 | default 38 35 | config PIN_NUM_LCD_WRX 36 | int "LCD Pin WRX" 37 | default 36 38 | config PIN_NUM_LCD_SCK 39 | int "LCD Pin SCK" 40 | default 39 41 | config SPI_CHANNEL 42 | int "spi channel" 43 | default 0 44 | config SPI_SLAVE_SELECT 45 | int "spi slave select" 46 | default 3 47 | endmenu 48 | 49 | menu "LCD Pin Func configuration" 50 | depends on ENABLE_LCD 51 | 52 | config GPIOHS_NUM_LCD_DCX 53 | int "LCD Pin DCX bind with GPIOHS num" 54 | default 2 55 | config GPIOHS_NUM_LCD_RST 56 | int "LCD Pin RST bind with GPIOHS num" 57 | default 3 58 | endmenu 59 | 60 | endmenu 61 | -------------------------------------------------------------------------------- /components/drivers/lcd/include/lcd.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2018 Canaan Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | #ifndef _LCD_H_ 16 | #define _LCD_H_ 17 | 18 | #include 19 | 20 | /* clang-format off */ 21 | 22 | 23 | #define BLACK 0x0000 24 | #define NAVY 0x000F 25 | #define DARKGREEN 0x03E0 26 | #define DARKCYAN 0x03EF 27 | #define MAROON 0x7800 28 | #define PURPLE 0x780F 29 | #define OLIVE 0x7BE0 30 | #define LIGHTGREY 0xC618 31 | #define DARKGREY 0x7BEF 32 | #define BLUE 0x001F 33 | #define GREEN 0x07E0 34 | #define CYAN 0x07FF 35 | #define RED 0xF800 36 | #define MAGENTA 0xF81F 37 | #define YELLOW 0xFFE0 38 | #define WHITE 0xFFFF 39 | #define ORANGE 0xFD20 40 | #define GREENYELLOW 0xAFE5 41 | #define PINK 0xF81F 42 | #define USER_COLOR 0xAA55 43 | /* clang-format on */ 44 | 45 | typedef enum _lcd_dir 46 | { 47 | DIR_XY_RLUD = 0x00, 48 | DIR_YX_RLUD = 0x20, 49 | DIR_XY_LRUD = 0x40, 50 | DIR_YX_LRUD = 0x60, 51 | DIR_XY_RLDU = 0x80, 52 | DIR_YX_RLDU = 0xA0, 53 | DIR_XY_LRDU = 0xC0, 54 | DIR_YX_LRDU = 0xE0, 55 | DIR_XY_MASK = 0x20, 56 | DIR_MASK = 0xE0, 57 | } lcd_dir_t; 58 | 59 | typedef struct _lcd_ctl 60 | { 61 | uint8_t mode; 62 | uint8_t dir; 63 | uint16_t width; 64 | uint16_t height; 65 | } lcd_ctl_t; 66 | 67 | void lcd_polling_enable(void); 68 | void lcd_interrupt_enable(void); 69 | void lcd_init(void); 70 | void lcd_clear(uint16_t color); 71 | void lcd_set_direction(lcd_dir_t dir); 72 | void lcd_set_area(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2); 73 | void lcd_clear_area(uint16_t color, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2); 74 | void lcd_draw_point(uint16_t x, uint16_t y, uint16_t color); 75 | void lcd_draw_string(uint16_t x, uint16_t y, char *str, uint16_t color); 76 | void lcd_draw_picture(uint16_t x1, uint16_t y1, uint16_t width, uint16_t height, uint32_t *ptr); 77 | void lcd_draw_rectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t width, uint16_t color); 78 | void lcd_ram_draw_string(char *str, uint32_t *ptr, uint16_t font_color, uint16_t bg_color); 79 | 80 | #endif 81 | 82 | -------------------------------------------------------------------------------- /components/drivers/lcd/include/nt35310.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2018 Canaan Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | #ifndef _NT35310_H_ 16 | #define _NT35310_H_ 17 | 18 | #include 19 | 20 | /* clang-format off */ 21 | #define NO_OPERATION 0x00 22 | #define SOFTWARE_RESET 0x01 23 | #define READ_ID 0x04 24 | #define READ_STATUS 0x09 25 | #define READ_POWER_MODE 0x0A 26 | #define READ_MADCTL 0x0B 27 | #define READ_PIXEL_FORMAT 0x0C 28 | #define READ_IMAGE_FORMAT 0x0D 29 | #define READ_SIGNAL_MODE 0x0E 30 | #define READ_SELT_DIAG_RESULT 0x0F 31 | #define SLEEP_ON 0x10 32 | #define SLEEP_OFF 0x11 33 | #define PARTIAL_DISPALY_ON 0x12 34 | #define NORMAL_DISPALY_ON 0x13 35 | #define INVERSION_DISPALY_OFF 0x20 36 | #define INVERSION_DISPALY_ON 0x21 37 | #define GAMMA_SET 0x26 38 | #define DISPALY_OFF 0x28 39 | #define DISPALY_ON 0x29 40 | #define HORIZONTAL_ADDRESS_SET 0x2A 41 | #define VERTICAL_ADDRESS_SET 0x2B 42 | #define MEMORY_WRITE 0x2C 43 | #define COLOR_SET 0x2D 44 | #define MEMORY_READ 0x2E 45 | #define PARTIAL_AREA 0x30 46 | #define VERTICAL_SCROL_DEFINE 0x33 47 | #define TEAR_EFFECT_LINE_OFF 0x34 48 | #define TEAR_EFFECT_LINE_ON 0x35 49 | #define MEMORY_ACCESS_CTL 0x36 50 | #define VERTICAL_SCROL_S_ADD 0x37 51 | #define IDLE_MODE_OFF 0x38 52 | #define IDLE_MODE_ON 0x39 53 | #define PIXEL_FORMAT_SET 0x3A 54 | #define WRITE_MEMORY_CONTINUE 0x3C 55 | #define READ_MEMORY_CONTINUE 0x3E 56 | #define SET_TEAR_SCANLINE 0x44 57 | #define GET_SCANLINE 0x45 58 | #define WRITE_BRIGHTNESS 0x51 59 | #define READ_BRIGHTNESS 0x52 60 | #define WRITE_CTRL_DISPALY 0x53 61 | #define READ_CTRL_DISPALY 0x54 62 | #define WRITE_BRIGHTNESS_CTL 0x55 63 | #define READ_BRIGHTNESS_CTL 0x56 64 | #define WRITE_MIN_BRIGHTNESS 0x5E 65 | #define READ_MIN_BRIGHTNESS 0x5F 66 | #define READ_ID1 0xDA 67 | #define READ_ID2 0xDB 68 | #define READ_ID3 0xDC 69 | #define RGB_IF_SIGNAL_CTL 0xB0 70 | #define NORMAL_FRAME_CTL 0xB1 71 | #define IDLE_FRAME_CTL 0xB2 72 | #define PARTIAL_FRAME_CTL 0xB3 73 | #define INVERSION_CTL 0xB4 74 | #define BLANK_PORCH_CTL 0xB5 75 | #define DISPALY_FUNCTION_CTL 0xB6 76 | #define ENTRY_MODE_SET 0xB7 77 | #define BACKLIGHT_CTL1 0xB8 78 | #define BACKLIGHT_CTL2 0xB9 79 | #define BACKLIGHT_CTL3 0xBA 80 | #define BACKLIGHT_CTL4 0xBB 81 | #define BACKLIGHT_CTL5 0xBC 82 | #define BACKLIGHT_CTL7 0xBE 83 | #define BACKLIGHT_CTL8 0xBF 84 | #define POWER_CTL1 0xC0 85 | #define POWER_CTL2 0xC1 86 | #define VCOM_CTL1 0xC5 87 | #define VCOM_CTL2 0xC7 88 | #define NV_MEMORY_WRITE 0xD0 89 | #define NV_MEMORY_PROTECT_KEY 0xD1 90 | #define NV_MEMORY_STATUS_READ 0xD2 91 | #define READ_ID4 0xD3 92 | #define POSITIVE_GAMMA_CORRECT 0xE0 93 | #define NEGATIVE_GAMMA_CORRECT 0xE1 94 | #define DIGITAL_GAMMA_CTL1 0xE2 95 | #define DIGITAL_GAMMA_CTL2 0xE3 96 | #define INTERFACE_CTL 0xF6 97 | 98 | // #define DCX_GPIONUM (2) 99 | // #define RST_GPIONUM (3) 100 | 101 | // #define SPI_CHANNEL 0 102 | // #define SPI_SLAVE_SELECT 3 103 | /* clang-format on */ 104 | 105 | void tft_hard_init(void); 106 | void tft_write_command(uint8_t cmd); 107 | void tft_write_byte(uint8_t *data_buf, uint32_t length); 108 | void tft_write_half(uint16_t *data_buf, uint32_t length); 109 | void tft_write_word(uint32_t *data_buf, uint32_t length, uint32_t flag); 110 | void tft_fill_data(uint32_t *data_buf, uint32_t length); 111 | 112 | #endif 113 | 114 | -------------------------------------------------------------------------------- /components/drivers/lcd/src/lcd.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2018 Canaan Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | #include 16 | #include 17 | #include "lcd.h" 18 | #include "nt35310.h" 19 | #include "font.h" 20 | #include "global_config.h" 21 | 22 | static lcd_ctl_t lcd_ctl; 23 | 24 | void lcd_polling_enable(void) 25 | { 26 | lcd_ctl.mode = 0; 27 | } 28 | 29 | void lcd_interrupt_enable(void) 30 | { 31 | lcd_ctl.mode = 1; 32 | } 33 | 34 | void lcd_init(void) 35 | { 36 | uint8_t data = 0; 37 | 38 | tft_hard_init(); 39 | /*soft reset*/ 40 | tft_write_command(SOFTWARE_RESET); 41 | usleep(100000); 42 | /*exit sleep*/ 43 | tft_write_command(SLEEP_OFF); 44 | usleep(100000); 45 | /*pixel format*/ 46 | tft_write_command(PIXEL_FORMAT_SET); 47 | data = 0x55; 48 | tft_write_byte(&data, 1); 49 | lcd_set_direction(DIR_XY_LRUD); 50 | 51 | /*display on*/ 52 | tft_write_command(DISPALY_ON); 53 | lcd_polling_enable(); 54 | } 55 | 56 | void lcd_set_direction(lcd_dir_t dir) 57 | { 58 | #if CONFIG_MAIX_DOCK 59 | #else 60 | dir |= 0x08; 61 | #endif 62 | lcd_ctl.dir = dir; 63 | if (dir & DIR_XY_MASK) 64 | { 65 | lcd_ctl.width = CONFIG_LCD_WIDTH - 1; 66 | lcd_ctl.height = CONFIG_LCD_HEIGHT - 1; 67 | } 68 | else 69 | { 70 | lcd_ctl.width = CONFIG_LCD_HEIGHT - 1; 71 | lcd_ctl.height = CONFIG_LCD_WIDTH - 1; 72 | } 73 | 74 | tft_write_command(MEMORY_ACCESS_CTL); 75 | tft_write_byte((uint8_t *)&dir, 1); 76 | } 77 | 78 | void lcd_set_area(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) 79 | { 80 | uint8_t data[4] = {0}; 81 | 82 | data[0] = (uint8_t)(x1 >> 8); 83 | data[1] = (uint8_t)(x1); 84 | data[2] = (uint8_t)(x2 >> 8); 85 | data[3] = (uint8_t)(x2); 86 | tft_write_command(HORIZONTAL_ADDRESS_SET); 87 | tft_write_byte(data, 4); 88 | 89 | data[0] = (uint8_t)(y1 >> 8); 90 | data[1] = (uint8_t)(y1); 91 | data[2] = (uint8_t)(y2 >> 8); 92 | data[3] = (uint8_t)(y2); 93 | tft_write_command(VERTICAL_ADDRESS_SET); 94 | tft_write_byte(data, 4); 95 | 96 | tft_write_command(MEMORY_WRITE); 97 | } 98 | 99 | void lcd_draw_point(uint16_t x, uint16_t y, uint16_t color) 100 | { 101 | lcd_set_area(x, y, x, y); 102 | tft_write_half(&color, 1); 103 | } 104 | 105 | void lcd_draw_char(uint16_t x, uint16_t y, char c, uint16_t color) 106 | { 107 | uint8_t i = 0; 108 | uint8_t j = 0; 109 | uint8_t data = 0; 110 | 111 | for (i = 0; i < 16; i++) 112 | { 113 | data = ascii0816[c * 16 + i]; 114 | for (j = 0; j < 8; j++) 115 | { 116 | if (data & 0x80) 117 | lcd_draw_point(x + j, y, color); 118 | data <<= 1; 119 | } 120 | y++; 121 | } 122 | } 123 | 124 | void lcd_draw_string(uint16_t x, uint16_t y, char *str, uint16_t color) 125 | { 126 | while (*str) 127 | { 128 | lcd_draw_char(x, y, *str, color); 129 | str++; 130 | x += 8; 131 | } 132 | } 133 | 134 | void lcd_ram_draw_string(char *str, uint32_t *ptr, uint16_t font_color, uint16_t bg_color) 135 | { 136 | uint8_t i = 0; 137 | uint8_t j = 0; 138 | uint8_t data = 0; 139 | uint8_t *pdata = NULL; 140 | uint16_t width = 0; 141 | uint32_t *pixel = NULL; 142 | 143 | width = 4 * strlen(str); 144 | while (*str) 145 | { 146 | pdata = (uint8_t *)&ascii0816[(*str) * 16]; 147 | for (i = 0; i < 16; i++) 148 | { 149 | data = *pdata++; 150 | pixel = ptr + i * width; 151 | for (j = 0; j < 4; j++) 152 | { 153 | switch (data >> 6) 154 | { 155 | case 0: 156 | *pixel = ((uint32_t)bg_color << 16) | bg_color; 157 | break; 158 | case 1: 159 | *pixel = ((uint32_t)bg_color << 16) | font_color; 160 | break; 161 | case 2: 162 | *pixel = ((uint32_t)font_color << 16) | bg_color; 163 | break; 164 | case 3: 165 | *pixel = ((uint32_t)font_color << 16) | font_color; 166 | break; 167 | default: 168 | *pixel = 0; 169 | break; 170 | } 171 | data <<= 2; 172 | pixel++; 173 | } 174 | } 175 | str++; 176 | ptr += 4; 177 | } 178 | } 179 | 180 | void lcd_clear(uint16_t color) 181 | { 182 | uint32_t data = ((uint32_t)color << 16) | (uint32_t)color; 183 | 184 | lcd_set_area(0, 0, lcd_ctl.width, lcd_ctl.height); 185 | tft_fill_data(&data, CONFIG_LCD_HEIGHT * CONFIG_LCD_WIDTH / 2); 186 | } 187 | 188 | void lcd_clear_area(uint16_t color, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) 189 | { 190 | uint32_t data = ((uint32_t)color << 16) | (uint32_t)color; 191 | 192 | lcd_set_area(x1, y1, x2, y2); 193 | tft_fill_data(&data, (x2-x1)*(y2-y1)); 194 | } 195 | 196 | void lcd_draw_rectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t width, uint16_t color) 197 | { 198 | uint32_t data_buf[640] = {0}; 199 | uint32_t *p = data_buf; 200 | uint32_t data = color; 201 | uint32_t index = 0; 202 | 203 | data = (data << 16) | data; 204 | for (index = 0; index < 160 * width; index++) 205 | *p++ = data; 206 | 207 | lcd_set_area(x1, y1, x2, y1 + width - 1); 208 | tft_write_word(data_buf, ((x2 - x1 + 1) * width + 1) / 2, 0); 209 | lcd_set_area(x1, y2 - width + 1, x2, y2); 210 | tft_write_word(data_buf, ((x2 - x1 + 1) * width + 1) / 2, 0); 211 | lcd_set_area(x1, y1, x1 + width - 1, y2); 212 | tft_write_word(data_buf, ((y2 - y1 + 1) * width + 1) / 2, 0); 213 | lcd_set_area(x2 - width + 1, y1, x2, y2); 214 | tft_write_word(data_buf, ((y2 - y1 + 1) * width + 1) / 2, 0); 215 | } 216 | 217 | void lcd_draw_picture(uint16_t x1, uint16_t y1, uint16_t width, uint16_t height, uint32_t *ptr) 218 | { 219 | lcd_set_area(x1, y1, x1 + width - 1, y1 + height - 1); 220 | tft_write_word(ptr, width * height / 2, lcd_ctl.mode ? 2 : 0); 221 | } 222 | 223 | -------------------------------------------------------------------------------- /components/drivers/lcd/src/nt35310.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2018 Canaan Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | #include "nt35310.h" 16 | #include "gpiohs.h" 17 | #include "spi.h" 18 | #include "unistd.h" 19 | #include "global_config.h" 20 | 21 | static void init_dcx(void) 22 | { 23 | gpiohs_set_drive_mode(CONFIG_GPIOHS_NUM_LCD_DCX, GPIO_DM_OUTPUT); 24 | gpiohs_set_pin(CONFIG_GPIOHS_NUM_LCD_DCX, GPIO_PV_HIGH); 25 | } 26 | 27 | static void set_dcx_control(void) 28 | { 29 | gpiohs_set_pin(CONFIG_GPIOHS_NUM_LCD_DCX, GPIO_PV_LOW); 30 | } 31 | 32 | static void set_dcx_data(void) 33 | { 34 | gpiohs_set_pin(CONFIG_GPIOHS_NUM_LCD_DCX, GPIO_PV_HIGH); 35 | } 36 | 37 | #if CONFIG_MAIX_DOCK 38 | static void init_rst(void) 39 | { 40 | gpiohs_set_drive_mode(CONFIG_GPIOHS_NUM_LCD_RST, GPIO_DM_OUTPUT); 41 | gpiohs_set_pin(CONFIG_GPIOHS_NUM_LCD_RST, GPIO_PV_LOW); 42 | usleep(100000); 43 | gpiohs_set_pin(CONFIG_GPIOHS_NUM_LCD_RST, GPIO_PV_HIGH); 44 | usleep(100000); 45 | } 46 | #endif 47 | 48 | void tft_hard_init(void) 49 | { 50 | init_dcx(); 51 | spi_init(CONFIG_SPI_CHANNEL, SPI_WORK_MODE_0, SPI_FF_OCTAL, 8, 0); 52 | #if CONFIG_MAIX_DOCK 53 | init_rst(); 54 | spi_set_clk_rate(CONFIG_SPI_CHANNEL, 20000000); 55 | #else 56 | spi_set_clk_rate(CONFIG_SPI_CHANNEL, 25000000); 57 | #endif 58 | } 59 | 60 | void tft_write_command(uint8_t cmd) 61 | { 62 | set_dcx_control(); 63 | spi_init(CONFIG_SPI_CHANNEL, SPI_WORK_MODE_0, SPI_FF_OCTAL, 8, 0); 64 | spi_init_non_standard(CONFIG_SPI_CHANNEL, 8/*instrction length*/, 0/*address length*/, 0/*wait cycles*/, 65 | SPI_AITM_AS_FRAME_FORMAT/*spi address trans mode*/); 66 | spi_send_data_normal_dma(DMAC_CHANNEL0, CONFIG_SPI_CHANNEL, CONFIG_SPI_SLAVE_SELECT, (uint8_t *)(&cmd), 1,SPI_TRANS_CHAR); 67 | } 68 | 69 | void tft_write_byte(uint8_t *data_buf, uint32_t length) 70 | { 71 | set_dcx_data(); 72 | spi_init(CONFIG_SPI_CHANNEL, SPI_WORK_MODE_0, SPI_FF_OCTAL, 8, 0); 73 | spi_init_non_standard(CONFIG_SPI_CHANNEL, 8/*instrction length*/, 0/*address length*/, 0/*wait cycles*/, 74 | SPI_AITM_AS_FRAME_FORMAT/*spi address trans mode*/); 75 | spi_send_data_normal_dma(DMAC_CHANNEL0, CONFIG_SPI_CHANNEL, CONFIG_SPI_SLAVE_SELECT, data_buf, length, SPI_TRANS_CHAR); 76 | } 77 | 78 | void tft_write_half(uint16_t *data_buf, uint32_t length) 79 | { 80 | set_dcx_data(); 81 | spi_init(CONFIG_SPI_CHANNEL, SPI_WORK_MODE_0, SPI_FF_OCTAL, 16, 0); 82 | spi_init_non_standard(CONFIG_SPI_CHANNEL, 16/*instrction length*/, 0/*address length*/, 0/*wait cycles*/, 83 | SPI_AITM_AS_FRAME_FORMAT/*spi address trans mode*/); 84 | spi_send_data_normal_dma(DMAC_CHANNEL0, CONFIG_SPI_CHANNEL, CONFIG_SPI_SLAVE_SELECT,data_buf, length, SPI_TRANS_SHORT); 85 | } 86 | 87 | void tft_write_word(uint32_t *data_buf, uint32_t length, uint32_t flag) 88 | { 89 | set_dcx_data(); 90 | spi_init(CONFIG_SPI_CHANNEL, SPI_WORK_MODE_0, SPI_FF_OCTAL, 32, 0); 91 | 92 | spi_init_non_standard(CONFIG_SPI_CHANNEL, 0/*instrction length*/, 32/*address length*/, 0/*wait cycles*/, 93 | SPI_AITM_AS_FRAME_FORMAT/*spi address trans mode*/); 94 | spi_send_data_normal_dma(DMAC_CHANNEL0, CONFIG_SPI_CHANNEL, CONFIG_SPI_SLAVE_SELECT,data_buf, length, SPI_TRANS_INT); 95 | } 96 | 97 | void tft_fill_data(uint32_t *data_buf, uint32_t length) 98 | { 99 | set_dcx_data(); 100 | spi_init(CONFIG_SPI_CHANNEL, SPI_WORK_MODE_0, SPI_FF_OCTAL, 32, 0); 101 | spi_init_non_standard(CONFIG_SPI_CHANNEL, 0/*instrction length*/, 32/*address length*/, 0/*wait cycles*/, 102 | SPI_AITM_AS_FRAME_FORMAT/*spi address trans mode*/); 103 | spi_fill_data_dma(DMAC_CHANNEL0, CONFIG_SPI_CHANNEL, CONFIG_SPI_SLAVE_SELECT,data_buf, length); 104 | } 105 | 106 | -------------------------------------------------------------------------------- /components/drivers/sd_card/Kconfig: -------------------------------------------------------------------------------- 1 | 2 | menu "SPI TF card configuration" 3 | 4 | config ENABLE_SD_CARD 5 | bool "Enable SPI TF card" 6 | default n 7 | 8 | menu "SPI TF card configuration" 9 | depends on ENABLE_SD_CARD 10 | 11 | config PIN_NUM_SD_CARD_SCLK 12 | int "SPI TF card SCLK pin number" 13 | default 27 14 | config PIN_NUM_SD_CARD_MOSI 15 | int "SPI TF card MOSI pin number" 16 | default 28 17 | config PIN_NUM_SD_CARD_MISO 18 | int "SPI TF card MISO pin number" 19 | default 26 20 | config PIN_NUM_SD_CARD_CS 21 | int "SPI TF card CS pin number" 22 | default 29 23 | endmenu 24 | 25 | endmenu 26 | -------------------------------------------------------------------------------- /components/drivers/sd_card/include/diskio.h: -------------------------------------------------------------------------------- 1 | /*-----------------------------------------------------------------------/ 2 | / Low level disk interface modlue include file (C)ChaN, 2014 / 3 | /-----------------------------------------------------------------------*/ 4 | 5 | #ifndef _DISKIO_DEFINED 6 | #define _DISKIO_DEFINED 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | #include "integer.h" 13 | 14 | 15 | /* Status of Disk Functions */ 16 | typedef BYTE DSTATUS; 17 | 18 | /* Results of Disk Functions */ 19 | typedef enum { 20 | RES_OK = 0, /* 0: Successful */ 21 | RES_ERROR, /* 1: R/W Error */ 22 | RES_WRPRT, /* 2: Write Protected */ 23 | RES_NOTRDY, /* 3: Not Ready */ 24 | RES_PARERR /* 4: Invalid Parameter */ 25 | } DRESULT; 26 | 27 | 28 | /*---------------------------------------*/ 29 | /* Prototypes for disk control functions */ 30 | 31 | 32 | DSTATUS disk_initialize (BYTE pdrv); 33 | DSTATUS disk_status (BYTE pdrv); 34 | DRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count); 35 | DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count); 36 | DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff); 37 | 38 | 39 | /* Disk Status Bits (DSTATUS) */ 40 | 41 | #define STA_NOINIT 0x01 /* Drive not initialized */ 42 | #define STA_NODISK 0x02 /* No medium in the drive */ 43 | #define STA_PROTECT 0x04 /* Write protected */ 44 | 45 | 46 | /* Command code for disk_ioctrl fucntion */ 47 | 48 | /* Generic command (Used by FatFs) */ 49 | #define CTRL_SYNC 0 /* Complete pending write process (needed at _FS_READONLY == 0) */ 50 | #define GET_SECTOR_COUNT 1 /* Get media size (needed at _USE_MKFS == 1) */ 51 | #define GET_SECTOR_SIZE 2 /* Get sector size (needed at _MAX_SS != _MIN_SS) */ 52 | #define GET_BLOCK_SIZE 3 /* Get erase block size (needed at _USE_MKFS == 1) */ 53 | #define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at _USE_TRIM == 1) */ 54 | 55 | /* Generic command (Not used by FatFs) */ 56 | #define CTRL_POWER 5 /* Get/Set power status */ 57 | #define CTRL_LOCK 6 /* Lock/Unlock media removal */ 58 | #define CTRL_EJECT 7 /* Eject media */ 59 | #define CTRL_FORMAT 8 /* Create physical format on the media */ 60 | 61 | /* MMC/SDC specific ioctl command */ 62 | #define MMC_GET_TYPE 10 /* Get card type */ 63 | #define MMC_GET_CSD 11 /* Get CSD */ 64 | #define MMC_GET_CID 12 /* Get CID */ 65 | #define MMC_GET_OCR 13 /* Get OCR */ 66 | #define MMC_GET_SDSTAT 14 /* Get SD status */ 67 | #define ISDIO_READ 55 /* Read data form SD iSDIO register */ 68 | #define ISDIO_WRITE 56 /* Write data to SD iSDIO register */ 69 | #define ISDIO_MRITE 57 /* Masked write data to SD iSDIO register */ 70 | 71 | /* ATA/CF specific ioctl command */ 72 | #define ATA_GET_REV 20 /* Get F/W revision */ 73 | #define ATA_GET_MODEL 21 /* Get model name */ 74 | #define ATA_GET_SN 22 /* Get serial number */ 75 | 76 | #ifdef __cplusplus 77 | } 78 | #endif 79 | 80 | #endif 81 | -------------------------------------------------------------------------------- /components/drivers/sd_card/include/integer.h: -------------------------------------------------------------------------------- 1 | /*-------------------------------------------*/ 2 | /* Integer type definitions for FatFs module */ 3 | /*-------------------------------------------*/ 4 | 5 | #ifndef _FF_INTEGER 6 | #define _FF_INTEGER 7 | 8 | #ifdef _WIN32 /* FatFs development platform */ 9 | 10 | #include 11 | #include 12 | typedef unsigned __int64 QWORD; 13 | 14 | 15 | #else /* Embedded platform */ 16 | 17 | /* These types MUST be 16-bit or 32-bit */ 18 | typedef int INT; 19 | typedef unsigned int UINT; 20 | 21 | /* This type MUST be 8-bit */ 22 | typedef unsigned char BYTE; 23 | 24 | /* These types MUST be 16-bit */ 25 | typedef short SHORT; 26 | typedef unsigned short WORD; 27 | typedef unsigned short WCHAR; 28 | 29 | /* These types MUST be 32-bit */ 30 | typedef long LONG; 31 | typedef unsigned long DWORD; 32 | 33 | /* This type MUST be 64-bit (Remove this for C89 compatibility) */ 34 | typedef unsigned long long QWORD; 35 | 36 | #endif 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /components/drivers/sd_card/include/sdcard.h: -------------------------------------------------------------------------------- 1 | #ifndef _SDCARD_H 2 | #define _SDCARD_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include "stdint.h" 9 | 10 | /** 11 | * @brief Card Specific Data: CSD Register 12 | */ 13 | typedef struct { 14 | uint8_t CSDStruct; /*!< CSD structure */ 15 | uint8_t SysSpecVersion; /*!< System specification version */ 16 | uint8_t Reserved1; /*!< Reserved */ 17 | uint8_t TAAC; /*!< Data read access-time 1 */ 18 | uint8_t NSAC; /*!< Data read access-time 2 in CLK cycles */ 19 | uint8_t MaxBusClkFrec; /*!< Max. bus clock frequency */ 20 | uint16_t CardComdClasses; /*!< Card command classes */ 21 | uint8_t RdBlockLen; /*!< Max. read data block length */ 22 | uint8_t PartBlockRead; /*!< Partial blocks for read allowed */ 23 | uint8_t WrBlockMisalign; /*!< Write block misalignment */ 24 | uint8_t RdBlockMisalign; /*!< Read block misalignment */ 25 | uint8_t DSRImpl; /*!< DSR implemented */ 26 | uint8_t Reserved2; /*!< Reserved */ 27 | uint32_t DeviceSize; /*!< Device Size */ 28 | uint8_t MaxRdCurrentVDDMin; /*!< Max. read current @ VDD min */ 29 | uint8_t MaxRdCurrentVDDMax; /*!< Max. read current @ VDD max */ 30 | uint8_t MaxWrCurrentVDDMin; /*!< Max. write current @ VDD min */ 31 | uint8_t MaxWrCurrentVDDMax; /*!< Max. write current @ VDD max */ 32 | uint8_t DeviceSizeMul; /*!< Device size multiplier */ 33 | uint8_t EraseGrSize; /*!< Erase group size */ 34 | uint8_t EraseGrMul; /*!< Erase group size multiplier */ 35 | uint8_t WrProtectGrSize; /*!< Write protect group size */ 36 | uint8_t WrProtectGrEnable; /*!< Write protect group enable */ 37 | uint8_t ManDeflECC; /*!< Manufacturer default ECC */ 38 | uint8_t WrSpeedFact; /*!< Write speed factor */ 39 | uint8_t MaxWrBlockLen; /*!< Max. write data block length */ 40 | uint8_t WriteBlockPaPartial; /*!< Partial blocks for write allowed */ 41 | uint8_t Reserved3; /*!< Reserded */ 42 | uint8_t ContentProtectAppli; /*!< Content protection application */ 43 | uint8_t FileFormatGrouop; /*!< File format group */ 44 | uint8_t CopyFlag; /*!< Copy flag (OTP) */ 45 | uint8_t PermWrProtect; /*!< Permanent write protection */ 46 | uint8_t TempWrProtect; /*!< Temporary write protection */ 47 | uint8_t FileFormat; /*!< File Format */ 48 | uint8_t ECC; /*!< ECC code */ 49 | uint8_t CSD_CRC; /*!< CSD CRC */ 50 | uint8_t Reserved4; /*!< always 1*/ 51 | } SD_CSD; 52 | 53 | /** 54 | * @brief Card Identification Data: CID Register 55 | */ 56 | typedef struct { 57 | uint8_t ManufacturerID; /*!< ManufacturerID */ 58 | uint16_t OEM_AppliID; /*!< OEM/Application ID */ 59 | uint32_t ProdName1; /*!< Product Name part1 */ 60 | uint8_t ProdName2; /*!< Product Name part2*/ 61 | uint8_t ProdRev; /*!< Product Revision */ 62 | uint32_t ProdSN; /*!< Product Serial Number */ 63 | uint8_t Reserved1; /*!< Reserved1 */ 64 | uint16_t ManufactDate; /*!< Manufacturing Date */ 65 | uint8_t CID_CRC; /*!< CID CRC */ 66 | uint8_t Reserved2; /*!< always 1 */ 67 | } SD_CID; 68 | 69 | /** 70 | * @brief SD Card information 71 | */ 72 | typedef struct { 73 | SD_CSD SD_csd; 74 | SD_CID SD_cid; 75 | uint64_t CardCapacity; /*!< Card Capacity */ 76 | uint32_t CardBlockSize; /*!< Card Block Size */ 77 | } SD_CardInfo; 78 | 79 | extern SD_CardInfo cardinfo; 80 | 81 | uint8_t sd_init(void); 82 | uint8_t sd_read_sector(uint8_t *data_buff, uint32_t sector, uint32_t count); 83 | uint8_t sd_write_sector(uint8_t *data_buff, uint32_t sector, uint32_t count); 84 | uint8_t sd_read_sector_dma(uint8_t *data_buff, uint32_t sector, uint32_t count); 85 | uint8_t sd_write_sector_dma(uint8_t *data_buff, uint32_t sector, uint32_t count); 86 | 87 | #ifdef __cplusplus 88 | } 89 | #endif 90 | 91 | #endif 92 | -------------------------------------------------------------------------------- /components/drivers/sd_card/src/diskio.c: -------------------------------------------------------------------------------- 1 | /*-----------------------------------------------------------------------*/ 2 | /* Low level disk I/O module skeleton for FatFs (C)ChaN, 2016 */ 3 | /*-----------------------------------------------------------------------*/ 4 | /* If a working storage control module is available, it should be */ 5 | /* attached to the FatFs via a glue function rather than modifying it. */ 6 | /* This is an example of glue functions to attach various exsisting */ 7 | /* storage control modules to the FatFs module with a defined API. */ 8 | /*-----------------------------------------------------------------------*/ 9 | 10 | #include "diskio.h" /* FatFs lower layer API */ 11 | #include "sdcard.h" 12 | 13 | /* Definitions of physical drive number for each drive */ 14 | #define M0 0 /* Example: Map MMC/SD card to physical drive 0 */ 15 | 16 | 17 | /*-----------------------------------------------------------------------*/ 18 | /* Get Drive Status */ 19 | /*-----------------------------------------------------------------------*/ 20 | 21 | DSTATUS disk_status(BYTE pdrv) 22 | { 23 | return 0; 24 | } 25 | 26 | 27 | 28 | /*-----------------------------------------------------------------------*/ 29 | /* Inidialize a Drive */ 30 | /*-----------------------------------------------------------------------*/ 31 | 32 | DSTATUS disk_initialize(BYTE pdrv) 33 | { 34 | if (sd_init() == 0) 35 | return 0; 36 | return STA_NOINIT; 37 | } 38 | 39 | 40 | 41 | /*-----------------------------------------------------------------------*/ 42 | /* Read Sector(s) */ 43 | /*-----------------------------------------------------------------------*/ 44 | 45 | DRESULT disk_read(BYTE pdrv, BYTE *buff, DWORD sector, UINT count) 46 | { 47 | if (sd_read_sector_dma(buff, sector, count) == 0) 48 | return RES_OK; 49 | return RES_ERROR; 50 | } 51 | 52 | 53 | 54 | /*-----------------------------------------------------------------------*/ 55 | /* Write Sector(s) */ 56 | /*-----------------------------------------------------------------------*/ 57 | 58 | DRESULT disk_write(BYTE pdrv, const BYTE *buff, DWORD sector, UINT count) 59 | { 60 | if (sd_write_sector_dma((BYTE *)buff, sector, count) == 0) 61 | return RES_OK; 62 | return RES_ERROR; 63 | } 64 | 65 | 66 | 67 | /*-----------------------------------------------------------------------*/ 68 | /* Miscellaneous Functions */ 69 | /*-----------------------------------------------------------------------*/ 70 | 71 | DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void *buff) 72 | { 73 | DRESULT res = RES_ERROR; 74 | 75 | switch (cmd) { 76 | /* Make sure that no pending write process */ 77 | case CTRL_SYNC: 78 | res = RES_OK; 79 | break; 80 | /* Get number of sectors on the disk (DWORD) */ 81 | case GET_SECTOR_COUNT: 82 | *(DWORD *)buff = (cardinfo.SD_csd.DeviceSize + 1) << 10; 83 | res = RES_OK; 84 | break; 85 | /* Get R/W sector size (WORD) */ 86 | case GET_SECTOR_SIZE: 87 | *(WORD *)buff = cardinfo.CardBlockSize; 88 | res = RES_OK; 89 | break; 90 | /* Get erase block size in unit of sector (DWORD) */ 91 | case GET_BLOCK_SIZE: 92 | *(DWORD *)buff = cardinfo.CardBlockSize; 93 | res = RES_OK; 94 | break; 95 | default: 96 | res = RES_PARERR; 97 | } 98 | return res; 99 | } 100 | -------------------------------------------------------------------------------- /components/drivers/w25q_flash/Kconfig: -------------------------------------------------------------------------------- 1 | 2 | menu "FLASH configuration" 3 | 4 | config ENABLE_FLASH 5 | bool "enable flash" 6 | default y 7 | endmenu 8 | -------------------------------------------------------------------------------- /components/drivers/w25q_flash/include/w25qxx.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2018 Canaan Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | #ifndef _W25QXX_H 16 | #define _W25QXX_H 17 | 18 | #include 19 | 20 | /* clang-format off */ 21 | #define DATALENGTH 8 22 | 23 | #define w25qxx_FLASH_PAGE_SIZE 256 24 | #define w25qxx_FLASH_SECTOR_SIZE 4096 25 | #define w25qxx_FLASH_PAGE_NUM_PER_SECTOR 16 26 | #define w25qxx_FLASH_CHIP_SIZE (16777216 UL) 27 | 28 | #define WRITE_ENABLE 0x06 29 | #define WRITE_DISABLE 0x04 30 | #define READ_REG1 0x05 31 | #define READ_REG2 0x35 32 | #define READ_REG3 0x15 33 | #define WRITE_REG1 0x01 34 | #define WRITE_REG2 0x31 35 | #define WRITE_REG3 0x11 36 | #define READ_DATA 0x03 37 | #define FAST_READ 0x0B 38 | #define FAST_READ_DUAL_OUTPUT 0x3B 39 | #define FAST_READ_QUAL_OUTPUT 0x6B 40 | #define FAST_READ_DUAL_IO 0xBB 41 | #define FAST_READ_QUAL_IO 0xEB 42 | #define DUAL_READ_RESET 0xFFFF 43 | #define QUAL_READ_RESET 0xFF 44 | #define PAGE_PROGRAM 0x02 45 | #define QUAD_PAGE_PROGRAM 0x32 46 | #define SECTOR_ERASE 0x20 47 | #define BLOCK_32K_ERASE 0x52 48 | #define BLOCK_64K_ERASE 0xD8 49 | #define CHIP_ERASE 0x60 50 | #define READ_ID 0x90 51 | #define ENABLE_QPI 0x38 52 | #define EXIT_QPI 0xFF 53 | #define ENABLE_RESET 0x66 54 | #define RESET_DEVICE 0x99 55 | 56 | #define REG1_BUSY_MASK 0x01 57 | #define REG2_QUAL_MASK 0x02 58 | 59 | #define LETOBE(x) ((x >> 24) | ((x & 0x00FF0000) >> 8) | ((x & 0x0000FF00) << 8) | (x << 24)) 60 | /* clang-format on */ 61 | 62 | /** 63 | * @brief w25qxx operating status enumerate 64 | */ 65 | typedef enum _w25qxx_status 66 | { 67 | W25QXX_OK = 0, 68 | W25QXX_BUSY, 69 | W25QXX_ERROR, 70 | } w25qxx_status_t; 71 | 72 | /** 73 | * @brief w25qxx read operating enumerate 74 | */ 75 | typedef enum _w25qxx_read 76 | { 77 | W25QXX_STANDARD = 0, 78 | W25QXX_STANDARD_FAST, 79 | W25QXX_DUAL, 80 | W25QXX_DUAL_FAST, 81 | W25QXX_QUAD, 82 | W25QXX_QUAD_FAST, 83 | } w25qxx_read_t; 84 | 85 | w25qxx_status_t w25qxx_init(uint8_t spi_index, uint8_t spi_ss); 86 | w25qxx_status_t w25qxx_is_busy(void); 87 | w25qxx_status_t w25qxx_chip_erase(void); 88 | w25qxx_status_t w25qxx_enable_quad_mode(void); 89 | w25qxx_status_t w25qxx_disable_quad_mode(void); 90 | w25qxx_status_t w25qxx_sector_erase(uint32_t addr); 91 | w25qxx_status_t w25qxx_32k_block_erase(uint32_t addr); 92 | w25qxx_status_t w25qxx_64k_block_erase(uint32_t addr); 93 | w25qxx_status_t w25qxx_read_status_reg1(uint8_t *reg_data); 94 | w25qxx_status_t w25qxx_read_status_reg2(uint8_t *reg_data); 95 | w25qxx_status_t w25qxx_write_status_reg(uint8_t reg1_data, uint8_t reg2_data); 96 | w25qxx_status_t w25qxx_read_id(uint8_t *manuf_id, uint8_t *device_id); 97 | w25qxx_status_t w25qxx_write_data(uint32_t addr, uint8_t *data_buf, uint32_t length); 98 | w25qxx_status_t w25qxx_write_data_direct(uint32_t addr, uint8_t *data_buf, uint32_t length); 99 | w25qxx_status_t w25qxx_read_data(uint32_t addr, uint8_t *data_buf, uint32_t length, w25qxx_read_t mode); 100 | w25qxx_status_t w25qxx_enable_xip_mode(void); 101 | w25qxx_status_t w25qxx_disable_xip_mode(void); 102 | w25qxx_status_t w25qxx_read_id_dma(uint8_t *manuf_id, uint8_t *device_id); 103 | w25qxx_status_t w25qxx_sector_erase_dma(uint32_t addr); 104 | w25qxx_status_t w25qxx_init_dma(uint8_t spi_index, uint8_t spi_ss); 105 | w25qxx_status_t w25qxx_write_data_dma(uint32_t addr, uint8_t *data_buf, uint32_t length); 106 | w25qxx_status_t w25qxx_write_data_direct_dma(uint32_t addr, uint8_t *data_buf, uint32_t length); 107 | w25qxx_status_t w25qxx_read_data_dma(uint32_t addr, uint8_t *data_buf, uint32_t length, w25qxx_read_t mode); 108 | w25qxx_status_t w25qxx_is_busy_dma(void); 109 | w25qxx_status_t w25qxx_enable_quad_mode_dma(void); 110 | 111 | #endif 112 | 113 | -------------------------------------------------------------------------------- /components/kendryte_sdk/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | ################# Add include ################# 3 | list(APPEND ADD_INCLUDE 4 | "kendryte-standalone-sdk/lib/bsp/include" 5 | "kendryte-standalone-sdk/lib/drivers/include" 6 | "kendryte-standalone-sdk/lib/nncase/include" 7 | 8 | "kendryte-standalone-sdk/lib/utils/include/" 9 | "kendryte-standalone-sdk/third_party/xtl/include" 10 | ) 11 | # list(APPEND ADD_PRIVATE_INCLUDE "include_private") 12 | ############################################### 13 | 14 | ############## Add source files ############### 15 | append_srcs_dir(ADD_SRCS "kendryte-standalone-sdk/lib/bsp") 16 | append_srcs_dir(ADD_SRCS "kendryte-standalone-sdk/lib/drivers") 17 | append_srcs_dir(ADD_SRCS "kendryte-standalone-sdk/lib/nncase") 18 | append_srcs_dir(ADD_SRCS "kendryte-standalone-sdk/lib/utils/include") 19 | 20 | 21 | FILE(GLOB_RECURSE NNCASE_SRC 22 | "kendryte-standalone-sdk/lib/nncase/*.c" 23 | "kendryte-standalone-sdk/lib/nncase/*.cpp" 24 | ) 25 | 26 | append_srcs_dir(ADD_SRCS "src") 27 | set(ADD_ASM_SRCS "kendryte-standalone-sdk/lib/bsp/crt.S") 28 | 29 | list(APPEND ADD_SRCS ${ADD_ASM_SRCS} ${NNCASE_SRC}) 30 | 31 | # list(REMOVE_ITEM COMPONENT_SRCS "src/test.c") 32 | 33 | SET_PROPERTY(SOURCE ${ADD_ASM_SRCS} PROPERTY LANGUAGE C) 34 | SET_SOURCE_FILES_PROPERTIES(${ADD_ASM_SRCS} PROPERTIES COMPILE_FLAGS "-x assembler-with-cpp -D __riscv64") 35 | ############################################### 36 | 37 | ###### Add required/dependent components ###### 38 | # list(APPEND ADD_REQUIREMENTS stdc++ m) 39 | list(APPEND ADD_REQUIREMENTS m) 40 | ############################################### 41 | 42 | ############ Add static libs ################## 43 | # list(APPEND ADD_STATIC_LIB "libs/lib_mic.a" 44 | # ) 45 | ############################################### 46 | 47 | list(APPEND ADD_DEFINITIONS -DCONFIG_LOG_LEVEL=${CONFIG_SDK_LOG_LEVEL} 48 | -DNNCASE_TARGET=k210 49 | -DTCB_SPAN_NO_EXCEPTIONS 50 | -DTCB_SPAN_NO_CONTRACT_CHECKING 51 | -DCONFIG_LOG_ENABLE=1 52 | -DCONFIG_LOG_COLORS=1 53 | -DLOG_KERNEL=1 54 | -D__riscv64 55 | ) 56 | 57 | register_component() 58 | 59 | -------------------------------------------------------------------------------- /components/kendryte_sdk/Kconfig: -------------------------------------------------------------------------------- 1 | 2 | menu "Kendryte SDK configurations" 3 | config SDK_LOG_LEVEL 4 | int "log level, 5:LOG_VERBOSE, 4:LOG_DEBUG, 3:LOG_INFO, 2:LOG_WARN, 1:LOG_ERROR, 0:LOG_NONE" 5 | range 0 5 6 | default 5 7 | endmenu 8 | -------------------------------------------------------------------------------- /components/utils/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | list(APPEND ADD_INCLUDE #"base64/include" 2 | # "cJSON/include" 3 | 4 | #option 5 | "jpeg_decode/include" 6 | "jpeg_encode/include" 7 | #yuv_tab 8 | "yuv_tab/include" 9 | #bmp 10 | "bmp/include" 11 | ) 12 | 13 | # append_srcs_dir(ADD_SRCS "base64/src") 14 | # append_srcs_dir(ADD_SRCS "cJSON/src") 15 | append_srcs_dir(ADD_SRCS "yuv_tab/src") 16 | 17 | if(CONFIG_ENABLE_JPEG_DECODE) 18 | append_srcs_dir(ADD_SRCS "jpeg_decode/src") 19 | endif() 20 | 21 | if(CONFIG_ENABLE_JPEG_ENCODE) 22 | append_srcs_dir(ADD_SRCS "jpeg_encode/src") 23 | endif() 24 | 25 | if(CONFIG_IMAGE_SUFFIX STREQUAL "bmp") 26 | append_srcs_dir(ADD_SRCS "bmp/src") 27 | endif() 28 | 29 | 30 | # if(CONFIG_ENABLE_QRCODE) 31 | # append_srcs_dir(ADD_SRCS "qrcode/src") 32 | # if(CONFIG_QRCODE_TYPE_QUIRC) 33 | # append_srcs_dir(ADD_SRCS "qrcode/quirc/src") 34 | # elseif(CONFIG_QRCODE_TYPE_ZBAR) 35 | # append_srcs_dir(ADD_SRCS "qrcode/zbar/src") 36 | # endif() 37 | # endif() 38 | list(APPEND ADD_REQUIREMENTS kendryte_sdk drivers) 39 | register_component() 40 | 41 | -------------------------------------------------------------------------------- /components/utils/Kconfig: -------------------------------------------------------------------------------- 1 | 2 | menu "utils config" 3 | 4 | config ENABLE_JPEG_DECODE 5 | bool "enable jpeg decode" 6 | default n 7 | select ENABLE_SD_CARD 8 | 9 | config ENABLE_JPEG_ENCODE 10 | bool "enable jpeg encode" 11 | default n 12 | select ENABLE_SD_CARD 13 | endmenu 14 | 15 | -------------------------------------------------------------------------------- /components/utils/base64/include/base64.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Base64 encoding/decoding (RFC1341) 3 | * Copyright (c) 2005, Jouni Malinen 4 | * 5 | * This software may be distributed under the terms of the BSD license. 6 | * See README for more details. 7 | */ 8 | 9 | #ifndef BASE64_H 10 | #define BASE64_H 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | unsigned char *base64_encode(const unsigned char *src, size_t len, size_t *out_len); 17 | unsigned char *base64_decode(const unsigned char *src, size_t len, size_t *out_len); 18 | 19 | #endif /* BASE64_H */ 20 | -------------------------------------------------------------------------------- /components/utils/base64/src/base64.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Base64 encoding/decoding (RFC1341) 3 | * Copyright (c) 2005-2011, Jouni Malinen 4 | * 5 | * This software may be distributed under the terms of the BSD license. 6 | * See README for more details. 7 | */ 8 | 9 | #include "base64.h" 10 | 11 | static const unsigned char base64_table[65] = 12 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 13 | 14 | /** 15 | * base64_encode - Base64 encode 16 | * @src: Data to be encoded 17 | * @len: Length of the data to be encoded 18 | * @out_len: Pointer to output length variable, or %NULL if not used 19 | * Returns: Allocated buffer of out_len bytes of encoded data, 20 | * or %NULL on failure 21 | * 22 | * Caller is responsible for freeing the returned buffer. Returned buffer is 23 | * nul terminated to make it easier to use as a C string. The nul terminator is 24 | * not included in out_len. 25 | */ 26 | unsigned char *base64_encode(const unsigned char *src, size_t len, size_t *out_len) 27 | { 28 | unsigned char *out, *pos; 29 | const unsigned char *end, *in; 30 | size_t olen; 31 | int line_len; 32 | 33 | olen = len * 4 / 3 + 4; /* 3-byte blocks to 4-byte */ 34 | olen += olen / 72; /* line feeds */ 35 | olen++; /* nul termination */ 36 | if (olen < len) 37 | return NULL; /* integer overflow */ 38 | out = malloc(olen); 39 | if (out == NULL) 40 | return NULL; 41 | 42 | end = src + len; 43 | in = src; 44 | pos = out; 45 | line_len = 0; 46 | while (end - in >= 3) 47 | { 48 | *pos++ = base64_table[in[0] >> 2]; 49 | *pos++ = base64_table[((in[0] & 0x03) << 4) | (in[1] >> 4)]; 50 | *pos++ = base64_table[((in[1] & 0x0f) << 2) | (in[2] >> 6)]; 51 | *pos++ = base64_table[in[2] & 0x3f]; 52 | in += 3; 53 | line_len += 4; 54 | if (line_len >= 72) 55 | { 56 | // *pos++ = '\n'; 57 | line_len = 0; 58 | } 59 | } 60 | 61 | if (end - in) 62 | { 63 | *pos++ = base64_table[in[0] >> 2]; 64 | if (end - in == 1) 65 | { 66 | *pos++ = base64_table[(in[0] & 0x03) << 4]; 67 | *pos++ = '='; 68 | } 69 | else 70 | { 71 | *pos++ = base64_table[((in[0] & 0x03) << 4) | (in[1] >> 4)]; 72 | *pos++ = base64_table[(in[1] & 0x0f) << 2]; 73 | } 74 | *pos++ = '='; 75 | line_len += 4; 76 | } 77 | 78 | // if (line_len) 79 | // *pos++ = '\n'; 80 | 81 | *pos = '\0'; 82 | if (out_len) 83 | *out_len = pos - out; 84 | return out; 85 | } 86 | 87 | /** 88 | * base64_decode - Base64 decode 89 | * @src: Data to be decoded 90 | * @len: Length of the data to be decoded 91 | * @out_len: Pointer to output length variable 92 | * Returns: Allocated buffer of out_len bytes of decoded data, 93 | * or %NULL on failure 94 | * 95 | * Caller is responsible for freeing the returned buffer. 96 | */ 97 | unsigned char *base64_decode(const unsigned char *src, size_t len, size_t *out_len) 98 | { 99 | unsigned char dtable[256], *out, *pos, block[4], tmp; 100 | size_t i, count, olen; 101 | int pad = 0; 102 | 103 | memset(dtable, 0x80, 256); 104 | for (i = 0; i < sizeof(base64_table) - 1; i++) 105 | dtable[base64_table[i]] = (unsigned char)i; 106 | dtable['='] = 0; 107 | 108 | count = 0; 109 | for (i = 0; i < len; i++) 110 | { 111 | if (dtable[src[i]] != 0x80) 112 | count++; 113 | } 114 | 115 | if (count == 0 || count % 4) 116 | return NULL; 117 | 118 | olen = count / 4 * 3; 119 | pos = out = malloc(olen); 120 | if (out == NULL) 121 | return NULL; 122 | 123 | count = 0; 124 | for (i = 0; i < len; i++) 125 | { 126 | tmp = dtable[src[i]]; 127 | if (tmp == 0x80) 128 | continue; 129 | 130 | if (src[i] == '=') 131 | pad++; 132 | block[count] = tmp; 133 | count++; 134 | if (count == 4) 135 | { 136 | *pos++ = (block[0] << 2) | (block[1] >> 4); 137 | *pos++ = (block[1] << 4) | (block[2] >> 2); 138 | *pos++ = (block[2] << 6) | block[3]; 139 | count = 0; 140 | if (pad) 141 | { 142 | if (pad == 1) 143 | pos--; 144 | else if (pad == 2) 145 | pos -= 2; 146 | else 147 | { 148 | /* Invalid padding */ 149 | free(out); 150 | return NULL; 151 | } 152 | break; 153 | } 154 | } 155 | } 156 | 157 | *pos = '\0'; 158 | 159 | if (out_len) 160 | *out_len = pos - out; 161 | return out; 162 | } 163 | -------------------------------------------------------------------------------- /components/utils/bmp/include/rgb2bmp.h: -------------------------------------------------------------------------------- 1 | #ifndef _RGB2BMP_H 2 | #define _RGB2BMP_H 3 | 4 | #include 5 | #include 6 | #define BI_BITFIELDS 0x3 7 | 8 | typedef struct tagBITMAPFILEHEADER 9 | { 10 | uint16_t bfType; /* file type, must be 0x4d42, ie. BM */ 11 | uint32_t bfSize; /* file size */ 12 | uint16_t bfReserved1; /* reserved, must be 0 */ 13 | uint16_t bfReserved2; /* reserved, must be 0 */ 14 | uint32_t bfOffBits; /* bmp data offset */ 15 | } __attribute__((packed)) BitMapFileHeader; 16 | 17 | typedef struct tagBITMAPINFOHEADER{ 18 | uint32_t biSize; /* size of the struct, must be 40 */ 19 | uint32_t biWidth; /* width in pixels */ 20 | uint32_t biHeight; /* height in pixels */ 21 | uint16_t biPlanes; /* must be 0 */ 22 | uint16_t biBitCount;/* bits of one pixel */ 23 | uint32_t biCompression; /* whether compressed or not */ 24 | uint32_t biSizeImage; /* bmp data size */ 25 | uint32_t biXPelsPerMeter; /* width resolution in pixels */ 26 | uint32_t biYPelsPerMeter; /* height resolution in pixels */ 27 | uint32_t biClrUsed; /* color number used */ 28 | uint32_t biClrImportant;/* important color number used */ 29 | }__attribute__((packed)) BitMapInfoHeader; 30 | 31 | typedef struct tagRGBQUAD{ 32 | uint8_t rgbBlue; /* blue component */ 33 | uint8_t rgbGreen; /* green component */ 34 | uint8_t rgbRed; /* red component */ 35 | uint8_t rgbReserved;/* reserved */ 36 | }__attribute__((packed)) RgbQuad; 37 | 38 | int rgb565tobmp(uint8_t *buf,int width,int height, const char *filename); 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /components/utils/bmp/src/rgb2bmp.c: -------------------------------------------------------------------------------- 1 | #include "rgb2bmp.h" 2 | #include "ff.h" 3 | 4 | int rgb565tobmp(uint8_t *buf,int width,int height, const char *filename) 5 | { 6 | FIL file; 7 | FRESULT ret = FR_OK; 8 | uint32_t ret_len = 0; 9 | uint32_t i; 10 | uint16_t temp; 11 | uint16_t *ptr; 12 | 13 | BitMapFileHeader bmfHdr; /* file header */ 14 | BitMapInfoHeader bmiHdr; /* information header */ 15 | RgbQuad bmiClr[3]; /* color palette */ 16 | 17 | bmiHdr.biSize = sizeof(BitMapInfoHeader); 18 | bmiHdr.biWidth = width; 19 | bmiHdr.biHeight = height; 20 | bmiHdr.biPlanes = 1; 21 | bmiHdr.biBitCount = 16; 22 | bmiHdr.biCompression = BI_BITFIELDS; 23 | bmiHdr.biSizeImage = (width * height * 2); 24 | bmiHdr.biXPelsPerMeter = 0; 25 | bmiHdr.biYPelsPerMeter = 0; 26 | bmiHdr.biClrUsed = 0; 27 | bmiHdr.biClrImportant = 0; 28 | 29 | /* rgb565 mask */ 30 | bmiClr[0].rgbBlue = 0; 31 | bmiClr[0].rgbGreen = 0xF8; 32 | bmiClr[0].rgbRed = 0; 33 | bmiClr[0].rgbReserved = 0; 34 | 35 | bmiClr[1].rgbBlue = 0xE0; 36 | bmiClr[1].rgbGreen = 0x07; 37 | bmiClr[1].rgbRed = 0; 38 | bmiClr[1].rgbReserved = 0; 39 | 40 | bmiClr[2].rgbBlue = 0x1F; 41 | bmiClr[2].rgbGreen = 0; 42 | bmiClr[2].rgbRed = 0; 43 | bmiClr[2].rgbReserved = 0; 44 | 45 | bmfHdr.bfType = 0x4D42; 46 | bmfHdr.bfSize = sizeof(BitMapFileHeader) + sizeof(BitMapInfoHeader) + sizeof(RgbQuad) * 3 + bmiHdr.biSizeImage; 47 | bmfHdr.bfReserved1 = 0; 48 | bmfHdr.bfReserved2 = 0; 49 | bmfHdr.bfOffBits = sizeof(BitMapFileHeader) + sizeof(BitMapInfoHeader)+ sizeof(RgbQuad) * 3; 50 | 51 | ptr = (uint16_t*)buf; 52 | 53 | for (i = 0; i < width * height; i += 2) 54 | { 55 | temp = ptr[i]; 56 | ptr[i] = ptr[i + 1]; 57 | ptr[i + 1] = temp; 58 | } 59 | 60 | if ((ret = f_open(&file, filename, FA_CREATE_ALWAYS | FA_WRITE)) != FR_OK) 61 | { 62 | printf("create file %s err[%d]\n", filename, ret); 63 | return ret; 64 | } 65 | 66 | f_write(&file, &bmfHdr, sizeof(BitMapFileHeader), &ret_len); 67 | f_write(&file, &bmiHdr, sizeof(BitMapInfoHeader), &ret_len); 68 | f_write(&file, &bmiClr, 3 * sizeof(RgbQuad), &ret_len); 69 | 70 | f_write(&file, buf, bmiHdr.biSizeImage, &ret_len); 71 | 72 | f_close(&file); 73 | 74 | return 0; 75 | } 76 | 77 | -------------------------------------------------------------------------------- /components/utils/cJSON/include/cJSON_Utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2009-2017 Dave Gamble and cJSON contributors 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | THE SOFTWARE. 21 | */ 22 | 23 | #ifndef cJSON_Utils__h 24 | #define cJSON_Utils__h 25 | 26 | #ifdef __cplusplus 27 | extern "C" 28 | { 29 | #endif 30 | 31 | #include "cJSON.h" 32 | 33 | /* Implement RFC6901 (https://tools.ietf.org/html/rfc6901) JSON Pointer spec. */ 34 | CJSON_PUBLIC(cJSON *) cJSONUtils_GetPointer(cJSON * const object, const char *pointer); 35 | CJSON_PUBLIC(cJSON *) cJSONUtils_GetPointerCaseSensitive(cJSON * const object, const char *pointer); 36 | 37 | /* Implement RFC6902 (https://tools.ietf.org/html/rfc6902) JSON Patch spec. */ 38 | /* NOTE: This modifies objects in 'from' and 'to' by sorting the elements by their key */ 39 | CJSON_PUBLIC(cJSON *) cJSONUtils_GeneratePatches(cJSON * const from, cJSON * const to); 40 | CJSON_PUBLIC(cJSON *) cJSONUtils_GeneratePatchesCaseSensitive(cJSON * const from, cJSON * const to); 41 | /* Utility for generating patch array entries. */ 42 | CJSON_PUBLIC(void) cJSONUtils_AddPatchToArray(cJSON * const array, const char * const operation, const char * const path, const cJSON * const value); 43 | /* Returns 0 for success. */ 44 | CJSON_PUBLIC(int) cJSONUtils_ApplyPatches(cJSON * const object, const cJSON * const patches); 45 | CJSON_PUBLIC(int) cJSONUtils_ApplyPatchesCaseSensitive(cJSON * const object, const cJSON * const patches); 46 | 47 | /* 48 | // Note that ApplyPatches is NOT atomic on failure. To implement an atomic ApplyPatches, use: 49 | //int cJSONUtils_AtomicApplyPatches(cJSON **object, cJSON *patches) 50 | //{ 51 | // cJSON *modme = cJSON_Duplicate(*object, 1); 52 | // int error = cJSONUtils_ApplyPatches(modme, patches); 53 | // if (!error) 54 | // { 55 | // cJSON_Delete(*object); 56 | // *object = modme; 57 | // } 58 | // else 59 | // { 60 | // cJSON_Delete(modme); 61 | // } 62 | // 63 | // return error; 64 | //} 65 | // Code not added to library since this strategy is a LOT slower. 66 | */ 67 | 68 | /* Implement RFC7386 (https://tools.ietf.org/html/rfc7396) JSON Merge Patch spec. */ 69 | /* target will be modified by patch. return value is new ptr for target. */ 70 | CJSON_PUBLIC(cJSON *) cJSONUtils_MergePatch(cJSON *target, const cJSON * const patch); 71 | CJSON_PUBLIC(cJSON *) cJSONUtils_MergePatchCaseSensitive(cJSON *target, const cJSON * const patch); 72 | /* generates a patch to move from -> to */ 73 | /* NOTE: This modifies objects in 'from' and 'to' by sorting the elements by their key */ 74 | CJSON_PUBLIC(cJSON *) cJSONUtils_GenerateMergePatch(cJSON * const from, cJSON * const to); 75 | CJSON_PUBLIC(cJSON *) cJSONUtils_GenerateMergePatchCaseSensitive(cJSON * const from, cJSON * const to); 76 | 77 | /* Given a root object and a target object, construct a pointer from one to the other. */ 78 | CJSON_PUBLIC(char *) cJSONUtils_FindPointerFromObjectTo(const cJSON * const object, const cJSON * const target); 79 | 80 | /* Sorts the members of the object into alphabetical order. */ 81 | CJSON_PUBLIC(void) cJSONUtils_SortObject(cJSON * const object); 82 | CJSON_PUBLIC(void) cJSONUtils_SortObjectCaseSensitive(cJSON * const object); 83 | 84 | #ifdef __cplusplus 85 | } 86 | #endif 87 | 88 | #endif 89 | -------------------------------------------------------------------------------- /components/utils/jpeg_decode/include/picojpeg.h: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // picojpeg - Public domain, Rich Geldreich 3 | //------------------------------------------------------------------------------ 4 | #ifndef PICOJPEG_H 5 | #define PICOJPEG_H 6 | 7 | /* clang-format off */ 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | // Error codes 13 | enum 14 | { 15 | PJPG_NO_MORE_BLOCKS = 1, 16 | PJPG_BAD_DHT_COUNTS, 17 | PJPG_BAD_DHT_INDEX, 18 | PJPG_BAD_DHT_MARKER, 19 | PJPG_BAD_DQT_MARKER, 20 | PJPG_BAD_DQT_TABLE, 21 | PJPG_BAD_PRECISION, 22 | PJPG_BAD_HEIGHT, 23 | PJPG_BAD_WIDTH, 24 | PJPG_TOO_MANY_COMPONENTS, 25 | PJPG_BAD_SOF_LENGTH, 26 | PJPG_BAD_VARIABLE_MARKER, 27 | PJPG_BAD_DRI_LENGTH, 28 | PJPG_BAD_SOS_LENGTH, 29 | PJPG_BAD_SOS_COMP_ID, 30 | PJPG_W_EXTRA_BYTES_BEFORE_MARKER, 31 | PJPG_NO_ARITHMITIC_SUPPORT, 32 | PJPG_UNEXPECTED_MARKER, 33 | PJPG_NOT_JPEG, 34 | PJPG_UNSUPPORTED_MARKER, 35 | PJPG_BAD_DQT_LENGTH, 36 | PJPG_TOO_MANY_BLOCKS, 37 | PJPG_UNDEFINED_QUANT_TABLE, 38 | PJPG_UNDEFINED_HUFF_TABLE, 39 | PJPG_NOT_SINGLE_SCAN, 40 | PJPG_UNSUPPORTED_COLORSPACE, 41 | PJPG_UNSUPPORTED_SAMP_FACTORS, 42 | PJPG_DECODE_ERROR, 43 | PJPG_BAD_RESTART_MARKER, 44 | PJPG_ASSERTION_ERROR, 45 | PJPG_BAD_SOS_SPECTRAL, 46 | PJPG_BAD_SOS_SUCCESSIVE, 47 | PJPG_STREAM_READ_ERROR, 48 | PJPG_NOTENOUGHMEM, 49 | PJPG_UNSUPPORTED_COMP_IDENT, 50 | PJPG_UNSUPPORTED_QUANT_TABLE, 51 | PJPG_UNSUPPORTED_MODE, // picojpeg doesn't support progressive JPEG's 52 | }; 53 | 54 | // Scan types 55 | typedef enum 56 | { 57 | PJPG_GRAYSCALE, 58 | PJPG_YH1V1, 59 | PJPG_YH2V1, 60 | PJPG_YH1V2, 61 | PJPG_YH2V2 62 | } pjpeg_scan_type_t; 63 | 64 | typedef struct 65 | { 66 | // Image resolution 67 | int m_width; 68 | int m_height; 69 | 70 | // Number of components (1 or 3) 71 | int m_comps; 72 | 73 | // Total number of minimum coded units (MCU's) per row/col. 74 | int m_MCUSPerRow; 75 | int m_MCUSPerCol; 76 | 77 | // Scan type 78 | pjpeg_scan_type_t m_scanType; 79 | 80 | // MCU width/height in pixels (each is either 8 or 16 depending on the scan type) 81 | int m_MCUWidth; 82 | int m_MCUHeight; 83 | 84 | // m_pMCUBufR, m_pMCUBufG, and m_pMCUBufB are pointers to internal MCU Y or RGB pixel component buffers. 85 | // Each time pjpegDecodeMCU() is called successfully these buffers will be filled with 8x8 pixel blocks of Y or RGB pixels. 86 | // Each MCU consists of (m_MCUWidth/8)*(m_MCUHeight/8) Y/RGB blocks: 1 for greyscale/no subsampling, 2 for H1V2/H2V1, or 4 blocks for H2V2 sampling factors. 87 | // Each block is a contiguous array of 64 (8x8) bytes of a single component: either Y for grayscale images, or R, G or B components for color images. 88 | // 89 | // The 8x8 pixel blocks are organized in these byte arrays like this: 90 | // 91 | // PJPG_GRAYSCALE: Each MCU is decoded to a single block of 8x8 grayscale pixels. 92 | // Only the values in m_pMCUBufR are valid. Each 8 bytes is a row of pixels (raster order: left to right, top to bottom) from the 8x8 block. 93 | // 94 | // PJPG_H1V1: Each MCU contains is decoded to a single block of 8x8 RGB pixels. 95 | // 96 | // PJPG_YH2V1: Each MCU is decoded to 2 blocks, or 16x8 pixels. 97 | // The 2 RGB blocks are at byte offsets: 0, 64 98 | // 99 | // PJPG_YH1V2: Each MCU is decoded to 2 blocks, or 8x16 pixels. 100 | // The 2 RGB blocks are at byte offsets: 0, 101 | // 128 102 | // 103 | // PJPG_YH2V2: Each MCU is decoded to 4 blocks, or 16x16 pixels. 104 | // The 2x2 block array is organized at byte offsets: 0, 64, 105 | // 128, 192 106 | // 107 | // It is up to the caller to copy or blit these pixels from these buffers into the destination bitmap. 108 | unsigned char *m_pMCUBufR; 109 | unsigned char *m_pMCUBufG; 110 | unsigned char *m_pMCUBufB; 111 | } pjpeg_image_info_t; 112 | 113 | typedef unsigned char (*pjpeg_need_bytes_callback_t)(unsigned char* pBuf, unsigned char buf_size, unsigned char *pBytes_actually_read, void *pCallback_data); 114 | 115 | // Initializes the decompressor. Returns 0 on success, or one of the above error codes on failure. 116 | // pNeed_bytes_callback will be called to fill the decompressor's internal input buffer. 117 | // If reduce is 1, only the first pixel of each block will be decoded. This mode is much faster because it skips the AC dequantization, IDCT and chroma upsampling of every image pixel. 118 | // Not thread safe. 119 | unsigned char pjpeg_decode_init(pjpeg_image_info_t *pInfo, pjpeg_need_bytes_callback_t pNeed_bytes_callback, void *pCallback_data, unsigned char reduce); 120 | 121 | // Decompresses the file's next MCU. Returns 0 on success, PJPG_NO_MORE_BLOCKS if no more blocks are available, or an error code. 122 | // Must be called a total of m_MCUSPerRow*m_MCUSPerCol times to completely decompress the image. 123 | // Not thread safe. 124 | unsigned char pjpeg_decode_mcu(void); 125 | 126 | #ifdef __cplusplus 127 | } 128 | #endif 129 | 130 | #endif // PICOJPEG_H 131 | -------------------------------------------------------------------------------- /components/utils/jpeg_decode/include/picojpeg_util.h: -------------------------------------------------------------------------------- 1 | #ifndef __PICOJPEG_UTIL_H__ 2 | #define __PICOJPEG_UTIL_H__ 3 | 4 | #include 5 | 6 | typedef struct _jpeg_decode_image 7 | { 8 | uint16_t width; 9 | uint16_t height; 10 | uint8_t comps; 11 | uint8_t scan_type; 12 | uint8_t *img_data; 13 | } jpeg_decode_image_t; 14 | 15 | void convert_jpeg_img_order(jpeg_decode_image_t *jpeg); 16 | jpeg_decode_image_t *pico_jpeg_decode(uint8_t *out_img, uint8_t *buf, uint32_t buf_len, uint8_t rgb565); 17 | 18 | 19 | void jpeg_display(uint16_t startx, uint16_t starty, jpeg_decode_image_t *jpeg); 20 | 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /components/utils/jpeg_encode/include/jpeg_encode.h: -------------------------------------------------------------------------------- 1 | #ifndef __JPEG_COMPRESS_H 2 | #define __JPEG_COMPRESS_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | /* clang-format off */ 9 | #define bool uint8_t 10 | #define false 0 11 | #define true 1 12 | 13 | // For K210 14 | #define __CLZ(n) __builtin_clz(n) 15 | 16 | // Software JPEG implementation. 17 | #define FIX_0_382683433 ((int32_t)98) 18 | #define FIX_0_541196100 ((int32_t)139) 19 | #define FIX_0_707106781 ((int32_t)181) 20 | #define FIX_1_306562965 ((int32_t)334) 21 | 22 | #define DESCALE(x, y) (x >> y) 23 | #define MULTIPLY(x, y) DESCALE((x) * (y), 8) 24 | 25 | #define COLOR_GRAYSCALE_MIN 0 26 | #define COLOR_GRAYSCALE_MAX 255 27 | 28 | #define IM_LOG2_2(x) (((x) & 0x2ULL) ? ( 2 ) : 1) // NO ({ ... }) ! 29 | #define IM_LOG2_4(x) (((x) & 0xCULL) ? ( 2 + IM_LOG2_2((x) >> 2)) : IM_LOG2_2(x)) // NO ({ ... }) ! 30 | #define IM_LOG2_8(x) (((x) & 0xF0ULL) ? ( 4 + IM_LOG2_4((x) >> 4)) : IM_LOG2_4(x)) // NO ({ ... }) ! 31 | #define IM_LOG2_16(x) (((x) & 0xFF00ULL) ? ( 8 + IM_LOG2_8((x) >> 8)) : IM_LOG2_8(x)) // NO ({ ... }) ! 32 | #define IM_LOG2_32(x) (((x) & 0xFFFF0000ULL) ? (16 + IM_LOG2_16((x) >> 16)) : IM_LOG2_16(x)) // NO ({ ... }) ! 33 | #define IM_LOG2(x) (((x) & 0xFFFFFFFF00000000ULL) ? (32 + IM_LOG2_32((x) >> 32)) : IM_LOG2_32(x)) // NO ({ ... }) ! 34 | 35 | #define UINT32_T_BITS (sizeof(uint32_t) * 8) 36 | #define UINT32_T_MASK (UINT32_T_BITS - 1) 37 | #define UINT32_T_SHIFT IM_LOG2(UINT32_T_MASK) 38 | 39 | #define IM_R825(p) \ 40 | ({ __typeof__ (p) _p = (p); \ 41 | rb825_table[_p]; }) 42 | 43 | #define IM_G826(p) \ 44 | ({ __typeof__ (p) _p = (p); \ 45 | g826_table[_p]; }) 46 | 47 | #define IM_B825(p) \ 48 | ({ __typeof__ (p) _p = (p); \ 49 | rb825_table[_p]; }) 50 | 51 | #define IM_RGB565(r, g, b) \ 52 | ({ __typeof__ (r) _r = (r); \ 53 | __typeof__ (g) _g = (g); \ 54 | __typeof__ (b) _b = (b); \ 55 | ((_r)<<3)|((_g)>>3)|((_g)<<13)|((_b)<<8); }) 56 | 57 | #define IMAGE_GET_BINARY_PIXEL(image, x, y) \ 58 | ({ \ 59 | __typeof__ (image) _image = (image); \ 60 | __typeof__ (x) _x = (x); \ 61 | __typeof__ (y) _y = (y); \ 62 | (((uint32_t *) _image->data)[(((_image->w + UINT32_T_MASK) >> UINT32_T_SHIFT) * _y) + (_x >> UINT32_T_SHIFT)] >> (_x & UINT32_T_MASK)) & 1; \ 63 | }) 64 | 65 | #define IMAGE_GET_GRAYSCALE_PIXEL(image, x, y) \ 66 | ({ \ 67 | __typeof__ (image) _image = (image); \ 68 | __typeof__ (x) _x = (x); \ 69 | __typeof__ (y) _y = (y); \ 70 | ((uint8_t *) _image->data)[(_image->w * _y) + _x]; \ 71 | }) 72 | 73 | #define IMAGE_GET_RGB565_PIXEL(image, x, y) \ 74 | ({ \ 75 | __typeof__ (image) _image = (image); \ 76 | __typeof__ (x) _x = (x); \ 77 | __typeof__ (y) _y = (y); \ 78 | ((uint16_t *) _image->data)[(_image->w * _y) + _x]; \ 79 | }) 80 | 81 | #define IM_GET_RAW_PIXEL(img, x, y) \ 82 | ({ __typeof__ (img) _img = (img); \ 83 | __typeof__ (x) _x = (x); \ 84 | __typeof__ (y) _y = (y); \ 85 | ((uint8_t*)_img->pixels)[(_y*_img->w)+_x]; }) 86 | 87 | #define IM_GET_RAW_PIXEL_CHECK_BOUNDS_X(img, x, y) \ 88 | ({ __typeof__ (img) _img = (img); \ 89 | __typeof__ (x) _x = (x); \ 90 | __typeof__ (y) _y = (y); \ 91 | _x = (_x < 0) ? 0 : (_x >= img->w) ? (img->w -1): _x; \ 92 | ((uint8_t*)_img->pixels)[(_y*_img->w)+_x]; }) 93 | 94 | #define IM_GET_RAW_PIXEL_CHECK_BOUNDS_Y(img, x, y) \ 95 | ({ __typeof__ (img) _img = (img); \ 96 | __typeof__ (x) _x = (x); \ 97 | __typeof__ (y) _y = (y); \ 98 | _y = (_y < 0) ? 0 : (_y >= img->h) ? (img->h -1): _y; \ 99 | ((uint8_t*)_img->pixels)[(_y*_img->w)+_x]; }) 100 | 101 | 102 | #define IM_GET_RAW_PIXEL_CHECK_BOUNDS_XY(img, x, y) \ 103 | ({ __typeof__ (img) _img = (img); \ 104 | __typeof__ (x) _x = (x); \ 105 | __typeof__ (y) _y = (y); \ 106 | _x = (_x < 0) ? 0 : (_x >= img->w) ? (img->w -1): _x; \ 107 | _y = (_y < 0) ? 0 : (_y >= img->h) ? (img->h -1): _y; \ 108 | ((uint8_t*)_img->pixels)[(_y*_img->w)+_x]; }) 109 | 110 | #define COLOR_BINARY_TO_GRAYSCALE(pixel) ((pixel) * COLOR_GRAYSCALE_MAX) 111 | 112 | /* clang-format on */ 113 | 114 | typedef struct 115 | { 116 | int idx; 117 | int length; 118 | uint8_t *buf; 119 | int bitc, bitb; 120 | bool realloc; 121 | bool overflow; 122 | } __attribute__((aligned(8))) jpeg_buf_t; 123 | 124 | typedef enum jpeg_subsample { 125 | JPEG_SUBSAMPLE_1x1 = 0x11, // 1x1 chroma subsampling (No subsampling) 126 | JPEG_SUBSAMPLE_2x1 = 0x21, // 2x2 chroma subsampling 127 | JPEG_SUBSAMPLE_2x2 = 0x22, // 2x2 chroma subsampling 128 | } __attribute__((aligned(8))) jpeg_subsample_t; 129 | 130 | typedef struct _jpeg_encode 131 | { 132 | int w; 133 | int h; 134 | int bpp; 135 | union { 136 | uint8_t *pixels; 137 | uint8_t *data; 138 | }; 139 | } __attribute__((aligned(8))) jpeg_encode_t; 140 | 141 | bool jpeg_compress(jpeg_encode_t *src, jpeg_encode_t *dst, int quality, bool realloc); 142 | 143 | //uint8_t reverse_u32pixel(uint32_t *addr, uint32_t length); 144 | 145 | #endif 146 | -------------------------------------------------------------------------------- /components/utils/yuv_tab/include/yuv_tab.h: -------------------------------------------------------------------------------- 1 | #ifndef __YUV_TAB_H 2 | #define __YUV_TAB_H 3 | 4 | #include 5 | 6 | int8_t yuv_table(uint32_t idx); 7 | 8 | void pix_fill_yuv(uint32_t idx, int8_t *y, int8_t *u, int8_t *v); 9 | 10 | void pix_fill_8y(uint16_t *pixels, uint32_t ofs, int8_t *y); 11 | 12 | void pix_fill_8uv2(uint16_t *pixels, uint32_t ofs, int8_t *u, int8_t *v); 13 | 14 | void pix_fill_8yuv(uint16_t *pixels, uint32_t ofs, int8_t *y, int8_t *u, int8_t *v); 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /projects/dvp2lcd/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | 3 | build 4 | .config.mk 5 | .flash.conf.json 6 | 7 | -------------------------------------------------------------------------------- /projects/dvp2lcd/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.9) 2 | 3 | 4 | # Get SDK path 5 | if(NOT SDK_PATH) 6 | get_filename_component(SDK_PATH ../../ ABSOLUTE) 7 | if(EXISTS $ENV{MY_SDK_PATH}) 8 | set(SDK_PATH $ENV{MY_SDK_PATH}) 9 | endif() 10 | endif() 11 | 12 | # Check SDK Path 13 | if(NOT EXISTS ${SDK_PATH}) 14 | message(FATAL_ERROR "SDK path Error, Please set SDK_PATH or MY_SDK_PATH variable") 15 | endif() 16 | 17 | # Get Toolchain path 18 | if(NOT CONFIG_TOOLCHAIN_PATH) 19 | if(EXISTS $ENV{MY_TOOLCHAIN_PATH}) 20 | set(CONFIG_TOOLCHAIN_PATH $ENV{MY_TOOLCHAIN_PATH}) 21 | endif() 22 | endif() 23 | 24 | ## Add preprocessor definitions for whole project 25 | # add_definitions(-DAAAAA=1) 26 | 27 | # Call compile 28 | include(${SDK_PATH}/tools/cmake/compile.cmake) 29 | 30 | 31 | # Project Name 32 | project(dvp2lcd) 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /projects/dvp2lcd/compile/compile_flags.cmake: -------------------------------------------------------------------------------- 1 | 2 | ########## set C flags ######### 3 | set(CMAKE_C_FLAGS -mcmodel=medany 4 | -mabi=lp64f 5 | -march=rv64imafc 6 | -fno-common 7 | -ffunction-sections 8 | -fdata-sections 9 | -fstrict-volatile-bitfields 10 | -fno-zero-initialized-in-bss 11 | -ffast-math 12 | -fno-math-errno 13 | -fsingle-precision-constant 14 | -ffloat-store 15 | -std=gnu11 16 | -Os 17 | -Wall 18 | -Werror=all 19 | -Wno-error=unused-function 20 | -Wno-error=unused-but-set-variable 21 | -Wno-error=unused-variable 22 | -Wno-error=deprecated-declarations 23 | -Wno-error=maybe-uninitialized 24 | -Wextra 25 | -Werror=frame-larger-than=32768 26 | -Wno-unused-parameter 27 | -Wno-unused-function 28 | -Wno-implicit-fallthrough 29 | -Wno-sign-compare 30 | -Wno-error=missing-braces 31 | -Wno-old-style-declaration 32 | -Wno-error=pointer-sign 33 | -Wno-pointer-to-int-cast 34 | -Wno-strict-aliasing 35 | -Wno-int-to-pointer-cast 36 | ) 37 | ################################ 38 | 39 | 40 | ###### set CXX(cpp) flags ###### 41 | set(CMAKE_CXX_FLAGS -mcmodel=medany 42 | -mabi=lp64f 43 | -march=rv64imafc 44 | -fno-common 45 | -ffunction-sections 46 | -fdata-sections 47 | -fstrict-volatile-bitfields 48 | -fno-zero-initialized-in-bss 49 | -Os 50 | -std=gnu++17 51 | -Wall 52 | -Wno-error=unused-function 53 | -Wno-error=unused-but-set-variable 54 | -Wno-error=unused-variable 55 | -Wno-error=deprecated-declarations 56 | -Wno-error=maybe-uninitialized 57 | -Wextra 58 | -Werror=frame-larger-than=32768 59 | -Wno-unused-parameter 60 | -Wno-unused-function 61 | -Wno-implicit-fallthrough 62 | -Wno-sign-compare 63 | -Wno-error=missing-braces 64 | -Wno-error=pointer-sign 65 | -Wno-pointer-to-int-cast 66 | -Wno-strict-aliasing 67 | -Wno-int-to-pointer-cast 68 | ) 69 | ################################ 70 | 71 | set(LINK_FLAGS ${LINK_FLAGS} 72 | -static 73 | -Wl,-static 74 | -nostartfiles 75 | -Wl,--gc-sections 76 | -Wl,-EL 77 | -T ${PROJECT_SOURCE_DIR}/compile/kendryte.ld 78 | -Wl,--start-group 79 | -Wl,--whole-archive 80 | kendryte_sdk/libkendryte_sdk.a main/libmain.a 81 | -Wl,--no-whole-archive 82 | -Wl,--end-group 83 | ) 84 | set(CMAKE_C_LINK_FLAGS ${CMAKE_C_LINK_FLAGS} 85 | ${LINK_FLAGS} 86 | ) 87 | set(CMAKE_CXX_LINK_FLAGS ${CMAKE_C_LINK_FLAGS} 88 | ) 89 | # set(CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS} 90 | # ${LINK_FLAGS} 91 | # ) 92 | # set(CMAKE_SHARED_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS} 93 | # ${LINK_FLAGS} 94 | # ) 95 | # set(CMAKE_MODULE_LINKER_FLAGS ${CMAKE_MODULE_LINKER_FLAGS} 96 | # ${LINK_FLAGS} 97 | # ) 98 | 99 | 100 | # Convert list to string 101 | string(REPLACE ";" " " CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") 102 | string(REPLACE ";" " " CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") 103 | string(REPLACE ";" " " LINK_FLAGS "${LINK_FLAGS}") 104 | string(REPLACE ";" " " CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS}") 105 | string(REPLACE ";" " " CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS}") 106 | -------------------------------------------------------------------------------- /projects/dvp2lcd/compile/gen_binary.cmake: -------------------------------------------------------------------------------- 1 | 2 | execute_process(COMMAND ${CMAKE_C_COMPILER} -print-file-name=crt0.o OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE CRT0_OBJ) 3 | execute_process(COMMAND ${CMAKE_C_COMPILER} -print-file-name=crtbegin.o OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE CRTBEGIN_OBJ) 4 | execute_process(COMMAND ${CMAKE_C_COMPILER} -print-file-name=crtend.o OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE CRTEND_OBJ) 5 | execute_process(COMMAND ${CMAKE_C_COMPILER} -print-file-name=crti.o OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE CRTI_OBJ) 6 | execute_process(COMMAND ${CMAKE_C_COMPILER} -print-file-name=crtn.o OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE CRTN_OBJ) 7 | 8 | 9 | set(CMAKE_C_LINK_EXECUTABLE " \"${CRTI_OBJ}\" \"${CRTBEGIN_OBJ}\" \"${CRTEND_OBJ}\" \"${CRTN_OBJ}\" -o .elf ") 10 | set(CMAKE_CXX_LINK_EXECUTABLE " \"${CRTI_OBJ}\" \"${CRTBEGIN_OBJ}\" \"${CRTEND_OBJ}\" \"${CRTN_OBJ}\" -o .elf ") 11 | 12 | 13 | # Config toolchain 14 | if(CONFIG_TOOLCHAIN_PATH) 15 | set(CMAKE_SIZE "${CONFIG_TOOLCHAIN_PATH}/${CONFIG_TOOLCHAIN_PREFIX}size${EXT}") 16 | set(CMAKE_OBJDUMP "${CONFIG_TOOLCHAIN_PATH}/${CONFIG_TOOLCHAIN_PREFIX}objdump${EXT}") 17 | else() 18 | set(CMAKE_SIZE "size${EXT}") 19 | set(CMAKE_SIZE "objdump${EXT}") 20 | endif() 21 | 22 | add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD 23 | COMMAND ${CMAKE_OBJCOPY} --output-format=binary ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.elf ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.bin 24 | COMMENT "-- Generating .bin firmware at ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.bin" 25 | ) 26 | 27 | add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD 28 | COMMAND ${CMAKE_SIZE} ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.elf 29 | COMMENT "============= firmware =============" 30 | ) 31 | 32 | add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD 33 | COMMAND ${CMAKE_OBJDUMP} -S ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.elf > ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.txt 34 | ) 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /projects/dvp2lcd/compile/kendryte.ld: -------------------------------------------------------------------------------- 1 | /* 2 | * The MEMORY command describes the location and size of blocks of memory 3 | * in the target. You can use it to describe which memory regions may be 4 | * used by the linker, and which memory regions it must avoid. 5 | */ 6 | MEMORY 7 | { 8 | /* 9 | * Memory with CPU cache. 10 | *6M CPU SRAM 11 | */ 12 | ram (wxa!ri) : ORIGIN = 0x80000000, LENGTH = (6 * 1024 * 1024) 13 | /* 14 | * Memory without CPU cache 15 | * 6M CPU SRAM 16 | */ 17 | ram_nocache (wxa!ri) : ORIGIN = 0x40000000, LENGTH = (6 * 1024 * 1024) 18 | } 19 | 20 | PROVIDE( _rom_start = ORIGIN(rom) ); 21 | PROVIDE( _rom_end = ORIGIN(rom) + LENGTH(rom) ); 22 | PROVIDE( _ram_start = ORIGIN(ram) ); 23 | PROVIDE( _ram_end = ORIGIN(ram) + LENGTH(ram) ); 24 | PROVIDE( _io_start = 0x40000000 ); 25 | PROVIDE( _io_end = _io_start + LENGTH(ram) ); 26 | PROVIDE( _stack_size = 1 << 15 ); 27 | 28 | 29 | /* 30 | * The OUTPUT_ARCH command specifies the machine architecture where the 31 | * argument is one of the names used in the Kendryte library. 32 | */ 33 | OUTPUT_ARCH( "riscv" ) 34 | 35 | /* 36 | * The ENTRY command specifies the entry point (ie. first instruction to 37 | * execute). The symbol _start is defined in crt0.S 38 | */ 39 | ENTRY(_start) 40 | 41 | /* 42 | * The GROUP command is special since the listed archives will be 43 | * searched repeatedly until there are no new undefined references. We 44 | * need this since -lc depends on -lgloss and -lgloss depends on -lc. I 45 | * thought gcc would automatically include -lgcc when needed, but 46 | * in this file includes it explicitly here and I was seeing link errors 47 | * without it. 48 | */ 49 | /* GROUP( -lc -lgloss -lgcc ) */ 50 | 51 | /* 52 | * The linker only pays attention to the PHDRS command when generating 53 | * an ELF output file. In other cases, the linker will simply ignore PHDRS. 54 | */ 55 | PHDRS 56 | { 57 | ram_ro PT_LOAD; 58 | ram_init PT_LOAD; 59 | ram PT_NULL; 60 | } 61 | 62 | /* 63 | * This is where we specify how the input sections map to output 64 | * sections. 65 | */ 66 | SECTIONS 67 | { 68 | /* Program code segment, also known as a text segment */ 69 | .text : 70 | { 71 | PROVIDE( _text = ABSOLUTE(.) ); 72 | /* Initialization code segment */ 73 | KEEP( *(.text.start) ) 74 | *(.text.unlikely .text.unlikely.*) 75 | *(.text.startup .text.startup.*) 76 | /* Normal code segment */ 77 | *(.text .text.*) 78 | *(.gnu.linkonce.t.*) 79 | 80 | . = ALIGN(8); 81 | PROVIDE( _etext = ABSOLUTE(.) ); 82 | } >ram AT>ram :ram_ro 83 | 84 | /* Read-only data segment */ 85 | .rodata : 86 | { 87 | *(.rdata) 88 | *(.rodata .rodata.*) 89 | *(.gnu.linkonce.r.*) 90 | } >ram AT>ram :ram_ro 91 | 92 | . = ALIGN(8); 93 | 94 | /* Exception handling */ 95 | .eh_frame : 96 | { 97 | KEEP (*(.eh_frame)) *(.eh_frame.*) 98 | . = ALIGN(8); 99 | } >ram AT>ram :ram_ro 100 | .gnu_extab : { *(.gnu_extab) } >ram AT>ram :ram_ro 101 | .gcc_except_table : { *(.gcc_except_table .gcc_except_table.*) } >ram AT>ram :ram_ro 102 | .exception_ranges : { *(.exception_ranges .exception_ranges*) } >ram AT>ram :ram_ro 103 | 104 | /* Init array and fini array */ 105 | .preinit_array : 106 | { 107 | PROVIDE_HIDDEN (__preinit_array_start = .); 108 | KEEP (*(.preinit_array)) 109 | PROVIDE_HIDDEN (__preinit_array_end = .); 110 | } >ram AT>ram :ram_ro 111 | 112 | .init_array : 113 | { 114 | PROVIDE_HIDDEN (__init_array_start = .); 115 | KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) 116 | *(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors) 117 | PROVIDE_HIDDEN (__init_array_end = .); 118 | } >ram AT>ram :ram_ro 119 | 120 | .fini_array : 121 | { 122 | PROVIDE_HIDDEN (__fini_array_start = .); 123 | KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) 124 | KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) 125 | PROVIDE_HIDDEN (__fini_array_end = .); 126 | } >ram AT>ram :ram_ro 127 | 128 | .ctors : 129 | { 130 | /* gcc uses crtbegin.o to find the start of 131 | the constructors, so we make sure it is 132 | first. Because this is a wildcard, it 133 | doesn't matter if the user does not 134 | actually link against crtbegin.o; the 135 | linker won't look for a file to match a 136 | wildcard. The wildcard also means that it 137 | doesn't matter which directory crtbegin.o 138 | is in. */ 139 | KEEP (*crtbegin.o(.ctors)) 140 | KEEP (*crtbegin?.o(.ctors)) 141 | /* We don't want to include the .ctor section from 142 | the crtend.o file until after the sorted ctors. 143 | The .ctor section from the crtend file contains the 144 | end of ctors marker and it must be last */ 145 | KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) 146 | KEEP (*(SORT(.ctors.*))) 147 | KEEP (*(.ctors)) 148 | } >ram AT>ram :ram_ro 149 | 150 | .dtors : 151 | { 152 | KEEP (*crtbegin.o(.dtors)) 153 | KEEP (*crtbegin?.o(.dtors)) 154 | KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) 155 | KEEP (*(SORT(.dtors.*))) 156 | KEEP (*(.dtors)) 157 | } >ram AT>ram :ram_ro 158 | 159 | . = ALIGN(8); 160 | 161 | .lalign : 162 | { 163 | . = ALIGN(8); 164 | PROVIDE( _data_lma = . ); 165 | } >ram AT>ram :ram_ro 166 | 167 | .dalign : 168 | { 169 | . = ALIGN(8); 170 | PROVIDE( _data = . ); 171 | } >ram AT>ram :ram_init 172 | 173 | . = ALIGN(8); 174 | 175 | /* .data, .sdata and .srodata segment */ 176 | .data : 177 | { 178 | /* Writable data segment (.data segment) */ 179 | *(.data .data.*) 180 | *(.gnu.linkonce.d.*) 181 | /* Have _gp point to middle of sdata/sbss to maximize displacement range */ 182 | . = ALIGN(8); 183 | PROVIDE( __global_pointer$ = ABSOLUTE(.) + 0x800); 184 | /* Writable small data segment (.sdata segment) */ 185 | *(.sdata .sdata.*) 186 | *(.gnu.linkonce.s.*) 187 | /* Read-only small data segment (.srodata segment) */ 188 | . = ALIGN(8); 189 | *(.srodata.cst16) 190 | *(.srodata.cst8) 191 | *(.srodata.cst4) 192 | *(.srodata.cst2) 193 | *(.srodata .srodata.*) 194 | /* Align _edata to cache line size */ 195 | . = ALIGN(64); 196 | PROVIDE( _edata = ABSOLUTE(.) ); 197 | } >ram AT>ram :ram_init 198 | 199 | /* .bss and .sbss segment */ 200 | .bss : 201 | { 202 | PROVIDE( _bss = ABSOLUTE(.) ); 203 | /* Writable uninitialized small data segment (.sbss segment)*/ 204 | *(.sbss .sbss.*) 205 | *(.gnu.linkonce.sb.*) 206 | *(.scommon) 207 | /* Uninitialized writeable data section (.bss segment)*/ 208 | *(.bss .bss.*) 209 | *(.gnu.linkonce.b.*) 210 | *(COMMON) 211 | 212 | . = ALIGN(8); 213 | PROVIDE( _ebss = ABSOLUTE(.) ); 214 | } >ram AT>ram :ram 215 | 216 | PROVIDE( _tls_data = ABSOLUTE(.) ); 217 | /* 218 | * Thread Local Storage (TLS) are per-thread global variables. 219 | * Compilers such as GCC provide a __thread keyword to mark global 220 | * variables as per-thread. Support is required in the program loader 221 | * and thread creator. 222 | */ 223 | 224 | /* Thread-local data segment, .tdata (initialized tls). */ 225 | .tdata : 226 | { 227 | KEEP( *(.tdata.begin) ) 228 | *(.tdata .tdata.*) 229 | *(.gnu.linkonce.td.*) 230 | KEEP( *(.tdata.end) ) 231 | } >ram AT>ram :ram 232 | 233 | /* Thread-local bss segment, .tbss (zero-initialized tls). */ 234 | .tbss : 235 | { 236 | *(.tbss .tbss.*) 237 | *(.gnu.linkonce.tb.*) 238 | KEEP( *(.tbss.end) ) 239 | } >ram AT>ram :ram 240 | 241 | /* 242 | * End of uninitalized data segement 243 | * 244 | * Actually the stack needs 16B alignment, and it won't hurt to also slightly 245 | * increase the alignment to 32 or even 64 (cache line size). 246 | * 247 | * Align _heap_start to cache line size 248 | */ 249 | . = ALIGN(64); 250 | PROVIDE( _end = ABSOLUTE(.) ); 251 | /* Leave 2 holes for stack & TLS, the size can set in kconfig */ 252 | PROVIDE( _heap_start = ABSOLUTE(.) + _stack_size * 2 ); 253 | PROVIDE( _tp0 = (_end + 63) & (-64) ); 254 | PROVIDE( _tp1 = _tp0 + _stack_size ); 255 | PROVIDE( _sp0 = _tp0 + _stack_size ); 256 | PROVIDE( _sp1 = _tp1 + _stack_size ); 257 | 258 | /* Heap end is at the end of memory, the memory size can set in kconfig */ 259 | PROVIDE( _heap_end = _ram_end ); 260 | } 261 | 262 | -------------------------------------------------------------------------------- /projects/dvp2lcd/compile/priority.conf: -------------------------------------------------------------------------------- 1 | # component register priority 2 | # The upper components have higher priority 3 | # comments start with `#` 4 | 5 | 6 | kendryte_sdk 7 | main 8 | 9 | -------------------------------------------------------------------------------- /projects/dvp2lcd/config_defaults.mk: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | CONFIG_KENDRYTE_SDK_ENABLE=y 5 | CONFIG_SDK_LOG_LEVEL=5 6 | 7 | -------------------------------------------------------------------------------- /projects/dvp2lcd/download2board.sh: -------------------------------------------------------------------------------- 1 | python project.py -B dan -p /dev/ttyUSB1 -b 2000000 -t -S flash -------------------------------------------------------------------------------- /projects/dvp2lcd/main/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ############### Add include ################### 2 | #list(APPEND ADD_INCLUDE "include") 3 | # list(APPEND ADD_PRIVATE_INCLUDE "") 4 | ############################################### 5 | 6 | ############ Add source files ################# 7 | # list(APPEND ADD_SRCS "src/main.c") 8 | append_srcs_dir(ADD_SRCS "src") 9 | 10 | # aux_source_directory(src ADD_SRCS) 11 | # list(REMOVE_ITEM COMPONENT_SRCS "src/test2.c") 12 | ############################################### 13 | 14 | ###### Add required/dependent components ###### 15 | list(APPEND ADD_REQUIREMENTS kendryte_sdk drivers) 16 | ############################################### 17 | 18 | ############ Add static libs ################## 19 | # list(APPEND ADD_STATIC_LIB "lib/libtest.a") 20 | ############################################### 21 | 22 | 23 | register_component() 24 | -------------------------------------------------------------------------------- /projects/dvp2lcd/main/Kconfig: -------------------------------------------------------------------------------- 1 | menu "Application configuration" 2 | 3 | menu "Board Type Select" 4 | 5 | choice BBOARD_TYPE 6 | bool "board type" 7 | default MAIX_DOCK 8 | 9 | config MAIX_DOCK 10 | bool "default DOCK board" 11 | 12 | config SELF_DEFINE 13 | bool "client 1 board" 14 | endchoice 15 | 16 | endmenu 17 | 18 | 19 | menu "Drivers configuration" 20 | # camera 21 | osource "${SDK_PATH}/components/drivers/camera/Kconfig" 22 | 23 | # lcd 24 | osource "${SDK_PATH}/components/drivers/lcd/Kconfig" 25 | 26 | #flash 27 | osource "${SDK_PATH}/components/drivers/flash/Kconfig" 28 | 29 | # sd_card 30 | osource "${SDK_PATH}/components/drivers/sd_card/Kconfig" 31 | 32 | endmenu 33 | 34 | 35 | endmenu 36 | 37 | -------------------------------------------------------------------------------- /projects/dvp2lcd/main/src/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "unistd.h" 4 | #include "sysctl.h" 5 | #include "global_config.h" 6 | 7 | #include "dvp.h" 8 | #include "fpioa.h" 9 | #include "iomem.h" 10 | #include "plic.h" 11 | #include "camera.h" 12 | #include "rtc.h" 13 | #include "syslog.h" 14 | 15 | #if CONFIG_ENABLE_LCD 16 | #include "nt35310.h" 17 | #include "lcd.h" 18 | #endif 19 | 20 | 21 | 22 | static const char *TAG = "MAIN"; 23 | 24 | static uint32_t *g_lcd_gram0; 25 | static uint32_t *g_lcd_gram1; 26 | volatile uint8_t g_dvp_finish_flag; 27 | 28 | 29 | volatile uint8_t g_ram_mux; 30 | #if CONFIG_ENABLE_LCD 31 | static uint32_t time_ram[8 * 16 * 8 / 2]; 32 | 33 | void rgb888_to_lcd(uint8_t *src, uint16_t *dest, size_t width, size_t height) 34 | { 35 | size_t chn_size = width * height; 36 | for (size_t i = 0; i < width * height; i++) 37 | { 38 | uint8_t r = src[i]; 39 | uint8_t g = src[chn_size + i]; 40 | uint8_t b = src[chn_size * 2 + i]; 41 | 42 | uint16_t rgb = ((r & 0b11111000) << 8) | ((g & 0b11111100) << 3) | (b >> 3); 43 | size_t d_i = i % 2 ? (i - 1) : (i + 1); 44 | dest[d_i] = rgb; 45 | } 46 | } 47 | #endif 48 | 49 | /*GET TIME*/ 50 | void get_date_time() 51 | { 52 | char time[25]; 53 | int year; 54 | int month; 55 | int day; 56 | int hour; 57 | int minute; 58 | int second; 59 | int w; 60 | rtc_timer_get(&year, &month, &day, &hour, &minute, &second); 61 | sprintf(time, "%02d:%02d:%02d", hour, minute, second); 62 | w = strlen(time) * 8; 63 | #if CONFIG_ENABLE_LCD 64 | lcd_ram_draw_string(time, time_ram, BLACK, WHITE); 65 | lcd_draw_picture(110, 0, w, 16, time_ram); 66 | #endif 67 | } 68 | /*TIME INTERRUPT*/ 69 | int on_timer_interrupt() 70 | { 71 | get_date_time(); 72 | return 0; 73 | } 74 | 75 | static int on_irq_dvp(void *ctx) 76 | { 77 | if (dvp_get_interrupt(DVP_STS_FRAME_FINISH)) 78 | { 79 | /* switch gram */ 80 | dvp_set_display_addr(g_ram_mux ? (uint32_t)g_lcd_gram0 : (uint32_t)g_lcd_gram1); 81 | 82 | dvp_clear_interrupt(DVP_STS_FRAME_FINISH); 83 | g_dvp_finish_flag = 1; 84 | } 85 | else 86 | { 87 | if (g_dvp_finish_flag == 0) 88 | dvp_start_convert(); 89 | dvp_clear_interrupt(DVP_STS_FRAME_START); 90 | } 91 | 92 | return 0; 93 | } 94 | 95 | int main(void) 96 | { 97 | /* Set CPU and dvp clk */ 98 | sysctl_pll_set_freq(SYSCTL_PLL0, 800000000UL); 99 | sysctl_pll_set_freq(SYSCTL_PLL1, 400000000UL); 100 | 101 | 102 | plic_init(); 103 | rtc_init(); 104 | /* DVP init */ 105 | LOGI(TAG, "DVP init"); 106 | camera_init(); 107 | #if CONFIG_ENABLE_LCD 108 | /* LCD init */ 109 | LOGI(TAG, "LCD init"); 110 | lcd_init(); 111 | #if CONFIG_MAIX_DOCK 112 | lcd_set_direction(DIR_YX_RLDU); 113 | 114 | #else 115 | lcd_set_direction(DIR_YX_RLUD); 116 | #endif 117 | 118 | lcd_clear(BLACK); 119 | #endif 120 | g_lcd_gram0 = (uint32_t *)iomem_malloc(320 * 240 * 2); 121 | g_lcd_gram1 = (uint32_t *)iomem_malloc(320 * 240 * 2); 122 | 123 | 124 | dvp_set_ai_addr((uint32_t)0x40600000, (uint32_t)0x40612C00, (uint32_t)0x40625800); 125 | dvp_set_display_addr((uint32_t)g_lcd_gram0); 126 | dvp_config_interrupt(DVP_CFG_START_INT_ENABLE | DVP_CFG_FINISH_INT_ENABLE, 0); 127 | dvp_disable_auto(); 128 | 129 | /* DVP interrupt config */ 130 | LOGD(TAG, "DVP interrupt config"); 131 | plic_set_priority(IRQN_DVP_INTERRUPT, 1); 132 | plic_irq_register(IRQN_DVP_INTERRUPT, on_irq_dvp, NULL); 133 | plic_irq_enable(IRQN_DVP_INTERRUPT); 134 | 135 | /* enable global interrupt */ 136 | sysctl_enable_irq(); 137 | 138 | /* system start */ 139 | LOGI(TAG, "System start"); 140 | g_ram_mux = 0; 141 | g_dvp_finish_flag = 0; 142 | dvp_clear_interrupt(DVP_STS_FRAME_START | DVP_STS_FRAME_FINISH); 143 | dvp_config_interrupt(DVP_CFG_START_INT_ENABLE | DVP_CFG_FINISH_INT_ENABLE, 1); 144 | uint64_t time_last = sysctl_get_time_us(); 145 | uint64_t time_now = sysctl_get_time_us(); 146 | char buf[10]; 147 | rtc_timer_set(2020, 7, 14, 14, 00, 50); 148 | 149 | while (1) 150 | { 151 | /* ai cal finish*/ 152 | while (g_dvp_finish_flag == 0) 153 | ; 154 | g_dvp_finish_flag = 0; 155 | // uint8_t* d=g_ram_mux?(uint16_t*)g_lcd_gram0:(uint16_t*)g_lcd_gram1; 156 | // for(int i=0;i<240;i++) 157 | // { 158 | // for(int j=0;j<320;j++) 159 | // { 160 | // printf("%d ",d[i*320+j]); 161 | // } 162 | // printf("\n"); 163 | // } 164 | #if CONFIG_ENABLE_LCD 165 | /* display pic*/ 166 | g_ram_mux ^= 0x01; 167 | 168 | lcd_draw_picture(0, 0, 320, 240, g_ram_mux ? g_lcd_gram0 : g_lcd_gram1); 169 | 170 | time_last = sysctl_get_time_us(); 171 | float fps = 1e6 / (time_last - time_now); 172 | sprintf(buf, "%0.2ffps", fps); 173 | time_now = time_last; 174 | get_date_time(); //update time 175 | lcd_ram_draw_string(buf, time_ram, BLACK, WHITE); 176 | lcd_draw_picture(0, 0, strlen(buf) * 8, 16, time_ram); 177 | printf("enable lcd\n"); 178 | #endif 179 | } 180 | iomem_free(g_lcd_gram0); 181 | iomem_free(g_lcd_gram1); 182 | return 0; 183 | } 184 | -------------------------------------------------------------------------------- /projects/dvp2lcd/project.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | #-*- coding = utf-8 -*- 3 | 4 | # 5 | # @file from https://github.com/Neutree/c_cpp_project_framework 6 | # @author neucrack 7 | # @license Apache 2.0 8 | # 9 | 10 | import sys, os 11 | 12 | sdk_env_name = "MY_SDK_PATH" 13 | 14 | # get SDK absolute path 15 | sdk_path = os.path.abspath(sys.path[0]+"/../../") 16 | try: 17 | sdk_path = os.environ[sdk_env_name] 18 | except Exception: 19 | pass 20 | print("-- SDK_PATH:{}".format(sdk_path)) 21 | 22 | # execute project script from SDK 23 | project_file_path = sdk_path+"/tools/cmake/project.py" 24 | with open(project_file_path) as f: 25 | exec(f.read()) 26 | 27 | -------------------------------------------------------------------------------- /projects/dvp2sdcard/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | 3 | build 4 | .config.mk 5 | .flash.conf.json 6 | 7 | -------------------------------------------------------------------------------- /projects/dvp2sdcard/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.9) 2 | 3 | 4 | # Get SDK path 5 | if(NOT SDK_PATH) 6 | get_filename_component(SDK_PATH ../../ ABSOLUTE) 7 | if(EXISTS $ENV{MY_SDK_PATH}) 8 | set(SDK_PATH $ENV{MY_SDK_PATH}) 9 | endif() 10 | endif() 11 | 12 | # Check SDK Path 13 | if(NOT EXISTS ${SDK_PATH}) 14 | message(FATAL_ERROR "SDK path Error, Please set SDK_PATH or MY_SDK_PATH variable") 15 | endif() 16 | 17 | # Get Toolchain path 18 | if(NOT CONFIG_TOOLCHAIN_PATH) 19 | if(EXISTS $ENV{MY_TOOLCHAIN_PATH}) 20 | set(CONFIG_TOOLCHAIN_PATH $ENV{MY_TOOLCHAIN_PATH}) 21 | endif() 22 | endif() 23 | 24 | ## Add preprocessor definitions for whole project 25 | # add_definitions(-DAAAAA=1) 26 | 27 | # Call compile 28 | include(${SDK_PATH}/tools/cmake/compile.cmake) 29 | 30 | 31 | # Project Name 32 | project(dvp2sdcard) 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /projects/dvp2sdcard/compile/compile_flags.cmake: -------------------------------------------------------------------------------- 1 | 2 | ########## set C flags ######### 3 | set(CMAKE_C_FLAGS -mcmodel=medany 4 | -mabi=lp64f 5 | -march=rv64imafc 6 | -fno-common 7 | -ffunction-sections 8 | -fdata-sections 9 | -fstrict-volatile-bitfields 10 | -fno-zero-initialized-in-bss 11 | -ffast-math 12 | -fno-math-errno 13 | -fsingle-precision-constant 14 | -ffloat-store 15 | -std=gnu11 16 | -Os 17 | -Wall 18 | -Werror=all 19 | -Wno-error=unused-function 20 | -Wno-error=unused-but-set-variable 21 | -Wno-error=unused-variable 22 | -Wno-error=deprecated-declarations 23 | -Wno-error=maybe-uninitialized 24 | -Wextra 25 | -Werror=frame-larger-than=32768 26 | -Wno-unused-parameter 27 | -Wno-unused-function 28 | -Wno-implicit-fallthrough 29 | -Wno-sign-compare 30 | -Wno-error=missing-braces 31 | -Wno-old-style-declaration 32 | -Wno-error=pointer-sign 33 | -Wno-pointer-to-int-cast 34 | -Wno-strict-aliasing 35 | -Wno-int-to-pointer-cast 36 | ) 37 | ################################ 38 | 39 | 40 | ###### set CXX(cpp) flags ###### 41 | set(CMAKE_CXX_FLAGS -mcmodel=medany 42 | -mabi=lp64f 43 | -march=rv64imafc 44 | -fno-common 45 | -ffunction-sections 46 | -fdata-sections 47 | -fstrict-volatile-bitfields 48 | -fno-zero-initialized-in-bss 49 | -Os 50 | -std=gnu++17 51 | -Wall 52 | -Wno-error=unused-function 53 | -Wno-error=unused-but-set-variable 54 | -Wno-error=unused-variable 55 | -Wno-error=deprecated-declarations 56 | -Wno-error=maybe-uninitialized 57 | -Wextra 58 | -Werror=frame-larger-than=32768 59 | -Wno-unused-parameter 60 | -Wno-unused-function 61 | -Wno-implicit-fallthrough 62 | -Wno-sign-compare 63 | -Wno-error=missing-braces 64 | -Wno-error=pointer-sign 65 | -Wno-pointer-to-int-cast 66 | -Wno-strict-aliasing 67 | -Wno-int-to-pointer-cast 68 | ) 69 | ################################ 70 | 71 | set(LINK_FLAGS ${LINK_FLAGS} 72 | -static 73 | -Wl,-static 74 | -nostartfiles 75 | -Wl,--gc-sections 76 | -Wl,-EL 77 | -T ${PROJECT_SOURCE_DIR}/compile/kendryte.ld 78 | -Wl,--start-group 79 | -Wl,--whole-archive 80 | kendryte_sdk/libkendryte_sdk.a main/libmain.a 81 | -Wl,--no-whole-archive 82 | -Wl,--end-group 83 | ) 84 | set(CMAKE_C_LINK_FLAGS ${CMAKE_C_LINK_FLAGS} 85 | ${LINK_FLAGS} 86 | ) 87 | set(CMAKE_CXX_LINK_FLAGS ${CMAKE_C_LINK_FLAGS} 88 | ) 89 | # set(CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS} 90 | # ${LINK_FLAGS} 91 | # ) 92 | # set(CMAKE_SHARED_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS} 93 | # ${LINK_FLAGS} 94 | # ) 95 | # set(CMAKE_MODULE_LINKER_FLAGS ${CMAKE_MODULE_LINKER_FLAGS} 96 | # ${LINK_FLAGS} 97 | # ) 98 | 99 | 100 | # Convert list to string 101 | string(REPLACE ";" " " CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") 102 | string(REPLACE ";" " " CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") 103 | string(REPLACE ";" " " LINK_FLAGS "${LINK_FLAGS}") 104 | string(REPLACE ";" " " CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS}") 105 | string(REPLACE ";" " " CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS}") 106 | -------------------------------------------------------------------------------- /projects/dvp2sdcard/compile/gen_binary.cmake: -------------------------------------------------------------------------------- 1 | 2 | execute_process(COMMAND ${CMAKE_C_COMPILER} -print-file-name=crt0.o OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE CRT0_OBJ) 3 | execute_process(COMMAND ${CMAKE_C_COMPILER} -print-file-name=crtbegin.o OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE CRTBEGIN_OBJ) 4 | execute_process(COMMAND ${CMAKE_C_COMPILER} -print-file-name=crtend.o OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE CRTEND_OBJ) 5 | execute_process(COMMAND ${CMAKE_C_COMPILER} -print-file-name=crti.o OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE CRTI_OBJ) 6 | execute_process(COMMAND ${CMAKE_C_COMPILER} -print-file-name=crtn.o OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE CRTN_OBJ) 7 | 8 | 9 | set(CMAKE_C_LINK_EXECUTABLE " \"${CRTI_OBJ}\" \"${CRTBEGIN_OBJ}\" \"${CRTEND_OBJ}\" \"${CRTN_OBJ}\" -o .elf ") 10 | set(CMAKE_CXX_LINK_EXECUTABLE " \"${CRTI_OBJ}\" \"${CRTBEGIN_OBJ}\" \"${CRTEND_OBJ}\" \"${CRTN_OBJ}\" -o .elf ") 11 | 12 | 13 | # Config toolchain 14 | if(CONFIG_TOOLCHAIN_PATH) 15 | set(CMAKE_SIZE "${CONFIG_TOOLCHAIN_PATH}/${CONFIG_TOOLCHAIN_PREFIX}size${EXT}") 16 | set(CMAKE_OBJDUMP "${CONFIG_TOOLCHAIN_PATH}/${CONFIG_TOOLCHAIN_PREFIX}objdump${EXT}") 17 | else() 18 | set(CMAKE_SIZE "size${EXT}") 19 | set(CMAKE_SIZE "objdump${EXT}") 20 | endif() 21 | 22 | add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD 23 | COMMAND ${CMAKE_OBJCOPY} --output-format=binary ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.elf ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.bin 24 | COMMENT "-- Generating .bin firmware at ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.bin" 25 | ) 26 | 27 | add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD 28 | COMMAND ${CMAKE_SIZE} ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.elf 29 | COMMENT "============= firmware =============" 30 | ) 31 | 32 | add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD 33 | COMMAND ${CMAKE_OBJDUMP} -S ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.elf > ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.txt 34 | ) 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /projects/dvp2sdcard/compile/kendryte.ld: -------------------------------------------------------------------------------- 1 | /* 2 | * The MEMORY command describes the location and size of blocks of memory 3 | * in the target. You can use it to describe which memory regions may be 4 | * used by the linker, and which memory regions it must avoid. 5 | */ 6 | MEMORY 7 | { 8 | /* 9 | * Memory with CPU cache. 10 | *6M CPU SRAM 11 | */ 12 | ram (wxa!ri) : ORIGIN = 0x80000000, LENGTH = (6 * 1024 * 1024) 13 | /* 14 | * Memory without CPU cache 15 | * 6M CPU SRAM 16 | */ 17 | ram_nocache (wxa!ri) : ORIGIN = 0x40000000, LENGTH = (6 * 1024 * 1024) 18 | } 19 | 20 | PROVIDE( _rom_start = ORIGIN(rom) ); 21 | PROVIDE( _rom_end = ORIGIN(rom) + LENGTH(rom) ); 22 | PROVIDE( _ram_start = ORIGIN(ram) ); 23 | PROVIDE( _ram_end = ORIGIN(ram) + LENGTH(ram) ); 24 | PROVIDE( _io_start = 0x40000000 ); 25 | PROVIDE( _io_end = _io_start + LENGTH(ram) ); 26 | PROVIDE( _stack_size = 1 << 15 ); 27 | 28 | 29 | /* 30 | * The OUTPUT_ARCH command specifies the machine architecture where the 31 | * argument is one of the names used in the Kendryte library. 32 | */ 33 | OUTPUT_ARCH( "riscv" ) 34 | 35 | /* 36 | * The ENTRY command specifies the entry point (ie. first instruction to 37 | * execute). The symbol _start is defined in crt0.S 38 | */ 39 | ENTRY(_start) 40 | 41 | /* 42 | * The GROUP command is special since the listed archives will be 43 | * searched repeatedly until there are no new undefined references. We 44 | * need this since -lc depends on -lgloss and -lgloss depends on -lc. I 45 | * thought gcc would automatically include -lgcc when needed, but 46 | * in this file includes it explicitly here and I was seeing link errors 47 | * without it. 48 | */ 49 | /* GROUP( -lc -lgloss -lgcc ) */ 50 | 51 | /* 52 | * The linker only pays attention to the PHDRS command when generating 53 | * an ELF output file. In other cases, the linker will simply ignore PHDRS. 54 | */ 55 | PHDRS 56 | { 57 | ram_ro PT_LOAD; 58 | ram_init PT_LOAD; 59 | ram PT_NULL; 60 | } 61 | 62 | /* 63 | * This is where we specify how the input sections map to output 64 | * sections. 65 | */ 66 | SECTIONS 67 | { 68 | /* Program code segment, also known as a text segment */ 69 | .text : 70 | { 71 | PROVIDE( _text = ABSOLUTE(.) ); 72 | /* Initialization code segment */ 73 | KEEP( *(.text.start) ) 74 | *(.text.unlikely .text.unlikely.*) 75 | *(.text.startup .text.startup.*) 76 | /* Normal code segment */ 77 | *(.text .text.*) 78 | *(.gnu.linkonce.t.*) 79 | 80 | . = ALIGN(8); 81 | PROVIDE( _etext = ABSOLUTE(.) ); 82 | } >ram AT>ram :ram_ro 83 | 84 | /* Read-only data segment */ 85 | .rodata : 86 | { 87 | *(.rdata) 88 | *(.rodata .rodata.*) 89 | *(.gnu.linkonce.r.*) 90 | } >ram AT>ram :ram_ro 91 | 92 | . = ALIGN(8); 93 | 94 | /* Exception handling */ 95 | .eh_frame : 96 | { 97 | KEEP (*(.eh_frame)) *(.eh_frame.*) 98 | . = ALIGN(8); 99 | } >ram AT>ram :ram_ro 100 | .gnu_extab : { *(.gnu_extab) } >ram AT>ram :ram_ro 101 | .gcc_except_table : { *(.gcc_except_table .gcc_except_table.*) } >ram AT>ram :ram_ro 102 | .exception_ranges : { *(.exception_ranges .exception_ranges*) } >ram AT>ram :ram_ro 103 | 104 | /* Init array and fini array */ 105 | .preinit_array : 106 | { 107 | PROVIDE_HIDDEN (__preinit_array_start = .); 108 | KEEP (*(.preinit_array)) 109 | PROVIDE_HIDDEN (__preinit_array_end = .); 110 | } >ram AT>ram :ram_ro 111 | 112 | .init_array : 113 | { 114 | PROVIDE_HIDDEN (__init_array_start = .); 115 | KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) 116 | *(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors) 117 | PROVIDE_HIDDEN (__init_array_end = .); 118 | } >ram AT>ram :ram_ro 119 | 120 | .fini_array : 121 | { 122 | PROVIDE_HIDDEN (__fini_array_start = .); 123 | KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) 124 | KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) 125 | PROVIDE_HIDDEN (__fini_array_end = .); 126 | } >ram AT>ram :ram_ro 127 | 128 | .ctors : 129 | { 130 | /* gcc uses crtbegin.o to find the start of 131 | the constructors, so we make sure it is 132 | first. Because this is a wildcard, it 133 | doesn't matter if the user does not 134 | actually link against crtbegin.o; the 135 | linker won't look for a file to match a 136 | wildcard. The wildcard also means that it 137 | doesn't matter which directory crtbegin.o 138 | is in. */ 139 | KEEP (*crtbegin.o(.ctors)) 140 | KEEP (*crtbegin?.o(.ctors)) 141 | /* We don't want to include the .ctor section from 142 | the crtend.o file until after the sorted ctors. 143 | The .ctor section from the crtend file contains the 144 | end of ctors marker and it must be last */ 145 | KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) 146 | KEEP (*(SORT(.ctors.*))) 147 | KEEP (*(.ctors)) 148 | } >ram AT>ram :ram_ro 149 | 150 | .dtors : 151 | { 152 | KEEP (*crtbegin.o(.dtors)) 153 | KEEP (*crtbegin?.o(.dtors)) 154 | KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) 155 | KEEP (*(SORT(.dtors.*))) 156 | KEEP (*(.dtors)) 157 | } >ram AT>ram :ram_ro 158 | 159 | . = ALIGN(8); 160 | 161 | .lalign : 162 | { 163 | . = ALIGN(8); 164 | PROVIDE( _data_lma = . ); 165 | } >ram AT>ram :ram_ro 166 | 167 | .dalign : 168 | { 169 | . = ALIGN(8); 170 | PROVIDE( _data = . ); 171 | } >ram AT>ram :ram_init 172 | 173 | . = ALIGN(8); 174 | 175 | /* .data, .sdata and .srodata segment */ 176 | .data : 177 | { 178 | /* Writable data segment (.data segment) */ 179 | *(.data .data.*) 180 | *(.gnu.linkonce.d.*) 181 | /* Have _gp point to middle of sdata/sbss to maximize displacement range */ 182 | . = ALIGN(8); 183 | PROVIDE( __global_pointer$ = ABSOLUTE(.) + 0x800); 184 | /* Writable small data segment (.sdata segment) */ 185 | *(.sdata .sdata.*) 186 | *(.gnu.linkonce.s.*) 187 | /* Read-only small data segment (.srodata segment) */ 188 | . = ALIGN(8); 189 | *(.srodata.cst16) 190 | *(.srodata.cst8) 191 | *(.srodata.cst4) 192 | *(.srodata.cst2) 193 | *(.srodata .srodata.*) 194 | /* Align _edata to cache line size */ 195 | . = ALIGN(64); 196 | PROVIDE( _edata = ABSOLUTE(.) ); 197 | } >ram AT>ram :ram_init 198 | 199 | /* .bss and .sbss segment */ 200 | .bss : 201 | { 202 | PROVIDE( _bss = ABSOLUTE(.) ); 203 | /* Writable uninitialized small data segment (.sbss segment)*/ 204 | *(.sbss .sbss.*) 205 | *(.gnu.linkonce.sb.*) 206 | *(.scommon) 207 | /* Uninitialized writeable data section (.bss segment)*/ 208 | *(.bss .bss.*) 209 | *(.gnu.linkonce.b.*) 210 | *(COMMON) 211 | 212 | . = ALIGN(8); 213 | PROVIDE( _ebss = ABSOLUTE(.) ); 214 | } >ram AT>ram :ram 215 | 216 | PROVIDE( _tls_data = ABSOLUTE(.) ); 217 | /* 218 | * Thread Local Storage (TLS) are per-thread global variables. 219 | * Compilers such as GCC provide a __thread keyword to mark global 220 | * variables as per-thread. Support is required in the program loader 221 | * and thread creator. 222 | */ 223 | 224 | /* Thread-local data segment, .tdata (initialized tls). */ 225 | .tdata : 226 | { 227 | KEEP( *(.tdata.begin) ) 228 | *(.tdata .tdata.*) 229 | *(.gnu.linkonce.td.*) 230 | KEEP( *(.tdata.end) ) 231 | } >ram AT>ram :ram 232 | 233 | /* Thread-local bss segment, .tbss (zero-initialized tls). */ 234 | .tbss : 235 | { 236 | *(.tbss .tbss.*) 237 | *(.gnu.linkonce.tb.*) 238 | KEEP( *(.tbss.end) ) 239 | } >ram AT>ram :ram 240 | 241 | /* 242 | * End of uninitalized data segement 243 | * 244 | * Actually the stack needs 16B alignment, and it won't hurt to also slightly 245 | * increase the alignment to 32 or even 64 (cache line size). 246 | * 247 | * Align _heap_start to cache line size 248 | */ 249 | . = ALIGN(64); 250 | PROVIDE( _end = ABSOLUTE(.) ); 251 | /* Leave 2 holes for stack & TLS, the size can set in kconfig */ 252 | PROVIDE( _heap_start = ABSOLUTE(.) + _stack_size * 2 ); 253 | PROVIDE( _tp0 = (_end + 63) & (-64) ); 254 | PROVIDE( _tp1 = _tp0 + _stack_size ); 255 | PROVIDE( _sp0 = _tp0 + _stack_size ); 256 | PROVIDE( _sp1 = _tp1 + _stack_size ); 257 | 258 | /* Heap end is at the end of memory, the memory size can set in kconfig */ 259 | PROVIDE( _heap_end = _ram_end ); 260 | } 261 | 262 | -------------------------------------------------------------------------------- /projects/dvp2sdcard/compile/priority.conf: -------------------------------------------------------------------------------- 1 | # component register priority 2 | # The upper components have higher priority 3 | # comments start with `#` 4 | 5 | 6 | kendryte_sdk 7 | main 8 | 9 | -------------------------------------------------------------------------------- /projects/dvp2sdcard/config_defaults.mk: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | CONFIG_KENDRYTE_SDK_ENABLE=y 5 | CONFIG_SDK_LOG_LEVEL=5 6 | 7 | -------------------------------------------------------------------------------- /projects/dvp2sdcard/download2board.sh: -------------------------------------------------------------------------------- 1 | python project.py -B dan -p /dev/ttyUSB0 -b 2000000 -t -S flash -------------------------------------------------------------------------------- /projects/dvp2sdcard/main/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ############### Add include ################### 2 | list(APPEND ADD_INCLUDE "include" 3 | ) 4 | # list(APPEND ADD_PRIVATE_INCLUDE "") 5 | ############################################### 6 | 7 | ############ Add source files ################# 8 | # list(APPEND ADD_SRCS "src/main.c") 9 | append_srcs_dir(ADD_SRCS "src") 10 | 11 | # aux_source_directory(src ADD_SRCS) 12 | # list(REMOVE_ITEM COMPONENT_SRCS "src/test2.c") 13 | ############################################### 14 | 15 | ###### Add required/dependent components ###### 16 | list(APPEND ADD_REQUIREMENTS kendryte_sdk drivers utils) 17 | ############################################### 18 | 19 | ############ Add static libs ################## 20 | # list(APPEND ADD_STATIC_LIB "lib/libtest.a") 21 | ############################################### 22 | 23 | 24 | register_component() 25 | -------------------------------------------------------------------------------- /projects/dvp2sdcard/main/Kconfig: -------------------------------------------------------------------------------- 1 | menu "Application configuration" 2 | 3 | menu "Board Type Select" 4 | 5 | choice BBOARD_TYPE 6 | bool "board type" 7 | default MAIX_DOCK 8 | 9 | config MAIX_DOCK 10 | bool "default DOCK board" 11 | 12 | config SELF_DEFINE 13 | bool "client 1 board" 14 | endchoice 15 | 16 | endmenu 17 | 18 | 19 | menu "Drivers configuration" 20 | # camera 21 | osource "${SDK_PATH}/components/drivers/camera/Kconfig" 22 | 23 | # lcd 24 | osource "${SDK_PATH}/components/drivers/lcd/Kconfig" 25 | 26 | #flash 27 | osource "${SDK_PATH}/components/drivers/flash/Kconfig" 28 | 29 | # sd_card 30 | osource "${SDK_PATH}/components/drivers/sd_card/Kconfig" 31 | 32 | endmenu 33 | 34 | menu "IMAGE FORMAT setting" 35 | comment "SAVE IMAGE TO sd_card BY PRESS KEY" 36 | config KEY_SAVE 37 | bool "enable key save" 38 | default n 39 | select ENABLE_SD_CARD 40 | 41 | config KEY_BTN_NUM 42 | depends on KEY_SAVE 43 | int "key button number" 44 | default 16 45 | config KEY_BTN_NUM_GPIOHS 46 | depends on KEY_SAVE 47 | int "gpiohs key button number" 48 | default 0 49 | 50 | config IMAGE_SUFFIX 51 | depends on KEY_SAVE 52 | string "image suffix to save, jpg or bmp" 53 | default bmp 54 | config JPEG_BUF_LEN 55 | depends on IMAGE_SUFFIX="jpg" 56 | int "JPEG image size(KB) buffer" 57 | default 30 58 | config JPEG_COMPRESS_QUALITY 59 | int "JPEG compress quality" 60 | default 90 61 | endmenu 62 | 63 | menu "READ IMAGE" 64 | comment "READ IMAGE FROM SDCARD" 65 | config READ_IMG_SDCARD 66 | bool "read jpg from sd_card" 67 | default n 68 | select ENABLE_JPEG_DECODE 69 | 70 | endmenu 71 | 72 | endmenu 73 | 74 | -------------------------------------------------------------------------------- /projects/dvp2sdcard/main/include/image_process.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2018 Canaan Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | #ifndef _IMAGE_PROCESS_H 16 | #define _IMAGE_PROCESS_H 17 | 18 | #include 19 | 20 | typedef struct 21 | { 22 | uint8_t *addr; 23 | uint16_t width; 24 | uint16_t height; 25 | uint16_t pixel; 26 | uint16_t format; 27 | } image_t; 28 | 29 | 30 | int image_init(image_t *image); 31 | void image_deinit(image_t *image); 32 | void image_resize(image_t *image_src, image_t *image_dst); 33 | int image_crop(image_t *src, image_t *dst, int x, int y, int w, int h, int stride); 34 | 35 | 36 | #endif /* _IMAGE_PROCESS_H */ 37 | -------------------------------------------------------------------------------- /projects/dvp2sdcard/main/include/sd_image.h: -------------------------------------------------------------------------------- 1 | #ifndef __SD_IMAGE_H 2 | #define __SD_IMAGE_H 3 | 4 | #include 5 | #include "global_config.h" 6 | 7 | #if CONFIG_ENABLE_SD_CARD 8 | 9 | #include "ff.h" 10 | #include "sdcard.h" 11 | #if CONFIG_KEY_SAVE 12 | #include "gpiohs.h" 13 | #include "rgb2bmp.h" 14 | #include "picojpeg.h" 15 | #include "picojpeg_util.h" 16 | #endif 17 | int sdcard_init(void); 18 | int fs_init(void); 19 | FRESULT sd_read_img(TCHAR *path, uint8_t *src_img, int len); 20 | int save_jpeg_sdcard(uint8_t *image_addr, const char *filename, int img_quality); 21 | #endif 22 | 23 | #endif -------------------------------------------------------------------------------- /projects/dvp2sdcard/main/src/image_process.c: -------------------------------------------------------------------------------- 1 | /* Copyright 2018 Canaan Inc. 2 | * 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | */ 15 | 16 | #include 17 | #include "image_process.h" 18 | #include "iomem.h" 19 | int min(int a, int b){return aaddr = calloc(image->width * image->height * image->pixel, 1); 26 | // if (image->addr == NULL) 27 | // return -1; 28 | // return 0; 29 | // } 30 | 31 | // void image_deinit(image_t *image) 32 | // { 33 | // free(image->addr); 34 | // } 35 | 36 | int image_init(image_t *image) 37 | { 38 | image->addr = iomem_malloc(image->width * image->height * image->pixel); 39 | if (image->addr == NULL) 40 | return -1; 41 | 42 | return 0; 43 | } 44 | 45 | void image_deinit(image_t *image) 46 | { 47 | iomem_free(image->addr); 48 | } 49 | 50 | int image_crop(image_t *src, image_t *dst, int x, int y, int w, int h, int stride){ 51 | int wh_dst = dst->width * dst->height; 52 | int wh_src = src->width * src->height; 53 | int channel = min(src->pixel, dst->pixel); 54 | if(channel==2){ 55 | for(int j=y, dst_j=0; dst_jaddr)[dst_j * dst->width + dst_i] = ((uint16_t*)src->addr)[j * src->width + i]; 58 | return 0; 59 | } 60 | for(int c=0; c < channel; c++) 61 | for(int j=y, dst_j=0; dst_jaddr[c * wh_dst + dst_j * dst->width + dst_i] = src->addr[c * wh_src + j * src->width + i]; 64 | return 0; 65 | } 66 | 67 | void image_resize(image_t *image_src, image_t *image_dst) 68 | { 69 | uint16_t x1, x2, y1, y2; 70 | float w_scale, h_scale; 71 | float temp1, temp2; 72 | float x_src, y_src; 73 | 74 | uint8_t *r_src, *g_src, *b_src, *r_dst, *g_dst, *b_dst; 75 | uint16_t w_src, h_src, w_dst, h_dst; 76 | 77 | w_src = image_src->width; 78 | h_src = image_src->height; 79 | r_src = image_src->addr; 80 | g_src = r_src + w_src * h_src; 81 | b_src = g_src + w_src * h_src; 82 | w_dst = image_dst->width; 83 | h_dst = image_dst->height; 84 | r_dst = image_dst->addr; 85 | g_dst = r_dst + w_dst * h_dst; 86 | b_dst = g_dst + w_dst * h_dst; 87 | 88 | w_scale = (float)w_src / w_dst; 89 | h_scale = (float)h_src / h_dst; 90 | 91 | for (uint16_t y = 0; y < h_dst; y++) 92 | { 93 | for (uint16_t x = 0; x < w_dst; x++) 94 | { 95 | x_src = (x + 0.5f) * w_scale - 0.5f; 96 | x1 = (uint16_t)x_src; 97 | x2 = x1 + 1; 98 | y_src = (y + 0.5f) * h_scale - 0.5f; 99 | y1 = (uint16_t)y_src; 100 | y2 = y1 + 1; 101 | 102 | if (x2 >= w_src || y2 >= h_src) 103 | { 104 | *(r_dst + x + y * w_dst) = *(r_src + x1 + y1 * w_src); 105 | *(g_dst + x + y * w_dst) = *(g_src + x1 + y1 * w_src); 106 | *(b_dst + x + y * w_dst) = *(b_src + x1 + y1 * w_src); 107 | continue; 108 | } 109 | 110 | temp1 = (x2 - x_src) * *(r_src + x1 + y1 * w_src) + (x_src - x1) * *(r_src + x2 + y1 * w_src); 111 | temp2 = (x2 - x_src) * *(r_src + x1 + y2 * w_src) + (x_src - x1) * *(r_src + x2 + y2 * w_src); 112 | *(r_dst + x + y * w_dst) = (uint8_t)((y2 - y_src) * temp1 + (y_src - y1) * temp2); 113 | temp1 = (x2 - x_src) * *(g_src + x1 + y1 * w_src) + (x_src - x1) * *(g_src + x2 + y1 * w_src); 114 | temp2 = (x2 - x_src) * *(g_src + x1 + y2 * w_src) + (x_src - x1) * *(g_src + x2 + y2 * w_src); 115 | *(g_dst + x + y * w_dst) = (uint8_t)((y2 - y_src) * temp1 + (y_src - y1) * temp2); 116 | temp1 = (x2 - x_src) * *(b_src + x1 + y1 * w_src) + (x_src - x1) * *(b_src + x2 + y1 * w_src); 117 | temp2 = (x2 - x_src) * *(b_src + x1 + y2 * w_src) + (x_src - x1) * *(b_src + x2 + y2 * w_src); 118 | *(b_dst + x + y * w_dst) = (uint8_t)((y2 - y_src) * temp1 + (y_src - y1) * temp2); 119 | } 120 | } 121 | } -------------------------------------------------------------------------------- /projects/dvp2sdcard/main/src/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "unistd.h" 5 | #include "sysctl.h" 6 | #include "global_config.h" 7 | #include "sleep.h" 8 | #include "dvp.h" 9 | #include "fpioa.h" 10 | #include "iomem.h" 11 | #include "plic.h" 12 | #include "camera.h" 13 | #include "syslog.h" 14 | 15 | #if CONFIG_ENABLE_LCD 16 | #include "nt35310.h" 17 | #include "lcd.h" 18 | #endif 19 | 20 | #include "image_process.h" 21 | #include "sd_image.h" 22 | 23 | 24 | static const char *TAG = "MAIN"; 25 | static image_t origin_image,kpu_image, display_image; 26 | volatile uint8_t g_dvp_finish_flag; 27 | 28 | #if CONFIG_ENABLE_SD_CARD 29 | static int frame = 0; 30 | volatile uint8_t g_save_flag; 31 | char filename[100]; 32 | 33 | 34 | #if CONFIG_KEY_SAVE 35 | static void irq_key(void *gp) 36 | { 37 | g_save_flag = 1; 38 | } 39 | #endif 40 | #endif 41 | #if CONFIG_ENABLE_LCD 42 | static uint32_t time_ram[8 * 16 * 8 / 2]; 43 | 44 | void rgb888_to_lcd(uint8_t *src, uint16_t *dest, size_t width, size_t height) 45 | { 46 | size_t chn_size = width * height; 47 | for (size_t i = 0; i < width * height; i++) 48 | { 49 | uint8_t r = src[i]; 50 | uint8_t g = src[chn_size + i]; 51 | uint8_t b = src[chn_size * 2 + i]; 52 | 53 | uint16_t rgb = ((r & 0b11111000) << 8) | ((g & 0b11111100) << 3) | (b >> 3); 54 | size_t d_i = i % 2 ? (i - 1) : (i + 1); 55 | dest[d_i] = rgb; 56 | } 57 | } 58 | #endif 59 | 60 | static int on_irq_dvp(void *ctx) 61 | { 62 | if(dvp_get_interrupt(DVP_STS_FRAME_FINISH)) 63 | { 64 | dvp_config_interrupt(DVP_CFG_START_INT_ENABLE | DVP_CFG_FINISH_INT_ENABLE, 0); 65 | dvp_clear_interrupt(DVP_STS_FRAME_FINISH); 66 | g_dvp_finish_flag = 1; 67 | 68 | } else 69 | { 70 | dvp_start_convert(); 71 | dvp_clear_interrupt(DVP_STS_FRAME_START); 72 | } 73 | return 0; 74 | } 75 | 76 | int main(void) 77 | { 78 | /* Set CPU and dvp clk */ 79 | sysctl_pll_set_freq(SYSCTL_PLL0, 800000000UL); 80 | sysctl_pll_set_freq(SYSCTL_PLL1, 400000000UL); 81 | sysctl_clock_enable(SYSCTL_CLOCK_AI); 82 | 83 | plic_init(); 84 | 85 | /* DVP init */ 86 | LOGI(TAG, "DVP init"); 87 | camera_init(); 88 | #if CONFIG_ENABLE_SD_CARD 89 | /* SD card init */ 90 | if (sdcard_init()) 91 | { 92 | LOGE(TAG, "Fail to init SD card"); 93 | return -1; 94 | } 95 | if (fs_init()) 96 | { 97 | LOGE(TAG, "Fail to mount file system,FAT32 err"); 98 | return -1; 99 | } 100 | #if CONFIG_KEY_SAVE 101 | gpiohs_set_drive_mode(CONFIG_KEY_BTN_NUM_GPIOHS, GPIO_DM_INPUT); 102 | gpiohs_set_pin_edge(CONFIG_KEY_BTN_NUM_GPIOHS, GPIO_PE_FALLING); 103 | gpiohs_set_irq(CONFIG_KEY_BTN_NUM_GPIOHS, 2, irq_key); 104 | 105 | FRESULT ret = FR_OK; 106 | char *dir = "SaveImage"; 107 | 108 | ret = f_mkdir(dir); 109 | if (ret == FR_OK) 110 | { 111 | LOGD(TAG, "Mkdir %s ok", dir); 112 | } 113 | else if (ret == FR_EXIST) 114 | { 115 | LOGD(TAG, "Mkdir %s is exist", dir); 116 | } 117 | else 118 | { 119 | LOGE(TAG, "Mkdir %s err [%d]", dir, ret); // if exist 120 | } 121 | 122 | #endif 123 | #endif 124 | 125 | #if CONFIG_ENABLE_LCD 126 | /* LCD init */ 127 | LOGI(TAG, "LCD init"); 128 | lcd_init(); 129 | #if CONFIG_MAIX_DOCK 130 | lcd_set_direction(DIR_YX_RLDU); 131 | #else 132 | lcd_set_direction(DIR_YX_RLUD); 133 | #endif 134 | 135 | lcd_clear(BLACK); 136 | #endif 137 | 138 | #if CONFIG_READ_IMG_SDCARD 139 | LOGI(TAG, "begin to read jpeg"); 140 | uint64_t tm = sysctl_get_time_us(); 141 | uint8_t *img = (uint8_t *)malloc(30000); 142 | sd_read_img("0:SaveImage/0.jpg", img, 30000); 143 | jpeg_decode_image_t *jpeg = pico_jpeg_decode(NULL, img, 30000, 1); 144 | jpeg_display(0, 0, jpeg); 145 | // convert_jpeg_img_order(jpeg); 146 | // lcd_draw_picture(0, 0, 320, 240, (uint32_t *)jpeg->img_data); 147 | LOGD(TAG, "decode use time %ld ms", (sysctl_get_time_us() - tm) / 1000); 148 | msleep(2000); 149 | free(jpeg->img_data); 150 | free(jpeg); 151 | free(img); 152 | #endif 153 | kpu_image.pixel = 3; 154 | kpu_image.width = 320; 155 | kpu_image.height = 240; 156 | image_init(&kpu_image); 157 | display_image.pixel = 2; 158 | display_image.width = 320; 159 | display_image.height = 240; 160 | image_init(&display_image); 161 | 162 | dvp_set_ai_addr((uint32_t)kpu_image.addr, (uint32_t)(kpu_image.addr + 320 * 240), 163 | (uint32_t)(kpu_image.addr + 320 * 240 * 2)); 164 | dvp_set_display_addr((uint32_t)display_image.addr); 165 | dvp_config_interrupt(DVP_CFG_START_INT_ENABLE | DVP_CFG_FINISH_INT_ENABLE, 0); 166 | dvp_disable_auto(); 167 | 168 | /* DVP interrupt config */ 169 | LOGD(TAG, "DVP interrupt config"); 170 | plic_set_priority(IRQN_DVP_INTERRUPT, 1); 171 | plic_irq_register(IRQN_DVP_INTERRUPT, on_irq_dvp, NULL); 172 | plic_irq_enable(IRQN_DVP_INTERRUPT); 173 | 174 | /* enable global interrupt */ 175 | sysctl_enable_irq(); 176 | 177 | /* system start */ 178 | LOGI(TAG, "System start"); 179 | uint64_t time_last = sysctl_get_time_us(); 180 | uint64_t time_now = sysctl_get_time_us(); 181 | char buf[10]; 182 | 183 | while (1) 184 | { 185 | /* ai cal finish*/ 186 | g_dvp_finish_flag = 0; 187 | dvp_clear_interrupt(DVP_STS_FRAME_START | DVP_STS_FRAME_FINISH); 188 | dvp_config_interrupt(DVP_CFG_START_INT_ENABLE | DVP_CFG_FINISH_INT_ENABLE, 1); 189 | 190 | while(g_dvp_finish_flag == 0) 191 | { 192 | }; 193 | #if CONFIG_ENABLE_LCD 194 | /* display pic*/ 195 | lcd_draw_picture(0, 0, 320, 240, (uint32_t *)display_image.addr); 196 | #if CONFIG_KEY_SAVE 197 | 198 | if(g_save_flag && strcmp(CONFIG_IMAGE_SUFFIX, "bmp") == 0) 199 | { 200 | sprintf(filename, "0:SaveImage/%d.bmp", frame++); 201 | rgb565tobmp(display_image.addr, 320, 240, filename); 202 | LOGD(TAG, "save image [%s].", filename); 203 | lcd_ram_draw_string(filename, time_ram, BLACK, WHITE); 204 | lcd_draw_picture(0, 20, strlen(filename) * 8, 16, time_ram); 205 | g_save_flag = 0; 206 | } 207 | 208 | if(g_save_flag && strcmp(CONFIG_IMAGE_SUFFIX, "jpg") == 0) 209 | { 210 | sprintf(filename, "0:SaveImage/%d.jpg", frame++); 211 | if(!save_jpeg_sdcard(display_image.addr, filename, CONFIG_JPEG_COMPRESS_QUALITY)) 212 | { 213 | frame--; 214 | sprintf(filename, "%s", "save failed"); 215 | } 216 | 217 | lcd_ram_draw_string(filename, time_ram, BLACK, WHITE); 218 | lcd_draw_picture(0, 20, strlen(filename) * 8, 16, time_ram); 219 | g_save_flag = 0; 220 | } 221 | 222 | #endif 223 | time_last = sysctl_get_time_us(); 224 | float fps = 1e6 / (time_last - time_now); 225 | sprintf(buf, "%0.2ffps", fps); 226 | time_now = time_last; 227 | 228 | lcd_ram_draw_string(buf, time_ram, BLACK, WHITE); 229 | lcd_draw_picture(0, 0, strlen(buf) * 8, 16, time_ram); 230 | #endif 231 | } 232 | image_deinit(&display_image); 233 | image_deinit(&kpu_image); 234 | return 0; 235 | } 236 | -------------------------------------------------------------------------------- /projects/dvp2sdcard/main/src/sd_image.c: -------------------------------------------------------------------------------- 1 | #include "sd_image.h" 2 | #include "syslog.h" 3 | #include "fpioa.h" 4 | #include "sysctl.h" 5 | #include "lcd.h" 6 | #include "nt35310.h" 7 | #include "jpeg_encode.h" 8 | #include "picojpeg_util.h" 9 | 10 | static const char *TAG = "SD_IMAGE"; 11 | 12 | 13 | #if CONFIG_ENABLE_JPEG_ENCODE 14 | static uint8_t jpeg_buf[CONFIG_JPEG_BUF_LEN * 1024]; 15 | static jpeg_encode_t jpeg_src, jpeg_out; 16 | #endif 17 | 18 | #define SWAP_16(x) ((x >> 8 & 0xff) | (x << 8)) 19 | 20 | void jpeg_display(uint16_t startx, uint16_t starty, jpeg_decode_image_t *jpeg) 21 | { 22 | uint16_t t[2]; 23 | uint16_t *ptr = jpeg->img_data; 24 | uint16_t *p = ptr; 25 | 26 | lcd_set_area(startx, starty, startx + jpeg->width - 1, starty + jpeg->height - 1); 27 | 28 | for (uint32_t i = 0; i < (jpeg->width * jpeg->height); i += 2) 29 | { 30 | t[0] = *(ptr + 1); 31 | t[1] = *(ptr); 32 | *(ptr) = SWAP_16(t[0]); 33 | *(ptr + 1) = SWAP_16(t[1]); 34 | ptr += 2; 35 | } 36 | 37 | tft_write_word(p, (jpeg->width * jpeg->height / 2), 0); 38 | } 39 | #if CONFIG_ENABLE_SD_CARD 40 | int sdcard_init(void) 41 | { 42 | uint8_t status; 43 | 44 | fpioa_set_function(CONFIG_PIN_NUM_SD_CARD_SCLK, FUNC_SPI1_SCLK); 45 | fpioa_set_function(CONFIG_PIN_NUM_SD_CARD_MOSI, FUNC_SPI1_D0); 46 | fpioa_set_function(CONFIG_PIN_NUM_SD_CARD_MISO, FUNC_SPI1_D1); 47 | fpioa_set_function(CONFIG_PIN_NUM_SD_CARD_CS, FUNC_GPIOHS7); 48 | 49 | LOGI(TAG, "/******************sdcard test*****************/"); 50 | status = sd_init(); 51 | LOGD(TAG, "sd init %d", status); 52 | if (status != 0) 53 | { 54 | return status; 55 | } 56 | 57 | LOGD(TAG, "card info status %d", status); 58 | LOGD(TAG, "CardCapacity:%ld", cardinfo.CardCapacity); 59 | LOGD(TAG, "CardBlockSize:%d", cardinfo.CardBlockSize); 60 | return 0; 61 | } 62 | 63 | int fs_init(void) 64 | { 65 | static FATFS sdcard_fs; 66 | FRESULT status; 67 | DIR dj; 68 | FILINFO fno; 69 | 70 | LOGI(TAG, "/********************fs test*******************/"); 71 | status = f_mount(&sdcard_fs, _T("0:"), 1); 72 | LOGD(TAG, "mount sdcard:%d", status); 73 | if (status != FR_OK) 74 | return status; 75 | 76 | LOGI(TAG, "/----------------printf filename---------------/"); 77 | status = f_findfirst(&dj, &fno, _T("0:"), _T("*")); 78 | while (status == FR_OK && fno.fname[0]) 79 | { 80 | if (fno.fattrib & AM_DIR) 81 | { 82 | 83 | LOGD(TAG, "dir:%s", fno.fname); 84 | } 85 | else 86 | { 87 | LOGD(TAG, "file:%s", fno.fname); 88 | } 89 | status = f_findnext(&dj, &fno); 90 | } 91 | f_closedir(&dj); 92 | LOGI(TAG, "/----------------printf filename---------------/"); 93 | return 0; 94 | } 95 | 96 | #if CONFIG_READ_IMG_SDCARD 97 | FRESULT sd_read_img(TCHAR *path, uint8_t *src_img, int len) 98 | { 99 | FIL file; 100 | FRESULT ret = FR_OK; 101 | uint32_t v_ret_len; 102 | if ((ret = f_open(&file, path, FA_READ)) == FR_OK) 103 | { 104 | ret = f_read(&file, (void *)src_img, len, &v_ret_len); 105 | if (ret != FR_OK) 106 | { 107 | LOGE(TAG, "read file error"); 108 | } 109 | else 110 | { 111 | LOGD(TAG, "read file is %s", src_img); 112 | } 113 | f_close(&file); 114 | } 115 | return ret; 116 | } 117 | #endif 118 | /** 119 | * rgb565 to jpeg 120 | */ 121 | #if CONFIG_ENABLE_JPEG_ENCODE 122 | static int convert_image2jpeg(uint8_t *image, int Quality) 123 | { 124 | 125 | uint64_t v_tim; 126 | v_tim = sysctl_get_time_us(); 127 | 128 | jpeg_src.w = CONFIG_CAMERA_RESOLUTION_WIDTH; 129 | jpeg_src.h = CONFIG_CAMERA_RESOLUTION_HEIGHT; 130 | jpeg_src.bpp = 2; 131 | jpeg_src.data = image; 132 | 133 | jpeg_out.w = jpeg_src.w; 134 | jpeg_out.h = jpeg_src.h; 135 | jpeg_out.bpp = CONFIG_JPEG_BUF_LEN * 1024; 136 | jpeg_out.data = jpeg_buf; 137 | 138 | v_tim = sysctl_get_time_us(); 139 | uint8_t ret = jpeg_compress(&jpeg_src, &jpeg_out, Quality, 0); 140 | if (ret == 0) 141 | { 142 | LOGD(TAG, "jpeg encode use %ld us", sysctl_get_time_us() - v_tim); 143 | LOGD(TAG, "w:%d\th:%d\tbpp:%d", jpeg_out.w, jpeg_out.h, jpeg_out.bpp); 144 | LOGD(TAG, "jpeg encode success!"); 145 | } 146 | else 147 | { 148 | LOGE(TAG, "jpeg encode failed"); 149 | } 150 | 151 | return ret; 152 | } 153 | 154 | int save_jpeg_sdcard(uint8_t *image_addr, const char *filename, int img_quality) 155 | { 156 | FIL file; 157 | FRESULT ret = FR_OK; 158 | uint32_t ret_len = 0; 159 | 160 | if (convert_image2jpeg(image_addr, img_quality) == 0) 161 | { 162 | 163 | if ((ret = f_open(&file, filename, FA_CREATE_ALWAYS | FA_WRITE)) != FR_OK) 164 | { 165 | LOGD(TAG, "create file %s err[%d]", filename, ret); 166 | return ret; 167 | } 168 | 169 | f_write(&file, jpeg_out.data, jpeg_out.bpp, &ret_len); 170 | 171 | f_close(&file); 172 | LOGD(TAG, "Save jpeg image %s", filename); 173 | return 1; 174 | } 175 | else 176 | { 177 | return 0; 178 | } 179 | } 180 | #endif 181 | #endif 182 | -------------------------------------------------------------------------------- /projects/dvp2sdcard/project.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | #-*- coding = utf-8 -*- 3 | 4 | # 5 | # @file from https://github.com/Neutree/c_cpp_project_framework 6 | # @author neucrack 7 | # @license Apache 2.0 8 | # 9 | 10 | import sys, os 11 | 12 | sdk_env_name = "MY_SDK_PATH" 13 | 14 | # get SDK absolute path 15 | sdk_path = os.path.abspath(sys.path[0]+"/../../") 16 | try: 17 | sdk_path = os.environ[sdk_env_name] 18 | except Exception: 19 | pass 20 | print("-- SDK_PATH:{}".format(sdk_path)) 21 | 22 | # execute project script from SDK 23 | project_file_path = sdk_path+"/tools/cmake/project.py" 24 | with open(project_file_path) as f: 25 | exec(f.read()) 26 | 27 | -------------------------------------------------------------------------------- /projects/testproject/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | 3 | build 4 | .config.mk 5 | .flash.conf.json 6 | 7 | -------------------------------------------------------------------------------- /projects/testproject/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.9) 2 | 3 | 4 | # Get SDK path 5 | if(NOT SDK_PATH) 6 | get_filename_component(SDK_PATH ../../ ABSOLUTE) 7 | if(EXISTS $ENV{MY_SDK_PATH}) 8 | set(SDK_PATH $ENV{MY_SDK_PATH}) 9 | endif() 10 | endif() 11 | 12 | # Check SDK Path 13 | if(NOT EXISTS ${SDK_PATH}) 14 | message(FATAL_ERROR "SDK path Error, Please set SDK_PATH or MY_SDK_PATH variable") 15 | endif() 16 | 17 | # Get Toolchain path 18 | if(NOT CONFIG_TOOLCHAIN_PATH) 19 | if(EXISTS $ENV{MY_TOOLCHAIN_PATH}) 20 | set(CONFIG_TOOLCHAIN_PATH $ENV{MY_TOOLCHAIN_PATH}) 21 | endif() 22 | endif() 23 | 24 | ## Add preprocessor definitions for whole project 25 | # add_definitions(-DAAAAA=1) 26 | 27 | # Call compile 28 | include(${SDK_PATH}/tools/cmake/compile.cmake) 29 | 30 | 31 | # Project Name 32 | project(testproject) 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /projects/testproject/compile/compile_flags.cmake: -------------------------------------------------------------------------------- 1 | 2 | ########## set C flags ######### 3 | set(CMAKE_C_FLAGS -mcmodel=medany 4 | -mabi=lp64f 5 | -march=rv64imafc 6 | -fno-common 7 | -ffunction-sections 8 | -fdata-sections 9 | -fstrict-volatile-bitfields 10 | -fno-zero-initialized-in-bss 11 | -ffast-math 12 | -fno-math-errno 13 | -fsingle-precision-constant 14 | -ffloat-store 15 | -std=gnu11 16 | -Os 17 | -Wall 18 | -Werror=all 19 | -Wno-error=unused-function 20 | -Wno-error=unused-but-set-variable 21 | -Wno-error=unused-variable 22 | -Wno-error=deprecated-declarations 23 | -Wno-error=maybe-uninitialized 24 | -Wextra 25 | -Werror=frame-larger-than=32768 26 | -Wno-unused-parameter 27 | -Wno-unused-function 28 | -Wno-implicit-fallthrough 29 | -Wno-sign-compare 30 | -Wno-error=missing-braces 31 | -Wno-old-style-declaration 32 | -Wno-error=pointer-sign 33 | -Wno-pointer-to-int-cast 34 | -Wno-strict-aliasing 35 | -Wno-int-to-pointer-cast 36 | ) 37 | ################################ 38 | 39 | 40 | ###### set CXX(cpp) flags ###### 41 | set(CMAKE_CXX_FLAGS -mcmodel=medany 42 | -mabi=lp64f 43 | -march=rv64imafc 44 | -fno-common 45 | -ffunction-sections 46 | -fdata-sections 47 | -fstrict-volatile-bitfields 48 | -fno-zero-initialized-in-bss 49 | -Os 50 | -std=gnu++17 51 | -Wall 52 | -Wno-error=unused-function 53 | -Wno-error=unused-but-set-variable 54 | -Wno-error=unused-variable 55 | -Wno-error=deprecated-declarations 56 | -Wno-error=maybe-uninitialized 57 | -Wextra 58 | -Werror=frame-larger-than=32768 59 | -Wno-unused-parameter 60 | -Wno-unused-function 61 | -Wno-implicit-fallthrough 62 | -Wno-sign-compare 63 | -Wno-error=missing-braces 64 | -Wno-error=pointer-sign 65 | -Wno-pointer-to-int-cast 66 | -Wno-strict-aliasing 67 | -Wno-int-to-pointer-cast 68 | ) 69 | ################################ 70 | 71 | set(LINK_FLAGS ${LINK_FLAGS} 72 | -static 73 | -Wl,-static 74 | -nostartfiles 75 | -Wl,--gc-sections 76 | -Wl,-EL 77 | -T ${PROJECT_SOURCE_DIR}/compile/kendryte.ld 78 | -Wl,--start-group 79 | -Wl,--whole-archive 80 | kendryte_sdk/libkendryte_sdk.a main/libmain.a 81 | -Wl,--no-whole-archive 82 | -Wl,--end-group 83 | ) 84 | set(CMAKE_C_LINK_FLAGS ${CMAKE_C_LINK_FLAGS} 85 | ${LINK_FLAGS} 86 | ) 87 | set(CMAKE_CXX_LINK_FLAGS ${CMAKE_C_LINK_FLAGS} 88 | ) 89 | # set(CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS} 90 | # ${LINK_FLAGS} 91 | # ) 92 | # set(CMAKE_SHARED_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS} 93 | # ${LINK_FLAGS} 94 | # ) 95 | # set(CMAKE_MODULE_LINKER_FLAGS ${CMAKE_MODULE_LINKER_FLAGS} 96 | # ${LINK_FLAGS} 97 | # ) 98 | 99 | 100 | # Convert list to string 101 | string(REPLACE ";" " " CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") 102 | string(REPLACE ";" " " CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") 103 | string(REPLACE ";" " " LINK_FLAGS "${LINK_FLAGS}") 104 | string(REPLACE ";" " " CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS}") 105 | string(REPLACE ";" " " CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS}") 106 | -------------------------------------------------------------------------------- /projects/testproject/compile/gen_binary.cmake: -------------------------------------------------------------------------------- 1 | 2 | execute_process(COMMAND ${CMAKE_C_COMPILER} -print-file-name=crt0.o OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE CRT0_OBJ) 3 | execute_process(COMMAND ${CMAKE_C_COMPILER} -print-file-name=crtbegin.o OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE CRTBEGIN_OBJ) 4 | execute_process(COMMAND ${CMAKE_C_COMPILER} -print-file-name=crtend.o OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE CRTEND_OBJ) 5 | execute_process(COMMAND ${CMAKE_C_COMPILER} -print-file-name=crti.o OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE CRTI_OBJ) 6 | execute_process(COMMAND ${CMAKE_C_COMPILER} -print-file-name=crtn.o OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE CRTN_OBJ) 7 | 8 | 9 | set(CMAKE_C_LINK_EXECUTABLE " \"${CRTI_OBJ}\" \"${CRTBEGIN_OBJ}\" \"${CRTEND_OBJ}\" \"${CRTN_OBJ}\" -o .elf ") 10 | set(CMAKE_CXX_LINK_EXECUTABLE " \"${CRTI_OBJ}\" \"${CRTBEGIN_OBJ}\" \"${CRTEND_OBJ}\" \"${CRTN_OBJ}\" -o .elf ") 11 | 12 | 13 | # Config toolchain 14 | if(CONFIG_TOOLCHAIN_PATH) 15 | set(CMAKE_SIZE "${CONFIG_TOOLCHAIN_PATH}/${CONFIG_TOOLCHAIN_PREFIX}size${EXT}") 16 | set(CMAKE_OBJDUMP "${CONFIG_TOOLCHAIN_PATH}/${CONFIG_TOOLCHAIN_PREFIX}objdump${EXT}") 17 | else() 18 | set(CMAKE_SIZE "size${EXT}") 19 | set(CMAKE_SIZE "objdump${EXT}") 20 | endif() 21 | 22 | add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD 23 | COMMAND ${CMAKE_OBJCOPY} --output-format=binary ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.elf ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.bin 24 | COMMENT "-- Generating .bin firmware at ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.bin" 25 | ) 26 | 27 | add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD 28 | COMMAND ${CMAKE_SIZE} ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.elf 29 | COMMENT "============= firmware =============" 30 | ) 31 | 32 | add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD 33 | COMMAND ${CMAKE_OBJDUMP} -S ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.elf > ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.txt 34 | ) 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /projects/testproject/compile/kendryte.ld: -------------------------------------------------------------------------------- 1 | /* 2 | * The MEMORY command describes the location and size of blocks of memory 3 | * in the target. You can use it to describe which memory regions may be 4 | * used by the linker, and which memory regions it must avoid. 5 | */ 6 | MEMORY 7 | { 8 | /* 9 | * Memory with CPU cache. 10 | *6M CPU SRAM 11 | */ 12 | ram (wxa!ri) : ORIGIN = 0x80000000, LENGTH = (6 * 1024 * 1024) 13 | /* 14 | * Memory without CPU cache 15 | * 6M CPU SRAM 16 | */ 17 | ram_nocache (wxa!ri) : ORIGIN = 0x40000000, LENGTH = (6 * 1024 * 1024) 18 | } 19 | 20 | PROVIDE( _rom_start = ORIGIN(rom) ); 21 | PROVIDE( _rom_end = ORIGIN(rom) + LENGTH(rom) ); 22 | PROVIDE( _ram_start = ORIGIN(ram) ); 23 | PROVIDE( _ram_end = ORIGIN(ram) + LENGTH(ram) ); 24 | PROVIDE( _io_start = 0x40000000 ); 25 | PROVIDE( _io_end = _io_start + LENGTH(ram) ); 26 | PROVIDE( _stack_size = 1 << 15 ); 27 | 28 | 29 | /* 30 | * The OUTPUT_ARCH command specifies the machine architecture where the 31 | * argument is one of the names used in the Kendryte library. 32 | */ 33 | OUTPUT_ARCH( "riscv" ) 34 | 35 | /* 36 | * The ENTRY command specifies the entry point (ie. first instruction to 37 | * execute). The symbol _start is defined in crt0.S 38 | */ 39 | ENTRY(_start) 40 | 41 | /* 42 | * The GROUP command is special since the listed archives will be 43 | * searched repeatedly until there are no new undefined references. We 44 | * need this since -lc depends on -lgloss and -lgloss depends on -lc. I 45 | * thought gcc would automatically include -lgcc when needed, but 46 | * in this file includes it explicitly here and I was seeing link errors 47 | * without it. 48 | */ 49 | /* GROUP( -lc -lgloss -lgcc ) */ 50 | 51 | /* 52 | * The linker only pays attention to the PHDRS command when generating 53 | * an ELF output file. In other cases, the linker will simply ignore PHDRS. 54 | */ 55 | PHDRS 56 | { 57 | ram_ro PT_LOAD; 58 | ram_init PT_LOAD; 59 | ram PT_NULL; 60 | } 61 | 62 | /* 63 | * This is where we specify how the input sections map to output 64 | * sections. 65 | */ 66 | SECTIONS 67 | { 68 | /* Program code segment, also known as a text segment */ 69 | .text : 70 | { 71 | PROVIDE( _text = ABSOLUTE(.) ); 72 | /* Initialization code segment */ 73 | KEEP( *(.text.start) ) 74 | *(.text.unlikely .text.unlikely.*) 75 | *(.text.startup .text.startup.*) 76 | /* Normal code segment */ 77 | *(.text .text.*) 78 | *(.gnu.linkonce.t.*) 79 | 80 | . = ALIGN(8); 81 | PROVIDE( _etext = ABSOLUTE(.) ); 82 | } >ram AT>ram :ram_ro 83 | 84 | /* Read-only data segment */ 85 | .rodata : 86 | { 87 | *(.rdata) 88 | *(.rodata .rodata.*) 89 | *(.gnu.linkonce.r.*) 90 | } >ram AT>ram :ram_ro 91 | 92 | . = ALIGN(8); 93 | 94 | /* Exception handling */ 95 | .eh_frame : 96 | { 97 | KEEP (*(.eh_frame)) *(.eh_frame.*) 98 | . = ALIGN(8); 99 | } >ram AT>ram :ram_ro 100 | .gnu_extab : { *(.gnu_extab) } >ram AT>ram :ram_ro 101 | .gcc_except_table : { *(.gcc_except_table .gcc_except_table.*) } >ram AT>ram :ram_ro 102 | .exception_ranges : { *(.exception_ranges .exception_ranges*) } >ram AT>ram :ram_ro 103 | 104 | /* Init array and fini array */ 105 | .preinit_array : 106 | { 107 | PROVIDE_HIDDEN (__preinit_array_start = .); 108 | KEEP (*(.preinit_array)) 109 | PROVIDE_HIDDEN (__preinit_array_end = .); 110 | } >ram AT>ram :ram_ro 111 | 112 | .init_array : 113 | { 114 | PROVIDE_HIDDEN (__init_array_start = .); 115 | KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) 116 | *(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors) 117 | PROVIDE_HIDDEN (__init_array_end = .); 118 | } >ram AT>ram :ram_ro 119 | 120 | .fini_array : 121 | { 122 | PROVIDE_HIDDEN (__fini_array_start = .); 123 | KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) 124 | KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) 125 | PROVIDE_HIDDEN (__fini_array_end = .); 126 | } >ram AT>ram :ram_ro 127 | 128 | .ctors : 129 | { 130 | /* gcc uses crtbegin.o to find the start of 131 | the constructors, so we make sure it is 132 | first. Because this is a wildcard, it 133 | doesn't matter if the user does not 134 | actually link against crtbegin.o; the 135 | linker won't look for a file to match a 136 | wildcard. The wildcard also means that it 137 | doesn't matter which directory crtbegin.o 138 | is in. */ 139 | KEEP (*crtbegin.o(.ctors)) 140 | KEEP (*crtbegin?.o(.ctors)) 141 | /* We don't want to include the .ctor section from 142 | the crtend.o file until after the sorted ctors. 143 | The .ctor section from the crtend file contains the 144 | end of ctors marker and it must be last */ 145 | KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) 146 | KEEP (*(SORT(.ctors.*))) 147 | KEEP (*(.ctors)) 148 | } >ram AT>ram :ram_ro 149 | 150 | .dtors : 151 | { 152 | KEEP (*crtbegin.o(.dtors)) 153 | KEEP (*crtbegin?.o(.dtors)) 154 | KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) 155 | KEEP (*(SORT(.dtors.*))) 156 | KEEP (*(.dtors)) 157 | } >ram AT>ram :ram_ro 158 | 159 | . = ALIGN(8); 160 | 161 | .lalign : 162 | { 163 | . = ALIGN(8); 164 | PROVIDE( _data_lma = . ); 165 | } >ram AT>ram :ram_ro 166 | 167 | .dalign : 168 | { 169 | . = ALIGN(8); 170 | PROVIDE( _data = . ); 171 | } >ram AT>ram :ram_init 172 | 173 | . = ALIGN(8); 174 | 175 | /* .data, .sdata and .srodata segment */ 176 | .data : 177 | { 178 | /* Writable data segment (.data segment) */ 179 | *(.data .data.*) 180 | *(.gnu.linkonce.d.*) 181 | /* Have _gp point to middle of sdata/sbss to maximize displacement range */ 182 | . = ALIGN(8); 183 | PROVIDE( __global_pointer$ = ABSOLUTE(.) + 0x800); 184 | /* Writable small data segment (.sdata segment) */ 185 | *(.sdata .sdata.*) 186 | *(.gnu.linkonce.s.*) 187 | /* Read-only small data segment (.srodata segment) */ 188 | . = ALIGN(8); 189 | *(.srodata.cst16) 190 | *(.srodata.cst8) 191 | *(.srodata.cst4) 192 | *(.srodata.cst2) 193 | *(.srodata .srodata.*) 194 | /* Align _edata to cache line size */ 195 | . = ALIGN(64); 196 | PROVIDE( _edata = ABSOLUTE(.) ); 197 | } >ram AT>ram :ram_init 198 | 199 | /* .bss and .sbss segment */ 200 | .bss : 201 | { 202 | PROVIDE( _bss = ABSOLUTE(.) ); 203 | /* Writable uninitialized small data segment (.sbss segment)*/ 204 | *(.sbss .sbss.*) 205 | *(.gnu.linkonce.sb.*) 206 | *(.scommon) 207 | /* Uninitialized writeable data section (.bss segment)*/ 208 | *(.bss .bss.*) 209 | *(.gnu.linkonce.b.*) 210 | *(COMMON) 211 | 212 | . = ALIGN(8); 213 | PROVIDE( _ebss = ABSOLUTE(.) ); 214 | } >ram AT>ram :ram 215 | 216 | PROVIDE( _tls_data = ABSOLUTE(.) ); 217 | /* 218 | * Thread Local Storage (TLS) are per-thread global variables. 219 | * Compilers such as GCC provide a __thread keyword to mark global 220 | * variables as per-thread. Support is required in the program loader 221 | * and thread creator. 222 | */ 223 | 224 | /* Thread-local data segment, .tdata (initialized tls). */ 225 | .tdata : 226 | { 227 | KEEP( *(.tdata.begin) ) 228 | *(.tdata .tdata.*) 229 | *(.gnu.linkonce.td.*) 230 | KEEP( *(.tdata.end) ) 231 | } >ram AT>ram :ram 232 | 233 | /* Thread-local bss segment, .tbss (zero-initialized tls). */ 234 | .tbss : 235 | { 236 | *(.tbss .tbss.*) 237 | *(.gnu.linkonce.tb.*) 238 | KEEP( *(.tbss.end) ) 239 | } >ram AT>ram :ram 240 | 241 | /* 242 | * End of uninitalized data segement 243 | * 244 | * Actually the stack needs 16B alignment, and it won't hurt to also slightly 245 | * increase the alignment to 32 or even 64 (cache line size). 246 | * 247 | * Align _heap_start to cache line size 248 | */ 249 | . = ALIGN(64); 250 | PROVIDE( _end = ABSOLUTE(.) ); 251 | /* Leave 2 holes for stack & TLS, the size can set in kconfig */ 252 | PROVIDE( _heap_start = ABSOLUTE(.) + _stack_size * 2 ); 253 | PROVIDE( _tp0 = (_end + 63) & (-64) ); 254 | PROVIDE( _tp1 = _tp0 + _stack_size ); 255 | PROVIDE( _sp0 = _tp0 + _stack_size ); 256 | PROVIDE( _sp1 = _tp1 + _stack_size ); 257 | 258 | /* Heap end is at the end of memory, the memory size can set in kconfig */ 259 | PROVIDE( _heap_end = _ram_end ); 260 | } 261 | 262 | -------------------------------------------------------------------------------- /projects/testproject/compile/priority.conf: -------------------------------------------------------------------------------- 1 | # component register priority 2 | # The upper components have higher priority 3 | # comments start with `#` 4 | 5 | 6 | kendryte_sdk 7 | main 8 | 9 | -------------------------------------------------------------------------------- /projects/testproject/config_defaults.mk: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | CONFIG_KENDRYTE_SDK_ENABLE=y 5 | CONFIG_SDK_LOG_LEVEL=5 6 | 7 | -------------------------------------------------------------------------------- /projects/testproject/download2board.sh: -------------------------------------------------------------------------------- 1 | python project.py -B dan -p /dev/ttyUSB1 -b 2000000 -t -S flash -------------------------------------------------------------------------------- /projects/testproject/main/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ############### Add include ################### 2 | #list(APPEND ADD_INCLUDE "include" ) 3 | # list(APPEND ADD_PRIVATE_INCLUDE "") 4 | ############################################### 5 | 6 | ############ Add source files ################# 7 | # list(APPEND ADD_SRCS "src/main.c") 8 | append_srcs_dir(ADD_SRCS "src") 9 | 10 | # aux_source_directory(src ADD_SRCS) 11 | # list(REMOVE_ITEM COMPONENT_SRCS "src/test2.c") 12 | ############################################### 13 | 14 | ###### Add required/dependent components ###### 15 | list(APPEND ADD_REQUIREMENTS kendryte_sdk) 16 | ############################################### 17 | 18 | ############ Add static libs ################## 19 | # list(APPEND ADD_STATIC_LIB "lib/libtest.a") 20 | ############################################### 21 | 22 | 23 | register_component() 24 | -------------------------------------------------------------------------------- /projects/testproject/main/Kconfig: -------------------------------------------------------------------------------- 1 | menu "Application configuration" 2 | 3 | menu "Board Type Select" 4 | 5 | choice BBOARD_TYPE 6 | bool "board type" 7 | default MAIX_DOCK 8 | 9 | config MAIX_DOCK 10 | bool "default DOCK board" 11 | 12 | config SELF_DEFINE 13 | bool "client 1 board" 14 | endchoice 15 | 16 | endmenu 17 | 18 | 19 | 20 | menu "Drivers configuration" 21 | # camera 22 | osource "${SDK_PATH}/components/drivers/camera/Kconfig" 23 | 24 | # lcd 25 | osource "${SDK_PATH}/components/drivers/lcd/Kconfig" 26 | 27 | #flash 28 | osource "${SDK_PATH}/components/drivers/flash/Kconfig" 29 | 30 | # sd_card 31 | osource "${SDK_PATH}/components/drivers/sd_card/Kconfig" 32 | 33 | endmenu 34 | 35 | 36 | endmenu 37 | 38 | -------------------------------------------------------------------------------- /projects/testproject/main/src/main.c: -------------------------------------------------------------------------------- 1 | 2 | #include "stdio.h" 3 | #include "global_config.h" 4 | 5 | int main() 6 | { 7 | printf("hello k210\n"); 8 | printf("version"); 9 | 10 | while(1){} 11 | } 12 | //python project.py -B bit_mic -p /dev/ttyUSB0 -b 1500000 -t -S flash 13 | -------------------------------------------------------------------------------- /projects/testproject/project.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | #-*- coding = utf-8 -*- 3 | 4 | # 5 | # @file from https://github.com/Neutree/c_cpp_project_framework 6 | # @author neucrack 7 | # @license Apache 2.0 8 | # 9 | 10 | import sys, os 11 | 12 | sdk_env_name = "MY_SDK_PATH" 13 | 14 | # get SDK absolute path 15 | sdk_path = os.path.abspath(sys.path[0]+"/../../") 16 | try: 17 | sdk_path = os.environ[sdk_env_name] 18 | except Exception: 19 | pass 20 | print("-- SDK_PATH:{}".format(sdk_path)) 21 | 22 | # execute project script from SDK 23 | project_file_path = sdk_path+"/tools/cmake/project.py" 24 | with open(project_file_path) as f: 25 | exec(f.read()) 26 | 27 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | pyserial==3.4 -------------------------------------------------------------------------------- /tools/cmake/compile_flags.cmake: -------------------------------------------------------------------------------- 1 | 2 | 3 | include(${PROJECT_SOURCE_DIR}/compile/compile_flags.cmake) 4 | 5 | -------------------------------------------------------------------------------- /tools/cmake/gen_binary.cmake: -------------------------------------------------------------------------------- 1 | 2 | include(${PROJECT_PATH}/compile/gen_binary.cmake) 3 | 4 | 5 | -------------------------------------------------------------------------------- /tools/cmake/project.py: -------------------------------------------------------------------------------- 1 | # 2 | # @file from https://github.com/Neutree/c_cpp_project_framework 3 | # @author neucrack 4 | # @license Apache 2.0 5 | # 6 | 7 | 8 | import argparse 9 | import os, sys, time, re, shutil 10 | import subprocess 11 | from multiprocessing import cpu_count 12 | 13 | if not os.path.exists("CMakeLists.txt") or not os.path.exists("main"): 14 | print("please run me at project folder!") 15 | exit(1) 16 | 17 | try: 18 | sdk_path = sdk_path 19 | except Exception: 20 | sdk_path = os.path.abspath("../../") 21 | project_path = sys.path[0] 22 | project_name = "" 23 | project_cmake_path = project_path+"/CMakeLists.txt" 24 | project_cmake_content = "" 25 | with open(project_cmake_path) as f: 26 | project_cmake_content = f.read() 27 | match = re.findall(r"{}(.*){}".format(r"project\(", r"\)"), project_cmake_content, re.MULTILINE|re.DOTALL) 28 | if len(match) != 0: 29 | project_name = match[0] 30 | print(project_name) 31 | if project_name == "": 32 | print("[ERROR] Can not find project name in {}".format(project_cmake_path)) 33 | exit(1) 34 | 35 | 36 | flash_dir = sdk_path+"/tools/flash" 37 | if os.path.exists(flash_dir): 38 | sys.path.insert(1, flash_dir) 39 | from flash import parser as flash_parser 40 | project_parser = argparse.ArgumentParser(description='build tool, e.g. `python project.py build`', prog="project.py", parents=[flash_parser]) 41 | 42 | project_parser.add_argument('--toolchain', 43 | help='toolchain path ( absolute path )', 44 | metavar='PATH', 45 | default="") 46 | 47 | project_parser.add_argument('--toolchain-prefix', 48 | help='toolchain prefix(e.g. mips-elf-', 49 | metavar='PREFIX', 50 | default="") 51 | project_parser.add_argument('--config_file', 52 | help='config file path, e.g. config_defaultd.mk', 53 | metavar='PATH', 54 | default="{}/config_defaults.mk".format(project_path)) 55 | project_parser.add_argument('--verbose', 56 | help='for build command, execute `make VERBOSE=1` to compile', 57 | action="store_true", 58 | default=False) 59 | cmd_help ='''project command''' 60 | project_parser.add_argument("cmd", 61 | help=cmd_help, 62 | choices=["config", "build", "rebuild", "menuconfig", "clean", "distclean", "clean_conf", "flash"] 63 | ) 64 | 65 | project_args = project_parser.parse_args() 66 | 67 | cwd = sys.path[0] 68 | os.chdir(cwd) 69 | 70 | config_filename = ".config.mk" 71 | gen_project_type = "Unix Makefiles" 72 | 73 | 74 | config_content_old = "" 75 | 76 | 77 | if os.path.exists(config_filename): 78 | with open(config_filename) as f: 79 | config_content_old = f.read() 80 | header = "# Generated by config.py, DO NOT edit!\n\n" 81 | config_content = header 82 | update_config = False 83 | if project_args.toolchain.strip() != "": 84 | if not os.path.exists(project_args.toolchain): 85 | print("config toolchain path error:", project_args.toolchain) 86 | exit(1) 87 | update_config = True 88 | project_args.toolchain = project_args.toolchain.strip().replace("\\","/") 89 | config_content += 'CONFIG_TOOLCHAIN_PATH="'+project_args.toolchain+'"\n' 90 | if project_args.toolchain_prefix.strip() != "": 91 | update_config = True 92 | project_args.toolchain_prefix = project_args.toolchain_prefix.strip().replace("\\","/") 93 | config_content += 'CONFIG_TOOLCHAIN_PREFIX="'+project_args.toolchain_prefix+'"\n' 94 | config_content += '\n' 95 | if update_config and config_content != config_content_old: 96 | with open(config_filename, "w") as f: 97 | f.write(config_content) 98 | if os.path.exists("build/config/global_config.mk"): 99 | os.remove("build/config/global_config.mk") 100 | print("generate config file at: {}".format(config_filename)) 101 | 102 | # config 103 | if project_args.cmd == "config": 104 | print("config complete") 105 | # rebuild / build 106 | elif project_args.cmd == "build" or project_args.cmd == "rebuild": 107 | print("build now") 108 | time_start = time.time() 109 | if not os.path.exists("build"): 110 | os.mkdir("build") 111 | os.chdir("build") 112 | if not os.path.exists("Makefile") or project_args.cmd == "rebuild": 113 | config_path = os.path.abspath(project_args.config_file) 114 | if not os.path.exists(config_path): 115 | print("config file path error:{}".format(config_path)) 116 | exit(1) 117 | res = subprocess.call(["cmake", "-G", gen_project_type, "-DDEFAULT_CONFIG_FILE={}".format(config_path), ".."]) 118 | if res != 0: 119 | exit(1) 120 | if project_args.verbose: 121 | res = subprocess.call(["make", "VERBOSE=1"]) 122 | else: 123 | res = subprocess.call(["make", "-j{}".format(cpu_count())]) 124 | if res != 0: 125 | exit(1) 126 | 127 | time_end = time.time() 128 | print("==================================") 129 | print("build end, time last:%.2fs" %(time_end-time_start)) 130 | print("==================================") 131 | # clean 132 | elif project_args.cmd == "clean": 133 | print("clean now") 134 | if os.path.exists("build"): 135 | os.chdir("build") 136 | p =subprocess.Popen(["make", "clean"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 137 | output, err = p.communicate("") 138 | res = p.returncode 139 | if res == 0: 140 | print(output.decode()) 141 | print("clean complete") 142 | # distclean 143 | elif project_args.cmd == "distclean": 144 | print("clean now") 145 | if os.path.exists("build"): 146 | os.chdir("build") 147 | p =subprocess.Popen(["make", "clean"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 148 | output, err = p.communicate("") 149 | res = p.returncode 150 | if res == 0: 151 | print(output.decode()) 152 | os.chdir("..") 153 | shutil.rmtree("build") 154 | print("clean complete") 155 | # menuconfig 156 | elif project_args.cmd == "menuconfig": 157 | time_start = time.time() 158 | if not os.path.exists("build"): 159 | os.mkdir("build") 160 | os.chdir("build") 161 | if not os.path.exists("build/Makefile"): 162 | config_path = os.path.abspath(project_args.config_file) 163 | if not os.path.exists(config_path): 164 | print("config file path error:{}".format(config_path)) 165 | exit(1) 166 | res = subprocess.call(["cmake", "-G", gen_project_type, "-DDEFAULT_CONFIG_FILE={}".format(config_path), ".."]) 167 | if res != 0: 168 | exit(1) 169 | res = subprocess.call(["make", "menuconfig"]) 170 | if res != 0: 171 | exit(1) 172 | # flash 173 | elif project_args.cmd == "flash": 174 | flash_file_path = os.path.abspath(sdk_path+"/tools/flash/flash.py") 175 | with open(flash_file_path) as f: 176 | exec(f.read()) 177 | # clean_conf 178 | elif project_args.cmd == "clean_conf": 179 | print("clean now") 180 | # clean cmake config files 181 | if os.path.exists(config_filename): 182 | os.remove(config_filename) 183 | if os.path.exists("build/config/"): 184 | shutil.rmtree("build/config") 185 | # clean flash config file 186 | flash_file_path = os.path.abspath(sdk_path+"/tools/flash/flash.py") 187 | with open(flash_file_path) as f: 188 | exec(f.read()) 189 | print("clean complete") 190 | else: 191 | print("Error: Unknown command") 192 | exit(1) 193 | 194 | -------------------------------------------------------------------------------- /tools/cmake/sort_components.py: -------------------------------------------------------------------------------- 1 | # 2 | # sort components according to priority.conf file 3 | # 4 | # @file from https://github.com/Neutree/c_cpp_project_framework 5 | # @author neucrack 6 | # @license Apache 2.0 7 | # 8 | # @usage: python sort_components.py priority.conf component_dir1 component_dir2 ... component_dir4 9 | # 10 | 11 | import sys, os 12 | 13 | conf_file = sys.argv[1] 14 | components = sys.argv[2:] 15 | 16 | if not os.path.exists(conf_file): 17 | exit(2) 18 | 19 | try: 20 | conf = "" 21 | f = open(conf_file) 22 | while True: 23 | line = f.readline() 24 | if not line: 25 | break 26 | line = line.strip() 27 | if line.startswith("#") or line == "": 28 | continue 29 | conf += line +" " 30 | f.close() 31 | except Exception as e: 32 | print("[ERROR] "+str(e)) 33 | exit(1) 34 | 35 | components_ordered = conf.split() 36 | dict_order = {} 37 | for i,component in enumerate(components_ordered): 38 | dict_order[component] = i 39 | 40 | final_components = [] 41 | components_not_ordered = [] 42 | for component in components: # all components 43 | name = os.path.basename(component) 44 | if name in dict_order.keys(): # have priority in config file 45 | find_pos = False 46 | if len(final_components) == 0: 47 | find_pos = True 48 | final_components.append(component) 49 | else: 50 | for j,tmp in enumerate(final_components): 51 | tmp_name = os.path.basename(tmp) 52 | if dict_order[name] < dict_order[tmp_name]: 53 | find_pos = True 54 | final_components.insert(j, component) 55 | break 56 | if not find_pos: 57 | final_components.append(component) 58 | else: # no priority in config file 59 | components_not_ordered.append(component) 60 | final_components += components_not_ordered 61 | 62 | for i in final_components: 63 | print(i, end = ";") 64 | 65 | 66 | -------------------------------------------------------------------------------- /tools/cmake/tools.cmake: -------------------------------------------------------------------------------- 1 | 2 | # add prefix for all list members 3 | # uage: prepend(out_var prefix in_var) 4 | function(prepend out prefix) 5 | set(listVar "") 6 | foreach(f ${ARGN}) 7 | list(APPEND listVar "${prefix}${f}") 8 | endforeach(f) 9 | set(${out} "${listVar}" PARENT_SCOPE) 10 | endfunction() 11 | 12 | # convert all members of list to absolute path(relative to CMAKE_CURRENT_SOURCE_DIR) 13 | # usage: abspath(out_var list_var) 14 | function(abspath out) 15 | set(listVar "") 16 | foreach(f ${ARGN}) 17 | list(APPEND listVar "${CMAKE_CURRENT_SOURCE_DIR}/${f}") 18 | endforeach(f) 19 | set(${out} "${listVar}" PARENT_SCOPE) 20 | endfunction() 21 | 22 | 23 | function(append_srcs_dir out_var) 24 | set(listVar ${${out_var}}) 25 | foreach(f ${ARGN}) 26 | aux_source_directory(${f} tmp) 27 | list(APPEND listVar ${tmp}) 28 | endforeach(f) 29 | set(${out_var} "${listVar}" PARENT_SCOPE) 30 | endfunction() 31 | 32 | -------------------------------------------------------------------------------- /tools/flash/flash.py: -------------------------------------------------------------------------------- 1 | # 2 | # @file from https://github.com/Neutree/c_cpp_project_framework 3 | # @author neucrack 4 | # 5 | 6 | from __future__ import print_function 7 | import argparse 8 | import os, sys, time, re, shutil 9 | import subprocess 10 | from multiprocessing import cpu_count 11 | import json 12 | import serial.tools.miniterm 13 | from kfpkg import * 14 | 15 | 16 | parser = argparse.ArgumentParser(add_help=False, prog="flash.py") 17 | 18 | ############################### Add option here ############################# 19 | boards_choices = ["dan", "bit", "bit_mic", "goE", "goD", "maixduino", "kd233", "auto"] 20 | parser.add_argument("-p", "--port", help="[flash] device port", default="") 21 | parser.add_argument("-b", "--baudrate", type=int, help="[flash] baudrate", default=115200) 22 | parser.add_argument("-t", "--terminal", help="[flash] start a terminal after finish (Python miniterm)", default=False, action="store_true") 23 | parser.add_argument("-n", "--noansi", help="[flash] do not use ANSI colors, recommended in Windows CMD", default=False, action="store_true") 24 | parser.add_argument("-s", "--sram", help="[flash] download firmware to SRAM and boot", default=False, action="store_true") 25 | parser.add_argument("-B", "--Board",required=False, type=str, default="auto", help="[flash] select dev board, e.g. -B bit", choices=boards_choices) 26 | parser.add_argument("-S", "--Slow",required=False, help="[flash] slow download mode", default=False, action="store_true") 27 | parser.add_argument("-e", "--erase",required=False, help="[flash] erase", default=False, action="store_true") 28 | dict_arg = {"port":"", 29 | "baudrate": 115200, 30 | "terminal": False, 31 | "noansi": False, 32 | "sram": False, 33 | "Board": "auto", 34 | "Slow": False, 35 | "erase":False 36 | } 37 | dict_arg_not_save = ["sram", "terminal", "Slow"] 38 | 39 | def kflash_py_printCallback(*args, **kwargs): 40 | end = kwargs.pop("end", "\n") 41 | msg = "" 42 | for i in args: 43 | msg += str(i) 44 | msg.replace("\n", " ") 45 | print(msg, end=end) 46 | 47 | def kflash_progress(fileTypeStr, current, total, speedStr): 48 | # print("{}/{}".format(current, total)) 49 | pass 50 | ############################################################################# 51 | 52 | # use project_args created by SDK_PATH/tools/cmake/project.py 53 | 54 | # args = parser.parse_args() 55 | if __name__ == '__main__': 56 | firmware = "" 57 | try: 58 | flash_conf_path = project_path+"/.flash.conf.json" 59 | if project_args.cmd == "clean_conf": 60 | if os.path.exists(flash_conf_path): 61 | os.remove(flash_conf_path) 62 | exit(0) 63 | if project_args.cmd != "flash": 64 | print("call flash.py error") 65 | exit(1) 66 | except Exception: 67 | print("-- call flash.py directly!") 68 | parser.add_argument("firmware", help="firmware file name") 69 | project_parser = parser 70 | project_args = project_parser.parse_args() 71 | project_path = "" 72 | if not os.path.exists(project_args.firmware): 73 | print("firmware not found:{}".format(project_args.firmware)) 74 | exit(1) 75 | firmware = project_args.firmware 76 | sdk_path = "" 77 | 78 | config_old = {} 79 | # load flash config from file 80 | try: 81 | with open(flash_conf_path, "r") as f: 82 | config_old = json.load(f) 83 | except Exception as e: 84 | pass 85 | # update flash config from args 86 | for key in dict_arg.keys(): 87 | dict_arg[key] = getattr(project_args, key) 88 | # check if config update, if do, use new and update config file 89 | config = {} 90 | for key in config_old: 91 | config[key] = config_old[key] 92 | for key in dict_arg.keys(): 93 | if dict_arg[key] != project_parser.get_default(key): # arg valid, update config 94 | config[key] = dict_arg[key] 95 | else: 96 | if not key in config: 97 | config[key] = dict_arg[key] 98 | if config != config_old: 99 | print("-- flash config changed, update at {}".format(flash_conf_path)) 100 | with open(flash_conf_path, "w+") as f: 101 | json.dump(config, f, indent=4) 102 | # mask options that not read from file 103 | for key in config: 104 | if key in dict_arg_not_save: 105 | config[key] = dict_arg[key] 106 | print("-- flash start") 107 | ############## Add flash command here ################ 108 | if project_path != "": 109 | firmware = project_path+"/build/"+project_name+".bin" 110 | prepare_path = project_path+"/tools/flash_prepare.py" 111 | if os.path.exists(prepare_path): 112 | with open(prepare_path) as f: 113 | exec(f.read()) 114 | 115 | if not os.path.exists(firmware): 116 | print("[ERROR] Firmware not found:{}".format(firmware)) 117 | exit(1) 118 | if config["port"] == "": 119 | print("[ERROR] Invalid port:{}, set by -p or --port, e.g. -p /dev/ttyUSB0".format(config["port"])) 120 | exit(1) 121 | print("=============== flash config =============") 122 | print("-- flash port :{}".format( config["port"] )) 123 | print("-- flash baudrate:{}".format( config["baudrate"] )) 124 | print("-- flash board:{}".format( config["Board"] )) 125 | print("-- flash open terminal:{}".format( config["terminal"] )) 126 | print("-- flash download to sram:{}".format( config["sram"] )) 127 | print("-- flash noansi:{}".format( config["noansi"] )) 128 | print("-- flash slow mode:{}".format( config["Slow"] )) 129 | print("-- flash erase mode:{}".format( config["erase"] )) 130 | print("-- flash firmware:{}".format( firmware )) 131 | print("") 132 | print("-- kflash start") 133 | # call kflash to burn firmware 134 | from kflash_py.kflash import KFlash 135 | 136 | kflash = KFlash(print_callback=kflash_py_printCallback) 137 | flash_success = True 138 | err_msg = "" 139 | try: 140 | if config["Board"]=="auto": 141 | kflash.process(terminal=False, dev=config["port"], baudrate=config["baudrate"], \ 142 | sram = config["sram"], file=firmware, callback=kflash_progress, noansi= config["noansi"], \ 143 | terminal_auto_size=True, slow_mode = config["Slow"]) 144 | else: 145 | kflash.process(terminal=False, dev=config["port"], baudrate=config["baudrate"], board=config["Board"], \ 146 | sram = config["sram"], file=firmware, callback=kflash_progress, noansi= config["noansi"], \ 147 | terminal_auto_size=True, slow_mode = config["Slow"]) 148 | except Exception as e: 149 | flash_success = False 150 | err_msg = str(e) 151 | if not flash_success: 152 | print("[ERROR] flash firmware fail:") 153 | print(" "+err_msg) 154 | exit(1) 155 | ###################################################### 156 | print("== flash end ==") 157 | 158 | ###################################################### 159 | # open serial tool 160 | if config["terminal"]: 161 | reset = True 162 | if config["sram"]: 163 | reset = False 164 | sys.argv=[project_path+"/tools/flash/flash.py"] 165 | serial.tools.miniterm.main(default_port=config["port"], default_baudrate=115200, default_dtr=reset, default_rts=reset) 166 | 167 | 168 | ###################################################### 169 | 170 | 171 | -------------------------------------------------------------------------------- /tools/flash/kfpkg.py: -------------------------------------------------------------------------------- 1 | 2 | import json, zipfile, os, tempfile 3 | 4 | class KFPKG(): 5 | def __init__(self): 6 | self.fileInfo = {"version": "0.1.0", "files": []} 7 | self.filePath = {} 8 | self.burnAddr = [] 9 | 10 | def addFile(self, addr, path, prefix=False): 11 | if not os.path.exists(path): 12 | raise ValueError("FilePathError") 13 | if addr in self.burnAddr: 14 | raise ValueError("Burn dddr duplicate"+":0x%06x" %(addr)) 15 | f = {} 16 | f_name = os.path.split(path)[1] 17 | f["address"] = addr 18 | f["bin"] = f_name 19 | f["sha256Prefix"] = prefix 20 | self.fileInfo["files"].append(f) 21 | self.filePath[f_name] = path 22 | self.burnAddr.append(addr) 23 | 24 | def listDumps(self): 25 | kfpkg_json = json.dumps(self.fileInfo, indent=4) 26 | return kfpkg_json 27 | 28 | def listDump(self, path): 29 | with open(path, "w") as f: 30 | f.write(json.dumps(self.fileInfo, indent=4)) 31 | 32 | def listLoads(self, kfpkgJson): 33 | self.fileInfo = json.loads(kfpkgJson) 34 | 35 | def listLload(self, path): 36 | with open(path) as f: 37 | self.fileInfo = json.load(f) 38 | 39 | def save(self, path): 40 | listName = os.path.join(tempfile.gettempdir(), "kflash_gui_tmp_list.json") 41 | self.listDump(listName) 42 | try: 43 | with zipfile.ZipFile(path, "w") as zip: 44 | for name,path in self.filePath.items(): 45 | zip.write(path, arcname=name, compress_type=zipfile.ZIP_DEFLATED) 46 | zip.write(listName, arcname="flash-list.json", compress_type=zipfile.ZIP_DEFLATED) 47 | zip.close() 48 | except Exception as e: 49 | os.remove(listName) 50 | raise e 51 | os.remove(listName) 52 | 53 | -------------------------------------------------------------------------------- /tools/kconfig/genconfig.py: -------------------------------------------------------------------------------- 1 | # 2 | # @file from https://github.com/Neutree/c_cpp_project_framework 3 | # @author neucrack 4 | # 5 | 6 | import argparse 7 | import os, sys 8 | 9 | kconfig_lib_path = sys.path[0]+"/Kconfiglib" 10 | sys.path.append(kconfig_lib_path) 11 | 12 | import kconfiglib 13 | from menuconfig import menuconfig 14 | 15 | 16 | def _cmake_contents(kconfig, header): 17 | chunks = [header] 18 | add = chunks.append 19 | config_vars = [] 20 | for sym in kconfig.unique_defined_syms: 21 | # _write_to_conf is determined when the value is calculated. This 22 | # is a hidden function call due to property magic. 23 | val = sym.str_value 24 | if not sym._write_to_conf: 25 | continue 26 | if sym.orig_type in (kconfiglib.BOOL, kconfiglib.TRISTATE) and val == "n": 27 | val = "" 28 | add("set({}{} \"{}\")\n".format( 29 | kconfig.config_prefix, sym.name, val)) 30 | config_vars.append(str(kconfig.config_prefix+sym.name)) 31 | add("set(CONFIGS_LIST {})\n".format(";".join(config_vars))) 32 | return "".join(chunks) 33 | 34 | 35 | def write_config(kconfig, filename, gui): 36 | print("-- Write makefile config at: " + filename) 37 | if not gui: 38 | kconfig.write_config(filename) 39 | 40 | def write_cmake(kconfig, filename, gui): 41 | print("-- Write cmake config at: " + filename) 42 | cmake_conf_header = "# Generated by c_cpp_project_framework(https://github.com/Neutree/c_cpp_project_framework)\n" 43 | cmake_conf_header += "### DO NOT edit this file!! ###\n\n" 44 | cmake_conf_content = _cmake_contents(kconfig, cmake_conf_header) 45 | # don't change file info if config no change 46 | if os.path.exists(filename): 47 | with open(filename) as f: 48 | if f.read() == cmake_conf_content: 49 | return 50 | f = open(filename, "w") 51 | f.write(cmake_conf_content) 52 | f.close() 53 | 54 | 55 | def write_header(kconfig, filename, gui): 56 | print("-- write c header file at: " + filename) 57 | kconfig.write_autoconf(filename) 58 | 59 | OUTPUT_FORMATS = {"makefile": write_config, 60 | "header": write_header, 61 | "cmake": write_cmake 62 | } 63 | 64 | parser = argparse.ArgumentParser(description='menuconfig tool', prog=os.path.basename(sys.argv[0])) 65 | 66 | parser.add_argument('--kconfig', 67 | help='KConfig file', 68 | default='Kconfig', 69 | metavar='FILENAME', 70 | required=None) 71 | 72 | parser.add_argument('--defaults', 73 | action='append', 74 | default=[], 75 | help='Optional project defaults file. ' 76 | 'Multiple files can be specified using multiple --defaults arguments.', 77 | metavar="FILENAME" 78 | ) 79 | 80 | parser.add_argument('--output', nargs=2, action='append', 81 | help='Write output file (format and output filename)', 82 | metavar=('FORMAT', 'FILENAME'), 83 | default=[]) 84 | 85 | parser.add_argument('--env', 86 | action='append', 87 | default=[], 88 | help='Environment to set when evaluating the config file', 89 | metavar='VAR=VALUE' 90 | ) 91 | 92 | parser.add_argument("--menuconfig", 93 | help="Open menuconfig GUI interface", 94 | choices=["False", "True"], 95 | default="False", 96 | ) 97 | 98 | args = parser.parse_args() 99 | 100 | for env in args.env: 101 | env = env.split("=") 102 | var = env[0] 103 | value = env[1] 104 | os.environ[var] = value 105 | 106 | out_format = {"makefile": ".config"} 107 | for fmt, filename in args.output: 108 | if fmt not in OUTPUT_FORMATS.keys(): 109 | print("Format %s not supported! Known formats:%s" %(fmt, OUTPUT_FORMATS.keys())) 110 | sys.exit(1) 111 | out_format[fmt] = filename 112 | 113 | if out_format["makefile"] != ".config": 114 | os.environ["KCONFIG_CONFIG"] = out_format["makefile"] 115 | 116 | kconfig = kconfiglib.Kconfig(args.kconfig) 117 | 118 | # load config, so if config file exist, the default file may 119 | # not take effect, if want to use default, 120 | # remove the config file in build directory 121 | if not os.path.exists(out_format["makefile"]): 122 | for path in args.defaults: 123 | if not os.path.exists(path): 124 | raise ValueError("Path %s not found!" %(path)) 125 | print("-- Load default:", path) 126 | kconfig.load_config(path, replace=False) 127 | else: 128 | kconfig.load_config() 129 | 130 | if args.menuconfig == "True": 131 | menuconfig(kconfig) 132 | 133 | # write back 134 | for fmt, filename in out_format.items(): 135 | dir = os.path.split(filename)[0] 136 | if not os.path.exists(dir): 137 | os.makedirs(dir) 138 | 139 | for fmt, filename in out_format.items(): 140 | func = OUTPUT_FORMATS[fmt] 141 | func(kconfig, filename, args.menuconfig == "True") 142 | 143 | 144 | --------------------------------------------------------------------------------