├── .gitignore ├── src ├── hw │ ├── syscalls.c │ ├── pi.h │ ├── system_fn.h │ ├── system_fn.c │ ├── sha1.h │ ├── eeprom.h │ ├── stm32f4xx_it.h │ ├── sensors.h │ ├── controls.h │ ├── flash.h │ ├── sensors.c │ ├── stm32f4xx_conf.h │ ├── leds.h │ ├── signals.h │ ├── stm32f4xx_it.c │ ├── pi.c │ └── eeprom.c ├── AudioLoopNoFilters.h ├── extensions │ ├── Antarctica.h │ ├── MIDI.h │ ├── Reverb.h │ ├── Sequencer.h │ ├── Chaos.h │ ├── Samples.h │ ├── Bytebeat.h │ ├── CV_Gate.h │ ├── Granular.h │ ├── Drums.h │ ├── MIDI.c │ ├── DCO_Synth.h │ ├── CV_Gate.c │ ├── Samples.c │ ├── Drums.c │ ├── Antarctica.cpp │ └── Sequencer.cpp ├── AudioLoopFilters.h ├── dsp │ ├── Goertzel.h │ ├── Detectors.h │ ├── Goertzel.cpp │ ├── Filters.h │ ├── IIR_filters.h │ ├── freqs.h │ ├── Detectors.cpp │ └── IIR_filters.cpp ├── Test_fn.h ├── main.h ├── MusicBox.h ├── Channels.h ├── notes.h ├── songs.c ├── main.cpp ├── Interface.h ├── MusicBox.cpp └── board_config.h ├── README.md ├── lib ├── Device │ └── STM32F4xx │ │ └── Include │ │ ├── stm32f4xx.h │ │ └── system_stm32f4xx.h ├── CMSIS │ ├── CMSIS END USER LICENCE AGREEMENT.pdf │ └── Include │ │ └── arm_common_tables.h └── STM32F4xx_StdPeriph_Driver │ ├── Release_Notes.html │ ├── inc │ ├── stm32f4xx_crc.h │ ├── stm32f4xx_wwdg.h │ ├── stm32f4xx_rng.h │ ├── stm32f4xx_dbgmcu.h │ ├── stm32f4xx_iwdg.h │ ├── stm32f4xx_pwr.h │ └── misc.h │ └── src │ ├── stm32f4xx_crc.c │ └── stm32f4xx_dbgmcu.c ├── .settings ├── org.eclipse.ltk.core.refactoring.prefs ├── org.eclipse.cdt.core.prefs ├── com.atollic.truestudio.debug.hardware_device.prefs ├── language.settings.xml └── org.eclipse.cdt.managedbuilder.core.prefs ├── .project ├── LICENSE ├── gecho-v1.elf.launch └── Debug_STM32F405RG_FLASH.ld /.gitignore: -------------------------------------------------------------------------------- 1 | /Debug/ 2 | /Release/ 3 | /Optimized/ 4 | -------------------------------------------------------------------------------- /src/hw/syscalls.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/h3o/Gecho_v1/HEAD/src/hw/syscalls.c -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Gecho_v1 2 | firmware for Gecho Loopsynth, STM32F4 based pocket synth ( http://gechologic.com/ ) 3 | -------------------------------------------------------------------------------- /lib/Device/STM32F4xx/Include/stm32f4xx.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/h3o/Gecho_v1/HEAD/lib/Device/STM32F4xx/Include/stm32f4xx.h -------------------------------------------------------------------------------- /lib/CMSIS/CMSIS END USER LICENCE AGREEMENT.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/h3o/Gecho_v1/HEAD/lib/CMSIS/CMSIS END USER LICENCE AGREEMENT.pdf -------------------------------------------------------------------------------- /lib/STM32F4xx_StdPeriph_Driver/Release_Notes.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/h3o/Gecho_v1/HEAD/lib/STM32F4xx_StdPeriph_Driver/Release_Notes.html -------------------------------------------------------------------------------- /.settings/org.eclipse.ltk.core.refactoring.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false 3 | -------------------------------------------------------------------------------- /.settings/org.eclipse.cdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | environment/project/com.atollic.truestudio.exe.debug.122518818/append=true 3 | environment/project/com.atollic.truestudio.exe.debug.122518818/appendContributed=true 4 | -------------------------------------------------------------------------------- /src/hw/pi.h: -------------------------------------------------------------------------------- 1 | #ifndef PI_H 2 | #define PI_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | int calculate_pi_at_nth_digit(int n, int indication); 9 | int load_pi_at_nth_dword(int n); 10 | 11 | #ifdef __cplusplus 12 | } 13 | #endif 14 | 15 | #endif /* PI_H */ 16 | -------------------------------------------------------------------------------- /.settings/com.atollic.truestudio.debug.hardware_device.prefs: -------------------------------------------------------------------------------- 1 | BOARD=None 2 | CODE_LOCATION=FLASH 3 | ENDIAN=Little-endian 4 | MCU=STM32F405RG 5 | MCU_VENDOR=STMicroelectronics 6 | MODEL=Lite 7 | PROBE=ST-LINK 8 | PROJECT_FORMAT_VERSION=2 9 | TARGET=ARM\u00AE 10 | VERSION=5.4.2 11 | eclipse.preferences.version=1 12 | -------------------------------------------------------------------------------- /src/AudioLoopNoFilters.h: -------------------------------------------------------------------------------- 1 | /* 2 | * AudioLoopNoFilters.h 3 | * 4 | * Created on: Sep 04, 2017 5 | * Author: mayo 6 | * 7 | * This file is part of the Gecho Loopsynth Firmware Development Framework. 8 | * It can be used within the terms of CC-BY-NC-SA license. 9 | * It must not be distributed separately. 10 | * 11 | * Find more information at: http://gechologic.com/gechologists/ 12 | */ 13 | 14 | #ifndef AUDIO_LOOP_NO_FILTERS_H_ 15 | #define AUDIO_LOOP_NO_FILTERS_H_ 16 | 17 | void audio_loop_no_filters(); 18 | 19 | #endif 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/hw/system_fn.h: -------------------------------------------------------------------------------- 1 | /* 2 | * system_fn.h 3 | * 4 | * Created on: Apr 27, 2016 5 | * Author: mayo 6 | * 7 | * This file is part of the Gecho Loopsynth Firmware Development Framework. 8 | * It can be used within the terms of CC-BY-NC-SA license. 9 | * It must not be distributed separately. 10 | * 11 | * Find more information at: http://gechologic.com/gechologists/ 12 | */ 13 | 14 | #ifndef SYSTEM_FN_H_ 15 | #define SYSTEM_FN_H_ 16 | 17 | #include "stm32f4xx.h" 18 | 19 | #ifdef __cplusplus 20 | extern "C" { 21 | #endif 22 | 23 | void FlashAcceleratorInit(); 24 | 25 | #ifdef __cplusplus 26 | } 27 | #endif 28 | 29 | #endif /* SYSTEM_FN_H_ */ 30 | -------------------------------------------------------------------------------- /src/extensions/Antarctica.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Antarctica.h 3 | * 4 | * Created on: Sep 24, 2016 5 | * Author: mayo 6 | * 7 | * This file is part of the Gecho Loopsynth Firmware Development Framework. 8 | * It can be used within the terms of CC-BY-NC-SA license. 9 | * It must not be distributed separately. 10 | * 11 | * Find more information at: http://gechologic.com/gechologists/ 12 | */ 13 | 14 | #ifndef ANTARCTICA_H_ 15 | #define ANTARCTICA_H_ 16 | 17 | #include "stm32f4xx.h" 18 | 19 | #ifdef __cplusplus 20 | extern "C" { 21 | #endif 22 | 23 | void song_of_wind_and_ice(); 24 | 25 | #ifdef __cplusplus 26 | } 27 | #endif 28 | 29 | #endif /* ANTARCTICA_H_ */ 30 | -------------------------------------------------------------------------------- /src/AudioLoopFilters.h: -------------------------------------------------------------------------------- 1 | /* 2 | * AudioLoopFilters.h 3 | * 4 | * Created on: Apr 10, 2016 5 | * Author: mayo 6 | * 7 | * This file is part of the Gecho Loopsynth Firmware Development Framework. 8 | * It can be used within the terms of CC-BY-NC-SA license. 9 | * It must not be distributed separately. 10 | * 11 | * Find more information at: http://gechologic.com/gechologists/ 12 | */ 13 | 14 | #ifndef AUDIO_LOOP_FILTERS_H_ 15 | #define AUDIO_LOOP_FILTERS_H_ 16 | 17 | //time-critical stuff 18 | #define SHIFT_MELODY_NOTE_TIMING_BY_SAMPLE 3 19 | #define SHIFT_CHORD_TIMING_BY_SAMPLE 5 20 | #define SHIFT_ARP_TIMING_BY_SAMPLE 2 21 | 22 | void audio_loop_filters(); 23 | 24 | #endif 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/extensions/MIDI.h: -------------------------------------------------------------------------------- 1 | /* 2 | * MIDI.h 3 | * 4 | * Created on: Jan 9, 2017 5 | * Author: mayo 6 | * 7 | * This file is part of the Gecho Loopsynth Firmware Development Framework. 8 | * It can be used within the terms of CC-BY-NC-SA license. 9 | * It must not be distributed separately. 10 | * 11 | * Find more information at: http://gechologic.com/gechologists/ 12 | */ 13 | 14 | #ifndef MIDI_H_ 15 | #define MIDI_H_ 16 | 17 | extern int MIDI_notes_to_freq[128]; 18 | 19 | #ifdef __cplusplus 20 | extern "C" { 21 | #endif 22 | 23 | void MIDI_out_test(); 24 | void MIDI_record_playback_test(); 25 | void MIDI_direct_signals_test(); 26 | 27 | #ifdef __cplusplus 28 | } 29 | #endif 30 | 31 | #endif /* MIDI_H_ */ 32 | -------------------------------------------------------------------------------- /src/extensions/Reverb.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Reverb.h 3 | * 4 | * Created on: 17 July 2018 5 | * Author: mayo 6 | * 7 | * This file is part of the Gecho Loopsynth Firmware Development Framework. 8 | * It can be used within the terms of CC-BY-NC-SA license. 9 | * 10 | * Find more information at: http://gechologic.com/gechologists/ 11 | */ 12 | 13 | #ifndef EXTENSIONS_REVERB_H_ 14 | #define EXTENSIONS_REVERB_H_ 15 | 16 | #include 17 | #include 18 | #include "hw/gpio.h" 19 | #include "hw/leds.h" 20 | #include "hw/sensors.h" 21 | #include "hw/signals.h" 22 | #include 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | void reverb_with_echo(int mode); 29 | int16_t add_reverb(int16_t sample); 30 | 31 | #ifdef __cplusplus 32 | } 33 | #endif 34 | 35 | #endif /* EXTENSIONS_REVERB_H_ */ 36 | -------------------------------------------------------------------------------- /src/extensions/Sequencer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Sequencer.h 3 | * 4 | * Created on: 26 Jan 2018 5 | * Author: mayo 6 | * 7 | * As explained in the coding tutorial: http://gechologic.com/granular-sampler 8 | * 9 | * This file is part of the Gecho Loopsynth Firmware Development Framework. 10 | * It can be used within the terms of CC-BY-NC-SA license. 11 | * 12 | * Find more information at: http://gechologic.com/gechologists/ 13 | */ 14 | 15 | #ifndef EXTENSIONS_SEQUENCER_H_ 16 | #define EXTENSIONS_SEQUENCER_H_ 17 | 18 | #include 19 | #include "hw/gpio.h" 20 | #include "hw/leds.h" 21 | #include "hw/sensors.h" 22 | #include 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | void drum_sequencer(); 29 | 30 | #ifdef __cplusplus 31 | } 32 | #endif 33 | 34 | #endif /* EXTENSIONS_SEQUENCER_H_ */ 35 | -------------------------------------------------------------------------------- /src/extensions/Chaos.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Chaos.h 3 | * 4 | * Created on: Dec 28, 2016 5 | * Author: mayo 6 | * 7 | * This file is part of the Gecho Loopsynth Firmware Development Framework. 8 | * It can be used within the terms of CC-BY-NC-SA license. 9 | * It must not be distributed separately. 10 | * 11 | * Find more information at: http://gechologic.com/gechologists/ 12 | */ 13 | 14 | #ifndef CHAOS_H_ 15 | #define CHAOS_H_ 16 | 17 | #ifdef __cplusplus 18 | extern "C" { 19 | #endif 20 | 21 | int get_music_from_noise(char **progression_buffer, char **melody_buffer); 22 | int generate_chord_progression(char **progression_buffer); 23 | int get_melody_fragment(char *chord, char *buffer); 24 | int get_chord_expansion(char *chord, char *expansion); 25 | void shuffle_octaves(char *buffer); 26 | 27 | #ifdef __cplusplus 28 | } 29 | #endif 30 | 31 | #endif /* MIDI_H_ */ 32 | -------------------------------------------------------------------------------- /src/dsp/Goertzel.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Goertzel.h 3 | * 4 | * Created on: Jun 29, 2016 5 | * Author: mayo 6 | * 7 | * Based on code by Kevin Banks 8 | * Source: http://www.embedded.com/design/configurable-systems/4024443/The-Goertzel-Algorithm 9 | * 10 | */ 11 | 12 | #ifndef GOERTZEL_H_ 13 | #define GOERTZEL_H_ 14 | 15 | #include "stm32f4xx.h" 16 | 17 | #define SAMPLING_RATE 22050.0 //22kHz 18 | //#define TARGET_FREQUENCY 941.0 //941 Hz 19 | 20 | class Goertzel { 21 | 22 | float coeff; 23 | float Q1; 24 | float Q2; 25 | float sine; 26 | float cosine; 27 | 28 | public: 29 | Goertzel(); 30 | virtual ~Goertzel(); 31 | void reset(); 32 | void init(float TARGET_FREQUENCY, int N); //N=block size 33 | void process_sample(uint16_t sample); 34 | void get_real_imag(float *realPart, float *imagPart); 35 | float get_magnitude_squared(void); 36 | }; 37 | 38 | #endif /* GOERTZEL_H_ */ 39 | -------------------------------------------------------------------------------- /src/extensions/Samples.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Samples.h 3 | * 4 | * Created on: Nov 26, 2016 5 | * Author: mayo 6 | * 7 | * This file is part of the Gecho Loopsynth Firmware Development Framework. 8 | * It can be used within the terms of CC-BY-NC-SA license. 9 | * It must not be distributed separately. 10 | * 11 | * Find more information at: http://gechologic.com/gechologists/ 12 | */ 13 | 14 | #ifndef SAMPLES_H_ 15 | #define SAMPLES_H_ 16 | 17 | #include //for uint16_t type 18 | 19 | #ifdef __cplusplus 20 | extern "C" { 21 | #endif 22 | 23 | uint16_t flash_sample_process(float playback_note_frequency); 24 | void play_buffer(uint16_t *buffer, int buffer_length, int channels); 25 | //void mix_in_buffer(uint16_t *buffer, int buffer_length, int channels, int volume_sample_rshift, unsigned int mask); 26 | 27 | #ifdef __cplusplus 28 | } 29 | #endif 30 | 31 | #endif /* SAMPLES_H_ */ 32 | -------------------------------------------------------------------------------- /src/hw/system_fn.c: -------------------------------------------------------------------------------- 1 | /* 2 | * system_fn.c 3 | * 4 | * Created on: Oct 31, 2016 5 | * Author: mayo 6 | * 7 | * This file is part of the Gecho Loopsynth Firmware Development Framework. 8 | * It can be used within the terms of CC-BY-NC-SA license. 9 | * It must not be distributed separately. 10 | * 11 | * Find more information at: http://gechologic.com/gechologists/ 12 | */ 13 | 14 | #include "system_fn.h" 15 | 16 | void FlashAcceleratorInit() 17 | { 18 | //Disable prefetch buffer 19 | //FLASH->ACR &= ~FLASH_ACR_PRFTEN; 20 | //Enable prefetch buffer 21 | FLASH->ACR |= FLASH_ACR_PRFTEN; 22 | 23 | //Enable flash instruction cache 24 | FLASH->ACR |= FLASH_ACR_ICEN; 25 | //Disable flash instruction cache 26 | //FLASH->ACR &= ~FLASH_ACR_ICEN; 27 | 28 | //Enable flash data cache 29 | FLASH->ACR |= FLASH_ACR_DCEN; 30 | //Disable flash data cache 31 | //FLASH->ACR &= ~FLASH_ACR_DCEN; 32 | } 33 | -------------------------------------------------------------------------------- /src/extensions/Bytebeat.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Bytebeat.h 3 | * 4 | * Created on: 19 July 2018 5 | * Author: mario (http://gechologic.com/contact) 6 | * 7 | * Used bytebeat math formulas from: https://youtu.be/GtQdIYUtAHg 8 | * 9 | * This file is part of the Gecho Loopsynth Firmware Development Framework. 10 | * It can be used within the terms of CC-BY-NC-SA license. 11 | * 12 | * Find more information at: http://gechologic.com/gechologists/ 13 | */ 14 | 15 | #ifndef EXTENSIONS_BYTEBEAT_H_ 16 | #define EXTENSIONS_BYTEBEAT_H_ 17 | 18 | #include 19 | #include 20 | #include "hw/gpio.h" 21 | #include "hw/leds.h" 22 | //#include "hw/sensors.h" 23 | #include "hw/signals.h" 24 | #include 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | void bytebeat(int mode); 31 | 32 | #ifdef __cplusplus 33 | } 34 | #endif 35 | 36 | #endif /* EXTENSIONS_BYTEBEAT_H_ */ 37 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | gecho-v1 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder 10 | clean,full,incremental, 11 | 12 | 13 | 14 | 15 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder 16 | full,incremental, 17 | 18 | 19 | 20 | 21 | 22 | org.eclipse.cdt.core.cnature 23 | org.eclipse.cdt.core.ccnature 24 | org.eclipse.cdt.managedbuilder.core.managedBuildNature 25 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/extensions/CV_Gate.h: -------------------------------------------------------------------------------- 1 | /* 2 | * CV_Gate.h 3 | * 4 | * Created on: May 28, 2017 5 | * Author: mayo 6 | * 7 | * This file is part of the Gecho Loopsynth Firmware Development Framework. 8 | * It can be used within the terms of CC-BY-NC-SA license. 9 | * It must not be distributed separately. 10 | * 11 | * Find more information at: http://gechologic.com/gechologists/ 12 | */ 13 | 14 | #ifndef CV_GATE_H_ 15 | #define CV_GATE_H_ 16 | 17 | #define CV_GATE_PB0_PB1 1 18 | #define CV_GATE_PC0_PB0 2 19 | 20 | #define GATE_PB0 (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0)==1) 21 | 22 | 23 | #ifdef __cplusplus 24 | extern "C" { 25 | #endif 26 | 27 | void ADC_configure_CV_GATE(int signals); 28 | int Calibrate_CV(); 29 | int Calculate_CV_values(int *reference_notes, int *cv_values_buffer); 30 | int find_nearest_note_freq(int CV_ADC_value); 31 | 32 | #ifdef __cplusplus 33 | } 34 | #endif 35 | 36 | #endif /* CV_GATE_H_ */ 37 | -------------------------------------------------------------------------------- /src/hw/sha1.h: -------------------------------------------------------------------------------- 1 | #ifndef SHA1_H 2 | #define SHA1_H 3 | 4 | /* 5 | SHA-1 in C 6 | By Steve Reid 7 | 100% Public Domain 8 | */ 9 | 10 | #include "stdint.h" 11 | 12 | typedef struct 13 | { 14 | uint32_t state[5]; 15 | uint32_t count[2]; 16 | unsigned char buffer[64]; 17 | } SHA1_CTX; 18 | 19 | #ifdef __cplusplus 20 | extern "C" { 21 | #endif 22 | 23 | void SHA1Transform( 24 | uint32_t state[5], 25 | const unsigned char buffer[64] 26 | ); 27 | 28 | void SHA1Init( 29 | SHA1_CTX * context 30 | ); 31 | 32 | void SHA1Update( 33 | SHA1_CTX * context, 34 | const unsigned char *data, 35 | uint32_t len 36 | ); 37 | 38 | void SHA1Final( 39 | unsigned char digest[20], 40 | SHA1_CTX * context 41 | ); 42 | 43 | void SHA1( 44 | char *hash_out, 45 | const char *str, 46 | int len); 47 | 48 | #ifdef __cplusplus 49 | } 50 | #endif 51 | 52 | #endif /* SHA1_H */ 53 | -------------------------------------------------------------------------------- /src/extensions/Granular.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Granular.h 3 | * 4 | * Created on: 22 Jan 2018 5 | * Author: mario (http://gechologic.com/contact) 6 | * 7 | * As explained in the coding tutorial: http://gechologic.com/granular-sampler 8 | * 9 | * This file is part of the Gecho Loopsynth Firmware Development Framework. 10 | * It can be used within the terms of CC-BY-NC-SA license. 11 | * 12 | * Find more information at: http://gechologic.com/gechologists/ 13 | */ 14 | 15 | #ifndef EXTENSIONS_GRANULAR_H_ 16 | #define EXTENSIONS_GRANULAR_H_ 17 | 18 | #include 19 | #include 20 | #include "hw/gpio.h" 21 | #include "hw/leds.h" 22 | #include "hw/sensors.h" 23 | #include "hw/signals.h" 24 | #include 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | void granular_sampler(int mode); 31 | int16_t add_echo(int16_t sample); 32 | void update_grain_freqs(float *freq, float *bases, int voices_used, int part); //part: 0=all 33 | 34 | #ifdef __cplusplus 35 | } 36 | #endif 37 | 38 | #endif /* EXTENSIONS_GRANULAR_H_ */ 39 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Mario 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 | -------------------------------------------------------------------------------- /src/Test_fn.h: -------------------------------------------------------------------------------- 1 | /* 2 | * test_fn.h 3 | * 4 | * Created on: Apr 27, 2016 5 | * Author: mayo 6 | */ 7 | 8 | #ifndef TEST_FN_H_ 9 | #define TEST_FN_H_ 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | extern Filters *fil; 16 | extern volatile uint32_t sampleCounter; 17 | extern uint32_t random_value; 18 | extern float sample_f[2],sample_synth[2],sample_mix; 19 | extern float volume2; 20 | extern volatile int16_t sample_i16; 21 | extern float noise_volume, noise_volume_max, noise_boost_by_sensor; 22 | 23 | #ifdef __cplusplus 24 | extern "C" { 25 | #endif 26 | 27 | void MAGNETIC_sensors_test(int sensor_value); 28 | 29 | #ifdef GORS 30 | void Goertzel_detectors_capture(int tones_to_find, int *found_tones, char *goertzel_octaves); 31 | void AutoCorrelation_capture(int tones_to_find, int *found_tones, int preamp_boost); 32 | void MagneticRing_capture(int tones_to_find, int *found_tones); 33 | #endif 34 | 35 | void Stylus_test(); 36 | int IR_remote_capture(); 37 | 38 | void check_battery_level(); 39 | 40 | void show_board_serial_no(); 41 | void show_firmware_version(); 42 | 43 | void acoustic_location_test(); 44 | void direct_buttons_LEDs_test(); 45 | 46 | #ifdef __cplusplus 47 | } 48 | #endif 49 | 50 | #endif /* TEST_FN_H_ */ 51 | -------------------------------------------------------------------------------- /src/dsp/Detectors.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Detectors.h 3 | * 4 | * Created on: Jun 30, 2016 5 | * Author: mayo 6 | */ 7 | 8 | #ifndef DETECTORS_H_ 9 | #define DETECTORS_H_ 10 | 11 | #include 12 | 13 | //detection of two octaves 14 | #define GORS 25 15 | #define GORS_FREQS_345 "c3,c#3,d3,d#3,e3,f3,f#3,g3,g#3,a3,a#3,b3,c4,c#4,d4,d#4,e4,f4,f#4,g4,g#4,a4,a#4,b4,c5" 16 | #define GORS_FREQS_456 "c4,c#4,d4,d#4,e4,f4,f#4,g4,g#4,a4,a#4,b4,c5,c#5,d5,d#5,e5,f5,f#5,g5,g#5,a5,a#5,b5,c6" 17 | #define GORS_FREQS_567 "c5,c#5,d5,d#5,e5,f5,f#5,g5,g#5,a5,a#5,b5,c6,c#6,d6,d#6,e6,f6,f#6,g6,g#6,a6,a#6,b6,c7" 18 | #define GORS_FREQS_678 "c6,c#6,d6,d#6,e6,f6,f#6,g6,g#6,a6,a#6,b6,c7,c#7,d7,d#7,e7,f7,f#7,g7,g#7,a7,a#7,b7,c8" 19 | 20 | #define GOERTZEL_OCTAVES_345 GORS_FREQS_345 21 | #define GOERTZEL_OCTAVES_456 GORS_FREQS_456 22 | #define GOERTZEL_OCTAVES_567 GORS_FREQS_567 23 | #define GOERTZEL_OCTAVES_678 GORS_FREQS_678 24 | 25 | class Detectors 26 | { 27 | public: 28 | 29 | Goertzel *gor; 30 | 31 | float *gors_freqs; 32 | char *gors_freq_notes; 33 | 34 | Detectors(char *goertzel_octaves); 35 | ~Detectors(void); 36 | 37 | void detectors_setup(int buffer_length); 38 | void process_sample(float sample); 39 | int find_max_freq(); 40 | void reset_all(); 41 | //void test_Goertzel_detectors(); 42 | 43 | private: 44 | 45 | }; 46 | 47 | #endif /* DETECTORS_H_ */ 48 | -------------------------------------------------------------------------------- /lib/CMSIS/Include/arm_common_tables.h: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------- 2 | * Copyright (C) 2010 ARM Limited. All rights reserved. 3 | * 4 | * $Date: 11. November 2010 5 | * $Revision: V1.0.2 6 | * 7 | * Project: CMSIS DSP Library 8 | * Title: arm_common_tables.h 9 | * 10 | * Description: This file has extern declaration for common tables like Bitreverse, reciprocal etc which are used across different functions 11 | * 12 | * Target Processor: Cortex-M4/Cortex-M3 13 | * 14 | * Version 1.0.2 2010/11/11 15 | * Documentation updated. 16 | * 17 | * Version 1.0.1 2010/10/05 18 | * Production release and review comments incorporated. 19 | * 20 | * Version 1.0.0 2010/09/20 21 | * Production release and review comments incorporated. 22 | * -------------------------------------------------------------------- */ 23 | 24 | #ifndef _ARM_COMMON_TABLES_H 25 | #define _ARM_COMMON_TABLES_H 26 | 27 | #include "arm_math.h" 28 | 29 | extern const uint16_t armBitRevTable[1024]; 30 | extern const q15_t armRecipTableQ15[64]; 31 | extern const q31_t armRecipTableQ31[64]; 32 | extern const q31_t realCoefAQ31[1024]; 33 | extern const q31_t realCoefBQ31[1024]; 34 | extern const float32_t twiddleCoef[6144]; 35 | extern const q31_t twiddleCoefQ31[6144]; 36 | extern const q15_t twiddleCoefQ15[6144]; 37 | 38 | #endif /* ARM_COMMON_TABLES_H */ 39 | -------------------------------------------------------------------------------- /src/main.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Gecho Loopsynth official firmware 3 | * 4 | * Created on: Apr 10, 2016 5 | * Author: mario (http://gechologic.com/contact) 6 | * 7 | * This file is part of the Gecho Loopsynth Firmware Development Framework. 8 | * It can be used within the terms of CC-BY-NC-SA license. 9 | * 10 | * Find more information at: http://gechologic.com/gechologists/ 11 | */ 12 | 13 | //Includes 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | 39 | //----------------------------------------------------------------------------------- 40 | 41 | volatile int16_t sample_i16 = 0; 42 | //volatile uint16_t sample_u16 = 0; 43 | 44 | Filters *fil; 45 | 46 | float sample_f[2],sample_mix; 47 | int16_t ADC_sample_recv; 48 | 49 | int run_program = 1; 50 | int tempo = 1; 51 | int chord = 0; 52 | 53 | //int MIDI_new_note = 0; 54 | //int MIDI_new_volume = 0; 55 | //int MIDI_new_note_freq = 0; 56 | //int MIDI_notes_to_freq[100]; 57 | -------------------------------------------------------------------------------- /src/MusicBox.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Chord.h 3 | * 4 | * Created on: May 30, 2016 5 | * Author: mayo 6 | */ 7 | 8 | #ifndef MUSICBOX_H_ 9 | #define MUSICBOX_H_ 10 | 11 | #include 12 | #include 13 | 14 | typedef struct { 15 | int tones; 16 | float *freqs = NULL; 17 | } CHORD; 18 | 19 | class MusicBox { 20 | public: 21 | MusicBox(int song); 22 | virtual ~MusicBox(); 23 | void generate(int max_voices); 24 | int get_song_total_chords(char *base_notes); 25 | int* get_current_chord_LED(); 26 | int get_current_melody_note(); 27 | float get_current_melody_freq(); 28 | static int get_song_total_melody_notes(char *melody); 29 | 30 | CHORD *chords = NULL; 31 | 32 | #define MAX_VOICES_PER_CHORD 9 //only 8 needed for 16 filters by default 33 | #define BASE_FREQS_PER_CHORD 3 34 | 35 | static const int expand_multipliers[MAX_VOICES_PER_CHORD][2]; 36 | 37 | char *base_notes = NULL; 38 | float *bases_parsed = NULL; 39 | int *led_indicators = NULL; 40 | 41 | float *melody_freqs_parsed = NULL; 42 | int *melody_indicator_leds = NULL; 43 | 44 | char *use_song; 45 | char *use_melody = NULL; 46 | 47 | //for sequential playback (test) 48 | int total_chords; //number of chors in whole song (default 8) 49 | int current_chord; //the chord that currently plays 50 | int total_melody_notes; //number of notes in melody string 51 | int current_melody_note; //the note that currently plays 52 | 53 | static const char *SONGS[]; 54 | char *XAOS_MELODY = NULL; //for dynamically created melody 55 | }; 56 | 57 | #endif /* MUSICBOX_H_ */ 58 | -------------------------------------------------------------------------------- /src/Channels.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Channels.h 3 | * 4 | * Created on: Nov 26, 2016 5 | * Author: mayo 6 | */ 7 | 8 | #ifndef CHANNELS_H_ 9 | #define CHANNELS_H_ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #define CHORDS_CAPTURE_BUTTONS 1 17 | #define CHORDS_CAPTURE_MAGNETIC_RING 2 18 | #define CHORDS_CAPTURE_MIC 3 19 | #define CHORDS_CAPTURE_PICKUPS 4 20 | 21 | #define CHANNEL_21_INTERACTIVE_NOISE_EFFECT 21 22 | #define CHANNEL_22_INTERACTIVE_NOISE_EFFECT 22 23 | #define CHANNEL_23_INTERACTIVE_NOISE_EFFECT 23 24 | #define CHANNEL_24_INTERACTIVE_NOISE_EFFECT 24 25 | 26 | #define CHANNEL_31_THEREMIN_BY_MAGNETIC_RING 31 27 | #define CHANNEL_32_THEREMIN_BY_IR_SENSORS 32 28 | #define CHANNEL_33_DCO_SYNTH_DIRECT 33 29 | #define CHANNEL_34_DCO_SYNTH_PROGRAMMABLE 34 30 | 31 | #define CHANNEL_111_RECENTLY_GENERATED_SONG 111 32 | #define CHANNEL_112_RECENTLY_GENERATED_SONG_W_MELODY 112 33 | #define CHANNEL_113_DIRECT_PLAY_BY_USART 113 34 | 35 | #define CHANNEL_222_GENERATE_SONG_FROM_NOISE 222 36 | 37 | extern uint64_t channel; 38 | 39 | extern char *melody_str; 40 | extern char *progression_str; 41 | extern int progression_str_length; 42 | extern char *settings_str; 43 | 44 | void custom_program_init(uint64_t prog); 45 | void custom_effect_init(uint64_t prog); 46 | void custom_effect_filter_process(); 47 | void alt_mode_hi_pass_with_water(); 48 | 49 | extern int mixed_sample_buffer_ptr_L, mixed_sample_buffer_ptr_R; 50 | extern int16_t *mixed_sample_buffer; 51 | extern int MIXED_SAMPLE_BUFFER_LENGTH; 52 | 53 | #endif /* CHANNELS_H_ */ 54 | -------------------------------------------------------------------------------- /src/notes.h: -------------------------------------------------------------------------------- 1 | /* 2 | * notes.h 3 | * 4 | * Created on: Oct 31, 2016 5 | * Author: mayo 6 | * 7 | * This file is part of the Gecho Loopsynth Firmware Development Framework. 8 | * It can be used within the terms of CC-BY-NC-SA license. 9 | * It must not be distributed separately. 10 | * 11 | * Find more information at: http://gechologic.com/gechologists/ 12 | */ 13 | 14 | #ifndef NOTES_H_ 15 | #define NOTES_H_ 16 | 17 | #define NOTE_FREQ_A4 440.0f //440Hz of A4 note as default for calculation 18 | #define HALFTONE_STEP_COEF (pow((double)2,(double)1/(double)12)) 19 | 20 | #define NOTES_PER_CHORD 3 21 | extern int *set_chords_map; 22 | extern int (*temp_song)[NOTES_PER_CHORD]; 23 | extern int temp_total_chords; 24 | 25 | extern char *progression_str; 26 | extern char *melody_str; 27 | extern char *settings_str; 28 | 29 | extern const float notes_freqs[13]; 30 | 31 | #ifdef __cplusplus 32 | extern "C" { 33 | #endif 34 | 35 | int encode_temp_song_to_notes(int (*song)[NOTES_PER_CHORD], int chords, char **dest_buffer); 36 | int tmp_song_find_note(int note, char *buffer); 37 | 38 | int translate_intervals_to_notes(char *buffer, char chord_code, char *fragment); 39 | int interval_to_note(char *buffer, int distance); 40 | 41 | void set_progression_str(char *chord_progression); 42 | void set_melody_str(char *melody); 43 | 44 | void notes_to_LEDs(int *notes, int *leds, int notes_per_chord); 45 | int parse_notes(char *base_notes_buf, float *bases_parsed_buf, int *led_indicators_buf); 46 | char *read_next_note(char *str, int *return_buffer); 47 | int spread_notes(float *sequence_notes, int seq_length, int multiplier); 48 | 49 | #ifdef __cplusplus 50 | } 51 | #endif 52 | 53 | #endif /* NOTES_H_ */ 54 | -------------------------------------------------------------------------------- /src/extensions/Drums.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Drums.h 3 | * 4 | * Created on: Nov 26, 2016 5 | * Author: mayo 6 | * 7 | * This file is part of the Gecho Loopsynth Firmware Development Framework. 8 | * It can be used within the terms of CC-BY-NC-SA license. 9 | * It must not be distributed separately. 10 | * 11 | * Find more information at: http://gechologic.com/gechologists/ 12 | */ 13 | 14 | #ifndef DRUMS_H_ 15 | #define DRUMS_H_ 16 | 17 | #define DRUM_BASE_ADDR1 0x080D2420 //base address where we uploaded samples 18 | #define DRUM_LENGTH1 17416 //length of first sample in bytes 19 | #define DRUM_BASE_ADDR2 (DRUM_BASE_ADDR1 + DRUM_LENGTH1) 20 | #define DRUM_LENGTH2 39104 21 | #define DRUM_BASE_ADDR3 (DRUM_BASE_ADDR2 + DRUM_LENGTH2) 22 | #define DRUM_LENGTH3 12416 23 | #define DRUM_BASE_ADDR4 (DRUM_BASE_ADDR3 + DRUM_LENGTH3) 24 | #define DRUM_LENGTH4 68310 25 | 26 | #define DRUM_SAMPLES 4 //we uploaded 4 samples to FLASH memory 27 | #define DRUM_CHANNELS_MAX 4 //no real polyphony for now, just one of each samples at the time 28 | 29 | #define DRUM_SENSOR_THRESHOLD(x) ((x==0||x==3)?600:300) //how far from the sensor to flip trigger, inner sensors more sensitive 30 | #define DRUM_SAMPLE_VOLUME 0.19f //general adjustment volume for samples we used 31 | 32 | extern int drum_samples_ptr[DRUM_CHANNELS_MAX]; //pointers for currently playing sample 33 | extern int drum_trigger[DRUM_CHANNELS_MAX]; //triggers for execution of each drum 34 | extern int drum_lengths[DRUM_SAMPLES]; //lengths of samples in bytes 35 | extern int drum_bases[DRUM_SAMPLES]; //base addresses of samples 36 | 37 | 38 | #include //for uint16_t type 39 | 40 | #ifdef __cplusplus 41 | extern "C" { 42 | #endif 43 | 44 | uint16_t drum_kit_process(); 45 | uint16_t drum_kit_process_cv_trigger(); 46 | 47 | #ifdef __cplusplus 48 | } 49 | #endif 50 | 51 | #endif /* DRUMS_H_ */ 52 | -------------------------------------------------------------------------------- /src/dsp/Goertzel.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Goertzel.cpp 3 | * 4 | * Created on: Jun 29, 2016 5 | * Author: mayo 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | Goertzel::Goertzel() { 13 | // TODO Auto-generated constructor stub 14 | 15 | } 16 | 17 | Goertzel::~Goertzel() { 18 | // TODO Auto-generated destructor stub 19 | } 20 | 21 | /* Call this routine before every "block" (size=N) of samples. */ 22 | void Goertzel::reset() 23 | { 24 | Q2 = 0; 25 | Q1 = 0; 26 | } 27 | 28 | /* Call this once, to precompute the constants. */ 29 | void Goertzel::init(float TARGET_FREQUENCY, int N) //N=block size 30 | { 31 | int k; 32 | float floatN; 33 | float omega; 34 | 35 | floatN = (float) N; 36 | k = (int) (0.5 + ((floatN * TARGET_FREQUENCY) / SAMPLING_RATE)); 37 | omega = (2.0 * M_PI * k) / floatN; 38 | sine = sin(omega); 39 | cosine = cos(omega); 40 | coeff = 2.0 * cosine; 41 | 42 | //printf("For SAMPLING_RATE = %f", SAMPLING_RATE); 43 | //printf(" N = %d", N); 44 | //printf(" and FREQUENCY = %f,\n", TARGET_FREQUENCY); 45 | //printf("k = %d and coeff = %f\n\n", k, coeff); 46 | 47 | reset(); 48 | } 49 | 50 | /* Call this routine for every sample. */ 51 | void Goertzel::process_sample(uint16_t sample) 52 | { 53 | float Q0; 54 | Q0 = coeff * Q1 - Q2 + (float) sample; 55 | Q2 = Q1; 56 | Q1 = Q0; 57 | } 58 | 59 | /* Basic Goertzel */ 60 | /* Call this routine after every block to get the complex result. */ 61 | void Goertzel::get_real_imag(float *realPart, float *imagPart) 62 | { 63 | *realPart = (Q1 - Q2 * cosine); 64 | *imagPart = (Q2 * sine); 65 | } 66 | 67 | /* Optimized Goertzel */ 68 | /* Call this after every block to get the RELATIVE magnitude squared. */ 69 | float Goertzel::get_magnitude_squared(void) 70 | { 71 | float result; 72 | 73 | result = Q1 * Q1 + Q2 * Q2 - Q1 * Q2 * coeff; 74 | return result; 75 | } 76 | -------------------------------------------------------------------------------- /src/dsp/Filters.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Filters.h 3 | * 4 | * Created on: Apr 27, 2016 5 | * Author: mayo 6 | * 7 | * This file is part of the Gecho Loopsynth Firmware Development Framework. 8 | * It can be used within the terms of CC-BY-NC-SA license. 9 | * It must not be distributed separately. 10 | * 11 | * Find more information at: http://gechologic.com/gechologists/ 12 | */ 13 | 14 | #ifndef FILTERS_H_ 15 | #define FILTERS_H_ 16 | 17 | #include "IIR_filters.h" 18 | #include 19 | #include 20 | #include 21 | 22 | #define FILTERS (FILTER_PAIRS*2) 23 | #define ACCORD MINOR 24 | 25 | #define CHORD_MAX_VOICES (FILTERS/2) //two channels per voice 26 | #define FILTERS_FREQ_CORRECTION 1.035 27 | #define MELODY_MIXING_VOLUME 2.5f 28 | 29 | typedef struct { 30 | 31 | float volume_coef,volume_f,resonance; 32 | float mixing_volumes[FILTERS]; 33 | 34 | int melody_filter_pair; //between 0 and CHORD_MAX_VOICES 35 | int arpeggiator_filter_pair; //between 0 and CHORD_MAX_VOICES 36 | 37 | } FILTERS_PARAMS; 38 | 39 | class Filters 40 | { 41 | public: 42 | 43 | IIR_Filter *iir2 = NULL; 44 | FILTERS_PARAMS fp; 45 | MusicBox *chord; 46 | 47 | Filters(int selected_song); 48 | ~Filters(void); 49 | 50 | void setup(); 51 | void setup(int filters_type_and_order); 52 | 53 | //void start_update_filters(int f1, int f2, int f3, int f4, float freq1, float freq2, float freq3, float freq4); 54 | void start_update_filters_pairs(int *filter_n, float *freq, int filters_to_update); 55 | void start_next_chord(); 56 | void start_next_melody_note(); 57 | void progress_update_filters(Filters *fil, bool reset_buffers); 58 | void start_nth_chord(int chord_n); 59 | void set_melody_voice(int filter_pair, int melody_id); 60 | void add_to_update_filters_pairs(int filter_n, float freq); 61 | 62 | private: 63 | 64 | int update_filters_f[CHORD_MAX_VOICES*2 + 2]; //also two spaces for updating melody 65 | float update_filters_freq[CHORD_MAX_VOICES*2 + 2]; //also two spaces for updating melody 66 | int update_filters_loop; 67 | }; 68 | 69 | #endif /* FILTERS_H_ */ 70 | -------------------------------------------------------------------------------- /src/hw/eeprom.h: -------------------------------------------------------------------------------- 1 | /* 2 | * eeprom.h 3 | * 4 | * Created on: Jul 14, 2016 5 | * Author: mayo 6 | */ 7 | 8 | #ifndef EEPROM_H_ 9 | #define EEPROM_H_ 10 | 11 | #include "stm32f4xx.h" 12 | 13 | #ifdef __cplusplus 14 | extern "C" { 15 | #endif 16 | 17 | #define SETTINGS_BASE (BKPSRAM_BASE + 4000) 18 | #define SETTINGS_RESERVED_LENGTH 64 19 | 20 | #define BKPSRAM_TEST_BASE (SETTINGS_BASE + SETTINGS_RESERVED_LENGTH) //test space at the very end, after settings space 21 | #define BKPSRAM_TEST_LENGTH 32 22 | 23 | #define SONG_STORED_ID (char *) (BKPSRAM_BASE+128) 24 | #define SONG_STORED_DATA (char *) (BKPSRAM_BASE+128+16) 25 | #define MELODY_STORED_ID (char *) (BKPSRAM_BASE+2048) 26 | #define MELODY_STORED_DATA (char *) (BKPSRAM_BASE+2048+16) 27 | 28 | #define SETTINGS_MAIN_VOLUME (SETTINGS_BASE + 8) //after the "SETTINGS" string 29 | #define SETTINGS_DELAY_LENGTH (SETTINGS_BASE + 9) 30 | #define SETTINGS_INPUT_SELECT (SETTINGS_BASE + 10) 31 | #define SETTINGS_EQ_BASS (SETTINGS_BASE + 11) 32 | //#define SETTINGS_EQ_TREBLE (SETTINGS_BASE + 12) 33 | #define SETTINGS_EQ_TREBLE (SETTINGS_BASE + 13) 34 | #define SETTINGS_INPUT_GAIN (SETTINGS_BASE + 14) //length = 4Bytes 35 | #define SETTINGS_CODEC_VOLUME (SETTINGS_BASE + 18) //length = 2Bytes 36 | 37 | #define SETTINGS_WAVETABLE_SAMPLE (SETTINGS_BASE + 20) //length = 1Byte 38 | #define SETTINGS_TEMPO_BPM (SETTINGS_BASE + 22) //length = 2Bytes 39 | 40 | void EEPROM_Init(); 41 | void EEPROM_Test(); 42 | void EEPROM_LoadSongAndMelody(char **song_buffer, char **melody_buffer); 43 | void EEPROM_StoreSongAndMelody(char *song_buffer, char *melody_buffer); 44 | 45 | void EEPROM_StoreSettings_B(uint32_t settings_position,uint8_t value); 46 | void EEPROM_StoreSettings_W(uint32_t settings_position,uint16_t value); 47 | void EEPROM_StoreSettings_DW(uint32_t settings_position,uint32_t value); 48 | uint8_t EEPROM_LoadSettings_B(uint32_t settings_position,uint8_t default_value); 49 | uint16_t EEPROM_LoadSettings_W(uint32_t settings_position,uint16_t default_value); 50 | uint32_t EEPROM_LoadSettings_DW(uint32_t settings_position); 51 | void EEPROM_ClearSettings(); 52 | 53 | #ifdef __cplusplus 54 | } 55 | #endif 56 | 57 | #endif /* EEPROM_H_ */ 58 | -------------------------------------------------------------------------------- /src/hw/stm32f4xx_it.h: -------------------------------------------------------------------------------- 1 | /** 2 | ***************************************************************************** 3 | ** 4 | ** File : stm32f4xx_it.h 5 | ** 6 | ** Abstract : Main Interrupt Service Routines. 7 | ** This file provides template for all exceptions handler and 8 | ** peripherals interrupt service routine. 9 | ** 10 | ** Environment : Atollic TrueSTUDIO(R) 11 | ** STMicroelectronics STM32F4xx Standard Peripherals Library 12 | ** 13 | ** Distribution: The file is distributed "as is", without any warranty 14 | ** of any kind. 15 | ** 16 | ** (c)Copyright Atollic AB. 17 | ** You may use this file as-is or modify it according to the needs of your 18 | ** project. This file may only be built (assembled or compiled and linked) 19 | ** using the Atollic TrueSTUDIO(R) product. The use of this file together 20 | ** with other tools than Atollic TrueSTUDIO(R) is not permitted. 21 | ** 22 | ***************************************************************************** 23 | */ 24 | 25 | /* Define to prevent recursive inclusion -------------------------------------*/ 26 | #ifndef __STM32F4xx_IT_H 27 | #define __STM32F4xx_IT_H 28 | 29 | #ifdef __cplusplus 30 | extern "C" { 31 | #endif 32 | 33 | /* Includes ------------------------------------------------------------------*/ 34 | #include "stm32f4xx.h" 35 | 36 | /* Exported types ------------------------------------------------------------*/ 37 | /* Exported constants --------------------------------------------------------*/ 38 | /* Exported macro ------------------------------------------------------------*/ 39 | 40 | /* Exported functions ------------------------------------------------------- */ 41 | 42 | //uint32_t get_sys_clock(); 43 | uint32_t get_micros(); 44 | uint32_t get_millis(); 45 | 46 | void NMI_Handler(void); 47 | void HardFault_Handler(void); 48 | void MemManage_Handler(void); 49 | void BusFault_Handler(void); 50 | void UsageFault_Handler(void); 51 | void SVC_Handler(void); 52 | void DebugMon_Handler(void); 53 | void PendSV_Handler(void); 54 | void SysTick_Handler(void); 55 | 56 | #ifdef __cplusplus 57 | } 58 | #endif 59 | 60 | #endif /* __STM32F4xx_IT_H */ 61 | -------------------------------------------------------------------------------- /src/extensions/MIDI.c: -------------------------------------------------------------------------------- 1 | /* 2 | * MIDI.c 3 | * 4 | * Created on: Jan 9, 2017 5 | * Author: mayo 6 | * 7 | * This file is part of the Gecho Loopsynth Firmware Development Framework. 8 | * It can be used within the terms of CC-BY-NC-SA license. 9 | * It must not be distributed separately. 10 | * 11 | * Find more information at: http://gechologic.com/gechologists/ 12 | */ 13 | 14 | #include "MIDI.h" 15 | #include 16 | #include 17 | 18 | int MIDI_notes_to_freq[128]; 19 | 20 | void MIDI_out_test() 21 | { 22 | while(1) 23 | { 24 | for(int i=36;i<=72;i++) 25 | { 26 | USART_SendData(USART3, 144); //new note 27 | Delay(1); 28 | USART_SendData(USART3,i); //note value 29 | Delay(1); 30 | USART_SendData(USART3, 64); //velocity 31 | Delay(1900); 32 | 33 | USART_SendData(USART3, 128); //new note 34 | Delay(1); 35 | USART_SendData(USART3, i); //note value 36 | Delay(1); 37 | USART_SendData(USART3, 64); //velocity 38 | Delay(96); 39 | } 40 | } 41 | } 42 | 43 | void MIDI_record_playback_test() 44 | { 45 | int MIDI_new_note = 0; 46 | //int MIDI_new_volume = 0; 47 | //int MIDI_new_note_freq = 0; 48 | //int MIDI_notes_to_freq[100]; 49 | 50 | while(1) 51 | { 52 | if(USART_GetFlagStatus(USART3, USART_FLAG_RXNE)) 53 | { 54 | // Read received char 55 | int data = USART_ReceiveData(USART3); 56 | if(data!=248 && data!=254) 57 | { 58 | if(data!=144) 59 | { 60 | if(MIDI_new_note==0) 61 | { 62 | MIDI_new_note = data; 63 | LED_R8_set_byte(data); 64 | LED_B5_1_ON; 65 | Delay(20); 66 | LED_B5_1_OFF; 67 | } 68 | } 69 | } 70 | else 71 | { 72 | MIDI_new_note = 0; 73 | LED_B5_0_ON; 74 | Delay(20); 75 | LED_B5_0_OFF; 76 | } 77 | } 78 | } 79 | } 80 | 81 | void MIDI_direct_signals_test() 82 | { 83 | while (1) 84 | { 85 | if (USART3_RX) 86 | { 87 | LED_O4_2_ON; 88 | } 89 | else 90 | { 91 | LED_O4_2_OFF; 92 | } 93 | 94 | if (BUTTON_U1_ON) 95 | { 96 | LED_O4_0_ON; //USART3_TX_ON; 97 | } 98 | else 99 | { 100 | LED_O4_0_OFF; //USART3_TX_OFF; 101 | } 102 | 103 | Delay(50); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /src/hw/sensors.h: -------------------------------------------------------------------------------- 1 | /* 2 | * sensors.h 3 | * 4 | * Created on: Jun 21, 2016 5 | * Author: mayo 6 | */ 7 | 8 | #ifndef SENSORS_H_ 9 | #define SENSORS_H_ 10 | 11 | #include 12 | #include "stm32f4xx_adc.h" 13 | 14 | #define USE_IR_SENSORS 15 | 16 | #define IR_sensors_THRESHOLD_1 150 17 | #define IR_sensors_THRESHOLD_2 250 18 | #define IR_sensors_THRESHOLD_3 350 19 | #define IR_sensors_THRESHOLD_4 450 20 | #define IR_sensors_THRESHOLD_5 600 21 | #define IR_sensors_THRESHOLD_6 800 22 | #define IR_sensors_THRESHOLD_7 1000 23 | #define IR_sensors_THRESHOLD_8 1200 24 | #define IR_sensors_THRESHOLD_9 2000 25 | 26 | //STM32F4_DISC1 27 | //#define LED_IR_DETECTORS_ON GPIOA->BSRRL = GPIO_Pin_3; 28 | //#define LED_IR_DETECTORS_OFF GPIOA->BSRRH = GPIO_Pin_3; 29 | 30 | #ifdef BOARD_GECHO_V001 31 | 32 | //Gecho V0.01 - PA1 - problematic 33 | #define LED_IR_DETECTORS_ON GPIOA->BSRRL = GPIO_Pin_1; 34 | #define LED_IR_DETECTORS_OFF GPIOA->BSRRH = GPIO_Pin_1; 35 | 36 | //PA0 - rattling test #2 37 | //#define LED_IR_DETECTORS_ON GPIOA->BSRRL = GPIO_Pin_0; 38 | //#define LED_IR_DETECTORS_OFF GPIOA->BSRRH = GPIO_Pin_0; 39 | 40 | //Rattling test #3 via PB14 41 | //#define LED_IR_DETECTORS_ON GPIOB->BSRRL = GPIO_Pin_14; 42 | //#define LED_IR_DETECTORS_OFF GPIOB->BSRRH = GPIO_Pin_14; 43 | 44 | //PD2 - alternative test - wired to But2 45 | //#define LED_IR_DETECTORS_ON GPIOD->BSRRL = GPIO_Pin_2; 46 | //#define LED_IR_DETECTORS_OFF GPIOD->BSRRH = GPIO_Pin_2; 47 | 48 | #endif 49 | 50 | #ifdef BOARD_GECHO_V002 51 | #define LED_IR_DETECTORS_ON GPIOB->BSRRL = GPIO_Pin_15; 52 | #define LED_IR_DETECTORS_OFF GPIOB->BSRRH = GPIO_Pin_15; 53 | #endif 54 | 55 | #define CLEAR_ADC_RESULT_RDY_FLAG ADC_result_ready = 0; 56 | 57 | #ifdef __cplusplus 58 | extern "C" { 59 | #endif 60 | 61 | //distance sensors 62 | extern int adc3_val1, adc3_val2, adc3_diff, adc3_sum, adc3_cnt; 63 | extern volatile uint16_t ADCConvertedValues[]; 64 | 65 | extern uint16_t ADC_measured_vals[]; 66 | extern int ADC_last_result[]; 67 | extern int ADC_result_ready; 68 | extern int ADC_measured_vals_updated; 69 | 70 | extern int sensors_loop; 71 | 72 | // -------------------------------------- 73 | 74 | int ADC_process_sensors(); 75 | void ADC_test_SENSORS(); 76 | 77 | #ifdef __cplusplus 78 | } 79 | #endif 80 | 81 | #endif /* SENSORS_H_ */ 82 | -------------------------------------------------------------------------------- /src/songs.c: -------------------------------------------------------------------------------- 1 | /* 2 | * songs.c 3 | * 4 | * Created on: May 30, 2016 5 | * Author: mayo 6 | * 7 | * This file is part of the Gecho Loopsynth Firmware Development Framework. 8 | * It can be used within the terms of CC-BY-NC-SA license. 9 | * It must not be distributed separately. 10 | * 11 | * Find more information at: http://gechologic.com/gechologists/ 12 | */ 13 | 14 | #include "songs.h" 15 | #include 16 | //#include 17 | //#include 18 | //#include 19 | //#include 20 | //#include 21 | 22 | //returns selected song and melody encoded as one int value (song + 1000 * melody) 23 | int channel_to_song_and_melody(int channel) 24 | { 25 | int selected_song = 0, selected_melody = 0; 26 | 27 | //look up if channel overridden in FLASH user-content sector 28 | 29 | 30 | //if not found in FLASH user-content sector, fall back to hard-coded mapping 31 | if (channel <= 4) 32 | { 33 | selected_song = channel; 34 | selected_melody = 0; 35 | 36 | if (selected_song == 1) //song #1 with melody and hi-pass filters 37 | { 38 | selected_song = 1; 39 | selected_melody = 1; 40 | } 41 | if (selected_song == 2) //song #2 with melody (epic ad) 42 | { 43 | selected_song = 2; 44 | selected_melody = 2; 45 | } 46 | if (selected_song == 3) //pick random one out of basic songs and play it with low-pass filters 47 | { 48 | new_random_value(); 49 | 50 | if(random_value % 5 == 0) 51 | { 52 | selected_song = 11; 53 | } 54 | else if(random_value % 5 == 1) 55 | { 56 | selected_song = 12; 57 | } 58 | else if(random_value % 5 == 2) 59 | { 60 | selected_song = 13; 61 | } 62 | else if(random_value % 5 == 3) 63 | { 64 | selected_song = 22; 65 | } 66 | else if(random_value % 5 == 4) 67 | { 68 | selected_song = 23; 69 | } 70 | } 71 | if (selected_song == 4) //override - song #21 (GITS) 72 | { 73 | selected_song = 21; 74 | } 75 | } 76 | if (channel >= 4111 && channel <= 4144) 77 | { 78 | selected_song = channel % 100; //songs 11-44 79 | selected_melody = 0; 80 | 81 | if(selected_song == 14 || selected_song == 21) 82 | { 83 | selected_melody = selected_song; 84 | } 85 | } 86 | /* 87 | if(channel==111 || channel==112) 88 | { 89 | selected_song = 111; 90 | selected_melody = 112; 91 | } 92 | */ 93 | return selected_song + 1000 * selected_melody; 94 | } 95 | -------------------------------------------------------------------------------- /src/hw/controls.h: -------------------------------------------------------------------------------- 1 | /* 2 | * controls.h 3 | * 4 | * Created on: Sep 24, 2016 5 | * Author: mayo 6 | * 7 | * This file is part of the Gecho Loopsynth Firmware Development Framework. 8 | * It can be used within the terms of CC-BY-NC-SA license. 9 | * It must not be distributed separately. 10 | * 11 | * Find more information at: http://gechologic.com/gechologists/ 12 | */ 13 | 14 | #ifndef CONTROLS_H_ 15 | #define CONTROLS_H_ 16 | 17 | #include "codec.h" 18 | #include "stdbool.h" 19 | 20 | //click 21 | #define ADC_SENSOR_THRESHOLD 400 22 | #define ADC_SENSOR_CLICK_LOOP_DELAY 5 23 | 24 | //gesture 25 | #define ADC_SENSOR_THRESHOLD_DIFF 10 26 | #define ADC_SENSOR_GESTURE_LOOP_DELAY 20 27 | #define ADC_SENSOR_GESTURE_INIT_DELAY 5 28 | 29 | #define USER_BUTTONS_N 4 30 | #define USER_BUTTONS_DEBOUNCE 5 //limit for "pressed" state counter, until button is considered pressed 31 | #define SCAN_BUTTONS_LOOP_DELAY 10 //buttons are scanned each 10ms 32 | #define PWR_BUTTON_THRESHOLD_1 10 //SCAN_BUTTONS_LOOP_DELAY * x ms -> 100ms 33 | #define PWR_BUTTON_THRESHOLD_2 100 //SCAN_BUTTONS_LOOP_DELAY * x ms -> 1 sec 34 | #define PWR_BUTTON_THRESHOLD_3 300 //SCAN_BUTTONS_LOOP_DELAY * x ms -> 3 sec 35 | 36 | #define PRESS_ORDER_MAX 19 //maximum lenght of main-menu buttons sequence to parse 37 | 38 | extern const char *BINARY_ID; 39 | extern const char *FW_VERSION; 40 | 41 | #define UID_BASE_ADDRESS 0x1FFF7A10 //location of MCU's factory-programmed unique ID 42 | #define CODE_CHALLENGE_KEY "ouroboros_of_the_sound" 43 | 44 | extern int mode_set_flag; 45 | extern bool PROG_wavetable_sample; 46 | extern bool PROG_audio_input_microphones; 47 | extern bool PROG_add_OpAmp_ADC12_signal; 48 | extern bool PROG_mix_input_signal; 49 | 50 | 51 | #define FILTER_PAIRS 8 //default number of filter pairs 52 | extern int ACTIVE_FILTERS_PAIRS; 53 | 54 | #ifdef __cplusplus 55 | extern "C" { 56 | #endif 57 | 58 | uint64_t select_channel(); 59 | uint64_t get_user_buttons_sequence(int *press_order_ptr, int *press_order); 60 | 61 | int preview_composition(char *data); 62 | 63 | int scan_buttons(); 64 | void user_button_pressed(int button, int *binary_status_O4, int *press_order_ptr, int *press_order); 65 | void buttons_controls_during_play(); 66 | 67 | //int wait_for_gesture(); 68 | //int wait_for_sensor_click(); 69 | 70 | void l33tsp34k(char *buffer, int buf_length); 71 | void string_to_14(char *buffer, int buf_length); 72 | void sha1_to_hex(char *code_sha1_hex, uint8_t *code_sha1); 73 | int verify_activation_unlock_code(char *code); 74 | void send_activation_info_USART(); 75 | 76 | #ifdef __cplusplus 77 | } 78 | #endif 79 | 80 | #endif /* CONTROLS_H_ */ 81 | -------------------------------------------------------------------------------- /.settings/language.settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /lib/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_crc.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file stm32f4xx_crc.h 4 | * @author MCD Application Team 5 | * @version V1.1.0 6 | * @date 11-January-2013 7 | * @brief This file contains all the functions prototypes for the CRC firmware 8 | * library. 9 | ****************************************************************************** 10 | * @attention 11 | * 12 | *

© COPYRIGHT 2013 STMicroelectronics

13 | * 14 | * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); 15 | * You may not use this file except in compliance with the License. 16 | * You may obtain a copy of the License at: 17 | * 18 | * http://www.st.com/software_license_agreement_liberty_v2 19 | * 20 | * Unless required by applicable law or agreed to in writing, software 21 | * distributed under the License is distributed on an "AS IS" BASIS, 22 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 23 | * See the License for the specific language governing permissions and 24 | * limitations under the License. 25 | * 26 | ****************************************************************************** 27 | */ 28 | 29 | /* Define to prevent recursive inclusion -------------------------------------*/ 30 | #ifndef __STM32F4xx_CRC_H 31 | #define __STM32F4xx_CRC_H 32 | 33 | #ifdef __cplusplus 34 | extern "C" { 35 | #endif 36 | 37 | /* Includes ------------------------------------------------------------------*/ 38 | #include "stm32f4xx.h" 39 | 40 | /** @addtogroup STM32F4xx_StdPeriph_Driver 41 | * @{ 42 | */ 43 | 44 | /** @addtogroup CRC 45 | * @{ 46 | */ 47 | 48 | /* Exported types ------------------------------------------------------------*/ 49 | /* Exported constants --------------------------------------------------------*/ 50 | 51 | /** @defgroup CRC_Exported_Constants 52 | * @{ 53 | */ 54 | 55 | /** 56 | * @} 57 | */ 58 | 59 | /* Exported macro ------------------------------------------------------------*/ 60 | /* Exported functions --------------------------------------------------------*/ 61 | 62 | void CRC_ResetDR(void); 63 | uint32_t CRC_CalcCRC(uint32_t Data); 64 | uint32_t CRC_CalcBlockCRC(uint32_t pBuffer[], uint32_t BufferLength); 65 | uint32_t CRC_GetCRC(void); 66 | void CRC_SetIDRegister(uint8_t IDValue); 67 | uint8_t CRC_GetIDRegister(void); 68 | 69 | #ifdef __cplusplus 70 | } 71 | #endif 72 | 73 | #endif /* __STM32F4xx_CRC_H */ 74 | 75 | /** 76 | * @} 77 | */ 78 | 79 | /** 80 | * @} 81 | */ 82 | 83 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 84 | -------------------------------------------------------------------------------- /lib/Device/STM32F4xx/Include/system_stm32f4xx.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file system_stm32f4xx.h 4 | * @author MCD Application Team 5 | * @version V1.1.0 6 | * @date 11-January-2013 7 | * @brief CMSIS Cortex-M4 Device System Source File for STM32F4xx devices. 8 | ****************************************************************************** 9 | * @attention 10 | * 11 | *

© COPYRIGHT 2013 STMicroelectronics

12 | * 13 | * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); 14 | * You may not use this file except in compliance with the License. 15 | * You may obtain a copy of the License at: 16 | * 17 | * http://www.st.com/software_license_agreement_liberty_v2 18 | * 19 | * Unless required by applicable law or agreed to in writing, software 20 | * distributed under the License is distributed on an "AS IS" BASIS, 21 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 22 | * See the License for the specific language governing permissions and 23 | * limitations under the License. 24 | * 25 | ****************************************************************************** 26 | */ 27 | 28 | /** @addtogroup CMSIS 29 | * @{ 30 | */ 31 | 32 | /** @addtogroup stm32f4xx_system 33 | * @{ 34 | */ 35 | 36 | /** 37 | * @brief Define to prevent recursive inclusion 38 | */ 39 | #ifndef __SYSTEM_STM32F4XX_H 40 | #define __SYSTEM_STM32F4XX_H 41 | 42 | #ifdef __cplusplus 43 | extern "C" { 44 | #endif 45 | 46 | /** @addtogroup STM32F4xx_System_Includes 47 | * @{ 48 | */ 49 | 50 | /** 51 | * @} 52 | */ 53 | 54 | 55 | /** @addtogroup STM32F4xx_System_Exported_types 56 | * @{ 57 | */ 58 | 59 | extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ 60 | 61 | 62 | /** 63 | * @} 64 | */ 65 | 66 | /** @addtogroup STM32F4xx_System_Exported_Constants 67 | * @{ 68 | */ 69 | 70 | /** 71 | * @} 72 | */ 73 | 74 | /** @addtogroup STM32F4xx_System_Exported_Macros 75 | * @{ 76 | */ 77 | 78 | /** 79 | * @} 80 | */ 81 | 82 | /** @addtogroup STM32F4xx_System_Exported_Functions 83 | * @{ 84 | */ 85 | 86 | extern void SystemInit(void); 87 | extern void SystemCoreClockUpdate(void); 88 | /** 89 | * @} 90 | */ 91 | 92 | #ifdef __cplusplus 93 | } 94 | #endif 95 | 96 | #endif /*__SYSTEM_STM32F4XX_H */ 97 | 98 | /** 99 | * @} 100 | */ 101 | 102 | /** 103 | * @} 104 | */ 105 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 106 | -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Gecho Loopsynth official firmware 3 | * 4 | * Created on: Apr 10, 2016 5 | * Author: mario (http://gechologic.com/contact) 6 | * 7 | * This file is part of the Gecho Loopsynth Firmware Development Framework. 8 | * It can be used within the terms of CC-BY-NC-SA license. 9 | * 10 | * Find more information at: http://gechologic.com/gechologists/ 11 | */ 12 | 13 | #include "main.h" 14 | 15 | //#define DIRECT_BUTTONS_LEDS_TEST //useful when assembling master DIY kit 16 | 17 | int main(void) 18 | { 19 | SystemInit(); 20 | FlashAcceleratorInit(); 21 | 22 | SysTick_Config(168000000/1000); //each 1000ms 23 | 24 | EEPROM_Init(); 25 | //EEPROM_LoadSongAndMelody(&progression_str, &melody_str); 26 | EEPROM_Test(); 27 | 28 | #ifdef CAN_BLOCK_SWD_DEBUG 29 | GPIO_Init_all(true); 30 | #else 31 | GPIO_Init_all(false); 32 | #endif 33 | 34 | //------------------------------------------------------------ 35 | 36 | //check_battery_level(); //TODO: add an option to disable this 37 | 38 | while(1) //select channel loop 39 | { 40 | GPIO_LEDs_Buttons_Reset(); 41 | program_settings_reset(); 42 | 43 | 44 | #ifdef DIRECT_BUTTONS_LEDS_TEST 45 | direct_buttons_LEDs_test(); 46 | #endif 47 | 48 | codec_init(); //audio codec - init but keep off (RESET -> LOW) 49 | 50 | #ifndef CODEC_COMM_BLINK_TEST 51 | 52 | #ifdef DIRECT_PROGRAM_START 53 | channel = DIRECT_PROGRAM_START; 54 | LED_RDY_ON; //set RDY so the sensors will work later 55 | #else 56 | channel = select_channel(); 57 | #endif 58 | 59 | #endif 60 | 61 | #ifdef CODEC_COMM_BLINK_TEST 62 | codec_comm_blink_test(1); 63 | #endif 64 | 65 | #ifdef CODEC_TLV 66 | codec_ctrl_init_TLV(); //new v2 boards - TLV320AIC3104 67 | #else 68 | codec_ctrl_init(); //audio codec - release reset, init controller 69 | #endif 70 | 71 | #ifdef CODEC_COMM_BLINK_TEST 72 | codec_comm_blink_test(2); 73 | while(1); 74 | #endif 75 | 76 | I2S_Cmd(CODEC_I2S, ENABLE); 77 | 78 | #ifdef CODEC_TLV 79 | /* Enable the I2Sx_ext peripheral for Full Duplex mode */ 80 | I2S_Cmd(CODEC_I2SEXT, ENABLE); 81 | #endif 82 | 83 | //if(channel==11111) 84 | //{ 85 | //legacy_reference_low_pass(); 86 | //} 87 | 88 | custom_program_init(channel); 89 | filters_and_signals_init(); 90 | custom_effect_init(channel); 91 | 92 | //float smx0=-1000000, smx1=1000000; 93 | //uint16_t si0=0, si1=0xffff; 94 | 95 | if(loop_type > 0) 96 | { 97 | audio_loop_no_filters(); 98 | } 99 | else 100 | { 101 | audio_loop_filters(); 102 | } 103 | 104 | //release some allocated memory 105 | if(fil != NULL) 106 | { 107 | delete(fil); 108 | fil = NULL; 109 | } 110 | 111 | } //select program loop 112 | } 113 | -------------------------------------------------------------------------------- /src/hw/flash.h: -------------------------------------------------------------------------------- 1 | /* 2 | * flash.h 3 | * 4 | * Created on: Oct 7, 2017 5 | * Author: mayo 6 | */ 7 | 8 | #ifndef FLASH_H_ 9 | #define FLASH_H_ 10 | 11 | #include "stm32f4xx.h" 12 | #include 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif 17 | 18 | #define COMPILE_PRODUCTION 19 | 20 | #ifdef COMPILE_PRODUCTION 21 | //production, when code <128k 22 | #define SECTOR_BASE 0x08020000 23 | #define SECTOR_LENGTH 0x20000 //128kB 24 | #define SECTOR_ID FLASH_Sector_5 25 | #define FLASH_VOLTAGE_RANGE VoltageRange_3 26 | 27 | #else 28 | 29 | //debug, when code >128k 30 | #define SECTOR_BASE 0x08040000 31 | #define SECTOR_LENGTH 0x20000 //128kB 32 | #define SECTOR_ID FLASH_Sector_6 33 | #define FLASH_VOLTAGE_RANGE VoltageRange_3 34 | 35 | #endif 36 | 37 | #define FLASH_CONTENT_MAP_SIZE 8192 //reserved space - should be enough for all user custom songs in overriddable channels 38 | 39 | #define ACTIVATION_LOCK_ADDRESS (SECTOR_BASE+1337*16) 40 | #define ACTIVATION_LOCK_DWORD ((uint64_t)0xdeadbeefc0de10cc) 41 | 42 | #define OVERRIDABLE_CHANNELS 85 43 | static const int overridable_channels[OVERRIDABLE_CHANNELS] = { 44 | 1, 45 | 2, 46 | 3, 47 | 4, 48 | 111, 49 | 3411, 50 | 3412, 51 | 3413, 52 | 3414, 53 | 3421, 54 | 3422, 55 | 3423, 56 | 3424, 57 | 3431, 58 | 3432, 59 | 3433, 60 | 3434, 61 | 3441, 62 | 3442, 63 | 3443, 64 | 3444, 65 | 4111, 66 | 4112, 67 | 4113, 68 | 4114, 69 | 4121, 70 | 4122, 71 | 4123, 72 | 4124, 73 | 4131, 74 | 4132, 75 | 4133, 76 | 4134, 77 | 4141, 78 | 4142, 79 | 4143, 80 | 4144, 81 | 4211, 82 | 4212, 83 | 4213, 84 | 4214, 85 | 4221, 86 | 4222, 87 | 4223, 88 | 4224, 89 | 4231, 90 | 4232, 91 | 4233, 92 | 4234, 93 | 4241, 94 | 4242, 95 | 4243, 96 | 4244, 97 | 4311, 98 | 4312, 99 | 4313, 100 | 4314, 101 | 4321, 102 | 4322, 103 | 4323, 104 | 4324, 105 | 4331, 106 | 4332, 107 | 4333, 108 | 4334, 109 | 4341, 110 | 4342, 111 | 4343, 112 | 4344, 113 | 4411, 114 | 4412, 115 | 4413, 116 | 4414, 117 | 4421, 118 | 4422, 119 | 4423, 120 | 4424, 121 | 4431, 122 | 4432, 123 | 4433, 124 | 4434, 125 | 4441, 126 | 4442, 127 | 4443, 128 | 4444 129 | }; 130 | 131 | extern char **overridable_memory_map; 132 | 133 | int FLASH_channel_to_position(int channel); 134 | int FLASH_position_to_channel(int position); 135 | void FLASH_load_memory_map(); 136 | void FLASH_save_memory_map(); 137 | void FLASH_delete_memory_map(); 138 | 139 | void FLASH_save_to_overridable_channel(char *command); 140 | char *FLASH_load_from_overridable_channel(char *command); 141 | 142 | int FLASH_all_empty(); 143 | 144 | void FLASH_LoadChannelMap(char **return_buffer); 145 | void FLASH_LoadOverriddenChannel(int channel, char **song, char **melody, char **settings); 146 | int FLASH_IsOverriddenChannel(int channel); 147 | 148 | void FLASH_erase_all_custom_data(); 149 | void FLASH_set_activation_lock(); 150 | int FLASH_check_activation_lock(); 151 | 152 | #ifdef __cplusplus 153 | } 154 | #endif 155 | 156 | #endif /* FLASH_H_ */ 157 | -------------------------------------------------------------------------------- /src/hw/sensors.c: -------------------------------------------------------------------------------- 1 | /* 2 | * sensors.c 3 | * 4 | * Created on: Jun 21, 2016 5 | * Author: mayo 6 | */ 7 | 8 | #include 9 | #include "sensors.h" 10 | #include "gpio.h" 11 | 12 | //distance sensors 13 | int adc3_val1, adc3_val2, adc3_diff, adc3_sum=0, adc3_cnt=0; 14 | 15 | volatile uint16_t ADCConvertedValues[ADC_SENSORS]; 16 | 17 | uint16_t ADC_measured_vals[2*ADC_SENSORS]; 18 | int ADC_last_result[ADC_SENSORS]={0,0,0,0}; //static dim, not futureproof 19 | int ADC_result_ready = 0; 20 | //int ADC_measured_vals_updated = 0; 21 | 22 | int process_sensors_phase = 0; 23 | int sensors_loop = 0; 24 | 25 | 26 | //#define ADC_timing_factor 3 //30ms, 60ms 27 | #define ADC_timing_factor 2 28 | 29 | int ADC_process_sensors() 30 | { 31 | int s; 32 | if(process_sensors_phase==0) 33 | { 34 | for(s=0;sBSRRL = GPIO_Pin_0; //rattling test #2 64 | } 65 | else if(process_sensors_phase==ADC_timing_factor) 66 | { 67 | for(s=0;sBSRRH = GPIO_Pin_0; //rattling test #2 96 | 97 | for(s=0;s 21 | 22 | class IIR_Filter 23 | { 24 | public: 25 | enum FilterMode { 26 | FILTER_MODE_LOWPASS = 0, 27 | FILTER_MODE_HIGHPASS, 28 | FILTER_MODE_BANDPASS, 29 | kNumFilterModes 30 | }; 31 | 32 | int BoundaryFn001(void); 33 | 34 | IIR_Filter(void); 35 | //virtual float process(float inputValue); 36 | virtual float process(float inputValue) { return 0.0f; }; 37 | //float process(float inputValue); 38 | //float process_HIGH_PASS_4TH_ORDER(float inputValue); 39 | //float process_LOW_PASS_4TH_ORDER(float inputValue); 40 | 41 | //inline void setCutoff(float newCutoff) { cutoff = newCutoff; calculateFeedbackAmount(); }; 42 | inline void setCutoff(float newCutoff) { cutoff = newCutoff; feedbackAmount = resonance + resonance/(1.0 - cutoff); }; 43 | inline void setCutoffKeepFeedback(float newCutoff) { cutoff = newCutoff; }; 44 | 45 | inline void setCutoffAndLimits(float newCutoff) { 46 | if(newCutoff < 0.001) 47 | { 48 | newCutoff = 0.247836739 / 2; 49 | } 50 | cutoff = newCutoff; 51 | cutoff_min = cutoff / 2; 52 | cutoff_max = cutoff * 2; 53 | calculateFeedbackAmount(); 54 | }; 55 | 56 | inline void driftCutoff(float drift) { 57 | cutoff += drift; 58 | if(cutoffcutoff_max) 63 | { 64 | cutoff = cutoff_max; 65 | } 66 | calculateFeedbackAmount(); 67 | }; 68 | 69 | inline void setResonance(float newResonance) { resonance = newResonance; calculateFeedbackAmount(); }; 70 | inline void setResonanceKeepFeedback(float newResonance) { resonance = newResonance; }; 71 | inline void setResonanceAndFeedback(float newResonance, float newFeedback) { resonance = newResonance; feedbackAmount = newFeedback; }; 72 | 73 | inline void resetFilterBuffers() { buf0 = 0; buf1 = 0; buf2 = 0; buf3 = 0; }; 74 | inline void disturbFilterBuffers() { buf0 /= 2; buf1 = 0; }; 75 | 76 | static float iir_filter_multi_sum(float input, IIR_Filter *iir_array, int total_filters, float *mixing_volumes); 77 | static float iir_filter_multi_sum_w_noise(float input, IIR_Filter *iir_array, int total_filters, float *mixing_volumes, uint16_t noise, float noise_volume); 78 | 79 | int BoundaryFn002(void); 80 | 81 | protected: 82 | //private: 83 | 84 | float cutoff, resonance, feedbackAmount; 85 | float buf0,buf1,buf2,buf3; 86 | float cutoff_min, cutoff_max; 87 | inline void calculateFeedbackAmount() { feedbackAmount = resonance + resonance/(1.0 - cutoff); } 88 | }; 89 | 90 | class IIR_Filter_LOW_PASS_4TH_ORDER : public IIR_Filter 91 | { 92 | public: 93 | float process(float inputValue); 94 | }; 95 | 96 | class IIR_Filter_HIGH_PASS_4TH_ORDER : public IIR_Filter 97 | { 98 | public: 99 | float process(float inputValue); 100 | }; 101 | 102 | #endif /* IIR_FILTERS_H_ */ 103 | -------------------------------------------------------------------------------- /src/dsp/freqs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * freqs.h 3 | * 4 | * Created on: Apr 27, 2016 5 | * Author: mayo 6 | */ 7 | 8 | #ifndef FREQS_H_ 9 | #define FREQS_H_ 10 | 11 | //Chords ---------------------------------------------------------- 12 | 13 | #define MAJOR 1 14 | #define MINOR 2 15 | 16 | #if FILTERS == 32 17 | int freqs[] = { 18 | 55, 110, 220, 440, 880, 1760, 19 | 275, 550, 1100, 2200, 3300, 20 | 165, 330, 660, 1320, 2640}; 21 | #endif 22 | 23 | #if FILTERS == 30 24 | int freqs[] = {55, 110, 220, 440, 880, 1760, 275, 550, 1100, 2200, 165, 330, 660, 1320, 2640}; 25 | #endif 26 | 27 | #if FILTERS == 28 28 | int freqs[] = {55, 110, 220, 440, 880, 1760, 550, 1100, 2200, 165, 330, 660, 1320, 2640}; 29 | #endif 30 | 31 | #if FILTERS == 24 32 | int freqs[] = {55, 110, 220, 440, 880, 1760, 550, 1100, 2200, 330, 660, 2640}; 33 | #endif 34 | 35 | #if FILTERS == 22 36 | int freqs[] = {55, 110, 440, 660, 880, 550, 220, 1760, 1100, 2200, 2640}; 37 | #endif 38 | 39 | #if FILTERS == 20 40 | int freqs[] = {110, 440, 660, 880, 550, 220, 1760, 1100, 2200, 2640}; 41 | #endif 42 | 43 | #if FILTERS == 18 44 | int freqs[] = {440, 660, 880, 550, 220, 1760, 1100, 2200, 2640}; 45 | #endif 46 | 47 | #if FILTERS == 16 48 | //int freqs[] = {440, 660, 880, 550, 220, 1760, 1100, 2200};//, 520}; //2640 49 | #if ACCORD == MAJOR 50 | int freqs[] = {440, 660, 880, 550, 220, 1760, 1100, 110};//, 520}; //2640 51 | #elif ACCORD == MINOR 52 | int freqs[] = {440, 660, 880, 520, 220, 1760, 1040, 110};//, 520}; //2640 53 | #endif 54 | #endif 55 | 56 | #if FILTERS == 14 57 | int freqs[] = {110, 220, 440, 520, 660, 880, 1040};//, 1760};//, 520}; 58 | #endif 59 | 60 | #if FILTERS == 12 61 | #if ACCORD == MAJOR 62 | ////int freqs[FILTERS/2] = {440, 660, 880, 550, 220};//, 520}; 63 | int freqs[] = {440, 550, 660, 880, 1100, 2200}; 64 | #elif ACCORD == MINOR 65 | int freqs[] = {440, 660, 880, 520, 220, 1760};//, 1040};//, 520}; 66 | #endif 67 | #endif 68 | 69 | #if FILTERS == 10 70 | #if ACCORD == MAJOR 71 | int freqs[] = {440, 550, 660, 880, 1100}; 72 | #elif ACCORD == MINOR 73 | //int freqs[] = {440, 660, 880, 520, 220}; 74 | int freqs[] = {440, 660, 110, 520, 220}; 75 | #endif 76 | #endif 77 | 78 | #if FILTERS == 6 79 | #if ACCORD == MAJOR 80 | int freqs[] = {440, 550, 660}; //major chord 81 | #elif ACCORD == MINOR 82 | int freqs[] = {440, 520, 660}; //minor chord 83 | #endif 84 | #endif 85 | 86 | #if FILTERS == 4 87 | //int freqs[] = {440, 1760}; 88 | int freqs[] = {440, 550}; 89 | #endif 90 | 91 | #if FILTERS == 2 92 | int freqs[] = {440}; 93 | //int freqs[] = {880}; 94 | #endif 95 | 96 | //Others---------------------------------------------------------- 97 | 98 | //Formantic Synthesis - VOWEL SOUND AS IN... F1 F2 F3 99 | //source: http://www.soundonsound.com/sos/mar01/articles/synthsec.asp 100 | /* 101 | #if FORMANTS == 'F_EE' //"ee" leap 102 | int freqs[] = {270, 2300, 3000}; 103 | #endif 104 | 105 | 106 | #if FORMANTS == 'F_OO' //"oo" loop 107 | int freqs[] = {300, 870, 2250}; 108 | #endif 109 | 110 | #if FORMANTS == 'F_I' //"i" lip 111 | int freqs[] = {400, 2000, 2550}; 112 | #endif 113 | 114 | #if FORMANTS == 'F_E' //"e" let 115 | int freqs[] = {530, 1850, 2500}; 116 | #endif 117 | 118 | #if FORMANTS == 'F_U' //"u" lug 119 | int freqs[] = {640, 1200, 2400}; 120 | #endif 121 | 122 | #if FORMANTS == 'F_A' //"a" lap 123 | int freqs[] = {660, 1700, 2400}; 124 | #endif 125 | */ 126 | 127 | #endif /* FREQS_H_ */ 128 | -------------------------------------------------------------------------------- /src/extensions/DCO_Synth.h: -------------------------------------------------------------------------------- 1 | /* 2 | * DCO_synth.h 3 | * 4 | * Created on: 11 May 2017 5 | * Author: mayo 6 | * 7 | * Based on "The Tiny-TS Touch Synthesizer" by Janost 2016, Sweden 8 | * https://janostman.wordpress.com/the-tiny-ts-diy-touch-synthesizer/ 9 | * 10 | */ 11 | 12 | // This program is free software: you can redistribute it and/or modify 13 | // it under the terms of the GNU General Public License as published by 14 | // the Free Software Foundation, either version 3 of the License, or 15 | // (at your option) any later version. 16 | // This program is distributed in the hope that it will be useful, 17 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | // GNU General Public License for more details. 20 | 21 | #ifndef DCO_SYNTH_H_ 22 | #define DCO_SYNTH_H_ 23 | 24 | //extern void IR_sensors_LED_indicators(int *sensor_values); 25 | 26 | #include 27 | #include "CV_Gate.h" 28 | #include "MIDI.h" 29 | #include "MusicBox.h" 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | 46 | //variables from other modules 47 | 48 | #define DCO_BLOCKS_MAX 24 49 | 50 | extern unsigned long seconds; 51 | extern bool PROG_buttons_control_tone_volume; 52 | extern volatile int16_t sample_i16; 53 | extern float sample_f[2],sample_mix; 54 | 55 | class DCO_Synth 56 | { 57 | static const uint8_t sinetable256[256]; 58 | uint8_t *sawtable256; 59 | uint8_t *squaretable256; 60 | uint8_t *use_table256; 61 | 62 | uint16_t envtick;//=549; 63 | volatile uint8_t DOUBLE;//=0; 64 | int16_t resonant_peak_mod_volume;// = 0; 65 | 66 | //-------- Synth parameters -------------- 67 | //volatile uint8_t VCA=255; //VCA level 0-255 68 | volatile uint8_t ATTACK;//=1; // ENV Attack rate 0-255 69 | volatile uint8_t RELEASE;//=1; // ENV Release rate 0-255 70 | //volatile uint8_t ENVELOPE=0; // ENV Shape 71 | //volatile uint8_t TRIG=0; //MIDItrig 1=note ON 72 | volatile uint16_t PDmod; //Resonant Peak index 73 | volatile uint8_t ENVamt; //Resonant Peak envelope modulation amount 74 | volatile uint8_t PHASEamt; //Resonant Peak bias 75 | //----------------------------------------- 76 | 77 | uint8_t otone1[DCO_BLOCKS_MAX]; 78 | uint8_t otone2[DCO_BLOCKS_MAX]; 79 | uint16_t phacc[DCO_BLOCKS_MAX]; 80 | uint16_t pdacc[DCO_BLOCKS_MAX]; 81 | 82 | int DCO_BLOCKS_ACTIVE;// = DCO_BLOCKS_MAX; 83 | 84 | int32_t DCO_output[2]; 85 | 86 | /* 87 | #define SEQUENCE_LENGTH 16 88 | float sequence[SEQUENCE_LENGTH]; 89 | int sequencer_head=0; 90 | int SEQUENCER_THRESHOLD = 0; 91 | */ 92 | 93 | int DCO_mode;// = 0; 94 | int SET_mode;// = 0; 95 | int button_set_held;// = 0; 96 | 97 | public: 98 | 99 | uint16_t FREQ;//=0; //DCO pitch 100 | int MIDI_note_set;// = 0;//, MIDI_note_on = 0; 101 | //int MIDI_data; 102 | 103 | DCO_Synth(); 104 | //~DCO_Synth(void); 105 | 106 | void v1_init(); 107 | void v1_play_loop(); 108 | 109 | void v2_init(); 110 | void v2_play_loop(); 111 | 112 | //void v3_init(); 113 | void v3_play_loop(); 114 | void v4_play_loop(); 115 | 116 | static void init_codec(); 117 | }; 118 | 119 | #endif /* DCO_SYNTH_H_ */ 120 | -------------------------------------------------------------------------------- /src/dsp/Detectors.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Detectors.cpp 3 | * 4 | * Created on: Jun 30, 2016 5 | * Author: mayo 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | Detectors::Detectors(char *goertzel_octaves) 13 | { 14 | gor = new Goertzel[GORS]; 15 | gors_freqs = (float*)malloc(GORS * sizeof(float)); 16 | 17 | gors_freq_notes = (char*)malloc(strlen(goertzel_octaves) * sizeof(char)); 18 | memcpy(gors_freq_notes, goertzel_octaves, strlen(goertzel_octaves) * sizeof(char)); 19 | } 20 | 21 | Detectors::~Detectors(void) 22 | { 23 | free(gors_freqs); 24 | free(gors_freq_notes); 25 | } 26 | 27 | void Detectors::detectors_setup(int buffer_length) 28 | { 29 | for(int i=0;i limit && mag > max) 53 | { 54 | max = mag; 55 | max_index = i; 56 | } 57 | mags[i] = mag; 58 | } 59 | 60 | mag = mags[0]; 61 | 62 | return max_index; 63 | } 64 | 65 | void Detectors::reset_all() 66 | { 67 | for(int i=0;idetectors_setup(fft_samples); 89 | 90 | while(1) 91 | { 92 | led_blue_state++; 93 | if(led_blue_state%2) 94 | { 95 | LED_BLUE_ON; 96 | } 97 | else 98 | { 99 | LED_BLUE_OFF; 100 | } 101 | timing = get_millis(); 102 | for(int i=0;iprocess_sample(fft_test_buf[i]); 118 | } 119 | timing = get_millis() - timing; 120 | 121 | int max_freq = det->find_max_freq(); 122 | 123 | det->reset_all(); 124 | 125 | int result = max_freq; 126 | 127 | if(result>-1) 128 | { 129 | result ++; 130 | 131 | if(result==1) 132 | { 133 | LED_SB1_ON; 134 | } 135 | else if(result==2) 136 | { 137 | LED_SB2_ON; 138 | } 139 | else if(result==3) 140 | { 141 | LED_SB3_ON; 142 | } 143 | else if(result==4) 144 | { 145 | LED_SB4_ON; 146 | } 147 | else if(result==5) 148 | { 149 | LED_SR1_ON; 150 | } 151 | else if(result==6) 152 | { 153 | LED_SR2_ON; 154 | } 155 | else if(result==7) 156 | { 157 | LED_SR3_ON; 158 | } 159 | else if(result==8) 160 | { 161 | LED_SR4_ON; 162 | } 163 | } 164 | else 165 | { 166 | LED_SB1_OFF; 167 | LED_SB2_OFF; 168 | LED_SB3_OFF; 169 | LED_SB4_OFF; 170 | LED_SR1_OFF; 171 | LED_SR2_OFF; 172 | LED_SR3_OFF; 173 | LED_SR4_OFF; 174 | } 175 | } 176 | } 177 | 178 | */ 179 | -------------------------------------------------------------------------------- /src/dsp/IIR_filters.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * IIR_filters.cpp 3 | * 4 | * Created on: Apr 18, 2016 5 | * Author: mayo 6 | * 7 | * Based on code by Paul Kellett 8 | * Source: http://www.musicdsp.org/showone.php?id=29 9 | * 10 | * This file is part of the Gecho Loopsynth Firmware Development Framework. 11 | * It can be used within the terms of CC-BY-NC-SA license. 12 | * It must not be distributed separately. 13 | * 14 | * Find more information at: http://gechologic.com/gechologists/ 15 | */ 16 | 17 | #include "IIR_filters.h" 18 | 19 | int IIR_Filter::BoundaryFn001(void) 20 | { 21 | int c; 22 | c = 0x1111; 23 | c = 0x2222; 24 | c = 0x3333; 25 | c = 0x4444; 26 | c++; 27 | return c; 28 | } 29 | 30 | IIR_Filter::IIR_Filter(void) 31 | { 32 | cutoff = 0.99; 33 | resonance = 0.0; 34 | buf0 = 0.0; 35 | buf1 = 0.0; 36 | buf2 = 0.0; 37 | buf3 = 0.0; 38 | calculateFeedbackAmount(); 39 | } 40 | 41 | //virtual float IIR_Filter::process(float inputValue) { }; 42 | /* 43 | float IIR_Filter::process(float inputValue) { 44 | //buf0 += cutoff * (inputValue - buf0); 45 | buf0 += cutoff * (inputValue - buf0 + feedbackAmount * (buf0 - buf1)); //with resonance 46 | buf1 += cutoff * (buf0 - buf1); 47 | 48 | //2nd order outputs: 49 | 50 | //return buf1; //low-pass 51 | //return inputValue - buf0; //high-pass 52 | //return buf0 - buf1; //band-pass 53 | 54 | buf2 += cutoff * (buf1 - buf2); 55 | buf3 += cutoff * (buf2 - buf3); 56 | 57 | //4th order outputs: 58 | 59 | return buf3; //low-pass (default) 60 | //return inputValue - buf3; //high-pass 61 | //return buf0 - buf3; //band-pass 62 | }; 63 | */ 64 | 65 | float IIR_Filter_LOW_PASS_4TH_ORDER::process(float inputValue) { 66 | //buf0 += cutoff * (inputValue - buf0); 67 | buf0 += cutoff * (inputValue - buf0 + feedbackAmount * (buf0 - buf1)); //with resonance 68 | buf1 += cutoff * (buf0 - buf1); 69 | 70 | //2nd order outputs: 71 | 72 | //return buf1; //low-pass 73 | //return inputValue - buf0; //high-pass 74 | //return buf0 - buf1; //band-pass 75 | 76 | buf2 += cutoff * (buf1 - buf2); 77 | buf3 += cutoff * (buf2 - buf3); 78 | 79 | //4th order outputs: 80 | 81 | return buf3; //low-pass (default) 82 | //return inputValue - buf3; //high-pass 83 | //return buf0 - buf3; //band-pass 84 | } 85 | 86 | float IIR_Filter_HIGH_PASS_4TH_ORDER::process(float inputValue) { 87 | buf0 += cutoff * (inputValue - buf0 + feedbackAmount * (buf0 - buf1)); //with resonance 88 | buf1 += cutoff * (buf0 - buf1); 89 | buf2 += cutoff * (buf1 - buf2); 90 | buf3 += cutoff * (buf2 - buf3); 91 | return inputValue - buf3; //high-pass 92 | } 93 | 94 | float IIR_Filter::iir_filter_multi_sum(float input, IIR_Filter *iir_array, int total_filters, float *mixing_volumes) 95 | { 96 | float output = 0.0; 97 | 98 | for(int f=0;f 100) //trap 113 | { 114 | total_filters++; 115 | } 116 | */ 117 | 118 | for(int f=0;f
© COPYRIGHT 2013 STMicroelectronics
13 | * 14 | * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); 15 | * You may not use this file except in compliance with the License. 16 | * You may obtain a copy of the License at: 17 | * 18 | * http://www.st.com/software_license_agreement_liberty_v2 19 | * 20 | * Unless required by applicable law or agreed to in writing, software 21 | * distributed under the License is distributed on an "AS IS" BASIS, 22 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 23 | * See the License for the specific language governing permissions and 24 | * limitations under the License. 25 | * 26 | ****************************************************************************** 27 | */ 28 | 29 | /* Define to prevent recursive inclusion -------------------------------------*/ 30 | #ifndef __STM32F4xx_WWDG_H 31 | #define __STM32F4xx_WWDG_H 32 | 33 | #ifdef __cplusplus 34 | extern "C" { 35 | #endif 36 | 37 | /* Includes ------------------------------------------------------------------*/ 38 | #include "stm32f4xx.h" 39 | 40 | /** @addtogroup STM32F4xx_StdPeriph_Driver 41 | * @{ 42 | */ 43 | 44 | /** @addtogroup WWDG 45 | * @{ 46 | */ 47 | 48 | /* Exported types ------------------------------------------------------------*/ 49 | /* Exported constants --------------------------------------------------------*/ 50 | 51 | /** @defgroup WWDG_Exported_Constants 52 | * @{ 53 | */ 54 | 55 | /** @defgroup WWDG_Prescaler 56 | * @{ 57 | */ 58 | 59 | #define WWDG_Prescaler_1 ((uint32_t)0x00000000) 60 | #define WWDG_Prescaler_2 ((uint32_t)0x00000080) 61 | #define WWDG_Prescaler_4 ((uint32_t)0x00000100) 62 | #define WWDG_Prescaler_8 ((uint32_t)0x00000180) 63 | #define IS_WWDG_PRESCALER(PRESCALER) (((PRESCALER) == WWDG_Prescaler_1) || \ 64 | ((PRESCALER) == WWDG_Prescaler_2) || \ 65 | ((PRESCALER) == WWDG_Prescaler_4) || \ 66 | ((PRESCALER) == WWDG_Prescaler_8)) 67 | #define IS_WWDG_WINDOW_VALUE(VALUE) ((VALUE) <= 0x7F) 68 | #define IS_WWDG_COUNTER(COUNTER) (((COUNTER) >= 0x40) && ((COUNTER) <= 0x7F)) 69 | 70 | /** 71 | * @} 72 | */ 73 | 74 | /** 75 | * @} 76 | */ 77 | 78 | /* Exported macro ------------------------------------------------------------*/ 79 | /* Exported functions --------------------------------------------------------*/ 80 | 81 | /* Function used to set the WWDG configuration to the default reset state ****/ 82 | void WWDG_DeInit(void); 83 | 84 | /* Prescaler, Refresh window and Counter configuration functions **************/ 85 | void WWDG_SetPrescaler(uint32_t WWDG_Prescaler); 86 | void WWDG_SetWindowValue(uint8_t WindowValue); 87 | void WWDG_EnableIT(void); 88 | void WWDG_SetCounter(uint8_t Counter); 89 | 90 | /* WWDG activation function ***************************************************/ 91 | void WWDG_Enable(uint8_t Counter); 92 | 93 | /* Interrupts and flags management functions **********************************/ 94 | FlagStatus WWDG_GetFlagStatus(void); 95 | void WWDG_ClearFlag(void); 96 | 97 | #ifdef __cplusplus 98 | } 99 | #endif 100 | 101 | #endif /* __STM32F4xx_WWDG_H */ 102 | 103 | /** 104 | * @} 105 | */ 106 | 107 | /** 108 | * @} 109 | */ 110 | 111 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 112 | -------------------------------------------------------------------------------- /src/hw/stm32f4xx_conf.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file Project/STM32F4xx_StdPeriph_Templates/stm32f4xx_conf.h 4 | * @author MCD Application Team 5 | * @version V1.1.0 6 | * @date 18-January-2013 7 | * @brief Library configuration file. 8 | ****************************************************************************** 9 | * @attention 10 | * 11 | *

© COPYRIGHT 2013 STMicroelectronics

12 | * 13 | * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); 14 | * You may not use this file except in compliance with the License. 15 | * You may obtain a copy of the License at: 16 | * 17 | * http://www.st.com/software_license_agreement_liberty_v2 18 | * 19 | * Unless required by applicable law or agreed to in writing, software 20 | * distributed under the License is distributed on an "AS IS" BASIS, 21 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 22 | * See the License for the specific language governing permissions and 23 | * limitations under the License. 24 | * 25 | ****************************************************************************** 26 | */ 27 | 28 | /* Define to prevent recursive inclusion -------------------------------------*/ 29 | #ifndef __STM32F4xx_CONF_H 30 | #define __STM32F4xx_CONF_H 31 | 32 | /* Includes ------------------------------------------------------------------*/ 33 | /* Uncomment the line below to enable peripheral header file inclusion */ 34 | #include "stm32f4xx_adc.h" 35 | #include "stm32f4xx_can.h" 36 | #include "stm32f4xx_crc.h" 37 | #include "stm32f4xx_cryp.h" 38 | #include "stm32f4xx_dac.h" 39 | #include "stm32f4xx_dbgmcu.h" 40 | #include "stm32f4xx_dcmi.h" 41 | #include "stm32f4xx_dma.h" 42 | #include "stm32f4xx_exti.h" 43 | #include "stm32f4xx_flash.h" 44 | #include "stm32f4xx_fsmc.h" 45 | #include "stm32f4xx_hash.h" 46 | #include "stm32f4xx_gpio.h" 47 | #include "stm32f4xx_i2c.h" 48 | #include "stm32f4xx_iwdg.h" 49 | #include "stm32f4xx_pwr.h" 50 | #include "stm32f4xx_rcc.h" 51 | #include "stm32f4xx_rng.h" 52 | #include "stm32f4xx_rtc.h" 53 | #include "stm32f4xx_sdio.h" 54 | #include "stm32f4xx_spi.h" 55 | #include "stm32f4xx_syscfg.h" 56 | #include "stm32f4xx_tim.h" 57 | #include "stm32f4xx_usart.h" 58 | #include "stm32f4xx_wwdg.h" 59 | #include "misc.h" /* High level functions for NVIC and SysTick (add-on to CMSIS functions) */ 60 | 61 | /* Exported types ------------------------------------------------------------*/ 62 | /* Exported constants --------------------------------------------------------*/ 63 | 64 | /* If an external clock source is used, then the value of the following define 65 | should be set to the value of the external clock source, else, if no external 66 | clock is used, keep this define commented */ 67 | /*#define I2S_EXTERNAL_CLOCK_VAL 12288000 */ /* Value of the external clock in Hz */ 68 | 69 | 70 | /* Uncomment the line below to expanse the "assert_param" macro in the 71 | Standard Peripheral Library drivers code */ 72 | /* #define USE_FULL_ASSERT 1 */ 73 | 74 | /* Exported macro ------------------------------------------------------------*/ 75 | #ifdef USE_FULL_ASSERT 76 | 77 | /** 78 | * @brief The assert_param macro is used for function's parameters check. 79 | * @param expr: If expr is false, it calls assert_failed function 80 | * which reports the name of the source file and the source 81 | * line number of the call that failed. 82 | * If expr is true, it returns no value. 83 | * @retval None 84 | */ 85 | #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__)) 86 | /* Exported functions ------------------------------------------------------- */ 87 | void assert_failed(uint8_t* file, uint32_t line); 88 | #else 89 | #define assert_param(expr) ((void)0) 90 | #endif /* USE_FULL_ASSERT */ 91 | 92 | #endif /* __STM32F4xx_CONF_H */ 93 | 94 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 95 | -------------------------------------------------------------------------------- /gecho-v1.elf.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /lib/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_crc.c: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file stm32f4xx_crc.c 4 | * @author MCD Application Team 5 | * @version V1.1.0 6 | * @date 11-January-2013 7 | * @brief This file provides all the CRC firmware functions. 8 | ****************************************************************************** 9 | * @attention 10 | * 11 | *

© COPYRIGHT 2013 STMicroelectronics

12 | * 13 | * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); 14 | * You may not use this file except in compliance with the License. 15 | * You may obtain a copy of the License at: 16 | * 17 | * http://www.st.com/software_license_agreement_liberty_v2 18 | * 19 | * Unless required by applicable law or agreed to in writing, software 20 | * distributed under the License is distributed on an "AS IS" BASIS, 21 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 22 | * See the License for the specific language governing permissions and 23 | * limitations under the License. 24 | * 25 | ****************************************************************************** 26 | */ 27 | 28 | /* Includes ------------------------------------------------------------------*/ 29 | #include "stm32f4xx_crc.h" 30 | 31 | /** @addtogroup STM32F4xx_StdPeriph_Driver 32 | * @{ 33 | */ 34 | 35 | /** @defgroup CRC 36 | * @brief CRC driver modules 37 | * @{ 38 | */ 39 | 40 | /* Private typedef -----------------------------------------------------------*/ 41 | /* Private define ------------------------------------------------------------*/ 42 | /* Private macro -------------------------------------------------------------*/ 43 | /* Private variables ---------------------------------------------------------*/ 44 | /* Private function prototypes -----------------------------------------------*/ 45 | /* Private functions ---------------------------------------------------------*/ 46 | 47 | /** @defgroup CRC_Private_Functions 48 | * @{ 49 | */ 50 | 51 | /** 52 | * @brief Resets the CRC Data register (DR). 53 | * @param None 54 | * @retval None 55 | */ 56 | void CRC_ResetDR(void) 57 | { 58 | /* Reset CRC generator */ 59 | CRC->CR = CRC_CR_RESET; 60 | } 61 | 62 | /** 63 | * @brief Computes the 32-bit CRC of a given data word(32-bit). 64 | * @param Data: data word(32-bit) to compute its CRC 65 | * @retval 32-bit CRC 66 | */ 67 | uint32_t CRC_CalcCRC(uint32_t Data) 68 | { 69 | CRC->DR = Data; 70 | 71 | return (CRC->DR); 72 | } 73 | 74 | /** 75 | * @brief Computes the 32-bit CRC of a given buffer of data word(32-bit). 76 | * @param pBuffer: pointer to the buffer containing the data to be computed 77 | * @param BufferLength: length of the buffer to be computed 78 | * @retval 32-bit CRC 79 | */ 80 | uint32_t CRC_CalcBlockCRC(uint32_t pBuffer[], uint32_t BufferLength) 81 | { 82 | uint32_t index = 0; 83 | 84 | for(index = 0; index < BufferLength; index++) 85 | { 86 | CRC->DR = pBuffer[index]; 87 | } 88 | return (CRC->DR); 89 | } 90 | 91 | /** 92 | * @brief Returns the current CRC value. 93 | * @param None 94 | * @retval 32-bit CRC 95 | */ 96 | uint32_t CRC_GetCRC(void) 97 | { 98 | return (CRC->DR); 99 | } 100 | 101 | /** 102 | * @brief Stores a 8-bit data in the Independent Data(ID) register. 103 | * @param IDValue: 8-bit value to be stored in the ID register 104 | * @retval None 105 | */ 106 | void CRC_SetIDRegister(uint8_t IDValue) 107 | { 108 | CRC->IDR = IDValue; 109 | } 110 | 111 | /** 112 | * @brief Returns the 8-bit data stored in the Independent Data(ID) register 113 | * @param None 114 | * @retval 8-bit value of the ID register 115 | */ 116 | uint8_t CRC_GetIDRegister(void) 117 | { 118 | return (CRC->IDR); 119 | } 120 | 121 | /** 122 | * @} 123 | */ 124 | 125 | /** 126 | * @} 127 | */ 128 | 129 | /** 130 | * @} 131 | */ 132 | 133 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 134 | -------------------------------------------------------------------------------- /src/Interface.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Interface.h 3 | * 4 | * Created on: Apr 27, 2016 5 | * Author: mayo 6 | * 7 | * This file is part of the Gecho Loopsynth Firmware Development Framework. 8 | * It can be used within the terms of CC-BY-NC-SA license. 9 | * It must not be distributed separately. 10 | * 11 | * Find more information at: http://gechologic.com/gechologists/ 12 | */ 13 | 14 | #ifndef INTERFACE_H_ 15 | #define INTERFACE_H_ 16 | 17 | #include 18 | #include "notes.h" 19 | 20 | extern unsigned long seconds; 21 | 22 | //extern int progressive_rhythm_factor; 23 | //#define PROGRESSIVE_RHYTHM_BOOST_RATIO 2 24 | //#define PROGRESSIVE_RHYTHM_RAMP_COEF 0.999f 25 | 26 | extern float noise_volume, noise_volume_max, noise_boost_by_sensor; 27 | extern int special_effect, selected_song, selected_melody; 28 | 29 | #define LOOP_TYPE_FILTERS 0 30 | #define LOOP_TYPE_NO_FILTERS 1 31 | extern int loop_type; 32 | 33 | extern bool 34 | PROG_enable_filters, 35 | //PROG_enable_rhythm, 36 | PROG_enable_chord_loop, 37 | PROG_enable_LED_indicators_sequencer, 38 | PROG_enable_LED_indicators_IR_sensors, 39 | PROG_enable_S1_control_noise_boost, 40 | PROG_enable_S2_control_noise_attenuation, //only when rhythm active 41 | PROG_enable_S3_control_resonance, 42 | PROG_enable_S4_control_arpeggiator, 43 | PROG_add_OpAmp_ADC12_signal, 44 | PROG_add_echo, 45 | PROG_load_echo_setting, 46 | PROG_add_plain_noise, 47 | PROG_audio_input_microphones, 48 | PROG_audio_input_pickups, 49 | PROG_audio_input_IR_sensors, 50 | PROG_audio_input_magnetic_sensor, 51 | PROG_load_input_setting, 52 | PROG_load_bpm_setting, 53 | PROG_buttons_controls_during_play, 54 | PROG_magnetic_sensor_test, 55 | PROG_magnetic_sensor_test_display, 56 | PROG_noise_effects, 57 | PROG_drum_kit, 58 | PROG_drum_kit_with_echo, 59 | PROG_mix_sample_from_flash, 60 | PROG_mix_input_signal, 61 | PROG_wavetable_sample, 62 | PROG_melody_by_MIDI, 63 | PROG_melody_by_USART; 64 | 65 | extern bool 66 | TEST_enable_V1_control_voice, 67 | TEST_enable_V2_control_drum; 68 | 69 | #define FILTERS_TYPE_LOW_PASS 0x01 70 | #define FILTERS_TYPE_HIGH_PASS 0x02 71 | #define FILTERS_ORDER_2 0x10 72 | #define FILTERS_ORDER_4 0x20 73 | #define DEFAULT_FILTERS_TYPE_AND_ORDER (FILTERS_TYPE_LOW_PASS + FILTERS_ORDER_4) 74 | extern int FILTERS_TYPE_AND_ORDER; 75 | 76 | extern int ACTIVE_FILTERS_PAIRS; 77 | extern int PROGRESS_UPDATE_FILTERS_RATE; 78 | extern int DEFAULT_ARPEGGIATOR_FILTER_PAIR; 79 | 80 | extern int SHIFT_CHORD_INTERVAL; 81 | 82 | extern int *current_chord_LEDs; 83 | extern int current_melody_LED; 84 | extern float current_melody_freq; 85 | 86 | extern float sample_f[2],sample_mix, volume2; 87 | extern int16_t ADC_sample_recv; 88 | extern uint32_t random_value; 89 | extern volatile int16_t sample_i16; 90 | extern Filters *fil; 91 | 92 | #define WAVES_FILTERS 4 93 | extern int direct_update_filters_id[WAVES_FILTERS*2]; 94 | extern float direct_update_filters_freq[WAVES_FILTERS*2]; 95 | 96 | extern int arpeggiator_loop; 97 | 98 | void filters_and_signals_init(); 99 | void program_settings_reset(); 100 | 101 | void IR_sensors_level_process(int *sensor_values); 102 | void custom_song_programming_mode(int chords_capture_method); 103 | int set_number_of_chords(int *row1, int *row2); 104 | int set_number_of_chords(); 105 | void display_chord_position(); 106 | void goto_previous_chord(); 107 | void goto_next_chord(); 108 | void blink_current_chord(int chord); 109 | void start_playing_current_chord(int (*temp_song)[NOTES_PER_CHORD], int current_chord); 110 | void change_current_chord(int (*temp_song)[NOTES_PER_CHORD], int direction, int alteration); 111 | void set_current_chord(int (*temp_song)[NOTES_PER_CHORD], int *notes, int notes_n); 112 | int count_unset_chords(); 113 | void display_and_preview_current_chord(int (*temp_song)[NOTES_PER_CHORD]); 114 | void start_preview_chord(int *notes, int notes_per_chord); 115 | void process_preview_chord(); 116 | void indicate_not_enough_chords(); 117 | void edit_chords_by_buttons(); 118 | void capture_chords_from_ADC(int chords_capture_method, int auto_corr_preamp_boost); 119 | void custom_song_edit_mode(char *progression_str); 120 | void set_tempo_by_buttons(); 121 | 122 | #endif /* INTERFACE_H_ */ 123 | -------------------------------------------------------------------------------- /src/hw/leds.h: -------------------------------------------------------------------------------- 1 | /* 2 | * leds.h 3 | * 4 | * Created on: Jun 21, 2016 5 | * Author: mayo 6 | * 7 | * This file is part of the Gecho Loopsynth Firmware Development Framework. 8 | * It can be used within the terms of CC-BY-NC-SA license. 9 | * It must not be distributed separately. 10 | * 11 | * Find more information at: http://gechologic.com/gechologists/ 12 | */ 13 | 14 | #ifndef LEDS_H_ 15 | #define LEDS_H_ 16 | 17 | #include 18 | 19 | extern int LEDs_RED_seq; 20 | extern int sensor_active[]; 21 | 22 | #define SENSOR_THRESHOLD_ORANGE_4 (sensor_values[1] > IR_sensors_THRESHOLD_7) 23 | #define SENSOR_THRESHOLD_ORANGE_3 (sensor_values[1] > IR_sensors_THRESHOLD_5) //was 500, could be IR_sensors_THRESHOLD_4(400) or IR_sensors_THRESHOLD_5(600) 24 | #define SENSOR_THRESHOLD_ORANGE_2 (sensor_values[1] > IR_sensors_THRESHOLD_3) 25 | #define SENSOR_THRESHOLD_ORANGE_1 (sensor_values[1] > IR_sensors_THRESHOLD_1) 26 | 27 | #define SENSOR_THRESHOLD_RED_8 (sensor_values[0] > IR_sensors_THRESHOLD_8) 28 | #define SENSOR_THRESHOLD_RED_7 (sensor_values[0] > IR_sensors_THRESHOLD_7) 29 | #define SENSOR_THRESHOLD_RED_6 (sensor_values[0] > IR_sensors_THRESHOLD_6) 30 | #define SENSOR_THRESHOLD_RED_5 (sensor_values[0] > IR_sensors_THRESHOLD_5) 31 | #define SENSOR_THRESHOLD_RED_4 (sensor_values[0] > IR_sensors_THRESHOLD_4) 32 | #define SENSOR_THRESHOLD_RED_3 (sensor_values[0] > IR_sensors_THRESHOLD_3) 33 | #define SENSOR_THRESHOLD_RED_2 (sensor_values[0] > IR_sensors_THRESHOLD_2) 34 | #define SENSOR_THRESHOLD_RED_1 (sensor_values[0] > IR_sensors_THRESHOLD_1) 35 | 36 | #define SENSOR_THRESHOLD_BLUE_1 (sensor_values[2] > IR_sensors_THRESHOLD_8) 37 | #define SENSOR_THRESHOLD_BLUE_2 (sensor_values[2] > IR_sensors_THRESHOLD_6) 38 | #define SENSOR_THRESHOLD_BLUE_3 (sensor_values[2] > IR_sensors_THRESHOLD_4) 39 | #define SENSOR_THRESHOLD_BLUE_4 (sensor_values[2] > IR_sensors_THRESHOLD_2) 40 | #define SENSOR_THRESHOLD_BLUE_5 (sensor_values[2] > IR_sensors_THRESHOLD_1) 41 | 42 | #define SENSOR_THRESHOLD_WHITE_1 (sensor_values[3] > IR_sensors_THRESHOLD_8) 43 | #define SENSOR_THRESHOLD_WHITE_2 (sensor_values[3] > IR_sensors_THRESHOLD_7) 44 | #define SENSOR_THRESHOLD_WHITE_3 (sensor_values[3] > IR_sensors_THRESHOLD_6) 45 | #define SENSOR_THRESHOLD_WHITE_4 (sensor_values[3] > IR_sensors_THRESHOLD_5) 46 | #define SENSOR_THRESHOLD_WHITE_5 (sensor_values[3] > IR_sensors_THRESHOLD_4) 47 | #define SENSOR_THRESHOLD_WHITE_6 (sensor_values[3] > IR_sensors_THRESHOLD_3) 48 | #define SENSOR_THRESHOLD_WHITE_7 (sensor_values[3] > IR_sensors_THRESHOLD_2) 49 | #define SENSOR_THRESHOLD_WHITE_8 (sensor_values[3] > IR_sensors_THRESHOLD_1) 50 | 51 | #ifdef __cplusplus 52 | extern "C" { 53 | #endif 54 | 55 | void IR_sensors_LED_indicators(int *sensor_values); 56 | void LED_sequencer_indicators(int current_chord, int total_chords); 57 | void display_chord(int *chord_LEDs, int total_leds); 58 | 59 | void LEDs_RED_next(int limit, int update_LEDs); 60 | void LEDs_RED_off(); 61 | 62 | void LEDs_ORANGE_next(int limit); 63 | void LEDs_ORANGE_off(); 64 | void LEDs_ORANGE_reset(); 65 | 66 | void LED_W8_all_ON(); 67 | void LED_W8_all_OFF(); 68 | void LED_B5_all_OFF(); 69 | void LED_O4_all_OFF(); 70 | void LED_R8_all_OFF(); 71 | 72 | void LED_R8_set(int led, int status); 73 | void LED_O4_set(int led, int status); 74 | 75 | void LED_R8_set_byte(int value); //default: left to right 76 | void LED_O4_set_byte(int value); 77 | void LED_B5_set_byte(int value); 78 | void LED_W8_set_byte(int value); 79 | 80 | void LED_R8_set_byte_RL(int value); //reversed: right to left 81 | void LED_O4_set_byte_RL(int value); 82 | void LED_B5_set_byte_RL(int value); 83 | void LED_W8_set_byte_RL(int value); 84 | 85 | void all_LEDs_test(); 86 | void all_LEDs_test_seq1(); 87 | void all_LEDs_test_seq2(); 88 | 89 | void KEY_LED_on(int note); 90 | void KEY_LED_all_off(); 91 | 92 | void display_number_of_chords(int row1, int row2); 93 | void ack_by_signal_LED(); 94 | void display_code_challenge(uint32_t *code); 95 | 96 | void display_volume_level_indicator_f(float value, float min, float max); 97 | void display_volume_level_indicator_i(int value, int min, int max); 98 | void display_tempo_indicator(int bpm); 99 | 100 | void display_BCD_numbers(char *digits, int length); 101 | 102 | #ifdef __cplusplus 103 | } 104 | #endif 105 | 106 | #endif /* LEDS_H_ */ 107 | -------------------------------------------------------------------------------- /lib/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_rng.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file stm32f4xx_rng.h 4 | * @author MCD Application Team 5 | * @version V1.1.0 6 | * @date 11-January-2013 7 | * @brief This file contains all the functions prototypes for the Random 8 | * Number Generator(RNG) firmware library. 9 | ****************************************************************************** 10 | * @attention 11 | * 12 | *

© COPYRIGHT 2013 STMicroelectronics

13 | * 14 | * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); 15 | * You may not use this file except in compliance with the License. 16 | * You may obtain a copy of the License at: 17 | * 18 | * http://www.st.com/software_license_agreement_liberty_v2 19 | * 20 | * Unless required by applicable law or agreed to in writing, software 21 | * distributed under the License is distributed on an "AS IS" BASIS, 22 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 23 | * See the License for the specific language governing permissions and 24 | * limitations under the License. 25 | * 26 | ****************************************************************************** 27 | */ 28 | 29 | /* Define to prevent recursive inclusion -------------------------------------*/ 30 | #ifndef __STM32F4xx_RNG_H 31 | #define __STM32F4xx_RNG_H 32 | 33 | #ifdef __cplusplus 34 | extern "C" { 35 | #endif 36 | 37 | /* Includes ------------------------------------------------------------------*/ 38 | #include "stm32f4xx.h" 39 | 40 | /** @addtogroup STM32F4xx_StdPeriph_Driver 41 | * @{ 42 | */ 43 | 44 | /** @addtogroup RNG 45 | * @{ 46 | */ 47 | 48 | /* Exported types ------------------------------------------------------------*/ 49 | /* Exported constants --------------------------------------------------------*/ 50 | 51 | /** @defgroup RNG_Exported_Constants 52 | * @{ 53 | */ 54 | 55 | /** @defgroup RNG_flags_definition 56 | * @{ 57 | */ 58 | #define RNG_FLAG_DRDY ((uint8_t)0x0001) /*!< Data ready */ 59 | #define RNG_FLAG_CECS ((uint8_t)0x0002) /*!< Clock error current status */ 60 | #define RNG_FLAG_SECS ((uint8_t)0x0004) /*!< Seed error current status */ 61 | 62 | #define IS_RNG_GET_FLAG(RNG_FLAG) (((RNG_FLAG) == RNG_FLAG_DRDY) || \ 63 | ((RNG_FLAG) == RNG_FLAG_CECS) || \ 64 | ((RNG_FLAG) == RNG_FLAG_SECS)) 65 | #define IS_RNG_CLEAR_FLAG(RNG_FLAG) (((RNG_FLAG) == RNG_FLAG_CECS) || \ 66 | ((RNG_FLAG) == RNG_FLAG_SECS)) 67 | /** 68 | * @} 69 | */ 70 | 71 | /** @defgroup RNG_interrupts_definition 72 | * @{ 73 | */ 74 | #define RNG_IT_CEI ((uint8_t)0x20) /*!< Clock error interrupt */ 75 | #define RNG_IT_SEI ((uint8_t)0x40) /*!< Seed error interrupt */ 76 | 77 | #define IS_RNG_IT(IT) ((((IT) & (uint8_t)0x9F) == 0x00) && ((IT) != 0x00)) 78 | #define IS_RNG_GET_IT(RNG_IT) (((RNG_IT) == RNG_IT_CEI) || ((RNG_IT) == RNG_IT_SEI)) 79 | /** 80 | * @} 81 | */ 82 | 83 | /** 84 | * @} 85 | */ 86 | 87 | /* Exported macro ------------------------------------------------------------*/ 88 | /* Exported functions --------------------------------------------------------*/ 89 | 90 | /* Function used to set the RNG configuration to the default reset state *****/ 91 | void RNG_DeInit(void); 92 | 93 | /* Configuration function *****************************************************/ 94 | void RNG_Cmd(FunctionalState NewState); 95 | 96 | /* Get 32 bit Random number function ******************************************/ 97 | uint32_t RNG_GetRandomNumber(void); 98 | 99 | /* Interrupts and flags management functions **********************************/ 100 | void RNG_ITConfig(FunctionalState NewState); 101 | FlagStatus RNG_GetFlagStatus(uint8_t RNG_FLAG); 102 | void RNG_ClearFlag(uint8_t RNG_FLAG); 103 | ITStatus RNG_GetITStatus(uint8_t RNG_IT); 104 | void RNG_ClearITPendingBit(uint8_t RNG_IT); 105 | 106 | #ifdef __cplusplus 107 | } 108 | #endif 109 | 110 | #endif /*__STM32F4xx_RNG_H */ 111 | 112 | /** 113 | * @} 114 | */ 115 | 116 | /** 117 | * @} 118 | */ 119 | 120 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 121 | -------------------------------------------------------------------------------- /lib/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_dbgmcu.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file stm32f4xx_dbgmcu.h 4 | * @author MCD Application Team 5 | * @version V1.1.0 6 | * @date 11-January-2013 7 | * @brief This file contains all the functions prototypes for the DBGMCU firmware library. 8 | ****************************************************************************** 9 | * @attention 10 | * 11 | *

© COPYRIGHT 2013 STMicroelectronics

12 | * 13 | * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); 14 | * You may not use this file except in compliance with the License. 15 | * You may obtain a copy of the License at: 16 | * 17 | * http://www.st.com/software_license_agreement_liberty_v2 18 | * 19 | * Unless required by applicable law or agreed to in writing, software 20 | * distributed under the License is distributed on an "AS IS" BASIS, 21 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 22 | * See the License for the specific language governing permissions and 23 | * limitations under the License. 24 | * 25 | ****************************************************************************** 26 | */ 27 | 28 | /* Define to prevent recursive inclusion -------------------------------------*/ 29 | #ifndef __STM32F4xx_DBGMCU_H 30 | #define __STM32F4xx_DBGMCU_H 31 | 32 | #ifdef __cplusplus 33 | extern "C" { 34 | #endif 35 | 36 | /* Includes ------------------------------------------------------------------*/ 37 | #include "stm32f4xx.h" 38 | 39 | /** @addtogroup STM32F4xx_StdPeriph_Driver 40 | * @{ 41 | */ 42 | 43 | /** @addtogroup DBGMCU 44 | * @{ 45 | */ 46 | 47 | /* Exported types ------------------------------------------------------------*/ 48 | /* Exported constants --------------------------------------------------------*/ 49 | 50 | /** @defgroup DBGMCU_Exported_Constants 51 | * @{ 52 | */ 53 | #define DBGMCU_SLEEP ((uint32_t)0x00000001) 54 | #define DBGMCU_STOP ((uint32_t)0x00000002) 55 | #define DBGMCU_STANDBY ((uint32_t)0x00000004) 56 | #define IS_DBGMCU_PERIPH(PERIPH) ((((PERIPH) & 0xFFFFFFF8) == 0x00) && ((PERIPH) != 0x00)) 57 | 58 | #define DBGMCU_TIM2_STOP ((uint32_t)0x00000001) 59 | #define DBGMCU_TIM3_STOP ((uint32_t)0x00000002) 60 | #define DBGMCU_TIM4_STOP ((uint32_t)0x00000004) 61 | #define DBGMCU_TIM5_STOP ((uint32_t)0x00000008) 62 | #define DBGMCU_TIM6_STOP ((uint32_t)0x00000010) 63 | #define DBGMCU_TIM7_STOP ((uint32_t)0x00000020) 64 | #define DBGMCU_TIM12_STOP ((uint32_t)0x00000040) 65 | #define DBGMCU_TIM13_STOP ((uint32_t)0x00000080) 66 | #define DBGMCU_TIM14_STOP ((uint32_t)0x00000100) 67 | #define DBGMCU_RTC_STOP ((uint32_t)0x00000400) 68 | #define DBGMCU_WWDG_STOP ((uint32_t)0x00000800) 69 | #define DBGMCU_IWDG_STOP ((uint32_t)0x00001000) 70 | #define DBGMCU_I2C1_SMBUS_TIMEOUT ((uint32_t)0x00200000) 71 | #define DBGMCU_I2C2_SMBUS_TIMEOUT ((uint32_t)0x00400000) 72 | #define DBGMCU_I2C3_SMBUS_TIMEOUT ((uint32_t)0x00800000) 73 | #define DBGMCU_CAN1_STOP ((uint32_t)0x02000000) 74 | #define DBGMCU_CAN2_STOP ((uint32_t)0x04000000) 75 | #define IS_DBGMCU_APB1PERIPH(PERIPH) ((((PERIPH) & 0xF91FE200) == 0x00) && ((PERIPH) != 0x00)) 76 | 77 | #define DBGMCU_TIM1_STOP ((uint32_t)0x00000001) 78 | #define DBGMCU_TIM8_STOP ((uint32_t)0x00000002) 79 | #define DBGMCU_TIM9_STOP ((uint32_t)0x00010000) 80 | #define DBGMCU_TIM10_STOP ((uint32_t)0x00020000) 81 | #define DBGMCU_TIM11_STOP ((uint32_t)0x00040000) 82 | #define IS_DBGMCU_APB2PERIPH(PERIPH) ((((PERIPH) & 0xFFF8FFFC) == 0x00) && ((PERIPH) != 0x00)) 83 | /** 84 | * @} 85 | */ 86 | 87 | /* Exported macro ------------------------------------------------------------*/ 88 | /* Exported functions --------------------------------------------------------*/ 89 | uint32_t DBGMCU_GetREVID(void); 90 | uint32_t DBGMCU_GetDEVID(void); 91 | void DBGMCU_Config(uint32_t DBGMCU_Periph, FunctionalState NewState); 92 | void DBGMCU_APB1PeriphConfig(uint32_t DBGMCU_Periph, FunctionalState NewState); 93 | void DBGMCU_APB2PeriphConfig(uint32_t DBGMCU_Periph, FunctionalState NewState); 94 | 95 | #ifdef __cplusplus 96 | } 97 | #endif 98 | 99 | #endif /* __STM32F4xx_DBGMCU_H */ 100 | 101 | /** 102 | * @} 103 | */ 104 | 105 | /** 106 | * @} 107 | */ 108 | 109 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 110 | -------------------------------------------------------------------------------- /lib/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_iwdg.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file stm32f4xx_iwdg.h 4 | * @author MCD Application Team 5 | * @version V1.1.0 6 | * @date 11-January-2013 7 | * @brief This file contains all the functions prototypes for the IWDG 8 | * firmware library. 9 | ****************************************************************************** 10 | * @attention 11 | * 12 | *

© COPYRIGHT 2013 STMicroelectronics

13 | * 14 | * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); 15 | * You may not use this file except in compliance with the License. 16 | * You may obtain a copy of the License at: 17 | * 18 | * http://www.st.com/software_license_agreement_liberty_v2 19 | * 20 | * Unless required by applicable law or agreed to in writing, software 21 | * distributed under the License is distributed on an "AS IS" BASIS, 22 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 23 | * See the License for the specific language governing permissions and 24 | * limitations under the License. 25 | * 26 | ****************************************************************************** 27 | */ 28 | 29 | /* Define to prevent recursive inclusion -------------------------------------*/ 30 | #ifndef __STM32F4xx_IWDG_H 31 | #define __STM32F4xx_IWDG_H 32 | 33 | #ifdef __cplusplus 34 | extern "C" { 35 | #endif 36 | 37 | /* Includes ------------------------------------------------------------------*/ 38 | #include "stm32f4xx.h" 39 | 40 | /** @addtogroup STM32F4xx_StdPeriph_Driver 41 | * @{ 42 | */ 43 | 44 | /** @addtogroup IWDG 45 | * @{ 46 | */ 47 | 48 | /* Exported types ------------------------------------------------------------*/ 49 | /* Exported constants --------------------------------------------------------*/ 50 | 51 | /** @defgroup IWDG_Exported_Constants 52 | * @{ 53 | */ 54 | 55 | /** @defgroup IWDG_WriteAccess 56 | * @{ 57 | */ 58 | #define IWDG_WriteAccess_Enable ((uint16_t)0x5555) 59 | #define IWDG_WriteAccess_Disable ((uint16_t)0x0000) 60 | #define IS_IWDG_WRITE_ACCESS(ACCESS) (((ACCESS) == IWDG_WriteAccess_Enable) || \ 61 | ((ACCESS) == IWDG_WriteAccess_Disable)) 62 | /** 63 | * @} 64 | */ 65 | 66 | /** @defgroup IWDG_prescaler 67 | * @{ 68 | */ 69 | #define IWDG_Prescaler_4 ((uint8_t)0x00) 70 | #define IWDG_Prescaler_8 ((uint8_t)0x01) 71 | #define IWDG_Prescaler_16 ((uint8_t)0x02) 72 | #define IWDG_Prescaler_32 ((uint8_t)0x03) 73 | #define IWDG_Prescaler_64 ((uint8_t)0x04) 74 | #define IWDG_Prescaler_128 ((uint8_t)0x05) 75 | #define IWDG_Prescaler_256 ((uint8_t)0x06) 76 | #define IS_IWDG_PRESCALER(PRESCALER) (((PRESCALER) == IWDG_Prescaler_4) || \ 77 | ((PRESCALER) == IWDG_Prescaler_8) || \ 78 | ((PRESCALER) == IWDG_Prescaler_16) || \ 79 | ((PRESCALER) == IWDG_Prescaler_32) || \ 80 | ((PRESCALER) == IWDG_Prescaler_64) || \ 81 | ((PRESCALER) == IWDG_Prescaler_128)|| \ 82 | ((PRESCALER) == IWDG_Prescaler_256)) 83 | /** 84 | * @} 85 | */ 86 | 87 | /** @defgroup IWDG_Flag 88 | * @{ 89 | */ 90 | #define IWDG_FLAG_PVU ((uint16_t)0x0001) 91 | #define IWDG_FLAG_RVU ((uint16_t)0x0002) 92 | #define IS_IWDG_FLAG(FLAG) (((FLAG) == IWDG_FLAG_PVU) || ((FLAG) == IWDG_FLAG_RVU)) 93 | #define IS_IWDG_RELOAD(RELOAD) ((RELOAD) <= 0xFFF) 94 | /** 95 | * @} 96 | */ 97 | 98 | /** 99 | * @} 100 | */ 101 | 102 | /* Exported macro ------------------------------------------------------------*/ 103 | /* Exported functions --------------------------------------------------------*/ 104 | 105 | /* Prescaler and Counter configuration functions ******************************/ 106 | void IWDG_WriteAccessCmd(uint16_t IWDG_WriteAccess); 107 | void IWDG_SetPrescaler(uint8_t IWDG_Prescaler); 108 | void IWDG_SetReload(uint16_t Reload); 109 | void IWDG_ReloadCounter(void); 110 | 111 | /* IWDG activation function ***************************************************/ 112 | void IWDG_Enable(void); 113 | 114 | /* Flag management function ***************************************************/ 115 | FlagStatus IWDG_GetFlagStatus(uint16_t IWDG_FLAG); 116 | 117 | #ifdef __cplusplus 118 | } 119 | #endif 120 | 121 | #endif /* __STM32F4xx_IWDG_H */ 122 | 123 | /** 124 | * @} 125 | */ 126 | 127 | /** 128 | * @} 129 | */ 130 | 131 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 132 | -------------------------------------------------------------------------------- /src/extensions/CV_Gate.c: -------------------------------------------------------------------------------- 1 | /* 2 | * CV_Gate.c 3 | * 4 | * Created on: May 28, 2017 5 | * Author: mayo 6 | * 7 | * This file is part of the Gecho Loopsynth Firmware Development Framework. 8 | * It can be used within the terms of CC-BY-NC-SA license. 9 | * It must not be distributed separately. 10 | * 11 | * Find more information at: http://gechologic.com/gechologists/ 12 | */ 13 | 14 | #include "CV_Gate.h" 15 | #include 16 | #include 17 | #include 18 | 19 | int *calibrated_cv_values; 20 | 21 | void ADC_configure_CV_GATE(int signals) 22 | { 23 | // struct to initialize GPIO pins 24 | GPIO_InitTypeDef GPIO_InitStructure; 25 | 26 | if (signals == CV_GATE_PB0_PB1) 27 | { 28 | 29 | } 30 | else if (signals == CV_GATE_PC0_PB0) 31 | { 32 | //configure PB0 as input 33 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; 34 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; //Input mode 35 | GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //Output type push-pull 36 | GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; //Without pull up/down resistors 37 | GPIO_InitStructure.GPIO_Speed = GPIO_SPEED_LEDS_BUTTONS; 38 | GPIO_Init(GPIOB, &GPIO_InitStructure); 39 | } 40 | } 41 | 42 | int Calibrate_CV() 43 | { 44 | //turn off IR sensor LEDs 45 | LED_RDY_OFF; 46 | LED_IR_DETECTORS_OFF; 47 | 48 | while(GATE_PB0); //wait till gate level goes down 49 | 50 | while(!GATE_PB0) { //indication repeats until gate goes back up 51 | 52 | int delay = 500 / 8; 53 | 54 | LED_W8_0_ON; 55 | Delay(delay); 56 | LED_W8_0_OFF; 57 | Delay(delay); 58 | 59 | LED_W8_4_ON; 60 | Delay(delay); 61 | LED_W8_4_OFF; 62 | Delay(delay); 63 | 64 | LED_W8_7_ON; 65 | Delay(delay); 66 | LED_W8_7_OFF; 67 | Delay(delay); 68 | 69 | Delay(500 - 6 * delay); 70 | //ADC_process_sensors(); 71 | } 72 | 73 | int notes[3]; 74 | int gate_level, gate_stable; //de-bouncing 75 | uint32_t gate_avg = 0; 76 | int gate_avg_samples = 0; 77 | #define GATE_THRESHOLD 50000 78 | 79 | for(int note = 0; note < 3; note++) 80 | { 81 | //CLEAR_ADC_RESULT_RDY_FLAG; 82 | //Delay(100); 83 | gate_stable = 0; 84 | gate_level = 0; 85 | while(!gate_level || notes[note]>3000) { //wait till gate level goes up 86 | //ADC_process_sensors(); 87 | //notes[note] = ADCConvertedValues[0]; 88 | if(GATE_PB0) 89 | { 90 | gate_stable++; 91 | if(gate_stable > GATE_THRESHOLD / 4) //at 25% of threshold, start collecting values 92 | { 93 | gate_avg += ADCConvertedValues[0]; 94 | gate_avg_samples++; 95 | } 96 | if(gate_stable==GATE_THRESHOLD) 97 | { 98 | gate_level = 1; 99 | notes[note] = gate_avg / gate_avg_samples; 100 | } 101 | } 102 | else 103 | { 104 | gate_stable = 0; 105 | } 106 | } 107 | //while(!ADC_process_sensors()); //wait till signal is measured 108 | //notes[note] = ADC_measured_vals[0]; 109 | //notes[note] = ADCConvertedValues[0]; 110 | //CLEAR_ADC_RESULT_RDY_FLAG; 111 | 112 | if(note == 0) 113 | { 114 | LED_W8_0_ON; 115 | } 116 | else if(note == 1) 117 | { 118 | LED_W8_4_ON; 119 | } 120 | else if(note == 2) 121 | { 122 | LED_W8_7_ON; 123 | } 124 | 125 | //Delay(100); 126 | //while(GATE_PB0) { //wait till gate level goes down again 127 | //ADC_process_sensors(); 128 | //Delay(50); 129 | //} 130 | 131 | gate_stable = 0; 132 | gate_level = 1; 133 | while(gate_level) { //wait till gate level goes down again 134 | if(!GATE_PB0) 135 | { 136 | gate_stable++; 137 | if(gate_stable==GATE_THRESHOLD) 138 | { 139 | gate_level = 0; 140 | } 141 | } 142 | else 143 | { 144 | gate_stable = 0; 145 | } 146 | } 147 | } 148 | 149 | //after 3 notes captured, analyze values and extrapolate the rest of the voltage scale 150 | calibrated_cv_values = (int*)malloc(128); //full scale, 10 and half octaves 151 | return Calculate_CV_values(notes, calibrated_cv_values); //return success 152 | } 153 | 154 | int Calculate_CV_values(int *reference_notes, int *cv_values_buffer) 155 | { 156 | //notes will be numbered according to http://www.electronics.dit.ie/staff/tscarff/Music_technology/midi/midi_note_numbers_for_octaves.htm 157 | 158 | //we assume reference notes to be C4, G4 and C5 159 | cv_values_buffer[48] = reference_notes[0]; 160 | cv_values_buffer[55] = reference_notes[1]; 161 | cv_values_buffer[60] = reference_notes[2]; 162 | 163 | float one_octave = cv_values_buffer[60] - cv_values_buffer[48]; 164 | float one_note = one_octave / 12; 165 | float g4 = cv_values_buffer[48] + 7 * one_note; 166 | float err = g4 - (float)cv_values_buffer[55]; 167 | if(abs(err) > one_note / 2) 168 | { 169 | //too much imprecision 170 | return (int)err; 171 | } 172 | 173 | for(int n=0;n<128;n++) 174 | { 175 | cv_values_buffer[n] = reference_notes[0] + one_note * (n-48); 176 | } 177 | return 0; //error is low enough 178 | } 179 | 180 | int find_nearest_note_freq(int CV_ADC_value) 181 | { 182 | //*calibrated_cv_values; 183 | } 184 | -------------------------------------------------------------------------------- /src/hw/signals.h: -------------------------------------------------------------------------------- 1 | /* 2 | * signals.h 3 | * 4 | * Created on: Apr 27, 2016 5 | * Author: mayo 6 | * 7 | * Based on "Simple ADC use on the STM32" by Peter Harrison 8 | * http://www.micromouseonline.com/2009/05/26/simple-adc-use-on-the-stm32/ 9 | * 10 | * This file is part of the Gecho Loopsynth Firmware Development Framework. 11 | * It can be used within the terms of CC-BY-NC-SA license. 12 | * It must not be distributed separately. 13 | * 14 | * Find more information at: http://gechologic.com/gechologists/ 15 | */ 16 | 17 | #ifndef SIGNALS_H_ 18 | #define SIGNALS_H_ 19 | 20 | #include 21 | #include 22 | #include "stm32f4xx_adc.h" 23 | 24 | #define ADC_PA0_PC0 10 25 | #define ADC_PA2_PC2 20 26 | #define ADC_PA6_PA7 30 27 | 28 | extern uint32_t random_value; 29 | extern float rnd_f; 30 | 31 | #ifdef __cplusplus 32 | extern "C" { 33 | #endif 34 | 35 | void ADC_configure_MIC(int pins_channels); 36 | void ADC_configure_PICKUPS(); 37 | void ADC_configure_ADC12_mute(); 38 | void ADC_set_input_multiplexer(int select); 39 | 40 | void ADC_configure_IR_sensors_as_audio(); 41 | void ADC_configure_MAGNETIC_SENSOR(); 42 | void ADC_configure_SENSORS(volatile uint16_t *converted_values); 43 | void ADC_configure_VBAT_channel(); 44 | 45 | int ADC1_read(); 46 | int ADC2_read(); 47 | //int ADC3_read(); 48 | 49 | void RNG_Config (void); 50 | 51 | void reset_pseudo_random_seed(); 52 | void set_pseudo_random_seed(double new_value); 53 | 54 | float PseudoRNG1a_next_float(); 55 | //float PseudoRNG1b_next_float(); 56 | //uint32_t PseudoRNG2_next_int32(); 57 | 58 | void new_random_value(); 59 | int fill_with_random_value(char *buffer); 60 | void PseudoRNG_next_value(uint32_t *buffer); 61 | 62 | void DMA2_Stream1_IRQHandler(void); 63 | 64 | void init_echo_buffer(); 65 | int get_echo_length(int step); 66 | 67 | int find_minimum(float *array, int size); 68 | int find_minimum_with_threshold(float *array, int size, int threshold); 69 | int find_minimum_with_threshold_f(float *array, int size, float threshold); 70 | 71 | extern int magnetic_sensor_calibration; 72 | extern int magnetic_sensor_latest_value; 73 | 74 | //-------------------------- sample and echo buffers ------------------- 75 | 76 | #define ECHO_DYNAMIC_LOOP_STEPS 15 77 | //the length is now controlled dynamically (as defined in signals.c) 78 | 79 | //#define ECHO_BUFFER_LENGTH (I2S_AUDIOFREQ * 5 / 2) //longest delay currently used 80 | #define ECHO_BUFFER_LENGTH (I2S_AUDIOFREQ * 5) //longest delay currently used, now allocating as bytes so *2 81 | #define ECHO_BUFFER_LENGTH_LOW_MEM (I2S_AUDIOFREQ * 4) //fallback buffer length when not enough memory for default (larger) 82 | 83 | //#define ECHO_BUFFER_LENGTH (I2S_AUDIOFREQ * 5 / 4) //longest delay that can be used at 44.1kHz 84 | 85 | //extern int16_t echo_buffer[ECHO_BUFFER_LENGTH]; 86 | extern int16_t *echo_buffer; //the buffer is allocated dynamically 87 | 88 | extern int echo_buffer_ptr0, echo_buffer_ptr; //pointers for echo buffer 89 | extern int echo_dynamic_loop_length; 90 | extern int echo_dynamic_loop_current_step; 91 | extern int echo_buffer_low_memory; 92 | #define ECHO_BUFFER_LOW_MEM_SKIP 3 93 | extern float ECHO_MIXING_GAIN_MUL, ECHO_MIXING_GAIN_DIV; 94 | extern float echo_mix_f; 95 | extern const int echo_dynamic_loop_steps[ECHO_DYNAMIC_LOOP_STEPS]; 96 | extern bool PROG_add_echo; 97 | 98 | #define REVERB_BUFFER_LENGTH (I2S_AUDIOFREQ / 21) //longest reverb currently used (1050 samples @ 22.5k) 99 | 100 | extern int16_t reverb_buffer[REVERB_BUFFER_LENGTH+8]; //the buffer is allocated statically 101 | extern int reverb_buffer_ptr0, reverb_buffer_ptr; //pointers for reverb buffer 102 | extern int reverb_dynamic_loop_length; 103 | extern float REVERB_MIXING_GAIN_MUL, REVERB_MIXING_GAIN_DIV; 104 | extern float reverb_mix_f; 105 | 106 | //-------------------------- inputs switching during play ------------------- 107 | 108 | #define INPUT_MUX_MICS 0 109 | #define INPUT_MUX_PICKUPS 1 110 | #define INPUT_MUX_OFF 2 111 | 112 | #define INPUT_MUX_STEPS 3 113 | extern int input_mux_current_step; 114 | 115 | //-------------------------- limits and gain multipliers -------------------- 116 | 117 | #define OPAMP_ADC12_CONVERSION_FACTOR_DEFAULT 0.00292f //by ref version, 12/4096... previous value: 0.00500f 118 | #define OPAMP_ADC12_CONVERSION_FACTOR_MIN 0.00010f 119 | #define OPAMP_ADC12_CONVERSION_FACTOR_MAX 0.02000f 120 | #define OPAMP_ADC12_CONVERSION_FACTOR_STEP 0.00010f 121 | extern float OpAmp_ADC12_signal_conversion_factor; 122 | 123 | #define OPAMP_ADC12_CONVERSION_FACTOR_BOOST_LOW_PASS 4.0f 124 | 125 | #define COMPUTED_SAMPLE_MIXING_LIMIT_UPPER 32000.0f 126 | #define COMPUTED_SAMPLE_MIXING_LIMIT_LOWER -32000.0f 127 | extern float computed_sample_dynamic_limit; 128 | 129 | #define PREAMP_BOOST 9 //multiplier for signal from ADC1/ADC2 (microphones and piezo pickups input) 130 | #define MAIN_VOLUME 64.0f //multiplier for samples mixing volume (float to int) 131 | 132 | #define UNFILTERED_SIGNAL_VOLUME 64.0f //for mixing white noise in 133 | #define FLASH_SAMPLES_MIXING_VOLUME 0.5f //for mixing the samples from flash 134 | #define COMPUTED_SAMPLES_MIXING_VOLUME 2.0f //used to adjust volume when converting from float to int 135 | //TODO: 4 was used while recording signal fed to pickup inputs 136 | 137 | //#define NOISE_BOOST_BY_SENSOR_LIMIT 3.0f 138 | //#define NOISE_BOOST_BY_SENSOR_LIMIT 4.0f 139 | //#define NOISE_BOOST_BY_SENSOR_LIMIT 6.0f 140 | #define NOISE_BOOST_BY_SENSOR_LIMIT 9.0f 141 | #define NOISE_BOOST_BY_SENSOR_DEFAULT 2.0f 142 | 143 | #define AUTOCORRELATION_PREAMP_BOOST_MIC 12 144 | #define AUTOCORRELATION_PREAMP_BOOST_LINEIN 19 145 | 146 | #ifdef __cplusplus 147 | } 148 | #endif 149 | 150 | #endif /* SIGNALS_H_ */ 151 | -------------------------------------------------------------------------------- /src/hw/stm32f4xx_it.c: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file Project/STM32F4xx_StdPeriph_Template/stm32f4xx_it.c 4 | * @author MCD Application Team 5 | * @version V1.1.0 6 | * @date 18-January-2013 7 | * @brief Main Interrupt Service Routines. 8 | * This file provides template for all exceptions handler and 9 | * peripherals interrupt service routine. 10 | ****************************************************************************** 11 | * @attention 12 | * 13 | *

© COPYRIGHT 2013 STMicroelectronics

14 | * 15 | * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); 16 | * You may not use this file except in compliance with the License. 17 | * You may obtain a copy of the License at: 18 | * 19 | * http://www.st.com/software_license_agreement_liberty_v2 20 | * 21 | * Unless required by applicable law or agreed to in writing, software 22 | * distributed under the License is distributed on an "AS IS" BASIS, 23 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 24 | * See the License for the specific language governing permissions and 25 | * limitations under the License. 26 | * 27 | ****************************************************************************** 28 | */ 29 | 30 | /* Includes ------------------------------------------------------------------*/ 31 | #include 32 | 33 | /** @addtogroup Template_Project 34 | * @{ 35 | */ 36 | 37 | /* Private typedef -----------------------------------------------------------*/ 38 | /* Private define ------------------------------------------------------------*/ 39 | /* Private macro -------------------------------------------------------------*/ 40 | /* Private variables ---------------------------------------------------------*/ 41 | //static volatile uint32_t sys_timer = 0; 42 | extern uint32_t sys_timer; 43 | //static volatile uint32_t sys_clock = 0; 44 | extern uint32_t sys_clock; 45 | /* Private function prototypes -----------------------------------------------*/ 46 | /* Private functions ---------------------------------------------------------*/ 47 | void TimingDelay_Decrement(void) 48 | { 49 | if(sys_timer>0) 50 | { 51 | sys_timer--; 52 | } 53 | 54 | sys_clock++; 55 | } 56 | 57 | /*uint32_t get_sys_clock() 58 | { 59 | return sys_clock; 60 | }*/ 61 | uint32_t get_micros() 62 | { 63 | return sys_clock; 64 | } 65 | uint32_t get_millis() 66 | { 67 | return sys_clock;///1000; 68 | } 69 | 70 | /******************************************************************************/ 71 | /* Cortex-M4 Processor Exceptions Handlers */ 72 | /******************************************************************************/ 73 | 74 | /** 75 | * @brief This function handles NMI exception. 76 | * @param None 77 | * @retval None 78 | */ 79 | void NMI_Handler(void) 80 | { 81 | } 82 | 83 | /** 84 | * @brief This function handles Hard Fault exception. 85 | * @param None 86 | * @retval None 87 | */ 88 | void HardFault_Handler(void) 89 | { 90 | NVIC_SystemReset(); 91 | /* Go to infinite loop when Hard Fault exception occurs */ 92 | while (1) 93 | { 94 | } 95 | } 96 | 97 | /** 98 | * @brief This function handles Memory Manage exception. 99 | * @param None 100 | * @retval None 101 | */ 102 | void MemManage_Handler(void) 103 | { 104 | /* Go to infinite loop when Memory Manage exception occurs */ 105 | while (1) 106 | { 107 | } 108 | } 109 | 110 | /** 111 | * @brief This function handles Bus Fault exception. 112 | * @param None 113 | * @retval None 114 | */ 115 | void BusFault_Handler(void) 116 | { 117 | /* Go to infinite loop when Bus Fault exception occurs */ 118 | while (1) 119 | { 120 | } 121 | } 122 | 123 | /** 124 | * @brief This function handles Usage Fault exception. 125 | * @param None 126 | * @retval None 127 | */ 128 | void UsageFault_Handler(void) 129 | { 130 | /* Go to infinite loop when Usage Fault exception occurs */ 131 | while (1) 132 | { 133 | } 134 | } 135 | 136 | /** 137 | * @brief This function handles SVCall exception. 138 | * @param None 139 | * @retval None 140 | */ 141 | void SVC_Handler(void) 142 | { 143 | } 144 | 145 | /** 146 | * @brief This function handles Debug Monitor exception. 147 | * @param None 148 | * @retval None 149 | */ 150 | void DebugMon_Handler(void) 151 | { 152 | } 153 | 154 | /** 155 | * @brief This function handles PendSVC exception. 156 | * @param None 157 | * @retval None 158 | */ 159 | void PendSV_Handler(void) 160 | { 161 | } 162 | 163 | /** 164 | * @brief This function handles SysTick Handler. 165 | * @param None 166 | * @retval None 167 | */ 168 | void SysTick_Handler(void) 169 | { 170 | TimingDelay_Decrement(); 171 | //sys_clock+=100; 172 | } 173 | 174 | /******************************************************************************/ 175 | /* STM32F4xx Peripherals Interrupt Handlers */ 176 | /* Add here the Interrupt Handler for the used peripheral(s) (PPP), for the */ 177 | /* available peripheral interrupt handler's name please refer to the startup */ 178 | /* file (startup_stm32f40xx.s/startup_stm32f427x.s). */ 179 | /******************************************************************************/ 180 | 181 | /** 182 | * @brief This function handles PPP interrupt request. 183 | * @param None 184 | * @retval None 185 | */ 186 | /*void PPP_IRQHandler(void) 187 | { 188 | }*/ 189 | 190 | /** 191 | * @} 192 | */ 193 | 194 | 195 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 196 | -------------------------------------------------------------------------------- /src/extensions/Samples.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Samples.c 3 | * 4 | * Created on: Nov 26, 2016 5 | * Author: mayo 6 | * 7 | * This file is part of the Gecho Loopsynth Firmware Development Framework. 8 | * It can be used within the terms of CC-BY-NC-SA license. 9 | * It must not be distributed separately. 10 | * 11 | * Find more information at: http://gechologic.com/gechologists/ 12 | */ 13 | 14 | #include "Samples.h" 15 | #include 16 | #include 17 | 18 | //toy box sample 19 | #define SAMPLE_BASE_ADDR1 0x808C960 //base address where we uploaded samples 20 | #define SAMPLE_LENGTH1 88480 //length of first sample in bytes 21 | 22 | #define FLASH_SAMPLES 1 //we uploaded 1 sample to FLASH memory 23 | 24 | int flash_samples_ptr[FLASH_SAMPLES]; //pointers for currently playing sample 25 | int fhash_sample_trigger[FLASH_SAMPLES]; //triggers for execution of each sample 26 | int flash_sample_lengths[FLASH_SAMPLES]; //lengths of samples in bytes 27 | int flash_sample_bases[FLASH_SAMPLES]; //base addresses of samples 28 | int flash_sample_init = 0; //has the sample playback been initialized? 29 | float flash_sample_return_value = 0; //variable to mix all samples into one value 30 | float flash_sample_note_freq = 0; 31 | 32 | #define FLASH_SAMPLE_VOLUME 0.04f; //general adjustment volume for samples we used 33 | 34 | extern volatile int16_t sample_i16; 35 | extern float sample_mix; 36 | 37 | uint16_t flash_sample_process(float playback_note_frequency) //returns 16-bit sample 38 | { 39 | int sample_ptr; 40 | 41 | if (!flash_sample_init) 42 | { 43 | flash_sample_init = 1; 44 | for (int i=0;i1) //some frequency 57 | { 58 | flash_sample_note_freq = playback_note_frequency; //store the new frequency 59 | fhash_sample_trigger[i] = 1; //flip the trigger 60 | flash_samples_ptr[i] = 0; //set pointer to the beginning of the sample 61 | } 62 | } 63 | 64 | if (sampleCounter%2==0) //calculate the value only on each "left" sample 65 | { 66 | flash_sample_return_value = 0; //clear the previous value 67 | 68 | for (int i=0;i= 0) //if playing 71 | { 72 | //translate from 16-bit binary format to float 73 | sample_ptr = flash_samples_ptr[i] * flash_sample_note_freq / 523.0f * 2; 74 | 75 | if (sample_ptr < flash_sample_lengths[i]) //do not overrun real sample length 76 | { 77 | flash_sample_return_value += ((float)((int16_t*)(flash_sample_bases[i]))[sample_ptr]) * FLASH_SAMPLE_VOLUME; 78 | } 79 | 80 | flash_samples_ptr[i]++; //move on to the next sample 81 | if (flash_samples_ptr[i]==flash_sample_lengths[i]) //if reached the end of the sample 82 | { 83 | flash_samples_ptr[i] = -1; //reset the pointer to "stopped" state 84 | } 85 | } 86 | } 87 | } 88 | else //return previous value for the other channel 89 | { 90 | //nothing needs to be done 91 | } 92 | return (int16_t)(flash_sample_return_value * FLASH_SAMPLES_MIXING_VOLUME); //return sample 93 | } 94 | 95 | void play_buffer(uint16_t *buffer, int buffer_length, int channels) 96 | { 97 | int buffer_ptr = 0; 98 | 99 | codec_ctrl_init(); 100 | I2S_Cmd(CODEC_I2S, ENABLE); 101 | 102 | codec_volume = CODEC_VOLUME_MIN; 103 | 104 | CodecCommandBuffer[0] = CODEC_MAP_MASTER_A_VOL; //0x20 105 | CodecCommandBuffer[1] = codec_volume; 106 | send_codec_ctrl(CodecCommandBuffer, 2); 107 | CodecCommandBuffer[0] = CODEC_MAP_MASTER_B_VOL; //0x21 108 | CodecCommandBuffer[1] = codec_volume; 109 | send_codec_ctrl(CodecCommandBuffer, 2); 110 | 111 | for(int delay=0;delay<22050;delay++) 112 | { 113 | while (!SPI_I2S_GetFlagStatus(CODEC_I2S, SPI_I2S_FLAG_TXE)); 114 | SPI_I2S_SendData(CODEC_I2S, 0); 115 | } 116 | 117 | buffer_ptr = 0; 118 | 119 | for(int i=0;i> volume_sample_rshift) & mask);// * PLAYBACK_VOLUME); 147 | SPI_I2S_SendData(CODEC_I2S, sample_i16); 148 | //if(channels==2) 149 | //{ 150 | // buffer_ptr++; 151 | //} 152 | while (!SPI_I2S_GetFlagStatus(CODEC_I2S, SPI_I2S_FLAG_TXE)); 153 | //SPI_I2S_SendData(CODEC_I2S, (buffer[buffer_ptr] >> volume_sample_rshift) & mask);// * PLAYBACK_VOLUME); 154 | SPI_I2S_SendData(CODEC_I2S, sample_i16);// * PLAYBACK_VOLUME); 155 | buffer_ptr++; 156 | } 157 | } 158 | */ 159 | 160 | -------------------------------------------------------------------------------- /src/extensions/Drums.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Drums.c 3 | * 4 | * Created on: Nov 26, 2016 5 | * Author: mayo 6 | * 7 | * This file is part of the Gecho Loopsynth Firmware Development Framework. 8 | * It can be used within the terms of CC-BY-NC-SA license. 9 | * It must not be distributed separately. 10 | * 11 | * Find more information at: http://gechologic.com/gechologists/ 12 | */ 13 | 14 | #include "Drums.h" 15 | #include 16 | #include 17 | #include 18 | 19 | int drum_samples_ptr[DRUM_CHANNELS_MAX]; //pointers for currently playing sample 20 | int drum_trigger[DRUM_CHANNELS_MAX]; //triggers for execution of each drum 21 | int drum_lengths[DRUM_SAMPLES]; //lengths of samples in bytes 22 | int drum_bases[DRUM_SAMPLES]; //base addresses of samples 23 | int drum_kit_init = 0; //has drum kit been initialized? 24 | float drum_machine_return_sample = 0; //variable to mix all samples into one value 25 | 26 | uint16_t drum_kit_process() //returns 16-bit sample 27 | { 28 | if (!drum_kit_init) 29 | { 30 | drum_kit_init = 1; 31 | for (int i=0;i DRUM_SENSOR_THRESHOLD(i)) && !drum_trigger[i]) //if not playing and CV threshold detected, start playing 52 | { 53 | drum_trigger[i] = 1; //flip the trigger 54 | drum_samples_ptr[i] = 0; //set pointer to the beginning of the sample 55 | } 56 | } 57 | else 58 | { 59 | if ((ADC_last_result[i] > DRUM_SENSOR_THRESHOLD(i)) && !drum_trigger[i]) //if not playing and IR Sensor threshold detected, start playing 60 | { 61 | drum_trigger[i] = 1; //flip the trigger 62 | drum_samples_ptr[i] = 0; //set pointer to the beginning of the sample 63 | } 64 | if ((ADC_last_result[i] < DRUM_SENSOR_THRESHOLD(i)) && drum_trigger[i]) //if playing and IR Sensor reports finger moved away, allow restart 65 | { 66 | drum_trigger[i] = 0; //release trigger 67 | } 68 | } 69 | } 70 | 71 | if (sampleCounter%2==0) //calculate the value only on each "left" sample 72 | { 73 | drum_machine_return_sample = 0; //clear the previous value 74 | 75 | for (int i=0;i= 0) //if playing 78 | { 79 | //translate from 16-bit binary format to float 80 | drum_machine_return_sample += ((float)((int16_t*)(drum_bases[i]))[drum_samples_ptr[i]]) * DRUM_SAMPLE_VOLUME; 81 | 82 | drum_samples_ptr[i]++; //move on to the next sample 83 | if (drum_samples_ptr[i]==drum_lengths[i]) //if reached the end of the sample 84 | { 85 | drum_samples_ptr[i] = -1; //reset the pointer to "stopped" state 86 | } 87 | } 88 | } 89 | } 90 | else //return previous value for the other channel 91 | { 92 | //nothing needs to be done 93 | } 94 | return (int16_t)(drum_machine_return_sample * FLASH_SAMPLES_MIXING_VOLUME); //return sample 95 | } 96 | 97 | uint16_t drum_kit_process_cv_trigger() //returns 16-bit sample 98 | { 99 | if (!drum_kit_init) 100 | { 101 | drum_kit_init = 1; 102 | for (int i=0;i DRUM_SENSOR_THRESHOLD(i)) && !drum_trigger[i]) //if not playing and IR Sensor threshold detected, start playing 121 | { 122 | drum_trigger[i] = 1; //flip the trigger 123 | drum_samples_ptr[i] = 0; //set pointer to the beginning of the sample 124 | } 125 | if ((ADC_measured_vals[i] < DRUM_SENSOR_THRESHOLD(i)) && drum_trigger[i]) //if playing and IR Sensor reports finger moved away, allow restart 126 | { 127 | drum_trigger[i] = 0; //release trigger 128 | } 129 | } 130 | 131 | if (sampleCounter%2==0) //calculate the value only on each "left" sample 132 | { 133 | drum_machine_return_sample = 0; //clear the previous value 134 | 135 | for (int i=0;i= 0) //if playing 138 | { 139 | //translate from 16-bit binary format to float 140 | drum_machine_return_sample += ((float)((int16_t*)(drum_bases[i]))[drum_samples_ptr[i]]) * DRUM_SAMPLE_VOLUME; 141 | 142 | drum_samples_ptr[i]++; //move on to the next sample 143 | if (drum_samples_ptr[i]==drum_lengths[i]) //if reached the end of the sample 144 | { 145 | drum_samples_ptr[i] = -1; //reset the pointer to "stopped" state 146 | } 147 | } 148 | } 149 | } 150 | else //return previous value for the other channel 151 | { 152 | //nothing needs to be done 153 | } 154 | return (int16_t)(drum_machine_return_sample * FLASH_SAMPLES_MIXING_VOLUME); //return sample 155 | } 156 | -------------------------------------------------------------------------------- /src/hw/pi.c: -------------------------------------------------------------------------------- 1 | //http://stackoverflow.com/questions/5905822/function-to-find-the-nth-digit-of-pi 2 | //http://bellard.org/pi/pi_n2/pi_n2.html 3 | 4 | /* 5 | * Computation of the n'th decimal digit of \pi with very little memory. 6 | * Written by Fabrice Bellard on January 8, 1997. 7 | * 8 | * We use a slightly modified version of the method described by Simon 9 | * Plouffe in "On the Computation of the n'th decimal digit of various 10 | * transcendental numbers" (November 1996). We have modified the algorithm 11 | * to get a running time of O(n^2) instead of O(n^3log(n)^3). 12 | * 13 | * This program uses mostly integer arithmetic. It may be slow on some 14 | * hardwares where integer multiplications and divisons must be done 15 | * by software. We have supposed that 'int' has a size of 32 bits. If 16 | * your compiler supports 'long long' integers of 64 bits, you may use 17 | * the integer version of 'mul_mod' (see HAS_LONG_LONG). 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | 27 | /* uncomment the following line to use 'long long' integers */ 28 | #define HAS_LONG_LONG //n=2222, 3.5min w/o long long, 45 sec w long long... n=3333 1:40min 29 | 30 | #ifdef HAS_LONG_LONG 31 | #define mul_mod(a,b,m) (( (long long) (a) * (long long) (b) ) % (m)) 32 | #else 33 | #define mul_mod(a,b,m) fmod( (double) a * (double) b, m) 34 | #endif 35 | 36 | /* return the inverse of x mod y */ 37 | int inv_mod(int x, int y) 38 | { 39 | int q, u, v, a, c, t; 40 | 41 | u = x; 42 | v = y; 43 | c = 1; 44 | a = 0; 45 | do { 46 | q = v / u; 47 | 48 | t = c; 49 | c = a - q * c; 50 | a = t; 51 | 52 | t = u; 53 | u = v - q * u; 54 | v = t; 55 | } while (u != 0); 56 | a = a % y; 57 | if (a < 0) 58 | a = y + a; 59 | return a; 60 | } 61 | 62 | /* return (a^b) mod m */ 63 | int pow_mod(int a, int b, int m) 64 | { 65 | int r, aa; 66 | 67 | r = 1; 68 | aa = a; 69 | while (1) { 70 | if (b & 1) 71 | r = mul_mod(r, aa, m); 72 | b = b >> 1; 73 | if (b == 0) 74 | break; 75 | aa = mul_mod(aa, aa, m); 76 | } 77 | return r; 78 | } 79 | 80 | /* return true if n is prime */ 81 | int is_prime(int n) 82 | { 83 | int r, i; 84 | if ((n % 2) == 0) 85 | return 0; 86 | 87 | r = (int) (sqrt(n)); 88 | for (i = 3; i <= r; i += 2) 89 | if ((n % i) == 0) 90 | return 0; 91 | return 1; 92 | } 93 | 94 | /* return the prime number immediatly after n */ 95 | int next_prime(int n) 96 | { 97 | do { 98 | n++; 99 | } while (!is_prime(n)); 100 | return n; 101 | } 102 | 103 | //int main(int argc, char *argv[]) 104 | int calculate_pi_at_nth_digit(int n, int indication) 105 | { 106 | int leds0 = 0; 107 | 108 | int av, a, vmax, N, /*n,*/ num, den, k, kq, kq2, t, v, s, i; 109 | double sum; 110 | 111 | //if (argc < 2 || (n = atoi(argv[1])) <= 0) { 112 | //printf("This program computes the n'th decimal digit of \\pi\n" 113 | // "usage: pi n , where n is the digit you want\n"); 114 | //exit(1); 115 | //} 116 | 117 | N = (int) ((n + 20) * log(10) / log(2)); 118 | 119 | sum = 0; 120 | 121 | for (a = 3; a <= (2 * N); a = next_prime(a)) { 122 | 123 | vmax = (int) (log(2 * N) / log(a)); 124 | av = 1; 125 | for (i = 0; i < vmax; i++) { 126 | av = av * a; 127 | } 128 | 129 | s = 0; 130 | num = 1; 131 | den = 1; 132 | v = 0; 133 | kq = 1; 134 | kq2 = 1; 135 | 136 | for (k = 1; k <= N; k++) { 137 | 138 | t = k; 139 | if (kq >= a) { 140 | do { 141 | t = t / a; 142 | v--; 143 | } while ((t % a) == 0); 144 | kq = 0; 145 | } 146 | kq++; 147 | num = mul_mod(num, t, av); 148 | 149 | t = (2 * k - 1); 150 | if (kq2 >= a) { 151 | if (kq2 == a) { 152 | do { 153 | t = t / a; 154 | v++; 155 | } while ((t % a) == 0); 156 | } 157 | kq2 -= a; 158 | } 159 | den = mul_mod(den, t, av); 160 | kq2 += 2; 161 | 162 | if (v > 0) { 163 | t = inv_mod(den, av); 164 | t = mul_mod(t, num, av); 165 | t = mul_mod(t, k, av); 166 | for (i = v; i < vmax; i++) { 167 | t = mul_mod(t, a, av); 168 | } 169 | s += t; 170 | if (s >= av) { 171 | s -= av; 172 | } 173 | } 174 | } 175 | 176 | t = pow_mod(10, n - 1, av); 177 | s = mul_mod(s, t, av); 178 | sum = fmod(sum + (double) s / (double) av, 1.0); 179 | 180 | if(indication) 181 | { 182 | float percents_complete = (float)a / (float)(2 * N); 183 | int leds = 16 * 256; 184 | leds *= percents_complete; 185 | //leds += 2; //correction 186 | 187 | if(leds != leds0) 188 | { 189 | //int orange = leds / 8; 190 | //int red = leds % 8; 191 | //LED_O4_set_byte(orange); 192 | //LED_K8_set_byte(red); 193 | 194 | //LED_O4_set_byte(leds); 195 | LED_R8_set_byte(leds >> 4); 196 | 197 | int orange = (leds/16) % 4; 198 | (orange==0) ? (LED_O4_0_ON) : (LED_O4_0_OFF); 199 | (orange==1) ? (LED_O4_1_ON) : (LED_O4_1_OFF); 200 | (orange==2) ? (LED_O4_2_ON) : (LED_O4_2_OFF); 201 | (orange==3) ? (LED_O4_3_ON) : (LED_O4_3_OFF); 202 | 203 | leds0 = leds; 204 | } 205 | } 206 | } 207 | //printf("Decimal digits of pi at position %d: %09d\n", n, 208 | // (int) (sum * 1e9)); 209 | //return 0; 210 | return (int) (sum * 1e9); 211 | } 212 | 213 | //===== BEGIN PI BASE ADDR BLOCK =========================================== 214 | 215 | #define PI_BASE_ADDR 0x080F3C3E //base addr where we uploaded binary representation of Pi 216 | 217 | //===== END PI BASE ADDR BLOCK =========================================== 218 | 219 | int32_t load_pi_at_nth_dword(int n) 220 | { 221 | return ((int32_t*)(PI_BASE_ADDR))[n]; 222 | } 223 | -------------------------------------------------------------------------------- /src/MusicBox.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Chord.cpp 3 | * 4 | * Created on: May 30, 2016 5 | * Author: mayo 6 | */ 7 | 8 | #include "MusicBox.h" 9 | #include 10 | #include 11 | #include "notes.h" 12 | #include "songs.h" 13 | #include 14 | 15 | const int MusicBox::expand_multipliers[MAX_VOICES_PER_CHORD][2] = { 16 | /* 17 | //v1. - more trebles, less basses 18 | {0, 1}, //source 0, no change 19 | {1, 1}, //source 1, no change 20 | {2, 1}, //source 2, no change 21 | {0, -2}, //source 0, freq / 2 22 | {0, 2}, //source 0, freq * 2 23 | {1, 2}, //source 1, freq * 2 24 | {2, 2}, //source 2, freq * 2 25 | {1, -2}, //source 1, freq / 2 26 | {2, -2} //source 2, freq / 2 27 | */ 28 | 29 | //v2. - less trebles, more basses 30 | {0, 1}, //source 0, no change 31 | {1, 1}, //source 1, no change 32 | {2, 1}, //source 2, no change 33 | {0, 2}, //source 0, freq * 2 //only powers of 2 make sense to shift octaves up and down (2,4,8) 34 | {0, -2}, //source 0, freq / 2 35 | {0, 4}, //source 0, freq * 4 36 | {0, -4}, //source 0, freq / 4 37 | {1, 2}, //source 1, freq * 2 38 | {2, 2} //source 2, freq * 2 //no need if only 8 voices per chord 39 | }; 40 | 41 | MusicBox::MusicBox(int song) { 42 | // TODO Auto-generated constructor stub 43 | 44 | if(song>0 && song!=CHANNEL_111_RECENTLY_GENERATED_SONG && song!=CHANNEL_112_RECENTLY_GENERATED_SONG_W_MELODY) 45 | { 46 | use_melody = NULL; 47 | use_song = (char*)MusicBox_SONGS[(song-1) * 2]; 48 | } 49 | else //if(song==CHANNEL_111_RECENTLY_GENERATED_SONG) 50 | { 51 | //translate to required notation 52 | //total_chords = temp_total_chords; 53 | /*int encoded_length =*/ //encode_temp_song_to_notes(temp_song, total_chords, &use_song); //memory will be allocated for use_song 54 | //} 55 | //else if(song==CHANNEL_112_RECENTLY_GENERATED_SONG_W_MELODY) 56 | //{ 57 | //the song is prepared in progression_str variable 58 | use_song = progression_str; 59 | if(melody_str && strlen(melody_str))//song==CHANNEL_112_RECENTLY_GENERATED_SONG_W_MELODY) 60 | { 61 | use_melody = melody_str; 62 | } 63 | } 64 | 65 | base_notes = (char*)malloc(strlen(use_song) * sizeof(char) + 1); 66 | memcpy(base_notes, use_song, strlen(use_song) * sizeof(char)); 67 | base_notes[strlen(use_song) * sizeof(char)] = 0; 68 | 69 | if(use_song && (song==CHANNEL_111_RECENTLY_GENERATED_SONG || song==CHANNEL_112_RECENTLY_GENERATED_SONG_W_MELODY)) 70 | { 71 | free(use_song); //free memory that was allocated by encode_temp_song_to_notes() 72 | } 73 | 74 | total_chords = get_song_total_chords(base_notes); 75 | 76 | bases_parsed = (float*)malloc(total_chords * BASE_FREQS_PER_CHORD * sizeof(float)); //default = 8 chords, 3 base freqs for each chord 77 | led_indicators = (int*)malloc(total_chords * 3 * sizeof(int)); //default = 8 chords, 3 LED lights per chord 78 | 79 | chords = (CHORD*) malloc(total_chords * sizeof(CHORD)); 80 | 81 | current_chord = 0; 82 | current_melody_note = 0; 83 | 84 | melody_freqs_parsed = NULL; 85 | melody_indicator_leds = NULL; 86 | } 87 | 88 | MusicBox::~MusicBox() { 89 | // TODO Auto-generated destructor stub 90 | 91 | if(chords != NULL) { 92 | 93 | //todo: first release all freqs arrays within chord structure: chords[c].freqs 94 | for(int c=0;c 0) 125 | { 126 | chords[c].freqs[t] = bases_parsed[3*c + expand_multipliers[t][0]] * (float)expand_multipliers[t][1]; 127 | //test = chords[c].freqs[t]; 128 | //test++; 129 | 130 | //if(chords[c].freqs[t] > 2000.0f) 131 | //{ 132 | // chords[c].freqs[t] /= 2.0f; 133 | //} 134 | } 135 | else 136 | { 137 | chords[c].freqs[t] = bases_parsed[3*c + expand_multipliers[t][0]] / (float)(-expand_multipliers[t][1]); 138 | //test = chords[c].freqs[t]; 139 | //test++; 140 | } 141 | } 142 | } 143 | } 144 | 145 | int MusicBox::get_song_total_chords(char *base_notes) 146 | { 147 | if(strlen(base_notes)==0) 148 | { 149 | return 0; 150 | } 151 | 152 | int chords = 1; 153 | 154 | for(unsigned int i=0;i='a' && melody[i]<='h')) 192 | { 193 | notes++; 194 | } 195 | } 196 | return notes; 197 | } 198 | 199 | /* 200 | void Chord::clear_old_song_and_melody() 201 | { 202 | if(use_song!=NULL) 203 | { 204 | free(use_song); //free memory that was allocated by encode_temp_song_to_notes() 205 | use_song = NULL; 206 | } 207 | if(use_melody!=NULL) 208 | { 209 | free(use_melody); 210 | use_melody = NULL; 211 | } 212 | } 213 | */ 214 | -------------------------------------------------------------------------------- /Debug_STM32F405RG_FLASH.ld: -------------------------------------------------------------------------------- 1 | /* 2 | ***************************************************************************** 3 | ** 4 | ** File : stm32_flash.ld 5 | ** 6 | ** Abstract : Linker script for STM32F405RG Device with 7 | ** 1024KByte FLASH, 128KByte RAM 8 | ** 9 | ** Set heap size, stack size and stack location according 10 | ** to application requirements. 11 | ** 12 | ** Set memory bank area and size if external memory is used. 13 | ** 14 | ** Target : STMicroelectronics STM32 15 | ** 16 | ** Environment : Atollic TrueSTUDIO(R) 17 | ** 18 | ** Distribution: The file is distributed "as is", without any warranty 19 | ** of any kind. 20 | ** 21 | ** (c)Copyright Atollic AB. 22 | ** You may use this file as-is or modify it according to the needs of your 23 | ** project. This file may only be built (assembled or compiled and linked) 24 | ** using the Atollic TrueSTUDIO(R) product. The use of this file together 25 | ** with other tools than Atollic TrueSTUDIO(R) is not permitted. 26 | ** 27 | ***************************************************************************** 28 | */ 29 | 30 | /* Entry Point */ 31 | ENTRY(Reset_Handler) 32 | 33 | /* Highest address of the user mode stack */ 34 | _estack = 0x20020000; /* end of 128K RAM */ 35 | 36 | /* Generate a link error if heap and stack don't fit into RAM */ 37 | _Min_Heap_Size = 0; /* required amount of heap */ 38 | _Min_Stack_Size = 0x400; /* required amount of stack */ 39 | 40 | /* Specify the memory areas */ 41 | MEMORY 42 | { 43 | FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K 44 | RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K 45 | MEMORY_B1 (rx) : ORIGIN = 0x60000000, LENGTH = 0K 46 | CCMRAM (rw) : ORIGIN = 0x10000000, LENGTH = 64K 47 | } 48 | 49 | /* Define output sections */ 50 | SECTIONS 51 | { 52 | /* The startup code goes first into FLASH */ 53 | .isr_vector : 54 | { 55 | . = ALIGN(4); 56 | KEEP(*(.isr_vector)) /* Startup code */ 57 | . = ALIGN(4); 58 | } >FLASH 59 | 60 | /* The program code and other data goes into FLASH */ 61 | .text : 62 | { 63 | . = ALIGN(4); 64 | *(.text) /* .text sections (code) */ 65 | *(.text*) /* .text* sections (code) */ 66 | *(.glue_7) /* glue arm to thumb code */ 67 | *(.glue_7t) /* glue thumb to arm code */ 68 | *(.eh_frame) 69 | 70 | KEEP (*(.init)) 71 | KEEP (*(.fini)) 72 | 73 | . = ALIGN(4); 74 | _etext = .; /* define a global symbols at end of code */ 75 | } >FLASH 76 | 77 | /* Constant data goes into FLASH */ 78 | .rodata : 79 | { 80 | . = ALIGN(4); 81 | *(.rodata) /* .rodata sections (constants, strings, etc.) */ 82 | *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ 83 | . = ALIGN(4); 84 | } >FLASH 85 | 86 | .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH 87 | .ARM : { 88 | __exidx_start = .; 89 | *(.ARM.exidx*) 90 | __exidx_end = .; 91 | } >FLASH 92 | 93 | .preinit_array : 94 | { 95 | PROVIDE_HIDDEN (__preinit_array_start = .); 96 | KEEP (*(.preinit_array*)) 97 | PROVIDE_HIDDEN (__preinit_array_end = .); 98 | } >FLASH 99 | .init_array : 100 | { 101 | PROVIDE_HIDDEN (__init_array_start = .); 102 | KEEP (*(SORT(.init_array.*))) 103 | KEEP (*(.init_array*)) 104 | PROVIDE_HIDDEN (__init_array_end = .); 105 | } >FLASH 106 | .fini_array : 107 | { 108 | PROVIDE_HIDDEN (__fini_array_start = .); 109 | KEEP (*(SORT(.fini_array.*))) 110 | KEEP (*(.fini_array*)) 111 | PROVIDE_HIDDEN (__fini_array_end = .); 112 | } >FLASH 113 | 114 | /* used by the startup to initialize data */ 115 | _sidata = LOADADDR(.data); 116 | 117 | /* Initialized data sections goes into RAM, load LMA copy after code */ 118 | .data : 119 | { 120 | . = ALIGN(4); 121 | _sdata = .; /* create a global symbol at data start */ 122 | *(.data) /* .data sections */ 123 | *(.data*) /* .data* sections */ 124 | 125 | . = ALIGN(4); 126 | _edata = .; /* define a global symbol at data end */ 127 | } >RAM AT> FLASH 128 | 129 | _siccmram = LOADADDR(.ccmram); 130 | 131 | /* CCM-RAM section 132 | * 133 | * IMPORTANT NOTE! 134 | * If initialized variables will be placed in this section, 135 | * the startup code needs to be modified to copy the init-values. 136 | */ 137 | .ccmram : 138 | { 139 | . = ALIGN(4); 140 | _sccmram = .; /* create a global symbol at ccmram start */ 141 | *(.ccmram) 142 | *(.ccmram*) 143 | 144 | . = ALIGN(4); 145 | _eccmram = .; /* create a global symbol at ccmram end */ 146 | } >CCMRAM AT> FLASH 147 | 148 | /* Uninitialized data section */ 149 | . = ALIGN(4); 150 | .bss : 151 | { 152 | /* This is used by the startup in order to initialize the .bss secion */ 153 | _sbss = .; /* define a global symbol at bss start */ 154 | __bss_start__ = _sbss; 155 | *(.bss) 156 | *(.bss*) 157 | *(COMMON) 158 | 159 | . = ALIGN(4); 160 | _ebss = .; /* define a global symbol at bss end */ 161 | __bss_end__ = _ebss; 162 | } >RAM 163 | 164 | /* User_heap_stack section, used to check that there is enough RAM left */ 165 | ._user_heap_stack : 166 | { 167 | . = ALIGN(4); 168 | PROVIDE ( end = . ); 169 | PROVIDE ( _end = . ); 170 | . = . + _Min_Heap_Size; 171 | . = . + _Min_Stack_Size; 172 | . = ALIGN(4); 173 | } >RAM 174 | 175 | /* MEMORY_bank1 section, code must be located here explicitly */ 176 | /* Example: extern int foo(void) __attribute__ ((section (".mb1text"))); */ 177 | .memory_b1_text : 178 | { 179 | *(.mb1text) /* .mb1text sections (code) */ 180 | *(.mb1text*) /* .mb1text* sections (code) */ 181 | *(.mb1rodata) /* read-only data (constants) */ 182 | *(.mb1rodata*) 183 | } >MEMORY_B1 184 | 185 | /* Remove information from the standard libraries */ 186 | /DISCARD/ : 187 | { 188 | libc.a ( * ) 189 | libm.a ( * ) 190 | libgcc.a ( * ) 191 | } 192 | 193 | .ARM.attributes 0 : { *(.ARM.attributes) } 194 | } 195 | -------------------------------------------------------------------------------- /src/extensions/Antarctica.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Antarctica.cpp 3 | * 4 | * Created on: Sep 24, 2016 5 | * Author: mayo 6 | * 7 | * This file is part of the Gecho Loopsynth Firmware Development Framework. 8 | * It can be used within the terms of CC-BY-NC-SA license. 9 | * It must not be distributed separately. 10 | * 11 | * Find more information at: http://gechologic.com/gechologists/ 12 | */ 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include "Antarctica.h" 20 | #include 21 | 22 | volatile uint32_t a_sampleCounter = 0; 23 | volatile int16_t a_sample_i16 = 0; 24 | 25 | //#define WIND_FILTERS 2 26 | //int wind_freqs[] = {880}; 27 | //float cutoff[WIND_FILTERS] = {0.159637183,0.159637183}; 28 | //float cutoff_limit[2] = {0.079818594}; 29 | 30 | #define WIND_FILTERS 4 31 | int wind_freqs[] = {880,880}; 32 | float cutoff[WIND_FILTERS] = {0.159637183,0.159637183,0.159637183,0.159637183}; 33 | float cutoff_limit[2] = {0.079818594,0.319274376}; 34 | //float cutoff[WIND_FILTERS] = {0.359637183,0.459637183,0.4159637183,0.3159637183}; 35 | //float cutoff_limit[2] = {0.279818594,0.5319274376}; 36 | //float cutoff[WIND_FILTERS] = {0.1759637183,0.18159637183,0.1578159637183,0.1983159637183}; 37 | //float cutoff_limit[2] = {0.15,0.20}; 38 | 39 | //#define WIND_FILTERS 8 40 | //int wind_freqs[] = {880,880,880,880}; 41 | //float cutoff[WIND_FILTERS] = {0.159637183,0.159637183,0.159637183,0.159637183,0.159637183,0.159637183,0.159637183,0.159637183}; 42 | //float cutoff_limit[2] = {0.079818594,0.319274376}; 43 | 44 | /* 45 | #define WIND_FILTERS 12 46 | int wind_freqs[] = {880,880,880,880,880,880}; 47 | float cutoff[WIND_FILTERS] = {0.159637183,0.159637183,0.159637183,0.159637183,0.159637183,0.159637183,0.159637183,0.159637183,0.159637183,0.159637183,0.159637183,0.159637183}; 48 | float cutoff_limit[2] = {0.079818594,0.319274376}; 49 | */ 50 | 51 | IIR_Filter *a_iir; 52 | 53 | uint32_t a_random_value; 54 | 55 | float a_sample[WIND_FILTERS/2],a_sample_mix; 56 | unsigned long a_seconds; 57 | 58 | float A_SAMPLE_VOLUME = 2.0f; //0.375f; 59 | 60 | float resonance = 0.970; 61 | float feedback; 62 | float resonance_limit[2] = {0.950,0.995}; 63 | float feedback_limit[2]; 64 | 65 | float a_volume = 400.0f; //400.0f; 66 | 67 | int i, cutoff_sweep = 0; 68 | 69 | float mixing_volumes[WIND_FILTERS]; 70 | int mixing_deltas[WIND_FILTERS]; 71 | 72 | #define BUTTON_SET_ON (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)==1) //SET button: PA0 73 | 74 | void filter_setup02() 75 | { 76 | a_iir = new IIR_Filter_LOW_PASS_4TH_ORDER[WIND_FILTERS]; 77 | 78 | for(i=0;i>16)) / 32768.0f; 112 | } 113 | 114 | while(!SPI_I2S_GetFlagStatus(CODEC_I2S, SPI_I2S_FLAG_TXE)); 115 | 116 | SPI_I2S_SendData(CODEC_I2S, a_sample_i16); 117 | 118 | pwr_button_shutdown(); 119 | 120 | if (a_sampleCounter & 0x00000001) //left channel 121 | { 122 | a_sample_mix = IIR_Filter::iir_filter_multi_sum(a_sample[0], a_iir, WIND_FILTERS/2, mixing_volumes) * a_volume; 123 | } 124 | else 125 | { 126 | a_sample_mix = IIR_Filter::iir_filter_multi_sum(a_sample[1], a_iir+WIND_FILTERS/2, WIND_FILTERS/2, mixing_volumes+WIND_FILTERS/2) * a_volume; 127 | } 128 | 129 | if (a_sample_mix > signal_max) 130 | { 131 | signal_max = a_sample_mix; 132 | } 133 | if (a_sample_mix < signal_min) 134 | { 135 | signal_min = a_sample_mix; 136 | } 137 | 138 | if (a_sample_mix > signal_max_limit) 139 | { 140 | a_sample_mix = signal_max_limit; 141 | } 142 | if (a_sample_mix < signal_min_limit) 143 | { 144 | a_sample_mix = signal_min_limit; 145 | } 146 | 147 | a_sample_i16 = (int16_t)(a_sample_mix * A_SAMPLE_VOLUME); 148 | 149 | a_sampleCounter++; 150 | 151 | if (a_sampleCounter==I2S_AUDIOFREQ) 152 | { 153 | //LED_BLUE_OFF; 154 | } 155 | else if (a_sampleCounter==2*I2S_AUDIOFREQ) 156 | { 157 | //LED_BLUE_ON; 158 | a_sampleCounter = 0; 159 | a_seconds++; 160 | 161 | if (a_seconds % 3 == 0) 162 | { 163 | for (int d=0; d> d) & 0x00000001; 166 | } 167 | } 168 | } 169 | if (a_sampleCounter%(2*I2S_AUDIOFREQ/10)==0) //every 100ms 170 | { 171 | cutoff_sweep++; 172 | cutoff_sweep %= WIND_FILTERS; 173 | 174 | cutoff[cutoff_sweep] += 0.005 - (float)(0.01 * ((a_random_value) & 0x00000001)); 175 | if (cutoff[cutoff_sweep] < cutoff_limit[0]) 176 | { 177 | cutoff[cutoff_sweep] = cutoff_limit[0]; 178 | } 179 | else if (cutoff[cutoff_sweep] > cutoff_limit[1]) 180 | { 181 | cutoff[cutoff_sweep] = cutoff_limit[1]; 182 | } 183 | 184 | mixing_volumes[cutoff_sweep] += mixing_deltas[cutoff_sweep] * 0.01f; 185 | if (mixing_volumes[cutoff_sweep] < 0) 186 | { 187 | mixing_volumes[cutoff_sweep] = 0; 188 | } 189 | else if (mixing_volumes[cutoff_sweep] > 1) 190 | { 191 | mixing_volumes[cutoff_sweep] = 1; 192 | } 193 | 194 | a_iir[cutoff_sweep].setCutoff(cutoff[cutoff_sweep]); 195 | } 196 | 197 | queue_codec_ctrl_process(); 198 | 199 | if (a_sampleCounter%(2*I2S_AUDIOFREQ/10)==3) //every 100ms - 10Hz periodically, at sample #3 200 | { 201 | check_for_reset(); 202 | } 203 | if (a_sampleCounter%(2*I2S_AUDIOFREQ/10)==2345) //every 100ms - 10Hz periodically, at sample #2345 204 | { 205 | buttons_controls_during_play(); 206 | } 207 | } 208 | } 209 | -------------------------------------------------------------------------------- /src/extensions/Sequencer.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Granular.cpp 3 | * 4 | * Created on: 26 Jan 2018 5 | * Author: mario 6 | * 7 | * As explained in the coding tutorial: http://gechologic.com/granular-sampler 8 | * 9 | * This file is part of the Gecho Loopsynth Firmware Development Framework. 10 | * It can be used within the terms of CC-BY-NC-SA license. 11 | * 12 | * Find more information at: http://gechologic.com/gechologists/ 13 | */ 14 | 15 | #include "Sequencer.h" 16 | #include "Drums.h" 17 | 18 | void drum_sequencer() 19 | { 20 | //-------------------------------------------------------------------------- 21 | //defines, constants and variables 22 | 23 | #define BAR_RESOLUTION 256 //how many events to record per bar (which is usually 0.5s) 24 | 25 | int sequence_length; //user-defined sequence length in bars, one bar usually corresponds to half a second 26 | int sequence_bars, sequence_verses; 27 | int verse = 0, bar = -1; //bar needs to be at position 0 at the first increment 28 | char *events; 29 | int events_n, event_position; 30 | 31 | //this selector is recycled from custom_song_programming_mode() 32 | //we have no chords here, but this needs to works the same way 33 | sequence_length = set_number_of_chords(&sequence_bars, &sequence_verses); 34 | 35 | events_n = sequence_length * BAR_RESOLUTION; 36 | events = (char*)malloc(events_n); //allocate memory for events 37 | memset(events,0,events_n); //clear the events array (set all elements to 0) 38 | 39 | float drum_kit_mixing_sample; //variable to mix all drum samples 40 | int metronome_ptr = -1; //"metronome" sample pointer, stopped initially 41 | 42 | int metronome_enabled = 1; 43 | int btn_held = 0; 44 | 45 | //mapping coefficient for determining event position by sampleCounter 46 | float sample_to_events = (float)BAR_RESOLUTION / (float)I2S_AUDIOFREQ; 47 | 48 | KEY_LED_all_off(); //turn off all LEDs 49 | while(ANY_USER_BUTTON_ON); //wait till all buttons released (some may still be pressed from selecting a channel) 50 | ADC_configure_SENSORS(ADCConvertedValues); //configure IR proximity sensors 51 | 52 | //init and configure audio codec 53 | codec_init(); 54 | codec_ctrl_init(); 55 | I2S_Cmd(CODEC_I2S, ENABLE); 56 | 57 | drum_kit_process(); //when run for the first time, this will init the drum kit 58 | 59 | while(1) 60 | { 61 | sampleCounter++; 62 | 63 | if (TIMING_BY_SAMPLE_EVERY_500_MS==0) //2Hz periodically, at 0ms 64 | { 65 | bar++; 66 | if(bar==sequence_bars) 67 | { 68 | bar = 0; 69 | verse++; 70 | if(verse==sequence_verses) 71 | { 72 | verse = 0; 73 | } 74 | } 75 | 76 | //light up a Red LED according to current bar 77 | LED_R8_all_OFF(); 78 | LED_R8_set(bar, 1); 79 | 80 | //light up an Orange LED according to current verse 81 | LED_O4_all_OFF(); 82 | LED_O4_set(verse, 1); 83 | } 84 | 85 | sample_mix = 0; //mix samples for all voices (left or right channel, based on sampleCounter) 86 | 87 | event_position = (sampleCounter % (I2S_AUDIOFREQ*sequence_length)) * sample_to_events; 88 | 89 | //process the drums 90 | for (int i=0;i DRUM_SENSOR_THRESHOLD(i)) && !drum_trigger[i]) //if not playing and IR Sensor threshold detected, start playing 99 | { 100 | drum_trigger[i] = 1; //flip the trigger 101 | drum_samples_ptr[i] = 0; //set pointer to the beginning of the sample 102 | 103 | //store the event 104 | events[event_position] += (2<= 0) //if playing 119 | { 120 | //translate from 16-bit binary format to float 121 | drum_kit_mixing_sample += ((float)((int16_t*)(drum_bases[i]))[drum_samples_ptr[i]]) * DRUM_SAMPLE_VOLUME; 122 | 123 | drum_samples_ptr[i]++; //move on to the next sample 124 | if (drum_samples_ptr[i]==drum_lengths[i]) //if reached the end of the sample 125 | { 126 | drum_samples_ptr[i] = -1; //reset the pointer to "stopped" state 127 | } 128 | } 129 | } 130 | } 131 | 132 | //add metronome at 120bpm 133 | #define METRONOME_SAMPLE 1 134 | #define METRONOME_SAMPLE_VOLUME (DRUM_SAMPLE_VOLUME/2) 135 | 136 | if (TIMING_BY_SAMPLE_EVERY_500_MS == 0) 137 | { 138 | if(metronome_enabled) 139 | { 140 | metronome_ptr = 0; //start playing 141 | } 142 | } 143 | if(metronome_ptr != -1) 144 | { 145 | drum_kit_mixing_sample += ((float)((int16_t*)(drum_bases[METRONOME_SAMPLE]))[metronome_ptr]) * METRONOME_SAMPLE_VOLUME; 146 | //metronome_ptr += 4; //play at two octaves higher 147 | metronome_ptr += 8; //play at three octaves higher 148 | 149 | if (metronome_ptr >= drum_lengths[METRONOME_SAMPLE]) //if reached the end of the sample 150 | { 151 | metronome_ptr = -1; //reset the pointer to "stopped" state 152 | } 153 | } 154 | 155 | sample_mix += (int16_t)(drum_kit_mixing_sample * FLASH_SAMPLES_MIXING_VOLUME); //return sample 156 | 157 | //send data to codec 158 | while (!SPI_I2S_GetFlagStatus(CODEC_I2S, SPI_I2S_FLAG_TXE)); 159 | SPI_I2S_SendData(CODEC_I2S, (int16_t)(sample_mix)); 160 | 161 | if (TIMING_BY_SAMPLE_EVERY_10_MS == 0) //100Hz periodically, at 0ms 162 | { 163 | if (ADC_process_sensors()==1) //process the sensors 164 | { 165 | //values from S3 and S4 are inverted (by hardware) 166 | ADC_last_result[2] = -ADC_last_result[2]; 167 | ADC_last_result[3] = -ADC_last_result[3]; 168 | 169 | CLEAR_ADC_RESULT_RDY_FLAG; 170 | sensors_loop++; 171 | 172 | //enable indicating of sensor levels by LEDs 173 | IR_sensors_LED_indicators(ADC_last_result); 174 | } 175 | } 176 | 177 | //we will enable default controls too (user buttons B1-B4 to control volume, inputs and echo on/off) 178 | if (TIMING_BY_SAMPLE_EVERY_100_MS==1234) //10Hz periodically, at sample #1234 179 | { 180 | buttons_controls_during_play(); 181 | 182 | if(BUTTON_U4_ON) 183 | { 184 | if(!btn_held) 185 | { 186 | metronome_enabled = metronome_enabled?0:1; 187 | btn_held = 1; 188 | } 189 | } 190 | else 191 | { 192 | btn_held = 0; 193 | } 194 | } 195 | 196 | //process any I2C commands in queue (e.g. volume change by buttons) 197 | queue_codec_ctrl_process(); 198 | } 199 | } 200 | -------------------------------------------------------------------------------- /lib/STM32F4xx_StdPeriph_Driver/inc/stm32f4xx_pwr.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file stm32f4xx_pwr.h 4 | * @author MCD Application Team 5 | * @version V1.1.0 6 | * @date 11-January-2013 7 | * @brief This file contains all the functions prototypes for the PWR firmware 8 | * library. 9 | ****************************************************************************** 10 | * @attention 11 | * 12 | *

© COPYRIGHT 2013 STMicroelectronics

13 | * 14 | * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); 15 | * You may not use this file except in compliance with the License. 16 | * You may obtain a copy of the License at: 17 | * 18 | * http://www.st.com/software_license_agreement_liberty_v2 19 | * 20 | * Unless required by applicable law or agreed to in writing, software 21 | * distributed under the License is distributed on an "AS IS" BASIS, 22 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 23 | * See the License for the specific language governing permissions and 24 | * limitations under the License. 25 | * 26 | ****************************************************************************** 27 | */ 28 | 29 | /* Define to prevent recursive inclusion -------------------------------------*/ 30 | #ifndef __STM32F4xx_PWR_H 31 | #define __STM32F4xx_PWR_H 32 | 33 | #ifdef __cplusplus 34 | extern "C" { 35 | #endif 36 | 37 | /* Includes ------------------------------------------------------------------*/ 38 | #include "stm32f4xx.h" 39 | 40 | /** @addtogroup STM32F4xx_StdPeriph_Driver 41 | * @{ 42 | */ 43 | 44 | /** @addtogroup PWR 45 | * @{ 46 | */ 47 | 48 | /* Exported types ------------------------------------------------------------*/ 49 | /* Exported constants --------------------------------------------------------*/ 50 | 51 | /** @defgroup PWR_Exported_Constants 52 | * @{ 53 | */ 54 | 55 | /** @defgroup PWR_PVD_detection_level 56 | * @{ 57 | */ 58 | 59 | #define PWR_PVDLevel_0 PWR_CR_PLS_LEV0 60 | #define PWR_PVDLevel_1 PWR_CR_PLS_LEV1 61 | #define PWR_PVDLevel_2 PWR_CR_PLS_LEV2 62 | #define PWR_PVDLevel_3 PWR_CR_PLS_LEV3 63 | #define PWR_PVDLevel_4 PWR_CR_PLS_LEV4 64 | #define PWR_PVDLevel_5 PWR_CR_PLS_LEV5 65 | #define PWR_PVDLevel_6 PWR_CR_PLS_LEV6 66 | #define PWR_PVDLevel_7 PWR_CR_PLS_LEV7 67 | 68 | #define IS_PWR_PVD_LEVEL(LEVEL) (((LEVEL) == PWR_PVDLevel_0) || ((LEVEL) == PWR_PVDLevel_1)|| \ 69 | ((LEVEL) == PWR_PVDLevel_2) || ((LEVEL) == PWR_PVDLevel_3)|| \ 70 | ((LEVEL) == PWR_PVDLevel_4) || ((LEVEL) == PWR_PVDLevel_5)|| \ 71 | ((LEVEL) == PWR_PVDLevel_6) || ((LEVEL) == PWR_PVDLevel_7)) 72 | /** 73 | * @} 74 | */ 75 | 76 | 77 | /** @defgroup PWR_Regulator_state_in_STOP_mode 78 | * @{ 79 | */ 80 | 81 | #define PWR_Regulator_ON ((uint32_t)0x00000000) 82 | #define PWR_Regulator_LowPower PWR_CR_LPDS 83 | #define IS_PWR_REGULATOR(REGULATOR) (((REGULATOR) == PWR_Regulator_ON) || \ 84 | ((REGULATOR) == PWR_Regulator_LowPower)) 85 | /** 86 | * @} 87 | */ 88 | 89 | /** @defgroup PWR_STOP_mode_entry 90 | * @{ 91 | */ 92 | 93 | #define PWR_STOPEntry_WFI ((uint8_t)0x01) 94 | #define PWR_STOPEntry_WFE ((uint8_t)0x02) 95 | #define IS_PWR_STOP_ENTRY(ENTRY) (((ENTRY) == PWR_STOPEntry_WFI) || ((ENTRY) == PWR_STOPEntry_WFE)) 96 | 97 | /** @defgroup PWR_Regulator_Voltage_Scale 98 | * @{ 99 | */ 100 | 101 | #define PWR_Regulator_Voltage_Scale1 ((uint32_t)0x0000C000) 102 | #define PWR_Regulator_Voltage_Scale2 ((uint32_t)0x00008000) 103 | #define PWR_Regulator_Voltage_Scale3 ((uint32_t)0x00004000) 104 | #define IS_PWR_REGULATOR_VOLTAGE(VOLTAGE) (((VOLTAGE) == PWR_Regulator_Voltage_Scale1) || \ 105 | ((VOLTAGE) == PWR_Regulator_Voltage_Scale2) || \ 106 | ((VOLTAGE) == PWR_Regulator_Voltage_Scale3)) 107 | 108 | /** 109 | * @} 110 | */ 111 | 112 | /** @defgroup PWR_Flag 113 | * @{ 114 | */ 115 | 116 | #define PWR_FLAG_WU PWR_CSR_WUF 117 | #define PWR_FLAG_SB PWR_CSR_SBF 118 | #define PWR_FLAG_PVDO PWR_CSR_PVDO 119 | #define PWR_FLAG_BRR PWR_CSR_BRR 120 | #define PWR_FLAG_VOSRDY PWR_CSR_VOSRDY 121 | 122 | /** @defgroup PWR_Flag_Legacy 123 | * @{ 124 | */ 125 | #define PWR_FLAG_REGRDY PWR_FLAG_VOSRDY 126 | /** 127 | * @} 128 | */ 129 | 130 | #define IS_PWR_GET_FLAG(FLAG) (((FLAG) == PWR_FLAG_WU) || ((FLAG) == PWR_FLAG_SB) || \ 131 | ((FLAG) == PWR_FLAG_PVDO) || ((FLAG) == PWR_FLAG_BRR) || \ 132 | ((FLAG) == PWR_FLAG_VOSRDY)) 133 | 134 | #define IS_PWR_CLEAR_FLAG(FLAG) (((FLAG) == PWR_FLAG_WU) || ((FLAG) == PWR_FLAG_SB)) 135 | /** 136 | * @} 137 | */ 138 | 139 | /** 140 | * @} 141 | */ 142 | 143 | /* Exported macro ------------------------------------------------------------*/ 144 | /* Exported functions --------------------------------------------------------*/ 145 | 146 | /* Function used to set the PWR configuration to the default reset state ******/ 147 | void PWR_DeInit(void); 148 | 149 | /* Backup Domain Access function **********************************************/ 150 | void PWR_BackupAccessCmd(FunctionalState NewState); 151 | 152 | /* PVD configuration functions ************************************************/ 153 | void PWR_PVDLevelConfig(uint32_t PWR_PVDLevel); 154 | void PWR_PVDCmd(FunctionalState NewState); 155 | 156 | /* WakeUp pins configuration functions ****************************************/ 157 | void PWR_WakeUpPinCmd(FunctionalState NewState); 158 | 159 | /* Main and Backup Regulators configuration functions *************************/ 160 | void PWR_BackupRegulatorCmd(FunctionalState NewState); 161 | void PWR_MainRegulatorModeConfig(uint32_t PWR_Regulator_Voltage); 162 | 163 | /* FLASH Power Down configuration functions ***********************************/ 164 | void PWR_FlashPowerDownCmd(FunctionalState NewState); 165 | 166 | /* Low Power modes configuration functions ************************************/ 167 | void PWR_EnterSTOPMode(uint32_t PWR_Regulator, uint8_t PWR_STOPEntry); 168 | void PWR_EnterSTANDBYMode(void); 169 | 170 | /* Flags management functions *************************************************/ 171 | FlagStatus PWR_GetFlagStatus(uint32_t PWR_FLAG); 172 | void PWR_ClearFlag(uint32_t PWR_FLAG); 173 | 174 | #ifdef __cplusplus 175 | } 176 | #endif 177 | 178 | #endif /* __STM32F4xx_PWR_H */ 179 | 180 | /** 181 | * @} 182 | */ 183 | 184 | /** 185 | * @} 186 | */ 187 | 188 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 189 | -------------------------------------------------------------------------------- /src/board_config.h: -------------------------------------------------------------------------------- 1 | 2 | //#define BOARD_STM32F4_DISC1 3 | //#define BOARD_GECHO_V001 4 | #define BOARD_GECHO_V002 5 | 6 | #ifdef BOARD_STM32F4_DISC1 7 | #define ADC_SENSORS 3 //STM32F4-DISC1 8 | #define SENSORS_STM32F4_DISC1 9 | #define PREAMP_BOOST 12 //stm32f4-disc1 10 | #endif 11 | 12 | #ifdef BOARD_GECHO_V001 13 | #define ADC_SENSORS 4 //GECHO_V001 14 | 15 | #define SENSORS_GECHO_V001 16 | #define PREAMP_BOOST 12 //8 //gecho board 17 | 18 | #define BOARD_MIC_ADC_CFG_STRING ADC_PA6_PA7 19 | 20 | #define BOARD_ADC_PIN_LINEIN1 GPIO_Pin_2 //PA2 21 | #define BOARD_ADC_PIN_LINEIN2 GPIO_Pin_3 //PA3, also the SOL sensor is attached here 22 | #define BOARD_ADC_PORT_LINEIN GPIOA 23 | #define BOARD_ADC_CHANNEL_LINEIN1 ADC_Channel_2 24 | #define BOARD_ADC_CHANNEL_LINEIN2 ADC_Channel_3 25 | 26 | //#define BOARD_ADC_PIN_IR_AUDIO1 GPIO_Pin_0 27 | #define BOARD_ADC_PIN_IR_AUDIO1 GPIO_Pin_1 28 | //#define BOARD_ADC_PIN_IR_AUDIO2 GPIO_Pin_2 29 | #define BOARD_ADC_PIN_IR_AUDIO2 GPIO_Pin_3 30 | #define BOARD_ADC_PORT_IR_AUDIO GPIOC 31 | //#define BOARD_ADC_CHANNEL_IR_AUDIO1 ADC_Channel_10 32 | #define BOARD_ADC_CHANNEL_IR_AUDIO1 ADC_Channel_11 33 | //#define BOARD_ADC_CHANNEL_IR_AUDIO2 ADC_Channel_12 34 | #define BOARD_ADC_CHANNEL_IR_AUDIO2 ADC_Channel_13 35 | 36 | #define BOARD_ADC_PIN_MAG_SENSOR GPIO_Pin_5 //PA5 37 | #define BOARD_ADC_PORT_MAG_SENSOR GPIOA 38 | #define BOARD_ADC_CHANNEL_MAG_SENSOR ADC_Channel_5 39 | #define BOARD_MAG_SENSOR_VALUE_OFFSET 2048 40 | #define BOARD_MAG_SENSOR_VALUE_COEF 30 41 | 42 | #define MAG_SENSOR_SIGNAL_BOOST 1000 43 | 44 | //#define CODEC_I2C_ADDRESS_NORMAL_AD0_LOW 45 | #define CODEC_I2C_ADDRESS_ALTERNATE_AD0_HIGH //board #4 46 | //#define BYPASS_W8_0 //board #3 has some problem with PA8 47 | //#define CAN_BLOCK_SWD_DEBUG 48 | 49 | #define IR_PAIRS_CONTROLLED_BY_TWO_LINES //newer revisions - board #3+ but doesn't seem to matter for board #1 50 | 51 | //if developing, or board has no buttons 52 | //#define DIRECT_PROGRAM_START 42 //arctic wind 53 | //#define DIRECT_PROGRAM_START 123 //all LEDs test 54 | //#define DIRECT_PROGRAM_START 1 //main seq 55 | #define DIRECT_PROGRAM_START 43 //waves 56 | 57 | //#define IGNORE_PA0_IF_PULLDOWN_NOT_ASSEMBLED //prevents program shutdown and/or restart if board not completely assembled 58 | 59 | #endif 60 | 61 | 62 | #ifdef BOARD_GECHO_V002 63 | #define ADC_SENSORS 4 64 | #define SENSORS_GECHO_V002 65 | 66 | #define BOARD_MIC_ADC_CFG_STRING ADC_PA6_PA7 67 | 68 | #define BOARD_ADC_PIN_LINEIN1 GPIO_Pin_2 //PA2 69 | #define BOARD_ADC_PIN_LINEIN2 GPIO_Pin_3 //PA3 70 | #define BOARD_ADC_PORT_LINEIN GPIOA 71 | #define BOARD_ADC_CHANNEL_LINEIN1 ADC_Channel_2 72 | #define BOARD_ADC_CHANNEL_LINEIN2 ADC_Channel_3 73 | 74 | #define BOARD_ADC_PIN_IR_AUDIO1 GPIO_Pin_1 75 | #define BOARD_ADC_PIN_IR_AUDIO2 GPIO_Pin_3 76 | #define BOARD_ADC_PORT_IR_AUDIO GPIOC 77 | #define BOARD_ADC_CHANNEL_IR_AUDIO1 ADC_Channel_11 78 | #define BOARD_ADC_CHANNEL_IR_AUDIO2 ADC_Channel_13 79 | 80 | #define BOARD_ADC_PIN_MAG_SENSOR GPIO_Pin_1 //PA1 81 | #define BOARD_ADC_PORT_MAG_SENSOR GPIOA 82 | #define BOARD_ADC_CHANNEL_MAG_SENSOR ADC_Channel_1 83 | #define BOARD_MAG_SENSOR_VALUE_OFFSET 2048 //2240 84 | #define BOARD_MAG_SENSOR_VALUE_COEF 30 85 | 86 | #define MAG_SENSOR_SIGNAL_BOOST 50 87 | 88 | #define CODEC_I2C_ADDRESS_NORMAL_AD0_LOW 89 | #define IR_PAIRS_CONTROLLED_BY_TWO_LINES //newer revisions - board #3+ but doesn't matter for board #1 90 | #define LEDS_WHITE_BLUE_INVERTED 91 | 92 | //#define IGNORE_PA0_IF_PULLDOWN_NOT_ASSEMBLED //prevents program shutdown and/or restart if board not completely assembled 93 | 94 | //start a channel immediately - useful while developing, or if board has no buttons assembled yet 95 | //#define DIRECT_PROGRAM_START 1 //main demo song 96 | //#define DIRECT_PROGRAM_START 3 //demo song with melody 97 | //#define DIRECT_PROGRAM_START 12 //arctic wind 98 | //#define DIRECT_PROGRAM_START 24 //solaris (VIP), test manual control filters 99 | //#define DIRECT_PROGRAM_START 124 //magnetic sensor test with LEDs 100 | //#define DIRECT_PROGRAM_START 323 //all LEDs test 101 | //#define DIRECT_PROGRAM_START 141 //Goertzel detectors test via mic 102 | //#define DIRECT_PROGRAM_START 142 //Goertzel detectors test via line-in 103 | //#define DIRECT_PROGRAM_START 143 //stylus test 104 | //#define DIRECT_PROGRAM_START 22234 //line in with echo, with special effect #222 (line-in overdrive) 105 | //#define DIRECT_PROGRAM_START 114 //experimental VIP 106 | //#define DIRECT_PROGRAM_START 13 //custom song programming mode (via mic) 107 | //#define DIRECT_PROGRAM_START 14 //custom song programming mode (via line-in) 108 | //#define DIRECT_PROGRAM_START 113 //alien spaceship 109 | //#define DIRECT_PROGRAM_START 144 //talkie lib port test 110 | //#define DIRECT_PROGRAM_START 121 //mag sensor direct notes test 111 | //#define DIRECT_PROGRAM_START 1211 //IR sensor override by CV direct notes test 112 | //#define DIRECT_PROGRAM_START 1212 //MIDI out demo 113 | //#define DIRECT_PROGRAM_START 12 //Custom song programming mode (manual input using magnetic ring) 114 | //#define DIRECT_PROGRAM_START 11223 //drum kit test for tutorial 115 | //#define DIRECT_PROGRAM_START 12233 //IR remote decoding test 116 | //#define DIRECT_PROGRAM_START 12234 //song #8 - epic ad 117 | //#define DIRECT_PROGRAM_START 12243 //song #8 - epic ad + drum kit 118 | //#define DIRECT_PROGRAM_START 23 //square wave mixing test 119 | //#define DIRECT_PROGRAM_START 12334 //song #10 - jingle bells 120 | //#define DIRECT_PROGRAM_START 1111 //automatic generator 121 | //#define DIRECT_PROGRAM_START 1214 //cv-gate test 122 | //#define DIRECT_PROGRAM_START 441 //Song #1 with pickups 123 | //#define DIRECT_PROGRAM_START 444 //Pachelbel with pickups 124 | //#define DIRECT_PROGRAM_START 4111 //Rachel's song 125 | //#define DIRECT_PROGRAM_START 4112 //app demo song 126 | //#define DIRECT_PROGRAM_START 333213243 //code challenge 127 | //#define DIRECT_PROGRAM_START 333213221112 //code challenge 128 | //#define DIRECT_PROGRAM_START 333213221112123432 //code challenge - longest possible (can't have 19 digits with 3 at the start) 129 | //#define DIRECT_PROGRAM_START 1223 //midi direct test 130 | //#define DIRECT_PROGRAM_START 3141232343//41412 //song of the pi 131 | //#define DIRECT_PROGRAM_START 33 //DCO synth 132 | //#define DIRECT_PROGRAM_START 234 //sequencer 133 | //#define DIRECT_PROGRAM_START 11223 //other tests 134 | //#define DIRECT_PROGRAM_START 411 //granular sampler 135 | //#define DIRECT_PROGRAM_START 234 //drum sequencer 136 | //#define DIRECT_PROGRAM_START 414 //reverb 137 | 138 | #define CAN_USE_CH340G_LEDS //can LEDs driven by USART1 be initialized normally? 139 | #define USART1_CONTROL_MODE //shall Gecho listen to USART1 commands when idle? 140 | #define CODEC_OUTPUT_LIMITER //enable hw limiter (by DAC DSP circuitry) 141 | 142 | //#define CAN_BLOCK_SWD_DEBUG //useful to disallow while developing, so you don't have to press reset at every upload 143 | 144 | #endif 145 | 146 | //#define CODEC_COMM_BLINK_TEST //test for DAC communication when buttons and rest of circuitry not assembled yet 147 | //#define CODEC_TLV 148 | //#define GECHO_V2 149 | -------------------------------------------------------------------------------- /lib/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_dbgmcu.c: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file stm32f4xx_dbgmcu.c 4 | * @author MCD Application Team 5 | * @version V1.1.0 6 | * @date 11-January-2013 7 | * @brief This file provides all the DBGMCU firmware functions. 8 | ****************************************************************************** 9 | * @attention 10 | * 11 | *

© COPYRIGHT 2013 STMicroelectronics

12 | * 13 | * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); 14 | * You may not use this file except in compliance with the License. 15 | * You may obtain a copy of the License at: 16 | * 17 | * http://www.st.com/software_license_agreement_liberty_v2 18 | * 19 | * Unless required by applicable law or agreed to in writing, software 20 | * distributed under the License is distributed on an "AS IS" BASIS, 21 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 22 | * See the License for the specific language governing permissions and 23 | * limitations under the License. 24 | * 25 | ****************************************************************************** 26 | */ 27 | 28 | /* Includes ------------------------------------------------------------------*/ 29 | #include "stm32f4xx_dbgmcu.h" 30 | 31 | /** @addtogroup STM32F4xx_StdPeriph_Driver 32 | * @{ 33 | */ 34 | 35 | /** @defgroup DBGMCU 36 | * @brief DBGMCU driver modules 37 | * @{ 38 | */ 39 | 40 | /* Private typedef -----------------------------------------------------------*/ 41 | /* Private define ------------------------------------------------------------*/ 42 | #define IDCODE_DEVID_MASK ((uint32_t)0x00000FFF) 43 | 44 | /* Private macro -------------------------------------------------------------*/ 45 | /* Private variables ---------------------------------------------------------*/ 46 | /* Private function prototypes -----------------------------------------------*/ 47 | /* Private functions ---------------------------------------------------------*/ 48 | 49 | /** @defgroup DBGMCU_Private_Functions 50 | * @{ 51 | */ 52 | 53 | /** 54 | * @brief Returns the device revision identifier. 55 | * @param None 56 | * @retval Device revision identifier 57 | */ 58 | uint32_t DBGMCU_GetREVID(void) 59 | { 60 | return(DBGMCU->IDCODE >> 16); 61 | } 62 | 63 | /** 64 | * @brief Returns the device identifier. 65 | * @param None 66 | * @retval Device identifier 67 | */ 68 | uint32_t DBGMCU_GetDEVID(void) 69 | { 70 | return(DBGMCU->IDCODE & IDCODE_DEVID_MASK); 71 | } 72 | 73 | /** 74 | * @brief Configures low power mode behavior when the MCU is in Debug mode. 75 | * @param DBGMCU_Periph: specifies the low power mode. 76 | * This parameter can be any combination of the following values: 77 | * @arg DBGMCU_SLEEP: Keep debugger connection during SLEEP mode 78 | * @arg DBGMCU_STOP: Keep debugger connection during STOP mode 79 | * @arg DBGMCU_STANDBY: Keep debugger connection during STANDBY mode 80 | * @param NewState: new state of the specified low power mode in Debug mode. 81 | * This parameter can be: ENABLE or DISABLE. 82 | * @retval None 83 | */ 84 | void DBGMCU_Config(uint32_t DBGMCU_Periph, FunctionalState NewState) 85 | { 86 | /* Check the parameters */ 87 | assert_param(IS_DBGMCU_PERIPH(DBGMCU_Periph)); 88 | assert_param(IS_FUNCTIONAL_STATE(NewState)); 89 | if (NewState != DISABLE) 90 | { 91 | DBGMCU->CR |= DBGMCU_Periph; 92 | } 93 | else 94 | { 95 | DBGMCU->CR &= ~DBGMCU_Periph; 96 | } 97 | } 98 | 99 | /** 100 | * @brief Configures APB1 peripheral behavior when the MCU is in Debug mode. 101 | * @param DBGMCU_Periph: specifies the APB1 peripheral. 102 | * This parameter can be any combination of the following values: 103 | * @arg DBGMCU_TIM2_STOP: TIM2 counter stopped when Core is halted 104 | * @arg DBGMCU_TIM3_STOP: TIM3 counter stopped when Core is halted 105 | * @arg DBGMCU_TIM4_STOP: TIM4 counter stopped when Core is halted 106 | * @arg DBGMCU_TIM5_STOP: TIM5 counter stopped when Core is halted 107 | * @arg DBGMCU_TIM6_STOP: TIM6 counter stopped when Core is halted 108 | * @arg DBGMCU_TIM7_STOP: TIM7 counter stopped when Core is halted 109 | * @arg DBGMCU_TIM12_STOP: TIM12 counter stopped when Core is halted 110 | * @arg DBGMCU_TIM13_STOP: TIM13 counter stopped when Core is halted 111 | * @arg DBGMCU_TIM14_STOP: TIM14 counter stopped when Core is halted 112 | * @arg DBGMCU_RTC_STOP: RTC Calendar and Wakeup counter stopped when Core is halted. 113 | * @arg DBGMCU_WWDG_STOP: Debug WWDG stopped when Core is halted 114 | * @arg DBGMCU_IWDG_STOP: Debug IWDG stopped when Core is halted 115 | * @arg DBGMCU_I2C1_SMBUS_TIMEOUT: I2C1 SMBUS timeout mode stopped when Core is halted 116 | * @arg DBGMCU_I2C2_SMBUS_TIMEOUT: I2C2 SMBUS timeout mode stopped when Core is halted 117 | * @arg DBGMCU_I2C3_SMBUS_TIMEOUT: I2C3 SMBUS timeout mode stopped when Core is halted 118 | * @arg DBGMCU_CAN2_STOP: Debug CAN1 stopped when Core is halted 119 | * @arg DBGMCU_CAN1_STOP: Debug CAN2 stopped when Core is halted 120 | * This parameter can be: ENABLE or DISABLE. 121 | * @retval None 122 | */ 123 | void DBGMCU_APB1PeriphConfig(uint32_t DBGMCU_Periph, FunctionalState NewState) 124 | { 125 | /* Check the parameters */ 126 | assert_param(IS_DBGMCU_APB1PERIPH(DBGMCU_Periph)); 127 | assert_param(IS_FUNCTIONAL_STATE(NewState)); 128 | 129 | if (NewState != DISABLE) 130 | { 131 | DBGMCU->APB1FZ |= DBGMCU_Periph; 132 | } 133 | else 134 | { 135 | DBGMCU->APB1FZ &= ~DBGMCU_Periph; 136 | } 137 | } 138 | 139 | /** 140 | * @brief Configures APB2 peripheral behavior when the MCU is in Debug mode. 141 | * @param DBGMCU_Periph: specifies the APB2 peripheral. 142 | * This parameter can be any combination of the following values: 143 | * @arg DBGMCU_TIM1_STOP: TIM1 counter stopped when Core is halted 144 | * @arg DBGMCU_TIM8_STOP: TIM8 counter stopped when Core is halted 145 | * @arg DBGMCU_TIM9_STOP: TIM9 counter stopped when Core is halted 146 | * @arg DBGMCU_TIM10_STOP: TIM10 counter stopped when Core is halted 147 | * @arg DBGMCU_TIM11_STOP: TIM11 counter stopped when Core is halted 148 | * @param NewState: new state of the specified peripheral in Debug mode. 149 | * This parameter can be: ENABLE or DISABLE. 150 | * @retval None 151 | */ 152 | void DBGMCU_APB2PeriphConfig(uint32_t DBGMCU_Periph, FunctionalState NewState) 153 | { 154 | /* Check the parameters */ 155 | assert_param(IS_DBGMCU_APB2PERIPH(DBGMCU_Periph)); 156 | assert_param(IS_FUNCTIONAL_STATE(NewState)); 157 | 158 | if (NewState != DISABLE) 159 | { 160 | DBGMCU->APB2FZ |= DBGMCU_Periph; 161 | } 162 | else 163 | { 164 | DBGMCU->APB2FZ &= ~DBGMCU_Periph; 165 | } 166 | } 167 | 168 | /** 169 | * @} 170 | */ 171 | 172 | /** 173 | * @} 174 | */ 175 | 176 | /** 177 | * @} 178 | */ 179 | 180 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 181 | -------------------------------------------------------------------------------- /src/hw/eeprom.c: -------------------------------------------------------------------------------- 1 | /* 2 | * eeprom.c 3 | * 4 | * Created on: Jul 14, 2016 5 | * Author: mayo 6 | */ 7 | 8 | #include "eeprom.h" 9 | #include "gpio.h" 10 | #include "leds.h" 11 | #include "stm32f4xx_pwr.h" 12 | #include 13 | #include 14 | 15 | void EEPROM_Init() 16 | { 17 | //Enable the PWR clock 18 | RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); 19 | //Enable access to the backup domain 20 | PWR_BackupAccessCmd(ENABLE); 21 | //Enable backup SRAM Clock 22 | RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_BKPSRAM, ENABLE); 23 | //Enable the Backup SRAM low power Regulator to retain it's content in VBAT mode 24 | PWR_BackupRegulatorCmd(ENABLE); 25 | 26 | // Wait until the Backup SRAM low power Regulator is ready 27 | while(PWR_GetFlagStatus(PWR_FLAG_BRR) == RESET) {}; 28 | } 29 | 30 | void EEPROM_Test() 31 | { 32 | //Enable access to the backup domain 33 | PWR_BackupAccessCmd(ENABLE); 34 | 35 | //and you can write/read datas to sram (these codes from BKP_Domain codes 36 | //in STM32F4xx_DSP_StdPeriph_Lib) (in my mcu stm32f417 BKPSRAM_BASE=0x40024000) 37 | 38 | // Write to Backup SRAM with 32-Bit Data 39 | int i, errorCount = 0; 40 | 41 | for (i = BKPSRAM_TEST_BASE; i < BKPSRAM_TEST_BASE + BKPSRAM_TEST_LENGTH; i += 4) { 42 | *(__IO uint32_t *) (i) = i; 43 | } 44 | 45 | // Check the written Data 46 | for (i = BKPSRAM_TEST_BASE; i < BKPSRAM_TEST_BASE + BKPSRAM_TEST_LENGTH; i += 4) { 47 | if ((*(__IO uint32_t *) (i)) != i){ 48 | errorCount++; 49 | } 50 | } 51 | 52 | if(errorCount) 53 | { 54 | //indicate Backup SRAM memory problem with blinking Orange LEDs 55 | for(i=0;i<16;i++) 56 | { 57 | LED_O4_set_byte(0x0f); 58 | Delay(32); 59 | LED_O4_all_OFF(); 60 | Delay(32); 61 | } 62 | } 63 | 64 | //check if settings space initialized 65 | if(!strncmp((char*)SETTINGS_BASE,"SETTINGS",8)) //check if the string stored there 66 | { 67 | //all ok 68 | } 69 | else //initialize settings space with all zeroes 70 | { 71 | memset((char*)SETTINGS_BASE,0,SETTINGS_RESERVED_LENGTH); 72 | strcpy((char*)SETTINGS_BASE,"SETTINGS"); 73 | } 74 | 75 | //Disable access to the backup domain 76 | PWR_BackupAccessCmd(DISABLE); 77 | } 78 | 79 | void EEPROM_LoadSongAndMelody(char **song_buffer, char **melody_buffer) 80 | { 81 | //Enable access to the backup domain 82 | //PWR_BackupAccessCmd(ENABLE); 83 | EEPROM_Init(); 84 | 85 | //char test[100]; 86 | //strncpy(test,SONG_STORED_ID,100); 87 | //strncpy(test,MELODY_STORED_ID,100); 88 | //test[0] = test[0]; 89 | 90 | if(!strncmp(SONG_STORED_ID,"SONG_STORED",11)) //check if someting really stored there 91 | { 92 | if(song_buffer[0]!=0) 93 | { 94 | free(song_buffer[0]); 95 | } 96 | song_buffer[0] = (char*)malloc(strlen(SONG_STORED_DATA)); 97 | strcpy(song_buffer[0],SONG_STORED_DATA); 98 | } 99 | else 100 | { 101 | song_buffer[0] = NULL; 102 | } 103 | if(!strncmp(MELODY_STORED_ID,"MELODY_STORED",13)) //check if someting really stored there 104 | { 105 | if(melody_buffer[0]!=0) 106 | { 107 | free(melody_buffer[0]); 108 | } 109 | melody_buffer[0] = (char*)malloc(strlen(MELODY_STORED_DATA)); 110 | strcpy(melody_buffer[0],MELODY_STORED_DATA); 111 | } 112 | else 113 | { 114 | melody_buffer[0] = NULL; 115 | } 116 | 117 | //strncpy(test,SONG_STORED_ID,100); 118 | //strncpy(test,MELODY_STORED_ID,100); 119 | //test[0] = test[0]; 120 | 121 | //Disable access to the backup domain 122 | PWR_BackupAccessCmd(DISABLE); 123 | } 124 | 125 | void EEPROM_StoreSongAndMelody(char *song_buffer, char *melody_buffer) 126 | { 127 | //Enable access to the backup domain 128 | //PWR_BackupAccessCmd(ENABLE); 129 | EEPROM_Init(); 130 | 131 | if(song_buffer!=0) 132 | { 133 | if(!strncmp(song_buffer,"CLEAR",5)) 134 | { 135 | strcpy(SONG_STORED_ID,""); //clear current content 136 | strcpy(SONG_STORED_DATA,""); 137 | } 138 | else 139 | { 140 | strcpy(SONG_STORED_ID,"SONG_STORED"); //write this string so we know a song was stored 141 | strcpy(SONG_STORED_DATA,song_buffer); 142 | } 143 | } 144 | 145 | if(melody_buffer!=0) 146 | { 147 | if(!strncmp(melody_buffer,"CLEAR",5)) 148 | { 149 | strcpy(MELODY_STORED_ID,""); //clear current content 150 | strcpy(MELODY_STORED_DATA,""); 151 | } 152 | else 153 | { 154 | strcpy(MELODY_STORED_ID,"MELODY_STORED"); //write this string so we know a melody was stored 155 | strcpy(MELODY_STORED_DATA,melody_buffer); 156 | } 157 | } 158 | 159 | //char test[100]; 160 | //strncpy(test,SONG_STORED_ID,100); 161 | //strncpy(test,MELODY_STORED_ID,100); 162 | //test[0] = test[0]; 163 | 164 | //Disable access to the backup domain 165 | PWR_BackupAccessCmd(DISABLE); 166 | } 167 | 168 | void EEPROM_StoreSettings_B(uint32_t settings_position,uint8_t value) 169 | { 170 | //Enable access to the backup domain 171 | //PWR_BackupAccessCmd(ENABLE); 172 | EEPROM_Init(); 173 | 174 | //memcpy(settings_position,&value,1); //write one byte 175 | ((uint8_t*)settings_position)[0] = value; 176 | 177 | //Disable access to the backup domain 178 | PWR_BackupAccessCmd(DISABLE); 179 | } 180 | 181 | void EEPROM_StoreSettings_W(uint32_t settings_position,uint16_t value) 182 | { 183 | //Enable access to the backup domain 184 | //PWR_BackupAccessCmd(ENABLE); 185 | EEPROM_Init(); 186 | 187 | //memcpy(settings_position,&value,2); //write one byte 188 | ((uint16_t*)settings_position)[0] = value; 189 | 190 | //Disable access to the backup domain 191 | PWR_BackupAccessCmd(DISABLE); 192 | } 193 | 194 | void EEPROM_StoreSettings_DW(uint32_t settings_position,uint32_t value) 195 | { 196 | //Enable access to the backup domain 197 | //PWR_BackupAccessCmd(ENABLE); 198 | EEPROM_Init(); 199 | 200 | ((uint32_t*)settings_position)[0] = value; //write four bytes 201 | 202 | //Disable access to the backup domain 203 | PWR_BackupAccessCmd(DISABLE); 204 | } 205 | 206 | uint8_t EEPROM_LoadSettings_B(uint32_t settings_position,uint8_t default_value) 207 | { 208 | uint8_t value; 209 | 210 | //Enable access to the backup domain 211 | //PWR_BackupAccessCmd(ENABLE); 212 | EEPROM_Init(); 213 | 214 | memcpy(&value, (char*)settings_position, 1); //load one byte 215 | 216 | //Disable access to the backup domain 217 | PWR_BackupAccessCmd(DISABLE); 218 | 219 | if(value==0) 220 | { 221 | return default_value; 222 | } 223 | return value; 224 | } 225 | 226 | uint16_t EEPROM_LoadSettings_W(uint32_t settings_position,uint16_t default_value) 227 | { 228 | uint16_t value; 229 | 230 | //Enable access to the backup domain 231 | //PWR_BackupAccessCmd(ENABLE); 232 | EEPROM_Init(); 233 | 234 | memcpy(&value, (char*)settings_position, 2); //load two bytes 235 | 236 | //Disable access to the backup domain 237 | PWR_BackupAccessCmd(DISABLE); 238 | 239 | if(value==0) 240 | { 241 | return default_value; 242 | } 243 | return value; 244 | } 245 | 246 | uint32_t EEPROM_LoadSettings_DW(uint32_t settings_position) 247 | { 248 | uint32_t value; 249 | 250 | //Enable access to the backup domain 251 | //PWR_BackupAccessCmd(ENABLE); 252 | EEPROM_Init(); 253 | 254 | memcpy(&value, (char*)settings_position, 4); //load four bytes 255 | 256 | //Disable access to the backup domain 257 | PWR_BackupAccessCmd(DISABLE); 258 | 259 | return value; 260 | } 261 | 262 | void EEPROM_ClearSettings() 263 | { 264 | EEPROM_Init(); 265 | memset((char*)SETTINGS_BASE,0,SETTINGS_RESERVED_LENGTH); 266 | strcpy((char*)SETTINGS_BASE,"SETTINGS"); 267 | //Disable access to the backup domain 268 | PWR_BackupAccessCmd(DISABLE); 269 | } 270 | -------------------------------------------------------------------------------- /lib/STM32F4xx_StdPeriph_Driver/inc/misc.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file misc.h 4 | * @author MCD Application Team 5 | * @version V1.1.0 6 | * @date 11-January-2013 7 | * @brief This file contains all the functions prototypes for the miscellaneous 8 | * firmware library functions (add-on to CMSIS functions). 9 | ****************************************************************************** 10 | * @attention 11 | * 12 | *

© COPYRIGHT 2013 STMicroelectronics

13 | * 14 | * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); 15 | * You may not use this file except in compliance with the License. 16 | * You may obtain a copy of the License at: 17 | * 18 | * http://www.st.com/software_license_agreement_liberty_v2 19 | * 20 | * Unless required by applicable law or agreed to in writing, software 21 | * distributed under the License is distributed on an "AS IS" BASIS, 22 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 23 | * See the License for the specific language governing permissions and 24 | * limitations under the License. 25 | * 26 | ****************************************************************************** 27 | */ 28 | 29 | /* Define to prevent recursive inclusion -------------------------------------*/ 30 | #ifndef __MISC_H 31 | #define __MISC_H 32 | 33 | #ifdef __cplusplus 34 | extern "C" { 35 | #endif 36 | 37 | /* Includes ------------------------------------------------------------------*/ 38 | #include "stm32f4xx.h" 39 | 40 | /** @addtogroup STM32F4xx_StdPeriph_Driver 41 | * @{ 42 | */ 43 | 44 | /** @addtogroup MISC 45 | * @{ 46 | */ 47 | 48 | /* Exported types ------------------------------------------------------------*/ 49 | 50 | /** 51 | * @brief NVIC Init Structure definition 52 | */ 53 | 54 | typedef struct 55 | { 56 | uint8_t NVIC_IRQChannel; /*!< Specifies the IRQ channel to be enabled or disabled. 57 | This parameter can be an enumerator of @ref IRQn_Type 58 | enumeration (For the complete STM32 Devices IRQ Channels 59 | list, please refer to stm32f4xx.h file) */ 60 | 61 | uint8_t NVIC_IRQChannelPreemptionPriority; /*!< Specifies the pre-emption priority for the IRQ channel 62 | specified in NVIC_IRQChannel. This parameter can be a value 63 | between 0 and 15 as described in the table @ref MISC_NVIC_Priority_Table 64 | A lower priority value indicates a higher priority */ 65 | 66 | uint8_t NVIC_IRQChannelSubPriority; /*!< Specifies the subpriority level for the IRQ channel specified 67 | in NVIC_IRQChannel. This parameter can be a value 68 | between 0 and 15 as described in the table @ref MISC_NVIC_Priority_Table 69 | A lower priority value indicates a higher priority */ 70 | 71 | FunctionalState NVIC_IRQChannelCmd; /*!< Specifies whether the IRQ channel defined in NVIC_IRQChannel 72 | will be enabled or disabled. 73 | This parameter can be set either to ENABLE or DISABLE */ 74 | } NVIC_InitTypeDef; 75 | 76 | /* Exported constants --------------------------------------------------------*/ 77 | 78 | /** @defgroup MISC_Exported_Constants 79 | * @{ 80 | */ 81 | 82 | /** @defgroup MISC_Vector_Table_Base 83 | * @{ 84 | */ 85 | 86 | #define NVIC_VectTab_RAM ((uint32_t)0x20000000) 87 | #define NVIC_VectTab_FLASH ((uint32_t)0x08000000) 88 | #define IS_NVIC_VECTTAB(VECTTAB) (((VECTTAB) == NVIC_VectTab_RAM) || \ 89 | ((VECTTAB) == NVIC_VectTab_FLASH)) 90 | /** 91 | * @} 92 | */ 93 | 94 | /** @defgroup MISC_System_Low_Power 95 | * @{ 96 | */ 97 | 98 | #define NVIC_LP_SEVONPEND ((uint8_t)0x10) 99 | #define NVIC_LP_SLEEPDEEP ((uint8_t)0x04) 100 | #define NVIC_LP_SLEEPONEXIT ((uint8_t)0x02) 101 | #define IS_NVIC_LP(LP) (((LP) == NVIC_LP_SEVONPEND) || \ 102 | ((LP) == NVIC_LP_SLEEPDEEP) || \ 103 | ((LP) == NVIC_LP_SLEEPONEXIT)) 104 | /** 105 | * @} 106 | */ 107 | 108 | /** @defgroup MISC_Preemption_Priority_Group 109 | * @{ 110 | */ 111 | 112 | #define NVIC_PriorityGroup_0 ((uint32_t)0x700) /*!< 0 bits for pre-emption priority 113 | 4 bits for subpriority */ 114 | #define NVIC_PriorityGroup_1 ((uint32_t)0x600) /*!< 1 bits for pre-emption priority 115 | 3 bits for subpriority */ 116 | #define NVIC_PriorityGroup_2 ((uint32_t)0x500) /*!< 2 bits for pre-emption priority 117 | 2 bits for subpriority */ 118 | #define NVIC_PriorityGroup_3 ((uint32_t)0x400) /*!< 3 bits for pre-emption priority 119 | 1 bits for subpriority */ 120 | #define NVIC_PriorityGroup_4 ((uint32_t)0x300) /*!< 4 bits for pre-emption priority 121 | 0 bits for subpriority */ 122 | 123 | #define IS_NVIC_PRIORITY_GROUP(GROUP) (((GROUP) == NVIC_PriorityGroup_0) || \ 124 | ((GROUP) == NVIC_PriorityGroup_1) || \ 125 | ((GROUP) == NVIC_PriorityGroup_2) || \ 126 | ((GROUP) == NVIC_PriorityGroup_3) || \ 127 | ((GROUP) == NVIC_PriorityGroup_4)) 128 | 129 | #define IS_NVIC_PREEMPTION_PRIORITY(PRIORITY) ((PRIORITY) < 0x10) 130 | 131 | #define IS_NVIC_SUB_PRIORITY(PRIORITY) ((PRIORITY) < 0x10) 132 | 133 | #define IS_NVIC_OFFSET(OFFSET) ((OFFSET) < 0x000FFFFF) 134 | 135 | /** 136 | * @} 137 | */ 138 | 139 | /** @defgroup MISC_SysTick_clock_source 140 | * @{ 141 | */ 142 | 143 | #define SysTick_CLKSource_HCLK_Div8 ((uint32_t)0xFFFFFFFB) 144 | #define SysTick_CLKSource_HCLK ((uint32_t)0x00000004) 145 | #define IS_SYSTICK_CLK_SOURCE(SOURCE) (((SOURCE) == SysTick_CLKSource_HCLK) || \ 146 | ((SOURCE) == SysTick_CLKSource_HCLK_Div8)) 147 | /** 148 | * @} 149 | */ 150 | 151 | /** 152 | * @} 153 | */ 154 | 155 | /* Exported macro ------------------------------------------------------------*/ 156 | /* Exported functions --------------------------------------------------------*/ 157 | 158 | void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup); 159 | void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct); 160 | void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset); 161 | void NVIC_SystemLPConfig(uint8_t LowPowerMode, FunctionalState NewState); 162 | void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource); 163 | 164 | #ifdef __cplusplus 165 | } 166 | #endif 167 | 168 | #endif /* __MISC_H */ 169 | 170 | /** 171 | * @} 172 | */ 173 | 174 | /** 175 | * @} 176 | */ 177 | 178 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 179 | --------------------------------------------------------------------------------