├── .gitignore ├── synth.h ├── usbcfg.h ├── codec.h ├── README.md ├── fast.lib ├── faust2stm32f4.py ├── synth.dsp ├── faust_synth_template.cpp ├── fastpow.h ├── main.c ├── Makefile ├── codec_CS43L22.c ├── halconf.h ├── usbcfg.c ├── mcuconf.h └── chconf.h /.gitignore: -------------------------------------------------------------------------------- 1 | .dep/ 2 | build/ 3 | synth 4 | synth-svg/ 5 | synth.c 6 | synth.cpp 7 | -------------------------------------------------------------------------------- /synth.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef SYNTH_H_ 3 | #define SYNTH_H_ 4 | 5 | #include "ch.h" 6 | #include "hal.h" 7 | 8 | #include "codec.h" 9 | 10 | #define SAMPLINGFREQ 44100 11 | #define CHANNEL_BUFFER_SIZE 128 12 | #define PLAYBACK_BUFFER_SIZE (CHANNEL_BUFFER_SIZE*2) 13 | 14 | typedef struct struct_synth_interface { 15 | float* acc_abs; 16 | float* acc_x; 17 | float* acc_y; 18 | float* acc_z; 19 | } synth_interface_t; 20 | 21 | extern synth_interface_t synth_interface; 22 | extern synth_interface_t synth_interface_bas; 23 | 24 | extern void start_synth_thread(void); 25 | 26 | #endif /* SYNTH_H_ */ -------------------------------------------------------------------------------- /usbcfg.h: -------------------------------------------------------------------------------- 1 | /* 2 | ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #ifndef _USBCFG_H_ 18 | #define _USBCFG_H_ 19 | 20 | extern const USBConfig usbcfg; 21 | extern SerialUSBConfig serusbcfg; 22 | 23 | #endif /* _USBCFG_H_ */ 24 | 25 | /** @} */ 26 | -------------------------------------------------------------------------------- /codec.h: -------------------------------------------------------------------------------- 1 | /* 2 | * codec.h 3 | * 4 | * Created on: Jun 7, 2012 5 | * Author: Kumar Abhishek 6 | */ 7 | 8 | #ifndef CODEC_H_ 9 | #define CODEC_H_ 10 | 11 | #include "ch.h" 12 | #include "hal.h" 13 | 14 | #define CODEC_I2C I2CD1 15 | #define CODEC_I2S_ENABLE rccEnableSPI3(FALSE) 16 | #define CODEC_I2S_DISABLE rccDisableSPI3(FALSE) 17 | #define CODEC_I2S SPI3 18 | 19 | enum CODEC_AUDIOSRC { 20 | CODEC_AUDIOSRC_DIGITAL, 21 | CODEC_AUDIOSRC_MIC, 22 | CODEC_AUDIOSRC_FMRADIO 23 | }; 24 | 25 | 26 | #define CS43L22_ADDR (0x94 >> 1) 27 | 28 | extern Thread* audioThread; 29 | 30 | extern void codec_hw_init(void); 31 | 32 | extern void codec_hw_reset(void); 33 | 34 | extern void codec_writeReg(uint8_t addr, uint8_t data); 35 | 36 | extern uint8_t codec_readReg(uint8_t addr); 37 | 38 | extern void codec_volCtl(uint8_t vol); 39 | 40 | extern void codec_pwrCtl(uint8_t pwr); 41 | 42 | extern void codec_muteCtl(uint8_t mute); 43 | 44 | extern void codec_sendBeep(void); 45 | 46 | extern void codec_selectAudioSource(uint8_t src); 47 | 48 | extern void codec_i2s_init(uint16_t sampleRate, uint8_t nBits); 49 | 50 | extern void codec_audio_send(void* txbuf, size_t n); 51 | 52 | extern void codec_pauseResumePlayback(uint8_t pause); 53 | 54 | #endif /* CODEC_H_ */ 55 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | STM32F4-Discovery Faust Synthesizer Target 2 | ============================================ 3 | 4 | This is an example of running [Faust](http://faust.grame.fr/) code on the [STM32F4-Discovery](http://www.chibios.org/dokuwiki/doku.php?id=chibios:articles:stm32f4_discovery) board. 5 | The synthesizer is controlled by the onboard accelerometer and the onboard 6 | audio codec is used for output. 7 | 8 | Requirements 9 | ------------ 10 | - ChibiOS 2.6.3, must be in `../ChibiOS` 11 | - dfu-util for direct uploading (or other way of uploading) 12 | - gcc-arm-none-eabi compiler 13 | - Faust 14 | 15 | Usage 16 | ----- 17 | Build and upload to STM32F4-Discovery board using dfu-util: 18 | 19 | make prog 20 | 21 | Make sure the MCU is in upload mode by putting a jumper over the BOOT0-VDD pins 22 | and pressing the reset button. 23 | 24 | The synthesizer is written in the [Faust language](http://faust.grame.fr/) and is 25 | called `synth.dsp`. 26 | The controllable parameters in this example are the absolute acceleration and normalized x, y, and z acceleration. They are now hard-coded on several locations: `synth.h`, `main.c`, `faust2stm32f4.py`. 27 | 28 | The code for controlling the onboard CS43L22 DAC and sending data to it via 29 | DMA is based on an implementation by [Abhishek](https://github.com/abhishek-kakkar/STM32F4Player). 30 | 31 | This Faust target has been developed as part of the development of the Striso, 32 | a self-contained battery powered music instrument, and is written by Piers 33 | Titus van der Torren. See http://www.striso.org/. 34 | -------------------------------------------------------------------------------- /fast.lib: -------------------------------------------------------------------------------- 1 | //fast.lib - Faust functions for fast approximations of various functions 2 | declare name "Faust Fast Approximations Library"; 3 | declare author "Piers Titus van der Torren (pierstitus@toverlamp.org)"; 4 | declare licence "Apache-2.0"; 5 | 6 | import("music.lib"); 7 | 8 | // 2^x approximation 9 | fastpow2 = ffunction(float fastpow2 (float), "fastpow.h", ""); 10 | 11 | // integer divide 12 | idiv = ffunction(int idiv (int, int),"fastpow.h",""); 13 | 14 | // fast midi note to frequency function 15 | note2freq(note) = 8.175798916 * fastpow2(note/12.0); 16 | 17 | // tailor approximation of tan for [0,pi/4] 18 | tan0(a) = (((2.033e-01 * a^2) + 3.1755e-01) * a^2 + 1.0) * a; 19 | 20 | // biquad filters section 21 | biquad(a0,a1,a2,b1,b2,x) = x : + ~ ((-1)*conv2(b1, b2)) : conv3(a0, a1, a2) 22 | with { 23 | conv2(c0,c1,x) = c0*x+c1*x'; 24 | conv3(c0,c1,c2,x) = c0*x+c1*x'+c2*x''; 25 | }; 26 | 27 | // fast approximation for K in the following biquad filters 28 | K_f0(f0) = tan0(PI * f0 / SR); 29 | 30 | // Low Pass Filter 31 | LPF(K, Q) = biquad(a0,a1,a2,b1,b2) 32 | with { 33 | //K = tan(PI * f0 / SR); 34 | norm = 1 / (1 + K / Q + K * K); 35 | a0 = K * K * norm; 36 | a1 = 2 * a0; 37 | a2 = a0; 38 | b1 = 2 * (K * K - 1) * norm; 39 | b2 = (1 - K / Q + K * K) * norm; 40 | }; 41 | 42 | // High Pass Filter 43 | HPF(K, Q) = biquad(a0,a1,a2,b1,b2) 44 | with { 45 | //K = tan(PI * f0 / SR); 46 | norm = 1 / (1 + K / Q + K * K); 47 | a0 = 1 * norm; 48 | a1 = -2 * a0; 49 | a2 = a0; 50 | b1 = 2 * (K * K - 1) * norm; 51 | b2 = (1 - K / Q + K * K) * norm; 52 | }; 53 | 54 | // Band Pass Filter 55 | BPF(K, Q) = biquad(a0,a1,a2,b1,b2) 56 | with { 57 | //K = tan(PI * f0 / SR); 58 | norm = 1 / (1 + K / Q + K * K); 59 | a0 = K / Q * norm; 60 | a1 = 0; 61 | a2 = -a0; 62 | b1 = 2 * (K * K - 1) * norm; 63 | b2 = (1 - K / Q + K * K) * norm; 64 | }; 65 | 66 | -------------------------------------------------------------------------------- /faust2stm32f4.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import re 4 | import subprocess 5 | import os 6 | 7 | def interface2embedded_interface(interface_cpp, inputs=('acc_abs','acc_x','acc_y','acc_z')): 8 | """ 9 | Convert Faust interface function to a faster hard-coded interface without strings. 10 | """ 11 | add_re = re.compile(r'interface->add\w*\(("\w*", &\w*),') 12 | ch_lines = [] 13 | for line in interface_cpp: 14 | line = line.strip() 15 | if line.startswith('interface->add'): 16 | par = add_re.findall(line)[0].split(',') 17 | name = par[0].strip('"') 18 | loc = par[1].strip() 19 | if name in inputs: 20 | ch_lines.append('synth_interface.{} = {};'.format(name, loc)) 21 | 22 | return ch_lines 23 | 24 | def faust_postprocess(source): 25 | 26 | # replace cpp templates with faster fixed defined functions 27 | source = source.replace('faustpower<2>', 'faustpower2') 28 | source = source.replace('faustpower<3>', 'faustpower3') 29 | 30 | # replace interface function with simpler version without strings 31 | start = source.find('virtual void buildUserInterface(UI* interface) {') 32 | stop = source.find('}',start) 33 | interface_embedded = interface2embedded_interface(source[start:stop].splitlines()) 34 | 35 | new_source = ''.join(( 36 | source[:start], 37 | 'virtual void buildUserInterfaceEmbedded() {\n\t\t', 38 | '\n\t\t'.join(interface_embedded), 39 | '\n\t', 40 | source[stop:])) 41 | 42 | return new_source 43 | 44 | def faust_replace_fixed_sliders(faust_in): 45 | """ 46 | replace hsliders with fixed values, useful for quick testing 47 | of settings on the pc but compiling the as fixed on embedded platform. 48 | vsliders stay variable. 49 | """ 50 | replace_slider = re.compile(r'hslider\(".*",([^,]*),[^)]*\)') 51 | return replace_slider.sub(r'\1',faust_in) 52 | 53 | def main(faust_source='synth.dsp', faust_template='faust_synth_template.cpp'): 54 | 55 | tmp_file = faust_source + '.tmp' 56 | 57 | # preprocess: replace hsliders with fixed values, useful for quick testing 58 | # of settings on the pc but compiling the as fixed on embedded platform. 59 | # vsliders stay variable. 60 | with open(tmp_file,'w') as f: 61 | f.write(faust_replace_fixed_sliders(open(faust_source).read())) 62 | 63 | # run faust compiler 64 | faust_cpp = subprocess.check_output(['faust','-a',faust_template,tmp_file]) 65 | 66 | # do some postprocessing for efficient embedded use 67 | faust_cpp = faust_postprocess(faust_cpp) 68 | with open('synth.cpp','w') as f: 69 | f.write(faust_cpp) 70 | 71 | if __name__ == '__main__': 72 | main() 73 | -------------------------------------------------------------------------------- /synth.dsp: -------------------------------------------------------------------------------- 1 | import("music.lib"); 2 | //ml = library("music.lib"); // SR, ... 3 | //fl = library("filter.lib"); 4 | oscillator = library("oscillator.lib"); 5 | maxmsp = library("maxmsp.lib"); 6 | fast = library("fast.lib"); 7 | 8 | halftime2fac(x) = 0.5^(1./(SR*x)); 9 | 10 | smooth(x) = maxmsp.line(x,2); 11 | 12 | envdecay(c) = (max:_ * c) ~ _; 13 | 14 | // vsliders to be used by embedded platform 15 | acc_abs = vslider("v:accelerometer/acc_abs[style:knob]",1,0,4,0.01); 16 | acc_x = vslider("v:accelerometer/acc_x[style:knob]",0,-1,1,0.01); 17 | acc_y = vslider("v:accelerometer/acc_y[style:knob]",0,-1,1,0.01); 18 | acc_z = vslider("v:accelerometer/acc_z[style:knob]",-1,-1,1,0.01); 19 | 20 | // hsliders will be changed to static values before compiliation for embedded 21 | note = hslider("v:[0]config/note[style:knob]",69,0,127,.01); 22 | decay = hslider("v:[0]config/decay[style:knob]",0.7,0,1,0.01):halftime2fac; 23 | bendRange = hslider("v:[0]config/bendRange[style:knob]",12,0,36,0.01); 24 | minFreq = hslider("v:[0]config/minFreq[style:knob]",400,0,1000,1); 25 | bodyFreq = hslider("v:[0]config/bodyFreq[style:knob]",500,0,1000,1); 26 | 27 | filtQ = hslider("v:[1]config2/filtQ[style:knob]",2,0,10,0.01); 28 | filt2Freq = hslider("v:[1]config2/filt2Freq[style:knob]",3000,0,10000,1); 29 | filt2Q = hslider("v:[1]config2/filt2Q[style:knob]",2,0.01,10,0.01); 30 | filt2level = hslider("v:[1]config2/filt2Level[style:knob]",2,0,50,0.01); 31 | 32 | 33 | // sawtooth + square oscilator 34 | oscss(freq, even_harm) = even_harm*saw-(1-even_harm)*square 35 | with { 36 | square = oscillator.lf_squarewave(freq)*0.5; 37 | saw = oscillator.saw2(freq); 38 | }; 39 | 40 | voice = vosc + perc <: filt, filt2 :> _ * level 41 | with { 42 | even_harm = (acc_x^3+1)/2; 43 | pitchbend = acc_y^3; 44 | freq = fast.note2freq(note+pitchbend*bendRange); 45 | vosc = oscss(freq, even_harm); 46 | 47 | perc = max(-acc_z,0.02) * noise; 48 | 49 | l = abs(acc_abs-1):envdecay(decay); 50 | level = (l*0.25)^2; 51 | K = fast.K_f0(max(freq,minFreq)) + max(-1,0); 52 | filt = fast.LPF(K, filtQ); 53 | 54 | filt2lev = max((acc_x^3+1)/2, 0); 55 | filt2 = fast.BPF(fast.K_f0(filt2Freq*filt2lev+minFreq), filt2Q) * filt2level * filt2lev; 56 | }; 57 | 58 | //Body Filter: a biquad filter with a normalized pick gain 59 | bodyFilter = fast.BPF(fast.K_f0(bodyFreq),0.55); 60 | 61 | mystereoizer(periodDuration) = _ <: _,widthdelay : stereopanner 62 | with { 63 | W = 0.5; //hslider("v:Spat/spatial width", 0.5, 0, 1, 0.01); 64 | A = 0.5; //hslider("v:Spat/pan angle", 0.6, 0, 1, 0.01); 65 | widthdelay = delay(4096,W*periodDuration/2); 66 | stereopanner = _,_ : *(1.0-A), *(A); 67 | }; 68 | 69 | stereo = mystereoizer(SR/440); 70 | 71 | process = hgroup("synth", 72 | voice : bodyFilter : stereo); 73 | -------------------------------------------------------------------------------- /faust_synth_template.cpp: -------------------------------------------------------------------------------- 1 | 2 | extern "C" { 3 | #include "synth.h" 4 | } 5 | 6 | // definitions for max and min used by faust. Not sure if this is optimal when 7 | // there are complex constructions inside. 8 | #define max(x,y) (x>y?x:y) 9 | #define min(x,y) (x(float x) 13 | #define faustpower3(x) ((x)*(x)*(x)) 14 | #define faustpower2(x) ((x)*(x)) 15 | 16 | // minimal DSP class 17 | class dsp { 18 | protected: 19 | int fSamplingFreq; 20 | }; 21 | 22 | // minimal Meta class 23 | struct Meta { 24 | virtual void declare(const char* key, const char* value) = 0; 25 | }; 26 | 27 | // variables 28 | synth_interface_t synth_interface; 29 | 30 | static int16_t buf1[PLAYBACK_BUFFER_SIZE] = {0}; 31 | static int16_t buf2[PLAYBACK_BUFFER_SIZE] = {0}; 32 | static float output0[CHANNEL_BUFFER_SIZE] = {0.0}; 33 | static float output1[CHANNEL_BUFFER_SIZE] = {0.0}; 34 | static float* output[2] = {output0, output1}; 35 | 36 | // Intrinsics 37 | <> 38 | 39 | // Class 40 | <> 41 | 42 | FAUSTCLASS dsp; 43 | 44 | static WORKING_AREA(waSynthThread, 1024); 45 | static msg_t synthThread(void *arg) { // THE SYNTH THREAD 46 | (void)arg; 47 | chRegSetThreadName("SYNTH"); 48 | 49 | uint_fast8_t bufSwitch=1; 50 | int16_t* buf = buf1; 51 | int32_t tmp; 52 | int count = CHANNEL_BUFFER_SIZE; 53 | int n = 0; 54 | 55 | codec_pwrCtl(1); // POWER ON 56 | codec_muteCtl(0); // MUTE OFF 57 | 58 | chEvtAddEvents(1); 59 | 60 | // initialization 61 | dsp.init(SAMPLINGFREQ); 62 | 63 | // initialize interface 64 | dsp.buildUserInterfaceEmbedded(); 65 | 66 | // computation loop 67 | while (true) { 68 | dsp.compute(count, NULL, output); 69 | 70 | // double buffering 71 | if (bufSwitch) { 72 | buf = buf1; 73 | bufSwitch=0; 74 | } else { 75 | buf = buf2; 76 | bufSwitch=1; 77 | } 78 | // convert float to int with scale, clamp and round 79 | for (int n = 0; n < CHANNEL_BUFFER_SIZE; n++) { 80 | tmp = (int32_t)(output0[n] * 32768); 81 | tmp = (tmp <= -32768) ? -32768 : (tmp >= 32767) ? 32767 : tmp; 82 | // enable LED on clip 83 | //if (tmp <= -32768 || tmp >= 32767) 84 | //{ 85 | // palSetPad(GPIOD, GPIOD_LED3); /* Orange. */ 86 | //} else { 87 | // palClearPad(GPIOD, GPIOD_LED3); /* Orange. */ 88 | //} 89 | // make both audio channels the same 90 | buf[2*n] = buf[2*n+1] = (int16_t)tmp; 91 | } 92 | 93 | if (--n <= 0) { 94 | palTogglePad(GPIOD, GPIOD_LED3); /* Orange. */ 95 | n = 100; 96 | } 97 | 98 | chEvtWaitOne(1); 99 | codec_audio_send(buf, PLAYBACK_BUFFER_SIZE); 100 | 101 | if (chThdShouldTerminate()) break; 102 | } 103 | 104 | codec_muteCtl(1); 105 | codec_pwrCtl(0); 106 | 107 | audioThread=NULL; 108 | palTogglePad(GPIOD, GPIOD_LED5); 109 | 110 | return 0; 111 | }; 112 | 113 | void start_synth_thread(void) { 114 | audioThread = chThdCreateStatic(waSynthThread, sizeof(waSynthThread), NORMALPRIO+2, synthThread, NULL); 115 | } 116 | 117 | -------------------------------------------------------------------------------- /fastpow.h: -------------------------------------------------------------------------------- 1 | /*=====================================================================* 2 | * Copyright (C) 2012 Paul Mineiro * 3 | * All rights reserved. * 4 | * * 5 | * Redistribution and use in source and binary forms, with * 6 | * or without modification, are permitted provided that the * 7 | * following conditions are met: * 8 | * * 9 | * * Redistributions of source code must retain the * 10 | * above copyright notice, this list of conditions and * 11 | * the following disclaimer. * 12 | * * 13 | * * Redistributions in binary form must reproduce the * 14 | * above copyright notice, this list of conditions and * 15 | * the following disclaimer in the documentation and/or * 16 | * other materials provided with the distribution. * 17 | * * 18 | * * Neither the name of Paul Mineiro nor the names * 19 | * of other contributors may be used to endorse or promote * 20 | * products derived from this software without specific * 21 | * prior written permission. * 22 | * * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * 24 | * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * 25 | * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * 26 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * 27 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER * 28 | * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * 29 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * 30 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE * 31 | * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * 32 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * 33 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 34 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * 35 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * 36 | * POSSIBILITY OF SUCH DAMAGE. * 37 | * * 38 | * Contact: Paul Mineiro * 39 | *=====================================================================*/ 40 | 41 | #ifndef __FASTPOW_H_ 42 | 43 | #ifdef __cplusplus 44 | #define cast_uint32_t static_cast 45 | #else 46 | #define cast_uint32_t (uint32_t) 47 | #endif 48 | 49 | #include 50 | 51 | // Underflow of exponential is common practice in numerical routines, 52 | // but not in this case, so remove handling. 53 | static inline float 54 | fastpow2 (float p) 55 | { 56 | //float offset = (p < 0) ? 1.0f : 0.0f; 57 | //p = (p < -126) ? -126.0f : p; 58 | int w = p; 59 | float z = p - w; 60 | union { uint32_t i; float f; } v = { cast_uint32_t ( (1 << 23) * (p + 121.2740575f + 27.7280233f / (4.84252568f - z) - 1.49012907f * z) ) }; 61 | return v.f; 62 | } 63 | 64 | #define idiv(a,b) (a)/(b) 65 | 66 | #endif // __FASTPOW_H_ -------------------------------------------------------------------------------- /main.c: -------------------------------------------------------------------------------- 1 | /* 2 | ChibiOS/RT Faust target - Copyright (C) 2014 Piers Titus van der Torren 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // File adopted from ChibiOS STM32F4Discovery Demo 18 | 19 | #include "ch.h" 20 | #include "hal.h" 21 | 22 | #include "chprintf.h" 23 | #include "lis302dl.h" 24 | 25 | // User Includes 26 | #include "codec.h" 27 | 28 | #include "synth.h" 29 | #include 30 | 31 | #include "usbcfg.h" 32 | 33 | // next lines are necessary since synth_contol.cpp is included 34 | // and are copied from ChibiOS/testhal/STM32F4xx/RTC/main.c 35 | /* libc stub */ 36 | int _getpid(void) {return 1;} 37 | /* libc stub */ 38 | void _exit(int i) {(void)i;while(1);} 39 | /* libc stub */ 40 | #include 41 | #undef errno 42 | extern int errno; 43 | int _kill(int pid, int sig) { 44 | (void)pid; 45 | (void)sig; 46 | errno = EINVAL; 47 | return -1; 48 | } 49 | 50 | // sqrtf which uses FPU, the standard one apparently doesn't 51 | float vsqrtf(float op1) { 52 | float result; 53 | __ASM volatile ("vsqrt.f32 %0, %1" : "=w" (result) : "w" (op1) ); 54 | return (result); 55 | } 56 | 57 | BaseSequentialStream* chp; 58 | 59 | /* Virtual serial port over USB.*/ 60 | SerialUSBDriver SDU1; 61 | 62 | static SerialConfig ser_cfg = { 63 | 2000000, 64 | 0, 65 | 0, 66 | 0, 67 | }; 68 | 69 | /* 70 | * SPI1 configuration structure. 71 | * Speed 5.25MHz, CPHA=1, CPOL=1, 8bits frames, MSb transmitted first. 72 | * The slave select line is the pin GPIOE_CS_SPI on the port GPIOE. 73 | */ 74 | static const SPIConfig spi1cfg = { 75 | NULL, 76 | /* HW dependent part.*/ 77 | GPIOE, 78 | GPIOE_CS_SPI, 79 | SPI_CR1_BR_0 | SPI_CR1_BR_1 | SPI_CR1_CPOL | SPI_CR1_CPHA 80 | }; 81 | /* 82 | * This is a periodic thread that reads accelerometer and sends messages 83 | */ 84 | static WORKING_AREA(waThreadAccel, 128); 85 | __attribute__ ((noreturn)) 86 | static msg_t ThreadAccel(void *arg) {\ 87 | systime_t time; /* Next deadline.*/ 88 | float acc_x, acc_y, acc_z, acc_abs; 89 | 90 | (void)arg; 91 | chRegSetThreadName("accel"); 92 | 93 | /* LIS302DL initialization.*/ 94 | lis302dlWriteRegister(&SPID1, LIS302DL_CTRL_REG1, 0b11000111); // 01000011 DR-0:100Hz, 1:400Hz PD-PowerDown FS-0:2g 1:8g STP STM Zen Yen Xen // 0x43 95 | lis302dlWriteRegister(&SPID1, LIS302DL_CTRL_REG2, 0x00); 96 | lis302dlWriteRegister(&SPID1, LIS302DL_CTRL_REG3, 0x00); 97 | 98 | /* Reader thread loop.*/ 99 | time = chTimeNow(); 100 | while (TRUE) { 101 | /* Reading MEMS accelerometer X and Y registers.*/ 102 | // Hard-coded calibration values, * 1.12 offset 103 | acc_x = ((float)(int8_t)lis302dlReadRegister(&SPID1, LIS302DL_OUTX))/64*1.0+0.0; 104 | acc_y = ((float)(int8_t)lis302dlReadRegister(&SPID1, LIS302DL_OUTY))/64*1.0+0.0; 105 | acc_z = ((float)(int8_t)lis302dlReadRegister(&SPID1, LIS302DL_OUTZ))/64*1.0+0.0; 106 | 107 | #define pow2(x) (x*x) 108 | acc_abs = vsqrtf(pow2(acc_x) + pow2(acc_y) + pow2(acc_z)); 109 | if (acc_abs>0.001) { 110 | acc_x /= acc_abs; 111 | acc_y /= acc_abs; 112 | acc_z /= acc_abs; 113 | } 114 | *(synth_interface.acc_abs) = acc_abs; 115 | *(synth_interface.acc_x) = acc_x; 116 | *(synth_interface.acc_y) = acc_y; 117 | *(synth_interface.acc_z) = acc_z; 118 | 119 | /* 120 | chprintf(chp, "%4d %4d %4d %4d \r", 121 | (int)(1000*acc_x), 122 | (int)(1000*acc_y), 123 | (int)(1000*acc_z), 124 | (int)(1000*acc_abs)); 125 | */ 126 | 127 | /* Waiting until the next 10 milliseconds time interval.*/ 128 | chThdSleepUntil(time += MS2ST(2)); 129 | } 130 | } 131 | 132 | 133 | // Hardware Initialization 134 | static void hw_init(void) 135 | { 136 | // Init Serial Port 137 | sdStart(&SD2, &ser_cfg); 138 | palSetPadMode(GPIOA, 2, PAL_MODE_ALTERNATE(7)); 139 | palSetPadMode(GPIOA, 3, PAL_MODE_ALTERNATE(7)); 140 | 141 | /* Initializes a serial-over-USB CDC driver. */ 142 | sduObjectInit(&SDU1); 143 | sduStart(&SDU1, &serusbcfg); 144 | 145 | /* 146 | * Initializes the SPI driver 1 in order to access the MEMS. The signals 147 | * are already initialized in the board file. 148 | */ 149 | spiStart(&SPID1, &spi1cfg); 150 | 151 | /* 152 | * Activates the USB driver and then the USB bus pull-up on D+. 153 | * Note, a delay is inserted in order to not have to disconnect the cable 154 | * after a reset. 155 | */ 156 | usbDisconnectBus(serusbcfg.usbp); 157 | chThdSleepMilliseconds(1000); 158 | usbStart(serusbcfg.usbp, &usbcfg); 159 | usbConnectBus(serusbcfg.usbp); 160 | 161 | codec_hw_init(); 162 | } 163 | 164 | static VirtualTimer vt1; 165 | 166 | static void led_toggle(void *p) 167 | { 168 | (void)p; 169 | palTogglePad(GPIOD, GPIOD_LED4); 170 | chVTSetI(&vt1, 500, led_toggle, NULL); 171 | } 172 | 173 | // Entry Point 174 | int main(void) 175 | { 176 | halInit(); 177 | chSysInit(); 178 | 179 | chThdSelf(); 180 | 181 | hw_init(); 182 | 183 | chp = (BaseSequentialStream *)&SDU1; // output for chprintf 184 | 185 | codec_i2s_init(44100, 16); 186 | 187 | start_synth_thread(); 188 | chThdSleep(10); 189 | 190 | chThdCreateStatic(waThreadAccel, sizeof(waThreadAccel), NORMALPRIO, ThreadAccel, NULL); 191 | 192 | chVTSetI(&vt1, 500, led_toggle, NULL); 193 | 194 | while (TRUE) { 195 | chThdSleep(100); 196 | } 197 | } 198 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ############################################################################## 2 | # Build global options 3 | # NOTE: Can be overridden externally. 4 | # 5 | 6 | # Compiler options here. 7 | ifeq ($(USE_OPT),) 8 | USE_OPT = -O2 -ggdb -fomit-frame-pointer -falign-functions=16 9 | endif 10 | 11 | # C specific options here (added to USE_OPT). 12 | ifeq ($(USE_COPT),) 13 | USE_COPT = -std=gnu99 14 | endif 15 | 16 | # C++ specific options here (added to USE_OPT). 17 | ifeq ($(USE_CPPOPT),) 18 | USE_CPPOPT = -fno-rtti -std=gnu++11 19 | endif 20 | 21 | # Enable this if you want the linker to remove unused code and data 22 | ifeq ($(USE_LINK_GC),) 23 | USE_LINK_GC = yes 24 | endif 25 | 26 | # If enabled, this option allows to compile the application in THUMB mode. 27 | ifeq ($(USE_THUMB),) 28 | USE_THUMB = yes 29 | endif 30 | 31 | # Enable this if you want to see the full log while compiling. 32 | ifeq ($(USE_VERBOSE_COMPILE),) 33 | USE_VERBOSE_COMPILE = no 34 | endif 35 | 36 | # 37 | # Build global options 38 | ############################################################################## 39 | 40 | ############################################################################## 41 | # Architecture or project specific options 42 | # 43 | 44 | # Enables the use of FPU on Cortex-M4. 45 | ifeq ($(USE_FPU),) 46 | USE_FPU = yes 47 | endif 48 | 49 | # Enable this if you really want to use the STM FWLib. 50 | ifeq ($(USE_FWLIB),) 51 | USE_FWLIB = no 52 | endif 53 | 54 | # 55 | # Architecture or project specific options 56 | ############################################################################## 57 | 58 | ############################################################################## 59 | # Project, sources and paths 60 | # 61 | 62 | # Define project name here 63 | PROJECT = STM32F4_Discovery_demo 64 | 65 | # Imported source files and paths 66 | CHIBIOS = ../ChibiOS 67 | include $(CHIBIOS)/boards/ST_STM32F4_DISCOVERY/board.mk 68 | include $(CHIBIOS)/os/hal/platforms/STM32F4xx/platform.mk 69 | include $(CHIBIOS)/os/hal/hal.mk 70 | include $(CHIBIOS)/os/ports/GCC/ARMCMx/STM32F4xx/port.mk 71 | include $(CHIBIOS)/os/kernel/kernel.mk 72 | 73 | # Define linker script file here 74 | LDSCRIPT= $(PORTLD)/STM32F407xG.ld 75 | #LDSCRIPT= $(PORTLD)/STM32F407xG_CCM.ld 76 | 77 | # C sources that can be compiled in ARM or THUMB mode depending on the global 78 | # setting. 79 | CSRC = $(PORTSRC) \ 80 | $(KERNSRC) \ 81 | $(TESTSRC) \ 82 | $(HALSRC) \ 83 | $(PLATFORMSRC) \ 84 | $(BOARDSRC) \ 85 | $(CHIBIOS)/os/various/devices_lib/accel/lis302dl.c \ 86 | $(CHIBIOS)/os/various/chprintf.c \ 87 | $(CHIBIOS)/os/various/syscalls.c \ 88 | main.c \ 89 | codec_CS43L22.c \ 90 | usbcfg.c 91 | 92 | # C++ sources that can be compiled in ARM or THUMB mode depending on the global 93 | # setting. 94 | CPPSRC = synth.cpp 95 | 96 | # C sources to be compiled in ARM mode regardless of the global setting. 97 | # NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler 98 | # option that results in lower performance and larger code size. 99 | ACSRC = 100 | 101 | # C++ sources to be compiled in ARM mode regardless of the global setting. 102 | # NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler 103 | # option that results in lower performance and larger code size. 104 | ACPPSRC = 105 | 106 | # C sources to be compiled in THUMB mode regardless of the global setting. 107 | # NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler 108 | # option that results in lower performance and larger code size. 109 | TCSRC = 110 | 111 | # C sources to be compiled in THUMB mode regardless of the global setting. 112 | # NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler 113 | # option that results in lower performance and larger code size. 114 | TCPPSRC = 115 | 116 | # List ASM source files here 117 | ASMSRC = $(PORTASM) 118 | 119 | INCDIR = $(PORTINC) $(KERNINC) \ 120 | $(HALINC) $(PLATFORMINC) $(BOARDINC) \ 121 | $(CHIBIOS)/os/various/devices_lib/accel \ 122 | $(CHIBIOS)/os/various \ 123 | 124 | 125 | # 126 | # Project, sources and paths 127 | ############################################################################## 128 | 129 | ############################################################################## 130 | # Compiler settings 131 | # 132 | 133 | MCU = cortex-m4 134 | 135 | #TRGT = arm-elf- 136 | TRGT = arm-none-eabi- 137 | CC = $(TRGT)gcc 138 | CPPC = $(TRGT)g++ 139 | # Enable loading with g++ only if you need C++ runtime support. 140 | # NOTE: You can use C++ even without C++ support if you are careful. C++ 141 | # runtime support makes code size explode. 142 | LD = $(TRGT)gcc 143 | #LD = $(TRGT)g++ 144 | CP = $(TRGT)objcopy 145 | AS = $(TRGT)gcc -x assembler-with-cpp 146 | OD = $(TRGT)objdump 147 | HEX = $(CP) -O ihex 148 | BIN = $(CP) -O binary 149 | 150 | # ARM-specific options here 151 | AOPT = 152 | 153 | # THUMB-specific options here 154 | TOPT = -mthumb -DTHUMB 155 | 156 | # Define C warning options here 157 | CWARN = -Wall -Wextra -Wstrict-prototypes 158 | 159 | # Define C++ warning options here 160 | CPPWARN = -Wall -Wextra 161 | 162 | # 163 | # Compiler settings 164 | ############################################################################## 165 | 166 | ############################################################################## 167 | # Start of default section 168 | # 169 | 170 | # List all default C defines here, like -D_DEBUG=1 171 | DDEFS = 172 | 173 | # List all default ASM defines here, like -D_DEBUG=1 174 | DADEFS = 175 | 176 | # List all default directories to look for include files here 177 | DINCDIR = 178 | 179 | # List the default directory to look for the libraries here 180 | DLIBDIR = 181 | 182 | # List all default libraries here 183 | DLIBS = 184 | 185 | # 186 | # End of default section 187 | ############################################################################## 188 | 189 | ############################################################################## 190 | # Start of user section 191 | # 192 | 193 | # List all user C define here, like -D_DEBUG=1 194 | UDEFS = 195 | 196 | # Define ASM defines here 197 | UADEFS = 198 | 199 | # List all user directories here 200 | UINCDIR = 201 | 202 | # List the user directory to look for the libraries here 203 | ULIBDIR = 204 | 205 | # List all user libraries here 206 | ULIBS = -lm 207 | 208 | # 209 | # End of user defines 210 | ############################################################################## 211 | 212 | ifeq ($(USE_FPU),yes) 213 | USE_OPT += -mfloat-abi=softfp -mfpu=fpv4-sp-d16 -fsingle-precision-constant 214 | DDEFS += -DCORTEX_USE_FPU=TRUE 215 | else 216 | DDEFS += -DCORTEX_USE_FPU=FALSE 217 | endif 218 | 219 | ifeq ($(USE_FWLIB),yes) 220 | include $(CHIBIOS)/ext/stm32lib/stm32lib.mk 221 | CSRC += $(STM32SRC) 222 | INCDIR += $(STM32INC) 223 | USE_OPT += -DUSE_STDPERIPH_DRIVER 224 | endif 225 | 226 | include $(CHIBIOS)/os/ports/GCC/ARMCMx/rules.mk 227 | 228 | prog: all 229 | dfu-util -d0483:df11 -a0 -s0x8000000 -D $(BUILDDIR)/$(PROJECT).bin 230 | 231 | synth.cpp: synth.dsp faust_synth_template.cpp 232 | ./faust2stm32f4.py 233 | -------------------------------------------------------------------------------- /codec_CS43L22.c: -------------------------------------------------------------------------------- 1 | /* 2 | * codec_CS43L22.c 3 | * ChibiOS driver for the CS43L22 audio codec available on STM32F4-Discovery. 4 | * 5 | * Created on: Jun 7, 2012 6 | * Author: Kumar Abhishek 7 | * 8 | * Modified by Piers Titus van der Torren, 2014 9 | */ 10 | 11 | #include "codec.h" 12 | 13 | #include "chprintf.h" 14 | 15 | const stm32_dma_stream_t* i2sdma; 16 | static uint32_t i2stxdmamode=0; 17 | 18 | Thread* audioThread; 19 | 20 | static const I2CConfig i2cfg = { 21 | OPMODE_I2C, 22 | 100000, 23 | FAST_DUTY_CYCLE_16_9, 24 | }; 25 | 26 | #define I2S3_TX_DMA_CHANNEL \ 27 | STM32_DMA_GETCHANNEL(STM32_SPI_SPI3_TX_DMA_STREAM, \ 28 | STM32_SPI3_TX_DMA_CHN) 29 | 30 | static uint8_t txbuf[2]={0}, rxbuf[2]={0}; 31 | 32 | void codec_hw_init(void) 33 | { 34 | /* 35 | 4.9 Recommended Power-Up Sequence 36 | 1. Hold RESET low until the power supplies are stable. 37 | 2. Bring RESET high. 38 | 3. The default state of the “Power Ctl. 1” register (0x02) is 0x01. Load the desired register settings while 39 | keeping the “Power Ctl 1” register set to 0x01. 40 | 4. Load the required initialization settings listed in Section 4.11. 41 | 5. Apply MCLK at the appropriate frequency, as discussed in Section 4.6. SCLK may be applied or set to 42 | master at any time; LRCK may only be applied or set to master while the PDN bit is set to 1. 43 | 6. Set the “Power Ctl 1” register (0x02) to 0x9E. 44 | 7. Bring RESET low if the analog or digital supplies drop below the recommended operating condition to 45 | prevent power glitch related issues. 46 | 47 | 4.11 Required Initialization Settings 48 | Various sections in the device must be adjusted by implementing the initialization settings shown below after 49 | power-up sequence step 3. All performance and power consumption measurements were taken with the 50 | following settings: 51 | 1. Write 0x99 to register 0x00. 52 | 2. Write 0x80 to register 0x47. 53 | 3. Write ‘1’b to bit 7 in register 0x32. 54 | 4. Write ‘0’b to bit 7 in register 0x32. 55 | 5. Write 0x00 to register 0x00. 56 | */ 57 | // Fortunately, all pins have already been initialized in board.h 58 | 59 | // Start the i2c driver 60 | i2cStart(&CODEC_I2C, &i2cfg); 61 | 62 | // Reset the codec 63 | codec_hw_reset(); 64 | 65 | // Write init sequence 66 | // Keep codec powered down initially 67 | codec_pwrCtl(0); 68 | 69 | codec_muteCtl(0); 70 | 71 | // Auto Detect Clock, MCLK/2 72 | codec_writeReg(0x05, 0x81); 73 | 74 | // Slave Mode, I2S Data Format (default is Left Justified) 75 | codec_writeReg(0x06, 0x04); 76 | 77 | codec_pwrCtl(1); 78 | 79 | //codec_volCtl(200); 80 | 81 | // Adjust PCM Volume, 0x0A * 0.5 dB = +5dB 82 | //codec_writeReg(0x1A, 0x0A); 83 | //codec_writeReg(0x1B, 0x0A); 84 | 85 | // Disable the analog passthrough volume at zero crossing and soft ramp 86 | //codec_writeReg(0x0A, 0x00); 87 | 88 | // Disable the digital soft ramp 89 | //codec_writeReg(0x0E, 0x04); 90 | 91 | // Disable the limiter attack level 92 | //codec_writeReg(0x27, 0x00); 93 | 94 | // Set beep to 1043.48 Hz = C6, ~86 ms 95 | codec_writeReg(0x1C, 0x80); 96 | } 97 | 98 | void codec_hw_reset(void) 99 | { 100 | palClearPad(GPIOD, GPIOD_RESET); 101 | halPolledDelay(MS2RTT(10)); 102 | palSetPad(GPIOD, GPIOD_RESET); 103 | } 104 | 105 | static void dma_i2s_interrupt(void* dat, uint32_t flags) 106 | { 107 | (void)dat; 108 | (void)flags; 109 | dmaStreamDisable(i2sdma); 110 | 111 | chSysLockFromIsr(); 112 | chEvtSignalI(audioThread, 1); 113 | chSysUnlockFromIsr(); 114 | } 115 | 116 | static void codec_dma_init(void) 117 | { 118 | i2sdma=STM32_DMA_STREAM(STM32_SPI_SPI3_TX_DMA_STREAM); 119 | 120 | i2stxdmamode = STM32_DMA_CR_CHSEL(I2S3_TX_DMA_CHANNEL) | 121 | STM32_DMA_CR_PL(STM32_SPI_SPI3_DMA_PRIORITY) | 122 | STM32_DMA_CR_DIR_M2P | 123 | STM32_DMA_CR_DMEIE | 124 | STM32_DMA_CR_TEIE | 125 | STM32_DMA_CR_TCIE | 126 | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD; 127 | 128 | bool_t b = dmaStreamAllocate(i2sdma, 129 | STM32_SPI_SPI3_IRQ_PRIORITY, 130 | (stm32_dmaisr_t)dma_i2s_interrupt, 131 | (void *)&SPID3); 132 | 133 | if (!b) 134 | chprintf((BaseSequentialStream*)&SD2, "DMA Allocated Successfully to I2S3\r\n"); 135 | 136 | dmaStreamSetPeripheral(i2sdma, &(SPI3->DR)); 137 | } 138 | 139 | void codec_i2s_init(uint16_t sampleRate, uint8_t nBits) 140 | { 141 | uint16_t prescale; 142 | uint32_t pllfreq=STM32_PLLI2SVCO / STM32_PLLI2SR_VALUE; 143 | 144 | if (nBits!=16) 145 | return; 146 | 147 | // SPI3 in I2S Mode, Master 148 | CODEC_I2S_ENABLE; 149 | 150 | CODEC_I2S->I2SCFGR=SPI_I2SCFGR_I2SMOD | SPI_I2SCFGR_I2SCFG_1; 151 | 152 | // Master clock mode Fs * 256 153 | prescale=(pllfreq*10)/(256*sampleRate) + 5; 154 | prescale/=10; 155 | 156 | chprintf((BaseSequentialStream*)&SD2, "Prescale value:%d\r\n", prescale); 157 | 158 | if (prescale > 0xFF || prescale < 2) prescale=2; 159 | 160 | if (prescale & 0x01) 161 | CODEC_I2S->I2SPR=SPI_I2SPR_MCKOE | SPI_I2SPR_ODD | (prescale>>1); 162 | else 163 | CODEC_I2S->I2SPR=SPI_I2SPR_MCKOE | (prescale>>1); 164 | 165 | codec_dma_init(); 166 | 167 | // Enable I2S DMA Request 168 | CODEC_I2S->CR2 = SPI_CR2_TXDMAEN; 169 | 170 | // Now Enable I2S 171 | CODEC_I2S->I2SCFGR|=SPI_I2SCFGR_I2SE; 172 | } 173 | 174 | void codec_writeReg(uint8_t addr, uint8_t data) 175 | { 176 | txbuf[0]=addr; 177 | txbuf[1]=data; 178 | i2cMasterTransmitTimeout(&I2CD1, CS43L22_ADDR, txbuf, 2, NULL, 0, MS2ST(4)); 179 | } 180 | 181 | uint8_t codec_readReg(uint8_t addr) 182 | { 183 | txbuf[0]=addr; 184 | i2cMasterTransmitTimeout(&I2CD1, CS43L22_ADDR, txbuf, 1, rxbuf, 2, MS2ST(4)); 185 | return rxbuf[0]; 186 | } 187 | 188 | void codec_pwrCtl(uint8_t pwr) 189 | { 190 | if (pwr) 191 | codec_writeReg(0x02, 0x9E); // Powered up 192 | else 193 | codec_writeReg(0x02, 0x01); // Powered down 194 | } 195 | 196 | void codec_muteCtl(uint8_t mute) 197 | { 198 | if (mute) 199 | codec_writeReg(0x04, 0xFF); // Headphone channels are always OFF. Speaker channels are always OFF. 200 | else 201 | codec_writeReg(0x04, 0xAF); // Headphone channels are always ON. Speaker channels are always OFF. 202 | } 203 | 204 | void codec_volCtl(uint8_t vol) 205 | { 206 | /* 207 | * set volume from 0:-115.5 dB to 255:+12dB 208 | * Default is 231: 0dB 209 | */ 210 | if (vol > 0xE6) 211 | { 212 | codec_writeReg(0x20, vol-0xE7); 213 | codec_writeReg(0x21, vol-0xE7); 214 | } 215 | else 216 | { 217 | codec_writeReg(0x20, vol+0x19); 218 | codec_writeReg(0x21, vol+0x19); 219 | } 220 | } 221 | 222 | void codec_selectAudioSource(uint8_t src) 223 | { 224 | switch (src) { 225 | case CODEC_AUDIOSRC_DIGITAL: 226 | // Disable all pass through channels 227 | codec_writeReg(0x0E, 0x04); 228 | break; 229 | 230 | case CODEC_AUDIOSRC_MIC: 231 | // Select AIN4A/B for pass through 232 | codec_writeReg(0x08, 0x08); 233 | codec_writeReg(0x09, 0x08); 234 | codec_writeReg(0x0E, 0xC4); 235 | break; 236 | 237 | case CODEC_AUDIOSRC_FMRADIO: 238 | // Select AIN2A/B for pass through 239 | codec_writeReg(0x08, 0x02); 240 | codec_writeReg(0x09, 0x02); 241 | codec_writeReg(0x0E, 0xC4); 242 | break; 243 | } 244 | } 245 | 246 | // Send data to the codec via I2S 247 | void codec_audio_send(void* txbuf, size_t n) 248 | { 249 | dmaStreamSetMemory0(i2sdma, txbuf); 250 | dmaStreamSetTransactionSize(i2sdma, n); 251 | dmaStreamSetMode(i2sdma, i2stxdmamode | STM32_DMA_CR_MINC); 252 | dmaStreamClearInterrupt(i2sdma); 253 | dmaStreamEnable(i2sdma); 254 | } 255 | 256 | void codec_pauseResumePlayback(uint8_t pause) 257 | { 258 | if (pause) { 259 | codec_muteCtl(1); 260 | codec_pwrCtl(0); 261 | 262 | CODEC_I2S->CR2=0; 263 | 264 | } else { 265 | codec_pwrCtl(1); 266 | 267 | CODEC_I2S->CR2=SPI_CR2_TXDMAEN; 268 | 269 | codec_muteCtl(0); 270 | } 271 | } 272 | 273 | void codec_sendBeep(void) 274 | { 275 | codec_writeReg(0x1E, 0x00); 276 | codec_writeReg(0x1E, 0x40); 277 | } 278 | -------------------------------------------------------------------------------- /halconf.h: -------------------------------------------------------------------------------- 1 | /* 2 | ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | /** 18 | * @file templates/halconf.h 19 | * @brief HAL configuration header. 20 | * @details HAL configuration file, this file allows to enable or disable the 21 | * various device drivers from your application. You may also use 22 | * this file in order to override the device drivers default settings. 23 | * 24 | * @addtogroup HAL_CONF 25 | * @{ 26 | */ 27 | 28 | #ifndef _HALCONF_H_ 29 | #define _HALCONF_H_ 30 | 31 | #include "mcuconf.h" 32 | 33 | /** 34 | * @brief Enables the TM subsystem. 35 | */ 36 | #if !defined(HAL_USE_TM) || defined(__DOXYGEN__) 37 | #define HAL_USE_TM FALSE 38 | #endif 39 | 40 | /** 41 | * @brief Enables the PAL subsystem. 42 | */ 43 | #if !defined(HAL_USE_PAL) || defined(__DOXYGEN__) 44 | #define HAL_USE_PAL TRUE 45 | #endif 46 | 47 | /** 48 | * @brief Enables the ADC subsystem. 49 | */ 50 | #if !defined(HAL_USE_ADC) || defined(__DOXYGEN__) 51 | #define HAL_USE_ADC TRUE 52 | #endif 53 | 54 | /** 55 | * @brief Enables the CAN subsystem. 56 | */ 57 | #if !defined(HAL_USE_CAN) || defined(__DOXYGEN__) 58 | #define HAL_USE_CAN FALSE 59 | #endif 60 | 61 | /** 62 | * @brief Enables the EXT subsystem. 63 | */ 64 | #if !defined(HAL_USE_EXT) || defined(__DOXYGEN__) 65 | #define HAL_USE_EXT FALSE 66 | #endif 67 | 68 | /** 69 | * @brief Enables the GPT subsystem. 70 | */ 71 | #if !defined(HAL_USE_GPT) || defined(__DOXYGEN__) 72 | #define HAL_USE_GPT FALSE 73 | #endif 74 | 75 | /** 76 | * @brief Enables the I2C subsystem. 77 | */ 78 | #if !defined(HAL_USE_I2C) || defined(__DOXYGEN__) 79 | #define HAL_USE_I2C TRUE 80 | #endif 81 | 82 | /** 83 | * @brief Enables the ICU subsystem. 84 | */ 85 | #if !defined(HAL_USE_ICU) || defined(__DOXYGEN__) 86 | #define HAL_USE_ICU FALSE 87 | #endif 88 | 89 | /** 90 | * @brief Enables the MAC subsystem. 91 | */ 92 | #if !defined(HAL_USE_MAC) || defined(__DOXYGEN__) 93 | #define HAL_USE_MAC FALSE 94 | #endif 95 | 96 | /** 97 | * @brief Enables the MMC_SPI subsystem. 98 | */ 99 | #if !defined(HAL_USE_MMC_SPI) || defined(__DOXYGEN__) 100 | #define HAL_USE_MMC_SPI TRUE 101 | #endif 102 | 103 | /** 104 | * @brief Enables the PWM subsystem. 105 | */ 106 | #if !defined(HAL_USE_PWM) || defined(__DOXYGEN__) 107 | #define HAL_USE_PWM TRUE 108 | #endif 109 | 110 | /** 111 | * @brief Enables the RTC subsystem. 112 | */ 113 | #if !defined(HAL_USE_RTC) || defined(__DOXYGEN__) 114 | #define HAL_USE_RTC FALSE 115 | #endif 116 | 117 | /** 118 | * @brief Enables the SDC subsystem. 119 | */ 120 | #if !defined(HAL_USE_SDC) || defined(__DOXYGEN__) 121 | #define HAL_USE_SDC FALSE 122 | #endif 123 | 124 | /** 125 | * @brief Enables the SERIAL subsystem. 126 | */ 127 | #if !defined(HAL_USE_SERIAL) || defined(__DOXYGEN__) 128 | #define HAL_USE_SERIAL TRUE 129 | #endif 130 | 131 | /** 132 | * @brief Enables the SERIAL over USB subsystem. 133 | */ 134 | #if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__) 135 | #define HAL_USE_SERIAL_USB TRUE 136 | #endif 137 | 138 | /** 139 | * @brief Enables the SPI subsystem. 140 | */ 141 | #if !defined(HAL_USE_SPI) || defined(__DOXYGEN__) 142 | #define HAL_USE_SPI TRUE 143 | #endif 144 | 145 | /** 146 | * @brief Enables the UART subsystem. 147 | */ 148 | #if !defined(HAL_USE_UART) || defined(__DOXYGEN__) 149 | #define HAL_USE_UART FALSE 150 | #endif 151 | 152 | /** 153 | * @brief Enables the USB subsystem. 154 | */ 155 | #if !defined(HAL_USE_USB) || defined(__DOXYGEN__) 156 | #define HAL_USE_USB TRUE 157 | #endif 158 | 159 | /*===========================================================================*/ 160 | /* ADC driver related settings. */ 161 | /*===========================================================================*/ 162 | 163 | /** 164 | * @brief Enables synchronous APIs. 165 | * @note Disabling this option saves both code and data space. 166 | */ 167 | #if !defined(ADC_USE_WAIT) || defined(__DOXYGEN__) 168 | #define ADC_USE_WAIT TRUE 169 | #endif 170 | 171 | /** 172 | * @brief Enables the @p adcAcquireBus() and @p adcReleaseBus() APIs. 173 | * @note Disabling this option saves both code and data space. 174 | */ 175 | #if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) 176 | #define ADC_USE_MUTUAL_EXCLUSION TRUE 177 | #endif 178 | 179 | /*===========================================================================*/ 180 | /* CAN driver related settings. */ 181 | /*===========================================================================*/ 182 | 183 | /** 184 | * @brief Sleep mode related APIs inclusion switch. 185 | */ 186 | #if !defined(CAN_USE_SLEEP_MODE) || defined(__DOXYGEN__) 187 | #define CAN_USE_SLEEP_MODE TRUE 188 | #endif 189 | 190 | /*===========================================================================*/ 191 | /* I2C driver related settings. */ 192 | /*===========================================================================*/ 193 | 194 | /** 195 | * @brief Enables the mutual exclusion APIs on the I2C bus. 196 | */ 197 | #if !defined(I2C_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) 198 | #define I2C_USE_MUTUAL_EXCLUSION TRUE 199 | #endif 200 | 201 | /*===========================================================================*/ 202 | /* MAC driver related settings. */ 203 | /*===========================================================================*/ 204 | 205 | /** 206 | * @brief Enables an event sources for incoming packets. 207 | */ 208 | #if !defined(MAC_USE_ZERO_COPY) || defined(__DOXYGEN__) 209 | #define MAC_USE_ZERO_COPY FALSE 210 | #endif 211 | 212 | /** 213 | * @brief Enables an event sources for incoming packets. 214 | */ 215 | #if !defined(MAC_USE_EVENTS) || defined(__DOXYGEN__) 216 | #define MAC_USE_EVENTS TRUE 217 | #endif 218 | 219 | /*===========================================================================*/ 220 | /* MMC_SPI driver related settings. */ 221 | /*===========================================================================*/ 222 | 223 | /** 224 | * @brief Delays insertions. 225 | * @details If enabled this options inserts delays into the MMC waiting 226 | * routines releasing some extra CPU time for the threads with 227 | * lower priority, this may slow down the driver a bit however. 228 | * This option is recommended also if the SPI driver does not 229 | * use a DMA channel and heavily loads the CPU. 230 | */ 231 | #if !defined(MMC_NICE_WAITING) || defined(__DOXYGEN__) 232 | #define MMC_NICE_WAITING TRUE 233 | #endif 234 | 235 | /*===========================================================================*/ 236 | /* SDC driver related settings. */ 237 | /*===========================================================================*/ 238 | 239 | /** 240 | * @brief Number of initialization attempts before rejecting the card. 241 | * @note Attempts are performed at 10mS intervals. 242 | */ 243 | #if !defined(SDC_INIT_RETRY) || defined(__DOXYGEN__) 244 | #define SDC_INIT_RETRY 100 245 | #endif 246 | 247 | /** 248 | * @brief Include support for MMC cards. 249 | * @note MMC support is not yet implemented so this option must be kept 250 | * at @p FALSE. 251 | */ 252 | #if !defined(SDC_MMC_SUPPORT) || defined(__DOXYGEN__) 253 | #define SDC_MMC_SUPPORT FALSE 254 | #endif 255 | 256 | /** 257 | * @brief Delays insertions. 258 | * @details If enabled this options inserts delays into the MMC waiting 259 | * routines releasing some extra CPU time for the threads with 260 | * lower priority, this may slow down the driver a bit however. 261 | */ 262 | #if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__) 263 | #define SDC_NICE_WAITING TRUE 264 | #endif 265 | 266 | /*===========================================================================*/ 267 | /* SERIAL driver related settings. */ 268 | /*===========================================================================*/ 269 | 270 | /** 271 | * @brief Default bit rate. 272 | * @details Configuration parameter, this is the baud rate selected for the 273 | * default configuration. 274 | */ 275 | #if !defined(SERIAL_DEFAULT_BITRATE) || defined(__DOXYGEN__) 276 | #define SERIAL_DEFAULT_BITRATE 38400 277 | #endif 278 | 279 | /** 280 | * @brief Serial buffers size. 281 | * @details Configuration parameter, you can change the depth of the queue 282 | * buffers depending on the requirements of your application. 283 | * @note The default is 64 bytes for both the transmission and receive 284 | * buffers. 285 | */ 286 | #if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__) 287 | #define SERIAL_BUFFERS_SIZE 256 288 | #endif 289 | 290 | /*===========================================================================*/ 291 | /* SPI driver related settings. */ 292 | /*===========================================================================*/ 293 | 294 | /** 295 | * @brief Enables synchronous APIs. 296 | * @note Disabling this option saves both code and data space. 297 | */ 298 | #if !defined(SPI_USE_WAIT) || defined(__DOXYGEN__) 299 | #define SPI_USE_WAIT TRUE 300 | #endif 301 | 302 | /** 303 | * @brief Enables the @p spiAcquireBus() and @p spiReleaseBus() APIs. 304 | * @note Disabling this option saves both code and data space. 305 | */ 306 | #if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) 307 | #define SPI_USE_MUTUAL_EXCLUSION TRUE 308 | #endif 309 | 310 | #endif /* _HALCONF_H_ */ 311 | 312 | /** @} */ 313 | -------------------------------------------------------------------------------- /usbcfg.c: -------------------------------------------------------------------------------- 1 | /* 2 | ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include "ch.h" 18 | #include "hal.h" 19 | 20 | /* 21 | * Endpoints to be used for USBD1. 22 | */ 23 | #define USBD1_DATA_REQUEST_EP 1 24 | #define USBD1_DATA_AVAILABLE_EP 1 25 | #define USBD1_INTERRUPT_REQUEST_EP 2 26 | 27 | /* 28 | * USB Device Descriptor. 29 | */ 30 | static const uint8_t vcom_device_descriptor_data[18] = { 31 | USB_DESC_DEVICE (0x0110, /* bcdUSB (1.1). */ 32 | 0x02, /* bDeviceClass (CDC). */ 33 | 0x00, /* bDeviceSubClass. */ 34 | 0x00, /* bDeviceProtocol. */ 35 | 0x40, /* bMaxPacketSize. */ 36 | 0x0483, /* idVendor (ST). */ 37 | 0x5740, /* idProduct. */ 38 | 0x0200, /* bcdDevice. */ 39 | 1, /* iManufacturer. */ 40 | 2, /* iProduct. */ 41 | 3, /* iSerialNumber. */ 42 | 1) /* bNumConfigurations. */ 43 | }; 44 | 45 | /* 46 | * Device Descriptor wrapper. 47 | */ 48 | static const USBDescriptor vcom_device_descriptor = { 49 | sizeof vcom_device_descriptor_data, 50 | vcom_device_descriptor_data 51 | }; 52 | 53 | /* Configuration Descriptor tree for a CDC.*/ 54 | static const uint8_t vcom_configuration_descriptor_data[67] = { 55 | /* Configuration Descriptor.*/ 56 | USB_DESC_CONFIGURATION(67, /* wTotalLength. */ 57 | 0x02, /* bNumInterfaces. */ 58 | 0x01, /* bConfigurationValue. */ 59 | 0, /* iConfiguration. */ 60 | 0xC0, /* bmAttributes (self powered). */ 61 | 50), /* bMaxPower (100mA). */ 62 | /* Interface Descriptor.*/ 63 | USB_DESC_INTERFACE (0x00, /* bInterfaceNumber. */ 64 | 0x00, /* bAlternateSetting. */ 65 | 0x01, /* bNumEndpoints. */ 66 | 0x02, /* bInterfaceClass (Communications 67 | Interface Class, CDC section 68 | 4.2). */ 69 | 0x02, /* bInterfaceSubClass (Abstract 70 | Control Model, CDC section 4.3). */ 71 | 0x01, /* bInterfaceProtocol (AT commands, 72 | CDC section 4.4). */ 73 | 0), /* iInterface. */ 74 | /* Header Functional Descriptor (CDC section 5.2.3).*/ 75 | USB_DESC_BYTE (5), /* bLength. */ 76 | USB_DESC_BYTE (0x24), /* bDescriptorType (CS_INTERFACE). */ 77 | USB_DESC_BYTE (0x00), /* bDescriptorSubtype (Header 78 | Functional Descriptor. */ 79 | USB_DESC_BCD (0x0110), /* bcdCDC. */ 80 | /* Call Management Functional Descriptor. */ 81 | USB_DESC_BYTE (5), /* bFunctionLength. */ 82 | USB_DESC_BYTE (0x24), /* bDescriptorType (CS_INTERFACE). */ 83 | USB_DESC_BYTE (0x01), /* bDescriptorSubtype (Call Management 84 | Functional Descriptor). */ 85 | USB_DESC_BYTE (0x00), /* bmCapabilities (D0+D1). */ 86 | USB_DESC_BYTE (0x01), /* bDataInterface. */ 87 | /* ACM Functional Descriptor.*/ 88 | USB_DESC_BYTE (4), /* bFunctionLength. */ 89 | USB_DESC_BYTE (0x24), /* bDescriptorType (CS_INTERFACE). */ 90 | USB_DESC_BYTE (0x02), /* bDescriptorSubtype (Abstract 91 | Control Management Descriptor). */ 92 | USB_DESC_BYTE (0x02), /* bmCapabilities. */ 93 | /* Union Functional Descriptor.*/ 94 | USB_DESC_BYTE (5), /* bFunctionLength. */ 95 | USB_DESC_BYTE (0x24), /* bDescriptorType (CS_INTERFACE). */ 96 | USB_DESC_BYTE (0x06), /* bDescriptorSubtype (Union 97 | Functional Descriptor). */ 98 | USB_DESC_BYTE (0x00), /* bMasterInterface (Communication 99 | Class Interface). */ 100 | USB_DESC_BYTE (0x01), /* bSlaveInterface0 (Data Class 101 | Interface). */ 102 | /* Endpoint 2 Descriptor.*/ 103 | USB_DESC_ENDPOINT (USBD1_INTERRUPT_REQUEST_EP|0x80, 104 | 0x03, /* bmAttributes (Interrupt). */ 105 | 0x0008, /* wMaxPacketSize. */ 106 | 0xFF), /* bInterval. */ 107 | /* Interface Descriptor.*/ 108 | USB_DESC_INTERFACE (0x01, /* bInterfaceNumber. */ 109 | 0x00, /* bAlternateSetting. */ 110 | 0x02, /* bNumEndpoints. */ 111 | 0x0A, /* bInterfaceClass (Data Class 112 | Interface, CDC section 4.5). */ 113 | 0x00, /* bInterfaceSubClass (CDC section 114 | 4.6). */ 115 | 0x00, /* bInterfaceProtocol (CDC section 116 | 4.7). */ 117 | 0x00), /* iInterface. */ 118 | /* Endpoint 3 Descriptor.*/ 119 | USB_DESC_ENDPOINT (USBD1_DATA_AVAILABLE_EP, /* bEndpointAddress.*/ 120 | 0x02, /* bmAttributes (Bulk). */ 121 | 0x0040, /* wMaxPacketSize. */ 122 | 0x00), /* bInterval. */ 123 | /* Endpoint 1 Descriptor.*/ 124 | USB_DESC_ENDPOINT (USBD1_DATA_REQUEST_EP|0x80, /* bEndpointAddress.*/ 125 | 0x02, /* bmAttributes (Bulk). */ 126 | 0x0040, /* wMaxPacketSize. */ 127 | 0x00) /* bInterval. */ 128 | }; 129 | 130 | /* 131 | * Configuration Descriptor wrapper. 132 | */ 133 | static const USBDescriptor vcom_configuration_descriptor = { 134 | sizeof vcom_configuration_descriptor_data, 135 | vcom_configuration_descriptor_data 136 | }; 137 | 138 | /* 139 | * U.S. English language identifier. 140 | */ 141 | static const uint8_t vcom_string0[] = { 142 | USB_DESC_BYTE(4), /* bLength. */ 143 | USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */ 144 | USB_DESC_WORD(0x0409) /* wLANGID (U.S. English). */ 145 | }; 146 | 147 | /* 148 | * Vendor string. 149 | */ 150 | static const uint8_t vcom_string1[] = { 151 | USB_DESC_BYTE(38), /* bLength. */ 152 | USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */ 153 | 'S', 0, 'T', 0, 'M', 0, 'i', 0, 'c', 0, 'r', 0, 'o', 0, 'e', 0, 154 | 'l', 0, 'e', 0, 'c', 0, 't', 0, 'r', 0, 'o', 0, 'n', 0, 'i', 0, 155 | 'c', 0, 's', 0 156 | }; 157 | 158 | /* 159 | * Device Description string. 160 | */ 161 | static const uint8_t vcom_string2[] = { 162 | USB_DESC_BYTE(56), /* bLength. */ 163 | USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */ 164 | 'C', 0, 'h', 0, 'i', 0, 'b', 0, 'i', 0, 'O', 0, 'S', 0, '/', 0, 165 | 'R', 0, 'T', 0, ' ', 0, 'V', 0, 'i', 0, 'r', 0, 't', 0, 'u', 0, 166 | 'a', 0, 'l', 0, ' ', 0, 'C', 0, 'O', 0, 'M', 0, ' ', 0, 'P', 0, 167 | 'o', 0, 'r', 0, 't', 0 168 | }; 169 | 170 | /* 171 | * Serial Number string. 172 | */ 173 | static const uint8_t vcom_string3[] = { 174 | USB_DESC_BYTE(8), /* bLength. */ 175 | USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */ 176 | '0' + CH_KERNEL_MAJOR, 0, 177 | '0' + CH_KERNEL_MINOR, 0, 178 | '0' + CH_KERNEL_PATCH, 0 179 | }; 180 | 181 | /* 182 | * Strings wrappers array. 183 | */ 184 | static const USBDescriptor vcom_strings[] = { 185 | {sizeof vcom_string0, vcom_string0}, 186 | {sizeof vcom_string1, vcom_string1}, 187 | {sizeof vcom_string2, vcom_string2}, 188 | {sizeof vcom_string3, vcom_string3} 189 | }; 190 | 191 | /* 192 | * Handles the GET_DESCRIPTOR callback. All required descriptors must be 193 | * handled here. 194 | */ 195 | static const USBDescriptor *get_descriptor(USBDriver *usbp, 196 | uint8_t dtype, 197 | uint8_t dindex, 198 | uint16_t lang) { 199 | 200 | (void)usbp; 201 | (void)lang; 202 | switch (dtype) { 203 | case USB_DESCRIPTOR_DEVICE: 204 | return &vcom_device_descriptor; 205 | case USB_DESCRIPTOR_CONFIGURATION: 206 | return &vcom_configuration_descriptor; 207 | case USB_DESCRIPTOR_STRING: 208 | if (dindex < 4) 209 | return &vcom_strings[dindex]; 210 | } 211 | return NULL; 212 | } 213 | 214 | /** 215 | * @brief IN EP1 state. 216 | */ 217 | static USBInEndpointState ep1instate; 218 | 219 | /** 220 | * @brief OUT EP1 state. 221 | */ 222 | static USBOutEndpointState ep1outstate; 223 | 224 | /** 225 | * @brief EP1 initialization structure (both IN and OUT). 226 | */ 227 | static const USBEndpointConfig ep1config = { 228 | USB_EP_MODE_TYPE_BULK, 229 | NULL, 230 | sduDataTransmitted, 231 | sduDataReceived, 232 | 0x0040, 233 | 0x0040, 234 | &ep1instate, 235 | &ep1outstate, 236 | 2, 237 | NULL 238 | }; 239 | 240 | /** 241 | * @brief IN EP2 state. 242 | */ 243 | static USBInEndpointState ep2instate; 244 | 245 | /** 246 | * @brief EP2 initialization structure (IN only). 247 | */ 248 | static const USBEndpointConfig ep2config = { 249 | USB_EP_MODE_TYPE_INTR, 250 | NULL, 251 | sduInterruptTransmitted, 252 | NULL, 253 | 0x0010, 254 | 0x0000, 255 | &ep2instate, 256 | NULL, 257 | 1, 258 | NULL 259 | }; 260 | 261 | /* 262 | * Handles the USB driver global events. 263 | */ 264 | static void usb_event(USBDriver *usbp, usbevent_t event) { 265 | extern SerialUSBDriver SDU1; 266 | 267 | switch (event) { 268 | case USB_EVENT_RESET: 269 | return; 270 | case USB_EVENT_ADDRESS: 271 | return; 272 | case USB_EVENT_CONFIGURED: 273 | chSysLockFromIsr(); 274 | 275 | /* Enables the endpoints specified into the configuration. 276 | Note, this callback is invoked from an ISR so I-Class functions 277 | must be used.*/ 278 | usbInitEndpointI(usbp, USBD1_DATA_REQUEST_EP, &ep1config); 279 | usbInitEndpointI(usbp, USBD1_INTERRUPT_REQUEST_EP, &ep2config); 280 | 281 | /* Resetting the state of the CDC subsystem.*/ 282 | sduConfigureHookI(&SDU1); 283 | 284 | chSysUnlockFromIsr(); 285 | return; 286 | case USB_EVENT_SUSPEND: 287 | return; 288 | case USB_EVENT_WAKEUP: 289 | return; 290 | case USB_EVENT_STALLED: 291 | return; 292 | } 293 | return; 294 | } 295 | 296 | /* 297 | * USB driver configuration. 298 | */ 299 | const USBConfig usbcfg = { 300 | usb_event, 301 | get_descriptor, 302 | sduRequestsHook, 303 | NULL 304 | }; 305 | 306 | /* 307 | * Serial over USB driver configuration. 308 | */ 309 | const SerialUSBConfig serusbcfg = { 310 | &USBD1, 311 | USBD1_DATA_REQUEST_EP, 312 | USBD1_DATA_AVAILABLE_EP, 313 | USBD1_INTERRUPT_REQUEST_EP 314 | }; 315 | -------------------------------------------------------------------------------- /mcuconf.h: -------------------------------------------------------------------------------- 1 | /* 2 | ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | /* 18 | * STM32F4xx drivers configuration. 19 | * The following settings override the default settings present in 20 | * the various device driver implementation headers. 21 | * Note that the settings for each driver only have effect if the whole 22 | * driver is enabled in halconf.h. 23 | * 24 | * IRQ priorities: 25 | * 15...0 Lowest...Highest. 26 | * 27 | * DMA priorities: 28 | * 0...3 Lowest...Highest. 29 | */ 30 | 31 | #define STM32F4xx_MCUCONF 32 | 33 | /* 34 | * HAL driver system settings. 35 | */ 36 | #define STM32_NO_INIT FALSE 37 | #define STM32_HSI_ENABLED TRUE 38 | #define STM32_LSI_ENABLED TRUE 39 | #define STM32_HSE_ENABLED TRUE 40 | #define STM32_LSE_ENABLED FALSE 41 | #define STM32_CLOCK48_REQUIRED TRUE 42 | #define STM32_SW STM32_SW_PLL 43 | #define STM32_PLLSRC STM32_PLLSRC_HSE 44 | #define STM32_PLLM_VALUE 8 45 | #define STM32_PLLN_VALUE 336 46 | #define STM32_PLLP_VALUE 2 47 | #define STM32_PLLQ_VALUE 7 48 | #define STM32_HPRE STM32_HPRE_DIV1 49 | #define STM32_PPRE1 STM32_PPRE1_DIV4 50 | #define STM32_PPRE2 STM32_PPRE2_DIV2 51 | #define STM32_RTCSEL STM32_RTCSEL_LSI 52 | #define STM32_RTCPRE_VALUE 8 53 | #define STM32_MCO1SEL STM32_MCO1SEL_HSI 54 | #define STM32_MCO1PRE STM32_MCO1PRE_DIV1 55 | #define STM32_MCO2SEL STM32_MCO2SEL_SYSCLK 56 | #define STM32_MCO2PRE STM32_MCO2PRE_DIV5 57 | #define STM32_I2SSRC STM32_I2SSRC_PLLI2S 58 | #define STM32_PLLI2SN_VALUE 271 59 | #define STM32_PLLI2SR_VALUE 2 60 | #define STM32_PVD_ENABLE FALSE 61 | #define STM32_PLS STM32_PLS_LEV0 62 | #define STM32_BKPRAM_ENABLE FALSE 63 | 64 | /* 65 | * ADC driver system settings. 66 | */ 67 | #define STM32_ADC_ADCPRE ADC_CCR_ADCPRE_DIV4 68 | #define STM32_ADC_USE_ADC1 TRUE 69 | #define STM32_ADC_USE_ADC2 FALSE 70 | #define STM32_ADC_USE_ADC3 FALSE 71 | #define STM32_ADC_ADC1_DMA_STREAM STM32_DMA_STREAM_ID(2, 4) 72 | #define STM32_ADC_ADC2_DMA_STREAM STM32_DMA_STREAM_ID(2, 2) 73 | #define STM32_ADC_ADC3_DMA_STREAM STM32_DMA_STREAM_ID(2, 1) 74 | #define STM32_ADC_ADC1_DMA_PRIORITY 2 75 | #define STM32_ADC_ADC2_DMA_PRIORITY 2 76 | #define STM32_ADC_ADC3_DMA_PRIORITY 2 77 | #define STM32_ADC_IRQ_PRIORITY 6 78 | #define STM32_ADC_ADC1_DMA_IRQ_PRIORITY 6 79 | #define STM32_ADC_ADC2_DMA_IRQ_PRIORITY 6 80 | #define STM32_ADC_ADC3_DMA_IRQ_PRIORITY 6 81 | 82 | /* 83 | * CAN driver system settings. 84 | */ 85 | #define STM32_CAN_USE_CAN1 FALSE 86 | #define STM32_CAN_USE_CAN2 FALSE 87 | #define STM32_CAN_CAN1_IRQ_PRIORITY 11 88 | #define STM32_CAN_CAN2_IRQ_PRIORITY 11 89 | 90 | /* 91 | * EXT driver system settings. 92 | */ 93 | #define STM32_EXT_EXTI0_IRQ_PRIORITY 6 94 | #define STM32_EXT_EXTI1_IRQ_PRIORITY 6 95 | #define STM32_EXT_EXTI2_IRQ_PRIORITY 6 96 | #define STM32_EXT_EXTI3_IRQ_PRIORITY 6 97 | #define STM32_EXT_EXTI4_IRQ_PRIORITY 6 98 | #define STM32_EXT_EXTI5_9_IRQ_PRIORITY 6 99 | #define STM32_EXT_EXTI10_15_IRQ_PRIORITY 6 100 | #define STM32_EXT_EXTI16_IRQ_PRIORITY 6 101 | #define STM32_EXT_EXTI17_IRQ_PRIORITY 15 102 | #define STM32_EXT_EXTI18_IRQ_PRIORITY 6 103 | #define STM32_EXT_EXTI19_IRQ_PRIORITY 6 104 | #define STM32_EXT_EXTI20_IRQ_PRIORITY 6 105 | #define STM32_EXT_EXTI21_IRQ_PRIORITY 15 106 | #define STM32_EXT_EXTI22_IRQ_PRIORITY 15 107 | 108 | /* 109 | * GPT driver system settings. 110 | */ 111 | #define STM32_GPT_USE_TIM1 FALSE 112 | #define STM32_GPT_USE_TIM2 FALSE 113 | #define STM32_GPT_USE_TIM3 FALSE 114 | #define STM32_GPT_USE_TIM4 FALSE 115 | #define STM32_GPT_USE_TIM5 FALSE 116 | #define STM32_GPT_USE_TIM6 FALSE 117 | #define STM32_GPT_USE_TIM7 FALSE 118 | #define STM32_GPT_USE_TIM8 FALSE 119 | #define STM32_GPT_USE_TIM9 FALSE 120 | #define STM32_GPT_USE_TIM11 FALSE 121 | #define STM32_GPT_USE_TIM12 FALSE 122 | #define STM32_GPT_USE_TIM14 FALSE 123 | #define STM32_GPT_TIM1_IRQ_PRIORITY 7 124 | #define STM32_GPT_TIM2_IRQ_PRIORITY 7 125 | #define STM32_GPT_TIM3_IRQ_PRIORITY 7 126 | #define STM32_GPT_TIM4_IRQ_PRIORITY 7 127 | #define STM32_GPT_TIM5_IRQ_PRIORITY 7 128 | #define STM32_GPT_TIM6_IRQ_PRIORITY 7 129 | #define STM32_GPT_TIM7_IRQ_PRIORITY 7 130 | #define STM32_GPT_TIM8_IRQ_PRIORITY 7 131 | #define STM32_GPT_TIM9_IRQ_PRIORITY 7 132 | #define STM32_GPT_TIM11_IRQ_PRIORITY 7 133 | #define STM32_GPT_TIM12_IRQ_PRIORITY 7 134 | #define STM32_GPT_TIM14_IRQ_PRIORITY 7 135 | 136 | /* 137 | * I2C driver system settings. 138 | */ 139 | #define STM32_I2C_USE_I2C1 TRUE 140 | #define STM32_I2C_USE_I2C2 FALSE 141 | #define STM32_I2C_USE_I2C3 FALSE 142 | #define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 0) 143 | #define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6) 144 | #define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) 145 | #define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7) 146 | #define STM32_I2C_I2C3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) 147 | #define STM32_I2C_I2C3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) 148 | #define STM32_I2C_I2C1_IRQ_PRIORITY 5 149 | #define STM32_I2C_I2C2_IRQ_PRIORITY 5 150 | #define STM32_I2C_I2C3_IRQ_PRIORITY 5 151 | #define STM32_I2C_I2C1_DMA_PRIORITY 3 152 | #define STM32_I2C_I2C2_DMA_PRIORITY 3 153 | #define STM32_I2C_I2C3_DMA_PRIORITY 3 154 | #define STM32_I2C_I2C1_DMA_ERROR_HOOK() chSysHalt() 155 | #define STM32_I2C_I2C2_DMA_ERROR_HOOK() chSysHalt() 156 | #define STM32_I2C_I2C3_DMA_ERROR_HOOK() chSysHalt() 157 | 158 | /* 159 | * ICU driver system settings. 160 | */ 161 | #define STM32_ICU_USE_TIM1 FALSE 162 | #define STM32_ICU_USE_TIM2 FALSE 163 | #define STM32_ICU_USE_TIM3 FALSE 164 | #define STM32_ICU_USE_TIM4 FALSE 165 | #define STM32_ICU_USE_TIM5 FALSE 166 | #define STM32_ICU_USE_TIM8 FALSE 167 | #define STM32_ICU_USE_TIM9 FALSE 168 | #define STM32_ICU_TIM1_IRQ_PRIORITY 7 169 | #define STM32_ICU_TIM2_IRQ_PRIORITY 7 170 | #define STM32_ICU_TIM3_IRQ_PRIORITY 7 171 | #define STM32_ICU_TIM4_IRQ_PRIORITY 7 172 | #define STM32_ICU_TIM5_IRQ_PRIORITY 7 173 | #define STM32_ICU_TIM8_IRQ_PRIORITY 7 174 | #define STM32_ICU_TIM9_IRQ_PRIORITY 7 175 | 176 | /* 177 | * MAC driver system settings. 178 | */ 179 | #define STM32_MAC_TRANSMIT_BUFFERS 2 180 | #define STM32_MAC_RECEIVE_BUFFERS 4 181 | #define STM32_MAC_BUFFERS_SIZE 1522 182 | #define STM32_MAC_PHY_TIMEOUT 100 183 | #define STM32_MAC_ETH1_CHANGE_PHY_STATE TRUE 184 | #define STM32_MAC_ETH1_IRQ_PRIORITY 13 185 | #define STM32_MAC_IP_CHECKSUM_OFFLOAD 0 186 | 187 | /* 188 | * PWM driver system settings. 189 | */ 190 | #define STM32_PWM_USE_ADVANCED FALSE 191 | #define STM32_PWM_USE_TIM1 FALSE 192 | #define STM32_PWM_USE_TIM2 FALSE 193 | #define STM32_PWM_USE_TIM3 FALSE 194 | #define STM32_PWM_USE_TIM4 TRUE 195 | #define STM32_PWM_USE_TIM5 FALSE 196 | #define STM32_PWM_USE_TIM8 FALSE 197 | #define STM32_PWM_USE_TIM9 FALSE 198 | #define STM32_PWM_TIM1_IRQ_PRIORITY 7 199 | #define STM32_PWM_TIM2_IRQ_PRIORITY 7 200 | #define STM32_PWM_TIM3_IRQ_PRIORITY 7 201 | #define STM32_PWM_TIM4_IRQ_PRIORITY 7 202 | #define STM32_PWM_TIM5_IRQ_PRIORITY 7 203 | #define STM32_PWM_TIM8_IRQ_PRIORITY 7 204 | #define STM32_PWM_TIM9_IRQ_PRIORITY 7 205 | 206 | /* 207 | * SERIAL driver system settings. 208 | */ 209 | #define STM32_SERIAL_USE_USART1 FALSE 210 | #define STM32_SERIAL_USE_USART2 TRUE 211 | #define STM32_SERIAL_USE_USART3 TRUE 212 | #define STM32_SERIAL_USE_UART4 FALSE 213 | #define STM32_SERIAL_USE_UART5 FALSE 214 | #define STM32_SERIAL_USE_USART6 FALSE 215 | #define STM32_SERIAL_USART1_PRIORITY 12 216 | #define STM32_SERIAL_USART2_PRIORITY 12 217 | #define STM32_SERIAL_USART3_PRIORITY 12 218 | #define STM32_SERIAL_UART4_PRIORITY 12 219 | #define STM32_SERIAL_UART5_PRIORITY 12 220 | #define STM32_SERIAL_USART6_PRIORITY 12 221 | 222 | /* 223 | * SPI driver system settings. 224 | */ 225 | #define STM32_SPI_USE_SPI1 TRUE 226 | #define STM32_SPI_USE_SPI2 FALSE 227 | #define STM32_SPI_USE_SPI3 TRUE 228 | #define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 0) 229 | #define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 3) 230 | #define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) 231 | #define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) 232 | #define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 0) 233 | #define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7) 234 | #define STM32_SPI_SPI1_DMA_PRIORITY 1 235 | #define STM32_SPI_SPI2_DMA_PRIORITY 1 236 | #define STM32_SPI_SPI3_DMA_PRIORITY 3 237 | #define STM32_SPI_SPI1_IRQ_PRIORITY 10 238 | #define STM32_SPI_SPI2_IRQ_PRIORITY 10 239 | #define STM32_SPI_SPI3_IRQ_PRIORITY 4 240 | #define STM32_SPI_DMA_ERROR_HOOK(spip) chSysHalt() 241 | 242 | /* 243 | * UART driver system settings. 244 | */ 245 | #define STM32_UART_USE_USART1 FALSE 246 | #define STM32_UART_USE_USART2 TRUE 247 | #define STM32_UART_USE_USART3 TRUE 248 | #define STM32_UART_USE_UART4 FALSE 249 | #define STM32_UART_USE_UART5 FALSE 250 | #define STM32_UART_USE_USART6 FALSE 251 | #define STM32_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 5) 252 | #define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 7) 253 | #define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5) 254 | #define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6) 255 | #define STM32_UART_USART3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 1) 256 | #define STM32_UART_USART3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) 257 | #define STM32_UART_UART4_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) 258 | #define STM32_UART_UART4_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) 259 | #define STM32_UART_UART5_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 0) 260 | #define STM32_UART_UART5_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7) 261 | #define STM32_UART_USART6_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2) 262 | #define STM32_UART_USART6_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 7) 263 | #define STM32_UART_USART1_IRQ_PRIORITY 12 264 | #define STM32_UART_USART2_IRQ_PRIORITY 12 265 | #define STM32_UART_USART3_IRQ_PRIORITY 12 266 | #define STM32_UART_UART4_IRQ_PRIORITY 12 267 | #define STM32_UART_UART5_IRQ_PRIORITY 12 268 | #define STM32_UART_USART6_IRQ_PRIORITY 12 269 | #define STM32_UART_USART1_DMA_PRIORITY 0 270 | #define STM32_UART_USART2_DMA_PRIORITY 0 271 | #define STM32_UART_USART3_DMA_PRIORITY 0 272 | #define STM32_UART_UART4_DMA_PRIORITY 0 273 | #define STM32_UART_UART5_DMA_PRIORITY 0 274 | #define STM32_UART_USART6_DMA_PRIORITY 0 275 | #define STM32_UART_DMA_ERROR_HOOK(uartp) chSysHalt() 276 | 277 | /* 278 | * USB driver system settings. 279 | */ 280 | #define STM32_USB_USE_OTG1 TRUE 281 | #define STM32_USB_USE_OTG2 FALSE 282 | #define STM32_USB_OTG1_IRQ_PRIORITY 14 283 | #define STM32_USB_OTG2_IRQ_PRIORITY 14 284 | #define STM32_USB_OTG1_RX_FIFO_SIZE 512 285 | #define STM32_USB_OTG2_RX_FIFO_SIZE 1024 286 | #define STM32_USB_OTG_THREAD_PRIO LOWPRIO 287 | #define STM32_USB_OTG_THREAD_STACK_SIZE 128 288 | #define STM32_USB_OTGFIFO_FILL_BASEPRI 0 289 | -------------------------------------------------------------------------------- /chconf.h: -------------------------------------------------------------------------------- 1 | /* 2 | ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | /** 18 | * @file templates/chconf.h 19 | * @brief Configuration file template. 20 | * @details A copy of this file must be placed in each project directory, it 21 | * contains the application specific kernel settings. 22 | * 23 | * @addtogroup config 24 | * @details Kernel related settings and hooks. 25 | * @{ 26 | */ 27 | 28 | #ifndef _CHCONF_H_ 29 | #define _CHCONF_H_ 30 | 31 | /*===========================================================================*/ 32 | /** 33 | * @name Kernel parameters and options 34 | * @{ 35 | */ 36 | /*===========================================================================*/ 37 | 38 | /** 39 | * @brief System tick frequency. 40 | * @details Frequency of the system timer that drives the system ticks. This 41 | * setting also defines the system tick time unit. 42 | */ 43 | #if !defined(CH_FREQUENCY) || defined(__DOXYGEN__) 44 | #define CH_FREQUENCY 1000 45 | #endif 46 | 47 | /** 48 | * @brief Round robin interval. 49 | * @details This constant is the number of system ticks allowed for the 50 | * threads before preemption occurs. Setting this value to zero 51 | * disables the preemption for threads with equal priority and the 52 | * round robin becomes cooperative. Note that higher priority 53 | * threads can still preempt, the kernel is always preemptive. 54 | * 55 | * @note Disabling the round robin preemption makes the kernel more compact 56 | * and generally faster. 57 | */ 58 | #if !defined(CH_TIME_QUANTUM) || defined(__DOXYGEN__) 59 | #define CH_TIME_QUANTUM 20 60 | #endif 61 | 62 | /** 63 | * @brief Managed RAM size. 64 | * @details Size of the RAM area to be managed by the OS. If set to zero 65 | * then the whole available RAM is used. The core memory is made 66 | * available to the heap allocator and/or can be used directly through 67 | * the simplified core memory allocator. 68 | * 69 | * @note In order to let the OS manage the whole RAM the linker script must 70 | * provide the @p __heap_base__ and @p __heap_end__ symbols. 71 | * @note Requires @p CH_USE_MEMCORE. 72 | */ 73 | #if !defined(CH_MEMCORE_SIZE) || defined(__DOXYGEN__) 74 | #define CH_MEMCORE_SIZE 0 75 | #endif 76 | 77 | /** 78 | * @brief Idle thread automatic spawn suppression. 79 | * @details When this option is activated the function @p chSysInit() 80 | * does not spawn the idle thread automatically. The application has 81 | * then the responsibility to do one of the following: 82 | * - Spawn a custom idle thread at priority @p IDLEPRIO. 83 | * - Change the main() thread priority to @p IDLEPRIO then enter 84 | * an endless loop. In this scenario the @p main() thread acts as 85 | * the idle thread. 86 | * . 87 | * @note Unless an idle thread is spawned the @p main() thread must not 88 | * enter a sleep state. 89 | */ 90 | #if !defined(CH_NO_IDLE_THREAD) || defined(__DOXYGEN__) 91 | #define CH_NO_IDLE_THREAD FALSE 92 | #endif 93 | 94 | /** @} */ 95 | 96 | /*===========================================================================*/ 97 | /** 98 | * @name Performance options 99 | * @{ 100 | */ 101 | /*===========================================================================*/ 102 | 103 | /** 104 | * @brief OS optimization. 105 | * @details If enabled then time efficient rather than space efficient code 106 | * is used when two possible implementations exist. 107 | * 108 | * @note This is not related to the compiler optimization options. 109 | * @note The default is @p TRUE. 110 | */ 111 | #if !defined(CH_OPTIMIZE_SPEED) || defined(__DOXYGEN__) 112 | #define CH_OPTIMIZE_SPEED TRUE 113 | #endif 114 | 115 | /** @} */ 116 | 117 | /*===========================================================================*/ 118 | /** 119 | * @name Subsystem options 120 | * @{ 121 | */ 122 | /*===========================================================================*/ 123 | 124 | /** 125 | * @brief Threads registry APIs. 126 | * @details If enabled then the registry APIs are included in the kernel. 127 | * 128 | * @note The default is @p TRUE. 129 | */ 130 | #if !defined(CH_USE_REGISTRY) || defined(__DOXYGEN__) 131 | #define CH_USE_REGISTRY TRUE 132 | #endif 133 | 134 | /** 135 | * @brief Threads synchronization APIs. 136 | * @details If enabled then the @p chThdWait() function is included in 137 | * the kernel. 138 | * 139 | * @note The default is @p TRUE. 140 | */ 141 | #if !defined(CH_USE_WAITEXIT) || defined(__DOXYGEN__) 142 | #define CH_USE_WAITEXIT TRUE 143 | #endif 144 | 145 | /** 146 | * @brief Semaphores APIs. 147 | * @details If enabled then the Semaphores APIs are included in the kernel. 148 | * 149 | * @note The default is @p TRUE. 150 | */ 151 | #if !defined(CH_USE_SEMAPHORES) || defined(__DOXYGEN__) 152 | #define CH_USE_SEMAPHORES TRUE 153 | #endif 154 | 155 | /** 156 | * @brief Semaphores queuing mode. 157 | * @details If enabled then the threads are enqueued on semaphores by 158 | * priority rather than in FIFO order. 159 | * 160 | * @note The default is @p FALSE. Enable this if you have special requirements. 161 | * @note Requires @p CH_USE_SEMAPHORES. 162 | */ 163 | #if !defined(CH_USE_SEMAPHORES_PRIORITY) || defined(__DOXYGEN__) 164 | #define CH_USE_SEMAPHORES_PRIORITY FALSE 165 | #endif 166 | 167 | /** 168 | * @brief Atomic semaphore API. 169 | * @details If enabled then the semaphores the @p chSemSignalWait() API 170 | * is included in the kernel. 171 | * 172 | * @note The default is @p TRUE. 173 | * @note Requires @p CH_USE_SEMAPHORES. 174 | */ 175 | #if !defined(CH_USE_SEMSW) || defined(__DOXYGEN__) 176 | #define CH_USE_SEMSW TRUE 177 | #endif 178 | 179 | /** 180 | * @brief Mutexes APIs. 181 | * @details If enabled then the mutexes APIs are included in the kernel. 182 | * 183 | * @note The default is @p TRUE. 184 | */ 185 | #if !defined(CH_USE_MUTEXES) || defined(__DOXYGEN__) 186 | #define CH_USE_MUTEXES TRUE 187 | #endif 188 | 189 | /** 190 | * @brief Conditional Variables APIs. 191 | * @details If enabled then the conditional variables APIs are included 192 | * in the kernel. 193 | * 194 | * @note The default is @p TRUE. 195 | * @note Requires @p CH_USE_MUTEXES. 196 | */ 197 | #if !defined(CH_USE_CONDVARS) || defined(__DOXYGEN__) 198 | #define CH_USE_CONDVARS TRUE 199 | #endif 200 | 201 | /** 202 | * @brief Conditional Variables APIs with timeout. 203 | * @details If enabled then the conditional variables APIs with timeout 204 | * specification are included in the kernel. 205 | * 206 | * @note The default is @p TRUE. 207 | * @note Requires @p CH_USE_CONDVARS. 208 | */ 209 | #if !defined(CH_USE_CONDVARS_TIMEOUT) || defined(__DOXYGEN__) 210 | #define CH_USE_CONDVARS_TIMEOUT TRUE 211 | #endif 212 | 213 | /** 214 | * @brief Events Flags APIs. 215 | * @details If enabled then the event flags APIs are included in the kernel. 216 | * 217 | * @note The default is @p TRUE. 218 | */ 219 | #if !defined(CH_USE_EVENTS) || defined(__DOXYGEN__) 220 | #define CH_USE_EVENTS TRUE 221 | #endif 222 | 223 | /** 224 | * @brief Events Flags APIs with timeout. 225 | * @details If enabled then the events APIs with timeout specification 226 | * are included in the kernel. 227 | * 228 | * @note The default is @p TRUE. 229 | * @note Requires @p CH_USE_EVENTS. 230 | */ 231 | #if !defined(CH_USE_EVENTS_TIMEOUT) || defined(__DOXYGEN__) 232 | #define CH_USE_EVENTS_TIMEOUT TRUE 233 | #endif 234 | 235 | /** 236 | * @brief Synchronous Messages APIs. 237 | * @details If enabled then the synchronous messages APIs are included 238 | * in the kernel. 239 | * 240 | * @note The default is @p TRUE. 241 | */ 242 | #if !defined(CH_USE_MESSAGES) || defined(__DOXYGEN__) 243 | #define CH_USE_MESSAGES TRUE 244 | #endif 245 | 246 | /** 247 | * @brief Synchronous Messages queuing mode. 248 | * @details If enabled then messages are served by priority rather than in 249 | * FIFO order. 250 | * 251 | * @note The default is @p FALSE. Enable this if you have special requirements. 252 | * @note Requires @p CH_USE_MESSAGES. 253 | */ 254 | #if !defined(CH_USE_MESSAGES_PRIORITY) || defined(__DOXYGEN__) 255 | #define CH_USE_MESSAGES_PRIORITY FALSE 256 | #endif 257 | 258 | /** 259 | * @brief Mailboxes APIs. 260 | * @details If enabled then the asynchronous messages (mailboxes) APIs are 261 | * included in the kernel. 262 | * 263 | * @note The default is @p TRUE. 264 | * @note Requires @p CH_USE_SEMAPHORES. 265 | */ 266 | #if !defined(CH_USE_MAILBOXES) || defined(__DOXYGEN__) 267 | #define CH_USE_MAILBOXES TRUE 268 | #endif 269 | 270 | /** 271 | * @brief I/O Queues APIs. 272 | * @details If enabled then the I/O queues APIs are included in the kernel. 273 | * 274 | * @note The default is @p TRUE. 275 | */ 276 | #if !defined(CH_USE_QUEUES) || defined(__DOXYGEN__) 277 | #define CH_USE_QUEUES TRUE 278 | #endif 279 | 280 | /** 281 | * @brief Core Memory Manager APIs. 282 | * @details If enabled then the core memory manager APIs are included 283 | * in the kernel. 284 | * 285 | * @note The default is @p TRUE. 286 | */ 287 | #if !defined(CH_USE_MEMCORE) || defined(__DOXYGEN__) 288 | #define CH_USE_MEMCORE TRUE 289 | #endif 290 | 291 | /** 292 | * @brief Heap Allocator APIs. 293 | * @details If enabled then the memory heap allocator APIs are included 294 | * in the kernel. 295 | * 296 | * @note The default is @p TRUE. 297 | * @note Requires @p CH_USE_MEMCORE and either @p CH_USE_MUTEXES or 298 | * @p CH_USE_SEMAPHORES. 299 | * @note Mutexes are recommended. 300 | */ 301 | #if !defined(CH_USE_HEAP) || defined(__DOXYGEN__) 302 | #define CH_USE_HEAP TRUE 303 | #endif 304 | 305 | /** 306 | * @brief C-runtime allocator. 307 | * @details If enabled the the heap allocator APIs just wrap the C-runtime 308 | * @p malloc() and @p free() functions. 309 | * 310 | * @note The default is @p FALSE. 311 | * @note Requires @p CH_USE_HEAP. 312 | * @note The C-runtime may or may not require @p CH_USE_MEMCORE, see the 313 | * appropriate documentation. 314 | */ 315 | #if !defined(CH_USE_MALLOC_HEAP) || defined(__DOXYGEN__) 316 | #define CH_USE_MALLOC_HEAP FALSE 317 | #endif 318 | 319 | /** 320 | * @brief Memory Pools Allocator APIs. 321 | * @details If enabled then the memory pools allocator APIs are included 322 | * in the kernel. 323 | * 324 | * @note The default is @p TRUE. 325 | */ 326 | #if !defined(CH_USE_MEMPOOLS) || defined(__DOXYGEN__) 327 | #define CH_USE_MEMPOOLS TRUE 328 | #endif 329 | 330 | /** 331 | * @brief Dynamic Threads APIs. 332 | * @details If enabled then the dynamic threads creation APIs are included 333 | * in the kernel. 334 | * 335 | * @note The default is @p TRUE. 336 | * @note Requires @p CH_USE_WAITEXIT. 337 | * @note Requires @p CH_USE_HEAP and/or @p CH_USE_MEMPOOLS. 338 | */ 339 | #if !defined(CH_USE_DYNAMIC) || defined(__DOXYGEN__) 340 | #define CH_USE_DYNAMIC TRUE 341 | #endif 342 | 343 | /** @} */ 344 | 345 | /*===========================================================================*/ 346 | /** 347 | * @name Debug options 348 | * @{ 349 | */ 350 | /*===========================================================================*/ 351 | 352 | /** 353 | * @brief Debug option, system state check. 354 | * @details If enabled the correct call protocol for system APIs is checked 355 | * at runtime. 356 | * 357 | * @note The default is @p FALSE. 358 | */ 359 | #if !defined(CH_DBG_SYSTEM_STATE_CHECK) || defined(__DOXYGEN__) 360 | #define CH_DBG_SYSTEM_STATE_CHECK FALSE 361 | #endif 362 | 363 | /** 364 | * @brief Debug option, parameters checks. 365 | * @details If enabled then the checks on the API functions input 366 | * parameters are activated. 367 | * 368 | * @note The default is @p FALSE. 369 | */ 370 | #if !defined(CH_DBG_ENABLE_CHECKS) || defined(__DOXYGEN__) 371 | #define CH_DBG_ENABLE_CHECKS FALSE 372 | #endif 373 | 374 | /** 375 | * @brief Debug option, consistency checks. 376 | * @details If enabled then all the assertions in the kernel code are 377 | * activated. This includes consistency checks inside the kernel, 378 | * runtime anomalies and port-defined checks. 379 | * 380 | * @note The default is @p FALSE. 381 | */ 382 | #if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__) 383 | #define CH_DBG_ENABLE_ASSERTS FALSE 384 | #endif 385 | 386 | /** 387 | * @brief Debug option, trace buffer. 388 | * @details If enabled then the context switch circular trace buffer is 389 | * activated. 390 | * 391 | * @note The default is @p FALSE. 392 | */ 393 | #if !defined(CH_DBG_ENABLE_TRACE) || defined(__DOXYGEN__) 394 | #define CH_DBG_ENABLE_TRACE FALSE 395 | #endif 396 | 397 | /** 398 | * @brief Debug option, stack checks. 399 | * @details If enabled then a runtime stack check is performed. 400 | * 401 | * @note The default is @p FALSE. 402 | * @note The stack check is performed in a architecture/port dependent way. 403 | * It may not be implemented or some ports. 404 | * @note The default failure mode is to halt the system with the global 405 | * @p panic_msg variable set to @p NULL. 406 | */ 407 | #if !defined(CH_DBG_ENABLE_STACK_CHECK) || defined(__DOXYGEN__) 408 | #define CH_DBG_ENABLE_STACK_CHECK FALSE 409 | #endif 410 | 411 | /** 412 | * @brief Debug option, stacks initialization. 413 | * @details If enabled then the threads working area is filled with a byte 414 | * value when a thread is created. This can be useful for the 415 | * runtime measurement of the used stack. 416 | * 417 | * @note The default is @p FALSE. 418 | */ 419 | #if !defined(CH_DBG_FILL_THREADS) || defined(__DOXYGEN__) 420 | #define CH_DBG_FILL_THREADS FALSE 421 | #endif 422 | 423 | /** 424 | * @brief Debug option, threads profiling. 425 | * @details If enabled then a field is added to the @p Thread structure that 426 | * counts the system ticks occurred while executing the thread. 427 | * 428 | * @note The default is @p TRUE. 429 | * @note This debug option is defaulted to TRUE because it is required by 430 | * some test cases into the test suite. 431 | */ 432 | #if !defined(CH_DBG_THREADS_PROFILING) || defined(__DOXYGEN__) 433 | #define CH_DBG_THREADS_PROFILING TRUE 434 | #endif 435 | 436 | /** @} */ 437 | 438 | /*===========================================================================*/ 439 | /** 440 | * @name Kernel hooks 441 | * @{ 442 | */ 443 | /*===========================================================================*/ 444 | 445 | /** 446 | * @brief Threads descriptor structure extension. 447 | * @details User fields added to the end of the @p Thread structure. 448 | */ 449 | #if !defined(THREAD_EXT_FIELDS) || defined(__DOXYGEN__) 450 | #define THREAD_EXT_FIELDS \ 451 | /* Add threads custom fields here.*/ 452 | #endif 453 | 454 | /** 455 | * @brief Threads initialization hook. 456 | * @details User initialization code added to the @p chThdInit() API. 457 | * 458 | * @note It is invoked from within @p chThdInit() and implicitly from all 459 | * the threads creation APIs. 460 | */ 461 | #if !defined(THREAD_EXT_INIT_HOOK) || defined(__DOXYGEN__) 462 | #define THREAD_EXT_INIT_HOOK(tp) { \ 463 | /* Add threads initialization code here.*/ \ 464 | } 465 | #endif 466 | 467 | /** 468 | * @brief Threads finalization hook. 469 | * @details User finalization code added to the @p chThdExit() API. 470 | * 471 | * @note It is inserted into lock zone. 472 | * @note It is also invoked when the threads simply return in order to 473 | * terminate. 474 | */ 475 | #if !defined(THREAD_EXT_EXIT_HOOK) || defined(__DOXYGEN__) 476 | #define THREAD_EXT_EXIT_HOOK(tp) { \ 477 | /* Add threads finalization code here.*/ \ 478 | } 479 | #endif 480 | 481 | /** 482 | * @brief Context switch hook. 483 | * @details This hook is invoked just before switching between threads. 484 | */ 485 | #if !defined(THREAD_CONTEXT_SWITCH_HOOK) || defined(__DOXYGEN__) 486 | #define THREAD_CONTEXT_SWITCH_HOOK(ntp, otp) { \ 487 | /* System halt code here.*/ \ 488 | } 489 | #endif 490 | 491 | /** 492 | * @brief Idle Loop hook. 493 | * @details This hook is continuously invoked by the idle thread loop. 494 | */ 495 | #if !defined(IDLE_LOOP_HOOK) || defined(__DOXYGEN__) 496 | #define IDLE_LOOP_HOOK() { \ 497 | /* Idle loop code here.*/ \ 498 | } 499 | #endif 500 | 501 | /** 502 | * @brief System tick event hook. 503 | * @details This hook is invoked in the system tick handler immediately 504 | * after processing the virtual timers queue. 505 | */ 506 | #if !defined(SYSTEM_TICK_EVENT_HOOK) || defined(__DOXYGEN__) 507 | #define SYSTEM_TICK_EVENT_HOOK() { \ 508 | /* System tick event code here.*/ \ 509 | } 510 | #endif 511 | 512 | /** 513 | * @brief System halt hook. 514 | * @details This hook is invoked in case to a system halting error before 515 | * the system is halted. 516 | */ 517 | #if !defined(SYSTEM_HALT_HOOK) || defined(__DOXYGEN__) 518 | #define SYSTEM_HALT_HOOK() { \ 519 | /* System halt code here.*/ \ 520 | } 521 | #endif 522 | 523 | /** @} */ 524 | 525 | /*===========================================================================*/ 526 | /* Port-specific settings (override port settings defaulted in chcore.h). */ 527 | /*===========================================================================*/ 528 | 529 | #define CORTEX_USE_FPU TRUE 530 | 531 | #endif /* _CHCONF_H_ */ 532 | 533 | /** @} */ 534 | --------------------------------------------------------------------------------