├── lissa.ntkdigunit ├── manifest.json ├── project.mk ├── ld ├── main_api.syms ├── userdelfx.ld └── rules.ld ├── LICENSE ├── README.md ├── lissa.cpp ├── tpl └── _unit.c └── Makefile /lissa.ntkdigunit: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/boochow/lissa/HEAD/lissa.ntkdigunit -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "header" : 3 | { 4 | "platform" : "nutekt-digital", 5 | "module" : "delfx", 6 | "api" : "1.1-0", 7 | "dev_id" : 0, 8 | "prg_id" : 0, 9 | "version" : "1.0-0", 10 | "name" : "lisa", 11 | "num_param" : 0 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /project.mk: -------------------------------------------------------------------------------- 1 | # ############################################################################# 2 | # Project Customization 3 | # ############################################################################# 4 | 5 | PROJECT = lissa 6 | 7 | UCSRC = 8 | 9 | UCXXSRC = lissa.cpp 10 | 11 | UINCDIR = 12 | 13 | UDEFS = 14 | 15 | ULIB = 16 | 17 | ULIBDIR = 18 | -------------------------------------------------------------------------------- /ld/main_api.syms: -------------------------------------------------------------------------------- 1 | 2 | k_fx_api_version = 0x0807b000; 3 | k_fx_api_platform = 0x0807b004; 4 | sqrtm2log_lut_f = 0x0807b100; 5 | tanpi_lut_f = 0x0807b504; 6 | log_lut_f = 0x0807b908; 7 | bitres_lut_f = 0x0807bd0c; 8 | wt_sine_lut_f = 0x0807bf10; 9 | schetzen_lut_f = 0x0807c114; 10 | cubicsat_lut_f = 0x0807c318; 11 | pow2_lut_f = 0x0807c51c; 12 | _fx_mcu_hash = 0x0807c920; 13 | _fx_rand = 0x0807c92c; 14 | _fx_white = 0x0807c964; 15 | _fx_get_bpm = 0x0807ca88; 16 | _fx_get_bpmf = 0x0807ca8c; 17 | midi_to_hz_lut_f = 0x0800f100; 18 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 boochow 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /ld/userdelfx.ld: -------------------------------------------------------------------------------- 1 | /* 2 | BSD 3-Clause License 3 | 4 | Copyright (c) 2018, KORG INC. 5 | All rights reserved. 6 | 7 | Redistribution and use in source and binary forms, with or without 8 | modification, are permitted provided that the following conditions are met: 9 | 10 | * Redistributions of source code must retain the above copyright notice, this 11 | list of conditions and the following disclaimer. 12 | 13 | * Redistributions in binary form must reproduce the above copyright notice, 14 | this list of conditions and the following disclaimer in the documentation 15 | and/or other materials provided with the distribution. 16 | 17 | * Neither the name of the copyright holder nor the names of its 18 | contributors may be used to endorse or promote products derived from 19 | this software without specific prior written permission. 20 | 21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 25 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 28 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | //*/ 33 | 34 | /* 35 | * File: userdelfx.ld 36 | * 37 | * Linker Script for user delay effects 38 | */ 39 | 40 | /* Entry Point */ 41 | ENTRY(_entry) 42 | 43 | /* Specify the memory areas */ 44 | MEMORY 45 | { 46 | SRAM (rx) : org = 0x20019000, len = 12K 47 | SDRAM (rw) : org = 0xC0420000, len = 2432K 48 | } 49 | 50 | /* Include Rules */ 51 | INCLUDE rules.ld 52 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Lissa delay 2 | 3 | ## About 4 | Lissa is a delay module for Korg Nu:Tekt NTS1 and other synthesizers compatible with [logue SDK](https://github.com/korginc/logue-sdk). 5 | 6 | The primary purpose of Lissa is to generate a sweep signal to display the waveform of the input signal on an oscilloscope as a [Lissajous figure](https://en.wikipedia.org/wiki/Lissajous_curve). 7 | 8 | [![top-page](https://raw.githubusercontent.com/boochow/lissa/image/vpm.gif)](https://www.youtube.com/watch?v=_FJFkW42QLE) 9 | 10 | Lissa passes the input signal to the right channel of output with no change. The left channel is used for sweep signal, which is one of sine wave, sawtooth wave, or the input signal with 90 degrees delay. 11 | 12 | Lissa delay is mainly for fun and educational purposes. It is almost useless for the usual music production. 13 | 14 | ## How to use 15 | 16 | 1. Firstly, install an oscilloscope software with X-Y display capability on your PC or Mac. I recommend [Oscilloscope](https://asdfg.me/osci/), [Soundcard Scope](https://www.zeitnitz.eu/scope_en), or [Winscope](http://www.zen22142.zen.co.uk/Prac/winscope.htm). 17 | 18 | 1. Connect your NTS-1 output to the audio input of your PC. 19 | 20 | 1. Hit E key of NTS-1. Then, press EG button and select "oPEn" with the TYPE knob. 21 | 22 | 1. Press the DELAY button then select "LiSa" with the TYPE knob. 23 | 24 | 1. Adjust the aspect ratio of the Lissajous figure with the B knob. 25 | 26 | 1. Press the DELAY button and keep it pressed. Then turn the B knob clockwise to change the sweep signal to a sawtooth wave. 27 | 28 | 1. Adjust the pitch of the sweep signal (left channel) to the same value with the input signal (right channel). 29 | 30 | 1. Again press the DELAY button and keep it pressed. Tweak the B knob and watch how the figure is changed. Then modify the tone of input sound by the filter, OSC parameters, etc. and look at how it is reflected on the screen. 31 | 32 | ## Parameters 33 | 34 | ### Time 35 | 36 | To synchronize the input signal and the sweep signal, you have to tune the sweep signal manually. That is done by the Time parameter, which is assigned to the knob A in the case of NTS1. 37 | 38 | The time parameter varies from 0 to 127. This value represents a MIDI note number, which is used to determine the sweep signal frequency. 39 | 40 | ### Depth 41 | 42 | The depth parameter controls the amplitude of the sweep signal. 43 | 44 | ### Shift-Depth 45 | 46 | The shift-depth parameter changes the waveform of the sweep signal and its time offset. 47 | This parameter is between 0.0 and 1.0, and its default value is 0.5. 48 | The waveform and time offset become as follows, depending on the shit-depth value. 49 | 50 | + 0.0 .. 0.4: sweep signal is a sine wave. Offset varies from -0.5 to 0.5. 51 | + 0.4 .. 0.6: sweep signal is a delayed input signal. The length of the delay is a quarter of the wavelength, which is determined by the time parameter. 52 | + 0.6 .. 1.0: sweep signal is a sawtooth wave. Offset varies from 0.0 to 1.0. 53 | 54 | ## How to build 55 | 56 | Place this directory under `logue-sdk/platform/nutekt-digital/` then type `make`. 57 | 58 | ## Others 59 | 60 | My other user oscillators / modules are [here](https://blog.boochow.com/logue). 61 | -------------------------------------------------------------------------------- /lissa.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * File: lissa.cpp 3 | */ 4 | 5 | #include "userdelfx.h" 6 | 7 | #include "simplelfo.hpp" 8 | 9 | #include "osc_api.h" 10 | 11 | #include "delayline.hpp" 12 | 13 | // lowest note frequency is 8.2 Hz. 14 | // longest delay is wave length/4 = 1/(8.2 * 4). 15 | // so 1/32 sec is sufficient for delay buffer. 16 | #define BUFSIZE 1500 17 | 18 | // lfo default frequency. Actually, this value is not used 19 | // because lfo freqency is changed by DELFX_PARAM() when 20 | // the delay instance is started and its value is always 330 21 | // (frequency of MIDI note #64, which is 0.5*128) 22 | #define DEFAULTFREQ 330 23 | 24 | static dsp::DelayLine s_delay; 25 | 26 | static __sdram float s_delay_ram[BUFSIZE]; 27 | 28 | static float s_len_z, s_len; 29 | 30 | static dsp::SimpleLFO s_lfo; 31 | static const float s_fs_recip = 1.f / 48000.f; 32 | static float amp = 1.0; 33 | static float offset = 0; 34 | 35 | enum { 36 | SWEEP_SINE = 0, 37 | SWEEP_SAW = 1, 38 | SWEEP_IN = 2, 39 | }; 40 | static int32_t lfo_type = 0; 41 | 42 | void DELFX_INIT(uint32_t platform, uint32_t api) 43 | { 44 | s_delay.setMemory(s_delay_ram, BUFSIZE); 45 | s_len = s_len_z = 48000.f / (4 * DEFAULTFREQ); 46 | s_lfo.reset(); 47 | s_lfo.setF0(DEFAULTFREQ, s_fs_recip); 48 | amp = 1.0; 49 | offset = 0; 50 | lfo_type = 0; 51 | } 52 | 53 | void DELFX_PROCESS(float *xn, uint32_t frames) 54 | { 55 | float * __restrict x = xn; 56 | const float * x_e = x + 2*frames; 57 | 58 | const float len = s_len; 59 | float len_z = s_len_z; 60 | 61 | for (; x != x_e; ) { 62 | len_z = linintf(0.002f, len_z, len); 63 | const float r = s_delay.readFrac(len_z); 64 | 65 | float wave; 66 | s_lfo.cycle(); 67 | 68 | switch(lfo_type) { 69 | case SWEEP_SINE: 70 | wave = amp * s_lfo.sine_bi_off(offset); 71 | break; 72 | case SWEEP_SAW: 73 | wave = amp * s_lfo.saw_bi_off(offset); 74 | break; 75 | case SWEEP_IN: 76 | wave = 2.5 * amp * s_delay.readFrac(len_z); 77 | break; 78 | default: 79 | break; 80 | } 81 | float in = *x; 82 | s_delay.write(in); 83 | *(x++) = wave; 84 | *(x++) = in; 85 | } 86 | s_len_z = len_z; 87 | } 88 | 89 | 90 | void DELFX_PARAM(uint8_t index, int32_t value) 91 | { 92 | const float valf = q31_to_f32(value); 93 | float hz; 94 | 95 | switch (index) { 96 | case k_user_delfx_param_time: 97 | hz = osc_notehzf(valf * 128); 98 | s_lfo.setF0(hz, s_fs_recip); 99 | s_len = 48000.f / (4 * hz); /* delay length = 1/4 * wave length */ 100 | break; 101 | case k_user_delfx_param_depth: 102 | amp = valf; 103 | break; 104 | case k_user_delfx_param_shift_depth: 105 | if (valf <= 0.4) { 106 | offset = valf * 2.5 - 0.5; /* offset = -0.5 .. 0.5 */ 107 | lfo_type = SWEEP_SINE; 108 | } else if (valf >= 0.6) { 109 | offset = (1.0 - valf) * 2.5; /* offset = 0.0 .. 1.0 */ 110 | lfo_type = SWEEP_SAW; 111 | } else { 112 | lfo_type = SWEEP_IN; 113 | } 114 | break; 115 | default: 116 | break; 117 | } 118 | } 119 | 120 | void DELFX_RESUME(void) { 121 | s_lfo.reset(); 122 | } 123 | -------------------------------------------------------------------------------- /tpl/_unit.c: -------------------------------------------------------------------------------- 1 | /* 2 | BSD 3-Clause License 3 | 4 | Copyright (c) 2018, KORG INC. 5 | All rights reserved. 6 | 7 | Redistribution and use in source and binary forms, with or without 8 | modification, are permitted provided that the following conditions are met: 9 | 10 | * Redistributions of source code must retain the above copyright notice, this 11 | list of conditions and the following disclaimer. 12 | 13 | * Redistributions in binary form must reproduce the above copyright notice, 14 | this list of conditions and the following disclaimer in the documentation 15 | and/or other materials provided with the distribution. 16 | 17 | * Neither the name of the copyright holder nor the names of its 18 | contributors may be used to endorse or promote products derived from 19 | this software without specific prior written permission. 20 | 21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 25 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 28 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | //*/ 33 | 34 | /** 35 | * @file _unit.c 36 | * @brief Delay effect entry template. 37 | * 38 | * @addtogroup api 39 | * @{ 40 | */ 41 | 42 | #include "userdelfx.h" 43 | 44 | /*===========================================================================*/ 45 | /* Externs and Types. */ 46 | /*===========================================================================*/ 47 | 48 | /** 49 | * @name Externs and Types. 50 | * @{ 51 | */ 52 | 53 | extern uint8_t _bss_start; 54 | extern uint8_t _bss_end; 55 | 56 | extern void (*__init_array_start []) (void); 57 | extern void (*__init_array_end []) (void); 58 | 59 | typedef void (*__init_fptr)(void); 60 | 61 | /** @} */ 62 | 63 | /*===========================================================================*/ 64 | /* Local Constants and Vars. */ 65 | /*===========================================================================*/ 66 | 67 | /** 68 | * @name Local Constants and Vars. 69 | * @{ 70 | */ 71 | 72 | __attribute__((used, section(".hooks"))) 73 | static const user_delfx_hook_table_t s_hook_table = { 74 | .magic = {'U','D','E','L'}, 75 | .api = USER_API_VERSION, 76 | .platform = USER_TARGET_PLATFORM>>8, 77 | .reserved0 = {0}, 78 | .func_entry = _entry, 79 | .func_process = _hook_process, 80 | .func_suspend = _hook_suspend, 81 | .func_resume = _hook_resume, 82 | .func_param = _hook_param, 83 | .reserved1 = {0} 84 | }; 85 | 86 | /** @} */ 87 | 88 | /*===========================================================================*/ 89 | /* Default Hooks. */ 90 | /*===========================================================================*/ 91 | 92 | /** 93 | * @name Default Hooks. 94 | * @{ 95 | */ 96 | 97 | __attribute__((used)) 98 | void _entry(uint32_t platform, uint32_t api) 99 | { 100 | // Ensure zero-clear BSS segment 101 | uint8_t * __restrict bss_p = (uint8_t *)&_bss_start; 102 | const uint8_t * const bss_e = (uint8_t *)&_bss_end; 103 | 104 | for (; bss_p != bss_e;) 105 | *(bss_p++) = 0; 106 | 107 | // Call constructors if any. 108 | const size_t count = __init_array_end - __init_array_start; 109 | for (size_t i = 0; i SRAM 54 | 55 | /* Constructors */ 56 | .init_array : ALIGN(4) SUBALIGN(4) 57 | { 58 | . = ALIGN(4); 59 | PROVIDE(__init_array_start = .); 60 | KEEP(*(SORT(.init_array.*))) 61 | KEEP(*(.init_array*)) 62 | . = ALIGN(4); 63 | PROVIDE(__init_array_end = .); 64 | } > SRAM 65 | 66 | /* Common Code */ 67 | .text : ALIGN(4) SUBALIGN(4) 68 | { 69 | . = ALIGN(4); 70 | _text_start = .; 71 | *(.text) 72 | *(.text.*) 73 | *(.glue_7) /* glue arm to thumb code */ 74 | *(.glue_7t) /* glue thumb to arm code */ 75 | *(.gcc*) 76 | . = ALIGN(4); 77 | _text_end = .; 78 | } > SRAM 79 | 80 | /* Constants and strings */ 81 | .rodata : ALIGN(4) SUBALIGN(4) 82 | { 83 | . = ALIGN(4); 84 | _rodata_start = .; 85 | *(.rodata) 86 | *(.rodata.*) 87 | . = ALIGN(4); 88 | _rodata_end = .; 89 | } > SRAM 90 | 91 | /* Read-write data */ 92 | .data ALIGN(8) : ALIGN(8) SUBALIGN(8) 93 | { 94 | . = ALIGN(8); 95 | _data_start = .; 96 | *(.data) 97 | *(.data.*) 98 | . = ALIGN(8); 99 | _data_end = .; 100 | } > SRAM 101 | 102 | /* Uninitialized variables */ 103 | .bss (NOLOAD) : ALIGN(4) 104 | { 105 | . = ALIGN(4); 106 | _bss_start = .; 107 | *(.bss) 108 | *(.bss.*) 109 | *(COMMON) 110 | . = ALIGN(4); 111 | _bss_end = .; 112 | } > SRAM 113 | 114 | /* Exception sections */ 115 | .ARM.extab : ALIGN(4) SUBALIGN(4) 116 | { 117 | . = ALIGN(4); 118 | __extab_start = .; 119 | *(.ARM.extab* .gnu.linkonce.armextab.*) 120 | . = ALIGN(4); 121 | __extab_end = .; 122 | } > SRAM 123 | 124 | .ARM.exidx : ALIGN(4) SUBALIGN(4) 125 | { /* Note: Aligning when there's no content for this section throws a warning. Looks like a linker bug. */ 126 | /* . = ALIGN(4); */ 127 | __exidx_start = .; 128 | *(.ARM.exidx* .gnu.linkonce.armexidx.*) 129 | /* . = ALIGN(4); */ 130 | __exidx_end = .; 131 | } > SRAM 132 | 133 | .eh_frame_hdr : ALIGN(4) SUBALIGN(4) 134 | { 135 | . = ALIGN(4); 136 | _eh_frame_hdr_start = .; 137 | *(.eh_frame_hdr) 138 | . = ALIGN(4); 139 | _eh_frame_hdr_end = .; 140 | } > SRAM 141 | 142 | .eh_frame : ALIGN(4) SUBALIGN(4) ONLY_IF_RO 143 | { 144 | . = ALIGN(4); 145 | _eh_frame_start = .; 146 | *(.eh_frame) 147 | . = ALIGN(4); 148 | _eh_frame_end = .; 149 | } > SRAM 150 | 151 | .sdram (NOLOAD) : ALIGN(4) SUBALIGN(4) 152 | { 153 | . = ALIGN(4); 154 | _usr_sdram_start = .; 155 | KEEP(*(.sdram*)) 156 | . = ALIGN(4); 157 | _usr_sdram_end = .; 158 | } > SDRAM 159 | 160 | /* 161 | /DISCARD/ 162 | { 163 | libc.a ( * ) 164 | libm.a ( * ) 165 | libgcc.a ( * ) 166 | } 167 | //*/ 168 | 169 | /* .ARM.attributes 0 : { *(.ARM.attributes) } //*/ 170 | } 171 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # ############################################################################# 2 | # Prologue Delay FX Makefile 3 | # ############################################################################# 4 | 5 | ifeq ($(OS),Windows_NT) 6 | ifeq ($(MSYSTEM), MSYS) 7 | detected_OS := $(shell uname -s) 8 | else 9 | detected_OS := Windows 10 | endif 11 | else 12 | detected_OS := $(shell uname -s) 13 | endif 14 | 15 | PLATFORMDIR = .. 16 | PROJECTDIR = . 17 | TOOLSDIR = $(PLATFORMDIR)/../../tools 18 | EXTDIR = $(PLATFORMDIR)/../ext 19 | 20 | CMSISDIR = $(EXTDIR)/CMSIS/CMSIS 21 | 22 | # ############################################################################# 23 | # configure archive utility 24 | # ############################################################################# 25 | 26 | ZIP = /usr/bin/zip 27 | ZIP_ARGS = -r -m -q 28 | 29 | ifeq ($(OS),Windows_NT) 30 | ifneq ($(MSYSTEM), MSYS) 31 | ifneq ($(MSYSTEM), MINGW64) 32 | ZIP = $(TOOLSDIR)/zip/bin/zip 33 | endif 34 | endif 35 | endif 36 | 37 | # ############################################################################# 38 | # Include project specific definition 39 | # ############################################################################# 40 | 41 | include ./project.mk 42 | 43 | # ############################################################################# 44 | # configure cross compilation 45 | # ############################################################################# 46 | 47 | MCU = cortex-m4 48 | 49 | GCC_TARGET = arm-none-eabi- 50 | GCC_BIN_PATH = $(TOOLSDIR)/gcc/gcc-arm-none-eabi-5_4-2016q3/bin 51 | 52 | CC = $(GCC_BIN_PATH)/$(GCC_TARGET)gcc 53 | CXXC = $(GCC_BIN_PATH)/$(GCC_TARGET)g++ 54 | LD = $(GCC_BIN_PATH)/$(GCC_TARGET)gcc 55 | #LD = $(GCC_BIN_PATH)/$(GCC_TARGET)g++ 56 | CP = $(GCC_BIN_PATH)/$(GCC_TARGET)objcopy 57 | AS = $(GCC_BIN_PATH)/$(GCC_TARGET)gcc -x assembler-with-cpp 58 | AR = $(GCC_BIN_PATH)/$(GCC_TARGET)ar 59 | OD = $(GCC_BIN_PATH)/$(GCC_TARGET)objdump 60 | SZ = $(GCC_BIN_PATH)/$(GCC_TARGET)size 61 | 62 | HEX = $(CP) -O ihex 63 | BIN = $(CP) -O binary 64 | 65 | LDDIR = $(PROJECTDIR)/ld 66 | RULESPATH = $(LDDIR) 67 | LDSCRIPT = $(LDDIR)/userdelfx.ld 68 | DLIBS = -lm 69 | 70 | DADEFS = -DSTM32F446xE -DCORTEX_USE_FPU=TRUE -DARM_MATH_CM4 71 | DDEFS = -DSTM32F446xE -DCORTEX_USE_FPU=TRUE -DARM_MATH_CM4 -D__FPU_PRESENT 72 | 73 | COPT = -std=c11 -mstructure-size-boundary=8 74 | CXXOPT = -std=c++11 -fno-rtti -fno-exceptions -fno-non-call-exceptions 75 | 76 | LDOPT = -Xlinker --just-symbols=$(LDDIR)/main_api.syms 77 | 78 | CWARN = -W -Wall -Wextra 79 | CXXWARN = 80 | 81 | FPU_OPTS = -mfloat-abi=hard -mfpu=fpv4-sp-d16 -fsingle-precision-constant -fcheck-new 82 | 83 | OPT = -g -Os -mlittle-endian 84 | OPT += $(FPU_OPTS) 85 | #OPT += -flto 86 | 87 | TOPT = -mthumb -mno-thumb-interwork -DTHUMB_NO_INTERWORKING -DTHUMB_PRESENT 88 | 89 | 90 | # ############################################################################# 91 | # set targets and directories 92 | # ############################################################################# 93 | 94 | PKGDIR = $(PROJECT) 95 | PKGARCH = $(PROJECT).ntkdigunit 96 | MANIFEST = manifest.json 97 | PAYLOAD = payload.bin 98 | BUILDDIR = $(PROJECTDIR)/build 99 | OBJDIR = $(BUILDDIR)/obj 100 | LSTDIR = $(BUILDDIR)/lst 101 | 102 | ASMSRC = $(UASMSRC) 103 | 104 | ASMXSRC = $(UASMXSRC) 105 | 106 | CSRC = $(PROJECTDIR)/tpl/_unit.c $(UCSRC) 107 | 108 | CXXSRC = $(UCXXSRC) 109 | 110 | vpath %.s $(sort $(dir $(ASMSRC))) 111 | vpath %.S $(sort $(dir $(ASMXSRC))) 112 | vpath %.c $(sort $(dir $(CSRC))) 113 | vpath %.cpp $(sort $(dir $(CXXSRC))) 114 | 115 | ASMOBJS := $(addprefix $(OBJDIR)/, $(notdir $(ASMSRC:.s=.o))) 116 | ASMXOBJS := $(addprefix $(OBJDIR)/, $(notdir $(ASMXSRC:.S=.o))) 117 | COBJS := $(addprefix $(OBJDIR)/, $(notdir $(CSRC:.c=.o))) 118 | CXXOBJS := $(addprefix $(OBJDIR)/, $(notdir $(CXXSRC:.cpp=.o))) 119 | 120 | OBJS := $(ASMXOBJS) $(ASMOBJS) $(COBJS) $(CXXOBJS) 121 | 122 | DINCDIR = $(PROJECTDIR)/inc \ 123 | $(PROJECTDIR)/inc/api \ 124 | $(PLATFORMDIR)/inc \ 125 | $(PLATFORMDIR)/inc/dsp \ 126 | $(PLATFORMDIR)/inc/utils \ 127 | $(CMSISDIR)/Include 128 | 129 | INCDIR := $(patsubst %,-I%,$(DINCDIR) $(UINCDIR)) 130 | 131 | DEFS := $(DDEFS) $(UDEFS) 132 | ADEFS := $(DADEFS) $(UADEFS) 133 | 134 | LIBS := $(DLIBS) $(ULIBS) 135 | 136 | LIBDIR := $(patsubst %,-I%,$(DLIBDIR) $(ULIBDIR)) 137 | 138 | 139 | # ############################################################################# 140 | # compiler flags 141 | # ############################################################################# 142 | 143 | MCFLAGS := -mcpu=$(MCU) 144 | ODFLAGS = -x --syms 145 | ASFLAGS = $(MCFLAGS) -g $(TOPT) -Wa,-alms=$(LSTDIR)/$(notdir $(<:.s=.lst)) $(ADEFS) 146 | ASXFLAGS = $(MCFLAGS) -g $(TOPT) -Wa,-alms=$(LSTDIR)/$(notdir $(<:.S=.lst)) $(ADEFS) 147 | CFLAGS = $(MCFLAGS) $(TOPT) $(OPT) $(COPT) $(CWARN) -Wa,-alms=$(LSTDIR)/$(notdir $(<:.c=.lst)) $(DEFS) 148 | CXXFLAGS = $(MCFLAGS) $(TOPT) $(OPT) $(CXXOPT) $(CXXWARN) -Wa,-alms=$(LSTDIR)/$(notdir $(<:.cpp=.lst)) $(DEFS) 149 | LDFLAGS = $(MCFLAGS) $(TOPT) $(OPT) -nostartfiles $(LIBDIR) -Wl,-Map=$(BUILDDIR)/$(PROJECT).map,--cref,--no-warn-mismatch,--library-path=$(RULESPATH),--script=$(LDSCRIPT) $(LDOPT) 150 | 151 | OUTFILES := $(BUILDDIR)/$(PROJECT).elf \ 152 | $(BUILDDIR)/$(PROJECT).hex \ 153 | $(BUILDDIR)/$(PROJECT).bin \ 154 | $(BUILDDIR)/$(PROJECT).dmp \ 155 | $(BUILDDIR)/$(PROJECT).list 156 | 157 | ############################################################################### 158 | # targets 159 | ############################################################################### 160 | 161 | all: PRE_ALL $(OBJS) $(OUTFILES) POST_ALL 162 | 163 | PRE_ALL: 164 | 165 | POST_ALL: package 166 | 167 | $(OBJS): | $(BUILDDIR) $(OBJDIR) $(LSTDIR) 168 | 169 | $(BUILDDIR): 170 | @echo Compiler Options 171 | @echo $(CC) -c $(CFLAGS) -I. $(INCDIR) 172 | @echo 173 | @mkdir -p $(BUILDDIR) 174 | 175 | $(OBJDIR): 176 | @mkdir -p $(OBJDIR) 177 | 178 | $(LSTDIR): 179 | @mkdir -p $(LSTDIR) 180 | 181 | $(ASMOBJS) : $(OBJDIR)/%.o : %.s Makefile 182 | @echo Assembling $( $@ 212 | @echo 213 | @$(SZ) $< 214 | @echo 215 | 216 | %.list: %.elf 217 | @echo Creating $@ 218 | @$(OD) -S $< > $@ 219 | 220 | clean: 221 | @echo Cleaning 222 | -rm -fR .dep $(BUILDDIR) $(PKGARCH) 223 | @echo 224 | @echo Done 225 | 226 | package: 227 | @echo Packaging to ./$(PKGARCH) 228 | @mkdir -p $(PKGDIR) 229 | @cp -a $(MANIFEST) $(PKGDIR)/ 230 | @cp -a $(BUILDDIR)/$(PROJECT).bin $(PKGDIR)/$(PAYLOAD) 231 | @$(ZIP) $(ZIP_ARGS) $(PROJECT).zip $(PKGDIR) 232 | @mv $(PROJECT).zip $(PKGARCH) 233 | @echo 234 | @echo Done 235 | --------------------------------------------------------------------------------