├── .clang-format ├── .gitignore ├── .gitmodules ├── LICENSE ├── Makefile ├── README.org ├── assets ├── equations.gcx ├── ex06-dag.png ├── ex07-dag.png ├── gangknob48_12_bg.png ├── moogknob48_16_bg.png └── ws-ldn-12-minigorille.jpg ├── cleanup ├── ext └── usbh_midi │ ├── usbh_MIDI.c │ └── usbh_MIDI.h ├── make ├── devices │ ├── stm32f746.ld │ └── stm32f746.make ├── modules │ ├── ex01.make │ ├── ex02.make │ ├── ex03.make │ ├── ex04.make │ ├── ex05.make │ ├── ex06.make │ ├── ex07.make │ └── ex08.make └── sources.txt └── src ├── common ├── clockconfig.c ├── clockconfig.h ├── handlers.c ├── sdram_alloc.c └── sdram_alloc.h ├── ex01 └── main.c ├── ex02 ├── main.c └── moogknob.c ├── ex03 └── main.c ├── ex04 └── main.c ├── ex05 ├── ffconf.h ├── main.c ├── usbh_conf.c └── usbh_conf.h ├── ex06 └── main.c ├── ex07 └── main.c ├── ex08 ├── main.c ├── usbh_conf.c └── usbh_conf.h ├── stm32f7xx_hal_conf.h └── synth_extras ├── midi_log.c ├── midi_log.h ├── osc_noise.c ├── osc_noise.h ├── sdram_delay.c └── sdram_delay.h /.clang-format: -------------------------------------------------------------------------------- 1 | BasedOnStyle: Google 2 | AllowAllParametersOfDeclarationOnNextLine: false 3 | AlignConsecutiveAssignments: true 4 | AllowShortBlocksOnASingleLine: false 5 | AllowShortFunctionsOnASingleLine: false 6 | AllowShortIfStatementsOnASingleLine: false 7 | AllowShortLoopsOnASingleLine: false 8 | BinPackParameters: false 9 | BreakBeforeBraces: Attach 10 | ColumnLimit: 80 11 | ReflowComments: false 12 | SortIncludes: true -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /bin 2 | /build 3 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "ext/ct-head"] 2 | path = ext/ct-head 3 | url = https://github.com/thi-ng/ct-head 4 | branch = master 5 | [submodule "ext/ct-gui"] 6 | path = ext/ct-gui 7 | url = https://github.com/thi-ng/ct-gui 8 | branch = master 9 | [submodule "ext/ct-synstack"] 10 | path = ext/ct-synstack 11 | url = https://github.com/thi-ng/synstack 12 | branch = master 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ifndef STM_CUBE_HOME 2 | $(error STM_CUBE_HOME is not set) 3 | endif 4 | 5 | STM_SRC_ROOT = $(STM_CUBE_HOME)/Drivers 6 | CMSIS_DIR = $(STM_SRC_ROOT)/CMSIS 7 | LL_DIR = $(STM_SRC_ROOT)/BSP/Components 8 | USBH_DIR = $(STM_CUBE_HOME)/Middlewares/ST/STM32_USB_Host_Library 9 | FATFS_DIR = $(STM_CUBE_HOME)/Middlewares/Third_Party/FatFs/src 10 | 11 | ifndef device 12 | device = stm32f746 13 | endif 14 | 15 | ifndef module 16 | module = ex01 17 | endif 18 | 19 | USER_SRC_DIR = src 20 | EXT_SRC_DIR = ext 21 | LIB_DIR = lib 22 | BUILD_DIR = build/$(module) 23 | BIN_DIR = bin/$(module) 24 | 25 | include make/devices/$(device).make 26 | 27 | $(info building module: $(module)) 28 | include make/modules/$(module).make 29 | 30 | ifndef catalog 31 | catalog = make/sources.txt 32 | endif 33 | 34 | $(info using source catalog: $(catalog)) 35 | SRC_FILTER = $(shell grep -v '\#' $(catalog)) 36 | 37 | CC = arm-none-eabi-gcc 38 | LD = arm-none-eabi-g++ 39 | OBJCOPY = arm-none-eabi-objcopy 40 | SIZE = arm-none-eabi-size 41 | 42 | ifndef TARGET_NAME 43 | TARGET_NAME = app 44 | endif 45 | 46 | TARGET_ELF = $(BIN_DIR)/$(TARGET_NAME).elf 47 | TARGET_BIN = $(BIN_DIR)/$(TARGET_NAME).bin 48 | TARGET_SIZE = $(BIN_DIR)/$(TARGET_NAME).siz 49 | 50 | CMSIS_INCLUDES = -I$(CMSIS_DIR)/Include -I$(DEVICE_DIR)/Include 51 | CMSIS_SRC = $(filter $(SRC_FILTER), $(wildcard $(DEVICE_DIR)/Source/Templates/*.c)) 52 | 53 | HAL_INCLUDES = -I$(HAL_DIR)/Inc 54 | HAL_SRC = $(filter $(SRC_FILTER), $(wildcard $(HAL_DIR)/Src/*.c)) 55 | 56 | BSP_INCLUDES = -I$(BSP_DIR) 57 | BSP_SRC = $(filter $(SRC_FILTER), $(wildcard $(BSP_DIR)/*.c)) 58 | 59 | ifeq ($(USE_USBH),1) 60 | $(info including USBH...) 61 | USBH_INCLUDES += -I$(USBH_DIR)/Core/Inc -I$(USBH_DIR)/Class/AUDIO/Inc -I$(USBH_DIR)/Class/MSC/Inc 62 | USBH_SRC += $(filter $(SRC_FILTER), $(wildcard $(USBH_DIR)/Core/Src/*.c)) 63 | USBH_SRC += $(wildcard $(USBH_DIR)/Class/AUDIO/Src/*.c) 64 | USBH_SRC += $(wildcard $(USBH_DIR)/Class/MSC/Src/*.c) 65 | endif 66 | 67 | ifeq ($(USE_FATFS),1) 68 | $(info including FatFS...) 69 | FATFS_INCLUDES += -I$(FATFS_DIR) -I$(FATFS_DIR)/drivers 70 | FATFS_SRC += $(wildcard $(FATFS_DIR)/*.c) 71 | FATFS_SRC += $(filter $(SRC_FILTER), $(wildcard $(FATFS_DIR)/drivers/*.c)) 72 | FATFS_SRC += $(filter $(SRC_FILTER), $(wildcard $(FATFS_DIR)/option/*.c)) 73 | endif 74 | 75 | SYS_INCLUDES = $(CMSIS_INCLUDES) $(HAL_INCLUDES) $(BSP_INCLUDES) $(USBH_INCLUDES) $(FATFS_INCLUDES) 76 | SYS_SRC = $(CMSIS_SRC) $(HAL_SRC) $(BSP_SRC) $(LL_SRC) $(USBH_SRC) $(FATFS_SRC) 77 | 78 | USER_INCLUDES += -I$(USER_SRC_DIR) -Iext 79 | USER_SRC += $(wildcard $(USER_SRC_DIR)/common/*.c) $(wildcard $(USER_SRC_DIR)/$(module)/*.c) 80 | 81 | ALL_INCLUDES = $(USER_INCLUDES) $(SYS_INCLUDES) 82 | ALL_SRC = $(SYS_SRC) $(USER_SRC) 83 | 84 | ASM_OBJ = $(addprefix $(BUILD_DIR)/, $(notdir $(ASM_SRC:.s=.o))) 85 | 86 | C_OBJ += $(addprefix $(BUILD_DIR)/, $(notdir $(ALL_SRC:.c=.o))) 87 | 88 | DEPS += $(ASM_OBJ:.o=.d) $(C_OBJ:.o=.d) 89 | 90 | LIBS += -lm 91 | 92 | CFLAGS += -std=c11 -fsigned-char -ffunction-sections -fdata-sections -Wall 93 | 94 | LD_FLAGS += -Lmake/devices -L$(LIB_DIR) 95 | LD_FLAGS += -Xlinker --gc-sections -Wl,-Map,$(BIN_DIR)/$(TARGET_NAME).map 96 | LD_FLAGS += -specs=nosys.specs -specs=nano.specs 97 | 98 | # Used to enable rules below, allows building from given source list 99 | # http://stackoverflow.com/a/24967712/294515 100 | .SECONDEXPANSION: 101 | PERCENT = % 102 | 103 | all: $(BUILD_DIR) $(BIN_DIR) $(TARGET_ELF) $(TARGET_BIN) $(TARGET_SIZE) 104 | @: 105 | 106 | $(BUILD_DIR): 107 | @echo Creating $(BUILD_DIR) 108 | @mkdir -p $(BUILD_DIR) 109 | 110 | $(BIN_DIR): 111 | @echo Creating $(BIN_DIR) 112 | @mkdir -p $(BIN_DIR) 113 | 114 | $(TARGET_ELF): $(C_OBJ) $(ASM_OBJ) 115 | @echo Linking target: $(TARGET_ELF) 116 | $(CC) $(CFLAGS) $(LD_FLAGS) -o $@ $^ $(LIBS) 117 | 118 | $(TARGET_BIN): $(TARGET_ELF) 119 | @echo Creating flash image: $@ 120 | @$(OBJCOPY) -O binary $< $@ 121 | 122 | $(TARGET_SIZE): $(TARGET_ELF) 123 | @$(SIZE) --format=berkeley -x --totals $(TARGET_ELF) 124 | 125 | $(C_OBJ): %.o : $$(filter $$(PERCENT)/$$(notdir %).c, $(ALL_SRC)) 126 | @echo compiling: $(notdir $<) 127 | @$(CC) $(DEFINES) $(ALL_INCLUDES) $(CFLAGS) -o $@ -c $< -MMD -MP -MF "$(@:%.o=%.d)" 128 | 129 | $(ASM_OBJ): %.o : $$(filter $$(PERCENT)/$$(notdir %).s, $(ASM_SRC)) 130 | @echo assembling: $(notdir $<) 131 | @$(CC) $(DEFINES) $(ALL_INCLUDES) $(CFLAGS) -o $@ -c $< -MMD -MP -MF "$(@:%.o=%.d)" 132 | 133 | -include $(DEPS) 134 | 135 | .PHONY: clean trace 136 | 137 | clean: 138 | @echo Cleaning... 139 | rm -rf $(BUILD_DIR) $(BIN_DIR) 140 | 141 | trace: 142 | @echo SRC_FILTER: $(SRC_FILTER) 143 | @echo BSP: $(BSP_SRC) 144 | @echo HAL: $(HAL_SRC) 145 | @echo ALL_INCL: $(ALL_INCLUDES) 146 | @echo ALL_SRC: $(ALL_SRC) $(ASM_SRC) 147 | @echo OBJ: $(C_OBJ) $(ASM_OBJ) 148 | @echo DEPS: $(DEPS) 149 | -------------------------------------------------------------------------------- /README.org: -------------------------------------------------------------------------------- 1 | * thi.ng/ws-ldn-12 2 | ARM / STM32F7 DIY synth workshop (STM32F746-DISCO) 3 | 4 | [[./assets/ws-ldn-12-minigorille.jpg]] 5 | 6 | Photo by Lysandre Follet 7 | 8 | *[[https://soundcloud.com/forthcharlie/sets/stm32f4][Check out demo tracks on Soundcloud]]* 9 | 10 | ** Project setup 11 | 12 | This repo contains 8 sub-projects, all described below and each 13 | compilable as standalone application. The repo also includes various 14 | support libraries of the thi.ng collection as Git submodules, located 15 | in the [[./ext][/ext]] folder: 16 | 17 | - [[http://thi.ng/ct-gui][ct-gui]] - tiny GUI library 18 | - [[http://thi.ng/ct-head][ct-head]] - common headers, macros & utils 19 | - [[http://thi.ng/synstack][ct-synstack]] - softsynth / DSP engine 20 | 21 | #+BEGIN_SRC shell 22 | # clone with submodules 23 | git clone https://github.com/thi-ng/ws-ldn-12 --recursive 24 | #+END_SRC 25 | 26 | *** Other 3rd party dependecies 27 | 28 | - [[http://www.st.com/web/en/catalog/tools/PF261909][STM32 CubeF7 SDK]] 29 | - [[https://launchpad.net/gcc-arm-embedded][GCC ARM toolchain]] 30 | - [[https://github.com/texane/stlink][ST-Link]] 31 | - [[https://gnuarmeclipse.github.io/openocd/releases/][OpenOCD]] (optional, using dev version w/ STM32F746 support) 32 | ** Building 33 | 34 | This repo uses a flexible =Makefile= to build all included 35 | projects - *no IDE required!* The setup features: 36 | 37 | - easily customizable device config & linker scripts 38 | - no requirement to manually copy STM Cube SDK sources 39 | - catalog file(s) to selectively exclude various SDK source files (see 40 | [[./make/sources.txt][/make/sources.txt]], can be overridden per project) 41 | - config flags to include USBH & FatFs middlewares 42 | - support for multiple sub-projects (with & without shared sources) 43 | - individual module (sub-project) configs (e.g. [[./make/modules/ex08.make][/make/modules/ex08.make]]) 44 | - separate build & target folders for each module 45 | 46 | Currently only the STM32F746-DISCO board is supported, but additional 47 | board configurations can be easily added (see [[./make/devices/][/make/devices/]] for 48 | reference). 49 | 50 | *IMPORTANT:* The =Makefile= requires the env var =STM_CUBE_HOME= to be 51 | set to the root of your STM SDK directory, e.g. 52 | =~/dev/arm/STM32Cube_FW_F7_V1.4.0=. 53 | 54 | #+BEGIN_SRC shell 55 | export STM_CUBE_HOME=~/dev/arm/STM32Cube_FW_F7_V1.4.0 56 | 57 | make module=ex01 clean 58 | make module=ex01 -j4 59 | 60 | # flash device (0x800000 is ROM start address) 61 | st-flash --reset write bin/ex01/app.bin 0x8000000 62 | 63 | # combine for improved usability in terminal 64 | make module=ex01 -j4 && st-flash --reset write bin/ex01/app.bin 0x8000000 65 | #+END_SRC 66 | 67 | ** Examples 68 | *** ex01 - blinky 69 | 70 | [[./src/ex01/main.c][Source]] 71 | 72 | Simple Hello World LED blink example & demo of using EXTI interrupt to 73 | react to user button. Stops/starts blinking each time button is 74 | pressed. 75 | 76 | *** ex02 - LCD, touchscreen & GUI basics 77 | 78 | [[./src/ex02/main.c][Source]] 79 | 80 | Basic demonstration of working with BSP LCD & touchscreen modules, as 81 | well as intro to working w/ external libraries (here 82 | [[http://thi.ng/ct-gui][thi.ng/ct-gui]]). 83 | 84 | Edit the source file to [[./src/ex02/main.c#L28][uncomment different demo modes]]: 85 | 86 | - =demoWelcome()= - simple text rendering & random dots, non-interactive 87 | - =demoScribble()= - 5 point multi-touch drawing 88 | - =demoGUI()= - basic GUI usage example (dials control nothing) 89 | 90 | *** ex03 - Timers 91 | 92 | [[./src/ex03/main.c][Source]] 93 | 94 | Basic timer setup & multi-tasking example. Timer runs @ 10kHz and 95 | controls simple LED blinking task. Task can be suspended interactively 96 | by pressing user button. 97 | 98 | *** ex04 - Oscillators 99 | 100 | [[./src/ex04/main.c][Source]] 101 | 102 | Simple oscillator & frequency modulation experiment. The following 103 | oscillator types are supported for both main osc & modulator: 104 | 105 | | *ID* | *Type* | 106 | |------+-------------------------------| 107 | | 0 | Sine | 108 | | 1 | Saw | 109 | | 2 | Square | 110 | | 3 | Triangle | 111 | | 4 | Saw + Sin | 112 | | 5 | Noise (uses [[http://xoroshiro.di.unimi.it/][Xorshift128]] PRNG) | 113 | 114 | *Important:* The =mod_amp= field of the =Oscillator= struct is the 115 | modulation amplitude, but since the modulator is acting in the 116 | frequency domain, this amplitude too is in Hz. 117 | 118 | *** ex05 - USB stick WAV file streaming playback 119 | 120 | [[./src/ex05/main.c][Source]] 121 | 122 | This example uses the STM USB Host library & FatFS to access a USB 123 | memory stick connected to the board. Once USB handshake is complete, 124 | the app will then attempt to read the file =sound.wav= located in the 125 | root of the USB filesystem and start streaming to the headphone audio 126 | output (looping playback). 127 | 128 | *Important:* 129 | - The WAV file MUST be in 44.1kHz, 16bit stereo format 130 | - The example is currently configured to use the USB FS (fullspeed) 131 | port (not HS (highspeed)). This can be changed via the 132 | =ex05/usbh_conf.h= file. 133 | 134 | *** ex06 - thi.ng/synstack basics 135 | 136 | [[./src/ex06/main.c][Source]] | [[https://soundcloud.com/forthcharlie/stm32f7-synstack-ex06-ws-ldn-12][Soundcloud]] 137 | 138 | First example using [[http://thi.ng/synstack][thi.ng/synstack]] to implement polyphonic synth with 139 | fully configurable node based DSP graph (1 graph per voice). The graph 140 | implemented is shown below. 141 | 142 | We also define a musical scale to play a randomized, but always 143 | harmonic sequence and show how to dynamically modify parameters of the 144 | DSP node. 145 | 146 | *Note*: The graph doesn't show global LFOs, which are used for various 147 | modulation purposes (env mod, freq etc.). 148 | 149 | #+BEGIN_SRC dot :file assets/ex06-dag.png :exports results 150 | digraph g { 151 | rankdir=LR; 152 | node[color="black",style="filled",fontname="Inconsolata",fontcolor="white",fontsize=11]; 153 | edge[fontname="Inconsolata",fontsize=9]; 154 | 155 | env[label="AD(S)R"]; 156 | osc1[label="osc #1\n(spiral)"]; 157 | osc2[label="osc #2\n(saw-sin)"]; 158 | mul1[shape="circle",label="*"]; 159 | mul2[shape="circle",label="*"]; 160 | sum[shape="circle",label="+"]; 161 | filter[label="biquad LPF\n(randomized)"]; 162 | pan[label="stereo pan"]; 163 | delay[label="delay"]; 164 | env -> mul1; 165 | env -> mul2; 166 | osc1 -> mul1 -> sum; 167 | osc2 -> mul2 -> sum; 168 | sum -> filter -> pan -> delay; 169 | } 170 | #+END_SRC 171 | 172 | #+RESULTS: 173 | [[file:assets/ex06-dag.png]] 174 | 175 | *** ex07 - thi.ng/synstack & custom SDRAM delay 176 | 177 | [[./src/ex07/main.c][Source]] | [[https://soundcloud.com/forthcharlie/stm32f7-synstack-3-osc-fb-sdramdelay][Soundcloud]] 178 | 179 | Similar setup to *ex06* above, however to enable much longer delay 180 | times and not be limited by the <320KB of available on-chip RAM of the 181 | STM32F746-DISCO board, this example uses the 8MB "external" SDRAM 182 | (still on-board, just not in-chip), a [[./src/common/sdram_alloc.c][custom memory allocator]] 183 | (targetting SDRAM) and shows how to easily extend Synstack with custom 184 | DSP nodes - in this case a [[./src/synth_extras/osc_noise.c][noise oscillator]] and a [[./src/synth_extras/sdram_delay.c][new delay node]], 185 | which stores its long delay line in SDRAM, but then has to work with 186 | small, windowed sections in main RAM and mirror them back & forth. 187 | 188 | We also updated the DSP node graph to add the new oscillator, foldback 189 | distortion and replace the old delay with the new one... 190 | 191 | #+BEGIN_SRC dot :file assets/ex07-dag.png :exports results 192 | digraph g { 193 | rankdir=LR; 194 | node[color="black",style="filled",fontname="Inconsolata",fontcolor="white",fontsize=11]; 195 | edge[fontname="Inconsolata",fontsize=9]; 196 | 197 | env[label="AD(S)R"]; 198 | osc1[label="osc #1\n(spiral)"]; 199 | osc2[label="osc #2\n(saw-sin)"]; 200 | osc3[label="osc #3\n(noise)", color="red"]; 201 | mul1[shape="circle",label="*"]; 202 | mul2[shape="circle",label="*"]; 203 | mul3[shape="circle",label="*"]; 204 | sum[shape="circle",label="+"]; 205 | sum2[shape="circle",label="+"]; 206 | fb[label="foldback\ndistortion", color="red"]; 207 | filter[label="biquad LPF\n(randomized)"]; 208 | pan[label="stereo pan"]; 209 | delay[label="SDRAM delay", color="red"]; 210 | env -> mul1; 211 | env -> mul2; 212 | osc1 -> mul1 -> sum -> sum2; 213 | osc2 -> mul2 -> sum; 214 | osc3 -> mul3 -> sum2; 215 | sum2 -> fb -> filter -> pan -> delay; 216 | } 217 | #+END_SRC 218 | 219 | #+RESULTS: 220 | [[file:assets/ex07-dag.png]] 221 | 222 | *** ex08 - Synstack & MIDI 223 | 224 | [[./src/ex08/main.c][Source]] 225 | 226 | Based on *ex07* synth setup, but with USB MIDI support to turn synth 227 | into actual instrument (4 voice polyphonic). Via the optional 228 | =LOG_MIDI= flag (defined in [[./make/modules/ex08.make][ex08.make]]), received MIDI message can be 229 | logged to the board's LCD screen. 230 | 231 | *Note:* Currently the synth only accepts MIDI Note On messages and 232 | ignores MIDI Note Off's, since all voices only use an ADR envelope, 233 | without "sustain" phase. This will be added later... 234 | ** Resources 235 | 236 | - http://asm.thi.ng/ - links to all required SDK & build tools, 237 | references, learning resources... 238 | 239 | ** Contributors 240 | 241 | | *Name* | *Role* | *Website* | 242 | | [[mailto:k@thi.ng][Karsten Schmidt]] | initiator & principal developer | [[http://thi.ng][thi.ng]] | 243 | 244 | ** License 245 | 246 | This project is open source and licensed under the [[http://www.apache.org/licenses/LICENSE-2.0][Apache Software License 2.0]]. 247 | -------------------------------------------------------------------------------- /assets/equations.gcx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thi-ng/ws-ldn-12/c8f449408ff1d617470f3f57f1f185ab9158f999/assets/equations.gcx -------------------------------------------------------------------------------- /assets/ex06-dag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thi-ng/ws-ldn-12/c8f449408ff1d617470f3f57f1f185ab9158f999/assets/ex06-dag.png -------------------------------------------------------------------------------- /assets/ex07-dag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thi-ng/ws-ldn-12/c8f449408ff1d617470f3f57f1f185ab9158f999/assets/ex07-dag.png -------------------------------------------------------------------------------- /assets/gangknob48_12_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thi-ng/ws-ldn-12/c8f449408ff1d617470f3f57f1f185ab9158f999/assets/gangknob48_12_bg.png -------------------------------------------------------------------------------- /assets/moogknob48_16_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thi-ng/ws-ldn-12/c8f449408ff1d617470f3f57f1f185ab9158f999/assets/moogknob48_16_bg.png -------------------------------------------------------------------------------- /assets/ws-ldn-12-minigorille.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thi-ng/ws-ldn-12/c8f449408ff1d617470f3f57f1f185ab9158f999/assets/ws-ldn-12-minigorille.jpg -------------------------------------------------------------------------------- /cleanup: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | find . \( -name \*.c -or -name \*.cpp -or -name \*.cc -or -name \*.h \) \ 3 | -not -path "./ext/*" \ 4 | | xargs -n12 -P4 clang-format -i 5 | -------------------------------------------------------------------------------- /ext/usbh_midi/usbh_MIDI.c: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file usbh_MIDI.c 4 | * @author Xavier Halgand 5 | * @version 6 | * @date 7 | * @brief This file is the MIDI Layer Handlers for USB Host MIDI streaming class. 8 | * 9 | * 10 | ****************************************************************************** 11 | */ 12 | 13 | /* 14 | * This program is free software; you can redistribute it and/or modify 15 | * it under the terms of the GNU General Public License as published by 16 | * the Free Software Foundation; either version 2 of the License, or 17 | * (at your option) any later version. 18 | * 19 | * This program is distributed in the hope that it will be useful, 20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 | * GNU General Public License for more details. 23 | * 24 | * You should have received a copy of the GNU General Public License 25 | * along with this program; if not, write to the Free Software 26 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 27 | * 28 | */ 29 | 30 | /* Includes ------------------------------------------------------------------*/ 31 | #include "usbh_MIDI.h" 32 | 33 | /*------------------------------------------------------------------------------------------------------------------------------*/ 34 | 35 | /** @defgroup USBH_MIDI_CORE_Private_FunctionPrototypes 36 | * @{ 37 | */ 38 | 39 | static USBH_StatusTypeDef USBH_MIDI_InterfaceInit(USBH_HandleTypeDef *phost); 40 | 41 | static USBH_StatusTypeDef USBH_MIDI_InterfaceDeInit(USBH_HandleTypeDef *phost); 42 | 43 | static USBH_StatusTypeDef USBH_MIDI_Process(USBH_HandleTypeDef *phost); 44 | 45 | static USBH_StatusTypeDef USBH_MIDI_SOFProcess(USBH_HandleTypeDef *phost); 46 | 47 | static USBH_StatusTypeDef USBH_MIDI_ClassRequest(USBH_HandleTypeDef *phost); 48 | 49 | static void MIDI_ProcessTransmission(USBH_HandleTypeDef *phost); 50 | 51 | static void MIDI_ProcessReception(USBH_HandleTypeDef *phost); 52 | 53 | /*-------------------------------------------------------------------------*/ 54 | 55 | USBH_ClassTypeDef MIDI_Class = { 56 | "MIDI", USB_AUDIO_CLASS, USBH_MIDI_InterfaceInit, USBH_MIDI_InterfaceDeInit, 57 | USBH_MIDI_ClassRequest, 58 | USBH_MIDI_Process, // background process called in HOST_CLASS state (core state machine) 59 | USBH_MIDI_SOFProcess, 60 | NULL // MIDI handle structure 61 | }; 62 | 63 | /*------------------------------------------------------------------------------------------------------------------------------*/ 64 | 65 | /** 66 | * @brief USBH_MIDI_InterfaceInit 67 | * The function init the MIDI class. 68 | * @param phost: Host handle 69 | * @retval USBH Status 70 | */ 71 | static USBH_StatusTypeDef USBH_MIDI_InterfaceInit(USBH_HandleTypeDef *phost) { 72 | USBH_StatusTypeDef status = USBH_FAIL; 73 | uint8_t interface = 0; 74 | MIDI_HandleTypeDef *MIDI_Handle; 75 | 76 | //USB_MIDI_ChangeConnectionState(0); 77 | 78 | interface = USBH_FindInterface(phost, USB_AUDIO_CLASS, 79 | USB_MIDISTREAMING_SubCLASS, 0xFF); 80 | 81 | if (interface == 0xFF) /* No Valid Interface */ 82 | { 83 | USBH_DbgLog("Cannot Find the interface for MIDI Interface Class.", 84 | phost->pActiveClass->Name); 85 | status = USBH_FAIL; 86 | } else { 87 | USBH_SelectInterface(phost, interface); 88 | 89 | phost->pActiveClass->pData = 90 | (MIDI_HandleTypeDef *)USBH_malloc(sizeof(MIDI_HandleTypeDef)); 91 | MIDI_Handle = phost->pActiveClass->pData; 92 | 93 | if (phost->device.CfgDesc.Itf_Desc[phost->device.current_interface] 94 | .Ep_Desc[0] 95 | .bEndpointAddress & 96 | 0x80) { 97 | MIDI_Handle->InEp = 98 | (phost->device.CfgDesc.Itf_Desc[phost->device.current_interface] 99 | .Ep_Desc[0] 100 | .bEndpointAddress); 101 | MIDI_Handle->InEpSize = 102 | phost->device.CfgDesc.Itf_Desc[phost->device.current_interface] 103 | .Ep_Desc[0] 104 | .wMaxPacketSize; 105 | } else { 106 | MIDI_Handle->OutEp = 107 | (phost->device.CfgDesc.Itf_Desc[phost->device.current_interface] 108 | .Ep_Desc[0] 109 | .bEndpointAddress); 110 | MIDI_Handle->OutEpSize = 111 | phost->device.CfgDesc.Itf_Desc[phost->device.current_interface] 112 | .Ep_Desc[0] 113 | .wMaxPacketSize; 114 | } 115 | 116 | if (phost->device.CfgDesc.Itf_Desc[phost->device.current_interface] 117 | .Ep_Desc[1] 118 | .bEndpointAddress & 119 | 0x80) { 120 | MIDI_Handle->InEp = 121 | (phost->device.CfgDesc.Itf_Desc[phost->device.current_interface] 122 | .Ep_Desc[1] 123 | .bEndpointAddress); 124 | MIDI_Handle->InEpSize = 125 | phost->device.CfgDesc.Itf_Desc[phost->device.current_interface] 126 | .Ep_Desc[1] 127 | .wMaxPacketSize; 128 | } else { 129 | MIDI_Handle->OutEp = 130 | (phost->device.CfgDesc.Itf_Desc[phost->device.current_interface] 131 | .Ep_Desc[1] 132 | .bEndpointAddress); 133 | MIDI_Handle->OutEpSize = 134 | phost->device.CfgDesc.Itf_Desc[phost->device.current_interface] 135 | .Ep_Desc[1] 136 | .wMaxPacketSize; 137 | } 138 | 139 | MIDI_Handle->OutPipe = USBH_AllocPipe(phost, MIDI_Handle->OutEp); 140 | MIDI_Handle->InPipe = USBH_AllocPipe(phost, MIDI_Handle->InEp); 141 | 142 | /* Open the new channels */ 143 | USBH_OpenPipe(phost, MIDI_Handle->OutPipe, MIDI_Handle->OutEp, 144 | phost->device.address, phost->device.speed, USB_EP_TYPE_BULK, 145 | MIDI_Handle->OutEpSize); 146 | 147 | USBH_OpenPipe(phost, MIDI_Handle->InPipe, MIDI_Handle->InEp, 148 | phost->device.address, phost->device.speed, USB_EP_TYPE_BULK, 149 | MIDI_Handle->InEpSize); 150 | 151 | //USB_MIDI_ChangeConnectionState(1); 152 | MIDI_Handle->state = MIDI_IDLE_STATE; 153 | 154 | USBH_LL_SetToggle(phost, MIDI_Handle->InPipe, 0); 155 | USBH_LL_SetToggle(phost, MIDI_Handle->OutPipe, 0); 156 | status = USBH_OK; 157 | } 158 | return status; 159 | } 160 | 161 | /*------------------------------------------------------------------------------------------------------------------------------*/ 162 | 163 | /** 164 | * @brief USBH_MIDI_InterfaceDeInit 165 | * The function DeInit the Pipes used for the MIDI class. 166 | * @param phost: Host handle 167 | * @retval USBH Status 168 | */ 169 | USBH_StatusTypeDef USBH_MIDI_InterfaceDeInit(USBH_HandleTypeDef *phost) { 170 | MIDI_HandleTypeDef *MIDI_Handle = phost->pActiveClass->pData; 171 | 172 | if (MIDI_Handle->OutPipe) { 173 | USBH_ClosePipe(phost, MIDI_Handle->OutPipe); 174 | USBH_FreePipe(phost, MIDI_Handle->OutPipe); 175 | MIDI_Handle->OutPipe = 0; /* Reset the Channel as Free */ 176 | } 177 | 178 | if (MIDI_Handle->InPipe) { 179 | USBH_ClosePipe(phost, MIDI_Handle->InPipe); 180 | USBH_FreePipe(phost, MIDI_Handle->InPipe); 181 | MIDI_Handle->InPipe = 0; /* Reset the Channel as Free */ 182 | } 183 | 184 | if (phost->pActiveClass->pData) { 185 | USBH_free(phost->pActiveClass->pData); 186 | phost->pActiveClass->pData = 0; 187 | } 188 | 189 | return USBH_OK; 190 | } 191 | 192 | /*------------------------------------------------------------------------------------------------------------------------------*/ 193 | 194 | /** 195 | * @brief USBH_MIDI_ClassRequest 196 | * The function is responsible for handling Standard requests 197 | * for MIDI class. 198 | * @param phost: Host handle 199 | * @retval USBH Status 200 | */ 201 | static USBH_StatusTypeDef USBH_MIDI_ClassRequest(USBH_HandleTypeDef *phost) { 202 | phost->pUser(phost, HOST_USER_CLASS_ACTIVE); 203 | 204 | return USBH_OK; 205 | } 206 | 207 | /*------------------------------------------------------------------------------------------------------------------------------*/ 208 | 209 | /** 210 | * @brief USBH_MIDI_Stop 211 | * Stop current MIDI Transmission 212 | * @param phost: Host handle 213 | * @retval USBH Status 214 | */ 215 | USBH_StatusTypeDef USBH_MIDI_Stop(USBH_HandleTypeDef *phost) { 216 | MIDI_HandleTypeDef *MIDI_Handle = phost->pActiveClass->pData; 217 | 218 | if (phost->gState == HOST_CLASS) { 219 | MIDI_Handle->state = MIDI_IDLE_STATE; 220 | 221 | USBH_ClosePipe(phost, MIDI_Handle->InPipe); 222 | USBH_ClosePipe(phost, MIDI_Handle->OutPipe); 223 | } 224 | return USBH_OK; 225 | } 226 | 227 | /*------------------------------------------------------------------------------------------------------------------------------*/ 228 | 229 | /** 230 | * @brief USBH_MIDI_Process 231 | * The function is for managing state machine for MIDI data transfers 232 | * (background process) 233 | * @param phost: Host handle 234 | * @retval USBH Status 235 | */ 236 | static USBH_StatusTypeDef USBH_MIDI_Process(USBH_HandleTypeDef *phost) { 237 | USBH_StatusTypeDef status = USBH_BUSY; 238 | USBH_StatusTypeDef req_status = USBH_OK; 239 | MIDI_HandleTypeDef *MIDI_Handle = phost->pActiveClass->pData; 240 | 241 | switch (MIDI_Handle->state) { 242 | case MIDI_IDLE_STATE: 243 | status = USBH_OK; 244 | break; 245 | 246 | case MIDI_TRANSFER_DATA: 247 | 248 | MIDI_ProcessTransmission(phost); 249 | MIDI_ProcessReception(phost); 250 | break; 251 | 252 | case MIDI_ERROR_STATE: 253 | req_status = USBH_ClrFeature(phost, 0x00); 254 | 255 | if (req_status == USBH_OK) { 256 | /*Change the state to waiting*/ 257 | MIDI_Handle->state = MIDI_IDLE_STATE; 258 | } 259 | break; 260 | 261 | default: 262 | break; 263 | } 264 | 265 | return status; 266 | } 267 | /*------------------------------------------------------------------------------------------------------------------------------*/ 268 | 269 | /** 270 | * @brief USBH_MIDI_SOFProcess 271 | * The function is for managing SOF callback 272 | * @param phost: Host handle 273 | * @retval USBH Status 274 | */ 275 | static USBH_StatusTypeDef USBH_MIDI_SOFProcess(USBH_HandleTypeDef *phost) { 276 | return USBH_OK; 277 | } 278 | 279 | /*------------------------------------------------------------------------------------------------------------------------------*/ 280 | 281 | /** 282 | * @brief This function return last recieved data size 283 | * @param None 284 | * @retval None 285 | */ 286 | uint16_t USBH_MIDI_GetLastReceivedDataSize(USBH_HandleTypeDef *phost) { 287 | MIDI_HandleTypeDef *MIDI_Handle = phost->pActiveClass->pData; 288 | 289 | if (phost->gState == HOST_CLASS) { 290 | return USBH_LL_GetLastXferSize(phost, MIDI_Handle->InPipe); 291 | } else { 292 | return 0; 293 | } 294 | } 295 | 296 | /*------------------------------------------------------------------------------------------------------------------------------*/ 297 | 298 | /** 299 | * @brief This function prepares the state before issuing the class specific commands 300 | * @param None 301 | * @retval None 302 | */ 303 | USBH_StatusTypeDef USBH_MIDI_Transmit(USBH_HandleTypeDef *phost, 304 | uint8_t *pbuff, 305 | uint16_t length) { 306 | USBH_StatusTypeDef Status = USBH_BUSY; 307 | MIDI_HandleTypeDef *MIDI_Handle = phost->pActiveClass->pData; 308 | 309 | if ((MIDI_Handle->state == MIDI_IDLE_STATE) || 310 | (MIDI_Handle->state == MIDI_TRANSFER_DATA)) { 311 | MIDI_Handle->pTxData = pbuff; 312 | MIDI_Handle->TxDataLength = length; 313 | MIDI_Handle->state = MIDI_TRANSFER_DATA; 314 | MIDI_Handle->data_tx_state = MIDI_SEND_DATA; 315 | Status = USBH_OK; 316 | #if (USBH_USE_OS == 1) 317 | osMessagePut(phost->os_event, USBH_CLASS_EVENT, 0); 318 | #endif 319 | } 320 | return Status; 321 | } 322 | 323 | /*------------------------------------------------------------------------------------------------------------------------------*/ 324 | 325 | /** 326 | * @brief This function prepares the state before issuing the class specific commands 327 | * @param None 328 | * @retval None 329 | */ 330 | USBH_StatusTypeDef USBH_MIDI_Receive(USBH_HandleTypeDef *phost, 331 | uint8_t *pbuff, 332 | uint16_t length) { 333 | USBH_StatusTypeDef Status = USBH_BUSY; 334 | MIDI_HandleTypeDef *MIDI_Handle = phost->pActiveClass->pData; 335 | 336 | if ((MIDI_Handle->state == MIDI_IDLE_STATE) || 337 | (MIDI_Handle->state == MIDI_TRANSFER_DATA)) { 338 | MIDI_Handle->pRxData = pbuff; 339 | MIDI_Handle->RxDataLength = length; 340 | MIDI_Handle->state = MIDI_TRANSFER_DATA; 341 | MIDI_Handle->data_rx_state = MIDI_RECEIVE_DATA; 342 | Status = USBH_OK; 343 | #if (USBH_USE_OS == 1) 344 | osMessagePut(phost->os_event, USBH_CLASS_EVENT, 0); 345 | #endif 346 | } 347 | return Status; 348 | } 349 | 350 | /*------------------------------------------------------------------------------------------------------------------------------*/ 351 | 352 | /** 353 | * @brief The function is responsible for sending data to the device 354 | * @param pdev: Selected device 355 | * @retval None 356 | */ 357 | static void MIDI_ProcessTransmission(USBH_HandleTypeDef *phost) { 358 | MIDI_HandleTypeDef *MIDI_Handle = phost->pActiveClass->pData; 359 | USBH_URBStateTypeDef URB_Status = USBH_URB_IDLE; 360 | 361 | switch (MIDI_Handle->data_tx_state) { 362 | case MIDI_SEND_DATA: 363 | if (MIDI_Handle->TxDataLength > MIDI_Handle->OutEpSize) { 364 | USBH_BulkSendData(phost, MIDI_Handle->pTxData, MIDI_Handle->OutEpSize, 365 | MIDI_Handle->OutPipe, 1); 366 | } else { 367 | USBH_BulkSendData(phost, MIDI_Handle->pTxData, 368 | MIDI_Handle->TxDataLength, MIDI_Handle->OutPipe, 1); 369 | } 370 | 371 | MIDI_Handle->data_tx_state = MIDI_SEND_DATA_WAIT; 372 | 373 | break; 374 | 375 | case MIDI_SEND_DATA_WAIT: 376 | 377 | URB_Status = USBH_LL_GetURBState(phost, MIDI_Handle->OutPipe); 378 | 379 | /*Check the status done for transmission*/ 380 | if (URB_Status == USBH_URB_DONE) { 381 | if (MIDI_Handle->TxDataLength > MIDI_Handle->OutEpSize) { 382 | MIDI_Handle->TxDataLength -= MIDI_Handle->OutEpSize; 383 | MIDI_Handle->pTxData += MIDI_Handle->OutEpSize; 384 | } else { 385 | MIDI_Handle->TxDataLength = 0; 386 | } 387 | 388 | if (MIDI_Handle->TxDataLength > 0) { 389 | MIDI_Handle->data_tx_state = MIDI_SEND_DATA; 390 | } else { 391 | MIDI_Handle->data_tx_state = MIDI_IDLE; 392 | USBH_MIDI_TransmitCallback(phost); 393 | } 394 | #if (USBH_USE_OS == 1) 395 | osMessagePut(phost->os_event, USBH_CLASS_EVENT, 0); 396 | #endif 397 | } else if (URB_Status == USBH_URB_NOTREADY) { 398 | MIDI_Handle->data_tx_state = MIDI_SEND_DATA; 399 | #if (USBH_USE_OS == 1) 400 | osMessagePut(phost->os_event, USBH_CLASS_EVENT, 0); 401 | #endif 402 | } 403 | break; 404 | default: 405 | break; 406 | } 407 | } 408 | 409 | /*------------------------------------------------------------------------------------------------------------------------------*/ 410 | 411 | /** 412 | * @brief This function responsible for reception of data from the device 413 | * @param pdev: Selected device 414 | * @retval None 415 | */ 416 | 417 | static void MIDI_ProcessReception(USBH_HandleTypeDef *phost) { 418 | MIDI_HandleTypeDef *MIDI_Handle = phost->pActiveClass->pData; 419 | USBH_URBStateTypeDef URB_Status = USBH_URB_IDLE; 420 | uint16_t length; 421 | 422 | switch (MIDI_Handle->data_rx_state) { 423 | case MIDI_RECEIVE_DATA: 424 | 425 | USBH_BulkReceiveData(phost, MIDI_Handle->pRxData, MIDI_Handle->InEpSize, 426 | MIDI_Handle->InPipe); 427 | 428 | MIDI_Handle->data_rx_state = MIDI_RECEIVE_DATA_WAIT; 429 | //BSP_LED_On(LED_Red); //ok only here 430 | 431 | break; 432 | 433 | case MIDI_RECEIVE_DATA_WAIT: 434 | 435 | URB_Status = USBH_LL_GetURBState(phost, MIDI_Handle->InPipe); 436 | 437 | /*Check the status done for reception*/ 438 | if (URB_Status == USBH_URB_DONE) { 439 | length = USBH_LL_GetLastXferSize(phost, MIDI_Handle->InPipe); 440 | 441 | if (((MIDI_Handle->RxDataLength - length) > 0) && 442 | (length > MIDI_Handle->InEpSize)) { 443 | MIDI_Handle->RxDataLength -= length; 444 | MIDI_Handle->pRxData += length; 445 | MIDI_Handle->data_rx_state = MIDI_RECEIVE_DATA; 446 | } else { 447 | MIDI_Handle->data_rx_state = MIDI_IDLE; 448 | USBH_MIDI_ReceiveCallback(phost); 449 | } 450 | #if (USBH_USE_OS == 1) 451 | osMessagePut(phost->os_event, USBH_CLASS_EVENT, 0); 452 | #endif 453 | } 454 | break; 455 | 456 | default: 457 | break; 458 | } 459 | } 460 | 461 | /*------------------------------------------------------------------------------------------------------------------------------*/ 462 | 463 | /** 464 | * @brief The function informs user that data have been transmitted. 465 | * @param pdev: Selected device 466 | * @retval None 467 | */ 468 | __weak void USBH_MIDI_TransmitCallback(USBH_HandleTypeDef *phost) { 469 | } 470 | 471 | /*------------------------------------------------------------------------------------------------------------------------------*/ 472 | 473 | /** 474 | * @brief The function informs user that data have been received. 475 | * @retval None 476 | */ 477 | __weak void USBH_MIDI_ReceiveCallback(USBH_HandleTypeDef *phost) { 478 | } 479 | 480 | /**************************END OF FILE*********************************************************/ 481 | -------------------------------------------------------------------------------- /ext/usbh_midi/usbh_MIDI.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file usbh_MIDI.h 4 | * @author Xavier Halgand 5 | * @version 6 | * @date 7 | * @brief This file contains all the prototypes for the usbh_MIDI.c 8 | ****************************************************************************** 9 | */ 10 | /* 11 | * This program is free software; you can redistribute it and/or modify 12 | * it under the terms of the GNU General Public License as published by 13 | * the Free Software Foundation; either version 2 of the License, or 14 | * (at your option) any later version. 15 | * 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 | * You should have received a copy of the GNU General Public License 22 | * along with this program; if not, write to the Free Software 23 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 | * 25 | */ 26 | 27 | /* Define to prevent recursive ----------------------------------------------*/ 28 | #ifndef __USBH_MIDI_CORE_H 29 | #define __USBH_MIDI_CORE_H 30 | 31 | /* Includes ------------------------------------------------------------------*/ 32 | #include "stm32746g_discovery.h" 33 | #include "usbh_core.h" 34 | 35 | /*-------------------------------------------------------------------------------*/ 36 | // buffer size (should be at least >= MIOS32_USB_MIDI_DESC_DATA_*_SIZE/4) 37 | #define USB_MIDI_RX_BUFFER_SIZE 64 // packages 38 | #define USB_MIDI_TX_BUFFER_SIZE 64 // packages 39 | 40 | // size of IN/OUT pipe 41 | #define USB_MIDI_DATA_IN_SIZE 64 42 | #define USB_MIDI_DATA_OUT_SIZE 64 43 | 44 | // endpoint assignments (don't change!) 45 | #define USB_MIDI_DATA_OUT_EP 0x02 46 | #define USB_MIDI_DATA_IN_EP 0x81 47 | /** @defgroup USBH_MIDI_CORE_Exported_Defines 48 | * @{ 49 | */ 50 | #define USB_AUDIO_CLASS 0x01 51 | #define USB_MIDISTREAMING_SubCLASS 0x03 52 | #define USB_MIDI_DESC_SIZE 9 53 | #define USBH_MIDI_CLASS &MIDI_Class 54 | 55 | /*-------------------------------------------------------------------------------*/ 56 | 57 | extern USBH_ClassTypeDef MIDI_Class; 58 | 59 | /* -------------------- Exported_Types ------------------------------------------*/ 60 | 61 | typedef enum { 62 | NoteOff = 0x8, 63 | NoteOn = 0x9, 64 | PolyPressure = 0xa, 65 | CC = 0xb, 66 | ProgramChange = 0xc, 67 | Aftertouch = 0xd, 68 | PitchBend = 0xe 69 | } midi_event_t; 70 | 71 | typedef enum { 72 | Chn1, 73 | Chn2, 74 | Chn3, 75 | Chn4, 76 | Chn5, 77 | Chn6, 78 | Chn7, 79 | Chn8, 80 | Chn9, 81 | Chn10, 82 | Chn11, 83 | Chn12, 84 | Chn13, 85 | Chn14, 86 | Chn15, 87 | Chn16 88 | } midi_chn_t; 89 | 90 | typedef union { 91 | struct { 92 | uint32_t ALL; 93 | }; 94 | struct { 95 | uint8_t cin_cable; 96 | uint8_t evnt0; 97 | uint8_t evnt1; 98 | uint8_t evnt2; 99 | }; 100 | struct { 101 | uint8_t type : 4; 102 | uint8_t cable : 4; 103 | uint8_t chn : 4; // mios32_midi_chn_t 104 | uint8_t event : 4; // mios32_midi_event_t 105 | uint8_t value1; 106 | uint8_t value2; 107 | }; 108 | 109 | // C++ doesn't allow to redefine names in anonymous unions 110 | // as a simple workaround, we rename these redundant names 111 | struct { 112 | uint8_t cin : 4; 113 | uint8_t dummy1_cable : 4; 114 | uint8_t dummy1_chn : 4; // mios32_midi_chn_t 115 | uint8_t dummy1_event : 4; // mios32_midi_event_t 116 | uint8_t note : 8; 117 | uint8_t velocity : 8; 118 | }; 119 | struct { 120 | uint8_t dummy2_cin : 4; 121 | uint8_t dummy2_cable : 4; 122 | uint8_t dummy2_chn : 4; // mios32_midi_chn_t 123 | uint8_t dummy2_event : 4; // mios32_midi_event_t 124 | uint8_t cc_number : 8; 125 | uint8_t value : 8; 126 | }; 127 | struct { 128 | uint8_t dummy3_cin : 4; 129 | uint8_t dummy3_cable : 4; 130 | uint8_t dummy3_chn : 4; // mios32_midi_chn_t 131 | uint8_t dummy3_event : 4; // mios32_midi_event_t 132 | uint8_t program_change : 8; 133 | uint8_t dummy3 : 8; 134 | }; 135 | } midi_package_t; 136 | 137 | /* States for MIDI State Machine */ 138 | typedef enum { 139 | MIDI_IDLE = 0, 140 | MIDI_SEND_DATA, 141 | MIDI_SEND_DATA_WAIT, 142 | MIDI_RECEIVE_DATA, 143 | MIDI_RECEIVE_DATA_WAIT, 144 | } MIDI_DataStateTypeDef; 145 | 146 | typedef enum { 147 | MIDI_IDLE_STATE = 0, 148 | MIDI_TRANSFER_DATA, 149 | MIDI_ERROR_STATE, 150 | } MIDI_StateTypeDef; 151 | 152 | /* Structure for MIDI process */ 153 | typedef struct _MIDI_Process { 154 | MIDI_StateTypeDef state; 155 | uint8_t InPipe; 156 | uint8_t OutPipe; 157 | uint8_t OutEp; 158 | uint8_t InEp; 159 | uint16_t OutEpSize; 160 | uint16_t InEpSize; 161 | 162 | uint8_t *pTxData; 163 | uint8_t *pRxData; 164 | uint16_t TxDataLength; 165 | uint16_t RxDataLength; 166 | MIDI_DataStateTypeDef data_tx_state; 167 | MIDI_DataStateTypeDef data_rx_state; 168 | uint8_t Rx_Poll; 169 | //uint8_t buff[8]; 170 | //MIDI_DataItfTypedef DataItf; 171 | //CDC_InterfaceDesc_Typedef CDC_Desc; 172 | } MIDI_HandleTypeDef; 173 | 174 | /*---------------------------Exported_FunctionsPrototype-------------------------------------*/ 175 | 176 | USBH_StatusTypeDef USBH_MIDI_Transmit(USBH_HandleTypeDef *phost, 177 | uint8_t *pbuff, 178 | uint16_t length); 179 | 180 | USBH_StatusTypeDef USBH_MIDI_Receive(USBH_HandleTypeDef *phost, 181 | uint8_t *pbuff, 182 | uint16_t length); 183 | 184 | uint16_t USBH_MIDI_GetLastReceivedDataSize(USBH_HandleTypeDef *phost); 185 | 186 | USBH_StatusTypeDef USBH_MIDI_Stop(USBH_HandleTypeDef *phost); 187 | 188 | void USBH_MIDI_TransmitCallback(USBH_HandleTypeDef *phost); 189 | 190 | void USBH_MIDI_ReceiveCallback(USBH_HandleTypeDef *phost); 191 | 192 | /*-------------------------------------------------------------------------------------------*/ 193 | #endif /* __USBH_MIDI_CORE_H */ 194 | 195 | /*****************************END OF FILE*************************************************************/ 196 | -------------------------------------------------------------------------------- /make/devices/stm32f746.ld: -------------------------------------------------------------------------------- 1 | /* 2 | * Default linker script for Cortex-M (it includes specifics for STM32F[34]xx). 3 | * Based on GNU ARM Eclipse & STM32F7Cube templates 4 | */ 5 | 6 | /* Boot entry (defined in startup_stm32f746xx.s) */ 7 | ENTRY(Reset_Handler) 8 | 9 | /* Specify the memory areas */ 10 | MEMORY { 11 | FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K 12 | RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 320K 13 | /* 14 | * SRAM starts at 0xC0000000, but we reserve memory 15 | * for two LCD screen buffers (800 * 480 * 4 * 2) 16 | */ 17 | SRAM (xrw) : ORIGIN = 0xC02EE000, LENGTH = 5192K 18 | } 19 | 20 | /* Highest address of the user mode stack */ 21 | __stack = ORIGIN(RAM) + LENGTH(RAM); 22 | _estack = __stack; /* STM specific */ 23 | 24 | /* Define SRAM region limits */ 25 | _sram_start = ORIGIN(SRAM); 26 | _sram_end = ORIGIN(SRAM) + LENGTH(SRAM); 27 | 28 | /* Generate a link error if heap and stack don't fit into RAM */ 29 | _Min_Heap_Size = 0x200; /* required amount of heap */ 30 | _Min_Stack_Size = 0x400; /* required amount of stack */ 31 | 32 | /* Define output sections */ 33 | SECTIONS { 34 | /* 35 | * For Cortex-M devices, the beginning of the startup code is stored in 36 | * the .isr_vector section, which goes to FLASH. 37 | */ 38 | .isr_vector : ALIGN(4) { 39 | KEEP(*(.isr_vector)) /* ISR jump table */ 40 | . = ALIGN(4); 41 | } >FLASH 42 | 43 | /* Program code and other data goes into FLASH */ 44 | .text : ALIGN(4) { 45 | *(.text .text.*) 46 | /* 47 | * Stub sections generated by the linker, to glue together 48 | * ARM and Thumb code. .glue_7 is used for ARM code calling 49 | * Thumb code, and .glue_7t is used for Thumb code calling 50 | * ARM code. Apparently always generated by the linker, for some 51 | * architectures, so better leave them here. 52 | */ 53 | *(.glue_7 .glue_7t) 54 | *(.eh_frame) 55 | 56 | KEEP (*(.init)) 57 | KEEP (*(.fini)) 58 | 59 | . = ALIGN(4); 60 | _etext = .; /* define a global symbols at end of code */ 61 | } >FLASH 62 | 63 | /* Constant data (constants, strings, etc.) goes into FLASH */ 64 | .rodata : ALIGN(4) { 65 | *(.rodata .rodata*) 66 | . = ALIGN(4); 67 | } >FLASH 68 | 69 | .ARM.extab : ALIGN(4) { 70 | *(.ARM.extab* .gnu.linkonce.armextab.*) 71 | } >FLASH 72 | 73 | .ARM : ALIGN(4) { 74 | __exidx_start = .; 75 | *(.ARM.exidx* .gnu.linkonce.armexidx.*) 76 | __exidx_end = .; 77 | } >FLASH 78 | 79 | .preinit_array : { 80 | PROVIDE_HIDDEN (__preinit_array_start = .); 81 | KEEP (*(.preinit_array*)) 82 | PROVIDE_HIDDEN (__preinit_array_end = .); 83 | } >FLASH 84 | 85 | .init_array : { 86 | PROVIDE_HIDDEN (__init_array_start = .); 87 | KEEP (*(SORT(.init_array.*))) 88 | KEEP (*(.init_array*)) 89 | PROVIDE_HIDDEN (__init_array_end = .); 90 | } >FLASH 91 | 92 | .fini_array : { 93 | PROVIDE_HIDDEN (__fini_array_start = .); 94 | KEEP (*(SORT(.fini_array.*))) 95 | KEEP (*(.fini_array*)) 96 | PROVIDE_HIDDEN (__fini_array_end = .); 97 | } >FLASH 98 | 99 | /* used by the startup to initialize data */ 100 | _sidata = LOADADDR(.data); 101 | 102 | /* Initialized data sections goes into RAM, load LMA copy after code */ 103 | .data : ALIGN(4) { 104 | _sdata = .; /* create a global symbol at data start */ 105 | *(.data) /* .data sections */ 106 | *(.data*) /* .data* sections */ 107 | 108 | . = ALIGN(4); 109 | _edata = .; /* define a global symbol at data end */ 110 | } >RAM AT> FLASH 111 | 112 | 113 | /* Uninitialized data section */ 114 | .bss (NOLOAD) : ALIGN(4) { 115 | /* This is used by the startup in order to initialize the .bss secion */ 116 | _sbss = .; /* define a global symbol at bss start */ 117 | __bss_start__ = _sbss; 118 | *(.bss .bss*) 119 | *(COMMON) 120 | 121 | . = ALIGN(4); 122 | _ebss = .; /* define a global symbol at bss end */ 123 | __bss_end__ = _ebss; 124 | } >RAM 125 | 126 | /* User_heap_stack section, used to check that there is enough RAM left */ 127 | ._user_heap_stack : ALIGN(8) { 128 | PROVIDE ( end = . ); 129 | PROVIDE ( _end = . ); 130 | . = . + _Min_Heap_Size; 131 | . = . + _Min_Stack_Size; 132 | . = ALIGN(8); 133 | } >RAM 134 | 135 | /* Remove information from the standard libraries */ 136 | /DISCARD/ : 137 | { 138 | libc.a ( * ) 139 | libm.a ( * ) 140 | libgcc.a ( * ) 141 | } 142 | 143 | .ARM.attributes 0 : { *(.ARM.attributes) } 144 | } 145 | -------------------------------------------------------------------------------- /make/devices/stm32f746.make: -------------------------------------------------------------------------------- 1 | $(info configuring for STM32F746) 2 | 3 | DEVICE_DIR = $(CMSIS_DIR)/Device/ST/STM32F7xx 4 | HAL_DIR = $(STM_SRC_ROOT)/STM32F7xx_HAL_Driver 5 | BSP_DIR = $(STM_SRC_ROOT)/BSP/STM32746G-Discovery 6 | 7 | DEFINES += -DSTM32F746xx -DUSE_STM32746G_DISCO 8 | 9 | CFLAGS += -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-sp-d16 10 | LD_FLAGS += -Tstm32f746.ld 11 | 12 | ASM_SRC += $(DEVICE_DIR)/Source/Templates/gcc/startup_stm32f746xx.s 13 | 14 | # always include audio & touchscreen drivers 15 | LL_SRC = $(addprefix $(LL_DIR),/ft5336/ft5336.c /wm8994/wm8994.c) 16 | -------------------------------------------------------------------------------- /make/modules/ex01.make: -------------------------------------------------------------------------------- 1 | catalog = make/sources.txt 2 | 3 | CFLAGS += -Os 4 | -------------------------------------------------------------------------------- /make/modules/ex02.make: -------------------------------------------------------------------------------- 1 | catalog = make/sources.txt 2 | 3 | USER_SRC += $(wildcard ext/ct-gui/*.c) 4 | 5 | CFLAGS += -Os 6 | -------------------------------------------------------------------------------- /make/modules/ex03.make: -------------------------------------------------------------------------------- 1 | catalog = make/sources.txt 2 | 3 | CFLAGS += -Os 4 | -------------------------------------------------------------------------------- /make/modules/ex04.make: -------------------------------------------------------------------------------- 1 | catalog = make/sources.txt 2 | 3 | USER_SRC += $(wildcard ext/ct-gui/*.c) 4 | 5 | CFLAGS += -O3 -ffast-math 6 | -------------------------------------------------------------------------------- /make/modules/ex05.make: -------------------------------------------------------------------------------- 1 | catalog = make/sources.txt 2 | 3 | USE_USBH = 1 4 | USE_FATFS = 1 5 | 6 | USER_INCLUDES += -Isrc/ex05 -Iext/ct-synstack/src 7 | 8 | CFLAGS += -O3 -ffast-math 9 | -------------------------------------------------------------------------------- /make/modules/ex06.make: -------------------------------------------------------------------------------- 1 | catalog = make/sources.txt 2 | 3 | USER_INCLUDES += -Iext/ct-synstack/src 4 | USER_SRC += $(wildcard ext/ct-synstack/src/*.c) 5 | 6 | CFLAGS += -O3 -ffast-math 7 | -------------------------------------------------------------------------------- /make/modules/ex07.make: -------------------------------------------------------------------------------- 1 | catalog = make/sources.txt 2 | 3 | USER_INCLUDES += -Iext/ct-synstack/src -Isrc/synth_extras 4 | USER_SRC += $(wildcard ext/ct-synstack/src/*.c) 5 | USER_SRC += src/synth_extras/osc_noise.c src/synth_extras/sdram_delay.c 6 | 7 | CFLAGS += -O3 -ffast-math 8 | -------------------------------------------------------------------------------- /make/modules/ex08.make: -------------------------------------------------------------------------------- 1 | catalog = make/sources.txt 2 | 3 | USE_USBH = 1 4 | USBH_INCLUDES += -I$(EXT_SRC_DIR)/usbh_midi 5 | USBH_SRC += $(EXT_SRC_DIR)/usbh_midi/usbh_MIDI.c 6 | 7 | USER_INCLUDES += -Isrc/ex08 -Iext/ct-synstack/src -Isrc/synth_extras 8 | USER_SRC += $(wildcard ext/ct-synstack/src/*.c) $(wildcard src/synth_extras/*.c) 9 | 10 | #DEFINES += -DLOG_MIDI 11 | 12 | CFLAGS += -O3 -ffast-math 13 | -------------------------------------------------------------------------------- /make/sources.txt: -------------------------------------------------------------------------------- 1 | # In order to speed up the build process using the STM32CubeF7 SDK 2 | # only the uncommented files listed here will be included. The filter 3 | # is NOT applied to any user sources in /src 4 | # 5 | # IMPORTANT: 6 | # It's the user's responsibility to ensure the selected HAL files 7 | # are in sync with the config in /src/stm32f7xx_hal_conf.h 8 | # I.e. if you've enabled a HAL module in the config header file 9 | # then it also MUST be enabled here! 10 | 11 | # CMSIS 12 | %system_stm32f7xx.c 13 | 14 | # HAL 15 | %stm32f7xx_hal.c 16 | %stm32f7xx_hal_adc.c 17 | %stm32f7xx_hal_adc_ex.c 18 | # %stm32f7xx_hal_can.c 19 | # %stm32f7xx_hal_cec.c 20 | %stm32f7xx_hal_cortex.c 21 | # %stm32f7xx_hal_crc.c 22 | # %stm32f7xx_hal_crc_ex.c 23 | # %stm32f7xx_hal_cryp.c 24 | # %stm32f7xx_hal_cryp_ex.c 25 | %stm32f7xx_hal_dac.c 26 | %stm32f7xx_hal_dac_ex.c 27 | # %stm32f7xx_hal_dcmi.c 28 | # %stm32f7xx_hal_dcmi_ex.c 29 | # %stm32f7xx_hal_dfsdm.c 30 | %stm32f7xx_hal_dma.c 31 | %stm32f7xx_hal_dma2d.c 32 | %stm32f7xx_hal_dma_ex.c 33 | # %stm32f7xx_hal_dsi.c 34 | # %stm32f7xx_hal_eth.c 35 | %stm32f7xx_hal_flash.c 36 | %stm32f7xx_hal_flash_ex.c 37 | %stm32f7xx_hal_gpio.c 38 | # %stm32f7xx_hal_hash.c 39 | # %stm32f7xx_hal_hash_ex.c 40 | %stm32f7xx_hal_hcd.c 41 | %stm32f7xx_hal_i2c.c 42 | %stm32f7xx_hal_i2c_ex.c 43 | %stm32f7xx_hal_i2s.c 44 | # %stm32f7xx_hal_irda.c 45 | # %stm32f7xx_hal_iwdg.c 46 | # %stm32f7xx_hal_jpeg.c 47 | # %stm32f7xx_hal_lptim.c 48 | %stm32f7xx_hal_ltdc.c 49 | %stm32f7xx_hal_ltdc_ex.c 50 | # %stm32f7xx_hal_mdios.c 51 | # %stm32f7xx_hal_nand.c 52 | # %stm32f7xx_hal_nor.c 53 | # %stm32f7xx_hal_pcd.c 54 | # %stm32f7xx_hal_pcd_ex.c 55 | %stm32f7xx_hal_pwr.c 56 | %stm32f7xx_hal_pwr_ex.c 57 | # %stm32f7xx_hal_qspi.c 58 | %stm32f7xx_hal_rcc.c 59 | %stm32f7xx_hal_rcc_ex.c 60 | %stm32f7xx_hal_rng.c 61 | # %stm32f7xx_hal_rtc.c 62 | # %stm32f7xx_hal_rtc_ex.c 63 | %stm32f7xx_hal_sai.c 64 | %stm32f7xx_hal_sai_ex.c 65 | # %stm32f7xx_hal_sd.c 66 | %stm32f7xx_hal_sdram.c 67 | # %stm32f7xx_hal_smartcard.c 68 | # %stm32f7xx_hal_smartcard_ex.c 69 | # %stm32f7xx_hal_spdifrx.c 70 | # %stm32f7xx_hal_spi.c 71 | # %stm32f7xx_hal_sram.c 72 | %stm32f7xx_hal_tim.c 73 | %stm32f7xx_hal_tim_ex.c 74 | %stm32f7xx_hal_uart.c 75 | %stm32f7xx_hal_usart.c 76 | # %stm32f7xx_hal_wwdg.c 77 | %stm32f7xx_ll_fmc.c 78 | %stm32f7xx_ll_sdmmc.c 79 | %stm32f7xx_ll_usb.c 80 | 81 | # BSP 82 | %stm32746g_discovery.c 83 | %stm32746g_discovery_audio.c 84 | # %stm32746g_discovery_camera.c 85 | # %stm32746g_discovery_eeprom.c 86 | %stm32746g_discovery_lcd.c 87 | # %stm32746g_discovery_qspi.c 88 | # %stm32746g_discovery_sd.c 89 | %stm32746g_discovery_sdram.c 90 | %stm32746g_discovery_ts.c 91 | 92 | # USBH 93 | %usbh_core.c 94 | %usbh_ctlreq.c 95 | %usbh_ioreq.c 96 | %usbh_pipes.c 97 | 98 | # FatFS 99 | # %sd_diskio.c 100 | # %sdram_diskio.c 101 | # %sram_diskio.c 102 | %usbh_diskio.c 103 | # %cc932.c 104 | # %cc936.c 105 | # %cc949.c 106 | # %cc950.c 107 | %ccsbcs.c 108 | %syscall.c 109 | # %unicode.c 110 | -------------------------------------------------------------------------------- /src/common/clockconfig.c: -------------------------------------------------------------------------------- 1 | #include "clockconfig.h" 2 | 3 | /** 4 | * @brief System Clock Configuration 5 | * The system Clock is configured as follow : 6 | * System Clock source = PLL (HSE) 7 | * SYSCLK(Hz) = 216000000 8 | * HCLK(Hz) = 216000000 9 | * AHB Prescaler = 1 10 | * APB1 Prescaler = 4 11 | * APB2 Prescaler = 2 12 | * HSE Frequency(Hz) = 25000000 13 | * PLL_M = 25 14 | * PLL_N = 432 15 | * PLL_P = 2 16 | * PLL_Q = 9 17 | * VDD(V) = 3.3 18 | * Main regulator output voltage = Scale1 mode 19 | * Flash Latency(WS) = 7 20 | * @param None 21 | * @retval None 22 | */ 23 | void SystemClock_Config(void) { 24 | RCC_ClkInitTypeDef RCC_ClkInitStruct; 25 | RCC_OscInitTypeDef RCC_OscInitStruct; 26 | RCC_PeriphCLKInitTypeDef PeriphClkInitStruct; 27 | HAL_StatusTypeDef ret = HAL_OK; 28 | 29 | /* Enable HSE Oscillator and activate PLL with HSE as source */ 30 | RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; 31 | RCC_OscInitStruct.HSEState = RCC_HSE_ON; 32 | RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; 33 | RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; 34 | RCC_OscInitStruct.PLL.PLLM = 25; 35 | RCC_OscInitStruct.PLL.PLLN = 432; 36 | RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; 37 | RCC_OscInitStruct.PLL.PLLQ = 9; 38 | 39 | ret = HAL_RCC_OscConfig(&RCC_OscInitStruct); 40 | if (ret != HAL_OK) { 41 | Error_Handler(); 42 | } 43 | 44 | /* Activate the OverDrive to reach the 216 MHz Frequency */ 45 | ret = HAL_PWREx_EnableOverDrive(); 46 | if (ret != HAL_OK) { 47 | Error_Handler(); 48 | } 49 | 50 | /* Select PLLSAI output as USB clock source */ 51 | PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_CLK48; 52 | PeriphClkInitStruct.Clk48ClockSelection = RCC_CLK48SOURCE_PLLSAIP; 53 | PeriphClkInitStruct.PLLSAI.PLLSAIN = 192; 54 | PeriphClkInitStruct.PLLSAI.PLLSAIQ = 4; 55 | PeriphClkInitStruct.PLLSAI.PLLSAIP = RCC_PLLSAIP_DIV4; 56 | ret = HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); 57 | if (ret != HAL_OK) { 58 | Error_Handler(); 59 | } 60 | 61 | /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */ 62 | RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | 63 | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); 64 | RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; 65 | RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; 66 | RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; 67 | RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; 68 | 69 | ret = HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_7); 70 | if (ret != HAL_OK) { 71 | Error_Handler(); 72 | } 73 | } 74 | 75 | /** 76 | * @brief System Clock Configuration 77 | * The system Clock is configured as follow : 78 | * System Clock source = PLL (HSE) 79 | * SYSCLK(Hz) = 200000000 80 | * HCLK(Hz) = 200000000 81 | * AHB Prescaler = 1 82 | * APB1 Prescaler = 4 83 | * APB2 Prescaler = 2 84 | * HSE Frequency(Hz) = 25000000 85 | * PLL_M = 25 86 | * PLL_N = 400 87 | * PLL_P = 2 88 | * PLLSAI_N = 384 89 | * PLLSAI_P = 8 90 | * VDD(V) = 3.3 91 | * Main regulator output voltage = Scale1 mode 92 | * Flash Latency(WS) = 7 93 | * @param None 94 | * @retval None 95 | */ 96 | void SystemClock_Config_USB(void) { 97 | RCC_ClkInitTypeDef RCC_ClkInitStruct; 98 | RCC_OscInitTypeDef RCC_OscInitStruct; 99 | RCC_PeriphCLKInitTypeDef PeriphClkInitStruct; 100 | 101 | /* Enable HSE Oscillator and activate PLL with HSE as source */ 102 | RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; 103 | RCC_OscInitStruct.HSEState = RCC_HSE_ON; 104 | RCC_OscInitStruct.HSIState = RCC_HSI_OFF; 105 | RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; 106 | RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; 107 | RCC_OscInitStruct.PLL.PLLM = 25; 108 | RCC_OscInitStruct.PLL.PLLN = 400; 109 | RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; 110 | RCC_OscInitStruct.PLL.PLLQ = 8; 111 | if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { 112 | Error_Handler(); 113 | } 114 | 115 | /* Activate the OverDrive to reach the 200 Mhz Frequency */ 116 | if (HAL_PWREx_EnableOverDrive() != HAL_OK) { 117 | Error_Handler(); 118 | } 119 | 120 | /* Select PLLSAI output as USB clock source */ 121 | PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_CLK48; 122 | PeriphClkInitStruct.Clk48ClockSelection = RCC_CLK48SOURCE_PLLSAIP; 123 | PeriphClkInitStruct.PLLSAI.PLLSAIN = 192; 124 | PeriphClkInitStruct.PLLSAI.PLLSAIQ = 4; 125 | PeriphClkInitStruct.PLLSAI.PLLSAIP = RCC_PLLSAIP_DIV4; 126 | if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) { 127 | Error_Handler(); 128 | } 129 | 130 | /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 131 | clocks dividers */ 132 | RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | 133 | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); 134 | RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; 135 | RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; 136 | RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; 137 | RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; 138 | if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_6) != HAL_OK) { 139 | Error_Handler(); 140 | } 141 | } 142 | 143 | // Enable instruction & data caches 144 | void CPU_CACHE_Enable(void) { 145 | SCB_EnableICache(); 146 | SCB_EnableDCache(); 147 | } 148 | -------------------------------------------------------------------------------- /src/common/clockconfig.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "stm32f7xx_hal.h" 4 | 5 | void SystemClock_Config(void); 6 | void SystemClock_Config_USB(void); 7 | void CPU_CACHE_Enable(void); 8 | 9 | extern void Error_Handler(); 10 | -------------------------------------------------------------------------------- /src/common/handlers.c: -------------------------------------------------------------------------------- 1 | #include "stm32746g_discovery.h" 2 | #include "stm32f7xx_hal.h" 3 | 4 | void Error_Handler(void) { 5 | BSP_LED_On(LED_GREEN); 6 | while (1) { 7 | } 8 | } 9 | 10 | void SysTick_Handler(void) { 11 | HAL_IncTick(); 12 | } 13 | -------------------------------------------------------------------------------- /src/common/sdram_alloc.c: -------------------------------------------------------------------------------- 1 | #include "sdram_alloc.h" 2 | #include "ct-head/math.h" 3 | 4 | // start of heap = SDRAM base address PLUS length of screen buffer 5 | static uint32_t sdram_heap_ptr = SDRAM_DEVICE_ADDR + 480 * 276 * 4; 6 | static uint32_t sdram_heap_end = SDRAM_DEVICE_ADDR + SDRAM_DEVICE_SIZE; 7 | static uint32_t sdram_zero[32] = {0}; 8 | 9 | void* ct_sdram_malloc(size_t size) { 10 | void* ptr = NULL; 11 | if (sdram_heap_ptr + size < sdram_heap_end) { 12 | ptr = (void*)sdram_heap_ptr; 13 | sdram_heap_ptr += ct_ceil_multiple_pow2(size, 4); 14 | } 15 | return ptr; 16 | } 17 | 18 | void* ct_sdram_calloc(size_t num, size_t size) { 19 | size *= num; 20 | void* ptr = ct_sdram_malloc(size); 21 | if (ptr) { 22 | uint32_t addr = (uint32_t)ptr; 23 | while (size > 32) { 24 | BSP_SDRAM_WriteData(addr, sdram_zero, 32); 25 | addr += 32; 26 | size -= 32; 27 | } 28 | if (size > 0) { 29 | BSP_SDRAM_WriteData(addr, sdram_zero, size); 30 | } 31 | } 32 | return ptr; 33 | } 34 | -------------------------------------------------------------------------------- /src/common/sdram_alloc.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "stm32746g_discovery_sdram.h" 4 | 5 | void* ct_sdram_malloc(size_t size); 6 | 7 | void* ct_sdram_calloc(size_t num, size_t size); 8 | -------------------------------------------------------------------------------- /src/ex01/main.c: -------------------------------------------------------------------------------- 1 | #include "stm32746g_discovery.h" 2 | 3 | #include "common/clockconfig.h" 4 | 5 | #define LED_SPEED 100 6 | 7 | volatile int do_blink = 1; 8 | 9 | int main() { 10 | HAL_Init(); 11 | SystemClock_Config(); 12 | BSP_LED_Init(LED_GREEN); 13 | // configure user button in ISR mode 14 | BSP_PB_Init(BUTTON_KEY, BUTTON_MODE_EXTI); 15 | 16 | while (1) { 17 | if (do_blink) { 18 | BSP_LED_On(LED_GREEN); 19 | HAL_Delay(LED_SPEED); 20 | BSP_LED_Off(LED_GREEN); 21 | HAL_Delay(LED_SPEED); 22 | } 23 | } 24 | return 0; 25 | } 26 | 27 | void EXTI15_10_IRQHandler(void) { 28 | HAL_GPIO_EXTI_IRQHandler(KEY_BUTTON_PIN); 29 | } 30 | 31 | void HAL_GPIO_EXTI_Callback(uint16_t pin) { 32 | if (pin == KEY_BUTTON_PIN) { 33 | while (BSP_PB_GetState(BUTTON_KEY) != RESET) 34 | ; 35 | do_blink = !do_blink; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/ex02/main.c: -------------------------------------------------------------------------------- 1 | #include "stm32f7xx_hal.h" 2 | 3 | #include "ct-gui/gui_stm32.h" 4 | #include "ct-head/random.h" 5 | 6 | #include "common/clockconfig.h" 7 | 8 | extern const CTGUI_SpriteSheet ctgui_spritesheet_moogknob50; 9 | 10 | // touch event state 11 | static TS_StateTypeDef rawTouchState; 12 | 13 | static void demoWelcome(); 14 | static void demoScribble(); 15 | static void demoGUI(); 16 | 17 | int main() { 18 | CPU_CACHE_Enable(); 19 | HAL_Init(); 20 | SystemClock_Config(); 21 | BSP_LCD_Init(); 22 | 23 | // only continue if touch screen init ok 24 | if (BSP_TS_Init(BSP_LCD_GetXSize(), BSP_LCD_GetYSize()) == TS_OK) { 25 | BSP_LCD_LayerDefaultInit(LTDC_ACTIVE_LAYER, SDRAM_DEVICE_ADDR); 26 | BSP_LCD_SelectLayer(LTDC_ACTIVE_LAYER); 27 | 28 | // Only enable ONE of the following: 29 | //demoWelcome(); 30 | //demoScribble(); 31 | demoGUI(); 32 | } 33 | return 0; 34 | } 35 | 36 | static void demoWelcome() { 37 | BSP_LCD_SetFont(&CTGUI_FONT); 38 | BSP_LCD_SetBackColor(LCD_COLOR_WHITE); 39 | BSP_LCD_Clear(LCD_COLOR_WHITE); 40 | BSP_LCD_SetTextColor(LCD_COLOR_BLUE); 41 | BSP_LCD_DisplayStringAt(0, BSP_LCD_GetYSize() / 2 - 8, 42 | (uint8_t *)"STM32F746G", CENTER_MODE); 43 | BSP_LCD_SetTextColor(LCD_COLOR_DARKBLUE); 44 | BSP_LCD_DisplayStringAt(0, BSP_LCD_GetYSize() / 2 + 8, (uint8_t *)"Welcome!", 45 | CENTER_MODE); 46 | const float w = BSP_LCD_GetXSize() - 5; 47 | const float h = BSP_LCD_GetYSize() - 5; 48 | 49 | CT_Smush rnd; 50 | // seed random number generator 51 | ct_smush_init(&rnd, 0xdecafbad); 52 | 53 | while (1) { 54 | BSP_LCD_SetTextColor((ct_smush(&rnd) & 0xffffff) | 0xff000000); 55 | BSP_LCD_FillCircle(ct_smush_minmax(&rnd, 5.f, w), 56 | ct_smush_minmax(&rnd, 5.f, h), 4); 57 | HAL_Delay(1); 58 | } 59 | } 60 | 61 | static void demoScribble() { 62 | static uint32_t cols[] = {LCD_COLOR_RED, LCD_COLOR_GREEN, LCD_COLOR_BLUE, 63 | LCD_COLOR_YELLOW, LCD_COLOR_MAGENTA}; 64 | uint16_t width = BSP_LCD_GetXSize(); 65 | uint16_t height = BSP_LCD_GetYSize(); 66 | BSP_LCD_Clear(LCD_COLOR_WHITE); 67 | while (1) { 68 | BSP_TS_GetState(&rawTouchState); 69 | if (rawTouchState.touchDetected) { 70 | for (int i = 0; i < CT_MIN(rawTouchState.touchDetected, 5); i++) { 71 | BSP_LCD_SetTextColor(cols[i]); 72 | BSP_LCD_FillCircle(CT_CLAMP(rawTouchState.touchX[i], 6, width - 6), 73 | CT_CLAMP(rawTouchState.touchY[i], 6, height - 6), 5); 74 | } 75 | } 76 | HAL_Delay(10); 77 | } 78 | } 79 | 80 | static void demoGUI() { 81 | CTGUI gui; 82 | CTGUI_TouchState touchState; 83 | ctgui_init(&gui, 3, &CTGUI_FONT, CTGUI_BG_COLOR, CTGUI_TEXT_COLOR); 84 | ctgui_dialbutton(&gui, 0, "Volume", 135, 100, 0.0f, 0.025f, 85 | &ctgui_spritesheet_moogknob50, NULL); 86 | ctgui_dialbutton(&gui, 1, "Freq", 205, 100, 0.0f, 0.025f, 87 | &ctgui_spritesheet_moogknob50, NULL); 88 | ctgui_dialbutton(&gui, 2, "Filter", 275, 100, 0.0f, 0.025f, 89 | &ctgui_spritesheet_moogknob50, NULL); 90 | 91 | BSP_LCD_Clear(gui.col_bg); 92 | ctgui_force_redraw(&gui); 93 | 94 | while (1) { 95 | BSP_TS_GetState(&rawTouchState); 96 | ctgui_update_touch(&rawTouchState, &touchState); 97 | ctgui_update(&gui, &touchState); 98 | ctgui_draw(&gui); 99 | HAL_Delay(10); 100 | } 101 | } 102 | 103 | // Interrupt handler shared between: 104 | // SD_DETECT pin, USER_KEY button and touch screen interrupt 105 | void EXTI15_10_IRQHandler(void) { 106 | if (__HAL_GPIO_EXTI_GET_IT(SD_DETECT_PIN) != RESET) { 107 | HAL_GPIO_EXTI_IRQHandler(SD_DETECT_PIN | TS_INT_PIN); 108 | } else { 109 | // User button event or Touch screen interrupt 110 | HAL_GPIO_EXTI_IRQHandler(KEY_BUTTON_PIN); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/ex03/main.c: -------------------------------------------------------------------------------- 1 | #include "stm32746g_discovery.h" 2 | #include "stm32f7xx_hal.h" 3 | 4 | #include "common/clockconfig.h" 5 | 6 | #define TIMx TIM3 7 | #define TIMx_CLK_ENABLE() __HAL_RCC_TIM3_CLK_ENABLE() 8 | #define TIMx_IRQn TIM3_IRQn 9 | #define TIMx_IRQHandler TIM3_IRQHandler 10 | 11 | TIM_HandleTypeDef timer; 12 | static uint8_t isBlinking = 1; 13 | 14 | static void initTimer(uint16_t period); 15 | 16 | int main(void) { 17 | CPU_CACHE_Enable(); 18 | HAL_Init(); 19 | SystemClock_Config(); 20 | BSP_LED_Init(LED_GREEN); 21 | BSP_PB_Init(BUTTON_KEY, BUTTON_MODE_EXTI); 22 | 23 | // Start timer w/ 500ms interval (time base = 10kHz) 24 | initTimer(5000); 25 | 26 | while (1) 27 | ; 28 | 29 | return 0; 30 | } 31 | 32 | // Initialize timer w/ 10kHz resolution and given period 33 | static void initTimer(uint16_t period) { 34 | uint32_t prescaler = (uint32_t)((SystemCoreClock / 2) / 10000) - 1; 35 | timer.Instance = TIMx; 36 | timer.Init.Period = period - 1; 37 | timer.Init.Prescaler = prescaler; 38 | timer.Init.ClockDivision = 0; 39 | timer.Init.CounterMode = TIM_COUNTERMODE_UP; 40 | timer.Init.RepetitionCounter = 0; 41 | 42 | if (HAL_TIM_Base_Init(&timer) != HAL_OK) { 43 | Error_Handler(); 44 | } 45 | if (HAL_TIM_Base_Start_IT(&timer) != HAL_OK) { 46 | Error_Handler(); 47 | } 48 | } 49 | 50 | void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim) { 51 | // TIMx Peripheral clock enable 52 | TIMx_CLK_ENABLE(); 53 | // Set the TIMx priority 54 | HAL_NVIC_SetPriority(TIMx_IRQn, 3, 0); 55 | // Enable the TIMx global Interrupt 56 | HAL_NVIC_EnableIRQ(TIMx_IRQn); 57 | } 58 | 59 | // Timer interrupt request. 60 | void TIMx_IRQHandler(void) { 61 | HAL_TIM_IRQHandler(&timer); 62 | } 63 | 64 | // Callback function run whenever timer caused interrupt 65 | void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { 66 | if (isBlinking) { 67 | BSP_LED_Toggle(LED_GREEN); 68 | } 69 | } 70 | 71 | // External line 0 interrupt request. 72 | void EXTI15_10_IRQHandler(void) { 73 | HAL_GPIO_EXTI_IRQHandler(KEY_BUTTON_PIN); 74 | } 75 | 76 | // Callback function run whenever user button has been pressed 77 | void HAL_GPIO_EXTI_Callback(uint16_t pin) { 78 | if (pin == KEY_BUTTON_PIN) { 79 | isBlinking = !isBlinking; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/ex04/main.c: -------------------------------------------------------------------------------- 1 | #include "stm32746g_discovery_audio.h" 2 | 3 | #include "ct-head/math.h" 4 | #include "ct-head/random.h" 5 | 6 | #include "common/clockconfig.h" 7 | 8 | #define VOLUME 50 9 | #define SAMPLE_RATE 44100 10 | 11 | // in bytes... 12 | #define AUDIO_DMA_BUFFER_SIZE 512 13 | // 16bit words 14 | #define AUDIO_DMA_BUFFER_SIZE2 (AUDIO_DMA_BUFFER_SIZE >> 1) 15 | // half buffer size (in 16bit words) 16 | #define AUDIO_DMA_BUFFER_SIZE4 (AUDIO_DMA_BUFFER_SIZE >> 2) 17 | // number of stereo samples (16bit words) 18 | #define AUDIO_DMA_BUFFER_SIZE8 (AUDIO_DMA_BUFFER_SIZE >> 3) 19 | 20 | #define TAU_RATE (CT_TAU / (float)SAMPLE_RATE) 21 | #define HZ_TO_RAD(freq) ((freq)*TAU_RATE) 22 | 23 | typedef struct { 24 | float phase; 25 | float freq; 26 | float mod_phase; 27 | float mod_freq; 28 | float mod_amp; 29 | uint8_t type; 30 | uint8_t mod_type; 31 | } Oscillator; 32 | 33 | extern SAI_HandleTypeDef haudio_out_sai; 34 | static uint8_t audioBuf[AUDIO_DMA_BUFFER_SIZE]; 35 | static CT_XorShift rnd; 36 | 37 | // clang-format off 38 | static Oscillator osc = { 39 | .phase = 0.0f, 40 | .freq = HZ_TO_RAD(220.0f), 41 | .type = 0, 42 | .mod_phase = 0.0f, 43 | .mod_freq = HZ_TO_RAD(0.5f), 44 | .mod_amp = HZ_TO_RAD(110.0f), 45 | .mod_type = 2 46 | }; 47 | // clang-format on 48 | 49 | int main() { 50 | CPU_CACHE_Enable(); 51 | HAL_Init(); 52 | SystemClock_Config(); 53 | ct_xors_init(&rnd); 54 | 55 | if (BSP_AUDIO_OUT_Init(OUTPUT_DEVICE_HEADPHONE, VOLUME, SAMPLE_RATE) != 0) { 56 | Error_Handler(); 57 | } 58 | BSP_AUDIO_OUT_SetAudioFrameSlot(CODEC_AUDIOFRAME_SLOT_02); 59 | BSP_AUDIO_OUT_SetVolume(VOLUME); 60 | BSP_AUDIO_OUT_Play((uint16_t *)audioBuf, AUDIO_DMA_BUFFER_SIZE); 61 | 62 | while (1) { 63 | } 64 | 65 | return 0; 66 | } 67 | 68 | static float compute_osc(size_t type, float phase) { 69 | switch (type) { 70 | case 0: 71 | return sinf(phase); 72 | case 1: // saw 73 | return ct_mapf(phase, 0.0f, CT_TAU, 1.f, -1.f); 74 | case 2: // square 75 | return phase < CT_PI ? -1.0f : 1.0f; 76 | case 3: // triangle 77 | if (phase < CT_PI) { 78 | return ct_mapf(phase, 0.0f, CT_PI, -1.f, 1.f); 79 | } else { 80 | return ct_mapf(phase, CT_PI, CT_TAU, 1.f, -1.f); 81 | } 82 | case 4: // saw + sin 83 | if (phase < CT_PI) { 84 | return ct_mapf(phase, 0.0f, CT_PI, -1.f, 1.f); 85 | } else { 86 | return sinf(phase); 87 | } 88 | case 5: 89 | return ct_xors_normpos(&rnd); 90 | } 91 | return 0; 92 | } 93 | 94 | static void renderAudio(int16_t *ptr) { 95 | size_t len = AUDIO_DMA_BUFFER_SIZE8; 96 | int16_t y; 97 | float f; 98 | while (len--) { 99 | osc.mod_phase += osc.mod_freq; 100 | if (osc.mod_phase >= CT_TAU) { 101 | osc.mod_phase -= CT_TAU; 102 | } 103 | f = osc.freq + osc.mod_amp * compute_osc(osc.mod_type, osc.mod_phase); 104 | osc.phase = ct_wrapf(osc.phase + f, CT_TAU); 105 | y = ct_clamp16(compute_osc(osc.type, osc.phase) * 32767.f); 106 | *ptr++ = y; 107 | *ptr++ = y; 108 | } 109 | } 110 | 111 | void AUDIO_OUT_SAIx_DMAx_IRQHandler(void) { 112 | HAL_DMA_IRQHandler(haudio_out_sai.hdmatx); 113 | } 114 | 115 | void BSP_AUDIO_OUT_HalfTransfer_CallBack(void) { 116 | renderAudio((int16_t *)&audioBuf[0]); 117 | } 118 | 119 | void BSP_AUDIO_OUT_TransferComplete_CallBack(void) { 120 | renderAudio((int16_t *)&audioBuf[0] + AUDIO_DMA_BUFFER_SIZE4); 121 | } 122 | 123 | void BSP_AUDIO_OUT_Error_CallBack(void) { 124 | Error_Handler(); 125 | } 126 | -------------------------------------------------------------------------------- /src/ex05/ffconf.h: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------------/ 2 | / FatFs - FAT file system module configuration file R0.11 (C)ChaN, 2015 3 | /---------------------------------------------------------------------------*/ 4 | 5 | #ifndef _FFCONF 6 | #define _FFCONF 32020 /* Revision ID */ 7 | 8 | /*-----------------------------------------------------------------------------/ 9 | / Additional user header to be used 10 | /-----------------------------------------------------------------------------*/ 11 | #include "stm32f7xx_hal.h" 12 | 13 | /* If uSD is used, then include the uSD BSP header file. 14 | Replace 'stm32xxx' with your EVAL board name, ex: stm324x9i_eval_sd.h 15 | */ 16 | // #include "stm32xxx_eval_sd.h" 17 | 18 | /* If USB Host MSC is used, then need to include the USBH and UBSH MSC core header files */ 19 | #include "usbh_core.h" 20 | #include "usbh_msc.h" 21 | /* hUSBH to be updated with the USBH handle defined in the application code */ 22 | #define HOST_HANDLE hUSBH 23 | 24 | /*---------------------------------------------------------------------------/ 25 | / Functions and Buffer Configurations 26 | /---------------------------------------------------------------------------*/ 27 | 28 | #define _FS_TINY 0 /* 0:Normal or 1:Tiny */ 29 | /* This option switches tiny buffer configuration. (0:Normal or 1:Tiny) 30 | / At the tiny configuration, size of the file object (FIL) is reduced _MAX_SS 31 | / bytes. Instead of private sector buffer eliminated from the file object, 32 | / common sector buffer in the file system object (FATFS) is used for the file 33 | / data transfer. */ 34 | 35 | #define _FS_READONLY 0 /* 0:Read/Write or 1:Read only */ 36 | /* This option switches read-only configuration. (0:Read/Write or 1:Read-only) 37 | / Read-only configuration removes writing API functions, f_write(), f_sync(), 38 | / f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree() 39 | / and optional writing functions as well. */ 40 | 41 | #define _FS_MINIMIZE 0 /* 0 to 3 */ 42 | /* This option defines minimization level to remove some basic API functions. 43 | / 44 | / 0: All basic functions are enabled. 45 | / 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_chmod(), f_utime(), 46 | / f_truncate() and f_rename() function are removed. 47 | / 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1. 48 | / 3: f_lseek() function is removed in addition to 2. */ 49 | 50 | #define _USE_STRFUNC 2 /* 0:Disable or 1-2:Enable */ 51 | /* This option switches string functions, f_gets(), f_putc(), f_puts() and 52 | / f_printf(). 53 | / 54 | / 0: Disable string functions. 55 | / 1: Enable without LF-CRLF conversion. 56 | / 2: Enable with LF-CRLF conversion. */ 57 | 58 | #define _USE_FIND 0 59 | /* This option switches filtered directory read feature and related functions, 60 | / f_findfirst() and f_findnext(). (0:Disable or 1:Enable) */ 61 | 62 | #define _USE_MKFS 1 63 | /* This option switches f_mkfs() function. (0:Disable or 1:Enable) */ 64 | 65 | #define _USE_FASTSEEK 1 66 | /* This option switches fast seek feature. (0:Disable or 1:Enable) */ 67 | 68 | #define _USE_LABEL 0 69 | /* This option switches volume label functions, f_getlabel() and f_setlabel(). 70 | / (0:Disable or 1:Enable) */ 71 | 72 | #define _USE_FORWARD 0 73 | /* This option switches f_forward() function. (0:Disable or 1:Enable) 74 | / To enable it, also _FS_TINY need to be set to 1. */ 75 | 76 | #define _USE_BUFF_WO_ALIGNMENT 0 77 | /* This option is available only for usbh diskio interface and allow to disable 78 | / the management of the unaligned buffer. 79 | / When STM32 USB OTG HS or FS IP is used with internal DMA enabled, this define 80 | / must be set to 0 to align data into 32bits through an internal scratch buffer 81 | / before being processed by the DMA . Otherwise (DMA not used), this define must 82 | / be set to 1 to avoid Data alignment and improve the performance. 83 | / Please note that if _USE_BUFF_WO_ALIGNMENT is set to 1 and an unaligned 32bits 84 | / buffer is forwarded to the FatFs Write/Read functions, an error will be returned. 85 | / (0: default value or 1: unaligned buffer return an error). */ 86 | 87 | /*---------------------------------------------------------------------------/ 88 | / Locale and Namespace Configurations 89 | /---------------------------------------------------------------------------*/ 90 | 91 | #define _CODE_PAGE 1252 92 | /* This option specifies the OEM code page to be used on the target system. 93 | / Incorrect setting of the code page can cause a file open failure. 94 | / 95 | / 932 - Japanese Shift_JIS (DBCS, OEM, Windows) 96 | / 936 - Simplified Chinese GBK (DBCS, OEM, Windows) 97 | / 949 - Korean (DBCS, OEM, Windows) 98 | / 950 - Traditional Chinese Big5 (DBCS, OEM, Windows) 99 | / 1250 - Central Europe (Windows) 100 | / 1251 - Cyrillic (Windows) 101 | / 1252 - Latin 1 (Windows) 102 | / 1253 - Greek (Windows) 103 | / 1254 - Turkish (Windows) 104 | / 1255 - Hebrew (Windows) 105 | / 1256 - Arabic (Windows) 106 | / 1257 - Baltic (Windows) 107 | / 1258 - Vietnam (OEM, Windows) 108 | / 437 - U.S. (OEM) 109 | / 720 - Arabic (OEM) 110 | / 737 - Greek (OEM) 111 | / 775 - Baltic (OEM) 112 | / 850 - Multilingual Latin 1 (OEM) 113 | / 858 - Multilingual Latin 1 + Euro (OEM) 114 | / 852 - Latin 2 (OEM) 115 | / 855 - Cyrillic (OEM) 116 | / 866 - Russian (OEM) 117 | / 857 - Turkish (OEM) 118 | / 862 - Hebrew (OEM) 119 | / 874 - Thai (OEM, Windows) 120 | / 1 - ASCII (No extended character. Valid for only non-LFN configuration.) */ 121 | 122 | #define _USE_LFN 3 123 | #define _MAX_LFN 255 /* Maximum LFN length to handle (12 to 255) */ 124 | /* The _USE_LFN option switches the LFN feature. 125 | / 126 | / 0: Disable LFN feature. _MAX_LFN has no effect. 127 | / 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe. 128 | / 2: Enable LFN with dynamic working buffer on the STACK. 129 | / 3: Enable LFN with dynamic working buffer on the HEAP. 130 | / 131 | / When enable the LFN feature, Unicode handling functions (option/unicode.c) must 132 | / be added to the project. The LFN working buffer occupies (_MAX_LFN + 1) * 2 bytes. 133 | / When use stack for the working buffer, take care on stack overflow. When use heap 134 | / memory for the working buffer, memory management functions, ff_memalloc() and 135 | / ff_memfree(), must be added to the project. */ 136 | 137 | #define _LFN_UNICODE 0 /* 0:ANSI/OEM or 1:Unicode */ 138 | /* This option switches character encoding on the API. (0:ANSI/OEM or 1:Unicode) 139 | / To use Unicode string for the path name, enable LFN feature and set _LFN_UNICODE 140 | / to 1. This option also affects behavior of string I/O functions. */ 141 | 142 | #define _STRF_ENCODE 3 143 | /* When _LFN_UNICODE is 1, this option selects the character encoding on the file to 144 | / be read/written via string I/O functions, f_gets(), f_putc(), f_puts and f_printf(). 145 | / 146 | / 0: ANSI/OEM 147 | / 1: UTF-16LE 148 | / 2: UTF-16BE 149 | / 3: UTF-8 150 | / 151 | / When _LFN_UNICODE is 0, this option has no effect. */ 152 | 153 | #define _FS_RPATH 0 154 | /* This option configures relative path feature. 155 | / 156 | / 0: Disable relative path feature and remove related functions. 157 | / 1: Enable relative path feature. f_chdir() and f_chdrive() are available. 158 | / 2: f_getcwd() function is available in addition to 1. 159 | / 160 | / Note that directory items read via f_readdir() are affected by this option. */ 161 | 162 | /*---------------------------------------------------------------------------/ 163 | / Drive/Volume Configurations 164 | /---------------------------------------------------------------------------*/ 165 | 166 | #define _VOLUMES 1 167 | /* Number of volumes (logical drives) to be used. */ 168 | 169 | #define _STR_VOLUME_ID 0 170 | #define _VOLUME_STRS "RAM", "NAND", "CF", "SD1", "SD2", "USB1", "USB2", "USB3" 171 | /* _STR_VOLUME_ID option switches string volume ID feature. 172 | / When _STR_VOLUME_ID is set to 1, also pre-defined strings can be used as drive 173 | / number in the path name. _VOLUME_STRS defines the drive ID strings for each 174 | / logical drives. Number of items must be equal to _VOLUMES. Valid characters for 175 | / the drive ID strings are: A-Z and 0-9. */ 176 | 177 | #define _MULTI_PARTITION 0 178 | /* This option switches multi-partition feature. By default (0), each logical drive 179 | / number is bound to the same physical drive number and only an FAT volume found on 180 | / the physical drive will be mounted. When multi-partition feature is enabled (1), 181 | / each logical drive number is bound to arbitrary physical drive and partition 182 | / listed in the VolToPart[]. Also f_fdisk() funciton will be available. */ 183 | 184 | #define _MIN_SS 512 185 | #define _MAX_SS 512 186 | /* These options configure the range of sector size to be supported. (512, 1024, 187 | / 2048 or 4096) Always set both 512 for most systems, all type of memory cards and 188 | / harddisk. But a larger value may be required for on-board flash memory and some 189 | / type of optical media. When _MAX_SS is larger than _MIN_SS, FatFs is configured 190 | / to variable sector size and GET_SECTOR_SIZE command must be implemented to the 191 | / disk_ioctl() function. */ 192 | 193 | #define _USE_TRIM 0 194 | /* This option switches ATA-TRIM feature. (0:Disable or 1:Enable) 195 | / To enable Trim feature, also CTRL_TRIM command should be implemented to the 196 | / disk_ioctl() function. */ 197 | 198 | #define _FS_NOFSINFO 0 199 | /* If you need to know correct free space on the FAT32 volume, set bit 0 of this 200 | / option, and f_getfree() function at first time after volume mount will force 201 | / a full FAT scan. Bit 1 controls the use of last allocated cluster number. 202 | / 203 | / bit0=0: Use free cluster count in the FSINFO if available. 204 | / bit0=1: Do not trust free cluster count in the FSINFO. 205 | / bit1=0: Use last allocated cluster number in the FSINFO if available. 206 | / bit1=1: Do not trust last allocated cluster number in the FSINFO. 207 | */ 208 | 209 | /*---------------------------------------------------------------------------/ 210 | / System Configurations 211 | /---------------------------------------------------------------------------*/ 212 | 213 | #define _FS_NORTC 1 214 | #define _NORTC_MON 1 215 | #define _NORTC_MDAY 1 216 | #define _NORTC_YEAR 2016 217 | /* The _FS_NORTC option switches timestamp feature. If the system does not have 218 | / an RTC function or valid timestamp is not needed, set _FS_NORTC to 1 to disable 219 | / the timestamp feature. All objects modified by FatFs will have a fixed timestamp 220 | / defined by _NORTC_MON, _NORTC_MDAY and _NORTC_YEAR. 221 | / When timestamp feature is enabled (_FS_NORTC == 0), get_fattime() function need 222 | / to be added to the project to read current time form RTC. _NORTC_MON, 223 | / _NORTC_MDAY and _NORTC_YEAR have no effect. 224 | / These options have no effect at read-only configuration (_FS_READONLY == 1). */ 225 | 226 | #define _FS_LOCK 2 227 | /* The _FS_LOCK option switches file lock feature to control duplicated file open 228 | / and illegal operation to open objects. This option must be 0 when _FS_READONLY 229 | / is 1. 230 | / 231 | / 0: Disable file lock feature. To avoid volume corruption, application program 232 | / should avoid illegal open, remove and rename to the open objects. 233 | / >0: Enable file lock feature. The value defines how many files/sub-directories 234 | / can be opened simultaneously under file lock control. Note that the file 235 | / lock feature is independent of re-entrancy. */ 236 | 237 | #define _FS_REENTRANT 0 238 | #define _FS_TIMEOUT 1000 239 | #define _SYNC_t osSemaphoreId 240 | /* The _FS_REENTRANT option switches the re-entrancy (thread safe) of the FatFs 241 | / module itself. Note that regardless of this option, file access to different 242 | / volume is always re-entrant and volume control functions, f_mount(), f_mkfs() 243 | / and f_fdisk() function, are always not re-entrant. Only file/directory access 244 | / to the same volume is under control of this feature. 245 | / 246 | / 0: Disable re-entrancy. _FS_TIMEOUT and _SYNC_t have no effect. 247 | / 1: Enable re-entrancy. Also user provided synchronization handlers, 248 | / ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj() 249 | / function, must be added to the project. Samples are available in 250 | / option/syscall.c. 251 | / 252 | / The _FS_TIMEOUT defines timeout period in unit of time tick. 253 | / The _SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*, 254 | / SemaphoreHandle_t and etc.. */ 255 | 256 | #define _WORD_ACCESS 0 257 | /* The _WORD_ACCESS option is an only platform dependent option. It defines 258 | / which access method is used to the word data on the FAT volume. 259 | / 260 | / 0: Byte-by-byte access. Always compatible with all platforms. 261 | / 1: Word access. Do not choose this unless under both the following conditions. 262 | / 263 | / * Address misaligned memory access is always allowed to ALL instructions. 264 | / * Byte order on the memory is little-endian. 265 | / 266 | / If it is the case, _WORD_ACCESS can also be set to 1 to reduce code size. 267 | / Following table shows allowable settings of some processor types. 268 | / 269 | / ARM7TDMI 0 ColdFire 0 V850E 0 270 | / Cortex-M3 0 Z80 0/1 V850ES 0/1 271 | / Cortex-M0 0 x86 0/1 TLCS-870 0/1 272 | / AVR 0/1 RX600(LE) 0/1 TLCS-900 0/1 273 | / AVR32 0 RL78 0 R32C 0 274 | / PIC18 0/1 SH-2 0 M16C 0/1 275 | / PIC24 0 H8S 0 MSP430 0 276 | / PIC32 0 H8/300H 0 8051 0/1 277 | */ 278 | 279 | #endif /* _FFCONF */ 280 | -------------------------------------------------------------------------------- /src/ex05/main.c: -------------------------------------------------------------------------------- 1 | #include "stm32746g_discovery.h" 2 | #include "stm32746g_discovery_audio.h" 3 | #include "stm32f7xx_hal.h" 4 | 5 | #include "ff.h" 6 | #include "ff_gen_drv.h" 7 | #include "usbh_diskio.h" 8 | 9 | #include "common/clockconfig.h" 10 | #include "wavfile.h" 11 | 12 | #define VOLUME 70 13 | 14 | #define AUDIO_DMA_BUFFER_SIZE 4096 15 | #define AUDIO_DMA_BUFFER_SIZE2 (AUDIO_DMA_BUFFER_SIZE >> 1) 16 | 17 | #define WAVEFILENAME "0:sound.wav" 18 | 19 | typedef enum { 20 | BUFFER_OFFSET_NONE = 0, 21 | BUFFER_OFFSET_HALF, 22 | BUFFER_OFFSET_FULL 23 | } DMABufferState; 24 | 25 | extern HCD_HandleTypeDef hhcd; 26 | extern USBH_HandleTypeDef hUSBH; 27 | extern SAI_HandleTypeDef haudio_out_sai; 28 | 29 | static uint8_t audio_buf[AUDIO_DMA_BUFFER_SIZE]; 30 | static DMABufferState dma_state = BUFFER_OFFSET_NONE; 31 | 32 | FIL audio_file; 33 | CTSS_WavHeader audio_format; 34 | UINT bytes_read; 35 | 36 | static char usb_drive_path[4]; 37 | 38 | static void process_usbh_message(USBH_HandleTypeDef *host, uint8_t msg); 39 | static void start_playback(); 40 | static void stop_playback(); 41 | static void play_wav_file(); 42 | 43 | int main() { 44 | CPU_CACHE_Enable(); 45 | HAL_Init(); 46 | SystemClock_Config(); 47 | BSP_LED_Init(LED_GREEN); 48 | if (FATFS_LinkDriver(&USBH_Driver, usb_drive_path) == 0) { 49 | USBH_Init(&hUSBH, process_usbh_message, 0); 50 | USBH_RegisterClass(&hUSBH, USBH_MSC_CLASS); 51 | USBH_Start(&hUSBH); 52 | while (1) { 53 | USBH_Process(&hUSBH); 54 | } 55 | } else { 56 | Error_Handler(); 57 | } 58 | return 0; 59 | } 60 | 61 | static void process_usbh_message(USBH_HandleTypeDef *host, uint8_t msg) { 62 | switch (msg) { 63 | case HOST_USER_SELECT_CONFIGURATION: 64 | break; 65 | 66 | case HOST_USER_DISCONNECTION: 67 | f_mount(NULL, (TCHAR const *)"", 0); 68 | stop_playback(); 69 | break; 70 | 71 | case HOST_USER_CLASS_ACTIVE: 72 | start_playback(); 73 | break; 74 | 75 | case HOST_USER_CONNECTION: 76 | break; 77 | 78 | default: 79 | break; 80 | } 81 | } 82 | 83 | static void start_playback() { 84 | if (f_open(&audio_file, WAVEFILENAME, FA_READ) == FR_OK) { 85 | f_read(&audio_file, &audio_format, sizeof(CTSS_WavHeader), &bytes_read); 86 | play_wav_file(); 87 | } else { 88 | Error_Handler(); 89 | } 90 | } 91 | 92 | static void play_wav_file() { 93 | BSP_AUDIO_OUT_Init(OUTPUT_DEVICE_HEADPHONE, VOLUME, audio_format.sampleRate); 94 | BSP_AUDIO_OUT_SetAudioFrameSlot(CODEC_AUDIOFRAME_SLOT_02); 95 | f_lseek(&audio_file, 0); 96 | f_read(&audio_file, audio_buf, AUDIO_DMA_BUFFER_SIZE, &bytes_read); 97 | uint32_t samples_remaining = audio_format.riffLength - bytes_read; 98 | BSP_AUDIO_OUT_Play((uint16_t *)audio_buf, AUDIO_DMA_BUFFER_SIZE); 99 | uint32_t err = 0; 100 | while (!err) { 101 | bytes_read = 0; 102 | if (dma_state == BUFFER_OFFSET_HALF) { 103 | err = (f_read(&audio_file, audio_buf, AUDIO_DMA_BUFFER_SIZE2, 104 | &bytes_read) != FR_OK); 105 | dma_state = BUFFER_OFFSET_NONE; 106 | } else if (dma_state == BUFFER_OFFSET_FULL) { 107 | err = (f_read(&audio_file, &audio_buf[AUDIO_DMA_BUFFER_SIZE2], 108 | AUDIO_DMA_BUFFER_SIZE2, &bytes_read) != FR_OK); 109 | dma_state = BUFFER_OFFSET_NONE; 110 | } 111 | if (!err) { 112 | if (samples_remaining > AUDIO_DMA_BUFFER_SIZE2) { 113 | samples_remaining -= bytes_read; 114 | } else { 115 | f_lseek(&audio_file, 0); 116 | samples_remaining = audio_format.riffLength - bytes_read; 117 | } 118 | BSP_LED_Toggle(LED_GREEN); 119 | } 120 | } 121 | stop_playback(); 122 | } 123 | 124 | static void stop_playback() { 125 | BSP_AUDIO_OUT_Stop(CODEC_PDWN_HW); 126 | } 127 | 128 | void OTG_FS_IRQHandler(void) { 129 | HAL_HCD_IRQHandler(&hhcd); 130 | } 131 | 132 | void AUDIO_OUT_SAIx_DMAx_IRQHandler(void) { 133 | HAL_DMA_IRQHandler(haudio_out_sai.hdmatx); 134 | } 135 | 136 | void BSP_AUDIO_OUT_HalfTransfer_CallBack(void) { 137 | dma_state = BUFFER_OFFSET_HALF; 138 | } 139 | 140 | void BSP_AUDIO_OUT_TransferComplete_CallBack(void) { 141 | dma_state = BUFFER_OFFSET_FULL; 142 | } 143 | 144 | void BSP_AUDIO_OUT_Error_CallBack(void) { 145 | Error_Handler(); 146 | } 147 | -------------------------------------------------------------------------------- /src/ex05/usbh_conf.c: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file USB_Host/MSC_Standalone/Src/usbh_conf.c 4 | * @author MCD Application Team 5 | * @version V1.0.3 6 | * @date 22-April-2016 7 | * @brief USB Host configuration file. 8 | ****************************************************************************** 9 | * @attention 10 | * 11 | *

© Copyright (c) 2016 STMicroelectronics International N.V. 12 | * All rights reserved.

13 | * 14 | * Redistribution and use in source and binary forms, with or without 15 | * modification, are permitted, provided that the following conditions are met: 16 | * 17 | * 1. Redistribution of source code must retain the above copyright notice, 18 | * this list of conditions and the following disclaimer. 19 | * 2. Redistributions in binary form must reproduce the above copyright notice, 20 | * this list of conditions and the following disclaimer in the documentation 21 | * and/or other materials provided with the distribution. 22 | * 3. Neither the name of STMicroelectronics nor the names of other 23 | * contributors to this software may be used to endorse or promote products 24 | * derived from this software without specific written permission. 25 | * 4. This software, including modifications and/or derivative works of this 26 | * software, must execute solely and exclusively on microcontroller or 27 | * microprocessor devices manufactured by or for STMicroelectronics. 28 | * 5. Redistribution and use of this software other than as permitted under 29 | * this license is void and will automatically terminate your rights under 30 | * this license. 31 | * 32 | * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" 33 | * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT 34 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 35 | * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY 36 | * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT 37 | * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 38 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 39 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 40 | * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 41 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 42 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 43 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 44 | * 45 | ****************************************************************************** 46 | */ 47 | 48 | /* Includes ------------------------------------------------------------------*/ 49 | #include "stm32f7xx_hal.h" 50 | #include "usbh_core.h" 51 | //#include "main.h" 52 | #include "ff.h" 53 | #include "ff_gen_drv.h" 54 | 55 | HCD_HandleTypeDef hhcd; 56 | USBH_HandleTypeDef hUSBH; 57 | 58 | FATFS usb_fatfs; 59 | 60 | /******************************************************************************* 61 | HCD BSP Routines 62 | *******************************************************************************/ 63 | /** 64 | * @brief Initializes the HCD MSP. 65 | * @param hhcd: HCD handle 66 | * @retval None 67 | */ 68 | void HAL_HCD_MspInit(HCD_HandleTypeDef *hhcd) { 69 | GPIO_InitTypeDef GPIO_InitStruct; 70 | 71 | if (hhcd->Instance == USB_OTG_FS) { 72 | /* Configure USB FS GPIOs */ 73 | __HAL_RCC_GPIOA_CLK_ENABLE(); 74 | __HAL_RCC_GPIOD_CLK_ENABLE(); 75 | 76 | GPIO_InitStruct.Pin = (GPIO_PIN_11 | GPIO_PIN_12); 77 | GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; 78 | GPIO_InitStruct.Pull = GPIO_NOPULL; 79 | GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; 80 | GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS; 81 | HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 82 | 83 | GPIO_InitStruct.Pin = GPIO_PIN_10; 84 | GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; 85 | GPIO_InitStruct.Pull = GPIO_PULLUP; 86 | GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS; 87 | HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 88 | 89 | /* Configure POWER_SWITCH IO pin */ 90 | GPIO_InitStruct.Pin = GPIO_PIN_5; 91 | GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; 92 | GPIO_InitStruct.Pull = GPIO_NOPULL; 93 | HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); 94 | 95 | /* Enable USB FS Clocks */ 96 | __HAL_RCC_USB_OTG_FS_CLK_ENABLE(); 97 | 98 | /* Set USBFS Interrupt priority */ 99 | HAL_NVIC_SetPriority(OTG_FS_IRQn, 6, 0); 100 | 101 | /* Enable USBFS Interrupt */ 102 | HAL_NVIC_EnableIRQ(OTG_FS_IRQn); 103 | } else if (hhcd->Instance == USB_OTG_HS) { 104 | /* Configure USB HS GPIOs */ 105 | __HAL_RCC_GPIOA_CLK_ENABLE(); 106 | __HAL_RCC_GPIOB_CLK_ENABLE(); 107 | __HAL_RCC_GPIOC_CLK_ENABLE(); 108 | __HAL_RCC_GPIOH_CLK_ENABLE(); 109 | 110 | /* CLK */ 111 | GPIO_InitStruct.Pin = GPIO_PIN_5; 112 | GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; 113 | GPIO_InitStruct.Pull = GPIO_NOPULL; 114 | GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; 115 | GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS; 116 | HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 117 | 118 | /* D0 */ 119 | GPIO_InitStruct.Pin = GPIO_PIN_3; 120 | GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; 121 | GPIO_InitStruct.Pull = GPIO_NOPULL; 122 | GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; 123 | GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS; 124 | HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 125 | 126 | /* D1 D2 D3 D4 D5 D6 D7 */ 127 | GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_5 | GPIO_PIN_10 | 128 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13; 129 | GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; 130 | GPIO_InitStruct.Pull = GPIO_NOPULL; 131 | GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS; 132 | HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); 133 | 134 | /* STP */ 135 | GPIO_InitStruct.Pin = GPIO_PIN_0; 136 | GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; 137 | GPIO_InitStruct.Pull = GPIO_NOPULL; 138 | GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS; 139 | HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); 140 | 141 | /* NXT */ 142 | GPIO_InitStruct.Pin = GPIO_PIN_4; 143 | GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; 144 | GPIO_InitStruct.Pull = GPIO_NOPULL; 145 | GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS; 146 | HAL_GPIO_Init(GPIOH, &GPIO_InitStruct); 147 | 148 | /* DIR */ 149 | GPIO_InitStruct.Pin = GPIO_PIN_2; 150 | GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; 151 | GPIO_InitStruct.Pull = GPIO_NOPULL; 152 | GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS; 153 | HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); 154 | 155 | __HAL_RCC_USB_OTG_HS_ULPI_CLK_ENABLE(); 156 | 157 | /* Enable USB HS Clocks */ 158 | __HAL_RCC_USB_OTG_HS_CLK_ENABLE(); 159 | 160 | /* Set USBHS Interrupt priority */ 161 | HAL_NVIC_SetPriority(OTG_HS_IRQn, 6, 0); 162 | 163 | /* Enable USBHS Interrupt */ 164 | HAL_NVIC_EnableIRQ(OTG_HS_IRQn); 165 | } 166 | } 167 | 168 | /** 169 | * @brief DeInitializes the HCD MSP. 170 | * @param hhcd: HCD handle 171 | * @retval None 172 | */ 173 | void HAL_HCD_MspDeInit(HCD_HandleTypeDef *hhcd) { 174 | if (hhcd->Instance == USB_OTG_FS) { 175 | /* Disable USB FS Clocks */ 176 | __HAL_RCC_USB_OTG_FS_CLK_DISABLE(); 177 | } else if (hhcd->Instance == USB_OTG_HS) { 178 | /* Disable USB HS Clocks */ 179 | __HAL_RCC_USB_OTG_HS_CLK_DISABLE(); 180 | __HAL_RCC_USB_OTG_HS_ULPI_CLK_DISABLE(); 181 | } 182 | } 183 | 184 | /******************************************************************************* 185 | LL Driver Callbacks (HCD -> USB Host Library) 186 | *******************************************************************************/ 187 | 188 | /** 189 | * @brief SOF callback. 190 | * @param hhcd: HCD handle 191 | * @retval None 192 | */ 193 | void HAL_HCD_SOF_Callback(HCD_HandleTypeDef *hhcd) { 194 | USBH_LL_IncTimer(hhcd->pData); 195 | } 196 | 197 | /** 198 | * @brief Connect callback. 199 | * @param hhcd: HCD handle 200 | * @retval None 201 | */ 202 | void HAL_HCD_Connect_Callback(HCD_HandleTypeDef *hhcd) { 203 | USBH_LL_Connect(hhcd->pData); 204 | 205 | /* Register the file system object to the FatFs module */ 206 | if (f_mount(&usb_fatfs, "", 0) != FR_OK) { 207 | //LCD_ErrLog("ERROR : Cannot Initialize FatFs! \n"); 208 | } 209 | } 210 | 211 | /** 212 | * @brief Disconnect callback. 213 | * @param hhcd: HCD handle 214 | * @retval None 215 | */ 216 | void HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef *hhcd) { 217 | USBH_LL_Disconnect(hhcd->pData); 218 | } 219 | 220 | /** 221 | * @brief Notify URB state change callback. 222 | * @param hhcd: HCD handle 223 | * @param chnum: Channel number 224 | * @param urb_state: URB State 225 | * @retval None 226 | */ 227 | void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd, 228 | uint8_t chnum, 229 | HCD_URBStateTypeDef urb_state) { 230 | /* To be used with OS to sync URB state with the global state machine */ 231 | } 232 | 233 | /******************************************************************************* 234 | LL Driver Interface (USB Host Library --> HCD) 235 | *******************************************************************************/ 236 | /** 237 | * @brief USBH_LL_Init 238 | * Initialize the Low Level portion of the Host driver. 239 | * @param phost: Host handle 240 | * @retval USBH Status 241 | */ 242 | USBH_StatusTypeDef USBH_LL_Init(USBH_HandleTypeDef *phost) { 243 | #ifdef USE_USB_FS 244 | /* Set the LL Driver parameters */ 245 | hhcd.Instance = USB_OTG_FS; 246 | hhcd.Init.Host_channels = 11; 247 | hhcd.Init.dma_enable = 0; 248 | hhcd.Init.low_power_enable = 0; 249 | hhcd.Init.phy_itface = HCD_PHY_EMBEDDED; 250 | hhcd.Init.Sof_enable = 0; 251 | hhcd.Init.speed = HCD_SPEED_FULL; 252 | hhcd.Init.vbus_sensing_enable = 0; 253 | hhcd.Init.lpm_enable = 0; 254 | 255 | /* Link the driver to the stack */ 256 | hhcd.pData = phost; 257 | phost->pData = &hhcd; 258 | 259 | /* Initialize the LL Driver */ 260 | HAL_HCD_Init(&hhcd); 261 | #endif 262 | 263 | #ifdef USE_USB_HS 264 | /* Set the LL driver parameters */ 265 | hhcd.Instance = USB_OTG_HS; 266 | hhcd.Init.Host_channels = 11; 267 | hhcd.Init.dma_enable = 1; 268 | hhcd.Init.low_power_enable = 0; 269 | hhcd.Init.phy_itface = HCD_PHY_ULPI; 270 | hhcd.Init.Sof_enable = 0; 271 | hhcd.Init.speed = HCD_SPEED_HIGH; 272 | hhcd.Init.vbus_sensing_enable = 0; 273 | hhcd.Init.use_external_vbus = 1; 274 | hhcd.Init.lpm_enable = 0; 275 | 276 | /* Link the driver to the stack */ 277 | hhcd.pData = phost; 278 | phost->pData = &hhcd; 279 | 280 | /* Initialize the LL driver */ 281 | HAL_HCD_Init(&hhcd); 282 | 283 | #endif /*USE_USB_HS*/ 284 | USBH_LL_SetTimer(phost, HAL_HCD_GetCurrentFrame(&hhcd)); 285 | 286 | return USBH_OK; 287 | } 288 | 289 | /** 290 | * @brief De-Initializes the Low Level portion of the Host driver. 291 | * @param phost: Host handle 292 | * @retval USBH Status 293 | */ 294 | USBH_StatusTypeDef USBH_LL_DeInit(USBH_HandleTypeDef *phost) { 295 | HAL_HCD_DeInit(phost->pData); 296 | return USBH_OK; 297 | } 298 | 299 | /** 300 | * @brief Starts the Low Level portion of the Host driver. 301 | * @param phost: Host handle 302 | * @retval USBH Status 303 | */ 304 | USBH_StatusTypeDef USBH_LL_Start(USBH_HandleTypeDef *phost) { 305 | HAL_HCD_Start(phost->pData); 306 | return USBH_OK; 307 | } 308 | 309 | /** 310 | * @brief Stops the Low Level portion of the Host driver. 311 | * @param phost: Host handle 312 | * @retval USBH Status 313 | */ 314 | USBH_StatusTypeDef USBH_LL_Stop(USBH_HandleTypeDef *phost) { 315 | HAL_HCD_Stop(phost->pData); 316 | return USBH_OK; 317 | } 318 | 319 | /** 320 | * @brief Returns the USB Host Speed from the Low Level Driver. 321 | * @param phost: Host handle 322 | * @retval USBH Speeds 323 | */ 324 | USBH_SpeedTypeDef USBH_LL_GetSpeed(USBH_HandleTypeDef *phost) { 325 | USBH_SpeedTypeDef speed = USBH_SPEED_FULL; 326 | 327 | switch (HAL_HCD_GetCurrentSpeed(phost->pData)) { 328 | case 0: 329 | speed = USBH_SPEED_HIGH; 330 | break; 331 | 332 | case 1: 333 | speed = USBH_SPEED_FULL; 334 | break; 335 | 336 | case 2: 337 | speed = USBH_SPEED_LOW; 338 | break; 339 | 340 | default: 341 | speed = USBH_SPEED_FULL; 342 | break; 343 | } 344 | return speed; 345 | } 346 | 347 | /** 348 | * @brief Resets the Host Port of the Low Level Driver. 349 | * @param phost: Host handle 350 | * @retval USBH Status 351 | */ 352 | USBH_StatusTypeDef USBH_LL_ResetPort(USBH_HandleTypeDef *phost) { 353 | HAL_HCD_ResetPort(phost->pData); 354 | return USBH_OK; 355 | } 356 | 357 | /** 358 | * @brief Returns the last transferred packet size. 359 | * @param phost: Host handle 360 | * @param pipe: Pipe index 361 | * @retval Packet Size 362 | */ 363 | uint32_t USBH_LL_GetLastXferSize(USBH_HandleTypeDef *phost, uint8_t pipe) { 364 | return HAL_HCD_HC_GetXferCount(phost->pData, pipe); 365 | } 366 | 367 | /** 368 | * @brief Opens a pipe of the Low Level Driver. 369 | * @param phost: Host handle 370 | * @param pipe: Pipe index 371 | * @param epnum: Endpoint Number 372 | * @param dev_address: Device USB address 373 | * @param speed: Device Speed 374 | * @param ep_type: Endpoint Type 375 | * @param mps: Endpoint Max Packet Size 376 | * @retval USBH Status 377 | */ 378 | USBH_StatusTypeDef USBH_LL_OpenPipe(USBH_HandleTypeDef *phost, 379 | uint8_t pipe, 380 | uint8_t epnum, 381 | uint8_t dev_address, 382 | uint8_t speed, 383 | uint8_t ep_type, 384 | uint16_t mps) { 385 | HAL_HCD_HC_Init(phost->pData, pipe, epnum, dev_address, speed, ep_type, mps); 386 | return USBH_OK; 387 | } 388 | 389 | /** 390 | * @brief Closes a pipe of the Low Level Driver. 391 | * @param phost: Host handle 392 | * @param pipe: Pipe index 393 | * @retval USBH Status 394 | */ 395 | USBH_StatusTypeDef USBH_LL_ClosePipe(USBH_HandleTypeDef *phost, uint8_t pipe) { 396 | HAL_HCD_HC_Halt(phost->pData, pipe); 397 | return USBH_OK; 398 | } 399 | 400 | /** 401 | * @brief Submits a new URB to the low level driver. 402 | * @param phost: Host handle 403 | * @param pipe: Pipe index 404 | * This parameter can be a value from 1 to 15 405 | * @param direction: Channel number 406 | * This parameter can be one of these values: 407 | * 0: Output 408 | * 1: Input 409 | * @param ep_type: Endpoint Type 410 | * This parameter can be one of these values: 411 | * @arg EP_TYPE_CTRL: Control type 412 | * @arg EP_TYPE_ISOC: Isochronous type 413 | * @arg EP_TYPE_BULK: Bulk type 414 | * @arg EP_TYPE_INTR: Interrupt type 415 | * @param token: Endpoint Type 416 | * This parameter can be one of these values: 417 | * @arg 0: PID_SETUP 418 | * @arg 1: PID_DATA 419 | * @param pbuff: pointer to URB data 420 | * @param length: length of URB data 421 | * @param do_ping: activate do ping protocol (for high speed only) 422 | * This parameter can be one of these values: 423 | * 0: do ping inactive 424 | * 1: do ping active 425 | * @retval USBH Status 426 | */ 427 | USBH_StatusTypeDef USBH_LL_SubmitURB(USBH_HandleTypeDef *phost, 428 | uint8_t pipe, 429 | uint8_t direction, 430 | uint8_t ep_type, 431 | uint8_t token, 432 | uint8_t *pbuff, 433 | uint16_t length, 434 | uint8_t do_ping) { 435 | HAL_HCD_HC_SubmitRequest(phost->pData, pipe, direction, ep_type, token, pbuff, 436 | length, do_ping); 437 | return USBH_OK; 438 | } 439 | 440 | /** 441 | * @brief Gets a URB state from the low level driver. 442 | * @param phost: Host handle 443 | * @param pipe: Pipe index 444 | * This parameter can be a value from 1 to 15 445 | * @retval URB state 446 | * This parameter can be one of these values: 447 | * @arg URB_IDLE 448 | * @arg URB_DONE 449 | * @arg URB_NOTREADY 450 | * @arg URB_NYET 451 | * @arg URB_ERROR 452 | * @arg URB_STALL 453 | */ 454 | USBH_URBStateTypeDef USBH_LL_GetURBState(USBH_HandleTypeDef *phost, 455 | uint8_t pipe) { 456 | return (USBH_URBStateTypeDef)HAL_HCD_HC_GetURBState(phost->pData, pipe); 457 | } 458 | 459 | /** 460 | * @brief Drives VBUS. 461 | * @param phost: Host handle 462 | * @param state: VBUS state 463 | * This parameter can be one of these values: 464 | * 0: VBUS Active 465 | * 1: VBUS Inactive 466 | * @retval USBH Status 467 | */ 468 | USBH_StatusTypeDef USBH_LL_DriverVBUS(USBH_HandleTypeDef *phost, 469 | uint8_t state) { 470 | #ifdef USE_USB_FS 471 | if (state == 0) { 472 | HAL_GPIO_WritePin(GPIOD, GPIO_PIN_5, GPIO_PIN_SET); 473 | } else { 474 | HAL_GPIO_WritePin(GPIOD, GPIO_PIN_5, GPIO_PIN_RESET); 475 | } 476 | 477 | HAL_Delay(200); 478 | #endif /* USE_USB_FS */ 479 | return USBH_OK; 480 | } 481 | 482 | /** 483 | * @brief Sets toggle for a pipe. 484 | * @param phost: Host handle 485 | * @param pipe: Pipe index 486 | * @param toggle: toggle (0/1) 487 | * @retval USBH Status 488 | */ 489 | USBH_StatusTypeDef USBH_LL_SetToggle(USBH_HandleTypeDef *phost, 490 | uint8_t pipe, 491 | uint8_t toggle) { 492 | if (hhcd.hc[pipe].ep_is_in) { 493 | hhcd.hc[pipe].toggle_in = toggle; 494 | } else { 495 | hhcd.hc[pipe].toggle_out = toggle; 496 | } 497 | return USBH_OK; 498 | } 499 | 500 | /** 501 | * @brief Returns the current toggle of a pipe. 502 | * @param phost: Host handle 503 | * @param pipe: Pipe index 504 | * @retval toggle (0/1) 505 | */ 506 | uint8_t USBH_LL_GetToggle(USBH_HandleTypeDef *phost, uint8_t pipe) { 507 | uint8_t toggle = 0; 508 | 509 | if (hhcd.hc[pipe].ep_is_in) { 510 | toggle = hhcd.hc[pipe].toggle_in; 511 | } else { 512 | toggle = hhcd.hc[pipe].toggle_out; 513 | } 514 | return toggle; 515 | } 516 | 517 | /** 518 | * @brief Delay routine for the USB Host Library 519 | * @param Delay: Delay in ms 520 | * @retval None 521 | */ 522 | void USBH_Delay(uint32_t Delay) { 523 | #if (USBH_USE_OS == 1) 524 | osDelay(Delay); 525 | #else 526 | HAL_Delay(Delay); 527 | #endif 528 | } 529 | 530 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 531 | -------------------------------------------------------------------------------- /src/ex05/usbh_conf.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include "stm32f7xx.h" 7 | 8 | #define USBH_MAX_NUM_ENDPOINTS 2 9 | #define USBH_MAX_NUM_INTERFACES 2 10 | #define USBH_MAX_NUM_CONFIGURATION 1 11 | #define USBH_MAX_NUM_SUPPORTED_CLASS 1 12 | #define USBH_KEEP_CFG_DESCRIPTOR 1 13 | #define USBH_MAX_SIZE_CONFIGURATION 0x200 14 | #define USBH_MAX_DATA_BUFFER 0x200 15 | #define USBH_DEBUG_LEVEL 0 16 | #define USBH_USE_OS 0 17 | #define USE_USB_FS 0 18 | 19 | /* CMSIS OS macros */ 20 | #if (USBH_USE_OS == 1) 21 | #include "cmsis_os.h" 22 | #define USBH_PROCESS_PRIO osPriorityNormal 23 | #endif 24 | 25 | /* Memory management macros */ 26 | #define USBH_malloc malloc 27 | #define USBH_free free 28 | #define USBH_memset memset 29 | #define USBH_memcpy memcpy 30 | 31 | /* DEBUG macros */ 32 | 33 | #if (USBH_DEBUG_LEVEL > 0) 34 | #define USBH_UsrLog(...) \ 35 | printf(__VA_ARGS__); \ 36 | printf("\n"); 37 | #else 38 | #define USBH_UsrLog(...) 39 | #endif 40 | 41 | #if (USBH_DEBUG_LEVEL > 1) 42 | 43 | #define USBH_ErrLog(...) \ 44 | printf("ERROR: "); \ 45 | printf(__VA_ARGS__); \ 46 | printf("\n"); 47 | #else 48 | #define USBH_ErrLog(...) 49 | #endif 50 | 51 | #if (USBH_DEBUG_LEVEL > 2) 52 | #define USBH_DbgLog(...) \ 53 | printf("DEBUG : "); \ 54 | printf(__VA_ARGS__); \ 55 | printf("\n"); 56 | #else 57 | #define USBH_DbgLog(...) 58 | #endif 59 | -------------------------------------------------------------------------------- /src/ex06/main.c: -------------------------------------------------------------------------------- 1 | #include "stm32746g_discovery_audio.h" 2 | #include "stm32746g_discovery_lcd.h" 3 | 4 | #include "adsr.h" 5 | #include "biquad.h" 6 | #include "delay.h" 7 | #include "node_ops.h" 8 | #include "osc.h" 9 | #include "panning.h" 10 | #include "synth.h" 11 | 12 | #include "common/clockconfig.h" 13 | #include "ct-head/random.h" 14 | 15 | #define VOLUME 90 16 | #define SAMPLE_RATE 44100 17 | 18 | #define AUDIO_DMA_BUFFER_SIZE 512 19 | #define AUDIO_DMA_BUFFER_SIZE2 (AUDIO_DMA_BUFFER_SIZE >> 1) 20 | #define AUDIO_DMA_BUFFER_SIZE4 (AUDIO_DMA_BUFFER_SIZE >> 2) 21 | #define AUDIO_DMA_BUFFER_SIZE8 (AUDIO_DMA_BUFFER_SIZE >> 3) 22 | 23 | extern SAI_HandleTypeDef haudio_out_sai; 24 | static uint8_t audioBuf[AUDIO_DMA_BUFFER_SIZE]; 25 | 26 | static CTSS_Synth synth; 27 | static CT_Smush rnd; 28 | 29 | //static const uint8_t scale[] = {36, 40, 43, 45, 60, 48, 52, 55}; 30 | static const uint8_t scale[] = {36, 40, 43, 45, 55, 52, 48, 60}; 31 | static uint32_t note_id = 0; 32 | static uint32_t voice_id = 0; 33 | static __IO uint32_t new_note = 0; 34 | 35 | static void init_voice(CTSS_Synth *synth, CTSS_DSPStack *stack); 36 | static void trigger_note(); 37 | static void render_audio(int16_t *buf); 38 | 39 | int main() { 40 | CPU_CACHE_Enable(); 41 | HAL_Init(); 42 | SystemClock_Config(); 43 | BSP_LED_Init(LED_GREEN); 44 | BSP_LCD_Init(); 45 | 46 | ct_smush_init(&rnd, 0xcafebabe); 47 | ctss_init(&synth, 7); 48 | ctss_add_global_lfo(&synth, ctss_osc("lfo1", ctss_process_osc_sin, 0.0f, 49 | HZ_TO_RAD(0.125f), 0.3f, 0.8f)); 50 | ctss_add_global_lfo(&synth, ctss_osc("lfo2", ctss_process_osc_sin, 0.0f, 51 | HZ_TO_RAD(0.25f), 0.495f, 0.5f)); 52 | 53 | for (uint8_t i = 0; i < synth.numStacks; i++) { 54 | init_voice(&synth, &synth.stacks[i]); 55 | } 56 | ctss_collect_stacks(&synth); 57 | 58 | if (BSP_AUDIO_OUT_Init(OUTPUT_DEVICE_HEADPHONE, VOLUME, SAMPLE_RATE) != 0) { 59 | Error_Handler(); 60 | } 61 | BSP_AUDIO_OUT_SetAudioFrameSlot(CODEC_AUDIOFRAME_SLOT_02); 62 | BSP_AUDIO_OUT_SetVolume(VOLUME); 63 | BSP_AUDIO_OUT_Play((uint16_t *)audioBuf, AUDIO_DMA_BUFFER_SIZE); 64 | 65 | while (1) { 66 | new_note = 1; 67 | BSP_LED_Toggle(LED_GREEN); 68 | HAL_Delay(125); 69 | } 70 | 71 | return 0; 72 | } 73 | 74 | static void init_voice(CTSS_Synth *synth, CTSS_DSPStack *stack) { 75 | CTSS_DSPNode *env = ctss_adsr("env", synth->lfo[0]); 76 | ctss_configure_adsr(env, 0.01f, 0.035f, 0.8f, 1.0f, 0.15f, false); 77 | CTSS_DSPNode *osc1 = ctss_osc("osc1", ctss_process_osc_spiral, 0, 0, 0.22f, 0); 78 | CTSS_DSPNode *osc2 = ctss_osc("osc2", ctss_process_osc_sawsin, 0, 0, 0.22f, 0); 79 | CTSS_DSPNode *sum = ctss_op4("sum", osc1, env, osc2, env, ctss_process_madd); 80 | CTSS_DSPNode *filter = 81 | ctss_filter_biquad("filter", LPF, sum, 1000.0f, 0.0f, 0.5f); 82 | CTSS_DSPNode *pan = ctss_panning("pan", filter, synth->lfo[1], 0.0f); 83 | CTSS_DSPNode *delay = 84 | ctss_delay("delay", pan, (uint32_t)(SAMPLE_RATE * 0.125f), 0.6f, 2); 85 | CTSS_DSPNode *nodes[] = {env, osc1, osc2, sum, filter, pan, delay}; 86 | ctss_build_stack(stack, nodes, 7); 87 | } 88 | 89 | static void trigger_note() { 90 | float time = HAL_GetTick(); 91 | int32_t pitch = scale[ct_smush(&rnd) % 8] - (ct_smush(&rnd) & 1) * 12; 92 | float freq = ctss_notes[pitch]; 93 | freq = HZ_TO_RAD(freq); 94 | CTSS_DSPStack *s = &synth.stacks[voice_id]; 95 | ctss_reset_adsr(NODE_ID(s, "env")); 96 | NODE_ID_STATE(CTSS_OscState, s, "osc1")->freq = freq; 97 | NODE_ID_STATE(CTSS_OscState, s, "osc2")->freq = freq * 0.505; 98 | ctss_calculate_biquad_coeff(NODE_ID(s, "filter"), LPF, 99 | 2800.0f + sinf(time * 0.1f) * 2400.0f, -18.0f, 100 | ct_smush_minmax(&rnd, 0.075f, 2.0f)); 101 | ctss_activate_stack(s); 102 | note_id = (note_id + 1) % 8; 103 | voice_id = (voice_id + 1) % synth.numStacks; 104 | } 105 | 106 | static void render_audio(int16_t *buf) { 107 | if (new_note) { 108 | trigger_note(); 109 | new_note = 0; 110 | } 111 | ctss_update_mix_stereo_i16(&synth, ctss_mixdown_i16, AUDIO_DMA_BUFFER_SIZE8, 112 | buf); 113 | } 114 | 115 | void AUDIO_OUT_SAIx_DMAx_IRQHandler(void) { 116 | HAL_DMA_IRQHandler(haudio_out_sai.hdmatx); 117 | } 118 | 119 | void BSP_AUDIO_OUT_HalfTransfer_CallBack(void) { 120 | render_audio((int16_t *)&audioBuf[0]); 121 | } 122 | 123 | void BSP_AUDIO_OUT_TransferComplete_CallBack(void) { 124 | render_audio((int16_t *)&audioBuf[AUDIO_DMA_BUFFER_SIZE2]); 125 | } 126 | 127 | void BSP_AUDIO_OUT_Error_CallBack(void) { 128 | Error_Handler(); 129 | } 130 | -------------------------------------------------------------------------------- /src/ex07/main.c: -------------------------------------------------------------------------------- 1 | #include "stm32746g_discovery_audio.h" 2 | #include "stm32746g_discovery_lcd.h" 3 | #include "stm32746g_discovery_sdram.h" 4 | 5 | #include "adsr.h" 6 | #include "biquad.h" 7 | #include "foldback.h" 8 | #include "node_ops.h" 9 | #include "osc.h" 10 | #include "osc_noise.h" 11 | #include "panning.h" 12 | #include "sdram_delay.h" 13 | #include "synth.h" 14 | 15 | #include "common/clockconfig.h" 16 | #include "ct-head/random.h" 17 | 18 | #define VOLUME 80 19 | #define SAMPLE_RATE 44100 20 | 21 | #define AUDIO_DMA_BUFFER_SIZE 512 22 | #define AUDIO_DMA_BUFFER_SIZE2 (AUDIO_DMA_BUFFER_SIZE >> 1) 23 | #define AUDIO_DMA_BUFFER_SIZE4 (AUDIO_DMA_BUFFER_SIZE >> 2) 24 | #define AUDIO_DMA_BUFFER_SIZE8 (AUDIO_DMA_BUFFER_SIZE >> 3) 25 | 26 | extern SAI_HandleTypeDef haudio_out_sai; 27 | static uint8_t audioBuf[AUDIO_DMA_BUFFER_SIZE]; 28 | 29 | static CTSS_Synth synth; 30 | static CT_Smush rnd; 31 | 32 | static const uint8_t scale[] = {36, 40, 43, 45, 55, 52, 48, 60}; 33 | static uint32_t note_id = 0; 34 | static uint32_t voice_id = 0; 35 | static __IO uint32_t new_note = 0; 36 | 37 | static void init_voice(CTSS_Synth *synth, CTSS_DSPStack *stack); 38 | static void trigger_note(); 39 | static void render_audio(int16_t *buf); 40 | 41 | int main() { 42 | CPU_CACHE_Enable(); 43 | HAL_Init(); 44 | SystemClock_Config(); 45 | BSP_LED_Init(LED_GREEN); 46 | 47 | // IMPORTANT! Initialize SDRAM before using sdram_malloc & co. 48 | if (BSP_SDRAM_Init() != SDRAM_OK) { 49 | Error_Handler(); 50 | } 51 | 52 | ct_smush_init(&rnd, 0xcafebabe); 53 | ctss_osc_noise_init(); 54 | ctss_init(&synth, 2); 55 | ctss_add_global_lfo(&synth, ctss_osc("lfo1", ctss_process_osc_sin, 0.0f, 56 | HZ_TO_RAD(0.125f), 0.4f, 0.8f)); 57 | ctss_add_global_lfo(&synth, ctss_osc("lfo2", ctss_process_osc_sin, 0.0f, 58 | HZ_TO_RAD(0.25f), 0.495f, 0.5f)); 59 | ctss_add_global_lfo(&synth, ctss_osc("lfo3", ctss_process_osc_tri, 0.0f, 60 | HZ_TO_RAD(0.1f), 0.499f, 0.5f)); 61 | 62 | for (uint8_t i = 0; i < synth.numStacks; i++) { 63 | init_voice(&synth, &synth.stacks[i]); 64 | } 65 | ctss_collect_stacks(&synth); 66 | 67 | if (BSP_AUDIO_OUT_Init(OUTPUT_DEVICE_HEADPHONE, VOLUME, SAMPLE_RATE) != 0) { 68 | Error_Handler(); 69 | } 70 | BSP_AUDIO_OUT_SetAudioFrameSlot(CODEC_AUDIOFRAME_SLOT_02); 71 | BSP_AUDIO_OUT_SetVolume(VOLUME); 72 | BSP_AUDIO_OUT_Play((uint16_t *)audioBuf, AUDIO_DMA_BUFFER_SIZE); 73 | 74 | while (1) { 75 | new_note = 1; 76 | BSP_LED_Toggle(LED_GREEN); 77 | HAL_Delay(750); 78 | } 79 | 80 | return 0; 81 | } 82 | 83 | // see README for DSP graph visualization 84 | 85 | static void init_voice(CTSS_Synth *synth, CTSS_DSPStack *stack) { 86 | CTSS_DSPNode *env = ctss_adsr("env", synth->lfo[0]); 87 | ctss_configure_adsr(env, 0.01f, 0.05f, 0.85f, 1.0f, 0.25f, false); 88 | CTSS_DSPNode *osc1 = ctss_osc("osc1", ctss_process_osc_spiral, 0, 0, 0.3f, 0); 89 | CTSS_DSPNode *osc2 = ctss_osc("osc2", ctss_process_osc_sawsin, 0, 0, 0.3f, 0); 90 | CTSS_DSPNode *osc3 = 91 | ctss_osc("osc3", ctss_process_osc_noise, 0, 0, 0.025f, 0); 92 | CTSS_DSPNode *sum = ctss_op4("sum", osc1, env, osc2, env, ctss_process_madd); 93 | CTSS_DSPNode *nsum = ctss_op2("nsum", osc3, synth->lfo[2], ctss_process_mult); 94 | CTSS_DSPNode *sum2 = ctss_op2("sum2", sum, nsum, ctss_process_sum); 95 | CTSS_DSPNode *fb = ctss_foldback("fb", sum2, 0.1, 4.0f); 96 | CTSS_DSPNode *filter = 97 | ctss_filter_biquad("filter", LPF, fb, 1000.0f, 0.0f, 0.5f); 98 | CTSS_DSPNode *pan = ctss_panning("pan", filter, synth->lfo[1], 0.0f); 99 | CTSS_DSPNode *delay = 100 | ctss_delay_sdram("delay", pan, (uint32_t)(SAMPLE_RATE * 0.5f), 0.9f, 2); 101 | CTSS_DSPNode *nodes[] = {env, osc1, osc2, osc3, sum, nsum, 102 | sum2, fb, filter, pan, delay}; 103 | ctss_build_stack(stack, nodes, 11); 104 | } 105 | 106 | static void trigger_note() { 107 | float time = HAL_GetTick(); 108 | int32_t pitch = scale[ct_smush(&rnd) % 8] - (ct_smush(&rnd) & 1) * 12; 109 | float freq = ctss_notes[pitch]; 110 | freq = HZ_TO_RAD(freq); 111 | CTSS_DSPStack *s = &synth.stacks[voice_id]; 112 | ctss_reset_adsr(NODE_ID(s, "env")); 113 | NODE_ID_STATE(CTSS_OscState, s, "osc1")->freq = freq; 114 | NODE_ID_STATE(CTSS_OscState, s, "osc2")->freq = freq * 0.51; 115 | ctss_calculate_biquad_coeff(NODE_ID(s, "filter"), LPF, 116 | 2800.0f + sinf(time * 0.1f) * 2400.0f, -18.0f, 117 | ct_smush_minmax(&rnd, 0.25f, 2.0f)); 118 | ctss_activate_stack(s); 119 | note_id = (note_id + 1) % 8; 120 | voice_id = (voice_id + 1) % synth.numStacks; 121 | } 122 | 123 | static void render_audio(int16_t *buf) { 124 | if (new_note) { 125 | trigger_note(); 126 | new_note = 0; 127 | } 128 | ctss_update_mix_stereo_i16(&synth, ctss_mixdown_i16, AUDIO_DMA_BUFFER_SIZE8, 129 | buf); 130 | } 131 | 132 | void AUDIO_OUT_SAIx_DMAx_IRQHandler(void) { 133 | HAL_DMA_IRQHandler(haudio_out_sai.hdmatx); 134 | } 135 | 136 | void BSP_AUDIO_OUT_HalfTransfer_CallBack(void) { 137 | render_audio((int16_t *)&audioBuf[0]); 138 | } 139 | 140 | void BSP_AUDIO_OUT_TransferComplete_CallBack(void) { 141 | render_audio((int16_t *)&audioBuf[AUDIO_DMA_BUFFER_SIZE2]); 142 | } 143 | 144 | void BSP_AUDIO_OUT_Error_CallBack(void) { 145 | Error_Handler(); 146 | } 147 | -------------------------------------------------------------------------------- /src/ex08/main.c: -------------------------------------------------------------------------------- 1 | #include "stm32746g_discovery_audio.h" 2 | #include "stm32746g_discovery_lcd.h" 3 | #include "stm32746g_discovery_sdram.h" 4 | 5 | #include "adsr.h" 6 | #include "biquad.h" 7 | #include "foldback.h" 8 | #include "node_ops.h" 9 | #include "osc.h" 10 | #include "osc_noise.h" 11 | #include "panning.h" 12 | #include "sdram_delay.h" 13 | #include "synth.h" 14 | 15 | #include "common/clockconfig.h" 16 | #include "ct-head/random.h" 17 | #include "midi_log.h" 18 | #include "usbh_MIDI.h" 19 | 20 | #define VOLUME 70 21 | 22 | #define AUDIO_DMA_BUFFER_SIZE 512 23 | #define AUDIO_DMA_BUFFER_SIZE2 (AUDIO_DMA_BUFFER_SIZE >> 1) 24 | #define AUDIO_DMA_BUFFER_SIZE4 (AUDIO_DMA_BUFFER_SIZE >> 2) 25 | #define AUDIO_DMA_BUFFER_SIZE8 (AUDIO_DMA_BUFFER_SIZE >> 3) 26 | 27 | extern HCD_HandleTypeDef hhcd; 28 | extern USBH_HandleTypeDef hUSBH; 29 | extern SAI_HandleTypeDef haudio_out_sai; 30 | 31 | static uint8_t audio_buf[AUDIO_DMA_BUFFER_SIZE] = {0}; 32 | static uint8_t midi_receive_buf[USB_MIDI_RX_BUFFER_SIZE]; 33 | static uint32_t voice_id = 0; 34 | 35 | static CTSS_Synth synth; 36 | static CT_Smush rnd; 37 | 38 | static void process_usbh_message(USBH_HandleTypeDef *host, uint8_t msg); 39 | static void start_playback(); 40 | static void stop_playback(); 41 | static void init_synth(); 42 | static void init_voice(CTSS_Synth *synth, CTSS_DSPStack *stack); 43 | 44 | int main() { 45 | CPU_CACHE_Enable(); 46 | HAL_Init(); 47 | SystemClock_Config(); 48 | BSP_LED_Init(LED_GREEN); 49 | BSP_SDRAM_Init(); 50 | 51 | init_midi_log(); 52 | init_synth(); 53 | 54 | USBH_Init(&hUSBH, process_usbh_message, 0); 55 | USBH_RegisterClass(&hUSBH, USBH_MIDI_CLASS); 56 | USBH_Start(&hUSBH); 57 | while (1) { 58 | USBH_Process(&hUSBH); 59 | } 60 | return 0; 61 | } 62 | 63 | static void init_synth() { 64 | ct_smush_init(&rnd, 0xcafebabe); 65 | ctss_osc_noise_init(); 66 | ctss_init(&synth, 4); 67 | ctss_add_global_lfo(&synth, ctss_osc("lfo1", ctss_process_osc_sin, 0.0f, 68 | HZ_TO_RAD(0.125f), 0.4f, 0.8f)); 69 | ctss_add_global_lfo(&synth, ctss_osc("lfo2", ctss_process_osc_sin, 0.0f, 70 | HZ_TO_RAD(0.25f), 0.495f, 0.5f)); 71 | ctss_add_global_lfo(&synth, ctss_osc("lfo3", ctss_process_osc_tri, 0.0f, 72 | HZ_TO_RAD(0.1f), 0.499f, 0.5f)); 73 | 74 | for (uint8_t i = 0; i < synth.numStacks; i++) { 75 | init_voice(&synth, &synth.stacks[i]); 76 | } 77 | ctss_collect_stacks(&synth); 78 | } 79 | 80 | static void init_voice(CTSS_Synth *synth, CTSS_DSPStack *stack) { 81 | CTSS_DSPNode *env = ctss_adsr("env", synth->lfo[0]); 82 | ctss_configure_adsr(env, 0.01f, 0.05f, 0.85f, 1.0f, 0.25f, false); 83 | CTSS_DSPNode *osc1 = ctss_osc("osc1", ctss_process_osc_spiral, 0, 0, 0.1f, 0); 84 | CTSS_DSPNode *osc2 = ctss_osc("osc2", ctss_process_osc_sawsin, 0, 0, 0.1f, 0); 85 | CTSS_DSPNode *osc3 = 86 | ctss_osc("osc3", ctss_process_osc_noise, 0, 0, 0.015f, 0); 87 | CTSS_DSPNode *sum = ctss_op4("sum", osc1, env, osc2, env, ctss_process_madd); 88 | CTSS_DSPNode *nsum = ctss_op2("nsum", osc3, synth->lfo[2], ctss_process_mult); 89 | CTSS_DSPNode *sum2 = ctss_op2("sum2", sum, nsum, ctss_process_sum); 90 | CTSS_DSPNode *fb = ctss_foldback("fb", sum2, 0.1, 4.0f); 91 | CTSS_DSPNode *filter = 92 | ctss_filter_biquad("filter", LPF, fb, 1000.0f, 0.0f, 0.5f); 93 | CTSS_DSPNode *pan = ctss_panning("pan", filter, synth->lfo[1], 0.0f); 94 | CTSS_DSPNode *delay = 95 | ctss_delay_sdram("delay", pan, (uint32_t)(SAMPLE_RATE * 0.5f), 0.6f, 2); 96 | CTSS_DSPNode *nodes[] = {env, osc1, osc2, osc3, sum, nsum, 97 | sum2, fb, filter, pan, delay}; 98 | ctss_build_stack(stack, nodes, 11); 99 | } 100 | 101 | static void trigger_note(uint8_t note) { 102 | float time = HAL_GetTick(); 103 | float freq = HZ_TO_RAD(ctss_notes[note]); 104 | CTSS_DSPStack *s = &synth.stacks[voice_id]; 105 | ctss_reset_adsr(NODE_ID(s, "env")); 106 | NODE_ID_STATE(CTSS_OscState, s, "osc1")->freq = freq; 107 | NODE_ID_STATE(CTSS_OscState, s, "osc2")->freq = freq * 0.51; 108 | ctss_calculate_biquad_coeff(NODE_ID(s, "filter"), LPF, 109 | 2800.0f + sinf(time * 0.1f) * 2400.0f, -18.0f, 110 | ct_smush_minmax(&rnd, 0.25f, 2.0f)); 111 | ctss_activate_stack(s); 112 | voice_id = (voice_id + 1) % synth.numStacks; 113 | } 114 | 115 | static void render_audio(int16_t *buf) { 116 | ctss_update_mix_stereo_i16(&synth, ctss_mixdown_i16, AUDIO_DMA_BUFFER_SIZE8, 117 | buf); 118 | } 119 | 120 | static void process_usbh_message(USBH_HandleTypeDef *host, uint8_t msg) { 121 | switch (msg) { 122 | case HOST_USER_SELECT_CONFIGURATION: 123 | break; 124 | 125 | case HOST_USER_DISCONNECTION: 126 | stop_playback(); 127 | break; 128 | 129 | case HOST_USER_CLASS_ACTIVE: 130 | USBH_MIDI_Receive(&hUSBH, midi_receive_buf, USB_MIDI_RX_BUFFER_SIZE); 131 | start_playback(); 132 | break; 133 | 134 | case HOST_USER_CONNECTION: 135 | break; 136 | 137 | default: 138 | break; 139 | } 140 | } 141 | 142 | static void start_playback() { 143 | BSP_AUDIO_OUT_Init(OUTPUT_DEVICE_HEADPHONE, VOLUME, 44100); 144 | BSP_AUDIO_OUT_SetAudioFrameSlot(CODEC_AUDIOFRAME_SLOT_02); 145 | BSP_AUDIO_OUT_Play((uint16_t *)audio_buf, AUDIO_DMA_BUFFER_SIZE); 146 | BSP_LED_On(LED_GREEN); 147 | } 148 | 149 | static void stop_playback() { 150 | BSP_LED_Off(LED_GREEN); 151 | } 152 | 153 | static void process_midi_packets() { 154 | midi_package_t *packet = (midi_package_t *)midi_receive_buf; 155 | uint16_t num = USBH_MIDI_GetLastReceivedDataSize(&hUSBH) / 4; 156 | if (num > 0) { 157 | while (num--) { 158 | if (packet->type > 7) { 159 | log_midi_packet(packet); 160 | if (packet->type == 9) { 161 | trigger_note(packet->value1); 162 | } 163 | } 164 | packet++; 165 | } 166 | } 167 | } 168 | 169 | void OTG_FS_IRQHandler(void) { 170 | HAL_HCD_IRQHandler(&hhcd); 171 | } 172 | 173 | void USBH_MIDI_ReceiveCallback(USBH_HandleTypeDef *phost) { 174 | BSP_LED_Toggle(LED_GREEN); 175 | process_midi_packets(); 176 | USBH_MIDI_Receive(&hUSBH, midi_receive_buf, USB_MIDI_RX_BUFFER_SIZE); 177 | //canReceive = 1; 178 | } 179 | 180 | void AUDIO_OUT_SAIx_DMAx_IRQHandler(void) { 181 | HAL_DMA_IRQHandler(haudio_out_sai.hdmatx); 182 | } 183 | 184 | void BSP_AUDIO_OUT_HalfTransfer_CallBack(void) { 185 | render_audio((int16_t *)&audio_buf[0]); 186 | } 187 | 188 | void BSP_AUDIO_OUT_TransferComplete_CallBack(void) { 189 | render_audio((int16_t *)&audio_buf[AUDIO_DMA_BUFFER_SIZE2]); 190 | } 191 | 192 | void BSP_AUDIO_OUT_Error_CallBack(void) { 193 | Error_Handler(); 194 | } 195 | -------------------------------------------------------------------------------- /src/ex08/usbh_conf.c: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file USB_Host/MSC_Standalone/Src/usbh_conf.c 4 | * @author MCD Application Team 5 | * @version V1.0.3 6 | * @date 22-April-2016 7 | * @brief USB Host configuration file. 8 | ****************************************************************************** 9 | * @attention 10 | * 11 | *

© Copyright (c) 2016 STMicroelectronics International N.V. 12 | * All rights reserved.

13 | * 14 | * Redistribution and use in source and binary forms, with or without 15 | * modification, are permitted, provided that the following conditions are met: 16 | * 17 | * 1. Redistribution of source code must retain the above copyright notice, 18 | * this list of conditions and the following disclaimer. 19 | * 2. Redistributions in binary form must reproduce the above copyright notice, 20 | * this list of conditions and the following disclaimer in the documentation 21 | * and/or other materials provided with the distribution. 22 | * 3. Neither the name of STMicroelectronics nor the names of other 23 | * contributors to this software may be used to endorse or promote products 24 | * derived from this software without specific written permission. 25 | * 4. This software, including modifications and/or derivative works of this 26 | * software, must execute solely and exclusively on microcontroller or 27 | * microprocessor devices manufactured by or for STMicroelectronics. 28 | * 5. Redistribution and use of this software other than as permitted under 29 | * this license is void and will automatically terminate your rights under 30 | * this license. 31 | * 32 | * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" 33 | * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT 34 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 35 | * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY 36 | * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT 37 | * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 38 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 39 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 40 | * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 41 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 42 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 43 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 44 | * 45 | ****************************************************************************** 46 | */ 47 | 48 | /* Includes ------------------------------------------------------------------*/ 49 | #include "stm32f7xx_hal.h" 50 | #include "usbh_core.h" 51 | //#include "main.h" 52 | 53 | HCD_HandleTypeDef hhcd; 54 | USBH_HandleTypeDef hUSBH; 55 | 56 | /******************************************************************************* 57 | HCD BSP Routines 58 | *******************************************************************************/ 59 | /** 60 | * @brief Initializes the HCD MSP. 61 | * @param hhcd: HCD handle 62 | * @retval None 63 | */ 64 | void HAL_HCD_MspInit(HCD_HandleTypeDef *hhcd) { 65 | GPIO_InitTypeDef GPIO_InitStruct; 66 | 67 | if (hhcd->Instance == USB_OTG_FS) { 68 | /* Configure USB FS GPIOs */ 69 | __HAL_RCC_GPIOA_CLK_ENABLE(); 70 | __HAL_RCC_GPIOD_CLK_ENABLE(); 71 | 72 | GPIO_InitStruct.Pin = (GPIO_PIN_11 | GPIO_PIN_12); 73 | GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; 74 | GPIO_InitStruct.Pull = GPIO_NOPULL; 75 | GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; 76 | GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS; 77 | HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 78 | 79 | GPIO_InitStruct.Pin = GPIO_PIN_10; 80 | GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; 81 | GPIO_InitStruct.Pull = GPIO_PULLUP; 82 | GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS; 83 | HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 84 | 85 | /* Configure POWER_SWITCH IO pin */ 86 | GPIO_InitStruct.Pin = GPIO_PIN_5; 87 | GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; 88 | GPIO_InitStruct.Pull = GPIO_NOPULL; 89 | HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); 90 | 91 | /* Enable USB FS Clocks */ 92 | __HAL_RCC_USB_OTG_FS_CLK_ENABLE(); 93 | 94 | /* Set USBFS Interrupt priority */ 95 | HAL_NVIC_SetPriority(OTG_FS_IRQn, 6, 0); 96 | 97 | /* Enable USBFS Interrupt */ 98 | HAL_NVIC_EnableIRQ(OTG_FS_IRQn); 99 | } else if (hhcd->Instance == USB_OTG_HS) { 100 | /* Configure USB HS GPIOs */ 101 | __HAL_RCC_GPIOA_CLK_ENABLE(); 102 | __HAL_RCC_GPIOB_CLK_ENABLE(); 103 | __HAL_RCC_GPIOC_CLK_ENABLE(); 104 | __HAL_RCC_GPIOH_CLK_ENABLE(); 105 | 106 | /* CLK */ 107 | GPIO_InitStruct.Pin = GPIO_PIN_5; 108 | GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; 109 | GPIO_InitStruct.Pull = GPIO_NOPULL; 110 | GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; 111 | GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS; 112 | HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 113 | 114 | /* D0 */ 115 | GPIO_InitStruct.Pin = GPIO_PIN_3; 116 | GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; 117 | GPIO_InitStruct.Pull = GPIO_NOPULL; 118 | GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; 119 | GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS; 120 | HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 121 | 122 | /* D1 D2 D3 D4 D5 D6 D7 */ 123 | GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_5 | GPIO_PIN_10 | 124 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13; 125 | GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; 126 | GPIO_InitStruct.Pull = GPIO_NOPULL; 127 | GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS; 128 | HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); 129 | 130 | /* STP */ 131 | GPIO_InitStruct.Pin = GPIO_PIN_0; 132 | GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; 133 | GPIO_InitStruct.Pull = GPIO_NOPULL; 134 | GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS; 135 | HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); 136 | 137 | /* NXT */ 138 | GPIO_InitStruct.Pin = GPIO_PIN_4; 139 | GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; 140 | GPIO_InitStruct.Pull = GPIO_NOPULL; 141 | GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS; 142 | HAL_GPIO_Init(GPIOH, &GPIO_InitStruct); 143 | 144 | /* DIR */ 145 | GPIO_InitStruct.Pin = GPIO_PIN_2; 146 | GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; 147 | GPIO_InitStruct.Pull = GPIO_NOPULL; 148 | GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS; 149 | HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); 150 | 151 | __HAL_RCC_USB_OTG_HS_ULPI_CLK_ENABLE(); 152 | 153 | /* Enable USB HS Clocks */ 154 | __HAL_RCC_USB_OTG_HS_CLK_ENABLE(); 155 | 156 | /* Set USBHS Interrupt priority */ 157 | HAL_NVIC_SetPriority(OTG_HS_IRQn, 6, 0); 158 | 159 | /* Enable USBHS Interrupt */ 160 | HAL_NVIC_EnableIRQ(OTG_HS_IRQn); 161 | } 162 | } 163 | 164 | /** 165 | * @brief DeInitializes the HCD MSP. 166 | * @param hhcd: HCD handle 167 | * @retval None 168 | */ 169 | void HAL_HCD_MspDeInit(HCD_HandleTypeDef *hhcd) { 170 | if (hhcd->Instance == USB_OTG_FS) { 171 | /* Disable USB FS Clocks */ 172 | __HAL_RCC_USB_OTG_FS_CLK_DISABLE(); 173 | } else if (hhcd->Instance == USB_OTG_HS) { 174 | /* Disable USB HS Clocks */ 175 | __HAL_RCC_USB_OTG_HS_CLK_DISABLE(); 176 | __HAL_RCC_USB_OTG_HS_ULPI_CLK_DISABLE(); 177 | } 178 | } 179 | 180 | /******************************************************************************* 181 | LL Driver Callbacks (HCD -> USB Host Library) 182 | *******************************************************************************/ 183 | 184 | /** 185 | * @brief SOF callback. 186 | * @param hhcd: HCD handle 187 | * @retval None 188 | */ 189 | void HAL_HCD_SOF_Callback(HCD_HandleTypeDef *hhcd) { 190 | USBH_LL_IncTimer(hhcd->pData); 191 | } 192 | 193 | /** 194 | * @brief Connect callback. 195 | * @param hhcd: HCD handle 196 | * @retval None 197 | */ 198 | void HAL_HCD_Connect_Callback(HCD_HandleTypeDef *hhcd) { 199 | USBH_LL_Connect(hhcd->pData); 200 | } 201 | 202 | /** 203 | * @brief Disconnect callback. 204 | * @param hhcd: HCD handle 205 | * @retval None 206 | */ 207 | void HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef *hhcd) { 208 | USBH_LL_Disconnect(hhcd->pData); 209 | } 210 | 211 | /** 212 | * @brief Notify URB state change callback. 213 | * @param hhcd: HCD handle 214 | * @param chnum: Channel number 215 | * @param urb_state: URB State 216 | * @retval None 217 | */ 218 | void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd, 219 | uint8_t chnum, 220 | HCD_URBStateTypeDef urb_state) { 221 | /* To be used with OS to sync URB state with the global state machine */ 222 | } 223 | 224 | /******************************************************************************* 225 | LL Driver Interface (USB Host Library --> HCD) 226 | *******************************************************************************/ 227 | /** 228 | * @brief USBH_LL_Init 229 | * Initialize the Low Level portion of the Host driver. 230 | * @param phost: Host handle 231 | * @retval USBH Status 232 | */ 233 | USBH_StatusTypeDef USBH_LL_Init(USBH_HandleTypeDef *phost) { 234 | #ifdef USE_USB_FS 235 | /* Set the LL Driver parameters */ 236 | hhcd.Instance = USB_OTG_FS; 237 | hhcd.Init.Host_channels = 11; 238 | hhcd.Init.dma_enable = 0; 239 | hhcd.Init.low_power_enable = 0; 240 | hhcd.Init.phy_itface = HCD_PHY_EMBEDDED; 241 | hhcd.Init.Sof_enable = 0; 242 | hhcd.Init.speed = HCD_SPEED_FULL; 243 | hhcd.Init.vbus_sensing_enable = 0; 244 | hhcd.Init.lpm_enable = 0; 245 | 246 | /* Link the driver to the stack */ 247 | hhcd.pData = phost; 248 | phost->pData = &hhcd; 249 | 250 | /* Initialize the LL Driver */ 251 | HAL_HCD_Init(&hhcd); 252 | #endif 253 | 254 | #ifdef USE_USB_HS 255 | /* Set the LL driver parameters */ 256 | hhcd.Instance = USB_OTG_HS; 257 | hhcd.Init.Host_channels = 11; 258 | hhcd.Init.dma_enable = 1; 259 | hhcd.Init.low_power_enable = 0; 260 | hhcd.Init.phy_itface = HCD_PHY_ULPI; 261 | hhcd.Init.Sof_enable = 0; 262 | hhcd.Init.speed = HCD_SPEED_HIGH; 263 | hhcd.Init.vbus_sensing_enable = 0; 264 | hhcd.Init.use_external_vbus = 1; 265 | hhcd.Init.lpm_enable = 0; 266 | 267 | /* Link the driver to the stack */ 268 | hhcd.pData = phost; 269 | phost->pData = &hhcd; 270 | 271 | /* Initialize the LL driver */ 272 | HAL_HCD_Init(&hhcd); 273 | 274 | #endif /*USE_USB_HS*/ 275 | USBH_LL_SetTimer(phost, HAL_HCD_GetCurrentFrame(&hhcd)); 276 | 277 | return USBH_OK; 278 | } 279 | 280 | /** 281 | * @brief De-Initializes the Low Level portion of the Host driver. 282 | * @param phost: Host handle 283 | * @retval USBH Status 284 | */ 285 | USBH_StatusTypeDef USBH_LL_DeInit(USBH_HandleTypeDef *phost) { 286 | HAL_HCD_DeInit(phost->pData); 287 | return USBH_OK; 288 | } 289 | 290 | /** 291 | * @brief Starts the Low Level portion of the Host driver. 292 | * @param phost: Host handle 293 | * @retval USBH Status 294 | */ 295 | USBH_StatusTypeDef USBH_LL_Start(USBH_HandleTypeDef *phost) { 296 | HAL_HCD_Start(phost->pData); 297 | return USBH_OK; 298 | } 299 | 300 | /** 301 | * @brief Stops the Low Level portion of the Host driver. 302 | * @param phost: Host handle 303 | * @retval USBH Status 304 | */ 305 | USBH_StatusTypeDef USBH_LL_Stop(USBH_HandleTypeDef *phost) { 306 | HAL_HCD_Stop(phost->pData); 307 | return USBH_OK; 308 | } 309 | 310 | /** 311 | * @brief Returns the USB Host Speed from the Low Level Driver. 312 | * @param phost: Host handle 313 | * @retval USBH Speeds 314 | */ 315 | USBH_SpeedTypeDef USBH_LL_GetSpeed(USBH_HandleTypeDef *phost) { 316 | USBH_SpeedTypeDef speed = USBH_SPEED_FULL; 317 | 318 | switch (HAL_HCD_GetCurrentSpeed(phost->pData)) { 319 | case 0: 320 | speed = USBH_SPEED_HIGH; 321 | break; 322 | 323 | case 1: 324 | speed = USBH_SPEED_FULL; 325 | break; 326 | 327 | case 2: 328 | speed = USBH_SPEED_LOW; 329 | break; 330 | 331 | default: 332 | speed = USBH_SPEED_FULL; 333 | break; 334 | } 335 | return speed; 336 | } 337 | 338 | /** 339 | * @brief Resets the Host Port of the Low Level Driver. 340 | * @param phost: Host handle 341 | * @retval USBH Status 342 | */ 343 | USBH_StatusTypeDef USBH_LL_ResetPort(USBH_HandleTypeDef *phost) { 344 | HAL_HCD_ResetPort(phost->pData); 345 | return USBH_OK; 346 | } 347 | 348 | /** 349 | * @brief Returns the last transferred packet size. 350 | * @param phost: Host handle 351 | * @param pipe: Pipe index 352 | * @retval Packet Size 353 | */ 354 | uint32_t USBH_LL_GetLastXferSize(USBH_HandleTypeDef *phost, uint8_t pipe) { 355 | return HAL_HCD_HC_GetXferCount(phost->pData, pipe); 356 | } 357 | 358 | /** 359 | * @brief Opens a pipe of the Low Level Driver. 360 | * @param phost: Host handle 361 | * @param pipe: Pipe index 362 | * @param epnum: Endpoint Number 363 | * @param dev_address: Device USB address 364 | * @param speed: Device Speed 365 | * @param ep_type: Endpoint Type 366 | * @param mps: Endpoint Max Packet Size 367 | * @retval USBH Status 368 | */ 369 | USBH_StatusTypeDef USBH_LL_OpenPipe(USBH_HandleTypeDef *phost, 370 | uint8_t pipe, 371 | uint8_t epnum, 372 | uint8_t dev_address, 373 | uint8_t speed, 374 | uint8_t ep_type, 375 | uint16_t mps) { 376 | HAL_HCD_HC_Init(phost->pData, pipe, epnum, dev_address, speed, ep_type, mps); 377 | return USBH_OK; 378 | } 379 | 380 | /** 381 | * @brief Closes a pipe of the Low Level Driver. 382 | * @param phost: Host handle 383 | * @param pipe: Pipe index 384 | * @retval USBH Status 385 | */ 386 | USBH_StatusTypeDef USBH_LL_ClosePipe(USBH_HandleTypeDef *phost, uint8_t pipe) { 387 | HAL_HCD_HC_Halt(phost->pData, pipe); 388 | return USBH_OK; 389 | } 390 | 391 | /** 392 | * @brief Submits a new URB to the low level driver. 393 | * @param phost: Host handle 394 | * @param pipe: Pipe index 395 | * This parameter can be a value from 1 to 15 396 | * @param direction: Channel number 397 | * This parameter can be one of these values: 398 | * 0: Output 399 | * 1: Input 400 | * @param ep_type: Endpoint Type 401 | * This parameter can be one of these values: 402 | * @arg EP_TYPE_CTRL: Control type 403 | * @arg EP_TYPE_ISOC: Isochronous type 404 | * @arg EP_TYPE_BULK: Bulk type 405 | * @arg EP_TYPE_INTR: Interrupt type 406 | * @param token: Endpoint Type 407 | * This parameter can be one of these values: 408 | * @arg 0: PID_SETUP 409 | * @arg 1: PID_DATA 410 | * @param pbuff: pointer to URB data 411 | * @param length: length of URB data 412 | * @param do_ping: activate do ping protocol (for high speed only) 413 | * This parameter can be one of these values: 414 | * 0: do ping inactive 415 | * 1: do ping active 416 | * @retval USBH Status 417 | */ 418 | USBH_StatusTypeDef USBH_LL_SubmitURB(USBH_HandleTypeDef *phost, 419 | uint8_t pipe, 420 | uint8_t direction, 421 | uint8_t ep_type, 422 | uint8_t token, 423 | uint8_t *pbuff, 424 | uint16_t length, 425 | uint8_t do_ping) { 426 | HAL_HCD_HC_SubmitRequest(phost->pData, pipe, direction, ep_type, token, pbuff, 427 | length, do_ping); 428 | return USBH_OK; 429 | } 430 | 431 | /** 432 | * @brief Gets a URB state from the low level driver. 433 | * @param phost: Host handle 434 | * @param pipe: Pipe index 435 | * This parameter can be a value from 1 to 15 436 | * @retval URB state 437 | * This parameter can be one of these values: 438 | * @arg URB_IDLE 439 | * @arg URB_DONE 440 | * @arg URB_NOTREADY 441 | * @arg URB_NYET 442 | * @arg URB_ERROR 443 | * @arg URB_STALL 444 | */ 445 | USBH_URBStateTypeDef USBH_LL_GetURBState(USBH_HandleTypeDef *phost, 446 | uint8_t pipe) { 447 | return (USBH_URBStateTypeDef)HAL_HCD_HC_GetURBState(phost->pData, pipe); 448 | } 449 | 450 | /** 451 | * @brief Drives VBUS. 452 | * @param phost: Host handle 453 | * @param state: VBUS state 454 | * This parameter can be one of these values: 455 | * 0: VBUS Active 456 | * 1: VBUS Inactive 457 | * @retval USBH Status 458 | */ 459 | USBH_StatusTypeDef USBH_LL_DriverVBUS(USBH_HandleTypeDef *phost, 460 | uint8_t state) { 461 | #ifdef USE_USB_FS 462 | if (state == 0) { 463 | HAL_GPIO_WritePin(GPIOD, GPIO_PIN_5, GPIO_PIN_SET); 464 | } else { 465 | HAL_GPIO_WritePin(GPIOD, GPIO_PIN_5, GPIO_PIN_RESET); 466 | } 467 | 468 | HAL_Delay(200); 469 | #endif /* USE_USB_FS */ 470 | return USBH_OK; 471 | } 472 | 473 | /** 474 | * @brief Sets toggle for a pipe. 475 | * @param phost: Host handle 476 | * @param pipe: Pipe index 477 | * @param toggle: toggle (0/1) 478 | * @retval USBH Status 479 | */ 480 | USBH_StatusTypeDef USBH_LL_SetToggle(USBH_HandleTypeDef *phost, 481 | uint8_t pipe, 482 | uint8_t toggle) { 483 | if (hhcd.hc[pipe].ep_is_in) { 484 | hhcd.hc[pipe].toggle_in = toggle; 485 | } else { 486 | hhcd.hc[pipe].toggle_out = toggle; 487 | } 488 | return USBH_OK; 489 | } 490 | 491 | /** 492 | * @brief Returns the current toggle of a pipe. 493 | * @param phost: Host handle 494 | * @param pipe: Pipe index 495 | * @retval toggle (0/1) 496 | */ 497 | uint8_t USBH_LL_GetToggle(USBH_HandleTypeDef *phost, uint8_t pipe) { 498 | uint8_t toggle = 0; 499 | 500 | if (hhcd.hc[pipe].ep_is_in) { 501 | toggle = hhcd.hc[pipe].toggle_in; 502 | } else { 503 | toggle = hhcd.hc[pipe].toggle_out; 504 | } 505 | return toggle; 506 | } 507 | 508 | /** 509 | * @brief Delay routine for the USB Host Library 510 | * @param Delay: Delay in ms 511 | * @retval None 512 | */ 513 | void USBH_Delay(uint32_t Delay) { 514 | #if (USBH_USE_OS == 1) 515 | osDelay(Delay); 516 | #else 517 | HAL_Delay(Delay); 518 | #endif 519 | } 520 | 521 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 522 | -------------------------------------------------------------------------------- /src/ex08/usbh_conf.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include "stm32f7xx.h" 7 | 8 | #define USBH_MAX_NUM_ENDPOINTS 2 9 | #define USBH_MAX_NUM_INTERFACES 2 10 | #define USBH_MAX_NUM_CONFIGURATION 1 11 | #define USBH_MAX_NUM_SUPPORTED_CLASS 1 12 | #define USBH_KEEP_CFG_DESCRIPTOR 1 13 | #define USBH_MAX_SIZE_CONFIGURATION 0x200 14 | #define USBH_MAX_DATA_BUFFER 0x200 15 | #define USBH_DEBUG_LEVEL 0 16 | #define USBH_USE_OS 0 17 | #define USE_USB_FS 0 18 | 19 | /* CMSIS OS macros */ 20 | #if (USBH_USE_OS == 1) 21 | #include "cmsis_os.h" 22 | #define USBH_PROCESS_PRIO osPriorityNormal 23 | #endif 24 | 25 | /* Memory management macros */ 26 | #define USBH_malloc malloc 27 | #define USBH_free free 28 | #define USBH_memset memset 29 | #define USBH_memcpy memcpy 30 | 31 | /* DEBUG macros */ 32 | 33 | #if (USBH_DEBUG_LEVEL > 0) 34 | #define USBH_UsrLog(...) \ 35 | printf(__VA_ARGS__); \ 36 | printf("\n"); 37 | #else 38 | #define USBH_UsrLog(...) 39 | #endif 40 | 41 | #if (USBH_DEBUG_LEVEL > 1) 42 | 43 | #define USBH_ErrLog(...) \ 44 | printf("ERROR: "); \ 45 | printf(__VA_ARGS__); \ 46 | printf("\n"); 47 | #else 48 | #define USBH_ErrLog(...) 49 | #endif 50 | 51 | #if (USBH_DEBUG_LEVEL > 2) 52 | #define USBH_DbgLog(...) \ 53 | printf("DEBUG : "); \ 54 | printf(__VA_ARGS__); \ 55 | printf("\n"); 56 | #else 57 | #define USBH_DbgLog(...) 58 | #endif 59 | -------------------------------------------------------------------------------- /src/stm32f7xx_hal_conf.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file stm32f7xx_hal_conf.h 4 | * @author MCD Application Team 5 | * @version V1.0.3 6 | * @date 22-April-2016 7 | * @brief HAL configuration file. 8 | ****************************************************************************** 9 | * @attention 10 | * 11 | *

© COPYRIGHT(c) 2016 STMicroelectronics

12 | * 13 | * Redistribution and use in source and binary forms, with or without modification, 14 | * are permitted provided that the following conditions are met: 15 | * 1. Redistributions of source code must retain the above copyright notice, 16 | * this list of conditions and the following disclaimer. 17 | * 2. Redistributions in binary form must reproduce the above copyright notice, 18 | * this list of conditions and the following disclaimer in the documentation 19 | * and/or other materials provided with the distribution. 20 | * 3. Neither the name of STMicroelectronics nor the names of its contributors 21 | * may be used to endorse or promote products derived from this software 22 | * without specific prior written permission. 23 | * 24 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 25 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 27 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 28 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 30 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 31 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 32 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 33 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | * 35 | ****************************************************************************** 36 | */ 37 | 38 | /* Define to prevent recursive inclusion -------------------------------------*/ 39 | #ifndef __STM32F7xx_HAL_CONF_H 40 | #define __STM32F7xx_HAL_CONF_H 41 | 42 | #ifdef __cplusplus 43 | extern "C" { 44 | #endif 45 | 46 | /* Exported types ------------------------------------------------------------*/ 47 | /* Exported constants --------------------------------------------------------*/ 48 | 49 | /* ########################## Module Selection ############################## */ 50 | /** 51 | * @brief This is the list of modules to be used in the HAL driver 52 | */ 53 | #define HAL_MODULE_ENABLED 54 | /* #define HAL_ADC_MODULE_ENABLED */ 55 | /* #define HAL_CAN_MODULE_ENABLED */ 56 | /* #define HAL_CEC_MODULE_ENABLED */ 57 | /* #define HAL_CRC_MODULE_ENABLED */ 58 | /* #define HAL_CRYP_MODULE_ENABLED */ 59 | /* #define HAL_DAC_MODULE_ENABLED */ 60 | /* #define HAL_DCMI_MODULE_ENABLED */ 61 | #define HAL_DMA_MODULE_ENABLED 62 | #define HAL_DMA2D_MODULE_ENABLED 63 | /* #define HAL_ETH_MODULE_ENABLED */ 64 | #define HAL_FLASH_MODULE_ENABLED 65 | /* #define HAL_NAND_MODULE_ENABLED */ 66 | /* #define HAL_NOR_MODULE_ENABLED */ 67 | #define HAL_SRAM_MODULE_ENABLED 68 | #define HAL_SDRAM_MODULE_ENABLED 69 | /* #define HAL_HASH_MODULE_ENABLED */ 70 | #define HAL_GPIO_MODULE_ENABLED 71 | #define HAL_I2C_MODULE_ENABLED 72 | #define HAL_I2S_MODULE_ENABLED 73 | /* #define HAL_IWDG_MODULE_ENABLED */ 74 | /* #define HAL_LPTIM_MODULE_ENABLED */ 75 | #define HAL_LTDC_MODULE_ENABLED 76 | #define HAL_PWR_MODULE_ENABLED 77 | /* #define HAL_QSPI_MODULE_ENABLED */ 78 | #define HAL_RCC_MODULE_ENABLED 79 | #define HAL_RNG_MODULE_ENABLED 80 | /* #define HAL_RTC_MODULE_ENABLED */ 81 | #define HAL_SAI_MODULE_ENABLED 82 | /* #define HAL_SD_MODULE_ENABLED */ 83 | /* #define HAL_SPDIFRX_MODULE_ENABLED */ 84 | /* #define HAL_SPI_MODULE_ENABLED */ 85 | #define HAL_TIM_MODULE_ENABLED 86 | #define HAL_UART_MODULE_ENABLED 87 | #define HAL_USART_MODULE_ENABLED 88 | /* #define HAL_IRDA_MODULE_ENABLED */ 89 | /* #define HAL_SMARTCARD_MODULE_ENABLED */ 90 | /* #define HAL_WWDG_MODULE_ENABLED */ 91 | #define HAL_CORTEX_MODULE_ENABLED 92 | /* #define HAL_PCD_MODULE_ENABLED */ 93 | #define HAL_HCD_MODULE_ENABLED 94 | 95 | /* ########################## HSE/HSI Values adaptation ##################### */ 96 | /** 97 | * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. 98 | * This value is used by the RCC HAL module to compute the system frequency 99 | * (when HSE is used as system clock source, directly or through the PLL). 100 | */ 101 | #if !defined(HSE_VALUE) 102 | #define HSE_VALUE \ 103 | ((uint32_t)25000000U) /*!< Value of the External oscillator in Hz */ 104 | #endif /* HSE_VALUE */ 105 | 106 | #if !defined(HSE_STARTUP_TIMEOUT) 107 | #define HSE_STARTUP_TIMEOUT \ 108 | ((uint32_t)100U) /*!< Time out for HSE start up, in ms */ 109 | #endif /* HSE_STARTUP_TIMEOUT */ 110 | 111 | /** 112 | * @brief Internal High Speed oscillator (HSI) value. 113 | * This value is used by the RCC HAL module to compute the system frequency 114 | * (when HSI is used as system clock source, directly or through the PLL). 115 | */ 116 | #if !defined(HSI_VALUE) 117 | #define HSI_VALUE \ 118 | ((uint32_t)16000000U) /*!< Value of the Internal oscillator in Hz*/ 119 | #endif /* HSI_VALUE */ 120 | 121 | /** 122 | * @brief Internal Low Speed oscillator (LSI) value. 123 | */ 124 | #if !defined(LSI_VALUE) 125 | #define LSI_VALUE ((uint32_t)32000U) /*!< LSI Typical Value in Hz*/ 126 | #endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz 127 | The real value may vary depending on the variations 128 | in voltage and temperature. */ 129 | /** 130 | * @brief External Low Speed oscillator (LSE) value. 131 | */ 132 | #if !defined(LSE_VALUE) 133 | #define LSE_VALUE \ 134 | ((uint32_t)32768U) /*!< Value of the External Low Speed oscillator in Hz */ 135 | #endif /* LSE_VALUE */ 136 | 137 | #if !defined(LSE_STARTUP_TIMEOUT) 138 | #define LSE_STARTUP_TIMEOUT \ 139 | ((uint32_t)5000U) /*!< Time out for LSE start up, in ms */ 140 | #endif /* LSE_STARTUP_TIMEOUT */ 141 | 142 | /** 143 | * @brief External clock source for I2S peripheral 144 | * This value is used by the I2S HAL module to compute the I2S clock source 145 | * frequency, this source is inserted directly through I2S_CKIN pad. 146 | */ 147 | #if !defined(EXTERNAL_CLOCK_VALUE) 148 | #define EXTERNAL_CLOCK_VALUE \ 149 | ((uint32_t)12288000U) /*!< Value of the Internal oscillator in Hz*/ 150 | #endif /* EXTERNAL_CLOCK_VALUE */ 151 | 152 | /* Tip: To avoid modifying this file each time you need to use different HSE, 153 | === you can define the HSE value in your toolchain compiler preprocessor. */ 154 | 155 | /* ########################### System Configuration ######################### */ 156 | /** 157 | * @brief This is the HAL system configuration section 158 | */ 159 | #define VDD_VALUE ((uint32_t)3300U) /*!< Value of VDD in mv */ 160 | #define TICK_INT_PRIORITY ((uint32_t)0x0FU) /*!< tick interrupt priority */ 161 | #define USE_RTOS 0U 162 | #define PREFETCH_ENABLE 1U 163 | #define ART_ACCLERATOR_ENABLE 1U /* To enable instruction cache and prefetch */ 164 | 165 | /* ########################## Assert Selection ############################## */ 166 | /** 167 | * @brief Uncomment the line below to expanse the "assert_param" macro in the 168 | * HAL drivers code 169 | */ 170 | /* #define USE_FULL_ASSERT 1 */ 171 | 172 | /* ################## Ethernet peripheral configuration ##################### */ 173 | 174 | /* Section 1 : Ethernet peripheral configuration */ 175 | 176 | /* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */ 177 | #define MAC_ADDR0 2U 178 | #define MAC_ADDR1 0U 179 | #define MAC_ADDR2 0U 180 | #define MAC_ADDR3 0U 181 | #define MAC_ADDR4 0U 182 | #define MAC_ADDR5 0U 183 | 184 | /* Definition of the Ethernet driver buffers size and count */ 185 | #define ETH_RX_BUF_SIZE \ 186 | ETH_MAX_PACKET_SIZE /* buffer size for receive */ 187 | #define ETH_TX_BUF_SIZE \ 188 | ETH_MAX_PACKET_SIZE /* buffer size for transmit */ 189 | #define ETH_RXBUFNB ((uint32_t)5U) /* 5 Rx buffers of size ETH_RX_BUF_SIZE */ 190 | #define ETH_TXBUFNB ((uint32_t)5U) /* 5 Tx buffers of size ETH_TX_BUF_SIZE */ 191 | 192 | /* Section 2: PHY configuration section */ 193 | /* LAN8742A PHY Address*/ 194 | #define LAN8742A_PHY_ADDRESS 0x00U 195 | /* PHY Reset delay these values are based on a 1 ms Systick interrupt*/ 196 | #define PHY_RESET_DELAY ((uint32_t)0x00000FFFU) 197 | /* PHY Configuration delay */ 198 | #define PHY_CONFIG_DELAY ((uint32_t)0x00000FFFU) 199 | 200 | #define PHY_READ_TO ((uint32_t)0x0000FFFFU) 201 | #define PHY_WRITE_TO ((uint32_t)0x0000FFFFU) 202 | 203 | /* Section 3: Common PHY Registers */ 204 | 205 | #define PHY_BCR ((uint16_t)0x00U) /*!< Transceiver Basic Control Register */ 206 | #define PHY_BSR ((uint16_t)0x01U) /*!< Transceiver Basic Status Register */ 207 | 208 | #define PHY_RESET ((uint16_t)0x8000U) /*!< PHY Reset */ 209 | #define PHY_LOOPBACK ((uint16_t)0x4000U) /*!< Select loop-back mode */ 210 | #define PHY_FULLDUPLEX_100M \ 211 | ((uint16_t)0x2100U) /*!< Set the full-duplex mode at 100 Mb/s */ 212 | #define PHY_HALFDUPLEX_100M \ 213 | ((uint16_t)0x2000U) /*!< Set the half-duplex mode at 100 Mb/s */ 214 | #define PHY_FULLDUPLEX_10M \ 215 | ((uint16_t)0x0100U) /*!< Set the full-duplex mode at 10 Mb/s */ 216 | #define PHY_HALFDUPLEX_10M \ 217 | ((uint16_t)0x0000U) /*!< Set the half-duplex mode at 10 Mb/s */ 218 | #define PHY_AUTONEGOTIATION \ 219 | ((uint16_t)0x1000U) /*!< Enable auto-negotiation function */ 220 | #define PHY_RESTART_AUTONEGOTIATION \ 221 | ((uint16_t)0x0200U) /*!< Restart auto-negotiation function */ 222 | #define PHY_POWERDOWN \ 223 | ((uint16_t)0x0800U) /*!< Select the power down mode */ 224 | #define PHY_ISOLATE \ 225 | ((uint16_t)0x0400U) /*!< Isolate PHY from MII */ 226 | 227 | #define PHY_AUTONEGO_COMPLETE \ 228 | ((uint16_t)0x0020U) /*!< Auto-Negotiation process completed */ 229 | #define PHY_LINKED_STATUS \ 230 | ((uint16_t)0x0004U) /*!< Valid link established */ 231 | #define PHY_JABBER_DETECTION \ 232 | ((uint16_t)0x0002U) /*!< Jabber condition detected */ 233 | 234 | /* Section 4: Extended PHY Registers */ 235 | 236 | #define PHY_SR \ 237 | ((uint16_t)0x1FU) /*!< PHY special control/ status register Offset */ 238 | 239 | #define PHY_SPEED_STATUS \ 240 | ((uint16_t)0x0004U) /*!< PHY Speed mask */ 241 | #define PHY_DUPLEX_STATUS \ 242 | ((uint16_t)0x0010U) /*!< PHY Duplex mask */ 243 | 244 | #define PHY_ISFR \ 245 | ((uint16_t)0x1DU) /*!< PHY Interrupt Source Flag register Offset */ 246 | #define PHY_ISFR_INT4 \ 247 | ((uint16_t)0x0010U) /*!< PHY Link down inturrupt */ 248 | 249 | /* ################## SPI peripheral configuration ########################## */ 250 | 251 | /* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver 252 | * Activated: CRC code is present inside driver 253 | * Deactivated: CRC code cleaned from driver 254 | */ 255 | 256 | #define USE_SPI_CRC 1U 257 | 258 | /* Includes ------------------------------------------------------------------*/ 259 | /** 260 | * @brief Include module's header file 261 | */ 262 | 263 | #ifdef HAL_RCC_MODULE_ENABLED 264 | #include "stm32f7xx_hal_rcc.h" 265 | #endif /* HAL_RCC_MODULE_ENABLED */ 266 | 267 | #ifdef HAL_GPIO_MODULE_ENABLED 268 | #include "stm32f7xx_hal_gpio.h" 269 | #endif /* HAL_GPIO_MODULE_ENABLED */ 270 | 271 | #ifdef HAL_DMA_MODULE_ENABLED 272 | #include "stm32f7xx_hal_dma.h" 273 | #endif /* HAL_DMA_MODULE_ENABLED */ 274 | 275 | #ifdef HAL_CORTEX_MODULE_ENABLED 276 | #include "stm32f7xx_hal_cortex.h" 277 | #endif /* HAL_CORTEX_MODULE_ENABLED */ 278 | 279 | #ifdef HAL_ADC_MODULE_ENABLED 280 | #include "stm32f7xx_hal_adc.h" 281 | #endif /* HAL_ADC_MODULE_ENABLED */ 282 | 283 | #ifdef HAL_CAN_MODULE_ENABLED 284 | #include "stm32f7xx_hal_can.h" 285 | #endif /* HAL_CAN_MODULE_ENABLED */ 286 | 287 | #ifdef HAL_CEC_MODULE_ENABLED 288 | #include "stm32f7xx_hal_cec.h" 289 | #endif /* HAL_CEC_MODULE_ENABLED */ 290 | 291 | #ifdef HAL_CRC_MODULE_ENABLED 292 | #include "stm32f7xx_hal_crc.h" 293 | #endif /* HAL_CRC_MODULE_ENABLED */ 294 | 295 | #ifdef HAL_CRYP_MODULE_ENABLED 296 | #include "stm32f7xx_hal_cryp.h" 297 | #endif /* HAL_CRYP_MODULE_ENABLED */ 298 | 299 | #ifdef HAL_DMA2D_MODULE_ENABLED 300 | #include "stm32f7xx_hal_dma2d.h" 301 | #endif /* HAL_DMA2D_MODULE_ENABLED */ 302 | 303 | #ifdef HAL_DAC_MODULE_ENABLED 304 | #include "stm32f7xx_hal_dac.h" 305 | #endif /* HAL_DAC_MODULE_ENABLED */ 306 | 307 | #ifdef HAL_DCMI_MODULE_ENABLED 308 | #include "stm32f7xx_hal_dcmi.h" 309 | #endif /* HAL_DCMI_MODULE_ENABLED */ 310 | 311 | #ifdef HAL_ETH_MODULE_ENABLED 312 | #include "stm32f7xx_hal_eth.h" 313 | #endif /* HAL_ETH_MODULE_ENABLED */ 314 | 315 | #ifdef HAL_FLASH_MODULE_ENABLED 316 | #include "stm32f7xx_hal_flash.h" 317 | #endif /* HAL_FLASH_MODULE_ENABLED */ 318 | 319 | #ifdef HAL_SRAM_MODULE_ENABLED 320 | #include "stm32f7xx_hal_sram.h" 321 | #endif /* HAL_SRAM_MODULE_ENABLED */ 322 | 323 | #ifdef HAL_NOR_MODULE_ENABLED 324 | #include "stm32f7xx_hal_nor.h" 325 | #endif /* HAL_NOR_MODULE_ENABLED */ 326 | 327 | #ifdef HAL_NAND_MODULE_ENABLED 328 | #include "stm32f7xx_hal_nand.h" 329 | #endif /* HAL_NAND_MODULE_ENABLED */ 330 | 331 | #ifdef HAL_SDRAM_MODULE_ENABLED 332 | #include "stm32f7xx_hal_sdram.h" 333 | #endif /* HAL_SDRAM_MODULE_ENABLED */ 334 | 335 | #ifdef HAL_HASH_MODULE_ENABLED 336 | #include "stm32f7xx_hal_hash.h" 337 | #endif /* HAL_HASH_MODULE_ENABLED */ 338 | 339 | #ifdef HAL_I2C_MODULE_ENABLED 340 | #include "stm32f7xx_hal_i2c.h" 341 | #endif /* HAL_I2C_MODULE_ENABLED */ 342 | 343 | #ifdef HAL_I2S_MODULE_ENABLED 344 | #include "stm32f7xx_hal_i2s.h" 345 | #endif /* HAL_I2S_MODULE_ENABLED */ 346 | 347 | #ifdef HAL_IWDG_MODULE_ENABLED 348 | #include "stm32f7xx_hal_iwdg.h" 349 | #endif /* HAL_IWDG_MODULE_ENABLED */ 350 | 351 | #ifdef HAL_LPTIM_MODULE_ENABLED 352 | #include "stm32f7xx_hal_lptim.h" 353 | #endif /* HAL_LPTIM_MODULE_ENABLED */ 354 | 355 | #ifdef HAL_LTDC_MODULE_ENABLED 356 | #include "stm32f7xx_hal_ltdc.h" 357 | #endif /* HAL_LTDC_MODULE_ENABLED */ 358 | 359 | #ifdef HAL_PWR_MODULE_ENABLED 360 | #include "stm32f7xx_hal_pwr.h" 361 | #endif /* HAL_PWR_MODULE_ENABLED */ 362 | 363 | #ifdef HAL_QSPI_MODULE_ENABLED 364 | #include "stm32f7xx_hal_qspi.h" 365 | #endif /* HAL_QSPI_MODULE_ENABLED */ 366 | 367 | #ifdef HAL_RNG_MODULE_ENABLED 368 | #include "stm32f7xx_hal_rng.h" 369 | #endif /* HAL_RNG_MODULE_ENABLED */ 370 | 371 | #ifdef HAL_RTC_MODULE_ENABLED 372 | #include "stm32f7xx_hal_rtc.h" 373 | #endif /* HAL_RTC_MODULE_ENABLED */ 374 | 375 | #ifdef HAL_SAI_MODULE_ENABLED 376 | #include "stm32f7xx_hal_sai.h" 377 | #endif /* HAL_SAI_MODULE_ENABLED */ 378 | 379 | #ifdef HAL_SD_MODULE_ENABLED 380 | #include "stm32f7xx_hal_sd.h" 381 | #endif /* HAL_SD_MODULE_ENABLED */ 382 | 383 | #ifdef HAL_SPDIFRX_MODULE_ENABLED 384 | #include "stm32f7xx_hal_spdifrx.h" 385 | #endif /* HAL_SPDIFRX_MODULE_ENABLED */ 386 | 387 | #ifdef HAL_SPI_MODULE_ENABLED 388 | #include "stm32f7xx_hal_spi.h" 389 | #endif /* HAL_SPI_MODULE_ENABLED */ 390 | 391 | #ifdef HAL_TIM_MODULE_ENABLED 392 | #include "stm32f7xx_hal_tim.h" 393 | #endif /* HAL_TIM_MODULE_ENABLED */ 394 | 395 | #ifdef HAL_UART_MODULE_ENABLED 396 | #include "stm32f7xx_hal_uart.h" 397 | #endif /* HAL_UART_MODULE_ENABLED */ 398 | 399 | #ifdef HAL_USART_MODULE_ENABLED 400 | #include "stm32f7xx_hal_usart.h" 401 | #endif /* HAL_USART_MODULE_ENABLED */ 402 | 403 | #ifdef HAL_IRDA_MODULE_ENABLED 404 | #include "stm32f7xx_hal_irda.h" 405 | #endif /* HAL_IRDA_MODULE_ENABLED */ 406 | 407 | #ifdef HAL_SMARTCARD_MODULE_ENABLED 408 | #include "stm32f7xx_hal_smartcard.h" 409 | #endif /* HAL_SMARTCARD_MODULE_ENABLED */ 410 | 411 | #ifdef HAL_WWDG_MODULE_ENABLED 412 | #include "stm32f7xx_hal_wwdg.h" 413 | #endif /* HAL_WWDG_MODULE_ENABLED */ 414 | 415 | #ifdef HAL_PCD_MODULE_ENABLED 416 | #include "stm32f7xx_hal_pcd.h" 417 | #endif /* HAL_PCD_MODULE_ENABLED */ 418 | 419 | #ifdef HAL_HCD_MODULE_ENABLED 420 | #include "stm32f7xx_hal_hcd.h" 421 | #endif /* HAL_HCD_MODULE_ENABLED */ 422 | 423 | /* Exported macro ------------------------------------------------------------*/ 424 | #ifdef USE_FULL_ASSERT 425 | /** 426 | * @brief The assert_param macro is used for function's parameters check. 427 | * @param expr: If expr is false, it calls assert_failed function 428 | * which reports the name of the source file and the source 429 | * line number of the call that failed. 430 | * If expr is true, it returns no value. 431 | * @retval None 432 | */ 433 | #define assert_param(expr) \ 434 | ((expr) ? (void)0 : assert_failed((uint8_t*)__FILE__, __LINE__)) 435 | /* Exported functions ------------------------------------------------------- */ 436 | void assert_failed(uint8_t* file, uint32_t line); 437 | #else 438 | #define assert_param(expr) ((void)0) 439 | #endif /* USE_FULL_ASSERT */ 440 | 441 | #ifdef __cplusplus 442 | } 443 | #endif 444 | 445 | #endif /* __STM32F7xx_HAL_CONF_H */ 446 | 447 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 448 | -------------------------------------------------------------------------------- /src/synth_extras/midi_log.c: -------------------------------------------------------------------------------- 1 | #include "midi_log.h" 2 | 3 | #ifdef LOG_MIDI 4 | 5 | static char *midi_msg_types[] = {"OFF", "ON", "PP", "CC", 6 | "PC", "AT", "PB", "SYSEX"}; 7 | 8 | void init_midi_log() { 9 | BSP_LCD_Init(); 10 | BSP_LCD_LayerDefaultInit(LTDC_ACTIVE_LAYER, SDRAM_DEVICE_ADDR); 11 | BSP_LCD_SelectLayer(LTDC_ACTIVE_LAYER); 12 | BSP_LCD_SetFont(&Font12); 13 | BSP_LCD_SetBackColor(LCD_COLOR_BLUE); 14 | BSP_LCD_Clear(LCD_COLOR_BLUE); 15 | BSP_LCD_SetTextColor(LCD_COLOR_WHITE); 16 | } 17 | 18 | void log_to_lcd(const char *msg) { 19 | static uint16_t curr_line = 0; 20 | BSP_LCD_ClearStringLine(curr_line + 1); 21 | BSP_LCD_DisplayStringAtLine(curr_line, (uint8_t *)msg); 22 | curr_line = (curr_line + 1) % 20; 23 | } 24 | 25 | void log_midi_packet(const midi_package_t *packet) { 26 | static char buf[64]; 27 | snprintf(buf, 64, "%s: c:%u e:%u v:%u/%u ", 28 | midi_msg_types[packet->type - 8], packet->chn, packet->event, 29 | packet->value1, packet->value2); 30 | log_to_lcd(buf); 31 | } 32 | 33 | #else 34 | 35 | void init_midi_log() { 36 | } 37 | void log_to_lcd(const char* msg) { 38 | } 39 | void log_midi_packet(const midi_package_t* packet) { 40 | } 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /src/synth_extras/midi_log.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "stm32746g_discovery_lcd.h" 4 | #include "usbh_MIDI.h" 5 | 6 | void init_midi_log(); 7 | void log_to_lcd(const char* msg); 8 | void log_midi_packet(const midi_package_t* packet); 9 | -------------------------------------------------------------------------------- /src/synth_extras/osc_noise.c: -------------------------------------------------------------------------------- 1 | #include "osc_noise.h" 2 | #include "ct-head/random.h" 3 | 4 | static CT_XorShift rnd; 5 | 6 | void ctss_osc_noise_init() { 7 | ct_xors_init(&rnd); 8 | } 9 | 10 | uint8_t ctss_process_osc_noise(CTSS_DSPNode *node, 11 | CTSS_DSPStack *stack, 12 | CTSS_Synth *synth) { 13 | CTSS_UNUSED(synth); 14 | CTSS_UNUSED(stack); 15 | CTSS_OscState *state = node->state; 16 | float *buf = node->buf; 17 | size_t len = AUDIO_BUFFER_SIZE; 18 | while (len--) { 19 | *buf++ = (state->gain * ct_xors_norm(&rnd)) + state->dcOffset; 20 | } 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /src/synth_extras/osc_noise.h: -------------------------------------------------------------------------------- 1 | #include "osc.h" 2 | 3 | void ctss_osc_noise_init(); 4 | uint8_t ctss_process_osc_noise(CTSS_DSPNode *node, 5 | CTSS_DSPStack *stack, 6 | CTSS_Synth *synth); 7 | -------------------------------------------------------------------------------- /src/synth_extras/sdram_delay.c: -------------------------------------------------------------------------------- 1 | #include "sdram_delay.h" 2 | #include "delay.h" 3 | 4 | static float delay_cache_r[AUDIO_BUFFER_SIZE * 2]; 5 | static float delay_cache_w[AUDIO_BUFFER_SIZE * 2]; 6 | 7 | CTSS_DSPNode *ctss_delay_sdram(char *id, 8 | CTSS_DSPNode *src, 9 | uint32_t len, 10 | float feedback, 11 | uint8_t channels) { 12 | CTSS_DSPNode *node = ctss_node(id, channels); 13 | CTSS_DelayState *state = malloc(sizeof(CTSS_DelayState)); 14 | state->delayLine = ct_sdram_calloc(len * channels, sizeof(float)); 15 | state->src = src->buf; 16 | state->len = len * channels; 17 | state->feedback = feedback; 18 | state->channels = channels; 19 | state->writePos = 0; 20 | state->readPos = channels; 21 | state->writePtr = state->delayLine; 22 | state->readPtr = state->delayLine + channels; 23 | node->state = state; 24 | node->handler = ctss_process_delay_sdram; 25 | return node; 26 | } 27 | 28 | uint8_t ctss_process_delay_sdram(CTSS_DSPNode *node, 29 | CTSS_DSPStack *stack, 30 | CTSS_Synth *synth) { 31 | CTSS_UNUSED(synth); 32 | CTSS_UNUSED(stack); 33 | CTSS_DelayState *state = node->state; 34 | float fb = state->feedback; 35 | uint32_t read = 0; 36 | uint32_t write = 0; 37 | uint32_t raddr = (uint32_t)state->delayLine + state->readPos * 4; 38 | uint32_t waddr = (uint32_t)state->delayLine + state->writePos * 4; 39 | float *src = state->src; 40 | float *buf = node->buf; 41 | size_t len = AUDIO_BUFFER_SIZE * state->channels; 42 | BSP_SDRAM_ReadData(waddr, (uint32_t *)delay_cache_w, len); 43 | BSP_SDRAM_ReadData(raddr, (uint32_t *)delay_cache_r, len); 44 | while (len--) { 45 | delay_cache_w[write] = (*src++) + delay_cache_r[read++] * fb; 46 | *buf++ = delay_cache_w[write++]; 47 | if (++state->readPos == state->len) { 48 | state->readPos = 0; 49 | read = 0; 50 | raddr = (uint32_t)state->delayLine; 51 | BSP_SDRAM_ReadData(raddr, (uint32_t *)delay_cache_r, len); 52 | } 53 | if (++state->writePos == state->len) { 54 | BSP_SDRAM_WriteData(waddr, (uint32_t *)delay_cache_w, write); 55 | waddr = (uint32_t)state->delayLine; 56 | state->writePos = 0; 57 | write = 0; 58 | BSP_SDRAM_ReadData(waddr, (uint32_t *)delay_cache_w, len); 59 | } 60 | } 61 | BSP_SDRAM_WriteData(waddr, (uint32_t *)delay_cache_w, write); 62 | return 0; 63 | } 64 | -------------------------------------------------------------------------------- /src/synth_extras/sdram_delay.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/sdram_alloc.h" 4 | #include "synth.h" 5 | 6 | CTSS_DSPNode *ctss_delay_sdram(char *id, 7 | CTSS_DSPNode *src, 8 | uint32_t len, 9 | float feedback, 10 | uint8_t channels); 11 | 12 | uint8_t ctss_process_delay_sdram(CTSS_DSPNode *node, 13 | CTSS_DSPStack *stack, 14 | CTSS_Synth *synth); 15 | --------------------------------------------------------------------------------